1 /**
2  * Contains the `Id` struct with a list of predefined symbols the compiler knows about.
3  *
4  * Copyright:   Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved
5  * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)
6  * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/id.d, _id.d)
8  * Documentation:  https://dlang.org/phobos/dmd_id.html
9  * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/id.d
10  */
11 
12 module dmd.id;
13 
14 import dmd.identifier;
15 import dmd.tokens;
16 
17 /**
18  * Represents a list of predefined symbols the compiler knows about.
19  *
20  * All static fields in this struct represents a specific predefined symbol.
21  */
22 extern (C++) struct Id
23 {
24     static __gshared:
25 
26     mixin(msgtable.generate(&identifier));
27 
28     /**
29      * Populates the identifier pool with all predefined symbols.
30      *
31      * An identifier that corresponds to each static field in this struct will
32      * be placed in the identifier pool.
33      */
34     extern(C++) void initialize()
35     {
36         mixin(msgtable.generate(&initializer));
37     }
38 
39     /**
40      * Deinitializes the global state of the compiler.
41      *
42      * This can be used to restore the state set by `initialize` to its original
43      * state.
44      */
45     extern (D) void deinitialize()
46     {
47         mixin(msgtable.generate(&deinitializer));
48     }
49 }
50 
51 private:
52 
53 
54 /**
55  * Each element in this array will generate one static field in the `Id` struct
56  * and a call to `Identifier.idPool` to populate the identifier pool in the
57  * `Id.initialize` method.
58  */
59 immutable Msgtable[] msgtable =
60 [
61     { "IUnknown" },
62     { "Object" },
63     { "object" },
64     { "string" },
65     { "wstring" },
66     { "dstring" },
67     { "max" },
68     { "min" },
69     { "This", "this" },
70     { "_super", "super" },
71     { "ctor", "__ctor" },
72     { "dtor", "__dtor" },
73     { "__xdtor", "__xdtor" },
74     { "__fieldDtor", "__fieldDtor" },
75     { "__aggrDtor", "__aggrDtor" },
76     { "cppdtor", "__cppdtor" },
77     { "ticppdtor", "__ticppdtor" },
78     { "postblit", "__postblit" },
79     { "__xpostblit", "__xpostblit" },
80     { "__fieldPostblit", "__fieldPostblit" },
81     { "__aggrPostblit", "__aggrPostblit" },
82     { "classInvariant", "__invariant" },
83     { "unitTest", "__unitTest" },
84     { "require", "__require" },
85     { "ensure", "__ensure" },
86     { "capture", "__capture" },
87     { "this2", "__this" },
88     { "_init", "init" },
89     { "__sizeof", "sizeof" },
90     { "__xalignof", "alignof" },
91     { "_mangleof", "mangleof" },
92     { "stringof" },
93     { "_tupleof", "tupleof" },
94     { "length" },
95     { "remove" },
96     { "ptr" },
97     { "array" },
98     { "funcptr" },
99     { "dollar", "__dollar" },
100     { "ctfe", "__ctfe" },
101     { "offset" },
102     { "offsetof" },
103     { "ModuleInfo" },
104     { "ClassInfo" },
105     { "classinfo" },
106     { "typeinfo" },
107     { "outer" },
108     { "Exception" },
109     { "RTInfo" },
110     { "Throwable" },
111     { "Error" },
112     { "withSym", "__withSym" },
113     { "result", "__result" },
114     { "returnLabel", "__returnLabel" },
115     { "line" },
116     { "empty", "" },
117     { "p" },
118     { "q" },
119     { "__vptr" },
120     { "__monitor" },
121     { "gate", "__gate" },
122     { "__c_long" },
123     { "__c_ulong" },
124     { "__c_longlong" },
125     { "__c_ulonglong" },
126     { "__c_long_double" },
127     { "__c_wchar_t" },
128     { "cpp_type_info_ptr", "__cpp_type_info_ptr" },
129     { "_assert", "assert" },
130     { "_unittest", "unittest" },
131     { "_body", "body" },
132     { "printf" },
133     { "scanf" },
134 
135     { "TypeInfo" },
136     { "TypeInfo_Class" },
137     { "TypeInfo_Interface" },
138     { "TypeInfo_Struct" },
139     { "TypeInfo_Enum" },
140     { "TypeInfo_Pointer" },
141     { "TypeInfo_Vector" },
142     { "TypeInfo_Array" },
143     { "TypeInfo_StaticArray" },
144     { "TypeInfo_AssociativeArray" },
145     { "TypeInfo_Function" },
146     { "TypeInfo_Delegate" },
147     { "TypeInfo_Tuple" },
148     { "TypeInfo_Const" },
149     { "TypeInfo_Invariant" },
150     { "TypeInfo_Shared" },
151     { "TypeInfo_Wild", "TypeInfo_Inout" },
152     { "elements" },
153     { "_arguments_typeinfo" },
154     { "_arguments" },
155     { "_argptr" },
156     { "destroy" },
157     { "xopEquals", "__xopEquals" },
158     { "xopCmp", "__xopCmp" },
159     { "xtoHash", "__xtoHash" },
160 
161     { "LINE", "__LINE__" },
162     { "FILE", "__FILE__" },
163     { "MODULE", "__MODULE__" },
164     { "FUNCTION", "__FUNCTION__" },
165     { "PRETTY_FUNCTION", "__PRETTY_FUNCTION__" },
166     { "DATE", "__DATE__" },
167     { "TIME", "__TIME__" },
168     { "TIMESTAMP", "__TIMESTAMP__" },
169     { "VENDOR", "__VENDOR__" },
170     { "VERSIONX", "__VERSION__" },
171     { "EOFX", "__EOF__" },
172 
173     { "nan" },
174     { "infinity" },
175     { "dig" },
176     { "epsilon" },
177     { "mant_dig" },
178     { "max_10_exp" },
179     { "max_exp" },
180     { "min_10_exp" },
181     { "min_exp" },
182     { "min_normal" },
183     { "re" },
184     { "im" },
185 
186     { "C" },
187     { "D" },
188     { "Windows" },
189     { "Pascal" },
190     { "System" },
191     { "Objective" },
192 
193     { "exit" },
194     { "success" },
195     { "failure" },
196 
197     { "keys" },
198     { "values" },
199     { "rehash" },
200 
201     { "future", "__future" },
202     { "property" },
203     { "nogc" },
204     { "live" },
205     { "safe" },
206     { "trusted" },
207     { "system" },
208     { "disable" },
209 
210     // For inline assembler
211     { "___out", "out" },
212     { "___in", "in" },
213     { "__int", "int" },
214     { "_dollar", "$" },
215     { "__LOCAL_SIZE" },
216 
217     // For operator overloads
218     { "uadd",    "opPos" },
219     { "neg",     "opNeg" },
220     { "com",     "opCom" },
221     { "add",     "opAdd" },
222     { "add_r",   "opAdd_r" },
223     { "sub",     "opSub" },
224     { "sub_r",   "opSub_r" },
225     { "mul",     "opMul" },
226     { "mul_r",   "opMul_r" },
227     { "div",     "opDiv" },
228     { "div_r",   "opDiv_r" },
229     { "mod",     "opMod" },
230     { "mod_r",   "opMod_r" },
231     { "eq",      "opEquals" },
232     { "cmp",     "opCmp" },
233     { "iand",    "opAnd" },
234     { "iand_r",  "opAnd_r" },
235     { "ior",     "opOr" },
236     { "ior_r",   "opOr_r" },
237     { "ixor",    "opXor" },
238     { "ixor_r",  "opXor_r" },
239     { "shl",     "opShl" },
240     { "shl_r",   "opShl_r" },
241     { "shr",     "opShr" },
242     { "shr_r",   "opShr_r" },
243     { "ushr",    "opUShr" },
244     { "ushr_r",  "opUShr_r" },
245     { "cat",     "opCat" },
246     { "cat_r",   "opCat_r" },
247     { "assign",  "opAssign" },
248     { "addass",  "opAddAssign" },
249     { "subass",  "opSubAssign" },
250     { "mulass",  "opMulAssign" },
251     { "divass",  "opDivAssign" },
252     { "modass",  "opModAssign" },
253     { "andass",  "opAndAssign" },
254     { "orass",   "opOrAssign" },
255     { "xorass",  "opXorAssign" },
256     { "shlass",  "opShlAssign" },
257     { "shrass",  "opShrAssign" },
258     { "ushrass", "opUShrAssign" },
259     { "catass",  "opCatAssign" },
260     { "postinc", "opPostInc" },
261     { "postdec", "opPostDec" },
262     { "index",   "opIndex" },
263     { "indexass", "opIndexAssign" },
264     { "slice",   "opSlice" },
265     { "sliceass", "opSliceAssign" },
266     { "call",    "opCall" },
267     { "_cast",    "opCast" },
268     { "opIn" },
269     { "opIn_r" },
270     { "opStar" },
271     { "opDot" },
272     { "opDispatch" },
273     { "opDollar" },
274     { "opUnary" },
275     { "opIndexUnary" },
276     { "opSliceUnary" },
277     { "opBinary" },
278     { "opBinaryRight" },
279     { "opOpAssign" },
280     { "opIndexOpAssign" },
281     { "opSliceOpAssign" },
282     { "pow", "opPow" },
283     { "pow_r", "opPow_r" },
284     { "powass", "opPowAssign" },
285 
286     { "classNew", "new" },
287     { "classDelete", "delete" },
288 
289     // For foreach
290     { "apply", "opApply" },
291     { "applyReverse", "opApplyReverse" },
292 
293     // Ranges
294     { "Fempty", "empty" },
295     { "Ffront", "front" },
296     { "Fback", "back" },
297     { "FpopFront", "popFront" },
298     { "FpopBack", "popBack" },
299 
300     // For internal functions
301     { "aaLen", "_aaLen" },
302     { "aaKeys", "_aaKeys" },
303     { "aaValues", "_aaValues" },
304     { "aaRehash", "_aaRehash" },
305     { "monitorenter", "_d_monitorenter" },
306     { "monitorexit", "_d_monitorexit" },
307     { "criticalenter", "_d_criticalenter" },
308     { "criticalexit", "_d_criticalexit" },
309     { "__ArrayPostblit" },
310     { "__ArrayDtor" },
311     { "_d_delThrowable" },
312     { "_d_assert_fail" },
313     { "dup" },
314     { "_aaApply" },
315     { "_aaApply2" },
316 
317     // For pragma's
318     { "Pinline", "inline" },
319     { "lib" },
320     { "linkerDirective" },
321     { "mangle" },
322     { "msg" },
323     { "startaddress" },
324     { "crt_constructor" },
325     { "crt_destructor" },
326 
327     // For special functions
328     { "tohash", "toHash" },
329     { "tostring", "toString" },
330     { "getmembers", "getMembers" },
331 
332     // Special functions
333     { "__alloca", "alloca" },
334     { "main" },
335     { "WinMain" },
336     { "DllMain" },
337     { "CMain", "_d_cmain" },
338     { "rt_init" },
339     { "__cmp" },
340     { "__equals"},
341     { "__switch"},
342     { "__switch_error"},
343     { "__ArrayCast"},
344     { "_d_HookTraceImpl" },
345     { "_d_arraysetlengthTImpl"},
346     { "_d_arraysetlengthT"},
347     { "_d_arraysetlengthTTrace"},
348 
349     // varargs implementation
350     { "stdc" },
351     { "stdarg" },
352     { "va_start" },
353 
354     // Builtin functions
355     { "std" },
356     { "core" },
357     { "etc" },
358     { "attribute" },
359     { "math" },
360     { "trig" },
361     { "sin" },
362     { "cos" },
363     { "tan" },
364     { "_sqrt", "sqrt" },
365     { "_pow", "pow" },
366     { "atan2" },
367     { "rint" },
368     { "ldexp" },
369     { "rndtol" },
370     { "exp" },
371     { "expm1" },
372     { "exp2" },
373     { "yl2x" },
374     { "yl2xp1" },
375     { "log" },
376     { "log2" },
377     { "log10" },
378     { "round" },
379     { "floor" },
380     { "trunc" },
381     { "fmax" },
382     { "fmin" },
383     { "fma" },
384     { "isnan" },
385     { "isInfinity" },
386     { "isfinite" },
387     { "ceil" },
388     { "copysign" },
389     { "fabs" },
390     { "toPrec" },
391     { "simd" },
392     { "__prefetch"},
393     { "__simd_sto"},
394     { "__simd"},
395     { "__simd_ib"},
396     { "bitop" },
397     { "bsf" },
398     { "bsr" },
399     { "btc" },
400     { "btr" },
401     { "bts" },
402     { "bswap" },
403     { "volatile"},
404     { "volatileLoad"},
405     { "volatileStore"},
406     { "_popcnt"},
407     { "inp"},
408     { "inpl"},
409     { "inpw"},
410     { "outp"},
411     { "outpl"},
412     { "outpw"},
413 
414     // Traits
415     { "isAbstractClass" },
416     { "isArithmetic" },
417     { "isAssociativeArray" },
418     { "isFinalClass" },
419     { "isTemplate" },
420     { "isPOD" },
421     { "isDeprecated" },
422     { "isDisabled" },
423     { "isFuture" },
424     { "isNested" },
425     { "isFloating" },
426     { "isIntegral" },
427     { "isScalar" },
428     { "isStaticArray" },
429     { "isUnsigned" },
430     { "isVirtualFunction" },
431     { "isVirtualMethod" },
432     { "isAbstractFunction" },
433     { "isFinalFunction" },
434     { "isOverrideFunction" },
435     { "isStaticFunction" },
436     { "isModule" },
437     { "isPackage" },
438     { "isRef" },
439     { "isOut" },
440     { "isLazy" },
441     { "hasMember" },
442     { "identifier" },
443     { "getProtection" },
444     { "parent" },
445     { "child" },
446     { "getMember" },
447     { "getOverloads" },
448     { "getVirtualFunctions" },
449     { "getVirtualMethods" },
450     { "classInstanceSize" },
451     { "allMembers" },
452     { "derivedMembers" },
453     { "isSame" },
454     { "compiles" },
455     { "parameters" },
456     { "getAliasThis" },
457     { "getAttributes" },
458     { "getFunctionAttributes" },
459     { "getFunctionVariadicStyle" },
460     { "getParameterStorageClasses" },
461     { "getLinkage" },
462     { "getUnitTests" },
463     { "getVirtualIndex" },
464     { "getPointerBitmap" },
465     { "isReturnOnStack" },
466     { "isZeroInit" },
467     { "getTargetInfo" },
468     { "getLocation" },
469     { "hasPostblit" },
470     { "hasCopyConstructor" },
471     { "isCopyable" },
472 
473     // For C++ mangling
474     { "allocator" },
475     { "basic_string" },
476     { "basic_istream" },
477     { "basic_ostream" },
478     { "basic_iostream" },
479     { "char_traits" },
480 
481     // Compiler recognized UDA's
482     { "udaGNUAbiTag", "gnuAbiTag" },
483     { "udaSelector", "selector" },
484 
485     // C names, for undefined identifier error messages
486     { "NULL" },
487     { "TRUE" },
488     { "FALSE" },
489     { "unsigned" },
490     { "wchar_t" },
491 ];
492 
493 
494 /*
495  * Tuple of DMD source code identifier and symbol in the D executable.
496  *
497  * The first element of the tuple is the identifier to use in the DMD source
498  * code and the second element, if present, is the name to use in the D
499  * executable. If second element, `name`, is not present the identifier,
500  * `ident`, will be used instead
501  */
502 struct Msgtable
503 {
504     // The identifier to use in the DMD source.
505     string ident;
506 
507     // The name to use in the D executable
508     private string name_;
509 
510     /*
511      * Returns: the name to use in the D executable, `name_` if non-empty,
512      *  otherwise `ident`
513      */
514     string name()
515     {
516         return name_ ? name_ : ident;
517     }
518 }
519 
520 /*
521  * Iterates the given Msgtable array, passes each element to the given lambda
522  * and accumulates a string from each return value of calling the lambda.
523  * Appends a newline character after each call to the lambda.
524  */
525 string generate(immutable(Msgtable)[] msgtable, string function(Msgtable) dg)
526 {
527     string code;
528 
529     foreach (i, m ; msgtable)
530     {
531         if (i != 0)
532             code ~= '\n';
533 
534         code ~= dg(m);
535     }
536 
537     return code;
538 }
539 
540 // Used to generate the code for each identifier.
541 string identifier(Msgtable m)
542 {
543     return "Identifier " ~ m.ident ~ ";";
544 }
545 
546 // Used to generate the code for each initializer.
547 string initializer(Msgtable m)
548 {
549     return m.ident ~ ` = Identifier.idPool("` ~ m.name ~ `");`;
550 }
551 
552 // Used to generate the code for each deinitializer.
553 string deinitializer(Msgtable m)
554 {
555     return m.ident ~ " = Identifier.init;";
556 }