]> granicus.if.org Git - clang/commitdiff
[index] Record class template specializations using a new 'SpecializationOf'
authorAlex Lorenz <arphaman@gmail.com>
Thu, 20 Apr 2017 10:43:22 +0000 (10:43 +0000)
committerAlex Lorenz <arphaman@gmail.com>
Thu, 20 Apr 2017 10:43:22 +0000 (10:43 +0000)
relationship

rdar://31603531

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@300832 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Index/IndexSymbol.h
lib/Index/IndexDecl.cpp
lib/Index/IndexSymbol.cpp
lib/Index/IndexTypeSourceInfo.cpp
lib/Index/IndexingContext.cpp
lib/Index/IndexingContext.h
test/Index/Core/index-source.cpp

index 217d6b1fb1cce1c8b7899c0b0081b10578d72fba..bc34938fb405d57a14bdeb7f695f94ac2a53bedb 100644 (file)
@@ -106,8 +106,9 @@ enum class SymbolRole : uint32_t {
   RelationAccessorOf  = 1 << 15,
   RelationContainedBy = 1 << 16,
   RelationIBTypeOf    = 1 << 17,
+  RelationSpecializationOf = 1 << 18,
 };
-static const unsigned SymbolRoleBitNum = 18;
+static const unsigned SymbolRoleBitNum = 19;
 typedef unsigned SymbolRoleSet;
 
 /// Represents a relation to another symbol for a symbol occurrence.
index dae0cdc0d9c91fe8b6effb2698c6997bc31958c8..0e893505516f928ccf02c6bb6e67ed13f4868f8b 100644 (file)
@@ -495,8 +495,18 @@ public:
                                            ClassTemplateSpecializationDecl *D) {
     // FIXME: Notify subsequent callbacks if info comes from implicit
     // instantiation.
-    if (D->isThisDeclarationADefinition())
-      IndexCtx.indexTagDecl(D);
+    if (D->isThisDeclarationADefinition()) {
+      llvm::PointerUnion<ClassTemplateDecl *,
+                         ClassTemplatePartialSpecializationDecl *>
+          Template = D->getSpecializedTemplateOrPartial();
+      const Decl *SpecializationOf =
+          Template.is<ClassTemplateDecl *>()
+              ? (Decl *)Template.get<ClassTemplateDecl *>()
+              : Template.get<ClassTemplatePartialSpecializationDecl *>();
+      IndexCtx.indexTagDecl(
+          D, SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf),
+                            SpecializationOf));
+    }
     return true;
   }
 
index fe3c17845daa5dff0a309f6e64142875419bbb7f..ea66b7017951c4cc1889089308d9e32d01f029d0 100644 (file)
@@ -346,6 +346,7 @@ bool index::applyForEachSymbolRoleInterruptible(SymbolRoleSet Roles,
   APPLY_FOR_ROLE(RelationAccessorOf);
   APPLY_FOR_ROLE(RelationContainedBy);
   APPLY_FOR_ROLE(RelationIBTypeOf);
+  APPLY_FOR_ROLE(RelationSpecializationOf);
 
 #undef APPLY_FOR_ROLE
 
@@ -386,6 +387,7 @@ void index::printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS) {
     case SymbolRole::RelationAccessorOf: OS << "RelAcc"; break;
     case SymbolRole::RelationContainedBy: OS << "RelCont"; break;
     case SymbolRole::RelationIBTypeOf: OS << "RelIBType"; break;
+    case SymbolRole::RelationSpecializationOf: OS << "RelSpecialization"; break;
     }
   });
 }
index 0645d5be5268474da6a5cdb92d71e820924df65e..a3566a9f2ae878d1cf904f62c3583df0df48dbbb 100644 (file)
@@ -208,11 +208,12 @@ void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
   }
 }
 
-void IndexingContext::indexTagDecl(const TagDecl *D) {
+void IndexingContext::indexTagDecl(const TagDecl *D,
+                                   ArrayRef<SymbolRelation> Relations) {
   if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalSymbol(D))
     return;
 
-  if (handleDecl(D)) {
+  if (handleDecl(D, /*Roles=*/SymbolRoleSet(), Relations)) {
     if (D->isThisDeclarationADefinition()) {
       indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
       if (auto CXXRD = dyn_cast<CXXRecordDecl>(D)) {
index f393b11ab884768706bf27060f3a662da4ab9a0e..85574d0a314d7deef6f49aeb08a95d55525e8a84 100644 (file)
@@ -233,6 +233,7 @@ static bool shouldReportOccurrenceForSystemDeclOnlyMode(
       case SymbolRole::RelationReceivedBy:
       case SymbolRole::RelationCalledBy:
       case SymbolRole::RelationContainedBy:
+      case SymbolRole::RelationSpecializationOf:
         return true;
       }
       llvm_unreachable("Unsupported SymbolRole value!");
index 933b0a2cda0723575e900b60f06ee6b6575e4519..1ebf6f9ce67a73fa2f9556e76cbaf7e2b25ff763 100644 (file)
@@ -80,7 +80,8 @@ public:
 
   bool indexDecl(const Decl *D);
 
-  void indexTagDecl(const TagDecl *D);
+  void indexTagDecl(const TagDecl *D,
+                    ArrayRef<SymbolRelation> Relations = None);
 
   void indexTypeSourceInfo(TypeSourceInfo *TInfo, const NamedDecl *Parent,
                            const DeclContext *DC = nullptr,
index 356d4a08de3a7d220dc49687527933b97450821a..5d4a1be456832fc5964565820b89b2637265bd42 100644 (file)
@@ -50,6 +50,12 @@ public:
   // CHECK-NEXT: RelChild | TemplCls | c:@ST>1#T@TemplCls
 };
 
+template<>
+class TemplCls<double> {
+// CHECK: [[@LINE-1]]:7 | class(Gen,TS)/C++ | TemplCls | c:@S@TemplCls>#d | <no-cgname> | Def,RelSpecialization | rel: 1
+// CHECK: RelSpecialization | TemplCls | c:@ST>1#T@TemplCls
+};
+
 TemplCls<int> gtv(0);
 // CHECK: [[@LINE-1]]:1 | class(Gen)/C++ | TemplCls | c:@ST>1#T@TemplCls | <no-cgname> | Ref,RelCont | rel: 1
 
@@ -91,3 +97,17 @@ int gvi = tmplVar<int>;
 // CHECK: [[@LINE+2]]:5 | variable/C | gvf | c:@gvf | _gvf | Def | rel: 0
 // CHECK: [[@LINE+1]]:11 | variable(Gen)/C++ | tmplVar | c:index-source.cpp@VT>1#T@tmplVar | __ZL7tmplVar | Ref,Read,RelCont | rel: 1
 int gvf = tmplVar<float>;
+
+template<typename A, typename B>
+class PartialSpecilizationClass { };
+// CHECK: [[@LINE-1]]:7 | class(Gen)/C++ | PartialSpecilizationClass | c:@ST>2#T#T@PartialSpecilizationClass | <no-cgname> | Def | rel: 0
+
+template<typename B>
+class PartialSpecilizationClass<int, B *> { };
+// CHECK: [[@LINE-1]]:7 | class(Gen,TPS)/C++ | PartialSpecilizationClass | c:@SP>1#T@PartialSpecilizationClass>#I#*t0.0 | <no-cgname> | Def,RelSpecialization | rel: 1
+// CHECK-NEXT: RelSpecialization | PartialSpecilizationClass | c:@ST>2#T#T@PartialSpecilizationClass
+
+template<>
+class PartialSpecilizationClass<int, int> { };
+// CHECK: [[@LINE-1]]:7 | class(Gen,TS)/C++ | PartialSpecilizationClass | c:@S@PartialSpecilizationClass>#I#I | <no-cgname> | Def,RelSpecialization | rel: 1
+// CHECK-NEXT: RelSpecialization | PartialSpecilizationClass | c:@ST>2#T#T@PartialSpecilizationClass