]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/d-lang.cc
d: Merge upstream dmd, druntime 4c18eed967, phobos d945686a4.
[thirdparty/gcc.git] / gcc / d / d-lang.cc
1 /* d-lang.cc -- Language-dependent hooks for D.
2 Copyright (C) 2006-2023 Free Software Foundation, Inc.
3
4 GCC is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GCC is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GCC; see the file COPYING3. If not see
16 <http://www.gnu.org/licenses/>. */
17
18 #include "config.h"
19 #include "system.h"
20 #include "coretypes.h"
21
22 #include "dmd/aggregate.h"
23 #include "dmd/cond.h"
24 #include "dmd/declaration.h"
25 #include "dmd/doc.h"
26 #include "dmd/errors.h"
27 #include "dmd/expression.h"
28 #include "dmd/hdrgen.h"
29 #include "dmd/id.h"
30 #include "dmd/identifier.h"
31 #include "dmd/json.h"
32 #include "dmd/mangle.h"
33 #include "dmd/module.h"
34 #include "dmd/mtype.h"
35 #include "dmd/target.h"
36 #include "dmd/template.h"
37
38 #include "opts.h"
39 #include "alias.h"
40 #include "tree.h"
41 #include "diagnostic.h"
42 #include "fold-const.h"
43 #include "toplev.h"
44 #include "langhooks.h"
45 #include "langhooks-def.h"
46 #include "target.h"
47 #include "function.h"
48 #include "stringpool.h"
49 #include "stor-layout.h"
50 #include "varasm.h"
51 #include "output.h"
52 #include "print-tree.h"
53 #include "debug.h"
54 #include "input.h"
55
56 #include "d-tree.h"
57 #include "d-frontend.h"
58
59
60 /* Array of D frontend type/decl nodes. */
61 tree d_global_trees[DTI_MAX];
62
63 /* True if compilation is currently inside the D frontend semantic passes. */
64 bool doing_semantic_analysis_p = false;
65
66 /* Options handled by the compiler that are separate from the frontend. */
67 struct d_option_data
68 {
69 const char *fonly; /* -fonly=<arg> */
70 const char *multilib; /* -imultilib <dir> */
71 const char *prefix; /* -iprefix <dir> */
72
73 bool deps; /* -M */
74 bool deps_skip_system; /* -MM */
75 const char *deps_filename; /* -M[M]D */
76 const char *deps_filename_user; /* -MF <arg> */
77 vec <const char *> deps_target; /* -M[QT] <arg> */
78 bool deps_phony; /* -MP */
79
80 bool stdinc; /* -nostdinc */
81 }
82 d_option;
83
84 /* List of modules being compiled. */
85 static Modules builtin_modules;
86
87 /* The current and global binding level in effect. */
88 struct binding_level *current_binding_level;
89 struct binding_level *global_binding_level;
90
91 /* The context to be used for global declarations. */
92 static GTY(()) tree global_context;
93
94 /* Array of all global declarations to pass back to the middle-end. */
95 static GTY(()) vec <tree, va_gc> *global_declarations;
96
97 /* Support for GCC-style command-line make dependency generation.
98 Adds TARGET to the make dependencies target buffer.
99 QUOTED is true if the string should be quoted. */
100
101 static void
102 deps_add_target (const char *target, bool quoted)
103 {
104 obstack buffer;
105 gcc_obstack_init (&buffer);
106
107 if (!quoted)
108 {
109 obstack_grow0 (&buffer, target, strlen (target));
110 d_option.deps_target.safe_push ((const char *) obstack_finish (&buffer));
111 return;
112 }
113
114 /* Quote characters in target which are significant to Make. */
115 unsigned slashes = 0;
116
117 for (const char *p = target; *p != '\0'; p++)
118 {
119 switch (*p)
120 {
121 case '\\':
122 slashes++;
123 break;
124
125 case ' ':
126 case '\t':
127 while (slashes--)
128 obstack_1grow (&buffer, '\\');
129 obstack_1grow (&buffer, '\\');
130 goto Ldef;
131
132 case '$':
133 obstack_1grow (&buffer, '$');
134 goto Ldef;
135
136 case '#':
137 case ':':
138 obstack_1grow (&buffer, '\\');
139 goto Ldef;
140
141 default:
142 Ldef:
143 slashes = 0;
144 break;
145 }
146
147 obstack_1grow (&buffer, *p);
148 }
149
150 obstack_1grow (&buffer, '\0');
151 d_option.deps_target.safe_push ((const char *) obstack_finish (&buffer));
152 }
153
154 /* Write STR, with a leading space to BUFFER, updating COLUMN as appropriate.
155 COLMAX is the number of columns to word-wrap at (0 means don't wrap). */
156
157 static void
158 deps_write_string (const char *str, obstack *buffer, unsigned &column,
159 unsigned colmax = 72)
160 {
161 unsigned size = strlen (str);
162
163 if (column != 0)
164 {
165 if (colmax && column + size > colmax)
166 {
167 obstack_grow (buffer, " \\\n ", 4);
168 column = 1;
169 }
170 else
171 {
172 obstack_1grow (buffer, ' ');
173 column++;
174 }
175 }
176
177 column += size;
178 obstack_grow (buffer, str, size);
179 }
180
181 /* Write out all dependencies of a given MODULE to the specified BUFFER. */
182
183 static void
184 deps_write (Module *module, obstack *buffer)
185 {
186 hash_set <const char *> seen_modules;
187 vec <const char *> dependencies = vNULL;
188
189 Modules modlist;
190 modlist.push (module);
191
192 vec <const char *> phonylist = vNULL;
193 unsigned column = 0;
194
195 /* Write out make target module name. */
196 if (d_option.deps_target.length ())
197 {
198 for (unsigned i = 0; i < d_option.deps_target.length (); i++)
199 deps_write_string (d_option.deps_target[i], buffer, column);
200 }
201 else
202 deps_write_string (module->objfile.toChars (), buffer, column);
203
204 obstack_1grow (buffer, ':');
205 column++;
206
207 /* Search all modules for file dependencies. */
208 while (modlist.length > 0)
209 {
210 Module *depmod = modlist.pop ();
211
212 const char *modstr = depmod->srcfile.toChars ();
213
214 /* Skip modules that have already been looked at. */
215 if (seen_modules.add (modstr))
216 continue;
217
218 dependencies.safe_push (modstr);
219
220 /* Add to list of phony targets if is not being compile. */
221 if (d_option.deps_phony && !depmod->isRoot ())
222 phonylist.safe_push (modstr);
223
224 /* Add imported files to dependency list. */
225 for (size_t i = 0; i < depmod->contentImportedFiles.length; i++)
226 {
227 const char *impstr = depmod->contentImportedFiles[i];
228 dependencies.safe_push (impstr);
229 phonylist.safe_push (impstr);
230 }
231
232 /* Search all imports of the module. */
233 for (size_t i = 0; i < depmod->aimports.length; i++)
234 {
235 Module *m = depmod->aimports[i];
236
237 /* Ignore compiler-generated modules. */
238 if (m->ident == Identifier::idPool ("__main") && m->parent == NULL)
239 continue;
240
241 /* Don't search system installed modules, this includes
242 object, core.*, std.*, and gcc.* packages. */
243 if (d_option.deps_skip_system)
244 {
245 if (m->ident == Identifier::idPool ("object")
246 && m->parent == NULL)
247 continue;
248
249 if (m->md && m->md->packages.length)
250 {
251 Identifier *package = m->md->packages.ptr[0];
252
253 if (package == Identifier::idPool ("core")
254 || package == Identifier::idPool ("std")
255 || package == Identifier::idPool ("gcc"))
256 continue;
257 }
258 }
259
260 modlist.push (m);
261 }
262 }
263
264 /* Write out all make dependencies. */
265 for (size_t i = 0; i < dependencies.length (); i++)
266 deps_write_string (dependencies[i], buffer, column);
267
268 obstack_1grow (buffer, '\n');
269
270 /* Write out all phony targets. */
271 for (size_t i = 0; i < phonylist.length (); i++)
272 {
273 const char *str = phonylist[i];
274 obstack_1grow (buffer, '\n');
275 obstack_grow (buffer, str, strlen (str));
276 obstack_grow (buffer, ":\n", 2);
277 }
278
279 obstack_1grow (buffer, '\0');
280 }
281
282 /* Implements the lang_hooks.init_options routine for language D.
283 This initializes the global state for the D frontend before calling
284 the option handlers. */
285
286 static void
287 d_init_options (unsigned int, cl_decoded_option *decoded_options)
288 {
289 /* Initialize the D runtime. */
290 rt_init ();
291 gc_disable ();
292
293 /* Set default values. */
294 global._init ();
295
296 global.compileEnv.vendor = lang_hooks.name;
297 global.params.argv0 = xstrdup (decoded_options[0].arg);
298
299 /* Default extern(C++) mangling to C++17. */
300 global.params.cplusplus = CppStdRevisionCpp17;
301
302 /* Warnings and deprecations are disabled by default. */
303 global.params.useDeprecated = DIAGNOSTICinform;
304 global.params.warnings = DIAGNOSTICoff;
305 global.params.v.errorLimit = flag_max_errors;
306 global.params.v.messageStyle = MessageStyle::gnu;
307
308 global.params.imppath = d_gc_malloc<Strings> ();
309 global.params.fileImppath = d_gc_malloc<Strings> ();
310
311 /* Extra GDC-specific options. */
312 d_option.fonly = NULL;
313 d_option.multilib = NULL;
314 d_option.prefix = NULL;
315 d_option.deps = false;
316 d_option.deps_skip_system = false;
317 d_option.deps_filename = NULL;
318 d_option.deps_filename_user = NULL;
319 d_option.deps_target = vNULL;
320 d_option.deps_phony = false;
321 d_option.stdinc = true;
322 }
323
324 /* Implements the lang_hooks.init_options_struct routine for language D.
325 Initializes the options structure OPTS. */
326
327 static void
328 d_init_options_struct (gcc_options *opts)
329 {
330 /* GCC options. */
331 opts->x_flag_exceptions = 1;
332
333 /* Unlike C, there is no global `errno' variable. */
334 opts->x_flag_errno_math = 0;
335 opts->frontend_set_flag_errno_math = true;
336
337 /* D says that signed overflow is precisely defined. */
338 opts->x_flag_wrapv = 1;
339 }
340
341 /* Implements the lang_hooks.lang_mask routine for language D.
342 Returns language mask for option parsing. */
343
344 static unsigned int
345 d_option_lang_mask (void)
346 {
347 return CL_D;
348 }
349
350 /* Implements input charset and BOM skipping configuration for
351 diagnostics. */
352 static const char *d_input_charset_callback (const char * /*filename*/)
353 {
354 /* TODO: The input charset is automatically determined by code in
355 dmd/dmodule.c based on the contents of the file. If this detection
356 logic were factored out and could be reused here, then we would be able
357 to return UTF-16 or UTF-32 as needed here. For now, we return always
358 NULL, which means no conversion is necessary, i.e. the input is assumed
359 to be UTF-8 when diagnostics read this file. */
360 return nullptr;
361 }
362
363 /* Implements the lang_hooks.init routine for language D. */
364
365 static bool
366 d_init (void)
367 {
368 Type::_init ();
369 Id::initialize ();
370 Module::_init ();
371 Expression::_init ();
372 Objc::_init ();
373
374 /* Diagnostics input init, to enable BOM skipping and
375 input charset conversion. */
376 diagnostic_initialize_input_context (global_dc,
377 d_input_charset_callback, true);
378
379 /* Back-end init. */
380 global_binding_level = ggc_cleared_alloc <binding_level> ();
381 current_binding_level = global_binding_level;
382
383 /* This allows the code in d-builtins.cc to not have to worry about
384 converting (C signed char *) to (D char *) for string arguments of
385 built-in functions. The parameter (signed_char = false) specifies
386 whether char is signed. */
387 build_common_tree_nodes (false);
388
389 d_init_builtins ();
390
391 if (flag_exceptions)
392 using_eh_for_cleanups ();
393
394 if (!supports_one_only ())
395 flag_weak_templates = 0;
396
397 /* This is the C main, not the D main. */
398 main_identifier_node = get_identifier ("main");
399
400 target._init (global.params);
401 d_init_versions ();
402
403 /* Insert all library-configured identifiers and import paths. */
404 add_import_paths (d_option.prefix, d_option.multilib, d_option.stdinc);
405
406 return 1;
407 }
408
409 /* Implements the lang_hooks.init_ts routine for language D. */
410
411 static void
412 d_init_ts (void)
413 {
414 MARK_TS_TYPED (FLOAT_MOD_EXPR);
415 MARK_TS_TYPED (UNSIGNED_RSHIFT_EXPR);
416 }
417
418 /* Implements the lang_hooks.handle_option routine for language D.
419 Handles D specific options. Return false if we didn't do anything. */
420
421 static bool
422 d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
423 int kind ATTRIBUTE_UNUSED,
424 location_t loc ATTRIBUTE_UNUSED,
425 const cl_option_handlers *handlers ATTRIBUTE_UNUSED)
426 {
427 opt_code code = (opt_code) scode;
428 bool result = true;
429
430 switch (code)
431 {
432 case OPT_fall_instantiations:
433 global.params.allInst = value;
434 break;
435
436 case OPT_fassert:
437 global.params.useAssert = value ? CHECKENABLEon : CHECKENABLEoff;
438 break;
439
440 case OPT_fbounds_check:
441 global.params.useArrayBounds = value ? CHECKENABLEon : CHECKENABLEoff;
442 break;
443
444 case OPT_fbounds_check_:
445 global.params.useArrayBounds = (value == 2) ? CHECKENABLEon
446 : (value == 1) ? CHECKENABLEsafeonly : CHECKENABLEoff;
447 break;
448
449 case OPT_fcheckaction_:
450 global.params.checkAction = (value == 0) ? CHECKACTION_D
451 : (value == 1) ? CHECKACTION_halt : CHECKACTION_context;
452 break;
453
454 case OPT_fdebug:
455 global.params.debuglevel = value ? 1 : 0;
456 break;
457
458 case OPT_fdebug_:
459 if (Identifier::isValidIdentifier (CONST_CAST (char *, arg)))
460 {
461 DebugCondition::addGlobalIdent (arg);
462 break;
463 }
464
465 error ("bad argument for %<-fdebug%>: %qs", arg);
466 break;
467
468 case OPT_fdoc:
469 global.params.ddoc.doOutput = value;
470 break;
471
472 case OPT_fdoc_dir_:
473 global.params.ddoc.doOutput = true;
474 global.params.ddoc.dir = arg;
475 break;
476
477 case OPT_fdoc_file_:
478 global.params.ddoc.doOutput = true;
479 global.params.ddoc.name = arg;
480 break;
481
482 case OPT_fdoc_inc_:
483 global.params.ddoc.files.push (arg);
484 break;
485
486 case OPT_fdruntime:
487 global.params.betterC = !value;
488 break;
489
490 case OPT_fdump_c___spec_:
491 global.params.cxxhdr.doOutput = true;
492 global.params.cxxhdr.name = arg;
493 break;
494
495 case OPT_fdump_c___spec_verbose:
496 global.params.cxxhdr.fullOutput = true;
497 break;
498
499 case OPT_fdump_d_original:
500 global.params.vcg_ast = value;
501 break;
502
503 case OPT_fexceptions:
504 global.params.useExceptions = value;
505 break;
506
507 case OPT_fextern_std_:
508 switch (value)
509 {
510 case CppStdRevisionCpp98:
511 case CppStdRevisionCpp11:
512 case CppStdRevisionCpp14:
513 case CppStdRevisionCpp17:
514 case CppStdRevisionCpp20:
515 global.params.cplusplus = (CppStdRevision) value;
516 break;
517
518 default:
519 error ("bad argument for %<-fextern-std%>: %qs", arg);
520 }
521 break;
522
523 case OPT_fignore_unknown_pragmas:
524 global.params.ignoreUnsupportedPragmas = value;
525 break;
526
527 case OPT_finvariants:
528 global.params.useInvariants = value ? CHECKENABLEon : CHECKENABLEoff;
529 break;
530
531 case OPT_fmain:
532 global.params.addMain = value;
533 break;
534
535 case OPT_fmodule_file_:
536 global.params.modFileAliasStrings.push (arg);
537 if (!strchr (arg, '='))
538 error ("bad argument for %<-fmodule-file%>: %qs", arg);
539 break;
540
541 case OPT_fmoduleinfo:
542 global.params.useModuleInfo = value;
543 break;
544
545 case OPT_fonly_:
546 d_option.fonly = arg;
547 break;
548
549 case OPT_fpostconditions:
550 global.params.useOut = value ? CHECKENABLEon : CHECKENABLEoff;
551 break;
552
553 case OPT_fpreconditions:
554 global.params.useIn = value ? CHECKENABLEon : CHECKENABLEoff;
555 break;
556
557 case OPT_fpreview_all:
558 global.params.ehnogc = value;
559 global.params.useDIP1000 = FeatureState::enabled;
560 global.params.useDIP1021 = value;
561 global.params.bitfields = value;
562 global.params.dtorFields = FeatureState::enabled;
563 global.params.fieldwise = FeatureState::enabled;
564 global.params.fixAliasThis = value;
565 global.params.previewIn = value;
566 global.params.fix16997 = value;
567 global.params.noSharedAccess = FeatureState::enabled;
568 global.params.rvalueRefParam = FeatureState::enabled;
569 global.params.inclusiveInContracts = value;
570 global.params.systemVariables = FeatureState::enabled;
571 global.params.fixImmutableConv = value;
572 break;
573
574 case OPT_fpreview_bitfields:
575 global.params.bitfields = value;
576 break;
577
578 case OPT_fpreview_dip1000:
579 global.params.useDIP1000 = FeatureState::enabled;
580 break;
581
582 case OPT_fpreview_dip1008:
583 global.params.ehnogc = value;
584 break;
585
586 case OPT_fpreview_dip1021:
587 global.params.useDIP1021 = value;
588 break;
589
590 case OPT_fpreview_dtorfields:
591 global.params.dtorFields = FeatureState::enabled;
592 break;
593
594 case OPT_fpreview_fieldwise:
595 global.params.fieldwise = FeatureState::enabled;
596 break;
597
598 case OPT_fpreview_fixaliasthis:
599 global.params.fixAliasThis = value;
600 break;
601
602 case OPT_fpreview_fiximmutableconv:
603 global.params.fixImmutableConv = value;
604 break;
605
606 case OPT_fpreview_in:
607 global.params.previewIn = value;
608 break;
609
610 case OPT_fpreview_inclusiveincontracts:
611 global.params.inclusiveInContracts = value;
612 break;
613
614 case OPT_fpreview_nosharedaccess:
615 global.params.noSharedAccess = FeatureState::enabled;
616 break;
617
618 case OPT_fpreview_rvaluerefparam:
619 global.params.rvalueRefParam = FeatureState::enabled;
620 break;
621
622 case OPT_fpreview_systemvariables:
623 global.params.systemVariables = FeatureState::enabled;
624 break;
625
626 case OPT_frelease:
627 global.params.release = value;
628 break;
629
630 case OPT_frevert_all:
631 global.params.useDIP1000 = FeatureState::disabled;
632 global.params.dtorFields = FeatureState::disabled;
633 global.params.fix16997 = !value;
634 break;
635
636 case OPT_frevert_dip1000:
637 global.params.useDIP1000 = FeatureState::disabled;
638 break;
639
640 case OPT_frevert_dtorfields:
641 global.params.dtorFields = FeatureState::disabled;
642 break;
643
644 case OPT_frevert_intpromote:
645 global.params.fix16997 = !value;
646 break;
647
648 case OPT_frtti:
649 global.params.useTypeInfo = value;
650 break;
651
652 case OPT_fsave_mixins_:
653 global.params.mixinOut.doOutput = true;
654 global.params.mixinOut.name = arg;
655 global.params.mixinOut.buffer = d_gc_malloc<OutBuffer> ();
656 break;
657
658 case OPT_fswitch_errors:
659 global.params.useSwitchError = value ? CHECKENABLEon : CHECKENABLEoff;
660 break;
661
662 case OPT_ftransition_all:
663 global.params.v.field = value;
664 global.params.v.gc = value;
665 global.params.v.vin = value;
666 global.params.v.tls = value;
667 break;
668
669 case OPT_ftransition_field:
670 global.params.v.field = value;
671 break;
672
673 case OPT_ftransition_in:
674 global.params.v.vin = value;
675 break;
676
677 case OPT_ftransition_nogc:
678 global.params.v.gc = value;
679 break;
680
681 case OPT_ftransition_templates:
682 global.params.v.templates = value;
683 break;
684
685 case OPT_ftransition_tls:
686 global.params.v.tls = value;
687 break;
688
689 case OPT_funittest:
690 global.params.useUnitTests = value;
691 break;
692
693 case OPT_fversion_:
694 if (Identifier::isValidIdentifier (CONST_CAST (char *, arg)))
695 {
696 VersionCondition::addGlobalIdent (arg);
697 break;
698 }
699
700 error ("bad argument for %<-fversion%>: %qs", arg);
701 break;
702
703 case OPT_H:
704 global.params.dihdr.doOutput = true;
705 break;
706
707 case OPT_Hd:
708 global.params.dihdr.doOutput = true;
709 global.params.dihdr.dir = arg;
710 break;
711
712 case OPT_Hf:
713 global.params.dihdr.doOutput = true;
714 global.params.dihdr.name = arg;
715 break;
716
717 case OPT_imultilib:
718 d_option.multilib = arg;
719 break;
720
721 case OPT_iprefix:
722 d_option.prefix = arg;
723 break;
724
725 case OPT_I:
726 global.params.imppath->push (arg);
727 break;
728
729 case OPT_J:
730 global.params.fileImppath->push (arg);
731 break;
732
733 case OPT_MM:
734 d_option.deps_skip_system = true;
735 /* Fall through. */
736
737 case OPT_M:
738 d_option.deps = true;
739 break;
740
741 case OPT_MMD:
742 d_option.deps_skip_system = true;
743 /* Fall through. */
744
745 case OPT_MD:
746 d_option.deps = true;
747 d_option.deps_filename = arg;
748 break;
749
750 case OPT_MF:
751 /* If specified multiple times, last one wins. */
752 d_option.deps_filename_user = arg;
753 break;
754
755 case OPT_MP:
756 d_option.deps_phony = true;
757 break;
758
759 case OPT_MQ:
760 deps_add_target (arg, true);
761 break;
762
763 case OPT_MT:
764 deps_add_target (arg, false);
765 break;
766
767 case OPT_nostdinc:
768 d_option.stdinc = false;
769 break;
770
771 case OPT_v:
772 global.params.v.verbose = value;
773 break;
774
775 case OPT_Wall:
776 if (value)
777 global.params.warnings = DIAGNOSTICinform;
778 break;
779
780 case OPT_Wdeprecated:
781 global.params.useDeprecated = value ? DIAGNOSTICinform : DIAGNOSTICoff;
782 break;
783
784 case OPT_Werror:
785 if (value)
786 global.params.warnings = DIAGNOSTICerror;
787 break;
788
789 case OPT_Wspeculative:
790 if (value)
791 global.params.v.showGaggedErrors = 1;
792 break;
793
794 case OPT_Xf:
795 global.params.json.name = arg;
796 /* Fall through. */
797
798 case OPT_X:
799 global.params.json.doOutput = true;
800 break;
801
802 default:
803 break;
804 }
805
806 D_handle_option_auto (&global_options, &global_options_set,
807 scode, arg, value,
808 d_option_lang_mask (), kind,
809 loc, handlers, global_dc);
810
811 return result;
812 }
813
814 /* Implements the lang_hooks.post_options routine for language D.
815 Deal with any options that imply the turning on/off of features.
816 FN is the main input filename passed on the command line. */
817
818 static bool
819 d_post_options (const char ** fn)
820 {
821 /* Verify the input file name. */
822 const char *filename = *fn;
823 if (!filename || strcmp (filename, "-") == 0)
824 filename = "";
825
826 /* The front end considers the first input file to be the main one. */
827 *fn = filename;
828
829 /* Release mode doesn't turn off bounds checking for safe functions. */
830 if (global.params.useArrayBounds == CHECKENABLEdefault)
831 {
832 global.params.useArrayBounds = global.params.release
833 ? CHECKENABLEsafeonly : CHECKENABLEon;
834 }
835
836 /* Assert code is generated if unittests are being compiled also, even if
837 release mode is turned on. */
838 if (global.params.useAssert == CHECKENABLEdefault)
839 {
840 if (global.params.useUnitTests || !global.params.release)
841 global.params.useAssert = CHECKENABLEon;
842 else
843 global.params.useAssert = CHECKENABLEoff;
844 }
845
846 /* Checks for switches without a default are turned off in release mode. */
847 if (global.params.useSwitchError == CHECKENABLEdefault)
848 {
849 global.params.useSwitchError = global.params.release
850 ? CHECKENABLEoff : CHECKENABLEon;
851 }
852
853 /* Contracts are turned off in release mode. */
854 if (global.params.useInvariants == CHECKENABLEdefault)
855 {
856 global.params.useInvariants = global.params.release
857 ? CHECKENABLEoff : CHECKENABLEon;
858 }
859
860 if (global.params.useIn == CHECKENABLEdefault)
861 {
862 global.params.useIn = global.params.release
863 ? CHECKENABLEoff : CHECKENABLEon;
864 }
865
866 if (global.params.useOut == CHECKENABLEdefault)
867 {
868 global.params.useOut = global.params.release
869 ? CHECKENABLEoff : CHECKENABLEon;
870 }
871
872 /* When not linking against D runtime, turn off all code generation that
873 would otherwise reference it. */
874 if (global.params.betterC)
875 {
876 if (!OPTION_SET_P (flag_moduleinfo))
877 global.params.useModuleInfo = false;
878
879 /* Ensure that the front-end options are in sync with the `-frtti' and
880 `-fexceptions' flags. */
881 if (!OPTION_SET_P (flag_rtti))
882 {
883 global.params.useTypeInfo = false;
884 flag_rtti = false;
885 }
886
887 if (!OPTION_SET_P (flag_exceptions))
888 {
889 global.params.useExceptions = false;
890 flag_exceptions = false;
891 }
892
893 global.params.useGC = false;
894 global.params.checkAction = CHECKACTION_C;
895 }
896
897 /* Enabling DIP1021 implies DIP1000. */
898 if (global.params.useDIP1021)
899 global.params.useDIP1000 = FeatureState::enabled;
900
901 /* Keep in sync with existing -fbounds-check flag. */
902 flag_bounds_check = (global.params.useArrayBounds == CHECKENABLEon);
903
904 /* Turn off partitioning unless it was explicitly requested, as it doesn't
905 work with D exception chaining, where EH handler uses LSDA to determine
906 whether two thrown exception are in the same context. */
907 if (!OPTION_SET_P (flag_reorder_blocks_and_partition))
908 global_options.x_flag_reorder_blocks_and_partition = 0;
909
910 /* Error about use of deprecated features. */
911 if (global.params.useDeprecated == DIAGNOSTICinform
912 && global.params.warnings == DIAGNOSTICerror)
913 global.params.useDeprecated = DIAGNOSTICerror;
914
915 if (flag_excess_precision == EXCESS_PRECISION_DEFAULT)
916 flag_excess_precision = EXCESS_PRECISION_STANDARD;
917
918 global.params.useInline = flag_inline_functions;
919
920 /* Make -fmax-errors visible to frontend's diagnostic machinery. */
921 if (OPTION_SET_P (flag_max_errors))
922 global.params.v.errorLimit = flag_max_errors;
923
924 global.params.v.showColumns = flag_show_column;
925 global.params.v.printErrorContext = flag_diagnostics_show_caret;
926
927 /* Keep the front-end location type in sync with params. */
928 Loc::set (global.params.v.showColumns, global.params.v.messageStyle);
929
930 if (global.params.useInline)
931 global.params.dihdr.fullOutput = true;
932
933 global.params.obj = !flag_syntax_only;
934
935 /* The front-end parser only has access to `compileEnv', synchronize its
936 fields with params. */
937 global.compileEnv.previewIn = global.params.previewIn;
938 global.compileEnv.ddocOutput = global.params.ddoc.doOutput;
939 global.compileEnv.shortenedMethods = global.params.shortenedMethods;
940
941 if (warn_return_type == -1)
942 warn_return_type = 0;
943
944 return false;
945 }
946
947 /* Add the module M to the list of modules that may declare GCC builtins.
948 These are scanned after first semantic and before codegen passes.
949 See d_maybe_set_builtin() for the implementation. */
950
951 void
952 d_add_builtin_module (Module *m)
953 {
954 builtin_modules.push (m);
955 }
956
957 /* Writes to FILENAME. DATA is the full content of the file to be written. */
958
959 static void
960 d_write_file (const char *filename, const char *data)
961 {
962 FILE *stream;
963
964 if (filename && (filename[0] != '-' || filename[1] != '\0'))
965 stream = fopen (filename, "w");
966 else
967 stream = stdout;
968
969 if (!stream)
970 {
971 error ("unable to open %s for writing: %m", filename);
972 return;
973 }
974
975 fprintf (stream, "%s", data);
976
977 if (stream != stdout && (ferror (stream) || fclose (stream)))
978 error ("writing output file %s: %m", filename);
979 }
980
981 /* Read ddoc macro files named by the DDOCFILES, then write the concatenated
982 the contents into DDOCBUF. */
983
984 static void
985 d_read_ddoc_files (Strings &ddocfiles, OutBuffer &ddocbuf)
986 {
987 if (ddocbuf.length ())
988 return;
989
990 for (size_t i = 0; i < ddocfiles.length; i++)
991 {
992 int fd = open (ddocfiles[i], O_RDONLY);
993 bool ok = false;
994 struct stat buf;
995
996 if (fd == -1 || fstat (fd, &buf))
997 {
998 error ("unable to open %s for reading: %m", ddocfiles[i]);
999 continue;
1000 }
1001
1002 /* Check we've not been given a directory, or a file bigger than 4GB. */
1003 if (S_ISDIR (buf.st_mode))
1004 errno = ENOENT;
1005 else if (buf.st_size != unsigned (buf.st_size))
1006 errno = EMFILE;
1007 else
1008 {
1009 unsigned size = unsigned (buf.st_size);
1010 char *buffer = (char *) xmalloc (size);
1011
1012 if (read (fd, buffer, size) == ssize_t (size))
1013 {
1014 ddocbuf.write (buffer, size);
1015 ok = true;
1016 }
1017
1018 free (buffer);
1019 }
1020
1021 close (fd);
1022 if (!ok)
1023 fatal_error (input_location, "reading ddoc file %s: %m", ddocfiles[i]);
1024 }
1025 }
1026
1027 static void
1028 d_generate_ddoc_file (Module *m, OutBuffer &ddocbuf)
1029 {
1030 input_location = make_location_t (m->loc);
1031
1032 d_read_ddoc_files (global.params.ddoc.files, ddocbuf);
1033
1034 OutBuffer ddocbuf_out;
1035 gendocfile (m, ddocbuf.peekChars (), ddocbuf.length (), global.datetime,
1036 global.errorSink, ddocbuf_out);
1037
1038 d_write_file (m->docfile.toChars (), ddocbuf_out.peekChars ());
1039 }
1040
1041 /* Implements the lang_hooks.parse_file routine for language D. */
1042
1043 static void
1044 d_parse_file (void)
1045 {
1046 if (global.params.v.verbose)
1047 {
1048 message ("binary %s", global.params.argv0.ptr);
1049 message ("version %s", global.versionChars ());
1050
1051 if (global.versionids)
1052 {
1053 obstack buffer;
1054 gcc_obstack_init (&buffer);
1055 obstack_grow (&buffer, "predefs ", 9);
1056 for (size_t i = 0; i < global.versionids->length; i++)
1057 {
1058 Identifier *id = (*global.versionids)[i];
1059 const char *str = id->toChars ();
1060 obstack_1grow (&buffer, ' ');
1061 obstack_grow (&buffer, str, strlen (str));
1062 }
1063
1064 obstack_1grow (&buffer, '\0');
1065 message ("%s", (char *) obstack_finish (&buffer));
1066 }
1067 }
1068
1069 /* Start the main input file, if the debug writer wants it. */
1070 if (debug_hooks->start_end_main_source_file)
1071 debug_hooks->start_source_file (0, main_input_filename);
1072
1073 /* Create Module's for all sources we will load. */
1074 Modules modules;
1075 modules.reserve (num_in_fnames);
1076
1077 /* Buffer for contents of .ddoc files. */
1078 OutBuffer ddocbuf;
1079
1080 /* In this mode, the first file name is supposed to be a duplicate
1081 of one of the input files. */
1082 if (d_option.fonly && strcmp (d_option.fonly, main_input_filename) != 0)
1083 error ("%<-fonly=%> argument is different from first input file name");
1084
1085 for (size_t i = 0; i < num_in_fnames; i++)
1086 {
1087 if (strcmp (in_fnames[i], "-") == 0)
1088 {
1089 /* Load the entire contents of stdin into memory. 8 kilobytes should
1090 be a good enough initial size, but double on each iteration.
1091 16 bytes are added for the final '\n' and 15 bytes of padding. */
1092 ssize_t size = 8 * 1024;
1093 uchar *buffer = XNEWVEC (uchar, size + 16);
1094 ssize_t len = 0;
1095 ssize_t count;
1096
1097 while ((count = read (STDIN_FILENO, buffer + len, size - len)) > 0)
1098 {
1099 len += count;
1100 if (len == size)
1101 {
1102 size *= 2;
1103 buffer = XRESIZEVEC (uchar, buffer, size + 16);
1104 }
1105 }
1106
1107 if (count < 0)
1108 {
1109 error (Loc ("stdin", 0, 0), "%s", xstrerror (errno));
1110 free (buffer);
1111 continue;
1112 }
1113
1114 /* Handling stdin, generate a unique name for the module. */
1115 Module *m = Module::create (in_fnames[i],
1116 Identifier::idPool ("__stdin"),
1117 global.params.ddoc.doOutput,
1118 global.params.dihdr.doOutput);
1119 modules.push (m);
1120
1121 /* Zero the padding past the end of the buffer so the D lexer has a
1122 sentinel. The lexer only reads up to 4 bytes at a time. */
1123 memset (buffer + len, '\0', 16);
1124
1125 /* Overwrite the source file for the module, the one created by
1126 Module::create would have a forced a `.d' suffix. */
1127 m->src.length = len;
1128 m->src.ptr = buffer;
1129 }
1130 else
1131 {
1132 /* Handling a D source file, strip off the path and extension. */
1133 const char *basename = FileName::name (in_fnames[i]);
1134 const char *name = FileName::removeExt (basename);
1135
1136 Module *m = Module::create (in_fnames[i], Identifier::idPool (name),
1137 global.params.ddoc.doOutput,
1138 global.params.dihdr.doOutput);
1139 modules.push (m);
1140 FileName::free (name);
1141 }
1142 }
1143
1144 /* Read all D source files. */
1145 for (size_t i = 0; i < modules.length; i++)
1146 {
1147 Module *m = modules[i];
1148 m->read (Loc ());
1149 }
1150
1151 /* Parse all D source files. */
1152 for (size_t i = 0; i < modules.length; i++)
1153 {
1154 Module *m = modules[i];
1155
1156 if (global.params.v.verbose)
1157 message ("parse %s", m->toChars ());
1158
1159 if (!Module::rootModule)
1160 Module::rootModule = m;
1161
1162 m->importedFrom = m;
1163 m->parse ();
1164
1165 if (m->filetype == FileType::ddoc)
1166 {
1167 d_generate_ddoc_file (m, ddocbuf);
1168
1169 /* Remove M from list of modules. */
1170 modules.remove (i);
1171 i--;
1172 }
1173 }
1174
1175 /* Load the module containing D main. */
1176 Module *main_module = NULL;
1177 if (global.params.addMain)
1178 {
1179 unsigned errors = global.startGagging ();
1180 main_module = Module::load (Loc (), NULL, Identifier::idPool ("__main"));
1181
1182 if (!global.endGagging (errors))
1183 {
1184 main_module->importedFrom = main_module;
1185 modules.push (main_module);
1186 }
1187 }
1188
1189 /* If an error occurs later during compilation, remember that we generated
1190 the headers, so that they can be removed before exit. */
1191 bool dump_headers = false;
1192
1193 if (global.errors)
1194 goto had_errors;
1195
1196 if (global.params.dihdr.doOutput)
1197 {
1198 /* Generate 'header' import files. Since 'header' import files must be
1199 independent of command line switches and what else is imported, they
1200 are generated before any semantic analysis. */
1201 for (size_t i = 0; i < modules.length; i++)
1202 {
1203 Module *m = modules[i];
1204 if (m->filetype == FileType::dhdr
1205 || (d_option.fonly && m != Module::rootModule))
1206 continue;
1207
1208 if (global.params.v.verbose)
1209 message ("import %s", m->toChars ());
1210
1211 OutBuffer buf;
1212 genhdrfile (m, buf);
1213 d_write_file (m->hdrfile.toChars (), buf.peekChars ());
1214 }
1215
1216 dump_headers = true;
1217 }
1218
1219 if (global.errors)
1220 goto had_errors;
1221
1222 /* Load all unconditional imports for better symbol resolving. */
1223 for (size_t i = 0; i < modules.length; i++)
1224 {
1225 Module *m = modules[i];
1226
1227 if (global.params.v.verbose)
1228 message ("importall %s", m->toChars ());
1229
1230 m->importAll (NULL);
1231 }
1232
1233 if (global.errors)
1234 goto had_errors;
1235
1236 /* Do semantic analysis. */
1237 doing_semantic_analysis_p = true;
1238
1239 for (size_t i = 0; i < modules.length; i++)
1240 {
1241 Module *m = modules[i];
1242
1243 /* If this is the `__main` module, check that `D main` hasn't already
1244 been declared in user code before running semantic on it. */
1245 if (m == main_module && global.hasMainFunction)
1246 {
1247 modules.remove (i);
1248 continue;
1249 }
1250
1251 if (global.params.v.verbose)
1252 message ("semantic %s", m->toChars ());
1253
1254 dsymbolSemantic (m, NULL);
1255 }
1256
1257 /* Do deferred semantic analysis. */
1258 Module::runDeferredSemantic ();
1259
1260 if (Module::deferred.length)
1261 {
1262 for (size_t i = 0; i < Module::deferred.length; i++)
1263 {
1264 Dsymbol *sd = Module::deferred[i];
1265 error_at (make_location_t (sd->loc),
1266 "unable to resolve forward reference in definition");
1267 }
1268 }
1269
1270 /* Process all built-in modules or functions now for CTFE. */
1271 while (builtin_modules.length != 0)
1272 {
1273 Module *m = builtin_modules.pop ();
1274 d_maybe_set_builtin (m);
1275 }
1276
1277 /* Do pass 2 semantic analysis. */
1278 for (size_t i = 0; i < modules.length; i++)
1279 {
1280 Module *m = modules[i];
1281
1282 if (global.params.v.verbose)
1283 message ("semantic2 %s", m->toChars ());
1284
1285 semantic2 (m, NULL);
1286 }
1287
1288 Module::runDeferredSemantic2 ();
1289
1290 if (global.errors)
1291 goto had_errors;
1292
1293 /* Do pass 3 semantic analysis. */
1294 for (size_t i = 0; i < modules.length; i++)
1295 {
1296 Module *m = modules[i];
1297
1298 if (global.params.v.verbose)
1299 message ("semantic3 %s", m->toChars ());
1300
1301 semantic3 (m, NULL);
1302 }
1303
1304 Module::runDeferredSemantic3 ();
1305
1306 /* Check again, incase semantic3 pass loaded any more modules. */
1307 while (builtin_modules.length != 0)
1308 {
1309 Module *m = builtin_modules.pop ();
1310 d_maybe_set_builtin (m);
1311 }
1312
1313 /* Do not attempt to generate output files if errors or warnings occurred. */
1314 if (global.errors || global.warnings)
1315 goto had_errors;
1316
1317 /* Generate output files. */
1318 doing_semantic_analysis_p = false;
1319
1320 if (Module::rootModule)
1321 {
1322 /* Declare the name of the root module as the first global name in order
1323 to make the middle-end fully deterministic. */
1324 OutBuffer buf;
1325 mangleToBuffer (Module::rootModule, buf);
1326 first_global_object_name = buf.extractChars ();
1327 }
1328
1329 /* Make dependencies. */
1330 if (d_option.deps)
1331 {
1332 obstack buffer;
1333 gcc_obstack_init (&buffer);
1334
1335 for (size_t i = 0; i < modules.length; i++)
1336 deps_write (modules[i], &buffer);
1337
1338 /* -MF <arg> overrides -M[M]D. */
1339 if (d_option.deps_filename_user)
1340 d_option.deps_filename = d_option.deps_filename_user;
1341
1342 d_write_file (d_option.deps_filename,
1343 (char *) obstack_finish (&buffer));
1344 }
1345
1346 if (global.params.v.templates)
1347 printTemplateStats ();
1348
1349 /* Generate JSON files. */
1350 if (global.params.json.doOutput)
1351 {
1352 OutBuffer buf;
1353 json_generate (modules, buf);
1354 d_write_file (global.params.json.name.ptr, buf.peekChars ());
1355 }
1356
1357 /* Generate Ddoc files. */
1358 if (global.params.ddoc.doOutput && !global.errors && !errorcount)
1359 {
1360 for (size_t i = 0; i < modules.length; i++)
1361 {
1362 Module *m = modules[i];
1363 d_generate_ddoc_file (m, ddocbuf);
1364 }
1365 }
1366
1367 /* Handle -fdump-d-original. */
1368 if (global.params.vcg_ast)
1369 {
1370 for (size_t i = 0; i < modules.length; i++)
1371 {
1372 Module *m = modules[i];
1373 OutBuffer buf;
1374 buf.doindent = 1;
1375
1376 moduleToBuffer (buf, m);
1377 message ("%s", buf.peekChars ());
1378 }
1379 }
1380
1381 /* Generate C++ header files. */
1382 if (global.params.cxxhdr.doOutput)
1383 genCppHdrFiles (modules);
1384
1385 if (global.errors)
1386 goto had_errors;
1387
1388 for (size_t i = 0; i < modules.length; i++)
1389 {
1390 Module *m = modules[i];
1391
1392 /* Skip generating code for header files, or when the module wasn't
1393 specified by `-fonly=`. */
1394 if ((m->filetype == FileType::dhdr && m != main_module)
1395 || (d_option.fonly && m != Module::rootModule))
1396 continue;
1397
1398 if (global.params.v.verbose)
1399 message ("code %s", m->toChars ());
1400
1401 if (!flag_syntax_only)
1402 build_decl_tree (m);
1403 }
1404
1405 /* And end the main input file, if the debug writer wants it. */
1406 if (debug_hooks->start_end_main_source_file)
1407 debug_hooks->end_source_file (0);
1408
1409 had_errors:
1410 /* Add the D frontend error count to the GCC error count to correctly
1411 exit with an error status. */
1412 errorcount += (global.errors + global.warnings);
1413
1414 /* We want to write the mixin expansion file also on error. */
1415 if (global.params.mixinOut.doOutput)
1416 {
1417 d_write_file (global.params.mixinOut.name.ptr,
1418 global.params.mixinOut.buffer->peekChars ());
1419 }
1420
1421 /* Remove generated .di files on error. */
1422 if (errorcount && dump_headers)
1423 {
1424 for (size_t i = 0; i < modules.length; i++)
1425 {
1426 Module *m = modules[i];
1427 if (m->filetype == FileType::dhdr
1428 || (d_option.fonly && m != Module::rootModule))
1429 continue;
1430
1431 remove (m->hdrfile.toChars ());
1432 }
1433 }
1434
1435 /* Write out globals. */
1436 d_finish_compilation (vec_safe_address (global_declarations),
1437 vec_safe_length (global_declarations));
1438 }
1439
1440 /* Implements the lang_hooks.types.type_for_mode routine for language D. */
1441
1442 static tree
1443 d_type_for_mode (machine_mode mode, int unsignedp)
1444 {
1445 if (mode == QImode)
1446 return unsignedp ? d_ubyte_type : d_byte_type;
1447
1448 if (mode == HImode)
1449 return unsignedp ? d_ushort_type : d_short_type;
1450
1451 if (mode == SImode)
1452 return unsignedp ? d_uint_type : d_int_type;
1453
1454 if (mode == DImode)
1455 return unsignedp ? d_ulong_type : d_long_type;
1456
1457 if (mode == TYPE_MODE (d_cent_type))
1458 return unsignedp ? d_ucent_type : d_cent_type;
1459
1460 if (mode == TYPE_MODE (float_type_node))
1461 return float_type_node;
1462
1463 if (mode == TYPE_MODE (double_type_node))
1464 return double_type_node;
1465
1466 if (mode == TYPE_MODE (long_double_type_node))
1467 return long_double_type_node;
1468
1469 if (mode == TYPE_MODE (build_pointer_type (char8_type_node)))
1470 return build_pointer_type (char8_type_node);
1471
1472 if (mode == TYPE_MODE (build_pointer_type (d_int_type)))
1473 return build_pointer_type (d_int_type);
1474
1475 for (int i = 0; i < NUM_INT_N_ENTS; i ++)
1476 {
1477 if (int_n_enabled_p[i] && mode == int_n_data[i].m)
1478 {
1479 if (unsignedp)
1480 return int_n_trees[i].unsigned_type;
1481 else
1482 return int_n_trees[i].signed_type;
1483 }
1484 }
1485
1486 if (COMPLEX_MODE_P (mode))
1487 {
1488 machine_mode inner_mode;
1489 tree inner_type;
1490
1491 if (mode == TYPE_MODE (complex_float_type_node))
1492 return complex_float_type_node;
1493 if (mode == TYPE_MODE (complex_double_type_node))
1494 return complex_double_type_node;
1495 if (mode == TYPE_MODE (complex_long_double_type_node))
1496 return complex_long_double_type_node;
1497
1498 inner_mode = (machine_mode) GET_MODE_INNER (mode);
1499 inner_type = d_type_for_mode (inner_mode, unsignedp);
1500 if (inner_type != NULL_TREE)
1501 return build_complex_type (inner_type);
1502 }
1503 else if (VECTOR_MODE_P (mode))
1504 {
1505 machine_mode inner_mode = (machine_mode) GET_MODE_INNER (mode);
1506 tree inner_type = d_type_for_mode (inner_mode, unsignedp);
1507 if (inner_type != NULL_TREE)
1508 return build_vector_type_for_mode (inner_type, mode);
1509 }
1510
1511 return 0;
1512 }
1513
1514 /* Implements the lang_hooks.types.type_for_size routine for language D. */
1515
1516 static tree
1517 d_type_for_size (unsigned bits, int unsignedp)
1518 {
1519 if (bits <= TYPE_PRECISION (d_byte_type))
1520 return unsignedp ? d_ubyte_type : d_byte_type;
1521
1522 if (bits <= TYPE_PRECISION (d_short_type))
1523 return unsignedp ? d_ushort_type : d_short_type;
1524
1525 if (bits <= TYPE_PRECISION (d_int_type))
1526 return unsignedp ? d_uint_type : d_int_type;
1527
1528 if (bits <= TYPE_PRECISION (d_long_type))
1529 return unsignedp ? d_ulong_type : d_long_type;
1530
1531 if (bits <= TYPE_PRECISION (d_cent_type))
1532 return unsignedp ? d_ucent_type : d_cent_type;
1533
1534 for (int i = 0; i < NUM_INT_N_ENTS; i ++)
1535 {
1536 if (int_n_enabled_p[i] && bits == int_n_data[i].bitsize)
1537 {
1538 if (unsignedp)
1539 return int_n_trees[i].unsigned_type;
1540 else
1541 return int_n_trees[i].signed_type;
1542 }
1543 }
1544
1545 return 0;
1546 }
1547
1548 /* Implements the lang_hooks.types.type_promotes_to routine for language D. */
1549
1550 static tree
1551 d_type_promotes_to (tree type)
1552 {
1553 /* Promotions are only applied on unnamed function arguments for declarations
1554 with `extern(C)' or `extern(C++)' linkage. */
1555 if (cfun && DECL_LANG_FRONTEND (cfun->decl)
1556 && DECL_LANG_FRONTEND (cfun->decl)->resolvedLinkage () != LINK::d)
1557 {
1558 /* In [type/integer-promotions], integer promotions are conversions of the
1559 following types:
1560
1561 bool int
1562 byte int
1563 ubyte int
1564 short int
1565 ushort int
1566 char int
1567 wchar int
1568 dchar uint
1569
1570 If an enum has as a base type one of the types in the left column, it
1571 is converted to the type in the right column. */
1572 if (TREE_CODE (type) == ENUMERAL_TYPE && ENUM_IS_SCOPED (type))
1573 type = TREE_TYPE (type);
1574
1575 type = TYPE_MAIN_VARIANT (type);
1576
1577 /* Check for promotions of target-defined types first. */
1578 tree promoted_type = targetm.promoted_type (type);
1579 if (promoted_type)
1580 return promoted_type;
1581
1582 if (TREE_CODE (type) == BOOLEAN_TYPE)
1583 return d_int_type;
1584
1585 if (INTEGRAL_TYPE_P (type))
1586 {
1587 if (type == d_byte_type || type == d_ubyte_type
1588 || type == d_short_type || type == d_ushort_type
1589 || type == char8_type_node || type == char16_type_node)
1590 return d_int_type;
1591
1592 if (type == char32_type_node)
1593 return d_uint_type;
1594
1595 if (TYPE_PRECISION (type) < TYPE_PRECISION (d_int_type))
1596 return d_int_type;
1597 }
1598
1599 /* Float arguments are converted to doubles. */
1600 if (type == float_type_node)
1601 return double_type_node;
1602
1603 if (type == ifloat_type_node)
1604 return idouble_type_node;
1605 }
1606
1607 return type;
1608 }
1609
1610 /* Implements the lang_hooks.decls.global_bindings_p routine for language D.
1611 Return true if we are in the global binding level. */
1612
1613 static bool
1614 d_global_bindings_p (void)
1615 {
1616 return (current_binding_level == global_binding_level);
1617 }
1618
1619 /* Return global_context, but create it first if need be. */
1620
1621 static tree
1622 get_global_context (void)
1623 {
1624 if (!global_context)
1625 {
1626 global_context = build_translation_unit_decl (NULL_TREE);
1627 debug_hooks->register_main_translation_unit (global_context);
1628 }
1629
1630 return global_context;
1631 }
1632
1633 /* Implements the lang_hooks.decls.pushdecl routine for language D.
1634 Record DECL as belonging to the current lexical scope. */
1635
1636 tree
1637 d_pushdecl (tree decl)
1638 {
1639 /* Set the context of the decl. If current_function_decl did not help in
1640 determining the context, use global scope. */
1641 if (!DECL_CONTEXT (decl))
1642 {
1643 if (current_function_decl)
1644 DECL_CONTEXT (decl) = current_function_decl;
1645 else
1646 DECL_CONTEXT (decl) = get_global_context ();
1647 }
1648
1649 /* Put decls on list in reverse order. */
1650 if (TREE_STATIC (decl) || d_global_bindings_p ())
1651 vec_safe_push (global_declarations, decl);
1652 else
1653 {
1654 TREE_CHAIN (decl) = current_binding_level->names;
1655 current_binding_level->names = decl;
1656 }
1657
1658 return decl;
1659 }
1660
1661 /* Implements the lang_hooks.decls.getdecls routine for language D.
1662 Return the list of declarations of the current level. */
1663
1664 static tree
1665 d_getdecls (void)
1666 {
1667 if (current_binding_level)
1668 return current_binding_level->names;
1669
1670 return NULL_TREE;
1671 }
1672
1673
1674 /* Implements the lang_hooks.get_alias_set routine for language D.
1675 Get the alias set corresponding to type or expression T.
1676 Return -1 if we don't do anything special. */
1677
1678 static alias_set_type
1679 d_get_alias_set (tree)
1680 {
1681 /* For now in D, assume everything aliases everything else, until we define
1682 some solid rules backed by a specification. There are also some parts
1683 of code generation routines that don't adhere to C alias rules, such as
1684 build_vconvert. In any case, a lot of user code already assumes there
1685 is no strict aliasing and will break if we were to change that. */
1686 return 0;
1687 }
1688
1689 /* Implements the lang_hooks.types_compatible_p routine for language D.
1690 Compares two types for equivalence in the D programming language.
1691 This routine should only return 1 if it is sure, even though the frontend
1692 should have already ensured that all types are compatible before handing
1693 over the parsed ASTs to the code generator. */
1694
1695 static int
1696 d_types_compatible_p (tree x, tree y)
1697 {
1698 Type *tx = TYPE_LANG_FRONTEND (x);
1699 Type *ty = TYPE_LANG_FRONTEND (y);
1700
1701 /* Try validating the types in the frontend. */
1702 if (tx != NULL && ty != NULL)
1703 {
1704 /* Types are equivalent. */
1705 if (same_type_p (tx, ty))
1706 return true;
1707
1708 /* Type system allows implicit conversion between. */
1709 if (tx->implicitConvTo (ty) != MATCH::nomatch
1710 || ty->implicitConvTo (tx) != MATCH::nomatch)
1711 return true;
1712 }
1713
1714 /* Fallback on using type flags for comparison. E.g: all dynamic arrays
1715 are distinct types in D, but are VIEW_CONVERT compatible. */
1716 if (TREE_CODE (x) == RECORD_TYPE && TREE_CODE (y) == RECORD_TYPE)
1717 {
1718 if (TYPE_DYNAMIC_ARRAY (x) && TYPE_DYNAMIC_ARRAY (y))
1719 return true;
1720
1721 if (TYPE_DELEGATE (x) && TYPE_DELEGATE (y))
1722 return true;
1723
1724 if (TYPE_ASSOCIATIVE_ARRAY (x) && TYPE_ASSOCIATIVE_ARRAY (y))
1725 return true;
1726 }
1727
1728 return false;
1729 }
1730
1731 /* Implements the lang_hooks.finish_incomplete_decl routine for language D. */
1732
1733 static void
1734 d_finish_incomplete_decl (tree decl)
1735 {
1736 if (VAR_P (decl))
1737 {
1738 /* D allows zero-length declarations. Such a declaration ends up with
1739 DECL_SIZE (t) == NULL_TREE which is what the back-end function
1740 assembler_variable checks. This could change in later versions, or
1741 maybe all of these variables should be aliased to one symbol. */
1742 if (DECL_SIZE (decl) == 0)
1743 {
1744 DECL_SIZE (decl) = bitsize_zero_node;
1745 DECL_SIZE_UNIT (decl) = size_zero_node;
1746 }
1747 }
1748 }
1749
1750 /* Implements the lang_hooks.types.classify_record routine for language D.
1751 Return the true debug type for TYPE. */
1752
1753 static classify_record
1754 d_classify_record (tree type)
1755 {
1756 Type *t = TYPE_LANG_FRONTEND (type);
1757 TypeClass *tc = t ? t->isTypeClass () : NULL;
1758
1759 if (tc != NULL)
1760 {
1761 /* extern(C++) interfaces get emitted as classes. */
1762 if (tc->sym->isInterfaceDeclaration ()
1763 && !tc->sym->isCPPinterface ())
1764 return RECORD_IS_INTERFACE;
1765
1766 return RECORD_IS_CLASS;
1767 }
1768
1769 return RECORD_IS_STRUCT;
1770 }
1771
1772 /* Implements the lang_hooks.tree_size routine for language D.
1773 Determine the size of our tcc_constant or tcc_exceptional nodes. */
1774
1775 static size_t
1776 d_tree_size (tree_code code)
1777 {
1778 switch (code)
1779 {
1780 case FUNCFRAME_INFO:
1781 return sizeof (tree_frame_info);
1782
1783 default:
1784 gcc_unreachable ();
1785 }
1786 }
1787
1788 /* Implements the lang_hooks.print_xnode routine for language D. */
1789
1790 static void
1791 d_print_xnode (FILE *file, tree node, int indent)
1792 {
1793 switch (TREE_CODE (node))
1794 {
1795 case FUNCFRAME_INFO:
1796 print_node (file, "frame_type", FRAMEINFO_TYPE (node), indent + 4);
1797 break;
1798
1799 default:
1800 break;
1801 }
1802 }
1803
1804 /* Return which tree structure is used by NODE, or TS_D_GENERIC if NODE
1805 is one of the language-independent trees. */
1806
1807 d_tree_node_structure_enum
1808 d_tree_node_structure (lang_tree_node *t)
1809 {
1810 switch (TREE_CODE (&t->generic))
1811 {
1812 case IDENTIFIER_NODE:
1813 return TS_D_IDENTIFIER;
1814
1815 case FUNCFRAME_INFO:
1816 return TS_D_FRAMEINFO;
1817
1818 default:
1819 return TS_D_GENERIC;
1820 }
1821 }
1822
1823 /* Allocate and return a lang specific structure for the frontend type. */
1824
1825 struct lang_type *
1826 build_lang_type (Type *t)
1827 {
1828 struct lang_type *lt = ggc_cleared_alloc <struct lang_type> ();
1829 lt->type = t;
1830 return lt;
1831 }
1832
1833 /* Allocate and return a lang specific structure for the frontend decl. */
1834
1835 struct lang_decl *
1836 build_lang_decl (Declaration *d)
1837 {
1838 /* For compiler generated run-time typeinfo, a lang_decl is allocated even if
1839 there's no associated frontend symbol to refer to (yet). If the symbol
1840 appears later in the compilation, then the slot will be re-used. */
1841 if (d == NULL)
1842 return ggc_cleared_alloc <struct lang_decl> ();
1843
1844 struct lang_decl *ld = (d->csym) ? DECL_LANG_SPECIFIC (d->csym) : NULL;
1845 if (ld == NULL)
1846 ld = ggc_cleared_alloc <struct lang_decl> ();
1847
1848 if (ld->decl == NULL)
1849 ld->decl = d;
1850
1851 return ld;
1852 }
1853
1854 /* Implements the lang_hooks.dup_lang_specific_decl routine for language D.
1855 Replace the DECL_LANG_SPECIFIC field of NODE with a copy. */
1856
1857 static void
1858 d_dup_lang_specific_decl (tree node)
1859 {
1860 if (!DECL_LANG_SPECIFIC (node))
1861 return;
1862
1863 struct lang_decl *ld = ggc_alloc <struct lang_decl> ();
1864 memcpy (ld, DECL_LANG_SPECIFIC (node), sizeof (struct lang_decl));
1865 DECL_LANG_SPECIFIC (node) = ld;
1866 }
1867
1868 /* This preserves trees we create from the garbage collector. */
1869
1870 static GTY(()) tree d_keep_list = NULL_TREE;
1871
1872 void
1873 d_keep (tree t)
1874 {
1875 d_keep_list = tree_cons (NULL_TREE, t, d_keep_list);
1876 }
1877
1878 /* Implements the lang_hooks.eh_personality routine for language D.
1879 Return the GDC personality function decl. */
1880
1881 static GTY(()) tree d_eh_personality_decl;
1882
1883 static tree
1884 d_eh_personality (void)
1885 {
1886 if (!d_eh_personality_decl)
1887 d_eh_personality_decl = build_personality_function ("gdc");
1888
1889 return d_eh_personality_decl;
1890 }
1891
1892 /* Implements the lang_hooks.eh_runtime_type routine for language D. */
1893
1894 static tree
1895 d_build_eh_runtime_type (tree type)
1896 {
1897 Type *t = TYPE_LANG_FRONTEND (type);
1898 gcc_assert (t != NULL);
1899 t = t->toBasetype ();
1900
1901 ClassDeclaration *cd = t->isTypeClass ()->sym;
1902 tree decl;
1903
1904 if (cd->isCPPclass ())
1905 decl = get_cpp_typeinfo_decl (cd);
1906 else
1907 decl = get_classinfo_decl (cd);
1908
1909 return convert (ptr_type_node, build_address (decl));
1910 }
1911
1912 /* Implements the lang_hooks.enum_underlying_base_type routine for language D.
1913 Returns the underlying type of the given enumeration TYPE. */
1914
1915 static tree
1916 d_enum_underlying_base_type (const_tree type)
1917 {
1918 gcc_assert (TREE_CODE (type) == ENUMERAL_TYPE);
1919 return TREE_TYPE (type);
1920 }
1921
1922 /* Get a value for the SARIF v2.1.0 "artifact.sourceLanguage" property,
1923 based on the list in SARIF v2.1.0 Appendix J. */
1924
1925 static const char *
1926 d_get_sarif_source_language (const char *)
1927 {
1928 return "d";
1929 }
1930
1931 /* Definitions for our language-specific hooks. */
1932
1933 #undef LANG_HOOKS_NAME
1934 #undef LANG_HOOKS_INIT
1935 #undef LANG_HOOKS_INIT_TS
1936 #undef LANG_HOOKS_INIT_OPTIONS
1937 #undef LANG_HOOKS_INIT_OPTIONS_STRUCT
1938 #undef LANG_HOOKS_OPTION_LANG_MASK
1939 #undef LANG_HOOKS_HANDLE_OPTION
1940 #undef LANG_HOOKS_POST_OPTIONS
1941 #undef LANG_HOOKS_PARSE_FILE
1942 #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
1943 #undef LANG_HOOKS_ATTRIBUTE_TABLE
1944 #undef LANG_HOOKS_GET_ALIAS_SET
1945 #undef LANG_HOOKS_TYPES_COMPATIBLE_P
1946 #undef LANG_HOOKS_BUILTIN_FUNCTION
1947 #undef LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE
1948 #undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
1949 #undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
1950 #undef LANG_HOOKS_GIMPLIFY_EXPR
1951 #undef LANG_HOOKS_CLASSIFY_RECORD
1952 #undef LANG_HOOKS_TREE_SIZE
1953 #undef LANG_HOOKS_PRINT_XNODE
1954 #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
1955 #undef LANG_HOOKS_EH_PERSONALITY
1956 #undef LANG_HOOKS_EH_RUNTIME_TYPE
1957 #undef LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE
1958 #undef LANG_HOOKS_PUSHDECL
1959 #undef LANG_HOOKS_GETDECLS
1960 #undef LANG_HOOKS_GLOBAL_BINDINGS_P
1961 #undef LANG_HOOKS_TYPE_FOR_MODE
1962 #undef LANG_HOOKS_TYPE_FOR_SIZE
1963 #undef LANG_HOOKS_TYPE_PROMOTES_TO
1964 #undef LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE
1965
1966 #define LANG_HOOKS_NAME "GNU D"
1967 #define LANG_HOOKS_INIT d_init
1968 #define LANG_HOOKS_INIT_TS d_init_ts
1969 #define LANG_HOOKS_INIT_OPTIONS d_init_options
1970 #define LANG_HOOKS_INIT_OPTIONS_STRUCT d_init_options_struct
1971 #define LANG_HOOKS_OPTION_LANG_MASK d_option_lang_mask
1972 #define LANG_HOOKS_HANDLE_OPTION d_handle_option
1973 #define LANG_HOOKS_POST_OPTIONS d_post_options
1974 #define LANG_HOOKS_PARSE_FILE d_parse_file
1975 #define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE d_langhook_common_attribute_table
1976 #define LANG_HOOKS_ATTRIBUTE_TABLE d_langhook_attribute_table
1977 #define LANG_HOOKS_GET_ALIAS_SET d_get_alias_set
1978 #define LANG_HOOKS_TYPES_COMPATIBLE_P d_types_compatible_p
1979 #define LANG_HOOKS_BUILTIN_FUNCTION d_builtin_function
1980 #define LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE d_builtin_function_ext_scope
1981 #define LANG_HOOKS_REGISTER_BUILTIN_TYPE d_register_builtin_type
1982 #define LANG_HOOKS_FINISH_INCOMPLETE_DECL d_finish_incomplete_decl
1983 #define LANG_HOOKS_GIMPLIFY_EXPR d_gimplify_expr
1984 #define LANG_HOOKS_CLASSIFY_RECORD d_classify_record
1985 #define LANG_HOOKS_TREE_SIZE d_tree_size
1986 #define LANG_HOOKS_PRINT_XNODE d_print_xnode
1987 #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL d_dup_lang_specific_decl
1988 #define LANG_HOOKS_EH_PERSONALITY d_eh_personality
1989 #define LANG_HOOKS_EH_RUNTIME_TYPE d_build_eh_runtime_type
1990 #define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE d_enum_underlying_base_type
1991 #define LANG_HOOKS_PUSHDECL d_pushdecl
1992 #define LANG_HOOKS_GETDECLS d_getdecls
1993 #define LANG_HOOKS_GLOBAL_BINDINGS_P d_global_bindings_p
1994 #define LANG_HOOKS_TYPE_FOR_MODE d_type_for_mode
1995 #define LANG_HOOKS_TYPE_FOR_SIZE d_type_for_size
1996 #define LANG_HOOKS_TYPE_PROMOTES_TO d_type_promotes_to
1997 #define LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE d_get_sarif_source_language
1998
1999 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
2000
2001 #include "gt-d-d-lang.h"
2002 #include "gtype-d.h"