Mercurial > projects > ddmd
view dmd/backend/Symbol.d @ 0:10317f0c89a5
Initial commit
author | korDen |
---|---|
date | Sat, 24 Oct 2009 08:42:06 +0400 |
parents | |
children | fd4acc376c45 |
line wrap: on
line source
module dmd.backend.Symbol; import dmd.backend.dt_t; import dmd.backend.TYPE; import dmd.backend.LIST; import dmd.backend.block; import dmd.backend.func_t; import dmd.backend.enum_t; import dmd.backend.elem; import dmd.backend.struct_t; import dmd.backend.template_t; import dmd.backend.targ_types; import dmd.backend.vec_t; import dmd.backend.SYMIDX; import dmd.backend.regm_t; import dmd.backend.Util; struct Symbol { ushort id; Symbol* Sl; Symbol* Sr; // left, right child Symbol *Snext; // next in threaded list dt_t* Sdt; // variables: initializer type* Stype; // type of Symbol tym_t ty() { return Stype.Tty; } union // variants for different Symbol types { enum_t* Senum; // SCenum struct { func_t* Sfunc; // tyfunc list_t Spath1; // SCfuncalias member functions: same as Spath // and in same position // SCadl: list of associated functions for ADL lookup } struct // SClabel { int Slabel; // TRUE if label was defined block* Slabelblk; // label block } /// #define Senumlist Senum->SEenumlist struct // SClinkage { int Slinkage; // tym linkage bits uint Smangle; } struct { char Sbit; // SCfield: bit position of start of bit field char Swidth; // SCfield: width in bits of bit field targ_size_t Smemoff; // SCmember,SCfield: offset from start of struct } elem* Svalue; /* SFLvalue: value of const SFLdtorexp: for objects with destructor, conditional expression to precede dtor call */ struct_t* Sstruct; // SCstruct template_t* Stemplate; // SCtemplate Symbol* Simport; // SCextern: if dllimport Symbol, this is the // Symbol it was imported from ubyte Spreg; // SCfastpar: register parameter is passed in } Symbol* Sscope; // enclosing scope (could be struct tag, // enclosing inline function for statics, // or namespace) ///#define isclassmember(s) ((s)->Sscope && (s)->Sscope->Sclass == SCstruct) const(char)* prettyIdent; // the symbol identifer as the user sees it enum_SC Sclass; // storage class (SCxxxx) char Sfl; // flavor (FLxxxx) SYMFLGS Sflags; // flag bits (SFLxxxx) vec_t Srange; // live range, if any vec_t Slvreg; // when symbol is in register targ_size_t Ssize; // tyfunc: size of function targ_size_t Soffset; // variables: offset of Symbol in its storage class SYMIDX Ssymnum; // Symbol number (index into globsym.tab[]) // SCauto,SCparameter,SCtmp,SCregpar,SCregister short Sseg; // segment index int Sweight; // usage count, the higher the number, // the more worthwhile it is to put in // a register union { uint Sxtrnnum; // SCcomdef,SCextern,SCcomdat: external symbol # (starting from 1) uint Stypidx; // SCstruct,SCunion,SCclass,SCenum,SCtypedef: debug info type index struct { ubyte Sreglsw; ubyte Sregmsw; regm_t Sregm; // mask of registers } } regm_t Sregsaved; // mask of registers not affected by this func char Sident[35]; // identifier string (dynamic array) // (the size is for static Symbols) bool needThis() // true if symbol needs a 'this' pointer { assert(false); } } void dumpSymbol(Symbol* foo) { foreach (a, b; foo.tupleof) { static if (typeof(foo.tupleof[a]).stringof != "char[35u]") { std.stdio.writeln(foo.tupleof[a].stringof, " ", cast(char*)&foo.tupleof[a] - cast(char*)foo, " = ", cast(int)foo.tupleof[a]); //std.stdio.writeln("printf(\"", foo.tupleof[a].stringof, " %d = %d\\n\",(char*)(&", foo.tupleof[a].stringof, ")-(char*)foo, ", foo.tupleof[a].stringof, ");"); } } std.stdio.writefln("(*foo).Sclass %d = %d", (cast(char*)&foo.Sclass - cast(char*)foo), cast(int)foo.Sclass); //std.stdio.writeln("printf(\"(*foo).Sclass %d %d\\n\", ((char*)&foo->Sclass - (char*)foo), (int)foo->Sclass);"); } /+ struct Symbol { debug { ushort id; ///#define IDsymbol 0x5678 ///#define symbol_debug(s) assert((s)->id == IDsymbol) ///#define class_debug(s) assert((s)->id == IDsymbol) } else { ///#define symbol_debug(s) ///#define class_debug(s) } Symbol* Sl; Symbol* Sr; // left, right child version (TX86) { Symbol *Snext; // next in threaded list } dt_t* Sdt; // variables: initializer type* Stype; // type of Symbol auto ty() { assert(false); //return Stype.Tty; } auto Senumlist() { return Senum.SEenumlist; } union // variants for different Symbol types { enum_t* Senum; // SCenum struct { func_t* Sfunc; // tyfunc list_t Spath1; // SCfuncalias member functions: same as Spath // and in same position // SCadl: list of associated functions for ADL lookup } struct // SClabel { int Slabel; // TRUE if label was defined block* Slabelblk_; // label block } version (TX86) { struct // SClinkage { long Slinkage; // tym linkage bits uint Smangle; } } else { long Slinkage; // SClinkage, tym linkage bits } struct { char Sbit; // SCfield: bit position of start of bit field char Swidth; // SCfield: width in bits of bit field version (TX86) { targ_size_t Smemoff; // SCmember,SCfield: offset from start of struct } } elem* Svalue; /* SFLvalue: value of const SFLdtorexp: for objects with destructor, conditional expression to precede dtor call */ struct_t* Sstruct; // SCstruct template_t* Stemplate; // SCtemplate version (SCPP) { struct // SCnamespace { Symbol* Snameroot; // the Symbol table for the namespace list_t Susing; // other namespaces from using-directives } struct { Symbol* Smemalias; // SCalias: pointer to Symbol to use instead // (generated by using-declarations and // namespace-alias-definitions) // SCmemalias: pointer to member of base class // to use instead (using-declarations) symlist_t Spath; // SCmemalias: path of classes to get to base // class of which Salias is a member } } version (TX86) { Symbol* Simport; // SCextern: if dllimport Symbol, this is the // Symbol it was imported from } ubyte Spreg; // SCfastpar: register parameter is passed in } version (SCPP_OR_MARS) { Symbol* Sscope; // enclosing scope (could be struct tag, // enclosing inline function for statics, // or namespace) //#define isclassmember(s) ((s)->Sscope && (s)->Sscope->Sclass == SCstruct) } version (SCPP) { Symbol* Scover; // if there is a tag name and a regular name // of the same identifier, Scover is the tag // Scover can be SCstruct, SCenum, SCtemplate // or an SCalias to them. //#define isscover(s) ((s)->Sclass == SCstruct || (s)->Sclass == SCenum || (s)->Sclass == SCtemplate) uint Ssequence; // sequence number (used for 2 level lookup) // also used as 'parameter number' for SCTtemparg } else version (MARS) { const(char)* prettyIdent; // the symbol identifer as the user sees it } else version (AUTONEST) { ubyte Spush; // # of pushes followed by # of ubyte Spop; // pops of scope level } version (ELFOBJ_OR_MACHOBJ) { int obj_si; // Symbol index of coff or elf symbol uint dwarf_off; // offset into .debug section targ_size_t code_off; // rel. offset from start of block where var is initialized targ_size_t last_off; // last offset using var } version (TARGET_OSX) { targ_size_t Slocalgotoffset; } SC Sclass; // storage class (SCxxxx) char Sfl; // flavor (FLxxxx) SYMFLGS Sflags; // flag bits (SFLxxxx) /// #define SFLmark 0x08 // temporary marker /// #define SFLvalue 0x01 // Svalue contains const expression /// #define SFLimplem 0x02 // if seen implementation of Symbol // (function body for functions, // initializer for variables) /// #define SFLdouble 0x02 // SCregpar or SCparameter, where float // is really passed as a double /// #define SFLfree 0x04 // if we can symbol_free() a Symbol in // a Symbol table[] /// #define SFLexit 0x10 // tyfunc: function does not return // (ex: exit,abort,_assert,longjmp) /// #define SFLtrue 0x200 // value of Symbol != 0 /// #define SFLreplace SFLmark // variable gets replaced in inline expansion /// #define SFLskipinit 0x10000 // SCfield, SCmember: initializer is skipped /// #define SFLnodebug 0x20000 // don't generate debug info /// #define SFLwasstatic 0x800000 // was an uninitialized static /// #define SFLweak 0x1000000 // resolve to NULL if not found // CPP /// #define SFLnodtor 0x10 // set if destructor for Symbol is already called /// #define SFLdtorexp 0x80 // Svalue has expression to tack onto dtor /// #define SFLmutable 0x100000 // SCmember or SCfield is mutable /// #define SFLdyninit 0x200000 // symbol has dynamic initializer /// #define SFLtmp 0x400000 // symbol is a generated temporary version (XXX) { ///TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS ///#define SFLthunk 0x40000 // symbol is temporary for thunk } // Possible values for protection bits /// #define SFLprivate 0x60 /// #define SFLprotected 0x40 /// #define SFLpublic 0x20 /// #define SFLnone 0x00 /// #define SFLpmask 0x60 // mask for the protection bits version (VEC_VTBL_LIST) { /// #define SFLvtbl 0x2000 // Symbol is a vtable or vbtable } // OPTIMIZER and CODGEN /// #define GTregcand 0x100 // if Symbol is a register candidate /// #define SFLdead 0x800 // this variable is dead // OPTIMIZER only /// #define SFLunambig 0x400 // only accessible by unambiguous reference, // i.e. cannot be addressed via pointer // (GTregcand is a subset of this) // P.S. code generator turns off this // flag if any reads are done from it. // This is to eliminate stores to it // that are never read. /// #define SFLlivexit 0x1000 // live on exit from function /// #define SFLnotbasiciv 0x4000 // not a basic induction variable /// #define SFLnord SFLdouble // SCauto,SCregister,SCtmp: disallow redundant warnings // CODGEN only /// #define GTtried SFLmark // tried to place in register /// #define GTbyte 0x8000 // variable is sometimes accessed as /// #define SFLread 0x40000 // variable is actually read from // (to eliminate dead stores) /// #define SFLspill 0x80000 // only in register part of the time vec_t Srange; // live range, if any vec_t Slvreg; // when symbol is in register targ_size_t Ssize; // tyfunc: size of function targ_size_t Soffset; // variables: offset of Symbol in its storage class version (TARGET_MAC) { ///#define Smemoff Soffset } // CPP || OPTIMIZER SYMIDX Ssymnum; // Symbol number (index into globsym.tab[]) // SCauto,SCparameter,SCtmp,SCregpar,SCregister // CODGEN version (TX86) { short Sseg; // segment index } int Sweight; // usage count, the higher the number, // the more worthwhile it is to put in // a register union { uint Sxtrnnum; // SCcomdef,SCextern,SCcomdat: external symbol # (starting from 1) uint Stypidx; // SCstruct,SCunion,SCclass,SCenum,SCtypedef: debug info type index struct { ubyte Sreglsw; ubyte Sregmsw; regm_t Sregm; // mask of registers } // SCregister,SCregpar,SCpseudo: register number } version (TX86) { regm_t Sregsaved; // mask of registers not affected by this func } version (SOURCE_4SYMS) { Srcpos Ssrcpos; // file position for definition } // Target Additions /// TARGET_structSYMBOL version (TX86) { char Sident[SYM_PREDEF_SZ]; // identifier string (dynamic array) // (the size is for static Symbols) } else { long[0] Sident; // identifier string (dynamic array) as a str4 } bool needThis() // true if symbol needs a 'this' pointer { assert(false); } } +/