| 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 | |