Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2238 lines
69 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1989-1999 Microsoft Corporation
  3. Module Name:
  4. ilxlat.cxx
  5. Abstract:
  6. Intermediate Language translator
  7. Notes:
  8. Author:
  9. GregJen Jun-11-1993 Created.
  10. Notes:
  11. ----------------------------------------------------------------------------*/
  12. /****************************************************************************
  13. * include files
  14. ***************************************************************************/
  15. #include "becls.hxx"
  16. #pragma hdrstop
  17. #include "ilxlat.hxx"
  18. #include "ilreg.hxx"
  19. #include "control.hxx"
  20. #include "tlgen.hxx"
  21. /****************************************************************************
  22. * local data
  23. ***************************************************************************/
  24. // #define trace_cg 1
  25. /****************************************************************************
  26. * externs
  27. ***************************************************************************/
  28. extern CMD_ARG * pCommand;
  29. extern BOOL IsTempName( char *);
  30. extern ccontrol * pCompiler;
  31. extern REUSE_DICT * pReUseDict;
  32. extern SymTable * pBaseSymTbl;
  33. /****************************************************************************
  34. * definitions
  35. ***************************************************************************/
  36. void
  37. AddToCGFileList( CG_FILE *& pCGList, CG_FILE * pFile )
  38. {
  39. if (pFile)
  40. {
  41. pFile->SetSibling( pCGList );
  42. pCGList = pFile;
  43. }
  44. }
  45. void XLAT_CTXT::InitializeMustAlign( node_skl * pPar )
  46. {
  47. if (pPar)
  48. {
  49. if (pPar->GetModifiers().IsModifierSet(ATTR_DECLSPEC_ALIGN))
  50. {
  51. GetMustAlign() = true;
  52. GetMemAlign() = __max(GetMemAlign(),
  53. pPar->GetModifiers().GetDeclspecAlign());
  54. }
  55. }
  56. }
  57. //--------------------------------------------------------------------
  58. //
  59. // XLAT_CTXT::~XLAT_CTXT
  60. //
  61. // Notes: If the node that created this context didn't remove all
  62. // the attributes it added, force the issue. This is done
  63. // mostly because tlb generation short-circuits code
  64. // generation and tends to leave attributes hanging around.
  65. // This causes asserts and possibly other problems in random
  66. // places later on. Also note that a lot of the top-level
  67. // stuff (interfaces, etc) don't strip much so you get lots
  68. // of hits with those.
  69. //
  70. //--------------------------------------------------------------------
  71. XLAT_CTXT::~XLAT_CTXT()
  72. {
  73. if ( !GetParent() || !GetParent()->HasAttributes() )
  74. return;
  75. named_node *pNode = dynamic_cast<named_node *>(GetParent());
  76. type_node_list attrs;
  77. node_base_attr *pAttr;
  78. MIDL_ASSERT( NULL != pNode);
  79. pNode->GetAttributeList(&attrs);
  80. while (ITERATOR_GETNEXT(attrs, pAttr))
  81. {
  82. #ifdef DUMP_UNEXTRACTED_ATTRIBUTES
  83. extern void GetSemContextString(char *, node_skl *, WALK_CTXT *);
  84. char szContext[1024];
  85. GetSemContextString(szContext, pNode, this);
  86. fprintf(
  87. stderr,
  88. "Unextracted attribute: %s: %s\n",
  89. pAttr->GetNodeNameString(),
  90. szContext );
  91. #endif
  92. ExtractAttribute( pAttr->GetAttrID() );
  93. }
  94. }
  95. //--------------------------------------------------------------------
  96. //
  97. // IsComplexReturn
  98. //
  99. // Notes: A complex return value is one that isn't be returned in an
  100. // ordinary register. structs, unions, and floating point
  101. // values are complex
  102. //
  103. //--------------------------------------------------------------------
  104. bool IsComplexReturn(node_skl *node)
  105. {
  106. // straight dce doesn't support complex returns in intrepreted mode yet
  107. if ( !pCommand->NeedsNDR64Run() )
  108. return false;
  109. node = node->GetNonDefSelf();
  110. NODE_T kind = node->NodeKind();
  111. if ( NODE_STRUCT == kind
  112. || NODE_UNION == kind
  113. || NODE_ARRAY == kind
  114. || NODE_FLOAT == kind
  115. || NODE_DOUBLE == kind
  116. || ( NODE_HYPER == kind && pCommand->Is32BitEnv() ) )
  117. {
  118. return true;
  119. }
  120. // REVIEW: NODE_INT64, NODE_LONGLONG
  121. return false;
  122. }
  123. //--------------------------------------------------------------------
  124. //
  125. // node_file::ILxlate
  126. //
  127. // Notes:
  128. //
  129. //
  130. //
  131. //--------------------------------------------------------------------
  132. CG_CLASS *
  133. node_file::ILxlate( XLAT_CTXT * pContext )
  134. {
  135. node_interface * pI = 0;
  136. CG_CLASS * pcgInterfaceList = NULL;
  137. CG_CLASS * pPrevChildCG = NULL;
  138. CG_PROXY_FILE * pProxyCG = NULL;
  139. CG_IID_FILE * pIidCG = NULL;
  140. CG_TYPELIBRARY_FILE * pLibCG = NULL;
  141. CG_NETMONSTUB_FILE * pNetmonCG = NULL;
  142. CG_NETMONSTUB_FILE * pNetmonObjCG = NULL;
  143. CG_CSTUB_FILE * pCCG = NULL;
  144. CG_SSTUB_FILE * pSCG = NULL;
  145. CG_HDR_FILE * pHCG = NULL;
  146. CG_CLASS * pChildCG = NULL;
  147. CG_FILE * pCGList = NULL;
  148. char * pHdrName = pCommand->GetHeader();
  149. XLAT_CTXT MyContext(this);
  150. BOOL HasObjectInterface = FALSE;
  151. BOOL HasRemoteProc = FALSE;
  152. BOOL HasRemoteObjectProc = FALSE;
  153. BOOL HasDefs = FALSE;
  154. BOOL HasLibrary = FALSE;
  155. #ifdef trace_cg
  156. printf("..node_file,\t%s\n", GetSymName());
  157. #endif
  158. // don't process for imported stuff
  159. if ( ImportLevel > 0 )
  160. {
  161. return NULL;
  162. }
  163. // at this point, there should be no more attributes...
  164. MIDL_ASSERT( !MyContext.HasAttributes() );
  165. //////////////////////////////////////////////////////////////////////
  166. // compute all the child nodes
  167. for(pI = (node_interface *)GetFirstMember();
  168. pI;
  169. pI = (node_interface *)pI->GetSibling())
  170. {
  171. // build a linked list of CG_INTERFACE and CG_OBJECT_INTERFACE nodes.
  172. // Notes: pChildCG points to first node. pPrevChildCG points to last node.
  173. MyContext.SetInterfaceContext( &MyContext );
  174. pcgInterfaceList = pI->ILxlate( &MyContext );
  175. if(pcgInterfaceList)
  176. {
  177. if (pPrevChildCG)
  178. {
  179. pPrevChildCG->SetSibling( pcgInterfaceList );
  180. }
  181. else
  182. {
  183. pChildCG = pcgInterfaceList;
  184. }
  185. pPrevChildCG = pcgInterfaceList;
  186. // advance to the end of the list (skipping inherited interfaces)
  187. while ( pPrevChildCG->GetSibling() )
  188. pPrevChildCG = pPrevChildCG->GetSibling();
  189. switch(pPrevChildCG->GetCGID())
  190. {
  191. case ID_CG_INTERFACE:
  192. //Check for a remote procedure.
  193. if(pPrevChildCG->GetChild())
  194. HasRemoteProc = TRUE;
  195. HasDefs = TRUE;
  196. break;
  197. case ID_CG_OBJECT_INTERFACE:
  198. case ID_CG_INHERITED_OBJECT_INTERFACE:
  199. HasDefs = TRUE;
  200. HasObjectInterface = TRUE;
  201. //Check for a remote object procedure or base interface
  202. if( pPrevChildCG->GetChild() ||
  203. ((CG_OBJECT_INTERFACE *)pPrevChildCG)->GetBaseInterfaceCG() )
  204. HasRemoteObjectProc = TRUE;
  205. break;
  206. case ID_CG_LIBRARY:
  207. HasLibrary = TRUE;
  208. if( pCommand->IsSwitchDefined( SWITCH_HEADER ) )
  209. HasDefs = TRUE;
  210. break;
  211. default:
  212. break;
  213. }
  214. }
  215. }
  216. // process the server and client stubs
  217. // make the list of imported files
  218. ITERATOR * pFileList = new ITERATOR;
  219. named_node * pCur;
  220. // make a list of the file nodes included directly by the main file
  221. // start with the first child of our parent
  222. pCur = (named_node *)
  223. ((node_source *) pContext->GetParent())
  224. ->GetFirstMember();
  225. while ( pCur )
  226. {
  227. if ( ( pCur->NodeKind() == NODE_FILE ) &&
  228. ( ( (node_file *) pCur )->GetImportLevel() == 1 ) )
  229. {
  230. // add all the files imported at lex level 1
  231. ITERATOR_INSERT( (*pFileList), ((void *) pCur) );
  232. }
  233. pCur = pCur->GetSibling();
  234. }
  235. ITERATOR_INIT( (*pFileList) );
  236. //////////////////////////////////////////////////////////////////////
  237. // manufacture the header file node
  238. if ( HasDefs )
  239. {
  240. pHCG = new CG_HDR_FILE( this,
  241. pHdrName,
  242. pFileList);
  243. pHCG->SetChild( pChildCG );
  244. }
  245. //////////////////////////////////////////////////////////////////////
  246. // manufacture the CG_SSTUB_FILE
  247. // if the IDL file contains at least one remotable function in a
  248. // non-object interface, then generate a server stub file.
  249. //
  250. if ( HasRemoteProc &&
  251. (pChildCG != NULL) ) // if server stub desired
  252. {
  253. pSCG = new CG_SSTUB_FILE(
  254. this,
  255. ( pCommand->GenerateSStub() ) ?
  256. pCommand->GetSstubFName():
  257. NULL,
  258. pHdrName
  259. );
  260. // plug in the child subtree and add the sstub to the head of the list
  261. pSCG->SetChild( pChildCG );
  262. }
  263. //////////////////////////////////////////////////////////////////////
  264. // manufacture the CG_CSTUB_FILE
  265. // if the IDL file contains at least one remotable function in a
  266. // non-object interface, then generate a client stub file.
  267. if ( HasRemoteProc &&
  268. (pChildCG != NULL) ) // if client stub desired
  269. {
  270. pCCG = new CG_CSTUB_FILE(
  271. this,
  272. ( pCommand->GenerateCStub() ) ?
  273. pCommand->GetCstubFName():
  274. NULL,
  275. pHdrName
  276. );
  277. pCCG->SetChild( pChildCG );
  278. }
  279. // If the IDL file contains at least one remotable function in an
  280. // object interface, then generate a proxy file.
  281. if ( HasRemoteObjectProc &&
  282. (pChildCG != NULL) ) // if proxy file desired
  283. {
  284. pProxyCG = new CG_PROXY_FILE(
  285. this,
  286. ( pCommand->GenerateProxy() ) ?
  287. pCommand->GetProxyFName():
  288. NULL,
  289. pHdrName
  290. );
  291. pProxyCG->SetChild( pChildCG );
  292. }
  293. // If the IDL file contains at least one object interface,
  294. // then generate an IID file.
  295. if ( (HasObjectInterface || (HasLibrary && HasDefs) )&&
  296. (pChildCG != NULL) ) // if IID file desired
  297. {
  298. pIidCG = new CG_IID_FILE(
  299. this,
  300. ( pCommand->GenerateIID() ) ?
  301. pCommand->GetIIDFName():
  302. NULL);
  303. pIidCG->SetChild( pChildCG );
  304. }
  305. // If the IDL file contains a library then gnerate a TYPELIBRARY_FILE
  306. if (HasLibrary && (NULL != pChildCG) )
  307. {
  308. #ifdef _WIN64
  309. bool fGenTypeLib = pCommand->Is64BitEnv() || ( pCommand->Is32BitEnv() && pCommand->IsSwitchDefined( SWITCH_ENV ) );
  310. #else
  311. bool fGenTypeLib = pCommand->Is32BitEnv() || ( pCommand->Is64BitEnv() && pCommand->IsSwitchDefined( SWITCH_ENV ) );
  312. #endif
  313. if ( fGenTypeLib && pCommand->GenerateTypeLibrary() )
  314. {
  315. pLibCG = new CG_TYPELIBRARY_FILE(
  316. this,
  317. pCommand->GetTypeLibraryFName() ) ;
  318. pLibCG->SetChild( pChildCG );
  319. }
  320. }
  321. // If the -netmon switch was used, generate the two NETMONSTUB_FILE's
  322. if ( pCommand->IsNetmonStubGenerationEnabled() )
  323. {
  324. if (HasRemoteProc)
  325. {
  326. pNetmonCG = new CG_NETMONSTUB_FILE(
  327. FALSE,
  328. this,
  329. pCommand->GetNetmonStubFName());
  330. pNetmonCG->SetChild( pChildCG );
  331. }
  332. if (HasRemoteObjectProc)
  333. {
  334. pNetmonObjCG = new CG_NETMONSTUB_FILE(
  335. TRUE,
  336. this,
  337. pCommand->GetNetmonStubObjFName());
  338. pNetmonObjCG->SetChild( pChildCG );
  339. }
  340. }
  341. /////////////////////////////////////////////////////////////////////
  342. // glue all the parts together by tacking onto the head of the list.
  343. // the final order is:
  344. // CStub - SStub - Proxy - IID - Hdr
  345. // doesn't need to create Hdr & tlb in ndr64 run.
  346. pCGList = NULL;
  347. AddToCGFileList( pCGList, pNetmonObjCG );
  348. AddToCGFileList( pCGList, pNetmonCG );
  349. if ( !pCommand->Is2ndCodegenRun() )
  350. AddToCGFileList( pCGList, pHCG );
  351. if ( !pCommand->Is2ndCodegenRun() )
  352. AddToCGFileList( pCGList, pIidCG );
  353. AddToCGFileList( pCGList, pProxyCG );
  354. AddToCGFileList( pCGList, pSCG );
  355. AddToCGFileList( pCGList, pCCG );
  356. if ( !pCommand->Is2ndCodegenRun() )
  357. AddToCGFileList( pCGList, pLibCG );
  358. return pCGList;
  359. };
  360. //--------------------------------------------------------------------
  361. //
  362. // node_implicit::ILxlate
  363. //
  364. // Notes:
  365. //
  366. // This is a little bit different, since it is not a node_skl...
  367. // therefore, it will not set up its own context
  368. //
  369. //--------------------------------------------------------------------
  370. CG_CLASS *
  371. node_implicit::ILxlate( XLAT_CTXT * pContext )
  372. {
  373. CG_NDR * pCG;
  374. if ( pHandleType->NodeKind() == NODE_HANDLE_T )
  375. {
  376. pCG = new CG_PRIMITIVE_HANDLE( pHandleType,
  377. pHandleID,
  378. *pContext );
  379. }
  380. else // assume generic handle
  381. {
  382. pCG = new CG_GENERIC_HANDLE( pHandleType,
  383. pHandleID,
  384. *pContext );
  385. }
  386. #ifdef trace_cg
  387. printf("..node_implicit,\t\n");
  388. #endif
  389. return pCG;
  390. }
  391. //--------------------------------------------------------------------
  392. //
  393. // node_proc::ILxlate
  394. //
  395. // Notes:
  396. //
  397. //
  398. //
  399. //--------------------------------------------------------------------
  400. CG_CLASS *
  401. node_proc::ILxlate( XLAT_CTXT * pContext )
  402. {
  403. MEM_ITER MemIter( this );
  404. node_param * pN;
  405. CG_PROC * pCG;
  406. CG_CLASS * pChildCG = NULL;
  407. CG_CLASS * pPrevChildCG = NULL;
  408. CG_CLASS * pFirstChildCG = NULL;
  409. CG_RETURN * pReturnCG = NULL;
  410. CG_CLASS * pBinding = NULL;
  411. CG_CLASS * pBindingParam = NULL;
  412. BOOL fHasCallback = FALSE;
  413. BOOL fNoCode = FALSE;
  414. BOOL fObject;
  415. BOOL fRetHresult = FALSE;
  416. BOOL fEnableAllocate;
  417. XLAT_CTXT MyContext( this, pContext );
  418. unsigned short OpBits = MyContext.GetOperationBits();
  419. XLAT_CTXT * pIntfCtxt = (XLAT_CTXT *)
  420. MyContext.GetInterfaceContext();
  421. node_interface * pIntf = (node_interface *)
  422. pIntfCtxt->GetParent();
  423. node_base_attr * pNotify,
  424. * pNotifyFlag;
  425. BOOL HasEncode = (NULL !=
  426. MyContext.ExtractAttribute( ATTR_ENCODE ) );
  427. BOOL HasDecode = (NULL !=
  428. MyContext.ExtractAttribute( ATTR_DECODE ) );
  429. node_call_as * pCallAs = (node_call_as *)
  430. MyContext.ExtractAttribute( ATTR_CALL_AS );
  431. bool fLocalProc = MyContext.ExtractAttribute( ATTR_LOCAL ) != 0;
  432. BOOL fLocal = (BOOL ) fLocalProc ||
  433. pIntfCtxt->FInSummary( ATTR_LOCAL );
  434. BOOL fLocalCall = IsCallAsTarget();
  435. unsigned short SavedProcCount = 0;
  436. unsigned short SavedCallbackProcCount = 0;
  437. node_param * pComplexReturn = NULL;
  438. MyContext.ExtractAttribute( ATTR_ENTRY );
  439. MyContext.ExtractAttribute( ATTR_ID );
  440. MyContext.ExtractAttribute( ATTR_HELPCONTEXT );
  441. MyContext.ExtractAttribute( ATTR_HELPSTRINGCONTEXT );
  442. MyContext.ExtractAttribute( ATTR_HELPSTRING );
  443. MyContext.ExtractAttribute( ATTR_IDLDESCATTR );
  444. MyContext.ExtractAttribute( ATTR_FUNCDESCATTR );
  445. MyContext.ExtractAttribute( ATTR_HIDDEN );
  446. MyContext.ExtractAttribute( ATTR_ASYNC );
  447. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  448. #ifdef trace_cg
  449. printf("..node_proc,\t%s\n", GetSymName());
  450. #endif
  451. BOOL fSupressHeader = FALSE;
  452. unsigned long ulOptFlags;
  453. unsigned long ulStackSize = 0;
  454. node_member_attr * pMA;
  455. while ( ( pMA = (node_member_attr *)MyContext.ExtractAttribute(ATTR_MEMBER) ) != 0 );
  456. // do my attribute parsing...
  457. fHasCallback = (NULL != MyContext.ExtractAttribute( ATTR_CALLBACK ) );
  458. fObject = (NULL != MyContext.ExtractAttribute( ATTR_OBJECT )) ||
  459. pIntfCtxt->FInSummary( ATTR_OBJECT );
  460. // do my attribute parsing... attributes to ignore here
  461. MyContext.ExtractAttribute( ATTR_OPTIMIZE );
  462. MyContext.ExtractAttribute( ATTR_EXPLICIT );
  463. HasEncode = HasEncode || pIntfCtxt->FInSummary( ATTR_ENCODE );
  464. HasDecode = HasDecode || pIntfCtxt->FInSummary( ATTR_DECODE );
  465. pNotify = MyContext.ExtractAttribute( ATTR_NOTIFY );
  466. pNotifyFlag = MyContext.ExtractAttribute( ATTR_NOTIFY_FLAG );
  467. fEnableAllocate = (NULL != MyContext.ExtractAttribute( ATTR_ENABLE_ALLOCATE ));
  468. fEnableAllocate = fEnableAllocate ||
  469. pIntfCtxt->FInSummary( ATTR_ENABLE_ALLOCATE ) ||
  470. pCommand->IsRpcSSAllocateEnabled();
  471. // do my attribute parsing...
  472. // locally applied [code] attribute overrides global [nocode] attribute
  473. fNoCode = MyContext.ExtractAttribute( ATTR_NOCODE ) ||
  474. pIntfCtxt->FInSummary( ATTR_NOCODE );
  475. fNoCode = !MyContext.ExtractAttribute( ATTR_CODE ) && fNoCode;
  476. if ( NULL != MyContext.ExtractAttribute( ATTR_CSTAGRTN ) )
  477. MyContext.SetAncestorBits( IL_CS_HAS_TAG_RTN );
  478. BOOL fImported = FALSE;
  479. if ( GetDefiningFile() )
  480. {
  481. fImported = GetDefiningFile()->GetImportLevel() != 0;
  482. }
  483. if ( fLocalProc && !IsCallAsTarget() && fObject )
  484. {
  485. SemError( this, MyContext, LOCAL_NO_CALL_AS, 0 );
  486. }
  487. // determine if the proc is local and
  488. // determine the proc number (local procs don't bump the number)
  489. if (fLocalCall || (fLocal && !fObject))
  490. {
  491. // return without making anything
  492. return NULL;
  493. }
  494. else
  495. {
  496. if ( fHasCallback )
  497. {
  498. ProcNum = ( pIntf ->GetCallBackProcCount() )++;
  499. }
  500. else
  501. {
  502. ProcNum = ( pIntf ->GetProcCount() )++;
  503. }
  504. }
  505. if ( fLocal && fObject && !MyContext.AnyAncestorBits(IL_IN_LIBRARY) )
  506. {
  507. if ( pIntf->IsValidRootInterface() )
  508. {
  509. pCG = new CG_IUNKNOWN_OBJECT_PROC( ProcNum,
  510. this,
  511. GetDefiningFile()->GetImportLevel() > 0,
  512. GetOptimizationFlags(),
  513. fHasDeny );
  514. }
  515. else
  516. {
  517. pCG = new CG_LOCAL_OBJECT_PROC( ProcNum,
  518. this,
  519. GetDefiningFile()->GetImportLevel() > 0,
  520. GetOptimizationFlags(),
  521. fHasDeny );
  522. }
  523. goto done;
  524. }
  525. SavedProcCount = pIntf->GetProcCount();
  526. SavedCallbackProcCount = pIntf->GetCallBackProcCount();
  527. // add the return type
  528. if ( HasReturn() )
  529. {
  530. node_skl * pReturnType = GetReturnType();
  531. CG_CLASS * pRetCG;
  532. // If the return value is complex it is treated in ndr as if a ref
  533. // pointer to the complex type was in the parameter list instead of
  534. // a true return value. Temporarily add a parameter to the type
  535. // to get the back-end parameter created.
  536. if ( IsComplexReturn( pReturnType ) )
  537. {
  538. pComplexReturn = new node_param;
  539. pComplexReturn->SetSymName( RETURN_VALUE_VAR_NAME );
  540. pComplexReturn->SetChild( new node_pointer( pReturnType) );
  541. pComplexReturn->GetChild()->GetModifiers().SetModifier( ATTR_TAGREF );
  542. pComplexReturn->SetAttribute( new node_base_attr( ATTR_OUT ) );
  543. MemIter.AddLastMember( pComplexReturn );
  544. ITERATOR_INIT( MemIter );
  545. }
  546. else
  547. {
  548. pRetCG = pReturnType->ILxlate( &MyContext );
  549. fRetHresult = (BOOL) ( pRetCG->GetCGID() == ID_CG_HRESULT );
  550. pReturnCG = new CG_RETURN( pReturnType,
  551. MyContext,
  552. (unsigned short) RTStatuses );
  553. pReturnCG->SetChild( pRetCG );
  554. }
  555. }
  556. // at this point, there should be no more attributes...
  557. MIDL_ASSERT( !MyContext.HasAttributes() );
  558. pContext->ReturnSize( MyContext );
  559. if ( MemIter.GetNumberOfArguments() > 0 )
  560. {
  561. //
  562. // for each of the parameters, call the core transformer.
  563. //
  564. while ( ( pN = (node_param *) MemIter.GetNext() ) != 0 )
  565. {
  566. // REVIEW: One could argue that hidden status params
  567. // aren't on the wire so there shouldn't be a CG node
  568. // for them. The main problem with this is that we
  569. // need to be able to calculate a stack offset for the
  570. // hidden param and that can only be done in the
  571. // back end.
  572. // Hidden status params are not really [out] params but the way
  573. // the -Os generator builds up local resources requires them to
  574. // be.
  575. if ( pN->IsExtraStatusParam()
  576. && ! ( GetOptimizationFlags() & OPTIMIZE_INTERPRETER_V2 ) )
  577. {
  578. pN->SetAttribute( ATTR_OUT );
  579. }
  580. pChildCG = pN->ILxlate( &MyContext );
  581. #ifdef trace_cg
  582. printf("back from..node_param %s\n",pN->GetSymName());
  583. printf("binding is now %08x\n",pBindingParam );
  584. printf("child is now %08x\n",pChildCG );
  585. #endif
  586. // pChildCG could be NULL if it's imported from .tlb somewhere else already
  587. if ( pChildCG )
  588. {
  589. // the first binding param gets picked up for binding
  590. if ( !pBindingParam
  591. && pN->IsBindingParam() )
  592. {
  593. #ifdef trace_cg
  594. printf("value for IsBindingParam is %08x\n",pN->IsBindingParam() );
  595. printf("binding found on node_param %s\n",pN->GetSymName());
  596. printf("binding is now %08x\n",pBindingParam );
  597. #endif
  598. pBindingParam = pChildCG;
  599. }
  600. // build up the parameter list
  601. if( pPrevChildCG )
  602. {
  603. pPrevChildCG->SetSibling( pChildCG );
  604. }
  605. else
  606. {
  607. pFirstChildCG = pChildCG;
  608. };
  609. // this is only a calculated guess. We need more information to make an accurate
  610. // estimate.
  611. unsigned long ulSize = ( ( CG_PARAM* ) pChildCG )->GetStackSize();
  612. ulSize += (8 - (ulSize % 8));
  613. ulStackSize += ulSize;
  614. pPrevChildCG = pChildCG;
  615. }
  616. else
  617. SemError( this, MyContext, FAILED_TO_GENERATE_PARAM, pN->GetSymName() );
  618. }
  619. }
  620. ulOptFlags = GetOptimizationFlags();
  621. if ( ( ulOptFlags & OPTIMIZE_INTERPRETER ) &&
  622. !( ulOptFlags & OPTIMIZE_INTERPRETER_V2 ) &&
  623. ( ulStackSize > INTERPRETER_THUNK_PARAM_SIZE_THRESHOLD ) )
  624. {
  625. if ( ForceNonInterpret() )
  626. {
  627. SemError( this, *pContext, OI_STACK_SIZE_EXCEEDED, 0 );
  628. }
  629. }
  630. if ( ulOptFlags & OPTIMIZE_INTERPRETER && ulStackSize > INTERPRETER_PROC_STACK_FRAME_SIZE_THRESHOLD )
  631. {
  632. if ( ForceNonInterpret() )
  633. {
  634. SemError( this, *pContext, STACK_FRAME_SIZE_EXCEEDED, GetSymName() );
  635. exit ( STACK_FRAME_SIZE_EXCEEDED );
  636. }
  637. }
  638. if (fForcedI2 && fForcedS)
  639. {
  640. // ERROR - Can't force it both ways.
  641. SemError( this, *pContext, CONFLICTING_OPTIMIZATION_REQUIREMENTS, 0 );
  642. exit ( CONFLICTING_OPTIMIZATION_REQUIREMENTS );
  643. }
  644. #ifdef trace_cg
  645. printf("done with param list for %s\n",GetSymName());
  646. printf("binding is now %08x\n",pBindingParam );
  647. #endif
  648. // get the binding information
  649. if ( pBindingParam )
  650. {
  651. pBinding = pBindingParam;
  652. while (! ((CG_NDR *) pBinding)->IsAHandle() )
  653. pBinding = pBinding->GetChild();
  654. // pBinding now points to the node for the binding handle
  655. }
  656. else // implicit handle or auto handle
  657. {
  658. // note: if no implicit handle,
  659. // then leave pBinding NULL for auto_handle
  660. if (pIntfCtxt->FInSummary( ATTR_IMPLICIT ) )
  661. {
  662. node_implicit * pImplAttr;
  663. pImplAttr = (node_implicit *) pIntf->GetAttribute( ATTR_IMPLICIT );
  664. pBinding = pImplAttr->ILxlate( &MyContext );
  665. }
  666. }
  667. #ifdef trace_cg
  668. printf("done with binding for %s",GetSymName());
  669. printf("binding is now %08x\n",pBinding );
  670. #endif
  671. // see if thunked interpreter needed for server side
  672. if ( GetOptimizationFlags() & OPTIMIZE_INTERPRETER )
  673. { // check for non-stdcall
  674. ATTR_T CallingConv;
  675. GetCallingConvention( CallingConv );
  676. if ( ( CallingConv != ATTR_STDCALL ) &&
  677. ( CallingConv != ATTR_NONE ) )
  678. {
  679. SetOptimizationFlags( unsigned short( GetOptimizationFlags() | OPTIMIZE_THUNKED_INTERPRET ) );
  680. }
  681. else if ( pCallAs )
  682. {
  683. SetOptimizationFlags( unsigned short( GetOptimizationFlags() | OPTIMIZE_THUNKED_INTERPRET ) );
  684. }
  685. else if ( pReturnCG ) // check the return type
  686. {
  687. CG_NDR * pRetTypeCG = (CG_NDR *) pReturnCG->GetChild();
  688. if ( !pCommand->NeedsNDR64Run()
  689. && pRetTypeCG->GetCGID() != ID_CG_CONTEXT_HDL )
  690. {
  691. // This check is bogus. First off, it should be checking the
  692. // memory size, not the wire size. Secondly, for straight dce
  693. // mode large (i.e. complex) return types are prohibited in
  694. // semantic analysis. Finally, it should be checking the size
  695. // against the pointer size, not 4.
  696. if ( ( pRetTypeCG->GetWireSize() > 4 ) ||
  697. ( !pRetTypeCG->IsSimpleType() &&
  698. !pRetTypeCG->IsPointer() ) )
  699. SetOptimizationFlags( unsigned short( GetOptimizationFlags() | OPTIMIZE_THUNKED_INTERPRET ) );
  700. }
  701. }
  702. }
  703. if ( fHasCallback )
  704. {
  705. pCG = new CG_CALLBACK_PROC(
  706. ProcNum,
  707. this,
  708. (CG_HANDLE *) pBinding,
  709. (CG_PARAM *) pBindingParam,
  710. HasAtLeastOneIn(),
  711. HasAtLeastOneOut(),
  712. HasAtLeastOneShipped(),
  713. fHasStatuses,
  714. fHasFullPointer,
  715. pReturnCG,
  716. GetOptimizationFlags(),
  717. OpBits,
  718. fHasDeny
  719. );
  720. }
  721. else if ( fObject )
  722. {
  723. BOOL fInherited = 0;
  724. if ( GetDefiningFile() )
  725. {
  726. fInherited = GetDefiningFile()->GetImportLevel() > 0;
  727. }
  728. if ( fInherited )
  729. {
  730. pCG = new CG_INHERITED_OBJECT_PROC(
  731. ProcNum,
  732. this,
  733. (CG_HANDLE *) pBinding,
  734. (CG_PARAM *) pBindingParam,
  735. HasAtLeastOneIn(),
  736. HasAtLeastOneOut(),
  737. HasAtLeastOneShipped(),
  738. fHasStatuses,
  739. fHasFullPointer,
  740. pReturnCG,
  741. GetOptimizationFlags(),
  742. OpBits,
  743. fHasDeny
  744. );
  745. }
  746. else
  747. {
  748. pCG = new CG_OBJECT_PROC(
  749. ProcNum,
  750. this,
  751. (CG_HANDLE *) pBinding,
  752. (CG_PARAM *) pBindingParam,
  753. HasAtLeastOneIn(),
  754. HasAtLeastOneOut(),
  755. HasAtLeastOneShipped(),
  756. fHasStatuses,
  757. fHasFullPointer,
  758. pReturnCG,
  759. GetOptimizationFlags(),
  760. OpBits,
  761. fHasDeny
  762. );
  763. }
  764. }
  765. else if ( HasEncode || HasDecode )
  766. {
  767. pCG = new CG_ENCODE_PROC(
  768. ProcNum,
  769. this,
  770. (CG_HANDLE *) pBinding,
  771. (CG_PARAM *) pBindingParam,
  772. HasAtLeastOneIn(),
  773. HasAtLeastOneOut(),
  774. HasAtLeastOneShipped(),
  775. fHasStatuses,
  776. fHasFullPointer,
  777. pReturnCG,
  778. GetOptimizationFlags(),
  779. OpBits,
  780. HasEncode,
  781. HasDecode,
  782. fHasDeny
  783. );
  784. }
  785. else
  786. {
  787. pCG = new CG_PROC(
  788. ProcNum,
  789. this,
  790. (CG_HANDLE *) pBinding,
  791. (CG_PARAM *) pBindingParam,
  792. HasAtLeastOneIn(),
  793. HasAtLeastOneOut(),
  794. HasAtLeastOneShipped(),
  795. fHasStatuses,
  796. fHasFullPointer,
  797. pReturnCG,
  798. GetOptimizationFlags(),
  799. OpBits,
  800. fHasDeny
  801. );
  802. }
  803. pCG->SetChild( pFirstChildCG );
  804. #ifdef trace_cg
  805. printf("....returning from %s\n",GetSymName());
  806. #endif
  807. pIntf->GetProcCount() = SavedProcCount;
  808. pIntf->GetCallBackProcCount() = SavedCallbackProcCount;
  809. done:
  810. // save a pointer to the interface CG node
  811. pCG->SetInterfaceNode( (CG_INTERFACE*) pIntf->GetCG( MyContext.AnyAncestorBits(IL_IN_LIBRARY) ) );
  812. if (fSupressHeader)
  813. pCG->SetSupressHeader();
  814. // mark nocode procs
  815. if ( fNoCode )
  816. pCG->SetNoCode();
  817. if ( pNotify )
  818. pCG->SetHasNotify();
  819. if ( pNotifyFlag )
  820. pCG->SetHasNotifyFlag();
  821. if ( fEnableAllocate )
  822. pCG->SetRpcSSSpecified( 1 );
  823. if ( fRetHresult )
  824. pCG->SetReturnsHRESULT();
  825. if (HasPipes())
  826. pCG->SetHasPipes(1);
  827. if ( pCallAs )
  828. pCG->SetCallAsName( pCallAs->GetCallAsName() );
  829. if ( HasExtraStatusParam() )
  830. pCG->SetHasExtraStatusParam();
  831. if ( HasAsyncHandle() )
  832. pCG->SetHasAsyncHandle();
  833. if ( HasAsyncUUID() )
  834. pCG->SetHasAsyncUUID();
  835. if ( HasServerCorr() )
  836. pCG->SetHasServerCorr();
  837. if ( HasClientCorr() )
  838. pCG->SetHasClientCorr();
  839. // A fake parameter was added to the type for complex return values.
  840. // Remove it.
  841. if ( pComplexReturn )
  842. {
  843. pCG->SetHasComplexReturnType();
  844. MemIter.RemoveLastMember();
  845. }
  846. pCG->SetCSTagRoutine( GetCSTagRoutine() );
  847. // Typelib generation does not remove ATTR_V1_ENUM.
  848. MyContext.ExtractAttribute( ATTR_V1_ENUM );
  849. // at this point, there should be no more attributes...
  850. MIDL_ASSERT( !MyContext.HasAttributes() );
  851. if ( ( pCG->GetOptimizationFlags() & OPTIMIZE_INTERPRETER ) &&
  852. !( pCG->GetOptimizationFlags() & OPTIMIZE_INTERPRETER_V2 ) &&
  853. pCommand->Is64BitEnv() )
  854. {
  855. SemError( this, *pContext, NO_OLD_INTERPRETER_64B, GetSymName() );
  856. exit ( NO_OLD_INTERPRETER_64B );
  857. }
  858. return pCG;
  859. }
  860. //--------------------------------------------------------------------
  861. //
  862. // node_param::ILxlate
  863. //
  864. // Notes:
  865. //
  866. //
  867. //
  868. //--------------------------------------------------------------------
  869. CG_CLASS *
  870. node_param::ILxlate( XLAT_CTXT * pContext )
  871. {
  872. CG_PARAM * pCG;
  873. CG_CLASS * pChildCG = NULL;
  874. expr_node * pSwitchExpr = NULL;
  875. #ifdef trace_cg
  876. printf("..node_param,\t%s\n",GetSymName());
  877. #endif
  878. PARAM_DIR_FLAGS F = 0;
  879. XLAT_CTXT MyContext( this, pContext );
  880. // make sure all member attributes get processed
  881. node_member_attr * pMA;
  882. MyContext.ExtractAttribute(ATTR_IDLDESCATTR);
  883. MyContext.ExtractAttribute(ATTR_DEFAULTVALUE);
  884. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  885. if ( MyContext.ExtractAttribute(ATTR_FLCID) )
  886. {
  887. LCID();
  888. }
  889. while ( ( pMA = (node_member_attr *)MyContext.ExtractAttribute(ATTR_MEMBER) ) != 0 )
  890. {
  891. switch (pMA->GetAttr())
  892. {
  893. case MATTR_RETVAL:
  894. Retval();
  895. break;
  896. case MATTR_OPTIONAL:
  897. {
  898. Optional();
  899. }
  900. break;
  901. default:
  902. char * pAttrName = pMA->GetNodeNameString();
  903. SemError( this, MyContext, INAPPLICABLE_ATTRIBUTE, pAttrName);
  904. break;
  905. }
  906. }
  907. if( MyContext.ExtractAttribute( ATTR_IN ) )
  908. {
  909. F |= IN_PARAM;
  910. }
  911. if( MyContext.ExtractAttribute( ATTR_OUT ) )
  912. {
  913. F |= OUT_PARAM;
  914. }
  915. if ( MyContext.ExtractAttribute( ATTR_PARTIAL_IGNORE ) )
  916. {
  917. F |= PARTIAL_IGNORE_PARAM;
  918. }
  919. // default to in
  920. if ( F == 0 && !IsExtraStatusParam() )
  921. F |= IN_PARAM;
  922. if ( MyContext.FInSummary( ATTR_SWITCH_IS ) )
  923. {
  924. node_switch_is * pAttr;
  925. if ( pCommand->IsNDR64Run() )
  926. {
  927. pAttr = (node_switch_is *) MyContext.GetAttribute( ATTR_SWITCH_IS );
  928. }
  929. else
  930. {
  931. pAttr = (node_switch_is *) MyContext.ExtractAttribute( ATTR_SWITCH_IS );
  932. }
  933. pSwitchExpr = pAttr->GetExpr();
  934. }
  935. BOOL fHasCSSTag = ( NULL != MyContext.ExtractAttribute( ATTR_STAG ) );
  936. BOOL fHasCSDRTag = ( NULL != MyContext.ExtractAttribute( ATTR_DRTAG ) );
  937. BOOL fHasCSRTag = ( NULL != MyContext.ExtractAttribute( ATTR_RTAG ) );
  938. MyContext.SetAncestorBits(
  939. ( fHasCSSTag ? IL_CS_STAG : 0 )
  940. | ( fHasCSDRTag ? IL_CS_DRTAG : 0 )
  941. | ( fHasCSRTag ? IL_CS_RTAG : 0 ) );
  942. BOOL HasForceAllocate = ( NULL != MyContext.ExtractAttribute( ATTR_FORCEALLOCATE ) );
  943. pChildCG = GetChild()->ILxlate( &MyContext );
  944. pContext->ReturnSize( MyContext );
  945. #ifdef trace_cg
  946. printf("..node_param back.. %s\n",GetSymName());
  947. #endif
  948. // make sure void parameters get skipped
  949. if ( !pChildCG )
  950. return NULL;
  951. pCG = new CG_PARAM( this,
  952. F,
  953. MyContext,
  954. pSwitchExpr,
  955. (unsigned short) Statuses );
  956. #ifdef trace_cg
  957. printf("..node_param ..... %08x child=%08x\n", pCG, pChildCG );
  958. fflush(stdout);
  959. #endif
  960. if ( IsExtraStatusParam() )
  961. pCG->SetIsExtraStatusParam();
  962. // only set the bit if there was non-toplevel only
  963. if ( fDontCallFreeInst == 1 )
  964. pCG->SetDontCallFreeInst( TRUE );
  965. #ifdef trace_cg
  966. printf("..node_param ........ %08x child=%08x\n", pCG, pChildCG );
  967. fflush(stdout);
  968. #endif
  969. pCG->SetChild( pChildCG );
  970. if (IsAsyncHandleParam())
  971. {
  972. pCG->SetIsAsyncHandleParam();
  973. }
  974. if ( IsSaveForAsyncFinish() )
  975. {
  976. pCG->SaveForAsyncFinish();
  977. }
  978. pCG->SetIsCSSTag( fHasCSSTag );
  979. pCG->SetIsCSDRTag( fHasCSDRTag );
  980. pCG->SetIsCSRTag( fHasCSRTag );
  981. if ( MyContext.AnyAncestorBits( IL_CS_HAS_TAG_RTN ) && pCG->IsSomeCSTag() )
  982. pCG->SetIsOmittedParam();
  983. #ifdef trace_cg
  984. printf("..node_param return %s\n",GetSymName());
  985. fflush(stdout);
  986. #endif
  987. if ( HasForceAllocate )
  988. {
  989. pCG->SetForceAllocate( );
  990. }
  991. if ( !MyContext.AnyAncestorBits(IL_IN_LIBRARY) )
  992. {
  993. SetCG( pCG );
  994. }
  995. // REVIEW: There is no concept of switch_type in a library block.
  996. // Perhaps issue an error in semantic analysis.
  997. if ( MyContext.AnyAncestorBits( IL_IN_LIBRARY )
  998. && MyContext.ExtractAttribute( ATTR_SWITCH_TYPE ) )
  999. {
  1000. SemError(
  1001. this,
  1002. MyContext,
  1003. IGNORE_UNIMPLEMENTED_ATTRIBUTE,
  1004. "[switch_type] in a library block");
  1005. }
  1006. return pCG;
  1007. }
  1008. const GUID_STRS DummyGuidStrs( "00000000", "0000", "0000", "0000", "000000000000" );
  1009. // helper function for adding a new list to the end of the list of children
  1010. inline
  1011. void AddToCGList(
  1012. const CG_CLASS * pCNew,
  1013. CG_CLASS * * ppChild,
  1014. CG_CLASS * * ppLastSibling )
  1015. {
  1016. CG_CLASS * pCurrent;
  1017. CG_CLASS * pNew = (CG_CLASS *) pCNew;
  1018. // hook the head on
  1019. if ( !*ppChild )
  1020. *ppChild = pNew;
  1021. else
  1022. (*ppLastSibling)->SetSibling( pNew );
  1023. // advance the last sibling pointer
  1024. *ppLastSibling = pNew;
  1025. while ( ( pCurrent = (*ppLastSibling)->GetSibling() ) != 0 )
  1026. *ppLastSibling = pCurrent;
  1027. }
  1028. //--------------------------------------------------------------------
  1029. //
  1030. // node_interface::ILxlate
  1031. //
  1032. // Notes: This function returns either a CG_INTERFACE or a
  1033. // CG_OBJECT_INTERFACE node.
  1034. //
  1035. //
  1036. //
  1037. //--------------------------------------------------------------------
  1038. CG_CLASS *
  1039. node_interface::ILxlate( XLAT_CTXT * pContext )
  1040. {
  1041. CG_NDR * pcgInterface = NULL;
  1042. CG_NDR * pResultCG = NULL;
  1043. CG_CLASS * pCG = NULL;
  1044. CG_CLASS * pChildCG = NULL;
  1045. CG_CLASS * pPrevChildCG = NULL;
  1046. MEM_ITER MemIter( this );
  1047. node_skl * pN;
  1048. XLAT_CTXT MyContext( this, pContext );
  1049. XLAT_CTXT ChildContext( MyContext );
  1050. node_guid * pGuid = (node_guid *)
  1051. MyContext.ExtractAttribute( ATTR_GUID );
  1052. GUID_STRS GuidStrs;
  1053. node_implicit * pImpHdl = NULL;
  1054. CG_HANDLE * pImpHdlCG = NULL;
  1055. NODE_T ChildKind;
  1056. BOOL IsPickle = MyContext.FInSummary( ATTR_ENCODE ) ||
  1057. MyContext.FInSummary( ATTR_DECODE );
  1058. BOOL fAllRpcSS = MyContext.FInSummary( ATTR_ENABLE_ALLOCATE ) ||
  1059. pCommand->IsRpcSSAllocateEnabled();
  1060. BOOL fObject = MyContext.FInSummary( ATTR_OBJECT );
  1061. node_interface * pBaseIntf = GetMyBaseInterface();
  1062. CG_OBJECT_INTERFACE * pBaseCG = NULL;
  1063. CG_OBJECT_INTERFACE * pCurrentCG = NULL;
  1064. CG_OBJECT_INTERFACE * pLastItfCG = 0;
  1065. BOOL fInheritedIntf = NULL;
  1066. MyContext.ExtractAttribute( ATTR_TYPEDESCATTR );
  1067. MyContext.ExtractAttribute( ATTR_HIDDEN );
  1068. MyContext.ExtractAttribute( ATTR_ASYNC );
  1069. MyContext.ExtractAttribute( ATTR_CSTAGRTN );
  1070. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  1071. #ifdef trace_cg
  1072. printf("..node_interface,\t%s\n", GetSymName());
  1073. #endif
  1074. if( FInSummary( ATTR_IMPLICIT ) )
  1075. {
  1076. pImpHdl = (node_implicit *) GetAttribute( ATTR_IMPLICIT );
  1077. if (pImpHdl)
  1078. pImpHdlCG = (CG_HANDLE *) pImpHdl->ILxlate( &MyContext );
  1079. }
  1080. if (pGuid)
  1081. GuidStrs = pGuid->GetStrs();
  1082. else
  1083. GuidStrs = DummyGuidStrs;
  1084. // don't pass the interface attributes down...
  1085. // save them off elsewhere
  1086. ChildContext.SetInterfaceContext( &MyContext );
  1087. // if we already got spit out, don't do it again...
  1088. if ( GetCG( MyContext.AnyAncestorBits(IL_IN_LIBRARY) ) )
  1089. return NULL;
  1090. // start the procnum counting over
  1091. GetProcCount() = 0;
  1092. GetCallBackProcCount() = 0;
  1093. // Generate the interface's CG node first
  1094. if( fObject || MyContext.AnyAncestorBits(IL_IN_LIBRARY))
  1095. {
  1096. // object interfaces need to have their base classes generated, too
  1097. if ( pBaseIntf )
  1098. {
  1099. pBaseCG = (CG_OBJECT_INTERFACE *) pBaseIntf->GetCG( MyContext.AnyAncestorBits(IL_IN_LIBRARY) );
  1100. if ( !pBaseCG )
  1101. {
  1102. XLAT_CTXT BaseCtxt( &ChildContext );
  1103. BaseCtxt.SetInterfaceContext( &BaseCtxt );
  1104. pCurrentCG = (CG_OBJECT_INTERFACE *)
  1105. pBaseIntf->ILxlate( &BaseCtxt );
  1106. AddToCGList( pCurrentCG, (CG_CLASS**) &pResultCG, (CG_CLASS**) &pLastItfCG );
  1107. // our base interface made the last one on the list
  1108. pBaseCG = pLastItfCG;
  1109. }
  1110. // start the procnum from our base interface
  1111. GetProcCount() = pBaseIntf->GetProcCount();
  1112. GetCallBackProcCount() = pBaseIntf->GetCallBackProcCount();
  1113. }
  1114. if ( GetFileNode() )
  1115. {
  1116. fInheritedIntf = GetFileNode()->GetImportLevel() > 0;
  1117. }
  1118. if ( IsValidRootInterface() )
  1119. {
  1120. pcgInterface = new CG_IUNKNOWN_OBJECT_INTERFACE(this,
  1121. GuidStrs,
  1122. FALSE,
  1123. FALSE,
  1124. pBaseCG,
  1125. fInheritedIntf);
  1126. }
  1127. else if ( fInheritedIntf )
  1128. {
  1129. pcgInterface = new CG_INHERITED_OBJECT_INTERFACE(this,
  1130. GuidStrs,
  1131. FALSE,
  1132. FALSE,
  1133. pBaseCG);
  1134. }
  1135. else
  1136. {
  1137. pcgInterface = new CG_OBJECT_INTERFACE(this,
  1138. GuidStrs,
  1139. FALSE,
  1140. FALSE,
  1141. pBaseCG);
  1142. }
  1143. }
  1144. else
  1145. {
  1146. pcgInterface = new CG_INTERFACE(this,
  1147. GuidStrs,
  1148. FALSE,
  1149. FALSE,
  1150. pImpHdlCG,
  1151. pBaseCG);
  1152. }
  1153. if ( fHasMSConfStructAttr )
  1154. {
  1155. ( (CG_INTERFACE*) pcgInterface)->SetHasMSConfStructAttr();
  1156. }
  1157. // store a pointer to our CG node
  1158. SetCG( MyContext.AnyAncestorBits(IL_IN_LIBRARY), pcgInterface );
  1159. // if we generated a bunch of new inherited interfaces, link us to the end
  1160. // of the list, and return the list
  1161. AddToCGList( pcgInterface, (CG_CLASS**) &pResultCG, (CG_CLASS**) &pLastItfCG );
  1162. BOOL fImported = FALSE;
  1163. if ( GetDefiningFile() )
  1164. {
  1165. fImported = GetDefiningFile()->GetImportLevel() != 0;
  1166. }
  1167. // if they specified LOCAL, don't generate any CG nodes (except for object)
  1168. if ( MyContext.FInSummary(ATTR_LOCAL) && !fObject )
  1169. {
  1170. return pResultCG;
  1171. }
  1172. //
  1173. // for each of the procedures.
  1174. //
  1175. CG_PROC * pBeginProc = NULL;
  1176. while ( ( pN = MemIter.GetNext() ) != 0 )
  1177. {
  1178. ChildKind = pN->NodeKind();
  1179. // proc nodes may hang under node_id's
  1180. if( ( ChildKind == NODE_PROC ) ||
  1181. ( ( ChildKind == NODE_ID )
  1182. && ( pN->GetChild()->NodeKind() == NODE_PROC ) ) ||
  1183. ( ( ChildKind == NODE_DEF )
  1184. && ( IsPickle ||
  1185. pN->FInSummary( ATTR_ENCODE ) ||
  1186. pN->FInSummary( ATTR_DECODE ) ) ) )
  1187. {
  1188. // skip call_as targets
  1189. if (ChildKind == NODE_PROC && ((node_proc *)pN)->IsCallAsTarget())
  1190. continue;
  1191. // translate target of call_as proc
  1192. CG_PROC * pTarget = NULL;
  1193. if (ChildKind == NODE_PROC)
  1194. {
  1195. node_proc * p = ((node_proc *)pN)->GetCallAsType();
  1196. if (p)
  1197. {
  1198. pTarget = (CG_PROC *) p->ILxlate( &ChildContext);
  1199. }
  1200. }
  1201. // translate CG_NODE
  1202. pChildCG = pN->ILxlate( &ChildContext );
  1203. // attach target of call_as proc
  1204. if ( pChildCG )
  1205. {
  1206. if (pTarget)
  1207. ((CG_PROC *)pChildCG)->SetCallAsCG(pTarget);
  1208. AddToCGList( pChildCG, &pCG, &pPrevChildCG );
  1209. }
  1210. // Connect Begin and Finish async DCOM procs together.
  1211. // CloneIFAndSplitMethods always places the procedures
  1212. // immediatly under the interface with the Finish proc
  1213. // immediatly following the begin proc. This code
  1214. // will need to be changed if CloneIFAndSplitMethods
  1215. // changes.
  1216. if ( NODE_PROC == ChildKind )
  1217. {
  1218. node_proc *pProc = ( node_proc * ) pN;
  1219. if ( pProc->IsBeginProc() )
  1220. {
  1221. MIDL_ASSERT( ( ( CG_NDR * ) pChildCG )->IsProc() );
  1222. pBeginProc = ( CG_PROC * )pChildCG;
  1223. #ifndef NDEBUG
  1224. // assert that the next proc is the finish proc
  1225. MEM_ITER NewMemIter = MemIter;
  1226. named_node *pNextNode = NewMemIter.GetNext();
  1227. MIDL_ASSERT( pNextNode );
  1228. MIDL_ASSERT( NODE_PROC == pNextNode->NodeKind() );
  1229. MIDL_ASSERT( ( (node_proc *)pNextNode )->IsFinishProc() );
  1230. #endif // NDEBUG
  1231. }
  1232. else if ( pProc->IsFinishProc() )
  1233. {
  1234. MIDL_ASSERT( ( ( CG_NDR * ) pChildCG )->IsProc() );
  1235. CG_PROC *pFinishProc = ( CG_PROC * )pChildCG;
  1236. // Link the begin and finsh procs together
  1237. pBeginProc->SetIsBeginProc();
  1238. pBeginProc->SetAsyncRelative( pFinishProc );
  1239. pFinishProc->SetIsFinishProc();
  1240. pFinishProc->SetAsyncRelative( pBeginProc );
  1241. pBeginProc = NULL;
  1242. }
  1243. }
  1244. }
  1245. }
  1246. // make sure we don't have too many procs
  1247. if ( fObject && fInheritedIntf )
  1248. {
  1249. if ( ( GetProcCount() > 256 ) )
  1250. {
  1251. // complain about too many delegated routines
  1252. SemError(this, MyContext, TOO_MANY_DELEGATED_PROCS, NULL);
  1253. }
  1254. else if ( GetProcCount() > 64 )
  1255. {
  1256. pCommand->GetNdrVersionControl().SetHasMoreThan64DelegatedProcs();
  1257. }
  1258. }
  1259. // mark ourselves if we are an all RPC SS interface
  1260. // or if enable is used anywhere within.
  1261. if ( fAllRpcSS )
  1262. {
  1263. ((CG_INTERFACE *)pcgInterface)->SetAllRpcSS( TRUE );
  1264. }
  1265. if ( fAllRpcSS || GetHasProcsWithRpcSs() )
  1266. {
  1267. ((CG_INTERFACE *)pcgInterface)->SetUsesRpcSS( TRUE );
  1268. }
  1269. // consume all the interface attributes
  1270. MyContext.ClearAttributes();
  1271. pContext->ReturnSize( MyContext );
  1272. pcgInterface->SetChild(pCG);
  1273. return pResultCG;
  1274. }
  1275. //--------------------------------------------------------------------
  1276. //
  1277. // node_interface_reference::ILxlate
  1278. //
  1279. // Notes:
  1280. //
  1281. //
  1282. //
  1283. //--------------------------------------------------------------------
  1284. CG_CLASS *
  1285. node_interface_reference::ILxlate( XLAT_CTXT * pContext )
  1286. {
  1287. XLAT_CTXT MyContext( this, pContext );
  1288. CG_CLASS * pCG = NULL;
  1289. #ifdef trace_cg
  1290. printf("..node_interface_reference,\t%s\n", GetSymName());
  1291. #endif
  1292. pCG = new CG_INTERFACE_POINTER( this,
  1293. (node_interface *) GetChild() );
  1294. pContext->ReturnSize( MyContext );
  1295. return pCG;
  1296. };
  1297. //--------------------------------------------------------------------
  1298. //
  1299. // node_source::ILxlate
  1300. //
  1301. // Notes:
  1302. //
  1303. //
  1304. //
  1305. //--------------------------------------------------------------------
  1306. CG_CLASS *
  1307. node_source::ILxlate( XLAT_CTXT * pContext )
  1308. {
  1309. MEM_ITER MemIter( this );
  1310. CG_CLASS * pCG;
  1311. CG_CLASS * pNew;
  1312. CG_CLASS * pChildCG = NULL;
  1313. CG_CLASS * pPrevChildCG = NULL;
  1314. node_skl * pN;
  1315. XLAT_CTXT MyContext( this, pContext );
  1316. #ifdef trace_cg
  1317. printf("..node_source,\t%s\n", GetSymName());
  1318. #endif
  1319. pCG = (CG_CLASS *) new CG_SOURCE( this );
  1320. //
  1321. // for each of the children.
  1322. //
  1323. while ( ( pN = MemIter.GetNext() ) != 0 )
  1324. {
  1325. pChildCG = pN->ILxlate( &MyContext );
  1326. if ( pChildCG )
  1327. {
  1328. if (pPrevChildCG)
  1329. {
  1330. pPrevChildCG->SetSibling( pChildCG );
  1331. }
  1332. else
  1333. {
  1334. pCG->SetChild(pChildCG);
  1335. };
  1336. pPrevChildCG = pChildCG;
  1337. while ( ( pNew = pPrevChildCG->GetSibling() ) != 0 )
  1338. pPrevChildCG = pNew;
  1339. }
  1340. }
  1341. pContext->ReturnSize( MyContext );
  1342. return pCG;
  1343. };
  1344. //--------------------------------------------------------------------
  1345. //
  1346. // node_echo_string::ILxlate
  1347. //
  1348. // Notes:
  1349. //
  1350. //
  1351. //
  1352. //--------------------------------------------------------------------
  1353. CG_CLASS *
  1354. node_echo_string::ILxlate( XLAT_CTXT* )
  1355. {
  1356. #ifdef trace_cg
  1357. printf("..node_echo_string,\t%s\n", GetSymName());
  1358. #endif
  1359. return 0;
  1360. };
  1361. //--------------------------------------------------------------------
  1362. //
  1363. // node_error::ILxlate
  1364. //
  1365. // Notes:
  1366. //
  1367. //
  1368. //
  1369. //--------------------------------------------------------------------
  1370. CG_CLASS *
  1371. node_error::ILxlate( XLAT_CTXT* )
  1372. {
  1373. #ifdef trace_cg
  1374. printf("..node_error,\t%s\n", GetSymName());
  1375. #endif
  1376. return 0;
  1377. };
  1378. CG_CLASS *
  1379. Transform(
  1380. IN node_skl * pIL )
  1381. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1382. Routine Description:
  1383. This routine performs the translation from the type graph into the
  1384. code generation classes.
  1385. Arguments:
  1386. pIL - a pointer to the il tranformer controlling structure.
  1387. Return Value:
  1388. A pointer to the new code generator class.
  1389. Notes:
  1390. This method should be called only on placeholder nodes like struct / proc
  1391. interface, file etc.
  1392. ----------------------------------------------------------------------------*/
  1393. {
  1394. XLAT_CTXT MyContext;
  1395. #ifdef trace_cg
  1396. printf("transforming...\n");
  1397. #endif
  1398. pReUseDict = new REUSE_DICT;
  1399. return pIL->ILxlate( &MyContext );
  1400. };
  1401. //--------------------------------------------------------------------
  1402. //
  1403. // node_library::ILxlate
  1404. //
  1405. // Notes:
  1406. //
  1407. //
  1408. //
  1409. //--------------------------------------------------------------------
  1410. CG_CLASS *
  1411. node_library::ILxlate( XLAT_CTXT * pContext )
  1412. {
  1413. MEM_ITER MemIter(this);
  1414. #ifdef trace_cg
  1415. printf("..node_library,\t%s\n", GetSymName());
  1416. #endif
  1417. XLAT_CTXT MyContext( this, pContext);
  1418. if ( pCommand->IsNDR64Run() )
  1419. {
  1420. if ( !pCommand->NeedsNDRRun() )
  1421. {
  1422. SemError( this, MyContext , NDR64_ONLY_TLB, GetSymName() );
  1423. }
  1424. return NULL;
  1425. }
  1426. MyContext.SetAncestorBits(IL_IN_LIBRARY);
  1427. XLAT_CTXT ChildContext( MyContext );
  1428. // don't pass the interface attributes down...
  1429. // save them off elsewhere
  1430. ChildContext.SetInterfaceContext( &MyContext );
  1431. CG_LIBRARY * pLib = new CG_LIBRARY(this, MyContext);
  1432. named_node * pN;
  1433. CG_CLASS * pLast = NULL;
  1434. CG_CLASS * pChild = 0;
  1435. while ( ( pN = MemIter.GetNext() ) != 0 )
  1436. {
  1437. switch(pN->NodeKind())
  1438. {
  1439. case NODE_FORWARD:
  1440. {
  1441. node_interface_reference * pIRef = (node_interface_reference *)pN->GetChild();
  1442. if (pIRef)
  1443. {
  1444. if (pIRef->NodeKind() == NODE_INTERFACE_REFERENCE)
  1445. {
  1446. // create a CG_INTEFACE_REFERENCE node that points to this node
  1447. pChild = new CG_INTERFACE_REFERENCE(pIRef, ChildContext);
  1448. // make sure that the interface gets ILxlated.
  1449. CG_CLASS * pRef = pIRef->GetRealInterface()->ILxlate(&ChildContext);
  1450. pChild->SetSibling(pRef);
  1451. }
  1452. else
  1453. {
  1454. if (pIRef->NodeKind() == NODE_COCLASS)
  1455. {
  1456. // don't process this type early
  1457. pChild = NULL;
  1458. }
  1459. else
  1460. {
  1461. pChild = pN->ILxlate(&ChildContext);
  1462. if (pChild && pChild->GetSibling())
  1463. pChild = NULL;
  1464. }
  1465. }
  1466. }
  1467. else
  1468. {
  1469. pChild = 0;
  1470. }
  1471. }
  1472. break;
  1473. case NODE_INTERFACE:
  1474. {
  1475. pChild = pN->ILxlate(&ChildContext);
  1476. // skip over inherited interfaces
  1477. while (pChild && pChild->GetCGID() == ID_CG_INHERITED_OBJECT_INTERFACE)
  1478. pChild=pChild->GetSibling();
  1479. }
  1480. break;
  1481. default:
  1482. // create the appropriate CG node
  1483. pChild = pN->ILxlate(&ChildContext);
  1484. if (pChild && pChild->GetSibling()) // We must have already entered this one.
  1485. pChild = NULL;
  1486. break;
  1487. }
  1488. // attach the CG_NODE to the end of my child list
  1489. if (NULL != pChild && pChild != pLast)
  1490. {
  1491. if (pLast)
  1492. {
  1493. pLast->SetSibling(pChild);
  1494. }
  1495. else
  1496. {
  1497. pLib->SetChild(pChild);
  1498. }
  1499. pLast = pChild;
  1500. // advance past the end of the list
  1501. while (pLast->GetSibling())
  1502. pLast = pLast->GetSibling();
  1503. }
  1504. }
  1505. SetCG(FALSE, pLib);
  1506. SetCG(TRUE, pLib);
  1507. return pLib;
  1508. }
  1509. //--------------------------------------------------------------------
  1510. //
  1511. // node_module::ILxlate
  1512. //
  1513. // Notes:
  1514. //
  1515. //
  1516. //
  1517. //--------------------------------------------------------------------
  1518. CG_CLASS *
  1519. node_module::ILxlate( XLAT_CTXT * pContext )
  1520. {
  1521. #ifdef trace_cg
  1522. printf("..node_module,\t%s\n", GetSymName());
  1523. #endif
  1524. CG_NDR * pcgModule = NULL;
  1525. CG_CLASS * pCG = NULL;
  1526. CG_CLASS * pChildCG = NULL;
  1527. CG_CLASS * pPrevChildCG = NULL;
  1528. MEM_ITER MemIter( this );
  1529. node_skl * pN;
  1530. XLAT_CTXT MyContext( this, pContext );
  1531. XLAT_CTXT ChildContext( MyContext );
  1532. MyContext.ExtractAttribute( ATTR_GUID );
  1533. MyContext.ExtractAttribute(ATTR_TYPEDESCATTR);
  1534. MyContext.ExtractAttribute( ATTR_HIDDEN );
  1535. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  1536. while (MyContext.ExtractAttribute(ATTR_TYPE));
  1537. // clear member attributes
  1538. while (MyContext.ExtractAttribute(ATTR_MEMBER));
  1539. // don't pass the interface attributes down...
  1540. // save them off elsewhere
  1541. ChildContext.SetInterfaceContext( &MyContext );
  1542. // if we already got spit out, don't do it again...
  1543. if ( GetCG( MyContext.AnyAncestorBits(IL_IN_LIBRARY) ) )
  1544. return NULL;
  1545. // generate our CG node
  1546. pcgModule = new CG_MODULE(this, MyContext);
  1547. // store a pointer to our CG node
  1548. SetCG( MyContext.AnyAncestorBits(IL_IN_LIBRARY), pcgModule );
  1549. //
  1550. // for each of the members.
  1551. //
  1552. while ( ( pN = MemIter.GetNext() ) != 0 )
  1553. {
  1554. pChildCG = pN->ILxlate( &ChildContext );
  1555. if ( pChildCG )
  1556. {
  1557. if (NODE_PROC == pN->NodeKind())
  1558. {
  1559. ((CG_PROC *)pChildCG)->SetProckind(PROC_STATIC);
  1560. }
  1561. AddToCGList( pChildCG, &pCG, &pPrevChildCG );
  1562. }
  1563. }
  1564. // consume all the interface attributes
  1565. MyContext.ClearAttributes();
  1566. pContext->ReturnSize( MyContext );
  1567. pcgModule->SetChild(pCG);
  1568. return pcgModule;
  1569. }
  1570. //--------------------------------------------------------------------
  1571. //
  1572. // node_coclass::ILxlate
  1573. //
  1574. // Notes:
  1575. //
  1576. //
  1577. //
  1578. //--------------------------------------------------------------------
  1579. CG_CLASS *
  1580. node_coclass::ILxlate( XLAT_CTXT * pContext )
  1581. {
  1582. #ifdef trace_cg
  1583. printf("..node_coclass,\t%s\n", GetSymName());
  1584. #endif
  1585. CG_NDR * pcgCoclass = NULL;
  1586. CG_CLASS * pCG = NULL;
  1587. CG_CLASS * pChildCG = NULL;
  1588. CG_CLASS * pPrevChildCG = NULL;
  1589. MEM_ITER MemIter( this );
  1590. node_skl * pN;
  1591. XLAT_CTXT MyContext( this, pContext );
  1592. XLAT_CTXT ChildContext(MyContext);
  1593. MyContext.ExtractAttribute( ATTR_GUID );
  1594. MyContext.ExtractAttribute(ATTR_TYPEDESCATTR);
  1595. MyContext.ExtractAttribute( ATTR_HIDDEN );
  1596. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  1597. while (MyContext.ExtractAttribute(ATTR_TYPE));
  1598. // clear member attributes
  1599. while (MyContext.ExtractAttribute(ATTR_MEMBER));
  1600. // don't pass the interface attributes down...
  1601. // save them off elsewhere
  1602. ChildContext.SetInterfaceContext( &MyContext );
  1603. // if we already got spit out, don't do it again...
  1604. if ( GetCG( MyContext.AnyAncestorBits(IL_IN_LIBRARY) ) )
  1605. return NULL ;
  1606. // generate our CG node
  1607. pcgCoclass = new CG_COCLASS(this, MyContext);
  1608. // store a pointer to our CG node
  1609. SetCG( MyContext.AnyAncestorBits(IL_IN_LIBRARY), pcgCoclass );
  1610. //
  1611. // for every member of the coclass
  1612. //
  1613. node_skl * pChild = 0;
  1614. while ( ( pN = MemIter.GetNext()) != 0 )
  1615. {
  1616. pChild = pN;
  1617. while(NODE_FORWARD == pChild->NodeKind() || NODE_HREF == pChild->NodeKind())
  1618. {
  1619. pChild = pChild->GetChild();
  1620. if ( !pChild )
  1621. {
  1622. XLAT_CTXT ChildErrContext( pN, &MyContext );
  1623. SemError( pN, ChildErrContext, UNSATISFIED_FORWARD, pN->GetSymName() );
  1624. exit( UNSATISFIED_FORWARD );
  1625. }
  1626. }
  1627. pChildCG = pChild->ILxlate( &ChildContext );
  1628. if (pChild->IsInterfaceOrObject())
  1629. {
  1630. // pChildCG = ((node_interface * )pChild)->GetCG(TRUE);
  1631. pChildCG = new CG_INTERFACE_POINTER(this, (node_interface *)pChild );
  1632. }
  1633. /*
  1634. if ( pChildCG && NODE_DISPINTERFACE == pChild->NodeKind())
  1635. {
  1636. pChildCG = new CG_INTERFACE_POINTER(this, pChild, NULL);
  1637. //((node_dispinterface *) pChild)->GetCG( MyContext.AnyAncestorBits(IL_IN_LIBRARY) );
  1638. }
  1639. */
  1640. if ( pChildCG )
  1641. AddToCGList( pChildCG, &pCG, &pPrevChildCG );
  1642. }
  1643. // consume all the interface attributes
  1644. MyContext.ClearAttributes();
  1645. pContext->ReturnSize( MyContext );
  1646. pcgCoclass->SetChild(pCG);
  1647. return pcgCoclass;
  1648. }
  1649. //--------------------------------------------------------------------
  1650. //
  1651. // node_dispinterface::ILxlate
  1652. //
  1653. // Notes:
  1654. //
  1655. //
  1656. //
  1657. //--------------------------------------------------------------------
  1658. CG_CLASS *
  1659. node_dispinterface::ILxlate( XLAT_CTXT * pContext )
  1660. {
  1661. #ifdef trace_cg
  1662. printf("..node_dispinterface,\t%s\n", GetSymName());
  1663. #endif
  1664. CG_NDR * pcgInterface = NULL;
  1665. CG_CLASS * pCG = NULL;
  1666. CG_CLASS * pChildCG = NULL;
  1667. CG_CLASS * pPrevChildCG = NULL;
  1668. CG_CLASS * pcgDispatch = NULL;
  1669. MEM_ITER MemIter( this );
  1670. node_skl * pN;
  1671. XLAT_CTXT MyContext( this, pContext );
  1672. XLAT_CTXT BaseContext( MyContext ); // context passed to IDispatch
  1673. XLAT_CTXT ChildContext( MyContext );
  1674. node_guid * pGuid = (node_guid *)
  1675. MyContext.ExtractAttribute( ATTR_GUID );
  1676. GUID_STRS GuidStrs;
  1677. NODE_T ChildKind;
  1678. node_interface * pBaseIntf;
  1679. MyContext.ExtractAttribute(ATTR_TYPEDESCATTR);
  1680. MyContext.ExtractAttribute( ATTR_HIDDEN );
  1681. while(MyContext.ExtractAttribute(ATTR_CUSTOM));
  1682. while (MyContext.ExtractAttribute(ATTR_TYPE));
  1683. // clear member attributes
  1684. while (MyContext.ExtractAttribute(ATTR_MEMBER));
  1685. if (pGuid)
  1686. GuidStrs = pGuid->GetStrs();
  1687. // don't pass the interface attributes down...
  1688. // save them off elsewhere
  1689. BaseContext.SetInterfaceContext( &MyContext );
  1690. ChildContext.SetInterfaceContext( &MyContext );
  1691. // if we already got spit out, don't do it again...
  1692. if ( GetCG( MyContext.AnyAncestorBits(IL_IN_LIBRARY) ) )
  1693. return NULL;
  1694. //
  1695. // ILxlate IDispatch
  1696. //
  1697. pcgDispatch = GetIDispatch()->ILxlate(&BaseContext);
  1698. pcgDispatch = ((node_interface *)GetIDispatch())->GetCG( MyContext.AnyAncestorBits(IL_IN_LIBRARY) );
  1699. // generate our CG node
  1700. pcgInterface = new CG_DISPINTERFACE(this, GuidStrs,(CG_OBJECT_INTERFACE *)pcgDispatch);
  1701. // store a pointer to our CG node
  1702. SetCG( MyContext.AnyAncestorBits(IL_IN_LIBRARY), pcgInterface );
  1703. // Either we have a single base interface, or we have no base interface.
  1704. pN = MemIter.GetNext();
  1705. if (pN)
  1706. {
  1707. ChildKind = pN->NodeKind();
  1708. if (ChildKind == NODE_FORWARD)
  1709. {
  1710. // We have a base interface
  1711. pBaseIntf = (node_interface *)GetMyBaseInterfaceReference();
  1712. // process the base interface
  1713. if (pBaseIntf)
  1714. {
  1715. pChildCG = pBaseIntf->ILxlate(&ChildContext);
  1716. if ( pChildCG )
  1717. AddToCGList( pChildCG, &pCG, &pPrevChildCG );
  1718. }
  1719. }
  1720. }
  1721. //
  1722. // for each of the procedures.
  1723. //
  1724. while( pN )
  1725. {
  1726. ChildKind = pN->NodeKind();
  1727. // proc nodes may hang under node_id's
  1728. if( (ChildKind == NODE_FIELD) ||
  1729. ( ChildKind == NODE_PROC ) ||
  1730. ( ( ChildKind == NODE_ID ) && ( pN->GetChild()->NodeKind() == NODE_PROC ) ) )
  1731. {
  1732. pChildCG = pN->ILxlate( &ChildContext );
  1733. if ( pChildCG )
  1734. AddToCGList( pChildCG, &pCG, &pPrevChildCG );
  1735. }
  1736. pN = MemIter.GetNext();
  1737. }
  1738. // consume all the interface attributes
  1739. MyContext.ClearAttributes();
  1740. pContext->ReturnSize( MyContext );
  1741. pcgInterface->SetChild(pCG);
  1742. return pcgInterface;
  1743. }
  1744. //--------------------------------------------------------------------
  1745. //
  1746. // node_pipe::ILxlate
  1747. //
  1748. // Notes:
  1749. //
  1750. //
  1751. //
  1752. //--------------------------------------------------------------------
  1753. CG_CLASS *
  1754. node_pipe::ILxlate( XLAT_CTXT * pContext )
  1755. {
  1756. #ifdef trace_cg
  1757. printf("..node_pipe,\t%s\n", GetSymName());
  1758. #endif
  1759. CG_CLASS * pChildCG;
  1760. XLAT_CTXT MyContext( this, pContext );
  1761. CG_PIPE * pCG = new CG_PIPE (
  1762. this,
  1763. MyContext
  1764. );
  1765. // if /deny is not specified, ignore [range]
  1766. // if [range] is not ignored, new format string is
  1767. // generated for pipes.
  1768. if ( pCommand->IsSwitchDefined( SWITCH_ROBUST ) )
  1769. {
  1770. pCG->SetRangeAttribute( ( node_range_attr* ) MyContext.ExtractAttribute( ATTR_RANGE ) );
  1771. }
  1772. pChildCG = GetChild()->ILxlate( &MyContext );
  1773. pContext->ReturnSize( MyContext );
  1774. pCG->SetChild( pChildCG );
  1775. return pCG;
  1776. };
  1777. //--------------------------------------------------------------------
  1778. //
  1779. // node_safearray::ILxlate
  1780. //
  1781. // Notes:
  1782. //
  1783. //
  1784. //
  1785. //--------------------------------------------------------------------
  1786. CG_CLASS *
  1787. node_safearray::ILxlate( XLAT_CTXT * pContext )
  1788. {
  1789. #ifdef trace_cg
  1790. printf("..node_safearray,\t%s\n", GetSymName());
  1791. #endif
  1792. CG_CLASS * pChildCG;
  1793. XLAT_CTXT MyContext( this, pContext );
  1794. CG_SAFEARRAY * pCG = new CG_SAFEARRAY(this, MyContext);
  1795. // SAFEARRAY, being defined in the public IDL files, has a known
  1796. // alignment of 4. Now the struct etc. that embeds the SAFEARRAY
  1797. // may have a different alignment but the struct code will make it
  1798. // right by choosing min(ZeePee, max(children)).
  1799. // The child of the node is a type specifier from SAFEARRAY(type).
  1800. // The type alias is the LPSAFEARRAY
  1801. pCG->SetMemoryAlignment( 4 );
  1802. MyContext.GetMemAlign() = 4;
  1803. pContext->ReturnSize( MyContext );
  1804. pChildCG = GetChild()->ILxlate( &MyContext );
  1805. pCG->SetChild( pChildCG );
  1806. // If the SAFEARRAY was not used in a proxy, just pass up the SAFEARRAY class.
  1807. if ( ! fInProxy )
  1808. return pCG;
  1809. // If the SAFEARRAY was used in a proxy, pass up the the annoted node for
  1810. // LPSAFEARRAY.
  1811. CG_NDR *pTypeAliasCG = (CG_NDR*) ( GetTypeAlias()->ILxlate( pContext ) );
  1812. MIDL_ASSERT( pTypeAliasCG->GetCGID() == ID_CG_USER_MARSHAL );
  1813. CG_USER_MARSHAL *pUserMarshalCG = (CG_USER_MARSHAL *)pTypeAliasCG;
  1814. pUserMarshalCG->SetTypeDescGenerator( pCG );
  1815. return pUserMarshalCG;
  1816. }
  1817. CG_CLASS*
  1818. node_async_handle::ILxlate( XLAT_CTXT * pContext )
  1819. {
  1820. #ifdef trace_cg
  1821. printf("..node_async_handle,\t%s\n", GetSymName());
  1822. #endif
  1823. XLAT_CTXT MyContext( this, pContext );
  1824. CG_ASYNC_HANDLE* pAsyncHdl = new CG_ASYNC_HANDLE( this, MyContext );
  1825. return pAsyncHdl;
  1826. }
  1827. CG_CLASS*
  1828. node_midl_pragma::ILxlate( XLAT_CTXT* )
  1829. {
  1830. return 0;
  1831. }
  1832. CG_CLASS*
  1833. node_decl_guid::ILxlate( XLAT_CTXT* )
  1834. {
  1835. return 0;
  1836. }