@@ -25,8 +25,44 @@ import dmd.mtype;
25
25
import dmd.root.ctfloat;
26
26
import dmd.root.stringtable;
27
27
import dmd.tokens;
28
+ import dmd.id;
28
29
static import core.bitop ;
29
30
31
+ /* *********************************
32
+ * Determine if function is a builtin one that we can
33
+ * evaluate at compile time.
34
+ */
35
+ public extern (C++ ) BUILTIN isBuiltin(FuncDeclaration fd)
36
+ {
37
+ if (fd.builtin == BUILTIN .unknown)
38
+ {
39
+ fd.builtin = determine_builtin(fd);
40
+ }
41
+ return fd.builtin;
42
+ }
43
+
44
+ /* *************************************
45
+ * Evaluate builtin function.
46
+ * Return result; NULL if cannot evaluate it.
47
+ */
48
+ public extern (C++ ) Expression eval_builtin(Loc loc, FuncDeclaration fd, Expressions* arguments)
49
+ {
50
+ if (fd.builtin == BUILTIN .unimp)
51
+ return null ;
52
+
53
+ switch (fd.builtin)
54
+ {
55
+ foreach (e; __traits (allMembers, BUILTIN ))
56
+ {
57
+ static if (e == " unknown" )
58
+ case BUILTIN .unknown: assert (false );
59
+ else
60
+ mixin (" case BUILTIN." ~ e~ " : return eval_" ~ e~ " (loc, fd, arguments);" );
61
+ }
62
+ default : assert (0 );
63
+ }
64
+ }
65
+
30
66
private :
31
67
32
68
/**
@@ -40,20 +76,93 @@ private:
40
76
* Returns:
41
77
* An Expression containing the return value of the call.
42
78
*/
43
- alias builtin_fp = Expression function (Loc loc, FuncDeclaration fd, Expressions* arguments);
44
79
45
- __gshared StringTable! builtin_fp builtins;
46
-
47
- void add_builtin (const (char )[] mangle, builtin_fp fp)
80
+ BUILTIN determine_builtin (FuncDeclaration func)
48
81
{
49
- builtins.insert(mangle, fp);
50
- }
82
+ auto fd = func.toAliasFunc();
83
+ if (fd.isDeprecated())
84
+ return BUILTIN .unimp;
85
+ auto m = fd.getModule();
86
+ if (! m || ! m.md)
87
+ return BUILTIN .unimp;
88
+ const md = m.md;
89
+ const id2 = md.id;
51
90
52
- builtin_fp builtin_lookup (const (char )* mangle)
53
- {
54
- if (const sv = builtins.lookup(mangle, strlen(mangle)))
55
- return sv.value;
56
- return null ;
91
+ // Look for core.math, core.bitop and std.math
92
+ if (id2 != Id.math && id2 != Id.bitop)
93
+ return BUILTIN .unimp;
94
+
95
+ if (! md.packages)
96
+ return BUILTIN .unimp;
97
+ if (md.packages.length != 1 )
98
+ return BUILTIN .unimp;
99
+
100
+ const id1 = (* md.packages)[0 ];
101
+ if (id1 != Id.core && id1 != Id.std)
102
+ return BUILTIN .unimp;
103
+ const id3 = fd.ident;
104
+
105
+ if (id1 == Id.core && id2 == Id.bitop)
106
+ {
107
+ if (id3 == Id.bsf) return BUILTIN .bsf;
108
+ if (id3 == Id.bsr) return BUILTIN .bsr;
109
+ if (id3 == Id.bswap) return BUILTIN .bswap;
110
+ if (id3 == Id._popcnt) return BUILTIN .popcnt;
111
+ return BUILTIN .unimp;
112
+ }
113
+
114
+ // Math
115
+ if (id3 == Id.sin) return BUILTIN .sin;
116
+ if (id3 == Id.cos) return BUILTIN .cos;
117
+ if (id3 == Id.tan) return BUILTIN .tan;
118
+ if (id3 == Id.atan2) return BUILTIN .unimp; // N.B unimplmeneted
119
+
120
+ if (id3 == Id._sqrt) return BUILTIN .sqrt;
121
+ if (id3 == Id.fabs) return BUILTIN .fabs;
122
+
123
+ if (id3 == Id.exp) return BUILTIN .exp;
124
+ if (id3 == Id.expm1) return BUILTIN .expm1;
125
+ if (id3 == Id.exp2) return BUILTIN .exp2;
126
+ if (id3 == Id.yl2x) return CTFloat.yl2x_supported ? BUILTIN .yl2x : BUILTIN .unimp;
127
+ if (id3 == Id.yl2xp1) return CTFloat.yl2xp1_supported ? BUILTIN .yl2xp1 : BUILTIN .unimp;
128
+
129
+ if (id3 == Id.log) return BUILTIN .log;
130
+ if (id3 == Id.log2) return BUILTIN .log2;
131
+ if (id3 == Id.log10) return BUILTIN .log10;
132
+
133
+ if (id3 == Id.ldexp) return BUILTIN .ldexp;
134
+ if (id3 == Id.round) return BUILTIN .round;
135
+ if (id3 == Id.floor) return BUILTIN .floor;
136
+ if (id3 == Id.ceil) return BUILTIN .ceil;
137
+ if (id3 == Id.trunc) return BUILTIN .trunc;
138
+
139
+ if (id3 == Id.fmin) return BUILTIN .fmin;
140
+ if (id3 == Id.fmax) return BUILTIN .fmax;
141
+ if (id3 == Id.fma) return BUILTIN .fma;
142
+ if (id3 == Id.copysign) return BUILTIN .copysign;
143
+
144
+ if (id3 == Id.isnan) return BUILTIN .isnan;
145
+ if (id3 == Id.isInfinity) return BUILTIN .isinfinity;
146
+ if (id3 == Id.isfinite) return BUILTIN .isfinite;
147
+
148
+ // Only match pow(fp,fp) where fp is a floating point type
149
+ if (id3 == Id._pow)
150
+ {
151
+ if ((* fd.parameters)[0 ].type.isfloating() &&
152
+ (* fd.parameters)[1 ].type.isfloating())
153
+ return BUILTIN .pow;
154
+ return BUILTIN .unimp;
155
+ }
156
+
157
+ if (id3 != Id.toPrec)
158
+ return BUILTIN .unimp;
159
+ const (char )* me = mangleExact(fd);
160
+ final switch (me[" _D4core4math__T6toPrecHT" .length])
161
+ {
162
+ case ' d' : return BUILTIN .toPrecDouble;
163
+ case ' e' : return BUILTIN .toPrecReal;
164
+ case ' f' : return BUILTIN .toPrecFloat;
165
+ }
57
166
}
58
167
59
168
Expression eval_unimp (Loc loc, FuncDeclaration fd, Expressions* arguments)
@@ -329,181 +438,3 @@ Expression eval_toPrecReal(Loc loc, FuncDeclaration fd, Expressions* arguments)
329
438
Expression arg0 = (* arguments)[0 ];
330
439
return new RealExp(loc, arg0.toReal(), Type.tfloat80);
331
440
}
332
-
333
- public extern (C++ ) void builtin_init()
334
- {
335
- builtins._init(113 );
336
- // @safe @nogc pure nothrow real function(real)
337
- add_builtin(" _D4core4math3sinFNaNbNiNfeZe" , &eval_sin);
338
- add_builtin(" _D4core4math3cosFNaNbNiNfeZe" , &eval_cos);
339
- add_builtin(" _D4core4math3tanFNaNbNiNfeZe" , &eval_tan);
340
- add_builtin(" _D4core4math4sqrtFNaNbNiNfeZe" , &eval_sqrt);
341
- add_builtin(" _D4core4math4fabsFNaNbNiNfeZe" , &eval_fabs);
342
- add_builtin(" _D4core4math5expm1FNaNbNiNfeZe" , &eval_unimp);
343
- add_builtin(" _D4core4math4exp2FNaNbNiNfeZe" , &eval_unimp);
344
- // @trusted @nogc pure nothrow real function(real)
345
- add_builtin(" _D4core4math3sinFNaNbNiNeeZe" , &eval_sin);
346
- add_builtin(" _D4core4math3cosFNaNbNiNeeZe" , &eval_cos);
347
- add_builtin(" _D4core4math3tanFNaNbNiNeeZe" , &eval_tan);
348
- add_builtin(" _D4core4math4sqrtFNaNbNiNeeZe" , &eval_sqrt);
349
- add_builtin(" _D4core4math4fabsFNaNbNiNeeZe" , &eval_fabs);
350
- add_builtin(" _D4core4math5expm1FNaNbNiNeeZe" , &eval_unimp);
351
- // @safe @nogc pure nothrow double function(double)
352
- add_builtin(" _D4core4math4sqrtFNaNbNiNfdZd" , &eval_sqrt);
353
- // @safe @nogc pure nothrow float function(float)
354
- add_builtin(" _D4core4math4sqrtFNaNbNiNffZf" , &eval_sqrt);
355
- // @safe @nogc pure nothrow real function(real, real)
356
- add_builtin(" _D4core4math5atan2FNaNbNiNfeeZe" , &eval_unimp);
357
- if (CTFloat.yl2x_supported)
358
- {
359
- add_builtin(" _D4core4math4yl2xFNaNbNiNfeeZe" , &eval_yl2x);
360
- }
361
- else
362
- {
363
- add_builtin(" _D4core4math4yl2xFNaNbNiNfeeZe" , &eval_unimp);
364
- }
365
- if (CTFloat.yl2xp1_supported)
366
- {
367
- add_builtin(" _D4core4math6yl2xp1FNaNbNiNfeeZe" , &eval_yl2xp1);
368
- }
369
- else
370
- {
371
- add_builtin(" _D4core4math6yl2xp1FNaNbNiNfeeZe" , &eval_unimp);
372
- }
373
- // @safe @nogc pure nothrow long function(real)
374
- add_builtin(" _D4core4math6rndtolFNaNbNiNfeZl" , &eval_unimp);
375
- // @safe @nogc pure nothrow real function(real)
376
- add_builtin(" _D3std4math3tanFNaNbNiNfeZe" , &eval_tan);
377
- add_builtin(" _D3std4math4trig3tanFNaNbNiNfeZe" , &eval_tan);
378
- add_builtin(" _D3std4math5expm1FNaNbNiNfeZe" , &eval_unimp);
379
- // @trusted @nogc pure nothrow real function(real)
380
- add_builtin(" _D3std4math3tanFNaNbNiNeeZe" , &eval_tan);
381
- add_builtin(" _D3std4math4trig3tanFNaNbNiNeeZe" , &eval_tan);
382
- add_builtin(" _D3std4math3expFNaNbNiNeeZe" , &eval_exp);
383
- add_builtin(" _D3std4math5expm1FNaNbNiNeeZe" , &eval_expm1);
384
- add_builtin(" _D3std4math4exp2FNaNbNiNeeZe" , &eval_exp2);
385
- // @safe @nogc pure nothrow real function(real, real)
386
- add_builtin(" _D3std4math5atan2FNaNbNiNfeeZe" , &eval_unimp);
387
- add_builtin(" _D3std4math4trig5atan2FNaNbNiNfeeZe" , &eval_unimp);
388
- // @safe @nogc pure nothrow T function(T, int)
389
- add_builtin(" _D4core4math5ldexpFNaNbNiNfeiZe" , &eval_ldexp);
390
-
391
- add_builtin(" _D3std4math3logFNaNbNiNfeZe" , &eval_log);
392
-
393
- add_builtin(" _D3std4math4log2FNaNbNiNfeZe" , &eval_log2);
394
-
395
- add_builtin(" _D3std4math5log10FNaNbNiNfeZe" , &eval_log10);
396
-
397
- add_builtin(" _D3std4math5roundFNbNiNeeZe" , &eval_round);
398
- add_builtin(" _D3std4math5roundFNaNbNiNeeZe" , &eval_round);
399
-
400
- add_builtin(" _D3std4math5floorFNaNbNiNefZf" , &eval_floor);
401
- add_builtin(" _D3std4math5floorFNaNbNiNedZd" , &eval_floor);
402
- add_builtin(" _D3std4math5floorFNaNbNiNeeZe" , &eval_floor);
403
-
404
- add_builtin(" _D3std4math4ceilFNaNbNiNefZf" , &eval_ceil);
405
- add_builtin(" _D3std4math4ceilFNaNbNiNedZd" , &eval_ceil);
406
- add_builtin(" _D3std4math4ceilFNaNbNiNeeZe" , &eval_ceil);
407
-
408
- add_builtin(" _D3std4math5truncFNaNbNiNeeZe" , &eval_trunc);
409
-
410
- add_builtin(" _D3std4math4fminFNaNbNiNfeeZe" , &eval_fmin);
411
-
412
- add_builtin(" _D3std4math4fmaxFNaNbNiNfeeZe" , &eval_fmax);
413
-
414
- add_builtin(" _D3std4math__T8copysignTfTfZQoFNaNbNiNeffZf" , &eval_copysign);
415
- add_builtin(" _D3std4math__T8copysignTdTdZQoFNaNbNiNeddZd" , &eval_copysign);
416
- add_builtin(" _D3std4math__T8copysignTeTeZQoFNaNbNiNeeeZe" , &eval_copysign);
417
-
418
- add_builtin(" _D3std4math__T3powTfTfZQjFNaNbNiNeffZf" , &eval_pow);
419
- add_builtin(" _D3std4math__T3powTdTdZQjFNaNbNiNeddZd" , &eval_pow);
420
- add_builtin(" _D3std4math__T3powTeTeZQjFNaNbNiNeeeZe" , &eval_pow);
421
-
422
- add_builtin(" _D3std4math3fmaFNaNbNiNfeeeZe" , &eval_fma);
423
-
424
- // @trusted @nogc pure nothrow bool function(T)
425
- add_builtin(" _D3std4math__T5isNaNTeZQjFNaNbNiNeeZb" , &eval_isnan);
426
- add_builtin(" _D3std4math__T5isNaNTdZQjFNaNbNiNedZb" , &eval_isnan);
427
- add_builtin(" _D3std4math__T5isNaNTfZQjFNaNbNiNefZb" , &eval_isnan);
428
- add_builtin(" _D3std4math__T10isInfinityTeZQpFNaNbNiNeeZb" , &eval_isinfinity);
429
- add_builtin(" _D3std4math__T10isInfinityTdZQpFNaNbNiNedZb" , &eval_isinfinity);
430
- add_builtin(" _D3std4math__T10isInfinityTfZQpFNaNbNiNefZb" , &eval_isinfinity);
431
- add_builtin(" _D3std4math__T8isFiniteTeZQmFNaNbNiNeeZb" , &eval_isfinite);
432
- add_builtin(" _D3std4math__T8isFiniteTdZQmFNaNbNiNedZb" , &eval_isfinite);
433
- add_builtin(" _D3std4math__T8isFiniteTfZQmFNaNbNiNefZb" , &eval_isfinite);
434
-
435
- // @safe @nogc pure nothrow int function(uint)
436
- add_builtin(" _D4core5bitop3bsfFNaNbNiNfkZi" , &eval_bsf);
437
- add_builtin(" _D4core5bitop3bsrFNaNbNiNfkZi" , &eval_bsr);
438
- // @safe @nogc pure nothrow int function(ulong)
439
- add_builtin(" _D4core5bitop3bsfFNaNbNiNfmZi" , &eval_bsf);
440
- add_builtin(" _D4core5bitop3bsrFNaNbNiNfmZi" , &eval_bsr);
441
- // @safe @nogc pure nothrow uint function(uint)
442
- add_builtin(" _D4core5bitop5bswapFNaNbNiNfkZk" , &eval_bswap);
443
- // @safe @nogc pure nothrow int function(uint)
444
- add_builtin(" _D4core5bitop7_popcntFNaNbNiNfkZi" , &eval_popcnt);
445
- // @safe @nogc pure nothrow ushort function(ushort)
446
- add_builtin(" _D4core5bitop7_popcntFNaNbNiNftZt" , &eval_popcnt);
447
- // @safe @nogc pure nothrow int function(ulong)
448
- if (global.params.is64bit)
449
- add_builtin(" _D4core5bitop7_popcntFNaNbNiNfmZi" , &eval_popcnt);
450
-
451
- // pure nothrow @nogc @safe float core.math.toPrec!(float).toPrec(float)
452
- add_builtin(" _D4core4math__T6toPrecHTfZQlFNaNbNiNffZf" , &eval_toPrecFloat);
453
- // pure nothrow @nogc @safe float core.math.toPrec!(float).toPrec(double)
454
- add_builtin(" _D4core4math__T6toPrecHTfZQlFNaNbNiNfdZf" , &eval_toPrecFloat);
455
- // pure nothrow @nogc @safe float core.math.toPrec!(float).toPrec(real)
456
- add_builtin(" _D4core4math__T6toPrecHTfZQlFNaNbNiNfeZf" , &eval_toPrecFloat);
457
- // pure nothrow @nogc @safe double core.math.toPrec!(double).toPrec(float)
458
- add_builtin(" _D4core4math__T6toPrecHTdZQlFNaNbNiNffZd" , &eval_toPrecDouble);
459
- // pure nothrow @nogc @safe double core.math.toPrec!(double).toPrec(double)
460
- add_builtin(" _D4core4math__T6toPrecHTdZQlFNaNbNiNfdZd" , &eval_toPrecDouble);
461
- // pure nothrow @nogc @safe double core.math.toPrec!(double).toPrec(real)
462
- add_builtin(" _D4core4math__T6toPrecHTdZQlFNaNbNiNfeZd" , &eval_toPrecDouble);
463
- // pure nothrow @nogc @safe double core.math.toPrec!(real).toPrec(float)
464
- add_builtin(" _D4core4math__T6toPrecHTeZQlFNaNbNiNffZe" , &eval_toPrecReal);
465
- // pure nothrow @nogc @safe double core.math.toPrec!(real).toPrec(double)
466
- add_builtin(" _D4core4math__T6toPrecHTeZQlFNaNbNiNfdZe" , &eval_toPrecReal);
467
- // pure nothrow @nogc @safe double core.math.toPrec!(real).toPrec(real)
468
- add_builtin(" _D4core4math__T6toPrecHTeZQlFNaNbNiNfeZe" , &eval_toPrecReal);
469
- }
470
-
471
- /**
472
- * Deinitializes the global state of the compiler.
473
- *
474
- * This can be used to restore the state set by `builtin_init` to its original
475
- * state.
476
- */
477
- public void builtinDeinitialize ()
478
- {
479
- builtins = builtins.init;
480
- }
481
-
482
- /* *********************************
483
- * Determine if function is a builtin one that we can
484
- * evaluate at compile time.
485
- */
486
- public extern (C++ ) BUILTIN isBuiltin(FuncDeclaration fd)
487
- {
488
- if (fd.builtin == BUILTIN .unknown)
489
- {
490
- builtin_fp fp = builtin_lookup(mangleExact(fd));
491
- fd.builtin = fp ? BUILTIN .yes : BUILTIN .no;
492
- }
493
- return fd.builtin;
494
- }
495
-
496
- /* *************************************
497
- * Evaluate builtin function.
498
- * Return result; NULL if cannot evaluate it.
499
- */
500
- public extern (C++ ) Expression eval_builtin(Loc loc, FuncDeclaration fd, Expressions* arguments)
501
- {
502
- if (fd.builtin == BUILTIN .yes)
503
- {
504
- builtin_fp fp = builtin_lookup(mangleExact(fd));
505
- assert (fp);
506
- return fp (loc, fd, arguments);
507
- }
508
- return null ;
509
- }
0 commit comments