diff --git a/toolchain/check/check.cpp b/toolchain/check/check.cpp index c7ffda3f3637..e298dbde1795 100644 --- a/toolchain/check/check.cpp +++ b/toolchain/check/check.cpp @@ -883,7 +883,8 @@ static auto CheckParseTree( library_id = packaging->names.library_id; } unit_info.unit->sem_ir->emplace( - unit_info.check_ir_id, package_id, library_id, + unit_info.check_ir_id, package_id, + SemIR::LibraryNameId::ForStringLiteralValueId(library_id), *unit_info.unit->value_stores, unit_info.unit->tokens->source().filename().str()); diff --git a/toolchain/sem_ir/file.cpp b/toolchain/sem_ir/file.cpp index 05485e7acd60..4bbd99ebcfee 100644 --- a/toolchain/sem_ir/file.cpp +++ b/toolchain/sem_ir/file.cpp @@ -20,7 +20,7 @@ namespace Carbon::SemIR { File::File(CheckIRId check_ir_id, IdentifierId package_id, - StringLiteralValueId library_id, SharedValueStores& value_stores, + LibraryNameId library_id, SharedValueStores& value_stores, std::string filename) : check_ir_id_(check_ir_id), package_id_(package_id), diff --git a/toolchain/sem_ir/file.h b/toolchain/sem_ir/file.h index e2ea1d3a6ef2..89b76e3f6c24 100644 --- a/toolchain/sem_ir/file.h +++ b/toolchain/sem_ir/file.h @@ -34,8 +34,8 @@ class File : public Printable { public: // Starts a new file for Check::CheckParseTree. explicit File(CheckIRId check_ir_id, IdentifierId package_id, - StringLiteralValueId library_id, - SharedValueStores& value_stores, std::string filename); + LibraryNameId library_id, SharedValueStores& value_stores, + std::string filename); File(const File&) = delete; auto operator=(const File&) -> File& = delete; @@ -82,7 +82,7 @@ class File : public Printable { auto check_ir_id() const -> CheckIRId { return check_ir_id_; } auto package_id() const -> IdentifierId { return package_id_; } - auto library_id() const -> StringLiteralValueId { return library_id_; } + auto library_id() const -> SemIR::LibraryNameId { return library_id_; } // Directly expose SharedValueStores members. auto identifiers() -> CanonicalValueStore& { @@ -181,7 +181,7 @@ class File : public Printable { IdentifierId package_id_ = IdentifierId::Invalid; // The file's library. - StringLiteralValueId library_id_ = StringLiteralValueId::Invalid; + LibraryNameId library_id_ = LibraryNameId::Invalid; // Shared, compile-scoped values. SharedValueStores* value_stores_; diff --git a/toolchain/sem_ir/formatter.cpp b/toolchain/sem_ir/formatter.cpp index 14641af8aa4b..2e145dab1f43 100644 --- a/toolchain/sem_ir/formatter.cpp +++ b/toolchain/sem_ir/formatter.cpp @@ -900,10 +900,12 @@ class FormatterImpl { out_ << "Main"; } out_ << "//"; - if (import_ir.library_id().is_valid()) { - out_ << import_ir.string_literal_values().Get(import_ir.library_id()); - } else { + CARBON_CHECK(import_ir.library_id().is_valid()); + if (import_ir.library_id() == LibraryNameId::Default) { out_ << "default"; + } else { + out_ << import_ir.string_literal_values().Get( + import_ir.library_id().AsStringLiteralValueId()); } } diff --git a/toolchain/sem_ir/id_kind.h b/toolchain/sem_ir/id_kind.h index ba411440563b..20c492bef19d 100644 --- a/toolchain/sem_ir/id_kind.h +++ b/toolchain/sem_ir/id_kind.h @@ -123,7 +123,7 @@ using IdKind = TypeEnum< InstId, ConstantId, EntityNameId, CompileTimeBindIndex, FunctionId, ClassId, InterfaceId, ImplId, GenericId, SpecificId, ImportIRId, ImportIRInstId, LocId, BoolValue, IntKind, NameId, NameScopeId, InstBlockId, TypeId, - TypeBlockId, ElementIndex, FloatKind>; + TypeBlockId, ElementIndex, LibraryNameId, FloatKind>; } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/ids.h b/toolchain/sem_ir/ids.h index 4cc843071e74..be9d5c912214 100644 --- a/toolchain/sem_ir/ids.h +++ b/toolchain/sem_ir/ids.h @@ -695,6 +695,56 @@ struct ElementIndex : public IndexBase, public Printable { } }; +// The ID of a library name. This is either a string literal or `default`. +struct LibraryNameId : public IdBase, public Printable { + using DiagnosticType = DiagnosticTypeInfo; + + // An explicitly invalid ID. + static const LibraryNameId Invalid; + // The name of `default`. + static const LibraryNameId Default; + // Track cases where the library name was set, but has been diagnosed and + // shouldn't be used anymore. + static const LibraryNameId Error; + + // Returns the LibraryNameId for a library name as a string literal. + static auto ForStringLiteralValueId(StringLiteralValueId id) + -> LibraryNameId { + CARBON_CHECK(id.index >= InvalidIndex) + << "Unexpected library name ID " << id; + if (id == StringLiteralValueId::Invalid) { + // Prior to SemIR, we use invalid to indicate `default`. + return LibraryNameId::Default; + } else { + return LibraryNameId(id.index); + } + } + + using IdBase::IdBase; + + // Converts a LibraryNameId back to a string literal. + auto AsStringLiteralValueId() const -> StringLiteralValueId { + CARBON_CHECK(index >= InvalidIndex) << *this << " must be handled directly"; + return StringLiteralValueId(index); + } + + auto Print(llvm::raw_ostream& out) const -> void { + out << "libraryName"; + if (*this == Default) { + out << "Default"; + } else if (*this == Error) { + out << ""; + } else { + IdBase::Print(out); + } + } +}; + +constexpr LibraryNameId LibraryNameId::Invalid = LibraryNameId(InvalidIndex); +constexpr LibraryNameId LibraryNameId::Default = + LibraryNameId(InvalidIndex - 1); +constexpr LibraryNameId LibraryNameId::Error = LibraryNameId(InvalidIndex - 2); + // The ID of an ImportIRInst. struct ImportIRInstId : public IdBase, public Printable { using ValueType = ImportIRInst;