本文整理汇总了C++中CallArgList类的典型用法代码示例。如果您正苦于以下问题:C++ CallArgList类的具体用法?C++ CallArgList怎么用?C++ CallArgList使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了CallArgList类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: EmitComplexBinOpLibCall
/// \brief Emit a libcall for a binary operation on complex types.
ComplexPairTy ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName,
const BinOpInfo &Op) {
CallArgList Args;
Args.add(RValue::get(Op.LHS.first),
Op.Ty->castAs<ComplexType>()->getElementType());
Args.add(RValue::get(Op.LHS.second),
Op.Ty->castAs<ComplexType>()->getElementType());
Args.add(RValue::get(Op.RHS.first),
Op.Ty->castAs<ComplexType>()->getElementType());
Args.add(RValue::get(Op.RHS.second),
Op.Ty->castAs<ComplexType>()->getElementType());
// We *must* use the full CG function call building logic here because the
// complex type has special ABI handling. We also should not forget about
// special calling convention which may be used for compiler builtins.
const CGFunctionInfo &FuncInfo =
CGF.CGM.getTypes().arrangeFreeFunctionCall(
Op.Ty, Args, FunctionType::ExtInfo(/* No CC here - will be added later */),
RequiredArgs::All);
llvm::FunctionType *FTy = CGF.CGM.getTypes().GetFunctionType(FuncInfo);
llvm::Constant *Func = CGF.CGM.CreateBuiltinFunction(FTy, LibCallName);
llvm::Instruction *Call;
RValue Res = CGF.EmitCall(FuncInfo, Func, ReturnValueSlot(), Args,
nullptr, &Call);
cast<llvm::CallInst>(Call)->setCallingConv(CGF.CGM.getBuiltinCC());
cast<llvm::CallInst>(Call)->setDoesNotThrow();
return Res.getComplexVal();
}
示例2: CopyObject
// CopyObject - Utility to copy an object. Calls copy constructor as necessary.
// DestPtr is casted to the right type.
static void CopyObject(CodeGenFunction &CGF, const Expr *E,
llvm::Value *DestPtr, llvm::Value *ExceptionPtrPtr) {
QualType ObjectType = E->getType();
// Store the throw exception in the exception object.
if (!CGF.hasAggregateLLVMType(ObjectType)) {
llvm::Value *Value = CGF.EmitScalarExpr(E);
const llvm::Type *ValuePtrTy = Value->getType()->getPointerTo();
CGF.Builder.CreateStore(Value,
CGF.Builder.CreateBitCast(DestPtr, ValuePtrTy));
} else {
const llvm::Type *Ty = CGF.ConvertType(ObjectType)->getPointerTo();
const CXXRecordDecl *RD =
cast<CXXRecordDecl>(ObjectType->getAs<RecordType>()->getDecl());
llvm::Value *This = CGF.Builder.CreateBitCast(DestPtr, Ty);
if (RD->hasTrivialCopyConstructor()) {
CGF.EmitAggExpr(E, This, false);
} else if (CXXConstructorDecl *CopyCtor
= RD->getCopyConstructor(CGF.getContext(), 0)) {
llvm::BasicBlock *PrevLandingPad = CGF.getInvokeDest();
if (CGF.Exceptions) {
CodeGenFunction::EHCleanupBlock Cleanup(CGF);
llvm::Constant *FreeExceptionFn = getFreeExceptionFn(CGF);
// Load the exception pointer.
llvm::Value *ExceptionPtr = CGF.Builder.CreateLoad(ExceptionPtrPtr);
CGF.Builder.CreateCall(FreeExceptionFn, ExceptionPtr);
}
llvm::Value *Src = CGF.EmitLValue(E).getAddress();
CGF.setInvokeDest(PrevLandingPad);
llvm::BasicBlock *TerminateHandler = CGF.getTerminateHandler();
PrevLandingPad = CGF.getInvokeDest();
CGF.setInvokeDest(TerminateHandler);
// Stolen from EmitClassAggrMemberwiseCopy
llvm::Value *Callee = CGF.CGM.GetAddrOfCXXConstructor(CopyCtor,
Ctor_Complete);
CallArgList CallArgs;
CallArgs.push_back(std::make_pair(RValue::get(This),
CopyCtor->getThisType(CGF.getContext())));
// Push the Src ptr.
CallArgs.push_back(std::make_pair(RValue::get(Src),
CopyCtor->getParamDecl(0)->getType()));
QualType ResultType =
CopyCtor->getType()->getAs<FunctionType>()->getResultType();
CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
Callee, CallArgs, CopyCtor);
CGF.setInvokeDest(PrevLandingPad);
} else
llvm_unreachable("uncopyable object");
}
}
示例3: assert
/// Emit a store to an l-value of atomic type.
///
/// Note that the r-value is expected to be an r-value *of the atomic
/// type*; this means that for aggregate r-values, it should include
/// storage for any padding that was necessary.
void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest, bool isInit) {
// If this is an aggregate r-value, it should agree in type except
// maybe for address-space qualification.
assert(!rvalue.isAggregate() ||
rvalue.getAggregateAddr()->getType()->getPointerElementType()
== dest.getAddress()->getType()->getPointerElementType());
AtomicInfo atomics(*this, dest);
// If this is an initialization, just put the value there normally.
if (isInit) {
atomics.emitCopyIntoMemory(rvalue, dest);
return;
}
// Check whether we should use a library call.
if (atomics.shouldUseLibcall()) {
// Produce a source address.
llvm::Value *srcAddr = atomics.materializeRValue(rvalue);
// void __atomic_store(size_t size, void *mem, void *val, int order)
CallArgList args;
args.add(RValue::get(atomics.getAtomicSizeValue()),
getContext().getSizeType());
args.add(RValue::get(EmitCastToVoidPtr(dest.getAddress())),
getContext().VoidPtrTy);
args.add(RValue::get(EmitCastToVoidPtr(srcAddr)),
getContext().VoidPtrTy);
args.add(RValue::get(llvm::ConstantInt::get(
IntTy, AtomicExpr::AO_ABI_memory_order_seq_cst)),
getContext().IntTy);
emitAtomicLibcall(*this, "__atomic_store", getContext().VoidTy, args);
return;
}
// Okay, we're doing this natively.
llvm::Value *intValue = atomics.convertRValueToInt(rvalue);
// Do the atomic store.
llvm::Value *addr = atomics.emitCastToAtomicIntPointer(dest.getAddress());
llvm::StoreInst *store = Builder.CreateStore(intValue, addr);
// Initializations don't need to be atomic.
if (!isInit) store->setAtomic(llvm::SequentiallyConsistent);
// Other decoration.
store->setAlignment(dest.getAlignment().getQuantity());
if (dest.isVolatileQualified())
store->setVolatile(true);
if (dest.getTBAAInfo())
CGM.DecorateInstruction(store, dest.getTBAAInfo());
}
示例4: atomics
/// Emit a load from an l-value of atomic type. Note that the r-value
/// we produce is an r-value of the atomic *value* type.
RValue CodeGenFunction::EmitAtomicLoad(LValue src, SourceLocation loc,
AggValueSlot resultSlot) {
AtomicInfo atomics(*this, src);
// Check whether we should use a library call.
if (atomics.shouldUseLibcall()) {
llvm::Value *tempAddr;
if (!resultSlot.isIgnored()) {
assert(atomics.getEvaluationKind() == TEK_Aggregate);
tempAddr = resultSlot.getAddr();
} else {
tempAddr = CreateMemTemp(atomics.getAtomicType(), "atomic-load-temp");
}
// void __atomic_load(size_t size, void *mem, void *return, int order);
CallArgList args;
args.add(RValue::get(atomics.getAtomicSizeValue()),
getContext().getSizeType());
args.add(RValue::get(EmitCastToVoidPtr(src.getAddress())),
getContext().VoidPtrTy);
args.add(RValue::get(EmitCastToVoidPtr(tempAddr)),
getContext().VoidPtrTy);
args.add(RValue::get(llvm::ConstantInt::get(
IntTy, AtomicExpr::AO_ABI_memory_order_seq_cst)),
getContext().IntTy);
emitAtomicLibcall(*this, "__atomic_load", getContext().VoidTy, args);
// Produce the r-value.
return atomics.convertTempToRValue(tempAddr, resultSlot, loc);
}
// Okay, we're doing this natively.
llvm::Value *addr = atomics.emitCastToAtomicIntPointer(src.getAddress());
llvm::LoadInst *load = Builder.CreateLoad(addr, "atomic-load");
load->setAtomic(llvm::SequentiallyConsistent);
// Other decoration.
load->setAlignment(src.getAlignment().getQuantity());
if (src.isVolatileQualified())
load->setVolatile(true);
if (src.getTBAAInfo())
CGM.DecorateInstruction(load, src.getTBAAInfo());
// If we're ignoring an aggregate return, don't do anything.
if (atomics.getEvaluationKind() == TEK_Aggregate && resultSlot.isIgnored())
return RValue::getAggregate(nullptr, false);
// Okay, turn that back into the original value type.
return atomics.convertIntToValue(load, resultSlot, loc);
}
示例5: AddDirectArgument
static void
AddDirectArgument(CodeGenFunction &CGF, CallArgList &Args,
bool UseOptimizedLibcall, llvm::Value *Val, QualType ValTy) {
if (UseOptimizedLibcall) {
// Load value and pass it to the function directly.
unsigned Align = CGF.getContext().getTypeAlignInChars(ValTy).getQuantity();
Val = CGF.EmitLoadOfScalar(Val, false, Align, ValTy);
Args.add(RValue::get(Val), ValTy);
} else {
// Non-optimized functions always take a reference.
Args.add(RValue::get(CGF.EmitCastToVoidPtr(Val)),
CGF.getContext().VoidPtrTy);
}
}
示例6: takeDestination
CharacterValueTy CharacterExprEmitter::VisitCallExpr(const CallExpr *E) {
CharacterValueTy Dest;
if(hasDestination())
Dest = takeDestination();
else {
// FIXME function returning CHARACTER*(*)
auto RetType = E->getFunction()->getType();
Dest = CGF.GetCharacterValueFromPtr(
CGF.CreateTempAlloca(CGF.ConvertTypeForMem(RetType), "characters"),
RetType);
}
CallArgList ArgList;
ArgList.addReturnValueArg(Dest);
return CGF.EmitCall(E->getFunction(), ArgList, E->getArguments()).asCharacter();
}
示例7: CopyObject
// CopyObject - Utility to copy an object. Calls copy constructor as necessary.
// N is casted to the right type.
static void CopyObject(CodeGenFunction &CGF, QualType ObjectType,
bool WasPointer, bool WasPointerReference,
llvm::Value *E, llvm::Value *N) {
// Store the throw exception in the exception object.
if (WasPointer || !CGF.hasAggregateLLVMType(ObjectType)) {
llvm::Value *Value = E;
if (!WasPointer)
Value = CGF.Builder.CreateLoad(Value);
const llvm::Type *ValuePtrTy = Value->getType()->getPointerTo(0);
if (WasPointerReference) {
llvm::Value *Tmp = CGF.CreateTempAlloca(Value->getType(), "catch.param");
CGF.Builder.CreateStore(Value, Tmp);
Value = Tmp;
ValuePtrTy = Value->getType()->getPointerTo(0);
}
N = CGF.Builder.CreateBitCast(N, ValuePtrTy);
CGF.Builder.CreateStore(Value, N);
} else {
const llvm::Type *Ty = CGF.ConvertType(ObjectType)->getPointerTo(0);
const CXXRecordDecl *RD;
RD = cast<CXXRecordDecl>(ObjectType->getAs<RecordType>()->getDecl());
llvm::Value *This = CGF.Builder.CreateBitCast(N, Ty);
if (RD->hasTrivialCopyConstructor()) {
CGF.EmitAggregateCopy(This, E, ObjectType);
} else if (CXXConstructorDecl *CopyCtor
= RD->getCopyConstructor(CGF.getContext(), 0)) {
llvm::Value *Src = E;
// Stolen from EmitClassAggrMemberwiseCopy
llvm::Value *Callee = CGF.CGM.GetAddrOfCXXConstructor(CopyCtor,
Ctor_Complete);
CallArgList CallArgs;
CallArgs.push_back(std::make_pair(RValue::get(This),
CopyCtor->getThisType(CGF.getContext())));
// Push the Src ptr.
CallArgs.push_back(std::make_pair(RValue::get(Src),
CopyCtor->getParamDecl(0)->getType()));
const FunctionProtoType *FPT
= CopyCtor->getType()->getAs<FunctionProtoType>();
CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(CallArgs, FPT),
Callee, ReturnValueSlot(), CallArgs, CopyCtor);
} else
llvm_unreachable("uncopyable object");
}
}
示例8: getContext
void CodeGenFunction::EmitUPCAggregateCopy(llvm::Value *Dest, llvm::Value *Src,
QualType DestTy, QualType SrcTy,
SourceLocation Loc) {
const ASTContext& Context = getContext();
QualType ArgTy = Context.getPointerType(Context.getSharedType(Context.VoidTy));
QualType SizeType = Context.getSizeType();
assert(DestTy->getCanonicalTypeUnqualified() == SrcTy->getCanonicalTypeUnqualified());
llvm::Constant *Len =
llvm::ConstantInt::get(ConvertType(SizeType),
Context.getTypeSizeInChars(DestTy).getQuantity());
llvm::SmallString<16> Name;
const char *OpName;
QualType DestArgTy, SrcArgTy;
if (DestTy.getQualifiers().hasShared() && SrcTy.getQualifiers().hasShared()) {
// both shared
OpName = "copy";
DestArgTy = SrcArgTy = ArgTy;
} else if (DestTy.getQualifiers().hasShared()) {
OpName = "put";
DestArgTy = ArgTy;
SrcArgTy = Context.VoidPtrTy;
} else if (SrcTy.getQualifiers().hasShared()) {
OpName = "get";
DestArgTy = Context.VoidPtrTy;
SrcArgTy = ArgTy;
} else {
llvm_unreachable("expected at least one shared argument");
}
Name += "__";
Name += OpName;
if (DestTy.getQualifiers().hasStrict() || SrcTy.getQualifiers().hasStrict())
Name += 's';
if (CGM.getCodeGenOpts().UPCDebug) Name += "g";
Name += "blk";
CallArgList Args;
Args.add(RValue::get(Dest), DestArgTy);
Args.add(RValue::get(Src), SrcArgTy);
Args.add(RValue::get(Len), SizeType);
if (CGM.getCodeGenOpts().UPCDebug) {
getFileAndLine(*this, Loc, &Args);
Name += '5';
} else {
Name += '3';
}
EmitUPCCall(*this, Name, Context.VoidTy, Args);
}
示例9: GetSelector
CodeGen::RValue
CGObjCJit::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
ReturnValueSlot Return,
QualType ResultType,
Selector Sel,
llvm::Value *Arg0,
llvm::Value *Arg0Class,
const CallArgList &CallArgs,
const ObjCMethodDecl *Method) {
llvm::Value *Arg1 = GetSelector(CGF, Sel);
CallArgList ActualArgs;
ActualArgs.add(RValue::get(Arg0), CGF.getContext().getObjCIdType());
ActualArgs.add(RValue::get(Arg1), CGF.getContext().getObjCSelType());
ActualArgs.addFrom(CallArgs);
if (Method)
assert(CGM.getContext().getCanonicalType(Method->getResultType()) ==
CGM.getContext().getCanonicalType(ResultType) &&
"Result type mismatch!");
// Perform the following:
// imp = class_getMethodImplementation( Arg0Class, Arg1 );
// (*imp)( Arg0, Arg1, CallArgs );
llvm::CallInst *getImp;
// Unfortunately, using the GNU runtime version of
// class_getMethodImplementation and then calling the resulting
// IMP doesn't work unless objc_msg_lookup was already
// called first. TODO: avoid doing this every time
//
if (fn_objc_msg_lookup.isValid()) {
getImp = CGF.Builder.CreateCall2(fn_objc_msg_lookup,
Arg0,
Arg1);
} else { // use the universal way
getImp = CGF.Builder.CreateCall2(fn_class_getMethodImplementation,
Arg0Class,
Arg1);
}
MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
llvm::Value *theImp = CGF.Builder.CreateBitCast(getImp, MSI.MessengerType);
return CGF.EmitCall(MSI.CallInfo, theImp, Return, ActualArgs);
}
示例10: assert
// Transforms a call to printf into a call to the NVPTX vprintf syscall (which
// isn't particularly special; it's invoked just like a regular function).
// vprintf takes two args: A format string, and a pointer to a buffer containing
// the varargs.
//
// For example, the call
//
// printf("format string", arg1, arg2, arg3);
//
// is converted into something resembling
//
// struct Tmp {
// Arg1 a1;
// Arg2 a2;
// Arg3 a3;
// };
// char* buf = alloca(sizeof(Tmp));
// *(Tmp*)buf = {a1, a2, a3};
// vprintf("format string", buf);
//
// buf is aligned to the max of {alignof(Arg1), ...}. Furthermore, each of the
// args is itself aligned to its preferred alignment.
//
// Note that by the time this function runs, E's args have already undergone the
// standard C vararg promotion (short -> int, float -> double, etc.).
RValue
CodeGenFunction::EmitCUDADevicePrintfCallExpr(const CallExpr *E,
ReturnValueSlot ReturnValue) {
assert(getLangOpts().CUDA);
assert(getLangOpts().CUDAIsDevice);
assert(E->getBuiltinCallee() == Builtin::BIprintf);
assert(E->getNumArgs() >= 1); // printf always has at least one arg.
const llvm::DataLayout &DL = CGM.getDataLayout();
llvm::LLVMContext &Ctx = CGM.getLLVMContext();
CallArgList Args;
EmitCallArgs(Args,
E->getDirectCallee()->getType()->getAs<FunctionProtoType>(),
E->arguments(), E->getDirectCallee(),
/* ParamsToSkip = */ 0);
// Construct and fill the args buffer that we'll pass to vprintf.
llvm::Value *BufferPtr;
if (Args.size() <= 1) {
// If there are no args, pass a null pointer to vprintf.
BufferPtr = llvm::ConstantPointerNull::get(llvm::Type::getInt8PtrTy(Ctx));
} else {
llvm::SmallVector<llvm::Type *, 8> ArgTypes;
for (unsigned I = 1, NumArgs = Args.size(); I < NumArgs; ++I)
ArgTypes.push_back(Args[I].RV.getScalarVal()->getType());
llvm::Type *AllocaTy = llvm::StructType::create(ArgTypes, "printf_args");
llvm::Value *Alloca = CreateTempAlloca(AllocaTy);
for (unsigned I = 1, NumArgs = Args.size(); I < NumArgs; ++I) {
llvm::Value *P = Builder.CreateStructGEP(AllocaTy, Alloca, I - 1);
llvm::Value *Arg = Args[I].RV.getScalarVal();
Builder.CreateAlignedStore(Arg, P, DL.getPrefTypeAlignment(Arg->getType()));
}
BufferPtr = Builder.CreatePointerCast(Alloca, llvm::Type::getInt8PtrTy(Ctx));
}
// Invoke vprintf and return.
llvm::Function* VprintfFunc = GetVprintfDeclaration(CGM.getModule());
return RValue::get(
Builder.CreateCall(VprintfFunc, {Args[0].RV.getScalarVal(), BufferPtr}));
}
示例11: AddDirectArgument
static void
AddDirectArgument(CodeGenFunction &CGF, CallArgList &Args,
bool UseOptimizedLibcall, llvm::Value *Val, QualType ValTy,
SourceLocation Loc, CharUnits SizeInChars) {
if (UseOptimizedLibcall) {
// Load value and pass it to the function directly.
unsigned Align = CGF.getContext().getTypeAlignInChars(ValTy).getQuantity();
int64_t SizeInBits = CGF.getContext().toBits(SizeInChars);
ValTy =
CGF.getContext().getIntTypeForBitwidth(SizeInBits, /*Signed=*/false);
llvm::Type *IPtrTy = llvm::IntegerType::get(CGF.getLLVMContext(),
SizeInBits)->getPointerTo();
Val = CGF.EmitLoadOfScalar(CGF.Builder.CreateBitCast(Val, IPtrTy), false,
Align, CGF.getContext().getPointerType(ValTy),
Loc);
// Coerce the value into an appropriately sized integer type.
Args.add(RValue::get(Val), ValTy);
} else {
// Non-optimized functions always take a reference.
Args.add(RValue::get(CGF.EmitCastToVoidPtr(Val)),
CGF.getContext().VoidPtrTy);
}
}
示例12: EmitComplexBinOpLibCall
/// \brief Emit a libcall for a binary operation on complex types.
ComplexPairTy ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName,
const BinOpInfo &Op) {
CallArgList Args;
Args.add(RValue::get(Op.LHS.first),
Op.Ty->castAs<ComplexType>()->getElementType());
Args.add(RValue::get(Op.LHS.second),
Op.Ty->castAs<ComplexType>()->getElementType());
Args.add(RValue::get(Op.RHS.first),
Op.Ty->castAs<ComplexType>()->getElementType());
Args.add(RValue::get(Op.RHS.second),
Op.Ty->castAs<ComplexType>()->getElementType());
// We *must* use the full CG function call building logic here because the
// complex type has special ABI handling. We also should not forget about
// special calling convention which may be used for compiler builtins.
// We create a function qualified type to state that this call does not have
// any exceptions.
FunctionProtoType::ExtProtoInfo EPI;
EPI = EPI.withExceptionSpec(
FunctionProtoType::ExceptionSpecInfo(EST_BasicNoexcept));
SmallVector<QualType, 4> ArgsQTys(
4, Op.Ty->castAs<ComplexType>()->getElementType());
QualType FQTy = CGF.getContext().getFunctionType(Op.Ty, ArgsQTys, EPI);
const CGFunctionInfo &FuncInfo = CGF.CGM.getTypes().arrangeFreeFunctionCall(
Args, cast<FunctionType>(FQTy.getTypePtr()), false);
llvm::FunctionType *FTy = CGF.CGM.getTypes().GetFunctionType(FuncInfo);
llvm::Constant *Func = CGF.CGM.CreateBuiltinFunction(FTy, LibCallName);
CGCallee Callee = CGCallee::forDirect(Func, FQTy->getAs<FunctionProtoType>());
llvm::Instruction *Call;
RValue Res = CGF.EmitCall(FuncInfo, Callee, ReturnValueSlot(), Args, &Call);
cast<llvm::CallInst>(Call)->setCallingConv(CGF.CGM.getBuiltinCC());
return Res.getComplexVal();
}
示例13: assert
RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE) {
const MemberExpr *ME = cast<MemberExpr>(CE->getCallee());
const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
assert(MD->isInstance() &&
"Trying to emit a member call expr on a static method!");
const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
const llvm::Type *Ty =
CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
FPT->isVariadic());
llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, Ty);
llvm::Value *BaseValue = 0;
// There's a deref operator node added in Sema::BuildCallToMemberFunction
// that's giving the wrong type for -> call exprs so we just ignore them
// for now.
if (ME->isArrow())
return EmitUnsupportedRValue(CE, "C++ member call expr");
else {
LValue BaseLV = EmitLValue(ME->getBase());
BaseValue = BaseLV.getAddress();
}
CallArgList Args;
// Push the 'this' pointer.
Args.push_back(std::make_pair(RValue::get(BaseValue),
MD->getThisType(getContext())));
EmitCallArgs(Args, FPT, CE->arg_begin(), CE->arg_end());
QualType ResultType = MD->getType()->getAsFunctionType()->getResultType();
return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args),
Callee, Args, MD);
}
示例14: EmitUPCCall
RValue EmitUPCCall(CodeGenFunction &CGF,
llvm::StringRef Name,
QualType ResultTy,
const CallArgList& Args) {
ASTContext &Context = CGF.CGM.getContext();
llvm::SmallVector<QualType, 5> ArgTypes;
for (CallArgList::const_iterator iter = Args.begin(),
end = Args.end(); iter != end; ++iter) {
ArgTypes.push_back(iter->Ty);
}
QualType FuncType =
Context.getFunctionType(ResultTy,
ArgTypes,
FunctionProtoType::ExtProtoInfo());
const CGFunctionInfo &Info =
CGF.getTypes().arrangeFreeFunctionCall(Args, FuncType->castAs<FunctionType>());
llvm::FunctionType * FTy =
cast<llvm::FunctionType>(CGF.ConvertType(FuncType));
llvm::Value * Fn = CGF.CGM.CreateRuntimeFunction(FTy, Name);
return CGF.EmitCall(Info, Fn, ReturnValueSlot(), Args);
}
示例15: assert
// Transforms a call to printf into a call to the NVPTX vprintf syscall (which
// isn't particularly special; it's invoked just like a regular function).
// vprintf takes two args: A format string, and a pointer to a buffer containing
// the varargs.
//
// For example, the call
//
// printf("format string", arg1, arg2, arg3);
//
// is converted into something resembling
//
// struct Tmp {
// Arg1 a1;
// Arg2 a2;
// Arg3 a3;
// };
// char* buf = alloca(sizeof(Tmp));
// *(Tmp*)buf = {a1, a2, a3};
// vprintf("format string", buf);
//
// buf is aligned to the max of {alignof(Arg1), ...}. Furthermore, each of the
// args is itself aligned to its preferred alignment.
//
// Note that by the time this function runs, E's args have already undergone the
// standard C vararg promotion (short -> int, float -> double, etc.).
RValue
CodeGenFunction::EmitNVPTXDevicePrintfCallExpr(const CallExpr *E,
ReturnValueSlot ReturnValue) {
assert(getTarget().getTriple().isNVPTX());
assert(E->getBuiltinCallee() == Builtin::BIprintf);
assert(E->getNumArgs() >= 1); // printf always has at least one arg.
const llvm::DataLayout &DL = CGM.getDataLayout();
llvm::LLVMContext &Ctx = CGM.getLLVMContext();
CallArgList Args;
EmitCallArgs(Args,
E->getDirectCallee()->getType()->getAs<FunctionProtoType>(),
E->arguments(), E->getDirectCallee(),
/* ParamsToSkip = */ 0);
// We don't know how to emit non-scalar varargs.
if (std::any_of(Args.begin() + 1, Args.end(), [&](const CallArg &A) {
return !A.getRValue(*this).isScalar();
})) {
CGM.ErrorUnsupported(E, "non-scalar arg to printf");
return RValue::get(llvm::ConstantInt::get(IntTy, 0));
}
// Construct and fill the args buffer that we'll pass to vprintf.
llvm::Value *BufferPtr;
if (Args.size() <= 1) {
// If there are no args, pass a null pointer to vprintf.
BufferPtr = llvm::ConstantPointerNull::get(llvm::Type::getInt8PtrTy(Ctx));
} else {
llvm::SmallVector<llvm::Type *, 8> ArgTypes;
for (unsigned I = 1, NumArgs = Args.size(); I < NumArgs; ++I)
ArgTypes.push_back(Args[I].getRValue(*this).getScalarVal()->getType());
// Using llvm::StructType is correct only because printf doesn't accept
// aggregates. If we had to handle aggregates here, we'd have to manually
// compute the offsets within the alloca -- we wouldn't be able to assume
// that the alignment of the llvm type was the same as the alignment of the
// clang type.
llvm::Type *AllocaTy = llvm::StructType::create(ArgTypes, "printf_args");
llvm::Value *Alloca = CreateTempAlloca(AllocaTy);
for (unsigned I = 1, NumArgs = Args.size(); I < NumArgs; ++I) {
llvm::Value *P = Builder.CreateStructGEP(AllocaTy, Alloca, I - 1);
llvm::Value *Arg = Args[I].getRValue(*this).getScalarVal();
Builder.CreateAlignedStore(Arg, P, DL.getPrefTypeAlignment(Arg->getType()));
}
BufferPtr = Builder.CreatePointerCast(Alloca, llvm::Type::getInt8PtrTy(Ctx));
}
// Invoke vprintf and return.
llvm::Function* VprintfFunc = GetVprintfDeclaration(CGM.getModule());
return RValue::get(Builder.CreateCall(
VprintfFunc, {Args[0].getRValue(*this).getScalarVal(), BufferPtr}));
}