1 // Compiler implementation of the D programming language
2 // Copyright (c) 1999-2015 by Digital Mars
3 // All Rights Reserved
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // Distributed under the Boost Software License, Version 1.0.
7 // http://www.boost.org/LICENSE_1_0.txt
8 
9 module ddmd.identifier;
10 
11 import core.stdc.stdio, core.stdc..string;
12 import ddmd.globals, ddmd.id, ddmd.root.outbuffer, ddmd.root.rootobject, ddmd.root.stringtable, ddmd.tokens;
13 
14 extern (C++) final class Identifier : RootObject
15 {
16 public:
17     int value;
18     const(char)* string;
19     size_t len;
20 
21     extern (D) this(const(char)* string, int value)
22     {
23         //printf("Identifier('%s', %d)\n", string, value);
24         this.string = string;
25         this.value = value;
26         this.len = strlen(string);
27     }
28 
29     static Identifier create(const(char)* string, int value)
30     {
31         return new Identifier(string, value);
32     }
33 
34     bool equals(RootObject o)
35     {
36         return this == o || strncmp(string, o.toChars(), len + 1) == 0;
37     }
38 
39     int compare(RootObject o)
40     {
41         return strncmp(string, o.toChars(), len + 1);
42     }
43 
44     void print()
45     {
46         fprintf(stderr, "%s", string);
47     }
48 
49     char* toChars()
50     {
51         return cast(char*)string;
52     }
53 
54     const(char)* toHChars2()
55     {
56         const(char)* p = null;
57         if (this == Id.ctor)
58             p = "this";
59         else if (this == Id.dtor)
60             p = "~this";
61         else if (this == Id.unitTest)
62             p = "unittest";
63         else if (this == Id.dollar)
64             p = "$";
65         else if (this == Id.withSym)
66             p = "with";
67         else if (this == Id.result)
68             p = "result";
69         else if (this == Id.returnLabel)
70             p = "return";
71         else
72         {
73             p = toChars();
74             if (*p == '_')
75             {
76                 if (strncmp(p, "_staticCtor", 11) == 0)
77                     p = "static this";
78                 else if (strncmp(p, "_staticDtor", 11) == 0)
79                     p = "static ~this";
80                 else if (strncmp(p, "__invariant", 11) == 0)
81                     p = "invariant";
82             }
83         }
84         return p;
85     }
86 
87     int dyncast()
88     {
89         return DYNCAST_IDENTIFIER;
90     }
91 
92     extern (C++) static __gshared StringTable stringtable;
93 
94     static Identifier generateId(const(char)* prefix)
95     {
96         static __gshared size_t i;
97         return generateId(prefix, ++i);
98     }
99 
100     static Identifier generateId(const(char)* prefix, size_t i)
101     {
102         OutBuffer buf;
103         buf.writestring(prefix);
104         buf.printf("%llu", cast(ulong)i);
105         char* id = buf.peekString();
106         return idPool(id);
107     }
108 
109     /********************************************
110      * Create an identifier in the string table.
111      */
112     static Identifier idPool(const(char)* s)
113     {
114         return idPool(s, strlen(s));
115     }
116 
117     static Identifier idPool(const(char)* s, size_t len)
118     {
119         StringValue* sv = stringtable.update(s, len);
120         Identifier id = cast(Identifier)sv.ptrvalue;
121         if (!id)
122         {
123             id = new Identifier(sv.toDchars(), TOKidentifier);
124             sv.ptrvalue = cast(char*)id;
125         }
126         return id;
127     }
128 
129     static Identifier lookup(const(char)* s, size_t len)
130     {
131         StringValue* sv = stringtable.lookup(s, len);
132         if (!sv)
133             return null;
134         return cast(Identifier)sv.ptrvalue;
135     }
136 
137     static void initTable()
138     {
139         stringtable._init(28000);
140     }
141 }