本文整理汇总了C++中FunctionType::getPointerTo方法的典型用法代码示例。如果您正苦于以下问题:C++ FunctionType::getPointerTo方法的具体用法?C++ FunctionType::getPointerTo怎么用?C++ FunctionType::getPointerTo使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类FunctionType
的用法示例。
在下文中一共展示了FunctionType::getPointerTo方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: makeArrayRef
/// Generate a thunk that puts the LSDA of ParentFunc in EAX and then calls
/// PersonalityFn, forwarding the parameters passed to PEXCEPTION_ROUTINE:
/// typedef _EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE)(
/// _EXCEPTION_RECORD *, void *, _CONTEXT *, void *);
/// We essentially want this code:
/// movl $lsda, %eax
/// jmpl ___CxxFrameHandler3
Function *WinEHStatePass::generateLSDAInEAXThunk(Function *ParentFunc) {
LLVMContext &Context = ParentFunc->getContext();
Type *Int32Ty = Type::getInt32Ty(Context);
Type *Int8PtrType = Type::getInt8PtrTy(Context);
Type *ArgTys[5] = {Int8PtrType, Int8PtrType, Int8PtrType, Int8PtrType,
Int8PtrType};
FunctionType *TrampolineTy =
FunctionType::get(Int32Ty, makeArrayRef(&ArgTys[0], 4),
/*isVarArg=*/false);
FunctionType *TargetFuncTy =
FunctionType::get(Int32Ty, makeArrayRef(&ArgTys[0], 5),
/*isVarArg=*/false);
Function *Trampoline = Function::Create(
TrampolineTy, GlobalValue::InternalLinkage,
Twine("__ehhandler$") + ParentFunc->getName(), TheModule);
BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", Trampoline);
IRBuilder<> Builder(EntryBB);
Value *LSDA = emitEHLSDA(Builder, ParentFunc);
Value *CastPersonality =
Builder.CreateBitCast(PersonalityFn, TargetFuncTy->getPointerTo());
auto AI = Trampoline->arg_begin();
Value *Args[5] = {LSDA, AI++, AI++, AI++, AI++};
CallInst *Call = Builder.CreateCall(CastPersonality, Args);
// Can't use musttail due to prototype mismatch, but we can use tail.
Call->setTailCall(true);
// Set inreg so we pass it in EAX.
Call->addAttribute(1, Attribute::InReg);
Builder.CreateRet(Call);
return Trampoline;
}
示例2: ExpandVarArgCall
static bool ExpandVarArgCall(Module *M, InstType *Call, DataLayout *DL) {
FunctionType *FuncType = cast<FunctionType>(
Call->getCalledValue()->getType()->getPointerElementType());
if (!FuncType->isFunctionVarArg())
return false;
if (auto *F = dyn_cast<Function>(Call->getCalledValue()))
if (isEmscriptenJSArgsFunc(M, F->getName()))
return false;
Function *F = Call->getParent()->getParent();
LLVMContext &Ctx = M->getContext();
SmallVector<AttributeSet, 8> Attrs;
Attrs.push_back(Call->getAttributes().getFnAttributes());
Attrs.push_back(Call->getAttributes().getRetAttributes());
// Split argument list into fixed and variable arguments.
SmallVector<Value *, 8> FixedArgs;
SmallVector<Value *, 8> VarArgs;
SmallVector<Type *, 8> VarArgsTypes;
for (unsigned I = 0, E = FuncType->getNumParams(); I < E; ++I) {
FixedArgs.push_back(Call->getArgOperand(I));
// AttributeSets use 1-based indexing.
Attrs.push_back(Call->getAttributes().getParamAttributes(I + 1));
}
for (unsigned I = FuncType->getNumParams(), E = Call->getNumArgOperands();
I < E; ++I) {
Value *ArgVal = Call->getArgOperand(I);
VarArgs.push_back(ArgVal);
bool isByVal = Call->getAttributes().hasAttribute(I + 1, Attribute::ByVal);
// For "byval" arguments we must dereference the pointer.
VarArgsTypes.push_back(isByVal ? ArgVal->getType()->getPointerElementType()
: ArgVal->getType());
}
if (VarArgsTypes.size() == 0) {
// Some buggy code (e.g. 176.gcc in Spec2k) uses va_arg on an
// empty argument list, which gives undefined behaviour in C. To
// work around such programs, we create a dummy varargs buffer on
// the stack even though there are no arguments to put in it.
// This allows va_arg to read an undefined value from the stack
// rather than crashing by reading from an uninitialized pointer.
// An alternative would be to pass a null pointer to catch the
// invalid use of va_arg.
VarArgsTypes.push_back(Type::getInt32Ty(Ctx));
}
// Create struct type for packing variable arguments into.
StructType *VarArgsTy = StructType::get(Ctx, VarArgsTypes);
// Allocate space for the variable argument buffer. Do this at the
// start of the function so that we don't leak space if the function
// is called in a loop.
IRBuilder<> IRB(F->getEntryBlock().getFirstInsertionPt());
auto *Buf = IRB.CreateAlloca(VarArgsTy, nullptr, "vararg_buffer");
// Call llvm.lifetime.start/end intrinsics to indicate that Buf is
// only used for the duration of the function call, so that the
// stack space can be reused elsewhere.
auto LifetimeStart = Intrinsic::getDeclaration(M, Intrinsic::lifetime_start);
auto LifetimeEnd = Intrinsic::getDeclaration(M, Intrinsic::lifetime_end);
auto *I8Ptr = Type::getInt8Ty(Ctx)->getPointerTo();
auto *BufPtr = IRB.CreateBitCast(Buf, I8Ptr, "vararg_lifetime_bitcast");
auto *BufSize =
ConstantInt::get(Ctx, APInt(64, DL->getTypeAllocSize(VarArgsTy)));
IRB.CreateCall2(LifetimeStart, BufSize, BufPtr);
// Copy variable arguments into buffer.
int Index = 0;
IRB.SetInsertPoint(Call);
for (Value *Arg : VarArgs) {
Value *Indexes[] = {ConstantInt::get(Ctx, APInt(32, 0)),
ConstantInt::get(Ctx, APInt(32, Index))};
Value *Ptr = IRB.CreateInBoundsGEP(Buf, Indexes, "vararg_ptr");
bool isByVal = Call->getAttributes().hasAttribute(
FuncType->getNumParams() + Index + 1, Attribute::ByVal);
if (isByVal)
IRB.CreateMemCpy(Ptr, Arg, DL->getTypeAllocSize(
Arg->getType()->getPointerElementType()),
/*Align=*/1);
else
IRB.CreateStore(Arg, Ptr);
++Index;
}
// Cast function to new type to add our extra pointer argument.
SmallVector<Type *, 8> ArgTypes(FuncType->param_begin(),
FuncType->param_end());
ArgTypes.push_back(VarArgsTy->getPointerTo());
FunctionType *NFTy = FunctionType::get(FuncType->getReturnType(), ArgTypes,
/*isVarArg=*/false);
Value *CastFunc = IRB.CreateBitCast(Call->getCalledValue(),
NFTy->getPointerTo(), "vararg_func");
// Create the converted function call.
FixedArgs.push_back(Buf);
Instruction *NewCall;
if (auto *C = dyn_cast<CallInst>(Call)) {
auto *N = IRB.CreateCall(CastFunc, FixedArgs);
N->setAttributes(AttributeSet::get(Ctx, Attrs));
NewCall = N;
//.........这里部分代码省略.........
示例3: ConvertCall
// Convert the given call to use normalized argument/return types.
template <class T> static bool ConvertCall(T *Call, Pass *P) {
// Don't try to change calls to intrinsics.
if (isa<IntrinsicInst>(Call))
return false;
FunctionType *FTy = cast<FunctionType>(
Call->getCalledValue()->getType()->getPointerElementType());
FunctionType *NFTy = NormalizeFunctionType(FTy);
if (NFTy == FTy)
return false; // No change needed.
// Convert arguments.
SmallVector<Value *, 8> Args;
for (unsigned I = 0; I < Call->getNumArgOperands(); ++I) {
Value *Arg = Call->getArgOperand(I);
if (NFTy->getParamType(I) != FTy->getParamType(I)) {
Instruction::CastOps CastType =
Call->getAttributes().hasAttribute(I + 1, Attribute::SExt) ?
Instruction::SExt : Instruction::ZExt;
Arg = CopyDebug(CastInst::Create(CastType, Arg, NFTy->getParamType(I),
"arg_ext", Call), Call);
}
Args.push_back(Arg);
}
Value *CastFunc =
CopyDebug(new BitCastInst(Call->getCalledValue(), NFTy->getPointerTo(),
Call->getName() + ".arg_cast", Call), Call);
Value *Result = NULL;
if (CallInst *OldCall = dyn_cast<CallInst>(Call)) {
CallInst *NewCall = CopyDebug(CallInst::Create(CastFunc, Args, "", OldCall),
OldCall);
NewCall->takeName(OldCall);
NewCall->setAttributes(OldCall->getAttributes());
NewCall->setCallingConv(OldCall->getCallingConv());
NewCall->setTailCall(OldCall->isTailCall());
Result = NewCall;
if (FTy->getReturnType() != NFTy->getReturnType()) {
Result = CopyDebug(new TruncInst(NewCall, FTy->getReturnType(),
NewCall->getName() + ".ret_trunc", Call),
Call);
}
} else if (InvokeInst *OldInvoke = dyn_cast<InvokeInst>(Call)) {
BasicBlock *Parent = OldInvoke->getParent();
BasicBlock *NormalDest = OldInvoke->getNormalDest();
BasicBlock *UnwindDest = OldInvoke->getUnwindDest();
if (FTy->getReturnType() != NFTy->getReturnType()) {
if (BasicBlock *SplitDest = SplitCriticalEdge(Parent, NormalDest)) {
NormalDest = SplitDest;
}
}
InvokeInst *New = CopyDebug(InvokeInst::Create(CastFunc, NormalDest,
UnwindDest, Args,
"", OldInvoke),
OldInvoke);
New->takeName(OldInvoke);
if (FTy->getReturnType() != NFTy->getReturnType()) {
Result = CopyDebug(new TruncInst(New, FTy->getReturnType(),
New->getName() + ".ret_trunc",
NormalDest->getTerminator()),
OldInvoke);
} else {
Result = New;
}
New->setAttributes(OldInvoke->getAttributes());
New->setCallingConv(OldInvoke->getCallingConv());
}
Call->replaceAllUsesWith(Result);
Call->eraseFromParent();
return true;
}