forked from OSchip/llvm-project
Use a slightly more semantic interface for emitting call arguments.
llvm-svn: 127494
This commit is contained in:
parent
d767d06b26
commit
32ea969415
|
@ -1116,42 +1116,48 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI) {
|
||||||
Ret->setDebugLoc(RetDbgLoc);
|
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
|
// StartFunction converted the ABI-lowered parameter(s) into a
|
||||||
// local alloca. We need to turn that into an r-value suitable
|
// local alloca. We need to turn that into an r-value suitable
|
||||||
// for EmitCall.
|
// 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:
|
// For the most part, we just need to load the alloca, except:
|
||||||
// 1) aggregate r-values are actually pointers to temporaries, and
|
// 1) aggregate r-values are actually pointers to temporaries, and
|
||||||
// 2) references to aggregates are pointers directly to the aggregate.
|
// 2) references to aggregates are pointers directly to the aggregate.
|
||||||
// I don't know why references to non-aggregates are different here.
|
// I don't know why references to non-aggregates are different here.
|
||||||
if (const ReferenceType *RefType = ArgType->getAs<ReferenceType>()) {
|
if (const ReferenceType *ref = type->getAs<ReferenceType>()) {
|
||||||
if (hasAggregateLLVMType(RefType->getPointeeType()))
|
if (hasAggregateLLVMType(ref->getPointeeType()))
|
||||||
return RValue::getAggregate(Local);
|
return args.add(RValue::getAggregate(local), type);
|
||||||
|
|
||||||
// Locals which are references to scalars are represented
|
// Locals which are references to scalars are represented
|
||||||
// with allocas holding the pointer.
|
// with allocas holding the pointer.
|
||||||
return RValue::get(Builder.CreateLoad(Local));
|
return args.add(RValue::get(Builder.CreateLoad(local)), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ArgType->isAnyComplexType())
|
if (type->isAnyComplexType()) {
|
||||||
return RValue::getComplex(LoadComplexFromAddr(Local, /*volatile*/ false));
|
ComplexPairTy complex = LoadComplexFromAddr(local, /*volatile*/ false);
|
||||||
|
return args.add(RValue::getComplex(complex), type);
|
||||||
|
}
|
||||||
|
|
||||||
if (hasAggregateLLVMType(ArgType))
|
if (hasAggregateLLVMType(type))
|
||||||
return RValue::getAggregate(Local);
|
return args.add(RValue::getAggregate(local), type);
|
||||||
|
|
||||||
unsigned Alignment = getContext().getDeclAlign(Param).getQuantity();
|
unsigned alignment = getContext().getDeclAlign(param).getQuantity();
|
||||||
return RValue::get(EmitLoadOfScalar(Local, false, Alignment, ArgType));
|
llvm::Value *value = EmitLoadOfScalar(local, false, alignment, type);
|
||||||
|
return args.add(RValue::get(value), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
RValue CodeGenFunction::EmitCallArg(const Expr *E, QualType ArgType) {
|
void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
|
||||||
if (ArgType->isReferenceType())
|
QualType type) {
|
||||||
return EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0);
|
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
|
/// Emits a call or invoke instruction to the given function, depending
|
||||||
|
|
|
@ -48,6 +48,10 @@ namespace CodeGen {
|
||||||
/// arguments in a call.
|
/// arguments in a call.
|
||||||
class CallArgList :
|
class CallArgList :
|
||||||
public llvm::SmallVector<std::pair<RValue, QualType>, 16> {
|
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
|
/// FunctionArgList - Type for representing both the decl and type
|
||||||
|
|
|
@ -1211,9 +1211,7 @@ CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D,
|
||||||
for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin()+1,
|
for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin()+1,
|
||||||
E = FPT->arg_type_end(); I != E; ++I, ++Arg) {
|
E = FPT->arg_type_end(); I != E; ++I, ++Arg) {
|
||||||
assert(Arg != ArgEnd && "Running over edge of argument list!");
|
assert(Arg != ArgEnd && "Running over edge of argument list!");
|
||||||
QualType ArgType = *I;
|
EmitCallArg(Args, *Arg, *I);
|
||||||
Args.push_back(std::make_pair(EmitCallArg(*Arg, ArgType),
|
|
||||||
ArgType));
|
|
||||||
}
|
}
|
||||||
// Either we've emitted all the call args, or we have a call to a
|
// Either we've emitted all the call args, or we have a call to a
|
||||||
// variadic function.
|
// 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.
|
// If we still have any arguments, emit them using the type of the argument.
|
||||||
for (; Arg != ArgEnd; ++Arg) {
|
for (; Arg != ArgEnd; ++Arg) {
|
||||||
QualType ArgType = Arg->getType();
|
QualType ArgType = Arg->getType();
|
||||||
Args.push_back(std::make_pair(EmitCallArg(*Arg, ArgType),
|
EmitCallArg(Args, *Arg, ArgType);
|
||||||
ArgType));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QualType ResultType = FPT->getResultType();
|
QualType ResultType = FPT->getResultType();
|
||||||
|
@ -1261,11 +1258,8 @@ CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor,
|
||||||
|
|
||||||
// Explicit arguments.
|
// Explicit arguments.
|
||||||
for (; I != E; ++I) {
|
for (; I != E; ++I) {
|
||||||
const VarDecl *Param = *I;
|
const VarDecl *param = *I;
|
||||||
QualType ArgType = Param->getType(); // because we're passing it to itself
|
EmitDelegateCallArg(DelegateArgs, param);
|
||||||
RValue Arg = EmitDelegateCallArg(Param);
|
|
||||||
|
|
||||||
DelegateArgs.push_back(std::make_pair(Arg, ArgType));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EmitCall(CGM.getTypes().getFunctionInfo(Ctor, CtorType),
|
EmitCall(CGM.getTypes().getFunctionInfo(Ctor, CtorType),
|
||||||
|
|
|
@ -956,9 +956,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
|
||||||
placementArg->getType()) &&
|
placementArg->getType()) &&
|
||||||
"type mismatch in call argument!");
|
"type mismatch in call argument!");
|
||||||
|
|
||||||
allocatorArgs.push_back(std::make_pair(EmitCallArg(*placementArg, argType),
|
EmitCallArg(allocatorArgs, *placementArg, argType);
|
||||||
argType));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Either we've emitted all the call args, or we have a call to a
|
// 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.
|
// If we still have any arguments, emit them using the type of the argument.
|
||||||
for (CXXNewExpr::const_arg_iterator placementArgsEnd = E->placement_arg_end();
|
for (CXXNewExpr::const_arg_iterator placementArgsEnd = E->placement_arg_end();
|
||||||
placementArg != placementArgsEnd; ++placementArg) {
|
placementArg != placementArgsEnd; ++placementArg) {
|
||||||
QualType argType = placementArg->getType();
|
EmitCallArg(allocatorArgs, *placementArg, placementArg->getType());
|
||||||
allocatorArgs.push_back(std::make_pair(EmitCallArg(*placementArg, argType),
|
|
||||||
argType));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit the allocation call.
|
// Emit the allocation call.
|
||||||
|
|
|
@ -2613,11 +2613,8 @@ void CodeGenFunction::GenerateThunk(llvm::Function *Fn,
|
||||||
// Add the rest of the parameters.
|
// Add the rest of the parameters.
|
||||||
for (FunctionDecl::param_const_iterator I = MD->param_begin(),
|
for (FunctionDecl::param_const_iterator I = MD->param_begin(),
|
||||||
E = MD->param_end(); I != E; ++I) {
|
E = MD->param_end(); I != E; ++I) {
|
||||||
ParmVarDecl *Param = *I;
|
ParmVarDecl *param = *I;
|
||||||
QualType ArgType = Param->getType();
|
EmitDelegateCallArg(CallArgs, param);
|
||||||
RValue Arg = EmitDelegateCallArg(Param);
|
|
||||||
|
|
||||||
CallArgs.push_back(std::make_pair(Arg, ArgType));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get our callee.
|
// Get our callee.
|
||||||
|
|
|
@ -2087,12 +2087,12 @@ public:
|
||||||
llvm::BasicBlock *getTrapBB();
|
llvm::BasicBlock *getTrapBB();
|
||||||
|
|
||||||
/// EmitCallArg - Emit a single call argument.
|
/// 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
|
/// EmitDelegateCallArg - We are performing a delegate call; that
|
||||||
/// is, the current function is delegating to another one. Produce
|
/// is, the current function is delegating to another one. Produce
|
||||||
/// a r-value suitable for passing the given parameter.
|
/// a r-value suitable for passing the given parameter.
|
||||||
RValue EmitDelegateCallArg(const VarDecl *Param);
|
void EmitDelegateCallArg(CallArgList &args, const VarDecl *param);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void EmitReturnOfRValue(RValue RV, QualType Ty);
|
void EmitReturnOfRValue(RValue RV, QualType Ty);
|
||||||
|
@ -2157,8 +2157,7 @@ private:
|
||||||
getContext().getCanonicalType(ActualArgType).getTypePtr() &&
|
getContext().getCanonicalType(ActualArgType).getTypePtr() &&
|
||||||
"type mismatch in call argument!");
|
"type mismatch in call argument!");
|
||||||
#endif
|
#endif
|
||||||
Args.push_back(std::make_pair(EmitCallArg(*Arg, ArgType),
|
EmitCallArg(Args, *Arg, ArgType);
|
||||||
ArgType));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Either we've emitted all the call args, or we have a call to a
|
// 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.
|
// If we still have any arguments, emit them using the type of the argument.
|
||||||
for (; Arg != ArgEnd; ++Arg) {
|
for (; Arg != ArgEnd; ++Arg)
|
||||||
QualType ArgType = Arg->getType();
|
EmitCallArg(Args, *Arg, Arg->getType());
|
||||||
Args.push_back(std::make_pair(EmitCallArg(*Arg, ArgType),
|
|
||||||
ArgType));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const TargetCodeGenInfo &getTargetHooks() const {
|
const TargetCodeGenInfo &getTargetHooks() const {
|
||||||
|
|
Loading…
Reference in New Issue