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