zcov: / lib/CodeGen/CGExprCXX.cpp


Files: 1 Branches Taken: 77.1% 185 / 240
Generated: 2010-02-10 01:31 Branches Executed: 93.3% 224 / 240
Line Coverage: 89.8% 406 / 452


Programs: 1 Runs 2897


       1                 : //===--- CGExprCXX.cpp - Emit LLVM Code for C++ expressions ---------------===//
       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 code generation of C++ expressions
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "CodeGenFunction.h"
      15                 : using namespace clang;
      16                 : using namespace CodeGen;
      17                 : 
      18                 : RValue CodeGenFunction::EmitCXXMemberCall(const CXXMethodDecl *MD,
      19                 :                                           llvm::Value *Callee,
      20                 :                                           ReturnValueSlot ReturnValue,
      21                 :                                           llvm::Value *This,
      22                 :                                           llvm::Value *VTT,
      23                 :                                           CallExpr::const_arg_iterator ArgBeg,
      24             1175:                                           CallExpr::const_arg_iterator ArgEnd) {
      25                 :   assert(MD->isInstance() &&
                     1175: branch 1 taken
                        0: branch 2 not taken
      26             1175:          "Trying to emit a member call expr on a static method!");
      27                 : 
      28             1175:   const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
      29                 : 
      30             1175:   CallArgList Args;
      31                 : 
      32                 :   // Push the this ptr.
      33                 :   Args.push_back(std::make_pair(RValue::get(This),
      34             1175:                                 MD->getThisType(getContext())));
      35                 : 
      36                 :   // If there is a VTT parameter, emit it.
                       84: branch 0 taken
                     1091: branch 1 taken
      37             1175:   if (VTT) {
      38               84:     QualType T = getContext().getPointerType(getContext().VoidPtrTy);
      39               84:     Args.push_back(std::make_pair(RValue::get(VTT), T));
      40                 :   }
      41                 :   
      42                 :   // And the rest of the call args
      43             1175:   EmitCallArgs(Args, FPT, ArgBeg, ArgEnd);
      44                 : 
      45             1175:   QualType ResultType = FPT->getResultType();
      46                 :   return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args,
      47                 :                                                  FPT->getCallConv(),
      48                 :                                                  FPT->getNoReturnAttr()), Callee, 
      49             1175:                   ReturnValue, Args, MD);
      50                 : }
      51                 : 
      52                 : /// canDevirtualizeMemberFunctionCalls - Checks whether virtual calls on given
      53                 : /// expr can be devirtualized.
      54               30: static bool canDevirtualizeMemberFunctionCalls(const Expr *Base) {
                       17: branch 1 taken
                       13: branch 2 taken
      55               30:   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Base)) {
                       17: branch 2 taken
                        0: branch 3 not taken
      56               17:     if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
      57                 :       // This is a record decl. We know the type and can devirtualize it.
      58               17:       return VD->getType()->isRecordType();
      59                 :     }
      60                 :     
      61                0:     return false;
      62                 :   }
      63                 :   
      64                 :   // We can always devirtualize calls on temporary object expressions.
                        1: branch 1 taken
                       12: branch 2 taken
      65               13:   if (isa<CXXConstructExpr>(Base))
      66                1:     return true;
      67                 :   
      68                 :   // And calls on bound temporaries.
                        2: branch 1 taken
                       10: branch 2 taken
      69               12:   if (isa<CXXBindTemporaryExpr>(Base))
      70                2:     return true;
      71                 :   
      72                 :   // Check if this is a call expr that returns a record type.
                        2: branch 1 taken
                        8: branch 2 taken
      73               10:   if (const CallExpr *CE = dyn_cast<CallExpr>(Base))
      74                2:     return CE->getCallReturnType()->isRecordType();
      75                 :   
      76                 :   // We can't devirtualize the call.
      77                8:   return false;
      78                 : }
      79                 : 
      80                 : RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
      81              269:                                               ReturnValueSlot ReturnValue) {
                       10: branch 3 taken
                      259: branch 4 taken
      82              269:   if (isa<BinaryOperator>(CE->getCallee()->IgnoreParens())) 
      83               10:     return EmitCXXMemberPointerCallExpr(CE, ReturnValue);
      84                 :       
      85              259:   const MemberExpr *ME = cast<MemberExpr>(CE->getCallee()->IgnoreParens());
      86              259:   const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
      87                 : 
                        2: branch 1 taken
                      257: branch 2 taken
      88              259:   if (MD->isStatic()) {
      89                 :     // The method is static, emit it as we would a regular call.
      90                2:     llvm::Value *Callee = CGM.GetAddrOfFunction(MD);
      91                 :     return EmitCall(getContext().getPointerType(MD->getType()), Callee,
      92                2:                     ReturnValue, CE->arg_begin(), CE->arg_end());
      93                 :   }
      94                 :   
      95              257:   const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
      96                 : 
      97                 :   const llvm::Type *Ty =
      98                 :     CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
      99              257:                                    FPT->isVariadic());
     100                 :   llvm::Value *This;
     101                 : 
                       51: branch 1 taken
                      206: branch 2 taken
     102              257:   if (ME->isArrow())
     103               51:     This = EmitScalarExpr(ME->getBase());
     104                 :   else {
     105              206:     LValue BaseLV = EmitLValue(ME->getBase());
     106              206:     This = BaseLV.getAddress();
     107                 :   }
     108                 : 
                        0: branch 1 not taken
                      257: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                      257: branch 7 taken
     109              257:   if (MD->isCopyAssignment() && MD->isTrivial()) {
     110                 :     // We don't like to generate the trivial copy assignment operator when
     111                 :     // it isn't necessary; just produce the proper effect here.
     112                0:     llvm::Value *RHS = EmitLValue(*CE->arg_begin()).getAddress();
     113                0:     EmitAggregateCopy(This, RHS, CE->getType());
     114                0:     return RValue::get(This);
     115                 :   }
     116                 : 
     117                 :   // C++ [class.virtual]p12:
     118                 :   //   Explicit qualification with the scope operator (5.1) suppresses the
     119                 :   //   virtual call mechanism.
     120                 :   //
     121                 :   // We also don't emit a virtual call if the base expression has a record type
     122                 :   // because then we know what the type is.
     123                 :   llvm::Value *Callee;
                        3: branch 0 taken
                      254: branch 1 taken
     124              257:   if (const CXXDestructorDecl *Destructor
     125              257:              = dyn_cast<CXXDestructorDecl>(MD)) {
                        2: branch 1 taken
                        1: branch 2 taken
     126                3:     if (Destructor->isTrivial())
     127                2:       return RValue::get(0);
                        1: branch 1 taken
                        0: branch 2 not taken
                        1: branch 4 taken
                        0: branch 5 not taken
                        1: branch 8 taken
                        0: branch 9 not taken
                        1: branch 10 taken
                        0: branch 11 not taken
     128                1:     if (MD->isVirtual() && !ME->hasQualifier() && 
     129                 :         !canDevirtualizeMemberFunctionCalls(ME->getBase())) {
     130                1:       Callee = BuildVirtualCall(Destructor, Dtor_Complete, This, Ty); 
     131                 :     } else {
     132                0:       Callee = CGM.GetAddrOfFunction(GlobalDecl(Destructor, Dtor_Complete), Ty);
     133                 :     }
                       30: branch 1 taken
                      224: branch 2 taken
                       28: branch 4 taken
                        2: branch 5 taken
                       20: branch 8 taken
                        8: branch 9 taken
                       20: branch 10 taken
                      234: branch 11 taken
     134              254:   } else if (MD->isVirtual() && !ME->hasQualifier() && 
     135                 :              !canDevirtualizeMemberFunctionCalls(ME->getBase())) {
     136               20:     Callee = BuildVirtualCall(MD, This, Ty); 
     137                 :   } else {
     138              234:     Callee = CGM.GetAddrOfFunction(MD, Ty);
     139                 :   }
     140                 : 
     141                 :   return EmitCXXMemberCall(MD, Callee, ReturnValue, This, /*VTT=*/0,
     142              255:                            CE->arg_begin(), CE->arg_end());
     143                 : }
     144                 : 
     145                 : RValue
     146                 : CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
     147               10:                                               ReturnValueSlot ReturnValue) {
     148                 :   const BinaryOperator *BO =
     149               10:       cast<BinaryOperator>(E->getCallee()->IgnoreParens());
     150               10:   const Expr *BaseExpr = BO->getLHS();
     151               10:   const Expr *MemFnExpr = BO->getRHS();
     152                 :   
     153                 :   const MemberPointerType *MPT = 
     154               10:     MemFnExpr->getType()->getAs<MemberPointerType>();
     155                 :   const FunctionProtoType *FPT = 
     156               10:     MPT->getPointeeType()->getAs<FunctionProtoType>();
     157                 :   const CXXRecordDecl *RD = 
     158               10:     cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
     159                 : 
     160                 :   const llvm::FunctionType *FTy = 
     161                 :     CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(RD, FPT),
     162               10:                                    FPT->isVariadic());
     163                 : 
     164               10:   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
     165                 : 
     166                 :   // Get the member function pointer.
     167               10:   llvm::Value *MemFnPtr = CreateMemTemp(MemFnExpr->getType(), "mem.fn");
     168               10:   EmitAggExpr(MemFnExpr, MemFnPtr, /*VolatileDest=*/false);
     169                 : 
     170                 :   // Emit the 'this' pointer.
     171                 :   llvm::Value *This;
     172                 :   
                        6: branch 1 taken
                        4: branch 2 taken
     173               10:   if (BO->getOpcode() == BinaryOperator::PtrMemI)
     174                6:     This = EmitScalarExpr(BaseExpr);
     175                 :   else 
     176                4:     This = EmitLValue(BaseExpr).getAddress();
     177                 :   
     178                 :   // Adjust it.
     179               10:   llvm::Value *Adj = Builder.CreateStructGEP(MemFnPtr, 1);
     180               10:   Adj = Builder.CreateLoad(Adj, "mem.fn.adj");
     181                 :   
     182               10:   llvm::Value *Ptr = Builder.CreateBitCast(This, Int8PtrTy, "ptr");
     183               10:   Ptr = Builder.CreateGEP(Ptr, Adj, "adj");
     184                 :   
     185               10:   This = Builder.CreateBitCast(Ptr, This->getType(), "this");
     186                 :   
     187               10:   llvm::Value *FnPtr = Builder.CreateStructGEP(MemFnPtr, 0, "mem.fn.ptr");
     188                 :   
     189               10:   const llvm::Type *PtrDiffTy = ConvertType(getContext().getPointerDiffType());
     190                 : 
     191               10:   llvm::Value *FnAsInt = Builder.CreateLoad(FnPtr, "fn");
     192                 :   
     193                 :   // If the LSB in the function pointer is 1, the function pointer points to
     194                 :   // a virtual function.
     195                 :   llvm::Value *IsVirtual 
     196                 :     = Builder.CreateAnd(FnAsInt, llvm::ConstantInt::get(PtrDiffTy, 1),
     197               10:                         "and");
     198                 :   
     199                 :   IsVirtual = Builder.CreateTrunc(IsVirtual,
     200               10:                                   llvm::Type::getInt1Ty(VMContext));
     201                 :   
     202               10:   llvm::BasicBlock *FnVirtual = createBasicBlock("fn.virtual");
     203               10:   llvm::BasicBlock *FnNonVirtual = createBasicBlock("fn.nonvirtual");
     204               10:   llvm::BasicBlock *FnEnd = createBasicBlock("fn.end");
     205                 :   
     206               10:   Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
     207               10:   EmitBlock(FnVirtual);
     208                 :   
     209                 :   const llvm::Type *VtableTy = 
     210               10:     FTy->getPointerTo()->getPointerTo();
     211                 : 
     212               10:   llvm::Value *Vtable = Builder.CreateBitCast(This, VtableTy->getPointerTo());
     213               10:   Vtable = Builder.CreateLoad(Vtable);
     214                 :   
     215               10:   Vtable = Builder.CreateBitCast(Vtable, Int8PtrTy);
     216                 :   llvm::Value *VtableOffset = 
     217               10:     Builder.CreateSub(FnAsInt, llvm::ConstantInt::get(PtrDiffTy, 1));
     218                 :   
     219               10:   Vtable = Builder.CreateGEP(Vtable, VtableOffset, "fn");
     220               10:   Vtable = Builder.CreateBitCast(Vtable, VtableTy);
     221                 :   
     222               10:   llvm::Value *VirtualFn = Builder.CreateLoad(Vtable, "virtualfn");
     223                 :   
     224               10:   EmitBranch(FnEnd);
     225               10:   EmitBlock(FnNonVirtual);
     226                 :   
     227                 :   // If the function is not virtual, just load the pointer.
     228               10:   llvm::Value *NonVirtualFn = Builder.CreateLoad(FnPtr, "fn");
     229               10:   NonVirtualFn = Builder.CreateIntToPtr(NonVirtualFn, FTy->getPointerTo());
     230                 :   
     231               10:   EmitBlock(FnEnd);
     232                 : 
     233               10:   llvm::PHINode *Callee = Builder.CreatePHI(FTy->getPointerTo());
     234               10:   Callee->reserveOperandSpace(2);
     235               10:   Callee->addIncoming(VirtualFn, FnVirtual);
     236               10:   Callee->addIncoming(NonVirtualFn, FnNonVirtual);
     237                 : 
     238               10:   CallArgList Args;
     239                 : 
     240                 :   QualType ThisType = 
     241               10:     getContext().getPointerType(getContext().getTagDeclType(RD));
     242                 : 
     243                 :   // Push the this ptr.
     244               10:   Args.push_back(std::make_pair(RValue::get(This), ThisType));
     245                 :   
     246                 :   // And the rest of the call args
     247               10:   EmitCallArgs(Args, FPT, E->arg_begin(), E->arg_end());
     248               10:   const FunctionType *BO_FPT = BO->getType()->getAs<FunctionProtoType>();
     249                 :   return EmitCall(CGM.getTypes().getFunctionInfo(Args, BO_FPT), Callee, 
     250               10:                   ReturnValue, Args);
     251                 : }
     252                 : 
     253                 : RValue
     254                 : CodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
     255                 :                                                const CXXMethodDecl *MD,
     256               36:                                                ReturnValueSlot ReturnValue) {
     257                 :   assert(MD->isInstance() &&
                       36: branch 1 taken
                        0: branch 2 not taken
     258               36:          "Trying to emit a member call expr on a static method!");
     259                 : 
                       15: branch 1 taken
                       21: branch 2 taken
     260               36:   if (MD->isCopyAssignment()) {
     261               15:     const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(MD->getDeclContext());
                        7: branch 1 taken
                        8: branch 2 taken
     262               15:     if (ClassDecl->hasTrivialCopyAssignment()) {
     263                 :       assert(!ClassDecl->hasUserDeclaredCopyAssignment() &&
                        7: branch 1 taken
                        0: branch 2 not taken
     264                7:              "EmitCXXOperatorMemberCallExpr - user declared copy assignment");
     265                7:       llvm::Value *This = EmitLValue(E->getArg(0)).getAddress();
     266                7:       llvm::Value *Src = EmitLValue(E->getArg(1)).getAddress();
     267                7:       QualType Ty = E->getType();
     268                7:       EmitAggregateCopy(This, Src, Ty);
     269                7:       return RValue::get(This);
     270                 :     }
     271                 :   }
     272                 : 
     273               29:   const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
     274                 :   const llvm::Type *Ty =
     275                 :     CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
     276               29:                                    FPT->isVariadic());
     277                 : 
     278               29:   llvm::Value *This = EmitLValue(E->getArg(0)).getAddress();
     279                 : 
     280                 :   llvm::Value *Callee;
                        1: branch 1 taken
                       28: branch 2 taken
                        1: branch 5 taken
                        0: branch 6 not taken
                        1: branch 7 taken
                       28: branch 8 taken
     281               29:   if (MD->isVirtual() && !canDevirtualizeMemberFunctionCalls(E->getArg(0)))
     282                1:     Callee = BuildVirtualCall(MD, This, Ty);
     283                 :   else
     284               28:     Callee = CGM.GetAddrOfFunction(MD, Ty);
     285                 : 
     286                 :   return EmitCXXMemberCall(MD, Callee, ReturnValue, This, /*VTT=*/0,
     287               29:                            E->arg_begin() + 1, E->arg_end());
     288                 : }
     289                 : 
     290                 : void
     291                 : CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,
     292              792:                                       const CXXConstructExpr *E) {
                        0: branch 0 not taken
                      792: branch 1 taken
     293              792:   assert(Dest && "Must have a destination!");
     294              792:   const CXXConstructorDecl *CD = E->getConstructor();
     295                 :   const ConstantArrayType *Array =
     296              792:   getContext().getAsConstantArrayType(E->getType());
     297                 :   // For a copy constructor, even if it is trivial, must fall thru so
     298                 :   // its argument is code-gen'ed.
                      671: branch 1 taken
                      121: branch 2 taken
     299              792:   if (!CD->isCopyConstructor()) {
     300              671:     QualType InitType = E->getType();
                       27: branch 0 taken
                      644: branch 1 taken
     301              671:     if (Array)
     302               27:       InitType = getContext().getBaseElementType(Array);
     303                 :     const CXXRecordDecl *RD =
     304              671:     cast<CXXRecordDecl>(InitType->getAs<RecordType>()->getDecl());
                       55: branch 1 taken
                      616: branch 2 taken
     305              671:     if (RD->hasTrivialConstructor())
     306               55:       return;
     307                 :   }
     308                 :   // Code gen optimization to eliminate copy constructor and return
     309                 :   // its first argument instead.
                      737: branch 2 taken
                        0: branch 3 not taken
                       42: branch 5 taken
                      695: branch 6 taken
                       42: branch 7 taken
                      695: branch 8 taken
     310              737:   if (getContext().getLangOptions().ElideConstructors && E->isElidable()) {
     311               42:     const Expr *Arg = E->getArg(0);
     312                 :     
                       40: branch 1 taken
                        2: branch 2 taken
     313               42:     if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) {
     314                 :       assert((ICE->getCastKind() == CastExpr::CK_NoOp ||
     315                 :               ICE->getCastKind() == CastExpr::CK_ConstructorConversion ||
     316                 :               ICE->getCastKind() == CastExpr::CK_UserDefinedConversion) &&
                       14: branch 1 taken
                       26: branch 2 taken
                        1: branch 4 taken
                       13: branch 5 taken
                        1: branch 7 taken
                        0: branch 8 not taken
     317               40:              "Unknown implicit cast kind in constructor elision");
     318               40:       Arg = ICE->getSubExpr();
     319                 :     }
     320                 :     
                        5: branch 1 taken
                       37: branch 2 taken
     321               42:     if (const CXXFunctionalCastExpr *FCE = dyn_cast<CXXFunctionalCastExpr>(Arg))
     322                5:       Arg = FCE->getSubExpr();
     323                 :     
                       16: branch 0 taken
                       26: branch 1 taken
     324               42:     if (const CXXBindTemporaryExpr *BindExpr = 
     325               42:         dyn_cast<CXXBindTemporaryExpr>(Arg))
     326               16:       Arg = BindExpr->getSubExpr();
     327                 :     
     328               42:     EmitAggExpr(Arg, Dest, false);
     329               42:     return;
     330                 :   }
                       27: branch 0 taken
                      668: branch 1 taken
     331              695:   if (Array) {
     332               27:     QualType BaseElementTy = getContext().getBaseElementType(Array);
     333               27:     const llvm::Type *BasePtr = ConvertType(BaseElementTy);
     334               27:     BasePtr = llvm::PointerType::getUnqual(BasePtr);
     335                 :     llvm::Value *BaseAddrPtr =
     336               27:     Builder.CreateBitCast(Dest, BasePtr);
     337                 :     
     338                 :     EmitCXXAggrConstructorCall(CD, Array, BaseAddrPtr, 
     339               27:                                E->arg_begin(), E->arg_end());
     340                 :   }
     341                 :   else
     342                 :     // Call the constructor.
     343                 :     EmitCXXConstructorCall(CD, 
     344                 :                            E->isBaseInitialization()? Ctor_Base : Ctor_Complete, 
     345                 :                            Dest,
                      258: branch 3 taken
                      410: branch 4 taken
     346              668:                            E->arg_begin(), E->arg_end());
     347                 : }
     348                 : 
     349               50: static CharUnits CalculateCookiePadding(ASTContext &Ctx, QualType ElementType) {
     350               50:   const RecordType *RT = ElementType->getAs<RecordType>();
                       16: branch 0 taken
                       34: branch 1 taken
     351               50:   if (!RT)
     352               16:     return CharUnits::Zero();
     353                 :   
     354               34:   const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
                        0: branch 0 not taken
                       34: branch 1 taken
     355               34:   if (!RD)
     356                0:     return CharUnits::Zero();
     357                 :   
     358                 :   // Check if the class has a trivial destructor.
                        6: branch 1 taken
                       28: branch 2 taken
     359               34:   if (RD->hasTrivialDestructor()) {
     360                 :     // Check if the usual deallocation function takes two arguments.
     361                6:     const CXXMethodDecl *UsualDeallocationFunction = 0;
     362                 :     
     363                 :     DeclarationName OpName =
     364                6:       Ctx.DeclarationNames.getCXXOperatorName(OO_Array_Delete);
     365                 :     DeclContext::lookup_const_iterator Op, OpEnd;
                        0: branch 3 not taken
                        6: branch 4 taken
     366                6:     for (llvm::tie(Op, OpEnd) = RD->lookup(OpName);
     367                 :          Op != OpEnd; ++Op) {
     368                0:       const CXXMethodDecl *Delete = cast<CXXMethodDecl>(*Op);
     369                 : 
                        0: branch 1 not taken
                        0: branch 2 not taken
     370                0:       if (Delete->isUsualDeallocationFunction()) {
     371                0:         UsualDeallocationFunction = Delete;
     372                0:         break;
     373                 :       }
     374                 :     }
     375                 :     
     376                 :     // No usual deallocation function, we don't need a cookie.
                        6: branch 0 taken
                        0: branch 1 not taken
     377                6:     if (!UsualDeallocationFunction)
     378                6:       return CharUnits::Zero();
     379                 :     
     380                 :     // The usual deallocation function doesn't take a size_t argument, so we
     381                 :     // don't need a cookie.
                        0: branch 1 not taken
                        0: branch 2 not taken
     382                0:     if (UsualDeallocationFunction->getNumParams() == 1)
     383                0:       return CharUnits::Zero();
     384                 :         
     385                 :     assert(UsualDeallocationFunction->getNumParams() == 2 && 
                        0: branch 1 not taken
                        0: branch 2 not taken
     386                0:            "Unexpected deallocation function type!");
     387                 :   }  
     388                 :   
     389                 :   // Padding is the maximum of sizeof(size_t) and alignof(ElementType)
     390                 :   return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()),
     391               28:                   Ctx.getTypeAlignInChars(ElementType));
     392                 : }
     393                 : 
     394               77: static CharUnits CalculateCookiePadding(ASTContext &Ctx, const CXXNewExpr *E) {
                       39: branch 1 taken
                       38: branch 2 taken
     395               77:   if (!E->isArray())
     396               39:     return CharUnits::Zero();
     397                 : 
     398                 :   // No cookie is required if the new operator being used is 
     399                 :   // ::operator new[](size_t, void*).
     400               38:   const FunctionDecl *OperatorNew = E->getOperatorNew();
                       38: branch 3 taken
                        0: branch 4 not taken
     401               38:   if (OperatorNew->getDeclContext()->getLookupContext()->isFileContext()) {
                        0: branch 1 not taken
                       38: branch 2 taken
     402               38:     if (OperatorNew->getNumParams() == 2) {
     403                 :       CanQualType ParamType = 
     404                0:         Ctx.getCanonicalType(OperatorNew->getParamDecl(1)->getType());
     405                 :       
                        0: branch 1 not taken
                        0: branch 2 not taken
     406                0:       if (ParamType == Ctx.VoidPtrTy)
     407                0:         return CharUnits::Zero();
     408                 :     }
     409                 :   }
     410                 :       
     411               38:   return CalculateCookiePadding(Ctx, E->getAllocatedType());
     412                 : }
     413                 : 
     414                 : static llvm::Value *EmitCXXNewAllocSize(CodeGenFunction &CGF, 
     415                 :                                         const CXXNewExpr *E,
     416               58:                                         llvm::Value *& NumElements) {
     417               58:   QualType Type = E->getAllocatedType();
     418               58:   CharUnits TypeSize = CGF.getContext().getTypeSizeInChars(Type);
     419               58:   const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType());
     420                 :   
                       39: branch 1 taken
                       19: branch 2 taken
     421               58:   if (!E->isArray())
     422               39:     return llvm::ConstantInt::get(SizeTy, TypeSize.getQuantity());
     423                 : 
     424               19:   CharUnits CookiePadding = CalculateCookiePadding(CGF.getContext(), E);
     425                 :   
     426               19:   Expr::EvalResult Result;
                       16: branch 3 taken
                        3: branch 4 taken
                       16: branch 5 taken
                        0: branch 6 not taken
                       16: branch 8 taken
                        0: branch 9 not taken
                       16: branch 10 taken
                        3: branch 11 taken
     427               19:   if (E->getArraySize()->Evaluate(Result, CGF.getContext()) &&
     428                 :       !Result.HasSideEffects && Result.Val.isInt()) {
     429                 : 
     430                 :     CharUnits AllocSize = 
     431               16:       Result.Val.getInt().getZExtValue() * TypeSize + CookiePadding;
     432                 :     
     433                 :     NumElements = 
     434               16:       llvm::ConstantInt::get(SizeTy, Result.Val.getInt().getZExtValue());
     435                 :     
     436               16:     return llvm::ConstantInt::get(SizeTy, AllocSize.getQuantity());
     437                 :   }
     438                 :   
     439                 :   // Emit the array size expression.
     440                3:   NumElements = CGF.EmitScalarExpr(E->getArraySize());
     441                 :   
     442                 :   // Multiply with the type size.
     443                 :   llvm::Value *V = 
     444                 :     CGF.Builder.CreateMul(NumElements, 
     445                 :                           llvm::ConstantInt::get(SizeTy, 
     446                3:                                                  TypeSize.getQuantity()));
     447                 : 
     448                 :   // And add the cookie padding if necessary.
                        1: branch 1 taken
                        2: branch 2 taken
     449                3:   if (!CookiePadding.isZero())
     450                 :     V = CGF.Builder.CreateAdd(V, 
     451                1:         llvm::ConstantInt::get(SizeTy, CookiePadding.getQuantity()));
     452                 :   
     453                3:   return V;
     454                 : }
     455                 : 
     456                 : static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E,
     457                 :                                llvm::Value *NewPtr,
     458               58:                                llvm::Value *NumElements) {
                       19: branch 1 taken
                       39: branch 2 taken
     459               58:   if (E->isArray()) {
                       13: branch 1 taken
                        6: branch 2 taken
     460               19:     if (CXXConstructorDecl *Ctor = E->getConstructor())
     461                 :       CGF.EmitCXXAggrConstructorCall(Ctor, NumElements, NewPtr, 
     462                 :                                      E->constructor_arg_begin(), 
     463               13:                                      E->constructor_arg_end());
     464               19:     return;
     465                 :   }
     466                 :   
     467               39:   QualType AllocType = E->getAllocatedType();
     468                 : 
                       25: branch 1 taken
                       14: branch 2 taken
     469               39:   if (CXXConstructorDecl *Ctor = E->getConstructor()) {
     470                 :     CGF.EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr,
     471                 :                                E->constructor_arg_begin(),
     472               25:                                E->constructor_arg_end());
     473                 : 
     474               25:     return;
     475                 :   }
     476                 :     
     477                 :   // We have a POD type.
                        3: branch 1 taken
                       11: branch 2 taken
     478               14:   if (E->getNumConstructorArgs() == 0)
     479                3:     return;
     480                 : 
     481                 :   assert(E->getNumConstructorArgs() == 1 &&
                       11: branch 1 taken
                        0: branch 2 not taken
     482               11:          "Can only have one argument to initializer of POD type.");
     483                 :       
     484               11:   const Expr *Init = E->getConstructorArg(0);
     485                 :     
                        9: branch 1 taken
                        2: branch 2 taken
     486               11:   if (!CGF.hasAggregateLLVMType(AllocType)) 
     487                 :     CGF.EmitStoreOfScalar(CGF.EmitScalarExpr(Init), NewPtr,
     488                9:                           AllocType.isVolatileQualified(), AllocType);
                        1: branch 2 taken
                        1: branch 3 taken
     489                2:   else if (AllocType->isAnyComplexType())
     490                 :     CGF.EmitComplexExprIntoAddr(Init, NewPtr, 
     491                1:                                 AllocType.isVolatileQualified());
     492                 :   else
     493                1:     CGF.EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified());
     494                 : }
     495                 : 
     496               58: llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
     497               58:   QualType AllocType = E->getAllocatedType();
     498               58:   FunctionDecl *NewFD = E->getOperatorNew();
     499               58:   const FunctionProtoType *NewFTy = NewFD->getType()->getAs<FunctionProtoType>();
     500                 : 
     501               58:   CallArgList NewArgs;
     502                 : 
     503                 :   // The allocation size is the first argument.
     504               58:   QualType SizeTy = getContext().getSizeType();
     505                 : 
     506               58:   llvm::Value *NumElements = 0;
     507               58:   llvm::Value *AllocSize = EmitCXXNewAllocSize(*this, E, NumElements);
     508                 :   
     509               58:   NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy));
     510                 : 
     511                 :   // Emit the rest of the arguments.
     512                 :   // FIXME: Ideally, this should just use EmitCallArgs.
     513               58:   CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin();
     514                 : 
     515                 :   // First, use the types from the function type.
     516                 :   // We start at 1 here because the first argument (the allocation size)
     517                 :   // has already been emitted.
                       19: branch 2 taken
                       58: branch 3 taken
     518              154:   for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) {
     519               19:     QualType ArgType = NewFTy->getArgType(i);
     520                 : 
     521                 :     assert(getContext().getCanonicalType(ArgType.getNonReferenceType()).
     522                 :            getTypePtr() ==
     523                 :            getContext().getCanonicalType(NewArg->getType()).getTypePtr() &&
                       19: branch 9 taken
                        0: branch 10 not taken
     524               19:            "type mismatch in call argument!");
     525                 : 
     526                 :     NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
     527               19:                                      ArgType));
     528                 : 
     529                 :   }
     530                 : 
     531                 :   // Either we've emitted all the call args, or we have a call to a
     532                 :   // variadic function.
     533                 :   assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) &&
                        1: branch 2 taken
                       57: branch 3 taken
                        1: branch 5 taken
                        0: branch 6 not taken
     534               58:          "Extra arguments in non-variadic function!");
     535                 : 
     536                 :   // If we still have any arguments, emit them using the type of the argument.
                        2: branch 3 taken
                       58: branch 4 taken
     537               60:   for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end();
     538                 :        NewArg != NewArgEnd; ++NewArg) {
     539                2:     QualType ArgType = NewArg->getType();
     540                 :     NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
     541                2:                                      ArgType));
     542                 :   }
     543                 : 
     544                 :   // Emit the call to new.
     545                 :   RValue RV =
     546                 :     EmitCall(CGM.getTypes().getFunctionInfo(NewArgs, NewFTy),
     547               58:              CGM.GetAddrOfFunction(NewFD), ReturnValueSlot(), NewArgs, NewFD);
     548                 : 
     549                 :   // If an allocation function is declared with an empty exception specification
     550                 :   // it returns null to indicate failure to allocate storage. [expr.new]p13.
     551                 :   // (We don't need to check for null when there's no new initializer and
     552                 :   // we're allocating a POD type).
     553                 :   bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() &&
                       10: branch 1 taken
                       48: branch 2 taken
                        7: branch 5 taken
                        3: branch 6 taken
                        6: branch 8 taken
                        1: branch 9 taken
     554               58:     !(AllocType->isPODType() && !E->hasInitializer());
     555                 : 
     556               58:   llvm::BasicBlock *NewNull = 0;
     557               58:   llvm::BasicBlock *NewNotNull = 0;
     558               58:   llvm::BasicBlock *NewEnd = 0;
     559                 : 
     560               58:   llvm::Value *NewPtr = RV.getScalarVal();
     561                 : 
                        9: branch 0 taken
                       49: branch 1 taken
     562               58:   if (NullCheckResult) {
     563                9:     NewNull = createBasicBlock("new.null");
     564                9:     NewNotNull = createBasicBlock("new.notnull");
     565                9:     NewEnd = createBasicBlock("new.end");
     566                 : 
     567                 :     llvm::Value *IsNull =
     568                 :       Builder.CreateICmpEQ(NewPtr,
     569                 :                            llvm::Constant::getNullValue(NewPtr->getType()),
     570                9:                            "isnull");
     571                 : 
     572                9:     Builder.CreateCondBr(IsNull, NewNull, NewNotNull);
     573                9:     EmitBlock(NewNotNull);
     574                 :   }
     575                 :   
     576               58:   CharUnits CookiePadding = CalculateCookiePadding(getContext(), E);
                       10: branch 1 taken
                       48: branch 2 taken
     577               58:   if (!CookiePadding.isZero()) {
     578                 :     CharUnits CookieOffset = 
     579               10:       CookiePadding - getContext().getTypeSizeInChars(SizeTy);
     580                 :     
     581                 :     llvm::Value *NumElementsPtr = 
     582               10:       Builder.CreateConstInBoundsGEP1_64(NewPtr, CookieOffset.getQuantity());
     583                 :     
     584                 :     NumElementsPtr = Builder.CreateBitCast(NumElementsPtr, 
     585               10:                                            ConvertType(SizeTy)->getPointerTo());
     586               10:     Builder.CreateStore(NumElements, NumElementsPtr);
     587                 : 
     588                 :     // Now add the padding to the new ptr.
     589                 :     NewPtr = Builder.CreateConstInBoundsGEP1_64(NewPtr, 
     590               10:                                                 CookiePadding.getQuantity());
     591                 :   }
     592                 :   
     593               58:   NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
     594                 : 
     595               58:   EmitNewInitializer(*this, E, NewPtr, NumElements);
     596                 : 
                        9: branch 0 taken
                       49: branch 1 taken
     597               58:   if (NullCheckResult) {
     598                9:     Builder.CreateBr(NewEnd);
     599                9:     NewNotNull = Builder.GetInsertBlock();
     600                9:     EmitBlock(NewNull);
     601                9:     Builder.CreateBr(NewEnd);
     602                9:     EmitBlock(NewEnd);
     603                 : 
     604                9:     llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType());
     605                9:     PHI->reserveOperandSpace(2);
     606                9:     PHI->addIncoming(NewPtr, NewNotNull);
     607                9:     PHI->addIncoming(llvm::Constant::getNullValue(NewPtr->getType()), NewNull);
     608                 : 
     609                9:     NewPtr = PHI;
     610                 :   }
     611                 : 
     612               58:   return NewPtr;
     613                 : }
     614                 : 
     615                 : static std::pair<llvm::Value *, llvm::Value *>
     616                 : GetAllocatedObjectPtrAndNumElements(CodeGenFunction &CGF,
     617               16:                                     llvm::Value *Ptr, QualType DeleteTy) {
     618               16:   QualType SizeTy = CGF.getContext().getSizeType();
     619               16:   const llvm::Type *SizeLTy = CGF.ConvertType(SizeTy);
     620                 :   
     621               16:   CharUnits DeleteTypeAlign = CGF.getContext().getTypeAlignInChars(DeleteTy);
     622                 :   CharUnits CookiePadding = 
     623                 :     std::max(CGF.getContext().getTypeSizeInChars(SizeTy),
     624               16:              DeleteTypeAlign);
                       16: branch 1 taken
                        0: branch 2 not taken
     625               16:   assert(!CookiePadding.isZero() && "CookiePadding should not be 0.");
     626                 : 
     627               16:   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
     628                 :   CharUnits CookieOffset = 
     629               16:     CookiePadding - CGF.getContext().getTypeSizeInChars(SizeTy);
     630                 : 
     631               16:   llvm::Value *AllocatedObjectPtr = CGF.Builder.CreateBitCast(Ptr, Int8PtrTy);
     632                 :   AllocatedObjectPtr = 
     633                 :     CGF.Builder.CreateConstInBoundsGEP1_64(AllocatedObjectPtr,
     634               16:                                            -CookiePadding.getQuantity());
     635                 : 
     636                 :   llvm::Value *NumElementsPtr =
     637                 :     CGF.Builder.CreateConstInBoundsGEP1_64(AllocatedObjectPtr, 
     638               16:                                            CookieOffset.getQuantity());
     639                 :   NumElementsPtr = 
     640               16:     CGF.Builder.CreateBitCast(NumElementsPtr, SizeLTy->getPointerTo());
     641                 :   
     642               16:   llvm::Value *NumElements = CGF.Builder.CreateLoad(NumElementsPtr);
     643                 :   NumElements = 
     644               16:     CGF.Builder.CreateIntCast(NumElements, SizeLTy, /*isSigned=*/false);
     645                 :   
     646               16:   return std::make_pair(AllocatedObjectPtr, NumElements);
     647                 : }
     648                 : 
     649                 : void CodeGenFunction::EmitDeleteCall(const FunctionDecl *DeleteFD,
     650                 :                                      llvm::Value *Ptr,
     651               41:                                      QualType DeleteTy) {
     652                 :   const FunctionProtoType *DeleteFTy =
     653               41:     DeleteFD->getType()->getAs<FunctionProtoType>();
     654                 : 
     655               41:   CallArgList DeleteArgs;
     656                 : 
     657                 :   // Check if we need to pass the size to the delete operator.
     658               41:   llvm::Value *Size = 0;
     659               41:   QualType SizeTy;
                        1: branch 1 taken
                       40: branch 2 taken
     660               41:   if (DeleteFTy->getNumArgs() == 2) {
     661                1:     SizeTy = DeleteFTy->getArgType(1);
     662                1:     CharUnits DeleteTypeSize = getContext().getTypeSizeInChars(DeleteTy);
     663                 :     Size = llvm::ConstantInt::get(ConvertType(SizeTy), 
     664                1:                                   DeleteTypeSize.getQuantity());
     665                 :   }
     666                 :   
                       12: branch 1 taken
                       29: branch 2 taken
                        8: branch 6 taken
                        4: branch 7 taken
                        8: branch 8 taken
                       33: branch 9 taken
     667               41:   if (DeleteFD->getOverloadedOperator() == OO_Array_Delete &&
     668                 :       !CalculateCookiePadding(getContext(), DeleteTy).isZero()) {
     669                 :     // We need to get the number of elements in the array from the cookie.
     670                 :     llvm::Value *AllocatedObjectPtr;
     671                 :     llvm::Value *NumElements;
     672                 :     llvm::tie(AllocatedObjectPtr, NumElements) =
     673                8:       GetAllocatedObjectPtrAndNumElements(*this, Ptr, DeleteTy);
     674                 :     
     675                 :     // Multiply the size with the number of elements.
                        0: branch 0 not taken
                        8: branch 1 taken
     676                8:     if (Size)
     677                0:       Size = Builder.CreateMul(NumElements, Size);
     678                 :     
     679                8:     Ptr = AllocatedObjectPtr;
     680                 :   }
     681                 :   
     682               41:   QualType ArgTy = DeleteFTy->getArgType(0);
     683               41:   llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy));
     684               41:   DeleteArgs.push_back(std::make_pair(RValue::get(DeletePtr), ArgTy));
     685                 : 
                        1: branch 0 taken
                       40: branch 1 taken
     686               41:   if (Size)
     687                1:     DeleteArgs.push_back(std::make_pair(RValue::get(Size), SizeTy));
     688                 : 
     689                 :   // Emit the call to delete.
     690                 :   EmitCall(CGM.getTypes().getFunctionInfo(DeleteArgs, DeleteFTy),
     691                 :            CGM.GetAddrOfFunction(DeleteFD), ReturnValueSlot(), 
     692               41:            DeleteArgs, DeleteFD);
     693               41: }
     694                 : 
     695               20: void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
     696                 :   
     697                 :   // Get at the argument before we performed the implicit conversion
     698                 :   // to void*.
     699               20:   const Expr *Arg = E->getArgument();
                       20: branch 1 taken
                       20: branch 2 taken
     700               60:   while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) {
                       20: branch 1 taken
                        0: branch 2 not taken
                       20: branch 6 taken
                        0: branch 7 not taken
                       20: branch 8 taken
                        0: branch 9 not taken
     701               20:     if (ICE->getCastKind() != CastExpr::CK_UserDefinedConversion &&
     702                 :         ICE->getType()->isVoidPointerType())
     703               20:       Arg = ICE->getSubExpr();
     704                 :     else
     705                0:       break;
     706                 :   }
     707                 :   
     708               20:   QualType DeleteTy = Arg->getType()->getAs<PointerType>()->getPointeeType();
     709                 : 
     710               20:   llvm::Value *Ptr = EmitScalarExpr(Arg);
     711                 : 
     712                 :   // Null check the pointer.
     713               20:   llvm::BasicBlock *DeleteNotNull = createBasicBlock("delete.notnull");
     714               20:   llvm::BasicBlock *DeleteEnd = createBasicBlock("delete.end");
     715                 : 
     716                 :   llvm::Value *IsNull =
     717                 :     Builder.CreateICmpEQ(Ptr, llvm::Constant::getNullValue(Ptr->getType()),
     718               20:                          "isnull");
     719                 : 
     720               20:   Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull);
     721               20:   EmitBlock(DeleteNotNull);
     722                 :   
     723               20:   bool ShouldCallDelete = true;
     724                 :   
     725                 :   // Call the destructor if necessary.
                       14: branch 2 taken
                        6: branch 3 taken
     726               20:   if (const RecordType *RT = DeleteTy->getAs<RecordType>()) {
                       14: branch 2 taken
                        0: branch 3 not taken
     727               14:     if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
                       11: branch 1 taken
                        3: branch 2 taken
     728               14:       if (!RD->hasTrivialDestructor()) {
     729               11:         const CXXDestructorDecl *Dtor = RD->getDestructor(getContext());
                        8: branch 1 taken
                        3: branch 2 taken
     730               11:         if (E->isArrayForm()) {
     731                 :           llvm::Value *AllocatedObjectPtr;
     732                 :           llvm::Value *NumElements;
     733                 :           llvm::tie(AllocatedObjectPtr, NumElements) =
     734                8:             GetAllocatedObjectPtrAndNumElements(*this, Ptr, DeleteTy);
     735                 :           
     736                8:           EmitCXXAggrDestructorCall(Dtor, NumElements, Ptr);
                        0: branch 1 not taken
                        3: branch 2 taken
     737                3:         } else if (Dtor->isVirtual()) {
     738                 :           const llvm::Type *Ty =
     739                 :             CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(Dtor),
     740                0:                                            /*isVariadic=*/false);
     741                 :           
     742                0:           llvm::Value *Callee = BuildVirtualCall(Dtor, Dtor_Deleting, Ptr, Ty);
     743                 :           EmitCXXMemberCall(Dtor, Callee, ReturnValueSlot(), Ptr, /*VTT=*/0,
     744                0:                             0, 0);
     745                 : 
     746                 :           // The dtor took care of deleting the object.
     747                0:           ShouldCallDelete = false;
     748                 :         } else 
     749                3:           EmitCXXDestructorCall(Dtor, Dtor_Complete, Ptr);
     750                 :       }
     751                 :     }
     752                 :   }
     753                 : 
                       20: branch 0 taken
                        0: branch 1 not taken
     754               20:   if (ShouldCallDelete)
     755               20:     EmitDeleteCall(E->getOperatorDelete(), Ptr, DeleteTy);
     756                 : 
     757               20:   EmitBlock(DeleteEnd);
     758               20: }
     759                 : 
     760               68: llvm::Value * CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) {
     761               68:   QualType Ty = E->getType();
     762               68:   const llvm::Type *LTy = ConvertType(Ty)->getPointerTo();
     763                 :   
                       67: branch 1 taken
                        1: branch 2 taken
     764               68:   if (E->isTypeOperand()) {
     765                 :     llvm::Constant *TypeInfo = 
     766               67:       CGM.GetAddrOfRTTIDescriptor(E->getTypeOperand());
     767               67:     return Builder.CreateBitCast(TypeInfo, LTy);
     768                 :   }
     769                 :   
     770                1:   Expr *subE = E->getExprOperand();
     771                1:   Ty = subE->getType();
     772                1:   CanQualType CanTy = CGM.getContext().getCanonicalType(Ty);
     773                1:   Ty = CanTy.getUnqualifiedType().getNonReferenceType();
                        1: branch 2 taken
                        0: branch 3 not taken
     774                1:   if (const RecordType *RT = Ty->getAs<RecordType>()) {
     775                1:     const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
                        0: branch 1 not taken
                        1: branch 2 taken
     776                1:     if (RD->isPolymorphic()) {
     777                 :       // FIXME: if subE is an lvalue do
     778                0:       LValue Obj = EmitLValue(subE);
     779                0:       llvm::Value *This = Obj.getAddress();
     780                0:       LTy = LTy->getPointerTo()->getPointerTo();
     781                0:       llvm::Value *V = Builder.CreateBitCast(This, LTy);
     782                 :       // We need to do a zero check for *p, unless it has NonNullAttr.
     783                 :       // FIXME: PointerType->hasAttr<NonNullAttr>()
     784                0:       bool CanBeZero = false;
                        0: branch 2 not taken
                        0: branch 3 not taken
     785                0:       if (UnaryOperator *UO = dyn_cast<UnaryOperator>(subE->IgnoreParens()))
                        0: branch 1 not taken
                        0: branch 2 not taken
     786                0:         if (UO->getOpcode() == UnaryOperator::Deref)
     787                0:           CanBeZero = true;
                        0: branch 0 not taken
                        0: branch 1 not taken
     788                0:       if (CanBeZero) {
     789                0:         llvm::BasicBlock *NonZeroBlock = createBasicBlock();
     790                0:         llvm::BasicBlock *ZeroBlock = createBasicBlock();
     791                 :         
     792                0:         llvm::Value *Zero = llvm::Constant::getNullValue(LTy);
     793                 :         Builder.CreateCondBr(Builder.CreateICmpNE(V, Zero),
     794                0:                              NonZeroBlock, ZeroBlock);
     795                0:         EmitBlock(ZeroBlock);
     796                 :         /// Call __cxa_bad_typeid
     797                0:         const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext);
     798                 :         const llvm::FunctionType *FTy;
     799                0:         FTy = llvm::FunctionType::get(ResultType, false);
     800                0:         llvm::Value *F = CGM.CreateRuntimeFunction(FTy, "__cxa_bad_typeid");
     801                0:         Builder.CreateCall(F)->setDoesNotReturn();
     802                0:         Builder.CreateUnreachable();
     803                0:         EmitBlock(NonZeroBlock);
     804                 :       }
     805                0:       V = Builder.CreateLoad(V, "vtable");
     806                0:       V = Builder.CreateConstInBoundsGEP1_64(V, -1ULL);
     807                0:       V = Builder.CreateLoad(V);
     808                0:       return V;
     809                 :     }
     810                 :   }
     811                1:   return Builder.CreateBitCast(CGM.GetAddrOfRTTIDescriptor(Ty), LTy);
     812                 : }
     813                 : 
     814                 : llvm::Value *CodeGenFunction::EmitDynamicCast(llvm::Value *V,
     815                9:                                               const CXXDynamicCastExpr *DCE) {
     816                9:   QualType SrcTy = DCE->getSubExpr()->getType();
     817                9:   QualType DestTy = DCE->getTypeAsWritten();
     818                9:   QualType InnerType = DestTy->getPointeeType();
     819                 :   
     820                9:   const llvm::Type *LTy = ConvertType(DCE->getType());
     821                 : 
     822                9:   bool CanBeZero = false;
     823                9:   bool ToVoid = false;
     824                9:   bool ThrowOnBad = false;
                        8: branch 2 taken
                        1: branch 3 taken
     825                9:   if (DestTy->isPointerType()) {
     826                 :     // FIXME: if PointerType->hasAttr<NonNullAttr>(), we don't set this
     827                8:     CanBeZero = true;
                        2: branch 2 taken
                        6: branch 3 taken
     828                8:     if (InnerType->isVoidType())
     829                2:       ToVoid = true;
     830                 :   } else {
     831                1:     LTy = LTy->getPointerTo();
     832                1:     ThrowOnBad = true;
     833                 :   }
     834                 : 
                        1: branch 2 taken
                        8: branch 3 taken
                        0: branch 6 not taken
                        1: branch 7 taken
                        8: branch 8 taken
                        1: branch 9 taken
     835                9:   if (SrcTy->isPointerType() || SrcTy->isReferenceType())
     836                8:     SrcTy = SrcTy->getPointeeType();
     837                9:   SrcTy = SrcTy.getUnqualifiedType();
     838                 : 
                        1: branch 2 taken
                        8: branch 3 taken
                        1: branch 6 taken
                        0: branch 7 not taken
                        9: branch 8 taken
                        0: branch 9 not taken
     839                9:   if (DestTy->isPointerType() || DestTy->isReferenceType())
     840                9:     DestTy = DestTy->getPointeeType();
     841                9:   DestTy = DestTy.getUnqualifiedType();
     842                 : 
     843                9:   llvm::BasicBlock *ContBlock = createBasicBlock();
     844                9:   llvm::BasicBlock *NullBlock = 0;
     845                9:   llvm::BasicBlock *NonZeroBlock = 0;
                        8: branch 0 taken
                        1: branch 1 taken
     846                9:   if (CanBeZero) {
     847                8:     NonZeroBlock = createBasicBlock();
     848                8:     NullBlock = createBasicBlock();
     849                8:     Builder.CreateCondBr(Builder.CreateIsNotNull(V), NonZeroBlock, NullBlock);
     850                8:     EmitBlock(NonZeroBlock);
     851                 :   }
     852                 : 
     853                9:   llvm::BasicBlock *BadCastBlock = 0;
     854                 : 
     855                9:   const llvm::Type *PtrDiffTy = ConvertType(getContext().getPointerDiffType());
     856                 : 
     857                 :   // See if this is a dynamic_cast(void*)
                        2: branch 0 taken
                        7: branch 1 taken
     858                9:   if (ToVoid) {
     859                2:     llvm::Value *This = V;
     860                2:     V = Builder.CreateBitCast(This, PtrDiffTy->getPointerTo()->getPointerTo());
     861                2:     V = Builder.CreateLoad(V, "vtable");
     862                2:     V = Builder.CreateConstInBoundsGEP1_64(V, -2ULL);
     863                2:     V = Builder.CreateLoad(V, "offset to top");
     864                2:     This = Builder.CreateBitCast(This, llvm::Type::getInt8PtrTy(VMContext));
     865                2:     V = Builder.CreateInBoundsGEP(This, V);
     866                2:     V = Builder.CreateBitCast(V, LTy);
     867                 :   } else {
     868                 :     /// Call __dynamic_cast
     869                7:     const llvm::Type *ResultType = llvm::Type::getInt8PtrTy(VMContext);
     870                 :     const llvm::FunctionType *FTy;
     871                7:     std::vector<const llvm::Type*> ArgTys;
     872                 :     const llvm::Type *PtrToInt8Ty
     873                7:       = llvm::Type::getInt8Ty(VMContext)->getPointerTo();
     874                7:     ArgTys.push_back(PtrToInt8Ty);
     875                7:     ArgTys.push_back(PtrToInt8Ty);
     876                7:     ArgTys.push_back(PtrToInt8Ty);
     877                7:     ArgTys.push_back(PtrDiffTy);
     878                7:     FTy = llvm::FunctionType::get(ResultType, ArgTys, false);
     879                 : 
     880                 :     // FIXME: Calculate better hint.
     881                7:     llvm::Value *hint = llvm::ConstantInt::get(PtrDiffTy, -1ULL);
     882                 :     
                        7: branch 2 taken
                        0: branch 3 not taken
     883                7:     assert(SrcTy->isRecordType() && "Src type must be record type!");
                        7: branch 2 taken
                        0: branch 3 not taken
     884                7:     assert(DestTy->isRecordType() && "Dest type must be record type!");
     885                 :     
     886                 :     llvm::Value *SrcArg
     887                7:       = CGM.GetAddrOfRTTIDescriptor(SrcTy.getUnqualifiedType());
     888                 :     llvm::Value *DestArg
     889                7:       = CGM.GetAddrOfRTTIDescriptor(DestTy.getUnqualifiedType());
     890                 :     
     891                7:     V = Builder.CreateBitCast(V, PtrToInt8Ty);
     892                 :     V = Builder.CreateCall4(CGM.CreateRuntimeFunction(FTy, "__dynamic_cast"),
     893                7:                             V, SrcArg, DestArg, hint);
     894                7:     V = Builder.CreateBitCast(V, LTy);
     895                 : 
                        1: branch 0 taken
                        6: branch 1 taken
     896                7:     if (ThrowOnBad) {
     897                1:       BadCastBlock = createBasicBlock();
     898                 : 
     899                1:       Builder.CreateCondBr(Builder.CreateIsNotNull(V), ContBlock, BadCastBlock);
     900                1:       EmitBlock(BadCastBlock);
     901                 :       /// Call __cxa_bad_cast
     902                1:       ResultType = llvm::Type::getVoidTy(VMContext);
     903                 :       const llvm::FunctionType *FBadTy;
     904                1:       FBadTy = llvm::FunctionType::get(ResultType, false);
     905                1:       llvm::Value *F = CGM.CreateRuntimeFunction(FBadTy, "__cxa_bad_cast");
     906                1:       Builder.CreateCall(F)->setDoesNotReturn();
     907                1:       Builder.CreateUnreachable();
     908                7:     }
     909                 :   }
     910                 :   
                        8: branch 0 taken
                        1: branch 1 taken
     911                9:   if (CanBeZero) {
     912                8:     Builder.CreateBr(ContBlock);
     913                8:     EmitBlock(NullBlock);
     914                8:     Builder.CreateBr(ContBlock);
     915                 :   }
     916                9:   EmitBlock(ContBlock);
                        8: branch 0 taken
                        1: branch 1 taken
     917                9:   if (CanBeZero) {
     918                8:     llvm::PHINode *PHI = Builder.CreatePHI(LTy);
     919                8:     PHI->reserveOperandSpace(2);
     920                8:     PHI->addIncoming(V, NonZeroBlock);
     921                8:     PHI->addIncoming(llvm::Constant::getNullValue(LTy), NullBlock);
     922                8:     V = PHI;
     923                 :   }
     924                 : 
     925                9:   return V;
     926                 : }

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