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