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);
	}
}
+/