#ifndef CLANG_CODEGEN_ABIINFO_H
#define CLANG_CODEGEN_ABIINFO_H
#include "clang/AST/Type.h"
#include "llvm/Type.h"
namespace llvm {
class Value;
class LLVMContext;
class TargetData;
}
namespace clang {
class ASTContext;
namespace CodeGen {
class CGFunctionInfo;
class CodeGenFunction;
class CodeGenTypes;
}
class ABIArgInfo {
public:
enum Kind {
Direct,
Extend,
Indirect,
Ignore,
Expand,
KindFirst=Direct, KindLast=Expand
};
private:
Kind TheKind;
llvm::Type *TypeData;
llvm::Type *PaddingType; unsigned UIntData;
bool BoolData0;
bool BoolData1;
ABIArgInfo(Kind K, llvm::Type *TD=0, unsigned UI=0,
bool B0 = false, bool B1 = false, llvm::Type* P = 0)
: TheKind(K), TypeData(TD), PaddingType(P), UIntData(UI), BoolData0(B0),
BoolData1(B1) {}
public:
ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
static ABIArgInfo getDirect(llvm::Type *T = 0, unsigned Offset = 0,
llvm::Type *Padding = 0) {
return ABIArgInfo(Direct, T, Offset, false, false, Padding);
}
static ABIArgInfo getExtend(llvm::Type *T = 0) {
return ABIArgInfo(Extend, T, 0);
}
static ABIArgInfo getIgnore() {
return ABIArgInfo(Ignore);
}
static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true
, bool Realign = false) {
return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign);
}
static ABIArgInfo getExpand() {
return ABIArgInfo(Expand);
}
Kind getKind() const { return TheKind; }
bool isDirect() const { return TheKind == Direct; }
bool isExtend() const { return TheKind == Extend; }
bool isIgnore() const { return TheKind == Ignore; }
bool isIndirect() const { return TheKind == Indirect; }
bool isExpand() const { return TheKind == Expand; }
bool canHaveCoerceToType() const {
return TheKind == Direct || TheKind == Extend;
}
unsigned getDirectOffset() const {
assert((isDirect() || isExtend()) && "Not a direct or extend kind");
return UIntData;
}
llvm::Type *getPaddingType() const {
return PaddingType;
}
llvm::Type *getCoerceToType() const {
assert(canHaveCoerceToType() && "Invalid kind!");
return TypeData;
}
void setCoerceToType(llvm::Type *T) {
assert(canHaveCoerceToType() && "Invalid kind!");
TypeData = T;
}
unsigned getIndirectAlign() const {
assert(TheKind == Indirect && "Invalid kind!");
return UIntData;
}
bool getIndirectByVal() const {
assert(TheKind == Indirect && "Invalid kind!");
return BoolData0;
}
bool getIndirectRealign() const {
assert(TheKind == Indirect && "Invalid kind!");
return BoolData1;
}
void dump() const;
};
class ABIInfo {
public:
CodeGen::CodeGenTypes &CGT;
ABIInfo(CodeGen::CodeGenTypes &cgt) : CGT(cgt) {}
virtual ~ABIInfo();
ASTContext &getContext() const;
llvm::LLVMContext &getVMContext() const;
const llvm::TargetData &getTargetData() const;
virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const = 0;
virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
CodeGen::CodeGenFunction &CGF) const = 0;
};
}
#endif