[svn r23] * Updated to DMD 1.021

This commit is contained in:
Tomas Lindquist Olsen
2007-10-04 03:42:56 +02:00
parent 8004219a69
commit 1cb583cbca
24 changed files with 638 additions and 179 deletions
+22
View File
@@ -192,6 +192,28 @@ void AttribDeclaration::toObjFile()
} }
} }
int AttribDeclaration::cvMember(unsigned char *p)
{
unsigned i;
int nwritten = 0;
int n;
Array *d = include(NULL, NULL);
if (d)
{
for (i = 0; i < d->dim; i++)
{ Dsymbol *s;
s = (Dsymbol *)d->data[i];
n = s->cvMember(p);
if (p)
p += n;
nwritten += n;
}
}
return nwritten;
}
int AttribDeclaration::hasPointers() int AttribDeclaration::hasPointers()
{ {
Array *d = include(NULL, NULL); Array *d = include(NULL, NULL);
+1
View File
@@ -51,6 +51,7 @@ struct AttribDeclaration : Dsymbol
AttribDeclaration *isAttribDeclaration() { return this; } AttribDeclaration *isAttribDeclaration() { return this; }
void toObjFile(); // compile to .obj file void toObjFile(); // compile to .obj file
int cvMember(unsigned char *p);
}; };
struct StorageClassDeclaration: AttribDeclaration struct StorageClassDeclaration: AttribDeclaration
+84 -85
View File
@@ -658,77 +658,85 @@ Expression *NullExp::castTo(Scope *sc, Type *t)
Expression *StringExp::castTo(Scope *sc, Type *t) Expression *StringExp::castTo(Scope *sc, Type *t)
{ {
/* This follows copy-on-write; any changes to 'this'
* will result in a copy.
* The this->string member is considered immutable.
*/
StringExp *se; StringExp *se;
Type *tb; Type *tb;
int unique; int copied = 0;
//printf("StringExp::castTo(t = %s), '%s' committed = %d\n", t->toChars(), toChars(), committed); //printf("StringExp::castTo(t = %s), '%s' committed = %d\n", t->toChars(), toChars(), committed);
if (!committed && t->ty == Tpointer && t->next->ty == Tvoid) if (!committed && t->ty == Tpointer && t->nextOf()->ty == Tvoid)
{ {
error("cannot convert string literal to void*"); error("cannot convert string literal to void*");
} }
se = this;
if (!committed)
{ se = (StringExp *)copy();
se->committed = 1;
copied = 1;
}
if (type == t)
{
return se;
}
tb = t->toBasetype(); tb = t->toBasetype();
//printf("\ttype = %s\n", type->toChars()); //printf("\ttype = %s\n", type->toChars());
if (tb->ty == Tdelegate && type->toBasetype()->ty != Tdelegate) if (tb->ty == Tdelegate && type->toBasetype()->ty != Tdelegate)
return Expression::castTo(sc, t); return Expression::castTo(sc, t);
se = this; Type *typeb = type->toBasetype();
unique = 0; if (typeb == tb)
if (!committed)
{ {
// Copy when committing the type if (!copied)
void *s; { se = (StringExp *)copy();
copied = 1;
s = (unsigned char *)mem.malloc((len + 1) * sz); }
memcpy(s, string, (len + 1) * sz); se->type = t;
se = new StringExp(loc, s, len);
se->type = type;
se->sz = sz;
se->committed = 0;
unique = 1; // this is the only instance
}
se->type = type->toBasetype();
if (tb == se->type)
{ se->type = t;
se->committed = 1;
return se; return se;
} }
if (tb->ty != Tsarray && tb->ty != Tarray && tb->ty != Tpointer) if (tb->ty != Tsarray && tb->ty != Tarray && tb->ty != Tpointer)
{ se->committed = 1; { if (!copied)
{ se = (StringExp *)copy();
copied = 1;
}
goto Lcast; goto Lcast;
} }
if (se->type->ty != Tsarray && se->type->ty != Tarray && se->type->ty != Tpointer) if (typeb->ty != Tsarray && typeb->ty != Tarray && typeb->ty != Tpointer)
{ se->committed = 1; { if (!copied)
goto Lcast; { se = (StringExp *)copy();
} copied = 1;
if (se->committed == 1)
{
if (se->type->next->size() == tb->next->size())
{ se->type = t;
return se;
} }
goto Lcast; goto Lcast;
} }
se->committed = 1; if (typeb->nextOf()->size() == tb->nextOf()->size())
{
if (!copied)
{ se = (StringExp *)copy();
copied = 1;
}
if (tb->ty == Tsarray)
goto L2; // handle possible change in static array dimension
se->type = t;
return se;
}
int tfty; if (committed)
int ttty; goto Lcast;
char *p;
size_t u;
unsigned c;
size_t newlen;
#define X(tf,tt) ((tf) * 256 + (tt)) #define X(tf,tt) ((tf) * 256 + (tt))
{ {
OutBuffer buffer; OutBuffer buffer;
newlen = 0; size_t newlen = 0;
tfty = se->type->next->toBasetype()->ty; int tfty = typeb->nextOf()->toBasetype()->ty;
ttty = tb->next->toBasetype()->ty; int ttty = tb->nextOf()->toBasetype()->ty;
switch (X(tfty, ttty)) switch (X(tfty, ttty))
{ {
case X(Tchar, Tchar): case X(Tchar, Tchar):
@@ -737,9 +745,9 @@ Expression *StringExp::castTo(Scope *sc, Type *t)
break; break;
case X(Tchar, Twchar): case X(Tchar, Twchar):
for (u = 0; u < len;) for (size_t u = 0; u < len;)
{ { unsigned c;
p = utf_decodeChar((unsigned char *)se->string, len, &u, &c); char *p = utf_decodeChar((unsigned char *)se->string, len, &u, &c);
if (p) if (p)
error("%s", p); error("%s", p);
else else
@@ -750,9 +758,9 @@ Expression *StringExp::castTo(Scope *sc, Type *t)
goto L1; goto L1;
case X(Tchar, Tdchar): case X(Tchar, Tdchar):
for (u = 0; u < len;) for (size_t u = 0; u < len;)
{ { unsigned c;
p = utf_decodeChar((unsigned char *)se->string, len, &u, &c); char *p = utf_decodeChar((unsigned char *)se->string, len, &u, &c);
if (p) if (p)
error("%s", p); error("%s", p);
buffer.write4(c); buffer.write4(c);
@@ -762,9 +770,9 @@ Expression *StringExp::castTo(Scope *sc, Type *t)
goto L1; goto L1;
case X(Twchar,Tchar): case X(Twchar,Tchar):
for (u = 0; u < len;) for (size_t u = 0; u < len;)
{ { unsigned c;
p = utf_decodeWchar((unsigned short *)se->string, len, &u, &c); char *p = utf_decodeWchar((unsigned short *)se->string, len, &u, &c);
if (p) if (p)
error("%s", p); error("%s", p);
else else
@@ -775,9 +783,9 @@ Expression *StringExp::castTo(Scope *sc, Type *t)
goto L1; goto L1;
case X(Twchar,Tdchar): case X(Twchar,Tdchar):
for (u = 0; u < len;) for (size_t u = 0; u < len;)
{ { unsigned c;
p = utf_decodeWchar((unsigned short *)se->string, len, &u, &c); char *p = utf_decodeWchar((unsigned short *)se->string, len, &u, &c);
if (p) if (p)
error("%s", p); error("%s", p);
buffer.write4(c); buffer.write4(c);
@@ -787,9 +795,9 @@ Expression *StringExp::castTo(Scope *sc, Type *t)
goto L1; goto L1;
case X(Tdchar,Tchar): case X(Tdchar,Tchar):
for (u = 0; u < len; u++) for (size_t u = 0; u < len; u++)
{ {
c = ((unsigned *)se->string)[u]; unsigned c = ((unsigned *)se->string)[u];
if (!utf_isValidDchar(c)) if (!utf_isValidDchar(c))
error("invalid UCS-32 char \\U%08x", c); error("invalid UCS-32 char \\U%08x", c);
else else
@@ -801,9 +809,9 @@ Expression *StringExp::castTo(Scope *sc, Type *t)
goto L1; goto L1;
case X(Tdchar,Twchar): case X(Tdchar,Twchar):
for (u = 0; u < len; u++) for (size_t u = 0; u < len; u++)
{ {
c = ((unsigned *)se->string)[u]; unsigned c = ((unsigned *)se->string)[u];
if (!utf_isValidDchar(c)) if (!utf_isValidDchar(c))
error("invalid UCS-32 char \\U%08x", c); error("invalid UCS-32 char \\U%08x", c);
else else
@@ -815,22 +823,23 @@ Expression *StringExp::castTo(Scope *sc, Type *t)
goto L1; goto L1;
L1: L1:
if (!unique) if (!copied)
se = new StringExp(loc, NULL, 0); { se = (StringExp *)copy();
copied = 1;
}
se->string = buffer.extractData(); se->string = buffer.extractData();
se->len = newlen; se->len = newlen;
se->sz = tb->next->size(); se->sz = tb->nextOf()->size();
break; break;
default: default:
if (se->type->next->size() == tb->next->size()) assert(typeb->nextOf()->size() != tb->nextOf()->size());
{ se->type = t;
return se;
}
goto Lcast; goto Lcast;
} }
} }
#undef X #undef X
L2:
assert(copied);
// See if need to truncate or extend the literal // See if need to truncate or extend the literal
if (tb->ty == Tsarray) if (tb->ty == Tsarray)
@@ -842,28 +851,18 @@ Expression *StringExp::castTo(Scope *sc, Type *t)
// Changing dimensions // Changing dimensions
if (dim2 != se->len) if (dim2 != se->len)
{ {
// Copy when changing the string literal
unsigned newsz = se->sz; unsigned newsz = se->sz;
void *s;
int d;
if (unique && dim2 < se->len) d = (dim2 < se->len) ? dim2 : se->len;
{ se->len = dim2; s = (unsigned char *)mem.malloc((dim2 + 1) * newsz);
// Add terminating 0 memcpy(s, se->string, d * newsz);
memset((unsigned char *)se->string + dim2 * newsz, 0, newsz); // Extend with 0, add terminating 0
} memset((char *)s + d * newsz, 0, (dim2 + 1 - d) * newsz);
else se->string = s;
{ se->len = dim2;
// Copy when changing the string literal
void *s;
int d;
d = (dim2 < se->len) ? dim2 : se->len;
s = (unsigned char *)mem.malloc((dim2 + 1) * newsz);
memcpy(s, se->string, d * newsz);
// Extend with 0, add terminating 0
memset((char *)s + d * newsz, 0, (dim2 + 1 - d) * newsz);
se = new StringExp(loc, s, dim2);
se->committed = 1; // it now has a firm type
se->sz = newsz;
}
} }
} }
se->type = t; se->type = t;
@@ -871,7 +870,7 @@ Expression *StringExp::castTo(Scope *sc, Type *t)
Lcast: Lcast:
Expression *e = new CastExp(loc, se, t); Expression *e = new CastExp(loc, se, t);
e->type = t; e->type = t; // so semantic() won't be run on e
return e; return e;
} }
+40 -8
View File
@@ -668,7 +668,35 @@ Expression *Equal(enum TOK op, Type *type, Expression *e1, Expression *e2)
assert(op == TOKequal || op == TOKnotequal); assert(op == TOKequal || op == TOKnotequal);
if (e1->op == TOKstring && e2->op == TOKstring) if (e1->op == TOKnull)
{
if (e2->op == TOKnull)
cmp = 1;
else if (e2->op == TOKstring)
{ StringExp *es2 = (StringExp *)e2;
cmp = (0 == es2->len);
}
else if (e2->op == TOKarrayliteral)
{ ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
cmp = !es2->elements || (0 == es2->elements->dim);
}
else
return EXP_CANT_INTERPRET;
}
else if (e2->op == TOKnull)
{
if (e1->op == TOKstring)
{ StringExp *es1 = (StringExp *)e1;
cmp = (0 == es1->len);
}
else if (e1->op == TOKarrayliteral)
{ ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
cmp = !es1->elements || (0 == es1->elements->dim);
}
else
return EXP_CANT_INTERPRET;
}
else if (e1->op == TOKstring && e2->op == TOKstring)
{ StringExp *es1 = (StringExp *)e1; { StringExp *es1 = (StringExp *)e1;
StringExp *es2 = (StringExp *)e2; StringExp *es2 = (StringExp *)e2;
@@ -792,7 +820,11 @@ Expression *Identity(enum TOK op, Type *type, Expression *e1, Expression *e2)
Loc loc = e1->loc; Loc loc = e1->loc;
int cmp; int cmp;
if (e1->op == TOKsymoff && e2->op == TOKsymoff) if (e1->op == TOKnull && e2->op == TOKnull)
{
cmp = 1;
}
else if (e1->op == TOKsymoff && e2->op == TOKsymoff)
{ {
SymOffExp *es1 = (SymOffExp *)e1; SymOffExp *es1 = (SymOffExp *)e1;
SymOffExp *es2 = (SymOffExp *)e2; SymOffExp *es2 = (SymOffExp *)e2;
@@ -1051,7 +1083,7 @@ Expression *Cast(Type *type, Type *to, Expression *e1)
} }
else else
{ {
error("cannot cast %s to %s", e1->type->toChars(), type->toChars()); error(loc, "cannot cast %s to %s", e1->type->toChars(), type->toChars());
e = new IntegerExp(loc, 0, type); e = new IntegerExp(loc, 0, type);
} }
return e; return e;
@@ -1245,11 +1277,11 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
//printf("Cat(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); //printf("Cat(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
if (e1->op == TOKnull && e2->op == TOKint64) if (e1->op == TOKnull && (e2->op == TOKint64 || e2->op == TOKstructliteral))
{ e = e2; { e = e2;
goto L2; goto L2;
} }
else if (e1->op == TOKint64 && e2->op == TOKnull) else if ((e1->op == TOKint64 || e1->op == TOKstructliteral) && e2->op == TOKnull)
{ e = e1; { e = e1;
L2: L2:
Type *tn = e->type->toBasetype(); Type *tn = e->type->toBasetype();
@@ -1381,7 +1413,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
e->type = type; e->type = type;
} }
else if (e1->op == TOKarrayliteral && else if (e1->op == TOKarrayliteral &&
e1->type->toBasetype()->next->equals(e2->type)) e1->type->toBasetype()->nextOf()->equals(e2->type))
{ {
ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
@@ -1398,7 +1430,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
e->type = type; e->type = type;
} }
else if (e2->op == TOKarrayliteral && else if (e2->op == TOKarrayliteral &&
e2->type->toBasetype()->next->equals(e1->type)) e2->type->toBasetype()->nextOf()->equals(e1->type))
{ {
ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
@@ -1425,7 +1457,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
t = e2->type; t = e2->type;
L1: L1:
Type *tb = t->toBasetype(); Type *tb = t->toBasetype();
if (tb->ty == Tarray && tb->next->equals(e->type)) if (tb->ty == Tarray && tb->nextOf()->equals(e->type))
{ Expressions *expressions = new Expressions(); { Expressions *expressions = new Expressions();
expressions->push(e); expressions->push(e);
e = new ArrayLiteralExp(loc, expressions); e = new ArrayLiteralExp(loc, expressions);
+24 -7
View File
@@ -771,7 +771,12 @@ void VarDeclaration::semantic(Scope *sc)
//printf("Providing default initializer for '%s'\n", toChars()); //printf("Providing default initializer for '%s'\n", toChars());
if (type->ty == Tstruct && if (type->ty == Tstruct &&
((TypeStruct *)type)->sym->zeroInit == 1) ((TypeStruct *)type)->sym->zeroInit == 1)
{ { /* If a struct is all zeros, as a special case
* set it's initializer to the integer 0.
* In AssignExp::toElem(), we check for this and issue
* a memset() to initialize the struct.
* Must do same check in interpreter.
*/
Expression *e = new IntegerExp(loc, 0, Type::tint32); Expression *e = new IntegerExp(loc, 0, Type::tint32);
Expression *e1; Expression *e1;
e1 = new VarExp(loc, this); e1 = new VarExp(loc, this);
@@ -801,11 +806,12 @@ void VarDeclaration::semantic(Scope *sc)
if (init) if (init)
{ {
ArrayInitializer *ai = init->isArrayInitializer(); ArrayInitializer *ai = init->isArrayInitializer();
if (ai && type->toBasetype()->ty == Taarray) if (ai && tb->ty == Taarray)
{ {
init = ai->toAssocArrayInitializer(); init = ai->toAssocArrayInitializer();
} }
StructInitializer *si = init->isStructInitializer();
ExpInitializer *ei = init->isExpInitializer(); ExpInitializer *ei = init->isExpInitializer();
// See if we can allocate on the stack // See if we can allocate on the stack
@@ -898,16 +904,25 @@ void VarDeclaration::semantic(Scope *sc)
* Ignore failure. * Ignore failure.
*/ */
if (ei && !global.errors && !inferred) if (!global.errors && !inferred)
{ {
unsigned errors = global.errors; unsigned errors = global.errors;
global.gag++; global.gag++;
//printf("+gag\n"); //printf("+gag\n");
Expression *e = ei->exp->syntaxCopy(); Expression *e;
Initializer *i2 = init;
inuse++; inuse++;
e = e->semantic(sc); if (ei)
{
e = ei->exp->syntaxCopy();
e = e->semantic(sc);
e = e->implicitCastTo(sc, type);
}
else if (si || ai)
{ i2 = init->syntaxCopy();
i2 = i2->semantic(sc, type);
}
inuse--; inuse--;
e = e->implicitCastTo(sc, type);
global.gag--; global.gag--;
//printf("-gag\n"); //printf("-gag\n");
if (errors != global.errors) // if errors happened if (errors != global.errors) // if errors happened
@@ -915,7 +930,7 @@ void VarDeclaration::semantic(Scope *sc)
if (global.gag == 0) if (global.gag == 0)
global.errors = errors; // act as if nothing happened global.errors = errors; // act as if nothing happened
} }
else else if (ei)
{ {
e = e->optimize(WANTvalue | WANTinterpret); e = e->optimize(WANTvalue | WANTinterpret);
if (e->op == TOKint64 || e->op == TOKstring) if (e->op == TOKint64 || e->op == TOKstring)
@@ -923,6 +938,8 @@ void VarDeclaration::semantic(Scope *sc)
ei->exp = e; // no errors, keep result ei->exp = e; // no errors, keep result
} }
} }
else
init = i2; // no errors, keep result
} }
} }
} }
+37
View File
@@ -775,6 +775,43 @@ char *ScopeDsymbol::kind()
} }
/*******************************************
* Look for member of the form:
* const(MemberInfo)[] getMembers(string);
* Returns NULL if not found
*/
#if V2
FuncDeclaration *ScopeDsymbol::findGetMembers()
{
Dsymbol *s = search_function(this, Id::getmembers);
FuncDeclaration *fdx = s ? s->isFuncDeclaration() : NULL;
#if 0 // Finish
static TypeFunction *tfgetmembers;
if (!tfgetmembers)
{
Scope sc;
Arguments *arguments = new Arguments;
Arguments *arg = new Argument(STCin, Type::tchar->constOf()->arrayOf(), NULL, NULL);
arguments->push(arg);
Type *tret = NULL;
tfgetmembers = new TypeFunction(arguments, tret, 0, LINKd);
tfgetmembers = (TypeFunction *)tfgetmembers->semantic(0, &sc);
}
if (fdx)
fdx = fdx->overloadExactMatch(tfgetmembers);
#endif
if (fdx && fdx->isVirtual())
fdx = NULL;
return fdx;
}
#endif
/****************************** WithScopeSymbol ******************************/ /****************************** WithScopeSymbol ******************************/
WithScopeSymbol::WithScopeSymbol(WithStatement *withstate) WithScopeSymbol::WithScopeSymbol(WithStatement *withstate)
+32 -12
View File
@@ -619,9 +619,11 @@ void argsToCBuffer(OutBuffer *buf, Expressions *arguments, HdrGenState *hgs)
for (size_t i = 0; i < arguments->dim; i++) for (size_t i = 0; i < arguments->dim; i++)
{ Expression *arg = (Expression *)arguments->data[i]; { Expression *arg = (Expression *)arguments->data[i];
if (i) if (arg)
buf->writeByte(','); { if (i)
expToCBuffer(buf, hgs, arg, PREC_assign); buf->writeByte(',');
expToCBuffer(buf, hgs, arg, PREC_assign);
}
} }
} }
} }
@@ -3979,9 +3981,9 @@ void HaltExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
/************************************************************/ /************************************************************/
IftypeExp::IftypeExp(Loc loc, Type *targ, Identifier *id, enum TOK tok, IsExp::IsExp(Loc loc, Type *targ, Identifier *id, enum TOK tok,
Type *tspec, enum TOK tok2) Type *tspec, enum TOK tok2)
: Expression(loc, TOKis, sizeof(IftypeExp)) : Expression(loc, TOKis, sizeof(IsExp))
{ {
this->targ = targ; this->targ = targ;
this->id = id; this->id = id;
@@ -3990,9 +3992,9 @@ IftypeExp::IftypeExp(Loc loc, Type *targ, Identifier *id, enum TOK tok,
this->tok2 = tok2; this->tok2 = tok2;
} }
Expression *IftypeExp::syntaxCopy() Expression *IsExp::syntaxCopy()
{ {
return new IftypeExp(loc, return new IsExp(loc,
targ->syntaxCopy(), targ->syntaxCopy(),
id, id,
tok, tok,
@@ -4000,10 +4002,10 @@ Expression *IftypeExp::syntaxCopy()
tok2); tok2);
} }
Expression *IftypeExp::semantic(Scope *sc) Expression *IsExp::semantic(Scope *sc)
{ Type *tded; { Type *tded;
//printf("IftypeExp::semantic()\n"); //printf("IsExp::semantic()\n");
if (id && !(sc->flags & SCOPEstaticif)) if (id && !(sc->flags & SCOPEstaticif))
error("can only declare type aliases within static if conditionals"); error("can only declare type aliases within static if conditionals");
@@ -4201,11 +4203,15 @@ Lno:
return new IntegerExp(0); return new IntegerExp(0);
} }
void IftypeExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) void IsExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{ {
buf->writestring("is("); buf->writestring("is(");
targ->toCBuffer(buf, id, hgs); targ->toCBuffer(buf, id, hgs);
if (tspec) if (tok2 != TOKreserved)
{
buf->printf(" %s %s", Token::toChars(tok), Token::toChars(tok2));
}
else if (tspec)
{ {
if (tok == TOKcolon) if (tok == TOKcolon)
buf->writestring(" : "); buf->writestring(" : ");
@@ -4213,6 +4219,17 @@ void IftypeExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writestring(" == "); buf->writestring(" == ");
tspec->toCBuffer(buf, NULL, hgs); tspec->toCBuffer(buf, NULL, hgs);
} }
#if V2
if (parameters)
{ // First parameter is already output, so start with second
for (int i = 1; i < parameters->dim; i++)
{
buf->writeByte(',');
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
tp->toCBuffer(buf, hgs);
}
}
#endif
buf->writeByte(')'); buf->writeByte(')');
} }
@@ -5308,7 +5325,7 @@ Expression *CallExp::semantic(Scope *sc)
int istemp; int istemp;
#if LOGSEMANTIC #if LOGSEMANTIC
printf("CallExp::semantic('%s')\n", toChars()); printf("CallExp::semantic() %s\n", toChars());
#endif #endif
if (type) if (type)
return this; // semantic() already run return this; // semantic() already run
@@ -5443,6 +5460,9 @@ Lagain:
ad = ((TypeStruct *)t1)->sym; ad = ((TypeStruct *)t1)->sym;
if (search_function(ad, Id::call)) if (search_function(ad, Id::call))
goto L1; // overload of opCall, therefore it's a call goto L1; // overload of opCall, therefore it's a call
if (e1->op != TOKtype)
error("%s %s does not overload ()", ad->kind(), ad->toChars());
/* It's a struct literal /* It's a struct literal
*/ */
Expression *e = new StructLiteralExp(loc, (StructDeclaration *)ad, arguments); Expression *e = new StructLiteralExp(loc, (StructDeclaration *)ad, arguments);
+4 -2
View File
@@ -70,6 +70,8 @@ void inferApplyArgTypes(enum TOK op, Arguments *arguments, Expression *aggr);
void argExpTypesToCBuffer(OutBuffer *buf, Expressions *arguments, HdrGenState *hgs); void argExpTypesToCBuffer(OutBuffer *buf, Expressions *arguments, HdrGenState *hgs);
void argsToCBuffer(OutBuffer *buf, Expressions *arguments, HdrGenState *hgs); void argsToCBuffer(OutBuffer *buf, Expressions *arguments, HdrGenState *hgs);
void expandTuples(Expressions *exps); void expandTuples(Expressions *exps);
FuncDeclaration *hasThis(Scope *sc);
Expression *fromConstInitializer(int result, Expression *e);
struct Expression : Object struct Expression : Object
{ {
@@ -622,7 +624,7 @@ struct HaltExp : Expression
elem *toElem(IRState *irs); elem *toElem(IRState *irs);
}; };
struct IftypeExp : Expression struct IsExp : Expression
{ {
/* is(targ id tok tspec) /* is(targ id tok tspec)
* is(targ id == tok2) * is(targ id == tok2)
@@ -633,7 +635,7 @@ struct IftypeExp : Expression
Type *tspec; // can be NULL Type *tspec; // can be NULL
enum TOK tok2; // 'struct', 'union', 'typedef', etc. enum TOK tok2; // 'struct', 'union', 'typedef', etc.
IftypeExp(Loc loc, Type *targ, Identifier *id, enum TOK tok, Type *tspec, enum TOK tok2); IsExp(Loc loc, Type *targ, Identifier *id, enum TOK tok, Type *tspec, enum TOK tok2);
Expression *syntaxCopy(); Expression *syntaxCopy();
Expression *semantic(Scope *sc); Expression *semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+10 -7
View File
@@ -255,7 +255,7 @@ void FuncDeclaration::semantic(Scope *sc)
if (!isVirtual()) if (!isVirtual())
{ {
//printf("\tnot virtual\n"); //printf("\tnot virtual\n");
return; goto Ldone;
} }
// Find index of existing function in vtbl[] to override // Find index of existing function in vtbl[] to override
@@ -405,8 +405,8 @@ void FuncDeclaration::semantic(Scope *sc)
#if 0 #if 0
if (offset) if (offset)
ti = fdv->type; ti = fdv->type;
else if (type->next->ty == Tclass) else if (type->nextOf()->ty == Tclass)
{ ClassDeclaration *cdn = ((TypeClass *)type->next)->sym; { ClassDeclaration *cdn = ((TypeClass *)type->nextOf())->sym;
if (cdn && cdn->sizeok != 1) if (cdn && cdn->sizeok != 1)
ti = fdv->type; ti = fdv->type;
} }
@@ -480,8 +480,8 @@ void FuncDeclaration::semantic(Scope *sc)
{ {
Argument *arg0 = Argument::getNth(f->parameters, 0); Argument *arg0 = Argument::getNth(f->parameters, 0);
if (arg0->type->ty != Tarray || if (arg0->type->ty != Tarray ||
arg0->type->next->ty != Tarray || arg0->type->nextOf()->ty != Tarray ||
arg0->type->next->next->ty != Tchar || arg0->type->nextOf()->nextOf()->ty != Tchar ||
arg0->storageClass & (STCout | STCref | STClazy)) arg0->storageClass & (STCout | STCref | STClazy))
goto Lmainerr; goto Lmainerr;
break; break;
@@ -526,6 +526,7 @@ void FuncDeclaration::semantic(Scope *sc)
} }
} }
Ldone:
/* Save scope for possible later use (if we need the /* Save scope for possible later use (if we need the
* function internals) * function internals)
*/ */
@@ -2185,7 +2186,8 @@ void DtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
/********************************* StaticCtorDeclaration ****************************/ /********************************* StaticCtorDeclaration ****************************/
StaticCtorDeclaration::StaticCtorDeclaration(Loc loc, Loc endloc) StaticCtorDeclaration::StaticCtorDeclaration(Loc loc, Loc endloc)
: FuncDeclaration(loc, endloc, Id::staticCtor, STCstatic, NULL) : FuncDeclaration(loc, endloc,
Identifier::generateId("_staticCtor"), STCstatic, NULL)
{ {
} }
@@ -2257,7 +2259,8 @@ void StaticCtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
/********************************* StaticDtorDeclaration ****************************/ /********************************* StaticDtorDeclaration ****************************/
StaticDtorDeclaration::StaticDtorDeclaration(Loc loc, Loc endloc) StaticDtorDeclaration::StaticDtorDeclaration(Loc loc, Loc endloc)
: FuncDeclaration(loc, endloc, Id::staticDtor, STCstatic, NULL) : FuncDeclaration(loc, endloc,
Identifier::generateId("_staticDtor"), STCstatic, NULL)
{ {
} }
-4
View File
@@ -12,8 +12,6 @@ Identifier *Id::ctor;
Identifier *Id::dtor; Identifier *Id::dtor;
Identifier *Id::classInvariant; Identifier *Id::classInvariant;
Identifier *Id::unitTest; Identifier *Id::unitTest;
Identifier *Id::staticCtor;
Identifier *Id::staticDtor;
Identifier *Id::init; Identifier *Id::init;
Identifier *Id::size; Identifier *Id::size;
Identifier *Id::__sizeof; Identifier *Id::__sizeof;
@@ -187,8 +185,6 @@ void Id::initialize()
dtor = Lexer::idPool("_dtor"); dtor = Lexer::idPool("_dtor");
classInvariant = Lexer::idPool("__invariant"); classInvariant = Lexer::idPool("__invariant");
unitTest = Lexer::idPool("_unitTest"); unitTest = Lexer::idPool("_unitTest");
staticCtor = Lexer::idPool("_staticCtor");
staticDtor = Lexer::idPool("_staticDtor");
init = Lexer::idPool("init"); init = Lexer::idPool("init");
size = Lexer::idPool("size"); size = Lexer::idPool("size");
__sizeof = Lexer::idPool("sizeof"); __sizeof = Lexer::idPool("sizeof");
-2
View File
@@ -14,8 +14,6 @@ struct Id
static Identifier *dtor; static Identifier *dtor;
static Identifier *classInvariant; static Identifier *classInvariant;
static Identifier *unitTest; static Identifier *unitTest;
static Identifier *staticCtor;
static Identifier *staticDtor;
static Identifier *init; static Identifier *init;
static Identifier *size; static Identifier *size;
static Identifier *__sizeof; static Identifier *__sizeof;
+9 -3
View File
@@ -53,14 +53,20 @@ char *Identifier::toHChars2()
else if (this == Id::dtor) p = "~this"; else if (this == Id::dtor) p = "~this";
else if (this == Id::classInvariant) p = "invariant"; else if (this == Id::classInvariant) p = "invariant";
else if (this == Id::unitTest) p = "unittest"; else if (this == Id::unitTest) p = "unittest";
else if (this == Id::staticCtor) p = "static this";
else if (this == Id::staticDtor) p = "static ~this";
else if (this == Id::dollar) p = "$"; else if (this == Id::dollar) p = "$";
else if (this == Id::withSym) p = "with"; else if (this == Id::withSym) p = "with";
else if (this == Id::result) p = "result"; else if (this == Id::result) p = "result";
else if (this == Id::returnLabel) p = "return"; else if (this == Id::returnLabel) p = "return";
else else
p = toChars(); { p = toChars();
if (*p == '_')
{
if (memcmp(p, "_staticCtor", 11) == 0)
p = "static this";
else if (memcmp(p, "_staticDtor", 11) == 0)
p = "static ~this";
}
}
return p; return p;
} }
-2
View File
@@ -38,8 +38,6 @@ Msgtable msgtable[] =
{ "dtor", "_dtor" }, { "dtor", "_dtor" },
{ "classInvariant", "__invariant" }, { "classInvariant", "__invariant" },
{ "unitTest", "_unitTest" }, { "unitTest", "_unitTest" },
{ "staticCtor", "_staticCtor" },
{ "staticDtor", "_staticDtor" },
{ "init" }, { "init" },
{ "size" }, { "size" },
{ "__sizeof", "sizeof" }, { "__sizeof", "sizeof" },
+36 -2
View File
@@ -235,9 +235,43 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t)
} }
/***************************************
* This works by transforming a struct initializer into
* a struct literal. In the future, the two should be the
* same thing.
*/
Expression *StructInitializer::toExpression() Expression *StructInitializer::toExpression()
{ { Expression *e;
return NULL; // cannot do it
//printf("StructInitializer::toExpression() %s\n", toChars());
if (!ad) // if fwd referenced
{
return NULL;
}
StructDeclaration *sd = ad->isStructDeclaration();
if (!sd)
return NULL;
Expressions *elements = new Expressions();
for (size_t i = 0; i < value.dim; i++)
{
if (field.data[i])
goto Lno;
Initializer *iz = (Initializer *)value.data[i];
if (!iz)
goto Lno;
Expression *ex = iz->toExpression();
if (!ex)
goto Lno;
elements->push(ex);
}
e = new StructLiteralExp(loc, sd, elements);
e->type = sd->type;
return e;
Lno:
delete elements;
//error(loc, "struct initializers as expressions are not allowed");
return NULL;
} }
+3 -2
View File
@@ -23,6 +23,7 @@ struct Type;
struct dt_t; struct dt_t;
struct AggregateDeclaration; struct AggregateDeclaration;
struct VoidInitializer; struct VoidInitializer;
struct StructInitializer;
struct ArrayInitializer; struct ArrayInitializer;
struct ExpInitializer; struct ExpInitializer;
struct StructInitializer; struct StructInitializer;
@@ -47,9 +48,9 @@ struct Initializer : Object
virtual dt_t *toDt(); virtual dt_t *toDt();
virtual VoidInitializer *isVoidInitializer() { return NULL; } virtual VoidInitializer *isVoidInitializer() { return NULL; }
virtual StructInitializer *isStructInitializer() { return NULL; }
virtual ArrayInitializer *isArrayInitializer() { return NULL; } virtual ArrayInitializer *isArrayInitializer() { return NULL; }
virtual ExpInitializer *isExpInitializer() { return NULL; } virtual ExpInitializer *isExpInitializer() { return NULL; }
virtual StructInitializer *isStructInitializer() { return NULL; }
}; };
struct VoidInitializer : Initializer struct VoidInitializer : Initializer
@@ -84,7 +85,7 @@ struct StructInitializer : Initializer
dt_t *toDt(); dt_t *toDt();
virtual StructInitializer *isStructInitializer() { return this; } StructInitializer *isStructInitializer() { return this; }
}; };
struct ArrayInitializer : Initializer struct ArrayInitializer : Initializer
+44 -18
View File
@@ -77,6 +77,7 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
return NULL; return NULL;
} }
//printf("test2 %d, %p\n", semanticRun, scope);
if (semanticRun == 0 && scope) if (semanticRun == 0 && scope)
{ {
semantic3(scope); semantic3(scope);
@@ -276,7 +277,7 @@ Expression *ExpStatement::interpret(InterState *istate)
Expression *e = exp->interpret(istate); Expression *e = exp->interpret(istate);
if (e == EXP_CANT_INTERPRET) if (e == EXP_CANT_INTERPRET)
{ {
//printf("cannot interpret %s\n", exp->toChars()); //printf("-ExpStatement::interpret(): %p\n", e);
return EXP_CANT_INTERPRET; return EXP_CANT_INTERPRET;
} }
} }
@@ -364,20 +365,13 @@ Expression *IfStatement::interpret(InterState *istate)
//if (e == EXP_CANT_INTERPRET) printf("cannot interpret\n"); //if (e == EXP_CANT_INTERPRET) printf("cannot interpret\n");
if (e != EXP_CANT_INTERPRET) if (e != EXP_CANT_INTERPRET)
{ {
if (!e->isConst()) if (e->isBool(TRUE))
{ e = ifbody ? ifbody->interpret(istate) : NULL;
e = EXP_CANT_INTERPRET; else if (e->isBool(FALSE))
} e = elsebody ? elsebody->interpret(istate) : NULL;
else else
{ {
if (e->isBool(TRUE)) e = EXP_CANT_INTERPRET;
e = ifbody ? ifbody->interpret(istate) : NULL;
else if (e->isBool(FALSE))
e = elsebody ? elsebody->interpret(istate) : NULL;
else
{
e = EXP_CANT_INTERPRET;
}
} }
} }
return e; return e;
@@ -957,7 +951,7 @@ Expression *getVarExp(Loc loc, InterState *istate, Declaration *d)
{ {
if (v->isConst() && v->init) if (v->isConst() && v->init)
{ e = v->init->toExpression(); { e = v->init->toExpression();
if (!e->type) if (e && !e->type)
e->type = v->type; e->type = v->type;
} }
else else
@@ -994,7 +988,7 @@ Expression *DeclarationExp::interpret(InterState *istate)
#if LOG #if LOG
printf("DeclarationExp::interpret() %s\n", toChars()); printf("DeclarationExp::interpret() %s\n", toChars());
#endif #endif
Expression *e = EXP_CANT_INTERPRET; Expression *e;
VarDeclaration *v = declaration->isVarDeclaration(); VarDeclaration *v = declaration->isVarDeclaration();
if (v) if (v)
{ {
@@ -1015,6 +1009,19 @@ Expression *DeclarationExp::interpret(InterState *istate)
e->type = v->type; e->type = v->type;
} }
} }
else if (declaration->isAttribDeclaration() ||
declaration->isTemplateMixin() ||
declaration->isTupleDeclaration())
{ // These can be made to work, too lazy now
e = EXP_CANT_INTERPRET;
}
else
{ // Others should not contain executable code, so are trivial to evaluate
e = NULL;
}
#if LOG
printf("-DeclarationExp::interpret(): %p\n", e);
#endif
return e; return e;
} }
@@ -1084,7 +1091,7 @@ Expression *ArrayLiteralExp::interpret(InterState *istate)
if (!expsx) if (!expsx)
{ expsx = new Expressions(); { expsx = new Expressions();
expsx->setDim(elements->dim); expsx->setDim(elements->dim);
for (size_t j = 0; j < i; j++) for (size_t j = 0; j < elements->dim; j++)
{ {
expsx->data[j] = elements->data[j]; expsx->data[j] = elements->data[j];
} }
@@ -1342,6 +1349,7 @@ Expression *BinExp::interpretCommon2(InterState *istate, fp2_t fp)
if (e1 == EXP_CANT_INTERPRET) if (e1 == EXP_CANT_INTERPRET)
goto Lcant; goto Lcant;
if (e1->isConst() != 1 && if (e1->isConst() != 1 &&
e1->op != TOKnull &&
e1->op != TOKstring && e1->op != TOKstring &&
e1->op != TOKarrayliteral && e1->op != TOKarrayliteral &&
e1->op != TOKstructliteral) e1->op != TOKstructliteral)
@@ -1351,6 +1359,7 @@ Expression *BinExp::interpretCommon2(InterState *istate, fp2_t fp)
if (e2 == EXP_CANT_INTERPRET) if (e2 == EXP_CANT_INTERPRET)
goto Lcant; goto Lcant;
if (e2->isConst() != 1 && if (e2->isConst() != 1 &&
e2->op != TOKnull &&
e2->op != TOKstring && e2->op != TOKstring &&
e2->op != TOKarrayliteral && e2->op != TOKarrayliteral &&
e2->op != TOKstructliteral) e2->op != TOKstructliteral)
@@ -1420,7 +1429,14 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, fp_t fp, int post)
if (fp) if (fp)
e2 = (*fp)(v->type, ev, e2); e2 = (*fp)(v->type, ev, e2);
else else
{ /* Look for special case of struct being initialized with 0.
*/
if (v->type->toBasetype()->ty == Tstruct && e2->op == TOKint64)
{
e2 = v->type->defaultInit();
}
e2 = Cast(v->type, v->type, e2); e2 = Cast(v->type, v->type, e2);
}
if (e2 != EXP_CANT_INTERPRET) if (e2 != EXP_CANT_INTERPRET)
{ {
if (!v->isParameter()) if (!v->isParameter())
@@ -1453,9 +1469,15 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, fp_t fp, int post)
{ error("variable %s is used before initialization", v->toChars()); { error("variable %s is used before initialization", v->toChars());
return e; return e;
} }
if (v->value->op != TOKstructliteral) Expression *vie = v->value;
if (vie->op == TOKvar)
{
Declaration *d = ((VarExp *)vie)->var;
vie = getVarExp(e1->loc, istate, d);
}
if (vie->op != TOKstructliteral)
return EXP_CANT_INTERPRET; return EXP_CANT_INTERPRET;
StructLiteralExp *se = (StructLiteralExp *)v->value; StructLiteralExp *se = (StructLiteralExp *)vie;
int fieldi = se->getFieldIndex(type, soe->offset); int fieldi = se->getFieldIndex(type, soe->offset);
if (fieldi == -1) if (fieldi == -1)
return EXP_CANT_INTERPRET; return EXP_CANT_INTERPRET;
@@ -1843,6 +1865,10 @@ Expression *ArrayLengthExp::interpret(InterState *istate)
{ {
e = ArrayLength(type, e1); e = ArrayLength(type, e1);
} }
else if (e1->op == TOKnull)
{
e = new IntegerExp(loc, 0, type);
}
else else
goto Lcant; goto Lcant;
return e; return e;
+242 -1
View File
@@ -459,7 +459,7 @@ int Lexer::isValidIdentifier(char *p)
if (!p || !*p) if (!p || !*p)
goto Linvalid; goto Linvalid;
if (isdigit(*p)) if (*p >= '0' && *p <= '9') // beware of isdigit() on signed chars
goto Linvalid; goto Linvalid;
len = strlen(p); len = strlen(p);
@@ -568,6 +568,23 @@ void Lexer::scan(Token *t)
t->value = hexStringConstant(t); t->value = hexStringConstant(t);
return; return;
#if V2
case 'q':
if (p[1] == '"')
{
p++;
t->value = delimitedStringConstant(t);
return;
}
else if (p[1] == '{')
{
p++;
t->value = tokenStringConstant(t);
return;
}
else
goto case_ident;
#endif
case '"': case '"':
t->value = escapeStringConstant(t,0); t->value = escapeStringConstant(t,0);
@@ -598,7 +615,11 @@ void Lexer::scan(Token *t)
case 'a': case 'b': case 'c': case 'd': case 'e': case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i': case 'j': case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'm': case 'n': case 'o': case 'k': case 'm': case 'n': case 'o':
#if V2
case 'p': /*case 'q': case 'r':*/ case 's': case 't':
#else
case 'p': case 'q': /*case 'r':*/ case 's': case 't': case 'p': case 'q': /*case 'r':*/ case 's': case 't':
#endif
case 'u': case 'v': case 'w': /*case 'x':*/ case 'y': case 'u': case 'v': case 'w': /*case 'x':*/ case 'y':
case 'z': case 'z':
case 'A': case 'B': case 'C': case 'D': case 'E': case 'A': case 'B': case 'C': case 'D': case 'E':
@@ -1431,6 +1452,223 @@ TOK Lexer::hexStringConstant(Token *t)
} }
} }
#if V2
/**************************************
* Lex delimited strings:
* q"(foo(xxx))" // "foo(xxx)"
* q"[foo(]" // "foo("
* q"/foo]/" // "foo]"
* q"HERE
* foo
* HERE" // "foo\n"
* Input:
* p is on the "
*/
TOK Lexer::delimitedStringConstant(Token *t)
{ unsigned c;
Loc start = loc;
unsigned delimleft = 0;
unsigned delimright = 0;
unsigned nest = 1;
unsigned nestcount;
Identifier *hereid = NULL;
unsigned blankrol = 0;
unsigned startline = 0;
p++;
stringbuffer.reset();
while (1)
{
c = *p++;
//printf("c = '%c'\n", c);
switch (c)
{
case '\n':
Lnextline:
printf("Lnextline\n");
loc.linnum++;
startline = 1;
if (blankrol)
{ blankrol = 0;
continue;
}
if (hereid)
{
stringbuffer.writeUTF8(c);
continue;
}
break;
case '\r':
if (*p == '\n')
continue; // ignore
c = '\n'; // treat EndOfLine as \n character
goto Lnextline;
case 0:
case 0x1A:
goto Lerror;
default:
if (c & 0x80)
{ p--;
c = decodeUTF();
p++;
if (c == PS || c == LS)
goto Lnextline;
}
break;
}
if (delimleft == 0)
{ delimleft = c;
nest = 1;
nestcount = 1;
if (c == '(')
delimright = ')';
else if (c == '{')
delimright = '}';
else if (c == '[')
delimright = ']';
else if (c == '<')
delimright = '>';
else if (isalpha(c) || c == '_' || (c >= 0x80 && isUniAlpha(c)))
{ // Start of identifier; must be a heredoc
Token t;
p--;
scan(&t); // read in heredoc identifier
if (t.value != TOKidentifier)
{ error("identifier expected for heredoc, not %s", t.toChars());
delimright = c;
}
else
{ hereid = t.ident;
printf("hereid = '%s'\n", hereid->toChars());
blankrol = 1;
}
nest = 0;
}
else
{ delimright = c;
nest = 0;
}
}
else
{
if (blankrol)
{ error("heredoc rest of line should be blank");
blankrol = 0;
continue;
}
if (nest == 1)
{
if (c == delimleft)
nestcount++;
else if (c == delimright)
{ nestcount--;
if (nestcount == 0)
goto Ldone;
}
}
else if (c == delimright)
goto Ldone;
if (startline && isalpha(c))
{ Token t;
unsigned char *psave = p;
p--;
scan(&t); // read in possible heredoc identifier
printf("endid = '%s'\n", t.ident->toChars());
if (t.value == TOKidentifier && t.ident->equals(hereid))
{ /* should check that rest of line is blank
*/
printf("done\n");
goto Ldone;
}
p = psave;
}
stringbuffer.writeUTF8(c);
startline = 0;
}
}
Ldone:
if (*p == '"')
p++;
else
error("delimited string must end in %c\"", delimright);
t->len = stringbuffer.offset;
stringbuffer.writeByte(0);
t->ustring = (unsigned char *)mem.malloc(stringbuffer.offset);
memcpy(t->ustring, stringbuffer.data, stringbuffer.offset);
stringPostfix(t);
return TOKstring;
Lerror:
error("unterminated string constant starting at %s", start.toChars());
t->ustring = (unsigned char *)"";
t->len = 0;
t->postfix = 0;
return TOKstring;
}
/**************************************
* Lex delimited strings:
* q{ foo(xxx) } // " foo(xxx) "
* q{foo(} // "foo("
* q{{foo}"}"} // "{foo}"}""
* Input:
* p is on the q
*/
TOK Lexer::tokenStringConstant(Token *t)
{
unsigned nest = 1;
Loc start = loc;
unsigned char *pstart = ++p;
while (1)
{ Token tok;
scan(&tok);
switch (tok.value)
{
case TOKlcurly:
nest++;
continue;
case TOKrcurly:
if (--nest == 0)
goto Ldone;
continue;
case TOKeof:
goto Lerror;
default:
continue;
}
}
Ldone:
t->len = p - 1 - pstart;
t->ustring = (unsigned char *)mem.malloc(t->len + 1);
memcpy(t->ustring, pstart, t->len);
t->ustring[t->len] = 0;
stringPostfix(t);
return TOKstring;
Lerror:
error("unterminated token string constant starting at %s", start.toChars());
t->ustring = (unsigned char *)"";
t->len = 0;
t->postfix = 0;
return TOKstring;
}
#endif
/************************************** /**************************************
*/ */
@@ -2641,6 +2879,9 @@ static Keyword keywords[] =
// Added after 1.0 // Added after 1.0
{ "ref", TOKref }, { "ref", TOKref },
{ "macro", TOKmacro }, { "macro", TOKmacro },
#if V2
{ "__traits", TOKtraits },
#endif
}; };
int Token::isKeyword() int Token::isKeyword()
+7
View File
@@ -150,6 +150,9 @@ enum TOK
// Added after 1.0 // Added after 1.0
TOKref, TOKref,
TOKmacro, TOKmacro,
#if V2
TOKtraits,
#endif
TOKMAX TOKMAX
}; };
@@ -266,6 +269,10 @@ struct Lexer
unsigned escapeSequence(); unsigned escapeSequence();
TOK wysiwygStringConstant(Token *t, int tc); TOK wysiwygStringConstant(Token *t, int tc);
TOK hexStringConstant(Token *t); TOK hexStringConstant(Token *t);
#if V2
TOK delimitedStringConstant(Token *t);
TOK tokenStringConstant(Token *t);
#endif
TOK escapeStringConstant(Token *t, int wide); TOK escapeStringConstant(Token *t, int wide);
TOK charConstant(Token *t, int wide); TOK charConstant(Token *t, int wide);
void stringPostfix(Token *t); void stringPostfix(Token *t);
+13 -2
View File
@@ -68,7 +68,7 @@ Global::Global()
copyright = "Copyright (c) 1999-2007 by Digital Mars and Tomas Lindquist Olsen"; copyright = "Copyright (c) 1999-2007 by Digital Mars and Tomas Lindquist Olsen";
written = "written by Walter Bright and Tomas Lindquist Olsen"; written = "written by Walter Bright and Tomas Lindquist Olsen";
llvmdc_version = "0.0.1"; llvmdc_version = "0.0.1";
version = "v1.020"; version = "v1.021";
global.structalign = 8; global.structalign = 8;
memset(&params, 0, sizeof(Param)); memset(&params, 0, sizeof(Param));
@@ -282,6 +282,9 @@ int main(int argc, char *argv[])
global.params.optimizeLevel = 2; global.params.optimizeLevel = 2;
global.params.runtimeImppath = 0; global.params.runtimeImppath = 0;
global.params.defaultlibname = "phobos";
global.params.debuglibname = global.params.defaultlibname;
// Predefine version identifiers // Predefine version identifiers
#if IN_LLVM #if IN_LLVM
VersionCondition::addPredefinedGlobalIdent("LLVM"); VersionCondition::addPredefinedGlobalIdent("LLVM");
@@ -474,7 +477,7 @@ int main(int argc, char *argv[])
{ {
global.params.runtimeImppath = p+2; global.params.runtimeImppath = p+2;
} }
else if (memcmp(p + 1, "debug", 5) == 0) else if (memcmp(p + 1, "debug", 5) == 0 && p[6] != 'l')
{ {
// Parse: // Parse:
// -debug // -debug
@@ -545,6 +548,14 @@ int main(int argc, char *argv[])
{ {
global.params.linkswitches->push(p + 2); global.params.linkswitches->push(p + 2);
} }
else if (memcmp(p + 1, "defaultlib=", 11) == 0)
{
global.params.defaultlibname = p + 1 + 11;
}
else if (memcmp(p + 1, "debuglib=", 9) == 0)
{
global.params.debuglibname = p + 1 + 9;
}
else if (strcmp(p + 1, "run") == 0) else if (strcmp(p + 1, "run") == 0)
{ global.params.run = 1; { global.params.run = 1;
global.params.runargs_length = ((i >= argcstart) ? argc : argcstart) - i - 1; global.params.runargs_length = ((i >= argcstart) ? argc : argcstart) - i - 1;
+5
View File
@@ -94,6 +94,11 @@ struct Param
bool dump_source; bool dump_source;
char *defaultlibname; // default library for non-debug builds
char *debuglibname; // default library for debug builds
char *xmlname; // filename for XML output
// Hidden debug switches // Hidden debug switches
char debuga; char debuga;
char debugb; char debugb;
+1 -1
View File
@@ -3940,7 +3940,7 @@ Expression *Parser::parsePrimaryExp()
{ error("(type identifier : specialization) expected following is"); { error("(type identifier : specialization) expected following is");
goto Lerr; goto Lerr;
} }
e = new IftypeExp(loc, targ, ident, tok, tspec, tok2); e = new IsExp(loc, targ, ident, tok, tspec, tok2);
break; break;
} }
+20 -19
View File
@@ -894,6 +894,7 @@ Statement *DoStatement::semantic(Scope *sc)
sc->noctor--; sc->noctor--;
condition = condition->semantic(sc); condition = condition->semantic(sc);
condition = resolveProperties(sc, condition); condition = resolveProperties(sc, condition);
condition = condition->optimize(WANTvalue);
condition = condition->checkToBoolean(); condition = condition->checkToBoolean();
@@ -979,6 +980,7 @@ Statement *ForStatement::semantic(Scope *sc)
sc->noctor++; sc->noctor++;
condition = condition->semantic(sc); condition = condition->semantic(sc);
condition = resolveProperties(sc, condition); condition = resolveProperties(sc, condition);
condition = condition->optimize(WANTvalue);
condition = condition->checkToBoolean(); condition = condition->checkToBoolean();
if (increment) if (increment)
increment = increment->semantic(sc); increment = increment->semantic(sc);
@@ -1090,7 +1092,8 @@ Statement *ForeachStatement::syntaxCopy()
{ {
Arguments *args = Argument::arraySyntaxCopy(arguments); Arguments *args = Argument::arraySyntaxCopy(arguments);
Expression *exp = aggr->syntaxCopy(); Expression *exp = aggr->syntaxCopy();
ForeachStatement *s = new ForeachStatement(loc, op, args, exp, body->syntaxCopy()); ForeachStatement *s = new ForeachStatement(loc, op, args, exp,
body ? body->syntaxCopy() : NULL);
return s; return s;
} }
@@ -1255,7 +1258,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
/* Look for special case of parsing char types out of char type /* Look for special case of parsing char types out of char type
* array. * array.
*/ */
tn = tab->next->toBasetype(); tn = tab->nextOf()->toBasetype();
if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar) if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar)
{ Argument *arg; { Argument *arg;
@@ -1311,9 +1314,6 @@ Statement *ForeachStatement::semantic(Scope *sc)
error("foreach: %s is not an array of %s", tab->toChars(), value->type->toChars()); error("foreach: %s is not an array of %s", tab->toChars(), value->type->toChars());
} }
if (value->storage_class & STCout && value->type->toBasetype()->ty == Tbit)
error("foreach: value cannot be out and type bit");
if (key && if (key &&
((key->type->ty != Tint32 && key->type->ty != Tuns32) || ((key->type->ty != Tint32 && key->type->ty != Tuns32) ||
(global.params.is64bit && (global.params.is64bit &&
@@ -1356,7 +1356,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
Identifier *id; Identifier *id;
Type *tret; Type *tret;
tret = func->type->next; tret = func->type->nextOf();
// Need a variable to hold value from any return statements in body. // Need a variable to hold value from any return statements in body.
if (!sc->func->vresult && tret && tret != Type::tvoid) if (!sc->func->vresult && tret && tret != Type::tvoid)
@@ -1430,8 +1430,8 @@ Statement *ForeachStatement::semantic(Scope *sc)
error("foreach: index must be type %s, not %s", taa->index->toChars(), arg->type->toChars()); error("foreach: index must be type %s, not %s", taa->index->toChars(), arg->type->toChars());
arg = (Argument *)arguments->data[1]; arg = (Argument *)arguments->data[1];
} }
if (!arg->type->equals(taa->next)) if (!arg->type->equals(taa->nextOf()))
error("foreach: value must be type %s, not %s", taa->next->toChars(), arg->type->toChars()); error("foreach: value must be type %s, not %s", taa->nextOf()->toChars(), arg->type->toChars());
/* Call: /* Call:
* _aaApply(aggr, keysize, flde) * _aaApply(aggr, keysize, flde)
@@ -1982,7 +1982,7 @@ Statement *SwitchStatement::semantic(Scope *sc)
// If it's not an array, cast it to one // If it's not an array, cast it to one
if (condition->type->ty != Tarray) if (condition->type->ty != Tarray)
{ {
condition = condition->implicitCastTo(sc, condition->type->next->arrayOf()); condition = condition->implicitCastTo(sc, condition->type->nextOf()->arrayOf());
} }
} }
else else
@@ -2122,6 +2122,7 @@ Statement *CaseStatement::syntaxCopy()
Statement *CaseStatement::semantic(Scope *sc) Statement *CaseStatement::semantic(Scope *sc)
{ SwitchStatement *sw = sc->sw; { SwitchStatement *sw = sc->sw;
//printf("CaseStatement::semantic() %s\n", toChars());
exp = exp->semantic(sc); exp = exp->semantic(sc);
if (sw) if (sw)
{ int i; { int i;
@@ -2390,9 +2391,9 @@ Statement *ReturnStatement::semantic(Scope *sc)
} }
} }
Type *tret = fd->type->next; Type *tret = fd->type->nextOf();
if (fd->tintro) if (fd->tintro)
tret = fd->tintro->next; tret = fd->tintro->nextOf();
Type *tbret = NULL; Type *tbret = NULL;
if (tret) if (tret)
@@ -2452,18 +2453,18 @@ Statement *ReturnStatement::semantic(Scope *sc)
} }
else if (fd->inferRetType) else if (fd->inferRetType)
{ {
if (fd->type->next) if (fd->type->nextOf())
{ {
if (!exp->type->equals(fd->type->next)) if (!exp->type->equals(fd->type->nextOf()))
error("mismatched function return type inference of %s and %s", error("mismatched function return type inference of %s and %s",
exp->type->toChars(), fd->type->next->toChars()); exp->type->toChars(), fd->type->nextOf()->toChars());
} }
else else
{ {
fd->type->next = exp->type; fd->type->next = exp->type;
fd->type = fd->type->semantic(loc, sc); fd->type = fd->type->semantic(loc, sc);
if (!fd->tintro) if (!fd->tintro)
{ tret = fd->type->next; { tret = fd->type->nextOf();
tbret = tret->toBasetype(); tbret = tret->toBasetype();
} }
} }
@@ -2475,11 +2476,11 @@ Statement *ReturnStatement::semantic(Scope *sc)
} }
else if (fd->inferRetType) else if (fd->inferRetType)
{ {
if (fd->type->next) if (fd->type->nextOf())
{ {
if (fd->type->next->ty != Tvoid) if (fd->type->nextOf()->ty != Tvoid)
error("mismatched function return type inference of void and %s", error("mismatched function return type inference of void and %s",
fd->type->next->toChars()); fd->type->nextOf()->toChars());
} }
else else
{ {
@@ -2510,7 +2511,7 @@ Statement *ReturnStatement::semantic(Scope *sc)
sc->fes->cases.push(this); sc->fes->cases.push(this);
s = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1)); s = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
} }
else if (fd->type->next->toBasetype() == Type::tvoid) else if (fd->type->nextOf()->toBasetype() == Type::tvoid)
{ {
Statement *s1; Statement *s1;
Statement *s2; Statement *s2;
+1
View File
@@ -49,6 +49,7 @@ void StaticAssert::semantic2(Scope *sc)
{ {
Expression *e; Expression *e;
//printf("StaticAssert::semantic2() %s\n", toChars());
e = exp->semantic(sc); e = exp->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret); e = e->optimize(WANTvalue | WANTinterpret);
if (e->isBool(FALSE)) if (e->isBool(FALSE))
+3 -2
View File
@@ -1232,7 +1232,7 @@ MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
return (MATCH) implicitConvTo(at); return (MATCH) implicitConvTo(at);
} }
else if (ty == Tsarray && at->ty == Tarray && else if (ty == Tsarray && at->ty == Tarray &&
next->equals(at->nextOf())) nextOf()->equals(at->nextOf()))
{ {
goto Lexact; goto Lexact;
} }
@@ -3278,7 +3278,6 @@ Identifier *TemplateInstance::genIdent()
else if (ea) else if (ea)
{ sinteger_t v; { sinteger_t v;
real_t r; real_t r;
unsigned char *p;
if (ea->op == TOKvar) if (ea->op == TOKvar)
{ {
@@ -3298,6 +3297,8 @@ Identifier *TemplateInstance::genIdent()
continue; continue;
} }
#if 1 #if 1
/* Use deco that matches what it would be for a function parameter
*/
buf.writestring(ea->type->deco); buf.writestring(ea->type->deco);
#else #else
// Use type of parameter, not type of argument // Use type of parameter, not type of argument