Skip to content

Commit

Permalink
Merge pull request #6822 from WalterBright/fix17419
Browse files Browse the repository at this point in the history
fix Issue 17419 - add __traits(getLinkage, s) to the the linkage of s…
  • Loading branch information
andralex authored May 23, 2017
2 parents a9b92ac + f3dcdb4 commit 31a8770
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/ddmd/idgen.d
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ Msgtable[] msgtable =
{ "getAliasThis" },
{ "getAttributes" },
{ "getFunctionAttributes" },
{ "getLinkage" },
{ "getUnitTests" },
{ "getVirtualIndex" },
{ "getPointerBitmap" },
Expand Down
30 changes: 30 additions & 0 deletions src/ddmd/traits.d
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ static this()
"identifier",
"getProtection",
"parent",
"getLinkage",
"getMember",
"getOverloads",
"getVirtualFunctions",
Expand Down Expand Up @@ -910,6 +911,35 @@ extern (C++) Expression semanticTraits(TraitsExp e, Scope* sc)
auto tup = new TupleExp(e.loc, mods);
return tup.semantic(sc);
}
if (e.ident == Id.getLinkage)
{
// get symbol linkage as a string
if (dim != 1)
return dimError(1);

auto o = (*e.args)[0];
auto s = getDsymbol(o);
Declaration d;
if (!s || (d = s.isDeclaration()) is null)
{
e.error("argument to `__traits(getLinkage, %s)` is not a declaration", o.toChars());
return new ErrorExp();
}
string linkage;
switch (d.linkage)
{
case LINK.d: linkage = "D"; break;
case LINK.c: linkage = "C"; break;
case LINK.cpp: linkage = "C++"; break;
case LINK.windows: linkage = "Windows"; break;
case LINK.pascal: linkage = "Pascal"; break;
case LINK.objc: linkage = "Objective-C"; break;
case LINK.system: linkage = "System"; break;
default: assert(0);
}
auto se = new StringExp(e.loc, cast(char*)linkage.ptr);
return se.semantic(sc);
}
if (e.ident == Id.allMembers ||
e.ident == Id.derivedMembers)
{
Expand Down
29 changes: 29 additions & 0 deletions test/compilable/test17419.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// https://issues.dlang.org/show_bug.cgi?id=17419


extern (C) int fooc();
alias aliasc = fooc;

static assert(__traits(getLinkage, fooc) == "C");
static assert(__traits(getLinkage, aliasc) == "C");

extern (D) int food();
extern (C++) int foocpp();
extern (Windows) int foow();
extern (Pascal) int foop();
extern (Objective-C) int fooobjc();
extern (System) int foos();

static assert(__traits(getLinkage, food) == "D");
static assert(__traits(getLinkage, foocpp) == "C++");
static assert(__traits(getLinkage, foow) == "Windows");
static assert(__traits(getLinkage, foop) == "Pascal");
static assert(__traits(getLinkage, fooobjc) == "Objective-C");
version (Windows)
static assert(__traits(getLinkage, foos) == "Windows");
else
static assert(__traits(getLinkage, foos) == "C");

extern (C) int global;
static assert(__traits(getLinkage, global) == "C");

12 changes: 12 additions & 0 deletions test/fail_compilation/fail17419.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

// https://issues.dlang.org/show_bug.cgi?id=17419
/* TEST_OUTPUT:
---
fail_compilation/fail17419.d(10): Error: argument to `__traits(getLinkage, 64)` is not a declaration
fail_compilation/fail17419.d(11): Error: expected 1 arguments for `getLinkage` but had 2
---
*/

enum s = __traits(getLinkage, 8 * 8);
enum t = __traits(getLinkage, 8, 8);

0 comments on commit 31a8770

Please sign in to comment.