[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:
Tomas Lindquist Olsen
2007-10-04 16:44:07 +02:00
parent c188a544de
commit 56d2cff2a2
8 changed files with 80 additions and 46 deletions

View File

@@ -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])

View File

@@ -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

View File

@@ -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()

View File

@@ -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;
};

View File

@@ -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;

View File

@@ -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)

View File

@@ -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
View File

@@ -0,0 +1,17 @@
module bug5;
struct hah {
static hah f()
{
hah res;
return res;
}
hah g()
{
return hah.init;
}
}
void main()
{
}