diff --git a/clang/lib/CodeGen/ABIInfo.h b/clang/lib/CodeGen/ABIInfo.h new file mode 100644 index 000000000000..4b33c4e8065d --- /dev/null +++ b/clang/lib/CodeGen/ABIInfo.h @@ -0,0 +1,116 @@ +//===----- ABIInfo.h - ABI information access & encapsulation ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef CLANG_CODEGEN_ABIINFO_H +#define CLANG_CODEGEN_ABIINFO_H + +namespace clang { + /* 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. + */ + + /// ABIArgInfo - Helper class to encapsulate information about how a + /// specific C type should be passed to or returned from a function. + class ABIArgInfo { + public: + enum Kind { + Default, + StructRet, /// Only valid for return values. The return value + /// should be passed through a pointer to a caller + /// allocated location passed as an implicit first + /// argument to the function. + + Ignore, /// Ignore the argument (treat as void). Useful for + /// void and empty structs. + + Coerce, /// Only valid for aggregate return types, the argument + /// should be accessed by coercion to a provided type. + + ByVal, /// Only valid for aggregate argument types. The + /// structure should be passed "byval" with the + /// specified alignment (0 indicates default + /// alignment). + + Expand, /// Only valid for aggregate argument types. The + /// structure should be expanded into consecutive + /// arguments for its constituent fields. Currently + /// expand is only allowed on structures whose fields + /// are all scalar types or are themselves expandable + /// types. + + KindFirst=Default, KindLast=Expand + }; + + private: + Kind TheKind; + const llvm::Type *TypeData; + unsigned UIntData; + + ABIArgInfo(Kind K, const llvm::Type *TD=0, + unsigned UI=0) : TheKind(K), + TypeData(TD), + UIntData(0) {} + public: + static ABIArgInfo getDefault() { + return ABIArgInfo(Default); + } + static ABIArgInfo getStructRet() { + return ABIArgInfo(StructRet); + } + static ABIArgInfo getIgnore() { + return ABIArgInfo(Ignore); + } + static ABIArgInfo getCoerce(const llvm::Type *T) { + return ABIArgInfo(Coerce, T); + } + static ABIArgInfo getByVal(unsigned Alignment) { + return ABIArgInfo(ByVal, 0, Alignment); + } + static ABIArgInfo getExpand() { + return ABIArgInfo(Expand); + } + + Kind getKind() const { return TheKind; } + bool isDefault() const { return TheKind == Default; } + bool isStructRet() const { return TheKind == StructRet; } + bool isIgnore() const { return TheKind == Ignore; } + bool isCoerce() const { return TheKind == Coerce; } + bool isByVal() const { return TheKind == ByVal; } + bool isExpand() const { return TheKind == Expand; } + + // Coerce accessors + const llvm::Type *getCoerceToType() const { + assert(TheKind == Coerce && "Invalid kind!"); + return TypeData; + } + + // ByVal accessors + unsigned getByValAlignment() const { + assert(TheKind == ByVal && "Invalid kind!"); + return UIntData; + } + }; + + /// ABIInfo - Target specific hooks for defining how a type should be + /// passed or returned from functions. + class ABIInfo { + public: + virtual ~ABIInfo(); + + virtual ABIArgInfo classifyReturnType(QualType RetTy, + ASTContext &Context) const = 0; + + virtual ABIArgInfo classifyArgumentType(QualType Ty, + ASTContext &Context) const = 0; + }; +} // end namespace clang + +#endif diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 30257d2699e4..c6e804ea0bbb 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -24,6 +24,9 @@ #include "llvm/Attributes.h" #include "llvm/Support/CommandLine.h" #include "llvm/Target/TargetData.h" + +#include "ABIInfo.h" + using namespace clang; using namespace CodeGen; @@ -118,109 +121,6 @@ CGFunctionInfo::arg_iterator CGFunctionInfo::arg_end() const { /***/ -/// ABIArgInfo - Helper class to encapsulate information about how a -/// specific C type should be passed to or returned from a function. -class ABIArgInfo { -public: - enum Kind { - Default, - StructRet, /// Only valid for return values. The return value - /// should be passed through a pointer to a caller - /// allocated location passed as an implicit first - /// argument to the function. - - Ignore, /// Ignore the argument (treat as void). Useful for - /// void and empty structs. - - Coerce, /// Only valid for aggregate return types, the argument - /// should be accessed by coercion to a provided type. - - ByVal, /// Only valid for aggregate argument types. The - /// structure should be passed "byval" with the - /// specified alignment (0 indicates default - /// alignment). - - Expand, /// Only valid for aggregate argument types. The - /// structure should be expanded into consecutive - /// arguments for its constituent fields. Currently - /// expand is only allowed on structures whose fields - /// are all scalar types or are themselves expandable - /// types. - - KindFirst=Default, KindLast=Expand - }; - -private: - Kind TheKind; - const llvm::Type *TypeData; - unsigned UIntData; - - ABIArgInfo(Kind K, const llvm::Type *TD=0, - unsigned UI=0) : TheKind(K), - TypeData(TD), - UIntData(0) {} -public: - static ABIArgInfo getDefault() { - return ABIArgInfo(Default); - } - static ABIArgInfo getStructRet() { - return ABIArgInfo(StructRet); - } - static ABIArgInfo getIgnore() { - return ABIArgInfo(Ignore); - } - static ABIArgInfo getCoerce(const llvm::Type *T) { - return ABIArgInfo(Coerce, T); - } - static ABIArgInfo getByVal(unsigned Alignment) { - return ABIArgInfo(ByVal, 0, Alignment); - } - static ABIArgInfo getExpand() { - return ABIArgInfo(Expand); - } - - Kind getKind() const { return TheKind; } - bool isDefault() const { return TheKind == Default; } - bool isStructRet() const { return TheKind == StructRet; } - bool isIgnore() const { return TheKind == Ignore; } - bool isCoerce() const { return TheKind == Coerce; } - bool isByVal() const { return TheKind == ByVal; } - bool isExpand() const { return TheKind == Expand; } - - // Coerce accessors - const llvm::Type *getCoerceToType() const { - assert(TheKind == Coerce && "Invalid kind!"); - return TypeData; - } - - // ByVal accessors - unsigned getByValAlignment() const { - assert(TheKind == ByVal && "Invalid kind!"); - return UIntData; - } -}; - -/***/ - -/* 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