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
deps_add_target(const char * target,bool quoted)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
deps_write(Module * module,OutBuffer * buffer,unsigned colmax=72)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.dim > 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.dim; 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.dim; 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
d_init_options(unsigned int,cl_decoded_option * decoded_options)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
d_init_options_struct(gcc_options * opts)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
d_option_lang_mask(void)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
d_init(void)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
d_init_ts(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
d_handle_option(size_t scode,const char * arg,HOST_WIDE_INT value,int kind ATTRIBUTE_UNUSED,location_t loc ATTRIBUTE_UNUSED,const cl_option_handlers * handlers ATTRIBUTE_UNUSED)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
d_post_options(const char ** fn)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
empty_modify_p(tree type,tree op)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
d_gimplify_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p ATTRIBUTE_UNUSED)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
d_add_builtin_module(Module * m)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
d_add_entrypoint_module(Module * entry,Module * root)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
d_parse_file(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->dim; 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 /* Load the entire contents of stdin into memory. 8 kilobytes should
1030 be a good enough initial size, but double on each iteration.
1031 16 bytes are added for the final '\n' and 15 bytes of padding. */
1032 ssize_t size = 8 * 1024;
1033 uchar *buffer = XNEWVEC (uchar, size + 16);
1034 ssize_t len = 0;
1035 ssize_t count;
1036
1037 while ((count = read (STDIN_FILENO, buffer + len, size - len)) > 0)
1038 {
1039 len += count;
1040 if (len == size)
1041 {
1042 size *= 2;
1043 buffer = XRESIZEVEC (uchar, buffer, size + 16);
1044 }
1045 }
1046
1047 if (count < 0)
1048 {
1049 error (Loc ("stdin", 0, 0), "%s", xstrerror (errno));
1050 free (buffer);
1051 continue;
1052 }
1053
1054 /* Handling stdin, generate a unique name for the module. */
1055 Module *m = Module::create (in_fnames[i],
1056 Identifier::generateId ("__stdin"),
1057 global.params.doDocComments,
1058 global.params.doHdrGeneration);
1059 modules.push (m);
1060
1061 /* Overwrite the source file for the module, the one created by
1062 Module::create would have a forced a `.d' suffix. */
1063 m->srcfile = File::create ("<stdin>");
1064 m->srcfile->len = len;
1065 m->srcfile->buffer = buffer;
1066 }
1067 else
1068 {
1069 /* Handling a D source file, strip off the path and extension. */
1070 const char *basename = FileName::name (in_fnames[i]);
1071 const char *name = FileName::removeExt (basename);
1072
1073 Module *m = Module::create (in_fnames[i], Identifier::idPool (name),
1074 global.params.doDocComments,
1075 global.params.doHdrGeneration);
1076 modules.push (m);
1077 FileName::free (name);
1078 }
1079 }
1080
1081 /* Read all D source files. */
1082 for (size_t i = 0; i < modules.dim; i++)
1083 {
1084 Module *m = modules[i];
1085 m->read (Loc ());
1086 }
1087
1088 /* Parse all D source files. */
1089 for (size_t i = 0; i < modules.dim; i++)
1090 {
1091 Module *m = modules[i];
1092
1093 if (global.params.verbose)
1094 message ("parse %s", m->toChars ());
1095
1096 if (!Module::rootModule)
1097 Module::rootModule = m;
1098
1099 m->importedFrom = m;
1100 m->parse ();
1101 Compiler::loadModule (m);
1102
1103 if (m->isDocFile)
1104 {
1105 gendocfile (m);
1106 /* Remove M from list of modules. */
1107 modules.remove (i);
1108 i--;
1109 }
1110 }
1111
1112 /* Load the module containing D main. */
1113 if (global.params.addMain)
1114 {
1115 unsigned errors = global.startGagging ();
1116 Module *m = Module::load (Loc (), NULL, Identifier::idPool ("__main"));
1117
1118 if (! global.endGagging (errors))
1119 {
1120 m->importedFrom = m;
1121 modules.push (m);
1122 }
1123 }
1124
1125 if (global.errors)
1126 goto had_errors;
1127
1128 if (global.params.doHdrGeneration)
1129 {
1130 /* Generate 'header' import files. Since 'header' import files must be
1131 independent of command line switches and what else is imported, they
1132 are generated before any semantic analysis. */
1133 for (size_t i = 0; i < modules.dim; i++)
1134 {
1135 Module *m = modules[i];
1136 if (d_option.fonly && m != Module::rootModule)
1137 continue;
1138
1139 if (global.params.verbose)
1140 message ("import %s", m->toChars ());
1141
1142 genhdrfile (m);
1143 }
1144 }
1145
1146 if (global.errors)
1147 goto had_errors;
1148
1149 /* Load all unconditional imports for better symbol resolving. */
1150 for (size_t i = 0; i < modules.dim; i++)
1151 {
1152 Module *m = modules[i];
1153
1154 if (global.params.verbose)
1155 message ("importall %s", m->toChars ());
1156
1157 m->importAll (NULL);
1158 }
1159
1160 if (global.errors)
1161 goto had_errors;
1162
1163 /* Do semantic analysis. */
1164 doing_semantic_analysis_p = true;
1165
1166 for (size_t i = 0; i < modules.dim; i++)
1167 {
1168 Module *m = modules[i];
1169
1170 if (global.params.verbose)
1171 message ("semantic %s", m->toChars ());
1172
1173 m->semantic (NULL);
1174 }
1175
1176 /* Do deferred semantic analysis. */
1177 Module::dprogress = 1;
1178 Module::runDeferredSemantic ();
1179
1180 if (Module::deferred.dim)
1181 {
1182 for (size_t i = 0; i < Module::deferred.dim; i++)
1183 {
1184 Dsymbol *sd = Module::deferred[i];
1185 error_at (make_location_t (sd->loc),
1186 "unable to resolve forward reference in definition");
1187 }
1188 }
1189
1190 /* Process all built-in modules or functions now for CTFE. */
1191 while (builtin_modules.dim != 0)
1192 {
1193 Module *m = builtin_modules.pop ();
1194 d_maybe_set_builtin (m);
1195 }
1196
1197 /* Do pass 2 semantic analysis. */
1198 for (size_t i = 0; i < modules.dim; i++)
1199 {
1200 Module *m = modules[i];
1201
1202 if (global.params.verbose)
1203 message ("semantic2 %s", m->toChars ());
1204
1205 m->semantic2 (NULL);
1206 }
1207
1208 Module::runDeferredSemantic2 ();
1209
1210 if (global.errors)
1211 goto had_errors;
1212
1213 /* Do pass 3 semantic analysis. */
1214 for (size_t i = 0; i < modules.dim; i++)
1215 {
1216 Module *m = modules[i];
1217
1218 if (global.params.verbose)
1219 message ("semantic3 %s", m->toChars ());
1220
1221 m->semantic3 (NULL);
1222 }
1223
1224 Module::runDeferredSemantic3 ();
1225
1226 /* Check again, incase semantic3 pass loaded any more modules. */
1227 while (builtin_modules.dim != 0)
1228 {
1229 Module *m = builtin_modules.pop ();
1230 d_maybe_set_builtin (m);
1231 }
1232
1233 /* Do not attempt to generate output files if errors or warnings occurred. */
1234 if (global.errors || global.warnings)
1235 goto had_errors;
1236
1237 /* Generate output files. */
1238 doing_semantic_analysis_p = false;
1239
1240 if (Module::rootModule)
1241 {
1242 /* Declare the name of the root module as the first global name in order
1243 to make the middle-end fully deterministic. */
1244 OutBuffer buf;
1245 mangleToBuffer (Module::rootModule, &buf);
1246 first_global_object_name = buf.extractString ();
1247 }
1248
1249 /* Make dependencies. */
1250 if (d_option.deps)
1251 {
1252 OutBuffer buf;
1253
1254 for (size_t i = 0; i < modules.dim; i++)
1255 deps_write (modules[i], &buf);
1256
1257 /* -MF <arg> overrides -M[M]D. */
1258 if (d_option.deps_filename_user)
1259 d_option.deps_filename = d_option.deps_filename_user;
1260
1261 if (d_option.deps_filename)
1262 {
1263 File *fdeps = File::create (d_option.deps_filename);
1264 fdeps->setbuffer ((void *) buf.data, buf.offset);
1265 fdeps->ref = 1;
1266 writeFile (Loc (), fdeps);
1267 }
1268 else
1269 message ("%.*s", (int) buf.offset, (char *) buf.data);
1270 }
1271
1272 /* Generate JSON files. */
1273 if (global.params.doJsonGeneration)
1274 {
1275 OutBuffer buf;
1276 json_generate (&buf, &modules);
1277
1278 const char *name = global.params.jsonfilename;
1279
1280 if (name && (name[0] != '-' || name[1] != '\0'))
1281 {
1282 const char *nameext = FileName::defaultExt (name, global.json_ext);
1283 File *fjson = File::create (nameext);
1284 fjson->setbuffer ((void *) buf.data, buf.offset);
1285 fjson->ref = 1;
1286 writeFile (Loc (), fjson);
1287 }
1288 else
1289 message ("%.*s", (int) buf.offset, (char *) buf.data);
1290 }
1291
1292 /* Generate Ddoc files. */
1293 if (global.params.doDocComments && !global.errors && !errorcount)
1294 {
1295 for (size_t i = 0; i < modules.dim; i++)
1296 {
1297 Module *m = modules[i];
1298 gendocfile (m);
1299 }
1300 }
1301
1302 /* Handle -fdump-d-original. */
1303 if (global.params.vcg_ast)
1304 {
1305 for (size_t i = 0; i < modules.dim; i++)
1306 {
1307 Module *m = modules[i];
1308 OutBuffer buf;
1309 buf.doindent = 1;
1310
1311 moduleToBuffer (&buf, m);
1312 message ("%.*s", (int) buf.offset, (char *) buf.data);
1313 }
1314 }
1315
1316 for (size_t i = 0; i < modules.dim; i++)
1317 {
1318 Module *m = modules[i];
1319 if (d_option.fonly && m != Module::rootModule)
1320 continue;
1321
1322 if (global.params.verbose)
1323 message ("code %s", m->toChars ());
1324
1325 if (!flag_syntax_only)
1326 {
1327 if ((entrypoint_module != NULL) && (m == entrypoint_root_module))
1328 build_decl_tree (entrypoint_module);
1329
1330 build_decl_tree (m);
1331 }
1332 }
1333
1334 /* And end the main input file, if the debug writer wants it. */
1335 if (debug_hooks->start_end_main_source_file)
1336 debug_hooks->end_source_file (0);
1337
1338 had_errors:
1339 /* Add the D frontend error count to the GCC error count to correctly
1340 exit with an error status. */
1341 errorcount += (global.errors + global.warnings);
1342
1343 /* Write out globals. */
1344 d_finish_compilation (vec_safe_address (global_declarations),
1345 vec_safe_length (global_declarations));
1346 }
1347
1348 /* Implements the lang_hooks.types.type_for_mode routine for language D. */
1349
1350 static tree
d_type_for_mode(machine_mode mode,int unsignedp)1351 d_type_for_mode (machine_mode mode, int unsignedp)
1352 {
1353 if (mode == QImode)
1354 return unsignedp ? d_ubyte_type : d_byte_type;
1355
1356 if (mode == HImode)
1357 return unsignedp ? d_ushort_type : d_short_type;
1358
1359 if (mode == SImode)
1360 return unsignedp ? d_uint_type : d_int_type;
1361
1362 if (mode == DImode)
1363 return unsignedp ? d_ulong_type : d_long_type;
1364
1365 if (mode == TYPE_MODE (d_cent_type))
1366 return unsignedp ? d_ucent_type : d_cent_type;
1367
1368 if (mode == TYPE_MODE (float_type_node))
1369 return float_type_node;
1370
1371 if (mode == TYPE_MODE (double_type_node))
1372 return double_type_node;
1373
1374 if (mode == TYPE_MODE (long_double_type_node))
1375 return long_double_type_node;
1376
1377 if (mode == TYPE_MODE (build_pointer_type (char8_type_node)))
1378 return build_pointer_type (char8_type_node);
1379
1380 if (mode == TYPE_MODE (build_pointer_type (d_int_type)))
1381 return build_pointer_type (d_int_type);
1382
1383 for (int i = 0; i < NUM_INT_N_ENTS; i ++)
1384 {
1385 if (int_n_enabled_p[i] && mode == int_n_data[i].m)
1386 {
1387 if (unsignedp)
1388 return int_n_trees[i].unsigned_type;
1389 else
1390 return int_n_trees[i].signed_type;
1391 }
1392 }
1393
1394 if (COMPLEX_MODE_P (mode))
1395 {
1396 machine_mode inner_mode;
1397 tree inner_type;
1398
1399 if (mode == TYPE_MODE (complex_float_type_node))
1400 return complex_float_type_node;
1401 if (mode == TYPE_MODE (complex_double_type_node))
1402 return complex_double_type_node;
1403 if (mode == TYPE_MODE (complex_long_double_type_node))
1404 return complex_long_double_type_node;
1405
1406 inner_mode = (machine_mode) GET_MODE_INNER (mode);
1407 inner_type = d_type_for_mode (inner_mode, unsignedp);
1408 if (inner_type != NULL_TREE)
1409 return build_complex_type (inner_type);
1410 }
1411 else if (VECTOR_MODE_P (mode))
1412 {
1413 machine_mode inner_mode = (machine_mode) GET_MODE_INNER (mode);
1414 tree inner_type = d_type_for_mode (inner_mode, unsignedp);
1415 if (inner_type != NULL_TREE)
1416 return build_vector_type_for_mode (inner_type, mode);
1417 }
1418
1419 return 0;
1420 }
1421
1422 /* Implements the lang_hooks.types.type_for_size routine for language D. */
1423
1424 static tree
d_type_for_size(unsigned bits,int unsignedp)1425 d_type_for_size (unsigned bits, int unsignedp)
1426 {
1427 if (bits <= TYPE_PRECISION (d_byte_type))
1428 return unsignedp ? d_ubyte_type : d_byte_type;
1429
1430 if (bits <= TYPE_PRECISION (d_short_type))
1431 return unsignedp ? d_ushort_type : d_short_type;
1432
1433 if (bits <= TYPE_PRECISION (d_int_type))
1434 return unsignedp ? d_uint_type : d_int_type;
1435
1436 if (bits <= TYPE_PRECISION (d_long_type))
1437 return unsignedp ? d_ulong_type : d_long_type;
1438
1439 if (bits <= TYPE_PRECISION (d_cent_type))
1440 return unsignedp ? d_ucent_type : d_cent_type;
1441
1442 for (int i = 0; i < NUM_INT_N_ENTS; i ++)
1443 {
1444 if (int_n_enabled_p[i] && bits == int_n_data[i].bitsize)
1445 {
1446 if (unsignedp)
1447 return int_n_trees[i].unsigned_type;
1448 else
1449 return int_n_trees[i].signed_type;
1450 }
1451 }
1452
1453 return 0;
1454 }
1455
1456 /* Return the signed or unsigned version of TYPE, an integral type, the
1457 signedness being specified by UNSIGNEDP. */
1458
1459 static tree
d_signed_or_unsigned_type(int unsignedp,tree type)1460 d_signed_or_unsigned_type (int unsignedp, tree type)
1461 {
1462 if (TYPE_UNSIGNED (type) == (unsigned) unsignedp)
1463 return type;
1464
1465 if (TYPE_PRECISION (type) == TYPE_PRECISION (d_cent_type))
1466 return unsignedp ? d_ucent_type : d_cent_type;
1467
1468 if (TYPE_PRECISION (type) == TYPE_PRECISION (d_long_type))
1469 return unsignedp ? d_ulong_type : d_long_type;
1470
1471 if (TYPE_PRECISION (type) == TYPE_PRECISION (d_int_type))
1472 return unsignedp ? d_uint_type : d_int_type;
1473
1474 if (TYPE_PRECISION (type) == TYPE_PRECISION (d_short_type))
1475 return unsignedp ? d_ushort_type : d_short_type;
1476
1477 if (TYPE_PRECISION (type) == TYPE_PRECISION (d_byte_type))
1478 return unsignedp ? d_ubyte_type : d_byte_type;
1479
1480 return signed_or_unsigned_type_for (unsignedp, type);
1481 }
1482
1483 /* Return the unsigned version of TYPE, an integral type. */
1484
1485 tree
d_unsigned_type(tree type)1486 d_unsigned_type (tree type)
1487 {
1488 return d_signed_or_unsigned_type (1, type);
1489 }
1490
1491 /* Return the signed version of TYPE, an integral type. */
1492
1493 tree
d_signed_type(tree type)1494 d_signed_type (tree type)
1495 {
1496 return d_signed_or_unsigned_type (0, type);
1497 }
1498
1499 /* Implements the lang_hooks.types.type_promotes_to routine for language D.
1500 All promotions for variable arguments are handled by the D frontend. */
1501
1502 static tree
d_type_promotes_to(tree type)1503 d_type_promotes_to (tree type)
1504 {
1505 return type;
1506 }
1507
1508 /* Implements the lang_hooks.decls.global_bindings_p routine for language D.
1509 Return true if we are in the global binding level. */
1510
1511 static bool
d_global_bindings_p(void)1512 d_global_bindings_p (void)
1513 {
1514 return (current_binding_level == global_binding_level);
1515 }
1516
1517 /* Return global_context, but create it first if need be. */
1518
1519 static tree
get_global_context(void)1520 get_global_context (void)
1521 {
1522 if (!global_context)
1523 {
1524 global_context = build_translation_unit_decl (NULL_TREE);
1525 debug_hooks->register_main_translation_unit (global_context);
1526 }
1527
1528 return global_context;
1529 }
1530
1531 /* Implements the lang_hooks.decls.pushdecl routine for language D.
1532 Record DECL as belonging to the current lexical scope. */
1533
1534 tree
d_pushdecl(tree decl)1535 d_pushdecl (tree decl)
1536 {
1537 /* Set the context of the decl. If current_function_decl did not help in
1538 determining the context, use global scope. */
1539 if (!DECL_CONTEXT (decl))
1540 {
1541 if (current_function_decl)
1542 DECL_CONTEXT (decl) = current_function_decl;
1543 else
1544 DECL_CONTEXT (decl) = get_global_context ();
1545 }
1546
1547 /* Put decls on list in reverse order. */
1548 if (TREE_STATIC (decl) || d_global_bindings_p ())
1549 vec_safe_push (global_declarations, decl);
1550 else
1551 {
1552 TREE_CHAIN (decl) = current_binding_level->names;
1553 current_binding_level->names = decl;
1554 }
1555
1556 return decl;
1557 }
1558
1559 /* Implements the lang_hooks.decls.getdecls routine for language D.
1560 Return the list of declarations of the current level. */
1561
1562 static tree
d_getdecls(void)1563 d_getdecls (void)
1564 {
1565 if (current_binding_level)
1566 return current_binding_level->names;
1567
1568 return NULL_TREE;
1569 }
1570
1571
1572 /* Implements the lang_hooks.get_alias_set routine for language D.
1573 Get the alias set corresponding to type or expression T.
1574 Return -1 if we don't do anything special. */
1575
1576 static alias_set_type
d_get_alias_set(tree)1577 d_get_alias_set (tree)
1578 {
1579 /* For now in D, assume everything aliases everything else, until we define
1580 some solid rules backed by a specification. There are also some parts
1581 of code generation routines that don't adhere to C alias rules, such as
1582 build_vconvert. In any case, a lot of user code already assumes there
1583 is no strict aliasing and will break if we were to change that. */
1584 return 0;
1585 }
1586
1587 /* Implements the lang_hooks.types_compatible_p routine for language D.
1588 Compares two types for equivalence in the D programming language.
1589 This routine should only return 1 if it is sure, even though the frontend
1590 should have already ensured that all types are compatible before handing
1591 over the parsed ASTs to the code generator. */
1592
1593 static int
d_types_compatible_p(tree x,tree y)1594 d_types_compatible_p (tree x, tree y)
1595 {
1596 Type *tx = TYPE_LANG_FRONTEND (x);
1597 Type *ty = TYPE_LANG_FRONTEND (y);
1598
1599 /* Try validating the types in the frontend. */
1600 if (tx != NULL && ty != NULL)
1601 {
1602 /* Types are equivalent. */
1603 if (same_type_p (tx, ty))
1604 return true;
1605
1606 /* Type system allows implicit conversion between. */
1607 if (tx->implicitConvTo (ty) || ty->implicitConvTo (tx))
1608 return true;
1609 }
1610
1611 /* Fallback on using type flags for comparison. E.g: all dynamic arrays
1612 are distinct types in D, but are VIEW_CONVERT compatible. */
1613 if (TREE_CODE (x) == RECORD_TYPE && TREE_CODE (y) == RECORD_TYPE)
1614 {
1615 if (TYPE_DYNAMIC_ARRAY (x) && TYPE_DYNAMIC_ARRAY (y))
1616 return true;
1617
1618 if (TYPE_DELEGATE (x) && TYPE_DELEGATE (y))
1619 return true;
1620
1621 if (TYPE_ASSOCIATIVE_ARRAY (x) && TYPE_ASSOCIATIVE_ARRAY (y))
1622 return true;
1623 }
1624
1625 return false;
1626 }
1627
1628 /* Implements the lang_hooks.finish_incomplete_decl routine for language D. */
1629
1630 static void
d_finish_incomplete_decl(tree decl)1631 d_finish_incomplete_decl (tree decl)
1632 {
1633 if (VAR_P (decl))
1634 {
1635 /* D allows zero-length declarations. Such a declaration ends up with
1636 DECL_SIZE (t) == NULL_TREE which is what the back-end function
1637 assembler_variable checks. This could change in later versions, or
1638 maybe all of these variables should be aliased to one symbol. */
1639 if (DECL_SIZE (decl) == 0)
1640 {
1641 DECL_SIZE (decl) = bitsize_zero_node;
1642 DECL_SIZE_UNIT (decl) = size_zero_node;
1643 }
1644 }
1645 }
1646
1647 /* Implements the lang_hooks.types.classify_record routine for language D.
1648 Return the true debug type for TYPE. */
1649
1650 static classify_record
d_classify_record(tree type)1651 d_classify_record (tree type)
1652 {
1653 Type *t = TYPE_LANG_FRONTEND (type);
1654
1655 if (t && t->ty == Tclass)
1656 {
1657 TypeClass *tc = (TypeClass *) t;
1658
1659 /* extern(C++) interfaces get emitted as classes. */
1660 if (tc->sym->isInterfaceDeclaration ()
1661 && !tc->sym->isCPPinterface ())
1662 return RECORD_IS_INTERFACE;
1663
1664 return RECORD_IS_CLASS;
1665 }
1666
1667 return RECORD_IS_STRUCT;
1668 }
1669
1670 /* Implements the lang_hooks.tree_size routine for language D.
1671 Determine the size of our tcc_constant or tcc_exceptional nodes. */
1672
1673 static size_t
d_tree_size(tree_code code)1674 d_tree_size (tree_code code)
1675 {
1676 switch (code)
1677 {
1678 case FUNCFRAME_INFO:
1679 return sizeof (tree_frame_info);
1680
1681 default:
1682 gcc_unreachable ();
1683 }
1684 }
1685
1686 /* Implements the lang_hooks.print_xnode routine for language D. */
1687
1688 static void
d_print_xnode(FILE * file,tree node,int indent)1689 d_print_xnode (FILE *file, tree node, int indent)
1690 {
1691 switch (TREE_CODE (node))
1692 {
1693 case FUNCFRAME_INFO:
1694 print_node (file, "frame_type", FRAMEINFO_TYPE (node), indent + 4);
1695 break;
1696
1697 default:
1698 break;
1699 }
1700 }
1701
1702 /* Return which tree structure is used by NODE, or TS_D_GENERIC if NODE
1703 is one of the language-independent trees. */
1704
1705 d_tree_node_structure_enum
d_tree_node_structure(lang_tree_node * t)1706 d_tree_node_structure (lang_tree_node *t)
1707 {
1708 switch (TREE_CODE (&t->generic))
1709 {
1710 case IDENTIFIER_NODE:
1711 return TS_D_IDENTIFIER;
1712
1713 case FUNCFRAME_INFO:
1714 return TS_D_FRAMEINFO;
1715
1716 default:
1717 return TS_D_GENERIC;
1718 }
1719 }
1720
1721 /* Allocate and return a lang specific structure for the frontend type. */
1722
1723 struct lang_type *
build_lang_type(Type * t)1724 build_lang_type (Type *t)
1725 {
1726 struct lang_type *lt = ggc_cleared_alloc<struct lang_type> ();
1727 lt->type = t;
1728 return lt;
1729 }
1730
1731 /* Allocate and return a lang specific structure for the frontend decl. */
1732
1733 struct lang_decl *
build_lang_decl(Declaration * d)1734 build_lang_decl (Declaration *d)
1735 {
1736 /* For compiler generated run-time typeinfo, a lang_decl is allocated even if
1737 there's no associated frontend symbol to refer to (yet). If the symbol
1738 appears later in the compilation, then the slot will be re-used. */
1739 if (d == NULL)
1740 return ggc_cleared_alloc<struct lang_decl> ();
1741
1742 struct lang_decl *ld = (d->csym) ? DECL_LANG_SPECIFIC (d->csym) : NULL;
1743 if (ld == NULL)
1744 ld = ggc_cleared_alloc<struct lang_decl> ();
1745
1746 if (ld->decl == NULL)
1747 ld->decl = d;
1748
1749 return ld;
1750 }
1751
1752 /* Implements the lang_hooks.dup_lang_specific_decl routine for language D.
1753 Replace the DECL_LANG_SPECIFIC field of NODE with a copy. */
1754
1755 static void
d_dup_lang_specific_decl(tree node)1756 d_dup_lang_specific_decl (tree node)
1757 {
1758 if (! DECL_LANG_SPECIFIC (node))
1759 return;
1760
1761 struct lang_decl *ld = ggc_alloc<struct lang_decl> ();
1762 memcpy (ld, DECL_LANG_SPECIFIC (node), sizeof (struct lang_decl));
1763 DECL_LANG_SPECIFIC (node) = ld;
1764 }
1765
1766 /* This preserves trees we create from the garbage collector. */
1767
1768 static GTY(()) tree d_keep_list = NULL_TREE;
1769
1770 void
d_keep(tree t)1771 d_keep (tree t)
1772 {
1773 d_keep_list = tree_cons (NULL_TREE, t, d_keep_list);
1774 }
1775
1776 /* Implements the lang_hooks.eh_personality routine for language D.
1777 Return the GDC personality function decl. */
1778
1779 static GTY(()) tree d_eh_personality_decl;
1780
1781 static tree
d_eh_personality(void)1782 d_eh_personality (void)
1783 {
1784 if (!d_eh_personality_decl)
1785 d_eh_personality_decl = build_personality_function ("gdc");
1786
1787 return d_eh_personality_decl;
1788 }
1789
1790 /* Implements the lang_hooks.eh_runtime_type routine for language D. */
1791
1792 static tree
d_build_eh_runtime_type(tree type)1793 d_build_eh_runtime_type (tree type)
1794 {
1795 Type *t = TYPE_LANG_FRONTEND (type);
1796
1797 if (t != NULL)
1798 t = t->toBasetype ();
1799
1800 gcc_assert (t != NULL && t->ty == Tclass);
1801 ClassDeclaration *cd = ((TypeClass *) t)->sym;
1802 tree decl;
1803
1804 if (cd->isCPPclass ())
1805 decl = get_cpp_typeinfo_decl (cd);
1806 else
1807 decl = get_classinfo_decl (cd);
1808
1809 return convert (ptr_type_node, build_address (decl));
1810 }
1811
1812 /* Definitions for our language-specific hooks. */
1813
1814 #undef LANG_HOOKS_NAME
1815 #undef LANG_HOOKS_INIT
1816 #undef LANG_HOOKS_INIT_TS
1817 #undef LANG_HOOKS_INIT_OPTIONS
1818 #undef LANG_HOOKS_INIT_OPTIONS_STRUCT
1819 #undef LANG_HOOKS_OPTION_LANG_MASK
1820 #undef LANG_HOOKS_HANDLE_OPTION
1821 #undef LANG_HOOKS_POST_OPTIONS
1822 #undef LANG_HOOKS_PARSE_FILE
1823 #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
1824 #undef LANG_HOOKS_ATTRIBUTE_TABLE
1825 #undef LANG_HOOKS_GET_ALIAS_SET
1826 #undef LANG_HOOKS_TYPES_COMPATIBLE_P
1827 #undef LANG_HOOKS_BUILTIN_FUNCTION
1828 #undef LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE
1829 #undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
1830 #undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
1831 #undef LANG_HOOKS_GIMPLIFY_EXPR
1832 #undef LANG_HOOKS_CLASSIFY_RECORD
1833 #undef LANG_HOOKS_TREE_SIZE
1834 #undef LANG_HOOKS_PRINT_XNODE
1835 #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
1836 #undef LANG_HOOKS_EH_PERSONALITY
1837 #undef LANG_HOOKS_EH_RUNTIME_TYPE
1838 #undef LANG_HOOKS_PUSHDECL
1839 #undef LANG_HOOKS_GETDECLS
1840 #undef LANG_HOOKS_GLOBAL_BINDINGS_P
1841 #undef LANG_HOOKS_TYPE_FOR_MODE
1842 #undef LANG_HOOKS_TYPE_FOR_SIZE
1843 #undef LANG_HOOKS_TYPE_PROMOTES_TO
1844
1845 #define LANG_HOOKS_NAME "GNU D"
1846 #define LANG_HOOKS_INIT d_init
1847 #define LANG_HOOKS_INIT_TS d_init_ts
1848 #define LANG_HOOKS_INIT_OPTIONS d_init_options
1849 #define LANG_HOOKS_INIT_OPTIONS_STRUCT d_init_options_struct
1850 #define LANG_HOOKS_OPTION_LANG_MASK d_option_lang_mask
1851 #define LANG_HOOKS_HANDLE_OPTION d_handle_option
1852 #define LANG_HOOKS_POST_OPTIONS d_post_options
1853 #define LANG_HOOKS_PARSE_FILE d_parse_file
1854 #define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE d_langhook_common_attribute_table
1855 #define LANG_HOOKS_ATTRIBUTE_TABLE d_langhook_attribute_table
1856 #define LANG_HOOKS_GET_ALIAS_SET d_get_alias_set
1857 #define LANG_HOOKS_TYPES_COMPATIBLE_P d_types_compatible_p
1858 #define LANG_HOOKS_BUILTIN_FUNCTION d_builtin_function
1859 #define LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE d_builtin_function_ext_scope
1860 #define LANG_HOOKS_REGISTER_BUILTIN_TYPE d_register_builtin_type
1861 #define LANG_HOOKS_FINISH_INCOMPLETE_DECL d_finish_incomplete_decl
1862 #define LANG_HOOKS_GIMPLIFY_EXPR d_gimplify_expr
1863 #define LANG_HOOKS_CLASSIFY_RECORD d_classify_record
1864 #define LANG_HOOKS_TREE_SIZE d_tree_size
1865 #define LANG_HOOKS_PRINT_XNODE d_print_xnode
1866 #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL d_dup_lang_specific_decl
1867 #define LANG_HOOKS_EH_PERSONALITY d_eh_personality
1868 #define LANG_HOOKS_EH_RUNTIME_TYPE d_build_eh_runtime_type
1869 #define LANG_HOOKS_PUSHDECL d_pushdecl
1870 #define LANG_HOOKS_GETDECLS d_getdecls
1871 #define LANG_HOOKS_GLOBAL_BINDINGS_P d_global_bindings_p
1872 #define LANG_HOOKS_TYPE_FOR_MODE d_type_for_mode
1873 #define LANG_HOOKS_TYPE_FOR_SIZE d_type_for_size
1874 #define LANG_HOOKS_TYPE_PROMOTES_TO d_type_promotes_to
1875
1876 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
1877
1878 #include "gt-d-d-lang.h"
1879 #include "gtype-d.h"
1880