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