Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_FS_1_19910112
-
kcc-6/kcc/ccsym.h
There are 8 other files named ccsym.h in the archive. Click here to see a list.
/* CCSYM.H - Declarations for KCC type and symbol table structures
**
** (c) Copyright Ken Harrenstien 1989
** All changes after v.126, 24-Sep-1987
** (c) Copyright Ken Harrenstien, SRI International 1985, 1986
** All changes after v.8, 8-Aug-1985
**
** Original version split from cc.h / David Eppstein / 23 May 85
*/
#ifndef EXT
#define EXT extern
#endif
/* Must define these together here since they need each other */
#define SYMBOL struct symbol
#define TYPE struct type
/* Constant - # words in a symbol identifier */
#define IDENTWDS ((IDENTSIZE+sizeof(int)-1)/sizeof(int))
/* SYMBOL - Symbol table entry
** All symbols have a name (Sname) and a "symbol class" (Sclass) which
** determines the meaning of the rest of the structure.
*/
SYMBOL {
struct {
int s_class; /* Symbol class - a SC_ value */
int s_flags; /* Symbol flags (SF_) */
union {
char s_ch[IDENTSIZE]; /* Symbol identifier string */
int s_int[IDENTWDS];
} Sid; /* Copyable contents */
union { /* Use depends on Sclass */
int s_int; /* symbol value, misc uses */
SYMBOL *s_sym; /* symbol for label,static */
struct { /* Handy values for macro defs (SC_MACRO) */
signed char svm_npar; /* # params (< 0 for special macs) */
unsigned char svm_parl; /* # chars of param names in body */
unsigned short svm_len; /* # total chars in body string */
} sv_mac;
} s_val;
union { /* Use depends on Sclass */
TYPE *s_type; /* C type pointer */
int s_rwkey; /* reserved word key */
char *s_macptr; /* macro pointer */
} s_var;
} Scontents; /* Copyable contents (for struct assigns) */
/* Primarily used for SC_TAG/SC_UTAG and SC_MEMBER/SC_ENUM;
** also used for linking SC_ARG/SC_RARG parameter lists.
*/
SYMBOL *Ssmnext; /* next structure member */
union {
SYMBOL *s_sym; /* tag of structure that member belongs to */
TYPE *s_typ; /* Hidden prototype list */
} s_tag;
SYMBOL *Sprev; /* ptr to prev symbol on glob/local list */
SYMBOL *Snext; /* ptr to next symbol on ditto */
int Srefs; /* # times referenced since created */
SYMBOL *Snhash; /* ptr to next sym on this hash chain */
};
/* Defs providing external access to structure fields, depending on
* the kind of symbol. No "s_" member should ever be referenced directly.
*/
/* Every symbol class uses these fields */
#define Sclass Scontents.s_class /* Symbol class */
#define Sflags Scontents.s_flags /* Symbol flags */
#define Sname Scontents.Sid.s_ch /* Symbol name string */
#define Sidwds Scontents.Sid.s_int /* name in wds for speed */
/* Many (but not all) symbol classes use these fields */
#define Stype Scontents.s_var.s_type /* C type of symbol */
#define Svalue Scontents.s_val.s_int /* Misc uses */
/* Sclass == SC_UNDEF
** When the lexer returns an identifier, it also points "csymbol"
** to an entry in the symtab. If the symbol did not already exist, it is
** created with class SC_UNDEF.
** Only Sname and Sclass will be set.
** Stype will be NULL and Svalue zero.
** Normally the parser changes this quickly to something else, or gets
** rid of the symbol. The only known usages which keep SC_UNDEF symbols
** around are:
** - A pair of dummy symbols at the start of the global & local sym lists.
** - References to structures/unions that have not yet been defined.
** Stype should indicate either TS_STRUCT or TS_UNION.
*/
/* Sclass == SC_RW (reserved word)
** Stoken holds the token code to return when the lexer finds this word.
** Skey contains a reserved-word token type key, one of the TKTY_ values.
*/
#define Stoken Scontents.s_val.s_int
#define Skey Scontents.s_var.s_rwkey
/* Sclass == SC_MACRO (preprocessor macro definition)
** Smacptr points to the macro body (a dynamically allocated string).
** This may be NULL for special types of macros.
** Smacnpar says how many arguments it takes, or (if < 0) indicates
** a special built-in macro. See CCPP for details.
** Smacparlen is the # chars of param-names at start of body, if any.
** Smaclen is the total # chars in the macro body string.
** Smacparlen and Smaclen are 0 if Smacptr is NULL.
*/
#define Smacptr Scontents.s_var.s_macptr
#define Smacnpar Scontents.s_val.sv_mac.svm_npar
#define Smacparlen Scontents.s_val.sv_mac.svm_parl
#define Smaclen Scontents.s_val.sv_mac.svm_len
/* Sclass == SC_TAG, SC_UTAG - Structure, union, or enum tag
** Sclass == SC_MEMBER - Structure or union member (component)
** Sclass == SC_ENUM - Enum list member
** See the discussion of structure tags and members farther on
** for a thorough explanation.
*/
#define Ssmoff Svalue /* Offset of member in struct/union */
#define Ssmtag s_tag.s_sym /* Tag of entity that member belongs to */
/* Sclass == SC_TYPEDEF
** This symbol is a "typedef name" and is lexically considered a
** type-specifier keyword.
** Stype points to the C type which this symbol represents.
*/
/* Sclass == SC_EXTDEF, SC_EXTREF, SC_XEXTREF, SC_EXLINK
** All of these classes refer to objects or functions with external
** linkage.
** SC_EXTDEF - the obj or fun has been defined (file-scope only)
** SC_EXTREF - the obj or fun has been declared (file or block scope).
** SC_XEXTREF - same, but declaration has gone out of scope.
** SC_EXLINK - this file-scope object (never function) has been
** declared with a "tentative definition". If no definition
** has been seen by end of the file, a zero initializer def is
** generated for it.
**
** Stype specifies the symbol's C type.
** Smaplab specifies the actual label to use for this object/function
** when emitting code. Currently this is a SIXBIT value.
** Shproto (SC_EXTDEF functions only) points to a hidden funct prototype.
**
** When parsing top-level declarations, SC_EXLINK is the default storage class
** when no explicit storage class is specified, as opposed to SC_EXTREF
** which indicates that "extern" was seen. This allows KCC
** to distinguish between "extern" that is assumed, and "extern" that
** is stated. See H&S 4.3.1 and 4.8.
** In the assembler output file, SC_EXTDEF causes the generation
** of an INTERN, and SC_(X)EXTREF an EXTERN. (SC_EXLINK should never be
** seen by that point).
**
** If the function was defined with an old-style declaration and no
** prototype already existed, then "Shproto" will be set to point to a
** "hidden" prototype constructed from the parameter declarations for the
** function. This is used for comparison if a later prototype declaration
** for the function is seen, and for optional validity checking on calls.
*/
#define Smaplab Svalue /* Mapped label name for assembler output */
#define Shproto s_tag.s_typ /* "Hidden" prototype for old-style fn def */
/* Sclass == SC_INTDEF, SC_INTREF, SC_INLINK
** All of these classes refer to file-scope objects or functions
** with internal linkage.
** SC_INTDEF - the obj or fun has been defined (file-scope "static").
** SC_INTREF - the funct (never obj) has been declared (file-scope "static").
** SC_INLINK - the object (never funct) is a tentative definition, just
** as for SC_EXLINK.
**
** The object (var or fun) has static extent and the symbol is not
** exported to the linker. This can only happen if "static" is explicitly
** stated, and only at top-level (file scope).
** Stype specifies the symbol's C type.
** Smaplab is used for object/function labels just as for SC_EX*.
** Shproto is used for functions just as for SC_EXTDEF.
*/
/* Sclass == SC_ISTATIC
** This class is used for objects (never functions) that have
** static extent, block scope and no linkage.
** Stype specifies the symbol's C type.
** Smaplab someday will be used as for SC_IN* and SC_EX*.
** Ssym points to a uniquely generated internal label symbol.
*/
#define Ssym Scontents.s_val.s_sym
/* Sclass == SC_ARG, SC_RARG - Function parameters
** Stype specifies the parameter's C type.
** Spmnext is a symbol pointer to the next parameter (or null if last one)
** Svalue contains stack offset, similar to SC_AUTO except that it is
** a positive number (if all args are 1 word, this is same as
** argument number) and thus needs to be inverted for an actual
** stack reference.
** The use of Spmnext overlays that of Ssmnext, but there is no conflict
** since tag and member idents can never be parameters.
** Note that Spmhead is not used in the symbol table, only in the temporary
** syms that CCDECL uses to parse declarators, and only for function type
** declarators in order to properly manage the scope of prototypes.
*/
#define Spmnext Ssmnext /* Pointer to next parameter */
#define Spmhead Ssmtag /* Saved start of local sym block for params */
/* Sclass == SC_REGISTER
** This isn't really used anywhere. For the time being,
** the classes SC_RAUTO and SC_RARG remember whether the "register" keyword
** was specified with auto vars or function parameters. This could be used
** to help the optimizer.
** Someday this may be changed to use a SF_REGISTER flag and flush
** the use of SC_RARG and SC_RAUTO as distinct classes.
*/
/* Sclass == SC_AUTO, SC_RAUTO, SC_XAUTO, SC_XRAUTO
** SC_AUTO describes an "auto" variable, within a block. This is the
** default storage class when parsing declarations within a block.
** SC_RAUTO is the same but indicates that the "register" storage class
** was given in the declaration.
** SC_XAUTO and SC_XRAUTO are what SC_AUTO and SC_RAUTO are turned
** into when parsing has left the block within which the variable
** was declared. That is, the declaration is no longer active.
**
** Stype specifies the symbol's C type.
** Svalue holds the stack offset value, in words.
*/
/* Sclass == SC_LABEL, SC_ULABEL (goto labels)
**
** Ssym is used just as for SC_ISTATIC; it points to a label symbol
** generated for use by goto statements.
*/
#define Ssym Scontents.s_val.s_sym
/* OVERLOADING CLASSES or NAME SPACES
**
** Certain types of symbols have a prefix character in their names
** as a hack to provide for "overloading classes" or "name spaces"
** [Ref H&S 4.2.4] [dpANS 3.1.2.3]
** These prefixes (none of which are legal as part of an input
** identifier) are:
** + - Structure member symbols ("component names")
** ^ - Structure/enum tag symbols ("struct, union, and enum tags")
** @ - Goto label symbols ("statement labels")
** The other two name classes ("preprocessor macro names" and "other names")
** do not need a prefix, because the former are handled during preprocessing
** prior to compilation, and the latter are normal. For reference, here
** is a list of the overloading classes as defined in H&S, with a code:
** OC= Overloading Class
** M Preprocessor macro names
** L Statement labels
** T Struct/union/enum tags
** * Structure component names (unique class for each structure)
** - Normal
*/
#define SPC_SMEM ('+') /* * Structure/union members */
#define SPC_TAG ('^') /* T Structure/union/enum tags */
#define SPC_LABEL ('@') /* L Statement labels */
#define SPC_MACDEF ('?') /* Special for hiding the "defined" macro */
#define SPC_IDQUOT ('`') /* Special for hiding quoted idents */
#define SPC_IAUTO ('<') /* Special for hiding internal auto vars */
/* Symbol Classes (some relationship to "storage classes") */
/* OC-----> Overloading Class */
/* vf --> v=var object, f=function */
enum symbolspec {
SC_UNDEF, /* Undefined - should be zero */
SC_MACRO, /* - Macro name */
SC_RW, /* - Reserved Word */
SC_TYPEDEF, /* - Typedef name */
SC_TAG, /* T Struct/union/enum tag */
SC_UTAG, /* T Undefined struct/union/enum tag */
SC_MEMBER, /* * v Struct/union member */
SC_ENUM, /* - v Enumeration constant "member" */
/* Extent Linkage Scope Def/Ref */
SC_XEXTREF, /* - vf static extern - reference */
SC_EXTREF, /* - vf static extern file reference */
SC_INTREF, /* - vf static intern file reference */
SC_EXTDEF, /* - vf static extern file definition */
SC_INTDEF, /* - vf static intern file definition */
SC_EXLINK, /* - v static extern file tentative def */
SC_INLINK, /* - v static intern file tentative def */
SC_ISTATIC, /* - v static - block definition */
SC_ARG, /* - v auto param block def */
SC_RARG, /* - v auto param block def (register) */
SC_AUTO, /* - v auto - block def */
SC_RAUTO, /* - v auto - block def (register) */
SC_REGISTER, /* - v auto - block def (register) */
SC_LABEL, /* L Goto label */
SC_ULABEL, /* L Undefined goto label */
SC_ILABEL /* L Internal ($xxx) label. Not used in symtab. */
};
/* Symbol flags */
#define SF_LOCAL 01 /* Local symbol (not file scope) */
#define SF_XLOCAL 02 /* Local symbol no longer active */
#define SF_PROTOTAG 04 /* SC_TAG or SC_UTAG only: prototype scope */
#define SF_PARAMDECL 010 /* SC_ARG only: parameter declaration seen */
#define SF_SIDEFF 020 /* Side-effect (tag or enum) during parsing.
** This flag is only set by CCDECL's pbase()
** for dummy "base" symbol structures
** and only used to detect null declarations.
*/
#define SF_MACEXP 0100 /* SC_MACRO only: macro being expanded.
** This is used to detect and suppress
** recursive expansions.
*/
#define SF_MACSHADOW 0200 /* Any class, indicates this symbol is
** shadowed by a macro symbol (ie has the
** same identifier).
*/
#define SF_MACRO 040 /* SC_MACRO only: overloading class flag */
#define SF_MEMBER 01000 /* SC_MEMBER only: overloading class flag */
#define SF_TAG 02000 /* SC_TAG/SC_UTAG only: ditto */
#define SF_LABEL 04000 /* SC_LABEL/SC_ULABEL only: ditto */
#define SF_OVCLS (SF_MACRO|SF_MEMBER|SF_TAG|SF_LABEL) /* All ov classes */
#if 0
#define SF_REGIS 02 /* User declared this as "register" */
#endif
/*
** Global vs Local symbols
** Local symbols are kept on the "locsymbol" list and global ones on
** the "symbol" list. Local symbols can have the following classes:
** SC_ARG, SC_RARG (function parameters)
** SC_AUTO, SC_RAUTO, SC_ISTATIC (auto, register, static)
** SC_TAG, SC_UTAG, SC_ENUM, SC_MEMBER (struct/union/enum tags,enums,mems)
** SC_LABEL, SC_ULABEL, SC_ILABEL (goto labels)
**
** When parsing enters a scope block, "beglsym()" is called to set
** a pointer to the start of the list of symbols local to that block.
** All symbols before this pointer will belong to outer blocks; all symbols
** after this pointer will belong to this block or inner blocks.
** When parsing leaves a block, the symbols local to that block are
** still retained so that code generation can refer to them, but they are
** rendered inactive by setting the SF_XLOCAL (ex-local) flag. This is
** done by having "compound()" call "endlsym()". The findsym
** routine will never return a symbol which has this flag set.
** Thus, at any time, the symbols defined within any specific block (and
** not outer or inner ones) are represented by all of the local symbols
** following this remembered "head pointer" which do NOT have SF_XLOCAL set.
**
** All local symbols -- ie everything on the locsymbol list -- are
** flushed completely when the code generator has finished dealing with
** a function's parse tree. "ridlsym()" is the function called to do this.
** Note that SC_ARG and SC_RARG are active over the entire body of
** a function.
**
** Note that SC_ILABEL symbols are never found in the symbol table
** itself. These are generated by CCLAB and kept on a separate label list.
** Certain symbols may point to these "label symbols", however.
*/
/* TYPE - Type table entry
*/
TYPE {
int Tspec; /* Type specifier, set to a TS_ value */
int Tflag; /* Flags, plus size in bits (mask 0777) */
union {
int t_int; /* Size in words, or # elements. */
TYPE *t_subt; /* Ptr to parameter list, if function */
} t_v0;
union {
int t_int;
TYPE *t_subt; /* Subtype if not a basic type */
SYMBOL *t_sym; /* or tag name of struct or union */
} t_v1;
TYPE *Tnhash; /* Pointer to next in hash chain */
};
/* Define generally used members for public consumption.
** Code should never refer to "t_" members directly.
*/
#define Tsize t_v0.t_int /* Size (in wds or elems) - all but TS_FUNCT */
#define Tsubt t_v1.t_subt /* Subtype - TS_FUNCT, TS_ARRAY, TS_PTR */
/* For all types:
**
** Tspec is set to a TS_ value. These are specified by the "alltypemacro"
** definition on the next page.
** Tflag is used to hold both TF_ flags as well as the # of bits occupied
** by an object of scalar type. The flags are set from:
** (1) the flags specified in the "alltypemacro" definition, plus
** (2) TF_CONST or TF_VOLATILE if so declared, plus
** (3) TF_BYTE if the object is a bitfield OR is smaller than
** a word. (This is the only machine-dependent flag).
** Note that the size in bits is only meaningful for objects of
** scalar type, and is only really used for objects of integral type.
** Tnhash serves to chain together all types which hash to the same
** value.
**
** The other two members of a TYPE struct have varied uses which depend on
** the TS_ value in Tspec. The most common usages are:
**
** Tsize - normally represents the size of the object in terms of words.
** Tsubt - holds pointer to a subtype, if any.
*/
/* Tspec == TS_VOID
** Tflag == 0 (may be qualified)
** Tsize == 0 (unused)
** Tsubt == NULL (unused)
*/
/* TS_FUNCT - Function returning Tsubt.
** Tflag == 0 (cannot be qualified)
** Tsubt - type of return value.
** Tproto - if NULL, no prototype exists. Otherwise, points to
** the first node of a parameter list.
** Note that Tproto occupies the space normally used for Tsize; the latter
** interpretation is meaningless for a function.
** Functions without prototypes may still have a "hidden prototype" if
** an old-style definition was seen prior to any prototype declaration; this
** prototype list will be pointed to by Shproto of the identifier's symbol.
** See SC_EXTDEF.
*/
#define Tproto t_v0.t_subt /* Ptr to prototype param list, if any */
/* TS_PARxxx - Parameter List "types"
** The Tspec values TS_PARVOID, TS_PARINF, and TS_PARAM
** are not real types; they are used to link together parameter lists for
** function prototypes.
**
** Tspec - a TS_PARxxx value.
** Tflag - 0 (unused).
** Tproto - points to next node in parameter list. (reusing Tsize)
** Tsubt - NULL for TS_PARVOID and TS_PARINF; otherwise (for TS_PARAM)
** points to the unqualified type for this parameter.
**
** TS_PARVOID, if it exists, should be the only thing in a prototype list;
** it indicates that the function takes no arguments.
** TS_PARINF, if it exists, should be the last thing in a prototype list;
** it represents ellipsis terminator (",...")
** TS_PARAM is used for all normal parameters.
** Note that the type pointed to is unqualified even if the parameter
** identifier has a qualified type. This is because all operations on
** function prototypes (comparison, casting) use the unqualified type;
** this does not prevent a function definition from using type
** qualifiers on a parameter, because any reference to that parameter's
** identifier within the function body will be given the qualified type
** that the ident's Stype points to.
*/
/* TS_ARRAY - Array of Tsubt.
** Tsubt - type of an array element. This may be an array too.
** Tsize is the # of elements (objects) in the array, each of which has
** the given subtype. So the total size is Tsize times the size of
** the subtype.
** If Tsize is 0, then the size of the array is unknown. This can
** happen when the user declares something like "int foo[];"
** However, only the first dimension of a (possibly multi-dimensional)
** array can be left unspecified in this way, and obviously it will not
** work to do a sizeof on this array.
*/
/* TS_STRUCT, TS_UNION, TS_ENUM - Structure/Union/Enum of Tsmtag.
** Tsmtag - points to the tag symbol for this type. This re-uses the
** space of "Tsubt".
** Tsize is # of words in object. If a struct/union is not yet
** defined (i.e. Tsmtag->Sclass == SC_UTAG) then Tsize is 0
** since the size is unknown.
** See the detailed description on the next page.
*/
#define Tsmtag t_v1.t_sym /* TS_STRUCT or TS_UNION - tag pointer */
/* TS_PTR - Pointer to Tsubt.
** Tsubt - type of object pointed to.
** Tsize == 1 always (# wds in a pointer).
**
** It used to be the case that a type of TS_PTR used Tsize as an array
** indicator. THIS IS NO LONGER TRUE, but for reference:
** If Tsize 0, this was a normal TS_PTR to some object and the pointer
** had the size PTRSIZE.
** If Tsize non-zero, then this was a hybrid type that represented an
** array name coerced into a pointer. Tsize and Tsubt
** were the same as the Tsize and Tsubt of the array in question.
** The array type itself could be found by doing a findtype
** of TS_ARRAY with the given Tsize and Tsubt.
** To repeat: TS_PTR is now just a normal type, and its Tsize always
** represents the pointer size (1 word).
*/
/* All arithmetic types (floating point and integral):
** Tflag == Low-order bits have size in bits. Many TF_ flags.
** Tsize == size in words (if less than 1, is 1).
** Tsubt == NULL (unused).
*/
/* Structure/Union/Enum tags and members
**
** If a type has Tspec TS_STRUCT, TS_UNION, or TS_ENUM, then it has no subtype
** pointer. Instead, t_var is interpreted as "Tsmtag" - that is, a pointer
** to a tag symbol (Sclass SC_TAG). In the following discussion, the word
** "structure" is understood to mean both "struct" and "union".
**
** Struct/Union/Enum types:
** Tspec - TS_STRUCT, TS_UNION, or TS_ENUM.
** Tsize - size of the structure, in words. 0 if structure not yet
** defined. INTSIZE if an enum type.
** Tsmtag - pointer to the tag symbol for this type.
**
** Tag symbols:
** Sclass - SC_TAG (or SC_UTAG if not yet defined).
** Sname - the tag name, prefixed with SPC_TAG. This will be
** a unique internal name if the structure or enum list was
** not named with a tag at definition time.
** Stype - pointer to the C type. This is in effect a backpointer
** to the type specification described above.
** Ssmnext - pointer to the first component symbol of this object.
** This will be NULL if the tag is still undefined (SC_UTAG).
** For a structure, the components are structure members
** with Sclass SC_MEMBER. For an enum, the components are
** enum constants with Sclass SC_ENUM.
**
** Structure member symbols:
** Each component of a structure is represented by an unique
** symbol table entry. The members are linked together in order of
** definition.
** Sclass - SC_MEMBER
** Stype - C type of this member.
** Ssmoff - offset from beginning of structure.
** If positive, it is a word offset from start of struct.
** If negative, it is a bitfield. After making it positive again,
** the low 12 bits are the P+S fields of a byte pointer,
** and the remaining high bits are the word offset.
** Ssmnext - pointer to next member (NULL if this is last one).
** Ssmtag - pointer back to "parent" structure tag symbol.
** The sole reason for the existence of Ssmtag is so that
** it is possible to find out very quickly whether an
** arbitrarily selected SC_MEMBER symbol does in fact
** belong to a specific structure.
**
** Enum constant symbols:
** Each component of an enum list is represented by an unique
** symbol table entry, linked together in order of definition.
** These are almost the same as SC_MEMBERs except that Svalue is used
** instead of Ssmoff.
** Sclass - SC_ENUM
** Stype - C type (always "int" for now).
** Svalue - integer value of this enum constant.
** Ssmnext - pointer to next component (NULL if this is last one).
** Ssmtag - pointer back to "parent" tag symbol.
** This is not really used at the moment but is kept for
** consistency with SC_MEMBER and (someday) error messages.
**
** Tag, enum constant, and structure member symbols are treated just as
** regular variable symbols are. They can be made global or local, and in
** particular can be "shadowed" by structure definitions in inner blocks,
** through use of the global/local symbol lists and the SF_XLOCAL flag.
** Note that each structure member always has its own symbol cell, even
** though the identifier may duplicate that of a another structure's
** member. They are distinguished by checking the "Ssmtag" pointer,
** which indicates the structure enclosing any particular member.
** Enum constant symbols likewise are all unique to a particular tag,
** even though the language does not require this (in fact it requires
** that enum constant identifiers be treated in the same overloading class
** as regular variable identifiers!) This is so the list structure won't
** be screwed up by redefinitions. However, error messages will be
** generated whenever a duplicate enum constant definition is seen.
**
** There is a special situation where a struct/union definition might still
** be needed even after the tag (explicit or internal) would ordinarily
** have been flushed from the symbol table. This is for a def within a
** function prototype (either def or ref), which
** results in a parameter "type" that cannot ever match another type in
** any function call or prototype comparison once the prototype scope is left.
** In order to do this, tags defined within prototype scope are flagged
** with SF_PROTOTAG, and ridlsym() avoids flushing those symbols; instead
** it hides them with SF_XLOCAL and moves them to the global list, there to
** reside forever (until a new file compilation is started). It does not
** bother preserving the members of such tags, however, and sets Ssmnext
** to NULL. This ensures that the TYPE node's Tsmtag reference will remain
** valid and unique for the rest of the file.
**
** K&R "global" structure members are no longer allowed, as per H&S
** and ANSI.
*/
/* Type Specifiers */
/* Define moby macro defining all type specs.
** typespec(enum_name, string, size_in_bits, flags)
**
** The size_in_bits for TS_BITF (bitfields) is 1 here only so that
** the tables will be initialized properly and the TF_BYTE flag set
** for them. In actuality their size varies (and the same is possible
** for char).
** The TF_BYTE flag is automatically set on startup for all types
** that are valid objects smaller than a word. It is also set
** specially for TS_VOID, so that (void *) will be recognized as having
** a byte-pointer representation even tho it has a zero size!
**
** WARNING!!! If the ordering of this macro is changed, the values in
** the CONVTAB table in CCTYPE must also be changed!!!
*/
#define alltypemacro \
/* Misc types (keep TS_VOID as zero for elegance) */\
typespec(TS_VOID, "void", 0,TF_BYTE) /* (void) */\
typespec(TS_FUNCT,"function",0,0) /* Function (rets subtype) */\
/* Aggregate types */\
typespec(TS_ARRAY, "array", 0,0) /* Array (of a subtype) */\
typespec(TS_STRUCT,"struct", 0,TF_STRUCT) /* Structure */\
typespec(TS_UNION, "union", 0,TF_STRUCT) /* Union */\
/* Scalar misc types */\
typespec(TS_PTR, "pointer",TGSIZ_PTR, TF_SCALAR) /* Ptr (to subtype) */\
typespec(TS_ENUM,"enum", TGSIZ_ENUM,TF_SCALAR) /* Enum */\
/* Scalar Arithmetic types - Floating-point */\
typespec(TS_FLOAT, "float", TGSIZ_FLOAT, TF_FLOAT) /* (float) */\
typespec(TS_DOUBLE,"double",TGSIZ_DOUBLE,TF_FLOAT) /* (double) */\
typespec(TS_LNGDBL,"lngdbl",TGSIZ_LNGDBL,TF_FLOAT) /* (long double) */\
/* Scalar Arithmetic types - Integral */\
typespec(TS_BITF, "bitf", 1, TF_INTEG+TF_BITF) /* bitfield */\
typespec(TS_CHAR, "char", TGSIZ_CHAR, TF_INTEG+TF_CHAR) /* char */\
typespec(TS_SHORT,"short", TGSIZ_SHORT,TF_INTEG) /* short */\
typespec(TS_INT, "int", TGSIZ_INT, TF_INTEG) /* int */\
typespec(TS_LONG, "long", TGSIZ_LONG, TF_INTEG) /* long */\
typespec(TS_UBITF,"u_bitf", 1, TF_UINTEG+TF_BITF) \
typespec(TS_UCHAR,"u_char", TGSIZ_CHAR, TF_UINTEG+TF_CHAR) \
typespec(TS_USHORT,"u_short",TGSIZ_SHORT,TF_UINTEG) \
typespec(TS_UINT, "u_int", TGSIZ_INT, TF_UINTEG) \
typespec(TS_ULONG,"u_long", TGSIZ_LONG, TF_UINTEG)
/* Define values for Tspec */
enum typespecs {
#define typespec(ts,str,bsiz,fl) ts,
alltypemacro /* Expand */
#undef typespec
TS_MAX, /* # types; 1st non-existent typespec index */
/* Additional Tspec vals for fn prototypes */
TS_PARVOID=TS_MAX, /* fn(void) - only at beg of proto list */
TS_PARINF, /* ", ..." - only at end of proto list */
TS_PARAM /* Normal parameter */
};
/* Definitions for Tflag - note that bitsize and flags must not overlap. */
#define tbitsize(t) ((t)->Tflag&0777) /* Get size in bits for a type */
#define TF_CONST 01000 /* Type is a "const" object */
#define TF_VOLATILE 02000 /* Type is a "volatile" object */
#define TF_INTEG 010000 /* Integral type */
#define TF_FLOAT 020000 /* Floating-point type */
#define TF_SCALAR 040000 /* Scalar type */
#define TF_UNSIGN 0100000 /* Unsigned type */
#define TF_CHAR 0200000 /* Char type */
#define TF_BITF 0400000 /* Bitfield type */
#define TF_STRUCT 01000000 /* Struct or Union type */
#define TF_BYTE 02000000 /* Byte (non-word) type (MACH DEPENDENT) */
#define TF_SICONST 04000000 /* Struct/union with inner "const" */
#define TF_SIVOLAT 010000000 /* Struct/union with inner "volatile" */
#if SYS_CSI
#define TF_FORTRAN 0100000000 /* fortran attribute for functions */
#define TF_BLISS 0200000000 /* bliss attrubute for functions */
#endif
/* Combos */
#define TF_QUALS (TF_CONST|TF_VOLATILE) /* Type qualifiers */
#define TF_SIQUALS (TF_SICONST|TF_SIVOLAT) /* Type qualifiers in struct */
#define TF_UINTEG (TF_INTEG+TF_UNSIGN) /* to save space in alltypemacro */
/* Quick-check macros. Try to avoid directly using the TF_ macros. */
#define tisqualif(t) ((t)->Tflag&TF_QUALS)
#define tisconst(t) ((t)->Tflag&TF_CONST)
#define tisvolatile(t) ((t)->Tflag&TF_VOLATILE)
#define tisstructiconst(t) ((t)->Tflag&TF_SICONST)
#define tisstructivolat(t) ((t)->Tflag&TF_SIVOLAT)
#define tisanyvolat(t) ((t)->Tflag&(TF_VOLATILE|TF_SIVOLAT))
#define tisinteg(t) ((t)->Tflag&TF_INTEG)
#define tisfloat(t) ((t)->Tflag&TF_FLOAT)
#define tisarith(t) ((t)->Tflag&(TF_INTEG+TF_FLOAT))
#define tisscalar(t) ((t)->Tflag&(TF_INTEG+TF_FLOAT+TF_SCALAR))
#define tischar(t) ((t)->Tflag&TF_CHAR)
#define tisbitf(t) ((t)->Tflag&TF_BITF)
#define tisunsign(t) ((t)->Tflag&TF_UNSIGN)
#define tissigned(t) (!tisunsign(t))
#define tisstruct(t) ((t)->Tflag&TF_STRUCT) /* struct or union */
#define tisbyte(t) ((t)->Tflag&TF_BYTE) /* Byte (non-word) object */
/* Similar functions too complex for macros */
#define tischarpointer tischp /* External name disambiguation */
#define tisbytepointer tisbyp
#define tischararray tischa
#define tisbytearray tisbya
extern int tischarpointer(), tisbytepointer(), tischararray(), tisbytearray();
extern int tispure();
/* Same macros, but with a Tspec argument. */
#define tspisinteg(ts) (tfltab[ts]&TF_INTEG)
#define tspisfloat(ts) (tfltab[ts]&TF_FLOAT)
#define tspisarith(ts) (tfltab[ts]&(TF_INTEG+TF_FLOAT))
#define tspisscalar(ts) (tfltab[ts]&(TF_INTEG+TF_FLOAT+TF_SCALAR))
#define tspischar(ts) (tfltab[ts]&TF_CHAR)
#define tspisunsigned(ts) (tfltab[ts]&TF_UNSIGN)
extern int tfltab[]; /* Flag table, kept in CCDATA */
/* Cast (Type Conversion) types (NODE.Ncast) */
#define allcastmacro \
/* General-purpose cast types */\
castspec(CAST_ILL,"ill") /* convtab[] only: Illegal cast */\
castspec(CAST_TRIV,"triv") /* convtab[] only: types must be == */\
castspec(CAST_NONE,"none") /* No actual conversion needed */\
/* Casts to Integer Type */\
castspec(CAST_IT_IT,"it_it") /* from Integer Type */\
castspec(CAST_FP_IT,"fp_it") /* from Floating-Point type */\
castspec(CAST_EN_IT,"en_it") /* from ENumeration type */\
castspec(CAST_PT_IT,"pt_it") /* from Pointer Type */\
/* Casts to Floating-Point type */\
castspec(CAST_FP_FP,"fp_fp") /* from Floating-Point type */\
castspec(CAST_IT_FP,"it_fp") /* from Integer Type */\
/* Casts to ENum type */\
castspec(CAST_EN_EN,"en_en") /* from ENumeration type */\
castspec(CAST_IT_EN,"it_en") /* from Integer Type */\
/* Casts to Pointer Type */\
castspec(CAST_PT_PT,"pt_pt") /* from Pointer Type */\
castspec(CAST_IT_PT,"it_pt") /* from Integer Type */\
/* Misc casts */\
castspec(CAST_AR_PA,"ar_pa") /* Array -> Ptr to 1st element */\
castspec(CAST_FN_PF,"fn_pf") /* Function -> Pointer to Function */\
castspec(CAST_VOID,"void") /* Any type to void type (discard) */
enum castspecs {
#define castspec(op,str) op,
allcastmacro /* Expand */
#undef castspec
CAST_MAX /* # of cast types */
};
/* Macro to generate a unique index for every possible type cast combo */
#define castidx(from,to) (((to)*TS_MAX)+(from))
/*
** Misc shared storage
*/
EXT SYMBOL
*symbol, /* Global symbol table head ptr */
*csymbol, /* Current symbol */
*minsym; /* minimum variable ptr (CC, CCSYM) */
EXT SYMBOL bytsym; /* Symbol for $BYTE */
extern SYMBOL *htable[]; /* Symbol hash table (CCSYM, CCDATA) */
extern TYPE *ttable[]; /* Type hash table (CCSYM, CCDATA) */
extern TYPE types[]; /* Table of type structs (CCDUMP, CCSYM, CCDATA) */
/* Eventually make this dynamic */