Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 62 additions & 60 deletions src/dmd/traits.d
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module dmd.traits;

import core.stdc.stdio;
import core.stdc.string;

import dmd.aggregate;
import dmd.arraytypes;
import dmd.canthrow;
Expand Down Expand Up @@ -443,6 +444,51 @@ extern (C++) Expression semanticTraits(TraitsExp e, Scope* sc)
return new IntegerExp(e.loc, false, Type.tbool);
}

/**
Gets the function type from a given AST node
if the node is a function of some sort.

Params:
o = an AST node to check for a `TypeFunction`
fdp = optional pointer to a function declararion, to be set
if `o` is a function declarartion.

Returns:
a type node if `o` is a declaration of
a delegate, function, function-pointer
or a variable of the former. Otherwise, `null`.
*/
static TypeFunction toTypeFunction(RootObject o, FuncDeclaration* fdp = null)
Copy link
Contributor

@JinShil JinShil Jan 18, 2018

Choose a reason for hiding this comment

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

Continuing our discussion from Slack: I completely overlooked that this was a nested function. In that case, yes, please disregard my previous comments (Sorry!). But none of the other nested functions here are static. I suggest removing static.

Otherwise, what I was implying with my previous comments is that this is a utility function, and might be better as a private free function of the module. I'm not going to require it though. your call.

UPDATE: In summary, either remove the static (or justify it), or make the function a private free function in the module. I leave it up to you to decide.

Copy link
Contributor

Choose a reason for hiding this comment

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

UPDATE 2: OK, I just realized the outer function context is not required, so static seems to make sense. I'm good, now. Sorry to beat this horse so much.

{
auto s = getDsymbolWithoutExpCtx(o);
auto t = isType(o);
TypeFunction tf = null;

if (s)
{
auto fd = s.isFuncDeclaration();
if (fd)
{
t = fd.type;
if (fdp)
*fdp = fd;
}
else if (auto vd = s.isVarDeclaration())
t = vd.type;
}
if (t)
{
if (t.ty == Tfunction)
tf = cast(TypeFunction)t;
else if (t.ty == Tdelegate)
tf = cast(TypeFunction)t.nextOf();
else if (t.ty == Tpointer && t.nextOf().ty == Tfunction)
tf = cast(TypeFunction)t.nextOf();
}

return tf;
}

IntegerExp isX(T)(bool function(T) fp)
{
if (!dim)
Expand Down Expand Up @@ -982,26 +1028,8 @@ extern (C++) Expression semanticTraits(TraitsExp e, Scope* sc)
if (dim != 1)
return dimError(1);

auto o = (*e.args)[0];
auto s = getDsymbolWithoutExpCtx(o);
auto t = isType(o);
TypeFunction tf = null;
if (s)
{
if (auto fd = s.isFuncDeclaration())
t = fd.type;
else if (auto vd = s.isVarDeclaration())
t = vd.type;
}
if (t)
{
if (t.ty == Tfunction)
tf = cast(TypeFunction)t;
else if (t.ty == Tdelegate)
tf = cast(TypeFunction)t.nextOf();
else if (t.ty == Tpointer && t.nextOf().ty == Tfunction)
tf = cast(TypeFunction)t.nextOf();
}
TypeFunction tf = toTypeFunction((*e.args)[0]);

if (!tf)
{
e.error("first argument is not a function");
Expand Down Expand Up @@ -1032,27 +1060,18 @@ extern (C++) Expression semanticTraits(TraitsExp e, Scope* sc)
LINK link;
int varargs;
auto o = (*e.args)[0];
auto t = isType(o);
TypeFunction tf = null;
if (t)
{
if (t.ty == Tfunction)
tf = cast(TypeFunction)t;
else if (t.ty == Tdelegate)
tf = cast(TypeFunction)t.nextOf();
else if (t.ty == Tpointer && t.nextOf().ty == Tfunction)
tf = cast(TypeFunction)t.nextOf();
}

FuncDeclaration fd;
TypeFunction tf = toTypeFunction(o, &fd);

if (tf)
{
link = tf.linkage;
varargs = tf.varargs;
}
else
{
auto s = getDsymbol(o);
FuncDeclaration fd;
if (!s || (fd = s.isFuncDeclaration()) is null)
if (!fd)
{
e.error("argument to `__traits(getFunctionVariadicStyle, %s)` is not a function", o.toChars());
return new ErrorExp();
Expand Down Expand Up @@ -1082,29 +1101,20 @@ extern (C++) Expression semanticTraits(TraitsExp e, Scope* sc)
if (dim != 2)
return dimError(2);

auto o1 = (*e.args)[1];
auto o = (*e.args)[0];
auto t = isType(o);
TypeFunction tf = null;
if (t)
{
if (t.ty == Tfunction)
tf = cast(TypeFunction)t;
else if (t.ty == Tdelegate)
tf = cast(TypeFunction)t.nextOf();
else if (t.ty == Tpointer && t.nextOf().ty == Tfunction)
tf = cast(TypeFunction)t.nextOf();
}
auto o1 = (*e.args)[1];

FuncDeclaration fd;
TypeFunction tf = toTypeFunction(o, &fd);

Parameters* fparams;
if (tf)
{
fparams = tf.parameters;
}
else
{
auto s = getDsymbol(o);
FuncDeclaration fd;
if (!s || (fd = s.isFuncDeclaration()) is null)
if (!fd)
{
e.error("first argument to `__traits(getParameterStorageClasses, %s, %s)` is not a function",
o.toChars(), o1.toChars());
Expand Down Expand Up @@ -1184,17 +1194,9 @@ extern (C++) Expression semanticTraits(TraitsExp e, Scope* sc)

LINK link;
auto o = (*e.args)[0];
auto t = isType(o);
TypeFunction tf = null;
if (t)
{
if (t.ty == Tfunction)
tf = cast(TypeFunction)t;
else if (t.ty == Tdelegate)
tf = cast(TypeFunction)t.nextOf();
else if (t.ty == Tpointer && t.nextOf().ty == Tfunction)
tf = cast(TypeFunction)t.nextOf();
}

TypeFunction tf = toTypeFunction(o);

if (tf)
link = tf.linkage;
else
Expand Down