aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Davis <cdavis@mines.edu>2010-02-05 18:13:10 +0000
committerCharles Davis <cdavis@mines.edu>2010-02-05 18:13:10 +0000
commit16c4f3c7d44289e30f5066dce7ce9efe7ff67bbc (patch)
tree2781cbdead8abdd85a9e224443ef52fdc0c35da2
parent8ca3eb0eca8230c2419fea229e3973a233c63a4b (diff)
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
-rw-r--r--lib/CodeGen/CGExpr.cpp16
-rw-r--r--test/CodeGen/stdcall-fastcall.c11
2 files changed, 19 insertions, 8 deletions
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<FunctionProtoType>(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<llvm::Function>(Callee->stripPointerCasts()))
- CallingConvention = F->getCallingConv();
+ unsigned CallingConvention =
+ ClangCallConvToLLVMCallConv(FnType->getAs<FunctionType>()->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;
}