From 04163186a7a1bcc6fcb5d1d96714f677cc7466d5 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 21 May 2010 00:31:19 +0000 Subject: 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 --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'clang/lib/Sema/SemaTemplateInstantiateDecl.cpp') diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 592b474dfb7..e8cbb66694f 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -323,6 +323,13 @@ static bool InstantiateInitializer(Sema &S, Expr *Init, } 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()) + if (RecordTy->getDecl()->isAnonymousStructOrUnion()) + if (!VisitCXXRecordDecl(cast(RecordTy->getDecl()))) + return 0; + // Do substitution on the type of the declaration TypeSourceInfo *DI = SemaRef.SubstType(D->getTypeSourceInfo(), TemplateArgs, @@ -490,6 +497,11 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) { if (!Field->getDeclName()) { // Keep track of where this decl came from. SemaRef.Context.setInstantiatedFromUnnamedFieldDecl(Field, D); + } + if (CXXRecordDecl *Parent= dyn_cast(Field->getDeclContext())) { + if (Parent->isAnonymousStructOrUnion() && + Parent->getLookupContext()->isFunctionOrMethod()) + SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Field); } Field->setImplicit(D->isImplicit()); @@ -913,7 +925,12 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) { if (Decl::FriendObjectKind FOK = D->getFriendObjectKind()) 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); return Record; -- cgit v1.2.3