Mercurial > projects > ddmd
diff dmd/TraitsExp.d @ 72:2e2a5c3f943a
reduced warnings by adding override to the methods
think this also normalizes different line endings used all over the place
author | Trass3r |
---|---|
date | Sat, 28 Aug 2010 16:19:48 +0200 |
parents | 460959608115 |
children | be2ab491772e |
line wrap: on
line diff
--- a/dmd/TraitsExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TraitsExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,454 +1,454 @@ -module dmd.TraitsExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.ArrayTypes; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.HdrGenState; -import dmd.TOK; -import dmd.TY; -import dmd.STC; -import dmd.WANT; -import dmd.Id; -import dmd.Global; -import dmd.Lexer; -import dmd.ArrayLiteralExp; -import dmd.VarExp; -import dmd.StringExp; -import dmd.DotIdExp; -import dmd.DotVarExp; -import dmd.IntegerExp; -import dmd.TupleExp; -import dmd.Type; -import dmd.Dsymbol; -import dmd.DsymbolExp; -import dmd.ScopeDsymbol; -import dmd.FuncDeclaration; -import dmd.ClassDeclaration; -import dmd.TemplateDeclaration; -import dmd.TemplateInstance; -import dmd.TypeClass; -import dmd.Util; -import dmd.expression.Util; - -import core.stdc.string : strcmp; - -/************************************************ - * Delegate to be passed to overloadApply() that looks - * for virtual functions. - */ - -struct Pvirtuals -{ - Expression e1; - Expressions exps; - int fpvirtuals(void* param, FuncDeclaration f) - { Pvirtuals p = *cast(Pvirtuals*)param; - - if (f.isVirtual()) - { Expression e; - - if (p.e1.op == TOK.TOKdotvar) - { DotVarExp dve = cast(DotVarExp)p.e1; - e = new DotVarExp(Loc(0), dve.e1, f); - } - else - e = new DsymbolExp(Loc(0), f); - p.exps.push(cast(void*)e); - } - return 0; - } -} - - - -class TraitsExp : Expression -{ - Identifier ident; - - Objects args; - - this(Loc loc, Identifier ident, Objects args) - { - super(loc, TOK.TOKtraits, this.sizeof); - this.ident = ident; - this.args = args; - } - - Expression syntaxCopy() - { - return new TraitsExp(loc, ident, TemplateInstance.arraySyntaxCopy(args)); - } - - Expression semantic(Scope sc) - { - version (LOGSEMANTIC) { - printf("TraitsExp.semantic() %s\n", toChars()); - } - if (ident != Id.compiles && ident != Id.isSame) - TemplateInstance.semanticTiargs(loc, sc, args, 1); - size_t dim = args ? args.dim : 0; - Object o; - FuncDeclaration f; - - string ISTYPE(string cond) - { - return ` - for (size_t i = 0; i < dim; i++) - { Type t = getType(cast(Object)args.data[i]); - if (!t) - goto Lfalse; - if (!(`~cond~`)) - goto Lfalse; - } - if (!dim) - goto Lfalse; - goto Ltrue; - `; - } - - string ISDSYMBOL(string cond) - { - return `for (size_t i = 0; i < dim; i++) - { Dsymbol s = getDsymbol(cast(Object)args.data[i]); - if (!s) - goto Lfalse; - if (!(`~cond~`)) - goto Lfalse; - } - if (!dim) - goto Lfalse; - goto Ltrue;`; - } - - if (ident == Id.isArithmetic) - { - mixin(ISTYPE(`t.isintegral() || t.isfloating()`)); - } - else if (ident == Id.isFloating) - { - mixin(ISTYPE(q{t.isfloating()})); - } - else if (ident == Id.isIntegral) - { - mixin(ISTYPE(q{t.isintegral()})); - } - else if (ident == Id.isScalar) - { - mixin(ISTYPE(q{t.isscalar()})); - } - else if (ident == Id.isUnsigned) - { - mixin(ISTYPE(q{t.isunsigned()})); - } - else if (ident == Id.isAssociativeArray) - { - mixin(ISTYPE(q{t.toBasetype().ty == TY.Taarray})); - } - else if (ident == Id.isStaticArray) - { - mixin(ISTYPE(q{t.toBasetype().ty == TY.Tsarray})); - } - else if (ident == Id.isAbstractClass) - { - mixin(ISTYPE(q{t.toBasetype().ty == TY.Tclass && (cast(TypeClass)t.toBasetype()).sym.isAbstract()})); - } - else if (ident == Id.isFinalClass) - { - mixin(ISTYPE(q{t.toBasetype().ty == TY.Tclass && (cast(TypeClass)t.toBasetype()).sym.storage_class & STC.STCfinal})); - } - else if (ident == Id.isAbstractFunction) - { - mixin(ISDSYMBOL(q{(f = s.isFuncDeclaration()) !is null && f.isAbstract()})); - } - else if (ident == Id.isVirtualFunction) - { - mixin(ISDSYMBOL(q{(f = s.isFuncDeclaration()) !is null && f.isVirtual()})); - } - else if (ident == Id.isFinalFunction) - { - mixin(ISDSYMBOL(q{(f = s.isFuncDeclaration()) !is null && f.isFinal()})); - } - else if (ident == Id.hasMember || - ident == Id.getMember || - ident == Id.getVirtualFunctions) - { - if (dim != 2) - goto Ldimerror; - Object o_ = cast(Object)args.data[0]; - Expression e = isExpression(cast(Object)args.data[1]); - if (!e) - { error("expression expected as second argument of __traits %s", ident.toChars()); - goto Lfalse; - } - e = e.optimize(WANT.WANTvalue | WANT.WANTinterpret); - if (e.op != TOKstring) - { error("string expected as second argument of __traits %s instead of %s", ident.toChars(), e.toChars()); - goto Lfalse; - } - StringExp se = cast(StringExp)e; - se = se.toUTF8(sc); - if (se.sz != 1) - { error("string must be chars"); - goto Lfalse; - } - Identifier id = Lexer.idPool(fromStringz(cast(char*)se.string_)); - - Type t = isType(o_); - e = isExpression(o_); - Dsymbol s = isDsymbol(o_); - if (t) - e = typeDotIdExp(loc, t, id); - else if (e) - e = new DotIdExp(loc, e, id); - else if (s) - { e = new DsymbolExp(loc, s); - e = new DotIdExp(loc, e, id); - } - else - { error("invalid first argument"); - goto Lfalse; - } - - if (ident == Id.hasMember) - { /* Take any errors as meaning it wasn't found - */ - e = e.trySemantic(sc); - if (!e) - { if (global.gag) - global.errors++; - goto Lfalse; - } - else - goto Ltrue; - } - else if (ident == Id.getMember) - { - e = e.semantic(sc); - return e; - } - else if (ident == Id.getVirtualFunctions) - { - uint errors = global.errors; - Expression ex = e; - e = e.semantic(sc); - if (errors < global.errors) - error("%s cannot be resolved", ex.toChars()); - - /* Create tuple of virtual function overloads of e - */ - //e.dump(0); - Expressions exps = new Expressions(); - FuncDeclaration f_; - if (e.op == TOKvar) - { VarExp ve = cast(VarExp)e; - f_ = ve.var.isFuncDeclaration(); - } - else if (e.op == TOKdotvar) - { DotVarExp dve = cast(DotVarExp)e; - f_ = dve.var.isFuncDeclaration(); - } - else - f_ = null; - Pvirtuals p; - p.exps = exps; - p.e1 = e; - overloadApply(f_, &p.fpvirtuals, &p); - - TupleExp tup = new TupleExp(loc, exps); - return tup.semantic(sc); - } - else - assert(0); - } - else if (ident == Id.classInstanceSize) - { - if (dim != 1) - goto Ldimerror; - Object o_ = cast(Object)args.data[0]; - Dsymbol s = getDsymbol(o_); - ClassDeclaration cd; - if (!s || (cd = s.isClassDeclaration()) is null) - { - error("first argument is not a class"); - goto Lfalse; - } - return new IntegerExp(loc, cd.structsize, Type.tsize_t); - } - else if (ident == Id.allMembers || ident == Id.derivedMembers) - { - if (dim != 1) - goto Ldimerror; - Object o_ = cast(Object)args.data[0]; - Dsymbol s = getDsymbol(o_); - ScopeDsymbol sd; - if (!s) - { - error("argument has no members"); - goto Lfalse; - } - if ((sd = s.isScopeDsymbol()) is null) - { - error("%s %s has no members", s.kind(), s.toChars()); - goto Lfalse; - } - Expressions exps = new Expressions; - while (1) - { size_t dim_ = ScopeDsymbol.dim(sd.members); - for (size_t i = 0; i < dim_; i++) - { - Dsymbol sm = ScopeDsymbol.getNth(sd.members, i); - //printf("\t[%i] %s %s\n", i, sm.kind(), sm.toChars()); - if (sm.ident) - { - //printf("\t%s\n", sm.ident.toChars()); - auto str = sm.ident.toChars(); - - /* Skip if already present in exps[] - */ - for (size_t j = 0; j < exps.dim; j++) - { StringExp se2 = cast(StringExp)exps.data[j]; - if (strcmp(toStringz(str), cast(char*)se2.string_) == 0) - goto Lnext; - } - - StringExp se = new StringExp(loc, str); - exps.push(cast(void*)se); - } -Lnext: - ; - } - ClassDeclaration cd = sd.isClassDeclaration(); - if (cd && cd.baseClass && ident == Id.allMembers) - sd = cd.baseClass; // do again with base class - else - break; - } - Expression e = new ArrayLiteralExp(loc, exps); - e = e.semantic(sc); - return e; - } - else if (ident == Id.compiles) - { - /* Determine if all the objects - types, expressions, or symbols - - * compile without error - */ - if (!dim) - goto Lfalse; - - for (size_t i = 0; i < dim; i++) - { Object o_ = cast(Object)args.data[i]; - Expression e; - - uint errors = global.errors; - global.gag++; - - Type t = isType(o_); - if (t) - { Dsymbol s; - t.resolve(loc, sc, &e, &t, &s); - if (t) - t.semantic(loc, sc); - else if (e) - e.semantic(sc); - } - else - { e = isExpression(o); - if (e) - e.semantic(sc); - } - - global.gag--; - if (errors != global.errors) - { if (global.gag == 0) - global.errors = errors; - goto Lfalse; - } - } - goto Ltrue; - } - else if (ident == Id.isSame) - { /* Determine if two symbols are the same - */ - if (dim != 2) - goto Ldimerror; - TemplateInstance.semanticTiargs(loc, sc, args, 0); - Object o1 = cast(Object)args.data[0]; - Object o2 = cast(Object)args.data[1]; - Dsymbol s1 = getDsymbol(o1); - Dsymbol s2 = getDsymbol(o2); - - static if (0) { - printf("o1: %p\n", o1); - printf("o2: %p\n", o2); - if (!s1) - { Expression ea = isExpression(o1); - if (ea) - printf("%s\n", ea.toChars()); - Type ta = isType(o1); - if (ta) - printf("%s\n", ta.toChars()); - goto Lfalse; - } - else - printf("%s %s\n", s1.kind(), s1.toChars()); - } - if (!s1 && !s2) - { Expression ea1 = isExpression(o1); - Expression ea2 = isExpression(o2); - if (ea1 && ea2 && ea1.equals(ea2)) - goto Ltrue; - } - - if (!s1 || !s2) - goto Lfalse; - - s1 = s1.toAlias(); - s2 = s2.toAlias(); - - if (s1 == s2) - goto Ltrue; - else - goto Lfalse; - } - else - { error("unrecognized trait %s", ident.toChars()); - goto Lfalse; - } - - return null; - -Lnottype: - error("%s is not a type", o/*.toChars()*/); // BUG: o is Object, no member toChars() - goto Lfalse; - -Ldimerror: - error("wrong number of arguments %d", dim); - goto Lfalse; - - -Lfalse: - return new IntegerExp(loc, 0, Type.tbool); - -Ltrue: - return new IntegerExp(loc, 1, Type.tbool); - } - - void toCBuffer(OutBuffer buf, HdrGenState* hgs) - { - buf.writestring("__traits("); - buf.writestring(ident.toChars()); - if (args) - { - for (int i = 0; i < args.dim; i++) - { - buf.writeByte(','); - Object oarg = cast(Object)args.data[i]; - ObjectToCBuffer(buf, hgs, oarg); - } - } - buf.writeByte(')'); - } -} +module dmd.TraitsExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.ArrayTypes; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.HdrGenState; +import dmd.TOK; +import dmd.TY; +import dmd.STC; +import dmd.WANT; +import dmd.Id; +import dmd.Global; +import dmd.Lexer; +import dmd.ArrayLiteralExp; +import dmd.VarExp; +import dmd.StringExp; +import dmd.DotIdExp; +import dmd.DotVarExp; +import dmd.IntegerExp; +import dmd.TupleExp; +import dmd.Type; +import dmd.Dsymbol; +import dmd.DsymbolExp; +import dmd.ScopeDsymbol; +import dmd.FuncDeclaration; +import dmd.ClassDeclaration; +import dmd.TemplateDeclaration; +import dmd.TemplateInstance; +import dmd.TypeClass; +import dmd.Util; +import dmd.expression.Util; + +import core.stdc.string : strcmp; + +/************************************************ + * Delegate to be passed to overloadApply() that looks + * for virtual functions. + */ + +struct Pvirtuals +{ + Expression e1; + Expressions exps; + int fpvirtuals(void* param, FuncDeclaration f) + { Pvirtuals p = *cast(Pvirtuals*)param; + + if (f.isVirtual()) + { Expression e; + + if (p.e1.op == TOK.TOKdotvar) + { DotVarExp dve = cast(DotVarExp)p.e1; + e = new DotVarExp(Loc(0), dve.e1, f); + } + else + e = new DsymbolExp(Loc(0), f); + p.exps.push(cast(void*)e); + } + return 0; + } +} + + + +class TraitsExp : Expression +{ + Identifier ident; + + Objects args; + + this(Loc loc, Identifier ident, Objects args) + { + super(loc, TOK.TOKtraits, this.sizeof); + this.ident = ident; + this.args = args; + } + + override Expression syntaxCopy() + { + return new TraitsExp(loc, ident, TemplateInstance.arraySyntaxCopy(args)); + } + + override Expression semantic(Scope sc) + { + version (LOGSEMANTIC) { + printf("TraitsExp.semantic() %s\n", toChars()); + } + if (ident != Id.compiles && ident != Id.isSame) + TemplateInstance.semanticTiargs(loc, sc, args, 1); + size_t dim = args ? args.dim : 0; + Object o; + FuncDeclaration f; + + string ISTYPE(string cond) + { + return ` + for (size_t i = 0; i < dim; i++) + { Type t = getType(cast(Object)args.data[i]); + if (!t) + goto Lfalse; + if (!(`~cond~`)) + goto Lfalse; + } + if (!dim) + goto Lfalse; + goto Ltrue; + `; + } + + string ISDSYMBOL(string cond) + { + return `for (size_t i = 0; i < dim; i++) + { Dsymbol s = getDsymbol(cast(Object)args.data[i]); + if (!s) + goto Lfalse; + if (!(`~cond~`)) + goto Lfalse; + } + if (!dim) + goto Lfalse; + goto Ltrue;`; + } + + if (ident == Id.isArithmetic) + { + mixin(ISTYPE(`t.isintegral() || t.isfloating()`)); + } + else if (ident == Id.isFloating) + { + mixin(ISTYPE(q{t.isfloating()})); + } + else if (ident == Id.isIntegral) + { + mixin(ISTYPE(q{t.isintegral()})); + } + else if (ident == Id.isScalar) + { + mixin(ISTYPE(q{t.isscalar()})); + } + else if (ident == Id.isUnsigned) + { + mixin(ISTYPE(q{t.isunsigned()})); + } + else if (ident == Id.isAssociativeArray) + { + mixin(ISTYPE(q{t.toBasetype().ty == TY.Taarray})); + } + else if (ident == Id.isStaticArray) + { + mixin(ISTYPE(q{t.toBasetype().ty == TY.Tsarray})); + } + else if (ident == Id.isAbstractClass) + { + mixin(ISTYPE(q{t.toBasetype().ty == TY.Tclass && (cast(TypeClass)t.toBasetype()).sym.isAbstract()})); + } + else if (ident == Id.isFinalClass) + { + mixin(ISTYPE(q{t.toBasetype().ty == TY.Tclass && (cast(TypeClass)t.toBasetype()).sym.storage_class & STC.STCfinal})); + } + else if (ident == Id.isAbstractFunction) + { + mixin(ISDSYMBOL(q{(f = s.isFuncDeclaration()) !is null && f.isAbstract()})); + } + else if (ident == Id.isVirtualFunction) + { + mixin(ISDSYMBOL(q{(f = s.isFuncDeclaration()) !is null && f.isVirtual()})); + } + else if (ident == Id.isFinalFunction) + { + mixin(ISDSYMBOL(q{(f = s.isFuncDeclaration()) !is null && f.isFinal()})); + } + else if (ident == Id.hasMember || + ident == Id.getMember || + ident == Id.getVirtualFunctions) + { + if (dim != 2) + goto Ldimerror; + Object o_ = cast(Object)args.data[0]; + Expression e = isExpression(cast(Object)args.data[1]); + if (!e) + { error("expression expected as second argument of __traits %s", ident.toChars()); + goto Lfalse; + } + e = e.optimize(WANT.WANTvalue | WANT.WANTinterpret); + if (e.op != TOKstring) + { error("string expected as second argument of __traits %s instead of %s", ident.toChars(), e.toChars()); + goto Lfalse; + } + StringExp se = cast(StringExp)e; + se = se.toUTF8(sc); + if (se.sz != 1) + { error("string must be chars"); + goto Lfalse; + } + Identifier id = Lexer.idPool(fromStringz(cast(char*)se.string_)); + + Type t = isType(o_); + e = isExpression(o_); + Dsymbol s = isDsymbol(o_); + if (t) + e = typeDotIdExp(loc, t, id); + else if (e) + e = new DotIdExp(loc, e, id); + else if (s) + { e = new DsymbolExp(loc, s); + e = new DotIdExp(loc, e, id); + } + else + { error("invalid first argument"); + goto Lfalse; + } + + if (ident == Id.hasMember) + { /* Take any errors as meaning it wasn't found + */ + e = e.trySemantic(sc); + if (!e) + { if (global.gag) + global.errors++; + goto Lfalse; + } + else + goto Ltrue; + } + else if (ident == Id.getMember) + { + e = e.semantic(sc); + return e; + } + else if (ident == Id.getVirtualFunctions) + { + uint errors = global.errors; + Expression ex = e; + e = e.semantic(sc); + if (errors < global.errors) + error("%s cannot be resolved", ex.toChars()); + + /* Create tuple of virtual function overloads of e + */ + //e.dump(0); + Expressions exps = new Expressions(); + FuncDeclaration f_; + if (e.op == TOKvar) + { VarExp ve = cast(VarExp)e; + f_ = ve.var.isFuncDeclaration(); + } + else if (e.op == TOKdotvar) + { DotVarExp dve = cast(DotVarExp)e; + f_ = dve.var.isFuncDeclaration(); + } + else + f_ = null; + Pvirtuals p; + p.exps = exps; + p.e1 = e; + overloadApply(f_, &p.fpvirtuals, &p); + + TupleExp tup = new TupleExp(loc, exps); + return tup.semantic(sc); + } + else + assert(0); + } + else if (ident == Id.classInstanceSize) + { + if (dim != 1) + goto Ldimerror; + Object o_ = cast(Object)args.data[0]; + Dsymbol s = getDsymbol(o_); + ClassDeclaration cd; + if (!s || (cd = s.isClassDeclaration()) is null) + { + error("first argument is not a class"); + goto Lfalse; + } + return new IntegerExp(loc, cd.structsize, Type.tsize_t); + } + else if (ident == Id.allMembers || ident == Id.derivedMembers) + { + if (dim != 1) + goto Ldimerror; + Object o_ = cast(Object)args.data[0]; + Dsymbol s = getDsymbol(o_); + ScopeDsymbol sd; + if (!s) + { + error("argument has no members"); + goto Lfalse; + } + if ((sd = s.isScopeDsymbol()) is null) + { + error("%s %s has no members", s.kind(), s.toChars()); + goto Lfalse; + } + Expressions exps = new Expressions; + while (1) + { size_t dim_ = ScopeDsymbol.dim(sd.members); + for (size_t i = 0; i < dim_; i++) + { + Dsymbol sm = ScopeDsymbol.getNth(sd.members, i); + //printf("\t[%i] %s %s\n", i, sm.kind(), sm.toChars()); + if (sm.ident) + { + //printf("\t%s\n", sm.ident.toChars()); + auto str = sm.ident.toChars(); + + /* Skip if already present in exps[] + */ + for (size_t j = 0; j < exps.dim; j++) + { StringExp se2 = cast(StringExp)exps.data[j]; + if (strcmp(toStringz(str), cast(char*)se2.string_) == 0) + goto Lnext; + } + + StringExp se = new StringExp(loc, str); + exps.push(cast(void*)se); + } +Lnext: + ; + } + ClassDeclaration cd = sd.isClassDeclaration(); + if (cd && cd.baseClass && ident == Id.allMembers) + sd = cd.baseClass; // do again with base class + else + break; + } + Expression e = new ArrayLiteralExp(loc, exps); + e = e.semantic(sc); + return e; + } + else if (ident == Id.compiles) + { + /* Determine if all the objects - types, expressions, or symbols - + * compile without error + */ + if (!dim) + goto Lfalse; + + for (size_t i = 0; i < dim; i++) + { Object o_ = cast(Object)args.data[i]; + Expression e; + + uint errors = global.errors; + global.gag++; + + Type t = isType(o_); + if (t) + { Dsymbol s; + t.resolve(loc, sc, &e, &t, &s); + if (t) + t.semantic(loc, sc); + else if (e) + e.semantic(sc); + } + else + { e = isExpression(o); + if (e) + e.semantic(sc); + } + + global.gag--; + if (errors != global.errors) + { if (global.gag == 0) + global.errors = errors; + goto Lfalse; + } + } + goto Ltrue; + } + else if (ident == Id.isSame) + { /* Determine if two symbols are the same + */ + if (dim != 2) + goto Ldimerror; + TemplateInstance.semanticTiargs(loc, sc, args, 0); + Object o1 = cast(Object)args.data[0]; + Object o2 = cast(Object)args.data[1]; + Dsymbol s1 = getDsymbol(o1); + Dsymbol s2 = getDsymbol(o2); + + static if (0) { + printf("o1: %p\n", o1); + printf("o2: %p\n", o2); + if (!s1) + { Expression ea = isExpression(o1); + if (ea) + printf("%s\n", ea.toChars()); + Type ta = isType(o1); + if (ta) + printf("%s\n", ta.toChars()); + goto Lfalse; + } + else + printf("%s %s\n", s1.kind(), s1.toChars()); + } + if (!s1 && !s2) + { Expression ea1 = isExpression(o1); + Expression ea2 = isExpression(o2); + if (ea1 && ea2 && ea1.equals(ea2)) + goto Ltrue; + } + + if (!s1 || !s2) + goto Lfalse; + + s1 = s1.toAlias(); + s2 = s2.toAlias(); + + if (s1 == s2) + goto Ltrue; + else + goto Lfalse; + } + else + { error("unrecognized trait %s", ident.toChars()); + goto Lfalse; + } + + return null; + +Lnottype: + error("%s is not a type", o/*.toChars()*/); // BUG: o is Object, no member toChars() + goto Lfalse; + +Ldimerror: + error("wrong number of arguments %d", dim); + goto Lfalse; + + +Lfalse: + return new IntegerExp(loc, 0, Type.tbool); + +Ltrue: + return new IntegerExp(loc, 1, Type.tbool); + } + + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) + { + buf.writestring("__traits("); + buf.writestring(ident.toChars()); + if (args) + { + for (int i = 0; i < args.dim; i++) + { + buf.writeByte(','); + Object oarg = cast(Object)args.data[i]; + ObjectToCBuffer(buf, hgs, oarg); + } + } + buf.writeByte(')'); + } +}