1 #include "d-gcc-includes.h"
13 /* struct rtx was modified for c++; this macro from rtl.h needs to
14 be modified accordingly. */
16 #define XEXP(RTX, N) (RTL_CHECK2 (RTX, N, 'e', 'u').rt_rtx)
19 static tree
dt2tree(dt_t
* dt
);
21 ModuleInfo
* ObjectFile::moduleInfo
;
22 Array
ObjectFile::modules
;
23 unsigned ObjectFile::moduleSearchIndex
;
24 Array
ObjectFile::deferredThunks
;
25 Array
ObjectFile::staticCtorList
;
26 Array
ObjectFile::staticDtorList
;
31 target_ptrdiff_t offset
;
34 ObjectFile::ObjectFile()
39 ObjectFile::beginModule(Module
* m
)
41 moduleInfo
= new ModuleInfo
;
46 ObjectFile::endModule()
48 for (unsigned i
= 0; i
< deferredThunks
.dim
; i
++) {
49 DeferredThunk
* t
= (DeferredThunk
*) deferredThunks
.data
[i
];
50 outputThunk(t
->decl
, t
->target
, t
->offset
);
52 deferredThunks
.setDim(0);
58 ObjectFile::hasModule(Module
*m
)
60 if (!m
|| ! modules
.dim
)
63 if (modules
.data
[moduleSearchIndex
] == m
)
65 for (unsigned i
= 0; i
< modules
.dim
; i
++) {
66 if ( (Module
*) modules
.data
[i
] == m
) {
67 moduleSearchIndex
= i
;
77 /* If the target does not directly support static constructors,
78 staticCtorList contains a list of all static constructors defined
79 so far. This routine will create a function to call all of those
80 and is picked up by collect2. */
81 if (staticCtorList
.dim
) {
82 doFunctionToCallFunctions(IDENTIFIER_POINTER(get_file_function_name('I')),
83 & staticCtorList
, true);
85 if (staticDtorList
.dim
) {
86 doFunctionToCallFunctions(IDENTIFIER_POINTER(get_file_function_name('D')),
87 & staticDtorList
, true);
92 ObjectFile::doLineNote(const Loc
& loc
)
97 location_t gcc_loc
= { loc
.filename
, loc
.linnum
};
98 emit_line_note (gcc_loc
);
106 ObjectFile::setLoc(const Loc
& loc
)
109 location_t gcc_loc
= { loc
.filename
, loc
.linnum
};
110 input_location
= gcc_loc
;
117 ObjectFile::setDeclLoc(tree t
, const Loc
& loc
)
119 // DWARF2 will often crash if the DECL_SOURCE_FILE is not set. It's
120 // easier the error here.
121 assert(loc
.filename
);
122 DECL_SOURCE_FILE (t
) = loc
.filename
;
123 DECL_SOURCE_LINE (t
) = loc
.linnum
;
127 ObjectFile::setDeclLoc(tree t
, Dsymbol
* decl
)
130 if (decl
->loc
.filename
) {
131 setDeclLoc(t
, decl
->loc
);
134 decl
= decl
->toParent();
137 // fallback; backend sometimes crashes if not set
141 Module
* m
= decl
->getModule();
142 if (m
&& m
->srcfile
&& m
->srcfile
->name
) {
143 l
.filename
= m
->srcfile
->name
->str
;
145 l
.filename
= "<no_file>"; // Emptry string can mess up debug info
152 ObjectFile::giveDeclUniqueName(tree decl
, const char * prefix
)
154 /* It would be nice to be able to use TRANSLATION_UNIT_DECL
155 so lhd_set_decl_assembler_name would do this automatically.
156 Unforntuately, the non-NULL decl context confuses dwarf2out.
158 Maybe this is fixed in later versions of GCC.
164 else if (DECL_NAME(decl
))
165 name
= IDENTIFIER_POINTER(DECL_NAME(decl
));
168 char *label
= d_asm_format_private_name(name
, DECL_UID(decl
));
169 SET_DECL_ASSEMBLER_NAME(decl
, get_identifier(label
));
175 is_function_nested_in_function(Dsymbol
* dsym
)
177 FuncDeclaration
* fd
= dsym
->isFuncDeclaration();
178 AggregateDeclaration
* ad
;
179 ClassDeclaration
* cd
;
183 else if (fd
->isNested())
185 else if ( (ad
= fd
->isThis()) && (cd
= ad
->isClassDeclaration()) )
187 while (cd
&& cd
->isNested())
189 dsym
= cd
->toParent2();
190 if (dsym
->isFuncDeclaration())
193 cd
= dsym
->isClassDeclaration();
202 ObjectFile::makeDeclOneOnly(tree decl_tree
, Dsymbol
* dsym
)
204 /* First method: Use one-only/coalesced attribute.
206 If user has specified -femit-templates=private, honor that
207 even if the target supports one-only. */
208 if ( ! D_DECL_IS_TEMPLATE( decl_tree
) || gen
.emitTemplates
!= TEprivate
) {
209 /* Weak definitions have to be public. Nested functions may or
210 may not be emitted as public even if TREE_PUBLIC is set.
211 There is no way to tell if the back end implements
212 make_decl_one_only with DECL_WEAK, so this check is
214 if ( (TREE_CODE(decl_tree
) == FUNCTION_DECL
&&
215 decl_function_context(decl_tree
) != NULL_TREE
&&
216 ! DECL_NO_STATIC_CHAIN(decl_tree
))
218 || ( dsym
&& is_function_nested_in_function(dsym
) )
225 #ifdef MAKE_DECL_COALESCED
226 // %% TODO: check if available like SUPPORTS_ONE_ONLY
228 MAKE_DECL_COALESCED( decl_tree
);
231 /* The following makes assumptions about the behavior
232 of make_decl_one_only */
233 if (SUPPORTS_ONE_ONLY
) { // Must check, otherwise backend will abort
234 make_decl_one_only( decl_tree
);
236 } else if (SUPPORTS_WEAK
) {
237 tree orig_init
= DECL_INITIAL( decl_tree
);
238 DECL_INITIAL( decl_tree
) = integer_zero_node
;
239 make_decl_one_only( decl_tree
);
240 DECL_INITIAL( decl_tree
) = orig_init
;
245 /* Second method: Make a private copy.
247 For RTTI, we can always make a private copy. For templates, only do
248 this if the user specified -femit-templates=private. */
249 if ( ! D_DECL_IS_TEMPLATE( decl_tree
) || gen
.emitTemplates
== TEprivate
) {
250 TREE_PRIVATE(decl_tree
) = 1;
251 TREE_PUBLIC(decl_tree
) = 0;
253 static bool warned
= false;
256 ::warning(0, "system does not support one-only linkage");
262 ObjectFile::setupSymbolStorage(Dsymbol
* dsym
, tree decl_tree
, bool force_static_public
)
264 Declaration
* real_decl
= dsym
->isDeclaration();
265 FuncDeclaration
* func_decl
= real_decl
? real_decl
->isFuncDeclaration() : 0;
267 if (force_static_public
||
268 ( TREE_CODE( decl_tree
) == VAR_DECL
&& (real_decl
&& real_decl
->isDataseg()) ) ||
269 ( TREE_CODE( decl_tree
) == FUNCTION_DECL
) ) {
271 bool is_template
= false;
272 Dsymbol
* sym
= dsym
->toParent();
273 Module
* ti_obj_file_mod
;
276 TemplateInstance
* ti
= sym
->isTemplateInstance();
278 ti_obj_file_mod
= ti
->objFileModule
;
282 sym
= sym
->toParent();
288 D_DECL_ONE_ONLY( decl_tree
) = 1;
289 D_DECL_IS_TEMPLATE( decl_tree
) = 1;
290 is_static
= hasModule(ti_obj_file_mod
) && gen
.emitTemplates
!= TEnone
;
292 is_static
= hasModule(dsym
->getModule());
296 fprintf(stderr, "%s: is_template = %d is_static = %d te = %d m = %s cur = %s\n",
297 func_decl->toPrettyChars(), is_template, is_static, emitTemplates,
298 dsym->getModule() ? dsym->getModule()->toChars() : "none",
299 getCurrentModule()->toChars());
301 if (TREE_CODE( decl_tree
) == VAR_DECL
&&
302 (real_decl
&& (real_decl
->storage_class
& STCextern
)) )
306 DECL_EXTERNAL( decl_tree
) = 0;
307 TREE_STATIC( decl_tree
) = 1; // %% don't set until there is a body?
308 if (real_decl
&& (real_decl
->storage_class
& STCcomdat
))
309 D_DECL_ONE_ONLY( decl_tree
) = 1;
311 DECL_EXTERNAL( decl_tree
) = 1;
312 TREE_STATIC( decl_tree
) = 0;
315 if ( ( real_decl
) ) {
316 switch (real_decl
->prot()) {
321 // %% set for specials like init,vtbl ? -- otherwise,special case
322 // for reverse the default
323 TREE_PUBLIC( decl_tree
) = 1;
326 if ( (func_decl
&& (func_decl
->isMain() || func_decl
->isWinMain() ||
327 func_decl
->isDllMain())) ||
328 (real_decl
->isMember() && ! real_decl
->isThis())) { // %% check this -- static members/
329 // DMD seems to ignore private in this case...
330 TREE_PUBLIC( decl_tree
) = 1;
333 /* private statics should still get a global symbol, in case
334 * another module inlines a function that references it.
337 // TREE_PUBLIC( decl_tree ) = 0;
338 TREE_PUBLIC( decl_tree
) = 1;
343 if (D_DECL_ONE_ONLY( decl_tree
))
344 makeDeclOneOnly(decl_tree
, dsym
);
346 if ( func_decl
&& func_decl
->isNested() )
347 TREE_PUBLIC( decl_tree
) = 0;
349 TREE_STATIC( decl_tree
) = 0;
350 DECL_EXTERNAL( decl_tree
) = 0;
351 TREE_PUBLIC( decl_tree
) = 0;
354 if (real_decl
&& real_decl
->attributes
)
355 decl_attributes(& decl_tree
, gen
.attributes(real_decl
->attributes
), 0);
359 ObjectFile::setupStaticStorage(Dsymbol
* dsym
, tree decl_tree
)
361 TREE_PUBLIC( decl_tree
) = 1; // Do this by default, but allow private templates to override
362 setupSymbolStorage(dsym
, decl_tree
, true);
366 ObjectFile::outputStaticSymbol(tree t
) {
367 d_add_global_function(t
);
371 /* D allows zero-length declarations. Such a declaration ends up with
372 DECL_SIZE(t) == NULL_TREE which is what the backend function
373 assembler_variable checks. This could change in later versions...
375 Maybe all of these variables should be aliased to one symbol... */
377 // %%TODO: could move this to lang_hooks.decls.prepare_assemble_variable to
378 // make this check less precarious. -- or finish_incomplete_decl (from
379 // wrapup_global_declarations
380 if ( DECL_SIZE(t
) == 0 ) {
381 DECL_SIZE(t
) = bitsize_int(0);
382 DECL_SIZE_UNIT(t
) = size_int(0);
383 } // Otherwise, if DECL_SIZE == 0, just let it fail...
389 ObjectFile::outputFunction(FuncDeclaration
* f
)
391 Symbol
* s
= f
->toSymbol();
394 if (TREE_CODE(t
) == FUNCTION_DECL
)
396 if (DECL_STATIC_CONSTRUCTOR( t
))
398 // %% check for nested function -- error
399 // otherwise, shouldn't be in a function, so safe to do asm_out
401 if (targetm
.have_ctors_dtors
) {
403 (* targetm
.asm_out
.constructor
) (XEXP (DECL_RTL (t
), 0),
404 DEFAULT_INIT_PRIORITY
);
406 // #else, handled in d_expand_function
408 // %% assert FuncDeclaration
409 staticCtorList
.push(f
);
410 // %%TODO: fallback if ! targetm.have_ctors_dtors
413 if (DECL_STATIC_DESTRUCTOR( t
)) {
414 if (targetm
.have_ctors_dtors
) {
416 (* targetm
.asm_out
.destructor
) (XEXP (DECL_RTL (t
), 0),
417 DEFAULT_INIT_PRIORITY
);
419 // #else, handled in d_expand_function
421 // %% assert FuncDeclaration
422 staticDtorList
.push(f
);
423 // %%TODO: fallback if ! targetm.have_ctors_dtors
429 rest_of_compilation(t
);
431 if (! gen
.functionNeedsChain(f
))
432 cgraph_finalize_function(t
,
433 decl_function_context(t
) != NULL
);
438 ObjectFile::shouldEmit(Dsymbol
* d_sym
)
440 if (gen
.emitTemplates
!= TEnone
)
443 Dsymbol
* sym
= d_sym
->toParent();
445 if (sym
->isTemplateInstance()) {
449 sym
= sym
->toParent();
455 ObjectFile::shouldEmit(Symbol
* sym
)
457 return (gen
.emitTemplates
!= TEnone
) || ! D_DECL_IS_TEMPLATE(sym
->Stree
);
461 ObjectFile::addAggMethods(tree rec_type
, AggregateDeclaration
* agg
)
463 if (write_symbols
!= NO_DEBUG
) {
465 for (unsigned i
= 0; i
< agg
->methods
.dim
; i
++) {
466 FuncDeclaration
* fd
= (FuncDeclaration
*) agg
->methods
.data
[i
];
468 methods
.chain(fd
->toSymbol()->Stree
);
470 TYPE_METHODS( rec_type
) = methods
.head
;
475 ObjectFile::initTypeDecl(tree t
, Dsymbol
* d_sym
)
477 assert( ! POINTER_TYPE_P( t
) );
478 if (! TYPE_STUB_DECL(t
))
480 const char * name
= d_sym
->ident
? d_sym
->ident
->string
: "fix";
481 tree decl
= build_decl(TYPE_DECL
, get_identifier(name
), t
);
482 DECL_CONTEXT( decl
) = gen
.declContext(d_sym
);
483 setDeclLoc(decl
, d_sym
);
484 initTypeDecl(t
, decl
);
490 ObjectFile::declareType(tree t
, Type
* d_type
)
492 // Note: It is not safe to call d_type->toCtype().
494 tree decl
= build_decl(TYPE_DECL
, get_identifier(d_type
->toChars()), t
);
495 l
.filename
= "<internal>";
499 declareType(t
, decl
);
503 ObjectFile::declareType(tree t
, Dsymbol
* d_sym
)
505 initTypeDecl(t
, d_sym
);
506 declareType(t
, TYPE_NAME(t
));
511 ObjectFile::initTypeDecl(tree t
, tree decl
)
513 if ( ! TYPE_STUB_DECL(t
))
515 assert( ! POINTER_TYPE_P( t
) );
517 TYPE_CONTEXT( t
) = DECL_CONTEXT( decl
);
518 TYPE_NAME( t
) = decl
;
519 switch (TREE_CODE(t
))
524 /* Not sure if there is a need for separate TYPE_DECLs in
525 TYPE_NAME and TYPE_STUB_DECL. */
526 TYPE_STUB_DECL( t
) = build_decl(TYPE_DECL
, DECL_NAME(decl
), t
);
527 // g++ does this and the debugging code assumes it:
528 DECL_ARTIFICIAL( TYPE_STUB_DECL( t
) ) = 1;
538 ObjectFile::declareType(tree t
, tree decl
)
540 bool top_level
= /*DECL_CONTEXT(decl) == fileContext || */
541 ! DECL_CONTEXT(decl
);
544 rodc(decl
, top_level
);
548 ObjectFile::stripVarDecl(tree value
) {
549 if ( TREE_CODE( value
) != VAR_DECL
) {
551 } else if ( DECL_INITIAL(value
) ) {
552 return DECL_INITIAL(value
);
554 Type
* d_type
= gen
.getDType( TREE_TYPE( value
));
556 d_type
= d_type
->toBasetype();
557 switch (d_type
->ty
) {
560 //tree t = gen.aggregateInitializer(((TypeStruct *) d_type)->sym, NULL, NULL, NULL_TREE);
561 // %% maker sure this is doing the right thing...
562 // %% better do get rid of it..
564 // need to VIEW_CONVERT?
567 tree t
= dt2tree( dt
);
568 TREE_CONSTANT(t
) = 1;
582 ObjectFile::doThunk(tree thunk_decl
, tree target_decl
, target_ptrdiff_t offset
)
584 if (current_function_decl
) {
585 DeferredThunk
* t
= new DeferredThunk
;
586 t
->decl
= thunk_decl
;
587 t
->target
= target_decl
;
589 deferredThunks
.push(t
);
591 outputThunk(thunk_decl
, target_decl
, offset
);
595 /* Thunk code is based on g++ */
597 #ifdef ASM_OUTPUT_DEF
598 static int thunk_labelno
;
600 /* Create a static alias to function. */
603 make_alias_for_thunk (tree function
)
608 #if defined (TARGET_IS_PE_COFF)
609 /* make_alias_for_thunk does not seem to be needed for TARGET_IS_PE_COFF
610 at all, and apparently causes problems... */
611 //if (DECL_ONE_ONLY (function))
614 // For gdc: Thunks may reference extern functions which cannot be aliased.
615 if (DECL_EXTERNAL(function
))
618 ASM_GENERATE_INTERNAL_LABEL (buf
, "LTHUNK", thunk_labelno
);
620 alias
= build_decl (FUNCTION_DECL
, get_identifier (buf
),
621 TREE_TYPE (function
));
622 DECL_CONTEXT (alias
) = NULL
;
623 TREE_READONLY (alias
) = TREE_READONLY (function
);
624 TREE_THIS_VOLATILE (alias
) = TREE_THIS_VOLATILE (function
);
625 TREE_PUBLIC (alias
) = 0;
626 DECL_EXTERNAL (alias
) = 0;
627 DECL_ARTIFICIAL (alias
) = 1;
628 DECL_NO_STATIC_CHAIN (alias
) = 1;
629 DECL_INLINE (alias
) = 0;
630 DECL_DECLARED_INLINE_P (alias
) = 0;
631 //DECL_INITIAL (alias) = error_mark_node;
632 TREE_ADDRESSABLE (alias
) = 1;
633 TREE_USED (alias
) = 1;
634 SET_DECL_ASSEMBLER_NAME (alias
, DECL_NAME (alias
));
635 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (alias
)) = 1;
636 if (!flag_syntax_only
)
637 assemble_alias (alias
, DECL_ASSEMBLER_NAME (function
));
643 ObjectFile::outputThunk(tree thunk_decl
, tree target_decl
, target_ptrdiff_t offset
)
645 target_ptrdiff_t delta
= -offset
;
648 #ifdef ASM_OUTPUT_DEF
649 alias
= make_alias_for_thunk(target_decl
);
654 TREE_ADDRESSABLE(target_decl
) = 1;
655 TREE_USED(target_decl
) = 1;
656 DECL_VISIBILITY (thunk_decl
) = DECL_VISIBILITY (target_decl
);
658 && !defined (TARGET_IS_PE_COFF)
659 if (targetm
.have_named_sections
)
661 resolve_unique_section (target_decl
, 0, flag_function_sections
);
663 if (DECL_SECTION_NAME (target_decl
) != NULL
&& DECL_ONE_ONLY (target_decl
))
665 resolve_unique_section (thunk_decl
, 0, flag_function_sections
);
667 /* Output the thunk into the same section as function. */
668 DECL_SECTION_NAME (thunk_decl
) = DECL_SECTION_NAME (target_decl
);
673 /* The back-end expects DECL_INITIAL to contain a BLOCK, so we
675 // ... actually doesn't seem to be the case for output_mi_thunk
676 DECL_INITIAL (thunk_decl
) = make_node (BLOCK
);
677 BLOCK_VARS (DECL_INITIAL (thunk_decl
)) = DECL_ARGUMENTS (thunk_decl
);
679 if (targetm
.asm_out
.can_output_mi_thunk(thunk_decl
, delta
, 0, alias
)) {
682 current_function_decl
= thunk_decl
;
683 DECL_RESULT( thunk_decl
) = build_decl(RESULT_DECL
, 0, integer_type_node
);
685 fnname
= XSTR(XEXP(DECL_RTL(thunk_decl
), 0), 0);
686 gen
.initFunctionStart(thunk_decl
, 0);
687 current_function_is_thunk
= 1;
688 assemble_start_function (thunk_decl
, fnname
);
689 targetm
.asm_out
.output_mi_thunk (asm_out_file
, thunk_decl
,
691 assemble_end_function(thunk_decl
, fnname
);
692 current_function_decl
= 0;
695 /* Because init_function_start increments this, we must
697 immediate_size_expand
--;
699 TREE_ASM_WRITTEN (thunk_decl
) = 1;
701 sorry("backend for this target machine does not support thunks");
706 ObjectFile::doSimpleFunction(const char * name
, tree expr
, bool static_ctor
, bool public_fn
)
708 Module
* mod
= g
.mod
;
710 mod
= d_gcc_get_output_module();
712 if (name
[0] == '*') {
713 Symbol
* s
= mod
->toSymbolX(name
+ 1, 0, 0, "FZv");
717 TypeFunction
* func_type
= new TypeFunction(0, Type::tvoid
, 0, LINKc
);
718 FuncDeclaration
* func
= new FuncDeclaration(mod
->loc
, mod
->loc
, // %% locs may be wrong
719 Lexer::idPool(name
), STCstatic
, func_type
); // name is only to prevent crashes
720 func
->loc
= Loc(mod
, 1); // to prevent debug info crash // maybe not needed if DECL_ARTIFICIAL?
721 func
->linkage
= func_type
->linkage
;
723 func
->protection
= public_fn
? PROTpublic
: PROTprivate
;
725 tree func_decl
= func
->toSymbol()->Stree
;
727 DECL_STATIC_CONSTRUCTOR( func_decl
) = 1; // apparently, the back end doesn't do anything with this
729 // D static ctors, dtors, unittests, and the ModuleInfo chain function
730 // are always private (see ObjectFile::setupSymbolStorage, default case)
731 TREE_PUBLIC( func_decl
) = public_fn
;
733 // %% maybe remove the identifier
735 func
->fbody
= new ExpStatement(mod
->loc
,
736 new WrappedExp(mod
->loc
, TOKcomma
, expr
, Type::tvoid
));
738 func
->toObjFile(false);
743 /* force: If true, create a new function even there is only one function in the
747 ObjectFile::doFunctionToCallFunctions(const char * name
, Array
* functions
, bool force_and_public
)
749 Module
* mod
= g
.mod
;
751 // If there is only one function, just return that
752 if (functions
->dim
== 1 && ! force_and_public
) {
753 return (FuncDeclaration
*) functions
->data
[0];
754 } else if (functions
->dim
>= 1) {
755 // %% shouldn't front end build these?
756 tree exp
= NULL_TREE
;
757 tree call_exp
= NULL_TREE
;
758 for (unsigned i
= 0; i
< functions
->dim
; i
++) {
759 FuncDeclaration
* fn_decl
= (FuncDeclaration
*) functions
->data
[i
];
760 call_exp
= gen
.buildCall(void_type_node
, gen
.addressOf(fn_decl
), NULL_TREE
);
764 exp
= build(COMPOUND_EXPR
, void_type_node
, exp
, call_exp
);
768 return doSimpleFunction(name
, exp
, false, force_and_public
);
775 dtnwords(dt_t
** pdt
, size_t word_count
, void * pwords
, unsigned word_size
)
777 return dtnbytes(pdt
, word_count
* word_size
,
778 gen
.hostToTargetString((char*) pwords
, word_count
, word_size
));
782 dtawords(dt_t
** pdt
, size_t word_count
, void * pwords
, unsigned word_size
)
784 return dtabytes(pdt
, TYnptr
, 0, word_count
* word_size
,
785 gen
.hostToTargetString((char*) pwords
, word_count
, word_size
));
788 /* Add a 32-bit value to a dt. If pad_to_word is true, adds any
789 necessary padding so that the next value is aligned to PTRSIZE. */
791 dti32(dt_t
** pdt
, unsigned val
, int pad_to_word
)
793 dt_t
** result
= dttree(pdt
, gen
.integerConstant(val
, Type::tuns32
));
794 if (! pad_to_word
|| PTRSIZE
== 4)
796 else if (PTRSIZE
== 8)
797 return dttree(result
, gen
.integerConstant(0, Type::tuns32
));
803 dtcontainer(dt_t
** pdt
, Type
* type
, dt_t
* values
)
806 d
->dt
= DT_container
;
809 d
->DTvalues
= values
;
810 return dtcat(pdt
, d
);
818 target_size_t size
= 0;
832 // This may cause problems for 64-bit since dtdword is used for
833 // (uint? / size_t?) and pointers... Nearly all cases are for size_t
834 // and pointer, though.
839 tree t_size
= TYPE_SIZE_UNIT( TREE_TYPE( dt
->DTtree
));
840 size
+= gen
.getTargetSizeConst(t_size
);
844 size
+= dt_size(dt
->DTvalues
);
856 check_static_sym(Symbol
* sym
)
859 //assert( sym->Sdt );// Unfortunately cannot check for this; it might be an empty dt_t list...
861 tree t_ini
= dt2tree( sym
->Sdt
); // %% recursion problems?
862 tree t_var
= build_decl( VAR_DECL
, NULL_TREE
, TREE_TYPE( t_ini
));
863 g
.ofile
->giveDeclUniqueName(t_var
);
864 DECL_INITIAL( t_var
) = t_ini
;
865 TREE_STATIC( t_var
) = 1;
866 if (sym
->Sseg
== CDATA
) {
867 TREE_CONSTANT( t_var
) = TREE_CONSTANT( t_ini
) = 1;
868 TREE_READONLY( t_var
) = TREE_READONLY( t_ini
) = 1;
870 // %% need to check SCcomdat?
872 TREE_PRIVATE( t_var
) = 1;
873 DECL_IGNORED_P( t_var
) = 1;
874 DECL_ARTIFICIAL( t_var
) = 1;
881 dt2tree_list_of_elems(dt_t
* dt
);
890 tree a
= make_node(CONSTRUCTOR
);
891 TREE_TYPE(a
) = gen
.arrayType(Type::tuns8
, dt
->DTint
);
892 TREE_READONLY(a
) = 1;
893 TREE_CONSTANT(a
) = 1;
898 tree s
= build_string(dt
->DTint
, (char *) dt
->DTpointer
);
899 TREE_TYPE( s
) = gen
.arrayType(Type::tuns8
, dt
->DTint
);
904 tree s
= build_string(dt
->DTint
, (char *) dt
->DTpointer
);
905 TREE_TYPE( s
) = gen
.arrayType(Type::tuns8
, dt
->DTint
);
906 TREE_STATIC( s
) = 1;
907 return gen
.addressOf( s
);
910 // %% make sure this is the target word type
911 return gen
.integerConstant(dt
->DTint
, Type::tsize_t
);
913 return build(PLUS_EXPR
, ptr_type_node
,
914 gen
.addressOf(check_static_sym(dt
->DTsym
)),
915 gen
.integerConstant(dt
->DTint
, Type::tsize_t
) );
920 /* It is necessary to give static array data its original
921 type. Otherwise, the SRA pass will not find the array
924 SRA accesses struct elements by field offset, so the ad
925 hoc type from dt2tree is fine. It must still be a
926 CONSTRUCTOR, or the CCP pass may use it incorrectly.
930 tb
= dt
->DTtype
->toBasetype();
931 if (tb
&& tb
->ty
== Tsarray
)
933 TypeSArray
* tsa
= (TypeSArray
*) tb
;
934 CtorEltMaker ctor_elts
;
935 dt_t
* dte
= dt
->DTvalues
;
937 ctor_elts
.reserve(tsa
->dim
->toInteger());
940 ctor_elts
.cons(gen
.integerConstant(i
++, size_type_node
),
944 tree ctor
= make_node(CONSTRUCTOR
);
945 TREE_TYPE(ctor
) = dt
->DTtype
->toCtype();
947 // DT data should always be constant. If the decl is not TREE_CONSTANT, fine.
948 TREE_CONSTANT(ctor
) = 1;
950 TREE_READONLY(ctor
) = 1;
951 TREE_STATIC(ctor
) = 1;
952 CONSTRUCTOR_ELTS(ctor
) = ctor_elts
.head
;
955 else if (tb
&& tb
->ty
== Tstruct
)
956 return dt2tree_list_of_elems(dt
->DTvalues
);
958 return dt2tree(dt
->DTvalues
);
969 if (dt
&& /*dt->dt == DT_container || */dt
->DTnext
== NULL
)
972 return dt2tree_list_of_elems(dt
);
976 dt2tree_list_of_elems(dt_t
* dt
)
978 // Generate type on the fly
981 tree offset
= size_zero_node
;
983 tree aggtype
= make_node(RECORD_TYPE
);
986 tree value
= dt2node(dt
);
987 tree field
= build_decl(FIELD_DECL
, NULL_TREE
, TREE_TYPE(value
));
988 DECL_CONTEXT(field
) = aggtype
;
989 DECL_FIELD_OFFSET(field
) = offset
;
990 DECL_FIELD_BIT_OFFSET(field
) = bitsize_zero_node
;
991 DECL_ARTIFICIAL(field
) = 1;
992 DECL_IGNORED_P(field
) = 1;
993 layout_decl(field
, 0);
996 elts
.cons(field
, value
);
997 offset
= size_binop(PLUS_EXPR
, offset
, TYPE_SIZE_UNIT( TREE_TYPE( value
)));
1002 TYPE_FIELDS(aggtype
) = fields
.head
; // or finish_laout
1003 TYPE_SIZE(aggtype
) = convert( bitsizetype
,
1004 size_binop( MULT_EXPR
, offset
, size_int( BITS_PER_UNIT
)));
1005 TYPE_SIZE_UNIT(aggtype
) = offset
;
1006 // okay no alignment -- decl (which has the correct type) should take care of it..
1007 // align=bits per word?
1008 compute_record_mode(aggtype
);
1010 tree ctor
= make_node(CONSTRUCTOR
);
1011 TREE_TYPE(ctor
) = aggtype
;
1012 TREE_READONLY(ctor
) = 1;
1013 // dt created data is always static
1014 TREE_STATIC(ctor
) = 1;
1015 // should always be constant
1016 TREE_CONSTANT(ctor
) = 1;
1018 // DT data should always be constant. If the decl is not TREE_CONSTANT, fine.
1019 CONSTRUCTOR_ELTS(ctor
) = elts
.head
;
1024 outdata(Symbol
* sym
)
1026 tree t
= check_static_sym( sym
);
1030 if (sym
->Sdt
&& DECL_INITIAL( t
) == NULL_TREE
)
1031 DECL_INITIAL( t
) = dt2tree( sym
->Sdt
);
1033 if (! g
.ofile
->shouldEmit(sym
))
1036 if ( DECL_EXTERNAL( t
) ) {
1037 // %% Oops, this was supposed to be static.
1038 // This is for typeinfo decls ... may
1039 // insert into module instead?
1040 DECL_EXTERNAL( t
) = 0;
1041 TREE_STATIC( t
) = 1;
1046 // from outputStaticSymbol:
1047 if ( DECL_SIZE(t
) == NULL_TREE
) {
1048 DECL_SIZE(t
) = bitsize_int(0);
1049 DECL_SIZE_UNIT(t
) = size_int(0);
1050 } // Otherwise, if DECL_SIZE == 0, just let it fail...
1052 d_add_global_function(t
);
1054 g
.ofile
->rodc(t
, 1);
1058 obj_includelib(char *name
)
1060 d_warning(OPT_Wunknown_pragmas
, "pragma(lib) not implemented");
1064 obj_startaddress(Symbol
*s
)
1066 d_warning(OPT_Wunknown_pragmas
, "pragma(startaddress) not implemented");
1070 obj_append(Dsymbol
*s
)
1072 // GDC does not do multi-obj, so just write it out now.
1073 s
->toObjFile(false);
1077 obj_moduleinfo(Symbol
*sym
)
1085 extern (C) _modref_t * _Dmodule_ref;
1086 private _modref_t our_mod_ref =
1087 { next: null, m: _ModuleInfo_xxx };
1088 void ___modinit() { // a static constructor
1089 our_mod_ref.next = _Dmodule_ref;
1090 _Dmodule_ref = & our_mod_ref;
1093 // struct ModuleReference in moduleinit.d
1094 tree mod_ref_type
= gen
.twoFieldType(Type::tvoid
->pointerTo(), gen
.getObjectType(),
1095 NULL
, "next", "mod");
1096 tree f0
= TYPE_FIELDS( mod_ref_type
);
1097 tree f1
= TREE_CHAIN( f0
);
1099 tree our_mod_ref
= build_decl(VAR_DECL
, NULL_TREE
, mod_ref_type
);
1101 g
.ofile
->giveDeclUniqueName(our_mod_ref
, "__mod_ref");
1103 tree init
= make_node(CONSTRUCTOR
);
1105 TREE_TYPE( init
) = mod_ref_type
;
1106 ce
.cons(f0
, d_null_pointer
);
1107 ce
.cons(f1
, gen
.addressOf(sym
->Stree
));
1108 CONSTRUCTOR_ELTS( init
) = ce
.head
;
1109 TREE_STATIC( init
) = 1;
1110 DECL_ARTIFICIAL( our_mod_ref
) = 1;
1111 DECL_IGNORED_P( our_mod_ref
) = 1;
1112 TREE_PRIVATE( our_mod_ref
) = 1;
1113 TREE_STATIC( our_mod_ref
) = 1;
1114 DECL_INITIAL( our_mod_ref
) = init
;
1115 g
.ofile
->rodc(our_mod_ref
, 1);
1117 tree the_mod_ref
= build_decl(VAR_DECL
, get_identifier("_Dmodule_ref"),
1118 build_pointer_type( mod_ref_type
));
1120 DECL_EXTERNAL( the_mod_ref
) = 1;
1121 TREE_PUBLIC( the_mod_ref
) = 1;
1123 tree m1
= build(MODIFY_EXPR
, void_type_node
,
1124 gen
.component(our_mod_ref
, f0
),
1126 tree m2
= build(MODIFY_EXPR
, void_type_node
,
1127 the_mod_ref
, gen
.addressOf(our_mod_ref
));
1128 tree exp
= build(COMPOUND_EXPR
, void_type_node
, m1
, m2
);
1130 g
.ofile
->doSimpleFunction("*__modinit", exp
, true);