Source code of Windows XP (NT5)
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.
|
|
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 1989-1999 Microsoft Corporation
Module Name:
walkctxt.cxx
Abstract:
typegraph walk context block routines
Notes:
Author:
GregJen Oct-27-1993 Created.
Notes:
----------------------------------------------------------------------------*/
#pragma warning ( disable : 4514 4706 )
/****************************************************************************
* include files ***************************************************************************/
#include "allnodes.hxx"
#include "walkctxt.hxx"
#include "cmdana.hxx"
#include "semantic.hxx"
#include "control.hxx"
/****************************************************************************
* local data ***************************************************************************/
/****************************************************************************
* externs ***************************************************************************/
extern ATTR_SUMMARY FieldAttrs; extern CMD_ARG * pCommand; extern ccontrol * pCompiler; extern ATTR_SUMMARY RedundantsOk;
/****************************************************************************
* definitions ***************************************************************************/
// Extract a single attribute from the attribute list (and remove from
// summary).
node_base_attr * ATTR_ITERATOR::GetAttribute( ATTR_T Attr ) { return AllAttrs[ Attr ]; }
// Extract a single attribute from the attribute list (and remove from
// summary).
node_base_attr * ATTR_ITERATOR::ExtractAttribute( ATTR_T Attr ) { node_base_attr * pResult = AllAttrs[ Attr ];
if ( !pResult ) { return pResult; }
// if there were extras of a redundant attr, get the next one from the list
if ( ( Attr <= REDUNDANT_ATTR_END ) && RedundantAttrExtras[ Attr ].NonNull() ) { RedundantAttrExtras[ Attr ].GetCurrent( (void **)&AllAttrs[Attr] ); RedundantAttrExtras[ Attr ].RemoveHead(); } else // no more of this attribute
{ AllAttrs[Attr] = NULL; RESET_ATTR( Summary, Attr ); }
return pResult; }
void ATTR_ITERATOR::ExtractFieldAttributes( FIELD_ATTR_INFO * FACtxt ) { node_base_attr * pAttrNode; expr_node * pExpr;
if ( pAttrNode = ExtractAttribute( ATTR_FIRST ) ) { pExpr = pAttrNode->GetExpr(); if ( pExpr ) FACtxt->SetFirstIs( pExpr ); }
if ( pAttrNode = ExtractAttribute( ATTR_LAST ) ) { pExpr = pAttrNode->GetExpr(); if ( pExpr ) FACtxt->SetLastIs( pExpr ); }
if ( pAttrNode = ExtractAttribute( ATTR_LENGTH ) ) { pExpr = pAttrNode->GetExpr(); if ( pExpr ) FACtxt->SetLengthIs( pExpr ); }
if ( pAttrNode = ExtractAttribute( ATTR_MIN ) ) { pExpr = pAttrNode->GetExpr(); if ( pExpr ) FACtxt->SetMinIs( pExpr ); }
if ( pAttrNode = ExtractAttribute( ATTR_MAX ) ) { pExpr = pAttrNode->GetExpr(); if ( pExpr ) FACtxt->SetMaxIs( pExpr ); }
if ( pAttrNode = ExtractAttribute( ATTR_SIZE ) ) { pExpr = pAttrNode->GetExpr(); if ( pExpr ) FACtxt->SetSizeIs( pExpr ); }
// pass iid_is and string attrs on to child
if ( (FACtxt->Control & FA_CHILD_IS_ARRAY_OR_PTR) == 0 ) {
if ( pAttrNode = ExtractAttribute( ATTR_IID_IS ) ) { FACtxt->SetIIDIs( pAttrNode->GetExpr() ); }
if ( pAttrNode = ExtractAttribute( ATTR_STRING ) ) { FACtxt->SetString(); }
if ( pAttrNode = ExtractAttribute( ATTR_BSTRING ) ) { FACtxt->SetBString(); }
} }
// this routine searches up the context stack looking for a
// matching node
WALK_CTXT * WALK_CTXT::FindAncestorContext( NODE_T Kind ) { WALK_CTXT * pCur = this;
while ( pCur ) { if ( (pCur->GetParent())->NodeKind() == Kind ) return pCur; pCur = pCur->GetParentContext(); }
return NULL; }
// this routine searches up the context stack looking for a
// matching node
WALK_CTXT * WALK_CTXT::FindRecursiveContext( node_skl * self ) { WALK_CTXT * pCur = this;
while ( pCur ) { if ( pCur->GetParent() == self ) return pCur; pCur = pCur->GetParentContext(); }
return NULL; }
// this routine searches up the context stack looking for a
// node other than a typedef
WALK_CTXT * WALK_CTXT::FindNonDefAncestorContext( ) { WALK_CTXT * pCur = this->GetParentContext();
while ( pCur ) { if ( (pCur->GetParent())->NodeKind() != NODE_DEF ) return pCur; pCur = pCur->GetParentContext(); }
return NULL; }
// for my context, find the appropriate pointer kind ( and extract it if needed )
PTRTYPE WALK_CTXT::GetPtrKind( BOOL * pfExplicitPtrAttr ) { PTRTYPE PtrKind = PTR_UNKNOWN; node_ptr_attr * pPtrAttr; node_interface * pIntf; BOOL fMsExt = pCommand->IsSwitchDefined( SWITCH_MS_EXT ); WALK_CTXT * pImportantCtxt = ( fMsExt ) ? FindNonDefAncestorContext() : GetParentContext(); BOOL fBelowParam = (pImportantCtxt->GetParent()->NodeKind()) == NODE_PARAM; node_interface * pItsIntf = GetParent()->GetMyInterfaceNode();
////////////////////////////////////////////////////////////////////////
// process pointer attributes
if ( pfExplicitPtrAttr ) *pfExplicitPtrAttr = FALSE;
if ( FInSummary( ATTR_PTR_KIND ) ) { pPtrAttr = (node_ptr_attr *) ExtractAttribute( ATTR_PTR_KIND );
PtrKind = pPtrAttr->GetPtrKind();
if ( pfExplicitPtrAttr && ( PtrKind == PTR_REF || PtrKind == PTR_FULL ) ) { *pfExplicitPtrAttr = TRUE; } } // top level pointer under param is ref ptr unless explicitly changed
else if ( fBelowParam ) { PtrKind = PTR_REF; } // pointer default on defining interface
else if ( pItsIntf->FInSummary( ATTR_PTR_KIND ) ) { pPtrAttr = (node_ptr_attr *) pItsIntf->GetAttribute( ATTR_PTR_KIND );
PtrKind = pPtrAttr->GetPtrKind(); } // pointer default on using interface
else if ( (pIntf=GetInterfaceNode()) ->FInSummary( ATTR_PTR_KIND ) ) { pPtrAttr = (node_ptr_attr *) pIntf->GetAttribute( ATTR_PTR_KIND );
// semantics verifies that there is exactly one here...
// ...and adds REF if needed
PtrKind = pPtrAttr->GetPtrKind(); } else // global default -- full for DCE, unique for MS_EXT
{ if ( fMsExt ) { PtrKind = PTR_UNIQUE; } else { PtrKind = PTR_FULL; } }
return PtrKind;
}
// get all the operation bits (MAYBE, IDEMPOTENT, BROADCAST, etc.
unsigned short WALK_CTXT::GetOperationBits() { unsigned short Bits = 0;
if ( ExtractAttribute( ATTR_MAYBE )) Bits |= OPERATION_MAYBE;
if ( ExtractAttribute( ATTR_BROADCAST )) Bits |= OPERATION_BROADCAST;
if ( ExtractAttribute( ATTR_IDEMPOTENT )) Bits |= OPERATION_IDEMPOTENT;
if ( ExtractAttribute( ATTR_MESSAGE )) Bits |= OPERATION_MESSAGE;
if ( ExtractAttribute( ATTR_INPUTSYNC )) Bits |= OPERATION_INPUT_SYNC;
return Bits; }
// add all the attributes to the attribute list; for duplicates, report the duplicate
void WALK_CTXT::AddAttributes( named_node * pNode ) { ATTRLIST MyAttrs; node_base_attr * pCurAttr; ATTR_T CurAttrKind;
pNode->GetAttributeList( MyAttrs );
pCurAttr = MyAttrs.GetFirst(); while ( pCurAttr ) { CurAttrKind = pCurAttr->GetAttrID();
if ( ( pDownAttrList->FInSummary( CurAttrKind ) ) && ( !IS_ATTR( RedundantsOk , CurAttrKind ) ) ) { ProcessDuplicates( pCurAttr ); } else pDownAttrList->Add( pCurAttr );
pCurAttr = pCurAttr->GetNext(); } }
void WALK_CTXT::ProcessDuplicates( node_base_attr * pAttr ) { if ( pCompiler->GetPassNumber() == SEMANTIC_PASS ) { STATUS_T errnum = ((pAttr->GetAttrID() > NO_DUPLICATES_END)? REDUNDANT_ATTRIBUTE : DUPLICATE_ATTR);
// it is safe to use SemError on us, since it only uses parts of OUR
// context that are ready, even though this is called during the constructor
if ( pAttr->IsAcfAttr() ) { AcfError( (acf_attr *)pAttr, NULL, *((SEM_ANALYSIS_CTXT *)this), errnum, NULL); } else { char * pAttrName = pAttr->GetNodeNameString(); SemError( NULL, *((SEM_ANALYSIS_CTXT *)this), errnum ,pAttrName); } } }
|