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