6412c1c204c44fddaa9c31120792b96b3c80a2cd
[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 "stringpool.h"
47 #include "stor-layout.h"
48 #include "varasm.h"
49 #include "output.h"
50 #include "print-tree.h"
51 #include "gimple-expr.h"
52 #include "gimplify.h"
53 #include "debug.h"
54
55 #include "d-tree.h"
56 #include "id.h"
57
58
59 /* Array of D frontend type/decl nodes. */
60 tree d_global_trees[DTI_MAX];
61
62 /* True if compilation is currently inside the D frontend semantic passes. */
63 bool doing_semantic_analysis_p = false;
64
65 /* Options handled by the compiler that are separate from the frontend. */
66 struct d_option_data
67 {
68 const char *fonly; /* -fonly=<arg> */
69 const char *multilib; /* -imultilib <dir> */
70 const char *prefix; /* -iprefix <dir> */
71
72 bool deps; /* -M */
73 bool deps_skip_system; /* -MM */
74 const char *deps_filename; /* -M[M]D */
75 const char *deps_filename_user; /* -MF <arg> */
76 vec <const char *> deps_target; /* -M[QT] <arg> */
77 bool deps_phony; /* -MP */
78
79 bool stdinc; /* -nostdinc */
80 }
81 d_option;
82
83 /* List of modules being compiled. */
84 static Modules builtin_modules;
85
86 /* Module where `C main' is defined, compiled in if needed. */
87 static Module *entrypoint_module = NULL;
88 static Module *entrypoint_root_module = NULL;
89
90 /* The current and global binding level in effect. */
91 struct binding_level *current_binding_level;
92 struct binding_level *global_binding_level;
93
94 /* The context to be used for global declarations. */
95 static GTY(()) tree global_context;
96
97 /* Array of all global declarations to pass back to the middle-end. */
98 static GTY(()) vec <tree, va_gc> *global_declarations;
99
100 /* Support for GCC-style command-line make dependency generation.
101 Adds TARGET to the make dependencies target buffer.
102 QUOTED is true if the string should be quoted. */
103
104 static void
105 deps_add_target (const char *target, bool quoted)
106 {
107 obstack buffer;
108 gcc_obstack_init (&buffer);
109
110 if (!quoted)
111 {
112 obstack_grow (&buffer, target, strlen (target));
113 d_option.deps_target.safe_push ((const char *) obstack_finish (&buffer));
114 return;
115 }
116
117 /* Quote characters in target which are significant to Make. */
118 for (const char *p = target; *p != '\0'; p++)
119 {
120 switch (*p)
121 {
122 case ' ':
123 case '\t':
124 for (const char *q = p - 1; target <= q && *q == '\\'; q--)
125 obstack_1grow (&buffer, '\\');
126 obstack_1grow (&buffer, '\\');
127 break;
128
129 case '$':
130 obstack_1grow (&buffer, '$');
131 break;
132
133 case '#':
134 obstack_1grow (&buffer, '\\');
135 break;
136
137 default:
138 break;
139 }
140
141 obstack_1grow (&buffer, *p);
142 }
143
144 d_option.deps_target.safe_push ((const char *) obstack_finish (&buffer));
145 }
146
147 /* Write STR, with a leading space to BUFFER, updating COLUMN as appropriate.
148 COLMAX is the number of columns to word-wrap at (0 means don't wrap). */
149
150 static void
151 deps_write_string (const char *str, obstack *buffer, unsigned &column,
152 unsigned colmax = 72)
153 {
154 unsigned size = strlen (str);
155
156 if (column != 0)
157 {
158 if (colmax && column + size > colmax)
159 {
160 obstack_grow (buffer, " \\\n ", 4);
161 column = 1;
162 }
163 else
164 {
165 obstack_1grow (buffer, ' ');
166 column++;
167 }
168 }
169
170 column += size;
171 obstack_grow (buffer, str, size);
172 }
173
174 /* Write out all dependencies of a given MODULE to the specified BUFFER. */
175
176 static void
177 deps_write (Module *module, obstack *buffer)
178 {
179 hash_set <const char *> seen_modules;
180 vec <const char *> dependencies = vNULL;
181
182 Modules modlist;
183 modlist.push (module);
184
185 vec <const char *> phonylist = vNULL;
186 unsigned column = 0;
187
188 /* Write out make target module name. */
189 if (d_option.deps_target.length ())
190 {
191 for (unsigned i = 0; i < d_option.deps_target.length (); i++)
192 deps_write_string (d_option.deps_target[i], buffer, column);
193 }
194 else
195 deps_write_string (module->objfile->name->str, buffer, column);
196
197 obstack_1grow (buffer, ':');
198 column++;
199
200 /* Search all modules for file dependencies. */
201 while (modlist.length > 0)
202 {
203 Module *depmod = modlist.pop ();
204
205 const char *modstr = depmod->srcfile->name->str;
206
207 /* Skip modules that have already been looked at. */
208 if (seen_modules.add (modstr))
209 continue;
210
211 dependencies.safe_push (modstr);
212
213 /* Add to list of phony targets if is not being compile. */
214 if (d_option.deps_phony && !depmod->isRoot ())
215 phonylist.safe_push (modstr);
216
217 /* Add imported files to dependency list. */
218 for (size_t i = 0; i < depmod->contentImportedFiles.length; i++)
219 {
220 const char *impstr = depmod->contentImportedFiles[i];
221 dependencies.safe_push (impstr);
222 phonylist.safe_push (impstr);
223 }
224
225 /* Search all imports of the module. */
226 for (size_t i = 0; i < depmod->aimports.length; i++)
227 {
228 Module *m = depmod->aimports[i];
229
230 /* Ignore compiler-generated modules. */
231 if ((m->ident == Identifier::idPool ("__entrypoint")
232 || m->ident == Identifier::idPool ("__main"))
233 && m->parent == NULL)
234 continue;
235
236 /* Don't search system installed modules, this includes
237 object, core.*, std.*, and gcc.* packages. */
238 if (d_option.deps_skip_system)
239 {
240 if (m->ident == Identifier::idPool ("object")
241 && m->parent == NULL)
242 continue;
243
244 if (m->md && m->md->packages)
245 {
246 Identifier *package = (*m->md->packages)[0];
247
248 if (package == Identifier::idPool ("core")
249 || package == Identifier::idPool ("std")
250 || package == Identifier::idPool ("gcc"))
251 continue;
252 }
253 }
254
255 modlist.push (m);
256 }
257 }
258
259 /* Write out all make dependencies. */
260 for (size_t i = 0; i < dependencies.length (); i++)
261 deps_write_string (dependencies[i], buffer, column);
262
263 obstack_1grow (buffer, '\n');
264
265 /* Write out all phony targets. */
266 for (size_t i = 0; i < phonylist.length (); i++)
267 {
268 const char *str = phonylist[i];
269 obstack_1grow (buffer, '\n');
270 obstack_grow (buffer, str, strlen (str));
271 obstack_grow (buffer, ":\n", 2);
272 }
273 }
274
275 /* Implements the lang_hooks.init_options routine for language D.
276 This initializes the global state for the D frontend before calling
277 the option handlers. */
278
279 static void
280 d_init_options (unsigned int, cl_decoded_option *decoded_options)
281 {
282 /* Set default values. */
283 global._init ();
284
285 global.vendor = lang_hooks.name;
286 global.params.argv0 = xstrdup (decoded_options[0].arg);
287 global.params.link = true;
288 global.params.useAssert = CHECKENABLEdefault;
289 global.params.useInvariants = CHECKENABLEdefault;
290 global.params.useIn = CHECKENABLEdefault;
291 global.params.useOut = CHECKENABLEdefault;
292 global.params.useArrayBounds = CHECKENABLEdefault;
293 global.params.useSwitchError = CHECKENABLEdefault;
294 global.params.checkAction = CHECKACTION_D;
295 global.params.useModuleInfo = true;
296 global.params.useTypeInfo = true;
297 global.params.useExceptions = true;
298 global.params.useInline = false;
299 global.params.obj = true;
300 global.params.hdrStripPlainFunctions = true;
301 global.params.betterC = false;
302 global.params.allInst = false;
303 global.params.errorLimit = flag_max_errors;
304
305 /* Default extern(C++) mangling to C++14. */
306 global.params.cplusplus = CppStdRevisionCpp14;
307
308 /* Warnings and deprecations are disabled by default. */
309 global.params.useDeprecated = DIAGNOSTICinform;
310 global.params.warnings = DIAGNOSTICoff;
311
312 global.params.imppath = new Strings ();
313 global.params.fileImppath = new Strings ();
314
315 /* Extra GDC-specific options. */
316 d_option.fonly = NULL;
317 d_option.multilib = NULL;
318 d_option.prefix = NULL;
319 d_option.deps = false;
320 d_option.deps_skip_system = false;
321 d_option.deps_filename = NULL;
322 d_option.deps_filename_user = NULL;
323 d_option.deps_target = vNULL;
324 d_option.deps_phony = false;
325 d_option.stdinc = true;
326 }
327
328 /* Implements the lang_hooks.init_options_struct routine for language D.
329 Initializes the options structure OPTS. */
330
331 static void
332 d_init_options_struct (gcc_options *opts)
333 {
334 /* GCC options. */
335 opts->x_flag_exceptions = 1;
336
337 /* Avoid range issues for complex multiply and divide. */
338 opts->x_flag_complex_method = 2;
339
340 /* Unlike C, there is no global `errno' variable. */
341 opts->x_flag_errno_math = 0;
342 opts->frontend_set_flag_errno_math = true;
343
344 /* D says that signed overflow is precisely defined. */
345 opts->x_flag_wrapv = 1;
346 }
347
348 /* Implements the lang_hooks.lang_mask routine for language D.
349 Returns language mask for option parsing. */
350
351 static unsigned int
352 d_option_lang_mask (void)
353 {
354 return CL_D;
355 }
356
357 /* Implements the lang_hooks.init routine for language D. */
358
359 static bool
360 d_init (void)
361 {
362 Type::_init ();
363 Id::initialize ();
364 Module::_init ();
365 Expression::_init ();
366 Objc::_init ();
367
368 /* Back-end init. */
369 global_binding_level = ggc_cleared_alloc <binding_level> ();
370 current_binding_level = global_binding_level;
371
372 /* This allows the code in d-builtins.cc to not have to worry about
373 converting (C signed char *) to (D char *) for string arguments of
374 built-in functions. The parameter (signed_char = false) specifies
375 whether char is signed. */
376 build_common_tree_nodes (false);
377
378 d_init_builtins ();
379
380 if (flag_exceptions)
381 using_eh_for_cleanups ();
382
383 if (!supports_one_only ())
384 flag_weak = 0;
385
386 /* This is the C main, not the D main. */
387 main_identifier_node = get_identifier ("main");
388
389 target._init (global.params);
390 d_init_versions ();
391
392 /* Insert all library-configured identifiers and import paths. */
393 add_import_paths (d_option.prefix, d_option.multilib, d_option.stdinc);
394
395 return 1;
396 }
397
398 /* Implements the lang_hooks.init_ts routine for language D. */
399
400 static void
401 d_init_ts (void)
402 {
403 MARK_TS_TYPED (FLOAT_MOD_EXPR);
404 MARK_TS_TYPED (UNSIGNED_RSHIFT_EXPR);
405 }
406
407 /* Implements the lang_hooks.handle_option routine for language D.
408 Handles D specific options. Return false if we didn't do anything. */
409
410 static bool
411 d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
412 int kind ATTRIBUTE_UNUSED,
413 location_t loc ATTRIBUTE_UNUSED,
414 const cl_option_handlers *handlers ATTRIBUTE_UNUSED)
415 {
416 opt_code code = (opt_code) scode;
417 bool result = true;
418
419 switch (code)
420 {
421 case OPT_fall_instantiations:
422 global.params.allInst = value;
423 break;
424
425 case OPT_fassert:
426 global.params.useAssert = value ? CHECKENABLEon : CHECKENABLEoff;
427 break;
428
429 case OPT_fbounds_check:
430 global.params.useArrayBounds = value ? CHECKENABLEon : CHECKENABLEoff;
431 break;
432
433 case OPT_fbounds_check_:
434 global.params.useArrayBounds = (value == 2) ? CHECKENABLEon
435 : (value == 1) ? CHECKENABLEsafeonly : CHECKENABLEoff;
436 break;
437
438 case OPT_fdebug:
439 global.params.debuglevel = value ? 1 : 0;
440 break;
441
442 case OPT_fdebug_:
443 if (ISDIGIT (arg[0]))
444 {
445 int level = integral_argument (arg);
446 if (level != -1)
447 {
448 global.params.debuglevel = level;
449 break;
450 }
451 }
452
453 if (Identifier::isValidIdentifier (CONST_CAST (char *, arg)))
454 {
455 if (!global.params.debugids)
456 global.params.debugids = new Strings ();
457 global.params.debugids->push (arg);
458 break;
459 }
460
461 error ("bad argument for %<-fdebug%>: %qs", arg);
462 break;
463
464 case OPT_fdoc:
465 global.params.doDocComments = value;
466 break;
467
468 case OPT_fdoc_dir_:
469 global.params.doDocComments = true;
470 global.params.docdir = arg;
471 break;
472
473 case OPT_fdoc_file_:
474 global.params.doDocComments = true;
475 global.params.docname = arg;
476 break;
477
478 case OPT_fdoc_inc_:
479 global.params.ddocfiles.push (arg);
480 break;
481
482 case OPT_fdruntime:
483 global.params.betterC = !value;
484 break;
485
486 case OPT_fdump_d_original:
487 global.params.vcg_ast = value;
488 break;
489
490 case OPT_fexceptions:
491 global.params.useExceptions = value;
492 break;
493
494 case OPT_fignore_unknown_pragmas:
495 global.params.ignoreUnsupportedPragmas = value;
496 break;
497
498 case OPT_finvariants:
499 global.params.useInvariants = value ? CHECKENABLEon : CHECKENABLEoff;
500 break;
501
502 case OPT_fmain:
503 global.params.addMain = value;
504 break;
505
506 case OPT_fmodule_file_:
507 global.params.modFileAliasStrings.push (arg);
508 if (!strchr (arg, '='))
509 error ("bad argument for %<-fmodule-file%>: %qs", arg);
510 break;
511
512 case OPT_fmoduleinfo:
513 global.params.useModuleInfo = value;
514 break;
515
516 case OPT_fonly_:
517 d_option.fonly = arg;
518 break;
519
520 case OPT_fpostconditions:
521 global.params.useOut = value ? CHECKENABLEon : CHECKENABLEoff;
522 break;
523
524 case OPT_fpreconditions:
525 global.params.useIn = value ? CHECKENABLEon : CHECKENABLEoff;
526 break;
527
528 case OPT_frelease:
529 global.params.release = value;
530 break;
531
532 case OPT_frtti:
533 global.params.useTypeInfo = value;
534 break;
535
536 case OPT_fswitch_errors:
537 global.params.useSwitchError = value ? CHECKENABLEon : CHECKENABLEoff;
538 break;
539
540 case OPT_ftransition_all:
541 global.params.vtls = value;
542 global.params.vfield = value;
543 global.params.vcomplex = value;
544 break;
545
546 case OPT_ftransition_checkimports:
547 global.params.check10378 = value;
548 break;
549
550 case OPT_ftransition_complex:
551 global.params.vcomplex = value;
552 break;
553
554 case OPT_ftransition_dip1000:
555 global.params.vsafe = value;
556 global.params.useDIP25 = value;
557 break;
558
559 case OPT_ftransition_dip25:
560 global.params.useDIP25 = value;
561 break;
562
563 case OPT_ftransition_field:
564 global.params.vfield = value;
565 break;
566
567 case OPT_ftransition_import:
568 global.params.bug10378 = 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 /* Return TRUE if an operand OP of a given TYPE being copied has no data.
847 The middle-end does a similar check with zero sized types. */
848
849 static bool
850 empty_modify_p (tree type, tree op)
851 {
852 tree_code code = TREE_CODE (op);
853 switch (code)
854 {
855 case COMPOUND_EXPR:
856 return empty_modify_p (type, TREE_OPERAND (op, 1));
857
858 case CONSTRUCTOR:
859 /* Non-empty construcors are valid. */
860 if (CONSTRUCTOR_NELTS (op) != 0 || TREE_CLOBBER_P (op))
861 return false;
862 break;
863
864 case CALL_EXPR:
865 /* Leave nrvo alone because it isn't a copy. */
866 if (CALL_EXPR_RETURN_SLOT_OPT (op))
867 return false;
868 break;
869
870 default:
871 /* If the operand doesn't have a simple form. */
872 if (!is_gimple_lvalue (op) && !INDIRECT_REF_P (op))
873 return false;
874 break;
875 }
876
877 return empty_aggregate_p (type);
878 }
879
880 /* Implements the lang_hooks.gimplify_expr routine for language D.
881 Do gimplification of D specific expression trees in EXPR_P. */
882
883 static int
884 d_gimplify_expr (tree *expr_p, gimple_seq *pre_p,
885 gimple_seq *post_p ATTRIBUTE_UNUSED)
886 {
887 tree_code code = TREE_CODE (*expr_p);
888 enum gimplify_status ret = GS_UNHANDLED;
889 tree op0, op1;
890 tree type;
891
892 switch (code)
893 {
894 case INIT_EXPR:
895 case MODIFY_EXPR:
896 op0 = TREE_OPERAND (*expr_p, 0);
897 op1 = TREE_OPERAND (*expr_p, 1);
898
899 if (!error_operand_p (op0) && !error_operand_p (op1)
900 && (AGGREGATE_TYPE_P (TREE_TYPE (op0))
901 || AGGREGATE_TYPE_P (TREE_TYPE (op1)))
902 && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
903 {
904 /* If the back end isn't clever enough to know that the lhs and rhs
905 types are the same, add an explicit conversion. */
906 TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
907 TREE_TYPE (op0), op1);
908 ret = GS_OK;
909 }
910 else if (empty_modify_p (TREE_TYPE (op0), op1))
911 {
912 /* Remove any copies of empty aggregates. */
913 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
914 is_gimple_lvalue, fb_lvalue);
915
916 if (TREE_SIDE_EFFECTS (op1))
917 gimplify_and_add (op1, pre_p);
918
919 *expr_p = TREE_OPERAND (*expr_p, 0);
920 ret = GS_OK;
921 }
922 break;
923
924 case ADDR_EXPR:
925 op0 = TREE_OPERAND (*expr_p, 0);
926 /* Constructors are not lvalues, so make them one. */
927 if (TREE_CODE (op0) == CONSTRUCTOR)
928 {
929 TREE_OPERAND (*expr_p, 0) = force_target_expr (op0);
930 ret = GS_OK;
931 }
932 break;
933
934 case CALL_EXPR:
935 if (CALL_EXPR_ARGS_ORDERED (*expr_p))
936 {
937 /* Strictly evaluate all arguments from left to right. */
938 int nargs = call_expr_nargs (*expr_p);
939 location_t loc = EXPR_LOC_OR_LOC (*expr_p, input_location);
940
941 /* No need to enforce evaluation order if only one argument. */
942 if (nargs < 2)
943 break;
944
945 /* Or if all arguments are already free of side-effects. */
946 bool has_side_effects = false;
947 for (int i = 0; i < nargs; i++)
948 {
949 if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, i)))
950 {
951 has_side_effects = true;
952 break;
953 }
954 }
955
956 if (!has_side_effects)
957 break;
958
959 /* Leave the last argument for gimplify_call_expr. */
960 for (int i = 0; i < nargs - 1; i++)
961 {
962 tree new_arg = CALL_EXPR_ARG (*expr_p, i);
963
964 /* If argument has a side-effect, gimplify_arg will handle it. */
965 if (gimplify_arg (&new_arg, pre_p, loc) == GS_ERROR)
966 ret = GS_ERROR;
967
968 /* Even if an argument itself doesn't have any side-effects, it
969 might be altered by another argument in the list. */
970 if (new_arg == CALL_EXPR_ARG (*expr_p, i)
971 && !really_constant_p (new_arg))
972 new_arg = get_formal_tmp_var (new_arg, pre_p);
973
974 CALL_EXPR_ARG (*expr_p, i) = new_arg;
975 }
976
977 if (ret != GS_ERROR)
978 ret = GS_OK;
979 }
980 break;
981
982 case UNSIGNED_RSHIFT_EXPR:
983 /* Convert op0 to an unsigned type. */
984 op0 = TREE_OPERAND (*expr_p, 0);
985 op1 = TREE_OPERAND (*expr_p, 1);
986
987 type = d_unsigned_type (TREE_TYPE (op0));
988
989 *expr_p = convert (TREE_TYPE (*expr_p),
990 build2 (RSHIFT_EXPR, type, convert (type, op0), op1));
991 ret = GS_OK;
992 break;
993
994 case FLOAT_MOD_EXPR:
995 gcc_unreachable ();
996
997 default:
998 break;
999 }
1000
1001 return ret;
1002 }
1003
1004 /* Add the module M to the list of modules that may declare GCC builtins.
1005 These are scanned after first semantic and before codegen passes.
1006 See d_maybe_set_builtin() for the implementation. */
1007
1008 void
1009 d_add_builtin_module (Module *m)
1010 {
1011 builtin_modules.push (m);
1012 }
1013
1014 /* Record the entrypoint module ENTRY which will be compiled in the current
1015 compilation. ROOT is the module scope where this was requested from. */
1016
1017 void
1018 d_add_entrypoint_module (Module *entry, Module *root)
1019 {
1020 /* We are emitting this straight to object file. */
1021 entrypoint_module = entry;
1022 entrypoint_root_module = root;
1023 }
1024
1025 /* Implements the lang_hooks.parse_file routine for language D. */
1026
1027 static void
1028 d_parse_file (void)
1029 {
1030 if (global.params.verbose)
1031 {
1032 message ("binary %s", global.params.argv0.ptr);
1033 message ("version %s", global.version.ptr);
1034
1035 if (global.versionids)
1036 {
1037 obstack buffer;
1038 gcc_obstack_init (&buffer);
1039 obstack_grow (&buffer, "predefs ", 9);
1040 for (size_t i = 0; i < global.versionids->length; i++)
1041 {
1042 Identifier *id = (*global.versionids)[i];
1043 const char *str = id->toChars ();
1044 obstack_1grow (&buffer, ' ');
1045 obstack_grow (&buffer, str, strlen (str));
1046 }
1047
1048 message ("%s", (char *) obstack_finish (&buffer));
1049 }
1050 }
1051
1052 /* Start the main input file, if the debug writer wants it. */
1053 if (debug_hooks->start_end_main_source_file)
1054 debug_hooks->start_source_file (0, main_input_filename);
1055
1056 /* Create Module's for all sources we will load. */
1057 Modules modules;
1058 modules.reserve (num_in_fnames);
1059
1060 /* In this mode, the first file name is supposed to be a duplicate
1061 of one of the input files. */
1062 if (d_option.fonly && strcmp (d_option.fonly, main_input_filename) != 0)
1063 error ("%<-fonly=%> argument is different from first input file name");
1064
1065 for (size_t i = 0; i < num_in_fnames; i++)
1066 {
1067 if (strcmp (in_fnames[i], "-") == 0)
1068 {
1069 /* Handling stdin, generate a unique name for the module. */
1070 obstack buffer;
1071 gcc_obstack_init (&buffer);
1072 int c;
1073
1074 Module *m = Module::create (in_fnames[i],
1075 Identifier::generateId ("__stdin"),
1076 global.params.doDocComments,
1077 global.params.doHdrGeneration);
1078 modules.push (m);
1079
1080 /* Load the entire contents of stdin into memory. */
1081 while ((c = getc (stdin)) != EOF)
1082 obstack_1grow (&buffer, c);
1083
1084 if (!obstack_object_size (&buffer))
1085 obstack_1grow (&buffer, '\0');
1086
1087 /* Overwrite the source file for the module, the one created by
1088 Module::create would have a forced a `.d' suffix. */
1089 m->srcfile = File::create ("<stdin>");
1090 m->srcfile->len = obstack_object_size (&buffer);
1091 m->srcfile->buffer = (unsigned char *) obstack_finish (&buffer);
1092
1093 /* Tell the front-end not to free the buffer after parsing. */
1094 m->srcfile->ref = 1;
1095 }
1096 else
1097 {
1098 /* Handling a D source file, strip off the path and extension. */
1099 const char *basename = FileName::name (in_fnames[i]);
1100 const char *name = FileName::removeExt (basename);
1101
1102 Module *m = Module::create (in_fnames[i], Identifier::idPool (name),
1103 global.params.doDocComments,
1104 global.params.doHdrGeneration);
1105 modules.push (m);
1106 FileName::free (name);
1107 }
1108 }
1109
1110 /* Read all D source files. */
1111 for (size_t i = 0; i < modules.length; i++)
1112 {
1113 Module *m = modules[i];
1114 m->read (Loc ());
1115 }
1116
1117 /* Parse all D source files. */
1118 for (size_t i = 0; i < modules.length; i++)
1119 {
1120 Module *m = modules[i];
1121
1122 if (global.params.verbose)
1123 message ("parse %s", m->toChars ());
1124
1125 if (!Module::rootModule)
1126 Module::rootModule = m;
1127
1128 m->importedFrom = m;
1129 m->parse ();
1130 Compiler::loadModule (m);
1131
1132 if (m->isDocFile)
1133 {
1134 gendocfile (m);
1135 /* Remove M from list of modules. */
1136 modules.remove (i);
1137 i--;
1138 }
1139 }
1140
1141 /* Load the module containing D main. */
1142 if (global.params.addMain)
1143 {
1144 unsigned errors = global.startGagging ();
1145 Module *m = Module::load (Loc (), NULL, Identifier::idPool ("__main"));
1146
1147 if (!global.endGagging (errors))
1148 {
1149 m->importedFrom = m;
1150 modules.push (m);
1151 }
1152 }
1153
1154 if (global.errors)
1155 goto had_errors;
1156
1157 if (global.params.doHdrGeneration)
1158 {
1159 /* Generate 'header' import files. Since 'header' import files must be
1160 independent of command line switches and what else is imported, they
1161 are generated before any semantic analysis. */
1162 for (size_t i = 0; i < modules.length; i++)
1163 {
1164 Module *m = modules[i];
1165 if (d_option.fonly && m != Module::rootModule)
1166 continue;
1167
1168 if (global.params.verbose)
1169 message ("import %s", m->toChars ());
1170
1171 genhdrfile (m);
1172 }
1173 }
1174
1175 if (global.errors)
1176 goto had_errors;
1177
1178 /* Load all unconditional imports for better symbol resolving. */
1179 for (size_t i = 0; i < modules.length; i++)
1180 {
1181 Module *m = modules[i];
1182
1183 if (global.params.verbose)
1184 message ("importall %s", m->toChars ());
1185
1186 m->importAll (NULL);
1187 }
1188
1189 if (global.errors)
1190 goto had_errors;
1191
1192 /* Do semantic analysis. */
1193 doing_semantic_analysis_p = true;
1194
1195 for (size_t i = 0; i < modules.length; i++)
1196 {
1197 Module *m = modules[i];
1198
1199 if (global.params.verbose)
1200 message ("semantic %s", m->toChars ());
1201
1202 m->semantic (NULL);
1203 }
1204
1205 /* Do deferred semantic analysis. */
1206 Module::dprogress = 1;
1207 Module::runDeferredSemantic ();
1208
1209 if (Module::deferred.length)
1210 {
1211 for (size_t i = 0; i < Module::deferred.length; i++)
1212 {
1213 Dsymbol *sd = Module::deferred[i];
1214 error_at (make_location_t (sd->loc),
1215 "unable to resolve forward reference in definition");
1216 }
1217 }
1218
1219 /* Process all built-in modules or functions now for CTFE. */
1220 while (builtin_modules.length != 0)
1221 {
1222 Module *m = builtin_modules.pop ();
1223 d_maybe_set_builtin (m);
1224 }
1225
1226 /* Do pass 2 semantic analysis. */
1227 for (size_t i = 0; i < modules.length; i++)
1228 {
1229 Module *m = modules[i];
1230
1231 if (global.params.verbose)
1232 message ("semantic2 %s", m->toChars ());
1233
1234 m->semantic2 (NULL);
1235 }
1236
1237 Module::runDeferredSemantic2 ();
1238
1239 if (global.errors)
1240 goto had_errors;
1241
1242 /* Do pass 3 semantic analysis. */
1243 for (size_t i = 0; i < modules.length; i++)
1244 {
1245 Module *m = modules[i];
1246
1247 if (global.params.verbose)
1248 message ("semantic3 %s", m->toChars ());
1249
1250 m->semantic3 (NULL);
1251 }
1252
1253 Module::runDeferredSemantic3 ();
1254
1255 /* Check again, incase semantic3 pass loaded any more modules. */
1256 while (builtin_modules.length != 0)
1257 {
1258 Module *m = builtin_modules.pop ();
1259 d_maybe_set_builtin (m);
1260 }
1261
1262 /* Do not attempt to generate output files if errors or warnings occurred. */
1263 if (global.errors || global.warnings)
1264 goto had_errors;
1265
1266 /* Generate output files. */
1267 doing_semantic_analysis_p = false;
1268
1269 if (Module::rootModule)
1270 {
1271 /* Declare the name of the root module as the first global name in order
1272 to make the middle-end fully deterministic. */
1273 OutBuffer buf;
1274 mangleToBuffer (Module::rootModule, &buf);
1275 first_global_object_name = buf.extractChars ();
1276 }
1277
1278 /* Make dependencies. */
1279 if (d_option.deps)
1280 {
1281 obstack buffer;
1282 FILE *deps_stream;
1283
1284 gcc_obstack_init (&buffer);
1285
1286 for (size_t i = 0; i < modules.length; i++)
1287 deps_write (modules[i], &buffer);
1288
1289 /* -MF <arg> overrides -M[M]D. */
1290 if (d_option.deps_filename_user)
1291 d_option.deps_filename = d_option.deps_filename_user;
1292
1293 if (d_option.deps_filename)
1294 {
1295 deps_stream = fopen (d_option.deps_filename, "w");
1296 if (!deps_stream)
1297 {
1298 fatal_error (input_location, "opening dependency file %s: %m",
1299 d_option.deps_filename);
1300 goto had_errors;
1301 }
1302 }
1303 else
1304 deps_stream = stdout;
1305
1306 fprintf (deps_stream, "%s", (char *) obstack_finish (&buffer));
1307
1308 if (deps_stream != stdout
1309 && (ferror (deps_stream) || fclose (deps_stream)))
1310 {
1311 fatal_error (input_location, "closing dependency file %s: %m",
1312 d_option.deps_filename);
1313 }
1314 }
1315
1316 /* Generate JSON files. */
1317 if (global.params.doJsonGeneration)
1318 {
1319 OutBuffer buf;
1320 json_generate (&buf, &modules);
1321
1322 const char *name = global.params.jsonfilename.ptr;
1323 FILE *json_stream;
1324
1325 if (name && (name[0] != '-' || name[1] != '\0'))
1326 {
1327 const char *nameext
1328 = FileName::defaultExt (name, global.json_ext.ptr);
1329 json_stream = fopen (nameext, "w");
1330 if (!json_stream)
1331 {
1332 fatal_error (input_location, "opening json file %s: %m", nameext);
1333 goto had_errors;
1334 }
1335 }
1336 else
1337 json_stream = stdout;
1338
1339 fprintf (json_stream, "%s", buf.peekChars ());
1340
1341 if (json_stream != stdout
1342 && (ferror (json_stream) || fclose (json_stream)))
1343 fatal_error (input_location, "closing json file %s: %m", name);
1344 }
1345
1346 /* Generate Ddoc files. */
1347 if (global.params.doDocComments && !global.errors && !errorcount)
1348 {
1349 for (size_t i = 0; i < modules.length; i++)
1350 {
1351 Module *m = modules[i];
1352 gendocfile (m);
1353 }
1354 }
1355
1356 /* Handle -fdump-d-original. */
1357 if (global.params.vcg_ast)
1358 {
1359 for (size_t i = 0; i < modules.length; i++)
1360 {
1361 Module *m = modules[i];
1362 OutBuffer buf;
1363 buf.doindent = 1;
1364
1365 moduleToBuffer (&buf, m);
1366 message ("%s", buf.peekChars ());
1367 }
1368 }
1369
1370 for (size_t i = 0; i < modules.length; i++)
1371 {
1372 Module *m = modules[i];
1373 if (d_option.fonly && m != Module::rootModule)
1374 continue;
1375
1376 if (global.params.verbose)
1377 message ("code %s", m->toChars ());
1378
1379 if (!flag_syntax_only)
1380 {
1381 if ((entrypoint_module != NULL) && (m == entrypoint_root_module))
1382 build_decl_tree (entrypoint_module);
1383
1384 build_decl_tree (m);
1385 }
1386 }
1387
1388 /* And end the main input file, if the debug writer wants it. */
1389 if (debug_hooks->start_end_main_source_file)
1390 debug_hooks->end_source_file (0);
1391
1392 had_errors:
1393 /* Add the D frontend error count to the GCC error count to correctly
1394 exit with an error status. */
1395 errorcount += (global.errors + global.warnings);
1396
1397 /* Write out globals. */
1398 d_finish_compilation (vec_safe_address (global_declarations),
1399 vec_safe_length (global_declarations));
1400 }
1401
1402 /* Implements the lang_hooks.types.type_for_mode routine for language D. */
1403
1404 static tree
1405 d_type_for_mode (machine_mode mode, int unsignedp)
1406 {
1407 if (mode == QImode)
1408 return unsignedp ? d_ubyte_type : d_byte_type;
1409
1410 if (mode == HImode)
1411 return unsignedp ? d_ushort_type : d_short_type;
1412
1413 if (mode == SImode)
1414 return unsignedp ? d_uint_type : d_int_type;
1415
1416 if (mode == DImode)
1417 return unsignedp ? d_ulong_type : d_long_type;
1418
1419 if (mode == TYPE_MODE (d_cent_type))
1420 return unsignedp ? d_ucent_type : d_cent_type;
1421
1422 if (mode == TYPE_MODE (float_type_node))
1423 return float_type_node;
1424
1425 if (mode == TYPE_MODE (double_type_node))
1426 return double_type_node;
1427
1428 if (mode == TYPE_MODE (long_double_type_node))
1429 return long_double_type_node;
1430
1431 if (mode == TYPE_MODE (build_pointer_type (char8_type_node)))
1432 return build_pointer_type (char8_type_node);
1433
1434 if (mode == TYPE_MODE (build_pointer_type (d_int_type)))
1435 return build_pointer_type (d_int_type);
1436
1437 for (int i = 0; i < NUM_INT_N_ENTS; i ++)
1438 {
1439 if (int_n_enabled_p[i] && mode == int_n_data[i].m)
1440 {
1441 if (unsignedp)
1442 return int_n_trees[i].unsigned_type;
1443 else
1444 return int_n_trees[i].signed_type;
1445 }
1446 }
1447
1448 if (COMPLEX_MODE_P (mode))
1449 {
1450 machine_mode inner_mode;
1451 tree inner_type;
1452
1453 if (mode == TYPE_MODE (complex_float_type_node))
1454 return complex_float_type_node;
1455 if (mode == TYPE_MODE (complex_double_type_node))
1456 return complex_double_type_node;
1457 if (mode == TYPE_MODE (complex_long_double_type_node))
1458 return complex_long_double_type_node;
1459
1460 inner_mode = (machine_mode) GET_MODE_INNER (mode);
1461 inner_type = d_type_for_mode (inner_mode, unsignedp);
1462 if (inner_type != NULL_TREE)
1463 return build_complex_type (inner_type);
1464 }
1465 else if (VECTOR_MODE_P (mode))
1466 {
1467 machine_mode inner_mode = (machine_mode) GET_MODE_INNER (mode);
1468 tree inner_type = d_type_for_mode (inner_mode, unsignedp);
1469 if (inner_type != NULL_TREE)
1470 return build_vector_type_for_mode (inner_type, mode);
1471 }
1472
1473 return 0;
1474 }
1475
1476 /* Implements the lang_hooks.types.type_for_size routine for language D. */
1477
1478 static tree
1479 d_type_for_size (unsigned bits, int unsignedp)
1480 {
1481 if (bits <= TYPE_PRECISION (d_byte_type))
1482 return unsignedp ? d_ubyte_type : d_byte_type;
1483
1484 if (bits <= TYPE_PRECISION (d_short_type))
1485 return unsignedp ? d_ushort_type : d_short_type;
1486
1487 if (bits <= TYPE_PRECISION (d_int_type))
1488 return unsignedp ? d_uint_type : d_int_type;
1489
1490 if (bits <= TYPE_PRECISION (d_long_type))
1491 return unsignedp ? d_ulong_type : d_long_type;
1492
1493 if (bits <= TYPE_PRECISION (d_cent_type))
1494 return unsignedp ? d_ucent_type : d_cent_type;
1495
1496 for (int i = 0; i < NUM_INT_N_ENTS; i ++)
1497 {
1498 if (int_n_enabled_p[i] && bits == int_n_data[i].bitsize)
1499 {
1500 if (unsignedp)
1501 return int_n_trees[i].unsigned_type;
1502 else
1503 return int_n_trees[i].signed_type;
1504 }
1505 }
1506
1507 return 0;
1508 }
1509
1510 /* Implements the lang_hooks.types.type_promotes_to routine for language D.
1511 All promotions for variable arguments are handled by the D frontend. */
1512
1513 static tree
1514 d_type_promotes_to (tree type)
1515 {
1516 return type;
1517 }
1518
1519 /* Implements the lang_hooks.decls.global_bindings_p routine for language D.
1520 Return true if we are in the global binding level. */
1521
1522 static bool
1523 d_global_bindings_p (void)
1524 {
1525 return (current_binding_level == global_binding_level);
1526 }
1527
1528 /* Return global_context, but create it first if need be. */
1529
1530 static tree
1531 get_global_context (void)
1532 {
1533 if (!global_context)
1534 {
1535 global_context = build_translation_unit_decl (NULL_TREE);
1536 debug_hooks->register_main_translation_unit (global_context);
1537 }
1538
1539 return global_context;
1540 }
1541
1542 /* Implements the lang_hooks.decls.pushdecl routine for language D.
1543 Record DECL as belonging to the current lexical scope. */
1544
1545 tree
1546 d_pushdecl (tree decl)
1547 {
1548 /* Set the context of the decl. If current_function_decl did not help in
1549 determining the context, use global scope. */
1550 if (!DECL_CONTEXT (decl))
1551 {
1552 if (current_function_decl)
1553 DECL_CONTEXT (decl) = current_function_decl;
1554 else
1555 DECL_CONTEXT (decl) = get_global_context ();
1556 }
1557
1558 /* Put decls on list in reverse order. */
1559 if (TREE_STATIC (decl) || d_global_bindings_p ())
1560 vec_safe_push (global_declarations, decl);
1561 else
1562 {
1563 TREE_CHAIN (decl) = current_binding_level->names;
1564 current_binding_level->names = decl;
1565 }
1566
1567 return decl;
1568 }
1569
1570 /* Implements the lang_hooks.decls.getdecls routine for language D.
1571 Return the list of declarations of the current level. */
1572
1573 static tree
1574 d_getdecls (void)
1575 {
1576 if (current_binding_level)
1577 return current_binding_level->names;
1578
1579 return NULL_TREE;
1580 }
1581
1582
1583 /* Implements the lang_hooks.get_alias_set routine for language D.
1584 Get the alias set corresponding to type or expression T.
1585 Return -1 if we don't do anything special. */
1586
1587 static alias_set_type
1588 d_get_alias_set (tree)
1589 {
1590 /* For now in D, assume everything aliases everything else, until we define
1591 some solid rules backed by a specification. There are also some parts
1592 of code generation routines that don't adhere to C alias rules, such as
1593 build_vconvert. In any case, a lot of user code already assumes there
1594 is no strict aliasing and will break if we were to change that. */
1595 return 0;
1596 }
1597
1598 /* Implements the lang_hooks.types_compatible_p routine for language D.
1599 Compares two types for equivalence in the D programming language.
1600 This routine should only return 1 if it is sure, even though the frontend
1601 should have already ensured that all types are compatible before handing
1602 over the parsed ASTs to the code generator. */
1603
1604 static int
1605 d_types_compatible_p (tree x, tree y)
1606 {
1607 Type *tx = TYPE_LANG_FRONTEND (x);
1608 Type *ty = TYPE_LANG_FRONTEND (y);
1609
1610 /* Try validating the types in the frontend. */
1611 if (tx != NULL && ty != NULL)
1612 {
1613 /* Types are equivalent. */
1614 if (same_type_p (tx, ty))
1615 return true;
1616
1617 /* Type system allows implicit conversion between. */
1618 if (tx->implicitConvTo (ty) || ty->implicitConvTo (tx))
1619 return true;
1620 }
1621
1622 /* Fallback on using type flags for comparison. E.g: all dynamic arrays
1623 are distinct types in D, but are VIEW_CONVERT compatible. */
1624 if (TREE_CODE (x) == RECORD_TYPE && TREE_CODE (y) == RECORD_TYPE)
1625 {
1626 if (TYPE_DYNAMIC_ARRAY (x) && TYPE_DYNAMIC_ARRAY (y))
1627 return true;
1628
1629 if (TYPE_DELEGATE (x) && TYPE_DELEGATE (y))
1630 return true;
1631
1632 if (TYPE_ASSOCIATIVE_ARRAY (x) && TYPE_ASSOCIATIVE_ARRAY (y))
1633 return true;
1634 }
1635
1636 return false;
1637 }
1638
1639 /* Implements the lang_hooks.finish_incomplete_decl routine for language D. */
1640
1641 static void
1642 d_finish_incomplete_decl (tree decl)
1643 {
1644 if (VAR_P (decl))
1645 {
1646 /* D allows zero-length declarations. Such a declaration ends up with
1647 DECL_SIZE (t) == NULL_TREE which is what the back-end function
1648 assembler_variable checks. This could change in later versions, or
1649 maybe all of these variables should be aliased to one symbol. */
1650 if (DECL_SIZE (decl) == 0)
1651 {
1652 DECL_SIZE (decl) = bitsize_zero_node;
1653 DECL_SIZE_UNIT (decl) = size_zero_node;
1654 }
1655 }
1656 }
1657
1658 /* Implements the lang_hooks.types.classify_record routine for language D.
1659 Return the true debug type for TYPE. */
1660
1661 static classify_record
1662 d_classify_record (tree type)
1663 {
1664 Type *t = TYPE_LANG_FRONTEND (type);
1665 TypeClass *tc = t ? t->isTypeClass () : NULL;
1666
1667 if (tc != NULL)
1668 {
1669 /* extern(C++) interfaces get emitted as classes. */
1670 if (tc->sym->isInterfaceDeclaration ()
1671 && !tc->sym->isCPPinterface ())
1672 return RECORD_IS_INTERFACE;
1673
1674 return RECORD_IS_CLASS;
1675 }
1676
1677 return RECORD_IS_STRUCT;
1678 }
1679
1680 /* Implements the lang_hooks.tree_size routine for language D.
1681 Determine the size of our tcc_constant or tcc_exceptional nodes. */
1682
1683 static size_t
1684 d_tree_size (tree_code code)
1685 {
1686 switch (code)
1687 {
1688 case FUNCFRAME_INFO:
1689 return sizeof (tree_frame_info);
1690
1691 default:
1692 gcc_unreachable ();
1693 }
1694 }
1695
1696 /* Implements the lang_hooks.print_xnode routine for language D. */
1697
1698 static void
1699 d_print_xnode (FILE *file, tree node, int indent)
1700 {
1701 switch (TREE_CODE (node))
1702 {
1703 case FUNCFRAME_INFO:
1704 print_node (file, "frame_type", FRAMEINFO_TYPE (node), indent + 4);
1705 break;
1706
1707 default:
1708 break;
1709 }
1710 }
1711
1712 /* Return which tree structure is used by NODE, or TS_D_GENERIC if NODE
1713 is one of the language-independent trees. */
1714
1715 d_tree_node_structure_enum
1716 d_tree_node_structure (lang_tree_node *t)
1717 {
1718 switch (TREE_CODE (&t->generic))
1719 {
1720 case IDENTIFIER_NODE:
1721 return TS_D_IDENTIFIER;
1722
1723 case FUNCFRAME_INFO:
1724 return TS_D_FRAMEINFO;
1725
1726 default:
1727 return TS_D_GENERIC;
1728 }
1729 }
1730
1731 /* Allocate and return a lang specific structure for the frontend type. */
1732
1733 struct lang_type *
1734 build_lang_type (Type *t)
1735 {
1736 struct lang_type *lt = ggc_cleared_alloc <struct lang_type> ();
1737 lt->type = t;
1738 return lt;
1739 }
1740
1741 /* Allocate and return a lang specific structure for the frontend decl. */
1742
1743 struct lang_decl *
1744 build_lang_decl (Declaration *d)
1745 {
1746 /* For compiler generated run-time typeinfo, a lang_decl is allocated even if
1747 there's no associated frontend symbol to refer to (yet). If the symbol
1748 appears later in the compilation, then the slot will be re-used. */
1749 if (d == NULL)
1750 return ggc_cleared_alloc <struct lang_decl> ();
1751
1752 struct lang_decl *ld = (d->csym) ? DECL_LANG_SPECIFIC (d->csym) : NULL;
1753 if (ld == NULL)
1754 ld = ggc_cleared_alloc <struct lang_decl> ();
1755
1756 if (ld->decl == NULL)
1757 ld->decl = d;
1758
1759 return ld;
1760 }
1761
1762 /* Implements the lang_hooks.dup_lang_specific_decl routine for language D.
1763 Replace the DECL_LANG_SPECIFIC field of NODE with a copy. */
1764
1765 static void
1766 d_dup_lang_specific_decl (tree node)
1767 {
1768 if (!DECL_LANG_SPECIFIC (node))
1769 return;
1770
1771 struct lang_decl *ld = ggc_alloc <struct lang_decl> ();
1772 memcpy (ld, DECL_LANG_SPECIFIC (node), sizeof (struct lang_decl));
1773 DECL_LANG_SPECIFIC (node) = ld;
1774 }
1775
1776 /* This preserves trees we create from the garbage collector. */
1777
1778 static GTY(()) tree d_keep_list = NULL_TREE;
1779
1780 void
1781 d_keep (tree t)
1782 {
1783 d_keep_list = tree_cons (NULL_TREE, t, d_keep_list);
1784 }
1785
1786 /* Implements the lang_hooks.eh_personality routine for language D.
1787 Return the GDC personality function decl. */
1788
1789 static GTY(()) tree d_eh_personality_decl;
1790
1791 static tree
1792 d_eh_personality (void)
1793 {
1794 if (!d_eh_personality_decl)
1795 d_eh_personality_decl = build_personality_function ("gdc");
1796
1797 return d_eh_personality_decl;
1798 }
1799
1800 /* Implements the lang_hooks.eh_runtime_type routine for language D. */
1801
1802 static tree
1803 d_build_eh_runtime_type (tree type)
1804 {
1805 Type *t = TYPE_LANG_FRONTEND (type);
1806 gcc_assert (t != NULL);
1807 t = t->toBasetype ();
1808
1809 ClassDeclaration *cd = t->isTypeClass ()->sym;
1810 tree decl;
1811
1812 if (cd->isCPPclass ())
1813 decl = get_cpp_typeinfo_decl (cd);
1814 else
1815 decl = get_classinfo_decl (cd);
1816
1817 return convert (ptr_type_node, build_address (decl));
1818 }
1819
1820 /* Definitions for our language-specific hooks. */
1821
1822 #undef LANG_HOOKS_NAME
1823 #undef LANG_HOOKS_INIT
1824 #undef LANG_HOOKS_INIT_TS
1825 #undef LANG_HOOKS_INIT_OPTIONS
1826 #undef LANG_HOOKS_INIT_OPTIONS_STRUCT
1827 #undef LANG_HOOKS_OPTION_LANG_MASK
1828 #undef LANG_HOOKS_HANDLE_OPTION
1829 #undef LANG_HOOKS_POST_OPTIONS
1830 #undef LANG_HOOKS_PARSE_FILE
1831 #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
1832 #undef LANG_HOOKS_ATTRIBUTE_TABLE
1833 #undef LANG_HOOKS_GET_ALIAS_SET
1834 #undef LANG_HOOKS_TYPES_COMPATIBLE_P
1835 #undef LANG_HOOKS_BUILTIN_FUNCTION
1836 #undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
1837 #undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
1838 #undef LANG_HOOKS_GIMPLIFY_EXPR
1839 #undef LANG_HOOKS_CLASSIFY_RECORD
1840 #undef LANG_HOOKS_TREE_SIZE
1841 #undef LANG_HOOKS_PRINT_XNODE
1842 #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
1843 #undef LANG_HOOKS_EH_PERSONALITY
1844 #undef LANG_HOOKS_EH_RUNTIME_TYPE
1845 #undef LANG_HOOKS_PUSHDECL
1846 #undef LANG_HOOKS_GETDECLS
1847 #undef LANG_HOOKS_GLOBAL_BINDINGS_P
1848 #undef LANG_HOOKS_TYPE_FOR_MODE
1849 #undef LANG_HOOKS_TYPE_FOR_SIZE
1850 #undef LANG_HOOKS_TYPE_PROMOTES_TO
1851
1852 #define LANG_HOOKS_NAME "GNU D"
1853 #define LANG_HOOKS_INIT d_init
1854 #define LANG_HOOKS_INIT_TS d_init_ts
1855 #define LANG_HOOKS_INIT_OPTIONS d_init_options
1856 #define LANG_HOOKS_INIT_OPTIONS_STRUCT d_init_options_struct
1857 #define LANG_HOOKS_OPTION_LANG_MASK d_option_lang_mask
1858 #define LANG_HOOKS_HANDLE_OPTION d_handle_option
1859 #define LANG_HOOKS_POST_OPTIONS d_post_options
1860 #define LANG_HOOKS_PARSE_FILE d_parse_file
1861 #define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE d_langhook_common_attribute_table
1862 #define LANG_HOOKS_ATTRIBUTE_TABLE d_langhook_attribute_table
1863 #define LANG_HOOKS_GET_ALIAS_SET d_get_alias_set
1864 #define LANG_HOOKS_TYPES_COMPATIBLE_P d_types_compatible_p
1865 #define LANG_HOOKS_BUILTIN_FUNCTION d_builtin_function
1866 #define LANG_HOOKS_REGISTER_BUILTIN_TYPE d_register_builtin_type
1867 #define LANG_HOOKS_FINISH_INCOMPLETE_DECL d_finish_incomplete_decl
1868 #define LANG_HOOKS_GIMPLIFY_EXPR d_gimplify_expr
1869 #define LANG_HOOKS_CLASSIFY_RECORD d_classify_record
1870 #define LANG_HOOKS_TREE_SIZE d_tree_size
1871 #define LANG_HOOKS_PRINT_XNODE d_print_xnode
1872 #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL d_dup_lang_specific_decl
1873 #define LANG_HOOKS_EH_PERSONALITY d_eh_personality
1874 #define LANG_HOOKS_EH_RUNTIME_TYPE d_build_eh_runtime_type
1875 #define LANG_HOOKS_PUSHDECL d_pushdecl
1876 #define LANG_HOOKS_GETDECLS d_getdecls
1877 #define LANG_HOOKS_GLOBAL_BINDINGS_P d_global_bindings_p
1878 #define LANG_HOOKS_TYPE_FOR_MODE d_type_for_mode
1879 #define LANG_HOOKS_TYPE_FOR_SIZE d_type_for_size
1880 #define LANG_HOOKS_TYPE_PROMOTES_TO d_type_promotes_to
1881
1882 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
1883
1884 #include "gt-d-d-lang.h"
1885 #include "gtype-d.h"