zcov: / lib/CodeGen/CGClass.cpp


Files: 1 Branches Taken: 76.9% 186 / 242
Generated: 2010-02-10 01:31 Branches Executed: 95.0% 230 / 242
Line Coverage: 91.6% 611 / 667


Programs: 1 Runs 2897


       1                 : //===--- CGClass.cpp - Emit LLVM Code for C++ classes ---------------------===//
       2                 : //
       3                 : //                     The LLVM Compiler Infrastructure
       4                 : //
       5                 : // This file is distributed under the University of Illinois Open Source
       6                 : // License. See LICENSE.TXT for details.
       7                 : //
       8                 : //===----------------------------------------------------------------------===//
       9                 : //
      10                 : // This contains code dealing with C++ code generation of classes
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "CodeGenFunction.h"
      15                 : #include "clang/AST/CXXInheritance.h"
      16                 : #include "clang/AST/RecordLayout.h"
      17                 : 
      18                 : using namespace clang;
      19                 : using namespace CodeGen;
      20                 : 
      21                 : static uint64_t 
      22                 : ComputeNonVirtualBaseClassOffset(ASTContext &Context, CXXBasePaths &Paths,
      23              351:                                  unsigned Start) {
      24              351:   uint64_t Offset = 0;
      25                 : 
      26              351:   const CXXBasePath &Path = Paths.front();
                      255: branch 1 taken
                      351: branch 2 taken
      27             1212:   for (unsigned i = Start, e = Path.size(); i != e; ++i) {
      28              255:     const CXXBasePathElement& Element = Path[i];
      29                 : 
      30                 :     // Get the layout.
      31              255:     const ASTRecordLayout &Layout = Context.getASTRecordLayout(Element.Class);
      32                 :     
      33              255:     const CXXBaseSpecifier *BS = Element.Base;
                      255: branch 1 taken
                        0: branch 2 not taken
      34              255:     assert(!BS->isVirtual() && "Should not see virtual bases here!");
      35                 :     
      36                 :     const CXXRecordDecl *Base = 
      37              255:       cast<CXXRecordDecl>(BS->getType()->getAs<RecordType>()->getDecl());
      38                 :     
      39                 :     // Add the offset.
      40              255:     Offset += Layout.getBaseClassOffset(Base) / 8;
      41                 :   }
      42                 : 
      43              351:   return Offset;
      44                 : }
      45                 : 
      46                 : llvm::Constant *
      47                 : CodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *Class,
      48               11:                                             const CXXRecordDecl *BaseClass) {
                        0: branch 0 not taken
                       11: branch 1 taken
      49               11:   if (Class == BaseClass)
      50                0:     return 0;
      51                 : 
      52                 :   CXXBasePaths Paths(/*FindAmbiguities=*/false,
      53               11:                      /*RecordPaths=*/true, /*DetectVirtual=*/false);
                        0: branch 1 not taken
                       11: branch 2 taken
      54               11:   if (!const_cast<CXXRecordDecl *>(Class)->
      55                 :         isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClass), Paths)) {
      56                0:     assert(false && "Class must be derived from the passed in base class!");
      57                 :     return 0;
      58                 :   }
      59                 : 
      60               11:   uint64_t Offset = ComputeNonVirtualBaseClassOffset(getContext(), Paths, 0);
                        6: branch 0 taken
                        5: branch 1 taken
      61               11:   if (!Offset)
      62                6:     return 0;
      63                 : 
      64                 :   const llvm::Type *PtrDiffTy = 
      65                5:     Types.ConvertType(getContext().getPointerDiffType());
      66                 : 
      67                5:   return llvm::ConstantInt::get(PtrDiffTy, Offset);
      68                 : }
      69                 : 
      70                 : // FIXME: This probably belongs in CGVtable, but it relies on 
      71                 : // the static function ComputeNonVirtualBaseClassOffset, so we should make that
      72                 : // a CodeGenModule member function as well.
      73                 : ThunkAdjustment
      74                 : CodeGenModule::ComputeThunkAdjustment(const CXXRecordDecl *ClassDecl,
      75              190:                                       const CXXRecordDecl *BaseClassDecl) {
      76                 :   CXXBasePaths Paths(/*FindAmbiguities=*/false,
      77              190:                      /*RecordPaths=*/true, /*DetectVirtual=*/false);
                        0: branch 1 not taken
                      190: branch 2 taken
      78              190:   if (!const_cast<CXXRecordDecl *>(ClassDecl)->
      79                 :         isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClassDecl), Paths)) {
      80                0:     assert(false && "Class must be derived from the passed in base class!");
      81                 :     return ThunkAdjustment();
      82                 :   }
      83                 : 
      84              190:   unsigned Start = 0;
      85              190:   uint64_t VirtualOffset = 0;
      86                 : 
      87              190:   const CXXBasePath &Path = Paths.front();
      88              190:   const CXXRecordDecl *VBase = 0;
                      252: branch 1 taken
                      190: branch 2 taken
      89              442:   for (unsigned i = 0, e = Path.size(); i != e; ++i) {
      90              252:     const CXXBasePathElement& Element = Path[i];
                      158: branch 1 taken
                       94: branch 2 taken
      91              252:     if (Element.Base->isVirtual()) {
      92              158:       Start = i+1;
      93              158:       QualType VBaseType = Element.Base->getType();
      94              158:       VBase = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl());
      95                 :     }
      96                 :   }
                      134: branch 0 taken
                       56: branch 1 taken
      97              190:   if (VBase)
      98                 :     VirtualOffset = 
      99              134:       getVtableInfo().getVirtualBaseOffsetIndex(ClassDecl, BaseClassDecl);
     100                 :   
     101                 :   uint64_t Offset = 
     102              190:     ComputeNonVirtualBaseClassOffset(getContext(), Paths, Start);
     103              190:   return ThunkAdjustment(Offset, VirtualOffset);
     104                 : }
     105                 : 
     106                 : llvm::Value *
     107                 : CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value,
     108                 :                                        const CXXRecordDecl *Class,
     109                 :                                        const CXXRecordDecl *BaseClass,
     110              261:                                        bool NullCheckValue) {
     111                 :   QualType BTy =
     112                 :     getContext().getCanonicalType(
     113              261:       getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(BaseClass)));
     114              261:   const llvm::Type *BasePtrTy = llvm::PointerType::getUnqual(ConvertType(BTy));
     115                 : 
                      111: branch 0 taken
                      150: branch 1 taken
     116              261:   if (Class == BaseClass) {
     117                 :     // Just cast back.
     118              111:     return Builder.CreateBitCast(Value, BasePtrTy);
     119                 :   }
     120                 : 
     121                 :   CXXBasePaths Paths(/*FindAmbiguities=*/false,
     122              150:                      /*RecordPaths=*/true, /*DetectVirtual=*/false);
                        0: branch 1 not taken
                      150: branch 2 taken
     123              150:   if (!const_cast<CXXRecordDecl *>(Class)->
     124                 :         isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClass), Paths)) {
     125                0:     assert(false && "Class must be derived from the passed in base class!");
     126                 :     return 0;
     127                 :   }
     128                 : 
     129              150:   unsigned Start = 0;
     130              150:   llvm::Value *VirtualOffset = 0;
     131                 : 
     132              150:   const CXXBasePath &Path = Paths.front();
     133              150:   const CXXRecordDecl *VBase = 0;
                      166: branch 1 taken
                      150: branch 2 taken
     134              316:   for (unsigned i = 0, e = Path.size(); i != e; ++i) {
     135              166:     const CXXBasePathElement& Element = Path[i];
                       14: branch 1 taken
                      152: branch 2 taken
     136              166:     if (Element.Base->isVirtual()) {
     137               14:       Start = i+1;
     138               14:       QualType VBaseType = Element.Base->getType();
     139               14:       VBase = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl());
     140                 :     }
     141                 :   }
     142                 : 
     143                 :   uint64_t Offset = 
     144              150:     ComputeNonVirtualBaseClassOffset(getContext(), Paths, Start);
     145                 :   
                      113: branch 0 taken
                       37: branch 1 taken
                      102: branch 2 taken
                       11: branch 3 taken
     146              150:   if (!Offset && !VBase) {
     147                 :     // Just cast back.
     148              102:     return Builder.CreateBitCast(Value, BasePtrTy);
     149                 :   }    
     150                 : 
     151               48:   llvm::BasicBlock *CastNull = 0;
     152               48:   llvm::BasicBlock *CastNotNull = 0;
     153               48:   llvm::BasicBlock *CastEnd = 0;
     154                 :   
                        9: branch 0 taken
                       39: branch 1 taken
     155               48:   if (NullCheckValue) {
     156                9:     CastNull = createBasicBlock("cast.null");
     157                9:     CastNotNull = createBasicBlock("cast.notnull");
     158                9:     CastEnd = createBasicBlock("cast.end");
     159                 :     
     160                 :     llvm::Value *IsNull = 
     161                 :       Builder.CreateICmpEQ(Value,
     162                9:                            llvm::Constant::getNullValue(Value->getType()));
     163                9:     Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
     164                9:     EmitBlock(CastNotNull);
     165                 :   }
     166                 :   
                       12: branch 0 taken
                       36: branch 1 taken
     167               48:   if (VBase)
     168               12:     VirtualOffset = GetVirtualBaseClassOffset(Value, Class, VBase);
     169                 : 
     170               48:   const llvm::Type *PtrDiffTy = ConvertType(getContext().getPointerDiffType());
     171               48:   llvm::Value *NonVirtualOffset = 0;
                       37: branch 0 taken
                       11: branch 1 taken
     172               48:   if (Offset)
     173               37:     NonVirtualOffset = llvm::ConstantInt::get(PtrDiffTy, Offset);
     174                 :   
     175                 :   llvm::Value *BaseOffset;
                       12: branch 0 taken
                       36: branch 1 taken
     176               48:   if (VBase) {
                        1: branch 0 taken
                       11: branch 1 taken
     177               12:     if (NonVirtualOffset)
     178                1:       BaseOffset = Builder.CreateAdd(VirtualOffset, NonVirtualOffset);
     179                 :     else
     180               11:       BaseOffset = VirtualOffset;
     181                 :   } else
     182               36:     BaseOffset = NonVirtualOffset;
     183                 :   
     184                 :   // Apply the base offset.
     185               48:   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
     186               48:   Value = Builder.CreateBitCast(Value, Int8PtrTy);
     187               48:   Value = Builder.CreateGEP(Value, BaseOffset, "add.ptr");
     188                 :   
     189                 :   // Cast back.
     190               48:   Value = Builder.CreateBitCast(Value, BasePtrTy);
     191                 :  
                        9: branch 0 taken
                       39: branch 1 taken
     192               48:   if (NullCheckValue) {
     193                9:     Builder.CreateBr(CastEnd);
     194                9:     EmitBlock(CastNull);
     195                9:     Builder.CreateBr(CastEnd);
     196                9:     EmitBlock(CastEnd);
     197                 :     
     198                9:     llvm::PHINode *PHI = Builder.CreatePHI(Value->getType());
     199                9:     PHI->reserveOperandSpace(2);
     200                9:     PHI->addIncoming(Value, CastNotNull);
     201                 :     PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 
     202                9:                      CastNull);
     203                9:     Value = PHI;
     204                 :   }
     205                 :   
     206               48:   return Value;
     207                 : }
     208                 : 
     209                 : llvm::Value *
     210                 : CodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value,
     211                 :                                           const CXXRecordDecl *Class,
     212                 :                                           const CXXRecordDecl *DerivedClass,
     213                4:                                           bool NullCheckValue) {
     214                 :   QualType DerivedTy =
     215                 :     getContext().getCanonicalType(
     216                4:     getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(DerivedClass)));
     217                4:   const llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo();
     218                 :   
                        0: branch 0 not taken
                        4: branch 1 taken
     219                4:   if (Class == DerivedClass) {
     220                 :     // Just cast back.
     221                0:     return Builder.CreateBitCast(Value, DerivedPtrTy);
     222                 :   }
     223                 : 
     224                 :   llvm::Value *NonVirtualOffset =
     225                4:     CGM.GetNonVirtualBaseClassOffset(DerivedClass, Class);
     226                 :   
                        4: branch 0 taken
                        0: branch 1 not taken
     227                4:   if (!NonVirtualOffset) {
     228                 :     // No offset, we can just cast back.
     229                4:     return Builder.CreateBitCast(Value, DerivedPtrTy);
     230                 :   }
     231                 :   
     232                0:   llvm::BasicBlock *CastNull = 0;
     233                0:   llvm::BasicBlock *CastNotNull = 0;
     234                0:   llvm::BasicBlock *CastEnd = 0;
     235                 :   
                        0: branch 0 not taken
                        0: branch 1 not taken
     236                0:   if (NullCheckValue) {
     237                0:     CastNull = createBasicBlock("cast.null");
     238                0:     CastNotNull = createBasicBlock("cast.notnull");
     239                0:     CastEnd = createBasicBlock("cast.end");
     240                 :     
     241                 :     llvm::Value *IsNull = 
     242                 :     Builder.CreateICmpEQ(Value,
     243                0:                          llvm::Constant::getNullValue(Value->getType()));
     244                0:     Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
     245                0:     EmitBlock(CastNotNull);
     246                 :   }
     247                 :   
     248                 :   // Apply the offset.
     249                0:   Value = Builder.CreatePtrToInt(Value, NonVirtualOffset->getType());
     250                0:   Value = Builder.CreateSub(Value, NonVirtualOffset);
     251                0:   Value = Builder.CreateIntToPtr(Value, DerivedPtrTy);
     252                 : 
     253                 :   // Just cast.
     254                0:   Value = Builder.CreateBitCast(Value, DerivedPtrTy);
     255                 : 
                        0: branch 0 not taken
                        0: branch 1 not taken
     256                0:   if (NullCheckValue) {
     257                0:     Builder.CreateBr(CastEnd);
     258                0:     EmitBlock(CastNull);
     259                0:     Builder.CreateBr(CastEnd);
     260                0:     EmitBlock(CastEnd);
     261                 :     
     262                0:     llvm::PHINode *PHI = Builder.CreatePHI(Value->getType());
     263                0:     PHI->reserveOperandSpace(2);
     264                0:     PHI->addIncoming(Value, CastNotNull);
     265                 :     PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 
     266                0:                      CastNull);
     267                0:     Value = PHI;
     268                 :   }
     269                 :   
     270                0:   return Value;
     271                 : }
     272                 : 
     273                 : /// EmitClassAggrMemberwiseCopy - This routine generates code to copy a class
     274                 : /// array of objects from SrcValue to DestValue. Copying can be either a bitwise
     275                 : /// copy or via a copy constructor call.
     276                 : //  FIXME. Consolidate this with EmitCXXAggrConstructorCall.
     277                 : void CodeGenFunction::EmitClassAggrMemberwiseCopy(llvm::Value *Dest,
     278                 :                                             llvm::Value *Src,
     279                 :                                             const ArrayType *Array,
     280                 :                                             const CXXRecordDecl *BaseClassDecl,
     281                4:                                             QualType Ty) {
     282                4:   const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
                        0: branch 0 not taken
                        4: branch 1 taken
     283                4:   assert(CA && "VLA cannot be copied over");
     284                4:   bool BitwiseCopy = BaseClassDecl->hasTrivialCopyConstructor();
     285                 : 
     286                 :   // Create a temporary for the loop index and initialize it with 0.
     287                 :   llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
     288                4:                                            "loop.index");
     289                 :   llvm::Value* zeroConstant =
     290                4:     llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
     291                4:   Builder.CreateStore(zeroConstant, IndexPtr);
     292                 :   // Start the loop with a block that tests the condition.
     293                4:   llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
     294                4:   llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
     295                 : 
     296                4:   EmitBlock(CondBlock);
     297                 : 
     298                4:   llvm::BasicBlock *ForBody = createBasicBlock("for.body");
     299                 :   // Generate: if (loop-index < number-of-elements fall to the loop body,
     300                 :   // otherwise, go to the block after the for-loop.
     301                4:   uint64_t NumElements = getContext().getConstantArrayElementCount(CA);
     302                 :   llvm::Value * NumElementsPtr =
     303                4:     llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements);
     304                4:   llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
     305                 :   llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr,
     306                4:                                               "isless");
     307                 :   // If the condition is true, execute the body.
     308                4:   Builder.CreateCondBr(IsLess, ForBody, AfterFor);
     309                 : 
     310                4:   EmitBlock(ForBody);
     311                4:   llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
     312                 :   // Inside the loop body, emit the constructor call on the array element.
     313                4:   Counter = Builder.CreateLoad(IndexPtr);
     314                4:   Src = Builder.CreateInBoundsGEP(Src, Counter, "srcaddress");
     315                4:   Dest = Builder.CreateInBoundsGEP(Dest, Counter, "destaddress");
                        2: branch 0 taken
                        2: branch 1 taken
     316                4:   if (BitwiseCopy)
     317                2:     EmitAggregateCopy(Dest, Src, Ty);
                        2: branch 0 taken
                        0: branch 1 not taken
     318                2:   else if (CXXConstructorDecl *BaseCopyCtor =
     319                2:            BaseClassDecl->getCopyConstructor(getContext(), 0)) {
     320                 :     llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor,
     321                2:                                                       Ctor_Complete);
     322                2:     CallArgList CallArgs;
     323                 :     // Push the this (Dest) ptr.
     324                 :     CallArgs.push_back(std::make_pair(RValue::get(Dest),
     325                2:                                       BaseCopyCtor->getThisType(getContext())));
     326                 : 
     327                 :     // Push the Src ptr.
     328                 :     CallArgs.push_back(std::make_pair(RValue::get(Src),
     329                2:                                      BaseCopyCtor->getParamDecl(0)->getType()));
     330                 :     const FunctionProtoType *FPT
     331                2:       = BaseCopyCtor->getType()->getAs<FunctionProtoType>();
     332                 :     EmitCall(CGM.getTypes().getFunctionInfo(CallArgs, FPT),
     333                2:              Callee, ReturnValueSlot(), CallArgs, BaseCopyCtor);
     334                 :   }
     335                4:   EmitBlock(ContinueBlock);
     336                 : 
     337                 :   // Emit the increment of the loop counter.
     338                4:   llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
     339                4:   Counter = Builder.CreateLoad(IndexPtr);
     340                4:   NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
     341                4:   Builder.CreateStore(NextVal, IndexPtr);
     342                 : 
     343                 :   // Finally, branch back up to the condition for the next iteration.
     344                4:   EmitBranch(CondBlock);
     345                 : 
     346                 :   // Emit the fall-through block.
     347                4:   EmitBlock(AfterFor, true);
     348                4: }
     349                 : 
     350                 : /// EmitClassAggrCopyAssignment - This routine generates code to assign a class
     351                 : /// array of objects from SrcValue to DestValue. Assignment can be either a
     352                 : /// bitwise assignment or via a copy assignment operator function call.
     353                 : /// FIXME. This can be consolidated with EmitClassAggrMemberwiseCopy
     354                 : void CodeGenFunction::EmitClassAggrCopyAssignment(llvm::Value *Dest,
     355                 :                                             llvm::Value *Src,
     356                 :                                             const ArrayType *Array,
     357                 :                                             const CXXRecordDecl *BaseClassDecl,
     358                2:                                             QualType Ty) {
     359                2:   const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
                        0: branch 0 not taken
                        2: branch 1 taken
     360                2:   assert(CA && "VLA cannot be asssigned");
     361                2:   bool BitwiseAssign = BaseClassDecl->hasTrivialCopyAssignment();
     362                 : 
     363                 :   // Create a temporary for the loop index and initialize it with 0.
     364                 :   llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
     365                2:                                            "loop.index");
     366                 :   llvm::Value* zeroConstant =
     367                2:   llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
     368                2:   Builder.CreateStore(zeroConstant, IndexPtr);
     369                 :   // Start the loop with a block that tests the condition.
     370                2:   llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
     371                2:   llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
     372                 : 
     373                2:   EmitBlock(CondBlock);
     374                 : 
     375                2:   llvm::BasicBlock *ForBody = createBasicBlock("for.body");
     376                 :   // Generate: if (loop-index < number-of-elements fall to the loop body,
     377                 :   // otherwise, go to the block after the for-loop.
     378                2:   uint64_t NumElements = getContext().getConstantArrayElementCount(CA);
     379                 :   llvm::Value * NumElementsPtr =
     380                2:   llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements);
     381                2:   llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
     382                 :   llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr,
     383                2:                                               "isless");
     384                 :   // If the condition is true, execute the body.
     385                2:   Builder.CreateCondBr(IsLess, ForBody, AfterFor);
     386                 : 
     387                2:   EmitBlock(ForBody);
     388                2:   llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
     389                 :   // Inside the loop body, emit the assignment operator call on array element.
     390                2:   Counter = Builder.CreateLoad(IndexPtr);
     391                2:   Src = Builder.CreateInBoundsGEP(Src, Counter, "srcaddress");
     392                2:   Dest = Builder.CreateInBoundsGEP(Dest, Counter, "destaddress");
     393                2:   const CXXMethodDecl *MD = 0;
                        0: branch 0 not taken
                        2: branch 1 taken
     394                2:   if (BitwiseAssign)
     395                0:     EmitAggregateCopy(Dest, Src, Ty);
     396                 :   else {
     397                2:     BaseClassDecl->hasConstCopyAssignment(getContext(), MD);
                        0: branch 0 not taken
                        2: branch 1 taken
     398                2:     assert(MD && "EmitClassAggrCopyAssignment - No user assign");
     399                2:     const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
     400                 :     const llvm::Type *LTy =
     401                 :     CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
     402                2:                                    FPT->isVariadic());
     403                2:     llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, LTy);
     404                 : 
     405                2:     CallArgList CallArgs;
     406                 :     // Push the this (Dest) ptr.
     407                 :     CallArgs.push_back(std::make_pair(RValue::get(Dest),
     408                2:                                       MD->getThisType(getContext())));
     409                 : 
     410                 :     // Push the Src ptr.
     411                2:     QualType SrcTy = MD->getParamDecl(0)->getType();
     412                 :     RValue SrcValue = SrcTy->isReferenceType() ? RValue::get(Src) :
                        1: branch 2 taken
                        1: branch 3 taken
     413                2:                                                  RValue::getAggregate(Src);
     414                2:     CallArgs.push_back(std::make_pair(SrcValue, SrcTy));
     415                 :     EmitCall(CGM.getTypes().getFunctionInfo(CallArgs, FPT),
     416                2:              Callee, ReturnValueSlot(), CallArgs, MD);
     417                 :   }
     418                2:   EmitBlock(ContinueBlock);
     419                 : 
     420                 :   // Emit the increment of the loop counter.
     421                2:   llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
     422                2:   Counter = Builder.CreateLoad(IndexPtr);
     423                2:   NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
     424                2:   Builder.CreateStore(NextVal, IndexPtr);
     425                 : 
     426                 :   // Finally, branch back up to the condition for the next iteration.
     427                2:   EmitBranch(CondBlock);
     428                 : 
     429                 :   // Emit the fall-through block.
     430                2:   EmitBlock(AfterFor, true);
     431                2: }
     432                 : 
     433                 : /// GetVTTParameter - Return the VTT parameter that should be passed to a
     434                 : /// base constructor/destructor with virtual bases.
     435              893: static llvm::Value *GetVTTParameter(CodeGenFunction &CGF, GlobalDecl GD) {
                      809: branch 1 taken
                       84: branch 2 taken
     436              893:   if (!CGVtableInfo::needsVTTParameter(GD)) {
     437                 :     // This constructor/destructor does not need a VTT parameter.
     438              809:     return 0;
     439                 :   }
     440                 :   
     441               84:   const CXXRecordDecl *RD = cast<CXXMethodDecl>(CGF.CurFuncDecl)->getParent();
     442               84:   const CXXRecordDecl *Base = cast<CXXMethodDecl>(GD.getDecl())->getParent();
     443                 :   
     444                 :   llvm::Value *VTT;
     445                 : 
     446                 :   uint64_t SubVTTIndex = 
     447               84:     CGF.CGM.getVtableInfo().getSubVTTIndex(RD, Base);
                        0: branch 0 not taken
                       84: branch 1 taken
     448               84:   assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!");
     449                 :   
                        8: branch 1 taken
                       76: branch 2 taken
     450               84:   if (CGVtableInfo::needsVTTParameter(CGF.CurGD)) {
     451                 :     // A VTT parameter was passed to the constructor, use it.
     452                8:     VTT = CGF.LoadCXXVTT();
     453                8:     VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex);
     454                 :   } else {
     455                 :     // We're the complete constructor, so get the VTT by name.
     456               76:     VTT = CGF.CGM.getVtableInfo().getVTT(RD);
     457               76:     VTT = CGF.Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex);
     458                 :   }
     459                 : 
     460               84:   return VTT;
     461                 : }
     462                 : 
     463                 :                                     
     464                 : /// EmitClassMemberwiseCopy - This routine generates code to copy a class
     465                 : /// object from SrcValue to DestValue. Copying can be either a bitwise copy
     466                 : /// or via a copy constructor call.
     467                 : void CodeGenFunction::EmitClassMemberwiseCopy(
     468                 :                         llvm::Value *Dest, llvm::Value *Src,
     469                 :                         const CXXRecordDecl *ClassDecl,
     470               16:                         const CXXRecordDecl *BaseClassDecl, QualType Ty) {
     471               16:   CXXCtorType CtorType = Ctor_Complete;
     472                 :   
                        6: branch 0 taken
                       10: branch 1 taken
     473               16:   if (ClassDecl) {
     474                 :     Dest = GetAddressOfBaseClass(Dest, ClassDecl, BaseClassDecl,
     475                6:                                  /*NullCheckValue=*/false);
     476                 :     Src = GetAddressOfBaseClass(Src, ClassDecl, BaseClassDecl,
     477                6:                                 /*NullCheckValue=*/false);
     478                 : 
     479                 :     // We want to call the base constructor.
     480                6:     CtorType = Ctor_Base;
     481                 :   }
                       14: branch 1 taken
                        2: branch 2 taken
     482               16:   if (BaseClassDecl->hasTrivialCopyConstructor()) {
     483               14:     EmitAggregateCopy(Dest, Src, Ty);
     484               14:     return;
     485                 :   }
     486                 : 
                        2: branch 0 taken
                        0: branch 1 not taken
     487                2:   if (CXXConstructorDecl *BaseCopyCtor =
     488                2:       BaseClassDecl->getCopyConstructor(getContext(), 0)) {
     489                2:     llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor, CtorType);
     490                2:     CallArgList CallArgs;
     491                 :     // Push the this (Dest) ptr.
     492                 :     CallArgs.push_back(std::make_pair(RValue::get(Dest),
     493                2:                                       BaseCopyCtor->getThisType(getContext())));
     494                 : 
     495                 :     // Push the VTT parameter, if necessary.
                        0: branch 0 not taken
                        2: branch 1 taken
     496                2:     if (llvm::Value *VTT = 
     497                2:           GetVTTParameter(*this, GlobalDecl(BaseCopyCtor, CtorType))) {
     498                0:       QualType T = getContext().getPointerType(getContext().VoidPtrTy);
     499                0:       CallArgs.push_back(std::make_pair(RValue::get(VTT), T));
     500                 :     }
     501                 : 
     502                 :     // Push the Src ptr.
     503                 :     CallArgs.push_back(std::make_pair(RValue::get(Src),
     504                2:                        BaseCopyCtor->getParamDecl(0)->getType()));
     505                 :     const FunctionProtoType *FPT =
     506                2:       BaseCopyCtor->getType()->getAs<FunctionProtoType>();
     507                 :     EmitCall(CGM.getTypes().getFunctionInfo(CallArgs, FPT),
     508                2:              Callee, ReturnValueSlot(), CallArgs, BaseCopyCtor);
     509                 :   }
     510                 : }
     511                 : 
     512                 : /// EmitClassCopyAssignment - This routine generates code to copy assign a class
     513                 : /// object from SrcValue to DestValue. Assignment can be either a bitwise
     514                 : /// assignment of via an assignment operator call.
     515                 : // FIXME. Consolidate this with EmitClassMemberwiseCopy as they share a lot.
     516                 : void CodeGenFunction::EmitClassCopyAssignment(
     517                 :                                         llvm::Value *Dest, llvm::Value *Src,
     518                 :                                         const CXXRecordDecl *ClassDecl,
     519                 :                                         const CXXRecordDecl *BaseClassDecl,
     520               13:                                         QualType Ty) {
                        7: branch 0 taken
                        6: branch 1 taken
     521               13:   if (ClassDecl) {
     522                 :     Dest = GetAddressOfBaseClass(Dest, ClassDecl, BaseClassDecl,
     523                7:                                  /*NullCheckValue=*/false);
     524                 :     Src = GetAddressOfBaseClass(Src, ClassDecl, BaseClassDecl,
     525                7:                                 /*NullCheckValue=*/false);
     526                 :   }
                        2: branch 1 taken
                       11: branch 2 taken
     527               13:   if (BaseClassDecl->hasTrivialCopyAssignment()) {
     528                2:     EmitAggregateCopy(Dest, Src, Ty);
     529                2:     return;
     530                 :   }
     531                 : 
     532               11:   const CXXMethodDecl *MD = 0;
     533               11:   BaseClassDecl->hasConstCopyAssignment(getContext(), MD);
                        0: branch 0 not taken
                       11: branch 1 taken
     534               11:   assert(MD && "EmitClassCopyAssignment - missing copy assign");
     535                 : 
     536               11:   const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
     537                 :   const llvm::Type *LTy =
     538                 :     CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
     539               11:                                    FPT->isVariadic());
     540               11:   llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, LTy);
     541                 : 
     542               11:   CallArgList CallArgs;
     543                 :   // Push the this (Dest) ptr.
     544                 :   CallArgs.push_back(std::make_pair(RValue::get(Dest),
     545               11:                                     MD->getThisType(getContext())));
     546                 : 
     547                 :   // Push the Src ptr.
     548               11:   QualType SrcTy = MD->getParamDecl(0)->getType();
     549                 :   RValue SrcValue = SrcTy->isReferenceType() ? RValue::get(Src) :
                       10: branch 2 taken
                        1: branch 3 taken
     550               11:                                                RValue::getAggregate(Src);
     551               11:   CallArgs.push_back(std::make_pair(SrcValue, SrcTy));
     552                 :   EmitCall(CGM.getTypes().getFunctionInfo(CallArgs, FPT),
     553               11:            Callee, ReturnValueSlot(), CallArgs, MD);
     554                 : }
     555                 : 
     556                 : /// SynthesizeDefaultConstructor - synthesize a default constructor
     557                 : void
     558                 : CodeGenFunction::SynthesizeDefaultConstructor(const CXXConstructorDecl *Ctor,
     559                 :                                               CXXCtorType Type,
     560                 :                                               llvm::Function *Fn,
     561              267:                                               const FunctionArgList &Args) {
                      267: branch 1 taken
                        0: branch 2 not taken
     562              267:   assert(!Ctor->isTrivial() && "shouldn't need to generate trivial ctor");
     563                 :   StartFunction(GlobalDecl(Ctor, Type), Ctor->getResultType(), Fn, Args, 
     564              267:                 SourceLocation());
     565              267:   EmitCtorPrologue(Ctor, Type);
     566              267:   FinishFunction();
     567              267: }
     568                 : 
     569                 : /// SynthesizeCXXCopyConstructor - This routine implicitly defines body of a
     570                 : /// copy constructor, in accordance with section 12.8 (p7 and p8) of C++03
     571                 : /// The implicitly-defined copy constructor for class X performs a memberwise
     572                 : /// copy of its subobjects. The order of copying is the same as the order of
     573                 : /// initialization of bases and members in a user-defined constructor
     574                 : /// Each subobject is copied in the manner appropriate to its type:
     575                 : ///  if the subobject is of class type, the copy constructor for the class is
     576                 : ///  used;
     577                 : ///  if the subobject is an array, each element is copied, in the manner
     578                 : ///  appropriate to the element type;
     579                 : ///  if the subobject is of scalar type, the built-in assignment operator is
     580                 : ///  used.
     581                 : /// Virtual base class subobjects shall be copied only once by the
     582                 : /// implicitly-defined copy constructor
     583                 : 
     584                 : void 
     585                 : CodeGenFunction::SynthesizeCXXCopyConstructor(const CXXConstructorDecl *Ctor,
     586                 :                                               CXXCtorType Type,
     587                 :                                               llvm::Function *Fn,
     588                5:                                               const FunctionArgList &Args) {
     589                5:   const CXXRecordDecl *ClassDecl = Ctor->getParent();
     590                 :   assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
                        5: branch 1 taken
                        0: branch 2 not taken
     591                5:       "SynthesizeCXXCopyConstructor - copy constructor has definition already");
                        5: branch 1 taken
                        0: branch 2 not taken
     592                5:   assert(!Ctor->isTrivial() && "shouldn't need to generate trivial ctor");
     593                 :   StartFunction(GlobalDecl(Ctor, Type), Ctor->getResultType(), Fn, Args, 
     594                5:                 SourceLocation());
     595                 : 
     596                5:   FunctionArgList::const_iterator i = Args.begin();
     597                5:   const VarDecl *ThisArg = i->first;
     598                5:   llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg);
     599                5:   llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this");
     600                5:   const VarDecl *SrcArg = (i+1)->first;
     601                5:   llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg);
     602                5:   llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj);
     603                 : 
                        6: branch 2 taken
                        5: branch 3 taken
     604               11:   for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
     605                 :        Base != ClassDecl->bases_end(); ++Base) {
     606                 :     // FIXME. copy constrution of virtual base NYI
                        0: branch 1 not taken
                        6: branch 2 taken
     607                6:     if (Base->isVirtual())
     608                0:       continue;
     609                 : 
     610                 :     CXXRecordDecl *BaseClassDecl
     611                6:       = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
     612                 :     EmitClassMemberwiseCopy(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl,
     613                6:                             Base->getType());
     614                 :   }
     615                 : 
                       32: branch 3 taken
                        5: branch 4 taken
     616               42:   for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(),
     617                5:        E = ClassDecl->field_end(); I != E; ++I) {
     618               32:     const FieldDecl *Field = *I;
     619                 :     
     620               32:     QualType FieldType = getContext().getCanonicalType(Field->getType());
     621                 :     const ConstantArrayType *Array =
     622               32:       getContext().getAsConstantArrayType(FieldType);
                        6: branch 0 taken
                       26: branch 1 taken
     623               32:     if (Array)
     624                6:       FieldType = getContext().getBaseElementType(FieldType);
     625                 : 
                       14: branch 2 taken
                       18: branch 3 taken
     626               32:     if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
     627                 :       CXXRecordDecl *FieldClassDecl
     628               14:         = cast<CXXRecordDecl>(FieldClassType->getDecl());
     629               14:       LValue LHS = EmitLValueForField(LoadOfThis, Field, 0);
     630               14:       LValue RHS = EmitLValueForField(LoadOfSrc, Field, 0);
                        4: branch 0 taken
                       10: branch 1 taken
     631               14:       if (Array) {
     632                4:         const llvm::Type *BasePtr = ConvertType(FieldType);
     633                4:         BasePtr = llvm::PointerType::getUnqual(BasePtr);
     634                 :         llvm::Value *DestBaseAddrPtr =
     635                4:           Builder.CreateBitCast(LHS.getAddress(), BasePtr);
     636                 :         llvm::Value *SrcBaseAddrPtr =
     637                4:           Builder.CreateBitCast(RHS.getAddress(), BasePtr);
     638                 :         EmitClassAggrMemberwiseCopy(DestBaseAddrPtr, SrcBaseAddrPtr, Array,
     639                4:                                     FieldClassDecl, FieldType);
     640                 :       }
     641                 :       else
     642                 :         EmitClassMemberwiseCopy(LHS.getAddress(), RHS.getAddress(),
     643               10:                                 0 /*ClassDecl*/, FieldClassDecl, FieldType);
     644               14:       continue;
     645                 :     }
     646                 :     
     647                 :     // Do a built-in assignment of scalar data members.
     648               18:     LValue LHS = EmitLValueForFieldInitialization(LoadOfThis, Field, 0);
     649               18:     LValue RHS = EmitLValueForFieldInitialization(LoadOfSrc, Field, 0);
     650                 : 
                       14: branch 2 taken
                        4: branch 3 taken
     651               18:     if (!hasAggregateLLVMType(Field->getType())) {
     652               14:       RValue RVRHS = EmitLoadOfLValue(RHS, Field->getType());
     653               14:       EmitStoreThroughLValue(RVRHS, LHS, Field->getType());
                        2: branch 3 taken
                        2: branch 4 taken
     654                4:     } else if (Field->getType()->isAnyComplexType()) {
     655                 :       ComplexPairTy Pair = LoadComplexFromAddr(RHS.getAddress(),
     656                2:                                                RHS.isVolatileQualified());
     657                2:       StoreComplexToAddr(Pair, LHS.getAddress(), LHS.isVolatileQualified());
     658                 :     } else {
     659                2:       EmitAggregateCopy(LHS.getAddress(), RHS.getAddress(), Field->getType());
     660                 :     }
     661                 :   }
     662                 : 
     663                5:   InitializeVtablePtrs(ClassDecl);
     664                5:   FinishFunction();
     665                5: }
     666                 : 
     667                 : /// SynthesizeCXXCopyAssignment - Implicitly define copy assignment operator.
     668                 : /// Before the implicitly-declared copy assignment operator for a class is
     669                 : /// implicitly defined, all implicitly- declared copy assignment operators for
     670                 : /// its direct base classes and its nonstatic data members shall have been
     671                 : /// implicitly defined. [12.8-p12]
     672                 : /// The implicitly-defined copy assignment operator for class X performs
     673                 : /// memberwise assignment of its subob- jects. The direct base classes of X are
     674                 : /// assigned first, in the order of their declaration in
     675                 : /// the base-specifier-list, and then the immediate nonstatic data members of X
     676                 : /// are assigned, in the order in which they were declared in the class
     677                 : /// definition.Each subobject is assigned in the manner appropriate to its type:
     678                 : ///   if the subobject is of class type, the copy assignment operator for the
     679                 : ///   class is used (as if by explicit qualification; that is, ignoring any
     680                 : ///   possible virtual overriding functions in more derived classes);
     681                 : ///
     682                 : ///   if the subobject is an array, each element is assigned, in the manner
     683                 : ///   appropriate to the element type;
     684                 : ///
     685                 : ///   if the subobject is of scalar type, the built-in assignment operator is
     686                 : ///   used.
     687                 : void CodeGenFunction::SynthesizeCXXCopyAssignment(const CXXMethodDecl *CD,
     688                 :                                                   llvm::Function *Fn,
     689                8:                                                   const FunctionArgList &Args) {
     690                 : 
     691                8:   const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
     692                 :   assert(!ClassDecl->hasUserDeclaredCopyAssignment() &&
                        8: branch 1 taken
                        0: branch 2 not taken
     693                8:          "SynthesizeCXXCopyAssignment - copy assignment has user declaration");
     694                8:   StartFunction(CD, CD->getResultType(), Fn, Args, SourceLocation());
     695                 : 
     696                8:   FunctionArgList::const_iterator i = Args.begin();
     697                8:   const VarDecl *ThisArg = i->first;
     698                8:   llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg);
     699                8:   llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this");
     700                8:   const VarDecl *SrcArg = (i+1)->first;
     701                8:   llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg);
     702                8:   llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj);
     703                 : 
                        7: branch 2 taken
                        8: branch 3 taken
     704               15:   for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
     705                 :        Base != ClassDecl->bases_end(); ++Base) {
     706                 :     // FIXME. copy assignment of virtual base NYI
                        0: branch 1 not taken
                        7: branch 2 taken
     707                7:     if (Base->isVirtual())
     708                0:       continue;
     709                 : 
     710                 :     CXXRecordDecl *BaseClassDecl
     711                7:       = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
     712                 :     EmitClassCopyAssignment(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl,
     713                7:                             Base->getType());
     714                 :   }
     715                 : 
                       24: branch 3 taken
                        8: branch 4 taken
     716               40:   for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
     717                8:        FieldEnd = ClassDecl->field_end();
     718                 :        Field != FieldEnd; ++Field) {
     719               24:     QualType FieldType = getContext().getCanonicalType((*Field)->getType());
     720                 :     const ConstantArrayType *Array =
     721               24:       getContext().getAsConstantArrayType(FieldType);
                        3: branch 0 taken
                       21: branch 1 taken
     722               24:     if (Array)
     723                3:       FieldType = getContext().getBaseElementType(FieldType);
     724                 : 
                        8: branch 2 taken
                       16: branch 3 taken
     725               24:     if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
     726                 :       CXXRecordDecl *FieldClassDecl
     727                8:       = cast<CXXRecordDecl>(FieldClassType->getDecl());
     728                8:       LValue LHS = EmitLValueForField(LoadOfThis, *Field, 0);
     729                8:       LValue RHS = EmitLValueForField(LoadOfSrc, *Field, 0);
                        2: branch 0 taken
                        6: branch 1 taken
     730                8:       if (Array) {
     731                2:         const llvm::Type *BasePtr = ConvertType(FieldType);
     732                2:         BasePtr = llvm::PointerType::getUnqual(BasePtr);
     733                 :         llvm::Value *DestBaseAddrPtr =
     734                2:           Builder.CreateBitCast(LHS.getAddress(), BasePtr);
     735                 :         llvm::Value *SrcBaseAddrPtr =
     736                2:           Builder.CreateBitCast(RHS.getAddress(), BasePtr);
     737                 :         EmitClassAggrCopyAssignment(DestBaseAddrPtr, SrcBaseAddrPtr, Array,
     738                2:                                     FieldClassDecl, FieldType);
     739                 :       }
     740                 :       else
     741                 :         EmitClassCopyAssignment(LHS.getAddress(), RHS.getAddress(),
     742                6:                                0 /*ClassDecl*/, FieldClassDecl, FieldType);
     743                8:       continue;
     744                 :     }
     745                 :     // Do a built-in assignment of scalar data members.
     746               16:     LValue LHS = EmitLValueForField(LoadOfThis, *Field, 0);
     747               16:     LValue RHS = EmitLValueForField(LoadOfSrc, *Field, 0);
                       13: branch 3 taken
                        3: branch 4 taken
     748               16:     if (!hasAggregateLLVMType(Field->getType())) {
     749               13:       RValue RVRHS = EmitLoadOfLValue(RHS, Field->getType());
     750               13:       EmitStoreThroughLValue(RVRHS, LHS, Field->getType());
                        1: branch 4 taken
                        2: branch 5 taken
     751                3:     } else if (Field->getType()->isAnyComplexType()) {
     752                 :       ComplexPairTy Pair = LoadComplexFromAddr(RHS.getAddress(),
     753                1:                                                RHS.isVolatileQualified());
     754                1:       StoreComplexToAddr(Pair, LHS.getAddress(), LHS.isVolatileQualified());
     755                 :     } else {
     756                2:       EmitAggregateCopy(LHS.getAddress(), RHS.getAddress(), Field->getType());
     757                 :     }
     758                 :   }
     759                 : 
     760                 :   // return *this;
     761                8:   Builder.CreateStore(LoadOfThis, ReturnValue);
     762                 : 
     763                8:   FinishFunction();
     764                8: }
     765                 : 
     766                 : static void EmitBaseInitializer(CodeGenFunction &CGF, 
     767                 :                                 const CXXRecordDecl *ClassDecl,
     768                 :                                 CXXBaseOrMemberInitializer *BaseInit,
     769              429:                                 CXXCtorType CtorType) {
     770                 :   assert(BaseInit->isBaseInitializer() &&
                      429: branch 1 taken
                        0: branch 2 not taken
     771              429:          "Must have base initializer!");
     772                 : 
     773              429:   llvm::Value *ThisPtr = CGF.LoadCXXThis();
     774                 :   
     775              429:   const Type *BaseType = BaseInit->getBaseClass();
     776                 :   CXXRecordDecl *BaseClassDecl =
     777              429:     cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
     778                 : 
     779                 :   // FIXME: This method of determining whether a base is virtual is ridiculous;
     780                 :   // it should be part of BaseInit.
     781              429:   bool isBaseVirtual = false;
                      800: branch 1 taken
                      148: branch 2 taken
     782             1377:   for (CXXRecordDecl::base_class_const_iterator I = ClassDecl->vbases_begin(),
     783              429:        E = ClassDecl->vbases_end(); I != E; ++I)
                      281: branch 4 taken
                      519: branch 5 taken
     784              800:     if (I->getType()->getAs<RecordType>()->getDecl() == BaseClassDecl) {
     785              281:       isBaseVirtual = true;
     786              281:       break;
     787                 :     }
     788                 : 
     789                 :   // The base constructor doesn't construct virtual bases.
                      200: branch 0 taken
                      229: branch 1 taken
                      145: branch 2 taken
                       55: branch 3 taken
     790              429:   if (CtorType == Ctor_Base && isBaseVirtual)
     791              145:     return;
     792                 : 
     793                 :   // Compute the offset to the base; we do this directly instead of using
     794                 :   // GetAddressOfBaseClass because the class doesn't have a vtable pointer
     795                 :   // at this point.
     796                 :   // FIXME: This could be refactored back into GetAddressOfBaseClass if it took
     797                 :   // an extra parameter for whether the derived class is the complete object
     798                 :   // class.
     799                 :   const ASTRecordLayout &Layout =
     800              284:       CGF.getContext().getASTRecordLayout(ClassDecl);
     801                 :   uint64_t Offset;
                      136: branch 0 taken
                      148: branch 1 taken
     802              284:   if (isBaseVirtual)
     803              136:     Offset = Layout.getVBaseClassOffset(BaseClassDecl);
     804                 :   else
     805              148:     Offset = Layout.getBaseClassOffset(BaseClassDecl);
     806              284:   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
     807              284:   const llvm::Type *BaseClassType = CGF.ConvertType(QualType(BaseType, 0));
     808              284:   llvm::Value *V = CGF.Builder.CreateBitCast(ThisPtr, Int8PtrTy);
     809              284:   V = CGF.Builder.CreateConstInBoundsGEP1_64(V, Offset/8);
     810              284:   V = CGF.Builder.CreateBitCast(V, BaseClassType->getPointerTo());
     811              284:   CGF.EmitAggExpr(BaseInit->getInit(), V, false, false, true);
     812                 :   
                        0: branch 0 not taken
                      284: branch 1 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                      284: branch 6 taken
     813              284:   if (CGF.Exceptions && !BaseClassDecl->hasTrivialDestructor()) {
     814                 :     // FIXME: Is this OK for C++0x delegating constructors?
     815                0:     CodeGenFunction::EHCleanupBlock Cleanup(CGF);
     816                 : 
     817                0:     llvm::Value *ThisPtr = CGF.LoadCXXThis();
     818                0:     llvm::Value *V = CGF.Builder.CreateBitCast(ThisPtr, Int8PtrTy);
     819                0:     V = CGF.Builder.CreateConstInBoundsGEP1_64(V, Offset / 8);
     820                0:     V = CGF.Builder.CreateBitCast(V, BaseClassType->getPointerTo());
     821                 :     
     822                0:     CXXDestructorDecl *DD = BaseClassDecl->getDestructor(CGF.getContext());
     823                0:     CGF.EmitCXXDestructorCall(DD, Dtor_Base, V);
     824                 :   }
     825                 : }
     826                 : 
     827                 : static void EmitMemberInitializer(CodeGenFunction &CGF,
     828                 :                                   const CXXRecordDecl *ClassDecl,
     829              230:                                   CXXBaseOrMemberInitializer *MemberInit) {
     830                 :   assert(MemberInit->isMemberInitializer() &&
                      230: branch 1 taken
                        0: branch 2 not taken
     831              230:          "Must have member initializer!");
     832                 :   
     833                 :   // non-static data member initializers.
     834              230:   FieldDecl *Field = MemberInit->getMember();
     835              230:   QualType FieldType = CGF.getContext().getCanonicalType(Field->getType());
     836                 : 
     837              230:   llvm::Value *ThisPtr = CGF.LoadCXXThis();
     838              230:   LValue LHS = CGF.EmitLValueForFieldInitialization(ThisPtr, Field, 0);
     839                 :   
     840                 :   // If we are initializing an anonymous union field, drill down to the field.
                       17: branch 1 taken
                      213: branch 2 taken
     841              230:   if (MemberInit->getAnonUnionMember()) {
     842               17:     Field = MemberInit->getAnonUnionMember();
     843               17:     LHS = CGF.EmitLValueForField(LHS.getAddress(), Field, 0);
     844               17:     FieldType = Field->getType();
     845                 :   }
     846                 : 
     847                 :   // FIXME: If there's no initializer and the CXXBaseOrMemberInitializer
     848                 :   // was implicitly generated, we shouldn't be zeroing memory.
     849                 :   RValue RHS;
                        5: branch 2 taken
                      225: branch 3 taken
     850              230:   if (FieldType->isReferenceType()) {
     851                 :     RHS = CGF.EmitReferenceBindingToExpr(MemberInit->getInit(),
     852                5:                                          /*IsInitializer=*/true);
     853                5:     CGF.EmitStoreThroughLValue(RHS, LHS, FieldType);
                       22: branch 2 taken
                      203: branch 3 taken
                        0: branch 5 not taken
                       22: branch 6 taken
                        0: branch 7 not taken
                      225: branch 8 taken
     854              225:   } else if (FieldType->isArrayType() && !MemberInit->getInit()) {
     855                0:     CGF.EmitMemSetToZero(LHS.getAddress(), Field->getType());
                      151: branch 2 taken
                       74: branch 3 taken
     856              225:   } else if (!CGF.hasAggregateLLVMType(Field->getType())) {
     857              151:     RHS = RValue::get(CGF.EmitScalarExpr(MemberInit->getInit(), true));
     858              151:     CGF.EmitStoreThroughLValue(RHS, LHS, FieldType);
                        2: branch 4 taken
                       72: branch 5 taken
     859               74:   } else if (MemberInit->getInit()->getType()->isAnyComplexType()) {
     860                 :     CGF.EmitComplexExprIntoAddr(MemberInit->getInit(), LHS.getAddress(),
     861                2:                                 LHS.isVolatileQualified());
     862                 :   } else {
     863                 :     CGF.EmitAggExpr(MemberInit->getInit(), LHS.getAddress(), 
     864               72:                     LHS.isVolatileQualified(), false, true);
     865                 :     
                       72: branch 0 taken
                        0: branch 1 not taken
     866               72:     if (!CGF.Exceptions)
     867               72:       return;
     868                 : 
     869                0:     const RecordType *RT = FieldType->getAs<RecordType>();
                        0: branch 0 not taken
                        0: branch 1 not taken
     870                0:     if (!RT)
     871                0:       return;
     872                 :     
     873                0:     CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
                        0: branch 1 not taken
                        0: branch 2 not taken
     874                0:     if (!RD->hasTrivialDestructor()) {
     875                 :       // FIXME: Is this OK for C++0x delegating constructors?
     876                0:       CodeGenFunction::EHCleanupBlock Cleanup(CGF);
     877                 :       
     878                0:       llvm::Value *ThisPtr = CGF.LoadCXXThis();
     879                0:       LValue LHS = CGF.EmitLValueForField(ThisPtr, Field, 0);
     880                 : 
     881                0:       CXXDestructorDecl *DD = RD->getDestructor(CGF.getContext());
     882                0:       CGF.EmitCXXDestructorCall(DD, Dtor_Complete, LHS.getAddress());
     883                 :     }
     884                 :   }
     885                 : }
     886                 : 
     887                 : /// EmitCtorPrologue - This routine generates necessary code to initialize
     888                 : /// base classes and non-static data members belonging to this constructor.
     889                 : /// FIXME: This needs to take a CXXCtorType.
     890                 : void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
     891              471:                                        CXXCtorType CtorType) {
     892              471:   const CXXRecordDecl *ClassDecl = CD->getParent();
     893                 : 
     894              471:   llvm::SmallVector<CXXBaseOrMemberInitializer *, 8> MemberInitializers;
     895                 :   
     896                 :   // FIXME: Add vbase initialization
     897                 :   
                      659: branch 1 taken
                      471: branch 2 taken
     898             1601:   for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
     899              471:        E = CD->init_end();
     900                 :        B != E; ++B) {
     901              659:     CXXBaseOrMemberInitializer *Member = (*B);
     902                 :     
     903                 :     assert(LiveTemporaries.empty() &&
                      659: branch 1 taken
                        0: branch 2 not taken
     904              659:            "Should not have any live temporaries at initializer start!");
     905                 : 
                      429: branch 1 taken
                      230: branch 2 taken
     906              659:     if (Member->isBaseInitializer())
     907              429:       EmitBaseInitializer(*this, ClassDecl, Member, CtorType);
     908                 :     else
     909              230:       MemberInitializers.push_back(Member);
     910                 :   }
     911                 : 
     912              471:   InitializeVtablePtrs(ClassDecl);
     913                 : 
                      230: branch 1 taken
                      471: branch 2 taken
     914             1402:   for (unsigned I = 0, E = MemberInitializers.size(); I != E; ++I) {
     915                 :     assert(LiveTemporaries.empty() &&
                      230: branch 1 taken
                        0: branch 2 not taken
     916              230:            "Should not have any live temporaries at initializer start!");
     917                 :     
     918              230:     EmitMemberInitializer(*this, ClassDecl, MemberInitializers[I]);
     919              471:   }
     920              471: }
     921                 : 
     922                 : /// EmitDtorEpilogue - Emit all code that comes at the end of class's
     923                 : /// destructor. This is to call destructors on members and base classes
     924                 : /// in reverse order of their construction.
     925                 : /// FIXME: This needs to take a CXXDtorType.
     926                 : void CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD,
     927              105:                                        CXXDtorType DtorType) {
     928                 :   assert(!DD->isTrivial() &&
                      105: branch 1 taken
                        0: branch 2 not taken
     929              105:          "Should not emit dtor epilogue for trivial dtor!");
     930                 : 
     931              105:   const CXXRecordDecl *ClassDecl = DD->getParent();
     932                 : 
     933                 :   // Collect the fields.
     934              105:   llvm::SmallVector<const FieldDecl *, 16> FieldDecls;
                       67: branch 3 taken
                      105: branch 4 taken
     935              277:   for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(),
     936              105:        E = ClassDecl->field_end(); I != E; ++I) {
     937               67:     const FieldDecl *Field = *I;
     938                 :     
     939               67:     QualType FieldType = getContext().getCanonicalType(Field->getType());
     940               67:     FieldType = getContext().getBaseElementType(FieldType);
     941                 :     
     942               67:     const RecordType *RT = FieldType->getAs<RecordType>();
                       48: branch 0 taken
                       19: branch 1 taken
     943               67:     if (!RT)
     944               48:       continue;
     945                 :     
     946               19:     CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
                        0: branch 1 not taken
                       19: branch 2 taken
     947               19:     if (FieldClassDecl->hasTrivialDestructor())
     948                0:         continue;
     949                 :     
     950               19:     FieldDecls.push_back(Field);
     951                 :   }
     952                 :   
     953                 :   // Now destroy the fields.
                       19: branch 1 taken
                      105: branch 2 taken
     954              124:   for (size_t i = FieldDecls.size(); i > 0; --i) {
     955               19:     const FieldDecl *Field = FieldDecls[i - 1];
     956                 :     
     957               19:     QualType FieldType = Field->getType();
     958                 :     const ConstantArrayType *Array = 
     959               19:       getContext().getAsConstantArrayType(FieldType);
                        6: branch 0 taken
                       13: branch 1 taken
     960               19:     if (Array)
     961                6:       FieldType = getContext().getBaseElementType(FieldType);
     962                 :     
     963               19:     const RecordType *RT = FieldType->getAs<RecordType>();
     964               19:     CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
     965                 : 
     966               19:     llvm::Value *ThisPtr = LoadCXXThis();
     967                 : 
     968                 :     LValue LHS = EmitLValueForField(ThisPtr, Field, 
     969                 :                                     // FIXME: Qualifiers?
     970               19:                                     /*CVRQualifiers=*/0);
                        6: branch 0 taken
                       13: branch 1 taken
     971               19:     if (Array) {
     972                6:       const llvm::Type *BasePtr = ConvertType(FieldType);
     973                6:       BasePtr = llvm::PointerType::getUnqual(BasePtr);
     974                 :       llvm::Value *BaseAddrPtr =
     975                6:         Builder.CreateBitCast(LHS.getAddress(), BasePtr);
     976                 :       EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()),
     977                6:                                 Array, BaseAddrPtr);
     978                 :     } else
     979                 :       EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
     980               13:                             Dtor_Complete, LHS.getAddress());
     981                 :   }
     982                 : 
     983                 :   // Destroy non-virtual bases.
                       43: branch 2 taken
                      105: branch 3 taken
     984              148:   for (CXXRecordDecl::reverse_base_class_const_iterator I = 
     985              105:         ClassDecl->bases_rbegin(), E = ClassDecl->bases_rend(); I != E; ++I) {
     986               43:     const CXXBaseSpecifier &Base = *I;
     987                 :     
     988                 :     // Ignore virtual bases.
                        3: branch 1 taken
                       40: branch 2 taken
     989               43:     if (Base.isVirtual())
     990                3:       continue;
     991                 :     
     992                 :     CXXRecordDecl *BaseClassDecl
     993               40:       = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
     994                 :     
     995                 :     // Ignore trivial destructors.
                        0: branch 1 not taken
                       40: branch 2 taken
     996               40:     if (BaseClassDecl->hasTrivialDestructor())
     997                0:       continue;
     998               40:     const CXXDestructorDecl *D = BaseClassDecl->getDestructor(getContext());
     999                 :     
    1000                 :     llvm::Value *V = GetAddressOfBaseClass(LoadCXXThis(),
    1001                 :                                            ClassDecl, BaseClassDecl, 
    1002               40:                                            /*NullCheckValue=*/false);
    1003               40:     EmitCXXDestructorCall(D, Dtor_Base, V);
    1004                 :   }
    1005                 : 
    1006                 :   // If we're emitting a base destructor, we don't want to emit calls to the
    1007                 :   // virtual bases.
                       26: branch 0 taken
                       79: branch 1 taken
    1008              105:   if (DtorType == Dtor_Base)
    1009               26:     return;
    1010                 :   
    1011                 :   // Handle virtual bases.
                        4: branch 2 taken
                       79: branch 3 taken
    1012               83:   for (CXXRecordDecl::reverse_base_class_const_iterator I = 
    1013               79:        ClassDecl->vbases_rbegin(), E = ClassDecl->vbases_rend(); I != E; ++I) {
    1014                4:     const CXXBaseSpecifier &Base = *I;
    1015                 :     CXXRecordDecl *BaseClassDecl
    1016                4:     = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
    1017                 :     
    1018                 :     // Ignore trivial destructors.
                        0: branch 1 not taken
                        4: branch 2 taken
    1019                4:     if (BaseClassDecl->hasTrivialDestructor())
    1020                0:       continue;
    1021                4:     const CXXDestructorDecl *D = BaseClassDecl->getDestructor(getContext());
    1022                 :     llvm::Value *V = GetAddressOfBaseClass(LoadCXXThis(),
    1023                 :                                            ClassDecl, BaseClassDecl, 
    1024                4:                                            /*NullCheckValue=*/false);
    1025                4:     EmitCXXDestructorCall(D, Dtor_Base, V);
    1026                 :   }
    1027                 :     
    1028                 :   // If we have a deleting destructor, emit a call to the delete operator.
                       21: branch 0 taken
                       58: branch 1 taken
    1029               79:   if (DtorType == Dtor_Deleting) {
    1030                 :     assert(DD->getOperatorDelete() && 
                       21: branch 1 taken
                        0: branch 2 not taken
    1031               21:            "operator delete missing - EmitDtorEpilogue");
    1032                 :     EmitDeleteCall(DD->getOperatorDelete(), LoadCXXThis(),
    1033               21:                    getContext().getTagDeclType(ClassDecl));
                       79: branch 1 taken
                       26: branch 2 taken
    1034              105:   }
    1035                 : }
    1036                 : 
    1037                 : void CodeGenFunction::SynthesizeDefaultDestructor(const CXXDestructorDecl *Dtor,
    1038                 :                                                   CXXDtorType DtorType,
    1039                 :                                                   llvm::Function *Fn,
    1040               17:                                                   const FunctionArgList &Args) {
    1041                 :   assert(!Dtor->getParent()->hasUserDeclaredDestructor() &&
                       17: branch 2 taken
                        0: branch 3 not taken
    1042               17:          "SynthesizeDefaultDestructor - destructor has user declaration");
    1043                 : 
    1044                 :   StartFunction(GlobalDecl(Dtor, DtorType), Dtor->getResultType(), Fn, Args, 
    1045               17:                 SourceLocation());
    1046               17:   InitializeVtablePtrs(Dtor->getParent());
    1047               17:   EmitDtorEpilogue(Dtor, DtorType);
    1048               17:   FinishFunction();
    1049               17: }
    1050                 : 
    1051                 : /// EmitCXXAggrConstructorCall - This routine essentially creates a (nested)
    1052                 : /// for-loop to call the default constructor on individual members of the
    1053                 : /// array. 
    1054                 : /// 'D' is the default constructor for elements of the array, 'ArrayTy' is the
    1055                 : /// array type and 'ArrayPtr' points to the beginning fo the array.
    1056                 : /// It is assumed that all relevant checks have been made by the caller.
    1057                 : void
    1058                 : CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
    1059                 :                                           const ConstantArrayType *ArrayTy,
    1060                 :                                           llvm::Value *ArrayPtr,
    1061                 :                                           CallExpr::const_arg_iterator ArgBeg,
    1062               27:                                           CallExpr::const_arg_iterator ArgEnd) {
    1063                 : 
    1064               27:   const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
    1065                 :   llvm::Value * NumElements =
    1066                 :     llvm::ConstantInt::get(SizeTy, 
    1067               27:                            getContext().getConstantArrayElementCount(ArrayTy));
    1068                 : 
    1069               27:   EmitCXXAggrConstructorCall(D, NumElements, ArrayPtr, ArgBeg, ArgEnd);
    1070               27: }
    1071                 : 
    1072                 : void
    1073                 : CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
    1074                 :                                           llvm::Value *NumElements,
    1075                 :                                           llvm::Value *ArrayPtr,
    1076                 :                                           CallExpr::const_arg_iterator ArgBeg,
    1077               40:                                           CallExpr::const_arg_iterator ArgEnd) {
    1078               40:   const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
    1079                 : 
    1080                 :   // Create a temporary for the loop index and initialize it with 0.
    1081               40:   llvm::Value *IndexPtr = CreateTempAlloca(SizeTy, "loop.index");
    1082               40:   llvm::Value *Zero = llvm::Constant::getNullValue(SizeTy);
    1083               40:   Builder.CreateStore(Zero, IndexPtr);
    1084                 : 
    1085                 :   // Start the loop with a block that tests the condition.
    1086               40:   llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
    1087               40:   llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
    1088                 : 
    1089               40:   EmitBlock(CondBlock);
    1090                 : 
    1091               40:   llvm::BasicBlock *ForBody = createBasicBlock("for.body");
    1092                 : 
    1093                 :   // Generate: if (loop-index < number-of-elements fall to the loop body,
    1094                 :   // otherwise, go to the block after the for-loop.
    1095               40:   llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
    1096               40:   llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElements, "isless");
    1097                 :   // If the condition is true, execute the body.
    1098               40:   Builder.CreateCondBr(IsLess, ForBody, AfterFor);
    1099                 : 
    1100               40:   EmitBlock(ForBody);
    1101                 : 
    1102               40:   llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
    1103                 :   // Inside the loop body, emit the constructor call on the array element.
    1104               40:   Counter = Builder.CreateLoad(IndexPtr);
    1105                 :   llvm::Value *Address = Builder.CreateInBoundsGEP(ArrayPtr, Counter, 
    1106               40:                                                    "arrayidx");
    1107                 : 
    1108                 :   // C++ [class.temporary]p4: 
    1109                 :   // There are two contexts in which temporaries are destroyed at a different
    1110                 :   // point than the end of the full-expression. The first context is when a
    1111                 :   // default constructor is called to initialize an element of an array. 
    1112                 :   // If the constructor has one or more default arguments, the destruction of 
    1113                 :   // every temporary created in a default argument expression is sequenced 
    1114                 :   // before the construction of the next array element, if any.
    1115                 :   
    1116                 :   // Keep track of the current number of live temporaries.
    1117               40:   unsigned OldNumLiveTemporaries = LiveTemporaries.size();
    1118                 : 
    1119               40:   EmitCXXConstructorCall(D, Ctor_Complete, Address, ArgBeg, ArgEnd);
    1120                 : 
    1121                 :   // Pop temporaries.
                        8: branch 1 taken
                       40: branch 2 taken
    1122               88:   while (LiveTemporaries.size() > OldNumLiveTemporaries)
    1123                8:     PopCXXTemporary();
    1124                 :   
    1125               40:   EmitBlock(ContinueBlock);
    1126                 : 
    1127                 :   // Emit the increment of the loop counter.
    1128               40:   llvm::Value *NextVal = llvm::ConstantInt::get(SizeTy, 1);
    1129               40:   Counter = Builder.CreateLoad(IndexPtr);
    1130               40:   NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
    1131               40:   Builder.CreateStore(NextVal, IndexPtr);
    1132                 : 
    1133                 :   // Finally, branch back up to the condition for the next iteration.
    1134               40:   EmitBranch(CondBlock);
    1135                 : 
    1136                 :   // Emit the fall-through block.
    1137               40:   EmitBlock(AfterFor, true);
    1138               40: }
    1139                 : 
    1140                 : /// EmitCXXAggrDestructorCall - calls the default destructor on array
    1141                 : /// elements in reverse order of construction.
    1142                 : void
    1143                 : CodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
    1144                 :                                            const ArrayType *Array,
    1145               14:                                            llvm::Value *This) {
    1146               14:   const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
                        0: branch 0 not taken
                       14: branch 1 taken
    1147               14:   assert(CA && "Do we support VLA for destruction ?");
    1148               14:   uint64_t ElementCount = getContext().getConstantArrayElementCount(CA);
    1149                 :   
    1150               14:   const llvm::Type *SizeLTy = ConvertType(getContext().getSizeType());
    1151               14:   llvm::Value* ElementCountPtr = llvm::ConstantInt::get(SizeLTy, ElementCount);
    1152               14:   EmitCXXAggrDestructorCall(D, ElementCountPtr, This);
    1153               14: }
    1154                 : 
    1155                 : /// EmitCXXAggrDestructorCall - calls the default destructor on array
    1156                 : /// elements in reverse order of construction.
    1157                 : void
    1158                 : CodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
    1159                 :                                            llvm::Value *UpperCount,
    1160               22:                                            llvm::Value *This) {
    1161               22:   const llvm::Type *SizeLTy = ConvertType(getContext().getSizeType());
    1162               22:   llvm::Value *One = llvm::ConstantInt::get(SizeLTy, 1);
    1163                 :   
    1164                 :   // Create a temporary for the loop index and initialize it with count of
    1165                 :   // array elements.
    1166               22:   llvm::Value *IndexPtr = CreateTempAlloca(SizeLTy, "loop.index");
    1167                 : 
    1168                 :   // Store the number of elements in the index pointer.
    1169               22:   Builder.CreateStore(UpperCount, IndexPtr);
    1170                 : 
    1171                 :   // Start the loop with a block that tests the condition.
    1172               22:   llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
    1173               22:   llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
    1174                 : 
    1175               22:   EmitBlock(CondBlock);
    1176                 : 
    1177               22:   llvm::BasicBlock *ForBody = createBasicBlock("for.body");
    1178                 : 
    1179                 :   // Generate: if (loop-index != 0 fall to the loop body,
    1180                 :   // otherwise, go to the block after the for-loop.
    1181                 :   llvm::Value* zeroConstant =
    1182               22:     llvm::Constant::getNullValue(SizeLTy);
    1183               22:   llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
    1184                 :   llvm::Value *IsNE = Builder.CreateICmpNE(Counter, zeroConstant,
    1185               22:                                             "isne");
    1186                 :   // If the condition is true, execute the body.
    1187               22:   Builder.CreateCondBr(IsNE, ForBody, AfterFor);
    1188                 : 
    1189               22:   EmitBlock(ForBody);
    1190                 : 
    1191               22:   llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
    1192                 :   // Inside the loop body, emit the constructor call on the array element.
    1193               22:   Counter = Builder.CreateLoad(IndexPtr);
    1194               22:   Counter = Builder.CreateSub(Counter, One);
    1195               22:   llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx");
    1196               22:   EmitCXXDestructorCall(D, Dtor_Complete, Address);
    1197                 : 
    1198               22:   EmitBlock(ContinueBlock);
    1199                 : 
    1200                 :   // Emit the decrement of the loop counter.
    1201               22:   Counter = Builder.CreateLoad(IndexPtr);
    1202               22:   Counter = Builder.CreateSub(Counter, One, "dec");
    1203               22:   Builder.CreateStore(Counter, IndexPtr);
    1204                 : 
    1205                 :   // Finally, branch back up to the condition for the next iteration.
    1206               22:   EmitBranch(CondBlock);
    1207                 : 
    1208                 :   // Emit the fall-through block.
    1209               22:   EmitBlock(AfterFor, true);
    1210               22: }
    1211                 : 
    1212                 : /// GenerateCXXAggrDestructorHelper - Generates a helper function which when
    1213                 : /// invoked, calls the default destructor on array elements in reverse order of
    1214                 : /// construction.
    1215                 : llvm::Constant * 
    1216                 : CodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D,
    1217                 :                                                  const ArrayType *Array,
    1218                6:                                                  llvm::Value *This) {
    1219                6:   FunctionArgList Args;
    1220                 :   ImplicitParamDecl *Dst =
    1221                 :     ImplicitParamDecl::Create(getContext(), 0,
    1222                 :                               SourceLocation(), 0,
    1223                6:                               getContext().getPointerType(getContext().VoidTy));
    1224                6:   Args.push_back(std::make_pair(Dst, Dst->getType()));
    1225                 :   
    1226                6:   llvm::SmallString<16> Name;
    1227                6:   llvm::raw_svector_ostream(Name) << "__tcf_" << (++UniqueAggrDestructorCount);
    1228                6:   QualType R = getContext().VoidTy;
    1229                 :   const CGFunctionInfo &FI
    1230                6:     = CGM.getTypes().getFunctionInfo(R, Args, CC_Default, false);
    1231                6:   const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false);
    1232                 :   llvm::Function *Fn =
    1233                 :     llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
    1234                 :                            Name.str(),
    1235                6:                            &CGM.getModule());
    1236                6:   IdentifierInfo *II = &CGM.getContext().Idents.get(Name.str());
    1237                 :   FunctionDecl *FD = FunctionDecl::Create(getContext(),
    1238                 :                                           getContext().getTranslationUnitDecl(),
    1239                 :                                           SourceLocation(), II, R, 0,
    1240                 :                                           FunctionDecl::Static,
                        6: branch 4 taken
                        0: branch 5 not taken
    1241                6:                                           false, true);
    1242                6:   StartFunction(FD, R, Fn, Args, SourceLocation());
    1243                6:   QualType BaseElementTy = getContext().getBaseElementType(Array);
    1244                6:   const llvm::Type *BasePtr = ConvertType(BaseElementTy);
    1245                6:   BasePtr = llvm::PointerType::getUnqual(BasePtr);
    1246                6:   llvm::Value *BaseAddrPtr = Builder.CreateBitCast(This, BasePtr);
    1247                6:   EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr);
    1248                6:   FinishFunction();
    1249                 :   llvm::Type *Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),
    1250                6:                                               0);
    1251                6:   llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty);
    1252                6:   return m;
    1253                 : }
    1254                 : 
    1255                 : 
    1256                 : void
    1257                 : CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
    1258                 :                                         CXXCtorType Type,
    1259                 :                                         llvm::Value *This,
    1260                 :                                         CallExpr::const_arg_iterator ArgBeg,
    1261              733:                                         CallExpr::const_arg_iterator ArgEnd) {
                       51: branch 1 taken
                      682: branch 2 taken
    1262              733:   if (D->isTrivial()) {
                        3: branch 1 taken
                       48: branch 2 taken
    1263               51:     if (ArgBeg == ArgEnd) {
    1264                 :       // Trivial default constructor, no codegen required.
    1265                 :       assert(D->isDefaultConstructor() &&
                        3: branch 1 taken
                        0: branch 2 not taken
    1266                3:              "trivial 0-arg ctor not a default ctor");
    1267                3:       return;
    1268                 :     }
    1269                 : 
                       48: branch 2 taken
                        0: branch 3 not taken
    1270               48:     assert(ArgBeg + 1 == ArgEnd && "unexpected argcount for trivial ctor");
                       48: branch 1 taken
                        0: branch 2 not taken
    1271               48:     assert(D->isCopyConstructor() && "trivial 1-arg ctor not a copy ctor");
    1272                 : 
    1273               48:     const Expr *E = (*ArgBeg);
    1274               48:     QualType Ty = E->getType();
    1275               48:     llvm::Value *Src = EmitLValue(E).getAddress();
    1276               48:     EmitAggregateCopy(This, Src, Ty);
    1277               48:     return;
    1278                 :   }
    1279                 : 
    1280              682:   llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(D, Type));
    1281              682:   llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
    1282                 : 
    1283              682:   EmitCXXMemberCall(D, Callee, ReturnValueSlot(), This, VTT, ArgBeg, ArgEnd);
    1284                 : }
    1285                 : 
    1286                 : void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD,
    1287                 :                                             CXXDtorType Type,
    1288              209:                                             llvm::Value *This) {
    1289              209:   llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(DD, Type));
    1290              209:   llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(DD, Type);
    1291                 :   
    1292              209:   EmitCXXMemberCall(DD, Callee, ReturnValueSlot(), This, VTT, 0, 0);
    1293              209: }
    1294                 : 
    1295                 : llvm::Value *
    1296                 : CodeGenFunction::GetVirtualBaseClassOffset(llvm::Value *This,
    1297                 :                                            const CXXRecordDecl *ClassDecl,
    1298               12:                                            const CXXRecordDecl *BaseClassDecl) {
    1299                 :   const llvm::Type *Int8PtrTy = 
    1300               12:     llvm::Type::getInt8Ty(VMContext)->getPointerTo();
    1301                 : 
    1302                 :   llvm::Value *VTablePtr = Builder.CreateBitCast(This, 
    1303               12:                                                  Int8PtrTy->getPointerTo());
    1304               12:   VTablePtr = Builder.CreateLoad(VTablePtr, "vtable");
    1305                 : 
    1306                 :   int64_t VBaseOffsetIndex = 
    1307               12:     CGM.getVtableInfo().getVirtualBaseOffsetIndex(ClassDecl, BaseClassDecl);
    1308                 :   
    1309                 :   llvm::Value *VBaseOffsetPtr = 
    1310               12:     Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetIndex, "vbase.offset.ptr");
    1311                 :   const llvm::Type *PtrDiffTy = 
    1312               12:     ConvertType(getContext().getPointerDiffType());
    1313                 :   
    1314                 :   VBaseOffsetPtr = Builder.CreateBitCast(VBaseOffsetPtr, 
    1315               12:                                          PtrDiffTy->getPointerTo());
    1316                 :                                          
    1317               12:   llvm::Value *VBaseOffset = Builder.CreateLoad(VBaseOffsetPtr, "vbase.offset");
    1318                 :   
    1319               12:   return VBaseOffset;
    1320                 : }
    1321                 : 
    1322              581: void CodeGenFunction::InitializeVtablePtrs(const CXXRecordDecl *ClassDecl) {
                      239: branch 1 taken
                      342: branch 2 taken
    1323              581:   if (!ClassDecl->isDynamicClass())
    1324              239:     return;
    1325                 : 
    1326              342:   llvm::Constant *Vtable = CGM.getVtableInfo().getVtable(ClassDecl);
    1327                 :   CGVtableInfo::AddrSubMap_t& AddressPoints =
    1328              342:       *(*CGM.getVtableInfo().AddressPoints[ClassDecl])[ClassDecl];
    1329              342:   llvm::Value *ThisPtr = LoadCXXThis();
    1330              342:   const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl);
    1331                 : 
    1332                 :   // Store address points for virtual bases
                      282: branch 0 taken
                      342: branch 1 taken
    1333              624:   for (CXXRecordDecl::base_class_const_iterator I = 
    1334              342:        ClassDecl->vbases_begin(), E = ClassDecl->vbases_end(); I != E; ++I) {
    1335              282:     const CXXBaseSpecifier &Base = *I;
    1336                 :     CXXRecordDecl *BaseClassDecl
    1337              282:       = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
    1338              282:     uint64_t Offset = Layout.getVBaseClassOffset(BaseClassDecl);
    1339                 :     InitializeVtablePtrsRecursive(BaseClassDecl, Vtable, AddressPoints,
    1340              282:                                   ThisPtr, Offset);
    1341                 :   }
    1342                 : 
    1343                 :   // Store address points for non-virtual bases and current class
    1344              342:   InitializeVtablePtrsRecursive(ClassDecl, Vtable, AddressPoints, ThisPtr, 0);
    1345                 : }
    1346                 : 
    1347                 : void CodeGenFunction::InitializeVtablePtrsRecursive(
    1348                 :         const CXXRecordDecl *ClassDecl,
    1349                 :         llvm::Constant *Vtable,
    1350                 :         CGVtableInfo::AddrSubMap_t& AddressPoints,
    1351                 :         llvm::Value *ThisPtr,
    1352              829:         uint64_t Offset) {
                      736: branch 1 taken
                       93: branch 2 taken
    1353              829:   if (!ClassDecl->isDynamicClass())
    1354               93:     return;
    1355                 : 
    1356                 :   // Store address points for non-virtual bases
    1357              736:   const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl);
                      504: branch 0 taken
                      736: branch 1 taken
    1358             1240:   for (CXXRecordDecl::base_class_const_iterator I = 
    1359              736:        ClassDecl->bases_begin(), E = ClassDecl->bases_end(); I != E; ++I) {
    1360              504:     const CXXBaseSpecifier &Base = *I;
                      299: branch 1 taken
                      205: branch 2 taken
    1361              504:     if (Base.isVirtual())
    1362              299:       continue;
    1363                 :     CXXRecordDecl *BaseClassDecl
    1364              205:       = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
    1365              205:     uint64_t NewOffset = Offset + Layout.getBaseClassOffset(BaseClassDecl);
    1366                 :     InitializeVtablePtrsRecursive(BaseClassDecl, Vtable, AddressPoints,
    1367              205:                                   ThisPtr, NewOffset);
    1368                 :   }
    1369                 : 
    1370                 :   // Compute the address point
    1371                 :   assert(AddressPoints.count(std::make_pair(ClassDecl, Offset)) &&
                      736: branch 2 taken
                        0: branch 3 not taken
    1372              736:          "Missing address point for class");
    1373              736:   uint64_t AddressPoint = AddressPoints[std::make_pair(ClassDecl, Offset)];
    1374                 :   llvm::Value *VtableAddressPoint =
    1375              736:       Builder.CreateConstInBoundsGEP2_64(Vtable, 0, AddressPoint);
    1376                 : 
    1377                 :   // Compute the address to store the address point
    1378              736:   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
    1379              736:   llvm::Value *VtableField = Builder.CreateBitCast(ThisPtr, Int8PtrTy);
    1380              736:   VtableField = Builder.CreateConstInBoundsGEP1_64(VtableField, Offset/8);
    1381                 :   const llvm::Type *AddressPointPtrTy =
    1382              736:       VtableAddressPoint->getType()->getPointerTo();
    1383              736:   VtableField = Builder.CreateBitCast(VtableField, AddressPointPtrTy);
    1384                 : 
    1385                 :   // Store address point
    1386              736:   Builder.CreateStore(VtableAddressPoint, VtableField);
    1387                 : }
    1388                 : 
    1389                8: llvm::Value *CodeGenFunction::LoadCXXVTT() {
    1390                 :   assert((isa<CXXConstructorDecl>(CurFuncDecl) ||
    1391                 :           isa<CXXDestructorDecl>(CurFuncDecl)) &&
                        0: branch 1 not taken
                        8: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
    1392                8:          "Must be in a C++ ctor or dtor to load the vtt parameter");
    1393                 : 
    1394                8:   return Builder.CreateLoad(LocalDeclMap[CXXVTTDecl], "vtt");
    1395                 : }

Generated: 2010-02-10 01:31 by zcov