From: Charles Davis Date: Fri, 5 Feb 2010 18:13:10 +0000 (+0000) Subject: Now that we store calling conventions in the types, use them instead of X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=16c4f3c7d44289e30f5066dce7ce9efe7ff67bbc;p=clang Now that we store calling conventions in the types, use them instead of getting the calling convention from the target function, which may or may not exist. Fixes PR5280. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95399 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 427975deb1..f16c600e9c 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1864,6 +1864,14 @@ LValue CodeGenFunction::EmitStmtExprLValue(const StmtExpr *E) { return LValue::MakeAddr(RV.getAggregateAddr(), MakeQualifiers(E->getType())); } +static unsigned ClangCallConvToLLVMCallConv(CallingConv CC) { + switch (CC) { + default: return llvm::CallingConv::C; + case CC_X86StdCall: return llvm::CallingConv::X86_StdCall; + case CC_X86FastCall: return llvm::CallingConv::X86_FastCall; + } +} + RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee, ReturnValueSlot ReturnValue, CallExpr::const_arg_iterator ArgBeg, @@ -1882,12 +1890,8 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee, CallArgList Args; EmitCallArgs(Args, dyn_cast(FnType), ArgBeg, ArgEnd); - // FIXME: We should not need to do this, it should be part of the function - // type. - unsigned CallingConvention = 0; - if (const llvm::Function *F = - dyn_cast(Callee->stripPointerCasts())) - CallingConvention = F->getCallingConv(); + unsigned CallingConvention = + ClangCallConvToLLVMCallConv(FnType->getAs()->getCallConv()); return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args, CallingConvention), Callee, ReturnValue, Args, TargetDecl); diff --git a/test/CodeGen/stdcall-fastcall.c b/test/CodeGen/stdcall-fastcall.c index 838ccfb48c..1fbed300d8 100644 --- a/test/CodeGen/stdcall-fastcall.c +++ b/test/CodeGen/stdcall-fastcall.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -emit-llvm < %s | grep 'fastcallcc' | count 4 -// RUN: %clang_cc1 -emit-llvm < %s | grep 'stdcallcc' | count 4 +// RUN: %clang_cc1 -emit-llvm < %s | grep 'fastcallcc' | count 6 +// RUN: %clang_cc1 -emit-llvm < %s | grep 'stdcallcc' | count 6 void __attribute__((fastcall)) f1(void); void __attribute__((stdcall)) f2(void); @@ -10,8 +10,15 @@ void __attribute__((stdcall)) f4(void) { f2(); } +// PR5280 +void (__attribute__((fastcall)) *pf1)(void) = f1; +void (__attribute__((stdcall)) *pf2)(void) = f2; +void (__attribute__((fastcall)) *pf3)(void) = f3; +void (__attribute__((stdcall)) *pf4)(void) = f4; + int main(void) { f3(); f4(); + pf1(); pf2(); pf3(); pf4(); return 0; }