[index] The references to fields from nested records in template instantiations
authorAlex Lorenz <arphaman@gmail.com>
Tue, 23 May 2017 16:25:06 +0000 (16:25 +0000)
committerAlex Lorenz <arphaman@gmail.com>
Tue, 23 May 2017 16:25:06 +0000 (16:25 +0000)
should refer to the pattern fields in the nested records in the base templates

rdar://32352429

llvm-svn: 303647

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

index b9f991d..1a341b0 100644 (file)
@@ -128,9 +128,8 @@ bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) {
     if (RD->getInstantiatedFromMemberClass())
       TKind = RD->getTemplateSpecializationKind();
   } else if (isa<FieldDecl>(D)) {
-    if (const auto *Parent =
-            dyn_cast<ClassTemplateSpecializationDecl>(D->getDeclContext()))
-      TKind = Parent->getSpecializationKind();
+    if (const auto *Parent = dyn_cast<Decl>(D->getDeclContext()))
+      return isTemplateImplicitInstantiation(Parent);
   }
   switch (TKind) {
     case TSK_Undeclared:
@@ -158,6 +157,16 @@ bool IndexingContext::shouldIgnoreIfImplicit(const Decl *D) {
   return true;
 }
 
+static const CXXRecordDecl *
+getDeclContextForTemplateInstationPattern(const Decl *D) {
+  if (const auto *CTSD =
+          dyn_cast<ClassTemplateSpecializationDecl>(D->getDeclContext()))
+    return CTSD->getTemplateInstantiationPattern();
+  else if (const auto *RD = dyn_cast<CXXRecordDecl>(D->getDeclContext()))
+    return RD->getInstantiatedFromMemberClass();
+  return nullptr;
+}
+
 static const Decl *adjustTemplateImplicitInstantiation(const Decl *D) {
   if (const ClassTemplateSpecializationDecl *
       SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
@@ -169,9 +178,8 @@ static const Decl *adjustTemplateImplicitInstantiation(const Decl *D) {
   } 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())) {
-      const CXXRecordDecl *Pattern = Parent->getTemplateInstantiationPattern();
+    if (const CXXRecordDecl *Pattern =
+            getDeclContextForTemplateInstationPattern(FD)) {
       for (const NamedDecl *ND : Pattern->lookup(FD->getDeclName())) {
         if (ND->isImplicit())
           continue;
index a1fe4a3..b0c9419 100644 (file)
@@ -28,6 +28,10 @@ public:
 
   struct NestedType {
 // CHECK: [[@LINE-1]]:10 | struct/C++ | NestedType | c:@ST>2#T#T@TemplateClass@S@NestedType |
+
+    T nestedField;
+// CHECK: [[@LINE-1]]:7 | field/C++ | nestedField | c:@ST>2#T#T@TemplateClass@S@NestedType@FI@nestedField |
+
     class SubNestedType {
 // CHECK: [[@LINE-1]]:11 | class/C++ | SubNestedType | c:@ST>2#T#T@TemplateClass@S@NestedType@S@SubNestedType |
     public:
@@ -53,6 +57,9 @@ void canonicalizeInstaniationReferences(TemplateClass<int, float> &object) {
 // 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 |
+  (void)nestedSubType.nestedField;
+// CHECK: [[@LINE-1]]:23 | field/C++ | nestedField | c:@ST>2#T#T@TemplateClass@S@NestedType@FI@nestedField |
+
   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 |