Mercurial > projects > ddmd
diff dmd/FuncDeclaration.d @ 174:af724d3510d7
lot os toCBuffer methods implemented
moved shared Type.* stuff into Global
author | korDen |
---|---|
date | Sun, 10 Oct 2010 03:47:23 +0400 |
parents | 50a6d232176c |
children | 94b6033c07f3 |
line wrap: on
line diff
--- a/dmd/FuncDeclaration.d Sun Oct 10 01:55:35 2010 +0400 +++ b/dmd/FuncDeclaration.d Sun Oct 10 03:47:23 2010 +0400 @@ -131,7 +131,7 @@ Statement frequire; Statement fensure; Statement fbody; - + FuncDeclarations foverrides; // functions this function overrides FuncDeclaration fdrequire; // function that does the in contract FuncDeclaration fdensure; // function that does the out contract @@ -252,7 +252,7 @@ foverrides = new FuncDeclarations(); closureVars = new Dsymbols(); } - + override Dsymbol syntaxCopy(Dsymbol s) { FuncDeclaration f; @@ -271,7 +271,7 @@ return f; } - + // Do the semantic analysis on the external interface to the function. override void semantic(Scope sc) { @@ -313,7 +313,7 @@ sc.stc |= storage_class & STC.STCref; // forward refness to function type type = type.semantic(loc, sc); sc = sc.pop(); - + /* Apply const, immutable and shared storage class * to the function type */ @@ -339,17 +339,17 @@ // Don't use toInvariant(), as that will do a merge() type = type.makeInvariant(); goto Lmerge; - + case STC.STCconst: case STC.STCconst | STC.STCwild: type = type.makeConst(); goto Lmerge; - + case STC.STCshared | STC.STCconst: case STC.STCshared | STC.STCconst | STC.STCwild: type = type.makeSharedConst(); goto Lmerge; - + case STC.STCshared: type = type.makeShared(); goto Lmerge; @@ -368,10 +368,10 @@ */ type.deco = type.merge().deco; break; - + case STC.STCundefined: break; - + default: assert(0); } @@ -556,7 +556,7 @@ // Verify this doesn't override previous final function if (cd.baseClass) - { + { Dsymbol s = cd.baseClass.search(loc, ident, 0); if (s) { @@ -589,7 +589,7 @@ return; default: - { + { FuncDeclaration fdv = cast(FuncDeclaration)cd.vtbl.data[vi]; // This function is covariant with fdv if (fdv.isFinal()) @@ -619,7 +619,7 @@ } cd.vtbl.data[vi] = cast(void*)this; vtblIndex = vi; - + /* Remember which functions this overrides */ foverrides.push(fdv); @@ -669,7 +669,7 @@ default: { FuncDeclaration fdv = cast(FuncDeclaration)b.base.vtbl.data[vi]; Type ti = null; - + /* Remember which functions this overrides */ foverrides.push(fdv); @@ -689,7 +689,7 @@ if (offset) ti = fdv.type; else if (type.nextOf().ty == Tclass) - { + { ClassDeclaration cdn = (cast(TypeClass)type.nextOf()).sym; if (cdn && cdn.sizeok != 1) ti = fdv.type; @@ -805,7 +805,7 @@ } } } - + if (isVirtual()) { /* Rewrite contracts as nested functions, then call them. @@ -813,7 +813,7 @@ * can call them. */ if (frequire) - { + { /* in { ... } * becomes: * void __require() { ... } @@ -843,7 +843,7 @@ auto arguments = new Parameters(); Parameter a = null; if (outId) - { + { a = new Parameter(STCref, f.nextOf(), outId, null); arguments.push(a); } @@ -877,7 +877,7 @@ } error("identity assignment operator overload is illegal"); } - + override void semantic2(Scope sc) { } @@ -923,7 +923,7 @@ error("can only throw classes, not %s", t.toChars()); } } - + frequire = mergeFrequire(frequire); fensure = mergeFensure(fensure); @@ -1038,17 +1038,17 @@ Type t; if (f.linkage == LINK.LINKd) - { + { // Declare _arguments[] version (BREAKABI) { - v_arguments = new VarDeclaration(Loc(0), Type.typeinfotypelist.type, Id._arguments_typeinfo, null); + v_arguments = new VarDeclaration(Loc(0), global.typeinfotypelist.type, Id._arguments_typeinfo, null); v_arguments.storage_class = STCparameter; v_arguments.semantic(sc2); sc2.insert(v_arguments); v_arguments.parent = this; //t = Type.typeinfo.type.constOf().arrayOf(); - t = Type.typeinfo.type.arrayOf(); + t = global.typeinfo.type.arrayOf(); _arguments = new VarDeclaration(Loc(0), t, Id._arguments, null); _arguments.semantic(sc2); sc2.insert(_arguments); @@ -1197,7 +1197,7 @@ error("post conditions are not supported if the return type is inferred"); return; } - + ScopeDsymbol sym = new ScopeDsymbol(); sym.parent = sc2.scopesym; sc2 = sc2.push(sym); @@ -1309,7 +1309,7 @@ } sc2.incontract--; - + if (fbody) { ClassDeclaration cd = isClassMember(); @@ -1319,7 +1319,7 @@ { for (int i = 0; i < cd.fields.dim; i++) { VarDeclaration v = cast(VarDeclaration)cd.fields[i]; - + v.ctorinit = 0; } } @@ -1340,9 +1340,9 @@ } f = cast(TypeFunction)type; } - + if (isStaticCtorDeclaration()) - { + { /* It's a static constructor. Ensure that all * ctor consts were initialized. */ @@ -1425,7 +1425,7 @@ else { if (offend) - { + { Expression e; version (DMDV1) { warning(loc, "no return exp; or assert(0); at end of function"); @@ -1646,7 +1646,7 @@ { Expression vsync; if (isStatic()) - { + { // The monitor is in the ClassInfo vsync = new DotIdExp(loc, new DsymbolExp(loc, cd), Id.classinfo_); } @@ -1672,7 +1672,7 @@ } semanticRun = 4; } - + // called from semantic3 void varArgs(Scope sc, TypeFunction, ref VarDeclaration, ref VarDeclaration) { @@ -1687,7 +1687,7 @@ type.toCBuffer(buf, ident, hgs); bodyToCBuffer(buf, hgs); } - + void bodyToCBuffer(OutBuffer buf, HdrGenState* hgs) { if (fbody && @@ -1735,7 +1735,7 @@ buf.writenl(); } } - + /**************************************************** * Determine if 'this' overrides fd. * Return true if it does. @@ -1748,7 +1748,7 @@ { int cov = type.covariant(fd.type); if (cov) - { + { ClassDeclaration cd1 = toParent().isClassDeclaration(); ClassDeclaration cd2 = fd.toParent().isClassDeclaration(); @@ -1758,7 +1758,7 @@ } return result; } - + /************************************************* * Find index of function in vtbl[0..dim] that * this function overrides. @@ -1839,7 +1839,7 @@ * applied yet. */ if (type) - { + { printf("type = %s\n", type.toChars()); printf("f.type = %s\n", f.type.toChars()); } @@ -1859,7 +1859,7 @@ //printf("\ttrue: no conflict\n"); return true; } - + FuncDeclaration overloadExactMatch(Type t) { Param1 p; @@ -1868,7 +1868,7 @@ overloadApply(this, p); return p.f; } - + FuncDeclaration overloadResolve(Loc loc, Expression ethis, Expressions arguments, int flags = 0) { TypeFunction tf; @@ -1877,11 +1877,11 @@ static if (false) { printf("FuncDeclaration.overloadResolve('%s')\n", toChars()); if (arguments) - { + { int i; for (i = 0; i < arguments.dim; i++) - { + { Expression arg; arg = cast(Expression)arguments.data[i]; @@ -1953,7 +1953,7 @@ } } } - + /************************************* * Determine partial specialization order of 'this' vs g. * This is very similar to TemplateDeclaration.leastAsSpecialized(). @@ -2031,7 +2031,7 @@ } return MATCHnomatch; } - + /******************************** * Labels are in a separate scope, one per function. */ @@ -2051,7 +2051,7 @@ return cast(LabelDsymbol)s; } - + /**************************************** * If non-static member function that has a 'this' pointer, * return the aggregate it is a member of. @@ -2069,7 +2069,7 @@ //printf("-FuncDeclaration.isThis() %p\n", ad); return ad; } - + AggregateDeclaration isMember2() { AggregateDeclaration ad = null; @@ -2091,7 +2091,7 @@ //printf("-FuncDeclaration.isMember2() %p\n", ad); return ad; } - + /***************************************** * Determine lexical level difference from 'this' to nested function 'fd'. * Error if this cannot call fd. @@ -2117,7 +2117,7 @@ //printf("\ts = '%s'\n", s.toChars()); FuncDeclaration thisfd = s.isFuncDeclaration(); if (thisfd) - { + { if (!thisfd.isNested() && !thisfd.vthis) goto Lerr; } @@ -2125,7 +2125,7 @@ { AggregateDeclaration thiscd = s.isAggregateDeclaration(); if (thiscd) - { + { if (!thiscd.isNested()) goto Lerr; } @@ -2172,7 +2172,7 @@ return Declaration.mangle(); } - + override string toPrettyChars() { if (isMain()) @@ -2180,12 +2180,12 @@ else return Dsymbol.toPrettyChars(); } - + int isMain() { return ident is Id.main && linkage != LINK.LINKc && !isMember() && !isNested(); } - + int isWinMain() { //printf("FuncDeclaration::isWinMain() %s\n", toChars()); @@ -2248,41 +2248,41 @@ return builtin; } - + override bool isExport() { return protection == PROT.PROTexport; } - + override bool isImportedSymbol() { //printf("isImportedSymbol()\n"); //printf("protection = %d\n", protection); return (protection == PROT.PROTexport) && !fbody; } - + override bool isAbstract() { return (storage_class & STC.STCabstract) != 0; } - + override bool isCodeseg() { return true; // functions are always in the code segment } - + override bool isOverloadable() { return 1; // functions can be overloaded } - + bool isPure() { //printf("FuncDeclaration::isPure() '%s'\n", toChars()); assert(type.ty == TY.Tfunction); return (cast(TypeFunction)this.type).ispure; } - + int isSafe() { assert(type.ty == TY.Tfunction); @@ -2294,7 +2294,7 @@ assert(type.ty == TY.Tfunction); return (cast(TypeFunction)this.type).trust == TRUST.TRUSTtrusted; } - + bool isNested() { //if (!toParent()) @@ -2303,7 +2303,7 @@ return ((storage_class & STC.STCstatic) == 0) && (toParent2().isFuncDeclaration() !is null); } - + override bool needThis() { //printf("FuncDeclaration.needThis() '%s'\n", toChars()); @@ -2318,7 +2318,7 @@ return needThis; } - + bool isVirtual() { static if (false) { @@ -2329,7 +2329,7 @@ } return isMember() && !(isStatic() || protection == PROT.PROTprivate || protection == PROT.PROTpackage) && toParent().isClassDeclaration(); } - + override bool isFinal() { ClassDeclaration cd; @@ -2341,7 +2341,7 @@ } return isMember() && (Declaration.isFinal() || ((cd = toParent().isClassDeclaration()) !is null && cd.storage_class & STC.STCfinal)); } - + bool addPreInvariant() { AggregateDeclaration ad = isThis(); @@ -2352,24 +2352,24 @@ !naked && ident !is Id.cpctor); } - + bool addPostInvariant() { AggregateDeclaration ad = isThis(); - return (ad && ad.inv && + return (ad && ad.inv && //ad.isClassDeclaration() && global.params.useInvariants && (protection == PROT.PROTpublic || protection == PROT.PROTexport) && !naked && ident !is Id.cpctor); } - + /************************************* * Attempt to interpret a function given the arguments. * Input: * istate state for calling function (null if none) * arguments function arguments - * thisarg 'this', if a needThis() function, null if not. + * thisarg 'this', if a needThis() function, null if not. * * Return result expression if successful, null if not. */ @@ -2402,12 +2402,12 @@ return interpret_values(istate, thisarg, this); } } - + if (cantInterpret || semanticRun == 3) return null; if (!fbody) - { + { cantInterpret = 1; return null; } @@ -2426,21 +2426,21 @@ TypeFunction tf = cast(TypeFunction)tb; Type tret = tf.next.toBasetype(); if (tf.varargs && arguments && parameters && arguments.dim != parameters.dim) - { + { cantInterpret = 1; error("C-style variadic functions are not yet implemented in CTFE"); return null; } - + // Ensure there are no lazy parameters if (tf.parameters) - { + { size_t dim = Parameter.dim(tf.parameters); for (size_t i = 0; i < dim; i++) - { + { auto arg = Parameter.getNth(tf.parameters, i); if (arg.storageClass & STClazy) - { + { cantInterpret = 1; return null; } @@ -2455,7 +2455,7 @@ scope Expressions vsave = new Expressions(); // place to save previous parameter values size_t dim = 0; if (needThis() && !thisarg) - { + { cantInterpret = 1; // error, no this. Prevent segfault. error("need 'this' to access member %s", toChars()); @@ -2474,7 +2474,7 @@ eargs.setDim(dim); for (size_t i = 0; i < dim; i++) - { + { Expression earg = arguments[i]; auto arg = Parameter.getNth(tf.parameters, i); @@ -2494,7 +2494,7 @@ } earg = earg.interpret(istate ? istate : istatex); if (earg is EXP_CANT_INTERPRET) - { + { cantInterpret = 1; return null; } @@ -2503,7 +2503,7 @@ } for (size_t i = 0; i < dim; i++) - { + { auto earg = eargs[i]; auto arg = Parameter.getNth(tf.parameters, i); auto v = cast(VarDeclaration)parameters[i]; @@ -2517,11 +2517,11 @@ * variable v2 */ if (!istate) - { + { cantInterpret = 1; error("%s cannot be by passed by reference at compile time", earg.toChars()); return null; // can't bind to non-interpreted vars - } + } // We need to chase down all of the the passed parameters until // we find something that isn't a TOKvar, then create a variable // containg that expression. @@ -2531,14 +2531,14 @@ VarExp ve = cast(VarExp)earg; v2 = ve.var.isVarDeclaration(); if (!v2) - { + { cantInterpret = 1; return null; } if (!v2.value || v2.value.op != TOKvar) break; - if ((cast(VarExp)v2.value).var.isSymbolDeclaration()) - { + if ((cast(VarExp)v2.value).var.isSymbolDeclaration()) + { // This can happen if v is a struct initialized to // 0 using an __initZ SymbolDeclaration from // TypeStruct.defaultInit() @@ -2553,17 +2553,17 @@ */ assert(istate); foreach(size_t j, Dsymbol s2; istate.vars)// (size_t j = 0; j < istate.vars.dim; j++) - { + { auto vd = cast(VarDeclaration)s2; if (vd == v2) - { + { istate.vars[j] = null; break; } } } else - { + { // Value parameters and non-trivial references v.value = earg; } @@ -2576,10 +2576,10 @@ if (needThis() && thisarg.op == TOKvar && istate) { VarDeclaration thisvar = (cast(VarExp)thisarg).var.isVarDeclaration(); foreach (size_t i, Dsymbol s; istate.vars) - { + { auto v = cast(VarDeclaration)s; if (v == thisvar) - { + { istate.vars[i] = null; break; } @@ -2594,7 +2594,7 @@ //printf("saving local variables...\n"); valueSaves.setDim(istate.vars.dim); foreach (size_t i, Dsymbol s3; istate.vars) - { + { if (auto v = cast(VarDeclaration)s3) { //printf("\tsaving [%d] %s = %s\n", i, v.toChars(), v.value ? v.value.toChars() : ""); @@ -2644,9 +2644,9 @@ */ //printf("restoring local variables...\n"); foreach (size_t i , Dsymbol s3; istate.vars) - { + { if (auto v = cast(VarDeclaration)s3) - { + { v.value = valueSaves[i]; //printf("\trestoring [%d] %s = %s\n", i, v.toChars(), v.value ? v.value.toChars() : ""); } @@ -2654,7 +2654,7 @@ } return e; } - + override void inlineScan() { InlineScanState iss; @@ -2671,7 +2671,7 @@ inlineNest--; } } - + int canInline(int hasthis, int hdrscan = 0) { int cost; @@ -2715,7 +2715,7 @@ } if (type) - { + { assert(type.ty == Tfunction); TypeFunction tf = cast(TypeFunction)type; if (tf.varargs == 1) // no variadic parameter lists @@ -2730,7 +2730,7 @@ goto Lno; } else - { + { CtorDeclaration ctor = isCtorDeclaration(); if (ctor && ctor.varargs == 1) goto Lno; @@ -2826,7 +2826,7 @@ version (STRUCTTHISREF) { if (ethis.type.ty == Tpointer) - { + { Type t = ethis.type.nextOf(); ethis = new PtrExp(ethis.loc, ethis); ethis.type = t; @@ -2859,7 +2859,7 @@ ei.exp.type = ve.type; version (STRUCTTHISREF) { if (ethis.type.ty != Tclass) - { + { /* This is a reference initialization, not a simple assignment. */ ei.exp.op = TOKconstruct; @@ -2935,15 +2935,15 @@ { assert(false); } - + FuncDeclaration isUnique() - { + { Unique unique; overloadApply(this, unique); - + return unique.f; } - + /******************************* * Look at all the variables in this function that are referenced * by nested functions, and determine if a closure needs to be @@ -2967,7 +2967,7 @@ //printf("FuncDeclaration.needsClosure() %s\n", toChars()); foreach (Dsymbol s3; closureVars) - { + { auto v = cast(VarDeclaration)s3; assert(v.isVarDeclaration()); //printf("\tv = %s\n", v.toChars()); @@ -2996,7 +2996,7 @@ //printf("\tneeds closure\n"); return true; } - + /**************************************************** * Merge into this function the 'in' contracts of all it overrides. * 'in's are OR'd together, i.e. only one of them needs to pass. @@ -3035,7 +3035,7 @@ Statement s2 = new ExpStatement(loc, e); if (sf) - { + { Catch c = new Catch(loc, null, null, sf); Array catches = new Array(); catches.push(cast(void*)c); @@ -3087,12 +3087,12 @@ } return sf; } - + static FuncDeclaration genCfunc(Type treturn, string name) { return genCfunc(treturn, Lexer.idPool(name)); } - + /********************************** * Generate a FuncDeclaration for a runtime library function. */ @@ -3124,7 +3124,7 @@ } return fd; } - + override Symbol* toSymbol() { if (!csym) @@ -3156,12 +3156,12 @@ f.Fstartline.Slinnum = loc.linnum; f.Fstartline.Sfilename = cast(char*)toStringz(loc.filename); if (endloc.linnum) - { + { f.Fendline.Slinnum = endloc.linnum; f.Fendline.Sfilename = cast(char*)toStringz(endloc.filename); } else - { + { f.Fendline.Slinnum = loc.linnum; f.Fendline.Sfilename = cast(char*)toStringz(loc.filename); } @@ -3227,7 +3227,7 @@ } return csym; } - + Symbol* toThunkSymbol(int offset) // thunk version { Symbol *sthunk; @@ -3256,14 +3256,14 @@ cod3_thunk(sthunk, csym, 0, TYnptr, -offset, -1, 0); return sthunk; } - + override void toObjFile(int multiobj) // compile to .obj file { Symbol* s; func_t* f; Symbol* senter; Symbol* sexit; - + FuncDeclaration func = this; ClassDeclaration cd = func.parent.isClassDeclaration(); int reverse; @@ -3286,7 +3286,7 @@ } if (multiobj && !isStaticDtorDeclaration() && !isStaticCtorDeclaration()) - { + { obj_append(this); return; } @@ -3294,8 +3294,6 @@ if (semanticRun >= 5) // if toObjFile() already run return; - semanticRun = 5; - if (!func.fbody) { return; @@ -3309,7 +3307,7 @@ s = func.toSymbol(); f = s.Sfunc; - + version (TARGET_WINDOS) { /* This is done so that the 'this' pointer on the stack is the same @@ -3416,7 +3414,7 @@ sprintf(hiddenparam.ptr, "__HID%d".ptr, ++hiddenparami); shidden = symbol_name(hiddenparam.ptr, SC.SCparameter, thidden); shidden.Sflags |= SFL.SFLtrue | SFL.SFLfree; - + version (DMDV1) { bool nestedref = func.nrvo_can && func.nrvo_var && func.nrvo_var.nestedref; } else { @@ -3448,9 +3446,9 @@ pi += parameters.dim; // Allow extra 2 for sthis and shidden - version (Bug4054) +version (Bug4054) params = cast(Symbol**)GC.malloc((pi + 2) * (Symbol*).sizeof); - else +else params = cast(Symbol**)alloca((pi + 2) * (Symbol*).sizeof); // Get the actual number of parameters, pi, and fill in the params[] @@ -3464,7 +3462,7 @@ { size_t i = 0; for ( ; i < parameters.dim; ++i) - { + { auto v = cast(VarDeclaration)parameters[i]; if (v.csym) @@ -3478,10 +3476,10 @@ } if (reverse) - { + { // Reverse params[] entries for (size_t i = 0; i < pi/2; i++) - { + { Symbol* sptmp = params[i]; params[i] = params[pi - 1 - i]; params[pi - 1 - i] = sptmp; @@ -3526,7 +3524,7 @@ } for (size_t i = 0; i < pi; i++) - { + { Symbol *sp = params[i]; sp.Sclass = SC.SCparameter; sp.Sflags &= ~SFL.SFLspill; @@ -3539,7 +3537,7 @@ { Symbol* sp = params[0]; if ((tyf == TYM.TYjfunc || tyf == TYM.TYmfunc) && type_jparam(sp.Stype)) - { + { sp.Sclass = SC.SCfastpar; sp.Spreg = (tyf == TYM.TYjfunc) ? REG.AX : REG.CX; sp.Sfl = FL.FLauto; @@ -3548,7 +3546,7 @@ } if (func.fbody) - { + { block* b; Blockx bx; Statement sbody; @@ -3572,7 +3570,7 @@ if (func.isSynchronized()) { if (cd) - { + { elem *esync; if (func.isStatic()) { // monitor is in ClassInfo @@ -3637,7 +3635,7 @@ b.Belem = el_combine(b.Belem, el_var(sthis)); } } - } + } } // If static constructor @@ -3660,7 +3658,7 @@ StaticDtorDeclaration f2 = isStaticDtorDeclaration(); assert(f2); if (f2.vgate) - { + { /* Increment destructor's vgate at construction time */ ectorgates.push(cast(void*)f2); @@ -3682,7 +3680,7 @@ return; writefunc(s); - + if (isExport()) { obj_export(s, Poffset); } @@ -3700,19 +3698,19 @@ } } version (DMDV2) { - if (irs.startaddress) + if (irs.startaddress) { writef("Setting start address\n"); obj_startaddress(irs.startaddress); } } } - + override int cvMember(ubyte* p) { assert(false); } - + /************************************* * Closures are implemented by taking the local variables that * need to survive the scope of the function, and copying them @@ -3735,7 +3733,7 @@ void buildClosure(IRState* irs) { if (needsClosure()) - { + { // Generate closure on the heap // BUG: doesn't capture variadic arguments passed to this function @@ -3762,7 +3760,7 @@ uint offset = PTRSIZE; // leave room for previous sthis foreach (Dsymbol s3; closureVars) - { + { auto v = cast(VarDeclaration)s3; assert(v.isVarDeclaration()); @@ -3843,7 +3841,7 @@ ex = el_bin(OPER.OPadd, TYM.TYnptr, el_var(sclosure), el_long(TYM.TYint, v.offset)); ex = el_una(OPER.OPind, tym, ex); if (ex.Ety == TYM.TYstruct) - { + { ex.Enumbytes = cast(uint)v.type.size(); ex = el_bin(OPER.OPstreq, tym, ex, el_var(v.toSymbol())); ex.Enumbytes = cast(uint)v.type.size(); @@ -3892,4 +3890,4 @@ override FuncDeclaration isFuncDeclaration() { return this; } } -alias Vector!FuncDeclaration FuncDeclarations; \ No newline at end of file +alias Vector!FuncDeclaration FuncDeclarations;