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