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