forked from OSchip/llvm-project
[index] References to fields from template instantiations should refer to
fields in base templates rdar://32197158 llvm-svn: 303068
This commit is contained in:
parent
96a13635f5
commit
048c8a9e7f
|
@ -124,6 +124,10 @@ bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) {
|
|||
TKind = FD->getTemplateSpecializationKind();
|
||||
} else if (auto *VD = dyn_cast<VarDecl>(D)) {
|
||||
TKind = VD->getTemplateSpecializationKind();
|
||||
} else if (isa<FieldDecl>(D)) {
|
||||
if (const auto *Parent =
|
||||
dyn_cast<ClassTemplateSpecializationDecl>(D->getDeclContext()))
|
||||
TKind = Parent->getSpecializationKind();
|
||||
}
|
||||
switch (TKind) {
|
||||
case TSK_Undeclared:
|
||||
|
@ -159,6 +163,17 @@ 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 *FD = dyn_cast<FieldDecl>(D)) {
|
||||
if (const auto *Parent =
|
||||
dyn_cast<ClassTemplateSpecializationDecl>(D->getDeclContext())) {
|
||||
const CXXRecordDecl *Pattern = Parent->getTemplateInstantiationPattern();
|
||||
for (const NamedDecl *ND : Pattern->lookup(FD->getDeclName())) {
|
||||
if (ND->isImplicit())
|
||||
continue;
|
||||
if (isa<FieldDecl>(ND))
|
||||
return ND;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
// RUN: c-index-test core -print-source-symbols -- %s -std=c++14 -target x86_64-apple-macosx10.7 | FileCheck %s
|
||||
// References to declarations in instantiations should be canonicalized:
|
||||
|
||||
template<typename T>
|
||||
class BaseTemplate {
|
||||
public:
|
||||
T baseTemplateFunction();
|
||||
// CHECK: [[@LINE-1]]:5 | instance-method/C++ | baseTemplateFunction | c:@ST>1#T@BaseTemplate@F@baseTemplateFunction#
|
||||
|
||||
T baseTemplateField;
|
||||
// CHECK: [[@LINE-1]]:5 | field/C++ | baseTemplateField | c:@ST>1#T@BaseTemplate@FI@baseTemplateField
|
||||
};
|
||||
|
||||
template<typename T, typename S>
|
||||
class TemplateClass: public BaseTemplate<T> {
|
||||
public:
|
||||
T function() { return T(); }
|
||||
// CHECK: [[@LINE-1]]:5 | instance-method/C++ | function | c:@ST>2#T#T@TemplateClass@F@function#
|
||||
|
||||
static void staticFunction() { }
|
||||
// CHECK: [[@LINE-1]]:15 | static-method/C++ | staticFunction | c:@ST>2#T#T@TemplateClass@F@staticFunction#S
|
||||
|
||||
T field;
|
||||
// CHECK: [[@LINE-1]]:5 | field/C++ | field | c:@ST>2#T#T@TemplateClass@FI@field
|
||||
};
|
||||
|
||||
void canonicalizeInstaniationReferences(TemplateClass<int, float> &object) {
|
||||
(void)object.function();
|
||||
// CHECK: [[@LINE-1]]:16 | instance-method/C++ | function | c:@ST>2#T#T@TemplateClass@F@function# | <no-cgname>
|
||||
(void)object.field;
|
||||
// CHECK: [[@LINE-1]]:16 | field/C++ | field | c:@ST>2#T#T@TemplateClass@FI@field | <no-cgname> | Ref,RelCont | rel: 1
|
||||
(void)object.baseTemplateFunction();
|
||||
// CHECK: [[@LINE-1]]:16 | instance-method/C++ | baseTemplateFunction | c:@ST>1#T@BaseTemplate@F@baseTemplateFunction# | <no-cgname>
|
||||
(void)object.baseTemplateField;
|
||||
// CHECK: [[@LINE-1]]:16 | field/C++ | baseTemplateField | c:@ST>1#T@BaseTemplate@FI@baseTemplateField | <no-cgname> | Ref,RelCont | rel: 1
|
||||
|
||||
TemplateClass<int, float>::staticFunction();
|
||||
// CHECK: [[@LINE-1]]:30 | static-method/C++ | staticFunction | c:@ST>2#T#T@TemplateClass@F@staticFunction#S | <no-cgname
|
||||
}
|
Loading…
Reference in New Issue