dump.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef NDEBUG
  5. #include "toolchain/sem_ir/dump.h"
  6. #include "common/ostream.h"
  7. #include "toolchain/sem_ir/stringify_type.h"
  8. namespace Carbon::SemIR {
  9. static auto DumpNameIfValid(const File& file, NameId name_id) -> void {
  10. if (name_id.has_value()) {
  11. llvm::errs() << " `" << file.names().GetFormatted(name_id) << "`";
  12. }
  13. }
  14. static auto DumpNoNewline(const File& file, ConstantId const_id) -> void {
  15. llvm::errs() << const_id;
  16. if (!const_id.has_value()) {
  17. return;
  18. }
  19. if (const_id.is_symbolic()) {
  20. llvm::errs() << ": "
  21. << file.constant_values().GetSymbolicConstant(const_id);
  22. } else if (const_id.is_concrete()) {
  23. llvm::errs() << ": "
  24. << file.insts().Get(
  25. file.constant_values().GetInstId(const_id));
  26. }
  27. }
  28. static auto DumpNoNewline(const File& file, InstId inst_id) -> void {
  29. llvm::errs() << inst_id;
  30. if (inst_id.has_value()) {
  31. llvm::errs() << ": " << file.insts().Get(inst_id);
  32. }
  33. }
  34. static auto DumpNoNewline(const File& file, InterfaceId interface_id) -> void {
  35. llvm::errs() << interface_id;
  36. if (interface_id.has_value()) {
  37. const auto& interface = file.interfaces().Get(interface_id);
  38. llvm::errs() << ": " << interface;
  39. DumpNameIfValid(file, interface.name_id);
  40. }
  41. }
  42. static auto DumpNoNewline(const File& file, SpecificId specific_id) -> void {
  43. llvm::errs() << specific_id;
  44. if (specific_id.has_value()) {
  45. llvm::errs() << ": " << file.specifics().Get(specific_id);
  46. }
  47. }
  48. LLVM_DUMP_METHOD auto Dump(const File& file, ClassId class_id) -> void {
  49. llvm::errs() << class_id;
  50. if (class_id.has_value()) {
  51. const auto& class_obj = file.classes().Get(class_id);
  52. llvm::errs() << ": " << class_obj;
  53. DumpNameIfValid(file, class_obj.name_id);
  54. }
  55. llvm::errs() << '\n';
  56. }
  57. LLVM_DUMP_METHOD auto Dump(const File& file, ConstantId const_id) -> void {
  58. DumpNoNewline(file, const_id);
  59. llvm::errs() << '\n';
  60. }
  61. LLVM_DUMP_METHOD auto Dump(const File& file, EntityNameId entity_name_id)
  62. -> void {
  63. llvm::errs() << entity_name_id;
  64. if (entity_name_id.has_value()) {
  65. auto entity_name = file.entity_names().Get(entity_name_id);
  66. llvm::errs() << ": " << entity_name;
  67. DumpNameIfValid(file, entity_name.name_id);
  68. }
  69. llvm::errs() << '\n';
  70. }
  71. LLVM_DUMP_METHOD auto Dump(const File& file, FacetTypeId facet_type_id)
  72. -> void {
  73. llvm::errs() << facet_type_id;
  74. if (facet_type_id.has_value()) {
  75. const auto& facet_type = file.facet_types().Get(facet_type_id);
  76. llvm::errs() << ": " << facet_type << '\n';
  77. for (auto impls : facet_type.impls_constraints) {
  78. llvm::errs() << " - ";
  79. DumpNoNewline(file, impls.interface_id);
  80. if (impls.specific_id.has_value()) {
  81. llvm::errs() << "; ";
  82. DumpNoNewline(file, impls.specific_id);
  83. }
  84. llvm::errs() << '\n';
  85. }
  86. for (auto rewrite : facet_type.rewrite_constraints) {
  87. llvm::errs() << " - ";
  88. Dump(file, rewrite.lhs_const_id);
  89. llvm::errs() << " - ";
  90. Dump(file, rewrite.rhs_const_id);
  91. }
  92. if (auto complete_id = file.complete_facet_types().TryGetId(facet_type_id);
  93. complete_id.has_value()) {
  94. llvm::errs() << "complete: ";
  95. Dump(file, complete_id);
  96. }
  97. } else {
  98. llvm::errs() << '\n';
  99. }
  100. }
  101. LLVM_DUMP_METHOD auto Dump(const File& file, FunctionId function_id) -> void {
  102. llvm::errs() << function_id;
  103. if (function_id.has_value()) {
  104. const auto& function = file.functions().Get(function_id);
  105. llvm::errs() << ": " << function;
  106. DumpNameIfValid(file, function.name_id);
  107. }
  108. llvm::errs() << '\n';
  109. }
  110. LLVM_DUMP_METHOD auto Dump(const File& file, GenericId generic_id) -> void {
  111. llvm::errs() << generic_id;
  112. if (!generic_id.has_value()) {
  113. llvm::errs() << '\n';
  114. return;
  115. }
  116. llvm::errs() << ": " << file.generics().Get(generic_id) << '\n';
  117. Dump(file, file.generics().Get(generic_id).bindings_id);
  118. }
  119. LLVM_DUMP_METHOD auto Dump(const File& file, ImplId impl_id) -> void {
  120. llvm::errs() << impl_id;
  121. if (!impl_id.has_value()) {
  122. llvm::errs() << '\n';
  123. return;
  124. }
  125. const auto& impl = file.impls().Get(impl_id);
  126. llvm::errs() << ": " << impl << '\n';
  127. llvm::errs() << " - interface_id: ";
  128. DumpNoNewline(file, impl.interface.interface_id);
  129. llvm::errs() << '\n';
  130. llvm::errs() << " - specific_id: ";
  131. DumpNoNewline(file, impl.interface.specific_id);
  132. llvm::errs() << '\n';
  133. if (impl.interface.specific_id.has_value()) {
  134. auto inst_block_id =
  135. file.specifics().Get(impl.interface.specific_id).args_id;
  136. Dump(file, inst_block_id);
  137. }
  138. }
  139. LLVM_DUMP_METHOD auto Dump(const File& file, InstBlockId inst_block_id)
  140. -> void {
  141. llvm::errs() << inst_block_id;
  142. if (inst_block_id.has_value()) {
  143. llvm::errs() << ":";
  144. auto inst_block = file.inst_blocks().Get(inst_block_id);
  145. for (auto inst_id : inst_block) {
  146. llvm::errs() << "\n - ";
  147. DumpNoNewline(file, inst_id);
  148. }
  149. }
  150. llvm::errs() << '\n';
  151. }
  152. LLVM_DUMP_METHOD auto Dump(const File& file, InstId inst_id) -> void {
  153. DumpNoNewline(file, inst_id);
  154. llvm::errs() << '\n';
  155. if (inst_id.has_value()) {
  156. Inst inst = file.insts().Get(inst_id);
  157. if (inst.type_id().has_value()) {
  158. llvm::errs() << " - type ";
  159. Dump(file, inst.type_id());
  160. }
  161. ConstantId const_id = file.constant_values().Get(inst_id);
  162. if (const_id.has_value()) {
  163. InstId const_inst_id = file.constant_values().GetInstId(const_id);
  164. llvm::errs() << " - value ";
  165. if (const_inst_id == inst_id) {
  166. llvm::errs() << const_id << '\n';
  167. } else {
  168. Dump(file, const_id);
  169. }
  170. }
  171. }
  172. }
  173. LLVM_DUMP_METHOD auto Dump(const File& file, InterfaceId interface_id) -> void {
  174. DumpNoNewline(file, interface_id);
  175. llvm::errs() << '\n';
  176. }
  177. LLVM_DUMP_METHOD auto Dump(const File& file, NameId name_id) -> void {
  178. llvm::errs() << name_id;
  179. DumpNameIfValid(file, name_id);
  180. llvm::errs() << '\n';
  181. }
  182. LLVM_DUMP_METHOD auto Dump(const File& file, NameScopeId name_scope_id)
  183. -> void {
  184. llvm::errs() << name_scope_id;
  185. if (name_scope_id.has_value()) {
  186. const auto& name_scope = file.name_scopes().Get(name_scope_id);
  187. llvm::errs() << ": " << name_scope;
  188. if (name_scope.inst_id().has_value()) {
  189. llvm::errs() << " " << file.insts().Get(name_scope.inst_id());
  190. }
  191. DumpNameIfValid(file, name_scope.name_id());
  192. llvm::errs() << '\n';
  193. for (const auto& entry : name_scope.entries()) {
  194. llvm::errs() << " - " << entry.name_id;
  195. DumpNameIfValid(file, entry.name_id);
  196. llvm::errs() << ": ";
  197. if (entry.result.is_poisoned()) {
  198. llvm::errs() << "<poisoned>\n";
  199. } else if (entry.result.is_found()) {
  200. switch (entry.result.access_kind()) {
  201. case AccessKind::Public:
  202. llvm::errs() << "public ";
  203. break;
  204. case AccessKind::Protected:
  205. llvm::errs() << "protected ";
  206. break;
  207. case AccessKind::Private:
  208. llvm::errs() << "private ";
  209. break;
  210. }
  211. DumpNoNewline(file, entry.result.target_inst_id());
  212. llvm::errs() << "\n";
  213. } else {
  214. llvm::errs() << "<not-found>\n";
  215. }
  216. }
  217. } else {
  218. llvm::errs() << '\n';
  219. }
  220. }
  221. LLVM_DUMP_METHOD auto Dump(const File& file,
  222. CompleteFacetTypeId complete_facet_type_id) -> void {
  223. llvm::errs() << complete_facet_type_id << "\n";
  224. if (complete_facet_type_id.has_value()) {
  225. const auto& complete_facet_type =
  226. file.complete_facet_types().Get(complete_facet_type_id);
  227. for (auto [i, req_interface] :
  228. llvm::enumerate(complete_facet_type.required_interfaces)) {
  229. llvm::errs() << " - ";
  230. DumpNoNewline(file, req_interface.interface_id);
  231. if (req_interface.specific_id.has_value()) {
  232. llvm::errs() << "; ";
  233. DumpNoNewline(file, req_interface.specific_id);
  234. }
  235. if (static_cast<int>(i) < complete_facet_type.num_to_impl) {
  236. llvm::errs() << " (to impl)";
  237. }
  238. llvm::errs() << '\n';
  239. }
  240. }
  241. }
  242. LLVM_DUMP_METHOD auto Dump(const File& file, SpecificId specific_id) -> void {
  243. DumpNoNewline(file, specific_id);
  244. llvm::errs() << '\n';
  245. if (specific_id.has_value()) {
  246. Dump(file, file.specifics().Get(specific_id).args_id);
  247. }
  248. }
  249. LLVM_DUMP_METHOD auto Dump(const File& file,
  250. SpecificInterfaceId specific_interface_id) -> void {
  251. const auto& interface = file.specific_interfaces().Get(specific_interface_id);
  252. llvm::errs() << specific_interface_id << '\n';
  253. llvm::errs() << " - interface: ";
  254. DumpNoNewline(file, interface.interface_id);
  255. llvm::errs() << '\n';
  256. llvm::errs() << " - specific_id: ";
  257. Dump(file, interface.specific_id);
  258. }
  259. LLVM_DUMP_METHOD auto Dump(const File& file,
  260. StructTypeFieldsId struct_type_fields_id) -> void {
  261. llvm::errs() << struct_type_fields_id;
  262. if (struct_type_fields_id.has_value()) {
  263. llvm::errs() << ":";
  264. auto block = file.struct_type_fields().Get(struct_type_fields_id);
  265. for (auto field : block) {
  266. llvm::errs() << "\n - " << field;
  267. DumpNameIfValid(file, field.name_id);
  268. if (field.type_id.has_value()) {
  269. InstId inst_id =
  270. file.constant_values().GetInstId(field.type_id.AsConstantId());
  271. llvm::errs() << ": " << StringifyTypeExpr(file, inst_id);
  272. }
  273. }
  274. }
  275. llvm::errs() << '\n';
  276. }
  277. LLVM_DUMP_METHOD auto Dump(const File& file, TypeBlockId type_block_id)
  278. -> void {
  279. llvm::errs() << type_block_id;
  280. if (type_block_id.has_value()) {
  281. llvm::errs() << ":\n";
  282. auto type_block = file.type_blocks().Get(type_block_id);
  283. for (auto type_id : type_block) {
  284. llvm::errs() << " - ";
  285. Dump(file, type_id);
  286. }
  287. } else {
  288. llvm::errs() << '\n';
  289. }
  290. }
  291. LLVM_DUMP_METHOD auto Dump(const File& file, TypeId type_id) -> void {
  292. llvm::errs() << type_id;
  293. if (type_id.has_value()) {
  294. InstId inst_id = file.constant_values().GetInstId(type_id.AsConstantId());
  295. llvm::errs() << ": " << StringifyTypeExpr(file, inst_id) << "; "
  296. << file.insts().Get(inst_id);
  297. }
  298. llvm::errs() << '\n';
  299. }
  300. // Functions that can be used instead of the corresponding constructor, which is
  301. // unavailable during debugging.
  302. LLVM_DUMP_METHOD static auto MakeClassId(int id) -> ClassId {
  303. return ClassId(id);
  304. }
  305. LLVM_DUMP_METHOD static auto MakeConstantId(int id) -> ConstantId {
  306. return ConstantId(id);
  307. }
  308. LLVM_DUMP_METHOD static auto MakeSymbolicConstantId(int id) -> ConstantId {
  309. return ConstantId::ForSymbolicConstantIndex(id);
  310. }
  311. LLVM_DUMP_METHOD static auto MakeEntityNameId(int id) -> EntityNameId {
  312. return EntityNameId(id);
  313. }
  314. LLVM_DUMP_METHOD static auto MakeFacetTypeId(int id) -> FacetTypeId {
  315. return FacetTypeId(id);
  316. }
  317. LLVM_DUMP_METHOD static auto MakeFunctionId(int id) -> FunctionId {
  318. return FunctionId(id);
  319. }
  320. LLVM_DUMP_METHOD static auto MakeGenericId(int id) -> GenericId {
  321. return GenericId(id);
  322. }
  323. LLVM_DUMP_METHOD static auto MakeImplId(int id) -> ImplId { return ImplId(id); }
  324. LLVM_DUMP_METHOD static auto MakeInstBlockId(int id) -> InstBlockId {
  325. return InstBlockId(id);
  326. }
  327. LLVM_DUMP_METHOD static auto MakeInstId(int id) -> InstId { return InstId(id); }
  328. LLVM_DUMP_METHOD static auto MakeInterfaceId(int id) -> InterfaceId {
  329. return InterfaceId(id);
  330. }
  331. LLVM_DUMP_METHOD static auto MakeNameId(int id) -> NameId { return NameId(id); }
  332. LLVM_DUMP_METHOD static auto MakeNameScopeId(int id) -> NameScopeId {
  333. return NameScopeId(id);
  334. }
  335. LLVM_DUMP_METHOD static auto MakeCompleteFacetTypeId(int id)
  336. -> CompleteFacetTypeId {
  337. return CompleteFacetTypeId(id);
  338. }
  339. LLVM_DUMP_METHOD static auto MakeSpecificId(int id) -> SpecificId {
  340. return SpecificId(id);
  341. }
  342. LLVM_DUMP_METHOD static auto MakeSpecificInterfaceId(int id)
  343. -> SpecificInterfaceId {
  344. return SpecificInterfaceId(id);
  345. }
  346. LLVM_DUMP_METHOD static auto MakeStructTypeFieldsId(int id)
  347. -> StructTypeFieldsId {
  348. return StructTypeFieldsId(id);
  349. }
  350. LLVM_DUMP_METHOD static auto MakeTypeBlockId(int id) -> TypeBlockId {
  351. return TypeBlockId(id);
  352. }
  353. LLVM_DUMP_METHOD static auto MakeTypeId(int id) -> TypeId { return TypeId(id); }
  354. } // namespace Carbon::SemIR
  355. #endif // NDEBUG