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