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