500 lines
11 KiB
C++
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;
|
|
}
|
|
|
|
|