Skip to content

Commit

Permalink
enhance __traits(identifier) to pick the identifier out of a paramete…
Browse files Browse the repository at this point in the history
…r list tuple
  • Loading branch information
WalterBright committed Nov 4, 2012
1 parent f018414 commit b3b4940
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 10 deletions.
1 change: 1 addition & 0 deletions src/mars.h
Expand Up @@ -408,6 +408,7 @@ enum DYNCAST
DYNCAST_TYPE,
DYNCAST_IDENTIFIER,
DYNCAST_TUPLE,
DYNCAST_PARAMETER,
};

enum MATCH
Expand Down
1 change: 1 addition & 0 deletions src/mtype.h
Expand Up @@ -983,6 +983,7 @@ struct Parameter : Object
Parameter *syntaxCopy();
Type *isLazyArray();
void toDecoBuffer(OutBuffer *buf);
int dyncast() { return DYNCAST_PARAMETER; } // kludge for template.isType()
static Parameters *arraySyntaxCopy(Parameters *args);
static char *argsTypesToChars(Parameters *args, int varargs);
static void argsCppMangle(OutBuffer *buf, CppMangleState *cms, Parameters *arguments, int varargs);
Expand Down
22 changes: 20 additions & 2 deletions src/template.c
Expand Up @@ -79,6 +79,14 @@ Tuple *isTuple(Object *o)
return (Tuple *)o;
}

Parameter *isParameter(Object *o)
{
//return dynamic_cast<Parameter *>(o);
if (!o || o->dyncast() != DYNCAST_PARAMETER)
return NULL;
return (Parameter *)o;
}

/**************************************
* Is this Object an error?
*/
Expand Down Expand Up @@ -127,6 +135,9 @@ Type *getType(Object *o)

Dsymbol *getDsymbol(Object *oarg)
{
//printf("getDsymbol()\n");
//printf("e %p s %p t %p v %p\n", isExpression(oarg), isDsymbol(oarg), isType(oarg), isTuple(oarg));

Dsymbol *sa;
Expression *ea = isExpression(oarg);
if (ea)
Expand Down Expand Up @@ -5076,6 +5087,7 @@ void TemplateInstance::semanticTiargs(Scope *sc)
/**********************************
* Input:
* flags 1: replace const variables with their initializers
* 2: don't devolve Parameter to Type
*/

void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int flags)
Expand Down Expand Up @@ -5136,7 +5148,10 @@ void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int f
{ tiargs->reserve(dim);
for (size_t i = 0; i < dim; i++)
{ Parameter *arg = (*tt->arguments)[i];
tiargs->insert(j + i, arg->type);
if (flags & 2 && arg->ident)
tiargs->insert(j + i, arg);
else
tiargs->insert(j + i, arg->type);
}
}
j--;
Expand Down Expand Up @@ -5213,11 +5228,14 @@ void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int f
}
else if (sa)
{
Lsa:
Lsa:
TemplateDeclaration *td = sa->isTemplateDeclaration();
if (td && !td->semanticRun && td->literal)
td->semantic(sc);
}
else if (isParameter(o))
{
}
else
{
assert(0);
Expand Down
2 changes: 2 additions & 0 deletions src/template.h
Expand Up @@ -36,6 +36,7 @@ struct Expression;
struct AliasDeclaration;
struct FuncDeclaration;
struct HdrGenState;
struct Parameter;
enum MATCH;
enum PASS;

Expand Down Expand Up @@ -368,6 +369,7 @@ Expression *isExpression(Object *o);
Dsymbol *isDsymbol(Object *o);
Type *isType(Object *o);
Tuple *isTuple(Object *o);
Parameter *isParameter(Object *o);
int arrayObjectIsError(Objects *args);
int isError(Object *o);
Type *getType(Object *o);
Expand Down
28 changes: 20 additions & 8 deletions src/traits.c
Expand Up @@ -190,20 +190,32 @@ Expression *TraitsExp::semantic(Scope *sc)
else if (ident == Id::identifier)
{ // Get identifier for symbol as a string literal

// Specify 0 for the flags argument to semanticTiargs() so that
// a symbol should not be folded to a constant.
TemplateInstance::semanticTiargs(loc, sc, args, 0);
/* Specify 0 for bit 0 of the flags argument to semanticTiargs() so that
* a symbol should not be folded to a constant.
* Bit 1 means don't convert Parameter to Type if Parameter has an identifier
*/
TemplateInstance::semanticTiargs(loc, sc, args, 2);

if (dim != 1)
goto Ldimerror;
Object *o = (*args)[0];
Dsymbol *s = getDsymbol(o);
if (!s || !s->ident)
Parameter *po = isParameter(o);
Identifier *id;
if (po)
{ id = po->ident;
assert(id);
}
else
{
error("argument %s has no identifier", o->toChars());
goto Lfalse;
Dsymbol *s = getDsymbol(o);
if (!s || !s->ident)
{
error("argument %s has no identifier", o->toChars());
goto Lfalse;
}
id = s->ident;
}
StringExp *se = new StringExp(loc, s->ident->toChars());
StringExp *se = new StringExp(loc, id->toChars());
return se->semantic(sc);
}
else if (ident == Id::parent)
Expand Down

1 comment on commit b3b4940

@braddr
Copy link
Member

@braddr braddr commented on b3b4940 Nov 4, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unit tests? docs?

Please sign in to comment.