P4C
The P4 Compiler
Loading...
Searching...
No Matches
resolveReferences.h
1/*
2Copyright 2013-present Barefoot Networks, Inc.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17#ifndef COMMON_RESOLVEREFERENCES_RESOLVEREFERENCES_H_
18#define COMMON_RESOLVEREFERENCES_RESOLVEREFERENCES_H_
19
20#include "absl/container/flat_hash_map.h"
21#include "absl/container/inlined_vector.h"
22#include "frontends/common/parser_options.h"
23#include "ir/ir.h"
24#include "ir/pass_manager.h"
25#include "lib/cstring.h"
26#include "lib/iterator_range.h"
27#include "referenceMap.h"
28
29namespace P4 {
30
32enum class ResolutionType { Any, Type, TypeVariable };
33
35class ResolutionContext : virtual public Visitor, public DeclarationLookup {
36 private:
37 // Returns a vector of the decls that exist in the given namespace, and caches the result
38 // for future lookups.
39 const std::vector<const IR::IDeclaration *> &memoizeDeclarations(
40 const IR::INamespace *ns) const;
41
42 using DeclsVector = absl::InlinedVector<const IR::IDeclaration *, 2>;
43 using NamespaceDeclsByName = absl::flat_hash_map<cstring, DeclsVector, Util::Hash>;
44
45 // Returns a mapping from name -> decl for the given namespace, and caches the result for
46 // future lookups.
47 NamespaceDeclsByName &memoizeDeclsByName(const IR::INamespace *ns) const;
48
49 mutable absl::flat_hash_map<const IR::INamespace *, std::vector<const IR::IDeclaration *>,
51 namespaceDecls;
52 mutable absl::flat_hash_map<const IR::INamespace *, NamespaceDeclsByName, Util::Hash>
53 namespaceDeclNames;
54
55 protected:
56 // Note that all errors have been merged by the parser into
57 // a single error { } namespace.
58 std::vector<const IR::IDeclaration *> lookup(const IR::INamespace *ns, const IR::ID &name,
59 ResolutionType type) const;
60
61 // match kinds exist in their own special namespace, made from all the match_kind
62 // declarations in the global scope. Unlike errors, we don't merge those scopes in
63 // the parser, so we have to find them and scan them here.
64 std::vector<const IR::IDeclaration *> lookupMatchKind(const IR::ID &name) const;
65
66 // P4_14 allows things to be used before their declaration while P4_16 (generally)
67 // does not, so we will resolve names to things declared later only when translating
68 // from P4_14 or Type_Vars or ParserStates, or after code transforms that may reorder
69 // the code.
70 bool anyOrder = false;
71
73 explicit ResolutionContext(bool ao) : anyOrder(ao) {}
74
77
78 public:
80 std::vector<const IR::IDeclaration *> resolve(const IR::ID &name, ResolutionType type) const;
81
83 const IR::IDeclaration *resolveUnique(const IR::ID &name, ResolutionType type,
84 const IR::INamespace * = nullptr) const;
85
88 virtual const IR::IDeclaration *resolvePath(const IR::Path *path, bool isType) const;
89
91 const IR::Type *resolveType(const IR::Type *type) const;
92
93 const IR::IDeclaration *getDeclaration(const IR::Path *path, bool notNull = false) const;
94 const IR::IDeclaration *getDeclaration(const IR::This *, bool notNull = false) const;
95
97 auto getDeclarations(const IR::INamespace *ns) const {
98 auto nsIt = namespaceDecls.find(ns);
99 const auto &decls = nsIt != namespaceDecls.end() ? nsIt->second : memoizeDeclarations(ns);
100 return Util::iterator_range(decls);
101 }
102
104 auto getDeclsByName(const IR::INamespace *ns, cstring name) const {
105 auto nsIt = namespaceDeclNames.find(ns);
106 const auto &namesToDecls =
107 nsIt != namespaceDeclNames.end() ? nsIt->second : memoizeDeclsByName(ns);
108
109 auto decls = namesToDecls.find(name);
110 if (decls == namesToDecls.end())
112 return Util::enumerate(decls->second);
113 }
114};
115
125 ReferenceMap *refMap;
126
128 bool checkShadow;
129
130 private:
133 const IR::IDeclaration *resolvePath(const IR::Path *path, bool isType) const override;
134
135 public:
136 explicit ResolveReferences(/* out */ P4::ReferenceMap *refMap, bool checkShadow = false);
137
138 Visitor::profile_t init_apply(const IR::Node *node) override;
139 void end_apply(const IR::Node *node) override;
140
141 bool preorder(const IR::Type_Name *type) override;
142 bool preorder(const IR::PathExpression *path) override;
143 bool preorder(const IR::KeyElement *path) override;
144 bool preorder(const IR::This *pointer) override;
145 bool preorder(const IR::Declaration_Instance *decl) override;
146
147 bool preorder(const IR::P4Program *t) override;
148 void postorder(const IR::P4Program *t) override;
149 bool preorder(const IR::P4Control *t) override;
150 bool preorder(const IR::P4Parser *t) override;
151 bool preorder(const IR::P4Action *t) override;
152 bool preorder(const IR::Function *t) override;
153 bool preorder(const IR::TableProperties *t) override;
154 bool preorder(const IR::Type_Method *t) override;
155 bool preorder(const IR::ParserState *t) override;
156 bool preorder(const IR::Type_Extern *t) override;
157 bool preorder(const IR::Type_ArchBlock *t) override;
158 void postorder(const IR::Type_ArchBlock *t) override;
159 bool preorder(const IR::Type_StructLike *t) override;
160 bool preorder(const IR::BlockStatement *t) override;
161
162 bool preorder(const IR::P4Table *table) override;
163 bool preorder(const IR::Declaration *d) override {
164 refMap->usedName(d->getName().name);
165 return true;
166 }
167 bool preorder(const IR::Type_Declaration *d) override {
168 refMap->usedName(d->getName().name);
169 return true;
170 }
171
172 void checkShadowing(const IR::INamespace *ns) const;
173};
174
176 ReferenceMap refMap;
177
178 public:
180 refMap.setIsV1(P4CContext::get().options().isv1());
181
182 addPasses({new ResolveReferences(&refMap, /* checkShadow */ true)});
183 setName("CheckShadowing");
184 }
185};
186
187} // namespace P4
188
189#endif /* COMMON_RESOLVEREFERENCES_RESOLVEREFERENCES_H_ */
Definition resolveReferences.h:175
Definition referenceMap.h:57
The Declaration interface, representing objects with names.
Definition declaration.h:26
Definition node.h:94
Definition vector.h:59
Definition visitor.h:400
static P4CContext & get()
Definition parser_options.cpp:539
Definition ir/pass_manager.h:40
Class used to encode maps from paths to declarations.
Definition referenceMap.h:66
void usedName(cstring name)
Indicate that name is used in the program.
Definition referenceMap.h:121
void setIsV1(bool isv1)
Set boolean indicating whether map is for a P4_14 program to isV1.
Definition referenceMap.h:105
Visitor mixin for looking up names in enclosing scopes from the Visitor::Context.
Definition resolveReferences.h:35
std::vector< const IR::IDeclaration * > resolve(const IR::ID &name, ResolutionType type) const
Resolve references for name, restricted to type declarations.
Definition resolveReferences.cpp:48
auto getDeclsByName(const IR::INamespace *ns, cstring name) const
Returns the set of decls with the given name that exist in the given namespace.
Definition resolveReferences.h:104
auto getDeclarations(const IR::INamespace *ns) const
Returns the set of decls that exist in the given namespace.
Definition resolveReferences.h:97
virtual const IR::IDeclaration * resolvePath(const IR::Path *path, bool isType) const
Definition resolveReferences.cpp:312
const IR::Vector< IR::Argument > * methodArguments(cstring name) const
We are resolving a method call. Find the arguments from the context.
Definition resolveReferences.cpp:184
const IR::Type * resolveType(const IR::Type *type) const
Resolve a refrence to a type type.
Definition resolveReferences.cpp:299
const IR::IDeclaration * resolveUnique(const IR::ID &name, ResolutionType type, const IR::INamespace *=nullptr) const
Resolve reference for name, restricted to type declarations, and expect one result.
Definition resolveReferences.cpp:224
Definition resolveReferences.h:123
Type-erased Enumerator interface.
Definition enumerator.h:68
Definition iterator_range.h:44
Definition visitor.h:78
Definition visitor.h:75
Definition cstring.h:85
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
ResolutionType
Helper class to indicate types of nodes that may be returned during resolution.
Definition resolveReferences.h:32
Definition id.h:28
Definition hash.h:125