GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/base/exception.h Lines: 32 34 94.1 %
Date: 2021-05-22 Branches: 16 36 44.4 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Morgan Deters, Tim King, Mathias Preiner
4
 *
5
 * This file is part of the cvc5 project.
6
 *
7
 * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8
 * in the top-level source directory and their institutional affiliations.
9
 * All rights reserved.  See the file COPYING in the top-level source
10
 * directory for licensing information.
11
 * ****************************************************************************
12
 *
13
 * cvc5's exception base class and some associated utilities.
14
 */
15
16
#include "cvc5_public.h"
17
18
#ifndef CVC5__EXCEPTION_H
19
#define CVC5__EXCEPTION_H
20
21
#include <exception>
22
#include <iosfwd>
23
#include <string>
24
25
#include "cvc5_export.h"
26
27
namespace cvc5 {
28
29
class Exception : public std::exception
30
{
31
 protected:
32
  std::string d_msg;
33
34
 public:
35
  // Constructors
36
166
  Exception() : d_msg("Unknown exception") {}
37
3810
  Exception(const std::string& msg) : d_msg(msg) {}
38
29
  Exception(const char* msg) : d_msg(msg) {}
39
40
  // Destructor
41
4005
  virtual ~Exception() {}
42
43
  // NON-VIRTUAL METHOD for setting and printing the error message
44
168
  void setMessage(const std::string& msg) { d_msg = msg; }
45
495
  std::string getMessage() const { return d_msg; }
46
47
  // overridden from base class std::exception
48
6
  const char* what() const noexcept override { return d_msg.c_str(); }
49
50
  /**
51
   * Get this exception as a string.  Note that
52
   *   cout << ex.toString();
53
   * is subtly different from
54
   *   cout << ex;
55
   * which is equivalent to
56
   *   ex.toStream(cout);
57
   * That is because with the latter two, the output language (and
58
   * other preferences) for exprs on the stream is respected.  In
59
   * toString(), there is no stream, so the parameters are default
60
   * and you'll get exprs and types printed using the AST language.
61
   */
62
  std::string toString() const;
63
64
  /**
65
   * Printing: feel free to redefine toStream().  When overridden in
66
   * a derived class, it's recommended that this method print the
67
   * type of exception before the actual message.
68
   */
69
13
  virtual void toStream(std::ostream& os) const { os << d_msg; }
70
71
}; /* class Exception */
72
73
148
class CVC5_EXPORT IllegalArgumentException : public Exception
74
{
75
 protected:
76
  IllegalArgumentException() : Exception() {}
77
78
  void construct(const char* header, const char* extra,
79
                 const char* function, const char* tail);
80
81
  void construct(const char* header, const char* extra,
82
                 const char* function);
83
84
  static std::string format_extra(const char* condStr, const char* argDesc);
85
86
  static const char* s_header;
87
88
public:
89
90
122
  IllegalArgumentException(const char* condStr, const char* argDesc,
91
122
                           const char* function, const char* tail) :
92
122
    Exception() {
93
122
    construct(s_header, format_extra(condStr, argDesc).c_str(), function, tail);
94
122
  }
95
96
26
  IllegalArgumentException(const char* condStr, const char* argDesc,
97
26
                           const char* function) :
98
26
    Exception() {
99
26
    construct(s_header, format_extra(condStr, argDesc).c_str(), function);
100
26
  }
101
102
  /**
103
   * This is a convenience function for building usages that are variadic.
104
   *
105
   * Having IllegalArgumentException itself be variadic is problematic for
106
   * making sure calls to IllegalArgumentException clean up memory.
107
   */
108
  static std::string formatVariadic();
109
  static std::string formatVariadic(const char* format, ...);
110
}; /* class IllegalArgumentException */
111
112
inline std::ostream& operator<<(std::ostream& os, const Exception& e);
113
27
inline std::ostream& operator<<(std::ostream& os, const Exception& e)
114
{
115
27
  e.toStream(os);
116
27
  return os;
117
}
118
119
template <class T>
120
inline void CheckArgument(bool cond, const T& arg, const char* tail);
121
template <class T>
122
154672
inline void CheckArgument(bool cond,
123
                          const T& arg CVC5_UNUSED,
124
                          const char* tail CVC5_UNUSED)
125
{
126
154672
  if(__builtin_expect( ( !cond ), false )) {
127
4
    throw ::cvc5::IllegalArgumentException("", "", tail);
128
  }
129
154668
}
130
template <class T>
131
inline void CheckArgument(bool cond, const T& arg);
132
template <class T>
133
12319466
inline void CheckArgument(bool cond, const T& arg CVC5_UNUSED)
134
{
135
12319466
  if(__builtin_expect( ( !cond ), false )) {
136
22
    throw ::cvc5::IllegalArgumentException("", "", "");
137
  }
138
12319444
}
139
140
class CVC5_EXPORT LastExceptionBuffer
141
{
142
 public:
143
  LastExceptionBuffer();
144
  ~LastExceptionBuffer();
145
146
  void setContents(const char* string);
147
  const char* getContents() const { return d_contents; }
148
149
9591
  static LastExceptionBuffer* getCurrent() { return s_currentBuffer; }
150
8385
  static void setCurrent(LastExceptionBuffer* buffer) { s_currentBuffer = buffer; }
151
152
  static const char* currentContents() {
153
    return (getCurrent() == nullptr) ? nullptr : getCurrent()->getContents();
154
  }
155
156
private:
157
  /* Disallow copies */
158
  LastExceptionBuffer(const LastExceptionBuffer&) = delete;
159
  LastExceptionBuffer& operator=(const LastExceptionBuffer&) = delete;
160
161
  char* d_contents;
162
163
  static thread_local LastExceptionBuffer* s_currentBuffer;
164
}; /* class LastExceptionBuffer */
165
166
}  // namespace cvc5
167
168
#endif /* CVC5__EXCEPTION_H */