1: // Copyright (C) 1985-1998 by Symantec
2: // Copyright (C) 2000-2009 by Digital Mars
3: // All Rights Reserved
4: // http://www.digitalmars.com
5: // Written by Walter Bright
6: /*
7: * This source file is made available for personal use
8: * only. The license is in /dmd/src/dmd/backendlicense.txt
9: * or /dm/src/dmd/backendlicense.txt
10: * For any other uses, please contact Digital Mars.
11: */
12:
13: #if __SC__
14: #pragma once
15: #endif
16:
17: #ifndef CC_H
18: #define CC_H 1
19:
20: #ifdef SCPP
21: #define CPP (config.flags3 & CFG3cpp) // if compiling for C++
22: #else
23: #if !SPP
24: #define SCPP 0
25: #endif
26: #endif
27:
28: #ifndef CPP
29: #define CPP 0
30: #endif
31:
32: #ifndef SPP
33: #define SPP 0
34: #endif
35:
36: #ifndef MARS
37: #define MARS 0 // not compiling MARS code
38: #endif
39:
40: #ifndef HTOD
41: #define HTOD 0
42: #endif
43:
44: #define GENOBJ 1 // generating .obj file
45:
46: #define mskl(i) (1L << (i)) /* convert int to mask */
47:
48: #ifndef STATIC
49: #define STATIC static
50: #endif
51:
52: #ifndef CEXTERN
53: #define CEXTERN extern
54: #endif
55:
56: // Warnings
57: enum WM
58: {
59: WM_no_inline = 1, //function '%s' is too complicated to inline
60: WM_assignment = 2, //possible unintended assignment
61: WM_nestcomment = 3, //comments do not nest
62: WM_assignthis = 4, //assignment to 'this' is obsolete, use X::operator new/delete
63: WM_notagname = 5, //no tag name for struct or enum
64: WM_valuenotused = 6, //value of expression is not used
65: WM_extra_semi = 7, //possible extraneous ';'
66: WM_large_auto = 8, //very large automatic
67: WM_obsolete_del = 9, //use delete[] rather than delete[expr], expr ignored
68: WM_obsolete_inc = 10, //using operator++() (or --) instead of missing operator++(int)
69: WM_init2tmp = 11, //non-const reference initialized to temporary
70: WM_used_b4_set = 12, //variable '%s' used before set
71: WM_bad_op = 13, //Illegal type/size of operands for the %s instruction
72: WM_386_op = 14, //Reference to '%s' caused a 386 instruction to be generated
73: WM_ret_auto = 15, //returning address of automatic '%s'
74: WM_ds_ne_dgroup = 16, //DS is not equal to DGROUP
75: WM_unknown_pragma = 17, //unrecognized pragma
76: WM_implied_ret = 18, //implied return at closing '}' does not return value
77: WM_num_args = 19, //%d actual arguments expected for %s, had %d
78: WM_before_pch = 20, //symbols or macros defined before #include of precompiled header
79: WM_pch_first = 21, //precompiled header must be first #include when -H is used
80: WM_pch_config = 22,
81: WM_divby0 = 23,
82: WM_badnumber = 24,
83: WM_ccast = 25,
84: WM_obsolete = 26,
85: #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
86: WM_skip_attribute = 27, // skip GNUC attribute specification
87: WM_warning_message = 28, // preprocessor warning message
88: WM_bad_vastart = 29, // args for builtin va_start bad
89: WM_undefined_inline = 30, // static inline not expanded or defined
90: #endif
91: };
92:
93: // Language for error messages
94: enum LANG
95: { LANGenglish,
96: LANGgerman,
97: LANGfrench,
98: LANGjapanese,
99: };
100:
101: #include "cdef.h" // host and target compiler definition
102:
103: #define INITIALIZED_STATIC_DEF static
104:
105: #if MEMMODELS == 1
106: #define LARGEDATA 0 /* don't want 48 bit pointers */
107: #define LARGECODE 0
108: #endif
109:
110: #ifndef __INTSIZE
111: #define __INTSIZE 4 // host ints are 4 bytes
112: #endif
113:
114: #if SPP || SCPP
115: #include "msgs2.h"
116: #endif
117: #include "ty.h"
118: #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
119: #include "../tk/mem.h"
120: #else
121: #include "mem.h"
122: #endif
123: #include "list.h"
124: #include "vec.h"
125:
126: #if SPP
127: #define COMPILER "Preprocessor"
128: #define ACTIVITY "preprocessing..."
129: #elif HTOD
130: #define COMPILER ".h to D Migration Tool"
131: #define ACTIVITY "migrating..."
132: #else
133: #define COMPILER "C/C++ Compiler"
134: #define ACTIVITY "compiling..."
135: #endif
136:
137: #ifdef DEBUG
138: # define debug(a) (a)
139: # define debugx(a) (a)
140: # define debug_assert assert
141: #else
142: # define debug(a)
143: # define debugx(a)
144: # define debug_assert(e)
145: #endif
146:
147:
148: /***************************
149: * Print out debugging information.
150: */
151:
152: #ifdef DEBUG
153: #define debugmes(s) (debugw && dbg_printf(s))
154: #define cmes(s) (debugc && dbg_printf(s))
155: #define cmes2(s,b) (debugc && dbg_printf((s),(b)))
156: #define cmes3(s,b,c) (debugc && dbg_printf((s),(b),(c)))
157: #else
158: #define debugmes(s)
159: #define cmes(s)
160: #define cmes2(s,b)
161: #define cmes3(s,b,c)
162: #endif
163:
164: #define TRUE 1
165: #define FALSE 0
166:
167: #ifndef ARG_TRUE
168: #define ARG_TRUE ,TRUE
169: #define ARG_FALSE ,FALSE
170: #endif
171:
172: #define arraysize(array) (sizeof(array) / sizeof(array[0]))
173:
174: #define IDMAX 900 //467 //254 // identifier max (excluding terminating 0)
175: #define IDOHD (4+1+sizeof(int)*3) // max amount of overhead to ID added by
176: #define STRMAX 65000 // max length of string (determined by
177: // max ph size)
178:
179: enum SC;
180: struct Thunk;
181: struct token_t;
182: struct PARAM;
183: typedef struct PARAM param_t;
184: struct block;
185: struct Classsym;
186: struct Nspacesym;
187: struct Outbuffer;
188: struct Aliassym;
189: struct dt_t;
190: typedef struct TYPE type;
191: typedef struct Symbol symbol;
192: typedef Symbol Funcsym;
193: //typedef Symbol Classsym; // a Symbol that is an SCclass, SCstruct or SCunion
194: struct elem;
195: typedef struct MACRO macro_t;
196: typedef struct BLKLST blklst;
197: typedef list_t symlist_t; /* list of pointers to Symbols */
198: typedef struct SYMTAB_S symtab_t;
199: struct code;
200:
201: extern Config config;
202:
203: /////////// Position in source file
204:
205: typedef struct Srcpos
206: {
207: unsigned Slinnum; // 0 means no info available
208: #if SPP || SCPP
209: struct Sfile **Sfilptr; // file
210: #define srcpos_sfile(p) (**(p).Sfilptr)
211: #define srcpos_name(p) (srcpos_sfile(p).SFname)
212: #endif
213: #if MARS
214: const char *Sfilename;
215: #define srcpos_name(p) ((p).SFname)
216: #endif
217: #if M_UNIX
218: short Sfilnum; // file number
219: #endif
220: #if SOURCE_OFFSETS
221: unsigned long Sfiloff; // byte offset
222: #endif
223:
224: void print(const char *func);
225: } Srcpos;
226:
227: #ifndef TOKEN_H
228: #include "token.h"
229: #endif
230:
231: /**********************************
232: * Current 'state' of the compiler.
233: * Used to gather together most global variables.
234: * This struct is saved/restored during function body parsing.
235: */
236:
237: typedef struct Pstate
238: {
239: char STinopeq; // if in n2_createopeq()
240: char STinarglist; // if !=0, then '>' is the end of a template
241: // argument list, not an operator
242: char STinsizeof; // !=0 if in a sizeof expression. Useful to
243: // prevent <array of> being converted to
244: // <pointer to>.
245: char STintemplate; // if !=0, then expanding a function template
246: // (do not expand template Symbols)
247: char STdeferDefaultArg; // defer parsing of default arg for parameter
248: char STnoexpand; // if !=0, don't expand template symbols
249: char STignoretal; // if !=0 ignore template argument list
250: char STexplicitInstantiation; // if !=0, then template explicit instantiation
251: char STexplicitSpecialization; // if !=0, then template explicit specialization
252: char STinconstexp; // if !=0, then parsing a constant expression
253: char STisaddr; // is this a possible pointer to member expression?
254: unsigned STinexp; // if !=0, then in an expression
255: #if NTEXCEPTIONS
256: char STinfilter; // if !=0 then in exception filter
257: char STinexcept; // if !=0 then in exception handler
258: block *STbfilter; // current exception filter
259: #endif
260: #if !MARS
261: int STinitseg; // segment for static constructor function pointer
262: #endif
263: Funcsym *STfuncsym_p; // if inside a function, then this is the
264: // function Symbol.
265:
266: # define funcsym_p (pstate.STfuncsym_p)
267:
268: unsigned STflags;
269: # define PFLpreprocessor 1 // in preprocessor
270: # define preprocessor (pstate.STflags & PFLpreprocessor)
271: # define PFLmasm 2 // in Microsoft-style inline assembler
272: # define PFLbasm 4 // in Borland-style inline assembler
273: # define inline_asm (pstate.STflags & (PFLmasm | PFLbasm))
274: # define PFLsemi 8 // ';' means start of comment
275: //# define PFLautogen 0x10 // automatically generate HX ph file
276: # define PFLmftemp 0x20 // if expanding member function template
277: # define PFLextdef 0x40 // we had an external def
278: # define PFLhxwrote 0x80 // already generated HX ph file
279: # define PFLhxdone 0x100 // done with HX ph file
280: #if TX86
281: # define PFLhxread 0x200 // have read in an HX ph file
282: # define PFLhxgen 0x400 // need to generate HX ph file
283: # define PFLphread 0x800 // read a ph file
284: # define PFLcomdef 0x1000 // had a common block
285: # define PFLmacdef 0x2000 // defined a macro in the source code
286: # define PFLsymdef 0x4000 // declared a global Symbol in the source
287: # define PFLinclude 0x8000 // read a .h file
288: # define PFLmfc 0x10000 // something will affect MFC compatibility
289: #endif
290: #if !MARS
291: int STinparamlist; // if != 0, then parser is in
292: // function parameter list
293: int STingargs; // in template argument list
294: list_t STincalias; // list of include aliases
295: list_t STsysincalias; // list of system include aliases
296: #endif
297:
298: #if TX86
299: // should probably be inside #if HYDRATE, but unclear for the dmc source
300: char SThflag; // FLAG_XXXX: hydration flag
301: #define FLAG_INPLACE 0 // in place hydration
302: #define FLAG_HX 1 // HX file hydration
303: #define FLAG_SYM 2 // .SYM file hydration
304: #endif
305:
306: Classsym *STclasssym; // if in the scope of this class
307: symlist_t STclasslist; // list of classes that have deferred inline
308: // functions to parse
309: Classsym *STstag; // returned by struct_searchmember() and with_search()
310: SYMIDX STmarksi; // to determine if temporaries are created
311: char STnoparse; // add to classlist instead of parsing
312: char STdeferparse; // defer member func parse
313: enum SC STgclass; // default function storage class
314: int STdefertemps; // defer allocation of temps
315: int STdeferaccesscheck; // defer access check for members (BUG: it
316: // never does get done later)
317: int STnewtypeid; // parsing new-type-id
318: int STdefaultargumentexpression; // parsing default argument expression
319: block *STbtry; // current try block
320: block *STgotolist; // threaded goto scoping list
321: long STtdbtimestamp; // timestamp of tdb file
322: Symbol *STlastfunc; // last function symbol parsed by ext_def()
323:
324: // For "point of definition" vs "point of instantiation" template name lookup
325: unsigned STsequence; // sequence number (Ssequence) of next Symbol
326: unsigned STmaxsequence; // won't find Symbols with STsequence larger
327: // than STmaxsequence
328: } Pstate;
329:
330: extern Pstate pstate;
331:
332: /****************************
333: * Global variables.
334: */
335:
336: typedef struct Cstate
337: {
338: struct BLKLST *CSfilblk; // current source file we are parsing
339: Symbol *CSlinkage; // table of forward referenced linkage pragmas
340: list_t CSlist_freelist; // free list for list package
341: symtab_t *CSpsymtab; // pointer to current Symbol table
342: #if MEMORYHX
343: void **CSphx; // pointer to HX data block
344: #endif
345: char *modname; // module unique identifier
346: } Cstate;
347:
348: extern Cstate cstate;
349:
350: /* Bits for sytab[] that give characteristics of storage classes */
351: #define SCEXP 1 // valid inside expressions
352: #define SCKEP 2 // Symbol should be kept even when function is done
353: #define SCSCT 4 // storage class is valid for use in static ctor
354: #define SCSS 8 // storage class is on the stack
355: #define SCRD 0x10 // we can do reaching definitions on these
356:
357: // Determine if Symbol has a Ssymnum associated with it.
358: // (That is, it is allocated on the stack or has live variable analysis
359: // done on it, so it is stack and register variables.)
360: #define symbol_isintab(s) (sytab[(s)->Sclass] & SCSS)
361:
362: #if defined(__SC__) || defined(_MSC_VER)
363: typedef char enum_SC;
364: #else
365: typedef enum SC enum_SC;
366: #endif
367:
368: /******************************************
369: * Basic blocks:
370: * Basic blocks are a linked list of all the basic blocks
371: * in a function. startblock heads the list.
372: */
373:
374: #if MARS
375: struct ClassDeclaration;
376: struct Declaration;
377: struct Module;
378: #endif
379:
380: struct Blockx
381: {
382: #if MARS
383: block *startblock;
384: block *curblock;
385: Funcsym *funcsym;
386: Symbol *context; // eh frame context variable
387: int scope_index; // current scope index
388: int next_index; // value for next scope index
389: unsigned flags; // value to OR into Bflags
390: block *tryblock; // current enclosing try block
391: elem *init; // static initializer
392: ClassDeclaration *classdec;
393: Declaration *member; // member we're compiling for
394: Module *module; // module we're in
395: #endif
396: };
397:
398: typedef struct block
399: {
400: union
401: {
402: elem *Belem; // pointer to elem tree
403: list_t Blist; // list of expressions
404: };
405:
406: block *Bnext; // pointer to next block in list
407: list_t Bsucc; // linked list of pointers to successors
408: // of this block
409: list_t Bpred; // and the predecessor list
410: int Bindex; // into created object stack
411: int Bendindex; // index at end of block
412: block *Btry; // BCtry,BC_try: enclosing try block, if any
413: // BC???: if in try-block, points to BCtry or BC_try
414: // note that can't have a BCtry and BC_try in
415: // the same function.
416: union
417: { targ_llong *Bswitch; // BCswitch: pointer to switch data
418: struct {
419: regm_t usIasmregs; // Registers modified
420: unsigned char bIasmrefparam; // References parameters?
421: #define usIasmregs BS.BIASM.usIasmregs
422: #define bIasmrefparam BS.BIASM.bIasmrefparam
423: } BIASM; // BCasm
424:
425: struct
426: { Symbol *catchvar; // __throw() fills in this
427: #define catchvar BS.BITRY.catchvar
428: } BITRY; // BCtry
429:
430: #if SCPP
431: struct
432: { type *catchtype; // one type for each catch block
433: #define Bcatchtype BS.BICATCH.catchtype
434: } BICATCH; // BCcatch
435: #endif
436: #if MARS
437: struct
438: { Symbol *catchtype; // one type for each catch block
439: #define Bcatchtype BS.BIJCATCH.catchtype
440: } BIJCATCH; // BCjcatch
441: #endif
442: #if NTEXCEPTIONS || MARS
443: struct
444: {
445: #if MARS
446: Symbol *jcatchvar; // __j_throw() fills in this
447: #define jcatchvar BS.BI_TRY.jcatchvar
448: #endif
449: int Bscope_index; // index into scope table
450: #define Bscope_index BS.BI_TRY.Bscope_index
451: int Blast_index; // enclosing index into scope table
452: #define Blast_index BS.BI_TRY.Blast_index
453: } BI_TRY; // BC_try
454: #endif
455:
456: } BS;
457: Srcpos Bsrcpos; // line number (0 if not known)
458: unsigned char BC; // exit condition (enum BC)
459: // NEW
460: unsigned char Balign; // alignment
461:
462: unsigned short Bflags; // flags (BFLxxxx)
463: #define BFLvisited 1 // set if block is visited
464: #define BFLmark 2 // set if block is visited
465: #define BFLjmpoptdone 4 // set when no more jump optimizations
466: // are possible for this block
467: #define BFLnostackopt 8 // set when stack elimination should not
468: // be done
469: #if NTEXCEPTIONS
470: #define BFLehcode 0x10 // set when we need to load exception code
471: #define BFLunwind 0x1000 // do local_unwind following block
472: #endif
473: #define BFLnomerg 0x20 // do not merge with other blocks
474: #define BFLprolog 0x80 // generate function prolog
475: #define BFLepilog 0x100 // generate function epilog
476: #define BFLrefparam 0x200 // referenced parameter
477: #define BFLreflocal 0x400 // referenced local
478: #define BFLoutsideprolog 0x800 // outside function prolog/epilog
479: #define BFLlabel 0x2000 // block preceded by label
480: #define BFLvolatile 0x4000 // block is volatile
481: code *Bcode; // code generated for this block
482:
483: unsigned Bweight; // relative number of times this block
484: // is executed (optimizer and codegen)
485:
486: unsigned Bdfoidx; // index of this block in dfo[]
487: union
488: {
489: // CPP
490: struct
491: {
492: SYMIDX symstart; // (symstart <= symnum < symend) Symbols
493: SYMIDX symend; // are declared in this block
494: block *endscope; // block that forms the end of the
495: // scope for the declared Symbols
496: unsigned blknum; // position of block from startblock
497: Symbol *Binitvar; // !=NULL points to an auto variable with
498: // an explicit or implicit initializer
499: block *gotolist; // BCtry, BCcatch: backward list of try scopes
500: block *gotothread; // BCgoto: threaded list of goto's to
501: // unknown labels
502:
503: #define Bsymstart _BLU._UP.symstart
504: #define Bsymend _BLU._UP.symend
505: #define Bendscope _BLU._UP.endscope
506: #define Bblknum _BLU._UP.blknum
507: #define Binitvar _BLU._UP.Binitvar
508: #define Bgotolist _BLU._UP.gotolist
509: #define Bgotothread _BLU._UP.gotothread
510: }_UP;
511:
512: // OPTIMIZER
513: struct
514: {
515: vec_t Bdom; // mask of dominators for this block
516: vec_t Binrd;
517: vec_t Boutrd; // IN and OUT for reaching definitions
518: vec_t Binlv;
519: vec_t Boutlv; // IN and OUT for live variables
520: vec_t Bin;
521: vec_t Bout; // IN and OUT for other flow analyses
522: vec_t Bgen;
523: vec_t Bkill; // pointers to bit vectors used by data
524: // flow analysis
525:
526: // BCiftrue can have different vectors for the 2nd successor:
527: vec_t Bout2;
528: vec_t Bgen2;
529: vec_t Bkill2;
530:
531: #define Bdom _BLU._UO.Bdom
532: #define Binrd _BLU._UO.Binrd
533: #define Boutrd _BLU._UO.Boutrd
534: #define Binlv _BLU._UO.Binlv
535: #define Boutlv _BLU._UO.Boutlv
536: #define Bin _BLU._UO.Bin
537: #define Bout _BLU._UO.Bout
538: #define Bgen _BLU._UO.Bgen
539: #define Bkill _BLU._UO.Bkill
540: #define Bout2 _BLU._UO.Bout2
541: #define Bgen2 _BLU._UO.Bgen2
542: #define Bkill2 _BLU._UO.Bkill2
543: }_UO;
544:
545: // CODGEN
546: struct
547: {
548: targ_size_t Btablesize; // BCswitch, BCjmptab
549: targ_size_t Btableoffset; // BCswitch, BCjmptab
550: targ_size_t Boffset; // code offset of start of this block
551: targ_size_t Bsize; // code size of this block
552: con_t Bregcon; // register state at block exit
553: targ_size_t Btryoff; // BCtry: offset of try block data
554:
555: #define Btablesize _BLU._UD.Btablesize
556: #define Btableoffset _BLU._UD.Btableoffset
557: #define Boffset _BLU._UD.Boffset
558: #define Bsize _BLU._UD.Bsize
559: // #define Bcode _BLU._UD.Bcode
560: #define Bregcon _BLU._UD.Bregcon
561: #define Btryoff _BLU._UD.Btryoff
562: } _UD;
563: } _BLU;
564: } block;
565:
566: #define list_block(l) ((block *) list_ptr(l))
567:
568: /** Basic block control flow operators. **/
569:
570: enum BC {
571: BCgoto = 1, // goto Bsucc block
572: BCiftrue = 2, // if (Belem) goto Bsucc[0] else Bsucc[1]
573: BCret = 3, // return (no return value)
574: BCretexp = 4, // return with return value
575: BCexit = 5, // never reaches end of block (like exit() was called)
576: BCasm = 6, // inline assembler block (Belem is NULL, Bcode
577: // contains code generated).
578: // These blocks have one or more successors in Bsucc,
579: // never 0
580: BCswitch = 7, // switch statement
581: // Bswitch points to switch data
582: // Default is Bsucc
583: // Cases follow in linked list
584: BCifthen = 8, // a BCswitch is converted to if-then
585: // statements
586: BCjmptab = 9, // a BCswitch is converted to a jump
587: // table (switch value is index into
588: // the table)
589: BCtry = 10, // C++ try block
590: // first block in a try-block. The first block in
591: // Bsucc is the next one to go to, subsequent
592: // blocks are the catch blocks
593: BCcatch = 11, // C++ catch block
594: BCjump = 12, // Belem specifies (near) address to jump to
595: BC_try = 13, // SEH: first block of try-except or try-finally
596: // Jupiter, Mars: try-catch or try-finally
597: BC_filter = 14, // SEH exception-filter (always exactly one block)
598: BC_finally = 15, // first block of SEH termination-handler,
599: // or finally block
600: BC_ret = 16, // last block of SEH termination-handler or finally block
601: BC_except = 17, // first block of SEH exception-handler
602: BCjcatch = 18, // first block of Jupiter or Mars catch-block
603: BCjplace = 19, // Jupiter: placeholder
604: BCMAX
605: };
606:
607: /**********************************
608: * Functions
609: */
610:
611: typedef struct SYMTAB_S
612: {
613: SYMIDX top; // 1 past end
614: SYMIDX symmax; // max # of entries in tab[] possible
615: Symbol **tab; // local Symbol table
616: } symtab_t;
617:
618: typedef struct FUNC_S
619: {
620: symlist_t Fsymtree; // local Symbol table
621: block *Fstartblock; // list of blocks comprising function
622: symtab_t Flocsym; // local Symbol table
623: Srcpos Fstartline; // starting line # of function
624: Srcpos Fendline; // line # of closing brace of function
625: Symbol *F__func__; // symbol for __func__[] string
626: unsigned Fflags;
627: # define Fpending 1 // if function has been queued for being written
628: # define Foutput 2 /* if function has been written out */
629: # define Finline 0x10 /* if SCinline, and function really is inline */
630: # define Foverload 0x20 /* if function can be overloaded */
631: # define Ftypesafe 0x40 /* if function name needs type appended */
632: # define Fmustoutput 0x80 /* set for forward ref'd functions that */
633: /* must be output */
634: # define Finlinenest 0x1000 /* used as a marker to prevent nested */
635: /* inlines from expanding */
636: # define Flinkage 0x2000 /* linkage is already specified */
637: # define Fstatic 0x4000 /* static member function (no this) */
638: # define Foperator 4 /* if operator overload */
639: # define Fcast 8 /* if cast overload */
640: # define Fvirtual 0x100 /* if function is a virtual function */
641: # define Fctor 0x200 /* if function is a constructor */
642: # define Fdtor 0x400 /* if function is a destructor */
643: # define Fnotparent 0x800 /* if function is down Foversym chain */
644: # define Fbitcopy 0x8000 /* it's a simple bitcopy (op=() or X(X&)) */
645: # define Fpure 0x10000 // pure function
646: # define Finstance 0x20000 // function is an instance of a template
647: # define Ffixed 0x40000 // ctor has had cpp_fixconstructor() run on it,
648: // dtor has had cpp_fixdestructor()
649: # define Fintro 0x80000 // function doesn't hide a previous virtual function
650: //# define unused 0x100000 // unused bit
651: # define Fkeeplink 0x200000 // don't change linkage to default
652: # define Fnodebug 0x400000 // do not generate debug info for this function
653: # define Fgen 0x800000 // compiler generated function
654: # define Finvariant 0x1000000 // __invariant function
655: # define Fexplicit 0x2000000 // explicit constructor
656: # define Fsurrogate 0x4000000 // surrogate call function
657: unsigned Fflags3;
658: #define Fvtblgen 0x01 // generate vtbl[] when this function is defined
659: #define Femptyexc 0x02 // empty exception specification (obsolete, use Tflags & TFemptyexc)
660: #define Fcppeh 0x04 // uses C++ EH
661: #define Fdeclared 0x10 // already declared function Symbol
662: #define Fmark 0x20 // has unbalanced OPctor's
663: #define Fnteh 0x08 // uses NT Structured EH
664: #define Fdoinline 0x40 // do inline walk
665: #define Foverridden 0x80 // ignore for overriding purposes
666: #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
667: #define Fnowrite 0x100 // SCinline should never output definition
668: #else
669: #define Fjmonitor 0x100 // Jupiter synchronized function
670: #endif
671: #define Fnosideeff 0x200 // function has no side effects
672: #define F3badoparrow 0x400 // bad operator->()
673: #define Fmain 0x800 // function is main() or wmain()
674: #define Fnested 0x1000 // D nested function with 'this'
675: #define Fmember 0x2000 // D member function with 'this'
676: #define Fnotailrecursion 0x4000 // no tail recursion optimizations
677: #define Ffakeeh 0x8000 // allocate space for NT EH context sym anyway
678: unsigned char Foper; // operator number (OPxxxx) if Foperator
679:
680: Symbol *Fparsescope; // use this scope to parse friend functions
681: // which are defined within a class, so the
682: // class is in scope, but are not members
683: // of the class
684:
685: Classsym *Fclass; // if member of a class, this is the class
686: // (I think this is redundant with Sscope)
687: Funcsym *Foversym; // overloaded function at same scope
688: symlist_t Fclassfriends; /* Symbol list of classes of which this */
689: /* function is a friend */
690: block *Fbaseblock; // block where base initializers get attached
691: block *Fbaseendblock; // block where member destructors get attached
692: elem *Fbaseinit; /* list of member initializers (meminit_t) */
693: /* this field has meaning only for */
694: /* functions which are constructors */
695: struct token_t *Fbody; /* if deferred parse, this is the list */
696: /* of tokens that make up the function */
697: /* body */
698: // also used if SCfunctempl, SCftexpspec
699: unsigned Fsequence; // sequence number at point of definition
700: union
701: {
702: Symbol *Ftempl; // if Finstance this is the template that generated it
703: struct Thunk *Fthunk; // !=NULL if this function is actually a thunk
704: };
705: Funcsym *Falias; // SCfuncalias: function Symbol referenced
706: // by using-declaration
707: symlist_t Fthunks; // list of thunks off of this function
708: param_t *Farglist; // SCfunctempl: the template-parameter-list
709: param_t *Fptal; // Finstance: this is the template-argument-list
710: // SCftexpspec: for explicit specialization, this
711: // is the template-argument-list
712: list_t Ffwdrefinstances; // SCfunctempl: list of forward referenced instances
713: list_t Fexcspec; // List of types in the exception-specification
714: // (NULL if none or empty)
715: Funcsym *Fexplicitspec; // SCfunctempl, SCftexpspec: threaded list
716: // of SCftexpspec explicit specializations
717: Funcsym *Fsurrogatesym; // Fsurrogate: surrogate cast function
718:
719: #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
720: char *Fredirect; // redirect function name to this name in object
721: #endif
722: } func_t;
723:
724: #define func_calloc() ((func_t *) mem_fcalloc(sizeof(func_t)))
725: #define func_free(f) mem_ffree(f)
726:
727: /**************************
728: * Item in list for member initializer.
729: */
730:
731: typedef struct MEMINIT
732: {
733: list_t MIelemlist; /* arg list for initializer */
734: Symbol *MIsym; /* if NULL, then this initializer is */
735: /* for the base class. Otherwise, this */
736: /* is the member that needs the ctor */
737: /* called for it */
738: } meminit_t;
739:
740:
741: /************************************
742: * Base classes are a list of these.
743: */
744:
745: typedef struct BASECLASS
746: {
747: Classsym *BCbase; // base class Symbol
748: struct BASECLASS *BCnext; // next base class
749: targ_size_t BCoffset; // offset from start of derived class to this
750: #if VBTABLES
751: unsigned short BCvbtbloff; // for BCFvirtual, offset from start of
752: // vbtbl[] to entry for this virtual base.
753: // Valid in Sbase list
754: #else
755: targ_size_t memoffset; /* for BCFvirtual, offset from this to
756: pointer to virtual base class.
757: Valid in Sbase list
758: */
759: Symbol *param; /* parameter for this Symbol (in */
760: /* Svirtbase list only) */
761: #endif
762: symlist_t BCpublics; // public members of base class (list is freeable)
763: list_t BCmptrlist; // (in Smptrbase only) this is the vtbl
764: // (NULL if not different from base class's vtbl
765: Symbol *BCvtbl; // Symbol for vtbl[] array (in Smptrbase list)
766: // Symbol for vbtbl[] array (in Svbptrbase list)
767: unsigned BCflags; // base class flags
768: #define BCFpublic 1 // base class is public
769: #define BCFprotected 2 // base class is protected
770: #define BCFprivate 4 // base class is private
771: #define BCFpmask (BCFpublic | BCFprotected | BCFprivate)
772:
773: #define BCFvirtual 8 // base class is virtual
774: #define BCFvfirst 0x10 // virtual base class, and this is the
775: // first virtual appearance of it
776: #define BCFnewvtbl 0x20 // new vtbl generated for this base class
777: #define BCFvirtprim 0x40 // Primary base class of a virtual base class
778: #define BCFdependent 0x80 // base class is a dependent type
779: Classsym *BCparent; // immediate parent of this base class
780: // in Smptrbase
781: #if TX86
782: struct BASECLASS *BCpbase; // parent base, NULL if did not come from a parent
783: #endif
784: } baseclass_t;
785:
786: #define baseclass_malloc() ((baseclass_t *)mem_fmalloc(sizeof(baseclass_t)))
787: #define baseclass_free(b) ((void)(b))
788:
789: /*************************
790: * For virtual tables.
791: */
792:
793: typedef struct MPTR
794: { targ_short MPd;
795: targ_short MPi;
796: Symbol *MPf;
797: Symbol *MPparent; // immediate parent of this base class
798: // in Smptrbase
799: unsigned char MPflags;
800: #define MPTRvirtual 1 // it's an offset to a virtual base
801: #define MPTRcovariant 2 // need covariant return pointer adjustment
802: } mptr_t;
803:
804: #define list_mptr(l) ((mptr_t *) list_ptr(l))
805:
806:
807: /***********************************
808: * Information gathered about externally defined template member functions,
809: * member data, and member classes.
810: */
811:
812: struct TMF
813: {
814: Classsym *stag; // if !=NULL, this is the enclosing class
815: token_t *tbody; // tokens making it up
816: token_t *to; // pointer within tbody where we left off in
817: // template_function_decl()
818: param_t *temp_arglist; // template parameter list
819: int member_class; // 1: it's a member class
820:
821: // These are for member templates
822: int castoverload; // 1: it's a user defined cast
823: char *name; // name of template (NULL if castoverload)
824: int member_template; // 0: regular template
825: // 1: member template
826: param_t *temp_arglist2; // if member template,
827: // then member's template parameter list
828:
829: param_t *ptal; // if explicit specialization, this is the
830: // explicit template-argument-list
831: Symbol *sclassfriend; // if member function is a friend of class X,
832: // this is class X
833: unsigned access_specifier;
834: };
835:
836: /***********************************
837: * Information gathered about primary member template explicit specialization.
838: */
839:
840: struct TME
841: {
842: /* Given:
843: * template<> template<class T2> struct A<short>::B { };
844: * temp_arglist2 = <class T2>
845: * name = "B"
846: * ptal = <short>
847: */
848: param_t *ptal; // explicit template-argument-list for enclosing
849: // template A
850: symbol *stempl; // template symbol for B
851: };
852:
853: /***********************************
854: * Information gathered about nested explicit specializations.
855: */
856:
857: struct TMNE
858: {
859: /* For:
860: * template<> template<> struct A<short>::B<double> { };
861: */
862:
863: enum_TK tk; // TKstruct / TKclass / TKunion
864: char *name; // name of template, i.e. "B"
865: param_t *ptal; // explicit template-argument-list for enclosing
866: // template A, i.e. "short"
867: token_t *tdecl; // the tokens "<double> { }"
868: };
869:
870: /***********************************
871: * Information gathered about nested class friends.
872: */
873:
874: struct TMNF
875: {
876: /* Given:
877: * template<class T> struct A { struct B { }; };
878: * class C { template<class T> friend struct A<T>::B;
879: */
880: token_t *tdecl; // the tokens "A<T>::B;"
881: param_t *temp_arglist; // <class T>
882: Classsym *stag; // the class symbol C
883: symbol *stempl; // the template symbol A
884: };
885:
886: /***********************************
887: * Special information for class templates.
888: */
889:
890: typedef struct TEMPLATE
891: {
892: symlist_t TMinstances; // list of Symbols that are instances
893: param_t *TMptpl; // template-parameter-list
894: struct token_t *TMbody; // tokens making up class body
895: unsigned TMsequence; // sequence number at point of definition
896: list_t TMmemberfuncs; // templates for member functions (list of TMF's)
897: list_t TMexplicit; // list of TME's: primary member template explicit specializations
898: list_t TMnestedexplicit; // list of TMNE's: primary member template nested explicit specializations
899: Symbol *TMnext; // threaded list of template classes headed
900: // up by template_class_list
901: enum_TK TMtk; // TKstruct, TKclass or TKunion
902: int TMflags; // STRxxx flags
903:
904: symbol *TMprimary; // primary class template
905: symbol *TMpartial; // next class template partial specialization
906: param_t *TMptal; // template-argument-list for partial specialization
907: // (NULL for primary class template)
908: list_t TMfriends; // list of Classsym's for which any instantiated
909: // classes of this template will be friends of
910: list_t TMnestedfriends; // list of TMNF's
911: int TMflags2; // !=0 means dummy template created by template_createargtab()
912: } template_t;
913:
914: /***********************************
915: * Special information for enums.
916: */
917:
918: typedef struct ENUM
919: {
920: unsigned SEflags;
921: #define SENnotagname 1 // no tag name for enum
922: #define SENforward 2 // forward referenced enum
923:
924: Symbol *SEalias; // pointer to identifier E to use if
925: /* enum was defined as: */
926: /* typedef enum { ... } E; */
927: symlist_t SEenumlist; // all members of enum
928: } enum_t;
929:
930: /***********************************
931: * Special information for structs.
932: */
933:
934: typedef struct STRUCT
935: {
936: targ_size_t Sstructsize; // size of struct
937: symlist_t Sfldlst; // all members of struct (list freeable)
938: Symbol *Sroot; // root of binary tree Symbol table
939: unsigned Salignsize; // size of struct for alignment purposes
940: unsigned char Sstructalign; // struct member alignment in effect
941: unsigned long Sflags;
942: #define STRanonymous 0x01 // set for unions with no tag names
943: #define STRglobal 0x02 // defined at file scope
944: #define STRnotagname 0x04 // struct/class with no tag name
945: #define STRoutdef 0x08 // we've output the debug definition
946: #define STRbitfields 0x10 // set if struct contains bit fields
947: #define STRpredef 0x1000 // a predefined struct
948: #define STRunion 0x4000 // actually, it's a union
949:
950: #define STRabstract 0x20 // abstract class
951: #define STRbitcopy 0x40 // set if operator=() is merely a bit copy
952: #define STRanyctor 0x80 // set if any constructors were defined
953: // by the user
954: #define STRnoctor 0x100 // no constructors allowed
955: #define STRgen 0x200 // if struct is an instantiation of a
956: // template class, and was generated by
957: // that template
958: #define STRvtblext 0x400 // generate vtbl[] only when first member function
959: // definition is encountered (see Fvtblgen)
960: #define STRexport 0x800 // all member functions are to be _export
961: #define STRclass 0x8000 // it's a class, not a struct
962: #if TX86
963: #define STRimport 0x40000 // imported class
964: #define STRstaticmems 0x80000 // class has static members
965: #endif
966: #define STR0size 0x100000 // zero sized struct
967: #define STRinstantiating 0x200000 // if currently being instantiated
968: #define STRexplicit 0x400000 // if explicit template instantiation
969: #define STRgenctor0 0x800000 // need to gen X::X()
970: tym_t ptrtype; // type of pointer to refer to classes by
971: unsigned short access; // current access privilege, here so
972: // enum declarations can get at it
973: targ_size_t Snonvirtsize; // size of struct excluding virtual classes
974: list_t Svirtual; // freeable list of mptrs
975: // that go into vtbl[]
976: #if TX86
977: list_t *Spvirtder; // pointer into Svirtual that points to start
978: // of virtual functions for this (derived) class
979: symlist_t Sopoverload; // overloaded operator funcs (list freeable)
980: #endif
981: symlist_t Scastoverload; // overloaded cast funcs (list freeable)
982: symlist_t Sclassfriends; // list of classes of which this is a friend
983: // (list is freeable)
984: symlist_t Sfriendclass; // classes which are a friend to this class
985: // (list is freeable)
986: symlist_t Sfriendfuncs; // functions which are a friend to this class
987: // (list is freeable)
988: symlist_t Sinlinefuncs; // list of tokenized functions
989: baseclass_t *Sbase; // list of direct base classes
990: baseclass_t *Svirtbase; // list of all virtual base classes
991: baseclass_t *Smptrbase; // list of all base classes that have
992: // their own vtbl[]
993: baseclass_t *Sprimary; // if not NULL, then points to primary
994: // base class
995: Funcsym *Svecctor; // constructor for use by vec_new()
996: Funcsym *Sctor; // constructor function
997:
998: Funcsym *Sdtor; // basic destructor
999: #if VBTABLES
1000: Funcsym *Sprimdtor; // primary destructor
1001: Funcsym *Spriminv; // primary invariant
1002: Funcsym *Sscaldeldtor; // scalar deleting destructor
1003: #endif
1004:
1005: Funcsym *Sinvariant; // basic invariant function
1006:
1007: Symbol *Svptr; // Symbol of vptr
1008: Symbol *Svtbl; // Symbol of vtbl[]
1009: #if VBTABLES
1010: Symbol *Svbptr; // Symbol of pointer to vbtbl[]
1011: Symbol *Svbptr_parent; // base class for which Svbptr is a member.
1012: // NULL if Svbptr is a member of this class
1013: targ_size_t Svbptr_off; // offset of Svbptr member
1014: Symbol *Svbtbl; // virtual base offset table
1015: baseclass_t *Svbptrbase; // list of all base classes in canonical
1016: // order that have their own vbtbl[]
1017: #endif
1018: Funcsym *Sopeq; // X& X::operator =(X&)
1019: Funcsym *Sopeq2; // Sopeq, but no copy of virtual bases
1020: Funcsym *Scpct; // copy constructor
1021: Funcsym *Sveccpct; // vector copy constructor
1022: Symbol *Salias; // pointer to identifier S to use if
1023: // struct was defined as:
1024: // typedef struct { ... } S;
1025:
1026: Symbol *Stempsym; // if this struct is an instantiation
1027: // of a template class, this is the
1028: // template class Symbol
1029:
1030: /* For:
1031: * template<class T> struct A { };
1032: * template<class T> struct A<T *> { };
1033: *
1034: * A<int> a; // primary
1035: * Gives:
1036: * Sarglist = <int>
1037: * Spr_arglist = NULL;
1038: *
1039: * A<int*> a; // specialization
1040: * Gives:
1041: * Sarglist = <int>
1042: * Spr_arglist = <int*>;
1043: */
1044:
1045: param_t *Sarglist; // if this struct is an instantiation
1046: // of a template class, this is the
1047: // actual arg list used
1048: param_t *Spr_arglist; // if this struct is an instantiation
1049: // of a specialized template class, this is the
1050: // actual primary arg list used.
1051: // It is NULL for the
1052: // primary template class (since it would be
1053: // identical to Sarglist).
1054: } struct_t;
1055:
1056: #define struct_calloc() ((struct_t *) mem_fcalloc(sizeof(struct_t)))
1057: #define struct_free(st) ((void)(st))
1058:
1059: /**********************************
1060: * Symbol Table
1061: */
1062:
1063: #define list_symbol(l) ((Symbol *) list_ptr(l))
1064: #define list_setsymbol(l,s) list_ptr(l) = (s)
1065: #define list_Classsym(l) ((Classsym *) list_ptr(l))
1066:
1067: struct Symbol
1068: {
1069: #ifdef DEBUG
1070: unsigned short id;
1071: #define IDsymbol 0x5678
1072: #define symbol_debug(s) assert((s)->id == IDsymbol)
1073: #define class_debug(s) assert((s)->id == IDsymbol)
1074: #else
1075: #define symbol_debug(s)
1076: #define class_debug(s)
1077: #endif
1078:
1079: Symbol *Sl,*Sr; // left, right child
1080: Symbol *Snext; // next in threaded list
1081: dt_t *Sdt; // variables: initializer
1082: type *Stype; // type of Symbol
1083: #define ty() Stype->Tty
1084:
1085: union // variants for different Symbol types
1086: {
1087: enum_t *Senum_; // SCenum
1088: #define Senum _SU.Senum_
1089: struct
1090: { func_t *Sfunc_; // tyfunc
1091: #define Sfunc _SU._SF.Sfunc_
1092: list_t Spath1_; // SCfuncalias member functions: same as Spath
1093: #define Spath1 _SU._SF.Spath1_
1094: // and in same position
1095: // SCadl: list of associated functions for ADL lookup
1096: }_SF;
1097: struct // SClabel
1098: { int Slabel_; // TRUE if label was defined
1099: #define Slabel _SU._SL.Slabel_
1100: block *Slabelblk_; // label block
1101: #define Slabelblk _SU._SL.Slabelblk_
1102: }_SL;
1103: #define Senumlist Senum->SEenumlist
1104:
1105: #if !MARS
1106: struct // SClinkage
1107: {
1108: long Slinkage_; // tym linkage bits
1109: #define Slinkage _SU._SLK.Slinkage_
1110: unsigned Smangle_;
1111: #define Smangle _SU._SLK.Smangle_
1112: }_SLK;
1113: #else
1114: long Slinkage; // SClinkage, tym linkage bits
1115: #endif
1116:
1117: struct
1118: {
1119: char Sbit_; // SCfield: bit position of start of bit field
1120: #define Sbit _SU._SB.Sbit_
1121: char Swidth_; // SCfield: width in bits of bit field
1122: #define Swidth _SU._SB.Swidth_
1123: targ_size_t Smemoff_; // SCmember,SCfield: offset from start of struct
1124: #define Smemoff _SU._SB.Smemoff_
1125: }_SB;
1126:
1127: elem *Svalue_; /* SFLvalue: value of const
1128: SFLdtorexp: for objects with destructor,
1129: conditional expression to precede dtor call
1130: */
1131: #define Svalue _SU.Svalue_
1132:
1133: struct_t *Sstruct_; // SCstruct
1134: #define Sstruct _SU.Sstruct_
1135: template_t *Stemplate_; // SCtemplate
1136: #define Stemplate _SU.Stemplate_
1137: #if SCPP
1138: struct // SCnamespace
1139: { Symbol *Snameroot_; // the Symbol table for the namespace
1140: #define Snameroot _SU._SN.Snameroot_
1141: list_t Susing_; // other namespaces from using-directives
1142: #define Susing _SU._SN.Susing_
1143: }_SN;
1144: struct
1145: { Symbol *Smemalias_; // SCalias: pointer to Symbol to use instead
1146: // (generated by using-declarations and
1147: // namespace-alias-definitions)
1148: // SCmemalias: pointer to member of base class
1149: // to use instead (using-declarations)
1150: #define Smemalias _SU._SA.Smemalias_
1151: symlist_t Spath_; // SCmemalias: path of classes to get to base
1152: // class of which Salias is a member
1153: #define Spath _SU._SA.Spath_
1154: }_SA;
1155: #endif
1156: #if !MARS
1157: Symbol *Simport_; // SCextern: if dllimport Symbol, this is the
1158: #define Simport _SU.Simport_
1159: // Symbol it was imported from
1160: #endif
1161: unsigned char Spreg_; // SCfastpar: register parameter is passed in
1162: #define Spreg _SU.Spreg_
1163: }_SU;
1164:
1165: #if SCPP || MARS
1166: Symbol *Sscope; // enclosing scope (could be struct tag,
1167: // enclosing inline function for statics,
1168: // or namespace)
1169: #define isclassmember(s) ((s)->Sscope && (s)->Sscope->Sclass == SCstruct)
1170: #endif
1171:
1172: #if SCPP
1173: Symbol *Scover; // if there is a tag name and a regular name
1174: // of the same identifier, Scover is the tag
1175: // Scover can be SCstruct, SCenum, SCtemplate
1176: // or an SCalias to them.
1177: #define isscover(s) ((s)->Sclass == SCstruct || (s)->Sclass == SCenum || (s)->Sclass == SCtemplate)
1178: unsigned Ssequence; // sequence number (used for 2 level lookup)
1179: // also used as 'parameter number' for SCTtemparg
1180: #elif MARS
1181: const char *prettyIdent; // the symbol identifer as the user sees it
1182: #elif AUTONEST
1183: unsigned char Spush; // # of pushes followed by # of
1184: unsigned char Spop; // pops of scope level
1185: #endif
1186:
1187: #if ELFOBJ || MACHOBJ
1188: long obj_si; // Symbol index of coff or elf symbol
1189: unsigned long dwarf_off; // offset into .debug section
1190: targ_size_t code_off; // rel. offset from start of block where var is initialized
1191: targ_size_t last_off; // last offset using var
1192: #endif
1193: #if TARGET_OSX
1194: targ_size_t Slocalgotoffset;
1195: #endif
1196:
1197: enum_SC Sclass; // storage class (SCxxxx)
1198: char Sfl; // flavor (FLxxxx)
1199: SYMFLGS Sflags; // flag bits (SFLxxxx)
1200: #define SFLmark 0x08 // temporary marker
1201: #define SFLvalue 0x01 // Svalue contains const expression
1202: #define SFLimplem 0x02 // if seen implementation of Symbol
1203: // (function body for functions,
1204: // initializer for variables)
1205: #define SFLdouble 0x02 // SCregpar or SCparameter, where float
1206: // is really passed as a double
1207: #define SFLfree 0x04 // if we can symbol_free() a Symbol in
1208: // a Symbol table[]
1209: #define SFLexit 0x10 // tyfunc: function does not return
1210: // (ex: exit,abort,_assert,longjmp)
1211: #define SFLtrue 0x200 // value of Symbol != 0
1212: #define SFLreplace SFLmark // variable gets replaced in inline expansion
1213: #define SFLskipinit 0x10000 // SCfield, SCmember: initializer is skipped
1214: #define SFLnodebug 0x20000 // don't generate debug info
1215: #define SFLwasstatic 0x800000 // was an uninitialized static
1216: #define SFLweak 0x1000000 // resolve to NULL if not found
1217:
1218: // CPP
1219: #define SFLnodtor 0x10 // set if destructor for Symbol is already called
1220: #define SFLdtorexp 0x80 // Svalue has expression to tack onto dtor
1221: #define SFLmutable 0x100000 // SCmember or SCfield is mutable
1222: #define SFLdyninit 0x200000 // symbol has dynamic initializer
1223: #define SFLtmp 0x400000 // symbol is a generated temporary
1224: #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
1225: #define SFLthunk 0x40000 // symbol is temporary for thunk
1226: #endif
1227:
1228: // Possible values for protection bits
1229: #define SFLprivate 0x60
1230: #define SFLprotected 0x40
1231: #define SFLpublic 0x20
1232: #define SFLnone 0x00
1233: #define SFLpmask 0x60 // mask for the protection bits
1234: #if VEC_VTBL_LIST
1235: #define SFLvtbl 0x2000 // Symbol is a vtable or vbtable
1236: #endif
1237:
1238: // OPTIMIZER and CODGEN
1239: #define GTregcand 0x100 // if Symbol is a register candidate
1240: #define SFLdead 0x800 // this variable is dead
1241: #define GTunregister 0x2000000 // 'unregister' a previous register assignment
1242:
1243: // OPTIMIZER only
1244: #define SFLunambig 0x400 // only accessible by unambiguous reference,
1245: // i.e. cannot be addressed via pointer
1246: // (GTregcand is a subset of this)
1247: // P.S. code generator turns off this
1248: // flag if any reads are done from it.
1249: // This is to eliminate stores to it
1250: // that are never read.
1251: #define SFLlivexit 0x1000 // live on exit from function
1252: #define SFLnotbasiciv 0x4000 // not a basic induction variable
1253: #define SFLnord SFLdouble // SCauto,SCregister,SCtmp: disallow redundant warnings
1254:
1255: // CODGEN only
1256: #define GTtried SFLmark // tried to place in register
1257: #define GTbyte 0x8000 // variable is sometimes accessed as
1258: #define SFLread 0x40000 // variable is actually read from
1259: // (to eliminate dead stores)
1260: #define SFLspill 0x80000 // only in register part of the time
1261:
1262: vec_t Srange; // live range, if any
1263: vec_t Slvreg; // when symbol is in register
1264: targ_size_t Ssize; // tyfunc: size of function
1265: targ_size_t Soffset; // variables: offset of Symbol in its storage class
1266:
1267: // CPP || OPTIMIZER
1268: SYMIDX Ssymnum; // Symbol number (index into globsym.tab[])
1269: // SCauto,SCparameter,SCtmp,SCregpar,SCregister
1270: // CODGEN
1271: int Sseg; // segment index
1272: int Sweight; // usage count, the higher the number,
1273: // the more worthwhile it is to put in
1274: // a register
1275: union
1276: {
1277: unsigned Sxtrnnum_; // SCcomdef,SCextern,SCcomdat: external symbol # (starting from 1)
1278: #define Sxtrnnum _SXR.Sxtrnnum_
1279: unsigned long Stypidx_; // SCstruct,SCunion,SCclass,SCenum,SCtypedef: debug info type index
1280: #define Stypidx _SXR.Stypidx_
1281: struct
1282: { unsigned char Sreglsw_;
1283: #define Sreglsw _SXR._SR.Sreglsw_
1284: unsigned char Sregmsw_;
1285: #define Sregmsw _SXR._SR.Sregmsw_
1286: regm_t Sregm_; // mask of registers
1287: #define Sregm _SXR._SR.Sregm_
1288: }_SR; // SCregister,SCregpar,SCpseudo: register number
1289: }_SXR;
1290: regm_t Sregsaved; // mask of registers not affected by this func
1291:
1292: #if SOURCE_4SYMS
1293: Srcpos Ssrcpos; // file position for definition
1294: #endif
1295:
1296: char Sident[SYM_PREDEF_SZ]; // identifier string (dynamic array)
1297: // (the size is for static Symbols)
1298:
1299: int needThis(); // !=0 if symbol needs a 'this' pointer
1300: };
1301: #pragma SC align
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
1302:
1303: // Class, struct or union
1304:
1305: struct Classsym : Symbol { };
1306:
1307: // Namespace Symbol
1308: struct Nspacesym : Symbol { };
1309:
1310: // Alias for another Symbol
1311: struct Aliassym : Symbol { };
1312:
1313: // Function symbol
1314: //struct Funcsym : Symbol { };
1315:
1316: // Determine if this Symbol is stored in a COMDAT
1317: #if MARS
1318: #define symbol_iscomdat(s) ((s)->Sclass == SCcomdat || \
1319: config.flags2 & CFG2comdat && (s)->Sclass == SCinline || \
1320: config.flags4 & CFG4allcomdat && ((s)->Sclass == SCglobal))
1321: #else
1322: #define symbol_iscomdat(s) ((s)->Sclass == SCcomdat || \
1323: config.flags2 & CFG2comdat && (s)->Sclass == SCinline || \
1324: config.flags4 & CFG4allcomdat && ((s)->Sclass == SCglobal || (s)->Sclass == SCstatic))
1325: #endif
1326:
1327: /* Format the identifier for presentation to the user */
1328: char *cpp_prettyident (Symbol *s);
1329:
1330: #if defined(CPP) && !CPP
1331: inline char *prettyident(Symbol *s) { return s->Sident; }
1332: #else
1333: inline char *prettyident(Symbol *s) { return CPP ? cpp_prettyident(s) : s->Sident; }
1334: #endif
1335:
1336: /**********************************
1337: * Function parameters:
1338: * Pident identifier of parameter
1339: * Ptype type of argument
1340: * Pelem default value for argument
1341: * Psym symbol corresponding to Pident when using the
1342: * parameter list as a symbol table
1343: * For template-parameter-list:
1344: * Pident identifier of parameter
1345: * Ptype if NULL, this is a type-parameter
1346: * else the type for a parameter-declaration value argument
1347: * Pelem default value for value argument
1348: * Pdeftype default value for type-parameter
1349: * Pptpl template-parameter-list for template-template-parameter
1350: * Psym default value for template-template-parameter
1351: * For template-arg-list: (actual arguments)
1352: * Pident NULL
1353: * Ptype type-name
1354: * Pelem expression (either Ptype or Pelem is NULL)
1355: * Psym SCtemplate for template-template-argument
1356: */
1357:
1358: struct PARAM
1359: {
1360: #ifdef DEBUG
1361: unsigned short id;
1362: #define IDparam 0x7050
1363: #define param_debug(s) assert((s)->id == IDparam)
1364: #else
1365: #define param_debug(s)
1366: #endif
1367:
1368: char *Pident; // identifier
1369: type *Ptype; // type of parameter (NULL if not known yet)
1370: elem *Pelem; // default value
1371: token_t *PelemToken; // tokens making up default elem
1372: type *Pdeftype; // Ptype==NULL: default type for type-argument
1373: param_t *Pptpl; // template-parameter-list for template-template-parameter
1374: Symbol *Psym;
1375: PARAM *Pnext; // next in list
1376: unsigned Pflags;
1377: #define PFexplicit 1 // this template argument was explicit, i.e. in < >
1378: #if SOURCE_4PARAMS
1379: Srcpos Psrcpos; // parameter source definition
1380: #endif
1381:
1382: PARAM *createTal(PARAM *); // create template-argument-list blank from
1383: // template-parameter-list
1384: PARAM *search(char *id); // look for Pident matching id
1385: int searchn(char *id); // look for Pident matching id, return index
1386: unsigned length(); // number of parameters in list
1387: void print(); // print this param_t
1388: void print_list(); // print this list of param_t's
1389: };
1390:
1391: /**************************************
1392: * Element types.
1393: * These should be combined with storage classes.
1394: */
1395:
1396: enum FL
1397: {
1398: FLunde,
1399: FLconst, // numerical constant
1400: FLoper, // operator node
1401: FLfunc, // function symbol
1402: FLdata, // ref to data segment variable
1403: FLreg, // ref to register variable
1404: FLpseudo, // pseuodo register variable
1405: FLauto, // ref to automatic variable
1406: FLpara, // ref to function parameter variable
1407: FLextern, // ref to external variable
1408: FLtmp, // ref to a stack temporary, int contains temp number
1409: FLcode, // offset to code
1410: FLblock, // offset to block
1411: FLudata, // ref to udata segment variable
1412: FLcs, // ref to common subexpression number
1413: FLswitch, // ref to offset of switch data block
1414: FLfltreg, // ref to floating reg on stack, int contains offset
1415: FLoffset, // offset (a variation on constant, needed so we
1416: // can add offsets (different meaning for FLconst))
1417: FLdatseg, // ref to data segment offset
1418: FLctor, // constructed object
1419: FLdtor, // destructed object
1420: FLregsave, // ref to saved register on stack, int contains offset
1421: FLasm, // (code) an ASM code
1422: #if TX86
1423: FLndp, // saved 8087 register
1424: FLfardata, // ref to far data segment
1425: FLlocalsize, // replaced with # of locals in the stack frame
1426: FLcsdata, // ref to code segment variable
1427: FLtlsdata, // thread local storage
1428: FLbprel, // ref to variable at fixed offset from frame pointer
1429: FLframehandler, // ref to C++ frame handler for NT EH
1430: FLblockoff, // address of block
1431: FLallocatmp, // temp for built-in alloca()
1432: FLstack, // offset from ESP rather than EBP
1433: FLdsymbol, // it's a Dsymbol
1434: #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
1435: // Change this, update debug.c too
1436: FLgot, // global offset table entry outside this object file
1437: FLgotoff, // global offset table entry inside this object file
1438: //FLoncedata, // link once data
1439: //FLoncecode, // link once code
1440: #endif
1441: #endif
1442: FLMAX
1443: };
1444:
1445: ////////// Srcfiles
1446:
1447: #if !MARS
1448: // Collect information about a source file.
1449: typedef struct Sfile
1450: {
1451: #ifdef DEBUG
1452: unsigned short id;
1453: #define IDsfile (('f' << 8) | 's')
1454: #define sfile_debug(sf) assert((sf)->id == IDsfile)
1455: #else
1456: #define sfile_debug(sf)
1457: #endif
1458:
1459: char *SFname; // name of file
1460: unsigned SFflags;
1461: #define SFonce 0x01 // file is to be #include'd only once
1462: #define SFhx 0x02 // file is in an HX file and has not been loaded
1463: #define SFtop 0x04 // file is a top level source file
1464: #define SFloaded 0x08 // read from PH file
1465: list_t SFfillist; // file pointers of Sfile's that this Sfile is
1466: // dependent on (i.e. they were #include'd).
1467: // Does not include nested #include's
1468: macro_t *SFmacdefs; // threaded list of macros #defined by this file
1469: macro_t **SFpmacdefs; // end of macdefs list
1470: Symbol *SFsymdefs; // threaded list of global symbols declared by this file
1471: symlist_t SFcomdefs; // comdefs defined in PH
1472: symlist_t SFtemp_ft; // template_ftlist
1473: symlist_t SFtemp_class; // template_class_list
1474: Symbol *SFtagsymdefs; // list of tag names (C only)
1475: unsigned SFhashval; // hash of file name
1476: } Sfile;
1477:
1478: // Source files are referred to by a pointer into pfiles[]. This is so that
1479: // when PH files are hydrated, only pfiles[] needs updating. Of course, this
1480: // means that pfiles[] cannot be reallocated to larger numbers, its size is
1481: // fixed at SRCFILES_MAX.
1482:
1483: typedef struct Srcfiles
1484: {
1485: // Sfile *arr; // array of Sfiles
1486: Sfile **pfiles; // parallel array of pointers into arr[]
1487: #define SRCFILES_MAX (2*512)
1488: unsigned dim; // dimension of array
1489: unsigned idx; // # used in array
1490: } Srcfiles;
1491:
1492: #define sfile(fi) (*srcfiles.pfiles[fi])
1493: #define srcfiles_name(fi) (sfile(fi).SFname)
1494: #endif
1495:
1496: /**************************************************
1497: * This is to support compiling expressions within the context of a function.
1498: */
1499:
1500: struct EEcontext
1501: {
1502: unsigned EElinnum; // line number to insert expression
1503: char *EEexpr; // expression
1504: char *EEtypedef; // typedef identifier
1505: char EEpending; // !=0 means we haven't compiled it yet
1506: char EEimminent; // we've installed it in the source text
1507: char EEcompile; // we're compiling for the EE expression
1508: char EEin; // we are parsing an EE expression
1509: elem *EEelem; // compiled version of EEexpr
1510: Symbol *EEfunc; // function expression is in
1511: code *EEcode; // generated code
1512: };
1513:
1514: extern EEcontext eecontext;
1515:
1516: #include "rtlsym.h"
1517:
1518: #undef SYMBOL_Z
1519: #define SYMBOL_Z(e,fl,saved,n,flags,ty) RTLSYM_##e,
1520:
1521: enum
1522: {
1523: RTLSYMS
1524:
1525: RTLSYM_MAX
1526: };
1527:
1528: extern Symbol *rtlsym[RTLSYM_MAX];
1529:
1530: // Different goals for el_optimize()
1531: #define GOALnone 0 // evaluate for side effects only
1532: #define GOALvalue 1 // evaluate for value
1533: #define GOALflags 2 // evaluate for flags
1534: #define GOALagain 4
1535: #define GOALstruct 8
1536: #define GOALhandle 0x10 // don't replace handle'd objects
1537:
1538: /* Globals returned by declar() */
1539: struct Declar
1540: {
1541: Classsym *class_sym;
1542: Nspacesym *namespace_sym;
1543: int oper;
1544: bool constructor;
1545: bool destructor;
1546: bool invariant;
1547: param_t *ptal;
1548: bool explicitSpecialization;
1549: int hasExcSpec; // has exception specification
1550: };
1551:
1552: extern Declar gdeclar;
1553:
1554: #endif
1555: