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