911 lines
24 KiB
C++
911 lines
24 KiB
C++
/*****************************************************************************/
|
|
/** Microsoft LAN Manager **/
|
|
/** Copyright(c) Microsoft Corp., 1987-1999 **/
|
|
/*****************************************************************************/
|
|
/*****************************************************************************
|
|
File : nodeskl.cxx
|
|
Title : skeletal node build routines
|
|
History :
|
|
04-Aug-1991 VibhasC Created
|
|
|
|
*****************************************************************************/
|
|
|
|
#pragma warning ( disable : 4514 )
|
|
|
|
/****************************************************************************
|
|
local defines and includes
|
|
****************************************************************************/
|
|
|
|
#include "nulldefs.h"
|
|
extern "C"
|
|
{
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
}
|
|
|
|
#include "allnodes.hxx"
|
|
#include "gramutil.hxx"
|
|
#include "cmdana.hxx"
|
|
#include "attrnode.hxx"
|
|
#include "ndrtypes.h"
|
|
#include "lextable.hxx"
|
|
#include "control.hxx"
|
|
|
|
inline
|
|
unsigned short ComputeAlignmentForZP( unsigned short Align, unsigned short ZeePee, BOOL IsMustAlign)
|
|
{
|
|
return ((Align > ZeePee) && !IsMustAlign) ? ZeePee : Align;
|
|
}
|
|
|
|
inline
|
|
unsigned long RoundToAlignment( unsigned long Size, unsigned short Align)
|
|
{
|
|
Align--;
|
|
return (Size + Align) & ~Align;
|
|
}
|
|
|
|
/****************************************************************************
|
|
external data
|
|
****************************************************************************/
|
|
|
|
extern CMD_ARG * pCommand;
|
|
extern node_e_attr * pErrorAttrNode;
|
|
extern node_error * pErrorTypeNode;
|
|
extern SymTable * pBaseSymTbl;
|
|
extern IDICT * pInterfaceDict;
|
|
extern ISTACK * pZpStack;
|
|
extern LexTable * pMidlLexTable;
|
|
extern CCONTROL * pCompiler;
|
|
|
|
/****************************************************************************
|
|
external procs
|
|
****************************************************************************/
|
|
|
|
extern BOOL IsTempName( char * );
|
|
extern void ParseError( STATUS_T, char * );
|
|
/****************************************************************************/
|
|
|
|
|
|
void
|
|
MEMLIST::SetMembers( class SIBLING_LIST & MEMLIST )
|
|
{
|
|
pMembers = MEMLIST.Linearize();
|
|
}
|
|
|
|
void
|
|
MEMLIST::MergeMembersToTail( class SIBLING_LIST & MEMLIST )
|
|
{
|
|
AddLastMember( MEMLIST.Linearize() );
|
|
}
|
|
|
|
STATUS_T
|
|
MEMLIST::GetMembers( class type_node_list * MEMLIST )
|
|
{
|
|
named_node * pCur = pMembers;
|
|
|
|
while ( pCur )
|
|
{
|
|
MEMLIST->SetPeer( pCur );
|
|
pCur = pCur->GetSibling();
|
|
}
|
|
|
|
return (pMembers)? STATUS_OK: I_ERR_NO_MEMBER;
|
|
};
|
|
|
|
short
|
|
MEMLIST::GetNumberOfArguments()
|
|
{
|
|
short count = 0;
|
|
named_node * pNext = pMembers;
|
|
|
|
while ( pNext )
|
|
{
|
|
count++;
|
|
pNext = pNext->GetSibling();
|
|
};
|
|
|
|
return count;
|
|
};
|
|
|
|
// add a new member onto the very tail
|
|
void
|
|
MEMLIST::AddLastMember( named_node * pNode )
|
|
{
|
|
named_node * pPrev = NULL;
|
|
named_node * pCur = pMembers;
|
|
|
|
while ( pCur )
|
|
{
|
|
pPrev = pCur;
|
|
pCur = pCur->GetSibling();
|
|
}
|
|
|
|
// pPrev is now null (empty list) or points to last element of list
|
|
if ( pPrev )
|
|
{
|
|
pPrev->SetSibling( pNode );
|
|
}
|
|
else
|
|
{
|
|
pMembers = pNode;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// Remove the last member from the tail
|
|
void
|
|
MEMLIST::RemoveLastMember()
|
|
{
|
|
named_node * pPrev = NULL;
|
|
named_node * pCur = pMembers;
|
|
|
|
while ( pCur && pCur->GetSibling() )
|
|
{
|
|
pPrev = pCur;
|
|
pCur = pCur->GetSibling();
|
|
}
|
|
|
|
// pPrev is now null (empty list) or points to next to last element of list
|
|
if ( pPrev )
|
|
{
|
|
pPrev->SetSibling( NULL);
|
|
}
|
|
|
|
}
|
|
|
|
void
|
|
MEMLIST::AddSecondMember( named_node * pNode )
|
|
{
|
|
named_node* pFirst = (named_node*)GetFirstMember();
|
|
|
|
if ( pFirst )
|
|
{
|
|
named_node* pSecond = pFirst->GetSibling();
|
|
pFirst->SetSibling( pNode );
|
|
pNode->SetSibling( pSecond );
|
|
}
|
|
else
|
|
{
|
|
pMembers = pNode;
|
|
}
|
|
|
|
}
|
|
|
|
/****************************************************************************
|
|
node_id:
|
|
the private memory allocator
|
|
****************************************************************************/
|
|
|
|
// initialize the memory allocators for node_id and node_id_fe
|
|
|
|
FreeListMgr
|
|
node_id::MyFreeList( sizeof (node_id ) );
|
|
|
|
FreeListMgr
|
|
node_id_fe::MyFreeList( sizeof (node_id_fe ) );
|
|
|
|
FRONT_MEMORY_INFO
|
|
node_skl::AdjustMemoryInfoForModifiers(FRONT_MEMORY_INFO OrigInfo)
|
|
{
|
|
if (!GetModifiers().IsModifierSet(ATTR_DECLSPEC_ALIGN))
|
|
return OrigInfo;
|
|
|
|
OrigInfo.IsMustAlign = TRUE;
|
|
OrigInfo.Align = __max(OrigInfo.Align, GetModifiers().GetDeclspecAlign());
|
|
|
|
return OrigInfo;
|
|
}
|
|
|
|
FRONT_MEMORY_INFO
|
|
node_skl::GetModifiedMemoryInfoFromChild()
|
|
{
|
|
node_skl *pChild = GetChild();
|
|
MIDL_ASSERT( pChild );
|
|
return AdjustMemoryInfoForModifiers( pChild->GetMemoryInfo() );
|
|
}
|
|
|
|
FRONT_MEMORY_INFO
|
|
node_skl::GetInvalidMemoryInfo()
|
|
{
|
|
return FRONT_MEMORY_INFO(0, 1, 0);
|
|
}
|
|
|
|
FRONT_MEMORY_INFO
|
|
node_enum::GetMemoryInfo()
|
|
{
|
|
unsigned long EnumSize = pCommand->GetEnumSize();
|
|
return AdjustMemoryInfoForModifiers( FRONT_MEMORY_INFO( EnumSize, (short)EnumSize, 0 ) );
|
|
}
|
|
|
|
FRONT_MEMORY_INFO
|
|
node_pointer::GetMemoryInfo()
|
|
{
|
|
unsigned long PointerSize = SIZEOF_MEM_PTR();
|
|
return AdjustMemoryInfoForModifiers( FRONT_MEMORY_INFO( PointerSize, (short)PointerSize, 0 ) );
|
|
}
|
|
|
|
FRONT_MEMORY_INFO
|
|
node_safearray::GetMemoryInfo()
|
|
{
|
|
unsigned long PointerSize = SIZEOF_MEM_PTR();
|
|
return AdjustMemoryInfoForModifiers( FRONT_MEMORY_INFO( PointerSize, (short)PointerSize, 0 ) );
|
|
}
|
|
|
|
FRONT_MEMORY_INFO
|
|
node_union::GetMemoryInfo()
|
|
{
|
|
|
|
// The size of a union is the size of the largest element rounded
|
|
// to the largest alignment.
|
|
|
|
FRONT_MEMORY_INFO UnionSize(0, 1, 0);
|
|
unsigned short ZeePee = GetZeePee();
|
|
MEM_ITER MemIter( this );
|
|
node_skl * pNode;
|
|
|
|
while ( ( pNode = MemIter.GetNext() ) != NULL )
|
|
{
|
|
FRONT_MEMORY_INFO TempSize = pNode->GetMemoryInfo();
|
|
|
|
// Merge in the size of the new union arm.
|
|
UnionSize.Size = __max(UnionSize.Size, TempSize.Size);
|
|
UnionSize.Align = __max(UnionSize.Align, TempSize.Align);
|
|
UnionSize.IsMustAlign = (UnionSize.IsMustAlign || TempSize.IsMustAlign);
|
|
}
|
|
|
|
// Add padding to end of union.
|
|
UnionSize = AdjustMemoryInfoForModifiers(UnionSize);
|
|
|
|
UnionSize.Align = ComputeAlignmentForZP( UnionSize.Align, ZeePee, UnionSize.IsMustAlign );
|
|
UnionSize.Size = RoundToAlignment( UnionSize.Size, UnionSize.Align );
|
|
|
|
return UnionSize;
|
|
}
|
|
|
|
FRONT_MEMORY_INFO
|
|
node_array::GetMemoryInfo()
|
|
{
|
|
// The size of an array is the size of the array element times the element count.
|
|
|
|
FRONT_MEMORY_INFO ArraySize = GetChild()->GetMemoryInfo();
|
|
|
|
unsigned long ArrayElements;
|
|
if ( pUpperBound && ( pUpperBound != (expr_node *) -1) )
|
|
{
|
|
|
|
ArrayElements = (ulong)pUpperBound->Evaluate();
|
|
}
|
|
else
|
|
{
|
|
// A conformant array is not sized.
|
|
ArrayElements = 0;
|
|
}
|
|
|
|
ArraySize.Size *= ArrayElements;
|
|
|
|
return AdjustMemoryInfoForModifiers(ArraySize);
|
|
}
|
|
|
|
|
|
FRONT_MEMORY_INFO
|
|
node_struct::GetMemoryInfo()
|
|
{
|
|
|
|
// The alignment of a structure is the largest alignment of all the members.
|
|
// Each structure is aligned according to the following rules.
|
|
// 1. If the field is a must align, the field is aligned to the Alignment.
|
|
// 2. If the field is not a must align, the field is aligned to min(Zp, Alignment).
|
|
|
|
|
|
MEM_ITER MemIter( this );
|
|
unsigned short ZeePee = GetZeePee();
|
|
FRONT_MEMORY_INFO StructSize(0,1,0);
|
|
node_skl * pNode;
|
|
|
|
while ( ( pNode = MemIter.GetNext() ) != 0 )
|
|
{
|
|
|
|
FRONT_MEMORY_INFO FieldSize = pNode->GetMemoryInfo();
|
|
FieldSize.Align = ComputeAlignmentForZP( FieldSize.Align, ZeePee, FieldSize.IsMustAlign );
|
|
|
|
StructSize.Size = RoundToAlignment( StructSize.Size, FieldSize.Align );
|
|
|
|
// StructSize.Size now contains the offset of the field.
|
|
|
|
// Merge in the attributes from the member
|
|
StructSize.Size += FieldSize.Size;
|
|
StructSize.Align = __max( FieldSize.Align, StructSize.Align );
|
|
StructSize.IsMustAlign = ( StructSize.IsMustAlign || FieldSize.IsMustAlign );
|
|
|
|
}
|
|
|
|
// Add padding to end of structure.
|
|
StructSize = AdjustMemoryInfoForModifiers( StructSize );
|
|
|
|
StructSize.Align = ComputeAlignmentForZP( StructSize.Align, ZeePee, StructSize.IsMustAlign );
|
|
StructSize.Size = RoundToAlignment( StructSize.Size, StructSize.Align );
|
|
|
|
return StructSize;
|
|
|
|
}
|
|
|
|
FRONT_MEMORY_INFO
|
|
node_def::GetMemoryInfo()
|
|
{
|
|
FRONT_MEMORY_INFO TypedefSize;
|
|
node_represent_as *pRep = (node_represent_as *)GetAttribute(ATTR_REPRESENT_AS);
|
|
node_user_marshal *pUserMarshall = (node_user_marshal *)GetAttribute(ATTR_USER_MARSHAL);
|
|
node_cs_char *pCSChar = (node_cs_char *) GetAttribute(ATTR_CSCHAR);
|
|
|
|
if (!pUserMarshall && !pRep && !pCSChar)
|
|
{
|
|
// Just use the modified child sizes.
|
|
return GetModifiedMemoryInfoFromChild();
|
|
}
|
|
|
|
if (pCSChar)
|
|
{
|
|
MIDL_ASSERT( NULL != pCSChar->GetUserType() );
|
|
return AdjustMemoryInfoForModifiers(
|
|
pCSChar->GetUserType()->GetMemoryInfo() );
|
|
}
|
|
|
|
// If both user_marshal and represent_as are specified, use represent_as and let semantic
|
|
// analysis flag the error.
|
|
|
|
if (pUserMarshall)
|
|
pRep = pUserMarshall;
|
|
|
|
node_skl *pNode = pRep->GetRepresentationType();
|
|
|
|
if (!pNode)
|
|
{
|
|
// unknown type. Use 0 as the size.
|
|
TypedefSize.Init(0, 1, 0);
|
|
}
|
|
else
|
|
{
|
|
TypedefSize = pNode->GetMemoryInfo();
|
|
}
|
|
|
|
return AdjustMemoryInfoForModifiers(TypedefSize);
|
|
}
|
|
|
|
FRONT_MEMORY_INFO
|
|
node_label::GetMemoryInfo()
|
|
{
|
|
return AdjustMemoryInfoForModifiers( FRONT_MEMORY_INFO(sizeof(short), (short)sizeof(short), 0) );
|
|
}
|
|
|
|
FRONT_MEMORY_INFO
|
|
node_base_type::GetMemoryInfo()
|
|
{
|
|
unsigned long size;
|
|
|
|
switch( NodeKind() )
|
|
{
|
|
case NODE_FLOAT: size = sizeof(float); break;
|
|
case NODE_DOUBLE: size = sizeof(double); break;
|
|
case NODE_FLOAT80: size = 16; break; //BUG, BUG double check once
|
|
//VC supports this
|
|
case NODE_FLOAT128: size = 16; break;
|
|
case NODE_HYPER: size = sizeof(__int64); break;
|
|
case NODE_INT64: size = sizeof(__int64); break;
|
|
case NODE_INT128: size = 16; break;
|
|
case NODE_INT3264: size = SIZEOF_MEM_INT3264(); break;
|
|
case NODE_INT32: size = sizeof(long); break;
|
|
case NODE_LONG: size = sizeof(long); break;
|
|
case NODE_LONGLONG: size = sizeof(LONGLONG); break;
|
|
case NODE_SHORT: size = sizeof(short); break;
|
|
case NODE_INT: size = sizeof(int); break;
|
|
case NODE_SMALL: size = sizeof(char); break;
|
|
case NODE_CHAR: size = sizeof(char); break;
|
|
case NODE_BOOLEAN: size = sizeof(char); break;
|
|
case NODE_BYTE: size = sizeof(char); break;
|
|
case NODE_HANDLE_T: size = SIZEOF_MEM_PTR(); break;
|
|
case NODE_VOID:
|
|
return AdjustMemoryInfoForModifiers(FRONT_MEMORY_INFO(0, 1, 0));
|
|
default:
|
|
size = 0;
|
|
MIDL_ASSERT(0);
|
|
}
|
|
|
|
return AdjustMemoryInfoForModifiers(FRONT_MEMORY_INFO(size, (short)size, 0));
|
|
}
|
|
|
|
FRONT_MEMORY_INFO
|
|
node_href::GetMemoryInfo()
|
|
{
|
|
node_skl *pChild = Resolve();
|
|
MIDL_ASSERT(pChild);
|
|
return AdjustMemoryInfoForModifiers(pChild->GetMemoryInfo());
|
|
}
|
|
|
|
/***************************************************************************
|
|
GetBasicType:
|
|
Get the basic type of the typenode
|
|
***************************************************************************/
|
|
node_skl *
|
|
node_skl::GetBasicType()
|
|
{
|
|
node_skl * pChildPtr;
|
|
|
|
switch( NodeKind() )
|
|
{
|
|
case NODE_STRUCT:
|
|
case NODE_ENUM:
|
|
case NODE_UNION:
|
|
|
|
return this;
|
|
|
|
case NODE_ID:
|
|
|
|
return GetChild();
|
|
|
|
default:
|
|
if ( ( pChildPtr = GetChild() ) != 0 )
|
|
{
|
|
if ( pChildPtr->NodeKind() == NODE_DEF ||
|
|
pChildPtr->NodeKind() == NODE_FORWARD ||
|
|
pChildPtr->NodeKind() == NODE_HREF )
|
|
return pChildPtr->GetBasicType();
|
|
|
|
return pChildPtr;
|
|
}
|
|
return this;
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
GetMyInterfaceNode:
|
|
Get the interface node for the typenode
|
|
***************************************************************************/
|
|
node_interface *
|
|
node_skl::GetMyInterfaceNode()
|
|
{
|
|
return (node_interface *) pInterfaceDict->GetElement( IntfKey );
|
|
}
|
|
|
|
|
|
void
|
|
node_interface::ResetCGIfNecessary()
|
|
{
|
|
if ( !fIs2ndCodegen &&
|
|
pCompiler->GetPassNumber() == NDR64_ILXLAT_PASS )
|
|
{
|
|
fIs2ndCodegen = TRUE;
|
|
SetCG(TRUE,NULL);
|
|
SetCG(FALSE,NULL);
|
|
}
|
|
}
|
|
|
|
|
|
node_file *
|
|
node_skl::GetDefiningFile()
|
|
{
|
|
if (GetMyInterfaceNode())
|
|
return GetMyInterfaceNode()->GetFileNode();
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
node_skl*
|
|
node_skl::GetDuplicateGuid (
|
|
node_guid* pGuid,
|
|
SymTable* pUUIDTable
|
|
)
|
|
{
|
|
node_skl* pDuplicate = 0;
|
|
|
|
if ( pGuid )
|
|
{
|
|
char * GuidStr = pGuid->GetGuidString();
|
|
SymKey SKey(GuidStr, NAME_DEF);
|
|
if ( !pUUIDTable->SymInsert( SKey, 0, (named_node*) this) )
|
|
{
|
|
pDuplicate = pUUIDTable->SymSearch( SKey );
|
|
}
|
|
}
|
|
return ( pDuplicate == this ) ? 0 : pDuplicate;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
utility functions
|
|
*****************************************************************************/
|
|
|
|
BOOL
|
|
COMPARE_ATTR(
|
|
ATTR_VECTOR & A1,
|
|
ATTR_VECTOR & A2 )
|
|
{
|
|
int i;
|
|
for( i = 0; i < MAX_ATTR_SUMMARY_ELEMENTS; ++i )
|
|
{
|
|
if( (A1[ i ] & A2[ i ] ) != A2[i] )
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
OR_ATTR(
|
|
ATTR_VECTOR & A1,
|
|
ATTR_VECTOR & A2 )
|
|
{
|
|
int i;
|
|
for( i= 0; i < MAX_ATTR_SUMMARY_ELEMENTS; ++i )
|
|
{
|
|
A1[ i ] |= A2[ i ];
|
|
}
|
|
}
|
|
void
|
|
XOR_ATTR(
|
|
ATTR_VECTOR & A1,
|
|
ATTR_VECTOR & A2 )
|
|
{
|
|
int i;
|
|
for( i= 0; i < MAX_ATTR_SUMMARY_ELEMENTS; ++i )
|
|
{
|
|
A1[ i ] ^= A2[ i ];
|
|
}
|
|
}
|
|
void
|
|
CLEAR_ATTR(
|
|
ATTR_VECTOR & A1 )
|
|
{
|
|
int i;
|
|
for( i= 0; i < MAX_ATTR_SUMMARY_ELEMENTS; ++i )
|
|
{
|
|
A1[ i ] = 0;
|
|
}
|
|
}
|
|
void
|
|
SET_ALL_ATTR(
|
|
ATTR_VECTOR & A1 )
|
|
{
|
|
int i;
|
|
for( i= 0; i < MAX_ATTR_SUMMARY_ELEMENTS; ++i )
|
|
{
|
|
A1[ i ] = 0xffffffff;
|
|
}
|
|
}
|
|
|
|
|
|
ATTR_T
|
|
CLEAR_FIRST_SET_ATTR ( ATTR_VECTOR & A)
|
|
{
|
|
int i;
|
|
unsigned long mask;
|
|
short at;
|
|
|
|
for ( i = 0; i < MAX_ATTR_SUMMARY_ELEMENTS; ++i )
|
|
{
|
|
for ( at = 0, mask = 1;
|
|
mask != 0;
|
|
++at, mask = mask<<1 )
|
|
{
|
|
if ( mask & A[i] )
|
|
{
|
|
A[i] &= ~mask;
|
|
return (ATTR_T) (at + ( i * 32 ));
|
|
}
|
|
}
|
|
}
|
|
return ATTR_NONE;
|
|
|
|
}
|
|
|
|
BOOL
|
|
node_base_type::IsUnsigned()
|
|
{
|
|
|
|
// make obvious choices
|
|
if ( FInSummary( ATTR_UNSIGNED ) )
|
|
return TRUE;
|
|
|
|
if ( FInSummary( ATTR_SIGNED ) )
|
|
return FALSE;
|
|
|
|
// unspec'd char is always unsigned
|
|
if ( NodeKind() == NODE_CHAR )
|
|
{
|
|
return TRUE;
|
|
}
|
|
// unspec'd small is always signed
|
|
else if ( NodeKind() == NODE_SMALL )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// the cracks...
|
|
return FALSE;
|
|
}
|
|
|
|
EXPR_VALUE
|
|
node_base_type::ConvertMyKindOfValueToEXPR_VALUE( EXPR_VALUE value )
|
|
{
|
|
|
|
// make obvious choice
|
|
if ( FInSummary( ATTR_UNSIGNED ) )
|
|
return value;
|
|
|
|
// small values are irrelevant
|
|
if ( (value & 0xffffff80) == 0 )
|
|
return value;
|
|
|
|
// handle default signedness
|
|
// simple type should be converted to int in expression evaluation.
|
|
switch ( NodeKind() )
|
|
{
|
|
case NODE_CHAR:
|
|
if ( !FInSummary( ATTR_SIGNED ) )
|
|
return value;
|
|
// fall through to sign extend
|
|
case NODE_SMALL:
|
|
{
|
|
signed int ch = (signed int) value;
|
|
return (EXPR_VALUE) ch;
|
|
}
|
|
case NODE_SHORT:
|
|
{
|
|
signed int sh = (signed int) value;
|
|
return (EXPR_VALUE) sh;
|
|
}
|
|
case NODE_LONG:
|
|
case NODE_INT32:
|
|
case NODE_INT:
|
|
{
|
|
signed long lng = (signed long) value;
|
|
return (EXPR_VALUE) lng;
|
|
}
|
|
case NODE_INT3264:
|
|
{
|
|
if ( ! pCommand->Is64BitEnv() )
|
|
{
|
|
signed long lng = (signed long) value;
|
|
return (EXPR_VALUE) lng;
|
|
}
|
|
}
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
BOOL
|
|
named_node::IsNamedNode()
|
|
{
|
|
return ( ( pName ) && !IsTempName( pName ) );
|
|
};
|
|
|
|
// return the transmit_as type (or NULL)
|
|
node_skl *
|
|
node_def::GetTransmittedType()
|
|
{
|
|
ta * pXmit = (ta *) GetAttribute( ATTR_TRANSMIT );
|
|
|
|
/*
|
|
Rkk just in case
|
|
*/
|
|
if ( !pXmit )
|
|
pXmit = (ta *) GetAttribute( ATTR_WIRE_MARSHAL );
|
|
|
|
// allow for transitive xmit_as
|
|
if ( !pXmit && ( GetChild()->NodeKind() == NODE_DEF ) )
|
|
return ((node_def*)GetChild())->GetTransmittedType();
|
|
|
|
return (pXmit) ? pXmit->GetType() : NULL;
|
|
}
|
|
|
|
// return the represent_as type (or NULL)
|
|
char *
|
|
node_def::GetRepresentationName()
|
|
{
|
|
node_represent_as * pRep =
|
|
(node_represent_as *) GetAttribute( ATTR_REPRESENT_AS );
|
|
|
|
if ( !pRep )
|
|
pRep = (node_represent_as *) GetAttribute( ATTR_USER_MARSHAL );
|
|
|
|
return (pRep) ? pRep->GetRepresentationName() : NULL;
|
|
}
|
|
|
|
|
|
// link self on as new top node
|
|
void
|
|
node_pragma_pack::Push( node_pragma_pack *& pTop )
|
|
{
|
|
pStackLink = pTop;
|
|
pTop = this;
|
|
}
|
|
|
|
// search for matching push and pop it off, returning new ZP
|
|
unsigned short
|
|
node_pragma_pack::Pop( node_pragma_pack *& pTop )
|
|
{
|
|
unsigned short result = 0;
|
|
|
|
if ( pString )
|
|
{
|
|
while ( pTop->PackType != PRAGMA_PACK_GARBAGE )
|
|
{
|
|
if ( pTop->pString &&
|
|
!strcmp( pTop->pString, pString ) )
|
|
{
|
|
result = pTop->usPackingLevel;
|
|
pTop = pTop->pStackLink;
|
|
return result;
|
|
}
|
|
|
|
pTop = pTop->pStackLink;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
if ( pTop->PackType != PRAGMA_PACK_GARBAGE )
|
|
{
|
|
result = pTop->usPackingLevel;
|
|
pTop = pTop->pStackLink;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// routines to save the pragma stack across files
|
|
|
|
class PRAGMA_FILE_STACK_ELEMENT
|
|
{
|
|
public:
|
|
node_pragma_pack * pPackStack;
|
|
unsigned short SavedZp;
|
|
|
|
PRAGMA_FILE_STACK_ELEMENT( node_pragma_pack * pSt,
|
|
unsigned short usZp )
|
|
{
|
|
pPackStack = pSt;
|
|
SavedZp = usZp;
|
|
}
|
|
};
|
|
|
|
|
|
void
|
|
PushZpStack( node_pragma_pack * & PackStack,
|
|
unsigned short & CurrentZp )
|
|
{
|
|
PRAGMA_FILE_STACK_ELEMENT * pSave = new PRAGMA_FILE_STACK_ELEMENT (
|
|
PackStack, CurrentZp );
|
|
|
|
pZpStack->Push( (IDICTELEMENT) pSave );
|
|
|
|
// make new zp stack and start new file with command line Zp
|
|
PackStack = new node_pragma_pack( NULL,
|
|
pCommand->GetZeePee(),
|
|
PRAGMA_PACK_GARBAGE );
|
|
CurrentZp = pCommand->GetZeePee();
|
|
}
|
|
|
|
// restore the Zp stack and current Zp on returning from imported file
|
|
void
|
|
PopZpStack( node_pragma_pack * & PackStack,
|
|
unsigned short & CurrentZp )
|
|
{
|
|
|
|
PRAGMA_FILE_STACK_ELEMENT * pSaved = (PRAGMA_FILE_STACK_ELEMENT *)
|
|
pZpStack->Pop();
|
|
|
|
PackStack = pSaved->pPackStack;
|
|
CurrentZp = pSaved->SavedZp;
|
|
|
|
}
|
|
|
|
BOOL MODIFIER_SET::IsFlagAModifier(ATTR_T flag) const
|
|
{
|
|
return (flag >= ATTR_CPORT_ATTRIBUTES_START && flag <= ATTR_CPORT_ATTRIBUTES_END);
|
|
}
|
|
|
|
BOOL MODIFIER_SET::IsModifierSet(ATTR_T flag) const
|
|
{
|
|
return (BOOL)( ModifierBits & SetModifierBit( flag ) );
|
|
}
|
|
|
|
BOOL MODIFIER_SET::AnyModifiersSet() const
|
|
{
|
|
return ModifierBits != 0;
|
|
}
|
|
|
|
void MODIFIER_SET::SetModifier(ATTR_T flag)
|
|
{
|
|
ModifierBits |= SetModifierBit( flag );
|
|
}
|
|
|
|
void MODIFIER_SET::ClearModifier(ATTR_T flag)
|
|
{
|
|
unsigned _int64 ModifierMask = SetModifierBit( flag );
|
|
ModifierBits &= ~ModifierMask;
|
|
if (ATTR_DECLSPEC_ALIGN == flag)
|
|
Align = 0;
|
|
}
|
|
|
|
void MODIFIER_SET::SetDeclspecAlign( unsigned short NewAlign)
|
|
{
|
|
SetModifier( ATTR_DECLSPEC_ALIGN);
|
|
Align = NewAlign;
|
|
}
|
|
|
|
unsigned short MODIFIER_SET::GetDeclspecAlign() const
|
|
{
|
|
if ( !IsModifierSet( ATTR_DECLSPEC_ALIGN ) )
|
|
return 1;
|
|
return Align;
|
|
}
|
|
|
|
void MODIFIER_SET::SetDeclspecUnknown(char *pNewUnknownTxt)
|
|
{
|
|
pUnknownTxt = pMidlLexTable->LexInsert(pNewUnknownTxt);
|
|
SetModifier( ATTR_DECLSPEC_UNKNOWN );
|
|
return;
|
|
}
|
|
|
|
char *MODIFIER_SET::GetDeclspecUnknown() const
|
|
{
|
|
if ( !IsModifierSet( ATTR_DECLSPEC_UNKNOWN ) )
|
|
return " ";
|
|
return pUnknownTxt;
|
|
}
|
|
|
|
void MODIFIER_SET::Clear()
|
|
{
|
|
ModifierBits = 0; Align = 0; pUnknownTxt = 0;
|
|
}
|
|
|
|
void MODIFIER_SET::Merge(const MODIFIER_SET & MergeModifierSet)
|
|
{
|
|
if ( MergeModifierSet.IsModifierSet( ATTR_DECLSPEC_ALIGN ) )
|
|
{
|
|
if (! IsModifierSet( ATTR_DECLSPEC_ALIGN ) )
|
|
{
|
|
Align = MergeModifierSet.Align;
|
|
}
|
|
else
|
|
{
|
|
Align = __max(MergeModifierSet.Align, Align);
|
|
}
|
|
}
|
|
|
|
if (MergeModifierSet.pUnknownTxt)
|
|
{
|
|
if (!pUnknownTxt)
|
|
{
|
|
pUnknownTxt = MergeModifierSet.pUnknownTxt;
|
|
}
|
|
else
|
|
{
|
|
size_t StrSize = strlen(MergeModifierSet.pUnknownTxt);
|
|
StrSize += strlen(pUnknownTxt) + 1;
|
|
char *pNewText = new char[StrSize];
|
|
strcpy(pNewText, pUnknownTxt);
|
|
strcat(pNewText, MergeModifierSet.pUnknownTxt);
|
|
pUnknownTxt = pMidlLexTable->LexInsert(pNewText);
|
|
delete[] pNewText;
|
|
}
|
|
|
|
}
|
|
|
|
ModifierBits |= MergeModifierSet.ModifierBits;
|
|
|
|
}
|
|
|
|
void MODIFIER_SET::PrintDebugInfo() const
|
|
{
|
|
printf("Modifiers: 0x%I64X\n", ModifierBits);
|
|
printf("Align: %u\n", Align);
|
|
if (pUnknownTxt)
|
|
{
|
|
printf("UnknownTxt: %s\n", pUnknownTxt);
|
|
}
|
|
}
|