P4C
The P4 Compiler
Loading...
Searching...
No Matches
lib/error.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/* -*-C++-*- */
18
19#ifndef LIB_ERROR_H_
20#define LIB_ERROR_H_
21
22#include <type_traits>
23
24#include "lib/compile_context.h"
25#include "lib/cstring.h"
26#include "lib/error_reporter.h"
27
28// This should eventually be turned to 0 when all the code is converted
29#define LEGACY 1
30
31namespace P4 {
32
34inline unsigned errorCount() { return BaseCompileContext::get().errorReporter().getErrorCount(); }
35
37inline unsigned warningCount() {
38 return BaseCompileContext::get().errorReporter().getWarningCount();
39}
40
42inline unsigned infoCount() { return BaseCompileContext::get().errorReporter().getInfoCount(); }
43
49
50// Errors, warnings, and infos are specified using boost::format format strings, i.e.,
51// %1%, %2%, etc (starting at 1, not at 0).
52// Some compatibility for printf-style arguments is also supported.
53
55// LEGACY: once we transition to error types, this should be deprecated
56#if LEGACY
57template <typename... Args>
58inline void error(const char *format, Args &&...args) {
59 auto &context = BaseCompileContext::get();
60 auto action = context.getDefaultErrorDiagnosticAction();
61 context.errorReporter().diagnose(action, nullptr, format, "", std::forward<Args>(args)...);
62}
63#endif
64
67template <class T, typename = std::enable_if_t<Util::has_SourceInfo_v<T>>, class... Args>
68void error(const int kind, const char *format, const T *node, Args &&...args) {
69 auto &context = BaseCompileContext::get();
70 auto action = context.getDefaultErrorDiagnosticAction();
71 context.errorReporter().diagnose(action, kind, format, "", node, std::forward<Args>(args)...);
72}
73
75template <class T, typename = std::enable_if_t<Util::has_SourceInfo_v<T>>, class... Args>
76void errorWithSuffix(const int kind, const char *format, const char *suffix, const T *node,
77 Args &&...args) {
78 auto &context = BaseCompileContext::get();
79 auto action = context.getDefaultErrorDiagnosticAction();
80 context.errorReporter().diagnose(action, kind, format, suffix, node,
81 std::forward<Args>(args)...);
82}
83
85template <class T, typename = std::enable_if_t<Util::has_SourceInfo_v<T> && !std::is_pointer_v<T>>,
86 class... Args>
87void error(const int kind, const char *format, const T &node, Args &&...args) {
88 error(kind, format, &node, std::forward<Args>(args)...);
89}
90
91#if LEGACY
95// LEGACY: once we transition to error types, this should be deprecated
96template <class T, typename = std::enable_if_t<Util::has_SourceInfo_v<T>>, class... Args>
97void error(const char *format, const T *node, Args &&...args) {
98 error(ErrorType::LEGACY_ERROR, format, node, std::forward<Args>(args)...);
99}
100
102// LEGACY: once we transition to error types, this should be deprecated
103template <class T, typename = std::enable_if_t<Util::has_SourceInfo_v<T> && !std::is_pointer_v<T>>,
104 class... Args>
105void error(const char *format, const T &node, Args &&...args) {
106 error(ErrorType::LEGACY_ERROR, format, node, std::forward<Args>(args)...);
107}
108#endif
109
112template <typename... Args>
113void error(const int kind, const char *format, Args &&...args) {
114 auto &context = BaseCompileContext::get();
115 auto action = context.getDefaultErrorDiagnosticAction();
116 context.errorReporter().diagnose(action, kind, format, "", std::forward<Args>(args)...);
117}
118
120#define ERROR_CHECK(e, ...) \
121 do { \
122 if (!(e)) ::P4::error(__VA_ARGS__); \
123 } while (0)
124
125#if LEGACY
127template <typename... Args>
128inline void warning(const char *format, Args &&...args) {
129 auto &context = BaseCompileContext::get();
130 auto action = context.getDefaultWarningDiagnosticAction();
131 context.errorReporter().diagnose(action, nullptr, format, "", std::forward<Args>(args)...);
132}
133#endif
134
136template <class T, typename = std::enable_if_t<Util::has_SourceInfo_v<T>>, class... Args>
137void warning(const int kind, const char *format, const T *node, Args &&...args) {
138 auto &context = BaseCompileContext::get();
139 auto action = context.getDefaultWarningDiagnosticAction();
140 context.errorReporter().diagnose(action, kind, format, "", node, std::forward<Args>(args)...);
141}
142
144template <class T, typename = std::enable_if_t<Util::has_SourceInfo_v<T> && !std::is_pointer_v<T>>,
145 class... Args>
146void warning(const int kind, const char *format, const T &node, Args &&...args) {
147 ::P4::warning(kind, format, &node, std::forward<Args>(args)...);
148}
149
152template <typename... Args>
153void warning(const int kind, const char *format, Args &&...args) {
154 auto &context = BaseCompileContext::get();
155 auto action = context.getDefaultWarningDiagnosticAction();
156 context.errorReporter().diagnose(action, kind, format, "", std::forward<Args>(args)...);
157}
158
160#define WARN_CHECK(e, ...) \
161 do { \
162 if (!(e)) ::P4::warning(__VA_ARGS__); \
163 } while (0)
164
166template <class T, typename = std::enable_if_t<Util::has_SourceInfo_v<T>>, class... Args>
167void info(const int kind, const char *format, const T *node, Args &&...args) {
168 auto &context = BaseCompileContext::get();
169 auto action = context.getDefaultInfoDiagnosticAction();
170 context.errorReporter().diagnose(action, kind, format, "", node, std::forward<Args>(args)...);
171}
172
174template <class T, typename = std::enable_if_t<Util::has_SourceInfo_v<T> && !std::is_pointer_v<T>>,
175 class... Args>
176void info(const int kind, const char *format, const T &node, Args &&...args) {
177 ::P4::info(kind, format, &node, std::forward<Args>(args)...);
178}
179
182template <typename... Args>
183void info(const int kind, const char *format, Args &&...args) {
184 auto &context = BaseCompileContext::get();
185 auto action = context.getDefaultInfoDiagnosticAction();
186 context.errorReporter().diagnose(action, kind, format, "", std::forward<Args>(args)...);
187}
188
189} // namespace P4
190
191#endif /* LIB_ERROR_H_ */
virtual ErrorReporter & errorReporter()
Definition compile_context.cpp:65
static BaseCompileContext & get()
Definition compile_context.cpp:61
unsigned getDiagnosticCount() const
Definition error_reporter.h:187
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
void warning(const char *format, Args &&...args)
Report a warning with the given message.
Definition lib/error.h:128
unsigned infoCount()
Definition lib/error.h:42
unsigned diagnosticCount()
Definition lib/error.h:46
unsigned warningCount()
Definition lib/error.h:37
void errorWithSuffix(const int kind, const char *format, const char *suffix, const T *node, Args &&...args)
This is similar to the above method, but also has a suffix.
Definition lib/error.h:76
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:58
void info(const int kind, const char *format, const T *node, Args &&...args)
Report info messages of type kind. Requires that the node argument have source info.
Definition lib/error.h:167
unsigned errorCount()
Definition lib/error.h:34