Mercurial > projects > ddmd
diff dmd/TypeFunction.d @ 130:60bb0fe4563e
dmdfe 2.037 first main iteration
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Thu, 09 Sep 2010 22:51:44 +0100 |
parents | 010eb8f0e18d |
children | 206db751bd4c |
line wrap: on
line diff
--- a/dmd/TypeFunction.d Sun Sep 05 15:32:22 2010 +0400 +++ b/dmd/TypeFunction.d Thu Sep 09 22:51:44 2010 +0100 @@ -26,10 +26,11 @@ import dmd.CppMangleState; import dmd.TypeInfoDeclaration; import dmd.MATCH; -import dmd.Argument; +import dmd.Parameter; import dmd.Expression; import dmd.RET; import dmd.TY; +import dmd.TRUST; import dmd.Util; import dmd.TemplateInstance : isTuple; @@ -49,7 +50,7 @@ { // .next is the return type - Arguments parameters; // function parameters + Parameters parameters; // function parameters int varargs; // 1: T t, ...) style for variable number of arguments // 2: T t ...) style for variable number of arguments bool isnothrow; // true: nothrow @@ -57,10 +58,11 @@ bool isproperty; // can be called without parentheses bool isref; // true: returns a reference LINK linkage; // calling convention + TRUST trust; // level of trust int inuse; - this(Arguments parameters, Type treturn, int varargs, LINK linkage) + this(Parameters parameters, Type treturn, int varargs, LINK linkage) { super(TY.Tfunction, treturn); @@ -70,18 +72,20 @@ this.parameters = parameters; this.varargs = varargs; this.linkage = linkage; + this.trust = TRUSTdefault; } override Type syntaxCopy() { Type treturn = next ? next.syntaxCopy() : null; - Arguments params = Argument.arraySyntaxCopy(parameters); + auto params = Parameter.arraySyntaxCopy(parameters); TypeFunction t = new TypeFunction(params, treturn, varargs, linkage); t.mod = mod; t.isnothrow = isnothrow; t.ispure = ispure; t.isproperty = isproperty; t.isref = isref; + t.trust = trust; return t; } @@ -145,8 +149,29 @@ tf.isnothrow = true; if (sc.stc & STC.STCref) tf.isref = true; + if (sc.stc & STCsafe) + tf.trust = TRUST.TRUSTsafe; + if (sc.stc & STCtrusted) + tf.trust = TRUST.TRUSTtrusted; + if (sc.stc & STCproperty) + tf.isproperty = true; + + tf.linkage = sc.linkage; + + /* If the parent is @safe, then this function defaults to safe + * too. + */ + if (tf.trust == TRUST.TRUSTdefault) + for (Dsymbol p = sc.func; p; p = p.toParent2()) + { FuncDeclaration fd = p.isFuncDeclaration(); + if (fd) + { + if (fd.isSafe()) + tf.trust = TRUST.TRUSTsafe; // default to @safe + break; + } + } - tf.linkage = sc.linkage; if (tf.next) { tf.next = tf.next.semantic(loc,sc); @@ -183,7 +208,7 @@ size_t dim = Argument.dim(tf.parameters); for (size_t i = 0; i < dim; i++) - { Argument arg = Argument.getNth(tf.parameters, i); + { auto arg = Parameter.getNth(tf.parameters, i); tf.inuse++; arg.type = arg.type.semantic(loc, argsc); @@ -220,7 +245,7 @@ * change. */ if (t.ty == TY.Ttuple) - { dim = Argument.dim(tf.parameters); + { dim = Parameter.dim(tf.parameters); i--; } } @@ -235,7 +260,10 @@ return terror; } - if (tf.varargs == 1 && tf.linkage != LINK.LINKd && Argument.dim(tf.parameters) == 0) + if (tf.isproperty && (tf.varargs || Parameter.dim(tf.parameters) > 1)) + error(loc, "properties can only have zero or one parameter"); + + if (tf.varargs == 1 && tf.linkage != LINK.LINKd && Parameter.dim(tf.parameters) == 0) error(loc, "variadic functions with non-D linkage must have at least one parameter"); /* Don't return merge(), because arg identifiers and default args @@ -274,7 +302,7 @@ case LINK.LINKcpp: mc = 'R'; break; } buf.writeByte(mc); - if (ispure || isnothrow || isproperty || isref) + if (ispure || isnothrow || isproperty || isref || trust) { if (ispure) buf.writestring("Na"); @@ -284,9 +312,18 @@ buf.writestring("Nc"); if (isproperty) buf.writestring("Nd"); + switch (trust) + { + case TRUST.TRUSTtrusted: + buf.writestring("Ne"); + break; + case TRUST.TRUSTsafe: + buf.writestring("Nd"); + break; + } } // Write argument types - Argument.argsToDecoBuffer(buf, parameters); + Parameter.argsToDecoBuffer(buf, parameters); //if (buf.data[buf.offset - 1] == '@') halt(); buf.writeByte('Z' - varargs); // mark end of arg list assert(next); @@ -324,6 +361,17 @@ if (isref) buf.writestring("ref "); + switch (trust) + { + case TRUST.TRUSTtrusted: + buf.writestring("@trusted "); + break; + + case TRUST.TRUSTsafe: + buf.writestring("@safe "); + break; + } + if (next && (!ident || ident.toHChars2() == ident.toChars())) next.toCBuffer2(buf, hgs, MODundefined); if (hgs.ddoc != 1) @@ -347,7 +395,7 @@ buf.writeByte(' '); buf.writestring(ident.toHChars2()); } - Argument.argsToCBuffer(buf, hgs, parameters, varargs); + Parameter.argsToCBuffer(buf, hgs, parameters, varargs); inuse--; } @@ -382,7 +430,7 @@ if (!hgs.hdrgen && p) buf.writestring(p); buf.writestring(" function"); - Argument.argsToCBuffer(buf, hgs, parameters, varargs); + Parameter.argsToCBuffer(buf, hgs, parameters, varargs); /* Use postfix style for attributes */ @@ -400,6 +448,16 @@ if (isref) buf.writestring(" ref"); + switch (trust) + { + case TRUSTtrusted: + buf.writestring(" @trusted"); + break; + + case TRUSTsafe: + buf.writestring(" @safe"); + break; + } inuse--; } @@ -417,8 +475,8 @@ linkage != tp.linkage) return MATCHnomatch; - size_t nfargs = Argument.dim(this.parameters); - size_t nfparams = Argument.dim(tp.parameters); + size_t nfargs = Parameter.dim(this.parameters); + size_t nfparams = Parameter.dim(tp.parameters); /* See if tuple match */ @@ -427,7 +485,7 @@ /* See if 'A' of the template parameter matches 'A' * of the type of the last function parameter. */ - Argument fparam = Argument.getNth(tp.parameters, nfparams - 1); + auto fparam = Parameter.getNth(tp.parameters, nfparams - 1); assert(fparam); assert(fparam.type); if (fparam.type.ty != Tident) @@ -465,7 +523,7 @@ return MATCHnomatch; for (size_t i = 0; i < tuple_dim; i++) { - Argument arg = Argument.getNth(this.parameters, nfparams - 1 + i); + auto arg = Parameter.getNth(this.parameters, nfparams - 1 + i); if (!arg.type.equals(t.objects[i])) return MATCHnomatch; } @@ -476,7 +534,7 @@ t.objects.setDim(tuple_dim); for (size_t i = 0; i < tuple_dim; i++) { - Argument arg = Argument.getNth(this.parameters, nfparams - 1 + i); + auto arg = Parameter.getNth(this.parameters, nfparams - 1 + i); t.objects[i] = arg.type; } dedtypes[tupi] = t; @@ -491,8 +549,8 @@ L2: for (size_t i = 0; i < nfparams; i++) { - Argument a = Argument.getNth(this.parameters, i); - Argument ap = Argument.getNth(tp.parameters, i); + auto a = Parameter.getNth(this.parameters, i); + auto ap = Parameter.getNth(tp.parameters, i); if (a.storageClass != ap.storageClass || !a.type.deduceType(sc, ap.type, parameters, dedtypes)) return MATCHnomatch; @@ -531,7 +589,7 @@ * Examine function signature for parameter p and see if * p can 'escape' the scope of the function. */ - bool parameterEscapes(Argument p) + bool parameterEscapes(Parameter p) { /* Scope parameters do not escape. * Allow 'lazy' to imply 'scope' - @@ -586,7 +644,7 @@ } } - size_t nparams = Argument.dim(parameters); + size_t nparams = Parameter.dim(parameters); size_t nargs = args ? args.dim : 0; if (nparams == nargs) { ; @@ -604,7 +662,7 @@ // BUG: what about out and ref? - Argument p = Argument.getNth(parameters, u); + auto p = Parameter.getNth(parameters, u); assert(p); if (u >= nargs) { @@ -745,10 +803,10 @@ type* tp; paramtypes = null; - size_t nparams = Argument.dim(parameters); + size_t nparams = Parameter.dim(parameters); for (size_t i = 0; i < nparams; i++) { - Argument arg = Argument.getNth(parameters, i); + auto arg = Parameter.getNth(parameters, i); tp = arg.type.toCtype(); if (arg.storageClass & (STC.STCout | STC.STCref)) {