1 | //===- offload-tblgen/RecordTypes.cpp - Offload record type wrappers -----===-// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #pragma once |
10 | |
11 | #include <string> |
12 | |
13 | #include "llvm/TableGen/Record.h" |
14 | |
15 | namespace llvm { |
16 | namespace offload { |
17 | namespace tblgen { |
18 | |
19 | class HandleRec { |
20 | public: |
21 | explicit HandleRec(const Record *rec) : rec(rec) {} |
22 | StringRef getName() const { return rec->getValueAsString(FieldName: "name" ); } |
23 | StringRef getDesc() const { return rec->getValueAsString(FieldName: "desc" ); } |
24 | |
25 | private: |
26 | const Record *rec; |
27 | }; |
28 | |
29 | class MacroRec { |
30 | public: |
31 | explicit MacroRec(const Record *rec) : rec(rec) { |
32 | auto Name = rec->getValueAsString(FieldName: "name" ); |
33 | auto OpenBrace = Name.find_first_of(Chars: "(" ); |
34 | nameWithoutArgs = Name.substr(Start: 0, N: OpenBrace); |
35 | } |
36 | StringRef getName() const { return nameWithoutArgs; } |
37 | StringRef getNameWithArgs() const { return rec->getValueAsString(FieldName: "name" ); } |
38 | StringRef getDesc() const { return rec->getValueAsString(FieldName: "desc" ); } |
39 | |
40 | std::optional<StringRef> getCondition() const { |
41 | return rec->getValueAsOptionalString(FieldName: "condition" ); |
42 | } |
43 | StringRef getValue() const { return rec->getValueAsString(FieldName: "value" ); } |
44 | std::optional<StringRef> getAltValue() const { |
45 | return rec->getValueAsOptionalString(FieldName: "alt_value" ); |
46 | } |
47 | |
48 | private: |
49 | const Record *rec; |
50 | std::string nameWithoutArgs; |
51 | }; |
52 | |
53 | class TypedefRec { |
54 | public: |
55 | explicit TypedefRec(const Record *rec) : rec(rec) {} |
56 | StringRef getName() const { return rec->getValueAsString(FieldName: "name" ); } |
57 | StringRef getDesc() const { return rec->getValueAsString(FieldName: "desc" ); } |
58 | StringRef getValue() const { return rec->getValueAsString(FieldName: "value" ); } |
59 | |
60 | private: |
61 | const Record *rec; |
62 | }; |
63 | |
64 | class EnumValueRec { |
65 | public: |
66 | explicit EnumValueRec(const Record *rec) : rec(rec) {} |
67 | std::string getName() const { return rec->getValueAsString(FieldName: "name" ).upper(); } |
68 | StringRef getDesc() const { return rec->getValueAsString(FieldName: "desc" ); } |
69 | StringRef getTaggedType() const { |
70 | return rec->getValueAsString(FieldName: "tagged_type" ); |
71 | } |
72 | |
73 | private: |
74 | const Record *rec; |
75 | }; |
76 | |
77 | class EnumRec { |
78 | public: |
79 | explicit EnumRec(const Record *rec) : rec(rec) { |
80 | for (const auto *Val : rec->getValueAsListOfDefs(FieldName: "etors" )) { |
81 | vals.emplace_back(args: EnumValueRec{Val}); |
82 | } |
83 | } |
84 | StringRef getName() const { return rec->getValueAsString(FieldName: "name" ); } |
85 | StringRef getDesc() const { return rec->getValueAsString(FieldName: "desc" ); } |
86 | const std::vector<EnumValueRec> &getValues() const { return vals; } |
87 | |
88 | std::string getEnumValNamePrefix() const { |
89 | return StringRef(getName().str().substr(pos: 0, n: getName().str().length() - 2)) |
90 | .upper(); |
91 | } |
92 | |
93 | bool isTyped() const { return rec->getValueAsBit(FieldName: "is_typed" ); } |
94 | |
95 | private: |
96 | const Record *rec; |
97 | std::vector<EnumValueRec> vals; |
98 | }; |
99 | |
100 | class StructMemberRec { |
101 | public: |
102 | explicit StructMemberRec(const Record *rec) : rec(rec) {} |
103 | StringRef getType() const { return rec->getValueAsString(FieldName: "type" ); } |
104 | StringRef getName() const { return rec->getValueAsString(FieldName: "name" ); } |
105 | StringRef getDesc() const { return rec->getValueAsString(FieldName: "desc" ); } |
106 | bool isPointerType() const { return getType().ends_with(Suffix: '*'); } |
107 | bool isHandleType() const { return getType().ends_with(Suffix: "_handle_t" ); } |
108 | |
109 | private: |
110 | const Record *rec; |
111 | }; |
112 | |
113 | class StructRec { |
114 | public: |
115 | explicit StructRec(const Record *rec) : rec(rec) { |
116 | for (auto *Member : rec->getValueAsListOfDefs(FieldName: "all_members" )) { |
117 | members.emplace_back(args: StructMemberRec(Member)); |
118 | } |
119 | } |
120 | StringRef getName() const { return rec->getValueAsString(FieldName: "name" ); } |
121 | StringRef getDesc() const { return rec->getValueAsString(FieldName: "desc" ); } |
122 | std::optional<StringRef> getBaseClass() const { |
123 | return rec->getValueAsOptionalString(FieldName: "base_class" ); |
124 | } |
125 | const std::vector<StructMemberRec> &getMembers() const { return members; } |
126 | |
127 | private: |
128 | const Record *rec; |
129 | std::vector<StructMemberRec> members; |
130 | }; |
131 | |
132 | class ParamRec { |
133 | public: |
134 | explicit ParamRec(const Record *rec) : rec(rec) { |
135 | flags = rec->getValueAsBitsInit(FieldName: "flags" ); |
136 | auto *Range = rec->getValueAsDef(FieldName: "range" ); |
137 | auto RangeBegin = Range->getValueAsString(FieldName: "begin" ); |
138 | auto RangeEnd = Range->getValueAsString(FieldName: "end" ); |
139 | if (RangeBegin != "" && RangeEnd != "" ) { |
140 | range = {RangeBegin, RangeEnd}; |
141 | } else { |
142 | range = std::nullopt; |
143 | } |
144 | |
145 | auto *TypeInfo = rec->getValueAsDef(FieldName: "type_info" ); |
146 | auto TypeInfoEnum = TypeInfo->getValueAsString(FieldName: "enum" ); |
147 | auto TypeInfoSize = TypeInfo->getValueAsString(FieldName: "size" ); |
148 | if (TypeInfoEnum != "" && TypeInfoSize != "" ) { |
149 | typeinfo = {TypeInfoEnum, TypeInfoSize}; |
150 | } else { |
151 | typeinfo = std::nullopt; |
152 | } |
153 | } |
154 | StringRef getName() const { return rec->getValueAsString(FieldName: "name" ); } |
155 | StringRef getType() const { return rec->getValueAsString(FieldName: "type" ); } |
156 | bool isPointerType() const { return getType().ends_with(Suffix: '*'); } |
157 | bool isHandleType() const { return getType().ends_with(Suffix: "_handle_t" ); } |
158 | bool isFptrType() const { return getType().ends_with(Suffix: "_cb_t" ); } |
159 | StringRef getDesc() const { return rec->getValueAsString(FieldName: "desc" ); } |
160 | bool isIn() const { return dyn_cast<BitInit>(Val: flags->getBit(Bit: 0))->getValue(); } |
161 | bool isOut() const { return dyn_cast<BitInit>(Val: flags->getBit(Bit: 1))->getValue(); } |
162 | bool isOpt() const { return dyn_cast<BitInit>(Val: flags->getBit(Bit: 2))->getValue(); } |
163 | |
164 | const Record *getRec() const { return rec; } |
165 | std::optional<std::pair<StringRef, StringRef>> getRange() const { |
166 | return range; |
167 | } |
168 | |
169 | std::optional<std::pair<StringRef, StringRef>> getTypeInfo() const { |
170 | return typeinfo; |
171 | } |
172 | |
173 | // Needed to check whether we're at the back of a vector of params |
174 | bool operator!=(const ParamRec &p) const { return rec != p.getRec(); } |
175 | |
176 | private: |
177 | const Record *rec; |
178 | const BitsInit *flags; |
179 | std::optional<std::pair<StringRef, StringRef>> range; |
180 | std::optional<std::pair<StringRef, StringRef>> typeinfo; |
181 | }; |
182 | |
183 | class ReturnRec { |
184 | public: |
185 | ReturnRec(const Record *rec) : rec(rec) {} |
186 | StringRef getValue() const { return rec->getValueAsString(FieldName: "value" ); } |
187 | // Strip the "OL_ERRC_" from the value, resulting in just "FOO" from |
188 | // "OL_ERRC_FOO" |
189 | StringRef getUnprefixedValue() const { |
190 | constexpr const char *ERRC = "ERRC_" ; |
191 | auto Start = getValue().find(Str: ERRC) + strlen(s: ERRC); |
192 | return getValue().substr(Start); |
193 | } |
194 | std::vector<StringRef> getConditions() const { |
195 | return rec->getValueAsListOfStrings(FieldName: "conditions" ); |
196 | } |
197 | |
198 | private: |
199 | const Record *rec; |
200 | }; |
201 | |
202 | class FunctionRec { |
203 | public: |
204 | FunctionRec(const Record *rec) : rec(rec) { |
205 | for (auto &Ret : rec->getValueAsListOfDefs(FieldName: "all_returns" )) |
206 | rets.emplace_back(args&: Ret); |
207 | for (auto &Param : rec->getValueAsListOfDefs(FieldName: "params" )) |
208 | params.emplace_back(args&: Param); |
209 | } |
210 | |
211 | std::string getParamStructName() const { |
212 | return llvm::formatv(Fmt: "{0}_params_t" , |
213 | Vals: llvm::convertToSnakeFromCamelCase(input: getName())); |
214 | } |
215 | |
216 | StringRef getName() const { return rec->getValueAsString(FieldName: "name" ); } |
217 | StringRef getClass() const { return rec->getValueAsString(FieldName: "api_class" ); } |
218 | const std::vector<ReturnRec> &getReturns() const { return rets; } |
219 | const std::vector<ParamRec> &getParams() const { return params; } |
220 | StringRef getDesc() const { return rec->getValueAsString(FieldName: "desc" ); } |
221 | std::vector<StringRef> getDetails() const { |
222 | return rec->getValueAsListOfStrings(FieldName: "details" ); |
223 | } |
224 | std::vector<StringRef> getAnalogues() const { |
225 | return rec->getValueAsListOfStrings(FieldName: "analogues" ); |
226 | } |
227 | |
228 | private: |
229 | std::vector<ReturnRec> rets; |
230 | std::vector<ParamRec> params; |
231 | |
232 | const Record *rec; |
233 | }; |
234 | |
235 | class FptrTypedefRec { |
236 | public: |
237 | explicit FptrTypedefRec(const Record *rec) : rec(rec) { |
238 | for (auto &Param : rec->getValueAsListOfDefs(FieldName: "params" )) |
239 | params.emplace_back(args&: Param); |
240 | } |
241 | StringRef getName() const { return rec->getValueAsString(FieldName: "name" ); } |
242 | StringRef getDesc() const { return rec->getValueAsString(FieldName: "desc" ); } |
243 | StringRef getReturn() const { return rec->getValueAsString(FieldName: "return" ); } |
244 | const std::vector<ParamRec> &getParams() const { return params; } |
245 | |
246 | private: |
247 | std::vector<ParamRec> params; |
248 | |
249 | const Record *rec; |
250 | }; |
251 | |
252 | } // namespace tblgen |
253 | } // namespace offload |
254 | } // namespace llvm |
255 | |