aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateInstantiate.cpp
diff options
context:
space:
mode:
authorDeLesley Hutchins <delesley@google.com>2012-09-26 17:57:31 +0000
committerDeLesley Hutchins <delesley@google.com>2012-09-26 17:57:31 +0000
commitd278dbe43aff06865ae3388ba6b4ac5a9d68e179 (patch)
tree97579dbd1670758712de90789213d7a28bfcda01 /lib/Sema/SemaTemplateInstantiate.cpp
parentfb9a0ede96023d18af24ee98854db9606fdafb5c (diff)
Fix template instantiation of attributes. More specifically, fix the case
where an attribute is attached to a forward declaration of a template function, and refers to parameters of that declaration, but is then inherited by the definition of that function. When the definition is instantiated, the parameter references need to be remapped. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164710 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 621f92bb67..665dd07b8f 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2635,8 +2635,25 @@ bool Sema::Subst(const TemplateArgumentLoc *Args, unsigned NumArgs,
return Instantiator.TransformTemplateArguments(Args, NumArgs, Result);
}
+
+static const Decl* getCanonicalParmVarDecl(const Decl *D) {
+ // When storing ParmVarDecls in the local instantiation scope, we always
+ // want to use the ParmVarDecl from the canonical function declaration,
+ // since the map is then valid for any redeclaration or definition of that
+ // function.
+ if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(D)) {
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
+ unsigned i = PV->getFunctionScopeIndex();
+ return FD->getCanonicalDecl()->getParamDecl(i);
+ }
+ }
+ return D;
+}
+
+
llvm::PointerUnion<Decl *, LocalInstantiationScope::DeclArgumentPack *> *
LocalInstantiationScope::findInstantiationOf(const Decl *D) {
+ D = getCanonicalParmVarDecl(D);
for (LocalInstantiationScope *Current = this; Current;
Current = Current->Outer) {
@@ -2668,6 +2685,7 @@ LocalInstantiationScope::findInstantiationOf(const Decl *D) {
}
void LocalInstantiationScope::InstantiatedLocal(const Decl *D, Decl *Inst) {
+ D = getCanonicalParmVarDecl(D);
llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = LocalDecls[D];
if (Stored.isNull())
Stored = Inst;
@@ -2680,11 +2698,13 @@ void LocalInstantiationScope::InstantiatedLocal(const Decl *D, Decl *Inst) {
void LocalInstantiationScope::InstantiatedLocalPackArg(const Decl *D,
Decl *Inst) {
+ D = getCanonicalParmVarDecl(D);
DeclArgumentPack *Pack = LocalDecls[D].get<DeclArgumentPack *>();
Pack->push_back(Inst);
}
void LocalInstantiationScope::MakeInstantiatedLocalArgPack(const Decl *D) {
+ D = getCanonicalParmVarDecl(D);
llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = LocalDecls[D];
assert(Stored.isNull() && "Already instantiated this local");
DeclArgumentPack *Pack = new DeclArgumentPack;