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 | 30398dd4108f8c5376e863ca665e29098f68db57 (patch) | |
| tree | 86bde3fcc7abb002511ec81bff0ceb19f34087b0 /clang/lib | |
| parent | 52ee45d64a7f5c0aec52f1f04a93884f6dd6b4ed (diff) | |
| download | bcm5719-llvm-30398dd4108f8c5376e863ca665e29098f68db57.tar.gz bcm5719-llvm-30398dd4108f8c5376e863ca665e29098f68db57.zip | |
Delayed template instantiation of late-parsed attributes.
llvm-svn: 148595
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 23 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 25 |
3 files changed, 43 insertions, 7 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 00a03390da6..ad31cbd6431 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -857,7 +857,7 @@ void Parser::ParseThreadSafetyAttribute(IdentifierInfo &AttrName, ConsumeToken(); // Eat the comma, move to the next argument } // Match the ')'. - if (ArgExprsOk && !T.consumeClose() && ArgExprs.size() > 0) { + if (ArgExprsOk && !T.consumeClose()) { Attrs.addNew(&AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(), ArgExprs.take(), ArgExprs.size()); } diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index a41878fcc1c..2b96a1c7447 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1654,6 +1654,10 @@ Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation, return Invalid; } +// Defined via #include from SemaTemplateInstantiateDecl.cpp +Attr* instantiateTemplateAttribute(const Attr *At, ASTContext &C, Sema &S, + const MultiLevelTemplateArgumentList &TemplateArgs); + /// \brief Instantiate the definition of a class from a given pattern. /// /// \param PointOfInstantiation The point of instantiation within the @@ -1763,6 +1767,10 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, SmallVector<Decl*, 4> Fields; SmallVector<std::pair<FieldDecl*, FieldDecl*>, 4> FieldsWithMemberInitializers; + // Delay instantiation of late parsed attributes. + LateInstantiatedAttrVec LateAttrs; + Instantiator.enableLateAttributeInstantiation(&LateAttrs); + for (RecordDecl::decl_iterator Member = Pattern->decls_begin(), MemberEnd = Pattern->decls_end(); Member != MemberEnd; ++Member) { @@ -1822,6 +1830,21 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, } } + // Instantiate late parsed attributes, and attach them to their decls. + // See Sema::InstantiateAttrs + for (LateInstantiatedAttrVec::iterator I = LateAttrs.begin(), + E = LateAttrs.end(); I != E; ++I) { + assert(CurrentInstantiationScope == Instantiator.getStartingScope()); + CurrentInstantiationScope = I->Scope; + Attr *NewAttr = + instantiateTemplateAttribute(I->TmplAttr, Context, *this, TemplateArgs); + I->NewDecl->addAttr(NewAttr); + LocalInstantiationScope::deleteScopes(I->Scope, + Instantiator.getStartingScope()); + } + Instantiator.disableLateAttributeInstantiation(); + LateAttrs.clear(); + if (!FieldsWithMemberInitializers.empty()) ActOnFinishDelayedMemberInitializers(Instantiation); diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 60bcbfb255f..c9d2cf6e18e 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/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; } |

