void AttribDeclaration::codegen(Ir* p) { Array *d = include(NULL, NULL); if (d) { for (unsigned i = 0; i < d->dim; i++) { Dsymbol *s = static_cast<Dsymbol *>(d->data[i]); s->codegen(p); } } }
void TemplateMixin::codegen(Ir* p) { if (!errors && members) { for (unsigned i = 0; i < members->dim; i++) { Dsymbol *s = static_cast<Dsymbol *>(members->data[i]); if (s->isVarDeclaration()) continue; s->codegen(p); } } }
void TemplateInstance::codegen(Ir* p) { #if LOG printf("TemplateInstance::codegen('%s', this = %p)\n", toChars(), this); #endif if (ignore) return; if (!errors && members) { for (unsigned i = 0; i < members->dim; i++) { Dsymbol *s = static_cast<Dsymbol *>(members->data[i]); s->codegen(p); } } }
llvm::Module* Module::genLLVMModule(llvm::LLVMContext& context, Ir* sir) { bool logenabled = Logger::enabled(); if (llvmForceLogging && !logenabled) { Logger::enable(); } Logger::println("Generating module: %s", (md ? md->toChars() : toChars())); LOG_SCOPE; if (global.params.verbose_cg) printf("codegen: %s (%s)\n", toPrettyChars(), srcfile->toChars()); assert(!global.errors); // name the module #if 1 // Temporary workaround for http://llvm.org/bugs/show_bug.cgi?id=11479 – // just use the source file name, as it is unlikely to collide with a // symbol name used somewhere in the module. llvm::StringRef mname(srcfile->toChars()); #else llvm::StringRef mname(toChars()); if (md != 0) mname = md->toChars(); #endif // create a new ir state // TODO look at making the instance static and moving most functionality into IrModule where it belongs IRState ir(new llvm::Module(mname, context)); gIR = &ir; ir.dmodule = this; // reset all IR data stored in Dsymbols IrDsymbol::resetAll(); sir->setState(&ir); // set target triple ir.module->setTargetTriple(global.params.targetTriple.str()); // set final data layout ir.module->setDataLayout(gDataLayout->getStringRepresentation()); if (Logger::enabled()) Logger::cout() << "Final data layout: " << ir.module->getDataLayout() << '\n'; // allocate the target abi gABI = TargetABI::getTarget(); // debug info DtoDwarfCompileUnit(this); // handle invalid 'objectø module if (!ClassDeclaration::object) { error("is missing 'class Object'"); fatal(); } if (!ClassDeclaration::classinfo) { error("is missing 'class ClassInfo'"); fatal(); } LLVM_D_InitRuntime(); // process module members for (unsigned k=0; k < members->dim; k++) { Dsymbol* dsym = static_cast<Dsymbol*>(members->data[k]); assert(dsym); dsym->codegen(sir); } // emit function bodies sir->emitFunctionBodies(); // for singleobj-compilation, fully emit all seen template instances if (global.params.singleObj) { while (!ir.seenTemplateInstances.empty()) { IRState::TemplateInstanceSet::iterator it, end = ir.seenTemplateInstances.end(); for (it = ir.seenTemplateInstances.begin(); it != end; ++it) (*it)->codegen(sir); ir.seenTemplateInstances.clear(); // emit any newly added function bodies sir->emitFunctionBodies(); } } // finilize debug info DtoDwarfModuleEnd(); // generate ModuleInfo genmoduleinfo(); // verify the llvm verifyModule(*ir.module); gIR = NULL; if (llvmForceLogging && !logenabled) { Logger::disable(); } sir->setState(NULL); return ir.module; }
void DtoResolveStruct(StructDeclaration* sd) { // don't do anything if already been here if (sd->ir.resolved) return; // make sure above works :P sd->ir.resolved = true; // log what we're doing Logger::println("Resolving struct type: %s (%s)", sd->toChars(), sd->loc.toChars()); LOG_SCOPE; // make sure type exists DtoType(sd->type); // if it's a forward declaration, all bets are off. The type should be enough if (sd->sizeok != 1) return; // create the IrStruct IrStruct* irstruct = new IrStruct(sd); sd->ir.irStruct = irstruct; // make sure all fields really get their ir field ArrayIter<VarDeclaration> it(sd->fields); for (; !it.done(); it.next()) { VarDeclaration* vd = it.get(); if (vd->ir.irField == NULL) { new IrField(vd); } else { IF_LOG Logger::println("struct field already exists!!!"); } } // perform definition bool needs_def = mustDefineSymbol(sd); if (needs_def) { // emit the initZ symbol LLGlobalVariable* initZ = irstruct->getInitSymbol(); // set initZ initializer initZ->setInitializer(irstruct->getDefaultInit()); } // emit members if (sd->members) { ArrayIter<Dsymbol> it(*sd->members); while (!it.done()) { Dsymbol* member = it.get(); if (member) member->codegen(Type::sir); it.next(); } } if (needs_def) { // emit typeinfo DtoTypeInfoOf(sd->type); } }
void DtoResolveClass(ClassDeclaration* cd) { // make sure the base classes are processed first ArrayIter<BaseClass> base_iter(cd->baseclasses); while (base_iter.more()) { BaseClass* bc = base_iter.get(); if (bc) { bc->base->codegen(Type::sir); } base_iter.next(); } if (cd->ir.resolved) return; cd->ir.resolved = true; Logger::println("DtoResolveClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); LOG_SCOPE; // make sure type exists DtoType(cd->type); // create IrStruct assert(cd->ir.irStruct == NULL); IrStruct* irstruct = new IrStruct(cd); cd->ir.irStruct = irstruct; // make sure all fields really get their ir field ArrayIter<VarDeclaration> it(cd->fields); for (; !it.done(); it.next()) { VarDeclaration* vd = it.get(); if (vd->ir.irField == NULL) { new IrField(vd); } else { IF_LOG Logger::println("class field already exists!!!"); } } bool needs_def = mustDefineSymbol(cd); // emit the ClassZ symbol LLGlobalVariable* ClassZ = irstruct->getClassInfoSymbol(); // emit the interfaceInfosZ symbol if necessary if (cd->vtblInterfaces && cd->vtblInterfaces->dim > 0) irstruct->getInterfaceArraySymbol(); // initializer is applied when it's built // interface only emit typeinfo and classinfo if (cd->isInterfaceDeclaration()) { irstruct->initializeInterface(); } else { // emit the initZ symbol LLGlobalVariable* initZ = irstruct->getInitSymbol(); // emit the vtblZ symbol LLGlobalVariable* vtblZ = irstruct->getVtblSymbol(); // perform definition if (needs_def) { // set symbol initializers initZ->setInitializer(irstruct->getDefaultInit()); vtblZ->setInitializer(irstruct->getVtblInit()); } } // emit members if (cd->members) { ArrayIter<Dsymbol> it(*cd->members); while (!it.done()) { Dsymbol* member = it.get(); if (member) member->codegen(Type::sir); it.next(); } } if (needs_def) { // emit typeinfo DtoTypeInfoOf(cd->type); // define classinfo ClassZ->setInitializer(irstruct->getClassInfoInit()); } }