From: Anders Carlsson Date: Tue, 1 Sep 2009 06:22:14 +0000 (+0000) Subject: Don't assume that a base is always a RecordType, it can also be a TemplateSpecializat... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cdc83c777973fa56b6f828bfe88210290ca58d62;p=clang Don't assume that a base is always a RecordType, it can also be a TemplateSpecializationType. Also, make sure to get the instantiated union member. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80662 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 4acde29b7b..f22a3e88b7 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -912,11 +912,21 @@ static void *GetKeyForTopLevelField(FieldDecl *Field) { return static_cast(Field); } +static void *GetKeyForBase(QualType BaseType) { + if (const RecordType *RT = BaseType->getAs()) + return (void *)RT; + + assert(0 && "Unexpected base type!"); + return 0; +} + static void *GetKeyForMember(CXXBaseOrMemberInitializer *Member, - bool MemberMaybeAnon=false) { + bool MemberMaybeAnon = false) { // For fields injected into the class via declaration of an anonymous union, // use its anonymous union class declaration as the unique key. - if (FieldDecl *Field = Member->getMember()) { + if (Member->isMemberInitializer()) { + FieldDecl *Field = Member->getMember(); + // After BuildBaseOrMemberInitializers call, Field is the anonymous union // data member of the class. Data member used in the initializer list is // in AnonUnionMember field. @@ -929,7 +939,8 @@ static void *GetKeyForMember(CXXBaseOrMemberInitializer *Member, } return static_cast(Field); } - return static_cast(Member->getBaseClass()); + + return GetKeyForBase(QualType(Member->getBaseClass(), 0)); } void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, @@ -1003,7 +1014,7 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, for (CXXRecordDecl::base_class_iterator VBase = ClassDecl->vbases_begin(), E = ClassDecl->vbases_end(); VBase != E; ++VBase) - AllBaseOrMembers.push_back(VBase->getType()->getAs()); + AllBaseOrMembers.push_back(GetKeyForBase(VBase->getType())); for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), E = ClassDecl->bases_end(); Base != E; ++Base) { @@ -1011,7 +1022,7 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, // first. if (Base->isVirtual()) continue; - AllBaseOrMembers.push_back(Base->getType()->getAs()); + AllBaseOrMembers.push_back(GetKeyForBase(Base->getType())); } for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 82228143e4..99b237d04e 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1145,7 +1145,6 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New, QualType BaseType(Init->getBaseClass(), 0); BaseType = SubstType(BaseType, TemplateArgs, Init->getSourceLocation(), New->getDeclName()); - BaseType = Context.getCanonicalType(BaseType); NewInit = BuildBaseInitializer(BaseType, (Expr **)NewArgs.data(), @@ -1158,7 +1157,7 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New, // Is this an anonymous union? if (FieldDecl *UnionInit = Init->getAnonUnionMember()) - Member = cast(UnionInit); + Member = cast(FindInstantiatedDecl(UnionInit)); else Member = cast(FindInstantiatedDecl(Init->getMember())); diff --git a/test/SemaTemplate/instantiate-anonymous-union.cpp b/test/SemaTemplate/instantiate-anonymous-union.cpp index 2c1e9d4c19..375c1da3ca 100644 --- a/test/SemaTemplate/instantiate-anonymous-union.cpp +++ b/test/SemaTemplate/instantiate-anonymous-union.cpp @@ -1,6 +1,4 @@ -// RUN: clang-cc -fsyntax-only %s - -// FIXME: We need to test anonymous structs/unions in templates for real. +// RUN: clang-cc -fsyntax-only %s -Wall template class A { struct { }; }; @@ -30,4 +28,4 @@ template struct C { C(void* b) : b(b) { } }; -C c0; +C c0(0);