Factor library names into their own ID structure. (#4219)

This supports distinguishing between unset, Default, and "incorrect but
already diagnosed, do not use" for `extern library` logic.
This commit is contained in:
Jon Ross-Perkins
2024-08-16 23:46:38 +00:00
committed by GitHub
parent 696668ccb0
commit 64204d9182
6 changed files with 63 additions and 10 deletions
+2 -1
View File
@@ -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());
+1 -1
View File
@@ -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),
+4 -4
View File
@@ -34,8 +34,8 @@ class File : public Printable<File> {
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<File> {
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<IdentifierId>& {
@@ -181,7 +181,7 @@ class File : public Printable<File> {
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_;
+5 -3
View File
@@ -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());
}
}
+1 -1
View File
@@ -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
+50
View File
@@ -695,6 +695,56 @@ struct ElementIndex : public IndexBase, public Printable<ElementIndex> {
}
};
// The ID of a library name. This is either a string literal or `default`.
struct LibraryNameId : public IdBase, public Printable<NameId> {
using DiagnosticType = DiagnosticTypeInfo<std::string>;
// 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 << "<error>";
} 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<ImportIRInstId> {
using ValueType = ImportIRInst;