diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp | 235 |
1 files changed, 87 insertions, 148 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp index 83c8ace..cc7b24d 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp @@ -16,6 +16,7 @@ #include "CGCXXABI.h" #include "CGDebugInfo.h" #include "CGObjCRuntime.h" +#include "clang/CodeGen/CGFunctionInfo.h" #include "clang/Frontend/CodeGenOptions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/Support/CallSite.h" @@ -62,99 +63,6 @@ RValue CodeGenFunction::EmitCXXMemberCall(const CXXMethodDecl *MD, Callee, ReturnValue, Args, MD); } -// FIXME: Ideally Expr::IgnoreParenNoopCasts should do this, but it doesn't do -// quite what we want. -static const Expr *skipNoOpCastsAndParens(const Expr *E) { - while (true) { - if (const ParenExpr *PE = dyn_cast<ParenExpr>(E)) { - E = PE->getSubExpr(); - continue; - } - - if (const CastExpr *CE = dyn_cast<CastExpr>(E)) { - if (CE->getCastKind() == CK_NoOp) { - E = CE->getSubExpr(); - continue; - } - } - if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) { - if (UO->getOpcode() == UO_Extension) { - E = UO->getSubExpr(); - continue; - } - } - return E; - } -} - -/// canDevirtualizeMemberFunctionCalls - Checks whether virtual calls on given -/// expr can be devirtualized. -static bool canDevirtualizeMemberFunctionCalls(ASTContext &Context, - const Expr *Base, - const CXXMethodDecl *MD) { - - // When building with -fapple-kext, all calls must go through the vtable since - // the kernel linker can do runtime patching of vtables. - if (Context.getLangOpts().AppleKext) - return false; - - // If the most derived class is marked final, we know that no subclass can - // override this member function and so we can devirtualize it. For example: - // - // struct A { virtual void f(); } - // struct B final : A { }; - // - // void f(B *b) { - // b->f(); - // } - // - const CXXRecordDecl *MostDerivedClassDecl = Base->getBestDynamicClassType(); - if (MostDerivedClassDecl->hasAttr<FinalAttr>()) - return true; - - // If the member function is marked 'final', we know that it can't be - // overridden and can therefore devirtualize it. - if (MD->hasAttr<FinalAttr>()) - return true; - - // Similarly, if the class itself is marked 'final' it can't be overridden - // and we can therefore devirtualize the member function call. - if (MD->getParent()->hasAttr<FinalAttr>()) - return true; - - Base = skipNoOpCastsAndParens(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 devirtualize calls on an object accessed by a class member access - // expression, since by C++11 [basic.life]p6 we know that it can't refer to - // a derived class object constructed in the same location. - if (const MemberExpr *ME = dyn_cast<MemberExpr>(Base)) - if (const ValueDecl *VD = dyn_cast<ValueDecl>(ME->getMemberDecl())) - return VD->getType()->isRecordType(); - - // We can always devirtualize calls on temporary object expressions. - if (isa<CXXConstructExpr>(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; -} - static CXXRecordDecl *getCXXRecord(const Expr *E) { QualType T = E->getType(); if (const PointerType *PTy = T->getAs<PointerType>()) @@ -175,22 +83,12 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE, const MemberExpr *ME = cast<MemberExpr>(callee); const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl()); - CGDebugInfo *DI = getDebugInfo(); - if (DI && - CGM.getCodeGenOpts().getDebugInfo() == CodeGenOptions::LimitedDebugInfo && - !isa<CallExpr>(ME->getBase())) { - QualType PQTy = ME->getBase()->IgnoreParenImpCasts()->getType(); - if (const PointerType * PTy = dyn_cast<PointerType>(PQTy)) { - DI->getOrCreateRecordType(PTy->getPointeeType(), - MD->getParent()->getLocation()); - } - } - 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()); + CE->getLocStart(), ReturnValue, CE->arg_begin(), + CE->arg_end()); } // Compute the object pointer. @@ -198,8 +96,7 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE, bool CanUseVirtualCall = MD->isVirtual() && !ME->hasQualifier(); const CXXMethodDecl *DevirtualizedMethod = NULL; - if (CanUseVirtualCall && - canDevirtualizeMemberFunctionCalls(getContext(), Base, MD)) { + if (CanUseVirtualCall && CanDevirtualizeMemberFunctionCall(Base, MD)) { const CXXRecordDecl *BestDynamicDecl = Base->getBestDynamicClassType(); DevirtualizedMethod = MD->getCorrespondingMethodInClass(BestDynamicDecl); assert(DevirtualizedMethod); @@ -271,7 +168,7 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE, else FInfo = &CGM.getTypes().arrangeCXXMethodDeclaration(CalleeDecl); - llvm::Type *Ty = CGM.getTypes().GetFunctionType(*FInfo); + llvm::FunctionType *Ty = CGM.getTypes().GetFunctionType(*FInfo); // C++ [class.virtual]p12: // Explicit qualification with the scope operator (5.1) suppresses the @@ -280,34 +177,37 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE, // We also don't emit a virtual call if the base expression has a record type // because then we know what the type is. bool UseVirtualCall = CanUseVirtualCall && !DevirtualizedMethod; - llvm::Value *Callee; + if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(MD)) { + assert(CE->arg_begin() == CE->arg_end() && + "Destructor shouldn't have explicit parameters"); + assert(ReturnValue.isNull() && "Destructor shouldn't have return value"); if (UseVirtualCall) { - assert(CE->arg_begin() == CE->arg_end() && - "Virtual destructor shouldn't have explicit parameters"); - return CGM.getCXXABI().EmitVirtualDestructorCall(*this, Dtor, - Dtor_Complete, - CE->getExprLoc(), - ReturnValue, This); + CGM.getCXXABI().EmitVirtualDestructorCall(*this, Dtor, Dtor_Complete, + CE->getExprLoc(), This); } else { if (getLangOpts().AppleKext && MD->isVirtual() && ME->hasQualifier()) Callee = BuildAppleKextVirtualCall(MD, ME->getQualifier(), Ty); else if (!DevirtualizedMethod) - Callee = CGM.GetAddrOfFunction(GlobalDecl(Dtor, Dtor_Complete), Ty); + Callee = CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete, FInfo, Ty); else { const CXXDestructorDecl *DDtor = cast<CXXDestructorDecl>(DevirtualizedMethod); Callee = CGM.GetAddrOfFunction(GlobalDecl(DDtor, Dtor_Complete), Ty); } + EmitCXXMemberCall(MD, CE->getExprLoc(), Callee, ReturnValue, This, + /*ImplicitParam=*/0, QualType(), 0, 0); } - } else if (const CXXConstructorDecl *Ctor = - dyn_cast<CXXConstructorDecl>(MD)) { + return RValue::get(0); + } + + if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(MD)) { Callee = CGM.GetAddrOfFunction(GlobalDecl(Ctor, Ctor_Complete), Ty); } else if (UseVirtualCall) { - Callee = BuildVirtualCall(MD, This, Ty); + Callee = CGM.getCXXABI().getVirtualFunctionPointer(*this, MD, This, Ty); } else { if (getLangOpts().AppleKext && MD->isVirtual() && @@ -320,6 +220,9 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE, } } + if (MD->isVirtual()) + This = CGM.getCXXABI().adjustThisArgumentForVirtualCall(*this, MD, This); + return EmitCXXMemberCall(MD, CE->getExprLoc(), Callee, ReturnValue, This, /*ImplicitParam=*/0, QualType(), CE->arg_begin(), CE->arg_end()); @@ -371,8 +274,8 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, // And the rest of the call args EmitCallArgs(Args, FPT, E->arg_begin(), E->arg_end()); - return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required), Callee, - ReturnValue, Args); + return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required), + Callee, ReturnValue, Args); } RValue @@ -540,8 +443,7 @@ CodeGenFunction::EmitSynthesizedCXXCopyCtor(llvm::Value *Dest, assert(!getContext().getAsConstantArrayType(E->getType()) && "EmitSynthesizedCXXCopyCtor - Copied-in Array"); - EmitSynthesizedCXXCopyCtorCall(CD, Dest, Src, - E->arg_begin(), E->arg_end()); + EmitSynthesizedCXXCopyCtorCall(CD, Dest, Src, E->arg_begin(), E->arg_end()); } static CharUnits CalculateCookiePadding(CodeGenFunction &CGF, @@ -818,7 +720,7 @@ static llvm::Value *EmitCXXNewAllocSize(CodeGenFunction &CGF, static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const Expr *Init, QualType AllocType, llvm::Value *NewPtr) { - + // FIXME: Refactor with EmitExprAsInit. CharUnits Alignment = CGF.getContext().getTypeAlignInChars(AllocType); switch (CGF.getEvaluationKind(AllocType)) { case TEK_Scalar: @@ -838,8 +740,6 @@ static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const Expr *Init, AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased); CGF.EmitAggExpr(Init, Slot); - - CGF.MaybeEmitStdInitializerListCleanup(NewPtr, Init); return; } } @@ -866,10 +766,22 @@ CodeGenFunction::EmitNewArrayInitializer(const CXXNewExpr *E, QualType::DestructionKind dtorKind = elementType.isDestructedType(); EHScopeStack::stable_iterator cleanup; llvm::Instruction *cleanupDominator = 0; + // If the initializer is an initializer list, first do the explicit elements. if (const InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) { initializerElements = ILE->getNumInits(); + // If this is a multi-dimensional array new, we will initialize multiple + // elements with each init list element. + QualType AllocType = E->getAllocatedType(); + if (const ConstantArrayType *CAT = dyn_cast_or_null<ConstantArrayType>( + AllocType->getAsArrayTypeUnsafe())) { + unsigned AS = explicitPtr->getType()->getPointerAddressSpace(); + llvm::Type *AllocPtrTy = ConvertTypeForMem(AllocType)->getPointerTo(AS); + explicitPtr = Builder.CreateBitCast(explicitPtr, AllocPtrTy); + initializerElements *= getContext().getConstantArrayElementCount(CAT); + } + // Enter a partial-destruction cleanup if necessary. if (needsEHCleanup(dtorKind)) { // In principle we could tell the cleanup where we are more @@ -888,12 +800,16 @@ CodeGenFunction::EmitNewArrayInitializer(const CXXNewExpr *E, // element. TODO: some of these stores can be trivially // observed to be unnecessary. if (endOfInit) Builder.CreateStore(explicitPtr, endOfInit); - StoreAnyExprIntoOneUnit(*this, ILE->getInit(i), elementType, explicitPtr); - explicitPtr =Builder.CreateConstGEP1_32(explicitPtr, 1, "array.exp.next"); + StoreAnyExprIntoOneUnit(*this, ILE->getInit(i), + ILE->getInit(i)->getType(), explicitPtr); + explicitPtr = Builder.CreateConstGEP1_32(explicitPtr, 1, + "array.exp.next"); } // The remaining elements are filled with the array filler expression. Init = ILE->getArrayFiller(); + + explicitPtr = Builder.CreateBitCast(explicitPtr, beginPtr->getType()); } // Create the continuation block. @@ -1012,6 +928,41 @@ static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E, StoreAnyExprIntoOneUnit(CGF, Init, E->getAllocatedType(), NewPtr); } +/// Emit a call to an operator new or operator delete function, as implicitly +/// created by new-expressions and delete-expressions. +static RValue EmitNewDeleteCall(CodeGenFunction &CGF, + const FunctionDecl *Callee, + const FunctionProtoType *CalleeType, + const CallArgList &Args) { + llvm::Instruction *CallOrInvoke; + llvm::Value *CalleeAddr = CGF.CGM.GetAddrOfFunction(Callee); + RValue RV = + CGF.EmitCall(CGF.CGM.getTypes().arrangeFreeFunctionCall(Args, CalleeType), + CalleeAddr, ReturnValueSlot(), Args, + Callee, &CallOrInvoke); + + /// C++1y [expr.new]p10: + /// [In a new-expression,] an implementation is allowed to omit a call + /// to a replaceable global allocation function. + /// + /// We model such elidable calls with the 'builtin' attribute. + llvm::Function *Fn = dyn_cast<llvm::Function>(CalleeAddr); + if (Callee->isReplaceableGlobalAllocationFunction() && + Fn && Fn->hasFnAttribute(llvm::Attribute::NoBuiltin)) { + // FIXME: Add addAttribute to CallSite. + if (llvm::CallInst *CI = dyn_cast<llvm::CallInst>(CallOrInvoke)) + CI->addAttribute(llvm::AttributeSet::FunctionIndex, + llvm::Attribute::Builtin); + else if (llvm::InvokeInst *II = dyn_cast<llvm::InvokeInst>(CallOrInvoke)) + II->addAttribute(llvm::AttributeSet::FunctionIndex, + llvm::Attribute::Builtin); + else + llvm_unreachable("unexpected kind of call instruction"); + } + + return RV; +} + namespace { /// A cleanup to call the given 'operator delete' function upon /// abnormal exit from a new expression. @@ -1061,9 +1012,7 @@ namespace { DeleteArgs.add(getPlacementArgs()[I], *AI++); // Call 'operator delete'. - CGF.EmitCall(CGF.CGM.getTypes().arrangeFreeFunctionCall(DeleteArgs, FPT), - CGF.CGM.GetAddrOfFunction(OperatorDelete), - ReturnValueSlot(), DeleteArgs, OperatorDelete); + EmitNewDeleteCall(CGF, OperatorDelete, FPT, DeleteArgs); } }; @@ -1122,9 +1071,7 @@ namespace { } // Call 'operator delete'. - CGF.EmitCall(CGF.CGM.getTypes().arrangeFreeFunctionCall(DeleteArgs, FPT), - CGF.CGM.GetAddrOfFunction(OperatorDelete), - ReturnValueSlot(), DeleteArgs, OperatorDelete); + EmitNewDeleteCall(CGF, OperatorDelete, FPT, DeleteArgs); } }; } @@ -1237,10 +1184,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { // TODO: kill any unnecessary computations done for the size // argument. } else { - RV = EmitCall(CGM.getTypes().arrangeFreeFunctionCall(allocatorArgs, - allocatorType), - CGM.GetAddrOfFunction(allocator), ReturnValueSlot(), - allocatorArgs, allocator); + RV = EmitNewDeleteCall(*this, allocator, allocatorType, allocatorArgs); } // Emit a null check on the allocation result if the allocation @@ -1360,9 +1304,7 @@ void CodeGenFunction::EmitDeleteCall(const FunctionDecl *DeleteFD, DeleteArgs.add(RValue::get(Size), SizeTy); // Emit the call to delete. - EmitCall(CGM.getTypes().arrangeFreeFunctionCall(DeleteArgs, DeleteFTy), - CGM.GetAddrOfFunction(DeleteFD), ReturnValueSlot(), - DeleteArgs, DeleteFD); + EmitNewDeleteCall(*this, DeleteFD, DeleteFTy, DeleteArgs); } namespace { @@ -1415,8 +1357,7 @@ static void EmitObjectDelete(CodeGenFunction &CGF, // FIXME: Provide a source location here. CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : Dtor_Deleting; CGF.CGM.getCXXABI().EmitVirtualDestructorCall(CGF, Dtor, DtorType, - SourceLocation(), - ReturnValueSlot(), Ptr); + SourceLocation(), Ptr); if (UseGlobalDelete) { CGF.PopCleanupBlock(); @@ -1519,9 +1460,7 @@ namespace { } // Emit the call to delete. - CGF.EmitCall(CGF.getTypes().arrangeFreeFunctionCall(Args, DeleteFTy), - CGF.CGM.GetAddrOfFunction(OperatorDelete), - ReturnValueSlot(), Args, OperatorDelete); + EmitNewDeleteCall(CGF, OperatorDelete, DeleteFTy, Args); } }; } @@ -1667,8 +1606,8 @@ llvm::Value *CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) { ConvertType(E->getType())->getPointerTo(); if (E->isTypeOperand()) { - llvm::Constant *TypeInfo = - CGM.GetAddrOfRTTIDescriptor(E->getTypeOperand()); + llvm::Constant *TypeInfo = + CGM.GetAddrOfRTTIDescriptor(E->getTypeOperand(getContext())); return Builder.CreateBitCast(TypeInfo, StdTypeInfoPtrTy); } |