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.

903 lines
21 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1989-1999 Microsoft Corporation
  3. Module Name:
  4. procana.cxx
  5. Abstract:
  6. This file provides analysis routines for a procedure code generation
  7. class.
  8. Notes:
  9. History:
  10. Aug-31-1993 VibhasC Created.
  11. ----------------------------------------------------------------------------*/
  12. /****************************************************************************
  13. * include files
  14. ***************************************************************************/
  15. #include "allana.hxx"
  16. #pragma hdrstop
  17. #pragma warning ( disable : 4701 )
  18. /****************************************************************************
  19. Implementation of the proc code generator class.
  20. ****************************************************************************/
  21. CG_STATUS
  22. CG_PROC::C_BindingAnalysis(
  23. ANALYSIS_INFO * pAna )
  24. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  25. Routine Description:
  26. Perform the binding analysis for the client side.
  27. Arguments:
  28. Return Value:
  29. Notes:
  30. If it is an auto handle procedure, make sure the global auto handle is
  31. registered as a global resource.
  32. ----------------------------------------------------------------------------*/
  33. {
  34. node_id * pID;
  35. if( IsAutoHandle() )
  36. {
  37. pAna->AddStandardResource( ST_RES_AUTO_BH_VARIABLE );
  38. }
  39. else
  40. {
  41. SetBindingResource( pAna->AddStandardResource( ST_RES_BH_VARIABLE ) );
  42. // Initialize the binding resource to 0, so it gets printed out.
  43. pID = (node_id *)GetBindingResource()->GetType();
  44. pID->SetExpr( new expr_constant( 0L ) );
  45. }
  46. return CG_OK;
  47. }
  48. CG_STATUS
  49. CG_PROC::MarshallAnalysis(
  50. ANALYSIS_INFO * pAna )
  51. {
  52. ITERATOR I;
  53. CG_PARAM * pCG = 0;
  54. CG_PARAM * pS;
  55. CG_RETURN * pRT;
  56. SIDE Side = pAna->GetCurrentSide();
  57. expr_node * pSE = 0;
  58. BOOL fReturnNeedsMarshall = FALSE;
  59. if( Side == C_SIDE )
  60. GetInParamList( I );
  61. else
  62. GetOutParamList( I );
  63. pRT = GetReturnType();
  64. if ( Side == S_SIDE && pRT != 0 )
  65. fReturnNeedsMarshall = TRUE;
  66. if( ITERATOR_GETCOUNT( I ) )
  67. {
  68. ITERATOR_INIT( I );
  69. while( ITERATOR_GETNEXT( I, pCG ) )
  70. {
  71. // The "invisible" fault or comm status param doesn't marshal.
  72. pS = (CG_PARAM *)ITERATOR_PEEKTHIS( I );
  73. if ( pCG->IsExtraStatusParam() )
  74. continue;
  75. pCG->MarshallAnalysis( pAna );
  76. // Add to the sizing expression.
  77. if( pSE )
  78. pSE = new expr_b_arithmetic( OP_PLUS,
  79. pSE,
  80. pCG->GetSizeExpression()
  81. );
  82. else
  83. pSE = pCG->GetSizeExpression();
  84. }
  85. }
  86. if(fReturnNeedsMarshall)
  87. {
  88. pRT->MarshallAnalysis( pAna );
  89. if( pSE )
  90. pSE = new expr_b_arithmetic( OP_PLUS,
  91. pSE,
  92. pRT->GetSizeExpression()
  93. );
  94. else
  95. pSE = pRT->GetSizeExpression();
  96. }
  97. if( pSE )
  98. SetSizeExpression( pSE );
  99. else
  100. SetSizeExpression( new expr_constant( 0L,VALUE_TYPE_NUMERIC_U ));
  101. if ( HasExtraStatusParam() )
  102. {
  103. GetMembers(I);
  104. while ( ITERATOR_GETNEXT( I, pCG ) )
  105. if ( pCG->IsExtraStatusParam() )
  106. break;
  107. node_skl *pType = pCG->GetType();
  108. pCG->SetResource( new RESOURCE( pType->GetSymName(), pType ) );
  109. }
  110. return CG_OK;
  111. }
  112. CG_STATUS
  113. CG_PROC::UnMarshallAnalysis(
  114. ANALYSIS_INFO * pAna )
  115. {
  116. ITERATOR I;
  117. CG_PARAM * pCG = 0;
  118. CG_PARAM * pS;
  119. CG_RETURN * pRT = 0;
  120. SIDE Side = pAna->GetCurrentSide();
  121. BOOL fReturnNeedsUnMarshall = FALSE;
  122. if( Side == C_SIDE )
  123. GetOutParamList( I );
  124. else
  125. GetInParamList( I );
  126. if( (Side == C_SIDE ) && (pRT = GetReturnType() ) != 0 )
  127. fReturnNeedsUnMarshall = TRUE;
  128. if( ITERATOR_GETCOUNT(I) )
  129. {
  130. while( ITERATOR_GETNEXT( I, pCG ) )
  131. {
  132. // The "invisible" fault/comm status param doesn't unmarshal.
  133. pS = (CG_PARAM *)ITERATOR_PEEKTHIS( I );
  134. if ( pCG->IsExtraStatusParam() )
  135. continue;
  136. pCG->UnMarshallAnalysis( pAna );
  137. }
  138. }
  139. if( fReturnNeedsUnMarshall )
  140. {
  141. pRT->UnMarshallAnalysis( pAna );
  142. }
  143. return CG_OK;
  144. }
  145. CG_STATUS
  146. CG_PROC::S_OutLocalAnalysis(
  147. ANALYSIS_INFO * pAna )
  148. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  149. Routine Description:
  150. Perform analysis for all params which may be allocated as locals for
  151. the server side stubs.
  152. Arguments:
  153. pAna - The analysis block.
  154. Return Value:
  155. CG_OK if all is well,
  156. error otherwise.
  157. Notes:
  158. ----------------------------------------------------------------------------*/
  159. {
  160. ITERATOR I;
  161. CG_PARAM * pParam = 0;
  162. GetOutParamList( I );
  163. while( ITERATOR_GETNEXT( I, pParam ) )
  164. {
  165. pParam->S_OutLocalAnalysis( pAna );
  166. }
  167. return CG_OK;
  168. }
  169. void
  170. CG_PROC::RpcSsPackageAnalysis(
  171. ANALYSIS_INFO * pAna )
  172. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  173. Routine Description:
  174. Perform analysis for the need to invoke RpcSsm package at server.
  175. Arguments:
  176. pAna - The analysis block.
  177. Return Value:
  178. Notes:
  179. Note that we perform both sides analysis at once as the format string
  180. is generated usually at the client pass.
  181. ----------------------------------------------------------------------------*/
  182. {
  183. //
  184. // In ms_ext mode:
  185. // only if Enable allocate is specified
  186. // In osf mode:
  187. // if( RpcSS is recommended by analysis || enable allocate specified )
  188. //
  189. SetMustInvokeRpcSSAllocate( 0 );
  190. if ( IsRpcSSSpecified() )
  191. SetMustInvokeRpcSSAllocate( 1 );
  192. if ( MustInvokeRpcSSAllocate() || pAna->GetMode() != 0 )
  193. return;
  194. // We analyze parameters in osf to boost performance by skipping
  195. // unnecessary enable and disable operations.
  196. //
  197. ITERATOR ParamList;
  198. CG_PARAM * pParam = 0;
  199. GetMembers( ParamList );
  200. if( ITERATOR_GETCOUNT( ParamList ) )
  201. {
  202. ITERATOR_INIT( ParamList );
  203. while( ITERATOR_GETNEXT( ParamList, pParam ) )
  204. {
  205. pParam->RpcSsPackageAnalysis( pAna );
  206. }
  207. }
  208. CG_RETURN * pReturn = GetReturnType();
  209. if ( pReturn )
  210. {
  211. if ( (pAna->GetOptimOption() & OPTIMIZE_INTERPRETER) ||
  212. (pReturn->GetChild() &&
  213. ( ((CG_NDR *)pReturn->GetChild())->IsPointer() ||
  214. ((CG_NDR *)pReturn->GetChild())->HasPointer() ||
  215. ((CG_NDR *)pReturn->GetChild())->GetCGID() == ID_CG_ENCAP_STRUCT ) )
  216. )
  217. {
  218. // We could do a better job for Oi2 if we watched its stack.
  219. // Encapsulated union is there as it was a hassle to make it
  220. // know about its pointers.
  221. pAna->SetRpcSSAllocateRecommended( 1 );
  222. }
  223. }
  224. if ( pAna->IsRpcSSAllocateRecommended() )
  225. SetMustInvokeRpcSSAllocate( 1 );
  226. }
  227. CG_STATUS
  228. CG_PROC::RefCheckAnalysis(
  229. ANALYSIS_INFO * pAna )
  230. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  231. Routine Description:
  232. Perform ref pointer check analysis.
  233. Arguments:
  234. pAna - The analysis info block.
  235. Return Value:
  236. CG_OK
  237. Notes:
  238. ----------------------------------------------------------------------------*/
  239. {
  240. ITERATOR I;
  241. CG_PARAM * pCG = 0;
  242. CG_RETURN * pRT = 0;
  243. SIDE Side = pAna->GetCurrentSide();
  244. BOOL fReturnNeedsMarshall = FALSE;
  245. // generate ref check resources for both in and out params.
  246. GetMembers( I );
  247. if( (Side == S_SIDE ) && (pRT = GetReturnType() ) != 0 )
  248. fReturnNeedsMarshall = TRUE;
  249. if( ITERATOR_GETCOUNT( I ) )
  250. {
  251. ITERATOR_INIT( I );
  252. while( ITERATOR_GETNEXT( I, pCG ) )
  253. {
  254. pCG->RefCheckAnalysis( pAna );
  255. }
  256. }
  257. if(fReturnNeedsMarshall)
  258. {
  259. pRT->RefCheckAnalysis( pAna );
  260. }
  261. return CG_OK;
  262. }
  263. CG_STATUS
  264. CG_PROC::InLocalAnalysis(
  265. ANALYSIS_INFO * pAna )
  266. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  267. Routine Description:
  268. Perform analysis for [in] params allocated as locals on server.
  269. Arguments:
  270. pAna - The analysis info block.
  271. Return Value:
  272. CG_OK
  273. Notes:
  274. ----------------------------------------------------------------------------*/
  275. {
  276. ITERATOR I;
  277. CG_PARAM * pCG = 0;
  278. GetInParamList( I );
  279. if( ITERATOR_GETCOUNT( I ) )
  280. {
  281. ITERATOR_INIT( I );
  282. while( ITERATOR_GETNEXT( I, pCG ) )
  283. {
  284. pCG->InLocalAnalysis( pAna );
  285. }
  286. }
  287. return CG_OK;
  288. }
  289. /****************************************************************************
  290. Implementation of the parameter code generator class.
  291. ****************************************************************************/
  292. CG_STATUS
  293. CG_PARAM::MarshallAnalysis(
  294. ANALYSIS_INFO * pAna )
  295. {
  296. CG_STATUS Status;
  297. //
  298. // Initialize the analysis block and the parameter for the current side
  299. // and analysis phase.
  300. //
  301. InitParamMarshallAnalysis( pAna );
  302. // Send the message to the lower cg nodes.
  303. Status = ((CG_NDR *)GetChild())->MarshallAnalysis( pAna );
  304. if( pAna->HasAtLeastOneDeferredPointee() )
  305. {
  306. pAna->ResetDeferPointee();
  307. ((CG_NDR *)GetChild())->FollowerMarshallAnalysis( pAna );
  308. }
  309. ConsolidateParamMarshallAnalysis( pAna );
  310. // The analysis block will now have properties which are a combo of the
  311. // properties before this param and the properties of this param.
  312. return CG_OK;
  313. }
  314. CG_STATUS
  315. CG_PARAM::UnMarshallAnalysis(
  316. ANALYSIS_INFO * pAna )
  317. {
  318. InitParamUnMarshallAnalysis( pAna );
  319. // Send the message to the child to perform the same analysis for us
  320. // and then consolidate the results on return.
  321. ((CG_NDR *)GetChild())->UnMarshallAnalysis( pAna );
  322. if( pAna->HasAtLeastOneDeferredPointee() )
  323. {
  324. pAna->ResetDeferPointee();
  325. ((CG_NDR *)GetChild())->FollowerUnMarshallAnalysis( pAna );
  326. }
  327. // Consolidate the results of analysis from the lower nodes.
  328. ConsolidateParamUnMarshallAnalysis( pAna );
  329. return CG_OK;
  330. }
  331. void
  332. CG_PARAM::InitParamMarshallAnalysis(
  333. ANALYSIS_INFO * pAna )
  334. {
  335. node_skl * pType = GetType();
  336. PNAME pName = pType->GetSymName();
  337. CG_NDR * pC = (CG_NDR *)GetChild();
  338. // For all cases of generic handles, where the CG_GENERIC_HANDLE will
  339. // sit below the param, we want to bypass the generic handle class during
  340. // marshall analysis.
  341. if( pC->GetCGID() == ID_CG_GENERIC_HDL )
  342. {
  343. pC = (CG_NDR *)pC->GetChild();
  344. }
  345. //
  346. // Allocate the resource for this parameter. On the client side, this
  347. // parameter is a param resource, while on the server, this param is a local
  348. // resource. One the client side, the param has already been added to the
  349. // resource dictionary.
  350. if( pAna->GetCurrentSide() == C_SIDE )
  351. {
  352. if( (pC->IsArray()) &&
  353. (pAna->GetOptimOption() & OPTIMIZE_INTERPRETER )
  354. )
  355. {
  356. pType = MakePtrIDNode( pName, pType->GetChild() );
  357. }
  358. SetResource( new RESOURCE( pName, pType) );
  359. }
  360. else
  361. {
  362. node_skl * pActualType = pType->GetChild();
  363. if( (pC->GetCGID() == ID_CG_CONTEXT_HDL ) ||
  364. (pC->GetChild() && (pC->GetChild()->GetCGID() == ID_CG_CONTEXT_HDL)))
  365. {
  366. pActualType = MakeIDNode( pName, new node_def ("NDR_SCONTEXT" ) );
  367. }
  368. else if( pC->IsArray() )
  369. pActualType = MakePtrIDNode( pName, pActualType);
  370. else
  371. pActualType = MakeIDNode( pName, pActualType );
  372. SetResource( pAna->AddLocalResource( pName, pActualType ));
  373. }
  374. SetSizeResource( 0 );
  375. SetLengthResource( 0 );
  376. SetFirstResource( 0 );
  377. pAna->SetMemoryAllocDone();
  378. pAna->ResetRefAllocDone();
  379. pAna->ResetEmbeddingLevel();
  380. pAna->ResetIndirectionLevel();
  381. pAna->SetRefChainIntact();
  382. pAna->ResetDeferPointee();
  383. pAna->ResetHasAtLeastOneDeferredPointee();
  384. pAna->SetLastPlaceholderClass( (CG_NDR *)this );
  385. }
  386. void
  387. CG_PARAM::ConsolidateParamMarshallAnalysis(
  388. ANALYSIS_INFO * pAna )
  389. {
  390. expr_node * pSE = 0;
  391. // Consolidate the result of the analysis from lower nodes, first into
  392. // this node, and then into the analysis block.
  393. pSE = new expr_constant( (long)0U, VALUE_TYPE_NUMERIC_U );
  394. SetSizeExpression( pSE );
  395. if( pAna->GetOptimOption() & OPTIMIZE_SIZE )
  396. {
  397. pAna->ClearTransientResourceDict();
  398. }
  399. }
  400. void
  401. CG_PARAM::InitParamUnMarshallAnalysis(
  402. ANALYSIS_INFO * pAna )
  403. {
  404. node_skl * pType = GetType();
  405. node_skl * pActualType = pType->GetBasicType();
  406. PNAME pName = pType->GetSymName();
  407. CG_NDR * pC = (CG_NDR *)GetChild();
  408. // For all cases of generic handles, where the CG_GENERIC_HANDLE will
  409. // sit below the param, we want to bypass the generic handle class during
  410. // marshall analysis.
  411. if( pC->GetCGID() == ID_CG_GENERIC_HDL )
  412. {
  413. pC = (CG_NDR *)pC->GetChild();
  414. }
  415. //
  416. // Allocate resources. On the client side, a parameter resource is allocated
  417. // and on the server, a local resource is allocated.
  418. //
  419. SetSubstitutePtrResource( 0 );
  420. if( pAna->GetCurrentSide() == C_SIDE )
  421. {
  422. pAna->SetDontReUseBuffer();
  423. if( (pC->IsArray()) &&
  424. (pAna->GetOptimOption() & OPTIMIZE_INTERPRETER )
  425. )
  426. {
  427. pType = MakePtrIDNode( pName, pType->GetChild() /* GetBasicType() ????????? */ );
  428. }
  429. SetResource( new RESOURCE( pName, pType) ) ;
  430. }
  431. else if ( ! IsOmittedParam() )
  432. {
  433. pC->SetAllocatedOnStack( 1 );
  434. if( (pC->GetCGID() == ID_CG_CONTEXT_HDL ) ||
  435. (pC->GetChild() && (pC->GetChild()->GetCGID() == ID_CG_CONTEXT_HDL)))
  436. {
  437. pActualType = MakeIDNode( pName, new node_def ("NDR_SCONTEXT" ) );
  438. }
  439. else if( pC->IsArray() )
  440. {
  441. pActualType = MakePtrIDNode( pName, pType->GetChild() );
  442. }
  443. else
  444. pActualType = MakeIDNode( pName, pType->GetChild() );
  445. pAna->ResetDontReUseBuffer();
  446. SetResource( pAna->AddLocalResource( pName, pActualType ) );
  447. }
  448. SetSizeResource( 0 );
  449. SetLengthResource( 0 );
  450. SetFirstResource( 0 );
  451. // Reset for analysis.
  452. pAna->SetMemoryAllocDone();
  453. pAna->ResetRefAllocDone();
  454. pAna->ResetEmbeddingLevel();
  455. pAna->ResetIndirectionLevel();
  456. pAna->SetRefChainIntact();
  457. pAna->ResetDeferPointee();
  458. pAna->ResetHasAtLeastOneDeferredPointee();
  459. pAna->SetLastPlaceholderClass( (CG_NDR *)this );
  460. }
  461. void
  462. CG_PARAM::ConsolidateParamUnMarshallAnalysis(
  463. ANALYSIS_INFO * pAna )
  464. {
  465. // Consolidate the result of the analysis from lower nodes, first into
  466. // this node, and then into the analysis block.
  467. if( pAna->GetOptimOption() & OPTIMIZE_SIZE )
  468. {
  469. pAna->ClearTransientResourceDict();
  470. }
  471. }
  472. CG_STATUS
  473. CG_PARAM::S_OutLocalAnalysis(
  474. ANALYSIS_INFO * pAna )
  475. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  476. Routine Description:
  477. Perform analysis for all params which may be allocated as locals for
  478. server stub
  479. Arguments:
  480. pAna - A pointer to the analysis block.
  481. Return Value:
  482. Notes:
  483. Ignore [in, out], since that would be done by the Unmarshall analysis.
  484. ----------------------------------------------------------------------------*/
  485. {
  486. // If the param is [out] only, determine if there is a need for local
  487. // variables and if they need to be inited.
  488. if( IsParamOut() && !IsParamIn() )
  489. {
  490. InitParamMarshallAnalysis( pAna );
  491. ((CG_NDR *)GetChild())->S_OutLocalAnalysis( pAna );
  492. }
  493. return CG_OK;
  494. }
  495. void
  496. CG_PARAM::RpcSsPackageAnalysis(
  497. ANALYSIS_INFO * pAna )
  498. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  499. Routine Description:
  500. Perform analysis for rpcss package enabling.
  501. Arguments:
  502. pAna - A pointer to the analysis block.
  503. Return Value:
  504. Notes:
  505. This routine should be called only in the osf mode.
  506. ----------------------------------------------------------------------------*/
  507. {
  508. //
  509. // Package needs to be enabled (only is OSF mode) when the NDR engine
  510. // is going to do any allocations whatsoever at the server side.
  511. //
  512. // In Os this may happen on
  513. // - anything other than simple type or pointer to simple type
  514. // - with simple type, if this happens to be enum16
  515. // In Oi this may happen on
  516. // - anything [out]
  517. // - [in] like Os
  518. // In Oi2 this may happen on
  519. // - anything [out] when lack of space on -Oi2 stack
  520. // - [in] like Os
  521. // (simple types and pointers to simple types are usually on
  522. // the interpreter stack, if there is space there).
  523. // However, this cannot be guaranteed.
  524. if( IsParamOut() &&
  525. ( pAna->GetOptimOption() & OPTIMIZE_INTERPRETER) )
  526. {
  527. // We could do a better job for Oi2 if we watched the its stack.
  528. pAna->SetRpcSSAllocateRecommended( 1 );
  529. return;
  530. }
  531. // We are here with
  532. // [in] or [in,out] for Oi?
  533. // any for Os
  534. // See if this is one of the simple cases mentioned above.
  535. // This is really a check for the buffer reusage.
  536. CG_NDR * pChild = (CG_NDR *)GetChild();
  537. if ( pChild->IsSimpleType() &&
  538. ( pChild->GetCGID() != ID_CG_ENUM ||
  539. pChild->GetCGID() == ID_CG_ENUM &&
  540. ((CG_ENUM*)pChild)->IsEnumLong() )
  541. && pChild->GetCGID() != ID_CG_INT3264
  542. )
  543. {
  544. // An [in] arg in the buffer.
  545. return;
  546. }
  547. // Note that we don't have to check for allocate(allnodes) etc.
  548. // as this is not an osf attribute.
  549. // Also note that we handle top level pointers here.
  550. if ( pChild->IsPointer() && ((CG_POINTER *)pChild)->IsRef() )
  551. {
  552. // In args would stay in the buffer,
  553. // out args would be on the Os stack.
  554. CG_NDR * pPointee = (CG_NDR *)pChild->GetChild();
  555. if ( ( pChild->GetCGID() == ID_CG_PTR ||
  556. pChild->GetCGID() == ID_CG_STRING_PTR ||
  557. pChild->GetCGID() == ID_CG_SIZE_PTR )
  558. &&
  559. pPointee->IsSimpleType()
  560. &&
  561. ( pPointee->GetCGID() != ID_CG_ENUM ||
  562. pPointee->GetCGID() == ID_CG_ENUM &&
  563. ((CG_ENUM*)pPointee)->IsEnumLong() )
  564. &&
  565. pPointee->GetCGID() != ID_CG_INT3264
  566. )
  567. return;
  568. }
  569. pAna->SetRpcSSAllocateRecommended( 1 );
  570. }
  571. /****************************************************************************
  572. Implementation of the return type node.
  573. ****************************************************************************/
  574. CG_STATUS
  575. CG_RETURN::MarshallAnalysis(
  576. ANALYSIS_INFO * pAna )
  577. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  578. Routine Description:
  579. Perform the size analysis for the return type.
  580. Arguments:
  581. pAna - A pointer to the analysis block.
  582. Return Value:
  583. Notes:
  584. For the return type, the size analysis contributes nothing on the
  585. client side, yet we must declare a local variable for the return.
  586. ----------------------------------------------------------------------------*/
  587. {
  588. node_skl * pType = GetType();
  589. PNAME pName = RETURN_VALUE_VAR_NAME;
  590. CG_STATUS Status;
  591. CG_NDR * pC = (CG_NDR *)GetChild();
  592. //
  593. // Always allocate a local resource for the return type.
  594. //
  595. if( (pC->GetCGID() == ID_CG_CONTEXT_HDL ) ||
  596. (pC->GetChild() && (pC->GetChild()->GetCGID() == ID_CG_CONTEXT_HDL)))
  597. {
  598. node_skl * pActualType = pType->GetBasicType();
  599. pActualType = MakeIDNode( pName, new node_def ("NDR_SCONTEXT" ) );
  600. SetResource( pAna->AddLocalResource( pName, pActualType ));
  601. }
  602. else
  603. {
  604. pType = MakeIDNode( pName, pType );
  605. SetResource( pAna->AddLocalResource( pName, pType ));
  606. }
  607. SetSizeResource( 0 );
  608. // Reset the analysis block for marshalling.
  609. pAna->SetMemoryAllocDone();
  610. pAna->ResetRefAllocDone();
  611. pAna->ResetEmbeddingLevel();
  612. pAna->SetRefChainIntact();
  613. pAna->SetDontReUseBuffer();
  614. pAna->SetReturnContext();
  615. pAna->SetLastPlaceholderClass( (CG_NDR *)this );
  616. // Send the analysis message to the child nodes.
  617. Status = ((CG_NDR *)GetChild())->MarshallAnalysis( pAna );
  618. SetSizeExpression(
  619. new expr_constant( 0L, VALUE_TYPE_NUMERIC_U ) );
  620. pAna->ResetReturnContext();
  621. if( pAna->GetOptimOption() & OPTIMIZE_SIZE )
  622. {
  623. pAna->ClearTransientResourceDict();
  624. }
  625. return Status;
  626. }
  627. CG_STATUS
  628. CG_RETURN::UnMarshallAnalysis(
  629. ANALYSIS_INFO * pAna )
  630. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  631. Routine Description:
  632. Perform the buffer analysis for the return type.
  633. Arguments:
  634. pAna - A pointer to the analysis block.
  635. Return Value:
  636. Notes:
  637. For the return type, the size analysis contributes nothing on the
  638. client side, yet we must declare a local variable for the return.
  639. ----------------------------------------------------------------------------*/
  640. {
  641. node_skl * pType = GetType();
  642. PNAME pName = RETURN_VALUE_VAR_NAME;
  643. CG_STATUS Status;
  644. //
  645. // Always allocate a local resource for the return type.
  646. //
  647. pType = MakeIDNode( pName, pType );
  648. SetResource( pAna->AddLocalResource( pName, pType ));
  649. pAna->SetMemoryAllocDone();
  650. pAna->ResetRefAllocDone();
  651. pAna->ResetEmbeddingLevel();
  652. pAna->SetRefChainIntact();
  653. pAna->SetDontReUseBuffer();
  654. pAna->SetReturnContext();
  655. pAna->SetLastPlaceholderClass( (CG_NDR *)this );
  656. Status = ((CG_NDR *)GetChild())->UnMarshallAnalysis( pAna );
  657. pAna->ResetReturnContext();
  658. if( pAna->GetOptimOption() & OPTIMIZE_SIZE )
  659. {
  660. pAna->ClearTransientResourceDict();
  661. }
  662. return Status;
  663. }