diff options
| author | Ellie Hermaszewska <ellieh@nvidia.com> | 2025-07-08 10:36:52 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-08 02:36:52 +0000 |
| commit | 69947dec841ea46e68ccdccae45a1080fcaea01c (patch) | |
| tree | f8208b40d2baab7e914b396d04f08d30ffb63105 /source/slang/slang-serialize-source-loc.h | |
| parent | 3865a6596afca1c193eb17bbb74008077096e7c3 (diff) | |
Use fossil for IR serialization (#7619)
* bottleneck ir module reading and writing
* compute/simple working
* more complex tests working
* neaten
* factor out SourceLoc serialization
* document changes
* Appease clang
* Correct name serialization
* remove unnecessary code
* neaten
* neaten
Diffstat (limited to 'source/slang/slang-serialize-source-loc.h')
| -rw-r--r-- | source/slang/slang-serialize-source-loc.h | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/source/slang/slang-serialize-source-loc.h b/source/slang/slang-serialize-source-loc.h index c6ef982c1..ea2a06d96 100644 --- a/source/slang/slang-serialize-source-loc.h +++ b/source/slang/slang-serialize-source-loc.h @@ -8,6 +8,7 @@ #include "../core/slang-riff.h" #include "../core/slang-string-slice-pool.h" #include "slang-serialize-types.h" +#include "slang-serialize.h" namespace Slang { @@ -233,6 +234,81 @@ public: Dictionary<SourceFile*, RefPtr<Source>> m_sourceFileMap; }; +// A class a custom serialization context can inherit from to enable +// serializing SourceLoc +struct SourceLocSerialContext +{ + virtual SerialSourceLocReader* getSourceLocReader() { return nullptr; } + virtual SerialSourceLocWriter* getSourceLocWriter() { return nullptr; } +}; + +template<typename S> +void serialize(S const& serializer, SourceLoc& value) +{ + static_assert( + std::is_convertible_v<decltype(serializer.getContext()), SourceLocSerialContext*>, + "getContext() must return a SourceLocSerialContext*"); + + SourceLocSerialContext* context = serializer.getContext(); + + // Writing of source location information can be disabled by + // compiler options, and in that case the `_sourceLocWriter` + // may be null. + // + // In order to handle that possibility, we serialize a `SourceLoc` + // as an optional value, dependent on whether we have a + // `_sourceLocWriter` that can be used. + // + SLANG_SCOPED_SERIALIZER_OPTIONAL(serializer); + if (isWriting(serializer)) + { + // The `SourceLoc` type is implemented under the hood as an + // integer offset that can only be decoded using the specific + // `SourceManager` that created it. + // + // The source location writer handles the task of translating + // the under-the-hood representation to a single integer value + // (represented as `SerialSourceLocData::SourceLoc`) that can + // be decoded on the other side using other data that the + // source location writer will write out as part of its own + // representation (all of which goes into the dedicated debug + // data chunk, distinct from the AST/IR module). + // + if (const auto sourceLocWriter = context->getSourceLocWriter()) + { + SerialSourceLocData::SourceLoc rawValue = sourceLocWriter->addSourceLoc(value); + serialize(serializer, rawValue); + } + } + else + { + if (hasElements(serializer)) + { + SerialSourceLocData::SourceLoc rawValue; + serialize(serializer, rawValue); + + // Even if the serialized optional had a value, it is + // possible that the debug-data chunk got stripped from + // the compiled module file, in which case we wouldn't + // have access to the data needed to decode it. + // + // In that case, the `_sourceLocReader` member would be + // null, so we handle that possibility here. + // + if (const auto sourceLocReader = context->getSourceLocReader()) + { + value = sourceLocReader->getSourceLoc(rawValue); + } + } + } +} + +// Now that we've seen the relevant serialization logic, it is clear that +// a `SourceLoc` gets fossilized the same way that an optional wrapping +// an integer (of type `SerialSourceLocData::SourceLoc`) would. +// +SLANG_DECLARE_FOSSILIZED_AS(SourceLoc, std::optional<SerialSourceLocData::SourceLoc>); + } // namespace Slang #endif |
