Permalink
Browse files

dmd 2.020

  • Loading branch information...
1 parent 894019b commit f87c229d74e02f7f6d9522068ce80b1bbcd1c3db @braddr braddr committed Jul 3, 2009
Showing with 513 additions and 121 deletions.
  1. +3 −1 src/attrib.c
  2. +2 −2 src/cast.c
  3. +1 −1 src/cond.c
  4. +25 −0 src/constfold.c
  5. +6 −1 src/declaration.c
  6. +1 −0 src/declaration.h
  7. +79 −4 src/e2ir.c
  8. +51 −13 src/expression.c
  9. +1 −1 src/func.c
  10. +17 −0 src/impcnvgen.c
  11. +10 −0 src/lexer.c
  12. +2 −1 src/lexer.h
  13. +1 −0 src/link.c
  14. +2 −1 src/mars.c
  15. +75 −56 src/mtype.c
  16. +3 −1 src/mtype.h
  17. +208 −38 src/parse.c
  18. +1 −0 src/parse.h
  19. +20 −1 src/statement.c
  20. +5 −0 src/toir.c
View
@@ -328,14 +328,16 @@ void StorageClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{ STCstatic, TOKstatic },
{ STCextern, TOKextern },
{ STCconst, TOKconst },
- { STCinvariant, TOKinvariant },
+ { STCinvariant, TOKimmutable },
+ { STCshared, TOKshared },
{ STCfinal, TOKfinal },
{ STCabstract, TOKabstract },
{ STCsynchronized, TOKsynchronized },
{ STCdeprecated, TOKdeprecated },
{ STCoverride, TOKoverride },
{ STCnothrow, TOKnothrow },
{ STCpure, TOKpure },
+ { STCref, TOKref },
{ STCtls, TOKtls },
};
View
@@ -339,8 +339,8 @@ MATCH IntegerExp::implicitConvTo(Type *t)
MATCH NullExp::implicitConvTo(Type *t)
{
#if 0
- printf("NullExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
- toChars(), type->toChars(), t->toChars());
+ printf("NullExp::implicitConvTo(this=%s, type=%s, t=%s, committed = %d)\n",
+ toChars(), type->toChars(), t->toChars(), committed);
#endif
if (this->type->equals(t))
return MATCHexact;
View
@@ -129,7 +129,7 @@ void VersionCondition::checkPredefined(Loc loc, const char *ident)
{
"DigitalMars", "X86", "X86_64",
"Windows", "Win32", "Win64",
- "linux",
+ "linux", "Posix",
"LittleEndian", "BigEndian",
"all",
"none",
View
@@ -1484,6 +1484,31 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
else
e->type = type;
}
+ else if (e1->op == TOKarrayliteral && e2->op == TOKnull &&
+ t1->nextOf()->equals(t2->nextOf()))
+ {
+ e = e1;
+ goto L3;
+ }
+ else if (e1->op == TOKnull && e2->op == TOKarrayliteral &&
+ t1->nextOf()->equals(t2->nextOf()))
+ {
+ e = e2;
+ L3:
+ // Concatenate the array with null
+ ArrayLiteralExp *es = (ArrayLiteralExp *)e;
+
+ es = new ArrayLiteralExp(es->loc, (Expressions *)es->elements->copy());
+ e = es;
+
+ if (type->toBasetype()->ty == Tsarray)
+ {
+ e->type = new TypeSArray(t1->nextOf(), new IntegerExp(loc, es->elements->dim, Type::tindex));
+ e->type = e->type->semantic(loc, NULL);
+ }
+ else
+ e->type = type;
+ }
else if ((e1->op == TOKarrayliteral || e1->op == TOKnull) &&
e1->type->toBasetype()->nextOf()->equals(e2->type))
{
View
@@ -855,6 +855,9 @@ void VarDeclaration::semantic(Scope *sc)
}
}
+ if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref)
+ error("only parameters or foreach declarations can be ref");
+
if (type->isauto() && !noauto)
{
if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls) || !fd)
@@ -925,7 +928,7 @@ void VarDeclaration::semantic(Scope *sc)
if (init)
{
sc = sc->push();
- sc->stc &= ~(STCconst | STCinvariant | STCpure);
+ sc->stc &= ~(STCconst | STCinvariant | STCpure | STCnothrow | STCref | STCshared);
ArrayInitializer *ai = init->isArrayInitializer();
if (ai && tb->ty == Taarray)
@@ -1202,8 +1205,10 @@ int VarDeclaration::isImportedSymbol()
void VarDeclaration::checkCtorConstInit()
{
+#if 0 /* doesn't work if more than one static ctor */
if (ctorinit == 0 && isCtorinit() && !(storage_class & STCfield))
error("missing initializer in static constructor for const variable");
+#endif
}
/************************************
View
@@ -70,6 +70,7 @@ enum STC
STCpure = 0x4000000, // pure function
STCtls = 0x8000000, // thread local
STCalias = 0x10000000, // alias parameter
+ STCshared = 0x20000000, // accessible from multiple threads
};
struct Match
View
@@ -274,6 +274,15 @@ elem *callfunc(Loc loc,
e->Ety = TYnptr;
e = el_una(OPind, tyret, e);
}
+
+#if V2
+ if (tf->isref)
+ {
+ e->Ety = TYnptr;
+ e = el_una(OPind, tyret, e);
+ }
+#endif
+
if (tybasic(tyret) == TYstruct)
{
e->Enumbytes = tret->size();
@@ -4452,7 +4461,26 @@ elem *AssocArrayLiteralExp::toElem(IRState *irs)
el = (Expression *)values->data[i];
}
}
- e = el_param(e, type->getTypeInfo(NULL)->toElem(irs));
+
+ Type *t = type->toBasetype()->mutableOf();
+ assert(t->ty == Taarray);
+ TypeAArray *ta = (TypeAArray *)t;
+
+ /* Unfortunately, the hash function for Aa (array of chars) is custom and
+ * different from Axa and Aya, which get the generic hash function.
+ * So, rewrite the type of the AArray so that if it's key type
+ * is an array of const or invariant, make it an array of mutable.
+ */
+ Type *tkey = ta->index->toBasetype();
+ if (tkey->ty == Tarray)
+ {
+ tkey = tkey->nextOf()->mutableOf()->arrayOf();
+ tkey = tkey->semantic(0, NULL);
+ ta = new TypeAArray(ta->nextOf(), tkey);
+ ta = (TypeAArray *)ta->merge();
+ }
+
+ e = el_param(e, ta->getTypeInfo(NULL)->toElem(irs));
// call _d_assocarrayliteralT(ti, dim, ...)
e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ASSOCARRAYLITERALT]),e);
@@ -4562,6 +4590,7 @@ elem *StructLiteralExp::toElem(IRState *irs)
e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset));
}
e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v->offset));
+ elem *ec = e1; // pointer to destination
elem *ep = el->toElem(irs);
@@ -4570,9 +4599,41 @@ elem *StructLiteralExp::toElem(IRState *irs)
if (t1b->ty == Tsarray)
{
if (t2b->implicitConvTo(t1b))
- { elem *esize = el_long(TYsize_t, t1b->size());
- ep = array_toPtr(el->type, ep);
- e1 = el_bin(OPmemcpy, TYnptr, e1, el_param(ep, esize));
+ {
+#if V2
+ // Determine if postblit is needed
+ int postblit = 0;
+ Type *t = t1b;
+ do
+ {
+ t = t->nextOf()->toBasetype();
+ } while (t->ty == Tsarray);
+ if (t->ty == Tstruct)
+ { StructDeclaration *sd = ((TypeStruct *)t)->sym;
+ if (sd->postblit)
+ postblit = 1;
+ }
+
+ if (postblit)
+ {
+ /* Generate:
+ * _d_arrayctor(ti, From: ep, To: e1)
+ */
+ Expression *ti = t1b->nextOf()->toBasetype()->getTypeInfo(NULL);
+ elem *esize = el_long(TYsize_t, ((TypeSArray *)t1b)->dim->toInteger());
+ e1 = el_pair(TYdarray, esize, e1);
+ ep = el_pair(TYdarray, el_copytree(esize), array_toPtr(el->type, ep));
+ ep = el_params(e1, ep, ti->toElem(irs), NULL);
+ int rtl = RTLSYM_ARRAYCTOR;
+ e1 = el_bin(OPcall, type->totym(), el_var(rtlsym[rtl]), ep);
+ }
+ else
+#endif
+ {
+ elem *esize = el_long(TYsize_t, t1b->size());
+ ep = array_toPtr(el->type, ep);
+ e1 = el_bin(OPmemcpy, TYnptr, e1, el_param(ep, esize));
+ }
}
else
{
@@ -4591,6 +4652,20 @@ elem *StructLiteralExp::toElem(IRState *irs)
{ e1->Eoper = OPstreq;
e1->Enumbytes = v->type->size();
}
+#if V2
+ /* Call postBlit() on e1
+ */
+ Type *tb = v->type->toBasetype();
+ if (tb->ty == Tstruct)
+ { StructDeclaration *sd = ((TypeStruct *)tb)->sym;
+ if (sd->postblit)
+ { FuncDeclaration *fd = sd->postblit;
+ ec = el_copytree(ec);
+ ec = callfunc(loc, irs, 1, Type::tvoid, ec, tb->pointerTo(), fd, fd->type, NULL, NULL);
+ e1 = el_bin(OPcomma, ec->Ety, e1, ec);
+ }
+ }
+#endif
}
e = el_combine(e, e1);
}
View
@@ -4424,6 +4424,7 @@ Expression *IsExp::semantic(Scope *sc)
break;
case TOKinvariant:
+ case TOKimmutable:
if (!targ->isInvariant())
goto Lno;
tded = targ;
@@ -4692,7 +4693,8 @@ Expression *BinExp::semantic(Scope *sc)
printf("BinExp::semantic('%s')\n", toChars());
#endif
e1 = e1->semantic(sc);
- if (!e1->type)
+ if (!e1->type &&
+ !(op == TOKassign && e1->op == TOKdottd)) // a.template = e2
{
error("%s has no value", e1->toChars());
e1->type = Type::terror;
@@ -4703,7 +4705,6 @@ Expression *BinExp::semantic(Scope *sc)
error("%s has no value", e2->toChars());
e2->type = Type::terror;
}
- assert(e1->type);
return this;
}
@@ -5133,6 +5134,8 @@ Expression *DotIdExp::semantic(Scope *sc)
return e;
}
+ Type *t1b = e1->type->toBasetype();
+
if (eright->op == TOKimport) // also used for template alias's
{
Dsymbol *s;
@@ -5287,15 +5290,40 @@ Expression *DotIdExp::semantic(Scope *sc)
type = Type::tvoid;
return this;
}
- else if (e1->type->ty == Tpointer &&
+ else if (t1b->ty == Tpointer &&
ident != Id::init && ident != Id::__sizeof &&
ident != Id::alignof && ident != Id::offsetof &&
ident != Id::mangleof && ident != Id::stringof)
- {
+ { /* Rewrite:
+ * p.ident
+ * as:
+ * (*p).ident
+ */
e = new PtrExp(loc, e1);
- e->type = ((TypePointer *)e1->type)->next;
+ e->type = ((TypePointer *)t1b)->next;
return e->type->dotExp(sc, e, ident);
}
+ else if (t1b->ty == Tarray ||
+ t1b->ty == Tsarray ||
+ t1b->ty == Taarray)
+ { /* If ident is not a valid property, rewrite:
+ * e1.ident
+ * as:
+ * .ident(e1)
+ */
+ unsigned errors = global.errors;
+ global.gag++;
+ e = e1->type->dotExp(sc, e1, ident);
+ global.gag--;
+ if (errors != global.errors) // if failed to find the property
+ {
+ global.errors = errors;
+ e = new DotIdExp(loc, new IdentifierExp(loc, Id::empty), ident);
+ e = new CallExp(loc, e, e1);
+ }
+ e = e->semantic(sc);
+ return e;
+ }
else
{
e = e1->type->dotExp(sc, e1, ident);
@@ -5771,7 +5799,7 @@ Expression *CallExp::semantic(Scope *sc)
}
/* Transform:
- * array.id(args) into id(array,args)
+ * array.id(args) into .id(array,args)
* aa.remove(arg) into delete aa[arg]
*/
if (e1->op == TOKdot)
@@ -5805,7 +5833,7 @@ Expression *CallExp::semantic(Scope *sc)
if (!arguments)
arguments = new Expressions();
arguments->shift(dotid->e1);
- e1 = new IdentifierExp(dotid->loc, dotid->ident);
+ e1 = new DotIdExp(dotid->loc, new IdentifierExp(dotid->loc, Id::empty), dotid->ident);
}
}
}
@@ -6337,16 +6365,17 @@ int CallExp::isLvalue()
{
if (type->toBasetype()->ty == Tstruct)
return 1;
- else
- return 0;
+ Type *tb = e1->type->toBasetype();
+ if (tb->ty == Tfunction && ((TypeFunction *)tb)->isref)
+ return 1; // function returns a reference
+ return 0;
}
Expression *CallExp::toLvalue(Scope *sc, Expression *e)
{
- if (type->toBasetype()->ty == Tstruct)
+ if (isLvalue())
return this;
- else
- return Expression::toLvalue(sc, e);
+ return Expression::toLvalue(sc, e);
}
void CallExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
@@ -6825,7 +6854,7 @@ Expression *CastExp::semantic(Scope *sc)
if (!to)
{ if (tok == TOKconst)
to = e1->type->constOf();
- else if (tok == TOKinvariant)
+ else if (tok == TOKinvariant || tok == TOKimmutable)
to = e1->type->invariantOf();
else
assert(0);
@@ -7654,6 +7683,14 @@ Expression *AssignExp::semantic(Scope *sc)
}
BinExp::semantic(sc);
+
+ if (e1->op == TOKdottd)
+ { // Rewrite a.b=e2, when b is a template, as a.b(e2)
+ Expression *e = new CallExp(loc, e1, e2);
+ e = e->semantic(sc);
+ return e;
+ }
+
e2 = resolveProperties(sc, e2);
assert(e1->type);
@@ -7770,6 +7807,7 @@ Expression *AssignExp::semantic(Scope *sc)
// before it got constant folded
if (e1->op != TOKvar)
e1 = e1->optimize(WANTvalue);
+
if (op != TOKconstruct)
e1 = e1->modifiableLvalue(sc, e1old);
}
View
@@ -114,7 +114,7 @@ void FuncDeclaration::semantic(Scope *sc)
printf("type: %p, %s\n", type, type->toChars());
#endif
- storage_class |= sc->stc;
+ storage_class |= sc->stc & ~STCref;
//printf("function storage_class = x%x\n", storage_class);
if (!originalType)
Oops, something went wrong.

0 comments on commit f87c229

Please sign in to comment.