69 auto vec =
new IR::IndexedVector<IR::StructField>();
70 flatten(typeMap,
"", type, type->annotations, vec, policy);
71 if (type->is<IR::Type_Struct>()) {
73 new IR::Type_Struct(type->srcInfo, type->name, IR::Annotations::empty, *vec);
74 }
else if (type->is<IR::Type_Header>()) {
76 new IR::Type_Header(type->srcInfo, type->name, IR::Annotations::empty, *vec);
78 BUG(
"Unexpected type %1%", type);
88 std::map<cstring, cstring> fieldNameRemap;
92 std::map<cstring, const IR::Type_StructLike *> structFieldMap;
100 const IR::Type *replacementType;
101 virtual void dbprint(std::ostream &out)
const { out << replacementType; }
105 const IR::Annotations *annotations, IR::IndexedVector<IR::StructField> *fields,
108 annotations = annotations->where(
109 [](
const IR::Annotation *a) {
return a->name != IR::Annotation::nameAnnotation; });
110 if (
auto st = type->to<T>()) {
111 auto sannotations = st->annotations->where([policy](
const IR::Annotation *annot) {
112 if (!policy)
return false;
113 return policy->
keep(annot);
115 structFieldMap.emplace(prefix, st);
116 for (
auto f : st->fields) {
117 auto na =
new IR::Annotations();
118 na->append(sannotations);
119 na->append(annotations);
120 na->append(f->annotations);
121 auto ft = typeMap->getType(f,
true);
122 flatten(typeMap, prefix +
"." + f->name, ft, na, fields, policy);
126 cstring fieldName = prefix.replace(
".",
"_") + cstring::to_cstring(fieldNameRemap.size());
127 fieldNameRemap.emplace(prefix, fieldName);
128 fields->push_back(
new IR::StructField(IR::ID(fieldName), annotations, type->getP4Type()));
129 LOG3(
"Flatten: " << type <<
" | " << prefix);
136 const IR::StructExpression *
explode(
const IR::Expression *root,
cstring prefix) {
137 auto vec =
new IR::IndexedVector<IR::NamedExpression>();
138 auto fieldType = ::get(structFieldMap, prefix);
139 BUG_CHECK(fieldType,
"No field for %1%", prefix);
140 for (
auto f : fieldType->fields) {
141 cstring fieldName = prefix +
"." + f->name.name;
142 auto newFieldname = ::get(fieldNameRemap, fieldName);
143 const IR::Expression *expr;
144 if (!newFieldname.isNullOrEmpty()) {
145 expr =
new IR::Member(root, newFieldname);
147 expr =
explode(root, fieldName);
149 vec->push_back(
new IR::NamedExpression(f->name, expr));
151 auto type = fieldType->getP4Type()->template to<IR::Type_Name>();
152 return new IR::StructExpression(root->srcInfo, type, type, *vec);
237 std::map<const IR::Parameter *, StructTypeReplacement<IR::Type_Struct> *> toReplace;
242 setName(
"ReplaceStructs");
245 const IR::Node *preorder(IR::P4Program *program)
override;
246 const IR::Node *postorder(IR::Member *expression)
override;
247 const IR::Node *preorder(IR::P4Parser *parser)
override;
248 const IR::Node *preorder(IR::P4Control *control)
override;
249 const IR::Node *postorder(IR::Type_Struct *type)
override;