[Issue 12100] __GENTYPE to generate ever different types

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Sun Apr 10 09:45:21 PDT 2016


https://issues.dlang.org/show_bug.cgi?id=12100

--- Comment #14 from Simen Kjaeraas <simen.kjaras at gmail.com> ---
A bit of reasoning behind the choices made in the PR above:

(In reply to bearophile_hugs from comment #12)
> VC++ and GCC have "__COUNTER__"

__COUNTER__ breaks when used with separate compilation, as discussed above.
Also:

(In reply to bearophile_hugs from comment #6)
> I am asking for a integer that is incremented every time by 1, and that
> is exported as a range by every pre-compiled module to avoid duplications.

So... how do the other modules know about this range? One'd have to include the
other compiled modules on the command line when compiling one module, from what
I can see. If not, the compiler won't know of the used values, and chaos would
ensue.

For my PR, __GENSYM__ returns a string with a 'G' prefix*, followed by the
mangled name of the containing scope, followed by a scope-local counter:

module bar;
struct Ham(string gensym = __GENSYM__) {
    enum s = gensym;
    Eggs!() e;
}

struct Eggs(string gensym = __GENSYM__) {
    enum s = gensym;
}

module foo;
import bar;

struct S {
    static assert(__GENSYM__ == "G3foo1S1");
    static assert(__GENSYM__ == "G3foo1S2");
}

void baz() {
    static assert(__GENSYM__ == "G_D3foo3bazFZv1");
    static assert(__GENSYM__ == "G_D3foo3bazFZv2");
}

static assert(__GENSYM__ == "G3foo1");
static assert(__GENSYM__ == "G3foo2");

void main() {
    static assert(__GENSYM__ == "G_Dmain1");
    static assert(__GENSYM__ == "G_Dmain2");
    static assert(Ham!().s == "G_Dmain3");
    static assert(Ham!().s == "G_Dmain4");
    static assert(Ham!().e.s == "G3bar31__T3HamVAyaa8_475f446d61696e35Z3Ham1");
    static assert(Ham!().e.s == "G3bar31__T3HamVAyaa8_475f446d61696e36Z3Ham1");
// Note that this is not identical to the above (5Z3Ham1 vs 6Z3Ham1)
}

The mangled names should be fairly unique, and I don't think there's a case
where the order of instantiation would be different within a single scope, but
I'm prepared to be proven wrong on this.
So that should take care of separate compilation.

It's possible that this scheme can return values that are no valid identifiers
(if mangleof contains invalid characters). This is currently simply ignored.

* The 'G' prefix is used so that __GENSYM__ should return a valid identifier.
The exact character is once again chosen for LISP compatibility.

--


More information about the Digitalmars-d-bugs mailing list