]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/d/d-lang.cc
d: Remove dependency on front-end File type for json and deps file generation.
[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;
0a98123c 1274 FILE *deps_stream;
b4c522fa 1275
2cbc99d1 1276 for (size_t i = 0; i < modules.length; i++)
b4c522fa
IB
1277 deps_write (modules[i], &buf);
1278
1279 /* -MF <arg> overrides -M[M]D. */
1280 if (d_option.deps_filename_user)
1281 d_option.deps_filename = d_option.deps_filename_user;
1282
1283 if (d_option.deps_filename)
1284 {
0a98123c
IB
1285 deps_stream = fopen (d_option.deps_filename, "w");
1286 if (!deps_stream)
1287 {
1288 fatal_error (input_location, "opening dependency file %s: %m",
1289 d_option.deps_filename);
1290 goto had_errors;
1291 }
b4c522fa
IB
1292 }
1293 else
0a98123c
IB
1294 deps_stream = stdout;
1295
1296 fprintf (deps_stream, "%s", buf.peekChars ());
1297
1298 if (deps_stream != stdout
1299 && (ferror (deps_stream) || fclose (deps_stream)))
1300 {
1301 fatal_error (input_location, "closing dependency file %s: %m",
1302 d_option.deps_filename);
1303 }
b4c522fa
IB
1304 }
1305
1306 /* Generate JSON files. */
1307 if (global.params.doJsonGeneration)
1308 {
1309 OutBuffer buf;
1310 json_generate (&buf, &modules);
1311
d8930b13 1312 const char *name = global.params.jsonfilename.ptr;
0a98123c 1313 FILE *json_stream;
b4c522fa
IB
1314
1315 if (name && (name[0] != '-' || name[1] != '\0'))
1316 {
d8930b13
IB
1317 const char *nameext
1318 = FileName::defaultExt (name, global.json_ext.ptr);
0a98123c
IB
1319 json_stream = fopen (nameext, "w");
1320 if (!json_stream)
1321 {
1322 fatal_error (input_location, "opening json file %s: %m", nameext);
1323 goto had_errors;
1324 }
b4c522fa
IB
1325 }
1326 else
0a98123c
IB
1327 json_stream = stdout;
1328
1329 fprintf (json_stream, "%s", buf.peekChars ());
1330
1331 if (json_stream != stdout
1332 && (ferror (json_stream) || fclose (json_stream)))
1333 fatal_error (input_location, "closing json file %s: %m", name);
b4c522fa
IB
1334 }
1335
1336 /* Generate Ddoc files. */
1337 if (global.params.doDocComments && !global.errors && !errorcount)
1338 {
2cbc99d1 1339 for (size_t i = 0; i < modules.length; i++)
b4c522fa
IB
1340 {
1341 Module *m = modules[i];
1342 gendocfile (m);
1343 }
1344 }
1345
1346 /* Handle -fdump-d-original. */
1347 if (global.params.vcg_ast)
1348 {
2cbc99d1 1349 for (size_t i = 0; i < modules.length; i++)
b4c522fa
IB
1350 {
1351 Module *m = modules[i];
1352 OutBuffer buf;
1353 buf.doindent = 1;
1354
1355 moduleToBuffer (&buf, m);
1356 message ("%.*s", (int) buf.offset, (char *) buf.data);
1357 }
1358 }
1359
2cbc99d1 1360 for (size_t i = 0; i < modules.length; i++)
b4c522fa
IB
1361 {
1362 Module *m = modules[i];
1363 if (d_option.fonly && m != Module::rootModule)
1364 continue;
1365
1366 if (global.params.verbose)
1367 message ("code %s", m->toChars ());
1368
1369 if (!flag_syntax_only)
1370 {
1371 if ((entrypoint_module != NULL) && (m == entrypoint_root_module))
1372 build_decl_tree (entrypoint_module);
1373
1374 build_decl_tree (m);
1375 }
1376 }
1377
1378 /* And end the main input file, if the debug writer wants it. */
1379 if (debug_hooks->start_end_main_source_file)
1380 debug_hooks->end_source_file (0);
1381
1382 had_errors:
1383 /* Add the D frontend error count to the GCC error count to correctly
1384 exit with an error status. */
1385 errorcount += (global.errors + global.warnings);
1386
1387 /* Write out globals. */
1388 d_finish_compilation (vec_safe_address (global_declarations),
1389 vec_safe_length (global_declarations));
1390}
1391
1392/* Implements the lang_hooks.types.type_for_mode routine for language D. */
1393
1394static tree
1395d_type_for_mode (machine_mode mode, int unsignedp)
1396{
1397 if (mode == QImode)
1398 return unsignedp ? d_ubyte_type : d_byte_type;
1399
1400 if (mode == HImode)
1401 return unsignedp ? d_ushort_type : d_short_type;
1402
1403 if (mode == SImode)
1404 return unsignedp ? d_uint_type : d_int_type;
1405
1406 if (mode == DImode)
1407 return unsignedp ? d_ulong_type : d_long_type;
1408
1409 if (mode == TYPE_MODE (d_cent_type))
1410 return unsignedp ? d_ucent_type : d_cent_type;
1411
1412 if (mode == TYPE_MODE (float_type_node))
1413 return float_type_node;
1414
1415 if (mode == TYPE_MODE (double_type_node))
1416 return double_type_node;
1417
1418 if (mode == TYPE_MODE (long_double_type_node))
1419 return long_double_type_node;
1420
1421 if (mode == TYPE_MODE (build_pointer_type (char8_type_node)))
1422 return build_pointer_type (char8_type_node);
1423
1424 if (mode == TYPE_MODE (build_pointer_type (d_int_type)))
1425 return build_pointer_type (d_int_type);
1426
edf09592
IB
1427 for (int i = 0; i < NUM_INT_N_ENTS; i ++)
1428 {
1429 if (int_n_enabled_p[i] && mode == int_n_data[i].m)
1430 {
1431 if (unsignedp)
1432 return int_n_trees[i].unsigned_type;
1433 else
1434 return int_n_trees[i].signed_type;
1435 }
1436 }
1437
b4c522fa
IB
1438 if (COMPLEX_MODE_P (mode))
1439 {
1440 machine_mode inner_mode;
1441 tree inner_type;
1442
1443 if (mode == TYPE_MODE (complex_float_type_node))
1444 return complex_float_type_node;
1445 if (mode == TYPE_MODE (complex_double_type_node))
1446 return complex_double_type_node;
1447 if (mode == TYPE_MODE (complex_long_double_type_node))
1448 return complex_long_double_type_node;
1449
1450 inner_mode = (machine_mode) GET_MODE_INNER (mode);
1451 inner_type = d_type_for_mode (inner_mode, unsignedp);
1452 if (inner_type != NULL_TREE)
1453 return build_complex_type (inner_type);
1454 }
1455 else if (VECTOR_MODE_P (mode))
1456 {
1457 machine_mode inner_mode = (machine_mode) GET_MODE_INNER (mode);
1458 tree inner_type = d_type_for_mode (inner_mode, unsignedp);
1459 if (inner_type != NULL_TREE)
1460 return build_vector_type_for_mode (inner_type, mode);
1461 }
1462
1463 return 0;
1464}
1465
1466/* Implements the lang_hooks.types.type_for_size routine for language D. */
1467
1468static tree
1469d_type_for_size (unsigned bits, int unsignedp)
1470{
1471 if (bits <= TYPE_PRECISION (d_byte_type))
1472 return unsignedp ? d_ubyte_type : d_byte_type;
1473
1474 if (bits <= TYPE_PRECISION (d_short_type))
1475 return unsignedp ? d_ushort_type : d_short_type;
1476
1477 if (bits <= TYPE_PRECISION (d_int_type))
1478 return unsignedp ? d_uint_type : d_int_type;
1479
1480 if (bits <= TYPE_PRECISION (d_long_type))
1481 return unsignedp ? d_ulong_type : d_long_type;
1482
1483 if (bits <= TYPE_PRECISION (d_cent_type))
1484 return unsignedp ? d_ucent_type : d_cent_type;
1485
edf09592
IB
1486 for (int i = 0; i < NUM_INT_N_ENTS; i ++)
1487 {
1488 if (int_n_enabled_p[i] && bits == int_n_data[i].bitsize)
1489 {
1490 if (unsignedp)
1491 return int_n_trees[i].unsigned_type;
1492 else
1493 return int_n_trees[i].signed_type;
1494 }
1495 }
1496
b4c522fa
IB
1497 return 0;
1498}
1499
1500/* Return the signed or unsigned version of TYPE, an integral type, the
1501 signedness being specified by UNSIGNEDP. */
1502
1503static tree
1504d_signed_or_unsigned_type (int unsignedp, tree type)
1505{
1506 if (TYPE_UNSIGNED (type) == (unsigned) unsignedp)
1507 return type;
1508
1509 if (TYPE_PRECISION (type) == TYPE_PRECISION (d_cent_type))
1510 return unsignedp ? d_ucent_type : d_cent_type;
1511
1512 if (TYPE_PRECISION (type) == TYPE_PRECISION (d_long_type))
1513 return unsignedp ? d_ulong_type : d_long_type;
1514
1515 if (TYPE_PRECISION (type) == TYPE_PRECISION (d_int_type))
1516 return unsignedp ? d_uint_type : d_int_type;
1517
1518 if (TYPE_PRECISION (type) == TYPE_PRECISION (d_short_type))
1519 return unsignedp ? d_ushort_type : d_short_type;
1520
1521 if (TYPE_PRECISION (type) == TYPE_PRECISION (d_byte_type))
1522 return unsignedp ? d_ubyte_type : d_byte_type;
1523
1524 return signed_or_unsigned_type_for (unsignedp, type);
1525}
1526
1527/* Return the unsigned version of TYPE, an integral type. */
1528
1529tree
1530d_unsigned_type (tree type)
1531{
1532 return d_signed_or_unsigned_type (1, type);
1533}
1534
1535/* Return the signed version of TYPE, an integral type. */
1536
1537tree
1538d_signed_type (tree type)
1539{
1540 return d_signed_or_unsigned_type (0, type);
1541}
1542
1543/* Implements the lang_hooks.types.type_promotes_to routine for language D.
1544 All promotions for variable arguments are handled by the D frontend. */
1545
1546static tree
1547d_type_promotes_to (tree type)
1548{
1549 return type;
1550}
1551
1552/* Implements the lang_hooks.decls.global_bindings_p routine for language D.
1553 Return true if we are in the global binding level. */
1554
1555static bool
1556d_global_bindings_p (void)
1557{
1558 return (current_binding_level == global_binding_level);
1559}
1560
1561/* Return global_context, but create it first if need be. */
1562
1563static tree
1564get_global_context (void)
1565{
1566 if (!global_context)
1567 {
1568 global_context = build_translation_unit_decl (NULL_TREE);
1569 debug_hooks->register_main_translation_unit (global_context);
1570 }
1571
1572 return global_context;
1573}
1574
1575/* Implements the lang_hooks.decls.pushdecl routine for language D.
1576 Record DECL as belonging to the current lexical scope. */
1577
1578tree
1579d_pushdecl (tree decl)
1580{
1581 /* Set the context of the decl. If current_function_decl did not help in
1582 determining the context, use global scope. */
1583 if (!DECL_CONTEXT (decl))
1584 {
1585 if (current_function_decl)
1586 DECL_CONTEXT (decl) = current_function_decl;
1587 else
1588 DECL_CONTEXT (decl) = get_global_context ();
1589 }
1590
1591 /* Put decls on list in reverse order. */
1592 if (TREE_STATIC (decl) || d_global_bindings_p ())
1593 vec_safe_push (global_declarations, decl);
1594 else
1595 {
1596 TREE_CHAIN (decl) = current_binding_level->names;
1597 current_binding_level->names = decl;
1598 }
1599
1600 return decl;
1601}
1602
1603/* Implements the lang_hooks.decls.getdecls routine for language D.
1604 Return the list of declarations of the current level. */
1605
1606static tree
1607d_getdecls (void)
1608{
1609 if (current_binding_level)
1610 return current_binding_level->names;
1611
1612 return NULL_TREE;
1613}
1614
1615
1616/* Implements the lang_hooks.get_alias_set routine for language D.
1617 Get the alias set corresponding to type or expression T.
1618 Return -1 if we don't do anything special. */
1619
1620static alias_set_type
1621d_get_alias_set (tree)
1622{
1623 /* For now in D, assume everything aliases everything else, until we define
1624 some solid rules backed by a specification. There are also some parts
1625 of code generation routines that don't adhere to C alias rules, such as
1626 build_vconvert. In any case, a lot of user code already assumes there
1627 is no strict aliasing and will break if we were to change that. */
1628 return 0;
1629}
1630
1631/* Implements the lang_hooks.types_compatible_p routine for language D.
1632 Compares two types for equivalence in the D programming language.
1633 This routine should only return 1 if it is sure, even though the frontend
1634 should have already ensured that all types are compatible before handing
1635 over the parsed ASTs to the code generator. */
1636
1637static int
1638d_types_compatible_p (tree x, tree y)
1639{
1640 Type *tx = TYPE_LANG_FRONTEND (x);
1641 Type *ty = TYPE_LANG_FRONTEND (y);
1642
1643 /* Try validating the types in the frontend. */
1644 if (tx != NULL && ty != NULL)
1645 {
1646 /* Types are equivalent. */
1647 if (same_type_p (tx, ty))
1648 return true;
1649
1650 /* Type system allows implicit conversion between. */
1651 if (tx->implicitConvTo (ty) || ty->implicitConvTo (tx))
1652 return true;
1653 }
1654
1655 /* Fallback on using type flags for comparison. E.g: all dynamic arrays
1656 are distinct types in D, but are VIEW_CONVERT compatible. */
1657 if (TREE_CODE (x) == RECORD_TYPE && TREE_CODE (y) == RECORD_TYPE)
1658 {
1659 if (TYPE_DYNAMIC_ARRAY (x) && TYPE_DYNAMIC_ARRAY (y))
1660 return true;
1661
1662 if (TYPE_DELEGATE (x) && TYPE_DELEGATE (y))
1663 return true;
1664
1665 if (TYPE_ASSOCIATIVE_ARRAY (x) && TYPE_ASSOCIATIVE_ARRAY (y))
1666 return true;
1667 }
1668
1669 return false;
1670}
1671
1672/* Implements the lang_hooks.finish_incomplete_decl routine for language D. */
1673
1674static void
1675d_finish_incomplete_decl (tree decl)
1676{
1677 if (VAR_P (decl))
1678 {
1679 /* D allows zero-length declarations. Such a declaration ends up with
1680 DECL_SIZE (t) == NULL_TREE which is what the back-end function
1681 assembler_variable checks. This could change in later versions, or
1682 maybe all of these variables should be aliased to one symbol. */
1683 if (DECL_SIZE (decl) == 0)
1684 {
1685 DECL_SIZE (decl) = bitsize_zero_node;
1686 DECL_SIZE_UNIT (decl) = size_zero_node;
1687 }
1688 }
1689}
1690
1691/* Implements the lang_hooks.types.classify_record routine for language D.
1692 Return the true debug type for TYPE. */
1693
1694static classify_record
1695d_classify_record (tree type)
1696{
1697 Type *t = TYPE_LANG_FRONTEND (type);
89fdaf5a 1698 TypeClass *tc = t ? t->isTypeClass () : NULL;
b4c522fa 1699
89fdaf5a 1700 if (tc != NULL)
b4c522fa 1701 {
b4c522fa
IB
1702 /* extern(C++) interfaces get emitted as classes. */
1703 if (tc->sym->isInterfaceDeclaration ()
1704 && !tc->sym->isCPPinterface ())
1705 return RECORD_IS_INTERFACE;
1706
1707 return RECORD_IS_CLASS;
1708 }
1709
1710 return RECORD_IS_STRUCT;
1711}
1712
1713/* Implements the lang_hooks.tree_size routine for language D.
1714 Determine the size of our tcc_constant or tcc_exceptional nodes. */
1715
1716static size_t
1717d_tree_size (tree_code code)
1718{
1719 switch (code)
1720 {
1721 case FUNCFRAME_INFO:
1722 return sizeof (tree_frame_info);
1723
1724 default:
1725 gcc_unreachable ();
1726 }
1727}
1728
1729/* Implements the lang_hooks.print_xnode routine for language D. */
1730
1731static void
1732d_print_xnode (FILE *file, tree node, int indent)
1733{
1734 switch (TREE_CODE (node))
1735 {
1736 case FUNCFRAME_INFO:
1737 print_node (file, "frame_type", FRAMEINFO_TYPE (node), indent + 4);
1738 break;
1739
1740 default:
1741 break;
1742 }
1743}
1744
1745/* Return which tree structure is used by NODE, or TS_D_GENERIC if NODE
1746 is one of the language-independent trees. */
1747
1748d_tree_node_structure_enum
1749d_tree_node_structure (lang_tree_node *t)
1750{
1751 switch (TREE_CODE (&t->generic))
1752 {
1753 case IDENTIFIER_NODE:
1754 return TS_D_IDENTIFIER;
1755
1756 case FUNCFRAME_INFO:
1757 return TS_D_FRAMEINFO;
1758
1759 default:
1760 return TS_D_GENERIC;
1761 }
1762}
1763
1764/* Allocate and return a lang specific structure for the frontend type. */
1765
1766struct lang_type *
1767build_lang_type (Type *t)
1768{
1769 struct lang_type *lt = ggc_cleared_alloc<struct lang_type> ();
1770 lt->type = t;
1771 return lt;
1772}
1773
1774/* Allocate and return a lang specific structure for the frontend decl. */
1775
1776struct lang_decl *
1777build_lang_decl (Declaration *d)
1778{
1779 /* For compiler generated run-time typeinfo, a lang_decl is allocated even if
1780 there's no associated frontend symbol to refer to (yet). If the symbol
1781 appears later in the compilation, then the slot will be re-used. */
1782 if (d == NULL)
1783 return ggc_cleared_alloc<struct lang_decl> ();
1784
1785 struct lang_decl *ld = (d->csym) ? DECL_LANG_SPECIFIC (d->csym) : NULL;
1786 if (ld == NULL)
1787 ld = ggc_cleared_alloc<struct lang_decl> ();
1788
1789 if (ld->decl == NULL)
1790 ld->decl = d;
1791
1792 return ld;
1793}
1794
1795/* Implements the lang_hooks.dup_lang_specific_decl routine for language D.
1796 Replace the DECL_LANG_SPECIFIC field of NODE with a copy. */
1797
1798static void
1799d_dup_lang_specific_decl (tree node)
1800{
1801 if (! DECL_LANG_SPECIFIC (node))
1802 return;
1803
1804 struct lang_decl *ld = ggc_alloc<struct lang_decl> ();
1805 memcpy (ld, DECL_LANG_SPECIFIC (node), sizeof (struct lang_decl));
1806 DECL_LANG_SPECIFIC (node) = ld;
1807}
1808
1809/* This preserves trees we create from the garbage collector. */
1810
1811static GTY(()) tree d_keep_list = NULL_TREE;
1812
1813void
1814d_keep (tree t)
1815{
1816 d_keep_list = tree_cons (NULL_TREE, t, d_keep_list);
1817}
1818
1819/* Implements the lang_hooks.eh_personality routine for language D.
1820 Return the GDC personality function decl. */
1821
1822static GTY(()) tree d_eh_personality_decl;
1823
1824static tree
1825d_eh_personality (void)
1826{
1827 if (!d_eh_personality_decl)
1828 d_eh_personality_decl = build_personality_function ("gdc");
1829
1830 return d_eh_personality_decl;
1831}
1832
1833/* Implements the lang_hooks.eh_runtime_type routine for language D. */
1834
1835static tree
1836d_build_eh_runtime_type (tree type)
1837{
1838 Type *t = TYPE_LANG_FRONTEND (type);
89fdaf5a
IB
1839 gcc_assert (t != NULL);
1840 t = t->toBasetype ();
b4c522fa 1841
89fdaf5a 1842 ClassDeclaration *cd = t->isTypeClass ()->sym;
b4c522fa
IB
1843 tree decl;
1844
1845 if (cd->isCPPclass ())
1846 decl = get_cpp_typeinfo_decl (cd);
1847 else
1848 decl = get_classinfo_decl (cd);
1849
1850 return convert (ptr_type_node, build_address (decl));
1851}
1852
1853/* Definitions for our language-specific hooks. */
1854
1855#undef LANG_HOOKS_NAME
1856#undef LANG_HOOKS_INIT
1857#undef LANG_HOOKS_INIT_TS
1858#undef LANG_HOOKS_INIT_OPTIONS
1859#undef LANG_HOOKS_INIT_OPTIONS_STRUCT
1860#undef LANG_HOOKS_OPTION_LANG_MASK
1861#undef LANG_HOOKS_HANDLE_OPTION
1862#undef LANG_HOOKS_POST_OPTIONS
1863#undef LANG_HOOKS_PARSE_FILE
1864#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
1865#undef LANG_HOOKS_ATTRIBUTE_TABLE
1866#undef LANG_HOOKS_GET_ALIAS_SET
1867#undef LANG_HOOKS_TYPES_COMPATIBLE_P
1868#undef LANG_HOOKS_BUILTIN_FUNCTION
1869#undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
1870#undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
1871#undef LANG_HOOKS_GIMPLIFY_EXPR
1872#undef LANG_HOOKS_CLASSIFY_RECORD
1873#undef LANG_HOOKS_TREE_SIZE
1874#undef LANG_HOOKS_PRINT_XNODE
1875#undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
1876#undef LANG_HOOKS_EH_PERSONALITY
1877#undef LANG_HOOKS_EH_RUNTIME_TYPE
1878#undef LANG_HOOKS_PUSHDECL
1879#undef LANG_HOOKS_GETDECLS
1880#undef LANG_HOOKS_GLOBAL_BINDINGS_P
1881#undef LANG_HOOKS_TYPE_FOR_MODE
1882#undef LANG_HOOKS_TYPE_FOR_SIZE
1883#undef LANG_HOOKS_TYPE_PROMOTES_TO
1884
1885#define LANG_HOOKS_NAME "GNU D"
1886#define LANG_HOOKS_INIT d_init
1887#define LANG_HOOKS_INIT_TS d_init_ts
1888#define LANG_HOOKS_INIT_OPTIONS d_init_options
1889#define LANG_HOOKS_INIT_OPTIONS_STRUCT d_init_options_struct
1890#define LANG_HOOKS_OPTION_LANG_MASK d_option_lang_mask
1891#define LANG_HOOKS_HANDLE_OPTION d_handle_option
1892#define LANG_HOOKS_POST_OPTIONS d_post_options
1893#define LANG_HOOKS_PARSE_FILE d_parse_file
1894#define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE d_langhook_common_attribute_table
1895#define LANG_HOOKS_ATTRIBUTE_TABLE d_langhook_attribute_table
1896#define LANG_HOOKS_GET_ALIAS_SET d_get_alias_set
1897#define LANG_HOOKS_TYPES_COMPATIBLE_P d_types_compatible_p
1898#define LANG_HOOKS_BUILTIN_FUNCTION d_builtin_function
1899#define LANG_HOOKS_REGISTER_BUILTIN_TYPE d_register_builtin_type
1900#define LANG_HOOKS_FINISH_INCOMPLETE_DECL d_finish_incomplete_decl
1901#define LANG_HOOKS_GIMPLIFY_EXPR d_gimplify_expr
1902#define LANG_HOOKS_CLASSIFY_RECORD d_classify_record
1903#define LANG_HOOKS_TREE_SIZE d_tree_size
1904#define LANG_HOOKS_PRINT_XNODE d_print_xnode
1905#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL d_dup_lang_specific_decl
1906#define LANG_HOOKS_EH_PERSONALITY d_eh_personality
1907#define LANG_HOOKS_EH_RUNTIME_TYPE d_build_eh_runtime_type
1908#define LANG_HOOKS_PUSHDECL d_pushdecl
1909#define LANG_HOOKS_GETDECLS d_getdecls
1910#define LANG_HOOKS_GLOBAL_BINDINGS_P d_global_bindings_p
1911#define LANG_HOOKS_TYPE_FOR_MODE d_type_for_mode
1912#define LANG_HOOKS_TYPE_FOR_SIZE d_type_for_size
1913#define LANG_HOOKS_TYPE_PROMOTES_TO d_type_promotes_to
1914
1915struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
1916
1917#include "gt-d-d-lang.h"
1918#include "gtype-d.h"