Index: lib/Tooling/ASTDiff/ASTDiff.cpp =================================================================== --- lib/Tooling/ASTDiff/ASTDiff.cpp +++ lib/Tooling/ASTDiff/ASTDiff.cpp @@ -68,7 +68,8 @@ // Compute ChangeKind for each node based on similarity. void computeChangeKinds(Mapping &M); - NodeId getMapped(const std::unique_ptr &Tree, NodeId Id) const { + NodeId getMapped(const std::unique_ptr &Tree, + NodeId Id) const { if (&*Tree == &T1) return TheMapping.getDst(Id); assert(&*Tree == &T2 && "Invalid tree."); @@ -157,12 +158,23 @@ void setLeftMostDescendants(); }; +static bool isSpecializedNodeExcluded(const Decl *D) { return D->isImplicit(); } +static bool isSpecializedNodeExcluded(const Stmt *S) { return false; } + template static bool isNodeExcluded(const SourceManager &SrcMgr, T *N) { if (!N) return true; SourceLocation SLoc = N->getLocStart(); - return SLoc.isValid() && SrcMgr.isInSystemHeader(SLoc); + if (SLoc.isValid()) { + // Ignore everything from other files. + if (!SrcMgr.isInMainFile(SLoc)) + return true; + // Ignore macros. + if (SLoc != SrcMgr.getSpellingLoc(SLoc)) + return true; + } + return isSpecializedNodeExcluded(N); } namespace { @@ -179,6 +191,8 @@ return true; } bool TraverseStmt(Stmt *S) { + if (S) + S = S->IgnoreImplicit(); if (isNodeExcluded(Tree.AST.getSourceManager(), S)) return true; ++Count; @@ -241,6 +255,8 @@ return true; } bool TraverseStmt(Stmt *S) { + if (S) + S = S->IgnoreImplicit(); if (isNodeExcluded(Tree.AST.getSourceManager(), S)) return true; auto SavedState = PreTraverse(S); @@ -900,7 +916,8 @@ return TreeImpl->findPositionInParent(Id); } -std::pair SyntaxTree::getSourceRangeOffsets(const Node &N) const { +std::pair +SyntaxTree::getSourceRangeOffsets(const Node &N) const { const SourceManager &SrcMgr = TreeImpl->AST.getSourceManager(); SourceRange Range = N.ASTNode.getSourceRange(); SourceLocation BeginLoc = Range.getBegin(); Index: test/Tooling/clang-diff-ast.cpp =================================================================== --- test/Tooling/clang-diff-ast.cpp +++ test/Tooling/clang-diff-ast.cpp @@ -12,7 +12,8 @@ // CHECK: IntegerLiteral: 1 auto i = 1; // CHECK: CallExpr( - // CHECK: DeclRefExpr: f( + // CHECK-NOT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr: f( f(); // CHECK: BinaryOperator: =( i = i; @@ -37,6 +38,7 @@ if (i == 0) // CHECK: StringLiteral: foo( return "foo"; + // CHECK-NOT: ImplicitCastExpr return 0; } @@ -48,3 +50,23 @@ int x = m; } }; + +#define M (void)1 +#define MA(a, b) (void)a, b +// CHECK: FunctionDecl +// CHECK-NEXT: CompoundStmt +void macros() { + M; + MA(1, 2); +} +// CHECK-NEXT: NamespaceDecl + +#ifndef GUARD +#define GUARD +namespace world { +// nodes from other files are excluded, there should be no output from this +// point on +// CHECK-NOT: {{.}} +#include "clang-diff-ast.cpp" +} +#endif Index: test/Tooling/clang-diff-json.cpp =================================================================== --- test/Tooling/clang-diff-json.cpp +++ test/Tooling/clang-diff-json.cpp @@ -3,9 +3,9 @@ // RUN: | FileCheck %s // CHECK: "begin": 299, -// CHECK: "type": "CXXRecordDecl", // CHECK: "type": "FieldDecl", // CHECK: "end": 319, +// CHECK: "type": "CXXRecordDecl", class A { int x; };