597 lines
20 KiB
C++
597 lines
20 KiB
C++
|
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
Copyright (c) 1989-1999 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
bindcls.hxx
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Contains definitions for binding related code generation class definitions.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
|
||
|
History:
|
||
|
|
||
|
VibhasC Sep-18-1993 Created.
|
||
|
----------------------------------------------------------------------------*/
|
||
|
#ifndef __BINDCLS_HXX__
|
||
|
#define __BINDCLS_HXX__
|
||
|
|
||
|
#include "nulldefs.h"
|
||
|
|
||
|
extern "C"
|
||
|
{
|
||
|
#include <stdio.h>
|
||
|
|
||
|
}
|
||
|
|
||
|
#include "ndrcls.hxx"
|
||
|
#include "ilxlat.hxx"
|
||
|
|
||
|
#if 0
|
||
|
|
||
|
Although not apparent, a large occurence of binding handle parameters need
|
||
|
the parameter be shipped on the wire. Generic handles get shipped as
|
||
|
ordinary data and context handles as a special representation. The only
|
||
|
class that does not ship anything is primitive handles. Their usage is
|
||
|
rare. Since most binding handle usage WILL result in shipped data, it
|
||
|
warrants a special code generation class of its own.
|
||
|
|
||
|
The usage of the handles is either explicit or implicit. Therefore, the
|
||
|
binding handle class will appear as an explicit child of a param
|
||
|
cg class if there is an explicit handle. The proc cg class always keeps
|
||
|
a ptr to a binding handle class on its own anyway. So in case of explicit
|
||
|
handles, the binding handle class pointer points to another cg class which
|
||
|
is in the param list. In case of implicit handles, there is a new binding
|
||
|
class instance created which is local only to the proc cg class. Therefore,
|
||
|
in both cases, after the IL translation is done, an explicit or implicit
|
||
|
handle looks the same to the analyser and code generation.
|
||
|
|
||
|
If any handle is part of the parameter list, then the handle will get
|
||
|
the GenCode and other related messages. An implicit handle will not be in
|
||
|
the normal parameter list and therefore will never get the code generation
|
||
|
messages. Therefore we dont really need to define implicit or explicit
|
||
|
classes deriving out of the basic handle classes. Handle classes will
|
||
|
implement the code generation methods appropriately and therefore the
|
||
|
differentiation between explicit and implicit will be based purely on
|
||
|
whether an instance of a class gets the code generation message or not.
|
||
|
Only the proc node needs to know if the handle is explicit or implicit,
|
||
|
and that it can do with a flag.
|
||
|
|
||
|
#endif // 0
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// The general binding handle class.
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
class CG_HANDLE : public CG_NDR
|
||
|
{
|
||
|
private:
|
||
|
|
||
|
//
|
||
|
// The type represented in this field is the type of the actual handle.
|
||
|
// Therefore, in case of a generic handle, this field will get the typedef
|
||
|
// node on which the [handle] attribute was applied. In case of a
|
||
|
// context_handle, this is either the typedef node on which [context_handle]
|
||
|
// was applied or the basic type of the parameter node on which the
|
||
|
// [context_handle] was applied. Therefore this field keeps the actual
|
||
|
// handle type.
|
||
|
|
||
|
// Remember this class derives from an ndr code gen class, so that has a
|
||
|
// type node pointer of its own. That is actually the pointer to the param
|
||
|
// node which is the binding handle. In case of implicit handles, that
|
||
|
// field is not relevant and can be 0.
|
||
|
//
|
||
|
|
||
|
node_skl * pHandleType;
|
||
|
|
||
|
//
|
||
|
// The actual param param or id node.
|
||
|
//
|
||
|
|
||
|
node_skl * pHandleIDOrParam;
|
||
|
|
||
|
//
|
||
|
// Offset to binding format string description.
|
||
|
//
|
||
|
long NdrBindDescriptionOffset;
|
||
|
|
||
|
public:
|
||
|
|
||
|
|
||
|
//
|
||
|
// The constructor. Note again that 2 params are required in most cases,
|
||
|
// the first representing the actual type of the handle, and the seconf
|
||
|
// param which is the node_skl of the actual parameter node which is the
|
||
|
// handle. In case of implicit handles, this can be 0.
|
||
|
//
|
||
|
|
||
|
CG_HANDLE( node_skl * pHT, // handle type.
|
||
|
node_skl * pHP, // handle param or 0.
|
||
|
XLAT_SIZE_INFO & Info // memory size
|
||
|
) : CG_NDR(pHP, Info )
|
||
|
{
|
||
|
pHandleType = pHT;
|
||
|
pHandleIDOrParam = pHP;
|
||
|
NdrBindDescriptionOffset = -1;
|
||
|
}
|
||
|
|
||
|
virtual
|
||
|
void Visit( CG_VISITOR *pVisitor ) = 0;
|
||
|
|
||
|
//
|
||
|
// Get and set methods.
|
||
|
//
|
||
|
|
||
|
node_skl * SetHandleType( node_skl * pHT )
|
||
|
{
|
||
|
return (pHandleType = pHT);
|
||
|
}
|
||
|
|
||
|
node_skl * GetHandleType()
|
||
|
{
|
||
|
return pHandleType;
|
||
|
}
|
||
|
|
||
|
node_skl * GetHandleIDOrParam()
|
||
|
{
|
||
|
return pHandleIDOrParam;
|
||
|
}
|
||
|
|
||
|
void SetNdrBindDescriptionOffset( long Offset )
|
||
|
{
|
||
|
NdrBindDescriptionOffset = Offset;
|
||
|
}
|
||
|
|
||
|
long GetNdrBindDescriptionOffset()
|
||
|
{
|
||
|
return NdrBindDescriptionOffset;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Queries.
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// Queries here should generally return a false, since the derived classes
|
||
|
// should implement the methods and return the correct result.
|
||
|
//
|
||
|
|
||
|
virtual
|
||
|
BOOL IsPrimitiveHandle()
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
virtual
|
||
|
BOOL IsGenericHandle()
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
virtual
|
||
|
BOOL IsContextHandle()
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
virtual
|
||
|
BOOL IsAHandle()
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Format string generation for the bind handle description in a
|
||
|
// procedure's description.
|
||
|
//
|
||
|
|
||
|
virtual
|
||
|
unsigned char MakeExplicitHandleFlag(
|
||
|
CG_PARAM * pHandleParam );
|
||
|
|
||
|
virtual
|
||
|
void GetNdrHandleInfo( CCB *, NDR64_BINDINGS * )
|
||
|
{
|
||
|
// Should be redefined by inheriting classes.
|
||
|
MIDL_ASSERT(0);
|
||
|
}
|
||
|
|
||
|
virtual
|
||
|
void GenNdrHandleFormat( CCB * )
|
||
|
{
|
||
|
// Should be redefined by inheriting classes.
|
||
|
MIDL_ASSERT(0);
|
||
|
}
|
||
|
|
||
|
virtual
|
||
|
void GenNdrParamDescription( CCB * pCCB );
|
||
|
|
||
|
virtual
|
||
|
void GenNdrParamDescriptionOld( CCB * pCCB );
|
||
|
|
||
|
virtual
|
||
|
long FixedBufferSize( CCB * )
|
||
|
{
|
||
|
return - 1;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
// The auto handle class.
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
class CG_PRIMITIVE_HANDLE : public CG_HANDLE
|
||
|
{
|
||
|
private:
|
||
|
public:
|
||
|
|
||
|
//
|
||
|
// The constructors.
|
||
|
//
|
||
|
|
||
|
CG_PRIMITIVE_HANDLE( node_skl * pHT,
|
||
|
node_skl * pHP,
|
||
|
XLAT_SIZE_INFO & Info // memory size
|
||
|
):
|
||
|
CG_HANDLE( pHT, pHP, Info )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
virtual
|
||
|
ID_CG GetCGID()
|
||
|
{
|
||
|
return ID_CG_PRIMITIVE_HDL;
|
||
|
}
|
||
|
virtual
|
||
|
void Visit( CG_VISITOR *pVisitor )
|
||
|
{
|
||
|
pVisitor->Visit( this );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Queries. An auto handle is treated as an implicit primitive handle.
|
||
|
//
|
||
|
|
||
|
virtual
|
||
|
BOOL IsPrimitiveHandle()
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Generate the format string for a handle.
|
||
|
//
|
||
|
virtual
|
||
|
void GenNdrFormat( CCB * pCCB );
|
||
|
|
||
|
//
|
||
|
// This method is called to generate offline portions of a type's
|
||
|
// format string.
|
||
|
//
|
||
|
virtual
|
||
|
void GenNdrParamOffline( CCB * pCCB );
|
||
|
|
||
|
virtual
|
||
|
void GenNdrParamDescription( CCB * pCCB );
|
||
|
|
||
|
virtual
|
||
|
void GenNdrParamDescriptionOld( CCB * pCCB );
|
||
|
|
||
|
virtual
|
||
|
void GetNdrHandleInfo( CCB *, NDR64_BINDINGS * );
|
||
|
|
||
|
virtual
|
||
|
void GenNdrHandleFormat( CCB * pCCB );
|
||
|
|
||
|
virtual
|
||
|
long FixedBufferSize( CCB * )
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
virtual
|
||
|
CG_STATUS MarshallAnalysis( ANALYSIS_INFO * )
|
||
|
{
|
||
|
return CG_OK;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
// The generic handle class.
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
//
|
||
|
// The generic handle drives off the name of the type which was defined as
|
||
|
// a handle. The typedef node, which is the handle type serves as the
|
||
|
// placeholder for the name of the handle.
|
||
|
//
|
||
|
|
||
|
class CG_GENERIC_HANDLE : public CG_HANDLE
|
||
|
{
|
||
|
private:
|
||
|
public:
|
||
|
//
|
||
|
// The constructor. The generic handle class needs info about the type
|
||
|
// of the handle. The typedef node on which the [handle] was applied,
|
||
|
// can serve as a placeholder for the name too. The second need is the
|
||
|
// parameter node which is the handle param in case the handle was an
|
||
|
// explicit parameter, or the id node of the implicit handle.
|
||
|
//
|
||
|
CG_GENERIC_HANDLE( node_skl * pHT,
|
||
|
node_skl * pHP,
|
||
|
XLAT_SIZE_INFO & Info // memory size
|
||
|
) :
|
||
|
CG_HANDLE( pHT, pHP, Info )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
virtual
|
||
|
ID_CG GetCGID()
|
||
|
{
|
||
|
return ID_CG_GENERIC_HDL;
|
||
|
}
|
||
|
virtual
|
||
|
void Visit( CG_VISITOR *pVisitor )
|
||
|
{
|
||
|
pVisitor->Visit( this );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Get and set methods.
|
||
|
//
|
||
|
|
||
|
PNAME GetHandleTypeName()
|
||
|
{
|
||
|
return GetHandleType()->GetSymName();
|
||
|
}
|
||
|
|
||
|
long GetImplicitSize()
|
||
|
{
|
||
|
return 4;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Queries.
|
||
|
//
|
||
|
|
||
|
virtual
|
||
|
BOOL IsGenericHandle()
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
virtual
|
||
|
BOOL HasAFixedBufferSize()
|
||
|
{
|
||
|
return GetChild()->HasAFixedBufferSize();
|
||
|
}
|
||
|
virtual
|
||
|
CG_STATUS MarshallAnalysis( ANALYSIS_INFO * pAna )
|
||
|
{
|
||
|
return ((CG_NDR *)GetChild())->MarshallAnalysis( pAna );
|
||
|
}
|
||
|
virtual
|
||
|
CG_STATUS UnMarshallAnalysis( ANALYSIS_INFO * pAna )
|
||
|
{
|
||
|
return ((CG_NDR *)GetChild())->UnMarshallAnalysis( pAna );
|
||
|
}
|
||
|
virtual
|
||
|
CG_STATUS S_OutLocalAnalysis( ANALYSIS_INFO * pAna )
|
||
|
{
|
||
|
return ((CG_NDR *)GetChild())->S_OutLocalAnalysis( pAna );
|
||
|
}
|
||
|
virtual
|
||
|
CG_STATUS S_GenInitOutLocals( CCB * pCCB )
|
||
|
{
|
||
|
return ((CG_NDR *)GetChild())->S_GenInitOutLocals( pCCB );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Generate the format string for a handle.
|
||
|
//
|
||
|
virtual
|
||
|
void GenNdrFormat( CCB * pCCB );
|
||
|
|
||
|
//
|
||
|
// This method is called to generate offline portions of a type's
|
||
|
// format string.
|
||
|
//
|
||
|
virtual
|
||
|
void GenNdrParamOffline( CCB * pCCB );
|
||
|
|
||
|
virtual
|
||
|
void GenNdrParamDescription( CCB * pCCB );
|
||
|
|
||
|
virtual
|
||
|
void GetNdrParamAttributes(
|
||
|
CCB * pCCB,
|
||
|
PARAM_ATTRIBUTES *attributes );
|
||
|
|
||
|
virtual
|
||
|
void GenNdrParamDescriptionOld( CCB * pCCB );
|
||
|
|
||
|
virtual
|
||
|
void GetNdrHandleInfo( CCB *, NDR64_BINDINGS * );
|
||
|
|
||
|
virtual
|
||
|
void GenNdrHandleFormat( CCB * pCCB );
|
||
|
|
||
|
virtual
|
||
|
BOOL ShouldFreeOffline()
|
||
|
{
|
||
|
return ((CG_NDR *)GetChild())->
|
||
|
ShouldFreeOffline();
|
||
|
}
|
||
|
|
||
|
virtual
|
||
|
void GenFreeInline( CCB * pCCB )
|
||
|
{
|
||
|
((CG_NDR *)GetChild())->GenFreeInline( pCCB );
|
||
|
}
|
||
|
|
||
|
virtual
|
||
|
long FixedBufferSize( CCB * pCCB )
|
||
|
{
|
||
|
return
|
||
|
((CG_NDR *)GetChild())->FixedBufferSize( pCCB );
|
||
|
}
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
// The context handle class.
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
|
||
|
class CG_CONTEXT_HANDLE : public CG_HANDLE
|
||
|
{
|
||
|
private:
|
||
|
bool fStrictContext;
|
||
|
bool fNoSerialize;
|
||
|
bool fSerialize;
|
||
|
bool fCannotBeNull;
|
||
|
char* pRundownRoutineName;
|
||
|
|
||
|
public:
|
||
|
CG_CONTEXT_HANDLE (
|
||
|
node_skl * pHT,
|
||
|
node_skl * pHP,
|
||
|
XLAT_CTXT& Info
|
||
|
) :
|
||
|
CG_HANDLE( pHT, pHP, ( XLAT_SIZE_INFO& ) Info),
|
||
|
pRundownRoutineName( 0 )
|
||
|
|
||
|
{
|
||
|
fStrictContext = Info.GetInterfaceContext()
|
||
|
->GetAttribute( ATTR_STRICT_CONTEXT_HANDLE ) != 0;
|
||
|
fNoSerialize = Info.ExtractAttribute( ATTR_NOSERIALIZE ) != 0;
|
||
|
fSerialize = Info.ExtractAttribute( ATTR_SERIALIZE ) != 0;
|
||
|
fCannotBeNull = false;
|
||
|
}
|
||
|
|
||
|
virtual
|
||
|
ID_CG GetCGID()
|
||
|
{
|
||
|
return ID_CG_CONTEXT_HDL;
|
||
|
}
|
||
|
|
||
|
virtual
|
||
|
void Visit( CG_VISITOR *pVisitor )
|
||
|
{
|
||
|
pVisitor->Visit( this );
|
||
|
}
|
||
|
|
||
|
virtual
|
||
|
BOOL IsContextHandle()
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
bool GetCannotBeNull()
|
||
|
{
|
||
|
return fCannotBeNull;
|
||
|
}
|
||
|
|
||
|
void SetCannotBeNull()
|
||
|
{
|
||
|
fCannotBeNull = true;
|
||
|
}
|
||
|
|
||
|
BOOL HasNewContextFlavor()
|
||
|
{
|
||
|
return fStrictContext || fNoSerialize || fSerialize;
|
||
|
}
|
||
|
|
||
|
BOOL HasSerialize()
|
||
|
{
|
||
|
return fSerialize;
|
||
|
}
|
||
|
|
||
|
BOOL HasNoSerialize()
|
||
|
{
|
||
|
return fNoSerialize;
|
||
|
}
|
||
|
|
||
|
BOOL HasStrict()
|
||
|
{
|
||
|
return fStrictContext;
|
||
|
}
|
||
|
|
||
|
PNAME GetRundownRtnName();
|
||
|
|
||
|
virtual
|
||
|
CG_STATUS MarshallAnalysis( ANALYSIS_INFO * pAna );
|
||
|
|
||
|
virtual
|
||
|
CG_STATUS UnMarshallAnalysis( ANALYSIS_INFO * pAna );
|
||
|
|
||
|
virtual
|
||
|
CG_STATUS S_GenInitOutLocals( CCB * pCCB );
|
||
|
|
||
|
//
|
||
|
// Generate the format string for a handle.
|
||
|
//
|
||
|
virtual
|
||
|
void GenNdrFormat( CCB * pCCB );
|
||
|
|
||
|
//
|
||
|
// This method is called to generate offline portions of a type's
|
||
|
// format string.
|
||
|
//
|
||
|
virtual
|
||
|
void GenNdrParamOffline( CCB * pCCB );
|
||
|
|
||
|
virtual
|
||
|
void GenNdrParamDescription( CCB * pCCB );
|
||
|
|
||
|
virtual
|
||
|
void GetNdrParamAttributes(
|
||
|
CCB * pCCB,
|
||
|
PARAM_ATTRIBUTES *attributes );
|
||
|
|
||
|
virtual
|
||
|
void GenNdrParamDescriptionOld( CCB * pCCB );
|
||
|
|
||
|
virtual
|
||
|
unsigned char MakeExplicitHandleFlag(
|
||
|
CG_PARAM * pHandleParam );
|
||
|
|
||
|
virtual
|
||
|
void GetNdrHandleInfo( CCB *, NDR64_BINDINGS * );
|
||
|
|
||
|
virtual
|
||
|
void GenNdrHandleFormat( CCB * pCCB );
|
||
|
|
||
|
virtual
|
||
|
long FixedBufferSize( CCB * )
|
||
|
{
|
||
|
return MAX_WIRE_ALIGNMENT + 20;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
class CG_ASYNC_HANDLE : public CG_NDR
|
||
|
{
|
||
|
private:
|
||
|
|
||
|
public:
|
||
|
CG_ASYNC_HANDLE(node_skl* pType,
|
||
|
XLAT_SIZE_INFO& Info) : CG_NDR( pType, Info )
|
||
|
{
|
||
|
SetSStubAllocLocation( S_STUB_ALLOC_LOCATION_UNKNOWN );
|
||
|
SetSStubAllocType( S_STUB_ALLOC_TYPE_NONE );
|
||
|
SetSStubInitNeed( S_STUB_INIT_NOT_NEEDED );
|
||
|
}
|
||
|
|
||
|
virtual
|
||
|
void Visit( CG_VISITOR *pVisitor )
|
||
|
{
|
||
|
pVisitor->Visit( this );
|
||
|
}
|
||
|
|
||
|
ID_CG GetCGID()
|
||
|
{
|
||
|
return ID_CG_ASYNC_HANDLE;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
#endif // __BINDCLS_HXX__
|