@@ -14,6 +14,7 @@ module dmd.traits;
1414
1515import core.stdc.stdio ;
1616import core.stdc.string ;
17+
1718import dmd.aggregate;
1819import dmd.arraytypes;
1920import dmd.canthrow;
@@ -444,6 +445,52 @@ extern (C++) Expression semanticTraits(TraitsExp e, Scope* sc)
444445 return new IntegerExp(e.loc, false , Type.tbool);
445446 }
446447
448+ /**
449+ Gets a function type from a given AST node
450+ if the node is a function of some sort.
451+
452+ Params:
453+ o = an AST node to check for a `TypeFunction`
454+ fdp = optional pointer to a function declararion, to be set
455+ if `o` is a function declarartion.
456+
457+ Returns:
458+ a type node if `o` is a declaration of
459+ a delegate, function, function-pointer
460+ or a variable of the former. Otherwise, `null`.
461+ */
462+
463+ static TypeFunction traitsFuncArg (RootObject o, FuncDeclaration* fdp = null )
464+ {
465+ auto s = getDsymbolWithoutExpCtx(o);
466+ auto t = isType(o);
467+ TypeFunction tf = null ;
468+
469+ if (s)
470+ {
471+ auto fd = s.isFuncDeclaration();
472+ if (fd)
473+ {
474+ t = fd.type;
475+ if (fdp)
476+ * fdp = fd;
477+ }
478+ else if (auto vd = s.isVarDeclaration())
479+ t = vd.type;
480+ }
481+ if (t)
482+ {
483+ if (t.ty == Tfunction)
484+ tf = cast (TypeFunction)t;
485+ else if (t.ty == Tdelegate)
486+ tf = cast (TypeFunction)t.nextOf();
487+ else if (t.ty == Tpointer && t.nextOf().ty == Tfunction)
488+ tf = cast (TypeFunction)t.nextOf();
489+ }
490+
491+ return tf;
492+ }
493+
447494 Expression isX (T)(bool function (T) fp)
448495 {
449496 if (! dim)
@@ -978,26 +1025,8 @@ extern (C++) Expression semanticTraits(TraitsExp e, Scope* sc)
9781025 if (dim != 1 )
9791026 return dimError (1 );
9801027
981- auto o = (* e.args)[0 ];
982- auto s = getDsymbolWithoutExpCtx(o);
983- auto t = isType(o);
984- TypeFunction tf = null ;
985- if (s)
986- {
987- if (auto fd = s.isFuncDeclaration())
988- t = fd.type;
989- else if (auto vd = s.isVarDeclaration())
990- t = vd.type;
991- }
992- if (t)
993- {
994- if (t.ty == Tfunction)
995- tf = cast (TypeFunction)t;
996- else if (t.ty == Tdelegate)
997- tf = cast (TypeFunction)t.nextOf();
998- else if (t.ty == Tpointer && t.nextOf().ty == Tfunction)
999- tf = cast (TypeFunction)t.nextOf();
1000- }
1028+ TypeFunction tf = traitsFuncArg((* e.args)[0 ]);
1029+
10011030 if (! tf)
10021031 {
10031032 e.error(" first argument is not a function" );
@@ -1028,27 +1057,18 @@ extern (C++) Expression semanticTraits(TraitsExp e, Scope* sc)
10281057 LINK link;
10291058 int varargs;
10301059 auto o = (* e.args)[0 ];
1031- auto t = isType(o);
1032- TypeFunction tf = null ;
1033- if (t)
1034- {
1035- if (t.ty == Tfunction)
1036- tf = cast (TypeFunction)t;
1037- else if (t.ty == Tdelegate)
1038- tf = cast (TypeFunction)t.nextOf();
1039- else if (t.ty == Tpointer && t.nextOf().ty == Tfunction)
1040- tf = cast (TypeFunction)t.nextOf();
1041- }
1060+
1061+ FuncDeclaration fd;
1062+ TypeFunction tf = traitsFuncArg(o, &fd);
1063+
10421064 if (tf)
10431065 {
10441066 link = tf.linkage;
10451067 varargs = tf.varargs;
10461068 }
10471069 else
10481070 {
1049- auto s = getDsymbol(o);
1050- FuncDeclaration fd;
1051- if (! s || (fd = s.isFuncDeclaration()) is null )
1071+ if (! fd)
10521072 {
10531073 e.error(" argument to `__traits(getFunctionVariadicStyle, %s)` is not a function" , o.toChars());
10541074 return new ErrorExp();
@@ -1078,29 +1098,20 @@ extern (C++) Expression semanticTraits(TraitsExp e, Scope* sc)
10781098 if (dim != 2 )
10791099 return dimError (2 );
10801100
1081- auto o1 = (* e.args)[1 ];
10821101 auto o = (* e.args)[0 ];
1083- auto t = isType(o);
1084- TypeFunction tf = null ;
1085- if (t)
1086- {
1087- if (t.ty == Tfunction)
1088- tf = cast (TypeFunction)t;
1089- else if (t.ty == Tdelegate)
1090- tf = cast (TypeFunction)t.nextOf();
1091- else if (t.ty == Tpointer && t.nextOf().ty == Tfunction)
1092- tf = cast (TypeFunction)t.nextOf();
1093- }
1102+ auto o1 = (* e.args)[1 ];
1103+
1104+ FuncDeclaration fd;
1105+ TypeFunction tf = traitsFuncArg(o, &fd);
1106+
10941107 Parameters* fparams;
10951108 if (tf)
10961109 {
10971110 fparams = tf.parameters;
10981111 }
10991112 else
11001113 {
1101- auto s = getDsymbol(o);
1102- FuncDeclaration fd;
1103- if (! s || (fd = s.isFuncDeclaration()) is null )
1114+ if (! fd)
11041115 {
11051116 e.error(" first argument to `__traits(getParameterStorageClasses, %s, %s)` is not a function" ,
11061117 o.toChars(), o1.toChars());
@@ -1180,17 +1191,9 @@ extern (C++) Expression semanticTraits(TraitsExp e, Scope* sc)
11801191
11811192 LINK link;
11821193 auto o = (* e.args)[0 ];
1183- auto t = isType(o);
1184- TypeFunction tf = null ;
1185- if (t)
1186- {
1187- if (t.ty == Tfunction)
1188- tf = cast (TypeFunction)t;
1189- else if (t.ty == Tdelegate)
1190- tf = cast (TypeFunction)t.nextOf();
1191- else if (t.ty == Tpointer && t.nextOf().ty == Tfunction)
1192- tf = cast (TypeFunction)t.nextOf();
1193- }
1194+
1195+ TypeFunction tf = traitsFuncArg(o);
1196+
11941197 if (tf)
11951198 link = tf.linkage;
11961199 else
0 commit comments