Lift out ABIInfo abstract base class.

- Currently still lives in CGCall.cpp but is intended to be the
   target specific place for hooking ABI information.
 - Select ABIInfo to use based on Target's prefix and pointer width.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57445 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Dunbar 2008-10-13 17:02:26 +00:00
Родитель e2ed203b43
Коммит 6b1da0ea19
3 изменённых файлов: 102 добавлений и 21 удалений

Просмотреть файл

@ -15,6 +15,7 @@
#include "CGCall.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
@ -170,6 +171,27 @@ public:
/***/
/* FIXME: All of this stuff should be part of the target interface
somehow. It is currently here because it is not clear how to factor
the targets to support this, since the Targets currently live in a
layer below types n'stuff.
*/
/// ABIInfo - Target specific hooks for defining how a type should be
/// passed or returned from functions.
class clang::ABIInfo {
public:
virtual ~ABIInfo();
virtual ABIArgInfo classifyReturnType(QualType RetTy,
ASTContext &Context) const = 0;
virtual ABIArgInfo classifyArgumentType(QualType Ty,
ASTContext &Context) const = 0;
};
ABIInfo::~ABIInfo() {}
/// isEmptyStruct - Return true iff a structure has no non-empty
/// members. Note that a structure with a flexible array member is not
/// considered empty.
@ -256,8 +278,32 @@ static bool areAllFields32Or64BitBasicType(const RecordDecl *RD,
return true;
}
static ABIArgInfo classifyReturnType(QualType RetTy,
ASTContext &Context) {
namespace {
/// DefaultABIInfo - The default implementation for ABI specific
/// details. This implementation provides information which results in
/// sensible LLVM IR generation, but does not conform to any
/// particular ABI.
class DefaultABIInfo : public ABIInfo {
virtual ABIArgInfo classifyReturnType(QualType RetTy,
ASTContext &Context) const;
virtual ABIArgInfo classifyArgumentType(QualType RetTy,
ASTContext &Context) const;
};
/// X86_32ABIInfo - The X86-32 ABI information.
class X86_32ABIInfo : public ABIInfo {
public:
virtual ABIArgInfo classifyReturnType(QualType RetTy,
ASTContext &Context) const;
virtual ABIArgInfo classifyArgumentType(QualType RetTy,
ASTContext &Context) const;
};
}
ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
ASTContext &Context) const {
assert(!RetTy->isArrayType() &&
"Array types cannot be passed directly.");
if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
@ -303,8 +349,8 @@ static ABIArgInfo classifyReturnType(QualType RetTy,
}
}
static ABIArgInfo classifyArgumentType(QualType Ty,
ASTContext &Context) {
ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
ASTContext &Context) const {
assert(!Ty->isArrayType() && "Array types cannot be passed directly.");
if (CodeGenFunction::hasAggregateLLVMType(Ty)) {
// Structures with flexible arrays are always byval.
@ -332,18 +378,50 @@ static ABIArgInfo classifyArgumentType(QualType Ty,
}
}
static ABIArgInfo getABIReturnInfo(QualType Ty,
ASTContext &Context) {
ABIArgInfo Info = classifyReturnType(Ty, Context);
ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy,
ASTContext &Context) const {
return ABIArgInfo::getDefault();
}
ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty,
ASTContext &Context) const {
assert(!Ty->isArrayType() && "Array types cannot be passed directly.");
return ABIArgInfo::getDefault();
}
const ABIInfo &CodeGenTypes::getABIInfo() const {
if (TheABIInfo)
return *TheABIInfo;
// For now we just cache this in the CodeGenTypes and don't bother
// to free it.
const char *TargetPrefix = getContext().Target.getTargetPrefix();
if (strcmp(TargetPrefix, "x86") == 0) {
if (getContext().Target.getPointerWidth(0) == 32)
return *(TheABIInfo = new X86_32ABIInfo());
}
return *(TheABIInfo = new DefaultABIInfo);
}
// getABIReturnInfo - Wrap the ABIInfo getABIReturnInfo, altering
// "default" types to StructRet when appropriate for simplicity.
static ABIArgInfo getABIReturnInfo(QualType Ty, CodeGenTypes &CGT) {
assert(!Ty->isArrayType() &&
"Array types cannot be passed directly.");
ABIArgInfo Info = CGT.getABIInfo().classifyReturnType(Ty, CGT.getContext());
// Ensure default on aggregate types is StructRet.
if (Info.isDefault() && CodeGenFunction::hasAggregateLLVMType(Ty))
return ABIArgInfo::getStructRet();
return Info;
}
static ABIArgInfo getABIArgumentInfo(QualType Ty,
ASTContext &Context) {
ABIArgInfo Info = classifyArgumentType(Ty, Context);
// getABIArgumentInfo - Wrap the ABIInfo getABIReturnInfo, altering
// "default" types to ByVal when appropriate for simplicity.
static ABIArgInfo getABIArgumentInfo(QualType Ty, CodeGenTypes &CGT) {
assert(!Ty->isArrayType() &&
"Array types cannot be passed directly.");
ABIArgInfo Info = CGT.getABIInfo().classifyArgumentType(Ty, CGT.getContext());
// Ensure default on aggregate types is ByVal.
if (Info.isDefault() && CodeGenFunction::hasAggregateLLVMType(Ty))
return ABIArgInfo::getByVal(0);
@ -450,7 +528,7 @@ CodeGenTypes::GetFunctionType(ArgTypeIterator begin, ArgTypeIterator end,
const llvm::Type *ResultType = 0;
QualType RetTy = *begin;
ABIArgInfo RetAI = getABIReturnInfo(RetTy, getContext());
ABIArgInfo RetAI = getABIReturnInfo(RetTy, *this);
switch (RetAI.getKind()) {
case ABIArgInfo::ByVal:
case ABIArgInfo::Expand:
@ -477,7 +555,7 @@ CodeGenTypes::GetFunctionType(ArgTypeIterator begin, ArgTypeIterator end,
}
for (++begin; begin != end; ++begin) {
ABIArgInfo AI = getABIArgumentInfo(*begin, getContext());
ABIArgInfo AI = getABIArgumentInfo(*begin, *this);
const llvm::Type *Ty = ConvertType(*begin);
switch (AI.getKind()) {
@ -505,7 +583,7 @@ CodeGenTypes::GetFunctionType(ArgTypeIterator begin, ArgTypeIterator end,
}
bool CodeGenModule::ReturnTypeUsesSret(QualType RetTy) {
return getABIReturnInfo(RetTy, getContext()).isStructRet();
return getABIReturnInfo(RetTy, getTypes()).isStructRet();
}
void CodeGenModule::ConstructAttributeList(const Decl *TargetDecl,
@ -528,7 +606,7 @@ void CodeGenModule::ConstructAttributeList(const Decl *TargetDecl,
QualType RetTy = *begin;
unsigned Index = 1;
ABIArgInfo RetAI = getABIReturnInfo(RetTy, getContext());
ABIArgInfo RetAI = getABIReturnInfo(RetTy, getTypes());
switch (RetAI.getKind()) {
case ABIArgInfo::Default:
if (RetTy->isPromotableIntegerType()) {
@ -560,7 +638,7 @@ void CodeGenModule::ConstructAttributeList(const Decl *TargetDecl,
for (++begin; begin != end; ++begin) {
QualType ParamType = *begin;
unsigned Attributes = 0;
ABIArgInfo AI = getABIArgumentInfo(ParamType, getContext());
ABIArgInfo AI = getABIArgumentInfo(ParamType, getTypes());
switch (AI.getKind()) {
case ABIArgInfo::StructRet:
@ -618,7 +696,7 @@ void CodeGenFunction::EmitFunctionProlog(llvm::Function *Fn,
i != e; ++i) {
const VarDecl *Arg = i->first;
QualType Ty = i->second;
ABIArgInfo ArgI = getABIArgumentInfo(Ty, getContext());
ABIArgInfo ArgI = getABIArgumentInfo(Ty, CGM.getTypes());
switch (ArgI.getKind()) {
case ABIArgInfo::ByVal:
@ -669,7 +747,7 @@ void CodeGenFunction::EmitFunctionEpilog(QualType RetTy,
// Functions with no result always return void.
if (ReturnValue) {
ABIArgInfo RetAI = getABIReturnInfo(RetTy, getContext());
ABIArgInfo RetAI = getABIReturnInfo(RetTy, CGM.getTypes());
switch (RetAI.getKind()) {
case ABIArgInfo::StructRet:
@ -707,7 +785,7 @@ RValue CodeGenFunction::EmitCall(llvm::Value *Callee,
// Handle struct-return functions by passing a pointer to the
// location that we would like to return into.
ABIArgInfo RetAI = getABIReturnInfo(RetTy, getContext());
ABIArgInfo RetAI = getABIReturnInfo(RetTy, CGM.getTypes());
switch (RetAI.getKind()) {
case ABIArgInfo::StructRet:
// Create a temporary alloca to hold the result of the call. :(
@ -725,7 +803,7 @@ RValue CodeGenFunction::EmitCall(llvm::Value *Callee,
for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end();
I != E; ++I) {
ABIArgInfo ArgInfo = getABIArgumentInfo(I->second, getContext());
ABIArgInfo ArgInfo = getABIArgumentInfo(I->second, CGM.getTypes());
RValue RV = I->first;
switch (ArgInfo.getKind()) {

Просмотреть файл

@ -64,7 +64,8 @@ namespace {
CodeGenTypes::CodeGenTypes(ASTContext &Ctx, llvm::Module& M,
const llvm::TargetData &TD)
: Context(Ctx), Target(Ctx.Target), TheModule(M), TheTargetData(TD) {
: Context(Ctx), Target(Ctx.Target), TheModule(M), TheTargetData(TD),
TheABIInfo(0) {
}
CodeGenTypes::~CodeGenTypes() {

Просмотреть файл

@ -30,6 +30,7 @@ namespace llvm {
}
namespace clang {
class ABIInfo;
class ASTContext;
class FieldDecl;
class FunctionTypeProto;
@ -82,8 +83,8 @@ class CodeGenTypes {
TargetInfo &Target;
llvm::Module& TheModule;
const llvm::TargetData& TheTargetData;
mutable const ABIInfo* TheABIInfo;
llvm::SmallVector<std::pair<const PointerLikeType *,
llvm::OpaqueType *>, 8> PointersToResolve;
@ -131,6 +132,7 @@ public:
const llvm::TargetData &getTargetData() const { return TheTargetData; }
TargetInfo &getTarget() const { return Target; }
ASTContext &getContext() const { return Context; }
const ABIInfo &getABIInfo() const;
/// ConvertType - Convert type T into a llvm::Type.
const llvm::Type *ConvertType(QualType T);