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.

359 lines
9.4 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1989-1999 Microsoft Corporation
  3. Module Name:
  4. walkctxt.cxx
  5. Abstract:
  6. typegraph walk context block routines
  7. Notes:
  8. Author:
  9. GregJen Oct-27-1993 Created.
  10. Notes:
  11. ----------------------------------------------------------------------------*/
  12. #pragma warning ( disable : 4514 4706 )
  13. /****************************************************************************
  14. * include files
  15. ***************************************************************************/
  16. #include "allnodes.hxx"
  17. #include "walkctxt.hxx"
  18. #include "cmdana.hxx"
  19. #include "semantic.hxx"
  20. #include "control.hxx"
  21. /****************************************************************************
  22. * local data
  23. ***************************************************************************/
  24. /****************************************************************************
  25. * externs
  26. ***************************************************************************/
  27. extern ATTR_SUMMARY FieldAttrs;
  28. extern CMD_ARG * pCommand;
  29. extern ccontrol * pCompiler;
  30. extern ATTR_SUMMARY RedundantsOk;
  31. /****************************************************************************
  32. * definitions
  33. ***************************************************************************/
  34. // Extract a single attribute from the attribute list (and remove from
  35. // summary).
  36. node_base_attr *
  37. ATTR_ITERATOR::GetAttribute( ATTR_T Attr )
  38. {
  39. return AllAttrs[ Attr ];
  40. }
  41. // Extract a single attribute from the attribute list (and remove from
  42. // summary).
  43. node_base_attr *
  44. ATTR_ITERATOR::ExtractAttribute( ATTR_T Attr )
  45. {
  46. node_base_attr * pResult = AllAttrs[ Attr ];
  47. if ( !pResult )
  48. {
  49. return pResult;
  50. }
  51. // if there were extras of a redundant attr, get the next one from the list
  52. if ( ( Attr <= REDUNDANT_ATTR_END ) && RedundantAttrExtras[ Attr ].NonNull() )
  53. {
  54. RedundantAttrExtras[ Attr ].GetCurrent( (void **)&AllAttrs[Attr] );
  55. RedundantAttrExtras[ Attr ].RemoveHead();
  56. }
  57. else // no more of this attribute
  58. {
  59. AllAttrs[Attr] = NULL;
  60. RESET_ATTR( Summary, Attr );
  61. }
  62. return pResult;
  63. }
  64. void
  65. ATTR_ITERATOR::ExtractFieldAttributes( FIELD_ATTR_INFO * FACtxt )
  66. {
  67. node_base_attr * pAttrNode;
  68. expr_node * pExpr;
  69. if ( pAttrNode = ExtractAttribute( ATTR_FIRST ) )
  70. {
  71. pExpr = pAttrNode->GetExpr();
  72. if ( pExpr )
  73. FACtxt->SetFirstIs( pExpr );
  74. }
  75. if ( pAttrNode = ExtractAttribute( ATTR_LAST ) )
  76. {
  77. pExpr = pAttrNode->GetExpr();
  78. if ( pExpr )
  79. FACtxt->SetLastIs( pExpr );
  80. }
  81. if ( pAttrNode = ExtractAttribute( ATTR_LENGTH ) )
  82. {
  83. pExpr = pAttrNode->GetExpr();
  84. if ( pExpr )
  85. FACtxt->SetLengthIs( pExpr );
  86. }
  87. if ( pAttrNode = ExtractAttribute( ATTR_MIN ) )
  88. {
  89. pExpr = pAttrNode->GetExpr();
  90. if ( pExpr )
  91. FACtxt->SetMinIs( pExpr );
  92. }
  93. if ( pAttrNode = ExtractAttribute( ATTR_MAX ) )
  94. {
  95. pExpr = pAttrNode->GetExpr();
  96. if ( pExpr )
  97. FACtxt->SetMaxIs( pExpr );
  98. }
  99. if ( pAttrNode = ExtractAttribute( ATTR_SIZE ) )
  100. {
  101. pExpr = pAttrNode->GetExpr();
  102. if ( pExpr )
  103. FACtxt->SetSizeIs( pExpr );
  104. }
  105. // pass iid_is and string attrs on to child
  106. if ( (FACtxt->Control & FA_CHILD_IS_ARRAY_OR_PTR) == 0 )
  107. {
  108. if ( pAttrNode = ExtractAttribute( ATTR_IID_IS ) )
  109. {
  110. FACtxt->SetIIDIs( pAttrNode->GetExpr() );
  111. }
  112. if ( pAttrNode = ExtractAttribute( ATTR_STRING ) )
  113. {
  114. FACtxt->SetString();
  115. }
  116. if ( pAttrNode = ExtractAttribute( ATTR_BSTRING ) )
  117. {
  118. FACtxt->SetBString();
  119. }
  120. }
  121. }
  122. // this routine searches up the context stack looking for a
  123. // matching node
  124. WALK_CTXT *
  125. WALK_CTXT::FindAncestorContext( NODE_T Kind )
  126. {
  127. WALK_CTXT * pCur = this;
  128. while ( pCur )
  129. {
  130. if ( (pCur->GetParent())->NodeKind() == Kind )
  131. return pCur;
  132. pCur = pCur->GetParentContext();
  133. }
  134. return NULL;
  135. }
  136. // this routine searches up the context stack looking for a
  137. // matching node
  138. WALK_CTXT *
  139. WALK_CTXT::FindRecursiveContext( node_skl * self )
  140. {
  141. WALK_CTXT * pCur = this;
  142. while ( pCur )
  143. {
  144. if ( pCur->GetParent() == self )
  145. return pCur;
  146. pCur = pCur->GetParentContext();
  147. }
  148. return NULL;
  149. }
  150. // this routine searches up the context stack looking for a
  151. // node other than a typedef
  152. WALK_CTXT *
  153. WALK_CTXT::FindNonDefAncestorContext( )
  154. {
  155. WALK_CTXT * pCur = this->GetParentContext();
  156. while ( pCur )
  157. {
  158. if ( (pCur->GetParent())->NodeKind() != NODE_DEF )
  159. return pCur;
  160. pCur = pCur->GetParentContext();
  161. }
  162. return NULL;
  163. }
  164. // for my context, find the appropriate pointer kind ( and extract it if needed )
  165. PTRTYPE
  166. WALK_CTXT::GetPtrKind( BOOL * pfExplicitPtrAttr )
  167. {
  168. PTRTYPE PtrKind = PTR_UNKNOWN;
  169. node_ptr_attr * pPtrAttr;
  170. node_interface * pIntf;
  171. BOOL fMsExt = pCommand->IsSwitchDefined( SWITCH_MS_EXT );
  172. WALK_CTXT * pImportantCtxt = ( fMsExt ) ? FindNonDefAncestorContext() :
  173. GetParentContext();
  174. BOOL fBelowParam = (pImportantCtxt->GetParent()->NodeKind())
  175. == NODE_PARAM;
  176. node_interface * pItsIntf = GetParent()->GetMyInterfaceNode();
  177. ////////////////////////////////////////////////////////////////////////
  178. // process pointer attributes
  179. if ( pfExplicitPtrAttr )
  180. *pfExplicitPtrAttr = FALSE;
  181. if ( FInSummary( ATTR_PTR_KIND ) )
  182. {
  183. pPtrAttr = (node_ptr_attr *) ExtractAttribute( ATTR_PTR_KIND );
  184. PtrKind = pPtrAttr->GetPtrKind();
  185. if ( pfExplicitPtrAttr &&
  186. ( PtrKind == PTR_REF || PtrKind == PTR_FULL ) )
  187. {
  188. *pfExplicitPtrAttr = TRUE;
  189. }
  190. }
  191. // top level pointer under param is ref ptr unless explicitly changed
  192. else if ( fBelowParam )
  193. {
  194. PtrKind = PTR_REF;
  195. }
  196. // pointer default on defining interface
  197. else if ( pItsIntf->FInSummary( ATTR_PTR_KIND ) )
  198. {
  199. pPtrAttr = (node_ptr_attr *) pItsIntf->GetAttribute( ATTR_PTR_KIND );
  200. PtrKind = pPtrAttr->GetPtrKind();
  201. }
  202. // pointer default on using interface
  203. else if ( (pIntf=GetInterfaceNode()) ->FInSummary( ATTR_PTR_KIND ) )
  204. {
  205. pPtrAttr = (node_ptr_attr *) pIntf->GetAttribute( ATTR_PTR_KIND );
  206. // semantics verifies that there is exactly one here...
  207. // ...and adds REF if needed
  208. PtrKind = pPtrAttr->GetPtrKind();
  209. }
  210. else // global default -- full for DCE, unique for MS_EXT
  211. {
  212. if ( fMsExt )
  213. {
  214. PtrKind = PTR_UNIQUE;
  215. }
  216. else
  217. {
  218. PtrKind = PTR_FULL;
  219. }
  220. }
  221. return PtrKind;
  222. }
  223. // get all the operation bits (MAYBE, IDEMPOTENT, BROADCAST, etc.
  224. unsigned short
  225. WALK_CTXT::GetOperationBits()
  226. {
  227. unsigned short Bits = 0;
  228. if ( ExtractAttribute( ATTR_MAYBE ))
  229. Bits |= OPERATION_MAYBE;
  230. if ( ExtractAttribute( ATTR_BROADCAST ))
  231. Bits |= OPERATION_BROADCAST;
  232. if ( ExtractAttribute( ATTR_IDEMPOTENT ))
  233. Bits |= OPERATION_IDEMPOTENT;
  234. if ( ExtractAttribute( ATTR_MESSAGE ))
  235. Bits |= OPERATION_MESSAGE;
  236. if ( ExtractAttribute( ATTR_INPUTSYNC ))
  237. Bits |= OPERATION_INPUT_SYNC;
  238. return Bits;
  239. }
  240. // add all the attributes to the attribute list; for duplicates, report the duplicate
  241. void
  242. WALK_CTXT::AddAttributes( named_node * pNode )
  243. {
  244. ATTRLIST MyAttrs;
  245. node_base_attr * pCurAttr;
  246. ATTR_T CurAttrKind;
  247. pNode->GetAttributeList( MyAttrs );
  248. pCurAttr = MyAttrs.GetFirst();
  249. while ( pCurAttr )
  250. {
  251. CurAttrKind = pCurAttr->GetAttrID();
  252. if ( ( pDownAttrList->FInSummary( CurAttrKind ) )
  253. && ( !IS_ATTR( RedundantsOk , CurAttrKind ) ) )
  254. {
  255. ProcessDuplicates( pCurAttr );
  256. }
  257. else
  258. pDownAttrList->Add( pCurAttr );
  259. pCurAttr = pCurAttr->GetNext();
  260. }
  261. }
  262. void
  263. WALK_CTXT::ProcessDuplicates( node_base_attr * pAttr )
  264. {
  265. if ( pCompiler->GetPassNumber() == SEMANTIC_PASS )
  266. {
  267. STATUS_T errnum = ((pAttr->GetAttrID() > NO_DUPLICATES_END)? REDUNDANT_ATTRIBUTE : DUPLICATE_ATTR);
  268. // it is safe to use SemError on us, since it only uses parts of OUR
  269. // context that are ready, even though this is called during the constructor
  270. if ( pAttr->IsAcfAttr() )
  271. {
  272. AcfError( (acf_attr *)pAttr,
  273. NULL,
  274. *((SEM_ANALYSIS_CTXT *)this),
  275. errnum,
  276. NULL);
  277. }
  278. else
  279. {
  280. char * pAttrName = pAttr->GetNodeNameString();
  281. SemError( NULL, *((SEM_ANALYSIS_CTXT *)this), errnum ,pAttrName);
  282. }
  283. }
  284. }