Skip to content

Commit

Permalink
partial merge of D2 pull 380
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Sep 14, 2011
1 parent 83123aa commit 31d6751
Show file tree
Hide file tree
Showing 15 changed files with 254 additions and 53 deletions.
15 changes: 8 additions & 7 deletions src/cond.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,13 +302,14 @@ int IftypeCondition::include(Scope *sc, ScopeDsymbol *sd)
inc = 2;
return 0;
}
unsigned errors = global.errors;
global.gag++; // suppress printing of error messages
targ = targ->semantic(loc, sc);
global.gag--;
if (errors != global.errors) // if any errors happened
{ inc = 2; // then condition is false
global.errors = errors;
Type *t = targ->trySemantic(loc, sc);
if (t)
targ = t;
else
inc = 2; // condition is false

if (!t)
{
}
else if (id && tspec)
{
Expand Down
19 changes: 11 additions & 8 deletions src/declaration.c
Original file line number Diff line number Diff line change
Expand Up @@ -1168,9 +1168,7 @@ void VarDeclaration::semantic(Scope *sc)

if (!global.errors && !inferred)
{
unsigned errors = global.errors;
global.gag++;
//printf("+gag\n");
unsigned errors = global.startGagging();
Expression *e;
Initializer *i2 = init;
inuse++;
Expand All @@ -1185,12 +1183,8 @@ void VarDeclaration::semantic(Scope *sc)
i2 = i2->semantic(sc, type, WANTinterpret);
}
inuse--;
global.gag--;
//printf("-gag\n");
if (errors != global.errors) // if errors happened
if (global.endGagging(errors)) // if errors happened
{
if (global.gag == 0)
global.errors = errors; // act as if nothing happened
#if DMDV2
/* Save scope for later use, to try again
*/
Expand Down Expand Up @@ -1461,6 +1455,15 @@ Expression *VarDeclaration::callScopeDtor(Scope *sc)
return e;
}

/******************************************
*/

void ObjectNotFound(Identifier *id)
{
Type::error(0, "%s not found. object.d may be incorrectly installed or corrupt.", id->toChars());
fatal();
}


/********************************* ClassInfoDeclaration ****************************/

Expand Down
10 changes: 10 additions & 0 deletions src/dsymbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,11 @@ void Dsymbol::error(const char *format, ...)

fprintf(stdmsg, "\n");
fflush(stdmsg);
//halt();
}
else
{
global.gaggedErrors++;
}
global.errors++;

Expand Down Expand Up @@ -577,6 +582,11 @@ void Dsymbol::error(Loc loc, const char *format, ...)

fprintf(stdmsg, "\n");
fflush(stdmsg);
//halt();
}
else
{
global.gaggedErrors++;
}

global.errors++;
Expand Down
71 changes: 66 additions & 5 deletions src/expression.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,23 @@ Expression *callCpCtor(Loc loc, Scope *sc, Expression *e)
}
#endif

// Check if this function is a member of a template which has only been
// instantiated speculatively, eg from inside is(typeof()).
// Return the speculative template instance it is part of,
// or NULL if not speculative.
TemplateInstance *isSpeculativeFunction(FuncDeclaration *fd)
{
Dsymbol * par = fd->parent;
while (par)
{
TemplateInstance *ti = par->isTemplateInstance();
if (ti && ti->speculative)
return ti;
par = par->toParent();
}
return NULL;
}

/****************************************
* Now that we know the exact type of the function we're calling,
* the arguments[] need to be adjusted:
Expand All @@ -528,6 +545,20 @@ 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());

#if DMDV2
// If inferring return type, and semantic3() needs to be run if not already run
if (!tf->next && fd->inferRetType)
{
TemplateInstance *spec = isSpeculativeFunction(fd);
int olderrs = global.errors;
fd->semantic3(fd->scope);
// Update the template instantiation with the number
// of errors which occured.
if (spec && global.errors != olderrs)
spec->errors = global.errors - olderrs;
}
#endif

unsigned n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams)

int done = 0;
Expand Down Expand Up @@ -915,6 +946,24 @@ Expression *Expression::semantic(Scope *sc)
return this;
}

/**********************************
* Try to run semantic routines.
* If they fail, return NULL.
*/

Expression *Expression::trySemantic(Scope *sc)
{
//printf("+trySemantic(%s)\n", toChars());
unsigned errors = global.startGagging();
Expression *e = semantic(sc);
if (global.endGagging(errors))
{
e = NULL;
}
//printf("-trySemantic(%s)\n", toChars());
return e;
}

void Expression::print()
{
fprintf(stdmsg, "%s\n", toChars());
Expand Down Expand Up @@ -2186,6 +2235,21 @@ Expression *DsymbolExp::semantic(Scope *sc)

if (!f->originalType && f->scope) // semantic not yet run
f->semantic(f->scope);

#if DMDV2
// if inferring return type, sematic3 needs to be run
if (f->inferRetType && f->scope && f->type && !f->type->nextOf())
{
TemplateInstance *spec = isSpeculativeFunction(f);
int olderrs = global.errors;
f->semantic3(f->scope);
// Update the template instantiation with the number
// of errors which occured.
if (spec && global.errors != olderrs)
spec->errors = global.errors - olderrs;
}
#endif

if (f->isUnitTestDeclaration())
{
error("cannot call unittest function %s", toChars());
Expand Down Expand Up @@ -5808,14 +5872,11 @@ Expression *DotIdExp::semantic(Scope *sc)
* as:
* .ident(e1)
*/
unsigned errors = global.errors;
global.gag++;
unsigned errors = global.startGagging();
Type *t1 = e1->type;
e = e1->type->dotExp(sc, e1, ident);
global.gag--;
if (errors != global.errors) // if failed to find the property
if (global.endGagging(errors)) // if failed to find the property
{
global.errors = errors;
e1->type = t1; // kludge to restore type
e = new DotIdExp(loc, new IdentifierExp(loc, Id::empty), ident);
e = new CallExp(loc, e, e1);
Expand Down
1 change: 1 addition & 0 deletions src/expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ struct Expression : Object
Expression *copy();
virtual Expression *syntaxCopy();
virtual Expression *semantic(Scope *sc);
Expression *trySemantic(Scope *sc);

int dyncast() { return DYNCAST_EXPRESSION; } // kludge for template.isExpression()

Expand Down
15 changes: 7 additions & 8 deletions src/func.c
Original file line number Diff line number Diff line change
Expand Up @@ -1161,15 +1161,14 @@ void FuncDeclaration::semantic3(Scope *sc)
Expression *e1 = new SuperExp(0);
Expression *e = new CallExp(0, e1);

unsigned errors = global.errors;
global.gag++;
e = e->semantic(sc2);
global.gag--;
if (errors != global.errors)
e = e->trySemantic(sc2);
if (!e)
error("no match for implicit super() call in constructor");

Statement *s = new ExpStatement(0, e);
fbody = new CompoundStatement(0, s, fbody);
else
{
Statement *s = new ExpStatement(0, e);
fbody = new CompoundStatement(0, s, fbody);
}
}
}
else if (fes)
Expand Down
20 changes: 19 additions & 1 deletion src/interpret.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
#include "id.h"
#include "utf.h"

#include "template.h"
TemplateInstance *isSpeculativeFunction(FuncDeclaration *fd);


#define LOG 0
#define LOGASSIGN 0

Expand Down Expand Up @@ -150,9 +154,23 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument

if (semanticRun < PASSsemantic3 && scope)
{
/* Forward reference - we need to run semantic3 on this function.
* If errors are gagged, and it's not part of a speculative
* template instance, we need to temporarily ungag errors.
*/
int olderrors = global.errors;
int oldgag = global.gag;
TemplateInstance *spec = isSpeculativeFunction(this);
if (global.gag && !spec)
global.gag = 0;
semantic3(scope);
if (olderrors != global.errors) // if errors compiling this function
global.gag = oldgag; // regag errors

// If it is a speculatively-instantiated template, and errors occur,
// we need to mark the template as having errors.
if (spec && global.errors != olderrors)
spec->errors = global.errors - olderrors;
if (olderrors != global.errors) // if errors compiling this function
return NULL;
}
if (semanticRun < PASSsemantic3done)
Expand Down
15 changes: 15 additions & 0 deletions src/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,10 @@ void Lexer::error(const char *format, ...)
if (global.errors >= 20) // moderate blizzard of cascading messages
fatal();
}
else
{
global.gaggedErrors++;
}
global.errors++;
}

Expand All @@ -341,6 +345,10 @@ void Lexer::error(Loc loc, const char *format, ...)
if (global.errors >= 20) // moderate blizzard of cascading messages
fatal();
}
else
{
global.gaggedErrors++;
}
global.errors++;
}

Expand Down Expand Up @@ -2261,6 +2269,7 @@ TOK Lexer::number(Token *t)
}

// Parse trailing 'u', 'U', 'l' or 'L' in any combination
const unsigned char *psuffix = p;
while (1)
{ unsigned char f;

Expand All @@ -2287,6 +2296,12 @@ TOK Lexer::number(Token *t)
break;
}

#if DMDV2
if (state == STATE_octal && n >= 8 && !global.params.useDeprecated)
error("octal literals 0%llo%.*s are deprecated, use std.conv.octal!%llo%.*s instead",
n, p - psuffix, psuffix, n, p - psuffix, psuffix);
#endif

switch (flags)
{
case 0:
Expand Down
33 changes: 33 additions & 0 deletions src/mars.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,35 @@ Global::Global()
memset(&params, 0, sizeof(Param));
}

unsigned Global::startGagging()
{
++gag;
#if DMDV1
return global.errors;
#else
return gaggedErrors;
#endif
}

bool Global::endGagging(unsigned oldGagged)
{
#if DMDV1
bool anyErrs = (errors != oldGagged);
--gag;
errors = oldGagged;
return anyErrs;
#else
bool anyErrs = (gaggedErrors != oldGagged);
--gag;
// Restore the original state of gagged errors; set total errors
// to be original errors + new ungagged errors.
errors -= (gaggedErrors - oldGagged);
gaggedErrors = oldGagged;
return anyErrs;
#endif
}


char *Loc::toChars()
{
OutBuffer buf;
Expand Down Expand Up @@ -177,6 +206,10 @@ void verror(Loc loc, const char *format, va_list ap)
fflush(stdmsg);
//halt();
}
else
{
global.gaggedErrors++;
}
global.errors++;
}

Expand Down
15 changes: 12 additions & 3 deletions src/mars.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,18 @@ struct Global
const char *version;

Param params;
unsigned errors; // number of errors reported so far
unsigned warnings; // number of warnings reported so far
unsigned gag; // !=0 means gag reporting of errors & warnings
unsigned errors; // number of errors reported so far
unsigned warnings; // number of warnings reported so far
unsigned gag; // !=0 means gag reporting of errors & warnings
unsigned gaggedErrors; // number of errors reported while gagged

// Start gagging. Return the current number of gagged errors
unsigned startGagging();

/* End gagging, restoring the old gagged state.
* Return true if errors occured while gagged.
*/
bool endGagging(unsigned oldGagged);

Global();
};
Expand Down
Loading

0 comments on commit 31d6751

Please sign in to comment.