Mercurial > projects > ldc
diff gen/declarations.cpp @ 1147:dbe4af57b240
Changed use of toObjFile to a new codegen method.
More versioning of DMD specific codegen code.
author | Tomas Lindquist Olsen <tomas.l.olsen gmail.com> |
---|---|
date | Fri, 27 Mar 2009 17:54:27 +0100 |
parents | |
children | 3d1b16dabd25 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gen/declarations.cpp Fri Mar 27 17:54:27 2009 +0100 @@ -0,0 +1,268 @@ +#include "gen/llvm.h" + +#include "aggregate.h" +#include "declaration.h" +#include "enum.h" +#include "id.h" +#include "mem.h" +#include "template.h" + +#include "gen/irstate.h" +#include "gen/tollvm.h" +#include "gen/llvmhelpers.h" +#include "gen/logger.h" + +#include "ir/ir.h" +#include "ir/irvar.h" + +/* ================================================================== */ + +void Dsymbol::codegen(Ir*) +{ + Logger::println("Ignoring Dsymbol::toObjFile for %s", toChars()); +} + +/* ================================================================== */ + +void Declaration::codegen(Ir*) +{ + Logger::println("Ignoring Declaration::toObjFile for %s", toChars()); +} + +/* ================================================================== */ + +void InterfaceDeclaration::codegen(Ir*) +{ + //Logger::println("Ignoring InterfaceDeclaration::toObjFile for %s", toChars()); + DtoResolveDsymbol(this); +} + +/* ================================================================== */ + +void StructDeclaration::codegen(Ir*) +{ + DtoResolveDsymbol(this); +} + +/* ================================================================== */ + +void ClassDeclaration::codegen(Ir*) +{ + DtoResolveDsymbol(this); +} + +/* ================================================================== */ + +void TupleDeclaration::codegen(Ir* p) +{ + Logger::println("TupleDeclaration::toObjFile(): %s", toChars()); + + assert(isexp); + assert(objects); + + int n = objects->dim; + + for (int i=0; i < n; ++i) + { + DsymbolExp* exp = (DsymbolExp*)objects->data[i]; + assert(exp->op == TOKdsymbol); + exp->s->codegen(p); + } +} + +/* ================================================================== */ + +void VarDeclaration::codegen(Ir* p) +{ + Logger::print("VarDeclaration::toObjFile(): %s | %s\n", toChars(), type->toChars()); + LOG_SCOPE; + + if (aliassym) + { + Logger::println("alias sym"); + toAlias()->codegen(p); + return; + } + + // global variable or magic +#if DMDV2 + // taken from dmd2/structs + if (isDataseg() || (storage_class & (STCconst | STCinvariant) && init)) +#else + if (isDataseg()) +#endif + { + Logger::println("data segment"); + + #if DMDV2 + if (storage_class & STCmanifest) + { + assert(0 && "manifest constant being codegened!!!"); + } + #endif + + // don't duplicate work + if (this->ir.resolved) return; + this->ir.resolved = true; + this->ir.declared = true; + + this->ir.irGlobal = new IrGlobal(this); + + Logger::println("parent: %s (%s)", parent->toChars(), parent->kind()); + + #if DMDV2 + // not sure why this is only needed for d2 + bool _isconst = isConst() && init; + #else + bool _isconst = isConst(); + #endif + + + Logger::println("Creating global variable"); + + const LLType* _type = this->ir.irGlobal->type.get(); + llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(this); + std::string _name(mangle()); + + llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,NULL,_name,gIR->module); + this->ir.irGlobal->value = gvar; + + if (Logger::enabled()) + Logger::cout() << *gvar << '\n'; + + // if this global is used from a nested function, this is necessary or + // optimization could potentially remove the global (if it's the only use) + if (nakedUse) + gIR->usedArray.push_back(DtoBitCast(gvar, getVoidPtrType())); + + gIR->constInitList.push_back(this); + } + else + { + // might already have its irField, as classes derive each other without getting copies of the VarDeclaration + if (!ir.irField) + { + assert(!ir.isSet()); + ir.irField = new IrField(this); + } + IrStruct* irstruct = gIR->topstruct(); + irstruct->addVar(this); + + Logger::println("added offset %u", offset); + } +} + +/* ================================================================== */ + +void TypedefDeclaration::codegen(Ir*) +{ + static int tdi = 0; + Logger::print("TypedefDeclaration::toObjFile(%d): %s\n", tdi++, toChars()); + LOG_SCOPE; + + // generate typeinfo + DtoTypeInfoOf(type, false); +} + +/* ================================================================== */ + +void EnumDeclaration::codegen(Ir*) +{ + Logger::println("Ignoring EnumDeclaration::toObjFile for %s", toChars()); +} + +/* ================================================================== */ + +void FuncDeclaration::codegen(Ir*) +{ + DtoResolveDsymbol(this); +} + +/* ================================================================== */ + +void AnonDeclaration::codegen(Ir* p) +{ + Array *d = include(NULL, NULL); + + if (d) + { + // get real aggregate parent + IrStruct* irstruct = gIR->topstruct(); + + // push a block on the stack + irstruct->pushAnon(isunion); + + // go over children + for (unsigned i = 0; i < d->dim; i++) + { Dsymbol *s = (Dsymbol *)d->data[i]; + s->codegen(p); + } + + // finish + irstruct->popAnon(); + } +} + +/* ================================================================== */ + +void TemplateInstance::codegen(Ir* p) +{ +#if LOG + printf("TemplateInstance::toObjFile('%s', this = %p)\n", toChars(), this); +#endif + if (!errors && members) + { + for (int i = 0; i < members->dim; i++) + { + Dsymbol *s = (Dsymbol *)members->data[i]; + s->codegen(p); + } + } +} + +/* ================================================================== */ + +void TemplateMixin::codegen(Ir* p) +{ + TemplateInstance::codegen(p); +} + +/* ================================================================== */ + +void AttribDeclaration::codegen(Ir* p) +{ + Array *d = include(NULL, NULL); + + if (d) + { + for (unsigned i = 0; i < d->dim; i++) + { Dsymbol *s = (Dsymbol *)d->data[i]; + s->codegen(p); + } + } +} + +/* ================================================================== */ + +void obj_includelib(const char* lib); + +void PragmaDeclaration::codegen(Ir* p) +{ + if (ident == Id::lib) + { + assert(args && args->dim == 1); + + Expression *e = (Expression *)args->data[0]; + + assert(e->op == TOKstring); + + StringExp *se = (StringExp *)e; + char *name = (char *)mem.malloc(se->len + 1); + memcpy(name, se->string, se->len); + name[se->len] = 0; + obj_includelib(name); + } + AttribDeclaration::codegen(p); +} + +/* ================================================================== */