/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 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__