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