]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/d-lang.cc
d: Return promoted types in d_type_promotes_to when linkage is not D
[thirdparty/gcc.git] / gcc / d / d-lang.cc
1 /* d-lang.cc -- Language-dependent hooks for D.
2 Copyright (C) 2006-2020 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 for (const char *p = target; *p != '\0'; p++)
118 {
119 switch (*p)
120 {
121 case ' ':
122 case '\t':
123 for (const char *q = p - 1; target <= q && *q == '\\'; q--)
124 obstack_1grow (&buffer, '\\');
125 obstack_1grow (&buffer, '\\');
126 break;
127
128 case '$':
129 obstack_1grow (&buffer, '$');
130 break;
131
132 case '#':
133 obstack_1grow (&buffer, '\\');
134 break;
135
136 default:
137 break;
138 }
139
140 obstack_1grow (&buffer, *p);
141 }
142
143 d_option.deps_target.safe_push ((const char *) obstack_finish (&buffer));
144 }
145
146 /* Write STR, with a leading space to BUFFER, updating COLUMN as appropriate.
147 COLMAX is the number of columns to word-wrap at (0 means don't wrap). */
148
149 static void
150 deps_write_string (const char *str, obstack *buffer, unsigned &column,
151 unsigned colmax = 72)
152 {
153 unsigned size = strlen (str);
154
155 if (column != 0)
156 {
157 if (colmax && column + size > colmax)
158 {
159 obstack_grow (buffer, " \\\n ", 4);
160 column = 1;
161 }
162 else
163 {
164 obstack_1grow (buffer, ' ');
165 column++;
166 }
167 }
168
169 column += size;
170 obstack_grow (buffer, str, size);
171 }
172
173 /* Write out all dependencies of a given MODULE to the specified BUFFER. */
174
175 static void
176 deps_write (Module *module, obstack *buffer)
177 {
178 hash_set <const char *> seen_modules;
179 vec <const char *> dependencies = vNULL;
180
181 Modules modlist;
182 modlist.push (module);
183
184 vec <const char *> phonylist = vNULL;
185 unsigned column = 0;
186
187 /* Write out make target module name. */
188 if (d_option.deps_target.length ())
189 {
190 for (unsigned i = 0; i < d_option.deps_target.length (); i++)
191 deps_write_string (d_option.deps_target[i], buffer, column);
192 }
193 else
194 deps_write_string (module->objfile->name->str, buffer, column);
195
196 obstack_1grow (buffer, ':');
197 column++;
198
199 /* Search all modules for file dependencies. */
200 while (modlist.length > 0)
201 {
202 Module *depmod = modlist.pop ();
203
204 const char *modstr = depmod->srcfile->name->str;
205
206 /* Skip modules that have already been looked at. */
207 if (seen_modules.add (modstr))
208 continue;
209
210 dependencies.safe_push (modstr);
211
212 /* Add to list of phony targets if is not being compile. */
213 if (d_option.deps_phony && !depmod->isRoot ())
214 phonylist.safe_push (modstr);
215
216 /* Add imported files to dependency list. */
217 for (size_t i = 0; i < depmod->contentImportedFiles.length; i++)
218 {
219 const char *impstr = depmod->contentImportedFiles[i];
220 dependencies.safe_push (impstr);
221 phonylist.safe_push (impstr);
222 }
223
224 /* Search all imports of the module. */
225 for (size_t i = 0; i < depmod->aimports.length; i++)
226 {
227 Module *m = depmod->aimports[i];
228
229 /* Ignore compiler-generated modules. */
230 if ((m->ident == Identifier::idPool ("__entrypoint")
231 || m->ident == Identifier::idPool ("__main"))
232 && m->parent == NULL)
233 continue;
234
235 /* Don't search system installed modules, this includes
236 object, core.*, std.*, and gcc.* packages. */
237 if (d_option.deps_skip_system)
238 {
239 if (m->ident == Identifier::idPool ("object")
240 && m->parent == NULL)
241 continue;
242
243 if (m->md && m->md->packages)
244 {
245 Identifier *package = (*m->md->packages)[0];
246
247 if (package == Identifier::idPool ("core")
248 || package == Identifier::idPool ("std")
249 || package == Identifier::idPool ("gcc"))
250 continue;
251 }
252 }
253
254 modlist.push (m);
255 }
256 }
257
258 /* Write out all make dependencies. */
259 for (size_t i = 0; i < dependencies.length (); i++)
260 deps_write_string (dependencies[i], buffer, column);
261
262 obstack_1grow (buffer, '\n');
263
264 /* Write out all phony targets. */
265 for (size_t i = 0; i < phonylist.length (); i++)
266 {
267 const char *str = phonylist[i];
268 obstack_1grow (buffer, '\n');
269 obstack_grow (buffer, str, strlen (str));
270 obstack_grow (buffer, ":\n", 2);
271 }
272 }
273
274 /* Implements the lang_hooks.init_options routine for language D.
275 This initializes the global state for the D frontend before calling
276 the option handlers. */
277
278 static void
279 d_init_options (unsigned int, cl_decoded_option *decoded_options)
280 {
281 /* Set default values. */
282 global._init ();
283
284 global.vendor = lang_hooks.name;
285 global.params.argv0 = xstrdup (decoded_options[0].arg);
286 global.params.link = true;
287 global.params.useAssert = CHECKENABLEdefault;
288 global.params.useInvariants = CHECKENABLEdefault;
289 global.params.useIn = CHECKENABLEdefault;
290 global.params.useOut = CHECKENABLEdefault;
291 global.params.useArrayBounds = CHECKENABLEdefault;
292 global.params.useSwitchError = CHECKENABLEdefault;
293 global.params.checkAction = CHECKACTION_D;
294 global.params.useModuleInfo = true;
295 global.params.useTypeInfo = true;
296 global.params.useExceptions = true;
297 global.params.useInline = false;
298 global.params.obj = true;
299 global.params.hdrStripPlainFunctions = true;
300 global.params.betterC = false;
301 global.params.allInst = false;
302 global.params.errorLimit = flag_max_errors;
303
304 /* Default extern(C++) mangling to C++14. */
305 global.params.cplusplus = CppStdRevisionCpp14;
306
307 /* Warnings and deprecations are disabled by default. */
308 global.params.useDeprecated = DIAGNOSTICinform;
309 global.params.warnings = DIAGNOSTICoff;
310
311 global.params.imppath = new Strings ();
312 global.params.fileImppath = new Strings ();
313
314 /* Extra GDC-specific options. */
315 d_option.fonly = NULL;
316 d_option.multilib = NULL;
317 d_option.prefix = NULL;
318 d_option.deps = false;
319 d_option.deps_skip_system = false;
320 d_option.deps_filename = NULL;
321 d_option.deps_filename_user = NULL;
322 d_option.deps_target = vNULL;
323 d_option.deps_phony = false;
324 d_option.stdinc = true;
325 }
326
327 /* Implements the lang_hooks.init_options_struct routine for language D.
328 Initializes the options structure OPTS. */
329
330 static void
331 d_init_options_struct (gcc_options *opts)
332 {
333 /* GCC options. */
334 opts->x_flag_exceptions = 1;
335
336 /* Avoid range issues for complex multiply and divide. */
337 opts->x_flag_complex_method = 2;
338
339 /* Unlike C, there is no global `errno' variable. */
340 opts->x_flag_errno_math = 0;
341 opts->frontend_set_flag_errno_math = true;
342
343 /* D says that signed overflow is precisely defined. */
344 opts->x_flag_wrapv = 1;
345 }
346
347 /* Implements the lang_hooks.lang_mask routine for language D.
348 Returns language mask for option parsing. */
349
350 static unsigned int
351 d_option_lang_mask (void)
352 {
353 return CL_D;
354 }
355
356 /* Implements the lang_hooks.init routine for language D. */
357
358 static bool
359 d_init (void)
360 {
361 Type::_init ();
362 Id::initialize ();
363 Module::_init ();
364 Expression::_init ();
365 Objc::_init ();
366
367 /* Back-end init. */
368 global_binding_level = ggc_cleared_alloc <binding_level> ();
369 current_binding_level = global_binding_level;
370
371 /* This allows the code in d-builtins.cc to not have to worry about
372 converting (C signed char *) to (D char *) for string arguments of
373 built-in functions. The parameter (signed_char = false) specifies
374 whether char is signed. */
375 build_common_tree_nodes (false);
376
377 d_init_builtins ();
378
379 if (flag_exceptions)
380 using_eh_for_cleanups ();
381
382 if (!supports_one_only ())
383 flag_weak = 0;
384
385 /* This is the C main, not the D main. */
386 main_identifier_node = get_identifier ("main");
387
388 target._init (global.params);
389 d_init_versions ();
390
391 /* Insert all library-configured identifiers and import paths. */
392 add_import_paths (d_option.prefix, d_option.multilib, d_option.stdinc);
393
394 return 1;
395 }
396
397 /* Implements the lang_hooks.init_ts routine for language D. */
398
399 static void
400 d_init_ts (void)
401 {
402 MARK_TS_TYPED (FLOAT_MOD_EXPR);
403 MARK_TS_TYPED (UNSIGNED_RSHIFT_EXPR);
404 }
405
406 /* Implements the lang_hooks.handle_option routine for language D.
407 Handles D specific options. Return false if we didn't do anything. */
408
409 static bool
410 d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
411 int kind ATTRIBUTE_UNUSED,
412 location_t loc ATTRIBUTE_UNUSED,
413 const cl_option_handlers *handlers ATTRIBUTE_UNUSED)
414 {
415 opt_code code = (opt_code) scode;
416 bool result = true;
417
418 switch (code)
419 {
420 case OPT_fall_instantiations:
421 global.params.allInst = value;
422 break;
423
424 case OPT_fassert:
425 global.params.useAssert = value ? CHECKENABLEon : CHECKENABLEoff;
426 break;
427
428 case OPT_fbounds_check:
429 global.params.useArrayBounds = value ? CHECKENABLEon : CHECKENABLEoff;
430 break;
431
432 case OPT_fbounds_check_:
433 global.params.useArrayBounds = (value == 2) ? CHECKENABLEon
434 : (value == 1) ? CHECKENABLEsafeonly : CHECKENABLEoff;
435 break;
436
437 case OPT_fdebug:
438 global.params.debuglevel = value ? 1 : 0;
439 break;
440
441 case OPT_fdebug_:
442 if (ISDIGIT (arg[0]))
443 {
444 int level = integral_argument (arg);
445 if (level != -1)
446 {
447 global.params.debuglevel = level;
448 break;
449 }
450 }
451
452 if (Identifier::isValidIdentifier (CONST_CAST (char *, arg)))
453 {
454 if (!global.params.debugids)
455 global.params.debugids = new Strings ();
456 global.params.debugids->push (arg);
457 break;
458 }
459
460 error ("bad argument for %<-fdebug%>: %qs", arg);
461 break;
462
463 case OPT_fdoc:
464 global.params.doDocComments = value;
465 break;
466
467 case OPT_fdoc_dir_:
468 global.params.doDocComments = true;
469 global.params.docdir = arg;
470 break;
471
472 case OPT_fdoc_file_:
473 global.params.doDocComments = true;
474 global.params.docname = arg;
475 break;
476
477 case OPT_fdoc_inc_:
478 global.params.ddocfiles.push (arg);
479 break;
480
481 case OPT_fdruntime:
482 global.params.betterC = !value;
483 break;
484
485 case OPT_fdump_d_original:
486 global.params.vcg_ast = value;
487 break;
488
489 case OPT_fexceptions:
490 global.params.useExceptions = value;
491 break;
492
493 case OPT_fignore_unknown_pragmas:
494 global.params.ignoreUnsupportedPragmas = value;
495 break;
496
497 case OPT_finvariants:
498 global.params.useInvariants = value ? CHECKENABLEon : CHECKENABLEoff;
499 break;
500
501 case OPT_fmain:
502 global.params.addMain = value;
503 break;
504
505 case OPT_fmodule_file_:
506 global.params.modFileAliasStrings.push (arg);
507 if (!strchr (arg, '='))
508 error ("bad argument for %<-fmodule-file%>: %qs", arg);
509 break;
510
511 case OPT_fmoduleinfo:
512 global.params.useModuleInfo = value;
513 break;
514
515 case OPT_fonly_:
516 d_option.fonly = arg;
517 break;
518
519 case OPT_fpostconditions:
520 global.params.useOut = value ? CHECKENABLEon : CHECKENABLEoff;
521 break;
522
523 case OPT_fpreconditions:
524 global.params.useIn = value ? CHECKENABLEon : CHECKENABLEoff;
525 break;
526
527 case OPT_frelease:
528 global.params.release = value;
529 break;
530
531 case OPT_frtti:
532 global.params.useTypeInfo = value;
533 break;
534
535 case OPT_fswitch_errors:
536 global.params.useSwitchError = value ? CHECKENABLEon : CHECKENABLEoff;
537 break;
538
539 case OPT_ftransition_all:
540 global.params.vtls = value;
541 global.params.vfield = value;
542 global.params.vcomplex = value;
543 break;
544
545 case OPT_ftransition_checkimports:
546 global.params.check10378 = value;
547 break;
548
549 case OPT_ftransition_complex:
550 global.params.vcomplex = value;
551 break;
552
553 case OPT_ftransition_dip1000:
554 global.params.vsafe = value;
555 global.params.useDIP25 = value;
556 break;
557
558 case OPT_ftransition_dip25:
559 global.params.useDIP25 = value;
560 break;
561
562 case OPT_ftransition_field:
563 global.params.vfield = value;
564 break;
565
566 case OPT_ftransition_import:
567 global.params.bug10378 = value;
568 break;
569
570 case OPT_ftransition_nogc:
571 global.params.vgc = value;
572 break;
573
574 case OPT_ftransition_tls:
575 global.params.vtls = value;
576 break;
577
578 case OPT_funittest:
579 global.params.useUnitTests = value;
580 break;
581
582 case OPT_fversion_:
583 if (ISDIGIT (arg[0]))
584 {
585 int level = integral_argument (arg);
586 if (level != -1)
587 {
588 global.params.versionlevel = level;
589 break;
590 }
591 }
592
593 if (Identifier::isValidIdentifier (CONST_CAST (char *, arg)))
594 {
595 if (!global.params.versionids)
596 global.params.versionids = new Strings ();
597 global.params.versionids->push (arg);
598 break;
599 }
600
601 error ("bad argument for %<-fversion%>: %qs", arg);
602 break;
603
604 case OPT_H:
605 global.params.doHdrGeneration = true;
606 break;
607
608 case OPT_Hd:
609 global.params.doHdrGeneration = true;
610 global.params.hdrdir = arg;
611 break;
612
613 case OPT_Hf:
614 global.params.doHdrGeneration = true;
615 global.params.hdrname = arg;
616 break;
617
618 case OPT_imultilib:
619 d_option.multilib = arg;
620 break;
621
622 case OPT_iprefix:
623 d_option.prefix = arg;
624 break;
625
626 case OPT_I:
627 global.params.imppath->push (arg);
628 break;
629
630 case OPT_J:
631 global.params.fileImppath->push (arg);
632 break;
633
634 case OPT_MM:
635 d_option.deps_skip_system = true;
636 /* Fall through. */
637
638 case OPT_M:
639 d_option.deps = true;
640 break;
641
642 case OPT_MMD:
643 d_option.deps_skip_system = true;
644 /* Fall through. */
645
646 case OPT_MD:
647 d_option.deps = true;
648 d_option.deps_filename = arg;
649 break;
650
651 case OPT_MF:
652 /* If specified multiple times, last one wins. */
653 d_option.deps_filename_user = arg;
654 break;
655
656 case OPT_MP:
657 d_option.deps_phony = true;
658 break;
659
660 case OPT_MQ:
661 deps_add_target (arg, true);
662 break;
663
664 case OPT_MT:
665 deps_add_target (arg, false);
666 break;
667
668 case OPT_nostdinc:
669 d_option.stdinc = false;
670 break;
671
672 case OPT_v:
673 global.params.verbose = value;
674 break;
675
676 case OPT_Wall:
677 if (value)
678 global.params.warnings = DIAGNOSTICinform;
679 break;
680
681 case OPT_Wdeprecated:
682 global.params.useDeprecated = value ? DIAGNOSTICinform : DIAGNOSTICoff;
683 break;
684
685 case OPT_Werror:
686 if (value)
687 global.params.warnings = DIAGNOSTICerror;
688 break;
689
690 case OPT_Wspeculative:
691 if (value)
692 global.params.showGaggedErrors = 1;
693 break;
694
695 case OPT_Xf:
696 global.params.jsonfilename = arg;
697 /* Fall through. */
698
699 case OPT_X:
700 global.params.doJsonGeneration = true;
701 break;
702
703 default:
704 break;
705 }
706
707 D_handle_option_auto (&global_options, &global_options_set,
708 scode, arg, value,
709 d_option_lang_mask (), kind,
710 loc, handlers, global_dc);
711
712 return result;
713 }
714
715 /* Implements the lang_hooks.post_options routine for language D.
716 Deal with any options that imply the turning on/off of features.
717 FN is the main input filename passed on the command line. */
718
719 static bool
720 d_post_options (const char ** fn)
721 {
722 /* Verify the input file name. */
723 const char *filename = *fn;
724 if (!filename || strcmp (filename, "-") == 0)
725 filename = "";
726
727 /* The front end considers the first input file to be the main one. */
728 *fn = filename;
729
730 /* Release mode doesn't turn off bounds checking for safe functions. */
731 if (global.params.useArrayBounds == CHECKENABLEdefault)
732 {
733 global.params.useArrayBounds = global.params.release
734 ? CHECKENABLEsafeonly : CHECKENABLEon;
735 }
736
737 /* Assert code is generated if unittests are being compiled also, even if
738 release mode is turned on. */
739 if (global.params.useAssert == CHECKENABLEdefault)
740 {
741 if (global.params.useUnitTests || !global.params.release)
742 global.params.useAssert = CHECKENABLEon;
743 else
744 global.params.useAssert = CHECKENABLEoff;
745 }
746
747 /* Checks for switches without a default are turned off in release mode. */
748 if (global.params.useSwitchError == CHECKENABLEdefault)
749 {
750 global.params.useSwitchError = global.params.release
751 ? CHECKENABLEoff : CHECKENABLEon;
752 }
753
754 /* Contracts are turned off in release mode. */
755 if (global.params.useInvariants == CHECKENABLEdefault)
756 {
757 global.params.useInvariants = global.params.release
758 ? CHECKENABLEoff : CHECKENABLEon;
759 }
760
761 if (global.params.useIn == CHECKENABLEdefault)
762 {
763 global.params.useIn = global.params.release
764 ? CHECKENABLEoff : CHECKENABLEon;
765 }
766
767 if (global.params.useOut == CHECKENABLEdefault)
768 {
769 global.params.useOut = global.params.release
770 ? CHECKENABLEoff : CHECKENABLEon;
771 }
772
773 if (global.params.betterC)
774 {
775 if (!global_options_set.x_flag_moduleinfo)
776 global.params.useModuleInfo = false;
777
778 if (!global_options_set.x_flag_rtti)
779 global.params.useTypeInfo = false;
780
781 if (!global_options_set.x_flag_exceptions)
782 global.params.useExceptions = false;
783
784 global.params.checkAction = CHECKACTION_C;
785 }
786
787 /* Keep in sync with existing -fbounds-check flag. */
788 flag_bounds_check = (global.params.useArrayBounds == CHECKENABLEon);
789
790 /* Turn off partitioning unless it was explicitly requested, as it doesn't
791 work with D exception chaining, where EH handler uses LSDA to determine
792 whether two thrown exception are in the same context. */
793 if (!global_options_set.x_flag_reorder_blocks_and_partition)
794 global_options.x_flag_reorder_blocks_and_partition = 0;
795
796 /* Error about use of deprecated features. */
797 if (global.params.useDeprecated == DIAGNOSTICinform
798 && global.params.warnings == DIAGNOSTICerror)
799 global.params.useDeprecated = DIAGNOSTICerror;
800
801 /* Make -fmax-errors visible to frontend's diagnostic machinery. */
802 if (global_options_set.x_flag_max_errors)
803 global.params.errorLimit = flag_max_errors;
804
805 if (flag_excess_precision == EXCESS_PRECISION_DEFAULT)
806 flag_excess_precision = EXCESS_PRECISION_STANDARD;
807
808 global.params.symdebug = write_symbols != NO_DEBUG;
809 global.params.useInline = flag_inline_functions;
810 global.params.showColumns = flag_show_column;
811
812 if (global.params.useInline)
813 global.params.hdrStripPlainFunctions = false;
814
815 global.params.obj = !flag_syntax_only;
816
817 /* Has no effect yet. */
818 global.params.pic = flag_pic != 0;
819
820 /* Add in versions given on the command line. */
821 if (global.params.versionids)
822 {
823 for (size_t i = 0; i < global.params.versionids->length; i++)
824 {
825 const char *s = (*global.params.versionids)[i];
826 VersionCondition::addGlobalIdent (s);
827 }
828 }
829
830 if (global.params.debugids)
831 {
832 for (size_t i = 0; i < global.params.debugids->length; i++)
833 {
834 const char *s = (*global.params.debugids)[i];
835 DebugCondition::addGlobalIdent (s);
836 }
837 }
838
839 if (warn_return_type == -1)
840 warn_return_type = 0;
841
842 return false;
843 }
844
845 /* Add the module M to the list of modules that may declare GCC builtins.
846 These are scanned after first semantic and before codegen passes.
847 See d_maybe_set_builtin() for the implementation. */
848
849 void
850 d_add_builtin_module (Module *m)
851 {
852 builtin_modules.push (m);
853 }
854
855 /* Record the entrypoint module ENTRY which will be compiled in the current
856 compilation. ROOT is the module scope where this was requested from. */
857
858 void
859 d_add_entrypoint_module (Module *entry, Module *root)
860 {
861 /* We are emitting this straight to object file. */
862 entrypoint_module = entry;
863 entrypoint_root_module = root;
864 }
865
866 /* Implements the lang_hooks.parse_file routine for language D. */
867
868 static void
869 d_parse_file (void)
870 {
871 if (global.params.verbose)
872 {
873 message ("binary %s", global.params.argv0.ptr);
874 message ("version %s", global.version.ptr);
875
876 if (global.versionids)
877 {
878 obstack buffer;
879 gcc_obstack_init (&buffer);
880 obstack_grow (&buffer, "predefs ", 9);
881 for (size_t i = 0; i < global.versionids->length; i++)
882 {
883 Identifier *id = (*global.versionids)[i];
884 const char *str = id->toChars ();
885 obstack_1grow (&buffer, ' ');
886 obstack_grow (&buffer, str, strlen (str));
887 }
888
889 message ("%s", (char *) obstack_finish (&buffer));
890 }
891 }
892
893 /* Start the main input file, if the debug writer wants it. */
894 if (debug_hooks->start_end_main_source_file)
895 debug_hooks->start_source_file (0, main_input_filename);
896
897 /* Create Module's for all sources we will load. */
898 Modules modules;
899 modules.reserve (num_in_fnames);
900
901 /* In this mode, the first file name is supposed to be a duplicate
902 of one of the input files. */
903 if (d_option.fonly && strcmp (d_option.fonly, main_input_filename) != 0)
904 error ("%<-fonly=%> argument is different from first input file name");
905
906 for (size_t i = 0; i < num_in_fnames; i++)
907 {
908 if (strcmp (in_fnames[i], "-") == 0)
909 {
910 /* Load the entire contents of stdin into memory. 8 kilobytes should
911 be a good enough initial size, but double on each iteration.
912 16 bytes are added for the final '\n' and 15 bytes of padding. */
913 ssize_t size = 8 * 1024;
914 uchar *buffer = XNEWVEC (uchar, size + 16);
915 ssize_t len = 0;
916 ssize_t count;
917
918 while ((count = read (STDIN_FILENO, buffer + len, size - len)) > 0)
919 {
920 len += count;
921 if (len == size)
922 {
923 size *= 2;
924 buffer = XRESIZEVEC (uchar, buffer, size + 16);
925 }
926 }
927
928 if (count < 0)
929 {
930 error (Loc ("stdin", 0, 0), "%s", xstrerror (errno));
931 free (buffer);
932 continue;
933 }
934
935 /* Handling stdin, generate a unique name for the module. */
936 Module *m = Module::create (in_fnames[i],
937 Identifier::generateId ("__stdin"),
938 global.params.doDocComments,
939 global.params.doHdrGeneration);
940 modules.push (m);
941
942 /* Overwrite the source file for the module, the one created by
943 Module::create would have a forced a `.d' suffix. */
944 m->srcfile = File::create ("<stdin>");
945 m->srcfile->len = len;
946 m->srcfile->buffer = buffer;
947 }
948 else
949 {
950 /* Handling a D source file, strip off the path and extension. */
951 const char *basename = FileName::name (in_fnames[i]);
952 const char *name = FileName::removeExt (basename);
953
954 Module *m = Module::create (in_fnames[i], Identifier::idPool (name),
955 global.params.doDocComments,
956 global.params.doHdrGeneration);
957 modules.push (m);
958 FileName::free (name);
959 }
960 }
961
962 /* Read all D source files. */
963 for (size_t i = 0; i < modules.length; i++)
964 {
965 Module *m = modules[i];
966 m->read (Loc ());
967 }
968
969 /* Parse all D source files. */
970 for (size_t i = 0; i < modules.length; i++)
971 {
972 Module *m = modules[i];
973
974 if (global.params.verbose)
975 message ("parse %s", m->toChars ());
976
977 if (!Module::rootModule)
978 Module::rootModule = m;
979
980 m->importedFrom = m;
981 m->parse ();
982 Compiler::loadModule (m);
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 m->semantic (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 m->semantic2 (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 m->semantic3 (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"