P4C
The P4 Compiler
Loading...
Searching...
No Matches
nestedStructs.h
1/*
2 * Copyright 2016 VMware, Inc.
3 * SPDX-FileCopyrightText: 2016 VMware, Inc.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef MIDEND_NESTEDSTRUCTS_H_
9#define MIDEND_NESTEDSTRUCTS_H_
10
11#include "frontends/common/resolveReferences/resolveReferences.h"
12#include "frontends/p4/typeChecking/typeChecker.h"
13#include "ir/ir.h"
14
15namespace P4 {
16
17class ComplexValues final {
18 public:
23 struct Component : public IHasDbPrint {
24 virtual const IR::Expression *convertToExpression() = 0;
25 virtual Component *getComponent(cstring name) = 0;
26 virtual void dbprint(std::ostream &out) const = 0;
27 };
28
29 struct FinalName : public Component {
30 cstring newName;
31 explicit FinalName(cstring name) : newName(name) {}
32 const IR::Expression *convertToExpression() override {
33 return new IR::PathExpression(IR::ID(newName));
34 }
35 Component *getComponent(cstring) override { return nullptr; }
36 void dbprint(std::ostream &out) const override { out << newName << Log::endl; }
37 };
38
39 struct FieldsMap : public Component {
41 const IR::Type *type;
42 explicit FieldsMap(const IR::Type *type) : type(type) {
43 CHECK_NULL(type);
44 BUG_CHECK(type->is<IR::Type_Struct>(), "%1%: expected a struct", type);
45 }
46 const IR::Expression *convertToExpression() override {
48 for (auto m : members) {
49 auto e = m.second->convertToExpression();
50 vec.push_back(new IR::NamedExpression(m.first, e));
51 }
52 return new IR::StructExpression(type->getP4Type(), vec);
53 }
54 Component *getComponent(cstring name) override { return ::P4::get(members, name); }
55 void dbprint(std::ostream &out) const override {
56 out << Log::indent;
57 for (auto m : members) out << m.first << "=>" << m.second;
58 out << Log::unindent;
59 }
60 };
61
62 std::map<const IR::Declaration_Variable *, Component *> values;
63 std::map<const IR::Expression *, Component *> translation;
64
65 TypeMap *typeMap;
66 NameGenerator &nameGen;
67
68 ComplexValues(TypeMap *typeMap, NameGenerator &nameGen) : typeMap(typeMap), nameGen(nameGen) {
69 CHECK_NULL(typeMap);
70 }
72 bool isNestedStruct(const IR::Type *type) const;
74 template <class T>
75 void explode(std::string_view prefix, const IR::Type_Struct *type, FieldsMap *map,
76 IR::Vector<T> *result);
77 Component *getTranslation(const IR::IDeclaration *decl) const {
78 auto dv = decl->to<IR::Declaration_Variable>();
79 if (dv == nullptr) return nullptr;
80 return ::P4::get(values, dv);
81 }
82 Component *getTranslation(const IR::Expression *expression) const {
83 LOG2("Check translation " << dbp(expression));
84 return ::P4::get(translation, expression);
85 }
86 void setTranslation(const IR::Expression *expression, Component *comp) {
87 translation.emplace(expression, comp);
88 LOG2("Translated " << dbp(expression) << " to " << comp);
89 }
90};
91
121class RemoveNestedStructs final : public Transform, public ResolutionContext {
122 ComplexValues values;
123 MinimalNameGenerator nameGen;
124
125 public:
126 explicit RemoveNestedStructs(TypeMap *typeMap) : values(typeMap, nameGen) {
127 setName("RemoveNestedStructs");
128 }
129 Visitor::profile_t init_apply(const IR::Node *node) override {
130 auto rv = Transform::init_apply(node);
131 node->apply(nameGen);
132
133 return rv;
134 }
135
137 const IR::Node *postorder(IR::Declaration_Variable *decl) override;
139 const IR::Node *postorder(IR::Member *expression) override;
141 const IR::Node *postorder(IR::PathExpression *expression) override;
142 const IR::Node *postorder(IR::MethodCallExpression *expression) override;
143};
144
145class NestedStructs final : public PassManager {
146 public:
147 explicit NestedStructs(TypeMap *typeMap, TypeChecking *typeChecking = nullptr) {
148 if (!typeChecking) typeChecking = new TypeChecking(nullptr, typeMap);
149 passes.push_back(typeChecking);
150 passes.push_back(new RemoveNestedStructs(typeMap));
151 passes.push_back(new ClearTypeMap(typeMap));
152 setName("NestedStructs");
153 }
154};
155
156} // namespace P4
157
158#endif /* MIDEND_NESTEDSTRUCTS_H_ */
Definition typeChecker.h:32
Definition nestedStructs.h:17
void explode(std::string_view prefix, const IR::Type_Struct *type, FieldsMap *map, IR::Vector< T > *result)
Flatten a nested struct to only contain field declaration or non-nested struct.
Definition nestedStructs.cpp:28
bool isNestedStruct(const IR::Type *type) const
Helper function that test if a struct is nested.
Definition nestedStructs.cpp:13
Definition stringify.h:33
The Declaration interface, representing objects with names.
Definition declaration.h:17
Definition indexed_vector.h:31
Definition node.h:53
Definition ir/vector.h:59
Definition referenceMap.h:36
Definition referenceMap.h:29
Definition nestedStructs.h:121
const IR::Node * postorder(IR::Declaration_Variable *decl) override
rewrite nested structs to non-nested structs
Definition nestedStructs.cpp:49
Definition visitor.h:442
Definition typeChecker.h:55
Definition typeMap.h:32
Definition visitor.h:78
Definition cstring.h:85
Definition ordered_map.h:32
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13
Definition nestedStructs.h:23
Definition id.h:28
T * to() noexcept
Definition rtti.h:226
Definition register_reference.h:28