Mercurial > projects > ldc
diff gen/toobj.c @ 52:0c77619e803b trunk
[svn r56] Initial support for TypeInfo.
Enums not work.
Several other bugfixes.
author | lindquist |
---|---|
date | Tue, 23 Oct 2007 05:55:12 +0200 |
parents | 6fcc08a4d406 |
children | 28e99b04a132 |
line wrap: on
line diff
--- a/gen/toobj.c Mon Oct 22 17:25:44 2007 +0200 +++ b/gen/toobj.c Tue Oct 23 05:55:12 2007 +0200 @@ -98,19 +98,19 @@ // run passes // TODO - /*if (global.params.llvmLL) { - //assert(0); - std::ofstream os(llfile->name->toChars()); - //llvm::WriteAssemblyToFile(ir.module, os); - ir.module->print(os); - }*/ + // write bytecode + { + Logger::println("Writing LLVM bitcode\n"); + std::ofstream bos(bcfile->name->toChars(), std::ios::binary); + llvm::WriteBitcodeToFile(ir.module, bos); + } - // write bytecode - //if (global.params.llvmBC) { - Logger::println("Writing LLVM bitcode\n"); - std::ofstream os(bcfile->name->toChars(), std::ios::binary); - llvm::WriteBitcodeToFile(ir.module, os); - //} + // disassemble ? + if (global.params.disassemble) { + Logger::println("Writing LLVM asm to: %s\n", llfile->name->toChars()); + std::ofstream aos(llfile->name->toChars()); + ir.module->print(aos); + } delete ir.module; gIR = NULL; @@ -295,7 +295,7 @@ gIR->structs.pop_back(); // generate typeinfo - type->getTypeInfo(NULL); // generate TypeInfo + //type->getTypeInfo(NULL); } /* ================================================================== */ @@ -407,8 +407,10 @@ { llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage; - std::string varname(mangle()); - varname.append("__vtblZ"); + std::string varname("_D"); + varname.append(mangle()); + varname.append("6__vtblZ"); + std::string styname(mangle()); styname.append("__vtblTy"); @@ -441,8 +443,10 @@ _init = llvm::ConstantStruct::get(structtype,gIR->topstruct().inits); assert(_init); - std::string initname(mangle()); - initname.append("__initZ"); + + std::string initname("_D"); + initname.append(mangle()); + initname.append("6__initZ"); //Logger::cout() << *_init << '\n'; llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType, true, _linkage, 0, initname, gIR->module); ts->llvmInit = initvar; @@ -499,7 +503,7 @@ bool _isconst = isConst(); llvm::GlobalValue::LinkageTypes _linkage; - if (parent->isFuncDeclaration()) + if (parent && parent->isFuncDeclaration()) _linkage = llvm::GlobalValue::InternalLinkage; else _linkage = LLVM_DtoLinkage(protection, storage_class); @@ -514,46 +518,51 @@ Logger::println("Creating global variable"); 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_DtoConstInitializer(t, init); - gIR->lvals.pop_back(); + // if extern don't emit initializer + if (!(storage_class & STCextern)) + { + gIR->lvals.push_back(gvar); + _init = LLVM_DtoConstInitializer(t, init); + gIR->lvals.pop_back(); - //Logger::cout() << "initializer: " << *_init << '\n'; - if (_type != _init->getType()) { - Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n"; - // zero initalizer - if (_init->isNullValue()) - _init = llvm::Constant::getNullValue(_type); - // pointer to global constant (struct.init) - else if (llvm::isa<llvm::GlobalVariable>(_init)) - { - assert(_init->getType()->getContainedType(0) == _type); - llvm::GlobalVariable* gv = llvm::cast<llvm::GlobalVariable>(_init); - assert(t->ty == Tstruct); - TypeStruct* ts = (TypeStruct*)t; - assert(ts->sym->llvmInitZ); - _init = ts->sym->llvmInitZ; + //Logger::cout() << "initializer: " << *_init << '\n'; + if (_type != _init->getType()) { + Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n"; + // zero initalizer + if (_init->isNullValue()) + _init = llvm::Constant::getNullValue(_type); + // pointer to global constant (struct.init) + else if (llvm::isa<llvm::GlobalVariable>(_init)) + { + assert(_init->getType()->getContainedType(0) == _type); + llvm::GlobalVariable* gv = llvm::cast<llvm::GlobalVariable>(_init); + assert(t->ty == Tstruct); + TypeStruct* ts = (TypeStruct*)t; + assert(ts->sym->llvmInitZ); + _init = ts->sym->llvmInitZ; + } + // array single value init + else if (llvm::isa<llvm::ArrayType>(_type)) + { + const llvm::ArrayType* at = llvm::cast<llvm::ArrayType>(_type); + assert(_type->getContainedType(0) == _init->getType()); + std::vector<llvm::Constant*> initvals; + initvals.resize(at->getNumElements(), _init); + _init = llvm::ConstantArray::get(at, initvals); + } + else { + Logger::cout() << "Unexpected initializer type: " << *_type << '\n'; + //assert(0); + } } - // array single value init - else if (llvm::isa<llvm::ArrayType>(_type)) - { - const llvm::ArrayType* at = llvm::cast<llvm::ArrayType>(_type); - assert(_type->getContainedType(0) == _init->getType()); - std::vector<llvm::Constant*> initvals; - initvals.resize(at->getNumElements(), _init); - _init = llvm::ConstantArray::get(at, initvals); - } - else { - Logger::cout() << "Unexpected initializer type: " << *_type << '\n'; - //assert(0); - } + + gvar->setInitializer(_init); } - gvar->setInitializer(_init); - llvmDModule = gIR->dmodule; //if (storage_class & STCprivate) @@ -618,7 +627,8 @@ Logger::print("TypedefDeclaration::toObjFile(%d): %s\n", tdi++, toChars()); LOG_SCOPE; - // TODO + // generate typeinfo + type->getTypeInfo(NULL); } /* ================================================================== */ @@ -695,7 +705,7 @@ // first make absolutely sure the type is up to date f->llvmType = llvmValue->getType()->getContainedType(0); - Logger::cout() << "func type: " << *f->llvmType << '\n'; + //Logger::cout() << "func type: " << *f->llvmType << '\n'; // this handling if (f->llvmUsesThis) { @@ -754,12 +764,15 @@ // 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()) { - if (gIR->scopebb()->empty() || !llvm::isa<llvm::TerminatorInst>(gIR->scopebb()->back())) { + if (!gIR->scopereturned()) { // 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()); } + else { + new llvm::ReturnInst(llvm::UndefValue::get(func->getReturnType()), gIR->scopebb()); + } } } @@ -778,7 +791,17 @@ // would be nice to figure out how to assert that this is correct llvm::BasicBlock* lastbb = &func->getBasicBlockList().back(); if (lastbb->empty()) { - lastbb->eraseFromParent(); + if (lastbb->getNumUses() == 0) + lastbb->eraseFromParent(); + else { + new llvm::UnreachableInst(lastbb); + /*if (func->getReturnType() == llvm::Type::VoidTy) { + new llvm::ReturnInst(lastbb); + } + else { + new llvm::ReturnInst(llvm::UndefValue::get(func->getReturnType()), lastbb); + }*/ + } } gIR->functions.pop_back();