32class SharedActionSelectorCheck :
public Inspector {
37 static bool checkSameKeyExpr(
const IR::Expression *expr0,
const IR::Expression *expr1) {
38 if (expr0->node_type_name() != expr1->node_type_name())
return false;
39 if (
auto pe0 = expr0->to<IR::PathExpression>()) {
40 auto pe1 = expr1->to<IR::PathExpression>();
41 return pe0->path->name == pe1->path->name && pe0->path->absolute == pe1->path->absolute;
42 }
else if (
auto mem0 = expr0->to<IR::Member>()) {
43 auto mem1 = expr1->to<IR::Member>();
44 return checkSameKeyExpr(mem0->expr, mem1->expr) && mem0->member == mem1->member;
45 }
else if (
auto l0 = expr0->to<IR::Literal>()) {
46 auto l1 = expr1->to<IR::Literal>();
48 }
else if (
auto ai0 = expr0->to<IR::ArrayIndex>()) {
49 auto ai1 = expr1->to<IR::ArrayIndex>();
50 return checkSameKeyExpr(ai0->left, ai1->left) &&
51 checkSameKeyExpr(ai0->right, ai1->right);
58 refMap = ctxt->refMap;
59 typeMap = ctxt->typeMap;
62 bool preorder(
const IR::P4Table *table)
override {
63 auto implementation = table->properties->getProperty(
"implementation");
64 if (implementation ==
nullptr)
return false;
65 if (!implementation->value->is<IR::ExpressionValue>()) {
66 ::P4::error(ErrorType::ERR_EXPECTED,
"%1%: expected expression for property",
70 auto propv = implementation->value->to<IR::ExpressionValue>();
71 if (!propv->expression->is<IR::PathExpression>())
return false;
72 auto pathe = propv->expression->to<IR::PathExpression>();
73 auto decl = refMap->getDeclaration(pathe->path,
true);
74 if (!decl->is<IR::Declaration_Instance>()) {
75 ::P4::error(ErrorType::ERR_EXPECTED,
"%1%: expected a reference to an instance", pathe);
78 auto dcltype = typeMap->getType(pathe,
true);
79 if (!dcltype->is<IR::Type_Extern>()) {
80 ::P4::error(ErrorType::ERR_UNEXPECTED,
"%1%: unexpected type for implementation",
84 auto type_extern_name = dcltype->to<IR::Type_Extern>()->name;
86 if (type_extern_name != actionSelectorName)
return false;
88 auto key = table->getKey();
90 for (
auto ke : key->keyElements) {
91 auto mt = refMap->getDeclaration(ke->matchType->path,
true)->to<IR::Declaration_ID>();
92 BUG_CHECK(mt !=
nullptr,
"%1%: could not find declaration", ke->matchType);
94 input.push_back(ke->expression);
96 auto decl_instance = decl->to<IR::Declaration_Instance>();
97 auto it = ctxt->selector_input_map.find(decl_instance);
98 if (it == ctxt->selector_input_map.end()) {
99 ctxt->selector_input_map[decl_instance] = input;
104 if (i1.size() != i2.size())
return false;
105 return std::equal(i1.begin(), i1.end(), i2.begin(), checkSameKeyExpr);
108 if (!cmp_inputs(it->second, input)) {
110 ErrorType::ERR_INVALID,
111 "Action selector %1% is used by multiple tables with different selector inputs",
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:58
Definition bmv2/common/helpers.h:288