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