]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/d/d-lang.cc
d: Change in DotTemplateExp type semantics leading to regression (PR101619)
[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
1003 if (global.errors)
1004 goto had_errors;
1005
1006 if (global.params.doHdrGeneration)
1007 {
1008 /* Generate 'header' import files. Since 'header' import files must be
1009 independent of command line switches and what else is imported, they
1010 are generated before any semantic analysis. */
2cbc99d1 1011 for (size_t i = 0; i < modules.length; i++)
b4c522fa
IB
1012 {
1013 Module *m = modules[i];
1014 if (d_option.fonly && m != Module::rootModule)
1015 continue;
1016
1017 if (global.params.verbose)
1018 message ("import %s", m->toChars ());
1019
1020 genhdrfile (m);
1021 }
1022 }
1023
1024 if (global.errors)
1025 goto had_errors;
1026
1027 /* Load all unconditional imports for better symbol resolving. */
2cbc99d1 1028 for (size_t i = 0; i < modules.length; i++)
b4c522fa
IB
1029 {
1030 Module *m = modules[i];
1031
1032 if (global.params.verbose)
1033 message ("importall %s", m->toChars ());
1034
1035 m->importAll (NULL);
1036 }
1037
1038 if (global.errors)
1039 goto had_errors;
1040
1041 /* Do semantic analysis. */
1042 doing_semantic_analysis_p = true;
1043
2cbc99d1 1044 for (size_t i = 0; i < modules.length; i++)
b4c522fa
IB
1045 {
1046 Module *m = modules[i];
1047
1048 if (global.params.verbose)
1049 message ("semantic %s", m->toChars ());
1050
a3b38b77 1051 dsymbolSemantic (m, NULL);
b4c522fa
IB
1052 }
1053
1054 /* Do deferred semantic analysis. */
1055 Module::dprogress = 1;
1056 Module::runDeferredSemantic ();
1057
2cbc99d1 1058 if (Module::deferred.length)
b4c522fa 1059 {
2cbc99d1 1060 for (size_t i = 0; i < Module::deferred.length; i++)
b4c522fa
IB
1061 {
1062 Dsymbol *sd = Module::deferred[i];
1063 error_at (make_location_t (sd->loc),
1064 "unable to resolve forward reference in definition");
1065 }
1066 }
1067
1068 /* Process all built-in modules or functions now for CTFE. */
2cbc99d1 1069 while (builtin_modules.length != 0)
b4c522fa
IB
1070 {
1071 Module *m = builtin_modules.pop ();
1072 d_maybe_set_builtin (m);
1073 }
1074
1075 /* Do pass 2 semantic analysis. */
2cbc99d1 1076 for (size_t i = 0; i < modules.length; i++)
b4c522fa
IB
1077 {
1078 Module *m = modules[i];
1079
1080 if (global.params.verbose)
1081 message ("semantic2 %s", m->toChars ());
1082
a3b38b77 1083 semantic2 (m, NULL);
b4c522fa
IB
1084 }
1085
1086 Module::runDeferredSemantic2 ();
1087
1088 if (global.errors)
1089 goto had_errors;
1090
1091 /* Do pass 3 semantic analysis. */
2cbc99d1 1092 for (size_t i = 0; i < modules.length; i++)
b4c522fa
IB
1093 {
1094 Module *m = modules[i];
1095
1096 if (global.params.verbose)
1097 message ("semantic3 %s", m->toChars ());
1098
a3b38b77 1099 semantic3 (m, NULL);
b4c522fa
IB
1100 }
1101
1102 Module::runDeferredSemantic3 ();
1103
1104 /* Check again, incase semantic3 pass loaded any more modules. */
2cbc99d1 1105 while (builtin_modules.length != 0)
b4c522fa
IB
1106 {
1107 Module *m = builtin_modules.pop ();
1108 d_maybe_set_builtin (m);
1109 }
1110
1111 /* Do not attempt to generate output files if errors or warnings occurred. */
1112 if (global.errors || global.warnings)
1113 goto had_errors;
1114
1115 /* Generate output files. */
1116 doing_semantic_analysis_p = false;
1117
1118 if (Module::rootModule)
1119 {
1120 /* Declare the name of the root module as the first global name in order
1121 to make the middle-end fully deterministic. */
1122 OutBuffer buf;
1123 mangleToBuffer (Module::rootModule, &buf);
fced594b 1124 first_global_object_name = buf.extractChars ();
b4c522fa
IB
1125 }
1126
1127 /* Make dependencies. */
1128 if (d_option.deps)
1129 {
a23b6d61 1130 obstack buffer;
0a98123c 1131 FILE *deps_stream;
b4c522fa 1132
a23b6d61
IB
1133 gcc_obstack_init (&buffer);
1134
2cbc99d1 1135 for (size_t i = 0; i < modules.length; i++)
a23b6d61 1136 deps_write (modules[i], &buffer);
b4c522fa
IB
1137
1138 /* -MF <arg> overrides -M[M]D. */
1139 if (d_option.deps_filename_user)
1140 d_option.deps_filename = d_option.deps_filename_user;
1141
1142 if (d_option.deps_filename)
1143 {
0a98123c
IB
1144 deps_stream = fopen (d_option.deps_filename, "w");
1145 if (!deps_stream)
1146 {
1147 fatal_error (input_location, "opening dependency file %s: %m",
1148 d_option.deps_filename);
1149 goto had_errors;
1150 }
b4c522fa
IB
1151 }
1152 else
0a98123c
IB
1153 deps_stream = stdout;
1154
a23b6d61 1155 fprintf (deps_stream, "%s", (char *) obstack_finish (&buffer));
0a98123c
IB
1156
1157 if (deps_stream != stdout
1158 && (ferror (deps_stream) || fclose (deps_stream)))
1159 {
1160 fatal_error (input_location, "closing dependency file %s: %m",
1161 d_option.deps_filename);
1162 }
b4c522fa
IB
1163 }
1164
1165 /* Generate JSON files. */
1166 if (global.params.doJsonGeneration)
1167 {
1168 OutBuffer buf;
1169 json_generate (&buf, &modules);
1170
d8930b13 1171 const char *name = global.params.jsonfilename.ptr;
0a98123c 1172 FILE *json_stream;
b4c522fa
IB
1173
1174 if (name && (name[0] != '-' || name[1] != '\0'))
1175 {
d8930b13
IB
1176 const char *nameext
1177 = FileName::defaultExt (name, global.json_ext.ptr);
0a98123c
IB
1178 json_stream = fopen (nameext, "w");
1179 if (!json_stream)
1180 {
1181 fatal_error (input_location, "opening json file %s: %m", nameext);
1182 goto had_errors;
1183 }
b4c522fa
IB
1184 }
1185 else
0a98123c
IB
1186 json_stream = stdout;
1187
1188 fprintf (json_stream, "%s", buf.peekChars ());
1189
1190 if (json_stream != stdout
1191 && (ferror (json_stream) || fclose (json_stream)))
1192 fatal_error (input_location, "closing json file %s: %m", name);
b4c522fa
IB
1193 }
1194
1195 /* Generate Ddoc files. */
1196 if (global.params.doDocComments && !global.errors && !errorcount)
1197 {
2cbc99d1 1198 for (size_t i = 0; i < modules.length; i++)
b4c522fa
IB
1199 {
1200 Module *m = modules[i];
1201 gendocfile (m);
1202 }
1203 }
1204
1205 /* Handle -fdump-d-original. */
1206 if (global.params.vcg_ast)
1207 {
2cbc99d1 1208 for (size_t i = 0; i < modules.length; i++)
b4c522fa
IB
1209 {
1210 Module *m = modules[i];
1211 OutBuffer buf;
1212 buf.doindent = 1;
1213
1214 moduleToBuffer (&buf, m);
d103f336 1215 message ("%s", buf.peekChars ());
b4c522fa
IB
1216 }
1217 }
1218
2cbc99d1 1219 for (size_t i = 0; i < modules.length; i++)
b4c522fa
IB
1220 {
1221 Module *m = modules[i];
1222 if (d_option.fonly && m != Module::rootModule)
1223 continue;
1224
1225 if (global.params.verbose)
1226 message ("code %s", m->toChars ());
1227
1228 if (!flag_syntax_only)
1229 {
1230 if ((entrypoint_module != NULL) && (m == entrypoint_root_module))
1231 build_decl_tree (entrypoint_module);
1232
1233 build_decl_tree (m);
1234 }
1235 }
1236
1237 /* And end the main input file, if the debug writer wants it. */
1238 if (debug_hooks->start_end_main_source_file)
1239 debug_hooks->end_source_file (0);
1240
1241 had_errors:
1242 /* Add the D frontend error count to the GCC error count to correctly
1243 exit with an error status. */
1244 errorcount += (global.errors + global.warnings);
1245
1246 /* Write out globals. */
1247 d_finish_compilation (vec_safe_address (global_declarations),
1248 vec_safe_length (global_declarations));
1249}
1250
1251/* Implements the lang_hooks.types.type_for_mode routine for language D. */
1252
1253static tree
1254d_type_for_mode (machine_mode mode, int unsignedp)
1255{
1256 if (mode == QImode)
1257 return unsignedp ? d_ubyte_type : d_byte_type;
1258
1259 if (mode == HImode)
1260 return unsignedp ? d_ushort_type : d_short_type;
1261
1262 if (mode == SImode)
1263 return unsignedp ? d_uint_type : d_int_type;
1264
1265 if (mode == DImode)
1266 return unsignedp ? d_ulong_type : d_long_type;
1267
1268 if (mode == TYPE_MODE (d_cent_type))
1269 return unsignedp ? d_ucent_type : d_cent_type;
1270
1271 if (mode == TYPE_MODE (float_type_node))
1272 return float_type_node;
1273
1274 if (mode == TYPE_MODE (double_type_node))
1275 return double_type_node;
1276
1277 if (mode == TYPE_MODE (long_double_type_node))
1278 return long_double_type_node;
1279
1280 if (mode == TYPE_MODE (build_pointer_type (char8_type_node)))
1281 return build_pointer_type (char8_type_node);
1282
1283 if (mode == TYPE_MODE (build_pointer_type (d_int_type)))
1284 return build_pointer_type (d_int_type);
1285
edf09592
IB
1286 for (int i = 0; i < NUM_INT_N_ENTS; i ++)
1287 {
1288 if (int_n_enabled_p[i] && mode == int_n_data[i].m)
1289 {
1290 if (unsignedp)
1291 return int_n_trees[i].unsigned_type;
1292 else
1293 return int_n_trees[i].signed_type;
1294 }
1295 }
1296
b4c522fa
IB
1297 if (COMPLEX_MODE_P (mode))
1298 {
1299 machine_mode inner_mode;
1300 tree inner_type;
1301
1302 if (mode == TYPE_MODE (complex_float_type_node))
1303 return complex_float_type_node;
1304 if (mode == TYPE_MODE (complex_double_type_node))
1305 return complex_double_type_node;
1306 if (mode == TYPE_MODE (complex_long_double_type_node))
1307 return complex_long_double_type_node;
1308
1309 inner_mode = (machine_mode) GET_MODE_INNER (mode);
1310 inner_type = d_type_for_mode (inner_mode, unsignedp);
1311 if (inner_type != NULL_TREE)
1312 return build_complex_type (inner_type);
1313 }
1314 else if (VECTOR_MODE_P (mode))
1315 {
1316 machine_mode inner_mode = (machine_mode) GET_MODE_INNER (mode);
1317 tree inner_type = d_type_for_mode (inner_mode, unsignedp);
1318 if (inner_type != NULL_TREE)
1319 return build_vector_type_for_mode (inner_type, mode);
1320 }
1321
1322 return 0;
1323}
1324
1325/* Implements the lang_hooks.types.type_for_size routine for language D. */
1326
1327static tree
1328d_type_for_size (unsigned bits, int unsignedp)
1329{
1330 if (bits <= TYPE_PRECISION (d_byte_type))
1331 return unsignedp ? d_ubyte_type : d_byte_type;
1332
1333 if (bits <= TYPE_PRECISION (d_short_type))
1334 return unsignedp ? d_ushort_type : d_short_type;
1335
1336 if (bits <= TYPE_PRECISION (d_int_type))
1337 return unsignedp ? d_uint_type : d_int_type;
1338
1339 if (bits <= TYPE_PRECISION (d_long_type))
1340 return unsignedp ? d_ulong_type : d_long_type;
1341
1342 if (bits <= TYPE_PRECISION (d_cent_type))
1343 return unsignedp ? d_ucent_type : d_cent_type;
1344
edf09592
IB
1345 for (int i = 0; i < NUM_INT_N_ENTS; i ++)
1346 {
1347 if (int_n_enabled_p[i] && bits == int_n_data[i].bitsize)
1348 {
1349 if (unsignedp)
1350 return int_n_trees[i].unsigned_type;
1351 else
1352 return int_n_trees[i].signed_type;
1353 }
1354 }
1355
b4c522fa
IB
1356 return 0;
1357}
1358
707e9159 1359/* Implements the lang_hooks.types.type_promotes_to routine for language D. */
b4c522fa
IB
1360
1361static tree
1362d_type_promotes_to (tree type)
1363{
707e9159
IB
1364 /* Promotions are only applied on unnamed function arguments for declarations
1365 with `extern(C)' or `extern(C++)' linkage. */
1366 if (cfun && DECL_LANG_FRONTEND (cfun->decl)
1367 && DECL_LANG_FRONTEND (cfun->decl)->linkage != LINKd)
1368 {
1369 /* In [type/integer-promotions], integer promotions are conversions of the
1370 following types:
1371
1372 bool int
1373 byte int
1374 ubyte int
1375 short int
1376 ushort int
1377 char int
1378 wchar int
1379 dchar uint
1380
1381 If an enum has as a base type one of the types in the left column, it
1382 is converted to the type in the right column. */
1383 if (TREE_CODE (type) == ENUMERAL_TYPE && ENUM_IS_SCOPED (type))
1384 type = TREE_TYPE (type);
1385
1386 type = TYPE_MAIN_VARIANT (type);
1387
1388 /* Check for promotions of target-defined types first. */
1389 tree promoted_type = targetm.promoted_type (type);
1390 if (promoted_type)
1391 return promoted_type;
1392
1393 if (TREE_CODE (type) == BOOLEAN_TYPE)
1394 return d_int_type;
1395
1396 if (INTEGRAL_TYPE_P (type))
1397 {
1398 if (type == d_byte_type || type == d_ubyte_type
1399 || type == d_short_type || type == d_ushort_type
1400 || type == char8_type_node || type == char16_type_node)
1401 return d_int_type;
1402
1403 if (type == char32_type_node)
1404 return d_uint_type;
1405
1406 if (TYPE_PRECISION (type) < TYPE_PRECISION (d_int_type))
1407 return d_int_type;
1408 }
1409
1410 /* Float arguments are converted to doubles. */
1411 if (type == float_type_node)
1412 return double_type_node;
1413
1414 if (type == ifloat_type_node)
1415 return idouble_type_node;
1416 }
1417
b4c522fa
IB
1418 return type;
1419}
1420
1421/* Implements the lang_hooks.decls.global_bindings_p routine for language D.
1422 Return true if we are in the global binding level. */
1423
1424static bool
1425d_global_bindings_p (void)
1426{
1427 return (current_binding_level == global_binding_level);
1428}
1429
1430/* Return global_context, but create it first if need be. */
1431
1432static tree
1433get_global_context (void)
1434{
1435 if (!global_context)
1436 {
1437 global_context = build_translation_unit_decl (NULL_TREE);
1438 debug_hooks->register_main_translation_unit (global_context);
1439 }
1440
1441 return global_context;
1442}
1443
1444/* Implements the lang_hooks.decls.pushdecl routine for language D.
1445 Record DECL as belonging to the current lexical scope. */
1446
1447tree
1448d_pushdecl (tree decl)
1449{
1450 /* Set the context of the decl. If current_function_decl did not help in
1451 determining the context, use global scope. */
1452 if (!DECL_CONTEXT (decl))
1453 {
1454 if (current_function_decl)
1455 DECL_CONTEXT (decl) = current_function_decl;
1456 else
1457 DECL_CONTEXT (decl) = get_global_context ();
1458 }
1459
1460 /* Put decls on list in reverse order. */
1461 if (TREE_STATIC (decl) || d_global_bindings_p ())
1462 vec_safe_push (global_declarations, decl);
1463 else
1464 {
1465 TREE_CHAIN (decl) = current_binding_level->names;
1466 current_binding_level->names = decl;
1467 }
1468
1469 return decl;
1470}
1471
1472/* Implements the lang_hooks.decls.getdecls routine for language D.
1473 Return the list of declarations of the current level. */
1474
1475static tree
1476d_getdecls (void)
1477{
1478 if (current_binding_level)
1479 return current_binding_level->names;
1480
1481 return NULL_TREE;
1482}
1483
1484
1485/* Implements the lang_hooks.get_alias_set routine for language D.
1486 Get the alias set corresponding to type or expression T.
1487 Return -1 if we don't do anything special. */
1488
1489static alias_set_type
1490d_get_alias_set (tree)
1491{
1492 /* For now in D, assume everything aliases everything else, until we define
1493 some solid rules backed by a specification. There are also some parts
1494 of code generation routines that don't adhere to C alias rules, such as
1495 build_vconvert. In any case, a lot of user code already assumes there
1496 is no strict aliasing and will break if we were to change that. */
1497 return 0;
1498}
1499
1500/* Implements the lang_hooks.types_compatible_p routine for language D.
1501 Compares two types for equivalence in the D programming language.
1502 This routine should only return 1 if it is sure, even though the frontend
1503 should have already ensured that all types are compatible before handing
1504 over the parsed ASTs to the code generator. */
1505
1506static int
1507d_types_compatible_p (tree x, tree y)
1508{
1509 Type *tx = TYPE_LANG_FRONTEND (x);
1510 Type *ty = TYPE_LANG_FRONTEND (y);
1511
1512 /* Try validating the types in the frontend. */
1513 if (tx != NULL && ty != NULL)
1514 {
1515 /* Types are equivalent. */
1516 if (same_type_p (tx, ty))
1517 return true;
1518
1519 /* Type system allows implicit conversion between. */
1520 if (tx->implicitConvTo (ty) || ty->implicitConvTo (tx))
1521 return true;
1522 }
1523
1524 /* Fallback on using type flags for comparison. E.g: all dynamic arrays
1525 are distinct types in D, but are VIEW_CONVERT compatible. */
1526 if (TREE_CODE (x) == RECORD_TYPE && TREE_CODE (y) == RECORD_TYPE)
1527 {
1528 if (TYPE_DYNAMIC_ARRAY (x) && TYPE_DYNAMIC_ARRAY (y))
1529 return true;
1530
1531 if (TYPE_DELEGATE (x) && TYPE_DELEGATE (y))
1532 return true;
1533
1534 if (TYPE_ASSOCIATIVE_ARRAY (x) && TYPE_ASSOCIATIVE_ARRAY (y))
1535 return true;
1536 }
1537
1538 return false;
1539}
1540
1541/* Implements the lang_hooks.finish_incomplete_decl routine for language D. */
1542
1543static void
1544d_finish_incomplete_decl (tree decl)
1545{
1546 if (VAR_P (decl))
1547 {
1548 /* D allows zero-length declarations. Such a declaration ends up with
1549 DECL_SIZE (t) == NULL_TREE which is what the back-end function
1550 assembler_variable checks. This could change in later versions, or
1551 maybe all of these variables should be aliased to one symbol. */
1552 if (DECL_SIZE (decl) == 0)
1553 {
1554 DECL_SIZE (decl) = bitsize_zero_node;
1555 DECL_SIZE_UNIT (decl) = size_zero_node;
1556 }
1557 }
1558}
1559
1560/* Implements the lang_hooks.types.classify_record routine for language D.
1561 Return the true debug type for TYPE. */
1562
1563static classify_record
1564d_classify_record (tree type)
1565{
1566 Type *t = TYPE_LANG_FRONTEND (type);
89fdaf5a 1567 TypeClass *tc = t ? t->isTypeClass () : NULL;
b4c522fa 1568
89fdaf5a 1569 if (tc != NULL)
b4c522fa 1570 {
b4c522fa
IB
1571 /* extern(C++) interfaces get emitted as classes. */
1572 if (tc->sym->isInterfaceDeclaration ()
1573 && !tc->sym->isCPPinterface ())
1574 return RECORD_IS_INTERFACE;
1575
1576 return RECORD_IS_CLASS;
1577 }
1578
1579 return RECORD_IS_STRUCT;
1580}
1581
1582/* Implements the lang_hooks.tree_size routine for language D.
1583 Determine the size of our tcc_constant or tcc_exceptional nodes. */
1584
1585static size_t
1586d_tree_size (tree_code code)
1587{
1588 switch (code)
1589 {
1590 case FUNCFRAME_INFO:
1591 return sizeof (tree_frame_info);
1592
1593 default:
1594 gcc_unreachable ();
1595 }
1596}
1597
1598/* Implements the lang_hooks.print_xnode routine for language D. */
1599
1600static void
1601d_print_xnode (FILE *file, tree node, int indent)
1602{
1603 switch (TREE_CODE (node))
1604 {
1605 case FUNCFRAME_INFO:
1606 print_node (file, "frame_type", FRAMEINFO_TYPE (node), indent + 4);
1607 break;
1608
1609 default:
1610 break;
1611 }
1612}
1613
1614/* Return which tree structure is used by NODE, or TS_D_GENERIC if NODE
1615 is one of the language-independent trees. */
1616
1617d_tree_node_structure_enum
1618d_tree_node_structure (lang_tree_node *t)
1619{
1620 switch (TREE_CODE (&t->generic))
1621 {
1622 case IDENTIFIER_NODE:
1623 return TS_D_IDENTIFIER;
1624
1625 case FUNCFRAME_INFO:
1626 return TS_D_FRAMEINFO;
1627
1628 default:
1629 return TS_D_GENERIC;
1630 }
1631}
1632
1633/* Allocate and return a lang specific structure for the frontend type. */
1634
1635struct lang_type *
1636build_lang_type (Type *t)
1637{
af3c19f0 1638 struct lang_type *lt = ggc_cleared_alloc <struct lang_type> ();
b4c522fa
IB
1639 lt->type = t;
1640 return lt;
1641}
1642
1643/* Allocate and return a lang specific structure for the frontend decl. */
1644
1645struct lang_decl *
1646build_lang_decl (Declaration *d)
1647{
1648 /* For compiler generated run-time typeinfo, a lang_decl is allocated even if
1649 there's no associated frontend symbol to refer to (yet). If the symbol
1650 appears later in the compilation, then the slot will be re-used. */
1651 if (d == NULL)
af3c19f0 1652 return ggc_cleared_alloc <struct lang_decl> ();
b4c522fa
IB
1653
1654 struct lang_decl *ld = (d->csym) ? DECL_LANG_SPECIFIC (d->csym) : NULL;
1655 if (ld == NULL)
af3c19f0 1656 ld = ggc_cleared_alloc <struct lang_decl> ();
b4c522fa
IB
1657
1658 if (ld->decl == NULL)
1659 ld->decl = d;
1660
1661 return ld;
1662}
1663
1664/* Implements the lang_hooks.dup_lang_specific_decl routine for language D.
1665 Replace the DECL_LANG_SPECIFIC field of NODE with a copy. */
1666
1667static void
1668d_dup_lang_specific_decl (tree node)
1669{
af3c19f0 1670 if (!DECL_LANG_SPECIFIC (node))
b4c522fa
IB
1671 return;
1672
af3c19f0 1673 struct lang_decl *ld = ggc_alloc <struct lang_decl> ();
b4c522fa
IB
1674 memcpy (ld, DECL_LANG_SPECIFIC (node), sizeof (struct lang_decl));
1675 DECL_LANG_SPECIFIC (node) = ld;
1676}
1677
1678/* This preserves trees we create from the garbage collector. */
1679
1680static GTY(()) tree d_keep_list = NULL_TREE;
1681
1682void
1683d_keep (tree t)
1684{
1685 d_keep_list = tree_cons (NULL_TREE, t, d_keep_list);
1686}
1687
1688/* Implements the lang_hooks.eh_personality routine for language D.
1689 Return the GDC personality function decl. */
1690
1691static GTY(()) tree d_eh_personality_decl;
1692
1693static tree
1694d_eh_personality (void)
1695{
1696 if (!d_eh_personality_decl)
1697 d_eh_personality_decl = build_personality_function ("gdc");
1698
1699 return d_eh_personality_decl;
1700}
1701
1702/* Implements the lang_hooks.eh_runtime_type routine for language D. */
1703
1704static tree
1705d_build_eh_runtime_type (tree type)
1706{
1707 Type *t = TYPE_LANG_FRONTEND (type);
89fdaf5a
IB
1708 gcc_assert (t != NULL);
1709 t = t->toBasetype ();
b4c522fa 1710
89fdaf5a 1711 ClassDeclaration *cd = t->isTypeClass ()->sym;
b4c522fa
IB
1712 tree decl;
1713
1714 if (cd->isCPPclass ())
1715 decl = get_cpp_typeinfo_decl (cd);
1716 else
1717 decl = get_classinfo_decl (cd);
1718
1719 return convert (ptr_type_node, build_address (decl));
1720}
1721
0907036f
IB
1722/* Implements the lang_hooks.enum_underlying_base_type routine for language D.
1723 Returns the underlying type of the given enumeration TYPE. */
1724
1725static tree
1726d_enum_underlying_base_type (const_tree type)
1727{
1728 gcc_assert (TREE_CODE (type) == ENUMERAL_TYPE);
1729 return TREE_TYPE (type);
1730}
1731
b4c522fa
IB
1732/* Definitions for our language-specific hooks. */
1733
1734#undef LANG_HOOKS_NAME
1735#undef LANG_HOOKS_INIT
1736#undef LANG_HOOKS_INIT_TS
1737#undef LANG_HOOKS_INIT_OPTIONS
1738#undef LANG_HOOKS_INIT_OPTIONS_STRUCT
1739#undef LANG_HOOKS_OPTION_LANG_MASK
1740#undef LANG_HOOKS_HANDLE_OPTION
1741#undef LANG_HOOKS_POST_OPTIONS
1742#undef LANG_HOOKS_PARSE_FILE
1743#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
1744#undef LANG_HOOKS_ATTRIBUTE_TABLE
1745#undef LANG_HOOKS_GET_ALIAS_SET
1746#undef LANG_HOOKS_TYPES_COMPATIBLE_P
1747#undef LANG_HOOKS_BUILTIN_FUNCTION
1748#undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
1749#undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
1750#undef LANG_HOOKS_GIMPLIFY_EXPR
1751#undef LANG_HOOKS_CLASSIFY_RECORD
1752#undef LANG_HOOKS_TREE_SIZE
1753#undef LANG_HOOKS_PRINT_XNODE
1754#undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
1755#undef LANG_HOOKS_EH_PERSONALITY
1756#undef LANG_HOOKS_EH_RUNTIME_TYPE
0907036f 1757#undef LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE
b4c522fa
IB
1758#undef LANG_HOOKS_PUSHDECL
1759#undef LANG_HOOKS_GETDECLS
1760#undef LANG_HOOKS_GLOBAL_BINDINGS_P
1761#undef LANG_HOOKS_TYPE_FOR_MODE
1762#undef LANG_HOOKS_TYPE_FOR_SIZE
1763#undef LANG_HOOKS_TYPE_PROMOTES_TO
1764
1765#define LANG_HOOKS_NAME "GNU D"
1766#define LANG_HOOKS_INIT d_init
1767#define LANG_HOOKS_INIT_TS d_init_ts
1768#define LANG_HOOKS_INIT_OPTIONS d_init_options
1769#define LANG_HOOKS_INIT_OPTIONS_STRUCT d_init_options_struct
1770#define LANG_HOOKS_OPTION_LANG_MASK d_option_lang_mask
1771#define LANG_HOOKS_HANDLE_OPTION d_handle_option
1772#define LANG_HOOKS_POST_OPTIONS d_post_options
1773#define LANG_HOOKS_PARSE_FILE d_parse_file
1774#define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE d_langhook_common_attribute_table
1775#define LANG_HOOKS_ATTRIBUTE_TABLE d_langhook_attribute_table
1776#define LANG_HOOKS_GET_ALIAS_SET d_get_alias_set
1777#define LANG_HOOKS_TYPES_COMPATIBLE_P d_types_compatible_p
1778#define LANG_HOOKS_BUILTIN_FUNCTION d_builtin_function
1779#define LANG_HOOKS_REGISTER_BUILTIN_TYPE d_register_builtin_type
1780#define LANG_HOOKS_FINISH_INCOMPLETE_DECL d_finish_incomplete_decl
1781#define LANG_HOOKS_GIMPLIFY_EXPR d_gimplify_expr
1782#define LANG_HOOKS_CLASSIFY_RECORD d_classify_record
1783#define LANG_HOOKS_TREE_SIZE d_tree_size
1784#define LANG_HOOKS_PRINT_XNODE d_print_xnode
1785#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL d_dup_lang_specific_decl
1786#define LANG_HOOKS_EH_PERSONALITY d_eh_personality
1787#define LANG_HOOKS_EH_RUNTIME_TYPE d_build_eh_runtime_type
0907036f 1788#define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE d_enum_underlying_base_type
b4c522fa
IB
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"