forked from OSchip/llvm-project
Instantiate attributes from the pattern record when instantiating
a class template. Fixes rdar://problem/8243419. llvm-svn: 109967
This commit is contained in:
parent
d9900542a6
commit
6602bb1115
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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<AlignedAttr>(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<Expr>());
|
||||
AddAlignedAttr(Aligned->getAlignmentExpr()->getExprLoc(),
|
||||
New, Result.takeAs<Expr>());
|
||||
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<TypedefDecl>(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;
|
||||
}
|
||||
|
|
|
@ -11,3 +11,16 @@ struct A {
|
|||
int a[sizeof(A<int>) == 16 ? 1 : -1];
|
||||
int a2[sizeof(A<int>::B) == 16 ? 1 : -1];
|
||||
|
||||
// rdar://problem/8243419
|
||||
namespace test1 {
|
||||
template <typename T> struct A {
|
||||
int a;
|
||||
T b[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef A<unsigned long> 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];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue