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
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 // Returns a mapping from name -> decl for the given namespace, and caches the result for
41 // future lookups.
42 std::unordered_multimap<cstring, const IR::IDeclaration *> &memoizeDeclsByName(
43 const IR::INamespace *ns) const;
44
45 mutable absl::flat_hash_map<const IR::INamespace *, std::vector<const IR::IDeclaration *>,
47 namespaceDecls;
48 mutable absl::flat_hash_map<const IR::INamespace *,
49 std::unordered_multimap<cstring, const IR::IDeclaration *>,
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;
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 auto &namesToDecls =
105 nsIt != namespaceDeclNames.end() ? nsIt->second : memoizeDeclsByName(ns);
106
107 auto decls = Values(namesToDecls.equal_range(name));
108 return Util::iterator_range(decls.begin(), decls.end());
109 }
110};
111
119class ResolveReferences : public Inspector, private ResolutionContext {
121 ReferenceMap *refMap;
122
124 bool checkShadow;
125
126 private:
129 const IR::IDeclaration *resolvePath(const IR::Path *path, bool isType) const override;
130
131 public:
132 explicit ResolveReferences(/* out */ P4::ReferenceMap *refMap, bool checkShadow = false);
133
134 Visitor::profile_t init_apply(const IR::Node *node) override;
135 void end_apply(const IR::Node *node) override;
136
137 bool preorder(const IR::Type_Name *type) override;
138 bool preorder(const IR::PathExpression *path) override;
139 bool preorder(const IR::KeyElement *path) override;
140 bool preorder(const IR::This *pointer) override;
141 bool preorder(const IR::Declaration_Instance *decl) override;
142
143 bool preorder(const IR::P4Program *t) override;
144 void postorder(const IR::P4Program *t) override;
145 bool preorder(const IR::P4Control *t) override;
146 bool preorder(const IR::P4Parser *t) override;
147 bool preorder(const IR::P4Action *t) override;
148 bool preorder(const IR::Function *t) override;
149 bool preorder(const IR::TableProperties *t) override;
150 bool preorder(const IR::Type_Method *t) override;
151 bool preorder(const IR::ParserState *t) override;
152 bool preorder(const IR::Type_Extern *t) override;
153 bool preorder(const IR::Type_ArchBlock *t) override;
154 void postorder(const IR::Type_ArchBlock *t) override;
155 bool preorder(const IR::Type_StructLike *t) override;
156 bool preorder(const IR::BlockStatement *t) override;
157
158 bool preorder(const IR::P4Table *table) override;
159 bool preorder(const IR::Declaration *d) override {
160 refMap->usedName(d->getName().name);
161 return true;
162 }
163 bool preorder(const IR::Type_Declaration *d) override {
164 refMap->usedName(d->getName().name);
165 return true;
166 }
167
168 void checkShadowing(const IR::INamespace *ns) const;
169};
170
171} // namespace P4
172
173#endif /* COMMON_RESOLVEREFERENCES_RESOLVEREFERENCES_H_ */
Definition externInstance.h:33
Definition referenceMap.h:57
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:292
const IR::Vector< IR::Argument > * methodArguments(cstring name) const
We are resolving a method call. Find the arguments from the context.
Definition resolveReferences.cpp:185
const IR::Type * resolveType(const IR::Type *type) const
Resolve a refrence to a type type.
Definition resolveReferences.cpp:279
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:215
Definition resolveReferences.h:119
Definition iterator_range.h:44
Definition cstring.h:72
Definition applyOptionsPragmas.cpp:24
ResolutionType
Helper class to indicate types of nodes that may be returned during resolution.
Definition resolveReferences.h:30
Definition hash.h:125