zcov: / lib/CodeGen/CGCXX.cpp


Files: 1 Branches Taken: 71.4% 50 / 70
Generated: 2010-02-10 01:31 Branches Executed: 91.4% 64 / 70
Line Coverage: 86.0% 208 / 242


Programs: 1 Runs 2897


       1                 : //===--- CGDecl.cpp - Emit LLVM Code for declarations ---------------------===//
       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.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : // We might split this into multiple files if it gets too unwieldy
      15                 : 
      16                 : #include "CodeGenFunction.h"
      17                 : #include "CodeGenModule.h"
      18                 : #include "Mangle.h"
      19                 : #include "clang/AST/ASTContext.h"
      20                 : #include "clang/AST/RecordLayout.h"
      21                 : #include "clang/AST/Decl.h"
      22                 : #include "clang/AST/DeclCXX.h"
      23                 : #include "clang/AST/DeclObjC.h"
      24                 : #include "clang/AST/StmtCXX.h"
      25                 : #include "llvm/ADT/StringExtras.h"
      26                 : using namespace clang;
      27                 : using namespace CodeGen;
      28                 : 
      29                 : 
      30                 : 
      31             1444: llvm::Value *CodeGenFunction::LoadCXXThis() {
      32                 :   assert(isa<CXXMethodDecl>(CurFuncDecl) &&
                     1444: branch 1 taken
                        0: branch 2 not taken
      33             1444:          "Must be in a C++ member function decl to load 'this'");
      34                 :   assert(cast<CXXMethodDecl>(CurFuncDecl)->isInstance() &&
                     1444: branch 2 taken
                        0: branch 3 not taken
      35             1444:          "Must be in a C++ member function decl to load 'this'");
      36                 : 
      37                 :   // FIXME: What if we're inside a block?
      38                 :   // ans: See how CodeGenFunction::LoadObjCSelf() uses
      39                 :   // CodeGenFunction::BlockForwardSelf() for how to do this.
      40             1444:   return Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this");
      41                 : }
      42                 : 
      43               38: void CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) {
      44               38:   EmitGlobal(GlobalDecl(D, Ctor_Complete));
      45               38:   EmitGlobal(GlobalDecl(D, Ctor_Base));
      46               38: }
      47                 : 
      48                 : void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D,
      49              476:                                        CXXCtorType Type) {
      50                 : 
      51              476:   llvm::Function *Fn = GetAddrOfCXXConstructor(D, Type);
      52                 : 
      53              476:   CodeGenFunction(*this).GenerateCode(GlobalDecl(D, Type), Fn);
      54                 : 
      55              476:   SetFunctionDefinitionAttributes(D, Fn);
      56              476:   SetLLVMFunctionAttributesForDefinition(D, Fn);
      57              476: }
      58                 : 
      59                 : llvm::Function *
      60                 : CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D,
      61             1164:                                        CXXCtorType Type) {
      62             1164:   const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>();
      63                 :   const llvm::FunctionType *FTy =
      64                 :     getTypes().GetFunctionType(getTypes().getFunctionInfo(D, Type), 
      65             1164:                                FPT->isVariadic());
      66                 : 
      67             1164:   const char *Name = getMangledCXXCtorName(D, Type);
      68                 :   return cast<llvm::Function>(
      69             1164:                       GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
      70                 : }
      71                 : 
      72                 : const char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D,
      73             1638:                                                  CXXCtorType Type) {
      74             1638:   llvm::SmallString<256> Name;
      75             1638:   getMangleContext().mangleCXXCtor(D, Type, Name);
      76                 : 
      77             1638:   Name += '\0';
      78             1638:   return UniqueMangledName(Name.begin(), Name.end());
      79                 : }
      80                 : 
      81               27: void CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) {
                       12: branch 1 taken
                       15: branch 2 taken
      82               27:   if (D->isVirtual())
      83               12:     EmitGlobal(GlobalDecl(D, Dtor_Deleting));
      84               27:   EmitGlobal(GlobalDecl(D, Dtor_Complete));
      85               27:   EmitGlobal(GlobalDecl(D, Dtor_Base));
      86               27: }
      87                 : 
      88                 : void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D,
      89              105:                                       CXXDtorType Type) {
      90              105:   llvm::Function *Fn = GetAddrOfCXXDestructor(D, Type);
      91                 : 
      92              105:   CodeGenFunction(*this).GenerateCode(GlobalDecl(D, Type), Fn);
      93                 : 
      94              105:   SetFunctionDefinitionAttributes(D, Fn);
      95              105:   SetLLVMFunctionAttributesForDefinition(D, Fn);
      96              105: }
      97                 : 
      98                 : llvm::Function *
      99                 : CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D,
     100              328:                                       CXXDtorType Type) {
     101                 :   const llvm::FunctionType *FTy =
     102              328:     getTypes().GetFunctionType(getTypes().getFunctionInfo(D, Type), false);
     103                 : 
     104              328:   const char *Name = getMangledCXXDtorName(D, Type);
     105                 :   return cast<llvm::Function>(
     106              328:                       GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
     107                 : }
     108                 : 
     109                 : const char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D,
     110              458:                                                  CXXDtorType Type) {
     111              458:   llvm::SmallString<256> Name;
     112              458:   getMangleContext().mangleCXXDtor(D, Type, Name);
     113                 : 
     114              458:   Name += '\0';
     115              458:   return UniqueMangledName(Name.begin(), Name.end());
     116                 : }
     117                 : 
     118                 : llvm::Constant *
     119                 : CodeGenFunction::GenerateThunk(llvm::Function *Fn, GlobalDecl GD,
     120                 :                                bool Extern, 
     121                0:                                const ThunkAdjustment &ThisAdjustment) {
     122                 :   return GenerateCovariantThunk(Fn, GD, Extern,
     123                 :                                 CovariantThunkAdjustment(ThisAdjustment,
     124                0:                                                          ThunkAdjustment()));
     125                 : }
     126                 : 
     127                 : llvm::Value *
     128                 : CodeGenFunction::DynamicTypeAdjust(llvm::Value *V, 
     129               87:                                    const ThunkAdjustment &Adjustment) {
     130               87:   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
     131                 : 
     132               87:   const llvm::Type *OrigTy = V->getType();
                       29: branch 0 taken
                       58: branch 1 taken
     133               87:   if (Adjustment.NonVirtual) {
     134                 :     // Do the non-virtual adjustment
     135               29:     V = Builder.CreateBitCast(V, Int8PtrTy);
     136               29:     V = Builder.CreateConstInBoundsGEP1_64(V, Adjustment.NonVirtual);
     137               29:     V = Builder.CreateBitCast(V, OrigTy);
     138                 :   }
     139                 :   
                       13: branch 0 taken
                       74: branch 1 taken
     140               87:   if (!Adjustment.Virtual)
     141               13:     return V;
     142                 : 
     143                 :   assert(Adjustment.Virtual % (LLVMPointerWidth / 8) == 0 && 
                        0: branch 0 not taken
                       74: branch 1 taken
     144               74:          "vtable entry unaligned");
     145                 : 
     146                 :   // Do the virtual this adjustment
     147               74:   const llvm::Type *PtrDiffTy = ConvertType(getContext().getPointerDiffType());
     148               74:   const llvm::Type *PtrDiffPtrTy = PtrDiffTy->getPointerTo();
     149                 :   
     150               74:   llvm::Value *ThisVal = Builder.CreateBitCast(V, Int8PtrTy);
     151               74:   V = Builder.CreateBitCast(V, PtrDiffPtrTy->getPointerTo());
     152               74:   V = Builder.CreateLoad(V, "vtable");
     153                 :   
     154               74:   llvm::Value *VTablePtr = V;
     155               74:   uint64_t VirtualAdjustment = Adjustment.Virtual / (LLVMPointerWidth / 8);
     156               74:   V = Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment);
     157               74:   V = Builder.CreateLoad(V);
     158               74:   V = Builder.CreateGEP(ThisVal, V);
     159                 :   
     160               74:   return Builder.CreateBitCast(V, OrigTy);
     161                 : }
     162                 : 
     163                 : llvm::Constant *
     164                 : CodeGenFunction::GenerateCovariantThunk(llvm::Function *Fn,
     165                 :                                    GlobalDecl GD, bool Extern,
     166               87:                                    const CovariantThunkAdjustment &Adjustment) {
     167               87:   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
     168               87:   const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
     169               87:   QualType ResultType = FPT->getResultType();
     170                 : 
     171               87:   FunctionArgList Args;
     172                 :   ImplicitParamDecl *ThisDecl =
     173                 :     ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
     174               87:                               MD->getThisType(getContext()));
     175               87:   Args.push_back(std::make_pair(ThisDecl, ThisDecl->getType()));
                        1: branch 1 taken
                       87: branch 2 taken
     176              175:   for (FunctionDecl::param_const_iterator i = MD->param_begin(),
     177               87:          e = MD->param_end();
     178                 :        i != e; ++i) {
     179                1:     ParmVarDecl *D = *i;
     180                1:     Args.push_back(std::make_pair(D, D->getType()));
     181                 :   }
     182                 :   IdentifierInfo *II
     183               87:     = &CGM.getContext().Idents.get("__thunk_named_foo_");
     184                 :   FunctionDecl *FD = FunctionDecl::Create(getContext(),
     185                 :                                           getContext().getTranslationUnitDecl(),
     186                 :                                           SourceLocation(), II, ResultType, 0,
     187                 :                                           Extern
     188                 :                                             ? FunctionDecl::Extern
     189                 :                                             : FunctionDecl::Static,
                       87: branch 0 taken
                        0: branch 1 not taken
                       87: branch 6 taken
                        0: branch 7 not taken
     190               87:                                           false, true);
     191               87:   StartFunction(FD, ResultType, Fn, Args, SourceLocation());
     192                 : 
     193                 :   // generate body
     194                 :   const llvm::Type *Ty =
     195                 :     CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
     196               87:                                    FPT->isVariadic());
     197               87:   llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty);
     198                 : 
     199               87:   CallArgList CallArgs;
     200                 : 
     201               87:   bool ShouldAdjustReturnPointer = true;
     202               87:   QualType ArgType = MD->getThisType(getContext());
     203               87:   llvm::Value *Arg = Builder.CreateLoad(LocalDeclMap[ThisDecl], "this");
                       51: branch 1 taken
                       36: branch 2 taken
     204               87:   if (!Adjustment.ThisAdjustment.isEmpty()) {
     205                 :     // Do the this adjustment.
     206               51:     const llvm::Type *OrigTy = Callee->getType();
     207               51:     Arg = DynamicTypeAdjust(Arg, Adjustment.ThisAdjustment);
     208                 :     
                       36: branch 1 taken
                       15: branch 2 taken
     209               51:     if (!Adjustment.ReturnAdjustment.isEmpty()) {
     210                 :       const CovariantThunkAdjustment &ReturnAdjustment = 
     211                 :         CovariantThunkAdjustment(ThunkAdjustment(),
     212               36:                                  Adjustment.ReturnAdjustment);
     213                 :       
     214               36:       Callee = CGM.BuildCovariantThunk(GD, Extern, ReturnAdjustment);
     215                 :       
     216               36:       Callee = Builder.CreateBitCast(Callee, OrigTy);
     217               36:       ShouldAdjustReturnPointer = false;
     218                 :     }
     219                 :   }    
     220                 : 
     221               87:   CallArgs.push_back(std::make_pair(RValue::get(Arg), ArgType));
     222                 : 
                        1: branch 1 taken
                       87: branch 2 taken
     223              175:   for (FunctionDecl::param_const_iterator i = MD->param_begin(),
     224               87:          e = MD->param_end();
     225                 :        i != e; ++i) {
     226                1:     ParmVarDecl *D = *i;
     227                1:     QualType ArgType = D->getType();
     228                 : 
     229                 :     // llvm::Value *Arg = CGF.GetAddrOfLocalVar(Dst);
     230                 :     Expr *Arg = new (getContext()) DeclRefExpr(D, ArgType.getNonReferenceType(),
                        1: branch 4 taken
                        0: branch 5 not taken
     231                1:                                                SourceLocation());
     232                1:     CallArgs.push_back(std::make_pair(EmitCallArg(Arg, ArgType), ArgType));
     233                 :   }
     234                 : 
     235                 :   RValue RV = EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs,
     236                 :                                                       FPT->getCallConv(),
     237                 :                                                       FPT->getNoReturnAttr()),
     238               87:                        Callee, ReturnValueSlot(), CallArgs, MD);
                       51: branch 0 taken
                       36: branch 1 taken
                       36: branch 3 taken
                       15: branch 4 taken
                       36: branch 5 taken
                       51: branch 6 taken
     239               87:   if (ShouldAdjustReturnPointer && !Adjustment.ReturnAdjustment.isEmpty()) {
     240                 :     bool CanBeZero = !(ResultType->isReferenceType()
     241                 :     // FIXME: attr nonnull can't be zero either
     242               36:                        /* || ResultType->hasAttr<NonNullAttr>() */ );
     243                 :     // Do the return result adjustment.
                       24: branch 0 taken
                       12: branch 1 taken
     244               36:     if (CanBeZero) {
     245               24:       llvm::BasicBlock *NonZeroBlock = createBasicBlock();
     246               24:       llvm::BasicBlock *ZeroBlock = createBasicBlock();
     247               24:       llvm::BasicBlock *ContBlock = createBasicBlock();
     248                 : 
     249               24:       const llvm::Type *Ty = RV.getScalarVal()->getType();
     250               24:       llvm::Value *Zero = llvm::Constant::getNullValue(Ty);
     251                 :       Builder.CreateCondBr(Builder.CreateICmpNE(RV.getScalarVal(), Zero),
     252               24:                            NonZeroBlock, ZeroBlock);
     253               24:       EmitBlock(NonZeroBlock);
     254                 :       llvm::Value *NZ = 
     255               24:         DynamicTypeAdjust(RV.getScalarVal(), Adjustment.ReturnAdjustment);
     256               24:       EmitBranch(ContBlock);
     257               24:       EmitBlock(ZeroBlock);
     258               24:       llvm::Value *Z = RV.getScalarVal();
     259               24:       EmitBlock(ContBlock);
     260               24:       llvm::PHINode *RVOrZero = Builder.CreatePHI(Ty);
     261               24:       RVOrZero->reserveOperandSpace(2);
     262               24:       RVOrZero->addIncoming(NZ, NonZeroBlock);
     263               24:       RVOrZero->addIncoming(Z, ZeroBlock);
     264               24:       RV = RValue::get(RVOrZero);
     265                 :     } else
     266                 :       RV = RValue::get(DynamicTypeAdjust(RV.getScalarVal(), 
     267               12:                                          Adjustment.ReturnAdjustment));
     268                 :   }
     269                 : 
                       72: branch 2 taken
                       15: branch 3 taken
     270               87:   if (!ResultType->isVoidType())
     271               72:     EmitReturnOfRValue(RV, ResultType);
     272                 : 
     273               87:   FinishFunction();
     274               87:   return Fn;
     275                 : }
     276                 : 
     277                 : llvm::Constant *
     278                 : CodeGenModule::GetAddrOfThunk(GlobalDecl GD,
     279               94:                               const ThunkAdjustment &ThisAdjustment) {
     280               94:   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
     281                 : 
     282                 :   // Compute mangled name
     283               94:   llvm::SmallString<256> OutName;
                        0: branch 1 not taken
                       94: branch 2 taken
     284               94:   if (const CXXDestructorDecl* DD = dyn_cast<CXXDestructorDecl>(MD))
     285                 :     getMangleContext().mangleCXXDtorThunk(DD, GD.getDtorType(), ThisAdjustment,
     286                0:                                           OutName);
     287                 :   else
     288               94:     getMangleContext().mangleThunk(MD, ThisAdjustment, OutName);
     289               94:   OutName += '\0';
     290               94:   const char* Name = UniqueMangledName(OutName.begin(), OutName.end());
     291                 : 
     292                 :   // Get function for mangled name
     293               94:   const llvm::Type *Ty = getTypes().GetFunctionTypeForVtable(MD);
     294               94:   return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl());
     295                 : }
     296                 : 
     297                 : llvm::Constant *
     298                 : CodeGenModule::GetAddrOfCovariantThunk(GlobalDecl GD,
     299              248:                                    const CovariantThunkAdjustment &Adjustment) {
     300              248:   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
     301                 : 
     302                 :   // Compute mangled name
     303              248:   llvm::SmallString<256> OutName;
     304              248:   getMangleContext().mangleCovariantThunk(MD, Adjustment, OutName);
     305              248:   OutName += '\0';
     306              248:   const char* Name = UniqueMangledName(OutName.begin(), OutName.end());
     307                 : 
     308                 :   // Get function for mangled name
     309              248:   const llvm::Type *Ty = getTypes().GetFunctionTypeForVtable(MD);
     310              248:   return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl());
     311                 : }
     312                 : 
     313              943: void CodeGenModule::BuildThunksForVirtual(GlobalDecl GD) {
     314              943:   CGVtableInfo::AdjustmentVectorTy *AdjPtr = getVtableInfo().getAdjustments(GD);
                      810: branch 0 taken
                      133: branch 1 taken
     315              943:   if (!AdjPtr)
     316              810:     return;
     317              133:   CGVtableInfo::AdjustmentVectorTy &Adj = *AdjPtr;
     318              133:   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
                      259: branch 1 taken
                      133: branch 2 taken
     319              392:   for (unsigned i = 0; i < Adj.size(); i++) {
     320              259:     GlobalDecl OGD = Adj[i].first;
     321              259:     const CXXMethodDecl *OMD = cast<CXXMethodDecl>(OGD.getDecl());
     322              259:     QualType nc_oret = OMD->getType()->getAs<FunctionType>()->getResultType();
     323              259:     CanQualType oret = getContext().getCanonicalType(nc_oret);
     324              259:     QualType nc_ret = MD->getType()->getAs<FunctionType>()->getResultType();
     325              259:     CanQualType ret = getContext().getCanonicalType(nc_ret);
     326              259:     ThunkAdjustment ReturnAdjustment;
                      190: branch 1 taken
                       69: branch 2 taken
     327              259:     if (oret != ret) {
     328              190:       QualType qD = nc_ret->getPointeeType();
     329              190:       QualType qB = nc_oret->getPointeeType();
     330              190:       CXXRecordDecl *D = cast<CXXRecordDecl>(qD->getAs<RecordType>()->getDecl());
     331              190:       CXXRecordDecl *B = cast<CXXRecordDecl>(qB->getAs<RecordType>()->getDecl());
     332              190:       ReturnAdjustment = ComputeThunkAdjustment(D, B);
     333                 :     }
     334              259:     ThunkAdjustment ThisAdjustment = Adj[i].second;
     335              259:     bool Extern = !cast<CXXRecordDecl>(OMD->getDeclContext())->isInAnonymousNamespace();
                       69: branch 1 taken
                      190: branch 2 taken
                       69: branch 4 taken
                        0: branch 5 not taken
                      259: branch 6 taken
                        0: branch 7 not taken
     336              259:     if (!ReturnAdjustment.isEmpty() || !ThisAdjustment.isEmpty()) {
     337              259:       CovariantThunkAdjustment CoAdj(ThisAdjustment, ReturnAdjustment);
     338                 :       llvm::Constant *FnConst;
                      190: branch 1 taken
                       69: branch 2 taken
     339              259:       if (!ReturnAdjustment.isEmpty())
     340              190:         FnConst = GetAddrOfCovariantThunk(GD, CoAdj);
     341                 :       else
     342               69:         FnConst = GetAddrOfThunk(GD, ThisAdjustment);
                        0: branch 1 not taken
                      259: branch 2 taken
     343              259:       if (!isa<llvm::Function>(FnConst)) {
     344                 :         llvm::Constant *SubExpr =
     345                0:             cast<llvm::ConstantExpr>(FnConst)->getOperand(0);
     346                0:         llvm::Function *OldFn = cast<llvm::Function>(SubExpr);
     347                0:         std::string Name = OldFn->getNameStr();
     348                 :         GlobalDeclMap.erase(UniqueMangledName(Name.data(),
     349                0:                                               Name.data() + Name.size() + 1));
     350                 :         llvm::Constant *NewFnConst;
                        0: branch 1 not taken
                        0: branch 2 not taken
     351                0:         if (!ReturnAdjustment.isEmpty())
     352                0:           NewFnConst = GetAddrOfCovariantThunk(GD, CoAdj);
     353                 :         else
     354                0:           NewFnConst = GetAddrOfThunk(GD, ThisAdjustment);
     355                0:         llvm::Function *NewFn = cast<llvm::Function>(NewFnConst);
     356                0:         NewFn->takeName(OldFn);
     357                 :         llvm::Constant *NewPtrForOldDecl =
     358                0:             llvm::ConstantExpr::getBitCast(NewFn, OldFn->getType());
     359                0:         OldFn->replaceAllUsesWith(NewPtrForOldDecl);
     360                0:         OldFn->eraseFromParent();
     361                0:         FnConst = NewFn;
     362                 :       }
     363              259:       llvm::Function *Fn = cast<llvm::Function>(FnConst);
                       51: branch 1 taken
                      208: branch 2 taken
     364              259:       if (Fn->isDeclaration()) {
     365                 :         llvm::GlobalVariable::LinkageTypes linktype;
     366               51:         linktype = llvm::GlobalValue::WeakAnyLinkage;
                        0: branch 0 not taken
                       51: branch 1 taken
     367               51:         if (!Extern)
     368                0:           linktype = llvm::GlobalValue::InternalLinkage;
     369               51:         Fn->setLinkage(linktype);
                       51: branch 0 taken
                        0: branch 1 not taken
                       51: branch 2 taken
                        0: branch 3 not taken
     370               51:         if (!Features.Exceptions && !Features.ObjCNonFragileABI)
     371               51:           Fn->addFnAttr(llvm::Attribute::NoUnwind);
     372               51:         Fn->setAlignment(2);
     373               51:         CodeGenFunction(*this).GenerateCovariantThunk(Fn, GD, Extern, CoAdj);
     374                 :       }
     375                 :     }
     376                 :   }
     377                 : }
     378                 : 
     379                 : llvm::Constant *
     380                 : CodeGenModule::BuildThunk(GlobalDecl GD, bool Extern,
     381                0:                           const ThunkAdjustment &ThisAdjustment) {
     382                0:   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
     383                0:   llvm::SmallString<256> OutName;
                        0: branch 1 not taken
                        0: branch 2 not taken
     384                0:   if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(MD)) {
     385                 :     getMangleContext().mangleCXXDtorThunk(D, GD.getDtorType(), ThisAdjustment,
     386                0:                                           OutName);
     387                 :   } else 
     388                0:     getMangleContext().mangleThunk(MD, ThisAdjustment, OutName);
     389                 :   
     390                 :   llvm::GlobalVariable::LinkageTypes linktype;
     391                0:   linktype = llvm::GlobalValue::WeakAnyLinkage;
                        0: branch 0 not taken
                        0: branch 1 not taken
     392                0:   if (!Extern)
     393                0:     linktype = llvm::GlobalValue::InternalLinkage;
     394                0:   llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0);
     395                0:   const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
     396                 :   const llvm::FunctionType *FTy =
     397                 :     getTypes().GetFunctionType(getTypes().getFunctionInfo(MD),
     398                0:                                FPT->isVariadic());
     399                 : 
     400                 :   llvm::Function *Fn = llvm::Function::Create(FTy, linktype, OutName.str(),
     401                0:                                               &getModule());
     402                0:   CodeGenFunction(*this).GenerateThunk(Fn, GD, Extern, ThisAdjustment);
     403                0:   llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty);
     404                0:   return m;
     405                 : }
     406                 : 
     407                 : llvm::Constant *
     408                 : CodeGenModule::BuildCovariantThunk(const GlobalDecl &GD, bool Extern,
     409               36:                                    const CovariantThunkAdjustment &Adjustment) {
     410               36:   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
     411               36:   llvm::SmallString<256> OutName;
     412               36:   getMangleContext().mangleCovariantThunk(MD, Adjustment, OutName);
     413                 :   llvm::GlobalVariable::LinkageTypes linktype;
     414               36:   linktype = llvm::GlobalValue::WeakAnyLinkage;
                        0: branch 0 not taken
                       36: branch 1 taken
     415               36:   if (!Extern)
     416                0:     linktype = llvm::GlobalValue::InternalLinkage;
     417               36:   llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0);
     418               36:   const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
     419                 :   const llvm::FunctionType *FTy =
     420                 :     getTypes().GetFunctionType(getTypes().getFunctionInfo(MD),
     421               36:                                FPT->isVariadic());
     422                 : 
     423                 :   llvm::Function *Fn = llvm::Function::Create(FTy, linktype, OutName.str(),
     424               36:                                               &getModule());
     425               36:   CodeGenFunction(*this).GenerateCovariantThunk(Fn, MD, Extern, Adjustment);
     426               36:   llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty);
     427               36:   return m;
     428                 : }
     429                 : 
     430                 : static llvm::Value *BuildVirtualCall(CodeGenFunction &CGF, uint64_t VtableIndex, 
     431               22:                                      llvm::Value *This, const llvm::Type *Ty) {
     432               22:   Ty = Ty->getPointerTo()->getPointerTo()->getPointerTo();
     433                 :   
     434               22:   llvm::Value *Vtable = CGF.Builder.CreateBitCast(This, Ty);
     435               22:   Vtable = CGF.Builder.CreateLoad(Vtable);
     436                 :   
     437                 :   llvm::Value *VFuncPtr = 
     438               22:     CGF.Builder.CreateConstInBoundsGEP1_64(Vtable, VtableIndex, "vfn");
     439               22:   return CGF.Builder.CreateLoad(VFuncPtr);
     440                 : }
     441                 : 
     442                 : llvm::Value *
     443                 : CodeGenFunction::BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *This,
     444               21:                                   const llvm::Type *Ty) {
     445               21:   MD = MD->getCanonicalDecl();
     446               21:   uint64_t VtableIndex = CGM.getVtableInfo().getMethodVtableIndex(MD);
     447                 :   
     448               21:   return ::BuildVirtualCall(*this, VtableIndex, This, Ty);
     449                 : }
     450                 : 
     451                 : llvm::Value *
     452                 : CodeGenFunction::BuildVirtualCall(const CXXDestructorDecl *DD, CXXDtorType Type, 
     453                1:                                   llvm::Value *&This, const llvm::Type *Ty) {
     454                1:   DD = cast<CXXDestructorDecl>(DD->getCanonicalDecl());
     455                 :   uint64_t VtableIndex = 
     456                1:     CGM.getVtableInfo().getMethodVtableIndex(GlobalDecl(DD, Type));
     457                 : 
     458                1:   return ::BuildVirtualCall(*this, VtableIndex, This, Ty);
     459                 : }

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