Skip several gcc.dg/builtin-dynamic-object-size tests on hppa*-*-hpux*
[official-gcc.git] / gcc / d / d-lang.cc
blob7840cf8a13283c5586e63a8d0e89ba819f137614
1 /* d-lang.cc -- Language-dependent hooks for D.
2 Copyright (C) 2006-2024 Free Software Foundation, Inc.
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.
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.
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/>. */
18 #include "config.h"
19 #include "system.h"
20 #include "coretypes.h"
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"
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"
56 #include "d-tree.h"
57 #include "d-frontend.h"
60 /* Array of D frontend type/decl nodes. */
61 tree d_global_trees[DTI_MAX];
63 /* True if compilation is currently inside the D frontend semantic passes. */
64 bool doing_semantic_analysis_p = false;
66 /* Options handled by the compiler that are separate from the frontend. */
67 struct d_option_data
69 const char *fonly; /* -fonly=<arg> */
70 const char *multilib; /* -imultilib <dir> */
71 const char *prefix; /* -iprefix <dir> */
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 */
80 bool stdinc; /* -nostdinc */
82 d_option;
84 /* List of modules being compiled. */
85 static Modules builtin_modules;
87 /* The current and global binding level in effect. */
88 struct binding_level *current_binding_level;
89 struct binding_level *global_binding_level;
91 /* The context to be used for global declarations. */
92 static GTY(()) tree global_context;
94 /* Array of all global declarations to pass back to the middle-end. */
95 static GTY(()) vec <tree, va_gc> *global_declarations;
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. */
101 static void
102 deps_add_target (const char *target, bool quoted)
104 obstack buffer;
105 gcc_obstack_init (&buffer);
107 if (!quoted)
109 obstack_grow0 (&buffer, target, strlen (target));
110 d_option.deps_target.safe_push ((const char *) obstack_finish (&buffer));
111 return;
114 /* Quote characters in target which are significant to Make. */
115 unsigned slashes = 0;
117 for (const char *p = target; *p != '\0'; p++)
119 switch (*p)
121 case '\\':
122 slashes++;
123 break;
125 case ' ':
126 case '\t':
127 while (slashes--)
128 obstack_1grow (&buffer, '\\');
129 obstack_1grow (&buffer, '\\');
130 goto Ldef;
132 case '$':
133 obstack_1grow (&buffer, '$');
134 goto Ldef;
136 case '#':
137 case ':':
138 obstack_1grow (&buffer, '\\');
139 goto Ldef;
141 default:
142 Ldef:
143 slashes = 0;
144 break;
147 obstack_1grow (&buffer, *p);
150 obstack_1grow (&buffer, '\0');
151 d_option.deps_target.safe_push ((const char *) obstack_finish (&buffer));
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). */
157 static void
158 deps_write_string (const char *str, obstack *buffer, unsigned &column,
159 unsigned colmax = 72)
161 unsigned size = strlen (str);
163 if (column != 0)
165 if (colmax && column + size > colmax)
167 obstack_grow (buffer, " \\\n ", 4);
168 column = 1;
170 else
172 obstack_1grow (buffer, ' ');
173 column++;
177 column += size;
178 obstack_grow (buffer, str, size);
181 /* Write out all dependencies of a given MODULE to the specified BUFFER. */
183 static void
184 deps_write (Module *module, obstack *buffer)
186 hash_set <const char *> seen_modules;
187 vec <const char *> dependencies = vNULL;
189 Modules modlist;
190 modlist.push (module);
192 vec <const char *> phonylist = vNULL;
193 unsigned column = 0;
195 /* Write out make target module name. */
196 if (d_option.deps_target.length ())
198 for (unsigned i = 0; i < d_option.deps_target.length (); i++)
199 deps_write_string (d_option.deps_target[i], buffer, column);
201 else
202 deps_write_string (module->objfile.toChars (), buffer, column);
204 obstack_1grow (buffer, ':');
205 column++;
207 /* Search all modules for file dependencies. */
208 while (modlist.length > 0)
210 Module *depmod = modlist.pop ();
212 const char *modstr = depmod->srcfile.toChars ();
214 /* Skip modules that have already been looked at. */
215 if (seen_modules.add (modstr))
216 continue;
218 dependencies.safe_push (modstr);
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);
224 /* Add imported files to dependency list. */
225 for (size_t i = 0; i < depmod->contentImportedFiles.length; i++)
227 const char *impstr = depmod->contentImportedFiles[i];
228 dependencies.safe_push (impstr);
229 phonylist.safe_push (impstr);
232 /* Search all imports of the module. */
233 for (size_t i = 0; i < depmod->aimports.length; i++)
235 Module *m = depmod->aimports[i];
237 /* Ignore compiler-generated modules. */
238 if (m->ident == Identifier::idPool ("__main") && m->parent == NULL)
239 continue;
241 /* Don't search system installed modules, this includes
242 object, core.*, std.*, and gcc.* packages. */
243 if (d_option.deps_skip_system)
245 if (m->ident == Identifier::idPool ("object")
246 && m->parent == NULL)
247 continue;
249 if (m->md && m->md->packages.length)
251 Identifier *package = m->md->packages.ptr[0];
253 if (package == Identifier::idPool ("core")
254 || package == Identifier::idPool ("std")
255 || package == Identifier::idPool ("gcc"))
256 continue;
260 modlist.push (m);
264 /* Write out all make dependencies. */
265 for (size_t i = 0; i < dependencies.length (); i++)
266 deps_write_string (dependencies[i], buffer, column);
268 obstack_1grow (buffer, '\n');
270 /* Write out all phony targets. */
271 for (size_t i = 0; i < phonylist.length (); i++)
273 const char *str = phonylist[i];
274 obstack_1grow (buffer, '\n');
275 obstack_grow (buffer, str, strlen (str));
276 obstack_grow (buffer, ":\n", 2);
279 obstack_1grow (buffer, '\0');
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. */
286 static void
287 d_init_options (unsigned int, cl_decoded_option *decoded_options)
289 /* Initialize the D runtime. */
290 rt_init ();
291 gc_disable ();
293 /* Set default values. */
294 global._init ();
296 global.compileEnv.vendor = lang_hooks.name;
297 global.params.argv0 = xstrdup (decoded_options[0].arg);
299 /* Default extern(C++) mangling to C++17. */
300 global.params.cplusplus = CppStdRevisionCpp17;
302 /* Warnings and deprecations are disabled by default. */
303 global.params.useDeprecated = DIAGNOSTICinform;
304 global.params.warnings = DIAGNOSTICoff;
305 global.params.v.errorLimit = flag_max_errors;
306 global.params.v.messageStyle = MessageStyle::gnu;
308 global.params.imppath = d_gc_malloc<Strings> ();
309 global.params.fileImppath = d_gc_malloc<Strings> ();
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;
324 /* Implements the lang_hooks.init_options_struct routine for language D.
325 Initializes the options structure OPTS. */
327 static void
328 d_init_options_struct (gcc_options *opts)
330 /* GCC options. */
331 opts->x_flag_exceptions = 1;
333 /* Unlike C, there is no global `errno' variable. */
334 opts->x_flag_errno_math = 0;
335 opts->frontend_set_flag_errno_math = true;
337 /* D says that signed overflow is precisely defined. */
338 opts->x_flag_wrapv = 1;
341 /* Implements the lang_hooks.lang_mask routine for language D.
342 Returns language mask for option parsing. */
344 static unsigned int
345 d_option_lang_mask (void)
347 return CL_D;
350 /* Implements input charset and BOM skipping configuration for
351 diagnostics. */
352 static const char *d_input_charset_callback (const char * /*filename*/)
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;
363 /* Implements the lang_hooks.init routine for language D. */
365 static bool
366 d_init (void)
368 Type::_init ();
369 Id::initialize ();
370 Module::_init ();
371 Expression::_init ();
372 Objc::_init ();
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);
379 /* Back-end init. */
380 global_binding_level = ggc_cleared_alloc <binding_level> ();
381 current_binding_level = global_binding_level;
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);
389 d_init_builtins ();
391 if (flag_exceptions)
392 using_eh_for_cleanups ();
394 if (!supports_one_only ())
395 flag_weak_templates = 0;
397 /* This is the C main, not the D main. */
398 main_identifier_node = get_identifier ("main");
400 target._init (global.params);
401 d_init_versions ();
403 /* Insert all library-configured identifiers and import paths. */
404 add_import_paths (d_option.prefix, d_option.multilib, d_option.stdinc);
406 return 1;
409 /* Implements the lang_hooks.init_ts routine for language D. */
411 static void
412 d_init_ts (void)
414 MARK_TS_TYPED (FLOAT_MOD_EXPR);
415 MARK_TS_TYPED (UNSIGNED_RSHIFT_EXPR);
418 /* Implements the lang_hooks.handle_option routine for language D.
419 Handles D specific options. Return false if we didn't do anything. */
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)
427 opt_code code = (opt_code) scode;
428 bool result = true;
430 switch (code)
432 case OPT_fall_instantiations:
433 global.params.allInst = value;
434 break;
436 case OPT_fassert:
437 global.params.useAssert = value ? CHECKENABLEon : CHECKENABLEoff;
438 break;
440 case OPT_fbounds_check:
441 global.params.useArrayBounds = value ? CHECKENABLEon : CHECKENABLEoff;
442 break;
444 case OPT_fbounds_check_:
445 global.params.useArrayBounds = (value == 2) ? CHECKENABLEon
446 : (value == 1) ? CHECKENABLEsafeonly : CHECKENABLEoff;
447 break;
449 case OPT_fcheckaction_:
450 global.params.checkAction = (value == 0) ? CHECKACTION_D
451 : (value == 1) ? CHECKACTION_halt : CHECKACTION_context;
452 break;
454 case OPT_fdebug:
455 global.params.debuglevel = value ? 1 : 0;
456 break;
458 case OPT_fdebug_:
459 if (Identifier::isValidIdentifier (CONST_CAST (char *, arg)))
461 DebugCondition::addGlobalIdent (arg);
462 break;
465 error ("bad argument for %<-fdebug%>: %qs", arg);
466 break;
468 case OPT_fdoc:
469 global.params.ddoc.doOutput = value;
470 break;
472 case OPT_fdoc_dir_:
473 global.params.ddoc.doOutput = true;
474 global.params.ddoc.dir = arg;
475 break;
477 case OPT_fdoc_file_:
478 global.params.ddoc.doOutput = true;
479 global.params.ddoc.name = arg;
480 break;
482 case OPT_fdoc_inc_:
483 global.params.ddoc.files.push (arg);
484 break;
486 case OPT_fdruntime:
487 global.params.betterC = !value;
488 break;
490 case OPT_fdump_c___spec_:
491 global.params.cxxhdr.doOutput = true;
492 global.params.cxxhdr.name = arg;
493 break;
495 case OPT_fdump_c___spec_verbose:
496 global.params.cxxhdr.fullOutput = true;
497 break;
499 case OPT_fdump_d_original:
500 global.params.vcg_ast = value;
501 break;
503 case OPT_fexceptions:
504 global.params.useExceptions = value;
505 break;
507 case OPT_fextern_std_:
508 switch (value)
510 case CppStdRevisionCpp98:
511 case CppStdRevisionCpp11:
512 case CppStdRevisionCpp14:
513 case CppStdRevisionCpp17:
514 case CppStdRevisionCpp20:
515 global.params.cplusplus = (CppStdRevision) value;
516 break;
518 default:
519 error ("bad argument for %<-fextern-std%>: %qs", arg);
521 break;
523 case OPT_fignore_unknown_pragmas:
524 global.params.ignoreUnsupportedPragmas = value;
525 break;
527 case OPT_finvariants:
528 global.params.useInvariants = value ? CHECKENABLEon : CHECKENABLEoff;
529 break;
531 case OPT_fmain:
532 global.params.addMain = value;
533 break;
535 case OPT_fmodule_file_:
536 global.params.modFileAliasStrings.push (arg);
537 if (!strchr (arg, '='))
538 error ("bad argument for %<-fmodule-file%>: %qs", arg);
539 break;
541 case OPT_fmoduleinfo:
542 global.params.useModuleInfo = value;
543 break;
545 case OPT_fonly_:
546 d_option.fonly = arg;
547 break;
549 case OPT_fpostconditions:
550 global.params.useOut = value ? CHECKENABLEon : CHECKENABLEoff;
551 break;
553 case OPT_fpreconditions:
554 global.params.useIn = value ? CHECKENABLEon : CHECKENABLEoff;
555 break;
557 case OPT_fpreview_all:
558 global.params.ehnogc = value;
559 global.params.useDIP1000 = FeatureState::enabled;
560 global.params.useDIP1021 = value;
561 global.params.bitfields = value;
562 global.params.dtorFields = FeatureState::enabled;
563 global.params.fieldwise = FeatureState::enabled;
564 global.params.fixAliasThis = value;
565 global.params.previewIn = value;
566 global.params.fix16997 = value;
567 global.params.noSharedAccess = FeatureState::enabled;
568 global.params.rvalueRefParam = FeatureState::enabled;
569 global.params.inclusiveInContracts = value;
570 global.params.systemVariables = FeatureState::enabled;
571 global.params.fixImmutableConv = value;
572 break;
574 case OPT_fpreview_bitfields:
575 global.params.bitfields = value;
576 break;
578 case OPT_fpreview_dip1000:
579 global.params.useDIP1000 = FeatureState::enabled;
580 break;
582 case OPT_fpreview_dip1008:
583 global.params.ehnogc = value;
584 break;
586 case OPT_fpreview_dip1021:
587 global.params.useDIP1021 = value;
588 break;
590 case OPT_fpreview_dtorfields:
591 global.params.dtorFields = FeatureState::enabled;
592 break;
594 case OPT_fpreview_fieldwise:
595 global.params.fieldwise = FeatureState::enabled;
596 break;
598 case OPT_fpreview_fixaliasthis:
599 global.params.fixAliasThis = value;
600 break;
602 case OPT_fpreview_fiximmutableconv:
603 global.params.fixImmutableConv = value;
604 break;
606 case OPT_fpreview_in:
607 global.params.previewIn = value;
608 break;
610 case OPT_fpreview_inclusiveincontracts:
611 global.params.inclusiveInContracts = value;
612 break;
614 case OPT_fpreview_nosharedaccess:
615 global.params.noSharedAccess = FeatureState::enabled;
616 break;
618 case OPT_fpreview_rvaluerefparam:
619 global.params.rvalueRefParam = FeatureState::enabled;
620 break;
622 case OPT_fpreview_systemvariables:
623 global.params.systemVariables = FeatureState::enabled;
624 break;
626 case OPT_frelease:
627 global.params.release = value;
628 break;
630 case OPT_frevert_all:
631 global.params.useDIP1000 = FeatureState::disabled;
632 global.params.dtorFields = FeatureState::disabled;
633 global.params.fix16997 = !value;
634 break;
636 case OPT_frevert_dip1000:
637 global.params.useDIP1000 = FeatureState::disabled;
638 break;
640 case OPT_frevert_dtorfields:
641 global.params.dtorFields = FeatureState::disabled;
642 break;
644 case OPT_frevert_intpromote:
645 global.params.fix16997 = !value;
646 break;
648 case OPT_frtti:
649 global.params.useTypeInfo = value;
650 break;
652 case OPT_fsave_mixins_:
653 global.params.mixinOut.doOutput = true;
654 global.params.mixinOut.name = arg;
655 global.params.mixinOut.buffer = d_gc_malloc<OutBuffer> ();
656 break;
658 case OPT_fswitch_errors:
659 global.params.useSwitchError = value ? CHECKENABLEon : CHECKENABLEoff;
660 break;
662 case OPT_ftransition_all:
663 global.params.v.field = value;
664 global.params.v.gc = value;
665 global.params.v.vin = value;
666 global.params.v.tls = value;
667 break;
669 case OPT_ftransition_field:
670 global.params.v.field = value;
671 break;
673 case OPT_ftransition_in:
674 global.params.v.vin = value;
675 break;
677 case OPT_ftransition_nogc:
678 global.params.v.gc = value;
679 break;
681 case OPT_ftransition_templates:
682 global.params.v.templates = value;
683 break;
685 case OPT_ftransition_tls:
686 global.params.v.tls = value;
687 break;
689 case OPT_funittest:
690 global.params.useUnitTests = value;
691 break;
693 case OPT_fversion_:
694 if (Identifier::isValidIdentifier (CONST_CAST (char *, arg)))
696 VersionCondition::addGlobalIdent (arg);
697 break;
700 error ("bad argument for %<-fversion%>: %qs", arg);
701 break;
703 case OPT_H:
704 global.params.dihdr.doOutput = true;
705 break;
707 case OPT_Hd:
708 global.params.dihdr.doOutput = true;
709 global.params.dihdr.dir = arg;
710 break;
712 case OPT_Hf:
713 global.params.dihdr.doOutput = true;
714 global.params.dihdr.name = arg;
715 break;
717 case OPT_imultilib:
718 d_option.multilib = arg;
719 break;
721 case OPT_iprefix:
722 d_option.prefix = arg;
723 break;
725 case OPT_I:
726 global.params.imppath->push (arg);
727 break;
729 case OPT_J:
730 global.params.fileImppath->push (arg);
731 break;
733 case OPT_MM:
734 d_option.deps_skip_system = true;
735 /* Fall through. */
737 case OPT_M:
738 d_option.deps = true;
739 break;
741 case OPT_MMD:
742 d_option.deps_skip_system = true;
743 /* Fall through. */
745 case OPT_MD:
746 d_option.deps = true;
747 d_option.deps_filename = arg;
748 break;
750 case OPT_MF:
751 /* If specified multiple times, last one wins. */
752 d_option.deps_filename_user = arg;
753 break;
755 case OPT_MP:
756 d_option.deps_phony = true;
757 break;
759 case OPT_MQ:
760 deps_add_target (arg, true);
761 break;
763 case OPT_MT:
764 deps_add_target (arg, false);
765 break;
767 case OPT_nostdinc:
768 d_option.stdinc = false;
769 break;
771 case OPT_v:
772 global.params.v.verbose = value;
773 break;
775 case OPT_Wall:
776 if (value)
777 global.params.warnings = DIAGNOSTICinform;
778 break;
780 case OPT_Wdeprecated:
781 global.params.useDeprecated = value ? DIAGNOSTICinform : DIAGNOSTICoff;
782 break;
784 case OPT_Werror:
785 if (value)
786 global.params.warnings = DIAGNOSTICerror;
787 break;
789 case OPT_Wspeculative:
790 if (value)
791 global.params.v.showGaggedErrors = 1;
792 break;
794 case OPT_Xf:
795 global.params.json.name = arg;
796 /* Fall through. */
798 case OPT_X:
799 global.params.json.doOutput = true;
800 break;
802 default:
803 break;
806 D_handle_option_auto (&global_options, &global_options_set,
807 scode, arg, value,
808 d_option_lang_mask (), kind,
809 loc, handlers, global_dc);
811 return result;
814 /* Implements the lang_hooks.post_options routine for language D.
815 Deal with any options that imply the turning on/off of features.
816 FN is the main input filename passed on the command line. */
818 static bool
819 d_post_options (const char ** fn)
821 /* Verify the input file name. */
822 const char *filename = *fn;
823 if (!filename || strcmp (filename, "-") == 0)
824 filename = "";
826 /* The front end considers the first input file to be the main one. */
827 *fn = filename;
829 /* Release mode doesn't turn off bounds checking for safe functions. */
830 if (global.params.useArrayBounds == CHECKENABLEdefault)
832 global.params.useArrayBounds = global.params.release
833 ? CHECKENABLEsafeonly : CHECKENABLEon;
836 /* Assert code is generated if unittests are being compiled also, even if
837 release mode is turned on. */
838 if (global.params.useAssert == CHECKENABLEdefault)
840 if (global.params.useUnitTests || !global.params.release)
841 global.params.useAssert = CHECKENABLEon;
842 else
843 global.params.useAssert = CHECKENABLEoff;
846 /* Checks for switches without a default are turned off in release mode. */
847 if (global.params.useSwitchError == CHECKENABLEdefault)
849 global.params.useSwitchError = global.params.release
850 ? CHECKENABLEoff : CHECKENABLEon;
853 /* Contracts are turned off in release mode. */
854 if (global.params.useInvariants == CHECKENABLEdefault)
856 global.params.useInvariants = global.params.release
857 ? CHECKENABLEoff : CHECKENABLEon;
860 if (global.params.useIn == CHECKENABLEdefault)
862 global.params.useIn = global.params.release
863 ? CHECKENABLEoff : CHECKENABLEon;
866 if (global.params.useOut == CHECKENABLEdefault)
868 global.params.useOut = global.params.release
869 ? CHECKENABLEoff : CHECKENABLEon;
872 /* When not linking against D runtime, turn off all code generation that
873 would otherwise reference it. */
874 if (global.params.betterC)
876 if (!OPTION_SET_P (flag_moduleinfo))
877 global.params.useModuleInfo = false;
879 /* Ensure that the front-end options are in sync with the `-frtti' and
880 `-fexceptions' flags. */
881 if (!OPTION_SET_P (flag_rtti))
883 global.params.useTypeInfo = false;
884 flag_rtti = false;
887 if (!OPTION_SET_P (flag_exceptions))
889 global.params.useExceptions = false;
890 flag_exceptions = false;
893 global.params.useGC = false;
894 global.params.checkAction = CHECKACTION_C;
897 /* Enabling DIP1021 implies DIP1000. */
898 if (global.params.useDIP1021)
899 global.params.useDIP1000 = FeatureState::enabled;
901 /* Keep in sync with existing -fbounds-check flag. */
902 flag_bounds_check = (global.params.useArrayBounds == CHECKENABLEon);
904 /* Turn off partitioning unless it was explicitly requested, as it doesn't
905 work with D exception chaining, where EH handler uses LSDA to determine
906 whether two thrown exception are in the same context. */
907 if (!OPTION_SET_P (flag_reorder_blocks_and_partition))
908 global_options.x_flag_reorder_blocks_and_partition = 0;
910 /* Error about use of deprecated features. */
911 if (global.params.useDeprecated == DIAGNOSTICinform
912 && global.params.warnings == DIAGNOSTICerror)
913 global.params.useDeprecated = DIAGNOSTICerror;
915 if (flag_excess_precision == EXCESS_PRECISION_DEFAULT)
916 flag_excess_precision = EXCESS_PRECISION_STANDARD;
918 global.params.useInline = flag_inline_functions;
920 /* Make -fmax-errors visible to frontend's diagnostic machinery. */
921 if (OPTION_SET_P (flag_max_errors))
922 global.params.v.errorLimit = flag_max_errors;
924 global.params.v.showColumns = flag_show_column;
925 global.params.v.printErrorContext = flag_diagnostics_show_caret;
927 /* Keep the front-end location type in sync with params. */
928 Loc::set (global.params.v.showColumns, global.params.v.messageStyle);
930 if (global.params.useInline)
931 global.params.dihdr.fullOutput = true;
933 global.params.obj = !flag_syntax_only;
935 /* The front-end parser only has access to `compileEnv', synchronize its
936 fields with params. */
937 global.compileEnv.previewIn = global.params.previewIn;
938 global.compileEnv.ddocOutput = global.params.ddoc.doOutput;
940 if (warn_return_type == -1)
941 warn_return_type = 0;
943 return false;
946 /* Add the module M to the list of modules that may declare GCC builtins.
947 These are scanned after first semantic and before codegen passes.
948 See d_maybe_set_builtin() for the implementation. */
950 void
951 d_add_builtin_module (Module *m)
953 builtin_modules.push (m);
956 /* Writes to FILENAME. DATA is the full content of the file to be written. */
958 static void
959 d_write_file (const char *filename, const char *data)
961 FILE *stream;
963 if (filename && (filename[0] != '-' || filename[1] != '\0'))
964 stream = fopen (filename, "w");
965 else
966 stream = stdout;
968 if (!stream)
970 error ("unable to open %s for writing: %m", filename);
971 return;
974 fprintf (stream, "%s", data);
976 if (stream != stdout && (ferror (stream) || fclose (stream)))
977 error ("writing output file %s: %m", filename);
980 /* Read ddoc macro files named by the DDOCFILES, then write the concatenated
981 the contents into DDOCBUF. */
983 static void
984 d_read_ddoc_files (Strings &ddocfiles, OutBuffer &ddocbuf)
986 if (ddocbuf.length ())
987 return;
989 for (size_t i = 0; i < ddocfiles.length; i++)
991 int fd = open (ddocfiles[i], O_RDONLY);
992 bool ok = false;
993 struct stat buf;
995 if (fd == -1 || fstat (fd, &buf))
997 error ("unable to open %s for reading: %m", ddocfiles[i]);
998 continue;
1001 /* Check we've not been given a directory, or a file bigger than 4GB. */
1002 if (S_ISDIR (buf.st_mode))
1003 errno = ENOENT;
1004 else if (buf.st_size != unsigned (buf.st_size))
1005 errno = EMFILE;
1006 else
1008 unsigned size = unsigned (buf.st_size);
1009 char *buffer = (char *) xmalloc (size);
1011 if (read (fd, buffer, size) == ssize_t (size))
1013 ddocbuf.write (buffer, size);
1014 ok = true;
1017 free (buffer);
1020 close (fd);
1021 if (!ok)
1022 fatal_error (input_location, "reading ddoc file %s: %m", ddocfiles[i]);
1026 static void
1027 d_generate_ddoc_file (Module *m, OutBuffer &ddocbuf)
1029 input_location = make_location_t (m->loc);
1031 d_read_ddoc_files (global.params.ddoc.files, ddocbuf);
1033 OutBuffer ddocbuf_out;
1034 gendocfile (m, ddocbuf.peekChars (), ddocbuf.length (), global.datetime,
1035 global.errorSink, ddocbuf_out);
1037 d_write_file (m->docfile.toChars (), ddocbuf_out.peekChars ());
1040 /* Implements the lang_hooks.parse_file routine for language D. */
1042 static void
1043 d_parse_file (void)
1045 if (global.params.v.verbose)
1047 message ("binary %s", global.params.argv0.ptr);
1048 message ("version %s", global.versionChars ());
1050 if (global.versionids)
1052 obstack buffer;
1053 gcc_obstack_init (&buffer);
1054 obstack_grow (&buffer, "predefs ", 9);
1055 for (size_t i = 0; i < global.versionids->length; i++)
1057 Identifier *id = (*global.versionids)[i];
1058 const char *str = id->toChars ();
1059 obstack_1grow (&buffer, ' ');
1060 obstack_grow (&buffer, str, strlen (str));
1063 obstack_1grow (&buffer, '\0');
1064 message ("%s", (char *) obstack_finish (&buffer));
1068 /* Start the main input file, if the debug writer wants it. */
1069 if (debug_hooks->start_end_main_source_file)
1070 debug_hooks->start_source_file (0, main_input_filename);
1072 /* Create Module's for all sources we will load. */
1073 Modules modules;
1074 modules.reserve (num_in_fnames);
1076 /* Buffer for contents of .ddoc files. */
1077 OutBuffer ddocbuf;
1079 /* In this mode, the first file name is supposed to be a duplicate
1080 of one of the input files. */
1081 if (d_option.fonly && strcmp (d_option.fonly, main_input_filename) != 0)
1082 error ("%<-fonly=%> argument is different from first input file name");
1084 for (size_t i = 0; i < num_in_fnames; i++)
1086 if (strcmp (in_fnames[i], "-") == 0)
1088 /* Load the entire contents of stdin into memory. 8 kilobytes should
1089 be a good enough initial size, but double on each iteration.
1090 16 bytes are added for the final '\n' and 15 bytes of padding. */
1091 ssize_t size = 8 * 1024;
1092 uchar *buffer = XNEWVEC (uchar, size + 16);
1093 ssize_t len = 0;
1094 ssize_t count;
1096 while ((count = read (STDIN_FILENO, buffer + len, size - len)) > 0)
1098 len += count;
1099 if (len == size)
1101 size *= 2;
1102 buffer = XRESIZEVEC (uchar, buffer, size + 16);
1106 if (count < 0)
1108 error (Loc ("stdin", 0, 0), "%s", xstrerror (errno));
1109 free (buffer);
1110 continue;
1113 /* Handling stdin, generate a unique name for the module. */
1114 Module *m = Module::create (in_fnames[i],
1115 Identifier::idPool ("__stdin"),
1116 global.params.ddoc.doOutput,
1117 global.params.dihdr.doOutput);
1118 modules.push (m);
1120 /* Zero the padding past the end of the buffer so the D lexer has a
1121 sentinel. The lexer only reads up to 4 bytes at a time. */
1122 memset (buffer + len, '\0', 16);
1124 /* Overwrite the source file for the module, the one created by
1125 Module::create would have a forced a `.d' suffix. */
1126 m->src.length = len;
1127 m->src.ptr = buffer;
1129 else
1131 /* Handling a D source file, strip off the path and extension. */
1132 const char *basename = FileName::name (in_fnames[i]);
1133 const char *name = FileName::removeExt (basename);
1135 Module *m = Module::create (in_fnames[i], Identifier::idPool (name),
1136 global.params.ddoc.doOutput,
1137 global.params.dihdr.doOutput);
1138 modules.push (m);
1139 FileName::free (name);
1143 /* Read all D source files. */
1144 for (size_t i = 0; i < modules.length; i++)
1146 Module *m = modules[i];
1147 m->read (Loc ());
1150 /* Parse all D source files. */
1151 for (size_t i = 0; i < modules.length; i++)
1153 Module *m = modules[i];
1155 if (global.params.v.verbose)
1156 message ("parse %s", m->toChars ());
1158 if (!Module::rootModule)
1159 Module::rootModule = m;
1161 m->importedFrom = m;
1162 m->parse ();
1164 if (m->filetype == FileType::ddoc)
1166 d_generate_ddoc_file (m, ddocbuf);
1168 /* Remove M from list of modules. */
1169 modules.remove (i);
1170 i--;
1174 /* Load the module containing D main. */
1175 Module *main_module = NULL;
1176 if (global.params.addMain)
1178 unsigned errors = global.startGagging ();
1179 main_module = Module::load (Loc (), NULL, Identifier::idPool ("__main"));
1181 if (!global.endGagging (errors))
1183 main_module->importedFrom = main_module;
1184 modules.push (main_module);
1188 /* If an error occurs later during compilation, remember that we generated
1189 the headers, so that they can be removed before exit. */
1190 bool dump_headers = false;
1192 if (global.errors)
1193 goto had_errors;
1195 if (global.params.dihdr.doOutput)
1197 /* Generate 'header' import files. Since 'header' import files must be
1198 independent of command line switches and what else is imported, they
1199 are generated before any semantic analysis. */
1200 for (size_t i = 0; i < modules.length; i++)
1202 Module *m = modules[i];
1203 if (m->filetype == FileType::dhdr
1204 || (d_option.fonly && m != Module::rootModule))
1205 continue;
1207 if (global.params.v.verbose)
1208 message ("import %s", m->toChars ());
1210 OutBuffer buf;
1211 genhdrfile (m, buf);
1212 d_write_file (m->hdrfile.toChars (), buf.peekChars ());
1215 dump_headers = true;
1218 if (global.errors)
1219 goto had_errors;
1221 /* Load all unconditional imports for better symbol resolving. */
1222 for (size_t i = 0; i < modules.length; i++)
1224 Module *m = modules[i];
1226 if (global.params.v.verbose)
1227 message ("importall %s", m->toChars ());
1229 m->importAll (NULL);
1232 if (global.errors)
1233 goto had_errors;
1235 /* Do semantic analysis. */
1236 doing_semantic_analysis_p = true;
1238 for (size_t i = 0; i < modules.length; i++)
1240 Module *m = modules[i];
1242 /* If this is the `__main` module, check that `D main` hasn't already
1243 been declared in user code before running semantic on it. */
1244 if (m == main_module && global.hasMainFunction)
1246 modules.remove (i);
1247 continue;
1250 if (global.params.v.verbose)
1251 message ("semantic %s", m->toChars ());
1253 dsymbolSemantic (m, NULL);
1256 /* Do deferred semantic analysis. */
1257 Module::runDeferredSemantic ();
1259 if (Module::deferred.length)
1261 for (size_t i = 0; i < Module::deferred.length; i++)
1263 Dsymbol *sd = Module::deferred[i];
1264 error_at (make_location_t (sd->loc),
1265 "unable to resolve forward reference in definition");
1269 /* Process all built-in modules or functions now for CTFE. */
1270 while (builtin_modules.length != 0)
1272 Module *m = builtin_modules.pop ();
1273 d_maybe_set_builtin (m);
1276 /* Do pass 2 semantic analysis. */
1277 for (size_t i = 0; i < modules.length; i++)
1279 Module *m = modules[i];
1281 if (global.params.v.verbose)
1282 message ("semantic2 %s", m->toChars ());
1284 semantic2 (m, NULL);
1287 Module::runDeferredSemantic2 ();
1289 if (global.errors)
1290 goto had_errors;
1292 /* Do pass 3 semantic analysis. */
1293 for (size_t i = 0; i < modules.length; i++)
1295 Module *m = modules[i];
1297 if (global.params.v.verbose)
1298 message ("semantic3 %s", m->toChars ());
1300 semantic3 (m, NULL);
1303 Module::runDeferredSemantic3 ();
1305 /* Check again, incase semantic3 pass loaded any more modules. */
1306 while (builtin_modules.length != 0)
1308 Module *m = builtin_modules.pop ();
1309 d_maybe_set_builtin (m);
1312 /* Do not attempt to generate output files if errors or warnings occurred. */
1313 if (global.errors || global.warnings)
1314 goto had_errors;
1316 /* Generate output files. */
1317 doing_semantic_analysis_p = false;
1319 if (Module::rootModule)
1321 /* Declare the name of the root module as the first global name in order
1322 to make the middle-end fully deterministic. */
1323 OutBuffer buf;
1324 mangleToBuffer (Module::rootModule, buf);
1325 first_global_object_name = buf.extractChars ();
1328 /* Make dependencies. */
1329 if (d_option.deps)
1331 obstack buffer;
1332 gcc_obstack_init (&buffer);
1334 for (size_t i = 0; i < modules.length; i++)
1335 deps_write (modules[i], &buffer);
1337 /* -MF <arg> overrides -M[M]D. */
1338 if (d_option.deps_filename_user)
1339 d_option.deps_filename = d_option.deps_filename_user;
1341 d_write_file (d_option.deps_filename,
1342 (char *) obstack_finish (&buffer));
1345 if (global.params.v.templates)
1346 printTemplateStats ();
1348 /* Generate JSON files. */
1349 if (global.params.json.doOutput)
1351 OutBuffer buf;
1352 json_generate (modules, buf);
1353 d_write_file (global.params.json.name.ptr, buf.peekChars ());
1356 /* Generate Ddoc files. */
1357 if (global.params.ddoc.doOutput && !global.errors && !errorcount)
1359 for (size_t i = 0; i < modules.length; i++)
1361 Module *m = modules[i];
1362 d_generate_ddoc_file (m, ddocbuf);
1366 /* Handle -fdump-d-original. */
1367 if (global.params.vcg_ast)
1369 for (size_t i = 0; i < modules.length; i++)
1371 Module *m = modules[i];
1372 OutBuffer buf;
1373 buf.doindent = 1;
1375 moduleToBuffer (buf, m);
1376 message ("%s", buf.peekChars ());
1380 /* Generate C++ header files. */
1381 if (global.params.cxxhdr.doOutput)
1382 genCppHdrFiles (modules);
1384 if (global.errors)
1385 goto had_errors;
1387 for (size_t i = 0; i < modules.length; i++)
1389 Module *m = modules[i];
1391 /* Skip generating code for header files, or when the module wasn't
1392 specified by `-fonly=`. */
1393 if ((m->filetype == FileType::dhdr && m != main_module)
1394 || (d_option.fonly && m != Module::rootModule))
1395 continue;
1397 if (global.params.v.verbose)
1398 message ("code %s", m->toChars ());
1400 if (!flag_syntax_only)
1401 build_decl_tree (m);
1404 /* And end the main input file, if the debug writer wants it. */
1405 if (debug_hooks->start_end_main_source_file)
1406 debug_hooks->end_source_file (0);
1408 had_errors:
1409 /* Add the D frontend error count to the GCC error count to correctly
1410 exit with an error status. */
1411 errorcount += (global.errors + global.warnings);
1413 /* We want to write the mixin expansion file also on error. */
1414 if (global.params.mixinOut.doOutput)
1416 d_write_file (global.params.mixinOut.name.ptr,
1417 global.params.mixinOut.buffer->peekChars ());
1420 /* Remove generated .di files on error. */
1421 if (errorcount && dump_headers)
1423 for (size_t i = 0; i < modules.length; i++)
1425 Module *m = modules[i];
1426 if (m->filetype == FileType::dhdr
1427 || (d_option.fonly && m != Module::rootModule))
1428 continue;
1430 remove (m->hdrfile.toChars ());
1434 /* Write out globals. */
1435 d_finish_compilation (vec_safe_address (global_declarations),
1436 vec_safe_length (global_declarations));
1439 /* Implements the lang_hooks.types.type_for_mode routine for language D. */
1441 static tree
1442 d_type_for_mode (machine_mode mode, int unsignedp)
1444 if (mode == QImode)
1445 return unsignedp ? d_ubyte_type : d_byte_type;
1447 if (mode == HImode)
1448 return unsignedp ? d_ushort_type : d_short_type;
1450 if (mode == SImode)
1451 return unsignedp ? d_uint_type : d_int_type;
1453 if (mode == DImode)
1454 return unsignedp ? d_ulong_type : d_long_type;
1456 if (mode == TYPE_MODE (d_cent_type))
1457 return unsignedp ? d_ucent_type : d_cent_type;
1459 if (mode == TYPE_MODE (float_type_node))
1460 return float_type_node;
1462 if (mode == TYPE_MODE (double_type_node))
1463 return double_type_node;
1465 if (mode == TYPE_MODE (long_double_type_node))
1466 return long_double_type_node;
1468 if (mode == TYPE_MODE (build_pointer_type (char8_type_node)))
1469 return build_pointer_type (char8_type_node);
1471 if (mode == TYPE_MODE (build_pointer_type (d_int_type)))
1472 return build_pointer_type (d_int_type);
1474 for (int i = 0; i < NUM_INT_N_ENTS; i ++)
1476 if (int_n_enabled_p[i] && mode == int_n_data[i].m)
1478 if (unsignedp)
1479 return int_n_trees[i].unsigned_type;
1480 else
1481 return int_n_trees[i].signed_type;
1485 if (COMPLEX_MODE_P (mode))
1487 machine_mode inner_mode;
1488 tree inner_type;
1490 if (mode == TYPE_MODE (complex_float_type_node))
1491 return complex_float_type_node;
1492 if (mode == TYPE_MODE (complex_double_type_node))
1493 return complex_double_type_node;
1494 if (mode == TYPE_MODE (complex_long_double_type_node))
1495 return complex_long_double_type_node;
1497 inner_mode = (machine_mode) GET_MODE_INNER (mode);
1498 inner_type = d_type_for_mode (inner_mode, unsignedp);
1499 if (inner_type != NULL_TREE)
1500 return build_complex_type (inner_type);
1502 else if (VECTOR_MODE_P (mode))
1504 machine_mode inner_mode = (machine_mode) GET_MODE_INNER (mode);
1505 tree inner_type = d_type_for_mode (inner_mode, unsignedp);
1506 if (inner_type != NULL_TREE)
1507 return build_vector_type_for_mode (inner_type, mode);
1510 return 0;
1513 /* Implements the lang_hooks.types.type_for_size routine for language D. */
1515 static tree
1516 d_type_for_size (unsigned bits, int unsignedp)
1518 if (bits <= TYPE_PRECISION (d_byte_type))
1519 return unsignedp ? d_ubyte_type : d_byte_type;
1521 if (bits <= TYPE_PRECISION (d_short_type))
1522 return unsignedp ? d_ushort_type : d_short_type;
1524 if (bits <= TYPE_PRECISION (d_int_type))
1525 return unsignedp ? d_uint_type : d_int_type;
1527 if (bits <= TYPE_PRECISION (d_long_type))
1528 return unsignedp ? d_ulong_type : d_long_type;
1530 if (bits <= TYPE_PRECISION (d_cent_type))
1531 return unsignedp ? d_ucent_type : d_cent_type;
1533 for (int i = 0; i < NUM_INT_N_ENTS; i ++)
1535 if (int_n_enabled_p[i] && bits == int_n_data[i].bitsize)
1537 if (unsignedp)
1538 return int_n_trees[i].unsigned_type;
1539 else
1540 return int_n_trees[i].signed_type;
1544 return 0;
1547 /* Implements the lang_hooks.types.type_promotes_to routine for language D. */
1549 static tree
1550 d_type_promotes_to (tree type)
1552 /* Promotions are only applied on unnamed function arguments for declarations
1553 with `extern(C)' or `extern(C++)' linkage. */
1554 if (cfun && DECL_LANG_FRONTEND (cfun->decl)
1555 && DECL_LANG_FRONTEND (cfun->decl)->resolvedLinkage () != LINK::d)
1557 /* In [type/integer-promotions], integer promotions are conversions of the
1558 following types:
1560 bool int
1561 byte int
1562 ubyte int
1563 short int
1564 ushort int
1565 char int
1566 wchar int
1567 dchar uint
1569 If an enum has as a base type one of the types in the left column, it
1570 is converted to the type in the right column. */
1571 if (TREE_CODE (type) == ENUMERAL_TYPE && ENUM_IS_SCOPED (type))
1572 type = TREE_TYPE (type);
1574 type = TYPE_MAIN_VARIANT (type);
1576 /* Check for promotions of target-defined types first. */
1577 tree promoted_type = targetm.promoted_type (type);
1578 if (promoted_type)
1579 return promoted_type;
1581 if (TREE_CODE (type) == BOOLEAN_TYPE)
1582 return d_int_type;
1584 if (INTEGRAL_TYPE_P (type))
1586 if (type == d_byte_type || type == d_ubyte_type
1587 || type == d_short_type || type == d_ushort_type
1588 || type == char8_type_node || type == char16_type_node)
1589 return d_int_type;
1591 if (type == char32_type_node)
1592 return d_uint_type;
1594 if (TYPE_PRECISION (type) < TYPE_PRECISION (d_int_type))
1595 return d_int_type;
1598 /* Float arguments are converted to doubles. */
1599 if (type == float_type_node)
1600 return double_type_node;
1602 if (type == ifloat_type_node)
1603 return idouble_type_node;
1606 return type;
1609 /* Implements the lang_hooks.decls.global_bindings_p routine for language D.
1610 Return true if we are in the global binding level. */
1612 static bool
1613 d_global_bindings_p (void)
1615 return (current_binding_level == global_binding_level);
1618 /* Return global_context, but create it first if need be. */
1620 static tree
1621 get_global_context (void)
1623 if (!global_context)
1625 global_context = build_translation_unit_decl (NULL_TREE);
1626 debug_hooks->register_main_translation_unit (global_context);
1629 return global_context;
1632 /* Implements the lang_hooks.decls.pushdecl routine for language D.
1633 Record DECL as belonging to the current lexical scope. */
1635 tree
1636 d_pushdecl (tree decl)
1638 /* Set the context of the decl. If current_function_decl did not help in
1639 determining the context, use global scope. */
1640 if (!DECL_CONTEXT (decl))
1642 if (current_function_decl)
1643 DECL_CONTEXT (decl) = current_function_decl;
1644 else
1645 DECL_CONTEXT (decl) = get_global_context ();
1648 /* Put decls on list in reverse order. */
1649 if (TREE_STATIC (decl) || d_global_bindings_p ())
1650 vec_safe_push (global_declarations, decl);
1651 else
1653 TREE_CHAIN (decl) = current_binding_level->names;
1654 current_binding_level->names = decl;
1657 return decl;
1660 /* Implements the lang_hooks.decls.getdecls routine for language D.
1661 Return the list of declarations of the current level. */
1663 static tree
1664 d_getdecls (void)
1666 if (current_binding_level)
1667 return current_binding_level->names;
1669 return NULL_TREE;
1673 /* Implements the lang_hooks.get_alias_set routine for language D.
1674 Get the alias set corresponding to type or expression T.
1675 Return -1 if we don't do anything special. */
1677 static alias_set_type
1678 d_get_alias_set (tree)
1680 /* For now in D, assume everything aliases everything else, until we define
1681 some solid rules backed by a specification. There are also some parts
1682 of code generation routines that don't adhere to C alias rules, such as
1683 build_vconvert. In any case, a lot of user code already assumes there
1684 is no strict aliasing and will break if we were to change that. */
1685 return 0;
1688 /* Implements the lang_hooks.types_compatible_p routine for language D.
1689 Compares two types for equivalence in the D programming language.
1690 This routine should only return 1 if it is sure, even though the frontend
1691 should have already ensured that all types are compatible before handing
1692 over the parsed ASTs to the code generator. */
1694 static int
1695 d_types_compatible_p (tree x, tree y)
1697 Type *tx = TYPE_LANG_FRONTEND (x);
1698 Type *ty = TYPE_LANG_FRONTEND (y);
1700 /* Try validating the types in the frontend. */
1701 if (tx != NULL && ty != NULL)
1703 /* Types are equivalent. */
1704 if (same_type_p (tx, ty))
1705 return true;
1707 /* Type system allows implicit conversion between. */
1708 if (tx->implicitConvTo (ty) != MATCH::nomatch
1709 || ty->implicitConvTo (tx) != MATCH::nomatch)
1710 return true;
1713 /* Fallback on using type flags for comparison. E.g: all dynamic arrays
1714 are distinct types in D, but are VIEW_CONVERT compatible. */
1715 if (TREE_CODE (x) == RECORD_TYPE && TREE_CODE (y) == RECORD_TYPE)
1717 if (TYPE_DYNAMIC_ARRAY (x) && TYPE_DYNAMIC_ARRAY (y))
1718 return true;
1720 if (TYPE_DELEGATE (x) && TYPE_DELEGATE (y))
1721 return true;
1723 if (TYPE_ASSOCIATIVE_ARRAY (x) && TYPE_ASSOCIATIVE_ARRAY (y))
1724 return true;
1727 return false;
1730 /* Implements the lang_hooks.finish_incomplete_decl routine for language D. */
1732 static void
1733 d_finish_incomplete_decl (tree decl)
1735 if (VAR_P (decl))
1737 /* D allows zero-length declarations. Such a declaration ends up with
1738 DECL_SIZE (t) == NULL_TREE which is what the back-end function
1739 assembler_variable checks. This could change in later versions, or
1740 maybe all of these variables should be aliased to one symbol. */
1741 if (DECL_SIZE (decl) == 0)
1743 DECL_SIZE (decl) = bitsize_zero_node;
1744 DECL_SIZE_UNIT (decl) = size_zero_node;
1749 /* Implements the lang_hooks.types.classify_record routine for language D.
1750 Return the true debug type for TYPE. */
1752 static classify_record
1753 d_classify_record (tree type)
1755 Type *t = TYPE_LANG_FRONTEND (type);
1756 TypeClass *tc = t ? t->isTypeClass () : NULL;
1758 if (tc != NULL)
1760 /* extern(C++) interfaces get emitted as classes. */
1761 if (tc->sym->isInterfaceDeclaration ()
1762 && !tc->sym->isCPPinterface ())
1763 return RECORD_IS_INTERFACE;
1765 return RECORD_IS_CLASS;
1768 return RECORD_IS_STRUCT;
1771 /* Implements the lang_hooks.tree_size routine for language D.
1772 Determine the size of our tcc_constant or tcc_exceptional nodes. */
1774 static size_t
1775 d_tree_size (tree_code code)
1777 switch (code)
1779 case FUNCFRAME_INFO:
1780 return sizeof (tree_frame_info);
1782 default:
1783 gcc_unreachable ();
1787 /* Implements the lang_hooks.print_xnode routine for language D. */
1789 static void
1790 d_print_xnode (FILE *file, tree node, int indent)
1792 switch (TREE_CODE (node))
1794 case FUNCFRAME_INFO:
1795 print_node (file, "frame_type", FRAMEINFO_TYPE (node), indent + 4);
1796 break;
1798 default:
1799 break;
1803 /* Return which tree structure is used by NODE, or TS_D_GENERIC if NODE
1804 is one of the language-independent trees. */
1806 d_tree_node_structure_enum
1807 d_tree_node_structure (lang_tree_node *t)
1809 switch (TREE_CODE (&t->generic))
1811 case IDENTIFIER_NODE:
1812 return TS_D_IDENTIFIER;
1814 case FUNCFRAME_INFO:
1815 return TS_D_FRAMEINFO;
1817 default:
1818 return TS_D_GENERIC;
1822 /* Allocate and return a lang specific structure for the frontend type. */
1824 struct lang_type *
1825 build_lang_type (Type *t)
1827 struct lang_type *lt = ggc_cleared_alloc <struct lang_type> ();
1828 lt->type = t;
1829 return lt;
1832 /* Allocate and return a lang specific structure for the frontend decl. */
1834 struct lang_decl *
1835 build_lang_decl (Declaration *d)
1837 /* For compiler generated run-time typeinfo, a lang_decl is allocated even if
1838 there's no associated frontend symbol to refer to (yet). If the symbol
1839 appears later in the compilation, then the slot will be re-used. */
1840 if (d == NULL)
1841 return ggc_cleared_alloc <struct lang_decl> ();
1843 struct lang_decl *ld = (d->csym) ? DECL_LANG_SPECIFIC (d->csym) : NULL;
1844 if (ld == NULL)
1845 ld = ggc_cleared_alloc <struct lang_decl> ();
1847 if (ld->decl == NULL)
1848 ld->decl = d;
1850 return ld;
1853 /* Implements the lang_hooks.dup_lang_specific_decl routine for language D.
1854 Replace the DECL_LANG_SPECIFIC field of NODE with a copy. */
1856 static void
1857 d_dup_lang_specific_decl (tree node)
1859 if (!DECL_LANG_SPECIFIC (node))
1860 return;
1862 struct lang_decl *ld = ggc_alloc <struct lang_decl> ();
1863 memcpy (ld, DECL_LANG_SPECIFIC (node), sizeof (struct lang_decl));
1864 DECL_LANG_SPECIFIC (node) = ld;
1867 /* This preserves trees we create from the garbage collector. */
1869 static GTY(()) tree d_keep_list = NULL_TREE;
1871 void
1872 d_keep (tree t)
1874 d_keep_list = tree_cons (NULL_TREE, t, d_keep_list);
1877 /* Implements the lang_hooks.eh_personality routine for language D.
1878 Return the GDC personality function decl. */
1880 static GTY(()) tree d_eh_personality_decl;
1882 static tree
1883 d_eh_personality (void)
1885 if (!d_eh_personality_decl)
1886 d_eh_personality_decl = build_personality_function ("gdc");
1888 return d_eh_personality_decl;
1891 /* Implements the lang_hooks.eh_runtime_type routine for language D. */
1893 static tree
1894 d_build_eh_runtime_type (tree type)
1896 Type *t = TYPE_LANG_FRONTEND (type);
1897 gcc_assert (t != NULL);
1898 t = t->toBasetype ();
1900 ClassDeclaration *cd = t->isTypeClass ()->sym;
1901 tree decl;
1903 if (cd->isCPPclass ())
1904 decl = get_cpp_typeinfo_decl (cd);
1905 else
1906 decl = get_classinfo_decl (cd);
1908 return convert (ptr_type_node, build_address (decl));
1911 /* Implements the lang_hooks.enum_underlying_base_type routine for language D.
1912 Returns the underlying type of the given enumeration TYPE. */
1914 static tree
1915 d_enum_underlying_base_type (const_tree type)
1917 gcc_assert (TREE_CODE (type) == ENUMERAL_TYPE);
1918 return TREE_TYPE (type);
1921 /* Get a value for the SARIF v2.1.0 "artifact.sourceLanguage" property,
1922 based on the list in SARIF v2.1.0 Appendix J. */
1924 static const char *
1925 d_get_sarif_source_language (const char *)
1927 return "d";
1930 const scoped_attribute_specs *const d_langhook_attribute_table[] =
1932 &d_langhook_gnu_attribute_table,
1933 &d_langhook_common_attribute_table,
1936 /* Definitions for our language-specific hooks. */
1938 #undef LANG_HOOKS_NAME
1939 #undef LANG_HOOKS_INIT
1940 #undef LANG_HOOKS_INIT_TS
1941 #undef LANG_HOOKS_INIT_OPTIONS
1942 #undef LANG_HOOKS_INIT_OPTIONS_STRUCT
1943 #undef LANG_HOOKS_OPTION_LANG_MASK
1944 #undef LANG_HOOKS_HANDLE_OPTION
1945 #undef LANG_HOOKS_POST_OPTIONS
1946 #undef LANG_HOOKS_PARSE_FILE
1947 #undef LANG_HOOKS_ATTRIBUTE_TABLE
1948 #undef LANG_HOOKS_GET_ALIAS_SET
1949 #undef LANG_HOOKS_TYPES_COMPATIBLE_P
1950 #undef LANG_HOOKS_BUILTIN_FUNCTION
1951 #undef LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE
1952 #undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
1953 #undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
1954 #undef LANG_HOOKS_GIMPLIFY_EXPR
1955 #undef LANG_HOOKS_CLASSIFY_RECORD
1956 #undef LANG_HOOKS_TREE_SIZE
1957 #undef LANG_HOOKS_PRINT_XNODE
1958 #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
1959 #undef LANG_HOOKS_EH_PERSONALITY
1960 #undef LANG_HOOKS_EH_RUNTIME_TYPE
1961 #undef LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE
1962 #undef LANG_HOOKS_PUSHDECL
1963 #undef LANG_HOOKS_GETDECLS
1964 #undef LANG_HOOKS_GLOBAL_BINDINGS_P
1965 #undef LANG_HOOKS_TYPE_FOR_MODE
1966 #undef LANG_HOOKS_TYPE_FOR_SIZE
1967 #undef LANG_HOOKS_TYPE_PROMOTES_TO
1968 #undef LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE
1970 #define LANG_HOOKS_NAME "GNU D"
1971 #define LANG_HOOKS_INIT d_init
1972 #define LANG_HOOKS_INIT_TS d_init_ts
1973 #define LANG_HOOKS_INIT_OPTIONS d_init_options
1974 #define LANG_HOOKS_INIT_OPTIONS_STRUCT d_init_options_struct
1975 #define LANG_HOOKS_OPTION_LANG_MASK d_option_lang_mask
1976 #define LANG_HOOKS_HANDLE_OPTION d_handle_option
1977 #define LANG_HOOKS_POST_OPTIONS d_post_options
1978 #define LANG_HOOKS_PARSE_FILE d_parse_file
1979 #define LANG_HOOKS_ATTRIBUTE_TABLE d_langhook_attribute_table
1980 #define LANG_HOOKS_GET_ALIAS_SET d_get_alias_set
1981 #define LANG_HOOKS_TYPES_COMPATIBLE_P d_types_compatible_p
1982 #define LANG_HOOKS_BUILTIN_FUNCTION d_builtin_function
1983 #define LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE d_builtin_function_ext_scope
1984 #define LANG_HOOKS_REGISTER_BUILTIN_TYPE d_register_builtin_type
1985 #define LANG_HOOKS_FINISH_INCOMPLETE_DECL d_finish_incomplete_decl
1986 #define LANG_HOOKS_GIMPLIFY_EXPR d_gimplify_expr
1987 #define LANG_HOOKS_CLASSIFY_RECORD d_classify_record
1988 #define LANG_HOOKS_TREE_SIZE d_tree_size
1989 #define LANG_HOOKS_PRINT_XNODE d_print_xnode
1990 #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL d_dup_lang_specific_decl
1991 #define LANG_HOOKS_EH_PERSONALITY d_eh_personality
1992 #define LANG_HOOKS_EH_RUNTIME_TYPE d_build_eh_runtime_type
1993 #define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE d_enum_underlying_base_type
1994 #define LANG_HOOKS_PUSHDECL d_pushdecl
1995 #define LANG_HOOKS_GETDECLS d_getdecls
1996 #define LANG_HOOKS_GLOBAL_BINDINGS_P d_global_bindings_p
1997 #define LANG_HOOKS_TYPE_FOR_MODE d_type_for_mode
1998 #define LANG_HOOKS_TYPE_FOR_SIZE d_type_for_size
1999 #define LANG_HOOKS_TYPE_PROMOTES_TO d_type_promotes_to
2000 #define LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE d_get_sarif_source_language
2002 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
2004 #include "gt-d-d-lang.h"
2005 #include "gtype-d.h"