# HG changeset patch # User lindquist # Date 1191903690 -7200 # Node ID 3cfcb944304e17d3d9e6975c961dd2345ab8e345 # Parent 4648206ca21347c7b27d018eae564542aff1e308 [svn r39] * Updated to DMD 1.022 with the exception of: Bugzilla 278: dmd.conf search path doesn't work This fix was causing crashes for me :/ So for it's the old behaviour diff -r 4648206ca213 -r 3cfcb944304e dmd/aggregate.h --- a/dmd/aggregate.h Tue Oct 09 02:50:00 2007 +0200 +++ b/dmd/aggregate.h Tue Oct 09 06:21:30 2007 +0200 @@ -213,6 +213,7 @@ void interfaceSemantic(Scope *sc); int isNested(); int isCOMclass(); + virtual int isCOMinterface(); int isAbstract(); virtual int vtblOffset(); char *kind(); @@ -248,6 +249,7 @@ int isBaseOf(BaseClass *bc, int *poffset); char *kind(); int vtblOffset(); + virtual int isCOMinterface(); void toObjFile(); // compile to .obj file Symbol *toSymbol(); diff -r 4648206ca213 -r 3cfcb944304e dmd/class.c --- a/dmd/class.c Tue Oct 09 02:50:00 2007 +0200 +++ b/dmd/class.c Tue Oct 09 06:21:30 2007 +0200 @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2006 by Digital Mars +// Copyright (c) 1999-2007 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -146,6 +146,20 @@ Type::typeinfotypelist->error("%s", msg); Type::typeinfotypelist = this; } + +#if V2 + if (id == Id::TypeInfo_Const) + { if (Type::typeinfoconst) + Type::typeinfoconst->error("%s", msg); + Type::typeinfoconst = this; + } + + if (id == Id::TypeInfo_Invariant) + { if (Type::typeinfoinvariant) + Type::typeinfoinvariant->error("%s", msg); + Type::typeinfoinvariant = this; + } +#endif } if (id == Id::Object) @@ -168,10 +182,6 @@ } com = 0; -#if 0 - if (id == Id::IUnknown) // IUnknown is the root of all COM objects - com = 1; -#endif isauto = 0; isabstract = 0; isnested = 0; @@ -249,6 +259,11 @@ methods.setDim(0); #endif + if (sc->stc & STCdeprecated) + { //printf("test1: %s is deprecated\n", toChars()); + isdeprecated = 1; + } + // Expand any tuples in baseclasses[] for (i = 0; i < baseclasses.dim; ) { BaseClass *b = (BaseClass *)baseclasses.data[i]; @@ -286,6 +301,17 @@ else { tc = (TypeClass *)(tb); + if (tc->sym->isDeprecated()) + { + if (!isDeprecated()) + { + // Deriving from deprecated class makes this one deprecated too + isdeprecated = 1; + + tc->checkDeprecated(loc, sc); + } + } + if (tc->sym->isInterfaceDeclaration()) ; else @@ -340,6 +366,17 @@ } else { + if (tc->sym->isDeprecated()) + { + if (!isDeprecated()) + { + // Deriving from deprecated class makes this one deprecated too + isdeprecated = 1; + + tc->checkDeprecated(loc, sc); + } + } + // Check for duplicate interfaces for (size_t j = (baseClass ? 1 : 0); j < i; j++) { @@ -480,8 +517,6 @@ isauto = 1; if (storage_class & STCabstract) isabstract = 1; - if (storage_class & STCdeprecated) - isdeprecated = 1; sc = sc->push(this); sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic | @@ -567,7 +602,7 @@ ctor->fbody = new CompoundStatement(0, new Statements()); members->push(ctor); ctor->addMember(sc, this, 1); - *sc = scsave; + *sc = scsave; // why? What about sc->nofree? sc->offset = structsize; ctor->semantic(sc); defaultCtor = ctor; @@ -754,6 +789,35 @@ return s; } +/********************************************************** + * fd is in the vtbl[] for this class. + * Return 1 if function is hidden (not findable through search). + */ + +#if V2 +int isf(void *param, FuncDeclaration *fd) +{ + //printf("param = %p, fd = %p %s\n", param, fd, fd->toChars()); + return param == fd; +} + +int ClassDeclaration::isFuncHidden(FuncDeclaration *fd) +{ + //printf("ClassDeclaration::isFuncHidden(%s)\n", fd->toChars()); + Dsymbol *s = search(0, fd->ident, 4|2); + if (!s) + { //printf("not found\n"); + /* Because, due to a hack, if there are multiple definitions + * of fd->ident, NULL is returned. + */ + return 0; + } + FuncDeclaration *fdstart = s->toAlias()->isFuncDeclaration(); + //printf("%s fdstart = %p\n", s->kind(), fdstart); + return !overloadApply(fdstart, &isf, fd); +} +#endif + /**************** * Find virtual function matching identifier and type. * Used to build virtual function tables for interface implementations. @@ -802,7 +866,7 @@ // If this is an interface, and it derives from a COM interface, // then this is a COM interface too. - if (b->base->isCOMclass()) + if (b->base->isCOMinterface()) com = 1; vtblInterfaces->push(b); @@ -818,6 +882,11 @@ return com; } +int ClassDeclaration::isCOMinterface() +{ + return 0; +} + /**************************************** */ @@ -927,6 +996,11 @@ scope = NULL; } + if (sc->stc & STCdeprecated) + { + isdeprecated = 1; + } + // Expand any tuples in baseclasses[] for (i = 0; i < baseclasses.dim; ) { BaseClass *b = (BaseClass *)baseclasses.data[0]; @@ -1044,7 +1118,7 @@ sc = sc->push(this); sc->parent = this; - if (isCOMclass()) + if (isCOMinterface()) sc->linkage = LINKwindows; sc->structalign = 8; structalign = sc->structalign; @@ -1134,18 +1208,23 @@ /**************************************** * Determine if slot 0 of the vtbl[] is reserved for something else. - * For class objects, yes, this is where the classinfo ptr goes. + * For class objects, yes, this is where the ClassInfo ptr goes. * For COM interfaces, no. * For non-COM interfaces, yes, this is where the Interface ptr goes. */ int InterfaceDeclaration::vtblOffset() { - if (isCOMclass()) + if (isCOMinterface()) return 0; return 1; } +int InterfaceDeclaration::isCOMinterface() +{ + return com; +} + /******************************************* */ diff -r 4648206ca213 -r 3cfcb944304e dmd/constfold.c --- a/dmd/constfold.c Tue Oct 09 02:50:00 2007 +0200 +++ b/dmd/constfold.c Tue Oct 09 06:21:30 2007 +0200 @@ -733,6 +733,36 @@ } } } + else if (e1->op == TOKarrayliteral && e2->op == TOKstring) + { // Swap operands and use common code + Expression *e = e1; + e1 = e2; + e2 = e; + goto Lsa; + } + else if (e1->op == TOKstring && e2->op == TOKarrayliteral) + { + Lsa: + StringExp *es1 = (StringExp *)e1; + ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; + size_t dim1 = es1->len; + size_t dim2 = es2->elements ? es2->elements->dim : 0; + if (dim1 != dim2) + cmp = 0; + else + { + for (size_t i = 0; i < dim1; i++) + { + uinteger_t c = es1->charAt(i); + Expression *ee2 = (Expression *)es2->elements->data[i]; + if (ee2->isConst() != 1) + return EXP_CANT_INTERPRET; + cmp = (c == ee2->toInteger()); + if (cmp == 0) + break; + } + } + } else if (e1->op == TOKstructliteral && e2->op == TOKstructliteral) { StructLiteralExp *es1 = (StructLiteralExp *)e1; StructLiteralExp *es2 = (StructLiteralExp *)e2; @@ -1132,26 +1162,7 @@ if (i >= es1->len) e1->error("string index %ju is out of bounds [0 .. %zu]", i, es1->len); else - { integer_t value; - - switch (es1->sz) - { - case 1: - value = ((unsigned char *)es1->string)[i]; - break; - - case 2: - value = ((unsigned short *)es1->string)[i]; - break; - - case 4: - value = ((unsigned int *)es1->string)[i]; - break; - - default: - assert(0); - break; - } + { unsigned value = es1->charAt(i); e = new IntegerExp(loc, value, type); } } diff -r 4648206ca213 -r 3cfcb944304e dmd/expression.c --- a/dmd/expression.c Tue Oct 09 02:50:00 2007 +0200 +++ b/dmd/expression.c Tue Oct 09 06:21:30 2007 +0200 @@ -2354,26 +2354,36 @@ return result ? TRUE : FALSE; } +unsigned StringExp::charAt(size_t i) +{ unsigned value; + + switch (sz) + { + case 1: + value = ((unsigned char *)string)[i]; + break; + + case 2: + value = ((unsigned short *)string)[i]; + break; + + case 4: + value = ((unsigned int *)string)[i]; + break; + + default: + assert(0); + break; + } + return value; +} + void StringExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { buf->writeByte('"'); for (size_t i = 0; i < len; i++) - { unsigned c; - - switch (sz) - { - case 1: - c = ((unsigned char *)string)[i]; - break; - case 2: - c = ((unsigned short *)string)[i]; - break; - case 4: - c = ((unsigned *)string)[i]; - break; - default: - assert(0); - } + { unsigned c = charAt(i); + switch (c) { case '"': @@ -4933,7 +4943,7 @@ { AggregateDeclaration *ad = var->toParent()->isAggregateDeclaration(); L1: - Type *t = e1->type; + Type *t = e1->type->toBasetype(); if (ad && !(t->ty == Tpointer && t->next->ty == Tstruct && @@ -5467,6 +5477,7 @@ */ Expression *e = new StructLiteralExp(loc, (StructDeclaration *)ad, arguments); e = e->semantic(sc); + e->type = e1->type; // in case e1->type was a typedef return e; } else if (t1->ty == Tclass) @@ -6087,8 +6098,11 @@ { TypeClass *tc = (TypeClass *)tb; ClassDeclaration *cd = tc->sym; - if (cd->isInterfaceDeclaration() && cd->isCOMclass()) + if (cd->isCOMinterface()) + { /* Because COM classes are deleted by IUnknown.Release() + */ error("cannot delete instance of COM interface %s", cd->toChars()); + } break; } case Tpointer: diff -r 4648206ca213 -r 3cfcb944304e dmd/expression.h --- a/dmd/expression.h Tue Oct 09 02:50:00 2007 +0200 +++ b/dmd/expression.h Tue Oct 09 06:21:30 2007 +0200 @@ -321,6 +321,7 @@ Expression *castTo(Scope *sc, Type *t); int compare(Object *obj); int isBool(int result); + unsigned charAt(size_t i); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toMangleBuffer(OutBuffer *buf); elem *toElem(IRState *irs); diff -r 4648206ca213 -r 3cfcb944304e dmd/func.c --- a/dmd/func.c Tue Oct 09 02:50:00 2007 +0200 +++ b/dmd/func.c Tue Oct 09 06:21:30 2007 +0200 @@ -929,12 +929,19 @@ * ctor consts were initialized. */ - ScopeDsymbol *ad = toParent()->isScopeDsymbol(); - assert(ad); - for (int i = 0; i < ad->members->dim; i++) - { Dsymbol *s = (Dsymbol *)ad->members->data[i]; - - s->checkCtorConstInit(); + Dsymbol *p = toParent(); + ScopeDsymbol *ad = p->isScopeDsymbol(); + if (!ad) + { + error("static constructor can only be member of struct/class/module, not %s %s", p->kind(), p->toChars()); + } + else + { + for (int i = 0; i < ad->members->dim; i++) + { Dsymbol *s = (Dsymbol *)ad->members->data[i]; + + s->checkCtorConstInit(); + } } } @@ -2249,7 +2256,7 @@ void StaticCtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { if (hgs->hdrgen) - { buf->writestring("static this(){}\n"); + { buf->writestring("static this();\n"); return; } buf->writestring("static this()"); diff -r 4648206ca213 -r 3cfcb944304e dmd/inifile.c --- a/dmd/inifile.c Tue Oct 09 02:50:00 2007 +0200 +++ b/dmd/inifile.c Tue Oct 09 06:21:30 2007 +0200 @@ -76,6 +76,28 @@ if (!FileName::exists(filename)) { #if linux + +#if 0 +#if __GLIBC__ // This fix by Thomas Kuehne + /* argv0 might be a symbolic link, + * so try again looking past it to the real path + */ + char* real_argv0 = realpath(argv0, NULL); + if (real_argv0) + { + filename = FileName::replaceName(real_argv0, inifile); + free(real_argv0); + if (FileName::exists(filename)) + goto Ldone; + } +#else +#error use of glibc non-standard extension realpath(char*, NULL) +#endif +#endif + + // old way; problem is that argv0 might not be on the PATH at all + // and some other instance might be found + // Search PATH for argv0 const char *p = getenv("PATH"); Array *paths = FileName::splitPath(p); diff -r 4648206ca213 -r 3cfcb944304e dmd/mars.c --- a/dmd/mars.c Tue Oct 09 02:50:00 2007 +0200 +++ b/dmd/mars.c Tue Oct 09 06:21:30 2007 +0200 @@ -67,8 +67,8 @@ copyright = "Copyright (c) 1999-2007 by Digital Mars and Tomas Lindquist Olsen"; written = "written by Walter Bright and Tomas Lindquist Olsen"; - llvmdc_version = "0.0.1"; - version = "v1.021"; + llvmdc_version = "0.1"; + version = "v1.022"; global.structalign = 8; memset(¶ms, 0, sizeof(Param)); @@ -173,6 +173,8 @@ -debug compile in debug code\n\ -debug=level compile in debug code <= level\n\ -debug=ident compile in debug code identified by ident\n\ + -debuglib=name set symbolic debug library to name\n\ + -defaultlib=name set default library to name\n\ -g add symbolic debug info\n\ -gc add symbolic debug info, pretend to be C\n\ -H generate 'header' file\n\ diff -r 4648206ca213 -r 3cfcb944304e dmd/mtype.c --- a/dmd/mtype.c Tue Oct 09 02:50:00 2007 +0200 +++ b/dmd/mtype.c Tue Oct 09 06:21:30 2007 +0200 @@ -554,6 +554,8 @@ } else if (ident == Id::init) { + if (ty == Tvoid) + error(loc, "void does not have an initializer"); e = defaultInit(); e->loc = loc; } @@ -642,7 +644,9 @@ return e; } #endif - return defaultInit(); + Expression *ex = defaultInit(); + ex->loc = e->loc; + return ex; } } if (ident == Id::typeinfo) @@ -3760,6 +3764,8 @@ #if LOGDOTEXP printf("TypeEnum::dotExp(e = '%s', ident = '%s') '%s'\n", e->toChars(), ident->toChars(), toChars()); #endif + if (!sym->symtab) + goto Lfwd; s = sym->symtab->lookup(ident); if (!s) { @@ -3769,6 +3775,10 @@ em = m->value->copy(); em->loc = e->loc; return em; + +Lfwd: + error(e->loc, "forward reference of %s.%s", toChars(), ident->toChars()); + return new IntegerExp(0, 0, this); } Expression *TypeEnum::getProperty(Loc loc, Identifier *ident) @@ -4472,6 +4482,9 @@ t = ClassDeclaration::classinfo->type; if (e->op == TOKtype || e->op == TOKdottype) { + /* For type.classinfo, we know the classinfo + * at compile time. + */ if (!sym->vclassinfo) sym->vclassinfo = new ClassInfoDeclaration(sym); e = new VarExp(e->loc, sym->vclassinfo); @@ -4479,13 +4492,25 @@ e->type = t; // do this so we don't get redundant dereference } else - { + { /* For class objects, the classinfo reference is the first + * entry in the vtbl[] + */ e = new PtrExp(e->loc, e); e->type = t->pointerTo(); if (sym->isInterfaceDeclaration()) { - if (sym->isCOMclass()) + if (sym->isCOMinterface()) + { /* COM interface vtbl[]s are different in that the + * first entry is always pointer to QueryInterface(). + * We can't get a .classinfo for it. + */ error(e->loc, "no .classinfo for COM interface objects"); + } + /* For an interface, the first entry in the vtbl[] + * is actually a pointer to an instance of struct Interface. + * The first member of Interface is the .classinfo, + * so add an extra pointer indirection. + */ e->type = e->type->pointerTo(); e = new PtrExp(e->loc, e); e->type = t->pointerTo(); diff -r 4648206ca213 -r 3cfcb944304e dmd/optimize.c --- a/dmd/optimize.c Tue Oct 09 02:50:00 2007 +0200 +++ b/dmd/optimize.c Tue Oct 09 06:21:30 2007 +0200 @@ -371,6 +371,18 @@ //printf("BinExp::optimize(result = %d) %s\n", result, toChars()); e1 = e1->optimize(result); e2 = e2->optimize(result); + if (op == TOKshlass || op == TOKshrass || op == TOKushrass) + { + if (e2->isConst() == 1) + { + integer_t i2 = e2->toInteger(); + d_uns64 sz = e1->type->size() * 8; + if (i2 < 0 || i2 > sz) + { error("shift assign by %jd is outside the range 0..%zu", i2, sz); + e2 = new IntegerExp(0); + } + } + } return this; } @@ -451,55 +463,41 @@ return e; } -Expression *ShlExp::optimize(int result) -{ Expression *e; +Expression *shift_optimize(int result, BinExp *e, Expression *(*shift)(Type *, Expression *, Expression *)) +{ Expression *ex = e; - //printf("ShlExp::optimize(result = %d) %s\n", result, toChars()); - e1 = e1->optimize(result); - e2 = e2->optimize(result); - e = this; - if (e2->isConst() == 1) + e->e1 = e->e1->optimize(result); + e->e2 = e->e2->optimize(result); + if (e->e2->isConst() == 1) { - integer_t i2 = e2->toInteger(); - if (i2 < 0 || i2 > e1->type->size() * 8) - { error("shift left by %jd exceeds %zu", i2, e2->type->size() * 8); - e2 = new IntegerExp(0); + integer_t i2 = e->e2->toInteger(); + d_uns64 sz = e->e1->type->size() * 8; + if (i2 < 0 || i2 > sz) + { error("shift by %jd is outside the range 0..%zu", i2, sz); + e->e2 = new IntegerExp(0); } - if (e1->isConst() == 1) - e = new IntegerExp(loc, e1->toInteger() << e2->toInteger(), type); + if (e->e1->isConst() == 1) + ex = (*shift)(e->type, e->e1, e->e2); } - return e; + return ex; +} + +Expression *ShlExp::optimize(int result) +{ + //printf("ShlExp::optimize(result = %d) %s\n", result, toChars()); + return shift_optimize(result, this, Shl); } Expression *ShrExp::optimize(int result) -{ Expression *e; - - e1 = e1->optimize(result); - e2 = e2->optimize(result); - - if (e1->isConst() == 1 && e2->isConst() == 1) - { - e = Shr(type, e1, e2); - } - else - e = this; - return e; +{ + //printf("ShrExp::optimize(result = %d) %s\n", result, toChars()); + return shift_optimize(result, this, Shr); } Expression *UshrExp::optimize(int result) -{ Expression *e; - - //printf("UshrExp::optimize() %s\n", toChars()); - e1 = e1->optimize(result); - e2 = e2->optimize(result); - - if (e1->isConst() == 1 && e2->isConst() == 1) - { - e = Ushr(type, e1, e2); - } - else - e = this; - return e; +{ + //printf("UshrExp::optimize(result = %d) %s\n", result, toChars()); + return shift_optimize(result, this, Ushr); } Expression *AndExp::optimize(int result) diff -r 4648206ca213 -r 3cfcb944304e dmd/parse.c --- a/dmd/parse.c Tue Oct 09 02:50:00 2007 +0200 +++ b/dmd/parse.c Tue Oct 09 06:21:30 2007 +0200 @@ -1835,7 +1835,6 @@ case TOKlparen: { Arguments *arguments; int varargs; - Type **pt; if (tpl) { @@ -1852,7 +1851,8 @@ } arguments = parseParameters(&varargs); - ta = new TypeFunction(arguments, t, varargs, linkage); + Type *ta = new TypeFunction(arguments, t, varargs, linkage); + Type **pt; for (pt = &ts; *pt != t; pt = &(*pt)->next) ; *pt = ta; diff -r 4648206ca213 -r 3cfcb944304e gen/runtime.c --- a/gen/runtime.c Tue Oct 09 02:50:00 2007 +0200 +++ b/gen/runtime.c Tue Oct 09 06:21:30 2007 +0200 @@ -18,6 +18,10 @@ Logger::println("*** Loading D runtime ***"); LOG_SCOPE; + if (!global.params.runtimeImppath) { + error("You must set the runtime import path with -E"); + fatal(); + } std::string filename(global.params.runtimeImppath); filename.append("/llvmdcore.bc"); llvm::MemoryBuffer* buffer = llvm::MemoryBuffer::getFile(filename.c_str(), filename.length()); diff -r 4648206ca213 -r 3cfcb944304e lphobos/internal/objectimpl.d --- a/lphobos/internal/objectimpl.d Tue Oct 09 02:50:00 2007 +0200 +++ b/lphobos/internal/objectimpl.d Tue Oct 09 06:21:30 2007 +0200 @@ -109,7 +109,7 @@ char[] toString() { //return this.classinfo.name; - return "classinfo.name not yet implemented"; + return "Object.toString: classinfo not yet implemented"; } /** @@ -135,9 +135,9 @@ // BUG: this prevents a compacting GC from working, needs to be fixed //return cast(int)cast(void *)this - cast(int)cast(void *)o; + assert(0, "need opCmp for class "); + return 0; //throw new Error("need opCmp for class " ~ this.classinfo.name); - assert(0); - return 0; } /** @@ -257,7 +257,6 @@ } } - /** * Information about an interface. * A pointer to this appears as the first entry in the interface's vtbl[]. @@ -342,7 +341,6 @@ TypeInfo ti; /// TypeInfo for this member } - /** * Runtime type information about a type. * Can be retrieved for any type using a @@ -1024,6 +1022,7 @@ assert(0); } } ++/ /** * All recoverable exceptions should be derived from class Exception. @@ -1042,7 +1041,8 @@ void print() { - printf("%.*s\n", toString()); + auto str = toString(); + printf("%.*s\n", str.length, str.ptr); } char[] toString() { return msg; } @@ -1071,5 +1071,3 @@ } //extern (C) int nullext = 0; - -+/ diff -r 4648206ca213 -r 3cfcb944304e premake.lua --- a/premake.lua Tue Oct 09 02:50:00 2007 +0200 +++ b/premake.lua Tue Oct 09 06:21:30 2007 +0200 @@ -1,5 +1,4 @@ project.name = llvmdc -project.bindir = "bin" package = newpackage() package.name = "idgen" @@ -7,7 +6,7 @@ package.language = "c++" package.files = { "dmd/idgen.c" } package.buildoptions = { "-x c++" } -package.postbuildcommands = { "bin/idgen", "mv -f id.c id.h dmd" } +package.postbuildcommands = { "./idgen", "mv -f id.c id.h dmd" } package = newpackage() package.name = "impcnvgen" @@ -15,9 +14,10 @@ package.language = "c++" package.files = { "dmd/impcnvgen.c" } package.buildoptions = { "-x c++" } -package.postbuildcommands = { "bin/impcnvgen", "mv -f impcnvtab.c dmd" } +package.postbuildcommands = { "./impcnvgen", "mv -f impcnvtab.c dmd" } package = newpackage() +package.bindir = "bin" package.name = "llvmdc" package.kind = "exe" package.language = "c++" diff -r 4648206ca213 -r 3cfcb944304e tester.sh --- a/tester.sh Tue Oct 09 02:50:00 2007 +0200 +++ b/tester.sh Tue Oct 09 06:21:30 2007 +0200 @@ -24,10 +24,10 @@ llvmdc $1 -Itest -odtest -c exit $? elif [ "$2" = "gdb" ]; then - gdb --args llvmdc $1 -Itest -odtest '-c' + gdb --args llvmdc $1 -Itest -odtest -c exit $? elif [ "$2" = "gdbrun" ]; then - llvmdc $1 -Itest -odtest '-c' && + llvmdc $1 -Itest -odtest -c && gdb $1 exit $? else