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.

264 lines
7.1 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1989-1999 Microsoft Corporation
  3. Module Name:
  4. cgdump.cxx
  5. Abstract:
  6. A debug code generation object dumper.
  7. Notes:
  8. History:
  9. VibhasC Aug-13-1993 Created.
  10. mzoran Nov-15-1999 Modified to print tree.
  11. ----------------------------------------------------------------------------*/
  12. #include "becls.hxx"
  13. #pragma hdrstop
  14. //
  15. // Characters for class graph dumper
  16. //
  17. #if defined(WIN32)
  18. const char CharElbow = '';
  19. const char CharTee = '';
  20. const char CharVLine = '';
  21. const char StringTeeLine[] = "����";
  22. const char StringElbowLine[] = "����";
  23. #else
  24. const char CharElbow = '\\';
  25. const char CharTee = '>';
  26. const char CharVLine = '|';
  27. const char StringTeeLine[] = ">---";
  28. const char StringElbowLine[] = "\\---";
  29. #endif
  30. #ifdef MIDL_INTERNAL
  31. typedef PTR_SET<CG_CLASS> CG_DUMP_SET;
  32. typedef MAP<CG_CLASS*, unsigned long> CG_DUMP_MAP;
  33. const char * DoGetAdditionalDumpInfo( CG_CLASS *pClass )
  34. {
  35. if ( ( dynamic_cast<CG_FILE*>( pClass ) != NULL ) &&
  36. ( static_cast<CG_FILE*>( pClass )->GetFileName() != NULL ) )
  37. {
  38. return static_cast<CG_FILE*>( pClass )->GetFileName();
  39. }
  40. else if ( ( dynamic_cast<CG_HANDLE*>( pClass ) != NULL ) &&
  41. ( static_cast<CG_HANDLE*>( pClass )->GetHandleType() != NULL ) &&
  42. ( static_cast<CG_HANDLE*>( pClass )->GetHandleType()->GetSymName() != NULL ) )
  43. {
  44. return static_cast<CG_HANDLE*>( pClass )->GetHandleType()->GetSymName();
  45. }
  46. else if ( dynamic_cast<CG_FIELD*>( pClass ) != NULL )
  47. {
  48. CG_FIELD *pField = dynamic_cast<CG_FIELD*>( pClass );
  49. size_t Length = strlen(pField->GetSymName()) +
  50. strlen(pField->GetPrintPrefix()) + 1;
  51. char *p = new char[Length];
  52. strcpy( p, pField->GetPrintPrefix() );
  53. strcat( p, pField->GetSymName() );
  54. return p;
  55. }
  56. else if ( ( pClass->GetType() != NULL ) &&
  57. ( pClass->GetType()->GetSymName() != NULL ) )
  58. {
  59. return pClass->GetType()->GetSymName();
  60. }
  61. else
  62. {
  63. return "";
  64. }
  65. }
  66. unsigned long DoDumpCGClassList( CG_CLASS *pClass, CG_DUMP_MAP & DumpMap, unsigned long & LastNodeNum )
  67. {
  68. if ( pClass == NULL )
  69. return 0;
  70. // See if this node has already been printed
  71. unsigned long Me;
  72. if ( DumpMap.Lookup( pClass, &Me ) )
  73. return Me;
  74. Me = ++LastNodeNum;
  75. DumpMap.Insert( pClass, Me );
  76. CG_CLASS * pChild = pClass->GetChild();
  77. CG_CLASS * pSibling= pClass->GetSibling();
  78. CG_CLASS *pReturnType;
  79. if ( ( dynamic_cast<CG_PROC*>( pClass ) != NULL ) &&
  80. ( ( pReturnType = static_cast<CG_PROC*>( pClass )->GetReturnType() ) != NULL ) )
  81. {
  82. DoDumpCGClassList( pReturnType, DumpMap, LastNodeNum );
  83. }
  84. unsigned long Ch = DoDumpCGClassList( pChild, DumpMap, LastNodeNum );
  85. unsigned long Si = DoDumpCGClassList( pSibling, DumpMap, LastNodeNum );
  86. const char *pName = typeid( *pClass ).name();
  87. const char *pAdditionalInfo = DoGetAdditionalDumpInfo( pClass );
  88. fprintf( stderr,
  89. "%30s : %.4d(0x%p) : Ch = %.4d, Si = %.4d %s\n",
  90. pName,
  91. Me,
  92. pClass,
  93. Ch,
  94. Si,
  95. pAdditionalInfo
  96. );
  97. return Me;
  98. }
  99. void DoDumpCGClassList( CG_CLASS *pClass, CG_DUMP_MAP *pDumpMap = NULL )
  100. {
  101. unsigned long NodeNum = 0;
  102. if ( NULL == pDumpMap )
  103. {
  104. CG_DUMP_MAP DumpMap;
  105. DoDumpCGClassList( pClass, DumpMap, NodeNum );
  106. }
  107. else
  108. DoDumpCGClassList( pClass, *pDumpMap, NodeNum );
  109. fprintf( stderr, "\n" );
  110. }
  111. void DoDumpCGClassGraph( CG_CLASS *pClass, CG_DUMP_MAP * pDumpMap, CG_DUMP_SET & DumpSet,
  112. const char *pPrefixString )
  113. {
  114. if ( pClass == NULL )
  115. return;
  116. //
  117. // Print Myself
  118. //
  119. unsigned long Me;
  120. BOOL LookupResult = pDumpMap->Lookup( pClass, &Me );
  121. MIDL_ASSERT( LookupResult );
  122. fprintf( stderr, "%s%s, %.4d(0x%p), %s\n",
  123. pPrefixString,
  124. typeid( *pClass ).name(),
  125. Me,
  126. pClass,
  127. DoGetAdditionalDumpInfo( pClass ) );
  128. //
  129. // If this node has already been printed, do not print children.
  130. //
  131. if ( DumpSet.Lookup( pClass ) )
  132. return;
  133. DumpSet.Insert( pClass );
  134. //
  135. // Copy old prefix
  136. //
  137. const size_t PrevStrLen = strlen( pPrefixString );
  138. const size_t NewStringLength = PrevStrLen + 4 + sizeof('\0');
  139. char *pNewPrefix = new char[ NewStringLength ];
  140. char *pNewPrefixTail = pNewPrefix + PrevStrLen;
  141. memset( pNewPrefix, 0xBD, NewStringLength );
  142. memcpy( pNewPrefix, pPrefixString, PrevStrLen + 1 );
  143. //
  144. // Modify the previous characters. If this was the last child,
  145. // convert previous 4 characters to spaces, otherwise convert
  146. // to a line with spaces.
  147. //
  148. if ( PrevStrLen >= 4 )
  149. {
  150. pNewPrefix[PrevStrLen - 3] = ' ';
  151. pNewPrefix[PrevStrLen - 2] = ' ';
  152. pNewPrefix[PrevStrLen - 1] = ' ';
  153. if (pNewPrefix[PrevStrLen - 4] == CharElbow)
  154. pNewPrefix[PrevStrLen - 4] = ' ';
  155. else if ( pNewPrefix[PrevStrLen - 4] == CharTee )
  156. pNewPrefix[PrevStrLen - 4] = CharVLine;
  157. else MIDL_ASSERT( false );
  158. }
  159. gplistmgr Children;
  160. pClass->GetMembers( Children );
  161. //
  162. // Add return type for procs
  163. //
  164. CG_CLASS *pReturnType;
  165. if ( ( dynamic_cast<CG_PROC*>( pClass ) != NULL ) &&
  166. ( ( pReturnType = static_cast<CG_PROC*>( pClass )->GetReturnType() ) != NULL ) )
  167. {
  168. Children.InsertHead( pReturnType );
  169. }
  170. CG_CLASS *pChild;
  171. CG_CLASS *pNext;
  172. ITERATOR_INIT( Children );
  173. if ( ITERATOR_GETNEXT( Children, pChild ) )
  174. {
  175. for(;;)
  176. {
  177. if ( ITERATOR_GETNEXT( Children, pNext ) )
  178. {
  179. //
  180. // Additional children follow
  181. //
  182. memcpy( pNewPrefixTail, StringTeeLine, sizeof(StringTeeLine));
  183. DoDumpCGClassGraph( pChild, pDumpMap, DumpSet, pNewPrefix );
  184. pChild = pNext;
  185. }
  186. else
  187. {
  188. //
  189. // No more children
  190. //
  191. memcpy( pNewPrefixTail, StringElbowLine, sizeof(StringElbowLine) );
  192. DoDumpCGClassGraph( pChild, pDumpMap, DumpSet, pNewPrefix );
  193. break;
  194. }
  195. }
  196. }
  197. delete[] pNewPrefix;
  198. }
  199. void DoDumpCGClassGraph( CG_CLASS *pClass, CG_DUMP_MAP * pDumpMap = NULL )
  200. {
  201. CG_DUMP_SET DumpSet;
  202. DoDumpCGClassGraph( pClass, pDumpMap, DumpSet, "");
  203. fprintf( stderr, "\n" );
  204. }
  205. void CG_CLASS::Dump( const char *pTitle )
  206. {
  207. if ( pTitle )
  208. {
  209. fprintf( stderr, pTitle );
  210. fprintf( stderr, "\n" );
  211. }
  212. CG_DUMP_MAP DumpMap;
  213. DoDumpCGClassList( this, &DumpMap );
  214. DoDumpCGClassGraph( this, &DumpMap );
  215. }
  216. #endif // MIDL_INTERNAL