P4C
The P4 Compiler
Loading...
Searching...
No Matches
staticAssert.h
1/*
2 * Copyright 2022 VMware, Inc.
3 * SPDX-FileCopyrightText: 2022 VMware, Inc.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef FRONTENDS_P4_STATICASSERT_H_
9#define FRONTENDS_P4_STATICASSERT_H_
10
11#include "frontends/common/resolveReferences/resolveReferences.h"
12#include "frontends/p4/methodInstance.h"
13#include "frontends/p4/typeChecking/typeChecker.h"
14#include "ir/ir.h"
15
16namespace P4 {
17
18using namespace literals;
19
20const cstring staticAssertMethodName = "static_assert"_cs;
21
26class DoStaticAssert : public Transform, public ResolutionContext {
27 TypeMap *typeMap;
28 bool removeStatement = false;
29
30 public:
31 explicit DoStaticAssert(TypeMap *typeMap) : typeMap(typeMap) {
32 CHECK_NULL(typeMap);
33 setName("DoStaticAssert");
34 }
35 const IR::Node *postorder(IR::MethodCallExpression *method) override {
36 MethodInstance *mi = MethodInstance::resolve(method, this, typeMap);
37 if (auto ef = mi->to<ExternFunction>()) {
38 if (ef->method->name == staticAssertMethodName) {
39 auto subst = ef->substitution;
40 auto params = subst.getParametersInOrder();
41 if (!params->moveNext()) {
42 ::P4::warning(ErrorType::WARN_INVALID, "static_assert with no arguments: %1%",
43 method);
44 return method;
45 }
46 auto param = params->getCurrent();
47 CHECK_NULL(param);
48 auto arg = subst.lookup(param);
49 CHECK_NULL(arg);
50 if (auto bl = arg->expression->to<IR::BoolLiteral>()) {
51 if (!bl->value) {
52 std::string_view message = "static_assert failed";
53 if (params->moveNext()) {
54 param = params->getCurrent();
55 CHECK_NULL(param);
56 auto msg = subst.lookup(param);
57 CHECK_NULL(msg);
58 if (const auto *sl = msg->expression->to<IR::StringLiteral>()) {
59 message = sl->value;
60 }
61 }
62 ::P4::error(ErrorType::ERR_EXPECTED, "%1%: %2%", method, message);
63 return method;
64 }
65 if (getContext()->node->is<IR::MethodCallStatement>()) {
66 removeStatement = true;
67 return method;
68 }
69 return new IR::BoolLiteral(method->srcInfo, true);
70 } else {
71 ::P4::error(ErrorType::ERR_UNEXPECTED,
72 "Could not evaluate static_assert to a constant: %1%", arg);
73 return method;
74 }
75 }
76 }
77 return method;
78 }
79
80 const IR::Node *postorder(IR::MethodCallStatement *statement) override {
81 if (removeStatement) {
82 removeStatement = false;
83 return nullptr;
84 }
85 return statement;
86 }
87};
88
89class StaticAssert : public PassManager {
90 public:
91 explicit StaticAssert(TypeMap *typeMap) {
92 passes.push_back(new ReadOnlyTypeInference(typeMap));
93 passes.push_back(new DoStaticAssert(typeMap));
94 setName("StaticAssert");
95 }
96};
97
98} // namespace P4
99
100#endif /* FRONTENDS_P4_STATICASSERT_H_ */
Definition staticAssert.h:26
Definition methodInstance.h:194
Definition node.h:53
Definition methodInstance.h:56
static MethodInstance * resolve(const IR::MethodCallExpression *mce, const DeclarationLookup *refMap, TypeMap *typeMap, bool useExpressionType=false, const Visitor::Context *ctxt=nullptr, bool incomplete=false)
Definition methodInstance.cpp:27
Definition typeChecker.h:354
Definition visitor.h:442
Definition typeMap.h:32
Definition cstring.h:85
Definition cstring.h:80
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13
void warning(const char *format, Args &&...args)
Report a warning with the given message.
Definition lib/error.h:128
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:58
T * to() noexcept
Definition rtti.h:226