aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGCall.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGCall.cpp')
-rw-r--r--lib/CodeGen/CGCall.cpp76
1 files changed, 47 insertions, 29 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index ce361f08fe..7a47d5bcc0 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -33,12 +33,19 @@ using namespace CodeGen;
// FIXME: Use iterator and sidestep silly type array creation.
+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;
+ }
+}
+
const
CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionNoProtoType *FTNP) {
- // FIXME: Set calling convention correctly, it needs to be associated with the
- // type somehow.
return getFunctionInfo(FTNP->getResultType(),
- llvm::SmallVector<QualType, 16>(), 0);
+ llvm::SmallVector<QualType, 16>(),
+ FTNP->getCallConv(), FTNP->getNoReturnAttr());
}
const
@@ -47,20 +54,19 @@ CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionProtoType *FTP) {
// FIXME: Kill copy.
for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
ArgTys.push_back(FTP->getArgType(i));
- // FIXME: Set calling convention correctly, it needs to be associated with the
- // type somehow.
- return getFunctionInfo(FTP->getResultType(), ArgTys, 0);
+ return getFunctionInfo(FTP->getResultType(), ArgTys,
+ FTP->getCallConv(), FTP->getNoReturnAttr());
}
-static unsigned getCallingConventionForDecl(const Decl *D) {
+static CallingConv getCallingConventionForDecl(const Decl *D) {
// Set the appropriate calling convention for the Function.
if (D->hasAttr<StdCallAttr>())
- return llvm::CallingConv::X86_StdCall;
+ return CC_X86StdCall;
if (D->hasAttr<FastCallAttr>())
- return llvm::CallingConv::X86_FastCall;
+ return CC_X86FastCall;
- return llvm::CallingConv::C;
+ return CC_C;
}
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXRecordDecl *RD,
@@ -75,7 +81,8 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXRecordDecl *RD,
// FIXME: Set calling convention correctly, it needs to be associated with the
// type somehow.
- return getFunctionInfo(FTP->getResultType(), ArgTys, 0);
+ return getFunctionInfo(FTP->getResultType(), ArgTys,
+ FTP->getCallConv(), FTP->getNoReturnAttr());
}
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXMethodDecl *MD) {
@@ -87,8 +94,8 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXMethodDecl *MD) {
const FunctionProtoType *FTP = MD->getType()->getAs<FunctionProtoType>();
for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
ArgTys.push_back(FTP->getArgType(i));
- return getFunctionInfo(FTP->getResultType(), ArgTys,
- getCallingConventionForDecl(MD));
+ return getFunctionInfo(FTP->getResultType(), ArgTys, FTP->getCallConv(),
+ FTP->getNoReturnAttr());
}
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXConstructorDecl *D,
@@ -105,8 +112,8 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXConstructorDecl *D,
const FunctionProtoType *FTP = D->getType()->getAs<FunctionProtoType>();
for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
ArgTys.push_back(FTP->getArgType(i));
- return getFunctionInfo(FTP->getResultType(), ArgTys,
- getCallingConventionForDecl(D));
+ return getFunctionInfo(FTP->getResultType(), ArgTys, FTP->getCallConv(),
+ FTP->getNoReturnAttr());
}
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXDestructorDecl *D,
@@ -123,8 +130,8 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXDestructorDecl *D,
const FunctionProtoType *FTP = D->getType()->getAs<FunctionProtoType>();
for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
ArgTys.push_back(FTP->getArgType(i));
- return getFunctionInfo(FTP->getResultType(), ArgTys,
- getCallingConventionForDecl(D));
+ return getFunctionInfo(FTP->getResultType(), ArgTys, FTP->getCallConv(),
+ FTP->getNoReturnAttr());
}
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionDecl *FD) {
@@ -132,19 +139,19 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionDecl *FD) {
if (MD->isInstance())
return getFunctionInfo(MD);
- unsigned CallingConvention = getCallingConventionForDecl(FD);
const FunctionType *FTy = FD->getType()->getAs<FunctionType>();
if (const FunctionNoProtoType *FNTP = dyn_cast<FunctionNoProtoType>(FTy))
return getFunctionInfo(FNTP->getResultType(),
llvm::SmallVector<QualType, 16>(),
- CallingConvention);
+ FNTP->getCallConv(), FNTP->getNoReturnAttr());
const FunctionProtoType *FPT = cast<FunctionProtoType>(FTy);
llvm::SmallVector<QualType, 16> ArgTys;
// FIXME: Kill copy.
for (unsigned i = 0, e = FPT->getNumArgs(); i != e; ++i)
ArgTys.push_back(FPT->getArgType(i));
- return getFunctionInfo(FPT->getResultType(), ArgTys, CallingConvention);
+ return getFunctionInfo(FPT->getResultType(), ArgTys,
+ FPT->getCallConv(), FPT->getNoReturnAttr());
}
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) {
@@ -156,37 +163,43 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) {
e = MD->param_end(); i != e; ++i)
ArgTys.push_back((*i)->getType());
return getFunctionInfo(MD->getResultType(), ArgTys,
- getCallingConventionForDecl(MD));
+ getCallingConventionForDecl(MD),
+ /*NoReturn*/ false);
}
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
const CallArgList &Args,
- unsigned CallingConvention){
+ CallingConv CC,
+ bool NoReturn) {
// FIXME: Kill copy.
llvm::SmallVector<QualType, 16> ArgTys;
for (CallArgList::const_iterator i = Args.begin(), e = Args.end();
i != e; ++i)
ArgTys.push_back(i->second);
- return getFunctionInfo(ResTy, ArgTys, CallingConvention);
+ return getFunctionInfo(ResTy, ArgTys, CC, NoReturn);
}
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
const FunctionArgList &Args,
- unsigned CallingConvention){
+ CallingConv CC,
+ bool NoReturn) {
// FIXME: Kill copy.
llvm::SmallVector<QualType, 16> ArgTys;
for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
i != e; ++i)
ArgTys.push_back(i->second);
- return getFunctionInfo(ResTy, ArgTys, CallingConvention);
+ return getFunctionInfo(ResTy, ArgTys, CC, NoReturn);
}
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
const llvm::SmallVector<QualType, 16> &ArgTys,
- unsigned CallingConvention){
+ CallingConv CallConv,
+ bool NoReturn) {
+ unsigned CC = ClangCallConvToLLVMCallConv(CallConv);
+
// Lookup or create unique function info.
llvm::FoldingSetNodeID ID;
- CGFunctionInfo::Profile(ID, CallingConvention, ResTy,
+ CGFunctionInfo::Profile(ID, CC, NoReturn, ResTy,
ArgTys.begin(), ArgTys.end());
void *InsertPos = 0;
@@ -195,7 +208,7 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
return *FI;
// Construct the function info.
- FI = new CGFunctionInfo(CallingConvention, ResTy, ArgTys);
+ FI = new CGFunctionInfo(CC, NoReturn, ResTy, ArgTys);
FunctionInfos.InsertNode(FI, InsertPos);
// Compute ABI information.
@@ -205,10 +218,12 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
}
CGFunctionInfo::CGFunctionInfo(unsigned _CallingConvention,
+ bool _NoReturn,
QualType ResTy,
const llvm::SmallVector<QualType, 16> &ArgTys)
: CallingConvention(_CallingConvention),
- EffectiveCallingConvention(_CallingConvention)
+ EffectiveCallingConvention(_CallingConvention),
+ NoReturn(_NoReturn)
{
NumArgs = ArgTys.size();
Args = new ArgInfo[1 + NumArgs];
@@ -490,6 +505,9 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
CallingConv = FI.getEffectiveCallingConvention();
+ if (FI.isNoReturn())
+ FuncAttrs |= llvm::Attribute::NoReturn;
+
// FIXME: handle sseregparm someday...
if (TargetDecl) {
if (TargetDecl->hasAttr<NoThrowAttr>())