windows-nt/Source/XPSP1/NT/com/rpc/midl/codegen/ilctxt.cxx

579 lines
13 KiB
C++
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 1989-1999 Microsoft Corporation
Module Name:
ilctxt.cxx
Abstract:
Intermediate Language translator context management routines
Notes:
Author:
GregJen Jun-11-1993 Created.
Notes:
----------------------------------------------------------------------------*/
/****************************************************************************
* include files
***************************************************************************/
#include "becls.hxx"
#pragma hdrstop
#include "nodeskl.hxx"
#include "ilxlat.hxx"
#include "cmdana.hxx"
#include "optprop.hxx"
#include "ilreg.hxx"
#include "ndrcls.hxx"
/****************************************************************************
* externs
***************************************************************************/
extern CMD_ARG * pCommand;
/****************************************************************************
* definitions
***************************************************************************/
// #define trace_cg
//--------------------------------------------------------------------
//
// XLAT_SIZE_INFO::XLAT_SIZE_INFO
//
// Notes:
//
//
//
//--------------------------------------------------------------------
XLAT_SIZE_INFO::XLAT_SIZE_INFO(
CG_NDR * pCG )
{
ZeePee = pCommand->GetZeePee();
MemAlign = pCG->GetMemoryAlignment();
WireAlign = pCG->GetWireAlignment();
MemSize = pCG->GetMemorySize();
WireSize = pCG->GetWireSize();
MemOffset = 0;
WireOffset = 0;
MustAlign = false;
}
//--------------------------------------------------------------------
//
// ::RoundToAlignment
//
// Helper round-up routine
//
// Notes:
//
//
//
//--------------------------------------------------------------------
inline unsigned long
RoundToAlignment( unsigned long & Offset, unsigned short Alignment )
{
unsigned long AlignFactor = Alignment - 1;
return (Offset = (Offset + AlignFactor) & ~AlignFactor );
}
//--------------------------------------------------------------------
//
// XLAT_SIZE_INFO::BaseTypeSizes
//
// Notes:
//
// Merges attributes for a base type with the given context.
//
//--------------------------------------------------------------------
void
XLAT_SIZE_INFO::BaseTypeSizes( node_skl * pNode )
{
unsigned short MS, WS;
switch( pNode->NodeKind() )
{
case NODE_DOUBLE:
case NODE_HYPER:
case NODE_INT64:
case NODE_LONGLONG:
{
MS=8; WS=8;
break;
};
case NODE_INT128:
case NODE_FLOAT80: //BUG, BUG double check this once VC supports
case NODE_FLOAT128:
{
MS=16; WS = 16;
break;
}
case NODE_POINTER:
case NODE_HANDLE_T:
{
MS = (unsigned short) SIZEOF_MEM_PTR();
WS = (unsigned short) SIZEOF_WIRE_PTR();
break;
};
case NODE_INT3264:
{
MS = (unsigned short) SIZEOF_MEM_INT3264();
WS = (unsigned short) SIZEOF_WIRE_INT3264();
break;
};
case NODE_FLOAT:
case NODE_LONG:
case NODE_INT32:
case NODE_INT:
case NODE_E_STATUS_T:
{
MS=4; WS=4;
break;
};
case NODE_SHORT:
case NODE_WCHAR_T:
{
MS=2; WS=2;
break;
};
case NODE_SMALL:
case NODE_CHAR:
case NODE_BOOLEAN:
case NODE_BYTE:
{
MS=1; WS=1;
break;
};
default:
{
MS=0; WS=0;
break;
}
}
GetMemSize() = MS;
GetMemAlign() = __max(MS,GetMemAlign());
GetWireSize() = WS;
GetWireAlign() = __max(WS,GetWireAlign());
};
//--------------------------------------------------------------------
//
// XLAT_SIZE_INFO::EnumTypeSizes
//
// Notes:
//
// Merges in the sizes for an enum.
//
//--------------------------------------------------------------------
void
XLAT_SIZE_INFO::EnumTypeSizes( node_skl*, BOOL Enum32 )
/*
Called when xlating node_enum: Enum32 means [enum_v1] used.
*/
{
unsigned short MS, WS;
// note - this needs to check environment
WS = unsigned short( ( Enum32 ) ? 4 : 2 );
MS = 4;
GetMemSize() = MS;
GetMemAlign() = __max(MS, GetMemAlign());
GetWireSize() = WS;
GetWireAlign() = __max(WS, GetWireAlign());
};
//--------------------------------------------------------------------
//
// XLAT_SIZE_INFO::ContextHandleSizes
//
// Notes:
//
//
//
//--------------------------------------------------------------------
void
XLAT_SIZE_INFO::ContextHandleSizes( node_skl * pNode )
{
FixMemSizes( pNode );
GetWireSize() = 20;
GetWireAlign() = 4;
};
//--------------------------------------------------------------------
//
// XLAT_SIZE_INFO::ArraySize
//
// Notes:
//
//
//
//--------------------------------------------------------------------
void
XLAT_SIZE_INFO::ArraySize( node_skl*, FIELD_ATTR_INFO * pFA )
{
// if conformant, set sizes to 0 and return
if ( pFA->Kind & FA_CONFORMANT )
{
MemSize =
WireSize = 0;
return;
}
// round up element size to alignment boundary
// Element is already rounded up.
// RoundToAlignment( MemSize, MemAlign );
// RoundToAlignment( WireSize, WireAlign );
// compute number of elements and multiply...
unsigned long ElementCount;
ElementCount = (ulong) pFA->pSizeIsExpr->GetValue();
MemSize *= ElementCount;
WireSize *= ElementCount;
}
//--------------------------------------------------------------------
//
// XLAT_SIZE_INFO::GetOffset
//
// Notes:
// For use only by field nodes !!
//
// Fetch the offsets from another size info block
//
//--------------------------------------------------------------------
void
XLAT_SIZE_INFO::GetOffset( XLAT_SIZE_INFO & pInfo )
{
MemOffset = pInfo.MemOffset;
WireOffset = pInfo.WireOffset;
}
//--------------------------------------------------------------------
//
// XLAT_SIZE_INFO::AlignOffset
//
// Notes:
// For use only by field and struct/union nodes!!
//
// Round the offsets up to the corresponding alignments.
//
//--------------------------------------------------------------------
void
XLAT_SIZE_INFO::AlignOffset()
{
RoundToAlignment( MemOffset, MemAlign );
RoundToAlignment( WireOffset, WireAlign );
}
//--------------------------------------------------------------------
//
// XLAT_SIZE_INFO::AlignEmbeddedUnion
//
// Notes:
// For use only by field and struct/union nodes!!
//
// Round the offsets up to the corresponding alignments.
// don't round up the wire offset
//
//--------------------------------------------------------------------
void
XLAT_SIZE_INFO::AlignEmbeddedUnion()
{
RoundToAlignment( MemOffset, MemAlign );
RoundToAlignment( MemSize, MemAlign );
// RoundToAlignment( WireOffset, WireAlign );
}
//--------------------------------------------------------------------
//
// XLAT_SIZE_INFO::AlignConfOffset
//
// Notes:
// For use only by field and struct/union nodes!!
//
// Round the offsets up to the corresponding alignments.
//
// the Mem offset passed down from the parent
// of the conformant field is aligned
// the Wire offset passed down from the parent is advanced by
// the wire size and then aligned
//
//--------------------------------------------------------------------
void
XLAT_SIZE_INFO::AlignConfOffset()
{
RoundToAlignment( MemOffset, MemAlign );
//WireSize += WireOffset;
WireOffset += WireSize;
RoundToAlignment( WireOffset, WireAlign );
}
//--------------------------------------------------------------------
//
// XLAT_SIZE_INFO::AdjustForZP
//
// Notes:
// For use only by field and struct/union nodes!!
//
// Round the offsets up to the corresponding alignments.
//
//--------------------------------------------------------------------
void
XLAT_SIZE_INFO::AdjustForZP()
{
if ( ( MemAlign > ZeePee ) && !MustAlign ) MemAlign = ZeePee;
}
//--------------------------------------------------------------------
//
// XLAT_SIZE_INFO::AdjustSize
//
// Notes:
// For use only by field and struct nodes!!
//
// Add current offsets to current sizes
// pad MemSize out to ZeePee
//
//--------------------------------------------------------------------
void
XLAT_SIZE_INFO::AdjustSize()
{
MemSize += MemOffset;
MemOffset = MemSize;
WireSize += WireOffset;
WireOffset = WireSize;
}
//--------------------------------------------------------------------
//
// XLAT_SIZE_INFO::AdjustConfSize
//
// Notes:
// For use only by field and struct nodes!!
//
// Add current offsets to current sizes
// pad MemSize out to ZeePee
//
//--------------------------------------------------------------------
void
XLAT_SIZE_INFO::AdjustConfSize()
{
MemSize += MemOffset;
MemOffset = MemSize;
// don't count padding before the conformance (in case it has size 0)
/*****
WireSize += WireOffset;
WireOffset = WireSize;
******/
}
//--------------------------------------------------------------------
//
// XLAT_SIZE_INFO::AdjustTotalSize
//
// Notes:
// For use only by field and struct/union nodes!!
//
// Add current offsets to current sizes
// pad MemSize out to ZeePee
//
//--------------------------------------------------------------------
void
XLAT_SIZE_INFO::AdjustTotalSize()
{
RoundToAlignment( MemSize, MemAlign );
}
//--------------------------------------------------------------------
//
// XLAT_SIZE_INFO::Ndr64AdjustTotalStructSize
//
// Notes:
// For use only by field and struct nodes!!
//
// Add current offsets to current sizes
// pad MemSize and BuffSize out to ZeePee
//
//--------------------------------------------------------------------
void
XLAT_SIZE_INFO::Ndr64AdjustTotalStructSize()
{
RoundToAlignment( WireSize, WireAlign );
RoundToAlignment( MemSize, MemAlign );
}
//--------------------------------------------------------------------
//
// XLAT_SIZE_INFO::FixMemSizes
//
// Notes:
//
// This routine fixes up mem sizes when they are different from what
// the IL translate of children generated
//
//--------------------------------------------------------------------
void
XLAT_SIZE_INFO::FixMemSizes( node_skl * pNode )
{
FRONT_MEMORY_INFO MemInfo = pNode->GetMemoryInfo();
MemSize = MemInfo.Size;
MemAlign = MemInfo.Align;
MustAlign = MemInfo.IsMustAlign;
}
//--------------------------------------------------------------------
//
// XLAT_SIZE_INFO::IgnoredPointerSizes
//
// Notes:
//
// This routine fixes up sizes for an ignored pointer
//
//--------------------------------------------------------------------
void
XLAT_SIZE_INFO::IgnoredPtrSizes()
{
MemSize = SIZEOF_MEM_PTR();
MemAlign = (unsigned short) SIZEOF_MEM_PTR();
}
//--------------------------------------------------------------------
//
// XLAT_SIZE_INFO::ReturnSize
//
// Notes:
//
// Copy the size information up into the parent.
//
//--------------------------------------------------------------------
void
XLAT_SIZE_INFO::ReturnSize( XLAT_SIZE_INFO & pCtxt )
{
if ( pCtxt.MemAlign > MemAlign )
MemAlign = pCtxt.MemAlign;
MemSize = pCtxt.MemSize;
if ( pCtxt.WireAlign > WireAlign )
WireAlign = pCtxt.WireAlign;
WireSize = pCtxt.WireSize;
MustAlign = MustAlign || pCtxt.MustAlign;
// note: ZeePee is NOT propogated up, only down
// note: offsets are propogated up specially
}
//--------------------------------------------------------------------
//
// XLAT_SIZE_INFO::ReturnConfSize
//
// Notes:
//
// Copy the size information up into the parent.
// Don't overwrite the wire size the parent already has
//
//--------------------------------------------------------------------
void
XLAT_SIZE_INFO::ReturnConfSize( XLAT_SIZE_INFO & pCtxt )
{
if ( pCtxt.MemAlign > MemAlign )
MemAlign = pCtxt.MemAlign;
MemSize = pCtxt.MemSize;
if ( pCtxt.WireAlign > WireAlign )
WireAlign = pCtxt.WireAlign;
// WireSize = pCtxt.WireSize;
MustAlign = MustAlign || pCtxt.MustAlign;
// note: ZeePee is NOT propogated up, only down
// note: offsets are propogated up specially
}
//--------------------------------------------------------------------
//
// XLAT_SIZE_INFO::ReturnUnionSize
//
// Notes:
//
// Copy the size information up into the parent.
//
//--------------------------------------------------------------------
void
XLAT_SIZE_INFO::ReturnUnionSize( XLAT_SIZE_INFO & pCtxt )
{
if ( pCtxt.MemAlign > MemAlign ) MemAlign = pCtxt.MemAlign;
if ( pCtxt.MemSize > MemSize ) MemSize = pCtxt.MemSize;
if ( pCtxt.WireAlign > WireAlign ) WireAlign = pCtxt.WireAlign;
if ( pCtxt.WireSize > WireSize ) WireSize = pCtxt.WireSize;
MustAlign = MustAlign || pCtxt.MustAlign;
// note: ZeePee is NOT propogated up, only down
// note: offsets are propogated up specially
}