diff options
author | DeLesley Hutchins <delesley@google.com> | 2012-01-20 22:50:54 +0000 |
---|---|---|
committer | DeLesley Hutchins <delesley@google.com> | 2012-01-20 22:50:54 +0000 |
commit | 23323e0253716ff03c95a00fb6903019daafe3aa (patch) | |
tree | 765f6ebb8f08a68f2881021e582472a27fcb1d24 /lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | 7b9ff0c09025dcbe48ec7db71330e2066d1e1863 (diff) |
Delayed template instantiation of late-parsed attributes.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148595 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 60bcbfb255..c9d2cf6e18 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -61,10 +61,13 @@ bool TemplateDeclInstantiator::SubstQualifier(const TagDecl *OldDecl, #include "clang/Sema/AttrTemplateInstantiate.inc" void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, - const Decl *Tmpl, Decl *New) { + const Decl *Tmpl, Decl *New, + LateInstantiatedAttrVec *LateAttrs, + LocalInstantiationScope *OuterMostScope) { for (AttrVec::const_iterator i = Tmpl->attr_begin(), e = Tmpl->attr_end(); i != e; ++i) { const Attr *TmplAttr = *i; + // FIXME: This should be generalized to more than just the AlignedAttr. if (const AlignedAttr *Aligned = dyn_cast<AlignedAttr>(TmplAttr)) { if (Aligned->isAlignmentDependent()) { @@ -89,9 +92,18 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, } } - Attr *NewAttr = - instantiateTemplateAttribute(TmplAttr, Context, *this, TemplateArgs); - New->addAttr(NewAttr); + if (TmplAttr->isLateParsed() && LateAttrs) { + // Late parsed attributes must be instantiated and attached after the + // enclosing class has been instantiated. See Sema::InstantiateClass. + LocalInstantiationScope *Saved = 0; + if (CurrentInstantiationScope) + Saved = CurrentInstantiationScope->cloneScopes(OuterMostScope); + LateAttrs->push_back(LateInstantiatedAttribute(TmplAttr, Saved, New)); + } else { + Attr *NewAttr = + instantiateTemplateAttribute(TmplAttr, Context, *this, TemplateArgs); + New->addAttr(NewAttr); + } } } @@ -495,7 +507,7 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) { return 0; } - SemaRef.InstantiateAttrs(TemplateArgs, D, Field); + SemaRef.InstantiateAttrs(TemplateArgs, D, Field, LateAttrs, StartingScope); if (Invalid) Field->setInvalidDecl(); @@ -2378,7 +2390,8 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, // Get the definition. Leaves the variable unchanged if undefined. Tmpl->isDefined(Definition); - SemaRef.InstantiateAttrs(TemplateArgs, Definition, New); + SemaRef.InstantiateAttrs(TemplateArgs, Definition, New, + LateAttrs, StartingScope); return false; } |