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

2197 lines
73 KiB
C++

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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 <stdio.h>
}
#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__