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

450 lines
11 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1989-2000 Microsoft Corporation
  3. Module Name:
  4. header.cxx
  5. Abstract:
  6. Generates header file.
  7. Notes:
  8. History:
  9. ----------------------------------------------------------------------------*/
  10. /****************************************************************************
  11. * include files
  12. ***************************************************************************/
  13. #include "becls.hxx"
  14. #pragma hdrstop
  15. #include "buffer.hxx"
  16. /****************************************************************************
  17. * local definitions
  18. ***************************************************************************/
  19. /****************************************************************************
  20. * externs
  21. ***************************************************************************/
  22. extern CMD_ARG * pCommand;
  23. CG_STATUS
  24. CG_OBJECT_INTERFACE::GenHeader(
  25. CCB * pCCB )
  26. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  27. Routine Description:
  28. Generate interface header file.
  29. Arguments:
  30. pCCB - a pointer to the code generation control block.
  31. Return Value:
  32. CG_OK if all is well, error otherwise.
  33. Notes: The interface header file has the following structure:
  34. Forward declaration
  35. TypeDeclarations
  36. #if defined(__cplusplus) && !defined(CINTERFACE)
  37. CPlusPlusLanguageBinding
  38. #else
  39. CLanguageBinding
  40. #endif
  41. ----------------------------------------------------------------------------*/
  42. {
  43. node_interface * pInterface = (node_interface *) GetType();
  44. ISTREAM * pStream = pCCB->GetStream();
  45. char * pName = pInterface->GetSymName();
  46. if (!pInterface->PrintedDef())
  47. {
  48. //Initialize the CCB for this interface.
  49. InitializeCCB(pCCB);
  50. // put out the interface guards
  51. pStream->Write("\n#ifndef __");
  52. pStream->Write( pName );
  53. pStream->Write( "_INTERFACE_DEFINED__\n" );
  54. pStream->Write( "#define __");
  55. pStream->Write( pName );
  56. pStream->Write( "_INTERFACE_DEFINED__\n" );
  57. // Print out the declarations of the types
  58. pStream->NewLine();
  59. pInterface->PrintType( PRT_INTERFACE | PRT_OMIT_PROTOTYPE, pStream, 0);
  60. Out_IID(pCCB);
  61. // print out the vtable/class definitions
  62. pStream->NewLine();
  63. pStream->Write("#if defined(__cplusplus) && !defined(CINTERFACE)");
  64. pStream->IndentInc();
  65. CPlusPlusLanguageBinding(pCCB);
  66. pStream->IndentDec();
  67. pStream->NewLine();
  68. pStream->Write("#else \t/* C style interface */");
  69. pStream->IndentInc();
  70. CLanguageBinding(pCCB);
  71. pStream->IndentDec();
  72. // print out the C Macros
  73. CLanguageMacros( pCCB );
  74. pStream->NewLine( 2 );
  75. pStream->Write("#endif \t/* C style interface */");
  76. pStream->NewLine( 2 );
  77. // print out the prototypes for the proxy and stub routines
  78. ProxyPrototypes(pCCB);
  79. pStream->NewLine();
  80. // put out the trailing interface guard
  81. pStream->Write( "\n#endif \t/* __");
  82. pStream->Write( pName );
  83. pStream->Write( "_INTERFACE_DEFINED__ */\n" );
  84. pStream->NewLine();
  85. pInterface->SetPrintedDef();
  86. }
  87. return CG_OK;
  88. }
  89. CG_STATUS
  90. CG_OBJECT_INTERFACE::CPlusPlusLanguageBinding(CCB *pCCB)
  91. {
  92. ISTREAM *pStream = pCCB->GetStream();
  93. char *pName;
  94. pStream->NewLine();
  95. pName = GetType()->GetSymName();
  96. MIDL_ASSERT (pName != (char *)0);
  97. pStream->NewLine();
  98. // put out the declspec for the uuid
  99. if ( pCommand->GetMSCVer() >= 1100 )
  100. {
  101. pStream->Write("MIDL_INTERFACE(\"");
  102. pStream->Write(GuidStrs.str1);
  103. pStream->Write('-');
  104. pStream->Write(GuidStrs.str2);
  105. pStream->Write('-');
  106. pStream->Write(GuidStrs.str3);
  107. pStream->Write('-');
  108. pStream->Write(GuidStrs.str4);
  109. pStream->Write('-');
  110. pStream->Write(GuidStrs.str5);
  111. pStream->Write("\")");
  112. }
  113. else
  114. {
  115. pStream->Write(" struct ");
  116. }
  117. pStream->NewLine();
  118. pStream->Write(pName);
  119. CG_OBJECT_INTERFACE* pBaseCG = (CG_OBJECT_INTERFACE*) GetBaseInterfaceCG();
  120. //Check if this interface was derived from a base interface.
  121. if(pBaseCG)
  122. {
  123. pStream->Write(" : public ");
  124. pStream->Write(pBaseCG->GetType()->GetSymName());
  125. }
  126. pStream->NewLine();
  127. pStream->Write('{');
  128. pStream->NewLine();
  129. pStream->Write("public:");
  130. pStream->IndentInc();
  131. // REVIEW: BEGIN/END_INTERFACE were only need for PowerMac. Maybe we
  132. // should stop emitting them? -- MikeW 26-Jul-99
  133. if( ! pBaseCG )
  134. {
  135. pStream->NewLine();
  136. pStream->Write("BEGIN_INTERFACE");
  137. }
  138. PrintMemberFunctions( pStream, TRUE );
  139. if( ! pBaseCG )
  140. {
  141. pStream->NewLine();
  142. pStream->Write("END_INTERFACE");
  143. }
  144. pStream->IndentDec();
  145. pStream->NewLine();
  146. pStream->Write("};");
  147. pStream->NewLine();
  148. return CG_OK;
  149. }
  150. STATUS_T
  151. CG_OBJECT_INTERFACE::PrintMemberFunctions(
  152. ISTREAM * pStream,
  153. BOOL fAbstract)
  154. /*++
  155. Routine Description:
  156. This routine prints C++ function prototypes for the interface member functions.
  157. We assume that all of the procedure nodes are pure virtual functions.
  158. Arguments:
  159. pStream - Specifies the output stream.
  160. fAbstract - Specifies whether the methods should be abstract ( = 0 ).
  161. --*/
  162. {
  163. CG_OBJECT_PROC * pProc = (CG_OBJECT_PROC *) GetChild();
  164. MIDL_ASSERT (GetType()->GetSymName() != (char *)0);
  165. while( pProc )
  166. {
  167. if ( !pProc->SupressHeader() )
  168. {
  169. node_skl* pN = pProc->GetType();
  170. //Assume this is a pure virtual function.
  171. // use the call_as form, if any
  172. pStream->NewLine();
  173. pStream->Write("virtual ");
  174. pN->PrintType( PRT_PROTOTYPE | PRT_CALL_AS | PRT_FORCE_CALL_CONV | PRT_CPP_PROTOTYPE,
  175. pStream,
  176. 0 );
  177. if ( fAbstract)
  178. pStream->Write(" = 0;");
  179. else
  180. pStream->Write(";");
  181. pStream->NewLine();
  182. }
  183. pProc = (CG_OBJECT_PROC *) pProc->GetSibling();
  184. }
  185. return STATUS_OK;
  186. }
  187. CG_STATUS
  188. CG_OBJECT_PROC::PrintVtableEntry(
  189. CCB * pCCB)
  190. {
  191. ISTREAM * pStream = pCCB->GetStream();
  192. node_id * pTempID;
  193. char * pName = GetType()->GetSymName();
  194. if (SupressHeader())
  195. {
  196. return CG_OK;
  197. }
  198. if ( GetCallAsName() )
  199. {
  200. pName = GetCallAsName();
  201. }
  202. pTempID = MakePtrIDNode( pName, GetType() );
  203. pStream->NewLine();
  204. pTempID->PrintType( PRT_PROC_PTR_PROTOTYPE | PRT_THIS_POINTER | PRT_CALL_AS | PRT_FORCE_CALL_CONV,
  205. pStream,
  206. NULL ,
  207. pCCB->GetInterfaceCG()->GetType() );
  208. return CG_OK;
  209. }
  210. CG_STATUS
  211. CG_OBJECT_INTERFACE::CLanguageBinding(CCB *pCCB)
  212. {
  213. #ifndef DISABLE_C_OUTPUT
  214. ISTREAM * pStream = pCCB->GetStream();
  215. char * pName = pCCB->GetInterfaceName();
  216. pStream->NewLine( 2 );
  217. pStream->Write("typedef struct ");
  218. pStream->Write(pName);
  219. pStream->Write("Vtbl");
  220. pStream->NewLine();
  221. pStream->Write('{');
  222. pStream->IndentInc();
  223. pStream->NewLine();
  224. // REVIEW: BEGIN/END_INTERFACE were only need for PowerMac. Maybe we
  225. // should stop emitting them? -- MikeW 26-Jul-99
  226. pStream->Write("BEGIN_INTERFACE");
  227. pStream->NewLine();
  228. // Now the regular entries.
  229. PrintVtableEntries( pCCB );
  230. // This is a match for the other macro.
  231. pStream->NewLine();
  232. pStream->Write("END_INTERFACE");
  233. pStream->IndentDec();
  234. pStream->NewLine();
  235. pStream->Write("} ");
  236. pStream->Write(pName);
  237. pStream->Write("Vtbl;");
  238. pStream->NewLine( 2 );
  239. pStream->Write("interface ");
  240. pStream->Write(pName);
  241. pStream->NewLine();
  242. pStream->Write('{');
  243. pStream->IndentInc();
  244. pStream->NewLine();
  245. pStream->Write("CONST_VTBL struct ");
  246. pStream->Write(pName);
  247. pStream->Write("Vtbl *lpVtbl;");
  248. pStream->IndentDec();
  249. pStream->NewLine();
  250. pStream->Write("};");
  251. pStream->NewLine( 2 );
  252. #endif
  253. return CG_OK;
  254. }
  255. CG_STATUS
  256. CG_OBJECT_INTERFACE::ProxyPrototypes(CCB *pCCB)
  257. /*++
  258. Routine Description:
  259. This routine generates function prototypes for the interface proxy.
  260. For each procedure, we generate a proxy prototype and a
  261. stub prototype.
  262. Arguments:
  263. pCCB - a pointer to the code generation control block.
  264. Return Value:
  265. CG_OK if all is well, error otherwise.
  266. --*/
  267. {
  268. ISTREAM * pStream = pCCB->GetStream();
  269. CG_OBJECT_PROC * pProcCG = 0;
  270. char * pszName;
  271. CG_ITERATOR I;
  272. pszName = GetType()->GetSymName();
  273. MIDL_ASSERT (pszName != (char *)0);
  274. GetMembers( I );
  275. while( ITERATOR_GETNEXT( I, pProcCG ) )
  276. {
  277. if (!pProcCG->SupressHeader())
  278. {
  279. //print proxy function prototype
  280. pStream->NewLine();
  281. pProcCG->Out_ProxyFunctionPrototype(pCCB,
  282. PRT_TRAILING_SEMI );
  283. //print stub function prototype
  284. pStream->NewLine();
  285. pProcCG->Out_StubFunctionPrototype( pCCB );
  286. pStream->Write(';');
  287. pStream->NewLine();
  288. }
  289. }
  290. pStream->NewLine();
  291. return CG_OK;
  292. }
  293. CG_STATUS
  294. CG_OBJECT_INTERFACE::PrintCMacros(CCB *pCCB)
  295. /*++
  296. Routine Description:
  297. This routine generates C macros for an interface
  298. Arguments:
  299. pCCB - a pointer to the code generation control block.
  300. Return Value:
  301. CG_OK if all is well, error otherwise.
  302. --*/
  303. {
  304. #ifndef DISABLE_C_OUTPUT
  305. ISTREAM * pStream = pCCB->GetStream();
  306. CG_OBJECT_PROC * pProcCG = 0;
  307. CG_ITERATOR I;
  308. // print inherited methods ( with our current ccb intf name )
  309. if ( GetBaseInterfaceCG() )
  310. ((CG_OBJECT_INTERFACE *)GetBaseInterfaceCG())->PrintCMacros( pCCB );
  311. GetMembers( I );
  312. while( ITERATOR_GETNEXT( I, pProcCG ) )
  313. {
  314. //print proxy function prototype
  315. pStream->NewLine();
  316. pProcCG->GenCMacro(pCCB);
  317. }
  318. pStream->NewLine();
  319. #endif
  320. return CG_OK;
  321. }
  322. CG_STATUS
  323. CG_OBJECT_INTERFACE::CLanguageMacros(CCB *pCCB)
  324. {
  325. #ifndef DISABLE_C_OUTPUT
  326. ISTREAM * pStream = pCCB->GetStream();
  327. pStream->NewLine( 2 );
  328. pStream->Write("#ifdef COBJMACROS");
  329. pStream->NewLine();
  330. PrintCMacros( pCCB );
  331. pStream->NewLine();
  332. pStream->Write("#endif /* COBJMACROS */");
  333. pStream->NewLine();
  334. #endif
  335. return CG_OK;
  336. }