johannes updated this revision to Diff 109415.
johannes added a comment.

add some test, replace -no-compilation-database with --


https://reviews.llvm.org/D36177

Files:
  include/clang/Tooling/ASTDiff/ASTDiff.h
  lib/Tooling/ASTDiff/ASTDiff.cpp
  test/Tooling/clang-diff-args.sh
  test/Tooling/clang-diff-basic.cpp
  tools/clang-diff/ClangDiff.cpp

Index: tools/clang-diff/ClangDiff.cpp
===================================================================
--- tools/clang-diff/ClangDiff.cpp
+++ tools/clang-diff/ClangDiff.cpp
@@ -28,12 +28,6 @@
             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,43 +37,88 @@
                                             cl::Optional,
                                             cl::cat(ClangDiffCategory));
 
-static std::unique_ptr<ASTUnit> getAST(const StringRef Filename) {
+static cl::opt<std::string> StopAfter("stop-after",
+                                      cl::desc("<topdown|bottomup>"),
+                                      cl::Optional, cl::init(""),
+                                      cl::cat(ClangDiffCategory));
+
+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())
     return nullptr;
   return std::move(ASTs[0]);
 }
 
 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 +131,22 @@
     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;
+  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);
Index: test/Tooling/clang-diff-basic.cpp
===================================================================
--- test/Tooling/clang-diff-basic.cpp
+++ test/Tooling/clang-diff-basic.cpp
@@ -1,6 +1,6 @@
 // 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-diff %T/src.cpp %T/dst.cpp -- | FileCheck %s
 
 #ifndef DEST
 namespace src {
Index: test/Tooling/clang-diff-args.sh
===================================================================
--- /dev/null
+++ test/Tooling/clang-diff-args.sh
@@ -0,0 +1,8 @@
+RUN: echo a > %t.cpp
+
+RUN: echo "CHECK: unknown type name 'X'" > %t1
+
+check adding command-line arguments
+RUN: clang-diff -ast-dump -extra-arg=-Da=X        %t.cpp -- 2>&1 | FileCheck %t1
+RUN: clang-diff -ast-dump -extra-arg-before=-Da=X %t.cpp -- 2>&1 | FileCheck %t1
+RUN: clang-diff -ast-dump %t.cpp -- 2>&1 -Da=X | FileCheck %t1
Index: lib/Tooling/ASTDiff/ASTDiff.cpp
===================================================================
--- lib/Tooling/ASTDiff/ASTDiff.cpp
+++ lib/Tooling/ASTDiff/ASTDiff.cpp
@@ -878,6 +878,8 @@
   if (IsMappingDone)
     return;
   TheMapping = matchTopDown();
+  if (Options.StopAfterTopDown)
+    return;
   matchBottomUp(TheMapping);
   IsMappingDone = true;
 }
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());
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to