|
|
@@ -84,6 +84,29 @@ struct StringId : public IndexBase, public Printable<StringId> {
|
|
|
};
|
|
|
constexpr StringId StringId::Invalid(StringId::InvalidIndex);
|
|
|
|
|
|
+// Adapts StringId for identifiers.
|
|
|
+struct IdentifierId : public IndexBase, public Printable<IdentifierId> {
|
|
|
+ static const IdentifierId Invalid;
|
|
|
+ using IndexBase::IndexBase;
|
|
|
+ auto Print(llvm::raw_ostream& out) const -> void {
|
|
|
+ out << "strId";
|
|
|
+ IndexBase::Print(out);
|
|
|
+ }
|
|
|
+};
|
|
|
+constexpr IdentifierId IdentifierId::Invalid(IdentifierId::InvalidIndex);
|
|
|
+
|
|
|
+// Adapts StringId for string literals.
|
|
|
+struct StringLiteralId : public IndexBase, public Printable<StringLiteralId> {
|
|
|
+ static const StringLiteralId Invalid;
|
|
|
+ using IndexBase::IndexBase;
|
|
|
+ auto Print(llvm::raw_ostream& out) const -> void {
|
|
|
+ out << "strLit";
|
|
|
+ IndexBase::Print(out);
|
|
|
+ }
|
|
|
+};
|
|
|
+constexpr StringLiteralId StringLiteralId::Invalid(
|
|
|
+ StringLiteralId::InvalidIndex);
|
|
|
+
|
|
|
namespace Internal {
|
|
|
// Used as a parent class for non-printable types. This is just for
|
|
|
// std::conditional, not as an API.
|
|
|
@@ -98,9 +121,6 @@ class ValueStore
|
|
|
Yaml::Printable<ValueStore<IdT, ValueT>>,
|
|
|
Internal::ValueStoreNotPrintable> {
|
|
|
public:
|
|
|
- using PrintFn =
|
|
|
- llvm::function_ref<void(llvm::raw_ostream&, const ValueT& val)>;
|
|
|
-
|
|
|
// Stores the value and returns an ID to reference it.
|
|
|
auto Add(ValueT value) -> IdT {
|
|
|
IdT id = IdT(values_.size());
|
|
|
@@ -153,9 +173,6 @@ class ValueStore
|
|
|
template <>
|
|
|
class ValueStore<StringId> : public Yaml::Printable<ValueStore<StringId>> {
|
|
|
public:
|
|
|
- using PrintFn =
|
|
|
- llvm::function_ref<void(llvm::raw_ostream&, const llvm::StringRef& val)>;
|
|
|
-
|
|
|
// Returns an ID to reference the value. May return an existing ID if the
|
|
|
// string was previously added.
|
|
|
auto Add(llvm::StringRef value) -> StringId {
|
|
|
@@ -186,16 +203,55 @@ class ValueStore<StringId> : public Yaml::Printable<ValueStore<StringId>> {
|
|
|
llvm::SmallVector<llvm::StringRef> values_;
|
|
|
};
|
|
|
|
|
|
+// A thin wrapper around a `ValueStore<StringId>` that provides a different IdT,
|
|
|
+// while using a unified storage for values. This avoids potentially
|
|
|
+// duplicative string hash maps, which are expensive.
|
|
|
+template <typename IdT>
|
|
|
+class StringStoreWrapper : public Printable<StringStoreWrapper<IdT>> {
|
|
|
+ public:
|
|
|
+ explicit StringStoreWrapper(ValueStore<StringId>* values) : values_(values) {}
|
|
|
+
|
|
|
+ auto Add(llvm::StringRef value) -> IdT {
|
|
|
+ return IdT(values_->Add(value).index);
|
|
|
+ }
|
|
|
+
|
|
|
+ auto Get(IdT id) const -> llvm::StringRef {
|
|
|
+ return values_->Get(StringId(id.index));
|
|
|
+ }
|
|
|
+
|
|
|
+ auto Print(llvm::raw_ostream& out) const -> void { out << *values_; }
|
|
|
+
|
|
|
+ private:
|
|
|
+ ValueStore<StringId>* values_;
|
|
|
+};
|
|
|
+
|
|
|
// Stores that will be used across compiler phases for a given compilation unit.
|
|
|
// This is provided mainly so that they don't need to be passed separately.
|
|
|
class SharedValueStores : public Yaml::Printable<SharedValueStores> {
|
|
|
public:
|
|
|
+ explicit SharedValueStores()
|
|
|
+ : identifiers_(&strings_), string_literals_(&strings_) {}
|
|
|
+
|
|
|
+ // Not copyable or movable.
|
|
|
+ SharedValueStores(const SharedValueStores&) = delete;
|
|
|
+ auto operator=(const SharedValueStores&) -> SharedValueStores& = delete;
|
|
|
+
|
|
|
+ auto identifiers() -> StringStoreWrapper<IdentifierId>& {
|
|
|
+ return identifiers_;
|
|
|
+ }
|
|
|
+ auto identifiers() const -> const StringStoreWrapper<IdentifierId>& {
|
|
|
+ return identifiers_;
|
|
|
+ }
|
|
|
auto integers() -> ValueStore<IntegerId>& { return integers_; }
|
|
|
auto integers() const -> const ValueStore<IntegerId>& { return integers_; }
|
|
|
auto reals() -> ValueStore<RealId>& { return reals_; }
|
|
|
auto reals() const -> const ValueStore<RealId>& { return reals_; }
|
|
|
- auto strings() -> ValueStore<StringId>& { return strings_; }
|
|
|
- auto strings() const -> const ValueStore<StringId>& { return strings_; }
|
|
|
+ auto string_literals() -> StringStoreWrapper<StringLiteralId>& {
|
|
|
+ return string_literals_;
|
|
|
+ }
|
|
|
+ auto string_literals() const -> const StringStoreWrapper<StringLiteralId>& {
|
|
|
+ return string_literals_;
|
|
|
+ }
|
|
|
|
|
|
auto OutputYaml(std::optional<llvm::StringRef> filename = std::nullopt) const
|
|
|
-> Yaml::OutputMapping {
|
|
|
@@ -215,11 +271,19 @@ class SharedValueStores : public Yaml::Printable<SharedValueStores> {
|
|
|
private:
|
|
|
ValueStore<IntegerId> integers_;
|
|
|
ValueStore<RealId> reals_;
|
|
|
+
|
|
|
ValueStore<StringId> strings_;
|
|
|
+ StringStoreWrapper<IdentifierId> identifiers_;
|
|
|
+ StringStoreWrapper<StringLiteralId> string_literals_;
|
|
|
};
|
|
|
|
|
|
} // namespace Carbon
|
|
|
|
|
|
+// Support use of IdentifierId as DenseMap/DenseSet keys.
|
|
|
+// TODO: Remove once NameId is used in checking.
|
|
|
+template <>
|
|
|
+struct llvm::DenseMapInfo<Carbon::IdentifierId>
|
|
|
+ : public Carbon::IndexMapInfo<Carbon::IdentifierId> {};
|
|
|
// Support use of StringId as DenseMap/DenseSet keys.
|
|
|
template <>
|
|
|
struct llvm::DenseMapInfo<Carbon::StringId>
|