Standardize the parsing of function type attributes in a way that
follows (as conservatively as possible) gcc's current behavior: attributes
written on return types that don't apply there are applied to the function
instead, etc. Only parse CC attributes as type attributes, not as decl attributes;
don't accepet noreturn as a decl attribute on ValueDecls, either (it still
needs to apply to other decls, like blocks). Consistently consume CC/noreturn
information throughout codegen; enforce this by removing their default values
in CodeGenTypes::getFunctionInfo().
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95436 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index ce361f0..7a47d5b 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -33,12 +33,19 @@
// 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 @@
// 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 @@
// 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 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 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 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 @@
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 @@
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 @@
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 @@
}
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 @@
CallingConv = FI.getEffectiveCallingConvention();
+ if (FI.isNoReturn())
+ FuncAttrs |= llvm::Attribute::NoReturn;
+
// FIXME: handle sseregparm someday...
if (TargetDecl) {
if (TargetDecl->hasAttr<NoThrowAttr>())