void ConvertHeaders::addTypesAndInstances()

in flexsai/p4/backend/json_stage/header.cpp [42:112]


void ConvertHeaders::addTypesAndInstances(const IR::Type_StructLike* type, bool meta) {
    LOG1("Adding " << type);
    for (auto f : type->fields) {
        auto ft = typeMap->getType(f, true);
        if (ft->is<IR::Type_StructLike>()) {
            // The headers struct can not contain nested structures.
            if (!meta && ft->is<IR::Type_Struct>()) {
                ::error("Type %1% should only contain headers, header stacks, or header unions",
                        type);
                return;
            }
            auto st = ft->to<IR::Type_StructLike>();
            addHeaderType(st);
        }
    }

    for (auto f : type->fields) {
        auto ft = typeMap->getType(f, true);
        bool is_extracted = isSaiExtractedField(type->toString(), f);
        if (ft->is<IR::Type_StructLike>()) {
            auto header_name = f->controlPlaneName();
            auto header_type = ft->to<IR::Type_StructLike>()->controlPlaneName();
            if (meta == true) {
                json->add_metadata(header_type, header_name);
            } else {
                if (ft->is<IR::Type_Header>()) {
                    json->add_header(header_type, header_name, isSaiFixedHeader(header_name, ft));
                } else if (ft->is<IR::Type_HeaderUnion>()) {
                    // We have to add separately a header instance for all
                    // headers in the union.  Each instance will be named with
                    // a prefix including the union name, e.g., "u.h"
                    Util::JsonArray* fields = new Util::JsonArray();
                    for (auto uf : ft->to<IR::Type_HeaderUnion>()->fields) {
                        auto uft = typeMap->getType(uf, true);
                        auto h_name = header_name + "." + uf->controlPlaneName();
                        auto h_type = uft->to<IR::Type_StructLike>()
                                         ->controlPlaneName();
                        unsigned id = json->add_header(h_type, h_name, isSaiFixedHeader(header_name, ft));
                        fields->append(id);
                    }
                    json->add_union(header_type, fields, header_name);
                } else {
                    BUG("Unexpected type %1%", ft);
                }
            }
        } else if (ft->is<IR::Type_Stack>()) {
            // Done elsewhere
            LOG1("stack generation done elsewhere");
            continue;
        } else {
            // Treat this field like a scalar local variable
            cstring newName = refMap->newName(type->getName() + "." + f->name);
            if (ft->is<IR::Type_Bits>()) {
                auto tb = ft->to<IR::Type_Bits>();
                addHeaderField(scalarsTypeName, newName, tb->size, tb->isSigned, is_extracted);
                scalars_width += tb->size;
                backend->scalarMetadataFields.emplace(f, newName);
            } else if (ft->is<IR::Type_Boolean>()) {
                addHeaderField(scalarsTypeName, newName, boolWidth, 0, is_extracted);
                scalars_width += boolWidth;
                backend->scalarMetadataFields.emplace(f, newName);
            } else if (ft->is<IR::Type_Error>()) {
                addHeaderField(scalarsTypeName, newName, errorWidth, 0, is_extracted);
                scalars_width += errorWidth;
                backend->scalarMetadataFields.emplace(f, newName);
            } else {
                BUG("%1%: Unhandled type for %2%", ft, f);
            }
        }
    }
}