Mercurial > projects > ddmd
changeset 16:5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Sun, 04 Apr 2010 22:41:11 +0100 |
parents | da741eed6c00 |
children | ddae60498573 |
files | commands.linux.txt dmd/AggregateDeclaration.d dmd/AliasDeclaration.d dmd/Argument.d dmd/Declaration.d dmd/ExpStatement.d dmd/Expression.d dmd/File.d dmd/FileName.d dmd/Module.d dmd/Token.d dmd/Tuple.d dmd/TupleDeclaration.d dmd/TupleExp.d dmd/Type.d dmd/TypeExp.d dmd/TypeInstance.d dmd/TypeTuple.d dmd/Util.d dmd/VarDeclaration.d dmd/backend/Config.d dmd/backend/Cstate.d dmd/backend/LIST.d dmd/backend/OPER.d dmd/backend/RTLSYM.d dmd/backend/TYM.d dmd/backend/TYPE.d dmd/backend/glue.d dmd/expression/Add.d dmd/expression/Slice.d dmd/expression/Util.d |
diffstat | 31 files changed, 993 insertions(+), 300 deletions(-) [+] |
line wrap: on
line diff
--- a/commands.linux.txt Sun Apr 04 02:15:33 2010 +0100 +++ b/commands.linux.txt Sun Apr 04 22:41:11 2010 +0100 @@ -1,4 +1,4 @@ --g +-gc -debug -version=Bug3602 -version=Bug4054
--- a/dmd/AggregateDeclaration.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/AggregateDeclaration.d Sun Apr 04 22:41:11 2010 +0100 @@ -640,4 +640,4 @@ } AggregateDeclaration isAggregateDeclaration() { return this; } -} \ No newline at end of file +}
--- a/dmd/AliasDeclaration.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/AliasDeclaration.d Sun Apr 04 22:41:11 2010 +0100 @@ -20,49 +20,75 @@ class AliasDeclaration : Declaration { - Dsymbol aliassym; - Dsymbol overnext; // next in overload list - int inSemantic; + Dsymbol aliassym; + Dsymbol overnext; // next in overload list + int inSemantic; - this(Loc loc, Identifier ident, Type type) + this(Loc loc, Identifier ident, Type type) { super(ident); - + //printf("AliasDeclaration(id = '%s', type = %p)\n", id.toChars(), type); //printf("type = '%s'\n", type.toChars()); this.loc = loc; this.type = type; this.aliassym = null; - version (_DH) { - this.htype = null; - this.haliassym = null; - } + version (_DH) { + this.htype = null; + this.haliassym = null; + } assert(type); } - - this(Loc loc, Identifier id, Dsymbol s) + + this(Loc loc, Identifier id, Dsymbol s) { super(id); - + //printf("AliasDeclaration(id = '%s', s = %p)\n", id->toChars(), s); assert(s !is this); /// huh? this.loc = loc; this.type = null; this.aliassym = s; - version (_DH) { - this.htype = null; - this.haliassym = null; - } + version (_DH) { + this.htype = null; + this.haliassym = null; + } assert(s); } - - Dsymbol syntaxCopy(Dsymbol) + + Dsymbol syntaxCopy(Dsymbol s) { - assert(false); + //printf("AliasDeclaration::syntaxCopy()\n"); + assert(!s); + AliasDeclaration sa; + if (type) + sa = new AliasDeclaration(loc, ident, type.syntaxCopy()); + else + sa = new AliasDeclaration(loc, ident, aliassym.syntaxCopy(null)); +version (_DH) { + // Syntax copy for header file + if (!htype) // Don't overwrite original + { if (type) // Make copy for both old and new instances + { htype = type.syntaxCopy(); + sa.htype = type.syntaxCopy(); + } + } + else // Make copy of original for new instance + sa.htype = htype.syntaxCopy(); + if (!haliassym) + { if (aliassym) + { haliassym = aliassym.syntaxCopy(s); + sa.haliassym = aliassym.syntaxCopy(s); + } + } + else + sa.haliassym = haliassym.syntaxCopy(s); +} // version (_DH) + return sa; } - - void semantic(Scope sc) + + void semantic(Scope sc) { //printf("AliasDeclaration.semantic() %s\n", toChars()); if (aliassym) @@ -100,7 +126,7 @@ if (s && ((s.getType() && type.equals(s.getType())) || s.isEnumMember())) goto L2; // it's a symbolic alias -///version (DMDV2) { + ///version (DMDV2) { if (storage_class & STC.STCref) { // For 'ref' to be attached to function types, and picked // up by Type.resolve(), it has to go into sc. @@ -110,8 +136,8 @@ sc = sc.pop(); } else -/// #endif - type.resolve(loc, sc, &e, &t, &s); + /// #endif + type.resolve(loc, sc, &e, &t, &s); if (s) { goto L2; @@ -135,7 +161,7 @@ this.inSemantic = 0; return; - L2: +L2: //printf("alias is a symbol %s %s\n", s.kind(), s.toChars()); type = null; VarDeclaration v = s.isVarDeclaration(); @@ -171,8 +197,8 @@ aliassym = s; this.inSemantic = 0; } - - bool overloadInsert(Dsymbol s) + + bool overloadInsert(Dsymbol s) { /* Don't know yet what the aliased symbol is, so assume it can * be overloaded and check later for correctness. @@ -189,17 +215,17 @@ return overnext.overloadInsert(s); } } - - string kind() + + string kind() { return "alias"; } - - Type getType() + + Type getType() { return type; } - + Dsymbol toAlias() { //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : ""); @@ -214,20 +240,20 @@ Dsymbol s = aliassym ? aliassym.toAlias() : this; return s; } - - void toCBuffer(OutBuffer buf, HdrGenState* hgs) - { - assert(false); - } - -version (_DH) { - Type htype; - Dsymbol haliassym; -} - void toDocBuffer(OutBuffer buf) + + void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - AliasDeclaration isAliasDeclaration() { return this; } -} \ No newline at end of file + version (_DH) { + Type htype; + Dsymbol haliassym; + } + void toDocBuffer(OutBuffer buf) + { + assert(false); + } + + AliasDeclaration isAliasDeclaration() { return this; } + }
--- a/dmd/Argument.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/Argument.d Sun Apr 04 22:41:11 2010 +0100 @@ -107,7 +107,7 @@ buf.writeByte('('); if (args) { - OutBuffer argbuf; + OutBuffer argbuf = new OutBuffer(); HdrGenState hgs; for (int i = 0; i < args.dim; i++) @@ -275,4 +275,4 @@ return null; } -} \ No newline at end of file +}
--- a/dmd/Declaration.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/Declaration.d Sun Apr 04 22:41:11 2010 +0100 @@ -90,7 +90,6 @@ void semantic(Scope sc) { - assert(false); } string kind()
--- a/dmd/ExpStatement.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/ExpStatement.d Sun Apr 04 22:41:11 2010 +0100 @@ -15,6 +15,7 @@ import dmd.BE; import dmd.TOK; import dmd.DeclarationStatement; +import dmd.Util : printf; import dmd.backend.Blockx; import dmd.backend.Util; @@ -122,4 +123,4 @@ if (exp) block_appendexp(blx.curblock, exp.toElem(irs)); } -} \ No newline at end of file +}
--- a/dmd/Expression.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/Expression.d Sun Apr 04 22:41:11 2010 +0100 @@ -906,4 +906,4 @@ { assert(false); } -} \ No newline at end of file +}
--- a/dmd/File.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/File.d Sun Apr 04 22:41:11 2010 +0100 @@ -86,7 +86,8 @@ int fd = open(toStringz(name), O_RDONLY); if (fd == -1) { result = errno; - //printf("\topen error, errno = %d\n", errno); + printf("file: %s\n", toStringz(name)); + printf("\topen error, errno = %d\n", errno); goto err1; }
--- a/dmd/FileName.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/FileName.d Sun Apr 04 22:41:11 2010 +0100 @@ -504,7 +504,32 @@ return null; } - + + static string searchPath(string[] path, string name, bool cwd) + { + if (absolute(name)) { + return exists(name) ? name : null; + } + + if (cwd) { + if (exists(name)) { + return name; + } + } + + if (path !is null) { + foreach (i, p; path) + { + string n = combine(p, name); + + if (exists(n)) + return n; + } + } + + return null; + } + static int exists(string name) { version (POSIX) {
--- a/dmd/Module.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/Module.d Sun Apr 04 22:41:11 2010 +0100 @@ -456,7 +456,7 @@ le = 1; Lutf32: - OutBuffer dbuf; + OutBuffer dbuf = new OutBuffer(); uint* pu = cast(uint*)buf; uint* pumax = &pu[buflen / 4]; @@ -491,7 +491,7 @@ le = 1; Lutf16: - OutBuffer dbuf; + OutBuffer dbuf = new OutBuffer(); ushort* pu = cast(ushort*)(buf); ushort *pumax = &pu[buflen / 2];
--- a/dmd/Token.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/Token.d Sun Apr 04 22:41:11 2010 +0100 @@ -136,7 +136,7 @@ version (CSTRINGS) { p = string; } else { - { OutBuffer buf; + { OutBuffer buf = new OutBuffer(); buf.writeByte('"'); for (size_t i = 0; i < len; ) @@ -212,4 +212,4 @@ return p; } -} \ No newline at end of file +}
--- a/dmd/Tuple.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/Tuple.d Sun Apr 04 22:41:11 2010 +0100 @@ -2,13 +2,18 @@ import dmd.ArrayTypes; -class Tuple -{ - Objects objects; - - int dyncast() - { - assert(false); - } -} - +class Tuple +{ + Objects objects; + + this() + { + objects = new Objects; + } + + int dyncast() + { + assert(false); + } +} +
--- a/dmd/TupleDeclaration.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/TupleDeclaration.d Sun Apr 04 22:41:11 2010 +0100 @@ -1,45 +1,113 @@ module dmd.TupleDeclaration; import dmd.Declaration; +import dmd.Argument; import dmd.ArrayTypes; import dmd.TypeTuple; import dmd.Loc; +import dmd.STC; +import dmd.TOK; import dmd.Identifier; import dmd.Dsymbol; import dmd.Type; +import dmd.DYNCAST; +import dmd.OutBuffer; +import dmd.Expression; +import dmd.DsymbolExp; class TupleDeclaration : Declaration { - Objects objects; - int isexp; // 1: expression tuple + Objects objects; + int isexp; // 1: expression tuple - TypeTuple tupletype; // !=NULL if this is a type tuple + TypeTuple tupletype; // !=NULL if this is a type tuple - this(Loc loc, Identifier ident, Objects objects) + this(Loc loc, Identifier ident, Objects objects) { - assert(false); super(ident); + type = null; + this.objects = objects; + isexp = 0; + tupletype = null; } - Dsymbol syntaxCopy(Dsymbol) - { - assert(false); - } - - string kind() + Dsymbol syntaxCopy(Dsymbol) { assert(false); } - Type getType() + string kind() { - assert(false); + return "tuple"; } - - bool needThis() + + Type getType() { - assert(false); + /* If this tuple represents a type, return that type + */ + + //printf("TupleDeclaration::getType() %s\n", toChars()); + if (isexp) + return null; + if (!tupletype) + { + /* It's only a type tuple if all the Object's are types + */ + for (size_t i = 0; i < objects.dim; i++) + { Dsymbol o = cast(Dsymbol)objects.data[i]; + + if (o.dyncast() != DYNCAST.DYNCAST_TYPE) + { + //printf("\tnot[%d], %p, %d\n", i, o, o->dyncast()); + return null; + } + } + + /* We know it's a type tuple, so build the TypeTuple + */ + Arguments args = new Arguments(); + args.setDim(objects.dim); + OutBuffer buf = new OutBuffer(); + for (size_t i = 0; i < objects.dim; i++) + { Type t = cast(Type)objects.data[i]; + + //printf("type = %s\n", t->toChars()); + static if (0) { + buf.printf("_%s_%d", ident.toChars(), i); + char *name = cast(char *)buf.extractData(); + Identifier id = new Identifier(name, TOKidentifier); + Argument arg = new Argument(STCin, t, id, null); + } else { + Argument arg = new Argument(STCundefined, t, null, null); + } + args.data[i] = cast(void *)arg; + } + + tupletype = new TypeTuple(args); + } + + return tupletype; } - - TupleDeclaration isTupleDeclaration() { return this; } -}; \ No newline at end of file + + bool needThis() + { + //printf("TupleDeclaration::needThis(%s)\n", toChars()); + for (size_t i = 0; i < objects.dim; i++) + { Dsymbol o = cast(Dsymbol)objects.data[i]; + if (o.dyncast() == DYNCAST.DYNCAST_EXPRESSION) + { Expression e = cast(Expression)o; + if (e.op == TOKdsymbol) + { DsymbolExp ve = cast(DsymbolExp)e; + Declaration d = ve.s.isDeclaration(); + if (d && d.needThis()) + { + return 1; + } + } + } + } + return 0; + } + + TupleDeclaration isTupleDeclaration() { return this; } +}
--- a/dmd/TupleExp.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/TupleExp.d Sun Apr 04 22:41:11 2010 +0100 @@ -14,97 +14,236 @@ import dmd.HdrGenState; import dmd.InlineScanState; import dmd.ArrayTypes; +import dmd.TypeExp; +import dmd.TypeTuple; import dmd.TOK; +import dmd.TY; +import dmd.Dsymbol; +import dmd.DsymbolExp; +import dmd.DYNCAST; +import dmd.expression.Util; + +/**************************************** + * Expand tuples. + */ +/+ +void expandTuples(Expressions exps) +{ + //printf("expandTuples()\n"); + if (exps) + { + for (size_t i = 0; i < exps.dim; i++) + { Expression arg = cast(Expression)exps.data[i]; + if (!arg) + continue; + + // Look for tuple with 0 members + if (arg.op == TOKtype) + { TypeExp e = cast(TypeExp)arg; + if (e.type.toBasetype().ty == Ttuple) + { TypeTuple tt = cast(TypeTuple)e.type.toBasetype(); + + if (!tt.arguments || tt.arguments.dim == 0) + { + exps.remove(i); + if (i == exps.dim) + return; + i--; + continue; + } + } + } + + // Inline expand all the tuples + while (arg.op == TOKtuple) + { TupleExp te = cast(TupleExp)arg; + + exps.remove(i); // remove arg + exps.insert(i, te.exps); // replace with tuple contents + if (i == exps.dim) + return; // empty tuple, no more arguments + arg = cast(Expression)exps.data[i]; + } + } + } +} ++/ +class TupleExp : Expression +{ + Expressions exps; + + this(Loc loc, Expressions exps) + { + super(Loc(0), TOK.init, this.sizeof); + this.exps = exps; + this.type = null; + } + + this(Loc loc, TupleDeclaration tup) + { + super(Loc(0), TOK.init, this.sizeof); + exps = new Expressions(); + type = null; -class TupleExp : Expression -{ - Expressions exps; - - this(Loc loc, Expressions exps) - { - assert(false); - super(Loc(0), TOK.init, 0); - } - - this(Loc loc, TupleDeclaration tup) - { + exps.reserve(tup.objects.dim); + for (size_t i = 0; i < tup.objects.dim; i++) + { Dsymbol o = cast(Dsymbol)tup.objects.data[i]; + if (o.dyncast() == DYNCAST.DYNCAST_EXPRESSION) + { + Expression e = cast(Expression)o; + e = e.syntaxCopy(); + exps.push(cast(void*)e); + } + else if (o.dyncast() == DYNCAST.DYNCAST_DSYMBOL) + { + Dsymbol s = cast(Dsymbol)o; + Expression e = new DsymbolExp(loc, s); + exps.push(cast(void*)e); + } + else if (o.dyncast() == DYNCAST.DYNCAST_TYPE) + { + Type t = cast(Type)o; + Expression e = new TypeExp(loc, t); + exps.push(cast(void*)e); + } + else + { + error("%s is not an expression", o.toChars()); + } + } + } + + Expression syntaxCopy() + { + return new TupleExp(loc, arraySyntaxCopy(exps)); + } + + int equals(Object o) + { + TupleExp ne; + + if (this == o) + return 1; + if ((cast(Expression)o).op == TOKtuple) + { + TupleExp te = cast(TupleExp)o; + if (exps.dim != te.exps.dim) + return 0; + for (size_t i = 0; i < exps.dim; i++) + { Expression e1 = cast(Expression)exps.data[i]; + Expression e2 = cast(Expression)te.exps.data[i]; + + if (!e1.equals(e2)) + return 0; + } + return 1; + } + return 0; + } + + Expression semantic(Scope sc) + { + version (LOGSEMANTIC) { + printf("+TupleExp::semantic(%s)\n", toChars()); + } + if (type) + return this; + + // Run semantic() on each argument + for (size_t i = 0; i < exps.dim; i++) + { Expression e = cast(Expression)exps.data[i]; + + e = e.semantic(sc); + if (!e.type) + { error("%s has no value", e.toChars()); + e.type = Type.terror; + } + exps.data[i] = cast(void *)e; + } + + expandTuples(exps); + if (0 && exps.dim == 1) + { + return cast(Expression)exps.data[0]; + } + type = new TypeTuple(exps); + type = type.semantic(loc, sc); + //printf("-TupleExp::semantic(%s)\n", toChars()); + return this; + } + + void toCBuffer(OutBuffer buf, HdrGenState* hgs) + { + buf.writestring("tuple("); + argsToCBuffer(buf, exps, hgs); + buf.writeByte(')'); + } + + void scanForNestedRef(Scope sc) + { assert(false); - super(Loc(0), TOK.init, 0); - } - - Expression syntaxCopy() - { - assert(false); - } - - int equals(Object o) - { - assert(false); - } - - Expression semantic(Scope sc) - { - assert(false); - } - - void toCBuffer(OutBuffer buf, HdrGenState* hgs) - { - assert(false); - } - - void scanForNestedRef(Scope sc) - { - assert(false); - } - - void checkEscape() - { - assert(false); - } - - bool checkSideEffect(int flag) - { - assert(false); - } - - Expression optimize(int result) - { - assert(false); - } - - Expression interpret(InterState* istate) - { - assert(false); - } - - Expression castTo(Scope sc, Type t) - { - assert(false); - } - - elem* toElem(IRState* irs) - { - assert(false); - } - - bool canThrow() - { - assert(false); - } - - int inlineCost(InlineCostState* ics) - { - assert(false); - } - - Expression doInline(InlineDoState ids) - { - assert(false); - } - - Expression inlineScan(InlineScanState* iss) - { - assert(false); - } -} - + } + + void checkEscape() + { + for (size_t i = 0; i < exps.dim; i++) + { Expression e = cast(Expression)exps.data[i]; + e.checkEscape(); + } + } + + bool checkSideEffect(int flag) + { + bool f = false; + + for (int i = 0; i < exps.dim; i++) + { Expression e = cast(Expression)exps.data[i]; + + f |= e.checkSideEffect(2); + } + if (flag == 0 && f == 0) + Expression.checkSideEffect(0); + return f; + } + + Expression optimize(int result) + { + assert(false); + } + + Expression interpret(InterState* istate) + { + assert(false); + } + + Expression castTo(Scope sc, Type t) + { + assert(false); + } + + elem* toElem(IRState* irs) + { + assert(false); + } + + bool canThrow() + { + return arrayExpressionCanThrow(exps); + } + + int inlineCost(InlineCostState* ics) + { + assert(false); + } + + Expression doInline(InlineDoState ids) + { + assert(false); + } + + Expression inlineScan(InlineScanState* iss) + { + assert(false); + } +} +
--- a/dmd/Type.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/Type.d Sun Apr 04 22:41:11 2010 +0100 @@ -713,7 +713,7 @@ * flag 0x100 do not do const/invariant */ void toDecoBuffer(OutBuffer buf, int flag = 0) - { + { if( buf is null )asm { int 3; } if (flag != mod && flag != 0x100) { if (mod & MOD.MODshared)
--- a/dmd/TypeExp.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/TypeExp.d Sun Apr 04 22:41:11 2010 +0100 @@ -46,7 +46,7 @@ void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - assert(false); + type.toCBuffer(buf, null, hgs); } Expression optimize(int result)
--- a/dmd/TypeInstance.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/TypeInstance.d Sun Apr 04 22:41:11 2010 +0100 @@ -1,7 +1,14 @@ module dmd.TypeInstance; import dmd.TypeQualified; +import dmd.TemplateAliasParameter; +import dmd.TemplateDeclaration; import dmd.TemplateInstance; +import dmd.TemplateParameter; +import dmd.TemplateValueParameter; +import dmd.TemplateTupleParameter; +import dmd.Tuple; +import dmd.VarExp; import dmd.MOD; import dmd.MATCH; import dmd.Loc; @@ -13,43 +20,56 @@ import dmd.Expression; import dmd.Scope; import dmd.ArrayTypes; +import dmd.TOK; import dmd.TY; +import dmd.Util : printf; /* Similar to TypeIdentifier, but with a TemplateInstance as the root */ class TypeInstance : TypeQualified { - TemplateInstance tempinst; + TemplateInstance tempinst; - this(Loc loc, TemplateInstance tempinst) + this(Loc loc, TemplateInstance tempinst) { super(Tinstance, loc); this.tempinst = tempinst; } - -version (DumbClone) { -} else { - Type clone() - { - assert(false); + + version (DumbClone) { + } else { + Type clone() + { + assert(false); + } } -} - - Type syntaxCopy() + + Type syntaxCopy() { - assert(false); + //printf("TypeInstance::syntaxCopy() %s, %d\n", toChars(), idents.dim); + TypeInstance t; + + t = new TypeInstance(loc, cast(TemplateInstance)tempinst.syntaxCopy(null)); + t.syntaxCopyHelper(this); + t.mod = mod; + return t; } - - //char *toChars(); - - //void toDecoBuffer(OutBuffer *buf, int flag); - - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + + //char *toChars(); + + //void toDecoBuffer(OutBuffer *buf, int flag); + + void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { - assert(false); + if (mod != this.mod) + { toCBuffer3(buf, hgs, mod); + return; + } + tempinst.toCBuffer(buf, hgs); + toCBuffer2Helper(buf, hgs); } - - void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) + + void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) { // Note close similarity to TypeIdentifier::resolve() Dsymbol s; @@ -58,13 +78,13 @@ *pt = null; *ps = null; - static if (false) { - if (!idents.dim) - { - error(loc, "template instance '%s' has no identifier", toChars()); - return; + static if (false) { + if (!idents.dim) + { + error(loc, "template instance '%s' has no identifier", toChars()); + return; + } } - } //id = (Identifier *)idents.data[0]; //printf("TypeInstance::resolve(sc = %p, idents = '%s')\n", sc, id->toChars()); s = tempinst; @@ -75,13 +95,42 @@ *pt = (*pt).addMod(mod); //printf("pt = '%s'\n", (*pt)->toChars()); } - - Type semantic(Loc loc, Scope sc) + + Type semantic(Loc loc, Scope sc) { - assert(false); + Type t; + Expression e; + Dsymbol s; + + //printf("TypeInstance::semantic(%s)\n", toChars()); + + if (sc.parameterSpecialization) + { + uint errors = global.errors; + global.gag++; + + resolve(loc, sc, &e, &t, &s); + + global.gag--; + if (errors != global.errors) + { if (global.gag == 0) + global.errors = errors; + return this; + } + } + else + resolve(loc, sc, &e, &t, &s); + + if (!t) + { + debug printf("2: "); + error(loc, "%s is used as a type", toChars()); + t = tvoid; + } + return t; } - - Dsymbol toDsymbol(Scope sc) + + Dsymbol toDsymbol(Scope sc) { Type t; Expression e; @@ -110,9 +159,225 @@ return s; } - - MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) + + MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) { - assert(false); +static if (0) { + printf("TypeInstance::deduceType()\n"); + printf("\tthis = %d, ", ty); print(); + printf("\ttparam = %d, ", tparam.ty); tparam.print(); +} + + // Extra check + if (tparam && tparam.ty == Tinstance) + { + TypeInstance tp = cast(TypeInstance)tparam; + + //printf("tempinst->tempdecl = %p\n", tempinst->tempdecl); + //printf("tp->tempinst->tempdecl = %p\n", tp->tempinst->tempdecl); + if (!tp.tempinst.tempdecl) + { //printf("tp->tempinst->name = '%s'\n", tp->tempinst->name->toChars()); + if (!tp.tempinst.name.equals(tempinst.name)) + { + /* Handle case of: + * template Foo(T : sa!(T), alias sa) + */ + int i = templateIdentifierLookup(tp.tempinst.name, parameters); + if (i == -1) + { /* Didn't find it as a parameter identifier. Try looking + * it up and seeing if is an alias. See Bugzilla 1454 + */ + Dsymbol s = tempinst.tempdecl.scope_.search(Loc(0), tp.tempinst.name, null); + if (s) + { + s = s.toAlias(); + TemplateDeclaration td = s.isTemplateDeclaration(); + if (td && td == tempinst.tempdecl) + goto L2; + } + goto Lnomatch; + } + TemplateParameter tpx = cast(TemplateParameter)parameters.data[i]; + // This logic duplicates tpx->matchArg() + TemplateAliasParameter ta = tpx.isTemplateAliasParameter(); + if (!ta) + goto Lnomatch; + Object sa = tempinst.tempdecl; + if (!sa) + goto Lnomatch; + if (ta.specAlias && sa != ta.specAlias) + goto Lnomatch; + if (dedtypes.data[i]) + { // Must match already deduced symbol + Object s = cast(Object)dedtypes.data[i]; + + if (s != sa) + goto Lnomatch; + } + dedtypes.data[i] = cast(void*)sa; + } + } + else if (tempinst.tempdecl != tp.tempinst.tempdecl) + goto Lnomatch; + +L2: + + for (int i = 0; 1; i++) + { + //printf("\ttest: tempinst->tiargs[%d]\n", i); + Object o1; + if (i < tempinst.tiargs.dim) + o1 = cast(Object)tempinst.tiargs.data[i]; + else if (i < tempinst.tdtypes.dim && i < tp.tempinst.tiargs.dim) + // Pick up default arg + o1 = cast(Object)tempinst.tdtypes.data[i]; + else + break; + + if (i >= tp.tempinst.tiargs.dim) + goto Lnomatch; + + Object o2 = cast(Object)tp.tempinst.tiargs.data[i]; + + Type t1 = isType(o1); + Type t2 = isType(o2); + + Expression e1 = isExpression(o1); + Expression e2 = isExpression(o2); + + Dsymbol s1 = isDsymbol(o1); + Dsymbol s2 = isDsymbol(o2); + + Tuple v1 = isTuple(o1); + Tuple v2 = isTuple(o2); +static if (0) { + if (t1) printf("t1 = %s\n", t1.toChars()); + if (t2) printf("t2 = %s\n", t2.toChars()); + if (e1) printf("e1 = %s\n", e1.toChars()); + if (e2) printf("e2 = %s\n", e2.toChars()); + if (s1) printf("s1 = %s\n", s1.toChars()); + if (s2) printf("s2 = %s\n", s2.toChars()); + if (v1) printf("v1 = %s\n", v1.toChars()); + if (v2) printf("v2 = %s\n", v2.toChars()); +} + + TemplateTupleParameter ttp; + int j; + if (t2 && + t2.ty == Tident && + i == tp.tempinst.tiargs.dim - 1 && + i == tempinst.tempdecl.parameters.dim - 1 && + (ttp = tempinst.tempdecl.isVariadic()) !is null) + { + /* Given: + * struct A(B...) {} + * alias A!(int, float) X; + * static if (!is(X Y == A!(Z), Z)) + * deduce that Z is a tuple(int, float) + */ + + j = templateParameterLookup(t2, parameters); + if (j == -1) + goto Lnomatch; + + /* Create tuple from remaining args + */ + Tuple vt = new Tuple(); + int vtdim = tempinst.tiargs.dim - i; + vt.objects.setDim(vtdim); + for (size_t k = 0; k < vtdim; k++) + vt.objects.data[k] = cast(void *)tempinst.tiargs.data[i + k]; + + Tuple v = cast(Tuple)dedtypes.data[j]; + if (v) + { + if (!match(v, vt, tempinst.tempdecl, sc)) + goto Lnomatch; + } + else + dedtypes.data[j] = cast(void*)vt; + break; //return MATCHexact; + } + + if (t1 && t2) + { + if (!t1.deduceType(sc, t2, parameters, dedtypes)) + goto Lnomatch; + } + else if (e1 && e2) + { + if (!e1.equals(e2)) + { if (e2.op == TOKvar) + { + /* + * (T:Number!(e2), int e2) + */ + j = templateIdentifierLookup((cast(VarExp)e2).var.ident, parameters); + goto L1; + } + goto Lnomatch; + } + } + else if (e1 && t2 && t2.ty == Tident) + { + j = templateParameterLookup(t2, parameters); +L1: + if (j == -1) + goto Lnomatch; + TemplateParameter tp_ = cast(TemplateParameter)parameters.data[j]; + // BUG: use tp->matchArg() instead of the following + TemplateValueParameter tv = tp_.isTemplateValueParameter(); + if (!tv) + goto Lnomatch; + Expression e = cast(Expression)dedtypes.data[j]; + if (e) + { + if (!e1.equals(e)) + goto Lnomatch; + } + else + { Type vt = tv.valType.semantic(Loc(0), sc); + MATCH m = cast(MATCH)e1.implicitConvTo(vt); + if (!m) + goto Lnomatch; + dedtypes.data[j] = cast(void*)e1; + } + } + else if (s1 && t2 && t2.ty == Tident) + { + j = templateParameterLookup(t2, parameters); + if (j == -1) + goto Lnomatch; + TemplateParameter tp_ = cast(TemplateParameter)parameters.data[j]; + // BUG: use tp->matchArg() instead of the following + TemplateAliasParameter ta = tp_.isTemplateAliasParameter(); + if (!ta) + goto Lnomatch; + Dsymbol s = cast(Dsymbol)dedtypes.data[j]; + if (s) + { + if (!s1.equals(s)) + goto Lnomatch; + } + else + { + dedtypes.data[j] = cast(void*)s1; + } + } + else if (s1 && s2) + { + if (!s1.equals(s2)) + goto Lnomatch; + } + // BUG: Need to handle tuple parameters + else + goto Lnomatch; + } + } + return Type.deduceType(sc, tparam, parameters, dedtypes); + +Lnomatch: + //printf("no match\n"); + return MATCHnomatch; } -} \ No newline at end of file +}
--- a/dmd/TypeTuple.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/TypeTuple.d Sun Apr 04 22:41:11 2010 +0100 @@ -11,68 +11,165 @@ import dmd.HdrGenState; import dmd.Scope; import dmd.TY; +import dmd.Id; +import dmd.STC; +import dmd.Argument; +import dmd.ErrorExp; +import dmd.IntegerExp; class TypeTuple : Type { - Arguments arguments; // types making up the tuple + Arguments arguments; // types making up the tuple + + this(Arguments arguments) + { + super(TY.Ttuple); + //printf("TypeTuple(this = %p)\n", this); + this.arguments = arguments; + //printf("TypeTuple() %s\n", toChars()); + debug { + if (arguments) + { + for (size_t i = 0; i < arguments.dim; i++) + { + Argument arg = cast(Argument)arguments.data[i]; + assert(arg && arg.type); + } + } + } + } + + version (DumbClone) { + } else { + Type clone() + { + assert(false); + } + } - this(Arguments arguments) + /**************** + * Form TypeTuple from the types of the expressions. + * Assume exps[] is already tuple expanded. + */ + this(Expressions exps) + { + super(TY.Ttuple); + Arguments arguments = new Arguments; + if (exps) + { + arguments.setDim(exps.dim); + for (size_t i = 0; i < exps.dim; i++) + { Expression e = cast(Expression)exps.data[i]; + if (e.type.ty == Ttuple) + e.error("cannot form tuple of tuples"); + Argument arg = new Argument(STCundefined, e.type, null, null); + arguments.data[i] = cast(void *)arg; + } + } + this.arguments = arguments; + } + + Type syntaxCopy() + { + Arguments args = Argument.arraySyntaxCopy(arguments); + Type t = new TypeTuple(args); + t.mod = mod; + return t; + } + + Type semantic(Loc loc, Scope sc) + { + //printf("TypeTuple::semantic(this = %p)\n", this); + //printf("TypeTuple::semantic() %s\n", toChars()); + if (!deco) + deco = merge().deco; + + /* Don't return merge(), because a tuple with one type has the + * same deco as that type. + */ + return this; + } + + int equals(Object o) { - assert(false); - super(TY.init); + Type t; + + t = cast(Type)o; + //printf("TypeTuple::equals(%s, %s)\n", toChars(), t-cast>toChars()); + if (this == t) + { + return 1; + } + if (t.ty == Ttuple) + { TypeTuple tt = cast(TypeTuple)t; + + if (arguments.dim == tt.arguments.dim) + { + for (size_t i = 0; i < tt.arguments.dim; i++) + { Argument arg1 = cast(Argument)arguments.data[i]; + Argument arg2 = cast(Argument)tt.arguments.data[i]; + + if (!arg1.type.equals(arg2.type)) + return 0; + } + return 1; + } + } + return 0; } - -version (DumbClone) { -} else { - Type clone() + + Type reliesOnTident() + { + if (arguments) + { + for (size_t i = 0; i < arguments.dim; i++) + { + Argument arg = cast(Argument)arguments.data[i]; + Type t = arg.type.reliesOnTident(); + if (t) + return t; + } + } + return null; + } + + void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + { + Argument.argsToCBuffer(buf, hgs, arguments, 0); + } + + void toDecoBuffer(OutBuffer buf, int flag) + { + //printf("TypeTuple::toDecoBuffer() this = %p, %s\n", this, toChars()); + Type.toDecoBuffer(buf, flag); + OutBuffer buf2 = new OutBuffer(); + Argument.argsToDecoBuffer(buf2, arguments); + uint len = buf2.offset; + //buf.printf("%d%.*s", len, len, cast(char *)buf2.extractData()); + buf.printf("%d%s", len, buf2.extractString()); + } + + Expression getProperty(Loc loc, Identifier ident) + { + Expression e; + + version (LOGDOTEXP) { + printf("TypeTuple::getProperty(type = '%s', ident = '%s')\n", toChars(), ident.toChars()); + } + if (ident == Id.length) + { + e = new IntegerExp(loc, arguments.dim, Type.tsize_t); + } + else + { + error(loc, "no property '%s' for tuple '%s'", ident.toChars(), toChars()); + e = new ErrorExp(); + } + return e; + } + + TypeInfoDeclaration getTypeInfoDeclaration() { assert(false); } } - - this(Expressions exps) - { - assert(false); - super(TY.init); - } - - Type syntaxCopy() - { - assert(false); - } - - Type semantic(Loc loc, Scope sc) - { - assert(false); - } - - int equals(Object *o) - { - assert(false); - } - - Type reliesOnTident() - { - assert(false); - } - - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) - { - assert(false); - } - - void toDecoBuffer(OutBuffer buf, int flag) - { - assert(false); - } - - Expression getProperty(Loc loc, Identifier ident) - { - assert(false); - } - - TypeInfoDeclaration getTypeInfoDeclaration() - { - assert(false); - } -} \ No newline at end of file
--- a/dmd/Util.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/Util.d Sun Apr 04 22:41:11 2010 +0100 @@ -20,16 +20,36 @@ import core.stdc.stdlib; import core.stdc.ctype; import core.stdc.stdarg; -import core.stdc.stdio; +public import core.stdc.stdio; version (Bug4054) import core.memory; extern(C) int putenv(char*); +/+version (LOG) +{ + static if( !is(typeof(printf)) ) + extern (C) int printf(const char*,...); +}+/ +//version = LOG; -//version = LOG; +version (TARGET_OSX) +{ + version = TARGET_FOS; // FreeBSD, OS X, Solaris +} +version (TARGET_FREEBSD) +{ + version = TARGET_FOS; // FreeBSD, OS X, Solaris +} +version (TARGET_SOLARIS) +{ + version = TARGET_FOS; // FreeBSD, OS X, Solaris +} version (POSIX) { + import dmd.Array; import dmd.Gnuc; + import core.sys.posix.stdlib; + version (TARGET_FOS) import core.stdc.limits; } enum MAX_PATH = 256; /// @@ -140,20 +160,20 @@ } filename = FileName.replaceName(argv0, inifile); if (!FileName.exists(filename)) { -version (XXX) { /// linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 - version (XXX) { /// __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 // This fix by Thomas Kuehne +version (POSIX) { /// linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 + version (POSIX) { /// __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 // This fix by Thomas Kuehne /* argv0 might be a symbolic link, * so try again looking past it to the real path */ - version (XXX) {/// #if __APPLE__ || __FreeBSD__ || __sun&&__SVR4 + version (TARGET_FOS) {/// #if __APPLE__ || __FreeBSD__ || __sun&&__SVR4 char resolved_name[PATH_MAX + 1]; - char* real_argv0 = realpath(argv0, resolved_name); + char* real_argv0 = realpath(toStringz(argv0), resolved_name); } else { - char* real_argv0 = realpath(argv0, null); + char* real_argv0 = realpath(toStringz(argv0), null); } //printf("argv0 = %s, real_argv0 = %p\n", argv0, real_argv0); if (real_argv0) { - filename = FileName.replaceName(real_argv0, inifile); + filename = FileName.replaceName(fromStringz(real_argv0), inifile); version (linux) { ///free(real_argv0); } @@ -166,11 +186,11 @@ } if (true) { // Search PATH for argv0 - const(char)* p = getenv("PATH"); + const(char)* p = toStringz(getenv("PATH")); version (LOG) { writef("\tPATH='%s'\n", p); } - Array paths = FileName.splitPath(p); + auto paths = FileName.splitPath(fromStringz(p)); filename = FileName.searchPath(paths, argv0, 0); if (!filename) { goto Letc; // argv0 not found on path
--- a/dmd/VarDeclaration.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/VarDeclaration.d Sun Apr 04 22:41:11 2010 +0100 @@ -245,7 +245,7 @@ for (size_t i = 0; i < nelems; i++) { Argument arg = Argument.getNth(tt.arguments, i); - OutBuffer buf; + OutBuffer buf = new OutBuffer(); buf.printf("_%s_field_%zu", ident.toChars(), i); buf.writeByte(0); string name = buf.extractString(); @@ -1185,4 +1185,4 @@ // Eliminate need for dynamic_cast VarDeclaration isVarDeclaration() { return this; } -} \ No newline at end of file +}
--- a/dmd/backend/Config.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/backend/Config.d Sun Apr 04 22:41:11 2010 +0100 @@ -8,7 +8,7 @@ void cod3_set386(); } -debug extern (C) /+extern+/ +debug extern (C) extern { __gshared char debuga; /* cg - watch assignaddr() */ __gshared char debugb; /* watch block optimization */ @@ -192,7 +192,7 @@ LINKAGE linkage; // default function call linkage } -extern (C) /+extern+/ __gshared Config config; +extern (C) extern __gshared Config config; enum CVNONE = 0; // No symbolic info ///enum CVOLD = 1; // Codeview 1 symbolic info
--- a/dmd/backend/Cstate.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/backend/Cstate.d Sun Apr 04 22:41:11 2010 +0100 @@ -18,4 +18,4 @@ char* modname; // module unique identifier } -extern (C++) /+extern+/ __gshared Cstate cstate; +extern (C) extern __gshared Cstate cstate;
--- a/dmd/backend/LIST.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/backend/LIST.d Sun Apr 04 22:41:11 2010 +0100 @@ -1,1 +1,26 @@ -module dmd.backend.LIST; import dmd.backend.Symbol; struct LIST { /* Do not access items in this struct directly, use the */ /* functions designed for that purpose. */ LIST* next; /* next element in list */ int count; /* when 0, element may be deleted */ union { void *ptr; /* data pointer */ int data; } } alias LIST* list_t; /* pointer to a list entry */ alias list_t symlist_t; /* pointer to a list entry */ extern (C++) extern { __gshared list_t slist; list_t list_prepend(list_t* plist, void* ptr); void slist_add(Symbol* s); } \ No newline at end of file +module dmd.backend.LIST; + +import dmd.backend.Symbol; + +struct LIST +{ + /* Do not access items in this struct directly, use the */ + /* functions designed for that purpose. */ + LIST* next; /* next element in list */ + int count; /* when 0, element may be deleted */ + + union + { + void *ptr; /* data pointer */ + int data; + } +} + +alias LIST* list_t; /* pointer to a list entry */ +alias list_t symlist_t; /* pointer to a list entry */ + +extern (C++) extern { + extern(C) extern __gshared list_t slist; + list_t list_prepend(list_t* plist, void* ptr); + void slist_add(Symbol* s); +}
--- a/dmd/backend/OPER.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/backend/OPER.d Sun Apr 04 22:41:11 2010 +0100 @@ -291,10 +291,10 @@ } else { - extern(C++) __gshared const ubyte[OPER.OPMAX] optab1; - extern(C++) __gshared const ubyte[OPER.OPMAX] optab2; - extern(C++) __gshared const ubyte[OPER.OPMAX] optab3; - extern(C++) __gshared const ubyte[OPER.OPMAX] opcost; + extern(C) extern __gshared const ubyte[OPER.OPMAX] optab1; + extern(C) extern __gshared const ubyte[OPER.OPMAX] optab2; + extern(C) extern __gshared const ubyte[OPER.OPMAX] optab3; + extern(C) extern __gshared const ubyte[OPER.OPMAX] opcost; } enum _OT
--- a/dmd/backend/RTLSYM.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/backend/RTLSYM.d Sun Apr 04 22:41:11 2010 +0100 @@ -99,4 +99,4 @@ mixin(BringToCurrentScope!(RTLSYM)); //extern(C++) extern __gshared Symbol* rtlsym[RTLSYM.RTLSYM_MAX]; -extern(C++) __gshared Symbol* rtlsym[RTLSYM.RTLSYM_MAX]; +extern(C) extern __gshared Symbol* rtlsym[RTLSYM.RTLSYM_MAX];
--- a/dmd/backend/TYM.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/backend/TYM.d Sun Apr 04 22:41:11 2010 +0100 @@ -76,7 +76,7 @@ ///#endif } -extern (C++) /+extern+/ { +extern (C) extern { __gshared int TYptrdiff, TYsize, TYsize_t; }
--- a/dmd/backend/TYPE.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/backend/TYPE.d Sun Apr 04 22:41:11 2010 +0100 @@ -97,8 +97,8 @@ alias type* typep_t; -extern(C++) /+extern+/ __gshared typep_t tstypes[TYM.TYMAX]; -extern(C++) /+extern+/ __gshared typep_t tsptr2types[TYM.TYMAX]; +extern(C) extern __gshared typep_t tstypes[TYM.TYMAX]; +extern(C) extern __gshared typep_t tsptr2types[TYM.TYMAX]; ref type* tsbool () { return tstypes[TYM.TYbool]; } ref type* tschar () { return tstypes[TYM.TYchar]; } @@ -118,7 +118,7 @@ ref type* tsdouble () { return tstypes[TYM.TYdouble]; } ref type* tsreal64 () { return tstypes[TYM.TYdouble_alias]; } ref type* tsldouble () { return tstypes[TYM.TYldouble]; } -ref type* tsvoid () { return tstypes[TYM.TYvoid]; } +ref type* tsvoid () { return tstypes[TYM.TYvoid]; } ref type* tsifloat () { return tstypes[TYM.TYifloat]; } ref type* tsidouble () { return tstypes[TYM.TYidouble]; } ref type* tsildouble () { return tstypes[TYM.TYildouble]; }
--- a/dmd/backend/glue.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/backend/glue.d Sun Apr 04 22:41:11 2010 +0100 @@ -22,7 +22,7 @@ extern (C++) /+extern+/ { - __gshared Outbuffer objbuf; + extern(C) extern __gshared Outbuffer objbuf; int go_flag(char* cp); void util_set64(); void util_set386();
--- a/dmd/expression/Add.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/expression/Add.d Sun Apr 04 22:41:11 2010 +0100 @@ -9,6 +9,7 @@ import dmd.TOK; import dmd.SymOffExp; import dmd.Complex; +import dmd.Util : printf; Expression Add(Type type, Expression e1, Expression e2) { @@ -102,4 +103,4 @@ e = new IntegerExp(loc, e1.toInteger() + e2.toInteger(), type); return e; -} \ No newline at end of file +}
--- a/dmd/expression/Slice.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/expression/Slice.d Sun Apr 04 22:41:11 2010 +0100 @@ -8,6 +8,7 @@ import dmd.GlobalExpressions; import dmd.ArrayLiteralExp; import dmd.ArrayTypes; +import dmd.Util : printf; import core.memory; @@ -16,6 +17,7 @@ import std.contracts; + /* Also return EXP_CANT_INTERPRET if this fails */ Expression Slice(Type type, Expression e1, Expression lwr, Expression upr) @@ -78,4 +80,4 @@ } } return e; -} \ No newline at end of file +}
--- a/dmd/expression/Util.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/expression/Util.d Sun Apr 04 22:41:11 2010 +0100 @@ -772,6 +772,25 @@ } } +/****************************** + * Perform canThrow() on an array of Expressions. + */ + +version (DMDV2) { +bool arrayExpressionCanThrow(Expressions exps) +{ + if (exps) + { + for (size_t i = 0; i < exps.dim; i++) + { Expression e = cast(Expression)exps.data[i]; + if (e && e.canThrow()) + return true; + } + } + return false; +} +} + /**************************************** * Expand tuples. */ @@ -1360,4 +1379,4 @@ } } } -} \ No newline at end of file +}