|
|
// Copyright (c) 1993-1999 Microsoft Corporation
#ifndef __NODESKL_HXX__
#define __NODESKL_HXX__
#pragma warning ( disable : 4710 4706 )
#include "common.hxx"
#include "errors.hxx"
#include "midlnode.hxx"
#include "symtable.hxx"
#include "symtable.hxx"
#include "stream.hxx"
#include "prttype.hxx"
#include "expr.hxx"
#include "attrlist.hxx"
#include "linenum.hxx"
#include "freelist.hxx"
class node_guid;
/***
*** Here is the class hierarcy for the typegraph nodes. *** (last updated 6/22/95) ***/
/*
node_skl named_node \\nodes with siblings and names and attributes node_base_type node_def node_def_fe node_e_status_t node_echo_string node_pragma_pack node_field node_bitfield node_file node_forward node_href node_id node_id_fe \\ front-end version of node_id node_interface node_coclass node_dispinterface node_libarary node_module node_pipe_object node_interface_reference node_label node_param node_proc node_su_base node_enum node_struct node_en_struct node_union node_en_union node_wchar_t node_error node_source npa_nodes node_array node_pointer node_safearray
*/
/***
*** The base node type all the nodes in the typegraph are derived from. *** This is a virtual class; there are no nodes directly of this type. *** It is used to describe the routines used to walk the typegraph. ***/
// forward class declarations
class CG_CLASS; class XLAT_CTXT; class SEM_ANALYSIS_CTXT; class node_interface; class node_file; class gplistmgr;
extern unsigned short CurrentIntfKey;
enum TypeSet { ts_UnsignedFixedPoint, ts_FixedPoint, ts_FloatingPoint, ts_Character, ts_String, ts_Interface, };
class MODIFIER_SET { private: unsigned _int64 ModifierBits; // Modifier bits
unsigned short Align; // alignment from __declspec(align(N))
char * pUnknownTxt; // Text for unknown __declspec"
public: BOOL IsFlagAModifier(ATTR_T flag) const; BOOL IsModifierSet(ATTR_T flag) const; BOOL AnyModifiersSet() const; void SetModifier(ATTR_T flag); void ClearModifier(ATTR_T flag); void SetDeclspecAlign( unsigned short NewAlign); unsigned short GetDeclspecAlign() const; void SetDeclspecUnknown(char *pNewUnknownTxt); char *GetDeclspecUnknown() const; void Clear(); void Merge(const MODIFIER_SET & MergeModifierSet); void PrintDebugInfo() const; };
class INITIALIZED_MODIFIER_SET : public MODIFIER_SET { public: INITIALIZED_MODIFIER_SET() {Clear();} INITIALIZED_MODIFIER_SET( ATTR_T flag ) {Clear(); SetModifier( flag );} };
struct FRONT_MEMORY_INFO { unsigned long Size; // Size of the item
unsigned short Align; // Required memory alignment
BOOL IsMustAlign; // Has __declspec(align())
FRONT_MEMORY_INFO() : Size(0), Align(1), IsMustAlign(FALSE) { } FRONT_MEMORY_INFO(unsigned long NewSize, unsigned short NewAlign, BOOL NewIsMustAlign) : Size(NewSize), Align(NewAlign), IsMustAlign(NewIsMustAlign) { } void Init(unsigned long NewSize, unsigned short NewAlign, BOOL NewIsMustAlign ) { Size = NewSize; Align = NewAlign; IsMustAlign = NewIsMustAlign; } };
class node_skl { private:
node_skl * pChild; node_file * pTLBFile;
// ISSUE-2000/08/03-mikew
// The ia64 compiler is optimizing bitfields badly. The C guys said
// it will be fixed in the next drop.
#ifdef IA64
unsigned long Kind ;// : 8;
protected:
unsigned long MiscBits ;// : 8; // this field should be cleared by any
// class that uses it
private: unsigned long IntfKey ;// : 16;
#else // !IA64
unsigned long Kind : 8;
protected:
unsigned long MiscBits : 8; // this field should be cleared by any
// class that uses it
private: unsigned long IntfKey : 16; #endif
INITIALIZED_MODIFIER_SET ModiferSet;
public:
node_skl( ) { Kind = (unsigned long) NODE_ILLEGAL; pChild = NULL; IntfKey = CurrentIntfKey; pTLBFile = NULL; }
node_skl( NODE_T NodeKind, node_skl * pCh = NULL) { Kind = (unsigned long) NodeKind; pChild = pCh; IntfKey = CurrentIntfKey; pTLBFile = NULL; }
// lightweight version for backend use
node_skl( node_skl * pCh, NODE_T NodeKind ) { Kind = (unsigned long) NodeKind; pChild = pCh; IntfKey = 0; pTLBFile = NULL; }
virtual unsigned long GetInterfaceKey() { return IntfKey; };
virtual void SetInterfaceKey( unsigned long uIntfKey ) { IntfKey = uIntfKey; };
node_skl * GetChild() { return pChild; }
node_skl * SetChild(node_skl * pCh) { return pChild = pCh; }
node_skl * GetBasicType();
node_skl * GetNonDefChild() { node_skl * p = pChild; while ( p && p->NodeKind() == NODE_DEF ) p = p->GetChild(); return p; }
node_skl * GetNonDefSelf() { node_skl * p = this; while ( p->NodeKind() == NODE_DEF ) p = p->GetChild(); return p; }
node_skl * SetBasicType(node_skl * pBT) { return pChild = pBT; };
NODE_T NodeKind() { return (NODE_T) Kind; };
node_interface *GetMyInterfaceNode();
virtual node_file * GetDefiningFile();
virtual BOOL IsStringableType() { return FALSE; }
node_file * GetDefiningTLB() { return pTLBFile; }
void SetDefiningTLB(node_file *p) { pTLBFile = p; }
inline // see sneaky definition for this below named_node
char * GetSymName();
inline // see sneaky definition for this below named_node
char * GetCurrentSpelling();
MODIFIER_SET & GetModifiers() { return ModiferSet;} BOOL IsDef() { return ! GetModifiers().IsModifierSet(ATTR_TAGREF); };
void SetEdgeType( EDGE_T Et ) { if (Et == EDGE_USE) { GetModifiers().SetModifier( ATTR_TAGREF ); }; };
virtual BOOL FInSummary( ATTR_T ) { return FALSE; };
virtual BOOL HasAttributes() { return FALSE; }
virtual BOOL IsEncapsulatedStruct() { return FALSE; }
virtual BOOL IsEncapsulatedUnion() { return FALSE; }
virtual BOOL IsPtrOrArray() { return FALSE; }
virtual BOOL IsStructOrUnion() { return FALSE; }
virtual BOOL IsBasicType() { return FALSE; } // virtual
// bool IsCompatibleType( TypeSet )
// {
// return FALSE;
// }
virtual BOOL IsInterfaceOrObject() { return FALSE; }
FRONT_MEMORY_INFO AdjustMemoryInfoForModifiers(FRONT_MEMORY_INFO OrigInfo);
// For use by classes that just use the child memory size modified with
// modifiers.
FRONT_MEMORY_INFO GetModifiedMemoryInfoFromChild(); FRONT_MEMORY_INFO GetInvalidMemoryInfo();
virtual FRONT_MEMORY_INFO GetMemoryInfo() = 0;
unsigned long GetSize() { return GetMemoryInfo().Size; }
unsigned short GetAlign() { return GetMemoryInfo().Align; }
BOOL IsMustAlign() { return GetMemoryInfo().IsMustAlign; }
virtual void PrintMemoryInfo(ISTREAM *pStream, BOOL bNewLine);
virtual EXPR_VALUE ConvertMyKindOfValueToEXPR_VALUE( EXPR_VALUE value ) { return value; }
virtual void GetPositionInfo( tracked_node& ) { }
virtual STATUS_T DoPrintType( PRTFLAGS , BufferManager * , ISTREAM * , node_skl * , node_skl * ) { return STATUS_OK; }; virtual STATUS_T DoPrintDecl( PRTFLAGS , BufferManager * , ISTREAM * , node_skl * , node_skl * ) { return STATUS_OK; };
STATUS_T PrintType(PRTFLAGS Flags, ISTREAM * pStream, node_skl * pParent = NULL, node_skl * pIntf = NULL);
void EmitModifiers( BufferManager *, bool fSuppressConst);
void EmitProcModifiers( BufferManager *, PRTFLAGS );
void EmitModelModifiers( BufferManager *);
virtual void EmitPtrModifiers( BufferManager *, unsigned long ulFlags = 0 );
void CheckDeclspecAlign( SEM_ANALYSIS_CTXT & MyContext );
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
void * operator new ( size_t size ) { return AllocateOnceNew( size ); }
void operator delete( void * ptr ) { AllocateOnceDelete( ptr ); } virtual node_skl* GetDuplicateGuid ( node_guid*, SymTable* );
// returns true if context_handle attribute is present
// semantic checks for context handle
virtual bool CheckContextHandle( SEM_ANALYSIS_CTXT& );
}; // end of class node_skl
/***
*** Here are the direct descendents of node_skl; nodes with symtab entries *** and nodes without them ***/
// named nodes that can be on a list (have siblings)
class named_node : public node_skl { private: char * pName; char * pCurrentSpelling; class named_node *pSibling; class ATTRLIST AttrList; // attributes dangle from here
protected: unsigned int fBeingAnalyzed : 1;
public: // lightweight version for backend use
named_node( char * psz, NODE_T Kind ) : node_skl( NULL, Kind ), fBeingAnalyzed( FALSE ) { pCurrentSpelling = pName = psz; pSibling = NULL; AttrList.MakeAttrList(); };
named_node( NODE_T Kind, char * psz = NULL) : node_skl( Kind, NULL ), fBeingAnalyzed( FALSE ) { pCurrentSpelling = pName = psz; pSibling = NULL; AttrList.MakeAttrList(); };
// convert constructor (for node_id to other named_node)
named_node( NODE_T Kind, class named_node * pID ) : node_skl( Kind, pID->GetChild() ), fBeingAnalyzed( FALSE ) { pCurrentSpelling = pName = pID->pName; pSibling = pID->pSibling; AttrList = pID->AttrList; GetModifiers() = pID->GetModifiers(); };
virtual void CopyAttributes( named_node* pNode ) { AttrList = pNode->AttrList.Clone(); // Clone reverses the order of the list. Fix it.
AttrList.Reverse(); }
char * SetCurrentSpelling(char * sz) { return pCurrentSpelling = sz; }; char * SetSymName(char * psz) { return pName = psz; };
class named_node * GetSibling() { return pSibling; };
class named_node * SetSibling(named_node * pSib) { return pSibling = pSib; };
void SetAttributes( ATTRLIST & AList ) { AttrList = AList; };
void SetAttribute( ATTR_T bit ) { AttrList.Add( bit ); };
void SetAttribute( node_base_attr * attr ) { AttrList.Add( attr ); };
void AddAttributes( ATTRLIST & AList ) { AttrList.Merge( AList ); };
void RemoveAttribute( ATTR_T atrib ) { AttrList.Remove( atrib ); };
node_base_attr * GetAttribute( ATTR_T flag ) { return AttrList.GetAttribute( flag ); };
ATTRLIST & GetAttributeList( ATTRLIST & AList ) { return (AList = AttrList); }
void GetAttributeList( type_node_list * AList ) { AttrList.GetAttributeList( AList ); }
void DumpAttributes( ISTREAM * pStream );
virtual BOOL HasAttributes() { return AttrList.NonNull(); }
BOOL FInSummary( ATTR_T flag ) { BOOL result;
if ( GetModifiers().IsFlagAModifier(flag) ) { result = GetModifiers().IsModifierSet( flag ); } else { result = AttrList.FInSummary( flag ); }
return result; };
BOOL FMATTRInSummary( MATTR_T flag) { return AttrList.FMATTRInSummary(flag); };
BOOL FTATTRInSummary( TATTR_T flag) { return AttrList.FTATTRInSummary(flag); };
BOOL IsNamedNode();
virtual node_file * GetFileNode() { return NULL; }
virtual node_file * SetFileNode(node_file *) { return NULL; }
virtual char* GetDeclSpecGuid();
// to allow the below GetSymName to work
friend class node_skl;
}; // end of class named_node
inline char * node_skl::GetCurrentSpelling() { if ( IS_NAMED_NODE(NodeKind()) ) { return ((named_node *)this)->pCurrentSpelling; } else { return ""; } }
inline char * node_skl::GetSymName() { if ( IS_NAMED_NODE(NodeKind()) ) { return ((named_node *)this)->pName; } else { return ""; } }
class SIBLING_LIST;
class MEMLIST { protected: named_node * pMembers;
public: MEMLIST( named_node * pHead = NULL) { pMembers = pHead; };
MEMLIST( MEMLIST * pList ) { *this = *pList; };
void SetMembers( SIBLING_LIST & MemList );
STATUS_T GetMembers( class type_node_list * MemList );
node_skl * GetFirstMember() { return pMembers; }
void SetFirstMember( named_node * pNode ) { pMembers = pNode; }
short GetNumberOfArguments();
void AddLastMember( named_node * pNode );
void RemoveLastMember();
void AddFirstMember( named_node * pNode ) { pNode->SetSibling( pMembers ); pMembers = pNode; }
void RemoveFirstMember() { if (pMembers) pMembers = pMembers->GetSibling(); }
void AddSecondMember( named_node* pNode );
void MergeMembersToTail( SIBLING_LIST & MemList );
void MergeMembersToTail( MEMLIST & ML ) { AddLastMember( ML.pMembers ); }
void MergeMembersToHead( MEMLIST & ML ) { ML.MergeMembersToTail( *this ); pMembers = ML.pMembers; }
};
class MEM_ITER : public MEMLIST { private: named_node * pCur;
public: MEM_ITER( MEMLIST * pList ) : MEMLIST( pList ) { pCur = pMembers; }
named_node * GetNext() { named_node * Ret = pCur; pCur = (pCur) ? pCur->GetSibling() : NULL; return Ret; }
void Init() { pCur = pMembers; }
};
// identifiers
class node_id : public named_node { public: expr_node * pInit;
// lightweight version for backend
node_id( char * pNewName) : named_node( pNewName, NODE_ID ) { pInit = NULL; };
// heavier version for frontend
node_id( NODE_T Kind, char * pNewName) : named_node( Kind, pNewName ) { pInit = NULL; };
expr_node * GetInitList() { return pInit; };
expr_node * GetExpr() { return pInit; };
void SetExpr( expr_node * pExpr ) { pInit = pExpr; };
// these two functions are only valid after the defining declaration is complete
BOOL IsConstant() { return (BOOL) ( pInit && pInit->IsConstant() && (FInSummary( ATTR_CONST ) || IsConstantString() ) ); }
BOOL IsConstantString();
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual STATUS_T DoPrintDecl( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual FRONT_MEMORY_INFO GetMemoryInfo() {return GetModifiedMemoryInfoFromChild();}
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
// here is the use of the private memory allocator
private:
static FreeListMgr MyFreeList;
public:
void * operator new (size_t size) { return (MyFreeList.Get (size)); }
void operator delete (void * pX) { MyFreeList.Put (pX); }
}; // end of class node_id
// this is what a node_id generated in the front-end looks like
// it has tracking added
class node_id_fe : public node_id, public tracked_node { public: node_id_fe( char * pNewName) : node_id( NODE_ID, pNewName ) { };
virtual void GetPositionInfo( tracked_node & Posn ) { if (this->HasTracking() ) Posn = * ((tracked_node *) this); }
// here is the use of the private memory allocator
private:
static FreeListMgr MyFreeList;
public:
void * operator new (size_t size) { return (MyFreeList.Get (size)); }
void operator delete (void * pX) { MyFreeList.Put (pX); }
};
/***
*** named nodes *** *** These nodes may be constructed ***/
// enum labels
class node_label : public named_node { public: expr_node * pExpr;
node_label( char * LabelName, expr_node * pNewExpr ) : named_node( NODE_LABEL, LabelName ) { pExpr = pNewExpr; };
EXPR_VALUE GetValue() { return pExpr->GetValue(); }
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual FRONT_MEMORY_INFO GetMemoryInfo();
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_label
// handle types stored for node_def and node_param
// these are in order of increasing precedence as binding handles
#define HDL_NONE 0x00
#define HDL_CTXT 0x01
#define HDL_GEN 0x02
#define HDL_PRIM 0x04
// comm/fault status kind
#define STATUS_NONE 0
#define STATUS_COMM 1
#define STATUS_FAULT 2
#define STATUS_BOTH 3
class CG_PARAM;
// function formal parameters
class node_param : public named_node { private: BOOL fOptional : 1; // odl attribute
BOOL fRetval : 1; BOOL fLCID : 1; BOOL fExtraStatusParam : 1; // invisible fault or comm status
BOOL fIsAsyncHandle : 1; BOOL fGenDefaultValueExpr : 1; BOOL fSaveForAsyncFinish : 1; BOOL fHasCSSTag : 1; BOOL fHasCSDRTag : 1; BOOL fHasCSRTag : 1;
node_param* pAsyncBeginSibling; node_param* pAsyncFinishSibling; CG_PARAM* pCGParam;
public:
// the kind of handle, and whether it was applied to the
// param node directly, or to the TypeSpecifier
unsigned long HandleKind : 4; unsigned long fAppliedHere : 1; // true if the handle is an [in] handle
unsigned long fBindingParam : 1; // for below field: bits 1=>toplevel 2=>non-toplevel
unsigned long fDontCallFreeInst : 2; unsigned long Statuses : 2; // comm/fault statuses
// copy fields from the pID
node_param( node_id_fe * pID) : named_node( NODE_PARAM, pID ), fOptional ( 0 ), fLCID ( 0 ), fRetval ( 0 ), fExtraStatusParam ( 0 ), HandleKind ( 0 ), fAppliedHere ( 0 ), fBindingParam ( 0 ), fDontCallFreeInst ( 0 ), fIsAsyncHandle ( 0 ), fGenDefaultValueExpr( 0 ), Statuses ( STATUS_NONE ), pAsyncBeginSibling( 0 ), pAsyncFinishSibling( 0 ), fSaveForAsyncFinish( 0 ), fHasCSSTag ( 0 ), fHasCSDRTag ( 0 ), fHasCSRTag ( 0 ) { }
node_param() : named_node( NODE_PARAM ), fOptional ( 0 ), fLCID ( 0 ), fRetval ( 0 ), fExtraStatusParam ( 0 ), HandleKind ( 0 ), fAppliedHere ( 0 ), fBindingParam ( 0 ), fDontCallFreeInst ( 0 ), fIsAsyncHandle ( 0 ), fGenDefaultValueExpr( 0 ), Statuses ( STATUS_NONE ), pAsyncBeginSibling( 0 ), pAsyncFinishSibling( 0 ), fSaveForAsyncFinish( 0 ), fHasCSSTag ( 0 ), fHasCSDRTag ( 0 ), fHasCSRTag ( 0 ) { }
virtual CG_PARAM* GetCG() { return pCGParam; }
virtual void SetCG( CG_PARAM* pCG ) { pCGParam = pCG; }
virtual void SetAsyncBeginSibling( node_param* pParam ) { pAsyncBeginSibling = pParam; }; virtual node_param* GetAsyncBeginSibling( void ) { return pAsyncBeginSibling; };
virtual void SetAsyncFinishSibling( node_param* pParam ) { pAsyncFinishSibling = pParam; }; virtual node_param* GetAsyncFinishSibling( void ) { return pAsyncFinishSibling; };
virtual void SaveForAsyncFinish( void ) { fSaveForAsyncFinish = TRUE; }; virtual BOOL IsSaveForAsyncFinish( void ) { return fSaveForAsyncFinish; };
BOOL HasExplicitHandle() { return (HandleKind != HDL_NONE); }
unsigned short GetHandleKind() { return (unsigned short) HandleKind; }
BOOL IsBindingParam() { return ( fBindingParam ); }
BOOL IsExtraStatusParam() { return ( fExtraStatusParam ); }
void SetExtraStatusParam() { fExtraStatusParam = TRUE; }
BOOL IsAsyncHandleParam() { return ( fIsAsyncHandle ); }
void SetIsAsyncHandleParam() { fIsAsyncHandle = TRUE; }
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf ); virtual STATUS_T DoPrintDecl( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual FRONT_MEMORY_INFO GetMemoryInfo() {return GetModifiedMemoryInfoFromChild();}
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
void Optional(void) { fOptional = TRUE; }
BOOL IsOptional(void) { return fOptional; }
void Retval(void) { fRetval = TRUE; }
BOOL IsRetval(void) { return fRetval; }
void LCID(void) { fLCID = TRUE; }
BOOL IsLCID(void) { return fLCID; }
void GenDefaultValueExpr( BOOL fGen = TRUE ) { fGenDefaultValueExpr = fGen; }
BOOL HasGenDefaultValueExpr( void ) { return fGenDefaultValueExpr; }
void SetHasCSSTag() { fHasCSSTag = TRUE; }
void SetHasCSDRTag() { fHasCSDRTag = TRUE; }
void SetHasCSRTag() { fHasCSRTag = TRUE; }
BOOL HasCSTag() { return fHasCSSTag | fHasCSRTag | fHasCSDRTag; } }; // end of class node_param
class CG_PROC;
// imported files
class node_file : public named_node, public MEMLIST { private: char * pActualFileName; short ImportLevel; BOOL fAcfInclude : 1; BOOL fIsXXXBaseIdl : 1; BOOL fHasComClasses : 1;
public: node_file( char *, short );
short GetImportLevel() { return ImportLevel; }
char * GetFileName() { return pActualFileName; }
BOOL AcfExists(); void AcfName( char * ); void SetFileName( char * ); BOOL IsAcfInclude() { return fAcfInclude; }
BOOL HasComClasses() { return fHasComClasses; }
BOOL SetHasComClasses( BOOL yes = TRUE ) { return (fHasComClasses = yes); }
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual FRONT_MEMORY_INFO GetMemoryInfo() {return GetInvalidMemoryInfo();};
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
void SetXXXBaseIdl() { fIsXXXBaseIdl = TRUE; }
BOOL IsXXXBaseIdl() { return fIsXXXBaseIdl; }
}; // end of class node_file
// functions and procs
class node_proc : public named_node, public tracked_node, public MEMLIST { unsigned long ProcNum : 16; unsigned long OptimFlags : 8; unsigned long ImportLevel : 4; unsigned long fHasFullPointer : 1; unsigned long fHasAtLeastOneIn : 1; unsigned long fHasAtLeastOneOut : 1; unsigned long fHasExplicitHandle : 1; unsigned long fHasPointer : 1; // ANYWHERE below us
unsigned long fHasStatuses : 1; // has comm/fault status
unsigned long fHasExtraStatusParam: 1; // has the "invisible" status param
unsigned long fCallAsTarget : 1; // the target of a call_as
unsigned long RTStatuses : 2; // return type statuses
unsigned long fHasPipes : 1; unsigned long fForcedI2 : 1; // true if -Oi2 mode has been forced
unsigned long fForcedS : 1; // true if -Os mode has been forced
unsigned long fHasAsyncHandle : 1; unsigned long fHasDeny : 1; // true on /deny
unsigned long fHasServerCorr : 1; // correlation on Server
unsigned long fHasClientCorr : 1; // correlation on Client
unsigned long fHasAsyncUUID : 1; // async_uuid
unsigned long fIsBeginProc : 1; // Begin_*
unsigned long fIsFinishProc : 1; // Finish_*
unsigned long fObjectProc : 1; // object proc
unsigned long ulServerCorrCount; unsigned long ulClientCorrCount; class node_proc * pCallAsType; // if this is a call_as function
// then this pointer will be set to
// points to its companion during
// semantic analysis
node_proc* pBeginProc;
node_proc* pCSTagRoutine; // from [cs_tag_rtn]
OPT_LEVEL_ENUM OptimLevel;
public: node_proc( short level, BOOL ) : named_node ( NODE_PROC ), ProcNum ( 0xffff ), OptimFlags ( 0 ), ImportLevel ( ( level > 15 ) ? 15 : level ), fHasAtLeastOneIn ( FALSE ), fHasAtLeastOneOut ( FALSE ), fHasExplicitHandle ( FALSE ), fHasPointer ( FALSE ), fHasFullPointer ( FALSE ), fHasStatuses ( FALSE ), fHasExtraStatusParam ( FALSE ), fCallAsTarget ( FALSE ), RTStatuses ( STATUS_NONE ), fHasPipes ( FALSE ), fForcedI2 ( FALSE ), fForcedS ( FALSE ), fHasAsyncHandle ( FALSE ), pCallAsType ( NULL ), OptimLevel ( OPT_LEVEL_OS ), fHasDeny ( FALSE ), fHasServerCorr ( FALSE ), fHasClientCorr ( FALSE ), fHasAsyncUUID ( FALSE ), fIsBeginProc ( FALSE ), fIsFinishProc ( FALSE ), ulClientCorrCount ( 0 ), ulServerCorrCount ( 0 ), pBeginProc ( 0 ), pCSTagRoutine ( 0 ), fObjectProc ( FALSE ) { }
node_proc( short level, BOOL , node_id_fe * pID) : named_node ( NODE_PROC, pID ), ProcNum ( 0xffff ), OptimFlags ( 0 ), ImportLevel ( ( level > 15 ) ? 15 : level ), fHasAtLeastOneIn ( FALSE ), fHasAtLeastOneOut ( FALSE ), fHasExplicitHandle ( FALSE ), fHasPointer ( FALSE ), fHasFullPointer ( FALSE ), fHasStatuses ( FALSE ), fHasExtraStatusParam ( FALSE ), fCallAsTarget ( FALSE ), RTStatuses ( STATUS_NONE ), fHasPipes ( FALSE ), fForcedI2 ( FALSE ), fForcedS ( FALSE ), fHasAsyncHandle ( FALSE ), pCallAsType ( NULL ), OptimLevel ( OPT_LEVEL_OS ), fHasDeny ( FALSE ), fHasServerCorr ( FALSE ), fHasClientCorr ( FALSE ), fHasAsyncUUID ( FALSE ), fIsBeginProc ( FALSE ), fIsFinishProc ( FALSE ), ulClientCorrCount ( 0 ), ulServerCorrCount ( 0 ), pBeginProc ( 0 ), pCSTagRoutine ( 0 ), fObjectProc ( FALSE ) { }
node_proc( node_proc * pClone ) : named_node( NODE_PROC ) { *this = *pClone; }
BOOL IsObjectProc() { return fObjectProc; }; void SetObjectProc( BOOL fObject = TRUE ) { fObjectProc = fObject; };
node_proc* GetBeginProc() { return pBeginProc; }
void SetBeginProc( node_proc* pBegin ) { pBeginProc = pBegin; }
node_proc * SetCallAsType(node_proc *p) { return (pCallAsType = p); } node_proc * GetCallAsType() { return (pCallAsType); }
STATUS_T GetParameterList( class type_node_list * MemList ) { return GetMembers( MemList ); };
node_skl * GetReturnType() { return GetChild(); };
short GetImportLevel() { return (short) ImportLevel; }
unsigned short GetOptimizationFlags() { return (unsigned short)OptimFlags; }
unsigned short SetOptimizationFlags( unsigned short OF ) { return (unsigned short)(OptimFlags = OF); }
OPT_LEVEL_ENUM GetOptimizationLevel() { return (OPT_LEVEL_ENUM) OptimLevel; }
OPT_LEVEL_ENUM SetOptimizationLevel( OPT_LEVEL_ENUM Level ) { return OptimLevel = Level; }
BOOL ForceNonInterpret();
BOOL ForceInterpret2();
void AddStatusParam( char * pName, ATTRLIST Alist );
void AddExplicitHandle ( SEM_ANALYSIS_CTXT* pParentCtxt, unsigned int uParamNumber = 1 ); void AddFullAsyncHandle ( SEM_ANALYSIS_CTXT* pParentCtxt, node_skl* pType, char* szType );
// returns ATTR_NONE if none explicitly specified
BOOL GetCallingConvention( ATTR_T & Attr );
BOOL HasPipes() { return fHasPipes; }
BOOL HasAtLeastOneIn() { return fHasAtLeastOneIn; };
BOOL HasAtLeastOneOut() { return fHasAtLeastOneOut; };
BOOL HasExplicitHandle() { return fHasExplicitHandle; };
BOOL HasAtLeastOneHandle() { // for now....
return fHasExplicitHandle; };
BOOL SetHasExtraStatusParam() { return fHasExtraStatusParam = TRUE; }
BOOL HasExtraStatusParam() { return fHasExtraStatusParam; }
BOOL HasPointer() { return fHasPointer; };
BOOL IsCallAsTarget() { return fCallAsTarget; }
BOOL HasAtLeastOneShipped();
BOOL HasReturn() { node_skl * pCh = GetNonDefChild(); return (pCh) && (pCh->NodeKind() != NODE_VOID); };
void SetHasAsyncHandle() { fHasAsyncHandle = TRUE; } BOOL HasAsyncHandle() { return fHasAsyncHandle; }
void SetHasAsyncUUID() { fHasAsyncUUID = TRUE; } BOOL HasAsyncUUID() { return fHasAsyncUUID; }
void SetHasServerCorr() { fHasServerCorr = TRUE; } BOOL HasServerCorr() { return fHasServerCorr; }
void SetHasClientCorr() { fHasClientCorr = TRUE; } BOOL HasClientCorr() { return fHasClientCorr; }
void SetIsBeginProc() { fIsBeginProc = TRUE; } BOOL IsBeginProc() { return fIsBeginProc; }
void SetIsFinishProc() { fIsFinishProc = TRUE; } BOOL IsFinishProc() { return fIsFinishProc; }
BOOL HasAParameter() { // check if the first one is different from void
node_skl * pParam = GetFirstMember();
if ( !pParam || pParam->NodeKind() == NODE_VOID ) return FALSE;
if ( pParam->NodeKind() == NODE_DEF ) { node_skl * pCh = pParam->GetNonDefChild(); if ( !pCh || pCh->NodeKind() == NODE_VOID ) return FALSE; }
return TRUE; };
node_param * GetParamNode( char * pName ) { node_param * pCur = (node_param *) GetFirstMember();
while ( pCur ) { if ( strcmp( pCur->GetSymName(), pName ) == 0 ) return pCur; pCur = (node_param *) pCur->GetSibling(); }
return NULL; }
virtual FRONT_MEMORY_INFO GetMemoryInfo() {return GetReturnType()->GetMemoryInfo();}
virtual void GetPositionInfo( tracked_node & Posn ) { if (this->HasTracking() ) Posn = * ((tracked_node *) this); }
virtual unsigned long GetServerCorrelationCount() { return ulServerCorrCount; }
virtual unsigned long GetClientCorrelationCount() { return ulClientCorrCount; }
virtual void SetServerCorrelationCount( unsigned long ulCount = 0 ) { ulServerCorrCount = ulCount; }
virtual void SetClientCorrelationCount( unsigned long ulCount = 0 ) { ulClientCorrCount = ulCount; }
virtual void IncServerCorrelationCount( unsigned long ulInc ) { ulServerCorrCount += ulInc; }
virtual void IncClientCorrelationCount( unsigned long ulInc ) { ulClientCorrCount += ulInc; }
void SetCSTagRoutine(node_proc *p) { pCSTagRoutine = p; }
node_proc * GetCSTagRoutine() { return pCSTagRoutine; } virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf ); virtual STATUS_T DoPrintDecl( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext ); }; // end of class node_proc
class SymTable;
// forward declarations -- may go away
class node_forward : public named_node, public tracked_node { SymKey SKey; SymTable * pSymTbl;
public: node_forward( SymKey key, SymTable * pTbl ) : named_node( NODE_FORWARD ) { SKey = key; pSymTbl = pTbl; pTbl->SetHasFwds(); MiscBits = 0; };
named_node * ResolveFDecl();
void GetSymDetails( NAME_T * nm, char ** ppszName);
BOOL IsFirstPass() { return ( MiscBits == 0 ); }
void MarkSecondPass() { MiscBits = 1; }
void MarkFirstPass() { MiscBits = 0; }
virtual FRONT_MEMORY_INFO GetMemoryInfo() {return GetInvalidMemoryInfo();} virtual void GetPositionInfo( tracked_node & Posn ) { if (this->HasTracking() ) Posn = * ((tracked_node *) this); }
virtual STATUS_T DoPrintDecl( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
};
// reference to a type defined in an importlib
class node_href : public named_node, public tracked_node { SymKey SKey; SymTable * pSymTbl; void * pTypeInfo; node_file * pFile;
public: node_href( SymKey key, SymTable * pTbl, void * pti, node_file * pf) : named_node( NODE_HREF, key.GetString() ) { SKey = key; pSymTbl = pTbl; pTbl->SetHasFwds(); MiscBits = 0; pTypeInfo = pti; pFile = pf; };
~node_href();
named_node * Resolve();
void GetSymDetails( NAME_T * pTag, char ** ppszName) { *pTag = SKey.GetKind(); *ppszName = SKey.GetString(); };
virtual STATUS_T DoPrintDecl( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual FRONT_MEMORY_INFO GetMemoryInfo();
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
virtual node_file * GetDefiningFile() { return pFile; };
};
// fields in structures
class node_field : public named_node { public: node_field( char * pNewName = NULL ) : named_node( NODE_FIELD, pNewName ) { MiscBits = 0; };
node_field( node_id_fe * pId ) : named_node( NODE_FIELD, pId ) { MiscBits = 0; };
BOOL HasUnknownRepAs() { return (BOOL) MiscBits & 1; };
BOOL SetHasUnknownRepAs() { return (BOOL) (MiscBits |= 1); };
BOOL IsEmptyArm() { return (GetChild()->NodeKind() == NODE_ERROR); };
BOOL IsLastField() { return !(GetSibling()); };
virtual BOOL IsBitField() { return FALSE; }
virtual short GetFieldSize() { return 0; };
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual FRONT_MEMORY_INFO GetMemoryInfo() {return GetModifiedMemoryInfoFromChild();}
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_field
// bitfields in structures
class node_bitfield : public node_field { public: unsigned char fBitField;
node_bitfield( char * pNewName = NULL) : node_field( pNewName ) { fBitField = 0; };
node_bitfield( node_id_fe * pId ) : node_field( pId ) { fBitField = 0; };
virtual BOOL IsBitField() { return TRUE; }
virtual short GetFieldSize() { return fBitField; };
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_bitfield
// bits for different kinds of arrays as fields.
// if more than one bit is set, it is a complex array
#define FLD_PLAIN 0x0
#define FLD_VAR 0x1
#define FLD_CONF 0x2
#define FLD_CONF_VAR 0x4
#define FLD_COMPLEX 0x8 // don't check for equality here!
// structures and unions, and enums, too
class node_su_base : public named_node, public tracked_node, public MEMLIST { protected: unsigned long ZeePee : 16; unsigned long Complexity : 8; unsigned long fHasAtLeastOnePointer : 1; unsigned long fSemAnalyzed : 1; unsigned long fHasConformance : 1; char * szTypeInfoName;
public: node_su_base( NODE_T Kind, char * pName ) : named_node( Kind, pName ) { fHasAtLeastOnePointer = 0; ZeePee = 0; Complexity = 0; fSemAnalyzed = 0; fHasConformance = 0; szTypeInfoName = pName; };
unsigned short SetZeePee( unsigned short zp ) { return (unsigned short) (ZeePee = zp); };
unsigned short GetZeePee() { return (unsigned short) ZeePee; };
unsigned short SetHasAtLeastOnePointer( unsigned short HP ) { return (unsigned short) (fHasAtLeastOnePointer = HP); };
unsigned short HasAtLeastOnePointer() { return (unsigned short) fHasAtLeastOnePointer; };
virtual void GetPositionInfo( tracked_node & Posn ) { if (this->HasTracking() ) Posn = * ((tracked_node *) this); }
BOOL HasConformance() { return fHasConformance; }
void CheckLegalParent(SEM_ANALYSIS_CTXT & MyContext); void SetTypeInfoName(char * szName) { szTypeInfoName = szName; } char * GetTypeInfoName(void) { return szTypeInfoName; } }; // end of class node_su_base
// enum and its tag
class node_enum : public node_su_base { BOOL fLong : 1; public:
node_enum ( char* pTagName ) : node_su_base( NODE_ENUM, pTagName ), fLong( FALSE ) { }
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual STATUS_T DoPrintDecl( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual FRONT_MEMORY_INFO GetMemoryInfo();
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_enum
// structures
class node_struct : public node_su_base { public: node_struct( char * pNewName ) : node_su_base( NODE_STRUCT, pNewName ) { };
virtual BOOL IsEncapsulatedStruct() { return FALSE; }
virtual BOOL IsStructOrUnion() { return TRUE; }
virtual BOOL IsStringableType();
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf ); virtual STATUS_T DoPrintDecl( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual FRONT_MEMORY_INFO GetMemoryInfo();
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_struct
class node_en_struct : public node_struct { public: node_en_struct( char * pNewName ) : node_struct( pNewName ) { };
BOOL IsEncapsulatedStruct() { return TRUE; }
node_skl * GetSwitchField() { return GetFirstMember(); }
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_en_struct
// unions
class node_union : public node_su_base { public: node_union( char * pNewName ) : node_su_base( NODE_UNION, pNewName ) { };
virtual BOOL IsStructOrUnion() { return TRUE; }
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf ); virtual STATUS_T DoPrintDecl( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual FRONT_MEMORY_INFO GetMemoryInfo();
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_union
class node_en_union : public node_union { public: node_en_union( char * pNewName ) : node_union( pNewName ) { };
virtual BOOL IsEncapsulatedUnion() { return TRUE; }
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_en_union
#define HANDLE_KIND_MASK 0x7
#define HRESULT_FLAG_MASK 0x8
// typedef entries
class node_def : public named_node {
public: // (lightweight version) make a typedef with a given name
node_def( char * pName = NULL) : named_node( pName, NODE_DEF ) { SetHandleKind( HDL_NONE ); };
// make a typedef with a given name and child
node_def( char * pName, node_skl * pChld ) : named_node( NODE_DEF, pName ) { MiscBits = 0; SetHandleKind( HDL_NONE ); SetChild( pChld ); };
// make a typedef cloned from a node_id
node_def( node_id_fe * pIdent ) : named_node( NODE_DEF, pIdent ) { MiscBits = 0; SetHandleKind( HDL_NONE ); };
// make a typedef node for (above) a proc
node_def( node_proc * pProc ) : named_node( NODE_DEF, (node_id_fe *) pProc ) { MiscBits = 0; SetChild( pProc ); SetHandleKind( HDL_NONE ); };
unsigned long GetHandleKind() { return MiscBits & HANDLE_KIND_MASK; }
unsigned long SetHandleKind( unsigned long H ) { MiscBits = ( MiscBits & ~HANDLE_KIND_MASK ) | H; return H; }
void SetIsHResultOrSCode() { MiscBits |= HRESULT_FLAG_MASK; }
BOOL IsHResultOrSCode() { return ( MiscBits & HRESULT_FLAG_MASK ) != 0; }
BOOL HasAnyHandleSpecification() { return (GetHandleKind() != HDL_NONE); };
BOOL HasAnyCtxtHdlSpecification() { return (GetHandleKind() == HDL_CTXT); };
// return the transmit_as type (or NULL)
node_skl * GetTransmittedType();
// return the represent_as type (or NULL)
char * GetRepresentationName();
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf ); virtual STATUS_T DoPrintDecl( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
void MarkDontCallFreeInst( SEM_ANALYSIS_CTXT * pCtxt );
virtual FRONT_MEMORY_INFO GetMemoryInfo();
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
void node_def::SemanticAnalysisForTransmit( SEM_ANALYSIS_CTXT *pMyContext, BOOL fPresented );
void node_def::SemanticAnalysisForWireMarshal( SEM_ANALYSIS_CTXT *pMyContext, BOOL fPresented ); virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_def
// front-end only version of node_def ( adds line number tracking )
class node_def_fe : public node_def, public tracked_node { public: // make a typedef with a given name and child
node_def_fe( char * pName, node_skl * pChld ) : node_def( pName, pChld ) { }
// make a typedef cloned from a node_id
node_def_fe( node_id_fe * pIdent ) : node_def( pIdent ) { }
// make a typedef node for (above) a proc
node_def_fe( node_proc * pProc ) : node_def( pProc ) { };
virtual void GetPositionInfo( tracked_node & Posn ) { if (this->HasTracking() ) Posn = * ((tracked_node *) this); }
}; // end of class node_def_fe
typedef struct tagIDLISTMEM { struct tagIDLISTMEM * pNext; char * szName; __int64 lId; } IDLISTMEM;
// class for checking for duplicate dispatch ids
class CIDLIST { private: IDLISTMEM * pHead; public: CIDLIST() { pHead = NULL; };
~CIDLIST() { while (pHead) { IDLISTMEM * pThis = pHead; pHead = pHead->pNext; delete pThis; } };
BOOL AddId(__int64 lId, char * szName); };
// the interface
class node_interface : public named_node, public MEMLIST, public tracked_node { protected:
named_node * pBaseIntf; // base interface if derived intf
node_file * pDefiningFile; CG_CLASS * pMyCG; CG_CLASS * pMyTlbCG; // CG node generated in library block
SymTable * pProcTbl; unsigned short ProcCount; unsigned short CallBackProcCount; unsigned short OptimFlags; OPT_LEVEL_ENUM OptimLevel; BOOL fIAmIUnknown : 1; BOOL fPickle : 1; BOOL fHasProcsWithRpcSs : 1; BOOL fSemAnalyzed : 1; BOOL fPrintedDef : 1; BOOL fPrintedIID : 1; BOOL fHasOLEAutomation : 1; BOOL fIsAsyncClone : 1; BOOL fHasMSConfStructAttr: 1; BOOL fIs2ndCodegen : 1; CIDLIST IdList; node_interface* pAsyncInterface;
void ResetCGIfNecessary();
public: node_interface( NODE_T Kind = NODE_INTERFACE );
unsigned short &GetProcCount() { return ProcCount; }
unsigned short &GetCallBackProcCount() { return CallBackProcCount; }
void GetVersionDetails( unsigned short * Maj, unsigned short * Min );
BOOL AddId(__int64 lId, char * szName) { return IdList.AddId(lId, szName); } virtual BOOL IsAsyncClone() { return fIsAsyncClone; }
virtual void SetIsAsyncClone() { fIsAsyncClone = TRUE; }
virtual BOOL IsInterfaceOrObject() { return TRUE; }
BOOL IsValidRootInterface() { return fIAmIUnknown; }
void SetValidRootInterface() { fIAmIUnknown = TRUE; }
BOOL IsPickleInterface() { return fPickle; }
void SetPickleInterface() { fPickle = TRUE; }
BOOL GetHasProcsWithRpcSs() { return fHasProcsWithRpcSs; }
virtual node_file * GetDefiningFile() { return pDefiningFile; }
void SetHasProcsWithRpcSs() { fHasProcsWithRpcSs = TRUE; }
BOOL PrintedDef() { return fPrintedDef; } void SetPrintedDef() { fPrintedDef = TRUE; }
BOOL PrintedIID() { return fPrintedIID; } void SetPrintedIID() { fPrintedIID = TRUE; }
node_interface *GetMyBaseInterface();
// note that my base interface reference may be
// a fwd or null
named_node * GetMyBaseInterfaceReference() { return pBaseIntf; }
named_node * SetMyBaseInterfaceReference( named_node * pIF ) { return (pBaseIntf = pIF); }
virtual node_file * GetFileNode() { return pDefiningFile; }
virtual node_file * SetFileNode(node_file * pF) { return (pDefiningFile = pF); }
CG_CLASS * GetCG(BOOL fInLibrary) { ResetCGIfNecessary(); if (fInLibrary) return pMyTlbCG; else return pMyCG; }
CG_CLASS * SetCG(BOOL fInLibrary, CG_CLASS * pF) { if (fInLibrary) return (pMyTlbCG = pF); else return (pMyCG = pF); }
SymTable * GetProcTbl() { return pProcTbl; }
SymTable * SetProcTbl( SymTable * pS ) { return (pProcTbl = pS); }
unsigned short GetOptimizationFlags() { return OptimFlags; }
unsigned short SetOptimizationFlags(unsigned short F) { return (OptimFlags = F); }
OPT_LEVEL_ENUM GetOptimizationLevel() { return (OPT_LEVEL_ENUM) OptimLevel; }
OPT_LEVEL_ENUM SetOptimizationLevel( OPT_LEVEL_ENUM Level ) { return OptimLevel = Level; }
virtual FRONT_MEMORY_INFO GetMemoryInfo() {return GetInvalidMemoryInfo();}
virtual void GetPositionInfo( tracked_node & Posn ) { if (this->HasTracking() ) Posn = * ((tracked_node *) this); }
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext ); virtual BOOL HasOLEAutomation() { return fHasOLEAutomation; }; virtual void HasOLEAutomation(BOOL fHas) { fHasOLEAutomation = fHas; };
virtual node_interface* GetAsyncInterface() { return pAsyncInterface; }; virtual void SetAsyncInterface( node_interface* pIF ) { pAsyncInterface = pIF; };
}; // end of class node_interface
class node_pipe;
// the interface
class node_interface_reference : public named_node { private:
public: node_interface_reference( node_interface * pIntf ) : named_node( NODE_INTERFACE_REFERENCE ) { SetChild( pIntf ); SetSymName( pIntf->GetSymName() ); }
node_interface *GetRealInterface() { return (node_interface *)GetChild(); }
named_node * GetMyBaseInterfaceReference() { return ((node_interface *)GetChild())-> GetMyBaseInterfaceReference(); }
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual STATUS_T DoPrintDecl( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual FRONT_MEMORY_INFO GetMemoryInfo( ) { return GetInvalidMemoryInfo();}
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_interface_reference
/***
*** unnamed nodes ***/
// the root of the typegraph
class node_source : public node_skl, public MEMLIST { public:
node_source() : node_skl( NODE_SOURCE, NULL ) { }
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual FRONT_MEMORY_INFO GetMemoryInfo() {return GetInvalidMemoryInfo();};
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_source
// pointers and arrays
class npa_nodes : public node_skl {
unsigned long fHasCSType : 1; // An array of international chars
public: npa_nodes( NODE_T Kind ) : node_skl( Kind, NULL ) { fHasCSType = FALSE; };
void SetHasCSType() { fHasCSType = TRUE; }
BOOL HasCSType() { return fHasCSType; }
BOOL FInSummary( ATTR_T flag ) { BOOL result;
if ( flag >= ATTR_CPORT_ATTRIBUTES_START && flag <= ATTR_CPORT_ATTRIBUTES_END) { result = GetModifiers().IsModifierSet( flag ); } else { result = FALSE; }
return result; };
BOOL IsPtrOrArray() { return TRUE; }
}; // end of class npa_nodes
// pointers
class node_pointer : public npa_nodes { private:
public: // constructors
node_pointer() : npa_nodes( NODE_POINTER ) { }
node_pointer(node_skl * pChild) : npa_nodes( NODE_POINTER ) { SetChild(pChild); }
virtual FRONT_MEMORY_INFO GetMemoryInfo();
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf ); virtual STATUS_T DoPrintDecl( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_pointer
// array
class node_array : public npa_nodes { expr_node * pUpperBound; expr_node * pLowerBound; unsigned long fConformant : 1; unsigned long fMaybeVarying : 1; // set during semantic analysis
unsigned long fHasPointer : 1;
public: node_array( expr_node * pLower, expr_node * pUpper ) : npa_nodes( NODE_ARRAY ) { pUpperBound = pUpper; pLowerBound = pLower; fMaybeVarying = TRUE; fConformant = (pUpper == (expr_node *) -1); fHasPointer = FALSE; }
BOOL HasPointer() { return fHasPointer; };
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf ); virtual STATUS_T DoPrintDecl( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual FRONT_MEMORY_INFO GetMemoryInfo();
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_array
// misc strings to echo directly
class node_echo_string : public named_node { protected: char * pString;
public: node_echo_string( char * pStr ) : named_node( NODE_ECHO_STRING ) { pString = pStr; SetChild( NULL ); };
char * GetEchoString() { return pString; };
virtual void PrintSelf( ISTREAM * pStream );
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual FRONT_MEMORY_INFO GetMemoryInfo() {return GetInvalidMemoryInfo();}
virtual void PrintMemoryInfo( ISTREAM *pStream, BOOL bNewLine ); virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_echo_string
// #pragma pack(...) string node
#define PRAGMA_PACK_GARBAGE 0
#define PRAGMA_PACK_PUSH 1
#define PRAGMA_PACK_POP 2
#define PRAGMA_PACK_SET 3
#define PRAGMA_PACK_RESET 4
class node_pragma_pack : public node_echo_string { private:
node_pragma_pack * pStackLink; unsigned short PackType; unsigned short usPackingLevel; unsigned short usNewLevel;
public:
node_pragma_pack( char * ID, unsigned short lvl, unsigned short PT, unsigned short nlvl = 0 ) : node_echo_string( ID ) { usPackingLevel = lvl; PackType = PT; usNewLevel = nlvl; }
unsigned short GetZeePee() { return usPackingLevel; }
// link self on as new top node
void Push( node_pragma_pack *& pTop );
// search for matching push and pop it off, returning new ZP
unsigned short Pop( node_pragma_pack *& pTop );
virtual void PrintSelf( ISTREAM * pStream );
};
class node_e_status_t : public named_node { public: node_e_status_t();
void VerifyParamUsage( SEM_ANALYSIS_CTXT * pCtxt );
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual STATUS_T DoPrintDecl( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual FRONT_MEMORY_INFO GetMemoryInfo() {return GetModifiedMemoryInfoFromChild();}
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_e_status_t
// error status -- may go away
class node_error : public node_skl { public: node_error() : node_skl( NODE_ERROR, NULL ) { }
virtual FRONT_MEMORY_INFO GetMemoryInfo() {return GetInvalidMemoryInfo();}
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_error
// Flag if the variable is used in a size_is, etc expression, and wether or not
// it's a cs_char array expression
enum SIZE_LENGTH_USAGE { NoSizeLengthUsage, CSSizeLengthUsage, NonCSSizeLengthUsage };
// base types e.g. char, long
class node_base_type : public named_node { // SIZE_LENGTH_USAGE SizeLengthUsage;
public: node_base_type( NODE_T MyKind, ATTR_T attr ) : named_node( MyKind ) { if ( attr != ATTR_NONE ) GetModifiers().SetModifier( attr );
// SizeLengthUsage = NoSizeLengthUsage;
};
node_base_type( const node_base_type * pOriginal ) : named_node( NODE_ILLEGAL ) { *this = *pOriginal; } virtual BOOL IsBasicType() { return TRUE; }
virtual BOOL IsStringableType() { return ( NodeKind() == NODE_CHAR ) || ( NodeKind() == NODE_BYTE ); }
BOOL IsAssignmentCompatible( node_base_type * ); // bool IsCompatibleType( TypeSet set ); Nishad
/*
BUGBUG: CG_INTERFACE_POINTER has a bug where it will case a node_base_type to a node_interface for QI. It just happens to work at the momement but when the size for node_base_type is increased it causes the TLB code to AV. Put this back when that is fixed. -- MikeW
SIZE_LENGTH_USAGE GetSizeLengthUsage() { return SizeLengthUsage; } void SetSizeLengthUsage( SIZE_LENGTH_USAGE usage ) { SizeLengthUsage = usage; } */ BOOL RangeCheck( __int64 Val );
BOOL IsUnsigned();
virtual EXPR_VALUE ConvertMyKindOfValueToEXPR_VALUE( __int64 EXPR_VALUE );
void CheckVoidUsage( SEM_ANALYSIS_CTXT * pContext );
void CheckVoidUsageInDispinterface( SEM_ANALYSIS_CTXT * pContext );
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf ); virtual STATUS_T DoPrintDecl( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual FRONT_MEMORY_INFO GetMemoryInfo();
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_base_type
// character width specifier
class node_wchar_t : public named_node { public: node_wchar_t();
virtual BOOL IsStringableType() { return TRUE; }
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual STATUS_T DoPrintDecl( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual FRONT_MEMORY_INFO GetMemoryInfo() {return GetModifiedMemoryInfoFromChild();}
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_wchar_t
class node_library : public node_interface { private: public: node_library() : node_interface( NODE_LIBRARY ) { }
virtual void GetPositionInfo( tracked_node & Posn ) { if (this->HasTracking() ) Posn = * ((tracked_node *) this); }
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
virtual node_file * SetFileNode(node_file * pF) { named_node * pN; MEM_ITER MemIter(this); while ( pN = MemIter.GetNext() ) { pN->SetFileNode( pF ); } return (pDefiningFile = pF); } }; // end of class node_library
class node_coclass : public node_interface { private: BOOL fNotCreatable;
protected:
public: node_coclass() : node_interface( NODE_COCLASS ) { fNotCreatable = FALSE; }
virtual void GetPositionInfo( tracked_node & Posn ) { if (this->HasTracking() ) Posn = * ((tracked_node *) this); }
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual STATUS_T DoPrintDecl( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
BOOL IsNotCreatable(void) { return fNotCreatable; }
BOOL SetNotCreatable(BOOL f) { return (fNotCreatable = f); }
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_coclass
class node_module : public node_interface { private:
protected:
public: node_module() : node_interface( NODE_MODULE ) { }
virtual void GetPositionInfo( tracked_node & Posn ) { if (this->HasTracking() ) Posn = * ((tracked_node *) this); }
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_module
class node_dispinterface : public node_interface { named_node * pDispatch; protected:
public: node_dispinterface() : node_interface( NODE_DISPINTERFACE ) { }
virtual void GetPositionInfo( tracked_node & Posn ) { if (this->HasTracking() ) Posn = * ((tracked_node *) this); }
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf ); virtual STATUS_T DoPrintDecl ( PRTFLAGS Flags, BufferManager* pBuffer, ISTREAM* pStream, node_skl* pParent, node_skl* pIntf );
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
named_node * GetIDispatch() { return pDispatch; } }; // end of class node_dispinterface
#define SZ_ASYNCPIPEDEFPREFIX "ASYNC_"
class node_pipe : public named_node { private: bool fGenAsyncPipeFlavor;
protected: bool GenAsyncPipeFlavor() { return fGenAsyncPipeFlavor; } void SetGenAsyncPipeFlavor( bool fGen = true ) { fGenAsyncPipeFlavor = fGen; } STATUS_T PrintDeclaration( PRTFLAGS Flags, BufferManager* pBuffer, ISTREAM* pStream, node_skl* pParent, node_skl* pIntf, char* szPrefix ); public: // constructors
node_pipe() : named_node( NODE_PIPE ), fGenAsyncPipeFlavor( false ) { }
node_pipe(node_skl * pType) : named_node( NODE_PIPE ), fGenAsyncPipeFlavor( false ) { SetChild(pType); }
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual STATUS_T DoPrintDecl( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual FRONT_MEMORY_INFO GetMemoryInfo() {return GetInvalidMemoryInfo();}
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
}; // end of class node_pipe
class node_safearray : public npa_nodes { private: // this maintains a reference to LPSAFEARRAY. This is
// necessary to generate the appropriate code when
// SAFEARRAY(type) construct is used outside the library block
named_node* pSafeArrayTypedef; BOOL fInProxy; public: // constructors
node_safearray() : npa_nodes( NODE_SAFEARRAY ), pSafeArrayTypedef( 0 ), fInProxy(0) { }
node_safearray(node_skl * pType) : npa_nodes( NODE_SAFEARRAY ), pSafeArrayTypedef( 0 ), fInProxy(0) { SetChild(pType); }
virtual STATUS_T DoPrintType( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual STATUS_T DoPrintDecl( PRTFLAGS Flags, BufferManager * pBuffer, ISTREAM * pStream, node_skl * pParent, node_skl * pIntf );
virtual FRONT_MEMORY_INFO GetMemoryInfo();
virtual void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
virtual CG_CLASS * ILxlate( XLAT_CTXT * pContext );
virtual void SetTypeAlias( named_node* pAlias) { pSafeArrayTypedef = pAlias; };
virtual named_node* GetTypeAlias( void ) { return pSafeArrayTypedef; };
}; // end of class node_pointer
class node_async_handle : public named_node { private: public:
node_async_handle( char* szName ) : named_node( szName, NODE_ASYNC_HANDLE ) { } STATUS_T DoPrintDecl(PRTFLAGS Flags, BufferManager* pBuffer, ISTREAM* pStream, node_skl* pParent, node_skl* pIntf ); STATUS_T DoPrintType(PRTFLAGS Flags, BufferManager* pBuffer, ISTREAM* pStream, node_skl* pParent, node_skl* pIntf); virtual FRONT_MEMORY_INFO GetMemoryInfo( ) { return GetInvalidMemoryInfo();}
CG_CLASS* ILxlate( XLAT_CTXT* pContext ); void SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt );
}; // node_async_handle
typedef enum __PragmaType { mp_MessageDisable, mp_MessageEnable } PragmaType;
class node_midl_pragma : public named_node { private: PragmaType m_PragmaType; gplistmgr* m_pMsgList; public: node_midl_pragma( PragmaType pt, gplistmgr* pList ) : named_node( NODE_MIDL_PRAGMA, "midl_pragma" ), m_PragmaType( pt ), m_pMsgList( pList ) { } virtual FRONT_MEMORY_INFO GetMemoryInfo() {return GetInvalidMemoryInfo();} void SemanticAnalysis( SEM_ANALYSIS_CTXT* ); CG_CLASS* ILxlate( XLAT_CTXT* pContext ); void ProcessPragma();
}; // node_midl_pragma
class node_decl_guid : public named_node { public: node_decl_guid( char* szName, node_guid* guid ) : named_node( NODE_DECL_GUID, szName ), pGuid( guid ) { }
virtual FRONT_MEMORY_INFO GetMemoryInfo() {return GetInvalidMemoryInfo();}
void SemanticAnalysis( SEM_ANALYSIS_CTXT* ); CG_CLASS* ILxlate( XLAT_CTXT* pContext ); STATUS_T DoPrintType ( PRTFLAGS, BufferManager*, ISTREAM*, node_skl*, node_skl* ); STATUS_T DoPrintDecl ( PRTFLAGS, BufferManager*, ISTREAM*, node_skl*, node_skl* ); private: node_guid* pGuid; };
#endif // __NODESKL_HXX__
|