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