Skip to content

Commit ebdcf07

Browse files
committed
<format> specializations for some metadata types
1 parent fbef688 commit ebdcf07

File tree

3 files changed

+232
-7
lines changed

3 files changed

+232
-7
lines changed

include/mrdox/MetadataFwd.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ class Corpus;
2525

2626
class Interface;
2727

28+
enum class Access;
29+
2830
struct BaseInfo;
2931
struct EnumValueInfo;
3032
struct EnumInfo;

source/Support/Debug.cpp

+139
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
55
//
66
// Copyright (c) 2023 Vinnie Falco ([email protected])
7+
// Copyright (c) 2023 Krystian Stasiowski ([email protected])
78
//
89
// Official repository: https://github.com/cppalliance/mrdox
910
//
@@ -12,6 +13,14 @@
1213
#include <atomic>
1314
#include <memory>
1415

16+
#ifdef MRDOX_HAS_CXX20_FORMAT
17+
#include "Support/Radix.hpp"
18+
#include <mrdox/Metadata/Access.hpp>
19+
#include <mrdox/Metadata/Reference.hpp>
20+
#include <mrdox/Metadata/Symbols.hpp>
21+
#include <mrdox/Metadata/Info.hpp>
22+
#endif
23+
1524
#if defined(_MSC_VER) && ! defined(NDEBUG)
1625

1726
#define WIN32_LEAN_AND_MEAN
@@ -124,3 +133,133 @@ void debugEnableHeapChecking()
124133
} // clang
125134

126135
#endif
136+
137+
#ifdef MRDOX_HAS_CXX20_FORMAT
138+
std::format_context::iterator
139+
std::formatter<clang::mrdox::SymbolID>::
140+
format(
141+
const clang::mrdox::SymbolID& s,
142+
std::format_context& ctx) const
143+
{
144+
std::string str = s == clang::mrdox::EmptySID ?
145+
"<empty SymbolID>" : clang::mrdox::toBase64(s);
146+
return std::formatter<std::string>::format(std::move(str), ctx);
147+
}
148+
149+
std::format_context::iterator
150+
std::formatter<clang::mrdox::OptionalSymbolID>::
151+
format(
152+
const clang::mrdox::OptionalSymbolID& s,
153+
std::format_context& ctx) const
154+
{
155+
return std::formatter<clang::mrdox::SymbolID>::format(*s, ctx);
156+
}
157+
158+
std::format_context::iterator
159+
std::formatter<clang::mrdox::InfoType>::
160+
format(
161+
clang::mrdox::InfoType t,
162+
std::format_context& ctx) const
163+
{
164+
const char* str = "<unknown InfoType>";
165+
switch(t)
166+
{
167+
case clang::mrdox::InfoType::IT_default:
168+
str = "default";
169+
break;
170+
case clang::mrdox::InfoType::IT_namespace:
171+
str = "namespace";
172+
break;
173+
case clang::mrdox::InfoType::IT_record:
174+
str = "record";
175+
break;
176+
case clang::mrdox::InfoType::IT_function:
177+
str = "function";
178+
break;
179+
case clang::mrdox::InfoType::IT_enum:
180+
str = "enum";
181+
break;
182+
case clang::mrdox::InfoType::IT_typedef:
183+
str = "typedef";
184+
break;
185+
case clang::mrdox::InfoType::IT_variable:
186+
str = "variable";
187+
break;
188+
default:
189+
break;
190+
}
191+
return std::formatter<std::string>::format(str, ctx);
192+
}
193+
194+
std::format_context::iterator
195+
std::formatter<clang::mrdox::Access>::
196+
format(
197+
clang::mrdox::Access a,
198+
std::format_context& ctx) const
199+
{
200+
const char* str = "<unknown Access>";
201+
switch(a)
202+
{
203+
case clang::mrdox::Access::Public:
204+
str = "public";
205+
break;
206+
case clang::mrdox::Access::Protected:
207+
str = "protected";
208+
break;
209+
case clang::mrdox::Access::Private:
210+
str = "private";
211+
break;
212+
default:
213+
break;
214+
}
215+
return std::formatter<std::string>::format(str, ctx);
216+
}
217+
218+
std::format_context::iterator
219+
std::formatter<clang::mrdox::Reference>::
220+
format(
221+
const clang::mrdox::Reference& r,
222+
std::format_context& ctx) const
223+
{
224+
std::string str = std::format("Reference: type = {}", r.RefType);
225+
if(! r.Name.empty())
226+
str += std::format(", name = '{}'", std::string(r.Name));
227+
str += std::format(", ID = {}", r.id);
228+
return std::formatter<std::string>::format(std::move(str), ctx);
229+
}
230+
231+
std::format_context::iterator
232+
std::formatter<clang::mrdox::RefWithAccess>::
233+
format(
234+
const clang::mrdox::RefWithAccess& r,
235+
std::format_context& ctx) const
236+
{
237+
std::string str = std::format("RefWithAccess: access = {}, ID = {}",
238+
r.access, r.id);
239+
return std::formatter<std::string>::format(std::move(str), ctx);
240+
}
241+
242+
std::format_context::iterator
243+
std::formatter<clang::mrdox::Info>::
244+
format(
245+
const clang::mrdox::Info& i,
246+
std::format_context& ctx) const
247+
{
248+
std::string str = std::format("Info: type = {}", i.IT);
249+
if(! i.Name.empty())
250+
str += std::format(", name = '{}'", i.Name);
251+
str += std::format(", ID = {}", i.id);
252+
if(! i.Namespace.empty())
253+
{
254+
std::string namespaces;
255+
namespaces += i.Namespace[0].Name;
256+
for(std::size_t idx = 1; idx < i.Namespace.size(); ++idx)
257+
{
258+
namespaces += "::";
259+
namespaces += i.Namespace[0].Name;
260+
}
261+
str += std::format(", namespace = {}", namespaces);
262+
}
263+
return std::formatter<std::string>::format(std::move(str), ctx);
264+
}
265+
#endif

source/Support/Debug.hpp

+91-7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
55
//
66
// Copyright (c) 2023 Vinnie Falco ([email protected])
7+
// Copyright (c) 2023 Krystian Stasiowski ([email protected])
78
//
89
// Official repository: https://github.com/cppalliance/mrdox
910
//
@@ -18,15 +19,76 @@
1819
#include <llvm/Support/raw_ostream.h>
1920

2021
#if __has_include(<format>)
22+
#define MRDOX_HAS_CXX20_FORMAT
23+
#endif
24+
25+
#ifdef MRDOX_HAS_CXX20_FORMAT
2126
#include <format>
27+
#include <string>
28+
#include <mrdox/MetadataFwd.hpp>
2229

23-
#define PRINT_FMT(fmt, ...) (debug_outs() << std::format(fmt \
24-
__VA_OPT__(,) __VA_ARGS__))
25-
#define PRINT_FUNC_AND_NAME(name) PRINT_FMT("{:<48} {}\n", \
26-
(std::string(std::source_location::current().function_name()) + ":"), name)
27-
#else
28-
#define PRINT_FMT(fmt, ...)
29-
#define PRINT_FUNC_AND_NAME(name)
30+
template<>
31+
struct std::formatter<clang::mrdox::SymbolID>
32+
: std::formatter<std::string>
33+
{
34+
std::format_context::iterator format(
35+
const clang::mrdox::SymbolID& s,
36+
std::format_context& ctx) const;
37+
};
38+
39+
template<>
40+
struct std::formatter<clang::mrdox::OptionalSymbolID>
41+
: std::formatter<clang::mrdox::SymbolID>
42+
{
43+
std::format_context::iterator format(
44+
const clang::mrdox::OptionalSymbolID& s,
45+
std::format_context& ctx) const;
46+
};
47+
48+
template<>
49+
struct std::formatter<clang::mrdox::InfoType>
50+
: std::formatter<std::string>
51+
{
52+
std::format_context::iterator format(
53+
clang::mrdox::InfoType t,
54+
std::format_context& ctx) const;
55+
};
56+
57+
template<>
58+
struct std::formatter<clang::mrdox::Access>
59+
: std::formatter<std::string>
60+
{
61+
std::format_context::iterator format(
62+
clang::mrdox::Access a,
63+
std::format_context& ctx) const;
64+
};
65+
66+
template<>
67+
struct std::formatter<clang::mrdox::Reference>
68+
: std::formatter<std::string>
69+
{
70+
std::format_context::iterator format(
71+
const clang::mrdox::Reference& r,
72+
std::format_context& ctx) const;
73+
};
74+
75+
template<>
76+
struct std::formatter<clang::mrdox::RefWithAccess>
77+
: std::formatter<std::string>
78+
{
79+
std::format_context::iterator format(
80+
const clang::mrdox::RefWithAccess& r,
81+
std::format_context& ctx) const;
82+
};
83+
84+
template<>
85+
struct std::formatter<clang::mrdox::Info>
86+
: std::formatter<std::string>
87+
{
88+
std::format_context::iterator format(
89+
const clang::mrdox::Info& i,
90+
std::format_context& ctx) const;
91+
};
3092
#endif
3193

3294
// Some nice odds and ends such as leak checking
@@ -55,6 +117,28 @@ MRDOX_DECL void debugEnableHeapChecking();
55117
#define static_error(msg, value) \
56118
static_assert(!std::is_same_v<decltype(value),decltype(value)>,msg)
57119

120+
#ifdef MRDOX_HAS_CXX20_FORMAT
121+
// effectively the same as c++23 <print>,
122+
// except using debug_outs() as the output stream
123+
template<
124+
typename Format,
125+
typename... Args>
126+
void print_debug(
127+
Format fmt,
128+
Args&&... args)
129+
{
130+
debug_outs() << std::vformat(fmt,
131+
std::make_format_args(std::forward<Args>(args)...));
132+
}
133+
#else
134+
template<typename... Args>
135+
void print_debug(
136+
Args&&...)
137+
{
138+
// if <format> isn't supported, ignore the call
139+
}
140+
#endif
141+
58142
} // mrdox
59143
} // clang
60144

0 commit comments

Comments
 (0)