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

500 lines
11 KiB
C++

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 1989-1999 Microsoft Corporation
Module Name:
ptrgen.cxx
Abstract:
Implementations of the pointer cg class methods.
Notes:
History:
Oct-10-1993 VibhasC Created
----------------------------------------------------------------------------*/
/****************************************************************************
* include files
***************************************************************************/
#include "becls.hxx"
#pragma hdrstop
/****************************************************************************
* local definitions
***************************************************************************/
/****************************************************************************
* local data
***************************************************************************/
/****************************************************************************
* externs
***************************************************************************/
/****************************************************************************/
CG_STATUS
CG_POINTER::S_GenInitOutLocals(
CCB * pCCB )
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Generate code for initialization of server side local variables.
Arguments:
pCCB - A Ptr to the code gen controller block.
Return Value:
Notes:
The source expression field of the ccb has the final presented expression.
----------------------------------------------------------------------------*/
{
expr_node * pExpr;
if( pCCB->IsRefAllocDone() )
{
pExpr = MakeAddressExpressionNoMatterWhat( GetResource() );
Out_Assign( pCCB, pCCB->GetSourceExpression(), pExpr );
pExpr = pCCB->SetSourceExpression( GetResource() );
Out_Assign( pCCB, GetResource(), new expr_constant( 0L ) );
}
else
pExpr = pCCB->GetSourceExpression();
if( IsRef() && !IsQualifiedPointer() )
{
pCCB->ResetMemoryAllocDone();
pCCB->SetRefAllocDone();
((CG_NDR *)GetChild())->S_GenInitOutLocals( pCCB );
}
// If it is a byte count pointer, allocate the bytes specified as the
// byte count param.
// else if it is an out sized etc pointer, then must allocate.
if( GetCGID() == ID_CG_BC_PTR )
{
PNAME pName = ((CG_BYTE_COUNT_POINTER *)this)->GetByteCountParam()->GetSymName();
expr_node * pByteCountExpr = new expr_variable( pName );
Out_Alloc(pCCB,
pExpr,
0,
pByteCountExpr );
}
else if( IsQualifiedPointer() && !(GetCGID() == ID_CG_STRING_PTR) && IsRef() )
{
expr_node * pElementExpr;
expr_node * pFinalExpr;
expr_node * pCheckExpr;
BOOL fIsSigned;
// Fool the presented expression to beleive it is marshalling, so that
// it generates the correct expression.
CGPHASE Ph = pCCB->GetCodeGenPhase();
pCCB->SetCodeGenPhase( CGPHASE_MARSHALL );
// The proper size of the allocation is size times the element size.
pElementExpr = new expr_constant(
(long) (((CG_NDR *)GetChild())->GetMemorySize()) );
pFinalExpr = FinalSizeExpression( pCCB );
fIsSigned = !((node_base_type *)pFinalExpr->GetType()->GetBasicType())->IsUnsigned();
pFinalExpr = new expr_op_binary( OP_STAR,
pFinalExpr,
pElementExpr );
// Allocate the proper size.
// If the size expression is signed and the value is less than 0, we
// need to raise an exception.
if( pCCB->MustCheckBounds() && fIsSigned )
{
pCheckExpr = new expr_op_binary( OP_LESS,
pFinalExpr,
new expr_constant(0L));
Out_If( pCCB, pCheckExpr);
Out_RaiseException( pCCB, "RPC_X_INVALID_BOUND" );
Out_Endif( pCCB );
}
Out_Alloc(pCCB,
pExpr,
0,
pFinalExpr );
pCCB->SetCodeGenPhase( Ph );
}
return CG_OK;
}
CG_STATUS
CG_STRING_POINTER::GenConfVarianceEtcUnMarshall( CCB* )
{
return CG_OK;
}
/*****************************************************************************
utility functions
*****************************************************************************/
expr_node *
CG_POINTER::GenBindOrUnBindExpression(
CCB * pCCB,
BOOL )
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Generate the final binding expression.
Arguments:
pCCB - Ptr to Code gen controller block.
fBind - Indicates a bind or unbind code gen.
Return Value:
Notes:
----------------------------------------------------------------------------*/
{
MIDL_ASSERT( pCCB->GetSourceExpression() );
return new expr_u_deref( pCCB->GetSourceExpression() );
}
CG_STATUS
CG_POINTER::GenRefChecks(
CCB * pCCB )
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Generate ref checks for a pointer.
Arguments:
Return Value:
CG_OK
Notes:
----------------------------------------------------------------------------*/
{
expr_node * pSrc = pCCB->GetSourceExpression();
if( IsRef() )
{
if( pCCB->IsRefAllocDone() )
pSrc = pCCB->SetSourceExpression(
MakeDereferentExpressionIfNecessary(
pCCB->GetSourceExpression()));
// using the source expression, check for null ref pointers.
Out_If( pCCB, new expr_u_not( pSrc ) );
Out_RaiseException( pCCB, "RPC_X_NULL_REF_POINTER" );
Out_Endif( pCCB );
pCCB->SetRefAllocDone();
pCCB->ResetMemoryAllocDone();
((CG_NDR *)GetChild())->GenRefChecks( pCCB );
}
return CG_OK;
}
CG_STATUS
CG_POINTER::S_GenInitInLocals(
CCB * pCCB )
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Perform in local init code generation. This method does nothing for
pointers. Ref pointers are supposed to pass this message to their
children after setting the appropriate source expressions.
Arguments:
pCCB - The code gen block.
Return Value:
CG_OK
Notes:
----------------------------------------------------------------------------*/
{
expr_node * pSrc = pCCB->GetSourceExpression();
if( IsRef() )
{
if( pCCB->IsRefAllocDone() )
pSrc = pCCB->SetSourceExpression(
MakeDereferentExpressionIfNecessary(
pCCB->GetSourceExpression()));
((CG_NDR *)GetChild())->S_GenInitInLocals( pCCB );
}
return CG_OK;
}
expr_node *
CG_POINTER::FinalSizeExpression(
CCB * pCCB )
{
return PresentedSizeExpression( pCCB );
}
expr_node *
CG_POINTER::FinalFirstExpression(
CCB * pCCB )
{
return PresentedFirstExpression( pCCB );
}
expr_node *
CG_POINTER::FinalLengthExpression(
CCB * pCCB )
{
return PresentedLengthExpression( pCCB );
}
expr_node *
CG_STRING_POINTER::PresentedSizeExpression(
CCB * pCCB )
{
if( pCCB->GetCodeGenPhase() == CGPHASE_UNMARSHALL )
{
return GetSizeResource();
}
else
{
return PresentedLengthExpression( pCCB );
}
}
expr_node *
CG_STRING_POINTER::PresentedLengthExpression(
CCB * pCCB )
{
if( pCCB->GetCodeGenPhase() == CGPHASE_UNMARSHALL )
{
return GetLengthResource();
}
else if((pCCB->GetCodeGenPhase() == CGPHASE_MARSHALL ) && !IsUsedInArray())
{
return GetLengthResource();
}
else
{
unsigned short Size = (unsigned short )((CG_NDR *)GetChild())->GetMemorySize();
expr_proc_call * pProc;
PNAME pName;
expr_node * pExpr;
if( Size == 1 )
{
pName = "strlen";
}
else if( Size == 2)
{
pName = "MIDL_wchar_strlen";
}
else
pName = "MIDL_NChar_strlen";
pProc = new expr_proc_call( pName );
pProc->SetParam( new expr_param( pCCB->GetSourceExpression() ));
pExpr = new expr_b_arithmetic( OP_PLUS,
pProc,
new expr_constant( 1L ));
return pExpr;
}
}
expr_node *
CG_SIZE_STRING_POINTER::PresentedSizeExpression(
CCB * pCCB )
{
if( pCCB->GetCodeGenPhase() == CGPHASE_UNMARSHALL )
{
return GetSizeResource();
}
else
{
return GetSizeIsExpr();
}
}
expr_node *
CG_SIZE_POINTER::PresentedSizeExpression(
CCB * pCCB )
{
if( pCCB->GetCodeGenPhase() == CGPHASE_UNMARSHALL )
{
return GetSizeResource();
}
else
{
return GetSizeIsExpr();
}
}
expr_node *
CG_LENGTH_POINTER::PresentedLengthExpression(
CCB * pCCB )
{
if( pCCB->GetCodeGenPhase() == CGPHASE_UNMARSHALL )
{
return GetLengthResource();
}
else
{
return GetLengthIsExpr();
}
}
expr_node *
CG_LENGTH_POINTER::PresentedFirstExpression(
CCB * pCCB )
{
if( pCCB->GetCodeGenPhase() == CGPHASE_UNMARSHALL )
{
return GetFirstResource();
}
else
{
return GetFirstIsExpr();
}
}
expr_node *
CG_SIZE_LENGTH_POINTER::PresentedSizeExpression(
CCB * pCCB )
{
if( pCCB->GetCodeGenPhase() == CGPHASE_UNMARSHALL )
{
return GetSizeResource();
}
else
{
return GetSizeIsExpr();
}
}
expr_node *
CG_SIZE_LENGTH_POINTER::PresentedLengthExpression(
CCB * pCCB )
{
if( pCCB->GetCodeGenPhase() == CGPHASE_UNMARSHALL )
{
return GetLengthResource();
}
else
{
return GetLengthIsExpr();
}
}
expr_node *
CG_SIZE_LENGTH_POINTER::PresentedFirstExpression(
CCB * pCCB )
{
if( pCCB->GetCodeGenPhase() == CGPHASE_UNMARSHALL )
{
return GetFirstResource();
}
else
{
return GetFirstIsExpr();
}
}
CG_STATUS
CG_IIDIS_INTERFACE_POINTER::S_GenInitOutLocals(
CCB * pCCB )
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Generate the init call for the locals.
Arguments:
pCCB - The ptr to code gen block.
Return Value:
Notes:
----------------------------------------------------------------------------*/
{
expr_node * pExpr;
if( !pCCB->IsRefAllocDone() )
{
pExpr = new expr_sizeof( GetType() );
Out_Alloc( pCCB, pCCB->GetSourceExpression(), 0, pExpr );
}
else
{
pExpr = MakeAddressExpressionNoMatterWhat( GetResource() );
Out_Assign( pCCB, pCCB->GetSourceExpression(), pExpr );
pExpr = pCCB->SetSourceExpression( GetResource() );
Out_Assign( pCCB, GetResource(), new expr_constant( 0L ) );
}
return CG_OK;
}
CG_STATUS
CG_INTERFACE_POINTER::S_GenInitOutLocals(
CCB * pCCB )
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Generate the init call for the locals.
Arguments:
pCCB - The ptr to code gen block.
Return Value:
Notes:
----------------------------------------------------------------------------*/
{
expr_node * pExpr;
if( !pCCB->IsRefAllocDone() )
{
pExpr = new expr_sizeof( GetType() );
Out_Alloc( pCCB, pCCB->GetSourceExpression(), 0, pExpr );
}
else
{
pExpr = MakeAddressExpressionNoMatterWhat( GetResource() );
Out_Assign( pCCB, pCCB->GetSourceExpression(), pExpr );
pExpr = pCCB->SetSourceExpression( GetResource() );
Out_Assign( pCCB, GetResource(), new expr_constant( 0L ) );
}
return CG_OK;
}