/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Copyright (c) 1989-2000 Microsoft Corporation Module Name: proccls.hxx Abstract: Contains definitions for procedure related code gen class definitions. Notes: History: VibhasC Jul-29-1993 Created. ----------------------------------------------------------------------------*/ #ifndef __PROCCLS_HXX__ #define __PROCCLS_HXX__ #include "nulldefs.h" extern "C" { #include } #include "ndrcls.hxx" #include "bindcls.hxx" #include "sdesc.hxx" class CG_PARAM; class CG_RETURN; class CG_ENCODE_PROC; class CG_TYPE_ENCODE_PROC; class CG_INTERFACE; ///////////////////////////////////////////////////////////////////////////// // the procedure code generation class. ///////////////////////////////////////////////////////////////////////////// enum PROCKIND { PROC_VIRTUAL, PROC_PUREVIRTUAL, PROC_NONVIRTUAL, PROC_STATIC, PROC_DISPATCH, }; // Platforms for interpreter call flavors typedef enum { PROC_PLATFORM_X86, PROC_PLATFORM_V1_INTERPRETER, PROC_PLATFORM_IA64 } PROC_CALL_PLATFORM; // // This class corresponds to a procedure specified for remoting. This class // is responsible for gathering all the information relating to code gen for // a procedure and generating code for it. There are 2 kinds of procedures // known to mankind. Call and callback procedures. This class provides the // basis for both those procedure types. Most of the functionality of the // call and callback procedures is the same. The main difference is the side // that the code will be generated in. // class CG_PROC : public CG_NDR { private: // // Flags storing information about in and out params. The fHasShippedParam // field specifies that at least one param exists that is shipped. This // is different from fHasIn, because the proc may have an [in] handle_t // param which does not get shipped, so no buffer allocation for that is // necessary, yet such a param must be generated and initialized in the // server stub. // unsigned long fHasIn : 1; unsigned long fHasOut : 1; unsigned long fHasShippedParam : 1; unsigned long fHasStatuses : 1; unsigned long fHasExtraStatusParam : 1; // the invisible one unsigned long fNoCode : 1; unsigned long fOutLocalAnalysisDone : 1; unsigned long fHasFullPtr : 1; unsigned long fHasNotify : 1; unsigned long fHasNotifyFlag : 1; unsigned long fRpcSSSpecified : 1; unsigned long fMustRpcSSAllocate : 1; unsigned long fReturnsHRESULT : 1; unsigned long fHasPipes : 1; unsigned long fSupressHeader : 1; unsigned long fHasAsyncHandle : 1; unsigned long fHasDeny : 1; unsigned long fHasAsyncUUID : 1; unsigned long fHasServerCorr : 1; unsigned long fHasClientCorr : 1; unsigned long fIsBeginProc : 1; unsigned long fIsFinishProc : 1; unsigned long fHasComplexReturn : 1; // // This is used by type info generation to determine what the FUNKIND should be // unsigned uProckind; // // This field specifies the usage of the handle. This information really // needs to be kept only with the cg_proc since the proc is entity // responsible for the binding. // HANDLE_USAGE HandleUsage : 1; // // This field keeps track of the binding handle. Refer to the binding // handle class definition for more info on how it is used. // If the handle is explicit, then this is a pointer to a cg class which // will be part of the param list anyhow. If the handle is implicit, then // this is a pointer to a separately allocated binding handle class. // Also, this field is used in conjunction with the HandleUsage field, // which specifies the usage of the binding: explicit or implicit. CG_HANDLE * pHDLClass; // // This field specifies the usage of the handle. This information really // needs to be kept only with the cg_proc since the proc is entity // responsible for the binding. // CG_PARAM * pHandleUsage; // // This field specifies the procedure number. The proc num is the lexical // sequence number of the proc specified in the idl file, not counting the // callback procedures which have their own lexical sequence. This field // is an unsigned int to match the declaration in the rpc message. // unsigned int ProcNum; // // This field specifies the return type. // This is NULL if there is no return type. Otherwise, it points to a // CG_RETURN node which in turn points to the CG nodes for the return // type. // CG_RETURN * pReturn; // the optimization flags to use for this procedure OPTIM_OPTION OptimizationFlags; // The generated size expression generated out of the sizing pass of the // code generator. expr_node * pSizeExpr; RESOURCE * pBindingResource; RESOURCE * pStatusResource; // The stub descriptor for the procedure. SDESC * pSStubDescriptor; SDESC * pCStubDescriptor; long FormatStringParamStart; // the operation flags such as BROADCAST, IDEMPOTENT, etc in internal format unsigned int OperationBits; // the call_as name, if any char * pCallAsName; // pointer to MY interface node CG_INTERFACE * pMyInterfaceCG; short ContextHandleCount; FORMAT_STRING * pSavedFormatString; FORMAT_STRING * pSavedProcFormatString; short cRefSaved; unsigned short uNotifyTableOffset; CG_PROC * pCallAsType; CG_PROC * pAsyncRelative; // // Specifies the international character tag-setting routine to be used // for this proc. If the proc doesn't use international characters // it will be NULL. // node_proc * pCSTagRoutine; public: // // The constructor. // CG_PROC( unsigned int ProcNum, node_skl * pProc, CG_HANDLE * pBH, CG_PARAM * pHU, BOOL fAtLeastOneIn, BOOL fAtLeastOneOut, BOOL fAtLeastOneShipped, BOOL fHasStatuses, BOOL fHasFullPtr, CG_RETURN * pReturn, OPTIM_OPTION OptimFlags, unsigned short OpBits, BOOL fDeny ); virtual unsigned GetProckind() { return uProckind; } virtual unsigned SetProckind(unsigned uKind) { return (uProckind = uKind); } CG_PROC * SetCallAsCG(CG_PROC * p) { return (pCallAsType = p); } CG_PROC * GetCallAsCG() { return (pCallAsType); } // // Generate typeinfo // virtual CG_STATUS GenTypeInfo( CCB * pCCB); void SetRpcSSSpecified( unsigned long f ) { fRpcSSSpecified = f; } BOOL IsRpcSSSpecified() { return (BOOL)( fRpcSSSpecified == 1 ); } void SetMustInvokeRpcSSAllocate( unsigned long f ) { fMustRpcSSAllocate = f; } BOOL MustInvokeRpcSSAllocate() { return (BOOL)fMustRpcSSAllocate; } void SetOutLocalAnalysisDone() { fOutLocalAnalysisDone = 1; } BOOL IsOutLocalAnalysisDone() { return (BOOL)( fOutLocalAnalysisDone == 1); } RESOURCE * SetStatusResource( RESOURCE * pR ) { return (pStatusResource = pR); } RESOURCE * GetStatusResource() { return pStatusResource; } RESOURCE * SetBindingResource( RESOURCE * pR ) { return (pBindingResource = pR); } RESOURCE * GetBindingResource() { return pBindingResource; } SDESC * SetSStubDescriptor( SDESC * pSD ) { return (pSStubDescriptor = pSD ); } SDESC * GetSStubDescriptor() { return pSStubDescriptor; } SDESC * SetCStubDescriptor( SDESC * pSD ) { return (pCStubDescriptor = pSD ); } SDESC * GetCStubDescriptor() { return pCStubDescriptor; } OPTIM_OPTION SetOptimizationFlags( OPTIM_OPTION Opt ) { return (OptimizationFlags = Opt ); } OPTIM_OPTION GetOptimizationFlags() { return OptimizationFlags; } unsigned int SetOperationBits( unsigned int OpBits ) { return (OperationBits = OpBits ); } unsigned int GetOperationBits() { return OperationBits; } void GetCommAndFaultOffset( CCB * pCCB, long & CommOffset, long & FaultOffset ); void SetNoCode() { fNoCode = TRUE; } BOOL IsNoCode() { return fNoCode; } void SetHasNotify() { fHasNotify = TRUE; } void SetHasNotifyFlag() { fHasNotifyFlag = TRUE; } BOOL HasNotify() { return fHasNotify; } BOOL HasNotifyFlag() { return fHasNotifyFlag; } void SetReturnsHRESULT() { fReturnsHRESULT = TRUE; } BOOL ReturnsHRESULT() { return fReturnsHRESULT; } 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 SetHasDeny() { fHasDeny = TRUE; } BOOL HasDeny() { return fHasDeny; } virtual CG_STATUS Pass1( ANALYSIS_INFO * ) { return CG_OK; } virtual ID_CG GetCGID() { return ID_CG_PROC; } virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); } virtual BOOL IsProc() { return TRUE; } virtual BOOL IsInherited() { return FALSE; } virtual BOOL IsDelegated() { return FALSE; } // // Get and set methods. // void SetFormatStringParamStart( long Offset ) { FormatStringParamStart = Offset; } long GetFormatStringParamStart() { return FormatStringParamStart; } expr_node * SetSizeExpression( expr_node * pE ) { return ( pSizeExpr = pE ); } expr_node * GetSizeExpression() { return pSizeExpr; } unsigned int SetProcNum( unsigned int ProcNumber ) { return (ProcNum = ProcNumber); } virtual unsigned int GetProcNum() { return ProcNum; } short GetFloatArgMask( CCB * pCCB ); void SetContextHandleCount( short c ) { ContextHandleCount = c; } short GetContextHandleCount() { return ContextHandleCount; } CG_HANDLE * SetHandleClassPtr( CG_HANDLE * pHC ) { return (pHDLClass = pHC); } CG_HANDLE * GetHandleClassPtr() { return pHDLClass; } CG_PARAM * SetHandleUsagePtr( CG_PARAM * pHU ) { return (pHandleUsage = pHU); } CG_PARAM * GetHandleUsagePtr() { return pHandleUsage; } HANDLE_USAGE GetHandleUsage() { return (pHandleUsage) ? HU_EXPLICIT : HU_IMPLICIT; } CG_RETURN * SetReturnType( CG_RETURN * pRT ) { return (pReturn = pRT); } CG_RETURN * GetReturnType() { return pReturn; } void SetHasComplexReturnType() { fHasComplexReturn = 1; } BOOL HasComplexReturnType() { return fHasComplexReturn; } CG_INTERFACE * SetInterfaceNode( CG_INTERFACE * pIntf ) { return (pMyInterfaceCG = pIntf); } CG_INTERFACE * GetInterfaceNode() { return pMyInterfaceCG; } char * GetInterfaceName(); char * SetCallAsName( char * pName ); char * GetCallAsName() { return pCallAsName; } char * GenMangledCallAsName( CCB * pCCB ) { char * pName = new char[62]; strcpy( pName, pCCB->GetInterfaceName() ); strcat( pName, pCCB->GenMangledName() ); strcat( pName, "_" ); strcat( pName, pCallAsName ); return pName; } void SetHasAtLeastOneShipped() { fHasShippedParam = 1; } void ResetHasAtLeastOneShipped() { fHasShippedParam = 0; } void SetHasAtLeastOneIn() { fHasIn = 1; } void SetHasAtLeastOneOut() { fHasOut = 1; } void ResetHasAtLeastOneIn() { fHasIn = 0; } void ResetHasAtLeastOneOut() { fHasOut = 0; } BOOL HasAtLeastOneShipped() { return (BOOL)(fHasShippedParam == 1); } BOOL HasAtLeastOneIn() { return (BOOL)(fHasIn == 1); } BOOL HasAtLeastOneOut() { return (BOOL)(fHasOut == 1); } BOOL HasPipes() { return (BOOL)(fHasPipes == 1); } BOOL SetHasPipes(BOOL f); BOOL SupressHeader() { return (BOOL)(1 == fSupressHeader); } void SetSupressHeader() { fSupressHeader = TRUE; } virtual BOOL HasStatuses() { return (BOOL)(fHasStatuses); } BOOL HasExtraStatusParam() { return ( fHasExtraStatusParam ); } void SetHasExtraStatusParam() { fHasExtraStatusParam = TRUE; } BOOL HasFullPtr() { return ( fHasFullPtr ); } BOOL SetHasFullPtr( BOOL f ) { return ( fHasFullPtr = f ); } BOOL HasReturn() { return (BOOL)(pReturn != NULL); } BOOL HasOuts() { return (HasAtLeastOneOut() || HasReturn()); } BOOL HasInterpreterDeferredFree(); BOOL IsNullCall() { return (!HasAtLeastOneIn() && !HasAtLeastOneOut()&& !HasReturn() ); } virtual BOOL HasEncode() { return FALSE; } virtual BOOL HasDecode() { return FALSE; } virtual BOOL HasAPicklingAttribute() { return FALSE; } void SetAsyncRelative( CG_PROC *pAsync ) { pAsyncRelative = pAsync; } CG_PROC * GetAsyncRelative() { return pAsyncRelative; } void SetIsBeginProc() { fIsBeginProc = TRUE; } BOOL IsBeginProc() { return fIsBeginProc; } void SetIsFinishProc() { fIsFinishProc = TRUE; } BOOL IsFinishProc() { return fIsFinishProc; } void SetCSTagRoutine( node_proc *p ) { pCSTagRoutine = p; } node_proc * GetCSTagRoutine() { return pCSTagRoutine; } unsigned short GetNotifyTableOffset( CCB *pCCB ) { uNotifyTableOffset = pCCB->RegisterNotify(this); return uNotifyTableOffset; } // // Queries. // virtual BOOL IsAutoHandle() { return (GetHandleClassPtr() == 0); } virtual BOOL IsPrimitiveHandle() { return (!IsAutoHandle()) && GetHandleClassPtr()->IsPrimitiveHandle(); } virtual BOOL IsGenericHandle() { return (!IsAutoHandle()) && GetHandleClassPtr()->IsGenericHandle(); } virtual BOOL IsContextHandle() { return (!IsAutoHandle()) && GetHandleClassPtr()->IsContextHandle(); } // // Generate the client and server stubs. // virtual CG_STATUS GenClientStub( CCB * pCCB ); // // This method does size calculation analysis for the client side // marshalling. // // // This method performs binding related analysis on the client side. // virtual CG_STATUS C_BindingAnalysis( ANALYSIS_INFO * pAna ); virtual CG_STATUS RefCheckAnalysis( ANALYSIS_INFO * pAna ); // // Unmarshalling analysis for the server side. // // This pair of methods generates the prolog and epilog for the client // side marshall. // virtual CG_STATUS C_GenProlog( CCB * pCCB ); virtual CG_STATUS C_GenBind( CCB * pCCB ); virtual CG_STATUS GenSizing( CCB * pCCB ); virtual CG_STATUS GenGetBuffer( CCB * pCCB ); virtual CG_STATUS S_GenInitMarshall( CCB * pCCB ); virtual CG_STATUS GenMarshall( CCB * pCCB ); virtual CG_STATUS C_GenSendReceive( CCB * pCCB ); virtual CG_STATUS GenUnMarshall( CCB * pCCB ); virtual CG_STATUS C_GenUnBind( CCB * pCCB ); virtual CG_STATUS GenFree( CCB * pCCB ); virtual CG_STATUS C_GenFreeBuffer( CCB * pCCB ); virtual CG_STATUS GenEpilog( CCB * pCCB ); virtual CG_STATUS GenServerStub( CCB * pCCB ); virtual CG_STATUS S_GenInitOutLocals( CCB * pCCB ); virtual CG_STATUS S_GenInitTopLevelStuff( CCB * pCCB ); virtual CG_STATUS S_GenProlog( CCB * pCCB ); // // Format string routines for generating the format string and // the NDR calls. // virtual void GenNdrFormat( CCB * pCCB ); void GenNdrFormatV1( CCB * pCCB ); void SetupFormatStrings( CCB * pCCB ); void UnsetupFormatStrings( CCB * pCCB ); void GenNdrFormatProcInfo( CCB * pCCB ); // // This routine generates the code for the "one call" Ndr case on the // client side. // virtual void GenNdrSingleClientCall( CCB * pCCB ); expr_node * GenCoreNdrSingleClientCall( CCB * pCCB, PROC_CALL_PLATFORM Platform ); // // This routine generates the code for the "one call" Ndr case on the // server side. It's actually 3 calls, but who's counting. // virtual void GenNdrSingleServerCall( CCB * pCCB ); // // Outputs an old style "three call" server stub. // void GenNdrOldInterpretedServerStub( CCB * pCCB ); // // Outputs a thunk stub to call the server routine. Thunk stub is called // from the interpreter, not the rpc runtime. // void GenNdrThunkInterpretedServerStub( CCB * pCCB ); // // Outputs the locals for interpreted server stubs. // void GenNdrInterpretedServerLocals( CCB * pCCB ); // // Outputs the param struct for interpreted server stubs. // void GenNdrInterpreterParamStruct( CCB * pCCB); void GenNdrInterpreterParamStruct32( CCB * pCCB ); void GenNdrInterpreterParamStruct64( CCB * pCCB); // // Outputs the call to the manager routine for interpreted server stubs. // virtual void GenNdrInterpretedManagerCall( CCB * pCCB ); virtual CG_STATUS C_XFormToProperFormat( CCB * ) { return CG_OK; } virtual CG_STATUS S_XFormToProperFormat( CCB * ) { return CG_OK; } virtual CG_STATUS S_GenCallManager( CCB * pCCB ); // // Queries. // BOOL MustUseSingleEngineCall( CCB * pCCB ); BOOL UseOldInterpreterMode( CCB * pCCB ); BOOL NeedsServerThunk( CCB * pCCB, CGSIDE Side ); // // miscellaneous methods. // // Oi stack size, includes the return type. long GetTotalStackSize( CCB * pCCB ); // // This method registers pre-allocated stub resources like the params, // standard local variables etc, with the corresponding resource dictionary // in the analysis block. // void C_PreAllocateResources( ANALYSIS_INFO * ); virtual void S_PreAllocateResources( ANALYSIS_INFO * ); virtual expr_node * GenBindOrUnBindExpression( CCB * pCCB, BOOL fBind ); short GetInParamList( ITERATOR& ); short GetOutParamList( ITERATOR& ); CG_PARAM * SearchForBindingParam() { return (CG_PARAM *)GetHandleUsagePtr(); } virtual CG_STATUS MarshallAnalysis( ANALYSIS_INFO * pAna ); virtual CG_STATUS SizeAnalysis( ANALYSIS_INFO * ) { return CG_OK; } virtual CG_STATUS UnMarshallAnalysis( ANALYSIS_INFO * pAna ); virtual CG_STATUS S_OutLocalAnalysis( ANALYSIS_INFO * pAna ); void RpcSsPackageAnalysis( ANALYSIS_INFO * pAna ); CG_STATUS C_GenMapCommAndFaultStatus( CCB * pCCB ); CG_STATUS C_GenMapHRESULT( CCB * pCCB ); CG_STATUS C_GenClearOutParams( CCB * pCCB ); virtual CG_STATUS GenRefChecks( CCB * pCCB ); virtual CG_STATUS InLocalAnalysis( ANALYSIS_INFO * pAna ); virtual CG_STATUS S_GenInitInLocals( CCB * pCCB ); unsigned int TranslateOpBitsIntoUnsignedInt(); void GetCorrectAllocFreeRoutines( CCB * pCCB, BOOL fServer, char ** pAllocRtnName, char ** pFreeRtnName ); CG_STATUS GenNotify( CCB * pCCB, BOOL fHasFlag ); }; ///////////////////////////////////////////////////////////////////////////// // the callback proc code generation class. ///////////////////////////////////////////////////////////////////////////// // // this is derived from the regular proc class class CG_CALLBACK_PROC: public CG_PROC { public: // // The constructor. Just call the proc constructor // CG_CALLBACK_PROC( unsigned int ProcNum, node_skl * pProc, CG_HANDLE * pBH, CG_PARAM * pHU, BOOL fAtLeastOneIn, BOOL fAtLeastOneOut, BOOL fAtLeastOneShipped, BOOL fHasStatuses, BOOL fHasFullPtr, CG_RETURN * pRT, OPTIM_OPTION OptimFlags, unsigned short OpBits, BOOL fDeny ) : CG_PROC( ProcNum, pProc, pBH, pHU, fAtLeastOneIn, fAtLeastOneOut, fAtLeastOneShipped, fHasStatuses, fHasFullPtr, pRT, OptimFlags, OpBits, fDeny ) { } virtual ID_CG GetCGID() { return ID_CG_CALLBACK_PROC; } virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); } CG_STATUS GenClientStub( CCB * pCCB ); CG_STATUS GenServerStub( CCB * pCCB ); virtual BOOL IsAutoHandle() { return FALSE; } virtual BOOL IsPrimitiveHandle() { return FALSE; } virtual BOOL IsGenericHandle() { return FALSE; } virtual BOOL IsContextHandle() { return FALSE; } }; ///////////////////////////////////////////////////////////////////////////// // the object proc code generation classes. ///////////////////////////////////////////////////////////////////////////// // // this is derived from the regular proc class class CG_OBJECT_PROC: public CG_PROC { public: // // The constructor. Just call the proc constructor // CG_OBJECT_PROC( unsigned int ProcNum, node_skl * pProc, CG_HANDLE * pBH, CG_PARAM * pHU, BOOL fAtLeastOneIn, BOOL fAtLeastOneOut, BOOL fAtLeastOneShipped, BOOL fHasStatuses, BOOL fHasFullPtr, CG_RETURN * pRT, OPTIM_OPTION OptimFlags, unsigned short OpBits, BOOL fDeny) : CG_PROC( ProcNum, pProc, pBH, pHU, fAtLeastOneIn, fAtLeastOneOut, fAtLeastOneShipped, fHasStatuses, fHasFullPtr, pRT, OptimFlags, OpBits, fDeny ) { } virtual ID_CG GetCGID() { return ID_CG_OBJECT_PROC; } virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); } virtual BOOL IsObject() { return TRUE; } virtual BOOL IsLocal() { return FALSE; } // // miscellaneous methods. // // // This method registers pre-allocated stub resources like the params, // standard local variables etc, with the corresponding resource dictionary // in the analysis block. // virtual CG_STATUS C_GenProlog( CCB * pCCB ); virtual CG_STATUS C_GenBind( CCB * pCCB ); virtual CG_STATUS GenGetBuffer( CCB * pCCB ); virtual CG_STATUS C_GenSendReceive( CCB * pCCB ); virtual CG_STATUS C_GenFreeBuffer( CCB * pCCB ); virtual CG_STATUS C_GenUnBind( CCB * pCCB ); virtual void S_PreAllocateResources( ANALYSIS_INFO * ); virtual CG_STATUS S_GenProlog( CCB * pCCB ); virtual CG_STATUS S_GenCallManager( CCB * pCCB ); virtual CG_STATUS S_GenInitMarshall( CCB * pCCB ); // // Outputs the call to the manager routine for interpreted server stubs. // virtual void GenNdrInterpretedManagerCall( CCB * pCCB ); CG_STATUS PrintVtableEntry( CCB * pCCB); void Out_ServerStubProlog( CCB * pCCB, ITERATOR& LocalsList, ITERATOR& TransientList ); void Out_ProxyFunctionPrototype(CCB *pCCB, PRTFLAGS F ); void Out_StubFunctionPrototype(CCB *pCCB); CG_STATUS GenCMacro(CCB * pCCB ); CG_STATUS GenComClassMemberFunction( CCB * pCCB ); CG_STATUS ReGenComClassMemberFunction( CCB * pCCB ); virtual BOOL IsDelegated() { return FALSE; } void OutProxyRoutineName( ISTREAM * pStream, BOOL fForcesDelegation ); void OutStubRoutineName( ISTREAM * pStream ); BOOL IsStublessProxy(); }; // the class for inherited object procs class CG_INHERITED_OBJECT_PROC: public CG_OBJECT_PROC { public: // // The constructor. Just call the proc constructor // CG_INHERITED_OBJECT_PROC( unsigned int ProcNum, node_skl * pProc, CG_HANDLE * pBH, CG_PARAM * pHU, BOOL fAtLeastOneIn, BOOL fAtLeastOneOut, BOOL fAtLeastOneShipped, BOOL fHasStatuses, BOOL fHasFullPtr, CG_RETURN * pRT, OPTIM_OPTION OptimFlags, unsigned short OpBits, BOOL fDeny ) : CG_OBJECT_PROC( ProcNum, pProc, pBH, pHU, fAtLeastOneIn, fAtLeastOneOut, fAtLeastOneShipped, fHasStatuses, fHasFullPtr, pRT, OptimFlags, OpBits, fDeny ) { } virtual ID_CG GetCGID() { return ID_CG_INHERITED_OBJECT_PROC; } virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); } // // miscellaneous methods. // virtual BOOL IsInherited() { return TRUE; } virtual BOOL IsDelegated() { return TRUE; } // // This method registers pre-allocated stub resources like the params, // standard local variables etc, with the corresponding resource dictionary // in the analysis block. // }; // the class for local object procs, whether inherited or not class CG_LOCAL_OBJECT_PROC: public CG_OBJECT_PROC { BOOL fInherited; public: // // The constructor. Just call the proc constructor // CG_LOCAL_OBJECT_PROC( unsigned int ProcNum, node_skl * pProc, BOOL fInh, OPTIM_OPTION OptimFlags, BOOL fDeny ) : CG_OBJECT_PROC( ProcNum, pProc, NULL, NULL, 0, 0, 0, 0, 0, NULL, OptimFlags, 0, fDeny ) { fInherited = fInh; } virtual ID_CG GetCGID() { return ID_CG_LOCAL_OBJECT_PROC; } virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); } // // miscellaneous methods. // virtual BOOL IsInherited() { return fInherited; } virtual CG_STATUS GenClientStub( CCB * ) { return CG_OK; } virtual CG_STATUS GenServerStub( CCB * ) { return CG_OK; } virtual BOOL IsDelegated() { return TRUE; } virtual BOOL IsLocal() { return TRUE; } }; class CG_IUNKNOWN_OBJECT_PROC : public CG_LOCAL_OBJECT_PROC { public: // // The constructor. Just call the proc constructor // CG_IUNKNOWN_OBJECT_PROC( unsigned int ProcNum, node_skl* pProc, BOOL fInh, OPTIM_OPTION OptimFlags, BOOL fDeny ) : CG_LOCAL_OBJECT_PROC( ProcNum, pProc, fInh, OptimFlags, fDeny ) { } virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); } virtual BOOL IsDelegated() { return FALSE; } }; ///////////////////////////////////////////////////////////////////////////// // the encode proc code generation class. ///////////////////////////////////////////////////////////////////////////// // // this is derived from the regular proc class class CG_ENCODE_PROC: public CG_PROC { BOOL fHasEncode; BOOL fHasDecode; public: // // The constructor. Just call the proc constructor // CG_ENCODE_PROC( unsigned int ProcNum, node_skl * pProc, CG_HANDLE * pBH, CG_PARAM * pHU, BOOL fAtLeastOneIn, BOOL fAtLeastOneOut, BOOL fAtLeastOneShipped, BOOL fHasStatuses, BOOL fHasFullPtr, CG_RETURN * pRT, OPTIM_OPTION OptimFlags, unsigned short OpBits, BOOL fEncode, BOOL fDecode, BOOL fDeny ) : CG_PROC( ProcNum, pProc, pBH, pHU, fAtLeastOneIn, fAtLeastOneOut, fAtLeastOneShipped, fHasStatuses, fHasFullPtr, pRT, OptimFlags, OpBits, fDeny ), fHasEncode( fEncode ), fHasDecode( fDecode ) { } virtual ID_CG GetCGID() { return ID_CG_ENCODE_PROC; } virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); } virtual BOOL HasEncode() { return fHasEncode; } virtual BOOL HasDecode() { return fHasDecode; } virtual BOOL HasAPicklingAttribute() { return TRUE; } // Generate the client side (the only side) of the encoding stub. virtual CG_STATUS GenClientStub( CCB * pCCB ); CG_STATUS GenClientStubV1( CCB * pCCB ); CG_STATUS GenMesProcEncodeDecodeCall( CCB * pCCB, PROC_CALL_PLATFORM Platform ); virtual CG_STATUS GenServerStub( CCB * ) { return CG_OK; } }; ///////////////////////////////////////////////////////////////////////////// // the type encode code generation class. ///////////////////////////////////////////////////////////////////////////// // // this is derived from the regular proc class class CG_TYPE_ENCODE_PROC: public CG_PROC { public: // // The constructor. Just call the proc constructor // CG_TYPE_ENCODE_PROC( unsigned int ProcNum, node_skl * pProc, CG_HANDLE * pBH, CG_PARAM * pHU, BOOL fAtLeastOneIn, BOOL fAtLeastOneOut, BOOL fAtLeastOneShipped, BOOL fHasStatuses, BOOL fHasFullPtr, CG_RETURN * pRT, OPTIM_OPTION OptimFlags, unsigned short OpBits, BOOL fDeny ) : CG_PROC( ProcNum, pProc, pBH, pHU, fAtLeastOneIn, fAtLeastOneOut, fAtLeastOneShipped, fHasStatuses, fHasFullPtr, pRT, OptimFlags, OpBits, fDeny ) { } virtual ID_CG GetCGID() { return ID_CG_TYPE_ENCODE_PROC; } virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); } // Generate the client side (the only side) of the encoding stub. virtual CG_STATUS GenClientStub( CCB * pCCB ); virtual CG_STATUS GenServerStub( CCB * ) { return CG_OK; } }; ///////////////////////////////////////////////////////////////////////////// // the parameter code generation class. ///////////////////////////////////////////////////////////////////////////// typedef unsigned long PARAM_DIR_FLAGS; #define IN_PARAM 0x1 #define OUT_PARAM 0x2 #define IN_OUT_PARAM (IN_PARAM | OUT_PARAM) #define PARTIAL_IGNORE_PARAM (IN_PARAM | OUT_PARAM | 0x4 ) #define I386_STACK_SIZING 0x1 struct StackOffsets { union { // Historically x86 was overloaded to mean ia64 long x86; // in 64bit. long ia64; }; }; // // The following defines the code generation class for the parameter. // class CG_PARAM : public CG_NDR { private: PARAM_DIR_FLAGS fDirAttrs : 3; // directional info unsigned long fDontCallFreeInst : 1; // as the name says unsigned long fInterpreterMustSize: 1; // interpreter has to size unsigned long fIsExtraStatusParam : 1; // invisible fault/comm unsigned long fIsAsyncHandle : 1; unsigned long fIsCSSTag : 1; // is cs sending tag unsigned long fIsCSDRTag : 1; // is cs desired recv tag unsigned long fIsCSRTag : 1; // is cs receiving tag unsigned long fIsOmitted : 1; // is not in param list unsigned long fIsForceAllocate : 1; // is forced to allocate flag set unsigned short Statuses; // comm/fault statuses short ParamNumber; expr_node * pFinalExpression; // for the server stub expr_node * pSizeExpression; // sizing expression // For unions only. expr_node * pSwitchExpr; // the switch_is expression // (if a non-encap union below) long UnionFormatStringOffset; // Resource for size / length if necessary. RESOURCE * pSizeResource; RESOURCE * pLengthResource; RESOURCE * pFirstResource; RESOURCE * pSubstitutePtrResource; unsigned long MarshallWeight; // the marshaling weight bool fSaveForAsyncFinish; long SavedFixedBufferSize; public: // // The constructor. // CG_PARAM( node_skl * pParam, PARAM_DIR_FLAGS Dir, XLAT_SIZE_INFO & Info , expr_node * pSw, unsigned short Stat ); virtual void SaveForAsyncFinish() { fSaveForAsyncFinish = true; }; virtual bool IsSaveForAsyncFinish() { return fSaveForAsyncFinish; }; // // TYPEDESC generation routine // virtual CG_STATUS GetTypeDesc(TYPEDESC * &ptd, CCB * pCCB); // // get and set methods. // virtual ID_CG GetCGID() { return ID_CG_PARAM; } virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); } void SetParamNumber( short pn ) { ParamNumber = pn; } short GetParamNumber() { MIDL_ASSERT( ParamNumber != -1 ); return ParamNumber; } long GetStackOffset( CCB * pCCB, long Platform ); void GetStackOffsets( CCB * pCCB, StackOffsets *p ) { // x86 is a synonym for ia64 in 64bit p->x86 = GetStackOffset( pCCB, I386_STACK_SIZING ); } long GetStackSize(); expr_node * SetSwitchExpr( expr_node * pE ) { return (pSwitchExpr = pE); } expr_node * GetSwitchExpr() { return pSwitchExpr; } void SetUnionFormatStringOffset( long offset ) { UnionFormatStringOffset = offset; } long GetUnionFormatStringOffset() { return UnionFormatStringOffset; } virtual unsigned short GetStatuses() { return Statuses; } virtual BOOL HasStatuses() { return (BOOL)( Statuses != STATUS_NONE ); } BOOL IsExtraStatusParam() { return fIsExtraStatusParam; } void SetIsExtraStatusParam() { fIsExtraStatusParam = TRUE; } virtual RESOURCE * SetSubstitutePtrResource( RESOURCE * pSR ) { return pSubstitutePtrResource = pSR; } BOOL IsAsyncHandleParam() { return fIsAsyncHandle; } void SetIsAsyncHandleParam() { fIsAsyncHandle = TRUE; } virtual RESOURCE * GetSubstitutePtrResource() { return pSubstitutePtrResource; } virtual RESOURCE * SetSizeResource( RESOURCE * pSR ) { return pSizeResource = pSR; } virtual RESOURCE * SetLengthResource( RESOURCE * pLR ) { return pLengthResource = pLR; } virtual RESOURCE * GetSizeResource() { return pSizeResource; } virtual RESOURCE * GetLengthResource() { return pLengthResource; } virtual RESOURCE * SetFirstResource( RESOURCE * pR) { return (pFirstResource = pR); } virtual RESOURCE * GetFirstResource() { return pFirstResource; } unsigned long SetMarshallWeight( unsigned long W ) { return (MarshallWeight = W); } unsigned long GetMarshallWeight() { return MarshallWeight; } BOOL GetDontCallFreeInst() { return (BOOL) fDontCallFreeInst; } void SetDontCallFreeInst( BOOL fDontCall ) { fDontCallFreeInst = fDontCall ? 1 : 0; } void SetForceAllocate( ) { fIsForceAllocate = TRUE; } BOOL IsForceAllocate() { return fIsForceAllocate; } BOOL IsOptional() { return(((node_param *)GetType())->IsOptional()); } BOOL IsRetval() { return(((node_param *)GetType())->IsRetval()); } expr_node * SetFinalExpression( expr_node * pR ) { return (pFinalExpression = pR ); } expr_node * GetFinalExpression() { return pFinalExpression; } expr_node * SetSizeExpression( expr_node * pR ) { return (pSizeExpression = pR ); } expr_node * GetSizeExpression() { return pSizeExpression; } void SetIsCSSTag(BOOL f) { fIsCSSTag = f; } BOOL IsCSSTag() { return fIsCSSTag; } void SetIsCSDRTag(BOOL f) { fIsCSDRTag = f; } BOOL IsCSDRTag() { return fIsCSDRTag; } void SetIsCSRTag(BOOL f) { fIsCSRTag = f; } BOOL IsCSRTag() { return fIsCSRTag; } BOOL IsSomeCSTag() { return IsCSSTag() || IsCSDRTag() || IsCSRTag(); } BOOL IsOmittedParam() { return fIsOmitted; } void SetIsOmittedParam( BOOL f = TRUE ) { fIsOmitted = f; } long GetFixedBufferSize() { return SavedFixedBufferSize; } void SetFixedBufferSize(long NewBufferSize) { SavedFixedBufferSize = NewBufferSize; } long FixedBufferSize( CCB * pCCB ) { return ((CG_NDR *)GetChild())->FixedBufferSize( pCCB ); } // // This method performs binding related analysis on the client side. // virtual CG_STATUS C_BindingAnalysis( ANALYSIS_INFO * ) { return CG_OK; } // // Generate the client side marshalling code. // virtual CG_STATUS GenMarshall( CCB * pCCB ); virtual CG_STATUS GenUnMarshall( CCB * pCCB ); virtual CG_STATUS GenSizing( CCB * pCCB ); virtual CG_STATUS GenFree( CCB * pCCB ); CG_STATUS GenTypeEncodingStub( CCB * pCCB ); virtual CG_STATUS S_GenInitOutLocals( CCB * pCCB ); virtual CG_STATUS S_GenInitTopLevelStuff( CCB * pCCB ); // // Format string routines for generating the format string and // the NDR calls for a parameter. // virtual void GenNdrFormat( CCB * pCCB ); void GenNdrFormatOld( CCB * pCCB ); void GenNdrMarshallCall( CCB * pCCB ); void GenNdrUnmarshallCall( CCB * pCCB ); void GenNdrBufferSizeCall( CCB * pCCB ); void GenNdrFreeCall( CCB * pCCB ); void GenNdrTopLevelAttributeSupport( CCB * pCCB, BOOL fForClearOut = FALSE ); // // Queries. // BOOL IsParamIn() { return (BOOL) ((fDirAttrs & IN_PARAM) == IN_PARAM); } BOOL IsParamOut() { return (BOOL) ((fDirAttrs & OUT_PARAM) == OUT_PARAM); } BOOL IsParamPartialIgnore() { return (BOOL) ((fDirAttrs & PARTIAL_IGNORE_PARAM ) == PARTIAL_IGNORE_PARAM ); } // // Should we use the new NDR engine to marshall/unmarshall a parameter. // For now we pass the CCB since it contains optimization information. // Later the analyzer will put optimization information in the CG_PARAM // class. // BOOL UseNdrEngine( CCB * pCCB ) { return (pCCB->GetOptimOption() & OPTIMIZE_SIZE); } // // miscellaneous methods. // virtual expr_node * GenBindOrUnBindExpression( CCB * pCCB, BOOL fBind ); //////////////////////////////////////////////////////////////////////////// virtual CG_STATUS BufferAnalysis( ANALYSIS_INFO * ) { return CG_OK; } virtual CG_STATUS MarshallAnalysis( ANALYSIS_INFO * pAna ); virtual CG_STATUS SizeAnalysis( ANALYSIS_INFO * ) { return CG_OK; } virtual CG_STATUS UnMarshallAnalysis( ANALYSIS_INFO * pAna ); virtual CG_STATUS S_OutLocalAnalysis( ANALYSIS_INFO * pAna ); void RpcSsPackageAnalysis( ANALYSIS_INFO * pAna ); void InitParamMarshallAnalysis( ANALYSIS_INFO * pAna ); void InitParamUnMarshallAnalysis( ANALYSIS_INFO * pAna ); void ConsolidateParamMarshallAnalysis( ANALYSIS_INFO * pAna ); void ConsolidateParamUnMarshallAnalysis( ANALYSIS_INFO * pAna ); virtual CG_STATUS GenRefChecks( CCB * pCCB ); virtual CG_STATUS S_GenInitInLocals( CCB * pCCB ); void SetInterpreterMustSize( BOOL f ) { fInterpreterMustSize = f ? 1 : 0; } BOOL GetInterpreterMustSize() { return fInterpreterMustSize; } }; // // The return-type code generation class // // This is a place-holder node for the return type, much like the param // and field nodes. This way, info about marshalling/unmarshalling the // return type doesn't need to clutter up the proc node. // // If the function has no return (or returns "void") then no CG_RETURN // is generated for the function. // class CG_RETURN : public CG_PARAM { private: public: // // The constructor. // CG_RETURN( node_skl * pRetType, XLAT_SIZE_INFO & Info, unsigned short Stat ) : CG_PARAM( pRetType, OUT_PARAM, Info, NULL, Stat ) { } // // get and set methods. // virtual ID_CG GetCGID() { return ID_CG_RETURN; } virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); } virtual CG_STATUS MarshallAnalysis( ANALYSIS_INFO * pAna ); virtual CG_STATUS UnMarshallAnalysis( ANALYSIS_INFO * pAna ); virtual CG_STATUS GenMarshall( CCB * pCCB ); virtual CG_STATUS GenUnMarshall( CCB * pCCB ); virtual CG_STATUS GenSizing( CCB * pCCB ); virtual CG_STATUS GenFree( CCB * pCCB ); virtual CG_STATUS S_GenInitOutLocals( CCB * pCCB ); virtual CG_STATUS S_GenInitTopLevelStuff( CCB * pCCB ); expr_node * GetFinalExpression(); }; #endif // __PROCCLS_HXX__