17#ifndef LIB_BUG_HELPER_H_
18#define LIB_BUG_HELPER_H_
26#include <boost/format.hpp>
28#include "absl/strings/str_cat.h"
30#include "source_file.h"
36static inline std::pair<std::string_view, std::string> getPositionTail(
const Util::SourceInfo &
info,
37 std::string_view position,
38 std::string_view tail) {
39 std::string_view posString =
info.toPositionString().string_view();
40 std::string outTail(tail);
41 if (position.empty()) {
44 outTail.append(posString);
45 if (!posString.empty()) outTail.append(
"\n");
47 outTail +=
info.toSourceFragment();
49 return std::pair(position, outTail);
53std::pair<std::string_view, std::string> maybeAddSourceInfo(
const T &t, std::string_view position,
54 std::string_view tail) {
55 if constexpr (Util::has_SourceInfo_v<T>)
56 return getPositionTail(t.getSourceInfo(), position, tail);
63static inline std::string bug_helper(boost::format &f, std::string_view position,
64 std::string_view tail) {
65 return absl::StrCat(position, position.empty() ?
"" :
": ", boost::str(f),
"\n", tail);
68template <
typename T,
class... Args>
69auto bug_helper(boost::format &f, std::string_view position, std::string_view tail,
const T *t,
72template <
typename T,
class... Args>
73auto bug_helper(boost::format &f, std::string_view position, std::string_view tail,
const T &t,
74 Args &&...args) -> std::enable_if_t<!std::is_pointer_v<T>, std::string>;
76template <
class... Args>
77std::string bug_helper(boost::format &f, std::string_view position, std::string_view tail,
78 const char *t, Args &&...args) {
79 return bug_helper(f % t, position, tail, std::forward<Args>(args)...);
82template <
class... Args>
83std::string bug_helper(boost::format &f, std::string_view position, std::string_view tail,
84 const Util::SourceInfo &
info, Args &&...args) {
85 auto [outPos, outTail] = detail::getPositionTail(
info, position, tail);
86 return bug_helper(f %
"", outPos, outTail, std::forward<Args>(args)...);
96 if constexpr (has_dbprint_v<T>) {
97 dispatch.val->dbprint(os);
99 static_assert(has_ostream_operator_v<
decltype(dispatch.val)>,
100 "cannot debug print this type, implement dbprint method");
107template <
typename T,
class... Args>
108auto bug_helper(boost::format &f, std::string_view position, std::string_view tail,
const T *t,
110 if (t ==
nullptr)
return bug_helper(f, position, tail, std::forward<Args>(args)...);
112 auto [outPos, outTail] = maybeAddSourceInfo(*t, position, tail);
113 return bug_helper(f % DbprintDispatchPtr<T>{t}, outPos, outTail, std::forward<Args>(args)...);
123 if constexpr (has_dbprint_v<T>) {
124 dispatch.val.dbprint(os);
126 static_assert(has_ostream_operator_v<
decltype(dispatch.val)>,
127 "cannot debug print this type, implement dbprint method");
134template <
typename T,
class... Args>
135auto bug_helper(boost::format &f, std::string_view position, std::string_view tail,
const T &t,
136 Args &&...args) -> std::enable_if_t<!std::is_pointer_v<T>, std::string> {
137 auto [outPos, outTail] = maybeAddSourceInfo(t, position, tail);
138 return bug_helper(f % DbprintDispatchRef<T>{t}, outPos, outTail, std::forward<Args>(args)...);
143template <
class... Args>
144std::string bug_helper(boost::format &f, std::string_view position, std::string_view tail,
146 return detail::bug_helper(f, position, tail, std::forward<Args>(args)...);
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
void info(const int kind, const char *format, const T *node, Args &&...args)
Report info messages of type kind. Requires that the node argument have source info.
Definition lib/error.h:148
Definition bug_helper.h:90
Definition bug_helper.h:117