P4C
The P4 Compiler
 
Loading...
Searching...
No Matches
methodInstance.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 FRONTENDS_P4_METHODINSTANCE_H_
18#define FRONTENDS_P4_METHODINSTANCE_H_
19
20#include "frontends/common/resolveReferences/referenceMap.h"
21#include "frontends/p4/parameterSubstitution.h"
22#include "frontends/p4/typeMap.h"
23#include "ir/ir.h"
24
25namespace P4 {
26
27class InstanceBase : public ICastable {
28 protected:
29 virtual ~InstanceBase() {}
30
31 public:
37
38 DECLARE_TYPEINFO(InstanceBase);
39};
40
57 protected:
58 MethodInstance(const IR::MethodCallExpression *mce, const IR::IDeclaration *decl,
59 const IR::Type_MethodBase *originalMethodType,
60 const IR::Type_MethodBase *actualMethodType)
61 : expr(mce),
62 object(decl),
65 CHECK_NULL(mce);
66 CHECK_NULL(originalMethodType);
67 CHECK_NULL(actualMethodType);
68 }
69
70 void bindParameters() {
71 auto params = getActualParameters();
72 substitution.populate(params, expr->arguments);
73 }
74
75 public:
76 const IR::MethodCallExpression *expr;
79 const IR::IDeclaration *object;
82 const IR::Type_MethodBase *originalMethodType;
85 const IR::Type_MethodBase *actualMethodType;
86 virtual bool isApply() const { return false; }
87
94 static MethodInstance *resolve(const IR::MethodCallExpression *mce, DeclarationLookup *refMap,
95 TypeMap *typeMap, bool useExpressionType = false,
96 const Visitor::Context *ctxt = nullptr, bool incomplete = false);
97 static MethodInstance *resolve(const IR::MethodCallExpression *mce, DeclarationLookup *refMap,
98 TypeMap *typeMap, const Visitor::Context *ctxt,
99 bool incomplete = false) {
100 return resolve(mce, refMap, typeMap, false, ctxt, incomplete);
101 }
102 static MethodInstance *resolve(const IR::MethodCallStatement *mcs, DeclarationLookup *refMap,
103 TypeMap *typeMap, const Visitor::Context *ctxt = nullptr) {
104 return resolve(mcs->methodCall, refMap, typeMap, false, ctxt, false);
105 }
106 static MethodInstance *resolve(const IR::MethodCallExpression *mce, DeclarationLookup *refMap,
107 const Visitor::Context *ctxt = nullptr) {
108 return resolve(mce, refMap, nullptr, true, ctxt, false);
109 }
110 static MethodInstance *resolve(const IR::MethodCallStatement *mcs, DeclarationLookup *refMap,
111 const Visitor::Context *ctxt = nullptr) {
112 return resolve(mcs->methodCall, refMap, nullptr, true, ctxt, false);
113 }
114 const IR::ParameterList *getOriginalParameters() const {
115 return originalMethodType->parameters;
116 }
117 const IR::ParameterList *getActualParameters() const { return actualMethodType->parameters; }
118
119 DECLARE_TYPEINFO(MethodInstance, InstanceBase);
120};
121
124class ApplyMethod final : public MethodInstance {
125 ApplyMethod(const IR::MethodCallExpression *expr, const IR::IDeclaration *decl,
126 const IR::IApply *applyObject)
127 : MethodInstance(expr, decl, applyObject->getApplyMethodType(),
128 applyObject->getApplyMethodType()),
129 applyObject(applyObject) {
130 CHECK_NULL(applyObject);
131 bindParameters();
132 }
133 friend class MethodInstance;
134
135 public:
136 const IR::IApply *applyObject;
137 bool isApply() const override { return true; }
138 bool isTableApply() const { return object->is<IR::P4Table>(); }
139
140 DECLARE_TYPEINFO(ApplyMethod, MethodInstance);
141};
142
144class ExternMethod final : public MethodInstance {
145 ExternMethod(const IR::MethodCallExpression *expr, const IR::IDeclaration *decl,
146 const IR::Method *method, const IR::Type_Extern *originalExternType,
147 const IR::Type_Method *originalMethodType, const IR::Type_Extern *actualExternType,
148 const IR::Type_Method *actualMethodType, bool incomplete)
150 method(method),
151 originalExternType(originalExternType),
152 actualExternType(actualExternType) {
153 CHECK_NULL(method);
154 CHECK_NULL(originalExternType);
155 CHECK_NULL(actualExternType);
156 bindParameters();
157 if (!incomplete)
158 typeSubstitution.setBindings(expr, method->type->typeParameters, expr->typeArguments);
159 }
160 friend class MethodInstance;
161
162 public:
163 const IR::Method *method;
164 const IR::Type_Extern *originalExternType; // type of object method is applied to
165 const IR::Type_Extern *actualExternType; // with type variables substituted
166
168 // If this method is abstract, will consist of (just) the concrete implementation,
169 // otherwise will consist of those methods that are @synchronous with this
170 std::vector<const IR::IDeclaration *> mayCall() const;
171
172 DECLARE_TYPEINFO(ExternMethod, MethodInstance);
173};
174
176class ExternFunction final : public MethodInstance {
177 ExternFunction(const IR::MethodCallExpression *expr, const IR::Method *method,
178 const IR::Type_Method *originalMethodType,
179 const IR::Type_Method *actualMethodType, bool incomplete)
180 : MethodInstance(expr, nullptr, originalMethodType, actualMethodType), method(method) {
181 CHECK_NULL(method);
182 bindParameters();
183 if (!incomplete)
184 typeSubstitution.setBindings(expr, method->type->typeParameters, expr->typeArguments);
185 }
186 friend class MethodInstance;
187
188 public:
189 const IR::Method *method;
190
191 DECLARE_TYPEINFO(ExternFunction, MethodInstance);
192};
193
198class ActionCall final : public MethodInstance {
199 ActionCall(const IR::MethodCallExpression *expr, const IR::P4Action *action,
200 const IR::Type_Action *actionType)
201 : // Actions are never generic
202 MethodInstance(expr, nullptr, actionType, actionType),
203 action(action) {
204 CHECK_NULL(action);
205 bindParameters();
206 }
207 friend class MethodInstance;
208
209 public:
210 const IR::P4Action *action;
213 const IR::P4Action *specialize(ReferenceMap *refMap) const;
214
215 DECLARE_TYPEINFO(ActionCall, MethodInstance);
216};
217
221class FunctionCall final : public MethodInstance {
222 FunctionCall(const IR::MethodCallExpression *expr, const IR::Function *function,
223 const IR::Type_Method *originalMethodType, const IR::Type_Method *actualMethodType,
224 bool incomplete)
225 : MethodInstance(expr, nullptr, originalMethodType, actualMethodType), function(function) {
226 CHECK_NULL(function);
227 bindParameters();
228 if (!incomplete)
229 typeSubstitution.setBindings(function, function->type->typeParameters,
230 expr->typeArguments);
231 }
232 friend class MethodInstance;
233
234 public:
235 const IR::Function *function;
236
237 DECLARE_TYPEINFO(FunctionCall, MethodInstance);
238};
239
249class BuiltInMethod final : public MethodInstance {
250 friend class MethodInstance;
251 BuiltInMethod(const IR::MethodCallExpression *expr, IR::ID name,
252 const IR::Expression *appliedTo, const IR::Type_Method *methodType)
253 : MethodInstance(expr, nullptr, methodType, methodType), name(name), appliedTo(appliedTo) {
254 CHECK_NULL(appliedTo);
255 bindParameters();
256 }
257
258 public:
259 const IR::ID name;
260 const IR::Expression *appliedTo; // object is an expression
261
262 DECLARE_TYPEINFO(BuiltInMethod, MethodInstance);
263};
264
266
274 protected:
275 virtual ~ConstructorCall() {}
276 explicit ConstructorCall(const IR::ConstructorCallExpression *cce) : cce(cce) {
277 CHECK_NULL(cce);
278 }
279
280 public:
281 const IR::ConstructorCallExpression *cce = nullptr;
282 const IR::Vector<IR::Type> *typeArguments = nullptr;
283 const IR::ParameterList *constructorParameters = nullptr;
284 static ConstructorCall *resolve(const IR::ConstructorCallExpression *cce,
285 DeclarationLookup *refMap, TypeMap *typeMap);
286 DECLARE_TYPEINFO(ConstructorCall, InstanceBase);
287};
288
291 explicit ExternConstructorCall(const IR::ConstructorCallExpression *cce,
292 const IR::Type_Extern *type, const IR::Method *constructor)
293 : ConstructorCall(cce), type(type), constructor(constructor) {
294 CHECK_NULL(type);
295 CHECK_NULL(constructor);
296 }
297 friend class ConstructorCall;
298
299 public:
300 const IR::Type_Extern *type; // actual extern declaration in program IR
301 const IR::Method *constructor; // that is being invoked
302
303 DECLARE_TYPEINFO(ExternConstructorCall, ConstructorCall);
304};
305
309 explicit ContainerConstructorCall(const IR::ConstructorCallExpression *cce,
310 const IR::IContainer *cont)
311 : ConstructorCall(cce), container(cont) {
312 CHECK_NULL(cont);
313 }
314 friend class ConstructorCall;
315
316 public:
317 const IR::IContainer *container; // actual container in program IR
318
319 DECLARE_TYPEINFO(ContainerConstructorCall, ConstructorCall);
320};
321
323
326 protected:
327 void substitute() {
328 substitution.populate(constructorParameters, constructorArguments);
329 typeSubstitution.setBindings(instance, typeParameters, typeArguments);
330 }
331
332 public:
333 Instantiation(const IR::Declaration_Instance *instance,
334 const IR::Vector<IR::Type> *typeArguments)
335 : instance(instance), typeArguments(typeArguments) {
336 CHECK_NULL(instance);
337 constructorArguments = instance->arguments;
338 }
339
340 const IR::Declaration_Instance *instance;
341 const IR::Vector<IR::Type> *typeArguments;
342 const IR::Vector<IR::Argument> *constructorArguments;
343 const IR::ParameterList *constructorParameters = nullptr;
344 const IR::TypeParameters *typeParameters = nullptr;
345
346 static Instantiation *resolve(const IR::Declaration_Instance *instance,
347 DeclarationLookup *refMap, TypeMap *typeMap);
348
349 DECLARE_TYPEINFO(Instantiation, InstanceBase);
350};
351
353 public:
354 ExternInstantiation(const IR::Declaration_Instance *instance,
355 const IR::Vector<IR::Type> *typeArguments, const IR::Type_Extern *type)
356 : Instantiation(instance, typeArguments), type(type) {
357 auto constructor = type->lookupConstructor(constructorArguments);
358 BUG_CHECK(constructor, "%1%: could not find constructor", type);
359 constructorParameters = constructor->type->parameters;
360 typeParameters = type->typeParameters;
361 substitute();
362 }
363 const IR::Type_Extern *type;
364
365 DECLARE_TYPEINFO(ExternInstantiation, Instantiation);
366};
367
369 public:
370 PackageInstantiation(const IR::Declaration_Instance *instance,
371 const IR::Vector<IR::Type> *typeArguments, const IR::Type_Package *package)
372 : Instantiation(instance, typeArguments), package(package) {
373 constructorParameters = package->getConstructorParameters();
374 typeParameters = package->typeParameters;
375 substitute();
376 }
377 const IR::Type_Package *package;
378
379 DECLARE_TYPEINFO(PackageInstantiation, Instantiation);
380};
381
383 public:
384 ParserInstantiation(const IR::Declaration_Instance *instance,
385 const IR::Vector<IR::Type> *typeArguments, const IR::P4Parser *parser)
386 : Instantiation(instance, typeArguments), parser(parser) {
387 typeParameters = parser->type->typeParameters;
388 constructorParameters = parser->getConstructorParameters();
389 substitute();
390 }
391 const IR::P4Parser *parser;
392
393 DECLARE_TYPEINFO(ParserInstantiation, Instantiation);
394};
395
397 public:
398 ControlInstantiation(const IR::Declaration_Instance *instance,
399 const IR::Vector<IR::Type> *typeArguments, const IR::P4Control *control)
400 : Instantiation(instance, typeArguments), control(control) {
401 typeParameters = control->type->typeParameters;
402 constructorParameters = control->getConstructorParameters();
403 substitute();
404 }
405 const IR::P4Control *control;
406
407 DECLARE_TYPEINFO(ControlInstantiation, Instantiation);
408};
409
410} // namespace P4
411
412#endif /* FRONTENDS_P4_METHODINSTANCE_H_ */
Definition castable.h:34
Definition externInstance.h:33
Definition methodInstance.h:198
const IR::P4Action * specialize(ReferenceMap *refMap) const
Definition methodInstance.cpp:126
Definition methodInstance.h:124
Definition methodInstance.h:249
Definition methodInstance.h:273
Definition methodInstance.h:308
Definition methodInstance.h:396
Definition referenceMap.h:57
Definition methodInstance.h:290
Definition methodInstance.h:176
Definition methodInstance.h:352
Definition methodInstance.h:144
std::vector< const IR::IDeclaration * > mayCall() const
Set of IR::Method and IR::Function objects that may be called by this method.
Definition methodInstance.cpp:198
Definition methodInstance.h:221
Definition methodInstance.h:27
TypeVariableSubstitution typeSubstitution
Definition methodInstance.h:36
ParameterSubstitution substitution
For each callee parameter the corresponding argument.
Definition methodInstance.h:33
Used to resolve a Declaration_Instance.
Definition methodInstance.h:325
Definition methodInstance.h:56
const IR::Type_MethodBase * actualMethodType
Definition methodInstance.h:85
static MethodInstance * resolve(const IR::MethodCallExpression *mce, DeclarationLookup *refMap, TypeMap *typeMap, bool useExpressionType=false, const Visitor::Context *ctxt=nullptr, bool incomplete=false)
Definition methodInstance.cpp:26
const IR::Type_MethodBase * originalMethodType
Definition methodInstance.h:82
const IR::IDeclaration * object
Definition methodInstance.h:79
Definition methodInstance.h:368
Definition parameterSubstitution.h:31
void populate(const IR::ParameterList *params, const IR::Vector< IR::Argument > *args)
Definition parameterSubstitution.cpp:34
Definition methodInstance.h:382
Class used to encode maps from paths to declarations.
Definition referenceMap.h:66
Definition typeMap.h:42
Definition typeSubstitution.h:73
Definition applyOptionsPragmas.cpp:24
bool is() const noexcept
Definition rtti.h:216