Refactor call emission to package the function pointer together with

abstract information about the callee.  NFC.

The goal here is to make it easier to recognize indirect calls and
trigger additional logic in certain cases.  That logic will come in
a later patch; in the meantime, I felt that this was a significant
improvement to the code.

llvm-svn: 285258
This commit is contained in:
John McCall 2016-10-26 23:46:34 +00:00
parent 48ef6ca0c3
commit b92ab1afd5
26 changed files with 638 additions and 359 deletions

View File

@ -445,6 +445,11 @@ public:
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;

View File

@ -664,29 +664,6 @@ public:
}
};
/// 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

View File

@ -1181,8 +1181,16 @@ void CallExpr::updateDependenciesFromArg(Expr *Arg) {
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)) {
@ -1205,10 +1213,6 @@ Decl *CallExpr::getCalleeDecl() {
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.

View File

@ -307,7 +307,8 @@ static RValue emitAtomicLibcall(CodeGenFunction &CGF,
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?

View File

@ -975,25 +975,24 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
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();
@ -1013,8 +1012,11 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
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,

View File

@ -37,8 +37,8 @@ using namespace llvm;
/// 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).
@ -304,10 +304,10 @@ static Value *EmitSignBit(CodeGenFunction &CGF, Value *V) {
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.*
@ -1570,7 +1570,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
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: {
@ -2085,8 +2086,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
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:
@ -2692,7 +2693,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
// 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.

View File

@ -36,16 +36,7 @@ RValue CGCUDARuntime::EmitCUDAKernelCallExpr(CodeGenFunction &CGF,
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);

View File

@ -258,10 +258,10 @@ llvm::Constant *CodeGenModule::getAddrOfCXXStructor(
/*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();
@ -277,16 +277,19 @@ static llvm::Value *BuildAppleKextVirtualCall(CodeGenFunction &CGF,
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");
@ -304,21 +307,15 @@ CodeGenFunction::BuildAppleKextVirtualCall(const CXXMethodDecl *MD,
/// 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);
}

View File

@ -73,7 +73,7 @@ CGCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
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) {
@ -86,7 +86,8 @@ llvm::Value *CGCXXABI::EmitLoadOfMemberFunctionPointer(
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 *

View File

@ -35,6 +35,7 @@ class FieldDecl;
class MangleContext;
namespace CodeGen {
class CGCallee;
class CodeGenFunction;
class CodeGenModule;
struct CatchTypeInfo;
@ -154,7 +155,7 @@ public:
/// 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);
@ -403,11 +404,11 @@ public:
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 *

View File

@ -3519,21 +3519,22 @@ void CodeGenFunction::deferPlaceholderReplacement(llvm::Instruction *Old,
}
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!
@ -3593,6 +3594,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
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;
@ -3840,6 +3842,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
}
}
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()) {
@ -3847,10 +3852,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// 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);
@ -3874,39 +3878,57 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
IRCallArgs[IRFunctionArgs.getInallocaArgNo()] = Arg;
}
// 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);
// 3. Perform the actual call.
// Deactivate any cleanups that we're supposed to do immediately before
// the call.
if (!CallArgs.getCleanupsToDeactivate().empty())
deactivateArgCleanupsBeforeCall(*this, CallArgs);
// 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;
}
// 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;
}
}
// 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.
@ -3916,75 +3938,106 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
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)
@ -4003,18 +4056,14 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
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);
@ -4022,12 +4071,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// 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: {
@ -4124,8 +4168,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
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;

View File

@ -41,6 +41,131 @@ namespace clang {
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;

View File

@ -2181,10 +2181,12 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
*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:
@ -2944,7 +2946,7 @@ void CodeGenFunction::EmitForwardingCallToLambda(
// 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));
@ -2963,8 +2965,8 @@ void CodeGenFunction::EmitForwardingCallToLambda(
// 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())

View File

@ -535,7 +535,8 @@ namespace {
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

View File

@ -1433,7 +1433,8 @@ struct PerformSEHFinally final : EHScopeStack::Cleanup {
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

View File

@ -2025,9 +2025,14 @@ static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF,
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>()) {
@ -2035,11 +2040,18 @@ static LValue EmitFunctionDeclLValue(CodeGenFunction &CGF,
// 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);
}
@ -3780,70 +3792,86 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E,
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;
CGCallee callee = EmitCallee(E->getCallee());
// 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();
}
switch (DestroyedType.getObjCLifetime()) {
case Qualifiers::OCL_None:
case Qualifiers::OCL_ExplicitNone:
case Qualifiers::OCL_Autoreleasing:
break;
case Qualifiers::OCL_Strong:
EmitARCRelease(Builder.CreateLoad(BaseValue,
PseudoDtor->getDestroyedType().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.
EmitScalarExpr(E->getCallee());
}
return RValue::get(nullptr);
if (callee.isBuiltin()) {
return EmitBuiltinExpr(callee.getBuiltinDecl(), callee.getBuiltinID(),
E, ReturnValue);
}
llvm::Value *Callee = EmitScalarExpr(E->getCallee());
return EmitCall(E->getCallee()->getType(), Callee, E, ReturnValue,
TargetDecl);
if (callee.isPseudoDestructor()) {
return EmitCXXPseudoDestructorExpr(callee.getPseudoDestructorExpr());
}
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());
}
// 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);
}
// 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) {
@ -4019,22 +4047,15 @@ LValue CodeGenFunction::EmitStmtExprLValue(const StmtExpr *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
@ -4052,6 +4073,8 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
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 =
@ -4066,8 +4089,10 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
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 =
@ -4090,7 +4115,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
EmitCheckTypeDescriptor(CalleeType)
};
EmitCheck(std::make_pair(CalleeRTTIMatch, SanitizerKind::Function),
"function_type_mismatch", StaticData, Callee);
"function_type_mismatch", StaticData, CalleePtr);
Builder.CreateBr(Cont);
EmitBlock(Cont);
@ -4107,7 +4132,8 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
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});
@ -4187,11 +4213,13 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
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::

View File

@ -80,26 +80,78 @@ commonEmitCXXMemberOrOperatorCall(CodeGenFunction &CGF, const CXXMethodDecl *MD,
}
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) {
@ -124,8 +176,8 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
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);
}
@ -251,8 +303,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
// 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");
@ -261,15 +312,19 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
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(),
@ -278,8 +333,11 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
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());
@ -294,9 +352,11 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
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);
}
}
@ -341,7 +401,7 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
// 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);
@ -1173,23 +1233,24 @@ static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E,
/// 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))

View File

@ -598,10 +598,10 @@ ComplexPairTy ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName,
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();
}

View File

@ -589,9 +589,10 @@ static void emitStructGetterCall(CodeGenFunction &CGF, ObjCIvarDecl *ivar,
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
@ -852,11 +853,12 @@ static void emitCPPObjectAtomicGetterCall(CodeGenFunction &CGF,
// 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
@ -927,12 +929,13 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl,
}
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
@ -955,8 +958,7 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl,
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();
@ -1068,10 +1070,11 @@ static void emitStructSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD,
// 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
@ -1103,11 +1106,12 @@ static void emitCPPObjectAtomicSetterCall(CodeGenFunction &CGF,
// 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);
}
@ -1197,8 +1201,8 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
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 =
@ -1236,8 +1240,9 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
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());
@ -1247,8 +1252,9 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
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;
@ -1450,13 +1456,14 @@ QualType CodeGenFunction::TypeOfSelfObject() {
}
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)

View File

@ -1386,9 +1386,10 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGenFunction &CGF,
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;
}
@ -1500,8 +1501,8 @@ CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF,
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);

View File

@ -1978,8 +1978,9 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
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.
@ -6986,9 +6987,10 @@ CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,
// 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,

View File

@ -248,7 +248,7 @@ void CodeGenFunction::FinishThunk() {
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");
@ -268,7 +268,7 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::Value *Callee,
CGM.ErrorUnsupported(
MD, "non-trivial argument copy for return-adjusting thunk");
}
EmitMustTailThunk(MD, AdjustedThisPtr, Callee);
EmitMustTailThunk(MD, AdjustedThisPtr, CalleePtr);
return;
}
@ -317,7 +317,8 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::Value *Callee,
// 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())
@ -337,7 +338,7 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::Value *Callee,
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
@ -366,13 +367,14 @@ void CodeGenFunction::EmitMustTailThunk(const CXXMethodDecl *MD,
// 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);
@ -398,7 +400,7 @@ void CodeGenFunction::generateThunk(llvm::Function *Fn,
// 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);

View File

@ -78,6 +78,7 @@ class ObjCAutoreleasePoolStmt;
namespace CodeGen {
class CodeGenTypes;
class CGCallee;
class CGFunctionInfo;
class CGRecordLayout;
class CGBlockInfo;
@ -1434,7 +1435,8 @@ public:
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();
@ -2842,17 +2844,17 @@ public:
/// 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);
@ -2878,21 +2880,23 @@ public:
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);
@ -2915,6 +2919,7 @@ public:
RValue EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
const CXXMethodDecl *MD,
ReturnValueSlot ReturnValue);
RValue EmitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
RValue EmitCUDAKernelCallExpr(const CUDAKernelCallExpr *E,
ReturnValueSlot ReturnValue);

View File

@ -832,8 +832,8 @@ public:
/// 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);

View File

@ -114,7 +114,7 @@ public:
llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT) override;
llvm::Value *
CGCallee
EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
const Expr *E,
Address This,
@ -263,9 +263,9 @@ public:
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,
@ -520,7 +520,7 @@ ItaniumCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
///
/// 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) {
@ -609,9 +609,11 @@ llvm::Value *ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
// 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;
}
@ -1448,12 +1450,14 @@ void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
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,
@ -1598,19 +1602,20 @@ llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
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 {
@ -1618,8 +1623,11 @@ llvm::Value *ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
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(
@ -1631,7 +1639,7 @@ 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());

View File

@ -284,9 +284,9 @@ public:
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,
@ -660,7 +660,7 @@ public:
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,
@ -1494,7 +1494,9 @@ void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
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 &&
@ -1796,11 +1798,11 @@ getClassAtVTableLocation(ASTContext &Ctx, GlobalDecl GD,
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;
@ -1814,8 +1816,9 @@ llvm::Value *MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
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 {
@ -1825,8 +1828,11 @@ llvm::Value *MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
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(
@ -1841,7 +1847,7 @@ 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();
@ -3231,7 +3237,7 @@ llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
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) {
@ -3278,7 +3284,10 @@ llvm::Value *MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
"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) {
@ -3892,10 +3901,12 @@ MicrosoftCXXABI::getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD,
/*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();