8#ifndef FRONTENDS_P4_TYPECHECKING_TYPECONSTRAINTS_H_
9#define FRONTENDS_P4_TYPECHECKING_TYPECONSTRAINTS_H_
12#include "lib/castable.h"
13#include "lib/error_helper.h"
14#include "typeSubstitution.h"
15#include "typeSubstitutionVisitor.h"
16#include "typeUnification.h"
22 absl::flat_hash_set<const IR::Type_Var *, Util::Hash> explained;
26 std::string explanation;
30 return Inspector::init_apply(node);
32 void postorder(
const IR::Type_Var *tv)
override {
33 auto [_, inserted] = explained.emplace(tv);
37 auto val = subst->lookup(tv);
39 explanation +=
"Where '" + tv->toString() +
"' is bound to '" + val->toString() +
"'\n";
41 erec.setCalledBy(
this);
43 explanation += erec.explanation;
52 std::vector<const IR::Node *> errArguments;
63 explicit TypeConstraint(
const TypeConstraint *
derivedFrom)
66 std::string explain(
size_t index, Explain *explainer)
const {
67 const auto *node = errArguments.at(index);
68 node->apply(*explainer);
69 return explainer->explanation;
71 std::string localError(Explain *explainer)
const;
74 void setError(std::string_view format, std::initializer_list<const IR::Node *> nodes) {
75 errFormat = cstring(format);
78 template <
typename... Args>
81 Args &&...args)
const {
86 return reportErrorImpl(
87 subst,
" ---- Actual error:\n" +
88 ::P4::error_helper(format, std::forward<Args>(args)...).toString());
97class BinaryConstraint :
public TypeConstraint {
100 const IR::Type *right;
103 BinaryConstraint(
const IR::Type *left,
const IR::Type *right,
const TypeConstraint *
derivedFrom)
104 : TypeConstraint(
derivedFrom), left(left), right(right) {
107 BinaryConstraint(
const IR::Type *left,
const IR::Type *right,
const IR::Node *
origin)
108 : TypeConstraint(
origin), left(left), right(right) {
111 void validate()
const {
114 if (left->is<IR::Type_Name>() || right->is<IR::Type_Name>())
115 BUG(
"type names should not appear in unification: %1% and %2%", left, right);
119 virtual BinaryConstraint *create(
const IR::Type *left,
const IR::Type *right)
const = 0;
121 DECLARE_TYPEINFO(BinaryConstraint, TypeConstraint);
125class EqualityConstraint :
public BinaryConstraint {
127 EqualityConstraint(
const IR::Type *left,
const IR::Type *right,
130 EqualityConstraint(
const IR::Type *left,
const IR::Type *right,
const IR::Node *
origin)
131 : BinaryConstraint(left, right,
origin) {}
132 void dbprint(std::ostream &out)
const override {
133 out <<
"Constraint:" << dbp(left) <<
" == " << dbp(right);
137 return reportError(subst,
"Cannot unify type '%1%' with type '%2%'", right, left);
139 BinaryConstraint *create(
const IR::Type *left,
const IR::Type *right)
const override {
140 return new EqualityConstraint(left, right,
this);
143 DECLARE_TYPEINFO(EqualityConstraint, BinaryConstraint);
147class CanBeImplicitlyCastConstraint :
public BinaryConstraint {
149 CanBeImplicitlyCastConstraint(
const IR::Type *left,
const IR::Type *right,
152 CanBeImplicitlyCastConstraint(
const IR::Type *left,
const IR::Type *right,
154 : BinaryConstraint(left, right,
origin) {}
155 void dbprint(std::ostream &out)
const override {
156 out <<
"Constraint:" << dbp(left) <<
" := " << dbp(right);
160 return reportError(subst,
"Cannot cast implicitly type '%1%' to type '%2%'", right, left);
162 BinaryConstraint *create(
const IR::Type *left,
const IR::Type *right)
const override {
163 return new CanBeImplicitlyCastConstraint(left, right,
this);
166 DECLARE_TYPEINFO(CanBeImplicitlyCastConstraint, BinaryConstraint);
184 absl::flat_hash_set<const IR::ITypeVar *, Util::Hash> unifiableTypeVariables;
185 std::vector<const TypeConstraint *> constraints;
196 definedVariables(definedVariables),
198 replaceVariables(definedVariables) {}
200 void addUnifiableTypeVariable(
const IR::ITypeVar *typeVariable) {
201 LOG3(
"Adding unifiable type variable " << typeVariable);
202 unifiableTypeVariables.insert(typeVariable);
210 LOG3(
"Adding constraint " << constraint);
211 constraints.push_back(constraint);
213 void addEqualityConstraint(
const IR::Node *source,
const IR::Type *left,
const IR::Type *right);
214 void addImplicitCastConstraint(
const IR::Node *source,
const IR::Type *left,
215 const IR::Type *right);
224 void dbprint(std::ostream &out)
const;
Base class for EqualityConstraint and CanBeImplicitlyCastConstraint.
Definition typeConstraints.h:97
Definition stringify.h:24
Definition typeConstraints.h:47
bool reportError(const TypeVariableSubstitution *subst, const char *format, Args &&...args) const
Definition typeConstraints.h:80
const IR::Node * origin
Place in source code which originated the contraint. May be nullptr.
Definition typeConstraints.h:61
const TypeConstraint * derivedFrom
Constraint which produced this one. May be nullptr.
Definition typeConstraints.h:59
bool isUnifiableTypeVariable(const IR::Type *type)
Definition typeConstraints.cpp:42
Definition typeUnification.h:30
Definition typeSubstitution.h:64
Definition typeSubstitutionVisitor.h:36
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13