]> granicus.if.org Git - clang/commitdiff
[index] The references to records from template instantiations should refer
authorAlex Lorenz <arphaman@gmail.com>
Tue, 23 May 2017 16:23:28 +0000 (16:23 +0000)
committerAlex Lorenz <arphaman@gmail.com>
Tue, 23 May 2017 16:23:28 +0000 (16:23 +0000)
to the pattern records in the base templates

rdar://32325459

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

lib/Index/IndexingContext.cpp
test/Index/Core/index-instantiated-source.cpp

index 5cebb198460ffc12d29ca094488e53d48bf12aaa..b9f991d6ba622c57e881cb48988b8ca704fc220a 100644 (file)
@@ -124,6 +124,9 @@ bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) {
     TKind = FD->getTemplateSpecializationKind();
   } else if (auto *VD = dyn_cast<VarDecl>(D)) {
     TKind = VD->getTemplateSpecializationKind();
+  } else if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
+    if (RD->getInstantiatedFromMemberClass())
+      TKind = RD->getTemplateSpecializationKind();
   } else if (isa<FieldDecl>(D)) {
     if (const auto *Parent =
             dyn_cast<ClassTemplateSpecializationDecl>(D->getDeclContext()))
@@ -163,6 +166,8 @@ static const Decl *adjustTemplateImplicitInstantiation(const Decl *D) {
     return FD->getTemplateInstantiationPattern();
   } else if (auto *VD = dyn_cast<VarDecl>(D)) {
     return VD->getTemplateInstantiationPattern();
+  } else if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
+    return RD->getInstantiatedFromMemberClass();
   } else if (const auto *FD = dyn_cast<FieldDecl>(D)) {
     if (const auto *Parent =
             dyn_cast<ClassTemplateSpecializationDecl>(D->getDeclContext())) {
index f61795da540cdf4cdfe7283d989caf128b17289b..a1fe4a340a18b6134ce0c58747001515c74b785e 100644 (file)
@@ -9,6 +9,9 @@ public:
 
   T baseTemplateField;
 // CHECK: [[@LINE-1]]:5 | field/C++ | baseTemplateField | c:@ST>1#T@BaseTemplate@FI@baseTemplateField
+
+  struct NestedBaseType { };
+// CHECK: [[@LINE-1]]:10 | struct/C | NestedBaseType | c:@ST>1#T@BaseTemplate@S@NestedBaseType |
 };
 
 template<typename T, typename S>
@@ -22,6 +25,15 @@ public:
 
   T field;
 // CHECK: [[@LINE-1]]:5 | field/C++ | field | c:@ST>2#T#T@TemplateClass@FI@field
+
+  struct NestedType {
+// CHECK: [[@LINE-1]]:10 | struct/C++ | NestedType | c:@ST>2#T#T@TemplateClass@S@NestedType |
+    class SubNestedType {
+// CHECK: [[@LINE-1]]:11 | class/C++ | SubNestedType | c:@ST>2#T#T@TemplateClass@S@NestedType@S@SubNestedType |
+    public:
+      SubNestedType(int);
+    };
+  };
 };
 
 void canonicalizeInstaniationReferences(TemplateClass<int, float> &object) {
@@ -36,4 +48,13 @@ void canonicalizeInstaniationReferences(TemplateClass<int, float> &object) {
 
   TemplateClass<int, float>::staticFunction();
 // CHECK: [[@LINE-1]]:30 | static-method/C++ | staticFunction | c:@ST>2#T#T@TemplateClass@F@staticFunction#S | <no-cgname
+
+  TemplateClass<int, float>::NestedBaseType nestedBaseType;
+// CHECK: [[@LINE-1]]:30 | struct/C | NestedBaseType | c:@ST>1#T@BaseTemplate@S@NestedBaseType |
+  TemplateClass<int, float>::NestedType nestedSubType;
+// CHECK: [[@LINE-1]]:30 | struct/C++ | NestedType | c:@ST>2#T#T@TemplateClass@S@NestedType |
+  typedef TemplateClass<int, float> TT;
+  TT::NestedType::SubNestedType subNestedType(0);
+// CHECK: [[@LINE-1]]:7 | struct/C++ | NestedType | c:@ST>2#T#T@TemplateClass@S@NestedType |
+// CHECK: [[@LINE-2]]:19 | class/C++ | SubNestedType | c:@ST>2#T#T@TemplateClass@S@NestedType@S@SubNestedType |
 }