1 /* d-lang.cc -- Language-dependent hooks for D.
2 Copyright (C) 2006-2025 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)
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/>. */
20 #include "coretypes.h"
22 #include "dmd/aggregate.h"
24 #include "dmd/declaration.h"
26 #include "dmd/dsymbol.h"
27 #include "dmd/errors.h"
28 #include "dmd/expression.h"
29 #include "dmd/hdrgen.h"
31 #include "dmd/identifier.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"
42 #include "diagnostic.h"
43 #include "fold-const.h"
45 #include "langhooks.h"
46 #include "langhooks-def.h"
49 #include "stringpool.h"
50 #include "stor-layout.h"
53 #include "print-tree.h"
58 #include "d-frontend.h"
61 /* Array of D frontend type/decl nodes. */
62 tree d_global_trees
[DTI_MAX
];
64 /* True if compilation is currently inside the D frontend semantic passes. */
65 bool doing_semantic_analysis_p
= false;
67 /* Options handled by the compiler that are separate from the frontend. */
70 const char *fonly
; /* -fonly=<arg> */
71 const char *multilib
; /* -imultilib <dir> */
72 const char *prefix
; /* -iprefix <dir> */
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 */
81 bool stdinc
; /* -nostdinc */
85 /* List of modules being compiled. */
86 static Modules builtin_modules
;
88 /* The current and global binding level in effect. */
89 struct binding_level
*current_binding_level
;
90 struct binding_level
*global_binding_level
;
92 /* The context to be used for global declarations. */
93 static GTY(()) tree global_context
;
95 /* Array of all global declarations to pass back to the middle-end. */
96 static GTY(()) vec
<tree
, va_gc
> *global_declarations
;
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. */
103 deps_add_target (const char *target
, bool quoted
)
106 gcc_obstack_init (&buffer
);
110 obstack_grow0 (&buffer
, target
, strlen (target
));
111 d_option
.deps_target
.safe_push ((const char *) obstack_finish (&buffer
));
115 /* Quote characters in target which are significant to Make. */
116 unsigned slashes
= 0;
118 for (const char *p
= target
; *p
!= '\0'; p
++)
129 obstack_1grow (&buffer
, '\\');
130 obstack_1grow (&buffer
, '\\');
134 obstack_1grow (&buffer
, '$');
139 obstack_1grow (&buffer
, '\\');
148 obstack_1grow (&buffer
, *p
);
151 obstack_1grow (&buffer
, '\0');
152 d_option
.deps_target
.safe_push ((const char *) obstack_finish (&buffer
));
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). */
159 deps_write_string (const char *str
, obstack
*buffer
, unsigned &column
,
160 unsigned colmax
= 72)
162 unsigned size
= strlen (str
);
166 if (colmax
&& column
+ size
> colmax
)
168 obstack_grow (buffer
, " \\\n ", 4);
173 obstack_1grow (buffer
, ' ');
179 obstack_grow (buffer
, str
, size
);
182 /* Write out all dependencies of a given MODULE to the specified BUFFER. */
185 deps_write (Module
*module
, obstack
*buffer
)
187 hash_set
<const char *> seen_modules
;
188 vec
<const char *> dependencies
= vNULL
;
191 modlist
.push (module
);
193 vec
<const char *> phonylist
= vNULL
;
196 /* Write out make target module name. */
197 if (d_option
.deps_target
.length ())
199 for (unsigned i
= 0; i
< d_option
.deps_target
.length (); i
++)
200 deps_write_string (d_option
.deps_target
[i
], buffer
, column
);
203 deps_write_string (module
->objfile
.toChars (), buffer
, column
);
205 obstack_1grow (buffer
, ':');
208 /* Search all modules for file dependencies. */
209 while (modlist
.length
> 0)
211 Module
*depmod
= modlist
.pop ();
213 const char *modstr
= depmod
->srcfile
.toChars ();
215 /* Skip modules that have already been looked at. */
216 if (seen_modules
.add (modstr
))
219 dependencies
.safe_push (modstr
);
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
);
225 /* Add imported files to dependency list. */
226 for (size_t i
= 0; i
< depmod
->contentImportedFiles
.length
; i
++)
228 const char *impstr
= depmod
->contentImportedFiles
[i
];
229 dependencies
.safe_push (impstr
);
230 phonylist
.safe_push (impstr
);
233 /* Search all imports of the module. */
234 for (size_t i
= 0; i
< depmod
->aimports
.length
; i
++)
236 Module
*m
= depmod
->aimports
[i
];
238 /* Ignore compiler-generated modules. */
239 if (m
->ident
== Identifier::idPool ("__main") && m
->parent
== NULL
)
242 /* Don't search system installed modules, this includes
243 object, core.*, std.*, and gcc.* packages. */
244 if (d_option
.deps_skip_system
)
246 if (m
->ident
== Identifier::idPool ("object")
247 && m
->parent
== NULL
)
250 if (m
->md
&& m
->md
->packages
.length
)
252 Identifier
*package
= m
->md
->packages
.ptr
[0];
254 if (package
== Identifier::idPool ("core")
255 || package
== Identifier::idPool ("std")
256 || package
== Identifier::idPool ("gcc"))
265 /* Write out all make dependencies. */
266 for (size_t i
= 0; i
< dependencies
.length (); i
++)
267 deps_write_string (dependencies
[i
], buffer
, column
);
269 obstack_1grow (buffer
, '\n');
271 /* Write out all phony targets. */
272 for (size_t i
= 0; i
< phonylist
.length (); i
++)
274 const char *str
= phonylist
[i
];
275 obstack_1grow (buffer
, '\n');
276 obstack_grow (buffer
, str
, strlen (str
));
277 obstack_grow (buffer
, ":\n", 2);
280 obstack_1grow (buffer
, '\0');
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. */
288 d_init_options (unsigned int, cl_decoded_option
*decoded_options
)
290 /* Initialize the D runtime. */
294 /* Set default values. */
297 global
.compileEnv
.vendor
= lang_hooks
.name
;
298 global
.params
.argv0
= xstrdup (decoded_options
[0].arg
);
300 /* Default extern(C++) mangling to C++17. */
301 global
.params
.cplusplus
= CppStdRevisionCpp17
;
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
;
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;
322 /* Implements the lang_hooks.init_options_struct routine for language D.
323 Initializes the options structure OPTS. */
326 d_init_options_struct (gcc_options
*opts
)
329 opts
->x_flag_exceptions
= 1;
331 /* Unlike C, there is no global `errno' variable. */
332 opts
->x_flag_errno_math
= 0;
333 opts
->frontend_set_flag_errno_math
= true;
335 /* D says that signed overflow is precisely defined. */
336 opts
->x_flag_wrapv
= 1;
339 /* Implements the lang_hooks.lang_mask routine for language D.
340 Returns language mask for option parsing. */
343 d_option_lang_mask (void)
348 /* Implements input charset and BOM skipping configuration for
350 static const char *d_input_charset_callback (const char * /*filename*/)
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. */
361 /* Implements the lang_hooks.init routine for language D. */
369 Expression::_init ();
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);
378 global_binding_level
= ggc_cleared_alloc
<binding_level
> ();
379 current_binding_level
= global_binding_level
;
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);
390 using_eh_for_cleanups ();
392 if (!supports_one_only ())
393 flag_weak_templates
= 0;
395 /* This is the C main, not the D main. */
396 main_identifier_node
= get_identifier ("main");
398 target
._init (global
.params
);
401 /* Insert all library-configured identifiers and import paths. */
402 add_import_paths (d_option
.prefix
, d_option
.multilib
, d_option
.stdinc
);
407 /* Implements the lang_hooks.init_ts routine for language D. */
412 MARK_TS_TYPED (FLOAT_MOD_EXPR
);
413 MARK_TS_TYPED (UNSIGNED_RSHIFT_EXPR
);
416 /* Implements the lang_hooks.handle_option routine for language D.
417 Handles D specific options. Return false if we didn't do anything. */
420 d_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
)
425 opt_code code
= (opt_code
) scode
;
430 case OPT_fall_instantiations
:
431 global
.params
.allInst
= value
;
435 global
.params
.useAssert
= value
? CHECKENABLEon
: CHECKENABLEoff
;
438 case OPT_fbounds_check
:
439 global
.params
.useArrayBounds
= value
? CHECKENABLEon
: CHECKENABLEoff
;
442 case OPT_fbounds_check_
:
443 global
.params
.useArrayBounds
= (value
== 2) ? CHECKENABLEon
444 : (value
== 1) ? CHECKENABLEsafeonly
: CHECKENABLEoff
;
447 case OPT_fcheckaction_
:
448 global
.params
.checkAction
= (value
== 0) ? CHECKACTION_D
449 : (value
== 1) ? CHECKACTION_halt
: CHECKACTION_context
;
453 global
.params
.debugEnabled
= value
? true : false;
457 if (Identifier::isValidIdentifier (CONST_CAST (char *, arg
)))
459 DebugCondition::addGlobalIdent (arg
);
463 error ("bad argument for %<-fdebug=%>: %qs", arg
);
467 global
.params
.ddoc
.doOutput
= value
;
471 global
.params
.ddoc
.doOutput
= true;
472 global
.params
.ddoc
.dir
= arg
;
476 global
.params
.ddoc
.doOutput
= true;
477 global
.params
.ddoc
.name
= arg
;
481 global
.params
.ddoc
.files
.push (arg
);
485 global
.params
.betterC
= !value
;
488 case OPT_fdump_c___spec_
:
489 global
.params
.cxxhdr
.doOutput
= true;
490 global
.params
.cxxhdr
.name
= arg
;
493 case OPT_fdump_c___spec_verbose
:
494 global
.params
.cxxhdr
.fullOutput
= true;
497 case OPT_fdump_d_original
:
498 global
.params
.vcg_ast
= value
;
501 case OPT_fexceptions
:
502 global
.params
.useExceptions
= value
;
505 case OPT_fextern_std_
:
508 case CppStdRevisionCpp98
:
509 case CppStdRevisionCpp11
:
510 case CppStdRevisionCpp14
:
511 case CppStdRevisionCpp17
:
512 case CppStdRevisionCpp20
:
513 case CppStdRevisionCpp23
:
514 global
.params
.cplusplus
= (CppStdRevision
) value
;
518 error ("bad argument for %<-fextern-std%>: %qs", arg
);
522 case OPT_fignore_unknown_pragmas
:
523 global
.params
.ignoreUnsupportedPragmas
= value
;
526 case OPT_finclude_imports
:
527 includeImports
= true;
530 case OPT_finvariants
:
531 global
.params
.useInvariants
= value
? CHECKENABLEon
: CHECKENABLEoff
;
535 global
.params
.addMain
= value
;
538 case OPT_fmodule_file_
:
539 global
.params
.modFileAliasStrings
.push (arg
);
540 if (!strchr (arg
, '='))
541 error ("bad argument for %<-fmodule-file=%>: %qs", arg
);
544 case OPT_fmoduleinfo
:
545 global
.params
.useModuleInfo
= value
;
549 d_option
.fonly
= arg
;
552 case OPT_fpostconditions
:
553 global
.params
.useOut
= value
? CHECKENABLEon
: CHECKENABLEoff
;
556 case OPT_fpreconditions
:
557 global
.params
.useIn
= value
? CHECKENABLEon
: CHECKENABLEoff
;
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
;
578 case OPT_fpreview_bitfields
:
579 global
.params
.bitfields
= value
;
582 case OPT_fpreview_dip1000
:
583 global
.params
.useDIP1000
= FeatureState::enabled
;
586 case OPT_fpreview_dip1008
:
587 global
.params
.ehnogc
= value
;
590 case OPT_fpreview_dip1021
:
591 global
.params
.useDIP1021
= value
;
594 case OPT_fpreview_dtorfields
:
595 global
.params
.dtorFields
= FeatureState::enabled
;
598 case OPT_fpreview_fieldwise
:
599 global
.params
.fieldwise
= FeatureState::enabled
;
602 case OPT_fpreview_fixaliasthis
:
603 global
.params
.fixAliasThis
= value
;
606 case OPT_fpreview_fiximmutableconv
:
607 global
.params
.fixImmutableConv
= value
;
610 case OPT_fpreview_in
:
611 global
.params
.previewIn
= value
;
614 case OPT_fpreview_inclusiveincontracts
:
615 global
.params
.inclusiveInContracts
= value
;
618 case OPT_fpreview_nosharedaccess
:
619 global
.params
.noSharedAccess
= FeatureState::enabled
;
622 case OPT_fpreview_safer
:
623 global
.params
.safer
= FeatureState::enabled
;
626 case OPT_fpreview_rvaluerefparam
:
627 global
.params
.rvalueRefParam
= FeatureState::enabled
;
630 case OPT_fpreview_systemvariables
:
631 global
.params
.systemVariables
= FeatureState::enabled
;
635 global
.params
.release
= value
;
638 case OPT_frevert_all
:
639 global
.params
.useDIP1000
= FeatureState::disabled
;
640 global
.params
.dtorFields
= FeatureState::disabled
;
641 global
.params
.fix16997
= !value
;
644 case OPT_frevert_dip1000
:
645 global
.params
.useDIP1000
= FeatureState::disabled
;
648 case OPT_frevert_dtorfields
:
649 global
.params
.dtorFields
= FeatureState::disabled
;
652 case OPT_frevert_intpromote
:
653 global
.params
.fix16997
= !value
;
657 global
.params
.useTypeInfo
= value
;
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
> ();
666 case OPT_fswitch_errors
:
667 global
.params
.useSwitchError
= value
? CHECKENABLEon
: CHECKENABLEoff
;
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
;
677 case OPT_ftransition_field
:
678 global
.params
.v
.field
= value
;
681 case OPT_ftransition_in
:
682 global
.params
.v
.vin
= value
;
685 case OPT_ftransition_nogc
:
686 global
.params
.v
.gc
= value
;
689 case OPT_ftransition_templates
:
690 global
.params
.v
.templates
= value
;
693 case OPT_ftransition_tls
:
694 global
.params
.v
.tls
= value
;
698 global
.params
.useUnitTests
= value
;
702 if (Identifier::isValidIdentifier (CONST_CAST (char *, arg
)))
704 VersionCondition::addGlobalIdent (arg
);
708 error ("bad argument for %<-fversion=%>: %qs", arg
);
712 global
.params
.dihdr
.doOutput
= true;
716 global
.params
.dihdr
.doOutput
= true;
717 global
.params
.dihdr
.dir
= arg
;
721 global
.params
.dihdr
.doOutput
= true;
722 global
.params
.dihdr
.name
= arg
;
726 d_option
.multilib
= arg
;
730 d_option
.prefix
= arg
;
734 global
.params
.imppath
.push (arg
);
738 global
.params
.fileImppath
.push (arg
);
742 d_option
.deps_skip_system
= true;
746 d_option
.deps
= true;
750 d_option
.deps_skip_system
= true;
754 d_option
.deps
= true;
755 d_option
.deps_filename
= arg
;
759 /* If specified multiple times, last one wins. */
760 d_option
.deps_filename_user
= arg
;
764 d_option
.deps_phony
= true;
768 deps_add_target (arg
, true);
772 deps_add_target (arg
, false);
776 d_option
.stdinc
= false;
780 global
.params
.v
.verbose
= value
;
785 global
.params
.useWarnings
= DIAGNOSTICinform
;
788 case OPT_Wdeprecated
:
789 global
.params
.useDeprecated
= value
? DIAGNOSTICinform
: DIAGNOSTICoff
;
794 global
.params
.useWarnings
= DIAGNOSTICerror
;
797 case OPT_Wspeculative
:
799 global
.params
.v
.showGaggedErrors
= 1;
803 global
.params
.json
.name
= arg
;
807 global
.params
.json
.doOutput
= true;
814 D_handle_option_auto (&global_options
, &global_options_set
,
816 d_option_lang_mask (), kind
,
817 loc
, handlers
, global_dc
);
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. */
827 d_post_options (const char ** fn
)
829 /* Verify the input file name. */
830 const char *filename
= *fn
;
831 if (!filename
|| strcmp (filename
, "-") == 0)
834 /* The front end considers the first input file to be the main one. */
837 /* Release mode doesn't turn off bounds checking for safe functions. */
838 if (global
.params
.useArrayBounds
== CHECKENABLEdefault
)
840 global
.params
.useArrayBounds
= global
.params
.release
841 ? CHECKENABLEsafeonly
: CHECKENABLEon
;
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
)
848 if (global
.params
.useUnitTests
|| !global
.params
.release
)
849 global
.params
.useAssert
= CHECKENABLEon
;
851 global
.params
.useAssert
= CHECKENABLEoff
;
854 /* Checks for switches without a default are turned off in release mode. */
855 if (global
.params
.useSwitchError
== CHECKENABLEdefault
)
857 global
.params
.useSwitchError
= global
.params
.release
858 ? CHECKENABLEoff
: CHECKENABLEon
;
861 /* Contracts are turned off in release mode. */
862 if (global
.params
.useInvariants
== CHECKENABLEdefault
)
864 global
.params
.useInvariants
= global
.params
.release
865 ? CHECKENABLEoff
: CHECKENABLEon
;
868 if (global
.params
.useIn
== CHECKENABLEdefault
)
870 global
.params
.useIn
= global
.params
.release
871 ? CHECKENABLEoff
: CHECKENABLEon
;
874 if (global
.params
.useOut
== CHECKENABLEdefault
)
876 global
.params
.useOut
= global
.params
.release
877 ? CHECKENABLEoff
: CHECKENABLEon
;
880 /* When not linking against D runtime, turn off all code generation that
881 would otherwise reference it. */
882 if (global
.params
.betterC
)
884 if (!OPTION_SET_P (flag_moduleinfo
))
885 global
.params
.useModuleInfo
= false;
887 /* Ensure that the front-end options are in sync with the `-frtti' and
888 `-fexceptions' flags. */
889 if (!OPTION_SET_P (flag_rtti
))
891 global
.params
.useTypeInfo
= false;
895 if (!OPTION_SET_P (flag_exceptions
))
897 global
.params
.useExceptions
= false;
898 flag_exceptions
= false;
901 global
.params
.useGC
= false;
902 global
.params
.checkAction
= CHECKACTION_C
;
905 /* Enabling DIP1021 implies DIP1000. */
906 if (global
.params
.useDIP1021
)
907 global
.params
.useDIP1000
= FeatureState::enabled
;
909 /* Keep in sync with existing -fbounds-check flag. */
910 flag_bounds_check
= (global
.params
.useArrayBounds
== CHECKENABLEon
);
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;
918 /* Error about use of deprecated features. */
919 if (global
.params
.useDeprecated
== DIAGNOSTICinform
920 && global
.params
.useWarnings
== DIAGNOSTICerror
)
921 global
.params
.useDeprecated
= DIAGNOSTICerror
;
923 if (flag_excess_precision
== EXCESS_PRECISION_DEFAULT
)
924 flag_excess_precision
= EXCESS_PRECISION_STANDARD
;
926 global
.params
.useInline
= flag_inline_functions
;
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
;
932 global
.params
.v
.showColumns
= flag_show_column
;
933 global
.params
.v
.errorPrintMode
= flag_diagnostics_show_caret
934 ? ErrorPrintMode::printErrorContext
: ErrorPrintMode::simpleError
;
936 /* Keep the front-end location type in sync with params. */
937 Loc::set (global
.params
.v
.showColumns
, global
.params
.v
.messageStyle
);
939 if (global
.params
.useInline
)
940 global
.params
.dihdr
.fullOutput
= true;
942 global
.params
.obj
= !flag_syntax_only
;
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
);
954 if (warn_return_type
== -1)
955 warn_return_type
= 0;
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. */
965 d_add_builtin_module (Module
*m
)
967 builtin_modules
.push (m
);
970 /* Writes to FILENAME. DATA is the full content of the file to be written. */
973 d_write_file (const char *filename
, const char *data
)
977 if (filename
&& (filename
[0] != '-' || filename
[1] != '\0'))
978 stream
= fopen (filename
, "w");
984 error ("unable to open %s for writing: %m", filename
);
988 fprintf (stream
, "%s", data
);
990 if (stream
!= stdout
&& (ferror (stream
) || fclose (stream
)))
991 error ("writing output file %s: %m", filename
);
994 /* Read ddoc macro files named by the DDOCFILES, then write the concatenated
995 the contents into DDOCBUF. */
998 d_read_ddoc_files (Strings
&ddocfiles
, OutBuffer
&ddocbuf
)
1000 if (ddocbuf
.length ())
1003 for (size_t i
= 0; i
< ddocfiles
.length
; i
++)
1005 int fd
= open (ddocfiles
[i
], O_RDONLY
);
1009 if (fd
== -1 || fstat (fd
, &buf
))
1011 error ("unable to open %s for reading: %m", ddocfiles
[i
]);
1015 /* Check we've not been given a directory, or a file bigger than 4GB. */
1016 if (S_ISDIR (buf
.st_mode
))
1018 else if (buf
.st_size
!= unsigned (buf
.st_size
))
1022 unsigned size
= unsigned (buf
.st_size
);
1023 char *buffer
= (char *) xmalloc (size
);
1025 if (read (fd
, buffer
, size
) == ssize_t (size
))
1027 ddocbuf
.write (buffer
, size
);
1036 fatal_error (input_location
, "reading ddoc file %s: %m", ddocfiles
[i
]);
1041 d_generate_ddoc_file (Module
*m
, OutBuffer
&ddocbuf
)
1043 input_location
= make_location_t (m
->loc
);
1045 d_read_ddoc_files (global
.params
.ddoc
.files
, ddocbuf
);
1047 OutBuffer ddocbuf_out
;
1048 dmd::gendocfile (m
, ddocbuf
.peekChars (), ddocbuf
.length (), global
.datetime
,
1049 global
.errorSink
, ddocbuf_out
);
1051 d_write_file (m
->docfile
.toChars (), ddocbuf_out
.peekChars ());
1054 /* Implements the lang_hooks.parse_file routine for language D. */
1059 if (global
.params
.v
.verbose
)
1061 /* Dump information about the D compiler and language version. */
1062 message ("binary %s", global
.params
.argv0
.ptr
);
1063 message ("version %s", global
.versionChars ());
1065 /* Dump all predefined version identifiers. */
1067 gcc_obstack_init (&buffer
);
1068 obstack_grow (&buffer
, "predefs ", 9);
1069 for (size_t i
= 0; i
< global
.versionids
.length
; i
++)
1071 Identifier
*id
= global
.versionids
[i
];
1072 const char *str
= id
->toChars ();
1073 obstack_1grow (&buffer
, ' ');
1074 obstack_grow (&buffer
, str
, strlen (str
));
1077 obstack_1grow (&buffer
, '\0');
1078 message ("%s", (char *) obstack_finish (&buffer
));
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
);
1085 /* Create Module's for all sources we will load. */
1087 modules
.reserve (num_in_fnames
);
1089 /* Buffer for contents of .ddoc files. */
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");
1097 for (size_t i
= 0; i
< num_in_fnames
; i
++)
1099 if (strcmp (in_fnames
[i
], "-") == 0)
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);
1109 while ((count
= read (STDIN_FILENO
, buffer
+ len
, size
- len
)) > 0)
1115 buffer
= XRESIZEVEC (uchar
, buffer
, size
+ 16);
1121 error (Loc::singleFilename ("stdin"), "%s", xstrerror (errno
));
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
);
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);
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
;
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
);
1148 Module
*m
= Module::create (in_fnames
[i
], Identifier::idPool (name
),
1149 global
.params
.ddoc
.doOutput
,
1150 global
.params
.dihdr
.doOutput
);
1152 FileName::free (name
);
1156 /* Read all D source files. */
1157 for (size_t i
= 0; i
< modules
.length
; i
++)
1159 Module
*m
= modules
[i
];
1163 /* Parse all D source files. */
1164 for (size_t i
= 0; i
< modules
.length
; i
++)
1166 Module
*m
= modules
[i
];
1168 if (global
.params
.v
.verbose
)
1169 message ("parse %s", m
->toChars ());
1171 if (!Module::rootModule
)
1172 Module::rootModule
= m
;
1174 m
->importedFrom
= m
;
1177 if (m
->filetype
== FileType::ddoc
)
1179 d_generate_ddoc_file (m
, ddocbuf
);
1181 /* Remove M from list of modules. */
1187 /* Load the module containing D main. */
1188 Module
*main_module
= NULL
;
1189 if (global
.params
.addMain
)
1191 unsigned errors
= global
.startGagging ();
1192 main_module
= Module::load (Loc (), NULL
, Identifier::idPool ("__main"));
1194 if (!global
.endGagging (errors
))
1196 main_module
->importedFrom
= main_module
;
1197 modules
.push (main_module
);
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;
1208 if (global
.params
.dihdr
.doOutput
)
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
++)
1215 Module
*m
= modules
[i
];
1216 if (m
->filetype
== FileType::dhdr
1217 || (d_option
.fonly
&& m
!= Module::rootModule
))
1220 if (global
.params
.v
.verbose
)
1221 message ("import %s", m
->toChars ());
1224 dmd::genhdrfile (m
, global
.params
.dihdr
.fullOutput
, buf
);
1225 d_write_file (m
->hdrfile
.toChars (), buf
.peekChars ());
1228 dump_headers
= true;
1234 /* Load all unconditional imports for better symbol resolving. */
1235 for (size_t i
= 0; i
< modules
.length
; i
++)
1237 Module
*m
= modules
[i
];
1239 if (global
.params
.v
.verbose
)
1240 message ("importall %s", m
->toChars ());
1242 dmd::importAll (m
, NULL
);
1248 /* Do semantic analysis. */
1249 doing_semantic_analysis_p
= true;
1251 for (size_t i
= 0; i
< modules
.length
; i
++)
1253 Module
*m
= modules
[i
];
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
)
1263 if (global
.params
.v
.verbose
)
1264 message ("semantic %s", m
->toChars ());
1266 dmd::dsymbolSemantic (m
, NULL
);
1269 /* Do deferred semantic analysis. */
1270 Module::runDeferredSemantic ();
1272 if (Module::deferred
.length
)
1274 for (size_t i
= 0; i
< Module::deferred
.length
; i
++)
1276 Dsymbol
*sd
= Module::deferred
[i
];
1277 error_at (make_location_t (sd
->loc
),
1278 "unable to resolve forward reference in definition");
1282 /* Process all built-in modules or functions now for CTFE. */
1283 while (builtin_modules
.length
!= 0)
1285 Module
*m
= builtin_modules
.pop ();
1286 d_maybe_set_builtin (m
);
1289 /* Do pass 2 semantic analysis. */
1290 for (size_t i
= 0; i
< modules
.length
; i
++)
1292 Module
*m
= modules
[i
];
1294 if (global
.params
.v
.verbose
)
1295 message ("semantic2 %s", m
->toChars ());
1297 dmd::semantic2 (m
, NULL
);
1300 Module::runDeferredSemantic2 ();
1305 /* Do pass 3 semantic analysis. */
1306 for (size_t i
= 0; i
< modules
.length
; i
++)
1308 Module
*m
= modules
[i
];
1310 if (global
.params
.v
.verbose
)
1311 message ("semantic3 %s", m
->toChars ());
1313 dmd::semantic3 (m
, NULL
);
1318 for (size_t i
= 0; i
< compiledImports
.length
; i
++)
1320 Module
*m
= compiledImports
[i
];
1321 gcc_assert (m
->isRoot ());
1323 if (global
.params
.v
.verbose
)
1324 message ("semantic3 %s", m
->toChars ());
1326 dmd::semantic3 (m
, NULL
);
1331 Module::runDeferredSemantic3 ();
1333 /* Check again, incase semantic3 pass loaded any more modules. */
1334 while (builtin_modules
.length
!= 0)
1336 Module
*m
= builtin_modules
.pop ();
1337 d_maybe_set_builtin (m
);
1340 /* Do not attempt to generate output files if errors or warnings occurred. */
1341 if (global
.errors
|| global
.warnings
)
1344 /* Generate output files. */
1345 doing_semantic_analysis_p
= false;
1347 if (Module::rootModule
)
1349 /* Declare the name of the root module as the first global name in order
1350 to make the middle-end fully deterministic. */
1352 dmd::mangleToBuffer (Module::rootModule
, buf
);
1353 first_global_object_name
= buf
.extractChars ();
1356 /* Make dependencies. */
1360 gcc_obstack_init (&buffer
);
1362 for (size_t i
= 0; i
< modules
.length
; i
++)
1363 deps_write (modules
[i
], &buffer
);
1365 /* -MF <arg> overrides -M[M]D. */
1366 if (d_option
.deps_filename_user
)
1367 d_option
.deps_filename
= d_option
.deps_filename_user
;
1369 d_write_file (d_option
.deps_filename
,
1370 (char *) obstack_finish (&buffer
));
1373 if (global
.params
.v
.templates
)
1375 dmd::printTemplateStats (global
.params
.v
.templatesListInstances
,
1379 /* Generate JSON files. */
1380 if (global
.params
.json
.doOutput
)
1383 dmd::json_generate (modules
, buf
);
1384 d_write_file (global
.params
.json
.name
.ptr
, buf
.peekChars ());
1387 /* Generate Ddoc files. */
1388 if (global
.params
.ddoc
.doOutput
&& !global
.errors
&& !errorcount
)
1390 for (size_t i
= 0; i
< modules
.length
; i
++)
1392 Module
*m
= modules
[i
];
1393 d_generate_ddoc_file (m
, ddocbuf
);
1397 /* Handle -fdump-d-original. */
1398 if (global
.params
.vcg_ast
)
1400 for (size_t i
= 0; i
< modules
.length
; i
++)
1402 Module
*m
= modules
[i
];
1406 dmd::moduleToBuffer (buf
, true, m
);
1407 message ("%s", buf
.peekChars ());
1411 /* Generate C++ header files. */
1412 if (global
.params
.cxxhdr
.doOutput
)
1413 dmd::genCppHdrFiles (modules
);
1418 for (size_t i
= 0; i
< modules
.length
; i
++)
1420 Module
*m
= modules
[i
];
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
))
1428 if (global
.params
.v
.verbose
)
1429 message ("code %s", m
->toChars ());
1431 if (!flag_syntax_only
)
1432 build_decl_tree (m
);
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);
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
);
1444 /* We want to write the mixin expansion file also on error. */
1445 if (global
.params
.mixinOut
.doOutput
)
1447 d_write_file (global
.params
.mixinOut
.name
.ptr
,
1448 global
.params
.mixinOut
.buffer
->peekChars ());
1451 /* Remove generated .di files on error. */
1452 if (errorcount
&& dump_headers
)
1454 for (size_t i
= 0; i
< modules
.length
; i
++)
1456 Module
*m
= modules
[i
];
1457 if (m
->filetype
== FileType::dhdr
1458 || (d_option
.fonly
&& m
!= Module::rootModule
))
1461 remove (m
->hdrfile
.toChars ());
1465 /* Write out globals. */
1466 d_finish_compilation (vec_safe_address (global_declarations
),
1467 vec_safe_length (global_declarations
));
1470 /* Implements the lang_hooks.types.type_for_mode routine for language D. */
1473 d_type_for_mode (machine_mode mode
, int unsignedp
)
1476 return unsignedp
? d_ubyte_type
: d_byte_type
;
1479 return unsignedp
? d_ushort_type
: d_short_type
;
1482 return unsignedp
? d_uint_type
: d_int_type
;
1485 return unsignedp
? d_ulong_type
: d_long_type
;
1487 if (mode
== TYPE_MODE (d_cent_type
))
1488 return unsignedp
? d_ucent_type
: d_cent_type
;
1490 if (mode
== TYPE_MODE (float_type_node
))
1491 return float_type_node
;
1493 if (mode
== TYPE_MODE (double_type_node
))
1494 return double_type_node
;
1496 if (mode
== TYPE_MODE (long_double_type_node
))
1497 return long_double_type_node
;
1499 if (mode
== TYPE_MODE (build_pointer_type (char8_type_node
)))
1500 return build_pointer_type (char8_type_node
);
1502 if (mode
== TYPE_MODE (build_pointer_type (d_int_type
)))
1503 return build_pointer_type (d_int_type
);
1505 for (int i
= 0; i
< NUM_INT_N_ENTS
; i
++)
1507 if (int_n_enabled_p
[i
] && mode
== int_n_data
[i
].m
)
1510 return int_n_trees
[i
].unsigned_type
;
1512 return int_n_trees
[i
].signed_type
;
1516 if (COMPLEX_MODE_P (mode
))
1518 machine_mode inner_mode
;
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
;
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
);
1533 else if (VECTOR_MODE_P (mode
))
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
);
1544 /* Implements the lang_hooks.types.type_for_size routine for language D. */
1547 d_type_for_size (unsigned bits
, int unsignedp
)
1549 if (bits
<= TYPE_PRECISION (d_byte_type
))
1550 return unsignedp
? d_ubyte_type
: d_byte_type
;
1552 if (bits
<= TYPE_PRECISION (d_short_type
))
1553 return unsignedp
? d_ushort_type
: d_short_type
;
1555 if (bits
<= TYPE_PRECISION (d_int_type
))
1556 return unsignedp
? d_uint_type
: d_int_type
;
1558 if (bits
<= TYPE_PRECISION (d_long_type
))
1559 return unsignedp
? d_ulong_type
: d_long_type
;
1561 if (bits
<= TYPE_PRECISION (d_cent_type
))
1562 return unsignedp
? d_ucent_type
: d_cent_type
;
1564 for (int i
= 0; i
< NUM_INT_N_ENTS
; i
++)
1566 if (int_n_enabled_p
[i
] && bits
== int_n_data
[i
].bitsize
)
1569 return int_n_trees
[i
].unsigned_type
;
1571 return int_n_trees
[i
].signed_type
;
1578 /* Implements the lang_hooks.types.type_promotes_to routine for language D. */
1581 d_type_promotes_to (tree type
)
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
)
1588 /* In [type/integer-promotions], integer promotions are conversions of the
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
);
1605 type
= TYPE_MAIN_VARIANT (type
);
1607 /* Check for promotions of target-defined types first. */
1608 tree promoted_type
= targetm
.promoted_type (type
);
1610 return promoted_type
;
1612 if (TREE_CODE (type
) == BOOLEAN_TYPE
)
1615 if (INTEGRAL_TYPE_P (type
))
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
)
1622 if (type
== char32_type_node
)
1625 if (TYPE_PRECISION (type
) < TYPE_PRECISION (d_int_type
))
1629 /* Float arguments are converted to doubles. */
1630 if (type
== float_type_node
)
1631 return double_type_node
;
1633 if (type
== ifloat_type_node
)
1634 return idouble_type_node
;
1640 /* Implements the lang_hooks.decls.global_bindings_p routine for language D.
1641 Return true if we are in the global binding level. */
1644 d_global_bindings_p (void)
1646 return (current_binding_level
== global_binding_level
);
1649 /* Return global_context, but create it first if need be. */
1652 get_global_context (void)
1654 if (!global_context
)
1656 global_context
= build_translation_unit_decl (NULL_TREE
);
1657 debug_hooks
->register_main_translation_unit (global_context
);
1660 return global_context
;
1663 /* Implements the lang_hooks.decls.pushdecl routine for language D.
1664 Record DECL as belonging to the current lexical scope. */
1667 d_pushdecl (tree decl
)
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
))
1673 if (current_function_decl
)
1674 DECL_CONTEXT (decl
) = current_function_decl
;
1676 DECL_CONTEXT (decl
) = get_global_context ();
1679 /* Put decls on list in reverse order. */
1680 if (TREE_STATIC (decl
) || d_global_bindings_p ())
1681 vec_safe_push (global_declarations
, decl
);
1684 TREE_CHAIN (decl
) = current_binding_level
->names
;
1685 current_binding_level
->names
= decl
;
1691 /* Implements the lang_hooks.decls.getdecls routine for language D.
1692 Return the list of declarations of the current level. */
1697 if (current_binding_level
)
1698 return current_binding_level
->names
;
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. */
1708 static alias_set_type
1709 d_get_alias_set (tree
)
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. */
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. */
1726 d_types_compatible_p (tree x
, tree y
)
1728 Type
*tx
= TYPE_LANG_FRONTEND (x
);
1729 Type
*ty
= TYPE_LANG_FRONTEND (y
);
1731 /* Try validating the types in the frontend. */
1732 if (tx
!= NULL
&& ty
!= NULL
)
1734 /* Types are equivalent. */
1735 if (same_type_p (tx
, ty
))
1738 /* Type system allows implicit conversion between. */
1739 if (dmd::implicitConvTo (tx
, ty
) != MATCH::nomatch
1740 || dmd::implicitConvTo (ty
, tx
) != MATCH::nomatch
)
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
)
1748 if (TYPE_DYNAMIC_ARRAY (x
) && TYPE_DYNAMIC_ARRAY (y
))
1751 if (TYPE_DELEGATE (x
) && TYPE_DELEGATE (y
))
1754 if (TYPE_ASSOCIATIVE_ARRAY (x
) && TYPE_ASSOCIATIVE_ARRAY (y
))
1761 /* Implements the lang_hooks.finish_incomplete_decl routine for language D. */
1764 d_finish_incomplete_decl (tree decl
)
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)
1774 DECL_SIZE (decl
) = bitsize_zero_node
;
1775 DECL_SIZE_UNIT (decl
) = size_zero_node
;
1780 /* Implements the lang_hooks.types.classify_record routine for language D.
1781 Return the true debug type for TYPE. */
1783 static classify_record
1784 d_classify_record (tree type
)
1786 Type
*t
= TYPE_LANG_FRONTEND (type
);
1787 TypeClass
*tc
= t
? t
->isTypeClass () : NULL
;
1791 /* extern(C++) interfaces get emitted as classes. */
1792 if (tc
->sym
->isInterfaceDeclaration ()
1793 && !tc
->sym
->isCPPinterface ())
1794 return RECORD_IS_INTERFACE
;
1796 return RECORD_IS_CLASS
;
1799 return RECORD_IS_STRUCT
;
1802 /* Implements the lang_hooks.tree_size routine for language D.
1803 Determine the size of our tcc_constant or tcc_exceptional nodes. */
1806 d_tree_size (tree_code code
)
1810 case FUNCFRAME_INFO
:
1811 return sizeof (tree_frame_info
);
1818 /* Implements the lang_hooks.print_xnode routine for language D. */
1821 d_print_xnode (FILE *file
, tree node
, int indent
)
1823 switch (TREE_CODE (node
))
1825 case FUNCFRAME_INFO
:
1826 print_node (file
, "frame_type", FRAMEINFO_TYPE (node
), indent
+ 4);
1834 /* Return which tree structure is used by NODE, or TS_D_GENERIC if NODE
1835 is one of the language-independent trees. */
1837 d_tree_node_structure_enum
1838 d_tree_node_structure (lang_tree_node
*t
)
1840 switch (TREE_CODE (&t
->generic
))
1842 case IDENTIFIER_NODE
:
1843 return TS_D_IDENTIFIER
;
1845 case FUNCFRAME_INFO
:
1846 return TS_D_FRAMEINFO
;
1849 return TS_D_GENERIC
;
1853 /* Allocate and return a lang specific structure for the frontend type. */
1856 build_lang_type (Type
*t
)
1858 struct lang_type
*lt
= ggc_cleared_alloc
<struct lang_type
> ();
1863 /* Allocate and return a lang specific structure for the frontend decl. */
1866 build_lang_decl (Declaration
*d
)
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. */
1872 return ggc_cleared_alloc
<struct lang_decl
> ();
1874 struct lang_decl
*ld
= (d
->csym
) ? DECL_LANG_SPECIFIC (d
->csym
) : NULL
;
1876 ld
= ggc_cleared_alloc
<struct lang_decl
> ();
1878 if (ld
->decl
== NULL
)
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. */
1888 d_dup_lang_specific_decl (tree node
)
1890 if (!DECL_LANG_SPECIFIC (node
))
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
;
1898 /* This preserves trees we create from the garbage collector. */
1900 static GTY(()) tree d_keep_list
= NULL_TREE
;
1905 d_keep_list
= tree_cons (NULL_TREE
, t
, d_keep_list
);
1908 /* Implements the lang_hooks.eh_personality routine for language D.
1909 Return the GDC personality function decl. */
1911 static GTY(()) tree d_eh_personality_decl
;
1914 d_eh_personality (void)
1916 if (!d_eh_personality_decl
)
1917 d_eh_personality_decl
= build_personality_function ("gdc");
1919 return d_eh_personality_decl
;
1922 /* Implements the lang_hooks.eh_runtime_type routine for language D. */
1925 d_build_eh_runtime_type (tree type
)
1927 Type
*t
= TYPE_LANG_FRONTEND (type
);
1928 gcc_assert (t
!= NULL
);
1929 t
= t
->toBasetype ();
1931 ClassDeclaration
*cd
= t
->isTypeClass ()->sym
;
1934 if (cd
->isCPPclass ())
1935 decl
= get_cpp_typeinfo_decl (cd
);
1937 decl
= get_classinfo_decl (cd
);
1939 return convert (ptr_type_node
, build_address (decl
));
1942 /* Implements the lang_hooks.enum_underlying_base_type routine for language D.
1943 Returns the underlying type of the given enumeration TYPE. */
1946 d_enum_underlying_base_type (const_tree type
)
1948 gcc_assert (TREE_CODE (type
) == ENUMERAL_TYPE
);
1949 return TREE_TYPE (type
);
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. */
1956 d_get_sarif_source_language (const char *)
1961 const scoped_attribute_specs
*const d_langhook_attribute_table
[] =
1963 &d_langhook_gnu_attribute_table
,
1964 &d_langhook_common_attribute_table
,
1967 /* Definitions for our language-specific hooks. */
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
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
2033 struct lang_hooks lang_hooks
= LANG_HOOKS_INITIALIZER
;
2035 #include "gt-d-d-lang.h"
2036 #include "gtype-d.h"