Skip to content

Commit 9be0e59

Browse files
committed
UDAs for function arguments
1 parent 08aaba0 commit 9be0e59

14 files changed

Lines changed: 215 additions & 69 deletions

File tree

src/arrayop.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ FuncDeclaration *buildArrayOp(Identifier *ident, BinExp *exp, Scope *sc, Loc loc
5454
Parameter *p = (*fparams)[0];
5555
// foreach (i; 0 .. p.length)
5656
Statement *s1 = new ForeachRangeStatement(Loc(), TOKforeach,
57-
new Parameter(0, NULL, Id::p, NULL),
57+
new Parameter(0, NULL, Id::p, NULL, NULL),
5858
new IntegerExp(Loc(), 0, Type::tsize_t),
5959
new ArrayLengthExp(Loc(), new IdentifierExp(Loc(), p->ident)),
6060
new ExpStatement(Loc(), loopbody),
@@ -425,7 +425,7 @@ Expression *buildArrayLoop(Expression *e, Parameters *fparams)
425425
void visit(Expression *e)
426426
{
427427
Identifier *id = Identifier::generateId("c", fparams->dim);
428-
Parameter *param = new Parameter(0, e->type, id, NULL);
428+
Parameter *param = new Parameter(0, e->type, id, NULL, NULL);
429429
fparams->shift(param);
430430
result = new IdentifierExp(Loc(), id);
431431
}
@@ -444,7 +444,7 @@ Expression *buildArrayLoop(Expression *e, Parameters *fparams)
444444
void visit(ArrayLiteralExp *e)
445445
{
446446
Identifier *id = Identifier::generateId("p", fparams->dim);
447-
Parameter *param = new Parameter(STCconst, e->type, id, NULL);
447+
Parameter *param = new Parameter(STCconst, e->type, id, NULL, NULL);
448448
fparams->shift(param);
449449
Expression *ie = new IdentifierExp(Loc(), id);
450450
Expressions *arguments = new Expressions();
@@ -456,7 +456,7 @@ Expression *buildArrayLoop(Expression *e, Parameters *fparams)
456456
void visit(SliceExp *e)
457457
{
458458
Identifier *id = Identifier::generateId("p", fparams->dim);
459-
Parameter *param = new Parameter(STCconst, e->type, id, NULL);
459+
Parameter *param = new Parameter(STCconst, e->type, id, NULL, NULL);
460460
fparams->shift(param);
461461
Expression *ie = new IdentifierExp(Loc(), id);
462462
Expressions *arguments = new Expressions();

src/clone.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ FuncDeclaration *buildOpAssign(StructDeclaration *sd, Scope *sc)
231231
}
232232

233233
Parameters *fparams = new Parameters;
234-
fparams->push(new Parameter(STCnodtor, sd->type, Id::p, NULL));
234+
fparams->push(new Parameter(STCnodtor, sd->type, Id::p, NULL, NULL));
235235
TypeFunction *tf = new TypeFunction(fparams, sd->handleType(), 0, LINKd, stc | STCref);
236236

237237
FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), Id::assign, stc, tf);
@@ -477,7 +477,7 @@ FuncDeclaration *buildXopEquals(StructDeclaration *sd, Scope *sc)
477477
/* const bool opEquals(ref const S s);
478478
*/
479479
Parameters *parameters = new Parameters;
480-
parameters->push(new Parameter(STCref | STCconst, sd->type, NULL, NULL));
480+
parameters->push(new Parameter(STCref | STCconst, sd->type, NULL, NULL, NULL));
481481
tfeqptr = new TypeFunction(parameters, Type::tbool, 0, LINKd);
482482
tfeqptr->mod = MODconst;
483483
tfeqptr = (TypeFunction *)tfeqptr->semantic(Loc(), &scx);
@@ -510,8 +510,8 @@ FuncDeclaration *buildXopEquals(StructDeclaration *sd, Scope *sc)
510510
Loc loc = Loc(); // loc is unnecessary so errors are gagged
511511

512512
Parameters *parameters = new Parameters;
513-
parameters->push(new Parameter(STCref | STCconst, sd->type, Id::p, NULL));
514-
parameters->push(new Parameter(STCref | STCconst, sd->type, Id::q, NULL));
513+
parameters->push(new Parameter(STCref | STCconst, sd->type, Id::p, NULL, NULL));
514+
parameters->push(new Parameter(STCref | STCconst, sd->type, Id::q, NULL, NULL));
515515
TypeFunction *tf = new TypeFunction(parameters, Type::tbool, 0, LINKd);
516516

517517
Identifier *id = Id::xopEquals;
@@ -562,7 +562,7 @@ FuncDeclaration *buildXopCmp(StructDeclaration *sd, Scope *sc)
562562
/* const int opCmp(ref const S s);
563563
*/
564564
Parameters *parameters = new Parameters;
565-
parameters->push(new Parameter(STCref | STCconst, sd->type, NULL, NULL));
565+
parameters->push(new Parameter(STCref | STCconst, sd->type, NULL, NULL, NULL));
566566
tfcmpptr = new TypeFunction(parameters, Type::tint32, 0, LINKd);
567567
tfcmpptr->mod = MODconst;
568568
tfcmpptr = (TypeFunction *)tfcmpptr->semantic(Loc(), &scx);
@@ -635,8 +635,8 @@ FuncDeclaration *buildXopCmp(StructDeclaration *sd, Scope *sc)
635635
Loc loc = Loc(); // loc is unnecessary so errors are gagged
636636

637637
Parameters *parameters = new Parameters;
638-
parameters->push(new Parameter(STCref | STCconst, sd->type, Id::p, NULL));
639-
parameters->push(new Parameter(STCref | STCconst, sd->type, Id::q, NULL));
638+
parameters->push(new Parameter(STCref | STCconst, sd->type, Id::p, NULL, NULL));
639+
parameters->push(new Parameter(STCref | STCconst, sd->type, Id::q, NULL, NULL));
640640
TypeFunction *tf = new TypeFunction(parameters, Type::tint32, 0, LINKd);
641641

642642
Identifier *id = Id::xopCmp;
@@ -748,7 +748,7 @@ FuncDeclaration *buildXtoHash(StructDeclaration *sd, Scope *sc)
748748
Loc loc = Loc(); // internal code should have no loc to prevent coverage
749749

750750
Parameters *parameters = new Parameters();
751-
parameters->push(new Parameter(STCref | STCconst, sd->type, Id::p, NULL));
751+
parameters->push(new Parameter(STCref | STCconst, sd->type, Id::p, NULL, NULL));
752752
TypeFunction *tf = new TypeFunction(parameters, Type::thash_t, 0, LINKd, STCnothrow | STCtrusted);
753753

754754
Identifier *id = Id::xtoHash;

src/declaration.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ Type *TupleDeclaration::getType()
243243
Identifier *id = new Identifier(name, TOKidentifier);
244244
Parameter *arg = new Parameter(STCin, t, id, NULL);
245245
#else
246-
Parameter *arg = new Parameter(0, t, NULL, NULL);
246+
Parameter *arg = new Parameter(0, t, NULL, NULL, NULL);
247247
#endif
248248
(*args)[i] = arg;
249249
if (!t->deco)

src/expression.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1917,7 +1917,7 @@ bool functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
19171917
args->setDim(arguments->dim - nparams);
19181918
for (size_t i = 0; i < arguments->dim - nparams; i++)
19191919
{
1920-
Parameter *arg = new Parameter(STCin, (*arguments)[nparams + i]->type, NULL, NULL);
1920+
Parameter *arg = new Parameter(STCin, (*arguments)[nparams + i]->type, NULL, NULL, NULL);
19211921
(*args)[i] = arg;
19221922
}
19231923

@@ -6295,7 +6295,7 @@ Expression *IsExp::semantic(Scope *sc)
62956295
for (size_t i = 0; i < cd->baseclasses->dim; i++)
62966296
{
62976297
BaseClass *b = (*cd->baseclasses)[i];
6298-
args->push(new Parameter(STCin, b->type, NULL, NULL));
6298+
args->push(new Parameter(STCin, b->type, NULL, NULL, NULL));
62996299
}
63006300
tded = new TypeTuple(args);
63016301
}
@@ -6343,8 +6343,9 @@ Expression *IsExp::semantic(Scope *sc)
63436343
arg->defaultArg->op == TOKerror)
63446344
return new ErrorExp();
63456345
args->push(new Parameter(arg->storageClass, arg->type,
6346-
(tok2 == TOKparameters) ? arg->ident : NULL,
6347-
(tok2 == TOKparameters) ? arg->defaultArg : NULL));
6346+
(tok2 == TOKparameters) ? arg->ident : NULL,
6347+
(tok2 == TOKparameters) ? arg->defaultArg : NULL,
6348+
arg->userAttribDecl));
63486349
}
63496350
tded = new TypeTuple(args);
63506351
break;

src/func.c

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,7 +1138,7 @@ void FuncDeclaration::semantic(Scope *sc)
11381138
Parameter *p = NULL;
11391139
if (outId)
11401140
{
1141-
p = new Parameter(STCref | STCconst, f->nextOf(), outId, NULL);
1141+
p = new Parameter(STCref | STCconst, f->nextOf(), outId, NULL, NULL);
11421142
fparams->push(p);
11431143
}
11441144
TypeFunction *tf = new TypeFunction(fparams, Type::tvoid, 0, LINKd);
@@ -1214,10 +1214,37 @@ void FuncDeclaration::semantic(Scope *sc)
12141214
genCmain(sc);
12151215

12161216
assert(type->ty != Terror || errors);
1217+
1218+
//semantic for parameters' UDAs
1219+
for (size_t i = 0; i < nparams; i++)
1220+
{
1221+
Parameter *param = Parameter::getNth(f->parameters, i);
1222+
if (param && param->userAttribDecl)
1223+
param->userAttribDecl->semantic(sc);
1224+
}
12171225
}
12181226

12191227
void FuncDeclaration::semantic2(Scope *sc)
12201228
{
1229+
#if 0
1230+
printf("FuncDeclaration::semantic2('%s')\n", toPrettyChars());
1231+
#endif
1232+
if (semanticRun >= PASSsemantic2)
1233+
return;
1234+
assert(semanticRun <= PASSsemantic2);
1235+
semanticRun = PASSsemantic2;
1236+
1237+
if (!type || type->ty != Tfunction) return;
1238+
TypeFunction *f = (TypeFunction *)type;
1239+
if (!f->parameters) return;
1240+
size_t nparams = Parameter::dim(f->parameters);
1241+
//semantic for parameters' UDAs
1242+
for (size_t i = 0; i < nparams; i++)
1243+
{
1244+
Parameter *param = Parameter::getNth(f->parameters, i);
1245+
if (param && param->userAttribDecl)
1246+
param->userAttribDecl->semantic2(sc);
1247+
}
12211248
}
12221249

12231250
// Do the semantic analysis on the internals of the function.
@@ -2188,10 +2215,22 @@ void FuncDeclaration::semantic3(Scope *sc)
21882215
* done by TemplateInstance::semantic.
21892216
* Otherwise, error gagging should be temporarily ungagged by functionSemantic3.
21902217
*/
2191-
semanticRun = PASSsemantic3done;
2192-
semantic3Errors = (global.errors != nerrors) || (fbody && fbody->isErrorStatement());
21932218
if (type->ty == Terror)
21942219
errors = true;
2220+
2221+
if (!errors)
2222+
{
2223+
assert(f);
2224+
size_t nparams = f->parameters ? Parameter::dim(f->parameters) : 0;
2225+
for (size_t i = 0; i < nparams; i++)
2226+
{
2227+
Parameter *param = Parameter::getNth(f->parameters, i);
2228+
if (param && param->userAttribDecl)
2229+
param->userAttribDecl->semantic3(sc);
2230+
}
2231+
}
2232+
semanticRun = PASSsemantic3done;
2233+
semantic3Errors = (global.errors != nerrors) || (fbody && fbody->isErrorStatement());
21952234
//printf("-FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", parent->toChars(), toChars(), sc, loc.toChars());
21962235
//fflush(stdout);
21972236
}

src/hdrgen.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2913,6 +2913,12 @@ class PrettyPrintVisitor : public Visitor
29132913

29142914
void visit(Parameter *p)
29152915
{
2916+
if (p->userAttribDecl)
2917+
{
2918+
buf->writestring("@(");
2919+
argsToBuffer(p->userAttribDecl->atts);
2920+
buf->writestring(") ");
2921+
}
29162922
if (p->storageClass & STCauto)
29172923
buf->writestring("auto ");
29182924

src/mtype.c

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,7 +1573,7 @@ Type *stripDefaultArgs(Type *t)
15731573
{
15741574
Parameter *p = (*params)[i];
15751575
Type *ta = stripDefaultArgs(p->type);
1576-
if (ta != p->type || p->defaultArg || p->ident)
1576+
if (ta != p->type || p->defaultArg || p->ident || p->userAttribDecl)
15771577
{
15781578
if (params == parameters)
15791579
{
@@ -1583,7 +1583,7 @@ Type *stripDefaultArgs(Type *t)
15831583
(*params)[j] = (*parameters)[j];
15841584
}
15851585
StorageClass stc = p->storageClass & (~STCauto); // issue 14656
1586-
(*params)[i] = new Parameter(stc, ta, NULL, NULL);
1586+
(*params)[i] = new Parameter(stc, ta, NULL, NULL, NULL);
15871587
}
15881588
}
15891589
}
@@ -2037,7 +2037,7 @@ Type *TypeFunction::substWildTo(unsigned)
20372037
continue;
20382038
if (params == parameters)
20392039
params = parameters->copy();
2040-
(*params)[i] = new Parameter(p->storageClass, t, NULL, NULL);
2040+
(*params)[i] = new Parameter(p->storageClass, t, NULL, NULL, NULL);
20412041
}
20422042
if (next == tret && params == parameters)
20432043
return this;
@@ -3706,7 +3706,7 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int f
37063706
Parameters *params = new Parameters;
37073707
Type *next = n->ty == Twchar ? Type::twchar : Type::tchar;
37083708
Type *arrty = next->arrayOf();
3709-
params->push(new Parameter(0, arrty, NULL, NULL));
3709+
params->push(new Parameter(0, arrty, NULL, NULL, NULL));
37103710
reverseFd[i] = FuncDeclaration::genCfunc(params, arrty, reverseName[i]);
37113711
}
37123712

@@ -3729,7 +3729,7 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int f
37293729
Parameters *params = new Parameters;
37303730
Type *next = n->ty == Twchar ? Type::twchar : Type::tchar;
37313731
Type *arrty = next->arrayOf();
3732-
params->push(new Parameter(0, arrty, NULL, NULL));
3732+
params->push(new Parameter(0, arrty, NULL, NULL, NULL));
37333733
sortFd[i] = FuncDeclaration::genCfunc(params, arrty, sortName[i]);
37343734
}
37353735

@@ -3754,8 +3754,8 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int f
37543754
if (!adReverse_fd)
37553755
{
37563756
Parameters *params = new Parameters;
3757-
params->push(new Parameter(0, Type::tvoid->arrayOf(), NULL, NULL));
3758-
params->push(new Parameter(0, Type::tsize_t, NULL, NULL));
3757+
params->push(new Parameter(0, Type::tvoid->arrayOf(), NULL, NULL, NULL));
3758+
params->push(new Parameter(0, Type::tsize_t, NULL, NULL, NULL));
37593759
adReverse_fd = FuncDeclaration::genCfunc(params, Type::tvoid->arrayOf(), Id::adReverse);
37603760
}
37613761
fd = adReverse_fd;
@@ -3778,8 +3778,8 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int f
37783778
if (!fd)
37793779
{
37803780
Parameters *params = new Parameters;
3781-
params->push(new Parameter(0, Type::tvoid->arrayOf(), NULL, NULL));
3782-
params->push(new Parameter(0, Type::dtypeinfo->type, NULL, NULL));
3781+
params->push(new Parameter(0, Type::tvoid->arrayOf(), NULL, NULL, NULL));
3782+
params->push(new Parameter(0, Type::dtypeinfo->type, NULL, NULL, NULL));
37833783
fd = FuncDeclaration::genCfunc(params, Type::tvoid->arrayOf(), "_adSort");
37843784
}
37853785
ec = new VarExp(Loc(), fd);
@@ -4785,7 +4785,7 @@ Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int
47854785
if (fd_aaLen == NULL)
47864786
{
47874787
Parameters *fparams = new Parameters();
4788-
fparams->push(new Parameter(STCin, this, NULL, NULL));
4788+
fparams->push(new Parameter(STCin, this, NULL, NULL, NULL));
47894789
fd_aaLen = FuncDeclaration::genCfunc(fparams, Type::tsize_t, Id::aaLen);
47904790
TypeFunction *tf = (TypeFunction *)fd_aaLen->type;
47914791
tf->purity = PUREconst;
@@ -5607,7 +5607,7 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
56075607
{
56085608
Parameter *narg = (*tt->arguments)[j];
56095609
(*newparams)[j] = new Parameter(narg->storageClass | fparam->storageClass,
5610-
narg->type, narg->ident, narg->defaultArg);
5610+
narg->type, narg->ident, narg->defaultArg, narg->userAttribDecl);
56115611
}
56125612
fparam->type = new TypeTuple(newparams);
56135613
}
@@ -8684,7 +8684,7 @@ TypeTuple::TypeTuple(Expressions *exps)
86848684
{ Expression *e = (*exps)[i];
86858685
if (e->type->ty == Ttuple)
86868686
e->error("cannot form tuple of tuples");
8687-
Parameter *arg = new Parameter(STCundefined, e->type, NULL, NULL);
8687+
Parameter *arg = new Parameter(STCundefined, e->type, NULL, NULL, NULL);
86888688
(*arguments)[i] = arg;
86898689
}
86908690
}
@@ -8710,15 +8710,15 @@ TypeTuple::TypeTuple(Type *t1)
87108710
: Type(Ttuple)
87118711
{
87128712
arguments = new Parameters();
8713-
arguments->push(new Parameter(0, t1, NULL, NULL));
8713+
arguments->push(new Parameter(0, t1, NULL, NULL, NULL));
87148714
}
87158715

87168716
TypeTuple::TypeTuple(Type *t1, Type *t2)
87178717
: Type(Ttuple)
87188718
{
87198719
arguments = new Parameters();
8720-
arguments->push(new Parameter(0, t1, NULL, NULL));
8721-
arguments->push(new Parameter(0, t2, NULL, NULL));
8720+
arguments->push(new Parameter(0, t1, NULL, NULL, NULL));
8721+
arguments->push(new Parameter(0, t2, NULL, NULL, NULL));
87228722
}
87238723

87248724
const char *TypeTuple::kind()
@@ -9015,25 +9015,27 @@ Expression *TypeNull::defaultInit(Loc loc) { return new NullExp(Loc(), Type::tnu
90159015

90169016
/***************************** Parameter *****************************/
90179017

9018-
Parameter::Parameter(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg)
9018+
Parameter::Parameter(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg, UserAttributeDeclaration *userAttribDecl)
90199019
{
90209020
this->type = type;
90219021
this->ident = ident;
90229022
this->storageClass = storageClass;
90239023
this->defaultArg = defaultArg;
9024+
this->userAttribDecl = userAttribDecl;
90249025
}
90259026

9026-
Parameter *Parameter::create(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg)
9027+
Parameter *Parameter::create(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg, UserAttributeDeclaration *userAttribDecl)
90279028
{
9028-
return new Parameter(storageClass, type, ident, defaultArg);
9029+
return new Parameter(storageClass, type, ident, defaultArg, userAttribDecl);
90299030
}
90309031

90319032
Parameter *Parameter::syntaxCopy()
90329033
{
90339034
return new Parameter(storageClass,
90349035
type ? type->syntaxCopy() : NULL,
90359036
ident,
9036-
defaultArg ? defaultArg->syntaxCopy() : NULL);
9037+
defaultArg ? defaultArg->syntaxCopy() : NULL,
9038+
userAttribDecl ? (UserAttributeDeclaration *)userAttribDecl->syntaxCopy(NULL) : NULL);
90379039
}
90389040

90399041
Parameters *Parameter::arraySyntaxCopy(Parameters *parameters)

src/mtype.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -911,9 +911,12 @@ class Parameter : public RootObject
911911
Type *type;
912912
Identifier *ident;
913913
Expression *defaultArg;
914+
UserAttributeDeclaration *userAttribDecl; // user defined attributes
914915

915-
Parameter(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg);
916-
static Parameter *create(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg);
916+
Parameter(StorageClass storageClass, Type *type, Identifier *ident,
917+
Expression *defaultArg, UserAttributeDeclaration *userAttribDecl);
918+
static Parameter *create(StorageClass storageClass, Type *type, Identifier *ident,
919+
Expression *defaultArg, UserAttributeDeclaration *userAttribDecl);
917920
Parameter *syntaxCopy();
918921
Type *isLazyArray();
919922
// kludge for template.isType()

0 commit comments

Comments
 (0)