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