Index: include/clang/Tooling/ASTDiff/ASTDiff.h =================================================================== --- include/clang/Tooling/ASTDiff/ASTDiff.h +++ include/clang/Tooling/ASTDiff/ASTDiff.h @@ -125,6 +125,8 @@ /// (see NodeComparison) will be allowed to be matched. bool EnableMatchingWithUnmatchableParents = false; + bool StopAfterTopDown = false; + /// Returns false if the nodes should never be matched. bool isMatchingAllowed(const DynTypedNode &N1, const DynTypedNode &N2) const { return N1.getNodeKind().isSame(N2.getNodeKind()); Index: lib/Tooling/ASTDiff/ASTDiff.cpp =================================================================== --- lib/Tooling/ASTDiff/ASTDiff.cpp +++ lib/Tooling/ASTDiff/ASTDiff.cpp @@ -875,6 +875,8 @@ if (IsMappingDone) return; TheMapping = matchTopDown(); + if (Options.StopAfterTopDown) + return; matchBottomUp(TheMapping); IsMappingDone = true; } Index: tools/clang-diff/ClangDiff.cpp =================================================================== --- tools/clang-diff/ClangDiff.cpp +++ tools/clang-diff/ClangDiff.cpp @@ -43,12 +43,33 @@ cl::Optional, cl::cat(ClangDiffCategory)); +static cl::opt StopAfter("stop-after", + cl::desc(""), + cl::Optional, cl::init(""), + cl::cat(ClangDiffCategory)); + +static cl::opt MaxSize("s", cl::desc(""), cl::Optional, + cl::init(-1), cl::cat(ClangDiffCategory)); + +static cl::opt BuildPath("p", cl::desc("Build path"), cl::init(""), + cl::Optional, cl::cat(ClangDiffCategory)); + +static cl::list ArgsAfter( + "extra-arg", + cl::desc("Additional argument to append to the compiler command line"), + cl::cat(ClangDiffCategory)); + +static cl::list ArgsBefore( + "extra-arg-before", + cl::desc("Additional argument to prepend to the compiler command line"), + cl::cat(ClangDiffCategory)); + static std::unique_ptr getAST(const StringRef Filename) { std::string ErrorMessage; std::unique_ptr Compilations; if (!NoCompilationDatabase) - Compilations = - CompilationDatabase::autoDetectFromSource(Filename, ErrorMessage); + Compilations = CompilationDatabase::autoDetectFromSource( + BuildPath.empty() ? Filename : BuildPath, ErrorMessage); if (!Compilations) { if (!NoCompilationDatabase) llvm::errs() @@ -58,6 +79,14 @@ Compilations = llvm::make_unique( ".", std::vector()); } + auto AdjustingCompilations = + llvm::make_unique( + std::move(Compilations)); + AdjustingCompilations->appendArgumentsAdjuster( + getInsertArgumentAdjuster(ArgsBefore, ArgumentInsertPosition::BEGIN)); + AdjustingCompilations->appendArgumentsAdjuster( + getInsertArgumentAdjuster(ArgsAfter, ArgumentInsertPosition::END)); + Compilations = std::move(AdjustingCompilations); std::array Files = {{Filename}}; ClangTool Tool(*Compilations, Files); std::vector> ASTs; @@ -98,6 +127,16 @@ return 1; diff::ComparisonOptions Options; + if (MaxSize != -1) + Options.MaxSize = MaxSize; + if (!StopAfter.empty()) { + if (StopAfter == "topdown") + Options.StopAfterTopDown = true; + else if (StopAfter != "bottomup") { + llvm::errs() << "Error: Invalid argument for -stop-after"; + return 1; + } + } diff::SyntaxTree SrcTree(Src->getASTContext()); diff::SyntaxTree DstTree(Dst->getASTContext()); diff::ASTDiff DiffTool(SrcTree, DstTree, Options);