| 15 | }; |
| 16 | |
| 17 | void OpDefEmitter::emit() { |
| 18 | auto className = op.getCppClassName(); |
| 19 | os << formatv( |
| 20 | "py::class_<{0}, std::shared_ptr<{0}>, OpDef> {0}Inst(m, \"{0}\");\n\n", |
| 21 | className); |
| 22 | for (auto&& i : op.getMgbAttributes()) { |
| 23 | if (auto attr = llvm::dyn_cast<MgbEnumAttr>(&i.attr)) { |
| 24 | unsigned int enumID; |
| 25 | if (auto alias = llvm::dyn_cast<MgbAliasAttr>(attr)) { |
| 26 | auto&& aliasBase = alias->getAliasBase(); |
| 27 | enumID = llvm::cast<MgbEnumAttr>(aliasBase).getBaseRecord()->getID(); |
| 28 | } else { |
| 29 | enumID = attr->getBaseRecord()->getID(); |
| 30 | } |
| 31 | auto&& enumAlias = env().enumAlias; |
| 32 | auto&& iter = enumAlias.find(enumID); |
| 33 | if (iter == enumAlias.end()) { |
| 34 | os << formatv( |
| 35 | "py::enum_<{0}::{1}>({0}Inst, \"{1}\")", className, |
| 36 | attr->getEnumName()); |
| 37 | std::vector<std::string> body; |
| 38 | for (auto&& i : attr->getEnumMembers()) { |
| 39 | size_t d1 = i.find(' '); |
| 40 | size_t d2 = i.find('='); |
| 41 | size_t d = d1 <= d2 ? d1 : d2; |
| 42 | os << formatv( |
| 43 | "\n .value(\"{2}\", {0}::{1}::{2})", className, |
| 44 | attr->getEnumName(), i.substr(0, d)); |
| 45 | body.push_back( |
| 46 | formatv("if (str == \"{2}\") return {0}::{1}::{2};", |
| 47 | className, attr->getEnumName(), i.substr(0, d))); |
| 48 | } |
| 49 | if (attr->getEnumCombinedFlag()) { |
| 50 | //! define operator | |
| 51 | os << formatv( |
| 52 | "\n .def(\"__or__\", []({0}::{1} s0, {0}::{1} s1) {{ " |
| 53 | "\n return static_cast<{0}::{1}>(uint32_t(s0) | " |
| 54 | "uint32_t(s1));" |
| 55 | "\n })", |
| 56 | className, attr->getEnumName()); |
| 57 | //! define operator & |
| 58 | os << formatv( |
| 59 | "\n .def(\"__and__\", []({0}::{1} s0, {0}::{1} s1) {{" |
| 60 | "\n return static_cast<{0}::{1}>(uint32_t(s0) & " |
| 61 | "uint32_t(s1));" |
| 62 | "\n })", |
| 63 | className, attr->getEnumName()); |
| 64 | } |
| 65 | os << formatv( |
| 66 | "\n .def(py::init([](const std::string& in) {" |
| 67 | "\n auto&& str = normalize_enum(in);" |
| 68 | "\n {0}" |
| 69 | "\n throw py::cast_error(\"invalid enum value \" + in);" |
| 70 | "\n }));\n", |
| 71 | llvm::join(body, "\n ")); |
| 72 | os << formatv( |
| 73 | "py::implicitly_convertible<std::string, {0}::{1}>();\n\n", |
| 74 | className, attr->getEnumName()); |
no test coverage detected