P4C
The P4 Compiler
Loading...
Searching...
No Matches
lib/exceptions.h
1/*
2 * SPDX-FileCopyrightText: 2013 Barefoot Networks, Inc.
3 * Copyright 2013-present Barefoot Networks, Inc.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8/* -*-c++-*- */
9
10#ifndef LIB_EXCEPTIONS_H_
11#define LIB_EXCEPTIONS_H_
12
13#include <unistd.h>
14
15#include <exception>
16#include <string>
17#include <utility>
18
19#include "absl/strings/str_cat.h"
20#include "lib/format.h"
21
22namespace P4::Util {
23
24// colors to pretty print messages
25constexpr char ANSI_RED[] = "\33[31m";
26constexpr char ANSI_BLUE[] = "\33[34m";
27constexpr char ANSI_CLR[] = "\33[0m";
28
31inline bool is_cerr_redirected() {
32 static bool initialized(false);
33 static bool is_redir;
34 if (!initialized) {
35 initialized = true;
36 is_redir = ttyname(fileno(stderr)) == nullptr; // NOLINT(runtime/threadsafe_fn)
37 }
38 return is_redir;
39}
40
42inline const char *cerr_colorize(const char *color) {
43 if (is_cerr_redirected()) {
44 return "";
45 }
46 return color;
47}
48
50inline const char *cerr_clear_colors() {
51 if (is_cerr_redirected()) {
52 return "";
53 }
54 return ANSI_CLR;
55}
56
60class P4CExceptionBase : public std::exception {
61 protected:
62 std::string message;
63 void traceCreation() {}
64
65 public:
67 explicit P4CExceptionBase(std::string formattedMessage) : message(std::move(formattedMessage)) {
68 traceCreation();
69 }
70
71 template <typename... Args>
72 explicit P4CExceptionBase(const char *format, Args &&...args) {
73 traceCreation();
74 message = createBugMessage(format, args...);
75 }
76
77 [[nodiscard]] const char *what() const noexcept override { return message.c_str(); }
78};
79
81class CompilerBug final : public P4CExceptionBase {
82 public:
84 explicit CompilerBug(std::string formattedMessage)
85 : P4CExceptionBase(std::move(formattedMessage)) {
86 // Check if output is redirected and if so, then don't color text so that
87 // escape characters are not present
88 message = absl::StrCat(cerr_colorize(ANSI_RED), "Compiler Bug", cerr_clear_colors(), ":\n",
89 message);
90 }
91
92 template <typename... Args>
93 explicit CompilerBug(const char *format, Args &&...args)
94 : CompilerBug(createBugMessage(format, args...)) {}
95
96 template <typename... Args>
97 CompilerBug(int line, const char *file, const char *format, Args &&...args)
98 : P4CExceptionBase(format, std::forward<Args>(args)...) {
99 message = absl::StrCat("In file: ", file, ":", line, "\n", cerr_colorize(ANSI_RED),
100 "Compiler Bug", cerr_clear_colors(), ": ", message);
101 }
102};
103
105class CompilerUnimplemented final : public P4CExceptionBase {
106 public:
107 template <typename... Args>
108 explicit CompilerUnimplemented(const char *format, Args &&...args)
109 : P4CExceptionBase(format, std::forward<Args>(args)...) {
110 // Do not add colors when redirecting to stderr
111 message = absl::StrCat(cerr_colorize(ANSI_BLUE), "Not yet implemented", cerr_clear_colors(),
112 ":\n", message);
113 }
114
115 template <typename... Args>
116 CompilerUnimplemented(int line, const char *file, const char *format, Args &&...args)
117 : P4CExceptionBase(format, std::forward<Args>(args)...) {
118 message =
119 absl::StrCat("In file: ", file, ":", line, "\n", cerr_colorize(ANSI_BLUE),
120 "Unimplemented compiler support", cerr_clear_colors(), ": ", message);
121 }
122};
123
126class CompilationError : public P4CExceptionBase {
127 public:
128 template <typename... Args>
129 explicit CompilationError(const char *format, Args &&...args)
130 : P4CExceptionBase(format, std::forward<Args>(args)...) {}
131};
132
134#define BUG(...) \
135 do { \
136 throw P4::Util::CompilerBug(__LINE__, __FILE__, __VA_ARGS__); \
137 } while (0)
138#define BUG_CHECK(e, ...) \
139 do { \
140 if (!(e)) BUG(__VA_ARGS__); \
141 } while (0)
142#define P4C_UNIMPLEMENTED(...) \
143 do { \
144 throw P4::Util::CompilerUnimplemented(__LINE__, __FILE__, __VA_ARGS__); \
145 } while (0)
146
147} // namespace P4::Util
148
150#define FATAL_ERROR(...) \
151 do { \
152 throw P4::Util::CompilationError(__VA_ARGS__); \
153 } while (0)
154
155#endif /* LIB_EXCEPTIONS_H_ */
This class indicates a bug in the compiler.
Definition lib/exceptions.h:81
CompilerBug(std::string formattedMessage)
Also usable when the diagnostic formatter itself fails.
Definition lib/exceptions.h:84
P4CExceptionBase(std::string formattedMessage)
Use already-formatted text without invoking the diagnostic formatter.
Definition lib/exceptions.h:67
STL namespace.