1 /**
2  * Contains the `Id` struct with a list of predefined symbols the compiler knows about.
3  *
4  * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
5  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
6  * License:     $(LINK2 https://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     { "_size_t", "size_t" },
65     { "_ptrdiff_t", "ptrdiff_t" },
66     { "string" },
67     { "wstring" },
68     { "dstring" },
69     { "max" },
70     { "min" },
71     { "This", "this" },
72     { "_super", "super" },
73     { "ctor", "__ctor" },
74     { "dtor", "__dtor" },
75     { "__xdtor", "__xdtor" },
76     { "__fieldDtor", "__fieldDtor" },
77     { "__aggrDtor", "__aggrDtor" },
78     { "cppdtor", "__cppdtor" },
79     { "ticppdtor", "__ticppdtor" },
80     { "postblit", "__postblit" },
81     { "__xpostblit", "__xpostblit" },
82     { "__fieldPostblit", "__fieldPostblit" },
83     { "__aggrPostblit", "__aggrPostblit" },
84     { "classInvariant", "__invariant" },
85     { "unitTest", "__unitTest" },
86     { "require", "__require" },
87     { "ensure", "__ensure" },
88     { "capture", "__capture" },
89     { "this2", "__this" },
90     { "_init", "init" },
91     { "__sizeof", "sizeof" },
92     { "__xalignof", "alignof" },
93     { "_mangleof", "mangleof" },
94     { "stringof" },
95     { "_tupleof", "tupleof" },
96     { "length" },
97     { "remove" },
98     { "ptr" },
99     { "array" },
100     { "funcptr" },
101     { "dollar", "__dollar" },
102     { "ctfe", "__ctfe" },
103     { "offset" },
104     { "offsetof" },
105     { "ModuleInfo" },
106     { "ClassInfo" },
107     { "classinfo" },
108     { "typeinfo" },
109     { "outer" },
110     { "Exception" },
111     { "RTInfo" },
112     { "Throwable" },
113     { "Error" },
114     { "withSym", "__withSym" },
115     { "result", "__result" },
116     { "returnLabel", "__returnLabel" },
117     { "line" },
118     { "empty", "" },
119     { "dotdotdot", "..." }, // use for error messages
120     { "p" },
121     { "__vptr" },
122     { "__monitor" },
123     { "gate", "__gate" },
124     { "__c_long" },
125     { "__c_ulong" },
126     { "__c_longlong" },
127     { "__c_ulonglong" },
128     { "__c_long_double" },
129     { "__c_char" },
130     { "__c_wchar_t" },
131     { "__c_complex_float" },
132     { "__c_complex_double" },
133     { "__c_complex_real" },
134     { "cpp_type_info_ptr", "__cpp_type_info_ptr" },
135     { "_assert", "assert" },
136     { "_unittest", "unittest" },
137     { "_body", "body" },
138     { "printf" },
139     { "scanf" },
140 
141     { "TypeInfo" },
142     { "TypeInfo_Class" },
143     { "TypeInfo_Interface" },
144     { "TypeInfo_Struct" },
145     { "TypeInfo_Enum" },
146     { "TypeInfo_Pointer" },
147     { "TypeInfo_Vector" },
148     { "TypeInfo_Array" },
149     { "TypeInfo_StaticArray" },
150     { "TypeInfo_AssociativeArray" },
151     { "TypeInfo_Function" },
152     { "TypeInfo_Delegate" },
153     { "TypeInfo_Tuple" },
154     { "TypeInfo_Const" },
155     { "TypeInfo_Invariant" },
156     { "TypeInfo_Shared" },
157     { "TypeInfo_Wild", "TypeInfo_Inout" },
158     { "elements" },
159     { "_arguments_typeinfo" },
160     { "_arguments" },
161     { "_argptr" },
162     { "destroy" },
163     { "xopEquals", "__xopEquals" },
164     { "xopCmp", "__xopCmp" },
165     { "xtoHash", "__xtoHash" },
166     { "__tmpfordtor" },
167 
168     { "LINE", "__LINE__" },
169     { "FILE", "__FILE__" },
170     { "MODULE", "__MODULE__" },
171     { "FUNCTION", "__FUNCTION__" },
172     { "PRETTY_FUNCTION", "__PRETTY_FUNCTION__" },
173     { "DATE", "__DATE__" },
174     { "TIME", "__TIME__" },
175     { "TIMESTAMP", "__TIMESTAMP__" },
176     { "VENDOR", "__VENDOR__" },
177     { "VERSIONX", "__VERSION__" },
178     { "EOFX", "__EOF__" },
179 
180     { "nan" },
181     { "infinity" },
182     { "dig" },
183     { "epsilon" },
184     { "mant_dig" },
185     { "max_10_exp" },
186     { "max_exp" },
187     { "min_10_exp" },
188     { "min_exp" },
189     { "min_normal" },
190     { "re" },
191     { "im" },
192 
193     { "C" },
194     { "D" },
195     { "Windows" },
196     { "System" },
197     { "Objective" },
198 
199     { "exit" },
200     { "success" },
201     { "failure" },
202 
203     { "keys" },
204     { "values" },
205     { "rehash" },
206 
207     { "future", "__future" },
208     { "property" },
209     { "nogc" },
210     { "live" },
211     { "safe" },
212     { "trusted" },
213     { "system" },
214     { "disable" },
215 
216     // For inline assembler
217     { "___out", "out" },
218     { "___in", "in" },
219     { "__int", "int" },
220     { "_dollar", "$" },
221     { "__LOCAL_SIZE" },
222 
223     // For operator overloads
224     { "uadd",    "opPos" },
225     { "neg",     "opNeg" },
226     { "com",     "opCom" },
227     { "add",     "opAdd" },
228     { "add_r",   "opAdd_r" },
229     { "sub",     "opSub" },
230     { "sub_r",   "opSub_r" },
231     { "mul",     "opMul" },
232     { "mul_r",   "opMul_r" },
233     { "div",     "opDiv" },
234     { "div_r",   "opDiv_r" },
235     { "mod",     "opMod" },
236     { "mod_r",   "opMod_r" },
237     { "eq",      "opEquals" },
238     { "cmp",     "opCmp" },
239     { "iand",    "opAnd" },
240     { "iand_r",  "opAnd_r" },
241     { "ior",     "opOr" },
242     { "ior_r",   "opOr_r" },
243     { "ixor",    "opXor" },
244     { "ixor_r",  "opXor_r" },
245     { "shl",     "opShl" },
246     { "shl_r",   "opShl_r" },
247     { "shr",     "opShr" },
248     { "shr_r",   "opShr_r" },
249     { "ushr",    "opUShr" },
250     { "ushr_r",  "opUShr_r" },
251     { "cat",     "opCat" },
252     { "cat_r",   "opCat_r" },
253     { "assign",  "opAssign" },
254     { "addass",  "opAddAssign" },
255     { "subass",  "opSubAssign" },
256     { "mulass",  "opMulAssign" },
257     { "divass",  "opDivAssign" },
258     { "modass",  "opModAssign" },
259     { "andass",  "opAndAssign" },
260     { "orass",   "opOrAssign" },
261     { "xorass",  "opXorAssign" },
262     { "shlass",  "opShlAssign" },
263     { "shrass",  "opShrAssign" },
264     { "ushrass", "opUShrAssign" },
265     { "catass",  "opCatAssign" },
266     { "postinc", "opPostInc" },
267     { "postdec", "opPostDec" },
268     { "index",   "opIndex" },
269     { "indexass", "opIndexAssign" },
270     { "slice",   "opSlice" },
271     { "sliceass", "opSliceAssign" },
272     { "call",    "opCall" },
273     { "_cast",    "opCast" },
274     { "opIn" },
275     { "opIn_r" },
276     { "opStar" },
277     { "opDot" },
278     { "opDispatch" },
279     { "opDollar" },
280     { "opUnary" },
281     { "opIndexUnary" },
282     { "opSliceUnary" },
283     { "opBinary" },
284     { "opBinaryRight" },
285     { "opOpAssign" },
286     { "opIndexOpAssign" },
287     { "opSliceOpAssign" },
288     { "pow", "opPow" },
289     { "pow_r", "opPow_r" },
290     { "powass", "opPowAssign" },
291 
292     { "classNew", "new" },
293     { "classDelete", "delete" },
294 
295     // For foreach
296     { "apply", "opApply" },
297     { "applyReverse", "opApplyReverse" },
298 
299     // Ranges
300     { "Fempty", "empty" },
301     { "Ffront", "front" },
302     { "Fback", "back" },
303     { "FpopFront", "popFront" },
304     { "FpopBack", "popBack" },
305 
306     // For internal functions
307     { "aaLen", "_aaLen" },
308     { "aaKeys", "_aaKeys" },
309     { "aaValues", "_aaValues" },
310     { "aaRehash", "_aaRehash" },
311     { "_aaAsStruct" },
312     { "monitorenter", "_d_monitorenter" },
313     { "monitorexit", "_d_monitorexit" },
314     { "criticalenter", "_d_criticalenter2" },
315     { "criticalexit", "_d_criticalexit" },
316     { "__ArrayPostblit" },
317     { "__ArrayDtor" },
318     { "_d_delThrowable" },
319     { "_d_newThrowable" },
320     { "_d_newclassT" },
321     { "_d_newclassTTrace" },
322     { "_d_newitemT" },
323     { "_d_newitemTTrace" },
324     { "_d_newarrayT" },
325     { "_d_newarrayTTrace" },
326     { "_d_assert_fail" },
327     { "dup" },
328     { "_aaApply" },
329     { "_aaApply2" },
330     { "_d_arrayctor" },
331     { "_d_arraysetctor" },
332     { "_d_arraysetassign" },
333     { "_d_arrayassign_l" },
334     { "_d_arrayassign_r" },
335 
336     // For pragma's
337     { "Pinline", "inline" },
338     { "lib" },
339     { "linkerDirective" },
340     { "mangle" },
341     { "msg" },
342     { "startaddress" },
343     { "crt_constructor" },
344     { "crt_destructor" },
345 
346     // For special functions
347     { "tohash", "toHash" },
348     { "tostring", "toString" },
349     { "getmembers", "getMembers" },
350 
351     // Special functions
352     { "__alloca", "alloca" },
353     { "main" },
354     { "WinMain" },
355     { "DllMain" },
356     { "CMain", "_d_cmain" },
357     { "rt_init" },
358     { "__cmp" },
359     { "__equals"},
360     { "__switch"},
361     { "__switch_error"},
362     { "__ArrayCast"},
363     { "_d_HookTraceImpl" },
364     { "_d_arraysetlengthTImpl"},
365     { "_d_arraysetlengthT"},
366     { "_d_arraysetlengthTTrace"},
367     { "_d_arrayappendT" },
368     { "_d_arrayappendTTrace" },
369     { "_d_arrayappendcTXImpl" },
370     { "_d_arrayappendcTX" },
371     { "_d_arrayappendcTXTrace" },
372     { "_d_arraycatnTX" },
373     { "_d_arraycatnTXTrace" },
374 
375     // varargs implementation
376     { "stdc" },
377     { "stdarg" },
378     { "va_start" },
379 
380     // Builtin functions
381     { "std" },
382     { "core" },
383     { "config" },
384     { "c_complex_float" },
385     { "c_complex_double" },
386     { "c_complex_real" },
387     { "etc" },
388     { "attribute" },
389     { "atomic" },
390     { "atomicOp" },
391     { "math" },
392     { "sin" },
393     { "cos" },
394     { "tan" },
395     { "_sqrt", "sqrt" },
396     { "_pow", "pow" },
397     { "atan2" },
398     { "rint" },
399     { "ldexp" },
400     { "rndtol" },
401     { "exp" },
402     { "expm1" },
403     { "exp2" },
404     { "yl2x" },
405     { "yl2xp1" },
406     { "log" },
407     { "log2" },
408     { "log10" },
409     { "round" },
410     { "floor" },
411     { "trunc" },
412     { "fmax" },
413     { "fmin" },
414     { "fma" },
415     { "isnan" },
416     { "isInfinity" },
417     { "isfinite" },
418     { "ceil" },
419     { "copysign" },
420     { "fabs" },
421     { "toPrec" },
422     { "simd" },
423     { "__prefetch"},
424     { "__simd_sto"},
425     { "__simd"},
426     { "__simd_ib"},
427     { "bitop" },
428     { "bsf" },
429     { "bsr" },
430     { "btc" },
431     { "btr" },
432     { "bts" },
433     { "bswap" },
434     { "volatile"},
435     { "volatileLoad"},
436     { "volatileStore"},
437     { "_popcnt"},
438     { "inp"},
439     { "inpl"},
440     { "inpw"},
441     { "outp"},
442     { "outpl"},
443     { "outpw"},
444 
445     // Traits
446     { "isAbstractClass" },
447     { "isArithmetic" },
448     { "isAssociativeArray" },
449     { "isFinalClass" },
450     { "isTemplate" },
451     { "isPOD" },
452     { "isDeprecated" },
453     { "isDisabled" },
454     { "isFuture" },
455     { "isNested" },
456     { "isFloating" },
457     { "isIntegral" },
458     { "isScalar" },
459     { "isStaticArray" },
460     { "isUnsigned" },
461     { "isVirtualFunction" },
462     { "isVirtualMethod" },
463     { "isAbstractFunction" },
464     { "isFinalFunction" },
465     { "isOverrideFunction" },
466     { "isStaticFunction" },
467     { "isModule" },
468     { "isPackage" },
469     { "isRef" },
470     { "isOut" },
471     { "isLazy" },
472     { "hasMember" },
473     { "identifier" },
474     { "fullyQualifiedName" },
475     { "getProtection" },
476     { "getVisibility" },
477     { "parent" },
478     { "child" },
479     { "getMember" },
480     { "getOverloads" },
481     { "getVirtualFunctions" },
482     { "getVirtualMethods" },
483     { "classInstanceSize" },
484     { "classInstanceAlignment" },
485     { "allMembers" },
486     { "derivedMembers" },
487     { "isSame" },
488     { "compiles" },
489     { "getAliasThis" },
490     { "getAttributes" },
491     { "getFunctionAttributes" },
492     { "getFunctionVariadicStyle" },
493     { "getParameterStorageClasses" },
494     { "getLinkage" },
495     { "getUnitTests" },
496     { "getVirtualIndex" },
497     { "getPointerBitmap" },
498     { "initSymbol" },
499     { "getCppNamespaces" },
500     { "isReturnOnStack" },
501     { "isZeroInit" },
502     { "getTargetInfo" },
503     { "getLocation" },
504     { "hasPostblit" },
505     { "hasCopyConstructor" },
506     { "isCopyable" },
507     { "toType" },
508     { "parameters" },
509 
510     // For C++ mangling
511     { "allocator" },
512     { "basic_string" },
513     { "basic_istream" },
514     { "basic_ostream" },
515     { "basic_iostream" },
516     { "char_traits" },
517 
518     // Compiler recognized UDA's
519     { "udaGNUAbiTag", "gnuAbiTag" },
520     { "udaSelector", "selector" },
521     { "udaOptional", "optional"},
522     { "udaMustUse", "mustuse" },
523 
524     // C names, for undefined identifier error messages
525     { "NULL" },
526     { "TRUE" },
527     { "FALSE" },
528     { "unsigned" },
529     { "wchar_t" },
530 
531     // for C compiler
532     { "ImportC", "__C" },
533     { "__tag" },
534     { "dllimport" },
535     { "dllexport" },
536     { "naked" },
537     { "thread" },
538     { "vector_size" },
539     { "__func__" },
540     { "always_inline" },
541     { "noinline" },
542     { "noreturn" },
543     { "_nothrow", "nothrow" },
544     { "_deprecated", "deprecated" },
545     { "_align", "align" },
546     { "aligned" },
547     { "__pragma", "pragma" },
548     { "builtins", "__builtins" },
549     { "builtin_va_list", "__builtin_va_list" },
550     { "builtin_va_arg", "__builtin_va_arg" },
551     { "va_list_tag", "__va_list_tag" },
552     { "va_arg" },
553     { "pack" },
554     { "show" },
555     { "push" },
556     { "pop" },
557     { "_pure", "pure" },
558     { "define" },
559     { "undef" },
560     { "ident" },
561 ];
562 
563 
564 /*
565  * Tuple of DMD source code identifier and symbol in the D executable.
566  *
567  * The first element of the tuple is the identifier to use in the DMD source
568  * code and the second element, if present, is the name to use in the D
569  * executable. If second element, `name`, is not present the identifier,
570  * `ident`, will be used instead
571  */
572 struct Msgtable
573 {
574     // The identifier to use in the DMD source.
575     string ident;
576 
577     // The name to use in the D executable
578     private string name_;
579 
580     /*
581      * Returns: the name to use in the D executable, `name_` if non-empty,
582      *  otherwise `ident`
583      */
584     string name() @safe
585     {
586         return name_ ? name_ : ident;
587     }
588 }
589 
590 /*
591  * Iterates the given Msgtable array, passes each element to the given lambda
592  * and accumulates a string from each return value of calling the lambda.
593  * Appends a newline character after each call to the lambda.
594  */
595 string generate(immutable(Msgtable)[] msgtable, string function(Msgtable) dg)
596 {
597     string code;
598 
599     foreach (i, m ; msgtable)
600     {
601         if (i != 0)
602             code ~= '\n';
603 
604         code ~= dg(m);
605     }
606 
607     return code;
608 }
609 
610 // Used to generate the code for each identifier.
611 string identifier(Msgtable m) @safe
612 {
613     return "Identifier " ~ m.ident ~ ";";
614 }
615 
616 // Used to generate the code for each initializer.
617 string initializer(Msgtable m) @safe
618 {
619     return m.ident ~ ` = Identifier.idPool("` ~ m.name ~ `");`;
620 }
621 
622 // Used to generate the code for each deinitializer.
623 string deinitializer(Msgtable m) @safe
624 {
625     return m.ident ~ " = Identifier.init;";
626 }