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