forked from OSchip/llvm-project
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. llvm-svn: 56047
This commit is contained in:
parent
a72d4aece6
commit
7a95ca3197
|
@ -26,21 +26,39 @@ using namespace CodeGen;
|
||||||
|
|
||||||
// FIXME: Use iterator and sidestep silly type array creation.
|
// 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)
|
CGFunctionInfo::CGFunctionInfo(const FunctionDecl *FD)
|
||||||
: TheDecl(FD)
|
|
||||||
{
|
{
|
||||||
const FunctionType *FTy = FD->getType()->getAsFunctionType();
|
const FunctionType *FTy = FD->getType()->getAsFunctionType();
|
||||||
const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(FTy);
|
const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(FTy);
|
||||||
|
|
||||||
ArgTypes.push_back(FTy->getResultType());
|
ArgTypes.push_back(FTy->getResultType());
|
||||||
if (FTP)
|
if (FTP) {
|
||||||
|
IsVariadic = FTP->isVariadic();
|
||||||
for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
|
for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
|
||||||
ArgTypes.push_back(FTP->getArgType(i));
|
ArgTypes.push_back(FTP->getArgType(i));
|
||||||
|
} else {
|
||||||
|
IsVariadic = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CGFunctionInfo::CGFunctionInfo(const ObjCMethodDecl *MD,
|
CGFunctionInfo::CGFunctionInfo(const ObjCMethodDecl *MD,
|
||||||
const ASTContext &Context)
|
const ASTContext &Context)
|
||||||
: TheDecl(MD)
|
: IsVariadic(MD->isVariadic())
|
||||||
{
|
{
|
||||||
ArgTypes.push_back(MD->getResultType());
|
ArgTypes.push_back(MD->getResultType());
|
||||||
ArgTypes.push_back(MD->getSelfDecl()->getType());
|
ArgTypes.push_back(MD->getSelfDecl()->getType());
|
||||||
|
@ -105,6 +123,12 @@ public:
|
||||||
bool isDefault() const { return TheKind == Default; }
|
bool isDefault() const { return TheKind == Default; }
|
||||||
bool isStructRet() const { return TheKind == StructRet; }
|
bool isStructRet() const { return TheKind == StructRet; }
|
||||||
bool isCoerce() const { return TheKind == Coerce; }
|
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) {
|
bool CodeGenModule::ReturnTypeUsesSret(QualType RetTy) {
|
||||||
return classifyReturnType(RetTy).isStructRet();
|
return classifyReturnType(RetTy).isStructRet();
|
||||||
}
|
}
|
||||||
|
@ -138,8 +205,8 @@ void CodeGenModule::ConstructParamAttrList(const Decl *TargetDecl,
|
||||||
|
|
||||||
QualType RetTy = *begin;
|
QualType RetTy = *begin;
|
||||||
unsigned Index = 1;
|
unsigned Index = 1;
|
||||||
ABIArgInfo ResAI = classifyReturnType(RetTy);
|
ABIArgInfo RetAI = classifyReturnType(RetTy);
|
||||||
switch (ResAI.getKind()) {
|
switch (RetAI.getKind()) {
|
||||||
case ABIArgInfo::Default:
|
case ABIArgInfo::Default:
|
||||||
if (RetTy->isPromotableIntegerType()) {
|
if (RetTy->isPromotableIntegerType()) {
|
||||||
if (RetTy->isSignedIntegerType()) {
|
if (RetTy->isSignedIntegerType()) {
|
||||||
|
|
|
@ -54,18 +54,18 @@ namespace CodeGen {
|
||||||
/// CGFunctionInfo - Class to encapsulate the information about a
|
/// CGFunctionInfo - Class to encapsulate the information about a
|
||||||
/// function definition.
|
/// function definition.
|
||||||
class CGFunctionInfo {
|
class CGFunctionInfo {
|
||||||
/// TheDecl - The decl we are storing information for. This is
|
bool IsVariadic;
|
||||||
/// either a Function or ObjCMethod Decl.
|
|
||||||
const Decl *TheDecl;
|
|
||||||
|
|
||||||
llvm::SmallVector<QualType, 16> ArgTypes;
|
llvm::SmallVector<QualType, 16> ArgTypes;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
CGFunctionInfo(const FunctionTypeNoProto *FTNP);
|
||||||
|
CGFunctionInfo(const FunctionTypeProto *FTP);
|
||||||
CGFunctionInfo(const FunctionDecl *FD);
|
CGFunctionInfo(const FunctionDecl *FD);
|
||||||
CGFunctionInfo(const ObjCMethodDecl *MD,
|
CGFunctionInfo(const ObjCMethodDecl *MD,
|
||||||
const ASTContext &Context);
|
const ASTContext &Context);
|
||||||
|
|
||||||
const Decl* getDecl() const { return TheDecl; }
|
bool isVariadic() const { return IsVariadic; }
|
||||||
|
|
||||||
ArgTypeIterator argtypes_begin() const;
|
ArgTypeIterator argtypes_begin() const;
|
||||||
ArgTypeIterator argtypes_end() const;
|
ArgTypeIterator argtypes_end() const;
|
||||||
|
|
|
@ -921,40 +921,15 @@ llvm::Function *CGObjCGNU::ModuleInitFunction() {
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD) {
|
llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD) {
|
||||||
const llvm::Type *ReturnTy =
|
|
||||||
CGM.getTypes().ConvertReturnType(OMD->getResultType());
|
|
||||||
const ObjCCategoryImplDecl *OCD =
|
const ObjCCategoryImplDecl *OCD =
|
||||||
dyn_cast<ObjCCategoryImplDecl>(OMD->getMethodContext());
|
dyn_cast<ObjCCategoryImplDecl>(OMD->getMethodContext());
|
||||||
const std::string &CategoryName = OCD ? OCD->getName() : "";
|
const std::string &CategoryName = OCD ? OCD->getName() : "";
|
||||||
const llvm::Type *SelfTy = llvm::PointerType::getUnqual(llvm::Type::Int32Ty);
|
|
||||||
const std::string &ClassName = OMD->getClassInterface()->getName();
|
const std::string &ClassName = OMD->getClassInterface()->getName();
|
||||||
const std::string &MethodName = OMD->getSelector().getName();
|
const std::string &MethodName = OMD->getSelector().getName();
|
||||||
unsigned ArgC = OMD->param_size();
|
|
||||||
bool isClassMethod = !OMD->isInstance();
|
bool isClassMethod = !OMD->isInstance();
|
||||||
bool isVarArg = OMD->isVariadic();
|
|
||||||
|
|
||||||
llvm::SmallVector<const llvm::Type *, 16> ArgTy;
|
const llvm::FunctionType *MethodTy =
|
||||||
for (unsigned i=0 ; i<OMD->param_size() ; i++) {
|
CGM.getTypes().GetFunctionType(CGFunctionInfo(OMD, CGM.getContext()));
|
||||||
const llvm::Type *Ty =
|
|
||||||
CGM.getTypes().ConvertType(OMD->getParamDecl(i)->getType());
|
|
||||||
if (Ty->isFirstClassType())
|
|
||||||
ArgTy.push_back(Ty);
|
|
||||||
else
|
|
||||||
ArgTy.push_back(llvm::PointerType::getUnqual(Ty));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<const llvm::Type*> Args;
|
|
||||||
if (!ReturnTy->isSingleValueType() && ReturnTy != llvm::Type::VoidTy) {
|
|
||||||
Args.push_back(llvm::PointerType::getUnqual(ReturnTy));
|
|
||||||
ReturnTy = llvm::Type::VoidTy;
|
|
||||||
}
|
|
||||||
Args.push_back(SelfTy);
|
|
||||||
Args.push_back(SelectorTy);
|
|
||||||
Args.insert(Args.end(), ArgTy.begin(), ArgTy.begin()+ArgC);
|
|
||||||
|
|
||||||
llvm::FunctionType *MethodTy = llvm::FunctionType::get(ReturnTy,
|
|
||||||
Args,
|
|
||||||
isVarArg);
|
|
||||||
std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName,
|
std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName,
|
||||||
MethodName, isClassMethod);
|
MethodName, isClassMethod);
|
||||||
|
|
||||||
|
|
|
@ -1344,66 +1344,18 @@ llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name,
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
|
llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
|
||||||
const llvm::Type *ReturnTy =
|
|
||||||
CGM.getTypes().ConvertReturnType(OMD->getResultType());
|
|
||||||
const llvm::Type *SelfTy =
|
|
||||||
CGM.getTypes().ConvertType(OMD->getSelfDecl()->getType());
|
|
||||||
|
|
||||||
std::vector<const llvm::Type*> ArgTys;
|
|
||||||
ArgTys.reserve(1 + 2 + OMD->param_size());
|
|
||||||
|
|
||||||
// FIXME: This is not something we should have to be dealing with
|
|
||||||
// here.
|
|
||||||
bool useStructRet =
|
|
||||||
CodeGen::CodeGenFunction::hasAggregateLLVMType(OMD->getResultType());
|
|
||||||
if (useStructRet) {
|
|
||||||
ArgTys.push_back(llvm::PointerType::getUnqual(ReturnTy));
|
|
||||||
ReturnTy = llvm::Type::VoidTy;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implicit arguments
|
|
||||||
ArgTys.push_back(SelfTy);
|
|
||||||
ArgTys.push_back(ObjCTypes.SelectorPtrTy);
|
|
||||||
|
|
||||||
for (ObjCMethodDecl::param_const_iterator
|
|
||||||
i = OMD->param_begin(), e = OMD->param_end();
|
|
||||||
i != e; ++i) {
|
|
||||||
const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
|
|
||||||
if (Ty->isSingleValueType()) {
|
|
||||||
ArgTys.push_back(Ty);
|
|
||||||
} else {
|
|
||||||
ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Name;
|
std::string Name;
|
||||||
GetNameForMethod(OMD, Name);
|
GetNameForMethod(OMD, Name);
|
||||||
|
|
||||||
|
const llvm::FunctionType *MethodTy =
|
||||||
|
CGM.getTypes().GetFunctionType(CGFunctionInfo(OMD, CGM.getContext()));
|
||||||
llvm::Function *Method =
|
llvm::Function *Method =
|
||||||
llvm::Function::Create(llvm::FunctionType::get(ReturnTy,
|
llvm::Function::Create(MethodTy,
|
||||||
ArgTys,
|
|
||||||
OMD->isVariadic()),
|
|
||||||
llvm::GlobalValue::InternalLinkage,
|
llvm::GlobalValue::InternalLinkage,
|
||||||
Name,
|
Name,
|
||||||
&CGM.getModule());
|
&CGM.getModule());
|
||||||
MethodDefinitions.insert(std::make_pair(OMD, Method));
|
MethodDefinitions.insert(std::make_pair(OMD, Method));
|
||||||
|
|
||||||
unsigned Offset = 3; // Return plus self and selector implicit args.
|
|
||||||
if (useStructRet) {
|
|
||||||
Method->addParamAttr(1, llvm::ParamAttr::StructRet);
|
|
||||||
++Offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: This is horrible, we need to be reusing the machinery in
|
|
||||||
// CodeGenModule.cpp (SetFunctionAttributes).
|
|
||||||
for (ObjCMethodDecl::param_const_iterator
|
|
||||||
i = OMD->param_begin(), e = OMD->param_end();
|
|
||||||
i != e; ++i, ++Offset) {
|
|
||||||
const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
|
|
||||||
if (!Ty->isSingleValueType())
|
|
||||||
Method->addParamAttr(Offset, llvm::ParamAttr::ByVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Method;
|
return Method;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -212,18 +212,18 @@ static void SetGlobalValueAttributes(const Decl *D,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGenModule::SetFunctionParamAttrs(const CGFunctionInfo &Info,
|
void CodeGenModule::SetFunctionParamAttrs(const Decl *D,
|
||||||
|
const CGFunctionInfo &Info,
|
||||||
llvm::Function *F) {
|
llvm::Function *F) {
|
||||||
ParamAttrListType ParamAttrList;
|
ParamAttrListType ParamAttrList;
|
||||||
ConstructParamAttrList(Info.getDecl(),
|
ConstructParamAttrList(D, Info.argtypes_begin(), Info.argtypes_end(),
|
||||||
Info.argtypes_begin(), Info.argtypes_end(),
|
|
||||||
ParamAttrList);
|
ParamAttrList);
|
||||||
|
|
||||||
F->setParamAttrs(llvm::PAListPtr::get(ParamAttrList.begin(),
|
F->setParamAttrs(llvm::PAListPtr::get(ParamAttrList.begin(),
|
||||||
ParamAttrList.size()));
|
ParamAttrList.size()));
|
||||||
|
|
||||||
// Set the appropriate calling convention for the Function.
|
// Set the appropriate calling convention for the Function.
|
||||||
if (Info.getDecl()->getAttr<FastCallAttr>())
|
if (D->getAttr<FastCallAttr>())
|
||||||
F->setCallingConv(llvm::CallingConv::Fast);
|
F->setCallingConv(llvm::CallingConv::Fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,19 +245,20 @@ void CodeGenModule::SetFunctionAttributesForDefinition(const Decl *D,
|
||||||
|
|
||||||
void CodeGenModule::SetMethodAttributes(const ObjCMethodDecl *MD,
|
void CodeGenModule::SetMethodAttributes(const ObjCMethodDecl *MD,
|
||||||
llvm::Function *F) {
|
llvm::Function *F) {
|
||||||
SetFunctionParamAttrs(CGFunctionInfo(MD, Context), F);
|
SetFunctionParamAttrs(MD, CGFunctionInfo(MD, Context), F);
|
||||||
|
|
||||||
SetFunctionAttributesForDefinition(MD, F);
|
SetFunctionAttributesForDefinition(MD, F);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD,
|
void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD,
|
||||||
llvm::Function *F) {
|
llvm::Function *F) {
|
||||||
SetFunctionParamAttrs(CGFunctionInfo(FD), F);
|
SetFunctionParamAttrs(FD, CGFunctionInfo(FD), F);
|
||||||
|
|
||||||
SetGlobalValueAttributes(FD, FD->getStorageClass() == FunctionDecl::Static,
|
SetGlobalValueAttributes(FD, FD->getStorageClass() == FunctionDecl::Static,
|
||||||
FD->isInline(), F, false);
|
FD->isInline(), F, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CodeGenModule::EmitAliases() {
|
void CodeGenModule::EmitAliases() {
|
||||||
for (unsigned i = 0, e = Aliases.size(); i != e; ++i) {
|
for (unsigned i = 0, e = Aliases.size(); i != e; ++i) {
|
||||||
const FunctionDecl *D = Aliases[i];
|
const FunctionDecl *D = Aliases[i];
|
||||||
|
|
|
@ -217,7 +217,8 @@ public:
|
||||||
void SetMethodAttributes(const ObjCMethodDecl *MD,
|
void SetMethodAttributes(const ObjCMethodDecl *MD,
|
||||||
llvm::Function *F);
|
llvm::Function *F);
|
||||||
|
|
||||||
void SetFunctionParamAttrs(const CGFunctionInfo &Info,
|
void SetFunctionParamAttrs(const Decl *D,
|
||||||
|
const CGFunctionInfo &Info,
|
||||||
llvm::Function *F);
|
llvm::Function *F);
|
||||||
|
|
||||||
/// ReturnTypeUsesSret - Return true iff the given type uses 'sret'
|
/// ReturnTypeUsesSret - Return true iff the given type uses 'sret'
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Target/TargetData.h"
|
#include "llvm/Target/TargetData.h"
|
||||||
|
|
||||||
|
#include "CGCall.h"
|
||||||
|
|
||||||
using namespace clang;
|
using namespace clang;
|
||||||
using namespace CodeGen;
|
using namespace CodeGen;
|
||||||
|
|
||||||
|
@ -167,13 +169,6 @@ void CodeGenTypes::CollectObjCIvarTypes(ObjCInterfaceDecl *ObjCClass,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const llvm::Type *CodeGenTypes::ConvertReturnType(QualType T) {
|
|
||||||
if (T->isVoidType())
|
|
||||||
return llvm::Type::VoidTy; // Result of function uses llvm void.
|
|
||||||
else
|
|
||||||
return ConvertType(T);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const llvm::Type* getTypeForFormat(const llvm::fltSemantics &format) {
|
static const llvm::Type* getTypeForFormat(const llvm::fltSemantics &format) {
|
||||||
if (&format == &llvm::APFloat::IEEEsingle)
|
if (&format == &llvm::APFloat::IEEEsingle)
|
||||||
return llvm::Type::FloatTy;
|
return llvm::Type::FloatTy;
|
||||||
|
@ -273,35 +268,9 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
|
||||||
VT.getNumElements());
|
VT.getNumElements());
|
||||||
}
|
}
|
||||||
case Type::FunctionNoProto:
|
case Type::FunctionNoProto:
|
||||||
case Type::FunctionProto: {
|
return GetFunctionType(CGFunctionInfo(cast<FunctionTypeNoProto>(&Ty)));
|
||||||
const FunctionType &FP = cast<FunctionType>(Ty);
|
case Type::FunctionProto:
|
||||||
const llvm::Type *ResultType;
|
return GetFunctionType(CGFunctionInfo(cast<FunctionTypeProto>(&Ty)));
|
||||||
|
|
||||||
if (FP.getResultType()->isVoidType())
|
|
||||||
ResultType = llvm::Type::VoidTy; // Result of function uses llvm void.
|
|
||||||
else
|
|
||||||
ResultType = ConvertTypeRecursive(FP.getResultType());
|
|
||||||
|
|
||||||
// FIXME: Convert argument types.
|
|
||||||
bool isVarArg;
|
|
||||||
std::vector<const llvm::Type*> ArgTys;
|
|
||||||
|
|
||||||
// Struct return passes the struct byref.
|
|
||||||
if (!ResultType->isSingleValueType() && ResultType != llvm::Type::VoidTy) {
|
|
||||||
ArgTys.push_back(llvm::PointerType::get(ResultType,
|
|
||||||
FP.getResultType().getAddressSpace()));
|
|
||||||
ResultType = llvm::Type::VoidTy;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(&FP)) {
|
|
||||||
DecodeArgumentTypes(*FTP, ArgTys);
|
|
||||||
isVarArg = FTP->isVariadic();
|
|
||||||
} else {
|
|
||||||
isVarArg = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return llvm::FunctionType::get(ResultType, ArgTys, isVarArg);
|
|
||||||
}
|
|
||||||
|
|
||||||
case Type::ASQual:
|
case Type::ASQual:
|
||||||
return
|
return
|
||||||
|
@ -364,18 +333,6 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
|
||||||
return llvm::OpaqueType::get();
|
return llvm::OpaqueType::get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGenTypes::DecodeArgumentTypes(const FunctionTypeProto &FTP,
|
|
||||||
std::vector<const llvm::Type*> &ArgTys) {
|
|
||||||
for (unsigned i = 0, e = FTP.getNumArgs(); i != e; ++i) {
|
|
||||||
const llvm::Type *Ty = ConvertTypeRecursive(FTP.getArgType(i));
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ConvertTagDeclType - Lay out a tagged decl type like struct or union or
|
/// ConvertTagDeclType - Lay out a tagged decl type like struct or union or
|
||||||
/// enum.
|
/// enum.
|
||||||
const llvm::Type *CodeGenTypes::ConvertTagDeclType(const TagDecl *TD) {
|
const llvm::Type *CodeGenTypes::ConvertTagDeclType(const TagDecl *TD) {
|
||||||
|
|
|
@ -19,28 +19,30 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
class FunctionType;
|
||||||
class Module;
|
class Module;
|
||||||
class Type;
|
|
||||||
class OpaqueType;
|
class OpaqueType;
|
||||||
class PATypeHolder;
|
class PATypeHolder;
|
||||||
class TargetData;
|
class TargetData;
|
||||||
|
class Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
class ASTContext;
|
class ASTContext;
|
||||||
class TagDecl;
|
|
||||||
class TargetInfo;
|
|
||||||
class QualType;
|
|
||||||
class PointerType;
|
|
||||||
class PointerLikeType;
|
|
||||||
class Type;
|
|
||||||
class FunctionTypeProto;
|
|
||||||
class FieldDecl;
|
class FieldDecl;
|
||||||
class RecordDecl;
|
class FunctionTypeProto;
|
||||||
class ObjCInterfaceDecl;
|
class ObjCInterfaceDecl;
|
||||||
class ObjCIvarDecl;
|
class ObjCIvarDecl;
|
||||||
|
class PointerLikeType;
|
||||||
|
class PointerType;
|
||||||
|
class QualType;
|
||||||
|
class RecordDecl;
|
||||||
|
class TagDecl;
|
||||||
|
class TargetInfo;
|
||||||
|
class Type;
|
||||||
|
|
||||||
namespace CodeGen {
|
namespace CodeGen {
|
||||||
|
class CGFunctionInfo;
|
||||||
class CodeGenTypes;
|
class CodeGenTypes;
|
||||||
|
|
||||||
/// CGRecordLayout - This class handles struct and union layout info while
|
/// CGRecordLayout - This class handles struct and union layout info while
|
||||||
|
@ -132,9 +134,6 @@ public:
|
||||||
/// ConvertType - Convert type T into a llvm::Type.
|
/// ConvertType - Convert type T into a llvm::Type.
|
||||||
const llvm::Type *ConvertType(QualType T);
|
const llvm::Type *ConvertType(QualType T);
|
||||||
const llvm::Type *ConvertTypeRecursive(QualType T);
|
const llvm::Type *ConvertTypeRecursive(QualType T);
|
||||||
/// ConvertReturnType - Convert T into an llvm::Type assuming that it will be
|
|
||||||
/// used as a function return type.
|
|
||||||
const llvm::Type *ConvertReturnType(QualType T);
|
|
||||||
|
|
||||||
/// ConvertTypeForMem - Convert type T into a llvm::Type. This differs from
|
/// ConvertTypeForMem - Convert type T into a llvm::Type. This differs from
|
||||||
/// ConvertType in that it is used to convert to the memory representation for
|
/// ConvertType in that it is used to convert to the memory representation for
|
||||||
|
@ -142,6 +141,9 @@ public:
|
||||||
/// memory representation is usually i8 or i32, depending on the target.
|
/// memory representation is usually i8 or i32, depending on the target.
|
||||||
const llvm::Type *ConvertTypeForMem(QualType T);
|
const llvm::Type *ConvertTypeForMem(QualType T);
|
||||||
|
|
||||||
|
/// GetFunctionType - Get the LLVM function type from Info.
|
||||||
|
const llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info);
|
||||||
|
|
||||||
void CollectObjCIvarTypes(ObjCInterfaceDecl *ObjCClass,
|
void CollectObjCIvarTypes(ObjCInterfaceDecl *ObjCClass,
|
||||||
std::vector<const llvm::Type*> &IvarTypes);
|
std::vector<const llvm::Type*> &IvarTypes);
|
||||||
|
|
||||||
|
@ -160,9 +162,6 @@ public:
|
||||||
void UpdateCompletedType(const TagDecl *TD);
|
void UpdateCompletedType(const TagDecl *TD);
|
||||||
|
|
||||||
public: // These are internal details of CGT that shouldn't be used externally.
|
public: // These are internal details of CGT that shouldn't be used externally.
|
||||||
void DecodeArgumentTypes(const FunctionTypeProto &FTP,
|
|
||||||
std::vector<const llvm::Type*> &ArgTys);
|
|
||||||
|
|
||||||
/// addFieldInfo - Assign field number to field FD.
|
/// addFieldInfo - Assign field number to field FD.
|
||||||
void addFieldInfo(const FieldDecl *FD, unsigned No);
|
void addFieldInfo(const FieldDecl *FD, unsigned No);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue