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
72 ResolutionContext();
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,
94 bool notNull = false) const override;
95 const IR::IDeclaration *getDeclaration(const IR::This *, bool notNull = false) const override;
96
98 auto getDeclarations(const IR::INamespace *ns) const {
99 auto nsIt = namespaceDecls.find(ns);
100 const auto &decls = nsIt != namespaceDecls.end() ? nsIt->second : memoizeDeclarations(ns);
101 return Util::iterator_range(decls);
102 }
103
105 auto getDeclsByName(const IR::INamespace *ns, cstring name) const {
106 auto nsIt = namespaceDeclNames.find(ns);
107 const auto &namesToDecls =
108 nsIt != namespaceDeclNames.end() ? nsIt->second : memoizeDeclsByName(ns);
109
110 auto decls = namesToDecls.find(name);
111 if (decls == namesToDecls.end())
112 return Util::Enumerator<const IR::IDeclaration *>::emptyEnumerator();
113 return Util::enumerate(decls->second);
114 }
115};
116
124class ResolveReferences : public Inspector, private ResolutionContext {
126 ReferenceMap *refMap;
127
129 bool checkShadow;
130
131 private:
134 const IR::IDeclaration *resolvePath(const IR::Path *path, bool isType) const override;
135
136 public:
137 explicit ResolveReferences(/* out */ P4::ReferenceMap *refMap, bool checkShadow = false);
138
139 Visitor::profile_t init_apply(const IR::Node *node) override;
140 void end_apply(const IR::Node *node) override;
141
142 bool preorder(const IR::Type_Name *type) override;
143 bool preorder(const IR::PathExpression *path) override;
144 bool preorder(const IR::KeyElement *path) override;
145 bool preorder(const IR::This *pointer) override;
146 bool preorder(const IR::Declaration_Instance *decl) override;
147
148 bool preorder(const IR::P4Program *t) override;
149 void postorder(const IR::P4Program *t) override;
150 bool preorder(const IR::P4Control *t) override;
151 bool preorder(const IR::P4Parser *t) override;
152 bool preorder(const IR::P4Action *t) override;
153 bool preorder(const IR::Function *t) override;
154 bool preorder(const IR::TableProperties *t) override;
155 bool preorder(const IR::Type_Method *t) override;
156 bool preorder(const IR::ParserState *t) override;
157 bool preorder(const IR::Type_Extern *t) override;
158 bool preorder(const IR::Type_ArchBlock *t) override;
159 void postorder(const IR::Type_ArchBlock *t) override;
160 bool preorder(const IR::Type_StructLike *t) override;
161 bool preorder(const IR::BlockStatement *t) override;
162
163 bool preorder(const IR::P4Table *table) override;
164 bool preorder(const IR::Declaration *d) override {
165 refMap->usedName(d->getName().name);
166 return true;
167 }
168 bool preorder(const IR::Type_Declaration *d) override {
169 refMap->usedName(d->getName().name);
170 return true;
171 }
172
173 void checkShadowing(const IR::INamespace *ns) const;
174};
175
176class CheckShadowing : public PassManager {
177 ReferenceMap refMap;
178
179 public:
180 CheckShadowing() {
181 refMap.setIsV1(P4CContext::get().options().isv1());
182
183 addPasses({new ResolveReferences(&refMap, /* checkShadow */ true)});
184 setName("CheckShadowing");
185 }
186};
187
188} // namespace P4
189
190#endif /* COMMON_RESOLVEREFERENCES_RESOLVEREFERENCES_H_ */
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:413
static P4CContext & get()
Definition parser_options.cpp:539
Class used to encode maps from paths to declarations.
Definition referenceMap.h:67
void setIsV1(bool isv1)
Set boolean indicating whether map is for a P4_14 program to isV1.
Definition referenceMap.h:106
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:105
auto getDeclarations(const IR::INamespace *ns) const
Returns the set of decls that exist in the given namespace.
Definition resolveReferences.h:98
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:124
Definition iterator_range.h:44
Definition visitor.h:78
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