Use a slightly more semantic interface for emitting call arguments.

llvm-svn: 127494
This commit is contained in:
John McCall 2011-03-11 20:59:21 +00:00
parent d767d06b26
commit 32ea969415
6 changed files with 40 additions and 47 deletions

View File

@ -1116,42 +1116,48 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI) {
Ret->setDebugLoc(RetDbgLoc);
}
RValue CodeGenFunction::EmitDelegateCallArg(const VarDecl *Param) {
void CodeGenFunction::EmitDelegateCallArg(CallArgList &args,
const VarDecl *param) {
// StartFunction converted the ABI-lowered parameter(s) into a
// local alloca. We need to turn that into an r-value suitable
// for EmitCall.
llvm::Value *Local = GetAddrOfLocalVar(Param);
llvm::Value *local = GetAddrOfLocalVar(param);
QualType ArgType = Param->getType();
QualType type = param->getType();
// For the most part, we just need to load the alloca, except:
// 1) aggregate r-values are actually pointers to temporaries, and
// 2) references to aggregates are pointers directly to the aggregate.
// I don't know why references to non-aggregates are different here.
if (const ReferenceType *RefType = ArgType->getAs<ReferenceType>()) {
if (hasAggregateLLVMType(RefType->getPointeeType()))
return RValue::getAggregate(Local);
if (const ReferenceType *ref = type->getAs<ReferenceType>()) {
if (hasAggregateLLVMType(ref->getPointeeType()))
return args.add(RValue::getAggregate(local), type);
// Locals which are references to scalars are represented
// with allocas holding the pointer.
return RValue::get(Builder.CreateLoad(Local));
return args.add(RValue::get(Builder.CreateLoad(local)), type);
}
if (ArgType->isAnyComplexType())
return RValue::getComplex(LoadComplexFromAddr(Local, /*volatile*/ false));
if (type->isAnyComplexType()) {
ComplexPairTy complex = LoadComplexFromAddr(local, /*volatile*/ false);
return args.add(RValue::getComplex(complex), type);
}
if (hasAggregateLLVMType(ArgType))
return RValue::getAggregate(Local);
if (hasAggregateLLVMType(type))
return args.add(RValue::getAggregate(local), type);
unsigned Alignment = getContext().getDeclAlign(Param).getQuantity();
return RValue::get(EmitLoadOfScalar(Local, false, Alignment, ArgType));
unsigned alignment = getContext().getDeclAlign(param).getQuantity();
llvm::Value *value = EmitLoadOfScalar(local, false, alignment, type);
return args.add(RValue::get(value), type);
}
RValue CodeGenFunction::EmitCallArg(const Expr *E, QualType ArgType) {
if (ArgType->isReferenceType())
return EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0);
void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
QualType type) {
if (type->isReferenceType())
return args.add(EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0),
type);
return EmitAnyExprToTemp(E);
args.add(EmitAnyExprToTemp(E), type);
}
/// Emits a call or invoke instruction to the given function, depending

View File

@ -48,6 +48,10 @@ namespace CodeGen {
/// arguments in a call.
class CallArgList :
public llvm::SmallVector<std::pair<RValue, QualType>, 16> {
public:
void add(RValue rvalue, QualType type) {
push_back(std::pair<RValue,QualType>(rvalue,type));
}
};
/// FunctionArgList - Type for representing both the decl and type

View File

@ -1211,9 +1211,7 @@ CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D,
for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin()+1,
E = FPT->arg_type_end(); I != E; ++I, ++Arg) {
assert(Arg != ArgEnd && "Running over edge of argument list!");
QualType ArgType = *I;
Args.push_back(std::make_pair(EmitCallArg(*Arg, ArgType),
ArgType));
EmitCallArg(Args, *Arg, *I);
}
// Either we've emitted all the call args, or we have a call to a
// variadic function.
@ -1222,8 +1220,7 @@ CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D,
// If we still have any arguments, emit them using the type of the argument.
for (; Arg != ArgEnd; ++Arg) {
QualType ArgType = Arg->getType();
Args.push_back(std::make_pair(EmitCallArg(*Arg, ArgType),
ArgType));
EmitCallArg(Args, *Arg, ArgType);
}
QualType ResultType = FPT->getResultType();
@ -1261,11 +1258,8 @@ CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor,
// Explicit arguments.
for (; I != E; ++I) {
const VarDecl *Param = *I;
QualType ArgType = Param->getType(); // because we're passing it to itself
RValue Arg = EmitDelegateCallArg(Param);
DelegateArgs.push_back(std::make_pair(Arg, ArgType));
const VarDecl *param = *I;
EmitDelegateCallArg(DelegateArgs, param);
}
EmitCall(CGM.getTypes().getFunctionInfo(Ctor, CtorType),

View File

@ -956,9 +956,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
placementArg->getType()) &&
"type mismatch in call argument!");
allocatorArgs.push_back(std::make_pair(EmitCallArg(*placementArg, argType),
argType));
EmitCallArg(allocatorArgs, *placementArg, argType);
}
// Either we've emitted all the call args, or we have a call to a
@ -970,9 +968,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
// If we still have any arguments, emit them using the type of the argument.
for (CXXNewExpr::const_arg_iterator placementArgsEnd = E->placement_arg_end();
placementArg != placementArgsEnd; ++placementArg) {
QualType argType = placementArg->getType();
allocatorArgs.push_back(std::make_pair(EmitCallArg(*placementArg, argType),
argType));
EmitCallArg(allocatorArgs, *placementArg, placementArg->getType());
}
// Emit the allocation call.

View File

@ -2613,11 +2613,8 @@ void CodeGenFunction::GenerateThunk(llvm::Function *Fn,
// Add the rest of the parameters.
for (FunctionDecl::param_const_iterator I = MD->param_begin(),
E = MD->param_end(); I != E; ++I) {
ParmVarDecl *Param = *I;
QualType ArgType = Param->getType();
RValue Arg = EmitDelegateCallArg(Param);
CallArgs.push_back(std::make_pair(Arg, ArgType));
ParmVarDecl *param = *I;
EmitDelegateCallArg(CallArgs, param);
}
// Get our callee.

View File

@ -2087,12 +2087,12 @@ public:
llvm::BasicBlock *getTrapBB();
/// EmitCallArg - Emit a single call argument.
RValue EmitCallArg(const Expr *E, QualType ArgType);
void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType);
/// EmitDelegateCallArg - We are performing a delegate call; that
/// is, the current function is delegating to another one. Produce
/// a r-value suitable for passing the given parameter.
RValue EmitDelegateCallArg(const VarDecl *Param);
void EmitDelegateCallArg(CallArgList &args, const VarDecl *param);
private:
void EmitReturnOfRValue(RValue RV, QualType Ty);
@ -2157,8 +2157,7 @@ private:
getContext().getCanonicalType(ActualArgType).getTypePtr() &&
"type mismatch in call argument!");
#endif
Args.push_back(std::make_pair(EmitCallArg(*Arg, ArgType),
ArgType));
EmitCallArg(Args, *Arg, ArgType);
}
// Either we've emitted all the call args, or we have a call to a
@ -2169,11 +2168,8 @@ private:
}
// If we still have any arguments, emit them using the type of the argument.
for (; Arg != ArgEnd; ++Arg) {
QualType ArgType = Arg->getType();
Args.push_back(std::make_pair(EmitCallArg(*Arg, ArgType),
ArgType));
}
for (; Arg != ArgEnd; ++Arg)
EmitCallArg(Args, *Arg, Arg->getType());
}
const TargetCodeGenInfo &getTargetHooks() const {