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