aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGCall.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2008-09-10 04:01:49 +0000
committerDaniel Dunbar <daniel@zuster.org>2008-09-10 04:01:49 +0000
commit45c25ba11cbf8c9a461def5b03f6ee9481e06769 (patch)
tree2be394b3b5a29a887130e782ffc0fcac8a1f48cd /lib/CodeGen/CGCall.cpp
parent2c8e0f32b9c33686be23c70add0b97490903de9f (diff)
Move FunctionType conversion into CGCall.cpp:
- Added CodeGenTypes::GetFunctionType, taking a CGFunctionInfo. - Updated Obj-C runtimes to use this instead of rolling the llvm::FunctionType by hand. - Killed CodeGenTypes::{ConvertReturnType, DecodeArgumentTypes}. Add ABIArgInfo class to encapsulate ABI decision of how to lower types to LLVM. - Will move to target sometime soon. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56047 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCall.cpp')
-rw-r--r--lib/CodeGen/CGCall.cpp79
1 files changed, 73 insertions, 6 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 7095165ec8..b684b4463e 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -26,21 +26,39 @@ using namespace CodeGen;
// FIXME: Use iterator and sidestep silly type array creation.
+CGFunctionInfo::CGFunctionInfo(const FunctionTypeNoProto *FTNP)
+ : IsVariadic(true)
+{
+ ArgTypes.push_back(FTNP->getResultType());
+}
+
+CGFunctionInfo::CGFunctionInfo(const FunctionTypeProto *FTP)
+ : IsVariadic(FTP->isVariadic())
+{
+ ArgTypes.push_back(FTP->getResultType());
+ for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
+ ArgTypes.push_back(FTP->getArgType(i));
+}
+
+// FIXME: Is there really any reason to have this still?
CGFunctionInfo::CGFunctionInfo(const FunctionDecl *FD)
- : TheDecl(FD)
{
const FunctionType *FTy = FD->getType()->getAsFunctionType();
const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(FTy);
-
+
ArgTypes.push_back(FTy->getResultType());
- if (FTP)
+ if (FTP) {
+ IsVariadic = FTP->isVariadic();
for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
ArgTypes.push_back(FTP->getArgType(i));
+ } else {
+ IsVariadic = true;
+ }
}
CGFunctionInfo::CGFunctionInfo(const ObjCMethodDecl *MD,
const ASTContext &Context)
- : TheDecl(MD)
+ : IsVariadic(MD->isVariadic())
{
ArgTypes.push_back(MD->getResultType());
ArgTypes.push_back(MD->getSelfDecl()->getType());
@@ -105,6 +123,12 @@ public:
bool isDefault() const { return TheKind == Default; }
bool isStructRet() const { return TheKind == StructRet; }
bool isCoerce() const { return TheKind == Coerce; }
+
+ // Coerce accessors
+ QualType getCoerceToType() const {
+ assert(TheKind == Coerce && "Invalid kind!");
+ return TypeData;
+ }
};
/***/
@@ -119,6 +143,49 @@ static ABIArgInfo classifyReturnType(QualType RetTy) {
/***/
+const llvm::FunctionType *
+CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) {
+ std::vector<const llvm::Type*> ArgTys;
+
+ const llvm::Type *ResultType = 0;
+
+ ArgTypeIterator begin = FI.argtypes_begin(), end = FI.argtypes_end();
+ QualType RetTy = *begin;
+ ABIArgInfo RetAI = classifyReturnType(RetTy);
+ switch (RetAI.getKind()) {
+ case ABIArgInfo::Default:
+ if (RetTy->isVoidType()) {
+ ResultType = llvm::Type::VoidTy;
+ } else {
+ ResultType = ConvertTypeRecursive(RetTy);
+ }
+ break;
+
+ case ABIArgInfo::StructRet: {
+ ResultType = llvm::Type::VoidTy;
+ const llvm::Type *STy = ConvertTypeRecursive(RetTy);
+ ArgTys.push_back(llvm::PointerType::get(STy, RetTy.getAddressSpace()));
+ break;
+ }
+
+ case ABIArgInfo::Coerce:
+ ResultType = llvm::Type::VoidTy;
+ ArgTys.push_back(ConvertTypeRecursive(RetAI.getCoerceToType()));
+ break;
+ }
+
+ for (++begin; begin != end; ++begin) {
+ const llvm::Type *Ty = ConvertTypeRecursive(*begin);
+ if (Ty->isSingleValueType())
+ ArgTys.push_back(Ty);
+ else
+ // byval arguments are always on the stack, which is addr space #0.
+ ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
+ }
+
+ return llvm::FunctionType::get(ResultType, ArgTys, FI.isVariadic());
+}
+
bool CodeGenModule::ReturnTypeUsesSret(QualType RetTy) {
return classifyReturnType(RetTy).isStructRet();
}
@@ -138,8 +205,8 @@ void CodeGenModule::ConstructParamAttrList(const Decl *TargetDecl,
QualType RetTy = *begin;
unsigned Index = 1;
- ABIArgInfo ResAI = classifyReturnType(RetTy);
- switch (ResAI.getKind()) {
+ ABIArgInfo RetAI = classifyReturnType(RetTy);
+ switch (RetAI.getKind()) {
case ABIArgInfo::Default:
if (RetTy->isPromotableIntegerType()) {
if (RetTy->isSignedIntegerType()) {