From: Anders Carlsson Date: Mon, 12 Apr 2010 00:51:03 +0000 (+0000) Subject: Have the CXXBaseOrMemberInitializer keep track of whether an initializer initializes... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=80638c5e6395344c1e6096542b0ff3b8bfb2139e;p=clang Have the CXXBaseOrMemberInitializer keep track of whether an initializer initializes a virtual base or not. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101004 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 9f110748d5..29587a9b01 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -1057,6 +1057,10 @@ class CXXBaseOrMemberInitializer { /// and AnonUnionMember holds field decl for au_i1. FieldDecl *AnonUnionMember; + /// IsVirtual - If the initializer is a base initializer, this keeps track + /// of whether the base is virtual or not. + bool IsVirtual; + /// LParenLoc - Location of the left paren of the ctor-initializer. SourceLocation LParenLoc; @@ -1067,7 +1071,7 @@ public: /// CXXBaseOrMemberInitializer - Creates a new base-class initializer. explicit CXXBaseOrMemberInitializer(ASTContext &Context, - TypeSourceInfo *TInfo, + TypeSourceInfo *TInfo, bool IsVirtual, SourceLocation L, Expr *Init, SourceLocation R); @@ -1100,7 +1104,14 @@ public: /// Otherwise, returns NULL. const Type *getBaseClass() const; Type *getBaseClass(); - + + /// Returns whether the base is virtual or not. + bool isBaseVirtual() const { + assert(isBaseInitializer() && "Must call this on base initializer!"); + + return IsVirtual; + } + /// \brief Returns the declarator information for a base class initializer. TypeSourceInfo *getBaseClassInfo() const { return BaseOrMember.dyn_cast(); diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 94ed85c7cd..28489d39c5 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -686,9 +686,9 @@ bool CXXMethodDecl::hasInlineBody() const { CXXBaseOrMemberInitializer:: CXXBaseOrMemberInitializer(ASTContext &Context, - TypeSourceInfo *TInfo, + TypeSourceInfo *TInfo, bool IsVirtual, SourceLocation L, Expr *Init, SourceLocation R) - : BaseOrMember(TInfo), Init(Init), AnonUnionMember(0), + : BaseOrMember(TInfo), Init(Init), AnonUnionMember(0), IsVirtual(IsVirtual), LParenLoc(L), RParenLoc(R) { } diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 177e862304..7ca8f29b7e 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -782,15 +782,7 @@ static void EmitBaseInitializer(CodeGenFunction &CGF, CXXRecordDecl *BaseClassDecl = cast(BaseType->getAs()->getDecl()); - // FIXME: This method of determining whether a base is virtual is ridiculous; - // it should be part of BaseInit. - bool isBaseVirtual = false; - for (CXXRecordDecl::base_class_const_iterator I = ClassDecl->vbases_begin(), - E = ClassDecl->vbases_end(); I != E; ++I) - if (I->getType()->getAs()->getDecl() == BaseClassDecl) { - isBaseVirtual = true; - break; - } + bool isBaseVirtual = BaseInit->isBaseVirtual(); // The base constructor doesn't construct virtual bases. if (CtorType == Ctor_Base && isBaseVirtual) @@ -976,8 +968,6 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, llvm::SmallVector MemberInitializers; - // FIXME: Add vbase initialization - for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(), E = CD->init_end(); B != E; ++B) { diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index d68351cc38..0b26e9be3a 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1337,6 +1337,7 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo, ExprTemporaries.end()); return new (Context) CXXBaseOrMemberInitializer(Context, BaseTInfo, + /*IsVirtual=*/false, LParenLoc, BaseInit.takeAs(), RParenLoc); @@ -1417,12 +1418,14 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo, = Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs, RParenLoc)); return new (Context) CXXBaseOrMemberInitializer(Context, BaseTInfo, + BaseSpec->isVirtual(), LParenLoc, Init.takeAs(), RParenLoc); } return new (Context) CXXBaseOrMemberInitializer(Context, BaseTInfo, + BaseSpec->isVirtual(), LParenLoc, BaseInit.takeAs(), RParenLoc); @@ -1494,6 +1497,7 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor, new (Context) CXXBaseOrMemberInitializer(Context, Context.getTrivialTypeSourceInfo(VBase->getType(), SourceLocation()), + /*IsVirtual=*/true, SourceLocation(), BaseInit.takeAs(), SourceLocation()); @@ -1528,6 +1532,7 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor, new (Context) CXXBaseOrMemberInitializer(Context, Context.getTrivialTypeSourceInfo(Base->getType(), SourceLocation()), + /*IsVirtual=*/false, SourceLocation(), BaseInit.takeAs(), SourceLocation());