Windows NT 4.0 source code leak
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.

428 lines
15 KiB

4 years ago
  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. semantic.hxx
  5. Abstract:
  6. types for semantic analysis
  7. Notes:
  8. Author:
  9. GregJen Sep-24-1993 Created.
  10. Notes:
  11. ----------------------------------------------------------------------------*/
  12. #ifndef __SEMANTIC_HXX__
  13. #define __SEMANTIC_HXX__
  14. /****************************************************************************
  15. * include files
  16. ***************************************************************************/
  17. #include "listhndl.hxx"
  18. #include "midlnode.hxx"
  19. #include "attrlist.hxx"
  20. #include "nodeskl.hxx"
  21. #include "fldattr.hxx"
  22. #include "walkctxt.hxx"
  23. #include "gramutil.hxx"
  24. #include "cmdana.hxx"
  25. /****************************************************************************
  26. * local data
  27. ***************************************************************************/
  28. /****************************************************************************
  29. * externs
  30. ***************************************************************************/
  31. /****************************************************************************
  32. * definitions
  33. ***************************************************************************/
  34. /*
  35. * here are flag bits passed down from parents to give info on the
  36. * current path down the typegraph. These are dynamic information only,
  37. * and are NOT to be stored with the node.
  38. *
  39. * Although a few of these bits are mutually exclusive, most may be used
  40. * in combination.
  41. */
  42. enum _ANCESTOR_FLAGS
  43. { // you are:
  44. IN_INTERFACE = 0x00000001, // in the base interface
  45. IN_PARAM_LIST = 0x00000002, // a descendant of a parameter
  46. IN_FUNCTION_RESULT = 0x00000004, // used as (part of) a return type
  47. IN_STRUCT = 0x00000008, // used in a struct
  48. IN_UNION = 0x00000010, // used in a union
  49. IN_ARRAY = 0x00000020, // used in an array
  50. IN_POINTER = 0x00000040, // below a pointer
  51. IN_RPC = 0x00000080, // in an RPC call
  52. UNDER_IN_PARAM = 0x00000100, // in an IN parameter
  53. UNDER_OUT_PARAM = 0x00000200, // in an OUT parameter
  54. BINDING_SEEN = 0x00000400, // binding handle already seen
  55. IN_TRANSMIT_AS = 0x00000800, // the transmitted type of transmit_as
  56. IN_REPRESENT_AS = 0x00001000, // the "transmitted" type of represent_as
  57. IN_USER_MARSHAL = 0x00002000, // transmitted type of
  58. IN_HANDLE = 0x00004000, // under generic or context hdl
  59. IN_NE_UNION = 0x00008000, // inside an non-encap union
  60. IN_INTERPRET = 0x00010000, // in an /Oi proc
  61. IN_NON_REF_PTR = 0x00020000, // under a series of unique/full ptrs
  62. UNDER_TOPLEVEL = 0x00040000, // top-level under param
  63. UNDER_TOPLVL_PTR = 0x00080000, // top-level under pointer param
  64. IN_BASE_CLASS = 0x00100000, // checking class derivation tree
  65. IN_PRESENTED_TYPE = 0x00200000, // the presented type of xmit/rep_as
  66. IN_ROOT_CLASS = 0x00400000, // a method/definition in the root class
  67. // (i.e. IUnknown)
  68. IN_ENCODE_INTF = 0x00800000, // inside an encode/decode only intf
  69. IN_RECURSIVE_DEF = 0x01000000, // inside of a recursive definition
  70. // be sure to make sure below type fits the range
  71. IN_OBJECT_INTF = 0x02000000, // in an object interface
  72. IN_LOCAL_PROC = 0x04000000, // in a [local] proc
  73. IN_INTERFACE_PTR = 0x08000000, // in the definition of an interface pointer
  74. IN_MODULE = 0x10000000, // in a module
  75. IN_COCLASS = 0x20000000, // in a coclass
  76. IN_LIBRARY = 0x40000000, // in a library
  77. IN_DISPINTERFACE = 0x80000000, // in a dispinterface
  78. };
  79. typedef unsigned long ANCESTOR_FLAGS; // above enum goes into here
  80. /*
  81. * Here are flag bits returned UP from children to give info on the current
  82. * path down the typegraph. Again, these are dynamic information.
  83. */
  84. enum _DESCENDANT_FLAGS
  85. {
  86. UNUSED_UNUSED_1 = 0x00000001, // *** free bit position
  87. HAS_IN = 0x00000002, // has [IN] attr
  88. HAS_OUT = 0x00000004, // has [OUT] attr
  89. HAS_HANDLE = 0x00000008, // is a handle
  90. HAS_POINTER = 0x00000010, // has a pointer below
  91. HAS_INCOMPLETE_TYPE = 0x00000020, // has incomplete type spec below
  92. HAS_VAR_ARRAY = 0x00000040, // has varying array (incl string)
  93. HAS_CONF_ARRAY = 0x00000080, // has conf array
  94. HAS_CONF_VAR_ARRAY = 0x00000100, // has conf_var array
  95. DERIVES_FROM_VOID = 0x00000200, // derives from void
  96. HAS_UNSAT_REP_AS = 0x00000400, // has unsatisfied rep_as
  97. HAS_CONTEXT_HANDLE = 0x00000800, // has context handle below
  98. HAS_CONF_PTR = 0x00001000, // has conformant pointer
  99. HAS_VAR_PTR = 0x00002000, // has varying pointer
  100. HAS_CONF_VAR_PTR = 0x00004000, // has conformant varying pointer
  101. HAS_TRANSMIT_AS = 0x00008000, // has transmit_as below
  102. HAS_REPRESENT_AS = 0x00010000, // has represent_as below
  103. HAS_E_STAT_T = 0x00020000, // has error_status_t below
  104. HAS_UNION = 0x00040000, // has union below
  105. HAS_ARRAY = 0x00080000, // has array below
  106. HAS_INTERFACE_PTR = 0x00100000, // has an interface ptr below
  107. HAS_DIRECT_CONF_OR_VAR = 0x00200000, // has direct conformance or variance
  108. HAS_RECURSIVE_DEF = 0x00400000, // is defined recursively
  109. HAS_ENUM = 0x00800000, // has an enum directly or embedded
  110. HAS_FUNC = 0x01000000, // has a function below
  111. HAS_FULL_PTR = 0x02000000, // has full pointers anywhere
  112. HAS_TOO_BIG_HDL = 0x04000000, // is /Oi but handle is too big
  113. HAS_STRUCT = 0x08000000, // has struct
  114. HAS_MULTIDIM_SIZING = 0x10000000, // has multi-dimensions
  115. HAS_ARRAY_OF_REF = 0x20000000, // has array of ref pointers
  116. HAS_HRESULT = 0x40000000, // has HRESULT
  117. HAS_PIPE = 0x80000000, // has a PIPE
  118. // more tbd
  119. // be sure to make sure below type fits the range
  120. };
  121. typedef unsigned long DESCENDANT_FLAGS; // above enum goes into here
  122. /*
  123. * Here is the context information passed down from parent to child.
  124. * These will be allocated on the stack during the traversal
  125. */
  126. class node_interface;
  127. class type_node_list;
  128. class ATTRLIST;
  129. class SEM_ANALYSIS_CTXT: public WALK_CTXT
  130. {
  131. public:
  132. struct _current_ctxt {
  133. // down stuff
  134. ANCESTOR_FLAGS AncestorBits; // where am I? stuff
  135. // up stuff
  136. DESCENDANT_FLAGS DescendantBits;
  137. } CurrentCtxt;
  138. // constructor and destructor
  139. SEM_ANALYSIS_CTXT(node_skl * Me)
  140. : WALK_CTXT( Me )
  141. {
  142. GetAncestorBits() = 0;
  143. GetDescendantBits() = 0;
  144. }
  145. SEM_ANALYSIS_CTXT(node_skl * Me,
  146. SEM_ANALYSIS_CTXT * pParentCtxt )
  147. : WALK_CTXT( Me, pParentCtxt )
  148. {
  149. // clone information from parent node
  150. CurrentCtxt = pParentCtxt->CurrentCtxt;
  151. // get fresh information from our children
  152. GetDescendantBits() = 0;
  153. // remove any inapplicable attributes
  154. CheckAttributes();
  155. }
  156. SEM_ANALYSIS_CTXT(SEM_ANALYSIS_CTXT * pParentCtxt )
  157. : WALK_CTXT( pParentCtxt )
  158. {
  159. // clone information from parent node
  160. CurrentCtxt = pParentCtxt->CurrentCtxt;
  161. // get fresh information from our children
  162. GetDescendantBits() = 0;
  163. }
  164. ANCESTOR_FLAGS& GetAncestorBits()
  165. {
  166. return CurrentCtxt.AncestorBits;
  167. }
  168. ANCESTOR_FLAGS& SetAncestorBits( ANCESTOR_FLAGS f )
  169. {
  170. CurrentCtxt.AncestorBits |= f;
  171. return CurrentCtxt.AncestorBits;
  172. }
  173. ANCESTOR_FLAGS& ClearAncestorBits( ANCESTOR_FLAGS f )
  174. {
  175. CurrentCtxt.AncestorBits &= ~f;
  176. return CurrentCtxt.AncestorBits;
  177. }
  178. BOOL AnyAncestorBits( ANCESTOR_FLAGS f )
  179. {
  180. return (CurrentCtxt.AncestorBits & f);
  181. }
  182. BOOL AllAncestorBits( ANCESTOR_FLAGS f )
  183. {
  184. return ((CurrentCtxt.AncestorBits & f) == f);
  185. }
  186. DESCENDANT_FLAGS& GetDescendantBits()
  187. {
  188. return CurrentCtxt.DescendantBits;
  189. }
  190. DESCENDANT_FLAGS& SetDescendantBits( DESCENDANT_FLAGS f )
  191. {
  192. CurrentCtxt.DescendantBits |= f;
  193. return CurrentCtxt.DescendantBits;
  194. }
  195. DESCENDANT_FLAGS& ClearDescendantBits( DESCENDANT_FLAGS f )
  196. {
  197. CurrentCtxt.DescendantBits &= ~f;
  198. return CurrentCtxt.DescendantBits;
  199. }
  200. DESCENDANT_FLAGS& ClearAllDescendantBits( )
  201. {
  202. CurrentCtxt.DescendantBits = 0;
  203. return CurrentCtxt.DescendantBits;
  204. }
  205. BOOL AnyDescendantBits( DESCENDANT_FLAGS f )
  206. {
  207. return (CurrentCtxt.DescendantBits & f);
  208. }
  209. BOOL AllDescendantBits( DESCENDANT_FLAGS f )
  210. {
  211. return ((CurrentCtxt.DescendantBits & f) == f);
  212. }
  213. void ReturnValues( SEM_ANALYSIS_CTXT & ChildCtxt )
  214. {
  215. // pass up the return context
  216. GetDescendantBits() |= ChildCtxt.GetDescendantBits();
  217. }
  218. void ResetDownValues( SEM_ANALYSIS_CTXT & ParentCtxt )
  219. {
  220. // reset the down values from the parent
  221. // (semantically different, but really the same code )
  222. ReturnValues( ParentCtxt );
  223. }
  224. void CheckAttributes();
  225. void RejectAttributes();
  226. }; // end of class SEM_ANALYSIS_CTXT
  227. inline void
  228. RpcSemError( node_skl * pNode,
  229. SEM_ANALYSIS_CTXT & Ctxt,
  230. STATUS_T ErrNum,
  231. char * pExtra )
  232. {
  233. if ( Ctxt.AnyAncestorBits( IN_RPC ) &&
  234. !Ctxt.AnyAncestorBits( IN_LOCAL_PROC ) )
  235. SemError( pNode, Ctxt, ErrNum, pExtra );
  236. }
  237. inline void
  238. TypeSemError( node_skl * pNode,
  239. SEM_ANALYSIS_CTXT & Ctxt,
  240. STATUS_T ErrNum,
  241. char * pExtra )
  242. {
  243. if ( !Ctxt.AnyAncestorBits( IN_LOCAL_PROC ) )
  244. SemError( pNode, Ctxt, ErrNum, pExtra );
  245. }
  246. // prototype for semantic advice routines
  247. inline void
  248. SemAdvice( node_skl * pNode,
  249. WALK_CTXT & Ctxt,
  250. STATUS_T ErrVal,
  251. char * pSuffix )
  252. {
  253. if ( pCommand->IsMintRun() )
  254. SemError( pNode, Ctxt, ErrVal, pSuffix );
  255. }
  256. class acf_attr;
  257. extern void
  258. AcfError( acf_attr*, node_skl *, WALK_CTXT &, STATUS_T, char * );
  259. /////////////////////////////////////////////
  260. //
  261. // expression analysis flags (passed up)
  262. enum _EXPR_UP_FLAGS
  263. {
  264. EX_NONE = 0x0000,
  265. EX_VALUE_INVALID = 0x0001, // value is NOT valid
  266. EX_UNSAT_FWD = 0x0002, // there is an unsatisfied fwd
  267. EX_NON_NUMERIC = 0x0004, // expr not entirely numerics
  268. // (can not be constant folded)
  269. EX_OUT_ONLY_PARAM = 0x0008, // expression includes an out-only param
  270. EX_PTR_FULL_UNIQUE = 0x0010, // has ptr deref of full or unique ptr
  271. EX_HYPER_IN_EXPR = 0x0020, // expr has a hyper item in it
  272. };
  273. typedef unsigned short EXPR_UP_FLAGS;
  274. ////////////////////////////////////////////
  275. // expression context block
  276. class EXPR_CTXT;
  277. class EXPR_CTXT
  278. {
  279. private:
  280. // passed down
  281. EXPR_CTXT * pParent;
  282. SEM_ANALYSIS_CTXT * pSemCtxt;
  283. // passed up
  284. EXPR_VALUE CurValue;
  285. EXPR_UP_FLAGS Flags;
  286. public:
  287. // type info
  288. node_skl * pType;
  289. struct _type_ana TypeInfo;
  290. BOOL fIntegral; // type is an integral type (above are valid)
  291. EXPR_CTXT( EXPR_CTXT * pMy )
  292. {
  293. pParent = pMy;
  294. pSemCtxt = pMy->pSemCtxt;
  295. CurValue = 0;
  296. Flags = EX_NONE;
  297. }
  298. EXPR_CTXT( SEM_ANALYSIS_CTXT * pSCtxt )
  299. {
  300. pParent = NULL;
  301. pSemCtxt = pSCtxt;
  302. CurValue = 0;
  303. Flags = EX_NONE;
  304. }
  305. // automatically pass up the flags
  306. ~EXPR_CTXT()
  307. {
  308. if ( pParent )
  309. pParent->Flags |= Flags;
  310. }
  311. EXPR_VALUE& Value()
  312. {
  313. return CurValue;
  314. }
  315. EXPR_UP_FLAGS& MergeUpFlags( EXPR_CTXT * pC )
  316. {
  317. Flags |= pC->Flags;
  318. return Flags;
  319. }
  320. EXPR_UP_FLAGS& SetUpFlags( EXPR_UP_FLAGS f )
  321. {
  322. Flags |= f;
  323. return Flags;
  324. }
  325. EXPR_UP_FLAGS& ClearUpFlags( EXPR_UP_FLAGS f )
  326. {
  327. Flags &= ~f;
  328. return Flags;
  329. }
  330. BOOL AnyUpFlags( EXPR_UP_FLAGS f )
  331. {
  332. return (Flags & f);
  333. }
  334. BOOL AllUpFlags( EXPR_UP_FLAGS f )
  335. {
  336. return ((Flags & f) == f);
  337. }
  338. node_skl* GetNode()
  339. {
  340. return pSemCtxt->GetParent();
  341. }
  342. SEM_ANALYSIS_CTXT * GetCtxt()
  343. {
  344. return pSemCtxt;
  345. }
  346. };
  347. #endif // __SEMANTIC_HXX__