From 77d76b73a614820bf45024b053db376f35b06d10 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Sat, 1 Aug 2026 17:10:33 +0800 Subject: [MIR] Add compilation unit reference context --- backend/include/rcc/MIR/EmbeddedIR.h | 175 +++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 backend/include/rcc/MIR/EmbeddedIR.h (limited to 'backend/include/rcc/MIR/EmbeddedIR.h') diff --git a/backend/include/rcc/MIR/EmbeddedIR.h b/backend/include/rcc/MIR/EmbeddedIR.h new file mode 100644 index 0000000..8e9e0f6 --- /dev/null +++ b/backend/include/rcc/MIR/EmbeddedIR.h @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef RCC_MIR_EMBEDDEDIR_H +#define RCC_MIR_EMBEDDEDIR_H + +#include "rcc/Support/TextDiagnostic.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rcc::mir { + +class EmbeddedIRIndexer; + +struct EmbeddedIRReference final { + std::string Name; + TextRange Range; +}; + +class EmbeddedIRFunction final { +public: + [[nodiscard]] std::string_view name() const noexcept { + return Name; + } + + [[nodiscard]] const TextRange &nameRange() const noexcept { + return NameRange; + } + + [[nodiscard]] bool isDefinition() const noexcept { + return IsDefinition; + } + + [[nodiscard]] std::span blocks() const noexcept { + return Blocks; + } + + [[nodiscard]] std::span allocas() const noexcept { + return Allocas; + } + + [[nodiscard]] const EmbeddedIRReference *block(std::string_view QueryName) const noexcept; + [[nodiscard]] const EmbeddedIRReference *alloca(std::string_view QueryName) const noexcept; + +private: + struct StringHash final { + using is_transparent = void; // NOLINT(readability-identifier-naming) + + [[nodiscard]] std::size_t operator()(std::string_view Value) const noexcept { + return std::hash{}(Value); + } + }; + + std::string Name; + TextRange NameRange; + bool IsDefinition = false; + std::vector Blocks; + std::vector Allocas; + std::unordered_map> BlockNameToIndex; + std::unordered_map> AllocaNameToIndex; + + friend class EmbeddedIRIndexer; +}; + +class EmbeddedIRReferenceIndex final { +public: + EmbeddedIRReferenceIndex(const EmbeddedIRReferenceIndex &) = delete; + EmbeddedIRReferenceIndex &operator=(const EmbeddedIRReferenceIndex &) = delete; + EmbeddedIRReferenceIndex(EmbeddedIRReferenceIndex &&) noexcept = default; + EmbeddedIRReferenceIndex &operator=(EmbeddedIRReferenceIndex &&) noexcept = default; + ~EmbeddedIRReferenceIndex() = default; + + [[nodiscard]] const TextSource &source() const noexcept { + return Source; + } + + [[nodiscard]] std::optional targetTriple() const noexcept { + if (!TargetTriple) + return std::nullopt; + return *TargetTriple; + } + + [[nodiscard]] std::optional dataLayout() const noexcept { + if (!DataLayout) + return std::nullopt; + return *DataLayout; + } + + [[nodiscard]] std::span functions() const noexcept { + return Functions; + } + + [[nodiscard]] std::span globalObjects() const noexcept { + return GlobalObjects; + } + + [[nodiscard]] std::span metadataDefinitions() const noexcept { + return MetadataDefinitions; + } + + [[nodiscard]] const EmbeddedIRFunction *function(std::string_view Name) const noexcept; + [[nodiscard]] const EmbeddedIRReference *globalObject(std::string_view Name) const noexcept; + [[nodiscard]] const EmbeddedIRReference *metadata(std::string_view Name) const noexcept; + [[nodiscard]] bool hasGlobalValue(std::string_view Name) const noexcept { + return function(Name) != nullptr || globalObject(Name) != nullptr; + } + +private: + struct StringHash final { + using is_transparent = void; // NOLINT(readability-identifier-naming) + + [[nodiscard]] std::size_t operator()(std::string_view Value) const noexcept { + return std::hash{}(Value); + } + }; + + EmbeddedIRReferenceIndex(std::string SourceName, std::string SourceText) + : Source(std::move(SourceName), std::move(SourceText)) {} + + TextSource Source; + std::optional TargetTriple; + std::optional TargetTripleRange; + std::optional DataLayout; + std::optional DataLayoutRange; + std::vector Functions; + std::vector GlobalObjects; + std::vector MetadataDefinitions; + std::unordered_map> FunctionNameToIndex; + std::unordered_map> GlobalNameToIndex; + std::unordered_map> MetadataNameToIndex; + + friend class EmbeddedIRIndexer; +}; + +class EmbeddedIRIndexResult final { +public: + EmbeddedIRIndexResult(const EmbeddedIRIndexResult &) = delete; + EmbeddedIRIndexResult &operator=(const EmbeddedIRIndexResult &) = delete; + EmbeddedIRIndexResult(EmbeddedIRIndexResult &&) noexcept = default; + EmbeddedIRIndexResult &operator=(EmbeddedIRIndexResult &&) noexcept = default; + ~EmbeddedIRIndexResult() = default; + + [[nodiscard]] bool succeeded() const noexcept { + return Index.has_value() && Diagnostics.empty(); + } + + [[nodiscard]] const EmbeddedIRReferenceIndex *index() const noexcept { + return Index.has_value() ? Index.operator->() : nullptr; + } + + [[nodiscard]] std::span diagnostics() const noexcept { + return Diagnostics; + } + +private: + EmbeddedIRIndexResult() = default; + + std::optional Index; + std::vector Diagnostics; + + friend class EmbeddedIRIndexer; +}; + +[[nodiscard]] EmbeddedIRIndexResult indexEmbeddedIR(std::string SourceName, std::string SourceText); + +} // namespace rcc::mir + +#endif // RCC_MIR_EMBEDDEDIR_H -- cgit v1.2.3