mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1454 lines
44 KiB
1454 lines
44 KiB
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
miscgen.cxx
|
|
|
|
Abstract:
|
|
|
|
This module contains miscellaneous routines needed for code
|
|
generation.
|
|
|
|
Author:
|
|
|
|
Donna Liu (donnali) 09-Nov-1990
|
|
|
|
Revision History:
|
|
|
|
26-Feb-1992 donnali
|
|
|
|
Moved toward NT coding style.
|
|
|
|
--*/
|
|
|
|
|
|
#include "nulldefs.h"
|
|
extern "C"
|
|
{
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
}
|
|
#include "nodeskl.hxx"
|
|
#include "buffer.hxx"
|
|
#include "output.hxx"
|
|
#include "listhndl.hxx"
|
|
#include "basetype.hxx"
|
|
#include "ptrarray.hxx"
|
|
#include "compnode.hxx"
|
|
#include "procnode.hxx"
|
|
#include "miscnode.hxx"
|
|
#include "typedef.hxx"
|
|
#include "attrnode.hxx"
|
|
#include "acfattr.hxx"
|
|
#include "stubgen.hxx"
|
|
|
|
#include "pickle.hxx"
|
|
|
|
#define MESSAGE "_message"
|
|
|
|
extern OutputManager * pOutput;
|
|
extern void midl_debug (char *);
|
|
|
|
extern node_skl * pImplicitHandleType;
|
|
extern char * pImplicitHandleName;
|
|
extern unsigned short HasAutoHandle;
|
|
|
|
extern PickleManager * pPicControlBlock;
|
|
|
|
BOOL fEmitConst = 0;
|
|
|
|
|
|
BOOL
|
|
node_skl::HasPointer(void)
|
|
{
|
|
type_node_list tnList;
|
|
node_skl * pNode;
|
|
|
|
midl_debug ("node_skl::HasPointer()\n");
|
|
|
|
switch (GetNodeType())
|
|
{
|
|
case NODE_FIELD:
|
|
if (((node_field *)this)->IsEmptyArm()) return FALSE;
|
|
// fall through
|
|
case NODE_PARAM:
|
|
case NODE_ARRAY:
|
|
pNode = GetMembers ();
|
|
return pNode->HasPointer ();
|
|
case NODE_POINTER:
|
|
return TRUE;
|
|
case NODE_PROC:
|
|
// return node can have type void
|
|
pNode = ((node_proc *)this)->GetReturnType ();
|
|
if (pNode->HasPointer()) return TRUE;
|
|
// fall through
|
|
case NODE_UNION:
|
|
case NODE_STRUCT:
|
|
if (GetMembers(&tnList) != STATUS_OK) return FALSE;
|
|
tnList.Init();
|
|
while (tnList.GetPeer(&pNode) == STATUS_OK)
|
|
{
|
|
if (pNode->HasPointer()) return TRUE;
|
|
}
|
|
return FALSE;
|
|
case NODE_DEF:
|
|
if( FInSummary( ATTR_TRANSMIT ) )
|
|
return FALSE;
|
|
else
|
|
return GetMembers()->HasPointer();
|
|
default:
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
node_skl::HasInterfacePointer(short cNestingLevel)
|
|
{
|
|
type_node_list tnList;
|
|
node_skl * pNode;
|
|
|
|
midl_debug ("node_skl::HasInterfacePointer()\n");
|
|
|
|
if(FInSummary(ATTR_IID))
|
|
return TRUE;
|
|
|
|
switch (GetNodeType())
|
|
{
|
|
case NODE_FIELD:
|
|
if (((node_field *)this)->IsEmptyArm()) return FALSE;
|
|
// fall through
|
|
case NODE_PARAM:
|
|
case NODE_ARRAY:
|
|
case NODE_POINTER:
|
|
pNode = GetMembers ();
|
|
return pNode->HasInterfacePointer (cNestingLevel);
|
|
case NODE_PROC:
|
|
// return node can have type void
|
|
pNode = ((node_proc *)this)->GetReturnType ();
|
|
if (pNode->HasInterfacePointer(cNestingLevel)) return TRUE;
|
|
// fall through
|
|
case NODE_UNION:
|
|
case NODE_STRUCT:
|
|
if(cNestingLevel > 0)
|
|
{
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
if (GetMembers(&tnList) == STATUS_OK)
|
|
{
|
|
tnList.Init();
|
|
while (tnList.GetPeer(&pNode) == STATUS_OK)
|
|
{
|
|
if (pNode->HasInterfacePointer(cNestingLevel + 1)) return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
break;
|
|
case NODE_DEF:
|
|
if( FInSummary( ATTR_TRANSMIT ) )
|
|
return FALSE;
|
|
else
|
|
return GetMembers()->HasInterfacePointer(cNestingLevel);
|
|
default:
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
node_skl::HasRef(void)
|
|
{
|
|
node_skl * pNode;
|
|
|
|
midl_debug ("node_skl::HasRef()\n");
|
|
|
|
switch (GetNodeType())
|
|
{
|
|
case NODE_DEF:
|
|
case NODE_ARRAY:
|
|
pNode = GetMembers ();
|
|
return pNode->HasRef ();
|
|
case NODE_POINTER:
|
|
if (FInSummary(ATTR_REF) ||
|
|
(!FInSummary(ATTR_UNIQUE) && !FInSummary(ATTR_PTR) &&
|
|
pOutput->PointerDefault() == POINTER_REF))
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
default:
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
node_skl::HasPtr(void)
|
|
{
|
|
type_node_list tnList;
|
|
node_skl * pNode;
|
|
|
|
midl_debug ("node_skl::HasRef()\n");
|
|
|
|
switch (GetNodeType())
|
|
{
|
|
case NODE_DEF:
|
|
case NODE_ARRAY:
|
|
pNode = GetMembers ();
|
|
return pNode->HasPtr ();
|
|
case NODE_POINTER:
|
|
if (FInSummary(ATTR_PTR) ||
|
|
(!FInSummary(ATTR_UNIQUE) && !FInSummary(ATTR_REF) &&
|
|
pOutput->PointerDefault() == POINTER_PTR))
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
case NODE_FIELD:
|
|
if (((node_field *)this)->IsEmptyArm()) return FALSE;
|
|
pNode = GetMembers ();
|
|
return pNode->HasPtr ();
|
|
case NODE_STRUCT:
|
|
case NODE_UNION:
|
|
if (GetMembers(&tnList) != STATUS_OK) return FALSE;
|
|
tnList.Init();
|
|
while (tnList.GetPeer(&pNode) == STATUS_OK)
|
|
{
|
|
if (pNode->HasPtr()) return TRUE;
|
|
}
|
|
return FALSE;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
node_skl::IsPersistent(void)
|
|
{
|
|
type_node_list tnList;
|
|
node_skl * pNode;
|
|
short fNode = 0;
|
|
|
|
midl_debug ("node_skl::IsPersistent()\n");
|
|
|
|
switch (GetNodeType())
|
|
{
|
|
case NODE_DEF:
|
|
case NODE_ARRAY:
|
|
pNode = GetMembers ();
|
|
return pNode->IsPersistent ();
|
|
case NODE_POINTER:
|
|
if (FInSummary(ATTR_ALLOCATE)) fNode = GetAllocateDetails ();
|
|
if (IS_ALLOCATE(fNode, ALLOCATE_DONT_FREE))
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
case NODE_FIELD:
|
|
if (((node_field *)this)->IsEmptyArm()) return FALSE;
|
|
pNode = GetMembers ();
|
|
return pNode->IsPersistent ();
|
|
case NODE_STRUCT:
|
|
case NODE_UNION:
|
|
if (GetMembers(&tnList) != STATUS_OK) return FALSE;
|
|
tnList.Init();
|
|
while (tnList.GetPeer(&pNode) == STATUS_OK)
|
|
{
|
|
if (!pNode->IsPersistent()) return FALSE;
|
|
}
|
|
return TRUE;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
unsigned short
|
|
node_skl::CheckAlign(unsigned long * pMscTotal, unsigned long * pNdrTotal)
|
|
{
|
|
type_node_list tnList;
|
|
node_skl * pNode;
|
|
NODE_T Type;
|
|
node_state State;
|
|
unsigned short AlnFlag = TRUE;
|
|
unsigned long MscTempTotal = 0;
|
|
unsigned long NdrTempTotal = 0;
|
|
unsigned long MscTempAlign = 0;
|
|
unsigned long NdrTempAlign = 0;
|
|
|
|
midl_debug ("node_skl::CheckAlign()\n");
|
|
|
|
Type = GetNodeType();
|
|
|
|
if (Type == NODE_DEF || Type == NODE_ERROR_STATUS_T || Type == NODE_WCHAR_T)
|
|
{
|
|
pNode = GetMembers ();
|
|
return pNode->CheckAlign (pMscTotal, pNdrTotal);
|
|
}
|
|
else if (Type == NODE_FIELD)
|
|
{
|
|
if (((node_field *)this)->IsEmptyArm()) return true;
|
|
pNode = GetMembers ();
|
|
return pNode->CheckAlign (pMscTotal, pNdrTotal);
|
|
}
|
|
else if (Type == NODE_ARRAY)
|
|
{
|
|
pNode = GetMembers ();
|
|
if (pNode->HasRef()) return FALSE;
|
|
}
|
|
|
|
if (*pMscTotal % GetMscAlign())
|
|
*pMscTotal += GetMscAlign() - (*pMscTotal % GetMscAlign());
|
|
if (*pNdrTotal % GetNdrAlign())
|
|
*pNdrTotal += GetNdrAlign() - (*pNdrTotal % GetNdrAlign());
|
|
if (*pMscTotal != *pNdrTotal) AlnFlag = false;
|
|
|
|
switch (Type)
|
|
{
|
|
case NODE_DOUBLE:
|
|
*pMscTotal += sizeof(double);
|
|
*pNdrTotal += 8;
|
|
break;
|
|
case NODE_FLOAT:
|
|
*pMscTotal += sizeof(float);
|
|
*pNdrTotal += 4;
|
|
break;
|
|
case NODE_HYPER:
|
|
case NODE_LONGLONG:
|
|
*pMscTotal += sizeof(double);
|
|
*pNdrTotal += 8;
|
|
break;
|
|
case NODE_LONG:
|
|
*pMscTotal += sizeof(long);
|
|
*pNdrTotal += 4;
|
|
break;
|
|
case NODE_SHORT:
|
|
*pMscTotal += sizeof(short);
|
|
*pNdrTotal += 2;
|
|
break;
|
|
case NODE_VOID:
|
|
case NODE_SMALL:
|
|
case NODE_CHAR:
|
|
case NODE_BYTE:
|
|
case NODE_BOOLEAN:
|
|
*pMscTotal += sizeof(char);
|
|
*pNdrTotal += 1;
|
|
break;
|
|
case NODE_POINTER:
|
|
*pMscTotal += sizeof(void *);
|
|
*pNdrTotal += 4;
|
|
break;
|
|
case NODE_ARRAY:
|
|
State = GetNodeState();
|
|
if (State & NODE_STATE_CONF_ARRAY) return FALSE;
|
|
if (State & NODE_STATE_VARYING_ARRAY) return FALSE;
|
|
if (FInSummary(ATTR_STRING)) return FALSE;
|
|
pNode = GetMembers ();
|
|
/// if (!pNode->CheckAlign(&MscTempTotal, &NdrTempTotal)) return FALSE;
|
|
if (!pNode->CheckAlign(&MscTempTotal, &NdrTempTotal))
|
|
AlnFlag = FALSE;
|
|
if (MscTempAlign = MscTempTotal % GetMscAlign())
|
|
MscTempTotal += GetMscAlign() - MscTempAlign;
|
|
if (NdrTempAlign = NdrTempTotal % GetNdrAlign())
|
|
NdrTempTotal += GetNdrAlign() - NdrTempAlign;
|
|
if (MscTempTotal != NdrTempTotal) AlnFlag = FALSE;
|
|
*pMscTotal += ((node_array *)this)->GetUpperBound() * MscTempTotal;
|
|
*pNdrTotal += ((node_array *)this)->GetUpperBound() * NdrTempTotal;
|
|
if (NdrTempAlign)
|
|
{
|
|
*pNdrTotal -= GetNdrAlign() - NdrTempAlign;
|
|
*pMscTotal = *pNdrTotal;
|
|
}
|
|
break;
|
|
case NODE_ENUM:
|
|
*pMscTotal += GetSize(0);
|
|
*pNdrTotal += 2;
|
|
AlnFlag = FALSE;
|
|
break;
|
|
case NODE_UNION:
|
|
*pMscTotal = 0;
|
|
*pNdrTotal = 0;
|
|
AlnFlag = FALSE;
|
|
break;
|
|
case NODE_STRUCT:
|
|
if (GetMembers(&tnList) != STATUS_OK) return FALSE;
|
|
tnList.Init();
|
|
while (tnList.GetPeer(&pNode) == STATUS_OK)
|
|
{
|
|
if (!pNode->CheckAlign(pMscTotal, pNdrTotal))
|
|
AlnFlag = FALSE;
|
|
}
|
|
if (*pMscTotal % GetMscAlign())
|
|
*pMscTotal += GetMscAlign() - (*pMscTotal % GetMscAlign());
|
|
break;
|
|
case NODE_PARAM:
|
|
if (!FInSummary(ATTR_IN)) break;
|
|
pNode = GetMembers ();
|
|
return pNode->CheckAlign (pMscTotal, pNdrTotal);
|
|
case NODE_PROC:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if( Type == NODE_DOUBLE ) return FALSE;
|
|
if (*pMscTotal != *pNdrTotal) return FALSE;
|
|
|
|
return AlnFlag;
|
|
}
|
|
|
|
|
|
void
|
|
node_skl::CountUsage (SIDE_T Side, BOOL fAllNodes)
|
|
{
|
|
type_node_list tnList;
|
|
node_skl * pNode;
|
|
node_skl * pXmit;
|
|
NODE_T Type;
|
|
|
|
Type = GetNodeType();
|
|
|
|
if (Type == NODE_DEF)
|
|
((node_def *)this)->PropogateAttributeToPointer (ATTR_ALLOCATE);
|
|
|
|
if (FInSummary(ATTR_ALLOCATE))
|
|
{
|
|
short fNode = 0;
|
|
|
|
fNode = GetAllocateDetails ();
|
|
if (IS_ALLOCATE(fNode, ALLOCATE_ALL_NODES))
|
|
fAllNodes = 1;
|
|
}
|
|
else if (FInSummary(ATTR_BYTE_COUNT))
|
|
{
|
|
fAllNodes = 1;
|
|
}
|
|
|
|
if (fAllNodes) fUseTreeBuffer = 1;
|
|
|
|
if (Side & CLIENT_SIDE)
|
|
{
|
|
if (ClientRefCount)
|
|
{
|
|
if (!(Side & SERVER_SIDE && !ServerRefCount))
|
|
return;
|
|
else
|
|
Side = SERVER_SIDE;
|
|
}
|
|
}
|
|
else if (!(Side & SERVER_SIDE && !ServerRefCount))
|
|
return;
|
|
|
|
BOOL fPicklingNeeded = FALSE;
|
|
|
|
switch (Type)
|
|
{
|
|
case NODE_UNION:
|
|
case NODE_STRUCT:
|
|
if (Side & CLIENT_SIDE) ClientRefCount = 0x1;
|
|
if (Side & SERVER_SIDE) ServerRefCount = 0x1;
|
|
// fall through
|
|
case NODE_SOURCE:
|
|
if (GetMembers(&tnList) != STATUS_OK)
|
|
return;
|
|
tnList.Init();
|
|
while (tnList.GetPeer(&pNode) == STATUS_OK)
|
|
pNode->CountUsage(Side, fAllNodes);
|
|
break;
|
|
|
|
case NODE_INTERFACE:
|
|
if ( FInSummary( ATTR_LOCAL ) )
|
|
return;
|
|
|
|
if (GetMembers(&tnList) != STATUS_OK)
|
|
return;
|
|
tnList.Init();
|
|
while (tnList.GetPeer(&pNode) == STATUS_OK)
|
|
{
|
|
fPicklingNeeded = FALSE;
|
|
if (pNode->GetNodeType() == NODE_PROC)
|
|
{
|
|
if ( !(pNode->FInSummary( ATTR_LOCAL )) &&
|
|
!(pNode->FInSummary( ATTR_INTERPRET )) &&
|
|
!( FInSummary( ATTR_INTERPRET ) &&
|
|
!pNode->FInSummary( ATTR_NOINTERPRET ) ) &&
|
|
!(pNode->GetNodeState() & NODE_STATE_IMPORT_OFF))
|
|
pNode->CountUsage(Side, fAllNodes);
|
|
}
|
|
else if ( pNode->GetNodeType() == NODE_DEF )
|
|
{
|
|
if ( pNode->FInSummary( ATTR_ENCODE ) ||
|
|
pNode->FInSummary( ATTR_DECODE ) ||
|
|
pPicControlBlock &&
|
|
( pPicControlBlock->GetEncodeAtIf() ||
|
|
pPicControlBlock->GetDecodeAtIf() )
|
|
)
|
|
{
|
|
fPicklingNeeded = TRUE;
|
|
pNode->CountUsage( Side, fAllNodes );
|
|
fPicklingNeeded = FALSE;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case NODE_FILE:
|
|
if (GetNodeState() & NODE_STATE_IMPORT) return;
|
|
pNode = GetMembers ();
|
|
pNode->CountUsage(Side, fAllNodes);
|
|
break;
|
|
|
|
case NODE_DEF:
|
|
if (FInSummary(ATTR_TRANSMIT))
|
|
{
|
|
pXmit = ((node_def *)this)->GetTransmitAsType ();
|
|
assert (pXmit != (node_skl *)0);
|
|
pXmit->CountUsage(Side, fAllNodes);
|
|
break;
|
|
}
|
|
pNode = GetMembers ();
|
|
pNode->CountUsage(Side, fAllNodes);
|
|
if (Side & CLIENT_SIDE) ClientRefCount = 0x1;
|
|
if (Side & SERVER_SIDE) ServerRefCount = 0x1;
|
|
|
|
// if (Side & SERVER_SIDE && fPicklingNeeded)
|
|
// ClientRefCount = 0x1;
|
|
break;
|
|
|
|
case NODE_PROC:
|
|
#if 1
|
|
((node_proc *)this)->GetReturnType()->CountUsage( Side, fAllNodes );
|
|
#endif // 1
|
|
if (FInSummary(ATTR_CALLBACK))
|
|
{
|
|
Side = SERVER_SIDE;
|
|
pOutput->SetCallBack ();
|
|
}
|
|
else
|
|
Side = CLIENT_SIDE;
|
|
|
|
if (GetMembers(&tnList) != STATUS_OK) return;
|
|
tnList.Init();
|
|
while (tnList.GetPeer(&pNode) == STATUS_OK)
|
|
pNode->CountUsage(Side, fAllNodes);
|
|
break;
|
|
|
|
case NODE_PARAM:
|
|
if (Side & CLIENT_SIDE)
|
|
{
|
|
Side = (SIDE_T)0;
|
|
if (FInSummary(ATTR_IN)) Side |= CLIENT_SIDE;
|
|
if (FInSummary(ATTR_OUT)) Side |= SERVER_SIDE;
|
|
}
|
|
else
|
|
{
|
|
Side = (SIDE_T)0;
|
|
if (FInSummary(ATTR_IN)) Side |= SERVER_SIDE;
|
|
if (FInSummary(ATTR_OUT)) Side |= CLIENT_SIDE;
|
|
}
|
|
// fall through
|
|
case NODE_FIELD:
|
|
if (((node_field *)this)->IsEmptyArm())
|
|
{
|
|
if (Side & CLIENT_SIDE) ClientRefCount = 0x1;
|
|
if (Side & SERVER_SIDE) ServerRefCount = 0x1;
|
|
break;
|
|
}
|
|
// fall through
|
|
default:
|
|
pNode = GetMembers ();
|
|
if (pNode == (node_skl *)0) break;
|
|
pNode->CountUsage(Side, fAllNodes);
|
|
if (Side & CLIENT_SIDE) ClientRefCount = 0x1;
|
|
if (Side & SERVER_SIDE) ServerRefCount = 0x1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
node_skl::CountAlloc (
|
|
BOOL MaxAlign
|
|
)
|
|
{
|
|
type_node_list tnList;
|
|
node_skl * pNode;
|
|
node_skl * pXmit;
|
|
|
|
switch (GetNodeType())
|
|
{
|
|
case NODE_UNION:
|
|
case NODE_STRUCT:
|
|
|
|
if (!fHasTreeBuffer)
|
|
{
|
|
BOOL fLinearBuffer = 1;
|
|
|
|
fHasTreeBuffer = 1;
|
|
if (GetMembers(&tnList) != STATUS_OK) return FALSE;
|
|
tnList.Init();
|
|
while (tnList.GetPeer(&pNode) == STATUS_OK)
|
|
{
|
|
if (pNode->CountAlloc(MaxAlign))
|
|
{
|
|
fLinearBuffer = 0;
|
|
}
|
|
}
|
|
fHasTreeBuffer = !fLinearBuffer;
|
|
}
|
|
if (fUseTreeBuffer) return TRUE;
|
|
break;
|
|
case NODE_INTERFACE:
|
|
if (FInSummary(ATTR_LOCAL)) return FALSE;
|
|
if (GetMembers(&tnList) != STATUS_OK) return FALSE;
|
|
tnList.Init();
|
|
while (tnList.GetPeer(&pNode) == STATUS_OK)
|
|
{
|
|
if (pNode->GetNodeType() == NODE_PROC)
|
|
{
|
|
if (!(pNode->FInSummary(ATTR_LOCAL)) &&
|
|
!(pNode->GetNodeState() & NODE_STATE_IMPORT_OFF))
|
|
pNode->CountAlloc(MaxAlign);
|
|
}
|
|
}
|
|
break;
|
|
case NODE_FILE:
|
|
if (GetNodeState() & NODE_STATE_IMPORT) return FALSE;
|
|
pNode = GetMembers ();
|
|
pNode->CountAlloc(MaxAlign);
|
|
break;
|
|
case NODE_SOURCE:
|
|
if (GetMembers(&tnList) != STATUS_OK) return FALSE;
|
|
tnList.Init();
|
|
while (tnList.GetPeer(&pNode) == STATUS_OK)
|
|
{
|
|
pNode->CountAlloc(MaxAlign);
|
|
}
|
|
break;
|
|
case NODE_DEF:
|
|
if (FInSummary(ATTR_TRANSMIT))
|
|
{
|
|
pXmit = ((node_def *)this)->GetTransmitAsType ();
|
|
assert (pXmit != (node_skl *)0);
|
|
fHasTreeBuffer = pXmit->CountAlloc (MaxAlign);
|
|
return fHasTreeBuffer;
|
|
}
|
|
|
|
((node_def *)this)->PropogateAttributeToPointer (ATTR_ALLOCATE);
|
|
|
|
pNode = GetMembers ();
|
|
fHasTreeBuffer = pNode->CountAlloc(MaxAlign);
|
|
return fHasTreeBuffer;
|
|
case NODE_PROC:
|
|
if (GetMembers(&tnList) != STATUS_OK) return FALSE;
|
|
tnList.Init();
|
|
while (tnList.GetPeer(&pNode) == STATUS_OK)
|
|
{
|
|
if (pNode->CountAlloc(MaxAlign)) fHasTreeBuffer = 1;
|
|
}
|
|
break;
|
|
case NODE_PARAM:
|
|
if (fUseTreeBuffer)
|
|
{
|
|
fHasTreeBuffer = TRUE;
|
|
}
|
|
else
|
|
{
|
|
pNode = GetMembers ();
|
|
if (pNode == (node_skl *)0) return FALSE;
|
|
if (!fHasTreeBuffer)
|
|
{
|
|
fHasTreeBuffer = pNode->CountAlloc(MaxAlign);
|
|
}
|
|
}
|
|
return fHasTreeBuffer;
|
|
case NODE_POINTER:
|
|
if (MaxAlign)
|
|
{
|
|
fAllocateAlign = 1;
|
|
}
|
|
else
|
|
{
|
|
short fNode = 0;
|
|
if (FInSummary(ATTR_ALLOCATE)) fNode = GetAllocateDetails ();
|
|
if (IS_ALLOCATE(fNode, ALLOCATE_ALL_NODES_ALIGNED)
|
|
== ALLOCATE_ALL_NODES_ALIGNED)
|
|
{
|
|
fAllocateAlign = 1;
|
|
}
|
|
}
|
|
pNode = GetMembers ();
|
|
if (pNode == (node_skl *)0) return FALSE;
|
|
#if 1
|
|
if( FInSummary( ATTR_STRING ) || FInSummary( ATTR_BSTRING ) )
|
|
fHasTreeBuffer = TRUE;
|
|
#endif // 1
|
|
|
|
if (!fHasTreeBuffer)
|
|
{
|
|
fHasTreeBuffer = pNode->CountAlloc(fAllocateAlign);
|
|
}
|
|
else
|
|
{
|
|
pNode->CountAlloc(fAllocateAlign);
|
|
}
|
|
return fHasTreeBuffer;
|
|
case NODE_FIELD:
|
|
if (((node_field *)this)->IsEmptyArm())
|
|
{
|
|
break;
|
|
}
|
|
// fall through
|
|
default:
|
|
pNode = GetMembers ();
|
|
if (pNode == (node_skl *)0) return FALSE;
|
|
if (!fHasTreeBuffer)
|
|
{
|
|
fHasTreeBuffer = pNode->CountAlloc(MaxAlign);
|
|
}
|
|
else
|
|
{
|
|
pNode->CountAlloc(MaxAlign);
|
|
}
|
|
return fHasTreeBuffer;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
void
|
|
node_skl::AllocBlock (NODE_T Parent, BufferManager * pBuffer)
|
|
{
|
|
node_skl * pNode;
|
|
node_skl * pTemp;
|
|
char * pName;
|
|
NODE_T Type;
|
|
node_state State;
|
|
|
|
pName = GetSymName();
|
|
|
|
Type = GetNodeType();
|
|
|
|
State = GetNodeState();
|
|
|
|
switch (Type)
|
|
{
|
|
case NODE_DEF:
|
|
if (State & NODE_STATE_CONF_ARRAY)
|
|
{
|
|
pNode = GetMembers ();
|
|
pNode->AllocBlock (Parent, pBuffer);
|
|
break;
|
|
}
|
|
// fall through
|
|
case NODE_DOUBLE:
|
|
case NODE_FLOAT:
|
|
case NODE_HYPER:
|
|
case NODE_LONGLONG:
|
|
case NODE_LONG:
|
|
case NODE_SHORT:
|
|
case NODE_SMALL:
|
|
case NODE_CHAR:
|
|
case NODE_BYTE:
|
|
case NODE_BOOLEAN:
|
|
case NODE_INT:
|
|
assert (pName != (char *)0);
|
|
pBuffer->ConcatTail ("sizeof(");
|
|
pBuffer->ConcatTail (pName);
|
|
pBuffer->ConcatTail (")");
|
|
break;
|
|
case NODE_VOID:
|
|
pBuffer->ConcatTail ("sizeof(unsigned char)");
|
|
break;
|
|
case NODE_POINTER:
|
|
if (Parent != NODE_DYNAMIC_ARRAY)
|
|
{
|
|
// pBuffer->ConcatTail ("sizeof(void *)");
|
|
pBuffer->ConcatTail ("sizeof(void ");
|
|
pBuffer->ConcatTail (pOutput->GetModifier());
|
|
pBuffer->ConcatTail ("*)");
|
|
break;
|
|
}
|
|
// fall through
|
|
case NODE_ARRAY:
|
|
pNode = GetMembers ();
|
|
if (FInSummary(ATTR_MAX) || FInSummary(ATTR_SIZE) ||
|
|
((FInSummary(ATTR_STRING) || FInSummary( ATTR_BSTRING )) && !(State & NODE_STATE_VARYING_ARRAY)))
|
|
{
|
|
pBuffer->ConcatTail ("_alloc_total * ");
|
|
}
|
|
else
|
|
{
|
|
AllocBounds.pLower->Clear ();
|
|
AllocBounds.pUpper->Clear ();
|
|
AllocBounds.pTotal->Clear ();
|
|
((node_array *)this)->GetAllocBoundInfo (pBuffer, 0, &AllocBounds, this);
|
|
pBuffer->Merge (AllocBounds.pTotal);
|
|
pBuffer->ConcatTail (" * ");
|
|
}
|
|
pNode->AllocBlock (NODE_ARRAY, pBuffer);
|
|
|
|
if( FInSummary( ATTR_BSTRING ) )
|
|
{
|
|
if( GetBasicType()->NodeKind() == NODE_WCHAR_T )
|
|
pBuffer->ConcatTail( "+(sizeof(int)/sizeof(unsigned short))" );
|
|
else
|
|
pBuffer->ConcatTail( "+(sizeof(int)/sizeof(char))" );
|
|
}
|
|
break;
|
|
case NODE_ENUM:
|
|
pBuffer->ConcatTail ("sizeof(int)");
|
|
break;
|
|
case NODE_UNION:
|
|
assert (pName != (char *)0);
|
|
|
|
pBuffer->ConcatTail( "sizeof(" );
|
|
|
|
if( ((su *)this)->HasOriginalTypedefName() )
|
|
{
|
|
pBuffer->ConcatTail( ((su *)this)->GetOriginalTypedefName() );
|
|
}
|
|
else
|
|
{
|
|
pBuffer->ConcatTail ("union ");
|
|
pBuffer->ConcatTail (pName);
|
|
}
|
|
|
|
pBuffer->ConcatTail (")");
|
|
break;
|
|
case NODE_STRUCT:
|
|
assert (pName != (char *)0);
|
|
|
|
pBuffer->ConcatTail ("sizeof(");
|
|
|
|
if( ((su *)this)->HasOriginalTypedefName() )
|
|
{
|
|
pBuffer->ConcatTail (((su *)this)->GetOriginalTypedefName());
|
|
}
|
|
else
|
|
{
|
|
pBuffer->ConcatTail ("struct ");
|
|
pBuffer->ConcatTail (pName);
|
|
}
|
|
|
|
pBuffer->ConcatTail (")");
|
|
|
|
if (State & NODE_STATE_CONF_ARRAY)
|
|
{
|
|
pNode = GetConfArrayNode ();
|
|
pNode->GetMembers (&pTemp);
|
|
pBuffer->ConcatTail (" - ");
|
|
pTemp->AllocBlock (NODE_ARRAY, pBuffer);
|
|
pBuffer->ConcatTail (" + ");
|
|
pNode->AllocBlock (NODE_STRUCT, pBuffer);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
node_skl *
|
|
node_struct::SkipBlock (
|
|
type_node_list * ptnList,
|
|
node_skl ** pTail, // beginning of unaligned data
|
|
unsigned long * pSize
|
|
)
|
|
{
|
|
node_skl * pNode;
|
|
node_skl * pBase;
|
|
node_skl * pHead = (node_skl *)0; // beginning of aligned data
|
|
unsigned long ulTotal = 0; // number of bytes in this aligned block
|
|
unsigned short usAlign = 0;
|
|
|
|
*pTail = (node_skl *)0;
|
|
while (ptnList->GetPeer(&pNode) == STATUS_OK)
|
|
{
|
|
if (!ulTotal) pHead = pNode;
|
|
#if 0
|
|
|
|
if( pNode->HasAnyNETransmitAsType() )
|
|
{
|
|
BOOL flag = 0;
|
|
|
|
pBase = pNode;
|
|
|
|
while( (flag == 0 ) && (pBase = pBase->GetChild() ) )
|
|
{
|
|
switch( pBase->NodeKind() )
|
|
{
|
|
case NODE_POINTER:
|
|
case NODE_ARRAY:
|
|
break;
|
|
case NODE_DEF:
|
|
if( pBase->FInSummary( ATTR_TRANSMIT ) )
|
|
{
|
|
pBase = ((node_def *)pBase)->GetTransmitAsType();
|
|
flag = 1;
|
|
}
|
|
else
|
|
break;
|
|
default:
|
|
flag = 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
pBase = pNode->GetBasicType();
|
|
|
|
#else // 1
|
|
|
|
pBase = pNode->GetBasicType ();
|
|
|
|
#endif // 1
|
|
|
|
if (!usAlign || pBase->GetNdrAlign() <= usAlign)
|
|
{
|
|
usAlign = pBase->GetNdrAlign();
|
|
}
|
|
else
|
|
{
|
|
*pSize = ulTotal;
|
|
*pTail = pNode;
|
|
return pHead;
|
|
}
|
|
switch (pBase->GetNodeType())
|
|
{
|
|
case NODE_DOUBLE:
|
|
case NODE_HYPER:
|
|
case NODE_LONGLONG:
|
|
if (ulTotal % usAlign)
|
|
ulTotal += usAlign - (ulTotal % usAlign);
|
|
ulTotal += 8;
|
|
break;
|
|
case NODE_FLOAT:
|
|
case NODE_LONG:
|
|
if (ulTotal % usAlign)
|
|
ulTotal += usAlign - (ulTotal % usAlign);
|
|
ulTotal += 4;
|
|
break;
|
|
case NODE_SHORT:
|
|
case NODE_ENUM:
|
|
if (ulTotal % usAlign)
|
|
ulTotal += usAlign - (ulTotal % usAlign);
|
|
ulTotal += 2;
|
|
break;
|
|
case NODE_SMALL:
|
|
case NODE_CHAR:
|
|
case NODE_BYTE:
|
|
case NODE_BOOLEAN:
|
|
if (ulTotal % usAlign)
|
|
ulTotal += usAlign - (ulTotal % usAlign);
|
|
ulTotal += 1;
|
|
break;
|
|
case NODE_POINTER:
|
|
case NODE_ARRAY:
|
|
case NODE_UNION:
|
|
case NODE_STRUCT:
|
|
*pSize = ulTotal;
|
|
*pTail = pNode;
|
|
return pHead;
|
|
default:
|
|
return pHead;
|
|
}
|
|
}
|
|
*pSize = ulTotal;
|
|
*pTail = (node_skl *)0;
|
|
return pHead;
|
|
}
|
|
|
|
node_skl *
|
|
node_union::SkipBlock (
|
|
type_node_list * ptnList,
|
|
node_skl ** pTail, // tail of prev block
|
|
unsigned long * pSize
|
|
)
|
|
{
|
|
node_skl * pNode; // head of next block
|
|
node_skl * pBase;
|
|
node_state State;
|
|
unsigned long MscTemp = 0;
|
|
unsigned long NdrTemp = 0;
|
|
|
|
if (ptnList->GetPeer(&pNode) == STATUS_OK)
|
|
{
|
|
State = pNode->GetNodeState();
|
|
if (*pTail == (node_skl *)0) *pTail = pNode; // the first member
|
|
if ((State & NODE_STATE_CONF_ARRAY) ||
|
|
(State & NODE_STATE_VARYING_ARRAY) ||
|
|
(State & NODE_STATE_UNION))
|
|
{
|
|
*pSize = 0;
|
|
return pNode;
|
|
}
|
|
if (((node_field *)pNode)->IsEmptyArm())
|
|
{
|
|
if (*pSize == 0) *pTail = pNode;
|
|
}
|
|
else
|
|
{
|
|
pBase = pNode->GetBasicType ();
|
|
#if 1
|
|
if( pBase->CheckAlign( &MscTemp, &NdrTemp ) )
|
|
{
|
|
if( *pSize == NdrTemp )
|
|
*pTail = pNode;
|
|
}
|
|
else
|
|
{
|
|
NdrTemp = 0;
|
|
}
|
|
#else // 1
|
|
|
|
pBase->CheckAlign (&MscTemp, &NdrTemp);
|
|
if (*pSize == NdrTemp) *pTail = pNode; // advance one member
|
|
#endif // 1
|
|
}
|
|
*pSize = NdrTemp;
|
|
return pNode;
|
|
}
|
|
return (node_skl *)0;
|
|
}
|
|
|
|
node_skl *
|
|
node_union::CopyBlock (
|
|
type_node_list * ptnList,
|
|
node_skl ** pTail, // tail of prev block
|
|
unsigned long * pSize
|
|
)
|
|
{
|
|
node_skl * pNode; // head of next block
|
|
node_skl * pBase;
|
|
node_state State;
|
|
unsigned long MscTemp = 0;
|
|
unsigned long NdrTemp = 0;
|
|
|
|
if (ptnList->GetPeer(&pNode) == STATUS_OK)
|
|
{
|
|
State = pNode->GetNodeState();
|
|
if (*pTail == (node_skl *)0) *pTail = pNode;
|
|
if ((State & NODE_STATE_CONF_ARRAY) ||
|
|
(State & NODE_STATE_VARYING_ARRAY) ||
|
|
(State & NODE_STATE_UNION) ||
|
|
(State & NODE_STATE_ENUM))
|
|
{
|
|
*pSize = 0;
|
|
return pNode;
|
|
}
|
|
if (((node_field *)pNode)->IsEmptyArm())
|
|
{
|
|
if (*pSize == 0)
|
|
*pTail = pNode;
|
|
}
|
|
else
|
|
{
|
|
pBase = pNode->GetBasicType ();
|
|
#if 1
|
|
if( pBase->CheckAlign( &MscTemp, &NdrTemp ) )
|
|
{
|
|
if( *pSize == NdrTemp )
|
|
*pTail = pNode;
|
|
}
|
|
else
|
|
{
|
|
NdrTemp = 0;
|
|
}
|
|
#else // 1
|
|
if (pBase->CheckAlign(&MscTemp, &NdrTemp) && (*pSize == NdrTemp))
|
|
*pTail = pNode;
|
|
#endif // 1
|
|
}
|
|
*pSize = NdrTemp;
|
|
return pNode;
|
|
}
|
|
return (node_skl *)0;
|
|
}
|
|
|
|
void
|
|
node_skl::EmitSpecifier (BufferManager * pBuffer)
|
|
{
|
|
if (FInSummary(ATTR_EXTERN))
|
|
pBuffer->ConcatHead ("extern ");
|
|
else if (FInSummary(ATTR_STATIC))
|
|
pBuffer->ConcatHead ("static ");
|
|
else if (FInSummary(ATTR_AUTOMATIC))
|
|
pBuffer->ConcatHead ("auto ");
|
|
else if (FInSummary(ATTR_REGISTER))
|
|
pBuffer->ConcatHead ("register ");
|
|
|
|
#if 0
|
|
if (FInSummary( ATTR_C_INLINE ))
|
|
pBuffer->ConcatHead("__inline ");
|
|
#endif // 0
|
|
}
|
|
|
|
void
|
|
node_skl::EmitQualifier (SIDE_T Side, BufferManager * pBuffer)
|
|
{
|
|
if (FInSummary(ATTR_CONST))
|
|
{
|
|
if((Side != SERVER_STUB) || fEmitConst)
|
|
pBuffer->ConcatHead ("const ");
|
|
}
|
|
else if (FInSummary(ATTR_VOLATILE))
|
|
pBuffer->ConcatHead ("volatile ");
|
|
}
|
|
|
|
void
|
|
node_skl::EmitModifier (BufferManager * pBuffer)
|
|
{
|
|
if (FInSummary(ATTR_FAR)) pBuffer->ConcatHead ("_far ");
|
|
if (FInSummary(ATTR_FAR16)) pBuffer->ConcatHead ("far16 ");
|
|
if (FInSummary(ATTR_NEAR)) pBuffer->ConcatHead ("_near ");
|
|
if (FInSummary(ATTR_HUGE)) pBuffer->ConcatHead ("_huge ");
|
|
if (FInSummary(ATTR_PASCAL)) pBuffer->ConcatHead ("_pascal ");
|
|
if (FInSummary(ATTR_FORTRAN)) pBuffer->ConcatHead ("_fortran ");
|
|
if (FInSummary(ATTR_CDECL)) pBuffer->ConcatHead ("_cdecl ");
|
|
if (FInSummary(ATTR_LOADDS)) pBuffer->ConcatHead ("_loadds ");
|
|
if (FInSummary(ATTR_SAVEREGS)) pBuffer->ConcatHead ("_saveregs ");
|
|
if (FInSummary(ATTR_FASTCALL)) pBuffer->ConcatHead ("_fastcall ");
|
|
if (FInSummary(ATTR_SEGMENT)) pBuffer->ConcatHead ("_segment ");
|
|
if (FInSummary(ATTR_INTERRUPT)) pBuffer->ConcatHead ("_interrupt ");
|
|
if (FInSummary(ATTR_SELF)) pBuffer->ConcatHead ("_self ");
|
|
if (FInSummary(ATTR_EXPORT)) pBuffer->ConcatHead ("_export ");
|
|
if (FInSummary(ATTR_BASE)) pBuffer->ConcatHead ("_based ");
|
|
if (FInSummary(ATTR_MSCUNALIGNED)) pBuffer->ConcatHead ("__unaligned ");
|
|
if (FInSummary(ATTR_STDCALL)) pBuffer->ConcatHead ("__stdcall ");
|
|
|
|
if (FInSummary( ATTR_C_INLINE ))
|
|
pBuffer->ConcatHead("__inline ");
|
|
}
|
|
void
|
|
node_skl::EmitModifierWOInLine (BufferManager * pBuffer)
|
|
{
|
|
if (FInSummary(ATTR_FAR)) pBuffer->ConcatHead ("_far ");
|
|
if (FInSummary(ATTR_FAR16)) pBuffer->ConcatHead ("far16 ");
|
|
if (FInSummary(ATTR_NEAR)) pBuffer->ConcatHead ("_near ");
|
|
if (FInSummary(ATTR_HUGE)) pBuffer->ConcatHead ("_huge ");
|
|
if (FInSummary(ATTR_PASCAL)) pBuffer->ConcatHead ("_pascal ");
|
|
if (FInSummary(ATTR_FORTRAN)) pBuffer->ConcatHead ("_fortran ");
|
|
if (FInSummary(ATTR_CDECL)) pBuffer->ConcatHead ("_cdecl ");
|
|
if (FInSummary(ATTR_LOADDS)) pBuffer->ConcatHead ("_loadds ");
|
|
if (FInSummary(ATTR_SAVEREGS)) pBuffer->ConcatHead ("_saveregs ");
|
|
if (FInSummary(ATTR_FASTCALL)) pBuffer->ConcatHead ("_fastcall ");
|
|
if (FInSummary(ATTR_SEGMENT)) pBuffer->ConcatHead ("_segment ");
|
|
if (FInSummary(ATTR_INTERRUPT)) pBuffer->ConcatHead ("_interrupt ");
|
|
if (FInSummary(ATTR_SELF)) pBuffer->ConcatHead ("_self ");
|
|
if (FInSummary(ATTR_EXPORT)) pBuffer->ConcatHead ("_export ");
|
|
if (FInSummary(ATTR_BASE)) pBuffer->ConcatHead ("_based ");
|
|
if (FInSummary(ATTR_MSCUNALIGNED)) pBuffer->ConcatHead ("__unaligned ");
|
|
if (FInSummary(ATTR_STDCALL)) pBuffer->ConcatHead ("__stdcall ");
|
|
|
|
}
|
|
|
|
void
|
|
node_proc::PassHandleInfo ()
|
|
{
|
|
type_node_list tnList;
|
|
node_skl * pNode;
|
|
node_skl * pHandleTypeNode;
|
|
short NumHandle;
|
|
HDL_TYPE HandleType;
|
|
|
|
BOOL UseAutomaticHandle = FALSE;
|
|
BOOL UsePrimitiveHandle = FALSE;
|
|
unsigned short NumGenericHandle = 0;
|
|
unsigned short NumContextHandle = 0;
|
|
|
|
if (FInSummary(ATTR_CONTEXT) || GetReturnType()->FInSummary(ATTR_CONTEXT))
|
|
{
|
|
NumContextHandle++;
|
|
}
|
|
|
|
NumHandle = HasHandle(&tnList);
|
|
|
|
if (NumHandle)
|
|
{
|
|
NumHandle = 0;
|
|
tnList.Init();
|
|
while (tnList.GetPeer(&pNode) == STATUS_OK)
|
|
{
|
|
HandleType = pNode->GetBasicHandle (&pHandleTypeNode);
|
|
switch (HandleType)
|
|
{
|
|
case HDL_PRIMITIVE :
|
|
UsePrimitiveHandle = TRUE;
|
|
NumHandle++;
|
|
break;
|
|
case HDL_CONTEXT:
|
|
NumContextHandle++;
|
|
if (pNode->FInSummary(ATTR_IN))
|
|
{
|
|
NumHandle++;
|
|
}
|
|
break;
|
|
case HDL_GENERIC:
|
|
NumGenericHandle++;
|
|
NumHandle++;
|
|
#if 1
|
|
{
|
|
char * pHandleName = pHandleTypeNode->GetSymName();
|
|
char * pParamName = pNode->GetSymName();
|
|
|
|
//
|
|
// set up for generic handle unbind in exceptions.
|
|
//
|
|
|
|
if( pNode->GetMembers() != pHandleTypeNode )
|
|
{
|
|
pOutput->SetupForGenHdlExceptions( PARAM_INOUT,
|
|
pHandleName,
|
|
pParamName );
|
|
}
|
|
else
|
|
{
|
|
pOutput->SetupForGenHdlExceptions( PARAM_IN,
|
|
pHandleName,
|
|
pParamName );
|
|
}
|
|
}
|
|
#endif // 1
|
|
break;
|
|
case HDL_AUTO:
|
|
// can't happen here. Label added to fix a comp warning.
|
|
assert( FALSE );
|
|
break;
|
|
case HDL_NONE:
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
if (NumHandle)
|
|
{
|
|
pOutput->InitHandle (
|
|
UseAutomaticHandle,
|
|
UsePrimitiveHandle,
|
|
NumGenericHandle,
|
|
NumContextHandle);
|
|
return;
|
|
}
|
|
}
|
|
if (pImplicitHandleType)
|
|
{
|
|
HandleType = pImplicitHandleType->GetBasicHandle (&pHandleTypeNode);
|
|
if (HandleType == HDL_GENERIC)
|
|
{
|
|
#if 1
|
|
{
|
|
char * pHandleName = pImplicitHandleType->GetSymName();
|
|
char * pParamName = pImplicitHandleName;
|
|
|
|
//
|
|
// set up for generic handle unbind in exceptions.
|
|
//
|
|
|
|
pOutput->SetupForGenHdlExceptions( PARAM_IN,
|
|
pHandleName,
|
|
pParamName );
|
|
}
|
|
#endif // 1
|
|
NumGenericHandle++;
|
|
}
|
|
else
|
|
{
|
|
UsePrimitiveHandle = TRUE;
|
|
}
|
|
}
|
|
else if (HasAutoHandle)
|
|
{
|
|
UseAutomaticHandle = TRUE;
|
|
}
|
|
|
|
pOutput->InitHandle (
|
|
UseAutomaticHandle,
|
|
UsePrimitiveHandle,
|
|
NumGenericHandle,
|
|
NumContextHandle);
|
|
}
|
|
|
|
|
|
STATUS_T
|
|
node_proc::EmitBindProlog(SIDE_T Side)
|
|
{
|
|
type_node_list tnList;
|
|
node_skl * pNode;
|
|
node_skl * pHandleTypeNode;
|
|
char * pHandleTypeName;
|
|
char * pHandleName;
|
|
short NumHandle;
|
|
HDL_TYPE HandleType;
|
|
|
|
midl_debug ("node_proc::EmitBindProlog()\n");
|
|
|
|
NumHandle = HasHandle(&tnList);
|
|
|
|
if (NumHandle)
|
|
{
|
|
NumHandle = 0;
|
|
tnList.Init();
|
|
while (tnList.GetPeer(&pNode) == STATUS_OK)
|
|
{
|
|
pHandleName = pNode->GetSymName();
|
|
assert (pHandleName != (char *)0);
|
|
HandleType = pNode->GetBasicHandle (&pHandleTypeNode);
|
|
switch (HandleType)
|
|
{
|
|
case HDL_PRIMITIVE :
|
|
pOutput->RpcPrimitiveBind (Side, pHandleName, TRUE);
|
|
NumHandle++;
|
|
break;
|
|
case HDL_CONTEXT:
|
|
if (pNode->FInSummary(ATTR_IN) && pNode->FInSummary(ATTR_OUT))
|
|
{
|
|
pOutput->RpcContextBind (Side, pHandleName, PARAM_INOUT);
|
|
NumHandle++;
|
|
}
|
|
else if (pNode->FInSummary(ATTR_IN))
|
|
{
|
|
pOutput->RpcContextBind (Side, pHandleName, PARAM_IN);
|
|
NumHandle++;
|
|
}
|
|
else if (pNode->FInSummary(ATTR_OUT))
|
|
{
|
|
pOutput->RpcContextBind (Side, pHandleName, PARAM_OUT);
|
|
}
|
|
break;
|
|
case HDL_GENERIC:
|
|
pHandleTypeName = pHandleTypeNode->GetSymName ();
|
|
assert (pHandleTypeName != (char *)0);
|
|
// if (pNode->FInSummary(ATTR_OUT))
|
|
if (pNode->GetMembers() != pHandleTypeNode)
|
|
{
|
|
pOutput->GenericBindProlog (
|
|
Side,
|
|
PARAM_INOUT,
|
|
pHandleTypeName,
|
|
pHandleName,
|
|
TRUE);
|
|
}
|
|
else
|
|
{
|
|
pOutput->GenericBindProlog (
|
|
Side,
|
|
PARAM_IN,
|
|
pHandleTypeName,
|
|
pHandleName,
|
|
TRUE);
|
|
}
|
|
NumHandle++;
|
|
break;
|
|
case HDL_AUTO:
|
|
// can't happen here. Label added to fix a comp warning.
|
|
assert( FALSE );
|
|
break;
|
|
case HDL_NONE:
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
if (NumHandle)
|
|
{
|
|
if (!FInSummary(ATTR_CALLBACK))
|
|
{
|
|
pOutput->Print (Side, " "MESSAGE".RpcInterfaceInformation = (void __RPC_FAR *) &");
|
|
pOutput->Print (Side, "___RpcClientInterface;\n");
|
|
}
|
|
return STATUS_OK;
|
|
}
|
|
}
|
|
if (pImplicitHandleType)
|
|
{
|
|
HandleType = pImplicitHandleType->GetBasicHandle (&pHandleTypeNode);
|
|
if (HandleType == HDL_GENERIC)
|
|
{
|
|
pHandleTypeName = pHandleTypeNode->GetSymName();
|
|
assert (pHandleTypeName != (char *)0);
|
|
pOutput->GenericBindProlog (
|
|
Side, PARAM_IN, pHandleTypeName, pImplicitHandleName, FALSE);
|
|
}
|
|
else
|
|
{
|
|
pOutput->RpcPrimitiveBind (Side, pImplicitHandleName, FALSE);
|
|
}
|
|
}
|
|
else if (HasAutoHandle)
|
|
{
|
|
pOutput->RpcAutomaticBind (Side);
|
|
}
|
|
if (!FInSummary(ATTR_CALLBACK))
|
|
{
|
|
pOutput->Print (Side, " "MESSAGE".RpcInterfaceInformation = (void __RPC_FAR *) &");
|
|
pOutput->Print (Side, "___RpcClientInterface;\n");
|
|
}
|
|
|
|
return STATUS_OK;
|
|
}
|
|
|
|
STATUS_T
|
|
node_proc::EmitBindEpilog(SIDE_T Side)
|
|
{
|
|
type_node_list tnList;
|
|
node_skl * pNode;
|
|
node_skl * pHandleTypeNode;
|
|
char * pHandleTypeName;
|
|
char * pHandleName;
|
|
short NumHandle;
|
|
HDL_TYPE HandleType;
|
|
|
|
midl_debug ("node_proc::EmitBindProlog()\n");
|
|
|
|
NumHandle = HasHandle(&tnList);
|
|
|
|
if (NumHandle)
|
|
{
|
|
tnList.Init();
|
|
|
|
while (tnList.GetPeer(&pNode) == STATUS_OK)
|
|
{
|
|
HandleType = pNode->GetBasicHandle (&pHandleTypeNode);
|
|
if (HandleType == HDL_GENERIC)
|
|
{
|
|
pHandleName = pNode->GetSymName ();
|
|
assert (pHandleName != (char *)0);
|
|
pHandleTypeName = pHandleTypeNode->GetSymName ();
|
|
assert (pHandleTypeName != (char *)0);
|
|
// if (pNode->FInSummary(ATTR_OUT))
|
|
if (pNode->GetMembers() != pHandleTypeNode)
|
|
{
|
|
pOutput->GenericBindEpilog (
|
|
Side, PARAM_INOUT, pHandleTypeName, pHandleName);
|
|
}
|
|
else
|
|
{
|
|
pOutput->GenericBindEpilog (
|
|
Side, PARAM_IN, pHandleTypeName, pHandleName);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else if (pImplicitHandleType)
|
|
{
|
|
HandleType = pImplicitHandleType->GetBasicHandle (&pHandleTypeNode);
|
|
if (HandleType == HDL_GENERIC)
|
|
{
|
|
pHandleTypeName = pHandleTypeNode->GetSymName ();
|
|
assert (pHandleTypeName != (char *)0);
|
|
pOutput->GenericBindEpilog (
|
|
Side, PARAM_IN, pHandleTypeName, pImplicitHandleName);
|
|
}
|
|
}
|
|
|
|
return STATUS_OK;
|
|
}
|