1 /* d-lang.cc -- Language-dependent hooks for D.
2 Copyright (C) 2006-2022 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/errors.h"
27 #include "dmd/expression.h"
28 #include "dmd/hdrgen.h"
30 #include "dmd/identifier.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"
41 #include "diagnostic.h"
42 #include "fold-const.h"
44 #include "langhooks.h"
45 #include "langhooks-def.h"
48 #include "stringpool.h"
49 #include "stor-layout.h"
52 #include "print-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. */
69 const char *fonly
; /* -fonly=<arg> */
70 const char *multilib
; /* -imultilib <dir> */
71 const char *prefix
; /* -iprefix <dir> */
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 */
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. */
102 deps_add_target (const char *target
, bool quoted
)
105 gcc_obstack_init (&buffer
);
109 obstack_grow0 (&buffer
, target
, strlen (target
));
110 d_option
.deps_target
.safe_push ((const char *) obstack_finish (&buffer
));
114 /* Quote characters in target which are significant to Make. */
115 unsigned slashes
= 0;
117 for (const char *p
= target
; *p
!= '\0'; p
++)
128 obstack_1grow (&buffer
, '\\');
129 obstack_1grow (&buffer
, '\\');
133 obstack_1grow (&buffer
, '$');
138 obstack_1grow (&buffer
, '\\');
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). */
158 deps_write_string (const char *str
, obstack
*buffer
, unsigned &column
,
159 unsigned colmax
= 72)
161 unsigned size
= strlen (str
);
165 if (colmax
&& column
+ size
> colmax
)
167 obstack_grow (buffer
, " \\\n ", 4);
172 obstack_1grow (buffer
, ' ');
178 obstack_grow (buffer
, str
, size
);
181 /* Write out all dependencies of a given MODULE to the specified BUFFER. */
184 deps_write (Module
*module
, obstack
*buffer
)
186 hash_set
<const char *> seen_modules
;
187 vec
<const char *> dependencies
= vNULL
;
190 modlist
.push (module
);
192 vec
<const char *> phonylist
= vNULL
;
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
);
202 deps_write_string (module
->objfile
.toChars (), buffer
, column
);
204 obstack_1grow (buffer
, ':');
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
))
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
)
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
)
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"))
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. */
287 d_init_options (unsigned int, cl_decoded_option
*decoded_options
)
289 /* Initialize the D runtime. */
293 /* Set default values. */
296 global
.vendor
= lang_hooks
.name
;
297 global
.params
.argv0
= xstrdup (decoded_options
[0].arg
);
298 global
.params
.errorLimit
= flag_max_errors
;
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
.warnings
= DIAGNOSTICoff
;
306 global
.params
.messageStyle
= MESSAGESTYLEgnu
;
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. */
328 d_init_options_struct (gcc_options
*opts
)
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. */
345 d_option_lang_mask (void)
350 /* Implements input charset and BOM skipping configuration for
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. */
363 /* Implements the lang_hooks.init routine for language D. */
371 Expression::_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);
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);
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
);
403 /* Insert all library-configured identifiers and import paths. */
404 add_import_paths (d_option
.prefix
, d_option
.multilib
, d_option
.stdinc
);
409 /* Implements the lang_hooks.init_ts routine for language D. */
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. */
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
;
432 case OPT_fall_instantiations
:
433 global
.params
.allInst
= value
;
437 global
.params
.useAssert
= value
? CHECKENABLEon
: CHECKENABLEoff
;
440 case OPT_fbounds_check
:
441 global
.params
.useArrayBounds
= value
? CHECKENABLEon
: CHECKENABLEoff
;
444 case OPT_fbounds_check_
:
445 global
.params
.useArrayBounds
= (value
== 2) ? CHECKENABLEon
446 : (value
== 1) ? CHECKENABLEsafeonly
: CHECKENABLEoff
;
449 case OPT_fcheckaction_
:
450 global
.params
.checkAction
= (value
== 0) ? CHECKACTION_D
451 : (value
== 1) ? CHECKACTION_halt
: CHECKACTION_context
;
455 global
.params
.debuglevel
= value
? 1 : 0;
459 if (ISDIGIT (arg
[0]))
461 int level
= integral_argument (arg
);
464 global
.params
.debuglevel
= level
;
469 if (Identifier::isValidIdentifier (CONST_CAST (char *, arg
)))
471 if (!global
.params
.debugids
)
472 global
.params
.debugids
= d_gc_malloc
<Strings
> ();
473 global
.params
.debugids
->push (arg
);
477 error ("bad argument for %<-fdebug%>: %qs", arg
);
481 global
.params
.doDocComments
= value
;
485 global
.params
.doDocComments
= true;
486 global
.params
.docdir
= arg
;
490 global
.params
.doDocComments
= true;
491 global
.params
.docname
= arg
;
495 global
.params
.ddocfiles
.push (arg
);
499 global
.params
.betterC
= !value
;
502 case OPT_fdump_c___spec_
:
503 if (global
.params
.doCxxHdrGeneration
== CxxHeaderMode::none
)
504 global
.params
.doCxxHdrGeneration
= CxxHeaderMode::silent
;
505 global
.params
.cxxhdrname
= arg
;
508 case OPT_fdump_c___spec_verbose
:
509 global
.params
.doCxxHdrGeneration
= CxxHeaderMode::verbose
;
512 case OPT_fdump_d_original
:
513 global
.params
.vcg_ast
= value
;
516 case OPT_fexceptions
:
517 global
.params
.useExceptions
= value
;
520 case OPT_fextern_std_
:
523 case CppStdRevisionCpp98
:
524 case CppStdRevisionCpp11
:
525 case CppStdRevisionCpp14
:
526 case CppStdRevisionCpp17
:
527 case CppStdRevisionCpp20
:
528 global
.params
.cplusplus
= (CppStdRevision
) value
;
532 error ("bad argument for %<-fextern-std%>: %qs", arg
);
536 case OPT_fignore_unknown_pragmas
:
537 global
.params
.ignoreUnsupportedPragmas
= value
;
540 case OPT_finvariants
:
541 global
.params
.useInvariants
= value
? CHECKENABLEon
: CHECKENABLEoff
;
545 global
.params
.addMain
= value
;
548 case OPT_fmodule_file_
:
549 global
.params
.modFileAliasStrings
.push (arg
);
550 if (!strchr (arg
, '='))
551 error ("bad argument for %<-fmodule-file%>: %qs", arg
);
554 case OPT_fmoduleinfo
:
555 global
.params
.useModuleInfo
= value
;
559 d_option
.fonly
= arg
;
562 case OPT_fpostconditions
:
563 global
.params
.useOut
= value
? CHECKENABLEon
: CHECKENABLEoff
;
566 case OPT_fpreconditions
:
567 global
.params
.useIn
= value
? CHECKENABLEon
: CHECKENABLEoff
;
570 case OPT_fpreview_all
:
571 global
.params
.ehnogc
= value
;
572 global
.params
.useDIP25
= FeatureState::enabled
;
573 global
.params
.useDIP1000
= FeatureState::enabled
;
574 global
.params
.useDIP1021
= value
;
575 global
.params
.dtorFields
= FeatureState::enabled
;
576 global
.params
.fieldwise
= value
;
577 global
.params
.fixAliasThis
= value
;
578 global
.params
.previewIn
= value
;
579 global
.params
.fix16997
= value
;
580 global
.params
.markdown
= value
;
581 global
.params
.noSharedAccess
= value
;
582 global
.params
.rvalueRefParam
= FeatureState::enabled
;
583 global
.params
.inclusiveInContracts
= value
;
584 global
.params
.shortenedMethods
= value
;
587 case OPT_fpreview_dip1000
:
588 global
.params
.useDIP1000
= FeatureState::enabled
;
591 case OPT_fpreview_dip1008
:
592 global
.params
.ehnogc
= value
;
595 case OPT_fpreview_dip1021
:
596 global
.params
.useDIP1021
= value
;
599 case OPT_fpreview_dip25
:
600 global
.params
.useDIP25
= FeatureState::enabled
;
603 case OPT_fpreview_dtorfields
:
604 global
.params
.dtorFields
= FeatureState::enabled
;
607 case OPT_fpreview_fieldwise
:
608 global
.params
.fieldwise
= value
;
611 case OPT_fpreview_fixaliasthis
:
612 global
.params
.fixAliasThis
= value
;
615 case OPT_fpreview_in
:
616 global
.params
.previewIn
= value
;
619 case OPT_fpreview_inclusiveincontracts
:
620 global
.params
.inclusiveInContracts
= value
;
623 case OPT_fpreview_nosharedaccess
:
624 global
.params
.noSharedAccess
= value
;
627 case OPT_fpreview_rvaluerefparam
:
628 global
.params
.rvalueRefParam
= FeatureState::enabled
;
631 case OPT_fpreview_shortenedmethods
:
632 global
.params
.shortenedMethods
= value
;
636 global
.params
.release
= value
;
639 case OPT_frevert_all
:
640 global
.params
.useDIP1000
= FeatureState::disabled
;
641 global
.params
.useDIP25
= FeatureState::disabled
;
642 global
.params
.dtorFields
= FeatureState::disabled
;
643 global
.params
.fix16997
= !value
;
644 global
.params
.markdown
= !value
;
647 case OPT_frevert_dip1000
:
648 global
.params
.useDIP1000
= FeatureState::disabled
;
651 case OPT_frevert_dip25
:
652 global
.params
.useDIP25
= FeatureState::disabled
;
655 case OPT_frevert_dtorfields
:
656 global
.params
.dtorFields
= FeatureState::disabled
;
659 case OPT_frevert_intpromote
:
660 global
.params
.fix16997
= !value
;
663 case OPT_frevert_markdown
:
664 global
.params
.markdown
= !value
;
668 global
.params
.useTypeInfo
= value
;
671 case OPT_fsave_mixins_
:
672 global
.params
.mixinFile
= arg
;
673 global
.params
.mixinOut
= d_gc_malloc
<OutBuffer
> ();
676 case OPT_fswitch_errors
:
677 global
.params
.useSwitchError
= value
? CHECKENABLEon
: CHECKENABLEoff
;
680 case OPT_ftransition_all
:
681 global
.params
.vfield
= value
;
682 global
.params
.vgc
= value
;
683 global
.params
.vin
= value
;
684 global
.params
.vmarkdown
= value
;
685 global
.params
.vtls
= value
;
688 case OPT_ftransition_field
:
689 global
.params
.vfield
= value
;
692 case OPT_ftransition_in
:
693 global
.params
.vin
= value
;
696 case OPT_ftransition_nogc
:
697 global
.params
.vgc
= value
;
700 case OPT_ftransition_vmarkdown
:
701 global
.params
.vmarkdown
= value
;
704 case OPT_ftransition_templates
:
705 global
.params
.vtemplates
= value
;
708 case OPT_ftransition_tls
:
709 global
.params
.vtls
= value
;
713 global
.params
.useUnitTests
= value
;
717 if (ISDIGIT (arg
[0]))
719 int level
= integral_argument (arg
);
722 global
.params
.versionlevel
= level
;
727 if (Identifier::isValidIdentifier (CONST_CAST (char *, arg
)))
729 if (!global
.params
.versionids
)
730 global
.params
.versionids
= d_gc_malloc
<Strings
> ();
731 global
.params
.versionids
->push (arg
);
735 error ("bad argument for %<-fversion%>: %qs", arg
);
739 global
.params
.doHdrGeneration
= true;
743 global
.params
.doHdrGeneration
= true;
744 global
.params
.hdrdir
= arg
;
748 global
.params
.doHdrGeneration
= true;
749 global
.params
.hdrname
= arg
;
753 d_option
.multilib
= arg
;
757 d_option
.prefix
= arg
;
761 global
.params
.imppath
->push (arg
);
765 global
.params
.fileImppath
->push (arg
);
769 d_option
.deps_skip_system
= true;
773 d_option
.deps
= true;
777 d_option
.deps_skip_system
= true;
781 d_option
.deps
= true;
782 d_option
.deps_filename
= arg
;
786 /* If specified multiple times, last one wins. */
787 d_option
.deps_filename_user
= arg
;
791 d_option
.deps_phony
= true;
795 deps_add_target (arg
, true);
799 deps_add_target (arg
, false);
803 d_option
.stdinc
= false;
807 global
.params
.verbose
= value
;
812 global
.params
.warnings
= DIAGNOSTICinform
;
815 case OPT_Wdeprecated
:
816 global
.params
.useDeprecated
= value
? DIAGNOSTICinform
: DIAGNOSTICoff
;
821 global
.params
.warnings
= DIAGNOSTICerror
;
824 case OPT_Wspeculative
:
826 global
.params
.showGaggedErrors
= 1;
830 global
.params
.jsonfilename
= arg
;
834 global
.params
.doJsonGeneration
= true;
841 D_handle_option_auto (&global_options
, &global_options_set
,
843 d_option_lang_mask (), kind
,
844 loc
, handlers
, global_dc
);
849 /* Implements the lang_hooks.post_options routine for language D.
850 Deal with any options that imply the turning on/off of features.
851 FN is the main input filename passed on the command line. */
854 d_post_options (const char ** fn
)
856 /* Verify the input file name. */
857 const char *filename
= *fn
;
858 if (!filename
|| strcmp (filename
, "-") == 0)
861 /* The front end considers the first input file to be the main one. */
864 /* Release mode doesn't turn off bounds checking for safe functions. */
865 if (global
.params
.useArrayBounds
== CHECKENABLEdefault
)
867 global
.params
.useArrayBounds
= global
.params
.release
868 ? CHECKENABLEsafeonly
: CHECKENABLEon
;
871 /* Assert code is generated if unittests are being compiled also, even if
872 release mode is turned on. */
873 if (global
.params
.useAssert
== CHECKENABLEdefault
)
875 if (global
.params
.useUnitTests
|| !global
.params
.release
)
876 global
.params
.useAssert
= CHECKENABLEon
;
878 global
.params
.useAssert
= CHECKENABLEoff
;
881 /* Checks for switches without a default are turned off in release mode. */
882 if (global
.params
.useSwitchError
== CHECKENABLEdefault
)
884 global
.params
.useSwitchError
= global
.params
.release
885 ? CHECKENABLEoff
: CHECKENABLEon
;
888 /* Contracts are turned off in release mode. */
889 if (global
.params
.useInvariants
== CHECKENABLEdefault
)
891 global
.params
.useInvariants
= global
.params
.release
892 ? CHECKENABLEoff
: CHECKENABLEon
;
895 if (global
.params
.useIn
== CHECKENABLEdefault
)
897 global
.params
.useIn
= global
.params
.release
898 ? CHECKENABLEoff
: CHECKENABLEon
;
901 if (global
.params
.useOut
== CHECKENABLEdefault
)
903 global
.params
.useOut
= global
.params
.release
904 ? CHECKENABLEoff
: CHECKENABLEon
;
907 if (global
.params
.betterC
)
909 if (!OPTION_SET_P (flag_moduleinfo
))
910 global
.params
.useModuleInfo
= false;
912 if (!OPTION_SET_P (flag_rtti
))
913 global
.params
.useTypeInfo
= false;
915 if (!OPTION_SET_P (flag_exceptions
))
916 global
.params
.useExceptions
= false;
918 global
.params
.checkAction
= CHECKACTION_C
;
921 /* Enabling DIP1021 implies DIP1000. */
922 if (global
.params
.useDIP1021
)
923 global
.params
.useDIP1000
= FeatureState::enabled
;
925 /* Enabling DIP1000 implies DIP25. */
926 if (global
.params
.useDIP1000
== FeatureState::enabled
)
927 global
.params
.useDIP25
= FeatureState::enabled
;
929 /* Keep in sync with existing -fbounds-check flag. */
930 flag_bounds_check
= (global
.params
.useArrayBounds
== CHECKENABLEon
);
932 /* Turn off partitioning unless it was explicitly requested, as it doesn't
933 work with D exception chaining, where EH handler uses LSDA to determine
934 whether two thrown exception are in the same context. */
935 if (!OPTION_SET_P (flag_reorder_blocks_and_partition
))
936 global_options
.x_flag_reorder_blocks_and_partition
= 0;
938 /* Error about use of deprecated features. */
939 if (global
.params
.useDeprecated
== DIAGNOSTICinform
940 && global
.params
.warnings
== DIAGNOSTICerror
)
941 global
.params
.useDeprecated
= DIAGNOSTICerror
;
943 /* Make -fmax-errors visible to frontend's diagnostic machinery. */
944 if (OPTION_SET_P (flag_max_errors
))
945 global
.params
.errorLimit
= flag_max_errors
;
947 if (flag_excess_precision
== EXCESS_PRECISION_DEFAULT
)
948 flag_excess_precision
= EXCESS_PRECISION_STANDARD
;
950 global
.params
.symdebug
= write_symbols
!= NO_DEBUG
;
951 global
.params
.useInline
= flag_inline_functions
;
952 global
.params
.showColumns
= flag_show_column
;
953 global
.params
.printErrorContext
= flag_diagnostics_show_caret
;
955 if (global
.params
.useInline
)
956 global
.params
.hdrStripPlainFunctions
= false;
958 global
.params
.obj
= !flag_syntax_only
;
960 /* Has no effect yet. */
961 global
.params
.pic
= flag_pic
!= 0;
963 /* Add in versions given on the command line. */
964 if (global
.params
.versionids
)
966 for (size_t i
= 0; i
< global
.params
.versionids
->length
; i
++)
968 const char *s
= (*global
.params
.versionids
)[i
];
969 VersionCondition::addGlobalIdent (s
);
973 if (global
.params
.debugids
)
975 for (size_t i
= 0; i
< global
.params
.debugids
->length
; i
++)
977 const char *s
= (*global
.params
.debugids
)[i
];
978 DebugCondition::addGlobalIdent (s
);
982 if (warn_return_type
== -1)
983 warn_return_type
= 0;
988 /* Add the module M to the list of modules that may declare GCC builtins.
989 These are scanned after first semantic and before codegen passes.
990 See d_maybe_set_builtin() for the implementation. */
993 d_add_builtin_module (Module
*m
)
995 builtin_modules
.push (m
);
998 /* Implements the lang_hooks.parse_file routine for language D. */
1003 if (global
.params
.verbose
)
1005 message ("binary %s", global
.params
.argv0
.ptr
);
1006 message ("version %s", global
.versionChars ());
1008 if (global
.versionids
)
1011 gcc_obstack_init (&buffer
);
1012 obstack_grow (&buffer
, "predefs ", 9);
1013 for (size_t i
= 0; i
< global
.versionids
->length
; i
++)
1015 Identifier
*id
= (*global
.versionids
)[i
];
1016 const char *str
= id
->toChars ();
1017 obstack_1grow (&buffer
, ' ');
1018 obstack_grow (&buffer
, str
, strlen (str
));
1021 obstack_1grow (&buffer
, '\0');
1022 message ("%s", (char *) obstack_finish (&buffer
));
1026 /* Start the main input file, if the debug writer wants it. */
1027 if (debug_hooks
->start_end_main_source_file
)
1028 debug_hooks
->start_source_file (0, main_input_filename
);
1030 /* Create Module's for all sources we will load. */
1032 modules
.reserve (num_in_fnames
);
1034 /* In this mode, the first file name is supposed to be a duplicate
1035 of one of the input files. */
1036 if (d_option
.fonly
&& strcmp (d_option
.fonly
, main_input_filename
) != 0)
1037 error ("%<-fonly=%> argument is different from first input file name");
1039 for (size_t i
= 0; i
< num_in_fnames
; i
++)
1041 if (strcmp (in_fnames
[i
], "-") == 0)
1043 /* Load the entire contents of stdin into memory. 8 kilobytes should
1044 be a good enough initial size, but double on each iteration.
1045 16 bytes are added for the final '\n' and 15 bytes of padding. */
1046 ssize_t size
= 8 * 1024;
1047 uchar
*buffer
= XNEWVEC (uchar
, size
+ 16);
1051 while ((count
= read (STDIN_FILENO
, buffer
+ len
, size
- len
)) > 0)
1057 buffer
= XRESIZEVEC (uchar
, buffer
, size
+ 16);
1063 error (Loc ("stdin", 0, 0), "%s", xstrerror (errno
));
1068 /* Handling stdin, generate a unique name for the module. */
1069 Module
*m
= Module::create (in_fnames
[i
],
1070 Identifier::idPool ("__stdin"),
1071 global
.params
.doDocComments
,
1072 global
.params
.doHdrGeneration
);
1075 /* Overwrite the source file for the module, the one created by
1076 Module::create would have a forced a `.d' suffix. */
1077 m
->src
.length
= len
;
1078 m
->src
.ptr
= buffer
;
1082 /* Handling a D source file, strip off the path and extension. */
1083 const char *basename
= FileName::name (in_fnames
[i
]);
1084 const char *name
= FileName::removeExt (basename
);
1086 Module
*m
= Module::create (in_fnames
[i
], Identifier::idPool (name
),
1087 global
.params
.doDocComments
,
1088 global
.params
.doHdrGeneration
);
1090 FileName::free (name
);
1094 /* Read all D source files. */
1095 for (size_t i
= 0; i
< modules
.length
; i
++)
1097 Module
*m
= modules
[i
];
1101 /* Parse all D source files. */
1102 for (size_t i
= 0; i
< modules
.length
; i
++)
1104 Module
*m
= modules
[i
];
1106 if (global
.params
.verbose
)
1107 message ("parse %s", m
->toChars ());
1109 if (!Module::rootModule
)
1110 Module::rootModule
= m
;
1112 m
->importedFrom
= m
;
1115 if (m
->filetype
== FileType::ddoc
)
1118 /* Remove M from list of modules. */
1124 /* Load the module containing D main. */
1125 Module
*main_module
= NULL
;
1126 if (global
.params
.addMain
)
1128 unsigned errors
= global
.startGagging ();
1129 main_module
= Module::load (Loc (), NULL
, Identifier::idPool ("__main"));
1131 if (!global
.endGagging (errors
))
1133 main_module
->importedFrom
= main_module
;
1134 modules
.push (main_module
);
1138 /* If an error occurs later during compilation, remember that we generated
1139 the headers, so that they can be removed before exit. */
1140 bool dump_headers
= false;
1145 if (global
.params
.doHdrGeneration
)
1147 /* Generate 'header' import files. Since 'header' import files must be
1148 independent of command line switches and what else is imported, they
1149 are generated before any semantic analysis. */
1150 for (size_t i
= 0; i
< modules
.length
; i
++)
1152 Module
*m
= modules
[i
];
1153 if (m
->filetype
== FileType::dhdr
1154 || (d_option
.fonly
&& m
!= Module::rootModule
))
1157 if (global
.params
.verbose
)
1158 message ("import %s", m
->toChars ());
1163 dump_headers
= true;
1169 /* Load all unconditional imports for better symbol resolving. */
1170 for (size_t i
= 0; i
< modules
.length
; i
++)
1172 Module
*m
= modules
[i
];
1174 if (global
.params
.verbose
)
1175 message ("importall %s", m
->toChars ());
1177 m
->importAll (NULL
);
1183 /* Do semantic analysis. */
1184 doing_semantic_analysis_p
= true;
1186 for (size_t i
= 0; i
< modules
.length
; i
++)
1188 Module
*m
= modules
[i
];
1190 /* If this is the `__main` module, check that `D main` hasn't already
1191 been declared in user code before running semantic on it. */
1192 if (m
== main_module
&& global
.hasMainFunction
)
1198 if (global
.params
.verbose
)
1199 message ("semantic %s", m
->toChars ());
1201 dsymbolSemantic (m
, NULL
);
1204 /* Do deferred semantic analysis. */
1205 Module::dprogress
= 1;
1206 Module::runDeferredSemantic ();
1208 if (Module::deferred
.length
)
1210 for (size_t i
= 0; i
< Module::deferred
.length
; i
++)
1212 Dsymbol
*sd
= Module::deferred
[i
];
1213 error_at (make_location_t (sd
->loc
),
1214 "unable to resolve forward reference in definition");
1218 /* Process all built-in modules or functions now for CTFE. */
1219 while (builtin_modules
.length
!= 0)
1221 Module
*m
= builtin_modules
.pop ();
1222 d_maybe_set_builtin (m
);
1225 /* Do pass 2 semantic analysis. */
1226 for (size_t i
= 0; i
< modules
.length
; i
++)
1228 Module
*m
= modules
[i
];
1230 if (global
.params
.verbose
)
1231 message ("semantic2 %s", m
->toChars ());
1233 semantic2 (m
, NULL
);
1236 Module::runDeferredSemantic2 ();
1241 /* Do pass 3 semantic analysis. */
1242 for (size_t i
= 0; i
< modules
.length
; i
++)
1244 Module
*m
= modules
[i
];
1246 if (global
.params
.verbose
)
1247 message ("semantic3 %s", m
->toChars ());
1249 semantic3 (m
, NULL
);
1252 Module::runDeferredSemantic3 ();
1254 /* Check again, incase semantic3 pass loaded any more modules. */
1255 while (builtin_modules
.length
!= 0)
1257 Module
*m
= builtin_modules
.pop ();
1258 d_maybe_set_builtin (m
);
1261 /* Do not attempt to generate output files if errors or warnings occurred. */
1262 if (global
.errors
|| global
.warnings
)
1265 /* Generate output files. */
1266 doing_semantic_analysis_p
= false;
1268 if (Module::rootModule
)
1270 /* Declare the name of the root module as the first global name in order
1271 to make the middle-end fully deterministic. */
1273 mangleToBuffer (Module::rootModule
, &buf
);
1274 first_global_object_name
= buf
.extractChars ();
1277 /* Make dependencies. */
1283 gcc_obstack_init (&buffer
);
1285 for (size_t i
= 0; i
< modules
.length
; i
++)
1286 deps_write (modules
[i
], &buffer
);
1288 /* -MF <arg> overrides -M[M]D. */
1289 if (d_option
.deps_filename_user
)
1290 d_option
.deps_filename
= d_option
.deps_filename_user
;
1292 if (d_option
.deps_filename
)
1294 deps_stream
= fopen (d_option
.deps_filename
, "w");
1297 fatal_error (input_location
, "opening dependency file %s: %m",
1298 d_option
.deps_filename
);
1303 deps_stream
= stdout
;
1305 fprintf (deps_stream
, "%s", (char *) obstack_finish (&buffer
));
1307 if (deps_stream
!= stdout
1308 && (ferror (deps_stream
) || fclose (deps_stream
)))
1310 fatal_error (input_location
, "closing dependency file %s: %m",
1311 d_option
.deps_filename
);
1315 if (global
.params
.vtemplates
)
1316 printTemplateStats ();
1318 /* Generate JSON files. */
1319 if (global
.params
.doJsonGeneration
)
1322 json_generate (&buf
, &modules
);
1324 const char *name
= global
.params
.jsonfilename
.ptr
;
1327 if (name
&& (name
[0] != '-' || name
[1] != '\0'))
1330 = FileName::defaultExt (name
, json_ext
.ptr
);
1331 json_stream
= fopen (nameext
, "w");
1334 fatal_error (input_location
, "opening json file %s: %m", nameext
);
1339 json_stream
= stdout
;
1341 fprintf (json_stream
, "%s", buf
.peekChars ());
1343 if (json_stream
!= stdout
1344 && (ferror (json_stream
) || fclose (json_stream
)))
1345 fatal_error (input_location
, "closing json file %s: %m", name
);
1348 /* Generate Ddoc files. */
1349 if (global
.params
.doDocComments
&& !global
.errors
&& !errorcount
)
1351 for (size_t i
= 0; i
< modules
.length
; i
++)
1353 Module
*m
= modules
[i
];
1358 /* Handle -fdump-d-original. */
1359 if (global
.params
.vcg_ast
)
1361 for (size_t i
= 0; i
< modules
.length
; i
++)
1363 Module
*m
= modules
[i
];
1367 moduleToBuffer (&buf
, m
);
1368 message ("%s", buf
.peekChars ());
1372 /* Generate C++ header files. */
1373 if (global
.params
.doCxxHdrGeneration
!= CxxHeaderMode::none
)
1374 genCppHdrFiles (modules
);
1379 for (size_t i
= 0; i
< modules
.length
; i
++)
1381 Module
*m
= modules
[i
];
1383 /* Skip generating code for header files, or when the module wasn't
1384 specified by `-fonly=`. */
1385 if ((m
->filetype
== FileType::dhdr
&& m
!= main_module
)
1386 || (d_option
.fonly
&& m
!= Module::rootModule
))
1389 if (global
.params
.verbose
)
1390 message ("code %s", m
->toChars ());
1392 if (!flag_syntax_only
)
1393 build_decl_tree (m
);
1396 /* And end the main input file, if the debug writer wants it. */
1397 if (debug_hooks
->start_end_main_source_file
)
1398 debug_hooks
->end_source_file (0);
1401 /* Add the D frontend error count to the GCC error count to correctly
1402 exit with an error status. */
1403 errorcount
+= (global
.errors
+ global
.warnings
);
1405 /* We want to write the mixin expansion file also on error. */
1406 if (global
.params
.mixinOut
)
1408 FILE *mixin_stream
= fopen (global
.params
.mixinFile
, "w");
1412 OutBuffer
*buf
= global
.params
.mixinOut
;
1413 fprintf (mixin_stream
, "%s", buf
->peekChars ());
1415 if (ferror (mixin_stream
) || fclose (mixin_stream
))
1416 fatal_error (input_location
, "closing mixin file %s: %m",
1417 global
.params
.mixinFile
);
1421 fatal_error (input_location
, "opening mixin file %s: %m",
1422 global
.params
.mixinFile
);
1426 /* Remove generated .di files on error. */
1427 if (errorcount
&& dump_headers
)
1429 for (size_t i
= 0; i
< modules
.length
; i
++)
1431 Module
*m
= modules
[i
];
1432 if (m
->filetype
== FileType::dhdr
1433 || (d_option
.fonly
&& m
!= Module::rootModule
))
1436 remove (m
->hdrfile
.toChars ());
1440 /* Write out globals. */
1441 d_finish_compilation (vec_safe_address (global_declarations
),
1442 vec_safe_length (global_declarations
));
1445 /* Implements the lang_hooks.types.type_for_mode routine for language D. */
1448 d_type_for_mode (machine_mode mode
, int unsignedp
)
1451 return unsignedp
? d_ubyte_type
: d_byte_type
;
1454 return unsignedp
? d_ushort_type
: d_short_type
;
1457 return unsignedp
? d_uint_type
: d_int_type
;
1460 return unsignedp
? d_ulong_type
: d_long_type
;
1462 if (mode
== TYPE_MODE (d_cent_type
))
1463 return unsignedp
? d_ucent_type
: d_cent_type
;
1465 if (mode
== TYPE_MODE (float_type_node
))
1466 return float_type_node
;
1468 if (mode
== TYPE_MODE (double_type_node
))
1469 return double_type_node
;
1471 if (mode
== TYPE_MODE (long_double_type_node
))
1472 return long_double_type_node
;
1474 if (mode
== TYPE_MODE (build_pointer_type (char8_type_node
)))
1475 return build_pointer_type (char8_type_node
);
1477 if (mode
== TYPE_MODE (build_pointer_type (d_int_type
)))
1478 return build_pointer_type (d_int_type
);
1480 for (int i
= 0; i
< NUM_INT_N_ENTS
; i
++)
1482 if (int_n_enabled_p
[i
] && mode
== int_n_data
[i
].m
)
1485 return int_n_trees
[i
].unsigned_type
;
1487 return int_n_trees
[i
].signed_type
;
1491 if (COMPLEX_MODE_P (mode
))
1493 machine_mode inner_mode
;
1496 if (mode
== TYPE_MODE (complex_float_type_node
))
1497 return complex_float_type_node
;
1498 if (mode
== TYPE_MODE (complex_double_type_node
))
1499 return complex_double_type_node
;
1500 if (mode
== TYPE_MODE (complex_long_double_type_node
))
1501 return complex_long_double_type_node
;
1503 inner_mode
= (machine_mode
) GET_MODE_INNER (mode
);
1504 inner_type
= d_type_for_mode (inner_mode
, unsignedp
);
1505 if (inner_type
!= NULL_TREE
)
1506 return build_complex_type (inner_type
);
1508 else if (VECTOR_MODE_P (mode
))
1510 machine_mode inner_mode
= (machine_mode
) GET_MODE_INNER (mode
);
1511 tree inner_type
= d_type_for_mode (inner_mode
, unsignedp
);
1512 if (inner_type
!= NULL_TREE
)
1513 return build_vector_type_for_mode (inner_type
, mode
);
1519 /* Implements the lang_hooks.types.type_for_size routine for language D. */
1522 d_type_for_size (unsigned bits
, int unsignedp
)
1524 if (bits
<= TYPE_PRECISION (d_byte_type
))
1525 return unsignedp
? d_ubyte_type
: d_byte_type
;
1527 if (bits
<= TYPE_PRECISION (d_short_type
))
1528 return unsignedp
? d_ushort_type
: d_short_type
;
1530 if (bits
<= TYPE_PRECISION (d_int_type
))
1531 return unsignedp
? d_uint_type
: d_int_type
;
1533 if (bits
<= TYPE_PRECISION (d_long_type
))
1534 return unsignedp
? d_ulong_type
: d_long_type
;
1536 if (bits
<= TYPE_PRECISION (d_cent_type
))
1537 return unsignedp
? d_ucent_type
: d_cent_type
;
1539 for (int i
= 0; i
< NUM_INT_N_ENTS
; i
++)
1541 if (int_n_enabled_p
[i
] && bits
== int_n_data
[i
].bitsize
)
1544 return int_n_trees
[i
].unsigned_type
;
1546 return int_n_trees
[i
].signed_type
;
1553 /* Implements the lang_hooks.types.type_promotes_to routine for language D. */
1556 d_type_promotes_to (tree type
)
1558 /* Promotions are only applied on unnamed function arguments for declarations
1559 with `extern(C)' or `extern(C++)' linkage. */
1560 if (cfun
&& DECL_LANG_FRONTEND (cfun
->decl
)
1561 && DECL_LANG_FRONTEND (cfun
->decl
)->linkage
!= LINK::d
)
1563 /* In [type/integer-promotions], integer promotions are conversions of the
1575 If an enum has as a base type one of the types in the left column, it
1576 is converted to the type in the right column. */
1577 if (TREE_CODE (type
) == ENUMERAL_TYPE
&& ENUM_IS_SCOPED (type
))
1578 type
= TREE_TYPE (type
);
1580 type
= TYPE_MAIN_VARIANT (type
);
1582 /* Check for promotions of target-defined types first. */
1583 tree promoted_type
= targetm
.promoted_type (type
);
1585 return promoted_type
;
1587 if (TREE_CODE (type
) == BOOLEAN_TYPE
)
1590 if (INTEGRAL_TYPE_P (type
))
1592 if (type
== d_byte_type
|| type
== d_ubyte_type
1593 || type
== d_short_type
|| type
== d_ushort_type
1594 || type
== char8_type_node
|| type
== char16_type_node
)
1597 if (type
== char32_type_node
)
1600 if (TYPE_PRECISION (type
) < TYPE_PRECISION (d_int_type
))
1604 /* Float arguments are converted to doubles. */
1605 if (type
== float_type_node
)
1606 return double_type_node
;
1608 if (type
== ifloat_type_node
)
1609 return idouble_type_node
;
1615 /* Implements the lang_hooks.decls.global_bindings_p routine for language D.
1616 Return true if we are in the global binding level. */
1619 d_global_bindings_p (void)
1621 return (current_binding_level
== global_binding_level
);
1624 /* Return global_context, but create it first if need be. */
1627 get_global_context (void)
1629 if (!global_context
)
1631 global_context
= build_translation_unit_decl (NULL_TREE
);
1632 debug_hooks
->register_main_translation_unit (global_context
);
1635 return global_context
;
1638 /* Implements the lang_hooks.decls.pushdecl routine for language D.
1639 Record DECL as belonging to the current lexical scope. */
1642 d_pushdecl (tree decl
)
1644 /* Set the context of the decl. If current_function_decl did not help in
1645 determining the context, use global scope. */
1646 if (!DECL_CONTEXT (decl
))
1648 if (current_function_decl
)
1649 DECL_CONTEXT (decl
) = current_function_decl
;
1651 DECL_CONTEXT (decl
) = get_global_context ();
1654 /* Put decls on list in reverse order. */
1655 if (TREE_STATIC (decl
) || d_global_bindings_p ())
1656 vec_safe_push (global_declarations
, decl
);
1659 TREE_CHAIN (decl
) = current_binding_level
->names
;
1660 current_binding_level
->names
= decl
;
1666 /* Implements the lang_hooks.decls.getdecls routine for language D.
1667 Return the list of declarations of the current level. */
1672 if (current_binding_level
)
1673 return current_binding_level
->names
;
1679 /* Implements the lang_hooks.get_alias_set routine for language D.
1680 Get the alias set corresponding to type or expression T.
1681 Return -1 if we don't do anything special. */
1683 static alias_set_type
1684 d_get_alias_set (tree
)
1686 /* For now in D, assume everything aliases everything else, until we define
1687 some solid rules backed by a specification. There are also some parts
1688 of code generation routines that don't adhere to C alias rules, such as
1689 build_vconvert. In any case, a lot of user code already assumes there
1690 is no strict aliasing and will break if we were to change that. */
1694 /* Implements the lang_hooks.types_compatible_p routine for language D.
1695 Compares two types for equivalence in the D programming language.
1696 This routine should only return 1 if it is sure, even though the frontend
1697 should have already ensured that all types are compatible before handing
1698 over the parsed ASTs to the code generator. */
1701 d_types_compatible_p (tree x
, tree y
)
1703 Type
*tx
= TYPE_LANG_FRONTEND (x
);
1704 Type
*ty
= TYPE_LANG_FRONTEND (y
);
1706 /* Try validating the types in the frontend. */
1707 if (tx
!= NULL
&& ty
!= NULL
)
1709 /* Types are equivalent. */
1710 if (same_type_p (tx
, ty
))
1713 /* Type system allows implicit conversion between. */
1714 if (tx
->implicitConvTo (ty
) != MATCH::nomatch
1715 || ty
->implicitConvTo (tx
) != MATCH::nomatch
)
1719 /* Fallback on using type flags for comparison. E.g: all dynamic arrays
1720 are distinct types in D, but are VIEW_CONVERT compatible. */
1721 if (TREE_CODE (x
) == RECORD_TYPE
&& TREE_CODE (y
) == RECORD_TYPE
)
1723 if (TYPE_DYNAMIC_ARRAY (x
) && TYPE_DYNAMIC_ARRAY (y
))
1726 if (TYPE_DELEGATE (x
) && TYPE_DELEGATE (y
))
1729 if (TYPE_ASSOCIATIVE_ARRAY (x
) && TYPE_ASSOCIATIVE_ARRAY (y
))
1736 /* Implements the lang_hooks.finish_incomplete_decl routine for language D. */
1739 d_finish_incomplete_decl (tree decl
)
1743 /* D allows zero-length declarations. Such a declaration ends up with
1744 DECL_SIZE (t) == NULL_TREE which is what the back-end function
1745 assembler_variable checks. This could change in later versions, or
1746 maybe all of these variables should be aliased to one symbol. */
1747 if (DECL_SIZE (decl
) == 0)
1749 DECL_SIZE (decl
) = bitsize_zero_node
;
1750 DECL_SIZE_UNIT (decl
) = size_zero_node
;
1755 /* Implements the lang_hooks.types.classify_record routine for language D.
1756 Return the true debug type for TYPE. */
1758 static classify_record
1759 d_classify_record (tree type
)
1761 Type
*t
= TYPE_LANG_FRONTEND (type
);
1762 TypeClass
*tc
= t
? t
->isTypeClass () : NULL
;
1766 /* extern(C++) interfaces get emitted as classes. */
1767 if (tc
->sym
->isInterfaceDeclaration ()
1768 && !tc
->sym
->isCPPinterface ())
1769 return RECORD_IS_INTERFACE
;
1771 return RECORD_IS_CLASS
;
1774 return RECORD_IS_STRUCT
;
1777 /* Implements the lang_hooks.tree_size routine for language D.
1778 Determine the size of our tcc_constant or tcc_exceptional nodes. */
1781 d_tree_size (tree_code code
)
1785 case FUNCFRAME_INFO
:
1786 return sizeof (tree_frame_info
);
1793 /* Implements the lang_hooks.print_xnode routine for language D. */
1796 d_print_xnode (FILE *file
, tree node
, int indent
)
1798 switch (TREE_CODE (node
))
1800 case FUNCFRAME_INFO
:
1801 print_node (file
, "frame_type", FRAMEINFO_TYPE (node
), indent
+ 4);
1809 /* Return which tree structure is used by NODE, or TS_D_GENERIC if NODE
1810 is one of the language-independent trees. */
1812 d_tree_node_structure_enum
1813 d_tree_node_structure (lang_tree_node
*t
)
1815 switch (TREE_CODE (&t
->generic
))
1817 case IDENTIFIER_NODE
:
1818 return TS_D_IDENTIFIER
;
1820 case FUNCFRAME_INFO
:
1821 return TS_D_FRAMEINFO
;
1824 return TS_D_GENERIC
;
1828 /* Allocate and return a lang specific structure for the frontend type. */
1831 build_lang_type (Type
*t
)
1833 struct lang_type
*lt
= ggc_cleared_alloc
<struct lang_type
> ();
1838 /* Allocate and return a lang specific structure for the frontend decl. */
1841 build_lang_decl (Declaration
*d
)
1843 /* For compiler generated run-time typeinfo, a lang_decl is allocated even if
1844 there's no associated frontend symbol to refer to (yet). If the symbol
1845 appears later in the compilation, then the slot will be re-used. */
1847 return ggc_cleared_alloc
<struct lang_decl
> ();
1849 struct lang_decl
*ld
= (d
->csym
) ? DECL_LANG_SPECIFIC (d
->csym
) : NULL
;
1851 ld
= ggc_cleared_alloc
<struct lang_decl
> ();
1853 if (ld
->decl
== NULL
)
1859 /* Implements the lang_hooks.dup_lang_specific_decl routine for language D.
1860 Replace the DECL_LANG_SPECIFIC field of NODE with a copy. */
1863 d_dup_lang_specific_decl (tree node
)
1865 if (!DECL_LANG_SPECIFIC (node
))
1868 struct lang_decl
*ld
= ggc_alloc
<struct lang_decl
> ();
1869 memcpy (ld
, DECL_LANG_SPECIFIC (node
), sizeof (struct lang_decl
));
1870 DECL_LANG_SPECIFIC (node
) = ld
;
1873 /* This preserves trees we create from the garbage collector. */
1875 static GTY(()) tree d_keep_list
= NULL_TREE
;
1880 d_keep_list
= tree_cons (NULL_TREE
, t
, d_keep_list
);
1883 /* Implements the lang_hooks.eh_personality routine for language D.
1884 Return the GDC personality function decl. */
1886 static GTY(()) tree d_eh_personality_decl
;
1889 d_eh_personality (void)
1891 if (!d_eh_personality_decl
)
1892 d_eh_personality_decl
= build_personality_function ("gdc");
1894 return d_eh_personality_decl
;
1897 /* Implements the lang_hooks.eh_runtime_type routine for language D. */
1900 d_build_eh_runtime_type (tree type
)
1902 Type
*t
= TYPE_LANG_FRONTEND (type
);
1903 gcc_assert (t
!= NULL
);
1904 t
= t
->toBasetype ();
1906 ClassDeclaration
*cd
= t
->isTypeClass ()->sym
;
1909 if (cd
->isCPPclass ())
1910 decl
= get_cpp_typeinfo_decl (cd
);
1912 decl
= get_classinfo_decl (cd
);
1914 return convert (ptr_type_node
, build_address (decl
));
1917 /* Implements the lang_hooks.enum_underlying_base_type routine for language D.
1918 Returns the underlying type of the given enumeration TYPE. */
1921 d_enum_underlying_base_type (const_tree type
)
1923 gcc_assert (TREE_CODE (type
) == ENUMERAL_TYPE
);
1924 return TREE_TYPE (type
);
1927 /* Definitions for our language-specific hooks. */
1929 #undef LANG_HOOKS_NAME
1930 #undef LANG_HOOKS_INIT
1931 #undef LANG_HOOKS_INIT_TS
1932 #undef LANG_HOOKS_INIT_OPTIONS
1933 #undef LANG_HOOKS_INIT_OPTIONS_STRUCT
1934 #undef LANG_HOOKS_OPTION_LANG_MASK
1935 #undef LANG_HOOKS_HANDLE_OPTION
1936 #undef LANG_HOOKS_POST_OPTIONS
1937 #undef LANG_HOOKS_PARSE_FILE
1938 #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
1939 #undef LANG_HOOKS_ATTRIBUTE_TABLE
1940 #undef LANG_HOOKS_GET_ALIAS_SET
1941 #undef LANG_HOOKS_TYPES_COMPATIBLE_P
1942 #undef LANG_HOOKS_BUILTIN_FUNCTION
1943 #undef LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE
1944 #undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
1945 #undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
1946 #undef LANG_HOOKS_GIMPLIFY_EXPR
1947 #undef LANG_HOOKS_CLASSIFY_RECORD
1948 #undef LANG_HOOKS_TREE_SIZE
1949 #undef LANG_HOOKS_PRINT_XNODE
1950 #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
1951 #undef LANG_HOOKS_EH_PERSONALITY
1952 #undef LANG_HOOKS_EH_RUNTIME_TYPE
1953 #undef LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE
1954 #undef LANG_HOOKS_PUSHDECL
1955 #undef LANG_HOOKS_GETDECLS
1956 #undef LANG_HOOKS_GLOBAL_BINDINGS_P
1957 #undef LANG_HOOKS_TYPE_FOR_MODE
1958 #undef LANG_HOOKS_TYPE_FOR_SIZE
1959 #undef LANG_HOOKS_TYPE_PROMOTES_TO
1961 #define LANG_HOOKS_NAME "GNU D"
1962 #define LANG_HOOKS_INIT d_init
1963 #define LANG_HOOKS_INIT_TS d_init_ts
1964 #define LANG_HOOKS_INIT_OPTIONS d_init_options
1965 #define LANG_HOOKS_INIT_OPTIONS_STRUCT d_init_options_struct
1966 #define LANG_HOOKS_OPTION_LANG_MASK d_option_lang_mask
1967 #define LANG_HOOKS_HANDLE_OPTION d_handle_option
1968 #define LANG_HOOKS_POST_OPTIONS d_post_options
1969 #define LANG_HOOKS_PARSE_FILE d_parse_file
1970 #define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE d_langhook_common_attribute_table
1971 #define LANG_HOOKS_ATTRIBUTE_TABLE d_langhook_attribute_table
1972 #define LANG_HOOKS_GET_ALIAS_SET d_get_alias_set
1973 #define LANG_HOOKS_TYPES_COMPATIBLE_P d_types_compatible_p
1974 #define LANG_HOOKS_BUILTIN_FUNCTION d_builtin_function
1975 #define LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE d_builtin_function_ext_scope
1976 #define LANG_HOOKS_REGISTER_BUILTIN_TYPE d_register_builtin_type
1977 #define LANG_HOOKS_FINISH_INCOMPLETE_DECL d_finish_incomplete_decl
1978 #define LANG_HOOKS_GIMPLIFY_EXPR d_gimplify_expr
1979 #define LANG_HOOKS_CLASSIFY_RECORD d_classify_record
1980 #define LANG_HOOKS_TREE_SIZE d_tree_size
1981 #define LANG_HOOKS_PRINT_XNODE d_print_xnode
1982 #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL d_dup_lang_specific_decl
1983 #define LANG_HOOKS_EH_PERSONALITY d_eh_personality
1984 #define LANG_HOOKS_EH_RUNTIME_TYPE d_build_eh_runtime_type
1985 #define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE d_enum_underlying_base_type
1986 #define LANG_HOOKS_PUSHDECL d_pushdecl
1987 #define LANG_HOOKS_GETDECLS d_getdecls
1988 #define LANG_HOOKS_GLOBAL_BINDINGS_P d_global_bindings_p
1989 #define LANG_HOOKS_TYPE_FOR_MODE d_type_for_mode
1990 #define LANG_HOOKS_TYPE_FOR_SIZE d_type_for_size
1991 #define LANG_HOOKS_TYPE_PROMOTES_TO d_type_promotes_to
1993 struct lang_hooks lang_hooks
= LANG_HOOKS_INITIALIZER
;
1995 #include "gt-d-d-lang.h"
1996 #include "gtype-d.h"