Leaked source code of windows server 2003
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.

1800 lines
55 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1989-2000 Microsoft Corporation
  3. Module Name:
  4. ilcore.cxx
  5. Abstract:
  6. Intermediate Language translator for core typegraph
  7. Notes:
  8. Author:
  9. GregJen Dec-24-1993 Created.
  10. Notes:
  11. ----------------------------------------------------------------------------*/
  12. /****************************************************************************
  13. * include files
  14. ***************************************************************************/
  15. #include "becls.hxx"
  16. #pragma hdrstop
  17. #include "ilxlat.hxx"
  18. #include "ilreg.hxx"
  19. /****************************************************************************
  20. * local data
  21. ***************************************************************************/
  22. /****************************************************************************
  23. * externs
  24. ***************************************************************************/
  25. extern CMD_ARG * pCommand;
  26. extern BOOL IsTempName( char *);
  27. extern REUSE_DICT * pReUseDict;
  28. /****************************************************************************
  29. * definitions
  30. ***************************************************************************/
  31. // #define trace_cg
  32. //--------------------------------------------------------------------
  33. //
  34. // node_href::ILxlate
  35. //
  36. // Notes:
  37. //
  38. //
  39. //
  40. //--------------------------------------------------------------------
  41. CG_CLASS *
  42. node_href::ILxlate( XLAT_CTXT * pContext )
  43. {
  44. #ifdef trace_cg
  45. printf("..node_href,\t%s\n", GetSymName());
  46. #endif
  47. if ( !GetChild() )
  48. {
  49. named_node * pRef = Resolve();
  50. if ( !pRef )
  51. {
  52. SemError( this, *pContext, UNSATISFIED_HREF, GetSymName() );
  53. exit( UNSATISFIED_HREF );
  54. }
  55. }
  56. return GetChild()->ILxlate( pContext );
  57. }
  58. //--------------------------------------------------------------------
  59. //
  60. // node_forward::ILxlate
  61. //
  62. // Notes:
  63. //
  64. //
  65. //
  66. //--------------------------------------------------------------------
  67. CG_CLASS *
  68. node_forward::ILxlate( XLAT_CTXT * pContext )
  69. {
  70. #ifdef trace_cg
  71. printf("..node_forward,\t%s\n", GetSymName());
  72. #endif
  73. // MIDL_ASSERT( GetChild() && "unsatisfied node_forward encountered" );
  74. node_skl* pChild = GetChild();
  75. // forward interface definitions return null
  76. if ( ( pContext->GetParent()->IsInterfaceOrObject() ) &&
  77. ( pChild->NodeKind() == NODE_INTERFACE_REFERENCE ) )
  78. return NULL;
  79. if ( pChild )
  80. {
  81. // pass it on to the child...
  82. return pChild->ILxlate( pContext );
  83. }
  84. else
  85. {
  86. // try again
  87. pChild = ResolveFDecl();
  88. if ( pChild )
  89. {
  90. // pass it on to the child...
  91. return pChild->ILxlate( pContext );
  92. }
  93. else
  94. {
  95. SemError( this, *pContext, UNSATISFIED_FORWARD, GetSymName() );
  96. exit( UNSATISFIED_FORWARD );
  97. }
  98. }
  99. };
  100. //--------------------------------------------------------------------
  101. //
  102. // node_id::ILxlate
  103. //
  104. // Notes:
  105. //
  106. //
  107. //
  108. //--------------------------------------------------------------------
  109. CG_CLASS *
  110. node_id::ILxlate( XLAT_CTXT * pContext )
  111. {
  112. #ifdef trace_cg
  113. printf("..node_id,\t%s\n", GetSymName());
  114. #endif
  115. XLAT_CTXT MyContext( this, pContext );
  116. CG_CLASS * pCG;
  117. MyContext.ExtractAttribute(ATTR_ID);
  118. MyContext.ExtractAttribute(ATTR_HELPCONTEXT);
  119. MyContext.ExtractAttribute(ATTR_HELPSTRINGCONTEXT);
  120. MyContext.ExtractAttribute(ATTR_HELPSTRING);
  121. MyContext.ExtractAttribute(ATTR_HIDDEN);
  122. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  123. pCG = GetChild()->ILxlate( &MyContext );
  124. if (NODE_MODULE == pContext->GetParent()->NodeKind())
  125. {
  126. CG_ID * pID = new CG_ID (this, MyContext);
  127. pID->SetChild(pCG);
  128. pCG = pID;
  129. }
  130. pContext->ReturnSize( MyContext );
  131. return pCG;
  132. };
  133. //--------------------------------------------------------------------
  134. //
  135. // node_field::ILxlate
  136. //
  137. // Notes:
  138. //
  139. //
  140. //
  141. //--------------------------------------------------------------------
  142. CG_CLASS *
  143. node_field::ILxlate( XLAT_CTXT * pContext )
  144. {
  145. CG_NDR * pCG;
  146. CG_CLASS * pChildCG;
  147. XLAT_CTXT MyContext( this, pContext );
  148. BOOL fUnionField;
  149. CG_CASE * pFirstCase;
  150. CG_CASE * pCurCase;
  151. expr_node * pSwitchExpr = NULL;
  152. node_su_base * pParent = (node_su_base *)pContext->GetParent();
  153. BOOL fConfFld = FALSE;
  154. MyContext.ExtractAttribute(ATTR_ID);
  155. MyContext.ExtractAttribute(ATTR_IDLDESCATTR);
  156. MyContext.ExtractAttribute(ATTR_VARDESCATTR);
  157. MyContext.ExtractAttribute(ATTR_HELPSTRING);
  158. MyContext.ExtractAttribute(ATTR_HELPSTRINGCONTEXT);
  159. MyContext.ExtractAttribute(ATTR_HELPCONTEXT);
  160. MyContext.ExtractAttribute(ATTR_HIDDEN);
  161. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  162. while (MyContext.ExtractAttribute(ATTR_MEMBER));
  163. #ifdef trace_cg
  164. printf("..node_field,\t%s\n", GetSymName());
  165. #endif
  166. if ( ( fUnionField = ( MyContext.FInSummary( ATTR_CASE ) ||
  167. MyContext.FInSummary( ATTR_DEFAULT ) ) ) != 0 )
  168. {
  169. CG_CASE * pPrevCase = NULL;
  170. node_case * pCaseAttr;
  171. expr_list * pExprList;
  172. expr_node * pExpr;
  173. pCG = new CG_UNION_FIELD( this, MyContext );
  174. // for each case attribute, make a CG_CASE for each expr in the attr
  175. while ( ( pCaseAttr = (node_case *) MyContext.ExtractAttribute( ATTR_CASE ) ) != 0 )
  176. {
  177. pExprList = pCaseAttr->GetExprList();
  178. pExprList->Init();
  179. while ( pExprList->GetPeer( &pExpr ) == STATUS_OK )
  180. {
  181. pCurCase = new CG_CASE( this, pExpr );
  182. pCurCase->SetChild( pCG );
  183. if ( pPrevCase )
  184. pPrevCase->SetSibling( pCurCase );
  185. else
  186. pFirstCase = pCurCase;
  187. pPrevCase = pCurCase;
  188. }
  189. }
  190. // now process the default, if any
  191. if ( MyContext.ExtractAttribute( ATTR_DEFAULT ) )
  192. {
  193. pCurCase = new CG_DEFAULT_CASE( this );
  194. pCurCase->SetChild( pCG );
  195. if ( pPrevCase )
  196. pPrevCase->SetSibling( pCurCase );
  197. else
  198. pFirstCase = pCurCase;
  199. pPrevCase = pCurCase;
  200. }
  201. // mark the last case for this arm
  202. pCurCase->SetLastCase( TRUE );
  203. }
  204. // if we have a switch_is expr, fetch it..
  205. if ( MyContext.FInSummary( ATTR_SWITCH_IS ) )
  206. {
  207. node_switch_is * pAttr;
  208. if ( pCommand->IsNDR64Run() )
  209. {
  210. pAttr = (node_switch_is*)MyContext.GetAttribute( ATTR_SWITCH_IS );
  211. }
  212. else
  213. {
  214. pAttr = (node_switch_is*)MyContext.ExtractAttribute( ATTR_SWITCH_IS );
  215. }
  216. pSwitchExpr = pAttr->GetExpr();
  217. }
  218. // process the child of the field
  219. pChildCG = GetChild()->ILxlate( &MyContext );
  220. // can't use attribute list after here...
  221. MyContext.AdjustForZP(); // fix up alignments for current ZP
  222. MyContext.GetOffset( *pContext ); // offset in parent struct/union
  223. node_skl * pBasic = GetBasicType();
  224. // If this is NDR64, treat conformant fields the same
  225. // as nonconformant fields since conformant arrays
  226. // have an alignment even is they have 0 elements.
  227. if ( !pCommand->IsNDR64Run() &&
  228. pParent->HasConformance() &&
  229. IsLastField() &&
  230. ( pBasic->NodeKind() != NODE_STRUCT ) &&
  231. !fUnionField) // if I'm a conf. field
  232. {
  233. fConfFld = TRUE;
  234. MyContext.AlignConfOffset(); // round mem, not wire up to alignment
  235. }
  236. else if ( pBasic->IsEncapsulatedStruct() ||
  237. ( pBasic->NodeKind() == NODE_UNION ) )
  238. {
  239. MyContext.AlignEmbeddedUnion();
  240. }
  241. else
  242. {
  243. MyContext.AlignOffset(); // round up to alignment
  244. }
  245. CG_FIELD *pField = NULL;
  246. if (fUnionField )
  247. {
  248. pCG->SetChild( pChildCG );
  249. pCG = pFirstCase;
  250. pField = (CG_FIELD *) pCG->GetChild();
  251. MIDL_ASSERT( ID_CG_UNION_FIELD == pField->GetCGID() );
  252. pContext->ReturnUnionSize( MyContext ); // return size and alignment
  253. }
  254. else
  255. {
  256. pField = new CG_FIELD( this, MyContext );
  257. pField->SetChild( pChildCG );
  258. pField->SetSwitchExpr( pSwitchExpr );
  259. pCG = pField;
  260. pContext->ReturnOffset( MyContext ); // return rounded-up offset
  261. // Treat conformant fields the same as non-conformant fields in Ndr64.
  262. // The wire-size and wire_offset should be 0 though.
  263. if ( !pCommand->IsNDR64Run() && fConfFld )
  264. pContext->ReturnConfSize( MyContext ); // don't munge wire size!
  265. else
  266. pContext->ReturnSize( MyContext ); // return size and alignment
  267. }
  268. if ( HasUnknownRepAs() )
  269. pField->SetHasEmbeddedUnknownRepAs();
  270. if ( fConfFld )
  271. {
  272. pCG->SetMemorySize( 0 );
  273. pCG->SetWireSize( 0 );
  274. }
  275. return pCG;
  276. };
  277. //--------------------------------------------------------------------
  278. //
  279. // node_bitfield::ILxlate
  280. //
  281. // Notes:
  282. //
  283. //
  284. //
  285. //--------------------------------------------------------------------
  286. CG_CLASS *
  287. node_bitfield::ILxlate( XLAT_CTXT* pContext )
  288. {
  289. #ifdef trace_cg
  290. printf("..node_bitfield,\t%s\n", GetSymName());
  291. #endif
  292. XLAT_CTXT MyContext( this, pContext );
  293. SemError( this, MyContext, FAILED_TO_GENERATE_BIT_FIELD, GetSymName() );
  294. return NULL;
  295. };
  296. //--------------------------------------------------------------------
  297. //
  298. // node_enum::ILxlate
  299. //
  300. // Notes:
  301. //
  302. //
  303. //
  304. //--------------------------------------------------------------------
  305. CG_CLASS *
  306. node_enum::ILxlate( XLAT_CTXT * pContext )
  307. {
  308. #ifdef trace_cg
  309. printf("..node_enum,\t%s\n", GetSymName());
  310. #endif
  311. XLAT_CTXT MyContext( this, pContext );
  312. node_range_attr* pRange = (node_range_attr*) MyContext.ExtractAttribute(ATTR_RANGE);
  313. node_base_attr *pV1enum = MyContext.ExtractAttribute( ATTR_V1_ENUM );
  314. pContext->ExtractAttribute(ATTR_TYPEDESCATTR);
  315. MyContext.EnumTypeSizes (
  316. this,
  317. // All enums are 32bit on wire in new syntax.
  318. pCommand->IsNDR64Run() || pV1enum
  319. );
  320. CG_ENUM * pCG = new CG_ENUM( this, MyContext );
  321. if ( pCommand->IsSwitchDefined( SWITCH_ROBUST ) )
  322. {
  323. pCG->SetRangeAttribute( pRange );
  324. }
  325. pContext->ReturnSize( MyContext );
  326. return pCG;
  327. };
  328. //--------------------------------------------------------------------
  329. //
  330. // node_struct::ILxlate
  331. //
  332. // Notes:
  333. //
  334. //
  335. //
  336. //--------------------------------------------------------------------
  337. CG_CLASS *
  338. node_struct::ILxlate( XLAT_CTXT * pContext )
  339. {
  340. MEM_ITER MemIter( this );
  341. node_field * pN;
  342. CG_STRUCT * pCG;
  343. CG_CLASS * pChildCG = NULL;
  344. CG_CLASS * pPrevChildCG = NULL;
  345. CG_CLASS * pFirstChildCG = NULL;
  346. XLAT_CTXT MyContext( this, pContext );
  347. REUSE_INFO * pSaved;
  348. BOOL fHasMovedFields = FALSE; // has fields with diff mem/wire offsets
  349. MyContext.ExtractAttribute(ATTR_TYPEDESCATTR);
  350. MyContext.ExtractAttribute(ATTR_HIDDEN);
  351. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  352. #ifdef trace_cg
  353. printf("..node_struct,\t%s\n", GetSymName());
  354. #endif
  355. MyContext.ExtractAttribute( ATTR_STRING );
  356. // raw rpc doesn't care about uuid's on structs, typelibs get a new context
  357. // during GetTypeInfo.
  358. MyContext.ExtractAttribute(ATTR_GUID);
  359. // process any context_handle attributes from param nodes
  360. if ( MyContext.ExtractAttribute( ATTR_CONTEXT ) )
  361. {
  362. CG_NDR * pChildCG;
  363. MyContext.ContextHandleSizes( this );
  364. pContext->ReturnSize( MyContext );
  365. pChildCG = new CG_CONTEXT_HANDLE (
  366. this,
  367. 0,
  368. MyContext
  369. );
  370. return pChildCG;
  371. }
  372. // clear member attributes
  373. while (MyContext.ExtractAttribute(ATTR_MEMBER));
  374. // at this point, there should be no more attributes...
  375. MIDL_ASSERT( !MyContext.HasAttributes() );
  376. // store our own zp value for below
  377. MyContext.GetZeePee() = GetZeePee();
  378. // see if we were already generated
  379. if ( pReUseDict->GetReUseEntry( pSaved, this ) )
  380. {
  381. // reuse found...
  382. pSaved->FetchInfo( &MyContext, pChildCG );
  383. pContext->ReturnSize( MyContext );
  384. return pChildCG;
  385. }
  386. // manufature the CG node (to allow for recursion)
  387. switch (Complexity)
  388. {
  389. case FLD_PLAIN:
  390. {
  391. pCG = new CG_STRUCT( this,
  392. MyContext,
  393. HasAtLeastOnePointer()
  394. );
  395. break;
  396. }
  397. case FLD_CONF:
  398. {
  399. pCG = new CG_CONFORMANT_STRUCT( this,
  400. MyContext,
  401. HasAtLeastOnePointer(),
  402. NULL
  403. );
  404. break;
  405. }
  406. case FLD_CONF_VAR:
  407. {
  408. pCG = new CG_CONFORMANT_VARYING_STRUCT( this,
  409. MyContext,
  410. HasAtLeastOnePointer(),
  411. NULL
  412. );
  413. break;
  414. }
  415. case FLD_VAR:
  416. default:
  417. {
  418. pCG = new CG_COMPLEX_STRUCT( this,
  419. MyContext,
  420. HasAtLeastOnePointer(),
  421. NULL
  422. );
  423. break;
  424. }
  425. }
  426. // save our CG node so that recursive use can find it
  427. pSaved->SaveInfo( &MyContext, pCG);
  428. //
  429. // for each of the fields, call the core transformer.
  430. //
  431. while ( ( pN = (node_field *) MemIter.GetNext() ) != 0 )
  432. {
  433. pChildCG = pN->ILxlate( &MyContext );
  434. // adjust the size and current offset of the struct, special
  435. // case the conformant field ( last one )
  436. //
  437. // Except if this is the new transfer syntax. In that case
  438. // the wire has a pad to the array even if the array has 0
  439. // elements. This allows a case like this to be simple instead
  440. // of complex.
  441. //
  442. // struct MyStruct {
  443. // char s;
  444. // [size_is(s)] long s[];
  445. // };
  446. //
  447. if ( !pCommand->IsNDR64Run() &&
  448. ( fHasConformance &&
  449. !pN->GetSibling() &&
  450. ( pN->GetBasicType()->NodeKind() != NODE_STRUCT ) ) )
  451. {
  452. MyContext.AdjustConfSize();
  453. }
  454. else
  455. {
  456. MyContext.AdjustSize();
  457. }
  458. if ( !MyContext.SameOffsets() )
  459. fHasMovedFields = TRUE;
  460. // Add the field to the list of fields if it's available
  461. // pChildCG might be NULL if it's imported from .tlb and being
  462. // processed earlier.
  463. if ( pChildCG )
  464. {
  465. if( pPrevChildCG )
  466. {
  467. pPrevChildCG->SetSibling( pChildCG );
  468. }
  469. else
  470. {
  471. pFirstChildCG = pChildCG;
  472. };
  473. pPrevChildCG = pChildCG;
  474. }
  475. else
  476. SemError( this, MyContext, FAILED_TO_GENERATE_FIELD, GetSymName() );
  477. // get the type of the field to determine kind of struct
  478. }
  479. // conformant structs don't get trailing padding
  480. if ( !fHasConformance )
  481. // The new transfer syntax pads the wire size for structures to the
  482. // the new wire alignment.
  483. if ( pCommand->IsNDR64Run() )
  484. {
  485. MyContext.Ndr64AdjustTotalStructSize();
  486. }
  487. else
  488. {
  489. MyContext.AdjustTotalSize();
  490. }
  491. pContext->ReturnSize( MyContext );
  492. pCG->SetChild( pFirstChildCG );
  493. // Sizes aren't determined until after the fields have been made,
  494. // so we have to set them manually. For the same reason, i.e. because of
  495. // invalid recursive definitions, we check the memory size here.
  496. pCG->SetSizesAndAlignments( MyContext );
  497. if ( pCommand->IsNDR64Run() )
  498. {
  499. if ( pCG->GetMemorySize() >= SIZE_2GB )
  500. {
  501. SemError( this, MyContext, SIZE_EXCEEDS_2GB, NULL );
  502. exit( SIZE_EXCEEDS_2GB );
  503. }
  504. }
  505. else if ( pCG->GetMemorySize() > 65535 )
  506. {
  507. SemError( this, MyContext, STRUCT_SIZE_EXCEEDS_64K, NULL );
  508. exit( STRUCT_SIZE_EXCEEDS_64K );
  509. }
  510. // this picks up whatever is the last field...
  511. if ( fHasConformance )
  512. ((CG_CONFORMANT_STRUCT *) pCG)->SetConformantField( pChildCG );
  513. if ( fHasMovedFields )
  514. {
  515. pCG->SetHasMovedFields();
  516. }
  517. pSaved->SaveInfo( &MyContext, pCG);
  518. return pCG;
  519. };
  520. //--------------------------------------------------------------------
  521. //
  522. // node_en_struct::ILxlate
  523. //
  524. // Notes:
  525. //
  526. //
  527. //
  528. //--------------------------------------------------------------------
  529. CG_CLASS *
  530. node_en_struct::ILxlate( XLAT_CTXT * pContext )
  531. {
  532. MEM_ITER MemIter( this );
  533. node_skl * pN;
  534. CG_STRUCT * pCG;
  535. CG_CLASS * pChildCG = NULL;
  536. CG_CLASS * pPrevChildCG = NULL;
  537. CG_CLASS * pFirstChildCG = NULL;
  538. XLAT_CTXT MyContext( this, pContext );
  539. REUSE_INFO * pSaved;
  540. #ifdef trace_cg
  541. printf("..node_en_struct,\t%s\n", GetSymName());
  542. #endif
  543. // store our own zp value for below
  544. MyContext.GetZeePee() = GetZeePee();
  545. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  546. // raw rpc doesn't care about uuid's on structs, typelibs get a new context
  547. // during GetTypeInfo.
  548. MyContext.ExtractAttribute(ATTR_GUID);
  549. // process any context_handle attributes from param nodes
  550. if ( MyContext.ExtractAttribute( ATTR_CONTEXT ) )
  551. {
  552. CG_HANDLE * pHdlCG;
  553. MyContext.ContextHandleSizes( this );
  554. pContext->ReturnSize( MyContext );
  555. pHdlCG = new CG_CONTEXT_HANDLE (
  556. this,
  557. 0,
  558. MyContext
  559. );
  560. return pHdlCG;
  561. }
  562. // at this point, there should be no more attributes...
  563. MIDL_ASSERT( !MyContext.HasAttributes() );
  564. if ( pReUseDict->GetReUseEntry( pSaved, this ) )
  565. {
  566. // reuse found...
  567. pSaved->FetchInfo( &MyContext, pChildCG );
  568. pContext->ReturnSize( MyContext );
  569. return pChildCG;
  570. }
  571. // manufature the CG node (to allow for recursion)
  572. pCG = new CG_ENCAPSULATED_STRUCT( this,
  573. MyContext,
  574. HasAtLeastOnePointer()
  575. );
  576. // set that struct is encapsulated
  577. // pCG->SetIsEncapsulated();
  578. // save our CG node so that recursive use can find it
  579. pSaved->SaveInfo( &MyContext, pCG);
  580. //
  581. // for each of the fields, call the core transformer.
  582. //
  583. while ( ( pN = MemIter.GetNext() ) != 0 )
  584. {
  585. pChildCG = pN->ILxlate( &MyContext );
  586. MyContext.AdjustSize();
  587. if (pChildCG)
  588. {
  589. if( pPrevChildCG )
  590. {
  591. pPrevChildCG->SetSibling( pChildCG );
  592. }
  593. else
  594. {
  595. pFirstChildCG = pChildCG;
  596. };
  597. pPrevChildCG = pChildCG;
  598. }
  599. else
  600. SemError( this, MyContext, FAILED_TO_GENERATE_FIELD, GetSymName() );
  601. }
  602. MyContext.AdjustTotalSize();
  603. pContext->ReturnSize( MyContext );
  604. pCG->SetChild( pFirstChildCG );
  605. // set sizes manually, since they weren't known at constructor time.
  606. pCG->SetSizesAndAlignments( MyContext );
  607. if ( pCommand->IsNDR64Run() )
  608. {
  609. if ( pCG->GetMemorySize() >= SIZE_2GB )
  610. {
  611. SemError( this, MyContext, SIZE_EXCEEDS_2GB, NULL );
  612. exit( SIZE_EXCEEDS_2GB );
  613. }
  614. }
  615. else if ( pCG->GetMemorySize() > 65535 )
  616. {
  617. SemError( this, MyContext, STRUCT_SIZE_EXCEEDS_64K, NULL );
  618. exit( STRUCT_SIZE_EXCEEDS_64K );
  619. }
  620. pSaved->SaveInfo( &MyContext, pCG);
  621. return pCG;
  622. };
  623. //--------------------------------------------------------------------
  624. //
  625. // node_union::ILxlate
  626. //
  627. // Notes:
  628. //
  629. //
  630. //
  631. //--------------------------------------------------------------------
  632. CG_CLASS *
  633. node_union::ILxlate( XLAT_CTXT * pContext )
  634. {
  635. XLAT_CTXT MyContext( this, pContext );
  636. MEM_ITER MemIter( this );
  637. CG_CASE * pCurCaseCG;
  638. CG_CASE * pFirstCaseCG = NULL;
  639. CG_CASE * pLastCaseCG = NULL;
  640. CG_UNION * pUnionCG;
  641. node_field * pCurField;
  642. REUSE_INFO * pSaved;
  643. BOOL fMSUnion;
  644. BOOL fEncap = IsEncapsulatedUnion();
  645. node_switch_type * pSwTypeAttr = ( node_switch_type *)
  646. MyContext.ExtractAttribute( ATTR_SWITCH_TYPE );
  647. node_switch_is * pSwIsAttr = NULL;
  648. node_skl * pReuseKey = this;
  649. if ( pCommand->IsNDR64Run() )
  650. {
  651. pSwIsAttr = (node_switch_is *)MyContext.ExtractAttribute( ATTR_SWITCH_IS );
  652. if ( !fEncap )
  653. {
  654. pReuseKey = (node_skl*)pSwIsAttr;
  655. }
  656. }
  657. MyContext.ExtractAttribute(ATTR_TYPEDESCATTR);
  658. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  659. #ifdef trace_cg
  660. printf("..node_union,\t%s\n", GetSymName());
  661. #endif
  662. // process any context_handle attributes from param nodes
  663. if ( MyContext.ExtractAttribute( ATTR_CONTEXT ) )
  664. {
  665. CG_NDR * pChildCG;
  666. MyContext.ContextHandleSizes( this );
  667. pContext->ReturnSize( MyContext );
  668. pChildCG = new CG_CONTEXT_HANDLE (
  669. this,
  670. 0,
  671. MyContext
  672. );
  673. return pChildCG;
  674. }
  675. // decide if we are a MS union or a DCE union
  676. fMSUnion = (NULL != MyContext.ExtractAttribute( ATTR_MS_UNION ));
  677. fMSUnion = fMSUnion ||
  678. GetMyInterfaceNode()->FInSummary( ATTR_MS_UNION ) ||
  679. pCommand->IsSwitchDefined( SWITCH_MS_UNION );
  680. fMSUnion = fMSUnion && !fEncap;
  681. // store our own zp value for below
  682. MyContext.GetZeePee() = GetZeePee();
  683. if ( pReUseDict->GetReUseEntry( pSaved, pReuseKey ) )
  684. {
  685. CG_CLASS * pCG;
  686. // reuse found...
  687. pSaved->FetchInfo( &MyContext, pCG );
  688. pContext->ReturnSize( MyContext );
  689. return pCG;
  690. }
  691. pUnionCG = new CG_UNION( this,
  692. MyContext,
  693. HasAtLeastOnePointer()
  694. );
  695. // save our CG node so that recursive use can find it
  696. pSaved->SaveInfo( &MyContext, pUnionCG);
  697. // process the union arms
  698. while ( ( pCurField = (node_field *) MemIter.GetNext() ) != 0 )
  699. {
  700. pCurCaseCG = (CG_CASE *) pCurField->ILxlate( &MyContext );
  701. // MyContext.AdjustSize();
  702. // add all the cases for the given field to the list
  703. if( pLastCaseCG )
  704. {
  705. pLastCaseCG->SetSibling( pCurCaseCG );
  706. }
  707. else
  708. {
  709. pFirstCaseCG = pCurCaseCG;
  710. };
  711. // advance pLastCaseCG to the end of the list
  712. pLastCaseCG = pCurCaseCG;
  713. MIDL_ASSERT( pLastCaseCG && "Null case list" );
  714. while ( pLastCaseCG->GetSibling() )
  715. pLastCaseCG = (CG_CASE *) pLastCaseCG->GetSibling();
  716. }
  717. // add a definition for the switch type to the CG node
  718. if ( pSwTypeAttr )
  719. {
  720. node_skl * pNode = pSwTypeAttr->GetType();
  721. // it gets its own context, so I doesn't mess up our sizing
  722. XLAT_CTXT SwTypeCtxt( &MyContext );
  723. CG_NDR * pSwCG = (CG_NDR *) pNode->ILxlate( &SwTypeCtxt );
  724. pUnionCG->SetSwitchType( pSwCG );
  725. }
  726. if ( pCommand->IsNDR64Run() && pSwIsAttr )
  727. {
  728. pUnionCG->SetNdr64SwitchIsExpr( pSwIsAttr->GetExpr() );
  729. }
  730. // add the case list to the union node and set all the union entries
  731. pUnionCG->SetChild( pFirstCaseCG );
  732. MyContext.AlignEmbeddedUnion();
  733. pUnionCG->SetSizesAndAlignments( MyContext );
  734. pUnionCG->SetUnionFlavor( unsigned short ( fMSUnion ? UNION_NONENCAP_MS : UNION_NONENCAP_DCE ) );
  735. if ( pCommand->IsNDR64Run() )
  736. {
  737. if ( pUnionCG->GetMemorySize() >= SIZE_2GB )
  738. {
  739. SemError( this, MyContext, SIZE_EXCEEDS_2GB, NULL );
  740. exit( SIZE_EXCEEDS_2GB );
  741. }
  742. }
  743. pSaved->SaveInfo( &MyContext, pUnionCG);
  744. if ( pCommand->IsNDR64Run() && !fEncap )
  745. {
  746. // If this is an nonencapsulated union, then we need to pass up the union alignment
  747. // instead of the arm alignment. To do this, put the max of the arm alignment and
  748. // switchtype alignment is the context.
  749. // we don't care about union in tlb: they might not have switch
  750. CG_NDR * pSwCG = dynamic_cast<CG_NDR*>( pUnionCG->GetSwitchType() );
  751. if ( pSwCG != NULL )
  752. MyContext.GetWireAlign() = MyContext.GetWireAlign() > pSwCG->GetWireAlignment() ?
  753. MyContext.GetWireAlign() : pSwCG->GetWireAlignment();
  754. }
  755. pContext->ReturnSize( MyContext );
  756. return pUnionCG;
  757. };
  758. //--------------------------------------------------------------------
  759. //
  760. // node_en_union::ILxlate
  761. //
  762. // Notes:
  763. //
  764. //
  765. // for an encapsulated union, we return the following tree:
  766. // CG_ENCAP_STRUCT ( with switch field )
  767. // |
  768. // CG_ENCAP_UNION
  769. // |
  770. // CG_CASE - CG_CASE - CG_CASE - CG_CASE
  771. // | | |
  772. // CG_UNION_FLD CG_UNION_FLD CG_UNION_FLD
  773. // |
  774. // etc.
  775. //
  776. //--------------------------------------------------------------------
  777. CG_CLASS *
  778. node_en_union::ILxlate( XLAT_CTXT * pContext )
  779. {
  780. CG_UNION * pUnionCG;
  781. #ifdef trace_cg
  782. printf("..node_en_union,\t%s\n", GetSymName());
  783. #endif
  784. XLAT_CTXT MyContext( this, pContext );
  785. // call non-encap union processor
  786. pUnionCG = (CG_UNION *) node_union::ILxlate( pContext );
  787. pUnionCG->SetUnionFlavor( UNION_ENCAP );
  788. if ( pCommand->IsNDR64Run() )
  789. {
  790. if ( pUnionCG->GetMemorySize() >= SIZE_2GB )
  791. {
  792. SemError( this, MyContext, SIZE_EXCEEDS_2GB, NULL );
  793. exit( SIZE_EXCEEDS_2GB );
  794. }
  795. }
  796. else if (pUnionCG->GetMemoryAlignment() > 16)
  797. {
  798. SemError( this, MyContext, ENCAP_UNION_ARM_ALIGN_EXCEEDS_16, NULL );
  799. }
  800. return pUnionCG;
  801. };
  802. //--------------------------------------------------------------------
  803. //
  804. // node_def::ILxlate
  805. //
  806. // Notes:
  807. //
  808. //
  809. //
  810. //--------------------------------------------------------------------
  811. CG_CLASS *
  812. node_def::ILxlate( XLAT_CTXT * pContext )
  813. {
  814. CG_CLASS * pChildCG = NULL;
  815. XLAT_CTXT MyContext( this, pContext );
  816. node_transmit * pTransmitAttr = (node_transmit *)
  817. MyContext.ExtractAttribute( ATTR_TRANSMIT );
  818. node_wire_marshal * pWireMarshalAttr= (node_wire_marshal *)
  819. MyContext.ExtractAttribute( ATTR_WIRE_MARSHAL );
  820. node_represent_as * pRepresentAttr = (node_represent_as *)
  821. MyContext.ExtractAttribute( ATTR_REPRESENT_AS );
  822. node_user_marshal * pUserMarshalAttr= (node_user_marshal *)
  823. MyContext.ExtractAttribute( ATTR_USER_MARSHAL );
  824. node_cs_char * pCSCharAttr = (node_cs_char *)
  825. MyContext.ExtractAttribute( ATTR_CSCHAR );
  826. BOOL fEncode = (NULL !=
  827. MyContext.ExtractAttribute( ATTR_ENCODE ) );
  828. BOOL fDecode = (NULL !=
  829. MyContext.ExtractAttribute( ATTR_DECODE ) );
  830. node_guid * pGUID = (node_guid *)MyContext.ExtractAttribute(ATTR_GUID);
  831. node_version * pVer = (node_version *)MyContext.ExtractAttribute(ATTR_VERSION);
  832. node_constant_attr * pHC = (node_constant_attr *)MyContext.ExtractAttribute(ATTR_HELPCONTEXT);
  833. node_text_attr * pHelpStr = (node_text_attr *)MyContext.ExtractAttribute(ATTR_HELPSTRING);
  834. XLAT_CTXT * pIntfCtxt = (XLAT_CTXT *) MyContext.GetInterfaceContext();
  835. BOOL fIsHRESULT = IsHResultOrSCode();
  836. REUSE_INFO * pSaved;
  837. MyContext.ExtractAttribute(ATTR_HELPSTRINGCONTEXT);
  838. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  839. #ifdef trace_cg
  840. printf("..node_def,\t%s\n", GetSymName());
  841. #endif
  842. fEncode |= pIntfCtxt->FInSummary( ATTR_ENCODE );
  843. fDecode |= pIntfCtxt->FInSummary( ATTR_DECODE );
  844. // only direct children of the interface get these bits
  845. if ( !pContext->GetParent()->IsInterfaceOrObject() )
  846. {
  847. fEncode = FALSE;
  848. fDecode = FALSE;
  849. }
  850. BOOL fInLibrary = MyContext.AnyAncestorBits(IL_IN_LIBRARY);
  851. BOOL fHidden = (NULL != MyContext.ExtractAttribute(ATTR_HIDDEN));
  852. BOOL fPublic = FALSE;
  853. MyContext.ExtractAttribute(ATTR_TYPEDESCATTR);
  854. // check for public attribute
  855. node_type_attr * pTA;
  856. while ( ( pTA = (node_type_attr *)MyContext.ExtractAttribute(ATTR_TYPE) ) != 0 )
  857. {
  858. switch (pTA->GetAttr())
  859. {
  860. case TATTR_PUBLIC:
  861. fPublic = TRUE;
  862. break;
  863. default:
  864. // MIDL_ASSERT(!"Illegal attribute found on node_def during ILxlate");
  865. break;
  866. }
  867. }
  868. // clear member attributes
  869. while (MyContext.ExtractAttribute(ATTR_MEMBER));
  870. BOOL fNeedsCGTYPEDEF = fInLibrary &&
  871. (fPublic || NULL != pGUID || NULL != pVer || NULL != pHC || NULL != pHelpStr || fHidden)
  872. &&
  873. !(fEncode || fDecode || pRepresentAttr || pTransmitAttr ||
  874. pUserMarshalAttr || pWireMarshalAttr || pCSCharAttr);
  875. if (fNeedsCGTYPEDEF)
  876. {
  877. // see if we're already generated
  878. if (pReUseDict->GetReUseEntry(pSaved, this))
  879. {
  880. MyContext.ExtractAttribute( ATTR_V1_ENUM );
  881. // reuse found...
  882. pSaved->FetchInfo(&MyContext, pChildCG);
  883. pContext->ReturnSize(MyContext);
  884. return pChildCG;
  885. }
  886. }
  887. // process handle stuff
  888. if ( GetHandleKind() == HDL_CTXT )
  889. {
  890. MyContext.ExtractAttribute( ATTR_CONTEXT );
  891. }
  892. else if (GetHandleKind() == HDL_GEN)
  893. {
  894. MyContext.ExtractAttribute( ATTR_HANDLE );
  895. }
  896. ////////////////////////////////////////////////////////////////////////
  897. // process the child, except for context handles and transmit_as types
  898. if ( ( GetHandleKind() != HDL_CTXT ) && !pTransmitAttr && !pWireMarshalAttr)
  899. {
  900. pChildCG = (CG_CLASS *) GetChild()->ILxlate( &MyContext );
  901. if (NULL != pChildCG && !IsTempName( GetSymName() ) )
  902. {
  903. switch ( pChildCG->GetCGID() )
  904. {
  905. // special case transmit_as to set the presented type
  906. case ID_CG_TRANSMIT_AS:
  907. ((CG_TRANSMIT_AS *) pChildCG)->SetPresentedType( this );
  908. break;
  909. case ID_CG_COCLASS:
  910. break;
  911. // acf attributes are NOT transitive
  912. case ID_CG_REPRESENT_AS:
  913. case ID_CG_USER_MARSHAL:
  914. // odl attributes are also NOT transitive
  915. case ID_CG_TYPEDEF:
  916. break;
  917. // idl attributes ARE transitive
  918. case ID_CG_CONTEXT_HDL:
  919. case ID_CG_GENERIC_HDL:
  920. default:
  921. ((CG_NDR *)pChildCG)->SetType( this );
  922. }
  923. }
  924. // an HRESULT return type should be a CG_HRESULT
  925. if ( fIsHRESULT )
  926. {
  927. if ( !MyContext.FindAncestorContext( NODE_PARAM ) )
  928. {
  929. node_proc * pProc;
  930. WALK_CTXT * pProcCtxt =
  931. MyContext.FindAncestorContext( NODE_PROC );
  932. if ( pProcCtxt )
  933. {
  934. pProc = (node_proc *)pProcCtxt->GetParent();
  935. if ( pProc->FInSummary( ATTR_OBJECT ) ||
  936. pProc->GetMyInterfaceNode()->FInSummary( ATTR_OBJECT ) )
  937. {
  938. pChildCG = new CG_HRESULT( this, MyContext );
  939. }
  940. }
  941. }
  942. } // HRESULT tests
  943. }
  944. else if ( pTransmitAttr )
  945. {
  946. node_skl * pXmit;
  947. CG_TRANSMIT_AS * pTransCG;
  948. pXmit = pTransmitAttr->GetTransmitAsType();
  949. // get rid of dangling attributes from the non-transmitted side
  950. // we've already picked up the attributes that go with our node
  951. MyContext.ClearAttributes();
  952. pChildCG = (CG_CLASS *) pXmit->ILxlate( &MyContext );
  953. MyContext.FixMemSizes( this );
  954. // if the child had generic handle, skip that...
  955. if ( pChildCG->GetCGID() == ID_CG_GENERIC_HDL )
  956. pChildCG = (CG_CLASS*) pChildCG->GetChild();
  957. pTransCG = new CG_TRANSMIT_AS( pXmit, this, MyContext );
  958. pTransCG->SetChild( pChildCG );
  959. pChildCG = pTransCG;
  960. }
  961. else if ( pWireMarshalAttr )
  962. {
  963. // Note that this is a node like for a transmit_as attribute,
  964. // but we map it into CG_USER_MARSHAL like for a user_marshal node.
  965. // "this" is the node for the presented type.
  966. node_skl * pXmit = pWireMarshalAttr->GetWireMarshalType();
  967. // get rid of dangling attributes from the non-transmitted side
  968. // we've already picked up the attributes that go with our node
  969. MyContext.ClearAttributes();
  970. pChildCG = (CG_CLASS *) pXmit->ILxlate( &MyContext );
  971. MyContext.FixMemSizes( this );
  972. // no support for user_marshal with Oi or Oi1.
  973. // Have to use Oi2 or Os.
  974. if ( (pCommand->GetOptimizationFlags() & OPTIMIZE_INTERPRETER) &&
  975. ! (pCommand->GetOptimizationFlags() & OPTIMIZE_INTERPRETER_V2)
  976. )
  977. SemError( this, MyContext, REQUIRES_I2, "[wire_marshal]" );
  978. CG_USER_MARSHAL * pUserCG = new CG_USER_MARSHAL(
  979. pXmit,
  980. GetSymName(), // pres type name
  981. this,
  982. MyContext,
  983. TRUE // from transmit_as
  984. );
  985. pUserCG->SetChild( pChildCG );
  986. pChildCG = pUserCG;
  987. }
  988. if ( GetHandleKind() != HDL_NONE )
  989. {
  990. CG_NDR * pCG;
  991. if ( GetHandleKind() == HDL_CTXT )
  992. {
  993. MyContext.ContextHandleSizes( this );
  994. // remaining attributes are not needed e.g. pointer attrs
  995. pCG = new CG_CONTEXT_HANDLE (
  996. this,
  997. 0,
  998. MyContext
  999. );
  1000. MyContext.ClearAttributes();
  1001. }
  1002. else // HDL_GEN
  1003. {
  1004. pCG = new CG_GENERIC_HANDLE( this, NULL, MyContext );
  1005. }
  1006. pCG->SetChild( pChildCG );
  1007. pChildCG = pCG;
  1008. }
  1009. if ( pRepresentAttr )
  1010. {
  1011. node_skl * pRepT = pRepresentAttr->GetRepresentationType();
  1012. if (pRepT)
  1013. {
  1014. MyContext.FixMemSizes( pRepT );
  1015. }
  1016. CG_REPRESENT_AS * pRepCG = new CG_REPRESENT_AS(
  1017. this,
  1018. pRepresentAttr->GetRepresentationName(),
  1019. pRepT,
  1020. MyContext
  1021. );
  1022. pRepCG->SetChild( pChildCG );
  1023. pChildCG = pRepCG;
  1024. }
  1025. else if ( pUserMarshalAttr )
  1026. {
  1027. node_skl * pUserT = pUserMarshalAttr->GetRepresentationType();
  1028. if (pUserT)
  1029. {
  1030. MyContext.FixMemSizes( pUserT );
  1031. }
  1032. // no support for user_marshal with Oi or Oi1.
  1033. // Have to use Oi2 or Os.
  1034. if ( (pCommand->GetOptimizationFlags() & OPTIMIZE_INTERPRETER) &&
  1035. ! (pCommand->GetOptimizationFlags() & OPTIMIZE_INTERPRETER_V2)
  1036. )
  1037. SemError( this, MyContext, REQUIRES_I2, "[user_marshal]" );
  1038. CG_USER_MARSHAL * pUserCG = new CG_USER_MARSHAL(
  1039. this,
  1040. pUserMarshalAttr->GetRepresentationName(),
  1041. pUserT,
  1042. MyContext,
  1043. FALSE // not from transmit_as
  1044. );
  1045. pUserCG->SetChild( pChildCG );
  1046. pChildCG = pUserCG;
  1047. }
  1048. // wire marshal has to be under transmit as.
  1049. if ( fEncode || fDecode )
  1050. {
  1051. CG_TYPE_ENCODE * pPickleCG;
  1052. CG_PARAM * pParamCG;
  1053. CG_PROC * pProcCG;
  1054. pPickleCG = new CG_TYPE_ENCODE( this, fEncode, fDecode );
  1055. pPickleCG->SetChild( pChildCG );
  1056. pParamCG = new CG_PARAM( this,
  1057. 0,
  1058. MyContext,
  1059. NULL,
  1060. 0);
  1061. pParamCG->SetChild( pPickleCG );
  1062. pProcCG = new CG_TYPE_ENCODE_PROC( 0,
  1063. this,
  1064. NULL,
  1065. NULL,
  1066. 0,
  1067. 0,
  1068. 0,
  1069. 0,
  1070. 0,
  1071. NULL,
  1072. unsigned short ( pCommand->Is64BitEnv() ? OPTIMIZE_ALL_I2_FLAGS :
  1073. OPTIMIZE_INTERPRETER ),
  1074. 0,
  1075. pCommand->IsSwitchDefined( SWITCH_ROBUST ) );
  1076. pProcCG->SetChild( pParamCG );
  1077. pChildCG = (CG_CLASS *)pProcCG;
  1078. }
  1079. if ( pCSCharAttr )
  1080. {
  1081. MyContext.FixMemSizes( pCSCharAttr->GetUserType() );
  1082. }
  1083. if (fNeedsCGTYPEDEF)
  1084. {
  1085. if (NULL == pChildCG)
  1086. {
  1087. // The only way we should be able to get here is if we had a typedef
  1088. // that contained a forward reference to an interface, dispinterface, etc.
  1089. // MKTYPLIB disallowed this but we're gonna go ahead and allow it.
  1090. pChildCG = ((node_interface *)GetChild())->GetCG(TRUE);
  1091. }
  1092. CG_TYPEDEF * pTD = new CG_TYPEDEF(this, MyContext);
  1093. pTD->SetChild(pChildCG);
  1094. pChildCG = (CG_CLASS *) pTD;
  1095. // remember this node so we don't generate two of these
  1096. pSaved->SaveInfo(&MyContext, pChildCG);
  1097. }
  1098. pContext->ReturnSize( MyContext );
  1099. return pChildCG;
  1100. };
  1101. //--------------------------------------------------------------------
  1102. //
  1103. // node_pointer::ILxlate
  1104. //
  1105. // Notes:
  1106. //
  1107. //
  1108. //
  1109. //--------------------------------------------------------------------
  1110. CG_CLASS *
  1111. node_pointer::ILxlate( XLAT_CTXT * pContext )
  1112. {
  1113. node_skl* pType = GetBasicType();
  1114. CG_CLASS * pChildCG = NULL;
  1115. CG_NDR * pCG = NULL;
  1116. XLAT_CTXT MyContext( this, pContext );
  1117. PTRTYPE PtrKind = PTR_UNKNOWN;
  1118. FIELD_ATTR_INFO FAInfo;
  1119. node_allocate * pAlloc;
  1120. short AllocDetails = 0;
  1121. node_byte_count * pCountAttr;
  1122. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  1123. #ifdef trace_cg
  1124. printf("..node_pointer,\t%s\n", GetSymName());
  1125. #endif
  1126. ////////////////////////////////////////////////////////////////////////
  1127. // process misc attributes
  1128. if ( ( pAlloc = (node_allocate *) MyContext.ExtractAttribute( ATTR_ALLOCATE ) ) != 0 )
  1129. {
  1130. AllocDetails = pAlloc->GetAllocateDetails();
  1131. }
  1132. ////////////////////////////////////////////////////////////////////////
  1133. // process pointer attributes
  1134. PtrKind = MyContext.GetPtrKind();
  1135. // see if a param or return type context attr reached us...
  1136. pCountAttr = (node_byte_count *)
  1137. MyContext.ExtractAttribute( ATTR_BYTE_COUNT );
  1138. ////////////////////////////////////////////////////////////////////////
  1139. // process field attributes
  1140. // see if we have any field attributes (are conformant or varying)
  1141. FAInfo.SetControl( TRUE, pType->IsPtrOrArray() );
  1142. MyContext.ExtractFieldAttributes( &FAInfo );
  1143. FAInfo.Normalize();
  1144. switch ( FAInfo.Kind )
  1145. {
  1146. case FA_NONE:
  1147. {
  1148. if ( ( pType->NodeKind() == NODE_INTERFACE_REFERENCE || pType->IsInterfaceOrObject() )
  1149. && MyContext.AnyAncestorBits(IL_IN_LIBRARY) )
  1150. {
  1151. //This is an interface pointer without an [iid_is] attribute but in a type library.
  1152. // we don't care about the pointee
  1153. MIDL_ASSERT ( FAInfo.pIIDIsExpr == NULL );
  1154. node_skl* pIf = ( pType->NodeKind() == NODE_INTERFACE_REFERENCE ) ?
  1155. ( ( node_interface_reference* ) pType )->GetRealInterface() : pType ;
  1156. pCG = new CG_INTERFACE_POINTER( this,
  1157. (node_interface *)pIf );
  1158. node_skl* pAlias = GetChild();
  1159. if ( pType->NodeKind() != NODE_INTERFACE_REFERENCE && pAlias && pAlias->NodeKind() == NODE_DEF)
  1160. {
  1161. ( (CG_INTERFACE_POINTER* ) pCG )->SetTypeAlias( ( CG_TYPEDEF* ) pAlias->ILxlate( &MyContext ) );
  1162. }
  1163. }
  1164. else if ( pCountAttr )
  1165. {
  1166. pCG = new CG_BYTE_COUNT_POINTER( this,
  1167. PtrKind,
  1168. pCountAttr->GetByteCountParam() );
  1169. }
  1170. else
  1171. {
  1172. pCG = new CG_POINTER( this,
  1173. PtrKind,
  1174. AllocDetails );
  1175. }
  1176. break;
  1177. }
  1178. case FA_VARYING:
  1179. {
  1180. pCG = new CG_LENGTH_POINTER( this,
  1181. PtrKind,
  1182. AllocDetails,
  1183. &FAInfo );
  1184. break;
  1185. }
  1186. case FA_CONFORMANT:
  1187. {
  1188. pCG = new CG_SIZE_POINTER( this,
  1189. PtrKind,
  1190. AllocDetails,
  1191. &FAInfo );
  1192. break;
  1193. }
  1194. case FA_CONFORMANT_VARYING:
  1195. {
  1196. pCG = new CG_SIZE_LENGTH_POINTER( this,
  1197. PtrKind,
  1198. AllocDetails,
  1199. &FAInfo );
  1200. break;
  1201. }
  1202. case FA_STRING:
  1203. {
  1204. pCG = new CG_STRING_POINTER( this,
  1205. PtrKind,
  1206. AllocDetails );
  1207. if (FAInfo.StringKind == STR_BSTRING)
  1208. {
  1209. ((CG_STRING_POINTER *) pCG)->SetBStr();
  1210. }
  1211. break;
  1212. }
  1213. case FA_CONFORMANT_STRING:
  1214. {
  1215. if (FAInfo.StringKind == STR_STRING)
  1216. {
  1217. pCG = new CG_SIZE_STRING_POINTER( this,
  1218. PtrKind,
  1219. AllocDetails,
  1220. &FAInfo );
  1221. }
  1222. break;
  1223. }
  1224. case FA_INTERFACE:
  1225. {
  1226. //This is an interface pointer with an [iid_is] attribute.
  1227. // we don't care about the pointee
  1228. node_skl* pIf = ( pType->NodeKind() == NODE_INTERFACE_REFERENCE ) ?
  1229. ( ( node_interface_reference* ) pType )->GetRealInterface() : pType ;
  1230. pCG = new CG_IIDIS_INTERFACE_POINTER( this,
  1231. pIf,
  1232. FAInfo.pIIDIsExpr );
  1233. break;
  1234. }
  1235. default: // string + varying combinations
  1236. {
  1237. MIDL_ASSERT (!"Invalid pointer kind");
  1238. break;
  1239. }
  1240. }
  1241. // process any context_handle attributes from param nodes
  1242. if ( MyContext.FInSummary( ATTR_CONTEXT ) )
  1243. if ( pType->NodeKind() != NODE_POINTER )
  1244. {
  1245. MyContext.ExtractAttribute( ATTR_CONTEXT );
  1246. MyContext.ContextHandleSizes( this );
  1247. pContext->ReturnSize( MyContext );
  1248. pCG = new CG_CONTEXT_HANDLE (
  1249. this,
  1250. 0,
  1251. MyContext
  1252. );
  1253. #ifdef trace_cg
  1254. printf("..node_pointer return 1\n");
  1255. #endif
  1256. return pCG;
  1257. }
  1258. // ignore pointers do not need to be rpc-able
  1259. if ( MyContext.ExtractAttribute( ATTR_IGNORE ) )
  1260. {
  1261. MyContext.IgnoredPtrSizes();
  1262. pContext->ReturnSize( MyContext );
  1263. pCG = new CG_IGNORED_POINTER( this );
  1264. return pCG;
  1265. }
  1266. ////////////////////////////////////////////////////////////////////////
  1267. // process child
  1268. node_skl* pChild = GetChild();
  1269. if ( ( !pType->IsInterfaceOrObject() ) &&
  1270. FAInfo.Kind != FA_INTERFACE &&
  1271. !pCG->IsInterfacePointer() )
  1272. {
  1273. pChildCG = GetChild()->ILxlate( &MyContext );
  1274. }
  1275. // if we are the pointer above an interface, we should get changed
  1276. // into an interface pointer
  1277. if ( ( ( pType->NodeKind() == NODE_INTERFACE_REFERENCE ) ||
  1278. ( pType->IsInterfaceOrObject() ) ) &&
  1279. !pCG->IsInterfacePointer() )
  1280. {
  1281. pCG = (CG_NDR *)pChildCG;
  1282. pChildCG = NULL;
  1283. }
  1284. if ( pCG == 0 )
  1285. {
  1286. SemError( this, *pContext, UNDEFINED_SYMBOL, pChild->GetSymName() );
  1287. exit( UNDEFINED_SYMBOL );
  1288. }
  1289. // do a three way merge of attributes to pass to parent.
  1290. // Get a new context since the starting context was polleted with pointee attributes.
  1291. XLAT_CTXT NewPointerContext( this, pContext );
  1292. NewPointerContext.BaseTypeSizes( this );
  1293. pContext->ReturnSize( NewPointerContext);
  1294. // update sizes with the size of the pointer
  1295. pCG->SetSizesAndAlignments( NewPointerContext );
  1296. pCG->SetChild( pChildCG );
  1297. if ( HasCSType() )
  1298. {
  1299. node_def *pChild = (node_def *) GetChild();
  1300. MIDL_ASSERT( NODE_DEF == pChild->NodeKind() );
  1301. node_cs_char *p = (node_cs_char *) pChild->GetAttribute( ATTR_CSCHAR );
  1302. MIDL_ASSERT( NULL != p );
  1303. ( (CG_POINTER *) pCG )->SetCSUserType( p );
  1304. CG_NDR *pUserTypeCG = (CG_NDR *) p->GetUserType()->ILxlate( &MyContext );
  1305. p->SetElementSize( pUserTypeCG->GetMemorySize() );
  1306. }
  1307. #ifdef trace_cg
  1308. printf("..node_pointer return 2\n");
  1309. #endif
  1310. return pCG;
  1311. }
  1312. //--------------------------------------------------------------------
  1313. //
  1314. // node_array::ILxlate
  1315. //
  1316. // Notes:
  1317. //
  1318. //
  1319. //
  1320. //--------------------------------------------------------------------
  1321. CG_CLASS *
  1322. node_array::ILxlate( XLAT_CTXT * pContext )
  1323. {
  1324. CG_CLASS * pChildCG;
  1325. CG_ARRAY * pCG;
  1326. unsigned short Dimensions;
  1327. PTRTYPE PtrKind = PTR_UNKNOWN;
  1328. XLAT_CTXT MyContext( this, pContext );
  1329. FIELD_ATTR_INFO FAInfo;
  1330. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  1331. #ifdef trace_cg
  1332. printf("..node_array,\t%s\n", GetSymName());
  1333. #endif
  1334. // process any context_handle attributes from param nodes
  1335. if ( MyContext.ExtractAttribute( ATTR_CONTEXT ) )
  1336. {
  1337. CG_NDR * pCG;
  1338. MyContext.ContextHandleSizes( this );
  1339. pContext->ReturnSize( MyContext );
  1340. pCG = new CG_CONTEXT_HANDLE (
  1341. this,
  1342. 0,
  1343. MyContext
  1344. );
  1345. return pCG;
  1346. }
  1347. ////////////////////////////////////////////////////////////////////////
  1348. // process pointer attributes
  1349. PtrKind = MyContext.GetPtrKind();
  1350. MIDL_ASSERT( PtrKind != PTR_UNKNOWN );
  1351. // see if we have any field attributes (are conformant or varying)
  1352. FAInfo.SetControl( FALSE, GetChild()->IsPtrOrArray() );
  1353. MyContext.ExtractFieldAttributes( &FAInfo );
  1354. FAInfo.Normalize( pLowerBound, pUpperBound );
  1355. // The 64bit transfer syntax has it's own mechanism
  1356. // for propagating conformant/variance among array dimensions.
  1357. if ( !pCommand->IsNDR64Run() )
  1358. {
  1359. // if we are multi-dimensional, absorb parent information
  1360. if ( MyContext.AnyAncestorBits( IL_IN_MULTIDIM_CONF ) )
  1361. FAInfo.Kind |= FA_CONFORMANT;
  1362. // don't propogate varying down into a string
  1363. if ( MyContext.AnyAncestorBits( IL_IN_MULTIDIM_VAR ) &&
  1364. ( ( FAInfo.Kind & FA_STRING ) == 0 ))
  1365. FAInfo.Kind |= FA_VARYING;
  1366. }
  1367. // if our child is also an array, tell it about us
  1368. if ( GetBasicType()->NodeKind() == NODE_ARRAY )
  1369. {
  1370. if ( FAInfo.Kind & FA_CONFORMANT )
  1371. MyContext.SetAncestorBits( IL_IN_MULTIDIM_CONF );
  1372. if ( FAInfo.Kind & FA_VARYING )
  1373. MyContext.SetAncestorBits( IL_IN_MULTIDIM_VAR );
  1374. }
  1375. else
  1376. {
  1377. MyContext.ClearAncestorBits( IL_IN_MULTIDIM_CONF | IL_IN_MULTIDIM_VAR );
  1378. }
  1379. // process the child
  1380. pChildCG = GetChild()->ILxlate( &MyContext );
  1381. MyContext.ArraySize( this, &FAInfo );
  1382. // fetch # of dimensions from child;
  1383. if ( pChildCG->IsArray() )
  1384. {
  1385. Dimensions = unsigned short ( ( (CG_ARRAY *) pChildCG )->GetDimensions() + 1 );
  1386. // force all inner dimensions to be REF
  1387. ( (CG_ARRAY *) pChildCG )->SetPtrType( PTR_REF );
  1388. }
  1389. else
  1390. {
  1391. Dimensions = 1;
  1392. }
  1393. // force embedded arrays to be REF
  1394. if ( PtrKind != PTR_REF )
  1395. {
  1396. WALK_CTXT * pUpperCtxt = MyContext.GetParentContext();
  1397. while ( pUpperCtxt )
  1398. {
  1399. NODE_T Kind = pUpperCtxt->GetParent()->NodeKind();
  1400. if ( Kind == NODE_PARAM )
  1401. break;
  1402. else if ( Kind == NODE_DEF )
  1403. {
  1404. node_def * pNode = (node_def *) pUpperCtxt->GetParent();
  1405. if ( pNode->FInSummary( ATTR_TRANSMIT ) ||
  1406. pNode->FInSummary( ATTR_REPRESENT_AS ) )
  1407. {
  1408. PtrKind = PTR_REF;
  1409. break;
  1410. }
  1411. // else go up another level
  1412. }
  1413. else
  1414. {
  1415. PtrKind = PTR_REF;
  1416. break;
  1417. }
  1418. pUpperCtxt = pUpperCtxt->GetParentContext();
  1419. }
  1420. }
  1421. switch ( FAInfo.Kind )
  1422. {
  1423. case FA_NONE:
  1424. {
  1425. pCG = new CG_FIXED_ARRAY( this,
  1426. &FAInfo,
  1427. Dimensions,
  1428. MyContext );
  1429. break;
  1430. }
  1431. case FA_VARYING:
  1432. {
  1433. pCG = new CG_VARYING_ARRAY( this,
  1434. &FAInfo,
  1435. Dimensions,
  1436. MyContext );
  1437. break;
  1438. }
  1439. case FA_CONFORMANT:
  1440. {
  1441. pCG = new CG_CONFORMANT_ARRAY( this,
  1442. &FAInfo,
  1443. Dimensions,
  1444. MyContext );
  1445. break;
  1446. }
  1447. case FA_CONFORMANT_VARYING:
  1448. {
  1449. pCG = new CG_CONFORMANT_VARYING_ARRAY( this,
  1450. &FAInfo,
  1451. Dimensions,
  1452. MyContext );
  1453. break;
  1454. }
  1455. case FA_STRING:
  1456. {
  1457. pCG = new CG_STRING_ARRAY( this,
  1458. &FAInfo,
  1459. Dimensions,
  1460. MyContext );
  1461. break;
  1462. }
  1463. case FA_CONFORMANT_STRING:
  1464. {
  1465. pCG = new CG_CONFORMANT_STRING_ARRAY( this,
  1466. &FAInfo,
  1467. Dimensions,
  1468. MyContext );
  1469. break;
  1470. }
  1471. default: // string + varying combinations
  1472. {
  1473. MIDL_ASSERT (!"invalid conf/var combination");
  1474. break;
  1475. }
  1476. }
  1477. pContext->ReturnSize( MyContext );
  1478. pCG->SetPtrType( PtrKind );
  1479. if ( HasCSType() )
  1480. {
  1481. node_def *pChild = (node_def *) GetChild();
  1482. MIDL_ASSERT( NODE_DEF == pChild->NodeKind() );
  1483. node_cs_char *p = (node_cs_char *) pChild->GetAttribute( ATTR_CSCHAR );
  1484. MIDL_ASSERT( NULL != p );
  1485. ( (CG_ARRAY *) pCG )->SetCSUserType( p );
  1486. CG_NDR *pUserTypeCG = (CG_NDR *) p->GetUserType()->ILxlate( &MyContext );
  1487. p->SetElementSize( pUserTypeCG->GetMemorySize() );
  1488. }
  1489. pCG->SetChild( pChildCG );
  1490. if ( pCommand->IsNDR64Run() )
  1491. {
  1492. if ( pCG->GetMemorySize() >= SIZE_2GB )
  1493. {
  1494. SemError( this, MyContext, SIZE_EXCEEDS_2GB, NULL );
  1495. exit( SIZE_EXCEEDS_2GB );
  1496. }
  1497. }
  1498. return pCG;
  1499. };