WindowsXP-SP1/com/rpc/midl/front/gramutil.hxx
2020-09-30 16:53:49 +02:00

614 lines
17 KiB
C++

/*****************************************************************************/
/** Microsoft LAN Manager **/
/** Copyright(c) Microsoft Corp., 1987-1999 **/
/*****************************************************************************/
/*****************************************************************************
File : gramutil.hxx
Title : grammar utility module
Description : contains definitions associated with the grammar and
: associated routines
History :
05-Sep-1990 VibhasC Created
11-Sep-1990 VibhasC Merged gramdefs.hxx into this one for easy
maintainability
20-Sep-1990 NateO Safeguards against double inclusion, added
include of rpctypes, common
*****************************************************************************/
#ifndef __GRAMUTIL_HXX__
#define __GRAMUTIL_HXX__
#include "allnodes.hxx"
#include "symtable.hxx"
#include "idict.hxx"
extern "C" {
#include "lex.h"
}
/***************************************************************************
* prototypes of all grammar related utility routines
***************************************************************************/
void BaseTypeSpecAnalysis( struct _type_ana *, short );
void SignSpecAnalysis( struct _type_ana *, short );
void SizeSpecAnalysis( struct _type_ana *, short );
void ParseError( STATUS_T , char *);
STATUS_T GetBaseTypeNode( node_skl **, short, short, short, short typeAttrib = 0);
STATUS_T GetBaseTypeNode( node_skl **, struct _type_ana );
/***************************************************************************
* general definitions
***************************************************************************/
//
// definitions for type specification and analysis
//
// basic types
#define TYPE_UNDEF (0)
#define TYPE_INT (1)
#define TYPE_FLOAT (2)
#define TYPE_DOUBLE (3)
#define TYPE_VOID (4)
#define TYPE_BOOLEAN (5)
#define TYPE_BYTE (6)
#define TYPE_HANDLE_T (7)
#define TYPE_PIPE (8)
#define TYPE_FLOAT80 (9)
#define TYPE_FLOAT128 (10)
// sizes of basic types
#define SIZE_UNDEF (0)
#define SIZE_CHAR (1)
#define SIZE_SHORT (2)
#define SIZE_LONG (3)
#define SIZE_HYPER (4)
#define SIZE_SMALL (5)
#define SIZE_LONGLONG (6)
#define SIZE_INT64 (7)
#define SIZE_INT32 (8)
#define SIZE_INT3264 (9)
#define SIZE_INT128 (10)
// signs
#define SIGN_UNDEF (0)
#define SIGN_SIGNED (1)
#define SIGN_UNSIGNED (2)
// attribs
#define ATT_NONE (0)
#define ATT_W64 (1)
#define SET_ATTRIB(x,att) (x = x | att)
#define SET_TYPE(x,type) (x = x | (type << 4 ))
#define SET_SIZE(x,size) (x = x | (size << 8))
#define SET_SIGN(x,sign) (x = x | (sign << 12))
#define GET_ATTRIB(x) (x & 0x000f)
#define GET_TYPE(x) ((x & 0x00f0) >> 4)
#define GET_SIZE(x) ((x & 0x0f00) >> 8)
#define GET_SIGN(x) ((x & 0xf000) >> 12)
#define MAKE_TYPE_SPEC(sign,size,type, attrib) ((sign << 12) | (size << 8) | (type << 4) | attrib)
//
// array bounds
//
#define DEFAULT_LOWER_BOUND (0)
/*****************************************************************************
* definitions local to the parser
****************************************************************************/
struct _type_ana
{
short TypeSize; // char/short/small/hyper/long/etc
short BaseType; // int/float/double/void/bool/handle_t ect
short TypeSign; // signed/unsigned
short TypeAttrib; // vanilla/__w64
};
class _DECLARATOR
{
public:
class node_skl * pHighest;
class node_skl * pLowest;
void Init()
{
pHighest = (node_skl *) NULL;
pLowest = (node_skl *) NULL;
};
void Init( node_skl * pSoloNode )
{
pHighest = pSoloNode;
pLowest = pSoloNode;
};
void Init( node_skl * pTop, node_skl * pBottom)
{
pHighest = pTop;
pLowest = pBottom;
};
void ReplTop( node_skl * pTop )
{
pTop->SetChild( pHighest->GetChild() );
pHighest = pTop;
};
// void MergeBelow( _DECLARATOR & dec );
};
// declarator lists are maintained as circular lists with a pointer to the
// tail element. Also, the list pointer is a full entry, not just a pointer.
class _DECLARATOR_SET;
class DECLARATOR_LIST_MGR;
class _DECLARATOR_SET: public _DECLARATOR
{
private:
class _DECLARATOR_SET * pNext;
friend class DECLARATOR_LIST_MGR;
public:
void Init()
{
pNext = NULL;
pHighest = NULL;
pLowest = NULL;
};
void Init( _DECLARATOR pFirst )
{
pHighest = pFirst.pHighest;
pLowest = pFirst.pLowest;
pNext = NULL;
};
void Add( _DECLARATOR pExtra )
{
// skip empty declarator
if (pExtra.pHighest == NULL)
return;
// fill in anchor if empty
if (pHighest == NULL)
{
Init( pExtra);
return;
};
// create a new link node, and fill it in
_DECLARATOR_SET * pNew = new _DECLARATOR_SET;
pNew->pHighest = pExtra.pHighest ;
pNew->pLowest = pExtra.pLowest ;
if ( pNext )
{
// point pNext to list head (tail's tail)
// point tail to new one
pNew->pNext = pNext->pNext;
pNext->pNext = pNew;
}
else
{
pNew->pNext = pNew;
}
// advance tail pointer
pNext = pNew;
};
};
class DECLARATOR_LIST_MGR
{
class _DECLARATOR_SET * pCur;
class _DECLARATOR_SET * pAnchor;
public:
DECLARATOR_LIST_MGR(_DECLARATOR_SET & First)
{
_DECLARATOR_SET * pTail = First.pNext;
pCur = NULL;
pAnchor = &First;
// break the circular list, so first points to head
// of list, and tail points to NULL
if (pTail)
{
First.pNext = pTail->pNext;
pTail->pNext = NULL;
}
};
// return next element
_DECLARATOR * DestructiveGetNext()
{
_DECLARATOR_SET * pLast = pCur;
// delete the element we returned last time (if
// not NULL or the Anchor node)
if (pCur)
{
pCur = pCur->pNext;
if (pLast != pAnchor)
{
delete pLast;
}
}
else
{
pCur = pAnchor;
};
return pCur;
};
BOOL NonEmpty()
{
return ( pAnchor->pHighest != NULL );
};
};
class SIBLING_LIST
{
named_node * pTail;
friend class SIBLING_ITER;
public:
SIBLING_LIST Init()
{
pTail = NULL;
return *this;
};
SIBLING_LIST Init( node_skl * pLoneNode )
{
named_node * pSoloNode = (named_node *) pLoneNode;
pTail = pSoloNode;
if ( pSoloNode )
{
pSoloNode->SetSibling( pSoloNode );
};
return *this;
};
BOOL NonNull()
{
return pTail != NULL;
};
named_node * Tail()
{
return pTail;
};
SIBLING_LIST SetPeer( named_node * pNewNode )
{
return Add( pNewNode );
};
SIBLING_LIST Add( named_node * pNewNode ); // add to tail
SIBLING_LIST Merge( SIBLING_LIST & NewList );
named_node * Linearize();
void AddAttributes( ATTRLIST & AList );
operator void * ()
{
return pTail;
};
};
class SIBLING_ITER
{
private:
named_node * pHead;
named_node * pCur;
public:
SIBLING_ITER( SIBLING_LIST & SibList )
{
pCur = NULL;
pHead = (SibList.pTail == NULL) ?
NULL :
(named_node *) SibList.pTail->GetSibling();
};
named_node * Next()
{
if (pCur == NULL)
{
pCur = pHead;
}
else
{
pCur = (named_node *) pCur->GetSibling();
pCur = (pCur == pHead) ? NULL : pCur;
}
return pCur;
};
};
class _decl_spec
{
public:
node_skl * pNode;
MODIFIER_SET modifiers;
void Init( node_skl * pOnly )
{
pNode = pOnly;
};
void Init( node_skl *pOnly, const MODIFIER_SET & mod )
{
pNode = pOnly;
modifiers = mod;
}
};
struct _interface_header
{
node_interface * pInterface; // interface node
};
struct _numeric
{
union
{
double dVal; // value
float fVal; // value
long Val; // value
};
char *pValStr; // value string as user specified
};
struct _array_bounds
{
class expr_node * LowerBound; // lower array bound
class expr_node * UpperBound; // upper bound
};
struct _int_body
{
SIBLING_LIST Imports; // import nodes
SIBLING_LIST Members; // type graph node below interface node
};
struct _library_header
{
node_library * pLibrary;
};
struct _disp_header
{
node_dispinterface * pDispInterface;
};
struct _coclass_header
{
node_coclass * pCoclass;
};
struct _module_header
{
node_module * pModule;
};
struct _enlab
{
class expr_node * pExpr;
class node_label * pLabel;
unsigned short fSparse;
};
struct _enlist
{
class SIBLING_LIST NodeList;
class node_label * pPrevLabel;
unsigned short fSparse;
};
struct _en_switch
{
class node_skl * pNode;
class node_switch_is * pSwitch;
char * pName;
};
struct _nu_caselabel
{
class expr_node * pExpr;
node_base_attr * pDefault;
};
struct _nu_cllist
{
class expr_list * pExprList;
class node_base_attr * pDefault;
short DefCount;
};
struct _nu_cases
{
SIBLING_LIST CaseList;
short DefCount;
};
union s_lextype {
short yy_short;
USHORT yy_ushort;
int yy_int;
long yy_long;
MODIFIER_SET yy_modifiers;
enum _operators yy_operator;
char * yy_pSymName;
char * yy_string;
_type_ana yy_type;
node_skl * yy_graph;
_DECLARATOR yy_declarator;
_DECLARATOR_SET yy_declarator_set;
_decl_spec yy_declspec;
_interface_header yy_inthead;
type_node_list * yy_tnlist;
_array_bounds yy_abounds;
_int_body yy_intbody;
expr_node * yy_expr;
expr_list * yy_exprlist;
_numeric yy_numeric;
_enlab yy_enlab;
_enlist yy_enlist;
expr_init_list * yy_initlist;
ATTR_T yy_attrenum;
class SIBLING_LIST yy_siblist;
class ATTRLIST yy_attrlist;
class node_base_attr * yy_attr;
struct _en_switch yy_en_switch;
struct _nu_caselabel yy_nucaselabel;
struct _nu_cllist yy_nucllist;
struct _nu_cases yy_nucases;
_library_header yy_libhead;
_disp_header yy_disphead;
_module_header yy_modulehead;
_coclass_header yy_coclasshead;
token_t yy_tokentype;
};
typedef union s_lextype lextype_t;
//
// the parse stack depth
//
#define YYMAXDEPTH 150
/////////////////////////////////////////////////////////////////////////////
// predefined type node data base
/////////////////////////////////////////////////////////////////////////////
struct _pre_type
{
unsigned short TypeSpec;
class node_skl * pPreAlloc;
};
#define PRE_TYPE_DB_SIZE (36)
class pre_type_db
{
private:
struct _pre_type TypeDB[ PRE_TYPE_DB_SIZE ];
public:
pre_type_db( void );
STATUS_T GetPreAllocType(node_skl **, unsigned short);
};
//
// A structure which carries the interface information while the interface
// is being processed. This is necessary since the interface node and the
// type graph gets joined after the interface declarations are fully processed
// and the interface declarations need this while it is being processed.
//
typedef struct _iInfo
{
node_interface * pInterfaceNode;
short CurrentTagNumber;
unsigned short IntfKey;
ATTR_T InterfacePtrAttribute;
BOOL fPtrDefErrorReported;
BOOL fPtrWarningIssued;
BOOL fLocal;
} IINFO ;
class IINFODICT : public ISTACK
{
private:
BOOL fBaseLocal;
ATTR_T BaseInterfacePtrAttribute;
node_interface * pBaseInterfaceNode;
public:
IINFODICT() : ISTACK( 5 )
{
BaseInterfacePtrAttribute = ATTR_NONE;
}
BOOL IsPtrWarningIssued();
void SetPtrWarningIssued();
void StartNewInterface();
void EndNewInterface();
void SetInterfacePtrAttribute( ATTR_T A );
ATTR_T GetInterfacePtrAttribute();
ATTR_T GetBaseInterfacePtrAttribute();
void SetInterfaceLocal();
BOOL IsInterfaceLocal();
void SetInterfaceNode( node_interface *p );
node_interface * GetInterfaceNode();
SymTable * GetInterfaceProcTable()
{
return GetInterfaceNode()->GetProcTbl();
}
char * GetInterfaceName()
{
return GetInterfaceNode()->GetSymName();
}
short GetCurrentTagNumber();
void IncrementCurrentTagNumber();
void SetPtrDefErrorReported();
BOOL IsPtrDefErrorReported();
};
class nsa : public gplistmgr
{
short CurrentLevel;
public:
nsa(void);
~nsa(void) { };
STATUS_T PushSymLevel( class SymTable ** );
STATUS_T PopSymLevel( class SymTable ** );
short GetCurrentLevel( void );
class SymTable * GetCurrentSymbolTable( void );
};
#endif