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