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

update


https://reviews.llvm.org/D37003

Files:
  lib/Tooling/ASTDiff/ASTDiff.cpp
  test/Tooling/Inputs/clang-diff-basic-src.cpp
  test/Tooling/clang-diff-ast.cpp
  test/Tooling/clang-diff-basic.cpp
  test/Tooling/clang-diff-html.test

Index: test/Tooling/clang-diff-html.test
===================================================================
--- test/Tooling/clang-diff-html.test
+++ test/Tooling/clang-diff-html.test
@@ -1,4 +1,4 @@
-RUN: clang-diff -html %S/Inputs/clang-diff-basic-src.cpp %S/clang-diff-basic.cpp -- | FileCheck %s
+RUN: clang-diff -html %S/Inputs/clang-diff-basic-src.cpp %S/clang-diff-basic.cpp -- -std=c++11 | FileCheck %s
 
 CHECK: <pre><div id='L' class='code'><span id='L0' tid='R0' title='TranslationUnitDecl
 CHECK-NEXT: 0 -> 0' class='u'>
Index: test/Tooling/clang-diff-basic.cpp
===================================================================
--- test/Tooling/clang-diff-basic.cpp
+++ test/Tooling/clang-diff-basic.cpp
@@ -1,4 +1,4 @@
-// RUN: clang-diff -dump-matches %S/Inputs/clang-diff-basic-src.cpp %s -- | FileCheck %s
+// RUN: clang-diff -dump-matches %S/Inputs/clang-diff-basic-src.cpp %s -- -std=c++11 | FileCheck %s
 
 // CHECK: Match TranslationUnitDecl(0) to TranslationUnitDecl(0)
 // CHECK: Match NamespaceDecl(1) to NamespaceDecl(1)
@@ -68,5 +68,18 @@
   F(1, /*b=*/1);
 }
 
+// CHECK: Match TemplateTypeParmDecl(77)
+template <class Type, class U = int>
+U visit(Type &t) {
+  int x = t;
+  return U();
+}
+
+void tmp() {
+  long x;
+  // CHECK: Match TemplateArgument(93)
+  visit<long>(x);
+}
+
 // CHECK: Delete AccessSpecDecl(39)
 // CHECK: Delete CXXMethodDecl(42)
Index: test/Tooling/clang-diff-ast.cpp
===================================================================
--- test/Tooling/clang-diff-ast.cpp
+++ test/Tooling/clang-diff-ast.cpp
@@ -93,3 +93,16 @@
 // CHECK-NEXT: FunctionDecl(64)
 void sentinel();
 #endif
+
+// CHECK-NEXT: ClassTemplateDecl(65)
+// CHECK-NEXT: TemplateTypeParmDecl(66)
+// CHECK-NEXT: CXXRecordDecl(67)
+template <class T> class C {
+  // CHECK-NEXT: FieldDecl(68)
+  T t;
+};
+
+// CHECK-NEXT: CXXRecordDecl(69)
+// CHECK-NEXT: TemplateName(70)
+// CHECK-NEXT: TemplateArgument(71)
+class I : C<int> {};
Index: test/Tooling/Inputs/clang-diff-basic-src.cpp
===================================================================
--- test/Tooling/Inputs/clang-diff-basic-src.cpp
+++ test/Tooling/Inputs/clang-diff-basic-src.cpp
@@ -41,3 +41,16 @@
   M1;
   F(1, 1);
 }
+
+template <class T, class U = void>
+U visit(T &t) {
+  int x = t;
+  return U();
+}
+
+void tmp() {
+  int x;
+  visit<int>(x);
+}
+
+int x = 1;
Index: lib/Tooling/ASTDiff/ASTDiff.cpp
===================================================================
--- lib/Tooling/ASTDiff/ASTDiff.cpp
+++ lib/Tooling/ASTDiff/ASTDiff.cpp
@@ -13,7 +13,7 @@
 
 #include "clang/Tooling/ASTDiff/ASTDiff.h"
 
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/LexicallyOrderedRecursiveASTVisitor.h"
 #include "clang/Lex/Lexer.h"
 #include "llvm/ADT/PriorityQueue.h"
 #include "llvm/Support/MD5.h"
@@ -141,6 +141,7 @@
   // Maps preorder indices to postorder ones.
   std::vector<int> PostorderIds;
   NodeList NodesBfs;
+  std::map<NodeId, SourceRange> TemplateArgumentLocations;
 
   int getSize() const { return Nodes.size(); }
   NodeRef getRoot() const { return getNode(getRootId()); }
@@ -175,6 +176,13 @@
 static bool isSpecializedNodeExcluded(CXXCtorInitializer *I) {
   return !I->isWritten();
 }
+static bool isSpecializedNodeExcluded(const TemplateArgumentLoc *S) {
+  return false;
+}
+
+static bool isNodeExcluded(ASTUnit &AST, TemplateName *Template) {
+  return false;
+}
 
 template <class T> static bool isNodeExcluded(ASTUnit &AST, T *N) {
   const SourceManager &SM = AST.getSourceManager();
@@ -194,20 +202,24 @@
 
 namespace {
 // Sets Height, Parent and Children for each node.
-struct PreorderVisitor : public RecursiveASTVisitor<PreorderVisitor> {
+struct PreorderVisitor
+    : public LexicallyOrderedRecursiveASTVisitor<PreorderVisitor> {
+  using BaseType = LexicallyOrderedRecursiveASTVisitor<PreorderVisitor>;
+
   int Id = 0, Depth = 0;
   NodeId Parent;
   SyntaxTree::Impl &Tree;
 
-  PreorderVisitor(SyntaxTree::Impl &Tree) : Tree(Tree) {}
+  PreorderVisitor(SyntaxTree::Impl &Tree)
+      : BaseType(Tree.AST.getSourceManager()), Tree(Tree) {}
 
-  template <class T> std::tuple<NodeId, NodeId> PreTraverse(T *ASTNode) {
+  template <class T> std::tuple<NodeId, NodeId> PreTraverse(const T &ASTNode) {
     NodeId MyId = Id;
     Tree.Nodes.emplace_back(Tree);
     Node &N = Tree.getMutableNode(MyId);
     N.Parent = Parent;
     N.Depth = Depth;
-    N.ASTNode = DynTypedNode::create(*ASTNode);
+    N.ASTNode = DynTypedNode::create(ASTNode);
     assert(!N.ASTNode.getNodeKind().isNone() &&
            "Expected nodes to have a valid kind.");
     if (Parent.isValid()) {
@@ -239,27 +251,44 @@
   bool TraverseDecl(Decl *D) {
     if (isNodeExcluded(Tree.AST, D))
       return true;
-    auto SavedState = PreTraverse(D);
-    RecursiveASTVisitor<PreorderVisitor>::TraverseDecl(D);
+    auto SavedState = PreTraverse(*D);
+    BaseType::TraverseDecl(D);
     PostTraverse(SavedState);
     return true;
   }
   bool TraverseStmt(Stmt *S) {
     if (S)
       S = S->IgnoreImplicit();
     if (isNodeExcluded(Tree.AST, S))
       return true;
-    auto SavedState = PreTraverse(S);
-    RecursiveASTVisitor<PreorderVisitor>::TraverseStmt(S);
+    auto SavedState = PreTraverse(*S);
+    BaseType::TraverseStmt(S);
     PostTraverse(SavedState);
     return true;
   }
   bool TraverseType(QualType T) { return true; }
   bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
     if (isNodeExcluded(Tree.AST, Init))
       return true;
-    auto SavedState = PreTraverse(Init);
-    RecursiveASTVisitor<PreorderVisitor>::TraverseConstructorInitializer(Init);
+    auto SavedState = PreTraverse(*Init);
+    BaseType::TraverseConstructorInitializer(Init);
+    PostTraverse(SavedState);
+    return true;
+  }
+  bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) {
+    if (isNodeExcluded(Tree.AST, &ArgLoc))
+      return true;
+    Tree.TemplateArgumentLocations.emplace(Id, ArgLoc.getSourceRange());
+    auto SavedState = PreTraverse(ArgLoc.getArgument());
+    BaseType::TraverseTemplateArgumentLoc(ArgLoc);
+    PostTraverse(SavedState);
+    return true;
+  }
+  bool TraverseTemplateName(TemplateName Template) {
+    if (isNodeExcluded(Tree.AST, &Template))
+      return true;
+    auto SavedState = PreTraverse(Template);
+    BaseType::TraverseTemplateName(Template);
     PostTraverse(SavedState);
     return true;
   }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to