/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 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; }