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