From 1d8d1ccd36888f1120b3a1df9e76f35dc2edb81d Mon Sep 17 00:00:00 2001 From: John McCall Date: Sun, 1 Aug 2010 02:01:53 +0000 Subject: [PATCH] Instantiate attributes from the pattern record when instantiating a class template. Fixes rdar://problem/8243419. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109967 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/Sema.h | 3 +++ lib/Sema/SemaTemplateInstantiate.cpp | 3 +++ lib/Sema/SemaTemplateInstantiateDecl.cpp | 25 ++++++++++++------------ test/SemaTemplate/instantiate-attr.cpp | 13 ++++++++++++ 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index ecd167d9a0..f676304b2f 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -3905,6 +3905,9 @@ public: TemplateSpecializationKind TSK, bool Complain = true); + void InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, + Decl *Pattern, Decl *Inst); + bool InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation, ClassTemplateSpecializationDecl *ClassTemplateSpec, diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 60b8e927fd..1a22abb2a1 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -1206,6 +1206,9 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, bool MergeWithParentScope = !Instantiation->isDefinedOutsideFunctionOrMethod(); Sema::LocalInstantiationScope Scope(*this, MergeWithParentScope); + // Pull attributes from the pattern onto the instantiation. + InstantiateAttrs(TemplateArgs, Pattern, Instantiation); + // Start the definition of this instantiation. Instantiation->startDefinition(); diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index d1503695bc..ad96d7ae4e 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -31,8 +31,6 @@ namespace { DeclContext *Owner; const MultiLevelTemplateArgumentList &TemplateArgs; - void InstantiateAttrs(Decl *Tmpl, Decl *New); - public: typedef Sema::OwningExprResult OwningExprResult; @@ -144,28 +142,29 @@ bool TemplateDeclInstantiator::SubstQualifier(const TagDecl *OldDecl, } // FIXME: Is this still too simple? -void TemplateDeclInstantiator::InstantiateAttrs(Decl *Tmpl, Decl *New) { +void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, + Decl *Tmpl, Decl *New) { for (const Attr *TmplAttr = Tmpl->getAttrs(); TmplAttr; TmplAttr = TmplAttr->getNext()) { // FIXME: This should be generalized to more than just the AlignedAttr. if (const AlignedAttr *Aligned = dyn_cast(TmplAttr)) { if (Aligned->isDependent()) { // The alignment expression is not potentially evaluated. - EnterExpressionEvaluationContext Unevaluated(SemaRef, + EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated); - OwningExprResult Result = SemaRef.SubstExpr(Aligned->getAlignmentExpr(), - TemplateArgs); + OwningExprResult Result = SubstExpr(Aligned->getAlignmentExpr(), + TemplateArgs); if (!Result.isInvalid()) // FIXME: Is this the correct source location? - SemaRef.AddAlignedAttr(Aligned->getAlignmentExpr()->getExprLoc(), - New, Result.takeAs()); + AddAlignedAttr(Aligned->getAlignmentExpr()->getExprLoc(), + New, Result.takeAs()); continue; } } // FIXME: Is cloning correct for all attributes? - Attr *NewAttr = TmplAttr->clone(SemaRef.Context); + Attr *NewAttr = TmplAttr->clone(Context); New->addAttr(NewAttr); } } @@ -234,7 +233,7 @@ Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) { Typedef->setPreviousDeclaration(cast(InstPrev)); } - InstantiateAttrs(D, Typedef); + SemaRef.InstantiateAttrs(TemplateArgs, D, Typedef); Typedef->setAccess(D->getAccess()); Owner->addDecl(Typedef); @@ -399,7 +398,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { if (Owner->isFunctionOrMethod()) SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Var); } - InstantiateAttrs(D, Var); + SemaRef.InstantiateAttrs(TemplateArgs, D, Var); // Link instantiations of static data members back to the template from // which they were instantiated. @@ -518,7 +517,7 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) { return 0; } - InstantiateAttrs(D, Field); + SemaRef.InstantiateAttrs(TemplateArgs, D, Field); if (Invalid) Field->setInvalidDecl(); @@ -1975,7 +1974,7 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, Proto->getExtInfo())); } - InstantiateAttrs(Tmpl, New); + SemaRef.InstantiateAttrs(TemplateArgs, Tmpl, New); return false; } diff --git a/test/SemaTemplate/instantiate-attr.cpp b/test/SemaTemplate/instantiate-attr.cpp index e8291ed00d..bbadb6375b 100644 --- a/test/SemaTemplate/instantiate-attr.cpp +++ b/test/SemaTemplate/instantiate-attr.cpp @@ -11,3 +11,16 @@ struct A { int a[sizeof(A) == 16 ? 1 : -1]; int a2[sizeof(A::B) == 16 ? 1 : -1]; +// rdar://problem/8243419 +namespace test1 { + template struct A { + int a; + T b[0]; + } __attribute__((packed)); + + typedef A type; + + int test0[sizeof(type) == 4 ? 1 : -1]; + int test1[__builtin_offsetof(type, a) == 0 ? 1 : -1]; + int test2[__builtin_offsetof(type, b) == 4 ? 1 : -1]; +} -- 2.40.0