diff options
| author | Fariborz Jahanian <fjahanian@apple.com> | 2009-07-25 21:12:28 +0000 | 
|---|---|---|
| committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-07-25 21:12:28 +0000 | 
| commit | dedf1e4b1ab988a12e734b27bd6b60ba11ce054a (patch) | |
| tree | 83e3b8396b9cb5847ade5ea37a716c5b8d1996e7 | |
| parent | 60f3b73e1119d985732c70df930deac9c45b205c (diff) | |
| download | bcm5719-llvm-dedf1e4b1ab988a12e734b27bd6b60ba11ce054a.tar.gz bcm5719-llvm-dedf1e4b1ab988a12e734b27bd6b60ba11ce054a.zip  | |
ir-gen for non-virtual base class initialization
in constructors.
llvm-svn: 77087
| -rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGCXX.cpp | 34 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenTypes.cpp | 8 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/constructor-init.cpp | 49 | 
4 files changed, 90 insertions, 4 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 1dcc4f84650..e78b3156754 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -53,6 +53,9 @@ void ASTRecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *RD) {    // Round up the current record size to the base's alignment boundary.    Size = (Size + (BaseAlign-1)) & ~(BaseAlign-1); +  // Non-virtual base class has offset too. +  FieldOffsets.push_back(Size); +    // Reserve space for this base.    Size += BaseSize; diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index 724364f5e23..dd32cad21b8 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -17,6 +17,7 @@  #include "CodeGenModule.h"  #include "Mangle.h"  #include "clang/AST/ASTContext.h" +#include "clang/AST/RecordLayout.h"  #include "clang/AST/Decl.h"  #include "clang/AST/DeclCXX.h"  #include "clang/AST/DeclObjC.h" @@ -418,13 +419,40 @@ const char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D,  /// EmitCtorPrologue - This routine generates necessary code to initialize  /// base classes and non-static data members belonging to this constructor.  void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) { -  for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(),  +  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext()); +  assert(ClassDecl->vbases_begin() == ClassDecl->vbases_end() +         && "FIXME. virtual base initialization unsupported"); +  const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl); +  llvm::Type *I8Ptr = VMContext.getPointerTypeUnqual(llvm::Type::Int8Ty); +  unsigned FieldNo = 0; +  for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(),         E = CD->init_end();         B != E; ++B) {      CXXBaseOrMemberInitializer *Member = (*B);      if (Member->isBaseInitializer()) { -      // FIXME. Added base initialilzers here. -      assert(false && "FIXME. base initialization unsupported"); +      uint64_t Offset = Layout.getFieldOffset(FieldNo++) / 8; +      assert(Member->getConstructor() &&  +             "EmitCtorPrologue - no constructor to initialize base class"); +      llvm::Value *LoadOfThis = LoadCXXThis(); +      llvm::LLVMContext &VMContext = getLLVMContext(); +      llvm::Value *V; +      if (Offset > 0) { +        llvm::Value *OffsetVal = llvm::ConstantInt::get(llvm::Type::Int32Ty, +                                                        Offset); +        V = Builder.CreateBitCast(LoadOfThis, I8Ptr); +        V = Builder.CreateGEP(V, OffsetVal, "add.ptr"); +      } +      else +        V = Builder.CreateBitCast(LoadOfThis, I8Ptr); + +      const llvm::Type *BasePtr =  +        ConvertType(QualType(Member->getBaseClass(), 0)); +      BasePtr = VMContext.getPointerTypeUnqual(BasePtr); +      V = Builder.CreateBitCast(V, BasePtr); +      EmitCXXConstructorCall(Member->getConstructor(), +                             Ctor_Complete, V, +                             Member->const_arg_begin(),  +                             Member->const_arg_end());      }      else {        // non-static data member initilaizers. diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index 0869b2d11c0..21c7c38eee1 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -14,6 +14,7 @@  #include "CodeGenTypes.h"  #include "clang/AST/ASTContext.h"  #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclCXX.h"  #include "clang/AST/Expr.h"  #include "clang/AST/RecordLayout.h"  #include "llvm/DerivedTypes.h" @@ -545,8 +546,13 @@ void RecordOrganizer::layoutStructFields(const ASTRecordLayout &RL) {    uint64_t llvmSize = 0;    // FIXME: Make this a SmallVector    std::vector<const llvm::Type*> LLVMFields; - +      unsigned curField = 0; +  // Adjust by number of bases. +  // FIXME. This will probably change when virtual bases are supported. +  if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(&RD)) +    curField += CXXRD->getNumBases(); +        for (RecordDecl::field_iterator Field = RD.field_begin(),                                 FieldEnd = RD.field_end();         Field != FieldEnd; ++Field) { diff --git a/clang/test/CodeGenCXX/constructor-init.cpp b/clang/test/CodeGenCXX/constructor-init.cpp new file mode 100644 index 00000000000..d2c33aef547 --- /dev/null +++ b/clang/test/CodeGenCXX/constructor-init.cpp @@ -0,0 +1,49 @@ +// RUN: clang-cc %s -emit-llvm -o %t + +extern "C" int printf(...); + +struct M { +  M() { printf("M()\n"); } +  M(int i) { iM = i; printf("M(%d)\n", i); } +  int iM; +  void MPR() {printf("iM = %d\n", iM); }; +}; + +struct P { +  P() { printf("P()\n"); } +  P(int i) { iP = i; printf("P(%d)\n", i); } +  int iP; +  void PPR() {printf("iP = %d\n", iP); }; +}; + +struct Q { +  Q() { printf("Q()\n"); } +  Q(int i) { iQ = i; printf("Q(%d)\n", i); } +  int iQ; +  void QPR() {printf("iQ = %d\n", iQ); }; +}; + +struct N : M , P, Q { +  N() : f1(1.314), P(2000), ld(00.1234+f1), M(1000), Q(3000), +        d1(3.4567), i1(1234), m1(100) { printf("N()\n"); } +  M m1; +  M m2; +  float f1; +  int i1; +  float d1; +  void PR() { printf("f1 = %f d1 = %f i1 = %d ld = %f \n", f1,d1,i1, ld);  +	      MPR(); +	      PPR(); +              QPR(); +            } +  float ld; +  float ff; +}; + +int main() { +  M m1; + +  N n1; +  n1.PR(); +} +  | 

