From: Anders Carlsson Date: Sat, 18 Apr 2009 20:20:22 +0000 (+0000) Subject: Make CodeGenFunction::EmitCallArgs a template function that takes a generic "Type... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=af23f69aa6247e6bd20a66b2e16babb91f192535;p=clang Make CodeGenFunction::EmitCallArgs a template function that takes a generic "Type Info" parameter. The type info parameter knows how to iterate over its arguments. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69469 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index e6474cb9ee..d17ab13446 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -1935,38 +1935,6 @@ RValue CodeGenFunction::EmitCallArg(const Expr *E, QualType ArgType) { return EmitAnyExprToTemp(E); } -void CodeGenFunction::EmitCallArgs(CallArgList& Args, - const FunctionProtoType *FPT, - CallExpr::const_arg_iterator ArgBeg, - CallExpr::const_arg_iterator ArgEnd) { - CallExpr::const_arg_iterator Arg = ArgBeg; - - // First, use the function argument types. - if (FPT) { - for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin(), - E = FPT->arg_type_end(); I != E; ++I, ++Arg) { - assert(getContext().getCanonicalType(I->getNonReferenceType()). - getTypePtr() == - getContext().getCanonicalType(Arg->getType()).getTypePtr() && - "type mismatch in call argument!"); - - QualType ArgType = *I; - Args.push_back(std::make_pair(EmitCallArg(*Arg, ArgType), - ArgType)); - } - - assert(Arg == ArgEnd || FPT->isVariadic() && - "Extra arguments in non-variadic function!"); - } - - // 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)); - } -} - RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, llvm::Value *Callee, const CallArgList &CallArgs, diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index d511da3f7f..45f96d33b7 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -811,14 +811,46 @@ private: RValue EmitCallArg(const Expr *E, QualType ArgType); /// EmitCallArgs - Emit call arguments for a function. - /// FIXME: It should be possible to generalize this and pass a generic - /// "argument type container" type instead of the FunctionProtoType. This way - /// it can work on Objective-C methods as well. - void EmitCallArgs(CallArgList& args, const FunctionProtoType *FPT, + /// The CallArgTypeInfo parameter is used for iterating over the known + /// argument types of the function being called. + template + void EmitCallArgs(CallArgList& Args, const T* CallArgTypeInfo, CallExpr::const_arg_iterator ArgBeg, - CallExpr::const_arg_iterator ArgEnd); - + CallExpr::const_arg_iterator ArgEnd) { + CallExpr::const_arg_iterator Arg = ArgBeg; + + // First, use the argument types that the type info knows about + if (CallArgTypeInfo) { + for (typename T::arg_type_iterator I = CallArgTypeInfo->arg_type_begin(), + E = CallArgTypeInfo->arg_type_end(); I != E; ++I, ++Arg) { + QualType ArgType = *I; + + assert(getContext().getCanonicalType(ArgType.getNonReferenceType()). + getTypePtr() == + getContext().getCanonicalType(Arg->getType()).getTypePtr() && + "type mismatch in call argument!"); + + 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 + // variadic function. + assert(Arg == ArgEnd || CallArgTypeInfo->isVariadic() && + "Extra arguments in non-variadic function!"); + + } + + // 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)); + } + } }; + + } // end namespace CodeGen } // end namespace clang