1627f7eb2Smrg /* d-lang.cc -- Language-dependent hooks for D.
2*4c3eb207Smrg Copyright (C) 2006-2020 Free Software Foundation, Inc.
3627f7eb2Smrg
4627f7eb2Smrg GCC is free software; you can redistribute it and/or modify
5627f7eb2Smrg it under the terms of the GNU General Public License as published by
6627f7eb2Smrg the Free Software Foundation; either version 3, or (at your option)
7627f7eb2Smrg any later version.
8627f7eb2Smrg
9627f7eb2Smrg GCC is distributed in the hope that it will be useful,
10627f7eb2Smrg but WITHOUT ANY WARRANTY; without even the implied warranty of
11627f7eb2Smrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12627f7eb2Smrg GNU General Public License for more details.
13627f7eb2Smrg
14627f7eb2Smrg You should have received a copy of the GNU General Public License
15627f7eb2Smrg along with GCC; see the file COPYING3. If not see
16627f7eb2Smrg <http://www.gnu.org/licenses/>. */
17627f7eb2Smrg
18627f7eb2Smrg #include "config.h"
19627f7eb2Smrg #include "system.h"
20627f7eb2Smrg #include "coretypes.h"
21627f7eb2Smrg
22627f7eb2Smrg #include "dmd/aggregate.h"
23627f7eb2Smrg #include "dmd/cond.h"
24627f7eb2Smrg #include "dmd/declaration.h"
25627f7eb2Smrg #include "dmd/doc.h"
26627f7eb2Smrg #include "dmd/errors.h"
27627f7eb2Smrg #include "dmd/expression.h"
28627f7eb2Smrg #include "dmd/hdrgen.h"
29627f7eb2Smrg #include "dmd/identifier.h"
30627f7eb2Smrg #include "dmd/json.h"
31627f7eb2Smrg #include "dmd/mangle.h"
32627f7eb2Smrg #include "dmd/mars.h"
33627f7eb2Smrg #include "dmd/module.h"
34627f7eb2Smrg #include "dmd/mtype.h"
35627f7eb2Smrg #include "dmd/target.h"
36627f7eb2Smrg
37627f7eb2Smrg #include "opts.h"
38627f7eb2Smrg #include "alias.h"
39627f7eb2Smrg #include "tree.h"
40627f7eb2Smrg #include "diagnostic.h"
41627f7eb2Smrg #include "fold-const.h"
42627f7eb2Smrg #include "toplev.h"
43627f7eb2Smrg #include "langhooks.h"
44627f7eb2Smrg #include "langhooks-def.h"
45627f7eb2Smrg #include "target.h"
46627f7eb2Smrg #include "stringpool.h"
47627f7eb2Smrg #include "stor-layout.h"
48627f7eb2Smrg #include "varasm.h"
49627f7eb2Smrg #include "output.h"
50627f7eb2Smrg #include "print-tree.h"
51627f7eb2Smrg #include "gimple-expr.h"
52627f7eb2Smrg #include "gimplify.h"
53627f7eb2Smrg #include "debug.h"
54627f7eb2Smrg
55627f7eb2Smrg #include "d-tree.h"
56627f7eb2Smrg #include "id.h"
57627f7eb2Smrg
58627f7eb2Smrg
59627f7eb2Smrg /* Array of D frontend type/decl nodes. */
60627f7eb2Smrg tree d_global_trees[DTI_MAX];
61627f7eb2Smrg
62627f7eb2Smrg /* True if compilation is currently inside the D frontend semantic passes. */
63627f7eb2Smrg bool doing_semantic_analysis_p = false;
64627f7eb2Smrg
65627f7eb2Smrg /* Options handled by the compiler that are separate from the frontend. */
66627f7eb2Smrg struct d_option_data
67627f7eb2Smrg {
68627f7eb2Smrg const char *fonly; /* -fonly=<arg> */
69627f7eb2Smrg const char *multilib; /* -imultilib <dir> */
70627f7eb2Smrg const char *prefix; /* -iprefix <dir> */
71627f7eb2Smrg
72627f7eb2Smrg bool deps; /* -M */
73627f7eb2Smrg bool deps_skip_system; /* -MM */
74627f7eb2Smrg const char *deps_filename; /* -M[M]D */
75627f7eb2Smrg const char *deps_filename_user; /* -MF <arg> */
76627f7eb2Smrg OutBuffer *deps_target; /* -M[QT] <arg> */
77627f7eb2Smrg bool deps_phony; /* -MP */
78627f7eb2Smrg
79627f7eb2Smrg bool stdinc; /* -nostdinc */
80627f7eb2Smrg }
81627f7eb2Smrg d_option;
82627f7eb2Smrg
83627f7eb2Smrg /* List of modules being compiled. */
84627f7eb2Smrg static Modules builtin_modules;
85627f7eb2Smrg
86627f7eb2Smrg /* Module where `C main' is defined, compiled in if needed. */
87627f7eb2Smrg static Module *entrypoint_module = NULL;
88627f7eb2Smrg static Module *entrypoint_root_module = NULL;
89627f7eb2Smrg
90627f7eb2Smrg /* The current and global binding level in effect. */
91627f7eb2Smrg struct binding_level *current_binding_level;
92627f7eb2Smrg struct binding_level *global_binding_level;
93627f7eb2Smrg
94627f7eb2Smrg /* The context to be used for global declarations. */
95627f7eb2Smrg static GTY(()) tree global_context;
96627f7eb2Smrg
97627f7eb2Smrg /* Array of all global declarations to pass back to the middle-end. */
98627f7eb2Smrg static GTY(()) vec<tree, va_gc> *global_declarations;
99627f7eb2Smrg
100627f7eb2Smrg /* Support for GCC-style command-line make dependency generation.
101627f7eb2Smrg Adds TARGET to the make dependencies target buffer.
102627f7eb2Smrg QUOTED is true if the string should be quoted. */
103627f7eb2Smrg
104627f7eb2Smrg static void
deps_add_target(const char * target,bool quoted)105627f7eb2Smrg deps_add_target (const char *target, bool quoted)
106627f7eb2Smrg {
107627f7eb2Smrg if (!d_option.deps_target)
108627f7eb2Smrg d_option.deps_target = new OutBuffer ();
109627f7eb2Smrg else
110627f7eb2Smrg d_option.deps_target->writeByte (' ');
111627f7eb2Smrg
112627f7eb2Smrg d_option.deps_target->reserve (strlen (target));
113627f7eb2Smrg
114627f7eb2Smrg if (!quoted)
115627f7eb2Smrg {
116627f7eb2Smrg d_option.deps_target->writestring (target);
117627f7eb2Smrg return;
118627f7eb2Smrg }
119627f7eb2Smrg
120627f7eb2Smrg /* Quote characters in target which are significant to Make. */
121627f7eb2Smrg for (const char *p = target; *p != '\0'; p++)
122627f7eb2Smrg {
123627f7eb2Smrg switch (*p)
124627f7eb2Smrg {
125627f7eb2Smrg case ' ':
126627f7eb2Smrg case '\t':
127627f7eb2Smrg for (const char *q = p - 1; target <= q && *q == '\\'; q--)
128627f7eb2Smrg d_option.deps_target->writeByte ('\\');
129627f7eb2Smrg d_option.deps_target->writeByte ('\\');
130627f7eb2Smrg break;
131627f7eb2Smrg
132627f7eb2Smrg case '$':
133627f7eb2Smrg d_option.deps_target->writeByte ('$');
134627f7eb2Smrg break;
135627f7eb2Smrg
136627f7eb2Smrg case '#':
137627f7eb2Smrg d_option.deps_target->writeByte ('\\');
138627f7eb2Smrg break;
139627f7eb2Smrg
140627f7eb2Smrg default:
141627f7eb2Smrg break;
142627f7eb2Smrg }
143627f7eb2Smrg
144627f7eb2Smrg d_option.deps_target->writeByte (*p);
145627f7eb2Smrg }
146627f7eb2Smrg }
147627f7eb2Smrg
148627f7eb2Smrg /* Write out all dependencies of a given MODULE to the specified BUFFER.
149627f7eb2Smrg COLMAX is the number of columns to word-wrap at (0 means don't wrap). */
150627f7eb2Smrg
151627f7eb2Smrg static void
deps_write(Module * module,OutBuffer * buffer,unsigned colmax=72)152627f7eb2Smrg deps_write (Module *module, OutBuffer *buffer, unsigned colmax = 72)
153627f7eb2Smrg {
154*4c3eb207Smrg hash_set <const char *> seen_modules;
155*4c3eb207Smrg vec <const char *> dependencies = vNULL;
156627f7eb2Smrg
157627f7eb2Smrg Modules modlist;
158627f7eb2Smrg modlist.push (module);
159627f7eb2Smrg
160*4c3eb207Smrg vec <const char *> phonylist = vNULL;
161627f7eb2Smrg unsigned column = 0;
162627f7eb2Smrg
163627f7eb2Smrg /* Write out make target module name. */
164627f7eb2Smrg if (d_option.deps_target)
165627f7eb2Smrg {
166*4c3eb207Smrg buffer->writestring (d_option.deps_target->extractString ());
167*4c3eb207Smrg column = d_option.deps_target->offset;
168627f7eb2Smrg }
169627f7eb2Smrg else
170627f7eb2Smrg {
171*4c3eb207Smrg buffer->writestring (module->objfile->name->str);
172*4c3eb207Smrg column = buffer->offset;
173627f7eb2Smrg }
174627f7eb2Smrg
175627f7eb2Smrg buffer->writestring (":");
176627f7eb2Smrg column++;
177627f7eb2Smrg
178*4c3eb207Smrg /* Search all modules for file dependencies. */
179627f7eb2Smrg while (modlist.dim > 0)
180627f7eb2Smrg {
181627f7eb2Smrg Module *depmod = modlist.pop ();
182627f7eb2Smrg
183*4c3eb207Smrg const char *modstr = depmod->srcfile->name->str;
184627f7eb2Smrg
185*4c3eb207Smrg /* Skip modules that have already been looked at. */
186*4c3eb207Smrg if (seen_modules.add (modstr))
187627f7eb2Smrg continue;
188627f7eb2Smrg
189*4c3eb207Smrg dependencies.safe_push (modstr);
190627f7eb2Smrg
191627f7eb2Smrg /* Add to list of phony targets if is not being compile. */
192627f7eb2Smrg if (d_option.deps_phony && !depmod->isRoot ())
193*4c3eb207Smrg phonylist.safe_push (modstr);
194627f7eb2Smrg
195*4c3eb207Smrg /* Add imported files to dependency list. */
196*4c3eb207Smrg for (size_t i = 0; i < depmod->contentImportedFiles.dim; i++)
197*4c3eb207Smrg {
198*4c3eb207Smrg const char *impstr = depmod->contentImportedFiles[i];
199*4c3eb207Smrg dependencies.safe_push (impstr);
200*4c3eb207Smrg phonylist.safe_push (impstr);
201*4c3eb207Smrg }
202*4c3eb207Smrg
203*4c3eb207Smrg /* Search all imports of the module. */
204627f7eb2Smrg for (size_t i = 0; i < depmod->aimports.dim; i++)
205627f7eb2Smrg {
206627f7eb2Smrg Module *m = depmod->aimports[i];
207627f7eb2Smrg
208627f7eb2Smrg /* Ignore compiler-generated modules. */
209627f7eb2Smrg if ((m->ident == Identifier::idPool ("__entrypoint")
210627f7eb2Smrg || m->ident == Identifier::idPool ("__main"))
211627f7eb2Smrg && m->parent == NULL)
212627f7eb2Smrg continue;
213627f7eb2Smrg
214627f7eb2Smrg /* Don't search system installed modules, this includes
215627f7eb2Smrg object, core.*, std.*, and gcc.* packages. */
216627f7eb2Smrg if (d_option.deps_skip_system)
217627f7eb2Smrg {
218627f7eb2Smrg if (m->ident == Identifier::idPool ("object")
219627f7eb2Smrg && m->parent == NULL)
220627f7eb2Smrg continue;
221627f7eb2Smrg
222627f7eb2Smrg if (m->md && m->md->packages)
223627f7eb2Smrg {
224627f7eb2Smrg Identifier *package = (*m->md->packages)[0];
225627f7eb2Smrg
226627f7eb2Smrg if (package == Identifier::idPool ("core")
227627f7eb2Smrg || package == Identifier::idPool ("std")
228627f7eb2Smrg || package == Identifier::idPool ("gcc"))
229627f7eb2Smrg continue;
230627f7eb2Smrg }
231627f7eb2Smrg }
232627f7eb2Smrg
233627f7eb2Smrg modlist.push (m);
234627f7eb2Smrg }
235627f7eb2Smrg }
236627f7eb2Smrg
237*4c3eb207Smrg /* Write out all make dependencies. */
238*4c3eb207Smrg for (size_t i = 0; i < dependencies.length (); i++)
239*4c3eb207Smrg {
240*4c3eb207Smrg const char *str = dependencies[i];
241*4c3eb207Smrg unsigned size = strlen (str);
242*4c3eb207Smrg column += size;
243*4c3eb207Smrg
244*4c3eb207Smrg if (colmax && column > colmax)
245*4c3eb207Smrg {
246*4c3eb207Smrg buffer->writestring (" \\\n ");
247*4c3eb207Smrg column = size + 1;
248*4c3eb207Smrg }
249*4c3eb207Smrg else
250*4c3eb207Smrg {
251*4c3eb207Smrg buffer->writestring (" ");
252*4c3eb207Smrg column++;
253*4c3eb207Smrg }
254*4c3eb207Smrg
255*4c3eb207Smrg buffer->writestring (str);
256*4c3eb207Smrg }
257*4c3eb207Smrg
258627f7eb2Smrg buffer->writenl ();
259627f7eb2Smrg
260627f7eb2Smrg /* Write out all phony targets. */
261*4c3eb207Smrg for (size_t i = 0; i < phonylist.length (); i++)
262627f7eb2Smrg {
263627f7eb2Smrg buffer->writenl ();
264*4c3eb207Smrg buffer->writestring (phonylist[i]);
265627f7eb2Smrg buffer->writestring (":\n");
266627f7eb2Smrg }
267627f7eb2Smrg }
268627f7eb2Smrg
269627f7eb2Smrg /* Implements the lang_hooks.init_options routine for language D.
270627f7eb2Smrg This initializes the global state for the D frontend before calling
271627f7eb2Smrg the option handlers. */
272627f7eb2Smrg
273627f7eb2Smrg static void
d_init_options(unsigned int,cl_decoded_option * decoded_options)274627f7eb2Smrg d_init_options (unsigned int, cl_decoded_option *decoded_options)
275627f7eb2Smrg {
276627f7eb2Smrg /* Set default values. */
277627f7eb2Smrg global._init ();
278627f7eb2Smrg
279627f7eb2Smrg global.vendor = lang_hooks.name;
280627f7eb2Smrg global.params.argv0 = xstrdup (decoded_options[0].arg);
281627f7eb2Smrg global.params.link = true;
282627f7eb2Smrg global.params.useAssert = true;
283627f7eb2Smrg global.params.useInvariants = true;
284627f7eb2Smrg global.params.useIn = true;
285627f7eb2Smrg global.params.useOut = true;
286627f7eb2Smrg global.params.useArrayBounds = BOUNDSCHECKdefault;
287627f7eb2Smrg global.params.useSwitchError = true;
288627f7eb2Smrg global.params.useModuleInfo = true;
289627f7eb2Smrg global.params.useTypeInfo = true;
290627f7eb2Smrg global.params.useExceptions = true;
291627f7eb2Smrg global.params.useInline = false;
292627f7eb2Smrg global.params.obj = true;
293627f7eb2Smrg global.params.hdrStripPlainFunctions = true;
294627f7eb2Smrg global.params.betterC = false;
295627f7eb2Smrg global.params.allInst = false;
296627f7eb2Smrg
297627f7eb2Smrg /* Default extern(C++) mangling to C++14. */
298627f7eb2Smrg global.params.cplusplus = CppStdRevisionCpp14;
299627f7eb2Smrg
300627f7eb2Smrg global.params.linkswitches = new Strings ();
301627f7eb2Smrg global.params.libfiles = new Strings ();
302627f7eb2Smrg global.params.objfiles = new Strings ();
303627f7eb2Smrg global.params.ddocfiles = new Strings ();
304627f7eb2Smrg
305627f7eb2Smrg /* Warnings and deprecations are disabled by default. */
306627f7eb2Smrg global.params.useDeprecated = DIAGNOSTICoff;
307627f7eb2Smrg global.params.warnings = DIAGNOSTICoff;
308627f7eb2Smrg
309627f7eb2Smrg global.params.imppath = new Strings ();
310627f7eb2Smrg global.params.fileImppath = new Strings ();
311627f7eb2Smrg global.params.modFileAliasStrings = new Strings ();
312627f7eb2Smrg
313627f7eb2Smrg /* Extra GDC-specific options. */
314627f7eb2Smrg d_option.fonly = NULL;
315627f7eb2Smrg d_option.multilib = NULL;
316627f7eb2Smrg d_option.prefix = NULL;
317627f7eb2Smrg d_option.deps = false;
318627f7eb2Smrg d_option.deps_skip_system = false;
319627f7eb2Smrg d_option.deps_filename = NULL;
320627f7eb2Smrg d_option.deps_filename_user = NULL;
321627f7eb2Smrg d_option.deps_target = NULL;
322627f7eb2Smrg d_option.deps_phony = false;
323627f7eb2Smrg d_option.stdinc = true;
324627f7eb2Smrg }
325627f7eb2Smrg
326627f7eb2Smrg /* Implements the lang_hooks.init_options_struct routine for language D.
327627f7eb2Smrg Initializes the options structure OPTS. */
328627f7eb2Smrg
329627f7eb2Smrg static void
d_init_options_struct(gcc_options * opts)330627f7eb2Smrg d_init_options_struct (gcc_options *opts)
331627f7eb2Smrg {
332627f7eb2Smrg /* GCC options. */
333627f7eb2Smrg opts->x_flag_exceptions = 1;
334627f7eb2Smrg
335627f7eb2Smrg /* Avoid range issues for complex multiply and divide. */
336627f7eb2Smrg opts->x_flag_complex_method = 2;
337627f7eb2Smrg
338627f7eb2Smrg /* Unlike C, there is no global 'errno' variable. */
339627f7eb2Smrg opts->x_flag_errno_math = 0;
340627f7eb2Smrg opts->frontend_set_flag_errno_math = true;
341627f7eb2Smrg
342627f7eb2Smrg /* Keep in sync with existing -fbounds-check flag. */
343627f7eb2Smrg opts->x_flag_bounds_check = global.params.useArrayBounds;
344627f7eb2Smrg
345627f7eb2Smrg /* D says that signed overflow is precisely defined. */
346627f7eb2Smrg opts->x_flag_wrapv = 1;
347627f7eb2Smrg }
348627f7eb2Smrg
349627f7eb2Smrg /* Implements the lang_hooks.lang_mask routine for language D.
350627f7eb2Smrg Returns language mask for option parsing. */
351627f7eb2Smrg
352627f7eb2Smrg static unsigned int
d_option_lang_mask(void)353627f7eb2Smrg d_option_lang_mask (void)
354627f7eb2Smrg {
355627f7eb2Smrg return CL_D;
356627f7eb2Smrg }
357627f7eb2Smrg
358627f7eb2Smrg /* Implements the lang_hooks.init routine for language D. */
359627f7eb2Smrg
360627f7eb2Smrg static bool
d_init(void)361627f7eb2Smrg d_init (void)
362627f7eb2Smrg {
363627f7eb2Smrg Type::_init ();
364627f7eb2Smrg Id::initialize ();
365627f7eb2Smrg Module::_init ();
366627f7eb2Smrg Expression::_init ();
367627f7eb2Smrg Objc::_init ();
368627f7eb2Smrg
369627f7eb2Smrg /* Back-end init. */
370627f7eb2Smrg global_binding_level = ggc_cleared_alloc<binding_level> ();
371627f7eb2Smrg current_binding_level = global_binding_level;
372627f7eb2Smrg
373627f7eb2Smrg /* This allows the code in d-builtins.cc to not have to worry about
374627f7eb2Smrg converting (C signed char *) to (D char *) for string arguments of
375627f7eb2Smrg built-in functions. The parameter (signed_char = false) specifies
376627f7eb2Smrg whether char is signed. */
377627f7eb2Smrg build_common_tree_nodes (false);
378627f7eb2Smrg
379627f7eb2Smrg d_init_builtins ();
380627f7eb2Smrg
381627f7eb2Smrg if (flag_exceptions)
382627f7eb2Smrg using_eh_for_cleanups ();
383627f7eb2Smrg
384627f7eb2Smrg if (!supports_one_only ())
385627f7eb2Smrg flag_weak = 0;
386627f7eb2Smrg
387627f7eb2Smrg /* This is the C main, not the D main. */
388627f7eb2Smrg main_identifier_node = get_identifier ("main");
389627f7eb2Smrg
390627f7eb2Smrg Target::_init ();
391627f7eb2Smrg d_init_versions ();
392627f7eb2Smrg
393627f7eb2Smrg /* Insert all library-configured identifiers and import paths. */
394627f7eb2Smrg add_import_paths (d_option.prefix, d_option.multilib, d_option.stdinc);
395627f7eb2Smrg
396627f7eb2Smrg return 1;
397627f7eb2Smrg }
398627f7eb2Smrg
399627f7eb2Smrg /* Implements the lang_hooks.init_ts routine for language D. */
400627f7eb2Smrg
401627f7eb2Smrg static void
d_init_ts(void)402627f7eb2Smrg d_init_ts (void)
403627f7eb2Smrg {
404627f7eb2Smrg MARK_TS_TYPED (FLOAT_MOD_EXPR);
405627f7eb2Smrg MARK_TS_TYPED (UNSIGNED_RSHIFT_EXPR);
406627f7eb2Smrg }
407627f7eb2Smrg
408627f7eb2Smrg /* Implements the lang_hooks.handle_option routine for language D.
409627f7eb2Smrg Handles D specific options. Return false if we didn't do anything. */
410627f7eb2Smrg
411627f7eb2Smrg 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)412627f7eb2Smrg d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
413627f7eb2Smrg int kind ATTRIBUTE_UNUSED,
414627f7eb2Smrg location_t loc ATTRIBUTE_UNUSED,
415627f7eb2Smrg const cl_option_handlers *handlers ATTRIBUTE_UNUSED)
416627f7eb2Smrg {
417627f7eb2Smrg opt_code code = (opt_code) scode;
418627f7eb2Smrg bool result = true;
419627f7eb2Smrg
420627f7eb2Smrg switch (code)
421627f7eb2Smrg {
422627f7eb2Smrg case OPT_fall_instantiations:
423627f7eb2Smrg global.params.allInst = value;
424627f7eb2Smrg break;
425627f7eb2Smrg
426627f7eb2Smrg case OPT_fassert:
427627f7eb2Smrg global.params.useAssert = value;
428627f7eb2Smrg break;
429627f7eb2Smrg
430627f7eb2Smrg case OPT_fbounds_check:
431627f7eb2Smrg global.params.useArrayBounds = value
432627f7eb2Smrg ? BOUNDSCHECKon : BOUNDSCHECKoff;
433627f7eb2Smrg break;
434627f7eb2Smrg
435627f7eb2Smrg case OPT_fbounds_check_:
436627f7eb2Smrg global.params.useArrayBounds = (value == 2) ? BOUNDSCHECKon
437627f7eb2Smrg : (value == 1) ? BOUNDSCHECKsafeonly : BOUNDSCHECKoff;
438627f7eb2Smrg break;
439627f7eb2Smrg
440627f7eb2Smrg case OPT_fdebug:
441627f7eb2Smrg global.params.debuglevel = value ? 1 : 0;
442627f7eb2Smrg break;
443627f7eb2Smrg
444627f7eb2Smrg case OPT_fdebug_:
445627f7eb2Smrg if (ISDIGIT (arg[0]))
446627f7eb2Smrg {
447627f7eb2Smrg int level = integral_argument (arg);
448627f7eb2Smrg if (level != -1)
449627f7eb2Smrg {
450627f7eb2Smrg DebugCondition::setGlobalLevel (level);
451627f7eb2Smrg break;
452627f7eb2Smrg }
453627f7eb2Smrg }
454627f7eb2Smrg
455627f7eb2Smrg if (Identifier::isValidIdentifier (CONST_CAST (char *, arg)))
456627f7eb2Smrg {
457627f7eb2Smrg DebugCondition::addGlobalIdent (arg);
458627f7eb2Smrg break;
459627f7eb2Smrg }
460627f7eb2Smrg
461*4c3eb207Smrg error ("bad argument for %<-fdebug%>: %qs", arg);
462627f7eb2Smrg break;
463627f7eb2Smrg
464627f7eb2Smrg case OPT_fdoc:
465627f7eb2Smrg global.params.doDocComments = value;
466627f7eb2Smrg break;
467627f7eb2Smrg
468627f7eb2Smrg case OPT_fdoc_dir_:
469627f7eb2Smrg global.params.doDocComments = true;
470627f7eb2Smrg global.params.docdir = arg;
471627f7eb2Smrg break;
472627f7eb2Smrg
473627f7eb2Smrg case OPT_fdoc_file_:
474627f7eb2Smrg global.params.doDocComments = true;
475627f7eb2Smrg global.params.docname = arg;
476627f7eb2Smrg break;
477627f7eb2Smrg
478627f7eb2Smrg case OPT_fdoc_inc_:
479627f7eb2Smrg global.params.ddocfiles->push (arg);
480627f7eb2Smrg break;
481627f7eb2Smrg
482627f7eb2Smrg case OPT_fdruntime:
483627f7eb2Smrg global.params.betterC = !value;
484627f7eb2Smrg break;
485627f7eb2Smrg
486627f7eb2Smrg case OPT_fdump_d_original:
487627f7eb2Smrg global.params.vcg_ast = value;
488627f7eb2Smrg break;
489627f7eb2Smrg
490627f7eb2Smrg case OPT_fexceptions:
491627f7eb2Smrg global.params.useExceptions = value;
492627f7eb2Smrg break;
493627f7eb2Smrg
494627f7eb2Smrg case OPT_fignore_unknown_pragmas:
495627f7eb2Smrg global.params.ignoreUnsupportedPragmas = value;
496627f7eb2Smrg break;
497627f7eb2Smrg
498627f7eb2Smrg case OPT_finvariants:
499627f7eb2Smrg global.params.useInvariants = value;
500627f7eb2Smrg break;
501627f7eb2Smrg
502627f7eb2Smrg case OPT_fmain:
503627f7eb2Smrg global.params.addMain = value;
504627f7eb2Smrg break;
505627f7eb2Smrg
506627f7eb2Smrg case OPT_fmodule_file_:
507627f7eb2Smrg global.params.modFileAliasStrings->push (arg);
508627f7eb2Smrg if (!strchr (arg, '='))
509*4c3eb207Smrg error ("bad argument for %<-fmodule-file%>: %qs", arg);
510627f7eb2Smrg break;
511627f7eb2Smrg
512627f7eb2Smrg case OPT_fmoduleinfo:
513627f7eb2Smrg global.params.useModuleInfo = value;
514627f7eb2Smrg break;
515627f7eb2Smrg
516627f7eb2Smrg case OPT_fonly_:
517627f7eb2Smrg d_option.fonly = arg;
518627f7eb2Smrg break;
519627f7eb2Smrg
520627f7eb2Smrg case OPT_fpostconditions:
521627f7eb2Smrg global.params.useOut = value;
522627f7eb2Smrg break;
523627f7eb2Smrg
524627f7eb2Smrg case OPT_fpreconditions:
525627f7eb2Smrg global.params.useIn = value;
526627f7eb2Smrg break;
527627f7eb2Smrg
528627f7eb2Smrg case OPT_frelease:
529627f7eb2Smrg global.params.release = value;
530627f7eb2Smrg break;
531627f7eb2Smrg
532627f7eb2Smrg case OPT_frtti:
533627f7eb2Smrg global.params.useTypeInfo = value;
534627f7eb2Smrg break;
535627f7eb2Smrg
536627f7eb2Smrg case OPT_fswitch_errors:
537627f7eb2Smrg global.params.useSwitchError = value;
538627f7eb2Smrg break;
539627f7eb2Smrg
540627f7eb2Smrg case OPT_ftransition_all:
541627f7eb2Smrg global.params.vtls = value;
542627f7eb2Smrg global.params.vfield = value;
543627f7eb2Smrg global.params.vcomplex = value;
544627f7eb2Smrg break;
545627f7eb2Smrg
546627f7eb2Smrg case OPT_ftransition_checkimports:
547627f7eb2Smrg global.params.check10378 = value;
548627f7eb2Smrg break;
549627f7eb2Smrg
550627f7eb2Smrg case OPT_ftransition_complex:
551627f7eb2Smrg global.params.vcomplex = value;
552627f7eb2Smrg break;
553627f7eb2Smrg
554627f7eb2Smrg case OPT_ftransition_dip1000:
555627f7eb2Smrg global.params.vsafe = value;
556627f7eb2Smrg global.params.useDIP25 = value;
557627f7eb2Smrg break;
558627f7eb2Smrg
559627f7eb2Smrg case OPT_ftransition_dip25:
560627f7eb2Smrg global.params.useDIP25 = value;
561627f7eb2Smrg break;
562627f7eb2Smrg
563627f7eb2Smrg case OPT_ftransition_field:
564627f7eb2Smrg global.params.vfield = value;
565627f7eb2Smrg break;
566627f7eb2Smrg
567627f7eb2Smrg case OPT_ftransition_import:
568627f7eb2Smrg global.params.bug10378 = value;
569627f7eb2Smrg break;
570627f7eb2Smrg
571627f7eb2Smrg case OPT_ftransition_nogc:
572627f7eb2Smrg global.params.vgc = value;
573627f7eb2Smrg break;
574627f7eb2Smrg
575627f7eb2Smrg case OPT_ftransition_tls:
576627f7eb2Smrg global.params.vtls = value;
577627f7eb2Smrg break;
578627f7eb2Smrg
579627f7eb2Smrg case OPT_funittest:
580627f7eb2Smrg global.params.useUnitTests = value;
581627f7eb2Smrg break;
582627f7eb2Smrg
583627f7eb2Smrg case OPT_fversion_:
584627f7eb2Smrg if (ISDIGIT (arg[0]))
585627f7eb2Smrg {
586627f7eb2Smrg int level = integral_argument (arg);
587627f7eb2Smrg if (level != -1)
588627f7eb2Smrg {
589627f7eb2Smrg VersionCondition::setGlobalLevel (level);
590627f7eb2Smrg break;
591627f7eb2Smrg }
592627f7eb2Smrg }
593627f7eb2Smrg
594627f7eb2Smrg if (Identifier::isValidIdentifier (CONST_CAST (char *, arg)))
595627f7eb2Smrg {
596627f7eb2Smrg VersionCondition::addGlobalIdent (arg);
597627f7eb2Smrg break;
598627f7eb2Smrg }
599627f7eb2Smrg
600*4c3eb207Smrg error ("bad argument for %<-fversion%>: %qs", arg);
601627f7eb2Smrg break;
602627f7eb2Smrg
603627f7eb2Smrg case OPT_H:
604627f7eb2Smrg global.params.doHdrGeneration = true;
605627f7eb2Smrg break;
606627f7eb2Smrg
607627f7eb2Smrg case OPT_Hd:
608627f7eb2Smrg global.params.doHdrGeneration = true;
609627f7eb2Smrg global.params.hdrdir = arg;
610627f7eb2Smrg break;
611627f7eb2Smrg
612627f7eb2Smrg case OPT_Hf:
613627f7eb2Smrg global.params.doHdrGeneration = true;
614627f7eb2Smrg global.params.hdrname = arg;
615627f7eb2Smrg break;
616627f7eb2Smrg
617627f7eb2Smrg case OPT_imultilib:
618627f7eb2Smrg d_option.multilib = arg;
619627f7eb2Smrg break;
620627f7eb2Smrg
621627f7eb2Smrg case OPT_iprefix:
622627f7eb2Smrg d_option.prefix = arg;
623627f7eb2Smrg break;
624627f7eb2Smrg
625627f7eb2Smrg case OPT_I:
626627f7eb2Smrg global.params.imppath->push (arg);
627627f7eb2Smrg break;
628627f7eb2Smrg
629627f7eb2Smrg case OPT_J:
630627f7eb2Smrg global.params.fileImppath->push (arg);
631627f7eb2Smrg break;
632627f7eb2Smrg
633627f7eb2Smrg case OPT_MM:
634627f7eb2Smrg d_option.deps_skip_system = true;
635627f7eb2Smrg /* Fall through. */
636627f7eb2Smrg
637627f7eb2Smrg case OPT_M:
638627f7eb2Smrg d_option.deps = true;
639627f7eb2Smrg break;
640627f7eb2Smrg
641627f7eb2Smrg case OPT_MMD:
642627f7eb2Smrg d_option.deps_skip_system = true;
643627f7eb2Smrg /* Fall through. */
644627f7eb2Smrg
645627f7eb2Smrg case OPT_MD:
646627f7eb2Smrg d_option.deps = true;
647627f7eb2Smrg d_option.deps_filename = arg;
648627f7eb2Smrg break;
649627f7eb2Smrg
650627f7eb2Smrg case OPT_MF:
651627f7eb2Smrg /* If specified multiple times, last one wins. */
652627f7eb2Smrg d_option.deps_filename_user = arg;
653627f7eb2Smrg break;
654627f7eb2Smrg
655627f7eb2Smrg case OPT_MP:
656627f7eb2Smrg d_option.deps_phony = true;
657627f7eb2Smrg break;
658627f7eb2Smrg
659627f7eb2Smrg case OPT_MQ:
660627f7eb2Smrg deps_add_target (arg, true);
661627f7eb2Smrg break;
662627f7eb2Smrg
663627f7eb2Smrg case OPT_MT:
664627f7eb2Smrg deps_add_target (arg, false);
665627f7eb2Smrg break;
666627f7eb2Smrg
667627f7eb2Smrg case OPT_nostdinc:
668627f7eb2Smrg d_option.stdinc = false;
669627f7eb2Smrg break;
670627f7eb2Smrg
671627f7eb2Smrg case OPT_v:
672627f7eb2Smrg global.params.verbose = value;
673627f7eb2Smrg break;
674627f7eb2Smrg
675627f7eb2Smrg case OPT_Wall:
676627f7eb2Smrg if (value)
677627f7eb2Smrg global.params.warnings = DIAGNOSTICinform;
678627f7eb2Smrg break;
679627f7eb2Smrg
680627f7eb2Smrg case OPT_Wdeprecated:
681627f7eb2Smrg global.params.useDeprecated = value ? DIAGNOSTICinform : DIAGNOSTICoff;
682627f7eb2Smrg break;
683627f7eb2Smrg
684627f7eb2Smrg case OPT_Werror:
685627f7eb2Smrg if (value)
686627f7eb2Smrg global.params.warnings = DIAGNOSTICerror;
687627f7eb2Smrg break;
688627f7eb2Smrg
689627f7eb2Smrg case OPT_Wspeculative:
690627f7eb2Smrg if (value)
691627f7eb2Smrg global.params.showGaggedErrors = 1;
692627f7eb2Smrg break;
693627f7eb2Smrg
694627f7eb2Smrg case OPT_Xf:
695627f7eb2Smrg global.params.jsonfilename = arg;
696627f7eb2Smrg /* Fall through. */
697627f7eb2Smrg
698627f7eb2Smrg case OPT_X:
699627f7eb2Smrg global.params.doJsonGeneration = true;
700627f7eb2Smrg break;
701627f7eb2Smrg
702627f7eb2Smrg default:
703627f7eb2Smrg break;
704627f7eb2Smrg }
705627f7eb2Smrg
706627f7eb2Smrg D_handle_option_auto (&global_options, &global_options_set,
707627f7eb2Smrg scode, arg, value,
708627f7eb2Smrg d_option_lang_mask (), kind,
709627f7eb2Smrg loc, handlers, global_dc);
710627f7eb2Smrg
711627f7eb2Smrg return result;
712627f7eb2Smrg }
713627f7eb2Smrg
714627f7eb2Smrg /* Implements the lang_hooks.post_options routine for language D.
715627f7eb2Smrg Deal with any options that imply the turning on/off of features.
716627f7eb2Smrg FN is the main input filename passed on the command line. */
717627f7eb2Smrg
718627f7eb2Smrg static bool
d_post_options(const char ** fn)719627f7eb2Smrg d_post_options (const char ** fn)
720627f7eb2Smrg {
721627f7eb2Smrg /* Verify the input file name. */
722627f7eb2Smrg const char *filename = *fn;
723627f7eb2Smrg if (!filename || strcmp (filename, "-") == 0)
724627f7eb2Smrg filename = "";
725627f7eb2Smrg
726627f7eb2Smrg /* The front end considers the first input file to be the main one. */
727627f7eb2Smrg *fn = filename;
728627f7eb2Smrg
729627f7eb2Smrg /* Release mode doesn't turn off bounds checking for safe functions. */
730627f7eb2Smrg if (global.params.useArrayBounds == BOUNDSCHECKdefault)
731627f7eb2Smrg {
732627f7eb2Smrg global.params.useArrayBounds = global.params.release
733627f7eb2Smrg ? BOUNDSCHECKsafeonly : BOUNDSCHECKon;
734627f7eb2Smrg flag_bounds_check = !global.params.release;
735627f7eb2Smrg }
736627f7eb2Smrg
737627f7eb2Smrg if (global.params.release)
738627f7eb2Smrg {
739627f7eb2Smrg if (!global_options_set.x_flag_invariants)
740627f7eb2Smrg global.params.useInvariants = false;
741627f7eb2Smrg
742627f7eb2Smrg if (!global_options_set.x_flag_preconditions)
743627f7eb2Smrg global.params.useIn = false;
744627f7eb2Smrg
745627f7eb2Smrg if (!global_options_set.x_flag_postconditions)
746627f7eb2Smrg global.params.useOut = false;
747627f7eb2Smrg
748627f7eb2Smrg if (!global_options_set.x_flag_assert)
749627f7eb2Smrg global.params.useAssert = false;
750627f7eb2Smrg
751627f7eb2Smrg if (!global_options_set.x_flag_switch_errors)
752627f7eb2Smrg global.params.useSwitchError = false;
753627f7eb2Smrg }
754627f7eb2Smrg
755627f7eb2Smrg if (global.params.betterC)
756627f7eb2Smrg {
757627f7eb2Smrg if (!global_options_set.x_flag_moduleinfo)
758627f7eb2Smrg global.params.useModuleInfo = false;
759627f7eb2Smrg
760627f7eb2Smrg if (!global_options_set.x_flag_rtti)
761627f7eb2Smrg global.params.useTypeInfo = false;
762627f7eb2Smrg
763627f7eb2Smrg if (!global_options_set.x_flag_exceptions)
764627f7eb2Smrg global.params.useExceptions = false;
765627f7eb2Smrg
766627f7eb2Smrg global.params.checkAction = CHECKACTION_halt;
767627f7eb2Smrg }
768627f7eb2Smrg
769627f7eb2Smrg /* Turn off partitioning unless it was explicitly requested, as it doesn't
770627f7eb2Smrg work with D exception chaining, where EH handler uses LSDA to determine
771627f7eb2Smrg whether two thrown exception are in the same context. */
772627f7eb2Smrg if (!global_options_set.x_flag_reorder_blocks_and_partition)
773627f7eb2Smrg global_options.x_flag_reorder_blocks_and_partition = 0;
774627f7eb2Smrg
775627f7eb2Smrg /* Error about use of deprecated features. */
776627f7eb2Smrg if (global.params.useDeprecated == DIAGNOSTICinform
777627f7eb2Smrg && global.params.warnings == DIAGNOSTICerror)
778627f7eb2Smrg global.params.useDeprecated = DIAGNOSTICerror;
779627f7eb2Smrg
780627f7eb2Smrg /* Make -fmax-errors visible to frontend's diagnostic machinery. */
781627f7eb2Smrg if (global_options_set.x_flag_max_errors)
782627f7eb2Smrg global.errorLimit = flag_max_errors;
783627f7eb2Smrg
784*4c3eb207Smrg if (flag_excess_precision == EXCESS_PRECISION_DEFAULT)
785*4c3eb207Smrg flag_excess_precision = EXCESS_PRECISION_STANDARD;
786627f7eb2Smrg
787627f7eb2Smrg if (global.params.useUnitTests)
788627f7eb2Smrg global.params.useAssert = true;
789627f7eb2Smrg
790627f7eb2Smrg global.params.symdebug = write_symbols != NO_DEBUG;
791627f7eb2Smrg global.params.useInline = flag_inline_functions;
792627f7eb2Smrg global.params.showColumns = flag_show_column;
793627f7eb2Smrg
794627f7eb2Smrg if (global.params.useInline)
795627f7eb2Smrg global.params.hdrStripPlainFunctions = false;
796627f7eb2Smrg
797627f7eb2Smrg global.params.obj = !flag_syntax_only;
798627f7eb2Smrg
799627f7eb2Smrg /* Has no effect yet. */
800627f7eb2Smrg global.params.pic = flag_pic != 0;
801627f7eb2Smrg
802627f7eb2Smrg if (warn_return_type == -1)
803627f7eb2Smrg warn_return_type = 0;
804627f7eb2Smrg
805627f7eb2Smrg return false;
806627f7eb2Smrg }
807627f7eb2Smrg
808627f7eb2Smrg /* Return TRUE if an operand OP of a given TYPE being copied has no data.
809627f7eb2Smrg The middle-end does a similar check with zero sized types. */
810627f7eb2Smrg
811627f7eb2Smrg static bool
empty_modify_p(tree type,tree op)812627f7eb2Smrg empty_modify_p (tree type, tree op)
813627f7eb2Smrg {
814627f7eb2Smrg tree_code code = TREE_CODE (op);
815627f7eb2Smrg switch (code)
816627f7eb2Smrg {
817627f7eb2Smrg case COMPOUND_EXPR:
818627f7eb2Smrg return empty_modify_p (type, TREE_OPERAND (op, 1));
819627f7eb2Smrg
820627f7eb2Smrg case CONSTRUCTOR:
821627f7eb2Smrg /* Non-empty construcors are valid. */
822627f7eb2Smrg if (CONSTRUCTOR_NELTS (op) != 0 || TREE_CLOBBER_P (op))
823627f7eb2Smrg return false;
824627f7eb2Smrg break;
825627f7eb2Smrg
826627f7eb2Smrg case CALL_EXPR:
827627f7eb2Smrg /* Leave nrvo alone because it isn't a copy. */
828627f7eb2Smrg if (CALL_EXPR_RETURN_SLOT_OPT (op))
829627f7eb2Smrg return false;
830627f7eb2Smrg break;
831627f7eb2Smrg
832627f7eb2Smrg default:
833627f7eb2Smrg /* If the operand doesn't have a simple form. */
834627f7eb2Smrg if (!is_gimple_lvalue (op) && !INDIRECT_REF_P (op))
835627f7eb2Smrg return false;
836627f7eb2Smrg break;
837627f7eb2Smrg }
838627f7eb2Smrg
839627f7eb2Smrg return empty_aggregate_p (type);
840627f7eb2Smrg }
841627f7eb2Smrg
842627f7eb2Smrg /* Implements the lang_hooks.gimplify_expr routine for language D.
843627f7eb2Smrg Do gimplification of D specific expression trees in EXPR_P. */
844627f7eb2Smrg
845627f7eb2Smrg int
d_gimplify_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p ATTRIBUTE_UNUSED)846627f7eb2Smrg d_gimplify_expr (tree *expr_p, gimple_seq *pre_p,
847627f7eb2Smrg gimple_seq *post_p ATTRIBUTE_UNUSED)
848627f7eb2Smrg {
849627f7eb2Smrg tree_code code = TREE_CODE (*expr_p);
850627f7eb2Smrg enum gimplify_status ret = GS_UNHANDLED;
851627f7eb2Smrg tree op0, op1;
852627f7eb2Smrg tree type;
853627f7eb2Smrg
854627f7eb2Smrg switch (code)
855627f7eb2Smrg {
856627f7eb2Smrg case INIT_EXPR:
857627f7eb2Smrg case MODIFY_EXPR:
858627f7eb2Smrg op0 = TREE_OPERAND (*expr_p, 0);
859627f7eb2Smrg op1 = TREE_OPERAND (*expr_p, 1);
860627f7eb2Smrg
861627f7eb2Smrg if (!error_operand_p (op0) && !error_operand_p (op1)
862627f7eb2Smrg && (AGGREGATE_TYPE_P (TREE_TYPE (op0))
863627f7eb2Smrg || AGGREGATE_TYPE_P (TREE_TYPE (op1)))
864627f7eb2Smrg && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
865627f7eb2Smrg {
866627f7eb2Smrg /* If the back end isn't clever enough to know that the lhs and rhs
867627f7eb2Smrg types are the same, add an explicit conversion. */
868627f7eb2Smrg TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
869627f7eb2Smrg TREE_TYPE (op0), op1);
870627f7eb2Smrg ret = GS_OK;
871627f7eb2Smrg }
872627f7eb2Smrg else if (empty_modify_p (TREE_TYPE (op0), op1))
873627f7eb2Smrg {
874627f7eb2Smrg /* Remove any copies of empty aggregates. */
875627f7eb2Smrg gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
876627f7eb2Smrg is_gimple_lvalue, fb_lvalue);
877627f7eb2Smrg
878627f7eb2Smrg if (TREE_SIDE_EFFECTS (op1))
879627f7eb2Smrg gimplify_and_add (op1, pre_p);
880627f7eb2Smrg
881627f7eb2Smrg *expr_p = TREE_OPERAND (*expr_p, 0);
882627f7eb2Smrg ret = GS_OK;
883627f7eb2Smrg }
884627f7eb2Smrg break;
885627f7eb2Smrg
886627f7eb2Smrg case ADDR_EXPR:
887627f7eb2Smrg op0 = TREE_OPERAND (*expr_p, 0);
888627f7eb2Smrg /* Constructors are not lvalues, so make them one. */
889627f7eb2Smrg if (TREE_CODE (op0) == CONSTRUCTOR)
890627f7eb2Smrg {
891627f7eb2Smrg TREE_OPERAND (*expr_p, 0) = force_target_expr (op0);
892627f7eb2Smrg ret = GS_OK;
893627f7eb2Smrg }
894627f7eb2Smrg break;
895627f7eb2Smrg
896627f7eb2Smrg case CALL_EXPR:
897627f7eb2Smrg if (CALL_EXPR_ARGS_ORDERED (*expr_p))
898627f7eb2Smrg {
899627f7eb2Smrg /* Strictly evaluate all arguments from left to right. */
900627f7eb2Smrg int nargs = call_expr_nargs (*expr_p);
901627f7eb2Smrg location_t loc = EXPR_LOC_OR_LOC (*expr_p, input_location);
902627f7eb2Smrg
903627f7eb2Smrg /* No need to enforce evaluation order if only one argument. */
904627f7eb2Smrg if (nargs < 2)
905627f7eb2Smrg break;
906627f7eb2Smrg
907627f7eb2Smrg /* Or if all arguments are already free of side-effects. */
908627f7eb2Smrg bool has_side_effects = false;
909627f7eb2Smrg for (int i = 0; i < nargs; i++)
910627f7eb2Smrg {
911627f7eb2Smrg if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, i)))
912627f7eb2Smrg {
913627f7eb2Smrg has_side_effects = true;
914627f7eb2Smrg break;
915627f7eb2Smrg }
916627f7eb2Smrg }
917627f7eb2Smrg
918627f7eb2Smrg if (!has_side_effects)
919627f7eb2Smrg break;
920627f7eb2Smrg
921627f7eb2Smrg /* Leave the last argument for gimplify_call_expr. */
922627f7eb2Smrg for (int i = 0; i < nargs - 1; i++)
923627f7eb2Smrg {
924627f7eb2Smrg tree new_arg = CALL_EXPR_ARG (*expr_p, i);
925627f7eb2Smrg
926627f7eb2Smrg /* If argument has a side-effect, gimplify_arg will handle it. */
927627f7eb2Smrg if (gimplify_arg (&new_arg, pre_p, loc) == GS_ERROR)
928627f7eb2Smrg ret = GS_ERROR;
929627f7eb2Smrg
930627f7eb2Smrg /* Even if an argument itself doesn't have any side-effects, it
931627f7eb2Smrg might be altered by another argument in the list. */
932627f7eb2Smrg if (new_arg == CALL_EXPR_ARG (*expr_p, i)
933627f7eb2Smrg && !really_constant_p (new_arg))
934627f7eb2Smrg new_arg = get_formal_tmp_var (new_arg, pre_p);
935627f7eb2Smrg
936627f7eb2Smrg CALL_EXPR_ARG (*expr_p, i) = new_arg;
937627f7eb2Smrg }
938627f7eb2Smrg
939627f7eb2Smrg if (ret != GS_ERROR)
940627f7eb2Smrg ret = GS_OK;
941627f7eb2Smrg }
942627f7eb2Smrg break;
943627f7eb2Smrg
944627f7eb2Smrg case UNSIGNED_RSHIFT_EXPR:
945627f7eb2Smrg /* Convert op0 to an unsigned type. */
946627f7eb2Smrg op0 = TREE_OPERAND (*expr_p, 0);
947627f7eb2Smrg op1 = TREE_OPERAND (*expr_p, 1);
948627f7eb2Smrg
949627f7eb2Smrg type = d_unsigned_type (TREE_TYPE (op0));
950627f7eb2Smrg
951627f7eb2Smrg *expr_p = convert (TREE_TYPE (*expr_p),
952627f7eb2Smrg build2 (RSHIFT_EXPR, type, convert (type, op0), op1));
953627f7eb2Smrg ret = GS_OK;
954627f7eb2Smrg break;
955627f7eb2Smrg
956627f7eb2Smrg case FLOAT_MOD_EXPR:
957627f7eb2Smrg gcc_unreachable ();
958627f7eb2Smrg
959627f7eb2Smrg default:
960627f7eb2Smrg break;
961627f7eb2Smrg }
962627f7eb2Smrg
963627f7eb2Smrg return ret;
964627f7eb2Smrg }
965627f7eb2Smrg
966627f7eb2Smrg /* Add the module M to the list of modules that may declare GCC builtins.
967627f7eb2Smrg These are scanned after first semantic and before codegen passes.
968627f7eb2Smrg See d_maybe_set_builtin() for the implementation. */
969627f7eb2Smrg
970627f7eb2Smrg void
d_add_builtin_module(Module * m)971627f7eb2Smrg d_add_builtin_module (Module *m)
972627f7eb2Smrg {
973627f7eb2Smrg builtin_modules.push (m);
974627f7eb2Smrg }
975627f7eb2Smrg
976627f7eb2Smrg /* Record the entrypoint module ENTRY which will be compiled in the current
977627f7eb2Smrg compilation. ROOT is the module scope where this was requested from. */
978627f7eb2Smrg
979627f7eb2Smrg void
d_add_entrypoint_module(Module * entry,Module * root)980627f7eb2Smrg d_add_entrypoint_module (Module *entry, Module *root)
981627f7eb2Smrg {
982627f7eb2Smrg /* We are emitting this straight to object file. */
983627f7eb2Smrg entrypoint_module = entry;
984627f7eb2Smrg entrypoint_root_module = root;
985627f7eb2Smrg }
986627f7eb2Smrg
987627f7eb2Smrg /* Implements the lang_hooks.parse_file routine for language D. */
988627f7eb2Smrg
989627f7eb2Smrg void
d_parse_file(void)990627f7eb2Smrg d_parse_file (void)
991627f7eb2Smrg {
992627f7eb2Smrg if (global.params.verbose)
993627f7eb2Smrg {
994627f7eb2Smrg message ("binary %s", global.params.argv0);
995627f7eb2Smrg message ("version %s", global.version);
996627f7eb2Smrg
997627f7eb2Smrg if (global.params.versionids)
998627f7eb2Smrg {
999627f7eb2Smrg OutBuffer buf;
1000627f7eb2Smrg buf.writestring ("predefs ");
1001627f7eb2Smrg for (size_t i = 0; i < global.params.versionids->dim; i++)
1002627f7eb2Smrg {
1003627f7eb2Smrg const char *s = (*global.params.versionids)[i];
1004627f7eb2Smrg buf.writestring (" ");
1005627f7eb2Smrg buf.writestring (s);
1006627f7eb2Smrg }
1007627f7eb2Smrg
1008627f7eb2Smrg message ("%.*s", (int) buf.offset, (char *) buf.data);
1009627f7eb2Smrg }
1010627f7eb2Smrg }
1011627f7eb2Smrg
1012627f7eb2Smrg /* Start the main input file, if the debug writer wants it. */
1013627f7eb2Smrg if (debug_hooks->start_end_main_source_file)
1014627f7eb2Smrg debug_hooks->start_source_file (0, main_input_filename);
1015627f7eb2Smrg
1016627f7eb2Smrg /* Create Module's for all sources we will load. */
1017627f7eb2Smrg Modules modules;
1018627f7eb2Smrg modules.reserve (num_in_fnames);
1019627f7eb2Smrg
1020627f7eb2Smrg /* In this mode, the first file name is supposed to be a duplicate
1021627f7eb2Smrg of one of the input files. */
1022627f7eb2Smrg if (d_option.fonly && strcmp (d_option.fonly, main_input_filename) != 0)
1023*4c3eb207Smrg error ("%<-fonly=%> argument is different from first input file name");
1024627f7eb2Smrg
1025627f7eb2Smrg for (size_t i = 0; i < num_in_fnames; i++)
1026627f7eb2Smrg {
1027627f7eb2Smrg if (strcmp (in_fnames[i], "-") == 0)
1028627f7eb2Smrg {
1029*4c3eb207Smrg /* Load the entire contents of stdin into memory. 8 kilobytes should
1030*4c3eb207Smrg be a good enough initial size, but double on each iteration.
1031*4c3eb207Smrg 16 bytes are added for the final '\n' and 15 bytes of padding. */
1032*4c3eb207Smrg ssize_t size = 8 * 1024;
1033*4c3eb207Smrg uchar *buffer = XNEWVEC (uchar, size + 16);
1034*4c3eb207Smrg ssize_t len = 0;
1035*4c3eb207Smrg ssize_t count;
1036627f7eb2Smrg
1037*4c3eb207Smrg while ((count = read (STDIN_FILENO, buffer + len, size - len)) > 0)
1038*4c3eb207Smrg {
1039*4c3eb207Smrg len += count;
1040*4c3eb207Smrg if (len == size)
1041*4c3eb207Smrg {
1042*4c3eb207Smrg size *= 2;
1043*4c3eb207Smrg buffer = XRESIZEVEC (uchar, buffer, size + 16);
1044*4c3eb207Smrg }
1045*4c3eb207Smrg }
1046*4c3eb207Smrg
1047*4c3eb207Smrg if (count < 0)
1048*4c3eb207Smrg {
1049*4c3eb207Smrg error (Loc ("stdin", 0, 0), "%s", xstrerror (errno));
1050*4c3eb207Smrg free (buffer);
1051*4c3eb207Smrg continue;
1052*4c3eb207Smrg }
1053*4c3eb207Smrg
1054*4c3eb207Smrg /* Handling stdin, generate a unique name for the module. */
1055627f7eb2Smrg Module *m = Module::create (in_fnames[i],
1056627f7eb2Smrg Identifier::generateId ("__stdin"),
1057627f7eb2Smrg global.params.doDocComments,
1058627f7eb2Smrg global.params.doHdrGeneration);
1059627f7eb2Smrg modules.push (m);
1060627f7eb2Smrg
1061627f7eb2Smrg /* Overwrite the source file for the module, the one created by
1062627f7eb2Smrg Module::create would have a forced a `.d' suffix. */
1063627f7eb2Smrg m->srcfile = File::create ("<stdin>");
1064*4c3eb207Smrg m->srcfile->len = len;
1065*4c3eb207Smrg m->srcfile->buffer = buffer;
1066627f7eb2Smrg }
1067627f7eb2Smrg else
1068627f7eb2Smrg {
1069627f7eb2Smrg /* Handling a D source file, strip off the path and extension. */
1070627f7eb2Smrg const char *basename = FileName::name (in_fnames[i]);
1071627f7eb2Smrg const char *name = FileName::removeExt (basename);
1072627f7eb2Smrg
1073627f7eb2Smrg Module *m = Module::create (in_fnames[i], Identifier::idPool (name),
1074627f7eb2Smrg global.params.doDocComments,
1075627f7eb2Smrg global.params.doHdrGeneration);
1076627f7eb2Smrg modules.push (m);
1077627f7eb2Smrg FileName::free (name);
1078627f7eb2Smrg }
1079627f7eb2Smrg }
1080627f7eb2Smrg
1081627f7eb2Smrg /* Read all D source files. */
1082627f7eb2Smrg for (size_t i = 0; i < modules.dim; i++)
1083627f7eb2Smrg {
1084627f7eb2Smrg Module *m = modules[i];
1085627f7eb2Smrg m->read (Loc ());
1086627f7eb2Smrg }
1087627f7eb2Smrg
1088627f7eb2Smrg /* Parse all D source files. */
1089627f7eb2Smrg for (size_t i = 0; i < modules.dim; i++)
1090627f7eb2Smrg {
1091627f7eb2Smrg Module *m = modules[i];
1092627f7eb2Smrg
1093627f7eb2Smrg if (global.params.verbose)
1094627f7eb2Smrg message ("parse %s", m->toChars ());
1095627f7eb2Smrg
1096627f7eb2Smrg if (!Module::rootModule)
1097627f7eb2Smrg Module::rootModule = m;
1098627f7eb2Smrg
1099627f7eb2Smrg m->importedFrom = m;
1100627f7eb2Smrg m->parse ();
1101627f7eb2Smrg Compiler::loadModule (m);
1102627f7eb2Smrg
1103627f7eb2Smrg if (m->isDocFile)
1104627f7eb2Smrg {
1105627f7eb2Smrg gendocfile (m);
1106627f7eb2Smrg /* Remove M from list of modules. */
1107627f7eb2Smrg modules.remove (i);
1108627f7eb2Smrg i--;
1109627f7eb2Smrg }
1110627f7eb2Smrg }
1111627f7eb2Smrg
1112627f7eb2Smrg /* Load the module containing D main. */
1113627f7eb2Smrg if (global.params.addMain)
1114627f7eb2Smrg {
1115627f7eb2Smrg unsigned errors = global.startGagging ();
1116627f7eb2Smrg Module *m = Module::load (Loc (), NULL, Identifier::idPool ("__main"));
1117627f7eb2Smrg
1118627f7eb2Smrg if (! global.endGagging (errors))
1119627f7eb2Smrg {
1120627f7eb2Smrg m->importedFrom = m;
1121627f7eb2Smrg modules.push (m);
1122627f7eb2Smrg }
1123627f7eb2Smrg }
1124627f7eb2Smrg
1125627f7eb2Smrg if (global.errors)
1126627f7eb2Smrg goto had_errors;
1127627f7eb2Smrg
1128627f7eb2Smrg if (global.params.doHdrGeneration)
1129627f7eb2Smrg {
1130627f7eb2Smrg /* Generate 'header' import files. Since 'header' import files must be
1131627f7eb2Smrg independent of command line switches and what else is imported, they
1132627f7eb2Smrg are generated before any semantic analysis. */
1133627f7eb2Smrg for (size_t i = 0; i < modules.dim; i++)
1134627f7eb2Smrg {
1135627f7eb2Smrg Module *m = modules[i];
1136627f7eb2Smrg if (d_option.fonly && m != Module::rootModule)
1137627f7eb2Smrg continue;
1138627f7eb2Smrg
1139627f7eb2Smrg if (global.params.verbose)
1140627f7eb2Smrg message ("import %s", m->toChars ());
1141627f7eb2Smrg
1142627f7eb2Smrg genhdrfile (m);
1143627f7eb2Smrg }
1144627f7eb2Smrg }
1145627f7eb2Smrg
1146627f7eb2Smrg if (global.errors)
1147627f7eb2Smrg goto had_errors;
1148627f7eb2Smrg
1149627f7eb2Smrg /* Load all unconditional imports for better symbol resolving. */
1150627f7eb2Smrg for (size_t i = 0; i < modules.dim; i++)
1151627f7eb2Smrg {
1152627f7eb2Smrg Module *m = modules[i];
1153627f7eb2Smrg
1154627f7eb2Smrg if (global.params.verbose)
1155627f7eb2Smrg message ("importall %s", m->toChars ());
1156627f7eb2Smrg
1157627f7eb2Smrg m->importAll (NULL);
1158627f7eb2Smrg }
1159627f7eb2Smrg
1160627f7eb2Smrg if (global.errors)
1161627f7eb2Smrg goto had_errors;
1162627f7eb2Smrg
1163627f7eb2Smrg /* Do semantic analysis. */
1164627f7eb2Smrg doing_semantic_analysis_p = true;
1165627f7eb2Smrg
1166627f7eb2Smrg for (size_t i = 0; i < modules.dim; i++)
1167627f7eb2Smrg {
1168627f7eb2Smrg Module *m = modules[i];
1169627f7eb2Smrg
1170627f7eb2Smrg if (global.params.verbose)
1171627f7eb2Smrg message ("semantic %s", m->toChars ());
1172627f7eb2Smrg
1173627f7eb2Smrg m->semantic (NULL);
1174627f7eb2Smrg }
1175627f7eb2Smrg
1176627f7eb2Smrg /* Do deferred semantic analysis. */
1177627f7eb2Smrg Module::dprogress = 1;
1178627f7eb2Smrg Module::runDeferredSemantic ();
1179627f7eb2Smrg
1180627f7eb2Smrg if (Module::deferred.dim)
1181627f7eb2Smrg {
1182627f7eb2Smrg for (size_t i = 0; i < Module::deferred.dim; i++)
1183627f7eb2Smrg {
1184627f7eb2Smrg Dsymbol *sd = Module::deferred[i];
1185627f7eb2Smrg error_at (make_location_t (sd->loc),
1186627f7eb2Smrg "unable to resolve forward reference in definition");
1187627f7eb2Smrg }
1188627f7eb2Smrg }
1189627f7eb2Smrg
1190627f7eb2Smrg /* Process all built-in modules or functions now for CTFE. */
1191627f7eb2Smrg while (builtin_modules.dim != 0)
1192627f7eb2Smrg {
1193627f7eb2Smrg Module *m = builtin_modules.pop ();
1194627f7eb2Smrg d_maybe_set_builtin (m);
1195627f7eb2Smrg }
1196627f7eb2Smrg
1197627f7eb2Smrg /* Do pass 2 semantic analysis. */
1198627f7eb2Smrg for (size_t i = 0; i < modules.dim; i++)
1199627f7eb2Smrg {
1200627f7eb2Smrg Module *m = modules[i];
1201627f7eb2Smrg
1202627f7eb2Smrg if (global.params.verbose)
1203627f7eb2Smrg message ("semantic2 %s", m->toChars ());
1204627f7eb2Smrg
1205627f7eb2Smrg m->semantic2 (NULL);
1206627f7eb2Smrg }
1207627f7eb2Smrg
1208627f7eb2Smrg Module::runDeferredSemantic2 ();
1209627f7eb2Smrg
1210627f7eb2Smrg if (global.errors)
1211627f7eb2Smrg goto had_errors;
1212627f7eb2Smrg
1213627f7eb2Smrg /* Do pass 3 semantic analysis. */
1214627f7eb2Smrg for (size_t i = 0; i < modules.dim; i++)
1215627f7eb2Smrg {
1216627f7eb2Smrg Module *m = modules[i];
1217627f7eb2Smrg
1218627f7eb2Smrg if (global.params.verbose)
1219627f7eb2Smrg message ("semantic3 %s", m->toChars ());
1220627f7eb2Smrg
1221627f7eb2Smrg m->semantic3 (NULL);
1222627f7eb2Smrg }
1223627f7eb2Smrg
1224627f7eb2Smrg Module::runDeferredSemantic3 ();
1225627f7eb2Smrg
1226627f7eb2Smrg /* Check again, incase semantic3 pass loaded any more modules. */
1227627f7eb2Smrg while (builtin_modules.dim != 0)
1228627f7eb2Smrg {
1229627f7eb2Smrg Module *m = builtin_modules.pop ();
1230627f7eb2Smrg d_maybe_set_builtin (m);
1231627f7eb2Smrg }
1232627f7eb2Smrg
1233627f7eb2Smrg /* Do not attempt to generate output files if errors or warnings occurred. */
1234627f7eb2Smrg if (global.errors || global.warnings)
1235627f7eb2Smrg goto had_errors;
1236627f7eb2Smrg
1237627f7eb2Smrg /* Generate output files. */
1238627f7eb2Smrg doing_semantic_analysis_p = false;
1239627f7eb2Smrg
1240627f7eb2Smrg if (Module::rootModule)
1241627f7eb2Smrg {
1242627f7eb2Smrg /* Declare the name of the root module as the first global name in order
1243627f7eb2Smrg to make the middle-end fully deterministic. */
1244627f7eb2Smrg OutBuffer buf;
1245627f7eb2Smrg mangleToBuffer (Module::rootModule, &buf);
1246627f7eb2Smrg first_global_object_name = buf.extractString ();
1247627f7eb2Smrg }
1248627f7eb2Smrg
1249627f7eb2Smrg /* Make dependencies. */
1250627f7eb2Smrg if (d_option.deps)
1251627f7eb2Smrg {
1252627f7eb2Smrg OutBuffer buf;
1253627f7eb2Smrg
1254627f7eb2Smrg for (size_t i = 0; i < modules.dim; i++)
1255627f7eb2Smrg deps_write (modules[i], &buf);
1256627f7eb2Smrg
1257627f7eb2Smrg /* -MF <arg> overrides -M[M]D. */
1258627f7eb2Smrg if (d_option.deps_filename_user)
1259627f7eb2Smrg d_option.deps_filename = d_option.deps_filename_user;
1260627f7eb2Smrg
1261627f7eb2Smrg if (d_option.deps_filename)
1262627f7eb2Smrg {
1263627f7eb2Smrg File *fdeps = File::create (d_option.deps_filename);
1264627f7eb2Smrg fdeps->setbuffer ((void *) buf.data, buf.offset);
1265627f7eb2Smrg fdeps->ref = 1;
1266627f7eb2Smrg writeFile (Loc (), fdeps);
1267627f7eb2Smrg }
1268627f7eb2Smrg else
1269627f7eb2Smrg message ("%.*s", (int) buf.offset, (char *) buf.data);
1270627f7eb2Smrg }
1271627f7eb2Smrg
1272627f7eb2Smrg /* Generate JSON files. */
1273627f7eb2Smrg if (global.params.doJsonGeneration)
1274627f7eb2Smrg {
1275627f7eb2Smrg OutBuffer buf;
1276627f7eb2Smrg json_generate (&buf, &modules);
1277627f7eb2Smrg
1278627f7eb2Smrg const char *name = global.params.jsonfilename;
1279627f7eb2Smrg
1280627f7eb2Smrg if (name && (name[0] != '-' || name[1] != '\0'))
1281627f7eb2Smrg {
1282627f7eb2Smrg const char *nameext = FileName::defaultExt (name, global.json_ext);
1283627f7eb2Smrg File *fjson = File::create (nameext);
1284627f7eb2Smrg fjson->setbuffer ((void *) buf.data, buf.offset);
1285627f7eb2Smrg fjson->ref = 1;
1286627f7eb2Smrg writeFile (Loc (), fjson);
1287627f7eb2Smrg }
1288627f7eb2Smrg else
1289627f7eb2Smrg message ("%.*s", (int) buf.offset, (char *) buf.data);
1290627f7eb2Smrg }
1291627f7eb2Smrg
1292627f7eb2Smrg /* Generate Ddoc files. */
1293627f7eb2Smrg if (global.params.doDocComments && !global.errors && !errorcount)
1294627f7eb2Smrg {
1295627f7eb2Smrg for (size_t i = 0; i < modules.dim; i++)
1296627f7eb2Smrg {
1297627f7eb2Smrg Module *m = modules[i];
1298627f7eb2Smrg gendocfile (m);
1299627f7eb2Smrg }
1300627f7eb2Smrg }
1301627f7eb2Smrg
1302627f7eb2Smrg /* Handle -fdump-d-original. */
1303627f7eb2Smrg if (global.params.vcg_ast)
1304627f7eb2Smrg {
1305627f7eb2Smrg for (size_t i = 0; i < modules.dim; i++)
1306627f7eb2Smrg {
1307627f7eb2Smrg Module *m = modules[i];
1308627f7eb2Smrg OutBuffer buf;
1309627f7eb2Smrg buf.doindent = 1;
1310627f7eb2Smrg
1311627f7eb2Smrg moduleToBuffer (&buf, m);
1312627f7eb2Smrg message ("%.*s", (int) buf.offset, (char *) buf.data);
1313627f7eb2Smrg }
1314627f7eb2Smrg }
1315627f7eb2Smrg
1316627f7eb2Smrg for (size_t i = 0; i < modules.dim; i++)
1317627f7eb2Smrg {
1318627f7eb2Smrg Module *m = modules[i];
1319627f7eb2Smrg if (d_option.fonly && m != Module::rootModule)
1320627f7eb2Smrg continue;
1321627f7eb2Smrg
1322627f7eb2Smrg if (global.params.verbose)
1323627f7eb2Smrg message ("code %s", m->toChars ());
1324627f7eb2Smrg
1325627f7eb2Smrg if (!flag_syntax_only)
1326627f7eb2Smrg {
1327627f7eb2Smrg if ((entrypoint_module != NULL) && (m == entrypoint_root_module))
1328627f7eb2Smrg build_decl_tree (entrypoint_module);
1329627f7eb2Smrg
1330627f7eb2Smrg build_decl_tree (m);
1331627f7eb2Smrg }
1332627f7eb2Smrg }
1333627f7eb2Smrg
1334627f7eb2Smrg /* And end the main input file, if the debug writer wants it. */
1335627f7eb2Smrg if (debug_hooks->start_end_main_source_file)
1336627f7eb2Smrg debug_hooks->end_source_file (0);
1337627f7eb2Smrg
1338627f7eb2Smrg had_errors:
1339627f7eb2Smrg /* Add the D frontend error count to the GCC error count to correctly
1340627f7eb2Smrg exit with an error status. */
1341627f7eb2Smrg errorcount += (global.errors + global.warnings);
1342627f7eb2Smrg
1343627f7eb2Smrg /* Write out globals. */
1344627f7eb2Smrg d_finish_compilation (vec_safe_address (global_declarations),
1345627f7eb2Smrg vec_safe_length (global_declarations));
1346627f7eb2Smrg }
1347627f7eb2Smrg
1348627f7eb2Smrg /* Implements the lang_hooks.types.type_for_mode routine for language D. */
1349627f7eb2Smrg
1350627f7eb2Smrg static tree
d_type_for_mode(machine_mode mode,int unsignedp)1351627f7eb2Smrg d_type_for_mode (machine_mode mode, int unsignedp)
1352627f7eb2Smrg {
1353627f7eb2Smrg if (mode == QImode)
1354627f7eb2Smrg return unsignedp ? d_ubyte_type : d_byte_type;
1355627f7eb2Smrg
1356627f7eb2Smrg if (mode == HImode)
1357627f7eb2Smrg return unsignedp ? d_ushort_type : d_short_type;
1358627f7eb2Smrg
1359627f7eb2Smrg if (mode == SImode)
1360627f7eb2Smrg return unsignedp ? d_uint_type : d_int_type;
1361627f7eb2Smrg
1362627f7eb2Smrg if (mode == DImode)
1363627f7eb2Smrg return unsignedp ? d_ulong_type : d_long_type;
1364627f7eb2Smrg
1365627f7eb2Smrg if (mode == TYPE_MODE (d_cent_type))
1366627f7eb2Smrg return unsignedp ? d_ucent_type : d_cent_type;
1367627f7eb2Smrg
1368627f7eb2Smrg if (mode == TYPE_MODE (float_type_node))
1369627f7eb2Smrg return float_type_node;
1370627f7eb2Smrg
1371627f7eb2Smrg if (mode == TYPE_MODE (double_type_node))
1372627f7eb2Smrg return double_type_node;
1373627f7eb2Smrg
1374627f7eb2Smrg if (mode == TYPE_MODE (long_double_type_node))
1375627f7eb2Smrg return long_double_type_node;
1376627f7eb2Smrg
1377627f7eb2Smrg if (mode == TYPE_MODE (build_pointer_type (char8_type_node)))
1378627f7eb2Smrg return build_pointer_type (char8_type_node);
1379627f7eb2Smrg
1380627f7eb2Smrg if (mode == TYPE_MODE (build_pointer_type (d_int_type)))
1381627f7eb2Smrg return build_pointer_type (d_int_type);
1382627f7eb2Smrg
1383*4c3eb207Smrg for (int i = 0; i < NUM_INT_N_ENTS; i ++)
1384*4c3eb207Smrg {
1385*4c3eb207Smrg if (int_n_enabled_p[i] && mode == int_n_data[i].m)
1386*4c3eb207Smrg {
1387*4c3eb207Smrg if (unsignedp)
1388*4c3eb207Smrg return int_n_trees[i].unsigned_type;
1389*4c3eb207Smrg else
1390*4c3eb207Smrg return int_n_trees[i].signed_type;
1391*4c3eb207Smrg }
1392*4c3eb207Smrg }
1393*4c3eb207Smrg
1394627f7eb2Smrg if (COMPLEX_MODE_P (mode))
1395627f7eb2Smrg {
1396627f7eb2Smrg machine_mode inner_mode;
1397627f7eb2Smrg tree inner_type;
1398627f7eb2Smrg
1399627f7eb2Smrg if (mode == TYPE_MODE (complex_float_type_node))
1400627f7eb2Smrg return complex_float_type_node;
1401627f7eb2Smrg if (mode == TYPE_MODE (complex_double_type_node))
1402627f7eb2Smrg return complex_double_type_node;
1403627f7eb2Smrg if (mode == TYPE_MODE (complex_long_double_type_node))
1404627f7eb2Smrg return complex_long_double_type_node;
1405627f7eb2Smrg
1406627f7eb2Smrg inner_mode = (machine_mode) GET_MODE_INNER (mode);
1407627f7eb2Smrg inner_type = d_type_for_mode (inner_mode, unsignedp);
1408627f7eb2Smrg if (inner_type != NULL_TREE)
1409627f7eb2Smrg return build_complex_type (inner_type);
1410627f7eb2Smrg }
1411627f7eb2Smrg else if (VECTOR_MODE_P (mode))
1412627f7eb2Smrg {
1413627f7eb2Smrg machine_mode inner_mode = (machine_mode) GET_MODE_INNER (mode);
1414627f7eb2Smrg tree inner_type = d_type_for_mode (inner_mode, unsignedp);
1415627f7eb2Smrg if (inner_type != NULL_TREE)
1416627f7eb2Smrg return build_vector_type_for_mode (inner_type, mode);
1417627f7eb2Smrg }
1418627f7eb2Smrg
1419627f7eb2Smrg return 0;
1420627f7eb2Smrg }
1421627f7eb2Smrg
1422627f7eb2Smrg /* Implements the lang_hooks.types.type_for_size routine for language D. */
1423627f7eb2Smrg
1424627f7eb2Smrg static tree
d_type_for_size(unsigned bits,int unsignedp)1425627f7eb2Smrg d_type_for_size (unsigned bits, int unsignedp)
1426627f7eb2Smrg {
1427627f7eb2Smrg if (bits <= TYPE_PRECISION (d_byte_type))
1428627f7eb2Smrg return unsignedp ? d_ubyte_type : d_byte_type;
1429627f7eb2Smrg
1430627f7eb2Smrg if (bits <= TYPE_PRECISION (d_short_type))
1431627f7eb2Smrg return unsignedp ? d_ushort_type : d_short_type;
1432627f7eb2Smrg
1433627f7eb2Smrg if (bits <= TYPE_PRECISION (d_int_type))
1434627f7eb2Smrg return unsignedp ? d_uint_type : d_int_type;
1435627f7eb2Smrg
1436627f7eb2Smrg if (bits <= TYPE_PRECISION (d_long_type))
1437627f7eb2Smrg return unsignedp ? d_ulong_type : d_long_type;
1438627f7eb2Smrg
1439627f7eb2Smrg if (bits <= TYPE_PRECISION (d_cent_type))
1440627f7eb2Smrg return unsignedp ? d_ucent_type : d_cent_type;
1441627f7eb2Smrg
1442*4c3eb207Smrg for (int i = 0; i < NUM_INT_N_ENTS; i ++)
1443*4c3eb207Smrg {
1444*4c3eb207Smrg if (int_n_enabled_p[i] && bits == int_n_data[i].bitsize)
1445*4c3eb207Smrg {
1446*4c3eb207Smrg if (unsignedp)
1447*4c3eb207Smrg return int_n_trees[i].unsigned_type;
1448*4c3eb207Smrg else
1449*4c3eb207Smrg return int_n_trees[i].signed_type;
1450*4c3eb207Smrg }
1451*4c3eb207Smrg }
1452*4c3eb207Smrg
1453627f7eb2Smrg return 0;
1454627f7eb2Smrg }
1455627f7eb2Smrg
1456627f7eb2Smrg /* Return the signed or unsigned version of TYPE, an integral type, the
1457627f7eb2Smrg signedness being specified by UNSIGNEDP. */
1458627f7eb2Smrg
1459627f7eb2Smrg static tree
d_signed_or_unsigned_type(int unsignedp,tree type)1460627f7eb2Smrg d_signed_or_unsigned_type (int unsignedp, tree type)
1461627f7eb2Smrg {
1462627f7eb2Smrg if (TYPE_UNSIGNED (type) == (unsigned) unsignedp)
1463627f7eb2Smrg return type;
1464627f7eb2Smrg
1465627f7eb2Smrg if (TYPE_PRECISION (type) == TYPE_PRECISION (d_cent_type))
1466627f7eb2Smrg return unsignedp ? d_ucent_type : d_cent_type;
1467627f7eb2Smrg
1468627f7eb2Smrg if (TYPE_PRECISION (type) == TYPE_PRECISION (d_long_type))
1469627f7eb2Smrg return unsignedp ? d_ulong_type : d_long_type;
1470627f7eb2Smrg
1471627f7eb2Smrg if (TYPE_PRECISION (type) == TYPE_PRECISION (d_int_type))
1472627f7eb2Smrg return unsignedp ? d_uint_type : d_int_type;
1473627f7eb2Smrg
1474627f7eb2Smrg if (TYPE_PRECISION (type) == TYPE_PRECISION (d_short_type))
1475627f7eb2Smrg return unsignedp ? d_ushort_type : d_short_type;
1476627f7eb2Smrg
1477627f7eb2Smrg if (TYPE_PRECISION (type) == TYPE_PRECISION (d_byte_type))
1478627f7eb2Smrg return unsignedp ? d_ubyte_type : d_byte_type;
1479627f7eb2Smrg
1480627f7eb2Smrg return signed_or_unsigned_type_for (unsignedp, type);
1481627f7eb2Smrg }
1482627f7eb2Smrg
1483627f7eb2Smrg /* Return the unsigned version of TYPE, an integral type. */
1484627f7eb2Smrg
1485627f7eb2Smrg tree
d_unsigned_type(tree type)1486627f7eb2Smrg d_unsigned_type (tree type)
1487627f7eb2Smrg {
1488627f7eb2Smrg return d_signed_or_unsigned_type (1, type);
1489627f7eb2Smrg }
1490627f7eb2Smrg
1491627f7eb2Smrg /* Return the signed version of TYPE, an integral type. */
1492627f7eb2Smrg
1493627f7eb2Smrg tree
d_signed_type(tree type)1494627f7eb2Smrg d_signed_type (tree type)
1495627f7eb2Smrg {
1496627f7eb2Smrg return d_signed_or_unsigned_type (0, type);
1497627f7eb2Smrg }
1498627f7eb2Smrg
1499627f7eb2Smrg /* Implements the lang_hooks.types.type_promotes_to routine for language D.
1500627f7eb2Smrg All promotions for variable arguments are handled by the D frontend. */
1501627f7eb2Smrg
1502627f7eb2Smrg static tree
d_type_promotes_to(tree type)1503627f7eb2Smrg d_type_promotes_to (tree type)
1504627f7eb2Smrg {
1505627f7eb2Smrg return type;
1506627f7eb2Smrg }
1507627f7eb2Smrg
1508627f7eb2Smrg /* Implements the lang_hooks.decls.global_bindings_p routine for language D.
1509627f7eb2Smrg Return true if we are in the global binding level. */
1510627f7eb2Smrg
1511627f7eb2Smrg static bool
d_global_bindings_p(void)1512627f7eb2Smrg d_global_bindings_p (void)
1513627f7eb2Smrg {
1514627f7eb2Smrg return (current_binding_level == global_binding_level);
1515627f7eb2Smrg }
1516627f7eb2Smrg
1517627f7eb2Smrg /* Return global_context, but create it first if need be. */
1518627f7eb2Smrg
1519627f7eb2Smrg static tree
get_global_context(void)1520627f7eb2Smrg get_global_context (void)
1521627f7eb2Smrg {
1522627f7eb2Smrg if (!global_context)
1523627f7eb2Smrg {
1524627f7eb2Smrg global_context = build_translation_unit_decl (NULL_TREE);
1525627f7eb2Smrg debug_hooks->register_main_translation_unit (global_context);
1526627f7eb2Smrg }
1527627f7eb2Smrg
1528627f7eb2Smrg return global_context;
1529627f7eb2Smrg }
1530627f7eb2Smrg
1531627f7eb2Smrg /* Implements the lang_hooks.decls.pushdecl routine for language D.
1532627f7eb2Smrg Record DECL as belonging to the current lexical scope. */
1533627f7eb2Smrg
1534627f7eb2Smrg tree
d_pushdecl(tree decl)1535627f7eb2Smrg d_pushdecl (tree decl)
1536627f7eb2Smrg {
1537627f7eb2Smrg /* Set the context of the decl. If current_function_decl did not help in
1538627f7eb2Smrg determining the context, use global scope. */
1539627f7eb2Smrg if (!DECL_CONTEXT (decl))
1540627f7eb2Smrg {
1541627f7eb2Smrg if (current_function_decl)
1542627f7eb2Smrg DECL_CONTEXT (decl) = current_function_decl;
1543627f7eb2Smrg else
1544627f7eb2Smrg DECL_CONTEXT (decl) = get_global_context ();
1545627f7eb2Smrg }
1546627f7eb2Smrg
1547627f7eb2Smrg /* Put decls on list in reverse order. */
1548627f7eb2Smrg if (TREE_STATIC (decl) || d_global_bindings_p ())
1549627f7eb2Smrg vec_safe_push (global_declarations, decl);
1550627f7eb2Smrg else
1551627f7eb2Smrg {
1552627f7eb2Smrg TREE_CHAIN (decl) = current_binding_level->names;
1553627f7eb2Smrg current_binding_level->names = decl;
1554627f7eb2Smrg }
1555627f7eb2Smrg
1556627f7eb2Smrg return decl;
1557627f7eb2Smrg }
1558627f7eb2Smrg
1559627f7eb2Smrg /* Implements the lang_hooks.decls.getdecls routine for language D.
1560627f7eb2Smrg Return the list of declarations of the current level. */
1561627f7eb2Smrg
1562627f7eb2Smrg static tree
d_getdecls(void)1563627f7eb2Smrg d_getdecls (void)
1564627f7eb2Smrg {
1565627f7eb2Smrg if (current_binding_level)
1566627f7eb2Smrg return current_binding_level->names;
1567627f7eb2Smrg
1568627f7eb2Smrg return NULL_TREE;
1569627f7eb2Smrg }
1570627f7eb2Smrg
1571627f7eb2Smrg
1572627f7eb2Smrg /* Implements the lang_hooks.get_alias_set routine for language D.
1573627f7eb2Smrg Get the alias set corresponding to type or expression T.
1574627f7eb2Smrg Return -1 if we don't do anything special. */
1575627f7eb2Smrg
1576627f7eb2Smrg static alias_set_type
d_get_alias_set(tree)1577627f7eb2Smrg d_get_alias_set (tree)
1578627f7eb2Smrg {
1579627f7eb2Smrg /* For now in D, assume everything aliases everything else, until we define
1580627f7eb2Smrg some solid rules backed by a specification. There are also some parts
1581627f7eb2Smrg of code generation routines that don't adhere to C alias rules, such as
1582627f7eb2Smrg build_vconvert. In any case, a lot of user code already assumes there
1583627f7eb2Smrg is no strict aliasing and will break if we were to change that. */
1584627f7eb2Smrg return 0;
1585627f7eb2Smrg }
1586627f7eb2Smrg
1587627f7eb2Smrg /* Implements the lang_hooks.types_compatible_p routine for language D.
1588627f7eb2Smrg Compares two types for equivalence in the D programming language.
1589627f7eb2Smrg This routine should only return 1 if it is sure, even though the frontend
1590627f7eb2Smrg should have already ensured that all types are compatible before handing
1591627f7eb2Smrg over the parsed ASTs to the code generator. */
1592627f7eb2Smrg
1593627f7eb2Smrg static int
d_types_compatible_p(tree x,tree y)1594627f7eb2Smrg d_types_compatible_p (tree x, tree y)
1595627f7eb2Smrg {
1596627f7eb2Smrg Type *tx = TYPE_LANG_FRONTEND (x);
1597627f7eb2Smrg Type *ty = TYPE_LANG_FRONTEND (y);
1598627f7eb2Smrg
1599627f7eb2Smrg /* Try validating the types in the frontend. */
1600627f7eb2Smrg if (tx != NULL && ty != NULL)
1601627f7eb2Smrg {
1602627f7eb2Smrg /* Types are equivalent. */
1603627f7eb2Smrg if (same_type_p (tx, ty))
1604627f7eb2Smrg return true;
1605627f7eb2Smrg
1606627f7eb2Smrg /* Type system allows implicit conversion between. */
1607627f7eb2Smrg if (tx->implicitConvTo (ty) || ty->implicitConvTo (tx))
1608627f7eb2Smrg return true;
1609627f7eb2Smrg }
1610627f7eb2Smrg
1611627f7eb2Smrg /* Fallback on using type flags for comparison. E.g: all dynamic arrays
1612627f7eb2Smrg are distinct types in D, but are VIEW_CONVERT compatible. */
1613627f7eb2Smrg if (TREE_CODE (x) == RECORD_TYPE && TREE_CODE (y) == RECORD_TYPE)
1614627f7eb2Smrg {
1615627f7eb2Smrg if (TYPE_DYNAMIC_ARRAY (x) && TYPE_DYNAMIC_ARRAY (y))
1616627f7eb2Smrg return true;
1617627f7eb2Smrg
1618627f7eb2Smrg if (TYPE_DELEGATE (x) && TYPE_DELEGATE (y))
1619627f7eb2Smrg return true;
1620627f7eb2Smrg
1621627f7eb2Smrg if (TYPE_ASSOCIATIVE_ARRAY (x) && TYPE_ASSOCIATIVE_ARRAY (y))
1622627f7eb2Smrg return true;
1623627f7eb2Smrg }
1624627f7eb2Smrg
1625627f7eb2Smrg return false;
1626627f7eb2Smrg }
1627627f7eb2Smrg
1628627f7eb2Smrg /* Implements the lang_hooks.finish_incomplete_decl routine for language D. */
1629627f7eb2Smrg
1630627f7eb2Smrg static void
d_finish_incomplete_decl(tree decl)1631627f7eb2Smrg d_finish_incomplete_decl (tree decl)
1632627f7eb2Smrg {
1633627f7eb2Smrg if (VAR_P (decl))
1634627f7eb2Smrg {
1635627f7eb2Smrg /* D allows zero-length declarations. Such a declaration ends up with
1636627f7eb2Smrg DECL_SIZE (t) == NULL_TREE which is what the back-end function
1637627f7eb2Smrg assembler_variable checks. This could change in later versions, or
1638627f7eb2Smrg maybe all of these variables should be aliased to one symbol. */
1639627f7eb2Smrg if (DECL_SIZE (decl) == 0)
1640627f7eb2Smrg {
1641627f7eb2Smrg DECL_SIZE (decl) = bitsize_zero_node;
1642627f7eb2Smrg DECL_SIZE_UNIT (decl) = size_zero_node;
1643627f7eb2Smrg }
1644627f7eb2Smrg }
1645627f7eb2Smrg }
1646627f7eb2Smrg
1647627f7eb2Smrg /* Implements the lang_hooks.types.classify_record routine for language D.
1648627f7eb2Smrg Return the true debug type for TYPE. */
1649627f7eb2Smrg
1650627f7eb2Smrg static classify_record
d_classify_record(tree type)1651627f7eb2Smrg d_classify_record (tree type)
1652627f7eb2Smrg {
1653627f7eb2Smrg Type *t = TYPE_LANG_FRONTEND (type);
1654627f7eb2Smrg
1655627f7eb2Smrg if (t && t->ty == Tclass)
1656627f7eb2Smrg {
1657627f7eb2Smrg TypeClass *tc = (TypeClass *) t;
1658627f7eb2Smrg
1659627f7eb2Smrg /* extern(C++) interfaces get emitted as classes. */
1660627f7eb2Smrg if (tc->sym->isInterfaceDeclaration ()
1661627f7eb2Smrg && !tc->sym->isCPPinterface ())
1662627f7eb2Smrg return RECORD_IS_INTERFACE;
1663627f7eb2Smrg
1664627f7eb2Smrg return RECORD_IS_CLASS;
1665627f7eb2Smrg }
1666627f7eb2Smrg
1667627f7eb2Smrg return RECORD_IS_STRUCT;
1668627f7eb2Smrg }
1669627f7eb2Smrg
1670627f7eb2Smrg /* Implements the lang_hooks.tree_size routine for language D.
1671627f7eb2Smrg Determine the size of our tcc_constant or tcc_exceptional nodes. */
1672627f7eb2Smrg
1673627f7eb2Smrg static size_t
d_tree_size(tree_code code)1674627f7eb2Smrg d_tree_size (tree_code code)
1675627f7eb2Smrg {
1676627f7eb2Smrg switch (code)
1677627f7eb2Smrg {
1678627f7eb2Smrg case FUNCFRAME_INFO:
1679627f7eb2Smrg return sizeof (tree_frame_info);
1680627f7eb2Smrg
1681627f7eb2Smrg default:
1682627f7eb2Smrg gcc_unreachable ();
1683627f7eb2Smrg }
1684627f7eb2Smrg }
1685627f7eb2Smrg
1686627f7eb2Smrg /* Implements the lang_hooks.print_xnode routine for language D. */
1687627f7eb2Smrg
1688627f7eb2Smrg static void
d_print_xnode(FILE * file,tree node,int indent)1689627f7eb2Smrg d_print_xnode (FILE *file, tree node, int indent)
1690627f7eb2Smrg {
1691627f7eb2Smrg switch (TREE_CODE (node))
1692627f7eb2Smrg {
1693627f7eb2Smrg case FUNCFRAME_INFO:
1694627f7eb2Smrg print_node (file, "frame_type", FRAMEINFO_TYPE (node), indent + 4);
1695627f7eb2Smrg break;
1696627f7eb2Smrg
1697627f7eb2Smrg default:
1698627f7eb2Smrg break;
1699627f7eb2Smrg }
1700627f7eb2Smrg }
1701627f7eb2Smrg
1702627f7eb2Smrg /* Return which tree structure is used by NODE, or TS_D_GENERIC if NODE
1703627f7eb2Smrg is one of the language-independent trees. */
1704627f7eb2Smrg
1705627f7eb2Smrg d_tree_node_structure_enum
d_tree_node_structure(lang_tree_node * t)1706627f7eb2Smrg d_tree_node_structure (lang_tree_node *t)
1707627f7eb2Smrg {
1708627f7eb2Smrg switch (TREE_CODE (&t->generic))
1709627f7eb2Smrg {
1710627f7eb2Smrg case IDENTIFIER_NODE:
1711627f7eb2Smrg return TS_D_IDENTIFIER;
1712627f7eb2Smrg
1713627f7eb2Smrg case FUNCFRAME_INFO:
1714627f7eb2Smrg return TS_D_FRAMEINFO;
1715627f7eb2Smrg
1716627f7eb2Smrg default:
1717627f7eb2Smrg return TS_D_GENERIC;
1718627f7eb2Smrg }
1719627f7eb2Smrg }
1720627f7eb2Smrg
1721627f7eb2Smrg /* Allocate and return a lang specific structure for the frontend type. */
1722627f7eb2Smrg
1723627f7eb2Smrg struct lang_type *
build_lang_type(Type * t)1724627f7eb2Smrg build_lang_type (Type *t)
1725627f7eb2Smrg {
1726627f7eb2Smrg struct lang_type *lt = ggc_cleared_alloc<struct lang_type> ();
1727627f7eb2Smrg lt->type = t;
1728627f7eb2Smrg return lt;
1729627f7eb2Smrg }
1730627f7eb2Smrg
1731627f7eb2Smrg /* Allocate and return a lang specific structure for the frontend decl. */
1732627f7eb2Smrg
1733627f7eb2Smrg struct lang_decl *
build_lang_decl(Declaration * d)1734627f7eb2Smrg build_lang_decl (Declaration *d)
1735627f7eb2Smrg {
1736627f7eb2Smrg /* For compiler generated run-time typeinfo, a lang_decl is allocated even if
1737627f7eb2Smrg there's no associated frontend symbol to refer to (yet). If the symbol
1738627f7eb2Smrg appears later in the compilation, then the slot will be re-used. */
1739627f7eb2Smrg if (d == NULL)
1740627f7eb2Smrg return ggc_cleared_alloc<struct lang_decl> ();
1741627f7eb2Smrg
1742627f7eb2Smrg struct lang_decl *ld = (d->csym) ? DECL_LANG_SPECIFIC (d->csym) : NULL;
1743627f7eb2Smrg if (ld == NULL)
1744627f7eb2Smrg ld = ggc_cleared_alloc<struct lang_decl> ();
1745627f7eb2Smrg
1746627f7eb2Smrg if (ld->decl == NULL)
1747627f7eb2Smrg ld->decl = d;
1748627f7eb2Smrg
1749627f7eb2Smrg return ld;
1750627f7eb2Smrg }
1751627f7eb2Smrg
1752627f7eb2Smrg /* Implements the lang_hooks.dup_lang_specific_decl routine for language D.
1753627f7eb2Smrg Replace the DECL_LANG_SPECIFIC field of NODE with a copy. */
1754627f7eb2Smrg
1755627f7eb2Smrg static void
d_dup_lang_specific_decl(tree node)1756627f7eb2Smrg d_dup_lang_specific_decl (tree node)
1757627f7eb2Smrg {
1758627f7eb2Smrg if (! DECL_LANG_SPECIFIC (node))
1759627f7eb2Smrg return;
1760627f7eb2Smrg
1761627f7eb2Smrg struct lang_decl *ld = ggc_alloc<struct lang_decl> ();
1762627f7eb2Smrg memcpy (ld, DECL_LANG_SPECIFIC (node), sizeof (struct lang_decl));
1763627f7eb2Smrg DECL_LANG_SPECIFIC (node) = ld;
1764627f7eb2Smrg }
1765627f7eb2Smrg
1766627f7eb2Smrg /* This preserves trees we create from the garbage collector. */
1767627f7eb2Smrg
1768627f7eb2Smrg static GTY(()) tree d_keep_list = NULL_TREE;
1769627f7eb2Smrg
1770627f7eb2Smrg void
d_keep(tree t)1771627f7eb2Smrg d_keep (tree t)
1772627f7eb2Smrg {
1773627f7eb2Smrg d_keep_list = tree_cons (NULL_TREE, t, d_keep_list);
1774627f7eb2Smrg }
1775627f7eb2Smrg
1776627f7eb2Smrg /* Implements the lang_hooks.eh_personality routine for language D.
1777627f7eb2Smrg Return the GDC personality function decl. */
1778627f7eb2Smrg
1779627f7eb2Smrg static GTY(()) tree d_eh_personality_decl;
1780627f7eb2Smrg
1781627f7eb2Smrg static tree
d_eh_personality(void)1782627f7eb2Smrg d_eh_personality (void)
1783627f7eb2Smrg {
1784627f7eb2Smrg if (!d_eh_personality_decl)
1785627f7eb2Smrg d_eh_personality_decl = build_personality_function ("gdc");
1786627f7eb2Smrg
1787627f7eb2Smrg return d_eh_personality_decl;
1788627f7eb2Smrg }
1789627f7eb2Smrg
1790627f7eb2Smrg /* Implements the lang_hooks.eh_runtime_type routine for language D. */
1791627f7eb2Smrg
1792627f7eb2Smrg static tree
d_build_eh_runtime_type(tree type)1793627f7eb2Smrg d_build_eh_runtime_type (tree type)
1794627f7eb2Smrg {
1795627f7eb2Smrg Type *t = TYPE_LANG_FRONTEND (type);
1796627f7eb2Smrg
1797627f7eb2Smrg if (t != NULL)
1798627f7eb2Smrg t = t->toBasetype ();
1799627f7eb2Smrg
1800627f7eb2Smrg gcc_assert (t != NULL && t->ty == Tclass);
1801627f7eb2Smrg ClassDeclaration *cd = ((TypeClass *) t)->sym;
1802627f7eb2Smrg tree decl;
1803627f7eb2Smrg
1804627f7eb2Smrg if (cd->isCPPclass ())
1805627f7eb2Smrg decl = get_cpp_typeinfo_decl (cd);
1806627f7eb2Smrg else
1807627f7eb2Smrg decl = get_classinfo_decl (cd);
1808627f7eb2Smrg
1809627f7eb2Smrg return convert (ptr_type_node, build_address (decl));
1810627f7eb2Smrg }
1811627f7eb2Smrg
1812627f7eb2Smrg /* Definitions for our language-specific hooks. */
1813627f7eb2Smrg
1814627f7eb2Smrg #undef LANG_HOOKS_NAME
1815627f7eb2Smrg #undef LANG_HOOKS_INIT
1816627f7eb2Smrg #undef LANG_HOOKS_INIT_TS
1817627f7eb2Smrg #undef LANG_HOOKS_INIT_OPTIONS
1818627f7eb2Smrg #undef LANG_HOOKS_INIT_OPTIONS_STRUCT
1819627f7eb2Smrg #undef LANG_HOOKS_OPTION_LANG_MASK
1820627f7eb2Smrg #undef LANG_HOOKS_HANDLE_OPTION
1821627f7eb2Smrg #undef LANG_HOOKS_POST_OPTIONS
1822627f7eb2Smrg #undef LANG_HOOKS_PARSE_FILE
1823627f7eb2Smrg #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
1824627f7eb2Smrg #undef LANG_HOOKS_ATTRIBUTE_TABLE
1825627f7eb2Smrg #undef LANG_HOOKS_GET_ALIAS_SET
1826627f7eb2Smrg #undef LANG_HOOKS_TYPES_COMPATIBLE_P
1827627f7eb2Smrg #undef LANG_HOOKS_BUILTIN_FUNCTION
1828*4c3eb207Smrg #undef LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE
1829627f7eb2Smrg #undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
1830627f7eb2Smrg #undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
1831627f7eb2Smrg #undef LANG_HOOKS_GIMPLIFY_EXPR
1832627f7eb2Smrg #undef LANG_HOOKS_CLASSIFY_RECORD
1833627f7eb2Smrg #undef LANG_HOOKS_TREE_SIZE
1834627f7eb2Smrg #undef LANG_HOOKS_PRINT_XNODE
1835627f7eb2Smrg #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
1836627f7eb2Smrg #undef LANG_HOOKS_EH_PERSONALITY
1837627f7eb2Smrg #undef LANG_HOOKS_EH_RUNTIME_TYPE
1838627f7eb2Smrg #undef LANG_HOOKS_PUSHDECL
1839627f7eb2Smrg #undef LANG_HOOKS_GETDECLS
1840627f7eb2Smrg #undef LANG_HOOKS_GLOBAL_BINDINGS_P
1841627f7eb2Smrg #undef LANG_HOOKS_TYPE_FOR_MODE
1842627f7eb2Smrg #undef LANG_HOOKS_TYPE_FOR_SIZE
1843627f7eb2Smrg #undef LANG_HOOKS_TYPE_PROMOTES_TO
1844627f7eb2Smrg
1845627f7eb2Smrg #define LANG_HOOKS_NAME "GNU D"
1846627f7eb2Smrg #define LANG_HOOKS_INIT d_init
1847627f7eb2Smrg #define LANG_HOOKS_INIT_TS d_init_ts
1848627f7eb2Smrg #define LANG_HOOKS_INIT_OPTIONS d_init_options
1849627f7eb2Smrg #define LANG_HOOKS_INIT_OPTIONS_STRUCT d_init_options_struct
1850627f7eb2Smrg #define LANG_HOOKS_OPTION_LANG_MASK d_option_lang_mask
1851627f7eb2Smrg #define LANG_HOOKS_HANDLE_OPTION d_handle_option
1852627f7eb2Smrg #define LANG_HOOKS_POST_OPTIONS d_post_options
1853627f7eb2Smrg #define LANG_HOOKS_PARSE_FILE d_parse_file
1854627f7eb2Smrg #define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE d_langhook_common_attribute_table
1855627f7eb2Smrg #define LANG_HOOKS_ATTRIBUTE_TABLE d_langhook_attribute_table
1856627f7eb2Smrg #define LANG_HOOKS_GET_ALIAS_SET d_get_alias_set
1857627f7eb2Smrg #define LANG_HOOKS_TYPES_COMPATIBLE_P d_types_compatible_p
1858627f7eb2Smrg #define LANG_HOOKS_BUILTIN_FUNCTION d_builtin_function
1859*4c3eb207Smrg #define LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE d_builtin_function_ext_scope
1860627f7eb2Smrg #define LANG_HOOKS_REGISTER_BUILTIN_TYPE d_register_builtin_type
1861627f7eb2Smrg #define LANG_HOOKS_FINISH_INCOMPLETE_DECL d_finish_incomplete_decl
1862627f7eb2Smrg #define LANG_HOOKS_GIMPLIFY_EXPR d_gimplify_expr
1863627f7eb2Smrg #define LANG_HOOKS_CLASSIFY_RECORD d_classify_record
1864627f7eb2Smrg #define LANG_HOOKS_TREE_SIZE d_tree_size
1865627f7eb2Smrg #define LANG_HOOKS_PRINT_XNODE d_print_xnode
1866627f7eb2Smrg #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL d_dup_lang_specific_decl
1867627f7eb2Smrg #define LANG_HOOKS_EH_PERSONALITY d_eh_personality
1868627f7eb2Smrg #define LANG_HOOKS_EH_RUNTIME_TYPE d_build_eh_runtime_type
1869627f7eb2Smrg #define LANG_HOOKS_PUSHDECL d_pushdecl
1870627f7eb2Smrg #define LANG_HOOKS_GETDECLS d_getdecls
1871627f7eb2Smrg #define LANG_HOOKS_GLOBAL_BINDINGS_P d_global_bindings_p
1872627f7eb2Smrg #define LANG_HOOKS_TYPE_FOR_MODE d_type_for_mode
1873627f7eb2Smrg #define LANG_HOOKS_TYPE_FOR_SIZE d_type_for_size
1874627f7eb2Smrg #define LANG_HOOKS_TYPE_PROMOTES_TO d_type_promotes_to
1875627f7eb2Smrg
1876627f7eb2Smrg struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
1877627f7eb2Smrg
1878627f7eb2Smrg #include "gt-d-d-lang.h"
1879627f7eb2Smrg #include "gtype-d.h"
1880