diff --git a/backends/dpdk/dpdkArch.h b/backends/dpdk/dpdkArch.h index f404c191a03..26dd960e1fc 100644 --- a/backends/dpdk/dpdkArch.h +++ b/backends/dpdk/dpdkArch.h @@ -593,7 +593,7 @@ class InjectInternetChecksumIntermediateValue : public Transform { auto fields = new IR::IndexedVector; for (auto fld : *csum_vec) { fields->push_back( - new IR::StructField(IR::ID(fld), new IR::Type_Bits(16, false))); + new IR::StructField(IR::ID(fld), IR::Type::Bits::get(16, false))); } new_objs->push_back(new IR::Type_Header(IR::ID("cksum_state_t"), *fields)); } diff --git a/backends/ebpf/ebpfType.cpp b/backends/ebpf/ebpfType.cpp index 7b1656f98b9..9814f46d7c2 100644 --- a/backends/ebpf/ebpfType.cpp +++ b/backends/ebpf/ebpfType.cpp @@ -51,7 +51,7 @@ EBPFType *EBPFTypeFactory::create(const IR::Type *type) { result = new EBPFScalarType(tv); } else if (type->is()) { // Implement error type as scalar of width 8 bits - result = new EBPFScalarType(new IR::Type_Bits(8, false)); + result = new EBPFScalarType(IR::Type_Bits::get(8, false)); } else { ::error(ErrorType::ERR_UNSUPPORTED_ON_TARGET, "Type %1% not supported", type); } diff --git a/backends/p4tools/modules/testgen/core/small_step/abstract_stepper.cpp b/backends/p4tools/modules/testgen/core/small_step/abstract_stepper.cpp index a939e0e3727..4a907f5df7b 100644 --- a/backends/p4tools/modules/testgen/core/small_step/abstract_stepper.cpp +++ b/backends/p4tools/modules/testgen/core/small_step/abstract_stepper.cpp @@ -260,8 +260,8 @@ const IR::MethodCallStatement *generateStacksetValid(const IR::Expression *stack stackRef->type->checkedTo()->elementType, stackRef, index); auto name = (isValid) ? IR::Type_Header::setValid : IR::Type_Header::setInvalid; return new IR::MethodCallStatement(new IR::MethodCallExpression( - new IR::Type_Void(), - new IR::Member(new IR::Type_Method(new IR::Type_Void(), new IR::ParameterList(), name), + IR::Type_Void::get(), + new IR::Member(new IR::Type_Method(IR::Type_Void::get(), new IR::ParameterList(), name), arrayIndex, name))); } diff --git a/backends/p4tools/modules/testgen/targets/pna/constants.cpp b/backends/p4tools/modules/testgen/targets/pna/constants.cpp index 21c54c9af5e..36786f893b7 100644 --- a/backends/p4tools/modules/testgen/targets/pna/constants.cpp +++ b/backends/p4tools/modules/testgen/targets/pna/constants.cpp @@ -7,13 +7,13 @@ namespace P4Tools::P4Testgen::Pna { const IR::Member PnaConstants::DROP_VAR = IR::Member(IR::Type_Boolean::get(), new IR::PathExpression("*pna_internal"), "drop_var"); -const IR::Member PnaConstants::OUTPUT_PORT_VAR = IR::Member( - new IR::Type_Bits(32, false), new IR::PathExpression("*pna_internal"), "output_port"); -const IR::Member PnaConstants::PARSER_ERROR = IR::Member( - new IR::Type_Bits(32, false), new IR::PathExpression("*pna_internal"), "parser_error"); +const IR::Member PnaConstants::OUTPUT_PORT_VAR = + IR::Member(IR::Type_Bits::get(32), new IR::PathExpression("*pna_internal"), "output_port"); +const IR::Member PnaConstants::PARSER_ERROR = + IR::Member(IR::Type_Bits::get(32), new IR::PathExpression("*pna_internal"), "parser_error"); // TODO: Make this a proper variables variable. // We can not use the utilities because of an issue related to the garbage collector. const IR::SymbolicVariable PnaSymbolicVars::DIRECTION = - IR::SymbolicVariable(new IR::Type_Bits(32, false), "direction"); + IR::SymbolicVariable(IR::Type_Bits::get(32), "direction"); } // namespace P4Tools::P4Testgen::Pna diff --git a/backends/p4tools/p4tools.def b/backends/p4tools/p4tools.def index 988be280340..56721564f2f 100644 --- a/backends/p4tools/p4tools.def +++ b/backends/p4tools/p4tools.def @@ -153,6 +153,10 @@ class SymbolicVariable : Expression { /// This type replaces Type_Varbits and can store information about the current size class Extracted_Varbits : Type_Bits { + public: +#emit + void *operator new(size_t size) { return ::operator new(size); } +#end /// The assigned size of this varbit (assigned by extract calls). int assignedSize; diff --git a/control-plane/addMissingIds.cpp b/control-plane/addMissingIds.cpp index 6dedfccba56..664294b5f22 100644 --- a/control-plane/addMissingIds.cpp +++ b/control-plane/addMissingIds.cpp @@ -36,7 +36,7 @@ const IR::Property *MissingIdAssigner::postorder(IR::Property *property) { auto *newAnnos = annos->clone(); IR::Vector annoExprs; const auto *idConst = - new IR::Constant(new IR::Type_Bits(ID_BIT_WIDTH, false), symbolId + 1); + new IR::Constant(IR::Type_Bits::get(ID_BIT_WIDTH, false), symbolId + 1); annoExprs.push_back(idConst); newAnnos->add(new IR::Annotation("id", annoExprs)); keyElement->annotations = newAnnos; @@ -60,7 +60,7 @@ const IR::P4Table *MissingIdAssigner::postorder(IR::P4Table *table) { auto *newAnnos = annos->clone(); IR::Vector annoExprs; auto symbolId = symbols->getId(ControlPlaneAPI::P4RuntimeSymbolType::P4RT_TABLE(), table); - const auto *idConst = new IR::Constant(new IR::Type_Bits(ID_BIT_WIDTH, false), symbolId); + const auto *idConst = new IR::Constant(IR::Type_Bits::get(ID_BIT_WIDTH, false), symbolId); annoExprs.push_back(idConst); newAnnos->add(new IR::Annotation("id", annoExprs)); table->annotations = newAnnos; @@ -80,7 +80,7 @@ const IR::Type_Header *MissingIdAssigner::postorder(IR::Type_Header *hdr) { IR::Vector annoExprs; auto symbolId = symbols->getId(ControlPlaneAPI::P4RuntimeSymbolType::P4RT_CONTROLLER_HEADER(), hdr); - const auto *idConst = new IR::Constant(new IR::Type_Bits(ID_BIT_WIDTH, false), symbolId); + const auto *idConst = new IR::Constant(IR::Type_Bits::get(ID_BIT_WIDTH, false), symbolId); annoExprs.push_back(idConst); newAnnos->add(new IR::Annotation("id", annoExprs)); hdr->annotations = newAnnos; @@ -101,7 +101,7 @@ const IR::P4ValueSet *MissingIdAssigner::postorder(IR::P4ValueSet *valueSet) { IR::Vector annoExprs; auto symbolId = symbols->getId(ControlPlaneAPI::P4RuntimeSymbolType::P4RT_VALUE_SET(), valueSet); - const auto *idConst = new IR::Constant(new IR::Type_Bits(ID_BIT_WIDTH, false), symbolId); + const auto *idConst = new IR::Constant(IR::Type_Bits::get(ID_BIT_WIDTH, false), symbolId); annoExprs.push_back(idConst); newAnnos->add(new IR::Annotation("id", annoExprs)); valueSet->annotations = newAnnos; @@ -120,7 +120,7 @@ const IR::P4Action *MissingIdAssigner::postorder(IR::P4Action *action) { auto *newAnnos = annos->clone(); IR::Vector annoExprs; auto symbolId = symbols->getId(ControlPlaneAPI::P4RuntimeSymbolType::P4RT_ACTION(), action); - const auto *idConst = new IR::Constant(new IR::Type_Bits(ID_BIT_WIDTH, false), symbolId); + const auto *idConst = new IR::Constant(IR::Type_Bits::get(ID_BIT_WIDTH, false), symbolId); annoExprs.push_back(idConst); newAnnos->add(new IR::Annotation("id", annoExprs)); action->annotations = newAnnos; @@ -135,7 +135,7 @@ const IR::P4Action *MissingIdAssigner::postorder(IR::P4Action *action) { auto *newAnnos = annos->clone(); IR::Vector annoExprs; const auto *idConst = - new IR::Constant(new IR::Type_Bits(ID_BIT_WIDTH, false), symbolId + 1); + new IR::Constant(IR::Type_Bits::get(ID_BIT_WIDTH, false), symbolId + 1); annoExprs.push_back(idConst); newAnnos->add(new IR::Annotation("id", annoExprs)); param->annotations = newAnnos; diff --git a/frontends/p4/typeChecking/typeChecker.cpp b/frontends/p4/typeChecking/typeChecker.cpp index 0b0529fd0db..443de0d6ebf 100644 --- a/frontends/p4/typeChecking/typeChecker.cpp +++ b/frontends/p4/typeChecking/typeChecker.cpp @@ -1236,7 +1236,7 @@ std::pair *> TypeInference::con forAllMatching(p, [tvs, dontCares, typeParams](const IR::Type_Var *tv) { if (tvs->lookup(tv)) return; // already bound if (typeParams->getDeclByName(tv->name) != tv) return; // not a tv of this call - dontCares->setBinding(tv, new IR::Type_Dontcare); + dontCares->setBinding(tv, IR::Type_Dontcare::get()); }); } addSubstitutions(dontCares); @@ -2660,7 +2660,7 @@ const IR::Node *TypeInference::shift(const IR::Operation_Binary *expression) { // If the amount is signed but positive, make it unsigned if (auto bt = rtype->to()) { if (bt->isSigned) { - rtype = new IR::Type_Bits(rtype->srcInfo, bt->width_bits(), false); + rtype = IR::Type_Bits::get(rtype->srcInfo, bt->width_bits(), false); auto amt = new IR::Constant(cst->srcInfo, rtype, cst->value, cst->base); if (expression->is()) { expression = new IR::Shl(expression->srcInfo, expression->left, amt); @@ -3168,8 +3168,8 @@ const IR::Node *TypeInference::postorder(IR::Slice *expression) { const IR::Node *TypeInference::postorder(IR::Dots *expression) { if (done()) return expression; - setType(expression, new IR::Type_Any()); - setType(getOriginal(), new IR::Type_Any()); + setType(expression, IR::Type_Any::get()); + setType(getOriginal(), IR::Type_Any::get()); setCompileTimeConstant(expression); setCompileTimeConstant(getOriginal()); return expression; @@ -3736,7 +3736,7 @@ const IR::Node *TypeInference::postorder(IR::MethodCallExpression *expression) { return; // already bound if (tvs->lookup(tv)) return; // already bound if (typeParams->getDeclByName(tv->name) != tv) return; // not a tv of this call - dontCares->setBinding(tv, new IR::Type_Dontcare); + dontCares->setBinding(tv, IR::Type_Dontcare::get()); }); } addSubstitutions(dontCares); diff --git a/frontends/parsers/p4/p4parser.ypp b/frontends/parsers/p4/p4parser.ypp index 980c2e18767..fc9027c80f8 100644 --- a/frontends/parsers/p4/p4parser.ypp +++ b/frontends/parsers/p4/p4parser.ypp @@ -1019,11 +1019,11 @@ specializedType ; baseType - : BOOL { $$ = new IR::Type_Boolean(@1); } - | MATCH_KIND { $$ = new IR::Type_MatchKind(@1); } + : BOOL { $$ = IR::Type_Boolean::get(@1); } + | MATCH_KIND { $$ = IR::Type_MatchKind::get(@1); } | ERROR { $$ = new IR::Type_Name(@1, new IR::Path(IR::ID(@1, "error"))); } | BIT { $$ = IR::Type::Bits::get(@1, 1); } - | STRING { $$ = new IR::Type::String(@1); } + | STRING { $$ = IR::Type::String::get(@1); } | INT { $$ = new IR::Type_InfInt(@1); } | BIT l_angle INTEGER r_angle { $$ = IR::Type::Bits::get(@1+@4, parseConstantChecked(@3, $3), false); } @@ -1033,16 +1033,16 @@ baseType { $$ = IR::Type::Varbits::get(@1+@4, parseConstantChecked(@3, $3)); } | BIT l_angle "(" expression ")" r_angle - { $$ = new IR::Type_Bits(@1+@6, $4, false); } + { $$ = IR::Type_Bits::get(@1+@6, $4, false); } | INT l_angle "(" expression ")" r_angle - { $$ = new IR::Type_Bits(@1+@6, $4, true); } + { $$ = IR::Type_Bits::get(@1+@6, $4, true); } | VARBIT l_angle "(" expression ")" r_angle - { $$ = new IR::Type_Varbits(@1+@6, $4); } + { $$ = IR::Type_Varbits::get(@1+@6, $4); } ; typeOrVoid : typeRef { $$ = $1; } - | VOID { $$ = new IR::Type_Void(@1); } + | VOID { $$ = IR::Type_Void::get(@1); } | IDENTIFIER { $$ = new IR::Type_Name(@1, new IR::Path(*(new IR::ID(@1, $1)))); } // This is necessary because template arguments may introduce the return type ; @@ -1066,8 +1066,8 @@ typeArg : typeRef { $$ = $1; } | nonTypeName { $$ = new IR::Type_Name(@1, new IR::Path(*$1)); } // This is necessary because template arguments may introduce the return type - | VOID { $$ = new IR::Type_Void(@1); } - | "_" { $$ = new IR::Type_Dontcare(@1); } + | VOID { $$ = IR::Type_Void::get(@1); } + | "_" { $$ = IR::Type_Dontcare::get(@1); } ; typeArgumentList @@ -1078,8 +1078,8 @@ typeArgumentList realTypeArg : typeRef { $$ = $1; } - | VOID { $$ = new IR::Type_Void(@1); } - | "_" { $$ = new IR::Type_Dontcare(@1); } + | VOID { $$ = IR::Type_Void::get(@1); } + | "_" { $$ = IR::Type_Dontcare::get(@1); } ; // For use in contexts where the `<` might be a less-than rather than introducing a type diff --git a/ir/base.def b/ir/base.def index 0ae26b64140..02c3f49a317 100644 --- a/ir/base.def +++ b/ir/base.def @@ -120,6 +120,7 @@ abstract Type_Base : Type { class Type_Unknown : Type_Base { #nodbprint static Type_Unknown get(); + static Type_Unknown get(const Util::SourceInfo &si); toString{ return "Unknown type"; } } diff --git a/ir/irutils.cpp b/ir/irutils.cpp index 9ed81f659a3..41ea6ab6035 100644 --- a/ir/irutils.cpp +++ b/ir/irutils.cpp @@ -47,22 +47,20 @@ const IR::Constant *convertBoolLiteral(const IR::BoolLiteral *lit) { const IR::Expression *getDefaultValue(const IR::Type *type, const Util::SourceInfo &srcInfo, bool valueRequired) { if (const auto *tb = type->to()) { - // TODO: Use getConstant. - return new IR::Constant(srcInfo, tb, 0); + return IR::Constant::get(tb, 0, srcInfo); } if (type->is()) { - // TODO: Use getBoolLiteral. - return new BoolLiteral(srcInfo, Type::Boolean::get(), false); + return IR::BoolLiteral::get(false, srcInfo); } if (type->is()) { - return new IR::Constant(srcInfo, 0); + return IR::Constant::get(type, 0, srcInfo); } if (const auto *te = type->to()) { return new IR::Member(srcInfo, new IR::TypeNameExpression(te->name), te->members.at(0)->getName()); } if (const auto *te = type->to()) { - return new IR::Cast(srcInfo, type->getP4Type(), new IR::Constant(srcInfo, te->type, 0)); + return new IR::Cast(srcInfo, type->getP4Type(), IR::Constant::get(te->type, 0, srcInfo)); } if (const auto *te = type->to()) { return new IR::Member(srcInfo, new IR::TypeNameExpression(te->name), "NoError"); diff --git a/ir/type.cpp b/ir/type.cpp index 885ec308a35..f306559789d 100644 --- a/ir/type.cpp +++ b/ir/type.cpp @@ -21,6 +21,7 @@ limitations under the License. #include "frontends/common/parser_options.h" #include "ir/configuration.h" #include "ir/id.h" +#include "ir/ir-generated.h" #include "ir/ir.h" #include "ir/vector.h" #include "lib/cstring.h" @@ -87,41 +88,65 @@ const Type_Bits *Type_Bits::get(int width, bool isSigned) { return result; } -const Type::Unknown *Type::Unknown::get() { - static const Type::Unknown *singleton = nullptr; - if (!singleton) singleton = (new Type::Unknown()); +const Type_Bits *Type_Bits::get(const Util::SourceInfo &si, int sz, bool isSigned) { + auto *result = new IR::Type_Bits(si, sz, isSigned); + if (sz < 0) { + ::error(ErrorType::ERR_INVALID, "%1%: Width of type cannot be negative", result); + // Return a value that will not cause crashes later on + return new IR::Type_Bits(si, 1024, isSigned); + } + if (sz == 0 && isSigned) { + ::error(ErrorType::ERR_INVALID, "%1%: Width of signed type cannot be zero", result); + // Return a value that will not cause crashes later on + return new IR::Type_Bits(si, 1024, isSigned); + } + return result; +} + +const Type_Bits *Type_Bits::get(const Util::SourceInfo &si, const IR::Expression *expression, + bool isSigned) { + return new IR::Type_Bits(si, expression, isSigned); +} + +const Type_Unknown *Type_Unknown::get() { + static const Type_Unknown *singleton = nullptr; + if (!singleton) singleton = (new Type_Unknown()); return singleton; } -const Type::Boolean *Type::Boolean::get() { - static const Type::Boolean *singleton = nullptr; - if (!singleton) singleton = (new Type::Boolean()); +const Type_Unknown *Type_Unknown::get(const Util::SourceInfo &si) { + // We do not cache types with source info (yet). + return new Type_Unknown(si); +} + +const Type_Boolean *Type_Boolean::get() { + static const Type_Boolean *singleton = nullptr; + if (!singleton) singleton = (new Type_Boolean()); return singleton; } +const Type_Boolean *Type_Boolean::get(const Util::SourceInfo &si) { + // We do not cache types with source info (yet). + return new Type_Boolean(si); +} + const Type_String *Type_String::get() { static const Type_String *singleton = nullptr; if (!singleton) singleton = (new Type_String()); return singleton; } -const Type::Bits *Type::Bits::get(Util::SourceInfo si, int sz, bool isSigned) { - auto result = new IR::Type_Bits(si, sz, isSigned); - if (sz < 0) { - ::error(ErrorType::ERR_INVALID, "%1%: Width of type cannot be negative", result); - // Return a value that will not cause crashes later on - return new IR::Type_Bits(si, 1024, isSigned); - } - if (sz == 0 && isSigned) { - ::error(ErrorType::ERR_INVALID, "%1%: Width of signed type cannot be zero", result); - // Return a value that will not cause crashes later on - return new IR::Type_Bits(si, 1024, isSigned); - } - return result; +const Type_String *Type_String::get(const Util::SourceInfo &si) { + // We do not cache types with source info (yet). + return new Type_String(si); +} + +const Type_Varbits *Type_Varbits::get(const Util::SourceInfo &si, const IR::Expression *expr) { + return new Type_Varbits(si, expr); } -const Type::Varbits *Type::Varbits::get(Util::SourceInfo si, int sz) { - auto result = new Type::Varbits(si, sz); +const Type_Varbits *Type_Varbits::get(const Util::SourceInfo &si, int sz) { + auto result = new Type_Varbits(si, sz); if (sz < 0) { ::error(ErrorType::ERR_INVALID, "%1%: Width cannot be negative or zero", result); // Return a value that will not cause crashes later on @@ -130,7 +155,9 @@ const Type::Varbits *Type::Varbits::get(Util::SourceInfo si, int sz) { return result; } -const Type::Varbits *Type::Varbits::get() { return new Type::Varbits(0); } +const Type_Varbits *Type_Varbits::get(int sz) { return new Type_Varbits(sz); } + +const Type_Varbits *Type_Varbits::get() { return new Type_Varbits(0); } const Type_Dontcare *Type_Dontcare::get() { static const Type_Dontcare *singleton; @@ -138,24 +165,55 @@ const Type_Dontcare *Type_Dontcare::get() { return singleton; } +const Type_Dontcare *Type_Dontcare::get(const Util::SourceInfo &si) { + // We do not cache types with source info (yet). + return new Type_Dontcare(si); +} + const Type_State *Type_State::get() { static const Type_State *singleton; if (!singleton) singleton = (new Type_State()); return singleton; } +const Type_State *Type_State::get(const Util::SourceInfo &si) { + // We do not cache types with source info (yet). + return new Type_State(si); +} + const Type_Void *Type_Void::get() { static const Type_Void *singleton; if (!singleton) singleton = (new Type_Void()); return singleton; } +const Type_Void *Type_Void::get(const Util::SourceInfo &si) { + // We do not cache types with source info (yet). + return new Type_Void(si); +} + const Type_MatchKind *Type_MatchKind::get() { static const Type_MatchKind *singleton; if (!singleton) singleton = (new Type_MatchKind()); return singleton; } +const Type_MatchKind *Type_MatchKind::get(const Util::SourceInfo &si) { + // We do not cache types with source info (yet). + return new Type_MatchKind(si); +} + +const Type_Any *Type_Any::get() { + static const Type_Any *singleton; + if (!singleton) singleton = (new Type_Any()); + return singleton; +} + +const Type_Any *Type_Any::get(const Util::SourceInfo &si) { + // We do not cache types with source info (yet). + return new Type_Any(si); +} + bool Type_ActionEnum::contains(cstring name) const { for (auto a : actionList->actionList) { if (a->getName() == name) return true; diff --git a/ir/type.def b/ir/type.def index 7e75ab6b764..c1bb81a8e79 100644 --- a/ir/type.def +++ b/ir/type.def @@ -67,16 +67,20 @@ inline bool operator>>(cstring s, IR::Direction &d) { /// There is no syntax to represent this type. /// Treated like a type variable so that unification can assign it a value. class Type_Any : Type, ITypeVar { - long declid = nextId++; - private: + protected: +#emit + void *operator new(size_t size) { return ::operator new(size); } +#end static long nextId; public: + long declid = nextId++; cstring getVarName() const override { return "int_" + Util::toString(declid); } int getDeclId() const override { return declid; } dbprint { out << "ANYTYPE/" << declid; } toString { return "ANYTYPE"; } operator== { return declid == a.declid; } static Type_Any get(); + static Type_Any get(const Util::SourceInfo &si); const Type* getP4Type() const override { return nullptr; } equiv { (void)a; // silence unused warning @@ -118,7 +122,13 @@ class Type_Type : Type { } class Type_Boolean : Type_Base { + protected: +#emit + void *operator new(size_t size) { return ::operator new(size); } +#end + public: static Type_Boolean get(); + static Type_Boolean get(const Util::SourceInfo &si); int width_bits() const override { return 1; } toString{ return "bool"; } dbprint { out << "bool"; } @@ -126,17 +136,29 @@ class Type_Boolean : Type_Base { /// The type of a parser state class Type_State : Type_Base { + protected: +#emit + void *operator new(size_t size) { return ::operator new(size); } +#end + public: static Type_State get(); + static Type_State get(const Util::SourceInfo &si); toString{ return "state"; } dbprint { out << "state"; } } /// Represents both bit<> and int<> types in P4-14 and P4-16 class Type_Bits : Type_Base { + protected: +#emit + void *operator new(size_t size) { return ::operator new(size); } +#end + public: optional int size = 0; // zero (only) for not-yet evaluated const expression NullOK optional Expression expression; // only used temporarily bool isSigned; - static Type_Bits get(Util::SourceInfo si, int sz, bool isSigned = false); + static Type_Bits get(const Util::SourceInfo &si, Expression expression, bool isSigned = false); + static Type_Bits get(const Util::SourceInfo &si, int sz, bool isSigned = false); static Type_Bits get(int sz, bool isSigned = false); cstring baseName() const { return isSigned ? "int" : "bit"; } int width_bits() const override { return size; } @@ -146,9 +168,16 @@ class Type_Bits : Type_Base { } class Type_Varbits : Type_Base { + protected: +#emit + void *operator new(size_t size) { return ::operator new(size); } +#end + public: optional int size = 0; // if zero it means "unknown" NullOK optional Expression expression = nullptr; // only used temporarily - static Type_Varbits get(Util::SourceInfo si, int size = 0); + static Type_Varbits get(const Util::SourceInfo &si, Expression expr); + static Type_Varbits get(const Util::SourceInfo &si, int size); + static Type_Varbits get(int size); static Type_Varbits get(); toString{ return cstring("varbit<") + Util::toString(size) + ">"; } dbprint { out << "varbit<" << size << ">"; } @@ -232,20 +261,38 @@ class Type_InfInt : Type, ITypeVar { } class Type_Dontcare : Type_Base { + protected: +#emit + void *operator new(size_t size) { return ::operator new(size); } +#end + public: toString{ return "_"; } static Type_Dontcare get(); + static Type_Dontcare get(const Util::SourceInfo &si); dbprint { out << "_"; } } class Type_Void : Type_Base { + protected: +#emit + void *operator new(size_t size) { return ::operator new(size); } +#end + public: toString{ return "void"; } static Type_Void get(); + static Type_Void get(const Util::SourceInfo &si); dbprint { out << "void"; } } class Type_MatchKind : Type_Base { + protected: +#emit + void *operator new(size_t size) { return ::operator new(size); } +#end + public: toString{ return "match_kind"; } static Type_MatchKind get(); + static Type_MatchKind get(const Util::SourceInfo &si); dbprint { out << "match_kind"; } } @@ -567,7 +614,13 @@ class Declaration_ID : Declaration, CompileTimeValue { /// The type of a string literal class Type_String : Type_Base { #nodbprint + protected: +#emit + void *operator new(size_t size) { return ::operator new(size); } +#end + public: static Type_String get(); + static Type_String get(const Util::SourceInfo &si); toString{ return "string"; } } diff --git a/midend/convertEnums.h b/midend/convertEnums.h index 221bab7cf78..0c0fbd82949 100644 --- a/midend/convertEnums.h +++ b/midend/convertEnums.h @@ -48,7 +48,7 @@ class EnumRepresentation { const IR::Type_Bits *type; EnumRepresentation(Util::SourceInfo srcInfo, unsigned width) { - type = new IR::Type_Bits(srcInfo, width, false); + type = IR::Type_Bits::get(srcInfo, width, false); } void add(cstring decl) { repr.emplace(decl, repr.size()); } unsigned get(cstring decl) const { return ::get(repr, decl); } diff --git a/midend/parserUnroll.cpp b/midend/parserUnroll.cpp index e15c01249ab..684dba63b54 100644 --- a/midend/parserUnroll.cpp +++ b/midend/parserUnroll.cpp @@ -791,8 +791,8 @@ class ParserSymbolicInterpreter { } hasOutOfboundState = true; newStates.insert(newName); - auto *pathExpr = - new IR::PathExpression(new IR::Type_State(), new IR::Path(outOfBoundsStateName, false)); + auto *pathExpr = new IR::PathExpression(IR::Type_State::get(), + new IR::Path(outOfBoundsStateName, false)); stateInfo->newState = new IR::ParserState(newName, components, pathExpr); } diff --git a/midend/parserUnroll.h b/midend/parserUnroll.h index 826ba3d969f..f2024aa2a3c 100644 --- a/midend/parserUnroll.h +++ b/midend/parserUnroll.h @@ -254,8 +254,7 @@ class RewriteAllParsers : public Transform { if (rewriter->hasOutOfboundState) { // generating state with verify(false, error.StackOutOfBounds) IR::Vector *arguments = new IR::Vector(); - arguments->push_back( - new IR::Argument(new IR::BoolLiteral(IR::Type::Boolean::get(), false))); + arguments->push_back(new IR::Argument(IR::BoolLiteral::get(false))); arguments->push_back(new IR::Argument( new IR::Member(new IR::TypeNameExpression(new IR::Type_Name(IR::ID("error"))), IR::ID("StackOutOfBounds")))); @@ -274,7 +273,7 @@ class RewriteAllParsers : public Transform { arguments))); auto *outOfBoundsState = new IR::ParserState( IR::ID(outOfBoundsStateName), components, - new IR::PathExpression(new IR::Type_State(), + new IR::PathExpression(IR::Type_State::get(), new IR::Path(IR::ParserState::reject, false))); newParser->states.push_back(outOfBoundsState); } diff --git a/midend/replaceSelectRange.cpp b/midend/replaceSelectRange.cpp index 804a5619a24..13593c94f9c 100644 --- a/midend/replaceSelectRange.cpp +++ b/midend/replaceSelectRange.cpp @@ -91,7 +91,7 @@ std::vector *DoReplaceSelectRange::rangeToMasks(const IR::Rang auto inType = r->left->type->to(); BUG_CHECK(inType != nullptr, "Range type %1% is not fixed-width integer", r->left->type); bool isSigned = inType->isSigned; - auto maskType = isSigned ? new IR::Type_Bits(inType->srcInfo, inType->size, false) : inType; + auto maskType = isSigned ? IR::Type_Bits::get(inType->srcInfo, inType->size, false) : inType; if (isSigned) { signedIndicesToReplace.emplace(keyIndex); @@ -150,7 +150,7 @@ const IR::Node *DoReplaceSelectRange::postorder(IR::SelectExpression *e) { "Cannot handle select on types other then fixed-width integeral " "types: %1%", expr->type); - auto unsignedType = new IR::Type_Bits(eType->srcInfo, eType->size, false); + auto unsignedType = IR::Type_Bits::get(eType->srcInfo, eType->size, false); newSelectList.push_back(new IR::Cast(expr->srcInfo, unsignedType, expr)); } else { diff --git a/midend/singleArgumentSelect.cpp b/midend/singleArgumentSelect.cpp index 46eb131a088..407e80d07eb 100644 --- a/midend/singleArgumentSelect.cpp +++ b/midend/singleArgumentSelect.cpp @@ -27,7 +27,7 @@ static const IR::Expression *convertList(const IR::Expression *expression, const IR::Type *selectListType) { if (expression->is()) { int width = selectListType->width_bits(); - auto type = new IR::Type_Bits(width, false); + auto type = IR::Type_Bits::get(width, false); return new IR::Mask(expression->srcInfo, new IR::Constant(type, 0, 16), new IR::Constant(type, 0, 16)); } diff --git a/test/gtest/p4runtime.cpp b/test/gtest/p4runtime.cpp index 381f1199516..0d706500cbc 100644 --- a/test/gtest/p4runtime.cpp +++ b/test/gtest/p4runtime.cpp @@ -1682,7 +1682,7 @@ class P4RuntimeDataTypeSpec : public P4Runtime { TEST_F(P4RuntimeDataTypeSpec, Bits) { int size(9); bool isSigned(true); - auto *type = new IR::Type_Bits(size, isSigned); + auto *type = IR::Type_Bits::get(size, isSigned); const auto *typeSpec = P4::ControlPlaneAPI::TypeSpecConverter::convert(&refMap, &typeMap, type, &typeInfo); ASSERT_TRUE(typeSpec->has_bitstring()); @@ -1693,7 +1693,7 @@ TEST_F(P4RuntimeDataTypeSpec, Bits) { TEST_F(P4RuntimeDataTypeSpec, Varbits) { int size(64); - auto *type = new IR::Type_Varbits(size); + auto *type = IR::Type_Varbits::get(size); const auto *typeSpec = P4::ControlPlaneAPI::TypeSpecConverter::convert(&refMap, &typeMap, type, &typeInfo); ASSERT_TRUE(typeSpec->has_bitstring()); @@ -1703,15 +1703,15 @@ TEST_F(P4RuntimeDataTypeSpec, Varbits) { } TEST_F(P4RuntimeDataTypeSpec, Boolean) { - auto *type = new IR::Type_Boolean(); + auto *type = IR::Type_Boolean::get(); const auto *typeSpec = P4::ControlPlaneAPI::TypeSpecConverter::convert(&refMap, &typeMap, type, &typeInfo); EXPECT_TRUE(typeSpec->has_bool_()); } TEST_F(P4RuntimeDataTypeSpec, Tuple) { - auto *typeMember1 = new IR::Type_Bits(1, false); - auto *typeMember2 = new IR::Type_Bits(2, false); + auto *typeMember1 = IR::Type_Bits::get(1, false); + auto *typeMember2 = IR::Type_Bits::get(2, false); IR::Vector components = {typeMember1, typeMember2}; auto *type = new IR::Type_Tuple(std::move(components)); const auto *typeSpec =