r355668 - [clang][Index] Mark references from Constructors and Destructors to class as NameReference

Kadir Cetinkaya via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 8 00:30:21 PST 2019


Author: kadircet
Date: Fri Mar  8 00:30:20 2019
New Revision: 355668

URL: http://llvm.org/viewvc/llvm-project?rev=355668&view=rev
Log:
[clang][Index] Mark references from Constructors and Destructors to class as NameReference

Summary:
In current indexing logic we get references to class itself when we see
a constructor/destructor which is only syntactically true. Semantically
this information is not correct. This patch marks that reference as
NameReference to let clients deal with it.

Reviewers: akyrtzi, gribozavr, nathawes, benlangmuir

Reviewed By: gribozavr, nathawes

Subscribers: nathawes, arphaman, cfe-commits

Tags: #clang

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

Modified:
    cfe/trunk/include/clang/Index/IndexSymbol.h
    cfe/trunk/lib/Index/IndexDecl.cpp
    cfe/trunk/lib/Index/IndexSymbol.cpp
    cfe/trunk/lib/Index/IndexingContext.cpp
    cfe/trunk/test/Index/Core/index-source.cpp
    cfe/trunk/unittests/Index/IndexTests.cpp

Modified: cfe/trunk/include/clang/Index/IndexSymbol.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Index/IndexSymbol.h?rev=355668&r1=355667&r2=355668&view=diff
==============================================================================
--- cfe/trunk/include/clang/Index/IndexSymbol.h (original)
+++ cfe/trunk/include/clang/Index/IndexSymbol.h Fri Mar  8 00:30:20 2019
@@ -118,8 +118,12 @@ enum class SymbolRole : uint32_t {
   RelationContainedBy = 1 << 17,
   RelationIBTypeOf = 1 << 18,
   RelationSpecializationOf = 1 << 19,
+
+  // Symbol only references the name of the object as written. For example, a
+  // constructor references the class declaration using that role.
+  NameReference = 1 << 20,
 };
-static const unsigned SymbolRoleBitNum = 20;
+static const unsigned SymbolRoleBitNum = 21;
 typedef unsigned SymbolRoleSet;
 
 /// Represents a relation to another symbol for a symbol occurrence.

Modified: cfe/trunk/lib/Index/IndexDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/IndexDecl.cpp?rev=355668&r1=355667&r2=355668&view=diff
==============================================================================
--- cfe/trunk/lib/Index/IndexDecl.cpp (original)
+++ cfe/trunk/lib/Index/IndexDecl.cpp Fri Mar  8 00:30:20 2019
@@ -247,7 +247,8 @@ public:
 
     if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
       IndexCtx.handleReference(Ctor->getParent(), Ctor->getLocation(),
-                               Ctor->getParent(), Ctor->getDeclContext());
+                               Ctor->getParent(), Ctor->getDeclContext(),
+                               (unsigned)SymbolRole::NameReference);
 
       // Constructor initializers.
       for (const auto *Init : Ctor->inits()) {
@@ -263,7 +264,8 @@ public:
       if (auto TypeNameInfo = Dtor->getNameInfo().getNamedTypeInfo()) {
         IndexCtx.handleReference(Dtor->getParent(),
                                  TypeNameInfo->getTypeLoc().getBeginLoc(),
-                                 Dtor->getParent(), Dtor->getDeclContext());
+                                 Dtor->getParent(), Dtor->getDeclContext(),
+                                 (unsigned)SymbolRole::NameReference);
       }
     } else if (const auto *Guide = dyn_cast<CXXDeductionGuideDecl>(D)) {
       IndexCtx.handleReference(Guide->getDeducedTemplate()->getTemplatedDecl(),

Modified: cfe/trunk/lib/Index/IndexSymbol.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/IndexSymbol.cpp?rev=355668&r1=355667&r2=355668&view=diff
==============================================================================
--- cfe/trunk/lib/Index/IndexSymbol.cpp (original)
+++ cfe/trunk/lib/Index/IndexSymbol.cpp Fri Mar  8 00:30:20 2019
@@ -396,6 +396,7 @@ bool index::applyForEachSymbolRoleInterr
   APPLY_FOR_ROLE(RelationContainedBy);
   APPLY_FOR_ROLE(RelationIBTypeOf);
   APPLY_FOR_ROLE(RelationSpecializationOf);
+  APPLY_FOR_ROLE(NameReference);
 
 #undef APPLY_FOR_ROLE
 
@@ -438,6 +439,7 @@ void index::printSymbolRoles(SymbolRoleS
     case SymbolRole::RelationContainedBy: OS << "RelCont"; break;
     case SymbolRole::RelationIBTypeOf: OS << "RelIBType"; break;
     case SymbolRole::RelationSpecializationOf: OS << "RelSpecialization"; break;
+    case SymbolRole::NameReference: OS << "NameReference"; break;
     }
   });
 }

Modified: cfe/trunk/lib/Index/IndexingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/IndexingContext.cpp?rev=355668&r1=355667&r2=355668&view=diff
==============================================================================
--- cfe/trunk/lib/Index/IndexingContext.cpp (original)
+++ cfe/trunk/lib/Index/IndexingContext.cpp Fri Mar  8 00:30:20 2019
@@ -332,6 +332,7 @@ static bool shouldReportOccurrenceForSys
       case SymbolRole::RelationCalledBy:
       case SymbolRole::RelationContainedBy:
       case SymbolRole::RelationSpecializationOf:
+      case SymbolRole::NameReference:
         return true;
       }
       llvm_unreachable("Unsupported SymbolRole value!");

Modified: cfe/trunk/test/Index/Core/index-source.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Core/index-source.cpp?rev=355668&r1=355667&r2=355668&view=diff
==============================================================================
--- cfe/trunk/test/Index/Core/index-source.cpp (original)
+++ cfe/trunk/test/Index/Core/index-source.cpp Fri Mar  8 00:30:20 2019
@@ -5,17 +5,17 @@
 class Cls { public:
   // CHECK: [[@LINE+3]]:3 | constructor/C++ | Cls | c:@S at Cls@F at Cls#I# | __ZN3ClsC1Ei | Decl,RelChild | rel: 1
   // CHECK-NEXT: RelChild | Cls | c:@S at Cls
-  // CHECK: [[@LINE+1]]:3 | class/C++ | Cls | c:@S at Cls | <no-cgname> | Ref,RelCont | rel: 1
+  // CHECK: [[@LINE+1]]:3 | class/C++ | Cls | c:@S at Cls | <no-cgname> | Ref,RelCont,NameReference | rel: 1
   Cls(int x);
   // CHECK: [[@LINE+2]]:3 | constructor/cxx-copy-ctor/C++ | Cls | c:@S at Cls@F at Cls#&1$@S at Cls# | __ZN3ClsC1ERKS_ | Decl,RelChild | rel: 1
-  // CHECK: [[@LINE+1]]:3 | class/C++ | Cls | c:@S at Cls | <no-cgname> | Ref,RelCont | rel: 1
+  // CHECK: [[@LINE+1]]:3 | class/C++ | Cls | c:@S at Cls | <no-cgname> | Ref,RelCont,NameReference | rel: 1
   Cls(const Cls &);
   // CHECK: [[@LINE+2]]:3 | constructor/cxx-move-ctor/C++ | Cls | c:@S at Cls@F at Cls#&&$@S at Cls# | __ZN3ClsC1EOS_ | Decl,RelChild | rel: 1
-  // CHECK: [[@LINE+1]]:3 | class/C++ | Cls | c:@S at Cls | <no-cgname> | Ref,RelCont | rel: 1
+  // CHECK: [[@LINE+1]]:3 | class/C++ | Cls | c:@S at Cls | <no-cgname> | Ref,RelCont,NameReference | rel: 1
   Cls(Cls &&);
 
   // CHECK: [[@LINE+2]]:3 | destructor/C++ | ~Cls | c:@S at Cls@F@~Cls# | __ZN3ClsD1Ev | Decl,RelChild | rel: 1
-  // CHECK: [[@LINE+1]]:4 | class/C++ | Cls | c:@S at Cls | <no-cgname> | Ref,RelCont | rel: 1
+  // CHECK: [[@LINE+1]]:4 | class/C++ | Cls | c:@S at Cls | <no-cgname> | Ref,RelCont,NameReference | rel: 1
   ~Cls();
 };
 
@@ -35,12 +35,12 @@ class SubCls2 : public ClsAlias {};
 Cls::Cls(int x) {}
 // CHECK: [[@LINE-1]]:6 | constructor/C++ | Cls | c:@S at Cls@F at Cls#I# | __ZN3ClsC1Ei | Def,RelChild | rel: 1
 // CHECK: [[@LINE-2]]:1 | class/C++ | Cls | c:@S at Cls | <no-cgname> | Ref,RelCont | rel: 1
-// CHECK: [[@LINE-3]]:6 | class/C++ | Cls | c:@S at Cls | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-3]]:6 | class/C++ | Cls | c:@S at Cls | <no-cgname> | Ref,RelCont,NameReference | rel: 1
 
 Cls::~/*a comment*/Cls() {}
 // CHECK: [[@LINE-1]]:6 | destructor/C++ | ~Cls | c:@S at Cls@F@~Cls# | __ZN3ClsD1Ev | Def,RelChild | rel: 1
 // CHECK: [[@LINE-2]]:1 | class/C++ | Cls | c:@S at Cls | <no-cgname> | Ref,RelCont | rel: 1
-// CHECK: [[@LINE-3]]:20 | class/C++ | Cls | c:@S at Cls | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-3]]:20 | class/C++ | Cls | c:@S at Cls | <no-cgname> | Ref,RelCont,NameReference | rel: 1
 
 template <typename TemplArg>
 class TemplCls {
@@ -394,7 +394,7 @@ struct DeletedMethods {
 // CHECK: [[@LINE-1]]:3 | constructor/cxx-copy-ctor/C++ | DeletedMethods | c:@S at DeletedMethods@F at DeletedMethods#&1$@S at DeletedMethods# | __ZN14DeletedMethodsC1ERKS_ | Def,RelChild | rel: 1
 // CHECK: RelChild | DeletedMethods | c:@S at DeletedMethods
 // CHECK: [[@LINE-3]]:24 | struct/C++ | DeletedMethods | c:@S at DeletedMethods | <no-cgname> | Ref,RelCont | rel: 1
-// CHECK: [[@LINE-4]]:3 | struct/C++ | DeletedMethods | c:@S at DeletedMethods | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-4]]:3 | struct/C++ | DeletedMethods | c:@S at DeletedMethods | <no-cgname> | Ref,RelCont,NameReference | rel: 1
 };
 
 namespace ns2 {
@@ -494,7 +494,7 @@ void localStructuredBindingAndRef() {
 // CHECK: [[@LINE-1]]:69 | variable/C++ | structuredBinding2 | c:@N at cpp17structuredBinding@structuredBinding2 | <no-cgname> | Ref,Read,RelCont | rel: 1
 // CHECK-NEXT: RelCont | localStructuredBindingAndRef | c:@N at cpp17structuredBinding@F at localStructuredBindingAndRef#
 // CHECK-NOT: localBinding
-// LOCAL: [[@LINE-4]]:9 | variable(local)/C++ | localBinding1 | c:index-source.cpp at 25408@N at cpp17structuredBinding@F at localStructuredBindingAndRef#@localBinding1
+// LOCAL: [[@LINE-4]]:9 | variable(local)/C++ | localBinding1 | c:index-source.cpp@{{.*}}@N at cpp17structuredBinding@F at localStructuredBindingAndRef#@localBinding1
 }
 
 }

Modified: cfe/trunk/unittests/Index/IndexTests.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Index/IndexTests.cpp?rev=355668&r1=355667&r2=355668&view=diff
==============================================================================
--- cfe/trunk/unittests/Index/IndexTests.cpp (original)
+++ cfe/trunk/unittests/Index/IndexTests.cpp Fri Mar  8 00:30:20 2019
@@ -58,11 +58,13 @@ struct TestSymbol {
   Position WrittenPos;
   Position DeclPos;
   SymbolInfo SymInfo;
+  SymbolRoleSet Roles;
   // FIXME: add more information.
 };
 
 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const TestSymbol &S) {
-  return OS << S.QName << '[' << S.WrittenPos << ']' << '@' << S.DeclPos;
+  return OS << S.QName << '[' << S.WrittenPos << ']' << '@' << S.DeclPos << '('
+            << static_cast<unsigned>(S.SymInfo.Kind) << ')';
 }
 
 class Indexer : public IndexDataConsumer {
@@ -84,6 +86,7 @@ public:
     S.WrittenPos = Position::fromSourceLocation(Loc, AST->getSourceManager());
     S.DeclPos =
         Position::fromSourceLocation(D->getLocation(), AST->getSourceManager());
+    S.Roles = Roles;
     Symbols.push_back(std::move(S));
     return true;
   }
@@ -143,6 +146,7 @@ MATCHER_P(QName, Name, "") { return arg.
 MATCHER_P(WrittenAt, Pos, "") { return arg.WrittenPos == Pos; }
 MATCHER_P(DeclAt, Pos, "") { return arg.DeclPos == Pos; }
 MATCHER_P(Kind, SymKind, "") { return arg.SymInfo.Kind == SymKind; }
+MATCHER_P(HasRole, Role, "") { return arg.Roles & static_cast<unsigned>(Role); }
 
 TEST(IndexTest, Simple) {
   auto Index = std::make_shared<Indexer>();
@@ -257,6 +261,32 @@ TEST(IndexTest, UsingDecls) {
               Contains(AllOf(QName("std::foo"), Kind(SymbolKind::Using))));
 }
 
+TEST(IndexTest, Constructors) {
+  std::string Code = R"cpp(
+    struct Foo {
+      Foo(int);
+      ~Foo();
+    };
+  )cpp";
+  auto Index = std::make_shared<Indexer>();
+  IndexingOptions Opts;
+  tooling::runToolOnCode(new IndexAction(Index, Opts), Code);
+  EXPECT_THAT(
+      Index->Symbols,
+      UnorderedElementsAre(
+          AllOf(QName("Foo"), Kind(SymbolKind::Struct),
+                WrittenAt(Position(2, 12))),
+          AllOf(QName("Foo::Foo"), Kind(SymbolKind::Constructor),
+                WrittenAt(Position(3, 7))),
+          AllOf(QName("Foo"), Kind(SymbolKind::Struct),
+                HasRole(SymbolRole::NameReference), WrittenAt(Position(3, 7))),
+          AllOf(QName("Foo::~Foo"), Kind(SymbolKind::Destructor),
+                WrittenAt(Position(4, 7))),
+          AllOf(QName("Foo"), Kind(SymbolKind::Struct),
+                HasRole(SymbolRole::NameReference),
+                WrittenAt(Position(4, 8)))));
+}
+
 } // namespace
 } // namespace index
 } // namespace clang




More information about the cfe-commits mailing list