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