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
17#include <boost/format.hpp>
18
19#include "absl/strings/str_cat.h"
20#include "lib/bug_helper.h"
21
22namespace P4::Util {
23
24// colors to pretty print messages
25// \e is non-standard escape sequence, use codepoint \33 instead
26constexpr char ANSI_RED[] = "\33[31m";
27constexpr char ANSI_BLUE[] = "\33[34m";
28constexpr char ANSI_CLR[] = "\33[0m";
29
32inline bool is_cerr_redirected() {
33 static bool initialized(false);
34 static bool is_redir;
35 if (!initialized) {
36 initialized = true;
37 is_redir = ttyname(fileno(stderr)) == nullptr; // NOLINT(runtime/threadsafe_fn)
38 }
39 return is_redir;
40}
41
43inline const char *cerr_colorize(const char *color) {
44 if (is_cerr_redirected()) {
45 return "";
46 }
47 return color;
48}
49
51inline const char *cerr_clear_colors() {
52 if (is_cerr_redirected()) {
53 return "";
54 }
55 return ANSI_CLR;
56}
57
61class P4CExceptionBase : public std::exception {
62 protected:
63 std::string message;
64 void traceCreation() {}
65
66 public:
67 template <typename... Args>
68 explicit P4CExceptionBase(const char *format, Args &&...args) {
69 traceCreation();
70 boost::format fmt(format);
71 // FIXME: This will implicitly take location of the first argument having
72 // SourceInfo. Not sure if this always desireable or not.
73 message = ::P4::bug_helper(fmt, "", "", std::forward<Args>(args)...);
74 }
75
76 const char *what() const noexcept override { return message.c_str(); }
77};
78
80class CompilerBug final : public P4CExceptionBase {
81 public:
82 template <typename... Args>
83 explicit CompilerBug(const char *format, Args &&...args)
84 : P4CExceptionBase(format, std::forward<Args>(args)...) {
85 // Check if output is redirected and if so, then don't color text so that
86 // escape characters are not present
87 message = absl::StrCat(cerr_colorize(ANSI_RED), "Compiler Bug", cerr_clear_colors(), ":\n",
88 message);
89 }
90
91 template <typename... Args>
92 CompilerBug(int line, const char *file, const char *format, Args &&...args)
93 : P4CExceptionBase(format, std::forward<Args>(args)...) {
94 message = absl::StrCat("In file: ", file, ":", line, "\n", cerr_colorize(ANSI_RED),
95 "Compiler Bug", cerr_clear_colors(), ": ", message);
96 }
97};
98
100class CompilerUnimplemented final : public P4CExceptionBase {
101 public:
102 template <typename... Args>
103 explicit CompilerUnimplemented(const char *format, Args &&...args)
104 : P4CExceptionBase(format, std::forward<Args>(args)...) {
105 // Do not add colors when redirecting to stderr
106 message = absl::StrCat(cerr_colorize(ANSI_BLUE), "Not yet implemented", cerr_clear_colors(),
107 ":\n", message);
108 }
109
110 template <typename... Args>
111 CompilerUnimplemented(int line, const char *file, const char *format, Args &&...args)
112 : P4CExceptionBase(format, std::forward<Args>(args)...) {
113 message =
114 absl::StrCat("In file: ", file, ":", line, "\n", cerr_colorize(ANSI_BLUE),
115 "Unimplemented compiler support", cerr_clear_colors(), ": ", message);
116 }
117};
118
121class CompilationError : public P4CExceptionBase {
122 public:
123 template <typename... Args>
124 explicit CompilationError(const char *format, Args &&...args)
125 : P4CExceptionBase(format, std::forward<Args>(args)...) {}
126};
127
129#define BUG(...) \
130 do { \
131 throw P4::Util::CompilerBug(__LINE__, __FILE__, __VA_ARGS__); \
132 } while (0)
133#define BUG_CHECK(e, ...) \
134 do { \
135 if (!(e)) BUG(__VA_ARGS__); \
136 } while (0)
137#define P4C_UNIMPLEMENTED(...) \
138 do { \
139 throw P4::Util::CompilerUnimplemented(__LINE__, __FILE__, __VA_ARGS__); \
140 } while (0)
141
142} // namespace P4::Util
143
145#define FATAL_ERROR(...) \
146 do { \
147 throw P4::Util::CompilationError(__VA_ARGS__); \
148 } while (0)
149
150#endif /* LIB_EXCEPTIONS_H_ */