Disallow x[y] if x has a maybe type
[delight/core.git] / d-decls.cc
blob978f835ab1d9a32d007b59b7fc7034628b868b32
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
19 This file is based on dmd/tocsym.c. Original copyright:
21 // Copyright (c) 1999-2002 by Digital Mars
22 // All Rights Reserved
23 // written by Walter Bright
24 // www.digitalmars.com
25 // License for redistribution is by either the Artistic License
26 // in artistic.txt, or the GNU General Public License in gnu.txt.
27 // See the included readme.txt for details.
31 #include "d-gcc-includes.h"
32 #include <assert.h>
34 #include "total.h"
35 #include "mars.h"
36 #include "statement.h"
37 #include "aggregate.h"
38 #include "init.h"
39 #include "attrib.h"
41 #include "symbol.h"
42 #include "d-lang.h"
43 #include "d-codegen.h"
45 void slist_add(Symbol */*s*/)
48 void slist_reset()
52 /********************************* SymbolDeclaration ****************************/
54 SymbolDeclaration::SymbolDeclaration(Loc loc, Symbol *s, StructDeclaration *dsym)
55 : Declaration(new Identifier(s->Sident, TOKidentifier))
57 this->loc = loc;
58 sym = s;
59 this->dsym = dsym;
60 storage_class |= STCconst;
63 Symbol *SymbolDeclaration::toSymbol()
65 // Create the actual back-end value if not yet done
66 if (! sym->Stree) {
67 if (dsym)
68 dsym->toInitializer();
69 assert(sym->Stree);
71 return sym;
74 /*************************************
75 * Helper
78 Symbol *Dsymbol::toSymbolX(const char *prefix, int sclass, type *t, const char *suffix)
80 Symbol *s;
81 char *id;
82 char *n;
84 n = mangle();
85 id = (char *) alloca(2 + strlen(n) + sizeof(size_t) * 3 + strlen(prefix) + strlen(suffix) + 1);
86 sprintf(id,"_D%s%"PRIuSIZE"%s%s", n, strlen(prefix), prefix, suffix);
87 s = symbol_name(id, sclass, t);
88 return s;
91 /*************************************
94 Symbol *Dsymbol::toSymbol()
96 fprintf(stderr, "Dsymbol::toSymbol() '%s', kind = '%s'\n", toChars(), kind());
97 assert(0); // BUG: implement
98 return NULL;
101 /*********************************
102 * Generate import symbol from symbol.
105 Symbol *Dsymbol::toImport()
107 if (!isym)
109 if (!csym)
110 csym = toSymbol();
111 isym = toImport(csym);
113 return isym;
116 /*************************************
119 Symbol *Dsymbol::toImport(Symbol * /*sym*/)
121 // not used in GCC (yet?)
122 return 0;
127 /* When using -combine, there may be name collisions on compiler-generated
128 or extern(C) symbols. This only should only apply to private symbols.
129 Otherwise, duplicate names are an error. */
131 static StringTable * uniqueNames = 0;
132 static void uniqueName(Declaration * d, tree t, const char * asm_name) {
133 Dsymbol * p = d->toParent2();
134 const char * out_name = asm_name;
135 char * alloc_name = 0;
137 FuncDeclaration * f = d->isFuncDeclaration();
138 VarDeclaration * v = d->isVarDeclaration();
140 /* Check cases for which it is okay to have a duplicate symbol name.
141 Otherwise, duplicate names are an error and the condition will
142 be caught by the assembler. */
143 if (!(f && ! f->fbody) &&
144 !(v && (v->storage_class & STCextern)) &&
146 // Static declarations in different scope statements
147 (p && p->isFuncDeclaration()) ||
149 // Top-level duplicate names are okay if private.
150 ((!p || p->isModule()) && d->protection == PROTprivate) ))
152 StringValue * sv;
154 // Assumes one assembler output file per compiler run. Otherwise, need
155 // to reset this for each file.
156 if (! uniqueNames)
157 uniqueNames = new StringTable;
158 sv = uniqueNames->update(asm_name, strlen(asm_name));
159 if (sv->intvalue) {
160 out_name = alloc_name = d_asm_format_private_name(asm_name, sv->intvalue );
162 sv->intvalue++;
165 SET_DECL_ASSEMBLER_NAME(t, get_identifier(out_name));
167 if (alloc_name)
168 free(alloc_name);
172 /*************************************
175 Symbol *VarDeclaration::toSymbol()
177 if (! csym) {
178 tree var_decl;
180 // For field declaration, it is possible for toSymbol to be called
181 // before the parent's toCtype()
182 if (storage_class & STCfield) {
183 AggregateDeclaration * parent_decl = toParent()->isAggregateDeclaration();
184 assert(parent_decl);
185 parent_decl->type->toCtype();
186 assert(csym);
187 return csym;
190 const char * ident_to_use;
191 if (isDataseg())
192 ident_to_use = mangle();
193 else
194 ident_to_use = ident->string;
196 enum tree_code decl_kind;
198 #if ! V2
199 bool is_template_const = false;
200 // Logic copied from toobj.c VarDeclaration::toObjFile
202 Dsymbol * parent = this->toParent();
203 #if 1 /* private statics should still get a global symbol, in case
204 * another module inlines a function that references it.
206 if (/*protection == PROTprivate ||*/
207 !parent || parent->ident == NULL || parent->isFuncDeclaration())
209 // nothing
211 else
212 #endif
216 /* Global template data members need to be in comdat's
217 * in case multiple .obj files instantiate the same
218 * template with the same types.
220 if (parent->isTemplateInstance() && !parent->isTemplateMixin())
222 /* These symbol constants have already been copied,
223 * so no reason to output them.
224 * Note that currently there is no way to take
225 * the address of such a const.
227 if (isConst() && type->toBasetype()->ty != Tsarray &&
228 init && init->isExpInitializer())
230 is_template_const = true;
231 break;
234 break;
236 parent = parent->parent;
237 } while (parent);
239 #endif
241 if (storage_class & STCparameter)
242 decl_kind = PARM_DECL;
243 else if (
244 #if V2
245 # if 0
246 // from VarDeclaration::getConstInitializer
247 (isConst() || isInvariant()) && (storage_class & STCinit)
248 # else
249 (storage_class & STCmanifest)
250 # endif
251 #else
252 is_template_const ||
254 isConst()
255 && ! gen.isDeclarationReferenceType( this ) &&
256 type->isscalar() && ! isDataseg()
258 #endif
260 decl_kind = CONST_DECL;
261 else
262 decl_kind = VAR_DECL;
264 var_decl = build_decl(decl_kind, get_identifier(ident_to_use),
265 gen.trueDeclarationType( this ));
267 csym = new Symbol();
268 csym->Stree = var_decl;
270 if (decl_kind != CONST_DECL) {
271 if (isDataseg())
272 uniqueName(this, var_decl, ident_to_use);
273 if (c_ident)
274 SET_DECL_ASSEMBLER_NAME(var_decl, get_identifier(c_ident->string));
276 dkeep(var_decl);
277 g.ofile->setDeclLoc(var_decl, this);
278 if ( decl_kind == VAR_DECL ) {
279 g.ofile->setupSymbolStorage(this, var_decl);
280 //DECL_CONTEXT( var_decl ) = gen.declContext(this);//EXPERkinda
281 } else if (decl_kind == PARM_DECL) {
282 /* from gcc code: Some languages have different nominal and real types. */
283 // %% What about DECL_ORIGINAL_TYPE, DECL_ARG_TYPE_AS_WRITTEN, DECL_ARG_TYPE ?
284 DECL_ARG_TYPE( var_decl ) = TREE_TYPE (var_decl);
286 DECL_CONTEXT( var_decl ) = gen.declContext(this);
287 assert( TREE_CODE(DECL_CONTEXT( var_decl )) == FUNCTION_DECL );
288 } else if (decl_kind == CONST_DECL) {
289 /* Not sure how much of an optimization this is... It is needed
290 for foreach loops on tuples which 'declare' the index variable
291 as a constant for each iteration. */
292 Expression * e = NULL;
294 if (init)
296 if (! init->isVoidInitializer())
298 e = init->toExpression();
299 assert(e != NULL);
302 else
303 e = type->defaultInit();
305 if (e)
307 DECL_INITIAL( var_decl ) = g.irs->assignValue(e, this);
308 if (! DECL_INITIAL(var_decl))
309 DECL_INITIAL( var_decl ) = e->toElem(g.irs);
313 // Can't set TREE_STATIC, etc. until we get to toObjFile as this could be
314 // called from a varaible in an imported module
315 // %% (out const X x) doesn't mean the reference is const...
316 if (
317 #if V2
318 (isConst() || isInvariant()) && (storage_class & STCinit)
319 #else
320 isConst()
321 #endif
322 && ! gen.isDeclarationReferenceType( this )) {
323 // %% CONST_DECLS don't have storage, so we can't use those,
324 // but it would be nice to get the benefit of them (could handle in
325 // VarExp -- makeAddressOf could switch back to the VAR_DECL
327 // if ( typs->isscalar() ) CONST_DECL...
329 TREE_READONLY( var_decl ) = 1;
330 // can at least do this...
331 // const doesn't seem to matter for aggregates, so prevent problems..
332 if ( type->isscalar() ) {
333 TREE_CONSTANT( var_decl ) = 1;
337 #if D_GCC_VER < 40
338 // With cgraph, backend can figure it out (improves inline nested funcs?)
339 if (
340 #if V2
341 nestedrefs.dim
342 #else
343 nestedref
344 #endif
345 && decl_kind != CONST_DECL) {
346 DECL_NONLOCAL( var_decl ) = 1;
347 TREE_ADDRESSABLE( var_decl ) = 1;
350 TREE_USED( var_decl ) = 1;
351 #endif
354 #ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
355 // Have to test for import first
356 if (isImportedSymbol())
357 gen.addDeclAttribute( var_decl, "dllimport" );
358 else if (isExport())
359 gen.addDeclAttribute( var_decl, "dllexport" );
360 #endif
362 return csym;
365 /*************************************
368 Symbol *ClassInfoDeclaration::toSymbol()
370 return cd->toSymbol();
373 /*************************************
376 Symbol *ModuleInfoDeclaration::toSymbol()
378 return mod->toSymbol();
381 /*************************************
384 Symbol *TypeInfoDeclaration::toSymbol()
386 if ( ! csym ) {
387 VarDeclaration::toSymbol();
389 // This variable is the static initialization for the
390 // given TypeInfo. It is the actual data, not a reference
391 assert( TREE_CODE( TREE_TYPE( csym->Stree )) == REFERENCE_TYPE );
392 TREE_TYPE( csym->Stree ) = TREE_TYPE( TREE_TYPE( csym->Stree ));
394 /* DMD makes typeinfo decls one-only by doing:
396 s->Sclass = SCcomdat;
398 in TypeInfoDeclaration::toObjFile. The difference is
399 that, in gdc, built-in typeinfo will be referenced as
400 one-only.
404 D_DECL_ONE_ONLY( csym->Stree ) = 1;
405 g.ofile->makeDeclOneOnly( csym->Stree );
407 return csym;
410 /*************************************
413 Symbol *FuncAliasDeclaration::toSymbol()
415 return funcalias->toSymbol();
418 /*************************************
421 // returns a FUNCTION_DECL tree
422 Symbol *FuncDeclaration::toSymbol()
424 if (! csym) {
425 csym = new Symbol();
427 if (! isym) {
428 tree id;
429 //struct prod_token_parm_item* parm;
430 //tree type_node;
431 Type * func_type = tintro ? tintro : type;
432 tree fn_decl;
433 char * mangled_ident_str = 0;
434 AggregateDeclaration * agg_decl;
436 if (ident) {
437 id = get_identifier(ident->string);
438 } else {
439 // This happens for assoc array foreach bodies
441 // Not sure if idents are strictly necc., but announce_function
442 // dies without them.
444 // %% better: use parent name
446 static unsigned unamed_seq = 0;
447 char buf[64];
448 sprintf(buf, "___unamed_%u", ++unamed_seq);//%% sprintf
449 id = get_identifier(buf);
452 tree fn_type = func_type->toCtype();
453 dkeep(fn_type); /* TODO: fix this. we need to keep the type because
454 the creation of a method type below leaves this fn_type
455 unreferenced. maybe lang_specific.based_on */
457 tree vindex = NULL_TREE;
458 if (isNested()) {
459 /* Even if DMD-style nested functions are not implemented, add an
460 extra argument to be compatible with delegates. */
462 // irs->functionType(func_type, Type::tvoid);
463 fn_type = build_method_type(void_type_node, fn_type);
464 } else if ( ( agg_decl = isMember() ) ) {
465 // Do this even if there is no debug info. It is needed to make
466 // sure member functions are not called statically
467 if (isThis()) {
468 tree method_type = build_method_type(TREE_TYPE(agg_decl->handle->toCtype()), fn_type);
469 TYPE_ATTRIBUTES( method_type ) = TYPE_ATTRIBUTES( fn_type );
470 fn_type = method_type;
472 if (isVirtual())
473 vindex = size_int(vtblIndex);
475 } else if (isMain() && func_type->nextOf()->toBasetype()->ty == Tvoid) {
476 fn_type = build_function_type(integer_type_node, TYPE_ARG_TYPES(fn_type));
479 // %%CHECK: is it okay for static nested functions to have a FUNC_DECL context?
480 // seems okay so far...
482 fn_decl = build_decl( FUNCTION_DECL, id, fn_type );
483 dkeep(fn_decl);
484 if (ident) {
485 mangled_ident_str = mangle();
486 uniqueName(this, fn_decl, mangled_ident_str);
488 if (c_ident)
489 SET_DECL_ASSEMBLER_NAME(fn_decl, get_identifier(c_ident->string));
490 // %% What about DECL_SECTION_NAME ?
491 //DECL_ARGUMENTS(fn_decl) = NULL_TREE; // Probably don't need to do this until toObjFile
492 DECL_CONTEXT (fn_decl) = gen.declContext(this); //context;
493 if (vindex) {
494 DECL_VINDEX (fn_decl) = vindex;
495 DECL_VIRTUAL_P (fn_decl) = 1;
497 if (! gen.functionNeedsChain(this)
498 #if D_GCC_VER >= 40
499 // gcc 4.0: seems to be an error to set DECL_NO_STATIC_CHAIN on a toplevel function
500 // (tree-nest.c:1282:convert_all_function_calls)
501 && decl_function_context(fn_decl)
502 #endif
504 // Prevent backend from thinking this is a nested function.
505 DECL_NO_STATIC_CHAIN( fn_decl ) = 1;
507 else
509 /* If a template instance has a nested function (because
510 a template argument is a local variable), the nested
511 function may not have its toObjFile called before the
512 outer function is finished. GCC requires that nested
513 functions be finished first so we need to arrange for
514 toObjFile to be called earlier.
516 It may be possible to defer calling the outer
517 function's cgraph_finalize_function until all nested
518 functions are finished, but this will only work for
519 GCC >= 3.4. */
520 Dsymbol * p = this->parent;
521 FuncDeclaration * outer_func = NULL;
522 bool is_template_member = false;
523 while (p)
525 if (p->isTemplateInstance() && ! p->isTemplateMixin())
527 is_template_member = true;
529 else if ( (outer_func = p->isFuncDeclaration()) )
530 break;
531 p = p->parent;
533 if (is_template_member && outer_func)
535 Symbol * outer_sym = outer_func->toSymbol();
536 assert(outer_sym->outputStage != Finished);
537 if (! outer_sym->otherNestedFuncs)
538 outer_sym->otherNestedFuncs = new FuncDeclarations;
539 outer_sym->otherNestedFuncs->push(this);
543 /* For now, inline asm means we can't inline (stack wouldn't be
544 what was expected and LDASM labels aren't unique.)
545 TODO: If the asm consists entirely
546 of extended asm, we can allow inlining. */
547 if (inlineAsm) {
548 DECL_UNINLINABLE(fn_decl) = 1;
549 } else {
550 #if D_GCC_VER >= 40
551 // see grokdeclarator in c-decl.c
552 if (flag_inline_trees == 2 && fbody /* && should_emit? */)
553 DECL_INLINE (fn_decl) = 1;
554 #endif
557 if (naked) {
558 D_DECL_NO_FRAME_POINTER( fn_decl ) = 1;
559 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT( fn_decl ) = 1;
561 /* Need to do this or GCC will set up a frame pointer with -finline-functions.
562 Must have something to do with defered processing -- after we turn
563 flag_omit_frame_pointer back on. */
564 DECL_UNINLINABLE( fn_decl ) = 1;
567 #ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
568 // Have to test for import first
569 if (isImportedSymbol())
570 gen.addDeclAttribute( fn_decl, "dllimport" );
571 else if (isExport())
572 gen.addDeclAttribute( fn_decl, "dllexport" );
573 #endif
575 g.ofile->setDeclLoc(fn_decl, this);
576 g.ofile->setupSymbolStorage(this, fn_decl);
577 if (! ident)
578 TREE_PUBLIC( fn_decl ) = 0;
580 TREE_USED (fn_decl) = 1; // %% Probably should be a little more intelligent about this
582 // if -mrtd is passed, how to handle this? handle in parsing or do
583 // we go back and find out if linkage was specified
584 switch (linkage)
586 case LINKwindows:
587 gen.addDeclAttribute(fn_decl, "stdcall");
588 // The stdcall attribute also needs to be set on the function type.
589 assert( ((TypeFunction *) func_type)->linkage == LINKwindows );
590 break;
591 case LINKpascal:
592 // stdcall and reverse params?
593 break;
594 case LINKc:
595 case LINKgobject:
596 // %% hack: on darwin (at least) using a DECL_EXTERNAL (IRState::getLibCallDecl)
597 // and TREE_STATIC FUNCTION_DECLs causes the stub label to be output twice. This
598 // is a work around. This doesn't handle the case in which the normal
599 // getLibCallDecl has already bee created and used. Note that the problem only
600 // occurs with function inlining is used.
601 gen.replaceLibCallDecl(this);
602 break;
603 case LINKd:
604 // %% If x86, regparm(1)
605 // not sure if reg struct return
606 break;
607 case LINKcpp:
608 break;
609 default:
610 fprintf(stderr, "linkage = %d\n", linkage);
611 assert(0);
614 csym->Sident = mangled_ident_str; // save for making thunks
615 csym->Stree = fn_decl;
617 gen.maybeSetUpBuiltin(this);
618 } else {
619 csym->Stree = isym->Stree;
622 return csym;
625 #define D_PRIVATE_THUNKS 1
627 /*************************************
629 Symbol *FuncDeclaration::toThunkSymbol(target_ptrdiff_t offset)
631 Symbol *sthunk;
632 Thunk * thunk;
634 toSymbol();
636 /* If the thunk is to be static (that is, it is being emitted in this
637 module, there can only be one FUNCTION_DECL for it. Thus, there
638 is a list of all thunks for a given function. */
639 if ( ! csym->thunks )
640 csym->thunks = new Array;
641 Array & thunks = * csym->thunks;
642 bool found = false;
644 for (unsigned i = 0; i < thunks.dim; i++) {
645 thunk = (Thunk *) thunks.data[i];
646 if (thunk->offset == offset) {
647 found = true;
648 break;
652 if (! found) {
653 thunk = new Thunk;
654 thunk->offset = offset;
655 thunks.push(thunk);
658 if ( ! thunk->symbol ) {
659 char *id;
660 char *n;
661 //type *t;
663 n = csym->Sident; // dmd uses 'sym' -- not sure what that is...
664 id = (char *) alloca(8 + 5 + strlen(n) + 1);
665 sprintf(id,"__t%"PRIdTSIZE"_%s", offset, n);
666 sthunk = symbol_calloc(id);
667 slist_add(sthunk);
668 /* todo: could use anonymous names like DMD, with ASM_FORMAT_RRIVATE_NAME*/
669 //sthunk = symbol_generate(SCstatic, csym->Stype);
670 //sthunk->Sflags |= SFLimplem;
672 tree target_func_decl = csym->Stree;
673 tree thunk_decl = build_decl(FUNCTION_DECL, get_identifier(id), TREE_TYPE( target_func_decl ));
674 dkeep(thunk_decl);
675 sthunk->Stree = thunk_decl;
677 //SET_DECL_ASSEMBLER_NAME(thunk_decl, DECL_NAME(thunk_decl));//old
678 DECL_CONTEXT(thunk_decl) = DECL_CONTEXT(target_func_decl); // from c++...
679 TREE_READONLY(thunk_decl) = TREE_READONLY(target_func_decl);
680 TREE_THIS_VOLATILE(thunk_decl) = TREE_THIS_VOLATILE(target_func_decl);
682 #ifdef D_PRIVATE_THUNKS
683 TREE_PRIVATE(thunk_decl) = 1;
684 #else
685 /* Due to changes in the assembler, it is not possible to emit
686 a private thunk that refers to an external symbol.
687 http://lists.gnu.org/archive/html/bug-binutils/2005-05/msg00002.html
689 DECL_EXTERNAL(thunk_decl) = DECL_EXTERNAL(target_func_decl);
690 TREE_STATIC(thunk_decl) = TREE_STATIC(target_func_decl);
691 TREE_PRIVATE(thunk_decl) = TREE_PRIVATE(target_func_decl);
692 TREE_PUBLIC(thunk_decl) = TREE_PUBLIC(target_func_decl);
693 #endif
695 DECL_ARTIFICIAL(thunk_decl) = 1;
696 DECL_IGNORED_P(thunk_decl) = 1;
697 DECL_NO_STATIC_CHAIN(thunk_decl) = 1;
698 DECL_INLINE(thunk_decl) = 0;
699 DECL_DECLARED_INLINE_P(thunk_decl) = 0;
700 //needed on some targets to avoid "causes a section type conflict"
701 D_DECL_ONE_ONLY(thunk_decl) = D_DECL_ONE_ONLY(target_func_decl);
702 if ( D_DECL_ONE_ONLY(thunk_decl) )
703 g.ofile->makeDeclOneOnly(thunk_decl);
705 TREE_ADDRESSABLE(thunk_decl) = 1;
706 TREE_USED (thunk_decl) = 1;
708 #ifdef D_PRIVATE_THUNKS
709 //g.ofile->prepareSymbolOutput(sthunk);
710 g.ofile->doThunk(thunk_decl, target_func_decl, offset);
711 #else
712 if ( TREE_STATIC(thunk_decl) )
713 g.ofile->doThunk(thunk_decl, target_func_decl, offset);
714 #endif
716 thunk->symbol = sthunk;
718 return thunk->symbol;
722 /****************************************
723 * Create a static symbol we can hang DT initializers onto.
726 Symbol *static_sym()
728 Symbol * s = symbol_tree(NULL_TREE);
729 //OLD//s->Sfl = FLstatic_sym;
730 /* Before GCC 4.0, it was possible to take the address of a CONSTRUCTOR
731 marked TREE_STATIC and the backend would output the data as an
732 anonymous symbol. This doesn't work in 4.0. To keep things, simple,
733 the same method is used for <4.0 and >= 4.0. */
734 // Can't build the VAR_DECL because the type is unknown
735 slist_add(s);
736 return s;
739 /**************************************
740 * Fake a struct symbol.
743 // Not used in GCC
745 Classsym *fake_classsym(char * name)
747 return 0;
751 /*************************************
752 * Create the "ClassInfo" symbol
755 Symbol *ClassDeclaration::toSymbol()
757 if (! csym)
759 tree decl;
760 csym = toSymbolX("__Class", SCextern, 0, "Z");
761 slist_add(csym);
762 decl = build_decl( VAR_DECL, get_identifier( csym->Sident ),
763 TREE_TYPE( ClassDeclaration::classinfo->type->toCtype() )); // want the RECORD_TYPE, not the REFERENCE_TYPE
764 csym->Stree = decl;
765 dkeep(decl);
767 g.ofile->setupStaticStorage(this, decl);
769 TREE_CONSTANT( decl ) = 0; // DMD puts this into .data, not .rodata...
770 TREE_READONLY( decl ) = 0;
772 return csym;
775 /*************************************
776 * Create the "InterfaceInfo" symbol
779 Symbol *InterfaceDeclaration::toSymbol()
781 if (!csym)
783 csym = ClassDeclaration::toSymbol();
784 tree decl = csym->Stree;
786 Symbol * temp_sym = toSymbolX("__Interface", SCextern, 0, "Z");
787 DECL_NAME( decl ) = get_identifier( temp_sym->Sident );
788 delete temp_sym;
790 TREE_CONSTANT( decl ) = 1; // Interface ClassInfo images are in .rodata, but classes arent..?
792 return csym;
795 /*************************************
796 * Create the "ModuleInfo" symbol
799 Symbol *Module::toSymbol()
801 if (!csym)
803 Type * some_type;
805 /* This causes problems .. workaround
806 is to call moduleinfo->toCtype() before we start processing
807 decls in genobjfile. ...
809 if (moduleinfo) {
810 some_type = moduleinfo->type;
811 } else {
812 some_type = gen.getObjectType();
815 some_type = gen.getObjectType();
817 csym = toSymbolX("__ModuleInfo", SCextern, 0, "Z");
818 slist_add(csym);
820 tree decl = build_decl(VAR_DECL, get_identifier(csym->Sident),
821 TREE_TYPE(some_type->toCtype())); // want the RECORD_TYPE, not the REFERENCE_TYPE
822 csym->Stree = decl;
824 dkeep(decl);
826 g.ofile->setupStaticStorage(this, decl);
828 TREE_CONSTANT( decl ) = 0; // *not* readonly, moduleinit depends on this
829 TREE_READONLY( decl ) = 0; // Not an lvalue, tho
831 return csym;
834 /*************************************
835 * This is accessible via the ClassData, but since it is frequently
836 * needed directly (like for rtti comparisons), make it directly accessible.
839 Symbol *ClassDeclaration::toVtblSymbol()
841 if (!vtblsym)
843 tree decl;
845 vtblsym = toSymbolX("__vtbl", SCextern, 0, "Z");
846 slist_add(vtblsym);
848 /* The DECL_INITIAL value will have a different type object from the
849 VAR_DECL. The back end seems to accept this. */
850 TypeSArray * vtbl_type = new TypeSArray(Type::tvoid->pointerTo(),
851 new IntegerExp(loc, vtbl.dim, Type::tindex));
853 decl = build_decl( VAR_DECL, get_identifier( vtblsym->Sident ), vtbl_type->toCtype() );
854 vtblsym->Stree = decl;
855 dkeep(decl);
857 g.ofile->setupStaticStorage(this, decl);
859 TREE_READONLY( decl ) = 1;
860 TREE_CONSTANT( decl ) = 1;
861 TREE_ADDRESSABLE( decl ) = 1;
862 // from cp/class.c
863 DECL_CONTEXT (decl) = TREE_TYPE( type->toCtype() );
864 DECL_VIRTUAL_P (decl) = 1;
865 DECL_ALIGN (decl) = TARGET_VTABLE_ENTRY_ALIGN;
867 return vtblsym;
870 /**********************************
871 * Create the static initializer for the struct/class.
874 /* Because this is called from the front end (mtype.cc:TypeStruct::defaultInit()),
875 we need to hold off using back-end stuff until the toobjfile phase.
877 Specifically, it is not safe create a VAR_DECL with a type from toCtype()
878 because there may be unresolved recursive references.
879 StructDeclaration::toObjFile calls toInitializer without ever calling
880 SymbolDeclaration::toSymbol, so we just need to keep checking if we
881 are in the toObjFile phase.
884 Symbol *AggregateDeclaration::toInitializer()
886 Symbol *s;
888 if (!sinit)
890 s = toSymbolX("__init", SCextern, 0, "Z");
891 slist_add(s);
892 sinit = s;
894 if (! sinit->Stree && g.ofile != NULL)
896 tree struct_type = type->toCtype();
897 if ( POINTER_TYPE_P( struct_type ) )
898 struct_type = TREE_TYPE( struct_type ); // for TypeClass, want the RECORD_TYPE, not the REFERENCE_TYPE
899 tree t = build_decl(VAR_DECL, get_identifier(sinit->Sident), struct_type);
900 sinit->Stree = t;
901 dkeep(t);
903 g.ofile->setupStaticStorage(this, t);
905 // %% what's the diff between setting this stuff on the DECL and the
906 // CONSTRUCTOR itself?
908 TREE_ADDRESSABLE( t ) = 1;
909 TREE_CONSTANT( t ) = 1;
910 TREE_READONLY( t ) = 1;
911 DECL_CONTEXT( t ) = 0; // These are always global
913 return sinit;
916 Symbol *TypedefDeclaration::toInitializer()
918 Symbol *s;
920 if (!sinit)
922 s = toSymbolX("__init", SCextern, 0, "Z");
923 s->Sfl = FLextern;
924 s->Sflags |= SFLnodebug;
925 slist_add(s);
926 sinit = s;
927 sinit->Sdt = ((TypeTypedef *)type)->sym->init->toDt();
929 return sinit;
932 Symbol *EnumDeclaration::toInitializer()
934 Symbol *s;
936 if (!sinit)
938 Identifier *ident_save = ident;
939 if (!ident)
940 { static int num;
941 char name[6 + sizeof(num) * 3 + 1];
942 snprintf(name, sizeof(name), "__enum%d", ++num);
943 ident = Lexer::idPool(name);
945 s = toSymbolX("__init", SCextern, 0, "Z");
946 ident = ident_save;
947 s->Sfl = FLextern;
948 s->Sflags |= SFLnodebug;
949 slist_add(s);
950 sinit = s;
952 if (! sinit->Stree && g.ofile != NULL)
954 tree t = build_decl(VAR_DECL, get_identifier(sinit->Sident), type->toCtype());
955 sinit->Stree = t;
956 dkeep(t);
958 g.ofile->setupStaticStorage(this, t);
959 TREE_CONSTANT( t ) = 1;
960 TREE_READONLY( t ) = 1;
961 DECL_CONTEXT( t ) = 0;
963 return sinit;
967 /******************************************
970 Symbol *Module::toModuleAssert()
972 // Not used in GCC
973 return 0;
976 /******************************************
979 Symbol *Module::toModuleArray()
981 // Not used in GCC (all array bounds checks are inlined)
982 return 0;
985 /********************************************
986 * Determine the right symbol to look up
987 * an associative array element.
988 * Input:
989 * flags 0 don't add value signature
990 * 1 add value signature
993 Symbol *TypeAArray::aaGetSymbol(char *func, int flags)
995 // This is not used in GCC (yet?)
996 return 0;