Early ir-gen for constructor prologue. This is on going.
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 20 Jul 2009 22:35:22 +0000 (22:35 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 20 Jul 2009 22:35:22 +0000 (22:35 +0000)
llvm-svn: 76493

clang/lib/CodeGen/CodeGenFunction.cpp
clang/lib/CodeGen/CodeGenFunction.h

index 3a689a43062b698f52e378e6f7a0f86a099367ac..4bfebe5c31d1d5589c1046f824bb8c0c5c65e1d6 100644 (file)
@@ -141,6 +141,39 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
   Ptr->eraseFromParent();
 }
 
+/// 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(), 
+       E = CD->init_end();
+       B != E; ++B) {
+    CXXBaseOrMemberInitializer *Member = (*B);
+    if (Member->isBaseInitializer()) {
+      // FIXME. Added base initialilzers here.
+      ;
+    }
+    else {
+      // non-static data member initilaizers.
+      FieldDecl *Field = Member->getMember();
+      QualType FieldType = getContext().getCanonicalType((Field)->getType());
+      assert(!getContext().getAsArrayType(FieldType) 
+             && "Field arrays initialization unsupported");
+      assert(!FieldType->getAsRecordType() 
+             && "Field class initialization unsupported");
+      llvm::Value *LoadOfThis = LoadCXXThis();
+      LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
+      
+      assert(Member->getNumArgs() == 1 && "Initializer count must be 1 only");
+      Expr *RhsExpr = *Member->begin();
+      llvm::Value *RHS = EmitScalarExpr(RhsExpr, true);
+      if (LHS.isBitfield())
+        EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, FieldType, 0);
+      else
+        EmitStoreThroughLValue(RValue::get(RHS), LHS, FieldType);
+    }
+  }
+}
+
 void CodeGenFunction::StartFunction(const Decl *D, QualType RetTy, 
                                     llvm::Function *Fn,
                                     const FunctionArgList &Args,
@@ -229,6 +262,8 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD,
   // FIXME: Support CXXTryStmt here, too.
   if (const CompoundStmt *S = FD->getCompoundBody()) {
     StartFunction(FD, FD->getResultType(), Fn, Args, S->getLBracLoc());
+    if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD))
+      EmitCtorPrologue(CD);
     EmitStmt(S);
     FinishFunction(S->getRBracLoc());
   }
index f2de3f6acbf360feb72a1751ea24cafdc5d11399..6e905e48ac01bc2df4efbc81f4c95e16a93860a6 100644 (file)
@@ -358,6 +358,8 @@ public:
   /// legal to call this function even if there is no current insertion point.
   void FinishFunction(SourceLocation EndLoc=SourceLocation());
 
+  void EmitCtorPrologue(const CXXConstructorDecl *CD);
+
   /// EmitFunctionProlog - Emit the target specific LLVM code to load the
   /// arguments for the given function. This is also responsible for naming the
   /// LLVM function arguments.