1 /* GDC -- D front-end for GCC
2 Copyright (C) 2004 David Friedman
4 This program 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 2 of the License, or
7 (at your option) any later version.
9 This program 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.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 dc-lang.cc: implementation of back-end callbacks and data structures
31 #include "d-gcc-includes.h"
34 #include "d-codegen.h"
35 #include "d-gcc-real.h"
36 #include "d-confdefs.h"
38 static char lang_name
[6] = "GNU D";
40 #undef LANG_HOOKS_NAME
41 #define LANG_HOOKS_NAME lang_name
43 #undef LANG_HOOKS_INIT
44 #define LANG_HOOKS_INIT d_init
46 #undef LANG_HOOKS_INIT_OPTIONS
47 #define LANG_HOOKS_INIT_OPTIONS d_init_options
49 #undef LANG_HOOKS_HANDLE_OPTION
50 #define LANG_HOOKS_HANDLE_OPTION d_handle_option
51 #undef LANG_HOOKS_POST_OPTIONS
52 #define LANG_HOOKS_POST_OPTIONS d_post_options
54 #undef LANG_HOOKS_PARSE_FILE
55 #define LANG_HOOKS_PARSE_FILE d_parse_file
58 #undef LANG_HOOKS_TRUTHVALUE_CONVERSION
59 #define LANG_HOOKS_TRUTHVALUE_CONVERSION d_truthvalue_conversion
62 #undef LANG_HOOKS_MARK_ADDRESSABLE
63 #define LANG_HOOKS_MARK_ADDRESSABLE d_mark_addressable
65 #undef LANG_HOOKS_TYPE_FOR_MODE
66 #define LANG_HOOKS_TYPE_FOR_MODE d_type_for_mode
68 #undef LANG_HOOKS_TYPE_FOR_SIZE
69 #define LANG_HOOKS_TYPE_FOR_SIZE d_type_for_size
72 #undef LANG_HOOKS_EXPAND_EXPR
73 #define LANG_HOOKS_EXPAND_EXPR d_expand_expr
76 #define LANG_HOOKS_UNSIGNED_TYPE d_unsigned_type
77 #define LANG_HOOKS_SIGNED_TYPE d_signed_type
78 #define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE d_signed_or_unsigned_type
79 #define LANG_HOOKS_TYPE_FOR_SIZE d_type_for_size
80 #define LANG_HOOKS_TYPE_FOR_MODE d_type_for_mode
82 #undef LANG_HOOKS_TYPE_PROMOTES_TO
83 #define LANG_HOOKS_TYPE_PROMOTES_TO d_type_promotes_to
85 #undef LANG_HOOKS_WRITE_GLOBALS
86 #define LANG_HOOKS_WRITE_GLOBALS d_write_global_declarations
88 // Some phobos code (isnormal, etc.) breaks with strict aliasing...
89 // so I guess D doesn't have aliasing rules. Would be nice to enable
90 // strict aliasing, but hooking or defaulting flag_strict_aliasing is
92 #undef LANG_HOOKS_GET_ALIAS_SET
93 #define LANG_HOOKS_GET_ALIAS_SET hook_get_alias_set_0
95 // Needed for try/finally -- statements cannont be re-evaluated
97 #undef LANG_HOOKS_UNSAFE_FOR_REEVAL
98 #define LANG_HOOKS_UNSAFE_FOR_REEVAL d_unsafe_for_reeval
101 #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
102 #define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE d_common_attribute_table
103 #undef LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE
104 #define LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE d_common_format_attribute_table
107 #undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
108 #define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION d_expand_function
112 #define LANG_HOOKS_TYPES_COMPATIBLE_P d_types_compatible_p
115 #undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING
116 #define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING d_convert_parm_for_inlining
122 ////static tree d_type_for_size PARAMS ((unsigned, int));
123 static tree
d_signed_or_unsigned_type(int, tree
);
124 ////tree d_unsigned_type(tree);
125 ////tree d_signed_type(tree);
135 static const char * iprefix
;
136 static bool std_inc
; // %%FIX: find a place for this
137 static const char * fonly_arg
;
138 static const char * multilib_dir
;
141 d_init_options (unsigned int, const char **)
143 // Set default values
144 global
.params
.argv0
= (char *) progname
;
145 global
.params
.link
= 1;
146 global
.params
.useAssert
= 1;
147 global
.params
.useInvariants
= 1;
148 global
.params
.useIn
= 1;
149 global
.params
.useOut
= 1;
150 global
.params
.useArrayBounds
= 1;
151 flag_bounds_check
= global
.params
.useArrayBounds
; // keep in synch with existing -fbounds-check flag
152 global
.params
.useSwitchError
= 1;
153 global
.params
.useInline
= 0;
154 global
.params
.warnings
= 0;
155 global
.params
.obj
= 1;
156 global
.params
.Dversion
= 2;
157 global
.params
.quiet
= 1;
159 global
.params
.linkswitches
= new Array();
160 global
.params
.libfiles
= new Array();
161 global
.params
.objfiles
= new Array();
162 global
.params
.ddocfiles
= new Array();
164 global
.params
.imppath
= new Array();
165 global
.params
.fileImppath
= new Array();
170 // extra D-specific options
171 gen
.splitDynArrayVarArgs
= true;
172 gen
.emitTemplates
= TEauto
;
173 gen
.useBuiltins
= true;
179 // support for the -mno-cygwin switch
180 // copied from cygwin.h, cygwin2.c
181 #ifndef CYGWIN_MINGW_SUBDIR
182 #define CYGWIN_MINGW_SUBDIR "/mingw"
184 #define CYGWIN_MINGW_SUBDIR_LEN (sizeof (CYGWIN_MINGW_SUBDIR) - 1)
186 char cygwin_d_phobos_dir
[sizeof(D_PHOBOS_DIR
) + 1
187 + (CYGWIN_MINGW_SUBDIR_LEN
)] = D_PHOBOS_DIR
;
189 #define D_PHOBOS_DIR (cygwin_d_phobos_dir)
190 char cygwin_d_target_dir
[sizeof(D_PHOBOS_TARGET_DIR
) + 1
191 + (CYGWIN_MINGW_SUBDIR_LEN
)] = D_PHOBOS_TARGET_DIR
;
192 #undef D_PHOBOS_TARGET_DIR
193 #define D_PHOBOS_TARGET_DIR (cygwin_d_target_dir)
196 const char * cygwin_d_os_versym
= D_OS_VERSYM
;
198 #define D_OS_VERSYM cygwin_d_os_versym
205 char * env
= getenv("GCC_CYGWIN_MINGW");
209 static char *d_cvt_to_mingw
[] = {
213 if (!strcmp(cygwin_d_os_versym
,"cygwin") && env
&& *env
== '1') {
214 cygwin_d_os_versym
= "Win32";
216 for (av
= d_cvt_to_mingw
; *av
; av
++)
219 while ((p
= strstr (*av
, "-cygwin")))
221 char *over
= p
+ sizeof ("-cygwin") - 1;
222 memmove (over
+ 1, over
, strlen (over
));
223 memcpy (p
, "-mingw32", sizeof("-mingw32") - 1);
230 if (!sawcygwin
&& !strstr (*av
, "mingw"))
231 strcat (*av
, CYGWIN_MINGW_SUBDIR
);
237 static bool is_target_win32
= false;
240 d_gcc_is_target_win32()
242 return is_target_win32
;
246 prefixed_path(const char * path
)
248 // based on c-incpath.c
249 size_t len
= cpp_GCC_INCLUDE_DIR_len
;
250 if (iprefix
&& len
!= 0 && ! strncmp(path
, cpp_GCC_INCLUDE_DIR
, len
))
251 return concat(iprefix
, path
+ len
, NULL
);
253 return xstrdup(path
);
257 d_cpp_forall_callback(cpp_reader
*, cpp_hashnode
* hn
, void *)
259 const char * str
= (const char *) hn
->ident
.str
;
260 unsigned int len
= hn
->ident
.len
;
261 char * d_ident
= new char[4 + len
+ 1];
262 if (len
> 4 && str
[0] == '_' && str
[1] == '_' &&
263 str
[len
- 1] == '_' && str
[len
- 2] == '_')
268 strcpy(d_ident
, "GNU_");
269 strncpy(d_ident
+ 4, str
, len
);
270 d_ident
[len
+ 4] = '\0';
271 VersionCondition::addPredefinedGlobalIdent(d_ident
);
275 /* Supports CPP builtins. */
276 cpp_reader
* parse_in
;
278 builtin_define_std (const char *macro
)
280 // Do nothing. No need for these (yet).
286 const char * cpu_versym
= NULL
;
288 /* Currently, isX86_64 indicates a 64-bit target in general and is not
291 global
.params
.isX86_64
= TARGET_64BIT
? 1 : 0;
293 /* TARGET_64BIT is only defined on biarched archs defaulted to 64-bit
294 * (as amd64 or s390x) so for full 64-bit archs (as ia64 or alpha) we
295 * need to test it more. */
296 # ifdef D_CPU_VERSYM64
297 /* We are "defaulting" to 32-bit, which mean that if both D_CPU_VERSYM
298 * and D_CPU_VERSYM64 are defined, and not TARGET_64BIT, we will use
299 * 32 bits. This will be overidden for full 64-bit archs */
300 global
.params
.isX86_64
= 0;
301 # ifndef D_CPU_VERSYM
302 /* So this is typically for alpha and ia64 */
303 global
.params
.isX86_64
= 1;
306 # ifdef D_CPU_VERSYM /* D_CPU_VERSYM is defined and D_CPU_VERSYM64 is not. */
307 global
.params
.isX86_64
= 0;
309 /* If none of D_CPU_VERSYM and D_CPU_VERSYM64 defined check size_t
311 switch (sizeof(size_t)) {
313 global
.params
.isX86_64
= 0;
316 global
.params
.isX86_64
= 1;
327 gcc_d_backend_init();
330 maybe_fixup_cygwin();
332 VersionCondition::addPredefinedGlobalIdent("GNU");
333 #ifdef D_CPU_VERSYM64
334 if (global
.params
.isX86_64
== 1)
335 cpu_versym
= D_CPU_VERSYM64
;
338 cpu_versym
= D_CPU_VERSYM
;
342 cpu_versym
= D_CPU_VERSYM
;
346 VersionCondition::addPredefinedGlobalIdent((char*) cpu_versym
);
348 VersionCondition::addPredefinedGlobalIdent((char*) D_OS_VERSYM
);
349 if (strcmp(D_OS_VERSYM
, "Win32") == 0)
350 is_target_win32
= true;
353 VersionCondition::addPredefinedGlobalIdent((char*) D_OS_VERSYM2
);
354 if (strcmp(D_OS_VERSYM2
, "Win32") == 0)
355 is_target_win32
= true;
360 VersionCondition::addPredefinedGlobalIdent("Thumb");
362 VersionCondition::addPredefinedGlobalIdent("Arm");
365 if (BYTES_BIG_ENDIAN
)
366 VersionCondition::addPredefinedGlobalIdent("BigEndian");
368 VersionCondition::addPredefinedGlobalIdent("LittleEndian");
370 if (d_using_sjlj_exceptions()) {
371 VersionCondition::addPredefinedGlobalIdent("GNU_SjLj_Exceptions");
373 #ifdef TARGET_LONG_DOUBLE_128
374 if (TARGET_LONG_DOUBLE_128
)
375 VersionCondition::addPredefinedGlobalIdent("GNU_LongDouble128");
378 if (d_have_inline_asm() && cpu_versym
&& strcmp(cpu_versym
, "X86") == 0)
380 VersionCondition::addPredefinedGlobalIdent("D_InlineAsm");
381 VersionCondition::addPredefinedGlobalIdent("D_InlineAsm_X86");
384 /* Setting global.params.cov forces module info generation which is
385 not needed for thee GCC coverage implementation. Instead, just
386 test flag_test_coverage while leaving global.params.cov unset. */
387 //if (global.params.cov)
388 if (flag_test_coverage
)
389 VersionCondition::addPredefinedGlobalIdent("D_Coverage");
390 if (global
.params
.useUnitTests
)
391 VersionCondition::addPredefinedGlobalIdent("unittest");
395 cpp_reader
* pfile
; // Target macros below expect this identifier.
396 int flag_iso
= 0; // ditto
399 parse_in
= pfile
= cpp_create_reader(CLK_STDC89
, NULL
404 cpp_change_file(pfile
, LC_ENTER
, "<built-in>");
406 // from c-cppbuiltin.c
407 #ifndef TARGET_OS_CPP_BUILTINS
408 # define TARGET_OS_CPP_BUILTINS()
410 #ifndef TARGET_OBJFMT_CPP_BUILTINS
411 # define TARGET_OBJFMT_CPP_BUILTINS()
414 # define preprocessing_asm_p() (cpp_get_options (pfile)->lang == CLK_ASM)
415 # define preprocessing_trad_p() (cpp_get_options (pfile)->traditional)
416 # define preprocessing_asm_p() (0)
417 # define preprocessing_trad_p() (0)
418 # define c_dialect_cxx() (0)
419 # define c_dialect_objc() (0)
420 # define builtin_define(TXT) (cpp_define (pfile, TXT))
421 # define builtin_define_with_value(m,e,s)
422 # define builtin_define_with_int_value(m,i)
423 # define builtin_define_std(TXT) (cpp_define (pfile, TXT))
424 # define builtin_assert(TXT) (cpp_assert (pfile, TXT))
425 TARGET_CPU_CPP_BUILTINS ();
426 TARGET_OS_CPP_BUILTINS ();
427 TARGET_OBJFMT_CPP_BUILTINS ();
429 cpp_forall_identifiers(pfile
, & d_cpp_forall_callback
, NULL
);
435 VersionCondition::addPredefinedGlobalIdent("all");
438 // %%TODO: front or back?
441 char * target_dir
= prefixed_path(D_PHOBOS_TARGET_DIR
);
443 target_dir
= concat(target_dir
, "/", multilib_dir
, NULL
);
445 global
.params
.imppath
->insert(0, prefixed_path(D_PHOBOS_DIR
));
446 global
.params
.imppath
->insert(0, target_dir
);
449 if (global
.params
.imppath
)
451 for (unsigned i
= 0; i
< global
.params
.imppath
->dim
; i
++)
453 char *path
= (char *)global
.params
.imppath
->data
[i
];
454 // We would do this for D_INCLUDE_PATH env var, but not for '-I'
455 // command line args.
456 //Array *a = FileName::splitPath(path);
461 global
.path
= new Array();
462 //global.path->append(a);
463 global
.path
->push(path
);
468 if (global
.params
.fileImppath
)
470 for (unsigned i
= 0; i
< global
.params
.fileImppath
->dim
; i
++)
472 char *path
= (char *)global
.params
.fileImppath
->data
[i
];
475 if (!global
.filePath
)
476 global
.filePath
= new Array();
477 global
.filePath
->push(path
);
483 char * path
= FileName::searchPath(global
.path
, "phobos-ver-syms", 1);
485 FILE * f
= fopen(path
, "r");
489 while ( ! feof(f
) && fgets(buf
, 256, f
) ) {
491 while (*p
&& ISSPACE(*p
))
494 while (*q
&& ! ISSPACE(*q
))
498 /* Needs to be predefined because we define
499 Unix/Windows this way. */
500 VersionCondition::addPredefinedGlobalIdent(xstrdup(p
));
505 //printf("failed\n");
508 //printf("no p-v-s found\n");
516 parse_int (const char * arg
, int * value_ret
)
521 v
= strtol(arg
, & err
, 10);
522 if (*err
|| errno
|| v
> INT_MAX
)
529 d_handle_option (size_t scode
, const char *arg
, int value
)
531 enum opt_code code
= (enum opt_code
) scode
;
537 global
.params
.imppath
->push(xstrdup(arg
)); // %% not sure if we can keep the arg or not
540 global
.params
.fileImppath
->push(xstrdup(arg
));
542 case OPT_fdeprecated
:
543 global
.params
.useDeprecated
= value
;
546 global
.params
.useAssert
= value
;
549 global
.params
.useInvariants
= ! value
;
550 global
.params
.useIn
= ! value
;
551 global
.params
.useOut
= ! value
;
552 global
.params
.useAssert
= ! value
;
553 flag_bounds_check
= global
.params
.useArrayBounds
= ! value
;
554 global
.params
.useSwitchError
= ! value
;
557 global
.params
.useUnitTests
= value
;
560 if (ISDIGIT(arg
[0])) {
561 if (! parse_int(arg
, & level
))
563 VersionCondition::setGlobalLevel(level
);
564 } else if (Lexer::isValidIdentifier((char*) arg
))
565 VersionCondition::addGlobalIdent(xstrdup(arg
));
568 error("bad argument for -fversion");
572 global
.params
.debuglevel
= value
? 1 : 0;
575 if (ISDIGIT(arg
[0])) {
576 if (! parse_int(arg
, & level
))
578 DebugCondition::setGlobalLevel(level
);
579 } else if (Lexer::isValidIdentifier((char*) arg
))
580 DebugCondition::addGlobalIdent(xstrdup(arg
));
583 error("bad argument for -fdebug");
587 strcpy(lang_name
, value
? "GNU C" : "GNU D");
589 case OPT_fignore_unknown_pragmas
:
590 global
.params
.ignoreUnsupportedPragmas
= value
;
594 global
.params
.doHdrGeneration
= value
;
596 case OPT_fintfc_dir_
:
597 global
.params
.doHdrGeneration
= 1;
598 global
.params
.hdrdir
= xstrdup(arg
);
600 case OPT_fintfc_file_
:
601 global
.params
.doHdrGeneration
= 1;
602 global
.params
.hdrname
= xstrdup(arg
);
606 global
.params
.doDocComments
= value
;
609 global
.params
.doDocComments
= 1;
610 global
.params
.docdir
= xstrdup(arg
);
613 global
.params
.doDocComments
= 1;
614 global
.params
.docname
= xstrdup(arg
);
617 global
.params
.ddocfiles
->push(xstrdup(arg
));
620 global
.params
.verbose
= 1;
622 case OPT_fd_version_1
:
623 global
.params
.Dversion
= 1;
625 case OPT_femit_templates
:
626 gen
.emitTemplates
= value
? TEauto
: TEnone
;
628 case OPT_femit_templates_
:
629 if (! arg
|| ! *arg
) {
630 gen
.emitTemplates
= value
? TEauto
: TEnone
;
631 } else if (! strcmp(arg
, "normal")) {
632 gen
.emitTemplates
= TEnormal
;
633 } else if (! strcmp(arg
, "all")) {
634 gen
.emitTemplates
= TEall
;
635 } else if (! strcmp(arg
, "private")) {
636 gen
.emitTemplates
= TEprivate
;
637 } else if (! strcmp(arg
, "none")) {
638 gen
.emitTemplates
= TEnone
;
639 } else if (! strcmp(arg
, "auto")) {
640 gen
.emitTemplates
= TEauto
;
642 error("bad argument for -femit-templates");
646 fonly_arg
= xstrdup(arg
);
649 iprefix
= xstrdup(arg
);
651 case OPT_fmultilib_dir_
:
652 multilib_dir
= xstrdup(arg
);
657 case OPT_fdump_source
:
658 global
.params
.dump_source
= value
;
661 gen
.useBuiltins
= value
;
663 case OPT_fsigned_char
:
664 case OPT_funsigned_char
:
668 global
.params
.warnings
= value
;
669 gen
.warnSignCompare
= value
;
671 case OPT_Wsign_compare
:
672 gen
.warnSignCompare
= value
;
680 bool d_post_options(const char ** fn
)
682 // The front end considers the first input file to be the main one.
687 // Inline option code copied from c-opts.c
688 flag_inline_trees
= 1;
690 /* Use tree inlining. */
693 if (flag_inline_functions
)
694 flag_inline_trees
= 2;
696 /* If we are given more than one input file, we must use
697 unit-at-a-time mode. */
698 if (num_in_fnames
> 1)
699 flag_unit_at_a_time
= 1;
704 /* wrapup_global_declaration needs to be called or functions will not
706 Array globalFunctions
; // Array of tree (for easy passing to wrapup_global_declarations)
709 d_add_global_function(tree decl
)
711 globalFunctions
.push(decl
);
715 d_write_global_declarations()
717 tree
* vec
= (tree
*) globalFunctions
.data
;
718 wrapup_global_declarations(vec
, globalFunctions
.dim
);
719 check_global_declarations(vec
, globalFunctions
.dim
);
727 for (int i
= 0; i
< globalFunctions
.dim
; i
++)
728 debug_hooks
->global_decl(vec
[i
]);
731 /* For 4.0.x, if cgraph_optimize is called before the loop over
732 globalFunctions, dwarf2out can generate a DIE tree that has a
733 nested class as the parent of an outer class (this causes an
734 ICE.) Not sure if this is due to a bug in the D front end, but calling
735 debug_hooks->global_decl ensures the outer elements are
738 For later versions, calling cgraph_optimize later causes more
748 // taken from c_common_unsafe_for_reeval
750 d_unsafe_for_reeval (tree exp
)
752 /* Statement expressions may not be reevaluated. */
753 if (TREE_CODE (exp
) == (enum tree_code
) D_STMT_EXPR
)
756 /* Walk all other expressions. */
761 static Module
* an_output_module
= 0;
764 d_gcc_get_output_module()
766 return an_output_module
;
770 nametype(tree type
, const char * name
)
772 tree ident
= get_identifier(name
);
773 tree decl
= build_decl(TYPE_DECL
, ident
, type
);
774 TYPE_NAME(type
) = decl
;
775 ObjectFile::rodc(decl
, 1);
781 nametype(t
->toCtype(), t
->toChars());
785 Symbol
* rtlsym
[N_RTLSYM
];
789 d_parse_file (int /*set_yydebug*/)
797 if (global
.params
.verbose
&& asm_out_file
== stdout
)
799 // Really, driver should see the option and turn off -pipe
800 error("Cannot use -fd-verbose with -pipe");
804 if (global
.params
.useUnitTests
)
805 global
.params
.useAssert
= 1;
806 global
.params
.useArrayBounds
= flag_bounds_check
;
807 if (gen
.emitTemplates
== TEauto
) {
808 gen
.emitTemplates
= (supports_one_only()) ? TEnormal
: TEprivate
;
810 global
.params
.symdebug
= write_symbols
!= NO_DEBUG
;
811 //global.params.useInline = flag_inline_functions;
812 global
.params
.obj
= ! flag_syntax_only
;
813 global
.params
.pic
= flag_pic
!= 0; // Has no effect yet.
814 gen
.originalOmitFramePointer
= flag_omit_frame_pointer
;
816 // better to use input_location.xxx ?
817 (*debug_hooks
->start_source_file
) (input_line
, input_filename
);
820 printf("input_filename = '%s'\n", input_filename);
821 printf("main_input_filename = '%s'\n", main_input_filename);
827 Type::tbit
->toCtype();
829 Type::tbool
->toCtype();
830 Type::tchar
->toCtype();
831 Type::twchar
->toCtype();
832 Type::tdchar
->toCtype();
834 for (TY ty
= (TY
) 0; ty
< TMAX
; ty
= (TY
)(ty
+ 1)) {
836 nametype(Type::basic
[ty
]);
840 p = FileName::name(input_filename);
841 e = FileName::ext(p);
845 name = (char *) xmalloc((e - p) + 1);
846 memcpy(name, p, e - p);
851 an_output_module
= NULL
;
852 Array modules
; // vs. outmodules... = [an_output_module] or modules
853 modules
.reserve(num_in_fnames
);
856 if ( ! input_filename
) {
857 ::error("input file name required; cannot use stdin");
862 /* In this mode, the first file name is supposed to be
863 a duplicate of one of the input file. */
864 if (strcmp(fonly_arg
, input_filename
))
865 ::error("-fonly= argument is different from main input file name");
866 if (strcmp(fonly_arg
, in_fnames
[0]))
867 ::error("-fonly= argument is different from first input file name");
870 //fprintf (stderr, "***** %d files main=%s\n", num_in_fnames, input_filename);
872 for (i
= 0; i
< num_in_fnames
; i
++) {
876 /* %% Do the other modules really need to be processed?
877 else if (an_output_module)
882 //fprintf(stderr, "fn %d = %s\n", i, in_fnames[i]);
884 char * the_fname
= (char*) in_fnames
[i
];
887 p
= FileName::name(the_fname
);
888 e
= FileName::ext(p
);
890 isDltFile
= (stricmp(e
, "dlt") == 0);
893 name
= (char *) xmalloc((e
- p
) + 1);
894 memcpy(name
, p
, e
- p
);
898 strcmp(name
, "..") == 0 ||
899 strcmp(name
, ".") == 0)
902 ::error("invalid file name '%s'", the_fname
);
912 id
= new Identifier(name
, 0);
913 Module
* m
= new Module(the_fname
, id
, global
.params
.doDocComments
, global
.params
.doHdrGeneration
, isDltFile
);
914 if (! strcmp(in_fnames
[i
], input_filename
))
915 an_output_module
= m
;
920 // There is only one of these so far...
921 rtlsym
[RTLSYM_DHIDDENFUNC
] =
922 gen
.getLibCallDecl(LIBCALL_HIDDEN_FUNC
)->toSymbol();
925 // current_module shouldn't have any implications before genobjfile..
926 // ... but it does. We need to know what module in which to insert
927 // TemplateInstanceS during the semantic pass. In order for
928 // -femit-templates=private to work, template instances must be emitted
929 // in every translation unit. To do this, the TemplateInstaceS have to
930 // have toObjFile called in the module being compiled.
931 // TemplateInstance puts itself somwhere during ::semantic, thus it has
932 // to know the current module...
934 assert(an_output_module
);
938 //global.params.verbose = 1;
940 // Read files, parse them
941 for (i
= 0; i
< modules
.dim
; i
++)
943 m
= (Module
*)modules
.data
[i
];
944 if (global
.params
.verbose
)
945 printf("parse %s\n", m
->toChars());
946 if (!Module::rootModule
)
947 Module::rootModule
= m
;
949 //m->deleteObjFile(); // %% driver does this
951 m
->parse(global
.params
.dump_source
);
952 d_gcc_magic_module(m
);
957 // Remove m from list of modules
966 if (global
.params
.doHdrGeneration
)
968 /* Generate 'header' import files.
969 * Since 'header' import files must be independent of command
970 * line switches and what else is imported, they are generated
971 * before any semantic analysis.
973 for (i
= 0; i
< modules
.dim
; i
++)
975 m
= (Module
*)modules
.data
[i
];
976 if (fonly_arg
&& m
!= an_output_module
)
978 if (global
.params
.verbose
)
979 printf("import %s\n", m
->toChars());
987 // Do semantic analysis
988 for (i
= 0; i
< modules
.dim
; i
++)
990 m
= (Module
*)modules
.data
[i
];
991 if (global
.params
.verbose
)
992 printf("semantic %s\n", m
->toChars());
998 // Do pass 2 semantic analysis
999 for (i
= 0; i
< modules
.dim
; i
++)
1001 m
= (Module
*)modules
.data
[i
];
1002 if (global
.params
.verbose
)
1003 printf("semantic2 %s\n", m
->toChars());
1009 // Do pass 3 semantic analysis
1010 for (i
= 0; i
< modules
.dim
; i
++)
1012 m
= (Module
*)modules
.data
[i
];
1013 if (global
.params
.verbose
)
1014 printf("semantic3 %s\n", m
->toChars());
1020 // Scan for functions to inline
1021 if (global
.params
.useInline
)
1023 for (i
= 0; i
< modules
.dim
; i
++)
1025 m
= (Module
*)modules
.data
[i
];
1026 if (global
.params
.verbose
)
1027 printf("inline scan %s\n", m
->toChars());
1034 g
.ofile
= new ObjectFile();
1036 g
.ofile
->modules
.push(an_output_module
);
1038 g
.ofile
->modules
.append(& modules
);
1039 g
.irs
= & gen
; // needed for FuncDeclaration::toObjFile shouldDefer check
1041 // Generate output files
1042 for (i
= 0; i
< modules
.dim
; i
++)
1044 m
= (Module
*)modules
.data
[i
];
1045 if (fonly_arg
&& m
!= an_output_module
)
1047 if (global
.params
.verbose
)
1048 printf("code %s\n", m
->toChars());
1049 if (! flag_syntax_only
)
1050 m
->genobjfile(false);
1051 if (! global
.errors
&& ! errorcount
)
1053 if (global
.params
.doDocComments
)
1058 // better to use input_location.xxx ?
1059 (*debug_hooks
->end_source_file
) (input_line
);
1061 // Add DMD error count to GCC error count to to exit with error status
1062 errorcount
+= global
.errors
;
1067 cgraph_finalize_compilation_unit();
1070 an_output_module
= 0;
1072 gcc_d_backend_term();
1076 d_gcc_dump_source(const char * srcname
, const char * ext
, unsigned char * data
, unsigned len
)
1078 // Note: There is a dump_base_name variable, but as long as the all-sources hack is in
1079 // around, the base name has to be determined here.
1081 /* construct output name */
1082 char* base
= (char*) alloca(strlen(srcname
)+1);
1083 base
= strcpy(base
, srcname
);
1084 base
= basename(base
);
1086 char* name
= (char*) alloca(strlen(base
)+strlen(ext
)+2);
1087 name
= strcpy(name
, base
);
1089 name
= strcat(name
, ".");
1090 name
= strcat(name
, ext
);
1094 * ignores if the output file exists
1095 * ignores if the output fails
1097 FILE* output
= fopen(name
, "w");
1099 fwrite(data
, 1, len
, output
);
1109 d_mark_addressable (tree t
)
1113 switch (TREE_CODE (x
))
1117 /* If D had bit fields, we would need to handle that here */
1121 x
= TREE_OPERAND (x
, 0);
1123 /* %% C++ prevents {& this} .... */
1124 /* %% TARGET_EXPR ... */
1125 case TRUTH_ANDIF_EXPR
:
1126 case TRUTH_ORIF_EXPR
:
1128 x
= TREE_OPERAND (x
, 1);
1132 return d_mark_addressable (TREE_OPERAND (x
, 1))
1133 && d_mark_addressable (TREE_OPERAND (x
, 2));
1136 TREE_ADDRESSABLE (x
) = 1;
1140 /* %% this was in Java, not sure for D */
1141 /* We sometimes add a cast *(TYPE*)&FOO to handle type and mode
1142 incompatibility problems. Handle this case by marking FOO. */
1143 if (TREE_CODE (TREE_OPERAND (x
, 0)) == NOP_EXPR
1144 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (x
, 0), 0)) == ADDR_EXPR
)
1146 x
= TREE_OPERAND (TREE_OPERAND (x
, 0), 0);
1149 if (TREE_CODE (TREE_OPERAND (x
, 0)) == ADDR_EXPR
)
1151 x
= TREE_OPERAND (x
, 0);
1161 if ( ! TREE_STATIC(x
) ) // %% C doesn't do this check
1162 put_var_into_stack(x
, 1);
1166 TREE_ADDRESSABLE (x
) = 1;
1178 d_type_for_mode (enum machine_mode mode
, int unsignedp
)
1180 // taken from c-common.c
1181 if (mode
== TYPE_MODE (integer_type_node
))
1182 return unsignedp
? unsigned_type_node
: integer_type_node
;
1184 if (mode
== TYPE_MODE (signed_char_type_node
))
1185 return unsignedp
? unsigned_char_type_node
: signed_char_type_node
;
1187 if (mode
== TYPE_MODE (short_integer_type_node
))
1188 return unsignedp
? short_unsigned_type_node
: short_integer_type_node
;
1190 if (mode
== TYPE_MODE (long_integer_type_node
))
1191 return unsignedp
? long_unsigned_type_node
: long_integer_type_node
;
1193 if (mode
== TYPE_MODE (long_long_integer_type_node
))
1194 return unsignedp
? long_long_unsigned_type_node
: long_long_integer_type_node
;
1197 if (mode == TYPE_MODE (widest_integer_literal_type_node))
1198 return unsignedp ? widest_unsigned_literal_type_node
1199 : widest_integer_literal_type_node;
1202 return unsignedp
? unsigned_intQI_type_node
: intQI_type_node
;
1205 return unsignedp
? unsigned_intHI_type_node
: intHI_type_node
;
1208 return unsignedp
? unsigned_intSI_type_node
: intSI_type_node
;
1211 return unsignedp
? unsigned_intDI_type_node
: intDI_type_node
;
1213 #if HOST_BITS_PER_WIDE_INT >= 64
1214 if (mode
== TYPE_MODE (intTI_type_node
))
1215 return unsignedp
? unsigned_intTI_type_node
: intTI_type_node
;
1218 if (mode
== TYPE_MODE (float_type_node
))
1219 return float_type_node
;
1221 if (mode
== TYPE_MODE (double_type_node
))
1222 return double_type_node
;
1224 if (mode
== TYPE_MODE (long_double_type_node
))
1225 return long_double_type_node
;
1227 if (mode
== TYPE_MODE (build_pointer_type (char_type_node
)))
1228 return build_pointer_type (char_type_node
);
1230 if (mode
== TYPE_MODE (build_pointer_type (integer_type_node
)))
1231 return build_pointer_type (integer_type_node
);
1237 return unsignedp
? unsigned_V16QI_type_node
: V16QI_type_node
;
1239 return unsignedp
? unsigned_V8HI_type_node
: V8HI_type_node
;
1241 return unsignedp
? unsigned_V4SI_type_node
: V4SI_type_node
;
1243 return unsignedp
? unsigned_V2DI_type_node
: V2DI_type_node
;
1245 return unsignedp
? unsigned_V2SI_type_node
: V2SI_type_node
;
1247 return unsignedp
? unsigned_V2HI_type_node
: V2HI_type_node
;
1249 return unsignedp
? unsigned_V4HI_type_node
: V4HI_type_node
;
1251 return unsignedp
? unsigned_V8QI_type_node
: V8QI_type_node
;
1253 return unsignedp
? unsigned_V1DI_type_node
: V1DI_type_node
;
1255 return V16SF_type_node
;
1257 return V4SF_type_node
;
1259 return V2SF_type_node
;
1261 return V2DF_type_node
;
1266 if (COMPLEX_MODE_P (mode
))
1268 enum machine_mode inner_mode
;
1271 if (mode
== TYPE_MODE (complex_float_type_node
))
1272 return complex_float_type_node
;
1273 if (mode
== TYPE_MODE (complex_double_type_node
))
1274 return complex_double_type_node
;
1275 if (mode
== TYPE_MODE (complex_long_double_type_node
))
1276 return complex_long_double_type_node
;
1278 if (mode
== TYPE_MODE (complex_integer_type_node
) && !unsignedp
)
1279 return complex_integer_type_node
;
1281 inner_mode
= (machine_mode
) GET_MODE_INNER (mode
);
1282 inner_type
= d_type_for_mode (inner_mode
, unsignedp
);
1283 if (inner_type
!= NULL_TREE
)
1284 return build_complex_type (inner_type
);
1286 else if (VECTOR_MODE_P (mode
))
1288 enum machine_mode inner_mode
= (machine_mode
) GET_MODE_INNER (mode
);
1289 tree inner_type
= d_type_for_mode (inner_mode
, unsignedp
);
1290 if (inner_type
!= NULL_TREE
)
1291 return build_vector_type_for_mode (inner_type
, mode
);
1299 d_type_for_size (unsigned bits
, int unsignedp
)
1301 if (bits
== TYPE_PRECISION (integer_type_node
))
1302 return unsignedp
? unsigned_type_node
: integer_type_node
;
1304 if (bits
== TYPE_PRECISION (signed_char_type_node
))
1305 return unsignedp
? unsigned_char_type_node
: signed_char_type_node
;
1307 if (bits
== TYPE_PRECISION (short_integer_type_node
))
1308 return unsignedp
? short_unsigned_type_node
: short_integer_type_node
;
1310 if (bits
== TYPE_PRECISION (long_integer_type_node
))
1311 return unsignedp
? long_unsigned_type_node
: long_integer_type_node
;
1313 if (bits
== TYPE_PRECISION (long_long_integer_type_node
))
1314 return (unsignedp
? long_long_unsigned_type_node
1315 : long_long_integer_type_node
);
1317 if (bits == TYPE_PRECISION (widest_integer_literal_type_node))
1318 return (unsignedp ? widest_unsigned_literal_type_node
1319 : widest_integer_literal_type_node);
1321 if (bits
<= TYPE_PRECISION (intQI_type_node
))
1322 return unsignedp
? unsigned_intQI_type_node
: intQI_type_node
;
1324 if (bits
<= TYPE_PRECISION (intHI_type_node
))
1325 return unsignedp
? unsigned_intHI_type_node
: intHI_type_node
;
1327 if (bits
<= TYPE_PRECISION (intSI_type_node
))
1328 return unsignedp
? unsigned_intSI_type_node
: intSI_type_node
;
1330 if (bits
<= TYPE_PRECISION (intDI_type_node
))
1331 return unsignedp
? unsigned_intDI_type_node
: intDI_type_node
;
1337 d_unsigned_type (tree type
)
1339 tree type1
= TYPE_MAIN_VARIANT (type
);
1340 if (type1
== signed_char_type_node
|| type1
== char_type_node
)
1341 return unsigned_char_type_node
;
1342 if (type1
== integer_type_node
)
1343 return unsigned_type_node
;
1344 if (type1
== short_integer_type_node
)
1345 return short_unsigned_type_node
;
1346 if (type1
== long_integer_type_node
)
1347 return long_unsigned_type_node
;
1348 if (type1
== long_long_integer_type_node
)
1349 return long_long_unsigned_type_node
;
1351 if (type1 == widest_integer_literal_type_node)
1352 return widest_unsigned_literal_type_node;
1354 #if HOST_BITS_PER_WIDE_INT >= 64
1355 if (type1
== intTI_type_node
)
1356 return unsigned_intTI_type_node
;
1358 if (type1
== intDI_type_node
)
1359 return unsigned_intDI_type_node
;
1360 if (type1
== intSI_type_node
)
1361 return unsigned_intSI_type_node
;
1362 if (type1
== intHI_type_node
)
1363 return unsigned_intHI_type_node
;
1364 if (type1
== intQI_type_node
)
1365 return unsigned_intQI_type_node
;
1367 return d_signed_or_unsigned_type (1, type
);
1371 d_signed_type (tree type
)
1373 tree type1
= TYPE_MAIN_VARIANT (type
);
1374 if (type1
== unsigned_char_type_node
|| type1
== char_type_node
)
1375 return signed_char_type_node
;
1376 if (type1
== unsigned_type_node
)
1377 return integer_type_node
;
1378 if (type1
== short_unsigned_type_node
)
1379 return short_integer_type_node
;
1380 if (type1
== long_unsigned_type_node
)
1381 return long_integer_type_node
;
1382 if (type1
== long_long_unsigned_type_node
)
1383 return long_long_integer_type_node
;
1385 if (type1 == widest_unsigned_literal_type_node)
1386 return widest_integer_literal_type_node;
1388 #if HOST_BITS_PER_WIDE_INT >= 64
1389 if (type1
== unsigned_intTI_type_node
)
1390 return intTI_type_node
;
1392 if (type1
== unsigned_intDI_type_node
)
1393 return intDI_type_node
;
1394 if (type1
== unsigned_intSI_type_node
)
1395 return intSI_type_node
;
1396 if (type1
== unsigned_intHI_type_node
)
1397 return intHI_type_node
;
1398 if (type1
== unsigned_intQI_type_node
)
1399 return intQI_type_node
;
1401 return d_signed_or_unsigned_type (0, type
);
1405 d_signed_or_unsigned_type (int unsignedp
, tree type
)
1407 if (! INTEGRAL_TYPE_P (type
)
1408 || TREE_UNSIGNED (type
) == (unsigned) unsignedp
)
1411 if (TYPE_PRECISION (type
) == TYPE_PRECISION (signed_char_type_node
))
1412 return unsignedp
? unsigned_char_type_node
: signed_char_type_node
;
1413 if (TYPE_PRECISION (type
) == TYPE_PRECISION (integer_type_node
))
1414 return unsignedp
? unsigned_type_node
: integer_type_node
;
1415 if (TYPE_PRECISION (type
) == TYPE_PRECISION (short_integer_type_node
))
1416 return unsignedp
? short_unsigned_type_node
: short_integer_type_node
;
1417 if (TYPE_PRECISION (type
) == TYPE_PRECISION (long_integer_type_node
))
1418 return unsignedp
? long_unsigned_type_node
: long_integer_type_node
;
1419 if (TYPE_PRECISION (type
) == TYPE_PRECISION (long_long_integer_type_node
))
1420 return (unsignedp
? long_long_unsigned_type_node
1421 : long_long_integer_type_node
);
1423 if (TYPE_PRECISION (type) == TYPE_PRECISION (widest_integer_literal_type_node))
1424 return (unsignedp ? widest_unsigned_literal_type_node
1425 : widest_integer_literal_type_node);
1427 #if HOST_BITS_PER_WIDE_INT >= 64
1428 if (TYPE_PRECISION (type
) == TYPE_PRECISION (intTI_type_node
))
1429 return unsignedp
? unsigned_intTI_type_node
: intTI_type_node
;
1431 if (TYPE_PRECISION (type
) == TYPE_PRECISION (intDI_type_node
))
1432 return unsignedp
? unsigned_intDI_type_node
: intDI_type_node
;
1433 if (TYPE_PRECISION (type
) == TYPE_PRECISION (intSI_type_node
))
1434 return unsignedp
? unsigned_intSI_type_node
: intSI_type_node
;
1435 if (TYPE_PRECISION (type
) == TYPE_PRECISION (intHI_type_node
))
1436 return unsignedp
? unsigned_intHI_type_node
: intHI_type_node
;
1437 if (TYPE_PRECISION (type
) == TYPE_PRECISION (intQI_type_node
))
1438 return unsignedp
? unsigned_intQI_type_node
: intQI_type_node
;
1444 #define TYPE_UNSIGNED TREE_UNSIGNED
1447 /* Type promotion for variable arguments. */
1449 d_type_promotes_to (tree type
)
1451 /* Almost the same as c_type_promotes_to. This is needed varargs to work on
1453 if (TYPE_MAIN_VARIANT (type
) == float_type_node
)
1454 return double_type_node
;
1456 // not quite the same as... if (c_promoting_integer_type_p (type))
1457 if (INTEGRAL_TYPE_P (type
) &&
1458 (TYPE_PRECISION (type
) < TYPE_PRECISION (integer_type_node
)) )
1460 /* Preserve unsignedness if not really getting any wider. */
1461 if (TYPE_UNSIGNED (type
)
1462 && (TYPE_PRECISION (type
) == TYPE_PRECISION (integer_type_node
)))
1463 return unsigned_type_node
;
1464 return integer_type_node
;
1471 extern "C" void pushlevel
PARAMS ((int));
1472 extern "C" tree poplevel
PARAMS ((int, int, int));
1473 extern "C" int global_bindings_p
PARAMS ((void));
1474 extern "C" void insert_block
PARAMS ((tree
));
1475 extern "C" void set_block
PARAMS ((tree
));
1476 extern "C" tree getdecls
PARAMS ((void));
1479 struct binding_level
* current_binding_level
;
1480 struct binding_level
* global_binding_level
;
1483 static binding_level
*
1484 alloc_binding_level()
1486 return (struct binding_level
*) ggc_alloc_cleared (sizeof (struct binding_level
));
1489 /* The D front-end does not use the 'binding level' system for a symbol table,
1490 It is only needed to get debugging information for local variables and
1491 otherwise support the backend. */
1494 pushlevel (int /*arg*/)
1496 binding_level
* new_level
= alloc_binding_level();
1497 new_level
->level_chain
= current_binding_level
;
1498 current_binding_level
= new_level
;
1502 poplevel (int keep
, int reverse
, int routinebody
)
1504 binding_level
* level
= current_binding_level
;
1507 current_binding_level
= level
->level_chain
;
1508 decls
= level
->names
;
1510 decls
= nreverse(decls
);
1512 if ( level
->this_block
)
1513 block
= level
->this_block
;
1514 else if (keep
|| routinebody
)
1515 block
= make_node(BLOCK
);
1520 BLOCK_VARS( block
) = routinebody
? NULL_TREE
: decls
;
1521 BLOCK_SUBBLOCKS( block
) = level
->blocks
;
1522 // %% need this for when insert_block is called by backend... or make
1523 // insert_block do it's work elsewere
1524 // BLOCK_SUBBLOCKS( block ) = level->blocks;
1525 // %% pascal does: in each subblock, record that this is the superiod..
1527 /* In each subblock, record that this is its superior. */
1528 for (tree t
= level
->blocks
; t
; t
= TREE_CHAIN (t
))
1529 BLOCK_SUPERCONTEXT (t
) = block
;
1530 /* Dispose of the block that we just made inside some higher level. */
1532 DECL_INITIAL (current_function_decl
) = block
;
1535 // Original logic was: If this block was created by this poplevel
1536 // call and not and earlier set_block, insert it into the parent's
1537 // list of blocks. Blocks created with set_block have to be
1538 // inserted with insert_block.
1540 // For D, currently always using set_block/insert_block
1541 if (!level
->this_block
)
1542 current_binding_level
->blocks
= chainon (current_binding_level
->blocks
, block
);
1544 /* If we did not make a block for the level just exited, any blocks made for inner
1545 levels (since they cannot be recorded as subblocks in that level) must be
1546 carried forward so they will later become subblocks of something else. */
1547 else if (level
->blocks
)
1548 current_binding_level
->blocks
= chainon (current_binding_level
->blocks
, level
->blocks
);
1550 TREE_USED (block
) = 1;
1555 global_bindings_p (void)
1557 // This is called by the backend before parsing. Need to make this do
1558 // something or lang_hooks.clear_binding_stack (lhd_clear_binding_stack)
1560 return current_binding_level
== global_binding_level
|| ! global_binding_level
;
1564 init_global_binding_level()
1566 current_binding_level
= global_binding_level
= alloc_binding_level();
1571 insert_block (tree block
)
1573 TREE_USED (block
) = 1;
1574 current_binding_level
->blocks
= chainon (current_binding_level
->blocks
, block
);
1578 set_block (tree block
)
1580 current_binding_level
->this_block
= block
;
1584 pushdecl (tree decl
)
1586 // %% Pascal: if not a local external routine decl doesn't consitite nesting
1588 // %% probably should be cur_irs->getDeclContext()
1589 // %% should only be for variables OR, should also use TRANSLATION_UNIT for toplevel..
1590 if ( DECL_CONTEXT( decl
) == NULL_TREE
)
1591 DECL_CONTEXT( decl
) = current_function_decl
; // could be NULL_TREE (top level) .. hmm. // hm.m.
1593 /* Put decls on list in reverse order. We will reverse them later if necessary. */
1594 TREE_CHAIN (decl
) = current_binding_level
->names
;
1595 current_binding_level
->names
= decl
;
1596 if (!TREE_CHAIN (decl
))
1597 current_binding_level
->names_end
= decl
;
1601 /* pushdecl_top_level is only for building with Apple GCC. */
1603 pushdecl_top_level (tree x
)
1606 struct binding_level
*b
= current_binding_level
;
1608 current_binding_level
= global_binding_level
;
1610 current_binding_level
= b
;
1616 set_decl_binding_chain(tree decl_chain
)
1618 assert(current_binding_level
);
1619 current_binding_level
->names
= decl_chain
;
1623 // Supports dbx and stabs
1627 if (current_binding_level
)
1628 return current_binding_level
->names
;
1634 /* Tree code classes. */
1637 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
1641 tree_code_type
[] = {
1644 #include "dlt/d-tree.def"
1649 const enum tree_code_class
1650 tree_code_type
[] = {
1653 #include "dlt/d-tree.def"
1659 /* Table indexed by tree code giving number of expression
1660 operands beyond the fixed part of the node structure.
1661 Not used for types or decls. */
1663 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
1665 const unsigned char tree_code_length
[] = {
1668 #include "dlt/d-tree.def"
1672 /* Names of tree components.
1673 Used for printing out the tree and error messages. */
1674 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
1676 const char *const tree_code_name
[] = {
1679 #include "dlt/d-tree.def"
1686 d_expand_function(tree fndecl
)
1688 if (!DECL_INITIAL (fndecl
)
1689 || DECL_INITIAL (fndecl
) == error_mark_node
)
1692 bool save_flag
= flag_omit_frame_pointer
;
1693 flag_omit_frame_pointer
= gen
.originalOmitFramePointer
||
1694 D_DECL_NO_FRAME_POINTER( fndecl
);
1696 tree_rest_of_compilation (fndecl
);
1698 flag_omit_frame_pointer
= save_flag
;
1700 if (DECL_STATIC_CONSTRUCTOR (fndecl
)
1701 && targetm
.have_ctors_dtors
)
1702 targetm
.asm_out
.constructor (XEXP (DECL_RTL (fndecl
), 0),
1703 DEFAULT_INIT_PRIORITY
);
1704 if (DECL_STATIC_DESTRUCTOR (fndecl
)
1705 && targetm
.have_ctors_dtors
)
1706 targetm
.asm_out
.destructor (XEXP (DECL_RTL (fndecl
), 0),
1707 DEFAULT_INIT_PRIORITY
);
1714 d_types_compatible_p (tree x
, tree y
)
1716 if (lhd_types_compatible_p(x
, y
))
1718 else if (d_gcc_builtin_va_list_d_type
&&
1720 ( x
== d_gcc_builtin_va_list_d_type
->ctype
&&
1721 y
== va_list_type_node
) ||
1722 ( y
== d_gcc_builtin_va_list_d_type
->ctype
&&
1723 x
== va_list_type_node
) ))
1728 return TYPE_MAIN_VARIANT (x
) == TYPE_MAIN_VARIANT (y
);
1733 /* DMD 2 makes a parameter delclaration's type 'const(T)' if the
1734 parameter is a simple STCin or STCconst. The TypeFunction's
1735 Argument's type stays unqualified, however.
1737 This mismatch causes a problem with optimization and inlining. For
1738 RECORD_TYPE arguments, failure will occur in (setup_one_parameter
1739 -> fold_convert). d_types_compatible_p hacks lead to failures in
1742 Fortunately, the middle end provides a simple workaround by using
1747 d_convert_parm_for_inlining (tree parm
, tree value
, tree fndecl
, int argnum
)
1749 if (TREE_TYPE(parm
) != TREE_TYPE(value
))
1750 return build1(NOP_EXPR
, TREE_TYPE(parm
), value
);
1760 build_d_type_lang_specific(Type
* t
)
1762 struct lang_type
* l
= (struct lang_type
*) ggc_alloc_cleared( sizeof(struct lang_type
) );
1767 tree d_keep_list
= NULL_TREE
;
1772 d_keep_list
= tree_cons(NULL_TREE
, t
, d_keep_list
);
1776 const struct lang_hooks lang_hooks
= LANG_HOOKS_INITIALIZER
;