From: Fariborz Jahanian Date: Fri, 24 Jul 2009 17:57:02 +0000 (+0000) Subject: More work toward initialization of objects X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=50b8eea3f36881a988a5757e0f6e15d45900324b;p=clang More work toward initialization of objects in constructors. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76980 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index ed08a60a88..8ad8aede60 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_DECLCXX_H #define LLVM_CLANG_AST_DECLCXX_H +#include "clang/AST/Expr.h" #include "clang/AST/Decl.h" #include "llvm/ADT/SmallVector.h" @@ -733,7 +734,7 @@ class CXXBaseOrMemberInitializer { uintptr_t BaseOrMember; /// Args - The arguments used to initialize the base or member. - Expr **Args; + Stmt **Args; unsigned NumArgs; /// CtorToCall - For a base or member needing a constructor for their @@ -761,11 +762,11 @@ public: /// arg_iterator - Iterates through the member initialization /// arguments. - typedef Expr **arg_iterator; + typedef ExprIterator arg_iterator; /// arg_const_iterator - Iterates through the member initialization /// arguments. - typedef Expr * const * arg_const_iterator; + typedef ConstExprIterator const_arg_iterator; /// getBaseOrMember - get the generic 'member' representing either the field /// or a base class. @@ -811,19 +812,19 @@ public: return 0; } - CXXConstructorDecl *getConstructor() const { return CtorToCall; } + const CXXConstructorDecl *getConstructor() const { return CtorToCall; } SourceLocation getSourceLocation() const { return IdLoc; } - /// begin() - Retrieve an iterator to the first initializer argument. - arg_iterator begin() { return Args; } - /// begin() - Retrieve an iterator to the first initializer argument. - arg_const_iterator begin() const { return Args; } + /// arg_begin() - Retrieve an iterator to the first initializer argument. + arg_iterator arg_begin() { return Args; } + /// arg_begin() - Retrieve an iterator to the first initializer argument. + const_arg_iterator const_arg_begin() const { return Args; } - /// end() - Retrieve an iterator past the last initializer argument. - arg_iterator end() { return Args + NumArgs; } - /// end() - Retrieve an iterator past the last initializer argument. - arg_const_iterator end() const { return Args + NumArgs; } + /// arg_end() - Retrieve an iterator past the last initializer argument. + arg_iterator arg_end() { return Args + NumArgs; } + /// arg_end() - Retrieve an iterator past the last initializer argument. + const_arg_iterator const_arg_end() const { return Args + NumArgs; } /// getNumArgs - Determine the number of arguments used to /// initialize the member or base. diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 4d861be9fd..7bbc76cb83 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -389,7 +389,8 @@ CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs, if (NumArgs > 0) { this->NumArgs = NumArgs; - this->Args = new Expr*[NumArgs]; + // FIXME. Allocation via Context + this->Args = new Stmt*[NumArgs]; for (unsigned Idx = 0; Idx < NumArgs; ++Idx) this->Args[Idx] = Args[Idx]; } @@ -406,7 +407,7 @@ CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs, if (NumArgs > 0) { this->NumArgs = NumArgs; - this->Args = new Expr*[NumArgs]; + this->Args = new Stmt*[NumArgs]; for (unsigned Idx = 0; Idx < NumArgs; ++Idx) this->Args[Idx] = Args[Idx]; } diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index fcc623ec78..589cdeca8a 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -346,7 +346,8 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { CXXBaseOrMemberInitializer * BMInitializer = (*B); if (B != CDecl->init_begin()) Out << ", "; - bool hasArguments = (BMInitializer->begin() != BMInitializer->end()); + bool hasArguments = (BMInitializer->arg_begin() != + BMInitializer->arg_end()); if (BMInitializer->isMemberInitializer()) { FieldDecl *FD = BMInitializer->getMember(); Out << FD->getNameAsString(); @@ -360,12 +361,12 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { } if (hasArguments) { Out << "("; - for (CXXBaseOrMemberInitializer::arg_const_iterator BE = - BMInitializer->begin(), EE = BMInitializer->end(); - BE != EE; BE++) { - if (BE != BMInitializer->begin()) + for (CXXBaseOrMemberInitializer::const_arg_iterator BE = + BMInitializer->const_arg_begin(), + EE = BMInitializer->const_arg_end(); BE != EE; ++BE) { + if (BE != BMInitializer->const_arg_begin()) Out<< ", "; - Expr *Exp = (*BE); + const Expr *Exp = (*BE); Exp->printPretty(Out, Context, 0, Policy, Indentation); } Out << ")"; diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 4a2db05532..2349171ae7 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -432,13 +432,22 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) { QualType FieldType = getContext().getCanonicalType((Field)->getType()); assert(!getContext().getAsArrayType(FieldType) && "FIXME. Field arrays initialization unsupported"); - assert(!FieldType->getAsRecordType() - && "FIXME. Field class initialization unsupported"); + llvm::Value *LoadOfThis = LoadCXXThis(); LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0); + if (FieldType->getAsRecordType()) { + + assert(Member->getConstructor() && + "EmitCtorPrologue - no constructor to initialize member"); + EmitCXXConstructorCall(Member->getConstructor(), + Ctor_Complete, LHS.getAddress(), + Member->const_arg_begin(), + Member->const_arg_end()); + continue; + } assert(Member->getNumArgs() == 1 && "Initializer count must be 1 only"); - Expr *RhsExpr = *Member->begin(); + Expr *RhsExpr = *Member->arg_begin(); llvm::Value *RHS = EmitScalarExpr(RhsExpr, true); if (LHS.isBitfield()) EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, FieldType, 0);