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