1313#include " mlir-c/BuiltinTypes.h"
1414#include " mlir-c/IR.h"
1515#include " mlir/Bindings/Python/NanobindAdaptors.h"
16+ #include " mlir/Bindings/Python/NanobindUtils.h"
1617#include < nanobind/nanobind.h>
1718#include < nanobind/stl/variant.h>
1819#include < nanobind/stl/vector.h>
@@ -29,6 +30,16 @@ struct Object;
2930struct BasePath ;
3031struct Path ;
3132
33+ // / Represents a value that is not known because it is an unsupplied input, or
34+ // / derived from unsupplied inputs.
35+ struct Unknown {
36+ Unknown (MlirType type) : type(type) {}
37+ MlirType getType () const { return type; }
38+
39+ private:
40+ MlirType type;
41+ };
42+
3243// / These are the Python types that are represented by the different primitive
3344// / OMEvaluatorValues as Attributes.
3445using PythonPrimitive = std::variant<nb::int_, nb::float_, nb::str, nb::bool_,
@@ -41,7 +52,7 @@ using PythonPrimitive = std::variant<nb::int_, nb::float_, nb::str, nb::bool_,
4152// / is tried first, then we can hit an assert inside the MLIR codebase.
4253struct None {};
4354using PythonValue =
44- std::variant<None, Object, List, BasePath, Path, PythonPrimitive>;
55+ std::variant<None, Object, List, BasePath, Path, Unknown, PythonPrimitive>;
4556
4657// / Map an opaque OMEvaluatorValue into a python value.
4758PythonValue omEvaluatorValueToPythonValue (OMEvaluatorValue result);
@@ -362,6 +373,9 @@ PythonValue omEvaluatorValueToPythonValue(OMEvaluatorValue result) {
362373 if (omEvaluatorValueIsAPath (result))
363374 return Path (result);
364375
376+ if (omEvaluatorValueIsUnknown (result))
377+ return Unknown (omEvaluatorValueGetType (result));
378+
365379 if (omEvaluatorValueIsAReference (result))
366380 return omEvaluatorValueToPythonValue (
367381 omEvaluatorValueGetReferenceValue (result));
@@ -385,6 +399,9 @@ OMEvaluatorValue pythonValueToOMEvaluatorValue(PythonValue result,
385399 if (auto *object = std::get_if<Object>(&result))
386400 return object->getValue ();
387401
402+ if (auto *unknown = std::get_if<Unknown>(&result))
403+ return omEvaluatorUnknownGet (ctx, unknown->getType ());
404+
388405 auto primitive = std::get<PythonPrimitive>(result);
389406 return omEvaluatorValueFromPrimitive (
390407 omPythonValueToPrimitive (primitive, ctx));
@@ -421,6 +438,19 @@ void circt::python::populateDialectOMSubmodule(nb::module_ &m) {
421438 .def (nb::init<Path>(), nb::arg (" path" ))
422439 .def (" __str__" , &Path::dunderStr);
423440
441+ // Add the Unknown sentinel class definition.
442+ nb::class_<Unknown>(m, " Unknown" )
443+ .def (nb::init<MlirType>(), nb::arg (" type" ))
444+ .def_prop_ro (" type" , &Unknown::getType)
445+ .def (" __repr__" , [](const Unknown &u) {
446+ PyPrintAccumulator printAccum;
447+ printAccum.parts .append (" Unknown(" );
448+ mlirTypePrint (u.getType (), printAccum.getCallback (),
449+ printAccum.getUserData ());
450+ printAccum.parts .append (" )" );
451+ return printAccum.join ();
452+ });
453+
424454 // Add the Object class definition.
425455 nb::class_<Object>(m, " Object" )
426456 .def (nb::init<Object>(), nb::arg (" object" ))
0 commit comments