1 /**
2  * Contains the `Id` struct with a list of predefined symbols the compiler knows about.
3  *
4  * Copyright:   Copyright (C) 1999-2021 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     { "__c_complex_float" },
129     { "__c_complex_double" },
130     { "__c_complex_real" },
131     { "cpp_type_info_ptr", "__cpp_type_info_ptr" },
132     { "_assert", "assert" },
133     { "_unittest", "unittest" },
134     { "_body", "body" },
135     { "printf" },
136     { "scanf" },
137 
138     { "TypeInfo" },
139     { "TypeInfo_Class" },
140     { "TypeInfo_Interface" },
141     { "TypeInfo_Struct" },
142     { "TypeInfo_Enum" },
143     { "TypeInfo_Pointer" },
144     { "TypeInfo_Vector" },
145     { "TypeInfo_Array" },
146     { "TypeInfo_StaticArray" },
147     { "TypeInfo_AssociativeArray" },
148     { "TypeInfo_Function" },
149     { "TypeInfo_Delegate" },
150     { "TypeInfo_Tuple" },
151     { "TypeInfo_Const" },
152     { "TypeInfo_Invariant" },
153     { "TypeInfo_Shared" },
154     { "TypeInfo_Wild", "TypeInfo_Inout" },
155     { "elements" },
156     { "_arguments_typeinfo" },
157     { "_arguments" },
158     { "_argptr" },
159     { "destroy" },
160     { "xopEquals", "__xopEquals" },
161     { "xopCmp", "__xopCmp" },
162     { "xtoHash", "__xtoHash" },
163 
164     { "LINE", "__LINE__" },
165     { "FILE", "__FILE__" },
166     { "MODULE", "__MODULE__" },
167     { "FUNCTION", "__FUNCTION__" },
168     { "PRETTY_FUNCTION", "__PRETTY_FUNCTION__" },
169     { "DATE", "__DATE__" },
170     { "TIME", "__TIME__" },
171     { "TIMESTAMP", "__TIMESTAMP__" },
172     { "VENDOR", "__VENDOR__" },
173     { "VERSIONX", "__VERSION__" },
174     { "EOFX", "__EOF__" },
175 
176     { "nan" },
177     { "infinity" },
178     { "dig" },
179     { "epsilon" },
180     { "mant_dig" },
181     { "max_10_exp" },
182     { "max_exp" },
183     { "min_10_exp" },
184     { "min_exp" },
185     { "min_normal" },
186     { "re" },
187     { "im" },
188 
189     { "C" },
190     { "D" },
191     { "Windows" },
192     { "System" },
193     { "Objective" },
194 
195     { "exit" },
196     { "success" },
197     { "failure" },
198 
199     { "keys" },
200     { "values" },
201     { "rehash" },
202 
203     { "future", "__future" },
204     { "property" },
205     { "nogc" },
206     { "live" },
207     { "safe" },
208     { "trusted" },
209     { "system" },
210     { "disable" },
211 
212     // For inline assembler
213     { "___out", "out" },
214     { "___in", "in" },
215     { "__int", "int" },
216     { "_dollar", "$" },
217     { "__LOCAL_SIZE" },
218 
219     // For operator overloads
220     { "uadd",    "opPos" },
221     { "neg",     "opNeg" },
222     { "com",     "opCom" },
223     { "add",     "opAdd" },
224     { "add_r",   "opAdd_r" },
225     { "sub",     "opSub" },
226     { "sub_r",   "opSub_r" },
227     { "mul",     "opMul" },
228     { "mul_r",   "opMul_r" },
229     { "div",     "opDiv" },
230     { "div_r",   "opDiv_r" },
231     { "mod",     "opMod" },
232     { "mod_r",   "opMod_r" },
233     { "eq",      "opEquals" },
234     { "cmp",     "opCmp" },
235     { "iand",    "opAnd" },
236     { "iand_r",  "opAnd_r" },
237     { "ior",     "opOr" },
238     { "ior_r",   "opOr_r" },
239     { "ixor",    "opXor" },
240     { "ixor_r",  "opXor_r" },
241     { "shl",     "opShl" },
242     { "shl_r",   "opShl_r" },
243     { "shr",     "opShr" },
244     { "shr_r",   "opShr_r" },
245     { "ushr",    "opUShr" },
246     { "ushr_r",  "opUShr_r" },
247     { "cat",     "opCat" },
248     { "cat_r",   "opCat_r" },
249     { "assign",  "opAssign" },
250     { "addass",  "opAddAssign" },
251     { "subass",  "opSubAssign" },
252     { "mulass",  "opMulAssign" },
253     { "divass",  "opDivAssign" },
254     { "modass",  "opModAssign" },
255     { "andass",  "opAndAssign" },
256     { "orass",   "opOrAssign" },
257     { "xorass",  "opXorAssign" },
258     { "shlass",  "opShlAssign" },
259     { "shrass",  "opShrAssign" },
260     { "ushrass", "opUShrAssign" },
261     { "catass",  "opCatAssign" },
262     { "postinc", "opPostInc" },
263     { "postdec", "opPostDec" },
264     { "index",   "opIndex" },
265     { "indexass", "opIndexAssign" },
266     { "slice",   "opSlice" },
267     { "sliceass", "opSliceAssign" },
268     { "call",    "opCall" },
269     { "_cast",    "opCast" },
270     { "opIn" },
271     { "opIn_r" },
272     { "opStar" },
273     { "opDot" },
274     { "opDispatch" },
275     { "opDollar" },
276     { "opUnary" },
277     { "opIndexUnary" },
278     { "opSliceUnary" },
279     { "opBinary" },
280     { "opBinaryRight" },
281     { "opOpAssign" },
282     { "opIndexOpAssign" },
283     { "opSliceOpAssign" },
284     { "pow", "opPow" },
285     { "pow_r", "opPow_r" },
286     { "powass", "opPowAssign" },
287 
288     { "classNew", "new" },
289     { "classDelete", "delete" },
290 
291     // For foreach
292     { "apply", "opApply" },
293     { "applyReverse", "opApplyReverse" },
294 
295     // Ranges
296     { "Fempty", "empty" },
297     { "Ffront", "front" },
298     { "Fback", "back" },
299     { "FpopFront", "popFront" },
300     { "FpopBack", "popBack" },
301 
302     // For internal functions
303     { "aaLen", "_aaLen" },
304     { "aaKeys", "_aaKeys" },
305     { "aaValues", "_aaValues" },
306     { "aaRehash", "_aaRehash" },
307     { "monitorenter", "_d_monitorenter" },
308     { "monitorexit", "_d_monitorexit" },
309     { "criticalenter", "_d_criticalenter2" },
310     { "criticalexit", "_d_criticalexit" },
311     { "__ArrayPostblit" },
312     { "__ArrayDtor" },
313     { "_d_delThrowable" },
314     { "_d_assert_fail" },
315     { "dup" },
316     { "_aaApply" },
317     { "_aaApply2" },
318 
319     // For pragma's
320     { "Pinline", "inline" },
321     { "lib" },
322     { "linkerDirective" },
323     { "mangle" },
324     { "msg" },
325     { "startaddress" },
326     { "crt_constructor" },
327     { "crt_destructor" },
328 
329     // For special functions
330     { "tohash", "toHash" },
331     { "tostring", "toString" },
332     { "getmembers", "getMembers" },
333 
334     // Special functions
335     { "__alloca", "alloca" },
336     { "main" },
337     { "WinMain" },
338     { "DllMain" },
339     { "CMain", "_d_cmain" },
340     { "rt_init" },
341     { "__cmp" },
342     { "__equals"},
343     { "__switch"},
344     { "__switch_error"},
345     { "__ArrayCast"},
346     { "_d_HookTraceImpl" },
347     { "_d_arraysetlengthTImpl"},
348     { "_d_arraysetlengthT"},
349     { "_d_arraysetlengthTTrace"},
350 
351     // varargs implementation
352     { "stdc" },
353     { "stdarg" },
354     { "va_start" },
355 
356     // Builtin functions
357     { "std" },
358     { "core" },
359     { "etc" },
360     { "attribute" },
361     { "math" },
362     { "trig" },
363     { "sin" },
364     { "cos" },
365     { "tan" },
366     { "_sqrt", "sqrt" },
367     { "_pow", "pow" },
368     { "atan2" },
369     { "rint" },
370     { "ldexp" },
371     { "rndtol" },
372     { "exp" },
373     { "expm1" },
374     { "exp2" },
375     { "yl2x" },
376     { "yl2xp1" },
377     { "log" },
378     { "log2" },
379     { "log10" },
380     { "round" },
381     { "floor" },
382     { "trunc" },
383     { "fmax" },
384     { "fmin" },
385     { "fma" },
386     { "isnan" },
387     { "isInfinity" },
388     { "isfinite" },
389     { "ceil" },
390     { "copysign" },
391     { "fabs" },
392     { "toPrec" },
393     { "simd" },
394     { "__prefetch"},
395     { "__simd_sto"},
396     { "__simd"},
397     { "__simd_ib"},
398     { "bitop" },
399     { "bsf" },
400     { "bsr" },
401     { "btc" },
402     { "btr" },
403     { "bts" },
404     { "bswap" },
405     { "volatile"},
406     { "volatileLoad"},
407     { "volatileStore"},
408     { "_popcnt"},
409     { "inp"},
410     { "inpl"},
411     { "inpw"},
412     { "outp"},
413     { "outpl"},
414     { "outpw"},
415 
416     // Traits
417     { "isAbstractClass" },
418     { "isArithmetic" },
419     { "isAssociativeArray" },
420     { "isFinalClass" },
421     { "isTemplate" },
422     { "isPOD" },
423     { "isDeprecated" },
424     { "isDisabled" },
425     { "isFuture" },
426     { "isNested" },
427     { "isFloating" },
428     { "isIntegral" },
429     { "isScalar" },
430     { "isStaticArray" },
431     { "isUnsigned" },
432     { "isVirtualFunction" },
433     { "isVirtualMethod" },
434     { "isAbstractFunction" },
435     { "isFinalFunction" },
436     { "isOverrideFunction" },
437     { "isStaticFunction" },
438     { "isModule" },
439     { "isPackage" },
440     { "isRef" },
441     { "isOut" },
442     { "isLazy" },
443     { "hasMember" },
444     { "identifier" },
445     { "getProtection" },
446     { "getVisibility" },
447     { "parent" },
448     { "child" },
449     { "getMember" },
450     { "getOverloads" },
451     { "getVirtualFunctions" },
452     { "getVirtualMethods" },
453     { "classInstanceSize" },
454     { "allMembers" },
455     { "derivedMembers" },
456     { "isSame" },
457     { "compiles" },
458     { "getAliasThis" },
459     { "getAttributes" },
460     { "getFunctionAttributes" },
461     { "getFunctionVariadicStyle" },
462     { "getParameterStorageClasses" },
463     { "getLinkage" },
464     { "getUnitTests" },
465     { "getVirtualIndex" },
466     { "getPointerBitmap" },
467     { "getCppNamespaces" },
468     { "isReturnOnStack" },
469     { "isZeroInit" },
470     { "getTargetInfo" },
471     { "getLocation" },
472     { "hasPostblit" },
473     { "hasCopyConstructor" },
474     { "isCopyable" },
475 
476     // For C++ mangling
477     { "allocator" },
478     { "basic_string" },
479     { "basic_istream" },
480     { "basic_ostream" },
481     { "basic_iostream" },
482     { "char_traits" },
483 
484     // Compiler recognized UDA's
485     { "udaGNUAbiTag", "gnuAbiTag" },
486     { "udaSelector", "selector" },
487     { "udaOptional", "optional"},
488 
489     // C names, for undefined identifier error messages
490     { "NULL" },
491     { "TRUE" },
492     { "FALSE" },
493     { "unsigned" },
494     { "wchar_t" },
495 ];
496 
497 
498 /*
499  * Tuple of DMD source code identifier and symbol in the D executable.
500  *
501  * The first element of the tuple is the identifier to use in the DMD source
502  * code and the second element, if present, is the name to use in the D
503  * executable. If second element, `name`, is not present the identifier,
504  * `ident`, will be used instead
505  */
506 struct Msgtable
507 {
508     // The identifier to use in the DMD source.
509     string ident;
510 
511     // The name to use in the D executable
512     private string name_;
513 
514     /*
515      * Returns: the name to use in the D executable, `name_` if non-empty,
516      *  otherwise `ident`
517      */
518     string name()
519     {
520         return name_ ? name_ : ident;
521     }
522 }
523 
524 /*
525  * Iterates the given Msgtable array, passes each element to the given lambda
526  * and accumulates a string from each return value of calling the lambda.
527  * Appends a newline character after each call to the lambda.
528  */
529 string generate(immutable(Msgtable)[] msgtable, string function(Msgtable) dg)
530 {
531     string code;
532 
533     foreach (i, m ; msgtable)
534     {
535         if (i != 0)
536             code ~= '\n';
537 
538         code ~= dg(m);
539     }
540 
541     return code;
542 }
543 
544 // Used to generate the code for each identifier.
545 string identifier(Msgtable m)
546 {
547     return "Identifier " ~ m.ident ~ ";";
548 }
549 
550 // Used to generate the code for each initializer.
551 string initializer(Msgtable m)
552 {
553     return m.ident ~ ` = Identifier.idPool("` ~ m.name ~ `");`;
554 }
555 
556 // Used to generate the code for each deinitializer.
557 string deinitializer(Msgtable m)
558 {
559     return m.ident ~ " = Identifier.init;";
560 }