Skip to content

Commit

Permalink
Merge pull request #4918 from 9rnsr/fix14889
Browse files Browse the repository at this point in the history
Issue 14889 & 14900 & [REG2.068.0] 14911 - Reimplement fix for issue 1215
  • Loading branch information
MartinNowak committed Aug 23, 2015
2 parents 2421415 + c1d8b52 commit 4cf5cf7
Show file tree
Hide file tree
Showing 11 changed files with 230 additions and 193 deletions.
5 changes: 5 additions & 0 deletions src/declaration.c
Expand Up @@ -381,6 +381,11 @@ void AliasDeclaration::semantic(Scope *sc)
* try to alias y to 3.
*/
s = type->toDsymbol(sc);
if (errors != global.errors)
{
s = NULL;
type = Type::terror;
}
if (s && s == this)
{
error("cannot resolve");
Expand Down
73 changes: 2 additions & 71 deletions src/dsymbol.c
Expand Up @@ -449,50 +449,12 @@ Dsymbol *Dsymbol::search_correct(Identifier *ident)
return (Dsymbol *)speller(ident->toChars(), &symbol_search_fp, (void *)this, idchars);
}

/*************************************
* Take an index in a TypeTuple.
*/
Dsymbol *Dsymbol::takeTypeTupleIndex(Loc loc, Scope *sc, Dsymbol *s, RootObject *id, Expression *indexExpr)
{
TupleDeclaration *td = s->isTupleDeclaration();
if (!td)
{
error(loc, "expected TypeTuple when indexing ('[%s]'), got '%s'.",
id->toChars(), s->toChars());
return NULL;
}
sc = sc->startCTFE();
indexExpr = indexExpr->semantic(sc);
sc = sc->endCTFE();

indexExpr = indexExpr->ctfeInterpret();
const uinteger_t d = indexExpr->toUInteger();

if (d >= td->objects->dim)
{
error(loc, "tuple index %llu exceeds length %u", d, td->objects->dim);
return NULL;
}
RootObject *o = (*td->objects)[(size_t)d];
if (o->dyncast() == DYNCAST_TYPE)
{
Type *t = (Type *)o;
return t->toDsymbol(sc)->toAlias();
}
else
{
assert(o->dyncast() == DYNCAST_DSYMBOL);
return (Dsymbol *)o;
}
}

/***************************************
* Search for identifier id as a member of 'this'.
* id may be a template instance.
* Returns:
* symbol found, NULL if not
*/

Dsymbol *Dsymbol::searchX(Loc loc, Scope *sc, RootObject *id)
{
//printf("Dsymbol::searchX(this=%p,%s, ident='%s')\n", this, toChars(), ident->toChars());
Expand All @@ -514,39 +476,6 @@ Dsymbol *Dsymbol::searchX(Loc loc, Scope *sc, RootObject *id)
sm = s->search(loc, (Identifier *)id);
break;

case DYNCAST_TYPE:
{
Type *index = (Type *)id;
Expression *expr = NULL;
Type *t = NULL;
Dsymbol *sym = NULL;

index->resolve(loc, sc, &expr, &t, &sym);
if (expr)
{
sm = takeTypeTupleIndex(loc, sc, s, id, expr);
}
else if (t)
{
index->error(loc, "expected an expression as index, got a type (%s)", t->toChars());
return NULL;
}
else
{
index->error(loc, "index is not an expression");
return NULL;
}
break;
}

case DYNCAST_EXPRESSION:
sm = takeTypeTupleIndex(loc, sc, s, id, (Expression *)id);
if (!sm)
{
return NULL;
}
break;

case DYNCAST_DSYMBOL:
{
// It's a template instance
Expand Down Expand Up @@ -579,6 +508,8 @@ Dsymbol *Dsymbol::searchX(Loc loc, Scope *sc, RootObject *id)
break;
}

case DYNCAST_TYPE:
case DYNCAST_EXPRESSION:
default:
assert(0);
}
Expand Down
3 changes: 0 additions & 3 deletions src/dsymbol.h
Expand Up @@ -275,9 +275,6 @@ class Dsymbol : public RootObject
virtual AttribDeclaration *isAttribDeclaration() { return NULL; }
virtual OverloadSet *isOverloadSet() { return NULL; }
virtual void accept(Visitor *v) { v->visit(this); }

private:
Dsymbol *takeTypeTupleIndex(Loc loc, Scope *sc, Dsymbol *s, RootObject *id, Expression *indexExpr);
};

// Dsymbol that generates a scope
Expand Down
219 changes: 124 additions & 95 deletions src/mtype.c
Expand Up @@ -6401,45 +6401,122 @@ d_uns64 TypeQualified::size(Loc loc)
}

/*************************************
* Resolve a TypeTuple index.
* Resolve a tuple index.
*/
bool TypeQualified::resolveTypeTupleIndex(Loc loc, Scope *sc, Dsymbol **s, Type **pt, Dsymbol **ps, RootObject *id, Expression *indexExpr)
void TypeQualified::resolveTupleIndex(Loc loc, Scope *sc, Dsymbol *s,
Expression **pe, Type **pt, Dsymbol **ps, RootObject *oindex)
{
TupleDeclaration *td = (*s)->isTupleDeclaration();
*pt = NULL;
*ps = NULL;
*pe = NULL;

TupleDeclaration *td = s->isTupleDeclaration();

Expression *eindex = isExpression(oindex);
Type *tindex = isType(oindex);
Dsymbol *sindex = isDsymbol(oindex);

if (!td)
{
error(loc, "expected TypeTuple when indexing ('[%s]'), got '%s'.",
id->toChars(), (*s)->toChars());
// It's really an index expression
if (tindex)
eindex = new TypeExp(loc, tindex);
else if (sindex)
eindex = new DsymbolExp(loc, sindex);
Expression *e = new IndexExp(loc, new DsymbolExp(loc, s), eindex);
e = e->semantic(sc);
if (e->op == TOKerror)
*pt = Type::terror;
else if (e->op == TOKtype)
*pt = ((TypeExp *)e)->type;
else
*pe = e;
return;
}

// Convert oindex to Expression, then try to resolve to constant.
if (tindex)
tindex->resolve(loc, sc, &eindex, &tindex, &sindex);
if (sindex)
eindex = new DsymbolExp(loc, sindex);
if (!eindex)
{
::error(loc, "index is %s not an expression", oindex->toChars());
*pt = Type::terror;
return false;
return;
}
sc = sc->startCTFE();
indexExpr = indexExpr->semantic(sc);
eindex = eindex->semantic(sc);
sc = sc->endCTFE();

indexExpr = indexExpr->ctfeInterpret();
const uinteger_t d = indexExpr->toUInteger();
eindex = eindex->ctfeInterpret();
if (eindex->op == TOKerror)
{
*pt = Type::terror;
return;
}

const uinteger_t d = eindex->toUInteger();
if (d >= td->objects->dim)
{
error(loc, "tuple index %llu exceeds length %u", d, td->objects->dim);
::error(loc, "tuple index %llu exceeds length %u", d, td->objects->dim);
*pt = Type::terror;
return false;
return;
}

RootObject *o = (*td->objects)[(size_t)d];
if (o->dyncast() == DYNCAST_TYPE)
*pt = isType(o);
*ps = isDsymbol(o);
*pe = isExpression(o);

if (*pt)
*pt = (*pt)->semantic(loc, sc);
}

void TypeQualified::resolveExprType(Loc loc, Scope *sc,
Expression *e, size_t i, Expression **pe, Type **pt)
{
//printf("resolveExprType(e = %s %s, type = %s)\n", Token::toChars(e->op), e->toChars(), e->type->toChars());

e = e->semantic(sc);

for (; i < idents.dim; i++)
{
*ps = NULL;
*pt = ((Type *)o)->addMod(this->mod);
*s = (*pt)->toDsymbol(sc)->toAlias();
if (e->op == TOKerror)
break;

RootObject *id = idents[i];
//printf("e: '%s', id: '%s', type = %s\n", e->toChars(), id->toChars(), e->type->toChars());
if (id->dyncast() == DYNCAST_IDENTIFIER)
{
DotIdExp *die = new DotIdExp(e->loc, e, (Identifier *)id);
e = die->semanticY(sc, 0);
}
else if (id->dyncast() == DYNCAST_TYPE) // Bugzilla 1215
{
e = new IndexExp(loc, e, new TypeExp(loc, (Type *)id));
e = e->semantic(sc);
}
else if (id->dyncast() == DYNCAST_EXPRESSION) // Bugzilla 1215
{
e = new IndexExp(loc, e, (Expression *)id);
e = e->semantic(sc);
}
else
{
assert(id->dyncast() == DYNCAST_DSYMBOL);
TemplateInstance *ti = ((Dsymbol *)id)->isTemplateInstance();
assert(ti);
DotTemplateInstanceExp *dte = new DotTemplateInstanceExp(e->loc, e, ti->name, ti->tiargs);
e = dte->semanticY(sc, 0);
}
}
if (e->op == TOKerror)
*pt = Type::terror;
else if (e->op == TOKtype)
*pt = e->type;
else
{
assert(o->dyncast() == DYNCAST_DSYMBOL);
*ps = (Dsymbol *)o;
*s = (*ps)->toAlias();
}
return true;
*pe = e;
}

/*************************************
Expand All @@ -6449,7 +6526,6 @@ bool TypeQualified::resolveTypeTupleIndex(Loc loc, Scope *sc, Dsymbol **s, Type
* if expression, *pe is set
* if type, *pt is set
*/

void TypeQualified::resolveHelper(Loc loc, Scope *sc,
Dsymbol *s, Dsymbol *scopesym,
Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
Expand All @@ -6471,43 +6547,26 @@ void TypeQualified::resolveHelper(Loc loc, Scope *sc,
for (size_t i = 0; i < idents.dim; i++)
{
RootObject *id = idents[i];
if (id->dyncast() == DYNCAST_EXPRESSION)

if (id->dyncast() == DYNCAST_EXPRESSION ||
id->dyncast() == DYNCAST_TYPE)
{
if (!resolveTypeTupleIndex(loc, sc, &s, pt, ps, id, (Expression *)id))
Type *tx;
Expression *ex;
Dsymbol *sx;
resolveTupleIndex(loc, sc, s, &ex, &tx, &sx, id);
if (sx)
{
return;
s = sx->toAlias();
continue;
}
continue;
if (tx)
ex = new TypeExp(loc, tx);
assert(ex);
resolveExprType(loc, sc, ex, i + 1, pe, pt);
return;
}
else if (id->dyncast() == DYNCAST_TYPE)
{
Type *index = (Type *)id;
Expression *expr = NULL;
Type *t = NULL;
Dsymbol *sym = NULL;

index->resolve(loc, sc, &expr, &t, &sym);
if (expr)
{
if (!resolveTypeTupleIndex(loc, sc, &s, pt, ps, id, expr))
{
return;
}
}
else if (t)
{
index->error(loc, "Expected an expression as index, got a type (%s)", t->toChars());
*pt = Type::terror;
return;
}
else
{
index->error(loc, "index is not a an expression");
*pt = Type::terror;
return;
}
continue;
}
Type *t = s->getType(); // type symbol, type alias, or type tuple?
unsigned errorsave = global.errors;
Dsymbol *sm = s->searchX(loc, sc, id);
Expand Down Expand Up @@ -6562,31 +6621,9 @@ void TypeQualified::resolveHelper(Loc loc, Scope *sc,
e = new DsymbolExp(loc, s);
else
e = new VarExp(loc, s->isDeclaration());
e = e->semantic(sc);
for (; i < idents.dim; i++)
{
RootObject *id2 = idents[i];
//printf("e: '%s', id: '%s', type = %s\n", e->toChars(), id2->toChars(), e->type->toChars());
if (id2->dyncast() == DYNCAST_IDENTIFIER)
{
DotIdExp *die = new DotIdExp(e->loc, e, (Identifier *)id2);
e = die->semanticY(sc, 0);
}
else
{
assert(id2->dyncast() == DYNCAST_DSYMBOL);
TemplateInstance *ti = ((Dsymbol *)id2)->isTemplateInstance();
assert(ti);
DotTemplateInstanceExp *dte = new DotTemplateInstanceExp(e->loc, e, ti->name, ti->tiargs);
e = dte->semanticY(sc, 0);
}
}
if (e->op == TOKtype)
*pt = e->type;
else if (e->op == TOKerror)
*pt = Type::terror;
else
*pe = e;

resolveExprType(loc, sc, e, i, pe, pt);
return;
}
else
{
Expand Down Expand Up @@ -6812,23 +6849,15 @@ Dsymbol *TypeIdentifier::toDsymbol(Scope *sc)
//printf("TypeIdentifier::toDsymbol('%s')\n", toChars());
if (!sc)
return NULL;
//printf("ident = '%s'\n", ident->toChars());

Dsymbol *scopesym;
Dsymbol *s = sc->search(loc, ident, &scopesym);
if (s)
{
for (size_t i = 0; i < idents.dim; i++)
{
RootObject *id = idents[i];
s = s->searchX(loc, sc, id);
if (!s) // failed to find a symbol
{
//printf("\tdidn't find a symbol\n");
break;
}
}
}
Type *t;
Expression *e;
Dsymbol *s;

resolve(loc, sc, &e, &t, &s);
if (t && t->ty != Tident)
s = t->toDsymbol(sc);

return s;
}

Expand Down

0 comments on commit 4cf5cf7

Please sign in to comment.