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);
}
}
}
}