# HG changeset patch # User lindquist # Date 1200536112 -3600 # Node ID 0e28624814e84b8eca39f19645b648922f524b5d # Parent 176bd52b3cf55c9665408283c39b0ad78a4df46f [svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though diff -r 176bd52b3cf5 -r 0e28624814e8 dmd/aggregate.h --- a/dmd/aggregate.h Mon Jan 14 23:09:55 2008 +0100 +++ b/dmd/aggregate.h Thu Jan 17 03:15:12 2008 +0100 @@ -45,7 +45,7 @@ class ConstantStruct; class GlobalVariable; } -struct IRStruct; +struct IrStruct; struct DUnion; struct AggregateDeclaration : ScopeDsymbol @@ -110,7 +110,7 @@ llvm::Constant* llvmConstClass; bool llvmHasUnions; DUnion* llvmUnion; - IRStruct* llvmIRStruct; + IrStruct* llvmIrStruct; bool llvmClassDeclared; bool llvmClassDefined; diff -r 176bd52b3cf5 -r 0e28624814e8 dmd/declaration.c --- a/dmd/declaration.c Mon Jan 14 23:09:55 2008 +0100 +++ b/dmd/declaration.c Thu Jan 17 03:15:12 2008 +0100 @@ -549,12 +549,10 @@ onstack = 0; canassign = 0; value = NULL; - llvmNestedIndex = -1; - llvmFieldIndex = -1; - llvmFieldIndexOffset = 0; - llvmNeedsStorage = false; - llvmConstInit = NULL; - llvmIRGlobal = NULL; + irGlobal = NULL; + irLocal = NULL; + irField = NULL; + needsStorage = false; } Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) @@ -1060,7 +1058,7 @@ fdthis->getLevel(loc, fdv); nestedref = 1; fdv->nestedFrameRef = 1; - fdv->llvmNestedVars.insert(this); + fdv->nestedVars.insert(this); //printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars()); } } diff -r 176bd52b3cf5 -r 0e28624814e8 dmd/declaration.h --- a/dmd/declaration.h Mon Jan 14 23:09:55 2008 +0100 +++ b/dmd/declaration.h Thu Jan 17 03:15:12 2008 +0100 @@ -24,8 +24,11 @@ namespace llvm { class Value; } -struct IRFunction; -struct IRGlobal; +struct IrFunction; +struct IrVar; +struct IrGlobal; +struct IrLocal; +struct IrField; struct Expression; struct Statement; @@ -261,12 +264,13 @@ VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; } // LLVMDC - int llvmNestedIndex; - int llvmFieldIndex; - size_t llvmFieldIndexOffset; - bool llvmNeedsStorage; - llvm::Constant* llvmConstInit; - IRGlobal* llvmIRGlobal; + IrGlobal* irGlobal; + IrLocal* irLocal; + IrField* irField; + bool needsStorage; + + IrVar* getIrVar(); + llvm::Value*& getIrValue(); }; /**************************************************************/ @@ -609,16 +613,9 @@ FuncDeclaration *isFuncDeclaration() { return this; } // llvmdc stuff - bool llvmQueued; - llvm::Value* llvmThisVar; - std::set llvmNestedVars; - llvm::Value* llvmNested; - llvm::Value* llvmArguments; - llvm::Value* llvmArgPtr; - llvm::Constant* llvmDwarfSubProgram; - bool llvmRunTimeHack; - IRFunction* llvmIRFunc; - llvm::Value* llvmRetArg; + bool runTimeHack; + IrFunction* irFunc; + std::set nestedVars; }; struct FuncAliasDeclaration : FuncDeclaration diff -r 176bd52b3cf5 -r 0e28624814e8 dmd/dsymbol.c --- a/dmd/dsymbol.c Mon Jan 14 23:09:55 2008 +0100 +++ b/dmd/dsymbol.c Thu Jan 17 03:15:12 2008 +0100 @@ -43,10 +43,12 @@ this->isym = NULL; this->loc = 0; this->comment = NULL; + this->llvmInternal = LLVMnone; this->llvmInternal1 = NULL; this->llvmInternal2 = NULL; - this->llvmValue = NULL; + + //this->llvmValue = NULL; this->llvmDModule = NULL; this->llvmResolved = false; @@ -65,10 +67,12 @@ this->isym = NULL; this->loc = 0; this->comment = NULL; + this->llvmInternal = LLVMnone; this->llvmInternal1 = NULL; this->llvmInternal2 = NULL; - this->llvmValue = NULL; + + //this->llvmValue = NULL; this->llvmDModule = NULL; this->llvmResolved = false; diff -r 176bd52b3cf5 -r 0e28624814e8 dmd/dsymbol.h --- a/dmd/dsymbol.h Mon Jan 14 23:09:55 2008 +0100 +++ b/dmd/dsymbol.h Thu Jan 17 03:15:12 2008 +0100 @@ -220,7 +220,7 @@ char* llvmInternal1; char* llvmInternal2; - llvm::Value* llvmValue; + //llvm::Value* llvmValue; Module* llvmDModule; bool llvmResolved; diff -r 176bd52b3cf5 -r 0e28624814e8 dmd/expression.c --- a/dmd/expression.c Mon Jan 14 23:09:55 2008 +0100 +++ b/dmd/expression.c Thu Jan 17 03:15:12 2008 +0100 @@ -3456,7 +3456,7 @@ if (v) { v->checkNestedReference(sc, loc); - v->llvmNeedsStorage = true; + v->needsStorage = true; } return this; } @@ -3601,7 +3601,7 @@ if (v && v->canassign == 0 && (var->isConst() || (global.params.Dversion > 1 && var->isFinal()))) error("cannot modify final variable '%s'", var->toChars()); - v->llvmNeedsStorage = true; + v->needsStorage = true; if (var->isCtorinit()) { // It's only modifiable if inside the right constructor @@ -5887,7 +5887,7 @@ } else if (v) { - v->llvmNeedsStorage = true; + v->needsStorage = true; } } else if (e1->op == TOKarray) diff -r 176bd52b3cf5 -r 0e28624814e8 dmd/func.c --- a/dmd/func.c Mon Jan 14 23:09:55 2008 +0100 +++ b/dmd/func.c Thu Jan 17 03:15:12 2008 +0100 @@ -73,15 +73,9 @@ nrvo_can = 1; nrvo_var = NULL; shidden = NULL; - llvmQueued = false; - llvmThisVar = NULL; - llvmNested = NULL; - llvmArguments = NULL; - llvmArgPtr = NULL; - llvmDwarfSubProgram = NULL; - llvmRunTimeHack = false; - llvmIRFunc = NULL; - llvmRetArg = NULL; + // llvmdc + runTimeHack = false; + irFunc = NULL; } Dsymbol *FuncDeclaration::syntaxCopy(Dsymbol *s) diff -r 176bd52b3cf5 -r 0e28624814e8 dmd/mtype.c --- a/dmd/mtype.c Mon Jan 14 23:09:55 2008 +0100 +++ b/dmd/mtype.c Thu Jan 17 03:15:12 2008 +0100 @@ -1514,7 +1514,7 @@ nm = name[n->ty == Twchar]; fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), nm); - fd->llvmRunTimeHack = true; + fd->runTimeHack = true; ec = new VarExp(0, fd); e = e->castTo(sc, n->arrayOf()); // convert to dynamic array arguments = new Expressions(); @@ -1532,7 +1532,7 @@ nm = name[n->ty == Twchar]; fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), nm); - fd->llvmRunTimeHack = true; + fd->runTimeHack = true; ec = new VarExp(0, fd); e = e->castTo(sc, n->arrayOf()); // convert to dynamic array arguments = new Expressions(); @@ -1551,7 +1551,7 @@ assert(size); dup = (ident == Id::dup); fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), dup ? Id::adDup : Id::adReverse); - fd->llvmRunTimeHack = true; + fd->runTimeHack = true; ec = new VarExp(0, fd); e = e->castTo(sc, n->arrayOf()); // convert to dynamic array arguments = new Expressions(); @@ -1571,7 +1571,7 @@ fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), (char*)(n->ty == Tbit ? "_adSortBit" : "_adSort")); - fd->llvmRunTimeHack = true; + fd->runTimeHack = true; ec = new VarExp(0, fd); e = e->castTo(sc, n->arrayOf()); // convert to dynamic array arguments = new Expressions(); @@ -2273,7 +2273,7 @@ Expressions *arguments; fd = FuncDeclaration::genCfunc(Type::tsize_t, Id::aaLen); - fd->llvmRunTimeHack = true; + fd->runTimeHack = true; ec = new VarExp(0, fd); arguments = new Expressions(); arguments->push(e); @@ -2289,7 +2289,7 @@ assert(size); fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), Id::aaKeys); - fd->llvmRunTimeHack = true; + fd->runTimeHack = true; ec = new VarExp(0, fd); arguments = new Expressions(); arguments->push(e); @@ -2304,7 +2304,7 @@ Expressions *arguments; fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), Id::aaValues); - fd->llvmRunTimeHack = true; + fd->runTimeHack = true; ec = new VarExp(0, fd); arguments = new Expressions(); arguments->push(e); @@ -2322,7 +2322,7 @@ Expressions *arguments; fd = FuncDeclaration::genCfunc(Type::tvoid->pointerTo(), Id::aaRehash); - fd->llvmRunTimeHack = true; + fd->runTimeHack = true; ec = new VarExp(0, fd); arguments = new Expressions(); arguments->push(e->addressOf(sc)); diff -r 176bd52b3cf5 -r 0e28624814e8 dmd/statement.c --- a/dmd/statement.c Mon Jan 14 23:09:55 2008 +0100 +++ b/dmd/statement.c Thu Jan 17 03:15:12 2008 +0100 @@ -1431,7 +1431,7 @@ fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply2"); else fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply"); - fdapply->llvmRunTimeHack = true; + fdapply->runTimeHack = true; ec = new VarExp(0, fdapply); Expressions *exps = new Expressions(); exps->push(aggr); @@ -1473,7 +1473,7 @@ int j = sprintf(fdname, "_aApply%s%.*s%d", r, 2, fntab[flag], dim); assert(j < sizeof(fdname)); fdapply = FuncDeclaration::genCfunc(Type::tindex, fdname); - fdapply->llvmRunTimeHack = true; + fdapply->runTimeHack = true; ec = new VarExp(0, fdapply); Expressions *exps = new Expressions(); diff -r 176bd52b3cf5 -r 0e28624814e8 dmd/struct.c --- a/dmd/struct.c Mon Jan 14 23:09:55 2008 +0100 +++ b/dmd/struct.c Thu Jan 17 03:15:12 2008 +0100 @@ -54,7 +54,7 @@ llvmInProgress = false; llvmHasUnions = false; llvmUnion = NULL; - llvmIRStruct = NULL; + llvmIrStruct = NULL; llvmClassDeclared = false; llvmClassDefined = false; } diff -r 176bd52b3cf5 -r 0e28624814e8 gen/aa.cpp --- a/gen/aa.cpp Mon Jan 14 23:09:55 2008 +0100 +++ b/gen/aa.cpp Thu Jan 17 03:15:12 2008 +0100 @@ -58,8 +58,8 @@ assert(tid); DtoResolveDsymbol(Type::typeinfo); DtoForceDeclareDsymbol(tid); - assert(tid->llvmValue); - return tid->llvmValue; + assert(tid->irGlobal->value); + return tid->irGlobal->value; } ///////////////////////////////////////////////////////////////////////////////////// diff -r 176bd52b3cf5 -r 0e28624814e8 gen/arrays.cpp --- a/gen/arrays.cpp Mon Jan 14 23:09:55 2008 +0100 +++ b/gen/arrays.cpp Thu Jan 17 03:15:12 2008 +0100 @@ -671,13 +671,11 @@ // pass element typeinfo ? if (useti) { TypeInfoDeclaration* ti = DtoDType(l->getType())->next->getTypeInfoDeclaration(); - if (!ti->llvmValue) { - DtoForceConstInitDsymbol(ti); - } - Logger::cout() << "typeinfo decl: " << *ti->llvmValue << '\n'; + DtoForceConstInitDsymbol(ti); + Logger::cout() << "typeinfo decl: " << *ti->getIrValue() << '\n'; pt = fn->getFunctionType()->getParamType(2); - args.push_back(DtoBitCast(ti->llvmValue, pt)); + args.push_back(DtoBitCast(ti->getIrValue(), pt)); } return gIR->ir->CreateCall(fn, args.begin(), args.end(), "tmp"); diff -r 176bd52b3cf5 -r 0e28624814e8 gen/classes.cpp --- a/gen/classes.cpp Mon Jan 14 23:09:55 2008 +0100 +++ b/gen/classes.cpp Thu Jan 17 03:15:12 2008 +0100 @@ -16,6 +16,8 @@ #include "gen/runtime.h" #include "gen/dvalue.h" +#include "ir/irstruct.h" + ////////////////////////////////////////////////////////////////////////////////////////// static void LLVM_AddBaseClassData(BaseClasses* bcs) @@ -24,9 +26,8 @@ for (int j=0; jdim; j++) { BaseClass* bc = (BaseClass*)(bcs->data[j]); - assert(bc); if (bc->base->isInterfaceDeclaration()) - continue; // interfaces only has methods + continue; // interfaces only have methods LLVM_AddBaseClassData(&bc->base->baseclasses); @@ -38,14 +39,6 @@ VarDeclaration* v = (VarDeclaration*)(arr->data[k]); v->toObjFile(); } - - /*for (int k=0; k < bc->base->members->dim; k++) { - Dsymbol* dsym = (Dsymbol*)(bc->base->members->data[k]); - if (dsym->isVarDeclaration()) - { - dsym->toObjFile(); - } - }*/ } } @@ -63,11 +56,11 @@ assert(cd->type->ty == Tclass); TypeClass* ts = (TypeClass*)cd->type; - // make sure the IRStruct is created - IRStruct* irstruct = cd->llvmIRStruct; + // make sure the IrStruct is created + IrStruct* irstruct = cd->llvmIrStruct; if (!irstruct) { - irstruct = new IRStruct(ts); - cd->llvmIRStruct = irstruct; + irstruct = new IrStruct(ts); + cd->llvmIrStruct = irstruct; } // resolve the base class @@ -75,7 +68,7 @@ DtoResolveClass(cd->baseClass); } - // resolve interfaces + // resolve interface vtables if (cd->vtblInterfaces) { for (int i=0; i < cd->vtblInterfaces->dim; i++) { BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i]; @@ -111,7 +104,7 @@ fieldtypes.push_back(ivtblTy); // add this interface to the map - IRInterface* iri = new IRInterface(b, isaStruct(itc->llvmVtblType->get())); + IrInterface* iri = new IrInterface(b, isaStruct(itc->llvmVtblType->get())); irstruct->interfaces.insert(std::make_pair(id, iri)); } @@ -140,14 +133,14 @@ VarDeclaration* fieldinit = NULL; size_t fieldpad = 0; int idx = 0; - for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { + for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { // first iteration if (lastoffset == (unsigned)-1) { lastoffset = i->first; fieldtype = i->second.type; fieldinit = i->second.var; prevsize = getABITypeSize(fieldtype); - i->second.var->llvmFieldIndex = idx; + i->second.var->irField->index = idx; } // colliding offset? else if (lastoffset == i->first) { @@ -157,15 +150,15 @@ prevsize = s; } cd->llvmHasUnions = true; - i->second.var->llvmFieldIndex = idx; + i->second.var->irField->index = idx; } // intersecting offset? else if (i->first < (lastoffset + prevsize)) { size_t s = getABITypeSize(i->second.type); assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size cd->llvmHasUnions = true; - i->second.var->llvmFieldIndex = idx; - i->second.var->llvmFieldIndexOffset = (i->first - lastoffset) / s; + i->second.var->irField->index = idx; + i->second.var->irField->indexOffset = (i->first - lastoffset) / s; } // fresh offset else { @@ -185,7 +178,7 @@ fieldtype = i->second.type; fieldinit = i->second.var; prevsize = getABITypeSize(fieldtype); - i->second.var->llvmFieldIndex = idx; + i->second.var->irField->index = idx; fieldpad = 0; } } @@ -199,7 +192,7 @@ /* // add field types - for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { + for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { fieldtypes.push_back(i->second.type); } */ @@ -307,8 +300,8 @@ assert(cd->type->ty == Tclass); TypeClass* ts = (TypeClass*)cd->type; - assert(cd->llvmIRStruct); - IRStruct* irstruct = cd->llvmIRStruct; + assert(cd->llvmIrStruct); + IrStruct* irstruct = cd->llvmIrStruct; gIR->structs.push_back(irstruct); gIR->classes.push_back(cd); @@ -318,56 +311,45 @@ needs_definition = true; } - // interface vtables are emitted by the class implementing them - // also, interfaces have no static initializer - // also, abstract classes have no vtable + llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage; + + // interfaces have no static initializer + // same goes for abstract classes if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) { // vtable std::string varname("_D"); varname.append(cd->mangle()); varname.append("6__vtblZ"); - llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage; - const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get()); cd->llvmVtbl = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module); + } - // build interface info type - std::vector types; - // ClassInfo classinfo - ClassDeclaration* cd2 = ClassDeclaration::classinfo; - DtoResolveClass(cd2); - types.push_back(getPtrToType(cd2->type->llvmType->get())); - // void*[] vtbl - std::vector vtbltypes; - vtbltypes.push_back(DtoSize_t()); - const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); - vtbltypes.push_back(byteptrptrty); - types.push_back(llvm::StructType::get(vtbltypes)); - // int offset - types.push_back(llvm::Type::Int32Ty); - // create type - const llvm::StructType* infoTy = llvm::StructType::get(types); + // get interface info type + const llvm::StructType* infoTy = DtoInterfaceInfoType(); - // interface info array - if (cd->vtblInterfaces->dim > 0) { - // symbol name - std::string nam = "_D"; - nam.append(cd->mangle()); - nam.append("16__interfaceInfosZ"); - // resolve array type - const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->vtblInterfaces->dim); - // declare global - irstruct->interfaceInfosTy = arrTy; - irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, _linkage, NULL, nam, gIR->module); - } + // interface info array + if (cd->vtblInterfaces->dim > 0) { + // symbol name + std::string nam = "_D"; + nam.append(cd->mangle()); + nam.append("16__interfaceInfosZ"); + // resolve array type + const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->vtblInterfaces->dim); + // declare global + irstruct->interfaceInfosTy = arrTy; + irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, _linkage, NULL, nam, gIR->module); + } + // interfaces have no static initializer + // same goes for abstract classes + if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) { // interface vtables unsigned idx = 0; - for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) + for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) { ClassDeclaration* id = i->first; - IRInterface* iri = i->second; + IrInterface* iri = i->second; std::string nam("_D"); nam.append(cd->mangle()); @@ -377,7 +359,6 @@ assert(iri->vtblTy); iri->vtbl = new llvm::GlobalVariable(iri->vtblTy, true, _linkage, 0, nam, gIR->module); - iri->infoTy = infoTy; llvm::Constant* idxs[2] = {DtoConstUint(0), DtoConstUint(idx)}; iri->info = llvm::ConstantExpr::getGetElementPtr(irstruct->interfaceInfos, idxs, 2); idx++; @@ -420,7 +401,7 @@ Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); LOG_SCOPE; - IRStruct* irstruct = cd->llvmIRStruct; + IrStruct* irstruct = cd->llvmIrStruct; gIR->structs.push_back(irstruct); gIR->classes.push_back(cd); @@ -431,12 +412,12 @@ const llvm::StructType* vtbltype = isaStruct(ts->llvmVtblType->get()); // make sure each offset knows its default initializer - for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) + for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { - IRStruct::Offset* so = &i->second; + IrStruct::Offset* so = &i->second; llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init); so->init = finit; - so->var->llvmConstInit = finit; + so->var->irField->constInit = finit; } // fill out fieldtypes/inits @@ -465,9 +446,11 @@ size_t dataoffset = 2; // next comes interface vtables - for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) + const llvm::StructType* infoTy = DtoInterfaceInfoType(); + for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) { - IRInterface* iri = i->second; + IrInterface* iri = i->second; + iri->infoTy = infoTy; if (cd->isAbstract()) { fieldinits.push_back(llvm::Constant::getNullValue(iri->vtblTy)); @@ -482,7 +465,7 @@ /* // rest - for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { + for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { Logger::println("adding fieldinit for: %s", i->second.var->toChars()); fieldinits.push_back(i->second.init); } @@ -493,7 +476,7 @@ for (size_t i=0; idefaultFields[i] != NULL) { - c = irstruct->defaultFields[i]->llvmConstInit; + c = irstruct->defaultFields[i]->irField->constInit; assert(c); } else { @@ -535,8 +518,8 @@ if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { DtoForceDeclareDsymbol(fd); - assert(fd->llvmValue); - llvm::Constant* c = llvm::cast(fd->llvmValue); + assert(fd->irFunc->func); + llvm::Constant* c = llvm::cast(fd->irFunc->func); // cast if necessary (overridden method) if (c->getType() != vtbltype->getElementType(k)) c = llvm::ConstantExpr::getBitCast(c, vtbltype->getElementType(k)); @@ -568,30 +551,34 @@ // create interface vtable const initalizers int idx = 2; int idxScale = PTRSIZE; - for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) + for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) { ClassDeclaration* id = i->first; assert(id->type->ty == Tclass); TypeClass* its = (TypeClass*)id->type; - IRInterface* iri = i->second; + IrInterface* iri = i->second; BaseClass* b = iri->base; const llvm::StructType* ivtbl_ty = isaStruct(its->llvmVtblType->get()); // generate interface info initializer std::vector infoInits; + // classinfo assert(id->llvmClass); llvm::Constant* c = id->llvmClass; infoInits.push_back(c); + // vtbl const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty); c = DtoConstSlice(DtoConstSize_t(b->vtbl.dim), c); infoInits.push_back(c); + // offset infoInits.push_back(DtoConstInt(idx*idxScale)); + // create interface info initializer constant iri->infoInit = llvm::cast(llvm::ConstantStruct::get(iri->infoTy, infoInits)); @@ -608,8 +595,9 @@ FuncDeclaration* fd = dsym->isFuncDeclaration(); assert(fd); DtoForceDeclareDsymbol(fd); - assert(fd->llvmValue); - llvm::Constant* c = llvm::cast(fd->llvmValue); + assert(fd->irFunc->func); + llvm::Constant* c = llvm::cast(fd->irFunc->func); + // we have to bitcast, as the type created in ResolveClass expects a different this type c = llvm::ConstantExpr::getBitCast(c, iri->vtblTy->getContainedType(k)); iinits.push_back(c); @@ -629,7 +617,39 @@ idx++; } - } // !abstract + } + // we always generate interfaceinfos as best we can + else + { + for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) + { + ClassDeclaration* id = i->first; + assert(id->type->ty == Tclass); + TypeClass* its = (TypeClass*)id->type; + + IrInterface* iri = i->second; + BaseClass* b = iri->base; + + // generate interface info initializer + std::vector infoInits; + + // classinfo + assert(id->llvmClass); + llvm::Constant* c = id->llvmClass; + infoInits.push_back(c); + + // vtbl + const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); + c = DtoConstSlice(DtoConstSize_t(0), getNullPtr(byteptrptrty)); + infoInits.push_back(c); + + // offset + infoInits.push_back(DtoConstInt(0)); + + // create interface info initializer constant + iri->infoInit = llvm::cast(llvm::ConstantStruct::get(iri->infoTy, infoInits)); + } + } gIR->classes.pop_back(); gIR->structs.pop_back(); @@ -658,11 +678,11 @@ cd->llvmVtbl->setInitializer(cd->llvmConstVtbl); // initialize interface vtables - IRStruct* irstruct = cd->llvmIRStruct; + IrStruct* irstruct = cd->llvmIrStruct; std::vector infoInits; - for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) + for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) { - IRInterface* iri = i->second; + IrInterface* iri = i->second; iri->vtbl->setInitializer(iri->vtblInit); infoInits.push_back(iri->infoInit); } @@ -711,7 +731,7 @@ LOG_SCOPE; DValue* thisval = newexp->thisexp->toElem(gIR); size_t idx = 2; - idx += tc->sym->llvmIRStruct->interfaces.size(); + idx += tc->sym->llvmIrStruct->interfaces.size(); llvm::Value* dst = thisval->getRVal(); llvm::Value* src = DtoGEPi(mem,0,idx,"tmp"); Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n'; @@ -723,10 +743,10 @@ Logger::println("Resolving nested context"); LOG_SCOPE; size_t idx = 2; - idx += tc->sym->llvmIRStruct->interfaces.size(); - llvm::Value* nest = gIR->func()->decl->llvmNested; + idx += tc->sym->llvmIrStruct->interfaces.size(); + llvm::Value* nest = gIR->func()->decl->irFunc->nestedVar; if (!nest) - nest = gIR->func()->decl->llvmThisVar; + nest = gIR->func()->decl->irFunc->thisVar; assert(nest); llvm::Value* gep = DtoGEPi(mem,0,idx,"tmp"); nest = DtoBitCast(nest, gep->getType()->getContainedType(0)); @@ -792,7 +812,7 @@ assert(ctor); DtoForceDeclareDsymbol(ctor); - llvm::Function* fn = llvm::cast(ctor->llvmValue); + llvm::Function* fn = ctor->irFunc->func; TypeFunction* tf = (TypeFunction*)DtoDType(ctor->type); std::vector ctorargs; @@ -822,8 +842,8 @@ for (size_t i=0; idim; i++) { FuncDeclaration* fd = (FuncDeclaration*)arr->data[i]; - assert(fd->llvmValue); - new llvm::CallInst(fd->llvmValue, instance, "", gIR->scopebb()); + assert(fd->irFunc->func); + new llvm::CallInst(fd->irFunc->func, instance, "", gIR->scopebb()); } } @@ -1031,37 +1051,37 @@ unsigned dataoffset = 2 + cd->vtblInterfaces->dim; - IRStruct* irstruct = cd->llvmIRStruct; - for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { + IrStruct* irstruct = cd->llvmIrStruct; + for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { //for (unsigned i=0; ifields.dim; ++i) { //VarDeclaration* vd = (VarDeclaration*)cd->fields.data[i]; VarDeclaration* vd = i->second.var; assert(vd); Type* vdtype = DtoDType(vd->type); Logger::println("found %u type %s", vd->offset, vdtype->toChars()); - assert(vd->llvmFieldIndex >= 0); + assert(vd->irField->index >= 0); if (os == vd->offset && vdtype == t) { - idxs.push_back(vd->llvmFieldIndex + dataoffset); + idxs.push_back(vd->irField->index + dataoffset); Logger::cout() << "indexing: " << *ptr << '\n'; ptr = DtoGEP(ptr, idxs, "tmp"); if (ptr->getType() != llt) ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); Logger::cout() << "indexing: " << *ptr << '\n'; - if (vd->llvmFieldIndexOffset) - ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb()); + if (vd->irField->indexOffset) + ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb()); Logger::cout() << "indexing: " << *ptr << '\n'; return ptr; } else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) { TypeStruct* ts = (TypeStruct*)vdtype; StructDeclaration* ssd = ts->sym; - idxs.push_back(vd->llvmFieldIndex + dataoffset); - if (vd->llvmFieldIndexOffset) { + idxs.push_back(vd->irField->index + dataoffset); + if (vd->irField->indexOffset) { Logger::println("has union field offset"); ptr = DtoGEP(ptr, idxs, "tmp"); if (ptr->getType() != llt) ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); - ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb()); + ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb()); std::vector tmp; return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); } @@ -1153,7 +1173,7 @@ vd->type->getTypeInfo(NULL); assert(vd->type->vtinfo); DtoForceDeclareDsymbol(vd->type->vtinfo); - llvm::Constant* c = isaConstant(vd->type->vtinfo->llvmValue); + llvm::Constant* c = isaConstant(vd->type->vtinfo->getIrValue()); const llvm::Type* tiTy = getPtrToType(Type::typeinfo->type->llvmType->get()); //Logger::cout() << "tiTy = " << *tiTy << '\n'; @@ -1230,8 +1250,8 @@ else if (cd->dtors.dim == 1) { DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0]; DtoForceDeclareDsymbol(d); - assert(d->llvmValue); - return llvm::ConstantExpr::getBitCast(isaConstant(d->llvmValue), getPtrToType(llvm::Type::Int8Ty)); + assert(d->irFunc->func); + return llvm::ConstantExpr::getBitCast(isaConstant(d->irFunc->func), getPtrToType(llvm::Type::Int8Ty)); } std::string gname("_D"); @@ -1249,8 +1269,8 @@ { DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[i]; DtoForceDeclareDsymbol(d); - assert(d->llvmValue); - builder.CreateCall(d->llvmValue, thisptr); + assert(d->irFunc->func); + builder.CreateCall(d->irFunc->func, thisptr); } builder.CreateRetVoid(); @@ -1380,7 +1400,7 @@ inits.push_back(c); // interfaces array - IRStruct* irstruct = cd->llvmIRStruct; + IrStruct* irstruct = cd->llvmIrStruct; if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos || cd->isAbstract()) { c = cinfo->llvmConstInit->getOperand(5); } @@ -1446,7 +1466,7 @@ // default constructor if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) { DtoForceDeclareDsymbol(cd->defaultCtor); - c = isaConstant(cd->defaultCtor->llvmValue); + c = isaConstant(cd->defaultCtor->irFunc->func); const llvm::Type* toTy = cinfo->llvmConstInit->getOperand(12)->getType(); c = llvm::ConstantExpr::getBitCast(c, toTy); } diff -r 176bd52b3cf5 -r 0e28624814e8 gen/functions.cpp --- a/gen/functions.cpp Mon Jan 14 23:09:55 2008 +0100 +++ b/gen/functions.cpp Thu Jan 17 03:15:12 2008 +0100 @@ -232,7 +232,7 @@ llvm::Function* func = llvm::dyn_cast(fn); assert(func); assert(func->isIntrinsic()); - fdecl->llvmValue = func; + fdecl->irFunc->func = func; return func; } @@ -257,7 +257,7 @@ Logger::println("DtoResolveFunction(%s): %s", fdecl->toPrettyChars(), fdecl->loc.toChars()); LOG_SCOPE; - if (fdecl->llvmRunTimeHack) { + if (fdecl->runTimeHack) { gIR->declareList.push_back(fdecl); TypeFunction* tf = (TypeFunction*)fdecl->type; tf->llvmRetInPtr = DtoIsPassedByRef(tf->next); @@ -309,10 +309,12 @@ fatal(); } - if (fdecl->llvmRunTimeHack) { + if (fdecl->runTimeHack) { Logger::println("runtime hack func chars: %s", fdecl->toChars()); - if (!fdecl->llvmValue) - fdecl->llvmValue = LLVM_D_GetRuntimeFunction(gIR->module, fdecl->toChars()); + if (!fdecl->irFunc) { + fdecl->irFunc = new IrFunction(fdecl); + fdecl->irFunc->func = LLVM_D_GetRuntimeFunction(gIR->module, fdecl->toChars()); + } return; } @@ -323,8 +325,8 @@ else if (fdecl->llvmInternal == LLVMva_start) declareOnly = true; - if (!fdecl->llvmIRFunc) { - fdecl->llvmIRFunc = new IRFunction(fdecl); + if (!fdecl->irFunc) { + fdecl->irFunc = new IrFunction(fdecl); } // mangled name @@ -351,7 +353,7 @@ assert(func->getFunctionType() == functype); // add func to IRFunc - fdecl->llvmIRFunc->func = func; + fdecl->irFunc->func = func; // calling convention if (!vafunc && fdecl->llvmInternal != LLVMintrinsic) @@ -372,7 +374,7 @@ func->setCallingConv(llvm::CallingConv::C); } - fdecl->llvmValue = func; + fdecl->irFunc->func = func; assert(llvm::isa(f->llvmType->get())); // main @@ -394,22 +396,22 @@ int k = 0; if (f->llvmRetInPtr) { iarg->setName("retval"); - fdecl->llvmRetArg = iarg; + fdecl->irFunc->retArg = iarg; ++iarg; } if (f->llvmUsesThis) { iarg->setName("this"); - fdecl->llvmThisVar = iarg; - assert(fdecl->llvmThisVar); + fdecl->irFunc->thisVar = iarg; + assert(fdecl->irFunc->thisVar); ++iarg; } if (f->linkage == LINKd && f->varargs == 1) { iarg->setName("_arguments"); - fdecl->llvmArguments = iarg; + fdecl->irFunc->_arguments = iarg; ++iarg; iarg->setName("_argptr"); - fdecl->llvmArgPtr = iarg; + fdecl->irFunc->_argptr = iarg; ++iarg; } @@ -420,7 +422,9 @@ //Logger::println("identifier: '%s' %p\n", arg->ident->toChars(), arg->ident); if (arg && arg->ident != 0) { if (arg->vardecl) { - arg->vardecl->llvmValue = iarg; + assert(!arg->vardecl->irLocal); + arg->vardecl->irLocal = new IrLocal(arg->vardecl); + arg->vardecl->irLocal->value = iarg; } iarg->setName(arg->ident->toChars()); } @@ -458,14 +462,14 @@ if (!mo->llvmCompileUnit) { mo->llvmCompileUnit = DtoDwarfCompileUnit(mo,false); } - fd->llvmDwarfSubProgram = DtoDwarfSubProgram(fd, mo->llvmCompileUnit); + fd->irFunc->dwarfSubProg = DtoDwarfSubProgram(fd, mo->llvmCompileUnit); } Type* t = DtoDType(fd->type); TypeFunction* f = (TypeFunction*)t; assert(f->llvmType); - llvm::Function* func = fd->llvmIRFunc->func; + llvm::Function* func = fd->irFunc->func; const llvm::FunctionType* functype = func->getFunctionType(); // only members of the current module or template instances maybe be defined @@ -477,8 +481,8 @@ if (fd->fbody != 0) { Logger::println("Doing function body for: %s", fd->toChars()); - assert(fd->llvmIRFunc); - gIR->functions.push_back(fd->llvmIRFunc); + assert(fd->irFunc); + gIR->functions.push_back(fd->irFunc); if (fd->isMain()) gIR->emitMain = true; @@ -496,7 +500,8 @@ // need result variable? (not nested) if (fd->vresult && !fd->vresult->nestedref) { Logger::println("non-nested vresult value"); - fd->vresult->llvmValue = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint); + fd->vresult->irLocal = new IrLocal(fd->vresult); + fd->vresult->irLocal->value = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint); } // give arguments storage @@ -505,16 +510,16 @@ Argument* arg = Argument::getNth(f->parameters, i); if (arg && arg->vardecl) { VarDeclaration* vd = arg->vardecl; - if (!vd->llvmNeedsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type)) + if (!vd->needsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type)) continue; - llvm::Value* a = vd->llvmValue; + llvm::Value* a = vd->irLocal->value; assert(a); std::string s(a->getName()); Logger::println("giving argument '%s' storage", s.c_str()); s.append("_storage"); llvm::Value* v = new llvm::AllocaInst(a->getType(),s,allocaPoint); gIR->ir->CreateStore(a,v); - vd->llvmValue = v; + vd->irLocal->value = v; } else { Logger::attention(fd->loc, "some unknown argument: %s", arg ? arg->toChars() : 0); @@ -527,29 +532,32 @@ llvm::Value* parentNested = NULL; if (FuncDeclaration* fd2 = fd->toParent2()->isFuncDeclaration()) { if (!fd->isStatic()) // huh? - parentNested = fd2->llvmNested; + parentNested = fd2->irFunc->nestedVar; } // need result variable? (nested) if (fd->vresult && fd->vresult->nestedref) { Logger::println("nested vresult value: %s", fd->vresult->toChars()); - fd->llvmNestedVars.insert(fd->vresult); + fd->nestedVars.insert(fd->vresult); } // construct nested variables struct - if (!fd->llvmNestedVars.empty() || parentNested) { + if (!fd->nestedVars.empty() || parentNested) { std::vector nestTypes; int j = 0; if (parentNested) { nestTypes.push_back(parentNested->getType()); j++; } - for (std::set::iterator i=fd->llvmNestedVars.begin(); i!=fd->llvmNestedVars.end(); ++i) { + for (std::set::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) { VarDeclaration* vd = *i; - vd->llvmNestedIndex = j++; + if (!vd->irLocal) + vd->irLocal = new IrLocal(vd); + vd->irLocal->nestedIndex = j++; if (vd->isParameter()) { - assert(vd->llvmValue); - nestTypes.push_back(vd->llvmValue->getType()); + + assert(vd->irLocal->value); + nestTypes.push_back(vd->irLocal->value->getType()); } else { nestTypes.push_back(DtoType(vd->type)); @@ -557,17 +565,18 @@ } const llvm::StructType* nestSType = llvm::StructType::get(nestTypes); Logger::cout() << "nested var struct has type:" << *nestSType << '\n'; - fd->llvmNested = new llvm::AllocaInst(nestSType,"nestedvars",allocaPoint); + fd->irFunc->nestedVar = new llvm::AllocaInst(nestSType,"nestedvars",allocaPoint); if (parentNested) { - assert(fd->llvmThisVar); - llvm::Value* ptr = gIR->ir->CreateBitCast(fd->llvmThisVar, parentNested->getType(), "tmp"); - gIR->ir->CreateStore(ptr, DtoGEPi(fd->llvmNested, 0,0, "tmp")); + assert(fd->irFunc->thisVar); + llvm::Value* ptr = gIR->ir->CreateBitCast(fd->irFunc->thisVar, parentNested->getType(), "tmp"); + gIR->ir->CreateStore(ptr, DtoGEPi(fd->irFunc->nestedVar, 0,0, "tmp")); } - for (std::set::iterator i=fd->llvmNestedVars.begin(); i!=fd->llvmNestedVars.end(); ++i) { + for (std::set::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) { VarDeclaration* vd = *i; if (vd->isParameter()) { - gIR->ir->CreateStore(vd->llvmValue, DtoGEPi(fd->llvmNested, 0, vd->llvmNestedIndex, "tmp")); - vd->llvmValue = fd->llvmNested; + assert(vd->irLocal); + gIR->ir->CreateStore(vd->irLocal->value, DtoGEPi(fd->irFunc->nestedVar, 0, vd->irLocal->nestedIndex, "tmp")); + vd->irLocal->value = fd->irFunc->nestedVar; } } } @@ -575,9 +584,9 @@ // copy _argptr to a memory location if (f->linkage == LINKd && f->varargs == 1) { - llvm::Value* argptrmem = new llvm::AllocaInst(fd->llvmArgPtr->getType(), "_argptrmem", gIR->topallocapoint()); - new llvm::StoreInst(fd->llvmArgPtr, argptrmem, gIR->scopebb()); - fd->llvmArgPtr = argptrmem; + llvm::Value* argptrmem = new llvm::AllocaInst(fd->irFunc->_argptr->getType(), "_argptrmem", gIR->topallocapoint()); + new llvm::StoreInst(fd->irFunc->_argptr, argptrmem, gIR->scopebb()); + fd->irFunc->_argptr = argptrmem; } // output function body diff -r 176bd52b3cf5 -r 0e28624814e8 gen/irstate.cpp --- a/gen/irstate.cpp Mon Jan 14 23:09:55 2008 +0100 +++ b/gen/irstate.cpp Thu Jan 17 03:15:12 2008 +0100 @@ -40,7 +40,7 @@ ir.state = this; } -IRFunction* IRState::func() +IrFunction* IRState::func() { assert(!functions.empty() && "Function stack is empty!"); return functions.back(); @@ -64,7 +64,7 @@ return functions.back()->allocapoint; } -IRStruct* IRState::topstruct() +IrStruct* IRState::topstruct() { assert(!structs.empty() && "Struct vector is empty!"); return structs.back(); @@ -101,32 +101,6 @@ ////////////////////////////////////////////////////////////////////////////////////////// -IRStruct::IRStruct(Type* t) - : recty((t->llvmType != NULL) ? *t->llvmType : llvm::OpaqueType::get()) -{ - type = t; - defined = false; - constinited = false; - interfaceInfosTy = NULL; - interfaceInfos = NULL; -} - -////////////////////////////////////////////////////////////////////////////////////////// - -IRFinally::IRFinally() -{ - bb = 0; - retbb = 0; -} - -IRFinally::IRFinally(llvm::BasicBlock* b, llvm::BasicBlock* rb) -{ - bb = b; - retbb = rb; -} - -////////////////////////////////////////////////////////////////////////////////////////// - LLVMBuilder* IRBuilderHelper::operator->() { LLVMBuilder& b = state->scope().builder; @@ -136,20 +110,6 @@ ////////////////////////////////////////////////////////////////////////////////////////// -IRFunction::IRFunction(FuncDeclaration* fd) -{ - decl = fd; - Type* t = DtoDType(fd->type); - assert(t->ty == Tfunction); - type = (TypeFunction*)t; - func = NULL; - allocapoint = NULL; - finallyretval = NULL; - defined = false; -} - -////////////////////////////////////////////////////////////////////////////////////////// - IRExp::IRExp() { e1 = e2 = NULL; @@ -162,11 +122,3 @@ e2 = r; v = val; } - -////////////////////////////////////////////////////////////////////////////////////////// - -IRGlobal::IRGlobal(VarDeclaration* v) : - type(llvm::OpaqueType::get()) -{ - var = v; -} diff -r 176bd52b3cf5 -r 0e28624814e8 gen/irstate.h --- a/gen/irstate.h Mon Jan 14 23:09:55 2008 +0100 +++ b/gen/irstate.h Thu Jan 17 03:15:12 2008 +0100 @@ -1,15 +1,16 @@ #ifndef LLVMDC_GEN_IRSTATE_H #define LLVMDC_GEN_IRSTATE_H -#include #include -#include -#include #include #include "root.h" #include "aggregate.h" +#include "ir/irfunction.h" +#include "ir/irstruct.h" +#include "ir/irvar.h" + // global ir state for current module struct IRState; extern IRState* gIR; @@ -23,13 +24,6 @@ struct TypeStruct; struct BaseClass; -/* -struct LLVMValue -{ - std::vector vals; -}; -*/ - // represents a scope struct IRScope { @@ -41,94 +35,6 @@ IRScope(llvm::BasicBlock* b, llvm::BasicBlock* e); }; -struct IRInterface : Object -{ - BaseClass* base; - ClassDeclaration* decl; - - const llvm::StructType* vtblTy; - llvm::ConstantStruct* vtblInit; - llvm::GlobalVariable* vtbl; - - const llvm::StructType* infoTy; - llvm::ConstantStruct* infoInit; - llvm::Constant* info; - - IRInterface(BaseClass* b, const llvm::StructType* vt) - { - base = b; - decl = b->base; - vtblTy = vt; - vtblInit = NULL; - vtbl = NULL; - infoTy = NULL; - infoInit = NULL; - info = NULL; - } -}; - -// represents a struct or class -struct IRStruct : Object -{ - struct Offset - { - VarDeclaration* var; - const llvm::Type* type; - llvm::Constant* init; - - Offset(VarDeclaration* v, const llvm::Type* ty) - : var(v), type(ty), init(NULL) {} - }; - - typedef std::multimap OffsetMap; - typedef std::vector VarDeclVector; - typedef std::map InterfaceMap; - typedef InterfaceMap::iterator InterfaceIter; - -public: - IRStruct(Type*); - - Type* type; - llvm::PATypeHolder recty; - OffsetMap offsets; - VarDeclVector defaultFields; - - InterfaceMap interfaces; - const llvm::ArrayType* interfaceInfosTy; - llvm::GlobalVariable* interfaceInfos; - - bool defined; - bool constinited; -}; - -// represents a finally block -struct IRFinally -{ - llvm::BasicBlock* bb; - llvm::BasicBlock* retbb; - - IRFinally(); - IRFinally(llvm::BasicBlock* b, llvm::BasicBlock* rb); -}; - -// represents a function -struct IRFunction : Object -{ - llvm::Function* func; - llvm::Instruction* allocapoint; - FuncDeclaration* decl; - TypeFunction* type; - - // finally blocks - typedef std::vector FinallyVec; - FinallyVec finallys; - llvm::Value* finallyretval; - - bool defined; - - IRFunction(FuncDeclaration*); -}; - struct IRBuilderHelper { IRState* state; @@ -144,15 +50,6 @@ IRExp(Expression* l, Expression* r, DValue* val); }; -// represents a global variable -struct IRGlobal : Object -{ - VarDeclaration* var; - llvm::PATypeHolder type; - - IRGlobal(VarDeclaration* v); -}; - // represents the module struct IRState { @@ -163,18 +60,18 @@ llvm::Module* module; // functions - typedef std::vector FunctionVector; + typedef std::vector FunctionVector; FunctionVector functions; - IRFunction* func(); + IrFunction* func(); llvm::Function* topfunc(); TypeFunction* topfunctype(); llvm::Instruction* topallocapoint(); // structs - typedef std::vector StructVector; + typedef std::vector StructVector; StructVector structs; - IRStruct* topstruct(); + IrStruct* topstruct(); // classes TODO move into IRClass typedef std::vector ClassDeclVec; diff -r 176bd52b3cf5 -r 0e28624814e8 gen/statements.cpp --- a/gen/statements.cpp Mon Jan 14 23:09:55 2008 +0100 +++ b/gen/statements.cpp Thu Jan 17 03:15:12 2008 +0100 @@ -25,6 +25,8 @@ #include "gen/todebug.h" #include "gen/dvalue.h" +#include "ir/irfunction.h" + ////////////////////////////////////////////////////////////////////////////// void CompoundStatement::toIR(IRState* p) @@ -57,13 +59,13 @@ if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) { assert(DtoIsPassedByRef(exptype)); - IRFunction* f = p->func(); + IrFunction* f = p->func(); assert(f->type->llvmRetInPtr); - assert(f->decl->llvmRetArg); + assert(f->decl->irFunc->retArg); if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum); - DValue* rvar = new DVarValue(f->type->next, f->decl->llvmRetArg, true); + DValue* rvar = new DVarValue(f->type->next, f->decl->irFunc->retArg, true); p->exps.push_back(IRExp(NULL,exp,rvar)); DValue* e = exp->toElem(p); @@ -72,7 +74,7 @@ if (!e->inPlace()) DtoAssign(rvar, e); - IRFunction::FinallyVec& fin = f->finallys; + IrFunction::FinallyVec& fin = f->finallys; if (fin.empty()) { if (global.params.symdebug) DtoDwarfFuncEnd(f->decl); new llvm::ReturnInst(p->scopebb()); @@ -88,7 +90,7 @@ delete e; Logger::cout() << "return value is '" <<*v << "'\n"; - IRFunction::FinallyVec& fin = p->func()->finallys; + IrFunction::FinallyVec& fin = p->func()->finallys; if (fin.empty()) { if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); new llvm::ReturnInst(v, p->scopebb()); @@ -105,7 +107,7 @@ else { if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) { - IRFunction::FinallyVec& fin = p->func()->finallys; + IrFunction::FinallyVec& fin = p->func()->finallys; if (fin.empty()) { if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); new llvm::ReturnInst(p->scopebb()); @@ -425,8 +427,8 @@ // do the try block p->scope() = IRScope(trybb,finallybb); - gIR->func()->finallys.push_back(IRFinally(finallybb,finallyretbb)); - IRFinally& fin = p->func()->finallys.back(); + gIR->func()->finallys.push_back(IrFinally(finallybb,finallyretbb)); + IrFinally& fin = p->func()->finallys.back(); assert(body); body->toIR(p); @@ -453,7 +455,7 @@ // terminate finally (return path) size_t nfin = p->func()->finallys.size(); if (nfin > 1) { - IRFinally& ofin = p->func()->finallys[nfin-2]; + IrFinally& ofin = p->func()->finallys[nfin-2]; p->ir->CreateBr(ofin.retbb); } // no outer @@ -793,7 +795,13 @@ // key const llvm::Type* keytype = key ? DtoType(key->type) : DtoSize_t(); llvm::Value* keyvar = new llvm::AllocaInst(keytype, "foreachkey", p->topallocapoint()); - if (key) key->llvmValue = keyvar; + if (key) + { + //key->llvmValue = keyvar; + assert(!key->irLocal); + key->irLocal = new IrLocal(key); + key->irLocal->value = keyvar; + } llvm::Value* zerokey = llvm::ConstantInt::get(keytype,0,false); // value @@ -801,6 +809,8 @@ llvm::Value* valvar = NULL; if (!value->isRef() && !value->isOut()) valvar = new llvm::AllocaInst(valtype, "foreachval", p->topallocapoint()); + assert(!value->irLocal); + value->irLocal = new IrLocal(value); // what to iterate DValue* aggrval = aggr->toElem(p); @@ -896,15 +906,15 @@ llvm::Constant* zero = llvm::ConstantInt::get(keytype,0,false); llvm::Value* loadedKey = p->ir->CreateLoad(keyvar,"tmp"); if (aggrtype->ty == Tsarray) - value->llvmValue = DtoGEP(val,zero,loadedKey,"tmp"); + value->irLocal->value = DtoGEP(val,zero,loadedKey,"tmp"); else if (aggrtype->ty == Tarray) - value->llvmValue = new llvm::GetElementPtrInst(val,loadedKey,"tmp",p->scopebb()); + value->irLocal->value = new llvm::GetElementPtrInst(val,loadedKey,"tmp",p->scopebb()); if (!value->isRef() && !value->isOut()) { DValue* dst = new DVarValue(value->type, valvar, true); - DValue* src = new DVarValue(value->type, value->llvmValue, true); + DValue* src = new DVarValue(value->type, value->irLocal->value, true); DtoAssign(dst, src); - value->llvmValue = valvar; + value->irLocal->value = valvar; } // emit body @@ -982,7 +992,7 @@ assert(body); DValue* e = exp->toElem(p); - wthis->llvmValue = e->getRVal(); + wthis->irLocal->value = e->getRVal(); delete e; body->toIR(p); diff -r 176bd52b3cf5 -r 0e28624814e8 gen/structs.cpp --- a/gen/structs.cpp Mon Jan 14 23:09:55 2008 +0100 +++ b/gen/structs.cpp Thu Jan 17 03:15:12 2008 +0100 @@ -13,6 +13,8 @@ #include "gen/logger.h" #include "gen/structs.h" +#include "ir/irstruct.h" + ////////////////////////////////////////////////////////////////////////////////////////// const llvm::Type* DtoStructType(Type* t) @@ -93,7 +95,7 @@ VarDeclaration* vd = (VarDeclaration*)si->vars.data[i]; assert(vd); llvm::Constant* v = DtoConstInitializer(vd->type, ini); - inits.push_back(DUnionIdx(vd->llvmFieldIndex, vd->llvmFieldIndexOffset, v)); + inits.push_back(DUnionIdx(vd->irField->index, vd->irField->indexOffset, v)); } DtoConstInitStruct((StructDeclaration*)si->ad); @@ -121,26 +123,26 @@ VarDeclaration* vd = (VarDeclaration*)sd->fields.data[i]; Type* vdtype = DtoDType(vd->type); Logger::println("found %u type %s", vd->offset, vdtype->toChars()); - assert(vd->llvmFieldIndex >= 0); + assert(vd->irField->index >= 0); if (os == vd->offset && vdtype == t) { - idxs.push_back(vd->llvmFieldIndex); + idxs.push_back(vd->irField->index); ptr = DtoGEP(ptr, idxs, "tmp"); if (ptr->getType() != llt) ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); - if (vd->llvmFieldIndexOffset) - ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb()); + if (vd->irField->indexOffset) + ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb()); return ptr; } else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) { TypeStruct* ts = (TypeStruct*)vdtype; StructDeclaration* ssd = ts->sym; - idxs.push_back(vd->llvmFieldIndex); - if (vd->llvmFieldIndexOffset) { + idxs.push_back(vd->irField->index); + if (vd->irField->indexOffset) { Logger::println("has union field offset"); ptr = DtoGEP(ptr, idxs, "tmp"); if (ptr->getType() != llt) ptr = DtoBitCast(ptr, llt); - ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb()); + ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb()); std::vector tmp; return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); } @@ -176,8 +178,8 @@ TypeStruct* ts = (TypeStruct*)DtoDType(sd->type); - IRStruct* irstruct = new IRStruct(ts); - sd->llvmIRStruct = irstruct; + IrStruct* irstruct = new IrStruct(ts); + sd->llvmIrStruct = irstruct; gIR->structs.push_back(irstruct); // fields @@ -233,7 +235,7 @@ VarDeclaration* fieldinit = NULL; size_t fieldpad = 0; int idx = 0; - for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { + for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { // first iteration if (lastoffset == (unsigned)-1) { lastoffset = i->first; @@ -241,7 +243,7 @@ fieldtype = i->second.type; fieldinit = i->second.var; prevsize = getABITypeSize(fieldtype); - i->second.var->llvmFieldIndex = idx; + i->second.var->irField->index = idx; } // colliding offset? else if (lastoffset == i->first) { @@ -251,15 +253,15 @@ prevsize = s; } sd->llvmHasUnions = true; - i->second.var->llvmFieldIndex = idx; + i->second.var->irField->index = idx; } // intersecting offset? else if (i->first < (lastoffset + prevsize)) { size_t s = getABITypeSize(i->second.type); assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size sd->llvmHasUnions = true; - i->second.var->llvmFieldIndex = idx; - i->second.var->llvmFieldIndexOffset = (i->first - lastoffset) / s; + i->second.var->irField->index = idx; + i->second.var->irField->indexOffset = (i->first - lastoffset) / s; } // fresh offset else { @@ -279,7 +281,7 @@ fieldtype = i->second.type; fieldinit = i->second.var; prevsize = getABITypeSize(fieldtype); - i->second.var->llvmFieldIndex = idx; + i->second.var->irField->index = idx; fieldpad = 0; } } @@ -349,16 +351,16 @@ Logger::println("DtoConstInitStruct(%s): %s", sd->toChars(), sd->loc.toChars()); LOG_SCOPE; - IRStruct* irstruct = sd->llvmIRStruct; + IrStruct* irstruct = sd->llvmIrStruct; gIR->structs.push_back(irstruct); // make sure each offset knows its default initializer - for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) + for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { - IRStruct::Offset* so = &i->second; + IrStruct::Offset* so = &i->second; llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init); so->init = finit; - so->var->llvmConstInit = finit; + so->var->irField->constInit = finit; } const llvm::StructType* structtype = isaStruct(sd->type->llvmType->get()); @@ -369,7 +371,7 @@ for (size_t i=0; idefaultFields[i] != NULL) { - c = irstruct->defaultFields[i]->llvmConstInit; + c = irstruct->defaultFields[i]->irField->constInit; assert(c); } else { @@ -435,12 +437,12 @@ DUnion::DUnion() { DUnionField* f = NULL; - IRStruct* topstruct = gIR->topstruct(); + IrStruct* topstruct = gIR->topstruct(); bool unions = false; - for (IRStruct::OffsetMap::iterator i=topstruct->offsets.begin(); i!=topstruct->offsets.end(); ++i) + for (IrStruct::OffsetMap::iterator i=topstruct->offsets.begin(); i!=topstruct->offsets.end(); ++i) { unsigned o = i->first; - IRStruct::Offset* so = &i->second; + IrStruct::Offset* so = &i->second; const llvm::Type* ft = so->init->getType(); size_t sz = getABITypeSize(ft); if (f == NULL) { // new field diff -r 176bd52b3cf5 -r 0e28624814e8 gen/todebug.cpp --- a/gen/todebug.cpp Mon Jan 14 23:09:55 2008 +0100 +++ b/gen/todebug.cpp Thu Jan 17 03:15:12 2008 +0100 @@ -164,14 +164,14 @@ void DtoDwarfFuncStart(FuncDeclaration* fd) { - assert(fd->llvmDwarfSubProgram); - gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), dbgToArrTy(fd->llvmDwarfSubProgram)); + assert(fd->irFunc->dwarfSubProg); + gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), dbgToArrTy(fd->irFunc->dwarfSubProg)); } void DtoDwarfFuncEnd(FuncDeclaration* fd) { - assert(fd->llvmDwarfSubProgram); - gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), dbgToArrTy(fd->llvmDwarfSubProgram)); + assert(fd->irFunc->dwarfSubProg); + gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), dbgToArrTy(fd->irFunc->dwarfSubProg)); } ////////////////////////////////////////////////////////////////////////////////////////////////// diff -r 176bd52b3cf5 -r 0e28624814e8 gen/toir.cpp --- a/gen/toir.cpp Mon Jan 14 23:09:55 2008 +0100 +++ b/gen/toir.cpp Thu Jan 17 03:15:12 2008 +0100 @@ -57,12 +57,14 @@ DtoAnnotation(toChars()); Logger::println("vdtype = %s", vd->type->toChars()); + // referenced by nested delegate? if (vd->nestedref) { Logger::println("has nestedref set"); - vd->llvmValue = p->func()->decl->llvmNested; - assert(vd->llvmValue); - assert(vd->llvmNestedIndex >= 0); + assert(vd->irLocal); + vd->irLocal->value = p->func()->decl->irFunc->nestedVar; + assert(vd->irLocal->value); + assert(vd->irLocal->nestedIndex >= 0); } // normal stack variable else { @@ -70,14 +72,16 @@ const llvm::Type* lltype = DtoType(vd->type); llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint()); //allocainst->setAlignment(vd->type->alignsize()); // TODO - vd->llvmValue = allocainst; + assert(!vd->irLocal); + vd->irLocal = new IrLocal(vd); + vd->irLocal->value = allocainst; } - Logger::cout() << "llvm value for decl: " << *vd->llvmValue << '\n'; + Logger::cout() << "llvm value for decl: " << *vd->irLocal->value << '\n'; DValue* ie = DtoInitializer(vd->init); } - return new DVarValue(vd, vd->llvmValue, true); + return new DVarValue(vd, vd->getIrValue(), true); } // struct declaration else if (StructDeclaration* s = declaration->isStructDeclaration()) @@ -149,19 +153,19 @@ if (vd->ident == Id::_arguments) { Logger::println("Id::_arguments"); - if (!vd->llvmValue) - vd->llvmValue = p->func()->decl->llvmArguments; - assert(vd->llvmValue); - return new DVarValue(vd, vd->llvmValue, true); + if (!vd->getIrValue()) + vd->getIrValue() = p->func()->decl->irFunc->_arguments; + assert(vd->getIrValue()); + return new DVarValue(vd, vd->getIrValue(), true); } // _argptr else if (vd->ident == Id::_argptr) { Logger::println("Id::_argptr"); - if (!vd->llvmValue) - vd->llvmValue = p->func()->decl->llvmArgPtr; - assert(vd->llvmValue); - return new DVarValue(vd, vd->llvmValue, true); + if (!vd->getIrValue()) + vd->getIrValue() = p->func()->decl->irFunc->_argptr; + assert(vd->getIrValue()); + return new DVarValue(vd, vd->getIrValue(), true); } // _dollar else if (vd->ident == Id::dollar) @@ -176,13 +180,13 @@ { Logger::println("TypeInfoDeclaration"); DtoForceDeclareDsymbol(tid); - assert(tid->llvmValue); + assert(tid->getIrValue()); const llvm::Type* vartype = DtoType(type); llvm::Value* m; - if (tid->llvmValue->getType() != getPtrToType(vartype)) - m = p->ir->CreateBitCast(tid->llvmValue, vartype, "tmp"); + if (tid->getIrValue()->getType() != getPtrToType(vartype)) + m = p->ir->CreateBitCast(tid->getIrValue(), vartype, "tmp"); else - m = tid->llvmValue; + m = tid->getIrValue(); return new DVarValue(vd, m, true); } // classinfo @@ -201,16 +205,16 @@ // function parameter else if (vd->isParameter()) { Logger::println("function param"); - if (!vd->llvmValue) { + if (!vd->getIrValue()) { // TODO: determine this properly // this happens when the DMD frontend generates by pointer wrappers for struct opEquals(S) and opCmp(S) - vd->llvmValue = &p->func()->func->getArgumentList().back(); + vd->getIrValue() = &p->func()->func->getArgumentList().back(); } - if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa(vd->llvmValue)) { - return new DVarValue(vd, vd->llvmValue, true); + if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa(vd->getIrValue())) { + return new DVarValue(vd, vd->getIrValue(), true); } - else if (llvm::isa(vd->llvmValue)) { - return new DImValue(type, vd->llvmValue); + else if (llvm::isa(vd->getIrValue())) { + return new DImValue(type, vd->getIrValue()); } else assert(0); } @@ -220,11 +224,11 @@ vd->toObjFile(); DtoConstInitGlobal(vd); } - if (!vd->llvmValue || vd->llvmValue->getType()->isAbstract()) { + if (!vd->getIrValue() || vd->getIrValue()->getType()->isAbstract()) { Logger::println("global variable not resolved :/ %s", vd->toChars()); assert(0); } - return new DVarValue(vd, vd->llvmValue, true); + return new DVarValue(vd, vd->getIrValue(), true); } } else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) @@ -233,7 +237,7 @@ if (fdecl->llvmInternal != LLVMva_arg) {// && fdecl->llvmValue == 0) DtoForceDeclareDsymbol(fdecl); } - return new DFuncValue(fdecl, fdecl->llvmValue); + return new DFuncValue(fdecl, fdecl->irFunc->func); } else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) { @@ -274,11 +278,11 @@ else if (TypeInfoDeclaration* ti = var->isTypeInfoDeclaration()) { DtoForceDeclareDsymbol(ti); - assert(ti->llvmValue); + assert(ti->getIrValue()); const llvm::Type* vartype = DtoType(type); - llvm::Constant* m = isaConstant(ti->llvmValue); + llvm::Constant* m = isaConstant(ti->getIrValue()); assert(m); - if (ti->llvmValue->getType() != getPtrToType(vartype)) + if (ti->getIrValue()->getType() != getPtrToType(vartype)) m = llvm::ConstantExpr::getBitCast(m, vartype); return m; } @@ -974,7 +978,7 @@ llargs[j] = new llvm::AllocaInst(argiter->get()->getContainedType(0),"rettmp",p->topallocapoint()); } - if (dfn && dfn->func && dfn->func->llvmRunTimeHack) { + if (dfn && dfn->func && dfn->func->runTimeHack) { const llvm::Type* rettype = getPtrToType(DtoType(type)); if (llargs[j]->getType() != llfnty->getParamType(j)) { Logger::println("llvmRunTimeHack==true - force casting return value param"); @@ -1075,8 +1079,8 @@ Expression* argexp = (Expression*)arguments->data[i]; TypeInfoDeclaration* tidecl = argexp->type->getTypeInfoDeclaration(); DtoForceDeclareDsymbol(tidecl); - assert(tidecl->llvmValue); - vtypeinfos.push_back(tidecl->llvmValue); + assert(tidecl->getIrValue()); + vtypeinfos.push_back(tidecl->getIrValue()); llvm::Value* v = p->ir->CreateBitCast(vtypeinfos[i], typeinfotype, "tmp"); p->ir->CreateStore(v, DtoGEPi(typeinfomem,0,i,"tmp")); } @@ -1108,7 +1112,7 @@ } // this hack is necessary :/ - if (dfn && dfn->func && dfn->func->llvmRunTimeHack) { + if (dfn && dfn->func && dfn->func->runTimeHack) { if (llfnty->getParamType(j) != NULL) { if (llargs[j]->getType() != llfnty->getParamType(j)) { Logger::println("llvmRunTimeHack==true - force casting argument"); @@ -1137,7 +1141,7 @@ llvm::CallInst* call = new llvm::CallInst(funcval, llargs.begin(), llargs.end(), varname, p->scopebb()); llvm::Value* retllval = (retinptr) ? llargs[0] : call; - if (retinptr && dfn && dfn->func && dfn->func->llvmRunTimeHack) { + if (retinptr && dfn && dfn->func && dfn->func->runTimeHack) { const llvm::Type* rettype = getPtrToType(DtoType(type)); if (retllval->getType() != rettype) { Logger::println("llvmRunTimeHack==true - force casting return value"); @@ -1208,12 +1212,12 @@ vd->toObjFile(); // TODO } - assert(vd->llvmValue); + assert(vd->getIrValue()); Type* t = DtoDType(type); Type* tnext = DtoDType(t->next); Type* vdtype = DtoDType(vd->type); - llvm::Value* llvalue = vd->nestedref ? DtoNestedVariable(vd) : vd->llvmValue; + llvm::Value* llvalue = vd->nestedref ? DtoNestedVariable(vd) : vd->getIrValue(); llvm::Value* varmem = 0; if (vdtype->ty == Tstruct && !(t->ty == Tpointer && t->next == vdtype)) { @@ -1287,9 +1291,8 @@ //Logger::println("FuncDeclaration"); FuncDeclaration* fd = fv->func; assert(fd); - if (fd->llvmValue == 0) - DtoForceDeclareDsymbol(fd); - return new DFuncValue(fd, fd->llvmValue); + DtoForceDeclareDsymbol(fd); + return new DFuncValue(fd, fd->irFunc->func); } else if (DImValue* im = v->isIm()) { Logger::println("is immediate"); @@ -1394,7 +1397,7 @@ // super call if (e1->op == TOKsuper) { DtoForceDeclareDsymbol(fdecl); - funcval = fdecl->llvmValue; + funcval = fdecl->irFunc->func; assert(funcval); } // normal virtual call @@ -1415,7 +1418,7 @@ // static call else { DtoForceDeclareDsymbol(fdecl); - funcval = fdecl->llvmValue; + funcval = fdecl->irFunc->func; assert(funcval); //assert(funcval->getType() == DtoType(fdecl->type)); } @@ -1438,7 +1441,7 @@ if (VarDeclaration* vd = var->isVarDeclaration()) { llvm::Value* v; - v = p->func()->decl->llvmThisVar; + v = p->func()->decl->irFunc->thisVar; if (llvm::isa(v)) v = new llvm::LoadInst(v, "tmp", p->scopebb()); return new DThisValue(vd, v); @@ -2187,7 +2190,7 @@ if (DFuncValue* f = u->isFunc()) { //assert(f->vthis); //uval = f->vthis; - llvm::Value* nestvar = p->func()->decl->llvmNested; + llvm::Value* nestvar = p->func()->decl->irFunc->nestedVar; if (nestvar) uval = nestvar; else @@ -2213,7 +2216,7 @@ else if (func->toParent()->isInterfaceDeclaration()) assert(0 && "TODO delegate to interface method"); else - castfptr = func->llvmValue; + castfptr = func->irFunc->func; castfptr = DtoBitCast(castfptr, fptr->getType()->getContainedType(0)); DtoStore(castfptr, fptr); @@ -2440,7 +2443,7 @@ llvm::Value* context = DtoGEPi(lval,0,0,"tmp",p->scopebb()); const llvm::PointerType* pty = isaPointer(context->getType()->getContainedType(0)); - llvm::Value* llvmNested = p->func()->decl->llvmNested; + llvm::Value* llvmNested = p->func()->decl->irFunc->nestedVar; if (llvmNested == NULL) { llvm::Value* nullcontext = llvm::ConstantPointerNull::get(pty); p->ir->CreateStore(nullcontext, context); @@ -2452,8 +2455,8 @@ llvm::Value* fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb()); - assert(fd->llvmValue); - llvm::Value* castfptr = new llvm::BitCastInst(fd->llvmValue,fptr->getType()->getContainedType(0),"tmp",p->scopebb()); + assert(fd->irFunc->func); + llvm::Value* castfptr = new llvm::BitCastInst(fd->irFunc->func,fptr->getType()->getContainedType(0),"tmp",p->scopebb()); new llvm::StoreInst(castfptr, fptr, p->scopebb()); if (temp) diff -r 176bd52b3cf5 -r 0e28624814e8 gen/tollvm.cpp --- a/gen/tollvm.cpp Mon Jan 14 23:09:55 2008 +0100 +++ b/gen/tollvm.cpp Thu Jan 17 03:15:12 2008 +0100 @@ -2,7 +2,6 @@ #include "gen/llvm.h" -#include "mtype.h" #include "dsymbol.h" #include "aggregate.h" #include "declaration.h" @@ -103,7 +102,7 @@ // recursive or cyclic declaration if (!gIR->structs.empty()) { - IRStruct* found = 0; + IrStruct* found = 0; for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i) { if (t == (*i)->type) @@ -117,7 +116,7 @@ TypeStruct* ts = (TypeStruct*)t; assert(ts->sym); DtoResolveDsymbol(ts->sym); - return ts->sym->llvmIRStruct->recty.get();//t->llvmType->get(); + return ts->sym->llvmIrStruct->recty.get();//t->llvmType->get(); } case Tclass: { @@ -125,7 +124,7 @@ // recursive or cyclic declaration if (!gIR->structs.empty()) { - IRStruct* found = 0; + IrStruct* found = 0; for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i) { if (t == (*i)->type) @@ -140,7 +139,7 @@ TypeClass* tc = (TypeClass*)t; assert(tc->sym); DtoResolveDsymbol(tc->sym); - return getPtrToType(tc->sym->llvmIRStruct->recty.get());//t->llvmType->get()); + return getPtrToType(tc->sym->llvmIrStruct->recty.get());//t->llvmType->get()); } // functions @@ -687,7 +686,7 @@ assert(p->isFuncDeclaration() || p->isClassDeclaration()); if (FuncDeclaration* fd = p->isFuncDeclaration()) { - llvm::Value* v = fd->llvmNested; + llvm::Value* v = fd->irFunc->nestedVar; assert(v); return v->getType(); } @@ -717,9 +716,9 @@ if (fd->toParent2() == func) { - if (!func->llvmNested) + if (!func->irFunc->nestedVar) return NULL; - return DtoBitCast(v, func->llvmNested->getType()); + return DtoBitCast(v, func->irFunc->nestedVar->getType()); } v = DtoBitCast(v, get_next_frame_ptr_type(fd)); @@ -733,7 +732,7 @@ else if (ClassDeclaration* cd = fd->toParent2()->isClassDeclaration()) { size_t idx = 2; - idx += cd->llvmIRStruct->interfaces.size(); + idx += cd->llvmIrStruct->interfaces.size(); v = DtoGEPi(v,0,idx,"tmp"); v = DtoLoad(v); } @@ -747,7 +746,7 @@ { Logger::println("scope is class: %s", cd->toChars()); /*size_t idx = 2; - idx += cd->llvmIRStruct->interfaces.size(); + idx += cd->llvmIrStruct->interfaces.size(); v = DtoGEPi(v,0,idx,"tmp"); Logger::cout() << "gep = " << *v << '\n'; v = DtoLoad(v);*/ @@ -766,14 +765,14 @@ { Logger::println("Resolving context pointer for nested function: '%s'", func->toPrettyChars()); LOG_SCOPE; - IRFunction* irfunc = gIR->func(); + IrFunction* irfunc = gIR->func(); // in the right scope already if (func == irfunc->decl) - return irfunc->decl->llvmNested; + return irfunc->decl->irFunc->nestedVar; // use the 'this' pointer - llvm::Value* ptr = irfunc->decl->llvmThisVar; + llvm::Value* ptr = irfunc->decl->irFunc->thisVar; assert(ptr); // return the fully resolved frame pointer @@ -830,7 +829,7 @@ llvm::Value* DtoNestedVariable(VarDeclaration* vd) { // log the frame list - IRFunction* irfunc = gIR->func(); + IrFunction* irfunc = gIR->func(); if (Logger::enabled()) print_nested_frame_list(vd, irfunc->decl); @@ -841,10 +840,10 @@ assert(ptr && "nested var, but no context"); // we must cast here to be sure. nested classes just have a void* - ptr = DtoBitCast(ptr, func->llvmNested->getType()); + ptr = DtoBitCast(ptr, func->irFunc->nestedVar->getType()); // index nested var and load (if necessary) - llvm::Value* v = DtoGEPi(ptr, 0, vd->llvmNestedIndex, "tmp"); + llvm::Value* v = DtoGEPi(ptr, 0, vd->irLocal->nestedIndex, "tmp"); // references must be loaded, for normal variables this IS already the variable storage!!! if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))) v = DtoLoad(v); @@ -922,9 +921,9 @@ llvm::Value* tmp = rhs->getRVal(); FuncDeclaration* fdecl = gIR->func()->decl; // respecify the this param - if (!llvm::isa(fdecl->llvmThisVar)) - fdecl->llvmThisVar = new llvm::AllocaInst(tmp->getType(), "newthis", gIR->topallocapoint()); - DtoStore(tmp, fdecl->llvmThisVar); + if (!llvm::isa(fdecl->irFunc->thisVar)) + fdecl->irFunc->thisVar = new llvm::AllocaInst(tmp->getType(), "newthis", gIR->topallocapoint()); + DtoStore(tmp, fdecl->irFunc->thisVar); } // regular class ref -> class ref assignment else { @@ -1584,11 +1583,11 @@ if (_init && _init->getType() != _type) _type = _init->getType(); - llvm::cast(vd->llvmIRGlobal->type.get())->refineAbstractTypeTo(_type); - _type = vd->llvmIRGlobal->type.get(); + llvm::cast(vd->irGlobal->type.get())->refineAbstractTypeTo(_type); + _type = vd->irGlobal->type.get(); assert(!_type->isAbstract()); - llvm::GlobalVariable* gvar = llvm::cast(vd->llvmValue); + llvm::GlobalVariable* gvar = llvm::cast(vd->irGlobal->value); if (!(vd->storage_class & STCextern) && (vd->getModule() == gIR->dmodule || istempl)) { gvar->setInitializer(_init); @@ -1743,3 +1742,29 @@ // create a noop with the code as the result name! gIR->ir->CreateAnd(DtoConstSize_t(0),DtoConstSize_t(0),s.c_str()); } + +const llvm::StructType* DtoInterfaceInfoType() +{ + static const llvm::StructType* t = NULL; + if (t) + return t; + + // build interface info type + std::vector types; + // ClassInfo classinfo + ClassDeclaration* cd2 = ClassDeclaration::classinfo; + DtoResolveClass(cd2); + types.push_back(getPtrToType(cd2->type->llvmType->get())); + // void*[] vtbl + std::vector vtbltypes; + vtbltypes.push_back(DtoSize_t()); + const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); + vtbltypes.push_back(byteptrptrty); + types.push_back(llvm::StructType::get(vtbltypes)); + // int offset + types.push_back(llvm::Type::Int32Ty); + // create type + t = llvm::StructType::get(types); + + return t; +} diff -r 176bd52b3cf5 -r 0e28624814e8 gen/tollvm.h --- a/gen/tollvm.h Mon Jan 14 23:09:55 2008 +0100 +++ b/gen/tollvm.h Thu Jan 17 03:15:12 2008 +0100 @@ -1,51 +1,74 @@ #ifndef LLVMDC_GEN_TOLLVM_H #define LLVMDC_GEN_TOLLVM_H -// D -> LLVM helpers +#include "gen/llvm.h" +#include "lexer.h" +#include "mtype.h" +#include "attrib.h" +#include "declaration.h" -struct DValue; - +// D->LLVM type handling stuff const llvm::Type* DtoType(Type* t); bool DtoIsPassedByRef(Type* type); + +// resolve typedefs to their real type. +// TODO should probably be removed in favor of DMD's Type::toBasetype Type* DtoDType(Type* t); +// delegate helpers const llvm::StructType* DtoDelegateType(Type* t); llvm::Value* DtoNullDelegate(llvm::Value* v); llvm::Value* DtoDelegateCopy(llvm::Value* dst, llvm::Value* src); llvm::Value* DtoCompareDelegate(TOK op, llvm::Value* lhs, llvm::Value* rhs); +// return linkage types for general cases llvm::GlobalValue::LinkageTypes DtoLinkage(PROT prot, uint stc); + +// convert DMD calling conv to LLVM unsigned DtoCallingConv(LINK l); +// TODO: this one should be removed!!! llvm::Value* DtoPointedType(llvm::Value* ptr, llvm::Value* val); + +// casts any value to a boolean llvm::Value* DtoBoolean(llvm::Value* val); +// some types const llvm::Type* DtoSize_t(); +const llvm::StructType* DtoInterfaceInfoType(); +// initializer helpers llvm::Constant* DtoConstInitializer(Type* type, Initializer* init); llvm::Constant* DtoConstFieldInitializer(Type* type, Initializer* init); DValue* DtoInitializer(Initializer* init); +// declaration of memset/cpy intrinsics llvm::Function* LLVM_DeclareMemSet32(); llvm::Function* LLVM_DeclareMemSet64(); llvm::Function* LLVM_DeclareMemCpy32(); llvm::Function* LLVM_DeclareMemCpy64(); +// getelementptr helpers llvm::Value* DtoGEP(llvm::Value* ptr, llvm::Value* i0, llvm::Value* i1, const std::string& var, llvm::BasicBlock* bb=NULL); llvm::Value* DtoGEP(llvm::Value* ptr, const std::vector& src, const std::string& var, llvm::BasicBlock* bb=NULL); llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i0, const std::string& var, llvm::BasicBlock* bb=NULL); llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std::string& var, llvm::BasicBlock* bb=NULL); +// dynamic memory helpers llvm::Value* DtoRealloc(llvm::Value* ptr, const llvm::Type* ty); llvm::Value* DtoRealloc(llvm::Value* ptr, llvm::Value* len); +// assertion generator void DtoAssert(Loc* loc, DValue* msg); +// nested variable/class helpers llvm::Value* DtoNestedContext(FuncDeclaration* func); llvm::Value* DtoNestedVariable(VarDeclaration* vd); +// annotation generator void DtoAnnotation(const char* str); +// to constant helpers llvm::ConstantInt* DtoConstSize_t(size_t); llvm::ConstantInt* DtoConstUint(unsigned i); llvm::ConstantInt* DtoConstInt(int i); @@ -56,17 +79,18 @@ llvm::Constant* DtoConstBool(bool); llvm::Constant* DtoConstNullPtr(const llvm::Type* t); +// is template instance check bool DtoIsTemplateInstance(Dsymbol* s); +// generates lazy static initialization code for a global variable void DtoLazyStaticInit(bool istempl, llvm::Value* gvar, Initializer* init, Type* t); +// these are all basically drivers for the codegeneration called by the main loop void DtoResolveDsymbol(Dsymbol* dsym); void DtoDeclareDsymbol(Dsymbol* dsym); void DtoDefineDsymbol(Dsymbol* dsym); void DtoConstInitDsymbol(Dsymbol* dsym); - void DtoConstInitGlobal(VarDeclaration* vd); - void DtoEmptyResolveList(); void DtoEmptyDeclareList(); void DtoEmptyConstInitList(); diff -r 176bd52b3cf5 -r 0e28624814e8 gen/toobj.cpp --- a/gen/toobj.cpp Mon Jan 14 23:09:55 2008 +0100 +++ b/gen/toobj.cpp Thu Jan 17 03:15:12 2008 +0100 @@ -41,6 +41,8 @@ #include "gen/todebug.h" #include "gen/runtime.h" +#include "ir/irvar.h" + ////////////////////////////////////////////////////////////////////////////////////////// // in gen/optimize.cpp @@ -169,7 +171,7 @@ size_t n = gIR->ctors.size(); if (n == 1) - return llvm::cast(gIR->ctors[0]->llvmValue); + return gIR->ctors[0]->irFunc->func; std::string name("_D"); name.append(gIR->dmodule->mangle()); @@ -184,7 +186,7 @@ LLVMBuilder builder(bb); for (size_t i=0; i(gIR->ctors[i]->llvmValue); + llvm::Function* f = gIR->ctors[i]->irFunc->func; llvm::CallInst* call = builder.CreateCall(f,""); call->setCallingConv(llvm::CallingConv::Fast); } @@ -202,7 +204,7 @@ size_t n = gIR->dtors.size(); if (n == 1) - return llvm::cast(gIR->dtors[0]->llvmValue); + return gIR->dtors[0]->irFunc->func; std::string name("_D"); name.append(gIR->dmodule->mangle()); @@ -217,7 +219,7 @@ LLVMBuilder builder(bb); for (size_t i=0; i(gIR->dtors[i]->llvmValue); + llvm::Function* f = gIR->dtors[i]->irFunc->func; llvm::CallInst* call = builder.CreateCall(f,""); call->setCallingConv(llvm::CallingConv::Fast); } @@ -235,7 +237,7 @@ size_t n = gIR->unitTests.size(); if (n == 1) - return llvm::cast(gIR->unitTests[0]->llvmValue); + return gIR->unitTests[0]->irFunc->func; std::string name("_D"); name.append(gIR->dmodule->mangle()); @@ -250,7 +252,7 @@ LLVMBuilder builder(bb); for (size_t i=0; i(gIR->unitTests[i]->llvmValue); + llvm::Function* f = gIR->unitTests[i]->irFunc->func; llvm::CallInst* call = builder.CreateCall(f,""); call->setCallingConv(llvm::CallingConv::Fast); } @@ -354,7 +356,7 @@ ClassDeclaration* cd = (ClassDeclaration*)aclasses.data[i]; if (cd->isInterfaceDeclaration()) { - Logger::println("skipping interface '%s'", cd->toPrettyChars()); + Logger::println("skipping interface '%s' in moduleinfo", cd->toPrettyChars()); continue; } Logger::println("class: %s", cd->toPrettyChars()); @@ -507,7 +509,7 @@ llvmResolved = true; llvmDeclared = true; - llvmIRGlobal = new IRGlobal(this); + irGlobal = new IrGlobal(this); Logger::println("parent: %s (%s)", parent->toChars(), parent->kind()); @@ -529,13 +531,13 @@ else _linkage = DtoLinkage(protection, storage_class); - const llvm::Type* _type = llvmIRGlobal->type.get(); + const llvm::Type* _type = irGlobal->type.get(); Logger::println("Creating global variable"); std::string _name(mangle()); llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,NULL,_name,gIR->module); - llvmValue = gvar; + irGlobal->value = gvar; if (static_local) DtoConstInitGlobal(this); @@ -549,9 +551,10 @@ Logger::println("Aggregate var declaration: '%s' offset=%d", toChars(), offset); const llvm::Type* _type = DtoType(type); + irField = new IrField(this); // add the field in the IRStruct - gIR->topstruct()->offsets.insert(std::make_pair(offset, IRStruct::Offset(this, _type))); + gIR->topstruct()->offsets.insert(std::make_pair(offset, IrStruct::Offset(this, _type))); } Logger::println("VarDeclaration::toObjFile is done"); diff -r 176bd52b3cf5 -r 0e28624814e8 gen/typinf.cpp --- a/gen/typinf.cpp Mon Jan 14 23:09:55 2008 +0100 +++ b/gen/typinf.cpp Thu Jan 17 03:15:12 2008 +0100 @@ -39,6 +39,8 @@ #include "gen/structs.h" #include "gen/classes.h" +#include "ir/irvar.h" + /******************************************* * Get a canonicalized form of the TypeInfo for use with the internal * runtime library routines. Canonicalized in that static arrays are @@ -254,7 +256,7 @@ Logger::println("DtoResolveTypeInfo(%s)", tid->toChars()); LOG_SCOPE; - tid->llvmIRGlobal = new IRGlobal(tid); + tid->irGlobal = new IrGlobal(tid); gIR->declareList.push_back(tid); } @@ -280,15 +282,17 @@ const llvm::Type* t = llvm::OpaqueType::get(); llvm::GlobalVariable* g = new llvm::GlobalVariable(t, true, llvm::GlobalValue::ExternalLinkage, NULL, mangled, gIR->module); assert(g); - tid->llvmValue = g; + /*if (!tid->irGlobal) + tid->irGlobal = new IrGlobal(tid);*/ + tid->irGlobal->value = g; mangled.append("__TYPE"); - gIR->module->addTypeName(mangled, tid->llvmValue->getType()->getContainedType(0)); - Logger::println("Got typeinfo var: %s", tid->llvmValue->getName().c_str()); + gIR->module->addTypeName(mangled, tid->irGlobal->value->getType()->getContainedType(0)); + Logger::println("Got typeinfo var: %s", tid->irGlobal->value->getName().c_str()); tid->llvmInitialized = true; tid->llvmDefined = true; } - else if (!tid->llvmValue) { - tid->llvmValue = found; + else if (!tid->irGlobal->value) { + tid->irGlobal->value = found; tid->llvmInitialized = true; tid->llvmDefined = true; } @@ -352,7 +356,7 @@ const llvm::StructType* stype = isaStruct(base->type->llvmType->get()); // create the symbol - llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); + irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); } void TypeInfoTypedefDeclaration::llvmDefine() @@ -385,12 +389,11 @@ sd->basetype->getTypeInfo(NULL); // generate vtinfo assert(sd->basetype->vtinfo); - if (!sd->basetype->vtinfo->llvmValue) - DtoForceDeclareDsymbol(sd->basetype->vtinfo); + DtoForceDeclareDsymbol(sd->basetype->vtinfo); - assert(sd->basetype->vtinfo->llvmValue); - assert(llvm::isa(sd->basetype->vtinfo->llvmValue)); - llvm::Constant* castbase = llvm::cast(sd->basetype->vtinfo->llvmValue); + assert(sd->basetype->vtinfo->irGlobal->value); + assert(llvm::isa(sd->basetype->vtinfo->irGlobal->value)); + llvm::Constant* castbase = llvm::cast(sd->basetype->vtinfo->irGlobal->value); castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2)); sinits.push_back(castbase); @@ -418,7 +421,7 @@ // create the symbol llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits); - isaGlobalVar(llvmValue)->setInitializer(tiInit); + isaGlobalVar(irGlobal->value)->setInitializer(tiInit); } void TypeInfoTypedefDeclaration::toDt(dt_t **pdt) @@ -439,7 +442,7 @@ const llvm::StructType* stype = isaStruct(base->type->llvmType->get()); // create the symbol - llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); + irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); } void TypeInfoEnumDeclaration::llvmDefine() @@ -471,11 +474,10 @@ sd->memtype->getTypeInfo(NULL); // generate vtinfo assert(sd->memtype->vtinfo); - if (!sd->memtype->vtinfo->llvmValue) - DtoForceDeclareDsymbol(sd->memtype->vtinfo); + DtoForceDeclareDsymbol(sd->memtype->vtinfo); - assert(llvm::isa(sd->memtype->vtinfo->llvmValue)); - llvm::Constant* castbase = llvm::cast(sd->memtype->vtinfo->llvmValue); + assert(llvm::isa(sd->memtype->vtinfo->irGlobal->value)); + llvm::Constant* castbase = llvm::cast(sd->memtype->vtinfo->irGlobal->value); castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2)); sinits.push_back(castbase); @@ -504,7 +506,7 @@ // create the symbol llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits); - isaGlobalVar(llvmValue)->setInitializer(tiInit); + isaGlobalVar(irGlobal->value)->setInitializer(tiInit); } void TypeInfoEnumDeclaration::toDt(dt_t **pdt) @@ -522,7 +524,7 @@ const llvm::StructType* stype = isaStruct(base->type->llvmType->get()); // create the symbol - tid->llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,tid->toChars(),gIR->module); + tid->irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,tid->toChars(),gIR->module); } static llvm::Constant* LLVM_D_Define_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid, ClassDeclaration* cd) @@ -543,16 +545,15 @@ Logger::println("generating base typeinfo"); basetype->getTypeInfo(NULL); assert(basetype->vtinfo); - if (!basetype->vtinfo->llvmValue) - DtoForceDeclareDsymbol(basetype->vtinfo); - assert(llvm::isa(basetype->vtinfo->llvmValue)); - llvm::Constant* castbase = llvm::cast(basetype->vtinfo->llvmValue); + DtoForceDeclareDsymbol(basetype->vtinfo); + assert(llvm::isa(basetype->vtinfo->irGlobal->value)); + llvm::Constant* castbase = llvm::cast(basetype->vtinfo->irGlobal->value); castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2)); sinits.push_back(castbase); // create the symbol llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits); - isaGlobalVar(tid->llvmValue)->setInitializer(tiInit); + isaGlobalVar(tid->irGlobal->value)->setInitializer(tiInit); } /* ========================================================================= */ @@ -628,7 +629,7 @@ const llvm::StructType* stype = isaStruct(base->type->llvmType->get()); // create the symbol - llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); + irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); } void TypeInfoStaticArrayDeclaration::llvmDefine() @@ -659,7 +660,7 @@ // get symbol assert(tc->next->vtinfo); DtoForceDeclareDsymbol(tc->next->vtinfo); - llvm::Constant* castbase = isaConstant(tc->next->vtinfo->llvmValue); + llvm::Constant* castbase = isaConstant(tc->next->vtinfo->irGlobal->value); castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2)); sinits.push_back(castbase); @@ -668,7 +669,7 @@ // create the symbol llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits); - isaGlobalVar(llvmValue)->setInitializer(tiInit); + isaGlobalVar(irGlobal->value)->setInitializer(tiInit); } void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt) @@ -691,7 +692,7 @@ const llvm::StructType* stype = isaStruct(base->type->llvmType->get()); // create the symbol - llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); + irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); } void TypeInfoAssociativeArrayDeclaration::llvmDefine() @@ -724,7 +725,7 @@ // get symbol assert(tc->next->vtinfo); DtoForceDeclareDsymbol(tc->next->vtinfo); - llvm::Constant* castbase = isaConstant(tc->next->vtinfo->llvmValue); + llvm::Constant* castbase = isaConstant(tc->next->vtinfo->irGlobal->value); castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2)); sinits.push_back(castbase); @@ -734,13 +735,13 @@ // get symbol assert(tc->index->vtinfo); DtoForceDeclareDsymbol(tc->index->vtinfo); - castbase = isaConstant(tc->index->vtinfo->llvmValue); + castbase = isaConstant(tc->index->vtinfo->irGlobal->value); castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(3)); sinits.push_back(castbase); // create the symbol llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits); - isaGlobalVar(llvmValue)->setInitializer(tiInit); + isaGlobalVar(irGlobal->value)->setInitializer(tiInit); } void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt) @@ -824,7 +825,7 @@ const llvm::StructType* stype = isaStruct(((TypeClass*)base->type)->llvmType->get()); // create the symbol - llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); + irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); } void TypeInfoStructDeclaration::llvmDefine() @@ -924,8 +925,8 @@ fd = fdx->overloadExactMatch(tftohash); if (fd) { DtoForceDeclareDsymbol(fd); - assert(fd->llvmValue != 0); - llvm::Constant* c = isaConstant(fd->llvmValue); + assert(fd->irFunc->func != 0); + llvm::Constant* c = isaConstant(fd->irFunc->func); assert(c); c = llvm::ConstantExpr::getBitCast(c, ptty); sinits.push_back(c); @@ -950,8 +951,8 @@ fd = fdx->overloadExactMatch(tfeqptr); if (fd) { DtoForceDeclareDsymbol(fd); - assert(fd->llvmValue != 0); - llvm::Constant* c = isaConstant(fd->llvmValue); + assert(fd->irFunc->func != 0); + llvm::Constant* c = isaConstant(fd->irFunc->func); assert(c); c = llvm::ConstantExpr::getBitCast(c, ptty); sinits.push_back(c); @@ -978,8 +979,8 @@ fd = fdx->overloadExactMatch(tftostring); if (fd) { DtoForceDeclareDsymbol(fd); - assert(fd->llvmValue != 0); - llvm::Constant* c = isaConstant(fd->llvmValue); + assert(fd->irFunc->func != 0); + llvm::Constant* c = isaConstant(fd->irFunc->func); assert(c); c = llvm::ConstantExpr::getBitCast(c, ptty); sinits.push_back(c); @@ -1000,7 +1001,7 @@ llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits); llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,tiInit,toChars(),gIR->module); - isaGlobalVar(llvmValue)->setInitializer(tiInit); + isaGlobalVar(irGlobal->value)->setInitializer(tiInit); } void TypeInfoStructDeclaration::toDt(dt_t **pdt) @@ -1024,7 +1025,7 @@ const llvm::StructType* stype = isaStruct(base->type->llvmType->get()); // create the symbol - llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); + irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); } void TypeInfoClassDeclaration::llvmDefine() @@ -1056,7 +1057,7 @@ // create the symbol llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits); - isaGlobalVar(llvmValue)->setInitializer(tiInit); + isaGlobalVar(irGlobal->value)->setInitializer(tiInit); } void TypeInfoClassDeclaration::toDt(dt_t **pdt) @@ -1080,7 +1081,7 @@ const llvm::StructType* stype = isaStruct(base->type->llvmType->get()); // create the symbol - llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); + irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); } void TypeInfoInterfaceDeclaration::llvmDefine() @@ -1112,7 +1113,7 @@ // create the symbol llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits); - isaGlobalVar(llvmValue)->setInitializer(tiInit); + isaGlobalVar(irGlobal->value)->setInitializer(tiInit); } void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt) @@ -1136,7 +1137,7 @@ const llvm::StructType* stype = isaStruct(base->type->llvmType->get()); // create the symbol - llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); + irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); } void TypeInfoTupleDeclaration::llvmDefine() @@ -1175,8 +1176,8 @@ Argument *arg = (Argument *)tu->arguments->data[i]; arg->type->getTypeInfo(NULL); DtoForceDeclareDsymbol(arg->type->vtinfo); - assert(arg->type->vtinfo->llvmValue); - llvm::Constant* c = isaConstant(arg->type->vtinfo->llvmValue); + assert(arg->type->vtinfo->irGlobal->value); + llvm::Constant* c = isaConstant(arg->type->vtinfo->irGlobal->value); c = llvm::ConstantExpr::getBitCast(c, tiTy); arrInits.push_back(c); } @@ -1191,7 +1192,7 @@ // create the symbol llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits); - isaGlobalVar(llvmValue)->setInitializer(tiInit); + isaGlobalVar(irGlobal->value)->setInitializer(tiInit); } void TypeInfoTupleDeclaration::toDt(dt_t **pdt) diff -r 176bd52b3cf5 -r 0e28624814e8 ir/ir.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ir/ir.h Thu Jan 17 03:15:12 2008 +0100 @@ -0,0 +1,14 @@ +// this head contains stuff used by all the IR + +#ifndef LLVMDC_IR_IR_H +#define LLVMDC_IR_IR_H + +#include "ir/irforw.h" +#include "root.h" + +struct IrBase : Object +{ + virtual ~IrBase() {} +}; + +#endif diff -r 176bd52b3cf5 -r 0e28624814e8 ir/irforw.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ir/irforw.h Thu Jan 17 03:15:12 2008 +0100 @@ -0,0 +1,45 @@ +#ifndef LLVMDC_IR_IRFORW_H +#define LLVMDC_IR_IRFORW_H + +// dmd forward declarations +struct Module; +struct Dsymbol; +struct Declaration; +struct VarDeclaration; +struct FuncDeclaration; +struct AggregateDeclaration; +struct StructDeclaration; +struct ClassDeclaration; +struct InterfaceDeclaration; +struct Expression; +struct BaseClass; +struct Array; +struct Argument; + +struct Type; +struct TypeStruct; +struct TypeClass; +struct TypeEnum; +struct TypeArray; +struct TypeFunction; + +// llvm forward declarations +namespace llvm +{ + class Value; + class GlobalValue; + class GlobalVariable; + class Function; + class Constant; + class ConstantStruct; + class ConstantArray; + class TargetData; + class Type; + class StructType; + class ArrayType; + class PointerType; + class BasicBlock; + class Instruction; +} + +#endif diff -r 176bd52b3cf5 -r 0e28624814e8 ir/irfunction.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ir/irfunction.cpp Thu Jan 17 03:15:12 2008 +0100 @@ -0,0 +1,44 @@ +#include "gen/tollvm.h" +#include "ir/irfunction.h" + +IrFinally::IrFinally() +{ + bb = 0; + retbb = 0; +} + +IrFinally::IrFinally(llvm::BasicBlock* b, llvm::BasicBlock* rb) +{ + bb = b; + retbb = rb; +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +IrFunction::IrFunction(FuncDeclaration* fd) +{ + decl = fd; + + Type* t = DtoDType(fd->type); + assert(t->ty == Tfunction); + type = (TypeFunction*)t; + func = NULL; + allocapoint = NULL; + finallyretval = NULL; + + queued = false; + defined = false; + + retArg = NULL; + thisVar = NULL; + nestedVar = NULL; + _arguments = NULL; + _argptr = NULL; + dwarfSubProg = NULL; +} + +IrFunction::~IrFunction() +{ +} diff -r 176bd52b3cf5 -r 0e28624814e8 ir/irfunction.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ir/irfunction.h Thu Jan 17 03:15:12 2008 +0100 @@ -0,0 +1,44 @@ +#ifndef LLVMDC_IR_IRFUNCTION_H +#define LLVMDC_IR_IRFUNCTION_H + +#include "ir/ir.h" + +#include + +// represents a finally block +struct IrFinally +{ + llvm::BasicBlock* bb; + llvm::BasicBlock* retbb; + + IrFinally(); + IrFinally(llvm::BasicBlock* b, llvm::BasicBlock* rb); +}; + +// represents a function +struct IrFunction : IrBase +{ + llvm::Function* func; + llvm::Instruction* allocapoint; + FuncDeclaration* decl; + TypeFunction* type; + + // finally blocks + typedef std::vector FinallyVec; + FinallyVec finallys; + llvm::Value* finallyretval; + + bool queued; + bool defined; + llvm::Value* retArg; + llvm::Value* thisVar; + llvm::Value* nestedVar; + llvm::Value* _arguments; + llvm::Value* _argptr; + llvm::Constant* dwarfSubProg; + + IrFunction(FuncDeclaration* fd); + virtual ~IrFunction(); +}; + +#endif diff -r 176bd52b3cf5 -r 0e28624814e8 ir/irmodule.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ir/irmodule.cpp Thu Jan 17 03:15:12 2008 +0100 @@ -0,0 +1,10 @@ +#include "ir/irmodule.h" + +IrModule::IrModule(Module* module) +{ + M = module; +} + +IrModule::~IrModule() +{ +} diff -r 176bd52b3cf5 -r 0e28624814e8 ir/irmodule.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ir/irmodule.h Thu Jan 17 03:15:12 2008 +0100 @@ -0,0 +1,16 @@ +#ifndef LLVMDC_IR_IRMODULE_H +#define LLVMDC_IR_IRMODULE_H + +#include "ir/ir.h" + +struct Module; + +struct IrModule : IrBase +{ + IrModule(Module* module); + virtual ~IrModule(); + + Module* M; +}; + +#endif diff -r 176bd52b3cf5 -r 0e28624814e8 ir/irstruct.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ir/irstruct.cpp Thu Jan 17 03:15:12 2008 +0100 @@ -0,0 +1,38 @@ +#include "gen/llvm.h" +#include "mtype.h" +#include "aggregate.h" +#include "ir/irstruct.h" + +IrInterface::IrInterface(BaseClass* b, const llvm::StructType* vt) +{ + base = b; + decl = b->base; + vtblTy = vt; + vtblInit = NULL; + vtbl = NULL; + infoTy = NULL; + infoInit = NULL; + info = NULL; +} + +IrInterface::~IrInterface() +{ +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +IrStruct::IrStruct(Type* t) + : recty((t->llvmType != NULL) ? *t->llvmType : llvm::OpaqueType::get()) +{ + type = t; + defined = false; + constinited = false; + interfaceInfosTy = NULL; + interfaceInfos = NULL; +} + +IrStruct::~IrStruct() +{ +} diff -r 176bd52b3cf5 -r 0e28624814e8 ir/irstruct.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ir/irstruct.h Thu Jan 17 03:15:12 2008 +0100 @@ -0,0 +1,65 @@ +#ifndef LLVMDC_IR_IRSTRUCT_H +#define LLVMDC_IR_IRSTRUCT_H + +#include "ir/ir.h" + +#include +#include + +struct IrInterface : IrBase +{ + BaseClass* base; + ClassDeclaration* decl; + + const llvm::StructType* vtblTy; + llvm::ConstantStruct* vtblInit; + llvm::GlobalVariable* vtbl; + + const llvm::StructType* infoTy; + llvm::ConstantStruct* infoInit; + llvm::Constant* info; + + IrInterface(BaseClass* b, const llvm::StructType* vt); + ~IrInterface(); +}; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +// represents a struct or class +struct IrStruct : IrBase +{ + struct Offset + { + VarDeclaration* var; + const llvm::Type* type; + llvm::Constant* init; + + Offset(VarDeclaration* v, const llvm::Type* ty) + : var(v), type(ty), init(NULL) {} + }; + + typedef std::multimap OffsetMap; + typedef std::vector VarDeclVector; + typedef std::map InterfaceMap; + typedef InterfaceMap::iterator InterfaceIter; + +public: + IrStruct(Type*); + virtual ~IrStruct(); + + Type* type; + llvm::PATypeHolder recty; + OffsetMap offsets; + VarDeclVector defaultFields; + + InterfaceMap interfaces; + const llvm::ArrayType* interfaceInfosTy; + llvm::GlobalVariable* interfaceInfos; + + bool defined; + bool constinited; +}; + +#endif diff -r 176bd52b3cf5 -r 0e28624814e8 ir/irvar.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ir/irvar.cpp Thu Jan 17 03:15:12 2008 +0100 @@ -0,0 +1,63 @@ +#include "llvm/DerivedTypes.h" +#include "declaration.h" +#include "ir/irvar.h" + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +IrVar* VarDeclaration::getIrVar() +{ + assert(irGlobal || irLocal || irField); + return irGlobal ? (IrVar*)irGlobal : irLocal ? (IrVar*)irLocal : (IrVar*)irField; +} + +llvm::Value*& VarDeclaration::getIrValue() +{ + return getIrVar()->value; +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +IrVar::IrVar(VarDeclaration* var) +{ + V = var; + value = NULL; +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +IrGlobal::IrGlobal(VarDeclaration* v): IrVar(v), + type(llvm::OpaqueType::get()) +{ + constInit = NULL; +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +IrLocal::IrLocal(VarDeclaration* v) : IrVar(v) +{ + nestedIndex = -1; +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +IrField::IrField(VarDeclaration* v) : IrVar(v) +{ + index = -1; + indexOffset = 0; + constInit = NULL; +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// diff -r 176bd52b3cf5 -r 0e28624814e8 ir/irvar.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ir/irvar.h Thu Jan 17 03:15:12 2008 +0100 @@ -0,0 +1,42 @@ +#ifndef LLVMDC_IR_IRVAR_H +#define LLVMDC_IR_IRVAR_H + +#include "ir/ir.h" +#include "llvm/Type.h" + +struct IrVar : IrBase +{ + IrVar(VarDeclaration* var); + + VarDeclaration* V; + llvm::Value* value; +}; + +// represents a global variable +struct IrGlobal : IrVar +{ + IrGlobal(VarDeclaration* v); + + llvm::PATypeHolder type; + llvm::Constant* constInit; +}; + +// represents a local variable variable +struct IrLocal : IrVar +{ + IrLocal(VarDeclaration* v); + + int nestedIndex; +}; + +// represents an aggregate field variable +struct IrField : IrVar +{ + IrField(VarDeclaration* v); + + int index; + size_t indexOffset; + llvm::Constant* constInit; +}; + +#endif diff -r 176bd52b3cf5 -r 0e28624814e8 llvmdc.kdevelop.filelist --- a/llvmdc.kdevelop.filelist Mon Jan 14 23:09:55 2008 +0100 +++ b/llvmdc.kdevelop.filelist Thu Jan 17 03:15:12 2008 +0100 @@ -120,7 +120,6 @@ gen/irstate.cpp gen/irstate.h gen/llvm.h -gen/llvmd.h gen/logger.cpp gen/logger.h gen/optimizer.cpp @@ -139,6 +138,19 @@ gen/toobj.cpp gen/typeinf.h gen/typinf.cpp +ir +ir/forw.h +ir/ir.h +ir/irfunction.cpp +ir/irfunction.h +ir/irglobal.cpp +ir/irglobal.h +ir/irmodule.cpp +ir/irmodule.h +ir/irstruct.cpp +ir/irstruct.h +ir/irvar.cpp +ir/irvar.h lphobos lphobos/build.sh lphobos/crc32.d @@ -263,7 +275,6 @@ tango/lib/compiler/llvmdc/adi.d tango/lib/compiler/llvmdc/arrays.d tango/lib/compiler/llvmdc/cast.d -tango/lib/compiler/llvmdc/contract.d tango/lib/compiler/llvmdc/critical.c tango/lib/compiler/llvmdc/dmain2.d tango/lib/compiler/llvmdc/eh.d @@ -749,6 +760,8 @@ tangotests/p.d tangotests/q.d tangotests/r.d +tangotests/s.d +tangotests/t.d test test/a.d test/aa1.d diff -r 176bd52b3cf5 -r 0e28624814e8 premake.lua --- a/premake.lua Mon Jan 14 23:09:55 2008 +0100 +++ b/premake.lua Thu Jan 17 03:15:12 2008 +0100 @@ -21,7 +21,7 @@ package.name = "llvmdc" package.kind = "exe" package.language = "c++" -package.files = { matchfiles("dmd/*.c"), matchfiles("gen/*.cpp") } +package.files = { matchfiles("dmd/*.c"), matchfiles("gen/*.cpp"), matchfiles("ir/*.cpp") } package.excludes = { "dmd/idgen.c", "dmd/impcnvgen.c" } package.buildoptions = { "-x c++", "`llvm-config --cxxflags`" } package.linkoptions = { diff -r 176bd52b3cf5 -r 0e28624814e8 tango/lib/compiler/llvmdc/cast.d --- a/tango/lib/compiler/llvmdc/cast.d Mon Jan 14 23:09:55 2008 +0100 +++ b/tango/lib/compiler/llvmdc/cast.d Thu Jan 17 03:15:12 2008 +0100 @@ -27,6 +27,9 @@ extern (C): +debug = PRINTF; +debug(PRINTF) int printf(char*, ...); + /****************************************** * Given a pointer: * If it is an Object, return that Object. @@ -54,6 +57,7 @@ o = cast(Object)(p - pi.offset); } } + debug(PRINTF) printf("toObject = %p\n", o); return o; } @@ -75,6 +79,7 @@ o = cast(Object)(p - pi.offset); return _d_dynamic_cast(o, c); } + debug(PRINTF) printf("_d_interface_cast = %p\n", o); return o; } @@ -82,7 +87,7 @@ { ClassInfo oc; size_t offset = 0; - //printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name); + debug(PRINTF) printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name.length, c.name.ptr); if (o) { @@ -96,16 +101,20 @@ o = null; } //printf("\tresult = %p\n", o); + debug(PRINTF) printf("_d_dynamic_cast = %p\n", o); return o; } int _d_isbaseof2(ClassInfo oc, ClassInfo c, ref size_t offset) { int i; + debug(PRINTF) printf("_d_isbaseof2(%.*s, %.*s, %ul)\n", oc.name.length, oc.name.ptr, c.name.length, c.name.ptr, offset); + if (oc is c) return 1; do { + debug(PRINTF) printf("oc.interfaces.length = %ul\n", oc.interfaces.length); if (oc.base is c) return 1; for (i = 0; i < oc.interfaces.length; i++) @@ -113,6 +122,7 @@ ClassInfo ic; ic = oc.interfaces[i].classinfo; + debug(PRINTF) printf("checking %.*s\n", ic.name.length, ic.name.ptr); if (ic is c) { offset = cast(size_t)oc.interfaces[i].offset; return 1; diff -r 176bd52b3cf5 -r 0e28624814e8 tango/tango/io/Buffer.d --- a/tango/tango/io/Buffer.d Mon Jan 14 23:09:55 2008 +0100 +++ b/tango/tango/io/Buffer.d Thu Jan 17 03:15:12 2008 +0100 @@ -25,6 +25,7 @@ extern (C) { protected void * memcpy (void *dst, void *src, uint); + private int printf(char*, ...); } /******************************************************************************* @@ -163,10 +164,14 @@ this (IConduit conduit) { + printf("Buffer.this(%p)\n", conduit); + assert (conduit !is null); assert (conduit); this (conduit.bufferSize); setConduit (conduit); + + assert(this !is null); } /*********************************************************************** @@ -221,7 +226,8 @@ this (uint capacity = 0) { - setContent (new ubyte[capacity], 0); + setContent (new ubyte[capacity], 0); + assert(this !is null); } /*********************************************************************** diff -r 176bd52b3cf5 -r 0e28624814e8 tango/tango/io/Console.d --- a/tango/tango/io/Console.d Mon Jan 14 23:09:55 2008 +0100 +++ b/tango/tango/io/Console.d Thu Jan 17 03:15:12 2008 +0100 @@ -23,6 +23,7 @@ version (Posix) private import tango.stdc.posix.unistd; // needed for isatty() +private extern(C) int printf(char*, ...); /******************************************************************************* @@ -69,6 +70,8 @@ private this (Conduit conduit, bool redirected) { + printf("Console.Input.this(%p, %d)\n", conduit, redirected); + assert (conduit); redirect = redirected; buffer = new Buffer (conduit); } @@ -596,6 +599,7 @@ private this (Handle handle) { + printf("Console.Conduit.this(%d)\n", handle); reopen (handle); redirected = (isatty(handle) is 0); } @@ -621,14 +625,13 @@ ******************************************************************************/ -extern(C) int printf(char*, ...); - static this () { printf("STATIC INIT FOR CONSOLE\n"); - printf("Cin\n"); + printf("Cin conduit\n"); auto conduit = new Console.Conduit (0); assert(conduit); + printf("Cin input\n"); Cin = new Console.Input (conduit, conduit.redirected); printf("Cout\n"); diff -r 176bd52b3cf5 -r 0e28624814e8 tango/tango/io/DeviceConduit.d --- a/tango/tango/io/DeviceConduit.d Mon Jan 14 23:09:55 2008 +0100 +++ b/tango/tango/io/DeviceConduit.d Thu Jan 17 03:15:12 2008 +0100 @@ -18,6 +18,8 @@ private import tango.core.Exception; +private extern(C) int printf(char*, ...); + /******************************************************************************* Implements a means of reading and writing a file device. Conduits