diff options
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.h')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 96 |
1 files changed, 53 insertions, 43 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index db291e3b1dd..2ddb1b9460d 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -2493,68 +2493,78 @@ private: SourceLocation Loc); /// EmitCallArgs - Emit call arguments for a function. - /// The CallArgTypeInfo parameter is used for iterating over the known - /// argument types of the function being called. - template<typename T> - void EmitCallArgs(CallArgList& Args, const T* CallArgTypeInfo, + template <typename T> + void EmitCallArgs(CallArgList &Args, const T *CallArgTypeInfo, CallExpr::const_arg_iterator ArgBeg, CallExpr::const_arg_iterator ArgEnd, bool ForceColumnInfo = false) { - CGDebugInfo *DI = getDebugInfo(); - SourceLocation CallLoc; - if (DI) CallLoc = DI->getLocation(); + if (CallArgTypeInfo) { + EmitCallArgs(Args, CallArgTypeInfo->isVariadic(), + CallArgTypeInfo->arg_type_begin(), + CallArgTypeInfo->arg_type_end(), ArgBeg, ArgEnd, + ForceColumnInfo); + } else { + // T::arg_type_iterator might not have a default ctor. + const QualType *NoIter = 0; + EmitCallArgs(Args, /*AllowExtraArguments=*/true, NoIter, NoIter, ArgBeg, + ArgEnd, ForceColumnInfo); + } + } + template<typename ArgTypeIterator> + void EmitCallArgs(CallArgList& Args, + bool AllowExtraArguments, + ArgTypeIterator ArgTypeBeg, + ArgTypeIterator ArgTypeEnd, + CallExpr::const_arg_iterator ArgBeg, + CallExpr::const_arg_iterator ArgEnd, + bool ForceColumnInfo = false) { + SmallVector<QualType, 16> ArgTypes; 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) { - assert(Arg != ArgEnd && "Running over edge of argument list!"); - QualType ArgType = *I; + for (ArgTypeIterator I = ArgTypeBeg, E = ArgTypeEnd; I != E; ++I, ++Arg) { + assert(Arg != ArgEnd && "Running over edge of argument list!"); #ifndef NDEBUG - QualType ActualArgType = Arg->getType(); - if (ArgType->isPointerType() && ActualArgType->isPointerType()) { - QualType ActualBaseType = + QualType ArgType = *I; + QualType ActualArgType = Arg->getType(); + if (ArgType->isPointerType() && ActualArgType->isPointerType()) { + QualType ActualBaseType = ActualArgType->getAs<PointerType>()->getPointeeType(); - QualType ArgBaseType = + QualType ArgBaseType = ArgType->getAs<PointerType>()->getPointeeType(); - if (ArgBaseType->isVariableArrayType()) { - if (const VariableArrayType *VAT = - getContext().getAsVariableArrayType(ActualBaseType)) { - if (!VAT->getSizeExpr()) - ActualArgType = ArgType; - } + if (ArgBaseType->isVariableArrayType()) { + if (const VariableArrayType *VAT = + getContext().getAsVariableArrayType(ActualBaseType)) { + if (!VAT->getSizeExpr()) + ActualArgType = ArgType; } } - assert(getContext().getCanonicalType(ArgType.getNonReferenceType()). - getTypePtr() == - getContext().getCanonicalType(ActualArgType).getTypePtr() && - "type mismatch in call argument!"); -#endif - EmitCallArg(Args, *Arg, ArgType); - - // Each argument expression could modify the debug - // location. Restore it. - if (DI) DI->EmitLocation(Builder, CallLoc, ForceColumnInfo); } - - // 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!"); - + assert(getContext().getCanonicalType(ArgType.getNonReferenceType()). + getTypePtr() == + getContext().getCanonicalType(ActualArgType).getTypePtr() && + "type mismatch in call argument!"); +#endif + ArgTypes.push_back(*I); } + // Either we've emitted all the call args, or we have a call to variadic + // function or some other call that allows extra arguments. + assert((Arg == ArgEnd || AllowExtraArguments) && + "Extra arguments in non-variadic function!"); + // If we still have any arguments, emit them using the type of the argument. - for (; Arg != ArgEnd; ++Arg) { - EmitCallArg(Args, *Arg, Arg->getType()); + for (; Arg != ArgEnd; ++Arg) + ArgTypes.push_back(Arg->getType()); - // Restore the debug location. - if (DI) DI->EmitLocation(Builder, CallLoc, ForceColumnInfo); - } + EmitCallArgs(Args, ArgTypes, ArgBeg, ArgEnd, ForceColumnInfo); } + void EmitCallArgs(CallArgList &Args, ArrayRef<QualType> ArgTypes, + CallExpr::const_arg_iterator ArgBeg, + CallExpr::const_arg_iterator ArgEnd, bool ForceColumnInfo); + const TargetCodeGenInfo &getTargetHooks() const { return CGM.getTargetCodeGenInfo(); } |