803 lines
18 KiB
C++
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__
|