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 boost::format fmt(format);
87 return reportErrorImpl(subst,
88 " ---- Actual error:\n" +
89 ::P4::error_helper(fmt, std::forward<Args>(args)...).toString());
98class BinaryConstraint :
public TypeConstraint {
100 const IR::Type *left;
101 const IR::Type *right;
104 BinaryConstraint(
const IR::Type *left,
const IR::Type *right,
const TypeConstraint *
derivedFrom)
105 : TypeConstraint(
derivedFrom), left(left), right(right) {
108 BinaryConstraint(
const IR::Type *left,
const IR::Type *right,
const IR::Node *
origin)
109 : TypeConstraint(
origin), left(left), right(right) {
112 void validate()
const {
115 if (left->is<IR::Type_Name>() || right->is<IR::Type_Name>())
116 BUG(
"type names should not appear in unification: %1% and %2%", left, right);
120 virtual BinaryConstraint *create(
const IR::Type *left,
const IR::Type *right)
const = 0;
122 DECLARE_TYPEINFO(BinaryConstraint, TypeConstraint);
126class EqualityConstraint :
public BinaryConstraint {
128 EqualityConstraint(
const IR::Type *left,
const IR::Type *right,
131 EqualityConstraint(
const IR::Type *left,
const IR::Type *right,
const IR::Node *
origin)
132 : BinaryConstraint(left, right,
origin) {}
133 void dbprint(std::ostream &out)
const override {
134 out <<
"Constraint:" << dbp(left) <<
" == " << dbp(right);
138 return reportError(subst,
"Cannot unify type '%1%' with type '%2%'", right, left);
140 BinaryConstraint *create(
const IR::Type *left,
const IR::Type *right)
const override {
141 return new EqualityConstraint(left, right,
this);
144 DECLARE_TYPEINFO(EqualityConstraint, BinaryConstraint);
148class CanBeImplicitlyCastConstraint :
public BinaryConstraint {
150 CanBeImplicitlyCastConstraint(
const IR::Type *left,
const IR::Type *right,
153 CanBeImplicitlyCastConstraint(
const IR::Type *left,
const IR::Type *right,
155 : BinaryConstraint(left, right,
origin) {}
156 void dbprint(std::ostream &out)
const override {
157 out <<
"Constraint:" << dbp(left) <<
" := " << dbp(right);
161 return reportError(subst,
"Cannot cast implicitly type '%1%' to type '%2%'", right, left);
163 BinaryConstraint *create(
const IR::Type *left,
const IR::Type *right)
const override {
164 return new CanBeImplicitlyCastConstraint(left, right,
this);
167 DECLARE_TYPEINFO(CanBeImplicitlyCastConstraint, BinaryConstraint);
185 absl::flat_hash_set<const IR::ITypeVar *, Util::Hash> unifiableTypeVariables;
186 std::vector<const TypeConstraint *> constraints;
197 definedVariables(definedVariables),
199 replaceVariables(definedVariables) {}
201 void addUnifiableTypeVariable(
const IR::ITypeVar *typeVariable) {
202 LOG3(
"Adding unifiable type variable " << typeVariable);
203 unifiableTypeVariables.insert(typeVariable);
211 LOG3(
"Adding constraint " << constraint);
212 constraints.push_back(constraint);
214 void addEqualityConstraint(
const IR::Node *source,
const IR::Type *left,
const IR::Type *right);
215 void addImplicitCastConstraint(
const IR::Node *source,
const IR::Type *left,
216 const IR::Type *right);
225 void dbprint(std::ostream &out)
const;
Base class for EqualityConstraint and CanBeImplicitlyCastConstraint.
Definition typeConstraints.h:98
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