P4C
The P4 Compiler
Loading...
Searching...
No Matches
namemap.h
1/*
2 * SPDX-FileCopyrightText: 2013 Barefoot Networks, Inc.
3 * Copyright 2013-present Barefoot Networks, Inc.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef IR_NAMEMAP_H_
9#define IR_NAMEMAP_H_
10
11#include <map>
12
13#include "ir/node.h"
14#include "lib/cstring.h"
15#include "lib/enumerator.h"
16#include "lib/error.h"
17#include "lib/exceptions.h"
18#include "lib/map.h"
19
20namespace P4 {
21class JSONLoader;
22} // namespace P4
23
24namespace P4::IR {
25
26template <class T, template <class K, class V, class COMP, class ALLOC> class MAP = std::map,
27 class COMP = std::less<cstring>,
28 class ALLOC = std::allocator<std::pair<const cstring, const T *>>>
29class NameMap : public Node {
30 typedef MAP<cstring, const T *, COMP, ALLOC> map_t;
31 map_t symbols;
32 /* if the object has a 'name' field, is it the same as name? */
33 template <class U>
34 auto match_name(cstring name, const U *obj) -> decltype(name == obj->name) {
35 return name == obj->name;
36 }
37 bool match_name(cstring, const void *) { return true; }
38 template <class U>
39 auto obj_name(const U *obj) -> decltype(obj->name) {
40 return obj->name;
41 }
42 cstring obj_name(const void *) { return nullptr; }
43
44 public:
45 NameMap() = default;
46 NameMap(const NameMap &) = default;
47 NameMap(NameMap &&) = default;
48 explicit NameMap(JSONLoader &);
49 NameMap &operator=(const NameMap &) = default;
50 NameMap &operator=(NameMap &&) = default;
51 typedef typename map_t::value_type value_type;
52 typedef typename map_t::iterator iterator;
53 typedef typename map_t::const_iterator const_iterator;
54 typedef typename map_t::reverse_iterator reverse_iterator;
55 typedef typename map_t::const_reverse_iterator const_reverse_iterator;
56
57 private:
58 struct elem_ref {
59 NameMap &self;
60 cstring name;
61 elem_ref(NameMap &s, cstring n) : self(s), name(n) {}
62 const T *operator=(const T *v) const {
63 if (!self.match_name(name, v)) BUG("Inserting into NameMap with incorrect name");
64 return self.symbols[name] = v;
65 }
66 operator const T *() const { return self.count(name) ? self.at(name) : nullptr; }
67 };
68
69 public:
70 const_iterator begin() const { return symbols.begin(); }
71 const_iterator end() const { return symbols.end(); }
72 iterator begin() { return symbols.begin(); }
73 iterator end() { return symbols.end(); }
74 // For multimaps
75 std::pair<const_iterator, const_iterator> equal_range(cstring key) const {
76 return symbols.equal_range(key);
77 }
78 const_reverse_iterator rbegin() const { return symbols.rbegin(); }
79 const_reverse_iterator rend() const { return symbols.rend(); }
80 reverse_iterator rbegin() { return symbols.rbegin(); }
81 reverse_iterator rend() { return symbols.rend(); }
82 size_t count(cstring name) const { return symbols.count(name); }
83 void clear() { symbols.clear(); }
84 size_t size() const { return symbols.size(); }
85 bool empty() const { return symbols.empty(); }
86 size_t erase(cstring n) { return symbols.erase(n); }
87 /* should be erase(const_iterator), but glibc++ std::list::erase is broken */
88 iterator erase(iterator p) { return symbols.erase(p); }
89 iterator erase(iterator f, iterator l) { return symbols.erase(f, l); }
90 const_iterator find(cstring name) const { return symbols.find(name); }
91 template <class U>
92 const U *get(cstring name) const {
93 for (auto it = symbols.find(name); it != symbols.end() && it->first == name; it++)
94 if (auto rv = it->second->template to<U>()) return rv;
95 return nullptr;
96 }
97 void add(cstring name, const T *n) {
98 if (!match_name(name, n)) BUG("Inserting into NameMap with incorrect name");
99 symbols.emplace(std::move(name), std::move(n));
100 }
101 // Expects to have a single node with each name.
102 // Only works for map and unordered_map
103 void addUnique(cstring name, const T *n) {
104 auto prev = symbols.find(name);
105 if (prev != symbols.end())
106 ::P4::error(ErrorType::ERR_DUPLICATE, "%1%: duplicated name (%2% is previous instance)",
107 n, prev->second);
108 symbols.emplace(std::move(name), std::move(n));
109 }
110 // Expects to have a single node with each name.
111 // Only works for map and unordered_map
112 const T *getUnique(cstring name) const {
113 auto it = symbols.find(name);
114 if (it == symbols.end()) return nullptr;
115 return it->second;
116 }
117 elem_ref operator[](cstring name) { return elem_ref(*this, name); }
118 const T *operator[](cstring name) const { return count(name) ? at(name) : nullptr; }
119 const T *&at(cstring name) { return symbols.at(name); }
120 const T *const &at(cstring name) const { return symbols.at(name); }
121 void check_null() const {
122 for (auto &e : symbols) CHECK_NULL(e.second);
123 }
124
125 IRNODE_SUBCLASS(NameMap)
126 bool operator==(const Node &a) const override { return a.operator==(*this); }
127 bool operator==(const NameMap &a) const { return symbols == a.symbols; }
128 bool equiv(const Node &a_) const override {
129 if (static_cast<const Node *>(this) == &a_) return true;
130 if (this->typeId() != a_.typeId()) return false;
131 auto &a = static_cast<const NameMap<T, MAP, COMP, ALLOC> &>(a_);
132 if (size() != a.size()) return false;
133 auto it = a.begin();
134 for (auto &el : *this)
135 if (el.first != it->first || !el.second->equiv(*(it++)->second)) return false;
136 return true;
137 }
138 cstring node_type_name() const override { return "NameMap<" + T::static_type_name() + ">"; }
139 static cstring static_type_name() { return "NameMap<" + T::static_type_name() + ">"; }
140 void visit_children(Visitor &v, const char *) override;
141 void visit_children(Visitor &v, const char *) const override;
142 void toJSON(JSONGenerator &json) const override;
143 static Node *fromJSON(JSONLoader &json);
144
145 Util::Enumerator<const T *> *valueEnumerator() const {
146 return Util::enumerate(Values(symbols));
147 }
148 template <typename S>
149 Util::Enumerator<const S *> *only() const {
150 return valueEnumerator()->template as<const S *>()->where(
151 [](const T *d) { return d != nullptr; });
152 }
153
154 DECLARE_TYPEINFO(NameMap, Node);
155};
156
157} // namespace P4::IR
158
159#endif /* IR_NAMEMAP_H_ */
const T & as() const
Tries to convert the class to type T. A BUG occurs if the cast fails.
Definition castable.h:33
Definition json_generator.h:30
Definition json_loader.h:32
Type-erased Enumerator interface.
Definition enumerator.h:60
Enumerator< T > * where(Filter filter)
Return an enumerator returning all elements that pass the filter.
Definition enumerator.h:577
Definition cstring.h:76
Definition constantParsing.h:13
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:49
Definition bson.cpp:69
T * to() noexcept
Definition rtti.h:226
virtual TypeId typeId() const noexcept=0