inst_namer.cpp 48 KB

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