// SPDX-License-Identifier: GPL-3.0-or-later #ifndef RCC_CODEGEN_MACHINEDEBUGINFO_H #define RCC_CODEGEN_MACHINEDEBUGINFO_H #include "rcc/CodeGen/MachineMetadata.h" #include "rcc/Support/Error.h" #include #include #include #include #include #include namespace rcc { class MachineDIExpression final { public: MachineDIExpression() = default; explicit MachineDIExpression(std::vector Elements) : Elements(std::move(Elements)) {} [[nodiscard]] std::span elements() const noexcept { return Elements; } friend bool operator==(const MachineDIExpression &Left, const MachineDIExpression &Right) = default; private: std::vector Elements; }; class MachineMetadataValue final { public: MachineMetadataValue() = default; [[nodiscard]] static Expected reference(MachineMetadataReference Reference); [[nodiscard]] static MachineMetadataValue expression(MachineDIExpression Expression); [[nodiscard]] bool isValid() const noexcept { return !std::holds_alternative(Storage); } [[nodiscard]] const MachineMetadataReference *reference() const noexcept { return std::get_if(&Storage); } [[nodiscard]] const MachineDIExpression *expression() const noexcept { return std::get_if(&Storage); } [[nodiscard]] Expected verify(const MachineMetadataInfo &Metadata) const; friend bool operator==(const MachineMetadataValue &Left, const MachineMetadataValue &Right) = default; private: explicit MachineMetadataValue(MachineMetadataReference Reference) : Storage(Reference) {} explicit MachineMetadataValue(MachineDIExpression Expression) : Storage(std::move(Expression)) {} std::variant Storage; }; struct MachineDILocationFrame final { std::uint32_t Line = 0; std::uint16_t Column = 0; MachineMetadataReference Scope; bool IsImplicitCode = false; std::uint64_t AtomGroup = 0; std::uint8_t AtomRank = 0; friend constexpr bool operator==(MachineDILocationFrame Left, MachineDILocationFrame Right) noexcept = default; }; class MachineDILocation final { public: static constexpr std::uint64_t MaxAtomGroup = (std::uint64_t{1} << 61) - 1; [[nodiscard]] static Expected create(std::vector InlineChain, std::optional TerminalInlinedAt = std::nullopt); [[nodiscard]] std::span inlineChain() const noexcept { return InlineChain; } [[nodiscard]] std::optional terminalInlinedAt() const noexcept { return TerminalInlinedAt; } [[nodiscard]] Expected verify(const MachineMetadataInfo &Metadata) const; friend bool operator==(const MachineDILocation &Left, const MachineDILocation &Right) = default; private: MachineDILocation(std::vector InlineChain, std::optional TerminalInlinedAt) : InlineChain(std::move(InlineChain)), TerminalInlinedAt(TerminalInlinedAt) {} [[nodiscard]] Expected verifyStructure() const; std::vector InlineChain; std::optional TerminalInlinedAt; }; class MachineDebugLocation final { public: MachineDebugLocation() = default; [[nodiscard]] static Expected reference(MachineMetadataReference Reference); [[nodiscard]] static MachineDebugLocation inlineLocation(MachineDILocation Location); [[nodiscard]] bool isValid() const noexcept { return !std::holds_alternative(Storage); } [[nodiscard]] const MachineMetadataReference *reference() const noexcept { return std::get_if(&Storage); } [[nodiscard]] const MachineDILocation *inlineLocation() const noexcept { return std::get_if(&Storage); } [[nodiscard]] Expected verify(const MachineMetadataInfo &Metadata) const; friend bool operator==(const MachineDebugLocation &Left, const MachineDebugLocation &Right) = default; private: explicit MachineDebugLocation(MachineMetadataReference Reference) : Storage(Reference) {} explicit MachineDebugLocation(MachineDILocation Location) : Storage(std::move(Location)) {} std::variant Storage; }; struct MachineVariableDebugInfo final { std::optional Variable; std::optional Expression; std::optional Location; [[nodiscard]] Expected verifyStructure() const; [[nodiscard]] Expected verify(const MachineMetadataInfo &Metadata) const; friend bool operator==(const MachineVariableDebugInfo &Left, const MachineVariableDebugInfo &Right) = default; }; } // namespace rcc #endif // RCC_CODEGEN_MACHINEDEBUGINFO_H