return const_cast<Expr*>(this)->getSourceBitField();
}
+ Decl *getReferencedDeclOfCallee();
+ const Decl *getReferencedDeclOfCallee() const {
+ return const_cast<Expr*>(this)->getReferencedDeclOfCallee();
+ }
+
/// \brief If this expression is an l-value for an Objective C
/// property, find the underlying property reference expression.
const ObjCPropertyRefExpr *getObjCProperty() const;
}
};
-/// CGCalleeInfo - Class to encapsulate the information about a callee to be
-/// used during the generation of call/invoke instructions.
-class CGCalleeInfo {
- /// \brief The function proto type of the callee.
- const FunctionProtoType *CalleeProtoTy;
- /// \brief The function declaration of the callee.
- const Decl *CalleeDecl;
-
-public:
- explicit CGCalleeInfo() : CalleeProtoTy(nullptr), CalleeDecl(nullptr) {}
- CGCalleeInfo(const FunctionProtoType *calleeProtoTy, const Decl *calleeDecl)
- : CalleeProtoTy(calleeProtoTy), CalleeDecl(calleeDecl) {}
- CGCalleeInfo(const FunctionProtoType *calleeProtoTy)
- : CalleeProtoTy(calleeProtoTy), CalleeDecl(nullptr) {}
- CGCalleeInfo(const Decl *calleeDecl)
- : CalleeProtoTy(nullptr), CalleeDecl(calleeDecl) {}
-
- const FunctionProtoType *getCalleeFunctionProtoType() {
- return CalleeProtoTy;
- }
- const Decl *getCalleeDecl() { return CalleeDecl; }
-};
-
} // end namespace CodeGen
} // end namespace clang
ExprBits.ContainsUnexpandedParameterPack = true;
}
+FunctionDecl *CallExpr::getDirectCallee() {
+ return dyn_cast_or_null<FunctionDecl>(getCalleeDecl());
+}
+
Decl *CallExpr::getCalleeDecl() {
- Expr *CEE = getCallee()->IgnoreParenImpCasts();
+ return getCallee()->getReferencedDeclOfCallee();
+}
+
+Decl *Expr::getReferencedDeclOfCallee() {
+ Expr *CEE = IgnoreParenImpCasts();
while (SubstNonTypeTemplateParmExpr *NTTP
= dyn_cast<SubstNonTypeTemplateParmExpr>(CEE)) {
return nullptr;
}
-FunctionDecl *CallExpr::getDirectCallee() {
- return dyn_cast_or_null<FunctionDecl>(getCalleeDecl());
-}
-
/// setNumArgs - This changes the number of arguments present in this call.
/// Any orphaned expressions are deleted by this, and any new operands are set
/// to null.
CGF.CGM.getTypes().arrangeBuiltinFunctionCall(resultType, args);
llvm::FunctionType *fnTy = CGF.CGM.getTypes().GetFunctionType(fnInfo);
llvm::Constant *fn = CGF.CGM.CreateRuntimeFunction(fnTy, fnName);
- return CGF.EmitCall(fnInfo, fn, ReturnValueSlot(), args);
+ auto callee = CGCallee::forDirect(fn);
+ return CGF.EmitCall(fnInfo, callee, ReturnValueSlot(), args);
}
/// Does a store of the given IR type modify the full expected width?
const BlockPointerType *BPT =
E->getCallee()->getType()->getAs<BlockPointerType>();
- llvm::Value *Callee = EmitScalarExpr(E->getCallee());
+ llvm::Value *BlockPtr = EmitScalarExpr(E->getCallee());
// Get a pointer to the generic block literal.
llvm::Type *BlockLiteralTy =
llvm::PointerType::getUnqual(CGM.getGenericBlockLiteralType());
// Bitcast the callee to a block literal.
- llvm::Value *BlockLiteral =
- Builder.CreateBitCast(Callee, BlockLiteralTy, "block.literal");
+ BlockPtr = Builder.CreateBitCast(BlockPtr, BlockLiteralTy, "block.literal");
// Get the function pointer from the literal.
llvm::Value *FuncPtr =
- Builder.CreateStructGEP(CGM.getGenericBlockLiteralType(), BlockLiteral, 3);
+ Builder.CreateStructGEP(CGM.getGenericBlockLiteralType(), BlockPtr, 3);
- BlockLiteral = Builder.CreateBitCast(BlockLiteral, VoidPtrTy);
+ BlockPtr = Builder.CreateBitCast(BlockPtr, VoidPtrTy);
// Add the block literal.
CallArgList Args;
- Args.add(RValue::get(BlockLiteral), getContext().VoidPtrTy);
+ Args.add(RValue::get(BlockPtr), getContext().VoidPtrTy);
QualType FnType = BPT->getPointeeType();
llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy);
Func = Builder.CreateBitCast(Func, BlockFTyPtr);
+ // Prepare the callee.
+ CGCallee Callee(CGCalleeInfo(), Func);
+
// And call the block.
- return EmitCall(FnInfo, Func, ReturnValue, Args);
+ return EmitCall(FnInfo, Callee, ReturnValue, Args);
}
Address CodeGenFunction::GetAddrOfBlockDecl(const VarDecl *variable,
/// getBuiltinLibFunction - Given a builtin id for a function like
/// "__builtin_fabsf", return a Function* for "fabsf".
-llvm::Value *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD,
- unsigned BuiltinID) {
+llvm::Constant *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD,
+ unsigned BuiltinID) {
assert(Context.BuiltinInfo.isLibFunction(BuiltinID));
// Get the name, skip over the __builtin_ prefix (if necessary).
return CGF.Builder.CreateICmpSLT(V, Zero);
}
-static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *Fn,
- const CallExpr *E, llvm::Value *calleeValue) {
- return CGF.EmitCall(E->getCallee()->getType(), calleeValue, E,
- ReturnValueSlot(), Fn);
+static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD,
+ const CallExpr *E, llvm::Constant *calleeValue) {
+ CGCallee callee = CGCallee::forDirect(calleeValue, FD);
+ return CGF.EmitCall(E->getCallee()->getType(), callee, E, ReturnValueSlot());
}
/// \brief Emit a call to llvm.{sadd,uadd,ssub,usub,smul,umul}.with.overflow.*
CGM.getTypes().arrangeBuiltinFunctionCall(E->getType(), Args);
llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo);
llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName);
- return EmitCall(FuncInfo, Func, ReturnValueSlot(), Args);
+ return EmitCall(FuncInfo, CGCallee::forDirect(Func),
+ ReturnValueSlot(), Args);
}
case Builtin::BI__atomic_test_and_set: {
const CallExpr *Call = cast<CallExpr>(E->getArg(0));
const Expr *Chain = E->getArg(1);
return EmitCall(Call->getCallee()->getType(),
- EmitScalarExpr(Call->getCallee()), Call, ReturnValue,
- Call->getCalleeDecl(), EmitScalarExpr(Chain));
+ EmitCallee(Call->getCallee()), Call, ReturnValue,
+ EmitScalarExpr(Chain));
}
case Builtin::BI_InterlockedExchange8:
case Builtin::BI_InterlockedExchange16:
// If this is a predefined lib function (e.g. malloc), emit the call
// using exactly the normal call path.
if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID))
- return emitLibraryCall(*this, FD, E, EmitScalarExpr(E->getCallee()));
+ return emitLibraryCall(*this, FD, E,
+ cast<llvm::Constant>(EmitScalarExpr(E->getCallee())));
// Check that a call to a target specific builtin has the correct target
// features.
eval.begin(CGF);
CGF.EmitBlock(ConfigOKBlock);
-
- const Decl *TargetDecl = nullptr;
- if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E->getCallee())) {
- if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CE->getSubExpr())) {
- TargetDecl = DRE->getDecl();
- }
- }
-
- llvm::Value *Callee = CGF.EmitScalarExpr(E->getCallee());
- CGF.EmitCall(E->getCallee()->getType(), Callee, E, ReturnValue, TargetDecl);
+ CGF.EmitSimpleCallExpr(E, ReturnValue);
CGF.EmitBranch(ContBlock);
CGF.EmitBlock(ContBlock);
/*isThunk=*/false, /*ExtraAttrs=*/llvm::AttributeSet(), IsForDefinition);
}
-static llvm::Value *BuildAppleKextVirtualCall(CodeGenFunction &CGF,
- GlobalDecl GD,
- llvm::Type *Ty,
- const CXXRecordDecl *RD) {
+static CGCallee BuildAppleKextVirtualCall(CodeGenFunction &CGF,
+ GlobalDecl GD,
+ llvm::Type *Ty,
+ const CXXRecordDecl *RD) {
assert(!CGF.CGM.getTarget().getCXXABI().isMicrosoft() &&
"No kext in Microsoft ABI");
GD = GD.getCanonicalDecl();
VTableIndex += AddressPoint;
llvm::Value *VFuncPtr =
CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfnkxt");
- return CGF.Builder.CreateAlignedLoad(VFuncPtr, CGF.PointerAlignInBytes);
+ llvm::Value *VFunc =
+ CGF.Builder.CreateAlignedLoad(VFuncPtr, CGF.PointerAlignInBytes);
+ CGCallee Callee(GD.getDecl(), VFunc);
+ return Callee;
}
/// BuildAppleKextVirtualCall - This routine is to support gcc's kext ABI making
/// indirect call to virtual functions. It makes the call through indexing
/// into the vtable.
-llvm::Value *
+CGCallee
CodeGenFunction::BuildAppleKextVirtualCall(const CXXMethodDecl *MD,
- NestedNameSpecifier *Qual,
- llvm::Type *Ty) {
+ NestedNameSpecifier *Qual,
+ llvm::Type *Ty) {
assert((Qual->getKind() == NestedNameSpecifier::TypeSpec) &&
"BuildAppleKextVirtualCall - bad Qual kind");
/// BuildVirtualCall - This routine makes indirect vtable call for
/// call to virtual destructors. It returns 0 if it could not do it.
-llvm::Value *
+CGCallee
CodeGenFunction::BuildAppleKextVirtualDestructorCall(
const CXXDestructorDecl *DD,
CXXDtorType Type,
const CXXRecordDecl *RD) {
- const auto *MD = cast<CXXMethodDecl>(DD);
- // FIXME. Dtor_Base dtor is always direct!!
- // It need be somehow inline expanded into the caller.
- // -O does that. But need to support -O0 as well.
- if (MD->isVirtual() && Type != Dtor_Base) {
- // Compute the function type we're calling.
- const CGFunctionInfo &FInfo = CGM.getTypes().arrangeCXXStructorDeclaration(
- DD, StructorType::Complete);
- llvm::Type *Ty = CGM.getTypes().GetFunctionType(FInfo);
- return ::BuildAppleKextVirtualCall(*this, GlobalDecl(DD, Type), Ty, RD);
- }
- return nullptr;
+ assert(DD->isVirtual() && Type != Dtor_Base);
+ // Compute the function type we're calling.
+ const CGFunctionInfo &FInfo = CGM.getTypes().arrangeCXXStructorDeclaration(
+ DD, StructorType::Complete);
+ llvm::Type *Ty = CGM.getTypes().GetFunctionType(FInfo);
+ return ::BuildAppleKextVirtualCall(*this, GlobalDecl(DD, Type), Ty, RD);
}
return CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
}
-llvm::Value *CGCXXABI::EmitLoadOfMemberFunctionPointer(
+CGCallee CGCXXABI::EmitLoadOfMemberFunctionPointer(
CodeGenFunction &CGF, const Expr *E, Address This,
llvm::Value *&ThisPtrForCall,
llvm::Value *MemPtr, const MemberPointerType *MPT) {
cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(
CGM.getTypes().arrangeCXXMethodType(RD, FPT, /*FD=*/nullptr));
- return llvm::Constant::getNullValue(FTy->getPointerTo());
+ llvm::Constant *FnPtr = llvm::Constant::getNullValue(FTy->getPointerTo());
+ return CGCallee::forDirect(FnPtr, FPT);
}
llvm::Value *
class MangleContext;
namespace CodeGen {
+class CGCallee;
class CodeGenFunction;
class CodeGenModule;
struct CatchTypeInfo;
/// Load a member function from an object and a member function
/// pointer. Apply the this-adjustment and set 'This' to the
/// adjusted value.
- virtual llvm::Value *EmitLoadOfMemberFunctionPointer(
+ virtual CGCallee EmitLoadOfMemberFunctionPointer(
CodeGenFunction &CGF, const Expr *E, Address This,
llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr,
const MemberPointerType *MPT);
CharUnits VPtrOffset) = 0;
/// Build a virtual function pointer in the ABI-specific way.
- virtual llvm::Value *getVirtualFunctionPointer(CodeGenFunction &CGF,
- GlobalDecl GD,
- Address This,
- llvm::Type *Ty,
- SourceLocation Loc) = 0;
+ virtual CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF,
+ GlobalDecl GD,
+ Address This,
+ llvm::Type *Ty,
+ SourceLocation Loc) = 0;
/// Emit the ABI-specific virtual destructor call.
virtual llvm::Value *
}
RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
- llvm::Value *Callee,
+ const CGCallee &Callee,
ReturnValueSlot ReturnValue,
const CallArgList &CallArgs,
- CGCalleeInfo CalleeInfo,
llvm::Instruction **callOrInvoke) {
// FIXME: We no longer need the types from CallArgs; lift up and simplify.
+ assert(Callee.isOrdinary());
+
// Handle struct-return functions by passing a pointer to the
// location that we would like to return into.
QualType RetTy = CallInfo.getReturnType();
const ABIArgInfo &RetAI = CallInfo.getReturnInfo();
- llvm::FunctionType *IRFuncTy =
- cast<llvm::FunctionType>(
- cast<llvm::PointerType>(Callee->getType())->getElementType());
+ llvm::FunctionType *IRFuncTy = Callee.getFunctionType();
+
+ // 1. Set up the arguments.
// If we're using inalloca, insert the allocation after the stack save.
// FIXME: Do this earlier rather than hacking it in here!
Address swiftErrorTemp = Address::invalid();
Address swiftErrorArg = Address::invalid();
+ // Translate all of the arguments as necessary to match the IR lowering.
assert(CallInfo.arg_size() == CallArgs.size() &&
"Mismatch between function signature & arguments.");
unsigned ArgNo = 0;
}
}
+ llvm::Value *CalleePtr = Callee.getFunctionPointer();
+
+ // If we're using inalloca, set up that argument.
if (ArgMemory.isValid()) {
llvm::Value *Arg = ArgMemory.getPointer();
if (CallInfo.isVariadic()) {
// end up with a variadic prototype and an inalloca call site. In such
// cases, we can't do any parameter mismatch checks. Give up and bitcast
// the callee.
- unsigned CalleeAS =
- cast<llvm::PointerType>(Callee->getType())->getAddressSpace();
- Callee = Builder.CreateBitCast(
- Callee, getTypes().GetFunctionType(CallInfo)->getPointerTo(CalleeAS));
+ unsigned CalleeAS = CalleePtr->getType()->getPointerAddressSpace();
+ auto FnTy = getTypes().GetFunctionType(CallInfo)->getPointerTo(CalleeAS);
+ CalleePtr = Builder.CreateBitCast(CalleePtr, FnTy);
} else {
llvm::Type *LastParamTy =
IRFuncTy->getParamType(IRFuncTy->getNumParams() - 1);
IRCallArgs[IRFunctionArgs.getInallocaArgNo()] = Arg;
}
- if (!CallArgs.getCleanupsToDeactivate().empty())
- deactivateArgCleanupsBeforeCall(*this, CallArgs);
+ // 2. Prepare the function pointer.
+
+ // If the callee is a bitcast of a non-variadic function to have a
+ // variadic function pointer type, check to see if we can remove the
+ // bitcast. This comes up with unprototyped functions.
+ //
+ // This makes the IR nicer, but more importantly it ensures that we
+ // can inline the function at -O0 if it is marked always_inline.
+ auto simplifyVariadicCallee = [](llvm::Value *Ptr) -> llvm::Value* {
+ llvm::FunctionType *CalleeFT =
+ cast<llvm::FunctionType>(Ptr->getType()->getPointerElementType());
+ if (!CalleeFT->isVarArg())
+ return Ptr;
+
+ llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Ptr);
+ if (!CE || CE->getOpcode() != llvm::Instruction::BitCast)
+ return Ptr;
+
+ llvm::Function *OrigFn = dyn_cast<llvm::Function>(CE->getOperand(0));
+ if (!OrigFn)
+ return Ptr;
+
+ llvm::FunctionType *OrigFT = OrigFn->getFunctionType();
+
+ // If the original type is variadic, or if any of the component types
+ // disagree, we cannot remove the cast.
+ if (OrigFT->isVarArg() ||
+ OrigFT->getNumParams() != CalleeFT->getNumParams() ||
+ OrigFT->getReturnType() != CalleeFT->getReturnType())
+ return Ptr;
+
+ for (unsigned i = 0, e = OrigFT->getNumParams(); i != e; ++i)
+ if (OrigFT->getParamType(i) != CalleeFT->getParamType(i))
+ return Ptr;
+
+ return OrigFn;
+ };
+ CalleePtr = simplifyVariadicCallee(CalleePtr);
- // If the callee is a bitcast of a function to a varargs pointer to function
- // type, check to see if we can remove the bitcast. This handles some cases
- // with unprototyped functions.
- if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Callee))
- if (llvm::Function *CalleeF = dyn_cast<llvm::Function>(CE->getOperand(0))) {
- llvm::PointerType *CurPT=cast<llvm::PointerType>(Callee->getType());
- llvm::FunctionType *CurFT =
- cast<llvm::FunctionType>(CurPT->getElementType());
- llvm::FunctionType *ActualFT = CalleeF->getFunctionType();
-
- if (CE->getOpcode() == llvm::Instruction::BitCast &&
- ActualFT->getReturnType() == CurFT->getReturnType() &&
- ActualFT->getNumParams() == CurFT->getNumParams() &&
- ActualFT->getNumParams() == IRCallArgs.size() &&
- (CurFT->isVarArg() || !ActualFT->isVarArg())) {
- bool ArgsMatch = true;
- for (unsigned i = 0, e = ActualFT->getNumParams(); i != e; ++i)
- if (ActualFT->getParamType(i) != CurFT->getParamType(i)) {
- ArgsMatch = false;
- break;
- }
+ // 3. Perform the actual call.
- // Strip the cast if we can get away with it. This is a nice cleanup,
- // but also allows us to inline the function at -O0 if it is marked
- // always_inline.
- if (ArgsMatch)
- Callee = CalleeF;
- }
- }
+ // Deactivate any cleanups that we're supposed to do immediately before
+ // the call.
+ if (!CallArgs.getCleanupsToDeactivate().empty())
+ deactivateArgCleanupsBeforeCall(*this, CallArgs);
+ // Assert that the arguments we computed match up. The IR verifier
+ // will catch this, but this is a common enough source of problems
+ // during IRGen changes that it's way better for debugging to catch
+ // it ourselves here.
+#ifndef NDEBUG
assert(IRCallArgs.size() == IRFuncTy->getNumParams() || IRFuncTy->isVarArg());
for (unsigned i = 0; i < IRCallArgs.size(); ++i) {
// Inalloca argument can have different type.
if (i < IRFuncTy->getNumParams())
assert(IRCallArgs[i]->getType() == IRFuncTy->getParamType(i));
}
+#endif
+ // Compute the calling convention and attributes.
unsigned CallingConv;
CodeGen::AttributeListType AttributeList;
- CGM.ConstructAttributeList(Callee->getName(), CallInfo, CalleeInfo,
+ CGM.ConstructAttributeList(CalleePtr->getName(), CallInfo,
+ Callee.getAbstractInfo(),
AttributeList, CallingConv,
/*AttrOnCallSite=*/true);
llvm::AttributeSet Attrs = llvm::AttributeSet::get(getLLVMContext(),
AttributeList);
+ // Apply some call-site-specific attributes.
+ // TODO: work this into building the attribute set.
+
+ // Apply always_inline to all calls within flatten functions.
+ // FIXME: should this really take priority over __try, below?
+ if (CurCodeDecl && CurCodeDecl->hasAttr<FlattenAttr>() &&
+ !(Callee.getAbstractInfo().getCalleeDecl() &&
+ Callee.getAbstractInfo().getCalleeDecl()->hasAttr<NoInlineAttr>())) {
+ Attrs =
+ Attrs.addAttribute(getLLVMContext(),
+ llvm::AttributeSet::FunctionIndex,
+ llvm::Attribute::AlwaysInline);
+ }
+
+ // Disable inlining inside SEH __try blocks.
+ if (isSEHTryScope()) {
+ Attrs =
+ Attrs.addAttribute(getLLVMContext(), llvm::AttributeSet::FunctionIndex,
+ llvm::Attribute::NoInline);
+ }
+
+ // Decide whether to use a call or an invoke.
bool CannotThrow;
if (currentFunctionUsesSEHTry()) {
- // SEH cares about asynchronous exceptions, everything can "throw."
+ // SEH cares about asynchronous exceptions, so everything can "throw."
CannotThrow = false;
} else if (isCleanupPadScope() &&
EHPersonality::get(*this).isMSVCXXPersonality()) {
// The MSVC++ personality will implicitly terminate the program if an
- // exception is thrown. An unwind edge cannot be reached.
+ // exception is thrown during a cleanup outside of a try/catch.
+ // We don't need to model anything in IR to get this behavior.
CannotThrow = true;
} else {
- // Otherwise, nowunind callsites will never throw.
+ // Otherwise, nounwind call sites will never throw.
CannotThrow = Attrs.hasAttribute(llvm::AttributeSet::FunctionIndex,
llvm::Attribute::NoUnwind);
}
llvm::BasicBlock *InvokeDest = CannotThrow ? nullptr : getInvokeDest();
SmallVector<llvm::OperandBundleDef, 1> BundleList;
- getBundlesForFunclet(Callee, CurrentFuncletPad, BundleList);
+ getBundlesForFunclet(CalleePtr, CurrentFuncletPad, BundleList);
+ // Emit the actual call/invoke instruction.
llvm::CallSite CS;
if (!InvokeDest) {
- CS = Builder.CreateCall(Callee, IRCallArgs, BundleList);
+ CS = Builder.CreateCall(CalleePtr, IRCallArgs, BundleList);
} else {
llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
- CS = Builder.CreateInvoke(Callee, Cont, InvokeDest, IRCallArgs,
+ CS = Builder.CreateInvoke(CalleePtr, Cont, InvokeDest, IRCallArgs,
BundleList);
EmitBlock(Cont);
}
+ llvm::Instruction *CI = CS.getInstruction();
if (callOrInvoke)
- *callOrInvoke = CS.getInstruction();
-
- if (CurCodeDecl && CurCodeDecl->hasAttr<FlattenAttr>() &&
- !CS.hasFnAttr(llvm::Attribute::NoInline))
- Attrs =
- Attrs.addAttribute(getLLVMContext(), llvm::AttributeSet::FunctionIndex,
- llvm::Attribute::AlwaysInline);
-
- // Disable inlining inside SEH __try blocks.
- if (isSEHTryScope())
- Attrs =
- Attrs.addAttribute(getLLVMContext(), llvm::AttributeSet::FunctionIndex,
- llvm::Attribute::NoInline);
+ *callOrInvoke = CI;
+ // Apply the attributes and calling convention.
CS.setAttributes(Attrs);
CS.setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
+ // Apply various metadata.
+
+ if (!CI->getType()->isVoidTy())
+ CI->setName("call");
+
// Insert instrumentation or attach profile metadata at indirect call sites.
// For more details, see the comment before the definition of
// IPVK_IndirectCallTarget in InstrProfData.inc.
if (!CS.getCalledFunction())
PGO.valueProfile(Builder, llvm::IPVK_IndirectCallTarget,
- CS.getInstruction(), Callee);
+ CI, CalleePtr);
// In ObjC ARC mode with no ObjC ARC exception safety, tell the ARC
// optimizer it can aggressively ignore unwind edges.
if (CGM.getLangOpts().ObjCAutoRefCount)
- AddObjCARCExceptionMetadata(CS.getInstruction());
+ AddObjCARCExceptionMetadata(CI);
+
+ // Suppress tail calls if requested.
+ if (llvm::CallInst *Call = dyn_cast<llvm::CallInst>(CI)) {
+ const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl();
+ if (TargetDecl && TargetDecl->hasAttr<NotTailCalledAttr>())
+ Call->setTailCallKind(llvm::CallInst::TCK_NoTail);
+ }
+
+ // 4. Finish the call.
// If the call doesn't return, finish the basic block and clear the
- // insertion point; this allows the rest of IRgen to discard
+ // insertion point; this allows the rest of IRGen to discard
// unreachable code.
if (CS.doesNotReturn()) {
if (UnusedReturnSize)
return GetUndefRValue(RetTy);
}
- llvm::Instruction *CI = CS.getInstruction();
- if (!CI->getType()->isVoidTy())
- CI->setName("call");
-
// Perform the swifterror writeback.
if (swiftErrorTemp.isValid()) {
llvm::Value *errorResult = Builder.CreateLoad(swiftErrorTemp);
Builder.CreateStore(errorResult, swiftErrorArg);
}
- // Emit any writebacks immediately. Arguably this should happen
- // after any return-value munging.
+ // Emit any call-associated writebacks immediately. Arguably this
+ // should happen after any return-value munging.
if (CallArgs.hasWritebacks())
emitWritebacks(*this, CallArgs);
// lexical order, so deactivate it and run it manually here.
CallArgs.freeArgumentMemory(*this);
- if (llvm::CallInst *Call = dyn_cast<llvm::CallInst>(CI)) {
- const Decl *TargetDecl = CalleeInfo.getCalleeDecl();
- if (TargetDecl && TargetDecl->hasAttr<NotTailCalledAttr>())
- Call->setTailCallKind(llvm::CallInst::TCK_NoTail);
- }
-
+ // Extract the return value.
RValue Ret = [&] {
switch (RetAI.getKind()) {
case ABIArgInfo::CoerceAndExpand: {
llvm_unreachable("Unhandled ABIArgInfo::Kind");
} ();
- const Decl *TargetDecl = CalleeInfo.getCalleeDecl();
-
+ // Emit the assume_aligned check on the return value.
+ const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl();
if (Ret.isScalar() && TargetDecl) {
if (const auto *AA = TargetDecl->getAttr<AssumeAlignedAttr>()) {
llvm::Value *OffsetValue = nullptr;
namespace CodeGen {
typedef SmallVector<llvm::AttributeSet, 8> AttributeListType;
+ /// Abstract information about a function or function prototype.
+ class CGCalleeInfo {
+ /// \brief The function prototype of the callee.
+ const FunctionProtoType *CalleeProtoTy;
+ /// \brief The function declaration of the callee.
+ const Decl *CalleeDecl;
+
+ public:
+ explicit CGCalleeInfo() : CalleeProtoTy(nullptr), CalleeDecl(nullptr) {}
+ CGCalleeInfo(const FunctionProtoType *calleeProtoTy, const Decl *calleeDecl)
+ : CalleeProtoTy(calleeProtoTy), CalleeDecl(calleeDecl) {}
+ CGCalleeInfo(const FunctionProtoType *calleeProtoTy)
+ : CalleeProtoTy(calleeProtoTy), CalleeDecl(nullptr) {}
+ CGCalleeInfo(const Decl *calleeDecl)
+ : CalleeProtoTy(nullptr), CalleeDecl(calleeDecl) {}
+
+ const FunctionProtoType *getCalleeFunctionProtoType() const {
+ return CalleeProtoTy;
+ }
+ const Decl *getCalleeDecl() const { return CalleeDecl; }
+ };
+
+ /// All available information about a concrete callee.
+ class CGCallee {
+ enum class SpecialKind : uintptr_t {
+ Invalid,
+ Builtin,
+ PseudoDestructor,
+
+ Last = PseudoDestructor
+ };
+
+ SpecialKind KindOrFunctionPointer;
+ union {
+ CGCalleeInfo AbstractInfo;
+ struct {
+ const FunctionDecl *Decl;
+ unsigned ID;
+ } BuiltinInfo;
+ struct {
+ const CXXPseudoDestructorExpr *Expr;
+ } PseudoDestructorInfo;
+ };
+
+ explicit CGCallee(SpecialKind kind) : KindOrFunctionPointer(kind) {}
+
+ CGCallee(const FunctionDecl *builtinDecl, unsigned builtinID)
+ : KindOrFunctionPointer(SpecialKind::Builtin) {
+ BuiltinInfo.Decl = builtinDecl;
+ BuiltinInfo.ID = builtinID;
+ }
+
+ public:
+ CGCallee() : KindOrFunctionPointer(SpecialKind::Invalid) {}
+
+ /// Construct a callee. Call this constructor directly when this
+ /// isn't a direct call.
+ CGCallee(const CGCalleeInfo &abstractInfo, llvm::Value *functionPtr)
+ : KindOrFunctionPointer(SpecialKind(uintptr_t(functionPtr))) {
+ AbstractInfo = abstractInfo;
+ assert(functionPtr && "configuring callee without function pointer");
+ assert(functionPtr->getType()->isPointerTy());
+ assert(functionPtr->getType()->getPointerElementType()->isFunctionTy());
+ }
+
+ static CGCallee forBuiltin(unsigned builtinID,
+ const FunctionDecl *builtinDecl) {
+ CGCallee result(SpecialKind::Builtin);
+ result.BuiltinInfo.Decl = builtinDecl;
+ result.BuiltinInfo.ID = builtinID;
+ return result;
+ }
+
+ static CGCallee forPseudoDestructor(const CXXPseudoDestructorExpr *E) {
+ CGCallee result(SpecialKind::PseudoDestructor);
+ result.PseudoDestructorInfo.Expr = E;
+ return result;
+ }
+
+ static CGCallee forDirect(llvm::Constant *functionPtr,
+ const CGCalleeInfo &abstractInfo = CGCalleeInfo()) {
+ return CGCallee(abstractInfo, functionPtr);
+ }
+
+ bool isBuiltin() const {
+ return KindOrFunctionPointer == SpecialKind::Builtin;
+ }
+ const FunctionDecl *getBuiltinDecl() const {
+ assert(isBuiltin());
+ return BuiltinInfo.Decl;
+ }
+ unsigned getBuiltinID() const {
+ assert(isBuiltin());
+ return BuiltinInfo.ID;
+ }
+
+ bool isPseudoDestructor() const {
+ return KindOrFunctionPointer == SpecialKind::PseudoDestructor;
+ }
+ const CXXPseudoDestructorExpr *getPseudoDestructorExpr() const {
+ assert(isPseudoDestructor());
+ return PseudoDestructorInfo.Expr;
+ }
+
+ bool isOrdinary() const {
+ return uintptr_t(KindOrFunctionPointer) > uintptr_t(SpecialKind::Last);
+ }
+ const CGCalleeInfo &getAbstractInfo() const {
+ assert(isOrdinary());
+ return AbstractInfo;
+ }
+ llvm::Value *getFunctionPointer() const {
+ assert(isOrdinary());
+ return reinterpret_cast<llvm::Value*>(uintptr_t(KindOrFunctionPointer));
+ }
+ llvm::FunctionType *getFunctionType() const {
+ return cast<llvm::FunctionType>(
+ getFunctionPointer()->getType()->getPointerElementType());
+ }
+ void setFunctionPointer(llvm::Value *functionPtr) {
+ assert(isOrdinary());
+ KindOrFunctionPointer = SpecialKind(uintptr_t(functionPtr));
+ }
+ };
+
struct CallArg {
RValue RV;
QualType Ty;
*this, D, Type, ForVirtualBase, Delegating, Args);
// Emit the call.
- llvm::Value *Callee = CGM.getAddrOfCXXStructor(D, getFromCtorType(Type));
+ llvm::Constant *CalleePtr =
+ CGM.getAddrOfCXXStructor(D, getFromCtorType(Type));
const CGFunctionInfo &Info =
- CGM.getTypes().arrangeCXXConstructorCall(Args, D, Type, ExtraArgs);
- EmitCall(Info, Callee, ReturnValueSlot(), Args, D);
+ CGM.getTypes().arrangeCXXConstructorCall(Args, D, Type, ExtraArgs);
+ CGCallee Callee = CGCallee::forDirect(CalleePtr, D);
+ EmitCall(Info, Callee, ReturnValueSlot(), Args);
// Generate vtable assumptions if we're constructing a complete object
// with a vtable. We don't do this for base subobjects for two reasons:
// Get the address of the call operator.
const CGFunctionInfo &calleeFnInfo =
CGM.getTypes().arrangeCXXMethodDeclaration(callOperator);
- llvm::Value *callee =
+ llvm::Constant *calleePtr =
CGM.GetAddrOfFunction(GlobalDecl(callOperator),
CGM.getTypes().GetFunctionType(calleeFnInfo));
// variadic arguments.
// Now emit our call.
- RValue RV = EmitCall(calleeFnInfo, callee, returnSlot,
- callArgs, callOperator);
+ auto callee = CGCallee::forDirect(calleePtr, callOperator);
+ RValue RV = EmitCall(calleeFnInfo, callee, returnSlot, callArgs);
// If necessary, copy the returned value into the slot.
if (!resultType->isVoidType() && returnSlot.isNull())
CallArgList Args;
Args.add(RValue::get(Arg),
CGF.getContext().getPointerType(Var.getType()));
- CGF.EmitCall(FnInfo, CleanupFn, ReturnValueSlot(), Args);
+ auto Callee = CGCallee::forDirect(CleanupFn);
+ CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args);
}
};
} // end anonymous namespace
const CGFunctionInfo &FnInfo =
CGM.getTypes().arrangeBuiltinFunctionCall(Context.VoidTy, Args);
- CGF.EmitCall(FnInfo, OutlinedFinally, ReturnValueSlot(), Args);
+ auto Callee = CGCallee::forDirect(OutlinedFinally);
+ CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args);
}
};
} // end anonymous namespace
return LV;
}
-static LValue EmitFunctionDeclLValue(CodeGenFunction &CGF,
- const Expr *E, const FunctionDecl *FD) {
- llvm::Value *V = CGF.CGM.GetAddrOfFunction(FD);
+static llvm::Constant *EmitFunctionDeclPointer(CodeGenModule &CGM,
+ const FunctionDecl *FD) {
+ if (FD->hasAttr<WeakRefAttr>()) {
+ ConstantAddress aliasee = CGM.GetWeakRefReference(FD);
+ return aliasee.getPointer();
+ }
+
+ llvm::Constant *V = CGM.GetAddrOfFunction(FD);
if (!FD->hasPrototype()) {
if (const FunctionProtoType *Proto =
FD->getType()->getAs<FunctionProtoType>()) {
// isn't the same as the type of a use. Correct for this with a
// bitcast.
QualType NoProtoType =
- CGF.getContext().getFunctionNoProtoType(Proto->getReturnType());
- NoProtoType = CGF.getContext().getPointerType(NoProtoType);
- V = CGF.Builder.CreateBitCast(V, CGF.ConvertType(NoProtoType));
+ CGM.getContext().getFunctionNoProtoType(Proto->getReturnType());
+ NoProtoType = CGM.getContext().getPointerType(NoProtoType);
+ V = llvm::ConstantExpr::getBitCast(V,
+ CGM.getTypes().ConvertType(NoProtoType));
}
}
+ return V;
+}
+
+static LValue EmitFunctionDeclLValue(CodeGenFunction &CGF,
+ const Expr *E, const FunctionDecl *FD) {
+ llvm::Value *V = EmitFunctionDeclPointer(CGF.CGM, FD);
CharUnits Alignment = CGF.getContext().getDeclAlign(FD);
return CGF.MakeAddrLValue(V, E->getType(), Alignment, AlignmentSource::Decl);
}
if (const auto *CE = dyn_cast<CUDAKernelCallExpr>(E))
return EmitCUDAKernelCallExpr(CE, ReturnValue);
- const Decl *TargetDecl = E->getCalleeDecl();
- if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
- if (unsigned builtinID = FD->getBuiltinID())
- return EmitBuiltinExpr(FD, builtinID, E, ReturnValue);
- }
-
if (const auto *CE = dyn_cast<CXXOperatorCallExpr>(E))
- if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(TargetDecl))
+ if (const CXXMethodDecl *MD =
+ dyn_cast_or_null<CXXMethodDecl>(CE->getCalleeDecl()))
return EmitCXXOperatorMemberCallExpr(CE, MD, ReturnValue);
- if (const auto *PseudoDtor =
- dyn_cast<CXXPseudoDestructorExpr>(E->getCallee()->IgnoreParens())) {
- QualType DestroyedType = PseudoDtor->getDestroyedType();
- if (DestroyedType.hasStrongOrWeakObjCLifetime()) {
- // Automatic Reference Counting:
- // If the pseudo-expression names a retainable object with weak or
- // strong lifetime, the object shall be released.
- Expr *BaseExpr = PseudoDtor->getBase();
- Address BaseValue = Address::invalid();
- Qualifiers BaseQuals;
-
- // If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar.
- if (PseudoDtor->isArrow()) {
- BaseValue = EmitPointerWithAlignment(BaseExpr);
- const PointerType *PTy = BaseExpr->getType()->getAs<PointerType>();
- BaseQuals = PTy->getPointeeType().getQualifiers();
- } else {
- LValue BaseLV = EmitLValue(BaseExpr);
- BaseValue = BaseLV.getAddress();
- QualType BaseTy = BaseExpr->getType();
- BaseQuals = BaseTy.getQualifiers();
- }
+ CGCallee callee = EmitCallee(E->getCallee());
- switch (DestroyedType.getObjCLifetime()) {
- case Qualifiers::OCL_None:
- case Qualifiers::OCL_ExplicitNone:
- case Qualifiers::OCL_Autoreleasing:
- break;
+ if (callee.isBuiltin()) {
+ return EmitBuiltinExpr(callee.getBuiltinDecl(), callee.getBuiltinID(),
+ E, ReturnValue);
+ }
- case Qualifiers::OCL_Strong:
- EmitARCRelease(Builder.CreateLoad(BaseValue,
- PseudoDtor->getDestroyedType().isVolatileQualified()),
- ARCPreciseLifetime);
- break;
+ if (callee.isPseudoDestructor()) {
+ return EmitCXXPseudoDestructorExpr(callee.getPseudoDestructorExpr());
+ }
- case Qualifiers::OCL_Weak:
- EmitARCDestroyWeak(BaseValue);
- break;
- }
- } else {
- // C++ [expr.pseudo]p1:
- // The result shall only be used as the operand for the function call
- // operator (), and the result of such a call has type void. The only
- // effect is the evaluation of the postfix-expression before the dot or
- // arrow.
- EmitScalarExpr(E->getCallee());
+ return EmitCall(E->getCallee()->getType(), callee, E, ReturnValue);
+}
+
+/// Emit a CallExpr without considering whether it might be a subclass.
+RValue CodeGenFunction::EmitSimpleCallExpr(const CallExpr *E,
+ ReturnValueSlot ReturnValue) {
+ CGCallee Callee = EmitCallee(E->getCallee());
+ return EmitCall(E->getCallee()->getType(), Callee, E, ReturnValue);
+}
+
+static CGCallee EmitDirectCallee(CodeGenFunction &CGF, const FunctionDecl *FD) {
+ if (auto builtinID = FD->getBuiltinID()) {
+ return CGCallee::forBuiltin(builtinID, FD);
+ }
+
+ llvm::Constant *calleePtr = EmitFunctionDeclPointer(CGF.CGM, FD);
+ return CGCallee::forDirect(calleePtr, FD);
+}
+
+CGCallee CodeGenFunction::EmitCallee(const Expr *E) {
+ E = E->IgnoreParens();
+
+ // Look through function-to-pointer decay.
+ if (auto ICE = dyn_cast<ImplicitCastExpr>(E)) {
+ if (ICE->getCastKind() == CK_FunctionToPointerDecay ||
+ ICE->getCastKind() == CK_BuiltinFnToFnPtr) {
+ return EmitCallee(ICE->getSubExpr());
}
- return RValue::get(nullptr);
+ // Resolve direct calls.
+ } else if (auto DRE = dyn_cast<DeclRefExpr>(E)) {
+ if (auto FD = dyn_cast<FunctionDecl>(DRE->getDecl())) {
+ return EmitDirectCallee(*this, FD);
+ }
+ } else if (auto ME = dyn_cast<MemberExpr>(E)) {
+ if (auto FD = dyn_cast<FunctionDecl>(ME->getMemberDecl())) {
+ EmitIgnoredExpr(ME->getBase());
+ return EmitDirectCallee(*this, FD);
+ }
+
+ // Look through template substitutions.
+ } else if (auto NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
+ return EmitCallee(NTTP->getReplacement());
+
+ // Treat pseudo-destructor calls differently.
+ } else if (auto PDE = dyn_cast<CXXPseudoDestructorExpr>(E)) {
+ return CGCallee::forPseudoDestructor(PDE);
}
- llvm::Value *Callee = EmitScalarExpr(E->getCallee());
- return EmitCall(E->getCallee()->getType(), Callee, E, ReturnValue,
- TargetDecl);
+ // Otherwise, we have an indirect reference.
+ llvm::Value *calleePtr;
+ QualType functionType;
+ if (auto ptrType = E->getType()->getAs<PointerType>()) {
+ calleePtr = EmitScalarExpr(E);
+ functionType = ptrType->getPointeeType();
+ } else {
+ functionType = E->getType();
+ calleePtr = EmitLValue(E).getPointer();
+ }
+ assert(functionType->isFunctionType());
+ CGCalleeInfo calleeInfo(functionType->getAs<FunctionProtoType>(),
+ E->getReferencedDeclOfCallee());
+ CGCallee callee(calleeInfo, calleePtr);
+ return callee;
}
LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {
AlignmentSource::Decl);
}
-RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
+RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee,
const CallExpr *E, ReturnValueSlot ReturnValue,
- CGCalleeInfo CalleeInfo, llvm::Value *Chain) {
+ llvm::Value *Chain) {
// Get the actual function type. The callee type will always be a pointer to
// function type or a block pointer type.
assert(CalleeType->isFunctionPointerType() &&
"Call must have function pointer type!");
- // Preserve the non-canonical function type because things like exception
- // specifications disappear in the canonical type. That information is useful
- // to drive the generation of more accurate code for this call later on.
- const FunctionProtoType *NonCanonicalFTP = CalleeType->getAs<PointerType>()
- ->getPointeeType()
- ->getAs<FunctionProtoType>();
-
- const Decl *TargetDecl = CalleeInfo.getCalleeDecl();
+ const Decl *TargetDecl = OrigCallee.getAbstractInfo().getCalleeDecl();
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
// We can only guarantee that a function is called from the correct
const auto *FnType =
cast<FunctionType>(cast<PointerType>(CalleeType)->getPointeeType());
+ CGCallee Callee = OrigCallee;
+
if (getLangOpts().CPlusPlus && SanOpts.has(SanitizerKind::Function) &&
(!TargetDecl || !isa<FunctionDecl>(TargetDecl))) {
if (llvm::Constant *PrefixSig =
llvm::StructType *PrefixStructTy = llvm::StructType::get(
CGM.getLLVMContext(), PrefixStructTyElems, /*isPacked=*/true);
+ llvm::Value *CalleePtr = Callee.getFunctionPointer();
+
llvm::Value *CalleePrefixStruct = Builder.CreateBitCast(
- Callee, llvm::PointerType::getUnqual(PrefixStructTy));
+ CalleePtr, llvm::PointerType::getUnqual(PrefixStructTy));
llvm::Value *CalleeSigPtr =
Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, 0, 0);
llvm::Value *CalleeSig =
EmitCheckTypeDescriptor(CalleeType)
};
EmitCheck(std::make_pair(CalleeRTTIMatch, SanitizerKind::Function),
- "function_type_mismatch", StaticData, Callee);
+ "function_type_mismatch", StaticData, CalleePtr);
Builder.CreateBr(Cont);
EmitBlock(Cont);
llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(QualType(FnType, 0));
llvm::Value *TypeId = llvm::MetadataAsValue::get(getLLVMContext(), MD);
- llvm::Value *CastedCallee = Builder.CreateBitCast(Callee, Int8PtrTy);
+ llvm::Value *CalleePtr = Callee.getFunctionPointer();
+ llvm::Value *CastedCallee = Builder.CreateBitCast(CalleePtr, Int8PtrTy);
llvm::Value *TypeTest = Builder.CreateCall(
CGM.getIntrinsic(llvm::Intrinsic::type_test), {CastedCallee, TypeId});
if (isa<FunctionNoProtoType>(FnType) || Chain) {
llvm::Type *CalleeTy = getTypes().GetFunctionType(FnInfo);
CalleeTy = CalleeTy->getPointerTo();
- Callee = Builder.CreateBitCast(Callee, CalleeTy, "callee.knr.cast");
+
+ llvm::Value *CalleePtr = Callee.getFunctionPointer();
+ CalleePtr = Builder.CreateBitCast(CalleePtr, CalleeTy, "callee.knr.cast");
+ Callee.setFunctionPointer(CalleePtr);
}
- return EmitCall(FnInfo, Callee, ReturnValue, Args,
- CGCalleeInfo(NonCanonicalFTP, TargetDecl));
+ return EmitCall(FnInfo, Callee, ReturnValue, Args);
}
LValue CodeGenFunction::
}
RValue CodeGenFunction::EmitCXXMemberOrOperatorCall(
- const CXXMethodDecl *MD, llvm::Value *Callee, ReturnValueSlot ReturnValue,
+ const CXXMethodDecl *MD, const CGCallee &Callee,
+ ReturnValueSlot ReturnValue,
llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy,
const CallExpr *CE, CallArgList *RtlArgs) {
const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
CallArgList Args;
RequiredArgs required = commonEmitCXXMemberOrOperatorCall(
*this, MD, This, ImplicitParam, ImplicitParamTy, CE, Args, RtlArgs);
- return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required),
- Callee, ReturnValue, Args, MD);
+ auto &FnInfo = CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required);
+ return EmitCall(FnInfo, Callee, ReturnValue, Args);
}
RValue CodeGenFunction::EmitCXXDestructorCall(
- const CXXDestructorDecl *DD, llvm::Value *Callee, llvm::Value *This,
+ const CXXDestructorDecl *DD, const CGCallee &Callee, llvm::Value *This,
llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *CE,
StructorType Type) {
CallArgList Args;
commonEmitCXXMemberOrOperatorCall(*this, DD, This, ImplicitParam,
ImplicitParamTy, CE, Args, nullptr);
return EmitCall(CGM.getTypes().arrangeCXXStructorDeclaration(DD, Type),
- Callee, ReturnValueSlot(), Args, DD);
+ Callee, ReturnValueSlot(), Args);
+}
+
+RValue CodeGenFunction::EmitCXXPseudoDestructorExpr(
+ const CXXPseudoDestructorExpr *E) {
+ QualType DestroyedType = E->getDestroyedType();
+ if (DestroyedType.hasStrongOrWeakObjCLifetime()) {
+ // Automatic Reference Counting:
+ // If the pseudo-expression names a retainable object with weak or
+ // strong lifetime, the object shall be released.
+ Expr *BaseExpr = E->getBase();
+ Address BaseValue = Address::invalid();
+ Qualifiers BaseQuals;
+
+ // If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar.
+ if (E->isArrow()) {
+ BaseValue = EmitPointerWithAlignment(BaseExpr);
+ const PointerType *PTy = BaseExpr->getType()->getAs<PointerType>();
+ BaseQuals = PTy->getPointeeType().getQualifiers();
+ } else {
+ LValue BaseLV = EmitLValue(BaseExpr);
+ BaseValue = BaseLV.getAddress();
+ QualType BaseTy = BaseExpr->getType();
+ BaseQuals = BaseTy.getQualifiers();
+ }
+
+ switch (DestroyedType.getObjCLifetime()) {
+ case Qualifiers::OCL_None:
+ case Qualifiers::OCL_ExplicitNone:
+ case Qualifiers::OCL_Autoreleasing:
+ break;
+
+ case Qualifiers::OCL_Strong:
+ EmitARCRelease(Builder.CreateLoad(BaseValue,
+ DestroyedType.isVolatileQualified()),
+ ARCPreciseLifetime);
+ break;
+
+ case Qualifiers::OCL_Weak:
+ EmitARCDestroyWeak(BaseValue);
+ break;
+ }
+ } else {
+ // C++ [expr.pseudo]p1:
+ // The result shall only be used as the operand for the function call
+ // operator (), and the result of such a call has type void. The only
+ // effect is the evaluation of the postfix-expression before the dot or
+ // arrow.
+ EmitIgnoredExpr(E->getBase());
+ }
+
+ return RValue::get(nullptr);
}
static CXXRecordDecl *getCXXRecord(const Expr *E) {
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, CE,
+ CGCallee callee = CGCallee::forDirect(CGM.GetAddrOfFunction(MD), MD);
+ return EmitCall(getContext().getPointerType(MD->getType()), callee, CE,
ReturnValue);
}
// 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");
CGM.getCXXABI().EmitVirtualDestructorCall(
*this, Dtor, Dtor_Complete, This, cast<CXXMemberCallExpr>(CE));
} else {
+ CGCallee Callee;
if (getLangOpts().AppleKext && MD->isVirtual() && HasQualifier)
Callee = BuildAppleKextVirtualCall(MD, Qualifier, Ty);
else if (!DevirtualizedMethod)
- Callee =
- CGM.getAddrOfCXXStructor(Dtor, StructorType::Complete, FInfo, Ty);
+ Callee = CGCallee::forDirect(
+ CGM.getAddrOfCXXStructor(Dtor, StructorType::Complete, FInfo, Ty),
+ Dtor);
else {
const CXXDestructorDecl *DDtor =
cast<CXXDestructorDecl>(DevirtualizedMethod);
- Callee = CGM.GetAddrOfFunction(GlobalDecl(DDtor, Dtor_Complete), Ty);
+ Callee = CGCallee::forDirect(
+ CGM.GetAddrOfFunction(GlobalDecl(DDtor, Dtor_Complete), Ty),
+ DDtor);
}
EmitCXXMemberOrOperatorCall(
CalleeDecl, Callee, ReturnValue, This.getPointer(),
return RValue::get(nullptr);
}
+ CGCallee Callee;
if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(MD)) {
- Callee = CGM.GetAddrOfFunction(GlobalDecl(Ctor, Ctor_Complete), Ty);
+ Callee = CGCallee::forDirect(
+ CGM.GetAddrOfFunction(GlobalDecl(Ctor, Ctor_Complete), Ty),
+ Ctor);
} else if (UseVirtualCall) {
Callee = CGM.getCXXABI().getVirtualFunctionPointer(*this, MD, This, Ty,
CE->getLocStart());
if (getLangOpts().AppleKext && MD->isVirtual() && HasQualifier)
Callee = BuildAppleKextVirtualCall(MD, Qualifier, Ty);
else if (!DevirtualizedMethod)
- Callee = CGM.GetAddrOfFunction(MD, Ty);
+ Callee = CGCallee::forDirect(CGM.GetAddrOfFunction(MD, Ty), MD);
else {
- Callee = CGM.GetAddrOfFunction(DevirtualizedMethod, Ty);
+ Callee = CGCallee::forDirect(
+ CGM.GetAddrOfFunction(DevirtualizedMethod, Ty),
+ DevirtualizedMethod);
}
}
// Ask the ABI to load the callee. Note that This is modified.
llvm::Value *ThisPtrForCall = nullptr;
- llvm::Value *Callee =
+ CGCallee Callee =
CGM.getCXXABI().EmitLoadOfMemberFunctionPointer(*this, BO, This,
ThisPtrForCall, MemFnPtr, MPT);
/// 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 FunctionDecl *CalleeDecl,
const FunctionProtoType *CalleeType,
const CallArgList &Args) {
llvm::Instruction *CallOrInvoke;
- llvm::Value *CalleeAddr = CGF.CGM.GetAddrOfFunction(Callee);
+ llvm::Constant *CalleePtr = CGF.CGM.GetAddrOfFunction(CalleeDecl);
+ CGCallee Callee = CGCallee::forDirect(CalleePtr, CalleeDecl);
RValue RV =
CGF.EmitCall(CGF.CGM.getTypes().arrangeFreeFunctionCall(
Args, CalleeType, /*chainCall=*/false),
- CalleeAddr, ReturnValueSlot(), Args, Callee, &CallOrInvoke);
+ Callee, ReturnValueSlot(), Args, &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() &&
+ llvm::Function *Fn = dyn_cast<llvm::Function>(CalleePtr);
+ if (CalleeDecl->isReplaceableGlobalAllocationFunction() &&
Fn && Fn->hasFnAttribute(llvm::Attribute::NoBuiltin)) {
// FIXME: Add addAttribute to CallSite.
if (llvm::CallInst *CI = dyn_cast<llvm::CallInst>(CallOrInvoke))
llvm::FunctionType *FTy = CGF.CGM.getTypes().GetFunctionType(FuncInfo);
llvm::Constant *Func = CGF.CGM.CreateBuiltinFunction(FTy, LibCallName);
- llvm::Instruction *Call;
+ CGCallee Callee = CGCallee::forDirect(Func, FQTy->getAs<FunctionProtoType>());
- RValue Res = CGF.EmitCall(FuncInfo, Func, ReturnValueSlot(), Args,
- FQTy->getAs<FunctionProtoType>(), &Call);
+ llvm::Instruction *Call;
+ RValue Res = CGF.EmitCall(FuncInfo, Callee, ReturnValueSlot(), Args, &Call);
cast<llvm::CallInst>(Call)->setCallingConv(CGF.CGM.getBuiltinCC());
return Res.getComplexVal();
}
args.add(RValue::get(CGF.Builder.getInt1(isAtomic)), Context.BoolTy);
args.add(RValue::get(CGF.Builder.getInt1(hasStrong)), Context.BoolTy);
- llvm::Value *fn = CGF.CGM.getObjCRuntime().GetGetStructFunction();
+ llvm::Constant *fn = CGF.CGM.getObjCRuntime().GetGetStructFunction();
+ CGCallee callee = CGCallee::forDirect(fn);
CGF.EmitCall(CGF.getTypes().arrangeBuiltinFunctionCall(Context.VoidTy, args),
- fn, ReturnValueSlot(), args);
+ callee, ReturnValueSlot(), args);
}
/// Determine whether the given architecture supports unaligned atomic
// Third argument is the helper function.
args.add(RValue::get(AtomicHelperFn), CGF.getContext().VoidPtrTy);
- llvm::Value *copyCppAtomicObjectFn =
+ llvm::Constant *copyCppAtomicObjectFn =
CGF.CGM.getObjCRuntime().GetCppAtomicObjectGetFunction();
+ CGCallee callee = CGCallee::forDirect(copyCppAtomicObjectFn);
CGF.EmitCall(
CGF.getTypes().arrangeBuiltinFunctionCall(CGF.getContext().VoidTy, args),
- copyCppAtomicObjectFn, ReturnValueSlot(), args);
+ callee, ReturnValueSlot(), args);
}
void
}
case PropertyImplStrategy::GetSetProperty: {
- llvm::Value *getPropertyFn =
+ llvm::Constant *getPropertyFn =
CGM.getObjCRuntime().GetPropertyGetFunction();
if (!getPropertyFn) {
CGM.ErrorUnsupported(propImpl, "Obj-C getter requiring atomic copy");
return;
}
+ CGCallee callee = CGCallee::forDirect(getPropertyFn);
// Return (ivar-type) objc_getProperty((id) self, _cmd, offset, true).
// FIXME: Can't this be simpler? This might even be worse than the
llvm::Instruction *CallInstruction;
RValue RV = EmitCall(
getTypes().arrangeBuiltinFunctionCall(propType, args),
- getPropertyFn, ReturnValueSlot(), args, CGCalleeInfo(),
- &CallInstruction);
+ callee, ReturnValueSlot(), args, &CallInstruction);
if (llvm::CallInst *call = dyn_cast<llvm::CallInst>(CallInstruction))
call->setTailCall();
// FIXME: should this really always be false?
args.add(RValue::get(CGF.Builder.getFalse()), CGF.getContext().BoolTy);
- llvm::Value *copyStructFn = CGF.CGM.getObjCRuntime().GetSetStructFunction();
+ llvm::Constant *fn = CGF.CGM.getObjCRuntime().GetSetStructFunction();
+ CGCallee callee = CGCallee::forDirect(fn);
CGF.EmitCall(
CGF.getTypes().arrangeBuiltinFunctionCall(CGF.getContext().VoidTy, args),
- copyStructFn, ReturnValueSlot(), args);
+ callee, ReturnValueSlot(), args);
}
/// emitCPPObjectAtomicSetterCall - Call the runtime function to store
// Third argument is the helper function.
args.add(RValue::get(AtomicHelperFn), CGF.getContext().VoidPtrTy);
- llvm::Value *copyCppAtomicObjectFn =
+ llvm::Constant *fn =
CGF.CGM.getObjCRuntime().GetCppAtomicObjectSetFunction();
+ CGCallee callee = CGCallee::forDirect(fn);
CGF.EmitCall(
CGF.getTypes().arrangeBuiltinFunctionCall(CGF.getContext().VoidTy, args),
- copyCppAtomicObjectFn, ReturnValueSlot(), args);
+ callee, ReturnValueSlot(), args);
}
case PropertyImplStrategy::GetSetProperty:
case PropertyImplStrategy::SetPropertyAndExpressionGet: {
- llvm::Value *setOptimizedPropertyFn = nullptr;
- llvm::Value *setPropertyFn = nullptr;
+ llvm::Constant *setOptimizedPropertyFn = nullptr;
+ llvm::Constant *setPropertyFn = nullptr;
if (UseOptimizedSetter(CGM)) {
// 10.8 and iOS 6.0 code and GC is off
setOptimizedPropertyFn =
if (setOptimizedPropertyFn) {
args.add(RValue::get(arg), getContext().getObjCIdType());
args.add(RValue::get(ivarOffset), getContext().getPointerDiffType());
+ CGCallee callee = CGCallee::forDirect(setOptimizedPropertyFn);
EmitCall(getTypes().arrangeBuiltinFunctionCall(getContext().VoidTy, args),
- setOptimizedPropertyFn, ReturnValueSlot(), args);
+ callee, ReturnValueSlot(), args);
} else {
args.add(RValue::get(ivarOffset), getContext().getPointerDiffType());
args.add(RValue::get(arg), getContext().getObjCIdType());
getContext().BoolTy);
// FIXME: We shouldn't need to get the function info here, the runtime
// already should have computed it to build the function.
+ CGCallee callee = CGCallee::forDirect(setPropertyFn);
EmitCall(getTypes().arrangeBuiltinFunctionCall(getContext().VoidTy, args),
- setPropertyFn, ReturnValueSlot(), args);
+ callee, ReturnValueSlot(), args);
}
return;
}
void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
- llvm::Constant *EnumerationMutationFn =
+ llvm::Constant *EnumerationMutationFnPtr =
CGM.getObjCRuntime().EnumerationMutationFunction();
-
- if (!EnumerationMutationFn) {
+ if (!EnumerationMutationFnPtr) {
CGM.ErrorUnsupported(&S, "Obj-C fast enumeration for this runtime");
return;
}
+ CGCallee EnumerationMutationFn =
+ CGCallee::forDirect(EnumerationMutationFnPtr);
CGDebugInfo *DI = getDebugInfo();
if (DI)
llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
+ CGCallee callee(CGCalleeInfo(), imp);
+
llvm::Instruction *call;
- RValue msgRet = CGF.EmitCall(MSI.CallInfo, imp, Return, ActualArgs,
- CGCalleeInfo(), &call);
+ RValue msgRet = CGF.EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
call->setMetadata(msgSendMDKind, node);
return msgRet;
}
imp = EnforceType(Builder, imp, MSI.MessengerType);
llvm::Instruction *call;
- RValue msgRet = CGF.EmitCall(MSI.CallInfo, imp, Return, ActualArgs,
- CGCalleeInfo(), &call);
+ CGCallee callee(CGCalleeInfo(), imp);
+ RValue msgRet = CGF.EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
call->setMetadata(msgSendMDKind, node);
llvm::Instruction *CallSite;
Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType);
- RValue rvalue = CGF.EmitCall(MSI.CallInfo, Fn, Return, ActualArgs,
- CGCalleeInfo(), &CallSite);
+ CGCallee Callee = CGCallee::forDirect(Fn);
+ RValue rvalue = CGF.EmitCall(MSI.CallInfo, Callee, Return, ActualArgs,
+ &CallSite);
// Mark the call as noreturn if the method is marked noreturn and the
// receiver cannot be null.
// Load the function to call from the message ref table.
Address calleeAddr =
CGF.Builder.CreateStructGEP(mref, 0, CharUnits::Zero());
- llvm::Value *callee = CGF.Builder.CreateLoad(calleeAddr, "msgSend_fn");
+ llvm::Value *calleePtr = CGF.Builder.CreateLoad(calleeAddr, "msgSend_fn");
- callee = CGF.Builder.CreateBitCast(callee, MSI.MessengerType);
+ calleePtr = CGF.Builder.CreateBitCast(calleePtr, MSI.MessengerType);
+ CGCallee callee(CGCalleeInfo(), calleePtr);
RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
return nullReturn.complete(CGF, result, resultType, formalArgs,
FinishFunction();
}
-void CodeGenFunction::EmitCallAndReturnForThunk(llvm::Value *Callee,
+void CodeGenFunction::EmitCallAndReturnForThunk(llvm::Constant *CalleePtr,
const ThunkInfo *Thunk) {
assert(isa<CXXMethodDecl>(CurGD.getDecl()) &&
"Please use a new CGF for this thunk");
CGM.ErrorUnsupported(
MD, "non-trivial argument copy for return-adjusting thunk");
}
- EmitMustTailThunk(MD, AdjustedThisPtr, Callee);
+ EmitMustTailThunk(MD, AdjustedThisPtr, CalleePtr);
return;
}
// Now emit our call.
llvm::Instruction *CallOrInvoke;
- RValue RV = EmitCall(*CurFnInfo, Callee, Slot, CallArgs, MD, &CallOrInvoke);
+ CGCallee Callee = CGCallee::forDirect(CalleePtr, MD);
+ RValue RV = EmitCall(*CurFnInfo, Callee, Slot, CallArgs, &CallOrInvoke);
// Consider return adjustment if we have ThunkInfo.
if (Thunk && !Thunk->Return.isEmpty())
void CodeGenFunction::EmitMustTailThunk(const CXXMethodDecl *MD,
llvm::Value *AdjustedThisPtr,
- llvm::Value *Callee) {
+ llvm::Value *CalleePtr) {
// Emitting a musttail call thunk doesn't use any of the CGCall.cpp machinery
// to translate AST arguments into LLVM IR arguments. For thunks, we know
// that the caller prototype more or less matches the callee prototype with
// Emit the musttail call manually. Even if the prologue pushed cleanups, we
// don't actually want to run them.
- llvm::CallInst *Call = Builder.CreateCall(Callee, Args);
+ llvm::CallInst *Call = Builder.CreateCall(CalleePtr, Args);
Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
// Apply the standard set of call attributes.
unsigned CallingConv;
CodeGen::AttributeListType AttributeList;
- CGM.ConstructAttributeList(Callee->getName(), *CurFnInfo, MD, AttributeList,
+ CGM.ConstructAttributeList(CalleePtr->getName(),
+ *CurFnInfo, MD, AttributeList,
CallingConv, /*AttrOnCallSite=*/true);
llvm::AttributeSet Attrs =
llvm::AttributeSet::get(getLLVMContext(), AttributeList);
// Get our callee.
llvm::Type *Ty =
CGM.getTypes().GetFunctionType(CGM.getTypes().arrangeGlobalDeclaration(GD));
- llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
+ llvm::Constant *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
// Make the call and return the result.
EmitCallAndReturnForThunk(Callee, &Thunk);
namespace CodeGen {
class CodeGenTypes;
+class CGCallee;
class CGFunctionInfo;
class CGRecordLayout;
class CGBlockInfo;
void StartThunk(llvm::Function *Fn, GlobalDecl GD,
const CGFunctionInfo &FnInfo);
- void EmitCallAndReturnForThunk(llvm::Value *Callee, const ThunkInfo *Thunk);
+ void EmitCallAndReturnForThunk(llvm::Constant *Callee,
+ const ThunkInfo *Thunk);
void FinishThunk();
/// EmitCall - Generate a call of the given function, expecting the given
/// result type, and using the given argument list which specifies both the
/// LLVM arguments and the types they were derived from.
- RValue EmitCall(const CGFunctionInfo &FnInfo, llvm::Value *Callee,
+ RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee,
ReturnValueSlot ReturnValue, const CallArgList &Args,
- CGCalleeInfo CalleeInfo = CGCalleeInfo(),
llvm::Instruction **callOrInvoke = nullptr);
- RValue EmitCall(QualType FnType, llvm::Value *Callee, const CallExpr *E,
+ RValue EmitCall(QualType FnType, const CGCallee &Callee, const CallExpr *E,
ReturnValueSlot ReturnValue,
- CGCalleeInfo CalleeInfo = CGCalleeInfo(),
llvm::Value *Chain = nullptr);
RValue EmitCallExpr(const CallExpr *E,
ReturnValueSlot ReturnValue = ReturnValueSlot());
+ RValue EmitSimpleCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue);
+ CGCallee EmitCallee(const Expr *E);
void checkTargetFeatures(const CallExpr *E, const FunctionDecl *TargetDecl);
void EmitNoreturnRuntimeCallOrInvoke(llvm::Value *callee,
ArrayRef<llvm::Value*> args);
- llvm::Value *BuildAppleKextVirtualCall(const CXXMethodDecl *MD,
- NestedNameSpecifier *Qual,
- llvm::Type *Ty);
+ CGCallee BuildAppleKextVirtualCall(const CXXMethodDecl *MD,
+ NestedNameSpecifier *Qual,
+ llvm::Type *Ty);
- llvm::Value *BuildAppleKextVirtualDestructorCall(const CXXDestructorDecl *DD,
- CXXDtorType Type,
- const CXXRecordDecl *RD);
+ CGCallee BuildAppleKextVirtualDestructorCall(const CXXDestructorDecl *DD,
+ CXXDtorType Type,
+ const CXXRecordDecl *RD);
RValue
- EmitCXXMemberOrOperatorCall(const CXXMethodDecl *MD, llvm::Value *Callee,
+ EmitCXXMemberOrOperatorCall(const CXXMethodDecl *Method,
+ const CGCallee &Callee,
ReturnValueSlot ReturnValue, llvm::Value *This,
llvm::Value *ImplicitParam,
QualType ImplicitParamTy, const CallExpr *E,
CallArgList *RtlArgs);
- RValue EmitCXXDestructorCall(const CXXDestructorDecl *DD, llvm::Value *Callee,
+ RValue EmitCXXDestructorCall(const CXXDestructorDecl *DD,
+ const CGCallee &Callee,
llvm::Value *This, llvm::Value *ImplicitParam,
QualType ImplicitParamTy, const CallExpr *E,
StructorType Type);
RValue EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
const CXXMethodDecl *MD,
ReturnValueSlot ReturnValue);
+ RValue EmitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
RValue EmitCUDAKernelCallExpr(const CUDAKernelCallExpr *E,
ReturnValueSlot ReturnValue);
/// Given a builtin id for a function like "__builtin_fabsf", return a
/// Function* for "fabsf".
- llvm::Value *getBuiltinLibFunction(const FunctionDecl *FD,
- unsigned BuiltinID);
+ llvm::Constant *getBuiltinLibFunction(const FunctionDecl *FD,
+ unsigned BuiltinID);
llvm::Function *getIntrinsic(unsigned IID, ArrayRef<llvm::Type*> Tys = None);
llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT) override;
- llvm::Value *
+ CGCallee
EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
const Expr *E,
Address This,
llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD,
CharUnits VPtrOffset) override;
- llvm::Value *getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
- Address This, llvm::Type *Ty,
- SourceLocation Loc) override;
+ CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
+ Address This, llvm::Type *Ty,
+ SourceLocation Loc) override;
llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
///
/// If the member is non-virtual, memptr.ptr is the address of
/// the function to call.
-llvm::Value *ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
+CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
CodeGenFunction &CGF, const Expr *E, Address ThisAddr,
llvm::Value *&ThisPtrForCall,
llvm::Value *MemFnPtr, const MemberPointerType *MPT) {
// We're done.
CGF.EmitBlock(FnEnd);
- llvm::PHINode *Callee = Builder.CreatePHI(FTy->getPointerTo(), 2);
- Callee->addIncoming(VirtualFn, FnVirtual);
- Callee->addIncoming(NonVirtualFn, FnNonVirtual);
+ llvm::PHINode *CalleePtr = Builder.CreatePHI(FTy->getPointerTo(), 2);
+ CalleePtr->addIncoming(VirtualFn, FnVirtual);
+ CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual);
+
+ CGCallee Callee(FPT, CalleePtr);
return Callee;
}
llvm::Value *VTT = CGF.GetVTTParameter(GD, ForVirtualBase, Delegating);
QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
- llvm::Value *Callee = nullptr;
- if (getContext().getLangOpts().AppleKext)
+ CGCallee Callee;
+ if (getContext().getLangOpts().AppleKext &&
+ Type != Dtor_Base && DD->isVirtual())
Callee = CGF.BuildAppleKextVirtualDestructorCall(DD, Type, DD->getParent());
-
- if (!Callee)
- Callee = CGM.getAddrOfCXXStructor(DD, getFromDtorType(Type));
+ else
+ Callee =
+ CGCallee::forDirect(CGM.getAddrOfCXXStructor(DD, getFromDtorType(Type)),
+ DD);
CGF.EmitCXXMemberOrOperatorCall(DD, Callee, ReturnValueSlot(),
This.getPointer(), VTT, VTTTy,
return VTable;
}
-llvm::Value *ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
- GlobalDecl GD,
- Address This,
- llvm::Type *Ty,
- SourceLocation Loc) {
+CGCallee ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
+ GlobalDecl GD,
+ Address This,
+ llvm::Type *Ty,
+ SourceLocation Loc) {
GD = GD.getCanonicalDecl();
Ty = Ty->getPointerTo()->getPointerTo();
auto *MethodDecl = cast<CXXMethodDecl>(GD.getDecl());
llvm::Value *VTable = CGF.GetVTablePtr(This, Ty, MethodDecl->getParent());
uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
+ llvm::Value *VFunc;
if (CGF.ShouldEmitVTableTypeCheckedLoad(MethodDecl->getParent())) {
- return CGF.EmitVTableTypeCheckedLoad(
+ VFunc = CGF.EmitVTableTypeCheckedLoad(
MethodDecl->getParent(), VTable,
VTableIndex * CGM.getContext().getTargetInfo().getPointerWidth(0) / 8);
} else {
llvm::Value *VFuncPtr =
CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfn");
- return CGF.Builder.CreateAlignedLoad(VFuncPtr, CGF.getPointerAlign());
+ VFunc = CGF.Builder.CreateAlignedLoad(VFuncPtr, CGF.getPointerAlign());
}
+
+ CGCallee Callee(MethodDecl, VFunc);
+ return Callee;
}
llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
Dtor, getFromDtorType(DtorType));
llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
- llvm::Value *Callee =
+ CGCallee Callee =
getVirtualFunctionPointer(CGF, GlobalDecl(Dtor, DtorType), This, Ty,
CE ? CE->getLocStart() : SourceLocation());
llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD,
CharUnits VPtrOffset) override;
- llvm::Value *getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
- Address This, llvm::Type *Ty,
- SourceLocation Loc) override;
+ CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
+ Address This, llvm::Type *Ty,
+ SourceLocation Loc) override;
llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
CastKind CK, CastExpr::path_const_iterator PathBegin,
CastExpr::path_const_iterator PathEnd, llvm::Constant *Src);
- llvm::Value *
+ CGCallee
EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, const Expr *E,
Address This, llvm::Value *&ThisPtrForCall,
llvm::Value *MemPtr,
const CXXDestructorDecl *DD,
CXXDtorType Type, bool ForVirtualBase,
bool Delegating, Address This) {
- llvm::Value *Callee = CGM.getAddrOfCXXStructor(DD, getFromDtorType(Type));
+ CGCallee Callee = CGCallee::forDirect(
+ CGM.getAddrOfCXXStructor(DD, getFromDtorType(Type)),
+ DD);
if (DD->isVirtual()) {
assert(Type != CXXDtorType::Dtor_Deleting &&
return getClassAtVTableLocation(Ctx, RD, ML.VFPtrOffset);
}
-llvm::Value *MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
- GlobalDecl GD,
- Address This,
- llvm::Type *Ty,
- SourceLocation Loc) {
+CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
+ GlobalDecl GD,
+ Address This,
+ llvm::Type *Ty,
+ SourceLocation Loc) {
GD = GD.getCanonicalDecl();
CGBuilderTy &Builder = CGF.Builder;
MicrosoftVTableContext::MethodVFTableLocation ML =
CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
+ llvm::Value *VFunc;
if (CGF.ShouldEmitVTableTypeCheckedLoad(MethodDecl->getParent())) {
- return CGF.EmitVTableTypeCheckedLoad(
+ VFunc = CGF.EmitVTableTypeCheckedLoad(
getClassAtVTableLocation(getContext(), GD, ML), VTable,
ML.Index * CGM.getContext().getTargetInfo().getPointerWidth(0) / 8);
} else {
llvm::Value *VFuncPtr =
Builder.CreateConstInBoundsGEP1_64(VTable, ML.Index, "vfn");
- return Builder.CreateAlignedLoad(VFuncPtr, CGF.getPointerAlign());
+ VFunc = Builder.CreateAlignedLoad(VFuncPtr, CGF.getPointerAlign());
}
+
+ CGCallee Callee(MethodDecl, VFunc);
+ return Callee;
}
llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
Dtor, StructorType::Deleting);
llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
- llvm::Value *Callee = getVirtualFunctionPointer(
+ CGCallee Callee = getVirtualFunctionPointer(
CGF, GD, This, Ty, CE ? CE->getLocStart() : SourceLocation());
ASTContext &Context = getContext();
return Dst;
}
-llvm::Value *MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
+CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
CodeGenFunction &CGF, const Expr *E, Address This,
llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr,
const MemberPointerType *MPT) {
"this.adjusted");
}
- return Builder.CreateBitCast(FunctionPointer, FTy->getPointerTo());
+ FunctionPointer =
+ Builder.CreateBitCast(FunctionPointer, FTy->getPointerTo());
+ CGCallee Callee(FPT, FunctionPointer);
+ return Callee;
}
CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
/*Delegating=*/false, Args);
// Call the destructor with our arguments.
- llvm::Value *CalleeFn = CGM.getAddrOfCXXStructor(CD, StructorType::Complete);
+ llvm::Constant *CalleePtr =
+ CGM.getAddrOfCXXStructor(CD, StructorType::Complete);
+ CGCallee Callee = CGCallee::forDirect(CalleePtr, CD);
const CGFunctionInfo &CalleeInfo = CGM.getTypes().arrangeCXXConstructorCall(
Args, CD, Ctor_Complete, ExtraArgs);
- CGF.EmitCall(CalleeInfo, CalleeFn, ReturnValueSlot(), Args, CD);
+ CGF.EmitCall(CalleeInfo, Callee, ReturnValueSlot(), Args);
Cleanups.ForceCleanup();