forked from OSchip/llvm-project
When instantiating anonymous structs/unions within a function, make
sure that the anonymous struct/union record declaration gets instantiated before the variable declaration, and that it and its fields (recursively) get entries in the local instantiation map. Fixes PR7088. llvm-svn: 104305
This commit is contained in:
parent
95dff818e7
commit
04163186a7
|
@ -323,6 +323,13 @@ static bool InstantiateInitializer(Sema &S, Expr *Init,
|
||||||
}
|
}
|
||||||
|
|
||||||
Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
|
Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
|
||||||
|
// If this is the variable for an anonymous struct or union,
|
||||||
|
// instantiate the anonymous struct/union type first.
|
||||||
|
if (const RecordType *RecordTy = D->getType()->getAs<RecordType>())
|
||||||
|
if (RecordTy->getDecl()->isAnonymousStructOrUnion())
|
||||||
|
if (!VisitCXXRecordDecl(cast<CXXRecordDecl>(RecordTy->getDecl())))
|
||||||
|
return 0;
|
||||||
|
|
||||||
// Do substitution on the type of the declaration
|
// Do substitution on the type of the declaration
|
||||||
TypeSourceInfo *DI = SemaRef.SubstType(D->getTypeSourceInfo(),
|
TypeSourceInfo *DI = SemaRef.SubstType(D->getTypeSourceInfo(),
|
||||||
TemplateArgs,
|
TemplateArgs,
|
||||||
|
@ -491,6 +498,11 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
|
||||||
// Keep track of where this decl came from.
|
// Keep track of where this decl came from.
|
||||||
SemaRef.Context.setInstantiatedFromUnnamedFieldDecl(Field, D);
|
SemaRef.Context.setInstantiatedFromUnnamedFieldDecl(Field, D);
|
||||||
}
|
}
|
||||||
|
if (CXXRecordDecl *Parent= dyn_cast<CXXRecordDecl>(Field->getDeclContext())) {
|
||||||
|
if (Parent->isAnonymousStructOrUnion() &&
|
||||||
|
Parent->getLookupContext()->isFunctionOrMethod())
|
||||||
|
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Field);
|
||||||
|
}
|
||||||
|
|
||||||
Field->setImplicit(D->isImplicit());
|
Field->setImplicit(D->isImplicit());
|
||||||
Field->setAccess(D->getAccess());
|
Field->setAccess(D->getAccess());
|
||||||
|
@ -913,7 +925,12 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
|
||||||
if (Decl::FriendObjectKind FOK = D->getFriendObjectKind())
|
if (Decl::FriendObjectKind FOK = D->getFriendObjectKind())
|
||||||
Record->setObjectOfFriendDecl(FOK == Decl::FOK_Declared);
|
Record->setObjectOfFriendDecl(FOK == Decl::FOK_Declared);
|
||||||
|
|
||||||
Record->setAnonymousStructOrUnion(D->isAnonymousStructOrUnion());
|
// Make sure that anonymous structs and unions are recorded.
|
||||||
|
if (D->isAnonymousStructOrUnion()) {
|
||||||
|
Record->setAnonymousStructOrUnion(true);
|
||||||
|
if (Record->getDeclContext()->getLookupContext()->isFunctionOrMethod())
|
||||||
|
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Record);
|
||||||
|
}
|
||||||
|
|
||||||
Owner->addDecl(Record);
|
Owner->addDecl(Record);
|
||||||
return Record;
|
return Record;
|
||||||
|
|
|
@ -29,3 +29,21 @@ template <typename T> struct C {
|
||||||
};
|
};
|
||||||
|
|
||||||
C<int> c0(0);
|
C<int> c0(0);
|
||||||
|
|
||||||
|
namespace PR7088 {
|
||||||
|
template<typename T>
|
||||||
|
void f() {
|
||||||
|
union {
|
||||||
|
int a;
|
||||||
|
union {
|
||||||
|
float real;
|
||||||
|
T d;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
a = 17;
|
||||||
|
d = 3.14;
|
||||||
|
}
|
||||||
|
|
||||||
|
template void f<double>();
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue