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 "ir/ir.h"
23#include "lib/cstring.h"
24#include "lib/iterator_range.h"
25#include "referenceMap.h"
26
27namespace P4 {
28
30enum class ResolutionType { Any, Type, TypeVariable };
31
33class ResolutionContext : virtual public Visitor, public DeclarationLookup {
34 private:
35 // Returns a vector of the decls that exist in the given namespace, and caches the result
36 // for future lookups.
37 const std::vector<const IR::IDeclaration *> &memoizeDeclarations(
38 const IR::INamespace *ns) const;
39
40 using DeclsVector = absl::InlinedVector<const IR::IDeclaration *, 2>;
41 using NamespaceDeclsByName = absl::flat_hash_map<cstring, DeclsVector, Util::Hash>;
42
43 // Returns a mapping from name -> decl for the given namespace, and caches the result for
44 // future lookups.
45 NamespaceDeclsByName &memoizeDeclsByName(const IR::INamespace *ns) const;
46
47 mutable absl::flat_hash_map<const IR::INamespace *, std::vector<const IR::IDeclaration *>,
49 namespaceDecls;
50 mutable absl::flat_hash_map<const IR::INamespace *, NamespaceDeclsByName, Util::Hash>
51 namespaceDeclNames;
52
53 protected:
54 // Note that all errors have been merged by the parser into
55 // a single error { } namespace.
56 std::vector<const IR::IDeclaration *> lookup(const IR::INamespace *ns, const IR::ID &name,
57 ResolutionType type) const;
58
59 // match kinds exist in their own special namespace, made from all the match_kind
60 // declarations in the global scope. Unlike errors, we don't merge those scopes in
61 // the parser, so we have to find them and scan them here.
62 std::vector<const IR::IDeclaration *> lookupMatchKind(const IR::ID &name) const;
63
64 // P4_14 allows things to be used before their declaration while P4_16 (generally)
65 // does not, so we will resolve names to things declared later only when translating
66 // from P4_14 or Type_Vars or ParserStates, or after code transforms that may reorder
67 // the code.
68 bool anyOrder = false;
69
71 explicit ResolutionContext(bool ao) : anyOrder(ao) {}
72
75
76 public:
78 std::vector<const IR::IDeclaration *> resolve(const IR::ID &name, ResolutionType type) const;
79
81 const IR::IDeclaration *resolveUnique(const IR::ID &name, ResolutionType type,
82 const IR::INamespace * = nullptr) const;
83
86 virtual const IR::IDeclaration *resolvePath(const IR::Path *path, bool isType) const;
87
89 const IR::Type *resolveType(const IR::Type *type) const;
90
91 const IR::IDeclaration *getDeclaration(const IR::Path *path, bool notNull = false) const;
92 const IR::IDeclaration *getDeclaration(const IR::This *, bool notNull = false) const;
93
95 auto getDeclarations(const IR::INamespace *ns) const {
96 auto nsIt = namespaceDecls.find(ns);
97 const auto &decls = nsIt != namespaceDecls.end() ? nsIt->second : memoizeDeclarations(ns);
98 return Util::iterator_range(decls);
99 }
100
102 auto getDeclsByName(const IR::INamespace *ns, cstring name) const {
103 auto nsIt = namespaceDeclNames.find(ns);
104 const auto &namesToDecls =
105 nsIt != namespaceDeclNames.end() ? nsIt->second : memoizeDeclsByName(ns);
106
107 auto decls = namesToDecls.find(name);
108 if (decls == namesToDecls.end())
110 return Util::enumerate(decls->second);
111 }
112};
113
123 ReferenceMap *refMap;
124
126 bool checkShadow;
127
128 private:
131 const IR::IDeclaration *resolvePath(const IR::Path *path, bool isType) const override;
132
133 public:
134 explicit ResolveReferences(/* out */ P4::ReferenceMap *refMap, bool checkShadow = false);
135
136 Visitor::profile_t init_apply(const IR::Node *node) override;
137 void end_apply(const IR::Node *node) override;
138
139 bool preorder(const IR::Type_Name *type) override;
140 bool preorder(const IR::PathExpression *path) override;
141 bool preorder(const IR::KeyElement *path) override;
142 bool preorder(const IR::This *pointer) override;
143 bool preorder(const IR::Declaration_Instance *decl) override;
144
145 bool preorder(const IR::P4Program *t) override;
146 void postorder(const IR::P4Program *t) override;
147 bool preorder(const IR::P4Control *t) override;
148 bool preorder(const IR::P4Parser *t) override;
149 bool preorder(const IR::P4Action *t) override;
150 bool preorder(const IR::Function *t) override;
151 bool preorder(const IR::TableProperties *t) override;
152 bool preorder(const IR::Type_Method *t) override;
153 bool preorder(const IR::ParserState *t) override;
154 bool preorder(const IR::Type_Extern *t) override;
155 bool preorder(const IR::Type_ArchBlock *t) override;
156 void postorder(const IR::Type_ArchBlock *t) override;
157 bool preorder(const IR::Type_StructLike *t) override;
158 bool preorder(const IR::BlockStatement *t) override;
159
160 bool preorder(const IR::P4Table *table) override;
161 bool preorder(const IR::Declaration *d) override {
162 refMap->usedName(d->getName().name);
163 return true;
164 }
165 bool preorder(const IR::Type_Declaration *d) override {
166 refMap->usedName(d->getName().name);
167 return true;
168 }
169
170 void checkShadowing(const IR::INamespace *ns) const;
171};
172
173} // namespace P4
174
175#endif /* COMMON_RESOLVEREFERENCES_RESOLVEREFERENCES_H_ */
Definition referenceMap.h:57
The Declaration interface, representing objects with names.
Definition declaration.h:26
Definition node.h:95
Definition vector.h:58
Definition visitor.h:400
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
Visitor mixin for looking up names in enclosing scopes from the Visitor::Context.
Definition resolveReferences.h:33
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:102
auto getDeclarations(const IR::INamespace *ns) const
Returns the set of decls that exist in the given namespace.
Definition resolveReferences.h:95
virtual const IR::IDeclaration * resolvePath(const IR::Path *path, bool isType) const
Definition resolveReferences.cpp:311
const IR::Vector< IR::Argument > * methodArguments(cstring name) const
We are resolving a method call. Find the arguments from the context.
Definition resolveReferences.cpp:183
const IR::Type * resolveType(const IR::Type *type) const
Resolve a refrence to a type type.
Definition resolveReferences.cpp:298
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:223
Definition resolveReferences.h:121
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:30
Definition id.h:28
Definition hash.h:125