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