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

552 lines
13 KiB
C++

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 1989-1999 Microsoft Corporation
Module Name:
arrayana.cxx
Abstract:
Implementation of array marshall and unmarshall analysis.
Notes:
History:
Nov-13-1993 VibhasC Created.
----------------------------------------------------------------------------*/
/****************************************************************************
* include files
***************************************************************************/
#include "allana.hxx"
#pragma hdrstop
/****************************************************************************
* local definitions
***************************************************************************/
/****************************************************************************
* local data
***************************************************************************/
/****************************************************************************
* externs
***************************************************************************/
/****************************************************************************/
CG_STATUS
CG_FIXED_ARRAY::MarshallAnalysis(
ANALYSIS_INFO * pAna )
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Perform marshall analysis for a fixed array.
Arguments:
pAna = The analysis block.
Return Value:
CG_OK
Notes:
----------------------------------------------------------------------------*/
{
CG_NDR * pBasicCGClass = GetBasicCGClass();
ID_CG ID = pBasicCGClass->GetCGID();
BOOL fIsArrayOfUnion = FALSE;
if((ID == ID_CG_UNION) || (ID == ID_CG_ENCAP_STRUCT))
fIsArrayOfUnion = TRUE;
// Temp fix for varying arrays.
if( IsVarying() || fIsArrayOfUnion )
{
return CG_OK;
}
pBasicCGClass->MarshallAnalysis( pAna );
return CG_OK;
}
CG_STATUS
CG_FIXED_ARRAY::FollowerMarshallAnalysis(
ANALYSIS_INFO * pAna )
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Perform Follower (embedded pointer) marshall analysis on the fixed array
Arguments:
pAna - The analyser block.
Return Value:
CG_OK
Notes:
// For buffer size calculation, we trick the child cg into beleieving it
// is the only element being marshalled, so that it gives us the real
// size per element. Then based on the alignment property before and
// after the analysis, we make the sizing decisions.
----------------------------------------------------------------------------*/
{
CG_NDR * pBasicCGClass = GetBasicCGClass();
pBasicCGClass->FollowerMarshallAnalysis( pAna );
return CG_OK;
}
CG_STATUS
CG_ARRAY::DimByDimMarshallAnalysis(
ANALYSIS_INFO * pAna )
{
pAna->PushEmbeddingLevel();
GetBasicCGClass()->MarshallAnalysis( pAna );
pAna->PopEmbeddingLevel();
return CG_OK;
}
CG_STATUS
CG_ARRAY::DimByDimUnMarshallAnalysis(
ANALYSIS_INFO* )
{
return CG_OK;
}
CG_STATUS
CG_ARRAY::S_OutLocalAnalysis(
ANALYSIS_INFO * pAna )
{
if( IsFixedArray() )
{
if( pAna->GetCurrentSide() != C_SIDE )
{
PNAME pName = pAna->GenTempResourceName( "A" );
node_skl * pType= MakeIDNode( pName, GetType() );
SetResource( pAna->AddLocalResource( pName, pType ));
}
SetAllocatedOnStack( 1 );
}
return CG_OK;
}
CG_STATUS
CG_ARRAY::MarshallAnalysis(
ANALYSIS_INFO * pAna )
{
ID_CG MyID = GetCGID();
short NoOfDimensions = short( GetDimensions() - 1 );
int i;
//
// Depending upon the id, perform analysis. Basically declare the
// needed local variables.
//
// If it has embedded pointers or if block copy is not possible, declare
// an index variable for each dimension.
if( !IsBlockCopyPossible() )
{
CG_ARRAY * pThis;
for( i = 0, pThis = this;
i <= NoOfDimensions;
i++, pThis = (CG_ARRAY *)pThis->GetChild() )
{
if( !pThis->GetIndexResource() )
{
node_skl * pType;
PNAME pResName = pAna->GenTempResourceName( "I" );
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_UNDEF, TYPE_INT );
pType = MakeIDNode( pResName, pType );
pThis->SetIndexResource( pAna->AddTransientResource( pResName, pType ));
}
else
pAna->AddTransientResource( GetIndexResource()->GetResourceName(),
GetIndexResource()->GetType()
);
}
DimByDimMarshallAnalysis( pAna );
}
if( IsFixedArray() && !IsArrayOfRefPointers() )
{
CG_FIXED_ARRAY * pThis = (CG_FIXED_ARRAY *)this;
unsigned long TotalSize = pThis->GetNumOfElements();
for( i = 0;
i < NoOfDimensions;
i++, pThis = (CG_FIXED_ARRAY *)pThis->GetChild() )
{
TotalSize = TotalSize * pThis->GetNumOfElements();
}
TotalSize = TotalSize * pThis->GetBasicCGClass()->GetWireSize();
}
if( (MyID == ID_CG_CONF_ARRAY) || (MyID == ID_CG_CONF_VAR_ARRAY))
{
CG_ARRAY * pThis;
for( i = 0, pThis = this;
i <= NoOfDimensions;
i++, pThis = (CG_ARRAY *)pThis->GetChild() )
{
if( !pThis->GetSizeResource() )
{
node_skl * pType;
PNAME pResName = pAna->GenTempResourceName( "S" );
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
pType = MakeIDNode( pResName, pType );
pThis->SetSizeResource( pAna->AddTransientResource( pResName, pType ));
}
else
pAna->AddTransientResource(GetSizeResource()->GetResourceName(),
GetSizeResource()->GetType()
);
}
}
//
// If this has any form of variance, generate locals for variance stuff.
//
if( (MyID == ID_CG_VAR_ARRAY ) || (MyID == ID_CG_CONF_VAR_ARRAY ))
{
CG_ARRAY * pThis;
for( i = 0, pThis = this;
i <= NoOfDimensions;
i++, pThis = (CG_ARRAY *)pThis->GetChild() )
{
if( !pThis->GetFirstResource() )
{
node_skl * pType;
PNAME pResName = pAna->GenTempResourceName( "F" );
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_UNDEF, TYPE_INT );
pType = MakeIDNode( pResName, pType );
pThis->SetFirstResource(pAna->AddTransientResource(pResName, pType));
}
else
pAna->AddTransientResource(GetFirstResource()->GetResourceName(),
GetFirstResource()->GetType()
);
}
for( i = 0, pThis = this;
i <= NoOfDimensions;
i++, pThis = (CG_ARRAY *)pThis->GetChild() )
{
if( !pThis->GetLengthResource() )
{
node_skl * pType;
PNAME pResName = pAna->GenTempResourceName( "L" );
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
pType = MakeIDNode( pResName, pType );
pThis->SetLengthResource( pAna->AddTransientResource( pResName, pType ));
}
else
pAna->AddTransientResource(GetLengthResource()->GetResourceName(),
GetLengthResource()->GetType()
);
}
}
if( pAna->IsPointeeDeferred() && HasPointer() )
{
pAna->SetHasAtLeastOneDeferredPointee();
}
return CG_OK;
}
CG_STATUS
CG_ARRAY::UnMarshallAnalysis(
ANALYSIS_INFO * pAna )
{
ID_CG MyID = GetCGID();
short NoOfDimensions = short( GetDimensions() - 1 );
int i;
//
// Depending upon the id, perform analysis. Basically declare the
// needed local variables.
//
// If it has embedded pointers or if block copy is not possible, declare
// an index variable for each dimension.
if( HasPointer() || !IsBlockCopyPossible() )
{
CG_ARRAY * pThis;
for( i = 0, pThis = this;
i <= NoOfDimensions;
i++, pThis = (CG_ARRAY *)pThis->GetChild() )
{
if( !pThis->GetIndexResource() )
{
node_skl * pType;
PNAME pResName= pAna->GenTempResourceName( "I" );
GetBaseTypeNode(&pType,SIGN_UNSIGNED, SIZE_UNDEF, TYPE_INT );
pType = MakeIDNode( pResName, pType );
pThis->SetIndexResource( pAna->AddTransientResource( pResName, pType ));
}
else
pAna->AddTransientResource( pThis->GetIndexResource()->GetResourceName(),
pThis->GetIndexResource()->GetType()
);
}
}
if( (MyID == ID_CG_CONF_ARRAY) || (MyID == ID_CG_CONF_VAR_ARRAY))
{
CG_ARRAY * pThis;
for( i = 0, pThis = this;
i <= NoOfDimensions;
i++, pThis = (CG_ARRAY *)pThis->GetChild() )
{
if( !pThis->GetSizeResource() )
{
node_skl * pType;
PNAME pResName = pAna->GenTempResourceName( "S" );
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
pType = MakeIDNode( pResName, pType );
pThis->SetSizeResource( pAna->AddTransientResource( pResName, pType ));
}
else
pAna->AddTransientResource(pThis->GetSizeResource()->GetResourceName(),
pThis->GetSizeResource()->GetType()
);
}
}
//
// If this has any form of variance, generate locals for variance stuff.
//
if( (MyID == ID_CG_VAR_ARRAY ) || (MyID == ID_CG_CONF_VAR_ARRAY ))
{
CG_ARRAY * pThis;
for( i = 0, pThis = this;
i <= NoOfDimensions;
i++, pThis = (CG_ARRAY *)pThis->GetChild() )
{
if( !pThis->GetFirstResource() )
{
node_skl * pType;
PNAME pResName = pAna->GenTempResourceName( "F" );
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_UNDEF, TYPE_INT );
pType = MakeIDNode( pResName, pType );
pThis->SetFirstResource(pAna->AddTransientResource(pResName, pType));
}
else
pAna->AddTransientResource(pThis->GetFirstResource()->GetResourceName(),
pThis->GetFirstResource()->GetType()
);
}
for( i = 0, pThis = this;
i <= NoOfDimensions;
i++, pThis = (CG_ARRAY *)pThis->GetChild() )
{
if( !pThis->GetLengthResource() )
{
node_skl * pType;
PNAME pResName = pAna->GenTempResourceName( "L" );
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
pType = MakeIDNode( pResName, pType );
pThis->SetLengthResource( pAna->AddTransientResource( pResName, pType ));
}
else
pAna->AddTransientResource(pThis->GetLengthResource()->GetResourceName(),
pThis->GetLengthResource()->GetType()
);
}
}
if( HasPointer() )
{
pAna->SetHasAtLeastOneDeferredPointee();
}
return CG_OK;
}
CG_STATUS
CG_ARRAY::FollowerMarshallAnalysis(
ANALYSIS_INFO * pAna )
{
pAna;
return CG_OK;
}
CG_STATUS
CG_ARRAY::FollowerUnMarshallAnalysis(
ANALYSIS_INFO * pAna )
{
node_skl * pType = GetBasicCGClass()->GetType();
PNAME pName;
// Declare a local variable for a member by member unmarshall of the
// array elements.
pName = pAna->GenTempResourceName("PE");
pType = MakePtrIDNode( pName, pType );
SetPtrResource( pAna->AddTransientResource( pName, pType ) );
GetBasicCGClass()->FollowerUnMarshallAnalysis( pAna );
return CG_OK;
}
CG_STATUS
CG_ARRAY::RefCheckAnalysis(
ANALYSIS_INFO * pAna )
{
int i;
int NoOfDimensions = GetDimensions();
if( IsArrayOfRefPointers() )
{
// Allocate an index resource per dimension.
CG_ARRAY * pThis;
for( i = 0, pThis = this;
i < NoOfDimensions;
i++, pThis = (CG_ARRAY *)pThis->GetChild() )
{
if( !pThis->GetIndexResource() )
{
node_skl * pType;
PNAME pResName = pAna->GenTempResourceName( "I" );
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_UNDEF, TYPE_INT );
pType = MakeIDNode( pResName, pType );
pThis->SetIndexResource( pAna->AddLocalResource( pResName, pType ));
}
else
pAna->AddLocalResource(
GetIndexResource()->GetResourceName(),
GetIndexResource()->GetType()
);
}
}
return CG_OK;
}
CG_STATUS
CG_ARRAY::InLocalAnalysis(
ANALYSIS_INFO * pAna )
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Perform Allocation of local resources on server side stub for an
array of ref pointers.
Arguments:
Return Value:
CG_OK
Notes:
----------------------------------------------------------------------------*/
{
if( IsArrayOfRefPointers() && IsFixedArray() )
{
if( !GetInLocalResource() )
{
node_skl * pType = GetType();
PNAME pResName = pAna->GenTempResourceName( "A" );
pType = MakeIDNode( pResName, pType );
SetInLocalResource(pAna->AddLocalResource(pResName,pType));
}
else
{
pAna->AddLocalResource(
GetInLocalResource()->GetResourceName(),
GetInLocalResource()->GetType()
);
}
}
return CG_OK;
}
/*****************************************************************************
CG_STRING_ARRAY methods.
*****************************************************************************/
CG_STATUS
CG_STRING_ARRAY::MarshallAnalysis(
ANALYSIS_INFO * pAna )
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Perform marshall analysis for a fixed string array.
Arguments:
pAna = The analysis block.
Return Value:
CG_OK
Notes:
For now this will work only for a single dimensional array on which
[string] is applied.
----------------------------------------------------------------------------*/
{
CG_NDR * pBasicCGClass = GetBasicCGClass();
pBasicCGClass->MarshallAnalysis( pAna );
return CG_OK;
}
/*****************************************************************************
CG_VARYING_ARRAY methods.
*****************************************************************************/
CG_STATUS
CG_VARYING_ARRAY::MarshallAnalysis(
ANALYSIS_INFO * pAna )
{
pAna;
return CG_OK;
}