mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-06 07:54:41 +01:00
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:
@@ -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());
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user