Mercurial > projects > ldc
view ir/irtype.h @ 1410:cc2d8a7388c7
Count the sret register as well when keeping track of how many integer registers
are available for extern(C) functions on x86-64.
Interestingly, llvm-g++ seems to have a very similar bug: http://llvm.org/pr4242
(So this breaks ABI-compatibility with llvm-gcc for this corner case, but gains
it with gcc...)
To clarify, this is about code like this:
{{{
struct S { void*[3] data; }
struct T { void*[2] data; }
// The T should be passed in memory, and p in the last int register.
extern(C) S fail(int, int, int, int, T t, void* p) {
S s;
s.data[0] = t.data[0];
s.data[1] = t.data[1];
s.data[2] = p;
return s;
}
}}}
which should generate code functionally equivalent to this:
{{{
extern(C) S* succeed(S* s, int, int, int, int, T t, void* p) {
s.data[0] = t.data[0];
s.data[1] = t.data[1];
s.data[2] = p;
return s;
}
}}}
(with the same definitions for S and T)
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Fri, 22 May 2009 13:17:06 +0200 |
parents | 81121ac19f61 |
children |
line wrap: on
line source
#ifndef __LDC_IR_IRTYPE_H__ #define __LDC_IR_IRTYPE_H__ #include "llvm/Type.h" ////////////////////////////////////////////////////////////////////////////// // forward declarations struct Type; class IrTypeAggr; class IrTypeArray; class IrTypeBasic; class IrTypeClass; class IrTypeDelegate; class IrTypeFunction; class IrTypePointer; class IrTypeSArray; class IrTypeStruct; ////////////////////////////////////////////////////////////////////////////// /// Base class for IrTypeS. class IrType { public: /// IrType(Type* dt, const llvm::Type* lt); /// virtual IrTypeAggr* isAggr() { return NULL; } /// virtual IrTypeArray* isArray() { return NULL; } /// virtual IrTypeBasic* isBasic() { return NULL; } /// virtual IrTypeClass* isClass() { return NULL; } /// virtual IrTypeDelegate* isDelegate(){ return NULL; } /// virtual IrTypeFunction* isFunction(){ return NULL; } /// virtual IrTypePointer* isPointer() { return NULL; } /// virtual IrTypeSArray* isSArray() { return NULL; } /// virtual IrTypeStruct* isStruct() { return NULL; } /// Type* getD() { return dtype; } /// virtual const llvm::Type* get() { return pa.get(); } /// llvm::PATypeHolder& getPA() { return pa; } /// virtual const llvm::Type* buildType() = 0; protected: /// Type* dtype; /// LLVM type holder. llvm::PATypeHolder pa; }; ////////////////////////////////////////////////////////////////////////////// /// IrType for basic D types. class IrTypeBasic : public IrType { public: /// IrTypeBasic(Type* dt); /// IrTypeBasic* isBasic() { return this; } /// const llvm::Type* buildType(); protected: /// const llvm::Type* basic2llvm(Type* t); }; ////////////////////////////////////////////////////////////////////////////// /// IrType from pointers. class IrTypePointer : public IrType { public: /// IrTypePointer(Type* dt); /// IrTypePointer* isPointer() { return this; } /// const llvm::Type* buildType(); protected: /// const llvm::Type* pointer2llvm(Type* t); }; ////////////////////////////////////////////////////////////////////////////// /// IrType for static arrays class IrTypeSArray : public IrType { public: /// IrTypeSArray(Type* dt); /// IrTypeSArray* isSArray() { return this; } /// const llvm::Type* buildType(); protected: /// const llvm::Type* sarray2llvm(Type* t); /// Dimension. uint64_t dim; }; ////////////////////////////////////////////////////////////////////////////// /// IrType for dynamic arrays class IrTypeArray : public IrType { public: /// IrTypeArray(Type* dt); /// IrTypeArray* isArray() { return this; } /// const llvm::Type* buildType(); protected: /// const llvm::Type* array2llvm(Type* t); }; ////////////////////////////////////////////////////////////////////////////// #endif