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