Permalink
Browse files

Merge pull request #1505 from 9rnsr/refactor_tiargs

Refactor semanticTiargs() and fix Issue 9178 - UDA: getAttributes does not play well with tupleof
  • Loading branch information...
2 parents fe48f17 + e918af2 commit 9b734c5d9ff4440e6479a2b10c866e5f1d837fab @WalterBright WalterBright committed Jan 19, 2013
Showing with 73 additions and 67 deletions.
  1. +61 −67 src/template.c
  2. +12 −0 test/runnable/uda.d
View
@@ -5249,70 +5249,50 @@ void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int f
//printf("type %s\n", ta->toChars());
// It might really be an Expression or an Alias
ta->resolve(loc, sc, &ea, &ta, &sa);
- if (ea)
+ if (ea) goto Lexpr;
+ if (sa) goto Ldsym;
+ if (ta == NULL)
{
- ea = ea->semantic(sc);
- //printf("-> ea = %s %s\n", Token::toChars(ea->op), ea->toChars());
- /* This test is to skip substituting a const var with
- * its initializer. The problem is the initializer won't
- * match with an 'alias' parameter. Instead, do the
- * const substitution in TemplateValueParameter::matchArg().
- */
- if (flags & 1) // only used by __traits, must not interpret the args
- ea = ea->optimize(WANTvalue);
- else if (ea->op != TOKvar)
- ea = ea->ctfeInterpret();
- (*tiargs)[j] = ea;
- }
- else if (sa)
- {
- Ldsym:
- (*tiargs)[j] = sa;
- TupleDeclaration *d = sa->toAlias()->isTupleDeclaration();
- if (d)
- {
- size_t dim = d->objects->dim;
- tiargs->remove(j);
- tiargs->insert(j, d->objects);
- j--;
- }
+ assert(global.errors);
+ ta = Type::terror;
}
- else if (ta)
- {
- Ltype:
- if (ta->ty == Ttuple)
- { // Expand tuple
- TypeTuple *tt = (TypeTuple *)ta;
- size_t dim = tt->arguments->dim;
- tiargs->remove(j);
- if (dim)
- { tiargs->reserve(dim);
- for (size_t i = 0; i < dim; i++)
- { Parameter *arg = (*tt->arguments)[i];
- if (flags & 2 && arg->ident)
- tiargs->insert(j + i, arg);
- else
- tiargs->insert(j + i, arg->type);
- }
+
+ Ltype:
+ if (ta->ty == Ttuple)
+ { // Expand tuple
+ TypeTuple *tt = (TypeTuple *)ta;
+ size_t dim = tt->arguments->dim;
+ tiargs->remove(j);
+ if (dim)
+ { tiargs->reserve(dim);
+ for (size_t i = 0; i < dim; i++)
+ { Parameter *arg = (*tt->arguments)[i];
+ if (flags & 2 && arg->ident)
+ tiargs->insert(j + i, arg);
+ else
+ tiargs->insert(j + i, arg->type);
}
- j--;
}
- else
- (*tiargs)[j] = ta;
- }
- else
- {
- assert(global.errors);
- (*tiargs)[j] = Type::terror;
+ j--;
+ continue;
}
+ (*tiargs)[j] = ta;
}
else if (ea)
{
+ Lexpr:
//printf("+[%d] ea = %s %s\n", j, Token::toChars(ea->op), ea->toChars());
ea = ea->semantic(sc);
if (flags & 1) // only used by __traits, must not interpret the args
ea = ea->optimize(WANTvalue);
- else if (ea->op != TOKvar && ea->op != TOKtuple &&
+ else if (ea->op == TOKvar)
+ { /* This test is to skip substituting a const var with
+ * its initializer. The problem is the initializer won't
+ * match with an 'alias' parameter. Instead, do the
+ * const substitution in TemplateValueParameter::matchArg().
+ */
+ }
+ else if (ea->op != TOKtuple &&
ea->op != TOKimport && ea->op != TOKtype &&
ea->op != TOKfunction && ea->op != TOKerror &&
ea->op != TOKthis && ea->op != TOKsuper)
@@ -5323,7 +5303,21 @@ void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int f
ea = new ErrorExp();
}
//printf("-[%d] ea = %s %s\n", j, Token::toChars(ea->op), ea->toChars());
+ if (ea->op == TOKtuple)
+ { // Expand tuple
+ TupleExp *te = (TupleExp *)ea;
+ size_t dim = te->exps->dim;
+ tiargs->remove(j);
+ if (dim)
+ { tiargs->reserve(dim);
+ for (size_t i = 0; i < dim; i++)
+ tiargs->insert(j + i, (*te->exps)[i]);
+ }
+ j--;
+ continue;
+ }
(*tiargs)[j] = ea;
+
if (ea->op == TOKtype)
{ ta = ea->type;
goto Ltype;
@@ -5346,9 +5340,8 @@ void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int f
else if (fe->td)
{ /* If template argument is a template lambda,
* get template declaration itself. */
- ea = NULL;
- (*tiargs)[j] = sa = fe->td;
- goto Lsa;
+ sa = fe->td;
+ goto Ldsym;
}
}
if (ea->op == TOKdotvar)
@@ -5365,25 +5358,26 @@ void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int f
sa = ((DotTemplateExp *)ea)->td;
goto Ldsym;
}
- if (ea->op == TOKtuple)
+ }
+ else if (sa)
+ {
+ Ldsym:
+ TupleDeclaration *d = sa->toAlias()->isTupleDeclaration();
+ if (d)
{ // Expand tuple
- TupleExp *te = (TupleExp *)ea;
- size_t dim = te->exps->dim;
+ size_t dim = d->objects->dim;
tiargs->remove(j);
- if (dim)
- { tiargs->reserve(dim);
- for (size_t i = 0; i < dim; i++)
- tiargs->insert(j + i, (*te->exps)[i]);
- }
+ tiargs->insert(j, d->objects);
j--;
+ continue;
}
- }
- else if (sa)
- {
- Lsa:
+ (*tiargs)[j] = sa;
+
TemplateDeclaration *td = sa->isTemplateDeclaration();
if (td && !td->semanticRun && td->literal)
+ {
td->semantic(sc);
+ }
}
else if (isParameter(o))
{
View
@@ -251,6 +251,17 @@ void test12()
}
/************************************************/
+// 9178
+
+void test9178()
+{
+ static class Foo { @(1) int a; }
+
+ Foo foo = new Foo;
+ static assert(__traits(getAttributes, foo.tupleof[0])[0] == 1);
+}
+
+/************************************************/
int main()
{
@@ -266,6 +277,7 @@ int main()
test10();
test11();
test12();
+ test9178();
printf("Success\n");
return 0;

0 comments on commit 9b734c5

Please sign in to comment.