Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

7008 lines
231 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1989-1999 Microsoft Corporation
  3. Module Name:
  4. semantic.cxx
  5. Abstract:
  6. semantic analysis routines
  7. Notes:
  8. Author:
  9. GregJen Jun-11-1993 Created.
  10. Notes:
  11. ----------------------------------------------------------------------------*/
  12. // unreferenced inline/local function has been removed
  13. #pragma warning ( disable : 4514 )
  14. /****************************************************************************
  15. * include files
  16. ***************************************************************************/
  17. #include <basetsd.h>
  18. #include "allnodes.hxx"
  19. #include "semantic.hxx"
  20. #include "cmdana.hxx"
  21. extern "C"
  22. {
  23. #include <string.h>
  24. }
  25. #include "treg.hxx"
  26. #include "tlgen.hxx"
  27. #include "Pragma.hxx"
  28. // #include "attrguid.hxx"
  29. BOOL
  30. IsOLEAutomationType (
  31. char*
  32. );
  33. BOOL
  34. IsOLEAutomationCompliant(
  35. node_skl*
  36. );
  37. node_interface*
  38. CloneIFAndSplitMethods (
  39. node_interface*
  40. );
  41. node_skl*
  42. GetInOnlyParamPairedWithOut (
  43. MEM_ITER& MemParamList
  44. );
  45. bool
  46. HasCorrelation (
  47. node_skl*
  48. );
  49. #define RPC_ASYNC_HANDLE_NAME "PRPC_ASYNC_STATE"
  50. #define RPC_ASYNC_STRUCT_NAME "_RPC_ASYNC_STATE"
  51. #define OBJECT_ASYNC_HANDLE_NAME "IAsyncManager"
  52. #define IS_OLD_INTERPRETER( x ) ( ((x) & OPTIMIZE_INTERPRETER) && !((x) & OPTIMIZE_INTERPRETER_V2) )
  53. #define IsCoclassOrDispKind(x) ( (x) == NODE_DISPINTERFACE || (x) == NODE_COCLASS )
  54. #define IsInterfaceKind(x) ( (x) == NODE_INTERFACE_REFERENCE || (x) == NODE_INTERFACE )
  55. //
  56. // This state table defines the rules that govern valid [propput] methods.
  57. //
  58. namespace PropPut
  59. {
  60. enum State
  61. {
  62. NoParam = 0,
  63. GeneralParam = 1,
  64. Optional = 2,
  65. Default = 3,
  66. LCID = 4,
  67. LastParam = 5,
  68. Reject = 6,
  69. Accept = 7,
  70. };
  71. // Accept = Param* (optional|default)* (param|lcidparam|default)
  72. State StateTable[][5] =
  73. {
  74. // no param regular optional default lcid
  75. // -----------------------------------------------------------
  76. {Reject, GeneralParam, Optional, Default, LCID}, // NoParam
  77. {Accept, GeneralParam, Optional, Default, LCID}, // GeneralParam
  78. {Reject, LastParam, Optional, Default, LCID}, // Optional
  79. {Accept, LastParam, Optional, Default, LCID}, // Default
  80. {Reject, LastParam, Reject, Reject, Reject}, // LCID
  81. {Accept, Reject, Reject, Reject, Reject}, // LastParam
  82. {Reject, Reject, Reject, Reject, Reject}, // Reject
  83. {Accept, Reject, Reject, Reject, Reject} // Accept
  84. };
  85. }
  86. /****************************************************************************
  87. * externs
  88. ***************************************************************************/
  89. extern BOOL IsTempName( char * );
  90. extern CMD_ARG * pCommand;
  91. extern SymTable * pUUIDTable;
  92. extern SymTable * pBaseSymTbl;
  93. extern TREGISTRY * pCallAsTable;
  94. extern BOOL Xxx_Is_Type_OK( node_skl * pType );
  95. extern "C"
  96. {
  97. #ifndef GUID_DEFINED
  98. #define GUID_DEFINED
  99. typedef struct _GUID { // size is 16
  100. unsigned long Data1;
  101. unsigned short Data2;
  102. unsigned short Data3;
  103. unsigned char Data4[8];
  104. } GUID;
  105. #endif
  106. typedef GUID IID;
  107. extern const GUID IID_IAdviseSink;
  108. extern const GUID IID_IAdviseSink2;
  109. extern const GUID IID_IAdviseSinkEx;
  110. extern const GUID IID_AsyncIAdviseSink;
  111. extern const GUID IID_AsyncIAdviseSink2;
  112. // {DE77BA62-517C-11d1-A2DA-0000F8773CE9}
  113. static const GUID IID_AsyncIAdviseSinkEx2 =
  114. { 0xde77ba62, 0x517c, 0x11d1, { 0xa2, 0xda, 0x0, 0x0, 0xf8, 0x77, 0x3c, 0xe9 } };
  115. };
  116. bool
  117. IsAnyIAdviseSinkIID (
  118. GUID& rIID
  119. )
  120. {
  121. return (
  122. !memcmp( &IID_IAdviseSink, &rIID, sizeof(GUID) )
  123. || !memcmp( &IID_IAdviseSink2, &rIID, sizeof(GUID) )
  124. || !memcmp( &IID_AsyncIAdviseSink, &rIID, sizeof(GUID) )
  125. || !memcmp( &IID_AsyncIAdviseSink2, &rIID, sizeof(GUID) )
  126. // IAdviseSinkEx will be converted to sync interface.
  127. || !memcmp( &IID_IAdviseSinkEx, &rIID, sizeof(GUID) )
  128. );
  129. }
  130. node_skl*
  131. GetIndirectionLevel (
  132. node_skl* pType,
  133. unsigned int& nIndirectionLevel
  134. )
  135. {
  136. if ( pType )
  137. {
  138. node_skl* pChild = pType->GetChild();
  139. if ( pChild )
  140. {
  141. pType = pChild;
  142. NODE_T nodeKind = pType->NodeKind();
  143. if ( nodeKind == NODE_POINTER )
  144. {
  145. return GetIndirectionLevel( pType, ++nIndirectionLevel );
  146. }
  147. else if ( nodeKind == NODE_INTERFACE )
  148. {
  149. return pType;
  150. }
  151. else
  152. {
  153. return GetIndirectionLevel( pType, nIndirectionLevel );
  154. }
  155. }
  156. }
  157. return pType;
  158. }
  159. node_skl*
  160. GetNonDefType (
  161. node_skl* pType
  162. )
  163. {
  164. node_skl* pChild = pType->GetChild();
  165. if ( pChild && pType->NodeKind() == NODE_DEF )
  166. {
  167. pType = GetNonDefType( pChild );
  168. }
  169. return pType;
  170. }
  171. void
  172. node_skl::SemanticAnalysis( SEM_ANALYSIS_CTXT * )
  173. {
  174. MIDL_ASSERT( !"node_skl semantic analysis called" );
  175. }
  176. void
  177. node_skl::CheckDeclspecAlign( SEM_ANALYSIS_CTXT & MyContext )
  178. {
  179. if (GetModifiers().IsModifierSet( ATTR_DECLSPEC_ALIGN ) &&
  180. MyContext.AnyAncestorBits( IN_LIBRARY ) )
  181. {
  182. SemError( this, MyContext, DECLSPEC_ALIGN_IN_LIBRARY, GetSymName() );
  183. }
  184. }
  185. void
  186. node_href::SemanticAnalysis( SEM_ANALYSIS_CTXT * )
  187. {
  188. // If this reference hasn't already been expanded, Resolve() will expand it.
  189. named_node * pRef = Resolve();
  190. MIDL_ASSERT(pRef || !"node_href::Resolve() failed" );
  191. // NOTE - we might want to just skip this step and simply clear any
  192. // remaining attributes.
  193. // Presumably, if it came from a type library, it must have
  194. // been previously analyzed and found to be correct.
  195. // pRef->SemanticAnalysis(pParentCtxt);
  196. // pParentCtxt->ClearAttributes();
  197. }
  198. void
  199. node_forward::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  200. {
  201. if ( fBeingAnalyzed )
  202. {
  203. return;
  204. }
  205. fBeingAnalyzed = TRUE;
  206. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  207. named_node * pRef = ResolveFDecl();
  208. MyContext.ExtractAttribute( ATTR_HELPSTRING );
  209. MyContext.ExtractAttribute( ATTR_DEFAULT );
  210. while(MyContext.ExtractAttribute( ATTR_CUSTOM ));
  211. // check for illegal member attributes
  212. node_member_attr * pMA;
  213. while ( ( pMA = (node_member_attr *)MyContext.ExtractAttribute(ATTR_MEMBER) ) != 0 )
  214. {
  215. switch (pMA->GetAttr())
  216. {
  217. case MATTR_PROPGET:
  218. case MATTR_PROPPUT:
  219. case MATTR_PROPPUTREF:
  220. case MATTR_BINDABLE:
  221. case MATTR_DISPLAYBIND:
  222. case MATTR_DEFAULTBIND:
  223. case MATTR_REQUESTEDIT:
  224. case MATTR_RETVAL:
  225. case MATTR_VARARG:
  226. case MATTR_SOURCE:
  227. case MATTR_DEFAULTVTABLE:
  228. case MATTR_RESTRICTED:
  229. case MATTR_OPTIONAL:
  230. case MATTR_PREDECLID:
  231. case MATTR_UIDEFAULT:
  232. case MATTR_NONBROWSABLE:
  233. case MATTR_DEFAULTCOLLELEM:
  234. case MATTR_IMMEDIATEBIND:
  235. case MATTR_USESGETLASTERROR:
  236. break;
  237. case MATTR_REPLACEABLE:
  238. default:
  239. {
  240. char * pAttrName = pMA->GetNodeNameString();
  241. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, pAttrName);
  242. break;
  243. }
  244. }
  245. }
  246. if ( !pRef && MyContext.AnyAncestorBits( IN_RPC ) )
  247. {
  248. SemError( this, MyContext, UNRESOLVED_TYPE, GetSymName() );
  249. }
  250. if ( pRef && ( pRef->NodeKind() == NODE_HREF ))
  251. {
  252. // expand the href
  253. pRef->SemanticAnalysis( &MyContext );
  254. node_skl* pChild = pRef->GetChild();
  255. if (pChild && pChild->NodeKind() == NODE_INTERFACE)
  256. {
  257. pRef = new node_interface_reference((node_interface *)pRef->GetChild());
  258. }
  259. }
  260. // we must go on and process interface references; they will
  261. // control any recursing and eliminate the forward reference.
  262. if ( pRef )
  263. {
  264. pRef->SemanticAnalysis( &MyContext );
  265. node_skl * pParent = pParentCtxt->GetParent();
  266. if ( pParent )
  267. {
  268. // if we came from an interface, set the base interface
  269. if ( pParent->IsInterfaceOrObject() && pRef->NodeKind() == NODE_INTERFACE_REFERENCE )
  270. {
  271. ((node_interface *)pParent)->SetMyBaseInterfaceReference( pRef );
  272. }
  273. else // otherwise, probably an interface pointer
  274. {
  275. pParent->SetChild( pRef );
  276. }
  277. }
  278. }
  279. else
  280. {
  281. // incomplete types may only be used in certain contexts...
  282. MyContext.SetDescendantBits( HAS_INCOMPLETE_TYPE );
  283. }
  284. if ( MyContext.FindRecursiveContext( pRef ) )
  285. {
  286. MyContext.SetDescendantBits( HAS_RECURSIVE_DEF );
  287. MyContext.SetAncestorBits( IN_RECURSIVE_DEF );
  288. }
  289. MyContext.RejectAttributes();
  290. pParentCtxt->ReturnValues( MyContext );
  291. fBeingAnalyzed = FALSE;
  292. }
  293. // checking the void usage in dispinterface.
  294. // currently we only check:
  295. // . void is not allowed as property or part of a structure.
  296. void node_base_type::CheckVoidUsageInDispinterface( SEM_ANALYSIS_CTXT * pContext )
  297. {
  298. SEM_ANALYSIS_CTXT * pCtxt = (SEM_ANALYSIS_CTXT *)
  299. pContext->GetParentContext();
  300. node_skl * pCur = pCtxt->GetParent();
  301. BOOL fHasPointer = FALSE;
  302. while ( pCur->NodeKind() != NODE_FIELD && pCur->NodeKind() != NODE_PROC )
  303. {
  304. if ( pCur->NodeKind() == NODE_POINTER )
  305. fHasPointer = TRUE;
  306. else
  307. {
  308. if ( pCur->NodeKind() != NODE_DEF )
  309. {
  310. RpcSemError( this, *pContext, NON_RPC_RTYPE_VOID, NULL );
  311. return;
  312. }
  313. }
  314. pCtxt = (SEM_ANALYSIS_CTXT *) pCtxt->GetParentContext();
  315. pCur = pCtxt->GetParent();
  316. }
  317. // This is either a property or part of a structure.
  318. if ( pCur->NodeKind() == NODE_FIELD )
  319. {
  320. if ( !fHasPointer )
  321. {
  322. SemError( this, *pContext, INVALID_VOID_IN_DISPINTERFACE, NULL );
  323. return;
  324. }
  325. }
  326. }
  327. void
  328. node_base_type::CheckVoidUsage( SEM_ANALYSIS_CTXT * pContext )
  329. {
  330. SEM_ANALYSIS_CTXT * pCtxt = (SEM_ANALYSIS_CTXT *)
  331. pContext->GetParentContext();
  332. node_skl * pCur = pCtxt->GetParent();
  333. // we assume that we are in an RPC, so we are in the return type
  334. // or we are in the param list
  335. if (pContext->AnyAncestorBits( IN_FUNCTION_RESULT ) )
  336. {
  337. // check up for anything other than def below proc
  338. while ( pCur->NodeKind() != NODE_PROC )
  339. {
  340. if ( pCur->NodeKind() != NODE_DEF )
  341. {
  342. RpcSemError( this, *pContext, NON_RPC_RTYPE_VOID, NULL );
  343. return;
  344. }
  345. pCtxt = (SEM_ANALYSIS_CTXT *) pCtxt->GetParentContext();
  346. pCur = pCtxt->GetParent();
  347. }
  348. return;
  349. }
  350. // else param list...
  351. node_proc * pProc;
  352. node_param * pParam;
  353. // check up for anything other than def below proc
  354. // make sure the proc only has one param
  355. while ( pCur->NodeKind() != NODE_PARAM )
  356. {
  357. if ( pCur->NodeKind() != NODE_DEF )
  358. {
  359. RpcSemError( this, *pContext, NON_RPC_PARAM_VOID, NULL );
  360. return;
  361. }
  362. pCtxt = (SEM_ANALYSIS_CTXT *) pCtxt->GetParentContext();
  363. pCur = pCtxt->GetParent();
  364. }
  365. // now we know the param derives directly from void
  366. // assume the proc is the immediate parent of the param
  367. pParam = ( node_param * ) pCur;
  368. pProc = ( node_proc * ) pCtxt->GetParentContext()->GetParent();
  369. MIDL_ASSERT ( pProc->NodeKind() == NODE_PROC );
  370. if ( ! IsTempName( pParam->GetSymName() ) )
  371. SemError( this, *pContext, VOID_PARAM_WITH_NAME, NULL );
  372. if ( pProc->GetNumberOfArguments() != 1 )
  373. SemError( this, *pContext, VOID_NON_FIRST_PARAM, NULL );
  374. // We know that the parameter is void.
  375. // So, chop it off to prevent complications from renaming etc.
  376. // and then using in a node_def in ILxlate.
  377. pProc->SetFirstMember( NULL );
  378. pProc->SetSibling( NULL );
  379. }
  380. void
  381. node_base_type::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  382. {
  383. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  384. CheckContextHandle( MyContext );
  385. CheckDeclspecAlign( MyContext );
  386. // warn about OUT const things
  387. if ( FInSummary( ATTR_CONST ) )
  388. {
  389. if ( MyContext.AnyAncestorBits( UNDER_OUT_PARAM ) )
  390. RpcSemError( this, MyContext, CONST_ON_OUT_PARAM, NULL );
  391. else if ( MyContext.AnyAncestorBits( IN_FUNCTION_RESULT ) )
  392. RpcSemError( this, MyContext, CONST_ON_RETVAL, NULL );
  393. }
  394. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  395. node_range_attr* pRange = ( node_range_attr* ) MyContext.ExtractAttribute(ATTR_RANGE);
  396. MyContext.ExtractAttribute(ATTR_RANGE);
  397. if ( pRange )
  398. {
  399. if ( pRange->GetMinExpr()->GetValue() > pRange->GetMaxExpr()->GetValue() )
  400. {
  401. SemError(this, MyContext, INCORRECT_RANGE_DEFN, 0);
  402. }
  403. }
  404. switch ( NodeKind() )
  405. {
  406. case NODE_FLOAT:
  407. case NODE_DOUBLE:
  408. case NODE_HYPER:
  409. case NODE_INT64:
  410. case NODE_LONGLONG:
  411. if ( pRange )
  412. {
  413. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, 0 );
  414. }
  415. break;
  416. case NODE_INT3264:
  417. if ( MyContext.AnyAncestorBits( IN_LIBRARY ) )
  418. {
  419. SemError( this, MyContext, NO_SUPPORT_IN_TLB, 0 );
  420. }
  421. if ( pRange && pCommand->Is64BitEnv() )
  422. {
  423. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, 0 );
  424. }
  425. break;
  426. case NODE_INT:
  427. if ( MyContext.AnyAncestorBits( IN_FUNCTION_RESULT ) )
  428. RpcSemError( this, MyContext, NON_RPC_RTYPE_INT, NULL );
  429. else
  430. RpcSemError( this, MyContext, NON_RPC_PARAM_INT, NULL );
  431. break;
  432. case NODE_INT128:
  433. case NODE_FLOAT80:
  434. case NODE_FLOAT128:
  435. if ( pRange )
  436. {
  437. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, 0 );
  438. }
  439. if ( MyContext.AnyAncestorBits( IN_LIBRARY ) )
  440. {
  441. SemError( this, MyContext, NO_SUPPORT_IN_TLB, 0 );
  442. }
  443. break;
  444. case NODE_VOID:
  445. MyContext.SetDescendantBits( DERIVES_FROM_VOID );
  446. // if we are in an RPC, then we must be THE return type,
  447. // or we must be the sole parameter, which must be tempname'd
  448. // (except that void * is allowed in [iid_is] constructs)
  449. if (MyContext.AnyAncestorBits( IN_RPC ) && !MyContext.AnyAncestorBits( IN_INTERFACE_PTR ) )
  450. CheckVoidUsage( &MyContext );
  451. if ( MyContext.AnyAncestorBits( IN_DISPINTERFACE ) )
  452. CheckVoidUsageInDispinterface( &MyContext );
  453. break;
  454. case NODE_HANDLE_T:
  455. MyContext.SetDescendantBits( HAS_HANDLE );
  456. if (MyContext.AnyAncestorBits( IN_PARAM_LIST ) )
  457. {
  458. SEM_ANALYSIS_CTXT * pParamCtxt;
  459. node_param * pParamNode;
  460. pParamCtxt = (SEM_ANALYSIS_CTXT *)
  461. pParentCtxt->FindAncestorContext( NODE_PARAM );
  462. pParamNode = (node_param *) pParamCtxt->GetParent();
  463. if ( MyContext.AnyAncestorBits( IN_RPC ) )
  464. pParamNode->HandleKind = HDL_PRIM;
  465. if ( MyContext.AnyAncestorBits( UNDER_OUT_PARAM ) &&
  466. !MyContext.AnyAncestorBits( UNDER_IN_PARAM ) )
  467. RpcSemError( this, MyContext, HANDLE_T_CANNOT_BE_OUT, NULL );
  468. if ( MyContext.AnyAncestorBits( IN_HANDLE ) )
  469. {
  470. RpcSemError( this, MyContext, GENERIC_HDL_HANDLE_T, NULL );
  471. }
  472. node_skl * pParamBasic = pParamNode->GetBasicType();
  473. if ( pParamBasic->NodeKind() == NODE_POINTER )
  474. {
  475. if ( pParamBasic->GetBasicType()->NodeKind() != NODE_HANDLE_T )
  476. RpcSemError( pParamNode, *pParamCtxt, HANDLE_T_NO_TRANSMIT, NULL );
  477. }
  478. }
  479. break;
  480. default:
  481. break;
  482. }
  483. MyContext.RejectAttributes();
  484. pParentCtxt->ReturnValues( MyContext );
  485. };
  486. BOOL
  487. node_id::IsConstantString()
  488. {
  489. // check for *, and const stringable type below
  490. node_skl * pBasic = GetBasicType();
  491. if ( pBasic->NodeKind() != NODE_POINTER )
  492. return FALSE;
  493. node_skl * pParent = pBasic;
  494. node_skl * pChild = pParent->GetChild();
  495. BOOL fConst = FALSE;
  496. while ( pChild )
  497. {
  498. // if we reached a stringable type, report it's constness
  499. if ( pChild->IsStringableType() || ( pChild->NodeKind() == NODE_VOID ) )
  500. {
  501. return fConst || pParent->FInSummary( ATTR_CONST );
  502. }
  503. // skip only typedefs looking for the base type
  504. if ( pChild->NodeKind() != NODE_DEF )
  505. return FALSE;
  506. // catch intervening const's
  507. if ( pParent->FInSummary( ATTR_CONST ) )
  508. fConst = TRUE;
  509. pParent = pChild;
  510. pChild = pParent->GetChild();
  511. }
  512. return FALSE;
  513. }
  514. void
  515. node_id::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  516. {
  517. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  518. BOOL fIsConstant;
  519. node_constant_attr * pID = (node_constant_attr *) MyContext.ExtractAttribute(ATTR_ID);
  520. MyContext.ExtractAttribute(ATTR_HELPCONTEXT);
  521. MyContext.ExtractAttribute(ATTR_HELPSTRINGCONTEXT);
  522. MyContext.ExtractAttribute(ATTR_HELPSTRING);
  523. if ( HasCorrelation( this ) )
  524. {
  525. MyContext.IncCorrelationCount();
  526. }
  527. CheckDeclspecAlign( MyContext );
  528. /*
  529. // NishadM: Stricter type checking
  530. if ( pID && pID->GetExpr()->AlwaysGetType() )
  531. {
  532. if ( !( ( node_base_type*) pID->GetExpr()->GetType() )->IsCompatibleType( ts_FixedPoint ) )
  533. {
  534. SemError( this, MyContext, EXPR_INCOMPATIBLE_TYPES, NULL);
  535. }
  536. }
  537. if ( pHC && pHC->GetExpr()->AlwaysGetType() )
  538. {
  539. if ( !( ( node_base_type*) pHC->GetExpr()->GetType() )->IsCompatibleType( ts_UnsignedFixedPoint ) )
  540. {
  541. SemError( this, MyContext, EXPR_INCOMPATIBLE_TYPES, NULL);
  542. }
  543. }
  544. if ( pHSC && pHSC->GetExpr()->AlwaysGetType() )
  545. {
  546. if ( !( ( node_base_type*) pHSC->GetExpr()->GetType() )->IsCompatibleType( ts_UnsignedFixedPoint ) )
  547. {
  548. SemError( this, MyContext, EXPR_INCOMPATIBLE_TYPES, NULL);
  549. }
  550. }
  551. */
  552. if (MyContext.ExtractAttribute(ATTR_HELPSTRINGDLL))
  553. {
  554. SemError(this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  555. }
  556. MyContext.ExtractAttribute(ATTR_HIDDEN);
  557. GetChild()->SemanticAnalysis( &MyContext );
  558. fIsConstant = FInSummary( ATTR_CONST ) ||
  559. IsConstantString() ||
  560. GetChild()->FInSummary( ATTR_CONST );
  561. if (pID)
  562. {
  563. SEM_ANALYSIS_CTXT * pIntfCtxt = (SEM_ANALYSIS_CTXT *)
  564. MyContext.GetInterfaceContext();
  565. node_interface * pIntf = (node_interface *) pIntfCtxt->GetParent();
  566. if (!pIntf->AddId(pID->GetExpr()->GetValue(), GetSymName()))
  567. SemError( this, MyContext, DUPLICATE_IID, NULL);
  568. if (fIsConstant)
  569. {
  570. SemError(this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  571. }
  572. }
  573. // don't allow instantiation of data
  574. if ( GetChild()->NodeKind() != NODE_PROC )
  575. {
  576. if ( !FInSummary( ATTR_EXTERN ) &&
  577. !FInSummary( ATTR_STATIC ) &&
  578. !fIsConstant )
  579. SemError( this, MyContext, ACTUAL_DECLARATION, NULL );
  580. // error here if dce for extern or static, too
  581. if ( !GetInitList() || !fIsConstant )
  582. SemError( this, MyContext, ILLEGAL_OSF_MODE_DECL, NULL );
  583. }
  584. if ( pInit )
  585. {
  586. EXPR_CTXT InitCtxt( &MyContext );
  587. node_skl * pBasicType = GetBasicType();
  588. node_skl * pInitType = NULL;
  589. pInit->ExprAnalyze( &InitCtxt );
  590. if ( InitCtxt.AnyUpFlags( EX_UNSAT_FWD ) )
  591. TypeSemError( this,
  592. MyContext,
  593. EXPR_NOT_EVALUATABLE,
  594. NULL );
  595. pInitType = pInit->GetType();
  596. if ( pInitType && !pInitType->IsBasicType() )
  597. pInitType = pInitType->GetBasicType();
  598. if ( pBasicType &&
  599. pInitType &&
  600. pBasicType->IsBasicType() &&
  601. pInitType->IsBasicType() )
  602. {
  603. if ( !((node_base_type *)pBasicType)
  604. ->RangeCheck( pInit->GetValue() ) )
  605. TypeSemError( this, MyContext, VALUE_OUT_OF_RANGE, NULL );
  606. }
  607. if ( !pInit->IsConstant() )
  608. TypeSemError( this, MyContext, RHS_OF_ASSIGN_NOT_CONST, NULL );
  609. }
  610. if ( MyContext.AnyAncestorBits( HAS_OLEAUTOMATION )|| MyContext.AnyAncestorBits( IN_DISPINTERFACE ) )
  611. {
  612. if ( !IsOLEAutomationCompliant( this ) )
  613. {
  614. SemError(this, MyContext, NOT_OLEAUTOMATION_INTERFACE, NULL);
  615. }
  616. }
  617. // disallow forward references on declarations
  618. if ( MyContext.AnyDescendantBits( HAS_INCOMPLETE_TYPE ) )
  619. {
  620. if (! MyContext.AnyAncestorBits( IN_LIBRARY ))
  621. SemError( this, MyContext, UNDEFINED_SYMBOL, NULL );
  622. MyContext.ClearDescendantBits( HAS_INCOMPLETE_TYPE );
  623. }
  624. MyContext.ClearDescendantBits( HAS_RECURSIVE_DEF );
  625. pParentCtxt->ReturnValues( MyContext );
  626. }
  627. void
  628. node_label::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  629. {
  630. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  631. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  632. if ( MyContext.ExtractAttribute(ATTR_IDLDESCATTR) )
  633. {
  634. SemError(this, MyContext, NEWLYFOUND_INAPPLICABLE_ATTRIBUTE, 0);
  635. }
  636. if ( MyContext.ExtractAttribute(ATTR_VARDESCATTR) )
  637. {
  638. SemError(this, MyContext, NEWLYFOUND_INAPPLICABLE_ATTRIBUTE, 0);
  639. }
  640. if ( MyContext.ExtractAttribute(ATTR_ID) )
  641. {
  642. SemError(this, MyContext, NEWLYFOUND_INAPPLICABLE_ATTRIBUTE, 0);
  643. }
  644. MyContext.ExtractAttribute(ATTR_HIDDEN);
  645. MyContext.ExtractAttribute( ATTR_HELPSTRING );
  646. MyContext.ExtractAttribute( ATTR_HELPSTRINGCONTEXT );
  647. MyContext.ExtractAttribute( ATTR_HELPCONTEXT );
  648. if (MyContext.ExtractAttribute(ATTR_HELPSTRINGDLL))
  649. {
  650. SemError(this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  651. }
  652. // check for illegal member attributes
  653. node_member_attr * pMA;
  654. while ( ( pMA = (node_member_attr *)MyContext.ExtractAttribute(ATTR_MEMBER) ) != 0 )
  655. {
  656. switch (pMA->GetAttr())
  657. {
  658. case MATTR_PROPGET:
  659. case MATTR_PROPPUT:
  660. case MATTR_PROPPUTREF:
  661. case MATTR_BINDABLE:
  662. case MATTR_DISPLAYBIND:
  663. case MATTR_DEFAULTBIND:
  664. case MATTR_REQUESTEDIT:
  665. case MATTR_RETVAL:
  666. case MATTR_VARARG:
  667. case MATTR_SOURCE:
  668. case MATTR_DEFAULTVTABLE:
  669. case MATTR_RESTRICTED:
  670. case MATTR_OPTIONAL:
  671. case MATTR_PREDECLID:
  672. case MATTR_UIDEFAULT:
  673. case MATTR_NONBROWSABLE:
  674. case MATTR_DEFAULTCOLLELEM:
  675. case MATTR_IMMEDIATEBIND:
  676. case MATTR_USESGETLASTERROR:
  677. break;
  678. case MATTR_REPLACEABLE:
  679. default:
  680. {
  681. char * pAttrName = pMA->GetNodeNameString();
  682. SemError( this, MyContext, NEWLYFOUND_INAPPLICABLE_ATTRIBUTE, pAttrName);
  683. break;
  684. }
  685. }
  686. }
  687. if ( HasCorrelation( this ) )
  688. {
  689. MyContext.IncCorrelationCount();
  690. }
  691. CheckDeclspecAlign( MyContext );
  692. if ( pExpr )
  693. {
  694. EXPR_CTXT ExprCtxt( &MyContext );
  695. pExpr->ExprAnalyze( &ExprCtxt );
  696. if ( ExprCtxt.AnyUpFlags( EX_UNSAT_FWD ) )
  697. TypeSemError( this,
  698. MyContext,
  699. EXPR_NOT_EVALUATABLE,
  700. NULL );
  701. }
  702. pParentCtxt->ReturnValues( MyContext );
  703. };
  704. #define DIRECT_NONE 0
  705. #define DIRECT_IN 1
  706. #define DIRECT_OUT 2
  707. #define DIRECT_PARTIAL_IGNORE (DIRECT_IN | DIRECT_OUT | 4 )
  708. #define DIRECT_IN_OUT (DIRECT_IN | DIRECT_OUT)
  709. void
  710. node_param::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  711. {
  712. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  713. unsigned short Direction = DIRECT_NONE;
  714. char * pName = GetSymName();
  715. node_skl * pChild = GetChild();
  716. BOOL NoDirection = FALSE;
  717. MyContext.SetAncestorBits( IN_PARAM_LIST );
  718. MyContext.MarkImportantPosition();
  719. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  720. MyContext.ExtractAttribute(ATTR_IDLDESCATTR);
  721. if ( MyContext.ExtractAttribute(ATTR_FLCID) )
  722. {
  723. LCID();
  724. }
  725. CheckDeclspecAlign( MyContext );
  726. // check for illegal member attributes
  727. node_member_attr * pMA;
  728. while ( ( pMA = (node_member_attr *)MyContext.ExtractAttribute(ATTR_MEMBER) ) != 0 )
  729. {
  730. switch (pMA->GetAttr())
  731. {
  732. case MATTR_OPTIONAL:
  733. {
  734. node_skl * pBase = this;
  735. do {
  736. pBase = pBase->GetChild()->GetBasicType();
  737. } while (NODE_ARRAY == pBase->NodeKind() || NODE_POINTER == pBase->NodeKind());
  738. if ( !pBase->GetSymName() ||
  739. ( (0 != _stricmp(pBase->GetSymName(), "tagVARIANT") )
  740. && FNewTypeLib()
  741. && ( MyContext.AnyAncestorBits( HAS_OLEAUTOMATION )
  742. || MyContext.AnyAncestorBits( IN_DISPINTERFACE ) ) ) )
  743. {
  744. SemError(this, MyContext, INAPPLICABLE_OPTIONAL_ATTRIBUTE, pMA->GetNodeNameString());
  745. }
  746. if ( ! MyContext.AnyAncestorBits( IN_LIBRARY ) )
  747. {
  748. SemError(this, MyContext, OPTIONAL_OUTSIDE_LIBRARY, NULL);
  749. }
  750. Optional();
  751. break;
  752. }
  753. case MATTR_RETVAL:
  754. Retval();
  755. break;
  756. case MATTR_RESTRICTED:
  757. case MATTR_SOURCE:
  758. case MATTR_PROPGET:
  759. case MATTR_PROPPUT:
  760. case MATTR_PROPPUTREF:
  761. {
  762. char * pAttrName = pMA->GetNodeNameString();
  763. SemError( this, MyContext, NEWLYFOUND_INAPPLICABLE_ATTRIBUTE, pAttrName);
  764. break;
  765. }
  766. case MATTR_BINDABLE:
  767. case MATTR_DISPLAYBIND:
  768. case MATTR_DEFAULTBIND:
  769. case MATTR_REQUESTEDIT:
  770. case MATTR_VARARG:
  771. case MATTR_DEFAULTVTABLE:
  772. case MATTR_PREDECLID:
  773. case MATTR_UIDEFAULT:
  774. case MATTR_NONBROWSABLE:
  775. case MATTR_DEFAULTCOLLELEM:
  776. case MATTR_USESGETLASTERROR:
  777. case MATTR_IMMEDIATEBIND:
  778. break;
  779. case MATTR_REPLACEABLE:
  780. default:
  781. {
  782. char * pAttrName = pMA->GetNodeNameString();
  783. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, pAttrName);
  784. break;
  785. }
  786. }
  787. }
  788. node_constant_attr * pcaDefaultValue = (node_constant_attr *)MyContext.ExtractAttribute(ATTR_DEFAULTVALUE);
  789. if ( pcaDefaultValue )
  790. {
  791. // UNDONE: Check that this attribute has a legal default value
  792. // We already have an [optional] flag. MIDL should issue a warning
  793. // that we shouldn't have both.
  794. if ( IsOptional() )
  795. {
  796. SemError( this, MyContext, DEFAULTVALUE_WITH_OPTIONAL, 0);
  797. }
  798. pParentCtxt->SetDescendantBits( HAS_DEFAULT_VALUE );
  799. Optional();
  800. }
  801. if ( MyContext.ExtractAttribute(ATTR_IN) )
  802. {
  803. pParentCtxt->SetDescendantBits( HAS_IN );
  804. MyContext.SetAncestorBits( UNDER_IN_PARAM );
  805. Direction |= DIRECT_IN;
  806. }
  807. if ( MyContext.ExtractAttribute(ATTR_OUT) )
  808. {
  809. pParentCtxt->SetDescendantBits( HAS_OUT );
  810. MyContext.SetAncestorBits( UNDER_OUT_PARAM );
  811. Direction |= DIRECT_OUT;
  812. }
  813. if ( MyContext.ExtractAttribute( ATTR_PARTIAL_IGNORE ) )
  814. {
  815. pCommand->GetNdrVersionControl().SetHasPartialIgnore();
  816. pParentCtxt->SetDescendantBits( HAS_PARTIAL_IGNORE );
  817. MyContext.SetAncestorBits( UNDER_PARTIAL_IGNORE_PARAM );
  818. if ( !( Direction & DIRECT_IN ) || !( Direction & DIRECT_OUT ) )
  819. {
  820. SemError( this, MyContext, PARTIAL_IGNORE_IN_OUT, GetSymName() );
  821. }
  822. if ( FInSummary( ATTR_STRING )
  823. && ! ( FInSummary( ATTR_SIZE ) || FInSummary( ATTR_MAX) ) )
  824. {
  825. SemError( this, MyContext, UNSIZED_PARTIAL_IGNORE, GetSymName() );
  826. }
  827. Direction |= DIRECT_PARTIAL_IGNORE;
  828. }
  829. if ( IsExtraStatusParam() )
  830. MyContext.SetAncestorBits( UNDER_HIDDEN_STATUS );
  831. // [retval] parameter must be on an [out] parameter and it
  832. // must be the last parameter in the list
  833. if (IsRetval() && (Direction != DIRECT_OUT || GetSibling() != NULL))
  834. SemError(this, MyContext, INVALID_USE_OF_RETVAL, NULL );
  835. // if the parameter has no IN or OUT, it is an IN parameter by default.
  836. // if so, issue a warning message
  837. // REVIEW: No warning is being issued. What about hidden status params
  838. // which are neither in nor out?
  839. if ( (Direction == DIRECT_NONE) &&
  840. MyContext.AnyAncestorBits( IN_RPC ) )
  841. {
  842. NoDirection = TRUE;
  843. MyContext.SetAncestorBits( UNDER_IN_PARAM );
  844. Direction |= DIRECT_IN;
  845. }
  846. // warn about OUT const things
  847. if ( ( Direction & DIRECT_OUT ) &&
  848. FInSummary( ATTR_CONST ) )
  849. RpcSemError( this, MyContext, CONST_ON_OUT_PARAM, NULL );
  850. if ( MyContext.FInSummary(ATTR_HANDLE) )
  851. {
  852. HandleKind |= HDL_GEN;
  853. fAppliedHere = 1;
  854. }
  855. if ( MyContext.FInSummary(ATTR_CONTEXT) )
  856. {
  857. HandleKind |= HDL_CTXT;
  858. fAppliedHere = 1;
  859. }
  860. if (HandleKind != HDL_NONE)
  861. MyContext.SetDescendantBits( HAS_HANDLE | HAS_CONTEXT_HANDLE );
  862. // notice comm and fault statuses; the attributes are extracted by
  863. // the error_status_t
  864. if ( MyContext.FInSummary( ATTR_COMMSTAT ) )
  865. {
  866. Statuses |= STATUS_COMM;
  867. }
  868. if ( MyContext.FInSummary( ATTR_FAULTSTAT ) )
  869. {
  870. Statuses |= STATUS_FAULT;
  871. }
  872. acf_attr *pDRtag = (acf_attr *) MyContext.ExtractAttribute( ATTR_DRTAG );
  873. acf_attr *pStag = (acf_attr *) MyContext.ExtractAttribute( ATTR_STAG );
  874. acf_attr *pRtag = (acf_attr *) MyContext.ExtractAttribute( ATTR_RTAG );
  875. if ( pDRtag )
  876. {
  877. if ( !( Direction & DIRECT_IN ) )
  878. AcfError(pDRtag, this, MyContext, IN_TAG_WITHOUT_IN, NULL);
  879. SetHasCSDRTag();
  880. MyContext.SetDescendantBits( HAS_DRTAG );
  881. }
  882. if ( pStag )
  883. {
  884. if ( !( Direction & DIRECT_IN ) )
  885. AcfError(pStag, this, MyContext, IN_TAG_WITHOUT_IN, NULL);
  886. SetHasCSSTag();
  887. MyContext.SetDescendantBits( HAS_STAG );
  888. }
  889. if ( pRtag )
  890. {
  891. if ( !( Direction & DIRECT_OUT ) )
  892. AcfError(pRtag, this, MyContext, OUT_TAG_WITHOUT_OUT, NULL);
  893. SetHasCSRTag();
  894. MyContext.SetDescendantBits( HAS_RTAG );
  895. }
  896. acf_attr * pForceAllocate = (acf_attr *) MyContext.ExtractAttribute( ATTR_FORCEALLOCATE );
  897. if ( pForceAllocate )
  898. {
  899. // we allow force allocation on [in] and [in,out] parameters. server allocate
  900. if ( ! (Direction & DIRECT_IN ) )
  901. AcfError( pForceAllocate, this, MyContext, OUT_ONLY_FORCEALLOCATE, NULL );
  902. MyContext.SetDescendantBits ( HAS_FORCEALLOCATE );
  903. pCommand->GetNdrVersionControl().SetHasForceAllocate();
  904. }
  905. pChild->SemanticAnalysis( &MyContext );
  906. // OUT parameters should be pointers or arrays.
  907. // Don't use HAS_POINTER or arrays as it may come from a field.
  908. if ( ( Direction & DIRECT_PARTIAL_IGNORE ) == DIRECT_PARTIAL_IGNORE )
  909. {
  910. node_skl *pPointer = GetNonDefChild();
  911. if ( ( pPointer->NodeKind() != NODE_POINTER ) ||
  912. MyContext.AnyDescendantBits((DESCENDANT_FLAGS) HAS_PIPE) )
  913. {
  914. SemError( this, MyContext, PARTIAL_IGNORE_UNIQUE, NULL );
  915. }
  916. node_skl *pPointee = pPointer->GetNonDefChild();
  917. if ( pPointee->IsStructOrUnion() )
  918. if ( ((node_su_base *) pPointee)->HasConformance() )
  919. SemError( this, MyContext, UNSIZED_PARTIAL_IGNORE, NULL );
  920. }
  921. else if ( (Direction & DIRECT_OUT) && !(
  922. GetNonDefChild()->IsPtrOrArray()
  923. || MyContext.AnyDescendantBits((DESCENDANT_FLAGS) HAS_PIPE)))
  924. {
  925. SemError( this, MyContext, NON_PTR_OUT, NULL );
  926. }
  927. if ( pForceAllocate )
  928. {
  929. if ( MyContext.AnyDescendantBits((DESCENDANT_FLAGS) HAS_PIPE) )
  930. AcfError( pForceAllocate, this, MyContext, FORCEALLOCATE_ON_PIPE, NULL );
  931. }
  932. // if no direction was specified, and we are not just void or a hidden
  933. // status parameter, then error
  934. if ( NoDirection )
  935. {
  936. pParentCtxt->SetDescendantBits( HAS_IN );
  937. if ( !MyContext.AnyDescendantBits( DERIVES_FROM_VOID )
  938. && !IsExtraStatusParam() )
  939. {
  940. RpcSemError( this, MyContext, NO_EXPLICIT_IN_OUT_ON_PARAM, NULL );
  941. }
  942. }
  943. // disallow forward references as union members
  944. if ( MyContext.AnyDescendantBits( HAS_INCOMPLETE_TYPE ) )
  945. {
  946. if (! MyContext.AnyAncestorBits( IN_LIBRARY ))
  947. SemError( this, MyContext, UNDEFINED_SYMBOL, NULL );
  948. MyContext.ClearDescendantBits( HAS_INCOMPLETE_TYPE );
  949. }
  950. MyContext.ClearDescendantBits( HAS_RECURSIVE_DEF );
  951. // disallow module as params
  952. if ( GetBasicType()->NodeKind() == NODE_MODULE )
  953. {
  954. SemError( this, MyContext, DERIVES_FROM_COCLASS_OR_MODULE, 0);
  955. }
  956. else if (GetBasicType()->NodeKind() == NODE_POINTER)
  957. {
  958. if (GetBasicType()->GetChild()->NodeKind() == NODE_MODULE )
  959. {
  960. SemError( this, MyContext, DERIVES_FROM_COCLASS_OR_MODULE, 0);
  961. }
  962. }
  963. if ( GetBasicType()->NodeKind() == NODE_INTERFACE ||
  964. GetBasicType()->NodeKind() == NODE_DISPINTERFACE )
  965. {
  966. SemError( this, MyContext, INTF_NON_POINTER, 0);
  967. }
  968. // compound types may not be declared in param lists
  969. NODE_T ChildKind = pChild->NodeKind();
  970. if ( ( ChildKind == NODE_ENUM )
  971. || ( ChildKind == NODE_STRUCT )
  972. || ( ChildKind == NODE_UNION ) )
  973. {
  974. if ( IsDef() )
  975. SemError( this, MyContext, COMP_DEF_IN_PARAM_LIST, NULL );
  976. }
  977. // things not allowed in an RPC
  978. if ( MyContext.AnyAncestorBits( IN_RPC | IN_LIBRARY ) )
  979. {
  980. if ( strcmp( pName, "..." ) == 0 )
  981. SemError( this, MyContext, PARAM_IS_ELIPSIS, NULL );
  982. if ( IsTempName( pName ) )
  983. RpcSemError( this, MyContext, ABSTRACT_DECL, NULL );
  984. }
  985. if ( ( HandleKind != HDL_NONE ) &&
  986. ( Direction & DIRECT_IN ) )
  987. fBindingParam = TRUE;
  988. if ( ( HandleKind == HDL_CTXT ) &&
  989. MyContext.AnyDescendantBits( HAS_TRANSMIT_AS ) )
  990. RpcSemError( this, MyContext, CTXT_HDL_TRANSMIT_AS, NULL );
  991. if ( MyContext.AnyAncestorBits( HAS_OLEAUTOMATION ) || MyContext.AnyAncestorBits( IN_DISPINTERFACE ) )
  992. {
  993. // check the child type instead of NODE_PARAM directly. nt bug #371499
  994. if ( !IsOLEAutomationCompliant( GetBasicType() ) )
  995. {
  996. SemError(this, MyContext, NOT_OLEAUTOMATION_INTERFACE, NULL);
  997. }
  998. }
  999. // don't allow functions as params
  1000. if ( MyContext.AnyDescendantBits( HAS_FUNC ) &&
  1001. MyContext.AllAncestorBits( IN_INTERFACE | IN_RPC ) )
  1002. RpcSemError( this, MyContext, BAD_CON_PARAM_FUNC, NULL );
  1003. if (MyContext.ExtractAttribute(ATTR_HELPSTRINGDLL))
  1004. {
  1005. SemError(this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  1006. }
  1007. if ( HasCorrelation( this ) )
  1008. {
  1009. MyContext.IncCorrelationCount();
  1010. }
  1011. if ( ( Direction & DIRECT_OUT ) && MyContext.GetCorrelationCount() )
  1012. {
  1013. MyContext.SetDescendantBits( HAS_CLIENT_CORRELATION );
  1014. }
  1015. if ( ( Direction & DIRECT_IN ) && MyContext.GetCorrelationCount() )
  1016. {
  1017. MyContext.SetDescendantBits( HAS_SERVER_CORRELATION );
  1018. }
  1019. if ( MyContext.AnyAncestorBits( HAS_ASYNCHANDLE ) &&
  1020. MyContext.AnyDescendantBits( (DESCENDANT_FLAGS) HAS_PIPE ) &&
  1021. pChild->GetNonDefSelf()->NodeKind() != NODE_POINTER )
  1022. {
  1023. SemError(this, MyContext, ASYNC_PIPE_BY_REF, GetSymName() );
  1024. }
  1025. // This is completely banned with the new transfer syntax.
  1026. if ( pCommand->NeedsNDR64Run() )
  1027. {
  1028. if ( MyContext.AnyDescendantBits( HAS_UNSAT_REP_AS ) )
  1029. {
  1030. RpcSemError( this, MyContext, UNSPECIFIED_EMBEDDED_REPRESENT_AS_NOT_SUPPORTED, NULL );
  1031. }
  1032. }
  1033. pParentCtxt->ReturnValues( MyContext );
  1034. }
  1035. void
  1036. node_file::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  1037. {
  1038. MEM_ITER MemIter( this );
  1039. node_skl * pN;
  1040. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  1041. if ( ImportLevel == 0 )
  1042. {
  1043. MyContext.SetAncestorBits( IN_INTERFACE );
  1044. }
  1045. #ifdef ReducedImportSemAnalysis
  1046. else
  1047. return;
  1048. #endif
  1049. while ( ( pN = MemIter.GetNext() ) != 0 )
  1050. {
  1051. // each interface node gets a fresh context
  1052. MyContext.SetInterfaceContext( &MyContext );
  1053. // allow echo string and midl_grama outside library block,
  1054. // even in mktyplib compatible mode
  1055. if ( ( 0 == ImportLevel )
  1056. && ( NODE_LIBRARY != pN->NodeKind() )
  1057. && ( NODE_ECHO_STRING != pN->NodeKind() )
  1058. && ( NODE_MIDL_PRAGMA != pN->NodeKind() )
  1059. && ( pCommand->IsSwitchDefined(SWITCH_MKTYPLIB ) ) )
  1060. {
  1061. SEM_ANALYSIS_CTXT DummyContext( pN, &MyContext );
  1062. SemError(pN, DummyContext, ILLEGAL_IN_MKTYPLIB_MODE, NULL);
  1063. }
  1064. pN->SemanticAnalysis( &MyContext );
  1065. };
  1066. pParentCtxt->ReturnValues( MyContext );
  1067. };
  1068. // for fault_status and comm_status
  1069. #define NOT_SEEN 0
  1070. #define SEEN_ON_RETURN 1
  1071. #define SEEN_ON_PARAM 2
  1072. void
  1073. node_proc::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  1074. {
  1075. node_param* pN;
  1076. node_optimize* pOptAttr;
  1077. acf_attr* pAttr;
  1078. ATTR_T CallingConv;
  1079. MEM_ITER MemIter( this );
  1080. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  1081. SEM_ANALYSIS_CTXT* pIntfCtxt = (SEM_ANALYSIS_CTXT *) MyContext.GetInterfaceContext();
  1082. node_interface* pIntf = (node_interface *) pIntfCtxt->GetParent();
  1083. node_entry_attr* pEntry = NULL;
  1084. node_base_attr* pAttrAsync = MyContext.ExtractAttribute( ATTR_ASYNC );
  1085. unsigned short Faultstat = NOT_SEEN;
  1086. unsigned short Commstat = NOT_SEEN;
  1087. unsigned short OpBits = MyContext.GetOperationBits();
  1088. BOOL fNoCode = FALSE;
  1089. BOOL fCode = FALSE;
  1090. BOOL Skipme = FALSE;
  1091. BOOL fNonOperation = FALSE;
  1092. BOOL fEncode = (NULL != MyContext.ExtractAttribute( ATTR_ENCODE ));
  1093. BOOL fDecode = (NULL != MyContext.ExtractAttribute( ATTR_DECODE ));
  1094. // Use bitwise or because otherwise the C/C++ compiler will incorrectly
  1095. // short-circuit the call to ExtractAttribute(ATTR_DECODE).
  1096. BOOL HasPickle = fEncode | fDecode;
  1097. BOOL fExpHdlAttr = FALSE;
  1098. BOOL fMaybe = OpBits & OPERATION_MAYBE;
  1099. BOOL fMessage = OpBits & OPERATION_MESSAGE;
  1100. BOOL fBindingFound = FALSE;
  1101. BOOL fProcIsCallback= (NULL != MyContext.ExtractAttribute( ATTR_CALLBACK ));
  1102. BOOL fLocal = (NULL != MyContext.ExtractAttribute( ATTR_LOCAL ));
  1103. BOOL fNotify = (NULL != MyContext.ExtractAttribute( ATTR_NOTIFY ));
  1104. BOOL fNotifyFlag = (NULL != MyContext.ExtractAttribute( ATTR_NOTIFY_FLAG ));
  1105. node_skl* pRet = GetReturnType();
  1106. NODE_T BasicChildKind = pRet->GetBasicType()->NodeKind();
  1107. node_call_as* pCallAs = (node_call_as *) MyContext.ExtractAttribute( ATTR_CALL_AS );
  1108. acf_attr* pEnableAllocate = (acf_attr *) MyContext.ExtractAttribute( ATTR_ENABLE_ALLOCATE );
  1109. node_constant_attr* pID = (node_constant_attr *) MyContext.ExtractAttribute(ATTR_ID);
  1110. node_constant_attr* pHC = (node_constant_attr *) MyContext.ExtractAttribute(ATTR_HELPCONTEXT);
  1111. node_constant_attr* pHSC = (node_constant_attr *) MyContext.ExtractAttribute(ATTR_HELPSTRINGCONTEXT);
  1112. node_text_attr* pHelpStr = (node_text_attr *) MyContext.ExtractAttribute(ATTR_HELPSTRING);
  1113. bool fAddExplicitHandle = false;
  1114. long nAfterLastOptionalParam = 0;
  1115. node_cs_tag_rtn * pCSTagAttr = (node_cs_tag_rtn *) MyContext.ExtractAttribute( ATTR_CSTAGRTN );
  1116. if (MyContext.ExtractAttribute(ATTR_HELPSTRINGDLL))
  1117. {
  1118. SemError(this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  1119. }
  1120. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  1121. MyContext.ExtractAttribute(ATTR_FUNCDESCATTR);
  1122. MyContext.ExtractAttribute( ATTR_HIDDEN );
  1123. fHasDeny = pCommand->IsSwitchDefined( SWITCH_ROBUST );
  1124. if (MyContext.AnyAncestorBits( IN_MODULE ))
  1125. {
  1126. pEntry = (node_entry_attr *) MyContext.ExtractAttribute( ATTR_ENTRY );
  1127. if (pEntry)
  1128. {
  1129. if (pEntry->IsNumeric())
  1130. {
  1131. char * szEntry = (char *)pEntry->GetID();
  1132. if ( ((LONG_PTR) szEntry) > 0xFFFF )
  1133. {
  1134. SemError( this, MyContext, BAD_ENTRY_VALUE, NULL);
  1135. }
  1136. }
  1137. else
  1138. {
  1139. char * szEntry = pEntry->GetSz();
  1140. if ( ((LONG_PTR) szEntry) <= 0xFFFF )
  1141. {
  1142. SemError( this, MyContext, BAD_ENTRY_VALUE, NULL);
  1143. }
  1144. }
  1145. }
  1146. else
  1147. {
  1148. SemError(this, MyContext, BAD_ENTRY_VALUE, NULL);
  1149. }
  1150. }
  1151. bool fBindable = false;
  1152. bool fPropSomething = false;
  1153. bool fPropGet = false;
  1154. int nchSkip = 0;
  1155. bool fHasVarArg = false;
  1156. // check for illegal member attributes
  1157. node_member_attr * pMA;
  1158. while ( ( pMA = (node_member_attr *)MyContext.ExtractAttribute(ATTR_MEMBER) ) != 0 )
  1159. {
  1160. switch (pMA->GetAttr())
  1161. {
  1162. case MATTR_BINDABLE:
  1163. fBindable = TRUE;
  1164. break;
  1165. case MATTR_PROPGET:
  1166. nchSkip = 4;
  1167. fPropSomething = TRUE;
  1168. fPropGet = TRUE;
  1169. break;
  1170. case MATTR_PROPPUT:
  1171. nchSkip = 4;
  1172. fPropSomething = TRUE;
  1173. break;
  1174. case MATTR_PROPPUTREF:
  1175. nchSkip = 7;
  1176. fPropSomething = TRUE;
  1177. break;
  1178. case MATTR_VARARG:
  1179. fHasVarArg = true;
  1180. break;
  1181. case MATTR_RESTRICTED:
  1182. case MATTR_SOURCE:
  1183. if ( MyContext.AnyAncestorBits( IN_MODULE ))
  1184. {
  1185. char * pAttrName = pMA->GetNodeNameString();
  1186. SemError( this, MyContext, NEWLYFOUND_INAPPLICABLE_ATTRIBUTE, pAttrName);
  1187. break;
  1188. }
  1189. case MATTR_DISPLAYBIND:
  1190. case MATTR_DEFAULTBIND:
  1191. case MATTR_REQUESTEDIT:
  1192. case MATTR_UIDEFAULT:
  1193. case MATTR_NONBROWSABLE:
  1194. case MATTR_DEFAULTCOLLELEM:
  1195. case MATTR_DEFAULTVTABLE:
  1196. case MATTR_IMMEDIATEBIND:
  1197. case MATTR_REPLACEABLE:
  1198. break;
  1199. case MATTR_READONLY:
  1200. case MATTR_USESGETLASTERROR:
  1201. {
  1202. char * pAttrName = pMA->GetNodeNameString();
  1203. SemError( this, MyContext, NEWLYFOUND_INAPPLICABLE_ATTRIBUTE, pAttrName);
  1204. break;
  1205. }
  1206. case MATTR_RETVAL:
  1207. case MATTR_OPTIONAL:
  1208. case MATTR_PREDECLID:
  1209. {
  1210. char * pAttrName = pMA->GetNodeNameString();
  1211. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, pAttrName);
  1212. break;
  1213. }
  1214. }
  1215. }
  1216. if (pID)
  1217. {
  1218. if (!pIntf->AddId(pID->GetExpr()->GetValue(),GetSymName() + nchSkip))
  1219. SemError( this, MyContext, DUPLICATE_IID, NULL);
  1220. }
  1221. if (fBindable && !fPropSomething)
  1222. SemError(this, MyContext, INVALID_USE_OF_BINDABLE, NULL);
  1223. if ( pEnableAllocate )
  1224. pIntf->SetHasProcsWithRpcSs();
  1225. fNonOperation = !pParentCtxt->GetParent()->IsInterfaceOrObject();
  1226. if ( !GetCallingConvention( CallingConv ) )
  1227. SemError( this, MyContext, MULTIPLE_CALLING_CONVENTIONS, NULL );
  1228. // locally applied [code] attribute overrides global [nocode] attribute
  1229. fNoCode = (NULL != MyContext.ExtractAttribute( ATTR_NOCODE ));
  1230. fCode = (NULL != MyContext.ExtractAttribute( ATTR_CODE ));
  1231. if ( fCode && fNoCode )
  1232. {
  1233. SemError( this, MyContext, CODE_NOCODE_CONFLICT, NULL );
  1234. }
  1235. fNoCode = fNoCode || pIntfCtxt->FInSummary( ATTR_NOCODE );
  1236. fNoCode = !fCode && fNoCode;
  1237. if ( fNoCode && pCommand->GenerateSStub() )
  1238. RpcSemError( this, MyContext, NOCODE_WITH_SERVER_STUBS, NULL );
  1239. // do my attribute parsing...
  1240. fObjectProc = MyContext.ExtractAttribute( ATTR_OBJECT ) || pIntfCtxt->FInSummary( ATTR_OBJECT );
  1241. SetObjectProc( fObjectProc );
  1242. if ( fObjectProc )
  1243. {
  1244. if ( pCommand->GetEnv() != ENV_WIN32 &&
  1245. pCommand->GetEnv() != ENV_WIN64 &&
  1246. !pCommand->IsSwitchDefined(SWITCH_MKTYPLIB))
  1247. {
  1248. // REVIEW: We can eliminate the warning if object procs can be
  1249. // in win64. It was necessary for dos, mac, etc.
  1250. SemError( this, MyContext, OBJECT_PROC_MUST_BE_WIN32, NULL );
  1251. }
  1252. if ( pEnableAllocate )
  1253. {
  1254. AcfError( pEnableAllocate, this, MyContext, INAPPROPRIATE_ON_OBJECT_PROC, NULL );
  1255. }
  1256. if ( HasPickle )
  1257. {
  1258. SemError( this, MyContext, PICKLING_INVALID_IN_OBJECT, NULL );
  1259. }
  1260. }
  1261. bool fAsync = ( MyContext.AnyAncestorBits( HAS_ASYNCHANDLE ) != 0 ) || ( pAttrAsync != 0 );
  1262. if ( fAsync )
  1263. {
  1264. MyContext.SetAncestorBits( HAS_ASYNCHANDLE );
  1265. // because we don't support async retry now, we need to issue an
  1266. // explicit warning about this.
  1267. if ( pCommand->NeedsNDR64Run() && !pCommand->NeedsNDRRun() )
  1268. SemError( this, MyContext, ASYNC_NDR64_ONLY, 0 );
  1269. }
  1270. // check return types for non object proc.s with maybe, message
  1271. // object proc.s should have HRESULT. This is checked later.
  1272. if ( ( fMessage || fMaybe ) && !fObjectProc )
  1273. {
  1274. if ( BasicChildKind != NODE_VOID )
  1275. {
  1276. if ( BasicChildKind != NODE_E_STATUS_T )
  1277. {
  1278. SemError( this, MyContext, MAYBE_NO_OUT_RETVALS, NULL );
  1279. }
  1280. else
  1281. {
  1282. unsigned long ulCommStat = (unsigned long) ( MyContext.FInSummary(ATTR_COMMSTAT) ? 1 : 0 ),
  1283. ulFaultStat = (unsigned long) ( MyContext.FInSummary(ATTR_FAULTSTAT) ? 1 : 0);
  1284. if ( ulCommStat ^ ulFaultStat )
  1285. {
  1286. SemError( this, MyContext, ASYNC_INCORRECT_ERROR_STATUS_T, 0 );
  1287. }
  1288. }
  1289. }
  1290. }
  1291. // check call_as characteristics
  1292. if ( pCallAs )
  1293. {
  1294. node_proc* pCallType = pCallAs->GetCallAsType();
  1295. // if we don't have it yet, search for the call_as target
  1296. if ( !pCallType )
  1297. {
  1298. // search the proc table for the particular proc
  1299. SymKey SKey( pCallAs->GetCallAsName(), NAME_PROC );
  1300. pCallType = ( node_proc* ) pIntf->GetProcTbl()->SymSearch( SKey );
  1301. if ( !pCallType )
  1302. {
  1303. if ( pIntfCtxt->FInSummary( ATTR_OBJECT ) )
  1304. AcfError( pCallAs,
  1305. this,
  1306. MyContext,
  1307. CALL_AS_UNSPEC_IN_OBJECT,
  1308. pCallAs->GetCallAsName() );
  1309. }
  1310. else
  1311. {
  1312. pCallAs->SetCallAsType(pCallType);
  1313. }
  1314. }
  1315. // now we should have the call_as type
  1316. if ( pCallType ) // found the call_as proc
  1317. {
  1318. ((node_proc *)pCallType)->fCallAsTarget = TRUE;
  1319. if ( ( pCallType->NodeKind() != NODE_PROC ) ||
  1320. !pCallType->FInSummary( ATTR_LOCAL ) )
  1321. AcfError( pCallAs,
  1322. this,
  1323. MyContext,
  1324. CALL_AS_NON_LOCAL_PROC,
  1325. pCallType->GetSymName() );
  1326. // insert pCallType into pCallAsTable
  1327. if ( pCallAsTable->IsRegistered( pCallType ) )
  1328. // error
  1329. AcfError( pCallAs,
  1330. this,
  1331. MyContext,
  1332. CALL_AS_USED_MULTIPLE_TIMES,
  1333. pCallType->GetSymName() );
  1334. else
  1335. pCallAsTable->Register( pCallType );
  1336. }
  1337. SetCallAsType( pCallType );
  1338. }
  1339. // local procs don't add to count
  1340. Skipme = fLocal;
  1341. if ( Skipme )
  1342. {
  1343. SemError( this, MyContext, LOCAL_ATTR_ON_PROC, NULL );
  1344. }
  1345. Skipme = Skipme || pIntfCtxt->FInSummary( ATTR_LOCAL );
  1346. if ( Skipme )
  1347. {
  1348. MyContext.SetAncestorBits( IN_LOCAL_PROC );
  1349. }
  1350. // do my attribute parsing...
  1351. // check for the [explicit_handle] attribute
  1352. fExpHdlAttr = (NULL != MyContext.ExtractAttribute( ATTR_EXPLICIT ));
  1353. fExpHdlAttr = fExpHdlAttr || pIntfCtxt->FInSummary( ATTR_EXPLICIT );
  1354. // we are in an RPC if we are in the main interface, its not local, and
  1355. // we are not a typedef of a proc...
  1356. if (
  1357. (ImportLevel == 0) &&
  1358. !MyContext.FindAncestorContext( NODE_DEF ) &&
  1359. pIntf &&
  1360. !Skipme
  1361. )
  1362. {
  1363. MyContext.SetAncestorBits( IN_RPC );
  1364. }
  1365. else
  1366. {
  1367. MyContext.ClearAncestorBits( IN_RPC );
  1368. }
  1369. // our optimization is controlled either locally or for the whole interface
  1370. if ( ( pOptAttr = (node_optimize *) MyContext.ExtractAttribute( ATTR_OPTIMIZE ) ) != 0 )
  1371. {
  1372. SetOptimizationFlags( pOptAttr->GetOptimizationFlags() );
  1373. SetOptimizationLevel( pOptAttr->GetOptimizationLevel() );
  1374. }
  1375. else
  1376. {
  1377. SetOptimizationFlags( pIntf->GetOptimizationFlags() );
  1378. SetOptimizationLevel( pIntf->GetOptimizationLevel() );
  1379. }
  1380. unsigned long fOptimize = GetOptimizationFlags();
  1381. if ( fOptimize & OPTIMIZE_INTERPRETER )
  1382. {
  1383. MyContext.SetAncestorBits( IN_INTERPRET );
  1384. }
  1385. HasPickle = HasPickle || pIntfCtxt->FInSummary( ATTR_ENCODE )
  1386. || pIntfCtxt->FInSummary( ATTR_DECODE );
  1387. if ( HasPickle && pCommand->IsSwitchDefined( SWITCH_ROBUST ) )
  1388. {
  1389. if ( fOptimize & OPTIMIZE_INTERPRETER_V2 )
  1390. {
  1391. pCommand->GetNdrVersionControl().SetHasOicfPickling();
  1392. }
  1393. else
  1394. {
  1395. SemError( this, MyContext, ROBUST_PICKLING_NO_OICF, 0 );
  1396. }
  1397. }
  1398. BOOL HasCommFault = MyContext.FInSummary( ATTR_COMMSTAT )
  1399. || MyContext.FInSummary( ATTR_FAULTSTAT );
  1400. if ( HasPickle && HasCommFault )
  1401. {
  1402. if ( ! ( fOptimize & OPTIMIZE_INTERPRETER_V2 ) )
  1403. {
  1404. SemError( this, MyContext, COMMFAULT_PICKLING_NO_OICF, 0 );
  1405. }
  1406. }
  1407. // determine the proc number (local procs don't get a number)
  1408. if ( !fNonOperation )
  1409. {
  1410. if ( !fLocal )
  1411. {
  1412. if ( fProcIsCallback )
  1413. {
  1414. ProcNum = ( pIntf ->GetCallBackProcCount() )++;
  1415. RpcSemError( this, MyContext, CALLBACK_NOT_OSF, NULL );
  1416. }
  1417. else
  1418. {
  1419. ProcNum = ( pIntf ->GetProcCount() )++;
  1420. }
  1421. }
  1422. // object procs need the procnum set for local procs, too
  1423. else if ( fObjectProc && fLocal )
  1424. {
  1425. ProcNum = ( pIntf ->GetProcCount() )++;
  1426. }
  1427. }
  1428. else if ( MyContext.AnyAncestorBits( IN_RPC ) )
  1429. {
  1430. RpcSemError( this, MyContext, FUNC_NON_RPC, NULL );
  1431. }
  1432. else // proc not an operation, validate its usage
  1433. {
  1434. SEM_ANALYSIS_CTXT * pAbove = (SEM_ANALYSIS_CTXT *)
  1435. MyContext.FindNonDefAncestorContext();
  1436. node_skl * pAboveNode = pAbove->GetParent();
  1437. if ( !pAboveNode->IsInterfaceOrObject() )
  1438. {
  1439. if ( pAboveNode->NodeKind() != NODE_POINTER )
  1440. {
  1441. TypeSemError( this, MyContext, FUNC_NON_POINTER, NULL );
  1442. }
  1443. }
  1444. }
  1445. if ( MyContext.FInSummary( ATTR_COMMSTAT ) )
  1446. Commstat = SEEN_ON_RETURN;
  1447. if ( MyContext.FInSummary( ATTR_FAULTSTAT ) )
  1448. Faultstat = SEEN_ON_RETURN;
  1449. //////////////////////////////////////
  1450. // process the return type (it will eat commstat or faultstat)
  1451. MyContext.SetAncestorBits( IN_FUNCTION_RESULT );
  1452. MyContext.MarkImportantPosition();
  1453. // warn about OUT const things
  1454. if ( FInSummary( ATTR_CONST ) )
  1455. RpcSemError( this, MyContext, CONST_ON_RETVAL, NULL );
  1456. pRet->SemanticAnalysis( &MyContext );
  1457. MyContext.UnMarkImportantPosition();
  1458. if ( MyContext.AnyDescendantBits( HAS_UNION | HAS_STRUCT )
  1459. && !pCommand->GetNdrVersionControl().AllowIntrepretedComplexReturns() )
  1460. {
  1461. // REVIEW: complex return types work for protocol all and ndr64.
  1462. // make it work for dce also.
  1463. if (HasPickle)
  1464. {
  1465. if (pCommand->Is64BitEnv())
  1466. RpcSemError( this, MyContext, PICKLING_RETVAL_TO_COMPLEX64, NULL );
  1467. }
  1468. else if (ForceNonInterpret())
  1469. {
  1470. RpcSemError( this, MyContext, NON_OI_BIG_RETURN, NULL );
  1471. }
  1472. }
  1473. else if ( MyContext.AnyDescendantBits( HAS_TOO_BIG_HDL ) )
  1474. {
  1475. if (ForceNonInterpret())
  1476. RpcSemError( this, MyContext, NON_OI_BIG_GEN_HDL, NULL );
  1477. }
  1478. else if ( !pCommand->NeedsNDR64Run()
  1479. && MyContext.AnyDescendantBits( HAS_UNSAT_REP_AS ))
  1480. {
  1481. // REVIEW: Another case of an error that has already been caught
  1482. // elsewhere. Investigate removing this check.
  1483. if (ForceNonInterpret())
  1484. RpcSemError( this, MyContext, NON_OI_UNK_REP_AS, NULL );
  1485. }
  1486. else if ( !pCommand->NeedsNDR64Run() &&
  1487. ( MyContext.AnyDescendantBits( HAS_REPRESENT_AS
  1488. | HAS_TRANSMIT_AS ) &&
  1489. MyContext.AnyDescendantBits( HAS_ARRAY ) ) )
  1490. {
  1491. if (ForceNonInterpret())
  1492. RpcSemError( this, MyContext, NON_OI_XXX_AS_ON_RETURN, NULL );
  1493. }
  1494. else if ( ( BasicChildKind == NODE_INT128 ) ||
  1495. ( BasicChildKind == NODE_FLOAT80 ) ||
  1496. ( BasicChildKind == NODE_FLOAT128 ) )
  1497. {
  1498. if (ForceNonInterpret())
  1499. RpcSemError( this, MyContext, RETURNVAL_TOO_COMPLEX_FORCE_OS, NULL );
  1500. }
  1501. else if ( !pCommand->GetNdrVersionControl().AllowIntrepretedComplexReturns() &&
  1502. ( ( ( BasicChildKind == NODE_HYPER ) && !pCommand->Is64BitEnv() )
  1503. || ( BasicChildKind == NODE_FLOAT )
  1504. || ( BasicChildKind == NODE_DOUBLE ) ) )
  1505. {
  1506. if ( HasPickle )
  1507. {
  1508. if ( fOptimize & OPTIMIZE_INTERPRETER_V2 )
  1509. {
  1510. if ( pCommand->Is64BitEnv() )
  1511. {
  1512. RpcSemError( this, MyContext, PICKLING_RETVAL_TO_COMPLEX64, NULL );
  1513. }
  1514. else if (ForceNonInterpret())
  1515. {
  1516. // For pickling -Os is the same as -Oi
  1517. RpcSemError( this, MyContext, PICKLING_RETVAL_FORCING_OI, NULL );
  1518. }
  1519. }
  1520. }
  1521. else if ( ( fOptimize & OPTIMIZE_INTERPRETER_V2) )
  1522. {
  1523. if ( fObjectProc )
  1524. {
  1525. // Don't switch, generate NT 4.0 guard
  1526. pCommand->GetNdrVersionControl().SetHasFloatOrDoubleInOi();
  1527. }
  1528. else
  1529. if (ForceNonInterpret())
  1530. RpcSemError( this, MyContext, NON_OI_RETVAL_64BIT, NULL );
  1531. }
  1532. else if ( ( fOptimize & OPTIMIZE_ALL_I1_FLAGS ) )
  1533. {
  1534. if (ForceNonInterpret())
  1535. RpcSemError( this, MyContext, NON_OI_RETVAL_64BIT, NULL );
  1536. }
  1537. }
  1538. else if ( ( CallingConv != ATTR_NONE ) &&
  1539. ( CallingConv != ATTR_STDCALL ) &&
  1540. ( CallingConv != ATTR_CDECL ) &&
  1541. !Skipme )
  1542. {
  1543. if (ForceNonInterpret())
  1544. RpcSemError( this, MyContext, NON_OI_WRONG_CALL_CONV, NULL );
  1545. }
  1546. if ( fProcIsCallback )
  1547. {
  1548. if ( MyContext.AnyDescendantBits( HAS_HANDLE) )
  1549. RpcSemError( this, MyContext, HANDLES_WITH_CALLBACK, NULL );
  1550. if ( fObjectProc )
  1551. RpcSemError( this, MyContext, INVALID_ON_OBJECT_PROC, "[callback]" );
  1552. }
  1553. if ( MyContext.AnyDescendantBits( HAS_FULL_PTR ) )
  1554. fHasFullPointer = TRUE;
  1555. // all object methods must return HRESULT (except those of IUnknown and async methods)
  1556. if ( fObjectProc &&
  1557. !Skipme &&
  1558. !MyContext.AnyDescendantBits( HAS_HRESULT ) )
  1559. {
  1560. if ( !MyContext.AnyAncestorBits( IN_ROOT_CLASS ) && // not IUnknown
  1561. !fAsync ) // not [async]
  1562. {
  1563. RpcSemError( this, MyContext, OBJECT_PROC_NON_HRESULT_RETURN, NULL );
  1564. }
  1565. }
  1566. //////////////////////////////////////
  1567. // process the parameters
  1568. if ( !pIntf->IsAsyncClone() )
  1569. {
  1570. if ( MyContext.AnyAncestorBits( HAS_ASYNC_UUID ) )
  1571. {
  1572. node_skl* pParam = GetInOnlyParamPairedWithOut( MemIter );
  1573. if ( pParam )
  1574. {
  1575. SemError( this, MyContext, ASYNC_INVALID_IN_OUT_PARAM_COMBO, pParam->GetSymName() );
  1576. }
  1577. }
  1578. }
  1579. BOOL fParentIsAnyIAdviseSink = MyContext.AnyAncestorBits( IN_IADVISESINK );
  1580. BOOL fHasAsyncManager = FALSE;
  1581. MyContext.ClearAncestorBits( IN_FUNCTION_RESULT );
  1582. MyContext.SetAncestorBits( IN_PARAM_LIST );
  1583. BOOL fLastParamWasOptional = FALSE;
  1584. BOOL fHasPipeParam = FALSE;
  1585. BOOL fHasConfOrVaryingParam = FALSE;
  1586. BOOL fGenDefaultValueExpr = FALSE;
  1587. BOOL fHasDRtag = FALSE;
  1588. BOOL fHasRtag = FALSE;
  1589. BOOL fHasStag = FALSE;
  1590. BOOL fHasInCSType = FALSE;
  1591. BOOL fHasOutCSType = FALSE;
  1592. node_param* pFirstParamWithDefValue = 0;
  1593. node_param* pLastParam = 0;
  1594. node_param* p2LastParam = 0;
  1595. node_param* p3LastParam = 0;
  1596. bool fRetval = false;
  1597. bool fLCID = false;
  1598. unsigned long ulParamNumber = 0;
  1599. MemIter.Init();
  1600. while ( ( pN = (node_param *) MemIter.GetNext() ) != 0 )
  1601. {
  1602. fOptimize = GetOptimizationFlags();
  1603. BasicChildKind = pN->GetBasicType()->NodeKind();
  1604. p3LastParam = p2LastParam;
  1605. p2LastParam = pLastParam;
  1606. pLastParam = pN;
  1607. MyContext.ClearAllDescendantBits();
  1608. MyContext.ResetCorrelationCount();
  1609. pN->SemanticAnalysis( &MyContext );
  1610. fRetval = fRetval || pN->IsRetval();
  1611. if ( pN->IsLCID() )
  1612. {
  1613. if (BasicChildKind != NODE_LONG)
  1614. {
  1615. SemError( this, MyContext, LCID_SHOULD_BE_LONG, 0 );
  1616. }
  1617. if (fLCID)
  1618. {
  1619. SemError( this, MyContext, INVALID_USE_OF_LCID, 0 );
  1620. }
  1621. else
  1622. fLCID = true;
  1623. }
  1624. if ( MyContext.AnyDescendantBits( HAS_MULTIDIM_VECTOR ) )
  1625. {
  1626. if ( ForceInterpret2() )
  1627. {
  1628. RpcSemError( this, MyContext, MULTI_DIM_VECTOR, NULL );
  1629. }
  1630. }
  1631. if ( MyContext.AnyDescendantBits( HAS_PARTIAL_IGNORE ) )
  1632. {
  1633. if ( (fOptimize & OPTIMIZE_INTERPRETER ) )
  1634. {
  1635. if ( ForceInterpret2() )
  1636. {
  1637. RpcSemError( this, MyContext, PARTIAL_IGNORE_NO_OI, NULL );
  1638. }
  1639. }
  1640. if ( MyContext.AnyAncestorBits( IN_LIBRARY ) )
  1641. {
  1642. SemError( this, MyContext, PARTIAL_IGNORE_IN_TLB, NULL );
  1643. }
  1644. if ( pCommand->IsSwitchDefined( SWITCH_OSF ) )
  1645. {
  1646. SemError( this, MyContext, INVALID_OSF_ATTRIBUTE, "[partial_ignore]" );
  1647. }
  1648. }
  1649. if ( MyContext.AnyDescendantBits( HAS_SERVER_CORRELATION ) )
  1650. {
  1651. SetHasServerCorr();
  1652. IncServerCorrelationCount( MyContext.GetCorrelationCount() );
  1653. }
  1654. if ( MyContext.AnyDescendantBits( HAS_CLIENT_CORRELATION ) )
  1655. {
  1656. SetHasClientCorr();
  1657. IncClientCorrelationCount( MyContext.GetCorrelationCount() );
  1658. }
  1659. BOOL fDefaultValue = MyContext.AnyDescendantBits( HAS_DEFAULT_VALUE );
  1660. if ( fDefaultValue )
  1661. {
  1662. if ( !pFirstParamWithDefValue )
  1663. {
  1664. pFirstParamWithDefValue = pN;
  1665. fGenDefaultValueExpr = TRUE;
  1666. }
  1667. // can't have defaultvalue in vararg
  1668. if ( fHasVarArg )
  1669. SemError(this, MyContext, NOT_VARARG_COMPATIBLE, 0);
  1670. }
  1671. else
  1672. {
  1673. // don't generate defaultvalue is c++ header if we have
  1674. // non-defaultvalue parameter after it.
  1675. fGenDefaultValueExpr = FALSE;
  1676. pFirstParamWithDefValue = 0;
  1677. }
  1678. if ( MyContext.AnyDescendantBits( HAS_PIPE ) )
  1679. {
  1680. fHasPipeParam = TRUE;
  1681. node_skl* pBasicType = pN->GetBasicType();
  1682. while ( pBasicType && pBasicType->NodeKind() == NODE_POINTER )
  1683. {
  1684. pBasicType = pBasicType->GetChild();
  1685. }
  1686. if ( ( pBasicType->NodeKind() == NODE_INTERFACE_REFERENCE && !fObjectProc ) ||
  1687. ( pBasicType->NodeKind() == NODE_PIPE && fObjectProc ) )
  1688. {
  1689. SemError(this, MyContext, UNIMPLEMENTED_FEATURE, pN->GetSymName() );
  1690. }
  1691. }
  1692. else if ( MyContext.AnyDescendantBits (
  1693. HAS_STRING |
  1694. HAS_FULL_PTR |
  1695. HAS_VAR_ARRAY |
  1696. HAS_CONF_ARRAY |
  1697. HAS_CONF_VAR_ARRAY
  1698. ) )
  1699. {
  1700. fHasConfOrVaryingParam = TRUE;
  1701. }
  1702. if ( ulParamNumber == 0 ) // first parameter
  1703. {
  1704. // if parent interface is is any IAdviseSink ignore [async].
  1705. if ( fAsync && fObjectProc )
  1706. {
  1707. unsigned int nIndirection = 0;
  1708. node_skl* pFType = GetIndirectionLevel (
  1709. pN,
  1710. nIndirection
  1711. );
  1712. // check async handle type
  1713. if ( nIndirection != 2 )
  1714. {
  1715. if ( !fParentIsAnyIAdviseSink )
  1716. {
  1717. SemError(this, MyContext, OBJECT_ASYNC_NOT_DOUBLE_PTR, pN->GetChild()->GetSymName() );
  1718. }
  1719. }
  1720. if ( strcmp( pFType->GetSymName(), OBJECT_ASYNC_HANDLE_NAME ) )
  1721. {
  1722. if ( !fParentIsAnyIAdviseSink )
  1723. {
  1724. SemError(this, MyContext, ASYNC_INCORRECT_TYPE, pN->GetChild()->GetSymName() );
  1725. }
  1726. }
  1727. else
  1728. {
  1729. fHasAsyncManager = TRUE;
  1730. }
  1731. // flag the first param of an object interface as async handle
  1732. pN->SetIsAsyncHandleParam();
  1733. if ( MyContext.AnyDescendantBits( HAS_OUT ) )
  1734. {
  1735. SemError( this, MyContext, ASYNC_NOT_IN, NULL );
  1736. }
  1737. }
  1738. // Oicf interpreter cannot handle floats as first param, switch to Os.
  1739. // This is a non-issue for ORPC because of the 'this' pointer.
  1740. if ( ! pCommand->NeedsNDR64Run()
  1741. && ( ( BasicChildKind == NODE_FLOAT )
  1742. || ( BasicChildKind == NODE_DOUBLE ) ) )
  1743. {
  1744. if ( ( fOptimize & OPTIMIZE_INTERPRETER_V2) )
  1745. {
  1746. if ( fObjectProc )
  1747. {
  1748. // Don't switch, generate NT 4.0 guard
  1749. pCommand->GetNdrVersionControl().SetHasFloatOrDoubleInOi();
  1750. }
  1751. else
  1752. if ( ForceNonInterpret() )
  1753. {
  1754. RpcSemError( this, MyContext, NON_OI_TOPLEVEL_FLOAT, NULL );
  1755. }
  1756. }
  1757. }
  1758. } // first parameter
  1759. // Oi/Oic interpreter cannot handle float params on alpha, switch to Os.
  1760. if ( ( BasicChildKind == NODE_FLOAT )
  1761. || ( BasicChildKind == NODE_DOUBLE ) )
  1762. {
  1763. if ( ! pCommand->NeedsNDR64Run() &&
  1764. ( fOptimize & OPTIMIZE_INTERPRETER ) )
  1765. {
  1766. // Old interpreter, always switch to -Os.
  1767. if ( !( fOptimize & OPTIMIZE_INTERPRETER_V2 ) )
  1768. {
  1769. if (ForceNonInterpret())
  1770. {
  1771. RpcSemError( this, MyContext, NON_OI_TOPLEVEL_FLOAT, NULL );
  1772. }
  1773. }
  1774. // For -Oicf, there were no problems for object rpc; check standard
  1775. else if ( !fObjectProc && ulParamNumber > 0 )
  1776. {
  1777. // For 64b, float and double work for object and standard rpc.
  1778. // The 32b NT4 engine didn't work for float args in standard rpc.
  1779. if ( !pCommand->Is64BitEnv() && ( BasicChildKind == NODE_FLOAT ) )
  1780. {
  1781. if (ForceNonInterpret())
  1782. {
  1783. RpcSemError( this, MyContext, NON_OI_TOPLEVEL_FLOAT, NULL );
  1784. }
  1785. }
  1786. }
  1787. // For param0 and retval we force above.
  1788. }
  1789. }
  1790. /*
  1791. parameter sequence of odl:
  1792. 1. Required parameters (parameters that do not have the defaultvalue or optional
  1793. attributes),
  1794. 2. optional parameters with or without the defaultvalue attribute,
  1795. 3. parameters with the optional attribute and without the defaultvalue attribute,
  1796. 4. lcid parameter, if any,
  1797. 5. retval parameter
  1798. */
  1799. if ( pN->IsOptional() )
  1800. {
  1801. fLastParamWasOptional = TRUE;
  1802. // [in,optional] VARIANT v1, [in] long l1, [in,optional] VARIANT v2
  1803. if (nAfterLastOptionalParam > 0)
  1804. nAfterLastOptionalParam++;
  1805. // vararg can't coexist with optional parameter.
  1806. if ( fHasVarArg )
  1807. SemError(this, MyContext , NOT_VARARG_COMPATIBLE, 0 );
  1808. }
  1809. else
  1810. {
  1811. // If the following parameter after [optional] is either a RetVal or
  1812. // LCID, we don't fail. The logic between Retval and LCID will be
  1813. // checked later.
  1814. if ( fLastParamWasOptional )
  1815. {
  1816. // The only other parameter allowed to come after [optional]
  1817. // in a propput/propget method is lcid.
  1818. if ( fPropSomething && !pN->IsLCID() )
  1819. nAfterLastOptionalParam++;
  1820. else
  1821. if ( (!pN->IsRetval() && !pN->IsLCID()) && FNewTypeLib() )
  1822. {
  1823. // In regular method, we can only have retval and lcid coming
  1824. // after optional
  1825. SemError( this, MyContext, OPTIONAL_PARAMS_MUST_BE_LAST, NULL );
  1826. }
  1827. }
  1828. }
  1829. if ( ( pAttr = (acf_attr *) pN->GetAttribute( ATTR_COMMSTAT ) ) != 0 )
  1830. {
  1831. if ( !MyContext.AnyDescendantBits( HAS_E_STAT_T ) )
  1832. AcfError( pAttr, this, MyContext, INVALID_COMM_STATUS_PARAM, NULL );
  1833. if ( Commstat == NOT_SEEN )
  1834. Commstat = SEEN_ON_PARAM;
  1835. else if ( Commstat == SEEN_ON_RETURN )
  1836. AcfError( pAttr, this, MyContext, PROC_PARAM_COMM_STATUS, NULL );
  1837. else // already on another parameter
  1838. AcfError( pAttr, this, MyContext, ERROR_STATUS_T_REPEATED, NULL );
  1839. }
  1840. if ( ( pAttr = (acf_attr *) pN->GetAttribute( ATTR_FAULTSTAT ) ) != 0 )
  1841. {
  1842. if ( !MyContext.AnyDescendantBits( HAS_E_STAT_T ) )
  1843. AcfError( pAttr, this, MyContext, INVALID_COMM_STATUS_PARAM, NULL );
  1844. if ( Faultstat == NOT_SEEN )
  1845. Faultstat = SEEN_ON_PARAM;
  1846. else if ( Faultstat == SEEN_ON_RETURN )
  1847. AcfError( pAttr, this, MyContext, PROC_PARAM_FAULT_STATUS, NULL );
  1848. else // already on another parameter
  1849. AcfError( pAttr, this, MyContext, ERROR_STATUS_T_REPEATED, NULL );
  1850. }
  1851. if (MyContext.AnyDescendantBits( HAS_HANDLE) )
  1852. fHasExplicitHandle = TRUE;
  1853. if (MyContext.AnyDescendantBits( HAS_IN ) )
  1854. fHasAtLeastOneIn = TRUE;
  1855. if ( MyContext.AnyDescendantBits( HAS_POINTER ) )
  1856. fHasPointer = TRUE;
  1857. if ( MyContext.AnyDescendantBits( HAS_FULL_PTR ) )
  1858. fHasFullPointer = TRUE;
  1859. if (MyContext.AnyDescendantBits( HAS_OUT) )
  1860. {
  1861. fHasAtLeastOneOut = TRUE;
  1862. // complain about [out] on [maybe] procs
  1863. if ( fMaybe )
  1864. RpcSemError( this, MyContext, MAYBE_NO_OUT_RETVALS, NULL );
  1865. }
  1866. if (MyContext.AnyDescendantBits( (DESCENDANT_FLAGS) HAS_PIPE ))
  1867. {
  1868. #if defined(TARGET_RKK)
  1869. if ( pCommand->GetTargetSystem() < NT40 )
  1870. RpcSemError( this, MyContext, REQUIRES_NT40, NULL );
  1871. #endif
  1872. if (ForceInterpret2())
  1873. RpcSemError( this, MyContext, REQUIRES_OI2, NULL );
  1874. fHasPipes = TRUE;
  1875. if ( HasPickle )
  1876. RpcSemError( this, MyContext, PIPES_WITH_PICKLING, NULL );
  1877. }
  1878. // handle checks
  1879. if ( pN->GetHandleKind() != HDL_NONE )
  1880. {
  1881. if ( !fBindingFound ) // first handle seen
  1882. {
  1883. // dce only allows in handles as the first param
  1884. if ( ulParamNumber != 0 )
  1885. RpcSemError( this, MyContext, HANDLE_NOT_FIRST, NULL );
  1886. // if the first binding handle is out-only, complain
  1887. if ( !MyContext.AnyDescendantBits( HAS_IN ) &&
  1888. MyContext.AnyDescendantBits( HAS_OUT ) )
  1889. {
  1890. if ( !( MyContext.AnyAncestorBits( HAS_AUTO_HANDLE | HAS_IMPLICIT_HANDLE ) ||
  1891. fExpHdlAttr ) )
  1892. {
  1893. RpcSemError( this, MyContext, BINDING_HANDLE_IS_OUT_ONLY, NULL );
  1894. }
  1895. else if ( fExpHdlAttr )
  1896. {
  1897. fAddExplicitHandle = true;
  1898. }
  1899. }
  1900. else if ( MyContext.AnyDescendantBits( HAS_OUT ) &&
  1901. ( pN->GetHandleKind() == HDL_PRIM ) )
  1902. {
  1903. RpcSemError( this, MyContext, HANDLE_T_CANNOT_BE_OUT, NULL );
  1904. }
  1905. else // plain [in], or [in,out]
  1906. {
  1907. fBindingFound = TRUE;
  1908. MyContext.SetAncestorBits( BINDING_SEEN );
  1909. }
  1910. }
  1911. else // binding handle after the real one
  1912. {
  1913. if ( pN->GetHandleKind() == HDL_PRIM )
  1914. RpcSemError( this, MyContext, HANDLE_T_NO_TRANSMIT, NULL );
  1915. }
  1916. } // if it had a handle
  1917. if ( MyContext.AnyDescendantBits( HAS_TOO_BIG_HDL ) )
  1918. {
  1919. if (ForceNonInterpret())
  1920. RpcSemError( this, MyContext, NON_OI_BIG_GEN_HDL, NULL );
  1921. }
  1922. else if ( !pCommand->NeedsNDR64Run()
  1923. &&MyContext.AnyDescendantBits( HAS_UNSAT_REP_AS ) )
  1924. {
  1925. // This case should have been caught earlier.
  1926. // REVIEW: Is this still relevant?
  1927. if (ForceNonInterpret())
  1928. RpcSemError( this, MyContext, NON_OI_UNK_REP_AS, NULL );
  1929. }
  1930. else if ( MyContext.AnyDescendantBits( HAS_UNION ) && IS_OLD_INTERPRETER( GetOptimizationFlags() ) )
  1931. {
  1932. node_skl * pNDC = pN->GetNonDefChild();
  1933. if (pNDC->NodeKind() != NODE_PIPE && !pNDC->IsPtrOrArray())
  1934. {
  1935. // unions by value but not arrays of unions
  1936. if (ForceNonInterpret())
  1937. RpcSemError( this, MyContext, NON_OI_UNION_PARM, NULL );
  1938. }
  1939. }
  1940. if ( MyContext.AnyDescendantBits( HAS_DRTAG ) )
  1941. fHasDRtag = TRUE;
  1942. if ( MyContext.AnyDescendantBits( HAS_RTAG ) )
  1943. fHasRtag = TRUE;
  1944. if ( MyContext.AnyDescendantBits( HAS_STAG ) )
  1945. fHasStag = TRUE;
  1946. if ( MyContext.AnyDescendantBits( HAS_IN_CSTYPE ) )
  1947. fHasInCSType = TRUE;
  1948. if ( MyContext.AnyDescendantBits( HAS_OUT_CSTYPE ) )
  1949. fHasOutCSType = TRUE;
  1950. ulParamNumber++;
  1951. } // end of param list
  1952. if ( MyContext.AnyDescendantBits( HAS_FORCEALLOCATE ) )
  1953. {
  1954. if ( ! ( GetOptimizationFlags() & OPTIMIZE_INTERPRETER_V2 ) )
  1955. SemError( this, MyContext, FORCEALLOCATE_SUPPORTED_IN_OICF_ONLY, NULL );
  1956. }
  1957. if ( fGenDefaultValueExpr )
  1958. {
  1959. bool fReallyGenDefaultValueExpr = true;
  1960. MemIter.Init();
  1961. do
  1962. {
  1963. pN = (node_param *) MemIter.GetNext();
  1964. }
  1965. while ( pN != pFirstParamWithDefValue );
  1966. do
  1967. {
  1968. node_skl* pType = GetNonDefType( pN->GetChild() );
  1969. if ( !pType->IsBasicType() && pType->NodeKind() != NODE_POINTER &&
  1970. pType->NodeKind() != NODE_ENUM )
  1971. {
  1972. SemError( this, MyContext, DEFAULTVALUE_NOT_ALLOWED, pN->GetSymName() );
  1973. fReallyGenDefaultValueExpr = false;
  1974. break;
  1975. }
  1976. pN->GenDefaultValueExpr();
  1977. pN = (node_param *) MemIter.GetNext();
  1978. }
  1979. while ( pN != 0 );
  1980. // don't genereate any defaultvalue in c++ header at all
  1981. if ( !fReallyGenDefaultValueExpr )
  1982. {
  1983. MemIter.Init();
  1984. while ( ( pN = (node_param *) MemIter.GetNext() ) != 0 )
  1985. {
  1986. pN->GenDefaultValueExpr( false );
  1987. }
  1988. }
  1989. }
  1990. if ( fHasPipeParam && fHasConfOrVaryingParam )
  1991. {
  1992. SemError( this, MyContext, PIPE_INCOMPATIBLE_PARAMS, 0 );
  1993. }
  1994. ///////////////////////////////////////////////////////////////////////
  1995. if ( fHasExplicitHandle )
  1996. {
  1997. if ( fProcIsCallback )
  1998. RpcSemError( this, MyContext, HANDLES_WITH_CALLBACK, NULL );
  1999. }
  2000. if ( !fHasExplicitHandle || fAddExplicitHandle )
  2001. {
  2002. if ( fExpHdlAttr )
  2003. {
  2004. // async handle should be first param,
  2005. // programmer supplies IAsyncManager in ORPC
  2006. // MIDL adds PRPC_ASYNC_STATE in RPC
  2007. // if parent interface is is any IAdviseSink ignore async.
  2008. if ( fObjectProc && fAsync && fHasAsyncManager )
  2009. {
  2010. AddExplicitHandle( &MyContext, 2 );
  2011. }
  2012. else
  2013. {
  2014. // MIDL will add async handle later
  2015. AddExplicitHandle( &MyContext, 1 );
  2016. }
  2017. }
  2018. else if ( !(pIntfCtxt->FInSummary( ATTR_IMPLICIT ) ) )
  2019. {
  2020. // no explicit handle, no implicit handle, use auto_handle
  2021. if ( !fProcIsCallback &&
  2022. MyContext.AnyAncestorBits( IN_RPC ) &&
  2023. !fObjectProc )
  2024. {
  2025. if ( !pIntfCtxt->FInSummary( ATTR_AUTO ) )
  2026. RpcSemError( this, MyContext, NO_HANDLE_DEFINED_FOR_PROC, NULL );
  2027. }
  2028. }
  2029. }
  2030. if ( fObjectProc || MyContext.AnyAncestorBits( IN_LIBRARY ))
  2031. {
  2032. if (fHasExplicitHandle ||
  2033. fExpHdlAttr ||
  2034. MyContext.FInSummary( ATTR_IMPLICIT ) ||
  2035. MyContext.FInSummary( ATTR_AUTO ) ||
  2036. pIntfCtxt->FInSummary( ATTR_AUTO ) ||
  2037. pIntfCtxt->FInSummary( ATTR_IMPLICIT ) ||
  2038. pIntfCtxt->FInSummary( ATTR_EXPLICIT ) )
  2039. {
  2040. SemError( this, MyContext, HANDLES_WITH_OBJECT, NULL );
  2041. }
  2042. }
  2043. // record whether there are any comm/fault statuses
  2044. if ( ( Faultstat != NOT_SEEN ) || ( Commstat != NOT_SEEN ) )
  2045. {
  2046. fHasStatuses = TRUE;
  2047. // [comm_status] and [fault_status] are supported in -Os. Intrepreted
  2048. // modes are only supported in NT 3.51 or later. Hidden status
  2049. // params are only supported in interpreted mode post-Win2000.
  2050. // REVIEW: We can get hidden status params to work for Win2000 by
  2051. // adding a line to the client stub that zero's the status
  2052. // before calling the interpreter.
  2053. if ( GetOptimizationFlags() & OPTIMIZE_ANY_INTERPRETER )
  2054. {
  2055. if ( HasExtraStatusParam()
  2056. && ( ! ( GetOptimizationFlags() & OPTIMIZE_INTERPRETER_V2 )
  2057. || !pCommand->NeedsNDR64Run() ) )
  2058. {
  2059. // invisible fault/comm status are not supported in the V1
  2060. // interpreter. Switch to -Os
  2061. // REVIEW: For now, only support hidden status params in the
  2062. // V2 interpreter in -protocol all and -protocol ndr64
  2063. if (ForceNonInterpret())
  2064. RpcSemError( this, MyContext, NON_OI_ERR_STATS, NULL );
  2065. }
  2066. else
  2067. pCommand->GetNdrVersionControl().SetHasCommFaultStatusInOi12();
  2068. }
  2069. }
  2070. // record info for statuses on the return type
  2071. if ( Faultstat == SEEN_ON_RETURN )
  2072. RTStatuses |= STATUS_FAULT;
  2073. if ( Commstat == SEEN_ON_RETURN )
  2074. RTStatuses |= STATUS_COMM;
  2075. if ( fHasPointer && !pCommand->IsSwitchDefined( SWITCH_MS_EXT ) )
  2076. pIntf->SetHasProcsWithRpcSs();
  2077. if ( ( OpBits & ( OPERATION_MAYBE | OPERATION_BROADCAST | OPERATION_IDEMPOTENT ) ) != 0 &&
  2078. fObjectProc )
  2079. {
  2080. SemError(this, MyContext, ILLEGAL_COMBINATION_OF_ATTRIBUTES, NULL);
  2081. }
  2082. // [message] only allowed in ORPC interfaces and RPC procs.
  2083. if ( fMessage && fObjectProc )
  2084. {
  2085. // [message] applied on proc.
  2086. SemError(this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  2087. }
  2088. if ( MyContext.AnyAncestorBits( HAS_MESSAGE ) )
  2089. {
  2090. // [message] applied on interface.
  2091. if ( !fObjectProc )
  2092. {
  2093. SemError(this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  2094. }
  2095. fMessage = TRUE;
  2096. }
  2097. if ( fMessage )
  2098. {
  2099. if ( OpBits & OPERATION_BROADCAST
  2100. || OpBits & OPERATION_IDEMPOTENT
  2101. || OpBits & OPERATION_INPUT_SYNC
  2102. || fMaybe
  2103. || fAsync
  2104. || fProcIsCallback
  2105. || pCallAs
  2106. || HasPickle
  2107. || pHC
  2108. || pHSC
  2109. || pID
  2110. || pHelpStr
  2111. || MyContext.FInSummary(ATTR_BYTE_COUNT)
  2112. || MyContext.FInSummary(ATTR_COMMSTAT)
  2113. || MyContext.FInSummary(ATTR_CONTEXT)
  2114. || MyContext.FInSummary(ATTR_CUSTOM)
  2115. || MyContext.FInSummary(ATTR_ENABLE_ALLOCATE)
  2116. || MyContext.FInSummary(ATTR_ENTRY)
  2117. || MyContext.FInSummary(ATTR_FAULTSTAT)
  2118. || MyContext.FInSummary(ATTR_FUNCDESCATTR)
  2119. || MyContext.FInSummary(ATTR_HIDDEN)
  2120. || MyContext.FInSummary(ATTR_MEMBER)
  2121. || MyContext.FInSummary(ATTR_PTR_KIND)
  2122. || MyContext.FInSummary(ATTR_VARDESCATTR)
  2123. || MyContext.FInSummary(ATTR_OBJECT)
  2124. || MyContext.FInSummary(ATTR_TYPEDESCATTR)
  2125. || MyContext.FInSummary(ATTR_TYPE)
  2126. )
  2127. {
  2128. SemError(this, MyContext, ILLEGAL_COMBINATION_OF_ATTRIBUTES, NULL);
  2129. }
  2130. if ( HasAtLeastOneOut() )
  2131. {
  2132. SemError(this, MyContext, MAYBE_NO_OUT_RETVALS, NULL);
  2133. }
  2134. }
  2135. if ( MyContext.AnyAncestorBits( HAS_OLEAUTOMATION ) )
  2136. {
  2137. char* szRetTypeNonDefName = 0;
  2138. node_skl* pReturnType = GetReturnType();
  2139. if (pReturnType)
  2140. {
  2141. szRetTypeNonDefName = pReturnType->GetSymName();
  2142. }
  2143. if ( GetReturnType()->GetBasicType()->NodeKind() != NODE_VOID &&
  2144. ( !szRetTypeNonDefName ||
  2145. _stricmp(szRetTypeNonDefName, "HRESULT") ) )
  2146. {
  2147. SemError(this, MyContext, NOT_OLEAUTOMATION_INTERFACE, NULL);
  2148. }
  2149. }
  2150. if ( fPropSomething && MyContext.AnyAncestorBits( IN_LIBRARY ) )
  2151. {
  2152. // propget can either return the property in an out parameter or
  2153. // in the return value.
  2154. if ( fPropGet && !HasAParameter() && !HasReturn() )
  2155. {
  2156. SemError(this, MyContext, INVALID_USE_OF_PROPGET, NULL);
  2157. }
  2158. // propput must set the property in a parameter
  2159. else if ( !fPropGet && !HasAParameter() )
  2160. {
  2161. SemError(this, MyContext, INVALID_USE_OF_PROPPUT, NULL);
  2162. }
  2163. }
  2164. if (MyContext.AnyAncestorBits( (ANCESTOR_FLAGS) IN_DISPINTERFACE ) && !pID)
  2165. {
  2166. SemError(this, MyContext, DISPATCH_ID_REQUIRED, NULL);
  2167. }
  2168. if ( fAsync )
  2169. {
  2170. if ( fForcedS ||
  2171. pOptAttr ||
  2172. fNotify ||
  2173. HasPickle ||
  2174. fProcIsCallback ||
  2175. fLocal ||
  2176. fCode ||
  2177. fNoCode ||
  2178. fMaybe ||
  2179. fMessage ||
  2180. OpBits & OPERATION_INPUT_SYNC ||
  2181. pIntfCtxt->FInSummary( ATTR_AUTO ) )
  2182. {
  2183. SemError(this, MyContext, ILLEGAL_COMBINATION_OF_ATTRIBUTES, NULL);
  2184. }
  2185. // async handle should be first param,
  2186. // programmer supplies IAsyncManager in ORPC
  2187. // MIDL adds PRPC_ASYNC_STATE in RPC
  2188. if ( fObjectProc )
  2189. {
  2190. if ( fHasAsyncManager )
  2191. {
  2192. SetHasAsyncHandle();
  2193. }
  2194. // if parent interface is is any IAdviseSink ignore.
  2195. if ( !fParentIsAnyIAdviseSink )
  2196. {
  2197. if ( ulParamNumber == 0 )
  2198. {
  2199. SemError( this, MyContext, ASYNC_INCORRECT_TYPE, 0);
  2200. }
  2201. pCommand->GetNdrVersionControl().SetHasAsyncHandleRpc();
  2202. }
  2203. }
  2204. else
  2205. {
  2206. AddFullAsyncHandle( &MyContext, 0, RPC_ASYNC_HANDLE_NAME );
  2207. if ( pAttrAsync && !pAttrAsync->IsAcfAttr() )
  2208. {
  2209. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  2210. }
  2211. if ( !pIntfCtxt->FInSummary( ATTR_IMPLICIT ) &&
  2212. !fExpHdlAttr &&
  2213. !fHasExplicitHandle )
  2214. {
  2215. SemError( this, MyContext, ASYNC_INCORRECT_BINDING_HANDLE, 0 );
  2216. }
  2217. pCommand->GetNdrVersionControl().SetHasAsyncHandleRpc();
  2218. }
  2219. if ( pCommand->IsSwitchDefined( SWITCH_OSF ) )
  2220. {
  2221. SemError( this, MyContext, INVALID_OSF_ATTRIBUTE, "[async]" );
  2222. }
  2223. // switch compiler modes
  2224. if (ForceInterpret2())
  2225. {
  2226. RpcSemError( this, MyContext, ASYNC_REQUIRES_OI2, NULL );
  2227. }
  2228. }
  2229. // I don't like this complex logic, but unfortunately this is the right logic. It's easier
  2230. // to code this logic in mktyplib code structure but hard to do it here...
  2231. if ( fLCID )
  2232. {
  2233. node_param* pLCID;
  2234. // if there is a [retval], [lcid] must be the second last
  2235. if ( fRetval)
  2236. pLCID = p2LastParam;
  2237. else
  2238. {
  2239. if (fPropSomething)
  2240. {
  2241. // in propget without a retval, the lcid must be the last.
  2242. // in propput/propputref, lcid is second last.
  2243. if (fPropGet)
  2244. pLCID = pLastParam;
  2245. else
  2246. pLCID = p2LastParam;
  2247. }
  2248. // lcid should be the last if it's a regular method without propsomething & retval
  2249. else
  2250. pLCID = pLastParam;
  2251. }
  2252. if ( !pLCID || !pLCID->IsLCID() )
  2253. {
  2254. SemError( this, MyContext, INVALID_USE_OF_LCID, 0 );
  2255. }
  2256. }
  2257. // we can only have one parameter after optioanl in propput/propget, other than lcid.
  2258. if ( fLastParamWasOptional && fPropSomething && ( nAfterLastOptionalParam > 1 ) )
  2259. SemError(this, MyContext , INVALID_PROP_PARAMS , 0);
  2260. // Verify that a propput method is valid.
  2261. // TODO: much of the above code relating to propput/get could be simplified
  2262. // with state driven logic and is redundent with the code below
  2263. if ( fPropSomething & !fPropGet )
  2264. {
  2265. using namespace PropPut;
  2266. State state = NoParam;
  2267. node_param *pParam;
  2268. MemIter.Init();
  2269. while ( NULL != (pParam = (node_param *) MemIter.GetNext()) )
  2270. {
  2271. if ( pParam->FInSummary( ATTR_DEFAULTVALUE ) )
  2272. state = StateTable[state][Default];
  2273. else if ( pParam->IsOptional() )
  2274. state = StateTable[state][Optional];
  2275. else if ( pParam->IsLCID() )
  2276. state = StateTable[state][LCID];
  2277. else
  2278. state = StateTable[state][GeneralParam];
  2279. }
  2280. state = StateTable[state][NoParam];
  2281. if ( Accept != state )
  2282. SemError(this, MyContext , INVALID_PROPPUT , 0);
  2283. }
  2284. if ( fHasVarArg )
  2285. {
  2286. // [vararg] [lcid] [retval]
  2287. // last 0 0
  2288. // 2 last last 0
  2289. // 2 last 0 last
  2290. // 3 last 2last last
  2291. node_param* pVarargParam = fRetval ? ( fLCID ? p3LastParam : p2LastParam ) : ( fLCID ? p2LastParam : pLastParam );
  2292. if ( pVarargParam )
  2293. {
  2294. node_skl* pType = pVarargParam->GetChild();
  2295. if ( pType->NodeKind() == NODE_POINTER )
  2296. {
  2297. pType = pType->GetChild();
  2298. }
  2299. pType = GetNonDefType( pType );
  2300. if ( pType->NodeKind() != NODE_SAFEARRAY ||
  2301. strcmp( GetNonDefType( pType->GetChild() )->GetSymName(), "tagVARIANT" ) )
  2302. {
  2303. SemError( this, MyContext, NOT_VARARG_COMPATIBLE, 0 );
  2304. }
  2305. }
  2306. else
  2307. {
  2308. SemError( this, MyContext, NOT_VARARG_COMPATIBLE, 0 );
  2309. }
  2310. }
  2311. if ( pIntf->IsAsyncClone() )
  2312. {
  2313. SetHasAsyncUUID();
  2314. ForceInterpret2();
  2315. }
  2316. if ( fNotify || fNotifyFlag )
  2317. {
  2318. unsigned short uOpt = GetOptimizationFlags();
  2319. if ( !( uOpt & OPTIMIZE_SIZE ) )
  2320. {
  2321. pCommand->GetNdrVersionControl().SetHasInterpretedNotify();
  2322. if ( IS_OLD_INTERPRETER(uOpt) )
  2323. {
  2324. if (ForceInterpret2())
  2325. RpcSemError( this, MyContext, NON_OI_NOTIFY, NULL );
  2326. }
  2327. }
  2328. }
  2329. if ( fHasInCSType && !fHasStag )
  2330. SemError( this, MyContext, NO_TAGS_FOR_IN_CSTYPE, 0 );
  2331. if ( fHasOutCSType && ( !fHasDRtag || !fHasRtag ) )
  2332. SemError( this, MyContext, NO_TAGS_FOR_OUT_CSTYPE, 0 );
  2333. if ( fHasInCSType || fHasOutCSType )
  2334. {
  2335. if ( NULL != pCSTagAttr )
  2336. SetCSTagRoutine( pCSTagAttr->GetCSTagRoutine() );
  2337. else
  2338. MyContext.SetDescendantBits( HAS_IN_CSTYPE );
  2339. }
  2340. if ( HasPickle && MyContext.AnyDescendantBits( HAS_PARTIAL_IGNORE ) )
  2341. {
  2342. SemError( this, MyContext, PARTIAL_IGNORE_PICKLING, GetSymName() );
  2343. }
  2344. MyContext.SetDescendantBits( HAS_FUNC );
  2345. pParentCtxt->ReturnValues( MyContext );
  2346. }
  2347. void
  2348. node_field::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  2349. {
  2350. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  2351. BOOL fLastField = ( GetSibling() == NULL );
  2352. node_case * pCaseAttr;
  2353. expr_list * pCaseExprList;
  2354. expr_node * pCaseExpr;
  2355. BOOL fHasCases = FALSE;
  2356. node_su_base * pParent = (node_su_base *)
  2357. MyContext.GetParentContext()->GetParent();
  2358. BOOL fInUnion = ( pParent->NodeKind() == NODE_UNION );
  2359. node_switch_type * pSwTypeAttr = ( node_switch_type *)
  2360. pParent->GetAttribute( ATTR_SWITCH_TYPE );
  2361. node_skl * pSwType = NULL;
  2362. char * pName = GetSymName();
  2363. node_constant_attr * pID = (node_constant_attr *) MyContext.ExtractAttribute(ATTR_ID);
  2364. MyContext.ExtractAttribute(ATTR_HELPCONTEXT);
  2365. MyContext.ExtractAttribute(ATTR_HELPSTRINGCONTEXT);
  2366. MyContext.ExtractAttribute(ATTR_HELPSTRING);
  2367. if (MyContext.ExtractAttribute(ATTR_HELPSTRINGDLL))
  2368. {
  2369. SemError(this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  2370. }
  2371. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  2372. if ( MyContext.ExtractAttribute(ATTR_IDLDESCATTR) )
  2373. {
  2374. SemError(this, MyContext, NEWLYFOUND_INAPPLICABLE_ATTRIBUTE, 0);
  2375. }
  2376. if ( MyContext.ExtractAttribute(ATTR_VARDESCATTR) )
  2377. {
  2378. SemError(this, MyContext, NEWLYFOUND_INAPPLICABLE_ATTRIBUTE, 0);
  2379. }
  2380. MyContext.ExtractAttribute(ATTR_HIDDEN);
  2381. if ( HasCorrelation( this ) )
  2382. {
  2383. MyContext.IncCorrelationCount();
  2384. }
  2385. CheckDeclspecAlign( MyContext );
  2386. if (pID)
  2387. {
  2388. SEM_ANALYSIS_CTXT * pIntfCtxt = (SEM_ANALYSIS_CTXT *)
  2389. MyContext.GetInterfaceContext();
  2390. node_interface * pIntf = (node_interface *) pIntfCtxt->GetParent();
  2391. if (!pIntf->AddId(pID->GetExpr()->GetValue(), GetSymName()))
  2392. SemError( this, MyContext, DUPLICATE_IID, NULL);
  2393. }
  2394. else
  2395. {
  2396. if ( MyContext.AnyAncestorBits( (ANCESTOR_FLAGS) IN_DISPINTERFACE ) &&
  2397. pParent->NodeKind() == NODE_DISPINTERFACE)
  2398. {
  2399. SemError(this, MyContext, DISPATCH_ID_REQUIRED, NULL);
  2400. }
  2401. }
  2402. node_entry_attr * pEntry = NULL;
  2403. // check for illegal member attributes
  2404. node_member_attr * pMA;
  2405. while ( ( pMA = (node_member_attr *)MyContext.ExtractAttribute(ATTR_MEMBER) ) != 0 )
  2406. {
  2407. switch (pMA->GetAttr())
  2408. {
  2409. case MATTR_BINDABLE:
  2410. case MATTR_DISPLAYBIND:
  2411. case MATTR_DEFAULTBIND:
  2412. case MATTR_REQUESTEDIT:
  2413. case MATTR_DEFAULTVTABLE:
  2414. case MATTR_PREDECLID:
  2415. case MATTR_READONLY:
  2416. case MATTR_UIDEFAULT:
  2417. case MATTR_NONBROWSABLE:
  2418. case MATTR_DEFAULTCOLLELEM:
  2419. case MATTR_IMMEDIATEBIND:
  2420. case MATTR_REPLACEABLE:
  2421. break;
  2422. case MATTR_SOURCE:
  2423. {
  2424. char * pAttrName = pMA->GetNodeNameString();
  2425. if ( MyContext.AnyAncestorBits( IN_STRUCT | IN_UNION ) )
  2426. SemError( this, MyContext, NEWLYFOUND_INAPPLICABLE_ATTRIBUTE, pAttrName);
  2427. break;
  2428. }
  2429. case MATTR_PROPGET:
  2430. case MATTR_PROPPUT:
  2431. case MATTR_PROPPUTREF:
  2432. case MATTR_OPTIONAL:
  2433. case MATTR_RESTRICTED:
  2434. case MATTR_RETVAL:
  2435. case MATTR_VARARG:
  2436. case MATTR_USESGETLASTERROR:
  2437. default:
  2438. {
  2439. char * pAttrName = pMA->GetNodeNameString();
  2440. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, pAttrName);
  2441. break;
  2442. }
  2443. }
  2444. }
  2445. if (MyContext.AnyAncestorBits( IN_MODULE ))
  2446. pEntry = (node_entry_attr *) MyContext.ExtractAttribute( ATTR_ENTRY );
  2447. if ( pSwTypeAttr )
  2448. pSwType = pSwTypeAttr->GetType();
  2449. // process all the cases and the default
  2450. while ( ( pCaseAttr = (node_case *) MyContext.ExtractAttribute( ATTR_CASE ) ) != 0 )
  2451. {
  2452. if ( !fInUnion )
  2453. TypeSemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, "[case]" );
  2454. fHasCases = TRUE;
  2455. if ( pSwType )
  2456. {
  2457. pCaseExprList = pCaseAttr->GetExprList();
  2458. pCaseExprList->Init();
  2459. while ( pCaseExprList->GetPeer( &pCaseExpr ) == STATUS_OK )
  2460. {
  2461. // make sure the expression has the proper type, so sign extension behaves
  2462. node_skl * pCaseType = pCaseExpr->GetType();
  2463. if ( ( !pCaseType ) ||
  2464. ( pCaseType->GetNonDefSelf()->IsBasicType() ) )
  2465. {
  2466. pCaseExpr->SetType( pSwType->GetBasicType() );
  2467. }
  2468. // range/type checks
  2469. __int64 CaseValue = pCaseExpr->GetValue();
  2470. if ( !((node_base_type *)pSwType)->RangeCheck( CaseValue ) )
  2471. TypeSemError( this, MyContext, CASE_VALUE_OUT_OF_RANGE, NULL );
  2472. }
  2473. }
  2474. }
  2475. if ( MyContext.ExtractAttribute( ATTR_DEFAULT ) )
  2476. {
  2477. if ( !fInUnion )
  2478. TypeSemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, "[default]" );
  2479. fHasCases = TRUE;
  2480. }
  2481. // union fields in an RPC MUST have cases
  2482. if ( fInUnion && !fHasCases )
  2483. RpcSemError( this, MyContext, CASE_LABELS_MISSING_IN_UNION, NULL );
  2484. // temp field names valid for: structs/enums/empty arms
  2485. if ( IsTempName( pName ) )
  2486. {
  2487. NODE_T BaseType = GetBasicType()->NodeKind();
  2488. if ( ( BaseType != NODE_UNION ) &&
  2489. ( BaseType != NODE_STRUCT ) &&
  2490. ( BaseType != NODE_ERROR ) )
  2491. SemError( GetBasicType(), MyContext, BAD_CON_UNNAMED_FIELD_NO_STRUCT, NULL );
  2492. }
  2493. GetChild()->SemanticAnalysis( &MyContext );
  2494. // allow conformant array or struct only as last field, and not in unions!
  2495. if ( MyContext.AnyDescendantBits( HAS_CONF_ARRAY
  2496. | HAS_CONF_VAR_ARRAY ) )
  2497. {
  2498. if ( fInUnion )
  2499. {
  2500. RpcSemError( this, MyContext, BAD_CON_UNION_FIELD_CONF , NULL );
  2501. }
  2502. else if (!fLastField )
  2503. {
  2504. SemError( this, MyContext, CONFORMANT_ARRAY_NOT_LAST, NULL );
  2505. }
  2506. }
  2507. // disallow forward references as members
  2508. if ( MyContext.AnyDescendantBits( HAS_INCOMPLETE_TYPE ) )
  2509. {
  2510. if (! MyContext.AnyAncestorBits( IN_LIBRARY ))
  2511. SemError( this, MyContext, UNDEFINED_SYMBOL, NULL );
  2512. MyContext.ClearDescendantBits( HAS_INCOMPLETE_TYPE );
  2513. }
  2514. MyContext.ClearDescendantBits( HAS_RECURSIVE_DEF );
  2515. // don't allow functions as fields
  2516. if ( MyContext.AnyDescendantBits( HAS_FUNC ) &&
  2517. MyContext.AllAncestorBits( IN_INTERFACE | IN_RPC ) )
  2518. RpcSemError( this, MyContext, BAD_CON_FIELD_FUNC, NULL );
  2519. if ( MyContext.AnyDescendantBits( HAS_UNSAT_REP_AS ) )
  2520. SetHasUnknownRepAs();
  2521. pParentCtxt->ReturnValues( MyContext );
  2522. }
  2523. void
  2524. node_bitfield::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  2525. {
  2526. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  2527. CheckDeclspecAlign( MyContext );
  2528. RpcSemError( this, MyContext, BAD_CON_BIT_FIELDS, NULL );
  2529. if ( MyContext.AnyAncestorBits( IN_PARAM_LIST ) )
  2530. {
  2531. RpcSemError( this, MyContext, NON_RPC_PARAM_BIT_FIELDS, NULL );
  2532. }
  2533. else
  2534. {
  2535. RpcSemError( this, MyContext, NON_RPC_RTYPE_BIT_FIELDS, NULL );
  2536. }
  2537. GetChild()->SemanticAnalysis( &MyContext );
  2538. node_skl * pType = GetBasicType();
  2539. switch ( pType->NodeKind() )
  2540. {
  2541. case NODE_INT:
  2542. break;
  2543. case NODE_BOOLEAN:
  2544. case NODE_SHORT:
  2545. case NODE_CHAR:
  2546. case NODE_LONG:
  2547. case NODE_INT32:
  2548. case NODE_INT3264:
  2549. case NODE_INT64:
  2550. case NODE_INT128:
  2551. case NODE_HYPER:
  2552. SemError( this, MyContext, BAD_CON_BIT_FIELD_NON_ANSI, NULL );
  2553. break;
  2554. default:
  2555. SemError( this, MyContext, BAD_CON_BIT_FIELD_NOT_INTEGRAL, NULL );
  2556. break;
  2557. }
  2558. // disallow forward references as members
  2559. if ( MyContext.AnyDescendantBits( HAS_INCOMPLETE_TYPE ) )
  2560. {
  2561. if (! MyContext.AnyAncestorBits( IN_LIBRARY ))
  2562. SemError( this, MyContext, UNDEFINED_SYMBOL, NULL );
  2563. MyContext.ClearDescendantBits( HAS_INCOMPLETE_TYPE );
  2564. }
  2565. MyContext.ClearDescendantBits( HAS_RECURSIVE_DEF );
  2566. pParentCtxt->ReturnValues( MyContext );
  2567. }
  2568. void
  2569. node_su_base::CheckLegalParent(SEM_ANALYSIS_CTXT & MyContext)
  2570. {
  2571. WALK_CTXT * pParentCtxt = MyContext.GetParentContext();
  2572. node_file * pFile = GetDefiningFile();
  2573. if (NULL == pFile)
  2574. {
  2575. node_skl * pParent = pParentCtxt->GetParent();
  2576. if (NULL == pParent || pParent->NodeKind() == NODE_LIBRARY)
  2577. SemError( this, MyContext, ILLEGAL_SU_DEFINITION, NULL );
  2578. }
  2579. };
  2580. void
  2581. node_enum::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  2582. {
  2583. MEM_ITER MemIter( this );
  2584. node_skl * pN;
  2585. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  2586. MyContext.ExtractAttribute( ATTR_V1_ENUM );
  2587. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  2588. MyContext.ExtractAttribute(ATTR_TYPEDESCATTR);
  2589. MyContext.ExtractAttribute(ATTR_HELPCONTEXT);
  2590. MyContext.ExtractAttribute(ATTR_HELPSTRINGCONTEXT);
  2591. MyContext.ExtractAttribute( ATTR_HELPSTRING );
  2592. if (MyContext.ExtractAttribute(ATTR_HELPSTRINGDLL))
  2593. {
  2594. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  2595. }
  2596. if ( MyContext.ExtractAttribute(ATTR_IDLDESCATTR) )
  2597. {
  2598. SemError(this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  2599. }
  2600. // check for illegal type attributes
  2601. node_type_attr * pTA;
  2602. while ( ( pTA = (node_type_attr *)MyContext.ExtractAttribute(ATTR_TYPE) ) != 0 )
  2603. {
  2604. switch (pTA->GetAttr())
  2605. {
  2606. // acceptable attributes
  2607. case TATTR_PUBLIC:
  2608. {
  2609. char * pAttrName = pTA->GetNodeNameString();
  2610. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, pAttrName);
  2611. break;
  2612. }
  2613. }
  2614. }
  2615. // check for illegal member attributes
  2616. node_member_attr * pMA;
  2617. while ( ( pMA = (node_member_attr *)MyContext.ExtractAttribute(ATTR_MEMBER) ) != 0 )
  2618. {
  2619. switch (pMA->GetAttr())
  2620. {
  2621. case MATTR_USESGETLASTERROR:
  2622. {
  2623. char * pAttrName = pMA->GetNodeNameString();
  2624. SemError( this, MyContext, NEWLYFOUND_INAPPLICABLE_ATTRIBUTE, pAttrName);
  2625. break;
  2626. }
  2627. }
  2628. }
  2629. CheckDeclspecAlign( MyContext );
  2630. node_guid * pGuid = (node_guid *) MyContext.ExtractAttribute( ATTR_GUID );
  2631. // make sure the UUID is unique
  2632. if ( pGuid )
  2633. {
  2634. node_skl* pDuplicate = GetDuplicateGuid( pGuid, pUUIDTable );
  2635. if ( pDuplicate )
  2636. {
  2637. SemError(this, MyContext, DUPLICATE_UUID, pDuplicate->GetSymName());
  2638. }
  2639. }
  2640. if (pCommand->IsSwitchDefined(SWITCH_MKTYPLIB))
  2641. CheckLegalParent(MyContext);
  2642. node_range_attr* pRange = ( node_range_attr* ) MyContext.ExtractAttribute(ATTR_RANGE);
  2643. if ( pRange )
  2644. {
  2645. if ( pRange->GetMinExpr()->GetValue() > pRange->GetMaxExpr()->GetValue() )
  2646. {
  2647. SemError(this, MyContext, INCORRECT_RANGE_DEFN, 0);
  2648. }
  2649. }
  2650. while ( ( pN = MemIter.GetNext() ) != 0 )
  2651. {
  2652. pN->SemanticAnalysis( &MyContext );
  2653. }
  2654. MyContext.SetDescendantBits( HAS_ENUM );
  2655. pParentCtxt->ReturnValues( MyContext );
  2656. }
  2657. // structs are stringable if all the fields are "byte"
  2658. BOOL
  2659. node_struct::IsStringableType()
  2660. {
  2661. MEM_ITER MemIter( this );
  2662. node_skl * pBasic;
  2663. node_skl * pN;
  2664. // make sure all the fields are BYTE! with no attributes on the way
  2665. while ( ( pN = (node_skl *) MemIter.GetNext() ) != 0 )
  2666. {
  2667. pBasic = pN->GetBasicType();
  2668. do {
  2669. if ( pN->HasAttributes() )
  2670. return FALSE;
  2671. pN = pN->GetChild();
  2672. }
  2673. while ( pN != pBasic );
  2674. pBasic = pN->GetBasicType();
  2675. if ( pBasic &&
  2676. (pBasic->NodeKind() != NODE_BYTE ) )
  2677. {
  2678. return FALSE;
  2679. }
  2680. }
  2681. return TRUE;
  2682. }
  2683. void
  2684. node_struct::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  2685. {
  2686. MEM_ITER MemIter( this );
  2687. node_skl * pN;
  2688. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  2689. if ( fBeingAnalyzed )
  2690. {
  2691. // if we hit the same node more than once (it can only be through a ptr),
  2692. // and the ptr type is ref, we flag an error; recursive defn. through a ref ptr.
  2693. if ( !MyContext.AnyAncestorBits( IN_NON_REF_PTR ) &&
  2694. MyContext.AnyAncestorBits( IN_RPC ) )
  2695. {
  2696. TypeSemError( this, MyContext, RECURSION_THRU_REF, NULL );
  2697. }
  2698. return;
  2699. }
  2700. fBeingAnalyzed = TRUE;
  2701. CheckDeclspecAlign( MyContext );
  2702. BOOL fString = (NULL != MyContext.ExtractAttribute( ATTR_STRING ));
  2703. node_guid * pGuid = (node_guid *) MyContext.ExtractAttribute( ATTR_GUID );
  2704. // make sure the UUID is unique
  2705. if ( pGuid )
  2706. {
  2707. node_skl* pDuplicate = GetDuplicateGuid( pGuid, pUUIDTable );
  2708. if ( pDuplicate )
  2709. {
  2710. SemError(this, MyContext, DUPLICATE_UUID, pDuplicate->GetSymName());
  2711. }
  2712. }
  2713. MyContext.MarkImportantPosition();
  2714. MyContext.SetAncestorBits( IN_STRUCT );
  2715. // clear NE union flag
  2716. MyContext.ClearAncestorBits( IN_UNION | IN_NE_UNION );
  2717. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  2718. MyContext.ExtractAttribute(ATTR_TYPEDESCATTR);
  2719. MyContext.ExtractAttribute(ATTR_HELPCONTEXT);
  2720. MyContext.ExtractAttribute(ATTR_HELPSTRINGCONTEXT);
  2721. MyContext.ExtractAttribute( ATTR_HELPSTRING );
  2722. if ( MyContext.ExtractAttribute( ATTR_VERSION ) )
  2723. {
  2724. SemError(this, MyContext, NEWLYFOUND_INAPPLICABLE_ATTRIBUTE, 0);
  2725. }
  2726. if (MyContext.ExtractAttribute(ATTR_HELPSTRINGDLL))
  2727. {
  2728. SemError(this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  2729. }
  2730. // clear member attributes
  2731. while (MyContext.ExtractAttribute(ATTR_MEMBER));
  2732. if (pCommand->IsSwitchDefined(SWITCH_MKTYPLIB))
  2733. CheckLegalParent(MyContext);
  2734. // See if context_handle applied to param reached us
  2735. if ( CheckContextHandle( MyContext ) )
  2736. {
  2737. MyContext.SetDescendantBits( HAS_HANDLE | HAS_CONTEXT_HANDLE );
  2738. }
  2739. while ( ( pN = MemIter.GetNext() ) != 0 )
  2740. {
  2741. pN->SemanticAnalysis( &MyContext );
  2742. if ( MyContext.AnyDescendantBits( HAS_HANDLE ) )
  2743. TypeSemError( pN, MyContext, BAD_CON_CTXT_HDL_FIELD, NULL );
  2744. }
  2745. if ( fString && !IsStringableType() )
  2746. {
  2747. TypeSemError( this, MyContext, WRONG_TYPE_IN_STRING_STRUCT, NULL );
  2748. }
  2749. // If a structure has an embedded array of pointers the back end gets
  2750. // really confused and generates bad pointer layouts. Work around the
  2751. // problem by forcing the structure to be complex.
  2752. if ( MyContext.AnyDescendantBits( HAS_VAR_ARRAY | HAS_ARRAYOFPOINTERS ) )
  2753. Complexity |= FLD_VAR;
  2754. if ( MyContext.AnyDescendantBits( HAS_CONF_ARRAY ) )
  2755. {
  2756. Complexity |= FLD_CONF;
  2757. fHasConformance = 1;
  2758. }
  2759. if ( MyContext.AnyDescendantBits( HAS_CONF_VAR_ARRAY ) )
  2760. {
  2761. Complexity |= FLD_CONF_VAR;
  2762. fHasConformance = 1;
  2763. }
  2764. // don't pass up direct conformance characteristic
  2765. MyContext.ClearDescendantBits( HAS_DIRECT_CONF_OR_VAR );
  2766. // disallow direct forward references as struct members
  2767. if ( MyContext.AnyDescendantBits( HAS_INCOMPLETE_TYPE ) )
  2768. {
  2769. if (! MyContext.AnyAncestorBits( IN_LIBRARY ))
  2770. SemError( this, MyContext, UNDEFINED_SYMBOL, NULL );
  2771. MyContext.ClearDescendantBits( HAS_INCOMPLETE_TYPE );
  2772. }
  2773. MyContext.ClearDescendantBits( HAS_RECURSIVE_DEF );
  2774. if ( MyContext.AnyDescendantBits( HAS_POINTER ) )
  2775. SetHasAtLeastOnePointer( TRUE );
  2776. // save info on complexity for code generation
  2777. if ( MyContext.AnyDescendantBits( HAS_VAR_ARRAY |
  2778. HAS_TRANSMIT_AS |
  2779. HAS_REPRESENT_AS |
  2780. HAS_INTERFACE_PTR |
  2781. HAS_MULTIDIM_SIZING |
  2782. HAS_ARRAY_OF_REF ) )
  2783. {
  2784. Complexity |= FLD_COMPLEX;
  2785. }
  2786. if ( pCommand->NeedsNDR64Run() )
  2787. {
  2788. if ( MyContext.AnyDescendantBits( HAS_UNSAT_REP_AS ) )
  2789. {
  2790. RpcSemError( this, MyContext, UNSPECIFIED_EMBEDDED_REPRESENT_AS_NOT_SUPPORTED, NULL );
  2791. }
  2792. }
  2793. MyContext.ClearDescendantBits( HAS_ARRAY | HAS_MULTIDIM_VECTOR );
  2794. MyContext.SetDescendantBits( HAS_STRUCT );
  2795. pParentCtxt->ReturnValues( MyContext );
  2796. fBeingAnalyzed = FALSE;
  2797. }
  2798. // note: this lets HAS_UNION propogate up to any enclosing structs
  2799. void
  2800. node_en_struct::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  2801. {
  2802. MEM_ITER MemIter( this );
  2803. node_skl * pN;
  2804. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  2805. if ( fBeingAnalyzed )
  2806. {
  2807. // if we hit the same node more than once (it can only be through a ptr),
  2808. // and the ptr type is ref, we flag an error; recursive defn. through a ref ptr.
  2809. if ( !MyContext.AnyAncestorBits( IN_NON_REF_PTR ) &&
  2810. MyContext.AnyAncestorBits( IN_RPC ) )
  2811. {
  2812. TypeSemError( this, MyContext, RECURSION_THRU_REF, NULL );
  2813. }
  2814. return;
  2815. }
  2816. fBeingAnalyzed = TRUE;
  2817. MyContext.ExtractAttribute(ATTR_HELPCONTEXT);
  2818. MyContext.ExtractAttribute(ATTR_HELPSTRINGCONTEXT);
  2819. MyContext.ExtractAttribute( ATTR_HELPSTRING );
  2820. if (MyContext.ExtractAttribute(ATTR_HELPSTRINGDLL))
  2821. {
  2822. SemError(this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  2823. }
  2824. CheckDeclspecAlign( MyContext );
  2825. node_guid * pGuid = (node_guid *) MyContext.ExtractAttribute( ATTR_GUID );
  2826. // make sure the UUID is unique
  2827. if ( pGuid )
  2828. {
  2829. node_skl* pDuplicate = GetDuplicateGuid( pGuid, pUUIDTable );
  2830. if ( pDuplicate )
  2831. {
  2832. SemError(this, MyContext, DUPLICATE_UUID, pDuplicate->GetSymName());
  2833. }
  2834. }
  2835. if (pCommand->IsSwitchDefined(SWITCH_MKTYPLIB))
  2836. CheckLegalParent(MyContext);
  2837. MyContext.SetAncestorBits( IN_STRUCT );
  2838. // See if context_handle applied to param reached us
  2839. if ( CheckContextHandle( MyContext ) )
  2840. {
  2841. MyContext.SetDescendantBits( HAS_HANDLE | HAS_CONTEXT_HANDLE );
  2842. }
  2843. while ( ( pN = MemIter.GetNext() ) != 0 )
  2844. {
  2845. pN->SemanticAnalysis( &MyContext );
  2846. };
  2847. if ( pCommand->NeedsNDR64Run() )
  2848. {
  2849. if ( MyContext.AnyDescendantBits( HAS_UNSAT_REP_AS ) )
  2850. {
  2851. RpcSemError( this, MyContext, UNSPECIFIED_EMBEDDED_REPRESENT_AS_NOT_SUPPORTED, NULL );
  2852. }
  2853. }
  2854. if ( MyContext.AnyDescendantBits( HAS_POINTER ) )
  2855. SetHasAtLeastOnePointer( TRUE );
  2856. pParentCtxt->ReturnValues( MyContext );
  2857. fBeingAnalyzed = FALSE;
  2858. }
  2859. void
  2860. node_union::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  2861. {
  2862. MEM_ITER MemIter( this );
  2863. node_field * pN;
  2864. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  2865. BOOL fEncap = IsEncapsulatedUnion();
  2866. node_switch_type * pSwTypeAttr = (node_switch_type *) MyContext.ExtractAttribute( ATTR_SWITCH_TYPE );
  2867. node_switch_is * pSwIsAttr = (node_switch_is *) MyContext.ExtractAttribute( ATTR_SWITCH_IS );
  2868. BOOL NonEmptyArm = FALSE;
  2869. BOOL HasCases = FALSE;
  2870. BOOL HasBadExpr = FALSE;
  2871. if ( HasCorrelation( this ) )
  2872. {
  2873. MyContext.IncCorrelationCount();
  2874. }
  2875. if (pCommand->IsSwitchDefined(SWITCH_MKTYPLIB))
  2876. CheckLegalParent(MyContext);
  2877. MyContext.ExtractAttribute(ATTR_TYPEDESCATTR);
  2878. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  2879. MyContext.ExtractAttribute(ATTR_HELPCONTEXT);
  2880. MyContext.ExtractAttribute(ATTR_HELPSTRINGCONTEXT);
  2881. MyContext.ExtractAttribute( ATTR_HELPSTRING );
  2882. if (MyContext.ExtractAttribute(ATTR_HELPSTRINGDLL))
  2883. {
  2884. SemError(this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  2885. }
  2886. if ( MyContext.ExtractAttribute( ATTR_HIDDEN ) )
  2887. {
  2888. SemError(this, MyContext, NEWLYFOUND_INAPPLICABLE_ATTRIBUTE, 0);
  2889. }
  2890. if ( MyContext.ExtractAttribute( ATTR_VERSION ) )
  2891. {
  2892. SemError(this, MyContext, NEWLYFOUND_INAPPLICABLE_ATTRIBUTE, 0);
  2893. }
  2894. if ( fBeingAnalyzed )
  2895. {
  2896. // if we hit the same node more than once (it can only be through a ptr),
  2897. // and the ptr type is ref, we flag an error; recursive defn. through a ref ptr.
  2898. if ( !MyContext.AnyAncestorBits( IN_NON_REF_PTR ) &&
  2899. MyContext.AnyAncestorBits( IN_RPC ) )
  2900. {
  2901. TypeSemError( this, MyContext, RECURSION_THRU_REF, NULL );
  2902. }
  2903. return;
  2904. }
  2905. fBeingAnalyzed = TRUE;
  2906. CheckDeclspecAlign( MyContext );
  2907. if ( pSwIsAttr )
  2908. {
  2909. EXPR_CTXT SwCtxt( &MyContext );
  2910. expr_node * pSwIsExpr = pSwIsAttr->GetExpr();
  2911. pSwIsExpr->ExprAnalyze( &SwCtxt );
  2912. if ( SwCtxt.AnyUpFlags( EX_UNSAT_FWD ) )
  2913. {
  2914. TypeSemError( this,
  2915. MyContext,
  2916. ATTRIBUTE_ID_UNRESOLVED,
  2917. pSwIsAttr->GetNodeNameString() );
  2918. HasBadExpr = TRUE;
  2919. }
  2920. if ( !SwCtxt.AnyUpFlags( EX_VALUE_INVALID ) )
  2921. {
  2922. TypeSemError( this,
  2923. MyContext,
  2924. ATTRIBUTE_ID_MUST_BE_VAR,
  2925. pSwIsAttr->GetNodeNameString() );
  2926. HasBadExpr = TRUE;
  2927. }
  2928. }
  2929. // if they left off the switch_type, take it from the switch_is type
  2930. if ( !pSwTypeAttr && !fEncap && pSwIsAttr && !HasBadExpr )
  2931. {
  2932. node_skl * pSwIsType = pSwIsAttr->GetSwitchIsType();
  2933. MIDL_ASSERT( pSwIsType || !"no type for switch_is expr");
  2934. if ( ( pSwIsType->NodeKind() == NODE_FIELD ) ||
  2935. ( pSwIsType->NodeKind() == NODE_PARAM ) )
  2936. pSwIsType = pSwIsType->GetChild();
  2937. pSwTypeAttr = new node_switch_type( pSwIsType );
  2938. SetAttribute( pSwTypeAttr );
  2939. }
  2940. if ( pSwIsAttr && pSwTypeAttr && !HasBadExpr )
  2941. {
  2942. node_skl * pSwIsType = pSwIsAttr->GetSwitchIsType();
  2943. node_skl * pSwType = pSwTypeAttr->GetType();
  2944. pSwIsType = pSwIsType->GetBasicType();
  2945. if ( pSwIsType && pSwIsType->IsBasicType() && pSwType->IsBasicType() )
  2946. {
  2947. if ( !((node_base_type *)pSwType)
  2948. ->IsAssignmentCompatible( (node_base_type *) pSwIsType ) )
  2949. TypeSemError( this, MyContext, SWITCH_TYPE_MISMATCH, NULL );
  2950. }
  2951. if ( !pSwType || !Xxx_Is_Type_OK( pSwType ) )
  2952. {
  2953. TypeSemError( this,
  2954. MyContext,
  2955. SWITCH_IS_TYPE_IS_WRONG,
  2956. pSwType ? pSwType->GetSymName() : NULL );
  2957. }
  2958. if ( !pSwIsType || !Xxx_Is_Type_OK( pSwIsType ) )
  2959. {
  2960. TypeSemError( this,
  2961. MyContext,
  2962. SWITCH_IS_TYPE_IS_WRONG,
  2963. pSwIsType ? pSwIsType->GetSymName() : NULL );
  2964. }
  2965. }
  2966. // We don't care about local: it can be anything.
  2967. if ( MyContext.AnyAncestorBits( IN_RPC ) )
  2968. {
  2969. if ( !fEncap && !pSwTypeAttr && !pSwIsAttr )
  2970. {
  2971. if ( MyContext.AnyAncestorBits( IN_PARAM_LIST ) )
  2972. RpcSemError( this, MyContext, NON_RPC_UNION, NULL );
  2973. else
  2974. RpcSemError( this, MyContext, NON_RPC_RTYPE_UNION, NULL );
  2975. }
  2976. if ( !fEncap &&
  2977. MyContext.AnyAncestorBits( IN_FUNCTION_RESULT ) &&
  2978. !MyContext.AnyAncestorBits( IN_STRUCT | IN_UNION ) )
  2979. RpcSemError( this, MyContext, RETURN_OF_UNIONS_ILLEGAL, NULL );
  2980. if ( pSwTypeAttr && !pSwIsAttr )
  2981. RpcSemError( this, MyContext, NO_SWITCH_IS, NULL );
  2982. }
  2983. // See if context_handle applied to param reached us
  2984. if ( CheckContextHandle( MyContext ) )
  2985. {
  2986. MyContext.SetDescendantBits( HAS_HANDLE | HAS_CONTEXT_HANDLE );
  2987. }
  2988. MyContext.MarkImportantPosition();
  2989. if ( MyContext.AllAncestorBits( IN_INTERFACE | IN_NE_UNION ) )
  2990. {
  2991. RpcSemError( this, MyContext, NE_UNION_FIELD_NE_UNION, NULL );
  2992. }
  2993. if ( ( MyContext.FindNonDefAncestorContext()->GetParent()
  2994. ->NodeKind() == NODE_UNION ) &&
  2995. MyContext.AnyAncestorBits( IN_INTERFACE ) )
  2996. {
  2997. RpcSemError( this, MyContext, ARRAY_OF_UNIONS_ILLEGAL, NULL );
  2998. }
  2999. MyContext.SetAncestorBits( IN_UNION | IN_NE_UNION );
  3000. MyContext.SetDescendantBits( HAS_UNION );
  3001. // eat the union flavor determiner
  3002. MyContext.ExtractAttribute( ATTR_MS_UNION );
  3003. while ( ( pN = (node_field *) MemIter.GetNext() ) != 0 )
  3004. {
  3005. // tbd - put cases into case database...
  3006. // tbd - check type, range, and duplication
  3007. pN->SemanticAnalysis( &MyContext );
  3008. if ( !NonEmptyArm && !pN->IsEmptyArm() )
  3009. NonEmptyArm = TRUE;
  3010. if ( !HasCases && (pN->FInSummary( ATTR_CASE ) || pN->FInSummary( ATTR_DEFAULT ) ) )
  3011. HasCases = TRUE;
  3012. }
  3013. // at least one arm should be non-empty
  3014. if ( !NonEmptyArm )
  3015. SemError( this, MyContext, UNION_NO_FIELDS, NULL );
  3016. if ( !fEncap && !pSwTypeAttr && !HasCases )
  3017. RpcSemError( this, MyContext, BAD_CON_NON_RPC_UNION, NULL );
  3018. // disallow forward references as union members
  3019. if ( MyContext.AnyDescendantBits( HAS_INCOMPLETE_TYPE ) )
  3020. {
  3021. if (! MyContext.AnyAncestorBits( IN_LIBRARY ))
  3022. SemError( this, MyContext, UNDEFINED_SYMBOL, NULL );
  3023. MyContext.ClearDescendantBits( HAS_INCOMPLETE_TYPE );
  3024. }
  3025. MyContext.ClearDescendantBits( HAS_RECURSIVE_DEF );
  3026. if ( MyContext.AnyDescendantBits( HAS_POINTER ) )
  3027. SetHasAtLeastOnePointer( TRUE );
  3028. if ( MyContext.AnyDescendantBits( HAS_CONF_ARRAY | HAS_CONF_VAR_ARRAY ) )
  3029. {
  3030. RpcSemError( this, MyContext, BAD_CON_UNION_FIELD_CONF , NULL );
  3031. }
  3032. if ( pCommand->NeedsNDR64Run() )
  3033. {
  3034. if ( MyContext.AnyDescendantBits( HAS_UNSAT_REP_AS ) )
  3035. {
  3036. RpcSemError( this, MyContext, UNSPECIFIED_EMBEDDED_REPRESENT_AS_NOT_SUPPORTED, NULL );
  3037. }
  3038. }
  3039. // clear flags not affecting complexity above
  3040. MyContext.ClearDescendantBits( HAS_POINTER |
  3041. HAS_CONF_PTR |
  3042. HAS_VAR_PTR |
  3043. HAS_CONF_VAR_PTR |
  3044. HAS_MULTIDIM_SIZING |
  3045. HAS_MULTIDIM_VECTOR |
  3046. HAS_ARRAY_OF_REF |
  3047. HAS_ENUM |
  3048. HAS_DIRECT_CONF_OR_VAR |
  3049. HAS_ARRAY |
  3050. HAS_REPRESENT_AS |
  3051. HAS_TRANSMIT_AS |
  3052. HAS_CONF_VAR_ARRAY |
  3053. HAS_CONF_ARRAY |
  3054. HAS_VAR_ARRAY );
  3055. pParentCtxt->ReturnValues( MyContext );
  3056. fBeingAnalyzed = FALSE;
  3057. }
  3058. void
  3059. node_en_union::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  3060. {
  3061. MEM_ITER MemIter( this );
  3062. node_field * pN;
  3063. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  3064. node_switch_type* pSwTypeAttr = ( node_switch_type* ) MyContext.ExtractAttribute( ATTR_SWITCH_TYPE );
  3065. node_skl * pSwType;
  3066. node_switch_is* pSwIsAttr = ( node_switch_is* ) MyContext.ExtractAttribute( ATTR_SWITCH_IS );
  3067. BOOL NonEmptyArm = FALSE;
  3068. if ( HasCorrelation( this ) )
  3069. {
  3070. MyContext.IncCorrelationCount();
  3071. }
  3072. // gaj - tbd do semantic checks on these attributes
  3073. MyContext.ExtractAttribute( ATTR_HELPSTRING );
  3074. MyContext.ExtractAttribute( ATTR_HELPSTRINGCONTEXT );
  3075. MyContext.ExtractAttribute( ATTR_HELPCONTEXT );
  3076. if (MyContext.ExtractAttribute(ATTR_HELPSTRINGDLL))
  3077. {
  3078. SemError(this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  3079. }
  3080. node_guid * pGuid = (node_guid *) MyContext.ExtractAttribute( ATTR_GUID );
  3081. // make sure the UUID is unique
  3082. if ( pGuid )
  3083. {
  3084. node_skl* pDuplicate = GetDuplicateGuid( pGuid, pUUIDTable );
  3085. if ( pDuplicate )
  3086. {
  3087. SemError(this, MyContext, DUPLICATE_UUID, pDuplicate->GetSymName());
  3088. }
  3089. }
  3090. if ( fBeingAnalyzed )
  3091. {
  3092. // if we hit the same node more than once (it can only be through a ptr),
  3093. // and the ptr type is ref, we flag an error; recursive defn. through a ref ptr.
  3094. if ( !MyContext.AnyAncestorBits( IN_NON_REF_PTR ) &&
  3095. MyContext.AnyAncestorBits( IN_RPC ) )
  3096. {
  3097. TypeSemError( this, MyContext, RECURSION_THRU_REF, NULL );
  3098. }
  3099. return;
  3100. }
  3101. fBeingAnalyzed = TRUE;
  3102. CheckDeclspecAlign( MyContext );
  3103. if ( pSwTypeAttr )
  3104. {
  3105. pSwType = pSwTypeAttr->GetSwitchType();
  3106. if ( !pSwType ||
  3107. !Xxx_Is_Type_OK( pSwType ) ||
  3108. pSwType->NodeKind() == NODE_BYTE )
  3109. {
  3110. TypeSemError( this,
  3111. MyContext,
  3112. SWITCH_IS_TYPE_IS_WRONG,
  3113. pSwType ? pSwType->GetSymName() : NULL );
  3114. }
  3115. }
  3116. if ( pSwIsAttr )
  3117. {
  3118. EXPR_CTXT SwCtxt( &MyContext );
  3119. expr_node * pSwIsExpr = pSwIsAttr->GetExpr();
  3120. pSwIsExpr->ExprAnalyze( &SwCtxt );
  3121. if ( SwCtxt.AnyUpFlags( EX_UNSAT_FWD ) )
  3122. TypeSemError( this,
  3123. MyContext,
  3124. ATTRIBUTE_ID_UNRESOLVED,
  3125. pSwIsAttr->GetNodeNameString() );
  3126. if ( !SwCtxt.AnyUpFlags( EX_VALUE_INVALID ) )
  3127. TypeSemError( this,
  3128. MyContext,
  3129. ATTRIBUTE_ID_MUST_BE_VAR,
  3130. pSwIsAttr->GetNodeNameString() );
  3131. }
  3132. MyContext.MarkImportantPosition();
  3133. MyContext.SetAncestorBits( IN_UNION );
  3134. MyContext.SetDescendantBits( HAS_UNION );
  3135. while ( ( pN = (node_field *) MemIter.GetNext() ) != 0 )
  3136. {
  3137. // tbd - put cases into case database...
  3138. // tbd - check type, range, and duplication
  3139. pN->SemanticAnalysis( &MyContext );
  3140. if ( !pN->IsEmptyArm() )
  3141. NonEmptyArm = TRUE;
  3142. }
  3143. // at least one arm should be non-empty
  3144. if ( !NonEmptyArm )
  3145. SemError( this, MyContext, UNION_NO_FIELDS, NULL );
  3146. // remember if we have a pointer
  3147. if ( MyContext.AnyDescendantBits( HAS_POINTER ) )
  3148. SetHasAtLeastOnePointer( TRUE );
  3149. if ( MyContext.AnyDescendantBits( HAS_CONF_ARRAY | HAS_CONF_VAR_ARRAY ) )
  3150. {
  3151. RpcSemError( this, MyContext, BAD_CON_UNION_FIELD_CONF , NULL );
  3152. }
  3153. // clear flags not affecting complexity above
  3154. MyContext.ClearDescendantBits( HAS_POINTER |
  3155. HAS_CONF_PTR |
  3156. HAS_VAR_PTR |
  3157. HAS_CONF_VAR_PTR |
  3158. HAS_MULTIDIM_SIZING |
  3159. HAS_MULTIDIM_VECTOR |
  3160. HAS_ARRAY_OF_REF |
  3161. HAS_ENUM |
  3162. HAS_DIRECT_CONF_OR_VAR |
  3163. HAS_ARRAY |
  3164. HAS_REPRESENT_AS |
  3165. HAS_TRANSMIT_AS |
  3166. HAS_CONF_VAR_ARRAY |
  3167. HAS_CONF_ARRAY |
  3168. HAS_VAR_ARRAY );
  3169. pParentCtxt->ReturnValues( MyContext );
  3170. fBeingAnalyzed = FALSE;
  3171. }
  3172. void
  3173. node_def::SemanticAnalysisForTransmit(
  3174. SEM_ANALYSIS_CTXT * pMyContext,
  3175. BOOL fPresented )
  3176. {
  3177. if ( fPresented )
  3178. {
  3179. // the presented type may not be conformant.
  3180. if ( pMyContext->AnyDescendantBits( HAS_VAR_ARRAY
  3181. | HAS_CONF_ARRAY
  3182. | HAS_CONF_VAR_ARRAY ) )
  3183. TypeSemError( this, *pMyContext, TRANSMIT_TYPE_CONF, NULL );
  3184. }
  3185. else
  3186. {
  3187. // transmitted type may not have a pointer.
  3188. if ( pMyContext->AnyDescendantBits( HAS_POINTER | HAS_INTERFACE_PTR ) )
  3189. TypeSemError( this,*pMyContext, TRANSMIT_AS_POINTER, NULL );
  3190. // transmitted type may not derive from void
  3191. if ( pMyContext->AnyDescendantBits( DERIVES_FROM_VOID ) )
  3192. TypeSemError( this, *pMyContext, TRANSMIT_AS_VOID, NULL );
  3193. }
  3194. }
  3195. void
  3196. node_def::SemanticAnalysisForWireMarshal(
  3197. SEM_ANALYSIS_CTXT * pMyContext,
  3198. BOOL fPresented )
  3199. {
  3200. if ( fPresented )
  3201. {
  3202. // We need to check if the presented type is not void; note, void * is ok.
  3203. }
  3204. else
  3205. {
  3206. // We check only the transmitted type for wire_marshal, user marshal.
  3207. //
  3208. // The transmitted type must not have full pointers, since
  3209. // the app has no mechanism to generate the full pointer ids.
  3210. // BUG, BUG semantic analysis treats arrays in structures
  3211. // as pointers. Change to error once the bug is fixed.
  3212. if ( pMyContext->AnyDescendantBits( HAS_FULL_PTR ) )
  3213. TypeSemError( this, *pMyContext, WIRE_HAS_FULL_PTR, NULL);
  3214. // The wire type must have a fully defined memory size. It cannot be
  3215. // conformant or conformant varying. Arrays have a problem
  3216. // in that the app can't marshal the MaxCount, Actual Count, or Offset properly.
  3217. if ( pMyContext->AnyDescendantBits( HAS_CONF_ARRAY
  3218. | HAS_CONF_VAR_ARRAY ) )
  3219. TypeSemError( this, *pMyContext, WIRE_NOT_DEFINED_SIZE, NULL);
  3220. // transmitted type may not derive from void
  3221. if ( pMyContext->AnyDescendantBits( DERIVES_FROM_VOID ) )
  3222. TypeSemError( this, *pMyContext, TRANSMIT_AS_VOID, NULL );
  3223. }
  3224. }
  3225. void
  3226. node_def::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  3227. {
  3228. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  3229. BOOL fInRpc = MyContext.AnyAncestorBits( IN_RPC );
  3230. BOOL fInPresented = MyContext.AnyAncestorBits( IN_PRESENTED_TYPE );
  3231. SEM_ANALYSIS_CTXT * pIntfCtxt = (SEM_ANALYSIS_CTXT *)
  3232. MyContext.GetInterfaceContext();
  3233. node_represent_as * pRepresent = (node_represent_as *)
  3234. MyContext.ExtractAttribute( ATTR_REPRESENT_AS );
  3235. node_transmit * pTransmit = (node_transmit *)
  3236. MyContext.ExtractAttribute( ATTR_TRANSMIT );
  3237. node_user_marshal * pUserMarshal = (node_user_marshal *)
  3238. MyContext.ExtractAttribute( ATTR_USER_MARSHAL );
  3239. node_wire_marshal * pWireMarshal = (node_wire_marshal *)
  3240. MyContext.ExtractAttribute( ATTR_WIRE_MARSHAL );
  3241. BOOL fRepMarshal = pRepresent || pUserMarshal;
  3242. BOOL fXmitMarshal = pTransmit || pWireMarshal;
  3243. BOOL fEncodeDecode = (NULL != MyContext.ExtractAttribute( ATTR_ENCODE ));
  3244. MyContext.ExtractAttribute(ATTR_HELPSTRING);
  3245. MyContext.ExtractAttribute( ATTR_HELPCONTEXT );
  3246. MyContext.ExtractAttribute( ATTR_HELPSTRINGCONTEXT );
  3247. // Partial ignore may not be used directly on an xmit or rep as.
  3248. if (MyContext.AnyAncestorBits( UNDER_PARTIAL_IGNORE_PARAM ) &&
  3249. ( fRepMarshal || fXmitMarshal ) )
  3250. {
  3251. SemError( this, MyContext, PARTIAL_IGNORE_UNIQUE, 0 );
  3252. }
  3253. if (MyContext.ExtractAttribute(ATTR_HELPSTRINGDLL))
  3254. {
  3255. SemError(this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  3256. }
  3257. if ( HasCorrelation( this ) )
  3258. {
  3259. MyContext.IncCorrelationCount();
  3260. }
  3261. CheckDeclspecAlign( MyContext );
  3262. node_range_attr* pRange = ( node_range_attr* ) MyContext.GetAttribute(ATTR_RANGE);
  3263. if ( pRange )
  3264. {
  3265. if ( pRange->GetMinExpr()->GetValue() > pRange->GetMaxExpr()->GetValue() )
  3266. {
  3267. SemError(this, MyContext, INCORRECT_RANGE_DEFN, 0);
  3268. }
  3269. }
  3270. BOOL fPropogateChild = TRUE; // propogate direct child info
  3271. unsigned long ulHandleKind;
  3272. // check for illegal type attributes
  3273. node_type_attr * pTA;
  3274. while ( ( pTA = (node_type_attr *)MyContext.ExtractAttribute(ATTR_TYPE) ) != 0 )
  3275. {
  3276. switch (pTA->GetAttr())
  3277. {
  3278. // acceptable attributes
  3279. case TATTR_PUBLIC:
  3280. {
  3281. break;
  3282. }
  3283. // unacceptable attributes
  3284. case TATTR_LICENSED:
  3285. case TATTR_OLEAUTOMATION:
  3286. case TATTR_APPOBJECT:
  3287. case TATTR_CONTROL:
  3288. case TATTR_PROXY:
  3289. case TATTR_DUAL:
  3290. case TATTR_NONEXTENSIBLE:
  3291. case TATTR_NONCREATABLE:
  3292. case TATTR_AGGREGATABLE:
  3293. {
  3294. char * pAttrName = pTA->GetNodeNameString();
  3295. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, pAttrName);
  3296. break;
  3297. }
  3298. }
  3299. }
  3300. // check for illegal member attributes
  3301. node_member_attr * pMA;
  3302. while ( ( pMA = (node_member_attr *)MyContext.ExtractAttribute(ATTR_MEMBER) ) != 0 )
  3303. {
  3304. switch (pMA->GetAttr())
  3305. {
  3306. case MATTR_RESTRICTED:
  3307. break;
  3308. case MATTR_OPTIONAL:
  3309. case MATTR_RETVAL:
  3310. case MATTR_BINDABLE:
  3311. case MATTR_DISPLAYBIND:
  3312. case MATTR_DEFAULTBIND:
  3313. case MATTR_REQUESTEDIT:
  3314. case MATTR_PROPGET:
  3315. case MATTR_PROPPUT:
  3316. case MATTR_PROPPUTREF:
  3317. case MATTR_VARARG:
  3318. case MATTR_SOURCE:
  3319. case MATTR_DEFAULTVTABLE:
  3320. case MATTR_PREDECLID:
  3321. case MATTR_UIDEFAULT:
  3322. case MATTR_NONBROWSABLE:
  3323. case MATTR_DEFAULTCOLLELEM:
  3324. case MATTR_USESGETLASTERROR:
  3325. case MATTR_IMMEDIATEBIND:
  3326. case MATTR_REPLACEABLE:
  3327. default:
  3328. {
  3329. char * pAttrName = pMA->GetNodeNameString();
  3330. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, pAttrName);
  3331. break;
  3332. }
  3333. }
  3334. }
  3335. #if defined(TARGET_RKK)
  3336. // Checking the release compatibility
  3337. if ( pCommand->GetTargetSystem() < NT40 )
  3338. {
  3339. if ( pWireMarshal )
  3340. SemError( this, MyContext, REQUIRES_NT40, "[wire_marshal]" );
  3341. if ( pUserMarshal )
  3342. SemError( this, MyContext, REQUIRES_NT40, "[user_marshal]" );
  3343. }
  3344. if ( pCommand->GetTargetSystem() < NT351 )
  3345. {
  3346. if ( fEncodeDecode )
  3347. SemError( this, MyContext, REQUIRES_NT351, "[encode,decode]" );
  3348. }
  3349. #endif
  3350. MyContext.ExtractAttribute(ATTR_TYPEDESCATTR);
  3351. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  3352. // clear the GUID, VERSION and HIDDEN attributes if set
  3353. MyContext.ExtractAttribute( ATTR_HIDDEN );
  3354. MyContext.ExtractAttribute( ATTR_VERSION );
  3355. MyContext.ExtractAttribute( ATTR_HELPCONTEXT);
  3356. MyContext.ExtractAttribute( ATTR_HELPSTRINGCONTEXT);
  3357. node_guid * pGuid = (node_guid *) MyContext.ExtractAttribute( ATTR_GUID );
  3358. // make sure the UUID is unique
  3359. if ( pGuid )
  3360. {
  3361. node_skl* pDuplicate = GetDuplicateGuid( pGuid, pUUIDTable );
  3362. if ( pDuplicate )
  3363. {
  3364. SemError(this, MyContext, DUPLICATE_UUID, pDuplicate->GetSymName());
  3365. }
  3366. }
  3367. // get the encode and decode attributes
  3368. fEncodeDecode |= (NULL != MyContext.ExtractAttribute( ATTR_DECODE ));
  3369. fEncodeDecode |= pIntfCtxt->FInSummary( ATTR_ENCODE );
  3370. fEncodeDecode |= pIntfCtxt->FInSummary( ATTR_DECODE );
  3371. if ( fEncodeDecode )
  3372. {
  3373. // only direct children of the interface get these bits
  3374. if ( !pParentCtxt->GetParent()->IsInterfaceOrObject() )
  3375. {
  3376. fEncodeDecode = FALSE;
  3377. }
  3378. else if (MyContext.AnyAncestorBits( IN_OBJECT_INTF ) )
  3379. {
  3380. fEncodeDecode = FALSE;
  3381. TypeSemError( this, MyContext, PICKLING_INVALID_IN_OBJECT, NULL );
  3382. }
  3383. else
  3384. {
  3385. // note that this is an rpc-able interface
  3386. GetMyInterfaceNode()->SetPickleInterface();
  3387. MyContext.SetAncestorBits( IN_RPC );
  3388. }
  3389. SemError( this, MyContext, TYPE_PICKLING_INVALID_IN_OSF, NULL );
  3390. BOOL HasV2Optimize = pCommand->GetOptimizationFlags() & OPTIMIZE_INTERPRETER_V2;
  3391. if ( pCommand->IsSwitchDefined( SWITCH_ROBUST ) )
  3392. {
  3393. if ( HasV2Optimize )
  3394. {
  3395. pCommand->GetNdrVersionControl().SetHasOicfPickling();
  3396. }
  3397. else
  3398. {
  3399. SemError( this, MyContext, ROBUST_PICKLING_NO_OICF, 0 );
  3400. }
  3401. }
  3402. BOOL HasCommFault = MyContext.FInSummary( ATTR_COMMSTAT )
  3403. || MyContext.FInSummary( ATTR_FAULTSTAT );
  3404. if ( HasCommFault && !HasV2Optimize)
  3405. {
  3406. SemError( this, MyContext, COMMFAULT_PICKLING_NO_OICF, 0 );
  3407. }
  3408. }
  3409. // kind of handle applied right now (HandleKind only set for ones on this
  3410. // typedef node)
  3411. if ( FInSummary(ATTR_HANDLE) )
  3412. {
  3413. MyContext.ExtractAttribute( ATTR_HANDLE );
  3414. SetHandleKind( HDL_GEN );
  3415. }
  3416. bool fSerialize = MyContext.ExtractAttribute( ATTR_SERIALIZE ) != 0;
  3417. bool fNoSerialize = MyContext.ExtractAttribute( ATTR_NOSERIALIZE ) != 0;
  3418. // See if context_handle applied to param reached us
  3419. if ( FInSummary(ATTR_CONTEXT) )
  3420. {
  3421. if ( ( GetHandleKind() != HDL_NONE ) &&
  3422. ( GetHandleKind() != HDL_CTXT ) )
  3423. TypeSemError( this, MyContext, CTXT_HDL_GENERIC_HDL, NULL );
  3424. MyContext.ExtractAttribute( ATTR_CONTEXT );
  3425. if ( fSerialize && fNoSerialize )
  3426. {
  3427. SemError( this, MyContext, CONFLICTING_ATTRIBUTES, GetSymName() );
  3428. }
  3429. SetHandleKind( HDL_CTXT );
  3430. // since the base type is not transmitted, we aren't really
  3431. // in an rpc after here
  3432. MyContext.ClearAncestorBits( IN_RPC );
  3433. }
  3434. else
  3435. {
  3436. if ( fSerialize || fNoSerialize )
  3437. {
  3438. SemError( this, MyContext, NO_CONTEXT_HANDLE, GetSymName() );
  3439. }
  3440. }
  3441. ulHandleKind = GetHandleKind();
  3442. if ( ulHandleKind != HDL_NONE )
  3443. {
  3444. MyContext.SetAncestorBits( IN_HANDLE );
  3445. }
  3446. // effectively, the presented type is NOT involved in an RPC
  3447. if ( fXmitMarshal )
  3448. {
  3449. MyContext.ClearAncestorBits( IN_RPC );
  3450. MyContext.SetAncestorBits( IN_PRESENTED_TYPE );
  3451. if ( MyContext.FInSummary( ATTR_ALLOCATE ) )
  3452. AcfError( (acf_attr *) MyContext.ExtractAttribute( ATTR_ALLOCATE ),
  3453. this,
  3454. MyContext,
  3455. ALLOCATE_ON_TRANSMIT_AS,
  3456. NULL );
  3457. if ( GetHandleKind() == HDL_CTXT )
  3458. TypeSemError( this, MyContext, TRANSMIT_AS_CTXT_HANDLE, NULL );
  3459. }
  3460. if ( MyContext.ExtractAttribute( ATTR_CSCHAR ) )
  3461. {
  3462. if ( MyContext.AnyAncestorBits( UNDER_IN_PARAM ) )
  3463. MyContext.SetDescendantBits( HAS_IN_CSTYPE );
  3464. if ( MyContext.AnyAncestorBits( UNDER_OUT_PARAM ) )
  3465. MyContext.SetDescendantBits( HAS_OUT_CSTYPE );
  3466. }
  3467. // process the child
  3468. GetChild()->SemanticAnalysis( &MyContext );
  3469. if (pCommand->IsSwitchDefined(SWITCH_MKTYPLIB))
  3470. {
  3471. switch (GetChild()->NodeKind())
  3472. {
  3473. case NODE_STRUCT:
  3474. case NODE_UNION:
  3475. case NODE_ENUM:
  3476. {
  3477. // This is the 'typedef' part of a 'typedef struct',
  3478. // 'typedef union', or 'typedef enum' declaration.
  3479. // Make sure that the type info name is set to the name of the
  3480. // typedef and not the child.
  3481. ((node_su_base *)GetChild())->SetTypeInfoName(GetSymName());
  3482. }
  3483. break;
  3484. }
  3485. }
  3486. else
  3487. {
  3488. if (GetChild()->GetSymName() && IsTempName(GetChild()->GetSymName()))
  3489. {
  3490. // Make sure that at least the [public] attribute is
  3491. // set on this typedef, forcing this typedef to be put
  3492. // in a type library if it is referenced from within one.
  3493. SetAttribute(new node_type_attr(TATTR_PUBLIC));
  3494. }
  3495. }
  3496. /* yongqu: don't enable this before we read custom data.
  3497. if ( GetChild()->NodeKind() == NODE_INT3264 )
  3498. {
  3499. SetAttribute( GetCustomAttrINT3264() );
  3500. }
  3501. */
  3502. // process all the nasties of transmit_as and wire_marshal
  3503. if ( fXmitMarshal && !fInPresented && fInRpc )
  3504. {
  3505. SEM_ANALYSIS_CTXT TransmitContext( &MyContext );
  3506. // eat the attributes added by the above constructor
  3507. TransmitContext.ClearAttributes();
  3508. // process the transmitted type
  3509. TransmitContext.SetAncestorBits( IN_TRANSMIT_AS );
  3510. if ( pWireMarshal )
  3511. TransmitContext.SetAncestorBits( IN_USER_MARSHAL );
  3512. TransmitContext.ClearAncestorBits( IN_PRESENTED_TYPE );
  3513. if ( fInRpc)
  3514. TransmitContext.SetAncestorBits( IN_RPC );
  3515. if ( pTransmit )
  3516. pTransmit->GetType()->SemanticAnalysis( &TransmitContext );
  3517. else if ( pWireMarshal )
  3518. pWireMarshal->GetType()->SemanticAnalysis( &TransmitContext );
  3519. else
  3520. MIDL_ASSERT(0);
  3521. if ( pTransmit )
  3522. {
  3523. // check the transmitted type.
  3524. SemanticAnalysisForTransmit( &TransmitContext, FALSE );
  3525. // Check the presented type.
  3526. SemanticAnalysisForTransmit( &MyContext, TRUE );
  3527. }
  3528. else if ( pWireMarshal )
  3529. {
  3530. // check the transmitted type
  3531. SemanticAnalysisForWireMarshal( &TransmitContext, FALSE );
  3532. // check the presented type
  3533. SemanticAnalysisForWireMarshal( &MyContext, TRUE );
  3534. }
  3535. else {
  3536. MIDL_ASSERT(0);
  3537. }
  3538. if ( TransmitContext.AnyDescendantBits( HAS_HANDLE ) )
  3539. {
  3540. //gaj TypeSemError( this, MyContext, HANDLE_T_XMIT, NULL );
  3541. }
  3542. if ( TransmitContext.AnyDescendantBits( HAS_TRANSMIT_AS ) )
  3543. {
  3544. TypeSemError( this, MyContext, TRANSMIT_AS_NON_RPCABLE, NULL );
  3545. }
  3546. TransmitContext.SetDescendantBits( HAS_TRANSMIT_AS );
  3547. // since the base type is not transmitted, we aren't really
  3548. // in an rpc after here
  3549. pParentCtxt->ReturnValues( TransmitContext );
  3550. fPropogateChild = FALSE;
  3551. }
  3552. // process all the nasties of represent_as and user_marshal
  3553. if ( fRepMarshal )
  3554. {
  3555. node_represent_as * pRepUser = (pRepresent) ? pRepresent
  3556. : pUserMarshal ;
  3557. if ( ulHandleKind == HDL_CTXT )
  3558. AcfError( pRepUser, this, MyContext, TRANSMIT_AS_CTXT_HANDLE, NULL );
  3559. // process the transmitted type
  3560. MyContext.SetAncestorBits( IN_REPRESENT_AS );
  3561. if ( pUserMarshal )
  3562. MyContext.SetAncestorBits( IN_USER_MARSHAL );
  3563. pParentCtxt->SetDescendantBits( HAS_REPRESENT_AS );
  3564. if ( !pRepUser->GetRepresentationType() )
  3565. {
  3566. pParentCtxt->SetDescendantBits( HAS_UNSAT_REP_AS );
  3567. if ( pCommand->NeedsNDR64Run() )
  3568. {
  3569. AcfError( pRepUser, this, MyContext, UNSPECIFIED_REP_OR_UMRSHL_IN_NDR64, NULL );
  3570. }
  3571. }
  3572. if ( pUserMarshal )
  3573. {
  3574. // Check the transmitted type.
  3575. SemanticAnalysisForWireMarshal( &MyContext, FALSE );
  3576. }
  3577. else if ( pRepresent )
  3578. {
  3579. // Check the transmitted type.
  3580. SemanticAnalysisForTransmit( &MyContext, FALSE );
  3581. }
  3582. // since the base type is not transmitted, we aren't really
  3583. // in an rpc after here
  3584. }
  3585. // make checks for encode/decode
  3586. if ( fEncodeDecode )
  3587. {
  3588. if ( MyContext.AnyDescendantBits( HAS_DIRECT_CONF_OR_VAR ) )
  3589. TypeSemError( this, MyContext, ENCODE_CONF_OR_VAR, NULL );
  3590. }
  3591. // process handles
  3592. if ( ulHandleKind != HDL_NONE)
  3593. {
  3594. if ( ulHandleKind == HDL_GEN )
  3595. {
  3596. if ( MyContext.AnyDescendantBits( DERIVES_FROM_VOID ) )
  3597. TypeSemError( this, MyContext, GENERIC_HDL_VOID, NULL );
  3598. if ( MyContext.AnyDescendantBits( HAS_TRANSMIT_AS ) )
  3599. TypeSemError( this, MyContext, GENERIC_HANDLE_XMIT_AS, NULL );
  3600. if ( MyContext.AnyAncestorBits( IN_INTERPRET ) &&
  3601. ( GetChild()->GetSize() > (unsigned long)(SIZEOF_MEM_PTR()) ) )
  3602. {
  3603. if ( pCommand->NeedsNDR64Run() )
  3604. TypeSemError( this, MyContext, UNSUPPORTED_LARGE_GENERIC_HANDLE, NULL );
  3605. else
  3606. MyContext.SetDescendantBits( HAS_TOO_BIG_HDL );
  3607. }
  3608. }
  3609. if ( ulHandleKind == HDL_CTXT )
  3610. {
  3611. MyContext.SetDescendantBits( HAS_CONTEXT_HANDLE );
  3612. if ( GetBasicType()->NodeKind() != NODE_POINTER )
  3613. TypeSemError( this, MyContext, CTXT_HDL_NON_PTR, NULL );
  3614. }
  3615. MyContext.SetDescendantBits( HAS_HANDLE );
  3616. WALK_CTXT * pParamCtxt = (SEM_ANALYSIS_CTXT *)
  3617. MyContext.GetParentContext();
  3618. node_param * pParamNode;
  3619. node_skl * pCurNode;
  3620. short PtrDepth = 0;
  3621. // this returns NULL if no appropriate ancestor found
  3622. while ( pParamCtxt )
  3623. {
  3624. pCurNode = pParamCtxt->GetParent();
  3625. if ( pCurNode->NodeKind() == NODE_PARAM )
  3626. break;
  3627. if ( ( pCurNode->NodeKind() == NODE_DEF ) &&
  3628. pCurNode->FInSummary( ATTR_TRANSMIT ) )
  3629. {
  3630. pParamCtxt = NULL;
  3631. break;
  3632. }
  3633. if ( pCurNode->NodeKind() == NODE_POINTER )
  3634. {
  3635. PtrDepth ++;
  3636. if ( MyContext.AllAncestorBits( IN_RPC | IN_FUNCTION_RESULT ) )
  3637. {
  3638. SemError( this, MyContext, CTXT_HDL_MUST_BE_DIRECT_RETURN, NULL );
  3639. pParamCtxt = NULL;
  3640. break;
  3641. }
  3642. }
  3643. pParamCtxt = (SEM_ANALYSIS_CTXT *)pParamCtxt->GetParentContext();
  3644. }
  3645. pParamNode = (pParamCtxt) ? (node_param *) pParamCtxt->GetParent() : NULL;
  3646. // stuff handle info into our param node
  3647. if ( pParamNode )
  3648. pParamNode->HandleKind = ulHandleKind;
  3649. // out context/generic handles must be two levels deep
  3650. if ( pParamCtxt &&
  3651. MyContext.AnyAncestorBits( UNDER_OUT_PARAM ) &&
  3652. ( PtrDepth < 1 ) )
  3653. TypeSemError( this, MyContext, OUT_CONTEXT_GENERIC_HANDLE, NULL );
  3654. }
  3655. if ( IsHResultOrSCode() )
  3656. {
  3657. MyContext.SetDescendantBits( HAS_HRESULT );
  3658. }
  3659. // don't propogate info here from below if we had transmit_as,
  3660. // it is propogated above...
  3661. if ( fPropogateChild )
  3662. {
  3663. pParentCtxt->ReturnValues( MyContext );
  3664. }
  3665. // set the DontCallFreeInst flag on the param
  3666. if ( ( pTransmit || pRepresent ) &&
  3667. fInRpc &&
  3668. MyContext.AllAncestorBits( IN_PARAM_LIST ) &&
  3669. !MyContext.AnyAncestorBits( UNDER_OUT_PARAM ) )
  3670. {
  3671. // look up the context stack. If any non-pointer, non-def found,
  3672. // set the fDontCallFreeInst flag on the param
  3673. MarkDontCallFreeInst( &MyContext );
  3674. }
  3675. }
  3676. // look up the context stack. If any non-pointer, non-def found,
  3677. // set the fDontCallFreeInst flag on the param
  3678. void
  3679. node_def::MarkDontCallFreeInst( SEM_ANALYSIS_CTXT * pCtxt )
  3680. {
  3681. SEM_ANALYSIS_CTXT * pCurCtxt = pCtxt;
  3682. node_skl * pCurNode;
  3683. NODE_T Kind;
  3684. unsigned long MarkIt = 2;
  3685. for(;;)
  3686. {
  3687. pCurCtxt = (SEM_ANALYSIS_CTXT *) pCurCtxt->GetParentContext();
  3688. pCurNode = pCurCtxt->GetParent();
  3689. Kind = pCurNode->NodeKind();
  3690. switch ( Kind )
  3691. {
  3692. case NODE_DEF:
  3693. case NODE_POINTER:
  3694. break;
  3695. case NODE_PARAM:
  3696. // if we only found defs and pointers, this will
  3697. // leave it unchanged
  3698. ((node_param *)pCurNode)->fDontCallFreeInst |= MarkIt;
  3699. return;
  3700. default:
  3701. MarkIt = 1;
  3702. break;
  3703. }
  3704. }
  3705. }
  3706. // interface nodes have two entries on the context stack;
  3707. // one for the interface node, and one for info to pass to
  3708. // the children
  3709. void
  3710. node_interface::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  3711. {
  3712. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  3713. MEM_ITER MemList( this );
  3714. named_node* pN;
  3715. SEM_ANALYSIS_CTXT ChildCtxt( &MyContext );
  3716. BOOL IsLocal = MyContext.FInSummary( ATTR_LOCAL );
  3717. BOOL HasGuid = MyContext.FInSummary( ATTR_GUID );
  3718. BOOL IsObject = MyContext.FInSummary( ATTR_OBJECT );
  3719. BOOL fEncode = MyContext.FInSummary( ATTR_ENCODE );
  3720. BOOL fDecode = MyContext.FInSummary( ATTR_DECODE );
  3721. BOOL IsPickle = fEncode || fDecode;
  3722. BOOL HasVersion = MyContext.FInSummary( ATTR_VERSION );
  3723. BOOL IsIUnknown = FALSE;
  3724. BOOL fAuto = MyContext.FInSummary( ATTR_AUTO );
  3725. BOOL fCode = MyContext.FInSummary( ATTR_CODE );
  3726. BOOL fNoCode = MyContext.FInSummary( ATTR_NOCODE );
  3727. fHasMSConfStructAttr = fHasMSConfStructAttr || MyContext.ExtractAttribute( ATTR_MS_CONF_STRUCT ) != 0;
  3728. node_implicit* pImplicit = ( node_implicit* ) MyContext.GetAttribute( ATTR_IMPLICIT );
  3729. acf_attr* pExplicit = ( acf_attr* ) MyContext.GetAttribute( ATTR_EXPLICIT );
  3730. node_optimize* pOptAttr = 0;
  3731. bool fAnalizeAsyncIf = false;
  3732. node_cs_tag_rtn* pCSTagAttr = 0;
  3733. // [message] only allowed in ORPC interfaces and RPC procs.
  3734. node_base_attr* pTemp = MyContext.GetAttribute( ATTR_MESSAGE );
  3735. if ( pTemp )
  3736. {
  3737. if ( !IsObject )
  3738. {
  3739. SemError(
  3740. this,
  3741. MyContext,
  3742. INAPPLICABLE_ATTRIBUTE,
  3743. pTemp->GetNodeNameString()
  3744. );
  3745. }
  3746. ChildCtxt.SetAncestorBits( HAS_MESSAGE );
  3747. }
  3748. // process async_uuid before doing anything
  3749. if ( !IsAsyncClone() )
  3750. {
  3751. node_guid* pAsyncGuid = (node_guid*) MyContext.GetAttribute( ATTR_ASYNCUUID );
  3752. if ( pAsyncGuid )
  3753. {
  3754. if ( GetDefiningFile()->GetImportLevel() == 0 )
  3755. {
  3756. pCommand->GetNdrVersionControl().SetHasAsyncUUID();
  3757. }
  3758. ChildCtxt.SetAncestorBits( HAS_ASYNC_UUID );
  3759. // async_uuid can only be applied to an object interface.
  3760. if ( !IsObject || !pBaseIntf )
  3761. {
  3762. SemError(
  3763. this,
  3764. MyContext,
  3765. INAPPLICABLE_ATTRIBUTE,
  3766. pAsyncGuid->GetNodeNameString()
  3767. );
  3768. }
  3769. if ( !GetAsyncInterface() )
  3770. {
  3771. // duplicate this interface and split its methods
  3772. SetAsyncInterface( CloneIFAndSplitMethods( this ) );
  3773. if ( GetAsyncInterface() )
  3774. {
  3775. fAnalizeAsyncIf = true;
  3776. GetAsyncInterface()->SetIsAsyncClone();
  3777. }
  3778. }
  3779. }
  3780. }
  3781. else
  3782. {
  3783. // This is the cloned interface, don't clone it again.
  3784. ChildCtxt.SetAncestorBits( HAS_ASYNC_UUID );
  3785. }
  3786. while( MyContext.ExtractAttribute(ATTR_CUSTOM) )
  3787. ;
  3788. MyContext.ExtractAttribute( ATTR_TYPEDESCATTR );
  3789. MyContext.ExtractAttribute( ATTR_HIDDEN );
  3790. MyContext.ExtractAttribute( ATTR_VERSION );
  3791. MyContext.ExtractAttribute( ATTR_HELPSTRING );
  3792. MyContext.ExtractAttribute( ATTR_HELPSTRINGCONTEXT );
  3793. MyContext.ExtractAttribute( ATTR_HELPCONTEXT );
  3794. MyContext.ExtractAttribute( ATTR_LCID );
  3795. if (MyContext.ExtractAttribute(ATTR_HELPSTRINGDLL))
  3796. {
  3797. SemError(this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  3798. }
  3799. // don't pass the interface attributes down directly...
  3800. // pass them down elsewhere
  3801. ChildCtxt.SetInterfaceContext( &MyContext );
  3802. //
  3803. // check the interface attributes
  3804. //
  3805. // make sure we only get analyzed once when object interfaces
  3806. // check their inherited info
  3807. if ( fSemAnalyzed )
  3808. return;
  3809. fSemAnalyzed = TRUE;
  3810. #ifdef gajgaj
  3811. // look for pointer default
  3812. if ( !FInSummary( ATTR_PTR_KIND ) &&
  3813. MyContext.AnyAncestorBits( IN_INTERFACE ) )
  3814. {
  3815. RpcSemError(this, MyContext, NO_PTR_DEFAULT_ON_INTERFACE, NULL );
  3816. }
  3817. #endif // gajgaj
  3818. // must have exactly one of [local] or [UUID]
  3819. if (IsLocal && HasGuid && !IsObject )
  3820. {
  3821. SemError( this, MyContext, UUID_LOCAL_BOTH_SPECIFIED, NULL );
  3822. }
  3823. // object interface error checking
  3824. if ( IsObject )
  3825. {
  3826. MyContext.SetAncestorBits( IN_OBJECT_INTF );
  3827. ChildCtxt.SetAncestorBits( IN_OBJECT_INTF );
  3828. if ( HasVersion )
  3829. {
  3830. SemError( this, MyContext, OBJECT_WITH_VERSION, NULL );
  3831. }
  3832. }
  3833. // make sure the uuid is unique
  3834. node_guid * pGuid = (node_guid *) MyContext.ExtractAttribute( ATTR_GUID );
  3835. // make sure the UUID is unique
  3836. if ( pGuid )
  3837. {
  3838. node_skl* pDuplicate = GetDuplicateGuid( pGuid, pUUIDTable );
  3839. if ( pDuplicate )
  3840. {
  3841. SemError(this, MyContext, DUPLICATE_UUID, pDuplicate->GetSymName());
  3842. }
  3843. }
  3844. /////////////////////////////////////////////////////////////////////
  3845. //Check the base interface
  3846. if (pBaseIntf)
  3847. {
  3848. if ( !IsObject && !MyContext.AnyAncestorBits(IN_LIBRARY))
  3849. {
  3850. SemError( this, MyContext, ILLEGAL_INTERFACE_DERIVATION, NULL );
  3851. }
  3852. ChildCtxt.SetAncestorBits( IN_BASE_CLASS );
  3853. pBaseIntf->SemanticAnalysis( &ChildCtxt );
  3854. if ( ChildCtxt.AnyDescendantBits( HAS_INCOMPLETE_TYPE ) )
  3855. {
  3856. SemError( pBaseIntf, ChildCtxt, UNRESOLVED_TYPE, pBaseIntf->GetSymName() );
  3857. }
  3858. else
  3859. {
  3860. if ( pBaseIntf->NodeKind() != NODE_INTERFACE_REFERENCE && pBaseIntf->NodeKind() != NODE_HREF )
  3861. {
  3862. SemError( this, MyContext, ILLEGAL_BASE_INTERFACE, NULL );
  3863. }
  3864. node_interface* pRealBaseIf = ( ( node_interface_reference* ) pBaseIntf )->GetRealInterface();
  3865. // verify the base interface is really an interface.
  3866. if ( pRealBaseIf == NULL || ( pRealBaseIf->NodeKind() != NODE_INTERFACE &&
  3867. pRealBaseIf->NodeKind() != NODE_DISPINTERFACE ) )
  3868. {
  3869. SemError( this, MyContext, ILLEGAL_BASE_INTERFACE, NULL );
  3870. }
  3871. if ( fAnalizeAsyncIf )
  3872. {
  3873. if ( pBaseIntf->NodeKind() != NODE_INTERFACE_REFERENCE )
  3874. {
  3875. SemError( this, MyContext, ILLEGAL_BASE_INTERFACE, NULL );
  3876. }
  3877. else
  3878. {
  3879. node_interface* pRealBaseIf = ( ( node_interface_reference* ) pBaseIntf )->GetRealInterface();
  3880. if ( !pRealBaseIf->GetAsyncInterface() && strcmp( pRealBaseIf->GetSymName(), "IUnknown" ) )
  3881. {
  3882. SemError( this, MyContext, ILLEGAL_BASE_INTERFACE, NULL );
  3883. }
  3884. }
  3885. }
  3886. if ( pBaseIntf->NodeKind() == NODE_INTERFACE_REFERENCE && HasGuid )
  3887. {
  3888. node_interface* pRealBaseIf = ( ( node_interface_reference* ) pBaseIntf )->GetRealInterface();
  3889. if ( pRealBaseIf )
  3890. {
  3891. node_guid * pNodeGuid = (node_guid *) pRealBaseIf->GetAttribute( ATTR_GUID );
  3892. if ( pNodeGuid )
  3893. {
  3894. GUID thisGuid;
  3895. pGuid->GetGuid( thisGuid );
  3896. GUID baseIFGuid;
  3897. pNodeGuid->GetGuid( baseIFGuid );
  3898. if ( !IsAnyIAdviseSinkIID( thisGuid ) )
  3899. {
  3900. if ( IsAnyIAdviseSinkIID( baseIFGuid ) )
  3901. {
  3902. SemError( this, MyContext, CANNOT_INHERIT_IADVISESINK, pBaseIntf->GetSymName() );
  3903. }
  3904. }
  3905. else
  3906. {
  3907. ChildCtxt.SetAncestorBits( IN_IADVISESINK );
  3908. }
  3909. }
  3910. }
  3911. }
  3912. }
  3913. // note that the above deletes intervening forwards
  3914. ChildCtxt.ClearAncestorBits( IN_BASE_CLASS );
  3915. }
  3916. if ( IsValidRootInterface() )
  3917. {
  3918. ChildCtxt.SetAncestorBits( IN_ROOT_CLASS );
  3919. IsIUnknown = TRUE;
  3920. }
  3921. if ( IsObject && !pBaseIntf && !IsIUnknown && !MyContext.AnyAncestorBits(IN_LIBRARY))
  3922. {
  3923. SemError( pBaseIntf, MyContext, ILLEGAL_INTERFACE_DERIVATION, NULL );
  3924. }
  3925. // our optimization is controlled either here or for the whole compile
  3926. if ( IsAsyncClone() )
  3927. {
  3928. SetOptimizationFlags( OPTIMIZE_ALL_I2_FLAGS );
  3929. }
  3930. else
  3931. {
  3932. if ( ( pOptAttr = (node_optimize *) GetAttribute( ATTR_OPTIMIZE ) ) != 0 )
  3933. {
  3934. SetOptimizationFlags( pOptAttr->GetOptimizationFlags() );
  3935. SetOptimizationLevel( pOptAttr->GetOptimizationLevel() );
  3936. }
  3937. else
  3938. {
  3939. SetOptimizationFlags( pCommand->GetOptimizationFlags() );
  3940. SetOptimizationLevel( pCommand->GetOptimizationLevel() );
  3941. }
  3942. }
  3943. if ( MyContext.FInSummary( ATTR_NOCODE ) &&
  3944. pCommand->GenerateSStub() &&
  3945. !pCommand->IsSwitchDefined( SWITCH_MS_EXT ) )
  3946. {
  3947. SemError( this, MyContext, NOCODE_WITH_SERVER_STUBS, NULL );
  3948. }
  3949. if ( IsPickle && pCommand->IsSwitchDefined( SWITCH_ROBUST ) )
  3950. {
  3951. if ( GetOptimizationFlags() & OPTIMIZE_INTERPRETER_V2 )
  3952. {
  3953. pCommand->GetNdrVersionControl().SetHasOicfPickling();
  3954. }
  3955. else
  3956. {
  3957. SemError(this, MyContext, ROBUST_PICKLING_NO_OICF, 0);
  3958. }
  3959. }
  3960. BOOL HasCommFault = MyContext.FInSummary( ATTR_COMMSTAT )
  3961. || MyContext.FInSummary( ATTR_FAULTSTAT );
  3962. if ( HasCommFault )
  3963. {
  3964. if ( ! ( GetOptimizationFlags() & OPTIMIZE_INTERPRETER_V2 ) )
  3965. {
  3966. SemError( this, MyContext, COMMFAULT_PICKLING_NO_OICF, 0 );
  3967. }
  3968. }
  3969. // mark the interface as a pickle interface
  3970. if ( IsPickle )
  3971. SetPickleInterface();
  3972. // default the handle type, if needed
  3973. if ( !IsObject && !pImplicit && !pExplicit && !fAuto && !IsLocal )
  3974. {
  3975. if ( IsPickleInterface() )
  3976. {
  3977. pExplicit = new acf_attr( ATTR_EXPLICIT );
  3978. SetAttribute( pExplicit );
  3979. }
  3980. else
  3981. {
  3982. fAuto = TRUE;
  3983. SetAttribute( new acf_attr( ATTR_AUTO ) );
  3984. }
  3985. }
  3986. // make sure no pickle w/ auto handle
  3987. if ( IsPickleInterface() )
  3988. {
  3989. ChildCtxt.SetAncestorBits( IN_ENCODE_INTF );
  3990. if ( fAuto )
  3991. SemError( this, MyContext, ENCODE_AUTO_HANDLE, NULL );
  3992. }
  3993. // check for handle conflicts
  3994. if ( ( fAuto && pImplicit ) ||
  3995. ( fAuto && pExplicit ) ||
  3996. ( pImplicit && pExplicit ) )
  3997. SemError( this, MyContext, CONFLICTING_INTF_HANDLES, NULL );
  3998. if ( pImplicit )
  3999. {
  4000. node_id * pID;
  4001. node_skl * pType;
  4002. pImplicit->ImplicitHandleDetails( &pType, &pID );
  4003. char* szName = pType->GetNonDefSelf()->GetSymName();
  4004. if ( pImplicit->IsHandleTypeDefined() )
  4005. {
  4006. if ( !pType->FInSummary( ATTR_HANDLE ) &&
  4007. strcmp( szName, "handle_t" ) &&
  4008. !pID->FInSummary( ATTR_HANDLE ) )
  4009. {
  4010. SemError( this, MyContext, IMPLICIT_HANDLE_NON_HANDLE, NULL );
  4011. }
  4012. }
  4013. else
  4014. {
  4015. if ( !pID->FInSummary( ATTR_HANDLE ) )
  4016. SemError( this, MyContext, IMPLICIT_HDL_ASSUMED_GENERIC, NULL );
  4017. }
  4018. }
  4019. if ( fAuto )
  4020. {
  4021. ChildCtxt.SetAncestorBits( HAS_AUTO_HANDLE );
  4022. }
  4023. else if ( pExplicit )
  4024. {
  4025. ChildCtxt.SetAncestorBits( HAS_EXPLICIT_HANDLE );
  4026. }
  4027. else if ( pImplicit )
  4028. {
  4029. ChildCtxt.SetAncestorBits( HAS_IMPLICIT_HANDLE );
  4030. }
  4031. // check for illegal type attributes
  4032. node_type_attr * pTA;
  4033. BOOL fIsDual = FALSE;
  4034. while ( ( pTA = (node_type_attr *)MyContext.ExtractAttribute(ATTR_TYPE) ) != 0 )
  4035. {
  4036. switch (pTA->GetAttr())
  4037. {
  4038. // acceptable attributes
  4039. case TATTR_DUAL:
  4040. fIsDual = TRUE;
  4041. // fall through
  4042. case TATTR_OLEAUTOMATION:
  4043. HasOLEAutomation(TRUE);
  4044. break;
  4045. case TATTR_PROXY:
  4046. case TATTR_PUBLIC:
  4047. case TATTR_NONEXTENSIBLE:
  4048. break;
  4049. // unacceptable attributes
  4050. case TATTR_CONTROL:
  4051. case TATTR_LICENSED:
  4052. {
  4053. char * pAttrName = pTA->GetNodeNameString();
  4054. SemError( this, MyContext, NEWLYFOUND_INAPPLICABLE_ATTRIBUTE, pAttrName);
  4055. break;
  4056. }
  4057. case TATTR_APPOBJECT:
  4058. case TATTR_NONCREATABLE:
  4059. case TATTR_AGGREGATABLE:
  4060. {
  4061. char * pAttrName = pTA->GetNodeNameString();
  4062. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, pAttrName);
  4063. break;
  4064. }
  4065. }
  4066. }
  4067. if (HasOLEAutomation())
  4068. {
  4069. node_interface* pUltimate = 0;
  4070. node_interface* pIntf = this;
  4071. STATUS_T ErrorCode = NOT_OLEAUTOMATION_INTERFACE;
  4072. while ( pIntf )
  4073. {
  4074. pUltimate = pIntf;
  4075. pIntf = pIntf->GetMyBaseInterface();
  4076. if ( !pUltimate->IsValidRootInterface() )
  4077. {
  4078. // pUltimate is not IUnknown. If it is not a IDispatch either, it is not
  4079. // an oleautomation compliant interface.
  4080. char* szName = pUltimate->GetSymName();
  4081. if ( _stricmp(szName, "IDispatch") == 0 )
  4082. {
  4083. ErrorCode = STATUS_OK;
  4084. break;
  4085. }
  4086. }
  4087. else
  4088. {
  4089. // IUnknown could be OLEAUTOMATION compatible, but not DUAL
  4090. if ( fIsDual )
  4091. ErrorCode = NOT_DUAL_INTERFACE;
  4092. else
  4093. ErrorCode = STATUS_OK;
  4094. break;
  4095. }
  4096. }
  4097. if ( ErrorCode != STATUS_OK )
  4098. SemError( this, MyContext, ErrorCode, GetSymName() );
  4099. ChildCtxt.SetAncestorBits( HAS_OLEAUTOMATION );
  4100. }
  4101. // check for illegal member attributes
  4102. node_member_attr * pMA;
  4103. while ( ( pMA = (node_member_attr *)MyContext.ExtractAttribute(ATTR_MEMBER) ) != 0 )
  4104. {
  4105. switch (pMA->GetAttr())
  4106. {
  4107. case MATTR_RESTRICTED:
  4108. break;
  4109. case MATTR_DEFAULTVTABLE:
  4110. case MATTR_SOURCE:
  4111. {
  4112. if ( MyContext.AnyAncestorBits( IN_COCLASS ) )
  4113. // [source] and [defaultvtable] are only allowed on
  4114. // interface's defined as members of coclasses.
  4115. break;
  4116. // illegal attribute, so fall through
  4117. }
  4118. case MATTR_READONLY:
  4119. {
  4120. char * pAttrName = pMA->GetNodeNameString();
  4121. SemError( this, MyContext, NEWLYFOUND_INAPPLICABLE_ATTRIBUTE, pAttrName);
  4122. break;
  4123. }
  4124. case MATTR_BINDABLE:
  4125. case MATTR_DISPLAYBIND:
  4126. case MATTR_DEFAULTBIND:
  4127. case MATTR_REQUESTEDIT:
  4128. case MATTR_PROPGET:
  4129. case MATTR_PROPPUT:
  4130. case MATTR_PROPPUTREF:
  4131. case MATTR_OPTIONAL:
  4132. case MATTR_RETVAL:
  4133. case MATTR_VARARG:
  4134. case MATTR_PREDECLID:
  4135. case MATTR_UIDEFAULT:
  4136. case MATTR_NONBROWSABLE:
  4137. case MATTR_DEFAULTCOLLELEM:
  4138. case MATTR_IMMEDIATEBIND:
  4139. case MATTR_USESGETLASTERROR:
  4140. case MATTR_REPLACEABLE:
  4141. {
  4142. char * pAttrName = pMA->GetNodeNameString();
  4143. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, pAttrName);
  4144. break;
  4145. }
  4146. }
  4147. }
  4148. node_base_attr* pAttrAsync = MyContext.ExtractAttribute( ATTR_ASYNC );
  4149. if ( pAttrAsync )
  4150. {
  4151. if ( !pAttrAsync->IsAcfAttr() )
  4152. {
  4153. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  4154. }
  4155. if ( fCode || fNoCode || IsLocal || pOptAttr || IsObject || HasOLEAutomation() )
  4156. {
  4157. SemError( this, MyContext, ILLEGAL_COMBINATION_OF_ATTRIBUTES, 0 );
  4158. }
  4159. ChildCtxt.SetAncestorBits( HAS_ASYNCHANDLE );
  4160. }
  4161. pCSTagAttr = ( node_cs_tag_rtn *) MyContext.ExtractAttribute( ATTR_CSTAGRTN );
  4162. ////////////////////////////////////////////////////////////////////////
  4163. // process all the children of the interface
  4164. //
  4165. while ( ( pN = MemList.GetNext() ) != 0 )
  4166. {
  4167. pN->SemanticAnalysis( &ChildCtxt );
  4168. // Set the cs tag routine for the proc if it needs one and doesn't
  4169. // have one yet
  4170. if ( NODE_PROC == pN->NodeKind() )
  4171. {
  4172. node_proc *pProc = ( node_proc * ) pN;
  4173. if ( ChildCtxt.AnyDescendantBits( HAS_IN_CSTYPE | HAS_OUT_CSTYPE )
  4174. && ( NULL == pProc->GetCSTagRoutine() )
  4175. && ( NULL != pCSTagAttr ) )
  4176. {
  4177. pProc->SetCSTagRoutine( pCSTagAttr->GetCSTagRoutine() );
  4178. }
  4179. }
  4180. }
  4181. // make sure we had some rpc-able routines
  4182. if ( IsObject )
  4183. {
  4184. //UUID must be specified on object procs.
  4185. if( !HasGuid )
  4186. {
  4187. SemError( this, MyContext, NO_UUID_SPECIFIED, NULL );
  4188. }
  4189. }
  4190. else if( MyContext.AnyAncestorBits( IN_INTERFACE ) &&
  4191. pCommand->GenerateStubs() &&
  4192. !IsLocal )
  4193. {
  4194. if ( ProcCount == 0 )
  4195. {
  4196. if ( !IsPickleInterface() &&
  4197. !IsObject )
  4198. {
  4199. if (CallBackProcCount == 0 )
  4200. {
  4201. SemError( this, MyContext, NO_REMOTE_PROCS_NO_STUBS, NULL );
  4202. }
  4203. else
  4204. {
  4205. SemError( this, MyContext, INTERFACE_ONLY_CALLBACKS, NULL );
  4206. }
  4207. }
  4208. }
  4209. else
  4210. {
  4211. //UUID must be specified when interface has remote procs.
  4212. if( !HasGuid )
  4213. {
  4214. SemError( this, MyContext, NO_UUID_SPECIFIED, NULL );
  4215. }
  4216. }
  4217. }
  4218. if (pExplicit && MyContext.AnyAncestorBits( IN_LIBRARY ))
  4219. {
  4220. SemError(this, MyContext, INAPPLICABLE_ATTRIBUTE, NULL);
  4221. }
  4222. if (fCode && fNoCode)
  4223. {
  4224. SemError(this, MyContext, CODE_NOCODE_CONFLICT, NULL);
  4225. }
  4226. if ( IsObject )
  4227. {
  4228. unsigned short uProcCount = GetProcCount();
  4229. if ( GetFileNode() && GetFileNode()->GetImportLevel() > 0 )
  4230. {
  4231. if ( uProcCount > 64 && uProcCount <= 256 )
  4232. {
  4233. pCommand->GetNdrVersionControl().SetHasMoreThan64DelegatedProcs();
  4234. }
  4235. else if ( uProcCount > 256 )
  4236. {
  4237. SemError(this, MyContext, TOO_MANY_DELEGATED_PROCS, NULL);
  4238. }
  4239. }
  4240. // method limits apply only to stubless proxies. /Oicf not /Oi or /Os
  4241. /*
  4242. < 32 Windows NT 3.51-
  4243. 32 - 110 Windows NT 4.0
  4244. 110 - 512 Windows NT 4.0 SP3
  4245. > 512 Windows 2000
  4246. */
  4247. unsigned short uOpt = GetOptimizationFlags();
  4248. if ( GetFileNode() && GetFileNode()->GetImportLevel() == 0 && ( uOpt & OPTIMIZE_STUBLESS_CLIENT ) )
  4249. {
  4250. if ( (uProcCount > 512) && MyContext.AnyAncestorBits(IN_LIBRARY))
  4251. {
  4252. SemError(this, MyContext, TOO_MANY_PROCS, 0);
  4253. pCommand->GetNdrVersionControl().SetHasNT5VTableSize();
  4254. }
  4255. else if ( (uProcCount > 110) && (uProcCount <= 512) && MyContext.AnyAncestorBits(IN_LIBRARY))
  4256. {
  4257. SemError(this, MyContext, TOO_MANY_PROCS_FOR_NT4, 0);
  4258. pCommand->GetNdrVersionControl().SetHasNT43VTableSize();
  4259. }
  4260. else if ( uProcCount > 32 && uProcCount <= 110 )
  4261. {
  4262. pCommand->GetNdrVersionControl().SetHasNT4VTableSize();
  4263. }
  4264. }
  4265. }
  4266. if ( GetAsyncInterface() && fAnalizeAsyncIf )
  4267. {
  4268. GetAsyncInterface()->SemanticAnalysis( pParentCtxt );
  4269. }
  4270. MyContext.ReturnValues(ChildCtxt);
  4271. // consume all the interface attributes
  4272. MyContext.ClearAttributes();
  4273. pParentCtxt->ReturnValues( MyContext );
  4274. }
  4275. // a reference to an interface...
  4276. //Check for ms_ext mode.
  4277. //Check if the interface has the [object] attribute
  4278. //if used in an RPC, the parent must be a pointer.
  4279. void
  4280. node_interface_reference::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  4281. {
  4282. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  4283. CheckDeclspecAlign( MyContext );
  4284. // see if we are detecting class dependencies
  4285. if ( MyContext.AnyAncestorBits( IN_BASE_CLASS ) )
  4286. {
  4287. if ( !GetRealInterface()->FInSummary( ATTR_OBJECT ) && !MyContext.AnyAncestorBits(IN_LIBRARY))
  4288. {
  4289. SemError( this, MyContext, ILLEGAL_INTERFACE_DERIVATION, NULL );
  4290. }
  4291. // fetch my interface's BaseInteraceReference
  4292. named_node * pBaseClass = GetMyBaseInterfaceReference();
  4293. if ( pBaseClass )
  4294. {
  4295. if ( MyContext.FindRecursiveContext( pBaseClass ) )
  4296. SemError( this, MyContext, CIRCULAR_INTERFACE_DEPENDENCY, NULL);
  4297. else
  4298. {
  4299. // make sure our base class got analyzed
  4300. SEM_ANALYSIS_CTXT BaseContext( this, &MyContext );
  4301. BaseContext.ClearAncestorBits( IN_BASE_CLASS | IN_INTERFACE );
  4302. BaseContext.SetInterfaceContext( &BaseContext );
  4303. GetRealInterface()->SemanticAnalysis( &BaseContext );
  4304. pBaseClass->SemanticAnalysis( &MyContext );
  4305. }
  4306. }
  4307. else // root base class
  4308. {
  4309. if ( !GetRealInterface()->IsValidRootInterface() && !MyContext.AnyAncestorBits(IN_LIBRARY))
  4310. SemError( this, MyContext, NOT_VALID_AS_BASE_INTF, NULL );
  4311. }
  4312. }
  4313. else if ( ( pParentCtxt->GetParent()->NodeKind() == NODE_FORWARD ) &&
  4314. ( pParentCtxt->GetParentContext()->GetParent()->IsInterfaceOrObject() ) )
  4315. {
  4316. // we are an interface forward decl
  4317. }
  4318. else // we are at an interface pointer
  4319. {
  4320. node_interface * pIntf = GetRealInterface();
  4321. if ( !MyContext.AnyAncestorBits( IN_POINTER ) && !MyContext.AnyAncestorBits( IN_LIBRARY ))
  4322. {
  4323. SemError( this, MyContext, INTF_NON_POINTER, NULL );
  4324. }
  4325. if ( !pIntf->FInSummary( ATTR_GUID ) )
  4326. {
  4327. SemError( this, MyContext, PTR_INTF_NO_GUID, NULL );
  4328. }
  4329. MyContext.SetDescendantBits( HAS_INTERFACE_PTR );
  4330. }
  4331. pParentCtxt->ReturnValues( MyContext );
  4332. return;
  4333. };
  4334. void
  4335. node_source::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  4336. {
  4337. MEM_ITER MemIter( this );
  4338. node_skl * pN;
  4339. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  4340. while ( ( pN = MemIter.GetNext() ) != 0 )
  4341. {
  4342. pN->SemanticAnalysis( &MyContext );
  4343. }
  4344. pParentCtxt->ReturnValues( MyContext );
  4345. };
  4346. void
  4347. node_pointer::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  4348. {
  4349. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  4350. PTRTYPE PtrKind = PTR_UNKNOWN;
  4351. FIELD_ATTR_INFO FAInfo;
  4352. node_ptr_attr * pPAttr; // pointer attribute
  4353. node_byte_count * pCountAttr;
  4354. node_allocate * pAlloc;
  4355. BOOL fInterfacePtr = (GetChild()->NodeKind() == NODE_INTERFACE_REFERENCE );
  4356. BOOL fUnderAPtr = MyContext.AnyAncestorBits( IN_POINTER | IN_ARRAY );
  4357. BOOL fIgnore;
  4358. BOOL fIsSizedPtr = FALSE;
  4359. // see if we have allocate
  4360. pAlloc = (node_allocate *) MyContext.ExtractAttribute( ATTR_ALLOCATE );
  4361. if ( HasCorrelation( this ) )
  4362. {
  4363. MyContext.IncCorrelationCount();
  4364. }
  4365. CheckDeclspecAlign( MyContext );
  4366. ////////////////////////////////////////////////////////////////////////
  4367. // process pointer attributes
  4368. BOOL fExplicitPtrAttr = FALSE;
  4369. PtrKind = MyContext.GetPtrKind( &fExplicitPtrAttr );
  4370. if ( PtrKind == PTR_FULL )
  4371. {
  4372. MyContext.SetDescendantBits( HAS_FULL_PTR );
  4373. }
  4374. if ( ( pPAttr = (node_ptr_attr *)MyContext.ExtractAttribute( ATTR_PTR_KIND) ) != 0 )
  4375. {
  4376. TypeSemError( this, MyContext, MORE_THAN_ONE_PTR_ATTR, NULL );
  4377. }
  4378. if ( MyContext.AnyAncestorBits( UNDER_PARTIAL_IGNORE_PARAM ) &&
  4379. ( PtrKind != PTR_UNIQUE ) )
  4380. {
  4381. TypeSemError( this, MyContext, PARTIAL_IGNORE_UNIQUE, NULL );
  4382. }
  4383. MyContext.ClearAncestorBits( UNDER_PARTIAL_IGNORE_PARAM );
  4384. // mark this pointer as ref or non-ref. This flag is only valid for the
  4385. // pointer nodes themselves.
  4386. if ( PtrKind == PTR_REF )
  4387. MyContext.ClearAncestorBits( IN_NON_REF_PTR );
  4388. else
  4389. MyContext.SetAncestorBits( IN_NON_REF_PTR );
  4390. // detect top level ref pointer on return type
  4391. if ( ( PtrKind == PTR_REF ) &&
  4392. MyContext.AllAncestorBits( IN_RPC | IN_FUNCTION_RESULT ) )
  4393. {
  4394. if (MyContext.FindNonDefAncestorContext()->GetParent()->NodeKind()
  4395. == NODE_PROC )
  4396. TypeSemError( this, MyContext, BAD_CON_REF_RT, NULL );
  4397. }
  4398. // unique or full pointer may not be out only
  4399. if ( ( PtrKind != PTR_REF ) &&
  4400. MyContext.AllAncestorBits( IN_RPC | IN_PARAM_LIST ) &&
  4401. !fUnderAPtr &&
  4402. !MyContext.AnyAncestorBits( UNDER_IN_PARAM |
  4403. IN_STRUCT | IN_UNION ))
  4404. TypeSemError( this, MyContext, UNIQUE_FULL_PTR_OUT_ONLY, NULL );
  4405. MyContext.SetAncestorBits( IN_POINTER );
  4406. // warn about OUT const things
  4407. if ( FInSummary( ATTR_CONST ) )
  4408. {
  4409. if ( MyContext.AnyAncestorBits( UNDER_OUT_PARAM ) )
  4410. RpcSemError( this, MyContext, CONST_ON_OUT_PARAM, NULL );
  4411. else if ( MyContext.AnyAncestorBits( IN_FUNCTION_RESULT ) )
  4412. RpcSemError( this, MyContext, CONST_ON_RETVAL, NULL );
  4413. }
  4414. // ignore pointers do not need to be rpc-able
  4415. fIgnore = (NULL != MyContext.ExtractAttribute( ATTR_IGNORE ));
  4416. if ( fIgnore )
  4417. {
  4418. MyContext.ClearAncestorBits( IN_RPC );
  4419. }
  4420. ////////////////////////////////////////////////////////////////////////
  4421. // process field attributes
  4422. // see if we have any field attributes (are conformant or varying)
  4423. FAInfo.SetControl( TRUE, GetBasicType()->IsPtrOrArray() );
  4424. MyContext.ExtractFieldAttributes( &FAInfo );
  4425. FAInfo.Validate( &MyContext );
  4426. // ptr is conf or varying or conf/varying
  4427. if ( FAInfo.Kind & FA_CONFORMANT_VARYING )
  4428. {
  4429. fIsSizedPtr = TRUE;
  4430. }
  4431. switch ( FAInfo.Kind )
  4432. {
  4433. case FA_NONE:
  4434. {
  4435. break;
  4436. }
  4437. case FA_STRING:
  4438. {
  4439. // string attributes only allowed on char and wchar_t
  4440. if ( !GetBasicType()->IsStringableType() )
  4441. TypeSemError( this, MyContext, STRING_NOT_ON_BYTE_CHAR, NULL );
  4442. if ( MyContext.AllAncestorBits( UNDER_OUT_PARAM |
  4443. IN_PARAM_LIST | IN_RPC ) &&
  4444. !fUnderAPtr &&
  4445. !MyContext.AnyAncestorBits( IN_STRUCT | IN_UNION |
  4446. UNDER_IN_PARAM ) )
  4447. TypeSemError( this, MyContext, DERIVES_FROM_UNSIZED_STRING, NULL );
  4448. MyContext.SetDescendantBits( HAS_STRING );
  4449. // break; deliberate fall through to case below
  4450. }
  4451. case FA_VARYING:
  4452. {
  4453. MyContext.SetDescendantBits( HAS_VAR_PTR );
  4454. break;
  4455. }
  4456. case FA_CONFORMANT:
  4457. {
  4458. MyContext.SetDescendantBits( HAS_CONF_PTR );
  4459. break;
  4460. }
  4461. case FA_CONFORMANT_STRING:
  4462. {
  4463. // string attributes only allowed on char and wchar_t
  4464. if ( !GetBasicType()->IsStringableType() )
  4465. TypeSemError( this, MyContext, STRING_NOT_ON_BYTE_CHAR, NULL );
  4466. if ( FAInfo.StringKind == STR_BSTRING )
  4467. TypeSemError( this, MyContext, BSTRING_NOT_ON_PLAIN_PTR, NULL );
  4468. // break; deliberate fall through to case below
  4469. }
  4470. case FA_CONFORMANT_VARYING:
  4471. {
  4472. MyContext.SetDescendantBits( HAS_CONF_VAR_PTR );
  4473. break;
  4474. }
  4475. case FA_INTERFACE:
  4476. {
  4477. if ( !fInterfacePtr && (GetBasicType()->NodeKind() != NODE_VOID ) )
  4478. {
  4479. TypeSemError( this, MyContext, IID_IS_NON_POINTER, NULL );
  4480. }
  4481. fInterfacePtr = TRUE;
  4482. break;
  4483. }
  4484. default: // string + varying combinations
  4485. {
  4486. TypeSemError( this, MyContext, INVALID_SIZE_ATTR_ON_STRING, NULL );
  4487. break;
  4488. }
  4489. }
  4490. // tell our children we are constructing an interface pointer
  4491. if (fInterfacePtr)
  4492. MyContext.SetAncestorBits( IN_INTERFACE_PTR );
  4493. // interface pointer shouldn't have explicit pointer attributes
  4494. if ( fInterfacePtr && fExplicitPtrAttr &&
  4495. (PtrKind == PTR_FULL || PtrKind == PTR_REF ) )
  4496. {
  4497. TypeSemError( this, MyContext, INTF_EXPLICIT_PTR_ATTR, NULL );
  4498. }
  4499. // Non pipe [out] interface pointers must use double indirection.
  4500. // However, pipe interface pointers can use only a single indirection.
  4501. // Note that fInterfacePtr may be true for a void *.
  4502. if ( fInterfacePtr && MyContext.AnyAncestorBits( UNDER_OUT_PARAM ) &&
  4503. !fUnderAPtr )
  4504. {
  4505. if ( GetChild()->NodeKind() == NODE_INTERFACE_REFERENCE )
  4506. TypeSemError( this, MyContext, NON_INTF_PTR_PTR_OUT, NULL );
  4507. }
  4508. if ( MyContext.FInSummary( ATTR_SWITCH_IS ) &&
  4509. ( FAInfo.Kind != FA_NONE) )
  4510. TypeSemError( this, MyContext, ARRAY_OF_UNIONS_ILLEGAL, NULL );
  4511. // see if a param or return type context attr reached us...
  4512. bool fSerialize = MyContext.ExtractAttribute( ATTR_SERIALIZE ) != 0;
  4513. bool fNoSerialize = MyContext.ExtractAttribute( ATTR_NOSERIALIZE ) != 0;
  4514. if ( MyContext.FInSummary( ATTR_CONTEXT ) )
  4515. {
  4516. if (GetBasicType()->NodeKind() != NODE_POINTER )
  4517. {
  4518. if ( fSerialize && fNoSerialize )
  4519. {
  4520. SemError( this, MyContext, CONFLICTING_ATTRIBUTES, GetSymName() );
  4521. }
  4522. MyContext.ExtractAttribute( ATTR_CONTEXT );
  4523. MyContext.SetDescendantBits( HAS_HANDLE | HAS_CONTEXT_HANDLE );
  4524. pParentCtxt->SetDescendantBits( HAS_HANDLE | HAS_CONTEXT_HANDLE );
  4525. MyContext.ClearAncestorBits( IN_RPC );
  4526. if (GetBasicType()->NodeKind() != NODE_VOID )
  4527. {
  4528. TypeSemError( this, MyContext, CONTEXT_HANDLE_VOID_PTR, NULL );
  4529. }
  4530. }
  4531. }
  4532. else
  4533. {
  4534. if ( fSerialize || fNoSerialize )
  4535. {
  4536. SemError( this, MyContext, NO_CONTEXT_HANDLE, GetSymName() );
  4537. }
  4538. }
  4539. // see if a byte_count reached us...
  4540. pCountAttr = (node_byte_count *)
  4541. MyContext.ExtractAttribute( ATTR_BYTE_COUNT );
  4542. if (pCountAttr)
  4543. {
  4544. // byte count error checking
  4545. if ( pCommand->NeedsNDR64Run() )
  4546. TypeSemError( this, MyContext, BYTE_COUNT_IN_NDR64, 0 );
  4547. node_param * pParam = pCountAttr->GetByteCountParam();
  4548. if ( !MyContext.AnyAncestorBits( UNDER_OUT_PARAM ) ||
  4549. MyContext.AnyAncestorBits( UNDER_IN_PARAM ) )
  4550. {
  4551. TypeSemError( this, MyContext, BYTE_COUNT_NOT_OUT_PTR, 0 );
  4552. }
  4553. if ( !pParam || !pParam->FInSummary( ATTR_IN ) || pParam->FInSummary( ATTR_OUT ) )
  4554. TypeSemError( this, MyContext, BYTE_COUNT_PARAM_NOT_IN, 0 );
  4555. if ( pParam )
  4556. {
  4557. NODE_T nodeKind = pParam->GetBasicType()->NodeKind();
  4558. if ( nodeKind < NODE_HYPER || nodeKind > NODE_BYTE )
  4559. {
  4560. SemError( this, MyContext, BYTE_COUNT_PARAM_NOT_INTEGRAL, 0 );
  4561. }
  4562. }
  4563. if ( !pCommand->IsSwitchDefined( SWITCH_MS_EXT ) )
  4564. {
  4565. SemError( this, MyContext, BYTE_COUNT_INVALID, 0 );
  4566. }
  4567. if ( MyContext.AnyDescendantBits( HAS_CONF_VAR_PTR | HAS_VAR_PTR | HAS_CONF_PTR ) )
  4568. {
  4569. SemError( this, MyContext, BYTE_COUNT_INVALID, 0 );
  4570. }
  4571. }
  4572. if ( PtrKind == PTR_REF )
  4573. {
  4574. SEM_ANALYSIS_CTXT * pCtxt = (SEM_ANALYSIS_CTXT *)
  4575. MyContext.FindNonDefAncestorContext();
  4576. if ( ( pCtxt->GetParent()->NodeKind() == NODE_FIELD ) &&
  4577. ( pCtxt->GetParentContext()->GetParent()->NodeKind() == NODE_UNION ) )
  4578. TypeSemError( this, MyContext, REF_PTR_IN_UNION, NULL );
  4579. }
  4580. MyContext.ClearAncestorBits( IN_UNION | IN_NE_UNION | IN_ARRAY );
  4581. ////////////////////////////////////////////////////////////////////////
  4582. // finally, process the child
  4583. GetChild()->SemanticAnalysis( &MyContext );
  4584. // if the child and this node is a conf and/or varying pointer
  4585. if ( fIsSizedPtr )
  4586. {
  4587. if ( MyContext.AnyDescendantBits( HAS_SIZED_PTR ) )
  4588. {
  4589. MyContext.SetDescendantBits( HAS_MULTIDIM_VECTOR );
  4590. }
  4591. else
  4592. {
  4593. MyContext.SetDescendantBits( HAS_SIZED_PTR );
  4594. }
  4595. }
  4596. // allocate error checking
  4597. if ( pAlloc )
  4598. {
  4599. if ( MyContext.AnyDescendantBits( HAS_TRANSMIT_AS | HAS_REPRESENT_AS ) )
  4600. {
  4601. if ( MyContext.AnyAncestorBits( IN_RPC ) )
  4602. SemError( this, MyContext, ALLOCATE_ON_TRANSMIT_AS, NULL );
  4603. else
  4604. AcfError( pAlloc, this, MyContext, ALLOCATE_ON_TRANSMIT_AS, NULL );
  4605. }
  4606. if ( MyContext.AnyDescendantBits( HAS_HANDLE ) )
  4607. {
  4608. if ( MyContext.AnyAncestorBits( IN_RPC ) )
  4609. SemError( this, MyContext, ALLOCATE_ON_HANDLE, NULL );
  4610. else
  4611. AcfError( pAlloc, this, MyContext, ALLOCATE_ON_HANDLE, NULL );
  4612. }
  4613. // warn about allocate(all_nodes) with [in,out] parameter
  4614. if ( MyContext.AllAncestorBits( IN_RPC |
  4615. IN_PARAM_LIST |
  4616. UNDER_IN_PARAM |
  4617. UNDER_OUT_PARAM ) &&
  4618. ( pAlloc->GetAllocateDetails() & ALLOCATE_ALL_NODES ) )
  4619. {
  4620. SemError( this, MyContext, ALLOCATE_IN_OUT_PTR, NULL );
  4621. }
  4622. }
  4623. if ( fInterfacePtr )
  4624. MyContext.SetAncestorBits( IN_INTERFACE_PTR );
  4625. if ( MyContext.AnyDescendantBits( HAS_CONF_ARRAY |
  4626. HAS_CONF_VAR_ARRAY ) &&
  4627. !MyContext.AnyDescendantBits( HAS_ARRAY |
  4628. HAS_TRANSMIT_AS ) &&
  4629. MyContext.AllAncestorBits( IN_RPC | UNDER_OUT_PARAM ) &&
  4630. !MyContext.AnyAncestorBits( UNDER_IN_PARAM |
  4631. IN_ARRAY |
  4632. IN_STRUCT |
  4633. IN_UNION |
  4634. IN_TRANSMIT_AS |
  4635. IN_REPRESENT_AS ) &&
  4636. ( PtrKind == PTR_REF ) )
  4637. TypeSemError( this, MyContext, DERIVES_FROM_PTR_TO_CONF, NULL );
  4638. #if 0
  4639. if ( MyContext.AnyDescendantBits( HAS_DIRECT_CONF_OR_VAR ) )
  4640. {
  4641. TypeSemError( this, MyContext, ILLEGAL_CONFORMANT_ARRAY, NULL );
  4642. }
  4643. #endif
  4644. // incomplete types are OK below a pointer
  4645. // array characteristics blocked by pointer
  4646. MyContext.ClearDescendantBits( HAS_INCOMPLETE_TYPE
  4647. | HAS_RECURSIVE_DEF
  4648. | HAS_ARRAY
  4649. | HAS_VAR_ARRAY
  4650. | HAS_CONF_ARRAY
  4651. | HAS_CONF_VAR_ARRAY
  4652. | HAS_MULTIDIM_SIZING
  4653. | HAS_UNION
  4654. | HAS_STRUCT
  4655. | HAS_TRANSMIT_AS
  4656. | HAS_REPRESENT_AS
  4657. | HAS_UNSAT_REP_AS
  4658. | HAS_DIRECT_CONF_OR_VAR
  4659. | HAS_ENUM
  4660. | HAS_ARRAY_OF_REF
  4661. | HAS_CONTEXT_HANDLE
  4662. | HAS_HRESULT );
  4663. if ( !fInterfacePtr && !fIgnore )
  4664. MyContext.SetDescendantBits( HAS_POINTER );
  4665. if ( ( FAInfo.Kind != FA_NONE ) &&
  4666. ( FAInfo.Kind != FA_STRING ) &&
  4667. ( FAInfo.Kind != FA_INTERFACE ) )
  4668. MyContext.SetDescendantBits( HAS_DIRECT_CONF_OR_VAR );
  4669. if ( ( PtrKind == PTR_REF ) &&
  4670. ( MyContext.FindNonDefAncestorContext()
  4671. ->GetParent()->NodeKind() == NODE_ARRAY ) )
  4672. {
  4673. MyContext.SetDescendantBits( HAS_ARRAY_OF_REF );
  4674. }
  4675. #ifdef gajgaj
  4676. if ( (PtrKind != PTR_REF ) &&
  4677. MyContext.AnyDescendantBits( HAS_HANDLE ) &&
  4678. MyContext.AnyAncestorBits( IN_RPC ) )
  4679. TypeSemError( this, MyContext, PTR_TO_HDL_UNIQUE_OR_FULL, NULL );
  4680. #endif //gajgaj
  4681. if ( MyContext.AnyDescendantBits( HAS_IN_CSTYPE | HAS_OUT_CSTYPE ) )
  4682. {
  4683. if ( !FAInfo.VerifyOnlySimpleExpression() )
  4684. SemError( this, MyContext, CSCHAR_EXPR_MUST_BE_SIMPLE, NULL );
  4685. if ( FA_CONFORMANT == FAInfo.Kind )
  4686. SemError( this, MyContext, NO_CONFORMANT_CSCHAR, NULL );
  4687. if ( MyContext.AnyDescendantBits( HAS_MULTIDIM_SIZING
  4688. | HAS_MULTIDIM_VECTOR ) )
  4689. {
  4690. SemError( this, MyContext, NO_MULTIDIM_CSCHAR, NULL );
  4691. }
  4692. // We want to propagate the the descendant bits up so that the proc
  4693. // and interface know the cs stuff is around but we only want to set
  4694. // the "this is a cs array" flag if it's actually a cs array
  4695. if ( GetChild()->FInSummary( ATTR_CSCHAR ) )
  4696. SetHasCSType();
  4697. }
  4698. SIZE_LENGTH_USAGE usage;
  4699. if ( HasCSType() )
  4700. usage = CSSizeLengthUsage;
  4701. else
  4702. usage = NonCSSizeLengthUsage;
  4703. if ( ! FAInfo.SetExpressionVariableUsage( usage ) )
  4704. SemError( this, MyContext, SHARED_CSCHAR_EXPR_VAR, NULL );
  4705. pParentCtxt->ReturnValues( MyContext );
  4706. }
  4707. void
  4708. node_array::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  4709. {
  4710. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  4711. FIELD_ATTR_INFO FAInfo;
  4712. PTRTYPE PtrKind = PTR_UNKNOWN;
  4713. BOOL fArrayParent = MyContext.AnyAncestorBits( IN_ARRAY );
  4714. if ( HasCorrelation( this ) )
  4715. {
  4716. MyContext.IncCorrelationCount();
  4717. }
  4718. CheckDeclspecAlign( MyContext );
  4719. // See if context_handle applied to param reached us
  4720. if ( CheckContextHandle( MyContext ) )
  4721. {
  4722. MyContext.SetDescendantBits( HAS_HANDLE | HAS_CONTEXT_HANDLE );
  4723. }
  4724. if ( MyContext.FInSummary( ATTR_SWITCH_IS ) )
  4725. TypeSemError( this, MyContext, ARRAY_OF_UNIONS_ILLEGAL, NULL );
  4726. ////////////////////////////////////////////////////////////////////////
  4727. // process pointer attributes
  4728. PtrKind = MyContext.GetPtrKind();
  4729. MIDL_ASSERT( PtrKind != PTR_UNKNOWN );
  4730. if ( PtrKind == PTR_FULL )
  4731. {
  4732. MyContext.SetDescendantBits( HAS_FULL_PTR );
  4733. }
  4734. if ( MyContext.ExtractAttribute( ATTR_PTR_KIND) )
  4735. TypeSemError( this, MyContext, MORE_THAN_ONE_PTR_ATTR, NULL );
  4736. // ref pointer may not be returned
  4737. if ( ( PtrKind == PTR_REF ) &&
  4738. MyContext.AllAncestorBits( IN_RPC | IN_FUNCTION_RESULT ) )
  4739. {
  4740. if (MyContext.FindNonDefAncestorContext()->GetParent()->NodeKind()
  4741. == NODE_PROC )
  4742. TypeSemError( this, MyContext, BAD_CON_REF_RT, NULL );
  4743. }
  4744. // unique or full pointer may not be out only
  4745. if ( ( PtrKind != PTR_REF ) &&
  4746. MyContext.AllAncestorBits( IN_RPC | IN_PARAM_LIST ) &&
  4747. !MyContext.AnyAncestorBits( UNDER_IN_PARAM |
  4748. IN_STRUCT |
  4749. IN_UNION |
  4750. IN_ARRAY |
  4751. IN_POINTER ) )
  4752. TypeSemError( this, MyContext, UNIQUE_FULL_PTR_OUT_ONLY, NULL );
  4753. MyContext.SetAncestorBits( IN_ARRAY );
  4754. // warn about OUT const things
  4755. if ( FInSummary( ATTR_CONST ) )
  4756. {
  4757. if ( MyContext.AnyAncestorBits( UNDER_OUT_PARAM ) )
  4758. RpcSemError( this, MyContext, CONST_ON_OUT_PARAM, NULL );
  4759. else if ( MyContext.AnyAncestorBits( IN_FUNCTION_RESULT ) )
  4760. RpcSemError( this, MyContext, CONST_ON_RETVAL, NULL );
  4761. }
  4762. /////////////////////////////////////////////////////////////////////////
  4763. // process field attributes
  4764. FAInfo.SetControl( FALSE, GetBasicType()->IsPtrOrArray() );
  4765. MyContext.ExtractFieldAttributes( &FAInfo );
  4766. FAInfo.Validate( &MyContext, pLowerBound, pUpperBound );
  4767. if (MyContext.AnyAncestorBits( IN_LIBRARY ))
  4768. {
  4769. if ( FA_NONE != FAInfo.Kind && FA_CONFORMANT != FAInfo.Kind)
  4770. {
  4771. // only Fixed size arrays and SAFEARRAYs are allowed in Type Libraries
  4772. SemError( this, MyContext, NOT_FIXED_ARRAY, NULL );
  4773. }
  4774. }
  4775. switch ( FAInfo.Kind )
  4776. {
  4777. case FA_NONE:
  4778. {
  4779. break;
  4780. }
  4781. case FA_STRING:
  4782. {
  4783. // string attributes only allowed on char and wchar_t
  4784. if ( !GetBasicType()->IsStringableType() )
  4785. TypeSemError( this, MyContext, STRING_NOT_ON_BYTE_CHAR, NULL );
  4786. if ( MyContext.AllAncestorBits( UNDER_OUT_PARAM |
  4787. IN_PARAM_LIST |
  4788. IN_RPC ) &&
  4789. !MyContext.AnyAncestorBits( IN_STRUCT |
  4790. IN_UNION |
  4791. IN_POINTER |
  4792. IN_ARRAY |
  4793. UNDER_IN_PARAM ) )
  4794. TypeSemError( this, MyContext, DERIVES_FROM_UNSIZED_STRING, NULL );
  4795. if ( FAInfo.StringKind == STR_BSTRING )
  4796. TypeSemError( this, MyContext, BSTRING_NOT_ON_PLAIN_PTR, NULL );
  4797. // break; deliberate fall through to case below
  4798. }
  4799. case FA_VARYING:
  4800. {
  4801. MyContext.SetDescendantBits( HAS_VAR_ARRAY );
  4802. break;
  4803. }
  4804. case FA_CONFORMANT:
  4805. {
  4806. MyContext.SetDescendantBits( HAS_CONF_ARRAY );
  4807. break;
  4808. }
  4809. case FA_CONFORMANT_STRING:
  4810. {
  4811. // string attributes only allowed on char and wchar_t
  4812. if ( !GetBasicType()->IsStringableType() )
  4813. TypeSemError( this, MyContext, STRING_NOT_ON_BYTE_CHAR, NULL );
  4814. if ( FAInfo.StringKind == STR_BSTRING )
  4815. TypeSemError( this, MyContext, BSTRING_NOT_ON_PLAIN_PTR, NULL );
  4816. MyContext.SetDescendantBits( HAS_STRING );
  4817. // break; deliberate fall through to case below
  4818. }
  4819. case FA_CONFORMANT_VARYING:
  4820. {
  4821. MyContext.SetDescendantBits( HAS_CONF_VAR_ARRAY );
  4822. break;
  4823. }
  4824. case FA_INTERFACE:
  4825. {
  4826. // gaj - tbd
  4827. break;
  4828. }
  4829. default: // string + varying combinations
  4830. {
  4831. TypeSemError( this, MyContext, INVALID_SIZE_ATTR_ON_STRING, NULL );
  4832. break;
  4833. }
  4834. }
  4835. // detect things like arrays of conf structs...
  4836. // if we have an array as an ancestor, and we have conformance, then complain
  4837. if ( MyContext.AnyDescendantBits( HAS_CONF_ARRAY | HAS_CONF_VAR_ARRAY ) &&
  4838. fArrayParent )
  4839. {
  4840. // see if there are any bad things between us and our parent array
  4841. SEM_ANALYSIS_CTXT * pCtxt = (SEM_ANALYSIS_CTXT *) pParentCtxt;
  4842. node_skl * pCur = pCtxt->GetParent();
  4843. // check up for anything other than def below proc
  4844. // make sure the proc only has one param
  4845. while ( pCur->NodeKind() != NODE_ARRAY )
  4846. {
  4847. if ( pCur->NodeKind() != NODE_DEF )
  4848. {
  4849. SemError( this, MyContext, ILLEGAL_CONFORMANT_ARRAY, NULL );
  4850. break;
  4851. }
  4852. pCtxt = (SEM_ANALYSIS_CTXT *) pCtxt->GetParentContext();
  4853. pCur = pCtxt->GetParent();
  4854. }
  4855. }
  4856. //////////////////////////////////////////////////////////////
  4857. // process the array element
  4858. GetChild()->SemanticAnalysis( &MyContext );
  4859. if ( MyContext.AnyDescendantBits( HAS_PIPE ) )
  4860. {
  4861. SemError( this, MyContext, INVALID_ARRAY_ELEMENT, 0 );
  4862. }
  4863. BOOL IsMultiDim = MyContext.AnyDescendantBits( HAS_ARRAY );
  4864. if ( MyContext.AnyDescendantBits( HAS_ARRAY ) &&
  4865. MyContext.AnyDescendantBits( HAS_CONF_ARRAY |
  4866. HAS_CONF_VAR_ARRAY |
  4867. HAS_VAR_ARRAY ) )
  4868. {
  4869. MyContext.SetDescendantBits( HAS_MULTIDIM_SIZING );
  4870. MyContext.SetDescendantBits( HAS_MULTIDIM_VECTOR );
  4871. }
  4872. MyContext.SetDescendantBits( HAS_ARRAY );
  4873. if ( NODE_POINTER == GetNonDefChild()->NodeKind() )
  4874. MyContext.SetDescendantBits( HAS_ARRAYOFPOINTERS );
  4875. // disallow forward references as array elements
  4876. if ( MyContext.AnyDescendantBits( HAS_INCOMPLETE_TYPE ) )
  4877. {
  4878. if (! MyContext.AnyAncestorBits( IN_LIBRARY ))
  4879. SemError( this, MyContext, UNDEFINED_SYMBOL, NULL );
  4880. MyContext.ClearDescendantBits( HAS_INCOMPLETE_TYPE );
  4881. }
  4882. MyContext.ClearDescendantBits( HAS_RECURSIVE_DEF );
  4883. if ( MyContext.AllDescendantBits( HAS_DIRECT_CONF_OR_VAR |
  4884. HAS_MULTIDIM_SIZING ) &&
  4885. MyContext.AnyDescendantBits( HAS_CONF_ARRAY | HAS_CONF_VAR_ARRAY ) &&
  4886. ( GetChild()->NodeKind() == NODE_DEF ) )
  4887. {
  4888. SemError( this, MyContext, NON_ANSI_MULTI_CONF_ARRAY, NULL );
  4889. }
  4890. MyContext.ClearDescendantBits( HAS_DIRECT_CONF_OR_VAR );
  4891. if ( ( FAInfo.Kind != FA_NONE ) &&
  4892. ( FAInfo.Kind != FA_STRING ) &&
  4893. ( FAInfo.Kind != FA_INTERFACE ) )
  4894. MyContext.SetDescendantBits( HAS_DIRECT_CONF_OR_VAR );
  4895. if ( MyContext.AnyDescendantBits( HAS_POINTER ) )
  4896. fHasPointer = TRUE;
  4897. if ( MyContext.AnyDescendantBits( HAS_HANDLE ) )
  4898. TypeSemError( this, MyContext, BAD_CON_CTXT_HDL_ARRAY, NULL );
  4899. // don't allow functions as elements
  4900. if ( MyContext.AnyDescendantBits( HAS_FUNC ) &&
  4901. MyContext.AllAncestorBits( IN_INTERFACE | IN_RPC ) )
  4902. TypeSemError( this, MyContext, BAD_CON_ARRAY_FUNC, NULL );
  4903. if ( MyContext.AnyDescendantBits( HAS_IN_CSTYPE | HAS_OUT_CSTYPE ) )
  4904. {
  4905. if ( FA_CONFORMANT == FAInfo.Kind )
  4906. SemError( this, MyContext, NO_CONFORMANT_CSCHAR, NULL );
  4907. if ( IsMultiDim )
  4908. SemError( this, MyContext, NO_MULTIDIM_CSCHAR, NULL );
  4909. SetHasCSType();
  4910. }
  4911. SIZE_LENGTH_USAGE usage;
  4912. if ( HasCSType() )
  4913. usage = CSSizeLengthUsage;
  4914. else
  4915. usage = NonCSSizeLengthUsage;
  4916. if ( ! FAInfo.SetExpressionVariableUsage( usage ) )
  4917. SemError( this, MyContext, SHARED_CSCHAR_EXPR_VAR, NULL );
  4918. MyContext.ClearDescendantBits( HAS_STRUCT );
  4919. pParentCtxt->ReturnValues( MyContext );
  4920. }
  4921. void
  4922. node_echo_string::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  4923. {
  4924. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  4925. pParentCtxt->ReturnValues( MyContext );
  4926. };
  4927. void
  4928. node_e_status_t::VerifyParamUsage( SEM_ANALYSIS_CTXT * pCtxt )
  4929. {
  4930. // verify that we are under an OUT-only pointer
  4931. // or a "hidden" status parameter (only specified in the acf file)
  4932. if ( pCtxt->AnyAncestorBits( UNDER_IN_PARAM ) ||
  4933. !pCtxt->AnyAncestorBits( UNDER_OUT_PARAM ) )
  4934. {
  4935. if ( !pCtxt->AnyAncestorBits( UNDER_HIDDEN_STATUS ) )
  4936. {
  4937. TypeSemError( this, *pCtxt, E_STAT_T_MUST_BE_PTR_TO_E, NULL );
  4938. return;
  4939. }
  4940. }
  4941. SEM_ANALYSIS_CTXT * pCurCtxt = (SEM_ANALYSIS_CTXT *)pCtxt->GetParentContext();
  4942. node_skl * pPar = pCurCtxt->GetParent();
  4943. unsigned short PtrSeen = 0;
  4944. NODE_T Kind;
  4945. while ( ( Kind = pPar->NodeKind() ) != NODE_PARAM )
  4946. {
  4947. switch ( Kind )
  4948. {
  4949. case NODE_POINTER: // count pointers (must see just 1 )
  4950. PtrSeen++;
  4951. break;
  4952. case NODE_DEF: // skip DEF nodes
  4953. case NODE_E_STATUS_T: // and the error_status_t node
  4954. break;
  4955. default: // error on anything else
  4956. TypeSemError( this, *pCtxt, E_STAT_T_MUST_BE_PTR_TO_E, NULL );
  4957. return;
  4958. }
  4959. // advance up the stack
  4960. pCurCtxt = (SEM_ANALYSIS_CTXT *) pCurCtxt->GetParentContext();
  4961. pPar = pCurCtxt->GetParent();
  4962. }
  4963. // complain about wrong number of pointers
  4964. if ( PtrSeen != 1 )
  4965. TypeSemError( this, *pCtxt, E_STAT_T_MUST_BE_PTR_TO_E, NULL );
  4966. }
  4967. void
  4968. node_e_status_t::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  4969. {
  4970. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  4971. BOOL fFaultstat = (NULL != MyContext.ExtractAttribute( ATTR_FAULTSTAT ));
  4972. BOOL fCommstat = (NULL != MyContext.ExtractAttribute( ATTR_COMMSTAT ));
  4973. MyContext.SetDescendantBits( HAS_E_STAT_T );
  4974. CheckDeclspecAlign( MyContext );
  4975. // an error status_t can only be:
  4976. // 1: a parameter return type, or
  4977. // 2: an [out] only pointer parameter
  4978. // and it must have at least one of [comm_status] or
  4979. // [fault_status] applied
  4980. // make sure parameter is an OUT-only pointer if it has comm/fault_status
  4981. if ( fFaultstat || fCommstat )
  4982. {
  4983. if ( MyContext.AnyAncestorBits( IN_RPC ) )
  4984. {
  4985. // A proc in an actual remote interface.
  4986. // Then it must be an appropriate parameter
  4987. if ( MyContext.AnyAncestorBits( IN_PARAM_LIST ) )
  4988. {
  4989. VerifyParamUsage( &MyContext );
  4990. }
  4991. // or on a return type.
  4992. else if ( !MyContext.AnyAncestorBits( IN_FUNCTION_RESULT ) )
  4993. {
  4994. TypeSemError( this, MyContext, E_STAT_T_MUST_BE_PTR_TO_E , NULL );
  4995. }
  4996. }
  4997. if ( MyContext.AnyAncestorBits( IN_ARRAY ) )
  4998. TypeSemError( this, MyContext, E_STAT_T_ARRAY_ELEMENT, NULL );
  4999. if ( MyContext.AnyAncestorBits( IN_TRANSMIT_AS | IN_REPRESENT_AS ) )
  5000. TypeSemError( this, MyContext, TRANSMIT_AS_ON_E_STAT_T, NULL );
  5001. if ( MyContext.AnyAncestorBits( IN_STRUCT | IN_UNION ) )
  5002. TypeSemError( this, MyContext, BAD_CON_E_STAT_T_FIELD, NULL );
  5003. if ( MyContext.AnyAncestorBits( IN_USER_MARSHAL ) )
  5004. TypeSemError( this, MyContext, TRANSMIT_AS_ON_E_STAT_T, NULL );
  5005. }
  5006. MyContext.RejectAttributes();
  5007. pParentCtxt->ReturnValues( MyContext );
  5008. };
  5009. void
  5010. node_error::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  5011. {
  5012. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  5013. MyContext.RejectAttributes();
  5014. CheckDeclspecAlign( MyContext );
  5015. pParentCtxt->ReturnValues( MyContext );
  5016. };
  5017. void
  5018. node_wchar_t::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  5019. {
  5020. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  5021. CheckDeclspecAlign( MyContext );
  5022. TypeSemError( this, MyContext, WCHAR_T_INVALID_OSF, NULL );
  5023. if ( MyContext.AllAncestorBits( IN_PARAM_LIST | IN_RPC ) )
  5024. SemError( this, MyContext, WCHAR_T_NEEDS_MS_EXT_TO_RPC, NULL );
  5025. MyContext.RejectAttributes();
  5026. pParentCtxt->ReturnValues( MyContext );
  5027. };
  5028. void
  5029. node_library::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt)
  5030. {
  5031. MEM_ITER MemIter(this);
  5032. SEM_ANALYSIS_CTXT MyContext(this, pParentCtxt);
  5033. BOOL HasGuid = MyContext.FInSummary( ATTR_GUID );
  5034. MyContext.ExtractAttribute(ATTR_HELPSTRING);
  5035. MyContext.ExtractAttribute(ATTR_HELPCONTEXT);
  5036. MyContext.ExtractAttribute(ATTR_HELPSTRINGCONTEXT);
  5037. MyContext.ExtractAttribute(ATTR_HELPSTRINGDLL);
  5038. gfCaseSensitive=FALSE;
  5039. // check for illegal attributes
  5040. node_member_attr * pMA;
  5041. while ( ( pMA = (node_member_attr *)MyContext.ExtractAttribute(ATTR_MEMBER) ) != 0 )
  5042. {
  5043. switch (pMA->GetAttr())
  5044. {
  5045. // acceptable attributes
  5046. case MATTR_RESTRICTED:
  5047. break;
  5048. // unacceptable attributes
  5049. case MATTR_READONLY:
  5050. case MATTR_SOURCE:
  5051. case MATTR_DEFAULTVTABLE:
  5052. case MATTR_BINDABLE:
  5053. case MATTR_DISPLAYBIND:
  5054. case MATTR_DEFAULTBIND:
  5055. case MATTR_REQUESTEDIT:
  5056. case MATTR_PROPGET:
  5057. case MATTR_PROPPUT:
  5058. case MATTR_PROPPUTREF:
  5059. case MATTR_OPTIONAL:
  5060. case MATTR_RETVAL:
  5061. case MATTR_VARARG:
  5062. case MATTR_PREDECLID:
  5063. case MATTR_UIDEFAULT:
  5064. case MATTR_NONBROWSABLE:
  5065. case MATTR_DEFAULTCOLLELEM:
  5066. case MATTR_IMMEDIATEBIND:
  5067. case MATTR_USESGETLASTERROR:
  5068. case MATTR_REPLACEABLE:
  5069. {
  5070. char * pAttrName = pMA->GetNodeNameString();
  5071. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, pAttrName);
  5072. break;
  5073. }
  5074. }
  5075. }
  5076. node_type_attr * pTA;
  5077. while ( ( pTA = (node_type_attr *)MyContext.ExtractAttribute(ATTR_TYPE) ) != 0 )
  5078. {
  5079. switch (pTA->GetAttr())
  5080. {
  5081. // acceptable attributes
  5082. case TATTR_CONTROL:
  5083. break;
  5084. // unacceptable attributes
  5085. case TATTR_LICENSED:
  5086. case TATTR_APPOBJECT:
  5087. case TATTR_PUBLIC:
  5088. case TATTR_DUAL:
  5089. case TATTR_PROXY:
  5090. case TATTR_NONEXTENSIBLE:
  5091. case TATTR_OLEAUTOMATION:
  5092. case TATTR_NONCREATABLE:
  5093. case TATTR_AGGREGATABLE:
  5094. {
  5095. char * pAttrName = pTA->GetNodeNameString();
  5096. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, pAttrName);
  5097. break;
  5098. }
  5099. }
  5100. }
  5101. // make sure the UUID is unique
  5102. if ( HasGuid )
  5103. {
  5104. node_guid * pGuid = (node_guid *) MyContext.ExtractAttribute( ATTR_GUID );
  5105. node_skl* pDuplicate = GetDuplicateGuid( pGuid, pUUIDTable );
  5106. if ( pDuplicate )
  5107. {
  5108. SemError(this, MyContext, DUPLICATE_UUID, pDuplicate->GetSymName());
  5109. }
  5110. }
  5111. else
  5112. {
  5113. SemError(this, MyContext, NO_UUID_SPECIFIED, NULL);
  5114. }
  5115. node_skl * pN;
  5116. NODE_T nodeKind;
  5117. while ( ( pN = MemIter.GetNext() ) != 0 )
  5118. {
  5119. SEM_ANALYSIS_CTXT ChildContext(MyContext);
  5120. ChildContext.SetInterfaceContext( &MyContext );
  5121. ChildContext.SetAncestorBits(IN_LIBRARY);
  5122. nodeKind = pN->NodeKind();
  5123. if ( nodeKind == NODE_PROC )
  5124. {
  5125. SemError( this, MyContext, INVALID_MEMBER, pN->GetSymName() );
  5126. }
  5127. else if (
  5128. nodeKind != NODE_MODULE &&
  5129. nodeKind != NODE_DISPINTERFACE &&
  5130. nodeKind != NODE_COCLASS &&
  5131. nodeKind != NODE_INTERFACE &&
  5132. nodeKind != NODE_STRUCT &&
  5133. nodeKind != NODE_UNION &&
  5134. nodeKind != NODE_ENUM &&
  5135. nodeKind != NODE_LABEL &&
  5136. nodeKind != NODE_DEF &&
  5137. nodeKind != NODE_INTERFACE_REFERENCE &&
  5138. nodeKind != NODE_ID &&
  5139. nodeKind != NODE_ECHO_STRING &&
  5140. nodeKind != NODE_FORWARD &&
  5141. nodeKind != NODE_MIDL_PRAGMA
  5142. )
  5143. {
  5144. SemError(this, MyContext, POSSIBLE_INVALID_MEMBER, pN->GetSymName());
  5145. }
  5146. pN->SemanticAnalysis(&ChildContext);
  5147. }
  5148. // consume all the library attributes
  5149. MyContext.CheckAttributes( );
  5150. // MyContext.ReturnValues(ChildContext);
  5151. pParentCtxt->ReturnValues( MyContext );
  5152. gfCaseSensitive=TRUE;
  5153. }
  5154. void
  5155. node_coclass::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt)
  5156. {
  5157. // make sure each coclass only gets analyzed once
  5158. if (fSemAnalyzed)
  5159. return;
  5160. fSemAnalyzed = TRUE;
  5161. MEM_ITER MemIter(this);
  5162. SEM_ANALYSIS_CTXT MyContext(this, pParentCtxt);
  5163. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  5164. MyContext.ExtractAttribute(ATTR_TYPEDESCATTR);
  5165. MyContext.ExtractAttribute( ATTR_HIDDEN );
  5166. MyContext.ExtractAttribute( ATTR_VERSION );
  5167. MyContext.ExtractAttribute( ATTR_HELPSTRING );
  5168. MyContext.ExtractAttribute( ATTR_HELPSTRINGCONTEXT );
  5169. MyContext.ExtractAttribute( ATTR_HELPCONTEXT );
  5170. MyContext.ExtractAttribute( ATTR_LCID );
  5171. if (MyContext.ExtractAttribute(ATTR_HELPSTRINGDLL))
  5172. {
  5173. SemError(this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  5174. }
  5175. SEM_ANALYSIS_CTXT ChildContext(MyContext);
  5176. ChildContext.SetInterfaceContext( &MyContext );
  5177. // check for illegal attributes
  5178. node_type_attr * pTA;
  5179. while ( ( pTA = (node_type_attr *)MyContext.ExtractAttribute(ATTR_TYPE) ) != 0 )
  5180. {
  5181. switch (pTA->GetAttr())
  5182. {
  5183. // acceptable attributes
  5184. case TATTR_NONCREATABLE:
  5185. SetNotCreatable(TRUE);
  5186. break;
  5187. case TATTR_LICENSED:
  5188. case TATTR_APPOBJECT:
  5189. case TATTR_CONTROL:
  5190. case TATTR_AGGREGATABLE:
  5191. break;
  5192. // unacceptable attributes
  5193. case TATTR_PUBLIC:
  5194. {
  5195. char * pAttrName = pTA->GetNodeNameString();
  5196. SemError( this, MyContext, NEWLYFOUND_INAPPLICABLE_ATTRIBUTE, pAttrName);
  5197. break;
  5198. }
  5199. case TATTR_DUAL:
  5200. case TATTR_PROXY:
  5201. case TATTR_NONEXTENSIBLE:
  5202. case TATTR_OLEAUTOMATION:
  5203. {
  5204. char * pAttrName = pTA->GetNodeNameString();
  5205. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, pAttrName);
  5206. break;
  5207. }
  5208. }
  5209. }
  5210. // check for illegal attributes
  5211. node_member_attr * pMA;
  5212. while ( ( pMA = (node_member_attr *)MyContext.ExtractAttribute(ATTR_MEMBER) ) != 0 )
  5213. {
  5214. switch (pMA->GetAttr())
  5215. {
  5216. // acceptable attributes
  5217. case MATTR_RESTRICTED:
  5218. break;
  5219. // unacceptable attributes
  5220. case MATTR_READONLY:
  5221. case MATTR_SOURCE:
  5222. case MATTR_DEFAULTVTABLE:
  5223. case MATTR_BINDABLE:
  5224. case MATTR_DISPLAYBIND:
  5225. case MATTR_DEFAULTBIND:
  5226. case MATTR_REQUESTEDIT:
  5227. case MATTR_PROPGET:
  5228. case MATTR_PROPPUT:
  5229. case MATTR_PROPPUTREF:
  5230. case MATTR_OPTIONAL:
  5231. case MATTR_RETVAL:
  5232. case MATTR_VARARG:
  5233. case MATTR_UIDEFAULT:
  5234. case MATTR_NONBROWSABLE:
  5235. case MATTR_DEFAULTCOLLELEM:
  5236. case MATTR_IMMEDIATEBIND:
  5237. case MATTR_USESGETLASTERROR:
  5238. case MATTR_REPLACEABLE:
  5239. {
  5240. char * pAttrName = pMA->GetNodeNameString();
  5241. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, pAttrName);
  5242. break;
  5243. }
  5244. }
  5245. }
  5246. BOOL HasGuid = MyContext.FInSummary( ATTR_GUID );
  5247. // make sure the UUID is unique
  5248. if ( HasGuid )
  5249. {
  5250. node_guid * pGuid = (node_guid *) MyContext.ExtractAttribute( ATTR_GUID );
  5251. node_skl* pDuplicate = GetDuplicateGuid( pGuid, pUUIDTable );
  5252. if ( pDuplicate )
  5253. {
  5254. SemError(this, MyContext, DUPLICATE_UUID, pDuplicate->GetSymName());
  5255. }
  5256. }
  5257. else
  5258. {
  5259. SemError(this, MyContext, NO_UUID_SPECIFIED, NULL);
  5260. }
  5261. ChildContext.SetAncestorBits(IN_COCLASS);
  5262. BOOL fHasDefaultSource = FALSE;
  5263. BOOL fHasDefaultSink = FALSE;
  5264. named_node * pN = (named_node *)MemIter.GetNext();
  5265. named_node * pNFirstSource = NULL;
  5266. named_node * pNFirstSink = NULL;
  5267. while (pN)
  5268. {
  5269. BOOL fSource = pN->FMATTRInSummary(MATTR_SOURCE);
  5270. BOOL fDefaultVtable = pN->FMATTRInSummary(MATTR_DEFAULTVTABLE);
  5271. if (fSource)
  5272. {
  5273. if (NULL == pNFirstSource && !pN->FMATTRInSummary(MATTR_RESTRICTED))
  5274. pNFirstSource = pN;
  5275. }
  5276. else
  5277. {
  5278. if (NULL == pNFirstSink && !pN->FMATTRInSummary(MATTR_RESTRICTED))
  5279. pNFirstSink = pN;
  5280. }
  5281. if (fDefaultVtable)
  5282. {
  5283. if (!fSource)
  5284. {
  5285. SemError(this, MyContext, DEFAULTVTABLE_REQUIRES_SOURCE, pN->GetSymName());
  5286. }
  5287. }
  5288. if (pN->GetAttribute(ATTR_DEFAULT))
  5289. {
  5290. if (fSource)
  5291. {
  5292. if (fHasDefaultSource)
  5293. {
  5294. SemError(this, MyContext, TWO_DEFAULT_INTERFACES, pN->GetSymName());
  5295. }
  5296. fHasDefaultSource = TRUE;
  5297. }
  5298. else
  5299. {
  5300. if (fHasDefaultSink)
  5301. {
  5302. SemError(this, MyContext, TWO_DEFAULT_INTERFACES, pN->GetSymName());
  5303. }
  5304. fHasDefaultSink = TRUE;
  5305. }
  5306. }
  5307. pN->SemanticAnalysis(&ChildContext);
  5308. pN = MemIter.GetNext();
  5309. }
  5310. if (!fHasDefaultSink)
  5311. {
  5312. if (pNFirstSink)
  5313. pNFirstSink->SetAttribute(ATTR_DEFAULT);
  5314. }
  5315. if (!fHasDefaultSource)
  5316. {
  5317. if (pNFirstSource)
  5318. pNFirstSource->SetAttribute(ATTR_DEFAULT);
  5319. }
  5320. MyContext.CheckAttributes( );
  5321. MyContext.ReturnValues(ChildContext);
  5322. pParentCtxt->ReturnValues( MyContext );
  5323. }
  5324. void
  5325. node_dispinterface::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt)
  5326. {
  5327. // make sure each dispinterface gets analyzed only once
  5328. if (fSemAnalyzed)
  5329. return;
  5330. fSemAnalyzed = TRUE;
  5331. MEM_ITER MemIter(this);
  5332. SEM_ANALYSIS_CTXT MyContext(this, pParentCtxt);
  5333. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  5334. MyContext.ExtractAttribute(ATTR_TYPEDESCATTR);
  5335. MyContext.ExtractAttribute( ATTR_HIDDEN );
  5336. MyContext.ExtractAttribute( ATTR_VERSION );
  5337. MyContext.ExtractAttribute( ATTR_HELPSTRING );
  5338. MyContext.ExtractAttribute( ATTR_HELPSTRINGCONTEXT );
  5339. MyContext.ExtractAttribute( ATTR_HELPCONTEXT );
  5340. MyContext.ExtractAttribute( ATTR_LCID );
  5341. if (MyContext.ExtractAttribute(ATTR_HELPSTRINGDLL))
  5342. {
  5343. SemError(this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  5344. }
  5345. SEM_ANALYSIS_CTXT ChildContext(MyContext);
  5346. ChildContext.SetInterfaceContext( &MyContext );
  5347. // check for illegal attributes
  5348. node_type_attr * pTA;
  5349. while ( ( pTA = (node_type_attr *)MyContext.ExtractAttribute(ATTR_TYPE) ) != 0 )
  5350. {
  5351. switch (pTA->GetAttr())
  5352. {
  5353. // acceptable attributes
  5354. case TATTR_NONEXTENSIBLE:
  5355. break;
  5356. // unacceptable attributes
  5357. case TATTR_OLEAUTOMATION:
  5358. case TATTR_PUBLIC:
  5359. {
  5360. char * pAttrName = pTA->GetNodeNameString();
  5361. SemError( this, MyContext, NEWLYFOUND_INAPPLICABLE_ATTRIBUTE, pAttrName);
  5362. break;
  5363. }
  5364. case TATTR_PROXY:
  5365. case TATTR_DUAL:
  5366. case TATTR_LICENSED:
  5367. case TATTR_APPOBJECT:
  5368. case TATTR_CONTROL:
  5369. case TATTR_NONCREATABLE:
  5370. case TATTR_AGGREGATABLE:
  5371. {
  5372. char * pAttrName = pTA->GetNodeNameString();
  5373. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, pAttrName);
  5374. break;
  5375. }
  5376. }
  5377. }
  5378. node_member_attr * pMA;
  5379. while ( ( pMA = (node_member_attr *)MyContext.ExtractAttribute(ATTR_MEMBER) ) != 0 )
  5380. {
  5381. switch (pMA->GetAttr())
  5382. {
  5383. // acceptable attributes
  5384. case MATTR_RESTRICTED:
  5385. break;
  5386. // unacceptable attributes
  5387. case MATTR_READONLY:
  5388. case MATTR_SOURCE:
  5389. case MATTR_DEFAULTVTABLE:
  5390. case MATTR_BINDABLE:
  5391. case MATTR_DISPLAYBIND:
  5392. case MATTR_DEFAULTBIND:
  5393. case MATTR_REQUESTEDIT:
  5394. case MATTR_PROPGET:
  5395. case MATTR_PROPPUT:
  5396. case MATTR_PROPPUTREF:
  5397. case MATTR_OPTIONAL:
  5398. case MATTR_RETVAL:
  5399. case MATTR_VARARG:
  5400. case MATTR_PREDECLID:
  5401. case MATTR_UIDEFAULT:
  5402. case MATTR_NONBROWSABLE:
  5403. case MATTR_DEFAULTCOLLELEM:
  5404. case MATTR_IMMEDIATEBIND:
  5405. case MATTR_USESGETLASTERROR:
  5406. case MATTR_REPLACEABLE:
  5407. {
  5408. char * pAttrName = pMA->GetNodeNameString();
  5409. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, pAttrName);
  5410. break;
  5411. }
  5412. }
  5413. }
  5414. BOOL HasGuid = MyContext.FInSummary( ATTR_GUID );
  5415. // make sure the UUID is unique
  5416. if ( HasGuid )
  5417. {
  5418. node_guid * pGuid = (node_guid *) MyContext.ExtractAttribute( ATTR_GUID );
  5419. node_skl* pDuplicate = GetDuplicateGuid( pGuid, pUUIDTable );
  5420. if ( pDuplicate )
  5421. {
  5422. SemError(this, MyContext, DUPLICATE_UUID, pDuplicate->GetSymName());
  5423. }
  5424. }
  5425. else
  5426. {
  5427. SemError(this, MyContext, NO_UUID_SPECIFIED, NULL);
  5428. }
  5429. // make sure IDispatch is defined.
  5430. SymKey SKey("IDispatch", NAME_DEF);
  5431. pDispatch = pBaseSymTbl->SymSearch(SKey);
  5432. if (!pDispatch)
  5433. {
  5434. // IDispatch is not defined: generate error.
  5435. SemError(this, MyContext, NO_IDISPATCH, GetSymName());
  5436. }
  5437. else
  5438. {
  5439. if (pDispatch->NodeKind() == NODE_INTERFACE_REFERENCE)
  5440. pDispatch = ((node_interface_reference *)pDispatch)->GetRealInterface();
  5441. }
  5442. ChildContext.SetAncestorBits((ANCESTOR_FLAGS) IN_DISPINTERFACE);
  5443. node_skl * pN;
  5444. while ( ( pN = MemIter.GetNext() ) != 0 )
  5445. {
  5446. pN->SemanticAnalysis(&ChildContext);
  5447. }
  5448. MyContext.CheckAttributes( );
  5449. MyContext.ReturnValues(ChildContext);
  5450. pParentCtxt->ReturnValues( MyContext );
  5451. }
  5452. void
  5453. node_module::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt)
  5454. {
  5455. // make sure each module gets analyzed only once
  5456. if (fSemAnalyzed)
  5457. return;
  5458. fSemAnalyzed = TRUE;
  5459. MEM_ITER MemIter(this);
  5460. SEM_ANALYSIS_CTXT MyContext(this, pParentCtxt);
  5461. BOOL HasGuid = MyContext.FInSummary( ATTR_GUID );
  5462. MyContext.ExtractAttribute(ATTR_DLLNAME);
  5463. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  5464. MyContext.ExtractAttribute(ATTR_TYPEDESCATTR);
  5465. MyContext.ExtractAttribute( ATTR_HIDDEN );
  5466. MyContext.ExtractAttribute( ATTR_VERSION );
  5467. MyContext.ExtractAttribute( ATTR_HELPSTRING );
  5468. MyContext.ExtractAttribute( ATTR_HELPSTRINGCONTEXT );
  5469. MyContext.ExtractAttribute( ATTR_HELPCONTEXT );
  5470. MyContext.ExtractAttribute( ATTR_LCID );
  5471. if (MyContext.ExtractAttribute(ATTR_HELPSTRINGDLL))
  5472. {
  5473. SemError(this, MyContext, INAPPLICABLE_ATTRIBUTE, 0);
  5474. }
  5475. if ( !MyContext.AnyAncestorBits( IN_LIBRARY ) )
  5476. {
  5477. SemError(this, MyContext, NO_LIBRARY, 0);
  5478. }
  5479. SEM_ANALYSIS_CTXT ChildContext(MyContext);
  5480. ChildContext.SetInterfaceContext( &MyContext );
  5481. // make sure the UUID is unique
  5482. if ( HasGuid )
  5483. {
  5484. node_guid * pGuid = (node_guid *) MyContext.ExtractAttribute( ATTR_GUID );
  5485. node_skl* pDuplicate = GetDuplicateGuid( pGuid, pUUIDTable );
  5486. if ( pDuplicate )
  5487. {
  5488. SemError(this, MyContext, DUPLICATE_UUID, pDuplicate->GetSymName());
  5489. }
  5490. }
  5491. // check for illegal attributes
  5492. node_type_attr * pTA;
  5493. while ( ( pTA = (node_type_attr *)MyContext.ExtractAttribute(ATTR_TYPE) ) != 0 )
  5494. {
  5495. switch (pTA->GetAttr())
  5496. {
  5497. // acceptable attributes
  5498. case TATTR_PUBLIC:
  5499. {
  5500. char * pAttrName = pTA->GetNodeNameString();
  5501. SemError( this, MyContext, NEWLYFOUND_INAPPLICABLE_ATTRIBUTE, pAttrName);
  5502. break;
  5503. }
  5504. break;
  5505. // unacceptable attributes
  5506. case TATTR_OLEAUTOMATION:
  5507. case TATTR_LICENSED:
  5508. case TATTR_APPOBJECT:
  5509. case TATTR_CONTROL:
  5510. case TATTR_PROXY:
  5511. case TATTR_DUAL:
  5512. case TATTR_NONEXTENSIBLE:
  5513. case TATTR_NONCREATABLE:
  5514. case TATTR_AGGREGATABLE:
  5515. {
  5516. char * pAttrName = pTA->GetNodeNameString();
  5517. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, pAttrName);
  5518. break;
  5519. }
  5520. }
  5521. }
  5522. node_member_attr * pMA;
  5523. node_member_attr * pUsesGetLastErrorAttr = 0;
  5524. while ( ( pMA = (node_member_attr *)MyContext.ExtractAttribute(ATTR_MEMBER) ) != 0 )
  5525. {
  5526. switch (pMA->GetAttr())
  5527. {
  5528. // acceptable attributes
  5529. case MATTR_RESTRICTED:
  5530. break;
  5531. case MATTR_USESGETLASTERROR:
  5532. pUsesGetLastErrorAttr = pMA;
  5533. break;
  5534. // unacceptable attributes
  5535. case MATTR_READONLY:
  5536. case MATTR_SOURCE:
  5537. case MATTR_DEFAULTVTABLE:
  5538. case MATTR_BINDABLE:
  5539. case MATTR_DISPLAYBIND:
  5540. case MATTR_DEFAULTBIND:
  5541. case MATTR_REQUESTEDIT:
  5542. case MATTR_PROPGET:
  5543. case MATTR_PROPPUT:
  5544. case MATTR_PROPPUTREF:
  5545. case MATTR_OPTIONAL:
  5546. case MATTR_RETVAL:
  5547. case MATTR_VARARG:
  5548. case MATTR_PREDECLID:
  5549. case MATTR_UIDEFAULT:
  5550. case MATTR_NONBROWSABLE:
  5551. case MATTR_DEFAULTCOLLELEM:
  5552. case MATTR_IMMEDIATEBIND:
  5553. case MATTR_REPLACEABLE:
  5554. {
  5555. char * pAttrName = pMA->GetNodeNameString();
  5556. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, pAttrName);
  5557. break;
  5558. }
  5559. }
  5560. }
  5561. if (pUsesGetLastErrorAttr != 0)
  5562. {
  5563. MyContext.Add(pUsesGetLastErrorAttr);
  5564. }
  5565. ChildContext.SetAncestorBits(IN_MODULE);
  5566. node_skl * pN;
  5567. while ( (pN = MemIter.GetNext() ) != 0 )
  5568. {
  5569. pN->SemanticAnalysis(&ChildContext);
  5570. }
  5571. MyContext.CheckAttributes( );
  5572. MyContext.ReturnValues(ChildContext);
  5573. pParentCtxt->ReturnValues( MyContext );
  5574. }
  5575. void
  5576. node_pipe::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  5577. {
  5578. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  5579. if (!GetSymName())
  5580. {
  5581. char * pParentName = pParentCtxt->GetParent()->GetSymName();
  5582. char * pName = new char [strlen(pParentName) + 6]; // the length of "pipe_" plus terminating null
  5583. strcpy(pName, "pipe_");
  5584. strcat(pName,pParentName);
  5585. SetSymName(pName);
  5586. }
  5587. if ( MyContext.AnyAncestorBits( HAS_ASYNCHANDLE ) &&
  5588. !MyContext.AnyAncestorBits( IN_OBJECT_INTF ) )
  5589. {
  5590. SetGenAsyncPipeFlavor();
  5591. }
  5592. GetChild()->SemanticAnalysis(&MyContext);
  5593. CheckDeclspecAlign( MyContext );
  5594. // Remove the following statement once support for UNIONS within PIPES is provided by the interpreter.
  5595. if (MyContext.AnyDescendantBits( HAS_UNION ))
  5596. {
  5597. // pipe with a UNION
  5598. RpcSemError(this , MyContext, UNIMPLEMENTED_FEATURE, "pipes can't contain unions" );
  5599. }
  5600. if (MyContext.AnyDescendantBits( HAS_HANDLE
  5601. | HAS_POINTER
  5602. | HAS_VAR_ARRAY
  5603. | HAS_CONF_ARRAY
  5604. | HAS_CONF_VAR_ARRAY
  5605. | HAS_CONTEXT_HANDLE
  5606. | HAS_CONF_PTR
  5607. | HAS_VAR_PTR
  5608. | HAS_CONF_VAR_PTR
  5609. | HAS_TRANSMIT_AS
  5610. | HAS_REPRESENT_AS
  5611. | HAS_INTERFACE_PTR
  5612. | HAS_DIRECT_CONF_OR_VAR ))
  5613. {
  5614. // All the above are illegal types within a pipe
  5615. RpcSemError(this, MyContext, ILLEGAL_PIPE_TYPE, NULL );
  5616. }
  5617. MyContext.ClearAncestorBits( IN_UNION | IN_NE_UNION | IN_ARRAY );
  5618. if ( MyContext.AnyAncestorBits( IN_ARRAY |
  5619. IN_UNION |
  5620. IN_NE_UNION |
  5621. IN_STRUCT ))
  5622. TypeSemError( this, MyContext, ILLEGAL_PIPE_EMBEDDING, NULL );
  5623. if ( MyContext.AnyAncestorBits( IN_TRANSMIT_AS |
  5624. IN_REPRESENT_AS |
  5625. IN_USER_MARSHAL |
  5626. IN_FUNCTION_RESULT ))
  5627. TypeSemError( this, MyContext, ILLEGAL_PIPE_CONTEXT, NULL );
  5628. if ( MyContext.AnyAncestorBits( IN_ENCODE_INTF ))
  5629. TypeSemError( this, MyContext, PIPES_WITH_PICKLING, NULL );
  5630. if ( MyContext.AnyAncestorBits( IN_OBJECT_INTF ) )
  5631. {
  5632. node_skl* pType = pParentCtxt->GetParent();
  5633. if ( pType->GetChild() )
  5634. {
  5635. pType = pType->GetChild();
  5636. }
  5637. }
  5638. // BUGBUG UNDONE
  5639. // Basically, a pipe can only be used as a parameter.
  5640. // Pipe parameters may only be passed by value or by reference.
  5641. // Need to make sure that /-Os mode isn't enabled (until support
  5642. // for it has been implemented).
  5643. // Need to enable /-Oi2 mode for the containing proc if we decide not
  5644. // to implement /-Oi mode.
  5645. MyContext.SetDescendantBits( (DESCENDANT_FLAGS) HAS_PIPE );
  5646. pParentCtxt->ReturnValues( MyContext );
  5647. }
  5648. void
  5649. node_safearray::SemanticAnalysis( SEM_ANALYSIS_CTXT * pParentCtxt )
  5650. {
  5651. SEM_ANALYSIS_CTXT MyContext( this, pParentCtxt );
  5652. FIELD_ATTR_INFO FAInfo;
  5653. PTRTYPE PtrKind = PTR_UNKNOWN;
  5654. BOOL fArrayParent = MyContext.AnyAncestorBits( IN_ARRAY );
  5655. // this maintains a reference to LPSAFEARRAY. This is
  5656. // necessary to generate the appropriate code when
  5657. // SAFEARRAY(type) construct is used outside the library block
  5658. char* szSafeArray = "LPSAFEARRAY";
  5659. SymKey SKey( szSafeArray, NAME_DEF );
  5660. named_node* pSafeArrayNode = pBaseSymTbl->SymSearch( SKey );
  5661. if ( pSafeArrayNode == 0 )
  5662. {
  5663. SemError( this, MyContext, UNDEFINED_SYMBOL, szSafeArray );
  5664. }
  5665. else
  5666. {
  5667. SetTypeAlias( pSafeArrayNode );
  5668. }
  5669. CheckDeclspecAlign( MyContext );
  5670. // See if context_handle applied to param reached us
  5671. if ( CheckContextHandle( MyContext ) )
  5672. {
  5673. MyContext.SetDescendantBits( HAS_HANDLE | HAS_CONTEXT_HANDLE );
  5674. }
  5675. if ( MyContext.FInSummary( ATTR_SWITCH_IS ) )
  5676. TypeSemError( this, MyContext, ARRAY_OF_UNIONS_ILLEGAL, NULL );
  5677. // if ( !MyContext.AnyAncestorBits( IN_LIBRARY ) )
  5678. // {
  5679. // SemError(this, MyContext, SAFEARRAY_NOT_SUPPORT_OUTSIDE_TLB, 0);
  5680. // }
  5681. ////////////////////////////////////////////////////////////////////////
  5682. // process pointer attributes
  5683. PtrKind = MyContext.GetPtrKind();
  5684. MIDL_ASSERT( PtrKind != PTR_UNKNOWN );
  5685. if ( PtrKind == PTR_FULL )
  5686. {
  5687. MyContext.SetDescendantBits( HAS_FULL_PTR );
  5688. }
  5689. if ( MyContext.ExtractAttribute( ATTR_PTR_KIND) )
  5690. TypeSemError( this, MyContext, MORE_THAN_ONE_PTR_ATTR, NULL );
  5691. // ref pointer may not be returned
  5692. if ( ( PtrKind == PTR_REF ) &&
  5693. MyContext.AllAncestorBits( IN_RPC | IN_FUNCTION_RESULT ) )
  5694. {
  5695. if (MyContext.FindNonDefAncestorContext()->GetParent()->NodeKind()
  5696. == NODE_PROC )
  5697. TypeSemError( this, MyContext, BAD_CON_REF_RT, NULL );
  5698. }
  5699. // unique or full pointer may not be out only
  5700. if ( ( PtrKind != PTR_REF ) &&
  5701. MyContext.AllAncestorBits( IN_RPC | IN_PARAM_LIST ) &&
  5702. !MyContext.AnyAncestorBits( UNDER_IN_PARAM |
  5703. IN_STRUCT |
  5704. IN_UNION |
  5705. IN_ARRAY |
  5706. IN_POINTER ) )
  5707. TypeSemError( this, MyContext, UNIQUE_FULL_PTR_OUT_ONLY, NULL );
  5708. MyContext.SetAncestorBits( IN_ARRAY );
  5709. // warn about OUT const things
  5710. if ( FInSummary( ATTR_CONST ) )
  5711. {
  5712. if ( MyContext.AnyAncestorBits( UNDER_OUT_PARAM ) )
  5713. RpcSemError( this, MyContext, CONST_ON_OUT_PARAM, NULL );
  5714. else if ( MyContext.AnyAncestorBits( IN_FUNCTION_RESULT ) )
  5715. RpcSemError( this, MyContext, CONST_ON_RETVAL, NULL );
  5716. }
  5717. /////////////////////////////////////////////////////////////////////////
  5718. // process field attributes
  5719. FAInfo.SetControl( FALSE, GetBasicType()->IsPtrOrArray() );
  5720. MyContext.ExtractFieldAttributes( &FAInfo );
  5721. switch ( FAInfo.Kind )
  5722. {
  5723. case FA_NONE:
  5724. {
  5725. break;
  5726. }
  5727. case FA_STRING:
  5728. {
  5729. // string attributes only allowed on char and wchar_t
  5730. if ( !GetBasicType()->IsStringableType() )
  5731. TypeSemError( this, MyContext, STRING_NOT_ON_BYTE_CHAR, NULL );
  5732. if ( MyContext.AllAncestorBits( UNDER_OUT_PARAM |
  5733. IN_PARAM_LIST |
  5734. IN_RPC ) &&
  5735. !MyContext.AnyAncestorBits( IN_STRUCT |
  5736. IN_UNION |
  5737. IN_POINTER |
  5738. IN_ARRAY |
  5739. UNDER_IN_PARAM ) )
  5740. TypeSemError( this, MyContext, DERIVES_FROM_UNSIZED_STRING, NULL );
  5741. if ( FAInfo.StringKind == STR_BSTRING )
  5742. TypeSemError( this, MyContext, BSTRING_NOT_ON_PLAIN_PTR, NULL );
  5743. // break; deliberate fall through to case below
  5744. }
  5745. case FA_VARYING:
  5746. {
  5747. MyContext.SetDescendantBits( HAS_VAR_ARRAY );
  5748. break;
  5749. }
  5750. case FA_CONFORMANT:
  5751. {
  5752. MyContext.SetDescendantBits( HAS_CONF_ARRAY );
  5753. break;
  5754. }
  5755. case FA_CONFORMANT_STRING:
  5756. {
  5757. // string attributes only allowed on char and wchar_t
  5758. if ( !GetBasicType()->IsStringableType() )
  5759. TypeSemError( this, MyContext, STRING_NOT_ON_BYTE_CHAR, NULL );
  5760. if ( FAInfo.StringKind == STR_BSTRING )
  5761. TypeSemError( this, MyContext, BSTRING_NOT_ON_PLAIN_PTR, NULL );
  5762. // break; deliberate fall through to case below
  5763. }
  5764. case FA_CONFORMANT_VARYING:
  5765. {
  5766. MyContext.SetDescendantBits( HAS_CONF_VAR_ARRAY );
  5767. break;
  5768. }
  5769. case FA_INTERFACE:
  5770. {
  5771. // gaj - tbd
  5772. break;
  5773. }
  5774. default: // string + varying combinations
  5775. {
  5776. TypeSemError( this, MyContext, INVALID_SIZE_ATTR_ON_STRING, NULL );
  5777. break;
  5778. }
  5779. }
  5780. // detect things like arrays of conf structs...
  5781. // if we have an array as an ancestor, and we have conformance, then complain
  5782. if ( MyContext.AnyDescendantBits( HAS_CONF_ARRAY | HAS_CONF_VAR_ARRAY ) &&
  5783. fArrayParent )
  5784. {
  5785. // see if there are any bad things between us and our parent array
  5786. SEM_ANALYSIS_CTXT * pCtxt = (SEM_ANALYSIS_CTXT *) pParentCtxt;
  5787. node_skl * pCur = pCtxt->GetParent();
  5788. // check up for anything other than def below proc
  5789. // make sure the proc only has one param
  5790. while ( pCur->NodeKind() != NODE_ARRAY )
  5791. {
  5792. if ( pCur->NodeKind() != NODE_DEF )
  5793. {
  5794. SemError( this, MyContext, ILLEGAL_CONFORMANT_ARRAY, NULL );
  5795. break;
  5796. }
  5797. pCtxt = (SEM_ANALYSIS_CTXT *) pCtxt->GetParentContext();
  5798. pCur = pCtxt->GetParent();
  5799. }
  5800. }
  5801. //////////////////////////////////////////////////////////////
  5802. // process the array element
  5803. GetChild()->SemanticAnalysis( &MyContext );
  5804. /*
  5805. // BSTR has sizeis_ptr, eventhough under variant, and it would be ugly to
  5806. // hardcode checking variant here. well...
  5807. if ( MyContext.AnyDescendantBits( HAS_CONF_ARRAY |
  5808. HAS_CONF_VAR_ARRAY |
  5809. HAS_VAR_ARRAY |
  5810. HAS_UNSAT_REP_AS |
  5811. HAS_CONTEXT_HANDLE |
  5812. HAS_CONF_PTR |
  5813. HAS_VAR_PTR |
  5814. HAS_CONF_VAR_PTR |
  5815. HAS_DIRECT_CONF_OR_VAR |
  5816. HAS_FUNC |
  5817. HAS_FULL_PTR |
  5818. HAS_TOO_BIG_HDL |
  5819. HAS_MULTIDIM_SIZING |
  5820. HAS_PIPE |
  5821. HAS_MULTIDIM_VECTOR |
  5822. HAS_SIZED_ARRAY |
  5823. HAS_SIZED_PTR ) )
  5824. TypeSemError( this, MyContext, INVALID_SAFEARRAY_ATTRIBUTE, NULL );
  5825. */
  5826. MyContext.SetDescendantBits( HAS_ARRAY );
  5827. // early binding of safearray(interface pointer) doesn't work
  5828. node_skl * pChild = GetChild()->GetBasicType();
  5829. SEM_ANALYSIS_CTXT * pIntfCtxt = (SEM_ANALYSIS_CTXT *)
  5830. MyContext.GetInterfaceContext();
  5831. BOOL fLocal = pIntfCtxt->FInSummary( ATTR_LOCAL );
  5832. fLocal |= MyContext.AnyAncestorBits( IN_LOCAL_PROC );
  5833. if ( pChild->NodeKind() == NODE_POINTER )
  5834. pChild = pChild->GetChild();
  5835. if ( IsInterfaceKind( pChild->NodeKind() ) &&
  5836. !MyContext.AnyAncestorBits( IN_LIBRARY ) &&
  5837. !fLocal )
  5838. SemError( this, MyContext, SAFEARRAY_IF_OUTSIDE_LIBRARY, NULL );
  5839. // disallow forward references as array elements
  5840. // NOTE- all safearray elements are VARIANTS, we don't really need
  5841. // to enforce this restriction for safearrays. Besides, enforcing
  5842. // this restriction breaks some of our test cases.
  5843. if ( MyContext.AnyDescendantBits( HAS_INCOMPLETE_TYPE ) )
  5844. {
  5845. MyContext.ClearDescendantBits( HAS_INCOMPLETE_TYPE );
  5846. }
  5847. MyContext.ClearDescendantBits( HAS_RECURSIVE_DEF );
  5848. if ( MyContext.AllDescendantBits( HAS_DIRECT_CONF_OR_VAR |
  5849. HAS_MULTIDIM_SIZING ) &&
  5850. MyContext.AnyDescendantBits( HAS_CONF_ARRAY | HAS_CONF_VAR_ARRAY ) &&
  5851. ( GetChild()->NodeKind() == NODE_DEF ) )
  5852. {
  5853. SemError( this, MyContext, NON_ANSI_MULTI_CONF_ARRAY, NULL );
  5854. }
  5855. MyContext.ClearDescendantBits( HAS_DIRECT_CONF_OR_VAR );
  5856. if ( ( FAInfo.Kind != FA_NONE ) &&
  5857. ( FAInfo.Kind != FA_STRING ) &&
  5858. ( FAInfo.Kind != FA_INTERFACE ) )
  5859. MyContext.SetDescendantBits( HAS_DIRECT_CONF_OR_VAR );
  5860. if ( MyContext.AnyDescendantBits( HAS_HANDLE ) )
  5861. TypeSemError( this, MyContext, BAD_CON_CTXT_HDL_ARRAY, NULL );
  5862. // don't allow functions as elements
  5863. if ( MyContext.AnyDescendantBits( HAS_FUNC ) &&
  5864. MyContext.AllAncestorBits( IN_INTERFACE | IN_RPC ) )
  5865. TypeSemError( this, MyContext, BAD_CON_ARRAY_FUNC, NULL );
  5866. // This is a hack to propagate the correct attributes up to the next level.
  5867. // Unfortunately, semantic analysis does more then just determine
  5868. // if the *.idl file is legal. It also catches known limitations of the
  5869. // engine, aids in determining the complexity of the marshaling problem,
  5870. // and other checks that change the state of the front end which directly
  5871. // affect the backend.
  5872. // gracelly handle the error case and the library case.
  5873. if ( ! pSafeArrayNode | MyContext.AnyAncestorBits( IN_LIBRARY ) )
  5874. {
  5875. // Is this class was used in a proxy, continue to pass up the proxy bits.
  5876. if ( fInProxy )
  5877. {
  5878. pSafeArrayNode->SemanticAnalysis( pParentCtxt );
  5879. return;
  5880. }
  5881. MyContext.ClearDescendantBits( HAS_STRUCT );
  5882. pParentCtxt->ReturnValues( MyContext );
  5883. return;
  5884. }
  5885. fInProxy = TRUE;
  5886. pSafeArrayNode->SemanticAnalysis( pParentCtxt );
  5887. };
  5888. void
  5889. node_async_handle::SemanticAnalysis( SEM_ANALYSIS_CTXT* )
  5890. {
  5891. }
  5892. BOOL IsOLEAutomationType( char* szTypeName )
  5893. {
  5894. BOOL fRet = FALSE;
  5895. // keep this list sorted!
  5896. static char* szOLEAutomationTypes[] =
  5897. {
  5898. "BSTR", // wchar_t
  5899. "CURRENCY", // struct
  5900. "DATE", // double
  5901. "SCODE", // long
  5902. "VARIANT",
  5903. "VARIANT_BOOL",
  5904. };
  5905. int uFirst = 0;
  5906. int uLast = (sizeof(szOLEAutomationTypes) - 1) / sizeof(char*);
  5907. int uMid = (uFirst + uLast) / 2;
  5908. while (uLast >= uFirst && uLast >= 0 && uFirst <= (sizeof(szOLEAutomationTypes) - 1) / sizeof(char*))
  5909. {
  5910. int nCmp = strcmp(szOLEAutomationTypes[uMid], szTypeName);
  5911. if (nCmp == 0)
  5912. {
  5913. fRet = TRUE;
  5914. break;
  5915. }
  5916. else if (nCmp > 0)
  5917. {
  5918. uLast = uMid - 1;
  5919. }
  5920. else
  5921. {
  5922. uFirst = uMid + 1;
  5923. }
  5924. uMid = (uFirst + uLast) / 2;
  5925. }
  5926. return fRet;
  5927. }
  5928. BOOL IsBasicOleAutoKind( NODE_T x)
  5929. {
  5930. // NODE_INT128, NODE_FLOAT80, NODE_FLOAT128 is not supported.
  5931. return ( (x) == NODE_DOUBLE || (x) == NODE_FLOAT || (x) == NODE_INT ||
  5932. (x) == NODE_SHORT || (x) == NODE_LONG || (x) == NODE_CHAR ||
  5933. (x) == NODE_INT32 ||
  5934. (x) == NODE_HYPER || (x) == NODE_INT64 || (x) == NODE_INT3264 ||
  5935. (x) == NODE_BOOLEAN || (x) == NODE_WCHAR_T
  5936. );
  5937. }
  5938. BOOL IsOLEAutoBasicType ( node_base_type* pNBT )
  5939. {
  5940. NODE_T nodeKind = pNBT->NodeKind();
  5941. if ( nodeKind == NODE_CHAR )
  5942. {
  5943. return ( (node_base_type*) pNBT )->IsUnsigned();
  5944. }
  5945. else
  5946. {
  5947. return TRUE;
  5948. }
  5949. }
  5950. BOOL IsOLEAutoInterface ( node_interface* pType )
  5951. {
  5952. node_interface* pNodeIf;
  5953. BOOL fRet = FALSE;
  5954. // pType may be a node_interface or a node_interaface_reference
  5955. // "normalize" it.
  5956. if ( pType->NodeKind() == NODE_INTERFACE_REFERENCE )
  5957. {
  5958. pNodeIf = (( node_interface_reference *) pType )->GetRealInterface();
  5959. }
  5960. else
  5961. {
  5962. pNodeIf = pType;
  5963. }
  5964. fRet = pNodeIf->HasOLEAutomation();
  5965. if ( !fRet )
  5966. {
  5967. // the interface is forward declared,
  5968. // and has not been analyzed for semantic errors,
  5969. // it does not have HasOleAutomation flag set.
  5970. fRet = pNodeIf->FTATTRInSummary( TATTR_OLEAUTOMATION ) ||
  5971. pNodeIf->FTATTRInSummary( TATTR_DUAL );
  5972. if ( !fRet )
  5973. {
  5974. // interface may be an IUnknown or an IDispatch and these do not
  5975. // have HasOleAutomation flag set.
  5976. fRet = pNodeIf->IsValidRootInterface();
  5977. if ( !fRet )
  5978. {
  5979. // It is not IUnknown. If it is not IFont or IDispatch, it is not
  5980. // an oleautomation compliant interface.
  5981. char* szIfName = pNodeIf->GetSymName();
  5982. fRet = !_stricmp(szIfName, "IDispatch") || !_stricmp(szIfName, "IFontDisp");
  5983. }
  5984. }
  5985. }
  5986. return fRet;
  5987. }
  5988. BOOL
  5989. IsOLEAutomationCompliant( node_skl* pParamType )
  5990. {
  5991. if ( pParamType == 0 )
  5992. {
  5993. return FALSE;
  5994. }
  5995. BOOL fConforms = FALSE;
  5996. NODE_T nKind = pParamType->NodeKind();
  5997. if ( nKind == NODE_SAFEARRAY || nKind == NODE_HREF || nKind == NODE_POINTER )
  5998. {
  5999. fConforms = IsOLEAutomationCompliant( pParamType->GetChild() );
  6000. }
  6001. else if ( IsInterfaceKind( nKind ) )
  6002. {
  6003. fConforms = IsOLEAutoInterface( (node_interface*) pParamType );
  6004. }
  6005. else if ( IsCoclassOrDispKind( nKind ) || nKind == NODE_ENUM || nKind == NODE_STRUCT ||
  6006. IsBasicOleAutoKind( nKind ) )
  6007. {
  6008. fConforms = TRUE;
  6009. }
  6010. else if ( nKind == NODE_DEF )
  6011. {
  6012. node_skl* pChild = pParamType->GetChild();
  6013. fConforms = IsOLEAutomationType( pParamType->GetSymName() ) ? TRUE : IsOLEAutomationCompliant( pChild );
  6014. }
  6015. else if ( nKind == NODE_FORWARD )
  6016. {
  6017. node_skl* pChild = ( (node_forward*) pParamType )->ResolveFDecl();
  6018. fConforms = ( pChild ) ? IsOLEAutomationCompliant( pChild ) : FALSE;
  6019. }
  6020. return fConforms;
  6021. }
  6022. bool
  6023. HasCorrelation( node_skl* pNode )
  6024. {
  6025. if (
  6026. pNode->FInSummary( ATTR_SIZE ) ||
  6027. pNode->FInSummary( ATTR_FIRST ) ||
  6028. pNode->FInSummary( ATTR_BYTE_COUNT ) ||
  6029. pNode->FInSummary( ATTR_LAST ) ||
  6030. pNode->FInSummary( ATTR_LENGTH ) ||
  6031. pNode->FInSummary( ATTR_MAX ) ||
  6032. pNode->FInSummary( ATTR_MIN ) ||
  6033. pNode->FInSummary( ATTR_SIZE ) ||
  6034. pNode->FInSummary( ATTR_IID_IS ) ||
  6035. pNode->FInSummary( ATTR_SWITCH_IS )
  6036. )
  6037. {
  6038. return true;
  6039. }
  6040. return false;
  6041. }
  6042. bool
  6043. node_skl::CheckContextHandle( SEM_ANALYSIS_CTXT& MyContext )
  6044. {
  6045. bool fSerialize = MyContext.ExtractAttribute( ATTR_SERIALIZE ) != 0;
  6046. bool fNoSerialize = MyContext.ExtractAttribute( ATTR_NOSERIALIZE ) != 0;
  6047. bool fContextHandle = MyContext.ExtractAttribute( ATTR_CONTEXT ) != 0;
  6048. // See if context_handle applied to param reached us
  6049. if ( fContextHandle )
  6050. {
  6051. // not allowed in DCE mode; context handle must be void *
  6052. TypeSemError( this, MyContext, CONTEXT_HANDLE_VOID_PTR, 0 );
  6053. TypeSemError( this, MyContext, CTXT_HDL_NON_PTR, 0 );
  6054. }
  6055. else
  6056. {
  6057. if ( fSerialize || fNoSerialize )
  6058. {
  6059. SemError( this, MyContext, NO_CONTEXT_HANDLE, GetSymName() );
  6060. }
  6061. }
  6062. if ( fSerialize && fNoSerialize )
  6063. {
  6064. SemError( this, MyContext, CONFLICTING_ATTRIBUTES, GetSymName() );
  6065. }
  6066. return fContextHandle;
  6067. }
  6068. extern CMessageNumberList GlobalMainMessageNumberList;
  6069. void
  6070. node_midl_pragma::SemanticAnalysis( SEM_ANALYSIS_CTXT* )
  6071. {
  6072. ProcessPragma();
  6073. }
  6074. void
  6075. node_midl_pragma::ProcessPragma()
  6076. {
  6077. LONG_PTR ulMsg = 0;
  6078. m_pMsgList->Init();
  6079. while ( m_pMsgList->GetNext( (void**) &ulMsg ) == STATUS_OK )
  6080. {
  6081. if ( m_PragmaType == mp_MessageDisable )
  6082. {
  6083. GlobalMainMessageNumberList.ResetMessageFlag( (long)ulMsg );
  6084. }
  6085. else
  6086. {
  6087. GlobalMainMessageNumberList.SetMessageFlag( (long)ulMsg );
  6088. }
  6089. }
  6090. }
  6091. void
  6092. node_decl_guid::SemanticAnalysis( SEM_ANALYSIS_CTXT* )
  6093. {
  6094. }