mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-16 04:43:14 +01:00
[svn r35] * Attributes on struct fields/methods now work
* Updated object.d to 1.021 * Added -novalidate command line option. this is sometimes useful when debugging as it may let you read the .ll even if it's invalid.
This commit is contained in:
@@ -188,6 +188,7 @@ Usage:\n\
|
||||
x86 x86-64 ppc32 ppc64\n\
|
||||
-nofloat do not emit reference to floating point\n\
|
||||
-noruntime do not allow code that generates implicit runtime calls\n\
|
||||
-novalidate do not run the validation pass before writing bitcode\n\
|
||||
-O optimize, same as -O2\n\
|
||||
-On optimize at level n (0-5)\n\
|
||||
-o- do not write object file\n\
|
||||
@@ -279,6 +280,7 @@ int main(int argc, char *argv[])
|
||||
global.params.llvmArch = 0;
|
||||
global.params.forceBE = 0;
|
||||
global.params.noruntime = 0;
|
||||
global.params.novalidate = 0;
|
||||
global.params.optimizeLevel = 2;
|
||||
global.params.runtimeImppath = 0;
|
||||
|
||||
@@ -370,6 +372,8 @@ int main(int argc, char *argv[])
|
||||
global.params.forceBE = 1;
|
||||
else if (strcmp(p + 1, "noruntime") == 0)
|
||||
global.params.noruntime = 1;
|
||||
else if (strcmp(p + 1, "novalidate") == 0)
|
||||
global.params.novalidate = 1;
|
||||
else if (p[1] == 'o')
|
||||
{
|
||||
switch (p[2])
|
||||
|
||||
@@ -68,6 +68,7 @@ struct Param
|
||||
char cov; // generate code coverage data
|
||||
char nofloat; // code should not pull in floating point support
|
||||
char noruntime; // code is not allowed to make implicit calls to the runtime
|
||||
char novalidate;// no bitcode validation
|
||||
char Dversion; // D version number
|
||||
|
||||
char *argv0; // program name
|
||||
|
||||
@@ -98,12 +98,14 @@ IRStruct::IRStruct()
|
||||
: recty(llvm::OpaqueType::get())
|
||||
{
|
||||
type = 0;
|
||||
queueFuncs = true;
|
||||
}
|
||||
|
||||
IRStruct::IRStruct(Type* t)
|
||||
: recty(llvm::OpaqueType::get())
|
||||
{
|
||||
type = t;
|
||||
queueFuncs = true;
|
||||
}
|
||||
|
||||
IRStruct::~IRStruct()
|
||||
|
||||
@@ -41,7 +41,7 @@ struct IRStruct : Object
|
||||
{
|
||||
typedef std::vector<const llvm::Type*> TypeVector;
|
||||
typedef std::vector<llvm::Constant*> ConstantVector;
|
||||
typedef std::vector<llvm::PATypeHolder> PATypeHolderVector;
|
||||
typedef std::vector<FuncDeclaration*> FuncDeclVec;
|
||||
|
||||
public:
|
||||
IRStruct();
|
||||
@@ -52,6 +52,8 @@ public:
|
||||
TypeVector fields;
|
||||
ConstantVector inits;
|
||||
llvm::PATypeHolder recty;
|
||||
FuncDeclVec funcs;
|
||||
bool queueFuncs;
|
||||
};
|
||||
|
||||
// represents the module
|
||||
@@ -79,13 +81,6 @@ struct IRState : Object
|
||||
typedef std::vector<ClassDeclaration*> ClassDeclVec;
|
||||
ClassDeclVec classes;
|
||||
|
||||
typedef std::vector<FuncDeclaration*> FuncDeclVec;
|
||||
typedef std::vector<FuncDeclVec> ClassMethodVec;
|
||||
ClassMethodVec classmethods;
|
||||
|
||||
typedef std::vector<bool> BoolVec;
|
||||
BoolVec queueClassMethods;
|
||||
|
||||
// D main function
|
||||
bool emitMain;
|
||||
llvm::Function* mainFunc;
|
||||
@@ -115,6 +110,7 @@ struct IRState : Object
|
||||
LvalVec arrays;
|
||||
|
||||
// keeping track of the declaration for the current function body
|
||||
typedef std::vector<FuncDeclaration*> FuncDeclVec;
|
||||
FuncDeclVec funcdecls;
|
||||
};
|
||||
|
||||
|
||||
@@ -243,7 +243,7 @@ const llvm::FunctionType* LLVM_DtoFunctionType(FuncDeclaration* fdecl)
|
||||
std::vector<const llvm::Type*> paramvec;
|
||||
|
||||
if (retinptr) {
|
||||
Logger::print("returning through pointer parameter\n");
|
||||
Logger::cout() << "returning through pointer parameter: " << *rettype << '\n';
|
||||
paramvec.push_back(rettype);
|
||||
}
|
||||
|
||||
@@ -251,7 +251,8 @@ const llvm::FunctionType* LLVM_DtoFunctionType(FuncDeclaration* fdecl)
|
||||
if (AggregateDeclaration* ad = fdecl->isMember()) {
|
||||
Logger::print("isMember = this is: %s\n", ad->type->toChars());
|
||||
const llvm::Type* thisty = LLVM_DtoType(ad->type);
|
||||
if (llvm::isa<llvm::StructType>(thisty))
|
||||
Logger::cout() << "this llvm type: " << *thisty << '\n';
|
||||
if (llvm::isa<llvm::StructType>(thisty) || thisty == gIR->topstruct().recty.get())
|
||||
thisty = llvm::PointerType::get(thisty);
|
||||
paramvec.push_back(thisty);
|
||||
usesthis = true;
|
||||
|
||||
50
gen/toobj.c
50
gen/toobj.c
@@ -87,15 +87,18 @@ Module::genobjfile()
|
||||
}
|
||||
|
||||
// verify the llvm
|
||||
std::string verifyErr;
|
||||
Logger::println("Verifying module...");
|
||||
if (llvm::verifyModule(*ir.module,llvm::ReturnStatusAction,&verifyErr))
|
||||
{
|
||||
error("%s", verifyErr.c_str());
|
||||
fatal();
|
||||
if (!global.params.novalidate) {
|
||||
std::string verifyErr;
|
||||
Logger::println("Verifying module...");
|
||||
if (llvm::verifyModule(*ir.module,llvm::ReturnStatusAction,&verifyErr))
|
||||
{
|
||||
error("%s", verifyErr.c_str());
|
||||
fatal();
|
||||
}
|
||||
else {
|
||||
Logger::println("Verification passed!");
|
||||
}
|
||||
}
|
||||
else
|
||||
Logger::println("Verification passed!");
|
||||
|
||||
// run passes
|
||||
// TODO
|
||||
@@ -219,19 +222,9 @@ void StructDeclaration::toObjFile()
|
||||
|
||||
gIR->structs.push_back(IRStruct(ts));
|
||||
|
||||
std::vector<FuncDeclaration*> mfs;
|
||||
|
||||
for (int k=0; k < members->dim; k++) {
|
||||
Dsymbol* dsym = (Dsymbol*)(members->data[k]);
|
||||
|
||||
// need late generation of member functions
|
||||
// they need the llvm::StructType to exist to take the 'this' parameter
|
||||
if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
|
||||
mfs.push_back(fd);
|
||||
}
|
||||
else {
|
||||
dsym->toObjFile();
|
||||
}
|
||||
dsym->toObjFile();
|
||||
}
|
||||
|
||||
if (gIR->topstruct().fields.empty())
|
||||
@@ -293,7 +286,9 @@ void StructDeclaration::toObjFile()
|
||||
llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType, true, _linkage, _init, initname, gIR->module);
|
||||
ts->llvmInit = initvar;
|
||||
|
||||
// generate member functions
|
||||
// generate member function definitions
|
||||
gIR->topstruct().queueFuncs = false;
|
||||
IRState::FuncDeclVec& mfs = gIR->topstruct().funcs;
|
||||
size_t n = mfs.size();
|
||||
for (size_t i=0; i<n; ++i) {
|
||||
mfs[i]->toObjFile();
|
||||
@@ -341,8 +336,6 @@ void ClassDeclaration::toObjFile()
|
||||
|
||||
gIR->structs.push_back(IRStruct(ts));
|
||||
gIR->classes.push_back(this);
|
||||
gIR->classmethods.push_back(IRState::FuncDeclVec());
|
||||
gIR->queueClassMethods.push_back(true);
|
||||
|
||||
// add vtable
|
||||
llvm::PATypeHolder pa = llvm::OpaqueType::get();
|
||||
@@ -459,15 +452,13 @@ void ClassDeclaration::toObjFile()
|
||||
}
|
||||
|
||||
// generate member function definitions
|
||||
gIR->queueClassMethods.back() = false;
|
||||
IRState::FuncDeclVec& mfs = gIR->classmethods.back();
|
||||
gIR->topstruct().queueFuncs = false;
|
||||
IRState::FuncDeclVec& mfs = gIR->topstruct().funcs;
|
||||
size_t n = mfs.size();
|
||||
for (size_t i=0; i<n; ++i) {
|
||||
mfs[i]->toObjFile();
|
||||
}
|
||||
|
||||
gIR->queueClassMethods.pop_back();
|
||||
gIR->classmethods.pop_back();
|
||||
gIR->classes.pop_back();
|
||||
gIR->structs.pop_back();
|
||||
|
||||
@@ -644,11 +635,10 @@ void FuncDeclaration::toObjFile()
|
||||
|
||||
llvm::Function* func = LLVM_DtoDeclareFunction(this);
|
||||
|
||||
if (!gIR->queueClassMethods.empty() && gIR->queueClassMethods.back()) {
|
||||
if (!gIR->structs.empty() && gIR->topstruct().queueFuncs) {
|
||||
if (!llvmQueued) {
|
||||
Logger::println("queueing %s", toChars());
|
||||
assert(!gIR->classmethods.empty());
|
||||
gIR->classmethods.back().push_back(this);
|
||||
gIR->topstruct().funcs.push_back(this);
|
||||
llvmQueued = true;
|
||||
}
|
||||
return; // we wait with the definition as they might invoke a virtual method and the vtable is not yet complete
|
||||
@@ -699,6 +689,8 @@ void FuncDeclaration::toObjFile()
|
||||
// first make absolutely sure the type is up to date
|
||||
f->llvmType = llvmValue->getType()->getContainedType(0);
|
||||
|
||||
Logger::cout() << "func type: " << *f->llvmType << '\n';
|
||||
|
||||
// this handling
|
||||
if (f->llvmUsesThis) {
|
||||
if (f->llvmRetInPtr)
|
||||
|
||||
@@ -10,8 +10,13 @@ alias typeof(int.sizeof) size_t;
|
||||
alias typeof(cast(void*)0 - cast(void*)0) ptrdiff_t;
|
||||
alias size_t hash_t;
|
||||
|
||||
alias char[] string;
|
||||
alias wchar[] wstring;
|
||||
alias dchar[] dstring;
|
||||
|
||||
extern (C)
|
||||
{ int printf(char *, ...);
|
||||
void trace_term();
|
||||
}
|
||||
|
||||
class Object
|
||||
@@ -24,13 +29,15 @@ class Object
|
||||
|
||||
final void notifyRegister(void delegate(Object) dg);
|
||||
final void notifyUnRegister(void delegate(Object) dg);
|
||||
|
||||
static Object factory(char[] classname);
|
||||
}
|
||||
|
||||
struct Interface
|
||||
{
|
||||
ClassInfo classinfo;
|
||||
void *[] vtbl;
|
||||
ptrdiff_t offset; // offset to Interface 'this' from Object 'this'
|
||||
int offset; // offset to Interface 'this' from Object 'this'
|
||||
}
|
||||
|
||||
class ClassInfo : Object
|
||||
@@ -46,8 +53,13 @@ class ClassInfo : Object
|
||||
// 1: // IUnknown
|
||||
// 2: // has no possible pointers into GC memory
|
||||
// 4: // has offTi[] member
|
||||
// 8: // has constructors
|
||||
void *deallocator;
|
||||
OffsetTypeInfo[] offTi;
|
||||
void* defaultConstructor; // default Constructor
|
||||
|
||||
static ClassInfo find(char[] classname);
|
||||
Object create();
|
||||
}
|
||||
|
||||
struct OffsetTypeInfo
|
||||
@@ -141,15 +153,24 @@ class TypeInfo_Tuple : TypeInfo
|
||||
TypeInfo[] elements;
|
||||
}
|
||||
|
||||
class TypeInfo_Const : TypeInfo
|
||||
{
|
||||
TypeInfo next;
|
||||
}
|
||||
|
||||
class TypeInfo_Invariant : TypeInfo_Const
|
||||
{
|
||||
}
|
||||
|
||||
// Recoverable errors
|
||||
|
||||
class Exception : Object
|
||||
{
|
||||
char[] msg;
|
||||
string msg;
|
||||
|
||||
this(char[] msg);
|
||||
void print();
|
||||
char[] toString();
|
||||
this(string msg);
|
||||
override void print();
|
||||
override string toString();
|
||||
}
|
||||
|
||||
// Non-recoverable errors
|
||||
@@ -158,7 +179,7 @@ class Error : Exception
|
||||
{
|
||||
Error next;
|
||||
|
||||
this(char[] msg);
|
||||
this(char[] msg, Error next);
|
||||
this(string msg);
|
||||
this(string msg, Error next);
|
||||
}
|
||||
|
||||
|
||||
17
test/bug5.d
Normal file
17
test/bug5.d
Normal file
@@ -0,0 +1,17 @@
|
||||
module bug5;
|
||||
|
||||
struct hah {
|
||||
static hah f()
|
||||
{
|
||||
hah res;
|
||||
return res;
|
||||
}
|
||||
hah g()
|
||||
{
|
||||
return hah.init;
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
}
|
||||
Reference in New Issue
Block a user