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

803 lines
18 KiB
C++

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 1989-1999 Microsoft Corporation
Module Name:
stcls.hxx
Abstract:
Contains definitions for base type related code generation class
definitions.
Notes:
History:
GregJen Sep-30-1993 Created.
----------------------------------------------------------------------------*/
#ifndef __STCLS_HXX__
#define __STCLS_HXX__
#pragma warning ( disable : 4238 4239 )
#include "nulldefs.h"
extern "C"
{
#include <stdio.h>
}
#include "ndrcls.hxx"
class CG_ARRAY;
class ANALYSIS_INFO;
class CG_FIELD;
//
// This class is the base type for compound things like
// structures, unions, and fields
//
class CG_COMP : public CG_NDR
{
private:
unsigned short Zp;
BOOL fHasPointer : 1;
//
// this flag is set if there are fields with different mem and wire offsets
//
BOOL fHasMovedFields : 1;
expr_node * pSizeExpression;
public:
//
// The constructor.
//
CG_COMP(
node_skl * pBT, // base type
XLAT_SIZE_INFO & Info, // packing and size info
unsigned short HP
) :
CG_NDR( pBT, Info )
{
SetZp( Info.GetZeePee() );
SetHasPointer(HP);
ResetHasMovedFields();
SetSizeExpression( 0 );
}
virtual
void Visit( CG_VISITOR *pVisitor ) = 0;
//
// Get and set methods.
//
// make sure the ZP gets set along the way
virtual
void SetSizesAndAlignments( XLAT_SIZE_INFO & Info )
{
CG_NDR::SetSizesAndAlignments( Info );
SetZp( Info.GetZeePee() );
}
expr_node * SetSizeExpression( expr_node * pE )
{
return (pSizeExpression = pE);
}
expr_node * GetSizeExpression()
{
return pSizeExpression;
}
unsigned short SetZp( unsigned short ZP )
{
return (Zp = ZP);
}
unsigned short GetZp()
{
return Zp;
}
BOOL SetHasMovedFields()
{
return (fHasMovedFields = TRUE);
}
BOOL ResetHasMovedFields()
{
return (fHasMovedFields = FALSE);
}
BOOL HasMovedFields()
{
return fHasMovedFields;
}
BOOL SetHasPointer( BOOL HP )
{
return (fHasPointer = HP);
}
BOOL HasPointer()
{
return fHasPointer;
}
virtual
CG_STATUS S_GenInitOutLocals( CCB * pCCB );
virtual
CG_STATUS S_OutLocalAnalysis( ANALYSIS_INFO * pAna );
virtual
short GetPointerMembers( ITERATOR& I );
virtual
CG_STATUS RefCheckAnalysis( ANALYSIS_INFO * )
{
return CG_OK;
}
virtual
CG_STATUS InLocalAnalysis( ANALYSIS_INFO * )
{
return CG_OK;
}
virtual
CG_STATUS S_GenInitInLocals( CCB * )
{
return CG_OK;
}
virtual
CG_STATUS GenRefChecks( CCB * )
{
return CG_OK;
}
};
/////////////////////////////////////////////////////////////////////////////
// the structure code generation classes.
/////////////////////////////////////////////////////////////////////////////
class CG_COMPLEX_STRUCT;
//
// This class corresponds to a vanilla structure type.
//
class CG_STRUCT : public CG_COMP, public CG_CLONEABLE
{
private:
void * _pCTI;
// This is needed for recursive embedded complex fixups.
CG_COMPLEX_STRUCT * pDuplicatingComplex;
public:
//
// The constructor.
//
CG_STRUCT(
node_skl * pBT, // base type
XLAT_SIZE_INFO & Info, // memory size, etc
unsigned short HP // Has pointer
) :
CG_COMP( pBT, Info, HP )
{
_pCTI = NULL;
pDuplicatingComplex = NULL;
}
CG_STRUCT( CG_STRUCT * pStruct ) :
CG_COMP( pStruct->GetType(),
XLAT_SIZE_INFO(), // overwritten by copy below
( unsigned short )pStruct->HasPointer() )
{
// Make sure we copy everything.
*this = *pStruct;
}
//
// Generate typeinfo
//
virtual
CG_STATUS GenTypeInfo( CCB * pCCB);
virtual
ID_CG GetCGID()
{
return ID_CG_STRUCT;
}
virtual
void Visit( CG_VISITOR *pVisitor )
{
pVisitor->Visit( this );
}
virtual
CG_CLASS* Clone()
{
return new CG_STRUCT( *this );
}
// Unroll imbeded structure members.
void Unroll();
BOOL HasSizedPointer();
//
// Get and set methods.
//
virtual
BOOL IsStruct()
{
return TRUE;
}
BOOL IsComplexStruct();
CG_COMPLEX_STRUCT * GetDuplicatingComplex()
{
return( pDuplicatingComplex );
}
void SetDuplicatingComplex( CG_COMPLEX_STRUCT * pC )
{
pDuplicatingComplex = pC;
}
BOOL IsHardStruct();
BOOL IsHardStructOld();
virtual
bool IsHomogeneous(FORMAT_CHARACTER format);
long GetNumberOfPointers();
long GetNumberOfEnum16s();
long GetNumberOfUnions();
CG_FIELD * GetFinalField();
CG_FIELD * GetArrayField( CG_ARRAY * pArray );
long GetEnum16Offset();
//
// Generate the Ndr format string for the type.
//
virtual
void GenNdrFormat( CCB * pCCB );
//
// Generate the description for a "hard" structure.
//
void GenNdrFormatHard( CCB * pCCB );
//
// Generate the description for a "complex" structure.
//
void GenNdrFormatComplex( CCB * pCCB );
//
// Ndr format string generation methods shared by all structure classes
// except CG_COMPLEX_STRUCT, which redefines both of these methods.
//
virtual
void GenNdrStructurePointerLayout( CCB * pCCB,
BOOL fNoPP,
BOOL fNoType );
void GenStructureMemPad( CCB * pCCB, unsigned long MemPad );
virtual
void GenNdrStructureLayout( CCB * pCCB );
virtual
BOOL ShouldFreeOffline();
virtual
void GenFreeInline( CCB * pCCB );
//
// One more Ndr format string generation method. This time shared by all
// structure classes, so it's not a virtual.
//
void GenNdrStructurePointees( CCB * pCCB );
virtual
long FixedBufferSize( CCB * pCCB );
BOOL InterpreterMustFree( CCB * ) { return TRUE; }
CG_FIELD * GetPreviousField( CG_FIELD * pField );
virtual
CG_STATUS MarshallAnalysis( ANALYSIS_INFO * pAna );
virtual
CG_STATUS UnMarshallAnalysis( ANALYSIS_INFO * pAna );
virtual
BOOL HasAFixedBufferSize();
};
//
// This class corresponds to a encapsulated structure type.
//
class CG_ENCAPSULATED_STRUCT : public CG_STRUCT
{
private:
public:
//
// The constructor.
//
CG_ENCAPSULATED_STRUCT(
node_skl * pBT, // base type
XLAT_SIZE_INFO & Info, // memory size, etc
unsigned short HP // Has pointer
) :
CG_STRUCT( pBT, Info, HP )
{
}
virtual
ID_CG GetCGID()
{
return ID_CG_ENCAP_STRUCT;
}
virtual
void Visit( CG_VISITOR *pVisitor )
{
pVisitor->Visit( this );
}
virtual
CG_CLASS* Clone()
{
return new CG_ENCAPSULATED_STRUCT( *this );
}
BOOL IsVarying()
{
return TRUE;
}
//
// Redefine this method, which CG_STRUCT defines.
//
virtual
BOOL IsStruct()
{
return FALSE;
}
//
// This is, for all intents and purposes, a union.
//
virtual
BOOL IsUnion()
{
return TRUE;
}
//
// Get and set methods.
//
//
// Generate the Ndr format string for the type.
//
virtual
void GenNdrFormat( CCB * pCCB );
virtual
BOOL ShouldFreeOffline();
virtual
void GenFreeInline( CCB * )
{
}
virtual
void GenNdrPointerFixUp( CCB * pCCB,
CG_STRUCT * pStruct );
long FixedBufferSize( CCB * )
{
return -1;
}
virtual
BOOL HasAFixedBufferSize()
{
return FALSE;
}
};
//
// This class corresponds to a conformant structure type.
//
// The pConfFld entry points to the CG_FIELD of this structure that describes
// the conformance. If the conformance is due to an embedded struct, then
// it points to the CG_FIELD above the embedded conformant structure
//
// The actual conformance is described by a CG_xxx_ARRAY somewhere below the
// CG_FIELD.
//
class CG_CONFORMANT_STRUCT : public CG_STRUCT
{
private:
CG_CLASS * pConfFld;
public:
//
// The constructor.
//
CG_CONFORMANT_STRUCT(
node_skl * pBT, // base type
XLAT_SIZE_INFO & Info, // memory size
unsigned short HP, // Has pointer
CG_CLASS * pCF // conformant field
) :
CG_STRUCT( pBT, Info, HP )
{
SetConformantField( pCF );
}
CG_CONFORMANT_STRUCT(
CG_STRUCT * pStruct,
CG_CLASS * pCF
) :
CG_STRUCT( pStruct )
{
SetConformantField( pCF );
}
virtual
ID_CG GetCGID()
{
return ID_CG_CONF_STRUCT;
}
virtual
CG_CLASS* Clone()
{
return new CG_CONFORMANT_STRUCT( *this );
}
virtual
void Visit( CG_VISITOR *pVisitor )
{
pVisitor->Visit( this );
}
//
// Get and set methods.
//
CG_CLASS * SetConformantField( CG_CLASS * pCF )
{
return (pConfFld = pCF);
}
CG_CLASS * GetConformantField()
{
return pConfFld;
}
//
// Dig down into the bowels of the CG class graph and get my
// conformant array class.
// Return a CG_ARRAY pointer since both conformant and conformant
// varying arrays inherit this.
//
CG_ARRAY * GetConformantArray();
};
//
// This class corresponds to a vanilla structure type.
//
class CG_CONFORMANT_VARYING_STRUCT : public CG_CONFORMANT_STRUCT
{
private:
public:
//
// The constructor.
//
CG_CONFORMANT_VARYING_STRUCT(
node_skl * pBT, // base type
XLAT_SIZE_INFO & Info, // memory size, etc
unsigned short HP, // Has pointer
CG_CLASS * pCF // conformant field
) :
CG_CONFORMANT_STRUCT( pBT, Info, HP, pCF )
{
}
virtual
ID_CG GetCGID()
{
return ID_CG_CONF_VAR_STRUCT;
}
virtual
CG_CLASS* Clone()
{
return new CG_CONFORMANT_VARYING_STRUCT( *this );
}
virtual
void Visit( CG_VISITOR *pVisitor )
{
pVisitor->Visit( this );
}
virtual
BOOL HasAFixedBufferSize()
{
return FALSE;
}
};
//
// This class corresponds to a vanilla structure type.
//
class CG_COMPLEX_STRUCT : public CG_CONFORMANT_STRUCT
{
private:
//
// Struct from which we were duplicated, if any. This is used for
// handling packed structures.
//
CG_STRUCT * pDuplicatedStruct;
public:
//
// The constructor.
//
CG_COMPLEX_STRUCT(
node_skl * pBT, // base type
XLAT_SIZE_INFO & Info, // memory size, etc
unsigned short HP, // Has pointer
CG_CLASS * pCF // conformant field
) :
CG_CONFORMANT_STRUCT( pBT, Info, HP, pCF )
{
pDuplicatedStruct = 0;
}
CG_COMPLEX_STRUCT(
CG_STRUCT * pStruct,
CG_CLASS * pCF
) :
CG_CONFORMANT_STRUCT( pStruct, pCF )
{
pDuplicatedStruct = pStruct;
}
virtual
ID_CG GetCGID()
{
return ID_CG_COMPLEX_STRUCT;
}
virtual
CG_CLASS* Clone()
{
return new CG_COMPLEX_STRUCT( *this );
}
virtual
void Visit( CG_VISITOR *pVisitor )
{
pVisitor->Visit( this );
}
BOOL IsVarying()
{
return TRUE;
}
//
// Get and set methods.
//
CG_STRUCT * GetDuplicatedStruct()
{
return pDuplicatedStruct;
}
//
// Generate the Ndr format string for the type.
//
virtual
void GenNdrFormat( CCB * pCCB );
virtual
void GenNdrStructurePointerLayout( CCB * pCCB );
BOOL WarnAboutEmbeddedComplexStruct();
};
//
// New Class for 64bit NDR
//
#define DECLARE_STRUCT_CG_CLASS( NEWTYPE, BASETYPE ) \
class NEWTYPE : public BASETYPE \
{ \
protected: \
NEWTYPE( const NEWTYPE & Node ) : \
BASETYPE( Node ) {} \
public: \
NEWTYPE(node_skl *pType, \
XLAT_SIZE_INFO & Info, \
BOOL HP ) : \
BASETYPE( pType, \
Info, \
(unsigned short)HP, \
NULL ) {} \
\
virtual CG_CLASS* Clone() { return new NEWTYPE(*this); } \
virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); } \
}; \
DECLARE_STRUCT_CG_CLASS( CG_FULL_COMPLEX_STRUCT, CG_COMPLEX_STRUCT )
DECLARE_STRUCT_CG_CLASS( CG_FORCED_COMPLEX_STRUCT, CG_COMPLEX_STRUCT )
DECLARE_STRUCT_CG_CLASS( CG_CONFORMANT_FULL_COMPLEX_STRUCT, CG_COMPLEX_STRUCT )
DECLARE_STRUCT_CG_CLASS( CG_CONFORMANT_FORCED_COMPLEX_STRUCT, CG_COMPLEX_STRUCT )
//
// Block copyable regions for 64bit NDR
//
// Do not instantiate CG_REGION directly since it is a base class.
class CG_REGION : public CG_STRUCT
{
protected:
CG_REGION( const CG_REGION & Node ) :
CG_STRUCT( Node )
{}
CG_REGION(CG_COMPLEX_STRUCT *pComplexStruct,
XLAT_SIZE_INFO & Info,
BOOL HP) :
CG_STRUCT(pComplexStruct->GetType(),
Info,
(unsigned short)HP)
{
}
public:
virtual CG_CLASS* Clone() = 0;
virtual void Visit( CG_VISITOR *pVisitor ) = 0;
};
// Small region without any pointers
class CG_SIMPLE_REGION : public CG_REGION
{
protected:
CG_SIMPLE_REGION( const CG_REGION & Node ) :
CG_REGION( Node )
{}
public:
CG_SIMPLE_REGION( CG_COMPLEX_STRUCT *pComplexStruct,
XLAT_SIZE_INFO & Info ) :
CG_REGION( pComplexStruct,
Info,
FALSE )
{}
virtual CG_CLASS* Clone() { return new CG_SIMPLE_REGION(*this); }
virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); }
};
// Larger region or region with pointers
class CG_COMPLEX_REGION : public CG_REGION
{
protected:
CG_COMPLEX_REGION( const CG_REGION & Node ) :
CG_REGION( Node )
{}
public:
CG_COMPLEX_REGION( CG_COMPLEX_STRUCT *pComplexStruct,
XLAT_SIZE_INFO & Info,
BOOL HP ) :
CG_REGION( pComplexStruct,
Info,
HP )
{}
virtual CG_CLASS* Clone() { return new CG_COMPLEX_REGION(*this); }
virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); }
};
// Represents a buffer pad.
class CG_PAD : public CG_NDR
{
private:
public:
//
// The constructor.
//
CG_PAD( node_skl *pType,
XLAT_SIZE_INFO & Info ) :
CG_NDR( pType, Info )
{
}
virtual
CG_CLASS * Clone()
{
return new CG_PAD( *this );
}
virtual
ID_CG GetCGID()
{
return ID_CG_PAD;
}
virtual
void Visit( CG_VISITOR *pVisitor )
{
pVisitor->Visit( this );
}
//
// Ndr format string generation method.
//
virtual
void GenNdrFormat( CCB * pCCB )
{
FORMAT_STRING * pFormat = pCCB->GetFormatString();
pFormat->PushFormatChar( FC_BUFFER_ALIGN );
pFormat->PushByte( GetWireAlignment() - 1 );
}
};
#endif // __STCLS_HXX__