Mercurial > projects > ldc
diff gen/toobj.c @ 40:8b0e809563df trunk
[svn r44] Lots of bug fixes.
New array literal support
New array ~= operator support (for single element)
New with statement support
More...
author | lindquist |
---|---|
date | Fri, 19 Oct 2007 07:43:21 +0200 |
parents | 27b2f40bdb58 |
children | 6fcc08a4d406 |
line wrap: on
line diff
--- a/gen/toobj.c Wed Oct 10 06:21:31 2007 +0200 +++ b/gen/toobj.c Fri Oct 19 07:43:21 2007 +0200 @@ -11,14 +11,9 @@ #include <iostream> #include <fstream> -#include "llvm/Type.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Instructions.h" +#include "gen/llvm.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Bitcode/ReaderWriter.h" - -#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachineRegistry.h" @@ -152,13 +147,14 @@ LOG_SCOPE; for (unsigned i=0; i<fields.dim; ++i) { VarDeclaration* vd = (VarDeclaration*)fields.data[i]; - Logger::println("found %u type %s", vd->offset, vd->type->toChars()); - if (os == vd->offset && vd->type == t) { + Type* vdtype = LLVM_DtoDType(vd->type); + Logger::println("found %u type %s", vd->offset, vdtype->toChars()); + if (os == vd->offset && vdtype == t) { result.push_back(i); return; } - else if (vd->type->ty == Tstruct && (vd->offset + vd->type->size()) > os) { - TypeStruct* ts = (TypeStruct*)vd->type; + else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) { + TypeStruct* ts = (TypeStruct*)vdtype; StructDeclaration* sd = ts->sym; result.push_back(i); sd->offsetToIndex(t, os - vd->offset, result); @@ -212,7 +208,7 @@ void StructDeclaration::toObjFile() { - TypeStruct* ts = (TypeStruct*)type; + TypeStruct* ts = (TypeStruct*)LLVM_DtoDType(type); if (llvmType != 0) return; @@ -288,7 +284,7 @@ // generate member function definitions gIR->topstruct().queueFuncs = false; - IRState::FuncDeclVec& mfs = gIR->topstruct().funcs; + IRStruct::FuncDeclVec& mfs = gIR->topstruct().funcs; size_t n = mfs.size(); for (size_t i=0; i<n; ++i) { mfs[i]->toObjFile(); @@ -311,6 +307,9 @@ { BaseClass* bc = (BaseClass*)(bcs->data[j]); assert(bc); + Logger::println("Adding base class members of %s", bc->base->toChars()); + LOG_SCOPE; + LLVM_AddBaseClassData(&bc->base->baseclasses); for (int k=0; k < bc->base->members->dim; k++) { Dsymbol* dsym = (Dsymbol*)(bc->base->members->data[k]); @@ -324,7 +323,7 @@ void ClassDeclaration::toObjFile() { - TypeClass* ts = (TypeClass*)type; + TypeClass* ts = (TypeClass*)LLVM_DtoDType(type); if (ts->llvmType != 0 || llvmInProgress) return; @@ -453,7 +452,7 @@ // generate member function definitions gIR->topstruct().queueFuncs = false; - IRState::FuncDeclVec& mfs = gIR->topstruct().funcs; + IRStruct::FuncDeclVec& mfs = gIR->topstruct().funcs; size_t n = mfs.size(); for (size_t i=0; i<n; ++i) { mfs[i]->toObjFile(); @@ -479,8 +478,7 @@ void VarDeclaration::toObjFile() { - static int vdi = 0; - Logger::print("VarDeclaration::toObjFile(%d): %s | %s\n", vdi++, toChars(), type->toChars()); + Logger::print("VarDeclaration::toObjFile(): %s | %s\n", toChars(), type->toChars()); LOG_SCOPE; llvm::Module* M = gIR->module; @@ -493,8 +491,11 @@ } // global variable or magic - if (isDataseg()) + if (isDataseg() || parent->isModule()) { + if (llvmTouched) return; + else llvmTouched = true; + bool _isconst = isConst(); llvm::GlobalValue::LinkageTypes _linkage; @@ -503,7 +504,9 @@ else _linkage = LLVM_DtoLinkage(protection, storage_class); - const llvm::Type* _type = LLVM_DtoType(type); + Type* t = LLVM_DtoDType(type); + + const llvm::Type* _type = LLVM_DtoType(t); assert(_type); llvm::Constant* _init = 0; @@ -513,10 +516,10 @@ std::string _name(mangle()); llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,0,_name,M); llvmValue = gvar; + gIR->lvals.push_back(gvar); - - _init = LLVM_DtoInitializer(type, init); - assert(_init); + _init = LLVM_DtoConstInitializer(t, init); + gIR->lvals.pop_back(); //Logger::cout() << "initializer: " << *_init << '\n'; if (_type != _init->getType()) { @@ -529,8 +532,8 @@ { assert(_init->getType()->getContainedType(0) == _type); llvm::GlobalVariable* gv = llvm::cast<llvm::GlobalVariable>(_init); - assert(type->ty == Tstruct); - TypeStruct* ts = (TypeStruct*)type; + assert(t->ty == Tstruct); + TypeStruct* ts = (TypeStruct*)t; assert(ts->sym->llvmInitZ); _init = ts->sym->llvmInitZ; } @@ -549,9 +552,9 @@ } } - gIR->lvals.pop_back(); - gvar->setInitializer(_init); + + llvmDModule = gIR->dmodule; //if (storage_class & STCprivate) // gvar->setVisibility(llvm::GlobalValue::ProtectedVisibility); @@ -562,36 +565,37 @@ { Logger::println("Aggregate var declaration: '%s' offset=%d", toChars(), offset); - const llvm::Type* _type = LLVM_DtoType(type); + Type* t = LLVM_DtoDType(type); + const llvm::Type* _type = LLVM_DtoType(t); gIR->topstruct().fields.push_back(_type); - llvm::Constant*_init = LLVM_DtoInitializer(type, init); + llvm::Constant*_init = LLVM_DtoConstInitializer(t, init); assert(_init); Logger::cout() << "field init is: " << *_init << " type should be " << *_type << '\n'; - if (!_init || _type != _init->getType()) + if (_type != _init->getType()) { - if (type->ty == Tsarray) + if (t->ty == Tsarray) { const llvm::ArrayType* arrty = llvm::cast<llvm::ArrayType>(_type); uint64_t n = arrty->getNumElements(); std::vector<llvm::Constant*> vals(n,_init); _init = llvm::ConstantArray::get(arrty, vals); } - else if (type->ty == Tarray) + else if (t->ty == Tarray) { assert(llvm::isa<llvm::StructType>(_type)); _init = llvm::ConstantAggregateZero::get(_type); } - else if (type->ty == Tstruct) + else if (t->ty == Tstruct) { const llvm::StructType* structty = llvm::cast<llvm::StructType>(_type); - TypeStruct* ts = (TypeStruct*)type; + TypeStruct* ts = (TypeStruct*)t; assert(ts); assert(ts->sym); assert(ts->sym->llvmInitZ); _init = ts->sym->llvmInitZ; } - else if (type->ty == Tclass) + else if (t->ty == Tclass) { _init = llvm::Constant::getNullValue(_type); } @@ -644,7 +648,8 @@ return; // we wait with the definition as they might invoke a virtual method and the vtable is not yet complete } - TypeFunction* f = (TypeFunction*)type; + Type* t = LLVM_DtoDType(type); + TypeFunction* f = (TypeFunction*)t; assert(f->llvmType); const llvm::FunctionType* functype = llvm::cast<llvm::FunctionType>(llvmValue->getType()->getContainedType(0)); @@ -684,7 +689,8 @@ // function definition if (allow_fbody && fbody != 0) { - gIR->funcdecls.push_back(this); + gIR->functions.push_back(IRFunction(this)); + gIR->func().func = func; // first make absolutely sure the type is up to date f->llvmType = llvmValue->getType()->getContainedType(0); @@ -703,39 +709,38 @@ if (isMain()) gIR->emitMain = true; - gIR->funcs.push(func); - gIR->functypes.push(f); - - IRScope irs; - irs.begin = new llvm::BasicBlock("entry",func); - irs.end = new llvm::BasicBlock("endentry",func); + llvm::BasicBlock* beginbb = new llvm::BasicBlock("entry",func); + llvm::BasicBlock* endbb = new llvm::BasicBlock("endentry",func); //assert(gIR->scopes.empty()); - gIR->scopes.push_back(irs); + gIR->scopes.push_back(IRScope(beginbb, endbb)); // create alloca point f->llvmAllocaPoint = new llvm::BitCastInst(llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false),llvm::Type::Int32Ty,"alloca point",gIR->scopebb()); + gIR->func().allocapoint = f->llvmAllocaPoint; // output function body fbody->toIR(gIR); // llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement // in automatically, so we do it here. - if (!isMain() && (gIR->scopebb()->empty() || !llvm::isa<llvm::TerminatorInst>(gIR->scopebb()->back()))) { - // pass the previous block into this block - //new llvm::BranchInst(irs.end, irs.begin); - new llvm::ReturnInst(gIR->scopebb()); + if (!isMain()) { + if (gIR->scopebb()->empty() || !llvm::isa<llvm::TerminatorInst>(gIR->scopebb()->back())) { + // pass the previous block into this block + //new llvm::BranchInst(irs.end, irs.begin); + if (func->getReturnType() == llvm::Type::VoidTy) { + new llvm::ReturnInst(gIR->scopebb()); + } + + } } // erase alloca point f->llvmAllocaPoint->eraseFromParent(); f->llvmAllocaPoint = 0; + gIR->func().allocapoint = 0; gIR->scopes.pop_back(); - //assert(gIR->scopes.empty()); - - gIR->functypes.pop(); - gIR->funcs.pop(); // get rid of the endentry block, it's never used assert(!func->getBasicBlockList().empty()); @@ -745,11 +750,10 @@ // would be nice to figure out how to assert that this is correct llvm::BasicBlock* lastbb = &func->getBasicBlockList().back(); if (lastbb->empty()) { - // possibly assert(lastbb->getNumPredecessors() == 0); ??? try it out sometime ... - new llvm::UnreachableInst(lastbb); + lastbb->eraseFromParent(); } - gIR->funcdecls.pop_back(); + gIR->functions.pop_back(); } // template instances should have weak linkage