aboutsummaryrefslogtreecommitdiff
path: root/backend/include/rcc/CodeGen/MachineDebugInfo.h
blob: 0d95e9663efda1542a93bfd26145f0fd62eefd90 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// 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 <cstdint>
#include <optional>
#include <span>
#include <utility>
#include <variant>
#include <vector>

namespace rcc {

class MachineDIExpression final {
public:
  MachineDIExpression() = default;
  explicit MachineDIExpression(std::vector<std::uint64_t> Elements)
      : Elements(std::move(Elements)) {}

  [[nodiscard]] std::span<const std::uint64_t> elements() const noexcept {
    return Elements;
  }

  friend bool operator==(const MachineDIExpression &Left,
                         const MachineDIExpression &Right) = default;

private:
  std::vector<std::uint64_t> Elements;
};

class MachineMetadataValue final {
public:
  MachineMetadataValue() = default;

  [[nodiscard]] static Expected<MachineMetadataValue> reference(MachineMetadataReference Reference);
  [[nodiscard]] static MachineMetadataValue expression(MachineDIExpression Expression);

  [[nodiscard]] bool isValid() const noexcept {
    return !std::holds_alternative<std::monostate>(Storage);
  }

  [[nodiscard]] const MachineMetadataReference *reference() const noexcept {
    return std::get_if<MachineMetadataReference>(&Storage);
  }

  [[nodiscard]] const MachineDIExpression *expression() const noexcept {
    return std::get_if<MachineDIExpression>(&Storage);
  }

  [[nodiscard]] Expected<void> 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<std::monostate, MachineMetadataReference, MachineDIExpression> 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<MachineDILocation>
  create(std::vector<MachineDILocationFrame> InlineChain,
         std::optional<MachineMetadataReference> TerminalInlinedAt = std::nullopt);

  [[nodiscard]] std::span<const MachineDILocationFrame> inlineChain() const noexcept {
    return InlineChain;
  }

  [[nodiscard]] std::optional<MachineMetadataReference> terminalInlinedAt() const noexcept {
    return TerminalInlinedAt;
  }

  [[nodiscard]] Expected<void> verify(const MachineMetadataInfo &Metadata) const;

  friend bool operator==(const MachineDILocation &Left, const MachineDILocation &Right) = default;

private:
  MachineDILocation(std::vector<MachineDILocationFrame> InlineChain,
                    std::optional<MachineMetadataReference> TerminalInlinedAt)
      : InlineChain(std::move(InlineChain)), TerminalInlinedAt(TerminalInlinedAt) {}

  [[nodiscard]] Expected<void> verifyStructure() const;

  std::vector<MachineDILocationFrame> InlineChain;
  std::optional<MachineMetadataReference> TerminalInlinedAt;
};

class MachineDebugLocation final {
public:
  MachineDebugLocation() = default;

  [[nodiscard]] static Expected<MachineDebugLocation> reference(MachineMetadataReference Reference);
  [[nodiscard]] static MachineDebugLocation inlineLocation(MachineDILocation Location);

  [[nodiscard]] bool isValid() const noexcept {
    return !std::holds_alternative<std::monostate>(Storage);
  }

  [[nodiscard]] const MachineMetadataReference *reference() const noexcept {
    return std::get_if<MachineMetadataReference>(&Storage);
  }

  [[nodiscard]] const MachineDILocation *inlineLocation() const noexcept {
    return std::get_if<MachineDILocation>(&Storage);
  }

  [[nodiscard]] Expected<void> 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<std::monostate, MachineMetadataReference, MachineDILocation> Storage;
};

struct MachineVariableDebugInfo final {
  std::optional<MachineMetadataReference> Variable;
  std::optional<MachineMetadataValue> Expression;
  std::optional<MachineDebugLocation> Location;

  [[nodiscard]] Expected<void> verifyStructure() const;
  [[nodiscard]] Expected<void> verify(const MachineMetadataInfo &Metadata) const;

  friend bool operator==(const MachineVariableDebugInfo &Left,
                         const MachineVariableDebugInfo &Right) = default;
};

} // namespace rcc

#endif // RCC_CODEGEN_MACHINEDEBUGINFO_H