]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/d-lang.cc
d: Merge upstream dmd, druntime 09faa4eacd, phobos 13ef27a56.
[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.vendor = lang_hooks.name;
297 global.params.argv0 = xstrdup (decoded_options[0].arg);
298 global.params.errorLimit = flag_max_errors;
299
300 /* Default extern(C++) mangling to C++17. */
301 global.params.cplusplus = CppStdRevisionCpp17;
302
303 /* Warnings and deprecations are disabled by default. */
304 global.params.useDeprecated = DIAGNOSTICinform;
305 global.params.warnings = DIAGNOSTICoff;
306 global.params.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 if (!global.params.debugids)
462 global.params.debugids = d_gc_malloc<Strings> ();
463 global.params.debugids->push (arg);
464 break;
465 }
466
467 error ("bad argument for %<-fdebug%>: %qs", arg);
468 break;
469
470 case OPT_fdoc:
471 global.params.ddoc.doOutput = value;
472 break;
473
474 case OPT_fdoc_dir_:
475 global.params.ddoc.doOutput = true;
476 global.params.ddoc.dir = arg;
477 break;
478
479 case OPT_fdoc_file_:
480 global.params.ddoc.doOutput = true;
481 global.params.ddoc.name = arg;
482 break;
483
484 case OPT_fdoc_inc_:
485 global.params.ddoc.files.push (arg);
486 break;
487
488 case OPT_fdruntime:
489 global.params.betterC = !value;
490 break;
491
492 case OPT_fdump_c___spec_:
493 global.params.cxxhdr.doOutput = true;
494 global.params.cxxhdr.name = arg;
495 break;
496
497 case OPT_fdump_c___spec_verbose:
498 global.params.cxxhdr.fullOutput = true;
499 break;
500
501 case OPT_fdump_d_original:
502 global.params.vcg_ast = value;
503 break;
504
505 case OPT_fexceptions:
506 global.params.useExceptions = value;
507 break;
508
509 case OPT_fextern_std_:
510 switch (value)
511 {
512 case CppStdRevisionCpp98:
513 case CppStdRevisionCpp11:
514 case CppStdRevisionCpp14:
515 case CppStdRevisionCpp17:
516 case CppStdRevisionCpp20:
517 global.params.cplusplus = (CppStdRevision) value;
518 break;
519
520 default:
521 error ("bad argument for %<-fextern-std%>: %qs", arg);
522 }
523 break;
524
525 case OPT_fignore_unknown_pragmas:
526 global.params.ignoreUnsupportedPragmas = value;
527 break;
528
529 case OPT_finvariants:
530 global.params.useInvariants = value ? CHECKENABLEon : CHECKENABLEoff;
531 break;
532
533 case OPT_fmain:
534 global.params.addMain = value;
535 break;
536
537 case OPT_fmodule_file_:
538 global.params.modFileAliasStrings.push (arg);
539 if (!strchr (arg, '='))
540 error ("bad argument for %<-fmodule-file%>: %qs", arg);
541 break;
542
543 case OPT_fmoduleinfo:
544 global.params.useModuleInfo = value;
545 break;
546
547 case OPT_fonly_:
548 d_option.fonly = arg;
549 break;
550
551 case OPT_fpostconditions:
552 global.params.useOut = value ? CHECKENABLEon : CHECKENABLEoff;
553 break;
554
555 case OPT_fpreconditions:
556 global.params.useIn = value ? CHECKENABLEon : CHECKENABLEoff;
557 break;
558
559 case OPT_fpreview_all:
560 global.params.ehnogc = value;
561 global.params.useDIP25 = FeatureState::enabled;
562 global.params.useDIP1000 = FeatureState::enabled;
563 global.params.useDIP1021 = value;
564 global.params.bitfields = value;
565 global.params.dtorFields = FeatureState::enabled;
566 global.params.fieldwise = value;
567 global.params.fixAliasThis = value;
568 global.params.previewIn = value;
569 global.params.fix16997 = value;
570 global.params.noSharedAccess = FeatureState::enabled;
571 global.params.rvalueRefParam = FeatureState::enabled;
572 global.params.inclusiveInContracts = value;
573 global.params.systemVariables = FeatureState::enabled;
574 global.params.fixImmutableConv = value;
575 break;
576
577 case OPT_fpreview_bitfields:
578 global.params.bitfields = value;
579 break;
580
581 case OPT_fpreview_dip1000:
582 global.params.useDIP1000 = FeatureState::enabled;
583 break;
584
585 case OPT_fpreview_dip1008:
586 global.params.ehnogc = value;
587 break;
588
589 case OPT_fpreview_dip1021:
590 global.params.useDIP1021 = value;
591 break;
592
593 case OPT_fpreview_dip25:
594 global.params.useDIP25 = FeatureState::enabled;
595 break;
596
597 case OPT_fpreview_dtorfields:
598 global.params.dtorFields = FeatureState::enabled;
599 break;
600
601 case OPT_fpreview_fieldwise:
602 global.params.fieldwise = value;
603 break;
604
605 case OPT_fpreview_fixaliasthis:
606 global.params.fixAliasThis = value;
607 break;
608
609 case OPT_fpreview_fiximmutableconv:
610 global.params.fixImmutableConv = value;
611 break;
612
613 case OPT_fpreview_in:
614 global.params.previewIn = value;
615 break;
616
617 case OPT_fpreview_inclusiveincontracts:
618 global.params.inclusiveInContracts = value;
619 break;
620
621 case OPT_fpreview_nosharedaccess:
622 global.params.noSharedAccess = FeatureState::enabled;
623 break;
624
625 case OPT_fpreview_rvaluerefparam:
626 global.params.rvalueRefParam = FeatureState::enabled;
627 break;
628
629 case OPT_fpreview_systemvariables:
630 global.params.systemVariables = FeatureState::enabled;
631 break;
632
633 case OPT_frelease:
634 global.params.release = value;
635 break;
636
637 case OPT_frevert_all:
638 global.params.useDIP1000 = FeatureState::disabled;
639 global.params.useDIP25 = FeatureState::disabled;
640 global.params.dtorFields = FeatureState::disabled;
641 global.params.fix16997 = !value;
642 break;
643
644 case OPT_frevert_dip1000:
645 global.params.useDIP1000 = FeatureState::disabled;
646 break;
647
648 case OPT_frevert_dip25:
649 global.params.useDIP25 = FeatureState::disabled;
650 break;
651
652 case OPT_frevert_dtorfields:
653 global.params.dtorFields = FeatureState::disabled;
654 break;
655
656 case OPT_frevert_intpromote:
657 global.params.fix16997 = !value;
658 break;
659
660 case OPT_frtti:
661 global.params.useTypeInfo = value;
662 break;
663
664 case OPT_fsave_mixins_:
665 global.params.mixinOut.doOutput = true;
666 global.params.mixinOut.name = arg;
667 global.params.mixinOut.buffer = d_gc_malloc<OutBuffer> ();
668 break;
669
670 case OPT_fswitch_errors:
671 global.params.useSwitchError = value ? CHECKENABLEon : CHECKENABLEoff;
672 break;
673
674 case OPT_ftransition_all:
675 global.params.vfield = value;
676 global.params.vgc = value;
677 global.params.vin = value;
678 global.params.vtls = value;
679 break;
680
681 case OPT_ftransition_field:
682 global.params.vfield = value;
683 break;
684
685 case OPT_ftransition_in:
686 global.params.vin = value;
687 break;
688
689 case OPT_ftransition_nogc:
690 global.params.vgc = value;
691 break;
692
693 case OPT_ftransition_templates:
694 global.params.vtemplates = value;
695 break;
696
697 case OPT_ftransition_tls:
698 global.params.vtls = value;
699 break;
700
701 case OPT_funittest:
702 global.params.useUnitTests = value;
703 break;
704
705 case OPT_fversion_:
706 if (Identifier::isValidIdentifier (CONST_CAST (char *, arg)))
707 {
708 if (!global.params.versionids)
709 global.params.versionids = d_gc_malloc<Strings> ();
710 global.params.versionids->push (arg);
711 break;
712 }
713
714 error ("bad argument for %<-fversion%>: %qs", arg);
715 break;
716
717 case OPT_H:
718 global.params.dihdr.doOutput = true;
719 break;
720
721 case OPT_Hd:
722 global.params.dihdr.doOutput = true;
723 global.params.dihdr.dir = arg;
724 break;
725
726 case OPT_Hf:
727 global.params.dihdr.doOutput = true;
728 global.params.dihdr.name = arg;
729 break;
730
731 case OPT_imultilib:
732 d_option.multilib = arg;
733 break;
734
735 case OPT_iprefix:
736 d_option.prefix = arg;
737 break;
738
739 case OPT_I:
740 global.params.imppath->push (arg);
741 break;
742
743 case OPT_J:
744 global.params.fileImppath->push (arg);
745 break;
746
747 case OPT_MM:
748 d_option.deps_skip_system = true;
749 /* Fall through. */
750
751 case OPT_M:
752 d_option.deps = true;
753 break;
754
755 case OPT_MMD:
756 d_option.deps_skip_system = true;
757 /* Fall through. */
758
759 case OPT_MD:
760 d_option.deps = true;
761 d_option.deps_filename = arg;
762 break;
763
764 case OPT_MF:
765 /* If specified multiple times, last one wins. */
766 d_option.deps_filename_user = arg;
767 break;
768
769 case OPT_MP:
770 d_option.deps_phony = true;
771 break;
772
773 case OPT_MQ:
774 deps_add_target (arg, true);
775 break;
776
777 case OPT_MT:
778 deps_add_target (arg, false);
779 break;
780
781 case OPT_nostdinc:
782 d_option.stdinc = false;
783 break;
784
785 case OPT_v:
786 global.params.verbose = value;
787 break;
788
789 case OPT_Wall:
790 if (value)
791 global.params.warnings = DIAGNOSTICinform;
792 break;
793
794 case OPT_Wdeprecated:
795 global.params.useDeprecated = value ? DIAGNOSTICinform : DIAGNOSTICoff;
796 break;
797
798 case OPT_Werror:
799 if (value)
800 global.params.warnings = DIAGNOSTICerror;
801 break;
802
803 case OPT_Wspeculative:
804 if (value)
805 global.params.showGaggedErrors = 1;
806 break;
807
808 case OPT_Xf:
809 global.params.json.name = arg;
810 /* Fall through. */
811
812 case OPT_X:
813 global.params.json.doOutput = true;
814 break;
815
816 default:
817 break;
818 }
819
820 D_handle_option_auto (&global_options, &global_options_set,
821 scode, arg, value,
822 d_option_lang_mask (), kind,
823 loc, handlers, global_dc);
824
825 return result;
826 }
827
828 /* Implements the lang_hooks.post_options routine for language D.
829 Deal with any options that imply the turning on/off of features.
830 FN is the main input filename passed on the command line. */
831
832 static bool
833 d_post_options (const char ** fn)
834 {
835 /* Verify the input file name. */
836 const char *filename = *fn;
837 if (!filename || strcmp (filename, "-") == 0)
838 filename = "";
839
840 /* The front end considers the first input file to be the main one. */
841 *fn = filename;
842
843 /* Release mode doesn't turn off bounds checking for safe functions. */
844 if (global.params.useArrayBounds == CHECKENABLEdefault)
845 {
846 global.params.useArrayBounds = global.params.release
847 ? CHECKENABLEsafeonly : CHECKENABLEon;
848 }
849
850 /* Assert code is generated if unittests are being compiled also, even if
851 release mode is turned on. */
852 if (global.params.useAssert == CHECKENABLEdefault)
853 {
854 if (global.params.useUnitTests || !global.params.release)
855 global.params.useAssert = CHECKENABLEon;
856 else
857 global.params.useAssert = CHECKENABLEoff;
858 }
859
860 /* Checks for switches without a default are turned off in release mode. */
861 if (global.params.useSwitchError == CHECKENABLEdefault)
862 {
863 global.params.useSwitchError = global.params.release
864 ? CHECKENABLEoff : CHECKENABLEon;
865 }
866
867 /* Contracts are turned off in release mode. */
868 if (global.params.useInvariants == CHECKENABLEdefault)
869 {
870 global.params.useInvariants = global.params.release
871 ? CHECKENABLEoff : CHECKENABLEon;
872 }
873
874 if (global.params.useIn == CHECKENABLEdefault)
875 {
876 global.params.useIn = global.params.release
877 ? CHECKENABLEoff : CHECKENABLEon;
878 }
879
880 if (global.params.useOut == CHECKENABLEdefault)
881 {
882 global.params.useOut = global.params.release
883 ? CHECKENABLEoff : CHECKENABLEon;
884 }
885
886 /* When not linking against D runtime, turn off all code generation that
887 would otherwise reference it. */
888 if (global.params.betterC)
889 {
890 if (!OPTION_SET_P (flag_moduleinfo))
891 global.params.useModuleInfo = false;
892
893 /* Ensure that the front-end options are in sync with the `-frtti' and
894 `-fexceptions' flags. */
895 if (!OPTION_SET_P (flag_rtti))
896 {
897 global.params.useTypeInfo = false;
898 flag_rtti = false;
899 }
900
901 if (!OPTION_SET_P (flag_exceptions))
902 {
903 global.params.useExceptions = false;
904 flag_exceptions = false;
905 }
906
907 global.params.checkAction = CHECKACTION_C;
908 }
909
910 /* Enabling DIP1021 implies DIP1000. */
911 if (global.params.useDIP1021)
912 global.params.useDIP1000 = FeatureState::enabled;
913
914 /* Enabling DIP1000 implies DIP25. */
915 if (global.params.useDIP1000 == FeatureState::enabled)
916 global.params.useDIP25 = FeatureState::enabled;
917
918 /* Keep in sync with existing -fbounds-check flag. */
919 flag_bounds_check = (global.params.useArrayBounds == CHECKENABLEon);
920
921 /* Turn off partitioning unless it was explicitly requested, as it doesn't
922 work with D exception chaining, where EH handler uses LSDA to determine
923 whether two thrown exception are in the same context. */
924 if (!OPTION_SET_P (flag_reorder_blocks_and_partition))
925 global_options.x_flag_reorder_blocks_and_partition = 0;
926
927 /* Error about use of deprecated features. */
928 if (global.params.useDeprecated == DIAGNOSTICinform
929 && global.params.warnings == DIAGNOSTICerror)
930 global.params.useDeprecated = DIAGNOSTICerror;
931
932 /* Make -fmax-errors visible to frontend's diagnostic machinery. */
933 if (OPTION_SET_P (flag_max_errors))
934 global.params.errorLimit = flag_max_errors;
935
936 if (flag_excess_precision == EXCESS_PRECISION_DEFAULT)
937 flag_excess_precision = EXCESS_PRECISION_STANDARD;
938
939 global.params.useInline = flag_inline_functions;
940 global.params.showColumns = flag_show_column;
941 global.params.printErrorContext = flag_diagnostics_show_caret;
942
943 /* Keep the front-end location type in sync with params. */
944 Loc::set (global.params.showColumns, global.params.messageStyle);
945
946 if (global.params.useInline)
947 global.params.dihdr.fullOutput = true;
948
949 global.params.obj = !flag_syntax_only;
950
951 /* Add in versions given on the command line. */
952 if (global.params.versionids)
953 {
954 for (size_t i = 0; i < global.params.versionids->length; i++)
955 {
956 const char *s = (*global.params.versionids)[i];
957 VersionCondition::addGlobalIdent (s);
958 }
959 }
960
961 if (global.params.debugids)
962 {
963 for (size_t i = 0; i < global.params.debugids->length; i++)
964 {
965 const char *s = (*global.params.debugids)[i];
966 DebugCondition::addGlobalIdent (s);
967 }
968 }
969
970 if (warn_return_type == -1)
971 warn_return_type = 0;
972
973 return false;
974 }
975
976 /* Add the module M to the list of modules that may declare GCC builtins.
977 These are scanned after first semantic and before codegen passes.
978 See d_maybe_set_builtin() for the implementation. */
979
980 void
981 d_add_builtin_module (Module *m)
982 {
983 builtin_modules.push (m);
984 }
985
986 /* Implements the lang_hooks.parse_file routine for language D. */
987
988 static void
989 d_parse_file (void)
990 {
991 if (global.params.verbose)
992 {
993 message ("binary %s", global.params.argv0.ptr);
994 message ("version %s", global.versionChars ());
995
996 if (global.versionids)
997 {
998 obstack buffer;
999 gcc_obstack_init (&buffer);
1000 obstack_grow (&buffer, "predefs ", 9);
1001 for (size_t i = 0; i < global.versionids->length; i++)
1002 {
1003 Identifier *id = (*global.versionids)[i];
1004 const char *str = id->toChars ();
1005 obstack_1grow (&buffer, ' ');
1006 obstack_grow (&buffer, str, strlen (str));
1007 }
1008
1009 obstack_1grow (&buffer, '\0');
1010 message ("%s", (char *) obstack_finish (&buffer));
1011 }
1012 }
1013
1014 /* Start the main input file, if the debug writer wants it. */
1015 if (debug_hooks->start_end_main_source_file)
1016 debug_hooks->start_source_file (0, main_input_filename);
1017
1018 /* Create Module's for all sources we will load. */
1019 Modules modules;
1020 modules.reserve (num_in_fnames);
1021
1022 /* In this mode, the first file name is supposed to be a duplicate
1023 of one of the input files. */
1024 if (d_option.fonly && strcmp (d_option.fonly, main_input_filename) != 0)
1025 error ("%<-fonly=%> argument is different from first input file name");
1026
1027 for (size_t i = 0; i < num_in_fnames; i++)
1028 {
1029 if (strcmp (in_fnames[i], "-") == 0)
1030 {
1031 /* Load the entire contents of stdin into memory. 8 kilobytes should
1032 be a good enough initial size, but double on each iteration.
1033 16 bytes are added for the final '\n' and 15 bytes of padding. */
1034 ssize_t size = 8 * 1024;
1035 uchar *buffer = XNEWVEC (uchar, size + 16);
1036 ssize_t len = 0;
1037 ssize_t count;
1038
1039 while ((count = read (STDIN_FILENO, buffer + len, size - len)) > 0)
1040 {
1041 len += count;
1042 if (len == size)
1043 {
1044 size *= 2;
1045 buffer = XRESIZEVEC (uchar, buffer, size + 16);
1046 }
1047 }
1048
1049 if (count < 0)
1050 {
1051 error (Loc ("stdin", 0, 0), "%s", xstrerror (errno));
1052 free (buffer);
1053 continue;
1054 }
1055
1056 /* Handling stdin, generate a unique name for the module. */
1057 Module *m = Module::create (in_fnames[i],
1058 Identifier::idPool ("__stdin"),
1059 global.params.ddoc.doOutput,
1060 global.params.dihdr.doOutput);
1061 modules.push (m);
1062
1063 /* Zero the padding past the end of the buffer so the D lexer has a
1064 sentinel. The lexer only reads up to 4 bytes at a time. */
1065 memset (buffer + len, '\0', 16);
1066
1067 /* Overwrite the source file for the module, the one created by
1068 Module::create would have a forced a `.d' suffix. */
1069 m->src.length = len;
1070 m->src.ptr = buffer;
1071 }
1072 else
1073 {
1074 /* Handling a D source file, strip off the path and extension. */
1075 const char *basename = FileName::name (in_fnames[i]);
1076 const char *name = FileName::removeExt (basename);
1077
1078 Module *m = Module::create (in_fnames[i], Identifier::idPool (name),
1079 global.params.ddoc.doOutput,
1080 global.params.dihdr.doOutput);
1081 modules.push (m);
1082 FileName::free (name);
1083 }
1084 }
1085
1086 /* Read all D source files. */
1087 for (size_t i = 0; i < modules.length; i++)
1088 {
1089 Module *m = modules[i];
1090 m->read (Loc ());
1091 }
1092
1093 /* Parse all D source files. */
1094 for (size_t i = 0; i < modules.length; i++)
1095 {
1096 Module *m = modules[i];
1097
1098 if (global.params.verbose)
1099 message ("parse %s", m->toChars ());
1100
1101 if (!Module::rootModule)
1102 Module::rootModule = m;
1103
1104 m->importedFrom = m;
1105 m->parse ();
1106
1107 if (m->filetype == FileType::ddoc)
1108 {
1109 gendocfile (m);
1110 /* Remove M from list of modules. */
1111 modules.remove (i);
1112 i--;
1113 }
1114 }
1115
1116 /* Load the module containing D main. */
1117 Module *main_module = NULL;
1118 if (global.params.addMain)
1119 {
1120 unsigned errors = global.startGagging ();
1121 main_module = Module::load (Loc (), NULL, Identifier::idPool ("__main"));
1122
1123 if (!global.endGagging (errors))
1124 {
1125 main_module->importedFrom = main_module;
1126 modules.push (main_module);
1127 }
1128 }
1129
1130 /* If an error occurs later during compilation, remember that we generated
1131 the headers, so that they can be removed before exit. */
1132 bool dump_headers = false;
1133
1134 if (global.errors)
1135 goto had_errors;
1136
1137 if (global.params.dihdr.doOutput)
1138 {
1139 /* Generate 'header' import files. Since 'header' import files must be
1140 independent of command line switches and what else is imported, they
1141 are generated before any semantic analysis. */
1142 for (size_t i = 0; i < modules.length; i++)
1143 {
1144 Module *m = modules[i];
1145 if (m->filetype == FileType::dhdr
1146 || (d_option.fonly && m != Module::rootModule))
1147 continue;
1148
1149 if (global.params.verbose)
1150 message ("import %s", m->toChars ());
1151
1152 genhdrfile (m);
1153 }
1154
1155 dump_headers = true;
1156 }
1157
1158 if (global.errors)
1159 goto had_errors;
1160
1161 /* Load all unconditional imports for better symbol resolving. */
1162 for (size_t i = 0; i < modules.length; i++)
1163 {
1164 Module *m = modules[i];
1165
1166 if (global.params.verbose)
1167 message ("importall %s", m->toChars ());
1168
1169 m->importAll (NULL);
1170 }
1171
1172 if (global.errors)
1173 goto had_errors;
1174
1175 /* Do semantic analysis. */
1176 doing_semantic_analysis_p = true;
1177
1178 for (size_t i = 0; i < modules.length; i++)
1179 {
1180 Module *m = modules[i];
1181
1182 /* If this is the `__main` module, check that `D main` hasn't already
1183 been declared in user code before running semantic on it. */
1184 if (m == main_module && global.hasMainFunction)
1185 {
1186 modules.remove (i);
1187 continue;
1188 }
1189
1190 if (global.params.verbose)
1191 message ("semantic %s", m->toChars ());
1192
1193 dsymbolSemantic (m, NULL);
1194 }
1195
1196 /* Do deferred semantic analysis. */
1197 Module::runDeferredSemantic ();
1198
1199 if (Module::deferred.length)
1200 {
1201 for (size_t i = 0; i < Module::deferred.length; i++)
1202 {
1203 Dsymbol *sd = Module::deferred[i];
1204 error_at (make_location_t (sd->loc),
1205 "unable to resolve forward reference in definition");
1206 }
1207 }
1208
1209 /* Process all built-in modules or functions now for CTFE. */
1210 while (builtin_modules.length != 0)
1211 {
1212 Module *m = builtin_modules.pop ();
1213 d_maybe_set_builtin (m);
1214 }
1215
1216 /* Do pass 2 semantic analysis. */
1217 for (size_t i = 0; i < modules.length; i++)
1218 {
1219 Module *m = modules[i];
1220
1221 if (global.params.verbose)
1222 message ("semantic2 %s", m->toChars ());
1223
1224 semantic2 (m, NULL);
1225 }
1226
1227 Module::runDeferredSemantic2 ();
1228
1229 if (global.errors)
1230 goto had_errors;
1231
1232 /* Do pass 3 semantic analysis. */
1233 for (size_t i = 0; i < modules.length; i++)
1234 {
1235 Module *m = modules[i];
1236
1237 if (global.params.verbose)
1238 message ("semantic3 %s", m->toChars ());
1239
1240 semantic3 (m, NULL);
1241 }
1242
1243 Module::runDeferredSemantic3 ();
1244
1245 /* Check again, incase semantic3 pass loaded any more modules. */
1246 while (builtin_modules.length != 0)
1247 {
1248 Module *m = builtin_modules.pop ();
1249 d_maybe_set_builtin (m);
1250 }
1251
1252 /* Do not attempt to generate output files if errors or warnings occurred. */
1253 if (global.errors || global.warnings)
1254 goto had_errors;
1255
1256 /* Generate output files. */
1257 doing_semantic_analysis_p = false;
1258
1259 if (Module::rootModule)
1260 {
1261 /* Declare the name of the root module as the first global name in order
1262 to make the middle-end fully deterministic. */
1263 OutBuffer buf;
1264 mangleToBuffer (Module::rootModule, &buf);
1265 first_global_object_name = buf.extractChars ();
1266 }
1267
1268 /* Make dependencies. */
1269 if (d_option.deps)
1270 {
1271 obstack buffer;
1272 FILE *deps_stream;
1273
1274 gcc_obstack_init (&buffer);
1275
1276 for (size_t i = 0; i < modules.length; i++)
1277 deps_write (modules[i], &buffer);
1278
1279 /* -MF <arg> overrides -M[M]D. */
1280 if (d_option.deps_filename_user)
1281 d_option.deps_filename = d_option.deps_filename_user;
1282
1283 if (d_option.deps_filename)
1284 {
1285 deps_stream = fopen (d_option.deps_filename, "w");
1286 if (!deps_stream)
1287 {
1288 fatal_error (input_location, "opening dependency file %s: %m",
1289 d_option.deps_filename);
1290 goto had_errors;
1291 }
1292 }
1293 else
1294 deps_stream = stdout;
1295
1296 fprintf (deps_stream, "%s", (char *) obstack_finish (&buffer));
1297
1298 if (deps_stream != stdout
1299 && (ferror (deps_stream) || fclose (deps_stream)))
1300 {
1301 fatal_error (input_location, "closing dependency file %s: %m",
1302 d_option.deps_filename);
1303 }
1304 }
1305
1306 if (global.params.vtemplates)
1307 printTemplateStats ();
1308
1309 /* Generate JSON files. */
1310 if (global.params.json.doOutput)
1311 {
1312 OutBuffer buf;
1313 json_generate (&buf, &modules);
1314
1315 const char *name = global.params.json.name.ptr;
1316 FILE *json_stream;
1317
1318 if (name && (name[0] != '-' || name[1] != '\0'))
1319 {
1320 const char *nameext
1321 = FileName::defaultExt (name, json_ext.ptr);
1322 json_stream = fopen (nameext, "w");
1323 if (!json_stream)
1324 {
1325 fatal_error (input_location, "opening json file %s: %m", nameext);
1326 goto had_errors;
1327 }
1328 }
1329 else
1330 json_stream = stdout;
1331
1332 fprintf (json_stream, "%s", buf.peekChars ());
1333
1334 if (json_stream != stdout
1335 && (ferror (json_stream) || fclose (json_stream)))
1336 fatal_error (input_location, "closing json file %s: %m", name);
1337 }
1338
1339 /* Generate Ddoc files. */
1340 if (global.params.ddoc.doOutput && !global.errors && !errorcount)
1341 {
1342 for (size_t i = 0; i < modules.length; i++)
1343 {
1344 Module *m = modules[i];
1345 gendocfile (m);
1346 }
1347 }
1348
1349 /* Handle -fdump-d-original. */
1350 if (global.params.vcg_ast)
1351 {
1352 for (size_t i = 0; i < modules.length; i++)
1353 {
1354 Module *m = modules[i];
1355 OutBuffer buf;
1356 buf.doindent = 1;
1357
1358 moduleToBuffer (&buf, m);
1359 message ("%s", buf.peekChars ());
1360 }
1361 }
1362
1363 /* Generate C++ header files. */
1364 if (global.params.cxxhdr.doOutput)
1365 genCppHdrFiles (modules);
1366
1367 if (global.errors)
1368 goto had_errors;
1369
1370 for (size_t i = 0; i < modules.length; i++)
1371 {
1372 Module *m = modules[i];
1373
1374 /* Skip generating code for header files, or when the module wasn't
1375 specified by `-fonly=`. */
1376 if ((m->filetype == FileType::dhdr && m != main_module)
1377 || (d_option.fonly && m != Module::rootModule))
1378 continue;
1379
1380 if (global.params.verbose)
1381 message ("code %s", m->toChars ());
1382
1383 if (!flag_syntax_only)
1384 build_decl_tree (m);
1385 }
1386
1387 /* And end the main input file, if the debug writer wants it. */
1388 if (debug_hooks->start_end_main_source_file)
1389 debug_hooks->end_source_file (0);
1390
1391 had_errors:
1392 /* Add the D frontend error count to the GCC error count to correctly
1393 exit with an error status. */
1394 errorcount += (global.errors + global.warnings);
1395
1396 /* We want to write the mixin expansion file also on error. */
1397 if (global.params.mixinOut.doOutput)
1398 {
1399 FILE *mixin_stream = fopen (global.params.mixinOut.name.ptr, "w");
1400
1401 if (mixin_stream)
1402 {
1403 OutBuffer *buf = global.params.mixinOut.buffer;
1404 fprintf (mixin_stream, "%s", buf->peekChars ());
1405
1406 if (ferror (mixin_stream) || fclose (mixin_stream))
1407 fatal_error (input_location, "closing mixin file %s: %m",
1408 global.params.mixinOut.name.ptr);
1409 }
1410 else
1411 {
1412 fatal_error (input_location, "opening mixin file %s: %m",
1413 global.params.mixinOut.name.ptr);
1414 }
1415 }
1416
1417 /* Remove generated .di files on error. */
1418 if (errorcount && dump_headers)
1419 {
1420 for (size_t i = 0; i < modules.length; i++)
1421 {
1422 Module *m = modules[i];
1423 if (m->filetype == FileType::dhdr
1424 || (d_option.fonly && m != Module::rootModule))
1425 continue;
1426
1427 remove (m->hdrfile.toChars ());
1428 }
1429 }
1430
1431 /* Write out globals. */
1432 d_finish_compilation (vec_safe_address (global_declarations),
1433 vec_safe_length (global_declarations));
1434 }
1435
1436 /* Implements the lang_hooks.types.type_for_mode routine for language D. */
1437
1438 static tree
1439 d_type_for_mode (machine_mode mode, int unsignedp)
1440 {
1441 if (mode == QImode)
1442 return unsignedp ? d_ubyte_type : d_byte_type;
1443
1444 if (mode == HImode)
1445 return unsignedp ? d_ushort_type : d_short_type;
1446
1447 if (mode == SImode)
1448 return unsignedp ? d_uint_type : d_int_type;
1449
1450 if (mode == DImode)
1451 return unsignedp ? d_ulong_type : d_long_type;
1452
1453 if (mode == TYPE_MODE (d_cent_type))
1454 return unsignedp ? d_ucent_type : d_cent_type;
1455
1456 if (mode == TYPE_MODE (float_type_node))
1457 return float_type_node;
1458
1459 if (mode == TYPE_MODE (double_type_node))
1460 return double_type_node;
1461
1462 if (mode == TYPE_MODE (long_double_type_node))
1463 return long_double_type_node;
1464
1465 if (mode == TYPE_MODE (build_pointer_type (char8_type_node)))
1466 return build_pointer_type (char8_type_node);
1467
1468 if (mode == TYPE_MODE (build_pointer_type (d_int_type)))
1469 return build_pointer_type (d_int_type);
1470
1471 for (int i = 0; i < NUM_INT_N_ENTS; i ++)
1472 {
1473 if (int_n_enabled_p[i] && mode == int_n_data[i].m)
1474 {
1475 if (unsignedp)
1476 return int_n_trees[i].unsigned_type;
1477 else
1478 return int_n_trees[i].signed_type;
1479 }
1480 }
1481
1482 if (COMPLEX_MODE_P (mode))
1483 {
1484 machine_mode inner_mode;
1485 tree inner_type;
1486
1487 if (mode == TYPE_MODE (complex_float_type_node))
1488 return complex_float_type_node;
1489 if (mode == TYPE_MODE (complex_double_type_node))
1490 return complex_double_type_node;
1491 if (mode == TYPE_MODE (complex_long_double_type_node))
1492 return complex_long_double_type_node;
1493
1494 inner_mode = (machine_mode) GET_MODE_INNER (mode);
1495 inner_type = d_type_for_mode (inner_mode, unsignedp);
1496 if (inner_type != NULL_TREE)
1497 return build_complex_type (inner_type);
1498 }
1499 else if (VECTOR_MODE_P (mode))
1500 {
1501 machine_mode inner_mode = (machine_mode) GET_MODE_INNER (mode);
1502 tree inner_type = d_type_for_mode (inner_mode, unsignedp);
1503 if (inner_type != NULL_TREE)
1504 return build_vector_type_for_mode (inner_type, mode);
1505 }
1506
1507 return 0;
1508 }
1509
1510 /* Implements the lang_hooks.types.type_for_size routine for language D. */
1511
1512 static tree
1513 d_type_for_size (unsigned bits, int unsignedp)
1514 {
1515 if (bits <= TYPE_PRECISION (d_byte_type))
1516 return unsignedp ? d_ubyte_type : d_byte_type;
1517
1518 if (bits <= TYPE_PRECISION (d_short_type))
1519 return unsignedp ? d_ushort_type : d_short_type;
1520
1521 if (bits <= TYPE_PRECISION (d_int_type))
1522 return unsignedp ? d_uint_type : d_int_type;
1523
1524 if (bits <= TYPE_PRECISION (d_long_type))
1525 return unsignedp ? d_ulong_type : d_long_type;
1526
1527 if (bits <= TYPE_PRECISION (d_cent_type))
1528 return unsignedp ? d_ucent_type : d_cent_type;
1529
1530 for (int i = 0; i < NUM_INT_N_ENTS; i ++)
1531 {
1532 if (int_n_enabled_p[i] && bits == int_n_data[i].bitsize)
1533 {
1534 if (unsignedp)
1535 return int_n_trees[i].unsigned_type;
1536 else
1537 return int_n_trees[i].signed_type;
1538 }
1539 }
1540
1541 return 0;
1542 }
1543
1544 /* Implements the lang_hooks.types.type_promotes_to routine for language D. */
1545
1546 static tree
1547 d_type_promotes_to (tree type)
1548 {
1549 /* Promotions are only applied on unnamed function arguments for declarations
1550 with `extern(C)' or `extern(C++)' linkage. */
1551 if (cfun && DECL_LANG_FRONTEND (cfun->decl)
1552 && DECL_LANG_FRONTEND (cfun->decl)->resolvedLinkage () != LINK::d)
1553 {
1554 /* In [type/integer-promotions], integer promotions are conversions of the
1555 following types:
1556
1557 bool int
1558 byte int
1559 ubyte int
1560 short int
1561 ushort int
1562 char int
1563 wchar int
1564 dchar uint
1565
1566 If an enum has as a base type one of the types in the left column, it
1567 is converted to the type in the right column. */
1568 if (TREE_CODE (type) == ENUMERAL_TYPE && ENUM_IS_SCOPED (type))
1569 type = TREE_TYPE (type);
1570
1571 type = TYPE_MAIN_VARIANT (type);
1572
1573 /* Check for promotions of target-defined types first. */
1574 tree promoted_type = targetm.promoted_type (type);
1575 if (promoted_type)
1576 return promoted_type;
1577
1578 if (TREE_CODE (type) == BOOLEAN_TYPE)
1579 return d_int_type;
1580
1581 if (INTEGRAL_TYPE_P (type))
1582 {
1583 if (type == d_byte_type || type == d_ubyte_type
1584 || type == d_short_type || type == d_ushort_type
1585 || type == char8_type_node || type == char16_type_node)
1586 return d_int_type;
1587
1588 if (type == char32_type_node)
1589 return d_uint_type;
1590
1591 if (TYPE_PRECISION (type) < TYPE_PRECISION (d_int_type))
1592 return d_int_type;
1593 }
1594
1595 /* Float arguments are converted to doubles. */
1596 if (type == float_type_node)
1597 return double_type_node;
1598
1599 if (type == ifloat_type_node)
1600 return idouble_type_node;
1601 }
1602
1603 return type;
1604 }
1605
1606 /* Implements the lang_hooks.decls.global_bindings_p routine for language D.
1607 Return true if we are in the global binding level. */
1608
1609 static bool
1610 d_global_bindings_p (void)
1611 {
1612 return (current_binding_level == global_binding_level);
1613 }
1614
1615 /* Return global_context, but create it first if need be. */
1616
1617 static tree
1618 get_global_context (void)
1619 {
1620 if (!global_context)
1621 {
1622 global_context = build_translation_unit_decl (NULL_TREE);
1623 debug_hooks->register_main_translation_unit (global_context);
1624 }
1625
1626 return global_context;
1627 }
1628
1629 /* Implements the lang_hooks.decls.pushdecl routine for language D.
1630 Record DECL as belonging to the current lexical scope. */
1631
1632 tree
1633 d_pushdecl (tree decl)
1634 {
1635 /* Set the context of the decl. If current_function_decl did not help in
1636 determining the context, use global scope. */
1637 if (!DECL_CONTEXT (decl))
1638 {
1639 if (current_function_decl)
1640 DECL_CONTEXT (decl) = current_function_decl;
1641 else
1642 DECL_CONTEXT (decl) = get_global_context ();
1643 }
1644
1645 /* Put decls on list in reverse order. */
1646 if (TREE_STATIC (decl) || d_global_bindings_p ())
1647 vec_safe_push (global_declarations, decl);
1648 else
1649 {
1650 TREE_CHAIN (decl) = current_binding_level->names;
1651 current_binding_level->names = decl;
1652 }
1653
1654 return decl;
1655 }
1656
1657 /* Implements the lang_hooks.decls.getdecls routine for language D.
1658 Return the list of declarations of the current level. */
1659
1660 static tree
1661 d_getdecls (void)
1662 {
1663 if (current_binding_level)
1664 return current_binding_level->names;
1665
1666 return NULL_TREE;
1667 }
1668
1669
1670 /* Implements the lang_hooks.get_alias_set routine for language D.
1671 Get the alias set corresponding to type or expression T.
1672 Return -1 if we don't do anything special. */
1673
1674 static alias_set_type
1675 d_get_alias_set (tree)
1676 {
1677 /* For now in D, assume everything aliases everything else, until we define
1678 some solid rules backed by a specification. There are also some parts
1679 of code generation routines that don't adhere to C alias rules, such as
1680 build_vconvert. In any case, a lot of user code already assumes there
1681 is no strict aliasing and will break if we were to change that. */
1682 return 0;
1683 }
1684
1685 /* Implements the lang_hooks.types_compatible_p routine for language D.
1686 Compares two types for equivalence in the D programming language.
1687 This routine should only return 1 if it is sure, even though the frontend
1688 should have already ensured that all types are compatible before handing
1689 over the parsed ASTs to the code generator. */
1690
1691 static int
1692 d_types_compatible_p (tree x, tree y)
1693 {
1694 Type *tx = TYPE_LANG_FRONTEND (x);
1695 Type *ty = TYPE_LANG_FRONTEND (y);
1696
1697 /* Try validating the types in the frontend. */
1698 if (tx != NULL && ty != NULL)
1699 {
1700 /* Types are equivalent. */
1701 if (same_type_p (tx, ty))
1702 return true;
1703
1704 /* Type system allows implicit conversion between. */
1705 if (tx->implicitConvTo (ty) != MATCH::nomatch
1706 || ty->implicitConvTo (tx) != MATCH::nomatch)
1707 return true;
1708 }
1709
1710 /* Fallback on using type flags for comparison. E.g: all dynamic arrays
1711 are distinct types in D, but are VIEW_CONVERT compatible. */
1712 if (TREE_CODE (x) == RECORD_TYPE && TREE_CODE (y) == RECORD_TYPE)
1713 {
1714 if (TYPE_DYNAMIC_ARRAY (x) && TYPE_DYNAMIC_ARRAY (y))
1715 return true;
1716
1717 if (TYPE_DELEGATE (x) && TYPE_DELEGATE (y))
1718 return true;
1719
1720 if (TYPE_ASSOCIATIVE_ARRAY (x) && TYPE_ASSOCIATIVE_ARRAY (y))
1721 return true;
1722 }
1723
1724 return false;
1725 }
1726
1727 /* Implements the lang_hooks.finish_incomplete_decl routine for language D. */
1728
1729 static void
1730 d_finish_incomplete_decl (tree decl)
1731 {
1732 if (VAR_P (decl))
1733 {
1734 /* D allows zero-length declarations. Such a declaration ends up with
1735 DECL_SIZE (t) == NULL_TREE which is what the back-end function
1736 assembler_variable checks. This could change in later versions, or
1737 maybe all of these variables should be aliased to one symbol. */
1738 if (DECL_SIZE (decl) == 0)
1739 {
1740 DECL_SIZE (decl) = bitsize_zero_node;
1741 DECL_SIZE_UNIT (decl) = size_zero_node;
1742 }
1743 }
1744 }
1745
1746 /* Implements the lang_hooks.types.classify_record routine for language D.
1747 Return the true debug type for TYPE. */
1748
1749 static classify_record
1750 d_classify_record (tree type)
1751 {
1752 Type *t = TYPE_LANG_FRONTEND (type);
1753 TypeClass *tc = t ? t->isTypeClass () : NULL;
1754
1755 if (tc != NULL)
1756 {
1757 /* extern(C++) interfaces get emitted as classes. */
1758 if (tc->sym->isInterfaceDeclaration ()
1759 && !tc->sym->isCPPinterface ())
1760 return RECORD_IS_INTERFACE;
1761
1762 return RECORD_IS_CLASS;
1763 }
1764
1765 return RECORD_IS_STRUCT;
1766 }
1767
1768 /* Implements the lang_hooks.tree_size routine for language D.
1769 Determine the size of our tcc_constant or tcc_exceptional nodes. */
1770
1771 static size_t
1772 d_tree_size (tree_code code)
1773 {
1774 switch (code)
1775 {
1776 case FUNCFRAME_INFO:
1777 return sizeof (tree_frame_info);
1778
1779 default:
1780 gcc_unreachable ();
1781 }
1782 }
1783
1784 /* Implements the lang_hooks.print_xnode routine for language D. */
1785
1786 static void
1787 d_print_xnode (FILE *file, tree node, int indent)
1788 {
1789 switch (TREE_CODE (node))
1790 {
1791 case FUNCFRAME_INFO:
1792 print_node (file, "frame_type", FRAMEINFO_TYPE (node), indent + 4);
1793 break;
1794
1795 default:
1796 break;
1797 }
1798 }
1799
1800 /* Return which tree structure is used by NODE, or TS_D_GENERIC if NODE
1801 is one of the language-independent trees. */
1802
1803 d_tree_node_structure_enum
1804 d_tree_node_structure (lang_tree_node *t)
1805 {
1806 switch (TREE_CODE (&t->generic))
1807 {
1808 case IDENTIFIER_NODE:
1809 return TS_D_IDENTIFIER;
1810
1811 case FUNCFRAME_INFO:
1812 return TS_D_FRAMEINFO;
1813
1814 default:
1815 return TS_D_GENERIC;
1816 }
1817 }
1818
1819 /* Allocate and return a lang specific structure for the frontend type. */
1820
1821 struct lang_type *
1822 build_lang_type (Type *t)
1823 {
1824 struct lang_type *lt = ggc_cleared_alloc <struct lang_type> ();
1825 lt->type = t;
1826 return lt;
1827 }
1828
1829 /* Allocate and return a lang specific structure for the frontend decl. */
1830
1831 struct lang_decl *
1832 build_lang_decl (Declaration *d)
1833 {
1834 /* For compiler generated run-time typeinfo, a lang_decl is allocated even if
1835 there's no associated frontend symbol to refer to (yet). If the symbol
1836 appears later in the compilation, then the slot will be re-used. */
1837 if (d == NULL)
1838 return ggc_cleared_alloc <struct lang_decl> ();
1839
1840 struct lang_decl *ld = (d->csym) ? DECL_LANG_SPECIFIC (d->csym) : NULL;
1841 if (ld == NULL)
1842 ld = ggc_cleared_alloc <struct lang_decl> ();
1843
1844 if (ld->decl == NULL)
1845 ld->decl = d;
1846
1847 return ld;
1848 }
1849
1850 /* Implements the lang_hooks.dup_lang_specific_decl routine for language D.
1851 Replace the DECL_LANG_SPECIFIC field of NODE with a copy. */
1852
1853 static void
1854 d_dup_lang_specific_decl (tree node)
1855 {
1856 if (!DECL_LANG_SPECIFIC (node))
1857 return;
1858
1859 struct lang_decl *ld = ggc_alloc <struct lang_decl> ();
1860 memcpy (ld, DECL_LANG_SPECIFIC (node), sizeof (struct lang_decl));
1861 DECL_LANG_SPECIFIC (node) = ld;
1862 }
1863
1864 /* This preserves trees we create from the garbage collector. */
1865
1866 static GTY(()) tree d_keep_list = NULL_TREE;
1867
1868 void
1869 d_keep (tree t)
1870 {
1871 d_keep_list = tree_cons (NULL_TREE, t, d_keep_list);
1872 }
1873
1874 /* Implements the lang_hooks.eh_personality routine for language D.
1875 Return the GDC personality function decl. */
1876
1877 static GTY(()) tree d_eh_personality_decl;
1878
1879 static tree
1880 d_eh_personality (void)
1881 {
1882 if (!d_eh_personality_decl)
1883 d_eh_personality_decl = build_personality_function ("gdc");
1884
1885 return d_eh_personality_decl;
1886 }
1887
1888 /* Implements the lang_hooks.eh_runtime_type routine for language D. */
1889
1890 static tree
1891 d_build_eh_runtime_type (tree type)
1892 {
1893 Type *t = TYPE_LANG_FRONTEND (type);
1894 gcc_assert (t != NULL);
1895 t = t->toBasetype ();
1896
1897 ClassDeclaration *cd = t->isTypeClass ()->sym;
1898 tree decl;
1899
1900 if (cd->isCPPclass ())
1901 decl = get_cpp_typeinfo_decl (cd);
1902 else
1903 decl = get_classinfo_decl (cd);
1904
1905 return convert (ptr_type_node, build_address (decl));
1906 }
1907
1908 /* Implements the lang_hooks.enum_underlying_base_type routine for language D.
1909 Returns the underlying type of the given enumeration TYPE. */
1910
1911 static tree
1912 d_enum_underlying_base_type (const_tree type)
1913 {
1914 gcc_assert (TREE_CODE (type) == ENUMERAL_TYPE);
1915 return TREE_TYPE (type);
1916 }
1917
1918 /* Get a value for the SARIF v2.1.0 "artifact.sourceLanguage" property,
1919 based on the list in SARIF v2.1.0 Appendix J. */
1920
1921 static const char *
1922 d_get_sarif_source_language (const char *)
1923 {
1924 return "d";
1925 }
1926
1927 /* Definitions for our language-specific hooks. */
1928
1929 #undef LANG_HOOKS_NAME
1930 #undef LANG_HOOKS_INIT
1931 #undef LANG_HOOKS_INIT_TS
1932 #undef LANG_HOOKS_INIT_OPTIONS
1933 #undef LANG_HOOKS_INIT_OPTIONS_STRUCT
1934 #undef LANG_HOOKS_OPTION_LANG_MASK
1935 #undef LANG_HOOKS_HANDLE_OPTION
1936 #undef LANG_HOOKS_POST_OPTIONS
1937 #undef LANG_HOOKS_PARSE_FILE
1938 #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
1939 #undef LANG_HOOKS_ATTRIBUTE_TABLE
1940 #undef LANG_HOOKS_GET_ALIAS_SET
1941 #undef LANG_HOOKS_TYPES_COMPATIBLE_P
1942 #undef LANG_HOOKS_BUILTIN_FUNCTION
1943 #undef LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE
1944 #undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
1945 #undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
1946 #undef LANG_HOOKS_GIMPLIFY_EXPR
1947 #undef LANG_HOOKS_CLASSIFY_RECORD
1948 #undef LANG_HOOKS_TREE_SIZE
1949 #undef LANG_HOOKS_PRINT_XNODE
1950 #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
1951 #undef LANG_HOOKS_EH_PERSONALITY
1952 #undef LANG_HOOKS_EH_RUNTIME_TYPE
1953 #undef LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE
1954 #undef LANG_HOOKS_PUSHDECL
1955 #undef LANG_HOOKS_GETDECLS
1956 #undef LANG_HOOKS_GLOBAL_BINDINGS_P
1957 #undef LANG_HOOKS_TYPE_FOR_MODE
1958 #undef LANG_HOOKS_TYPE_FOR_SIZE
1959 #undef LANG_HOOKS_TYPE_PROMOTES_TO
1960 #undef LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE
1961
1962 #define LANG_HOOKS_NAME "GNU D"
1963 #define LANG_HOOKS_INIT d_init
1964 #define LANG_HOOKS_INIT_TS d_init_ts
1965 #define LANG_HOOKS_INIT_OPTIONS d_init_options
1966 #define LANG_HOOKS_INIT_OPTIONS_STRUCT d_init_options_struct
1967 #define LANG_HOOKS_OPTION_LANG_MASK d_option_lang_mask
1968 #define LANG_HOOKS_HANDLE_OPTION d_handle_option
1969 #define LANG_HOOKS_POST_OPTIONS d_post_options
1970 #define LANG_HOOKS_PARSE_FILE d_parse_file
1971 #define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE d_langhook_common_attribute_table
1972 #define LANG_HOOKS_ATTRIBUTE_TABLE d_langhook_attribute_table
1973 #define LANG_HOOKS_GET_ALIAS_SET d_get_alias_set
1974 #define LANG_HOOKS_TYPES_COMPATIBLE_P d_types_compatible_p
1975 #define LANG_HOOKS_BUILTIN_FUNCTION d_builtin_function
1976 #define LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE d_builtin_function_ext_scope
1977 #define LANG_HOOKS_REGISTER_BUILTIN_TYPE d_register_builtin_type
1978 #define LANG_HOOKS_FINISH_INCOMPLETE_DECL d_finish_incomplete_decl
1979 #define LANG_HOOKS_GIMPLIFY_EXPR d_gimplify_expr
1980 #define LANG_HOOKS_CLASSIFY_RECORD d_classify_record
1981 #define LANG_HOOKS_TREE_SIZE d_tree_size
1982 #define LANG_HOOKS_PRINT_XNODE d_print_xnode
1983 #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL d_dup_lang_specific_decl
1984 #define LANG_HOOKS_EH_PERSONALITY d_eh_personality
1985 #define LANG_HOOKS_EH_RUNTIME_TYPE d_build_eh_runtime_type
1986 #define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE d_enum_underlying_base_type
1987 #define LANG_HOOKS_PUSHDECL d_pushdecl
1988 #define LANG_HOOKS_GETDECLS d_getdecls
1989 #define LANG_HOOKS_GLOBAL_BINDINGS_P d_global_bindings_p
1990 #define LANG_HOOKS_TYPE_FOR_MODE d_type_for_mode
1991 #define LANG_HOOKS_TYPE_FOR_SIZE d_type_for_size
1992 #define LANG_HOOKS_TYPE_PROMOTES_TO d_type_promotes_to
1993 #define LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE d_get_sarif_source_language
1994
1995 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
1996
1997 #include "gt-d-d-lang.h"
1998 #include "gtype-d.h"