r311433 - [clang-diff] Use the relative name for NamedDecl

Johannes Altmanninger via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 22 01:56:26 PDT 2017


Author: krobelus
Date: Tue Aug 22 01:56:26 2017
New Revision: 311433

URL: http://llvm.org/viewvc/llvm-project?rev=311433&view=rev
Log:
[clang-diff] Use the relative name for NamedDecl

Summary:
If a node referring to a name is within a class or namespace, do not use
the full qualified name, but strip the namespace prefix.

Reviewers: arphaman, bkramer

Subscribers: klimek

Differential Revision: https://reviews.llvm.org/D36681

Modified:
    cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiff.h
    cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp
    cfe/trunk/test/Tooling/clang-diff-ast.cpp
    cfe/trunk/test/Tooling/clang-diff-basic.cpp
    cfe/trunk/test/Tooling/clang-diff-html.test
    cfe/trunk/test/Tooling/clang-diff-topdown.cpp

Modified: cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiff.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiff.h?rev=311433&r1=311432&r2=311433&view=diff
==============================================================================
--- cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiff.h (original)
+++ cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiff.h Tue Aug 22 01:56:26 2017
@@ -68,10 +68,10 @@ private:
 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();

Modified: cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp?rev=311433&r1=311432&r2=311433&view=diff
==============================================================================
--- cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp (original)
+++ cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp Tue Aug 22 01:56:26 2017
@@ -111,24 +111,22 @@ private:
 /// 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;
@@ -147,6 +145,10 @@ public:
   bool isInSubtree(NodeId Id, NodeId SubtreeRoot) const;
   int findPositionInParent(NodeId Id, bool Shifted = false) const;
 
+  std::string getRelativeName(const NamedDecl *ND,
+                              const DeclContext *Context) const;
+  std::string getRelativeName(const NamedDecl *ND) const;
+
   std::string getNodeValue(NodeId Id) const;
   std::string getNodeValue(const Node &Node) const;
   std::string getDeclValue(const Decl *D) const;
@@ -270,7 +272,7 @@ struct PreorderVisitor : public Recursiv
 };
 } // 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 +282,7 @@ SyntaxTree::Impl::Impl(SyntaxTree *Paren
   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 +367,46 @@ int SyntaxTree::Impl::findPositionInPare
   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.
+std::string
+SyntaxTree::Impl::getRelativeName(const NamedDecl *ND,
+                                  const DeclContext *Context) const {
+  std::string ContextPrefix;
+  if (auto *Namespace = dyn_cast<NamespaceDecl>(Context))
+    ContextPrefix = Namespace->getQualifiedNameAsString();
+  else if (auto *Record = dyn_cast<RecordDecl>(Context))
+    ContextPrefix = Record->getQualifiedNameAsString();
+  else if (AST.getLangOpts().CPlusPlus11)
+    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;
+}
+
+std::string SyntaxTree::Impl::getRelativeName(const NamedDecl *ND) const {
+  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 +426,7 @@ std::string SyntaxTree::Impl::getDeclVal
   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,7 +438,7 @@ std::string SyntaxTree::Impl::getDeclVal
           Value += C->getNameAsString();
         } else {
           assert(Init->isAnyMemberInitializer());
-          Value += Init->getMember()->getQualifiedNameAsString();
+          Value += getRelativeName(Init->getMember());
         }
         Value += ",";
       }
@@ -405,7 +446,7 @@ std::string SyntaxTree::Impl::getDeclVal
     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 +470,7 @@ std::string SyntaxTree::Impl::getStmtVal
   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 +482,7 @@ std::string SyntaxTree::Impl::getStmtVal
     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))
@@ -949,7 +990,7 @@ NodeId ASTDiff::getMapped(const SyntaxTr
   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)) {}
 

Modified: cfe/trunk/test/Tooling/clang-diff-ast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Tooling/clang-diff-ast.cpp?rev=311433&r1=311432&r2=311433&view=diff
==============================================================================
--- cfe/trunk/test/Tooling/clang-diff-ast.cpp (original)
+++ cfe/trunk/test/Tooling/clang-diff-ast.cpp Tue Aug 22 01:56:26 2017
@@ -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 @@ void f() {
   auto b = true;
   // CHECK: CallExpr(
   // CHECK-NOT: ImplicitCastExpr
-  // CHECK: DeclRefExpr: test::f(
+  // CHECK: DeclRefExpr: :f(
   f();
   // CHECK: UnaryOperator: ++(
   ++i;
@@ -41,7 +41,7 @@ class Base {
 // 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 @@ public:
   int not_initialized;
   // All initialized members, bases and delegating initializers are are
   // appended, separated by commas.
-  // CHECK: CXXConstructorDecl: X::X(void (char, int){{( __attribute__\(\(thiscall\)\))?}})Base,X::m,(
+  // CHECK: CXXConstructorDecl: :X(void (char, int){{( __attribute__\(\(thiscall\)\))?}})Base,:m,(
   X(char c, int) : Base(), m(0) {
-    // CHECK: MemberExpr: X::m(
+    // CHECK: MemberExpr: :m(
     int x = m;
   }
-  // CHECK: CXXConstructorDecl: X::X(void (char){{( __attribute__\(\(thiscall\)\))?}})X,(
+  // CHECK: CXXConstructorDecl: :X(void (char){{( __attribute__\(\(thiscall\)\))?}})X,(
   X(char s) : X(s, 4) {}
 };
 

Modified: cfe/trunk/test/Tooling/clang-diff-basic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Tooling/clang-diff-basic.cpp?rev=311433&r1=311432&r2=311433&view=diff
==============================================================================
--- cfe/trunk/test/Tooling/clang-diff-basic.cpp (original)
+++ cfe/trunk/test/Tooling/clang-diff-basic.cpp Tue Aug 22 01:56:26 2017
@@ -11,18 +11,18 @@ void foo() {
 }
 }
 
-// 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

Modified: cfe/trunk/test/Tooling/clang-diff-html.test
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Tooling/clang-diff-html.test?rev=311433&r1=311432&r2=311433&view=diff
==============================================================================
--- cfe/trunk/test/Tooling/clang-diff-html.test (original)
+++ cfe/trunk/test/Tooling/clang-diff-html.test Tue Aug 22 01:56:26 2017
@@ -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

Modified: cfe/trunk/test/Tooling/clang-diff-topdown.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Tooling/clang-diff-topdown.cpp?rev=311433&r1=311432&r2=311433&view=diff
==============================================================================
--- cfe/trunk/test/Tooling/clang-diff-topdown.cpp (original)
+++ cfe/trunk/test/Tooling/clang-diff-topdown.cpp Tue Aug 22 01:56:26 2017
@@ -27,8 +27,19 @@ void f1()
   {{;;}}
 }
 
+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 @@ void f1() {
   ;
 }
 
+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




More information about the cfe-commits mailing list