retdec
debug.h
Go to the documentation of this file.
1 
7 #ifndef RETDEC_LLVMIR2HLL_SUPPORT_DEBUG_H
8 #define RETDEC_LLVMIR2HLL_SUPPORT_DEBUG_H
9 
10 #include <cstdlib>
11 
12 #include <llvm/Support/raw_ostream.h>
13 
16 
17 #ifndef NDEBUG
18 
19 // Death tests work only when assertions are enabled.
20 #define DEATH_TESTS_ENABLED 1
21 
26 #define ABORT_IMPL(MSG) \
27  (llvm::errs() << __FILE__ ":" << __LINE__ << ": " << __func__ << \
28  ": " << MSG << ".\n", std::abort())
29 
34 #define ASSERT_MSG_IMPL(TEST, MSG) \
35  ((TEST) ? static_cast<void>(0) : ABORT_IMPL(MSG))
36 
43 #define ASSERT(TEST) \
44  ASSERT_MSG_IMPL(TEST, "Assertion failed: `" << #TEST << "`")
45 
57 #define ASSERT_MSG(TEST, MSG) \
58  ASSERT_MSG_IMPL(TEST, "Assertion failed: `" << #TEST \
59  << "` (" << MSG << ")")
60 
73 #define PRECONDITION(TEST, MSG) \
74  ASSERT_MSG_IMPL(TEST, "Precondition failed: `" << #TEST \
75  << "` (" << MSG << ")")
76 
86 #define PRECONDITION_NON_NULL(TEST) \
87  PRECONDITION(TEST, "expected a non-null pointer")
88 
98 #define PRECONDITION_FAILED(MSG) \
99  ABORT_IMPL("Precondition failed: " << MSG)
100 
107 #define POSTCONDITION(TEST, MSG) \
108  ASSERT_MSG_IMPL(TEST, "Postcondition failed: `" << #TEST \
109  << "` (" << MSG << ")")
110 
115 #define POSTCONDITION_NON_NULL(TEST) \
116  POSTCONDITION(TEST, "expected a non-null pointer")
117 
127 #define POSTCONDITION_FAILED(MSG) \
128  ABORT_IMPL("Postcondition failed: " << MSG)
129 
136 #define INVARIANT(TEST, MSG) \
137  ASSERT_MSG_IMPL(TEST, "Invariant failed: `" << #TEST \
138  << "` (" << MSG << ")")
139 
144 #define INVARIANT_NON_NULL(TEST) \
145  INVARIANT(TEST, "expected a non-null pointer")
146 
156 #define INVARIANT_FAILED(MSG) \
157  ABORT_IMPL("Invariant failed: " << MSG)
158 
159 // In the google test framework, there already is a FAIL macro, so when we use
160 // this framework, use the FAIL macro from there.
161 #ifndef FAIL
167 #define FAIL(MSG) \
168  ABORT_IMPL("Fail (" << MSG << ")")
169 #endif
170 
171 #else // #defined NDEBUG
172 
173 // Death tests work only when assertions are enabled.
174 #define DEATH_TESTS_ENABLED 0
175 
176 #define ABORT_IMPL(MSG) static_cast<void>(0)
177 #define ASSERT(TEST) static_cast<void>(0)
178 #define ASSERT_MSG(TEST, MSG) static_cast<void>(0)
179 #define ASSERT_MSG_IMPL(TEST, MSG) static_cast<void>(0)
180 #define PRECONDITION(TEST, MSG) static_cast<void>(0)
181 #define PRECONDITION_NON_NULL(TEST) static_cast<void>(0)
182 #define PRECONDITION_FAILED(MSG) static_cast<void>(0)
183 #define POSTCONDITION(TEST, MSG) static_cast<void>(0)
184 #define POSTCONDITION_NON_NULL(TEST) static_cast<void>(0)
185 #define POSTCONDITOON_FAILED(MSG) static_cast<void>(0)
186 #define INVARIANT(TEST, MSG) static_cast<void>(0)
187 #define INVARIANT_NON_NULL(TEST) static_cast<void>(0)
188 #define INVARIANT_FAILED(MSG) static_cast<void>(0)
189 // In the google test framework, there already is a FAIL macro, so when we use
190 // this framework, use the FAIL macro from there.
191 #ifndef FAIL
192  #define FAIL(MSG) static_cast<void>(0)
193 #endif
194 
195 #endif // #ifndef NDEBUG
196 
198 
199 namespace retdec {
200 namespace llvmir2hll {
201 
207 template<typename T>
208 T &id(T &object) {
209  return object;
210 }
211 
214 
228 template<class Container, class DumpFunc>
229 void dump(const Container &container, DumpFunc dumpFunc, const std::string &delim = ", ",
230  const std::string &end = "\n") {
231  bool somethingEmitted = false;
232  for (const auto &item : container) {
233  if (somethingEmitted) {
234  llvm::errs() << delim;
235  }
236  llvm::errs() << dumpFunc(item);
237  somethingEmitted = true;
238  }
239  llvm::errs() << end;
240 }
241 
251 template<class Container>
252 void dump(const Container &container, const std::string &delim = ", ",
253  const std::string &end = "\n") {
254  dump(container, id<const typename Container::value_type>, delim, end);
255 }
256 
264 template<class T>
265 std::string dumpFuncGetName(T object) {
266  return object->getName();
267 }
268 
276 template<class T>
277 std::string dumpFuncGetTextRepr(T object) {
278  return object->getTextRepr();
279 }
280 
282 
283 } // namespace llvmir2hll
284 } // namespace retdec
285 
286 #endif
A library providing API for working with back-end IR.
void dump(const Container &container, DumpFunc dumpFunc, const std::string &delim=", ", const std::string &end="\n")
Dumps the contents of the given container to standard error using the given dumping function.
Definition: debug.h:229
std::string dumpFuncGetName(T object)
A dumping function which, given an object pointer, calls getName() on it via ->.
Definition: debug.h:265
std::string dumpFuncGetTextRepr(T object)
A dumping function which, given an object pointer, calls getTextRepr() on it via ->.
Definition: debug.h:277
T & id(T &object)
Returns object.
Definition: debug.h:208
Definition: archive_wrapper.h:19