diff options
author | Daniel Dunbar <daniel@zuster.org> | 2008-09-10 04:01:49 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2008-09-10 04:01:49 +0000 |
commit | 45c25ba11cbf8c9a461def5b03f6ee9481e06769 (patch) | |
tree | 2be394b3b5a29a887130e782ffc0fcac8a1f48cd /lib/CodeGen/CGCall.cpp | |
parent | 2c8e0f32b9c33686be23c70add0b97490903de9f (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.cpp | 79 |
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()) { |