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.

1321 lines
44 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1999.
  5. //
  6. // File: implib.cxx
  7. //
  8. // Contents: import lib functions
  9. //
  10. // Classes: NODE_MANAGER
  11. //
  12. // Functions: TypelibError
  13. // TypeinfoError
  14. // GetStringFromGuid
  15. // AddTypeLibraryMembers
  16. //
  17. // History: 5-02-95 stevebl Created
  18. //
  19. //----------------------------------------------------------------------------
  20. #pragma warning ( disable : 4514 )
  21. #include "tlcommon.hxx"
  22. #include "tlgen.hxx"
  23. #include "tllist.hxx"
  24. #include "becls.hxx"
  25. #include "walkctxt.hxx"
  26. // Initialize an instance of a type library list.
  27. // This way it will clean itself up as necessary.
  28. CTypeLibraryList gtllist;
  29. extern short ImportLevel;
  30. //+---------------------------------------------------------------------------
  31. //
  32. // Function: TypelibError
  33. //
  34. // Synopsis: Report generic type library error and exit.
  35. //
  36. // Arguments: [szFile] - file associated with the error
  37. //
  38. // History: 5-02-95 stevebl Created
  39. //
  40. //----------------------------------------------------------------------------
  41. void TypelibError(char * szFile, HRESULT /* UNREF hr */)
  42. {
  43. RpcError(NULL, 0, ERR_TYPELIB, szFile);
  44. exit(ERR_TYPELIB);
  45. }
  46. //+---------------------------------------------------------------------------
  47. //
  48. // Function: TypeinfoError
  49. //
  50. // Synopsis: Report generic type info error and exit.
  51. //
  52. // History: 5-02-95 stevebl Created
  53. //
  54. //----------------------------------------------------------------------------
  55. void TypeinfoError(HRESULT /* UNREF hr */)
  56. {
  57. RpcError(NULL, 0, ERR_TYPEINFO, NULL);
  58. exit(ERR_TYPEINFO);
  59. }
  60. //+---------------------------------------------------------------------------
  61. //
  62. // Function: AddToGuidString
  63. //
  64. // Synopsis: Private helper function for GetStringFromGuid.
  65. // Adds exactly cch hex characters to the string pch.
  66. //
  67. // Arguments: [pch] - pointer to the next available position in the string
  68. // buffer
  69. // [cch] - number of characters to add to the string buffer
  70. // [uVal] - value to be converted to text representation
  71. //
  72. // History: 5-02-95 stevebl Created
  73. //
  74. // Modifies: pch is advanced by cch characters (i.e. left pointing to the
  75. // next available position in the buffer).
  76. //
  77. // Notes: pch must be large enough to accept the characters.
  78. // The resulting string is not null terminated.
  79. //
  80. //----------------------------------------------------------------------------
  81. void AddToGuidString(char * &pch, unsigned cch, unsigned long uVal)
  82. {
  83. char bVal;
  84. unsigned long uMask = 0xf << ((cch - 1) * 4);
  85. while (cch)
  86. {
  87. bVal = (char)((uVal & uMask) >> ((cch - 1) * 4));
  88. if (bVal < 10)
  89. *(pch++) = char( '0' + bVal );
  90. else
  91. *(pch++) = char ( 'a' + bVal - 10 );
  92. uMask >>= 4;
  93. cch--;
  94. }
  95. }
  96. //+---------------------------------------------------------------------------
  97. //
  98. // Function: GetStringFromGuid
  99. //
  100. // Synopsis: returns the string representation of a guid
  101. //
  102. // Arguments: [g] - guid
  103. //
  104. // Returns: pointer to a newly allocated string
  105. //
  106. // History: 5-02-95 stevebl Created
  107. //
  108. // Notes: It is up to the caller to free the resulting string.
  109. //
  110. //----------------------------------------------------------------------------
  111. char * GetStringFromGuid(GUID &g)
  112. {
  113. char * sz = new char [37];
  114. char * pch = sz;
  115. AddToGuidString(pch, 8, g.Data1);
  116. *(pch++) = '-';
  117. AddToGuidString(pch, 4, g.Data2);
  118. *(pch++) = '-';
  119. AddToGuidString(pch, 4, g.Data3);
  120. *(pch++) = '-';
  121. int i;
  122. for (i = 0; i < 2; i++)
  123. {
  124. AddToGuidString(pch, 2, g.Data4[i]);
  125. }
  126. *(pch++) = '-';
  127. for (; i < 8; i++)
  128. {
  129. AddToGuidString(pch, 2, g.Data4[i]);
  130. }
  131. *(pch++) = '\0';
  132. return sz;
  133. }
  134. struct NODE_MANAGER_ELEMENT
  135. {
  136. ITypeInfo * pti;
  137. named_node * pskl;
  138. NODE_MANAGER_ELEMENT * pNext;
  139. };
  140. //+---------------------------------------------------------------------------
  141. //
  142. // Class: NODE_MANAGER
  143. //
  144. // Purpose: Maintains an ordered list of every ITypeInfo for which a
  145. // node_skl has been generated.
  146. //
  147. // Interface: GetNode -- retrieve a node_skl * from a type library
  148. //
  149. // History: 5-02-95 stevebl Created
  150. //
  151. // Notes: A client can call GetNode() to get a node_skl * from an
  152. // ITypeInfo pointer. If one has previously been generated then
  153. // the caller will get a pointer to the previously generated
  154. // node. Otherwise, GetNode() will call ExpandTI to generate one.
  155. //
  156. // This class exists as a mechanism to avoid infinite recursion
  157. // when importing type infos with cyclic type dependencies.
  158. //
  159. //----------------------------------------------------------------------------
  160. class NODE_MANAGER
  161. {
  162. private:
  163. NODE_MANAGER_ELEMENT * pHead;
  164. void ExpandTI(named_node * &pNode, ITypeInfo * pti);
  165. node_skl * GetNodeFromTYPEDESC(TYPEDESC tdesc, ITypeInfo * pti);
  166. named_node * GetNodeFromVARDESC(VARDESC vdesc, ITypeInfo * pti);
  167. named_node * GetNodeFromFUNCDESC(FUNCDESC fdesc, ITypeInfo *pti);
  168. void SetIDLATTRS(named_node * pNode, IDLDESC idldesc);
  169. void AddMembers(MEMLIST * pNode, TYPEATTR * ptattr, ITypeInfo * pti);
  170. expr_node * GetValueOfConstant(VARIANT * pVar);
  171. public:
  172. NODE_MANAGER()
  173. {
  174. pHead = NULL;
  175. }
  176. ~NODE_MANAGER()
  177. {
  178. NODE_MANAGER_ELEMENT * pNext;
  179. while (pHead)
  180. {
  181. pHead->pti->Release();
  182. pNext = pHead->pNext;
  183. delete(pHead);
  184. pHead = pNext;
  185. };
  186. }
  187. node_skl * GetNode(ITypeInfo * pti);
  188. } gNodeManager;
  189. BOOL FAddImportLib(char * szLibraryFileName)
  190. {
  191. return gtllist.Add(szLibraryFileName);
  192. }
  193. BOOL FIsLibraryName(char * szName)
  194. {
  195. return (NULL != gtllist.FindLibrary(szName));
  196. }
  197. extern SymTable * pBaseSymTbl;
  198. node_href::~node_href()
  199. {
  200. if (pTypeInfo)
  201. ((ITypeInfo *)pTypeInfo)->Release();
  202. }
  203. extern IINFODICT * pInterfaceInfoDict;
  204. char * GenIntfName();
  205. //+---------------------------------------------------------------------------
  206. //
  207. // Member: node_href::Resolve
  208. //
  209. // Synopsis: Expands a referenced type info into a complete type graph.
  210. //
  211. // Returns: Pointer to the expanded typegraph.
  212. //
  213. // History: 5-02-95 stevebl Created
  214. //
  215. //----------------------------------------------------------------------------
  216. named_node * node_href::Resolve()
  217. {
  218. char * sz;
  219. named_node * pReturn = (named_node *)GetChild();
  220. if (!pReturn)
  221. {
  222. pInterfaceInfoDict->StartNewInterface();
  223. // start a dummy interface for intervening stuff
  224. node_interface * pOuter = new node_interface;
  225. pOuter->SetSymName( GenIntfName() );
  226. pOuter->SetFileNode( GetDefiningFile() );
  227. pInterfaceInfoDict->SetInterfaceNode( pOuter );
  228. pReturn = (named_node *)gNodeManager.GetNode((ITypeInfo*)pTypeInfo);
  229. SetChild(pReturn);
  230. sz = pReturn->GetSymName();
  231. if ( sz )
  232. SetSymName(sz);
  233. pInterfaceInfoDict->EndNewInterface();
  234. }
  235. return pReturn;
  236. }
  237. //+---------------------------------------------------------------------------
  238. //
  239. // Member: NODE_MANAGER::GetNode
  240. //
  241. // Synopsis: Gets a type graph node from a type info pointer.
  242. //
  243. // Arguments: [pti] - type info pointer
  244. //
  245. // Returns: pointer to the type graph described by the type info
  246. //
  247. // History: 5-02-95 stevebl Created
  248. //
  249. //----------------------------------------------------------------------------
  250. node_skl * NODE_MANAGER::GetNode(ITypeInfo * pti)
  251. {
  252. NODE_MANAGER_ELEMENT ** ppThis = &pHead;
  253. while (*ppThis && (*ppThis)->pti <= pti)
  254. {
  255. if ((*ppThis)->pti == pti)
  256. return (*ppThis)->pskl;
  257. ppThis = &((*ppThis)->pNext);
  258. }
  259. NODE_MANAGER_ELEMENT * pNew = new NODE_MANAGER_ELEMENT;
  260. pNew->pti = pti;
  261. // Make sure no one can release this ITypeInfo pointer out from under us.
  262. // The corresponding release() occurs in NODE_MANAGER's destructor.
  263. pti->AddRef();
  264. // insert the new node into the table
  265. pNew->pNext = *ppThis;
  266. *ppThis = pNew;
  267. // expand the node
  268. ExpandTI(pNew->pskl, pti);
  269. ((named_node*)(pNew->pskl))->SetFileNode(pInterfaceInfoDict->GetInterfaceNode()->GetDefiningFile() );
  270. ((named_node*)(pNew->pskl))->SetDefiningTLB(pInterfaceInfoDict->GetInterfaceNode()->GetDefiningFile() );
  271. return pNew->pskl;
  272. }
  273. //+---------------------------------------------------------------------------
  274. //
  275. // Member: NODE_MANAGER::ExpandTI
  276. //
  277. // Synopsis: This is where all the work gets done.
  278. // Takes a type info pointer and expands it into a type graph.
  279. //
  280. // Arguments: [pti] - pointer to the type info
  281. //
  282. // Returns: pointer to the type graph
  283. //
  284. // History: 5-02-95 stevebl Created
  285. //
  286. //----------------------------------------------------------------------------
  287. void NODE_MANAGER::ExpandTI(named_node * &pNode, ITypeInfo * pti)
  288. {
  289. TYPEATTR * ptattr;
  290. HRESULT hr;
  291. BSTR bstrName;
  292. pNode = NULL;
  293. hr = pti->GetTypeAttr(&ptattr);
  294. pti->GetDocumentation(-1, &bstrName, NULL, NULL, NULL);
  295. char * szName = TranscribeO2A( bstrName );
  296. LateBound_SysFreeString(bstrName);
  297. BOOL fExtractGuid = TRUE;
  298. switch(ptattr->typekind)
  299. {
  300. case TKIND_MODULE:
  301. pNode = new node_module();
  302. pNode->SetSymName(szName);
  303. // Add properties and methods
  304. AddMembers((MEMLIST *)((node_module *)pNode), ptattr, pti);
  305. break;
  306. case TKIND_DISPATCH:
  307. // The code under the if has never been run due to the bug in the condition.
  308. // The condition according to the comment below should read as in the next line.
  309. //
  310. // if ( ! (ptattr->wTypeFlags & (TYPEFLAG_FOLEAUTOMATION | TYPEFLAG_FDUAL)) )
  311. //
  312. // However, fixing the line according to the original intentions brought in
  313. // a regression because the code paths have changed.
  314. // Hence, this has been commented out as a workaround for the VC 5.0 release
  315. // to force the code to execute like previously.
  316. //
  317. /*
  318. if ( 0 == ptattr->wTypeFlags & (TYPEFLAG_FOLEAUTOMATION | TYPEFLAG_FDUAL) )
  319. {
  320. pNode = new node_dispinterface();
  321. pNode->SetSymName(szName);
  322. // Ignore impltypes, add properties and methods
  323. AddMembers((MEMLIST *)((node_dispinterface *)pNode), ptattr, pti);
  324. break;
  325. }
  326. */
  327. // if TYPEFLAG_FOLEAUTOMATION or TYPEFLAG_FDUAL is set,
  328. // erase it's impltype (which will be IDispatch since it is
  329. // really a dispinterface) then fall through and treat it as a
  330. // normal interface
  331. ptattr->cImplTypes = 0;
  332. // fall through
  333. case TKIND_INTERFACE:
  334. {
  335. pNode = new node_interface();
  336. // consider processing all attributes
  337. if ( ( ptattr->wTypeFlags & ( TYPEFLAG_FOLEAUTOMATION | TYPEFLAG_FDUAL ) ) != 0 )
  338. {
  339. ( ( node_interface* ) pNode )->HasOLEAutomation( TRUE );
  340. }
  341. pNode->SetSymName(szName);
  342. // Add impltype as base interface reference
  343. if (ptattr->cImplTypes)
  344. {
  345. ITypeInfo * ptiRef;
  346. HREFTYPE hrt;
  347. hr = pti->GetRefTypeOfImplType(0, &hrt);
  348. hr = pti->GetRefTypeInfo(hrt, &ptiRef);
  349. if (FAILED(hr))
  350. {
  351. TypeinfoError(hr);
  352. }
  353. node_interface_reference * pir =
  354. new node_interface_reference((node_interface *)GetNode(ptiRef));
  355. int implflags;
  356. hr = pti->GetImplTypeFlags(0, &implflags);
  357. if (implflags & IMPLTYPEFLAG_FDEFAULT)
  358. {
  359. pir->SetAttribute(ATTR_DEFAULT);
  360. }
  361. if (implflags & IMPLTYPEFLAG_FSOURCE)
  362. {
  363. pir->SetAttribute(new node_member_attr(MATTR_SOURCE));
  364. }
  365. if (implflags & IMPLTYPEFLAG_FDEFAULTVTABLE)
  366. {
  367. pir->SetAttribute(new node_member_attr(MATTR_DEFAULTVTABLE));
  368. }
  369. if (implflags & IMPLTYPEFLAG_FRESTRICTED)
  370. {
  371. pir->SetAttribute(new node_member_attr(MATTR_RESTRICTED));
  372. }
  373. ((node_interface *)pNode)->SetMyBaseInterfaceReference(pir);
  374. ptiRef->Release();
  375. // NOTE - Multiple inheritance is not supported.
  376. }
  377. else
  378. {
  379. if (0 == _stricmp(szName, "IUnknown"))
  380. ((node_interface *)pNode)->SetValidRootInterface();
  381. }
  382. // Add properties and methods as children
  383. AddMembers((MEMLIST *)((node_interface *)pNode), ptattr, pti);
  384. }
  385. break;
  386. case TKIND_COCLASS:
  387. pNode = new node_coclass();
  388. pNode->SetSymName(szName);
  389. // Add impltypes
  390. {
  391. unsigned cImplTypes = ptattr->cImplTypes;
  392. while (cImplTypes--)
  393. {
  394. ITypeInfo * ptiRef;
  395. HREFTYPE hrt;
  396. hr = pti->GetRefTypeOfImplType(cImplTypes, &hrt);
  397. hr = pti->GetRefTypeInfo(hrt, &ptiRef);
  398. if (FAILED(hr))
  399. {
  400. TypeinfoError(hr);
  401. }
  402. node_interface_reference * pir =
  403. new node_interface_reference((node_interface *)GetNode(ptiRef));
  404. int implflags;
  405. hr = pti->GetImplTypeFlags(cImplTypes, &implflags);
  406. if (implflags & IMPLTYPEFLAG_FDEFAULT)
  407. {
  408. pir->SetAttribute(ATTR_DEFAULT);
  409. }
  410. if (implflags & IMPLTYPEFLAG_FSOURCE)
  411. {
  412. pir->SetAttribute(new node_member_attr(MATTR_SOURCE));
  413. }
  414. if (implflags & IMPLTYPEFLAG_FDEFAULTVTABLE)
  415. {
  416. pir->SetAttribute(new node_member_attr(MATTR_DEFAULTVTABLE));
  417. }
  418. if (implflags & IMPLTYPEFLAG_FRESTRICTED)
  419. {
  420. pir->SetAttribute(new node_member_attr(MATTR_RESTRICTED));
  421. }
  422. ((node_coclass *)pNode)->AddFirstMember(pir);
  423. ptiRef->Release();
  424. }
  425. }
  426. break;
  427. case TKIND_ALIAS:
  428. pNode = new node_def(szName);
  429. // add the type as a child
  430. pNode->SetChild(GetNodeFromTYPEDESC(ptattr->tdescAlias, pti));
  431. pNode->SetAttribute(new node_type_attr(TATTR_PUBLIC));
  432. fExtractGuid = FALSE;
  433. break;
  434. case TKIND_ENUM:
  435. pNode = new node_enum(szName);
  436. // add enumeration fields
  437. AddMembers((MEMLIST *)((node_enum *)pNode), ptattr, pti);
  438. fExtractGuid = FALSE;
  439. ( ( node_enum * ) pNode )->SetZeePee( ptattr->cbAlignment );
  440. break;
  441. case TKIND_RECORD:
  442. pNode = new node_struct(szName);
  443. // add members
  444. AddMembers((MEMLIST *)((node_struct *)pNode), ptattr, pti);
  445. fExtractGuid = FALSE;
  446. ( ( node_struct * ) pNode )->SetZeePee( ptattr->cbAlignment );
  447. break;
  448. case TKIND_UNION:
  449. pNode = new node_union(szName);
  450. // add members
  451. AddMembers((MEMLIST *)((node_union *)pNode), ptattr, pti);
  452. fExtractGuid = FALSE;
  453. ( ( node_union * ) pNode )->SetZeePee( ptattr->cbAlignment );
  454. break;
  455. default:
  456. MIDL_ASSERT(!"Illegal TKIND");
  457. break;
  458. }
  459. // make sure that all the TYPEDESC flags are preserved
  460. pNode->SetAttribute(new node_constant_attr(
  461. new expr_constant(ptattr->wTypeFlags), ATTR_TYPEDESCATTR));
  462. // and set each individual flag that we know about as of this writing
  463. if (ptattr->wTypeFlags & TYPEFLAG_FLICENSED)
  464. {
  465. pNode->SetAttribute(new node_type_attr(TATTR_LICENSED));
  466. }
  467. if (ptattr->wTypeFlags & TYPEFLAG_FAPPOBJECT)
  468. {
  469. pNode->SetAttribute(new node_type_attr(TATTR_APPOBJECT));
  470. }
  471. if (ptattr->wTypeFlags & TYPEFLAG_FCONTROL)
  472. {
  473. pNode->SetAttribute(new node_type_attr(TATTR_CONTROL));
  474. }
  475. if (ptattr->wTypeFlags & TYPEFLAG_FDUAL)
  476. {
  477. pNode->SetAttribute(new node_type_attr(TATTR_DUAL));
  478. }
  479. if (ptattr->wTypeFlags & TYPEFLAG_FPROXY)
  480. {
  481. pNode->SetAttribute(new node_type_attr(TATTR_PROXY));
  482. }
  483. if (ptattr->wTypeFlags & TYPEFLAG_FNONEXTENSIBLE)
  484. {
  485. pNode->SetAttribute(new node_type_attr(TATTR_NONEXTENSIBLE));
  486. }
  487. if (ptattr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)
  488. {
  489. pNode->SetAttribute(new node_type_attr(TATTR_OLEAUTOMATION));
  490. }
  491. if (ptattr->wTypeFlags & TYPEFLAG_FRESTRICTED)
  492. {
  493. pNode->SetAttribute(new node_member_attr(MATTR_RESTRICTED));
  494. }
  495. if (ptattr->wTypeFlags & TYPEFLAG_FPREDECLID)
  496. {
  497. pNode->SetAttribute(new node_member_attr(MATTR_PREDECLID));
  498. }
  499. if (ptattr->wTypeFlags & TYPEFLAG_FHIDDEN)
  500. {
  501. pNode->SetAttribute(ATTR_HIDDEN);
  502. }
  503. if (fExtractGuid)
  504. {
  505. char * szGuid = GetStringFromGuid(ptattr->guid);
  506. pNode->SetAttribute(new node_guid(szGuid));
  507. }
  508. pti->ReleaseTypeAttr(ptattr);
  509. }
  510. //+---------------------------------------------------------------------------
  511. //
  512. // Member: NODE_MANAGER::GetNodeFromTYPEDESC
  513. //
  514. // Synopsis: Returns part of a type graph from a TYPEDESC structure.
  515. //
  516. // Arguments: [tdesc] - the TYPEDESC
  517. // [pti] - the type info from which the TYPEDESC was retrieved
  518. //
  519. // Returns: type graph node
  520. //
  521. // History: 5-02-95 stevebl Created
  522. //
  523. // Notes: There are currently a couple of problem base types:
  524. // VT_CY, VT_BSTR, VT_VARIANT, VT_DISPATCH, and VT_UNKNOWN.
  525. //
  526. // These types are currently expanded by looking them up in the
  527. // global symbol table. This works because currently oaidl.idl
  528. // is always imported when an ODL library statement is
  529. // ecountered. It would be nice to be able to remove our
  530. // dependancy on oaidl.idl but before we can do that, we need to
  531. // reimplement this code to expand these types in another way.
  532. // (NOTE that because these are BASE TYPES in ODL, there is no
  533. // way to place their definitions in a type library. This means
  534. // that it is not sufficient to simply get their definitions
  535. // from some standard type library such as STDLIB.TLB.)
  536. //
  537. //----------------------------------------------------------------------------
  538. node_skl * NODE_MANAGER::GetNodeFromTYPEDESC(TYPEDESC tdesc, ITypeInfo * pti)
  539. {
  540. node_skl * pReturn = NULL;
  541. switch (tdesc.vt)
  542. {
  543. // base types
  544. case VT_I2:
  545. pReturn = new node_base_type(NODE_SHORT, ATTR_SIGNED);
  546. ((named_node *)pReturn)->SetSymName("short");
  547. break;
  548. case VT_I4:
  549. pReturn = new node_base_type(NODE_LONG, ATTR_SIGNED);
  550. ((named_node *)pReturn)->SetSymName("long");
  551. break;
  552. case VT_R4:
  553. pReturn = new node_base_type(NODE_FLOAT, ATTR_NONE);
  554. ((named_node *)pReturn)->SetSymName("float");
  555. break;
  556. case VT_R8:
  557. pReturn = new node_base_type(NODE_DOUBLE, ATTR_NONE);
  558. ((named_node *)pReturn)->SetSymName("double");
  559. break;
  560. case VT_I1:
  561. pReturn = new node_base_type(NODE_CHAR, ATTR_SIGNED);
  562. ((named_node *)pReturn)->SetSymName("char");
  563. break;
  564. case VT_UI1:
  565. pReturn = new node_base_type(NODE_CHAR, ATTR_UNSIGNED);
  566. ((named_node *)pReturn)->SetSymName("char");
  567. break;
  568. case VT_UI2:
  569. pReturn = new node_base_type(NODE_SHORT, ATTR_UNSIGNED);
  570. ((named_node *)pReturn)->SetSymName("short");
  571. break;
  572. case VT_UI4:
  573. pReturn = new node_base_type(NODE_LONG, ATTR_UNSIGNED);
  574. ((named_node *)pReturn)->SetSymName("long");
  575. break;
  576. case VT_I8:
  577. pReturn = new node_base_type(NODE_INT64, ATTR_SIGNED);
  578. ((named_node *)pReturn)->SetSymName("int64");
  579. break;
  580. case VT_UI8:
  581. pReturn = new node_base_type(NODE_INT64, ATTR_UNSIGNED);
  582. ((named_node *)pReturn)->SetSymName("int64");
  583. break;
  584. case VT_INT:
  585. pReturn = new node_base_type(NODE_INT, ATTR_SIGNED);
  586. ((named_node *)pReturn)->SetSymName("INT");
  587. break;
  588. case VT_UINT:
  589. pReturn = new node_base_type(NODE_INT, ATTR_UNSIGNED);
  590. ((named_node *)pReturn)->SetSymName("UINT");
  591. break;
  592. case VT_VOID:
  593. pReturn = new node_base_type(NODE_VOID, ATTR_NONE);
  594. ((named_node *)pReturn)->SetSymName("void");
  595. break;
  596. case VT_BOOL:
  597. pReturn = new node_base_type(NODE_BOOLEAN, ATTR_NONE);
  598. ((named_node *)pReturn)->SetSymName("BOOLEAN");
  599. break;
  600. // simple ODL base types (not base types in IDL)
  601. case VT_HRESULT:
  602. pReturn = new node_base_type(NODE_SHORT, ATTR_NONE);
  603. ((named_node *)pReturn)->SetSymName("HRESULT");
  604. break;
  605. case VT_DATE:
  606. pReturn = new node_base_type(NODE_LONGLONG, ATTR_NONE);
  607. ((named_node *)pReturn)->SetSymName("DATE");
  608. break;
  609. case VT_LPSTR:
  610. pReturn = new node_base_type(NODE_LONGLONG, ATTR_NONE);
  611. ((named_node *)pReturn)->SetSymName("LPSTR");
  612. break;
  613. case VT_LPWSTR:
  614. pReturn = new node_base_type(NODE_LONGLONG, ATTR_NONE);
  615. ((named_node *)pReturn)->SetSymName("LPWSTR");
  616. break;
  617. case VT_ERROR:
  618. pReturn = new node_base_type(NODE_INT64, ATTR_NONE);
  619. ((named_node *)pReturn)->SetSymName("SCODE");
  620. break;
  621. // complex ODL base types
  622. case VT_DECIMAL:
  623. {
  624. SymKey key("DECIMAL", NAME_DEF);
  625. pReturn = pBaseSymTbl->SymSearch(key);
  626. }
  627. break;
  628. case VT_CY:
  629. {
  630. SymKey key("CURRENCY", NAME_DEF);
  631. pReturn = pBaseSymTbl->SymSearch(key);
  632. }
  633. break;
  634. case VT_BSTR:
  635. {
  636. SymKey key("BSTR", NAME_DEF);
  637. pReturn = pBaseSymTbl->SymSearch(key);
  638. }
  639. break;
  640. case VT_VARIANT:
  641. {
  642. SymKey key("VARIANT", NAME_DEF);
  643. pReturn = pBaseSymTbl->SymSearch(key);
  644. }
  645. break;
  646. case VT_DISPATCH:
  647. {
  648. SymKey key("IDispatch", NAME_DEF);
  649. pReturn = new node_pointer(pBaseSymTbl->SymSearch(key));
  650. }
  651. break;
  652. case VT_UNKNOWN:
  653. {
  654. SymKey key("IUnknown", NAME_DEF);
  655. pReturn = new node_pointer(pBaseSymTbl->SymSearch(key));
  656. }
  657. break;
  658. // complex types
  659. case VT_PTR:
  660. pReturn = new node_pointer(GetNodeFromTYPEDESC(*(tdesc.lptdesc), pti));
  661. break;
  662. case VT_SAFEARRAY:
  663. pReturn = new node_safearray(GetNodeFromTYPEDESC(*(tdesc.lptdesc), pti));
  664. break;
  665. case VT_CARRAY:
  666. {
  667. node_skl * pCurrent = NULL;
  668. node_skl * pPrev = NULL;
  669. for (int i = 0; i < tdesc.lpadesc->cDims; i++)
  670. {
  671. pCurrent = new node_array(
  672. new expr_constant(tdesc.lpadesc->rgbounds[i].lLbound),
  673. new expr_constant((tdesc.lpadesc->rgbounds[i].cElements
  674. + tdesc.lpadesc->rgbounds[i].lLbound) - 1 )
  675. );
  676. if (pPrev)
  677. {
  678. pPrev->SetChild(pCurrent);
  679. }
  680. else
  681. {
  682. pReturn = pCurrent;
  683. }
  684. pPrev = pCurrent;
  685. }
  686. if (pCurrent)
  687. (pCurrent)->SetChild(GetNodeFromTYPEDESC(tdesc.lpadesc->tdescElem, pti));
  688. }
  689. break;
  690. case VT_USERDEFINED:
  691. {
  692. ITypeInfo * pRef;
  693. HRESULT hr = pti->GetRefTypeInfo(tdesc.hreftype, &pRef);
  694. if (FAILED(hr))
  695. {
  696. TypeinfoError(hr);
  697. }
  698. node_skl* pNode = GetNode(pRef);
  699. NODE_T nk = pNode->NodeKind();
  700. if ( nk == NODE_INTERFACE_REFERENCE || nk == NODE_INTERFACE )
  701. {
  702. pReturn = new node_interface_reference( (node_interface *) pNode );
  703. }
  704. else
  705. {
  706. pReturn = pNode;
  707. }
  708. pRef->Release();
  709. }
  710. break;
  711. default:
  712. MIDL_ASSERT(!"Illegal variant type found in a TYPEDESC");
  713. break;
  714. }
  715. if (pReturn && (pReturn->NodeKind() == NODE_DEF) &&
  716. pReturn->GetChild() &&
  717. (pReturn->GetChild()->NodeKind() == NODE_FORWARD))
  718. {
  719. node_forward * pFwd = (node_forward *) pReturn->GetChild();
  720. node_skl * pNewSkl = pFwd->ResolveFDecl();
  721. if (pNewSkl)
  722. {
  723. pReturn = new node_def_fe(pReturn->GetSymName(), pNewSkl);
  724. }
  725. }
  726. return pReturn;
  727. }
  728. //+---------------------------------------------------------------------------
  729. //
  730. // Member: NODE_MANAGER::AddMembers
  731. //
  732. // Synopsis: Generic routine to add type graph elements for variables and
  733. // functions to a type graph element.
  734. //
  735. // Arguments: [pNode] - pointer to the parent type graph node's MEMLIST
  736. // [ptattr] - pointer to the parent type info's TYPEATTR struct
  737. // [pti] - pointer to the parent type info
  738. //
  739. // Returns: nothing
  740. //
  741. // Modifies: adds each new node to the MEMLIST referred to by pNode
  742. //
  743. // History: 5-02-95 stevebl Created
  744. //
  745. //----------------------------------------------------------------------------
  746. void NODE_MANAGER::AddMembers(MEMLIST * pNode, TYPEATTR * ptattr, ITypeInfo * pti)
  747. {
  748. HRESULT hr;
  749. named_node * pNew;
  750. unsigned i = ptattr->cFuncs;
  751. while (i--)
  752. {
  753. FUNCDESC *pfdesc;
  754. hr = pti->GetFuncDesc(i, &pfdesc);
  755. pNew = GetNodeFromFUNCDESC(*pfdesc, pti);
  756. pNode->AddFirstMember(pNew);
  757. pti->ReleaseFuncDesc(pfdesc);
  758. }
  759. i = ptattr->cVars;
  760. while (i--)
  761. {
  762. VARDESC * pvdesc;
  763. hr = pti->GetVarDesc(i, &pvdesc);
  764. pNew = GetNodeFromVARDESC(*pvdesc, pti);
  765. pNode->AddFirstMember(pNew);
  766. pti->ReleaseVarDesc(pvdesc);
  767. }
  768. }
  769. //+---------------------------------------------------------------------------
  770. //
  771. // Member: NODE_MANAGER::GetNodeFromVARDESC
  772. //
  773. // Synopsis: gets a type graph node from a VARDESC
  774. //
  775. // Arguments: [vdesc] - VARDESC describing the variable
  776. // [pti] - type info containing the VARDESC
  777. //
  778. // Returns: type graph node describing the varible
  779. //
  780. // History: 5-02-95 stevebl Created
  781. //
  782. //----------------------------------------------------------------------------
  783. named_node * NODE_MANAGER::GetNodeFromVARDESC(VARDESC vdesc, ITypeInfo * pti)
  784. {
  785. BSTR bstrName;
  786. unsigned cNames;
  787. pti->GetNames(vdesc.memid, &bstrName, 1, &cNames);
  788. char * szName = TranscribeO2A( bstrName );
  789. LateBound_SysFreeString(bstrName);
  790. named_node *pNode;
  791. if (vdesc.varkind == VAR_CONST)
  792. {
  793. expr_node * pExpr = GetValueOfConstant(vdesc.lpvarValue);
  794. pNode = new node_label(szName, pExpr);
  795. }
  796. else
  797. {
  798. pNode = new node_field(szName);
  799. }
  800. pNode->SetBasicType(GetNodeFromTYPEDESC(vdesc.elemdescVar.tdesc, pti));
  801. SetIDLATTRS(pNode, vdesc.elemdescVar.idldesc);
  802. pNode->SetAttribute(new node_constant_attr(
  803. new expr_constant(vdesc.wVarFlags), ATTR_VARDESCATTR));
  804. if (vdesc.wVarFlags == VARFLAG_FREADONLY)
  805. {
  806. pNode->SetAttribute(new node_member_attr(MATTR_READONLY));
  807. }
  808. if (vdesc.wVarFlags == VARFLAG_FSOURCE)
  809. {
  810. pNode->SetAttribute(new node_member_attr(MATTR_SOURCE));
  811. }
  812. if (vdesc.wVarFlags == VARFLAG_FBINDABLE)
  813. {
  814. pNode->SetAttribute(new node_member_attr(MATTR_BINDABLE));
  815. }
  816. if (vdesc.wVarFlags == VARFLAG_FDISPLAYBIND)
  817. {
  818. pNode->SetAttribute(new node_member_attr(MATTR_DISPLAYBIND));
  819. }
  820. if (vdesc.wVarFlags == VARFLAG_FDEFAULTBIND)
  821. {
  822. pNode->SetAttribute(new node_member_attr(MATTR_DEFAULTBIND));
  823. }
  824. if (vdesc.wVarFlags == VARFLAG_FREQUESTEDIT)
  825. {
  826. pNode->SetAttribute(new node_member_attr(MATTR_REQUESTEDIT));
  827. }
  828. if (vdesc.wVarFlags == VARFLAG_FHIDDEN)
  829. {
  830. pNode->SetAttribute(ATTR_HIDDEN);
  831. }
  832. pNode->SetAttribute(new node_constant_attr(
  833. new expr_constant(vdesc.memid), ATTR_ID ));
  834. return pNode;
  835. }
  836. //+---------------------------------------------------------------------------
  837. //
  838. // Member: NODE_MANAGER::GetNodeFromFUNCDESC
  839. //
  840. // Synopsis: gets a type graph node from a FUNCDESC
  841. //
  842. // Arguments: [fdesc] - FUNCDESC describing the function
  843. // [pti] - type info containing the FUNCDESC
  844. //
  845. // Returns: type graph node describing the function
  846. //
  847. // History: 5-02-95 stevebl Created
  848. //
  849. //----------------------------------------------------------------------------
  850. named_node * NODE_MANAGER::GetNodeFromFUNCDESC(FUNCDESC fdesc, ITypeInfo *pti)
  851. {
  852. node_proc * pNode = new node_proc(ImportLevel, FALSE);
  853. BSTR * rgbstrName = new BSTR [fdesc.cParams + 1];
  854. unsigned cNames;
  855. pti->GetNames(fdesc.memid, rgbstrName, fdesc.cParams + 1, &cNames);
  856. char * szName = TranscribeO2A( rgbstrName[0] );
  857. LateBound_SysFreeString( rgbstrName[0] );
  858. pNode->SetSymName(szName);
  859. if (fdesc.invkind == DISPATCH_PROPERTYGET
  860. || fdesc.funckind == FUNC_DISPATCH
  861. || (fdesc.elemdescFunc.paramdesc.wParamFlags & PARAMFLAG_FRETVAL) != 0)
  862. {
  863. /*
  864. * Functions with the DISPATCH_PROPERTYGET attribute are special cases.
  865. * Their return values in the type graph are always of type HRESULT.
  866. * The last parameter of the function (after those listed in the fdesc)
  867. * is a pointer to the return type listed in the fdesc and it has
  868. * the OUT and RETVAL attributes.
  869. */
  870. node_skl* pChild = new node_pointer(GetNodeFromTYPEDESC(fdesc.elemdescFunc.tdesc, pti));
  871. node_param * pParam = new node_param();
  872. pChild->GetModifiers().SetModifier( ATTR_TAGREF );
  873. pParam->SetSymName("retval");
  874. pParam->SetChild( pChild );
  875. pParam->SetAttribute(ATTR_OUT);
  876. pParam->SetAttribute(new node_member_attr(MATTR_RETVAL));
  877. // add the [retval] parameter at the end of the parameter list
  878. // (the parameter list is currently empty and the other parameters
  879. // will be added in front of this one in reverse order so that's why
  880. // we use AddFirstMember)
  881. pNode->AddFirstMember(pParam);
  882. node_skl * pReturn = new node_base_type(NODE_SHORT, ATTR_NONE);
  883. ((named_node *)pReturn)->SetSymName("HRESULT");
  884. pNode->SetChild(pReturn);
  885. }
  886. else
  887. {
  888. node_skl* pChild = GetNodeFromTYPEDESC(fdesc.elemdescFunc.tdesc, pti);
  889. pNode->SetChild( pChild );
  890. NODE_T nk = pChild->NodeKind();
  891. if (nk == NODE_POINTER || nk == NODE_DEF)
  892. {
  893. pChild->GetModifiers().SetModifier( ATTR_TAGREF );
  894. }
  895. }
  896. unsigned cParams = fdesc.cParams;
  897. unsigned cParamsOpt = fdesc.cParamsOpt;
  898. while (cParams--)
  899. {
  900. node_param * pParam = new node_param();
  901. if (cParams + 1 < cNames)
  902. {
  903. szName = TranscribeO2A( rgbstrName[ cParams + 1] );
  904. pParam->SetSymName(szName);
  905. LateBound_SysFreeString(rgbstrName[cParams + 1]);
  906. }
  907. else
  908. pParam->SetSymName("noname");
  909. pParam->SetChild(GetNodeFromTYPEDESC(fdesc.lprgelemdescParam[cParams].tdesc, pti));
  910. SetIDLATTRS(pParam, fdesc.lprgelemdescParam[cParams].idldesc);
  911. if (cParamsOpt)
  912. {
  913. cParamsOpt--;
  914. pParam->SetAttribute(new node_member_attr(MATTR_OPTIONAL));
  915. }
  916. if (pParam && pParam->GetChild())
  917. {
  918. NODE_T nk = pParam->GetChild()->NodeKind();
  919. if (nk == NODE_POINTER || nk == NODE_DEF)
  920. {
  921. pParam->GetChild()->GetModifiers().SetModifier( ATTR_TAGREF );
  922. }
  923. }
  924. pNode->AddFirstMember(pParam);
  925. }
  926. delete[]rgbstrName;
  927. pNode->SetAttribute(new node_constant_attr(
  928. new expr_constant(fdesc.wFuncFlags), ATTR_FUNCDESCATTR));
  929. if (fdesc.wFuncFlags == FUNCFLAG_FRESTRICTED)
  930. {
  931. pNode->SetAttribute(new node_member_attr(MATTR_RESTRICTED));
  932. }
  933. if (fdesc.wFuncFlags == FUNCFLAG_FSOURCE)
  934. {
  935. pNode->SetAttribute(new node_member_attr(MATTR_SOURCE));
  936. }
  937. if (fdesc.wFuncFlags == FUNCFLAG_FBINDABLE)
  938. {
  939. pNode->SetAttribute(new node_member_attr(MATTR_BINDABLE));
  940. }
  941. if (fdesc.wFuncFlags == FUNCFLAG_FDISPLAYBIND)
  942. {
  943. pNode->SetAttribute(new node_member_attr(MATTR_DISPLAYBIND));
  944. }
  945. if (fdesc.wFuncFlags == FUNCFLAG_FDEFAULTBIND)
  946. {
  947. pNode->SetAttribute(new node_member_attr(MATTR_DEFAULTBIND));
  948. }
  949. if (fdesc.wFuncFlags == FUNCFLAG_FREQUESTEDIT)
  950. {
  951. pNode->SetAttribute(new node_member_attr(MATTR_REQUESTEDIT));
  952. }
  953. if (fdesc.wFuncFlags == FUNCFLAG_FHIDDEN)
  954. {
  955. pNode->SetAttribute(ATTR_HIDDEN);
  956. }
  957. if (fdesc.invkind == DISPATCH_PROPERTYGET)
  958. {
  959. szName = pNode->GetSymName();
  960. char * szNewName = new char[strlen(szName) + 5];
  961. sprintf(szNewName , "get_%s", szName);
  962. pNode->SetSymName(szNewName);
  963. pNode->SetAttribute(new node_member_attr(MATTR_PROPGET));
  964. }
  965. else if (fdesc.invkind == DISPATCH_PROPERTYPUT)
  966. {
  967. szName = pNode->GetSymName();
  968. char * szNewName = new char[strlen(szName) + 5];
  969. sprintf(szNewName , "put_%s", szName);
  970. pNode->SetSymName(szNewName);
  971. pNode->SetAttribute(new node_member_attr(MATTR_PROPPUT));
  972. }
  973. else if (fdesc.invkind == DISPATCH_PROPERTYPUTREF)
  974. {
  975. szName = pNode->GetSymName();
  976. char * szNewName = new char[strlen(szName) + 8];
  977. sprintf(szNewName , "putref_%s", szName);
  978. pNode->SetSymName(szNewName);
  979. pNode->SetAttribute(new node_member_attr(MATTR_PROPPUTREF));
  980. }
  981. pNode->GetModifiers().SetModifier( ATTR_TAGREF );
  982. pNode->SetAttribute(new node_constant_attr(
  983. new expr_constant(fdesc.memid), ATTR_ID ));
  984. return pNode;
  985. }
  986. //+---------------------------------------------------------------------------
  987. //
  988. // Member: NODE_MANAGER::SetIDLATTRS
  989. //
  990. // Synopsis: Adds IDL attributes to a type graph node
  991. //
  992. // Arguments: [pNode] - pointer to the type graph node
  993. // [idldesc] - IDLDESC containing the IDL attributes
  994. //
  995. // History: 5-02-95 stevebl Created
  996. //
  997. //----------------------------------------------------------------------------
  998. void NODE_MANAGER::SetIDLATTRS(named_node * pNode, IDLDESC idldesc)
  999. {
  1000. pNode->SetAttribute(new node_constant_attr(
  1001. new expr_constant(idldesc.wIDLFlags), ATTR_IDLDESCATTR));
  1002. if (idldesc.wIDLFlags & IDLFLAG_FIN)
  1003. {
  1004. pNode->SetAttribute(ATTR_IN);
  1005. }
  1006. if (idldesc.wIDLFlags & IDLFLAG_FOUT)
  1007. {
  1008. pNode->SetAttribute(ATTR_OUT);
  1009. }
  1010. if (idldesc.wIDLFlags & IDLFLAG_FLCID)
  1011. {
  1012. pNode->SetAttribute(ATTR_FLCID);
  1013. }
  1014. }
  1015. //+---------------------------------------------------------------------------
  1016. //
  1017. // Member: NODE_MANAGER::GetValueOfConstant
  1018. //
  1019. // Synopsis: creates an expr_constant node from a VARIANT
  1020. //
  1021. // Arguments: [pVar] - pointer to the variant containing the constant
  1022. //
  1023. // Returns: expr_node describing the constant expression
  1024. //
  1025. // History: 5-02-95 stevebl Created
  1026. //
  1027. //----------------------------------------------------------------------------
  1028. expr_node * NODE_MANAGER::GetValueOfConstant(VARIANT * pVar)
  1029. {
  1030. expr_node * pReturn;
  1031. switch(pVar->vt)
  1032. {
  1033. case VT_UI1:
  1034. pReturn = new expr_constant(pVar->bVal);
  1035. break;
  1036. case VT_BOOL:
  1037. case VT_I2:
  1038. pReturn = new expr_constant(pVar->iVal);
  1039. break;
  1040. case VT_I4:
  1041. pReturn = new expr_constant(pVar->lVal);
  1042. break;
  1043. case VT_R4:
  1044. pReturn = new expr_constant(pVar->fltVal);
  1045. break;
  1046. case VT_R8:
  1047. pReturn = new expr_constant(pVar->dblVal);
  1048. break;
  1049. case VT_CY:
  1050. case VT_DATE:
  1051. case VT_BSTR:
  1052. case VT_ERROR:
  1053. case VT_UNKNOWN:
  1054. case VT_VARIANT:
  1055. case VT_DISPATCH:
  1056. default:
  1057. // This case is currently illegal in every situation that I am
  1058. // aware of. However, just in case this ever changes, (and since
  1059. // it is possible to handle this situation even though it may be
  1060. // illeagal) I'll go ahead and allow it anyway. The alternative
  1061. // would be to choke on it and put out an error message.
  1062. // FUTURE - perhaps display a warning here
  1063. pReturn = new expr_constant(pVar->lVal);
  1064. break;
  1065. }
  1066. return pReturn;
  1067. }
  1068. //+---------------------------------------------------------------------------
  1069. //
  1070. // Function: CTypeLibraryList::AddTypeLibraryMembers
  1071. //
  1072. // Synopsis: Adds each of a type library's members to the global symbol
  1073. // table as a node_href. If another symbol with the same name
  1074. // already exists in the table, then no node will be added
  1075. // for that member.
  1076. //
  1077. // Arguments: [ptl] - type library pointer
  1078. // [szFileName] - name of the file containing the type library
  1079. //
  1080. // History: 5-02-95 stevebl Created
  1081. //
  1082. // Notes: Typeinfos added to the global symbol table in this manner are
  1083. // not parsed and expanded into their type graphs at this time;
  1084. // type info expansion occurs during the semantic pass.
  1085. //
  1086. //----------------------------------------------------------------------------
  1087. void CTypeLibraryList::AddTypeLibraryMembers(ITypeLib * ptl, char * szFileName)
  1088. {
  1089. unsigned int nMem = ptl->GetTypeInfoCount();
  1090. BSTR bstrName;
  1091. HRESULT hr;
  1092. ITypeInfo * pti;
  1093. char * sz;
  1094. node_file * pFile = new node_file(szFileName, 1);
  1095. while (nMem--)
  1096. {
  1097. hr = ptl->GetDocumentation(nMem, &bstrName, NULL, NULL, NULL);
  1098. if (FAILED(hr))
  1099. {
  1100. TypelibError(szFileName, hr);
  1101. }
  1102. sz = TranscribeO2A( bstrName );
  1103. LateBound_SysFreeString(bstrName);
  1104. NAME_T type;
  1105. TYPEKIND tkind;
  1106. hr = ptl->GetTypeInfoType(nMem, &tkind);
  1107. if (FAILED(hr))
  1108. {
  1109. TypelibError(szFileName, hr);
  1110. }
  1111. if (!pCommand->IsSwitchDefined(SWITCH_MKTYPLIB))
  1112. {
  1113. switch (tkind)
  1114. {
  1115. case TKIND_ENUM:
  1116. type = NAME_ENUM;
  1117. break;
  1118. case TKIND_UNION:
  1119. type = NAME_UNION;
  1120. break;
  1121. case TKIND_RECORD:
  1122. type = NAME_TAG;
  1123. break;
  1124. default:
  1125. type = NAME_DEF;
  1126. break;
  1127. }
  1128. }
  1129. else
  1130. {
  1131. type = NAME_DEF;
  1132. }
  1133. SymKey key(sz, type);
  1134. if (!pBaseSymTbl->SymSearch(key))
  1135. {
  1136. hr = ptl->GetTypeInfo(nMem, &pti);
  1137. if (FAILED(hr))
  1138. {
  1139. TypelibError(szFileName, hr);
  1140. }
  1141. pItfList->Add(pti, sz);
  1142. node_href * pref = new node_href(key, pBaseSymTbl, pti, pFile);
  1143. pref->SetSymName(sz);
  1144. pBaseSymTbl->SymInsert(key, NULL, pref);
  1145. }
  1146. }
  1147. }
  1148. //+---------------------------------------------------------------------------
  1149. //
  1150. // Function: AddQualifiedReferenceToType
  1151. //
  1152. // Synopsis: Verifies that a library contains a given type and returns
  1153. // a typegraph node pointer to the type.
  1154. //
  1155. // Arguments: [szLibrary] - name of the library (_NOT_ the TLB file)
  1156. // [szType] - name of the type to be referenced
  1157. //
  1158. // Returns: a node_href * to the referenced type.
  1159. // If the type isn't found to exist in the given library then
  1160. // this routine returns NULL.
  1161. //
  1162. // History: 12-20-95 stevebl Created
  1163. //
  1164. // Notes: These types are not added to the global symbol table.
  1165. // They are also not parsed and expanded into their complete
  1166. // type graphs at this time; type info expansion occurs
  1167. // during the semantic pass.
  1168. //
  1169. //----------------------------------------------------------------------------
  1170. void * AddQualifiedReferenceToType(char * szLibrary, char * szType)
  1171. {
  1172. return gtllist.AddQualifiedReferenceToType(szLibrary, szType);
  1173. }
  1174. void * CTypeLibraryList::AddQualifiedReferenceToType(char * szLibrary, char * szType)
  1175. {
  1176. ITypeLib * pTL = FindLibrary(szLibrary);
  1177. if (NULL != pTL)
  1178. {
  1179. node_file * pFile = new node_file(szLibrary, 1);
  1180. WCHAR * wsz = TranscribeA2O( szType );
  1181. ITypeInfo * ptiFound;
  1182. SYSKIND sk = ( SYSKIND ) ( pCommand->Is64BitEnv() ? SYS_WIN64 : SYS_WIN32 );
  1183. ULONG lHashVal = LateBound_LHashValOfNameSys(sk, NULL, wsz);
  1184. HRESULT hr;
  1185. MEMBERID memid;
  1186. unsigned short c;
  1187. c = 1;
  1188. hr = pTL->FindName(wsz, lHashVal, &ptiFound, &memid, &c);
  1189. if (SUCCEEDED(hr))
  1190. {
  1191. if (c)
  1192. {
  1193. if (-1 == memid)
  1194. {
  1195. // found a matching name
  1196. NAME_T type;
  1197. TYPEATTR * ptattr;
  1198. hr = ptiFound->GetTypeAttr(&ptattr);
  1199. if (FAILED(hr))
  1200. {
  1201. TypeinfoError(hr);
  1202. }
  1203. if (!pCommand->IsSwitchDefined(SWITCH_MKTYPLIB))
  1204. {
  1205. switch (ptattr->typekind)
  1206. {
  1207. case TKIND_ENUM:
  1208. type = NAME_ENUM;
  1209. break;
  1210. case TKIND_UNION:
  1211. type = NAME_UNION;
  1212. break;
  1213. case TKIND_RECORD:
  1214. type = NAME_TAG;
  1215. break;
  1216. default:
  1217. type = NAME_DEF;
  1218. break;
  1219. }
  1220. }
  1221. else
  1222. {
  1223. type = NAME_DEF;
  1224. }
  1225. ptiFound->ReleaseTypeAttr(ptattr);
  1226. pItfList->Add(ptiFound, szType);
  1227. SymKey key(szType, type);
  1228. node_href * pref = new node_href(key, pBaseSymTbl, ptiFound, pFile);
  1229. return pref;
  1230. }
  1231. // found a parameter name or some other non-global name
  1232. ptiFound->Release();
  1233. }
  1234. }
  1235. }
  1236. return NULL;
  1237. }