From 2a1b5af130ae3dd8d9d94f30e6356e2b0bc85dbe Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 24 Jul 2009 17:57:02 +0000 Subject: [PATCH] More work toward initialization of objects in constructors. llvm-svn: 76980 --- clang/include/clang/AST/DeclCXX.h | 25 +++++++++++++------------ clang/lib/AST/DeclCXX.cpp | 5 +++-- clang/lib/AST/DeclPrinter.cpp | 13 +++++++------ clang/lib/CodeGen/CGCXX.cpp | 15 ++++++++++++--- 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index ed08a60..8ad8aed 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/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/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 4d861be..7bbc76c 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/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/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index fcc623e..589cdec 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/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/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index 4a2db05..2349171 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/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); -- 2.7.4