mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
fixes #427 :: Upgrade to DMDFE 1.059+1.060 patch; thanks to SiegeLord
This commit is contained in:
14
dmd/cast.c
14
dmd/cast.c
@@ -100,7 +100,12 @@ fflush(stdout);
|
||||
|
||||
error("cannot implicitly convert expression (%s) of type %s to %s",
|
||||
toChars(), type->toChars(), t->toChars());
|
||||
return castTo(sc, t);
|
||||
return new ErrorExp();
|
||||
}
|
||||
|
||||
Expression *ErrorExp::implicitCastTo(Scope *sc, Type *t)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
@@ -746,6 +751,7 @@ Expression *StringExp::castTo(Scope *sc, Type *t)
|
||||
if (!committed && t->ty == Tpointer && t->nextOf()->ty == Tvoid)
|
||||
{
|
||||
error("cannot convert string literal to void*");
|
||||
return new ErrorExp();
|
||||
}
|
||||
|
||||
se = this;
|
||||
@@ -1115,11 +1121,11 @@ Expression *SymOffExp::castTo(Scope *sc, Type *t)
|
||||
}
|
||||
else if (f->needThis())
|
||||
{ error("no 'this' to create delegate for %s", f->toChars());
|
||||
e = new ErrorExp();
|
||||
return new ErrorExp();
|
||||
}
|
||||
else
|
||||
{ error("cannot cast from function pointer to delegate");
|
||||
e = new ErrorExp();
|
||||
return new ErrorExp();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1577,7 +1583,7 @@ Expression *Expression::integralPromotions(Scope *sc)
|
||||
{
|
||||
case Tvoid:
|
||||
error("void has no value");
|
||||
break;
|
||||
return new ErrorExp();
|
||||
|
||||
case Tint8:
|
||||
case Tuns8:
|
||||
|
||||
@@ -65,7 +65,7 @@ ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *basecla
|
||||
if (id)
|
||||
{ // Look for special class names
|
||||
|
||||
if (id == Id::__sizeof || id == Id::alignof || id == Id::mangleof)
|
||||
if (id == Id::__sizeof || id == Id::__xalignof || id == Id::mangleof)
|
||||
error("illegal class name");
|
||||
|
||||
// BUG: What if this is the wrong TypeInfo, i.e. it is nested?
|
||||
|
||||
@@ -891,6 +891,9 @@ void VarDeclaration::semantic(Scope *sc)
|
||||
else if (storage_class & STCtemplateparameter)
|
||||
{
|
||||
}
|
||||
else if (storage_class & STCctfe)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
AggregateDeclaration *aad = sc->anonAgg;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// Copyright (c) 1999-2010 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
@@ -974,6 +974,7 @@ struct UnitTestDeclaration : FuncDeclaration
|
||||
int addPreInvariant();
|
||||
int addPostInvariant();
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
void toJsonBuffer(OutBuffer *buf);
|
||||
|
||||
UnitTestDeclaration *isUnitTestDeclaration() { return this; }
|
||||
};
|
||||
|
||||
@@ -525,7 +525,7 @@ int Dsymbol::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
|
||||
}
|
||||
if (sd->isAggregateDeclaration() || sd->isEnumDeclaration())
|
||||
{
|
||||
if (ident == Id::__sizeof || ident == Id::alignof || ident == Id::mangleof)
|
||||
if (ident == Id::__sizeof || ident == Id::__xalignof || ident == Id::mangleof)
|
||||
error(".%s property cannot be redefined", ident->toChars());
|
||||
}
|
||||
return 1;
|
||||
|
||||
@@ -284,6 +284,7 @@ Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad,
|
||||
*/
|
||||
e1->error("this for %s needs to be type %s not type %s",
|
||||
var->toChars(), ad->toChars(), t->toChars());
|
||||
e1 = new ErrorExp();
|
||||
}
|
||||
}
|
||||
return e1;
|
||||
@@ -371,6 +372,7 @@ Expression *resolveProperties(Scope *sc, Expression *e)
|
||||
else if (e->op == TOKdotexp)
|
||||
{
|
||||
e->error("expression has no value");
|
||||
return new ErrorExp();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -386,17 +388,19 @@ Expression *resolveProperties(Scope *sc, Expression *e)
|
||||
* Perform semantic() on an array of Expressions.
|
||||
*/
|
||||
|
||||
void arrayExpressionSemantic(Expressions *exps, Scope *sc)
|
||||
Expressions *arrayExpressionSemantic(Expressions *exps, Scope *sc)
|
||||
{
|
||||
if (exps)
|
||||
{
|
||||
for (size_t i = 0; i < exps->dim; i++)
|
||||
{ Expression *e = (Expression *)exps->data[i];
|
||||
|
||||
e = e->semantic(sc);
|
||||
exps->data[i] = (void *)e;
|
||||
if (e)
|
||||
{ e = e->semantic(sc);
|
||||
exps->data[i] = (void *)e;
|
||||
}
|
||||
}
|
||||
}
|
||||
return exps;
|
||||
}
|
||||
|
||||
|
||||
@@ -497,6 +501,12 @@ Expressions *arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt
|
||||
#if DMDV2
|
||||
/* The type is determined by applying ?: to each pair.
|
||||
*/
|
||||
/* Still have a problem with:
|
||||
* ubyte[][] = [ cast(ubyte[])"hello", [1]];
|
||||
* which works if the array literal is initialized top down with the ubyte[][]
|
||||
* type, but fails with this function doing bottom up typing.
|
||||
*/
|
||||
//printf("arrayExpressionToCommonType()\n");
|
||||
IntegerExp integerexp(0);
|
||||
CondExp condexp(0, &integerexp, NULL, NULL);
|
||||
|
||||
@@ -524,7 +534,9 @@ Expressions *arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt
|
||||
condexp.semantic(sc);
|
||||
exps->data[j0] = (void *)condexp.e1;
|
||||
e = condexp.e2;
|
||||
t0 = e->type;
|
||||
j0 = i;
|
||||
e0 = e;
|
||||
t0 = e0->type;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -573,7 +585,7 @@ void preFunctionParameters(Loc loc, Scope *sc, Expressions *exps)
|
||||
printf("1: \n");
|
||||
#endif
|
||||
arg->error("%s is not an expression", arg->toChars());
|
||||
arg = new IntegerExp(arg->loc, 0, Type::tint32);
|
||||
arg = new ErrorExp();
|
||||
}
|
||||
|
||||
arg = resolveProperties(sc, arg);
|
||||
@@ -611,6 +623,7 @@ Expression *callCpCtor(Loc loc, Scope *sc, Expression *e)
|
||||
*/
|
||||
Identifier *idtmp = Lexer::uniqueId("__tmp");
|
||||
VarDeclaration *tmp = new VarDeclaration(loc, tb, idtmp, new ExpInitializer(0, e));
|
||||
tmp->storage_class |= STCctfe;
|
||||
Expression *ae = new DeclarationExp(loc, tmp);
|
||||
e = new CommaExp(loc, ae, new VarExp(loc, tmp));
|
||||
e = e->semantic(sc);
|
||||
@@ -630,8 +643,6 @@ Expression *callCpCtor(Loc loc, Scope *sc, Expression *e)
|
||||
|
||||
void functionParameters(Loc loc, Scope *sc, TypeFunction *tf, Expressions *arguments)
|
||||
{
|
||||
unsigned n;
|
||||
|
||||
//printf("functionParameters()\n");
|
||||
assert(arguments);
|
||||
size_t nargs = arguments ? arguments->dim : 0;
|
||||
@@ -640,7 +651,7 @@ void functionParameters(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argum
|
||||
if (nargs > nparams && tf->varargs == 0)
|
||||
error(loc, "expected %zu arguments, not %zu for non-variadic function type %s", nparams, nargs, tf->toChars());
|
||||
|
||||
n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams)
|
||||
unsigned n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams)
|
||||
|
||||
int done = 0;
|
||||
for (size_t i = 0; i < n; i++)
|
||||
@@ -667,14 +678,10 @@ void functionParameters(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argum
|
||||
return;
|
||||
}
|
||||
arg = p->defaultArg;
|
||||
arg = arg->inlineCopy(sc);
|
||||
#if DMDV2
|
||||
if (arg->op == TOKdefault)
|
||||
{ DefaultInitExp *de = (DefaultInitExp *)arg;
|
||||
arg = de->resolve(loc, sc);
|
||||
}
|
||||
else
|
||||
arg = arg->resolveLoc(loc, sc); // __FILE__ and __LINE__
|
||||
#endif
|
||||
arg = arg->copy();
|
||||
arguments->push(arg);
|
||||
nargs++;
|
||||
}
|
||||
@@ -2130,8 +2137,7 @@ Expression *IdentifierExp::semantic(Scope *sc)
|
||||
error("undefined identifier %s, did you mean %s %s?", ident->toChars(), s->kind(), s->toChars());
|
||||
else
|
||||
error("undefined identifier %s", ident->toChars());
|
||||
type = Type::terror;
|
||||
return this;
|
||||
return new ErrorExp();
|
||||
}
|
||||
|
||||
char *IdentifierExp::toChars()
|
||||
@@ -5694,12 +5700,11 @@ Expression *DotIdExp::semantic(Scope *sc)
|
||||
return e;
|
||||
}
|
||||
error("undefined identifier %s", toChars());
|
||||
type = Type::tvoid;
|
||||
return this;
|
||||
return new ErrorExp();
|
||||
}
|
||||
else if (e1->type->ty == Tpointer &&
|
||||
ident != Id::init && ident != Id::__sizeof &&
|
||||
ident != Id::alignof && ident != Id::offsetof &&
|
||||
ident != Id::__xalignof && ident != Id::offsetof &&
|
||||
ident != Id::mangleof && ident != Id::stringof)
|
||||
{ /* Rewrite:
|
||||
* p.ident
|
||||
|
||||
@@ -120,7 +120,7 @@ struct Expression : Object
|
||||
virtual void toMangleBuffer(OutBuffer *buf);
|
||||
virtual Expression *toLvalue(Scope *sc, Expression *e);
|
||||
virtual Expression *modifiableLvalue(Scope *sc, Expression *e);
|
||||
Expression *implicitCastTo(Scope *sc, Type *t);
|
||||
virtual Expression *implicitCastTo(Scope *sc, Type *t);
|
||||
virtual MATCH implicitConvTo(Type *t);
|
||||
virtual Expression *castTo(Scope *sc, Type *t);
|
||||
virtual void checkEscape();
|
||||
@@ -155,6 +155,7 @@ struct Expression : Object
|
||||
virtual int inlineCost(InlineCostState *ics);
|
||||
virtual Expression *doInline(InlineDoState *ids);
|
||||
virtual Expression *inlineScan(InlineScanState *iss);
|
||||
Expression *inlineCopy(Scope *sc);
|
||||
|
||||
// For operator overloading
|
||||
virtual int isCommutative();
|
||||
@@ -217,6 +218,7 @@ struct ErrorExp : IntegerExp
|
||||
{
|
||||
ErrorExp();
|
||||
|
||||
Expression *implicitCastTo(Scope *sc, Type *t);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
};
|
||||
|
||||
@@ -638,6 +640,18 @@ struct NewAnonClassExp : Expression
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
};
|
||||
|
||||
#if DMDV2
|
||||
struct SymbolExp : Expression
|
||||
{
|
||||
Declaration *var;
|
||||
int hasOverloads;
|
||||
|
||||
SymbolExp(Loc loc, enum TOK op, int size, Declaration *var, int hasOverloads);
|
||||
|
||||
elem *toElem(IRState *irs);
|
||||
};
|
||||
#endif
|
||||
|
||||
// Offset from symbol
|
||||
|
||||
struct SymOffExp : Expression
|
||||
|
||||
@@ -43,7 +43,7 @@ Msgtable msgtable[] =
|
||||
{ "init" },
|
||||
{ "size" },
|
||||
{ "__sizeof", "sizeof" },
|
||||
{ "alignof" },
|
||||
{ "__xalignof", "alignof" },
|
||||
{ "mangleof" },
|
||||
{ "stringof" },
|
||||
{ "tupleof" },
|
||||
|
||||
43
dmd/init.c
43
dmd/init.c
@@ -341,6 +341,7 @@ void ArrayInitializer::addInit(Expression *index, Initializer *value)
|
||||
Initializer *ArrayInitializer::semantic(Scope *sc, Type *t)
|
||||
{ unsigned i;
|
||||
unsigned length;
|
||||
const unsigned long amax = 0x80000000;
|
||||
|
||||
//printf("ArrayInitializer::semantic(%s)\n", t->toChars());
|
||||
if (sem) // if semantic() already run
|
||||
@@ -357,15 +358,13 @@ Initializer *ArrayInitializer::semantic(Scope *sc, Type *t)
|
||||
|
||||
default:
|
||||
error(loc, "cannot use array to initialize %s", type->toChars());
|
||||
return this;
|
||||
goto Lerr;
|
||||
}
|
||||
|
||||
length = 0;
|
||||
for (i = 0; i < index.dim; i++)
|
||||
{ Expression *idx;
|
||||
Initializer *val;
|
||||
|
||||
idx = (Expression *)index.data[i];
|
||||
{
|
||||
Expression *idx = (Expression *)index.data[i];
|
||||
if (idx)
|
||||
{ idx = idx->semantic(sc);
|
||||
idx = idx->optimize(WANTvalue | WANTinterpret);
|
||||
@@ -373,19 +372,35 @@ Initializer *ArrayInitializer::semantic(Scope *sc, Type *t)
|
||||
length = idx->toInteger();
|
||||
}
|
||||
|
||||
val = (Initializer *)value.data[i];
|
||||
val = val->semantic(sc, t->next);
|
||||
Initializer *val = (Initializer *)value.data[i];
|
||||
val = val->semantic(sc, t->nextOf());
|
||||
value.data[i] = (void *)val;
|
||||
length++;
|
||||
if (length == 0)
|
||||
error(loc, "array dimension overflow");
|
||||
{ error(loc, "array dimension overflow");
|
||||
goto Lerr;
|
||||
}
|
||||
if (length > dim)
|
||||
dim = length;
|
||||
}
|
||||
unsigned long amax = 0x80000000;
|
||||
if ((unsigned long) dim * t->next->size() >= amax)
|
||||
error(loc, "array dimension %u exceeds max of %ju", dim, amax / t->next->size());
|
||||
if (t->ty == Tsarray)
|
||||
{
|
||||
dinteger_t edim = ((TypeSArray *)t)->dim->toInteger();
|
||||
if (dim > edim)
|
||||
{
|
||||
error(loc, "array initializer has %u elements, but array length is %jd", dim, edim);
|
||||
goto Lerr;
|
||||
}
|
||||
}
|
||||
|
||||
if ((unsigned long) dim * t->nextOf()->size() >= amax)
|
||||
{ error(loc, "array dimension %u exceeds max of %ju", dim, amax / t->nextOf()->size());
|
||||
goto Lerr;
|
||||
}
|
||||
return this;
|
||||
|
||||
Lerr:
|
||||
return new ExpInitializer(loc, new ErrorExp());
|
||||
}
|
||||
|
||||
/********************************
|
||||
@@ -618,11 +633,11 @@ Initializer *ExpInitializer::semantic(Scope *sc, Type *t)
|
||||
// Look for the case of statically initializing an array
|
||||
// with a single member.
|
||||
if (tb->ty == Tsarray &&
|
||||
!tb->next->equals(exp->type->toBasetype()->next) &&
|
||||
exp->implicitConvTo(tb->next)
|
||||
!tb->nextOf()->equals(exp->type->toBasetype()->nextOf()) &&
|
||||
exp->implicitConvTo(tb->nextOf())
|
||||
)
|
||||
{
|
||||
t = tb->next;
|
||||
t = tb->nextOf();
|
||||
}
|
||||
|
||||
exp = exp->implicitCastTo(sc, t);
|
||||
|
||||
38
dmd/inline.c
38
dmd/inline.c
@@ -22,6 +22,7 @@
|
||||
#include "expression.h"
|
||||
#include "statement.h"
|
||||
#include "mtype.h"
|
||||
#include "scope.h"
|
||||
|
||||
/* ========== Compute cost of inlining =============== */
|
||||
|
||||
@@ -164,7 +165,10 @@ int VarExp::inlineCost(InlineCostState *ics)
|
||||
int ThisExp::inlineCost(InlineCostState *ics)
|
||||
{
|
||||
#if !IN_LLVM
|
||||
//printf("ThisExp::inlineCost() %s\n", toChars());
|
||||
FuncDeclaration *fd = ics->fd;
|
||||
if (!fd)
|
||||
return COST_MAX;
|
||||
if (!ics->hdrscan)
|
||||
if (fd->isNested() || !ics->hasthis)
|
||||
return COST_MAX;
|
||||
@@ -176,6 +180,8 @@ int SuperExp::inlineCost(InlineCostState *ics)
|
||||
{
|
||||
#if !IN_LLVM
|
||||
FuncDeclaration *fd = ics->fd;
|
||||
if (!fd)
|
||||
return COST_MAX;
|
||||
if (!ics->hdrscan)
|
||||
if (fd->isNested() || !ics->hasthis)
|
||||
return COST_MAX;
|
||||
@@ -205,6 +211,7 @@ int StructLiteralExp::inlineCost(InlineCostState *ics)
|
||||
|
||||
int FuncExp::inlineCost(InlineCostState *ics)
|
||||
{
|
||||
//printf("FuncExp::inlineCost()\n");
|
||||
// This breaks on LDC too, since nested functions have internal linkage
|
||||
// and thus can't be referenced from other objects.
|
||||
// Right now, this makes the function be output to the .obj file twice.
|
||||
@@ -470,10 +477,8 @@ Expressions *arrayExpressiondoInline(Expressions *a, InlineDoState *ids)
|
||||
{ Expression *e = (Expression *)a->data[i];
|
||||
|
||||
if (e)
|
||||
{
|
||||
e = e->doInline(ids);
|
||||
newa->data[i] = (void *)e;
|
||||
}
|
||||
newa->data[i] = (void *)e;
|
||||
}
|
||||
}
|
||||
return newa;
|
||||
@@ -1537,4 +1542,31 @@ Expression *FuncDeclaration::doInline(InlineScanState *iss, Expression *ethis, A
|
||||
}
|
||||
|
||||
|
||||
/****************************************************
|
||||
* Perform the "inline copying" of a default argument for a function parameter.
|
||||
*/
|
||||
|
||||
Expression *Expression::inlineCopy(Scope *sc)
|
||||
{
|
||||
#if 0
|
||||
/* See Bugzilla 2935 for explanation of why just a copy() is broken
|
||||
*/
|
||||
return copy();
|
||||
#else
|
||||
InlineCostState ics;
|
||||
|
||||
memset(&ics, 0, sizeof(ics));
|
||||
ics.hdrscan = 1; // so DeclarationExp:: will work on 'statics' which are not
|
||||
int cost = inlineCost(&ics);
|
||||
if (cost >= COST_MAX)
|
||||
{ error("cannot inline default argument %s", toChars());
|
||||
return new ErrorExp();
|
||||
}
|
||||
InlineDoState ids;
|
||||
memset(&ids, 0, sizeof(ids));
|
||||
ids.parent = sc->parent;
|
||||
Expression *e = doInline(&ids);
|
||||
return e;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -323,6 +323,7 @@ Expression *Statement::interpret(InterState *istate)
|
||||
printf("Statement::interpret()\n");
|
||||
#endif
|
||||
START()
|
||||
error("Statement %s cannot be interpreted at compile time", this->toChars());
|
||||
return EXP_CANT_INTERPRET;
|
||||
}
|
||||
|
||||
@@ -1032,6 +1033,68 @@ Expression *LabelStatement::interpret(InterState *istate)
|
||||
return statement ? statement->interpret(istate) : NULL;
|
||||
}
|
||||
|
||||
|
||||
Expression *TryCatchStatement::interpret(InterState *istate)
|
||||
{
|
||||
#if LOG
|
||||
printf("TryCatchStatement::interpret()\n");
|
||||
#endif
|
||||
START()
|
||||
error("try-catch statements are not yet supported in CTFE");
|
||||
return EXP_CANT_INTERPRET;
|
||||
}
|
||||
|
||||
|
||||
Expression *TryFinallyStatement::interpret(InterState *istate)
|
||||
{
|
||||
#if LOG
|
||||
printf("TryFinallyStatement::interpret()\n");
|
||||
#endif
|
||||
START()
|
||||
error("try-finally statements are not yet supported in CTFE");
|
||||
return EXP_CANT_INTERPRET;
|
||||
}
|
||||
|
||||
Expression *ThrowStatement::interpret(InterState *istate)
|
||||
{
|
||||
#if LOG
|
||||
printf("ThrowStatement::interpret()\n");
|
||||
#endif
|
||||
START()
|
||||
error("throw statements are not yet supported in CTFE");
|
||||
return EXP_CANT_INTERPRET;
|
||||
}
|
||||
|
||||
Expression *OnScopeStatement::interpret(InterState *istate)
|
||||
{
|
||||
#if LOG
|
||||
printf("OnScopeStatement::interpret()\n");
|
||||
#endif
|
||||
START()
|
||||
error("scope guard statements are not yet supported in CTFE");
|
||||
return EXP_CANT_INTERPRET;
|
||||
}
|
||||
|
||||
Expression *WithStatement::interpret(InterState *istate)
|
||||
{
|
||||
#if LOG
|
||||
printf("WithStatement::interpret()\n");
|
||||
#endif
|
||||
START()
|
||||
error("with statements are not yet supported in CTFE");
|
||||
return EXP_CANT_INTERPRET;
|
||||
}
|
||||
|
||||
Expression *AsmStatement::interpret(InterState *istate)
|
||||
{
|
||||
#if LOG
|
||||
printf("AsmStatement::interpret()\n");
|
||||
#endif
|
||||
START()
|
||||
error("asm statements cannot be interpreted at compile time");
|
||||
return EXP_CANT_INTERPRET;
|
||||
}
|
||||
|
||||
/******************************** Expression ***************************/
|
||||
|
||||
Expression *Expression::interpret(InterState *istate)
|
||||
@@ -1200,8 +1263,8 @@ Expression *getVarExp(Loc loc, InterState *istate, Declaration *d)
|
||||
e = v->init->toExpression();
|
||||
e = e->interpret(istate);
|
||||
}
|
||||
else // This should never happen
|
||||
e = v->type->defaultInitLiteral();
|
||||
else
|
||||
e = v->type->defaultInitLiteral(loc);
|
||||
}
|
||||
else
|
||||
{ e = v->value;
|
||||
@@ -2059,7 +2122,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, fp_t fp, int post)
|
||||
*/
|
||||
if (type->toBasetype()->ty == Tstruct && newval->op == TOKint64)
|
||||
{
|
||||
newval = type->defaultInitLiteral();
|
||||
newval = type->defaultInitLiteral(loc);
|
||||
}
|
||||
newval = Cast(type, type, newval);
|
||||
e = newval;
|
||||
|
||||
55
dmd/json.c
55
dmd/json.c
@@ -214,11 +214,17 @@ void AttribDeclaration::toJsonBuffer(OutBuffer *buf)
|
||||
|
||||
if (d)
|
||||
{
|
||||
size_t offset = buf->offset;
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = (Dsymbol *)d->data[i];
|
||||
//printf("AttribDeclaration::toJsonBuffer %s\n", s->toChars());
|
||||
if (offset != buf->offset)
|
||||
{ buf->writestring(",\n");
|
||||
offset = buf->offset;
|
||||
}
|
||||
s->toJsonBuffer(buf);
|
||||
}
|
||||
JsonRemoveComma(buf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,6 +246,7 @@ void StaticDtorDeclaration::toJsonBuffer(OutBuffer *buf) { }
|
||||
void ClassInfoDeclaration::toJsonBuffer(OutBuffer *buf) { }
|
||||
void ModuleInfoDeclaration::toJsonBuffer(OutBuffer *buf) { }
|
||||
void TypeInfoDeclaration::toJsonBuffer(OutBuffer *buf) { }
|
||||
void UnitTestDeclaration::toJsonBuffer(OutBuffer *buf) { }
|
||||
#if DMDV2
|
||||
void PostBlitDeclaration::toJsonBuffer(OutBuffer *buf) { }
|
||||
#endif
|
||||
@@ -307,19 +314,23 @@ void AggregateDeclaration::toJsonBuffer(OutBuffer *buf)
|
||||
}
|
||||
}
|
||||
|
||||
JsonString(buf, Pmembers);
|
||||
buf->writestring(" : [\n");
|
||||
size_t offset = buf->offset;
|
||||
for (int i = 0; i < members->dim; i++)
|
||||
{ Dsymbol *s = (Dsymbol *)members->data[i];
|
||||
if (offset != buf->offset)
|
||||
{ buf->writestring(",\n");
|
||||
offset = buf->offset;
|
||||
if (members)
|
||||
{
|
||||
JsonString(buf, Pmembers);
|
||||
buf->writestring(" : [\n");
|
||||
size_t offset = buf->offset;
|
||||
for (int i = 0; i < members->dim; i++)
|
||||
{ Dsymbol *s = (Dsymbol *)members->data[i];
|
||||
if (offset != buf->offset)
|
||||
{ buf->writestring(",\n");
|
||||
offset = buf->offset;
|
||||
}
|
||||
s->toJsonBuffer(buf);
|
||||
}
|
||||
s->toJsonBuffer(buf);
|
||||
JsonRemoveComma(buf);
|
||||
buf->writestring("]\n");
|
||||
}
|
||||
JsonRemoveComma(buf);
|
||||
buf->writestring("]\n");
|
||||
|
||||
buf->writestring("}\n");
|
||||
}
|
||||
@@ -386,19 +397,23 @@ void EnumDeclaration::toJsonBuffer(OutBuffer *buf)
|
||||
if (memtype)
|
||||
JsonProperty(buf, "base", memtype->toChars());
|
||||
|
||||
JsonString(buf, Pmembers);
|
||||
buf->writestring(" : [\n");
|
||||
size_t offset = buf->offset;
|
||||
for (int i = 0; i < members->dim; i++)
|
||||
{ Dsymbol *s = (Dsymbol *)members->data[i];
|
||||
if (offset != buf->offset)
|
||||
{ buf->writestring(",\n");
|
||||
offset = buf->offset;
|
||||
if (members)
|
||||
{
|
||||
JsonString(buf, Pmembers);
|
||||
buf->writestring(" : [\n");
|
||||
size_t offset = buf->offset;
|
||||
for (int i = 0; i < members->dim; i++)
|
||||
{ Dsymbol *s = (Dsymbol *)members->data[i];
|
||||
if (offset != buf->offset)
|
||||
{ buf->writestring(",\n");
|
||||
offset = buf->offset;
|
||||
}
|
||||
s->toJsonBuffer(buf);
|
||||
}
|
||||
s->toJsonBuffer(buf);
|
||||
JsonRemoveComma(buf);
|
||||
buf->writestring("]\n");
|
||||
}
|
||||
JsonRemoveComma(buf);
|
||||
buf->writestring("]\n");
|
||||
|
||||
buf->writestring("}\n");
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ Global::Global()
|
||||
|
||||
copyright = "Copyright (c) 1999-2010 by Digital Mars and Tomas Lindquist Olsen";
|
||||
written = "written by Walter Bright and Tomas Lindquist Olsen";
|
||||
version = "v1.058";
|
||||
version = "v1.060";
|
||||
ldc_version = LDC_REV;
|
||||
llvm_version = LLVM_REV_STR;
|
||||
global.structalign = 8;
|
||||
|
||||
@@ -647,7 +647,7 @@ Expression *Type::getProperty(Loc loc, Identifier *ident)
|
||||
error(loc, ".size property should be replaced with .sizeof");
|
||||
e = new ErrorExp();
|
||||
}
|
||||
else if (ident == Id::alignof)
|
||||
else if (ident == Id::__xalignof)
|
||||
{
|
||||
e = new IntegerExp(loc, alignsize(), Type::tsize_t);
|
||||
}
|
||||
|
||||
368
dmd/parse.c
368
dmd/parse.c
@@ -1,6 +1,6 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// Copyright (c) 1999-2010 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
@@ -122,9 +122,7 @@ Array *Parser::parseModule()
|
||||
|
||||
md = new ModuleDeclaration(a, id);
|
||||
|
||||
if (token.value != TOKsemicolon)
|
||||
error("';' expected following module declaration instead of %s", token.toChars());
|
||||
nextToken();
|
||||
check(TOKsemicolon, "module declaration");
|
||||
addComment(mod, comment);
|
||||
}
|
||||
}
|
||||
@@ -288,6 +286,7 @@ Array *Parser::parseDeclDefs(int once)
|
||||
case TOKtls: stc = STCtls; goto Lstc;
|
||||
case TOKgshared: stc = STCgshared; goto Lstc;
|
||||
//case TOKmanifest: stc = STCmanifest; goto Lstc;
|
||||
case TOKat: stc = parseAttribute(); goto Lstc;
|
||||
#endif
|
||||
|
||||
Lstc:
|
||||
@@ -453,9 +452,7 @@ Array *Parser::parseDeclDefs(int once)
|
||||
s = NULL;
|
||||
}
|
||||
nextToken();
|
||||
if (token.value != TOKsemicolon)
|
||||
error("semicolon expected");
|
||||
nextToken();
|
||||
check(TOKsemicolon, "debug declaration");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -476,9 +473,7 @@ Array *Parser::parseDeclDefs(int once)
|
||||
s = NULL;
|
||||
}
|
||||
nextToken();
|
||||
if (token.value != TOKsemicolon)
|
||||
error("semicolon expected");
|
||||
nextToken();
|
||||
check(TOKsemicolon, "version declaration");
|
||||
break;
|
||||
}
|
||||
condition = parseVersionCondition();
|
||||
@@ -600,7 +595,7 @@ StaticAssert *Parser::parseStaticAssert()
|
||||
msg = parseAssignExp();
|
||||
}
|
||||
check(TOKrparen);
|
||||
check(TOKsemicolon);
|
||||
check(TOKsemicolon, "static assert");
|
||||
return new StaticAssert(loc, exp, msg);
|
||||
}
|
||||
|
||||
@@ -781,20 +776,18 @@ Condition *Parser::parseStaticIfCondition()
|
||||
|
||||
/*****************************************
|
||||
* Parse a constructor definition:
|
||||
* this(arguments) { body }
|
||||
* this(parameters) { body }
|
||||
* Current token is 'this'.
|
||||
*/
|
||||
|
||||
Dsymbol *Parser::parseCtor()
|
||||
{
|
||||
CtorDeclaration *f;
|
||||
Parameters *arguments;
|
||||
int varargs;
|
||||
Loc loc = this->loc;
|
||||
|
||||
nextToken();
|
||||
arguments = parseParameters(&varargs);
|
||||
f = new CtorDeclaration(loc, 0, arguments, varargs);
|
||||
int varargs;
|
||||
Parameters *parameters = parseParameters(&varargs);
|
||||
CtorDeclaration *f = new CtorDeclaration(loc, 0, parameters, varargs);
|
||||
parseContracts(f);
|
||||
return f;
|
||||
}
|
||||
@@ -811,8 +804,8 @@ DtorDeclaration *Parser::parseDtor()
|
||||
Loc loc = this->loc;
|
||||
|
||||
nextToken();
|
||||
check(TOKthis);
|
||||
check(TOKlparen);
|
||||
check(TOKthis, "~");
|
||||
check(TOKlparen, "~this");
|
||||
check(TOKrparen);
|
||||
|
||||
f = new DtorDeclaration(loc, 0);
|
||||
@@ -828,18 +821,39 @@ DtorDeclaration *Parser::parseDtor()
|
||||
|
||||
StaticCtorDeclaration *Parser::parseStaticCtor()
|
||||
{
|
||||
StaticCtorDeclaration *f;
|
||||
Loc loc = this->loc;
|
||||
|
||||
nextToken();
|
||||
check(TOKlparen);
|
||||
check(TOKlparen, "static this");
|
||||
check(TOKrparen);
|
||||
|
||||
f = new StaticCtorDeclaration(loc, 0);
|
||||
StaticCtorDeclaration *f = new StaticCtorDeclaration(loc, 0);
|
||||
parseContracts(f);
|
||||
return f;
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
* Parse a shared static constructor definition:
|
||||
* shared static this() { body }
|
||||
* Current token is 'shared'.
|
||||
*/
|
||||
#if DMDV2
|
||||
SharedStaticCtorDeclaration *Parser::parseSharedStaticCtor()
|
||||
{
|
||||
Loc loc = this->loc;
|
||||
|
||||
nextToken();
|
||||
nextToken();
|
||||
nextToken();
|
||||
check(TOKlparen, "shared static this");
|
||||
check(TOKrparen);
|
||||
|
||||
SharedStaticCtorDeclaration *f = new SharedStaticCtorDeclaration(loc, 0);
|
||||
parseContracts(f);
|
||||
return f;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************
|
||||
* Parse a static destructor definition:
|
||||
* static ~this() { body }
|
||||
@@ -848,19 +862,41 @@ StaticCtorDeclaration *Parser::parseStaticCtor()
|
||||
|
||||
StaticDtorDeclaration *Parser::parseStaticDtor()
|
||||
{
|
||||
StaticDtorDeclaration *f;
|
||||
Loc loc = this->loc;
|
||||
|
||||
nextToken();
|
||||
check(TOKthis);
|
||||
check(TOKlparen);
|
||||
check(TOKthis, "~");
|
||||
check(TOKlparen, "~this");
|
||||
check(TOKrparen);
|
||||
|
||||
f = new StaticDtorDeclaration(loc, 0);
|
||||
StaticDtorDeclaration *f = new StaticDtorDeclaration(loc, 0);
|
||||
parseContracts(f);
|
||||
return f;
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
* Parse a shared static destructor definition:
|
||||
* shared static ~this() { body }
|
||||
* Current token is 'shared'.
|
||||
*/
|
||||
#if DMDV2
|
||||
SharedStaticDtorDeclaration *Parser::parseSharedStaticDtor()
|
||||
{
|
||||
Loc loc = this->loc;
|
||||
|
||||
nextToken();
|
||||
nextToken();
|
||||
nextToken();
|
||||
check(TOKthis, "shared static ~");
|
||||
check(TOKlparen, "shared static ~this");
|
||||
check(TOKrparen);
|
||||
|
||||
SharedStaticDtorDeclaration *f = new SharedStaticDtorDeclaration(loc, 0);
|
||||
parseContracts(f);
|
||||
return f;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************
|
||||
* Parse an invariant definition:
|
||||
* invariant() { body }
|
||||
@@ -957,7 +993,7 @@ Parameters *Parser::parseParameters(int *pvarargs)
|
||||
int varargs = 0;
|
||||
int hasdefault = 0;
|
||||
|
||||
check(TOKlparen);
|
||||
check(TOKlparen, "start of parameter list");
|
||||
while (1)
|
||||
{ Type *tb;
|
||||
Identifier *ai = NULL;
|
||||
@@ -1080,7 +1116,7 @@ EnumDeclaration *Parser::parseEnum()
|
||||
while (token.value != TOKrcurly)
|
||||
{
|
||||
if (token.value == TOKidentifier)
|
||||
{ EnumMember *em;
|
||||
{
|
||||
Expression *value;
|
||||
Identifier *ident;
|
||||
|
||||
@@ -1093,14 +1129,15 @@ EnumDeclaration *Parser::parseEnum()
|
||||
nextToken();
|
||||
value = parseAssignExp();
|
||||
}
|
||||
em = new EnumMember(loc, ident, value);
|
||||
EnumMember *em = new EnumMember(loc, ident, value);
|
||||
e->members->push(em);
|
||||
|
||||
if (token.value == TOKrcurly)
|
||||
;
|
||||
else
|
||||
{ addComment(em, comment);
|
||||
comment = NULL;
|
||||
check(TOKcomma);
|
||||
check(TOKcomma, "enum member");
|
||||
}
|
||||
addComment(em, comment);
|
||||
comment = token.blockComment;
|
||||
@@ -1129,6 +1166,7 @@ Dsymbol *Parser::parseAggregate()
|
||||
enum TOK tok;
|
||||
Identifier *id;
|
||||
TemplateParameters *tpl = NULL;
|
||||
Expression *constraint = NULL;
|
||||
|
||||
//printf("Parser::parseAggregate()\n");
|
||||
tok = token.value;
|
||||
@@ -1219,13 +1257,12 @@ Dsymbol *Parser::parseAggregate()
|
||||
}
|
||||
|
||||
if (tpl)
|
||||
{ Array *decldefs;
|
||||
TemplateDeclaration *tempdecl;
|
||||
{ // Wrap a template around the aggregate declaration
|
||||
|
||||
// Wrap a template around the aggregate declaration
|
||||
decldefs = new Array();
|
||||
Array *decldefs = new Array();
|
||||
decldefs->push(a);
|
||||
tempdecl = new TemplateDeclaration(loc, id, tpl, NULL, decldefs);
|
||||
TemplateDeclaration *tempdecl =
|
||||
new TemplateDeclaration(loc, id, tpl, constraint, decldefs);
|
||||
return tempdecl;
|
||||
}
|
||||
|
||||
@@ -1284,7 +1321,7 @@ Expression *Parser::parseConstraint()
|
||||
if (token.value == TOKif)
|
||||
{
|
||||
nextToken(); // skip over 'if'
|
||||
check(TOKlparen);
|
||||
check(TOKlparen, "if");
|
||||
e = parseExpression();
|
||||
check(TOKrparen);
|
||||
}
|
||||
@@ -1339,6 +1376,9 @@ Lerr:
|
||||
|
||||
/******************************************
|
||||
* Parse template parameter list.
|
||||
* Input:
|
||||
* flag 0: parsing "( list )"
|
||||
* 1: parsing non-empty "list )"
|
||||
*/
|
||||
|
||||
TemplateParameters *Parser::parseTemplateParameterList(int flag)
|
||||
@@ -1396,7 +1436,7 @@ TemplateParameters *Parser::parseTemplateParameterList(int flag)
|
||||
t->value == TOKcomma || t->value == TOKrparen)
|
||||
{ // TypeParameter
|
||||
if (token.value != TOKidentifier)
|
||||
{ error("Identifier expected for template parameter");
|
||||
{ error("identifier expected for template type parameter");
|
||||
goto Lerr;
|
||||
}
|
||||
tp_ident = token.ident;
|
||||
@@ -1514,7 +1554,7 @@ Dsymbol *Parser::parseMixin()
|
||||
exp = parseExpression();
|
||||
check(TOKrparen);
|
||||
tqual = new TypeTypeof(loc, exp);
|
||||
check(TOKdot);
|
||||
check(TOKdot, "typeof (expression)");
|
||||
}
|
||||
if (token.value != TOKidentifier)
|
||||
{
|
||||
@@ -1566,10 +1606,7 @@ Dsymbol *Parser::parseMixin()
|
||||
id = NULL;
|
||||
|
||||
tm = new TemplateMixin(loc, id, tqual, idents, tiargs);
|
||||
if (token.value != TOKsemicolon)
|
||||
error("';' expected after mixin");
|
||||
nextToken();
|
||||
|
||||
check(TOKsemicolon, "template mixin");
|
||||
return tm;
|
||||
}
|
||||
|
||||
@@ -1599,18 +1636,14 @@ Objects *Parser::parseTemplateArgumentList()
|
||||
// See if it is an Expression or a Type
|
||||
if (isDeclaration(&token, 0, TOKreserved, NULL))
|
||||
{ // Type
|
||||
Type *ta;
|
||||
|
||||
// Get TemplateArgument
|
||||
ta = parseBasicType();
|
||||
Type *ta = parseBasicType();
|
||||
ta = parseDeclarator(ta, NULL);
|
||||
tiargs->push(ta);
|
||||
}
|
||||
else
|
||||
{ // Expression
|
||||
Expression *ea;
|
||||
|
||||
ea = parseAssignExp();
|
||||
{ // Template argument is an expression
|
||||
Expression *ea = parseAssignExp();
|
||||
tiargs->push(ea);
|
||||
}
|
||||
if (token.value != TOKcomma)
|
||||
@@ -1655,7 +1688,7 @@ Import *Parser::parseImport(Array *decldefs, int isstatic)
|
||||
a->push(id);
|
||||
nextToken();
|
||||
if (token.value != TOKidentifier)
|
||||
{ error("Identifier expected following package");
|
||||
{ error("identifier expected following package");
|
||||
break;
|
||||
}
|
||||
id = token.ident;
|
||||
@@ -1673,14 +1706,13 @@ Import *Parser::parseImport(Array *decldefs, int isstatic)
|
||||
{
|
||||
do
|
||||
{ Identifier *name;
|
||||
Identifier *alias;
|
||||
|
||||
nextToken();
|
||||
if (token.value != TOKidentifier)
|
||||
{ error("Identifier expected following :");
|
||||
break;
|
||||
}
|
||||
alias = token.ident;
|
||||
Identifier *alias = token.ident;
|
||||
nextToken();
|
||||
if (token.value == TOKassign)
|
||||
{
|
||||
@@ -1708,8 +1740,7 @@ Import *Parser::parseImport(Array *decldefs, int isstatic)
|
||||
nextToken();
|
||||
else
|
||||
{
|
||||
error("';' expected");
|
||||
nextToken();
|
||||
check(TOKsemicolon, "import declaration");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -1734,6 +1765,17 @@ Type *Parser::parseType(Identifier **pident, TemplateParameters **tpl)
|
||||
t = t->makeSharedConst();
|
||||
return t;
|
||||
}
|
||||
else if (token.value == TOKwild && peekNext() == TOKshared && peekNext2() != TOKlparen ||
|
||||
token.value == TOKshared && peekNext() == TOKwild && peekNext2() != TOKlparen)
|
||||
{
|
||||
nextToken();
|
||||
nextToken();
|
||||
/* shared wild type
|
||||
*/
|
||||
t = parseType(pident, tpl);
|
||||
t = t->makeSharedWild();
|
||||
return t;
|
||||
}
|
||||
else if (token.value == TOKconst && peekNext() != TOKlparen)
|
||||
{
|
||||
nextToken();
|
||||
@@ -1762,6 +1804,15 @@ Type *Parser::parseType(Identifier **pident, TemplateParameters **tpl)
|
||||
t = t->makeShared();
|
||||
return t;
|
||||
}
|
||||
else if (token.value == TOKwild && peekNext() != TOKlparen)
|
||||
{
|
||||
nextToken();
|
||||
/* wild type
|
||||
*/
|
||||
t = parseType(pident, tpl);
|
||||
t = t->makeWild();
|
||||
return t;
|
||||
}
|
||||
else
|
||||
t = parseBasicType();
|
||||
t = parseDeclarator(t, pident, tpl);
|
||||
@@ -1773,7 +1824,6 @@ Type *Parser::parseBasicType()
|
||||
{ Type *t;
|
||||
Identifier *id;
|
||||
TypeQualified *tid;
|
||||
TemplateInstance *tempinst;
|
||||
|
||||
//printf("parseBasicType()\n");
|
||||
switch (token.value)
|
||||
@@ -1786,9 +1836,9 @@ Type *Parser::parseBasicType()
|
||||
id = token.ident;
|
||||
nextToken();
|
||||
if (token.value == TOKnot)
|
||||
{
|
||||
{ // ident!(template_arguments)
|
||||
TemplateInstance *tempinst = new TemplateInstance(loc, id);
|
||||
nextToken();
|
||||
tempinst = new TemplateInstance(loc, id);
|
||||
tempinst->tiargs = parseTemplateArgumentList();
|
||||
tid = new TypeInstance(loc, tempinst);
|
||||
goto Lident2;
|
||||
@@ -1807,7 +1857,7 @@ Type *Parser::parseBasicType()
|
||||
if (token.value == TOKnot)
|
||||
{
|
||||
nextToken();
|
||||
tempinst = new TemplateInstance(loc, id);
|
||||
TemplateInstance *tempinst = new TemplateInstance(loc, id);
|
||||
tempinst->tiargs = parseTemplateArgumentList();
|
||||
tid->addIdent((Identifier *)tempinst);
|
||||
}
|
||||
@@ -1823,11 +1873,10 @@ Type *Parser::parseBasicType()
|
||||
goto Lident;
|
||||
|
||||
case TOKtypeof:
|
||||
{ Expression *exp;
|
||||
|
||||
{
|
||||
nextToken();
|
||||
check(TOKlparen);
|
||||
exp = parseExpression();
|
||||
Expression *exp = parseExpression();
|
||||
check(TOKrparen);
|
||||
tid = new TypeTypeof(loc, exp);
|
||||
goto Lident2;
|
||||
@@ -1880,10 +1929,9 @@ Type *Parser::parseBasicType2(Type *t)
|
||||
}
|
||||
else if (isDeclaration(&token, 0, TOKrbracket, NULL))
|
||||
{ // It's an associative array declaration
|
||||
Type *index;
|
||||
|
||||
//printf("it's an associative array\n");
|
||||
index = parseBasicType();
|
||||
Type *index = parseBasicType();
|
||||
index = parseDeclarator(index, NULL); // [ type ]
|
||||
t = new TypeAArray(t, index);
|
||||
check(TOKrbracket);
|
||||
@@ -1894,10 +1942,9 @@ Type *Parser::parseBasicType2(Type *t)
|
||||
inBrackets++;
|
||||
Expression *e = parseExpression(); // [ expression ]
|
||||
if (token.value == TOKslice)
|
||||
{ Expression *e2;
|
||||
|
||||
{
|
||||
nextToken();
|
||||
e2 = parseExpression(); // [ exp .. exp ]
|
||||
Expression *e2 = parseExpression(); // [ exp .. exp ]
|
||||
t = new TypeSlice(t, e, e2);
|
||||
}
|
||||
else
|
||||
@@ -1925,7 +1972,7 @@ Type *Parser::parseBasicType2(Type *t)
|
||||
|
||||
//printf("it's an associative array\n");
|
||||
index = parseBasicType();
|
||||
index = parseDeclarator(index, NULL); // [ type ]
|
||||
index = parseDeclarator(index, NULL); // [ type ]
|
||||
check(TOKrbracket);
|
||||
ta = new TypeAArray(t, index);
|
||||
}
|
||||
@@ -2029,10 +2076,9 @@ Type *Parser::parseDeclarator(Type *t, Identifier **pident, TemplateParameters *
|
||||
}
|
||||
else if (isDeclaration(&token, 0, TOKrbracket, NULL))
|
||||
{ // It's an associative array declaration
|
||||
Type *index;
|
||||
|
||||
//printf("it's an associative array\n");
|
||||
index = parseBasicType();
|
||||
Type *index = parseBasicType();
|
||||
index = parseDeclarator(index, NULL); // [ type ]
|
||||
check(TOKrbracket);
|
||||
ta = new TypeAArray(t, index);
|
||||
@@ -2058,16 +2104,14 @@ Type *Parser::parseDeclarator(Type *t, Identifier **pident, TemplateParameters *
|
||||
}
|
||||
#endif
|
||||
case TOKlparen:
|
||||
{ Parameters *arguments;
|
||||
int varargs;
|
||||
|
||||
{
|
||||
if (tpl)
|
||||
{
|
||||
/* Look ahead to see if this is (...)(...),
|
||||
* i.e. a function template declaration
|
||||
*/
|
||||
if (peekPastParen(&token)->value == TOKlparen)
|
||||
{ // It's a function template declaration
|
||||
{
|
||||
//printf("function template declaration\n");
|
||||
|
||||
// Gather template parameter list
|
||||
@@ -2075,7 +2119,8 @@ Type *Parser::parseDeclarator(Type *t, Identifier **pident, TemplateParameters *
|
||||
}
|
||||
}
|
||||
|
||||
arguments = parseParameters(&varargs);
|
||||
int varargs;
|
||||
Parameters *arguments = parseParameters(&varargs);
|
||||
Type *ta = new TypeFunction(arguments, t, varargs, linkage);
|
||||
Type **pt;
|
||||
for (pt = &ts; *pt != t; pt = &(*pt)->next)
|
||||
@@ -2294,13 +2339,12 @@ Array *Parser::parseDeclarations()
|
||||
s = new LinkDeclaration(link, ax);
|
||||
}
|
||||
if (tpl) // it's a function template
|
||||
{ Array *decldefs;
|
||||
TemplateDeclaration *tempdecl;
|
||||
|
||||
{
|
||||
// Wrap a template around the aggregate declaration
|
||||
decldefs = new Array();
|
||||
Array *decldefs = new Array();
|
||||
decldefs->push(s);
|
||||
tempdecl = new TemplateDeclaration(loc, s->ident, tpl, NULL, decldefs);
|
||||
TemplateDeclaration *tempdecl =
|
||||
new TemplateDeclaration(loc, s->ident, tpl, NULL, decldefs);
|
||||
s = tempdecl;
|
||||
}
|
||||
addComment(s, comment);
|
||||
@@ -2338,7 +2382,7 @@ Array *Parser::parseDeclarations()
|
||||
continue;
|
||||
|
||||
default:
|
||||
error("semicolon expected, not '%s'", token.toChars());
|
||||
error("semicolon expected to close declaration, not '%s'", token.toChars());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2356,9 +2400,9 @@ Array *Parser::parseDeclarations()
|
||||
*/
|
||||
|
||||
#if DMDV2
|
||||
Array *Parser::parseAutoDeclarations(StorageClass storageClass, unsigned char *comment)
|
||||
Dsymbols *Parser::parseAutoDeclarations(StorageClass storageClass, unsigned char *comment)
|
||||
{
|
||||
Array *a = new Array;
|
||||
Dsymbols *a = new Dsymbols;
|
||||
|
||||
while (1)
|
||||
{
|
||||
@@ -2401,7 +2445,6 @@ Array *Parser::parseAutoDeclarations(StorageClass storageClass, unsigned char *c
|
||||
|
||||
void Parser::parseContracts(FuncDeclaration *f)
|
||||
{
|
||||
Type *tb;
|
||||
enum LINK linksave = linkage;
|
||||
|
||||
// The following is irrelevant, as it is overridden by sc->linkage in
|
||||
@@ -2444,7 +2487,7 @@ L1:
|
||||
check(TOKlparen);
|
||||
while (1)
|
||||
{
|
||||
tb = parseBasicType();
|
||||
Type *tb = parseBasicType();
|
||||
f->fthrows->push(tb);
|
||||
if (token.value == TOKcomma)
|
||||
{ nextToken();
|
||||
@@ -2468,7 +2511,7 @@ L1:
|
||||
nextToken();
|
||||
if (token.value != TOKlcurly)
|
||||
{
|
||||
check(TOKlparen);
|
||||
check(TOKlparen, "out");
|
||||
if (token.value != TOKidentifier)
|
||||
error("(identifier) following 'out' expected, not %s", token.toChars());
|
||||
f->outId = token.ident;
|
||||
@@ -2804,14 +2847,15 @@ Statement *Parser::parseStatement(int flags)
|
||||
case TOKis:
|
||||
case TOKlbracket:
|
||||
#if DMDV2
|
||||
case TOKtilde:
|
||||
case TOKnot:
|
||||
case TOKtraits:
|
||||
case TOKfile:
|
||||
case TOKline:
|
||||
#endif
|
||||
Lexp:
|
||||
{ Expression *exp;
|
||||
|
||||
exp = parseExpression();
|
||||
{
|
||||
Expression *exp = parseExpression();
|
||||
check(TOKsemicolon, "statement");
|
||||
s = new ExpStatement(loc, exp);
|
||||
break;
|
||||
@@ -2848,6 +2892,12 @@ Statement *Parser::parseStatement(int flags)
|
||||
#if DMDV2
|
||||
case TOKimmutable:
|
||||
case TOKshared:
|
||||
case TOKwild:
|
||||
case TOKnothrow:
|
||||
case TOKpure:
|
||||
case TOKtls:
|
||||
case TOKgshared:
|
||||
case TOKat:
|
||||
#endif
|
||||
// case TOKtypeof:
|
||||
Ldeclaration:
|
||||
@@ -2905,7 +2955,7 @@ Statement *Parser::parseStatement(int flags)
|
||||
check(TOKlparen, "mixin");
|
||||
Expression *e = parseAssignExp();
|
||||
check(TOKrparen);
|
||||
check(TOKsemicolon);
|
||||
check(TOKsemicolon, "mixin (string)");
|
||||
s = new CompileStatement(loc, e);
|
||||
break;
|
||||
}
|
||||
@@ -2935,7 +2985,7 @@ Statement *Parser::parseStatement(int flags)
|
||||
Statement *body;
|
||||
|
||||
nextToken();
|
||||
check(TOKlparen);
|
||||
check(TOKlparen, "while");
|
||||
condition = parseExpression();
|
||||
check(TOKrparen);
|
||||
body = parseStatement(PSscope);
|
||||
@@ -2956,8 +3006,8 @@ Statement *Parser::parseStatement(int flags)
|
||||
|
||||
nextToken();
|
||||
body = parseStatement(PSscope);
|
||||
check(TOKwhile);
|
||||
check(TOKlparen);
|
||||
check(TOKwhile, "statement");
|
||||
check(TOKlparen, "while");
|
||||
condition = parseExpression();
|
||||
check(TOKrparen);
|
||||
s = new DoStatement(loc, body, condition);
|
||||
@@ -2972,7 +3022,7 @@ Statement *Parser::parseStatement(int flags)
|
||||
Statement *body;
|
||||
|
||||
nextToken();
|
||||
check(TOKlparen);
|
||||
check(TOKlparen, "for");
|
||||
if (token.value == TOKsemicolon)
|
||||
{ init = NULL;
|
||||
nextToken();
|
||||
@@ -3009,16 +3059,15 @@ Statement *Parser::parseStatement(int flags)
|
||||
case TOKforeach_reverse:
|
||||
{
|
||||
enum TOK op = token.value;
|
||||
Parameters *arguments;
|
||||
|
||||
Statement *d;
|
||||
Statement *body;
|
||||
Expression *aggr;
|
||||
|
||||
nextToken();
|
||||
check(TOKlparen);
|
||||
check(TOKlparen, "foreach");
|
||||
|
||||
arguments = new Parameters();
|
||||
Parameters *arguments = new Parameters();
|
||||
|
||||
while (1)
|
||||
{
|
||||
@@ -3026,7 +3075,6 @@ Statement *Parser::parseStatement(int flags)
|
||||
Identifier *ai = NULL;
|
||||
Type *at;
|
||||
unsigned storageClass;
|
||||
Parameter *a;
|
||||
|
||||
storageClass = STCin;
|
||||
if (token.value == TOKinout || token.value == TOKref)
|
||||
@@ -3048,7 +3096,7 @@ Statement *Parser::parseStatement(int flags)
|
||||
if (!ai)
|
||||
error("no identifier for declarator %s", at->toChars());
|
||||
Larg:
|
||||
a = new Parameter(storageClass, at, ai, NULL);
|
||||
Parameter *a = new Parameter(storageClass, at, ai, NULL);
|
||||
arguments->push(a);
|
||||
if (token.value == TOKcomma)
|
||||
{ nextToken();
|
||||
@@ -3056,7 +3104,7 @@ Statement *Parser::parseStatement(int flags)
|
||||
}
|
||||
break;
|
||||
}
|
||||
check(TOKsemicolon);
|
||||
check(TOKsemicolon, "foreach statement");
|
||||
|
||||
aggr = parseExpression();
|
||||
check(TOKrparen);
|
||||
@@ -3072,7 +3120,7 @@ Statement *Parser::parseStatement(int flags)
|
||||
Statement *elsebody;
|
||||
|
||||
nextToken();
|
||||
check(TOKlparen);
|
||||
check(TOKlparen, "if");
|
||||
|
||||
if (token.value == TOKauto)
|
||||
{
|
||||
@@ -3140,9 +3188,9 @@ Statement *Parser::parseStatement(int flags)
|
||||
if (peek(&token)->value != TOKlparen)
|
||||
goto Ldeclaration; // scope used as storage class
|
||||
nextToken();
|
||||
check(TOKlparen);
|
||||
check(TOKlparen, "scope");
|
||||
if (token.value != TOKidentifier)
|
||||
{ error("scope identifier expected");
|
||||
{ error("scope (identifier) expected");
|
||||
goto Lerror;
|
||||
}
|
||||
else
|
||||
@@ -3213,14 +3261,12 @@ Statement *Parser::parseStatement(int flags)
|
||||
}
|
||||
|
||||
case TOKswitch:
|
||||
{ Expression *condition;
|
||||
Statement *body;
|
||||
|
||||
{
|
||||
nextToken();
|
||||
check(TOKlparen);
|
||||
condition = parseExpression();
|
||||
check(TOKlparen, "switch");
|
||||
Expression *condition = parseExpression();
|
||||
check(TOKrparen);
|
||||
body = parseStatement(PSscope);
|
||||
Statement *body = parseStatement(PSscope);
|
||||
s = new SwitchStatement(loc, condition, body);
|
||||
break;
|
||||
}
|
||||
@@ -3238,7 +3284,21 @@ Statement *Parser::parseStatement(int flags)
|
||||
if (token.value != TOKcomma)
|
||||
break;
|
||||
}
|
||||
check(TOKcolon);
|
||||
check(TOKcolon, "case expression");
|
||||
|
||||
#if DMDV2
|
||||
/* case exp: .. case last:
|
||||
*/
|
||||
if (token.value == TOKslice)
|
||||
{
|
||||
if (cases.dim > 1)
|
||||
error("only one case allowed for start of case range");
|
||||
nextToken();
|
||||
check(TOKcase, "..");
|
||||
last = parseAssignExp();
|
||||
check(TOKcolon, "case expression");
|
||||
}
|
||||
#endif
|
||||
|
||||
statements = new Statements();
|
||||
while (token.value != TOKcase &&
|
||||
@@ -3265,7 +3325,7 @@ Statement *Parser::parseStatement(int flags)
|
||||
Statements *statements;
|
||||
|
||||
nextToken();
|
||||
check(TOKcolon);
|
||||
check(TOKcolon, "default");
|
||||
|
||||
statements = new Statements();
|
||||
while (token.value != TOKcase &&
|
||||
@@ -3289,7 +3349,7 @@ Statement *Parser::parseStatement(int flags)
|
||||
exp = NULL;
|
||||
else
|
||||
exp = parseExpression();
|
||||
check(TOKsemicolon, "return statement");
|
||||
check(TOKsemicolon, "return expression");
|
||||
s = new ReturnStatement(loc, exp);
|
||||
break;
|
||||
}
|
||||
@@ -3381,7 +3441,7 @@ Statement *Parser::parseStatement(int flags)
|
||||
Statement *body;
|
||||
|
||||
nextToken();
|
||||
check(TOKlparen);
|
||||
check(TOKlparen, "with");
|
||||
exp = parseExpression();
|
||||
check(TOKrparen);
|
||||
body = parseStatement(PSscope);
|
||||
@@ -3412,7 +3472,7 @@ Statement *Parser::parseStatement(int flags)
|
||||
}
|
||||
else
|
||||
{
|
||||
check(TOKlparen);
|
||||
check(TOKlparen, "catch");
|
||||
t = parseBasicType();
|
||||
id = NULL;
|
||||
t = parseDeclarator(t, &id);
|
||||
@@ -3475,7 +3535,7 @@ Statement *Parser::parseStatement(int flags)
|
||||
// Defer parsing of AsmStatements until semantic processing.
|
||||
|
||||
nextToken();
|
||||
check(TOKlcurly);
|
||||
check(TOKlcurly, "asm");
|
||||
toklist = NULL;
|
||||
ptoklist = &toklist;
|
||||
label = NULL;
|
||||
@@ -3589,6 +3649,8 @@ void Parser::check(enum TOK value, const char *string)
|
||||
* needId 0 no identifier
|
||||
* 1 identifier optional
|
||||
* 2 must have identifier
|
||||
* Output:
|
||||
* if *pt is not NULL, it is set to the ending token, which would be endtok
|
||||
*/
|
||||
|
||||
int Parser::isDeclaration(Token *t, int needId, enum TOK endtok, Token **pt)
|
||||
@@ -3597,28 +3659,44 @@ int Parser::isDeclaration(Token *t, int needId, enum TOK endtok, Token **pt)
|
||||
int haveId = 0;
|
||||
|
||||
#if DMDV2
|
||||
if ((t->value == TOKconst || t->value == TOKinvariant) &&
|
||||
if ((t->value == TOKconst ||
|
||||
t->value == TOKinvariant ||
|
||||
t->value == TOKimmutable ||
|
||||
t->value == TOKwild ||
|
||||
t->value == TOKshared) &&
|
||||
peek(t)->value != TOKlparen)
|
||||
{ /* const type
|
||||
* invariant type
|
||||
* immutable type
|
||||
* shared type
|
||||
* wild type
|
||||
*/
|
||||
t = peek(t);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!isBasicType(&t))
|
||||
return FALSE;
|
||||
{
|
||||
goto Lisnot;
|
||||
}
|
||||
if (!isDeclarator(&t, &haveId, endtok))
|
||||
return FALSE;
|
||||
goto Lisnot;
|
||||
if ( needId == 1 ||
|
||||
(needId == 0 && !haveId) ||
|
||||
(needId == 2 && haveId))
|
||||
{ if (pt)
|
||||
*pt = t;
|
||||
return TRUE;
|
||||
goto Lis;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
goto Lisnot;
|
||||
|
||||
Lis:
|
||||
//printf("\tis declaration, t = %s\n", t->toChars());
|
||||
return TRUE;
|
||||
|
||||
Lisnot:
|
||||
//printf("\tis not declaration\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int Parser::isBasicType(Token **pt)
|
||||
@@ -3822,10 +3900,15 @@ int Parser::isDeclarator(Token **pt, int *haveId, enum TOK endtok)
|
||||
case TOKinvariant:
|
||||
case TOKimmutable:
|
||||
case TOKshared:
|
||||
case TOKwild:
|
||||
case TOKpure:
|
||||
case TOKnothrow:
|
||||
t = peek(t);
|
||||
continue;
|
||||
case TOKat:
|
||||
t = peek(t); // skip '@'
|
||||
t = peek(t); // skip identifier
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -4195,8 +4278,8 @@ Expression *Parser::parsePrimaryExp()
|
||||
|
||||
#if DMDV2
|
||||
case TOKfile:
|
||||
{ char *s = loc.filename ? loc.filename : mod->ident->toChars();
|
||||
e = new StringExp(loc, s, strlen(s), 0);
|
||||
{ const char *s = loc.filename ? loc.filename : mod->ident->toChars();
|
||||
e = new StringExp(loc, (char *)s, strlen(s), 0);
|
||||
nextToken();
|
||||
break;
|
||||
}
|
||||
@@ -4314,7 +4397,7 @@ Expression *Parser::parsePrimaryExp()
|
||||
Objects *args = NULL;
|
||||
|
||||
nextToken();
|
||||
check(TOKlparen);
|
||||
check(TOKlparen, "__traits");
|
||||
if (token.value != TOKidentifier)
|
||||
{ error("__traits(identifier, args...) expected");
|
||||
goto Lerr;
|
||||
@@ -4462,7 +4545,7 @@ Expression *Parser::parsePrimaryExp()
|
||||
values->push(e);
|
||||
if (token.value == TOKrbracket)
|
||||
break;
|
||||
check(TOKcomma);
|
||||
check(TOKcomma, "literal element");
|
||||
}
|
||||
}
|
||||
check(TOKrbracket);
|
||||
@@ -4615,7 +4698,7 @@ Expression *Parser::parsePostExp(Expression *e)
|
||||
arguments->push(arg);
|
||||
if (token.value == TOKrbracket)
|
||||
break;
|
||||
check(TOKcomma);
|
||||
check(TOKcomma, "array literal element");
|
||||
}
|
||||
}
|
||||
e = new ArrayExp(loc, e, arguments);
|
||||
@@ -4820,8 +4903,8 @@ Expression *Parser::parseMulExp()
|
||||
switch (token.value)
|
||||
{
|
||||
case TOKmul: nextToken(); e2 = parseUnaryExp(); e = new MulExp(loc,e,e2); continue;
|
||||
case TOKdiv: nextToken(); e2 = parseUnaryExp(); e = new DivExp(loc,e,e2); continue;
|
||||
case TOKmod: nextToken(); e2 = parseUnaryExp(); e = new ModExp(loc,e,e2); continue;
|
||||
case TOKdiv: nextToken(); e2 = parseUnaryExp(); e = new DivExp(loc,e,e2); continue;
|
||||
case TOKmod: nextToken(); e2 = parseUnaryExp(); e = new ModExp(loc,e,e2); continue;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -4904,6 +4987,20 @@ Expression *Parser::parseRelExp()
|
||||
e = new CmpExp(op, loc, e, e2);
|
||||
continue;
|
||||
|
||||
#if DMDV2
|
||||
case TOKnot: // could be !in
|
||||
if (peekNext() == TOKin)
|
||||
{
|
||||
nextToken();
|
||||
nextToken();
|
||||
e2 = parseShiftExp();
|
||||
e = new InExp(loc, e, e2);
|
||||
e = new NotExp(loc, e);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case TOKin:
|
||||
nextToken();
|
||||
e2 = parseShiftExp();
|
||||
@@ -4997,6 +5094,17 @@ Expression *Parser::parseCmpExp()
|
||||
case TOKnot:
|
||||
// Attempt to identify '!is'
|
||||
t = peek(&token);
|
||||
#if DMDV2
|
||||
if (t->value == TOKin)
|
||||
{
|
||||
nextToken();
|
||||
nextToken();
|
||||
e2 = parseShiftExp();
|
||||
e = new InExp(loc, e, e2);
|
||||
e = new NotExp(loc, e);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (t->value != TOKis)
|
||||
break;
|
||||
nextToken();
|
||||
@@ -5139,7 +5247,7 @@ Expression *Parser::parseCondExp()
|
||||
{
|
||||
nextToken();
|
||||
e1 = parseExpression();
|
||||
check(TOKcolon);
|
||||
check(TOKcolon, "condition ? expression");
|
||||
e2 = parseCondExp();
|
||||
e = new CondExp(loc, e, e1, e2);
|
||||
}
|
||||
@@ -5228,10 +5336,10 @@ Expressions *Parser::parseArguments()
|
||||
arguments->push(arg);
|
||||
if (token.value == endtok)
|
||||
break;
|
||||
check(TOKcomma);
|
||||
check(TOKcomma, "argument");
|
||||
}
|
||||
}
|
||||
check(endtok);
|
||||
check(endtok, "argument list");
|
||||
}
|
||||
return arguments;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ const char idchars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123
|
||||
*void*value returned by fp() for first possible correct spelling
|
||||
*/
|
||||
|
||||
void *speller(const char *seed, fp_speller_t fp, void *fparg, const char *charset)
|
||||
void *spellerX(const char *seed, fp_speller_t fp, void *fparg, const char *charset, int flag)
|
||||
{
|
||||
size_t seedlen = strlen(seed);
|
||||
if (!seedlen)
|
||||
@@ -36,7 +36,11 @@ void *speller(const char *seed, fp_speller_t fp, void *fparg, const char *charse
|
||||
for (int i = 0; i < seedlen; i++)
|
||||
{
|
||||
//printf("del buf = '%s'\n", buf);
|
||||
void *p = (*fp)(fparg, buf);
|
||||
void *p;
|
||||
if (flag)
|
||||
p = spellerX(buf, fp, fparg, charset, flag - 1);
|
||||
else
|
||||
p = (*fp)(fparg, buf);
|
||||
if (p)
|
||||
return p;
|
||||
|
||||
@@ -52,7 +56,11 @@ void *speller(const char *seed, fp_speller_t fp, void *fparg, const char *charse
|
||||
buf[i + 1] = seed[i];
|
||||
|
||||
//printf("tra buf = '%s'\n", buf);
|
||||
void *p = (*fp)(fparg, buf);
|
||||
void *p;
|
||||
if (flag)
|
||||
p = spellerX(buf, fp, fparg, charset, flag - 1);
|
||||
else
|
||||
p = (*fp)(fparg, buf);
|
||||
if (p)
|
||||
return p;
|
||||
|
||||
@@ -70,7 +78,11 @@ void *speller(const char *seed, fp_speller_t fp, void *fparg, const char *charse
|
||||
buf[i] = *s;
|
||||
|
||||
//printf("sub buf = '%s'\n", buf);
|
||||
void *p = (*fp)(fparg, buf);
|
||||
void *p;
|
||||
if (flag)
|
||||
p = spellerX(buf, fp, fparg, charset, flag - 1);
|
||||
else
|
||||
p = (*fp)(fparg, buf);
|
||||
if (p)
|
||||
return p;
|
||||
}
|
||||
@@ -86,7 +98,11 @@ void *speller(const char *seed, fp_speller_t fp, void *fparg, const char *charse
|
||||
buf[i] = *s;
|
||||
|
||||
//printf("ins buf = '%s'\n", buf);
|
||||
void *p = (*fp)(fparg, buf);
|
||||
void *p;
|
||||
if (flag)
|
||||
p = spellerX(buf, fp, fparg, charset, flag - 1);
|
||||
else
|
||||
p = (*fp)(fparg, buf);
|
||||
if (p)
|
||||
return p;
|
||||
}
|
||||
@@ -96,3 +112,54 @@ void *speller(const char *seed, fp_speller_t fp, void *fparg, const char *charse
|
||||
|
||||
return NULL;// didn't find any corrections
|
||||
}
|
||||
void *speller(const char *seed, fp_speller_t fp, void *fparg, const char *charset)
|
||||
{
|
||||
for (int distance = 0; distance < 2; distance++)
|
||||
{ void *p = spellerX(seed, fp, fparg, charset, distance);
|
||||
if (p)
|
||||
return p;
|
||||
}
|
||||
return NULL; // didn't find it
|
||||
}
|
||||
|
||||
|
||||
#if UNITTEST
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
void *speller_test(void *fparg, const char *s)
|
||||
{
|
||||
if (strcmp((char *)fparg, s) == 0)
|
||||
return fparg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void unittest_speller()
|
||||
{
|
||||
static const char *cases[][3] =
|
||||
{
|
||||
{ "hello", "hell", "y" },
|
||||
{ "hello", "abcd", "n" },
|
||||
{ "hello", "hel", "y" },
|
||||
{ "ehllo", "helol", "y" },
|
||||
{ "hello", "helxxlo", "y" },
|
||||
{ "hello", "ehlxxlo", "n" },
|
||||
{ "hello", "heaao", "y" },
|
||||
};
|
||||
//printf("unittest_speller()\n");
|
||||
void *p = speller("hello", &speller_test, (void *)"hell", idchars);
|
||||
assert(p != NULL);
|
||||
for (int i = 0; i < sizeof(cases)/sizeof(cases[0]); i++)
|
||||
{
|
||||
void *p = speller(cases[i][0], &speller_test, (void *)cases[i][1], idchars);
|
||||
if (p)
|
||||
assert(cases[i][2][0] == 'y');
|
||||
else
|
||||
assert(cases[i][2][0] == 'n');
|
||||
}
|
||||
//printf("unittest_speller() success\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -373,6 +373,7 @@ struct ForeachStatement : Statement
|
||||
ForeachStatement(Loc loc, enum TOK op, Parameters *arguments, Expression *aggr, Statement *body);
|
||||
Statement *syntaxCopy();
|
||||
Statement *semantic(Scope *sc);
|
||||
bool checkForArgTypes();
|
||||
int hasBreak();
|
||||
int hasContinue();
|
||||
int usesEH();
|
||||
@@ -714,6 +715,7 @@ struct WithStatement : Statement
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
int usesEH();
|
||||
int blockExit();
|
||||
Expression *interpret(InterState *istate);
|
||||
|
||||
Statement *inlineScan(InlineScanState *iss);
|
||||
|
||||
@@ -731,6 +733,7 @@ struct TryCatchStatement : Statement
|
||||
int hasBreak();
|
||||
int usesEH();
|
||||
int blockExit();
|
||||
Expression *interpret(InterState *istate);
|
||||
|
||||
Statement *inlineScan(InlineScanState *iss);
|
||||
|
||||
@@ -767,6 +770,7 @@ struct TryFinallyStatement : Statement
|
||||
int hasContinue();
|
||||
int usesEH();
|
||||
int blockExit();
|
||||
Expression *interpret(InterState *istate);
|
||||
|
||||
Statement *inlineScan(InlineScanState *iss);
|
||||
|
||||
@@ -785,6 +789,7 @@ struct OnScopeStatement : Statement
|
||||
Statement *semantic(Scope *sc);
|
||||
int usesEH();
|
||||
void scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally);
|
||||
Expression *interpret(InterState *istate);
|
||||
|
||||
void toIR(IRState *irs);
|
||||
};
|
||||
@@ -798,6 +803,7 @@ struct ThrowStatement : Statement
|
||||
Statement *semantic(Scope *sc);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
int blockExit();
|
||||
Expression *interpret(InterState *istate);
|
||||
|
||||
Statement *inlineScan(InlineScanState *iss);
|
||||
|
||||
@@ -889,6 +895,7 @@ struct AsmStatement : Statement
|
||||
Statement *semantic(Scope *sc);
|
||||
int blockExit();
|
||||
int comeFrom();
|
||||
Expression *interpret(InterState *istate);
|
||||
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
virtual AsmStatement *isAsmStatement() { return this; }
|
||||
|
||||
Reference in New Issue
Block a user