diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-01-15 15:39:40 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-01-15 15:39:40 +0000 |
commit | a3fa5c7f1b5e2ba4d6ec033dc0e2376326b05824 (patch) | |
tree | a6082d4d1d1e9ddaea09a6a04bb4a47da95d642d /lib/CodeGen/CGCXX.cpp | |
parent | bb1e3bc1e0be2b8f891db46457a8943451bf4d8b (diff) | |
download | FreeBSD-src-a3fa5c7f1b5e2ba4d6ec033dc0e2376326b05824.zip FreeBSD-src-a3fa5c7f1b5e2ba4d6ec033dc0e2376326b05824.tar.gz |
Update clang to r93512.
Diffstat (limited to 'lib/CodeGen/CGCXX.cpp')
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 671 |
1 files changed, 0 insertions, 671 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index cc006d9..4323f84 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -26,269 +26,7 @@ using namespace clang; using namespace CodeGen; -RValue CodeGenFunction::EmitCXXMemberCall(const CXXMethodDecl *MD, - llvm::Value *Callee, - ReturnValueSlot ReturnValue, - llvm::Value *This, - CallExpr::const_arg_iterator ArgBeg, - CallExpr::const_arg_iterator ArgEnd) { - assert(MD->isInstance() && - "Trying to emit a member call expr on a static method!"); - const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); - - CallArgList Args; - - // Push the this ptr. - Args.push_back(std::make_pair(RValue::get(This), - MD->getThisType(getContext()))); - - // And the rest of the call args - EmitCallArgs(Args, FPT, ArgBeg, ArgEnd); - - QualType ResultType = MD->getType()->getAs<FunctionType>()->getResultType(); - return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args), Callee, - ReturnValue, Args, MD); -} - -/// canDevirtualizeMemberFunctionCalls - Checks whether virtual calls on given -/// expr can be devirtualized. -static bool canDevirtualizeMemberFunctionCalls(const Expr *Base) { - if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Base)) { - if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) { - // This is a record decl. We know the type and can devirtualize it. - return VD->getType()->isRecordType(); - } - - return false; - } - - // We can always devirtualize calls on temporary object expressions. - if (isa<CXXTemporaryObjectExpr>(Base)) - return true; - - // And calls on bound temporaries. - if (isa<CXXBindTemporaryExpr>(Base)) - return true; - - // Check if this is a call expr that returns a record type. - if (const CallExpr *CE = dyn_cast<CallExpr>(Base)) - return CE->getCallReturnType()->isRecordType(); - - // We can't devirtualize the call. - return false; -} - -RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE, - ReturnValueSlot ReturnValue) { - if (isa<BinaryOperator>(CE->getCallee()->IgnoreParens())) - return EmitCXXMemberPointerCallExpr(CE, ReturnValue); - - const MemberExpr *ME = cast<MemberExpr>(CE->getCallee()->IgnoreParens()); - const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl()); - - if (MD->isStatic()) { - // The method is static, emit it as we would a regular call. - llvm::Value *Callee = CGM.GetAddrOfFunction(MD); - return EmitCall(getContext().getPointerType(MD->getType()), Callee, - ReturnValue, CE->arg_begin(), CE->arg_end()); - } - - const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); - - const llvm::Type *Ty = - CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), - FPT->isVariadic()); - llvm::Value *This; - - if (ME->isArrow()) - This = EmitScalarExpr(ME->getBase()); - else { - LValue BaseLV = EmitLValue(ME->getBase()); - This = BaseLV.getAddress(); - } - - if (MD->isCopyAssignment() && MD->isTrivial()) { - // We don't like to generate the trivial copy assignment operator when - // it isn't necessary; just produce the proper effect here. - llvm::Value *RHS = EmitLValue(*CE->arg_begin()).getAddress(); - EmitAggregateCopy(This, RHS, CE->getType()); - return RValue::get(This); - } - - // C++ [class.virtual]p12: - // Explicit qualification with the scope operator (5.1) suppresses the - // virtual call mechanism. - // - // We also don't emit a virtual call if the base expression has a record type - // because then we know what the type is. - llvm::Value *Callee; - if (const CXXDestructorDecl *Destructor - = dyn_cast<CXXDestructorDecl>(MD)) { - if (Destructor->isTrivial()) - return RValue::get(0); - if (MD->isVirtual() && !ME->hasQualifier() && - !canDevirtualizeMemberFunctionCalls(ME->getBase())) { - Callee = BuildVirtualCall(Destructor, Dtor_Complete, This, Ty); - } else { - Callee = CGM.GetAddrOfFunction(GlobalDecl(Destructor, Dtor_Complete), Ty); - } - } else if (MD->isVirtual() && !ME->hasQualifier() && - !canDevirtualizeMemberFunctionCalls(ME->getBase())) { - Callee = BuildVirtualCall(MD, This, Ty); - } else { - Callee = CGM.GetAddrOfFunction(MD, Ty); - } - - return EmitCXXMemberCall(MD, Callee, ReturnValue, This, - CE->arg_begin(), CE->arg_end()); -} - -RValue -CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, - ReturnValueSlot ReturnValue) { - const BinaryOperator *BO = - cast<BinaryOperator>(E->getCallee()->IgnoreParens()); - const Expr *BaseExpr = BO->getLHS(); - const Expr *MemFnExpr = BO->getRHS(); - - const MemberPointerType *MPT = - MemFnExpr->getType()->getAs<MemberPointerType>(); - const FunctionProtoType *FPT = - MPT->getPointeeType()->getAs<FunctionProtoType>(); - const CXXRecordDecl *RD = - cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl()); - - const llvm::FunctionType *FTy = - CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(RD, FPT), - FPT->isVariadic()); - - const llvm::Type *Int8PtrTy = - llvm::Type::getInt8Ty(VMContext)->getPointerTo(); - - // Get the member function pointer. - llvm::Value *MemFnPtr = - CreateTempAlloca(ConvertType(MemFnExpr->getType()), "mem.fn"); - EmitAggExpr(MemFnExpr, MemFnPtr, /*VolatileDest=*/false); - - // Emit the 'this' pointer. - llvm::Value *This; - - if (BO->getOpcode() == BinaryOperator::PtrMemI) - This = EmitScalarExpr(BaseExpr); - else - This = EmitLValue(BaseExpr).getAddress(); - - // Adjust it. - llvm::Value *Adj = Builder.CreateStructGEP(MemFnPtr, 1); - Adj = Builder.CreateLoad(Adj, "mem.fn.adj"); - - llvm::Value *Ptr = Builder.CreateBitCast(This, Int8PtrTy, "ptr"); - Ptr = Builder.CreateGEP(Ptr, Adj, "adj"); - - This = Builder.CreateBitCast(Ptr, This->getType(), "this"); - - llvm::Value *FnPtr = Builder.CreateStructGEP(MemFnPtr, 0, "mem.fn.ptr"); - - const llvm::Type *PtrDiffTy = ConvertType(getContext().getPointerDiffType()); - - llvm::Value *FnAsInt = Builder.CreateLoad(FnPtr, "fn"); - - // If the LSB in the function pointer is 1, the function pointer points to - // a virtual function. - llvm::Value *IsVirtual - = Builder.CreateAnd(FnAsInt, llvm::ConstantInt::get(PtrDiffTy, 1), - "and"); - - IsVirtual = Builder.CreateTrunc(IsVirtual, - llvm::Type::getInt1Ty(VMContext)); - - llvm::BasicBlock *FnVirtual = createBasicBlock("fn.virtual"); - llvm::BasicBlock *FnNonVirtual = createBasicBlock("fn.nonvirtual"); - llvm::BasicBlock *FnEnd = createBasicBlock("fn.end"); - - Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual); - EmitBlock(FnVirtual); - - const llvm::Type *VTableTy = - FTy->getPointerTo()->getPointerTo()->getPointerTo(); - - llvm::Value *VTable = Builder.CreateBitCast(This, VTableTy); - VTable = Builder.CreateLoad(VTable); - - VTable = Builder.CreateGEP(VTable, FnAsInt, "fn"); - - // Since the function pointer is 1 plus the virtual table offset, we - // subtract 1 by using a GEP. - VTable = Builder.CreateConstGEP1_64(VTable, (uint64_t)-1); - - llvm::Value *VirtualFn = Builder.CreateLoad(VTable, "virtualfn"); - - EmitBranch(FnEnd); - EmitBlock(FnNonVirtual); - - // If the function is not virtual, just load the pointer. - llvm::Value *NonVirtualFn = Builder.CreateLoad(FnPtr, "fn"); - NonVirtualFn = Builder.CreateIntToPtr(NonVirtualFn, FTy->getPointerTo()); - - EmitBlock(FnEnd); - - llvm::PHINode *Callee = Builder.CreatePHI(FTy->getPointerTo()); - Callee->reserveOperandSpace(2); - Callee->addIncoming(VirtualFn, FnVirtual); - Callee->addIncoming(NonVirtualFn, FnNonVirtual); - - CallArgList Args; - - QualType ThisType = - getContext().getPointerType(getContext().getTagDeclType(RD)); - - // Push the this ptr. - Args.push_back(std::make_pair(RValue::get(This), ThisType)); - - // And the rest of the call args - EmitCallArgs(Args, FPT, E->arg_begin(), E->arg_end()); - QualType ResultType = BO->getType()->getAs<FunctionType>()->getResultType(); - return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args), Callee, - ReturnValue, Args); -} - -RValue -CodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E, - const CXXMethodDecl *MD, - ReturnValueSlot ReturnValue) { - assert(MD->isInstance() && - "Trying to emit a member call expr on a static method!"); - - if (MD->isCopyAssignment()) { - const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(MD->getDeclContext()); - if (ClassDecl->hasTrivialCopyAssignment()) { - assert(!ClassDecl->hasUserDeclaredCopyAssignment() && - "EmitCXXOperatorMemberCallExpr - user declared copy assignment"); - llvm::Value *This = EmitLValue(E->getArg(0)).getAddress(); - llvm::Value *Src = EmitLValue(E->getArg(1)).getAddress(); - QualType Ty = E->getType(); - EmitAggregateCopy(This, Src, Ty); - return RValue::get(This); - } - } - - const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); - const llvm::Type *Ty = - CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), - FPT->isVariadic()); - - llvm::Value *This = EmitLValue(E->getArg(0)).getAddress(); - - llvm::Value *Callee; - if (MD->isVirtual() && !canDevirtualizeMemberFunctionCalls(E->getArg(0))) - Callee = BuildVirtualCall(MD, This, Ty); - else - Callee = CGM.GetAddrOfFunction(MD, Ty); - - return EmitCXXMemberCall(MD, Callee, ReturnValue, This, - E->arg_begin() + 1, E->arg_end()); -} llvm::Value *CodeGenFunction::LoadCXXThis() { assert(isa<CXXMethodDecl>(CurFuncDecl) && @@ -302,320 +40,6 @@ llvm::Value *CodeGenFunction::LoadCXXThis() { return Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this"); } -/// EmitCXXAggrConstructorCall - This routine essentially creates a (nested) -/// for-loop to call the default constructor on individual members of the -/// array. -/// 'D' is the default constructor for elements of the array, 'ArrayTy' is the -/// array type and 'ArrayPtr' points to the beginning fo the array. -/// It is assumed that all relevant checks have been made by the caller. -void -CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, - const ConstantArrayType *ArrayTy, - llvm::Value *ArrayPtr, - CallExpr::const_arg_iterator ArgBeg, - CallExpr::const_arg_iterator ArgEnd) { - - const llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); - llvm::Value * NumElements = - llvm::ConstantInt::get(SizeTy, - getContext().getConstantArrayElementCount(ArrayTy)); - - EmitCXXAggrConstructorCall(D, NumElements, ArrayPtr, ArgBeg, ArgEnd); -} - -void -CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, - llvm::Value *NumElements, - llvm::Value *ArrayPtr, - CallExpr::const_arg_iterator ArgBeg, - CallExpr::const_arg_iterator ArgEnd) { - const llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); - - // Create a temporary for the loop index and initialize it with 0. - llvm::Value *IndexPtr = CreateTempAlloca(SizeTy, "loop.index"); - llvm::Value *Zero = llvm::Constant::getNullValue(SizeTy); - Builder.CreateStore(Zero, IndexPtr); - - // Start the loop with a block that tests the condition. - llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); - llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); - - EmitBlock(CondBlock); - - llvm::BasicBlock *ForBody = createBasicBlock("for.body"); - - // Generate: if (loop-index < number-of-elements fall to the loop body, - // otherwise, go to the block after the for-loop. - llvm::Value *Counter = Builder.CreateLoad(IndexPtr); - llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElements, "isless"); - // If the condition is true, execute the body. - Builder.CreateCondBr(IsLess, ForBody, AfterFor); - - EmitBlock(ForBody); - - llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc"); - // Inside the loop body, emit the constructor call on the array element. - Counter = Builder.CreateLoad(IndexPtr); - llvm::Value *Address = Builder.CreateInBoundsGEP(ArrayPtr, Counter, - "arrayidx"); - - // C++ [class.temporary]p4: - // There are two contexts in which temporaries are destroyed at a different - // point than the end of the full-expression. The first context is when a - // default constructor is called to initialize an element of an array. - // If the constructor has one or more default arguments, the destruction of - // every temporary created in a default argument expression is sequenced - // before the construction of the next array element, if any. - - // Keep track of the current number of live temporaries. - unsigned OldNumLiveTemporaries = LiveTemporaries.size(); - - EmitCXXConstructorCall(D, Ctor_Complete, Address, ArgBeg, ArgEnd); - - // Pop temporaries. - while (LiveTemporaries.size() > OldNumLiveTemporaries) - PopCXXTemporary(); - - EmitBlock(ContinueBlock); - - // Emit the increment of the loop counter. - llvm::Value *NextVal = llvm::ConstantInt::get(SizeTy, 1); - Counter = Builder.CreateLoad(IndexPtr); - NextVal = Builder.CreateAdd(Counter, NextVal, "inc"); - Builder.CreateStore(NextVal, IndexPtr); - - // Finally, branch back up to the condition for the next iteration. - EmitBranch(CondBlock); - - // Emit the fall-through block. - EmitBlock(AfterFor, true); -} - -/// EmitCXXAggrDestructorCall - calls the default destructor on array -/// elements in reverse order of construction. -void -CodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D, - const ArrayType *Array, - llvm::Value *This) { - const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array); - assert(CA && "Do we support VLA for destruction ?"); - uint64_t ElementCount = getContext().getConstantArrayElementCount(CA); - - const llvm::Type *SizeLTy = ConvertType(getContext().getSizeType()); - llvm::Value* ElementCountPtr = llvm::ConstantInt::get(SizeLTy, ElementCount); - EmitCXXAggrDestructorCall(D, ElementCountPtr, This); -} - -/// EmitCXXAggrDestructorCall - calls the default destructor on array -/// elements in reverse order of construction. -void -CodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D, - llvm::Value *UpperCount, - llvm::Value *This) { - const llvm::Type *SizeLTy = ConvertType(getContext().getSizeType()); - llvm::Value *One = llvm::ConstantInt::get(SizeLTy, 1); - - // Create a temporary for the loop index and initialize it with count of - // array elements. - llvm::Value *IndexPtr = CreateTempAlloca(SizeLTy, "loop.index"); - - // Store the number of elements in the index pointer. - Builder.CreateStore(UpperCount, IndexPtr); - - // Start the loop with a block that tests the condition. - llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); - llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); - - EmitBlock(CondBlock); - - llvm::BasicBlock *ForBody = createBasicBlock("for.body"); - - // Generate: if (loop-index != 0 fall to the loop body, - // otherwise, go to the block after the for-loop. - llvm::Value* zeroConstant = - llvm::Constant::getNullValue(SizeLTy); - llvm::Value *Counter = Builder.CreateLoad(IndexPtr); - llvm::Value *IsNE = Builder.CreateICmpNE(Counter, zeroConstant, - "isne"); - // If the condition is true, execute the body. - Builder.CreateCondBr(IsNE, ForBody, AfterFor); - - EmitBlock(ForBody); - - llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc"); - // Inside the loop body, emit the constructor call on the array element. - Counter = Builder.CreateLoad(IndexPtr); - Counter = Builder.CreateSub(Counter, One); - llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx"); - EmitCXXDestructorCall(D, Dtor_Complete, Address); - - EmitBlock(ContinueBlock); - - // Emit the decrement of the loop counter. - Counter = Builder.CreateLoad(IndexPtr); - Counter = Builder.CreateSub(Counter, One, "dec"); - Builder.CreateStore(Counter, IndexPtr); - - // Finally, branch back up to the condition for the next iteration. - EmitBranch(CondBlock); - - // Emit the fall-through block. - EmitBlock(AfterFor, true); -} - -/// GenerateCXXAggrDestructorHelper - Generates a helper function which when -/// invoked, calls the default destructor on array elements in reverse order of -/// construction. -llvm::Constant * -CodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D, - const ArrayType *Array, - llvm::Value *This) { - FunctionArgList Args; - ImplicitParamDecl *Dst = - ImplicitParamDecl::Create(getContext(), 0, - SourceLocation(), 0, - getContext().getPointerType(getContext().VoidTy)); - Args.push_back(std::make_pair(Dst, Dst->getType())); - - llvm::SmallString<16> Name; - llvm::raw_svector_ostream(Name) << "__tcf_" << (++UniqueAggrDestructorCount); - QualType R = getContext().VoidTy; - const CGFunctionInfo &FI = CGM.getTypes().getFunctionInfo(R, Args); - const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false); - llvm::Function *Fn = - llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage, - Name.str(), - &CGM.getModule()); - IdentifierInfo *II = &CGM.getContext().Idents.get(Name.str()); - FunctionDecl *FD = FunctionDecl::Create(getContext(), - getContext().getTranslationUnitDecl(), - SourceLocation(), II, R, 0, - FunctionDecl::Static, - false, true); - StartFunction(FD, R, Fn, Args, SourceLocation()); - QualType BaseElementTy = getContext().getBaseElementType(Array); - const llvm::Type *BasePtr = ConvertType(BaseElementTy); - BasePtr = llvm::PointerType::getUnqual(BasePtr); - llvm::Value *BaseAddrPtr = Builder.CreateBitCast(This, BasePtr); - EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr); - FinishFunction(); - llvm::Type *Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), - 0); - llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty); - return m; -} - -void -CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, - CXXCtorType Type, - llvm::Value *This, - CallExpr::const_arg_iterator ArgBeg, - CallExpr::const_arg_iterator ArgEnd) { - if (D->isCopyConstructor()) { - const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(D->getDeclContext()); - if (ClassDecl->hasTrivialCopyConstructor()) { - assert(!ClassDecl->hasUserDeclaredCopyConstructor() && - "EmitCXXConstructorCall - user declared copy constructor"); - const Expr *E = (*ArgBeg); - QualType Ty = E->getType(); - llvm::Value *Src = EmitLValue(E).getAddress(); - EmitAggregateCopy(This, Src, Ty); - return; - } - } else if (D->isTrivial()) { - // FIXME: Track down why we're trying to generate calls to the trivial - // default constructor! - return; - } - - llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type); - - EmitCXXMemberCall(D, Callee, ReturnValueSlot(), This, ArgBeg, ArgEnd); -} - -void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD, - CXXDtorType Type, - llvm::Value *This) { - llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(DD, Type); - - CallArgList Args; - - // Push the this ptr. - Args.push_back(std::make_pair(RValue::get(This), - DD->getThisType(getContext()))); - - // Add a VTT parameter if necessary. - // FIXME: This should not be a dummy null parameter! - if (Type == Dtor_Base && DD->getParent()->getNumVBases() != 0) { - QualType T = getContext().getPointerType(getContext().VoidPtrTy); - - Args.push_back(std::make_pair(RValue::get(CGM.EmitNullConstant(T)), T)); - } - - // FIXME: We should try to share this code with EmitCXXMemberCall. - - QualType ResultType = DD->getType()->getAs<FunctionType>()->getResultType(); - EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args), Callee, - ReturnValueSlot(), Args, DD); -} - -void -CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest, - const CXXConstructExpr *E) { - assert(Dest && "Must have a destination!"); - const CXXConstructorDecl *CD = E->getConstructor(); - const ConstantArrayType *Array = - getContext().getAsConstantArrayType(E->getType()); - // For a copy constructor, even if it is trivial, must fall thru so - // its argument is code-gen'ed. - if (!CD->isCopyConstructor()) { - QualType InitType = E->getType(); - if (Array) - InitType = getContext().getBaseElementType(Array); - const CXXRecordDecl *RD = - cast<CXXRecordDecl>(InitType->getAs<RecordType>()->getDecl()); - if (RD->hasTrivialConstructor()) - return; - } - // Code gen optimization to eliminate copy constructor and return - // its first argument instead. - if (getContext().getLangOptions().ElideConstructors && E->isElidable()) { - const Expr *Arg = E->getArg(0); - - if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) { - assert((ICE->getCastKind() == CastExpr::CK_NoOp || - ICE->getCastKind() == CastExpr::CK_ConstructorConversion || - ICE->getCastKind() == CastExpr::CK_UserDefinedConversion) && - "Unknown implicit cast kind in constructor elision"); - Arg = ICE->getSubExpr(); - } - - if (const CXXFunctionalCastExpr *FCE = dyn_cast<CXXFunctionalCastExpr>(Arg)) - Arg = FCE->getSubExpr(); - - if (const CXXBindTemporaryExpr *BindExpr = - dyn_cast<CXXBindTemporaryExpr>(Arg)) - Arg = BindExpr->getSubExpr(); - - EmitAggExpr(Arg, Dest, false); - return; - } - if (Array) { - QualType BaseElementTy = getContext().getBaseElementType(Array); - const llvm::Type *BasePtr = ConvertType(BaseElementTy); - BasePtr = llvm::PointerType::getUnqual(BasePtr); - llvm::Value *BaseAddrPtr = - Builder.CreateBitCast(Dest, BasePtr); - - EmitCXXAggrConstructorCall(CD, Array, BaseAddrPtr, - E->arg_begin(), E->arg_end()); - } - else - // Call the constructor. - EmitCXXConstructorCall(CD, Ctor_Complete, Dest, - E->arg_begin(), E->arg_end()); -} - void CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) { EmitGlobal(GlobalDecl(D, Ctor_Complete)); EmitGlobal(GlobalDecl(D, Ctor_Base)); @@ -1001,33 +425,6 @@ CodeGenModule::BuildCovariantThunk(const GlobalDecl &GD, bool Extern, return m; } -llvm::Value * -CodeGenFunction::GetVirtualCXXBaseClassOffset(llvm::Value *This, - const CXXRecordDecl *ClassDecl, - const CXXRecordDecl *BaseClassDecl) { - const llvm::Type *Int8PtrTy = - llvm::Type::getInt8Ty(VMContext)->getPointerTo(); - - llvm::Value *VTablePtr = Builder.CreateBitCast(This, - Int8PtrTy->getPointerTo()); - VTablePtr = Builder.CreateLoad(VTablePtr, "vtable"); - - int64_t VBaseOffsetIndex = - CGM.getVtableInfo().getVirtualBaseOffsetIndex(ClassDecl, BaseClassDecl); - - llvm::Value *VBaseOffsetPtr = - Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetIndex, "vbase.offset.ptr"); - const llvm::Type *PtrDiffTy = - ConvertType(getContext().getPointerDiffType()); - - VBaseOffsetPtr = Builder.CreateBitCast(VBaseOffsetPtr, - PtrDiffTy->getPointerTo()); - - llvm::Value *VBaseOffset = Builder.CreateLoad(VBaseOffsetPtr, "vbase.offset"); - - return VBaseOffset; -} - static llvm::Value *BuildVirtualCall(CodeGenFunction &CGF, uint64_t VtableIndex, llvm::Value *This, const llvm::Type *Ty) { Ty = Ty->getPointerTo()->getPointerTo()->getPointerTo(); @@ -1058,71 +455,3 @@ CodeGenFunction::BuildVirtualCall(const CXXDestructorDecl *DD, CXXDtorType Type, return ::BuildVirtualCall(*this, VtableIndex, This, Ty); } - -void CodeGenFunction::InitializeVtablePtrs(const CXXRecordDecl *ClassDecl) { - if (!ClassDecl->isDynamicClass()) - return; - - llvm::Constant *Vtable = CGM.getVtableInfo().getVtable(ClassDecl); - CodeGenModule::AddrSubMap_t& AddressPoints = - *(*CGM.AddressPoints[ClassDecl])[ClassDecl]; - llvm::Value *ThisPtr = LoadCXXThis(); - const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl); - - // Store address points for virtual bases - for (CXXRecordDecl::base_class_const_iterator I = - ClassDecl->vbases_begin(), E = ClassDecl->vbases_end(); I != E; ++I) { - const CXXBaseSpecifier &Base = *I; - CXXRecordDecl *BaseClassDecl - = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); - uint64_t Offset = Layout.getVBaseClassOffset(BaseClassDecl); - InitializeVtablePtrsRecursive(BaseClassDecl, Vtable, AddressPoints, - ThisPtr, Offset); - } - - // Store address points for non-virtual bases and current class - InitializeVtablePtrsRecursive(ClassDecl, Vtable, AddressPoints, ThisPtr, 0); -} - -void CodeGenFunction::InitializeVtablePtrsRecursive( - const CXXRecordDecl *ClassDecl, - llvm::Constant *Vtable, - CodeGenModule::AddrSubMap_t& AddressPoints, - llvm::Value *ThisPtr, - uint64_t Offset) { - if (!ClassDecl->isDynamicClass()) - return; - - // Store address points for non-virtual bases - const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl); - for (CXXRecordDecl::base_class_const_iterator I = - ClassDecl->bases_begin(), E = ClassDecl->bases_end(); I != E; ++I) { - const CXXBaseSpecifier &Base = *I; - if (Base.isVirtual()) - continue; - CXXRecordDecl *BaseClassDecl - = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); - uint64_t NewOffset = Offset + Layout.getBaseClassOffset(BaseClassDecl); - InitializeVtablePtrsRecursive(BaseClassDecl, Vtable, AddressPoints, - ThisPtr, NewOffset); - } - - // Compute the address point - assert(AddressPoints.count(std::make_pair(ClassDecl, Offset)) && - "Missing address point for class"); - uint64_t AddressPoint = AddressPoints[std::make_pair(ClassDecl, Offset)]; - llvm::Value *VtableAddressPoint = - Builder.CreateConstInBoundsGEP2_64(Vtable, 0, AddressPoint); - - // Compute the address to store the address point - const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); - llvm::Value *VtableField = Builder.CreateBitCast(ThisPtr, Int8PtrTy); - VtableField = Builder.CreateConstInBoundsGEP1_64(VtableField, Offset/8); - const llvm::Type *AddressPointPtrTy = - VtableAddressPoint->getType()->getPointerTo(); - VtableField = Builder.CreateBitCast(VtableField, AddressPointPtrTy); - - // Store address point - Builder.CreateStore(VtableAddressPoint, VtableField); -} - |