/* * DECL.H * * (c)Copyright 1993-2014, Matthew Dillon, All Rights Reserved. See the * COPYRIGHT file at the base of the distribution. */ struct Exp; struct SemGroup; struct SGDepend; struct Declaration; struct RunContext; struct GenContext; typedef void (*ic_func_t)(struct Declaration *d, LValueStor *lvs); /* * Scope - scope associated with declaration * * WARNING: Must match classes/sys/runetime.d */ typedef struct Scope { int s_Flags; /* SCOPE_* flags */ int s_AlignOverride; /* __align(%d) override */ } Scope; #define INIT_SCOPE(flags) { flags, 0 } /* * Declaration - a qualified declaration * * This structure represents a declaration. A declaration is anything * with an identifier and scope. * * Declarations are grouped in SemGroup's. d_Offset is typically * assigned for DOP_STORAGE declarations but it should be noted that * SemGroups related to procedures are collapsed into a single set * of offsets relative to the top-level SemGroup for the procedure, * so d_Offset in a deeper SemGroup an exceed its sg_Bytes. * * d_Bytes almost always matches the declaration's type size, but * there are certain cases where it will not. A declaration representing * an LVALUE procedure argument, for example, has a size of a pointer * (for pass by reference) even though the underlying type may be * an object. * * d_SRNext is based at sg_SRBase, and is resolved at resolve-time. * This is a linked list of storage declarations which represent * reference-tracked items such as lvalues (in argument lists), and * pointers. * * (note 1): d_Level is usually d_MyGroup, except in a subclass when * we pull declarations down from the superclass, in which case it * points at the superclass (or higher superclasses) for those * declarations. It is used when our semgroup is being searched for * our id to locate the correct id. d_Search is what we have to use * when we are searching this declaration's object for sub identifiers. */ typedef RUNE_HEAD(decllist, Declaration) decllist_t; typedef struct Declaration { RUNE_ENTRY(Declaration) d_Node; struct Parse *d_Parse; struct Declaration *d_HNext; /* id hash table chain */ struct Declaration *d_SRNext; /* pointer or lvalue storage chain */ struct Declaration *d_CNext; /* constructor chain */ struct Declaration *d_DNext; /* destructor chain */ struct Declaration *d_GNext; /* global constructor/destructor chn */ struct Declaration *d_ONext; /* operid hash table chain */ int d_Op; /* declaration opcode */ int8_t d_Storage; /* (resolver) GENSTAT_* storage mode */ int8_t d_Dummy01; int8_t d_Dummy02; int8_t d_Dummy03; string_t d_Id; /* identifier or NULL */ struct SemGroup *d_Level; /* When searching for us (note 1) */ struct SemGroup *d_Search; /* when searching through (note 1) */ Scope d_Scope; /* scope of declaration */ int d_Flags; int d_BackendId; runesize_t d_Bytes; /* size of declaration (see note) */ runesize_t d_AlignMask; runesize_t d_Offset; /* see note above */ runesize_t d_TmpBytes; /* tmpspace required for *_AssExp */ runesize_t d_InfoIndex; /* PointerInfo index */ int d_Index; /* index on SemGroup list */ int d_DynIndex; /* dynamic index */ struct SemGroup *d_MyGroup; /* semantic grouping */ struct SemGroup *d_ImportSemGroup; /* upwards traversal for search */ struct Stmt *d_Stmt; /* only if declaration statement */ LexRef d_LexRef; /* for error reporting */ struct Declaration *d_Super; /* decl in superclass (semantic srch) */ struct Declaration *d_SubBase; /* refined decls */ struct Declaration *d_SubNext; /* link for refined decls */ union { struct { struct SemGroup *ed_SemGroup; /* semantic grouping */ Type *ed_Super; /* super class (type) */ } ClassDecl; struct { Type *ed_Type; /* type */ struct Exp *ed_AssExp; /* initialization */ void *ed_DLLAddr; /* DLL (C lang) ifc */ } StorDecl; struct { struct SemGroup *ed_SemGroup; /* semantic grouping */ } ImportDecl; /* * Statement bodies are duplicated before being resolved * in order to be able to re-resolve them in different * contexts. */ struct { Type *ed_Type; /* TY_PROC type */ struct Stmt *ed_ProcBody; /* ST_Proc statement */ struct Stmt *ed_OrigBody; /* ST_Proc statement */ string_t ed_OperId; /* If operator */ ic_func_t ed_IFunc; /* opt internal func */ void *ed_DLLFunc; /* DLL (C lang) ifc */ } ProcDecl; struct { void *ed_Fill0; void *ed_Fill1; void *ed_Fill2; void *ed_Fill3; void *ed_Fill4; void *ed_Fill5; } FILLER; } u; } Declaration; /* * DOP_CLASS - represents a class definition (statement) * DOP_TYPEDEF - represents a typedef * DOP_ALIAS - represents an alias * DOP_IMPORT - represents an import (statement) * DOP_PROC - represents a procedural definition * DOP_STACK_STOR - represents non-global stack-based storage relative a * procedure's (single) run-time context. * DOP_ARGS_STOR - represents non-global storage for arguments to * a procedure. * DOP_GLOB_STOR - represents global storage * DOP_GROUP_STOR - represents general storage declarations * within class definitions, top-level declarations * of an import (though these are always global so * are usually DOP_GLOB_STOR), and compound type * definitions... anything that would otherwise be * a DOP_STACK_STOR is a DOP_GROUP_STOR in these * contexts. */ #define DOP_CLASS 1 #define DOP_TYPEDEF 2 #define DOP_ALIAS 3 #define DOP_IMPORT 4 #define DOP_PROC 5 #define DOP_ARGS_STORAGE (6 | DOPF_STORAGE) #define DOP_STACK_STORAGE (7 | DOPF_STORAGE) #define DOP_GLOBAL_STORAGE (8 | DOPF_STORAGE) #define DOP_GROUP_STORAGE (9 | DOPF_STORAGE) #define DOPF_STORAGE 0x0100 #define DF_RESOLVING 0x00000001 #define DF_RESOLVED 0x00000002 #define DF_SUPERCOPY 0x00000004 /* temporary flag during resolve */ #define DF_SUPER 0x00000008 /* special case to access super proc */ #define DF_GENERATING 0x00000010 /* deferred generation of global def */ #define DF_ADDRUSED 0x00000020 /* addr taken or used temporarily */ #define DF_COLLAPSING 0x00000040 /* collapse pass */ #define DF_COLLAPSED 0x00000080 /* collapse pass */ #define DF_LAYOUT 0x00000100 /* available for global data layout */ #define DF_ONGLIST 0x00000200 /* decl on sg->sg_GList */ #define DF_ONDLIST 0x00000400 /* decl on sg->sg_DList */ #define DF_ONCLIST 0x00000800 /* decl on sg->sg_CList */ #define DF_TMPRESOLVED 0x00001000 /* temporary flag to avoid loops */ #define DF_INLINING 0x00002000 /* inlining in progress */ #define DF_DYNAMICREF 0x00004000 /* dynamic method may reference */ #define DF_DIDEXPDUP 0x00008000 /* dup'd assexp */ #define DF_ONSRLIST 0x00010000 #define DF_DIDPULLDOWN 0x00020000 /* did procedure pull-down */ #define DF_ALIGNRESOLVE 0x00040000 #define DF_ADDROF 0x00080000 /* &field taken explicitly */ #define d_ScopeFlags d_Scope.s_Flags #define d_ClassDecl u.ClassDecl #define d_StorDecl u.StorDecl #define d_GlobalDecl u.StorDecl #define d_AliasDecl u.StorDecl #define d_TypedefDecl u.StorDecl #define d_ImportDecl u.ImportDecl #define d_ProcDecl u.ProcDecl /* * SemGroup types */ typedef enum { SG_UNKNOWN = 0, SG_MODULE, /* module */ SG_CLASS, /* class */ SG_COMPOUND, /* compound object (other than proc-args) */ SG_PROCTOP, /* procedure-top */ SG_PROCARGS, /* procedure-args */ SG_EXEC /* execution (other than PROCARGS) */ } sg_type_t; /* * SemGroup - Block of declarations * * This is used to manage blocks of declarations. It is primarily * used to generate a semantic tree for our semantic searches. * * Note that the SemGroup representing an IMPORT block sets SCOPE_GLOBAL * on all of its declarations. * * WARNING! This structure is written out as global data by the code * generator. Do not rearrange, add, or remove fields without * also adjusting classes/sys/runtime.d */ typedef RUNE_HEAD(sglist, SemGroup) sglist_t; typedef struct SemGroup { RUNE_ENTRY(SemGroup) sg_Node; sg_type_t sg_Type; int sg_Complexity; /* aggregate complexity (stmt sg) */ struct Parse *sg_Parse; struct SemGroup *sg_Parent; /* parent semantic group */ struct SemGroup *sg_AltContext; /* (resolver) alt search context */ struct SGDepend *sg_DepFirst; /* dependency ordering */ Declaration *sg_SRBase; /* base of pointer/lvalue list */ Declaration *sg_CBase; /* base of constructor list */ Declaration *sg_DBase; /* base of destructor list */ Declaration *sg_GBase; /* base of global cons/dest list */ string_t sg_Project; /* shared data rendezvous (NULL ok) */ sglist_t sg_SemList; /* sub-semantic groups */ decllist_t sg_DeclList; /* list of declarations */ typelist_t sg_ClassList; /* list of [qualified] class types */ /* (also for compound types) */ struct Stmt *sg_Stmt; /* associated statement */ int sg_Flags; int sg_Compat; /* compatibility with superclass */ int sg_Level; int sg_DynCount; runesize_t sg_Bytes; /* aggregated size */ int sg_NestLevel; /* procedural nesting level */ int sg_NestSize; /* total number of nesting levels */ runesize_t sg_AlignMask; runesize_t sg_BlkOffset; /* this sg only, no children */ runesize_t sg_BlkBytes; /* this sg only, no children */ runesize_t sg_GlobalBytes; /* globals are separated out */ runesize_t sg_GlobalAlignMask; /* globals are separated out */ runesize_t sg_GlobalTmpBytes; /* globals are separated out */ runesize_t sg_TmpBytes; /* temporary space required */ runesize_t sg_TmpAlignMask;/* temporary space alignment reqs */ struct RunContext *sg_GlobalRunCtx; /* globals are separated out */ void *sg_GlobalGenCtx; /* globals are separated out */ int sg_DeclCount; /* total number of decls */ int sg_VarCount; /* how many decls are varargs */ runesize_t sg_InfoCount; /* #of PointerInfo's needed */ } SemGroup; #define SGF_RESOLVING 0x00000001 /* check for resolver loops */ #define SGF_RESOLVED 0x00000002 /* resolver complete */ #define SGF_VARARGS 0x00000004 /* (procedure only) */ #define SGF_ENTRY 0x00000008 /* entry module */ #define SGF_SEMTOP 0x00000010 #define SGF_NOINIT 0x00000020 /* (intrp - cache status) */ #define SGF_SELFCONTAINED 0x00000040 /* (import) self contained */ #define SGF_TMPRESOLVED 0x00000080 /* temporary space resolved */ #define SGF_NESTED 0x00000100 /* (proc SEMTOP), nested proc */ #define SGF_ISUNSIGNED 0x00000200 /* UInteger or subclass */ #define SGF_ISFLOATING 0x00000400 /* Float or subclass */ #define SGF_HASASS 0x00000800 /* contains decls w/ass */ #define SGF_GRESOLVING 0x00001000 /* resolve in-class globals */ #define SGF_GRESOLVED 0x00002000 /* resolve in-class globals */ #define SGF_GENERATING 0x00004000 /* avoid duplicate import gen */ #define SGF_ISINTEGER 0x00008000 /* UInteger or SInteger */ #define SGF_GHASASS 0x00010000 /* contains decls w/ass (glob)*/ #define SGF_ISBOOL 0x00020000 /* Bool or subclass */ #define SGF_COLLAPSING 0x00040000 /* collapse pass */ #define SGF_COLLAPSED 0x00080000 /* collapse pass */ #define SGF_LAYOUT 0x00100000 /* avail for global layout */ #define SGF_HASLVPTR 0x00200000 /* contains lvalues or ptrs */ #define SGF_GHASLVPTR 0x00400000 /* contains lvalues or ptrs */ #define SGF_DIDCTOR 0x00800000 /* ctor already generated */ #define SGF_ADDRUSED 0x01000000 /* rollup &obj used */ #define SGF_ALIGNRESOLVED 0x02000000 /* resolver */ #define SGF_FRESOLVING 0x04000000 /* resolver */ #define SGF_FRESOLVED 0x08000000 /* resolver */ #define SGF_DIDRESULT 0x10000000 /* resolver, thread detach */ #define SGF_ALTPRIORITY 0x20000000 /* alt ctx priority */ #define SGF_ABICALL 0x40000000 /* ABI call made (recursive)*/ #define SGF_GABICALL 0x80000000 /* GABI call made (recursive)*/ #define SGF_INHERIT_BASE (SGF_VARARGS | SGF_ENTRY | SGF_SEMTOP | \ SGF_SELFCONTAINED | SGF_NESTED | \ SGF_ALTPRIORITY | SGF_ABICALL) #define SGF_INHERIT_ALL (SGF_INHERIT_BASE | \ SGF_NOINIT | SGF_ISUNSIGNED | \ SGF_ISFLOATING | SGF_HASASS | \ SGF_ISINTEGER | SGF_GHASASS | \ SGF_ISBOOL | SGF_HASLVPTR | \ SGF_GHASLVPTR) /* * SG dependencies (used to order global ctors) */ typedef struct SGDepend { struct SGDepend *hnext; struct SGDepend *next; SemGroup *src; SemGroup *dst; int ctor_flag; } SGDepend; /* * SG_COMPAT* - super class / subclass compatibility: * * FULL * * Requested type is a subclass of the specified superclass and both * the method calls and the storage is compatible. Note, however, * that the subclass might extend (be larger then) the superclass. * * PART * * Requested type is a subclass of the specified superclass and the * method calls are compatible, but the storage is not compatible. * * SUBCLASS * * Requested type is a subclass of the specified superclass but the * method calls are not compatible (meaning we have to regenerate the * method call procedures for the subclass that propogate down from * the superclass). * * FAIL * * Requested type is not a subclass of the specified superclass. */ #define SG_COMPAT_FULL 0 #define SG_COMPAT_PART 1 #define SG_COMPAT_SUBCLASS 2 #define SG_COMPAT_FAIL 3 /* * FindDeclPath() flags */ #define FDC_NOBACK 0x0001 #define FDC_NULL 0x0002 #define dassert_decl(d, cond) if (!(cond)) DeclFatalError((d), 0) #define dassert_semgrp(sg, cond) dassert(cond) #ifdef LIBRUNTIME #define DeclFatalError(d, type) \ do { \ dpanic("Fatal Error Decl %p (%s)", d, d->d_Id); \ } while(0) #else #define DeclFatalError(d, type) \ do { \ DeclPrintError(d, type); \ dpanic(""); \ } while(0) #endif