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