inst_namer.cpp 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480
  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. #include "toolchain/sem_ir/inst_namer.h"
  5. #include <string>
  6. #include <utility>
  7. #include <variant>
  8. #include "common/ostream.h"
  9. #include "common/raw_string_ostream.h"
  10. #include "llvm/ADT/STLExtras.h"
  11. #include "llvm/ADT/SmallVector.h"
  12. #include "llvm/ADT/StableHashing.h"
  13. #include "toolchain/base/kind_switch.h"
  14. #include "toolchain/base/shared_value_stores.h"
  15. #include "toolchain/base/value_ids.h"
  16. #include "toolchain/lex/tokenized_buffer.h"
  17. #include "toolchain/parse/tree.h"
  18. #include "toolchain/sem_ir/cpp_overload_set.h"
  19. #include "toolchain/sem_ir/entity_with_params_base.h"
  20. #include "toolchain/sem_ir/function.h"
  21. #include "toolchain/sem_ir/ids.h"
  22. #include "toolchain/sem_ir/inst_kind.h"
  23. #include "toolchain/sem_ir/pattern.h"
  24. #include "toolchain/sem_ir/singleton_insts.h"
  25. #include "toolchain/sem_ir/specific_interface.h"
  26. #include "toolchain/sem_ir/specific_named_constraint.h"
  27. #include "toolchain/sem_ir/type_info.h"
  28. #include "toolchain/sem_ir/typed_insts.h"
  29. namespace Carbon::SemIR {
  30. class InstNamer::NamingContext {
  31. public:
  32. explicit NamingContext(InstNamer* inst_namer, InstNamer::ScopeId scope_id,
  33. InstId inst_id);
  34. // Names the single instruction. Use bound names where available. Otherwise,
  35. // assign a backup name.
  36. //
  37. // Insts with a type_id are required to add names; other insts may
  38. // optionally set a name. All insts may push other insts to be named.
  39. auto NameInst() -> void;
  40. private:
  41. // Adds the instruction's name.
  42. auto AddInstName(std::string name) -> void;
  43. // Adds the instruction's name for a StructType, which contains the names of
  44. // its fields.
  45. auto AddStructTypeInstName(StructType struct_ty, llvm::StringRef type_suffix,
  46. llvm::StringRef name_suffix) -> void;
  47. // Adds the instruction's name by `NameId`.
  48. auto AddInstNameId(NameId name_id, llvm::StringRef suffix = "") -> void {
  49. AddInstName((sem_ir().names().GetIRBaseName(name_id) + suffix).str());
  50. }
  51. // Names an `IntType` or `FloatType`.
  52. auto AddIntOrFloatTypeName(char type_literal_prefix, InstId bit_width_id,
  53. llvm::StringRef suffix = "") -> void;
  54. // Names an `ImplWitnessTable` instruction.
  55. auto AddWitnessTableName(InstId witness_table_inst_id, std::string name)
  56. -> void;
  57. auto AddBlockLabel(ScopeId scope_id, InstBlockId block_id, std::string name,
  58. LocId loc_id) -> void {
  59. inst_namer_->AddBlockLabel(scope_id, block_id, name, loc_id);
  60. }
  61. // Pushes all instructions in a generic, by ID.
  62. auto PushGeneric(ScopeId scope_id, GenericId generic_id) -> void {
  63. inst_namer_->PushGeneric(scope_id, generic_id);
  64. }
  65. // Pushes all instructions in a block, by ID.
  66. auto PushBlockId(ScopeId scope_id, InstBlockId block_id) -> void {
  67. inst_namer_->PushBlockId(scope_id, block_id);
  68. }
  69. // Names the instruction as an entity. May push processing of the entity.
  70. template <typename EntityIdT>
  71. auto AddEntityNameAndMaybePush(EntityIdT id, llvm::StringRef suffix = "")
  72. -> void {
  73. AddInstName((inst_namer_->MaybePushEntity(id) + suffix).str());
  74. }
  75. auto sem_ir() -> const File& { return *inst_namer_->sem_ir_; }
  76. InstNamer* inst_namer_;
  77. ScopeId scope_id_;
  78. InstId inst_id_;
  79. Inst inst_;
  80. };
  81. InstNamer::InstNamer(const File* sem_ir, int total_ir_count)
  82. : sem_ir_(sem_ir), fingerprinter_(total_ir_count) {
  83. insts_.resize(sem_ir->insts().size(), {ScopeId::None, Namespace::Name()});
  84. labels_.resize(sem_ir->inst_blocks().size());
  85. scopes_.resize(GetScopeIdOffset(ScopeIdTypeEnum::None));
  86. generic_scopes_.resize(sem_ir->generics().size(), ScopeId::None);
  87. // We process the stack between each large block in order to reduce the
  88. // temporary size of the stack.
  89. auto process_stack = [&] {
  90. while (!inst_stack_.empty() || !inst_block_stack_.empty()) {
  91. if (inst_stack_.empty()) {
  92. auto [scope_id, block_id] = inst_block_stack_.pop_back_val();
  93. if (block_id != SemIR::InstBlockId::Empty) {
  94. PushBlockInsts(scope_id, sem_ir_->inst_blocks().Get(block_id));
  95. }
  96. }
  97. while (!inst_stack_.empty()) {
  98. auto [scope_id, inst_id] = inst_stack_.pop_back_val();
  99. NamingContext context(this, scope_id, inst_id);
  100. context.NameInst();
  101. }
  102. }
  103. };
  104. // Name each of the top-level scopes, in order. We use these as the roots of
  105. // walking the IR.
  106. PushBlockInsts(ScopeId::Constants, sem_ir->constants().array_ref());
  107. process_stack();
  108. PushBlockId(ScopeId::Imports, InstBlockId::Imports);
  109. process_stack();
  110. PushBlockId(ScopeId::Generated, InstBlockId::Generated);
  111. process_stack();
  112. PushBlockId(ScopeId::File, sem_ir->top_inst_block_id());
  113. process_stack();
  114. // Global init won't have any other references, so we add it directly.
  115. if (sem_ir_->global_ctor_id().has_value()) {
  116. MaybePushEntity(sem_ir_->global_ctor_id());
  117. process_stack();
  118. }
  119. }
  120. auto InstNamer::GetScopeIdOffset(ScopeIdTypeEnum id_enum) const -> int {
  121. int offset = 0;
  122. // For each Id type, add the number of entities *above* its case; for example,
  123. // the offset for functions excludes the functions themselves. The fallthrough
  124. // handles summing to get uniqueness; order isn't special.
  125. switch (id_enum) {
  126. case ScopeIdTypeEnum::None:
  127. // `None` will be getting a full count of scopes.
  128. offset += sem_ir_->associated_constants().size();
  129. [[fallthrough]];
  130. case ScopeIdTypeEnum::For<AssociatedConstantId>:
  131. offset += sem_ir_->classes().size();
  132. [[fallthrough]];
  133. case ScopeIdTypeEnum::For<ClassId>:
  134. offset += sem_ir_->cpp_overload_sets().size();
  135. [[fallthrough]];
  136. case ScopeIdTypeEnum::For<CppOverloadSetId>:
  137. offset += sem_ir_->functions().size();
  138. [[fallthrough]];
  139. case ScopeIdTypeEnum::For<FunctionId>:
  140. offset += sem_ir_->impls().size();
  141. [[fallthrough]];
  142. case ScopeIdTypeEnum::For<ImplId>:
  143. offset += sem_ir_->interfaces().size();
  144. [[fallthrough]];
  145. case ScopeIdTypeEnum::For<InterfaceId>:
  146. offset += sem_ir_->interfaces().size();
  147. [[fallthrough]];
  148. case ScopeIdTypeEnum::For<InterfaceWithSelfId>:
  149. offset += sem_ir_->named_constraints().size();
  150. [[fallthrough]];
  151. case ScopeIdTypeEnum::For<NamedConstraintId>:
  152. offset += sem_ir_->named_constraints().size();
  153. [[fallthrough]];
  154. case ScopeIdTypeEnum::For<NamedConstraintWithSelfId>:
  155. offset += sem_ir_->require_impls().size();
  156. [[fallthrough]];
  157. case ScopeIdTypeEnum::For<RequireImplsId>:
  158. offset += sem_ir_->specific_interfaces().size();
  159. [[fallthrough]];
  160. case ScopeIdTypeEnum::For<SpecificInterfaceId>:
  161. offset += sem_ir_->vtables().size();
  162. [[fallthrough]];
  163. case ScopeIdTypeEnum::For<VtableId>:
  164. // All type-specific scopes are offset by `FirstEntityScope`.
  165. offset += static_cast<int>(ScopeId::FirstEntityScope);
  166. return offset;
  167. default:
  168. CARBON_FATAL("Unexpected ScopeIdTypeEnum: {0}", id_enum);
  169. }
  170. }
  171. auto InstNamer::GetScopeName(ScopeId scope) const -> std::string {
  172. switch (scope) {
  173. case ScopeId::None:
  174. return "<no scope>";
  175. // These are treated as SemIR keywords.
  176. case ScopeId::File:
  177. return "file";
  178. case ScopeId::Generated:
  179. return "generated";
  180. case ScopeId::Imports:
  181. return "imports";
  182. case ScopeId::Constants:
  183. return "constants";
  184. // For everything else, use an @ prefix.
  185. default:
  186. return ("@" + GetScopeInfo(scope).name.GetFullName()).str();
  187. }
  188. }
  189. auto InstNamer::GetUnscopedNameFor(InstId inst_id) const -> llvm::StringRef {
  190. if (!inst_id.has_value()) {
  191. return "";
  192. }
  193. if (IsSingletonInstId(inst_id)) {
  194. return sem_ir_->insts().Get(inst_id).kind().ir_name();
  195. }
  196. auto index = sem_ir_->insts().GetRawIndex(inst_id);
  197. const auto& inst_name = insts_[index].second;
  198. return inst_name ? inst_name.GetFullName() : "";
  199. }
  200. auto InstNamer::GetNameFor(ScopeId scope_id, InstId inst_id) const
  201. -> std::string {
  202. if (!inst_id.has_value()) {
  203. return "invalid";
  204. }
  205. // Check for a builtin.
  206. if (IsSingletonInstId(inst_id)) {
  207. return sem_ir_->insts().Get(inst_id).kind().ir_name().str();
  208. }
  209. if (inst_id == SemIR::Namespace::PackageInstId) {
  210. return "package";
  211. }
  212. auto index = sem_ir_->insts().GetRawIndex(inst_id);
  213. const auto& [inst_scope, inst_name] = insts_[index];
  214. if (!inst_name) {
  215. // This should not happen in valid IR.
  216. RawStringOstream out;
  217. out << "<unexpected>." << inst_id;
  218. auto loc_id = sem_ir_->insts().GetCanonicalLocId(inst_id);
  219. // TODO: Consider handling other kinds.
  220. if (loc_id.kind() == LocId::Kind::NodeId) {
  221. const auto& tree = sem_ir_->parse_tree();
  222. auto token = tree.node_token(loc_id.node_id());
  223. out << ".loc" << tree.tokens().GetLineNumber(token) << "_"
  224. << tree.tokens().GetColumnNumber(token);
  225. }
  226. return out.TakeStr();
  227. }
  228. if (inst_scope == scope_id) {
  229. return ("%" + inst_name.GetFullName()).str();
  230. }
  231. return (GetScopeName(inst_scope) + ".%" + inst_name.GetFullName()).str();
  232. }
  233. auto InstNamer::GetUnscopedLabelFor(InstBlockId block_id) const
  234. -> llvm::StringRef {
  235. if (!block_id.has_value()) {
  236. return "";
  237. }
  238. const auto& label_name =
  239. labels_[sem_ir_->inst_blocks().GetRawIndex(block_id)].second;
  240. return label_name ? label_name.GetFullName() : "";
  241. }
  242. // Returns the IR name to use for a label, when referenced from a given scope.
  243. auto InstNamer::GetLabelFor(ScopeId scope_id, InstBlockId block_id) const
  244. -> std::string {
  245. if (!block_id.has_value()) {
  246. return "!invalid";
  247. }
  248. const auto& [label_scope, label_name] =
  249. labels_[sem_ir_->inst_blocks().GetRawIndex(block_id)];
  250. if (!label_name) {
  251. // This should not happen in valid IR.
  252. RawStringOstream out;
  253. out << "<unexpected instblockref " << block_id << ">";
  254. return out.TakeStr();
  255. }
  256. if (label_scope == scope_id) {
  257. return ("!" + label_name.GetFullName()).str();
  258. }
  259. return (GetScopeName(label_scope) + ".!" + label_name.GetFullName()).str();
  260. }
  261. auto InstNamer::Namespace::Name::GetFullName() const -> llvm::StringRef {
  262. if (!value_) {
  263. return "<null name>";
  264. }
  265. llvm::StringMapEntry<NameResult>* value = value_;
  266. while (value->second.ambiguous && value->second.fallback) {
  267. value = value->second.fallback.value_;
  268. }
  269. return value->first();
  270. }
  271. auto InstNamer::Namespace::Name::GetBaseName() const -> llvm::StringRef {
  272. if (!value_) {
  273. return "<null name>";
  274. }
  275. return value_->first().take_front(base_name_size_);
  276. }
  277. auto InstNamer::Namespace::AllocateName(
  278. const InstNamer& inst_namer,
  279. std::variant<LocId, uint64_t> loc_id_or_fingerprint, std::string name)
  280. -> Name {
  281. // The best (shortest) name for this instruction so far, and the current
  282. // name for it.
  283. Name best;
  284. Name current;
  285. const size_t base_name_size = name.size();
  286. // Add `name` as a name for this entity.
  287. auto add_name = [&](bool mark_ambiguous = true) {
  288. auto [it, added] = allocated_.insert({name, NameResult()});
  289. Name new_name = Name(it, base_name_size);
  290. if (!added) {
  291. if (mark_ambiguous) {
  292. // This name was allocated for a different instruction. Mark it as
  293. // ambiguous and keep looking for a name for this instruction.
  294. new_name.SetAmbiguous();
  295. }
  296. } else {
  297. if (!best) {
  298. best = new_name;
  299. } else {
  300. CARBON_CHECK(current);
  301. current.SetFallback(new_name);
  302. }
  303. current = new_name;
  304. }
  305. return added;
  306. };
  307. // Use the given name if it's available.
  308. if (!name.empty()) {
  309. add_name();
  310. }
  311. // Append location information to try to disambiguate.
  312. if (auto* loc_id = std::get_if<LocId>(&loc_id_or_fingerprint)) {
  313. *loc_id = inst_namer.sem_ir_->insts().GetCanonicalLocId(*loc_id);
  314. // TODO: Consider handling other kinds.
  315. if (loc_id->kind() == LocId::Kind::NodeId) {
  316. const auto& tree = inst_namer.sem_ir_->parse_tree();
  317. auto token = tree.node_token(loc_id->node_id());
  318. llvm::raw_string_ostream(name)
  319. << ".loc" << tree.tokens().GetLineNumber(token);
  320. add_name();
  321. llvm::raw_string_ostream(name)
  322. << "_" << tree.tokens().GetColumnNumber(token);
  323. add_name();
  324. }
  325. } else {
  326. uint64_t fingerprint = std::get<uint64_t>(loc_id_or_fingerprint);
  327. llvm::raw_string_ostream out(name);
  328. out << ".";
  329. // Include names with 3-6 characters from the fingerprint. Then fall back to
  330. // sequential numbering.
  331. for (int n : llvm::seq(1, 7)) {
  332. out.write_hex((fingerprint >> (64 - 4 * n)) & 0xF);
  333. if (n >= 3) {
  334. add_name();
  335. }
  336. }
  337. }
  338. // Append numbers until we find an available name.
  339. name += ".";
  340. auto name_size_without_counter = name.size();
  341. for (int counter = 1;; ++counter) {
  342. name.resize(name_size_without_counter);
  343. llvm::raw_string_ostream(name) << counter;
  344. if (add_name(/*mark_ambiguous=*/false)) {
  345. return best;
  346. }
  347. }
  348. }
  349. auto InstNamer::AddBlockLabel(
  350. ScopeId scope_id, InstBlockId block_id, std::string name,
  351. std::variant<LocId, uint64_t> loc_id_or_fingerprint) -> void {
  352. if (!block_id.has_value() ||
  353. labels_[sem_ir_->inst_blocks().GetRawIndex(block_id)].second) {
  354. return;
  355. }
  356. if (auto* loc_id = std::get_if<LocId>(&loc_id_or_fingerprint);
  357. loc_id && !loc_id->has_value()) {
  358. if (const auto& block = sem_ir_->inst_blocks().Get(block_id);
  359. !block.empty()) {
  360. loc_id_or_fingerprint = LocId(block.front());
  361. }
  362. }
  363. labels_[sem_ir_->inst_blocks().GetRawIndex(block_id)] = {
  364. scope_id, GetScopeInfo(scope_id).labels.AllocateName(
  365. *this, loc_id_or_fingerprint, std::move(name))};
  366. }
  367. // Provides names for `AddBlockLabel`.
  368. struct BranchNames {
  369. // Returns names for a branching parse node, or nullopt if not a branch.
  370. static auto For(Parse::NodeKind node_kind) -> std::optional<BranchNames> {
  371. switch (node_kind) {
  372. case Parse::NodeKind::ForHeaderStart:
  373. return {{.prefix = "for", .branch = "next"}};
  374. case Parse::NodeKind::ForHeader:
  375. return {{.prefix = "for", .branch_if = "body", .branch = "done"}};
  376. case Parse::NodeKind::IfExprIf:
  377. return {{.prefix = "if.expr",
  378. .branch_if = "then",
  379. .branch = "else",
  380. .branch_with_arg = "result"}};
  381. case Parse::NodeKind::IfCondition:
  382. return {{.prefix = "if", .branch_if = "then", .branch = "else"}};
  383. case Parse::NodeKind::IfStatement:
  384. return {{.prefix = "if", .branch = "done"}};
  385. case Parse::NodeKind::ShortCircuitOperandAnd:
  386. return {
  387. {.prefix = "and", .branch_if = "rhs", .branch_with_arg = "result"}};
  388. case Parse::NodeKind::ShortCircuitOperandOr:
  389. return {
  390. {.prefix = "or", .branch_if = "rhs", .branch_with_arg = "result"}};
  391. case Parse::NodeKind::WhileConditionStart:
  392. return {{.prefix = "while", .branch = "cond"}};
  393. case Parse::NodeKind::WhileCondition:
  394. return {{.prefix = "while", .branch_if = "body", .branch = "done"}};
  395. default:
  396. return std::nullopt;
  397. }
  398. }
  399. // Returns the provided suffix for the instruction kind, or an empty string.
  400. auto GetSuffix(InstKind inst_kind) -> llvm::StringLiteral {
  401. switch (inst_kind) {
  402. case BranchIf::Kind:
  403. return branch_if;
  404. case Branch::Kind:
  405. return branch;
  406. case BranchWithArg::Kind:
  407. return branch_with_arg;
  408. default:
  409. return "";
  410. }
  411. }
  412. // The kind of branch, based on the node kind.
  413. llvm::StringLiteral prefix;
  414. // For labeling branch instruction kinds. Only expected kinds need a value;
  415. // the empty string is for unexpected kinds.
  416. llvm::StringLiteral branch_if = "";
  417. llvm::StringLiteral branch = "";
  418. llvm::StringLiteral branch_with_arg = "";
  419. };
  420. // Finds and adds a suitable block label for the given SemIR instruction that
  421. // represents some kind of branch.
  422. auto InstNamer::AddBlockLabel(ScopeId scope_id, LocId loc_id, AnyBranch branch)
  423. -> void {
  424. std::string label;
  425. loc_id = sem_ir_->insts().GetCanonicalLocId(loc_id);
  426. if (loc_id.node_id().has_value()) {
  427. if (auto names = BranchNames::For(
  428. sem_ir_->parse_tree().node_kind(loc_id.node_id()))) {
  429. if (auto suffix = names->GetSuffix(branch.kind); !suffix.empty()) {
  430. label = llvm::formatv("{0}.{1}", names->prefix, suffix);
  431. } else {
  432. label =
  433. llvm::formatv("{0}.<unexpected {1}>", names->prefix, branch.kind);
  434. }
  435. }
  436. }
  437. AddBlockLabel(scope_id, branch.target_id, label, loc_id);
  438. }
  439. auto InstNamer::PushBlockId(ScopeId scope_id, InstBlockId block_id) -> void {
  440. if (block_id.has_value()) {
  441. inst_block_stack_.push_back({scope_id, block_id});
  442. }
  443. }
  444. auto InstNamer::PushBlockInsts(ScopeId scope_id,
  445. llvm::ArrayRef<InstId> inst_ids) -> void {
  446. for (auto inst_id : llvm::reverse(inst_ids)) {
  447. if (inst_id.has_value() && !IsSingletonInstId(inst_id)) {
  448. inst_stack_.push_back(std::make_pair(scope_id, inst_id));
  449. }
  450. }
  451. }
  452. auto InstNamer::PushGeneric(ScopeId scope_id, GenericId generic_id) -> void {
  453. if (!generic_id.has_value()) {
  454. return;
  455. }
  456. generic_scopes_[sem_ir_->generics().GetRawIndex(generic_id)] = scope_id;
  457. const auto& generic = sem_ir_->generics().Get(generic_id);
  458. // Push blocks in reverse order.
  459. PushBlockId(scope_id, generic.definition_block_id);
  460. PushBlockId(scope_id, generic.decl_block_id);
  461. }
  462. auto InstNamer::PushEntity(AssociatedConstantId associated_constant_id,
  463. [[maybe_unused]] ScopeId scope_id, Scope& scope)
  464. -> void {
  465. const auto& assoc_const =
  466. sem_ir_->associated_constants().Get(associated_constant_id);
  467. scope.name = globals_.AllocateName(
  468. *this, LocId(assoc_const.decl_id),
  469. sem_ir_->names().GetIRBaseName(assoc_const.name_id).str());
  470. // The `decl_block_id` is associated with this `scope_id` from the
  471. // AssociatedConstantDecl instruction handler.
  472. }
  473. auto InstNamer::PushEntity(ClassId class_id, ScopeId scope_id, Scope& scope)
  474. -> void {
  475. const auto& class_info = sem_ir_->classes().Get(class_id);
  476. LocId class_loc(class_info.latest_decl_id());
  477. scope.name = globals_.AllocateName(
  478. *this, class_loc,
  479. sem_ir_->names().GetIRBaseName(class_info.name_id).str());
  480. AddBlockLabel(scope_id, class_info.body_block_id, "class", class_loc);
  481. PushGeneric(scope_id, class_info.generic_id);
  482. // Push blocks in reverse order.
  483. PushBlockId(scope_id, class_info.body_block_id);
  484. PushBlockId(scope_id, class_info.pattern_block_id);
  485. }
  486. auto InstNamer::GetNameForParentNameScope(NameScopeId name_scope_id)
  487. -> llvm::StringRef {
  488. if (!name_scope_id.has_value()) {
  489. return "";
  490. }
  491. auto scope_inst =
  492. sem_ir_->insts().Get(sem_ir_->name_scopes().Get(name_scope_id).inst_id());
  493. CARBON_KIND_SWITCH(scope_inst) {
  494. case CARBON_KIND(ClassDecl class_decl): {
  495. return MaybePushEntity(class_decl.class_id);
  496. }
  497. case CARBON_KIND(ImplDecl impl): {
  498. return MaybePushEntity(impl.impl_id);
  499. }
  500. case CARBON_KIND(InterfaceDecl interface): {
  501. return MaybePushEntity(interface.interface_id);
  502. }
  503. case CARBON_KIND(InterfaceWithSelfDecl interface_with_self): {
  504. return MaybePushEntity(
  505. InterfaceWithSelfId{interface_with_self.interface_id});
  506. }
  507. case CARBON_KIND(NamedConstraintDecl named_constraint): {
  508. return MaybePushEntity(named_constraint.named_constraint_id);
  509. }
  510. case CARBON_KIND(NamedConstraintWithSelfDecl named_constraint_with_self): {
  511. return MaybePushEntity(NamedConstraintWithSelfId{
  512. named_constraint_with_self.named_constraint_id});
  513. }
  514. case SemIR::Namespace::Kind: {
  515. // Only prefix type scopes.
  516. return "";
  517. }
  518. default: {
  519. return "<unsupported scope>";
  520. }
  521. }
  522. }
  523. auto InstNamer::PushEntity(FunctionId function_id, ScopeId scope_id,
  524. Scope& scope) -> void {
  525. const auto& fn = sem_ir_->functions().Get(function_id);
  526. LocId fn_loc(fn.latest_decl_id());
  527. auto scope_prefix = GetNameForParentNameScope(fn.parent_scope_id);
  528. scope.name = globals_.AllocateName(
  529. *this, fn_loc,
  530. llvm::formatv("{0}{1}{2}", scope_prefix, scope_prefix.empty() ? "" : ".",
  531. sem_ir_->names().GetIRBaseName(fn.name_id)));
  532. if (!fn.body_block_ids.empty()) {
  533. AddBlockLabel(scope_id, fn.body_block_ids.front(), "entry", fn_loc);
  534. }
  535. // Push blocks in reverse order.
  536. PushGeneric(scope_id, fn.generic_id);
  537. for (auto block_id : llvm::reverse(fn.body_block_ids)) {
  538. PushBlockId(scope_id, block_id);
  539. }
  540. PushBlockId(scope_id, fn.pattern_block_id);
  541. PushBlockId(scope_id, fn.call_params_id);
  542. }
  543. auto InstNamer::PushEntity(RequireImplsId require_impls_id, ScopeId scope_id,
  544. Scope& scope) -> void {
  545. const auto& require = sem_ir_->require_impls().Get(require_impls_id);
  546. LocId require_loc(require.decl_id);
  547. auto scope_prefix = GetNameForParentNameScope(require.parent_scope_id);
  548. llvm::StringRef self_name;
  549. auto self_const_id =
  550. sem_ir_->constant_values().GetConstantInstId(require.self_id);
  551. auto self_index = sem_ir_->insts().GetRawIndex(self_const_id);
  552. if (IsSingletonInstId(self_const_id)) {
  553. self_name = sem_ir_->insts().Get(self_const_id).kind().ir_name();
  554. } else if (const auto& inst_name = insts_[self_index].second) {
  555. self_name = inst_name.GetBaseName();
  556. } else {
  557. self_name = "<unexpected self>";
  558. }
  559. llvm::StringRef facet_type_name;
  560. auto facet_type_const_id =
  561. sem_ir_->constant_values().GetConstantInstId(require.facet_type_inst_id);
  562. auto facet_type_index = sem_ir_->insts().GetRawIndex(facet_type_const_id);
  563. if (IsSingletonInstId(facet_type_const_id)) {
  564. facet_type_name =
  565. sem_ir_->insts().Get(facet_type_const_id).kind().ir_name();
  566. } else if (const auto& inst_name = insts_[facet_type_index].second) {
  567. facet_type_name = inst_name.GetBaseName();
  568. } else {
  569. facet_type_name = "<unexpected facet type>";
  570. }
  571. scope.name = globals_.AllocateName(
  572. *this, require_loc,
  573. llvm::formatv("{0}{1}{2}.impls.{3}.require", scope_prefix,
  574. scope_prefix.empty() ? "" : ".", self_name,
  575. facet_type_name));
  576. auto decl = sem_ir_->insts().GetAs<SemIR::RequireImplsDecl>(require.decl_id);
  577. AddBlockLabel(scope_id, decl.decl_block_id, "require", require_loc);
  578. // Push blocks in reverse order.
  579. PushGeneric(scope_id, require.generic_id);
  580. }
  581. auto InstNamer::PushEntity(CppOverloadSetId cpp_overload_set_id,
  582. ScopeId /*scope_id*/, Scope& scope) -> void {
  583. const CppOverloadSet& overload_set =
  584. sem_ir_->cpp_overload_sets().Get(cpp_overload_set_id);
  585. uint64_t fingerprint =
  586. fingerprinter_.GetOrCompute(sem_ir_, cpp_overload_set_id);
  587. auto scope_prefix = GetNameForParentNameScope(overload_set.parent_scope_id);
  588. scope.name = globals_.AllocateName(
  589. *this, fingerprint,
  590. llvm::formatv("{0}{1}{2}.cpp_overload_set", scope_prefix,
  591. scope_prefix.empty() ? "" : ".",
  592. sem_ir_->names().GetIRBaseName(overload_set.name_id)));
  593. }
  594. auto InstNamer::PushEntity(ImplId impl_id, ScopeId scope_id, Scope& scope)
  595. -> void {
  596. const auto& impl = sem_ir_->impls().Get(impl_id);
  597. auto impl_fingerprint = fingerprinter_.GetOrCompute(sem_ir_, impl_id);
  598. llvm::StringRef self_name;
  599. auto self_const_id =
  600. sem_ir_->constant_values().GetConstantInstId(impl.self_id);
  601. auto index = sem_ir_->insts().GetRawIndex(self_const_id);
  602. if (IsSingletonInstId(self_const_id)) {
  603. self_name = sem_ir_->insts().Get(self_const_id).kind().ir_name();
  604. } else if (const auto& inst_name = insts_[index].second) {
  605. self_name = inst_name.GetBaseName();
  606. } else {
  607. self_name = "<unexpected self>";
  608. }
  609. llvm::StringRef interface_name;
  610. if (impl.interface.interface_id.has_value()) {
  611. interface_name = MaybePushEntity(impl.interface.interface_id);
  612. } else {
  613. interface_name = "<error>";
  614. }
  615. scope.name = globals_.AllocateName(
  616. *this, impl_fingerprint,
  617. llvm::formatv("{0}.as.{1}.impl", self_name, interface_name));
  618. AddBlockLabel(scope_id, impl.body_block_id, "impl", impl_fingerprint);
  619. // Push blocks in reverse order.
  620. PushGeneric(scope_id, impl.generic_id);
  621. PushBlockId(scope_id, impl.witness_block_id);
  622. PushBlockId(scope_id, impl.body_block_id);
  623. PushBlockId(scope_id, impl.pattern_block_id);
  624. }
  625. auto InstNamer::PushEntity(InterfaceId interface_id, ScopeId scope_id,
  626. Scope& scope) -> void {
  627. const auto& interface = sem_ir_->interfaces().Get(interface_id);
  628. LocId interface_loc(interface.latest_decl_id());
  629. auto name = sem_ir_->names().GetIRBaseName(interface.name_id).str();
  630. scope.name = globals_.AllocateName(*this, interface_loc, name);
  631. AddBlockLabel(scope_id, interface.body_block_without_self_id, "interface",
  632. interface_loc);
  633. // Push blocks in reverse order.
  634. PushGeneric(scope_id, interface.generic_id);
  635. PushBlockId(scope_id, interface.body_block_without_self_id);
  636. PushBlockId(scope_id, interface.pattern_block_id);
  637. }
  638. auto InstNamer::PushEntity(InterfaceWithSelfId interface_id, ScopeId scope_id,
  639. Scope& scope) -> void {
  640. const auto& interface = sem_ir_->interfaces().Get(interface_id.id);
  641. LocId interface_loc(interface.latest_decl_id());
  642. auto name = sem_ir_->names().GetIRBaseName(interface.name_id).str();
  643. name += ".WithSelf";
  644. scope.name = globals_.AllocateName(*this, interface_loc, name);
  645. AddBlockLabel(scope_id, interface.body_block_with_self_id,
  646. "interface_with_self", interface_loc);
  647. // Push blocks in reverse order.
  648. PushGeneric(scope_id, interface.generic_with_self_id);
  649. PushBlockId(scope_id, interface.body_block_with_self_id);
  650. }
  651. auto InstNamer::PushEntity(NamedConstraintId named_constraint_id,
  652. ScopeId scope_id, Scope& scope) -> void {
  653. const auto& constraint =
  654. sem_ir_->named_constraints().Get(named_constraint_id);
  655. LocId constraint_loc(constraint.latest_decl_id());
  656. auto name = sem_ir_->names().GetIRBaseName(constraint.name_id).str();
  657. scope.name = globals_.AllocateName(*this, constraint_loc, name);
  658. AddBlockLabel(scope_id, constraint.body_block_without_self_id, "constraint",
  659. constraint_loc);
  660. // Push blocks in reverse order.
  661. PushGeneric(scope_id, constraint.generic_id);
  662. PushBlockId(scope_id, constraint.body_block_without_self_id);
  663. PushBlockId(scope_id, constraint.pattern_block_id);
  664. }
  665. auto InstNamer::PushEntity(NamedConstraintWithSelfId named_constraint_id,
  666. ScopeId scope_id, Scope& scope) -> void {
  667. const auto& constraint =
  668. sem_ir_->named_constraints().Get(named_constraint_id.id);
  669. LocId constraint_loc(constraint.latest_decl_id());
  670. auto name = sem_ir_->names().GetIRBaseName(constraint.name_id).str();
  671. name += ".WithSelf";
  672. scope.name = globals_.AllocateName(*this, constraint_loc, name);
  673. AddBlockLabel(scope_id, constraint.body_block_with_self_id,
  674. "constraint_with_self", constraint_loc);
  675. // Push blocks in reverse order.
  676. PushGeneric(scope_id, constraint.generic_with_self_id);
  677. PushBlockId(scope_id, constraint.body_block_with_self_id);
  678. }
  679. auto InstNamer::PushEntity(VtableId vtable_id, ScopeId /*scope_id*/,
  680. Scope& scope) -> void {
  681. const auto& vtable = sem_ir_->vtables().Get(vtable_id);
  682. const auto& class_info = sem_ir_->classes().Get(vtable.class_id);
  683. LocId vtable_loc(class_info.latest_decl_id());
  684. scope.name = globals_.AllocateName(
  685. *this, vtable_loc,
  686. sem_ir_->names().GetIRBaseName(class_info.name_id).str() + ".vtable");
  687. // TODO: Add support for generic vtables here and elsewhere.
  688. // PushGeneric(scope_id, vtable_info.generic_id);
  689. }
  690. InstNamer::NamingContext::NamingContext(InstNamer* inst_namer,
  691. InstNamer::ScopeId scope_id,
  692. InstId inst_id)
  693. : inst_namer_(inst_namer),
  694. scope_id_(scope_id),
  695. inst_id_(inst_id),
  696. inst_(sem_ir().insts().Get(inst_id)) {}
  697. auto InstNamer::NamingContext::AddInstName(std::string name) -> void {
  698. auto index = sem_ir().insts().GetRawIndex(inst_id_);
  699. ScopeId old_scope_id = inst_namer_->insts_[index].first;
  700. if (old_scope_id == ScopeId::None) {
  701. std::variant<LocId, uint64_t> loc_id_or_fingerprint = LocId::None;
  702. if (scope_id_ == ScopeId::Constants || scope_id_ == ScopeId::Generated ||
  703. scope_id_ == ScopeId::Imports) {
  704. loc_id_or_fingerprint =
  705. inst_namer_->fingerprinter_.GetOrCompute(&sem_ir(), inst_id_);
  706. } else {
  707. loc_id_or_fingerprint = LocId(inst_id_);
  708. }
  709. auto scoped_name = inst_namer_->GetScopeInfo(scope_id_).insts.AllocateName(
  710. *inst_namer_, loc_id_or_fingerprint, std::move(name));
  711. inst_namer_->insts_[index] = {scope_id_, scoped_name};
  712. } else {
  713. CARBON_CHECK(old_scope_id == scope_id_,
  714. "Attempting to name inst in multiple scopes");
  715. }
  716. }
  717. auto InstNamer::NamingContext::AddStructTypeInstName(
  718. StructType struct_ty, llvm::StringRef type_suffix,
  719. llvm::StringRef name_suffix) -> void {
  720. RawStringOstream out;
  721. const auto& fields = sem_ir().struct_type_fields().Get(struct_ty.fields_id);
  722. if (fields.empty()) {
  723. out << "empty_struct" << type_suffix;
  724. } else {
  725. RawStringOstream name;
  726. name << "struct" << type_suffix;
  727. for (auto field : fields) {
  728. name << ".";
  729. name << sem_ir().names().GetIRBaseName(field.name_id);
  730. }
  731. out << name.TakeStr();
  732. }
  733. out << name_suffix;
  734. AddInstName(out.TakeStr());
  735. }
  736. auto InstNamer::NamingContext::AddIntOrFloatTypeName(char type_literal_prefix,
  737. InstId bit_width_id,
  738. llvm::StringRef suffix)
  739. -> void {
  740. RawStringOstream out;
  741. out << type_literal_prefix;
  742. if (auto bit_width = sem_ir().insts().TryGetAs<IntValue>(bit_width_id)) {
  743. out << sem_ir().ints().Get(bit_width->int_id);
  744. } else {
  745. out << "N";
  746. }
  747. out << suffix;
  748. AddInstName(out.TakeStr());
  749. }
  750. auto InstNamer::NamingContext::AddWitnessTableName(InstId witness_table_inst_id,
  751. std::string name) -> void {
  752. auto witness_table =
  753. sem_ir().insts().TryGetAs<ImplWitnessTable>(witness_table_inst_id);
  754. if (!witness_table || !witness_table->impl_id.has_value()) {
  755. // TODO: If `impl_id` is None, the witness comes from a facet value. Can we
  756. // get the interface names from it? Store the facet value instruction in the
  757. // table?
  758. AddInstName(name);
  759. return;
  760. }
  761. const auto& impl = sem_ir().impls().Get(witness_table->impl_id);
  762. auto name_id = sem_ir().interfaces().Get(impl.interface.interface_id).name_id;
  763. std::string suffix = llvm::formatv(".{}", name);
  764. AddInstNameId(name_id, suffix);
  765. }
  766. auto InstNamer::NamingContext::NameInst() -> void {
  767. CARBON_KIND_SWITCH(inst_) {
  768. case AddrOf::Kind: {
  769. AddInstName("addr");
  770. return;
  771. }
  772. case ArrayType::Kind: {
  773. // TODO: Can we figure out the name of the type this is an array of?
  774. AddInstName("array_type");
  775. return;
  776. }
  777. case CARBON_KIND(AssociatedConstantDecl inst): {
  778. AddEntityNameAndMaybePush(inst.assoc_const_id);
  779. PushBlockId(inst_namer_->GetScopeFor(inst.assoc_const_id),
  780. inst.decl_block_id);
  781. return;
  782. }
  783. case CARBON_KIND(AssociatedEntity inst): {
  784. RawStringOstream out;
  785. out << "assoc" << inst.index.index;
  786. AddInstName(out.TakeStr());
  787. return;
  788. }
  789. case CARBON_KIND(AssociatedEntityType inst): {
  790. AddEntityNameAndMaybePush(inst.interface_id, ".assoc_type");
  791. return;
  792. }
  793. case CARBON_KIND_ANY(AnyBindingOrExportDecl, inst): {
  794. AddInstNameId(sem_ir().entity_names().Get(inst.entity_name_id).name_id);
  795. return;
  796. }
  797. case CARBON_KIND_ANY(AnyBindingPattern, inst): {
  798. auto name_id = NameId::Underscore;
  799. if (inst.entity_name_id.has_value()) {
  800. name_id = sem_ir().entity_names().Get(inst.entity_name_id).name_id;
  801. }
  802. AddInstNameId(name_id, ".patt");
  803. return;
  804. }
  805. case CARBON_KIND(BoolLiteral inst): {
  806. if (inst.value.ToBool()) {
  807. AddInstName("true");
  808. } else {
  809. AddInstName("false");
  810. }
  811. return;
  812. }
  813. case CARBON_KIND(BoundMethod inst): {
  814. auto type_id = sem_ir().insts().Get(inst.function_decl_id).type_id();
  815. if (auto fn_ty = sem_ir().types().TryGetAs<FunctionType>(type_id)) {
  816. AddEntityNameAndMaybePush(fn_ty->function_id, ".bound");
  817. } else {
  818. AddInstName("bound_method");
  819. }
  820. return;
  821. }
  822. case CARBON_KIND_ANY(AnyBranch, branch): {
  823. inst_namer_->AddBlockLabel(scope_id_, LocId(inst_id_), branch);
  824. return;
  825. }
  826. case CARBON_KIND(Call inst): {
  827. auto callee = GetCallee(sem_ir(), inst.callee_id);
  828. if (auto* fn = std::get_if<CalleeFunction>(&callee)) {
  829. AddEntityNameAndMaybePush(fn->function_id, ".call");
  830. return;
  831. }
  832. AddInstName("");
  833. return;
  834. }
  835. case CARBON_KIND(ClassDecl inst): {
  836. AddEntityNameAndMaybePush(inst.class_id, ".decl");
  837. auto class_scope_id = inst_namer_->GetScopeFor(inst.class_id);
  838. PushBlockId(class_scope_id, inst.decl_block_id);
  839. return;
  840. }
  841. case CARBON_KIND(ClassType inst): {
  842. if (auto type_info = RecognizedTypeInfo::ForType(sem_ir(), inst);
  843. type_info.is_valid()) {
  844. RawStringOstream out;
  845. if (type_info.PrintLiteral(sem_ir(), out)) {
  846. AddInstName(out.TakeStr());
  847. return;
  848. }
  849. }
  850. AddEntityNameAndMaybePush(inst.class_id);
  851. return;
  852. }
  853. case CompleteTypeWitness::Kind: {
  854. // TODO: Can we figure out the name of the type this is a witness for?
  855. AddInstName("complete_type");
  856. return;
  857. }
  858. case CARBON_KIND(VtableDecl inst): {
  859. const auto& vtable = sem_ir().vtables().Get(inst.vtable_id);
  860. inst_namer_->MaybePushEntity(inst.vtable_id);
  861. if (inst_namer_->GetScopeFor(vtable.class_id) == scope_id_) {
  862. inst_namer_->MaybePushEntity(vtable.class_id);
  863. AddInstName("vtable_decl");
  864. } else {
  865. AddEntityNameAndMaybePush(vtable.class_id, ".vtable_decl");
  866. }
  867. return;
  868. }
  869. case CARBON_KIND(VtablePtr inst): {
  870. const auto& vtable = sem_ir().vtables().Get(inst.vtable_id);
  871. inst_namer_->MaybePushEntity(inst.vtable_id);
  872. AddEntityNameAndMaybePush(vtable.class_id, ".vtable_ptr");
  873. return;
  874. }
  875. case ConstType::Kind: {
  876. // TODO: Can we figure out the name of the type argument?
  877. AddInstName("const");
  878. return;
  879. }
  880. case CARBON_KIND(CppTemplateNameType inst): {
  881. AddInstNameId(sem_ir().entity_names().Get(inst.name_id).name_id, ".type");
  882. return;
  883. }
  884. case CustomWitness::Kind: {
  885. AddInstName("custom_witness");
  886. return;
  887. }
  888. case CARBON_KIND(ExprPattern inst): {
  889. for (auto block_id :
  890. sem_ir().expr_regions().Get(inst.expr_region_id).block_ids) {
  891. PushBlockId(scope_id_, block_id);
  892. }
  893. AddInstName("expr_patt");
  894. return;
  895. }
  896. case CARBON_KIND(FacetAccessType inst): {
  897. auto name_id = SemIR::NameId::None;
  898. if (auto name =
  899. sem_ir().insts().TryGetAs<NameRef>(inst.facet_value_inst_id)) {
  900. name_id = name->name_id;
  901. } else if (auto bind = sem_ir().insts().TryGetAs<SymbolicBinding>(
  902. inst.facet_value_inst_id)) {
  903. name_id = sem_ir().entity_names().Get(bind->entity_name_id).name_id;
  904. }
  905. if (name_id.has_value()) {
  906. AddInstNameId(name_id, ".as_type");
  907. } else {
  908. AddInstName("as_type");
  909. }
  910. return;
  911. }
  912. case CARBON_KIND(FacetType inst): {
  913. const auto& facet_type_info =
  914. sem_ir().facet_types().Get(inst.facet_type_id);
  915. bool has_where = facet_type_info.other_requirements ||
  916. !facet_type_info.self_impls_constraints.empty() ||
  917. !facet_type_info.self_impls_named_constraints.empty() ||
  918. !facet_type_info.type_impls_interfaces.empty() ||
  919. !facet_type_info.type_impls_named_constraints.empty() ||
  920. !facet_type_info.rewrite_constraints.empty();
  921. if (facet_type_info.extend_constraints.size() == 1 &&
  922. facet_type_info.extend_named_constraints.empty()) {
  923. AddEntityNameAndMaybePush(
  924. facet_type_info.extend_constraints.front().interface_id,
  925. has_where ? "_where.type" : ".type");
  926. } else if (facet_type_info.extend_named_constraints.size() == 1 &&
  927. facet_type_info.extend_constraints.empty()) {
  928. AddEntityNameAndMaybePush(
  929. facet_type_info.extend_named_constraints.front()
  930. .named_constraint_id,
  931. has_where ? "_where.type" : ".type");
  932. } else if (facet_type_info.extend_constraints.empty() &&
  933. facet_type_info.extend_named_constraints.empty()) {
  934. AddInstName(has_where ? "type_where" : "type");
  935. } else {
  936. AddInstName("facet_type");
  937. }
  938. return;
  939. }
  940. case CARBON_KIND(FacetValue inst): {
  941. if (auto facet_type =
  942. sem_ir().types().TryGetAs<FacetType>(inst.type_id)) {
  943. const auto& facet_type_info =
  944. sem_ir().facet_types().Get(facet_type->facet_type_id);
  945. if (auto single = facet_type_info.TryAsSingleExtend()) {
  946. CARBON_KIND_SWITCH(*single) {
  947. case CARBON_KIND(SemIR::SpecificInterface interface): {
  948. AddEntityNameAndMaybePush(interface.interface_id, ".facet");
  949. break;
  950. }
  951. case CARBON_KIND(SemIR::SpecificNamedConstraint constraint): {
  952. AddEntityNameAndMaybePush(constraint.named_constraint_id,
  953. ".facet");
  954. break;
  955. }
  956. }
  957. return;
  958. }
  959. if (facet_type_info.HasNoConstraints()) {
  960. if (auto class_ty =
  961. sem_ir().insts().TryGetAs<ClassType>(inst.type_inst_id)) {
  962. AddEntityNameAndMaybePush(class_ty->class_id, ".type.facet");
  963. return;
  964. }
  965. if (auto tuple_ty = sem_ir().insts().TryGetAs<SemIR::TupleType>(
  966. inst.type_inst_id)) {
  967. if (tuple_ty->type_elements_id == InstBlockId::Empty) {
  968. AddInstName("empty_tuple.type.facet");
  969. } else {
  970. AddInstName("tuple.type.facet");
  971. }
  972. return;
  973. }
  974. if (auto struct_ty = sem_ir().insts().TryGetAs<SemIR::StructType>(
  975. inst.type_inst_id)) {
  976. AddStructTypeInstName(*struct_ty, "", ".type.facet");
  977. return;
  978. }
  979. }
  980. }
  981. AddInstName("facet_value");
  982. return;
  983. }
  984. case CARBON_KIND(FloatType inst): {
  985. AddIntOrFloatTypeName('f', inst.bit_width_id);
  986. return;
  987. }
  988. case FloatLiteralValue::Kind:
  989. case FloatValue::Kind: {
  990. AddInstName("float");
  991. return;
  992. }
  993. case CARBON_KIND(FunctionDecl inst): {
  994. AddEntityNameAndMaybePush(inst.function_id, ".decl");
  995. auto function_scope_id = inst_namer_->GetScopeFor(inst.function_id);
  996. PushBlockId(function_scope_id, inst.decl_block_id);
  997. return;
  998. }
  999. case CARBON_KIND(FunctionType inst): {
  1000. AddEntityNameAndMaybePush(inst.function_id, ".type");
  1001. return;
  1002. }
  1003. case CARBON_KIND(CppOverloadSetValue inst): {
  1004. AddEntityNameAndMaybePush(inst.overload_set_id, ".value");
  1005. return;
  1006. }
  1007. case CARBON_KIND(CppOverloadSetType inst): {
  1008. AddEntityNameAndMaybePush(inst.overload_set_id, ".type");
  1009. return;
  1010. }
  1011. case CARBON_KIND(GenericClassType inst): {
  1012. AddEntityNameAndMaybePush(inst.class_id, ".type");
  1013. return;
  1014. }
  1015. case CARBON_KIND(GenericInterfaceType inst): {
  1016. AddEntityNameAndMaybePush(inst.interface_id, ".type");
  1017. return;
  1018. }
  1019. case CARBON_KIND(GenericNamedConstraintType inst): {
  1020. AddEntityNameAndMaybePush(inst.named_constraint_id, ".type");
  1021. return;
  1022. }
  1023. case CARBON_KIND(ImplDecl inst): {
  1024. // `impl` declarations aren't named because they aren't added to any
  1025. // namespace, and so aren't referenced directly.
  1026. inst_namer_->MaybePushEntity(inst.impl_id);
  1027. PushBlockId(inst_namer_->GetScopeFor(inst.impl_id), inst.decl_block_id);
  1028. return;
  1029. }
  1030. case CARBON_KIND(LookupImplWitness inst): {
  1031. const auto& interface =
  1032. sem_ir().specific_interfaces().Get(inst.query_specific_interface_id);
  1033. AddEntityNameAndMaybePush(interface.interface_id, ".lookup_impl_witness");
  1034. return;
  1035. }
  1036. case CARBON_KIND(ImplWitness inst): {
  1037. AddWitnessTableName(inst.witness_table_id, "impl_witness");
  1038. return;
  1039. }
  1040. case CARBON_KIND(ImplWitnessAccess inst): {
  1041. // TODO: Include information about the impl?
  1042. RawStringOstream out;
  1043. out << "impl.elem" << inst.index.index;
  1044. AddInstName(out.TakeStr());
  1045. return;
  1046. }
  1047. case CARBON_KIND(ImplWitnessAccessSubstituted inst): {
  1048. // TODO: Include information about the impl?
  1049. RawStringOstream out;
  1050. auto access = sem_ir().insts().GetAs<ImplWitnessAccess>(
  1051. inst.impl_witness_access_id);
  1052. out << "impl.elem" << access.index.index << ".subst";
  1053. AddInstName(out.TakeStr());
  1054. return;
  1055. }
  1056. case ImplWitnessAssociatedConstant::Kind: {
  1057. AddInstName("impl_witness_assoc_constant");
  1058. return;
  1059. }
  1060. case ImplWitnessTable::Kind: {
  1061. AddWitnessTableName(inst_id_, "impl_witness_table");
  1062. return;
  1063. }
  1064. case ImportCppDecl::Kind: {
  1065. AddInstName("Cpp.import_cpp");
  1066. return;
  1067. }
  1068. case CARBON_KIND(ImportDecl inst): {
  1069. if (inst.package_id.has_value()) {
  1070. AddInstNameId(inst.package_id, ".import");
  1071. } else {
  1072. AddInstName("default.import");
  1073. }
  1074. return;
  1075. }
  1076. case CARBON_KIND_ANY(AnyImportRef, inst): {
  1077. // Build the base import name: <package>.<entity-name>
  1078. RawStringOstream out;
  1079. auto import_ir_inst =
  1080. sem_ir().import_ir_insts().Get(inst.import_ir_inst_id);
  1081. const auto& import_ir =
  1082. *sem_ir().import_irs().Get(import_ir_inst.ir_id()).sem_ir;
  1083. auto package_id = import_ir.package_id();
  1084. if (auto ident_id = package_id.AsIdentifierId(); ident_id.has_value()) {
  1085. out << import_ir.identifiers().Get(ident_id);
  1086. } else {
  1087. out << package_id.AsSpecialName();
  1088. }
  1089. out << ".";
  1090. // Add entity name if available.
  1091. if (inst.entity_name_id.has_value()) {
  1092. auto name_id = sem_ir().entity_names().Get(inst.entity_name_id).name_id;
  1093. out << sem_ir().names().GetIRBaseName(name_id);
  1094. } else {
  1095. out << "import_ref";
  1096. }
  1097. AddInstName(out.TakeStr());
  1098. // When building import refs, we frequently add instructions without
  1099. // a block. Constants that refer to them need to be separately
  1100. // named.
  1101. auto const_id = sem_ir().constant_values().Get(inst_id_);
  1102. if (const_id.has_value() && const_id.is_concrete()) {
  1103. auto const_inst_id = sem_ir().constant_values().GetInstId(const_id);
  1104. auto index = sem_ir().insts().GetRawIndex(const_inst_id);
  1105. if (!inst_namer_->insts_[index].second) {
  1106. inst_namer_->PushBlockInsts(ScopeId::Imports, const_inst_id);
  1107. }
  1108. }
  1109. return;
  1110. }
  1111. case CARBON_KIND(InstValue inst): {
  1112. inst_namer_->PushBlockInsts(scope_id_, inst.inst_id);
  1113. AddInstName(
  1114. ("inst." + sem_ir().insts().Get(inst.inst_id).kind().ir_name())
  1115. .str());
  1116. return;
  1117. }
  1118. case CARBON_KIND(InterfaceDecl inst): {
  1119. AddEntityNameAndMaybePush(inst.interface_id, ".decl");
  1120. auto interface_scope_id = inst_namer_->GetScopeFor(inst.interface_id);
  1121. PushBlockId(interface_scope_id, inst.decl_block_id);
  1122. return;
  1123. }
  1124. case CARBON_KIND(InterfaceWithSelfDecl inst): {
  1125. AddEntityNameAndMaybePush(InterfaceWithSelfId{inst.interface_id},
  1126. ".decl");
  1127. return;
  1128. }
  1129. case CARBON_KIND(IntType inst): {
  1130. AddIntOrFloatTypeName(inst.int_kind == IntKind::Signed ? 'i' : 'u',
  1131. inst.bit_width_id, ".builtin");
  1132. return;
  1133. }
  1134. case CARBON_KIND(IntValue inst): {
  1135. RawStringOstream out;
  1136. out << "int_" << sem_ir().ints().Get(inst.int_id);
  1137. AddInstName(out.TakeStr());
  1138. return;
  1139. }
  1140. case CARBON_KIND(NameBindingDecl inst): {
  1141. PushBlockId(scope_id_, inst.pattern_block_id);
  1142. return;
  1143. }
  1144. case CARBON_KIND(NamedConstraintDecl inst): {
  1145. AddEntityNameAndMaybePush(inst.named_constraint_id, ".decl");
  1146. auto interface_scope_id =
  1147. inst_namer_->GetScopeFor(inst.named_constraint_id);
  1148. PushBlockId(interface_scope_id, inst.decl_block_id);
  1149. return;
  1150. }
  1151. case CARBON_KIND(NamedConstraintWithSelfDecl inst): {
  1152. AddEntityNameAndMaybePush(
  1153. NamedConstraintWithSelfId{inst.named_constraint_id}, ".decl");
  1154. return;
  1155. }
  1156. case CARBON_KIND(NameRef inst): {
  1157. AddInstNameId(inst.name_id, ".ref");
  1158. return;
  1159. }
  1160. // The namespace is specified here due to the name conflict.
  1161. case CARBON_KIND(SemIR::Namespace inst): {
  1162. AddInstNameId(sem_ir().name_scopes().Get(inst.name_scope_id).name_id());
  1163. return;
  1164. }
  1165. case CARBON_KIND_ANY(AnyParam, inst): {
  1166. AddInstNameId(inst.pretty_name_id, ".param");
  1167. return;
  1168. }
  1169. case OutParamPattern::Kind:
  1170. case RefParamPattern::Kind:
  1171. case ValueParamPattern::Kind:
  1172. case VarParamPattern::Kind: {
  1173. AddInstNameId(GetPrettyNameFromPatternId(sem_ir(), inst_id_),
  1174. ".param_patt");
  1175. return;
  1176. }
  1177. case PatternType::Kind: {
  1178. AddInstName("pattern_type");
  1179. return;
  1180. }
  1181. case PointerType::Kind: {
  1182. AddInstName("ptr");
  1183. return;
  1184. }
  1185. case RequireCompleteType::Kind: {
  1186. AddInstName("require_complete");
  1187. return;
  1188. }
  1189. case CARBON_KIND(RequireImplsDecl inst): {
  1190. AddEntityNameAndMaybePush(inst.require_impls_id, ".decl");
  1191. auto require_scope_id = inst_namer_->GetScopeFor(inst.require_impls_id);
  1192. PushBlockId(require_scope_id, inst.decl_block_id);
  1193. return;
  1194. }
  1195. case ReturnSlotPattern::Kind: {
  1196. AddInstNameId(NameId::ReturnSlot, ".patt");
  1197. return;
  1198. }
  1199. case CARBON_KIND(SpecificFunction inst): {
  1200. auto type_id = sem_ir().insts().Get(inst.callee_id).type_id();
  1201. if (auto fn_ty = sem_ir().types().TryGetAs<FunctionType>(type_id)) {
  1202. AddEntityNameAndMaybePush(fn_ty->function_id, ".specific_fn");
  1203. } else {
  1204. AddInstName("specific_fn");
  1205. }
  1206. return;
  1207. }
  1208. case CARBON_KIND(SpecificImplFunction inst): {
  1209. auto type_id = sem_ir().insts().Get(inst.callee_id).type_id();
  1210. if (auto fn_ty = sem_ir().types().TryGetAs<FunctionType>(type_id)) {
  1211. AddEntityNameAndMaybePush(fn_ty->function_id, ".specific_impl_fn");
  1212. } else {
  1213. AddInstName("specific_impl_fn");
  1214. }
  1215. return;
  1216. }
  1217. case ReturnSlot::Kind: {
  1218. AddInstNameId(NameId::ReturnSlot);
  1219. return;
  1220. }
  1221. case CARBON_KIND(SpliceBlock inst): {
  1222. PushBlockId(scope_id_, inst.block_id);
  1223. AddInstName("");
  1224. return;
  1225. }
  1226. case StringLiteral::Kind: {
  1227. AddInstName("str");
  1228. return;
  1229. }
  1230. case CARBON_KIND(StructType inst): {
  1231. AddStructTypeInstName(inst, "_type", "");
  1232. return;
  1233. }
  1234. case CARBON_KIND(StructValue inst): {
  1235. if (auto fn_ty = sem_ir().types().TryGetAs<FunctionType>(inst.type_id)) {
  1236. AddEntityNameAndMaybePush(fn_ty->function_id);
  1237. } else if (auto class_ty =
  1238. sem_ir().types().TryGetAs<ClassType>(inst.type_id)) {
  1239. AddEntityNameAndMaybePush(class_ty->class_id, ".val");
  1240. } else if (auto generic_class_ty =
  1241. sem_ir().types().TryGetAs<GenericClassType>(
  1242. inst.type_id)) {
  1243. AddEntityNameAndMaybePush(generic_class_ty->class_id, ".generic");
  1244. } else if (auto generic_interface_ty =
  1245. sem_ir().types().TryGetAs<GenericInterfaceType>(
  1246. inst.type_id)) {
  1247. AddInstNameId(sem_ir()
  1248. .interfaces()
  1249. .Get(generic_interface_ty->interface_id)
  1250. .name_id,
  1251. ".generic");
  1252. } else if (auto template_name_ty =
  1253. sem_ir().types().TryGetAs<CppTemplateNameType>(
  1254. inst.type_id)) {
  1255. AddInstNameId(
  1256. sem_ir().entity_names().Get(template_name_ty->name_id).name_id,
  1257. ".template");
  1258. } else {
  1259. if (sem_ir().inst_blocks().Get(inst.elements_id).empty()) {
  1260. AddInstName("empty_struct");
  1261. } else {
  1262. AddInstName("struct");
  1263. }
  1264. }
  1265. return;
  1266. }
  1267. case CARBON_KIND(TupleAccess inst): {
  1268. RawStringOstream out;
  1269. out << "tuple.elem" << inst.index.index;
  1270. AddInstName(out.TakeStr());
  1271. return;
  1272. }
  1273. case CARBON_KIND(TupleType inst): {
  1274. if (inst.type_elements_id == InstBlockId::Empty) {
  1275. AddInstName("empty_tuple.type");
  1276. } else {
  1277. AddInstName("tuple.type");
  1278. }
  1279. return;
  1280. }
  1281. case CARBON_KIND(TupleValue inst): {
  1282. if (sem_ir().types().Is<ArrayType>(inst.type_id)) {
  1283. AddInstName("array");
  1284. } else if (inst.elements_id == InstBlockId::Empty) {
  1285. AddInstName("empty_tuple");
  1286. } else {
  1287. AddInstName("tuple");
  1288. }
  1289. return;
  1290. }
  1291. case CARBON_KIND(TypeLiteral inst): {
  1292. if (auto value_id =
  1293. sem_ir().constant_values().GetConstantInstId(inst.value_id);
  1294. value_id.has_value()) {
  1295. if (auto class_type = sem_ir().insts().TryGetAs<ClassType>(value_id)) {
  1296. if (auto type_info =
  1297. RecognizedTypeInfo::ForType(sem_ir(), *class_type);
  1298. type_info.is_valid()) {
  1299. RawStringOstream out;
  1300. if (type_info.PrintLiteral(sem_ir(), out)) {
  1301. AddInstName(out.TakeStr());
  1302. return;
  1303. }
  1304. }
  1305. }
  1306. }
  1307. AddInstName("");
  1308. return;
  1309. }
  1310. case CARBON_KIND(UnboundElementType inst): {
  1311. if (auto class_ty =
  1312. sem_ir().insts().TryGetAs<ClassType>(inst.class_type_inst_id)) {
  1313. AddEntityNameAndMaybePush(class_ty->class_id, ".elem");
  1314. } else {
  1315. AddInstName("elem_type");
  1316. }
  1317. return;
  1318. }
  1319. case UninitializedValue::Kind: {
  1320. AddInstName("uninit");
  1321. return;
  1322. }
  1323. case VarPattern::Kind: {
  1324. AddInstNameId(GetPrettyNameFromPatternId(sem_ir(), inst_id_),
  1325. ".var_patt");
  1326. return;
  1327. }
  1328. case CARBON_KIND(VarStorage inst): {
  1329. if (inst.pattern_id.has_value()) {
  1330. AddInstNameId(GetPrettyNameFromPatternId(sem_ir(), inst.pattern_id),
  1331. ".var");
  1332. } else {
  1333. AddInstName("var");
  1334. }
  1335. return;
  1336. }
  1337. default: {
  1338. // Sequentially number all remaining values.
  1339. if (inst_.kind().has_type()) {
  1340. AddInstName("");
  1341. }
  1342. return;
  1343. }
  1344. }
  1345. }
  1346. auto InstNamer::has_name(InstId inst_id) const -> bool {
  1347. return static_cast<bool>(
  1348. insts_[sem_ir_->insts().GetRawIndex(inst_id)].second);
  1349. }
  1350. } // namespace Carbon::SemIR