diff --git a/src/ddmd/dclass.d b/src/ddmd/dclass.d index 490be4493ee3..cb8c26d8061f 100644 --- a/src/ddmd/dclass.d +++ b/src/ddmd/dclass.d @@ -97,8 +97,7 @@ struct BaseClass assert(ifd); // Find corresponding function in this class - tf = (ifd.type.ty == Tfunction) ? cast(TypeFunction)ifd.type : null; - assert(tf); // should always be non-null + tf = ifd.type.toTypeFunction(); fd = cd.findFunc(ifd.ident, tf); if (fd && !fd.isAbstract()) { @@ -928,7 +927,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration if (fd && !fd.errors) { //printf("Creating default this(){} for class %s\n", toChars()); - auto btf = cast(TypeFunction)fd.type; + auto btf = fd.type.toTypeFunction(); auto tf = new TypeFunction(null, null, 0, LINKd, fd.storage_class); tf.mod = btf.mod; tf.purity = btf.purity; @@ -1259,7 +1258,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration final bool isFuncHidden(FuncDeclaration fd) { - //printf("ClassDeclaration.isFuncHidden(class = %s, fd = %s)\n", toChars(), fd.toChars()); + //printf("ClassDeclaration.isFuncHidden(class = %s, fd = %s)\n", toChars(), fd.toPrettyChars()); Dsymbol s = search(Loc(), fd.ident, IgnoreAmbiguous | IgnoreErrors); if (!s) { @@ -1880,6 +1879,7 @@ extern (C++) final class InterfaceDeclaration : ClassDeclaration //printf("\tX base %s\n", b.sym.toChars()); if (this == b.sym) { + //printf("\tfound at offset %d\n", b.offset); if (poffset) { // don't return incorrect offsets https://issues.dlang.org/show_bug.cgi?id=16980 diff --git a/src/ddmd/dstruct.d b/src/ddmd/dstruct.d index fb265d557066..88c881cf0dcb 100644 --- a/src/ddmd/dstruct.d +++ b/src/ddmd/dstruct.d @@ -44,7 +44,7 @@ extern (C++) FuncDeclaration search_toString(StructDeclaration sd) if (!tftostring) { tftostring = new TypeFunction(null, Type.tstring, 0, LINKd); - tftostring = cast(TypeFunction)tftostring.merge(); + tftostring = tftostring.merge().toTypeFunction(); } fd = fd.overloadExactMatch(tftostring); } @@ -98,6 +98,7 @@ extern (C++) void semanticTypeInfo(Scope* sc, Type t) override void visit(TypeStruct t) { + //printf("semanticTypeInfo.visit(TypeStruct = %s)\n", t.toChars()); StructDeclaration sd = t.sym; /* Step 1: create TypeInfoDeclaration diff --git a/src/ddmd/func.d b/src/ddmd/func.d index f66fe6fce8da..d76933a1585c 100644 --- a/src/ddmd/func.d +++ b/src/ddmd/func.d @@ -349,7 +349,7 @@ extern (C++) class FuncDeclaration : Declaration fld.tok = TOKfunction; else assert(0); - linkage = (cast(TypeFunction)treq.nextOf()).linkage; + linkage = treq.nextOf().toTypeFunction().linkage; } else linkage = sc.linkage; @@ -359,12 +359,22 @@ extern (C++) class FuncDeclaration : Declaration if (!originalType) originalType = type.syntaxCopy(); + if (type.ty != Tfunction) + { + if (type.ty != Terror) + { + error("%s must be a function instead of %s", toChars(), type.toChars()); + type = Type.terror; + } + errors = true; + return; + } if (!type.deco) { sc = sc.push(); sc.stc |= storage_class & (STCdisable | STCdeprecated); // forward to function type - TypeFunction tf = cast(TypeFunction)type; + TypeFunction tf = type.toTypeFunction(); if (sc.func) { /* If the nesting parent is pure without inference, @@ -491,8 +501,8 @@ extern (C++) class FuncDeclaration : Declaration { // Merge back function attributes into 'originalType'. // It's used for mangling, ddoc, and json output. - TypeFunction tfo = cast(TypeFunction)originalType; - TypeFunction tfx = cast(TypeFunction)type; + TypeFunction tfo = originalType.toTypeFunction(); + TypeFunction tfx = type.toTypeFunction(); tfo.mod = tfx.mod; tfo.isscope = tfx.isscope; tfo.isref = tfx.isref; @@ -931,8 +941,7 @@ extern (C++) class FuncDeclaration : Declaration error("override only applies to class member functions"); // Reflect this.type to f because it could be changed by findVtblIndex - assert(type.ty == Tfunction); - f = cast(TypeFunction)type; + f = type.toTypeFunction(); /* Do not allow template instances to add virtual functions * to a class. @@ -1751,7 +1760,7 @@ extern (C++) class FuncDeclaration : Declaration // BUG: need to treat parameters as const // BUG: need to disallow returns and throws - if (inferRetType && fdensure && (cast(TypeFunction)fdensure.type).parameters) + if (inferRetType && fdensure && fdensure.type.toTypeFunction().parameters) { // Return type was unknown in the first semantic pass Parameter p = (*(cast(TypeFunction)fdensure.type).parameters)[0]; @@ -2504,7 +2513,7 @@ extern (C++) class FuncDeclaration : Declaration return 0; m.anyf = f; - auto tf = cast(TypeFunction)f.type; + auto tf = f.type.toTypeFunction(); //printf("tf = %s\n", tf.toChars()); MATCH match; @@ -2568,7 +2577,7 @@ extern (C++) class FuncDeclaration : Declaration else // no match { hasOverloads = true; - auto tf = cast(TypeFunction)this.type; + auto tf = this.type.toTypeFunction(); assert(tthis); assert(!MODimplicitConv(tthis.mod, tf.mod)); // modifier mismatch { @@ -2637,8 +2646,8 @@ extern (C++) class FuncDeclaration : Declaration * as g() is. */ - TypeFunction tf = cast(TypeFunction)type; - TypeFunction tg = cast(TypeFunction)g.type; + TypeFunction tf = type.toTypeFunction(); + TypeFunction tg = g.type.toTypeFunction(); size_t nfparams = Parameter.dim(tf.parameters); /* If both functions have a 'this' pointer, and the mods are not @@ -2799,7 +2808,7 @@ extern (C++) class FuncDeclaration : Declaration final const(char)* toFullSignature() { OutBuffer buf; - functionToBufferWithIdent(cast(TypeFunction)type, &buf, toChars()); + functionToBufferWithIdent(type.toTypeFunction(), &buf, toChars()); return buf.extractString(); } @@ -2899,8 +2908,8 @@ extern (C++) class FuncDeclaration : Declaration */ private final void initInferAttributes() { - assert(type.ty == Tfunction); - TypeFunction tf = cast(TypeFunction)type; + //printf("initInferAttributes() for %s\n", toPrettyChars()); + TypeFunction tf = type.toTypeFunction(); if (tf.purity == PUREimpure) // purity not specified flags |= FUNCFLAGpurityInprocess; @@ -2924,8 +2933,7 @@ extern (C++) class FuncDeclaration : Declaration final PURE isPure() { //printf("FuncDeclaration::isPure() '%s'\n", toChars()); - assert(type.ty == Tfunction); - TypeFunction tf = cast(TypeFunction)type; + TypeFunction tf = type.toTypeFunction(); if (flags & FUNCFLAGpurityInprocess) setImpure(); if (tf.purity == PUREfwdref) @@ -2978,10 +2986,9 @@ extern (C++) class FuncDeclaration : Declaration final bool isSafe() { - assert(type.ty == Tfunction); if (flags & FUNCFLAGsafetyInprocess) setUnsafe(); - return (cast(TypeFunction)type).trust == TRUSTsafe; + return type.toTypeFunction().trust == TRUSTsafe; } final bool isSafeBypassingInference() @@ -2991,10 +2998,9 @@ extern (C++) class FuncDeclaration : Declaration final bool isTrusted() { - assert(type.ty == Tfunction); if (flags & FUNCFLAGsafetyInprocess) setUnsafe(); - return (cast(TypeFunction)type).trust == TRUSTtrusted; + return type.toTypeFunction().trust == TRUSTtrusted; } /************************************** @@ -3007,7 +3013,7 @@ extern (C++) class FuncDeclaration : Declaration if (flags & FUNCFLAGsafetyInprocess) { flags &= ~FUNCFLAGsafetyInprocess; - (cast(TypeFunction)type).trust = TRUSTsystem; + type.toTypeFunction().trust = TRUSTsystem; if (fes) fes.func.setUnsafe(); } @@ -3018,10 +3024,9 @@ extern (C++) class FuncDeclaration : Declaration final bool isNogc() { - assert(type.ty == Tfunction); if (flags & FUNCFLAGnogcInprocess) setGC(); - return (cast(TypeFunction)type).isnogc; + return type.toTypeFunction().isnogc; } final bool isNogcBypassingInference() @@ -3040,7 +3045,7 @@ extern (C++) class FuncDeclaration : Declaration if (flags & FUNCFLAGnogcInprocess) { flags &= ~FUNCFLAGnogcInprocess; - (cast(TypeFunction)type).isnogc = false; + type.toTypeFunction().isnogc = false; if (fes) fes.func.setGC(); } @@ -3067,8 +3072,7 @@ extern (C++) class FuncDeclaration : Declaration */ final bool isolateReturn() { - assert(type.ty == Tfunction); - TypeFunction tf = cast(TypeFunction)type; + TypeFunction tf = type.toTypeFunction(); assert(tf.next); Type treti = tf.next; @@ -3088,8 +3092,7 @@ extern (C++) class FuncDeclaration : Declaration if (!isPureBypassingInference() || isNested()) return false; - assert(type.ty == Tfunction); - TypeFunction tf = cast(TypeFunction)type; + TypeFunction tf = type.toTypeFunction(); //printf("parametersIntersect(%s) t = %s\n", tf.toChars(), t.toChars()); @@ -3416,8 +3419,7 @@ extern (C++) class FuncDeclaration : Declaration */ if (closureVars.dim) { - assert(type.ty == Tfunction); - Type tret = (cast(TypeFunction)type).next; + Type tret = type.toTypeFunction().next; assert(tret); tret = tret.toBasetype(); //printf("\t\treturning %s\n", tret.toChars()); @@ -3562,8 +3564,7 @@ extern (C++) class FuncDeclaration : Declaration if (sc && vresult.semanticRun == PASSinit) { - assert(type.ty == Tfunction); - TypeFunction tf = cast(TypeFunction)type; + TypeFunction tf = type.toTypeFunction(); if (tf.isref) vresult.storage_class |= STCref; vresult.type = tret; @@ -3736,8 +3737,7 @@ extern (C++) class FuncDeclaration : Declaration if (type) { - assert(type.ty == Tfunction); - TypeFunction fdtype = cast(TypeFunction)type; + TypeFunction fdtype = type.toTypeFunction(); fparameters = fdtype.parameters; fvarargs = fdtype.varargs; } @@ -3793,7 +3793,7 @@ extern (C++) class FuncDeclaration : Declaration */ final void checkDmain() { - TypeFunction tf = cast(TypeFunction)type; + TypeFunction tf = type.toTypeFunction(); const nparams = Parameter.dim(tf.parameters); bool argerr; if (nparams == 1) @@ -4136,7 +4136,7 @@ extern (C++) FuncDeclaration resolveFuncCall(Loc loc, Scope* sc, Dsymbol s, assert(fd); bool hasOverloads = fd.overnext !is null; - auto tf = cast(TypeFunction)fd.type; + auto tf = fd.type.toTypeFunction(); if (tthis && !MODimplicitConv(tthis.mod, tf.mod)) // modifier mismatch { OutBuffer thisBuf, funcBuf; @@ -4204,8 +4204,8 @@ extern (C++) FuncDeclaration resolveFuncCall(Loc loc, Scope* sc, Dsymbol s, } else if (m.nextf) { - TypeFunction tf1 = cast(TypeFunction)m.lastf.type; - TypeFunction tf2 = cast(TypeFunction)m.nextf.type; + TypeFunction tf1 = m.lastf.type.toTypeFunction(); + TypeFunction tf2 = m.nextf.type.toTypeFunction(); const(char)* lastprms = parametersTypeToChars(tf1.parameters, tf1.varargs); const(char)* nextprms = parametersTypeToChars(tf2.parameters, tf2.varargs); .error(loc, "%s.%s called with argument types %s matches both:\n%s: %s%s\nand:\n%s: %s%s", @@ -4529,7 +4529,7 @@ extern (C++) final class FuncLiteralDeclaration : FuncDeclaration // This is required so the code generator does not try to cast the // modified returns back to the original type. if (inferRetType && type.nextOf() != tret) - (cast(TypeFunction)type).next = tret; + type.toTypeFunction().next = tret; } override inout(FuncLiteralDeclaration) isFuncLiteralDeclaration() inout @@ -4610,8 +4610,7 @@ extern (C++) final class CtorDeclaration : FuncDeclaration if (errors) return; - TypeFunction tf = cast(TypeFunction)type; - assert(tf && tf.ty == Tfunction); + TypeFunction tf = type.toTypeFunction(); /* See if it's the default constructor * But, template constructor should not become a default constructor. @@ -5426,10 +5425,9 @@ extern (C++) final class NewDeclaration : FuncDeclaration type = new TypeFunction(parameters, tret, varargs, LINKd, storage_class); type = type.semantic(loc, sc); - assert(type.ty == Tfunction); // Check that there is at least one argument of type size_t - TypeFunction tf = cast(TypeFunction)type; + TypeFunction tf = type.toTypeFunction(); if (Parameter.dim(tf.parameters) < 1) { error("at least one argument of type size_t expected"); @@ -5518,10 +5516,9 @@ extern (C++) final class DeleteDeclaration : FuncDeclaration type = new TypeFunction(parameters, Type.tvoid, 0, LINKd, storage_class); type = type.semantic(loc, sc); - assert(type.ty == Tfunction); // Check that there is only one argument of type void* - TypeFunction tf = cast(TypeFunction)type; + TypeFunction tf = type.toTypeFunction(); if (Parameter.dim(tf.parameters) != 1) { error("one argument of type void* expected"); diff --git a/src/ddmd/mtype.d b/src/ddmd/mtype.d index 089750675082..cc8353bcfe4b 100644 --- a/src/ddmd/mtype.d +++ b/src/ddmd/mtype.d @@ -3075,6 +3075,13 @@ extern (C++) abstract class Type : RootObject { v.visit(this); } + + final TypeFunction toTypeFunction() + { + if (ty != Tfunction) + assert(0); + return cast(TypeFunction)this; + } } /*********************************************************** @@ -5605,14 +5612,14 @@ extern (C++) final class TypeAArray : TypeArray auto fparams = new Parameters(); fparams.push(new Parameter(STCin, this, null, null)); fd_aaLen = FuncDeclaration.genCfunc(fparams, Type.tsize_t, Id.aaLen); - TypeFunction tf = cast(TypeFunction)fd_aaLen.type; + TypeFunction tf = fd_aaLen.type.toTypeFunction(); tf.purity = PUREconst; tf.isnothrow = true; tf.isnogc = false; } Expression ev = new VarExp(e.loc, fd_aaLen, false); e = new CallExp(e.loc, ev, e); - e.type = (cast(TypeFunction)fd_aaLen.type).next; + e.type = fd_aaLen.type.toTypeFunction().next; } else e = Type.dotExp(sc, e, ident, flag); @@ -6105,7 +6112,7 @@ extern (C++) final class TypeFunction : TypeNext * This can produce redundant copies if inferring return type, * as semantic() will get called again on this. */ - TypeFunction tf = cast(TypeFunction)copy(); + TypeFunction tf = copy().toTypeFunction(); if (parameters) { tf.parameters = parameters.copy(); @@ -6699,7 +6706,7 @@ extern (C++) final class TypeFunction : TypeNext override Type addStorageClass(StorageClass stc) { //printf("addStorageClass(%llx) %d\n", stc, (stc & STCscope) != 0); - TypeFunction t = cast(TypeFunction)Type.addStorageClass(stc); + TypeFunction t = Type.addStorageClass(stc).toTypeFunction(); if ((stc & STCpure && !t.purity) || (stc & STCnothrow && !t.isnothrow) || (stc & STCnogc && !t.isnogc) || @@ -10046,6 +10053,7 @@ extern (C++) final class TypeNull : Type { extern (D) this() { + //printf("TypeNull %p\n", this); super(Tnull); } @@ -10146,7 +10154,7 @@ extern (C++) final class Parameter : RootObject if (tel.ty == Tdelegate) { TypeDelegate td = cast(TypeDelegate)tel; - TypeFunction tf = cast(TypeFunction)td.next; + TypeFunction tf = td.next.toTypeFunction(); if (!tf.varargs && Parameter.dim(tf.parameters) == 0) { return tf.next; // return type of delegate