windows-nt/Source/XPSP1/NT/com/rpc/midl/codegen/filecls.hxx
2020-09-26 16:20:57 +08:00

629 lines
16 KiB
C++

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 1989-1999 Microsoft Corporation
Module Name:
filecls.hxx
Abstract:
cg classes for file nodes.
Notes:
History:
----------------------------------------------------------------------------*/
#ifndef __FILECLS_HXX__
#define __FILECLS_HXX__
#include "ndrcls.hxx"
#include "auxcls.hxx"
#include "bindcls.hxx"
class node_file;
class node_interface;
class node_source;
// Ids for tables that we need remember file position of for ANSI.
// Note that following tables don't need this, as they are tables of functions,
// not structs:
// ContextRundownSizePosition,
// ExprEvaluationSizePosition,
// NotifySizePosition,
//
typedef enum
{
TypeFormatStringSizePosition,
ProcFormatStringSizePosition,
GenericHandleSizePosition,
TransmitAsSizePosition,
WireMarshalSizePosition,
TABLE_ID_MAX
} TABLE_ID;
class CG_FILE : public CG_AUX
{
private:
PFILENAME pFileName;
//
// The header file name could be different from the default name
// based off the stub name. The ilxlat will supply this info.
//
char * pHeaderFileName;
node_file * pNode;
long OptionalTableSizePositions[ TABLE_ID_MAX ];
FORMAT_STRING * pLocalFormatString;
FORMAT_STRING * pLocalProcFormatString;
NdrVersionControl VersionControl;
// REVIEW: some of the flags are specific to certain types of files. We may
// want to create approriate intermediate classes for them
// Has the memory stuff for [enable_allocated] been emitted?
unsigned long fMallocAndFreeStructExternEmitted : 1;
public:
//
// constructor.
//
CG_FILE(
node_file * pN,
PFILENAME pFName,
PFILENAME pHdrFName = NULL
)
{
SetFileName( pFName );
SetFileNode( pN );
pHeaderFileName = pHdrFName;
for ( int i=0; i < TABLE_ID_MAX; i++ )
OptionalTableSizePositions[ i ] = 0;
fMallocAndFreeStructExternEmitted = 0;
}
virtual
void Visit( CG_VISITOR *pVisitor )
{
pVisitor->Visit( this );
}
//
// get and set methods.
//
PFILENAME SetFileName( PFILENAME p )
{
return (pFileName = p);
}
PFILENAME GetFileName()
{
return pFileName;
}
node_file * SetFileNode( node_file * pN )
{
return (pNode = pN);
}
node_file * GetFileNode()
{
return pNode;
}
PFILENAME GetHeaderFileName()
{
return pHeaderFileName;
}
NdrVersionControl & GetNdrVersionControl()
{
return( VersionControl );
}
long GetOptionalTableSizePosition( TABLE_ID TableId )
{
return OptionalTableSizePositions[ TableId ];
}
void SetOptionalTableSizePosition( TABLE_ID TableId,
long PositionInFile )
{
OptionalTableSizePositions[ TableId ] = PositionInFile;
}
BOOL GetMallocAndFreeStructExternEmitted()
{
return fMallocAndFreeStructExternEmitted;
}
void SetMallocAndFreeStructExternEmitted()
{
fMallocAndFreeStructExternEmitted = 1;
}
//
// code generation methods.
//
virtual
ID_CG GetCGID()
{
return ID_CG_FILE;
}
virtual
CG_STATUS GenCode( CCB * )
{
return CG_OK;
}
void EmitFileHeadingBlock( CCB * pCCB,
char * CommentStr,
char * CommentStr2 = 0,
bool fDualFile = true );
void EmitFileClosingBlock( CCB * pCCB,
bool fDualFile = true );
void EmitStandardHeadingBlock( CCB * pCCB );
void CheckForHeadingToken( CCB * pCCB );
void Out_TransferSyntaxDefs( CCB * pCCB);
void EmitFormatStringTypedefs( CCB * pCCB );
void EmitFixupToFormatStringTypedefs( CCB * pCCB );
void EmitOptionalClientTableSizeTypedefs( CCB * pCCB );
void EmitFixupToOptionalClientTableSizeTypedefs( CCB * pCCB );
void EvaluateVersionControl();
};
class CG_CSTUB_FILE : public CG_FILE
{
private:
public:
//
// The constructor.
//
CG_CSTUB_FILE(
node_file * pN,
PFILENAME pFName,
PFILENAME pHdrName
)
: CG_FILE( pN, pFName, pHdrName )
{
}
virtual
void Visit( CG_VISITOR *pVisitor )
{
pVisitor->Visit( this );
}
//
// Code generation methods.
//
virtual
CG_STATUS GenCode( CCB * pCCB );
void OutputTypePicklingTables( CCB * pCCB );
};
class CG_SSTUB_FILE : public CG_FILE
{
private:
public:
//
// The constructor.
//
CG_SSTUB_FILE(
node_file * pN,
PFILENAME pFName,
PFILENAME pHdrName
)
: CG_FILE( pN, pFName, pHdrName )
{
}
virtual
void Visit( CG_VISITOR *pVisitor )
{
pVisitor->Visit( this );
}
//
// Code generation methods.
//
virtual
CG_STATUS GenCode( CCB * pCCB );
};
//
// Header file generation class
//
// This includes a pointer to an iterator over the import level 1
// node_file nodes
//
class CG_HDR_FILE : public CG_FILE
{
private:
ITERATOR * pImportList; // ptr to list of level 1 imports
public:
CG_HDR_FILE(
node_file * pN,
PFILENAME pFName,
ITERATOR * pIList,
PFILENAME pOtherHdr = NULL
)
: CG_FILE(pN, pFName, pOtherHdr)
{
pImportList = pIList;
}
virtual
void Visit( CG_VISITOR *pVisitor )
{
pVisitor->Visit( this );
}
ITERATOR * GetImportList()
{
return pImportList;
}
//
// Code generation methods.
//
virtual
CG_STATUS GenCode( CCB * pCCB );
virtual
void OutputImportIncludes( CCB * pCCB );
void OutputMultipleInterfacePrototypes( CCB * pCCB );
};
class CG_IID_FILE : public CG_FILE
{
private:
public:
//
// The constructor.
//
CG_IID_FILE(
node_file * pN,
PFILENAME pFName
)
: CG_FILE( pN, pFName )
{
}
virtual
void Visit( CG_VISITOR *pVisitor )
{
pVisitor->Visit( this );
}
//
// Code generation methods.
//
virtual
CG_STATUS GenCode( CCB * pCCB );
};
class CG_PROXY_FILE : public CG_FILE
{
private:
//
// this is a list of all the interfaces supported by this proxy file
// (non-inherited, and non-local )
// This list may be sorted by IID in the future.
//
ITERATOR ImplementedInterfaces;
public:
//
// The constructor.
//
CG_PROXY_FILE(
node_file * pN,
PFILENAME pFName,
PFILENAME pHdrName
)
: CG_FILE( pN, pFName, pHdrName )
{
}
virtual
void Visit( CG_VISITOR *pVisitor )
{
pVisitor->Visit( this );
}
//
// Code generation methods.
//
virtual
CG_STATUS GenCode( CCB * pCCB );
//
// Output methods
//
void MakeImplementedInterfacesList( CCB * pCCB );
ITERATOR & GetImplementedInterfacesList()
{
ITERATOR_INIT( ImplementedInterfaces );
return ImplementedInterfaces;
}
void Out_ProxyBuffer( CCB *pCCB, char * pFName );
void Out_StubBuffer( CCB *pCCB, char * pFName );
void Out_InterfaceNamesList( CCB *pCCB, char * pFName );
void Out_BaseIntfsList( CCB * pCCB, char * pFName );
void Out_InfoSearchRoutine( CCB * pCCB, char * pFName );
void Out_AsyncInterfaceTable( CCB* pCCB, char* pFName );
void Out_ProxyFileInfo( CCB *pCCB );
void UpdateDLLDataFile( CCB * pCCB );
};
class CG_TYPELIBRARY_FILE: public CG_FILE
{
private:
public:
CG_TYPELIBRARY_FILE(
node_file * pN,
PFILENAME pFName
)
: CG_FILE(pN, pFName)
{
}
virtual
void Visit( CG_VISITOR *pVisitor )
{
pVisitor->Visit( this );
}
//
// Code generation methods.
//
virtual
CG_STATUS GenCode( CCB * pCCB );
};
// These are classes used by CG_NETMONSTUB_FILE to implement a hashtable class.
// CG_NETMONSTUB_FILE uses hashtables to store interface information for quick
// lookups. The CG_INTERFACE class could have been modified with some Get/Set flags
// to do the same thing, but the philosophy behind the CG_NETMONSTUB_FILE class was to
// modify as little of the main code base as possible.
class NetmonStubFileInterfaceNode {
protected:
char* m_pszInterface;
long m_lNumProcs;
NetmonStubFileInterfaceNode* m_pNext;
public:
NetmonStubFileInterfaceNode (char* pszInterface);
~NetmonStubFileInterfaceNode();
NetmonStubFileInterfaceNode* GetNext();
void SetNext (NetmonStubFileInterfaceNode* pNext);
char* GetInterface();
void SetNumProcedures (long lNumProcs);
long GetNumProcedures();
};
class NetmonStubFileInterfaceList {
protected:
NetmonStubFileInterfaceNode* m_pHead;
NetmonStubFileInterfaceNode* m_pTail;
public:
NetmonStubFileInterfaceList();
~NetmonStubFileInterfaceList();
void AddInterface (char* pszInterface);
BOOL FindInterface (char* pszInterface);
BOOL SetNumProcedures (char* pszInterface, long lNumProcs);
BOOL GetNumProcedures (char* pszInterface, long* plNumProcs);
};
class NetmonStubFileInterfaceTable {
protected:
NetmonStubFileInterfaceList* m_pTable;
long GetHashValue (char* pszInterface);
public:
NetmonStubFileInterfaceTable();
~NetmonStubFileInterfaceTable();
void AddInterface (char* pszInterface);
BOOL FindInterface (char* pszInterface);
BOOL SetNumProcedures (char* pszInterface, long lNumProcs);
BOOL GetNumProcedures (char* pszInterface, long* plNumProcs);
};
class CG_NETMONSTUB_FILE: public CG_FILE
{
protected:
CCB* m_pCCB;
ISTREAM* m_pStream;
// Tables used to keep track of interfaces present in the compile and
// mark interfaces that we've processed as used
NetmonStubFileInterfaceTable m_itInterfaceTable;
NetmonStubFileInterfaceTable m_itOutputInterfaceTable;
// TRUE if classic or object interfaces are present in the compile
BOOL m_bClassic;
BOOL m_bObject;
// TRUE if we're doing the object interface pass; false otherwise
BOOL m_bDoObject;
// Interface counters
long m_lNumClassicInterfaces;
long m_lNumObjectInterfaces;
CG_STATUS ScanInterfaces();
CG_STATUS OpenComment();
CG_STATUS EmitComment (char* pszString);
CG_STATUS CloseComment();
CG_STATUS EmitStandardIncludes();
CG_STATUS EmitLocalIncludes();
CG_STATUS EmitDefinitions();
CG_STATUS EmitDebugProcedures();
CG_STATUS EmitServerClientDebugProcedure (CG_PROC* pProc, BOOL bIsObject);
CG_STATUS EmitDataTables();
CG_STATUS EmitProcNameTables();
CG_STATUS EmitServerClientTables();
CG_STATUS EmitGlobalInterfaceData();
// Object interface functions
CG_STATUS EmitObjectInterfaceData();
CG_STATUS EmitRPCServerInterface (CG_INTERFACE* pCG);
public:
CG_NETMONSTUB_FILE(
BOOL bDoObject,
node_file * pN,
PFILENAME pFName
)
: CG_FILE(pN, pFName)
{
m_pCCB = NULL;
m_pStream = NULL;
m_bDoObject = bDoObject;
m_bClassic = m_bObject = FALSE;
m_lNumClassicInterfaces = m_lNumObjectInterfaces = 0;
}
virtual
void Visit( CG_VISITOR *pVisitor )
{
pVisitor->Visit( this );
}
// Codegen
virtual CG_STATUS GenCode( CCB * pCCB);
};
//
// the root of the IL translation tree
//
class CG_SOURCE : public CG_AUX
{
private:
node_source * pSourceNode;
public:
CG_SOURCE( node_source *p )
{
pSourceNode = p;
}
//
// code generation methods.
//
virtual
ID_CG GetCGID()
{
return ID_CG_SOURCE;
}
virtual
void Visit( CG_VISITOR *pVisitor )
{
pVisitor->Visit( this );
}
virtual
CG_STATUS GenCode( CCB * pCCB );
};
//
// Miscellaneous prototypes
//
void NormalizeString(
char* szSrc,
char* szNrm );
void SetNoOutputIn2ndCodegen( CCB * pCCB );
void ResetNoOutputIn2ndCodegen( CCB *pCCB );
#endif // __FILECLS_HXX__