From 2109d436abdb0408b2bd8b76602eb7a478e9dbbd Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Tue, 23 May 2017 16:23:28 +0000 Subject: [PATCH] [index] The references to records from template instantiations should refer to the pattern records in the base templates rdar://32325459 llvm-svn: 303646 --- clang/lib/Index/IndexingContext.cpp | 5 +++++ clang/test/Index/Core/index-instantiated-source.cpp | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/clang/lib/Index/IndexingContext.cpp b/clang/lib/Index/IndexingContext.cpp index 5cebb19..b9f991d 100644 --- a/clang/lib/Index/IndexingContext.cpp +++ b/clang/lib/Index/IndexingContext.cpp @@ -124,6 +124,9 @@ bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) { TKind = FD->getTemplateSpecializationKind(); } else if (auto *VD = dyn_cast(D)) { TKind = VD->getTemplateSpecializationKind(); + } else if (const auto *RD = dyn_cast(D)) { + if (RD->getInstantiatedFromMemberClass()) + TKind = RD->getTemplateSpecializationKind(); } else if (isa(D)) { if (const auto *Parent = dyn_cast(D->getDeclContext())) @@ -163,6 +166,8 @@ static const Decl *adjustTemplateImplicitInstantiation(const Decl *D) { return FD->getTemplateInstantiationPattern(); } else if (auto *VD = dyn_cast(D)) { return VD->getTemplateInstantiationPattern(); + } else if (const auto *RD = dyn_cast(D)) { + return RD->getInstantiatedFromMemberClass(); } else if (const auto *FD = dyn_cast(D)) { if (const auto *Parent = dyn_cast(D->getDeclContext())) { diff --git a/clang/test/Index/Core/index-instantiated-source.cpp b/clang/test/Index/Core/index-instantiated-source.cpp index f61795d..a1fe4a3 100644 --- a/clang/test/Index/Core/index-instantiated-source.cpp +++ b/clang/test/Index/Core/index-instantiated-source.cpp @@ -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 @@ -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 &object) { @@ -36,4 +48,13 @@ void canonicalizeInstaniationReferences(TemplateClass &object) { TemplateClass::staticFunction(); // CHECK: [[@LINE-1]]:30 | static-method/C++ | staticFunction | c:@ST>2#T#T@TemplateClass@F@staticFunction#S | ::NestedBaseType nestedBaseType; +// CHECK: [[@LINE-1]]:30 | struct/C | NestedBaseType | c:@ST>1#T@BaseTemplate@S@NestedBaseType | + TemplateClass::NestedType nestedSubType; +// CHECK: [[@LINE-1]]:30 | struct/C++ | NestedType | c:@ST>2#T#T@TemplateClass@S@NestedType | + typedef TemplateClass 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 | } -- 2.7.4