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.

6685 lines
217 KiB

  1. /*****************************************************************************/
  2. /** Microsoft LAN Manager **/
  3. /** Copyright(c) Microsoft Corp., 1987-1999 **/
  4. /*****************************************************************************/
  5. /*****************************************************************************
  6. File : grammar.y
  7. Title : the midl grammar file
  8. :
  9. Description: contains the syntactic and semantic handling of the
  10. : idl file
  11. History :
  12. 08-Aug-1991 VibhasC Create
  13. 15-Sep-1993 GregJen Rewrite for MIDL 2.0
  14. *****************************************************************************/
  15. %{
  16. /****************************************************************************
  17. *** local defines
  18. ***************************************************************************/
  19. #define pascal
  20. #define FARDATA
  21. #define NEARDATA
  22. #define FARCODE
  23. #define NEARCODE
  24. #define NEARSWAP
  25. #define YYFARDATA
  26. #define PASCAL pascal
  27. #define CDECL
  28. #define VOID void
  29. #define CONST const
  30. #define GLOBAL
  31. #define YYSTYPE lextype_t
  32. #define YYNEAR NEARCODE
  33. #define YYPASCAL PASCAL
  34. #define YYPRINT printf
  35. #define YYSTATIC static
  36. #define YYCONST static const
  37. #define YYLEX yylex
  38. #define YYPARSER yyparse
  39. #ifdef gajdebug3
  40. #define YYDEBUG
  41. #endif
  42. #define IS_CUR_INTERFACE_LOCAL() ( \
  43. (BOOL) (pInterfaceInfoDict->IsInterfaceLocal()) )
  44. // enable compilation under /W4
  45. #pragma warning ( disable : 4514 4710 4244 4127 4505 4706 )
  46. /****************************************************************************
  47. *** include files
  48. ***************************************************************************/
  49. #include "nulldefs.h"
  50. #include <basetsd.h>
  51. extern "C" {
  52. #include <stdio.h>
  53. #include <stdlib.h>
  54. #include <string.h>
  55. #include <ctype.h>
  56. int yyparse();
  57. }
  58. #include "allnodes.hxx"
  59. #include "lexutils.hxx"
  60. #include "gramutil.hxx"
  61. #include "idict.hxx"
  62. #include "filehndl.hxx"
  63. #include "cmdana.hxx"
  64. #include "control.hxx"
  65. #include "tlgen.hxx"
  66. #include "mbcs.hxx"
  67. extern "C" {
  68. #include "lex.h"
  69. extern char * KeywordToString( token_t );
  70. }
  71. /***************************************************************************
  72. * local data
  73. **************************************************************************/
  74. BOOL fBaseImported = FALSE;
  75. BOOL fOdlBaseImported = FALSE;
  76. BOOL fLibrary = FALSE;
  77. /***************************************************************************
  78. * external data
  79. **************************************************************************/
  80. extern CMD_ARG * pCommand;
  81. extern node_error * pErrorTypeNode;
  82. extern node_e_attr * pErrorAttrNode;
  83. extern SymTable * pBaseSymTbl;
  84. extern SymTable * pCurSymTbl;
  85. extern nsa * pSymTblMgr;
  86. extern short ImportLevel;
  87. extern BOOL fTypeGraphInited;
  88. extern BOOL fPragmaImportOn;
  89. extern CCONTROL * pCompiler;
  90. extern node_source * pSourceNode;
  91. extern NFA_INFO * pImportCntrl;
  92. extern PASS_1 * pPass1;
  93. extern IINFODICT * pInterfaceInfoDict;
  94. extern unsigned short LexContext;
  95. extern BOOL fRedundantImport;
  96. extern node_skl * pBaseImplicitHandle;
  97. extern unsigned short CurrentZp;
  98. extern node_pragma_pack * pPackStack;
  99. /***************************************************************************
  100. * external functions
  101. **************************************************************************/
  102. extern void yyunlex( token_t );
  103. extern BOOL IsTempName( char * );
  104. extern char * GenTempName();
  105. extern char * GenIntfName();
  106. extern char * GenCompName();
  107. extern void CopyNode( node_skl *, node_skl * );
  108. extern STATUS_T GetBaseTypeNode( node_skl **, short, short, short, short);
  109. extern ATTRLIST GenerateFieldAttribute( ATTR_T, expr_list *);
  110. extern node_skl * SearchTag( char *, NAME_T );
  111. extern void SyntaxError( STATUS_T, short );
  112. extern short PossibleMissingToken( short, short );
  113. extern char * MakeNewStringWithProperQuoting( char * );
  114. extern void CheckGlobalNamesClash( SymKey );
  115. extern void CheckSpecialForwardTypedef( node_skl *, node_skl *, type_node_list *);
  116. extern void PushZpStack( node_pragma_pack * & PackStack,
  117. unsigned short & CurrentZp );
  118. extern void PopZpStack( node_pragma_pack * & PackStack,
  119. unsigned short & CurrentZp );
  120. /***************************************************************************
  121. * local data
  122. **************************************************************************/
  123. /***************************************************************************
  124. * local defines
  125. **************************************************************************/
  126. #define YY_CATCH(x)
  127. #define DEFINE_STRING "#define"
  128. #define LEN_DEFINE (7)
  129. %}
  130. /****************************************************************************/
  131. %start RpcProg
  132. %token KWINTERFACE
  133. %token KWIMPORT
  134. %token KWIMPORTODLBASE
  135. %token KWCPPQUOTE
  136. %token KWCPRAGMA
  137. %token KWCPRAGMAPACK
  138. %token KWMPRAGMAIMPORT
  139. %token KWMPRAGMAECHO
  140. %token KWMPRAGMAIMPORTCLNTAUX
  141. %token KWMPRAGMAIMPORTSRVRAUX
  142. %token KWMIDLPRAGMA
  143. %token TYPENAME
  144. %token LIBNAME
  145. %token KWVOID
  146. %token KWUNSIGNED
  147. %token KWSIGNED
  148. %token KWFLOAT
  149. %token KWDOUBLE
  150. %token KWINT
  151. %token KWBYTE
  152. %token KWCHAR
  153. %token KWSMALL
  154. %token KWLONG
  155. %token KWSHORT
  156. %token KWHYPER
  157. %token KWINT32
  158. %token KWINT3264
  159. %token KWINT64
  160. %token KWINT128
  161. %token KWFLOAT80
  162. %token KWFLOAT128
  163. %token KWSTRUCT
  164. %token KWUNION
  165. %token KWENUM
  166. %token KWSHORTENUM
  167. %token KWLONGENUM
  168. %token KWCONST
  169. %token KWVOLATILE
  170. %token KW_C_INLINE
  171. %token KWTYPEDEF
  172. %token KWDECLGUID
  173. %token KWEXTERN
  174. %token KWSTATIC
  175. %token KWAUTO
  176. %token KWREGISTER
  177. %token KWERRORSTATUST
  178. %token KWBOOLEAN
  179. %token KWISOLATIN1
  180. %token KWPRIVATECHAR8
  181. %token KWISOMULTILINGUAL
  182. %token KWPRIVATECHAR16
  183. %token KWISOUCS
  184. %token KWPIPE
  185. %token KWSWITCH
  186. %token KWCASE
  187. %token KWDEFAULT
  188. %token KWUUID
  189. %token KWASYNCUUID
  190. %token KWVERSION
  191. %token KWSTRING
  192. %token KWBSTRING
  193. %token KWIN
  194. %token KWOUT
  195. %token KWPARTIALIGNORE
  196. %token KWIIDIS
  197. %token KWFIRSTIS
  198. %token KWLASTIS
  199. %token KWMAXIS
  200. %token KWMINIS
  201. %token KWLENGTHIS
  202. %token KWSIZEIS
  203. %token KWRANGE
  204. /* start of ODL key words */
  205. %token KWID
  206. %token KWHC /* helpcontext attribute */
  207. %token KWHSC /* helpstring context attribute */
  208. %token KWLCID
  209. %token KWDLLNAME
  210. %token KWHELPSTR
  211. %token KWHELPFILE
  212. %token KWHELPSTRINGDLL
  213. %token KWENTRY
  214. %token KWPROPGET
  215. %token KWPROPPUT
  216. %token KWPROPPUTREF
  217. %token KWOPTIONAL
  218. %token KWVARARG
  219. %token KWAPPOBJECT
  220. %token KWRESTRICTED
  221. %token KWPUBLIC
  222. %token KWREADONLY
  223. %token KWODL
  224. %token KWSOURCE
  225. %token KWBINDABLE
  226. %token KWREQUESTEDIT
  227. %token KWDISPLAYBIND
  228. %token KWDEFAULTBIND
  229. %token KWLICENSED
  230. %token KWPREDECLID
  231. %token KWHIDDEN
  232. %token KWRETVAL
  233. %token KWCONTROL
  234. %token KWDUAL
  235. %token KWPROXY
  236. %token KWNONEXTENSIBLE
  237. %token KWNONCREATABLE
  238. %token KWOLEAUTOMATION
  239. %token KWLIBRARY
  240. %token KWMODULE
  241. %token KWDISPINTERFACE
  242. %token KWCOCLASS
  243. %token KWMETHODS
  244. %token KWPROPERTIES
  245. %token KWIMPORTLIB
  246. %token KWFUNCDESCATTR
  247. %token KWIDLDESCATTR
  248. %token KWTYPEDESCATTR
  249. %token KWVARDESCATTR
  250. %token KWSAFEARRAY
  251. %token KWAGGREGATABLE
  252. %token KWUIDEFAULT
  253. %token KWNONBROWSABLE
  254. %token KWDEFAULTCOLLELEM
  255. %token KWDEFAULTVALUE
  256. %token KWCUSTOM
  257. %token KWDEFAULTVTABLE
  258. %token KWIMMEDIATEBIND
  259. %token KWUSESGETLASTERROR
  260. %token KWREPLACEABLE
  261. /* end of ODL key words */
  262. %token KWHANDLET /* Formerly RPCHNDL */
  263. %token KWHANDLE /* Formerly GEN_HNDL */
  264. %token KWCONTEXTHANDLE /* Aka LRPC_CTXT_HNDL */
  265. %token KWMSUNION
  266. %token KWMS_CONF_STRUCT
  267. %token KWENDPOINT
  268. %token KWDEFAULTPOINTER
  269. %token KWLOCAL
  270. %token KWSWITCHTYPE
  271. %token KWSWITCHIS
  272. %token KWTRANSMITAS
  273. %token KWWIREMARSHAL
  274. %token KWIGNORE
  275. %token KWREF
  276. %token KWUNIQUE
  277. %token KWPTR
  278. %token KWV1ARRAY
  279. %token KWV1STRUCT
  280. %token KWV1ENUM
  281. %token KWV1STRING
  282. %token KWIDEMPOTENT
  283. %token KWBROADCAST
  284. %token KWMAYBE
  285. %token KWASYNC
  286. %token KWINPUTSYNC
  287. %token KWCALLBACK
  288. %token KWALIGN
  289. %token KWUNALIGNED
  290. %token KWOPTIMIZE
  291. %token KWMESSAGE
  292. %token STRING
  293. %token WIDECHARACTERSTRING
  294. %token FLOATCONSTANT
  295. %token DOUBLECONSTANT
  296. %token KWTOKENNULL
  297. %token NUMERICCONSTANT
  298. %token NUMERICUCONSTANT
  299. %token NUMERICLONGCONSTANT
  300. %token NUMERICULONGCONSTANT
  301. %token HEXCONSTANT
  302. %token HEXUCONSTANT
  303. %token HEXLONGCONSTANT
  304. %token HEXULONGCONSTANT
  305. %token OCTALCONSTANT
  306. %token OCTALUCONSTANT
  307. %token OCTALLONGCONSTANT
  308. %token OCTALULONGCONSTANT
  309. %token CHARACTERCONSTANT
  310. %token WIDECHARACTERCONSTANT
  311. %token IDENTIFIER
  312. %token KWSIZEOF
  313. %token KWALIGNOF
  314. %token TOKENTRUE
  315. %token TOKENFALSE
  316. /* These are Microsoft C abominations */
  317. %token KWMSCDECLSPEC
  318. %token MSCEXPORT
  319. %token MSCFORTRAN
  320. %token MSCCDECL
  321. %token MSCSTDCALL
  322. %token MSCLOADDS
  323. %token MSCSAVEREGS
  324. %token MSCFASTCALL
  325. %token MSCSEGMENT
  326. %token MSCINTERRUPT
  327. %token MSCSELF
  328. %token MSCNEAR
  329. %token MSCFAR
  330. %token MSCUNALIGNED
  331. %token MSCHUGE
  332. %token MSCPTR32
  333. %token MSCPTR64
  334. %token MSCPASCAL
  335. %token MSCEMIT
  336. %token MSCASM
  337. %token MSCW64
  338. /* Microsoft proposed extentions to NIDL */
  339. %token KWNOCODE /* Allowed in .IDL in addition to .ACF */
  340. /* These are residual C tokens I'm not sure we should even allow */
  341. %token POINTSTO
  342. %token INCOP
  343. %token DECOP
  344. %token MULASSIGN
  345. %token DIVASSIGN
  346. %token MODASSIGN
  347. %token ADDASSIGN
  348. %token SUBASSIGN
  349. %token LEFTASSIGN
  350. %token RIGHTASSIGN
  351. %token ANDASSIGN
  352. %token XORASSIGN
  353. %token ORASSIGN
  354. %token DOTDOT
  355. %token LTEQ
  356. %token GTEQ
  357. %token NOTEQ
  358. %token LSHIFT
  359. %token RSHIFT
  360. %token ANDAND
  361. %token EQUALS
  362. %token OROR
  363. /* used by lex internally to signify "get another token" */
  364. %token NOTOKEN
  365. /* garbage token - should cause parse errors */
  366. %token GARBAGETOKEN
  367. /* OLE extensions */
  368. %token KWOBJECT
  369. /* Note that we're assuming that we get constants back and can check
  370. bounds (e.g. "are we integer") in the semantic actions.
  371. */
  372. /*
  373. ACF - Specific Tokens
  374. */
  375. %token KWSHAPE
  376. %token KWBYTECOUNT
  377. %token KWIMPLICITHANDLE
  378. %token KWAUTOHANDLE
  379. %token KWEXPLICITHANDLE
  380. %token KWREPRESENTAS
  381. %token KWCALLAS
  382. %token KWCODE
  383. %token KWINLINE
  384. %token KWOUTOFLINE
  385. %token KWINTERPRET
  386. %token KWNOINTERPRET
  387. %token KWCOMMSTATUS
  388. %token KWFAULTSTATUS
  389. %token KWHEAP
  390. %token KWINCLUDE
  391. %token KWPOINTERSIZE
  392. %token KWOFFLINE
  393. %token KWALLOCATE
  394. %token KWENABLEALLOCATE
  395. %token KWMANUAL
  396. %token KWNOTIFY
  397. %token KWNOTIFYFLAG
  398. %token KWUSERMARSHAL
  399. %token KWENCODE
  400. %token KWDECODE
  401. %token KWSTRICTCONTEXTHANDLE
  402. %token KWNOSERIALIZE
  403. %token KWSERIALIZE
  404. %token KWCSCHAR
  405. %token KWCSDRTAG
  406. %token KWCSRTAG
  407. %token KWCSSTAG
  408. %token KWCSTAGRTN
  409. %token KWFORCEALLOCATE
  410. /* Currently Unsupported Tokens */
  411. %token KWBITSET
  412. %token UUIDTOKEN
  413. %token VERSIONTOKEN
  414. %token EOI
  415. %token LASTTOKEN
  416. /* moved to ACF... */
  417. /*****************************************************************************
  418. * %types of various non terminals and terminals
  419. *****************************************************************************/
  420. %type <yy_attr> AcfCallType
  421. %type <yy_graph> AcfImpHdlTypeSpec
  422. %type <yy_attr> AcfInterfaceAttribute
  423. %type <yy_expr> AdditiveExpr
  424. %type <yy_operator> AddOp
  425. %type <yy_expr> AndExpr
  426. %type <yy_expr> ArgExprList
  427. %type <yy_abounds> ArrayBoundsPair
  428. %type <yy_declarator> ArrayDecl
  429. %type <yy_abounds> ArrayDecl2
  430. %type <yy_expr> AssignmentExpr
  431. %type <yy_attrlist> Attributes
  432. %type <yy_attrlist> AttributesWithDefault
  433. %type <yy_attrlist> AttrList
  434. %type <yy_attrlist> AttrListWithDefault
  435. %type <yy_attrlist> AttrSet
  436. %type <yy_attrlist> AttrSetWithDefault
  437. %type <yy_expr> AttrVar
  438. %type <yy_exprlist> AttrVarList
  439. %type <yy_tnlist> BaseInterfaceList
  440. %type <yy_type> BaseTypeSpec
  441. %type <yy_graph> BitSetType
  442. %type <yy_expr> CastExpr
  443. %type <yy_numeric> CHARACTERCONSTANT
  444. %type <yy_type> CharSpecs
  445. %type <yy_siblist> CoclassMember
  446. %type <yy_siblist> CoclassMemberList
  447. %type <yy_string> CoclassName
  448. %type <yy_expr> ConditionalExpr
  449. %type <yy_expr> ConstantExpr
  450. %type <yy_exprlist> ConstantExprs
  451. %type <yy_exprlist> MessageNumberList
  452. %type <yy_graph> CPragmaSet
  453. %type <yy_siblist> Declaration
  454. %type <yy_modifiers> DeclarationAccessories
  455. %type <yy_declspec> DeclarationSpecifiers
  456. %type <yy_declarator> Declarator
  457. %type <yy_declarator> Declarator2
  458. %type <yy_siblist> DispatchInterfaceBody
  459. %type <yy_disphead> DispatchInterfaceHeader
  460. %type <yy_string> DispatchInterfaceName
  461. %type <yy_numeric> DOUBLECONSTANT
  462. %type <yy_declarator> TypedefDeclarator
  463. %type <yy_declarator_set> TypedefDeclaratorList
  464. %type <yy_declarator_set> TypedefDeclaratorListElement
  465. %type <yy_siblist> DefaultCase
  466. %type <yy_attr> DirectionalAttribute
  467. %type <yy_string> EndPtSpec
  468. %type <yy_attr> EndPtSpecs
  469. %type <yy_declspec> EnumerationType
  470. %type <yy_enlab> Enumerator
  471. %type <yy_enlist> EnumeratorList
  472. %type <yy_declspec> EnumSpecifier
  473. %type <yy_expr> EqualityExpr
  474. %type <yy_expr> ExclusiveOrExpr
  475. %type <yy_expr> Expr
  476. %type <yy_attrlist> FieldAttribute
  477. %type <yy_expr> FAdditiveExpr
  478. %type <yy_numeric> FLOATCONSTANT
  479. %type <yy_expr> FConstantExpr
  480. %type <yy_expr> FMultExpr
  481. %type <yy_expr> FUnaryOp
  482. %type <yy_modifiers> FuncModifier
  483. %type <yy_attr> Guid
  484. %type <yy_attr> AsyncGuid
  485. %type <yy_numeric> HEXCONSTANT
  486. %type <yy_numeric> HEXLONGCONSTANT
  487. %type <yy_numeric> HEXUCONSTANT
  488. %type <yy_numeric> HEXULONGCONSTANT
  489. %type <yy_pSymName> IDENTIFIER
  490. %type <yy_siblist> Import
  491. %type <yy_siblist> ImportName
  492. %type <yy_siblist> ImportList
  493. %type <yy_expr> InclusiveOrExpr
  494. %type <yy_declarator> InitDeclarator
  495. %type <yy_declarator_set> InitDeclaratorList
  496. %type <yy_short> InternationalCharacterType
  497. %type <yy_type> IntModifiers
  498. %type <yy_short> IntSize
  499. %type <yy_type> IntSpec
  500. %type <yy_type> IntSpecs
  501. %type <yy_expr> Initializer
  502. %type <yy_initlist> InitializerList
  503. %type <yy_siblist> InputFile
  504. %type <yy_attr> InterfaceAttribute
  505. %type <yy_intbody> InterfaceBody
  506. %type <yy_siblist> InterfaceComp
  507. %type <yy_siblist> InterfaceComponent
  508. %type <yy_siblist> InterfaceComponents
  509. %type <yy_inthead> InterfaceHeader
  510. %type <yy_intbody> InterfaceList
  511. %type <yy_string> InterfaceName
  512. %type <yy_string> KWCPRAGMA
  513. %type <yy_intbody> LibraryBody
  514. %type <yy_libhead> LibraryHeader
  515. %type <yy_intbody> LibraryInterfaceList
  516. %type <yy_string> LibraryName
  517. %type <yy_expr> LogicalAndExpr
  518. %type <yy_expr> LogicalOrExpr
  519. %type <yy_siblist> MemberDeclaration
  520. %type <yy_declarator> MemberDeclarator
  521. %type <yy_declarator_set> MemberDeclaratorList
  522. %type <yy_siblist> MethodDeclaration
  523. %type <yy_siblist> MethodList
  524. %type <yy_graph> MidlPragmaSet
  525. %type <yy_modifiers> Modifier
  526. %type <yy_modifiers> ModifierList
  527. %type <yy_siblist> ModuleBody
  528. %type <yy_modulehead> ModuleHeader
  529. %type <yy_string> ModuleName
  530. %type <yy_modifiers> KWMSCDECLSPEC
  531. %type <yy_modifiers> MscDeclSpec
  532. %type <yy_modifiers> MscOptDeclSpecList
  533. %type <yy_operator> MultOp
  534. %type <yy_siblist> MultipleImport
  535. %type <yy_expr> MultExpr
  536. %type <yy_siblist> NidlMemberDeclaration
  537. %type <yy_siblist> NidlUnionBody
  538. %type <yy_nucases> NidlUnionCase
  539. %type <yy_nucaselabel> NidlUnionCaseLabel
  540. %type <yy_nucllist> NidlUnionCaseLabelList
  541. %type <yy_nucases> NidlUnionCases
  542. %type <yy_en_switch> NidlUnionSwitch
  543. %type <yy_numeric> NUMERICCONSTANT
  544. %type <yy_numeric> NUMERICLONGCONSTANT
  545. %type <yy_numeric> NUMERICUCONSTANT
  546. %type <yy_numeric> NUMERICULONGCONSTANT
  547. %type <yy_numeric> OCTALCONSTANT
  548. %type <yy_numeric> OCTALUCONSTANT
  549. %type <yy_numeric> OCTALLONGCONSTANT
  550. %type <yy_numeric> OCTALULONGCONSTANT
  551. %type <yy_attr> OdlAttribute
  552. %type <yy_attrlist> OneAttribute
  553. %type <yy_attrlist> OneAttributeWithDefault
  554. %type <yy_intbody> OneInterface
  555. %type <yy_attr> OperationAttribute
  556. %type <yy_attrlist> OptionalAttrList
  557. %type <yy_attrlist> OptionalAttrListWithDefault
  558. %type <yy_graph> OptionalBaseIF
  559. %type <yy_short> OptionalComma
  560. %type <yy_modifiers> OptionalConst
  561. %type <yy_declarator> OptionalDeclarator
  562. %type <yy_declarator_set> OptionalInitDeclaratorList
  563. %type <yy_siblist> OptionalMethodList
  564. %type <yy_modifiers> OptionalModifierList
  565. %type <yy_modifiers> OptionalPostfixPtrModifier
  566. %type <yy_siblist> OptionalModuleBody
  567. %type <yy_siblist> OptionalPropertyList
  568. %type <yy_string> OptionalTag
  569. %type <yy_short> OptPackIndex
  570. %type <yy_attrenum> OptShape
  571. %type <yy_short> PackIndex
  572. %type <yy_graph> ParameterDeclaration
  573. %type <yy_siblist> ParameterList
  574. %type <yy_siblist> ParameterTypeList
  575. %type <yy_siblist> ParamsDecl2
  576. %type <yy_siblist> PhantomInputFile
  577. /*
  578. %type <yy_inthead> PipeInterfaceHeader
  579. */
  580. %type <yy_declarator> Pointer
  581. %type <yy_expr> PostfixExpr
  582. %type <yy_graph> PredefinedTypeSpec
  583. %type <yy_expr> PrimaryExpr
  584. %type <yy_siblist> PropertyList
  585. %type <yy_attr> PtrAttr
  586. %type <yy_modifiers> PtrModifier
  587. %type <yy_short> PushOrPop
  588. %type <yy_expr> RelationalExpr
  589. %type <yy_expr> ShiftExpr
  590. %type <yy_type> SignSpecs
  591. %type <yy_graph> SimpleTypeSpec
  592. %type <yy_tokentype> SizeofOrAlignof
  593. %type <yy_modifiers> StorageClassSpecifier
  594. %type <yy_string> STRING
  595. %type <yy_siblist> StructDeclarationList
  596. %type <yy_en_switch> SwitchSpec
  597. %type <yy_graph> SwitchTypeSpec
  598. %type <yy_string> Tag
  599. %type <yy_declspec> TaggedSpec
  600. %type <yy_declspec> TaggedStructSpec
  601. %type <yy_declspec> TaggedUnionSpec
  602. %type <yy_attr> TypeAttribute
  603. %type <yy_declspec> TypeDeclarationSpecifiers
  604. %type <yy_graph> TYPENAME
  605. %type <yy_graph> TypeName
  606. %type <yy_pSymName> LIBNAME
  607. %type <yy_modifiers> TypeQualifier
  608. %type <yy_declspec> TypeSpecifier
  609. %type <yy_expr> UnaryExpr
  610. %type <yy_expr> UnaryOp
  611. %type <yy_attr> UnimplementedTypeAttribute
  612. %type <yy_siblist> UnionBody
  613. %type <yy_siblist> UnionCase
  614. %type <yy_attr> UnionCaseLabel
  615. %type <yy_siblist> UnionCases
  616. %type <yy_pSymName> UnionName
  617. %type <yy_string> UUIDTOKEN
  618. %type <yy_expr> VariableExpr
  619. %type <yy_string> VERSIONTOKEN
  620. %type <yy_numeric> WIDECHARACTERCONSTANT
  621. %type <yy_string> WIDECHARACTERSTRING
  622. /****************************************************************************/
  623. %%
  624. RpcProg:
  625. ForceBaseIdl InputFile
  626. {
  627. node_source * pSource = new node_source;
  628. pSource->SetMembers( $2 );
  629. pSourceNode = pSource;
  630. /**
  631. ** If there were errors detected in the 1st pass, the dont do
  632. ** anything.
  633. **/
  634. if( !pCompiler->GetErrorCount() )
  635. {
  636. /**
  637. ** If we found no errors, the first compiler phase is over
  638. **/
  639. return;
  640. }
  641. else
  642. {
  643. // if the errors prevented a resolution pass and semantics
  644. // to be performed, then issue a message. For that purpose
  645. // look at the node state of the source node. If it indicates
  646. // presence of a forward decl, then we must issue the error
  647. ParseError( ERRORS_PASS1_NO_PASS2, (char *)0 );
  648. }
  649. /**
  650. ** If we reached here, there were errors detected, and we dont
  651. ** want to invoke the subsequent passes, Just quit.
  652. **/
  653. pSourceNode = (node_source *)NULL;
  654. returnflag = 1;
  655. return;
  656. }
  657. ;
  658. InputFile:
  659. InterfaceList EOI
  660. {
  661. // create file node, add imports
  662. node_file * pFile;
  663. named_node * pN;
  664. char * pInputFileName;
  665. /**
  666. ** pick up the details of the file, because we need to set the
  667. ** file nodes name with this file
  668. **/
  669. pImportCntrl->GetInputDetails( &pInputFileName );
  670. pFile = new node_file( pInputFileName, ImportLevel );
  671. /**
  672. ** Attach the interface nodes as a member of the file node.
  673. ** Also, point the interface nodes to their parent file node.
  674. **/
  675. pFile->SetMembers( $1.Members );
  676. MEM_ITER MemIter(pFile);
  677. while ( pN = MemIter.GetNext() )
  678. {
  679. pN->SetFileNode( pFile );
  680. }
  681. /**
  682. ** we may have collected the more file nodes as part of the reduction
  683. ** process. If so, then attach this node to the list. If not then
  684. ** generate a new list and attach the file node there
  685. **/
  686. if( $1.Imports )
  687. $$ = $1.Imports;
  688. else
  689. $$.Init();
  690. $$.SetPeer( pFile );
  691. }
  692. ;
  693. InterfaceList:
  694. InterfaceList OneInterface
  695. {
  696. if( !pCommand->IsSwitchDefined( SWITCH_MS_EXT ) )
  697. {
  698. ParseError( MULTIPLE_INTF_NON_OSF, NULL );
  699. }
  700. // if we have dangling definitions, add them to the intf
  701. if ( $2.Members.Tail() &&
  702. ( !$2.Members.Tail()->IsInterfaceOrObject() ) )
  703. {
  704. node_interface * pIntf =
  705. pInterfaceInfoDict->GetInterfaceNode();
  706. $$ = $1;
  707. $$.Imports.Merge( $2.Imports );
  708. pIntf->MergeMembersToTail( $2.Members );
  709. if ( $1.Members.Tail() != pIntf )
  710. $$.Members.Add( pIntf );
  711. }
  712. else
  713. {
  714. // merge interface list and imports list
  715. $$ = $1;
  716. $$.Imports.Merge( $2.Imports );
  717. $$.Members.Merge( $2.Members );
  718. }
  719. }
  720. | OneInterface
  721. {
  722. if ( $1.Members.Tail() &&
  723. ( !$1.Members.Tail()->IsInterfaceOrObject() ) )
  724. {
  725. node_interface * pIntf =
  726. pInterfaceInfoDict->GetInterfaceNode();
  727. // gets siblist of declarations
  728. pIntf->MergeMembersToTail( $1.Members );
  729. $$.Imports = $1.Imports;
  730. $$.Members.Init( pIntf );
  731. }
  732. else
  733. {
  734. // pass interface list and imports list
  735. $$ = $1;
  736. }
  737. }
  738. ;
  739. LibraryInterfaceList:
  740. LibraryInterfaceList OneInterface
  741. {
  742. // merge interface list and imports list
  743. $$ = $1;
  744. $$.Imports.Merge( $2.Imports );
  745. $$.Members.Merge( $2.Members );
  746. }
  747. | OneInterface
  748. ;
  749. OneInterface:
  750. InterfaceHeader InterfaceBody '}' OptionalSemicolon
  751. {
  752. /**
  753. ** This is the place where the complete interface construct
  754. ** has been reduced. We need to hook the body to the interface
  755. ** and pass it up, with the imports
  756. **/
  757. node_interface * pInterface = $1.pInterface;
  758. pInterface->SetMembers( $2.Members );
  759. $$.Imports = $2.Imports;
  760. $$.Members.Init( pInterface );
  761. /**
  762. ** Start a new interface info dict in case there are
  763. ** multiple interfaces in this file.
  764. **/
  765. pInterfaceInfoDict->EndNewInterface();
  766. pInterfaceInfoDict->StartNewInterface();
  767. // start a dummy interface for intervening stuff
  768. node_interface * pOuter = new node_interface;
  769. pOuter->SetSymName( GenIntfName() );
  770. pInterfaceInfoDict->SetInterfaceNode( pOuter );
  771. pOuter->SetAttribute( new battr( ATTR_LOCAL ) );
  772. pOuter->SetProcTbl( (ImportLevel != 0) ? new SymTable : pBaseSymTbl );
  773. }
  774. | OptionalAttrList InterfaceName ';'
  775. {
  776. // put in a forward declaration
  777. SymKey SKey( $2, NAME_DEF );
  778. named_node * pNode;
  779. pNode = new node_forward( SKey, pBaseSymTbl );
  780. pNode->SetSymName( $2 );
  781. // tbd - error if $1.NonNull()
  782. named_node * pFound;
  783. pFound = pBaseSymTbl->SymSearch( SKey );
  784. // in InterfaceHeader, we are creating node_interface_reference on
  785. // top of node_interface, so pFound is node_interface_reference.
  786. // the bug is covered by GetDefiningFile() where GetMyInterface()
  787. // in fact is retrieving outer wrapper interface for import file
  788. // instead of the real child. It looks like in most cases, the
  789. // two bugs cancel each other, but under certain scenario
  790. // GetMyInterface() is retrieving the right node_interface, and
  791. // we are failing on referencing non-existing interface.
  792. // a work around is checking NodeKind() == NODE_INTERFACE_REFERENCE
  793. // but real solution should be make GetMyInterface() really work,
  794. // and better yet, use a better way to retrieve the child interface
  795. // yongqu - 10/5/2000
  796. if (pFound &&
  797. pFound->NodeKind() != NODE_HREF &&
  798. pFound->NodeKind() != NODE_INTERFACE &&
  799. pFound->NodeKind() != NODE_INTERFACE_REFERENCE &&
  800. NULL != pFound->GetDefiningFile())
  801. {
  802. pBaseSymTbl->SymDelete( SKey );
  803. }
  804. if(!pBaseSymTbl->SymInsert( SKey, (SymTable *)NULL, pNode ))
  805. {
  806. // ParseError( DUPLICATE_DEFINITION, pName );
  807. }
  808. $$.Imports.Init();
  809. $$.Members.Init( pNode );
  810. }
  811. | OptionalAttrList DispatchInterfaceName ';'
  812. {
  813. // put in a forward declaration
  814. SymKey SKey( $2, NAME_DEF );
  815. named_node * pNode;
  816. pNode = new node_forward( SKey, pBaseSymTbl );
  817. pNode->SetSymName( $2 );
  818. // tbd - error if $1.NonNull()
  819. named_node * pFound;
  820. pFound = pBaseSymTbl->SymSearch( SKey );
  821. if (pFound && pFound->NodeKind() != NODE_HREF && pFound->NodeKind() != NODE_DISPINTERFACE && NULL != pFound->GetDefiningFile())
  822. {
  823. pBaseSymTbl->SymDelete( SKey );
  824. }
  825. if(!pBaseSymTbl->SymInsert( SKey, (SymTable *)NULL, pNode ))
  826. {
  827. // ParseError( DUPLICATE_DEFINITION, pName );
  828. }
  829. $$.Imports.Init();
  830. $$.Members.Init( pNode );
  831. }
  832. | OptionalAttrList CoclassName ';'
  833. {
  834. // put in a forward declaration
  835. SymKey SKey( $2, NAME_DEF );
  836. named_node * pNode;
  837. pNode = new node_forward( SKey, pBaseSymTbl );
  838. pNode->SetSymName( $2 );
  839. // tbd - error if $1.NonNull()
  840. named_node * pFound;
  841. pFound = pBaseSymTbl->SymSearch( SKey );
  842. if (pFound && pFound->NodeKind() != NODE_HREF && pFound->NodeKind() != NODE_COCLASS && NULL != pFound->GetDefiningFile())
  843. {
  844. pBaseSymTbl->SymDelete( SKey );
  845. }
  846. if(!pBaseSymTbl->SymInsert( SKey, (SymTable *)NULL, pNode ))
  847. {
  848. // ParseError( DUPLICATE_DEFINITION, pName );
  849. }
  850. $$.Imports.Init();
  851. $$.Members.Init( pNode );
  852. }
  853. | OptionalAttrList ModuleName ';'
  854. {
  855. // put in a forward declaration
  856. SymKey SKey( $2, NAME_DEF );
  857. named_node * pNode;
  858. pNode = new node_forward( SKey, pBaseSymTbl );
  859. pNode->SetSymName( $2 );
  860. // tbd - error if $1.NonNull()
  861. named_node * pFound;
  862. pFound = pBaseSymTbl->SymSearch( SKey );
  863. if (pFound && pFound->NodeKind() != NODE_HREF && pFound->NodeKind() != NODE_MODULE && NULL != pFound->GetDefiningFile())
  864. {
  865. pBaseSymTbl->SymDelete( SKey );
  866. }
  867. if(!pBaseSymTbl->SymInsert( SKey, (SymTable *)NULL, pNode ))
  868. {
  869. // ParseError( DUPLICATE_DEFINITION, pName );
  870. }
  871. $$.Imports.Init();
  872. $$.Members.Init( pNode );
  873. }
  874. | Import
  875. {
  876. if( !pCommand->IsSwitchDefined( SWITCH_MS_EXT ) &&
  877. !((node_file*)$1.Tail())->IsXXXBaseIdl() )
  878. {
  879. ParseError( OUTSIDE_OF_INTERFACE, NULL );
  880. }
  881. // returns siblist
  882. // these need to get saved up so they will be added to
  883. // the header file
  884. $$.Imports = $1;
  885. $$.Members.Init();
  886. }
  887. | InterfaceComponent
  888. {
  889. if( !pCommand->IsSwitchDefined( SWITCH_MS_EXT ) )
  890. {
  891. ParseError( OUTSIDE_OF_INTERFACE, NULL );
  892. }
  893. // pass up a sibling list
  894. $$.Imports.Init();
  895. $$.Members = $1;
  896. }
  897. | LibraryHeader ForceBaseOdl LibraryBody '}' OptionalSemicolon
  898. {
  899. /**
  900. ** This is the place where the complete library construct
  901. ** has been reduced. We need to hook the body to the library
  902. ** and pass it up, with the imports
  903. **/
  904. if (ImportLevel == 1)
  905. {
  906. node_library * pLibrary = $1.pLibrary;
  907. pLibrary->SetMembers( $3.Members );
  908. $$.Imports = $3.Imports;
  909. $$.Members.Init( pLibrary );
  910. }
  911. else
  912. {
  913. // this library block is in an imported file
  914. // throw away the definitions
  915. $$.Imports.Init();
  916. $$.Members.Init();
  917. }
  918. // Throw the big "case sensitive again" switch here
  919. gfCaseSensitive = TRUE;
  920. // return to the previous Import Level
  921. ImportLevel--;
  922. }
  923. | KWIMPORTLIB '(' STRING ')' ';'
  924. {
  925. if ( gfCaseSensitive )
  926. {
  927. ParseError(ILLEGAL_IMPORTLIB, $3);
  928. }
  929. if ( !FAddImportLib($3) )
  930. {
  931. ParseError(TYPELIB_NOT_LOADED, $3);
  932. }
  933. $$.Imports.Init();
  934. $$.Members.Init();
  935. }
  936. | ModuleHeader PhantomPushSymtab OptionalModuleBody OptionalSemicolon
  937. {
  938. /**
  939. ** discard the inner symbol table contents (unless it had fwds)
  940. **/
  941. pCurSymTbl->DiscardScope();
  942. /**
  943. ** restore the symbol table level
  944. **/
  945. pSymTblMgr->PopSymLevel( &pCurSymTbl );
  946. node_module * pModule = $1.pModule;
  947. pModule->SetMembers($3);
  948. $$.Members.Init( pModule );
  949. $$.Imports.Init();
  950. /**
  951. ** Start a new interface info dict in case there are
  952. ** multiple interfaces in this file.
  953. **/
  954. pInterfaceInfoDict->EndNewInterface();
  955. pInterfaceInfoDict->StartNewInterface();
  956. // start a dummy interface for intervening stuff
  957. node_interface * pOuter = new node_interface;
  958. pOuter->SetSymName( GenIntfName() );
  959. pInterfaceInfoDict->SetInterfaceNode( pOuter );
  960. pOuter->SetAttribute( new battr( ATTR_LOCAL ) );
  961. pOuter->SetProcTbl( (ImportLevel != 0) ? new SymTable : pBaseSymTbl );
  962. }
  963. | DispatchInterfaceHeader PhantomPushSymtab DispatchInterfaceBody '}' OptionalSemicolon
  964. {
  965. /**
  966. ** discard the inner symbol table contents (unless it had fwds)
  967. **/
  968. pCurSymTbl->DiscardScope();
  969. /**
  970. ** restore the symbol table level
  971. **/
  972. pSymTblMgr->PopSymLevel( &pCurSymTbl );
  973. node_dispinterface * pDispInterface = $1.pDispInterface;
  974. pDispInterface->SetMembers($3);
  975. $$.Members.Init(pDispInterface);
  976. $$.Imports.Init();
  977. /**
  978. ** Start a new interface info dict in case there are
  979. ** multiple interfaces in this file.
  980. **/
  981. pInterfaceInfoDict->EndNewInterface();
  982. pInterfaceInfoDict->StartNewInterface();
  983. // start a dummy interface for intervening stuff
  984. node_interface * pOuter = new node_interface;
  985. pOuter->SetSymName( GenIntfName() );
  986. pInterfaceInfoDict->SetInterfaceNode( pOuter );
  987. pOuter->SetAttribute( new battr( ATTR_LOCAL ) );
  988. pOuter->SetProcTbl( (ImportLevel != 0) ? new SymTable : pBaseSymTbl );
  989. }
  990. | OptionalAttrList CoclassName '{' PhantomPushSymtab CoclassMemberList '}' OptionalSemicolon
  991. {
  992. /**
  993. ** discard the inner symbol table contents (unless it had fwds)
  994. **/
  995. pCurSymTbl->DiscardScope();
  996. /**
  997. ** restore the symbol table level
  998. **/
  999. pSymTblMgr->PopSymLevel( &pCurSymTbl );
  1000. char * szName = $2;
  1001. node_coclass * pCoclass = new node_coclass();
  1002. pCoclass->AddAttributes($1);
  1003. pCoclass->SetSymName(szName);
  1004. pCoclass->SetMembers( $5);
  1005. // add coclass node to the global symbol table
  1006. SymKey SKey (szName, NAME_DEF);
  1007. named_node * pFound;
  1008. pFound = pBaseSymTbl->SymSearch( SKey );
  1009. //if (pFound && ( pFound->NodeKind() == NODE_FORWARD || pFound->NodeKind() == NODE_HREF ))
  1010. if (pFound && ( pFound->NodeKind() == NODE_FORWARD || NULL != pFound->GetDefiningFile() ))
  1011. {
  1012. pBaseSymTbl->SymDelete( SKey );
  1013. }
  1014. if (!pBaseSymTbl->SymInsert(SKey, (SymTable *) NULL, pCoclass))
  1015. {
  1016. ParseError(DUPLICATE_DEFINITION, szName);
  1017. }
  1018. $$.Members.Init( pCoclass );
  1019. $$.Imports.Init();
  1020. }
  1021. ;
  1022. ModuleHeader:
  1023. OptionalAttrList ModuleName '{'
  1024. {
  1025. char * szName = $2;
  1026. node_module * pModule = new node_module();
  1027. pModule->AddAttributes($1);
  1028. pModule->SetSymName(szName);
  1029. // modules get a private scope for procs
  1030. pModule->SetProcTbl(new SymTable);
  1031. // start the new module
  1032. pInterfaceInfoDict->SetInterfaceNode(pModule);
  1033. // add module node to the base symbol table
  1034. SymKey SKey (szName, NAME_DEF);
  1035. named_node * pFound;
  1036. pFound = pBaseSymTbl->SymSearch( SKey );
  1037. //if (pFound && ( pFound->NodeKind() == NODE_FORWARD || pFound->NodeKind() == NODE_HREF ))
  1038. if (pFound && ( pFound->NodeKind() == NODE_FORWARD || NULL != pFound->GetDefiningFile() ))
  1039. {
  1040. pBaseSymTbl->SymDelete( SKey );
  1041. }
  1042. if (!pBaseSymTbl->SymInsert(SKey, (SymTable *) NULL, pModule))
  1043. {
  1044. ParseError(DUPLICATE_DEFINITION, szName);
  1045. }
  1046. $$.pModule = pModule;
  1047. }
  1048. ;
  1049. DispatchInterfaceHeader:
  1050. OptionalAttrList DispatchInterfaceName '{'
  1051. {
  1052. char * szName = $2;
  1053. node_dispinterface * pDispInterface = new node_dispinterface();
  1054. pDispInterface->AddAttributes($1);
  1055. pDispInterface->SetSymName(szName);
  1056. // dipatchinterfaces get a private scope for procs
  1057. pDispInterface->SetProcTbl(new SymTable);
  1058. // start the new dispatchinterface
  1059. pInterfaceInfoDict->SetInterfaceNode(pDispInterface);
  1060. // add dispinterface node to the global symbol table
  1061. SymKey SKey (szName, NAME_DEF);
  1062. named_node * pFound;
  1063. pFound = pBaseSymTbl->SymSearch( SKey );
  1064. //if (pFound && ( pFound->NodeKind() == NODE_FORWARD || pFound->NodeKind() == NODE_HREF ))
  1065. if (pFound && ( pFound->NodeKind() == NODE_FORWARD || NULL != pFound->GetDefiningFile() ))
  1066. {
  1067. pBaseSymTbl->SymDelete( SKey );
  1068. }
  1069. if (!pBaseSymTbl->SymInsert(SKey, (SymTable *) NULL, pDispInterface))
  1070. {
  1071. ParseError(DUPLICATE_DEFINITION, szName);
  1072. }
  1073. $$.pDispInterface = pDispInterface;
  1074. }
  1075. ;
  1076. OptionalSemicolon:
  1077. ';'
  1078. | /* nothing */
  1079. ;
  1080. LibraryHeader:
  1081. OptionalAttrList LibraryName '{'
  1082. {
  1083. char * szName = $2;
  1084. if (ImportLevel == 0)
  1085. {
  1086. // make sure that only one library statement exists
  1087. if (fLibrary)
  1088. {
  1089. ParseError(TWO_LIBRARIES, szName);
  1090. }
  1091. fLibrary = TRUE;
  1092. }
  1093. // create library node
  1094. node_library * pLibrary = new node_library();
  1095. $$.pLibrary = pLibrary;
  1096. pLibrary->AddAttributes($1);
  1097. pLibrary->SetSymName(szName);
  1098. // throw the big "case insensitive" switch here
  1099. gfCaseSensitive = FALSE;
  1100. // Bump the Import Level to ensure that interfaces under the
  1101. // library statement are treated correctly.
  1102. ImportLevel++;
  1103. }
  1104. ;
  1105. LibraryName:
  1106. KWLIBRARY Tag
  1107. {
  1108. $$ = $2;
  1109. }
  1110. ;
  1111. LibraryBody:
  1112. LibraryInterfaceList
  1113. // just pass back what we get from the list of interfaces
  1114. | /* nothing */
  1115. {
  1116. // initialize and return an empty list
  1117. $$.Imports.Init();
  1118. $$.Members.Init();
  1119. }
  1120. ;
  1121. ModuleName:
  1122. KWMODULE Tag
  1123. {
  1124. $$ = $2;
  1125. }
  1126. ;
  1127. OptionalModuleBody:
  1128. ModuleBody '}'
  1129. | '}'
  1130. {
  1131. $$.Init();
  1132. }
  1133. ;
  1134. ModuleBody:
  1135. ModuleBody MethodDeclaration
  1136. {
  1137. $$.Merge($2);
  1138. }
  1139. | MethodDeclaration
  1140. ;
  1141. DispatchInterfaceName:
  1142. KWDISPINTERFACE Tag
  1143. {
  1144. $$ = $2;
  1145. }
  1146. ;
  1147. DispatchInterfaceBody:
  1148. KWPROPERTIES ':' OptionalPropertyList KWMETHODS ':' OptionalMethodList
  1149. {
  1150. $$ = $3;
  1151. $$.Merge($6);
  1152. // Can I tell where the properties stop and the methods begin?
  1153. // And does it really matter?
  1154. }
  1155. | InterfaceName ';'
  1156. {
  1157. // put in a forward declaration
  1158. SymKey SKey( $1, NAME_DEF );
  1159. named_node * pNode;
  1160. pNode = new node_forward( SKey, pBaseSymTbl );
  1161. pNode->SetSymName( $1 );
  1162. // tbd - error if $1.NonNull()
  1163. if(!pBaseSymTbl->SymInsert( SKey, (SymTable *)NULL, pNode ))
  1164. {
  1165. // ParseError( DUPLICATE_DEFINITION, pName );
  1166. }
  1167. $$.Init( pNode );
  1168. }
  1169. | /* nothing */
  1170. {
  1171. $$.Init();
  1172. }
  1173. ;
  1174. OptionalPropertyList:
  1175. PropertyList
  1176. | /* nothing */
  1177. {
  1178. $$.Init();
  1179. }
  1180. ;
  1181. PropertyList:
  1182. PropertyList MemberDeclaration
  1183. {
  1184. $$.Merge($2);
  1185. }
  1186. | MemberDeclaration
  1187. ;
  1188. OptionalMethodList:
  1189. MethodList
  1190. | /* nothing */
  1191. {
  1192. $$.Init();
  1193. }
  1194. ;
  1195. MethodList:
  1196. MethodList MethodDeclaration
  1197. {
  1198. $$.Merge($2);
  1199. }
  1200. | MethodDeclaration
  1201. ;
  1202. MethodDeclaration:
  1203. OptionalAttrList Declaration
  1204. {
  1205. $2.AddAttributes($1);
  1206. $$ = $2;
  1207. /**
  1208. ** Check to see if it has a property attribute.
  1209. ** If it does, remove its name from the symbol table,
  1210. ** decorate it with the appropriate decoration
  1211. ** and re-insert it into the symbol table
  1212. **/
  1213. BOOL fPropPut = FALSE;
  1214. BOOL fPropGet = FALSE;
  1215. BOOL fPropPutRef = FALSE;
  1216. node_base_attr * pCur = $1.GetFirst();
  1217. named_node * pNode = $$.Tail();
  1218. char * szName = pNode->GetSymName();
  1219. while (pCur)
  1220. {
  1221. if (pCur->GetAttrID() == ATTR_MEMBER)
  1222. {
  1223. switch(((node_member_attr *)pCur)->GetAttr())
  1224. {
  1225. case MATTR_PROPPUT:
  1226. fPropPut = TRUE;
  1227. if (fPropGet | fPropPutRef)
  1228. ParseError(MULTIPLE_PROPERTY_ATTRIBUTES, szName);
  1229. break;
  1230. case MATTR_PROPGET:
  1231. fPropGet = TRUE;
  1232. if (fPropPut | fPropPutRef)
  1233. ParseError(MULTIPLE_PROPERTY_ATTRIBUTES, szName);
  1234. break;
  1235. case MATTR_PROPPUTREF:
  1236. fPropPutRef = TRUE;
  1237. if (fPropGet | fPropPut)
  1238. ParseError(MULTIPLE_PROPERTY_ATTRIBUTES, szName);
  1239. break;
  1240. }
  1241. }
  1242. pCur = pCur->GetNext();
  1243. }
  1244. if (fPropPut | fPropGet | fPropPutRef)
  1245. {
  1246. // remove the name from the correct symbol table
  1247. SymKey SKey(szName, NAME_PROC);
  1248. SymTable * pSymTable = pInterfaceInfoDict->GetInterfaceProcTable();
  1249. named_node * pFound = pSymTable->SymSearch(SKey);
  1250. if (pNode == pFound)
  1251. {
  1252. pSymTable->SymDelete(SKey);
  1253. char * szNewName;
  1254. if (fPropPut)
  1255. {
  1256. szNewName = new char[strlen(szName) + 5];
  1257. sprintf(szNewName , "put_%s", szName);
  1258. }
  1259. else
  1260. if (fPropGet)
  1261. {
  1262. szNewName = new char[strlen(szName) + 5];
  1263. sprintf(szNewName , "get_%s", szName);
  1264. }
  1265. else
  1266. {
  1267. szNewName = new char[strlen(szName) + 8];
  1268. sprintf(szNewName , "putref_%s", szName);
  1269. }
  1270. pFound->SetSymName(szNewName);
  1271. SymKey SNewKey(szNewName, NAME_PROC);
  1272. pSymTable->SymInsert(SNewKey, (SymTable *)NULL, pFound);
  1273. }
  1274. else
  1275. ParseError(ILLEGAL_USE_OF_PROPERTY_ATTRIBUTE, szName);
  1276. }
  1277. }
  1278. ;
  1279. CoclassName:
  1280. KWCOCLASS Tag
  1281. {
  1282. $$ = $2;
  1283. }
  1284. ;
  1285. CoclassMemberList:
  1286. CoclassMemberList CoclassMember
  1287. {
  1288. $$.Merge($2);
  1289. }
  1290. | CoclassMember
  1291. ;
  1292. CoclassMember:
  1293. OptionalAttrListWithDefault DispatchInterfaceName ';'
  1294. {
  1295. // put in a forward declaration
  1296. SymKey SKey( $2, NAME_DEF );
  1297. named_node * pNode;
  1298. pNode = new node_forward( SKey, pBaseSymTbl );
  1299. pNode->SetSymName( $2 );
  1300. // tbd - error if $2.NonNull()
  1301. if(!pCurSymTbl->SymInsert( SKey, (SymTable *)NULL, pNode ))
  1302. {
  1303. // ParseError( DUPLICATE_DEFINITION, pName );
  1304. }
  1305. // bugbug - how to I verify that the name actually belongs to a DispInterface?
  1306. $$.Init( pNode );
  1307. $$.AddAttributes($1);
  1308. }
  1309. | OptionalAttrListWithDefault InterfaceName ';'
  1310. {
  1311. // put in a forward declaration
  1312. SymKey SKey( $2, NAME_DEF );
  1313. named_node * pNode;
  1314. pNode = new node_forward( SKey, pBaseSymTbl );
  1315. pNode->SetSymName( $2 );
  1316. // tbd - error if $2.NonNull()
  1317. if(!pCurSymTbl->SymInsert( SKey, (SymTable *)NULL, pNode ))
  1318. {
  1319. // ParseError( DUPLICATE_DEFINITION, pName );
  1320. }
  1321. // bugbug - how to I verify that the name actually belongs to an Interface?
  1322. $$.Init( pNode );
  1323. $$.AddAttributes($1);
  1324. }
  1325. ;
  1326. ForceBaseOdl:
  1327. /* nothing */
  1328. {
  1329. /* force the lexer to return import "oaidl.idl";
  1330. */
  1331. if ( !fOdlBaseImported)
  1332. {
  1333. /* Make sure the MS_EXT and C_EXT switches get defined
  1334. */
  1335. pCommand->SwitchDefined( SWITCH_MS_EXT );
  1336. pCommand->SwitchDefined( SWITCH_C_EXT );
  1337. // make sure the change sticks
  1338. pCommand->SetModeSwitchConfigMask();
  1339. LexContext = LEX_ODL_BASE_IMPORT;
  1340. fOdlBaseImported = TRUE;
  1341. }
  1342. }
  1343. ;
  1344. ForceBaseIdl:
  1345. /* nothing */
  1346. {
  1347. node_interface * pOuter = new node_interface;
  1348. pOuter->SetSymName( GenIntfName() );
  1349. pInterfaceInfoDict->SetInterfaceNode( pOuter );
  1350. pOuter->SetAttribute( new battr( ATTR_LOCAL ) );
  1351. pOuter->SetProcTbl( (ImportLevel != 0) ? new SymTable : pBaseSymTbl);
  1352. }
  1353. ;
  1354. InterfaceHeader:
  1355. OptionalAttrList InterfaceName OptionalBaseIF '{'
  1356. {
  1357. node_interface_reference * pRef;
  1358. char * pName = $2;
  1359. node_interface * pIntf = new node_interface();
  1360. $$.pInterface = pIntf;
  1361. pIntf->AddAttributes( $1 );
  1362. // interfaces with inheritance implicitly become object interfaces now...
  1363. if ( $3 )
  1364. {
  1365. if ( !pIntf->FInSummary( ATTR_OBJECT ) )
  1366. {
  1367. pIntf->SetAttribute( ATTR_OBJECT );
  1368. }
  1369. }
  1370. // object intfs get a private scope for procs, imported intfs, too
  1371. if ( pIntf->FInSummary( ATTR_OBJECT ) ||
  1372. ( ImportLevel != 0 ) )
  1373. pIntf->SetProcTbl( new SymTable );
  1374. else
  1375. pIntf->SetProcTbl( pBaseSymTbl );
  1376. pIntf->SetSymName( pName );
  1377. if ( !strcmp( pName, "IUnknown" ) )
  1378. pIntf->SetValidRootInterface();
  1379. // add the interface reference node to the base symbol table as if
  1380. // it were a typedef
  1381. pRef = new node_interface_reference( pIntf );
  1382. SymKey SKey( pName, NAME_DEF );
  1383. named_node* pFound = pBaseSymTbl->SymSearch( SKey );
  1384. //if ( pFound && ( pFound->NodeKind() == NODE_FORWARD || pFound->NodeKind() == NODE_HREF) )
  1385. if (pFound && ( pFound->NodeKind() == NODE_FORWARD || NULL != pFound->GetDefiningFile() ))
  1386. {
  1387. pBaseSymTbl->SymDelete( SKey );
  1388. }
  1389. if(!pBaseSymTbl->SymInsert( SKey, (SymTable *)NULL, pRef ))
  1390. {
  1391. ParseError( DUPLICATE_DEFINITION, pName );
  1392. }
  1393. // set the base interface of this interface
  1394. // this MAY be a node_forward
  1395. pIntf->SetMyBaseInterfaceReference( (named_node *) $3 );
  1396. // interfaces with [async_uuid]
  1397. if ( pIntf->FInSummary( ATTR_ASYNCUUID ) )
  1398. {
  1399. pRef = new node_interface_reference( pIntf );
  1400. char* szAsyncName = new char[strlen(pName)+6];
  1401. strcpy( szAsyncName, "Async" );
  1402. strcat( szAsyncName, pName );
  1403. SymKey SKey( szAsyncName, NAME_DEF );
  1404. named_node* pFound = pBaseSymTbl->SymSearch( SKey );
  1405. pRef->SetSymName(szAsyncName);
  1406. if ( pFound &&
  1407. ( pFound->NodeKind() == NODE_FORWARD || 0 != pFound->GetDefiningFile() ) )
  1408. {
  1409. pBaseSymTbl->SymDelete( SKey );
  1410. }
  1411. if ( !pBaseSymTbl->SymInsert( SKey, (SymTable *)0, pRef ) )
  1412. {
  1413. ParseError( DUPLICATE_DEFINITION, szAsyncName );
  1414. }
  1415. }
  1416. // start the new interface
  1417. pInterfaceInfoDict->SetInterfaceNode( pIntf );
  1418. }
  1419. ;
  1420. OptionalBaseIF:
  1421. ':' Tag
  1422. {
  1423. node_skl * pNode;
  1424. SymKey SKey( $2, NAME_DEF );
  1425. BOOL fNotFound =
  1426. ! ( pNode = pBaseSymTbl->SymSearch( SKey ) );
  1427. if( fNotFound || (pNode->NodeKind() == NODE_FORWARD ) )
  1428. {
  1429. pNode = new node_forward( SKey, pBaseSymTbl );
  1430. ((named_node *)pNode)->SetSymName( $2 );
  1431. }
  1432. //Return a node_forward or a node_interface_reference.
  1433. $$ = pNode;
  1434. }
  1435. | /* Empty */
  1436. {
  1437. $$ = NULL;
  1438. }
  1439. ;
  1440. BaseInterfaceList:
  1441. ':' Tag
  1442. {
  1443. node_skl * pNode;
  1444. SymKey SKey( $2, NAME_DEF );
  1445. BOOL fNotFound =
  1446. ! ( pNode = pBaseSymTbl->SymSearch( SKey ) );
  1447. if( fNotFound || (pNode->NodeKind() == NODE_FORWARD ) )
  1448. {
  1449. pNode = new node_forward( SKey, pBaseSymTbl );
  1450. ((named_node *)pNode)->SetSymName( $2 );
  1451. }
  1452. //Return a new list with a node_forward or a node_interface_reference.
  1453. $$ = new type_node_list;
  1454. if( pNode )
  1455. $$->SetPeer( pNode );
  1456. }
  1457. | BaseInterfaceList ',' Tag
  1458. {
  1459. node_skl * pNode;
  1460. SymKey SKey( $3, NAME_DEF );
  1461. BOOL fNotFound =
  1462. ! ( pNode = pBaseSymTbl->SymSearch( SKey ) );
  1463. if( fNotFound || (pNode->NodeKind() == NODE_FORWARD ) )
  1464. {
  1465. pNode = new node_forward( SKey, pBaseSymTbl );
  1466. ((named_node *)pNode)->SetSymName( $3 );
  1467. }
  1468. //Add a node_forward or a node_interface_reference to the list.
  1469. $$ = $1;
  1470. $$->SetPeer(pNode);
  1471. }
  1472. ;
  1473. InterfaceName:
  1474. KWINTERFACE Tag
  1475. {
  1476. $$ = $2;
  1477. }
  1478. ;
  1479. TypeName:
  1480. TYPENAME
  1481. | LIBNAME "." TYPENAME
  1482. {
  1483. char * szType = $3->GetSymName();
  1484. node_skl * pNode = (named_node *)AddQualifiedReferenceToType($1, szType);
  1485. if (!pNode)
  1486. {
  1487. char * sz = new char [strlen($1) + strlen(szType) + 2];
  1488. strcpy(sz, $1);
  1489. strcat(sz, ".");
  1490. strcat(sz, szType);
  1491. ParseError( UNDEFINED_SYMBOL, sz);
  1492. pNode = $3;
  1493. }
  1494. $$ = pNode;
  1495. }
  1496. ;
  1497. InterfaceBody:
  1498. MultipleImport InterfaceComp
  1499. {
  1500. /**
  1501. ** This production is reduced when there is at least 1 imported
  1502. ** file
  1503. **/
  1504. $$.Imports = $1;
  1505. $$.Members = $2;
  1506. }
  1507. | InterfaceComp
  1508. {
  1509. /**
  1510. ** This production is reduced when there is NO import in the file
  1511. **/
  1512. $$.Imports.Init();
  1513. $$.Members = $1;
  1514. }
  1515. ;
  1516. /**
  1517. ** All the interface components have been reduced.
  1518. **/
  1519. InterfaceComp:
  1520. InterfaceComponents
  1521. | /* Nothing */
  1522. {
  1523. $$.Init();
  1524. }
  1525. ;
  1526. MultipleImport:
  1527. MultipleImport Import
  1528. {
  1529. $$ = $1;
  1530. $$.Merge( $2 );
  1531. }
  1532. | Import
  1533. ;
  1534. Import:
  1535. KWIMPORT ImportList ';'
  1536. {
  1537. $$ = $2;
  1538. }
  1539. | KWIMPORTODLBASE ImportList
  1540. {
  1541. $$ = $2;
  1542. }
  1543. ;
  1544. ImportList:
  1545. ImportName
  1546. | ImportList ',' ImportName
  1547. {
  1548. $$ = $1;
  1549. $$.Merge( $3 );
  1550. }
  1551. ;
  1552. /**
  1553. ** Imports are handled by making them part of the syntax. The following set of
  1554. ** productions control the import. As soon as an import string is seen, we
  1555. ** must get the productions from another idl file. It would be great if we
  1556. ** could recursively call the parser here. But yacc does not generate a
  1557. ** parser which can be recursivel called. So we make the idl syntax right
  1558. ** recursive by introducing "InputFile" at the rhs of the Importname
  1559. ** production. The type graph then gets generated with the imported parts of
  1560. ** the type graph compeleting first. We keep merging the type graphs from the
  1561. ** imported files. The beauty of this is that the parser does not have to do
  1562. ** any work at all. The parse tells the import controller to push his import
  1563. ** level, and switch input from another file. The import controller can do
  1564. ** this very easily. Then when the parser driver asks for the next token, it
  1565. ** will be from the imported file. Thus the parser conspires with the file
  1566. ** handler to fool itself and the lexer. This whole scheme makes it very
  1567. ** easy on all components - the parser, lexer and the file handler.
  1568. **
  1569. ** import of an already imported file is an idempotent operation. We can
  1570. ** generate the type graph of the reduncdantly imported file and then throw it
  1571. ** away, but that is wasteful. Again, the file handler helps. If it finds that
  1572. ** a file was redundantly imported, it just sets itself up so that it returns
  1573. ** an end of file on the next getchar operation on the file. This makes it
  1574. ** very easy for the parser. It can either expect an interface syntax after the
  1575. ** import statement or it can expect an end of file. Thus 2 simple productions
  1576. ** take care of this entire problem.
  1577. **/
  1578. ImportName:
  1579. STRING
  1580. {
  1581. /**
  1582. ** we just obtained the import file name as a string. Immediately
  1583. ** following, we must switch the input from the imported file.
  1584. **/
  1585. // push the current case sensitive setting on the stack
  1586. gCaseStack.Push(gfCaseSensitive);
  1587. // switch to case sensitive mode
  1588. gfCaseSensitive = TRUE;
  1589. pImportCntrl->PushLexLevel();
  1590. if( pImportCntrl->SetNewInputFile( $1 ) != STATUS_OK )
  1591. {
  1592. $$.Init();
  1593. returnflag = 1;
  1594. return;
  1595. }
  1596. /**
  1597. ** update the quick reference import level indicator
  1598. **/
  1599. ImportLevel++;
  1600. // the new file gets its own Zp stack
  1601. PushZpStack( pPackStack, CurrentZp );
  1602. // prepare for anything not in an interface body
  1603. pInterfaceInfoDict->StartNewInterface();
  1604. node_interface * pOuter = new node_interface;
  1605. pOuter->SetSymName( GenIntfName() );
  1606. pInterfaceInfoDict->SetInterfaceNode( pOuter );
  1607. pOuter->SetAttribute( new battr( ATTR_LOCAL ) );
  1608. pOuter->SetProcTbl( (ImportLevel != 0) ? new SymTable : pBaseSymTbl );
  1609. }
  1610. PhantomInputFile
  1611. {
  1612. /**
  1613. ** The phantom interface production is introduced to unify the actions
  1614. ** from a successful and unsuccessful import. An import can be
  1615. ** errorneous if the file being imported has been imported before.
  1616. **/
  1617. BOOL fError = !( ( $$ = $3 ).NonNull() );
  1618. /**
  1619. ** Restore the lexical level of the import controller.
  1620. **/
  1621. pImportCntrl->PopLexLevel();
  1622. pInterfaceInfoDict->EndNewInterface();
  1623. // return to the enclosing files Zp stack
  1624. PopZpStack( pPackStack, CurrentZp );
  1625. ImportLevel--;
  1626. //
  1627. // The filehandler will return an end of file if the file was a
  1628. // redundant import OR there was a genuine end of file. It will set
  1629. // a flag, fRedundantImport to differentiate between the two situations.
  1630. // Report different syntax errors in both these cases.
  1631. //
  1632. if( fError )
  1633. {
  1634. if( fRedundantImport )
  1635. ParseError( REDUNDANT_IMPORT, $1 );
  1636. else
  1637. {
  1638. ParseError( UNEXPECTED_END_OF_FILE, $1 );
  1639. }
  1640. }
  1641. fRedundantImport = FALSE;
  1642. // pop the previous case sensitive mode back off the stack
  1643. gCaseStack.Pop(gfCaseSensitive);
  1644. }
  1645. ;
  1646. PhantomInputFile:
  1647. InputFile
  1648. {
  1649. /**
  1650. ** InputFile is a list of file nodes
  1651. **/
  1652. char * pInputFileName;
  1653. $$ = $1;
  1654. pImportCntrl->GetInputDetails( &pInputFileName );
  1655. AddFileToDB( pInputFileName );
  1656. }
  1657. | EOI
  1658. {
  1659. $$.Init();
  1660. }
  1661. ;
  1662. InterfaceComponents:
  1663. InterfaceComponents InterfaceComponent
  1664. {
  1665. $$ = $1;
  1666. $$.Merge( $2 );
  1667. }
  1668. | InterfaceComponent
  1669. ;
  1670. /* Note that we have to semantically verify that the declaration
  1671. which has operation attributes is indeed a function prototype. */
  1672. InterfaceComponent:
  1673. CPragmaSet
  1674. {
  1675. $$.Init($1);
  1676. }
  1677. | MidlPragmaSet
  1678. {
  1679. $$.Init($1);
  1680. }
  1681. | KWCPPQUOTE '(' STRING ')'
  1682. {
  1683. ParseError( CPP_QUOTE_NOT_OSF, (char *)0 );
  1684. $3 = MakeNewStringWithProperQuoting( $3 );
  1685. $$.Init( new node_echo_string( $3 ) );
  1686. }
  1687. | MethodDeclaration
  1688. | KWMIDLPRAGMA Tag '(' KWDEFAULT ':' MessageNumberList ')'
  1689. {
  1690. node_midl_pragma* pPragma;
  1691. if ( strcmp( $2, "warning" ) )
  1692. {
  1693. ParseError( PRAGMA_SYNTAX_ERROR, 0 );
  1694. }
  1695. pPragma = new node_midl_pragma( mp_MessageEnable, $6 );
  1696. $$.Init( pPragma );
  1697. pPragma->ProcessPragma();
  1698. }
  1699. | KWMIDLPRAGMA Tag '(' Tag ':' MessageNumberList ')'
  1700. {
  1701. PragmaType pt;
  1702. node_midl_pragma* pPragma;
  1703. if ( strcmp( $2, "warning" ) )
  1704. {
  1705. ParseError( PRAGMA_SYNTAX_ERROR, 0 );
  1706. }
  1707. if ( !strcmp( $4, "enable" ) )
  1708. {
  1709. pt = mp_MessageEnable;
  1710. }
  1711. else if ( !strcmp( $4, "disable" ) )
  1712. {
  1713. pt = mp_MessageDisable;
  1714. }
  1715. else
  1716. {
  1717. ParseError( PRAGMA_SYNTAX_ERROR, 0 );
  1718. pt = mp_MessageDisable;
  1719. }
  1720. pPragma = new node_midl_pragma( pt, $6 );
  1721. $$.Init( pPragma );
  1722. pPragma->ProcessPragma();
  1723. }
  1724. ;
  1725. MessageNumberList:
  1726. MessageNumberList NUMERICCONSTANT
  1727. {
  1728. $$->Insert( (void*)(INT_PTR) $2.Val );
  1729. }
  1730. | NUMERICCONSTANT
  1731. {
  1732. $$ = new expr_list;
  1733. $$->Insert( (void*)(INT_PTR) $1.Val );
  1734. }
  1735. ;
  1736. CPragmaSet:
  1737. KWCPRAGMA
  1738. {
  1739. /**
  1740. ** we need to emit the c pragma strings as they are.
  1741. ** we introduce the echo string node, so that the back end can
  1742. ** emit it without even knowing the difference.
  1743. **/
  1744. #define PRAGMA_PACK_STRING ("#pragma pack( ")
  1745. #define PRAGMA_STRING ("#pragma ")
  1746. char * p = new char [ strlen( $1 ) + strlen( PRAGMA_STRING ) + 1 ];
  1747. strcpy( p, PRAGMA_STRING );
  1748. strcat( p, $1 );
  1749. /**
  1750. ** Check to see if the pragma ends in \r and strip it if so.
  1751. ** This happens because the file is opened in binary mode
  1752. ** and unrecognised pragma's are pulled in until the lexer
  1753. ** sees a \n. It's to risky to change the lexer right now
  1754. ** so we hack it here.
  1755. ** -- MikeW 9-Jul-99
  1756. **/
  1757. {
  1758. int lastchar = (int) strlen( p ) - 1;
  1759. if ( '\r' == p[lastchar] )
  1760. p[lastchar] = '\0';
  1761. }
  1762. $$ = new node_echo_string( p );
  1763. }
  1764. | KWCPRAGMAPACK '(' ')'
  1765. {
  1766. node_pragma_pack * pPack;
  1767. /* return to global packing level */
  1768. pPack = new node_pragma_pack( NULL,
  1769. pCommand->GetZeePee(),
  1770. PRAGMA_PACK_RESET );
  1771. CurrentZp = pCommand->GetZeePee();
  1772. $$ = pPack;
  1773. }
  1774. | KWCPRAGMAPACK '(' PackIndex ')'
  1775. {
  1776. /* set current packing level */
  1777. if ( $3 )
  1778. {
  1779. node_pragma_pack * pPack;
  1780. /* switch top to new packing level */
  1781. pPack = new node_pragma_pack( NULL,
  1782. 0,
  1783. PRAGMA_PACK_SET,
  1784. $3 );
  1785. CurrentZp = $3;
  1786. $$ = pPack;
  1787. }
  1788. else
  1789. $$ = NULL;
  1790. }
  1791. | KWCPRAGMAPACK '(' PushOrPop OptPackIndex ')'
  1792. {
  1793. node_pragma_pack * pPack;
  1794. switch( $3 )
  1795. {
  1796. case PRAGMA_PACK_PUSH:
  1797. {
  1798. // do push things
  1799. // push current zp
  1800. /* switch top to new packing level */
  1801. pPack = new node_pragma_pack( NULL,
  1802. CurrentZp,
  1803. PRAGMA_PACK_PUSH,
  1804. $4 );
  1805. pPack->Push( pPackStack );
  1806. $$ = pPack;
  1807. if ( $4 )
  1808. CurrentZp = $4;
  1809. break;
  1810. }
  1811. case PRAGMA_PACK_POP:
  1812. {
  1813. // do pop things
  1814. /* switch top to new packing level */
  1815. pPack = new node_pragma_pack( NULL,
  1816. $4,
  1817. PRAGMA_PACK_POP );
  1818. CurrentZp = pPack->Pop( pPackStack );
  1819. if ( !CurrentZp )
  1820. {
  1821. CurrentZp = pCommand->GetZeePee();
  1822. ParseError(MISMATCHED_PRAGMA_POP, NULL );
  1823. }
  1824. $$ = pPack;
  1825. break;
  1826. }
  1827. default:
  1828. $$ = NULL;
  1829. }
  1830. }
  1831. | KWCPRAGMAPACK '(' PushOrPop ',' IDENTIFIER OptPackIndex ')'
  1832. {
  1833. node_pragma_pack * pPack;
  1834. switch( $3 )
  1835. {
  1836. case PRAGMA_PACK_PUSH:
  1837. {
  1838. // do push things
  1839. // push current zp
  1840. /* switch top to new packing level */
  1841. pPack = new node_pragma_pack( $5,
  1842. CurrentZp,
  1843. PRAGMA_PACK_PUSH,
  1844. $6 );
  1845. pPack->Push( pPackStack );
  1846. $$ = pPack;
  1847. if ( $6 )
  1848. CurrentZp = $6;
  1849. break;
  1850. }
  1851. case PRAGMA_PACK_POP:
  1852. {
  1853. // do pop things
  1854. /* switch top to new packing level */
  1855. pPack = new node_pragma_pack( $5,
  1856. $6,
  1857. PRAGMA_PACK_POP );
  1858. CurrentZp = pPack->Pop( pPackStack );
  1859. if ( !CurrentZp )
  1860. {
  1861. CurrentZp = pCommand->GetZeePee();
  1862. ParseError(MISMATCHED_PRAGMA_POP, NULL );
  1863. }
  1864. $$ = pPack;
  1865. break;
  1866. }
  1867. default:
  1868. $$ = NULL;
  1869. }
  1870. }
  1871. ;
  1872. PushOrPop:
  1873. IDENTIFIER
  1874. {
  1875. if ( !strcmp( $1, "push" ) )
  1876. {
  1877. $$ = PRAGMA_PACK_PUSH;
  1878. }
  1879. else if ( !strcmp( $1, "pop" ) )
  1880. {
  1881. $$ = PRAGMA_PACK_POP;
  1882. }
  1883. else
  1884. {
  1885. ParseError( UNKNOWN_PRAGMA_OPTION, $1);
  1886. $$ = PRAGMA_PACK_GARBAGE;
  1887. }
  1888. }
  1889. ;
  1890. OptPackIndex:
  1891. ',' PackIndex
  1892. {
  1893. $$ = $2;
  1894. }
  1895. | /* null */
  1896. {
  1897. $$ = 0;
  1898. }
  1899. ;
  1900. PackIndex:
  1901. NUMERICCONSTANT
  1902. {
  1903. if (!pCommand->IsValidZeePee( $1.Val ))
  1904. {
  1905. ParseError( INVALID_PACKING_LEVEL, $1.pValStr );
  1906. $$ = DEFAULT_ZEEPEE;
  1907. }
  1908. else
  1909. {
  1910. $$ = $1.Val;
  1911. }
  1912. }
  1913. ;
  1914. MidlPragmaSet:
  1915. KWMPRAGMAIMPORT '(' IDENTIFIER ')'
  1916. {
  1917. /**
  1918. ** We need to set import on and off here
  1919. **/
  1920. char * p;
  1921. if( strcmp( $3, "off" ) == 0 )
  1922. {
  1923. p = "/* import off */";
  1924. fPragmaImportOn = FALSE;
  1925. }
  1926. else if( strcmp( $3, "on" ) == 0 )
  1927. {
  1928. p = "/* import on */";
  1929. fPragmaImportOn = TRUE;
  1930. }
  1931. else
  1932. p = "/* import unknown */";
  1933. $$ = new node_echo_string( p );
  1934. }
  1935. | KWMPRAGMAECHO '(' STRING ')'
  1936. {
  1937. $3 = MakeNewStringWithProperQuoting( $3 );
  1938. $$ = new node_echo_string( $3 );
  1939. }
  1940. | KWMPRAGMAIMPORTCLNTAUX '(' STRING ',' STRING ')'
  1941. {
  1942. $$ = NULL;
  1943. }
  1944. | KWMPRAGMAIMPORTSRVRAUX '(' STRING ',' STRING ')'
  1945. {
  1946. $$ = NULL;
  1947. }
  1948. ;
  1949. Declaration:
  1950. KWDECLGUID '(' Tag ','
  1951. {
  1952. LexContext = LEX_GUID; /* turned off by the lexer */
  1953. }
  1954. Guid ')' ';'
  1955. {
  1956. $$.Init( new node_decl_guid( $3, (node_guid*) $6 ) );
  1957. }
  1958. | KWTYPEDEF OptionalAttrList TypeDeclarationSpecifiers TypedefDeclaratorList
  1959. {
  1960. /**
  1961. ** create new typedef nodes for each of the declarators, apply any
  1962. ** type attributes to the declarator. The declarators will have a
  1963. ** basic type as specied by the Declaration specifiers.
  1964. ** Check for the presence of a init expression. The typedef derives
  1965. ** the declarators from the same place as the other declarators, so
  1966. ** an init list must be explicitly checked for and reported as a
  1967. ** syntax error. But dont report errors for each declarator, instead
  1968. ** report it only once at the end.
  1969. **/
  1970. class _DECLARATOR* pDec = 0;
  1971. char* pName = 0;
  1972. node_skl* pType = 0;
  1973. node_def_fe* pDef = 0;
  1974. DECLARATOR_LIST_MGR pDeclList( $4 );
  1975. /**
  1976. ** prepare for a list of typedefs to be made into interface
  1977. ** components
  1978. **/
  1979. $$.Init();
  1980. while( pDec = pDeclList.DestructiveGetNext() )
  1981. {
  1982. pDef = (node_def_fe *) pDec->pHighest;
  1983. pType = $3.pNode;
  1984. if (NULL == pDef)
  1985. {
  1986. /**
  1987. ** The declaration is a forward declaration following the
  1988. ** goofy mktyplib syntax: typedef struct foo; (or union).
  1989. ** We need to verify that the mktyplib203 switch is set
  1990. ** (only allow this syntax in mktyplib compatibility mode)
  1991. ** and we need to create a forward declaration so that
  1992. ** future references will resolve correctly.
  1993. **/
  1994. pName = pType->GetSymName();
  1995. SymKey SKey( pName, NAME_DEF );
  1996. node_forward * pFwd = new node_forward( SKey, pCurSymTbl );
  1997. pFwd->SetSymName( pName );
  1998. pDef = new node_def_fe(pName, pFwd);
  1999. pDec->Init(pDef);
  2000. if (!pCommand->IsSwitchDefined(SWITCH_MKTYPLIB))
  2001. ParseError( ILLEGAL_USE_OF_MKTYPLIB_SYNTAX, pName);
  2002. }
  2003. else
  2004. {
  2005. pName = pDef->GetSymName();
  2006. }
  2007. /**
  2008. ** set the basic type of the declarator.
  2009. **/
  2010. pDec->pLowest->SetChild( pType );
  2011. // complain about invalid redef of wchar_t or error_status_t
  2012. if (pName)
  2013. {
  2014. if ( strcmp( pName, "wchar_t" ) == 0 )
  2015. {
  2016. node_skl * pN = pType;
  2017. if( !((pN->NodeKind() == NODE_SHORT) &&
  2018. pN->FInSummary( ATTR_UNSIGNED) ) )
  2019. {
  2020. ParseError( WCHAR_T_ILLEGAL, (char *)0 );
  2021. }
  2022. }
  2023. else if( strcmp( pName, "error_status_t" ) == 0 )
  2024. {
  2025. node_skl * pN = pType;
  2026. if( !( pN->FInSummary( ATTR_UNSIGNED) &&
  2027. ((pN->NodeKind() == NODE_LONG) ||
  2028. (pN->NodeKind() == NODE_INT32) ||
  2029. (pN->NodeKind() == NODE_INT) )
  2030. ) )
  2031. {
  2032. ParseError( ERROR_STATUS_T_ILLEGAL, (char *)0 );
  2033. }
  2034. }
  2035. }
  2036. else
  2037. ParseError( BENIGN_SYNTAX_ERROR, "" );
  2038. //
  2039. // if the type specifier is a forward declared type, then
  2040. // the only syntax allowed is when context_handle is applied
  2041. // to the type. If not, report an error
  2042. //
  2043. //gaj CheckSpecialForwardTypedef( pDef, pType, $2);
  2044. /**
  2045. ** The typedef node graph is all set up,
  2046. ** apply attributes and enter into symbol table
  2047. **/
  2048. $$.Add( pDef );
  2049. /**
  2050. ** Remember that we have to apply the attributes to each of
  2051. ** the declarators, so we must clone the attribute list for
  2052. ** each declarator, the apply the type attribute list to each
  2053. ** of the declarators
  2054. **/
  2055. if ( $2.NonNull() )
  2056. {
  2057. pDef->AddAttributes( $2 );
  2058. }
  2059. /**
  2060. ** similarly, apply the remnant attributes collected from
  2061. ** declaration specifiers, to the declarator
  2062. **
  2063. ** Only the first declarator to use a composite type gets to
  2064. ** be the declaration; all the others reference that declaration;
  2065. ** e.g. struct FOO { xxx } foo, *pfoo
  2066. ** is treated as: struct FOO { xxx } foo
  2067. ** struct FOO *pfoo
  2068. **/
  2069. pDec->pLowest->GetModifiers().Merge($3.modifiers);
  2070. $3.modifiers.SetModifier( ATTR_TAGREF );
  2071. // prevent typedef ARRAYFOO ARRAYFOO[10];
  2072. // where ARRAYFOO is not defined.
  2073. // typedef struct SFoo; is valid in /mktyplib203 mode
  2074. // the following complicated if-conditional statements
  2075. // take all those wierd cases into account.
  2076. if ( pType->NodeKind() == NODE_FORWARD && pType->GetChild() == 0 )
  2077. {
  2078. node_skl* pDefChild = pDef->GetChild();
  2079. if ( pDefChild )
  2080. {
  2081. bool fError = pDefChild->NodeKind() == NODE_ARRAY || pDefChild->NodeKind() == NODE_POINTER;
  2082. if ( pType->GetSymName() &&
  2083. pDef->GetSymName() &&
  2084. !strcmp( pType->GetSymName(),
  2085. pDef->GetSymName() ) && fError )
  2086. {
  2087. ParseError( INVALID_TYPE_REDEFINITION, pType->GetSymName() );
  2088. }
  2089. }
  2090. }
  2091. }
  2092. }
  2093. | DeclarationSpecifiers OptionalInitDeclaratorList ';'
  2094. {
  2095. /**
  2096. ** All declarations other than typedefs are collected here.
  2097. ** They are collected and passed up to the interface component
  2098. ** production
  2099. **/
  2100. node_skl * pType = $1.pNode;
  2101. DECLARATOR_LIST_MGR DeclList( $2 );
  2102. #ifdef gajdebug3
  2103. printf("DeclarationSpecifiers OptionalInitDeclaratorList\n");
  2104. #endif
  2105. $$.Init();
  2106. /**
  2107. ** It is possible that there are no declarators, only a type decla-
  2108. ** ration. eg, the definition of a structure.
  2109. **/
  2110. if ( DeclList.NonEmpty() )
  2111. {
  2112. class _DECLARATOR * pDec;
  2113. /**
  2114. ** for each declarator, set the basic type, set the attributes
  2115. ** if any
  2116. **/
  2117. while( pDec = DeclList.DestructiveGetNext() )
  2118. {
  2119. pDec->pLowest->SetChild( pType );
  2120. /**
  2121. ** Apply the remnant attributes from the declaration specifier
  2122. ** prodn to this declarator;
  2123. **/
  2124. // move some modifiers to the top
  2125. MODIFIER_SET TempModifiers = $1.modifiers;
  2126. INITIALIZED_MODIFIER_SET TopModifiers;
  2127. ATTR_T TopAttrs[] = {ATTR_EXTERN, ATTR_STATIC, ATTR_AUTOMATIC, ATTR_REGISTER};
  2128. for(unsigned int i = 0; i < (sizeof(TopAttrs) / sizeof(ATTR_T)); i++)
  2129. {
  2130. ATTR_T ThisAttr = TopAttrs[i];
  2131. if (TempModifiers.IsModifierSet(ThisAttr)) {
  2132. TopModifiers.SetModifier(ThisAttr);
  2133. TempModifiers.ClearModifier(ThisAttr);
  2134. }
  2135. }
  2136. pDec->pLowest->GetModifiers().Merge( TempModifiers );
  2137. pDec->pHighest->GetModifiers().Merge( TopModifiers );
  2138. $1.modifiers.SetModifier( ATTR_TAGREF );
  2139. /**
  2140. ** shove the type node up.
  2141. **/
  2142. $$.Add( (named_node *) pDec->pHighest );
  2143. }
  2144. }
  2145. else
  2146. {
  2147. #ifdef gajdebug3
  2148. printf("\t\t...no declarators\n");
  2149. #endif
  2150. /**
  2151. ** This is the case when no specific declarator existed. Just
  2152. ** pass on the declaration to interface component. However, it
  2153. ** is possible that the declaration is a forward declaration,
  2154. ** in that case, just generate a dummy typedef. The dummy typedef
  2155. ** exists, so that the whole thing is transparent to the back end.
  2156. **/
  2157. named_node * pDef = (named_node *) $1.pNode;
  2158. /**
  2159. ** Apply the remnant attributes from the declaration specifier
  2160. ** prodn to this declarator;
  2161. **/
  2162. pDef->GetModifiers().Merge( $1.modifiers );
  2163. /**
  2164. ** shove the type node up.
  2165. **/
  2166. $$.Add( pDef );
  2167. }
  2168. }
  2169. ;
  2170. TypeDeclarationSpecifiers:
  2171. DeclarationSpecifiers
  2172. | IDENTIFIER
  2173. {
  2174. node_forward * pFwd;
  2175. SymKey SKey( $1, NAME_DEF );
  2176. pFwd = new node_forward( SKey, pCurSymTbl );
  2177. pFwd->SetSymName( $1 );
  2178. $$.pNode = pFwd;
  2179. $$.modifiers.Clear();
  2180. }
  2181. ;
  2182. SimpleTypeSpec:
  2183. BaseTypeSpec
  2184. {
  2185. node_base_type * pNode;
  2186. GetBaseTypeNode( (node_skl**) &pNode,
  2187. $1.TypeSign,
  2188. $1.TypeSize,
  2189. $1.BaseType,
  2190. $1.TypeAttrib);
  2191. $$ = pNode;
  2192. if ( pNode->NodeKind() == NODE_INT )
  2193. ParseError( BAD_CON_INT, NULL );
  2194. }
  2195. | PredefinedTypeSpec
  2196. | TypeName /* TYPENAME */
  2197. ;
  2198. DeclarationSpecifiers:
  2199. DeclarationAccessories TypeSpecifier
  2200. {
  2201. // Hack to make __declspec(align(N)) work. VC has defined that a __declspec(align(N))
  2202. // in front of a structure or union should go with the union. Put the attribute on
  2203. // the struct if this is a new type.
  2204. if ($2.pNode &&
  2205. !$2.pNode->GetModifiers().IsModifierSet( ATTR_TAGREF ) &&
  2206. $1.IsModifierSet( ATTR_DECLSPEC_ALIGN ) &&
  2207. $2.pNode->IsStructOrUnion() )
  2208. {
  2209. MODIFIER_SET TempModifiers;
  2210. TempModifiers.Clear();
  2211. TempModifiers.SetDeclspecAlign( $1.GetDeclspecAlign() );
  2212. $1.ClearModifier( ATTR_DECLSPEC_ALIGN );
  2213. $2.pNode->GetModifiers().Merge( TempModifiers );
  2214. }
  2215. $$.pNode = $2.pNode;
  2216. $$.modifiers = $1;
  2217. $$.modifiers.Merge($2.modifiers);
  2218. }
  2219. | TypeSpecifier
  2220. ;
  2221. DeclarationAccessories:
  2222. DeclarationAccessories StorageClassSpecifier
  2223. {
  2224. $$ = $1;
  2225. $$.Merge($2);
  2226. }
  2227. | DeclarationAccessories TypeQualifier
  2228. {
  2229. $$ = $1;
  2230. $$.Merge($2);
  2231. }
  2232. | StorageClassSpecifier
  2233. | TypeQualifier
  2234. ;
  2235. StorageClassSpecifier:
  2236. KWEXTERN
  2237. {
  2238. $$ = INITIALIZED_MODIFIER_SET(ATTR_EXTERN);
  2239. }
  2240. | KWSTATIC
  2241. {
  2242. $$ = INITIALIZED_MODIFIER_SET(ATTR_STATIC);
  2243. }
  2244. | KWAUTO
  2245. {
  2246. $$ = INITIALIZED_MODIFIER_SET(ATTR_AUTO);
  2247. }
  2248. | KWREGISTER
  2249. {
  2250. $$ = INITIALIZED_MODIFIER_SET(ATTR_REGISTER);
  2251. }
  2252. | MscDeclSpec
  2253. ;
  2254. TypeSpecifier:
  2255. BaseTypeSpec
  2256. {
  2257. node_base_type * pNode;
  2258. GetBaseTypeNode( (node_skl**) &pNode,
  2259. $1.TypeSign,
  2260. $1.TypeSize,
  2261. $1.BaseType,
  2262. $1.TypeAttrib);
  2263. $$.pNode = pNode;
  2264. if ( pNode->NodeKind() == NODE_INT )
  2265. ParseError( BAD_CON_INT, NULL );
  2266. $$.modifiers = INITIALIZED_MODIFIER_SET(ATTR_TAGREF);
  2267. }
  2268. | PredefinedTypeSpec
  2269. {
  2270. $$.pNode = $1;
  2271. $$.modifiers = INITIALIZED_MODIFIER_SET(ATTR_TAGREF);
  2272. }
  2273. | TaggedSpec
  2274. | EnumerationType
  2275. | BitSetType
  2276. {
  2277. $$.pNode = $1;
  2278. $$.modifiers = INITIALIZED_MODIFIER_SET(ATTR_TAGREF);
  2279. }
  2280. | TypeName /* TYPENAME */
  2281. {
  2282. /**
  2283. ** Note that there is no need to check for whether the symbol table
  2284. ** has the entry or not. If it did not, the TYPENAME token would not
  2285. ** have come in. If the TYPENAME is for a forward reference, see
  2286. ** if it has been satisfied; if so, create a NEW typedef that is the
  2287. ** same, but without the forward reference.
  2288. **/
  2289. node_def_fe * pDef = (node_def_fe *) $1;
  2290. if ( ( pDef->NodeKind() == NODE_DEF ) &&
  2291. pDef->GetChild() &&
  2292. ( pDef->GetChild()->NodeKind() == NODE_FORWARD ) )
  2293. {
  2294. node_forward * pFwd = (node_forward *) pDef->GetChild();
  2295. node_skl * pNewSkl = pFwd->ResolveFDecl();
  2296. if ( pNewSkl )
  2297. {
  2298. ATTRLIST alist;
  2299. MODIFIER_SET ModifierSet;
  2300. pDef->GetAttributeList(alist);
  2301. ModifierSet = pDef->GetModifiers();
  2302. pDef = new node_def_fe( pDef->GetSymName(), pNewSkl );
  2303. pDef->SetAttributes(alist);
  2304. pDef->GetModifiers().Clear();
  2305. pDef->GetModifiers().Merge( ModifierSet );
  2306. SymKey SKey(pDef->GetSymName(), NAME_DEF);
  2307. pBaseSymTbl->SymDelete(SKey);
  2308. pBaseSymTbl->SymInsert(SKey, (SymTable *) NULL, (named_node*) pDef);
  2309. }
  2310. };
  2311. $$.pNode = pDef;
  2312. $$.modifiers = INITIALIZED_MODIFIER_SET( ATTR_TAGREF );
  2313. }
  2314. | KWSAFEARRAY DeclarationSpecifiers OptionalDeclarator ')'
  2315. {
  2316. node_skl * pNode = pErrorTypeNode;
  2317. if( $2.pNode )
  2318. {
  2319. if( $3.pHighest )
  2320. {
  2321. $3.pLowest->SetChild( $2.pNode );
  2322. pNode = $3.pHighest;
  2323. ( (named_node *) $3.pLowest)->GetModifiers().Merge( $2.modifiers );
  2324. }
  2325. else
  2326. pNode = $2.pNode;
  2327. }
  2328. $$.pNode = new node_safearray( pNode );
  2329. $$.modifiers = INITIALIZED_MODIFIER_SET( ATTR_TAGREF );
  2330. }
  2331. | KWPIPE TypeSpecifier
  2332. {
  2333. node_skl * pNode = pErrorTypeNode;
  2334. if ($2.pNode )
  2335. {
  2336. pNode = $2.pNode;
  2337. }
  2338. $$.pNode = new node_pipe( pNode );
  2339. $$.modifiers = INITIALIZED_MODIFIER_SET( ATTR_TAGREF );
  2340. }
  2341. ;
  2342. BitSetType:
  2343. IntSize KWBITSET '{' IdentifierList '}'
  2344. {
  2345. ParseError( UNIMPLEMENTED_FEATURE, "bitset" );
  2346. $$ = pErrorTypeNode;
  2347. }
  2348. ;
  2349. IdentifierList:
  2350. IDENTIFIER
  2351. | IdentifierList ',' IDENTIFIER
  2352. ;
  2353. EnumerationType:
  2354. /**
  2355. IntSize EnumSpecifier
  2356. **/
  2357. EnumSpecifier
  2358. ;
  2359. EnumSpecifier:
  2360. KWENUM MscOptDeclSpecList OptionalTag '{' EnumeratorList OptionalComma '}'
  2361. {
  2362. /**
  2363. ** We just obtained a complete enum definition. Check for
  2364. ** duplicate definition and break circular label list;
  2365. **/
  2366. BOOL fFound = FALSE;
  2367. BOOL fEnumIsForwardDecl = FALSE;
  2368. node_skl * pNode;
  2369. SymKey SKey( $3, NAME_ENUM );
  2370. pNode = pBaseSymTbl->SymSearch( SKey );
  2371. if( fFound = (pNode != (node_skl *) NULL) )
  2372. fEnumIsForwardDecl = ( pNode->NodeKind() == NODE_FORWARD || pNode->NodeKind() == NODE_HREF );
  2373. if( fFound && !fEnumIsForwardDecl )
  2374. {
  2375. ParseError( DUPLICATE_DEFINITION, $3 );
  2376. $$.pNode = (node_skl *)pErrorTypeNode;
  2377. }
  2378. else
  2379. {
  2380. /**
  2381. ** This is a new definition of enum. Enter into symbol table
  2382. ** Also, pick up the label graph and attach it.
  2383. **/
  2384. node_enum * pEnum = new node_enum( $3 );
  2385. $$.pNode = pEnum;
  2386. pEnum->SetMembers( $5.NodeList );
  2387. /**
  2388. ** Note that the enum symbol table entry need not have a next
  2389. ** scope since the enum labels are global in scope.If the enum was
  2390. ** a forward decl into the symbol table, delete it.
  2391. **/
  2392. if( fEnumIsForwardDecl )
  2393. {
  2394. pBaseSymTbl->SymDelete( SKey );
  2395. }
  2396. pBaseSymTbl->SymInsert( SKey,
  2397. (SymTable *)NULL,
  2398. (named_node *) $$.pNode );
  2399. CheckGlobalNamesClash( SKey );
  2400. }
  2401. // if the enumerator is sparse, report an error if the
  2402. // switch configuration is not correct.
  2403. if( $5.fSparse )
  2404. ParseError( SPARSE_ENUM, (char *)NULL );
  2405. $$.modifiers = INITIALIZED_MODIFIER_SET();
  2406. /* Fix this goo once VC decides what they are doing.
  2407. The problem is that VC allows modifiers between the
  2408. struct and the tagname, but they are inconsistent in how
  2409. it works. The user can always just put the modifier on
  2410. the first field anyway.
  2411. */
  2412. if ($2.AnyModifiersSet())
  2413. {
  2414. ParseError( ILLEGAL_MODIFIERS_BETWEEN_SEUKEYWORD_AND_BRACE, NULL );
  2415. }
  2416. }
  2417. | KWENUM MscOptDeclSpecList Tag
  2418. {
  2419. /**
  2420. ** Search for the enum definition, if not found, return the type
  2421. ** as a forward declarator node. The semantic analysis will register
  2422. ** the forward declaration and resolve it when the second pass occurs.
  2423. ** See TaggedStruct production for a description on why we want to
  2424. ** enter even a fdecl enum in the symbol table.
  2425. **/
  2426. SymKey SKey( $3, NAME_ENUM );
  2427. $$.pNode = new node_forward( SKey, pBaseSymTbl );
  2428. $$.modifiers = INITIALIZED_MODIFIER_SET( ATTR_TAGREF );
  2429. /* Fix this goo once VC decides what they are doing.
  2430. The problem is that VC allows modifiers between the
  2431. struct and the tagname, but they are inconsistent in how
  2432. it works. The user can always just put the modifier on
  2433. the first field anyway.
  2434. */
  2435. if ($2.AnyModifiersSet())
  2436. {
  2437. ParseError( ILLEGAL_MODIFIERS_BETWEEN_SEUKEYWORD_AND_BRACE, NULL );
  2438. }
  2439. }
  2440. ;
  2441. EnumeratorList:
  2442. Enumerator
  2443. {
  2444. /**
  2445. ** this is the first label on an enum list. Set up the circular list
  2446. ** pointing to the tail, and set it's expr to 0L if there was none
  2447. **/
  2448. expr_node * pExpr;
  2449. node_label * pLabel = (node_label *) $1.pLabel;
  2450. pExpr = ($1.pExpr)
  2451. ? $1.pExpr
  2452. : GetConstant0();
  2453. pLabel->pExpr = pExpr;
  2454. /*
  2455. // NishadM
  2456. // check the expression type
  2457. if ( pExpr->AlwaysGetType() )
  2458. {
  2459. if ( ! ( pExpr->GetType()->IsCompatibleType( ts_FixedPoint ) ) )
  2460. {
  2461. ParseError( EXPR_INCOMPATIBLE_TYPES, pLabel->GetSymName() );
  2462. }
  2463. }
  2464. else
  2465. {
  2466. ParseError( EXPR_INCOMPATIBLE_TYPES, pLabel->GetSymName() );
  2467. }
  2468. */
  2469. $$.fSparse = $1.fSparse;
  2470. $$.pPrevLabel = pLabel;
  2471. $$.NodeList.Init( pLabel );
  2472. }
  2473. | EnumeratorList ',' Enumerator
  2474. {
  2475. /**
  2476. ** This is a new label we reduced.
  2477. **
  2478. ** if there was an expression associated with the label, use that
  2479. ** else use the already collected expression, and add 1 to it.
  2480. **/
  2481. expr_node * pExpr = (expr_node *)0;
  2482. node_label * pLabel = (node_label *) $3.pLabel;
  2483. pExpr = $3.pExpr;
  2484. // next node has no expression, give it an expression of:
  2485. // <prev label> + 1;
  2486. if (pExpr == NULL )
  2487. {
  2488. expr_named_constant * pPrev =
  2489. new expr_named_constant( $1.pPrevLabel->GetSymName(),
  2490. $1.pPrevLabel );
  2491. pExpr = new expr_b_arithmetic(OP_PLUS,
  2492. pPrev,
  2493. GetConstant1() );
  2494. }
  2495. pLabel->pExpr = pExpr;
  2496. $$ = $1;
  2497. $$.NodeList.Add( pLabel );
  2498. $$.pPrevLabel = pLabel;
  2499. $$.fSparse += $3.fSparse;
  2500. }
  2501. ;
  2502. Enumerator:
  2503. OptionalAttrList IDENTIFIER
  2504. {
  2505. /**
  2506. ** We have obtained an enum label, without an expression. Since
  2507. ** we dont know if this is the first label (most probably not),
  2508. ** we just indicate the absence of an expression by an NULL pointer.
  2509. ** The next parse state would know if this was the first or not
  2510. ** and take appropriate action
  2511. **
  2512. ** The enum labels go into the global name space. Search for
  2513. ** duplicates on the base symbol table.
  2514. **/
  2515. node_label * pLabel;
  2516. SymKey SKey( $2, NAME_LABEL );
  2517. if( pBaseSymTbl->SymSearch( SKey ) )
  2518. {
  2519. ParseError( DUPLICATE_DEFINITION, $2 );
  2520. pLabel = new node_label( GenTempName(), NULL );
  2521. }
  2522. else
  2523. {
  2524. /**
  2525. ** If the label has an expression, use it, else it is 0. Also
  2526. ** propogate the expression to $$, so that the next labels will
  2527. ** get it. Note that we DO NOT evaluate the expressions here.
  2528. ** The MIDL compiler will evaluate the expressions later.
  2529. **/
  2530. pLabel = new node_label( $2, NULL );
  2531. /**
  2532. ** Insert into the global table
  2533. **/
  2534. pBaseSymTbl->SymInsert(SKey, (SymTable *)NULL,(named_node *)pLabel);
  2535. CheckGlobalNamesClash( SKey );
  2536. }
  2537. if ( $1.NonNull() )
  2538. {
  2539. pLabel->AddAttributes( $1 );
  2540. }
  2541. $$.pLabel = pLabel;
  2542. $$.pExpr = NULL;
  2543. $$.fSparse = 0;
  2544. }
  2545. | OptionalAttrList IDENTIFIER '=' ConstantExpr
  2546. {
  2547. /**
  2548. ** This enum label has an expression associated with it. Use it.
  2549. ** sparse enums are illegal in osf mode
  2550. **/
  2551. node_label * pLabel;
  2552. SymKey SKey( $2, NAME_LABEL );
  2553. if ($4->IsStringConstant())
  2554. ParseError(ENUM_TYPE_MISMATCH, $2);
  2555. if( pBaseSymTbl->SymSearch( SKey ) )
  2556. {
  2557. ParseError( DUPLICATE_DEFINITION, $2 );
  2558. pLabel = new node_label( GenTempName(), NULL );
  2559. }
  2560. else
  2561. {
  2562. /**
  2563. ** If the label has an expression, use it, else it is 0. Also
  2564. ** propogate the expression to $$, so that the next labels will
  2565. ** get it. Note that we DO NOT evaluate the expressions. The MIDL
  2566. ** compiler will just dump the expressions for the c compiler to
  2567. ** evaluate.
  2568. **/
  2569. pLabel = new node_label( $2, $4 );
  2570. /**
  2571. ** Insert into the global table
  2572. **/
  2573. pBaseSymTbl->SymInsert(SKey, (SymTable *)NULL,(named_node *)pLabel);
  2574. CheckGlobalNamesClash( SKey );
  2575. }
  2576. if ( $1.NonNull() )
  2577. {
  2578. pLabel->AddAttributes( $1 );
  2579. }
  2580. $$.pLabel = pLabel;
  2581. $$.pExpr = $4;
  2582. $$.fSparse = 1;
  2583. }
  2584. ;
  2585. PredefinedTypeSpec:
  2586. InternationalCharacterType
  2587. {
  2588. ParseError( UNIMPLEMENTED_TYPE, KeywordToString( $1 ) );
  2589. $$ = (node_skl *)pErrorTypeNode;
  2590. }
  2591. ;
  2592. BaseTypeSpec:
  2593. KWFLOAT
  2594. {
  2595. $$.BaseType = TYPE_FLOAT;
  2596. $$.TypeSign = SIGN_UNDEF;
  2597. $$.TypeSize = SIZE_UNDEF;
  2598. $$.TypeAttrib = ATT_NONE;
  2599. }
  2600. | KWLONG KWDOUBLE
  2601. {
  2602. $$.BaseType = TYPE_DOUBLE;
  2603. $$.TypeSign = SIGN_UNDEF;
  2604. $$.TypeSize = SIZE_UNDEF;
  2605. $$.TypeAttrib = ATT_NONE;
  2606. }
  2607. | KWDOUBLE
  2608. {
  2609. $$.BaseType = TYPE_DOUBLE;
  2610. $$.TypeSign = SIGN_UNDEF;
  2611. $$.TypeSize = SIZE_UNDEF;
  2612. $$.TypeAttrib = ATT_NONE;
  2613. }
  2614. | KWFLOAT80
  2615. {
  2616. #ifndef SUPPORT_NEW_BASIC_TYPES
  2617. ParseError( TYPE_NOT_SUPPORTED, "__float80");
  2618. #endif
  2619. $$.BaseType = TYPE_FLOAT80;
  2620. $$.TypeSign = SIGN_UNDEF;
  2621. $$.TypeSize = SIZE_UNDEF;
  2622. $$.TypeAttrib = ATT_NONE;
  2623. }
  2624. | KWFLOAT128
  2625. {
  2626. #ifndef SUPPORT_NEW_BASIC_TYPES
  2627. ParseError( TYPE_NOT_SUPPORTED, "__float128");
  2628. #endif
  2629. $$.BaseType = TYPE_FLOAT128;
  2630. $$.TypeSign = SIGN_UNDEF;
  2631. $$.TypeSize = SIZE_UNDEF;
  2632. $$.TypeAttrib = ATT_NONE;
  2633. }
  2634. | KWVOID
  2635. {
  2636. $$.BaseType = TYPE_VOID;
  2637. $$.TypeSign = SIGN_UNDEF;
  2638. $$.TypeSize = SIZE_UNDEF;
  2639. $$.TypeAttrib = ATT_NONE;
  2640. }
  2641. | KWBOOLEAN
  2642. {
  2643. $$.BaseType = TYPE_BOOLEAN;
  2644. $$.TypeSign = SIGN_UNDEF;
  2645. $$.TypeSize = SIZE_UNDEF;
  2646. $$.TypeAttrib = ATT_NONE;
  2647. }
  2648. | KWBYTE
  2649. {
  2650. $$.BaseType = TYPE_BYTE;
  2651. $$.TypeSign = SIGN_UNDEF;
  2652. $$.TypeSize = SIZE_UNDEF;
  2653. $$.TypeAttrib = ATT_NONE;
  2654. }
  2655. | KWHANDLET
  2656. {
  2657. $$.BaseType = TYPE_HANDLE_T;
  2658. $$.TypeSign = SIGN_UNDEF;
  2659. $$.TypeSize = SIZE_UNDEF;
  2660. $$.TypeAttrib = ATT_NONE;
  2661. }
  2662. | IntSpecs
  2663. {
  2664. $$ = $1;
  2665. if( $$.BaseType == TYPE_UNDEF )
  2666. $$.BaseType = TYPE_INT;
  2667. if( $$.TypeSign == SIGN_UNDEF )
  2668. {
  2669. if( ($$.TypeSize != SIZE_SMALL) && ($$.TypeSize != SIZE_CHAR) )
  2670. $$.TypeSign = SIGN_SIGNED;
  2671. }
  2672. }
  2673. | CharSpecs
  2674. {
  2675. $$.BaseType = TYPE_INT;
  2676. $$.TypeSign = $1.TypeSign;
  2677. $$.TypeSize = SIZE_CHAR;
  2678. $$.TypeAttrib = ATT_NONE;
  2679. }
  2680. ;
  2681. CharSpecs:
  2682. SignSpecs KWCHAR
  2683. {
  2684. $$.TypeSign = $1.TypeSign;
  2685. }
  2686. | KWCHAR
  2687. {
  2688. $$.TypeSign = SIGN_UNDEF;
  2689. }
  2690. ;
  2691. IntSpecs:
  2692. MSCW64 IntSpec
  2693. {
  2694. $2.TypeAttrib = ATT_W64;
  2695. $$ = $2;
  2696. }
  2697. | IntSpec
  2698. ;
  2699. IntSpec:
  2700. IntModifiers KWINT
  2701. {
  2702. BaseTypeSpecAnalysis( &($1), TYPE_INT );
  2703. }
  2704. | IntModifiers
  2705. | KWINT IntModifiers
  2706. {
  2707. $$ = $2;
  2708. $$.BaseType = TYPE_UNDEF;
  2709. }
  2710. | KWINT
  2711. {
  2712. $$.BaseType = TYPE_UNDEF;
  2713. $$.TypeSign = SIGN_UNDEF;
  2714. $$.TypeSize = SIZE_UNDEF;
  2715. $$.TypeAttrib = ATT_NONE;
  2716. }
  2717. ;
  2718. IntModifiers:
  2719. IntSize
  2720. {
  2721. $$.TypeSign = SIGN_UNDEF;
  2722. $$.TypeSize = $1;
  2723. $$.BaseType = TYPE_UNDEF;
  2724. $$.TypeAttrib = ATT_NONE;
  2725. }
  2726. | SignSpecs
  2727. | IntSize SignSpecs
  2728. {
  2729. $$.TypeSign = $2.TypeSign;
  2730. $$.TypeSize = $1;
  2731. $$.BaseType = TYPE_UNDEF;
  2732. $$.TypeAttrib = ATT_NONE;
  2733. }
  2734. | SignSpecs IntSize
  2735. {
  2736. $$.TypeSign = $1.TypeSign;
  2737. $$.TypeSize = $2;
  2738. $$.BaseType = TYPE_UNDEF;
  2739. $$.TypeAttrib = ATT_NONE;
  2740. }
  2741. ;
  2742. SignSpecs:
  2743. KWSIGNED
  2744. {
  2745. ParseError(SIGNED_ILLEGAL, (char *)0);
  2746. $$.BaseType = TYPE_UNDEF;
  2747. $$.TypeSign = SIGN_SIGNED;
  2748. $$.TypeSize = SIZE_UNDEF;
  2749. $$.TypeAttrib = ATT_NONE;
  2750. }
  2751. | KWUNSIGNED
  2752. {
  2753. $$.BaseType = TYPE_UNDEF;
  2754. $$.TypeSign = SIGN_UNSIGNED;
  2755. $$.TypeSize = SIZE_UNDEF;
  2756. $$.TypeAttrib = ATT_NONE;
  2757. }
  2758. ;
  2759. IntSize:
  2760. KWHYPER
  2761. {
  2762. $$ = SIZE_HYPER;
  2763. }
  2764. | KWLONG KWLONG
  2765. {
  2766. $$ = SIZE_LONGLONG;
  2767. }
  2768. | KWINT64
  2769. {
  2770. $$ = SIZE_INT64;
  2771. }
  2772. | KWINT128
  2773. {
  2774. #ifndef SUPPORT_NEW_BASIC_TYPES
  2775. ParseError( TYPE_NOT_SUPPORTED, "__int128");
  2776. #endif
  2777. $$ = SIZE_INT128;
  2778. }
  2779. | KWINT3264
  2780. {
  2781. $$ = SIZE_INT3264;
  2782. if( !pCommand->IsSwitchDefined( SWITCH_MS_EXT ) )
  2783. {
  2784. ParseError( INVALID_MODE_FOR_INT3264, 0 );
  2785. }
  2786. }
  2787. | KWINT32
  2788. {
  2789. $$ = SIZE_INT32;
  2790. }
  2791. | KWLONG
  2792. {
  2793. $$ = SIZE_LONG;
  2794. }
  2795. | KWSHORT
  2796. {
  2797. $$ = SIZE_SHORT;
  2798. }
  2799. | KWSMALL
  2800. {
  2801. $$ = SIZE_SMALL;
  2802. }
  2803. ;
  2804. PhantomPushSymtab:
  2805. {
  2806. /**
  2807. ** We just obtained a starter for a new scope. Push the
  2808. ** symbol table to the next level for the rest of the including
  2809. ** production
  2810. **/
  2811. pSymTblMgr->PushSymLevel( &pCurSymTbl );
  2812. }
  2813. ;
  2814. /* START TAGGED SPEC */
  2815. TaggedSpec:
  2816. TaggedStructSpec
  2817. | TaggedUnionSpec
  2818. ;
  2819. /* START TAGGED STRUCT */
  2820. TaggedStructSpec:
  2821. KWSTRUCT MscOptDeclSpecList OptionalTag '{' PhantomPushSymtab StructDeclarationList '}'
  2822. {
  2823. /**
  2824. ** The entire struct was sucessfully reduced. Attach the fields as
  2825. ** members of the struct. Insert a new symbol table entry for the
  2826. ** struct and attach the lower scope of the symbol table to it.
  2827. ** Check for dupliate structure definition
  2828. **/
  2829. BOOL fFound = FALSE;
  2830. BOOL fStructIsForwardDecl = FALSE;
  2831. node_struct * pStruct;
  2832. SymTable * pSymLowerScope = pCurSymTbl;
  2833. SymKey SKey( $3, NAME_TAG );
  2834. /**
  2835. ** discard the inner symbol table contents (unless it had fwds)
  2836. **/
  2837. pCurSymTbl->DiscardScope();
  2838. /**
  2839. ** restore the symbol table level
  2840. **/
  2841. pSymTblMgr->PopSymLevel( &pCurSymTbl );
  2842. /**
  2843. ** if this is a duplicate definition, dont do anything. Note that
  2844. ** the struct tag name shares the global name space with enum and
  2845. ** union tag names.
  2846. **/
  2847. pStruct = (node_struct *) pBaseSymTbl->SymSearch( SKey );
  2848. if( fFound = ( pStruct != (node_struct *)NULL ) )
  2849. fStructIsForwardDecl = (pStruct->NodeKind() == NODE_FORWARD || pStruct->NodeKind() == NODE_HREF);
  2850. if( fFound && !fStructIsForwardDecl )
  2851. {
  2852. ParseError( DUPLICATE_DEFINITION, $3 );
  2853. pStruct = (node_struct *)pErrorTypeNode;
  2854. }
  2855. else
  2856. {
  2857. /**
  2858. ** this is a valid entry. Build the graph for it and
  2859. ** enter into symbol table. If the struct entry was present as
  2860. ** a forward decl, delete it
  2861. **/
  2862. if( fStructIsForwardDecl )
  2863. {
  2864. pBaseSymTbl->SymDelete( SKey );
  2865. }
  2866. pStruct = new node_struct( $3 );
  2867. pStruct->SetMembers( $6 );
  2868. pStruct->SetZeePee( CurrentZp );
  2869. pBaseSymTbl->SymInsert( SKey, pSymLowerScope, pStruct );
  2870. CheckGlobalNamesClash( SKey );
  2871. }
  2872. $$.pNode = pStruct;
  2873. $$.modifiers = INITIALIZED_MODIFIER_SET();
  2874. /* Fix this goo once VC decides what they are doing.
  2875. The problem is that VC allows modifiers between the
  2876. struct and the tagname, but they are inconsistent in how
  2877. it works. The user can always just put the modifier on
  2878. the first field anyway.
  2879. */
  2880. if ($2.AnyModifiersSet())
  2881. {
  2882. ParseError( ILLEGAL_MODIFIERS_BETWEEN_SEUKEYWORD_AND_BRACE, NULL );
  2883. }
  2884. }
  2885. | KWSTRUCT MscOptDeclSpecList Tag
  2886. {
  2887. /**
  2888. ** This is the invocation of a struct. If the struct was not
  2889. ** defined as yet, then return a forward declarator node. The
  2890. ** semantics will register the forward declaration and resolve it.
  2891. ** But there is a loop hole in this. If we do not enter the struct into
  2892. ** the symbol table, the user may define a union/enum of the same name.
  2893. ** We will let him, since we do not yet have an entry in the symbol
  2894. ** table. We will then never check for duplication, since the parser
  2895. ** is the only place we check for this. We will then generate wrong
  2896. ** code, with the struct and a union/enum with the same name !! The
  2897. ** solution is to enter a symbol entry with a fdecl node as the type
  2898. ** graph of the struct.
  2899. **/
  2900. SymKey SKey( $3, NAME_TAG );
  2901. named_node * pNode = new node_forward( SKey, pBaseSymTbl );
  2902. pNode->SetSymName( $3 );
  2903. $$.pNode = pNode;
  2904. $$.modifiers = INITIALIZED_MODIFIER_SET( ATTR_TAGREF );
  2905. /* Fix this goo once VC decides what they are doing.
  2906. The problem is that VC allows modifiers between the
  2907. struct and the tagname, but they are inconsistent in how
  2908. it works. The user can always just put the modifier on
  2909. the first field anyway.
  2910. */
  2911. if ($2.AnyModifiersSet())
  2912. {
  2913. ParseError( ILLEGAL_MODIFIERS_BETWEEN_SEUKEYWORD_AND_BRACE, NULL );
  2914. }
  2915. }
  2916. ;
  2917. OptionalTag:
  2918. Tag
  2919. | /* Empty */
  2920. {
  2921. $$ = GenCompName();
  2922. }
  2923. ;
  2924. Tag:
  2925. IDENTIFIER
  2926. {
  2927. $$ = $1;
  2928. }
  2929. | TypeName
  2930. {
  2931. //$$ = $1;
  2932. $$ = $1->GetCurrentSpelling();
  2933. }
  2934. ;
  2935. StructDeclarationList:
  2936. StructDeclarationList MemberDeclaration
  2937. {
  2938. $$.Merge( $2 );
  2939. }
  2940. | MemberDeclaration
  2941. ;
  2942. MemberDeclaration:
  2943. OptionalAttrList DeclarationSpecifiers MemberDeclaratorList ';'
  2944. {
  2945. /**
  2946. ** This is a complete field declaration. For each declarator,
  2947. ** set up a field with the basic type as the declaration specifier,
  2948. ** apply the field attributes, and add to the list of fields for the
  2949. ** struct / union
  2950. ** field
  2951. **/
  2952. class _DECLARATOR * pDec;
  2953. node_skl * pType;
  2954. DECLARATOR_LIST_MGR DeclList( $3 );
  2955. $$.Init();
  2956. while( pDec = DeclList.DestructiveGetNext() )
  2957. {
  2958. node_field * pField = (node_field *) pDec->pHighest;
  2959. /**
  2960. ** if the field was a bit field, we need to set up some additional
  2961. ** info.
  2962. **/
  2963. pType = $2.pNode;
  2964. pDec->pLowest->SetChild( pType );
  2965. /**
  2966. ** Apply the field attributes and set the field as part of the
  2967. ** list of fields of the struct/union
  2968. **/
  2969. if ( $1.NonNull() )
  2970. {
  2971. pField->AddAttributes( $1 );
  2972. }
  2973. /**
  2974. ** similarly, apply the remnant attributes collected from
  2975. ** declaration specifiers, to the declarator
  2976. **/
  2977. pDec->pLowest->GetModifiers().Merge( $2.modifiers );
  2978. /**
  2979. ** shove the type graph up
  2980. **/
  2981. $$.Add( pField );
  2982. }
  2983. }
  2984. ;
  2985. /* START UNION */
  2986. TaggedUnionSpec:
  2987. KWUNION MscOptDeclSpecList OptionalTag '{' PhantomPushSymtab UnionBody '}'
  2988. {
  2989. /**
  2990. ** The union bosy has been completely reduced. Attach the fields as
  2991. ** members, insert a new symbol table entry for the union
  2992. **/
  2993. BOOL fFound = FALSE;
  2994. BOOL fUnionIsForwardDecl = FALSE;
  2995. node_union * pUnion;
  2996. SymTable * pSymLowerScope = pCurSymTbl;
  2997. SymKey SKey( $3, NAME_UNION );
  2998. /**
  2999. ** discard the inner symbol table contents (unless it had fwds)
  3000. **/
  3001. pCurSymTbl->DiscardScope();
  3002. /**
  3003. ** restore the symbol table level
  3004. **/
  3005. pSymTblMgr->PopSymLevel( &pCurSymTbl );
  3006. /**
  3007. ** if this is a duplicate definition, dont do anything, else
  3008. ** enter into the symbol table, attach members. Note that the
  3009. ** symbol table search is actually a search for the tag becuase
  3010. ** the union tag shares the same name as the struct/enum names
  3011. **/
  3012. pUnion = (node_union *)pBaseSymTbl->SymSearch( SKey );
  3013. if( fFound = (pUnion != (node_union *) NULL ) )
  3014. fUnionIsForwardDecl = ( pUnion->NodeKind() == NODE_FORWARD || pUnion->NodeKind() == NODE_HREF );
  3015. if( fFound && !fUnionIsForwardDecl )
  3016. {
  3017. ParseError( DUPLICATE_DEFINITION, $3 );
  3018. pUnion = (node_union *)pErrorTypeNode;
  3019. }
  3020. else
  3021. {
  3022. /**
  3023. ** This is a valid entry, build the type graph and insert into
  3024. ** the symbol table. Delete the entry first if it was a forward
  3025. ** decl.
  3026. **/
  3027. pUnion = new node_union( $3 );
  3028. pUnion->SetMembers( $6 );
  3029. if( fUnionIsForwardDecl )
  3030. {
  3031. pBaseSymTbl->SymDelete( SKey );
  3032. }
  3033. pBaseSymTbl->SymInsert( SKey, pSymLowerScope, pUnion );
  3034. CheckGlobalNamesClash( SKey );
  3035. }
  3036. /**
  3037. ** pass this union up
  3038. **/
  3039. pUnion->SetZeePee( CurrentZp );
  3040. $$.pNode = pUnion;
  3041. $$.modifiers = INITIALIZED_MODIFIER_SET();
  3042. /* Fix this goo once VC decides what they are doing.
  3043. The problem is that VC allows modifiers between the
  3044. struct and the tagname, but they are inconsistent in how
  3045. it works. The user can always just put the modifier on
  3046. the first field anyway.
  3047. */
  3048. if ($2.AnyModifiersSet())
  3049. {
  3050. ParseError( ILLEGAL_MODIFIERS_BETWEEN_SEUKEYWORD_AND_BRACE, NULL );
  3051. }
  3052. }
  3053. | KWUNION MscOptDeclSpecList Tag
  3054. {
  3055. /**
  3056. ** this is an invocation of the union. If the union was not defined
  3057. ** then return a forward declarator node as the type node. The
  3058. ** semantics will register the forward declaration and resolve it
  3059. ** later. See TaggedStruct production for an explanation why we want to
  3060. ** enter even a forward declaration into the symbol table.
  3061. **/
  3062. SymKey SKey( $3, NAME_UNION );
  3063. named_node * pNode = new node_forward( SKey, pBaseSymTbl );
  3064. pNode->SetSymName( $3 );
  3065. $$.pNode = pNode;
  3066. $$.modifiers = INITIALIZED_MODIFIER_SET( ATTR_TAGREF );
  3067. /* Fix this goo once VC decides what they are doing.
  3068. The problem is that VC allows modifiers between the
  3069. struct and the tagname, but they are inconsistent in how
  3070. it works. The user can always just put the modifier on
  3071. the first field anyway.
  3072. */
  3073. if ($2.AnyModifiersSet())
  3074. {
  3075. ParseError( ILLEGAL_MODIFIERS_BETWEEN_SEUKEYWORD_AND_BRACE, NULL );
  3076. }
  3077. }
  3078. | KWUNION MscOptDeclSpecList OptionalTag NidlUnionSwitch '{' PhantomPushSymtab NidlUnionBody '}'
  3079. {
  3080. /**
  3081. ** The union body has been completely reduced. Attach the fields as
  3082. ** members, insert a new symbol table entry for the union
  3083. **/
  3084. BOOL fFound = FALSE;
  3085. BOOL fStructIsForwardDecl = FALSE;
  3086. node_en_union * pUnion;
  3087. SymTable * pSymLowerScope = pCurSymTbl;
  3088. /**
  3089. ** discard the inner symbol table contents (unless it had fwds)
  3090. **/
  3091. pCurSymTbl->DiscardScope();
  3092. /**
  3093. ** restore the symbol table level
  3094. **/
  3095. pSymTblMgr->PopSymLevel( &pCurSymTbl );
  3096. pUnion = new node_en_union( GenCompName() );
  3097. pUnion->SetMembers( $7 );
  3098. SymKey SKey( pUnion->GetSymName(), NAME_UNION );
  3099. pBaseSymTbl->SymInsert( SKey, pSymLowerScope, pUnion );
  3100. CheckGlobalNamesClash( SKey );
  3101. //
  3102. // The union is inserted into the base symbol table.
  3103. // Now insert into the base symbol table, a new struct entry
  3104. // corresponding to the struct entry that the encapsulated union
  3105. // results in.
  3106. //
  3107. pSymTblMgr->PushSymLevel( &pCurSymTbl );
  3108. SIBLING_LIST Fields;
  3109. node_field * pSwitchField = (node_field *) $4.pNode;
  3110. node_field * pUnionField = new node_field;
  3111. node_switch_type * pSwType = new node_switch_type(
  3112. pSwitchField->GetChild() );
  3113. if( IsTempName( $4.pName ) )
  3114. $4.pName = "tagged_union";
  3115. pUnionField->SetSymName( $4.pName );
  3116. pUnionField->SetChild( pUnion );
  3117. Fields.Init( pSwitchField );
  3118. Fields.Add( pUnionField );
  3119. //
  3120. // apply the switch_is attribute to the union field.
  3121. //
  3122. pUnionField->SetAttribute( $4.pSwitch );
  3123. // and the switch_type attribute to the union itself
  3124. pUnion->SetAttribute( pSwType );
  3125. //
  3126. // current symbol table is pointing to a new scope. Enter the two
  3127. // fields into this scope.
  3128. //
  3129. SKey.SetKind( NAME_MEMBER );
  3130. SKey.SetString( pSwitchField->GetSymName() );
  3131. pCurSymTbl->SymInsert( SKey, (SymTable *)0, pSwitchField );
  3132. CheckGlobalNamesClash( SKey );
  3133. SKey.SetString( pUnionField->GetSymName() );
  3134. pCurSymTbl->SymInsert( SKey, (SymTable *)0, pUnionField );
  3135. CheckGlobalNamesClash( SKey );
  3136. pSymLowerScope = pCurSymTbl;
  3137. pSymTblMgr->PopSymLevel( &pCurSymTbl );
  3138. //
  3139. // create a new structure entry and enter into the symbol table.
  3140. //
  3141. node_struct * pStruct;
  3142. SKey.SetKind( NAME_UNION );
  3143. SKey.SetString( $3 );
  3144. pStruct = (node_struct *)pBaseSymTbl->SymSearch( SKey );
  3145. if( fFound = ( pStruct != (node_struct *)NULL ) )
  3146. fStructIsForwardDecl = (pStruct->NodeKind() == NODE_FORWARD || pStruct->NodeKind() == NODE_HREF );
  3147. if( fFound && !fStructIsForwardDecl )
  3148. {
  3149. ParseError( DUPLICATE_DEFINITION, $3 );
  3150. pStruct = (node_struct *)pErrorTypeNode;
  3151. }
  3152. else
  3153. {
  3154. /**
  3155. ** this is a valid entry. Build the graph for it and
  3156. ** enter into symbol table. If the struct entry was present as
  3157. ** a forward decl, delete it
  3158. **/
  3159. // enter the struct as a union.
  3160. SKey.SetKind( NAME_UNION );
  3161. SKey.SetString( $3 );
  3162. if( fStructIsForwardDecl )
  3163. {
  3164. pBaseSymTbl->SymDelete( SKey );
  3165. }
  3166. pStruct = new node_en_struct( $3 );
  3167. pStruct->SetMembers( Fields );
  3168. pStruct->SetZeePee( CurrentZp );
  3169. pBaseSymTbl->SymInsert( SKey, pSymLowerScope, pStruct );
  3170. CheckGlobalNamesClash( SKey );
  3171. }
  3172. pUnion->SetZeePee( CurrentZp );
  3173. $$.pNode = pStruct;
  3174. $$.modifiers = INITIALIZED_MODIFIER_SET();
  3175. /* Fix this goo once VC decides what they are doing.
  3176. The problem is that VC allows modifiers between the
  3177. struct and the tagname, but they are inconsistent in how
  3178. it works. The user can always just put the modifier on
  3179. the first field anyway.
  3180. */
  3181. if ($2.AnyModifiersSet())
  3182. {
  3183. ParseError( ILLEGAL_MODIFIERS_BETWEEN_SEUKEYWORD_AND_BRACE, NULL );
  3184. }
  3185. }
  3186. ;
  3187. UnionBody:
  3188. UnionCases
  3189. ;
  3190. UnionCases:
  3191. UnionCases UnionCase
  3192. {
  3193. ($$ = $1).Merge( $2 );
  3194. }
  3195. | UnionCase
  3196. ;
  3197. UnionCase:
  3198. UnionCaseLabel MemberDeclaration
  3199. {
  3200. /**
  3201. ** for each of the fields, attach the case label attribute.
  3202. **/
  3203. named_node * pNode;
  3204. SIBLING_ITER MemIter( $2 );
  3205. $$ = $2;
  3206. while( pNode = MemIter.Next() )
  3207. {
  3208. pNode->SetAttribute( $1 );
  3209. }
  3210. }
  3211. | UnionCaseLabel ';'
  3212. {
  3213. /**
  3214. ** An empty arm. Allocate a field with a node_error as a basic type
  3215. ** and set the attribute as a case label
  3216. **/
  3217. node_field * pField = new node_field( GenTempName() );
  3218. pField->SetChild( pErrorTypeNode );
  3219. pField->SetAttribute( $1 );
  3220. /**
  3221. ** Generate a list of union fields and add this to the list of
  3222. ** union fields
  3223. **/
  3224. $$.Init( pField );
  3225. }
  3226. | MemberDeclaration
  3227. {
  3228. /**
  3229. ** A member declaration without a case label
  3230. **/
  3231. $$ = $1;
  3232. }
  3233. | DefaultCase
  3234. ;
  3235. UnionCaseLabel:
  3236. '[' KWCASE '(' ConstantExprs ')' ']'
  3237. {
  3238. $$ = new node_case( $4 );
  3239. }
  3240. ;
  3241. DefaultCase:
  3242. '[' KWDEFAULT ']' MemberDeclaration
  3243. {
  3244. named_node * pNode;
  3245. SIBLING_ITER MemIter( $4 );
  3246. $$ = $4;
  3247. while( pNode = MemIter.Next() )
  3248. {
  3249. pNode->SetAttribute( ATTR_DEFAULT );
  3250. }
  3251. }
  3252. | '[' KWDEFAULT ']' ';'
  3253. {
  3254. /**
  3255. ** This is a default with an empty arm. Set up a dummy field.
  3256. ** The upper productions will then mark set field with a
  3257. ** default attribute during semantic analysis. The type of this field
  3258. ** is set up to be an error node for uniformity.
  3259. **/
  3260. node_field * pField = new node_field( GenTempName() );
  3261. pField->SetAttribute( ATTR_DEFAULT );
  3262. pField->SetChild( pErrorTypeNode );
  3263. $$.Init( pField );
  3264. }
  3265. ;
  3266. NidlUnionSwitch:
  3267. SwitchSpec
  3268. {
  3269. $$ = $1;
  3270. $$.pName = GenCompName();
  3271. }
  3272. | SwitchSpec UnionName
  3273. {
  3274. $$ = $1;
  3275. $$.pName = $2;
  3276. }
  3277. ;
  3278. NidlUnionBody:
  3279. NidlUnionCases
  3280. {
  3281. $$ = $1.CaseList;
  3282. if( $1.DefCount > 1 )
  3283. ParseError( TWO_DEFAULT_CASES, (char *)0 );
  3284. }
  3285. ;
  3286. NidlUnionCases:
  3287. NidlUnionCases NidlUnionCase
  3288. {
  3289. $$.DefCount += $2.DefCount;
  3290. $$.CaseList.Merge( $2.CaseList );
  3291. }
  3292. | NidlUnionCase
  3293. ;
  3294. NidlUnionCase:
  3295. NidlUnionCaseLabelList NidlMemberDeclaration
  3296. {
  3297. named_node * pNode;
  3298. //
  3299. // set the case and default attributes.
  3300. //
  3301. $$.CaseList = $2;
  3302. if( $1.pExprList && $1.pExprList->GetCount() )
  3303. {
  3304. SIBLING_ITER CaseIter( $2 );
  3305. while( pNode = CaseIter.Next() )
  3306. {
  3307. pNode->SetAttribute( new node_case( $1.pExprList ));
  3308. }
  3309. }
  3310. //
  3311. // pick up default attribute. pick up the count of number of
  3312. // times the user specified default so that we can report the
  3313. // error later.
  3314. // Let the default case list count travel upward to report an
  3315. // error when the total list of case labels is seen.
  3316. //
  3317. if( $1.pDefault && ( $$.DefCount = $1.DefCount ) )
  3318. {
  3319. SIBLING_ITER CaseIter( $2 );
  3320. while( pNode = CaseIter.Next() )
  3321. {
  3322. pNode->SetAttribute( $1.pDefault );
  3323. }
  3324. }
  3325. }
  3326. ;
  3327. NidlMemberDeclaration:
  3328. MemberDeclaration
  3329. | ';'
  3330. {
  3331. node_field * pNode = new node_field( GenTempName() );
  3332. pNode->SetChild( pErrorTypeNode );
  3333. $$.Init( pNode );
  3334. }
  3335. ;
  3336. NidlUnionCaseLabelList:
  3337. NidlUnionCaseLabelList NidlUnionCaseLabel
  3338. {
  3339. if( $2.pExpr )
  3340. $$.pExprList->SetPeer( $2.pExpr );
  3341. if( !($$.pDefault) )
  3342. $$.pDefault = $2.pDefault;
  3343. if( $2.pDefault )
  3344. $$.DefCount++;
  3345. }
  3346. | NidlUnionCaseLabel
  3347. {
  3348. $$.pExprList = new expr_list;
  3349. if( $1.pExpr )
  3350. $$.pExprList->SetPeer( $1.pExpr );
  3351. if( $$.pDefault = $1.pDefault)
  3352. {
  3353. $$.DefCount = 1;
  3354. }
  3355. }
  3356. ;
  3357. NidlUnionCaseLabel:
  3358. KWCASE ConstantExpr ':'
  3359. {
  3360. $$.pExpr = $2;
  3361. $$.pDefault = 0;
  3362. }
  3363. | KWDEFAULT ':'
  3364. {
  3365. $$.pExpr = 0;
  3366. $$.pDefault = new battr( ATTR_DEFAULT );
  3367. }
  3368. ;
  3369. SwitchSpec:
  3370. KWSWITCH '(' SwitchTypeSpec IDENTIFIER ')'
  3371. {
  3372. node_field * pField = new node_field( $4 );
  3373. $$.pSwitch = new node_switch_is( new expr_variable( $4, pField ));
  3374. $$.pNode = pField;
  3375. pField->SetChild( $3 );
  3376. pField->GetModifiers().SetModifier( ATTR_TAGREF );
  3377. }
  3378. ;
  3379. UnionName:
  3380. IDENTIFIER
  3381. ;
  3382. /**
  3383. ** NIDL UNION END
  3384. **/
  3385. ConstantExprs:
  3386. ConstantExprs ',' ConstantExpr
  3387. {
  3388. $$->SetPeer( $3 );
  3389. }
  3390. | ConstantExpr
  3391. {
  3392. $$ = new expr_list;
  3393. $$->SetPeer( $1 );
  3394. }
  3395. ;
  3396. /* END UNION */
  3397. TypeQualifier:
  3398. KWVOLATILE
  3399. {
  3400. $$ = INITIALIZED_MODIFIER_SET(ATTR_VOLATILE);
  3401. }
  3402. | KWCONST
  3403. {
  3404. $$ = INITIALIZED_MODIFIER_SET(ATTR_CONST);
  3405. }
  3406. | KW_C_INLINE
  3407. {
  3408. $$ = INITIALIZED_MODIFIER_SET(ATTR_C_INLINE);
  3409. }
  3410. ;
  3411. MemberDeclaratorList:
  3412. MemberDeclarator
  3413. {
  3414. $$.Init( $1 );
  3415. }
  3416. | MemberDeclaratorList ',' MemberDeclarator
  3417. {
  3418. $$ = $1;
  3419. $$.Add( $3 );
  3420. }
  3421. ;
  3422. MemberDeclarator:
  3423. Declarator
  3424. {
  3425. /**
  3426. ** a declarator without bit fields specified; a plain field.
  3427. **/
  3428. if ( ($1.pHighest == NULL)
  3429. || ( $1.pHighest->NodeKind() != NODE_ID ))
  3430. {
  3431. // gaj - report error
  3432. ParseError( BENIGN_SYNTAX_ERROR, "expecting a declarator");
  3433. }
  3434. else
  3435. {
  3436. // convert top node of declarator chain to node_field
  3437. // and add the field to the symbol table
  3438. node_field * pField = new node_field(
  3439. (node_id_fe *) $1.pHighest );
  3440. char * pName = pField->GetSymName();
  3441. SymKey SKey( pName, NAME_MEMBER );
  3442. $$.pHighest = pField;
  3443. // if the top node was the only node, set pLowest accordingly
  3444. $$.pLowest = ( $1.pLowest == $1.pHighest ) ?
  3445. pField : $1.pLowest ;
  3446. delete (node_id_fe *) $1.pHighest;
  3447. if( !pCurSymTbl->SymInsert( SKey, (SymTable *)NULL, pField ) )
  3448. {
  3449. ParseError( DUPLICATE_DEFINITION, pName );
  3450. }
  3451. else
  3452. CheckGlobalNamesClash( SKey );
  3453. };
  3454. }
  3455. | ':' ConstantExpr
  3456. {
  3457. /**
  3458. ** This is a declarator specified without the field name
  3459. **/
  3460. node_bitfield * pField = new node_bitfield();
  3461. char * pName = GenTempName();
  3462. pField->SetSymName(pName);
  3463. $$.pHighest = pField;
  3464. $$.pLowest = pField;
  3465. // add the field to the symbol table
  3466. SymKey SKey( pName, NAME_MEMBER );
  3467. if( !pCurSymTbl->SymInsert( SKey, (SymTable *)NULL, pField ) )
  3468. {
  3469. ParseError( DUPLICATE_DEFINITION, pName );
  3470. }
  3471. else
  3472. CheckGlobalNamesClash( SKey );
  3473. pField->fBitField = (unsigned char)$2->Evaluate();
  3474. }
  3475. | Declarator ':' ConstantExpr
  3476. {
  3477. /**
  3478. ** The complete bit field specification.
  3479. **/
  3480. if ( ($1.pHighest == NULL)
  3481. || ( $1.pHighest->NodeKind() != NODE_ID ))
  3482. {
  3483. // gaj - report error
  3484. }
  3485. else
  3486. {
  3487. // convert top node of declarator chain to node_field
  3488. node_bitfield * pField = new node_bitfield( (node_id_fe *) $1.pHighest );
  3489. char * pName = pField->GetSymName();
  3490. $$.pHighest = pField;
  3491. // if the top node was the only node, set pLowest accordingly
  3492. $$.pLowest = ( $1.pLowest == $1.pHighest ) ? pField : $1.pLowest;
  3493. delete (node_id_fe *) $1.pHighest;
  3494. // add the field to the symbol table
  3495. SymKey SKey( pName, NAME_MEMBER );
  3496. if( !pCurSymTbl->SymInsert( SKey, (SymTable *)NULL, pField ) )
  3497. {
  3498. ParseError( DUPLICATE_DEFINITION, pName );
  3499. }
  3500. else
  3501. CheckGlobalNamesClash( SKey );
  3502. pField->fBitField = (unsigned char)$3->Evaluate();
  3503. }
  3504. }
  3505. | /** Empty **/
  3506. {
  3507. // this is used for unnamed nested struct references
  3508. node_field * pField = new node_field();
  3509. char * pName = GenTempName();
  3510. pField->SetSymName( pName);
  3511. $$.pHighest = pField;
  3512. $$.pLowest = pField;
  3513. }
  3514. ;
  3515. OptionalInitDeclaratorList:
  3516. InitDeclaratorList
  3517. | /* Empty */
  3518. {
  3519. $$.Init();
  3520. }
  3521. ;
  3522. InitDeclaratorList:
  3523. InitDeclarator
  3524. {
  3525. $$.Init( $1 );
  3526. }
  3527. | InitDeclaratorList ',' InitDeclarator
  3528. {
  3529. $$ = $1;
  3530. $$.Add( $3 );
  3531. }
  3532. ;
  3533. InitDeclarator:
  3534. Declarator
  3535. {
  3536. node_id_fe * pID = (node_id_fe *) $1.pHighest;
  3537. /**
  3538. ** If the top node of the declarator is null, create a dummy ID
  3539. ** but not if the top is a proc...
  3540. **/
  3541. if ( ($1.pHighest == NULL)
  3542. || ( ( $1.pHighest->NodeKind() != NODE_ID )
  3543. && ( $1.pHighest->NodeKind() != NODE_PROC) ) )
  3544. {
  3545. pID = new node_id_fe( GenTempName() );
  3546. pID->SetChild( $1.pHighest );
  3547. $$.pHighest = pID;
  3548. $$.pLowest = ( $1.pLowest ) ? $1.pLowest : pID; // in case of null
  3549. };
  3550. /**
  3551. ** and add the id to the symbol table
  3552. ** for node_proc's, leave original in symbol table
  3553. **/
  3554. if ( $1.pHighest->NodeKind() != NODE_PROC )
  3555. {
  3556. char * pName = pID->GetSymName();
  3557. SymKey SKey( pName, NAME_ID );
  3558. if( !pCurSymTbl->SymInsert( SKey, (SymTable *)NULL, pID ) )
  3559. {
  3560. ParseError( DUPLICATE_DEFINITION, pName );
  3561. }
  3562. else
  3563. CheckGlobalNamesClash( SKey );
  3564. }
  3565. };
  3566. | Declarator '=' Initializer
  3567. {
  3568. if ( ($1.pHighest == NULL)
  3569. || ( $1.pHighest->NodeKind() != NODE_ID ))
  3570. {
  3571. // gaj - report error
  3572. }
  3573. else
  3574. {
  3575. node_id_fe * pID = (node_id_fe *) $1.pHighest;
  3576. // fill in initializer
  3577. pID->pInit = $3;
  3578. $$ = $1;
  3579. // and add the id to the symbol table
  3580. char * pName = pID->GetSymName();
  3581. SymKey SKey( pName, NAME_ID );
  3582. if( !pCurSymTbl->SymInsert( SKey, (SymTable *)NULL, pID ) )
  3583. {
  3584. ParseError( DUPLICATE_DEFINITION, pName );
  3585. }
  3586. else
  3587. CheckGlobalNamesClash( SKey );
  3588. };
  3589. }
  3590. ;
  3591. TypedefDeclaratorList:
  3592. ';'
  3593. {
  3594. $$.Init();
  3595. }
  3596. | TypedefDeclaratorListElement ';'
  3597. ;
  3598. TypedefDeclaratorListElement:
  3599. TypedefDeclarator
  3600. {
  3601. $$.Init( $1 );
  3602. }
  3603. | TypedefDeclaratorListElement ',' TypedefDeclarator
  3604. {
  3605. $$ = $1;
  3606. $$.Add( $3 );
  3607. }
  3608. ;
  3609. TypedefDeclarator:
  3610. Declarator
  3611. {
  3612. node_def_fe * pDef;
  3613. char * pName;
  3614. if ($1.pHighest == NULL)
  3615. {
  3616. // gaj - report error
  3617. }
  3618. else if ( $1.pHighest->NodeKind() == NODE_PROC )
  3619. {
  3620. // build new node_def and attach to top
  3621. node_proc * pProc = (node_proc *) $1.pHighest;
  3622. pName = pProc->GetSymName();
  3623. pDef = new node_def_fe( (node_proc *) $1.pHighest );
  3624. pDef->SetSymName(pName);
  3625. pDef->SetChild( $1.pHighest );
  3626. if ( !strcmp(pName, "HRESULT") || !strcmp(pName, "SCODE") )
  3627. pDef->SetIsHResultOrSCode();
  3628. $$.pHighest = pDef;
  3629. $$.pLowest = $1.pLowest;
  3630. SymKey SkeyOld( pName, NAME_PROC );
  3631. pInterfaceInfoDict->GetInterfaceProcTable()->SymDelete( SkeyOld );
  3632. SymKey SKey( pName, NAME_DEF );
  3633. if( !pCurSymTbl->SymInsert( SKey, (SymTable *)NULL, pDef ) )
  3634. {
  3635. ParseError( DUPLICATE_DEFINITION, pName );
  3636. }
  3637. else
  3638. CheckGlobalNamesClash( SKey );
  3639. }
  3640. else if ( $1.pHighest->NodeKind() == NODE_ID )
  3641. {
  3642. // convert top node of declarator chain to node_def
  3643. // and add the def to the symbol table
  3644. node_def_fe * pDef = new node_def_fe( (node_id_fe *) $1.pHighest );
  3645. char * pName = pDef->GetSymName();
  3646. SymKey SKey( pName, NAME_DEF );
  3647. if ( !pName )
  3648. pDef->SetSymName( GenTempName() );
  3649. if ( !strcmp(pName, "HRESULT") || !strcmp(pName, "SCODE") )
  3650. pDef->SetIsHResultOrSCode();
  3651. $$.pHighest = pDef;
  3652. // if the top node was the only node, set pLowest accordingly
  3653. $$.pLowest = ( $1.pLowest == $1.pHighest ) ? pDef : $1.pLowest;
  3654. delete (node_id_fe *) $1.pHighest;
  3655. named_node * pFound;
  3656. // Allow redefinition of imported types.
  3657. pFound = pBaseSymTbl->SymSearch( SKey );
  3658. // if (pFound && ( pFound->NodeKind() == NODE_HREF ))
  3659. if (pFound && ( NULL != pFound->GetDefiningFile() ))
  3660. {
  3661. pBaseSymTbl->SymDelete( SKey );
  3662. }
  3663. if(!pCurSymTbl->SymInsert( SKey, (SymTable *)NULL, pDef ))
  3664. {
  3665. //
  3666. // allow benign redef of wchar_t & error_status_t.
  3667. //
  3668. if ( ( strcmp( pName, "wchar_t" ) != 0 ) &&
  3669. ( strcmp( pName, "error_status_t" ) != 0 ) )
  3670. {
  3671. ParseError( DUPLICATE_DEFINITION, pName );
  3672. }
  3673. }
  3674. else
  3675. {
  3676. CheckGlobalNamesClash( SKey );
  3677. }
  3678. };
  3679. }
  3680. ;
  3681. OptionalDeclarator:
  3682. Declarator
  3683. | /* Empty */
  3684. {
  3685. $$.Init();
  3686. }
  3687. ;
  3688. /***
  3689. *** declarators are the last part of declarations; e.g. with
  3690. *** long *p, **q, f(long abc);
  3691. *** each of "*p", "**q", and "f(long abc)" are declarators.
  3692. ***
  3693. *** As declarators are built, they are just dangling parts of the
  3694. *** typegraph, so we pass the topmost node and the lowest node (with
  3695. *** no child set yet)
  3696. ***
  3697. ***/
  3698. Declarator:
  3699. OptionalModifierList Declarator2
  3700. {
  3701. // note that leading modifiers eventually attach to the
  3702. // lowest node of the declarator
  3703. $2.pLowest->GetModifiers().Merge( $1 );
  3704. $$ = $2;
  3705. }
  3706. | Pointer
  3707. | Pointer OptionalModifierList Declarator2
  3708. {
  3709. // point dangling declarator2 lowest to pointer highest,
  3710. // set modifiers on Declarator2
  3711. // return declarator2 highest with pointer lowest
  3712. $3.pLowest->GetModifiers().Merge( $2 );
  3713. $3.pLowest->SetChild($1.pHighest);
  3714. $$.pLowest = $1.pLowest;
  3715. $$.pHighest = $3.pHighest;
  3716. }
  3717. ;
  3718. /***
  3719. *** Note that modifiers get stored with the pointer or declarator2 FOLLOWING
  3720. *** the attribute
  3721. ***
  3722. *** Note also that pHighest and pLowest are guaranteed to be non-null
  3723. *** for pointers.
  3724. ***/
  3725. Pointer:
  3726. OptionalModifierList '*' OptionalPostfixPtrModifier
  3727. {
  3728. node_pointer * pPtr = new node_pointer( (node_pointer *) NULL );
  3729. pPtr->GetModifiers().Merge( $1 );
  3730. pPtr->GetModifiers().Merge( $3 );
  3731. #ifdef gajdebug8
  3732. printf("\t\t attaching modifier to lone ptr: %08x\n",$1);
  3733. #endif
  3734. // create node_pointer with modifierlist
  3735. $$.Init( pPtr );
  3736. }
  3737. | Pointer OptionalModifierList '*' OptionalPostfixPtrModifier
  3738. {
  3739. node_pointer * pPtr = new node_pointer( $1.pHighest );
  3740. pPtr->GetModifiers().Merge( $2 );
  3741. pPtr->GetModifiers().Merge( $4 );
  3742. // create node_pointer, set child, apply modifierlist to it
  3743. $$.Init( pPtr, $1.pLowest );
  3744. }
  3745. ;
  3746. OptionalPostfixPtrModifier:
  3747. MSCPTR32
  3748. {
  3749. $$ = INITIALIZED_MODIFIER_SET( ATTR_PTR32 );
  3750. ParseError( BAD_CON_MSC_CDECL, "__ptr32" );
  3751. }
  3752. | MSCPTR64
  3753. {
  3754. $$ = INITIALIZED_MODIFIER_SET( ATTR_PTR64 );
  3755. ParseError( BAD_CON_MSC_CDECL, "__ptr64" );
  3756. }
  3757. |
  3758. {
  3759. $$.Clear();
  3760. }
  3761. ;
  3762. OptionalModifierList:
  3763. ModifierList
  3764. | /* Empty */
  3765. {
  3766. $$.Clear();
  3767. }
  3768. ;
  3769. ModifierList:
  3770. Modifier
  3771. | ModifierList Modifier
  3772. {
  3773. $$ = $1;
  3774. $$.Merge( $2 );
  3775. }
  3776. ;
  3777. Modifier:
  3778. PtrModifier
  3779. | FuncModifier
  3780. | TypeQualifier
  3781. ;
  3782. PtrModifier:
  3783. MSCFAR
  3784. {
  3785. $$ = INITIALIZED_MODIFIER_SET( ATTR_FAR );
  3786. ParseError( BAD_CON_MSC_CDECL, "__far" );
  3787. }
  3788. | MSCNEAR
  3789. {
  3790. $$ = INITIALIZED_MODIFIER_SET( ATTR_NEAR );
  3791. ParseError( BAD_CON_MSC_CDECL, "__near" );
  3792. }
  3793. | MSCHUGE
  3794. {
  3795. $$ = INITIALIZED_MODIFIER_SET( ATTR_HUGE );
  3796. ParseError( BAD_CON_MSC_CDECL, "__huge" );
  3797. }
  3798. | MSCUNALIGNED
  3799. {
  3800. $$ = INITIALIZED_MODIFIER_SET( ATTR_MSCUNALIGNED );
  3801. ParseError( BAD_CON_MSC_CDECL, "unaligned" );
  3802. }
  3803. ;
  3804. FuncModifier:
  3805. MSCPASCAL
  3806. {
  3807. $$ = INITIALIZED_MODIFIER_SET( ATTR_PASCAL );
  3808. ParseError( BAD_CON_MSC_CDECL, "__pascal" );
  3809. }
  3810. | MSCFORTRAN
  3811. {
  3812. $$ = INITIALIZED_MODIFIER_SET( ATTR_FORTRAN );
  3813. ParseError( BAD_CON_MSC_CDECL, "__fortran" );
  3814. }
  3815. | MSCCDECL
  3816. {
  3817. $$ = INITIALIZED_MODIFIER_SET( ATTR_CDECL );
  3818. ParseError( BAD_CON_MSC_CDECL, "__cdecl" );
  3819. }
  3820. | MSCSTDCALL
  3821. {
  3822. $$ = INITIALIZED_MODIFIER_SET( ATTR_STDCALL );
  3823. ParseError( BAD_CON_MSC_CDECL, "__stdcall" );
  3824. }
  3825. | MSCLOADDS /* potentially interesting */
  3826. {
  3827. $$ = INITIALIZED_MODIFIER_SET( ATTR_LOADDS );
  3828. ParseError( BAD_CON_MSC_CDECL, "__loadds" );
  3829. }
  3830. | MSCSAVEREGS
  3831. {
  3832. $$ = INITIALIZED_MODIFIER_SET( ATTR_SAVEREGS );
  3833. ParseError( BAD_CON_MSC_CDECL, "__saveregs" );
  3834. }
  3835. | MSCFASTCALL
  3836. {
  3837. $$ = INITIALIZED_MODIFIER_SET( ATTR_FASTCALL );
  3838. ParseError( BAD_CON_MSC_CDECL, "__fastcall" );
  3839. }
  3840. | MSCSEGMENT
  3841. {
  3842. $$ = INITIALIZED_MODIFIER_SET( ATTR_SEGMENT );
  3843. ParseError( BAD_CON_MSC_CDECL, "__segment" );
  3844. }
  3845. | MSCINTERRUPT
  3846. {
  3847. $$ = INITIALIZED_MODIFIER_SET( ATTR_INTERRUPT );
  3848. ParseError( BAD_CON_MSC_CDECL, "__interrupt" );
  3849. }
  3850. | MSCSELF
  3851. {
  3852. $$ = INITIALIZED_MODIFIER_SET( ATTR_SELF );
  3853. ParseError( BAD_CON_MSC_CDECL, "__self" );
  3854. }
  3855. | MSCEXPORT
  3856. {
  3857. $$ = INITIALIZED_MODIFIER_SET( ATTR_EXPORT );
  3858. ParseError( BAD_CON_MSC_CDECL, "__export" );
  3859. }
  3860. | MscDeclSpec
  3861. | MSCEMIT NUMERICCONSTANT
  3862. {
  3863. $$ = INITIALIZED_MODIFIER_SET( ATTR_NONE );
  3864. ParseError( BAD_CON_MSC_CDECL, "__emit" );
  3865. }
  3866. ;
  3867. /* Declarator2 is whatever is left of the declarator after all the
  3868. pointer stuff has been eaten
  3869. */
  3870. Declarator2:
  3871. '(' Declarator ')'
  3872. {
  3873. $$ = $2;
  3874. }
  3875. | Declarator2 PhantomPushSymtab ParamsDecl2 OptionalConst
  3876. {
  3877. node_proc * pProc;
  3878. char * pName;
  3879. SymTable * pParamSymTbl = pCurSymTbl;
  3880. BOOL IsProc = TRUE;
  3881. /**
  3882. ** If the declarator was an ID and just a simple ID (basic type is
  3883. ** a null), we have just seen a declaration of a procedure.
  3884. ** If we saw an ID which had a basic type, then the ID is a declarator
  3885. ** whose basic type is a procedure (like in a typedef of a proc or
  3886. ** pointer to proc).
  3887. **/
  3888. /**
  3889. ** if the node is a simple ID, then copy node details, else,
  3890. ** set the basic type of the declarator as this proc, and set the
  3891. ** procs name to a temporary.
  3892. **/
  3893. // gaj - check for null...
  3894. if ( ( $1.pHighest == $1.pLowest)
  3895. && ($1.pLowest->NodeKind() == NODE_ID ) )
  3896. {
  3897. pProc = new node_proc( ImportLevel,
  3898. IS_CUR_INTERFACE_LOCAL(),
  3899. (node_id_fe *) $1.pHighest);
  3900. pName = pProc->GetSymName();
  3901. $$.pHighest = pProc;
  3902. $$.pLowest = pProc;
  3903. delete (node_id_fe *) $1.pHighest;
  3904. }
  3905. else
  3906. {
  3907. pProc = new node_proc( ImportLevel,
  3908. IS_CUR_INTERFACE_LOCAL() );
  3909. pProc->SetSymName( pName = GenTempName() );
  3910. $1.pLowest->SetChild( pProc );
  3911. $$.pHighest = $1.pHighest;
  3912. $$.pLowest = pProc;
  3913. IsProc = FALSE;
  3914. }
  3915. /**
  3916. ** Set members of the procedure node as the parameter nodes.
  3917. **/
  3918. pProc->SetMembers( $3 );
  3919. /**
  3920. ** discard the inner symbol table contents (unless it had fwds)
  3921. **/
  3922. pCurSymTbl->DiscardScope();
  3923. /**
  3924. ** restore the symbol tables scope to normal, since we have already
  3925. ** picked up a pointer to the next scope symbol table.
  3926. **/
  3927. pSymTblMgr->PopSymLevel( &pCurSymTbl );
  3928. /**
  3929. ** if this proc was entered into our symbol table, then this is a
  3930. ** redeclaration.But wait ! This is true only if the importlevel is 0
  3931. ** I.e , if there was a proc of the same name defined at an import
  3932. ** level greater, we dont care. (Actually, we must really check
  3933. ** signatures, so that valid redeclarations are ok, with a warning )
  3934. **/
  3935. if( IsProc )
  3936. {
  3937. SymKey SKey( pName, NAME_PROC );
  3938. //if ( ImportLevel == 0 )
  3939. {
  3940. if( !pInterfaceInfoDict->GetInterfaceProcTable()->
  3941. SymInsert( SKey, pParamSymTbl, pProc ) )
  3942. {
  3943. ParseError( DUPLICATE_DEFINITION, pName );
  3944. }
  3945. }
  3946. /********
  3947. else
  3948. CheckGlobalNamesClash( SKey );
  3949. ********/
  3950. }
  3951. /**
  3952. ** finally, for the const support, if the optional const is true
  3953. ** apply the const attribute on the proc
  3954. **/
  3955. pProc->GetModifiers().Merge( $4 );
  3956. }
  3957. | '(' ')' OptionalConst
  3958. {
  3959. /**
  3960. ** this is an abstract declarator for a procedure. Generate a
  3961. ** new proc node with a temp name, enter the name into the symbol
  3962. ** table.
  3963. **/
  3964. char * pName = GenTempName();
  3965. SymKey SKey( pName, NAME_PROC );
  3966. node_proc * pProc = new node_proc( ImportLevel,
  3967. IS_CUR_INTERFACE_LOCAL() );
  3968. $$.Init ( pProc );
  3969. pProc->SetSymName( pName );
  3970. /**
  3971. ** enter this into the symbol table , only if we are in the base idl
  3972. ** file, not an imported file.
  3973. **/
  3974. if ( ImportLevel == 0 )
  3975. pInterfaceInfoDict->GetInterfaceProcTable()->
  3976. SymInsert( SKey,
  3977. (SymTable *)NULL,
  3978. (named_node *) $$.pHighest );
  3979. /**
  3980. ** finally, for the const support, if the optional const is true
  3981. ** apply the const attribute on the proc
  3982. **/
  3983. pProc->GetModifiers().Merge( $3 );
  3984. }
  3985. | Declarator2 ArrayDecl
  3986. {
  3987. /**
  3988. ** The basic type of the declarator is the array
  3989. **/
  3990. $$.pHighest = $1.pHighest;
  3991. $1.pLowest->SetChild( $2.pHighest );
  3992. $$.pLowest = $2.pLowest;
  3993. }
  3994. | ArrayDecl
  3995. {
  3996. $$ = $1;
  3997. }
  3998. | IDENTIFIER
  3999. {
  4000. char * pName = $1;
  4001. if ( !pName )
  4002. pName = GenTempName();
  4003. $$.Init( new node_id_fe( pName ) );
  4004. }
  4005. | TypeName
  4006. {
  4007. /**
  4008. ** This production ensures that a declarator can be the same name
  4009. ** as a typedef. The lexer will return all lexemes which are
  4010. ** typedefed as TYPENAMEs and we need to permit the user to specify
  4011. ** a declarator of the same name as the type name too! This conflict
  4012. ** arises only in the declarator productions, so this is an easy way
  4013. ** to support it.
  4014. **/
  4015. $$.Init( new node_id_fe( $1->GetCurrentSpelling() ) );
  4016. }
  4017. ;
  4018. /* Note: the omition of param_decl2 above precludes
  4019. int foo( int (bar) ); a real ambiguity of C. If bar is a predefined
  4020. type then the parameter of foo can be either:
  4021. 1. a function with a bar param, and an int return value, as in
  4022. int foo( int func(bar) );
  4023. 2. A function with an int parameter by the name of bar, as in
  4024. int foo( int bar );
  4025. */
  4026. ParamsDecl2:
  4027. '(' ')'
  4028. {
  4029. /**
  4030. ** this production corresponds to no params to a function.
  4031. **/
  4032. /**
  4033. ** Return it as an empty list of parameters
  4034. **/
  4035. $$.Init( NULL );
  4036. }
  4037. | '(' ParameterTypeList ')'
  4038. {
  4039. $$ = $2;
  4040. }
  4041. ;
  4042. ParameterTypeList:
  4043. ParameterList
  4044. | ParameterList ',' DOTDOT '.'
  4045. {
  4046. /**
  4047. ** This is meaningless in rpc, but we consume it and report an
  4048. ** error during semantics, if a proc using this param ever gets
  4049. ** remoted. We call this a param node with the name "...". And set its
  4050. ** basic type to an error node, so that a param is properly terminated.
  4051. ** The backend can emit a "..." for the name, so that this whole
  4052. ** thing is essentially transparent to it.
  4053. **/
  4054. if ( 1 ) //ImportLevel == 0 ) <- change back when imported params not needed
  4055. {
  4056. node_param * pParam = new node_param;
  4057. pParam->SetSymName( "..." );
  4058. pParam->SetChild( pErrorTypeNode );
  4059. $$ = $1;
  4060. $$.Add( pParam );
  4061. }
  4062. }
  4063. ;
  4064. ParameterList:
  4065. ParameterDeclaration
  4066. {
  4067. $$.Init( $1 );
  4068. }
  4069. | ParameterList ',' ParameterDeclaration
  4070. {
  4071. if ( $3 && $1.NonNull() )
  4072. {
  4073. $$.Add( (named_node *) $3 );
  4074. }
  4075. else
  4076. {
  4077. // tbd - error if later parameters are void
  4078. }
  4079. }
  4080. ;
  4081. ParameterDeclaration:
  4082. OptionalAttrList DeclarationSpecifiers Declarator
  4083. {
  4084. if (0) // ( ImportLevel > 0 )
  4085. {
  4086. if ( $3.pHighest->NodeKind() == NODE_ID )
  4087. delete (node_id_fe *) $3.pHighest;
  4088. $$ = NULL;
  4089. }
  4090. else
  4091. {
  4092. node_param * pParam;
  4093. char * pName;
  4094. node_id_fe * pOriginal = NULL;
  4095. /**
  4096. ** Apply the declaration specifier to the declarator as a basic type
  4097. **/
  4098. $3.pLowest->SetChild( $2.pNode );
  4099. /**
  4100. ** apply any attributes specified to the declaration specifiers
  4101. **/
  4102. $3.pLowest->GetModifiers().Merge( $2.modifiers );
  4103. /**
  4104. ** if the declarator was just an id, then we have to copy the
  4105. ** node details over, else set the basic type of the param to
  4106. ** the declarator
  4107. **/
  4108. if ( $3.pHighest->NodeKind() == NODE_ID )
  4109. {
  4110. pOriginal = (node_id_fe *) $3.pHighest;
  4111. pParam = new node_param( pOriginal );
  4112. }
  4113. else
  4114. {
  4115. pParam = new node_param;
  4116. pParam->SetChild( $3.pHighest );
  4117. };
  4118. /**
  4119. ** prepare for symbol table entry.
  4120. **/
  4121. if( !(pName = pParam->GetSymName()) )
  4122. {
  4123. pParam->SetSymName(pName = GenTempName() );
  4124. }
  4125. if ( IsTempName( pParam->GetSymName() ) )
  4126. ParseError( ABSTRACT_DECL, (char *)NULL );
  4127. SymKey SKey( pName, NAME_MEMBER );
  4128. /**
  4129. ** enter the parameter into the symbol table.
  4130. ** If the user specified more than one param with the same name,
  4131. ** report an error, else insert the symbol into the table
  4132. **/
  4133. if( !pCurSymTbl->SymInsert( SKey, (SymTable *)NULL, pParam ) )
  4134. {
  4135. //
  4136. // dont complain on another param of name void. This check is
  4137. // made elsewhere.
  4138. //
  4139. if( strcmp( pName, "void" ) != 0 )
  4140. ParseError( DUPLICATE_DEFINITION, pName );
  4141. }
  4142. else
  4143. CheckGlobalNamesClash( SKey );
  4144. if ( $1 )
  4145. {
  4146. pParam->AddAttributes( $1 );
  4147. }
  4148. // clean up any old node_id
  4149. if ( pOriginal )
  4150. delete pOriginal;
  4151. /**
  4152. ** return the node back
  4153. **/
  4154. $$ = pParam;
  4155. }
  4156. }
  4157. | OptionalAttrList DeclarationSpecifiers
  4158. {
  4159. /**
  4160. ** This is the case when the user specified a simple abstract
  4161. ** declaration eg proc1( short ). In other words, the declarator is
  4162. ** optional. Abstract declarators are illegal in osf mode.
  4163. ** If the declaration specifier is a void then skip the parameter
  4164. **/
  4165. if( // ( ImportLevel > 0 ) ||
  4166. ( $2.pNode->NodeKind() == NODE_VOID ) )
  4167. {
  4168. $$ = NULL;
  4169. }
  4170. else
  4171. {
  4172. char * pName = GenTempName();
  4173. SymKey SKey( pName, NAME_MEMBER );
  4174. node_param * pParam = new node_param;
  4175. pParam->SetSymName( pName );
  4176. pParam->SetChild( $2.pNode );
  4177. ParseError( ABSTRACT_DECL, (char *)NULL );
  4178. /**
  4179. ** enter into symbol table, just like anything else.
  4180. **/
  4181. if( !pCurSymTbl->SymInsert( SKey, (SymTable *)NULL, pParam ) )
  4182. {
  4183. ParseError( DUPLICATE_DEFINITION, pName );
  4184. }
  4185. /**
  4186. ** apply any attributes specified to the declaration specifiers
  4187. **/
  4188. pParam->GetModifiers().Merge( $2.modifiers );
  4189. if ( $1 )
  4190. {
  4191. pParam->AddAttributes( $1 );
  4192. }
  4193. $$ = pParam;
  4194. }
  4195. }
  4196. ;
  4197. OptionalConst:
  4198. KWCONST
  4199. {
  4200. $$ = INITIALIZED_MODIFIER_SET(ATTR_PROC_CONST);
  4201. }
  4202. | /* empty */
  4203. {
  4204. $$.Clear();
  4205. }
  4206. ;
  4207. ArrayDecl:
  4208. ArrayDecl2
  4209. {
  4210. $$.Init( new node_array( $1.LowerBound, $1.UpperBound ) );
  4211. }
  4212. ;
  4213. ArrayDecl2:
  4214. '[' ']'
  4215. {
  4216. /**
  4217. ** we identify a conformant array by setting the upperbound to -1
  4218. ** and the lower to 0
  4219. **/
  4220. $$.UpperBound = (expr_node *) -1;
  4221. $$.LowerBound = (expr_node *) 0;
  4222. }
  4223. | '[' '*' ']'
  4224. {
  4225. /**
  4226. ** This is also taken to mean a conformant array, upper bound known
  4227. ** only at runtime. The lower bound is 0
  4228. **/
  4229. $$.UpperBound = (expr_node *)-1;
  4230. $$.LowerBound = (expr_node *)0;
  4231. }
  4232. | '[' ConstantExpr ']'
  4233. {
  4234. /**
  4235. ** this is the case of an array whose lower bound is 0
  4236. **/
  4237. $$.UpperBound = $2;
  4238. $$.LowerBound = (expr_node *)0;
  4239. }
  4240. | '[' ArrayBoundsPair ']'
  4241. {
  4242. if( ($2.LowerBound)->Evaluate() != 0 )
  4243. ParseError( ARRAY_BOUNDS_CONSTRUCT_BAD, (char *)NULL );
  4244. $$ = $2;
  4245. }
  4246. ;
  4247. ArrayBoundsPair:
  4248. ConstantExpr DOTDOT ConstantExpr
  4249. {
  4250. /**
  4251. ** the fact that the expected expression is not a constant is
  4252. ** verified by the constantExpr production. All we have to do here is
  4253. ** to pass the expression up.
  4254. **/
  4255. $$.LowerBound = $1;
  4256. $$.UpperBound = new expr_b_arithmetic( OP_PLUS,
  4257. $3,
  4258. GetConstant1() );
  4259. }
  4260. ;
  4261. InternationalCharacterType:
  4262. KWISOLATIN1
  4263. {
  4264. $$ = KWISOLATIN1;
  4265. }
  4266. | KWPRIVATECHAR8
  4267. {
  4268. $$ = KWPRIVATECHAR8;
  4269. }
  4270. | KWISOMULTILINGUAL
  4271. {
  4272. $$ = KWISOMULTILINGUAL;
  4273. }
  4274. | KWPRIVATECHAR16
  4275. {
  4276. $$ = KWPRIVATECHAR16;
  4277. }
  4278. | KWISOUCS
  4279. {
  4280. $$ = KWISOUCS;
  4281. }
  4282. ;
  4283. MscDeclSpec:
  4284. KWMSCDECLSPEC
  4285. {
  4286. ParseError( BAD_CON_MSC_CDECL, "__declspec" );
  4287. $$ = $1;
  4288. }
  4289. ;
  4290. MscOptDeclSpecList:
  4291. MscDeclSpec
  4292. {
  4293. $$ = $1;
  4294. }
  4295. | MscOptDeclSpecList MscDeclSpec
  4296. {
  4297. $$ = $1;
  4298. $$.Merge($2);
  4299. }
  4300. |
  4301. {
  4302. $$.Clear();
  4303. }
  4304. ;
  4305. /********************************* MIDL attributes **********************/
  4306. OptionalAttrList:
  4307. AttrList
  4308. | /* Empty */
  4309. {
  4310. $$.MakeAttrList();
  4311. }
  4312. ;
  4313. OptionalAttrListWithDefault:
  4314. AttrListWithDefault
  4315. | /* Empty */
  4316. {
  4317. $$.MakeAttrList();
  4318. }
  4319. ;
  4320. AttrList:
  4321. AttrList AttrSet
  4322. {
  4323. // note that in all left-recursive productions like this we are
  4324. // relying on an implicit $$ = $1 operation
  4325. $$.Merge( $2 );
  4326. }
  4327. | AttrSet
  4328. ;
  4329. AttrListWithDefault:
  4330. AttrListWithDefault AttrSetWithDefault
  4331. {
  4332. // note that in all left-recursive productions like this we are
  4333. // relying on an implicit $$ = $1 operation
  4334. $$.Merge( $2 );
  4335. }
  4336. | AttrSetWithDefault
  4337. ;
  4338. AttrSet:
  4339. '[' Attributes ']'
  4340. {
  4341. $$ = $2;
  4342. }
  4343. ;
  4344. AttrSetWithDefault:
  4345. '[' AttributesWithDefault ']'
  4346. {
  4347. $$ = $2;
  4348. }
  4349. ;
  4350. Attributes:
  4351. Attributes ',' OneAttribute
  4352. {
  4353. $$.Merge( $3 );
  4354. }
  4355. | OneAttribute
  4356. ;
  4357. AttributesWithDefault:
  4358. AttributesWithDefault ',' OneAttributeWithDefault
  4359. {
  4360. $$.Merge( $3 );
  4361. }
  4362. | OneAttributeWithDefault
  4363. ;
  4364. OneAttribute:
  4365. InterfaceAttribute
  4366. {
  4367. $$.MakeAttrList( $1 );
  4368. }
  4369. | TypeAttribute
  4370. {
  4371. $$.MakeAttrList( $1 );
  4372. }
  4373. | FieldAttribute
  4374. | PtrAttr
  4375. {
  4376. $$.MakeAttrList( $1 );
  4377. }
  4378. | DirectionalAttribute
  4379. {
  4380. $$.MakeAttrList( $1 );
  4381. }
  4382. | OperationAttribute
  4383. {
  4384. $$.MakeAttrList( $1 );
  4385. }
  4386. | OdlAttribute
  4387. {
  4388. $$.MakeAttrList( $1 );
  4389. }
  4390. ;
  4391. OneAttributeWithDefault:
  4392. InterfaceAttribute
  4393. {
  4394. $$.MakeAttrList( $1 );
  4395. }
  4396. | TypeAttribute
  4397. {
  4398. $$.MakeAttrList( $1 );
  4399. }
  4400. | FieldAttribute
  4401. | PtrAttr
  4402. {
  4403. $$.MakeAttrList( $1 );
  4404. }
  4405. | DirectionalAttribute
  4406. {
  4407. $$.MakeAttrList( $1 );
  4408. }
  4409. | OperationAttribute
  4410. {
  4411. $$.MakeAttrList( $1 );
  4412. }
  4413. | OdlAttribute
  4414. {
  4415. $$.MakeAttrList( $1 );
  4416. }
  4417. | KWDEFAULT
  4418. {
  4419. $$.MakeAttrList(new battr( ATTR_DEFAULT ));
  4420. }
  4421. ;
  4422. ;
  4423. InterfaceAttribute:
  4424. KWENDPOINT '(' EndPtSpecs ')'
  4425. {
  4426. $$ = $3;
  4427. }
  4428. | KWUUID '('
  4429. {
  4430. LexContext = LEX_GUID; /* turned off by the lexer */
  4431. }
  4432. Guid ')'
  4433. {
  4434. $$ = $4;
  4435. }
  4436. | KWASYNCUUID '('
  4437. {
  4438. if ( pCommand->GetNdrVersionControl().TargetIsLessThanNT50() )
  4439. ParseError( INVALID_FEATURE_FOR_TARGET, "[async_uuid]");
  4440. LexContext = LEX_GUID; /* turned off by the lexer */
  4441. }
  4442. AsyncGuid ')'
  4443. {
  4444. $$ = $4;
  4445. }
  4446. | KWLOCAL
  4447. {
  4448. $$ = new battr( ATTR_LOCAL );
  4449. }
  4450. | KWOBJECT
  4451. {
  4452. ParseError( INVALID_OSF_ATTRIBUTE, "[object]" );
  4453. $$ = new battr( ATTR_OBJECT );
  4454. }
  4455. | KWVERSION '('
  4456. {
  4457. LexContext = LEX_VERSION;
  4458. /* LexContext is reset by lexer */
  4459. }
  4460. VERSIONTOKEN ')'
  4461. {
  4462. $$ = (new node_version( $4 ));
  4463. }
  4464. | KWDEFAULTPOINTER '(' PtrAttr ')'
  4465. {
  4466. $$ = $3;
  4467. }
  4468. | KWMS_CONF_STRUCT
  4469. {
  4470. $$ = new battr( ATTR_MS_CONF_STRUCT );
  4471. }
  4472. | AcfInterfaceAttribute
  4473. {
  4474. if( !pCommand->IsSwitchDefined( SWITCH_APP_CONFIG ) )
  4475. {
  4476. ParseError( ACF_IN_IDL_NEEDS_APP_CONFIG,
  4477. ($1)->GetNodeNameString() );
  4478. }
  4479. $$ = $1;
  4480. }
  4481. | /* empty attribute */
  4482. {
  4483. $$ = NULL;
  4484. }
  4485. ;
  4486. Guid:
  4487. UUIDTOKEN
  4488. {
  4489. $$ = (new node_guid( $1 ));
  4490. }
  4491. ;
  4492. AsyncGuid:
  4493. UUIDTOKEN
  4494. {
  4495. $$ = (new node_guid( $1, ATTR_ASYNCUUID ));
  4496. }
  4497. ;
  4498. EndPtSpecs:
  4499. EndPtSpec
  4500. {
  4501. $$ = new node_endpoint( $1 );
  4502. }
  4503. | EndPtSpecs ',' EndPtSpec
  4504. {
  4505. $$ = $1;
  4506. ( (node_endpoint *) $$)->SetEndPointString( $3 );
  4507. }
  4508. ;
  4509. EndPtSpec:
  4510. STRING
  4511. ;
  4512. AcfInterfaceAttribute:
  4513. KWIMPLICITHANDLE '(' AcfImpHdlTypeSpec IDENTIFIER ')'
  4514. {
  4515. $$ = (new node_implicit( $3, new node_id_fe($4) ));
  4516. }
  4517. | KWAUTOHANDLE
  4518. {
  4519. $$ = (new acf_attr( ATTR_AUTO ));
  4520. }
  4521. ;
  4522. AcfImpHdlTypeSpec:
  4523. KWHANDLET
  4524. {
  4525. GetBaseTypeNode( &($$), SIGN_UNDEF, SIZE_UNDEF, TYPE_HANDLE_T, 0 );
  4526. }
  4527. | IDENTIFIER
  4528. {
  4529. node_forward * pFwd;
  4530. SymKey SKey( $1, NAME_DEF );
  4531. pFwd = new node_forward( SKey, pCurSymTbl );
  4532. pFwd->SetSymName( $1 );
  4533. pFwd->SetAttribute( ATTR_HANDLE );
  4534. $$ = pFwd;
  4535. //
  4536. // keep a track of this node to ensure it is not used as a
  4537. // context handle.
  4538. //
  4539. if( ImportLevel == 0 )
  4540. {
  4541. pBaseImplicitHandle = $$;
  4542. }
  4543. }
  4544. | TypeName
  4545. ;
  4546. TypeAttribute:
  4547. UnimplementedTypeAttribute
  4548. {
  4549. $$ = NULL;
  4550. }
  4551. | KWHANDLE
  4552. {
  4553. $$ = new battr( ATTR_HANDLE );
  4554. }
  4555. | KWSTRING
  4556. {
  4557. $$ = (new battr( ATTR_STRING ));
  4558. }
  4559. | KWBSTRING
  4560. {
  4561. $$ = (new battr( ATTR_BSTRING ));
  4562. }
  4563. | KWCONTEXTHANDLE
  4564. {
  4565. $$ = (new battr( ATTR_CONTEXT ));
  4566. }
  4567. | KWSWITCHTYPE '(' SwitchTypeSpec ')'
  4568. {
  4569. $$ = (new node_switch_type( $3 ));
  4570. }
  4571. | KWTRANSMITAS '(' SimpleTypeSpec ')'
  4572. {
  4573. $$ = (new node_transmit( $3 ));
  4574. }
  4575. | KWWIREMARSHAL '(' SimpleTypeSpec ')'
  4576. {
  4577. $$ = (new node_wire_marshal( $3 ));
  4578. }
  4579. | KWCALLAS '(' AcfCallType ')'
  4580. {
  4581. $$ = $3;
  4582. }
  4583. | KWMSUNION
  4584. {
  4585. $$ = new battr( ATTR_MS_UNION );
  4586. }
  4587. | KWV1ENUM
  4588. {
  4589. $$ = new battr( ATTR_V1_ENUM );
  4590. }
  4591. ;
  4592. AcfCallType:
  4593. IDENTIFIER
  4594. {
  4595. SymKey SKey( $1, NAME_PROC );
  4596. node_proc * pProc = (node_proc *)
  4597. pInterfaceInfoDict->GetInterfaceProcTable()->SymSearch( SKey );
  4598. $$ = new node_call_as( $1, pProc );
  4599. }
  4600. ;
  4601. UnimplementedTypeAttribute:
  4602. KWALIGN '(' IntSize ')'
  4603. {
  4604. ParseError(IGNORE_UNIMPLEMENTED_ATTRIBUTE, "[align]");
  4605. }
  4606. | KWUNALIGNED
  4607. {
  4608. ParseError(IGNORE_UNIMPLEMENTED_ATTRIBUTE, "[unaligned]");
  4609. }
  4610. | KWV1ARRAY
  4611. {
  4612. ParseError(IGNORE_UNIMPLEMENTED_ATTRIBUTE, "[v1_array]");
  4613. }
  4614. | KWV1STRING
  4615. {
  4616. ParseError(IGNORE_UNIMPLEMENTED_ATTRIBUTE, "[v1_string]");
  4617. }
  4618. | KWV1STRUCT
  4619. {
  4620. ParseError(IGNORE_UNIMPLEMENTED_ATTRIBUTE, "[v1_struct]");
  4621. }
  4622. ;
  4623. PtrAttr:
  4624. KWREF
  4625. {
  4626. $$ = new node_ptr_attr( PTR_REF );
  4627. }
  4628. | KWUNIQUE
  4629. {
  4630. $$ = new node_ptr_attr( PTR_UNIQUE );
  4631. }
  4632. | KWPTR
  4633. {
  4634. $$ = new node_ptr_attr( PTR_FULL );
  4635. }
  4636. | KWIGNORE
  4637. {
  4638. $$ = new battr( ATTR_IGNORE );
  4639. }
  4640. ;
  4641. SwitchTypeSpec:
  4642. IntSpec
  4643. {
  4644. if( $1.BaseType == TYPE_UNDEF )
  4645. $1.BaseType = TYPE_INT;
  4646. if( $1.TypeSign == SIGN_UNDEF )
  4647. $1.TypeSign = SIGN_SIGNED;
  4648. GetBaseTypeNode( &($$), $1.TypeSign, $1.TypeSize, $1.BaseType, $1.TypeAttrib );
  4649. }
  4650. | CharSpecs
  4651. {
  4652. GetBaseTypeNode( &($$), $1.TypeSign, SIZE_CHAR, TYPE_INT, 0 );
  4653. }
  4654. | KWBYTE
  4655. {
  4656. GetBaseTypeNode( &($$), SIGN_UNDEF, SIZE_UNDEF, TYPE_BYTE, 0 );
  4657. }
  4658. | KWBOOLEAN
  4659. {
  4660. GetBaseTypeNode( &($$), SIGN_UNDEF, SIZE_UNDEF, TYPE_BOOLEAN, 0 );
  4661. }
  4662. | KWENUM Tag
  4663. {
  4664. SymKey SKey( $2, NAME_ENUM );
  4665. if( ! ($$ = pBaseSymTbl->SymSearch( SKey ) ) )
  4666. {
  4667. ParseError( UNDEFINED_SYMBOL, $2 );
  4668. $$ = new node_error;
  4669. }
  4670. }
  4671. | TypeName /* TYPENAME */
  4672. ;
  4673. FieldAttribute:
  4674. KWFIRSTIS '(' AttrVarList ')'
  4675. {
  4676. $$ = (GenerateFieldAttribute( ATTR_FIRST, $3 ));
  4677. }
  4678. | KWLASTIS '(' AttrVarList ')'
  4679. {
  4680. $$ = (GenerateFieldAttribute( ATTR_LAST, $3 ));
  4681. }
  4682. | KWLENGTHIS '(' AttrVarList ')'
  4683. {
  4684. $$ = (GenerateFieldAttribute( ATTR_LENGTH, $3 ));
  4685. }
  4686. | KWMINIS '(' AttrVarList ')'
  4687. {
  4688. $$ = (GenerateFieldAttribute( ATTR_MIN, $3 ));
  4689. }
  4690. | KWMAXIS '(' AttrVarList ')'
  4691. {
  4692. $$ = (GenerateFieldAttribute( ATTR_MAX, $3 ));
  4693. }
  4694. | KWSIZEIS '(' AttrVarList ')'
  4695. {
  4696. $$ = (GenerateFieldAttribute( ATTR_SIZE, $3 ));
  4697. }
  4698. | KWRANGE '(' ConstantExpr ',' ConstantExpr ')'
  4699. {
  4700. $$.MakeAttrList( new node_range_attr( $3, $5 ) );
  4701. }
  4702. | KWSWITCHIS '(' AttrVar ')'
  4703. {
  4704. $$.MakeAttrList( new node_switch_is( $3 ));
  4705. }
  4706. | KWIIDIS '(' AttrVar ')'
  4707. {
  4708. ParseError( INVALID_OSF_ATTRIBUTE, "[iid_is()]" );
  4709. $$.MakeAttrList( new size_attr( $3, ATTR_IID_IS ));
  4710. }
  4711. | KWID '(' ConstantExpr ')'
  4712. {
  4713. $$.MakeAttrList( new node_constant_attr( $3, ATTR_ID));
  4714. }
  4715. | KWHC '(' ConstantExpr ')'
  4716. {
  4717. $$.MakeAttrList( new node_constant_attr( $3, ATTR_HELPCONTEXT ));
  4718. }
  4719. | KWHSC '(' ConstantExpr ')'
  4720. {
  4721. if (!FNewTypeLib())
  4722. {
  4723. ParseError( INVALID_NEWTLB_ATTRIBUTE, "[helpstringcontext()]");
  4724. }
  4725. $$.MakeAttrList( new node_constant_attr( $3, ATTR_HELPSTRINGCONTEXT ));
  4726. }
  4727. | KWLCID '(' ConstantExpr ')'
  4728. {
  4729. $$.MakeAttrList( new node_constant_attr( $3, ATTR_LCID ));
  4730. // ignore [lcid()] from imported files
  4731. if ( ImportLevel == 0 )
  4732. {
  4733. CharacterSet::DBCS_ERRORS err = CurrentCharSet.SetDbcsLeadByteTable($3->GetValue());
  4734. if (err == CharacterSet::dbcs_LCIDConflict)
  4735. {
  4736. ParseError( CONFLICTING_LCID,
  4737. 0);
  4738. }
  4739. else if (err == CharacterSet::dbcs_BadLCID)
  4740. {
  4741. ParseError( INVALID_LOCALE_ID,
  4742. 0);
  4743. }
  4744. }
  4745. }
  4746. | KWFUNCDESCATTR '(' ConstantExpr ')'
  4747. {
  4748. $$.MakeAttrList( new node_constant_attr( $3, ATTR_FUNCDESCATTR ));
  4749. }
  4750. | KWIDLDESCATTR '(' ConstantExpr ')'
  4751. {
  4752. $$.MakeAttrList( new node_constant_attr( $3, ATTR_IDLDESCATTR ));
  4753. }
  4754. | KWTYPEDESCATTR '(' ConstantExpr ')'
  4755. {
  4756. $$.MakeAttrList( new node_constant_attr( $3, ATTR_TYPEDESCATTR ));
  4757. }
  4758. | KWVARDESCATTR '(' ConstantExpr ')'
  4759. {
  4760. $$.MakeAttrList( new node_constant_attr( $3, ATTR_VARDESCATTR ));
  4761. }
  4762. | KWDLLNAME '(' STRING ')'
  4763. {
  4764. $$.MakeAttrList( new node_text_attr( $3, ATTR_DLLNAME ));
  4765. }
  4766. | KWHELPSTR '(' STRING ')'
  4767. {
  4768. TranslateEscapeSequences($3);
  4769. $$.MakeAttrList( new node_text_attr( $3, ATTR_HELPSTRING ));
  4770. }
  4771. | KWHELPFILE '(' STRING ')'
  4772. {
  4773. TranslateEscapeSequences($3);
  4774. $$.MakeAttrList( new node_text_attr( $3, ATTR_HELPFILE ));
  4775. }
  4776. | KWHELPSTRINGDLL '(' STRING ')'
  4777. {
  4778. TranslateEscapeSequences($3);
  4779. $$.MakeAttrList( new node_text_attr( $3, ATTR_HELPSTRINGDLL ));
  4780. }
  4781. | KWENTRY '(' STRING ')'
  4782. {
  4783. $$.MakeAttrList( new node_entry_attr( $3 ));
  4784. }
  4785. | KWENTRY '(' NUMERICCONSTANT ')'
  4786. {
  4787. $$.MakeAttrList( new node_entry_attr( (long) $3.Val ));
  4788. }
  4789. | KWENTRY '(' HEXCONSTANT ')'
  4790. {
  4791. $$.MakeAttrList( new node_entry_attr( (long) $3.Val ));
  4792. }
  4793. | KWENTRY '(' OCTALCONSTANT ')'
  4794. {
  4795. $$.MakeAttrList( new node_entry_attr( (long) $3.Val ));
  4796. }
  4797. | KWDEFAULTVALUE '(' ConstantExpr ')'
  4798. {
  4799. if (!FNewTypeLib())
  4800. {
  4801. ParseError( INVALID_NEWTLB_ATTRIBUTE, "[defaultvalue()]");
  4802. }
  4803. $$.MakeAttrList( new node_constant_attr( $3, ATTR_DEFAULTVALUE ));
  4804. }
  4805. | KWCUSTOM '('
  4806. {
  4807. LexContext = LEX_GUID; /* turned off by the lexer */
  4808. }
  4809. Guid ',' ConstantExpr ')'
  4810. {
  4811. if (!FNewTypeLib())
  4812. {
  4813. ParseError( INVALID_NEWTLB_ATTRIBUTE, "[custom()]");
  4814. }
  4815. $$.MakeAttrList( new node_custom_attr( (node_guid *)$4, $6 ));
  4816. }
  4817. ;
  4818. AttrVarList:
  4819. AttrVarList ',' AttrVar
  4820. {
  4821. $$->SetPeer( $3 );
  4822. }
  4823. | AttrVar
  4824. {
  4825. $$ = new expr_list;
  4826. $$->SetPeer( $1 );
  4827. }
  4828. ;
  4829. AttrVar:
  4830. VariableExpr
  4831. | /* empty */
  4832. {
  4833. $$ = NULL;
  4834. }
  4835. ;
  4836. DirectionalAttribute:
  4837. KWIN OptShape
  4838. {
  4839. $$ = new battr ( ATTR_IN );
  4840. /*****************
  4841. if( $2 )
  4842. $$.Merge( ATTRLIST Shape_Attr($2) );
  4843. ******************/
  4844. }
  4845. | KWOUT OptShape
  4846. {
  4847. $$ = new battr ( ATTR_OUT );
  4848. /*****************
  4849. if( $2 )
  4850. $$.Merge( ATTRLIST Shape_Attr($2) );
  4851. ******************/
  4852. }
  4853. | KWPARTIALIGNORE
  4854. {
  4855. if ( pCommand->GetNdrVersionControl().TargetIsLessThanNT51() )
  4856. ParseError( INVALID_FEATURE_FOR_TARGET, "[partial_ignore]");
  4857. $$ = new battr ( ATTR_PARTIAL_IGNORE );
  4858. }
  4859. ;
  4860. OperationAttribute:
  4861. KWCALLBACK
  4862. {
  4863. $$ = (new battr( ATTR_CALLBACK ));
  4864. }
  4865. | KWIDEMPOTENT
  4866. {
  4867. $$ = (new battr( ATTR_IDEMPOTENT ));
  4868. }
  4869. | KWBROADCAST
  4870. {
  4871. $$ = (new battr( ATTR_BROADCAST ));
  4872. }
  4873. | KWMAYBE
  4874. {
  4875. $$ = (new battr( ATTR_MAYBE ));
  4876. }
  4877. | KWASYNC
  4878. {
  4879. if ( pCommand->GetNdrVersionControl().TargetIsLessThanNT50() )
  4880. ParseError( INVALID_FEATURE_FOR_TARGET, "[async]");
  4881. $$ = (new battr( ATTR_ASYNC ));
  4882. }
  4883. | KWMESSAGE
  4884. {
  4885. if ( pCommand->GetNdrVersionControl().TargetIsLessThanNT50() )
  4886. ParseError( INVALID_FEATURE_FOR_TARGET, "[message]");
  4887. $$ = (new battr( ATTR_MESSAGE ));
  4888. }
  4889. | KWINPUTSYNC
  4890. {
  4891. $$ = (new battr( ATTR_INPUTSYNC ));
  4892. }
  4893. ;
  4894. OdlAttribute:
  4895. KWHIDDEN
  4896. {
  4897. $$ = (new battr( ATTR_HIDDEN ));
  4898. }
  4899. | KWPROPGET
  4900. {
  4901. $$ = (new node_member_attr( MATTR_PROPGET ));
  4902. }
  4903. | KWPROPPUT
  4904. {
  4905. $$ = (new node_member_attr( MATTR_PROPPUT ));
  4906. }
  4907. | KWPROPPUTREF
  4908. {
  4909. $$ = (new node_member_attr( MATTR_PROPPUTREF ));
  4910. }
  4911. | KWOPTIONAL
  4912. {
  4913. $$ = (new node_member_attr( MATTR_OPTIONAL ));
  4914. }
  4915. | KWVARARG
  4916. {
  4917. $$ = (new node_member_attr( MATTR_VARARG ));
  4918. }
  4919. | KWRESTRICTED
  4920. {
  4921. $$ = (new node_member_attr( MATTR_RESTRICTED ));
  4922. }
  4923. | KWREADONLY
  4924. {
  4925. $$ = (new node_member_attr( MATTR_READONLY ));
  4926. }
  4927. | KWSOURCE
  4928. {
  4929. $$ = (new node_member_attr( MATTR_SOURCE ));
  4930. }
  4931. | KWDEFAULTVTABLE
  4932. {
  4933. if (!FNewTypeLib())
  4934. {
  4935. ParseError( INVALID_NEWTLB_ATTRIBUTE, "[defaultvtable]");
  4936. }
  4937. $$ = (new node_member_attr( MATTR_DEFAULTVTABLE ));
  4938. }
  4939. | KWIMMEDIATEBIND
  4940. {
  4941. if (!FNewTypeLib())
  4942. {
  4943. ParseError( INVALID_NEWTLB_ATTRIBUTE, "[immediatebind]");
  4944. }
  4945. $$ = (new node_member_attr( MATTR_IMMEDIATEBIND ));
  4946. }
  4947. | KWREPLACEABLE
  4948. {
  4949. if (!FNewTypeLib())
  4950. {
  4951. ParseError( INVALID_NEWTLB_ATTRIBUTE, "[replaceable]");
  4952. }
  4953. $$ = (new node_member_attr( MATTR_REPLACEABLE ));
  4954. }
  4955. | KWUSESGETLASTERROR
  4956. {
  4957. $$ = (new node_member_attr( MATTR_USESGETLASTERROR ));
  4958. }
  4959. | KWBINDABLE
  4960. {
  4961. $$ = (new node_member_attr( MATTR_BINDABLE ));
  4962. }
  4963. | KWREQUESTEDIT
  4964. {
  4965. $$ = (new node_member_attr( MATTR_REQUESTEDIT ));
  4966. }
  4967. | KWDISPLAYBIND
  4968. {
  4969. $$ = (new node_member_attr( MATTR_DISPLAYBIND ));
  4970. }
  4971. | KWDEFAULTBIND
  4972. {
  4973. $$ = (new node_member_attr( MATTR_DEFAULTBIND ));
  4974. }
  4975. | KWPREDECLID
  4976. {
  4977. $$ = (new node_member_attr( MATTR_PREDECLID ));
  4978. }
  4979. | KWRETVAL
  4980. {
  4981. $$ = (new node_member_attr( MATTR_RETVAL ));
  4982. }
  4983. | KWAPPOBJECT
  4984. {
  4985. $$ = (new node_type_attr( TATTR_APPOBJECT ));
  4986. }
  4987. | KWPUBLIC
  4988. {
  4989. $$ = (new node_type_attr( TATTR_PUBLIC ));
  4990. }
  4991. | KWODL
  4992. {
  4993. $$ = NULL;
  4994. }
  4995. | KWLICENSED
  4996. {
  4997. $$ = (new node_type_attr( TATTR_LICENSED ));
  4998. }
  4999. | KWCONTROL
  5000. {
  5001. $$ = (new node_type_attr( TATTR_CONTROL ));
  5002. }
  5003. | KWDUAL
  5004. {
  5005. $$ = (new node_type_attr( TATTR_DUAL ));
  5006. }
  5007. | KWPROXY
  5008. {
  5009. $$ = (new node_type_attr( TATTR_PROXY ));
  5010. }
  5011. | KWNONEXTENSIBLE
  5012. {
  5013. $$ = (new node_type_attr( TATTR_NONEXTENSIBLE ));
  5014. }
  5015. | KWOLEAUTOMATION
  5016. {
  5017. $$ = (new node_type_attr( TATTR_OLEAUTOMATION ));
  5018. }
  5019. | KWLCID
  5020. {
  5021. $$ = (new battr( ATTR_FLCID ));
  5022. }
  5023. | KWNONCREATABLE
  5024. {
  5025. if (!FNewTypeLib())
  5026. {
  5027. ParseError( INVALID_NEWTLB_ATTRIBUTE, "[noncreatable]");
  5028. }
  5029. $$ = (new node_type_attr( TATTR_NONCREATABLE ));
  5030. }
  5031. | KWAGGREGATABLE
  5032. {
  5033. if (!FNewTypeLib())
  5034. {
  5035. ParseError( INVALID_NEWTLB_ATTRIBUTE, "[aggregatable]");
  5036. }
  5037. $$ = (new node_type_attr( TATTR_AGGREGATABLE ));
  5038. }
  5039. | KWUIDEFAULT
  5040. {
  5041. if (!FNewTypeLib())
  5042. {
  5043. ParseError( INVALID_NEWTLB_ATTRIBUTE, "[uidefault]");
  5044. }
  5045. $$ = (new node_member_attr( MATTR_UIDEFAULT ));
  5046. }
  5047. | KWNONBROWSABLE
  5048. {
  5049. if (!FNewTypeLib())
  5050. {
  5051. ParseError( INVALID_NEWTLB_ATTRIBUTE, "[nonbrowsable]");
  5052. }
  5053. $$ = (new node_member_attr( MATTR_NONBROWSABLE ));
  5054. }
  5055. | KWDEFAULTCOLLELEM
  5056. {
  5057. if (!FNewTypeLib())
  5058. {
  5059. ParseError( INVALID_NEWTLB_ATTRIBUTE, "[defaultcollem]");
  5060. }
  5061. $$ = (new node_member_attr( MATTR_DEFAULTCOLLELEM ));
  5062. }
  5063. ;
  5064. OptShape:
  5065. '(' KWSHAPE ')'
  5066. {
  5067. ParseError(IGNORE_UNIMPLEMENTED_ATTRIBUTE, "[shape]");
  5068. $$ = ATTR_NONE;
  5069. }
  5070. | /* Empty */
  5071. {
  5072. $$ = ATTR_NONE;
  5073. }
  5074. ;
  5075. /*************** DANGER: EXPRESSIONS FOLLOW: ***************/
  5076. Initializer:
  5077. AssignmentExpr
  5078. {
  5079. $$ = $1;
  5080. #ifdef gajdebug3
  5081. printf("\t...init list has constant=%d, from %d\n",
  5082. $$->IsConstant(),$1->IsConstant() );
  5083. #endif
  5084. }
  5085. | '{' InitializerList OptionalComma '}'
  5086. {
  5087. ParseError( COMPOUND_INITS_NOT_SUPPORTED, (char *)0 );
  5088. $$ = NULL;
  5089. // $$ = new expr_init_list( (expr_node *)NULL );
  5090. // $$->LinkChild( $2 );
  5091. }
  5092. /**
  5093. ** known bug : we need to figure out a way to simulate this hanging list
  5094. ** maybe by creating a special expr_list node, such that it meets
  5095. ** all semantic requirements also
  5096. **/
  5097. ;
  5098. OptionalComma:
  5099. ','
  5100. {
  5101. }
  5102. | /** Empty **/
  5103. {
  5104. }
  5105. ;
  5106. InitializerList:
  5107. Initializer
  5108. {
  5109. // $$ = $1;
  5110. }
  5111. | InitializerList ',' Initializer
  5112. {
  5113. // $$->LinkSibling( $3 );
  5114. }
  5115. ;
  5116. /***
  5117. *** VibhasC:WHERE IS THE production expr ',' AssignmentExpr valid ?
  5118. ***/
  5119. Expr:
  5120. AssignmentExpr
  5121. | Expr ',' AssignmentExpr
  5122. {
  5123. $$ = $3;
  5124. }
  5125. ;
  5126. VariableExpr:
  5127. ConditionalExpr
  5128. ;
  5129. ConstantExpr:
  5130. FConstantExpr
  5131. | ConditionalExpr
  5132. {
  5133. /**
  5134. ** The expression must be a constant, if not report error
  5135. **/
  5136. #ifdef gajdebug3
  5137. printf("constant expr is: %d\n",$1->IsConstant());
  5138. #endif
  5139. if( ! $1->IsConstant() )
  5140. ParseError( EXPR_NOT_CONSTANT, (char *)NULL );
  5141. $$ = $1;
  5142. }
  5143. ;
  5144. AssignmentExpr:
  5145. ConditionalExpr
  5146. | UnaryExpr AssignOps AssignmentExpr
  5147. {
  5148. /**
  5149. ** we do not permit assignment in expressions
  5150. **/
  5151. ParseError( SYNTAX_ERROR, (char *)NULL );
  5152. $$ = new expr_error;
  5153. }
  5154. ;
  5155. ConditionalExpr:
  5156. LogicalOrExpr
  5157. {
  5158. $$ = $1;
  5159. #if 0
  5160. printf("\n************** expression dump start ***************\n");
  5161. BufferManager * pOutput = new BufferManager( 10 );
  5162. $$->PrintExpr( (BufferManager *)NULL, (BufferManager *)NULL, pOutput );
  5163. pOutput->Print( stdout );
  5164. printf("\n****************************************************\n");
  5165. #endif // 0
  5166. }
  5167. | LogicalOrExpr '?' Expr ':' ConditionalExpr
  5168. {
  5169. /**
  5170. ** This is a ternary operator.
  5171. **/
  5172. $$ = new expr_ternary( OP_QM, $1, $3, $5 );
  5173. }
  5174. ;
  5175. LogicalOrExpr:
  5176. LogicalAndExpr
  5177. | LogicalOrExpr OROR LogicalAndExpr
  5178. {
  5179. $$ = new expr_b_logical( OP_LOGICAL_OR, $1, $3 );
  5180. }
  5181. ;
  5182. LogicalAndExpr:
  5183. InclusiveOrExpr
  5184. | LogicalAndExpr ANDAND InclusiveOrExpr
  5185. {
  5186. $$ = new expr_b_logical( OP_LOGICAL_AND, $1, $3 );
  5187. }
  5188. ;
  5189. InclusiveOrExpr:
  5190. ExclusiveOrExpr
  5191. | InclusiveOrExpr '|' ExclusiveOrExpr
  5192. {
  5193. $$ = new expr_bitwise( OP_OR, $1, $3 );
  5194. }
  5195. ;
  5196. ExclusiveOrExpr:
  5197. AndExpr
  5198. | ExclusiveOrExpr '^' AndExpr
  5199. {
  5200. $$ = new expr_bitwise( OP_XOR, $1, $3 );
  5201. }
  5202. ;
  5203. AndExpr:
  5204. EqualityExpr
  5205. | AndExpr '&' EqualityExpr
  5206. {
  5207. $$ = new expr_bitwise( OP_AND, $1, $3 );
  5208. }
  5209. ;
  5210. EqualityExpr:
  5211. RelationalExpr
  5212. | EqualityExpr EQUALS RelationalExpr
  5213. {
  5214. $$ = new expr_relational( OP_EQUAL, $1, $3 );
  5215. }
  5216. | EqualityExpr NOTEQ RelationalExpr
  5217. {
  5218. $$ = new expr_relational( OP_NOT_EQUAL, $1, $3 );
  5219. }
  5220. ;
  5221. RelationalExpr:
  5222. ShiftExpr
  5223. | RelationalExpr '<' ShiftExpr
  5224. {
  5225. $$ = new expr_relational( OP_LESS, $1, $3 );
  5226. }
  5227. | RelationalExpr '>' ShiftExpr
  5228. {
  5229. $$ = new expr_relational( OP_GREATER, $1, $3 );
  5230. }
  5231. | RelationalExpr LTEQ ShiftExpr
  5232. {
  5233. $$ = new expr_relational( OP_LESS_EQUAL, $1, $3 );
  5234. }
  5235. | RelationalExpr GTEQ ShiftExpr
  5236. {
  5237. $$ = new expr_relational( OP_GREATER_EQUAL, $1, $3 );
  5238. }
  5239. ;
  5240. ShiftExpr:
  5241. AdditiveExpr
  5242. | ShiftExpr LSHIFT AdditiveExpr
  5243. {
  5244. $$ = new expr_shift( OP_LEFT_SHIFT, $1, $3 );
  5245. }
  5246. | ShiftExpr RSHIFT AdditiveExpr
  5247. {
  5248. $$ = new expr_shift( OP_RIGHT_SHIFT, $1, $3 );
  5249. }
  5250. ;
  5251. AdditiveExpr:
  5252. MultExpr
  5253. | AdditiveExpr AddOp MultExpr
  5254. {
  5255. $$ = new expr_b_arithmetic( $2, $1, $3 );
  5256. }
  5257. ;
  5258. MultExpr:
  5259. CastExpr
  5260. | MultExpr MultOp CastExpr
  5261. {
  5262. $$ = new expr_b_arithmetic( $2, $1, $3 );
  5263. }
  5264. ;
  5265. CastExpr:
  5266. UnaryExpr
  5267. | '(' DeclarationSpecifiers OptionalDeclarator ')' CastExpr
  5268. {
  5269. node_skl * pNode = pErrorTypeNode;
  5270. if( $2.pNode )
  5271. {
  5272. if( $3.pHighest )
  5273. {
  5274. $3.pLowest->SetChild( $2.pNode );
  5275. pNode = $3.pHighest;
  5276. ( (named_node *) $3.pLowest)->GetModifiers().Merge( $2.modifiers );
  5277. }
  5278. else
  5279. pNode = $2.pNode;
  5280. }
  5281. $$ = new expr_cast( pNode, $5 );
  5282. }
  5283. ;
  5284. SizeofOrAlignof:
  5285. KWSIZEOF
  5286. { $$ = KWSIZEOF; }
  5287. | KWALIGNOF
  5288. { $$ = KWALIGNOF; }
  5289. ;
  5290. UnaryExpr:
  5291. PostfixExpr
  5292. | UnaryOp CastExpr
  5293. {
  5294. ( (expr_op_unary *) ($$ = $1) )->SetLeft( $2 );
  5295. if ( $2 )
  5296. ( (expr_op_unary *) $$)->SetConstant( $2->IsConstant() );
  5297. }
  5298. | SizeofOrAlignof '(' DeclarationSpecifiers OptionalDeclarator ')'
  5299. {
  5300. /**
  5301. ** The sizeof and alignof constructs looks like a declaration and a possible
  5302. ** declarator. All we really do, is to contruct the type ( graph )
  5303. ** and hand it over to the sizeof expression node. If there was an
  5304. ** error, just construct the size of with an error node
  5305. **/
  5306. node_skl * pNode = pErrorTypeNode;
  5307. node_skl * pLow;
  5308. if( $3.pNode )
  5309. {
  5310. if( $4.pHighest )
  5311. {
  5312. pNode = $4.pHighest;
  5313. pLow = $4.pLowest;
  5314. pLow->SetChild( $3.pNode );
  5315. pLow->GetModifiers().Merge( $3.modifiers );
  5316. }
  5317. else
  5318. {
  5319. pNode = $3.pNode;
  5320. }
  5321. }
  5322. switch( $1 )
  5323. {
  5324. case KWALIGNOF:
  5325. $$ = new expr_alignof( pNode );
  5326. break;
  5327. case KWSIZEOF:
  5328. $$ = new expr_sizeof( pNode );
  5329. break;
  5330. default:
  5331. MIDL_ASSERT(0);
  5332. break;
  5333. }
  5334. }
  5335. | SizeofOrAlignof UnaryExpr
  5336. {
  5337. switch( $1 )
  5338. {
  5339. case KWALIGNOF:
  5340. $$ = new expr_alignof( $2 );
  5341. break;
  5342. case KWSIZEOF:
  5343. $$ = new expr_sizeof( $2 );
  5344. break;
  5345. default:
  5346. MIDL_ASSERT(0);
  5347. break;
  5348. }
  5349. }
  5350. ;
  5351. PostfixExpr:
  5352. PrimaryExpr
  5353. | PostfixExpr '[' Expr ']'
  5354. {
  5355. $$ = new expr_index( $1, $3 );
  5356. }
  5357. | PostfixExpr '(' ArgExprList ')'
  5358. {
  5359. /**
  5360. ** not implemented
  5361. **/
  5362. ParseError( EXPR_NOT_IMPLEMENTED, (char *)NULL );
  5363. $$ = new expr_error;
  5364. }
  5365. | PostfixExpr POINTSTO IDENTIFIER
  5366. {
  5367. expr_variable * pIDExpr = new expr_variable( $3 );
  5368. $$ = new expr_pointsto( $1, pIDExpr );
  5369. }
  5370. | PostfixExpr '.' IDENTIFIER
  5371. {
  5372. expr_variable * pIDExpr = new expr_variable( $3 );
  5373. $$ = new expr_dot( $1, pIDExpr );
  5374. }
  5375. ;
  5376. PrimaryExpr:
  5377. IDENTIFIER
  5378. {
  5379. // true if the identifier represents a constant
  5380. BOOL ConstVar = FALSE;
  5381. named_node * pNode = NULL;
  5382. SymKey SKey( $1, NAME_MEMBER );
  5383. pNode = pCurSymTbl->SymSearch( SKey );
  5384. // look for a global ID matching the id
  5385. if ( ! pNode )
  5386. {
  5387. SymKey SKey2( $1, NAME_ID );
  5388. pNode = pBaseSymTbl->SymSearch( SKey2 );
  5389. ConstVar = (pNode) ? ((node_id_fe *) pNode)->IsConstant() : FALSE;
  5390. }
  5391. // look for a global enum label matching the id
  5392. if ( !pNode )
  5393. {
  5394. SymKey SKey2( $1, NAME_LABEL );
  5395. pNode = pBaseSymTbl->SymSearch( SKey2 );
  5396. ConstVar = (pNode != NULL);
  5397. }
  5398. if ( !pNode ) pNode = new node_forward( SKey, pCurSymTbl );
  5399. if (ConstVar)
  5400. {
  5401. $$ = new expr_named_constant( $1, pNode );
  5402. }
  5403. else
  5404. {
  5405. $$ = new expr_variable( $1, pNode );
  5406. }
  5407. }
  5408. | FLOATCONSTANT
  5409. {
  5410. $$ = new expr_constant( $1.fVal, VALUE_TYPE_FLOAT );
  5411. $$->SetFloatExpr();
  5412. }
  5413. | DOUBLECONSTANT
  5414. {
  5415. $$ = new expr_constant( $1.dVal, VALUE_TYPE_DOUBLE );
  5416. $$->SetFloatExpr();
  5417. }
  5418. | NUMERICCONSTANT
  5419. {
  5420. $$ = new expr_constant( (long) $1.Val, VALUE_TYPE_NUMERIC );
  5421. }
  5422. | NUMERICUCONSTANT
  5423. {
  5424. $$ = new expr_constant( (long) $1.Val, VALUE_TYPE_NUMERIC_U);
  5425. node_skl * pType;
  5426. GetBaseTypeNode( &pType, SIGN_UNSIGNED,SIZE_UNDEF,TYPE_INT, 0 );
  5427. $$->SetType( pType );
  5428. }
  5429. | NUMERICLONGCONSTANT
  5430. {
  5431. $$ = new expr_constant( (long) $1.Val, VALUE_TYPE_NUMERIC_LONG);
  5432. node_skl * pType;
  5433. GetBaseTypeNode( &pType, SIGN_SIGNED,SIZE_LONG,TYPE_INT, 0 );
  5434. $$->SetType( pType );
  5435. }
  5436. | NUMERICULONGCONSTANT
  5437. {
  5438. $$ = new expr_constant( (long) $1.Val, VALUE_TYPE_NUMERIC_ULONG);
  5439. node_skl * pType;
  5440. GetBaseTypeNode( &pType, SIGN_UNSIGNED,SIZE_LONG,TYPE_INT, 0 );
  5441. $$->SetType( pType );
  5442. }
  5443. | HEXCONSTANT
  5444. {
  5445. $$ = new expr_constant( (long) $1.Val, VALUE_TYPE_HEX );
  5446. }
  5447. | HEXUCONSTANT
  5448. {
  5449. $$ = new expr_constant( (long) $1.Val, VALUE_TYPE_HEX_U);
  5450. node_skl * pType;
  5451. GetBaseTypeNode( &pType, SIGN_UNSIGNED,SIZE_UNDEF,TYPE_INT, 0 );
  5452. $$->SetType( pType );
  5453. }
  5454. | HEXLONGCONSTANT
  5455. {
  5456. $$ = new expr_constant( (long) $1.Val, VALUE_TYPE_HEX_LONG);
  5457. node_skl * pType;
  5458. GetBaseTypeNode( &pType, SIGN_SIGNED,SIZE_LONG,TYPE_INT, 0 );
  5459. $$->SetType( pType );
  5460. }
  5461. | HEXULONGCONSTANT
  5462. {
  5463. $$ = new expr_constant( (long) $1.Val, VALUE_TYPE_HEX_ULONG);
  5464. node_skl * pType;
  5465. GetBaseTypeNode( &pType, SIGN_UNSIGNED,SIZE_LONG,TYPE_INT, 0 );
  5466. $$->SetType( pType );
  5467. }
  5468. | OCTALCONSTANT
  5469. {
  5470. $$ = new expr_constant( (long) $1.Val, VALUE_TYPE_OCTAL );
  5471. }
  5472. | OCTALUCONSTANT
  5473. {
  5474. $$ = new expr_constant( (long) $1.Val, VALUE_TYPE_OCTAL_U);
  5475. node_skl * pType;
  5476. GetBaseTypeNode( &pType, SIGN_UNSIGNED,SIZE_UNDEF,TYPE_INT, 0 );
  5477. $$->SetType( pType );
  5478. }
  5479. | OCTALLONGCONSTANT
  5480. {
  5481. $$ = new expr_constant( (long) $1.Val, VALUE_TYPE_OCTAL_LONG);
  5482. node_skl * pType;
  5483. GetBaseTypeNode( &pType, SIGN_SIGNED,SIZE_LONG,TYPE_INT, 0 );
  5484. $$->SetType( pType );
  5485. }
  5486. | OCTALULONGCONSTANT
  5487. {
  5488. $$ = new expr_constant( (long) $1.Val, VALUE_TYPE_OCTAL_ULONG);
  5489. node_skl * pType;
  5490. GetBaseTypeNode( &pType, SIGN_UNSIGNED,SIZE_LONG,TYPE_INT, 0 );
  5491. $$->SetType( pType );
  5492. }
  5493. | TOKENTRUE
  5494. {
  5495. $$ = new expr_constant( (long)TRUE, VALUE_TYPE_BOOL );
  5496. }
  5497. | TOKENFALSE
  5498. {
  5499. $$ = new expr_constant( (long)FALSE, VALUE_TYPE_BOOL );
  5500. }
  5501. | KWTOKENNULL
  5502. {
  5503. $$ = new expr_constant( (char *)NULL, VALUE_TYPE_STRING );
  5504. }
  5505. | STRING
  5506. {
  5507. $$ = new expr_constant( (char *)$1, VALUE_TYPE_STRING );
  5508. }
  5509. | WIDECHARACTERSTRING
  5510. {
  5511. ParseError( WCHAR_STRING_NOT_OSF, (char *)NULL );
  5512. $$ = new expr_constant( (wchar_t *)$1, VALUE_TYPE_WSTRING );
  5513. }
  5514. | CHARACTERCONSTANT
  5515. {
  5516. $$ = new expr_constant( (long)( ((long)$1.Val) & 0xff ) ,
  5517. VALUE_TYPE_CHAR );
  5518. }
  5519. | WIDECHARACTERCONSTANT
  5520. {
  5521. $$ = new expr_constant( (long)( ((long)$1.Val ) & 0xffff ),
  5522. VALUE_TYPE_WCHAR );
  5523. ParseError( WCHAR_CONSTANT_NOT_OSF, (char *)NULL );
  5524. }
  5525. | '(' Expr ')'
  5526. {
  5527. $$ = $2;
  5528. }
  5529. ;
  5530. UnaryOp:
  5531. AddOp
  5532. {
  5533. $$ = new expr_u_arithmetic( ($1 == OP_PLUS) ?
  5534. OP_UNARY_PLUS : OP_UNARY_MINUS,
  5535. NULL );
  5536. }
  5537. | '!'
  5538. {
  5539. $$ = new expr_u_not( NULL );
  5540. }
  5541. | '&'
  5542. {
  5543. $$ = new expr_u_deref( OP_UNARY_AND, NULL );
  5544. }
  5545. | '*'
  5546. {
  5547. $$ = new expr_u_deref( OP_UNARY_INDIRECTION, NULL );
  5548. }
  5549. | '~'
  5550. {
  5551. $$ = new expr_u_complement( NULL);
  5552. }
  5553. ;
  5554. AddOp:
  5555. '+'
  5556. {
  5557. $$ = OP_PLUS;
  5558. }
  5559. | '-'
  5560. {
  5561. $$ = OP_MINUS;
  5562. }
  5563. ;
  5564. MultOp:
  5565. '*'
  5566. {
  5567. $$ = OP_STAR;
  5568. }
  5569. | '/'
  5570. {
  5571. $$ = OP_SLASH;
  5572. }
  5573. | '%'
  5574. {
  5575. $$ = OP_MOD;
  5576. }
  5577. ;
  5578. ArgExprList:
  5579. AssignmentExpr
  5580. {
  5581. ParseError( EXPR_NOT_IMPLEMENTED, (char *)NULL );
  5582. $$ = new expr_error;
  5583. }
  5584. | ArgExprList ',' AssignmentExpr
  5585. {
  5586. /* UNIMPLEMENTED YET */
  5587. $$ = $1;
  5588. }
  5589. ;
  5590. AssignOps:
  5591. MULASSIGN
  5592. | DIVASSIGN
  5593. | MODASSIGN
  5594. | ADDASSIGN
  5595. | SUBASSIGN
  5596. | LEFTASSIGN
  5597. | RIGHTASSIGN
  5598. | ANDASSIGN
  5599. | XORASSIGN
  5600. | ORASSIGN
  5601. ;
  5602. FConstantExpr:
  5603. FAdditiveExpr
  5604. | FConstantExpr AddOp FAdditiveExpr
  5605. {
  5606. $$ = new expr_b_arithmetic( $2, $1, $3 );
  5607. $$->SetFloatExpr();
  5608. }
  5609. ;
  5610. FAdditiveExpr:
  5611. FMultExpr
  5612. | FAdditiveExpr MultOp FMultExpr
  5613. {
  5614. $$ = new expr_b_arithmetic( $2, $1, $3 );
  5615. $$->SetFloatExpr();
  5616. }
  5617. ;
  5618. FMultExpr:
  5619. FUnaryOp FLOATCONSTANT
  5620. {
  5621. expr_constant* pExpr = new expr_constant( $2.fVal, VALUE_TYPE_FLOAT );
  5622. pExpr->SetFloatExpr();
  5623. ( (expr_op_unary *) ($$ = $1) )->SetLeft( pExpr );
  5624. }
  5625. | FUnaryOp DOUBLECONSTANT
  5626. {
  5627. expr_constant* pExpr = new expr_constant( $2.dVal, VALUE_TYPE_DOUBLE );
  5628. pExpr->SetFloatExpr();
  5629. ( (expr_op_unary *) ($$ = $1) )->SetLeft( pExpr );
  5630. }
  5631. | FLOATCONSTANT
  5632. {
  5633. $$ = new expr_constant( $1.fVal, VALUE_TYPE_FLOAT );
  5634. $$->SetFloatExpr();
  5635. }
  5636. | DOUBLECONSTANT
  5637. {
  5638. $$ = new expr_constant( $1.dVal, VALUE_TYPE_DOUBLE );
  5639. $$->SetFloatExpr();
  5640. }
  5641. ;
  5642. FUnaryOp:
  5643. AddOp
  5644. {
  5645. $$ = new expr_u_arithmetic( $1 == OP_MINUS ? OP_UNARY_MINUS : OP_UNARY_PLUS, 0 );
  5646. $$->SetFloatExpr();
  5647. }
  5648. ;
  5649. %%
  5650. /***************************************************************************
  5651. * utility routines
  5652. **************************************************************************/
  5653. YYSTATIC VOID FARCODE PASCAL
  5654. yyerror(char *szError)
  5655. {
  5656. // this routine should really never be called now, since I
  5657. // modified yypars.c to report errors thru the ParseError
  5658. // mechanism
  5659. fprintf(stderr, szError);
  5660. }
  5661. void
  5662. NTDBG( char * p )
  5663. {
  5664. printf("VC_DBG: %s\n", p );
  5665. }