71        flatten(typeMap, cstring::empty, type, type->annotations, vec, policy);
 
   72        if (type->is<IR::Type_Struct>()) {
 
   74                new IR::Type_Struct(type->srcInfo, type->name, IR::Annotations::empty, *vec);
 
   75        } 
else if (type->is<IR::Type_Header>()) {
 
   77                new IR::Type_Header(type->srcInfo, type->name, IR::Annotations::empty, *vec);
 
   79            BUG(
"Unexpected type %1%", type);
 
   89    std::map<cstring, cstring> fieldNameRemap;
 
   93    std::map<cstring, const IR::Type_StructLike *> structFieldMap;
 
  101    const IR::Type *replacementType;
 
  102    virtual void dbprint(std::ostream &out)
 const { out << replacementType; }
 
  109        annotations = annotations->where(
 
  110            [](
const IR::Annotation *a) { 
return a->name != IR::Annotation::nameAnnotation; });
 
  111        if (
auto st = type->to<T>()) {
 
  112            auto sannotations = st->annotations->where([policy](
const IR::Annotation *annot) {
 
  113                if (!policy) 
return false;
 
  114                return policy->
keep(annot);
 
  116            structFieldMap.emplace(prefix, st);
 
  117            for (
auto f : st->fields) {
 
  118                auto na = 
new IR::Annotations();
 
  119                na->append(sannotations);
 
  120                na->append(annotations);
 
  121                na->append(f->annotations);
 
  122                auto ft = typeMap->getType(f, 
true);
 
  123                flatten(typeMap, prefix + 
"." + f->name, ft, na, fields, policy);
 
  127        cstring fieldName = prefix.replace(
'.', 
'_') + std::to_string(fieldNameRemap.size());
 
  128        fieldNameRemap.emplace(prefix, fieldName);
 
  129        fields->push_back(
new IR::StructField(
IR::ID(fieldName), annotations, type->getP4Type()));
 
  130        LOG3(
"Flatten: " << type << 
" | " << prefix);
 
  137    const IR::StructExpression *
explode(
const IR::Expression *root, 
cstring prefix) {
 
  139        auto fieldType = ::get(structFieldMap, prefix);
 
  140        BUG_CHECK(fieldType, 
"No field for %1%", prefix);
 
  141        for (
auto f : fieldType->fields) {
 
  142            cstring fieldName = prefix + 
"." + f->name.name;
 
  143            auto newFieldname = ::get(fieldNameRemap, fieldName);
 
  144            const IR::Expression *expr;
 
  145            if (!newFieldname.isNullOrEmpty()) {
 
  146                expr = 
new IR::Member(root, newFieldname);
 
  148                expr = 
explode(root, fieldName);
 
  150            vec->push_back(
new IR::NamedExpression(f->name, expr));
 
  152        auto type = fieldType->getP4Type()->template to<IR::Type_Name>();
 
  153        return new IR::StructExpression(root->srcInfo, type, type, *vec);
 
 
 
  238    std::map<const IR::Parameter *, StructTypeReplacement<IR::Type_Struct> *> toReplace;
 
  243        setName(
"ReplaceStructs");
 
  246    const IR::Node *preorder(IR::P4Program *program) 
override;
 
  247    const IR::Node *postorder(IR::Member *expression) 
override;
 
  248    const IR::Node *preorder(IR::P4Parser *parser) 
override;
 
  249    const IR::Node *preorder(IR::P4Control *control) 
override;
 
  250    const IR::Node *postorder(IR::Type_Struct *type) 
override;