Fixed parsing of maybe types in statements
[delight/core.git] / d-decls.cc
blob65b54030765429b5d50480c4ea49e4574c040433
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 // %% hack: on darwin (at least) using a DECL_EXTERNAL (IRState::getLibCallDecl)
596 // and TREE_STATIC FUNCTION_DECLs causes the stub label to be output twice. This
597 // is a work around. This doesn't handle the case in which the normal
598 // getLibCallDecl has already bee created and used. Note that the problem only
599 // occurs with function inlining is used.
600 gen.replaceLibCallDecl(this);
601 break;
602 case LINKd:
603 // %% If x86, regparm(1)
604 // not sure if reg struct return
605 break;
606 case LINKcpp:
607 break;
608 default:
609 fprintf(stderr, "linkage = %d\n", linkage);
610 assert(0);
613 csym->Sident = mangled_ident_str; // save for making thunks
614 csym->Stree = fn_decl;
616 gen.maybeSetUpBuiltin(this);
617 } else {
618 csym->Stree = isym->Stree;
621 return csym;
624 #define D_PRIVATE_THUNKS 1
626 /*************************************
628 Symbol *FuncDeclaration::toThunkSymbol(target_ptrdiff_t offset)
630 Symbol *sthunk;
631 Thunk * thunk;
633 toSymbol();
635 /* If the thunk is to be static (that is, it is being emitted in this
636 module, there can only be one FUNCTION_DECL for it. Thus, there
637 is a list of all thunks for a given function. */
638 if ( ! csym->thunks )
639 csym->thunks = new Array;
640 Array & thunks = * csym->thunks;
641 bool found = false;
643 for (unsigned i = 0; i < thunks.dim; i++) {
644 thunk = (Thunk *) thunks.data[i];
645 if (thunk->offset == offset) {
646 found = true;
647 break;
651 if (! found) {
652 thunk = new Thunk;
653 thunk->offset = offset;
654 thunks.push(thunk);
657 if ( ! thunk->symbol ) {
658 char *id;
659 char *n;
660 //type *t;
662 n = csym->Sident; // dmd uses 'sym' -- not sure what that is...
663 id = (char *) alloca(8 + 5 + strlen(n) + 1);
664 sprintf(id,"__t%"PRIdTSIZE"_%s", offset, n);
665 sthunk = symbol_calloc(id);
666 slist_add(sthunk);
667 /* todo: could use anonymous names like DMD, with ASM_FORMAT_RRIVATE_NAME*/
668 //sthunk = symbol_generate(SCstatic, csym->Stype);
669 //sthunk->Sflags |= SFLimplem;
671 tree target_func_decl = csym->Stree;
672 tree thunk_decl = build_decl(FUNCTION_DECL, get_identifier(id), TREE_TYPE( target_func_decl ));
673 dkeep(thunk_decl);
674 sthunk->Stree = thunk_decl;
676 //SET_DECL_ASSEMBLER_NAME(thunk_decl, DECL_NAME(thunk_decl));//old
677 DECL_CONTEXT(thunk_decl) = DECL_CONTEXT(target_func_decl); // from c++...
678 TREE_READONLY(thunk_decl) = TREE_READONLY(target_func_decl);
679 TREE_THIS_VOLATILE(thunk_decl) = TREE_THIS_VOLATILE(target_func_decl);
681 #ifdef D_PRIVATE_THUNKS
682 TREE_PRIVATE(thunk_decl) = 1;
683 #else
684 /* Due to changes in the assembler, it is not possible to emit
685 a private thunk that refers to an external symbol.
686 http://lists.gnu.org/archive/html/bug-binutils/2005-05/msg00002.html
688 DECL_EXTERNAL(thunk_decl) = DECL_EXTERNAL(target_func_decl);
689 TREE_STATIC(thunk_decl) = TREE_STATIC(target_func_decl);
690 TREE_PRIVATE(thunk_decl) = TREE_PRIVATE(target_func_decl);
691 TREE_PUBLIC(thunk_decl) = TREE_PUBLIC(target_func_decl);
692 #endif
694 DECL_ARTIFICIAL(thunk_decl) = 1;
695 DECL_IGNORED_P(thunk_decl) = 1;
696 DECL_NO_STATIC_CHAIN(thunk_decl) = 1;
697 DECL_INLINE(thunk_decl) = 0;
698 DECL_DECLARED_INLINE_P(thunk_decl) = 0;
699 //needed on some targets to avoid "causes a section type conflict"
700 D_DECL_ONE_ONLY(thunk_decl) = D_DECL_ONE_ONLY(target_func_decl);
701 if ( D_DECL_ONE_ONLY(thunk_decl) )
702 g.ofile->makeDeclOneOnly(thunk_decl);
704 TREE_ADDRESSABLE(thunk_decl) = 1;
705 TREE_USED (thunk_decl) = 1;
707 #ifdef D_PRIVATE_THUNKS
708 //g.ofile->prepareSymbolOutput(sthunk);
709 g.ofile->doThunk(thunk_decl, target_func_decl, offset);
710 #else
711 if ( TREE_STATIC(thunk_decl) )
712 g.ofile->doThunk(thunk_decl, target_func_decl, offset);
713 #endif
715 thunk->symbol = sthunk;
717 return thunk->symbol;
721 /****************************************
722 * Create a static symbol we can hang DT initializers onto.
725 Symbol *static_sym()
727 Symbol * s = symbol_tree(NULL_TREE);
728 //OLD//s->Sfl = FLstatic_sym;
729 /* Before GCC 4.0, it was possible to take the address of a CONSTRUCTOR
730 marked TREE_STATIC and the backend would output the data as an
731 anonymous symbol. This doesn't work in 4.0. To keep things, simple,
732 the same method is used for <4.0 and >= 4.0. */
733 // Can't build the VAR_DECL because the type is unknown
734 slist_add(s);
735 return s;
738 /**************************************
739 * Fake a struct symbol.
742 // Not used in GCC
744 Classsym *fake_classsym(char * name)
746 return 0;
750 /*************************************
751 * Create the "ClassInfo" symbol
754 Symbol *ClassDeclaration::toSymbol()
756 if (! csym)
758 tree decl;
759 csym = toSymbolX("__Class", SCextern, 0, "Z");
760 slist_add(csym);
761 decl = build_decl( VAR_DECL, get_identifier( csym->Sident ),
762 TREE_TYPE( ClassDeclaration::classinfo->type->toCtype() )); // want the RECORD_TYPE, not the REFERENCE_TYPE
763 csym->Stree = decl;
764 dkeep(decl);
766 g.ofile->setupStaticStorage(this, decl);
768 TREE_CONSTANT( decl ) = 0; // DMD puts this into .data, not .rodata...
769 TREE_READONLY( decl ) = 0;
771 return csym;
774 /*************************************
775 * Create the "InterfaceInfo" symbol
778 Symbol *InterfaceDeclaration::toSymbol()
780 if (!csym)
782 csym = ClassDeclaration::toSymbol();
783 tree decl = csym->Stree;
785 Symbol * temp_sym = toSymbolX("__Interface", SCextern, 0, "Z");
786 DECL_NAME( decl ) = get_identifier( temp_sym->Sident );
787 delete temp_sym;
789 TREE_CONSTANT( decl ) = 1; // Interface ClassInfo images are in .rodata, but classes arent..?
791 return csym;
794 /*************************************
795 * Create the "ModuleInfo" symbol
798 Symbol *Module::toSymbol()
800 if (!csym)
802 Type * some_type;
804 /* This causes problems .. workaround
805 is to call moduleinfo->toCtype() before we start processing
806 decls in genobjfile. ...
808 if (moduleinfo) {
809 some_type = moduleinfo->type;
810 } else {
811 some_type = gen.getObjectType();
814 some_type = gen.getObjectType();
816 csym = toSymbolX("__ModuleInfo", SCextern, 0, "Z");
817 slist_add(csym);
819 tree decl = build_decl(VAR_DECL, get_identifier(csym->Sident),
820 TREE_TYPE(some_type->toCtype())); // want the RECORD_TYPE, not the REFERENCE_TYPE
821 csym->Stree = decl;
823 dkeep(decl);
825 g.ofile->setupStaticStorage(this, decl);
827 TREE_CONSTANT( decl ) = 0; // *not* readonly, moduleinit depends on this
828 TREE_READONLY( decl ) = 0; // Not an lvalue, tho
830 return csym;
833 /*************************************
834 * This is accessible via the ClassData, but since it is frequently
835 * needed directly (like for rtti comparisons), make it directly accessible.
838 Symbol *ClassDeclaration::toVtblSymbol()
840 if (!vtblsym)
842 tree decl;
844 vtblsym = toSymbolX("__vtbl", SCextern, 0, "Z");
845 slist_add(vtblsym);
847 /* The DECL_INITIAL value will have a different type object from the
848 VAR_DECL. The back end seems to accept this. */
849 TypeSArray * vtbl_type = new TypeSArray(Type::tvoid->pointerTo(),
850 new IntegerExp(loc, vtbl.dim, Type::tindex));
852 decl = build_decl( VAR_DECL, get_identifier( vtblsym->Sident ), vtbl_type->toCtype() );
853 vtblsym->Stree = decl;
854 dkeep(decl);
856 g.ofile->setupStaticStorage(this, decl);
858 TREE_READONLY( decl ) = 1;
859 TREE_CONSTANT( decl ) = 1;
860 TREE_ADDRESSABLE( decl ) = 1;
861 // from cp/class.c
862 DECL_CONTEXT (decl) = TREE_TYPE( type->toCtype() );
863 DECL_VIRTUAL_P (decl) = 1;
864 DECL_ALIGN (decl) = TARGET_VTABLE_ENTRY_ALIGN;
866 return vtblsym;
869 /**********************************
870 * Create the static initializer for the struct/class.
873 /* Because this is called from the front end (mtype.cc:TypeStruct::defaultInit()),
874 we need to hold off using back-end stuff until the toobjfile phase.
876 Specifically, it is not safe create a VAR_DECL with a type from toCtype()
877 because there may be unresolved recursive references.
878 StructDeclaration::toObjFile calls toInitializer without ever calling
879 SymbolDeclaration::toSymbol, so we just need to keep checking if we
880 are in the toObjFile phase.
883 Symbol *AggregateDeclaration::toInitializer()
885 Symbol *s;
887 if (!sinit)
889 s = toSymbolX("__init", SCextern, 0, "Z");
890 slist_add(s);
891 sinit = s;
893 if (! sinit->Stree && g.ofile != NULL)
895 tree struct_type = type->toCtype();
896 if ( POINTER_TYPE_P( struct_type ) )
897 struct_type = TREE_TYPE( struct_type ); // for TypeClass, want the RECORD_TYPE, not the REFERENCE_TYPE
898 tree t = build_decl(VAR_DECL, get_identifier(sinit->Sident), struct_type);
899 sinit->Stree = t;
900 dkeep(t);
902 g.ofile->setupStaticStorage(this, t);
904 // %% what's the diff between setting this stuff on the DECL and the
905 // CONSTRUCTOR itself?
907 TREE_ADDRESSABLE( t ) = 1;
908 TREE_CONSTANT( t ) = 1;
909 TREE_READONLY( t ) = 1;
910 DECL_CONTEXT( t ) = 0; // These are always global
912 return sinit;
915 Symbol *TypedefDeclaration::toInitializer()
917 Symbol *s;
919 if (!sinit)
921 s = toSymbolX("__init", SCextern, 0, "Z");
922 s->Sfl = FLextern;
923 s->Sflags |= SFLnodebug;
924 slist_add(s);
925 sinit = s;
926 sinit->Sdt = ((TypeTypedef *)type)->sym->init->toDt();
928 return sinit;
931 Symbol *EnumDeclaration::toInitializer()
933 Symbol *s;
935 if (!sinit)
937 Identifier *ident_save = ident;
938 if (!ident)
939 { static int num;
940 char name[6 + sizeof(num) * 3 + 1];
941 snprintf(name, sizeof(name), "__enum%d", ++num);
942 ident = Lexer::idPool(name);
944 s = toSymbolX("__init", SCextern, 0, "Z");
945 ident = ident_save;
946 s->Sfl = FLextern;
947 s->Sflags |= SFLnodebug;
948 slist_add(s);
949 sinit = s;
951 if (! sinit->Stree && g.ofile != NULL)
953 tree t = build_decl(VAR_DECL, get_identifier(sinit->Sident), type->toCtype());
954 sinit->Stree = t;
955 dkeep(t);
957 g.ofile->setupStaticStorage(this, t);
958 TREE_CONSTANT( t ) = 1;
959 TREE_READONLY( t ) = 1;
960 DECL_CONTEXT( t ) = 0;
962 return sinit;
966 /******************************************
969 Symbol *Module::toModuleAssert()
971 // Not used in GCC
972 return 0;
975 /******************************************
978 Symbol *Module::toModuleArray()
980 // Not used in GCC (all array bounds checks are inlined)
981 return 0;
984 /********************************************
985 * Determine the right symbol to look up
986 * an associative array element.
987 * Input:
988 * flags 0 don't add value signature
989 * 1 add value signature
992 Symbol *TypeAArray::aaGetSymbol(char *func, int flags)
994 // This is not used in GCC (yet?)
995 return 0;