diff --git a/src/aggregate.h b/src/aggregate.h index 934a2bbd8022..0e4c8bd845d3 100644 --- a/src/aggregate.h +++ b/src/aggregate.h @@ -120,7 +120,7 @@ struct StructDeclaration : AggregateDeclaration void semantic(Scope *sc); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); char *mangle(); - char *kind(); + const char *kind(); int needOpAssign(); FuncDeclaration *buildOpAssign(Scope *sc); FuncDeclaration *buildPostBlit(Scope *sc); @@ -140,7 +140,7 @@ struct UnionDeclaration : StructDeclaration { UnionDeclaration(Loc loc, Identifier *id); Dsymbol *syntaxCopy(Dsymbol *s); - char *kind(); + const char *kind(); UnionDeclaration *isUnionDeclaration() { return this; } }; @@ -229,7 +229,7 @@ struct ClassDeclaration : AggregateDeclaration #endif int isAbstract(); virtual int vtblOffset(); - char *kind(); + const char *kind(); char *mangle(); void toDocBuffer(OutBuffer *buf); @@ -261,7 +261,7 @@ struct InterfaceDeclaration : ClassDeclaration void semantic(Scope *sc); int isBaseOf(ClassDeclaration *cd, int *poffset); int isBaseOf(BaseClass *bc, int *poffset); - char *kind(); + const char *kind(); int vtblOffset(); #if V2 int isCPPinterface(); diff --git a/src/attrib.c b/src/attrib.c index fd5c63ca00ca..a7a63607174d 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -206,7 +206,7 @@ int AttribDeclaration::hasPointers() return 0; } -char *AttribDeclaration::kind() +const char *AttribDeclaration::kind() { return "attribute"; } @@ -703,9 +703,9 @@ void AnonDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) buf->writestring("}\n"); } -char *AnonDeclaration::kind() +const char *AnonDeclaration::kind() { - return (char *)(isunion ? "anonymous union" : "anonymous struct"); + return (isunion ? "anonymous union" : "anonymous struct"); } /********************************* PragmaDeclaration ****************************/ @@ -883,7 +883,7 @@ int PragmaDeclaration::oneMember(Dsymbol **ps) return TRUE; } -char *PragmaDeclaration::kind() +const char *PragmaDeclaration::kind() { return "pragma"; } @@ -1123,7 +1123,7 @@ void StaticIfDeclaration::semantic(Scope *sc) } } -char *StaticIfDeclaration::kind() +const char *StaticIfDeclaration::kind() { return "static if"; } @@ -1134,6 +1134,8 @@ char *StaticIfDeclaration::kind() CompileDeclaration::CompileDeclaration(Loc loc, Expression *exp) : AttribDeclaration(NULL) { + //printf("CompileDeclaration(loc = %d)\n", loc.linnum); + this->loc = loc; this->exp = exp; this->sd = NULL; this->compiled = 0; @@ -1162,12 +1164,12 @@ int CompileDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum) void CompileDeclaration::compileIt(Scope *sc) { - //printf("CompileDeclaration::compileIt()\n"); + //printf("CompileDeclaration::compileIt(loc = %d)\n", loc.linnum); exp = exp->semantic(sc); exp = resolveProperties(sc, exp); exp = exp->optimize(WANTvalue | WANTinterpret); if (exp->op != TOKstring) - { error("argument to mixin must be a string, not (%s)", exp->toChars()); + { exp->error("argument to mixin must be a string, not (%s)", exp->toChars()); } else { @@ -1178,7 +1180,7 @@ void CompileDeclaration::compileIt(Scope *sc) p.nextToken(); decl = p.parseDeclDefs(0); if (p.token.value != TOKeof) - error("incomplete mixin declaration (%s)", se->toChars()); + exp->error("incomplete mixin declaration (%s)", se->toChars()); } } diff --git a/src/attrib.h b/src/attrib.h index 8823b7dc851f..250c8157c7e4 100644 --- a/src/attrib.h +++ b/src/attrib.h @@ -42,7 +42,7 @@ struct AttribDeclaration : Dsymbol void inlineScan(); void addComment(unsigned char *comment); void emitComment(Scope *sc); - char *kind(); + const char *kind(); int oneMember(Dsymbol **ps); int hasPointers(); void checkCtorConstInit(); @@ -106,7 +106,7 @@ struct AnonDeclaration : AttribDeclaration Dsymbol *syntaxCopy(Dsymbol *s); void semantic(Scope *sc); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - char *kind(); + const char *kind(); }; struct PragmaDeclaration : AttribDeclaration @@ -118,7 +118,7 @@ struct PragmaDeclaration : AttribDeclaration void semantic(Scope *sc); int oneMember(Dsymbol **ps); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - char *kind(); + const char *kind(); void toObjFile(int multiobj); // compile to .obj file }; @@ -145,7 +145,7 @@ struct StaticIfDeclaration : ConditionalDeclaration Dsymbol *syntaxCopy(Dsymbol *s); int addMember(Scope *sc, ScopeDsymbol *s, int memnum); void semantic(Scope *sc); - char *kind(); + const char *kind(); }; // Mixin declarations diff --git a/src/class.c b/src/class.c index d495c55d7717..e0c8faa7448d 100644 --- a/src/class.c +++ b/src/class.c @@ -548,7 +548,7 @@ void ClassDeclaration::semantic(Scope *sc) // sc->offset += PTRSIZE; // room for uplevel context pointer } else - { sc->offset = 8; // allow room for vptr[] and monitor + { sc->offset = PTRSIZE * 2; // allow room for __vptr and __monitor alignsize = 4; } structsize = sc->offset; @@ -609,7 +609,7 @@ void ClassDeclaration::semantic(Scope *sc) if (!ctor && baseClass && baseClass->ctor) { //printf("Creating default this(){} for class %s\n", toChars()); - ctor = new CtorDeclaration(0, 0, NULL, 0); + ctor = new CtorDeclaration(loc, 0, NULL, 0); ctor->fbody = new CompoundStatement(0, new Statements()); members->push(ctor); ctor->addMember(sc, this, 1); @@ -971,7 +971,7 @@ int ClassDeclaration::vtblOffset() /**************************************** */ -char *ClassDeclaration::kind() +const char *ClassDeclaration::kind() { return "class"; } @@ -1179,7 +1179,7 @@ void InterfaceDeclaration::semantic(Scope *sc) sc->linkage = LINKcpp; sc->structalign = 8; structalign = sc->structalign; - sc->offset = 8; + sc->offset = PTRSIZE * 2; inuse++; for (i = 0; i < members->dim; i++) { @@ -1292,7 +1292,7 @@ int InterfaceDeclaration::isCPPinterface() /******************************************* */ -char *InterfaceDeclaration::kind() +const char *InterfaceDeclaration::kind() { return "interface"; } diff --git a/src/constfold.c b/src/constfold.c index 5e0ebaccba56..89b009a58b86 100644 --- a/src/constfold.c +++ b/src/constfold.c @@ -460,7 +460,7 @@ Expression *Div(Type *type, Expression *e1, Expression *e2) n2 = e2->toInteger(); if (n2 == 0) { e2->error("divide by 0"); - e2 = new IntegerExp(0, 1, e2->type); + e2 = new IntegerExp(loc, 1, e2->type); n2 = 1; } if (e1->type->isunsigned() || e2->type->isunsigned()) @@ -523,7 +523,7 @@ Expression *Mod(Type *type, Expression *e1, Expression *e2) n2 = e2->toInteger(); if (n2 == 0) { e2->error("divide by 0"); - e2 = new IntegerExp(0, 1, e2->type); + e2 = new IntegerExp(loc, 1, e2->type); n2 = 1; } if (e1->type->isunsigned() || e2->type->isunsigned()) @@ -632,26 +632,21 @@ Expression *Ushr(Type *type, Expression *e1, Expression *e2) } Expression *And(Type *type, Expression *e1, Expression *e2) -{ Expression *e; - Loc loc = e1->loc; - - e = new IntegerExp(loc, e1->toInteger() & e2->toInteger(), type); +{ + Expression *e; + e = new IntegerExp(e1->loc, e1->toInteger() & e2->toInteger(), type); return e; } Expression *Or(Type *type, Expression *e1, Expression *e2) { Expression *e; - Loc loc = e1->loc; - - e = new IntegerExp(loc, e1->toInteger() | e2->toInteger(), type); + e = new IntegerExp(e1->loc, e1->toInteger() | e2->toInteger(), type); return e; } Expression *Xor(Type *type, Expression *e1, Expression *e2) { Expression *e; - Loc loc = e1->loc; - - e = new IntegerExp(loc, e1->toInteger() ^ e2->toInteger(), type); + e = new IntegerExp(e1->loc, e1->toInteger() ^ e2->toInteger(), type); return e; } @@ -1166,7 +1161,7 @@ Expression *Cast(Type *type, Type *to, Expression *e1) else { error(loc, "cannot cast %s to %s", e1->type->toChars(), type->toChars()); - e = new IntegerExp(loc, 0, type); + e = new IntegerExp(loc, 0, Type::tint32); } return e; } @@ -1472,7 +1467,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2) if (type->toBasetype()->ty == Tsarray) { - e->type = new TypeSArray(t1->nextOf(), new IntegerExp(0, es1->elements->dim, Type::tindex)); + e->type = new TypeSArray(t1->nextOf(), new IntegerExp(loc, es1->elements->dim, Type::tindex)); e->type = e->type->semantic(loc, NULL); } else @@ -1495,7 +1490,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2) if (type->toBasetype()->ty == Tsarray) { - e->type = new TypeSArray(e2->type, new IntegerExp(0, es1->elements->dim, Type::tindex)); + e->type = new TypeSArray(e2->type, new IntegerExp(loc, es1->elements->dim, Type::tindex)); e->type = e->type->semantic(loc, NULL); } else @@ -1512,7 +1507,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2) if (type->toBasetype()->ty == Tsarray) { - e->type = new TypeSArray(e1->type, new IntegerExp(0, es2->elements->dim, Type::tindex)); + e->type = new TypeSArray(e1->type, new IntegerExp(loc, es2->elements->dim, Type::tindex)); e->type = e->type->semantic(loc, NULL); } else diff --git a/src/declaration.c b/src/declaration.c index d7832ecbcbe6..70ce8e10c26a 100644 --- a/src/declaration.c +++ b/src/declaration.c @@ -39,7 +39,7 @@ void Declaration::semantic(Scope *sc) { } -char *Declaration::kind() +const char *Declaration::kind() { return "declaration"; } @@ -167,7 +167,7 @@ Dsymbol *TupleDeclaration::syntaxCopy(Dsymbol *s) return NULL; } -char *TupleDeclaration::kind() +const char *TupleDeclaration::kind() { return "tuple"; } @@ -301,6 +301,7 @@ void TypedefDeclaration::semantic(Scope *sc) type = type->semantic(loc, sc); if (sc->parent->isFuncDeclaration() && init) semantic2(sc); + storage_class |= sc->stc & STCdeprecated; } else if (sem == 1) { @@ -327,7 +328,7 @@ void TypedefDeclaration::semantic2(Scope *sc) } } -char *TypedefDeclaration::kind() +const char *TypedefDeclaration::kind() { return "typedef"; } @@ -531,7 +532,7 @@ int AliasDeclaration::overloadInsert(Dsymbol *s) } } -char *AliasDeclaration::kind() +const char *AliasDeclaration::kind() { return "alias"; } @@ -1096,7 +1097,7 @@ void VarDeclaration::semantic2(Scope *sc) } } -char *VarDeclaration::kind() +const char *VarDeclaration::kind() { return "variable"; } @@ -1217,7 +1218,7 @@ ExpInitializer *VarDeclaration::getExpInitializer() ei = init->isExpInitializer(); else { - Expression *e = type->defaultInit(); + Expression *e = type->defaultInit(loc); if (e) ei = new ExpInitializer(loc, e); else diff --git a/src/declaration.h b/src/declaration.h index 8e5ae478cfbd..314f44a1fb27 100644 --- a/src/declaration.h +++ b/src/declaration.h @@ -99,7 +99,7 @@ struct Declaration : Dsymbol Declaration(Identifier *id); void semantic(Scope *sc); - char *kind(); + const char *kind(); unsigned size(Loc loc); void checkModify(Loc loc, Scope *sc, Type *t); @@ -145,7 +145,7 @@ struct TupleDeclaration : Declaration TupleDeclaration(Loc loc, Identifier *ident, Objects *objects); Dsymbol *syntaxCopy(Dsymbol *); - char *kind(); + const char *kind(); Type *getType(); int needThis(); @@ -169,7 +169,7 @@ struct TypedefDeclaration : Declaration void semantic(Scope *sc); void semantic2(Scope *sc); char *mangle(); - char *kind(); + const char *kind(); Type *getType(); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); #ifdef _DH @@ -202,7 +202,7 @@ struct AliasDeclaration : Declaration Dsymbol *syntaxCopy(Dsymbol *); void semantic(Scope *sc); int overloadInsert(Dsymbol *s); - char *kind(); + const char *kind(); Type *getType(); Dsymbol *toAlias(); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); @@ -238,7 +238,7 @@ struct VarDeclaration : Declaration Dsymbol *syntaxCopy(Dsymbol *); void semantic(Scope *sc); void semantic2(Scope *sc); - char *kind(); + const char *kind(); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); #ifdef _DH Type *htype; @@ -558,7 +558,7 @@ struct FuncDeclaration : Declaration void inlineScan(); int canInline(int hasthis, int hdrscan = 0); Expression *doInline(InlineScanState *iss, Expression *ethis, Array *arguments); - char *kind(); + const char *kind(); void toDocBuffer(OutBuffer *buf); FuncDeclaration *isUnique(); int needsClosure(); @@ -582,7 +582,7 @@ struct FuncAliasDeclaration : FuncDeclaration FuncAliasDeclaration(FuncDeclaration *funcalias); FuncAliasDeclaration *isFuncAliasDeclaration() { return this; } - char *kind(); + const char *kind(); Symbol *toSymbol(); }; @@ -595,9 +595,10 @@ struct FuncLiteralDeclaration : FuncDeclaration void toCBuffer(OutBuffer *buf, HdrGenState *hgs); Dsymbol *syntaxCopy(Dsymbol *); int isNested(); + int isVirtual(); FuncLiteralDeclaration *isFuncLiteralDeclaration() { return this; } - char *kind(); + const char *kind(); }; struct CtorDeclaration : FuncDeclaration @@ -608,7 +609,7 @@ struct CtorDeclaration : FuncDeclaration Dsymbol *syntaxCopy(Dsymbol *); void semantic(Scope *sc); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - char *kind(); + const char *kind(); char *toChars(); int isVirtual(); int addPreInvariant(); @@ -722,7 +723,7 @@ struct NewDeclaration : FuncDeclaration Dsymbol *syntaxCopy(Dsymbol *); void semantic(Scope *sc); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - char *kind(); + const char *kind(); int isVirtual(); int addPreInvariant(); int addPostInvariant(); @@ -738,7 +739,7 @@ struct DeleteDeclaration : FuncDeclaration Dsymbol *syntaxCopy(Dsymbol *); void semantic(Scope *sc); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - char *kind(); + const char *kind(); int isDelete(); int isVirtual(); int addPreInvariant(); diff --git a/src/doc.c b/src/doc.c index f5b9f612ea77..5c486b7ca6c2 100644 --- a/src/doc.c +++ b/src/doc.c @@ -417,8 +417,9 @@ void ScopeDsymbol::emitMemberComments(Scope *sc) else if (isTemplateDeclaration()) m = "$(DDOC_TEMPLATE_MEMBERS \n"; - // BUG: if no members are actually printed, we should not emit DDOC_MEMBERS + unsigned offset1 = buf->offset; // save starting offset buf->writestring(m); + unsigned offset2 = buf->offset; // to see if we write anything sc = sc->push(this); for (int i = 0; i < members->dim; i++) { @@ -427,7 +428,14 @@ void ScopeDsymbol::emitMemberComments(Scope *sc) s->emitComment(sc); } sc->pop(); - buf->writestring(")\n"); + if (buf->offset == offset2) + { + /* Didn't write out any members, so back out last write + */ + buf->offset = offset1; + } + else + buf->writestring(")\n"); } } @@ -448,7 +456,9 @@ void emitProtection(OutBuffer *buf, PROT prot) void Dsymbol::emitComment(Scope *sc) { } void InvariantDeclaration::emitComment(Scope *sc) { } +#if V2 void PostBlitDeclaration::emitComment(Scope *sc) { } +#endif void DtorDeclaration::emitComment(Scope *sc) { } void StaticCtorDeclaration::emitComment(Scope *sc) { } void StaticDtorDeclaration::emitComment(Scope *sc) { } @@ -525,12 +535,8 @@ void TemplateDeclaration::emitComment(Scope *sc) //printf("TemplateDeclaration::emitComment() '%s', kind = %s\n", toChars(), kind()); if (prot() == PROTprivate) return; - if (!comment) - return; - OutBuffer *buf = sc->docbuf; - DocComment *dc = DocComment::parse(sc, this, comment); - unsigned o; + unsigned char *com = comment; int hasmembers = 1; Dsymbol *ss = this; @@ -542,12 +548,22 @@ void TemplateDeclaration::emitComment(Scope *sc) { ss = onemember->isFuncDeclaration(); if (ss) - hasmembers = 0; + { hasmembers = 0; + if (com != ss->comment) + com = Lexer::combineComments(com, ss->comment); + } else ss = this; } } + if (!com) + return; + + OutBuffer *buf = sc->docbuf; + DocComment *dc = DocComment::parse(sc, this, com); + unsigned o; + if (!dc) { ss->emitDitto(sc); diff --git a/src/dsymbol.c b/src/dsymbol.c index 695e195fef00..aa58b72a28ba 100644 --- a/src/dsymbol.c +++ b/src/dsymbol.c @@ -192,7 +192,7 @@ char *Dsymbol::locToChars() return loc.toChars(); } -char *Dsymbol::kind() +const char *Dsymbol::kind() { return "symbol"; } @@ -612,7 +612,7 @@ void OverloadSet::push(Dsymbol *s) a.push(s); } -char *OverloadSet::kind() +const char *OverloadSet::kind() { return "overloadset"; } @@ -846,7 +846,7 @@ Dsymbol *ScopeDsymbol::nameCollision(Dsymbol *s) return sprev; } -char *ScopeDsymbol::kind() +const char *ScopeDsymbol::kind() { return "ScopeDsymbol"; } diff --git a/src/dsymbol.h b/src/dsymbol.h index 7df863e2f93b..4b45460509b5 100644 --- a/src/dsymbol.h +++ b/src/dsymbol.h @@ -120,7 +120,7 @@ struct Dsymbol : Object static Array *arraySyntaxCopy(Array *a); - virtual char *kind(); + virtual const char *kind(); virtual Dsymbol *toAlias(); // resolve real symbol virtual int addMember(Scope *sc, ScopeDsymbol *s, int memnum); virtual void semantic(Scope *sc); @@ -233,7 +233,7 @@ struct ScopeDsymbol : Dsymbol void defineRef(Dsymbol *s); static void multiplyDefined(Loc loc, Dsymbol *s1, Dsymbol *s2); Dsymbol *nameCollision(Dsymbol *s); - char *kind(); + const char *kind(); FuncDeclaration *findGetMembers(); void emitMemberComments(Scope *sc); @@ -282,7 +282,7 @@ struct OverloadSet : Dsymbol OverloadSet(); void push(Dsymbol *s); OverloadSet *isOverloadSet() { return this; } - char *kind(); + const char *kind(); }; // Table of Dsymbol's diff --git a/src/e2ir.c b/src/e2ir.c index 308d867039e6..1070045f8746 100644 --- a/src/e2ir.c +++ b/src/e2ir.c @@ -482,7 +482,7 @@ elem *eval_Darray(IRState *irs, Expression *e) /************************************ */ -elem *sarray_toDarray(Type *tfrom, Type *tto, elem *e) +elem *sarray_toDarray(Loc loc, Type *tfrom, Type *tto, elem *e) { //printf("sarray_toDarray()\n"); //elem_print(e); @@ -498,7 +498,7 @@ elem *sarray_toDarray(Type *tfrom, Type *tto, elem *e) if ((dim * fsize) % tsize != 0) { Lerr: - error((Loc)0, "cannot cast %s to %s since sizes don't line up", tfrom->toChars(), tto->toChars()); + error(loc, "cannot cast %s to %s since sizes don't line up", tfrom->toChars(), tto->toChars()); } dim = (dim * fsize) / tsize; } @@ -1834,7 +1834,7 @@ elem *AddExp::toElem(IRState *irs) (tb2->ty == Tarray || tb2->ty == Tsarray) ) { - error("Array operations not implemented"); + error("Array operation %s not implemented", toChars()); } else e = toElemBin(irs,OPadd); @@ -2064,8 +2064,14 @@ elem *CmpExp::toElem(IRState *irs) ea2 = e2->toElem(irs); ea2 = array_toDarray(t2, ea2); +#if 1 + ep = el_params(telement->arrayOf()->getInternalTypeInfo(NULL)->toElem(irs), + ea2, ea1, NULL); + rtlfunc = RTLSYM_ARRAYCMP2; +#else ep = el_params(telement->getInternalTypeInfo(NULL)->toElem(irs), ea2, ea1, NULL); rtlfunc = RTLSYM_ARRAYCMP; +#endif e = el_bin(OPcall, TYint, el_var(rtlsym[rtlfunc]), ep); e = el_bin(eop, TYint, e, el_long(TYint, 0)); el_setLoc(e,loc); @@ -2151,8 +2157,14 @@ elem *EqualExp::toElem(IRState *irs) ea2 = e2->toElem(irs); ea2 = array_toDarray(t2, ea2); +#if 1 + ep = el_params(telement->arrayOf()->getInternalTypeInfo(NULL)->toElem(irs), + ea2, ea1, NULL); + rtlfunc = RTLSYM_ARRAYEQ2; +#else ep = el_params(telement->getInternalTypeInfo(NULL)->toElem(irs), ea2, ea1, NULL); rtlfunc = RTLSYM_ARRAYEQ; +#endif e = el_bin(OPcall, TYint, el_var(rtlsym[rtlfunc]), ep); if (op == TOKnotequal) e = el_bin(OPxor, TYint, e, el_long(TYint, 1)); @@ -2478,6 +2490,44 @@ elem *AssignExp::toElem(IRState *irs) //elem_print(e); goto Lret; } + else if (e2->op == TOKadd || e2->op == TOKmin) + { + /* It's ea[] = eb[] +- ec[] + */ + BinExp *e2a = (BinExp *)e2; + Type *t = e2->type->toBasetype()->nextOf()->toBasetype(); + if (t->ty != Tfloat32 && t->ty != Tfloat64 && t->ty != Tfloat80) + { + e2->error("array add/min for %s not supported", t->toChars()); + return el_long(TYint, 0); + } + elem *ea = e1->toElem(irs); + ea = array_toDarray(e1->type, ea); + elem *eb = e2a->e1->toElem(irs); + eb = array_toDarray(e2a->e1->type, eb); + elem *ec = e2a->e2->toElem(irs); + ec = array_toDarray(e2a->e2->type, ec); + + int rtl = RTLSYM_ARRAYASSADDFLOAT; + if (t->ty == Tfloat64) + rtl = RTLSYM_ARRAYASSADDDOUBLE; + else if (t->ty == Tfloat80) + rtl = RTLSYM_ARRAYASSADDREAL; + if (e2->op == TOKmin) + { + rtl = RTLSYM_ARRAYASSMINFLOAT; + if (t->ty == Tfloat64) + rtl = RTLSYM_ARRAYASSMINDOUBLE; + else if (t->ty == Tfloat80) + rtl = RTLSYM_ARRAYASSMINREAL; + } + + /* Set parameters so the order of evaluation is eb, ec, ea + */ + elem *ep = el_params(eb, ec, ea, NULL); + e = el_bin(OPcall, type->totym(), el_var(rtlsym[rtl]), ep); + goto Lret; + } else { /* It's array1[]=array2[] @@ -3364,7 +3414,7 @@ elem *CastExp::toElem(IRState *irs) // Convert from static array to dynamic array if (tty == Tarray && fty == Tsarray) { - e = sarray_toDarray(tfrom, t, e); + e = sarray_toDarray(loc, tfrom, t, e); goto Lret; } @@ -4093,7 +4143,7 @@ elem *SliceExp::toElem(IRState *irs) } else if (t1->ty == Tsarray) { - e = sarray_toDarray(t1, NULL, e); + e = sarray_toDarray(loc, t1, NULL, e); } el_setLoc(e,loc); return e; diff --git a/src/enum.c b/src/enum.c index d7f8d8669f83..2023b4978664 100644 --- a/src/enum.c +++ b/src/enum.c @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2007 by Digital Mars +// Copyright (c) 1999-2008 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -17,6 +17,7 @@ #include "id.h" #include "expression.h" #include "module.h" +#include "declaration.h" /********************************* EnumDeclaration ****************************/ @@ -31,6 +32,7 @@ EnumDeclaration::EnumDeclaration(Loc loc, Identifier *id, Type *memtype) defaultval = NULL; sinit = NULL; scope = NULL; + isdeprecated = 0; } Dsymbol *EnumDeclaration::syntaxCopy(Dsymbol *s) @@ -79,6 +81,9 @@ void EnumDeclaration::semantic(Scope *sc) scope = NULL; } + if (sc->stc & STCdeprecated) + isdeprecated = 1; + parent = sc->parent; /* The separate, and distinct, cases are: @@ -307,11 +312,16 @@ Type *EnumDeclaration::getType() return type; } -char *EnumDeclaration::kind() +const char *EnumDeclaration::kind() { return "enum"; } +int EnumDeclaration::isDeprecated() +{ + return isdeprecated; +} + Dsymbol *EnumDeclaration::search(Loc loc, Identifier *ident, int flags) { //printf("%s.EnumDeclaration::search('%s')\n", toChars(), ident->toChars()); @@ -374,7 +384,7 @@ void EnumMember::toCBuffer(OutBuffer *buf, HdrGenState *hgs) } } -char *EnumMember::kind() +const char *EnumMember::kind() { return "enum member"; } diff --git a/src/enum.h b/src/enum.h index 7806c1c79a3a..be4472831eb1 100644 --- a/src/enum.h +++ b/src/enum.h @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2006 by Digital Mars +// Copyright (c) 1999-2008 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -32,11 +32,18 @@ struct EnumDeclaration : ScopeDsymbol Type *type; // the TypeEnum Type *memtype; // type of the members +#if V1 + integer_t maxval; + integer_t minval; + integer_t defaultval; // default initializer +#else Expression *maxval; Expression *minval; Expression *defaultval; // default initializer Scope *scope; // !=NULL means context to use +#endif + int isdeprecated; EnumDeclaration(Loc loc, Identifier *id, Type *memtype); Dsymbol *syntaxCopy(Dsymbol *s); @@ -44,8 +51,11 @@ struct EnumDeclaration : ScopeDsymbol int oneMember(Dsymbol **ps); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); Type *getType(); - char *kind(); + const char *kind(); +#if V2 Dsymbol *search(Loc, Identifier *ident, int flags); +#endif + int isDeprecated(); // is Dsymbol deprecated? void emitComment(Scope *sc); void toDocBuffer(OutBuffer *buf); @@ -69,7 +79,7 @@ struct EnumMember : Dsymbol EnumMember(Loc loc, Identifier *id, Expression *value, Type *type); Dsymbol *syntaxCopy(Dsymbol *s); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - char *kind(); + const char *kind(); void emitComment(Scope *sc); void toDocBuffer(OutBuffer *buf); diff --git a/src/expression.c b/src/expression.c index 230d374850d6..532f69565963 100644 --- a/src/expression.c +++ b/src/expression.c @@ -56,6 +56,7 @@ extern "C" char * __cdecl __locale_decpoint; #include "parse.h" Expression *createTypeInfoArray(Scope *sc, Expression *args[], int dim); +Expression *expandVar(int result, VarDeclaration *v); #define LOGSEMANTIC 0 @@ -264,7 +265,7 @@ Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad, } /* Can't find a path from e1 to ad */ - error("this for %s needs to be type %s not type %s", + e1->error("this for %s needs to be type %s not type %s", var->toChars(), ad->toChars(), t->toChars()); } } @@ -815,6 +816,7 @@ void argExpTypesToCBuffer(OutBuffer *buf, Expressions *arguments, HdrGenState *h Expression::Expression(Loc loc, enum TOK op, int size) : loc(loc) { + //printf("Expression::Expression(op = %d) this = %p\n", op, this); this->loc = loc; this->op = op; this->size = size; @@ -845,6 +847,7 @@ Expression *Expression::copy() assert(0); } e = (Expression *)mem.malloc(size); + //printf("Expression::copy(op = %d) e = %p\n", op, e); return (Expression *)memcpy(e, this, size); } @@ -1272,8 +1275,13 @@ integer_t IntegerExp::toInteger() } default: - type->print(); - assert(0); + /* This can happen if errors, such as + * the type is painted on like in fromConstInitializer(). + */ + if (!global.errors) + { type->print(); + assert(0); + } break; } break; @@ -1425,10 +1433,17 @@ void IntegerExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) goto L3; default: + /* This can happen if errors, such as + * the type is painted on like in fromConstInitializer(). + */ + if (!global.errors) + { #ifdef DEBUG - t->print(); + t->print(); #endif - assert(0); + assert(0); + } + break; } } else if (v & 0x8000000000000000LL) @@ -4194,6 +4209,8 @@ Expression *TypeidExp::semantic(Scope *sc) #endif typeidType = typeidType->semantic(loc, sc); e = typeidType->getTypeInfo(sc); + if (e->loc.linnum == 0) + e->loc = loc; // so there's at least some line number info return e; } @@ -5333,6 +5350,11 @@ Expression *DotVarExp::semantic(Scope *sc) e1 = getRightThis(loc, sc, ad, e1, var); if (!sc->noaccesscheck) accessCheck(loc, sc, e1, var); + + VarDeclaration *v = var->isVarDeclaration(); + Expression *e = expandVar(WANTvalue, v); + if (e) + return e; } } //printf("-DotVarExp::semantic('%s')\n", toChars()); @@ -5549,7 +5571,7 @@ Expression *DotTemplateInstanceExp::semantic(Scope *sc) return e; Lerr: - return new IntegerExp(0); + return new IntegerExp(loc, 0, Type::tint32); } void DotTemplateInstanceExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) @@ -5924,6 +5946,17 @@ e1->dump(0); if (f->needThis()) ue->e1 = getRightThis(loc, sc, ad, ue->e1, f); + /* Cannot call public functions from inside invariant + * (because then the invariant would have infinite recursion) + */ + if (sc->func && sc->func->isInvariantDeclaration() && + ue->e1->op == TOKthis && + f->addPostInvariant() + ) + { + error("cannot call public/export function %s from invariant", f->toChars()); + } + checkDeprecated(sc, f); accessCheck(loc, sc, ue->e1, f); if (!f->needThis()) diff --git a/src/func.c b/src/func.c index e9bfa3577c8b..ce2d2cca95e7 100644 --- a/src/func.c +++ b/src/func.c @@ -104,6 +104,7 @@ void FuncDeclaration::semantic(Scope *sc) StructDeclaration *sd; ClassDeclaration *cd; InterfaceDeclaration *id; + Dsymbol *pd; #if 0 printf("FuncDeclaration::semantic(sc = %p, this = %p, '%s', linkage = %d)\n", sc, this, toPrettyChars(), sc->linkage); @@ -252,6 +253,18 @@ void FuncDeclaration::semantic(Scope *sc) error("function body is not abstract in interface %s", id->toChars()); } + /* Template member functions aren't virtual: + * interface TestInterface { void tpl(T)(); } + * and so won't work in interfaces + */ + if ((pd = toParent()) != NULL && + pd->isTemplateInstance() && + (pd = toParent2()) != NULL && + (id = pd->isInterfaceDeclaration()) != NULL) + { + error("template member function not allowed in interface %s", id->toChars()); + } + cd = parent->isClassDeclaration(); if (cd) { int vi; @@ -1973,7 +1986,7 @@ int FuncDeclaration::isVirtual() { #if 0 printf("FuncDeclaration::isVirtual(%s)\n", toChars()); - printf("%p %d %d %d %d\n", isMember(), isStatic(), protection == PROTprivate, isCtorDeclaration(), linkage != LINKd); + printf("isMember:%p isStatic:%d private:%d ctor:%d !Dlinkage:%d\n", isMember(), isStatic(), protection == PROTprivate, isCtorDeclaration(), linkage != LINKd); printf("result is %d\n", isMember() && !(isStatic() || protection == PROTprivate || protection == PROTpackage) && @@ -2101,7 +2114,7 @@ FuncDeclaration *FuncDeclaration::genCfunc(Type *treturn, Identifier *id) return fd; } -char *FuncDeclaration::kind() +const char *FuncDeclaration::kind() { return "function"; } @@ -2144,7 +2157,7 @@ int FuncDeclaration::needsClosure() goto Lyes; // assume f escapes this function's scope // Look to see if any parents of f that are below this escape - for (Dsymbol *s = f->parent; s != this; s = s->parent) + for (Dsymbol *s = f->parent; s && s != this; s = s->parent) { f = s->isFuncDeclaration(); if (f && (f->isThis() || f->tookAddressOf)) @@ -2172,7 +2185,7 @@ FuncAliasDeclaration::FuncAliasDeclaration(FuncDeclaration *funcalias) this->funcalias = funcalias; } -char *FuncAliasDeclaration::kind() +const char *FuncAliasDeclaration::kind() { return "function alias"; } @@ -2217,7 +2230,12 @@ int FuncLiteralDeclaration::isNested() return (tok == TOKdelegate); } -char *FuncLiteralDeclaration::kind() +int FuncLiteralDeclaration::isVirtual() +{ + return FALSE; +} + +const char *FuncLiteralDeclaration::kind() { // GCC requires the (char*) casts return (tok == TOKdelegate) ? (char*)"delegate" : (char*)"function"; @@ -2245,7 +2263,7 @@ CtorDeclaration::CtorDeclaration(Loc loc, Loc endloc, Arguments *arguments, int { this->arguments = arguments; this->varargs = varargs; - //printf("CtorDeclaration() %s\n", toChars()); + //printf("CtorDeclaration(loc = %s) %s\n", loc.toChars(), toChars()); } Dsymbol *CtorDeclaration::syntaxCopy(Dsymbol *s) @@ -2316,7 +2334,7 @@ void CtorDeclaration::semantic(Scope *sc) cd->defaultCtor = this; } -char *CtorDeclaration::kind() +const char *CtorDeclaration::kind() { return "constructor"; } @@ -2914,7 +2932,7 @@ void NewDeclaration::semantic(Scope *sc) FuncDeclaration::semantic(sc); } -char *NewDeclaration::kind() +const char *NewDeclaration::kind() { return "allocator"; } @@ -2998,7 +3016,7 @@ void DeleteDeclaration::semantic(Scope *sc) FuncDeclaration::semantic(sc); } -char *DeleteDeclaration::kind() +const char *DeleteDeclaration::kind() { return "deallocator"; } diff --git a/src/idgen.c b/src/idgen.c index 091b9e5b6094..c244a687d50d 100644 --- a/src/idgen.c +++ b/src/idgen.c @@ -68,6 +68,8 @@ Msgtable msgtable[] = { "empty", "" }, { "p" }, { "coverage", "__coverage" }, + { "__vptr" }, + { "__monitor" }, { "TypeInfo" }, { "TypeInfo_Class" }, diff --git a/src/import.c b/src/import.c index b1b326a150b0..a28ce36063ed 100644 --- a/src/import.c +++ b/src/import.c @@ -55,7 +55,7 @@ void Import::addAlias(Identifier *name, Identifier *alias) aliases.push(alias); } -char *Import::kind() +const char *Import::kind() { return isstatic ? (char *)"static import" : (char *)"import"; } diff --git a/src/import.h b/src/import.h index 464708f8e871..fc49c326c410 100644 --- a/src/import.h +++ b/src/import.h @@ -48,7 +48,7 @@ struct Import : Dsymbol int isstatic); void addAlias(Identifier *name, Identifier *alias); - char *kind(); + const char *kind(); Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees void load(Scope *sc); void semantic(Scope *sc); diff --git a/src/init.c b/src/init.c index 5ea21962b3ec..98c9f35f4dfd 100644 --- a/src/init.c +++ b/src/init.c @@ -378,7 +378,7 @@ Initializer *ArrayInitializer::semantic(Scope *sc, Type *t) value.data[i] = (void *)val; length++; if (length == 0) - error("array dimension overflow"); + error(loc, "array dimension overflow"); if (length > dim) dim = length; } diff --git a/src/link.c b/src/link.c index abe699728440..9ed55912f15a 100644 --- a/src/link.c +++ b/src/link.c @@ -1,6 +1,6 @@ -// Copyright (c) 1999-2007 by Digital Mars +// Copyright (c) 1999-2008 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -35,6 +35,38 @@ int executecmd(char *cmd, char *args, int useenv); int executearg0(char *cmd, char *args); +/**************************************** + * Write filename to cmdbuf, quoting if necessary. + */ + +void writeFilename(OutBuffer *buf, char *filename, size_t len) +{ + /* Loop and see if we need to quote + */ + for (size_t i = 0; i < len; i++) + { char c = filename[i]; + + if (isalnum(c) || c == '_') + continue; + + /* Need to quote + */ + buf->writeByte('"'); + buf->write(filename, len); + buf->writeByte('"'); + return; + } + + /* No quoting necessary + */ + buf->write(filename, len); +} + +void writeFilename(OutBuffer *buf, char *filename) +{ + writeFilename(buf, filename, strlen(filename)); +} + /***************************** * Run the linker. Return status of execution. */ @@ -57,15 +89,18 @@ int runLINK() p = (char *)global.params.objfiles->data[i]; char *ext = FileName::ext(p); if (ext) - cmdbuf.write(p, ext - p - 1); + // Write name sans extension + writeFilename(&cmdbuf, p, ext - p - 1); else - cmdbuf.writestring(p); + writeFilename(&cmdbuf, p); } cmdbuf.writeByte(','); if (global.params.exefile) - cmdbuf.writestring(global.params.exefile); + writeFilename(&cmdbuf, global.params.exefile); else - { // Generate exe file name from first obj name + { /* Generate exe file name from first obj name. + * No need to add it to cmdbuf because the linker will default to it. + */ char *n = (char *)global.params.objfiles->data[0]; n = FileName::name(n); FileName *fn = FileName::forceExt(n, "exe"); @@ -89,13 +124,13 @@ int runLINK() { if (i) cmdbuf.writeByte('+'); - cmdbuf.writestring((char *) global.params.libfiles->data[i]); + writeFilename(&cmdbuf, (char *) global.params.libfiles->data[i]); } if (global.params.deffile) { cmdbuf.writeByte(','); - cmdbuf.writestring(global.params.deffile); + writeFilename(&cmdbuf, global.params.deffile); } /* Eliminate unnecessary trailing commas */ @@ -109,7 +144,7 @@ int runLINK() if (global.params.resfile) { cmdbuf.writestring("/RC:"); - cmdbuf.writestring(global.params.resfile); + writeFilename(&cmdbuf, global.params.resfile); } #if 0 diff --git a/src/mars.c b/src/mars.c index 91952018ef78..5f20ba8d0439 100644 --- a/src/mars.c +++ b/src/mars.c @@ -73,7 +73,7 @@ Global::Global() copyright = "Copyright (c) 1999-2008 by Digital Mars"; written = "written by Walter Bright"; - version = "v2.015"; + version = "v2.016"; global.structalign = 8; memset(¶ms, 0, sizeof(Param)); diff --git a/src/mars.h b/src/mars.h index 10c6a476f2e8..efee7397f73c 100644 --- a/src/mars.h +++ b/src/mars.h @@ -282,6 +282,7 @@ void deleteExeFile(); int runProgram(); void inifile(char *argv0, char *inifile); void halt(); +void util_progress(); /*** Where to send error messages ***/ #if IN_GCC diff --git a/src/md5.c b/src/md5.c new file mode 100644 index 000000000000..97333d7e04b7 --- /dev/null +++ b/src/md5.c @@ -0,0 +1,277 @@ +/* + ********************************************************************** + ** md5.c ** + ** RSA Data Security, Inc. MD5 Message Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version ** + ********************************************************************** + */ + +/* + ********************************************************************** + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + ** ** + ** License to copy and use this software is granted provided that ** + ** it is identified as the "RSA Data Security, Inc. MD5 Message ** + ** Digest Algorithm" in all material mentioning or referencing this ** + ** software or this function. ** + ** ** + ** License is also granted to make and use derivative works ** + ** provided that such works are identified as "derived from the RSA ** + ** Data Security, Inc. MD5 Message Digest Algorithm" in all ** + ** material mentioning or referencing the derived work. ** + ** ** + ** RSA Data Security, Inc. makes no representations concerning ** + ** either the merchantability of this software or the suitability ** + ** of this software for any particular purpose. It is provided "as ** + ** is" without express or implied warranty of any kind. ** + ** ** + ** These notices must be retained in any copies of any part of this ** + ** documentation and/or software. ** + ********************************************************************** + */ + +/* -- include the following line if the md5.h header file is separate -- */ +#include "md5.h" + +/* forward declaration */ +static void Transform (UINT4 *buf, UINT4 *in); + +static unsigned char PADDING[64] = { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* F, G and H are basic MD5 functions: selection, majority, parity */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ +/* Rotation is separate from addition to prevent recomputation */ +#define FF(a, b, c, d, x, s, ac) \ + {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) \ + {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) \ + {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) \ + {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +void MD5Init (mdContext) +MD5_CTX *mdContext; +{ + mdContext->i[0] = mdContext->i[1] = (UINT4)0; + + /* Load magic initialization constants. + */ + mdContext->buf[0] = (UINT4)0x67452301; + mdContext->buf[1] = (UINT4)0xefcdab89; + mdContext->buf[2] = (UINT4)0x98badcfe; + mdContext->buf[3] = (UINT4)0x10325476; +} + +void MD5Update (mdContext, inBuf, inLen) +MD5_CTX *mdContext; +unsigned char *inBuf; +unsigned int inLen; +{ + UINT4 in[16]; + int mdi; + unsigned int i, ii; + + /* compute number of bytes mod 64 */ + mdi = (int)((mdContext->i[0] >> 3) & 0x3F); + + /* update number of bits */ + if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0]) + mdContext->i[1]++; + mdContext->i[0] += ((UINT4)inLen << 3); + mdContext->i[1] += ((UINT4)inLen >> 29); + + while (inLen--) { + /* add new character to buffer, increment mdi */ + mdContext->in[mdi++] = *inBuf++; + + /* transform if necessary */ + if (mdi == 0x40) { + for (i = 0, ii = 0; i < 16; i++, ii += 4) + in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | + (((UINT4)mdContext->in[ii+2]) << 16) | + (((UINT4)mdContext->in[ii+1]) << 8) | + ((UINT4)mdContext->in[ii]); + Transform (mdContext->buf, in); + mdi = 0; + } + } +} + +void MD5Final (mdContext) +MD5_CTX *mdContext; +{ + UINT4 in[16]; + int mdi; + unsigned int i, ii; + unsigned int padLen; + + /* save number of bits */ + in[14] = mdContext->i[0]; + in[15] = mdContext->i[1]; + + /* compute number of bytes mod 64 */ + mdi = (int)((mdContext->i[0] >> 3) & 0x3F); + + /* pad out to 56 mod 64 */ + padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); + MD5Update (mdContext, PADDING, padLen); + + /* append length in bits and transform */ + for (i = 0, ii = 0; i < 14; i++, ii += 4) + in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | + (((UINT4)mdContext->in[ii+2]) << 16) | + (((UINT4)mdContext->in[ii+1]) << 8) | + ((UINT4)mdContext->in[ii]); + Transform (mdContext->buf, in); + + /* store buffer in digest */ + for (i = 0, ii = 0; i < 4; i++, ii += 4) { + mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); + mdContext->digest[ii+1] = + (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); + mdContext->digest[ii+2] = + (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); + mdContext->digest[ii+3] = + (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); + } +} + +/* Basic MD5 step. Transform buf based on in. + */ +static void Transform (buf, in) +UINT4 *buf; +UINT4 *in; +{ + UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; + + /* Round 1 */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 + FF ( a, b, c, d, in[ 0], S11, 3614090360); /* 1 */ + FF ( d, a, b, c, in[ 1], S12, 3905402710); /* 2 */ + FF ( c, d, a, b, in[ 2], S13, 606105819); /* 3 */ + FF ( b, c, d, a, in[ 3], S14, 3250441966); /* 4 */ + FF ( a, b, c, d, in[ 4], S11, 4118548399); /* 5 */ + FF ( d, a, b, c, in[ 5], S12, 1200080426); /* 6 */ + FF ( c, d, a, b, in[ 6], S13, 2821735955); /* 7 */ + FF ( b, c, d, a, in[ 7], S14, 4249261313); /* 8 */ + FF ( a, b, c, d, in[ 8], S11, 1770035416); /* 9 */ + FF ( d, a, b, c, in[ 9], S12, 2336552879); /* 10 */ + FF ( c, d, a, b, in[10], S13, 4294925233); /* 11 */ + FF ( b, c, d, a, in[11], S14, 2304563134); /* 12 */ + FF ( a, b, c, d, in[12], S11, 1804603682); /* 13 */ + FF ( d, a, b, c, in[13], S12, 4254626195); /* 14 */ + FF ( c, d, a, b, in[14], S13, 2792965006); /* 15 */ + FF ( b, c, d, a, in[15], S14, 1236535329); /* 16 */ + + /* Round 2 */ +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 + GG ( a, b, c, d, in[ 1], S21, 4129170786); /* 17 */ + GG ( d, a, b, c, in[ 6], S22, 3225465664); /* 18 */ + GG ( c, d, a, b, in[11], S23, 643717713); /* 19 */ + GG ( b, c, d, a, in[ 0], S24, 3921069994); /* 20 */ + GG ( a, b, c, d, in[ 5], S21, 3593408605); /* 21 */ + GG ( d, a, b, c, in[10], S22, 38016083); /* 22 */ + GG ( c, d, a, b, in[15], S23, 3634488961); /* 23 */ + GG ( b, c, d, a, in[ 4], S24, 3889429448); /* 24 */ + GG ( a, b, c, d, in[ 9], S21, 568446438); /* 25 */ + GG ( d, a, b, c, in[14], S22, 3275163606); /* 26 */ + GG ( c, d, a, b, in[ 3], S23, 4107603335); /* 27 */ + GG ( b, c, d, a, in[ 8], S24, 1163531501); /* 28 */ + GG ( a, b, c, d, in[13], S21, 2850285829); /* 29 */ + GG ( d, a, b, c, in[ 2], S22, 4243563512); /* 30 */ + GG ( c, d, a, b, in[ 7], S23, 1735328473); /* 31 */ + GG ( b, c, d, a, in[12], S24, 2368359562); /* 32 */ + + /* Round 3 */ +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 + HH ( a, b, c, d, in[ 5], S31, 4294588738); /* 33 */ + HH ( d, a, b, c, in[ 8], S32, 2272392833); /* 34 */ + HH ( c, d, a, b, in[11], S33, 1839030562); /* 35 */ + HH ( b, c, d, a, in[14], S34, 4259657740); /* 36 */ + HH ( a, b, c, d, in[ 1], S31, 2763975236); /* 37 */ + HH ( d, a, b, c, in[ 4], S32, 1272893353); /* 38 */ + HH ( c, d, a, b, in[ 7], S33, 4139469664); /* 39 */ + HH ( b, c, d, a, in[10], S34, 3200236656); /* 40 */ + HH ( a, b, c, d, in[13], S31, 681279174); /* 41 */ + HH ( d, a, b, c, in[ 0], S32, 3936430074); /* 42 */ + HH ( c, d, a, b, in[ 3], S33, 3572445317); /* 43 */ + HH ( b, c, d, a, in[ 6], S34, 76029189); /* 44 */ + HH ( a, b, c, d, in[ 9], S31, 3654602809); /* 45 */ + HH ( d, a, b, c, in[12], S32, 3873151461); /* 46 */ + HH ( c, d, a, b, in[15], S33, 530742520); /* 47 */ + HH ( b, c, d, a, in[ 2], S34, 3299628645); /* 48 */ + + /* Round 4 */ +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + II ( a, b, c, d, in[ 0], S41, 4096336452); /* 49 */ + II ( d, a, b, c, in[ 7], S42, 1126891415); /* 50 */ + II ( c, d, a, b, in[14], S43, 2878612391); /* 51 */ + II ( b, c, d, a, in[ 5], S44, 4237533241); /* 52 */ + II ( a, b, c, d, in[12], S41, 1700485571); /* 53 */ + II ( d, a, b, c, in[ 3], S42, 2399980690); /* 54 */ + II ( c, d, a, b, in[10], S43, 4293915773); /* 55 */ + II ( b, c, d, a, in[ 1], S44, 2240044497); /* 56 */ + II ( a, b, c, d, in[ 8], S41, 1873313359); /* 57 */ + II ( d, a, b, c, in[15], S42, 4264355552); /* 58 */ + II ( c, d, a, b, in[ 6], S43, 2734768916); /* 59 */ + II ( b, c, d, a, in[13], S44, 1309151649); /* 60 */ + II ( a, b, c, d, in[ 4], S41, 4149444226); /* 61 */ + II ( d, a, b, c, in[11], S42, 3174756917); /* 62 */ + II ( c, d, a, b, in[ 2], S43, 718787259); /* 63 */ + II ( b, c, d, a, in[ 9], S44, 3951481745); /* 64 */ + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +/* + ********************************************************************** + ** End of md5.c ** + ******************************* (cut) ******************************** + */ + diff --git a/src/md5.h b/src/md5.h new file mode 100644 index 000000000000..b7a7418d8f66 --- /dev/null +++ b/src/md5.h @@ -0,0 +1,61 @@ +/* + ********************************************************************** + ** md5.h -- Header file for implementation of MD5 ** + ** RSA Data Security, Inc. MD5 Message Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** + ** Revised (for MD5): RLR 4/27/91 ** + ** -- G modified to have y&~z instead of y&z ** + ** -- FF, GG, HH modified to add in last register done ** + ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** + ** -- distinct additive constant for each step ** + ** -- round 4 added, working mod 7 ** + ********************************************************************** + */ + +/* + ********************************************************************** + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + ** ** + ** License to copy and use this software is granted provided that ** + ** it is identified as the "RSA Data Security, Inc. MD5 Message ** + ** Digest Algorithm" in all material mentioning or referencing this ** + ** software or this function. ** + ** ** + ** License is also granted to make and use derivative works ** + ** provided that such works are identified as "derived from the RSA ** + ** Data Security, Inc. MD5 Message Digest Algorithm" in all ** + ** material mentioning or referencing the derived work. ** + ** ** + ** RSA Data Security, Inc. makes no representations concerning ** + ** either the merchantability of this software or the suitability ** + ** of this software for any particular purpose. It is provided "as ** + ** is" without express or implied warranty of any kind. ** + ** ** + ** These notices must be retained in any copies of any part of this ** + ** documentation and/or software. ** + ********************************************************************** + */ + +/* typedef a 32 bit type */ +typedef unsigned long int UINT4; + +/* Data structure for MD5 (Message Digest) computation */ +typedef struct { + UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ + UINT4 buf[4]; /* scratch buffer */ + unsigned char in[64]; /* input buffer */ + unsigned char digest[16]; /* actual digest after MD5Final call */ +} MD5_CTX; + +void MD5Init (MD5_CTX *mdContext); +void MD5Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned inLen); +void MD5Final (MD5_CTX *mdContext); + +/* + ********************************************************************** + ** End of md5.h ** + ******************************* (cut) ******************************** + */ + + diff --git a/src/module.c b/src/module.c index b036ef1fddc2..c7f7c4cdbd8c 100644 --- a/src/module.c +++ b/src/module.c @@ -228,7 +228,7 @@ Module::~Module() { } -char *Module::kind() +const char *Module::kind() { return "module"; } @@ -923,7 +923,7 @@ Package::Package(Identifier *ident) } -char *Package::kind() +const char *Package::kind() { return "package"; } diff --git a/src/module.h b/src/module.h index 6f58b00363d6..48f1922d1f90 100644 --- a/src/module.h +++ b/src/module.h @@ -36,7 +36,7 @@ struct elem; struct Package : ScopeDsymbol { Package(Identifier *ident); - char *kind(); + const char *kind(); static DsymbolTable *resolve(Array *packages, Dsymbol **pparent, Package **ppkg); @@ -110,7 +110,7 @@ struct Module : Package static Module *load(Loc loc, Array *packages, Identifier *ident); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - char *kind(); + const char *kind(); void setDocfile(); // set docfile member void read(Loc loc); // read file #if IN_GCC diff --git a/src/mtype.c b/src/mtype.c index c45927153498..35898c63578a 100644 --- a/src/mtype.c +++ b/src/mtype.c @@ -2947,7 +2947,7 @@ int Type::covariant(Type *t) #if 0 printf("Type::covariant(t = %s) %s\n", t->toChars(), toChars()); printf("deco = %p, %p\n", deco, t->deco); - //printf("ty = %d\n", next->ty); +// printf("ty = %d\n", next->ty); #endif int inoutmismatch = 0; @@ -3651,6 +3651,7 @@ void TypeQualified::resolveHelper(Loc loc, Scope *sc, if (s) { //printf("\t1: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind()); + s->checkDeprecated(loc, sc); // check for deprecated aliases s = s->toAlias(); //printf("\t2: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind()); for (int i = 0; i < idents.dim; i++) @@ -4074,7 +4075,7 @@ Dsymbol *TypeTypeof::toDsymbol(Scope *sc) { Type *t; - t = semantic(0, sc); + t = semantic(loc, sc); if (t == this) return NULL; return t->toDsymbol(sc); @@ -4150,6 +4151,10 @@ Type *TypeTypeof::semantic(Loc loc, Scope *sc) sc->intypeof++; exp = exp->semantic(sc); sc->intypeof--; + if (exp->op == TOKtype) + { + error(loc, "argument %s to typeof is not an expression", exp->toChars()); + } t = exp->type; if (!t) { @@ -4879,6 +4884,7 @@ Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident) } return Type::dotExp(sc, e, ident); } + s->checkDeprecated(e->loc, sc); s = s->toAlias(); v = s->isVarDeclaration(); @@ -5276,6 +5282,27 @@ Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident) return e; } + if (ident == Id::__vptr) + { /* The pointer to the vtbl[] + * *cast(invariant(void*)**)e + */ + e = e->castTo(sc, tvoidptr->invariantOf()->pointerTo()->pointerTo()); + e = new PtrExp(e->loc, e); + e = e->semantic(sc); + return e; + } + + if (ident == Id::__monitor) + { /* The handle to the monitor (call it a void*) + * *(cast(void**)e + 1) + */ + e = e->castTo(sc, tvoidptr->pointerTo()); + e = new AddExp(e->loc, e, new IntegerExp(1)); + e = new PtrExp(e->loc, e); + e = e->semantic(sc); + return e; + } + if (ident == Id::typeinfo) { if (!global.params.useDeprecated) @@ -5313,6 +5340,7 @@ Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident) return Type::dotExp(sc, e, ident); } } + s->checkDeprecated(e->loc, sc); s = s->toAlias(); v = s->isVarDeclaration(); if (v && !v->isDataseg()) diff --git a/src/optimize.c b/src/optimize.c index ca80c19563a5..91c9a41d23bc 100644 --- a/src/optimize.c +++ b/src/optimize.c @@ -611,7 +611,7 @@ Expression *shift_optimize(int result, BinExp *e, Expression *(*shift)(Type *, E integer_t i2 = e->e2->toInteger(); d_uns64 sz = e->e1->type->size() * 8; if (i2 < 0 || i2 > sz) - { error("shift by %jd is outside the range 0..%zu", i2, sz); + { e->error("shift by %jd is outside the range 0..%zu", i2, sz); e->e2 = new IntegerExp(0); } if (e->e1->isConst() == 1) diff --git a/src/parse.c b/src/parse.c index f1c38d11d4d9..eb5b5e42a25d 100644 --- a/src/parse.c +++ b/src/parse.c @@ -878,7 +878,7 @@ StaticDtorDeclaration *Parser::parseStaticDtor() /***************************************** * Parse an invariant definition: - * invariant { body } + * invariant() { body } * Current token is 'invariant'. */ @@ -1624,9 +1624,10 @@ Dsymbol *Parser::parseMixin() if (token.value != TOKidentifier) { error("identifier expected, not %s", token.toChars()); - goto Lerr; + id = Id::empty; } - id = token.ident; + else + id = token.ident; nextToken(); } @@ -1675,9 +1676,6 @@ Dsymbol *Parser::parseMixin() nextToken(); return tm; - -Lerr: - return NULL; } /****************************************** @@ -4407,8 +4405,6 @@ Expression *Parser::parsePrimaryExp() case TOKtypeof: { t = parseTypeof(); - if (token.value == TOKdot) - goto L1; e = new TypeExp(loc, t); break; } diff --git a/src/root.c b/src/root.c index dff9b9f0be31..7b65ddbc24ce 100644 --- a/src/root.c +++ b/src/root.c @@ -1415,7 +1415,7 @@ void OutBuffer::writebstring(unsigned char *string) write(string,*string + 1); } -void OutBuffer::writestring(char *string) +void OutBuffer::writestring(const char *string) { write(string,strlen(string)); } diff --git a/src/root.h b/src/root.h index b054ea5f2e06..aadf73aa6db4 100644 --- a/src/root.h +++ b/src/root.h @@ -264,7 +264,7 @@ struct OutBuffer : Object void reset(); void write(const void *data, unsigned nbytes); void writebstring(unsigned char *string); - void writestring(char *string); + void writestring(const char *string); void writedstring(const char *string); void writedstring(const wchar_t *string); void prependstring(char *string); diff --git a/src/statement.c b/src/statement.c index bb0506782380..59c9bdfaa5b8 100644 --- a/src/statement.c +++ b/src/statement.c @@ -299,12 +299,11 @@ Statements *CompileStatement::flatten(Scope *sc) Statement *CompileStatement::semantic(Scope *sc) { //printf("CompileStatement::semantic() %s\n", exp->toChars()); - /* Shouldn't happen unless errors, as CompileStatement::flatten() - * should have replaced it. - * Return NULL so no further errors happen. - */ - assert(global.errors); - return NULL; + Statements *a = flatten(sc); + if (!a) + return NULL; + Statement *s = new CompoundStatement(loc, a); + return s->semantic(sc); } @@ -582,7 +581,7 @@ int CompoundStatement::blockExit() int CompoundStatement::fallOffEnd() { int falloff = TRUE; - //printf("CompoundStatement::fallOffEnd()\n"); + //printf("CompoundStatement::fallOffEnd() %s\n", toChars()); for (int i = 0; i < statements->dim; i++) { Statement *s = (Statement *)statements->data[i]; @@ -925,14 +924,25 @@ int WhileStatement::blockExit() int result = BEnone; if (condition->canThrow()) result |= BEthrow; - if (body) - { result |= body->blockExit(); - if (result & BEbreak) - result |= BEfallthru; - result &= ~(BEbreak | BEcontinue); + if (condition->isBool(TRUE)) + { + if (body) + { result |= body->blockExit(); + if (result & BEbreak) + result |= BEfallthru; + } + } + else if (condition->isBool(FALSE)) + { + result |= BEfallthru; } else + { + if (body) + result |= body->blockExit(); result |= BEfallthru; + } + result &= ~(BEbreak | BEcontinue); return result; } @@ -1011,20 +1021,20 @@ int DoStatement::blockExit() if (body) { result = body->blockExit(); - if (result & BEbreak) - { - if (result == BEbreak) - return BEfallthru; - result |= BEfallthru; - } + if (result == BEbreak) + return BEfallthru; if (result & BEcontinue) result |= BEfallthru; - result &= ~(BEbreak | BEcontinue); } else result = BEfallthru; - if (result & BEfallthru && condition->canThrow()) - result |= BEthrow; + if (result & BEfallthru) + { if (condition->canThrow()) + result |= BEthrow; + if (!(result & BEbreak) && condition->isBool(TRUE)) + result &= ~BEfallthru; + } + result &= ~(BEbreak | BEcontinue); return result; } @@ -2033,14 +2043,31 @@ int IfStatement::blockExit() int result = BEnone; if (condition->canThrow()) result |= BEthrow; - if (ifbody) - result |= ifbody->blockExit(); - else - result |= BEfallthru; - if (elsebody) - result |= elsebody->blockExit(); + if (condition->isBool(TRUE)) + { + if (ifbody) + result |= ifbody->blockExit(); + else + result |= BEfallthru; + } + else if (condition->isBool(FALSE)) + { + if (elsebody) + result |= elsebody->blockExit(); + else + result |= BEfallthru; + } else - result |= BEfallthru; + { + if (ifbody) + result |= ifbody->blockExit(); + else + result |= BEfallthru; + if (elsebody) + result |= elsebody->blockExit(); + else + result |= BEfallthru; + } //printf("IfStatement::blockExit(%p) = x%x\n", this, result); return result; } @@ -2609,8 +2636,7 @@ int CaseStatement::usesEH() int CaseStatement::blockExit() { - // Assume the worst - return BEany; + return statement->blockExit(); } int CaseStatement::fallOffEnd() @@ -2676,8 +2702,7 @@ int DefaultStatement::usesEH() int DefaultStatement::blockExit() { - // Assume the worst - return BEany; + return statement->blockExit(); } int DefaultStatement::fallOffEnd() diff --git a/src/statement.h b/src/statement.h index c87a3bc752a0..01c0973637d0 100644 --- a/src/statement.h +++ b/src/statement.h @@ -340,6 +340,7 @@ struct ForeachStatement : Statement void toIR(IRState *irs); }; +#if V2 struct ForeachRangeStatement : Statement { enum TOK op; // TOKforeach or TOKforeach_reverse @@ -367,6 +368,7 @@ struct ForeachRangeStatement : Statement void toIR(IRState *irs); }; +#endif struct IfStatement : Statement { diff --git a/src/staticassert.c b/src/staticassert.c index 97e3a42be8fe..6188e236a8b7 100644 --- a/src/staticassert.c +++ b/src/staticassert.c @@ -90,7 +90,7 @@ void StaticAssert::toObjFile(int multiobj) { } -char *StaticAssert::kind() +const char *StaticAssert::kind() { return "static assert"; } diff --git a/src/staticassert.h b/src/staticassert.h index a38078d3f37b..632c1e901725 100644 --- a/src/staticassert.h +++ b/src/staticassert.h @@ -36,7 +36,7 @@ struct StaticAssert : Dsymbol void inlineScan(); int oneMember(Dsymbol **ps); void toObjFile(int multiobj); - char *kind(); + const char *kind(); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); }; diff --git a/src/struct.c b/src/struct.c index 3116916f3a7d..f202168d6bbb 100644 --- a/src/struct.c +++ b/src/struct.c @@ -265,6 +265,8 @@ void StructDeclaration::semantic(Scope *sc) structalign = sc->structalign; protection = sc->protection; storage_class |= sc->stc; + if (sc->stc & STCdeprecated) + isdeprecated = 1; assert(!isAnonymous()); if (sc->stc & STCabstract) error("structs, unions cannot be abstract"); @@ -469,7 +471,7 @@ void StructDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) } -char *StructDeclaration::kind() +const char *StructDeclaration::kind() { return "struct"; } @@ -494,7 +496,7 @@ Dsymbol *UnionDeclaration::syntaxCopy(Dsymbol *s) } -char *UnionDeclaration::kind() +const char *UnionDeclaration::kind() { return "union"; } diff --git a/src/template.c b/src/template.c index c104670055eb..b43a3e1f83f2 100644 --- a/src/template.c +++ b/src/template.c @@ -419,7 +419,7 @@ void TemplateDeclaration::semantic(Scope *sc) */ } -char *TemplateDeclaration::kind() +const char *TemplateDeclaration::kind() { return (onemember && onemember->isAggregateDeclaration()) ? onemember->kind() @@ -939,13 +939,6 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Loc loc, Objects *targsi, //printf("\tm2 = %d\n", m); } - /* If no match, see if we can implicitly convert farg to the - * parameter type. - */ - if (!m) - { m = farg->implicitConvTo(fparam->type); - } - if (m) { if (m < match) match = m; // pick worst match @@ -1460,10 +1453,20 @@ MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, { if (!sc) goto Lnomatch; + + /* Need a loc to go with the semantic routine. + */ + Loc loc; + if (parameters->dim) + { + TemplateParameter *tp = (TemplateParameter *)parameters->data[0]; + loc = tp->loc; + } + /* BUG: what if tparam is a template instance, that * has as an argument another Tident? */ - tparam = tparam->semantic(0, sc); + tparam = tparam->semantic(loc, sc); assert(tparam->ty != Tident); return deduceType(sc, tparam, parameters, dedtypes); } @@ -1517,7 +1520,8 @@ MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, } if (ty != tparam->ty) - goto Lnomatch; + return implicitConvTo(tparam); +// goto Lnomatch; if (nextOf()) return nextOf()->deduceType(sc, tparam->nextOf(), parameters, dedtypes); @@ -3615,7 +3619,7 @@ TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc) return NULL; } m = td->matchWithInstance(this, &dedtypes, 0); - //printf("m = %d\n", m); + //printf("matchWithInstance = %d\n", m); if (!m) // no match at all continue; @@ -4056,7 +4060,7 @@ AliasDeclaration *TemplateInstance::isAliasDeclaration() return aliasdecl; } -char *TemplateInstance::kind() +const char *TemplateInstance::kind() { return "template instance"; } @@ -4139,6 +4143,7 @@ void TemplateMixin::semantic(Scope *sc) #if LOG printf("\tdo semantic\n"); #endif + util_progress(); Scope *scx = NULL; if (scope) @@ -4253,6 +4258,11 @@ void TemplateMixin::semantic(Scope *sc) if (!tm || tempdecl != tm->tempdecl) continue; + /* Different argument list lengths happen with variadic args + */ + if (tiargs->dim != tm->tiargs->dim) + continue; + for (int i = 0; i < tiargs->dim; i++) { Object *o = (Object *)tiargs->data[i]; Type *ta = isType(o); @@ -4436,7 +4446,7 @@ void TemplateMixin::inlineScan() TemplateInstance::inlineScan(); } -char *TemplateMixin::kind() +const char *TemplateMixin::kind() { return "mixin"; } diff --git a/src/template.h b/src/template.h index ac4a110125dc..fc878a26a079 100644 --- a/src/template.h +++ b/src/template.h @@ -68,7 +68,7 @@ struct TemplateDeclaration : ScopeDsymbol void semantic(Scope *sc); int overloadInsert(Dsymbol *s); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - char *kind(); + const char *kind(); char *toChars(); void emitComment(Scope *sc); @@ -295,7 +295,7 @@ struct TemplateInstance : ScopeDsymbol void inlineScan(); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); Dsymbol *toAlias(); // resolve real symbol - char *kind(); + const char *kind(); int oneMember(Dsymbol **ps); char *toChars(); char *mangle(); @@ -328,7 +328,7 @@ struct TemplateMixin : TemplateInstance void semantic2(Scope *sc); void semantic3(Scope *sc); void inlineScan(); - char *kind(); + const char *kind(); int oneMember(Dsymbol **ps); int hasPointers(); char *toChars(); diff --git a/src/tocsym.c b/src/tocsym.c index 57557806c515..0333e4998f12 100644 --- a/src/tocsym.c +++ b/src/tocsym.c @@ -188,7 +188,7 @@ Symbol *VarDeclaration::toSymbol() t = type_fake(TYnptr); } else if (storage_class & STClazy) - t = type_fake(TYullong); // Tdelegate as C type + t = type_fake(TYdelegate); // Tdelegate as C type else if (isParameter()) t = type->toCParamtype(); else diff --git a/src/toir.c b/src/toir.c index eab33f132123..d91863359d98 100644 --- a/src/toir.c +++ b/src/toir.c @@ -443,9 +443,24 @@ void FuncDeclaration::buildClosure(IRState *irs) /* Align and allocate space for v in the closure * just like AggregateDeclaration::addField() does. */ - unsigned memsize = v->type->size(); - unsigned memalignsize = v->type->alignsize(); - unsigned xalign = v->type->memalign(global.structalign); + unsigned memsize; + unsigned memalignsize; + unsigned xalign; + if (v->storage_class & STClazy) + { + /* Lazy variables are really delegates, + * so give same answers that TypeDelegate would + */ + memsize = PTRSIZE * 2; + memalignsize = memsize; + xalign = global.structalign; + } + else + { + memsize = v->type->size(); + memalignsize = v->type->alignsize(); + xalign = v->type->memalign(global.structalign); + } AggregateDeclaration::alignmember(xalign, memalignsize, &offset); v->offset = offset; offset += memsize; @@ -489,6 +504,8 @@ void FuncDeclaration::buildClosure(IRState *irs) tym_t tym = v->type->totym(); if (v->type->toBasetype()->ty == Tsarray || v->isOut() || v->isRef()) tym = TYnptr; // reference parameters are just pointers + else if (v->storage_class & STClazy) + tym = TYdelegate; ex = el_bin(OPadd, TYnptr, el_var(sclosure), el_long(TYint, v->offset)); ex = el_una(OPind, tym, ex); if (ex->Ety == TYstruct) diff --git a/src/typinf.c b/src/typinf.c index fcd00f9ec4ba..135223737460 100644 --- a/src/typinf.c +++ b/src/typinf.c @@ -432,7 +432,7 @@ void TypeInfoStructDeclaration::toDt(dt_t **pdt) * char[] name; * void[] init; * hash_t function(in void*) xtoHash; - * int function(in void*, in void*) xopEquals; + * bool function(in void*, in void*) xopEquals; * int function(in void*, in void*) xopCmp; * string function(const(void)*) xtoString; * uint m_flags; @@ -479,29 +479,28 @@ void TypeInfoStructDeclaration::toDt(dt_t **pdt) } TypeFunction *tfeqptr; - { + { // bool opEqual(const T*) const; Scope sc; Arguments *arguments = new Arguments; Argument *arg = new Argument(STCin, tc->pointerTo(), NULL, NULL); arguments->push(arg); - tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd); + tfeqptr = new TypeFunction(arguments, Type::tbool, 0, LINKd); tfeqptr->mod = MODconst; tfeqptr = (TypeFunction *)tfeqptr->semantic(0, &sc); } -#if 0 - TypeFunction *tfeq; + TypeFunction *tfcmpptr; { Scope sc; - Array *arguments = new Array; - Argument *arg = new Argument(In, tc, NULL, NULL); + Arguments *arguments = new Arguments; + Argument *arg = new Argument(STCin, tc->pointerTo(), NULL, NULL); arguments->push(arg); - tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd); - tfeq = (TypeFunction *)tfeq->semantic(0, &sc); + tfcmpptr = new TypeFunction(arguments, Type::tint32, 0, LINKd); + tfcmpptr->mod = MODconst; + tfcmpptr = (TypeFunction *)tfcmpptr->semantic(0, &sc); } -#endif s = search_function(sd, Id::tohash); fdx = s ? s->isFuncDeclaration() : NULL; @@ -518,22 +517,35 @@ void TypeInfoStructDeclaration::toDt(dt_t **pdt) s = search_function(sd, Id::eq); fdx = s ? s->isFuncDeclaration() : NULL; - for (int i = 0; i < 2; i++) + if (fdx) { - if (fdx) - { fd = fdx->overloadExactMatch(tfeqptr); + //printf("test1 %s, %s, %s\n", fdx->toChars(), fdx->type->toChars(), tfeqptr->toChars()); + fd = fdx->overloadExactMatch(tfeqptr); + if (fd) + dtxoff(pdt, fd->toSymbol(), 0, TYnptr); + else + { fd = fdx->overloadExactMatch(tfcmpptr); if (fd) - dtxoff(pdt, fd->toSymbol(), 0, TYnptr); - else - //fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars()); - dtdword(pdt, 0); + fdx->error("must return bool, not int"); + //fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars()); + dtdword(pdt, 0); } + } + else + dtdword(pdt, 0); + + s = search_function(sd, Id::cmp); + fdx = s ? s->isFuncDeclaration() : NULL; + if (fdx) + { fd = fdx->overloadExactMatch(tfcmpptr); + if (fd) + dtxoff(pdt, fd->toSymbol(), 0, TYnptr); else + //fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars()); dtdword(pdt, 0); - - s = search_function(sd, Id::cmp); - fdx = s ? s->isFuncDeclaration() : NULL; } + else + dtdword(pdt, 0); s = search_function(sd, Id::tostring); fdx = s ? s->isFuncDeclaration() : NULL; diff --git a/src/version.c b/src/version.c index 18cc461a0d20..c1ad6fc4bdae 100644 --- a/src/version.c +++ b/src/version.c @@ -93,7 +93,7 @@ void DebugSymbol::toCBuffer(OutBuffer *buf, HdrGenState *hgs) buf->writenl(); } -char *DebugSymbol::kind() +const char *DebugSymbol::kind() { return "debug"; } @@ -173,7 +173,7 @@ void VersionSymbol::toCBuffer(OutBuffer *buf, HdrGenState *hgs) buf->writenl(); } -char *VersionSymbol::kind() +const char *VersionSymbol::kind() { return "version"; } diff --git a/src/version.h b/src/version.h index c9de7a7d83ca..b5ae51d28357 100644 --- a/src/version.h +++ b/src/version.h @@ -31,7 +31,7 @@ struct DebugSymbol : Dsymbol int addMember(Scope *sc, ScopeDsymbol *s, int memnum); void semantic(Scope *sc); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - char *kind(); + const char *kind(); }; struct VersionSymbol : Dsymbol @@ -45,7 +45,7 @@ struct VersionSymbol : Dsymbol int addMember(Scope *sc, ScopeDsymbol *s, int memnum); void semantic(Scope *sc); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - char *kind(); + const char *kind(); }; #endif /* DMD_VERSION_H */