diff --git a/test/Tooling/clang-diff-args.test b/test/Tooling/clang-diff-args.test new file mode 100644 index 0000000000000000000000000000000000000000..a051c3ba79b8bbfef21b96dc34b6fa5cbaf01d2f --- /dev/null +++ b/test/Tooling/clang-diff-args.test @@ -0,0 +1,8 @@ +RUN: echo a > %t.cpp + +CHECK: unknown type name 'X' + +check adding compiler cflags +RUN: clang-diff -ast-dump -extra-arg=-Da=X %t.cpp -- 2>&1 | FileCheck %s +RUN: clang-diff -ast-dump -extra-arg-before=-Da=X %t.cpp -- 2>&1 | FileCheck %s +RUN: clang-diff -ast-dump %t.cpp -- 2>&1 -Da=X | FileCheck %s diff --git a/test/Tooling/clang-diff-basic.cpp b/test/Tooling/clang-diff-basic.cpp index e23abbd4cee23775885ed024f3f2dad0fe76d22a..ac676991e99506c3a506da0b03e6d002b55232a8 100644 --- a/test/Tooling/clang-diff-basic.cpp +++ b/test/Tooling/clang-diff-basic.cpp @@ -1,7 +1,6 @@ -// RUN: mkdir -p %t -// RUN: %clang_cc1 -E %s > %t/src.cpp -// RUN: %clang_cc1 -E %s > %t/dst.cpp -DDEST -// RUN: clang-diff -no-compilation-database %t/src.cpp %t/dst.cpp | FileCheck %s +// RUN: %clang_cc1 -E %s > %t.src.cpp +// RUN: %clang_cc1 -E %s > %t.dst.cpp -DDEST +// RUN: clang-diff %t.src.cpp %t.dst.cpp -- | FileCheck %s #ifndef DEST namespace src { diff --git a/tools/clang-diff/ClangDiff.cpp b/tools/clang-diff/ClangDiff.cpp index 86284cda43707a39d4f91b70754ea1235d623e55..ea7218368852e993cc3dcc2bfa6645321e2fca8e 100644 --- a/tools/clang-diff/ClangDiff.cpp +++ b/tools/clang-diff/ClangDiff.cpp @@ -28,12 +28,6 @@ static cl::opt<bool> cl::desc("Print the internal representation of the AST as JSON."), cl::init(false), cl::cat(ClangDiffCategory)); -static cl::opt<bool> NoCompilationDatabase( - "no-compilation-database", - cl::desc( - "Do not attempt to load build settings from a compilation database"), - cl::init(false), cl::cat(ClangDiffCategory)); - static cl::opt<std::string> SourcePath(cl::Positional, cl::desc("<source>"), cl::Required, cl::cat(ClangDiffCategory)); @@ -43,23 +37,56 @@ static cl::opt<std::string> DestinationPath(cl::Positional, cl::Optional, cl::cat(ClangDiffCategory)); -static std::unique_ptr<ASTUnit> getAST(const StringRef Filename) { +static cl::opt<int> MaxSize("s", cl::desc("<maxsize>"), cl::Optional, + cl::init(-1), cl::cat(ClangDiffCategory)); + +static cl::opt<std::string> BuildPath("p", cl::desc("Build path"), cl::init(""), + cl::Optional, cl::cat(ClangDiffCategory)); + +static cl::list<std::string> ArgsAfter( + "extra-arg", + cl::desc("Additional argument to append to the compiler command line"), + cl::cat(ClangDiffCategory)); + +static cl::list<std::string> ArgsBefore( + "extra-arg-before", + cl::desc("Additional argument to prepend to the compiler command line"), + cl::cat(ClangDiffCategory)); + +static void addExtraArgs(std::unique_ptr<CompilationDatabase> &Compilations) { + if (!Compilations) + return; + auto AdjustingCompilations = + llvm::make_unique<ArgumentsAdjustingCompilations>( + std::move(Compilations)); + AdjustingCompilations->appendArgumentsAdjuster( + getInsertArgumentAdjuster(ArgsBefore, ArgumentInsertPosition::BEGIN)); + AdjustingCompilations->appendArgumentsAdjuster( + getInsertArgumentAdjuster(ArgsAfter, ArgumentInsertPosition::END)); + Compilations = std::move(AdjustingCompilations); +} + +static std::unique_ptr<ASTUnit> +getAST(const std::unique_ptr<CompilationDatabase> &CommonCompilations, + const StringRef Filename) { std::string ErrorMessage; std::unique_ptr<CompilationDatabase> Compilations; - if (!NoCompilationDatabase) - Compilations = - CompilationDatabase::autoDetectFromSource(Filename, ErrorMessage); - if (!Compilations) { - if (!NoCompilationDatabase) + if (!CommonCompilations) { + Compilations = CompilationDatabase::autoDetectFromSource( + BuildPath.empty() ? Filename : BuildPath, ErrorMessage); + if (!Compilations) { llvm::errs() << "Error while trying to load a compilation database, running " "without flags.\n" << ErrorMessage; - Compilations = llvm::make_unique<clang::tooling::FixedCompilationDatabase>( - ".", std::vector<std::string>()); + Compilations = + llvm::make_unique<clang::tooling::FixedCompilationDatabase>( + ".", std::vector<std::string>()); + } } + addExtraArgs(Compilations); std::array<std::string, 1> Files = {{Filename}}; - ClangTool Tool(*Compilations, Files); + ClangTool Tool(Compilations ? *Compilations : *CommonCompilations, Files); std::vector<std::unique_ptr<ASTUnit>> ASTs; Tool.buildASTs(ASTs); if (ASTs.size() != Files.size()) @@ -68,18 +95,25 @@ static std::unique_ptr<ASTUnit> getAST(const StringRef Filename) { } int main(int argc, const char **argv) { + std::string ErrorMessage; + std::unique_ptr<CompilationDatabase> CommonCompilations = + FixedCompilationDatabase::loadFromCommandLine(argc, argv, ErrorMessage); + if (!CommonCompilations && !ErrorMessage.empty()) + llvm::errs() << ErrorMessage; cl::HideUnrelatedOptions(ClangDiffCategory); if (!cl::ParseCommandLineOptions(argc, argv)) { cl::PrintOptionValues(); return 1; } + addExtraArgs(CommonCompilations); + if (ASTDump) { if (!DestinationPath.empty()) { llvm::errs() << "Error: Please specify exactly one filename.\n"; return 1; } - std::unique_ptr<ASTUnit> AST = getAST(SourcePath); + std::unique_ptr<ASTUnit> AST = getAST(CommonCompilations, SourcePath); if (!AST) return 1; diff::SyntaxTree Tree(AST->getASTContext()); @@ -92,12 +126,14 @@ int main(int argc, const char **argv) { return 1; } - std::unique_ptr<ASTUnit> Src = getAST(SourcePath); - std::unique_ptr<ASTUnit> Dst = getAST(DestinationPath); + std::unique_ptr<ASTUnit> Src = getAST(CommonCompilations, SourcePath); + std::unique_ptr<ASTUnit> Dst = getAST(CommonCompilations, DestinationPath); if (!Src || !Dst) return 1; diff::ComparisonOptions Options; + if (MaxSize != -1) + Options.MaxSize = MaxSize; diff::SyntaxTree SrcTree(Src->getASTContext()); diff::SyntaxTree DstTree(Dst->getASTContext()); diff::ASTDiff DiffTool(SrcTree, DstTree, Options);