johannes updated this revision to Diff 110962.
johannes added a comment.
rebase
https://reviews.llvm.org/D36187
Files:
include/clang/Tooling/ASTDiff/ASTDiff.h
lib/Tooling/ASTDiff/ASTDiff.cpp
test/Tooling/clang-diff-ast.cpp
test/Tooling/clang-diff-basic.cpp
test/Tooling/clang-diff-html.test
test/Tooling/clang-diff-topdown.cpp
Index: test/Tooling/clang-diff-topdown.cpp
===================================================================
--- test/Tooling/clang-diff-topdown.cpp
+++ test/Tooling/clang-diff-topdown.cpp
@@ -27,8 +27,19 @@
{{;;}}
}
+int x;
+
+namespace src {
+ int x;
+ int x1 = x + 1;
+ int x2 = ::x + 1;
+}
+
+class A { int x = 1 + 1; void f() { int x1 = x; } };
+
#else
+
void f1() {
{{;}}
@@ -45,4 +56,28 @@
;
}
+int x;
+
+namespace dst {
+ int x;
+ // CHECK: Match DeclRefExpr: :x(17) to DeclRefExpr: :x(22)
+ int x1 = x + 1;
+ // CHECK: Match DeclRefExpr: x(21) to DeclRefExpr: x(26)
+ int x2 = ::x + 1;
+}
+
+class B {
+ // Only the class name changed; it is not included in the field value,
+ // therefore there is no update.
+ // CHECK: Match FieldDecl: :x(int)(24) to FieldDecl: :x(int)(29)
+ // CHECK-NOT: Update FieldDecl: :x(int)(24)
+ int x = 1+1;
+ void f() {
+ // CHECK: Match MemberExpr: :x(32) to MemberExpr: :x(37)
+ // CHECK-NOT: Update MemberExpr: :x(32)
+ int x1 = B::x;
+ }
+
+};
+
#endif
Index: test/Tooling/clang-diff-html.test
===================================================================
--- test/Tooling/clang-diff-html.test
+++ test/Tooling/clang-diff-html.test
@@ -11,12 +11,12 @@
// match, move
// CHECK: <span id='L[[L:[0-9]+]]' tid='R[[R:[0-9]+]]' title='FunctionDecl
// CHECK-NEXT: [[L]] -> [[R]]
-// CHECK-NEXT: src::foo(void ())' class='u m'>void foo()
+// CHECK-NEXT: :foo(void ())' class='m'>void foo()
// match
// CHECK: <span id='L[[L:[0-9]+]]' tid='R[[R:[0-9]+]]' title='FunctionDecl
// CHECK-NEXT: [[L]] -> [[R]]
-// CHECK-NEXT: src::main(void ())' class='u'>void main()
+// CHECK-NEXT: :main(void ())'>void main()
// deletion
// CHECK: <span id='L[[L:[0-9]+]]' tid='R-1' title='IntegerLiteral
Index: test/Tooling/clang-diff-basic.cpp
===================================================================
--- test/Tooling/clang-diff-basic.cpp
+++ test/Tooling/clang-diff-basic.cpp
@@ -11,18 +11,18 @@
}
}
-// CHECK: Match DeclRefExpr: src::foo{{.*}} to DeclRefExpr: dst::inner::foo
+// CHECK: Match DeclRefExpr: :foo{{.*}} to DeclRefExpr: :inner::foo
void main() { inner::foo(); }
// CHECK: Match StringLiteral: foo{{.*}} to StringLiteral: foo
const char *b = "f" "o" "o";
// unsigned is canonicalized to unsigned int
-// CHECK: Match TypedefDecl: src::nat;unsigned int;{{.*}} to TypedefDecl: dst::nat;unsigned int;
+// CHECK: Match TypedefDecl: :nat;unsigned int;{{.*}} to TypedefDecl: :nat;unsigned int;
typedef unsigned nat;
-// CHECK: Match VarDecl: src::p(int){{.*}} to VarDecl: dst::prod(double)
-// CHECK: Update VarDecl: src::p(int){{.*}} to dst::prod(double)
+// CHECK: Match VarDecl: :p(int){{.*}} to VarDecl: :prod(double)
+// CHECK: Update VarDecl: :p(int){{.*}} to :prod(double)
// CHECK: Match BinaryOperator: *{{.*}} to BinaryOperator: *
double prod = 1 * 2 * 10;
// CHECK: Update DeclRefExpr
Index: test/Tooling/clang-diff-ast.cpp
===================================================================
--- test/Tooling/clang-diff-ast.cpp
+++ test/Tooling/clang-diff-ast.cpp
@@ -5,7 +5,7 @@
// CHECK: {{^}} NamespaceDecl: test;(
namespace test {
-// CHECK: {{^}} FunctionDecl: test::f(
+// CHECK: {{^}} FunctionDecl: :f(
// CHECK: CompoundStmt(
void f() {
// CHECK: VarDecl: i(int)(
@@ -17,7 +17,7 @@
auto b = true;
// CHECK: CallExpr(
// CHECK-NOT: ImplicitCastExpr
- // CHECK: DeclRefExpr: test::f(
+ // CHECK: DeclRefExpr: :f(
f();
// CHECK: UnaryOperator: ++(
++i;
@@ -41,7 +41,7 @@
// CHECK: CXXRecordDecl: X;X;(
class X : Base {
int m;
- // CHECK: CXXMethodDecl: X::foo(const char *(int))(
+ // CHECK: CXXMethodDecl: :foo(const char *(int))(
// CHECK: ParmVarDecl: i(int)(
const char *foo(int i) {
if (i == 0)
@@ -56,12 +56,12 @@
int not_initialized;
// All initialized members, bases and delegating initializers are are
// appended, separated by commas.
- // CHECK: CXXConstructorDecl: X::X(void (char, int))Base,X::m,(
- X(char c, int) : Base(), m(0) {
- // CHECK: MemberExpr: X::m(
+ // CHECK: CXXConstructorDecl: :X(void (char, int))Base,:m,(
+ X(char, int) : Base(), m(0) {
+ // CHECK: MemberExpr: :m(
int x = m;
}
- // CHECK: CXXConstructorDecl: X::X(void (char))X,(
+ // CHECK: CXXConstructorDecl: :X(void (char))X,(
X(char s) : X(s, 4) {}
};
Index: lib/Tooling/ASTDiff/ASTDiff.cpp
===================================================================
--- lib/Tooling/ASTDiff/ASTDiff.cpp
+++ lib/Tooling/ASTDiff/ASTDiff.cpp
@@ -111,24 +111,22 @@
/// Represents the AST of a TranslationUnit.
class SyntaxTree::Impl {
public:
- /// Constructs a tree from the entire translation unit.
- Impl(SyntaxTree *Parent, const ASTContext &AST);
/// Constructs a tree from an AST node.
- Impl(SyntaxTree *Parent, Decl *N, const ASTContext &AST);
- Impl(SyntaxTree *Parent, Stmt *N, const ASTContext &AST);
+ Impl(SyntaxTree *Parent, Decl *N, ASTContext &AST);
+ Impl(SyntaxTree *Parent, Stmt *N, ASTContext &AST);
template <class T>
Impl(SyntaxTree *Parent,
typename std::enable_if<std::is_base_of<Stmt, T>::value, T>::type *Node,
- const ASTContext &AST)
+ ASTContext &AST)
: Impl(Parent, dyn_cast<Stmt>(Node), AST) {}
template <class T>
Impl(SyntaxTree *Parent,
typename std::enable_if<std::is_base_of<Decl, T>::value, T>::type *Node,
- const ASTContext &AST)
+ ASTContext &AST)
: Impl(Parent, dyn_cast<Decl>(Node), AST) {}
SyntaxTree *Parent;
- const ASTContext &AST;
+ ASTContext &AST;
std::vector<NodeId> Leaves;
// Maps preorder indices to postorder ones.
std::vector<int> PostorderIds;
@@ -270,7 +268,7 @@
};
} // end anonymous namespace
-SyntaxTree::Impl::Impl(SyntaxTree *Parent, Decl *N, const ASTContext &AST)
+SyntaxTree::Impl::Impl(SyntaxTree *Parent, Decl *N, ASTContext &AST)
: Parent(Parent), AST(AST) {
NodeCountVisitor NodeCounter(*this);
NodeCounter.TraverseDecl(N);
@@ -280,7 +278,7 @@
initTree();
}
-SyntaxTree::Impl::Impl(SyntaxTree *Parent, Stmt *N, const ASTContext &AST)
+SyntaxTree::Impl::Impl(SyntaxTree *Parent, Stmt *N, ASTContext &AST)
: Parent(Parent), AST(AST) {
NodeCountVisitor NodeCounter(*this);
NodeCounter.TraverseStmt(N);
@@ -365,6 +363,43 @@
llvm_unreachable("Node not found in parent's children.");
}
+// Returns the qualified name of ND. If it is subordinate to Context,
+// then the prefix of the latter is removed from the returned value.
+static std::string getRelativeName(const NamedDecl *ND,
+ const DeclContext *Context) {
+ std::string ContextPrefix;
+ if (auto *Namespace = dyn_cast<NamespaceDecl>(Context))
+ ContextPrefix = Namespace->getQualifiedNameAsString();
+ else if (auto *Tag = dyn_cast<TagDecl>(Context))
+ ContextPrefix = Tag->getQualifiedNameAsString();
+ std::string Val = ND->getQualifiedNameAsString();
+ // Strip the qualifier, if Val refers to somthing in the current scope.
+ // But leave one leading ':' in place, so that we know that this is a
+ // relative path.
+ if (!ContextPrefix.empty() &&
+ StringRef(Val).startswith(ContextPrefix))
+ Val = Val.substr(ContextPrefix.size() + 1);
+ return Val;
+}
+
+static std::string getRelativeName(const NamedDecl *ND) {
+ return getRelativeName(ND, ND->getDeclContext());
+}
+
+static const DeclContext *getEnclosingDeclContext(ASTContext &AST,
+ const Stmt *S) {
+ while (S) {
+ const auto &Parents = AST.getParents(*S);
+ if (Parents.empty())
+ return nullptr;
+ const auto &P = Parents[0];
+ if (const auto *D = P.get<Decl>())
+ return D->getDeclContext();
+ S = P.get<Stmt>();
+ }
+ llvm_unreachable("Could not find Decl ancestor.");
+}
+
std::string SyntaxTree::Impl::getNodeValue(NodeId Id) const {
return getNodeValue(getNode(Id));
}
@@ -384,8 +419,7 @@
TypePP.AnonymousTagLocations = false;
if (auto *V = dyn_cast<ValueDecl>(D)) {
- Value += V->getQualifiedNameAsString() + "(" +
- V->getType().getAsString(TypePP) + ")";
+ Value += getRelativeName(V) + "(" + V->getType().getAsString(TypePP) + ")";
if (auto *C = dyn_cast<CXXConstructorDecl>(D)) {
for (auto *Init : C->inits()) {
if (!Init->isWritten())
@@ -397,15 +431,15 @@
Value += C->getNameAsString();
} else {
assert(Init->isAnyMemberInitializer());
- Value += Init->getMember()->getQualifiedNameAsString();
+ Value += getRelativeName(Init->getMember());
}
Value += ",";
}
}
return Value;
}
if (auto *N = dyn_cast<NamedDecl>(D))
- Value += N->getQualifiedNameAsString() + ";";
+ Value += getRelativeName(N) + ";";
if (auto *T = dyn_cast<TypedefNameDecl>(D))
return Value + T->getUnderlyingType().getAsString(TypePP) + ";";
if (auto *T = dyn_cast<TypeDecl>(D))
@@ -429,7 +463,7 @@
if (auto *B = dyn_cast<BinaryOperator>(S))
return B->getOpcodeStr();
if (auto *M = dyn_cast<MemberExpr>(S))
- return M->getMemberDecl()->getQualifiedNameAsString();
+ return getRelativeName(M->getMemberDecl());
if (auto *I = dyn_cast<IntegerLiteral>(S)) {
SmallString<256> Str;
I->getValue().toString(Str, /*Radix=*/10, /*Signed=*/false);
@@ -441,7 +475,7 @@
return Str.str();
}
if (auto *D = dyn_cast<DeclRefExpr>(S))
- return D->getDecl()->getQualifiedNameAsString();
+ return getRelativeName(D->getDecl(), getEnclosingDeclContext(AST, S));
if (auto *String = dyn_cast<StringLiteral>(S))
return String->getString();
if (auto *B = dyn_cast<CXXBoolLiteralExpr>(S))
@@ -950,7 +984,7 @@
return DiffImpl->getMapped(SourceTree.TreeImpl, Id);
}
-SyntaxTree::SyntaxTree(const ASTContext &AST)
+SyntaxTree::SyntaxTree(ASTContext &AST)
: TreeImpl(llvm::make_unique<SyntaxTree::Impl>(
this, AST.getTranslationUnitDecl(), AST)) {}
Index: include/clang/Tooling/ASTDiff/ASTDiff.h
===================================================================
--- include/clang/Tooling/ASTDiff/ASTDiff.h
+++ include/clang/Tooling/ASTDiff/ASTDiff.h
@@ -68,10 +68,10 @@
class SyntaxTree {
public:
/// Constructs a tree from a translation unit.
- SyntaxTree(const ASTContext &AST);
+ SyntaxTree(ASTContext &AST);
/// Constructs a tree from any AST node.
template <class T>
- SyntaxTree(T *Node, const ASTContext &AST)
+ SyntaxTree(T *Node, ASTContext &AST)
: TreeImpl(llvm::make_unique<Impl>(this, Node, AST)) {}
SyntaxTree(SyntaxTree &&Other) = default;
~SyntaxTree();
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits