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.

910 lines
24 KiB

  1. /*****************************************************************************/
  2. /** Microsoft LAN Manager **/
  3. /** Copyright(c) Microsoft Corp., 1987-1999 **/
  4. /*****************************************************************************/
  5. /*****************************************************************************
  6. File : nodeskl.cxx
  7. Title : skeletal node build routines
  8. History :
  9. 04-Aug-1991 VibhasC Created
  10. *****************************************************************************/
  11. #pragma warning ( disable : 4514 )
  12. /****************************************************************************
  13. local defines and includes
  14. ****************************************************************************/
  15. #include "nulldefs.h"
  16. extern "C"
  17. {
  18. #include <stdio.h>
  19. #include <string.h>
  20. }
  21. #include "allnodes.hxx"
  22. #include "gramutil.hxx"
  23. #include "cmdana.hxx"
  24. #include "attrnode.hxx"
  25. #include "ndrtypes.h"
  26. #include "lextable.hxx"
  27. #include "control.hxx"
  28. inline
  29. unsigned short ComputeAlignmentForZP( unsigned short Align, unsigned short ZeePee, BOOL IsMustAlign)
  30. {
  31. return ((Align > ZeePee) && !IsMustAlign) ? ZeePee : Align;
  32. }
  33. inline
  34. unsigned long RoundToAlignment( unsigned long Size, unsigned short Align)
  35. {
  36. Align--;
  37. return (Size + Align) & ~Align;
  38. }
  39. /****************************************************************************
  40. external data
  41. ****************************************************************************/
  42. extern CMD_ARG * pCommand;
  43. extern node_e_attr * pErrorAttrNode;
  44. extern node_error * pErrorTypeNode;
  45. extern SymTable * pBaseSymTbl;
  46. extern IDICT * pInterfaceDict;
  47. extern ISTACK * pZpStack;
  48. extern LexTable * pMidlLexTable;
  49. extern CCONTROL * pCompiler;
  50. /****************************************************************************
  51. external procs
  52. ****************************************************************************/
  53. extern BOOL IsTempName( char * );
  54. extern void ParseError( STATUS_T, char * );
  55. /****************************************************************************/
  56. void
  57. MEMLIST::SetMembers( class SIBLING_LIST & MEMLIST )
  58. {
  59. pMembers = MEMLIST.Linearize();
  60. }
  61. void
  62. MEMLIST::MergeMembersToTail( class SIBLING_LIST & MEMLIST )
  63. {
  64. AddLastMember( MEMLIST.Linearize() );
  65. }
  66. STATUS_T
  67. MEMLIST::GetMembers( class type_node_list * MEMLIST )
  68. {
  69. named_node * pCur = pMembers;
  70. while ( pCur )
  71. {
  72. MEMLIST->SetPeer( pCur );
  73. pCur = pCur->GetSibling();
  74. }
  75. return (pMembers)? STATUS_OK: I_ERR_NO_MEMBER;
  76. };
  77. short
  78. MEMLIST::GetNumberOfArguments()
  79. {
  80. short count = 0;
  81. named_node * pNext = pMembers;
  82. while ( pNext )
  83. {
  84. count++;
  85. pNext = pNext->GetSibling();
  86. };
  87. return count;
  88. };
  89. // add a new member onto the very tail
  90. void
  91. MEMLIST::AddLastMember( named_node * pNode )
  92. {
  93. named_node * pPrev = NULL;
  94. named_node * pCur = pMembers;
  95. while ( pCur )
  96. {
  97. pPrev = pCur;
  98. pCur = pCur->GetSibling();
  99. }
  100. // pPrev is now null (empty list) or points to last element of list
  101. if ( pPrev )
  102. {
  103. pPrev->SetSibling( pNode );
  104. }
  105. else
  106. {
  107. pMembers = pNode;
  108. }
  109. }
  110. // Remove the last member from the tail
  111. void
  112. MEMLIST::RemoveLastMember()
  113. {
  114. named_node * pPrev = NULL;
  115. named_node * pCur = pMembers;
  116. while ( pCur && pCur->GetSibling() )
  117. {
  118. pPrev = pCur;
  119. pCur = pCur->GetSibling();
  120. }
  121. // pPrev is now null (empty list) or points to next to last element of list
  122. if ( pPrev )
  123. {
  124. pPrev->SetSibling( NULL);
  125. }
  126. }
  127. void
  128. MEMLIST::AddSecondMember( named_node * pNode )
  129. {
  130. named_node* pFirst = (named_node*)GetFirstMember();
  131. if ( pFirst )
  132. {
  133. named_node* pSecond = pFirst->GetSibling();
  134. pFirst->SetSibling( pNode );
  135. pNode->SetSibling( pSecond );
  136. }
  137. else
  138. {
  139. pMembers = pNode;
  140. }
  141. }
  142. /****************************************************************************
  143. node_id:
  144. the private memory allocator
  145. ****************************************************************************/
  146. // initialize the memory allocators for node_id and node_id_fe
  147. FreeListMgr
  148. node_id::MyFreeList( sizeof (node_id ) );
  149. FreeListMgr
  150. node_id_fe::MyFreeList( sizeof (node_id_fe ) );
  151. FRONT_MEMORY_INFO
  152. node_skl::AdjustMemoryInfoForModifiers(FRONT_MEMORY_INFO OrigInfo)
  153. {
  154. if (!GetModifiers().IsModifierSet(ATTR_DECLSPEC_ALIGN))
  155. return OrigInfo;
  156. OrigInfo.IsMustAlign = TRUE;
  157. OrigInfo.Align = __max(OrigInfo.Align, GetModifiers().GetDeclspecAlign());
  158. return OrigInfo;
  159. }
  160. FRONT_MEMORY_INFO
  161. node_skl::GetModifiedMemoryInfoFromChild()
  162. {
  163. node_skl *pChild = GetChild();
  164. MIDL_ASSERT( pChild );
  165. return AdjustMemoryInfoForModifiers( pChild->GetMemoryInfo() );
  166. }
  167. FRONT_MEMORY_INFO
  168. node_skl::GetInvalidMemoryInfo()
  169. {
  170. return FRONT_MEMORY_INFO(0, 1, 0);
  171. }
  172. FRONT_MEMORY_INFO
  173. node_enum::GetMemoryInfo()
  174. {
  175. unsigned long EnumSize = pCommand->GetEnumSize();
  176. return AdjustMemoryInfoForModifiers( FRONT_MEMORY_INFO( EnumSize, (short)EnumSize, 0 ) );
  177. }
  178. FRONT_MEMORY_INFO
  179. node_pointer::GetMemoryInfo()
  180. {
  181. unsigned long PointerSize = SIZEOF_MEM_PTR();
  182. return AdjustMemoryInfoForModifiers( FRONT_MEMORY_INFO( PointerSize, (short)PointerSize, 0 ) );
  183. }
  184. FRONT_MEMORY_INFO
  185. node_safearray::GetMemoryInfo()
  186. {
  187. unsigned long PointerSize = SIZEOF_MEM_PTR();
  188. return AdjustMemoryInfoForModifiers( FRONT_MEMORY_INFO( PointerSize, (short)PointerSize, 0 ) );
  189. }
  190. FRONT_MEMORY_INFO
  191. node_union::GetMemoryInfo()
  192. {
  193. // The size of a union is the size of the largest element rounded
  194. // to the largest alignment.
  195. FRONT_MEMORY_INFO UnionSize(0, 1, 0);
  196. unsigned short ZeePee = GetZeePee();
  197. MEM_ITER MemIter( this );
  198. node_skl * pNode;
  199. while ( ( pNode = MemIter.GetNext() ) != NULL )
  200. {
  201. FRONT_MEMORY_INFO TempSize = pNode->GetMemoryInfo();
  202. // Merge in the size of the new union arm.
  203. UnionSize.Size = __max(UnionSize.Size, TempSize.Size);
  204. UnionSize.Align = __max(UnionSize.Align, TempSize.Align);
  205. UnionSize.IsMustAlign = (UnionSize.IsMustAlign || TempSize.IsMustAlign);
  206. }
  207. // Add padding to end of union.
  208. UnionSize = AdjustMemoryInfoForModifiers(UnionSize);
  209. UnionSize.Align = ComputeAlignmentForZP( UnionSize.Align, ZeePee, UnionSize.IsMustAlign );
  210. UnionSize.Size = RoundToAlignment( UnionSize.Size, UnionSize.Align );
  211. return UnionSize;
  212. }
  213. FRONT_MEMORY_INFO
  214. node_array::GetMemoryInfo()
  215. {
  216. // The size of an array is the size of the array element times the element count.
  217. FRONT_MEMORY_INFO ArraySize = GetChild()->GetMemoryInfo();
  218. unsigned long ArrayElements;
  219. if ( pUpperBound && ( pUpperBound != (expr_node *) -1) )
  220. {
  221. ArrayElements = (ulong)pUpperBound->Evaluate();
  222. }
  223. else
  224. {
  225. // A conformant array is not sized.
  226. ArrayElements = 0;
  227. }
  228. ArraySize.Size *= ArrayElements;
  229. return AdjustMemoryInfoForModifiers(ArraySize);
  230. }
  231. FRONT_MEMORY_INFO
  232. node_struct::GetMemoryInfo()
  233. {
  234. // The alignment of a structure is the largest alignment of all the members.
  235. // Each structure is aligned according to the following rules.
  236. // 1. If the field is a must align, the field is aligned to the Alignment.
  237. // 2. If the field is not a must align, the field is aligned to min(Zp, Alignment).
  238. MEM_ITER MemIter( this );
  239. unsigned short ZeePee = GetZeePee();
  240. FRONT_MEMORY_INFO StructSize(0,1,0);
  241. node_skl * pNode;
  242. while ( ( pNode = MemIter.GetNext() ) != 0 )
  243. {
  244. FRONT_MEMORY_INFO FieldSize = pNode->GetMemoryInfo();
  245. FieldSize.Align = ComputeAlignmentForZP( FieldSize.Align, ZeePee, FieldSize.IsMustAlign );
  246. StructSize.Size = RoundToAlignment( StructSize.Size, FieldSize.Align );
  247. // StructSize.Size now contains the offset of the field.
  248. // Merge in the attributes from the member
  249. StructSize.Size += FieldSize.Size;
  250. StructSize.Align = __max( FieldSize.Align, StructSize.Align );
  251. StructSize.IsMustAlign = ( StructSize.IsMustAlign || FieldSize.IsMustAlign );
  252. }
  253. // Add padding to end of structure.
  254. StructSize = AdjustMemoryInfoForModifiers( StructSize );
  255. StructSize.Align = ComputeAlignmentForZP( StructSize.Align, ZeePee, StructSize.IsMustAlign );
  256. StructSize.Size = RoundToAlignment( StructSize.Size, StructSize.Align );
  257. return StructSize;
  258. }
  259. FRONT_MEMORY_INFO
  260. node_def::GetMemoryInfo()
  261. {
  262. FRONT_MEMORY_INFO TypedefSize;
  263. node_represent_as *pRep = (node_represent_as *)GetAttribute(ATTR_REPRESENT_AS);
  264. node_user_marshal *pUserMarshall = (node_user_marshal *)GetAttribute(ATTR_USER_MARSHAL);
  265. node_cs_char *pCSChar = (node_cs_char *) GetAttribute(ATTR_CSCHAR);
  266. if (!pUserMarshall && !pRep && !pCSChar)
  267. {
  268. // Just use the modified child sizes.
  269. return GetModifiedMemoryInfoFromChild();
  270. }
  271. if (pCSChar)
  272. {
  273. MIDL_ASSERT( NULL != pCSChar->GetUserType() );
  274. return AdjustMemoryInfoForModifiers(
  275. pCSChar->GetUserType()->GetMemoryInfo() );
  276. }
  277. // If both user_marshal and represent_as are specified, use represent_as and let semantic
  278. // analysis flag the error.
  279. if (pUserMarshall)
  280. pRep = pUserMarshall;
  281. node_skl *pNode = pRep->GetRepresentationType();
  282. if (!pNode)
  283. {
  284. // unknown type. Use 0 as the size.
  285. TypedefSize.Init(0, 1, 0);
  286. }
  287. else
  288. {
  289. TypedefSize = pNode->GetMemoryInfo();
  290. }
  291. return AdjustMemoryInfoForModifiers(TypedefSize);
  292. }
  293. FRONT_MEMORY_INFO
  294. node_label::GetMemoryInfo()
  295. {
  296. return AdjustMemoryInfoForModifiers( FRONT_MEMORY_INFO(sizeof(short), (short)sizeof(short), 0) );
  297. }
  298. FRONT_MEMORY_INFO
  299. node_base_type::GetMemoryInfo()
  300. {
  301. unsigned long size;
  302. switch( NodeKind() )
  303. {
  304. case NODE_FLOAT: size = sizeof(float); break;
  305. case NODE_DOUBLE: size = sizeof(double); break;
  306. case NODE_FLOAT80: size = 16; break; //BUG, BUG double check once
  307. //VC supports this
  308. case NODE_FLOAT128: size = 16; break;
  309. case NODE_HYPER: size = sizeof(__int64); break;
  310. case NODE_INT64: size = sizeof(__int64); break;
  311. case NODE_INT128: size = 16; break;
  312. case NODE_INT3264: size = SIZEOF_MEM_INT3264(); break;
  313. case NODE_INT32: size = sizeof(long); break;
  314. case NODE_LONG: size = sizeof(long); break;
  315. case NODE_LONGLONG: size = sizeof(LONGLONG); break;
  316. case NODE_SHORT: size = sizeof(short); break;
  317. case NODE_INT: size = sizeof(int); break;
  318. case NODE_SMALL: size = sizeof(char); break;
  319. case NODE_CHAR: size = sizeof(char); break;
  320. case NODE_BOOLEAN: size = sizeof(char); break;
  321. case NODE_BYTE: size = sizeof(char); break;
  322. case NODE_HANDLE_T: size = SIZEOF_MEM_PTR(); break;
  323. case NODE_VOID:
  324. return AdjustMemoryInfoForModifiers(FRONT_MEMORY_INFO(0, 1, 0));
  325. default:
  326. size = 0;
  327. MIDL_ASSERT(0);
  328. }
  329. return AdjustMemoryInfoForModifiers(FRONT_MEMORY_INFO(size, (short)size, 0));
  330. }
  331. FRONT_MEMORY_INFO
  332. node_href::GetMemoryInfo()
  333. {
  334. node_skl *pChild = Resolve();
  335. MIDL_ASSERT(pChild);
  336. return AdjustMemoryInfoForModifiers(pChild->GetMemoryInfo());
  337. }
  338. /***************************************************************************
  339. GetBasicType:
  340. Get the basic type of the typenode
  341. ***************************************************************************/
  342. node_skl *
  343. node_skl::GetBasicType()
  344. {
  345. node_skl * pChildPtr;
  346. switch( NodeKind() )
  347. {
  348. case NODE_STRUCT:
  349. case NODE_ENUM:
  350. case NODE_UNION:
  351. return this;
  352. case NODE_ID:
  353. return GetChild();
  354. default:
  355. if ( ( pChildPtr = GetChild() ) != 0 )
  356. {
  357. if ( pChildPtr->NodeKind() == NODE_DEF ||
  358. pChildPtr->NodeKind() == NODE_FORWARD ||
  359. pChildPtr->NodeKind() == NODE_HREF )
  360. return pChildPtr->GetBasicType();
  361. return pChildPtr;
  362. }
  363. return this;
  364. }
  365. }
  366. /***************************************************************************
  367. GetMyInterfaceNode:
  368. Get the interface node for the typenode
  369. ***************************************************************************/
  370. node_interface *
  371. node_skl::GetMyInterfaceNode()
  372. {
  373. return (node_interface *) pInterfaceDict->GetElement( IntfKey );
  374. }
  375. void
  376. node_interface::ResetCGIfNecessary()
  377. {
  378. if ( !fIs2ndCodegen &&
  379. pCompiler->GetPassNumber() == NDR64_ILXLAT_PASS )
  380. {
  381. fIs2ndCodegen = TRUE;
  382. SetCG(TRUE,NULL);
  383. SetCG(FALSE,NULL);
  384. }
  385. }
  386. node_file *
  387. node_skl::GetDefiningFile()
  388. {
  389. if (GetMyInterfaceNode())
  390. return GetMyInterfaceNode()->GetFileNode();
  391. else
  392. return NULL;
  393. }
  394. node_skl*
  395. node_skl::GetDuplicateGuid (
  396. node_guid* pGuid,
  397. SymTable* pUUIDTable
  398. )
  399. {
  400. node_skl* pDuplicate = 0;
  401. if ( pGuid )
  402. {
  403. char * GuidStr = pGuid->GetGuidString();
  404. SymKey SKey(GuidStr, NAME_DEF);
  405. if ( !pUUIDTable->SymInsert( SKey, 0, (named_node*) this) )
  406. {
  407. pDuplicate = pUUIDTable->SymSearch( SKey );
  408. }
  409. }
  410. return ( pDuplicate == this ) ? 0 : pDuplicate;
  411. }
  412. /*****************************************************************************
  413. utility functions
  414. *****************************************************************************/
  415. BOOL
  416. COMPARE_ATTR(
  417. ATTR_VECTOR & A1,
  418. ATTR_VECTOR & A2 )
  419. {
  420. int i;
  421. for( i = 0; i < MAX_ATTR_SUMMARY_ELEMENTS; ++i )
  422. {
  423. if( (A1[ i ] & A2[ i ] ) != A2[i] )
  424. return FALSE;
  425. }
  426. return TRUE;
  427. }
  428. void
  429. OR_ATTR(
  430. ATTR_VECTOR & A1,
  431. ATTR_VECTOR & A2 )
  432. {
  433. int i;
  434. for( i= 0; i < MAX_ATTR_SUMMARY_ELEMENTS; ++i )
  435. {
  436. A1[ i ] |= A2[ i ];
  437. }
  438. }
  439. void
  440. XOR_ATTR(
  441. ATTR_VECTOR & A1,
  442. ATTR_VECTOR & A2 )
  443. {
  444. int i;
  445. for( i= 0; i < MAX_ATTR_SUMMARY_ELEMENTS; ++i )
  446. {
  447. A1[ i ] ^= A2[ i ];
  448. }
  449. }
  450. void
  451. CLEAR_ATTR(
  452. ATTR_VECTOR & A1 )
  453. {
  454. int i;
  455. for( i= 0; i < MAX_ATTR_SUMMARY_ELEMENTS; ++i )
  456. {
  457. A1[ i ] = 0;
  458. }
  459. }
  460. void
  461. SET_ALL_ATTR(
  462. ATTR_VECTOR & A1 )
  463. {
  464. int i;
  465. for( i= 0; i < MAX_ATTR_SUMMARY_ELEMENTS; ++i )
  466. {
  467. A1[ i ] = 0xffffffff;
  468. }
  469. }
  470. ATTR_T
  471. CLEAR_FIRST_SET_ATTR ( ATTR_VECTOR & A)
  472. {
  473. int i;
  474. unsigned long mask;
  475. short at;
  476. for ( i = 0; i < MAX_ATTR_SUMMARY_ELEMENTS; ++i )
  477. {
  478. for ( at = 0, mask = 1;
  479. mask != 0;
  480. ++at, mask = mask<<1 )
  481. {
  482. if ( mask & A[i] )
  483. {
  484. A[i] &= ~mask;
  485. return (ATTR_T) (at + ( i * 32 ));
  486. }
  487. }
  488. }
  489. return ATTR_NONE;
  490. }
  491. BOOL
  492. node_base_type::IsUnsigned()
  493. {
  494. // make obvious choices
  495. if ( FInSummary( ATTR_UNSIGNED ) )
  496. return TRUE;
  497. if ( FInSummary( ATTR_SIGNED ) )
  498. return FALSE;
  499. // unspec'd char is always unsigned
  500. if ( NodeKind() == NODE_CHAR )
  501. {
  502. return TRUE;
  503. }
  504. // unspec'd small is always signed
  505. else if ( NodeKind() == NODE_SMALL )
  506. {
  507. return FALSE;
  508. }
  509. // the cracks...
  510. return FALSE;
  511. }
  512. EXPR_VALUE
  513. node_base_type::ConvertMyKindOfValueToEXPR_VALUE( EXPR_VALUE value )
  514. {
  515. // make obvious choice
  516. if ( FInSummary( ATTR_UNSIGNED ) )
  517. return value;
  518. // small values are irrelevant
  519. if ( (value & 0xffffff80) == 0 )
  520. return value;
  521. // handle default signedness
  522. // simple type should be converted to int in expression evaluation.
  523. switch ( NodeKind() )
  524. {
  525. case NODE_CHAR:
  526. if ( !FInSummary( ATTR_SIGNED ) )
  527. return value;
  528. // fall through to sign extend
  529. case NODE_SMALL:
  530. {
  531. signed int ch = (signed int) value;
  532. return (EXPR_VALUE) ch;
  533. }
  534. case NODE_SHORT:
  535. {
  536. signed int sh = (signed int) value;
  537. return (EXPR_VALUE) sh;
  538. }
  539. case NODE_LONG:
  540. case NODE_INT32:
  541. case NODE_INT:
  542. {
  543. signed long lng = (signed long) value;
  544. return (EXPR_VALUE) lng;
  545. }
  546. case NODE_INT3264:
  547. {
  548. if ( ! pCommand->Is64BitEnv() )
  549. {
  550. signed long lng = (signed long) value;
  551. return (EXPR_VALUE) lng;
  552. }
  553. }
  554. }
  555. return value;
  556. }
  557. BOOL
  558. named_node::IsNamedNode()
  559. {
  560. return ( ( pName ) && !IsTempName( pName ) );
  561. };
  562. // return the transmit_as type (or NULL)
  563. node_skl *
  564. node_def::GetTransmittedType()
  565. {
  566. ta * pXmit = (ta *) GetAttribute( ATTR_TRANSMIT );
  567. /*
  568. Rkk just in case
  569. */
  570. if ( !pXmit )
  571. pXmit = (ta *) GetAttribute( ATTR_WIRE_MARSHAL );
  572. // allow for transitive xmit_as
  573. if ( !pXmit && ( GetChild()->NodeKind() == NODE_DEF ) )
  574. return ((node_def*)GetChild())->GetTransmittedType();
  575. return (pXmit) ? pXmit->GetType() : NULL;
  576. }
  577. // return the represent_as type (or NULL)
  578. char *
  579. node_def::GetRepresentationName()
  580. {
  581. node_represent_as * pRep =
  582. (node_represent_as *) GetAttribute( ATTR_REPRESENT_AS );
  583. if ( !pRep )
  584. pRep = (node_represent_as *) GetAttribute( ATTR_USER_MARSHAL );
  585. return (pRep) ? pRep->GetRepresentationName() : NULL;
  586. }
  587. // link self on as new top node
  588. void
  589. node_pragma_pack::Push( node_pragma_pack *& pTop )
  590. {
  591. pStackLink = pTop;
  592. pTop = this;
  593. }
  594. // search for matching push and pop it off, returning new ZP
  595. unsigned short
  596. node_pragma_pack::Pop( node_pragma_pack *& pTop )
  597. {
  598. unsigned short result = 0;
  599. if ( pString )
  600. {
  601. while ( pTop->PackType != PRAGMA_PACK_GARBAGE )
  602. {
  603. if ( pTop->pString &&
  604. !strcmp( pTop->pString, pString ) )
  605. {
  606. result = pTop->usPackingLevel;
  607. pTop = pTop->pStackLink;
  608. return result;
  609. }
  610. pTop = pTop->pStackLink;
  611. }
  612. }
  613. else
  614. {
  615. if ( pTop->PackType != PRAGMA_PACK_GARBAGE )
  616. {
  617. result = pTop->usPackingLevel;
  618. pTop = pTop->pStackLink;
  619. }
  620. }
  621. return result;
  622. }
  623. // routines to save the pragma stack across files
  624. class PRAGMA_FILE_STACK_ELEMENT
  625. {
  626. public:
  627. node_pragma_pack * pPackStack;
  628. unsigned short SavedZp;
  629. PRAGMA_FILE_STACK_ELEMENT( node_pragma_pack * pSt,
  630. unsigned short usZp )
  631. {
  632. pPackStack = pSt;
  633. SavedZp = usZp;
  634. }
  635. };
  636. void
  637. PushZpStack( node_pragma_pack * & PackStack,
  638. unsigned short & CurrentZp )
  639. {
  640. PRAGMA_FILE_STACK_ELEMENT * pSave = new PRAGMA_FILE_STACK_ELEMENT (
  641. PackStack, CurrentZp );
  642. pZpStack->Push( (IDICTELEMENT) pSave );
  643. // make new zp stack and start new file with command line Zp
  644. PackStack = new node_pragma_pack( NULL,
  645. pCommand->GetZeePee(),
  646. PRAGMA_PACK_GARBAGE );
  647. CurrentZp = pCommand->GetZeePee();
  648. }
  649. // restore the Zp stack and current Zp on returning from imported file
  650. void
  651. PopZpStack( node_pragma_pack * & PackStack,
  652. unsigned short & CurrentZp )
  653. {
  654. PRAGMA_FILE_STACK_ELEMENT * pSaved = (PRAGMA_FILE_STACK_ELEMENT *)
  655. pZpStack->Pop();
  656. PackStack = pSaved->pPackStack;
  657. CurrentZp = pSaved->SavedZp;
  658. }
  659. BOOL MODIFIER_SET::IsFlagAModifier(ATTR_T flag) const
  660. {
  661. return (flag >= ATTR_CPORT_ATTRIBUTES_START && flag <= ATTR_CPORT_ATTRIBUTES_END);
  662. }
  663. BOOL MODIFIER_SET::IsModifierSet(ATTR_T flag) const
  664. {
  665. return (BOOL)( ModifierBits & SetModifierBit( flag ) );
  666. }
  667. BOOL MODIFIER_SET::AnyModifiersSet() const
  668. {
  669. return ModifierBits != 0;
  670. }
  671. void MODIFIER_SET::SetModifier(ATTR_T flag)
  672. {
  673. ModifierBits |= SetModifierBit( flag );
  674. }
  675. void MODIFIER_SET::ClearModifier(ATTR_T flag)
  676. {
  677. unsigned _int64 ModifierMask = SetModifierBit( flag );
  678. ModifierBits &= ~ModifierMask;
  679. if (ATTR_DECLSPEC_ALIGN == flag)
  680. Align = 0;
  681. }
  682. void MODIFIER_SET::SetDeclspecAlign( unsigned short NewAlign)
  683. {
  684. SetModifier( ATTR_DECLSPEC_ALIGN);
  685. Align = NewAlign;
  686. }
  687. unsigned short MODIFIER_SET::GetDeclspecAlign() const
  688. {
  689. if ( !IsModifierSet( ATTR_DECLSPEC_ALIGN ) )
  690. return 1;
  691. return Align;
  692. }
  693. void MODIFIER_SET::SetDeclspecUnknown(char *pNewUnknownTxt)
  694. {
  695. pUnknownTxt = pMidlLexTable->LexInsert(pNewUnknownTxt);
  696. SetModifier( ATTR_DECLSPEC_UNKNOWN );
  697. return;
  698. }
  699. char *MODIFIER_SET::GetDeclspecUnknown() const
  700. {
  701. if ( !IsModifierSet( ATTR_DECLSPEC_UNKNOWN ) )
  702. return " ";
  703. return pUnknownTxt;
  704. }
  705. void MODIFIER_SET::Clear()
  706. {
  707. ModifierBits = 0; Align = 0; pUnknownTxt = 0;
  708. }
  709. void MODIFIER_SET::Merge(const MODIFIER_SET & MergeModifierSet)
  710. {
  711. if ( MergeModifierSet.IsModifierSet( ATTR_DECLSPEC_ALIGN ) )
  712. {
  713. if (! IsModifierSet( ATTR_DECLSPEC_ALIGN ) )
  714. {
  715. Align = MergeModifierSet.Align;
  716. }
  717. else
  718. {
  719. Align = __max(MergeModifierSet.Align, Align);
  720. }
  721. }
  722. if (MergeModifierSet.pUnknownTxt)
  723. {
  724. if (!pUnknownTxt)
  725. {
  726. pUnknownTxt = MergeModifierSet.pUnknownTxt;
  727. }
  728. else
  729. {
  730. size_t StrSize = strlen(MergeModifierSet.pUnknownTxt);
  731. StrSize += strlen(pUnknownTxt) + 1;
  732. char *pNewText = new char[StrSize];
  733. strcpy(pNewText, pUnknownTxt);
  734. strcat(pNewText, MergeModifierSet.pUnknownTxt);
  735. pUnknownTxt = pMidlLexTable->LexInsert(pNewText);
  736. delete[] pNewText;
  737. }
  738. }
  739. ModifierBits |= MergeModifierSet.ModifierBits;
  740. }
  741. void MODIFIER_SET::PrintDebugInfo() const
  742. {
  743. printf("Modifiers: 0x%I64X\n", ModifierBits);
  744. printf("Align: %u\n", Align);
  745. if (pUnknownTxt)
  746. {
  747. printf("UnknownTxt: %s\n", pUnknownTxt);
  748. }
  749. }