Skip to content

Commit 6602bb1

Browse files
committed
Instantiate attributes from the pattern record when instantiating
a class template. Fixes rdar://problem/8243419. llvm-svn: 109967
1 parent d990054 commit 6602bb1

File tree

4 files changed

+31
-13
lines changed

4 files changed

+31
-13
lines changed

clang/lib/Sema/Sema.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3905,6 +3905,9 @@ class Sema : public Action {
39053905
TemplateSpecializationKind TSK,
39063906
bool Complain = true);
39073907

3908+
void InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
3909+
Decl *Pattern, Decl *Inst);
3910+
39083911
bool
39093912
InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation,
39103913
ClassTemplateSpecializationDecl *ClassTemplateSpec,

clang/lib/Sema/SemaTemplateInstantiate.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,9 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
12061206
bool MergeWithParentScope = !Instantiation->isDefinedOutsideFunctionOrMethod();
12071207
Sema::LocalInstantiationScope Scope(*this, MergeWithParentScope);
12081208

1209+
// Pull attributes from the pattern onto the instantiation.
1210+
InstantiateAttrs(TemplateArgs, Pattern, Instantiation);
1211+
12091212
// Start the definition of this instantiation.
12101213
Instantiation->startDefinition();
12111214

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ namespace {
3131
DeclContext *Owner;
3232
const MultiLevelTemplateArgumentList &TemplateArgs;
3333

34-
void InstantiateAttrs(Decl *Tmpl, Decl *New);
35-
3634
public:
3735
typedef Sema::OwningExprResult OwningExprResult;
3836

@@ -144,28 +142,29 @@ bool TemplateDeclInstantiator::SubstQualifier(const TagDecl *OldDecl,
144142
}
145143

146144
// FIXME: Is this still too simple?
147-
void TemplateDeclInstantiator::InstantiateAttrs(Decl *Tmpl, Decl *New) {
145+
void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
146+
Decl *Tmpl, Decl *New) {
148147
for (const Attr *TmplAttr = Tmpl->getAttrs(); TmplAttr;
149148
TmplAttr = TmplAttr->getNext()) {
150149
// FIXME: This should be generalized to more than just the AlignedAttr.
151150
if (const AlignedAttr *Aligned = dyn_cast<AlignedAttr>(TmplAttr)) {
152151
if (Aligned->isDependent()) {
153152
// The alignment expression is not potentially evaluated.
154-
EnterExpressionEvaluationContext Unevaluated(SemaRef,
153+
EnterExpressionEvaluationContext Unevaluated(*this,
155154
Action::Unevaluated);
156155

157-
OwningExprResult Result = SemaRef.SubstExpr(Aligned->getAlignmentExpr(),
158-
TemplateArgs);
156+
OwningExprResult Result = SubstExpr(Aligned->getAlignmentExpr(),
157+
TemplateArgs);
159158
if (!Result.isInvalid())
160159
// FIXME: Is this the correct source location?
161-
SemaRef.AddAlignedAttr(Aligned->getAlignmentExpr()->getExprLoc(),
162-
New, Result.takeAs<Expr>());
160+
AddAlignedAttr(Aligned->getAlignmentExpr()->getExprLoc(),
161+
New, Result.takeAs<Expr>());
163162
continue;
164163
}
165164
}
166165

167166
// FIXME: Is cloning correct for all attributes?
168-
Attr *NewAttr = TmplAttr->clone(SemaRef.Context);
167+
Attr *NewAttr = TmplAttr->clone(Context);
169168
New->addAttr(NewAttr);
170169
}
171170
}
@@ -234,7 +233,7 @@ Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
234233
Typedef->setPreviousDeclaration(cast<TypedefDecl>(InstPrev));
235234
}
236235

237-
InstantiateAttrs(D, Typedef);
236+
SemaRef.InstantiateAttrs(TemplateArgs, D, Typedef);
238237

239238
Typedef->setAccess(D->getAccess());
240239
Owner->addDecl(Typedef);
@@ -399,7 +398,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
399398
if (Owner->isFunctionOrMethod())
400399
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Var);
401400
}
402-
InstantiateAttrs(D, Var);
401+
SemaRef.InstantiateAttrs(TemplateArgs, D, Var);
403402

404403
// Link instantiations of static data members back to the template from
405404
// which they were instantiated.
@@ -518,7 +517,7 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
518517
return 0;
519518
}
520519

521-
InstantiateAttrs(D, Field);
520+
SemaRef.InstantiateAttrs(TemplateArgs, D, Field);
522521

523522
if (Invalid)
524523
Field->setInvalidDecl();
@@ -1975,7 +1974,7 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,
19751974
Proto->getExtInfo()));
19761975
}
19771976

1978-
InstantiateAttrs(Tmpl, New);
1977+
SemaRef.InstantiateAttrs(TemplateArgs, Tmpl, New);
19791978

19801979
return false;
19811980
}

clang/test/SemaTemplate/instantiate-attr.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,16 @@ struct A {
1111
int a[sizeof(A<int>) == 16 ? 1 : -1];
1212
int a2[sizeof(A<int>::B) == 16 ? 1 : -1];
1313

14+
// rdar://problem/8243419
15+
namespace test1 {
16+
template <typename T> struct A {
17+
int a;
18+
T b[0];
19+
} __attribute__((packed));
20+
21+
typedef A<unsigned long> type;
22+
23+
int test0[sizeof(type) == 4 ? 1 : -1];
24+
int test1[__builtin_offsetof(type, a) == 0 ? 1 : -1];
25+
int test2[__builtin_offsetof(type, b) == 4 ? 1 : -1];
26+
}

0 commit comments

Comments
 (0)