[cfe-commits] r150451 - in /cfe/trunk: include/clang/AST/DeclCXX.h lib/CodeGen/CGClass.cpp

Eli Friedman eli.friedman at gmail.com
Mon Feb 13 18:15:49 PST 2012


Author: efriedma
Date: Mon Feb 13 20:15:49 2012
New Revision: 150451

URL: http://llvm.org/viewvc/llvm-project?rev=150451&view=rev
Log:
Refactor out new function EmitInitializerForField from EmitMemberInitializer.  The new function will be used to initialize the fields of lambda expressions.


Modified:
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/lib/CodeGen/CGClass.cpp

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=150451&r1=150450&r2=150451&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Mon Feb 13 20:15:49 2012
@@ -1809,6 +1809,11 @@
     assert(I < getNumArrayIndices() && "Out of bounds member array index");
     reinterpret_cast<VarDecl **>(this + 1)[I] = Index;
   }
+  ArrayRef<VarDecl *> getArrayIndexes() {
+    assert(getNumArrayIndices() != 0 && "Getting indexes for non-array init");
+    return ArrayRef<VarDecl *>(reinterpret_cast<VarDecl **>(this + 1),
+                               getNumArrayIndices());
+  }
 
   /// \brief Get the initializer. This is 0 if this is an in-class initializer
   /// for a non-static data member which has not yet been parsed.

Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=150451&r1=150450&r2=150451&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Mon Feb 13 20:15:49 2012
@@ -412,11 +412,12 @@
 
 static void EmitAggMemberInitializer(CodeGenFunction &CGF,
                                      LValue LHS,
+                                     Expr *Init,
                                      llvm::Value *ArrayIndexVar,
-                                     CXXCtorInitializer *MemberInit,
                                      QualType T,
+                                     ArrayRef<VarDecl *> ArrayIndexes,
                                      unsigned Index) {
-  if (Index == MemberInit->getNumArrayIndices()) {
+  if (Index == ArrayIndexes.size()) {
     CodeGenFunction::RunCleanupsScope Cleanups(CGF);
 
     LValue LV = LHS;
@@ -437,9 +438,9 @@
     }
 
     if (!CGF.hasAggregateLLVMType(T)) {
-      CGF.EmitScalarInit(MemberInit->getInit(), /*decl*/ 0, LV, false);
+      CGF.EmitScalarInit(Init, /*decl*/ 0, LV, false);
     } else if (T->isAnyComplexType()) {
-      CGF.EmitComplexExprIntoAddr(MemberInit->getInit(), LV.getAddress(),
+      CGF.EmitComplexExprIntoAddr(Init, LV.getAddress(),
                                   LV.isVolatileQualified());
     } else {
       AggValueSlot Slot =
@@ -448,7 +449,7 @@
                                 AggValueSlot::DoesNotNeedGCBarriers,
                                 AggValueSlot::IsNotAliased);
       
-      CGF.EmitAggExpr(MemberInit->getInit(), Slot);
+      CGF.EmitAggExpr(Init, Slot);
     }
     
     return;
@@ -457,7 +458,7 @@
   const ConstantArrayType *Array = CGF.getContext().getAsConstantArrayType(T);
   assert(Array && "Array initialization without the array type?");
   llvm::Value *IndexVar
-    = CGF.GetAddrOfLocalVar(MemberInit->getArrayIndex(Index));
+    = CGF.GetAddrOfLocalVar(ArrayIndexes[Index]);
   assert(IndexVar && "Array index variable not loaded");
   
   // Initialize this index variable to zero.
@@ -493,8 +494,8 @@
     
     // Inside the loop body recurse to emit the inner loop or, eventually, the
     // constructor call.
-    EmitAggMemberInitializer(CGF, LHS, ArrayIndexVar, MemberInit, 
-                             Array->getElementType(), Index + 1);
+    EmitAggMemberInitializer(CGF, LHS, Init, ArrayIndexVar,
+                             Array->getElementType(), ArrayIndexes, Index + 1);
   }
   
   CGF.EmitBlock(ContinueBlock);
@@ -514,19 +515,15 @@
 
 namespace {
   struct CallMemberDtor : EHScopeStack::Cleanup {
-    FieldDecl *Field;
+    llvm::Value *V;
     CXXDestructorDecl *Dtor;
 
-    CallMemberDtor(FieldDecl *Field, CXXDestructorDecl *Dtor)
-      : Field(Field), Dtor(Dtor) {}
+    CallMemberDtor(llvm::Value *V, CXXDestructorDecl *Dtor)
+      : V(V), Dtor(Dtor) {}
 
     void Emit(CodeGenFunction &CGF, Flags flags) {
-      // FIXME: Is this OK for C++0x delegating constructors?
-      llvm::Value *ThisPtr = CGF.LoadCXXThis();
-      LValue LHS = CGF.EmitLValueForField(ThisPtr, Field, 0);
-
       CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false,
-                                LHS.getAddress());
+                                V);
     }
   };
 }
@@ -536,7 +533,11 @@
   return Moving ? Record->hasTrivialMoveConstructor() :
                   Record->hasTrivialCopyConstructor();
 }
-  
+
+static void EmitInitializerForField(CodeGenFunction &CGF, FieldDecl *Field,
+                                    LValue LHS, Expr *Init,
+                                    ArrayRef<VarDecl *> ArrayIndexes);
+
 static void EmitMemberInitializer(CodeGenFunction &CGF,
                                   const CXXRecordDecl *ClassDecl,
                                   CXXCtorInitializer *MemberInit,
@@ -548,7 +549,7 @@
   
   // non-static data member initializers.
   FieldDecl *Field = MemberInit->getAnyMember();
-  QualType FieldType = CGF.getContext().getCanonicalType(Field->getType());
+  QualType FieldType = Field->getType();
 
   llvm::Value *ThisPtr = CGF.LoadCXXThis();
   LValue LHS;
@@ -562,28 +563,63 @@
     LHS = CGF.EmitLValueForFieldInitialization(ThisPtr, Field, 0);
   }
 
-  if (!CGF.hasAggregateLLVMType(Field->getType())) {
+  // Special case: if we are in a copy or move constructor, and we are copying
+  // an array of PODs or classes with trivial copy constructors, ignore the
+  // AST and perform the copy we know is equivalent.
+  // FIXME: This is hacky at best... if we had a bit more explicit information
+  // in the AST, we could generalize it more easily.
+  const ConstantArrayType *Array
+    = CGF.getContext().getAsConstantArrayType(FieldType);
+  if (Array && Constructor->isImplicitlyDefined() &&
+      Constructor->isCopyOrMoveConstructor()) {
+    QualType BaseElementTy = CGF.getContext().getBaseElementType(Array);
+    const CXXRecordDecl *Record = BaseElementTy->getAsCXXRecordDecl();
+    if (BaseElementTy.isPODType(CGF.getContext()) ||
+        (Record && hasTrivialCopyOrMoveConstructor(Record,
+                       Constructor->isMoveConstructor()))) {
+      // Find the source pointer. We knows it's the last argument because
+      // we know we're in a copy constructor.
+      unsigned SrcArgIndex = Args.size() - 1;
+      llvm::Value *SrcPtr
+        = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(Args[SrcArgIndex]));
+      LValue Src = CGF.EmitLValueForFieldInitialization(SrcPtr, Field, 0);
+      
+      // Copy the aggregate.
+      CGF.EmitAggregateCopy(LHS.getAddress(), Src.getAddress(), FieldType,
+                            LHS.isVolatileQualified());
+      return;
+    }
+  }
+
+  ArrayRef<VarDecl *> ArrayIndexes;
+  if (MemberInit->getNumArrayIndices())
+    ArrayIndexes = MemberInit->getArrayIndexes();
+  EmitInitializerForField(CGF, Field, LHS, MemberInit->getInit(), ArrayIndexes);
+}
+
+static void EmitInitializerForField(CodeGenFunction &CGF, FieldDecl *Field,
+                                    LValue LHS, Expr *Init,
+                                    ArrayRef<VarDecl *> ArrayIndexes) {
+  QualType FieldType = Field->getType();
+  if (!CGF.hasAggregateLLVMType(FieldType)) {
     if (LHS.isSimple()) {
-      CGF.EmitExprAsInit(MemberInit->getInit(), Field, LHS, false);
+      CGF.EmitExprAsInit(Init, Field, LHS, false);
     } else {
-      RValue RHS = RValue::get(CGF.EmitScalarExpr(MemberInit->getInit()));
+      RValue RHS = RValue::get(CGF.EmitScalarExpr(Init));
       CGF.EmitStoreThroughLValue(RHS, LHS);
     }
-  } else if (MemberInit->getInit()->getType()->isAnyComplexType()) {
-    CGF.EmitComplexExprIntoAddr(MemberInit->getInit(), LHS.getAddress(),
+  } else if (FieldType->isAnyComplexType()) {
+    CGF.EmitComplexExprIntoAddr(Init, LHS.getAddress(),
                                 LHS.isVolatileQualified());
   } else {
     llvm::Value *ArrayIndexVar = 0;
-    const ConstantArrayType *Array
-      = CGF.getContext().getAsConstantArrayType(FieldType);
-    if (Array && Constructor->isImplicitlyDefined() &&
-        Constructor->isCopyOrMoveConstructor()) {
+    if (ArrayIndexes.size()) {
       llvm::Type *SizeTy
         = CGF.ConvertType(CGF.getContext().getSizeType());
       
       // The LHS is a pointer to the first object we'll be constructing, as
       // a flat array.
-      QualType BaseElementTy = CGF.getContext().getBaseElementType(Array);
+      QualType BaseElementTy = CGF.getContext().getBaseElementType(FieldType);
       llvm::Type *BasePtr = CGF.ConvertType(BaseElementTy);
       BasePtr = llvm::PointerType::getUnqual(BasePtr);
       llvm::Value *BaseAddrPtr = CGF.Builder.CreateBitCast(LHS.getAddress(), 
@@ -596,31 +632,14 @@
       llvm::Value *Zero = llvm::Constant::getNullValue(SizeTy);
       CGF.Builder.CreateStore(Zero, ArrayIndexVar);
       
-      // If we are copying an array of PODs or classes with trivial copy 
-      // constructors, perform a single aggregate copy.
-      const CXXRecordDecl *Record = BaseElementTy->getAsCXXRecordDecl();
-      if (BaseElementTy.isPODType(CGF.getContext()) ||
-          (Record && hasTrivialCopyOrMoveConstructor(Record,
-                         Constructor->isMoveConstructor()))) {
-        // Find the source pointer. We knows it's the last argument because
-        // we know we're in a copy constructor.
-        unsigned SrcArgIndex = Args.size() - 1;
-        llvm::Value *SrcPtr
-          = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(Args[SrcArgIndex]));
-        LValue Src = CGF.EmitLValueForFieldInitialization(SrcPtr, Field, 0);
-        
-        // Copy the aggregate.
-        CGF.EmitAggregateCopy(LHS.getAddress(), Src.getAddress(), FieldType,
-                              LHS.isVolatileQualified());
-        return;
-      }
       
       // Emit the block variables for the array indices, if any.
-      for (unsigned I = 0, N = MemberInit->getNumArrayIndices(); I != N; ++I)
-        CGF.EmitAutoVarDecl(*MemberInit->getArrayIndex(I));
+      for (unsigned I = 0, N = ArrayIndexes.size(); I != N; ++I)
+        CGF.EmitAutoVarDecl(*ArrayIndexes[I]);
     }
     
-    EmitAggMemberInitializer(CGF, LHS, ArrayIndexVar, MemberInit, FieldType, 0);
+    EmitAggMemberInitializer(CGF, LHS, Init, ArrayIndexVar, FieldType,
+                             ArrayIndexes, 0);
     
     if (!CGF.CGM.getLangOptions().Exceptions)
       return;
@@ -634,7 +653,7 @@
     
     CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
     if (!RD->hasTrivialDestructor())
-      CGF.EHStack.pushCleanup<CallMemberDtor>(EHCleanup, Field,
+      CGF.EHStack.pushCleanup<CallMemberDtor>(EHCleanup, LHS.getAddress(),
                                               RD->getDestructor());
   }
 }





More information about the cfe-commits mailing list