1199990Srdivacky//===--- CGClass.cpp - Emit LLVM Code for C++ classes ---------------------===// 2199990Srdivacky// 3199990Srdivacky// The LLVM Compiler Infrastructure 4199990Srdivacky// 5199990Srdivacky// This file is distributed under the University of Illinois Open Source 6199990Srdivacky// License. See LICENSE.TXT for details. 7199990Srdivacky// 8199990Srdivacky//===----------------------------------------------------------------------===// 9199990Srdivacky// 10199990Srdivacky// This contains code dealing with C++ code generation of classes 11199990Srdivacky// 12199990Srdivacky//===----------------------------------------------------------------------===// 13199990Srdivacky 14234353Sdim#include "CGBlocks.h" 15212904Sdim#include "CGDebugInfo.h" 16249423Sdim#include "CGRecordLayout.h" 17199990Srdivacky#include "CodeGenFunction.h" 18249423Sdim#include "CGCXXABI.h" 19199990Srdivacky#include "clang/AST/CXXInheritance.h" 20263508Sdim#include "clang/AST/DeclTemplate.h" 21218893Sdim#include "clang/AST/EvaluatedExprVisitor.h" 22199990Srdivacky#include "clang/AST/RecordLayout.h" 23204643Srdivacky#include "clang/AST/StmtCXX.h" 24249423Sdim#include "clang/Basic/TargetBuiltins.h" 25263508Sdim#include "clang/CodeGen/CGFunctionInfo.h" 26219077Sdim#include "clang/Frontend/CodeGenOptions.h" 27199990Srdivacky 28199990Srdivackyusing namespace clang; 29199990Srdivackyusing namespace CodeGen; 30199990Srdivacky 31221345Sdimstatic CharUnits 32207619SrdivackyComputeNonVirtualBaseClassOffset(ASTContext &Context, 33207619Srdivacky const CXXRecordDecl *DerivedClass, 34212904Sdim CastExpr::path_const_iterator Start, 35212904Sdim CastExpr::path_const_iterator End) { 36221345Sdim CharUnits Offset = CharUnits::Zero(); 37207619Srdivacky 38207619Srdivacky const CXXRecordDecl *RD = DerivedClass; 39207619Srdivacky 40212904Sdim for (CastExpr::path_const_iterator I = Start; I != End; ++I) { 41207619Srdivacky const CXXBaseSpecifier *Base = *I; 42207619Srdivacky assert(!Base->isVirtual() && "Should not see virtual bases here!"); 43199990Srdivacky 44199990Srdivacky // Get the layout. 45207619Srdivacky const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 46199990Srdivacky 47207619Srdivacky const CXXRecordDecl *BaseDecl = 48207619Srdivacky cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 49199990Srdivacky 50207619Srdivacky // Add the offset. 51221345Sdim Offset += Layout.getBaseClassOffset(BaseDecl); 52199990Srdivacky 53207619Srdivacky RD = BaseDecl; 54199990Srdivacky } 55207619Srdivacky 56221345Sdim return Offset; 57199990Srdivacky} 58199990Srdivacky 59199990Srdivackyllvm::Constant * 60207619SrdivackyCodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, 61212904Sdim CastExpr::path_const_iterator PathBegin, 62212904Sdim CastExpr::path_const_iterator PathEnd) { 63212904Sdim assert(PathBegin != PathEnd && "Base path should not be empty!"); 64199990Srdivacky 65221345Sdim CharUnits Offset = 66212904Sdim ComputeNonVirtualBaseClassOffset(getContext(), ClassDecl, 67212904Sdim PathBegin, PathEnd); 68221345Sdim if (Offset.isZero()) 69199990Srdivacky return 0; 70207619Srdivacky 71226633Sdim llvm::Type *PtrDiffTy = 72207619Srdivacky Types.ConvertType(getContext().getPointerDiffType()); 73207619Srdivacky 74221345Sdim return llvm::ConstantInt::get(PtrDiffTy, Offset.getQuantity()); 75199990Srdivacky} 76199990Srdivacky 77207619Srdivacky/// Gets the address of a direct base class within a complete object. 78203955Srdivacky/// This should only be used for (1) non-virtual bases or (2) virtual bases 79203955Srdivacky/// when the type is known to be complete (e.g. in complete destructors). 80203955Srdivacky/// 81203955Srdivacky/// The object pointed to by 'This' is assumed to be non-null. 82199990Srdivackyllvm::Value * 83207619SrdivackyCodeGenFunction::GetAddressOfDirectBaseInCompleteClass(llvm::Value *This, 84207619Srdivacky const CXXRecordDecl *Derived, 85207619Srdivacky const CXXRecordDecl *Base, 86207619Srdivacky bool BaseIsVirtual) { 87203955Srdivacky // 'this' must be a pointer (in some address space) to Derived. 88203955Srdivacky assert(This->getType()->isPointerTy() && 89203955Srdivacky cast<llvm::PointerType>(This->getType())->getElementType() 90203955Srdivacky == ConvertType(Derived)); 91203955Srdivacky 92203955Srdivacky // Compute the offset of the virtual base. 93221345Sdim CharUnits Offset; 94203955Srdivacky const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Derived); 95207619Srdivacky if (BaseIsVirtual) 96221345Sdim Offset = Layout.getVBaseClassOffset(Base); 97203955Srdivacky else 98221345Sdim Offset = Layout.getBaseClassOffset(Base); 99203955Srdivacky 100203955Srdivacky // Shift and cast down to the base type. 101203955Srdivacky // TODO: for complete types, this should be possible with a GEP. 102203955Srdivacky llvm::Value *V = This; 103221345Sdim if (Offset.isPositive()) { 104203955Srdivacky V = Builder.CreateBitCast(V, Int8PtrTy); 105221345Sdim V = Builder.CreateConstInBoundsGEP1_64(V, Offset.getQuantity()); 106203955Srdivacky } 107203955Srdivacky V = Builder.CreateBitCast(V, ConvertType(Base)->getPointerTo()); 108203955Srdivacky 109203955Srdivacky return V; 110206084Srdivacky} 111203955Srdivacky 112207619Srdivackystatic llvm::Value * 113239462SdimApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, llvm::Value *ptr, 114239462Sdim CharUnits nonVirtualOffset, 115239462Sdim llvm::Value *virtualOffset) { 116239462Sdim // Assert that we have something to do. 117239462Sdim assert(!nonVirtualOffset.isZero() || virtualOffset != 0); 118239462Sdim 119239462Sdim // Compute the offset from the static and dynamic components. 120239462Sdim llvm::Value *baseOffset; 121239462Sdim if (!nonVirtualOffset.isZero()) { 122239462Sdim baseOffset = llvm::ConstantInt::get(CGF.PtrDiffTy, 123239462Sdim nonVirtualOffset.getQuantity()); 124239462Sdim if (virtualOffset) { 125239462Sdim baseOffset = CGF.Builder.CreateAdd(virtualOffset, baseOffset); 126239462Sdim } 127239462Sdim } else { 128239462Sdim baseOffset = virtualOffset; 129239462Sdim } 130207619Srdivacky 131207619Srdivacky // Apply the base offset. 132239462Sdim ptr = CGF.Builder.CreateBitCast(ptr, CGF.Int8PtrTy); 133239462Sdim ptr = CGF.Builder.CreateInBoundsGEP(ptr, baseOffset, "add.ptr"); 134239462Sdim return ptr; 135207619Srdivacky} 136207619Srdivacky 137203955Srdivackyllvm::Value * 138207619SrdivackyCodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, 139207619Srdivacky const CXXRecordDecl *Derived, 140212904Sdim CastExpr::path_const_iterator PathBegin, 141212904Sdim CastExpr::path_const_iterator PathEnd, 142199990Srdivacky bool NullCheckValue) { 143212904Sdim assert(PathBegin != PathEnd && "Base path should not be empty!"); 144199990Srdivacky 145212904Sdim CastExpr::path_const_iterator Start = PathBegin; 146203955Srdivacky const CXXRecordDecl *VBase = 0; 147207619Srdivacky 148239462Sdim // Sema has done some convenient canonicalization here: if the 149239462Sdim // access path involved any virtual steps, the conversion path will 150239462Sdim // *start* with a step down to the correct virtual base subobject, 151239462Sdim // and hence will not require any further steps. 152207619Srdivacky if ((*Start)->isVirtual()) { 153207619Srdivacky VBase = 154207619Srdivacky cast<CXXRecordDecl>((*Start)->getType()->getAs<RecordType>()->getDecl()); 155207619Srdivacky ++Start; 156203955Srdivacky } 157239462Sdim 158239462Sdim // Compute the static offset of the ultimate destination within its 159239462Sdim // allocating subobject (the virtual base, if there is one, or else 160239462Sdim // the "complete" object that we see). 161221345Sdim CharUnits NonVirtualOffset = 162207619Srdivacky ComputeNonVirtualBaseClassOffset(getContext(), VBase ? VBase : Derived, 163212904Sdim Start, PathEnd); 164203955Srdivacky 165239462Sdim // If there's a virtual step, we can sometimes "devirtualize" it. 166239462Sdim // For now, that's limited to when the derived type is final. 167239462Sdim // TODO: "devirtualize" this for accesses to known-complete objects. 168239462Sdim if (VBase && Derived->hasAttr<FinalAttr>()) { 169239462Sdim const ASTRecordLayout &layout = getContext().getASTRecordLayout(Derived); 170239462Sdim CharUnits vBaseOffset = layout.getVBaseClassOffset(VBase); 171239462Sdim NonVirtualOffset += vBaseOffset; 172239462Sdim VBase = 0; // we no longer have a virtual step 173239462Sdim } 174239462Sdim 175207619Srdivacky // Get the base pointer type. 176226633Sdim llvm::Type *BasePtrTy = 177212904Sdim ConvertType((PathEnd[-1])->getType())->getPointerTo(); 178239462Sdim 179239462Sdim // If the static offset is zero and we don't have a virtual step, 180239462Sdim // just do a bitcast; null checks are unnecessary. 181221345Sdim if (NonVirtualOffset.isZero() && !VBase) { 182203955Srdivacky return Builder.CreateBitCast(Value, BasePtrTy); 183203955Srdivacky } 184239462Sdim 185239462Sdim llvm::BasicBlock *origBB = 0; 186239462Sdim llvm::BasicBlock *endBB = 0; 187207619Srdivacky 188239462Sdim // Skip over the offset (and the vtable load) if we're supposed to 189239462Sdim // null-check the pointer. 190199990Srdivacky if (NullCheckValue) { 191239462Sdim origBB = Builder.GetInsertBlock(); 192239462Sdim llvm::BasicBlock *notNullBB = createBasicBlock("cast.notnull"); 193239462Sdim endBB = createBasicBlock("cast.end"); 194199990Srdivacky 195239462Sdim llvm::Value *isNull = Builder.CreateIsNull(Value); 196239462Sdim Builder.CreateCondBr(isNull, endBB, notNullBB); 197239462Sdim EmitBlock(notNullBB); 198199990Srdivacky } 199207619Srdivacky 200239462Sdim // Compute the virtual offset. 201207619Srdivacky llvm::Value *VirtualOffset = 0; 202218893Sdim if (VBase) { 203263508Sdim VirtualOffset = 204263508Sdim CGM.getCXXABI().GetVirtualBaseClassOffset(*this, Value, Derived, VBase); 205218893Sdim } 206218893Sdim 207239462Sdim // Apply both offsets. 208221345Sdim Value = ApplyNonVirtualAndVirtualOffset(*this, Value, 209221345Sdim NonVirtualOffset, 210207619Srdivacky VirtualOffset); 211199990Srdivacky 212239462Sdim // Cast to the destination type. 213199990Srdivacky Value = Builder.CreateBitCast(Value, BasePtrTy); 214239462Sdim 215239462Sdim // Build a phi if we needed a null check. 216199990Srdivacky if (NullCheckValue) { 217239462Sdim llvm::BasicBlock *notNullBB = Builder.GetInsertBlock(); 218239462Sdim Builder.CreateBr(endBB); 219239462Sdim EmitBlock(endBB); 220199990Srdivacky 221239462Sdim llvm::PHINode *PHI = Builder.CreatePHI(BasePtrTy, 2, "cast.result"); 222239462Sdim PHI->addIncoming(Value, notNullBB); 223239462Sdim PHI->addIncoming(llvm::Constant::getNullValue(BasePtrTy), origBB); 224199990Srdivacky Value = PHI; 225199990Srdivacky } 226199990Srdivacky 227199990Srdivacky return Value; 228199990Srdivacky} 229199990Srdivacky 230199990Srdivackyllvm::Value * 231199990SrdivackyCodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value, 232207619Srdivacky const CXXRecordDecl *Derived, 233212904Sdim CastExpr::path_const_iterator PathBegin, 234212904Sdim CastExpr::path_const_iterator PathEnd, 235199990Srdivacky bool NullCheckValue) { 236212904Sdim assert(PathBegin != PathEnd && "Base path should not be empty!"); 237207619Srdivacky 238199990Srdivacky QualType DerivedTy = 239207619Srdivacky getContext().getCanonicalType(getContext().getTagDeclType(Derived)); 240226633Sdim llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo(); 241249423Sdim 242203955Srdivacky llvm::Value *NonVirtualOffset = 243212904Sdim CGM.GetNonVirtualBaseClassOffset(Derived, PathBegin, PathEnd); 244203955Srdivacky 245203955Srdivacky if (!NonVirtualOffset) { 246203955Srdivacky // No offset, we can just cast back. 247203955Srdivacky return Builder.CreateBitCast(Value, DerivedPtrTy); 248203955Srdivacky } 249203955Srdivacky 250199990Srdivacky llvm::BasicBlock *CastNull = 0; 251199990Srdivacky llvm::BasicBlock *CastNotNull = 0; 252199990Srdivacky llvm::BasicBlock *CastEnd = 0; 253199990Srdivacky 254199990Srdivacky if (NullCheckValue) { 255199990Srdivacky CastNull = createBasicBlock("cast.null"); 256199990Srdivacky CastNotNull = createBasicBlock("cast.notnull"); 257199990Srdivacky CastEnd = createBasicBlock("cast.end"); 258199990Srdivacky 259221345Sdim llvm::Value *IsNull = Builder.CreateIsNull(Value); 260199990Srdivacky Builder.CreateCondBr(IsNull, CastNull, CastNotNull); 261199990Srdivacky EmitBlock(CastNotNull); 262199990Srdivacky } 263199990Srdivacky 264203955Srdivacky // Apply the offset. 265234353Sdim Value = Builder.CreateBitCast(Value, Int8PtrTy); 266234353Sdim Value = Builder.CreateGEP(Value, Builder.CreateNeg(NonVirtualOffset), 267234353Sdim "sub.ptr"); 268199990Srdivacky 269203955Srdivacky // Just cast. 270203955Srdivacky Value = Builder.CreateBitCast(Value, DerivedPtrTy); 271203955Srdivacky 272199990Srdivacky if (NullCheckValue) { 273199990Srdivacky Builder.CreateBr(CastEnd); 274199990Srdivacky EmitBlock(CastNull); 275199990Srdivacky Builder.CreateBr(CastEnd); 276199990Srdivacky EmitBlock(CastEnd); 277199990Srdivacky 278221345Sdim llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2); 279199990Srdivacky PHI->addIncoming(Value, CastNotNull); 280199990Srdivacky PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 281199990Srdivacky CastNull); 282199990Srdivacky Value = PHI; 283199990Srdivacky } 284199990Srdivacky 285199990Srdivacky return Value; 286199990Srdivacky} 287249423Sdim 288249423Sdimllvm::Value *CodeGenFunction::GetVTTParameter(GlobalDecl GD, 289249423Sdim bool ForVirtualBase, 290249423Sdim bool Delegating) { 291263508Sdim if (!CGM.getCXXABI().NeedsVTTParameter(GD)) { 292202379Srdivacky // This constructor/destructor does not need a VTT parameter. 293202379Srdivacky return 0; 294202379Srdivacky } 295202379Srdivacky 296251662Sdim const CXXRecordDecl *RD = cast<CXXMethodDecl>(CurCodeDecl)->getParent(); 297202379Srdivacky const CXXRecordDecl *Base = cast<CXXMethodDecl>(GD.getDecl())->getParent(); 298204643Srdivacky 299202379Srdivacky llvm::Value *VTT; 300202379Srdivacky 301204643Srdivacky uint64_t SubVTTIndex; 302204643Srdivacky 303249423Sdim if (Delegating) { 304249423Sdim // If this is a delegating constructor call, just load the VTT. 305249423Sdim return LoadCXXVTT(); 306249423Sdim } else if (RD == Base) { 307249423Sdim // If the record matches the base, this is the complete ctor/dtor 308249423Sdim // variant calling the base variant in a class with virtual bases. 309263508Sdim assert(!CGM.getCXXABI().NeedsVTTParameter(CurGD) && 310204643Srdivacky "doing no-op VTT offset in base dtor/ctor?"); 311207619Srdivacky assert(!ForVirtualBase && "Can't have same class as virtual base!"); 312204643Srdivacky SubVTTIndex = 0; 313204643Srdivacky } else { 314249423Sdim const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 315221345Sdim CharUnits BaseOffset = ForVirtualBase ? 316221345Sdim Layout.getVBaseClassOffset(Base) : 317221345Sdim Layout.getBaseClassOffset(Base); 318207619Srdivacky 319207619Srdivacky SubVTTIndex = 320249423Sdim CGM.getVTables().getSubVTTIndex(RD, BaseSubobject(Base, BaseOffset)); 321204643Srdivacky assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!"); 322204643Srdivacky } 323202379Srdivacky 324263508Sdim if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) { 325202379Srdivacky // A VTT parameter was passed to the constructor, use it. 326249423Sdim VTT = LoadCXXVTT(); 327249423Sdim VTT = Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex); 328202379Srdivacky } else { 329202379Srdivacky // We're the complete constructor, so get the VTT by name. 330249423Sdim VTT = CGM.getVTables().GetAddrOfVTT(RD); 331249423Sdim VTT = Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex); 332202379Srdivacky } 333202379Srdivacky 334202379Srdivacky return VTT; 335202379Srdivacky} 336202379Srdivacky 337212904Sdimnamespace { 338212904Sdim /// Call the destructor for a direct base class. 339212904Sdim struct CallBaseDtor : EHScopeStack::Cleanup { 340212904Sdim const CXXRecordDecl *BaseClass; 341212904Sdim bool BaseIsVirtual; 342212904Sdim CallBaseDtor(const CXXRecordDecl *Base, bool BaseIsVirtual) 343212904Sdim : BaseClass(Base), BaseIsVirtual(BaseIsVirtual) {} 344212904Sdim 345224145Sdim void Emit(CodeGenFunction &CGF, Flags flags) { 346212904Sdim const CXXRecordDecl *DerivedClass = 347212904Sdim cast<CXXMethodDecl>(CGF.CurCodeDecl)->getParent(); 348212904Sdim 349212904Sdim const CXXDestructorDecl *D = BaseClass->getDestructor(); 350212904Sdim llvm::Value *Addr = 351212904Sdim CGF.GetAddressOfDirectBaseInCompleteClass(CGF.LoadCXXThis(), 352212904Sdim DerivedClass, BaseClass, 353212904Sdim BaseIsVirtual); 354249423Sdim CGF.EmitCXXDestructorCall(D, Dtor_Base, BaseIsVirtual, 355249423Sdim /*Delegating=*/false, Addr); 356212904Sdim } 357212904Sdim }; 358218893Sdim 359218893Sdim /// A visitor which checks whether an initializer uses 'this' in a 360218893Sdim /// way which requires the vtable to be properly set. 361218893Sdim struct DynamicThisUseChecker : EvaluatedExprVisitor<DynamicThisUseChecker> { 362218893Sdim typedef EvaluatedExprVisitor<DynamicThisUseChecker> super; 363218893Sdim 364218893Sdim bool UsesThis; 365218893Sdim 366218893Sdim DynamicThisUseChecker(ASTContext &C) : super(C), UsesThis(false) {} 367218893Sdim 368218893Sdim // Black-list all explicit and implicit references to 'this'. 369218893Sdim // 370218893Sdim // Do we need to worry about external references to 'this' derived 371218893Sdim // from arbitrary code? If so, then anything which runs arbitrary 372218893Sdim // external code might potentially access the vtable. 373218893Sdim void VisitCXXThisExpr(CXXThisExpr *E) { UsesThis = true; } 374218893Sdim }; 375212904Sdim} 376212904Sdim 377218893Sdimstatic bool BaseInitializerUsesThis(ASTContext &C, const Expr *Init) { 378218893Sdim DynamicThisUseChecker Checker(C); 379218893Sdim Checker.Visit(const_cast<Expr*>(Init)); 380218893Sdim return Checker.UsesThis; 381218893Sdim} 382218893Sdim 383201361Srdivackystatic void EmitBaseInitializer(CodeGenFunction &CGF, 384201361Srdivacky const CXXRecordDecl *ClassDecl, 385218893Sdim CXXCtorInitializer *BaseInit, 386201361Srdivacky CXXCtorType CtorType) { 387201361Srdivacky assert(BaseInit->isBaseInitializer() && 388201361Srdivacky "Must have base initializer!"); 389201361Srdivacky 390201361Srdivacky llvm::Value *ThisPtr = CGF.LoadCXXThis(); 391201361Srdivacky 392201361Srdivacky const Type *BaseType = BaseInit->getBaseClass(); 393201361Srdivacky CXXRecordDecl *BaseClassDecl = 394201361Srdivacky cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl()); 395201361Srdivacky 396207619Srdivacky bool isBaseVirtual = BaseInit->isBaseVirtual(); 397201361Srdivacky 398201361Srdivacky // The base constructor doesn't construct virtual bases. 399201361Srdivacky if (CtorType == Ctor_Base && isBaseVirtual) 400201361Srdivacky return; 401201361Srdivacky 402218893Sdim // If the initializer for the base (other than the constructor 403218893Sdim // itself) accesses 'this' in any way, we need to initialize the 404218893Sdim // vtables. 405218893Sdim if (BaseInitializerUsesThis(CGF.getContext(), BaseInit->getInit())) 406218893Sdim CGF.InitializeVTablePointers(ClassDecl); 407218893Sdim 408203955Srdivacky // We can pretend to be a complete class because it only matters for 409203955Srdivacky // virtual bases, and we only do virtual bases for complete ctors. 410207619Srdivacky llvm::Value *V = 411207619Srdivacky CGF.GetAddressOfDirectBaseInCompleteClass(ThisPtr, ClassDecl, 412212904Sdim BaseClassDecl, 413212904Sdim isBaseVirtual); 414234353Sdim CharUnits Alignment = CGF.getContext().getTypeAlignInChars(BaseType); 415226633Sdim AggValueSlot AggSlot = 416234353Sdim AggValueSlot::forAddr(V, Alignment, Qualifiers(), 417226633Sdim AggValueSlot::IsDestructed, 418226633Sdim AggValueSlot::DoesNotNeedGCBarriers, 419226633Sdim AggValueSlot::IsNotAliased); 420218893Sdim 421218893Sdim CGF.EmitAggExpr(BaseInit->getInit(), AggSlot); 422203955Srdivacky 423234353Sdim if (CGF.CGM.getLangOpts().Exceptions && 424218893Sdim !BaseClassDecl->hasTrivialDestructor()) 425212904Sdim CGF.EHStack.pushCleanup<CallBaseDtor>(EHCleanup, BaseClassDecl, 426212904Sdim isBaseVirtual); 427201361Srdivacky} 428201361Srdivacky 429208600Srdivackystatic void EmitAggMemberInitializer(CodeGenFunction &CGF, 430208600Srdivacky LValue LHS, 431234353Sdim Expr *Init, 432208600Srdivacky llvm::Value *ArrayIndexVar, 433208600Srdivacky QualType T, 434234353Sdim ArrayRef<VarDecl *> ArrayIndexes, 435208600Srdivacky unsigned Index) { 436234353Sdim if (Index == ArrayIndexes.size()) { 437234353Sdim LValue LV = LHS; 438234353Sdim 439263508Sdim if (ArrayIndexVar) { 440263508Sdim // If we have an array index variable, load it and use it as an offset. 441263508Sdim // Then, increment the value. 442263508Sdim llvm::Value *Dest = LHS.getAddress(); 443263508Sdim llvm::Value *ArrayIndex = CGF.Builder.CreateLoad(ArrayIndexVar); 444263508Sdim Dest = CGF.Builder.CreateInBoundsGEP(Dest, ArrayIndex, "destaddress"); 445263508Sdim llvm::Value *Next = llvm::ConstantInt::get(ArrayIndex->getType(), 1); 446263508Sdim Next = CGF.Builder.CreateAdd(ArrayIndex, Next, "inc"); 447263508Sdim CGF.Builder.CreateStore(Next, ArrayIndexVar); 448234353Sdim 449263508Sdim // Update the LValue. 450263508Sdim LV.setAddress(Dest); 451263508Sdim CharUnits Align = CGF.getContext().getTypeAlignInChars(T); 452263508Sdim LV.setAlignment(std::min(Align, LV.getAlignment())); 453263508Sdim } 454234353Sdim 455263508Sdim switch (CGF.getEvaluationKind(T)) { 456263508Sdim case TEK_Scalar: 457263508Sdim CGF.EmitScalarInit(Init, /*decl*/ 0, LV, false); 458263508Sdim break; 459263508Sdim case TEK_Complex: 460263508Sdim CGF.EmitComplexExprIntoLValue(Init, LV, /*isInit*/ true); 461263508Sdim break; 462263508Sdim case TEK_Aggregate: { 463263508Sdim AggValueSlot Slot = 464263508Sdim AggValueSlot::forLValue(LV, 465263508Sdim AggValueSlot::IsDestructed, 466263508Sdim AggValueSlot::DoesNotNeedGCBarriers, 467263508Sdim AggValueSlot::IsNotAliased); 468234353Sdim 469263508Sdim CGF.EmitAggExpr(Init, Slot); 470263508Sdim break; 471208600Srdivacky } 472263508Sdim } 473218893Sdim 474208600Srdivacky return; 475208600Srdivacky } 476263508Sdim 477208600Srdivacky const ConstantArrayType *Array = CGF.getContext().getAsConstantArrayType(T); 478208600Srdivacky assert(Array && "Array initialization without the array type?"); 479208600Srdivacky llvm::Value *IndexVar 480234353Sdim = CGF.GetAddrOfLocalVar(ArrayIndexes[Index]); 481208600Srdivacky assert(IndexVar && "Array index variable not loaded"); 482208600Srdivacky 483208600Srdivacky // Initialize this index variable to zero. 484208600Srdivacky llvm::Value* Zero 485208600Srdivacky = llvm::Constant::getNullValue( 486208600Srdivacky CGF.ConvertType(CGF.getContext().getSizeType())); 487208600Srdivacky CGF.Builder.CreateStore(Zero, IndexVar); 488208600Srdivacky 489208600Srdivacky // Start the loop with a block that tests the condition. 490208600Srdivacky llvm::BasicBlock *CondBlock = CGF.createBasicBlock("for.cond"); 491208600Srdivacky llvm::BasicBlock *AfterFor = CGF.createBasicBlock("for.end"); 492208600Srdivacky 493208600Srdivacky CGF.EmitBlock(CondBlock); 494208600Srdivacky 495208600Srdivacky llvm::BasicBlock *ForBody = CGF.createBasicBlock("for.body"); 496208600Srdivacky // Generate: if (loop-index < number-of-elements) fall to the loop body, 497208600Srdivacky // otherwise, go to the block after the for-loop. 498208600Srdivacky uint64_t NumElements = Array->getSize().getZExtValue(); 499208600Srdivacky llvm::Value *Counter = CGF.Builder.CreateLoad(IndexVar); 500208600Srdivacky llvm::Value *NumElementsPtr = 501208600Srdivacky llvm::ConstantInt::get(Counter->getType(), NumElements); 502208600Srdivacky llvm::Value *IsLess = CGF.Builder.CreateICmpULT(Counter, NumElementsPtr, 503208600Srdivacky "isless"); 504208600Srdivacky 505208600Srdivacky // If the condition is true, execute the body. 506208600Srdivacky CGF.Builder.CreateCondBr(IsLess, ForBody, AfterFor); 507208600Srdivacky 508208600Srdivacky CGF.EmitBlock(ForBody); 509208600Srdivacky llvm::BasicBlock *ContinueBlock = CGF.createBasicBlock("for.inc"); 510263508Sdim 511263508Sdim // Inside the loop body recurse to emit the inner loop or, eventually, the 512263508Sdim // constructor call. 513263508Sdim EmitAggMemberInitializer(CGF, LHS, Init, ArrayIndexVar, 514263508Sdim Array->getElementType(), ArrayIndexes, Index + 1); 515263508Sdim 516208600Srdivacky CGF.EmitBlock(ContinueBlock); 517208600Srdivacky 518208600Srdivacky // Emit the increment of the loop counter. 519208600Srdivacky llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1); 520208600Srdivacky Counter = CGF.Builder.CreateLoad(IndexVar); 521208600Srdivacky NextVal = CGF.Builder.CreateAdd(Counter, NextVal, "inc"); 522208600Srdivacky CGF.Builder.CreateStore(NextVal, IndexVar); 523208600Srdivacky 524208600Srdivacky // Finally, branch back up to the condition for the next iteration. 525208600Srdivacky CGF.EmitBranch(CondBlock); 526208600Srdivacky 527208600Srdivacky // Emit the fall-through block. 528208600Srdivacky CGF.EmitBlock(AfterFor, true); 529208600Srdivacky} 530212904Sdim 531201361Srdivackystatic void EmitMemberInitializer(CodeGenFunction &CGF, 532201361Srdivacky const CXXRecordDecl *ClassDecl, 533218893Sdim CXXCtorInitializer *MemberInit, 534208600Srdivacky const CXXConstructorDecl *Constructor, 535208600Srdivacky FunctionArgList &Args) { 536218893Sdim assert(MemberInit->isAnyMemberInitializer() && 537201361Srdivacky "Must have member initializer!"); 538223017Sdim assert(MemberInit->getInit() && "Must have initializer!"); 539201361Srdivacky 540201361Srdivacky // non-static data member initializers. 541218893Sdim FieldDecl *Field = MemberInit->getAnyMember(); 542234353Sdim QualType FieldType = Field->getType(); 543201361Srdivacky 544201361Srdivacky llvm::Value *ThisPtr = CGF.LoadCXXThis(); 545234982Sdim QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl); 546239462Sdim LValue LHS = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy); 547234982Sdim 548218893Sdim if (MemberInit->isIndirectMemberInitializer()) { 549239462Sdim // If we are initializing an anonymous union field, drill down to 550239462Sdim // the field. 551239462Sdim IndirectFieldDecl *IndirectField = MemberInit->getIndirectMember(); 552239462Sdim IndirectFieldDecl::chain_iterator I = IndirectField->chain_begin(), 553239462Sdim IEnd = IndirectField->chain_end(); 554239462Sdim for ( ; I != IEnd; ++I) 555239462Sdim LHS = CGF.EmitLValueForFieldInitialization(LHS, cast<FieldDecl>(*I)); 556218893Sdim FieldType = MemberInit->getIndirectMember()->getAnonField()->getType(); 557208600Srdivacky } else { 558239462Sdim LHS = CGF.EmitLValueForFieldInitialization(LHS, Field); 559201361Srdivacky } 560201361Srdivacky 561234353Sdim // Special case: if we are in a copy or move constructor, and we are copying 562234353Sdim // an array of PODs or classes with trivial copy constructors, ignore the 563234353Sdim // AST and perform the copy we know is equivalent. 564234353Sdim // FIXME: This is hacky at best... if we had a bit more explicit information 565234353Sdim // in the AST, we could generalize it more easily. 566234353Sdim const ConstantArrayType *Array 567234353Sdim = CGF.getContext().getAsConstantArrayType(FieldType); 568263508Sdim if (Array && Constructor->isDefaulted() && 569234353Sdim Constructor->isCopyOrMoveConstructor()) { 570234353Sdim QualType BaseElementTy = CGF.getContext().getBaseElementType(Array); 571243830Sdim CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->getInit()); 572234353Sdim if (BaseElementTy.isPODType(CGF.getContext()) || 573243830Sdim (CE && CE->getConstructor()->isTrivial())) { 574243830Sdim // Find the source pointer. We know it's the last argument because 575243830Sdim // we know we're in an implicit copy constructor. 576234353Sdim unsigned SrcArgIndex = Args.size() - 1; 577234353Sdim llvm::Value *SrcPtr 578234353Sdim = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(Args[SrcArgIndex])); 579234982Sdim LValue ThisRHSLV = CGF.MakeNaturalAlignAddrLValue(SrcPtr, RecordTy); 580234982Sdim LValue Src = CGF.EmitLValueForFieldInitialization(ThisRHSLV, Field); 581234353Sdim 582234353Sdim // Copy the aggregate. 583234353Sdim CGF.EmitAggregateCopy(LHS.getAddress(), Src.getAddress(), FieldType, 584234353Sdim LHS.isVolatileQualified()); 585234353Sdim return; 586234353Sdim } 587234353Sdim } 588234353Sdim 589234353Sdim ArrayRef<VarDecl *> ArrayIndexes; 590234353Sdim if (MemberInit->getNumArrayIndices()) 591234353Sdim ArrayIndexes = MemberInit->getArrayIndexes(); 592234353Sdim CGF.EmitInitializerForField(Field, LHS, MemberInit->getInit(), ArrayIndexes); 593234353Sdim} 594234353Sdim 595234353Sdimvoid CodeGenFunction::EmitInitializerForField(FieldDecl *Field, 596234353Sdim LValue LHS, Expr *Init, 597234353Sdim ArrayRef<VarDecl *> ArrayIndexes) { 598234353Sdim QualType FieldType = Field->getType(); 599249423Sdim switch (getEvaluationKind(FieldType)) { 600249423Sdim case TEK_Scalar: 601224145Sdim if (LHS.isSimple()) { 602234353Sdim EmitExprAsInit(Init, Field, LHS, false); 603224145Sdim } else { 604234353Sdim RValue RHS = RValue::get(EmitScalarExpr(Init)); 605234353Sdim EmitStoreThroughLValue(RHS, LHS); 606224145Sdim } 607249423Sdim break; 608249423Sdim case TEK_Complex: 609249423Sdim EmitComplexExprIntoLValue(Init, LHS, /*isInit*/ true); 610249423Sdim break; 611249423Sdim case TEK_Aggregate: { 612208600Srdivacky llvm::Value *ArrayIndexVar = 0; 613234353Sdim if (ArrayIndexes.size()) { 614234353Sdim llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); 615208600Srdivacky 616208600Srdivacky // The LHS is a pointer to the first object we'll be constructing, as 617208600Srdivacky // a flat array. 618234353Sdim QualType BaseElementTy = getContext().getBaseElementType(FieldType); 619234353Sdim llvm::Type *BasePtr = ConvertType(BaseElementTy); 620208600Srdivacky BasePtr = llvm::PointerType::getUnqual(BasePtr); 621234353Sdim llvm::Value *BaseAddrPtr = Builder.CreateBitCast(LHS.getAddress(), 622234353Sdim BasePtr); 623234353Sdim LHS = MakeAddrLValue(BaseAddrPtr, BaseElementTy); 624208600Srdivacky 625208600Srdivacky // Create an array index that will be used to walk over all of the 626208600Srdivacky // objects we're constructing. 627234353Sdim ArrayIndexVar = CreateTempAlloca(SizeTy, "object.index"); 628208600Srdivacky llvm::Value *Zero = llvm::Constant::getNullValue(SizeTy); 629234353Sdim Builder.CreateStore(Zero, ArrayIndexVar); 630208600Srdivacky 631208600Srdivacky 632208600Srdivacky // Emit the block variables for the array indices, if any. 633234353Sdim for (unsigned I = 0, N = ArrayIndexes.size(); I != N; ++I) 634234353Sdim EmitAutoVarDecl(*ArrayIndexes[I]); 635208600Srdivacky } 636203955Srdivacky 637234353Sdim EmitAggMemberInitializer(*this, LHS, Init, ArrayIndexVar, FieldType, 638234353Sdim ArrayIndexes, 0); 639249423Sdim } 640249423Sdim } 641203955Srdivacky 642249423Sdim // Ensure that we destroy this object if an exception is thrown 643249423Sdim // later in the constructor. 644249423Sdim QualType::DestructionKind dtorKind = FieldType.isDestructedType(); 645249423Sdim if (needsEHCleanup(dtorKind)) 646249423Sdim pushEHDestroy(dtorKind, LHS.getAddress(), FieldType); 647201361Srdivacky} 648201361Srdivacky 649204643Srdivacky/// Checks whether the given constructor is a valid subject for the 650204643Srdivacky/// complete-to-base constructor delegation optimization, i.e. 651204643Srdivacky/// emitting the complete constructor as a simple call to the base 652204643Srdivacky/// constructor. 653204643Srdivackystatic bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor) { 654204643Srdivacky 655204643Srdivacky // Currently we disable the optimization for classes with virtual 656204643Srdivacky // bases because (1) the addresses of parameter variables need to be 657204643Srdivacky // consistent across all initializers but (2) the delegate function 658204643Srdivacky // call necessarily creates a second copy of the parameter variable. 659204643Srdivacky // 660204643Srdivacky // The limiting example (purely theoretical AFAIK): 661204643Srdivacky // struct A { A(int &c) { c++; } }; 662204643Srdivacky // struct B : virtual A { 663204643Srdivacky // B(int count) : A(count) { printf("%d\n", count); } 664204643Srdivacky // }; 665204643Srdivacky // ...although even this example could in principle be emitted as a 666204643Srdivacky // delegation since the address of the parameter doesn't escape. 667204643Srdivacky if (Ctor->getParent()->getNumVBases()) { 668204643Srdivacky // TODO: white-list trivial vbase initializers. This case wouldn't 669204643Srdivacky // be subject to the restrictions below. 670204643Srdivacky 671204643Srdivacky // TODO: white-list cases where: 672204643Srdivacky // - there are no non-reference parameters to the constructor 673204643Srdivacky // - the initializers don't access any non-reference parameters 674204643Srdivacky // - the initializers don't take the address of non-reference 675204643Srdivacky // parameters 676204643Srdivacky // - etc. 677204643Srdivacky // If we ever add any of the above cases, remember that: 678204643Srdivacky // - function-try-blocks will always blacklist this optimization 679204643Srdivacky // - we need to perform the constructor prologue and cleanup in 680204643Srdivacky // EmitConstructorBody. 681204643Srdivacky 682204643Srdivacky return false; 683204643Srdivacky } 684204643Srdivacky 685204643Srdivacky // We also disable the optimization for variadic functions because 686204643Srdivacky // it's impossible to "re-pass" varargs. 687204643Srdivacky if (Ctor->getType()->getAs<FunctionProtoType>()->isVariadic()) 688204643Srdivacky return false; 689204643Srdivacky 690221345Sdim // FIXME: Decide if we can do a delegation of a delegating constructor. 691221345Sdim if (Ctor->isDelegatingConstructor()) 692221345Sdim return false; 693221345Sdim 694204643Srdivacky return true; 695204643Srdivacky} 696204643Srdivacky 697204643Srdivacky/// EmitConstructorBody - Emits the body of the current constructor. 698204643Srdivackyvoid CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) { 699204643Srdivacky const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(CurGD.getDecl()); 700204643Srdivacky CXXCtorType CtorType = CurGD.getCtorType(); 701204643Srdivacky 702204643Srdivacky // Before we go any further, try the complete->base constructor 703204643Srdivacky // delegation optimization. 704239462Sdim if (CtorType == Ctor_Complete && IsConstructorDelegationValid(Ctor) && 705251662Sdim CGM.getTarget().getCXXABI().hasConstructorVariants()) { 706212904Sdim if (CGDebugInfo *DI = getDebugInfo()) 707226633Sdim DI->EmitLocation(Builder, Ctor->getLocEnd()); 708263508Sdim EmitDelegateCXXConstructorCall(Ctor, Ctor_Base, Args, Ctor->getLocEnd()); 709204643Srdivacky return; 710204643Srdivacky } 711204643Srdivacky 712204643Srdivacky Stmt *Body = Ctor->getBody(); 713204643Srdivacky 714204643Srdivacky // Enter the function-try-block before the constructor prologue if 715204643Srdivacky // applicable. 716204643Srdivacky bool IsTryBody = (Body && isa<CXXTryStmt>(Body)); 717204643Srdivacky if (IsTryBody) 718210299Sed EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true); 719204643Srdivacky 720263508Sdim RunCleanupsScope RunCleanups(*this); 721204643Srdivacky 722234353Sdim // TODO: in restricted cases, we can emit the vbase initializers of 723234353Sdim // a complete ctor and then delegate to the base ctor. 724234353Sdim 725204643Srdivacky // Emit the constructor prologue, i.e. the base and member 726204643Srdivacky // initializers. 727208600Srdivacky EmitCtorPrologue(Ctor, CtorType, Args); 728204643Srdivacky 729204643Srdivacky // Emit the body of the statement. 730204643Srdivacky if (IsTryBody) 731204643Srdivacky EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock()); 732204643Srdivacky else if (Body) 733204643Srdivacky EmitStmt(Body); 734204643Srdivacky 735204643Srdivacky // Emit any cleanup blocks associated with the member or base 736204643Srdivacky // initializers, which includes (along the exceptional path) the 737204643Srdivacky // destructors for those members and bases that were fully 738204643Srdivacky // constructed. 739263508Sdim RunCleanups.ForceCleanup(); 740204643Srdivacky 741204643Srdivacky if (IsTryBody) 742210299Sed ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true); 743204643Srdivacky} 744204643Srdivacky 745249423Sdimnamespace { 746263508Sdim /// RAII object to indicate that codegen is copying the value representation 747263508Sdim /// instead of the object representation. Useful when copying a struct or 748263508Sdim /// class which has uninitialized members and we're only performing 749263508Sdim /// lvalue-to-rvalue conversion on the object but not its members. 750263508Sdim class CopyingValueRepresentation { 751263508Sdim public: 752263508Sdim explicit CopyingValueRepresentation(CodeGenFunction &CGF) 753263508Sdim : CGF(CGF), SO(*CGF.SanOpts), OldSanOpts(CGF.SanOpts) { 754263508Sdim SO.Bool = false; 755263508Sdim SO.Enum = false; 756263508Sdim CGF.SanOpts = &SO; 757263508Sdim } 758263508Sdim ~CopyingValueRepresentation() { 759263508Sdim CGF.SanOpts = OldSanOpts; 760263508Sdim } 761263508Sdim private: 762263508Sdim CodeGenFunction &CGF; 763263508Sdim SanitizerOptions SO; 764263508Sdim const SanitizerOptions *OldSanOpts; 765263508Sdim }; 766263508Sdim} 767263508Sdim 768263508Sdimnamespace { 769249423Sdim class FieldMemcpyizer { 770249423Sdim public: 771249423Sdim FieldMemcpyizer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, 772249423Sdim const VarDecl *SrcRec) 773249423Sdim : CGF(CGF), ClassDecl(ClassDecl), SrcRec(SrcRec), 774249423Sdim RecLayout(CGF.getContext().getASTRecordLayout(ClassDecl)), 775249423Sdim FirstField(0), LastField(0), FirstFieldOffset(0), LastFieldOffset(0), 776249423Sdim LastAddedFieldIndex(0) { } 777249423Sdim 778249423Sdim static bool isMemcpyableField(FieldDecl *F) { 779249423Sdim Qualifiers Qual = F->getType().getQualifiers(); 780249423Sdim if (Qual.hasVolatile() || Qual.hasObjCLifetime()) 781249423Sdim return false; 782249423Sdim return true; 783249423Sdim } 784249423Sdim 785249423Sdim void addMemcpyableField(FieldDecl *F) { 786249423Sdim if (FirstField == 0) 787249423Sdim addInitialField(F); 788249423Sdim else 789249423Sdim addNextField(F); 790249423Sdim } 791249423Sdim 792249423Sdim CharUnits getMemcpySize() const { 793249423Sdim unsigned LastFieldSize = 794249423Sdim LastField->isBitField() ? 795249423Sdim LastField->getBitWidthValue(CGF.getContext()) : 796249423Sdim CGF.getContext().getTypeSize(LastField->getType()); 797249423Sdim uint64_t MemcpySizeBits = 798249423Sdim LastFieldOffset + LastFieldSize - FirstFieldOffset + 799249423Sdim CGF.getContext().getCharWidth() - 1; 800249423Sdim CharUnits MemcpySize = 801249423Sdim CGF.getContext().toCharUnitsFromBits(MemcpySizeBits); 802249423Sdim return MemcpySize; 803249423Sdim } 804249423Sdim 805249423Sdim void emitMemcpy() { 806249423Sdim // Give the subclass a chance to bail out if it feels the memcpy isn't 807249423Sdim // worth it (e.g. Hasn't aggregated enough data). 808249423Sdim if (FirstField == 0) { 809249423Sdim return; 810249423Sdim } 811249423Sdim 812249423Sdim CharUnits Alignment; 813249423Sdim 814249423Sdim if (FirstField->isBitField()) { 815249423Sdim const CGRecordLayout &RL = 816249423Sdim CGF.getTypes().getCGRecordLayout(FirstField->getParent()); 817249423Sdim const CGBitFieldInfo &BFInfo = RL.getBitFieldInfo(FirstField); 818249423Sdim Alignment = CharUnits::fromQuantity(BFInfo.StorageAlignment); 819249423Sdim } else { 820249423Sdim Alignment = CGF.getContext().getDeclAlign(FirstField); 821249423Sdim } 822249423Sdim 823249423Sdim assert((CGF.getContext().toCharUnitsFromBits(FirstFieldOffset) % 824249423Sdim Alignment) == 0 && "Bad field alignment."); 825249423Sdim 826249423Sdim CharUnits MemcpySize = getMemcpySize(); 827249423Sdim QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl); 828249423Sdim llvm::Value *ThisPtr = CGF.LoadCXXThis(); 829249423Sdim LValue DestLV = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy); 830249423Sdim LValue Dest = CGF.EmitLValueForFieldInitialization(DestLV, FirstField); 831249423Sdim llvm::Value *SrcPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(SrcRec)); 832249423Sdim LValue SrcLV = CGF.MakeNaturalAlignAddrLValue(SrcPtr, RecordTy); 833249423Sdim LValue Src = CGF.EmitLValueForFieldInitialization(SrcLV, FirstField); 834249423Sdim 835249423Sdim emitMemcpyIR(Dest.isBitField() ? Dest.getBitFieldAddr() : Dest.getAddress(), 836249423Sdim Src.isBitField() ? Src.getBitFieldAddr() : Src.getAddress(), 837249423Sdim MemcpySize, Alignment); 838249423Sdim reset(); 839249423Sdim } 840249423Sdim 841249423Sdim void reset() { 842249423Sdim FirstField = 0; 843249423Sdim } 844249423Sdim 845249423Sdim protected: 846249423Sdim CodeGenFunction &CGF; 847249423Sdim const CXXRecordDecl *ClassDecl; 848249423Sdim 849249423Sdim private: 850249423Sdim 851249423Sdim void emitMemcpyIR(llvm::Value *DestPtr, llvm::Value *SrcPtr, 852249423Sdim CharUnits Size, CharUnits Alignment) { 853249423Sdim llvm::PointerType *DPT = cast<llvm::PointerType>(DestPtr->getType()); 854249423Sdim llvm::Type *DBP = 855249423Sdim llvm::Type::getInt8PtrTy(CGF.getLLVMContext(), DPT->getAddressSpace()); 856249423Sdim DestPtr = CGF.Builder.CreateBitCast(DestPtr, DBP); 857249423Sdim 858249423Sdim llvm::PointerType *SPT = cast<llvm::PointerType>(SrcPtr->getType()); 859249423Sdim llvm::Type *SBP = 860249423Sdim llvm::Type::getInt8PtrTy(CGF.getLLVMContext(), SPT->getAddressSpace()); 861249423Sdim SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, SBP); 862249423Sdim 863249423Sdim CGF.Builder.CreateMemCpy(DestPtr, SrcPtr, Size.getQuantity(), 864249423Sdim Alignment.getQuantity()); 865249423Sdim } 866249423Sdim 867249423Sdim void addInitialField(FieldDecl *F) { 868249423Sdim FirstField = F; 869249423Sdim LastField = F; 870249423Sdim FirstFieldOffset = RecLayout.getFieldOffset(F->getFieldIndex()); 871249423Sdim LastFieldOffset = FirstFieldOffset; 872249423Sdim LastAddedFieldIndex = F->getFieldIndex(); 873249423Sdim return; 874249423Sdim } 875249423Sdim 876249423Sdim void addNextField(FieldDecl *F) { 877263508Sdim // For the most part, the following invariant will hold: 878263508Sdim // F->getFieldIndex() == LastAddedFieldIndex + 1 879263508Sdim // The one exception is that Sema won't add a copy-initializer for an 880263508Sdim // unnamed bitfield, which will show up here as a gap in the sequence. 881263508Sdim assert(F->getFieldIndex() >= LastAddedFieldIndex + 1 && 882263508Sdim "Cannot aggregate fields out of order."); 883249423Sdim LastAddedFieldIndex = F->getFieldIndex(); 884249423Sdim 885249423Sdim // The 'first' and 'last' fields are chosen by offset, rather than field 886249423Sdim // index. This allows the code to support bitfields, as well as regular 887249423Sdim // fields. 888249423Sdim uint64_t FOffset = RecLayout.getFieldOffset(F->getFieldIndex()); 889249423Sdim if (FOffset < FirstFieldOffset) { 890249423Sdim FirstField = F; 891249423Sdim FirstFieldOffset = FOffset; 892249423Sdim } else if (FOffset > LastFieldOffset) { 893249423Sdim LastField = F; 894249423Sdim LastFieldOffset = FOffset; 895249423Sdim } 896249423Sdim } 897249423Sdim 898249423Sdim const VarDecl *SrcRec; 899249423Sdim const ASTRecordLayout &RecLayout; 900249423Sdim FieldDecl *FirstField; 901249423Sdim FieldDecl *LastField; 902249423Sdim uint64_t FirstFieldOffset, LastFieldOffset; 903249423Sdim unsigned LastAddedFieldIndex; 904249423Sdim }; 905249423Sdim 906249423Sdim class ConstructorMemcpyizer : public FieldMemcpyizer { 907249423Sdim private: 908249423Sdim 909249423Sdim /// Get source argument for copy constructor. Returns null if not a copy 910249423Sdim /// constructor. 911249423Sdim static const VarDecl* getTrivialCopySource(const CXXConstructorDecl *CD, 912249423Sdim FunctionArgList &Args) { 913263508Sdim if (CD->isCopyOrMoveConstructor() && CD->isDefaulted()) 914249423Sdim return Args[Args.size() - 1]; 915249423Sdim return 0; 916249423Sdim } 917249423Sdim 918249423Sdim // Returns true if a CXXCtorInitializer represents a member initialization 919249423Sdim // that can be rolled into a memcpy. 920249423Sdim bool isMemberInitMemcpyable(CXXCtorInitializer *MemberInit) const { 921249423Sdim if (!MemcpyableCtor) 922249423Sdim return false; 923249423Sdim FieldDecl *Field = MemberInit->getMember(); 924249423Sdim assert(Field != 0 && "No field for member init."); 925249423Sdim QualType FieldType = Field->getType(); 926249423Sdim CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->getInit()); 927249423Sdim 928249423Sdim // Bail out on non-POD, not-trivially-constructable members. 929249423Sdim if (!(CE && CE->getConstructor()->isTrivial()) && 930249423Sdim !(FieldType.isTriviallyCopyableType(CGF.getContext()) || 931249423Sdim FieldType->isReferenceType())) 932249423Sdim return false; 933249423Sdim 934249423Sdim // Bail out on volatile fields. 935249423Sdim if (!isMemcpyableField(Field)) 936249423Sdim return false; 937249423Sdim 938249423Sdim // Otherwise we're good. 939249423Sdim return true; 940249423Sdim } 941249423Sdim 942249423Sdim public: 943249423Sdim ConstructorMemcpyizer(CodeGenFunction &CGF, const CXXConstructorDecl *CD, 944249423Sdim FunctionArgList &Args) 945249423Sdim : FieldMemcpyizer(CGF, CD->getParent(), getTrivialCopySource(CD, Args)), 946249423Sdim ConstructorDecl(CD), 947263508Sdim MemcpyableCtor(CD->isDefaulted() && 948249423Sdim CD->isCopyOrMoveConstructor() && 949249423Sdim CGF.getLangOpts().getGC() == LangOptions::NonGC), 950249423Sdim Args(Args) { } 951249423Sdim 952249423Sdim void addMemberInitializer(CXXCtorInitializer *MemberInit) { 953249423Sdim if (isMemberInitMemcpyable(MemberInit)) { 954249423Sdim AggregatedInits.push_back(MemberInit); 955249423Sdim addMemcpyableField(MemberInit->getMember()); 956249423Sdim } else { 957249423Sdim emitAggregatedInits(); 958249423Sdim EmitMemberInitializer(CGF, ConstructorDecl->getParent(), MemberInit, 959249423Sdim ConstructorDecl, Args); 960249423Sdim } 961249423Sdim } 962249423Sdim 963249423Sdim void emitAggregatedInits() { 964249423Sdim if (AggregatedInits.size() <= 1) { 965249423Sdim // This memcpy is too small to be worthwhile. Fall back on default 966249423Sdim // codegen. 967263508Sdim if (!AggregatedInits.empty()) { 968263508Sdim CopyingValueRepresentation CVR(CGF); 969249423Sdim EmitMemberInitializer(CGF, ConstructorDecl->getParent(), 970263508Sdim AggregatedInits[0], ConstructorDecl, Args); 971249423Sdim } 972249423Sdim reset(); 973249423Sdim return; 974249423Sdim } 975249423Sdim 976249423Sdim pushEHDestructors(); 977249423Sdim emitMemcpy(); 978249423Sdim AggregatedInits.clear(); 979249423Sdim } 980249423Sdim 981249423Sdim void pushEHDestructors() { 982249423Sdim llvm::Value *ThisPtr = CGF.LoadCXXThis(); 983249423Sdim QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl); 984249423Sdim LValue LHS = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy); 985249423Sdim 986249423Sdim for (unsigned i = 0; i < AggregatedInits.size(); ++i) { 987249423Sdim QualType FieldType = AggregatedInits[i]->getMember()->getType(); 988249423Sdim QualType::DestructionKind dtorKind = FieldType.isDestructedType(); 989249423Sdim if (CGF.needsEHCleanup(dtorKind)) 990249423Sdim CGF.pushEHDestroy(dtorKind, LHS.getAddress(), FieldType); 991249423Sdim } 992249423Sdim } 993249423Sdim 994249423Sdim void finish() { 995249423Sdim emitAggregatedInits(); 996249423Sdim } 997249423Sdim 998249423Sdim private: 999249423Sdim const CXXConstructorDecl *ConstructorDecl; 1000249423Sdim bool MemcpyableCtor; 1001249423Sdim FunctionArgList &Args; 1002249423Sdim SmallVector<CXXCtorInitializer*, 16> AggregatedInits; 1003249423Sdim }; 1004249423Sdim 1005249423Sdim class AssignmentMemcpyizer : public FieldMemcpyizer { 1006249423Sdim private: 1007249423Sdim 1008249423Sdim // Returns the memcpyable field copied by the given statement, if one 1009263508Sdim // exists. Otherwise returns null. 1010263508Sdim FieldDecl *getMemcpyableField(Stmt *S) { 1011249423Sdim if (!AssignmentsMemcpyable) 1012249423Sdim return 0; 1013249423Sdim if (BinaryOperator *BO = dyn_cast<BinaryOperator>(S)) { 1014249423Sdim // Recognise trivial assignments. 1015249423Sdim if (BO->getOpcode() != BO_Assign) 1016249423Sdim return 0; 1017249423Sdim MemberExpr *ME = dyn_cast<MemberExpr>(BO->getLHS()); 1018249423Sdim if (!ME) 1019249423Sdim return 0; 1020249423Sdim FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl()); 1021249423Sdim if (!Field || !isMemcpyableField(Field)) 1022249423Sdim return 0; 1023249423Sdim Stmt *RHS = BO->getRHS(); 1024249423Sdim if (ImplicitCastExpr *EC = dyn_cast<ImplicitCastExpr>(RHS)) 1025249423Sdim RHS = EC->getSubExpr(); 1026249423Sdim if (!RHS) 1027249423Sdim return 0; 1028249423Sdim MemberExpr *ME2 = dyn_cast<MemberExpr>(RHS); 1029249423Sdim if (dyn_cast<FieldDecl>(ME2->getMemberDecl()) != Field) 1030249423Sdim return 0; 1031249423Sdim return Field; 1032249423Sdim } else if (CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(S)) { 1033249423Sdim CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MCE->getCalleeDecl()); 1034249423Sdim if (!(MD && (MD->isCopyAssignmentOperator() || 1035249423Sdim MD->isMoveAssignmentOperator()) && 1036249423Sdim MD->isTrivial())) 1037249423Sdim return 0; 1038249423Sdim MemberExpr *IOA = dyn_cast<MemberExpr>(MCE->getImplicitObjectArgument()); 1039249423Sdim if (!IOA) 1040249423Sdim return 0; 1041249423Sdim FieldDecl *Field = dyn_cast<FieldDecl>(IOA->getMemberDecl()); 1042249423Sdim if (!Field || !isMemcpyableField(Field)) 1043249423Sdim return 0; 1044249423Sdim MemberExpr *Arg0 = dyn_cast<MemberExpr>(MCE->getArg(0)); 1045249423Sdim if (!Arg0 || Field != dyn_cast<FieldDecl>(Arg0->getMemberDecl())) 1046249423Sdim return 0; 1047249423Sdim return Field; 1048249423Sdim } else if (CallExpr *CE = dyn_cast<CallExpr>(S)) { 1049249423Sdim FunctionDecl *FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl()); 1050249423Sdim if (!FD || FD->getBuiltinID() != Builtin::BI__builtin_memcpy) 1051249423Sdim return 0; 1052249423Sdim Expr *DstPtr = CE->getArg(0); 1053249423Sdim if (ImplicitCastExpr *DC = dyn_cast<ImplicitCastExpr>(DstPtr)) 1054249423Sdim DstPtr = DC->getSubExpr(); 1055249423Sdim UnaryOperator *DUO = dyn_cast<UnaryOperator>(DstPtr); 1056249423Sdim if (!DUO || DUO->getOpcode() != UO_AddrOf) 1057249423Sdim return 0; 1058249423Sdim MemberExpr *ME = dyn_cast<MemberExpr>(DUO->getSubExpr()); 1059249423Sdim if (!ME) 1060249423Sdim return 0; 1061249423Sdim FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl()); 1062249423Sdim if (!Field || !isMemcpyableField(Field)) 1063249423Sdim return 0; 1064249423Sdim Expr *SrcPtr = CE->getArg(1); 1065249423Sdim if (ImplicitCastExpr *SC = dyn_cast<ImplicitCastExpr>(SrcPtr)) 1066249423Sdim SrcPtr = SC->getSubExpr(); 1067249423Sdim UnaryOperator *SUO = dyn_cast<UnaryOperator>(SrcPtr); 1068249423Sdim if (!SUO || SUO->getOpcode() != UO_AddrOf) 1069249423Sdim return 0; 1070249423Sdim MemberExpr *ME2 = dyn_cast<MemberExpr>(SUO->getSubExpr()); 1071249423Sdim if (!ME2 || Field != dyn_cast<FieldDecl>(ME2->getMemberDecl())) 1072249423Sdim return 0; 1073249423Sdim return Field; 1074249423Sdim } 1075249423Sdim 1076249423Sdim return 0; 1077249423Sdim } 1078249423Sdim 1079249423Sdim bool AssignmentsMemcpyable; 1080249423Sdim SmallVector<Stmt*, 16> AggregatedStmts; 1081249423Sdim 1082249423Sdim public: 1083249423Sdim 1084249423Sdim AssignmentMemcpyizer(CodeGenFunction &CGF, const CXXMethodDecl *AD, 1085249423Sdim FunctionArgList &Args) 1086249423Sdim : FieldMemcpyizer(CGF, AD->getParent(), Args[Args.size() - 1]), 1087249423Sdim AssignmentsMemcpyable(CGF.getLangOpts().getGC() == LangOptions::NonGC) { 1088249423Sdim assert(Args.size() == 2); 1089249423Sdim } 1090249423Sdim 1091249423Sdim void emitAssignment(Stmt *S) { 1092249423Sdim FieldDecl *F = getMemcpyableField(S); 1093249423Sdim if (F) { 1094249423Sdim addMemcpyableField(F); 1095249423Sdim AggregatedStmts.push_back(S); 1096249423Sdim } else { 1097249423Sdim emitAggregatedStmts(); 1098249423Sdim CGF.EmitStmt(S); 1099249423Sdim } 1100249423Sdim } 1101249423Sdim 1102249423Sdim void emitAggregatedStmts() { 1103249423Sdim if (AggregatedStmts.size() <= 1) { 1104263508Sdim if (!AggregatedStmts.empty()) { 1105263508Sdim CopyingValueRepresentation CVR(CGF); 1106263508Sdim CGF.EmitStmt(AggregatedStmts[0]); 1107263508Sdim } 1108249423Sdim reset(); 1109249423Sdim } 1110249423Sdim 1111249423Sdim emitMemcpy(); 1112249423Sdim AggregatedStmts.clear(); 1113249423Sdim } 1114249423Sdim 1115249423Sdim void finish() { 1116249423Sdim emitAggregatedStmts(); 1117249423Sdim } 1118249423Sdim }; 1119249423Sdim 1120249423Sdim} 1121249423Sdim 1122201361Srdivacky/// EmitCtorPrologue - This routine generates necessary code to initialize 1123201361Srdivacky/// base classes and non-static data members belonging to this constructor. 1124201361Srdivackyvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, 1125208600Srdivacky CXXCtorType CtorType, 1126208600Srdivacky FunctionArgList &Args) { 1127221345Sdim if (CD->isDelegatingConstructor()) 1128221345Sdim return EmitDelegatingCXXConstructorCall(CD, Args); 1129221345Sdim 1130201361Srdivacky const CXXRecordDecl *ClassDecl = CD->getParent(); 1131203955Srdivacky 1132249423Sdim CXXConstructorDecl::init_const_iterator B = CD->init_begin(), 1133249423Sdim E = CD->init_end(); 1134249423Sdim 1135249423Sdim llvm::BasicBlock *BaseCtorContinueBB = 0; 1136249423Sdim if (ClassDecl->getNumVBases() && 1137249423Sdim !CGM.getTarget().getCXXABI().hasConstructorVariants()) { 1138249423Sdim // The ABIs that don't have constructor variants need to put a branch 1139249423Sdim // before the virtual base initialization code. 1140263508Sdim BaseCtorContinueBB = 1141263508Sdim CGM.getCXXABI().EmitCtorCompleteObjectHandler(*this, ClassDecl); 1142249423Sdim assert(BaseCtorContinueBB); 1143201361Srdivacky } 1144201361Srdivacky 1145249423Sdim // Virtual base initializers first. 1146249423Sdim for (; B != E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) { 1147249423Sdim EmitBaseInitializer(*this, ClassDecl, *B, CtorType); 1148249423Sdim } 1149249423Sdim 1150249423Sdim if (BaseCtorContinueBB) { 1151249423Sdim // Complete object handler should continue to the remaining initializers. 1152249423Sdim Builder.CreateBr(BaseCtorContinueBB); 1153249423Sdim EmitBlock(BaseCtorContinueBB); 1154249423Sdim } 1155249423Sdim 1156249423Sdim // Then, non-virtual base initializers. 1157249423Sdim for (; B != E && (*B)->isBaseInitializer(); B++) { 1158249423Sdim assert(!(*B)->isBaseVirtual()); 1159249423Sdim EmitBaseInitializer(*this, ClassDecl, *B, CtorType); 1160249423Sdim } 1161249423Sdim 1162206084Srdivacky InitializeVTablePointers(ClassDecl); 1163203955Srdivacky 1164249423Sdim // And finally, initialize class members. 1165251662Sdim FieldConstructionScope FCS(*this, CXXThisValue); 1166249423Sdim ConstructorMemcpyizer CM(*this, CD, Args); 1167249423Sdim for (; B != E; B++) { 1168249423Sdim CXXCtorInitializer *Member = (*B); 1169249423Sdim assert(!Member->isBaseInitializer()); 1170249423Sdim assert(Member->isAnyMemberInitializer() && 1171249423Sdim "Delegating initializer on non-delegating constructor"); 1172249423Sdim CM.addMemberInitializer(Member); 1173249423Sdim } 1174249423Sdim CM.finish(); 1175201361Srdivacky} 1176201361Srdivacky 1177223017Sdimstatic bool 1178223017SdimFieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field); 1179223017Sdim 1180223017Sdimstatic bool 1181223017SdimHasTrivialDestructorBody(ASTContext &Context, 1182223017Sdim const CXXRecordDecl *BaseClassDecl, 1183223017Sdim const CXXRecordDecl *MostDerivedClassDecl) 1184223017Sdim{ 1185223017Sdim // If the destructor is trivial we don't have to check anything else. 1186223017Sdim if (BaseClassDecl->hasTrivialDestructor()) 1187223017Sdim return true; 1188223017Sdim 1189223017Sdim if (!BaseClassDecl->getDestructor()->hasTrivialBody()) 1190223017Sdim return false; 1191223017Sdim 1192223017Sdim // Check fields. 1193223017Sdim for (CXXRecordDecl::field_iterator I = BaseClassDecl->field_begin(), 1194223017Sdim E = BaseClassDecl->field_end(); I != E; ++I) { 1195223017Sdim const FieldDecl *Field = *I; 1196223017Sdim 1197223017Sdim if (!FieldHasTrivialDestructorBody(Context, Field)) 1198223017Sdim return false; 1199223017Sdim } 1200223017Sdim 1201223017Sdim // Check non-virtual bases. 1202223017Sdim for (CXXRecordDecl::base_class_const_iterator I = 1203223017Sdim BaseClassDecl->bases_begin(), E = BaseClassDecl->bases_end(); 1204223017Sdim I != E; ++I) { 1205223017Sdim if (I->isVirtual()) 1206223017Sdim continue; 1207223017Sdim 1208223017Sdim const CXXRecordDecl *NonVirtualBase = 1209223017Sdim cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl()); 1210223017Sdim if (!HasTrivialDestructorBody(Context, NonVirtualBase, 1211223017Sdim MostDerivedClassDecl)) 1212223017Sdim return false; 1213223017Sdim } 1214223017Sdim 1215223017Sdim if (BaseClassDecl == MostDerivedClassDecl) { 1216223017Sdim // Check virtual bases. 1217223017Sdim for (CXXRecordDecl::base_class_const_iterator I = 1218223017Sdim BaseClassDecl->vbases_begin(), E = BaseClassDecl->vbases_end(); 1219223017Sdim I != E; ++I) { 1220223017Sdim const CXXRecordDecl *VirtualBase = 1221223017Sdim cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl()); 1222223017Sdim if (!HasTrivialDestructorBody(Context, VirtualBase, 1223223017Sdim MostDerivedClassDecl)) 1224223017Sdim return false; 1225223017Sdim } 1226223017Sdim } 1227223017Sdim 1228223017Sdim return true; 1229223017Sdim} 1230223017Sdim 1231223017Sdimstatic bool 1232223017SdimFieldHasTrivialDestructorBody(ASTContext &Context, 1233223017Sdim const FieldDecl *Field) 1234223017Sdim{ 1235223017Sdim QualType FieldBaseElementType = Context.getBaseElementType(Field->getType()); 1236223017Sdim 1237223017Sdim const RecordType *RT = FieldBaseElementType->getAs<RecordType>(); 1238223017Sdim if (!RT) 1239223017Sdim return true; 1240223017Sdim 1241223017Sdim CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 1242223017Sdim return HasTrivialDestructorBody(Context, FieldClassDecl, FieldClassDecl); 1243223017Sdim} 1244223017Sdim 1245223017Sdim/// CanSkipVTablePointerInitialization - Check whether we need to initialize 1246223017Sdim/// any vtable pointers before calling this destructor. 1247223017Sdimstatic bool CanSkipVTablePointerInitialization(ASTContext &Context, 1248223017Sdim const CXXDestructorDecl *Dtor) { 1249223017Sdim if (!Dtor->hasTrivialBody()) 1250223017Sdim return false; 1251223017Sdim 1252223017Sdim // Check the fields. 1253223017Sdim const CXXRecordDecl *ClassDecl = Dtor->getParent(); 1254223017Sdim for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(), 1255223017Sdim E = ClassDecl->field_end(); I != E; ++I) { 1256223017Sdim const FieldDecl *Field = *I; 1257223017Sdim 1258223017Sdim if (!FieldHasTrivialDestructorBody(Context, Field)) 1259223017Sdim return false; 1260223017Sdim } 1261223017Sdim 1262223017Sdim return true; 1263223017Sdim} 1264223017Sdim 1265204643Srdivacky/// EmitDestructorBody - Emits the body of the current destructor. 1266204643Srdivackyvoid CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) { 1267204643Srdivacky const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CurGD.getDecl()); 1268204643Srdivacky CXXDtorType DtorType = CurGD.getDtorType(); 1269204643Srdivacky 1270212904Sdim // The call to operator delete in a deleting destructor happens 1271212904Sdim // outside of the function-try-block, which means it's always 1272212904Sdim // possible to delegate the destructor body to the complete 1273212904Sdim // destructor. Do so. 1274212904Sdim if (DtorType == Dtor_Deleting) { 1275212904Sdim EnterDtorCleanups(Dtor, Dtor_Deleting); 1276212904Sdim EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false, 1277249423Sdim /*Delegating=*/false, LoadCXXThis()); 1278212904Sdim PopCleanupBlock(); 1279212904Sdim return; 1280212904Sdim } 1281212904Sdim 1282204643Srdivacky Stmt *Body = Dtor->getBody(); 1283204643Srdivacky 1284204643Srdivacky // If the body is a function-try-block, enter the try before 1285212904Sdim // anything else. 1286212904Sdim bool isTryBody = (Body && isa<CXXTryStmt>(Body)); 1287204643Srdivacky if (isTryBody) 1288210299Sed EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true); 1289204643Srdivacky 1290212904Sdim // Enter the epilogue cleanups. 1291212904Sdim RunCleanupsScope DtorEpilogue(*this); 1292212904Sdim 1293204643Srdivacky // If this is the complete variant, just invoke the base variant; 1294204643Srdivacky // the epilogue will destruct the virtual bases. But we can't do 1295204643Srdivacky // this optimization if the body is a function-try-block, because 1296263508Sdim // we'd introduce *two* handler blocks. In the Microsoft ABI, we 1297263508Sdim // always delegate because we might not have a definition in this TU. 1298212904Sdim switch (DtorType) { 1299212904Sdim case Dtor_Deleting: llvm_unreachable("already handled deleting case"); 1300212904Sdim 1301212904Sdim case Dtor_Complete: 1302263508Sdim assert((Body || getTarget().getCXXABI().isMicrosoft()) && 1303263508Sdim "can't emit a dtor without a body for non-Microsoft ABIs"); 1304263508Sdim 1305212904Sdim // Enter the cleanup scopes for virtual bases. 1306212904Sdim EnterDtorCleanups(Dtor, Dtor_Complete); 1307212904Sdim 1308263508Sdim if (!isTryBody) { 1309212904Sdim EmitCXXDestructorCall(Dtor, Dtor_Base, /*ForVirtualBase=*/false, 1310249423Sdim /*Delegating=*/false, LoadCXXThis()); 1311212904Sdim break; 1312212904Sdim } 1313212904Sdim // Fallthrough: act like we're in the base variant. 1314204643Srdivacky 1315212904Sdim case Dtor_Base: 1316263508Sdim assert(Body); 1317263508Sdim 1318212904Sdim // Enter the cleanup scopes for fields and non-virtual bases. 1319212904Sdim EnterDtorCleanups(Dtor, Dtor_Base); 1320212904Sdim 1321212904Sdim // Initialize the vtable pointers before entering the body. 1322223017Sdim if (!CanSkipVTablePointerInitialization(getContext(), Dtor)) 1323223017Sdim InitializeVTablePointers(Dtor->getParent()); 1324204643Srdivacky 1325212904Sdim if (isTryBody) 1326212904Sdim EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock()); 1327212904Sdim else if (Body) 1328212904Sdim EmitStmt(Body); 1329212904Sdim else { 1330212904Sdim assert(Dtor->isImplicit() && "bodyless dtor not implicit"); 1331212904Sdim // nothing to do besides what's in the epilogue 1332212904Sdim } 1333218893Sdim // -fapple-kext must inline any call to this dtor into 1334218893Sdim // the caller's body. 1335243830Sdim if (getLangOpts().AppleKext) 1336249423Sdim CurFn->addFnAttr(llvm::Attribute::AlwaysInline); 1337212904Sdim break; 1338204643Srdivacky } 1339204643Srdivacky 1340212904Sdim // Jump out through the epilogue cleanups. 1341212904Sdim DtorEpilogue.ForceCleanup(); 1342204643Srdivacky 1343204643Srdivacky // Exit the try if applicable. 1344204643Srdivacky if (isTryBody) 1345210299Sed ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true); 1346204643Srdivacky} 1347204643Srdivacky 1348249423Sdimvoid CodeGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList &Args) { 1349249423Sdim const CXXMethodDecl *AssignOp = cast<CXXMethodDecl>(CurGD.getDecl()); 1350249423Sdim const Stmt *RootS = AssignOp->getBody(); 1351249423Sdim assert(isa<CompoundStmt>(RootS) && 1352249423Sdim "Body of an implicit assignment operator should be compound stmt."); 1353249423Sdim const CompoundStmt *RootCS = cast<CompoundStmt>(RootS); 1354249423Sdim 1355249423Sdim LexicalScope Scope(*this, RootCS->getSourceRange()); 1356249423Sdim 1357249423Sdim AssignmentMemcpyizer AM(*this, AssignOp, Args); 1358249423Sdim for (CompoundStmt::const_body_iterator I = RootCS->body_begin(), 1359249423Sdim E = RootCS->body_end(); 1360249423Sdim I != E; ++I) { 1361249423Sdim AM.emitAssignment(*I); 1362249423Sdim } 1363249423Sdim AM.finish(); 1364249423Sdim} 1365249423Sdim 1366212904Sdimnamespace { 1367212904Sdim /// Call the operator delete associated with the current destructor. 1368212904Sdim struct CallDtorDelete : EHScopeStack::Cleanup { 1369212904Sdim CallDtorDelete() {} 1370212904Sdim 1371224145Sdim void Emit(CodeGenFunction &CGF, Flags flags) { 1372212904Sdim const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl); 1373212904Sdim const CXXRecordDecl *ClassDecl = Dtor->getParent(); 1374212904Sdim CGF.EmitDeleteCall(Dtor->getOperatorDelete(), CGF.LoadCXXThis(), 1375212904Sdim CGF.getContext().getTagDeclType(ClassDecl)); 1376212904Sdim } 1377212904Sdim }; 1378212904Sdim 1379249423Sdim struct CallDtorDeleteConditional : EHScopeStack::Cleanup { 1380249423Sdim llvm::Value *ShouldDeleteCondition; 1381249423Sdim public: 1382249423Sdim CallDtorDeleteConditional(llvm::Value *ShouldDeleteCondition) 1383249423Sdim : ShouldDeleteCondition(ShouldDeleteCondition) { 1384249423Sdim assert(ShouldDeleteCondition != NULL); 1385249423Sdim } 1386249423Sdim 1387249423Sdim void Emit(CodeGenFunction &CGF, Flags flags) { 1388249423Sdim llvm::BasicBlock *callDeleteBB = CGF.createBasicBlock("dtor.call_delete"); 1389249423Sdim llvm::BasicBlock *continueBB = CGF.createBasicBlock("dtor.continue"); 1390249423Sdim llvm::Value *ShouldCallDelete 1391249423Sdim = CGF.Builder.CreateIsNull(ShouldDeleteCondition); 1392249423Sdim CGF.Builder.CreateCondBr(ShouldCallDelete, continueBB, callDeleteBB); 1393249423Sdim 1394249423Sdim CGF.EmitBlock(callDeleteBB); 1395249423Sdim const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl); 1396249423Sdim const CXXRecordDecl *ClassDecl = Dtor->getParent(); 1397249423Sdim CGF.EmitDeleteCall(Dtor->getOperatorDelete(), CGF.LoadCXXThis(), 1398249423Sdim CGF.getContext().getTagDeclType(ClassDecl)); 1399249423Sdim CGF.Builder.CreateBr(continueBB); 1400249423Sdim 1401249423Sdim CGF.EmitBlock(continueBB); 1402249423Sdim } 1403249423Sdim }; 1404249423Sdim 1405224145Sdim class DestroyField : public EHScopeStack::Cleanup { 1406224145Sdim const FieldDecl *field; 1407234353Sdim CodeGenFunction::Destroyer *destroyer; 1408224145Sdim bool useEHCleanupForArray; 1409212904Sdim 1410224145Sdim public: 1411224145Sdim DestroyField(const FieldDecl *field, CodeGenFunction::Destroyer *destroyer, 1412224145Sdim bool useEHCleanupForArray) 1413234353Sdim : field(field), destroyer(destroyer), 1414224145Sdim useEHCleanupForArray(useEHCleanupForArray) {} 1415224145Sdim 1416224145Sdim void Emit(CodeGenFunction &CGF, Flags flags) { 1417224145Sdim // Find the address of the field. 1418224145Sdim llvm::Value *thisValue = CGF.LoadCXXThis(); 1419234982Sdim QualType RecordTy = CGF.getContext().getTagDeclType(field->getParent()); 1420234982Sdim LValue ThisLV = CGF.MakeAddrLValue(thisValue, RecordTy); 1421234982Sdim LValue LV = CGF.EmitLValueForField(ThisLV, field); 1422224145Sdim assert(LV.isSimple()); 1423212904Sdim 1424224145Sdim CGF.emitDestroy(LV.getAddress(), field->getType(), destroyer, 1425224145Sdim flags.isForNormalCleanup() && useEHCleanupForArray); 1426212904Sdim } 1427212904Sdim }; 1428212904Sdim} 1429212904Sdim 1430201361Srdivacky/// EmitDtorEpilogue - Emit all code that comes at the end of class's 1431201361Srdivacky/// destructor. This is to call destructors on members and base classes 1432201361Srdivacky/// in reverse order of their construction. 1433212904Sdimvoid CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD, 1434212904Sdim CXXDtorType DtorType) { 1435201361Srdivacky assert(!DD->isTrivial() && 1436201361Srdivacky "Should not emit dtor epilogue for trivial dtor!"); 1437201361Srdivacky 1438212904Sdim // The deleting-destructor phase just needs to call the appropriate 1439212904Sdim // operator delete that Sema picked up. 1440204643Srdivacky if (DtorType == Dtor_Deleting) { 1441204643Srdivacky assert(DD->getOperatorDelete() && 1442204643Srdivacky "operator delete missing - EmitDtorEpilogue"); 1443249423Sdim if (CXXStructorImplicitParamValue) { 1444249423Sdim // If there is an implicit param to the deleting dtor, it's a boolean 1445249423Sdim // telling whether we should call delete at the end of the dtor. 1446249423Sdim EHStack.pushCleanup<CallDtorDeleteConditional>( 1447249423Sdim NormalAndEHCleanup, CXXStructorImplicitParamValue); 1448249423Sdim } else { 1449249423Sdim EHStack.pushCleanup<CallDtorDelete>(NormalAndEHCleanup); 1450249423Sdim } 1451204643Srdivacky return; 1452204643Srdivacky } 1453204643Srdivacky 1454212904Sdim const CXXRecordDecl *ClassDecl = DD->getParent(); 1455212904Sdim 1456226633Sdim // Unions have no bases and do not call field destructors. 1457226633Sdim if (ClassDecl->isUnion()) 1458226633Sdim return; 1459226633Sdim 1460212904Sdim // The complete-destructor phase just destructs all the virtual bases. 1461204643Srdivacky if (DtorType == Dtor_Complete) { 1462212904Sdim 1463212904Sdim // We push them in the forward order so that they'll be popped in 1464212904Sdim // the reverse order. 1465212904Sdim for (CXXRecordDecl::base_class_const_iterator I = 1466212904Sdim ClassDecl->vbases_begin(), E = ClassDecl->vbases_end(); 1467204643Srdivacky I != E; ++I) { 1468204643Srdivacky const CXXBaseSpecifier &Base = *I; 1469204643Srdivacky CXXRecordDecl *BaseClassDecl 1470204643Srdivacky = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); 1471204643Srdivacky 1472204643Srdivacky // Ignore trivial destructors. 1473204643Srdivacky if (BaseClassDecl->hasTrivialDestructor()) 1474204643Srdivacky continue; 1475212904Sdim 1476212904Sdim EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, 1477212904Sdim BaseClassDecl, 1478212904Sdim /*BaseIsVirtual*/ true); 1479204643Srdivacky } 1480212904Sdim 1481204643Srdivacky return; 1482204643Srdivacky } 1483204643Srdivacky 1484204643Srdivacky assert(DtorType == Dtor_Base); 1485212904Sdim 1486212904Sdim // Destroy non-virtual bases. 1487212904Sdim for (CXXRecordDecl::base_class_const_iterator I = 1488212904Sdim ClassDecl->bases_begin(), E = ClassDecl->bases_end(); I != E; ++I) { 1489212904Sdim const CXXBaseSpecifier &Base = *I; 1490212904Sdim 1491212904Sdim // Ignore virtual bases. 1492212904Sdim if (Base.isVirtual()) 1493212904Sdim continue; 1494212904Sdim 1495212904Sdim CXXRecordDecl *BaseClassDecl = Base.getType()->getAsCXXRecordDecl(); 1496212904Sdim 1497212904Sdim // Ignore trivial destructors. 1498212904Sdim if (BaseClassDecl->hasTrivialDestructor()) 1499212904Sdim continue; 1500204643Srdivacky 1501212904Sdim EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, 1502212904Sdim BaseClassDecl, 1503212904Sdim /*BaseIsVirtual*/ false); 1504212904Sdim } 1505212904Sdim 1506212904Sdim // Destroy direct fields. 1507226633Sdim SmallVector<const FieldDecl *, 16> FieldDecls; 1508201361Srdivacky for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(), 1509201361Srdivacky E = ClassDecl->field_end(); I != E; ++I) { 1510224145Sdim const FieldDecl *field = *I; 1511224145Sdim QualType type = field->getType(); 1512224145Sdim QualType::DestructionKind dtorKind = type.isDestructedType(); 1513224145Sdim if (!dtorKind) continue; 1514212904Sdim 1515234353Sdim // Anonymous union members do not have their destructors called. 1516234353Sdim const RecordType *RT = type->getAsUnionType(); 1517234353Sdim if (RT && RT->getDecl()->isAnonymousStructOrUnion()) continue; 1518234353Sdim 1519224145Sdim CleanupKind cleanupKind = getCleanupKind(dtorKind); 1520224145Sdim EHStack.pushCleanup<DestroyField>(cleanupKind, field, 1521224145Sdim getDestroyer(dtorKind), 1522224145Sdim cleanupKind & EHCleanup); 1523201361Srdivacky } 1524201361Srdivacky} 1525201361Srdivacky 1526224145Sdim/// EmitCXXAggrConstructorCall - Emit a loop to call a particular 1527224145Sdim/// constructor for each of several members of an array. 1528212904Sdim/// 1529224145Sdim/// \param ctor the constructor to call for each element 1530224145Sdim/// \param arrayType the type of the array to initialize 1531224145Sdim/// \param arrayBegin an arrayType* 1532224145Sdim/// \param zeroInitialize true if each element should be 1533224145Sdim/// zero-initialized before it is constructed 1534202379Srdivackyvoid 1535224145SdimCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, 1536224145Sdim const ConstantArrayType *arrayType, 1537224145Sdim llvm::Value *arrayBegin, 1538224145Sdim CallExpr::const_arg_iterator argBegin, 1539224145Sdim CallExpr::const_arg_iterator argEnd, 1540224145Sdim bool zeroInitialize) { 1541224145Sdim QualType elementType; 1542224145Sdim llvm::Value *numElements = 1543224145Sdim emitArrayLength(arrayType, elementType, arrayBegin); 1544202379Srdivacky 1545224145Sdim EmitCXXAggrConstructorCall(ctor, numElements, arrayBegin, 1546224145Sdim argBegin, argEnd, zeroInitialize); 1547202379Srdivacky} 1548202379Srdivacky 1549224145Sdim/// EmitCXXAggrConstructorCall - Emit a loop to call a particular 1550224145Sdim/// constructor for each of several members of an array. 1551224145Sdim/// 1552224145Sdim/// \param ctor the constructor to call for each element 1553224145Sdim/// \param numElements the number of elements in the array; 1554224145Sdim/// may be zero 1555224145Sdim/// \param arrayBegin a T*, where T is the type constructed by ctor 1556224145Sdim/// \param zeroInitialize true if each element should be 1557224145Sdim/// zero-initialized before it is constructed 1558202379Srdivackyvoid 1559224145SdimCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, 1560224145Sdim llvm::Value *numElements, 1561224145Sdim llvm::Value *arrayBegin, 1562224145Sdim CallExpr::const_arg_iterator argBegin, 1563224145Sdim CallExpr::const_arg_iterator argEnd, 1564224145Sdim bool zeroInitialize) { 1565202379Srdivacky 1566224145Sdim // It's legal for numElements to be zero. This can happen both 1567224145Sdim // dynamically, because x can be zero in 'new A[x]', and statically, 1568224145Sdim // because of GCC extensions that permit zero-length arrays. There 1569224145Sdim // are probably legitimate places where we could assume that this 1570224145Sdim // doesn't happen, but it's not clear that it's worth it. 1571224145Sdim llvm::BranchInst *zeroCheckBranch = 0; 1572202379Srdivacky 1573224145Sdim // Optimize for a constant count. 1574224145Sdim llvm::ConstantInt *constantCount 1575224145Sdim = dyn_cast<llvm::ConstantInt>(numElements); 1576224145Sdim if (constantCount) { 1577224145Sdim // Just skip out if the constant count is zero. 1578224145Sdim if (constantCount->isZero()) return; 1579202379Srdivacky 1580224145Sdim // Otherwise, emit the check. 1581224145Sdim } else { 1582224145Sdim llvm::BasicBlock *loopBB = createBasicBlock("new.ctorloop"); 1583224145Sdim llvm::Value *iszero = Builder.CreateIsNull(numElements, "isempty"); 1584224145Sdim zeroCheckBranch = Builder.CreateCondBr(iszero, loopBB, loopBB); 1585224145Sdim EmitBlock(loopBB); 1586224145Sdim } 1587224145Sdim 1588224145Sdim // Find the end of the array. 1589224145Sdim llvm::Value *arrayEnd = Builder.CreateInBoundsGEP(arrayBegin, numElements, 1590224145Sdim "arrayctor.end"); 1591202379Srdivacky 1592224145Sdim // Enter the loop, setting up a phi for the current location to initialize. 1593224145Sdim llvm::BasicBlock *entryBB = Builder.GetInsertBlock(); 1594224145Sdim llvm::BasicBlock *loopBB = createBasicBlock("arrayctor.loop"); 1595224145Sdim EmitBlock(loopBB); 1596224145Sdim llvm::PHINode *cur = Builder.CreatePHI(arrayBegin->getType(), 2, 1597224145Sdim "arrayctor.cur"); 1598224145Sdim cur->addIncoming(arrayBegin, entryBB); 1599202379Srdivacky 1600224145Sdim // Inside the loop body, emit the constructor call on the array element. 1601202379Srdivacky 1602224145Sdim QualType type = getContext().getTypeDeclType(ctor->getParent()); 1603202379Srdivacky 1604212904Sdim // Zero initialize the storage, if requested. 1605224145Sdim if (zeroInitialize) 1606224145Sdim EmitNullInitialization(cur, type); 1607212904Sdim 1608202379Srdivacky // C++ [class.temporary]p4: 1609202379Srdivacky // There are two contexts in which temporaries are destroyed at a different 1610202379Srdivacky // point than the end of the full-expression. The first context is when a 1611202379Srdivacky // default constructor is called to initialize an element of an array. 1612202379Srdivacky // If the constructor has one or more default arguments, the destruction of 1613202379Srdivacky // every temporary created in a default argument expression is sequenced 1614202379Srdivacky // before the construction of the next array element, if any. 1615202379Srdivacky 1616206084Srdivacky { 1617210299Sed RunCleanupsScope Scope(*this); 1618202379Srdivacky 1619224145Sdim // Evaluate the constructor and its arguments in a regular 1620224145Sdim // partial-destroy cleanup. 1621234353Sdim if (getLangOpts().Exceptions && 1622224145Sdim !ctor->getParent()->hasTrivialDestructor()) { 1623224145Sdim Destroyer *destroyer = destroyCXXObject; 1624224145Sdim pushRegularPartialArrayCleanup(arrayBegin, cur, type, *destroyer); 1625224145Sdim } 1626224145Sdim 1627224145Sdim EmitCXXConstructorCall(ctor, Ctor_Complete, /*ForVirtualBase=*/ false, 1628249423Sdim /*Delegating=*/false, cur, argBegin, argEnd); 1629206084Srdivacky } 1630202379Srdivacky 1631224145Sdim // Go to the next element. 1632224145Sdim llvm::Value *next = 1633224145Sdim Builder.CreateInBoundsGEP(cur, llvm::ConstantInt::get(SizeTy, 1), 1634224145Sdim "arrayctor.next"); 1635224145Sdim cur->addIncoming(next, Builder.GetInsertBlock()); 1636202379Srdivacky 1637224145Sdim // Check whether that's the end of the loop. 1638224145Sdim llvm::Value *done = Builder.CreateICmpEQ(next, arrayEnd, "arrayctor.done"); 1639224145Sdim llvm::BasicBlock *contBB = createBasicBlock("arrayctor.cont"); 1640224145Sdim Builder.CreateCondBr(done, contBB, loopBB); 1641202379Srdivacky 1642224145Sdim // Patch the earlier check to skip over the loop. 1643224145Sdim if (zeroCheckBranch) zeroCheckBranch->setSuccessor(0, contBB); 1644202379Srdivacky 1645224145Sdim EmitBlock(contBB); 1646202379Srdivacky} 1647202379Srdivacky 1648224145Sdimvoid CodeGenFunction::destroyCXXObject(CodeGenFunction &CGF, 1649224145Sdim llvm::Value *addr, 1650224145Sdim QualType type) { 1651224145Sdim const RecordType *rtype = type->castAs<RecordType>(); 1652224145Sdim const CXXRecordDecl *record = cast<CXXRecordDecl>(rtype->getDecl()); 1653224145Sdim const CXXDestructorDecl *dtor = record->getDestructor(); 1654224145Sdim assert(!dtor->isTrivial()); 1655224145Sdim CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*for vbase*/ false, 1656249423Sdim /*Delegating=*/false, addr); 1657202379Srdivacky} 1658202379Srdivacky 1659202379Srdivackyvoid 1660202379SrdivackyCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 1661207619Srdivacky CXXCtorType Type, bool ForVirtualBase, 1662249423Sdim bool Delegating, 1663202379Srdivacky llvm::Value *This, 1664202379Srdivacky CallExpr::const_arg_iterator ArgBeg, 1665202379Srdivacky CallExpr::const_arg_iterator ArgEnd) { 1666249423Sdim // If this is a trivial constructor, just emit what's needed. 1667203955Srdivacky if (D->isTrivial()) { 1668203955Srdivacky if (ArgBeg == ArgEnd) { 1669203955Srdivacky // Trivial default constructor, no codegen required. 1670203955Srdivacky assert(D->isDefaultConstructor() && 1671203955Srdivacky "trivial 0-arg ctor not a default ctor"); 1672202379Srdivacky return; 1673202379Srdivacky } 1674203955Srdivacky 1675203955Srdivacky assert(ArgBeg + 1 == ArgEnd && "unexpected argcount for trivial ctor"); 1676226633Sdim assert(D->isCopyOrMoveConstructor() && 1677226633Sdim "trivial 1-arg ctor not a copy/move ctor"); 1678203955Srdivacky 1679203955Srdivacky const Expr *E = (*ArgBeg); 1680203955Srdivacky QualType Ty = E->getType(); 1681203955Srdivacky llvm::Value *Src = EmitLValue(E).getAddress(); 1682203955Srdivacky EmitAggregateCopy(This, Src, Ty); 1683202379Srdivacky return; 1684202379Srdivacky } 1685202379Srdivacky 1686249423Sdim // Non-trivial constructors are handled in an ABI-specific manner. 1687263508Sdim CGM.getCXXABI().EmitConstructorCall(*this, D, Type, ForVirtualBase, 1688263508Sdim Delegating, This, ArgBeg, ArgEnd); 1689202379Srdivacky} 1690202379Srdivacky 1691204643Srdivackyvoid 1692218893SdimCodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, 1693218893Sdim llvm::Value *This, llvm::Value *Src, 1694218893Sdim CallExpr::const_arg_iterator ArgBeg, 1695218893Sdim CallExpr::const_arg_iterator ArgEnd) { 1696218893Sdim if (D->isTrivial()) { 1697218893Sdim assert(ArgBeg + 1 == ArgEnd && "unexpected argcount for trivial ctor"); 1698226633Sdim assert(D->isCopyOrMoveConstructor() && 1699226633Sdim "trivial 1-arg ctor not a copy/move ctor"); 1700218893Sdim EmitAggregateCopy(This, Src, (*ArgBeg)->getType()); 1701218893Sdim return; 1702218893Sdim } 1703263508Sdim llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, clang::Ctor_Complete); 1704218893Sdim assert(D->isInstance() && 1705218893Sdim "Trying to emit a member call expr on a static method!"); 1706218893Sdim 1707218893Sdim const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>(); 1708218893Sdim 1709218893Sdim CallArgList Args; 1710218893Sdim 1711218893Sdim // Push the this ptr. 1712221345Sdim Args.add(RValue::get(This), D->getThisType(getContext())); 1713218893Sdim 1714218893Sdim 1715218893Sdim // Push the src ptr. 1716218893Sdim QualType QT = *(FPT->arg_type_begin()); 1717226633Sdim llvm::Type *t = CGM.getTypes().ConvertType(QT); 1718218893Sdim Src = Builder.CreateBitCast(Src, t); 1719221345Sdim Args.add(RValue::get(Src), QT); 1720218893Sdim 1721218893Sdim // Skip over first argument (Src). 1722218893Sdim ++ArgBeg; 1723218893Sdim CallExpr::const_arg_iterator Arg = ArgBeg; 1724218893Sdim for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin()+1, 1725218893Sdim E = FPT->arg_type_end(); I != E; ++I, ++Arg) { 1726218893Sdim assert(Arg != ArgEnd && "Running over edge of argument list!"); 1727221345Sdim EmitCallArg(Args, *Arg, *I); 1728218893Sdim } 1729218893Sdim // Either we've emitted all the call args, or we have a call to a 1730218893Sdim // variadic function. 1731218893Sdim assert((Arg == ArgEnd || FPT->isVariadic()) && 1732218893Sdim "Extra arguments in non-variadic function!"); 1733218893Sdim // If we still have any arguments, emit them using the type of the argument. 1734218893Sdim for (; Arg != ArgEnd; ++Arg) { 1735218893Sdim QualType ArgType = Arg->getType(); 1736221345Sdim EmitCallArg(Args, *Arg, ArgType); 1737218893Sdim } 1738218893Sdim 1739239462Sdim EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, RequiredArgs::All), 1740239462Sdim Callee, ReturnValueSlot(), Args, D); 1741218893Sdim} 1742218893Sdim 1743218893Sdimvoid 1744204643SrdivackyCodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, 1745204643Srdivacky CXXCtorType CtorType, 1746263508Sdim const FunctionArgList &Args, 1747263508Sdim SourceLocation Loc) { 1748204643Srdivacky CallArgList DelegateArgs; 1749204643Srdivacky 1750204643Srdivacky FunctionArgList::const_iterator I = Args.begin(), E = Args.end(); 1751204643Srdivacky assert(I != E && "no parameters to constructor"); 1752204643Srdivacky 1753204643Srdivacky // this 1754221345Sdim DelegateArgs.add(RValue::get(LoadCXXThis()), (*I)->getType()); 1755204643Srdivacky ++I; 1756204643Srdivacky 1757204643Srdivacky // vtt 1758249423Sdim if (llvm::Value *VTT = GetVTTParameter(GlobalDecl(Ctor, CtorType), 1759249423Sdim /*ForVirtualBase=*/false, 1760249423Sdim /*Delegating=*/true)) { 1761204643Srdivacky QualType VoidPP = getContext().getPointerType(getContext().VoidPtrTy); 1762221345Sdim DelegateArgs.add(RValue::get(VTT), VoidPP); 1763204643Srdivacky 1764263508Sdim if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) { 1765204643Srdivacky assert(I != E && "cannot skip vtt parameter, already done with args"); 1766221345Sdim assert((*I)->getType() == VoidPP && "skipping parameter not of vtt type"); 1767204643Srdivacky ++I; 1768204643Srdivacky } 1769204643Srdivacky } 1770204643Srdivacky 1771204643Srdivacky // Explicit arguments. 1772204643Srdivacky for (; I != E; ++I) { 1773221345Sdim const VarDecl *param = *I; 1774263508Sdim // FIXME: per-argument source location 1775263508Sdim EmitDelegateCallArg(DelegateArgs, param, Loc); 1776204643Srdivacky } 1777204643Srdivacky 1778249423Sdim llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(Ctor, CtorType); 1779234353Sdim EmitCall(CGM.getTypes().arrangeCXXConstructorDeclaration(Ctor, CtorType), 1780249423Sdim Callee, ReturnValueSlot(), DelegateArgs, Ctor); 1781204643Srdivacky} 1782204643Srdivacky 1783223017Sdimnamespace { 1784223017Sdim struct CallDelegatingCtorDtor : EHScopeStack::Cleanup { 1785223017Sdim const CXXDestructorDecl *Dtor; 1786223017Sdim llvm::Value *Addr; 1787223017Sdim CXXDtorType Type; 1788223017Sdim 1789223017Sdim CallDelegatingCtorDtor(const CXXDestructorDecl *D, llvm::Value *Addr, 1790223017Sdim CXXDtorType Type) 1791223017Sdim : Dtor(D), Addr(Addr), Type(Type) {} 1792223017Sdim 1793224145Sdim void Emit(CodeGenFunction &CGF, Flags flags) { 1794223017Sdim CGF.EmitCXXDestructorCall(Dtor, Type, /*ForVirtualBase=*/false, 1795249423Sdim /*Delegating=*/true, Addr); 1796223017Sdim } 1797223017Sdim }; 1798223017Sdim} 1799223017Sdim 1800221345Sdimvoid 1801221345SdimCodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor, 1802221345Sdim const FunctionArgList &Args) { 1803221345Sdim assert(Ctor->isDelegatingConstructor()); 1804221345Sdim 1805221345Sdim llvm::Value *ThisPtr = LoadCXXThis(); 1806221345Sdim 1807234353Sdim QualType Ty = getContext().getTagDeclType(Ctor->getParent()); 1808234353Sdim CharUnits Alignment = getContext().getTypeAlignInChars(Ty); 1809224145Sdim AggValueSlot AggSlot = 1810234353Sdim AggValueSlot::forAddr(ThisPtr, Alignment, Qualifiers(), 1811226633Sdim AggValueSlot::IsDestructed, 1812226633Sdim AggValueSlot::DoesNotNeedGCBarriers, 1813226633Sdim AggValueSlot::IsNotAliased); 1814221345Sdim 1815221345Sdim EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot); 1816223017Sdim 1817223017Sdim const CXXRecordDecl *ClassDecl = Ctor->getParent(); 1818234353Sdim if (CGM.getLangOpts().Exceptions && !ClassDecl->hasTrivialDestructor()) { 1819223017Sdim CXXDtorType Type = 1820223017Sdim CurGD.getCtorType() == Ctor_Complete ? Dtor_Complete : Dtor_Base; 1821223017Sdim 1822223017Sdim EHStack.pushCleanup<CallDelegatingCtorDtor>(EHCleanup, 1823223017Sdim ClassDecl->getDestructor(), 1824223017Sdim ThisPtr, Type); 1825223017Sdim } 1826221345Sdim} 1827221345Sdim 1828202379Srdivackyvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD, 1829202379Srdivacky CXXDtorType Type, 1830207619Srdivacky bool ForVirtualBase, 1831249423Sdim bool Delegating, 1832202379Srdivacky llvm::Value *This) { 1833263508Sdim GlobalDecl GD(DD, Type); 1834263508Sdim llvm::Value *VTT = GetVTTParameter(GD, ForVirtualBase, Delegating); 1835218893Sdim llvm::Value *Callee = 0; 1836243830Sdim if (getLangOpts().AppleKext) 1837218893Sdim Callee = BuildAppleKextVirtualDestructorCall(DD, Type, 1838218893Sdim DD->getParent()); 1839218893Sdim 1840218893Sdim if (!Callee) 1841218893Sdim Callee = CGM.GetAddrOfCXXDestructor(DD, Type); 1842263508Sdim 1843263508Sdim if (DD->isVirtual()) 1844263508Sdim This = CGM.getCXXABI().adjustThisArgumentForVirtualCall(*this, GD, This); 1845263508Sdim 1846243830Sdim // FIXME: Provide a source location here. 1847243830Sdim EmitCXXMemberCall(DD, SourceLocation(), Callee, ReturnValueSlot(), This, 1848249423Sdim VTT, getContext().getPointerType(getContext().VoidPtrTy), 1849249423Sdim 0, 0); 1850202379Srdivacky} 1851202379Srdivacky 1852212904Sdimnamespace { 1853212904Sdim struct CallLocalDtor : EHScopeStack::Cleanup { 1854212904Sdim const CXXDestructorDecl *Dtor; 1855212904Sdim llvm::Value *Addr; 1856212904Sdim 1857212904Sdim CallLocalDtor(const CXXDestructorDecl *D, llvm::Value *Addr) 1858212904Sdim : Dtor(D), Addr(Addr) {} 1859212904Sdim 1860224145Sdim void Emit(CodeGenFunction &CGF, Flags flags) { 1861212904Sdim CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, 1862249423Sdim /*ForVirtualBase=*/false, 1863249423Sdim /*Delegating=*/false, Addr); 1864212904Sdim } 1865212904Sdim }; 1866212904Sdim} 1867212904Sdim 1868212904Sdimvoid CodeGenFunction::PushDestructorCleanup(const CXXDestructorDecl *D, 1869212904Sdim llvm::Value *Addr) { 1870212904Sdim EHStack.pushCleanup<CallLocalDtor>(NormalAndEHCleanup, D, Addr); 1871212904Sdim} 1872212904Sdim 1873210299Sedvoid CodeGenFunction::PushDestructorCleanup(QualType T, llvm::Value *Addr) { 1874210299Sed CXXRecordDecl *ClassDecl = T->getAsCXXRecordDecl(); 1875210299Sed if (!ClassDecl) return; 1876210299Sed if (ClassDecl->hasTrivialDestructor()) return; 1877210299Sed 1878210299Sed const CXXDestructorDecl *D = ClassDecl->getDestructor(); 1879221345Sdim assert(D && D->isUsed() && "destructor not marked as used!"); 1880212904Sdim PushDestructorCleanup(D, Addr); 1881210299Sed} 1882210299Sed 1883206084Srdivackyvoid 1884206084SrdivackyCodeGenFunction::InitializeVTablePointer(BaseSubobject Base, 1885207619Srdivacky const CXXRecordDecl *NearestVBase, 1886221345Sdim CharUnits OffsetFromNearestVBase, 1887206084Srdivacky const CXXRecordDecl *VTableClass) { 1888206084Srdivacky // Compute the address point. 1889263508Sdim bool NeedsVirtualOffset; 1890263508Sdim llvm::Value *VTableAddressPoint = 1891263508Sdim CGM.getCXXABI().getVTableAddressPointInStructor( 1892263508Sdim *this, VTableClass, Base, NearestVBase, NeedsVirtualOffset); 1893263508Sdim if (!VTableAddressPoint) 1894263508Sdim return; 1895202379Srdivacky 1896206084Srdivacky // Compute where to store the address point. 1897207619Srdivacky llvm::Value *VirtualOffset = 0; 1898221345Sdim CharUnits NonVirtualOffset = CharUnits::Zero(); 1899206084Srdivacky 1900263508Sdim if (NeedsVirtualOffset) { 1901206084Srdivacky // We need to use the virtual base offset offset because the virtual base 1902206084Srdivacky // might have a different offset in the most derived class. 1903263508Sdim VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset(*this, 1904263508Sdim LoadCXXThis(), 1905263508Sdim VTableClass, 1906263508Sdim NearestVBase); 1907221345Sdim NonVirtualOffset = OffsetFromNearestVBase; 1908206084Srdivacky } else { 1909207619Srdivacky // We can just use the base offset in the complete class. 1910221345Sdim NonVirtualOffset = Base.getBaseOffset(); 1911206084Srdivacky } 1912207619Srdivacky 1913207619Srdivacky // Apply the offsets. 1914207619Srdivacky llvm::Value *VTableField = LoadCXXThis(); 1915207619Srdivacky 1916221345Sdim if (!NonVirtualOffset.isZero() || VirtualOffset) 1917207619Srdivacky VTableField = ApplyNonVirtualAndVirtualOffset(*this, VTableField, 1918207619Srdivacky NonVirtualOffset, 1919207619Srdivacky VirtualOffset); 1920206084Srdivacky 1921206084Srdivacky // Finally, store the address point. 1922226633Sdim llvm::Type *AddressPointPtrTy = 1923206084Srdivacky VTableAddressPoint->getType()->getPointerTo(); 1924206084Srdivacky VTableField = Builder.CreateBitCast(VTableField, AddressPointPtrTy); 1925234353Sdim llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint, VTableField); 1926234353Sdim CGM.DecorateInstruction(Store, CGM.getTBAAInfoForVTablePtr()); 1927202379Srdivacky} 1928202379Srdivacky 1929206084Srdivackyvoid 1930206084SrdivackyCodeGenFunction::InitializeVTablePointers(BaseSubobject Base, 1931207619Srdivacky const CXXRecordDecl *NearestVBase, 1932221345Sdim CharUnits OffsetFromNearestVBase, 1933206084Srdivacky bool BaseIsNonVirtualPrimaryBase, 1934206084Srdivacky const CXXRecordDecl *VTableClass, 1935206084Srdivacky VisitedVirtualBasesSetTy& VBases) { 1936206084Srdivacky // If this base is a non-virtual primary base the address point has already 1937206084Srdivacky // been set. 1938206084Srdivacky if (!BaseIsNonVirtualPrimaryBase) { 1939206084Srdivacky // Initialize the vtable pointer for this base. 1940207619Srdivacky InitializeVTablePointer(Base, NearestVBase, OffsetFromNearestVBase, 1941263508Sdim VTableClass); 1942206084Srdivacky } 1943206084Srdivacky 1944206084Srdivacky const CXXRecordDecl *RD = Base.getBase(); 1945202379Srdivacky 1946206084Srdivacky // Traverse bases. 1947206084Srdivacky for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1948206084Srdivacky E = RD->bases_end(); I != E; ++I) { 1949206084Srdivacky CXXRecordDecl *BaseDecl 1950206084Srdivacky = cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1951206084Srdivacky 1952206084Srdivacky // Ignore classes without a vtable. 1953206084Srdivacky if (!BaseDecl->isDynamicClass()) 1954202379Srdivacky continue; 1955206084Srdivacky 1956221345Sdim CharUnits BaseOffset; 1957221345Sdim CharUnits BaseOffsetFromNearestVBase; 1958206084Srdivacky bool BaseDeclIsNonVirtualPrimaryBase; 1959206084Srdivacky 1960206084Srdivacky if (I->isVirtual()) { 1961206084Srdivacky // Check if we've visited this virtual base before. 1962206084Srdivacky if (!VBases.insert(BaseDecl)) 1963206084Srdivacky continue; 1964206084Srdivacky 1965206084Srdivacky const ASTRecordLayout &Layout = 1966206084Srdivacky getContext().getASTRecordLayout(VTableClass); 1967206084Srdivacky 1968221345Sdim BaseOffset = Layout.getVBaseClassOffset(BaseDecl); 1969221345Sdim BaseOffsetFromNearestVBase = CharUnits::Zero(); 1970206084Srdivacky BaseDeclIsNonVirtualPrimaryBase = false; 1971206084Srdivacky } else { 1972206084Srdivacky const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 1973206084Srdivacky 1974221345Sdim BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl); 1975207619Srdivacky BaseOffsetFromNearestVBase = 1976221345Sdim OffsetFromNearestVBase + Layout.getBaseClassOffset(BaseDecl); 1977206084Srdivacky BaseDeclIsNonVirtualPrimaryBase = Layout.getPrimaryBase() == BaseDecl; 1978206084Srdivacky } 1979206084Srdivacky 1980206084Srdivacky InitializeVTablePointers(BaseSubobject(BaseDecl, BaseOffset), 1981207619Srdivacky I->isVirtual() ? BaseDecl : NearestVBase, 1982207619Srdivacky BaseOffsetFromNearestVBase, 1983206084Srdivacky BaseDeclIsNonVirtualPrimaryBase, 1984263508Sdim VTableClass, VBases); 1985202379Srdivacky } 1986206084Srdivacky} 1987202379Srdivacky 1988206084Srdivackyvoid CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) { 1989206084Srdivacky // Ignore classes without a vtable. 1990206084Srdivacky if (!RD->isDynamicClass()) 1991206084Srdivacky return; 1992202379Srdivacky 1993206084Srdivacky // Initialize the vtable pointers for this class and all of its bases. 1994206084Srdivacky VisitedVirtualBasesSetTy VBases; 1995221345Sdim InitializeVTablePointers(BaseSubobject(RD, CharUnits::Zero()), 1996221345Sdim /*NearestVBase=*/0, 1997221345Sdim /*OffsetFromNearestVBase=*/CharUnits::Zero(), 1998263508Sdim /*BaseIsNonVirtualPrimaryBase=*/false, RD, VBases); 1999263508Sdim 2000263508Sdim if (RD->getNumVBases()) 2001263508Sdim CGM.getCXXABI().initializeHiddenVirtualInheritanceMembers(*this, RD); 2002202379Srdivacky} 2003218893Sdim 2004218893Sdimllvm::Value *CodeGenFunction::GetVTablePtr(llvm::Value *This, 2005226633Sdim llvm::Type *Ty) { 2006218893Sdim llvm::Value *VTablePtrSrc = Builder.CreateBitCast(This, Ty->getPointerTo()); 2007234353Sdim llvm::Instruction *VTable = Builder.CreateLoad(VTablePtrSrc, "vtable"); 2008234353Sdim CGM.DecorateInstruction(VTable, CGM.getTBAAInfoForVTablePtr()); 2009234353Sdim return VTable; 2010218893Sdim} 2011223017Sdim 2012223017Sdim 2013223017Sdim// FIXME: Ideally Expr::IgnoreParenNoopCasts should do this, but it doesn't do 2014223017Sdim// quite what we want. 2015223017Sdimstatic const Expr *skipNoOpCastsAndParens(const Expr *E) { 2016223017Sdim while (true) { 2017223017Sdim if (const ParenExpr *PE = dyn_cast<ParenExpr>(E)) { 2018223017Sdim E = PE->getSubExpr(); 2019223017Sdim continue; 2020223017Sdim } 2021223017Sdim 2022223017Sdim if (const CastExpr *CE = dyn_cast<CastExpr>(E)) { 2023223017Sdim if (CE->getCastKind() == CK_NoOp) { 2024223017Sdim E = CE->getSubExpr(); 2025223017Sdim continue; 2026223017Sdim } 2027223017Sdim } 2028223017Sdim if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) { 2029223017Sdim if (UO->getOpcode() == UO_Extension) { 2030223017Sdim E = UO->getSubExpr(); 2031223017Sdim continue; 2032223017Sdim } 2033223017Sdim } 2034223017Sdim return E; 2035223017Sdim } 2036223017Sdim} 2037223017Sdim 2038263508Sdimbool 2039263508SdimCodeGenFunction::CanDevirtualizeMemberFunctionCall(const Expr *Base, 2040263508Sdim const CXXMethodDecl *MD) { 2041263508Sdim // When building with -fapple-kext, all calls must go through the vtable since 2042263508Sdim // the kernel linker can do runtime patching of vtables. 2043263508Sdim if (getLangOpts().AppleKext) 2044263508Sdim return false; 2045263508Sdim 2046223017Sdim // If the most derived class is marked final, we know that no subclass can 2047223017Sdim // override this member function and so we can devirtualize it. For example: 2048223017Sdim // 2049223017Sdim // struct A { virtual void f(); } 2050223017Sdim // struct B final : A { }; 2051223017Sdim // 2052223017Sdim // void f(B *b) { 2053223017Sdim // b->f(); 2054223017Sdim // } 2055223017Sdim // 2056263508Sdim const CXXRecordDecl *MostDerivedClassDecl = Base->getBestDynamicClassType(); 2057223017Sdim if (MostDerivedClassDecl->hasAttr<FinalAttr>()) 2058223017Sdim return true; 2059223017Sdim 2060223017Sdim // If the member function is marked 'final', we know that it can't be 2061223017Sdim // overridden and can therefore devirtualize it. 2062223017Sdim if (MD->hasAttr<FinalAttr>()) 2063223017Sdim return true; 2064223017Sdim 2065223017Sdim // Similarly, if the class itself is marked 'final' it can't be overridden 2066223017Sdim // and we can therefore devirtualize the member function call. 2067223017Sdim if (MD->getParent()->hasAttr<FinalAttr>()) 2068223017Sdim return true; 2069223017Sdim 2070223017Sdim Base = skipNoOpCastsAndParens(Base); 2071223017Sdim if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Base)) { 2072223017Sdim if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) { 2073223017Sdim // This is a record decl. We know the type and can devirtualize it. 2074223017Sdim return VD->getType()->isRecordType(); 2075223017Sdim } 2076223017Sdim 2077223017Sdim return false; 2078223017Sdim } 2079263508Sdim 2080263508Sdim // We can devirtualize calls on an object accessed by a class member access 2081263508Sdim // expression, since by C++11 [basic.life]p6 we know that it can't refer to 2082263508Sdim // a derived class object constructed in the same location. 2083263508Sdim if (const MemberExpr *ME = dyn_cast<MemberExpr>(Base)) 2084263508Sdim if (const ValueDecl *VD = dyn_cast<ValueDecl>(ME->getMemberDecl())) 2085263508Sdim return VD->getType()->isRecordType(); 2086263508Sdim 2087223017Sdim // We can always devirtualize calls on temporary object expressions. 2088223017Sdim if (isa<CXXConstructExpr>(Base)) 2089223017Sdim return true; 2090223017Sdim 2091223017Sdim // And calls on bound temporaries. 2092223017Sdim if (isa<CXXBindTemporaryExpr>(Base)) 2093223017Sdim return true; 2094223017Sdim 2095223017Sdim // Check if this is a call expr that returns a record type. 2096223017Sdim if (const CallExpr *CE = dyn_cast<CallExpr>(Base)) 2097223017Sdim return CE->getCallReturnType()->isRecordType(); 2098223017Sdim 2099223017Sdim // We can't devirtualize the call. 2100223017Sdim return false; 2101223017Sdim} 2102223017Sdim 2103223017Sdimllvm::Value * 2104223017SdimCodeGenFunction::EmitCXXOperatorMemberCallee(const CXXOperatorCallExpr *E, 2105223017Sdim const CXXMethodDecl *MD, 2106223017Sdim llvm::Value *This) { 2107234353Sdim llvm::FunctionType *fnType = 2108234353Sdim CGM.getTypes().GetFunctionType( 2109234353Sdim CGM.getTypes().arrangeCXXMethodDeclaration(MD)); 2110223017Sdim 2111263508Sdim if (MD->isVirtual() && !CanDevirtualizeMemberFunctionCall(E->getArg(0), MD)) 2112263508Sdim return CGM.getCXXABI().getVirtualFunctionPointer(*this, MD, This, fnType); 2113223017Sdim 2114234353Sdim return CGM.GetAddrOfFunction(MD, fnType); 2115223017Sdim} 2116234353Sdim 2117263508Sdimvoid CodeGenFunction::EmitForwardingCallToLambda( 2118263508Sdim const CXXMethodDecl *callOperator, 2119263508Sdim CallArgList &callArgs) { 2120234353Sdim // Get the address of the call operator. 2121239462Sdim const CGFunctionInfo &calleeFnInfo = 2122239462Sdim CGM.getTypes().arrangeCXXMethodDeclaration(callOperator); 2123239462Sdim llvm::Value *callee = 2124239462Sdim CGM.GetAddrOfFunction(GlobalDecl(callOperator), 2125239462Sdim CGM.getTypes().GetFunctionType(calleeFnInfo)); 2126234353Sdim 2127239462Sdim // Prepare the return slot. 2128239462Sdim const FunctionProtoType *FPT = 2129239462Sdim callOperator->getType()->castAs<FunctionProtoType>(); 2130239462Sdim QualType resultType = FPT->getResultType(); 2131239462Sdim ReturnValueSlot returnSlot; 2132239462Sdim if (!resultType->isVoidType() && 2133239462Sdim calleeFnInfo.getReturnInfo().getKind() == ABIArgInfo::Indirect && 2134249423Sdim !hasScalarEvaluationKind(calleeFnInfo.getReturnType())) 2135239462Sdim returnSlot = ReturnValueSlot(ReturnValue, resultType.isVolatileQualified()); 2136239462Sdim 2137239462Sdim // We don't need to separately arrange the call arguments because 2138239462Sdim // the call can't be variadic anyway --- it's impossible to forward 2139239462Sdim // variadic arguments. 2140234353Sdim 2141234353Sdim // Now emit our call. 2142239462Sdim RValue RV = EmitCall(calleeFnInfo, callee, returnSlot, 2143239462Sdim callArgs, callOperator); 2144234353Sdim 2145239462Sdim // If necessary, copy the returned value into the slot. 2146239462Sdim if (!resultType->isVoidType() && returnSlot.isNull()) 2147239462Sdim EmitReturnOfRValue(RV, resultType); 2148249423Sdim else 2149249423Sdim EmitBranchThroughCleanup(ReturnBlock); 2150234353Sdim} 2151234353Sdim 2152234353Sdimvoid CodeGenFunction::EmitLambdaBlockInvokeBody() { 2153234353Sdim const BlockDecl *BD = BlockInfo->getBlockDecl(); 2154234353Sdim const VarDecl *variable = BD->capture_begin()->getVariable(); 2155234353Sdim const CXXRecordDecl *Lambda = variable->getType()->getAsCXXRecordDecl(); 2156234353Sdim 2157234353Sdim // Start building arguments for forwarding call 2158234353Sdim CallArgList CallArgs; 2159234353Sdim 2160234353Sdim QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda)); 2161234353Sdim llvm::Value *ThisPtr = GetAddrOfBlockDecl(variable, false); 2162234353Sdim CallArgs.add(RValue::get(ThisPtr), ThisType); 2163234353Sdim 2164234353Sdim // Add the rest of the parameters. 2165234353Sdim for (BlockDecl::param_const_iterator I = BD->param_begin(), 2166234353Sdim E = BD->param_end(); I != E; ++I) { 2167234353Sdim ParmVarDecl *param = *I; 2168263508Sdim EmitDelegateCallArg(CallArgs, param, param->getLocStart()); 2169234353Sdim } 2170263508Sdim assert(!Lambda->isGenericLambda() && 2171263508Sdim "generic lambda interconversion to block not implemented"); 2172263508Sdim EmitForwardingCallToLambda(Lambda->getLambdaCallOperator(), CallArgs); 2173234353Sdim} 2174234353Sdim 2175234353Sdimvoid CodeGenFunction::EmitLambdaToBlockPointerBody(FunctionArgList &Args) { 2176251662Sdim if (cast<CXXMethodDecl>(CurCodeDecl)->isVariadic()) { 2177234353Sdim // FIXME: Making this work correctly is nasty because it requires either 2178234353Sdim // cloning the body of the call operator or making the call operator forward. 2179251662Sdim CGM.ErrorUnsupported(CurCodeDecl, "lambda conversion to variadic function"); 2180234353Sdim return; 2181234353Sdim } 2182234353Sdim 2183263508Sdim EmitFunctionBody(Args, cast<FunctionDecl>(CurGD.getDecl())->getBody()); 2184234353Sdim} 2185234353Sdim 2186234353Sdimvoid CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) { 2187234353Sdim const CXXRecordDecl *Lambda = MD->getParent(); 2188234353Sdim 2189234353Sdim // Start building arguments for forwarding call 2190234353Sdim CallArgList CallArgs; 2191234353Sdim 2192234353Sdim QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda)); 2193234353Sdim llvm::Value *ThisPtr = llvm::UndefValue::get(getTypes().ConvertType(ThisType)); 2194234353Sdim CallArgs.add(RValue::get(ThisPtr), ThisType); 2195234353Sdim 2196234353Sdim // Add the rest of the parameters. 2197234353Sdim for (FunctionDecl::param_const_iterator I = MD->param_begin(), 2198234353Sdim E = MD->param_end(); I != E; ++I) { 2199234353Sdim ParmVarDecl *param = *I; 2200263508Sdim EmitDelegateCallArg(CallArgs, param, param->getLocStart()); 2201234353Sdim } 2202263508Sdim const CXXMethodDecl *CallOp = Lambda->getLambdaCallOperator(); 2203263508Sdim // For a generic lambda, find the corresponding call operator specialization 2204263508Sdim // to which the call to the static-invoker shall be forwarded. 2205263508Sdim if (Lambda->isGenericLambda()) { 2206263508Sdim assert(MD->isFunctionTemplateSpecialization()); 2207263508Sdim const TemplateArgumentList *TAL = MD->getTemplateSpecializationArgs(); 2208263508Sdim FunctionTemplateDecl *CallOpTemplate = CallOp->getDescribedFunctionTemplate(); 2209263508Sdim void *InsertPos = 0; 2210263508Sdim FunctionDecl *CorrespondingCallOpSpecialization = 2211263508Sdim CallOpTemplate->findSpecialization(TAL->data(), TAL->size(), InsertPos); 2212263508Sdim assert(CorrespondingCallOpSpecialization); 2213263508Sdim CallOp = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization); 2214263508Sdim } 2215263508Sdim EmitForwardingCallToLambda(CallOp, CallArgs); 2216234353Sdim} 2217234353Sdim 2218234353Sdimvoid CodeGenFunction::EmitLambdaStaticInvokeFunction(const CXXMethodDecl *MD) { 2219234353Sdim if (MD->isVariadic()) { 2220234353Sdim // FIXME: Making this work correctly is nasty because it requires either 2221234353Sdim // cloning the body of the call operator or making the call operator forward. 2222234353Sdim CGM.ErrorUnsupported(MD, "lambda conversion to variadic function"); 2223234353Sdim return; 2224234353Sdim } 2225234353Sdim 2226234353Sdim EmitLambdaDelegatingInvokeBody(MD); 2227234353Sdim} 2228