Add format_diagnostic() function

This commit is contained in:
Jonathan Müller 2017-10-11 22:10:17 +02:00
commit 49e63c4a9b
5 changed files with 45 additions and 41 deletions

View file

@ -5,6 +5,7 @@
#ifndef CPPAST_DIAGNOSTIC_HPP_INCLUDED #ifndef CPPAST_DIAGNOSTIC_HPP_INCLUDED
#define CPPAST_DIAGNOSTIC_HPP_INCLUDED #define CPPAST_DIAGNOSTIC_HPP_INCLUDED
#include <sstream>
#include <string> #include <string>
#include <type_safe/optional.hpp> #include <type_safe/optional.hpp>
@ -112,6 +113,27 @@ namespace cppast
source_location location; source_location location;
cppast::severity severity; cppast::severity severity;
}; };
namespace detail
{
template <typename... Args>
std::string format(Args&&... args)
{
std::ostringstream stream;
int dummy[] = {(stream << std::forward<Args>(args), 0)...};
(void)dummy;
return stream.str();
}
} // namespace detail
/// Creates a diagnostic.
/// \returns A diagnostic with the specified severity and location.
/// The message is created by streaming each argument in order to a [std::ostringstream]().
template <typename... Args>
diagnostic format_diagnostic(severity sev, source_location loc, Args&&... args)
{
return {detail::format(std::forward<Args>(args)...), std::move(loc), sev};
}
} // namespace cppast } // namespace cppast
#endif // CPPAST_DIAGNOSTIC_HPP_INCLUDED #endif // CPPAST_DIAGNOSTIC_HPP_INCLUDED

View file

@ -6,7 +6,6 @@
#define CPPAST_PARSE_ERROR_HPP_INCLUDED #define CPPAST_PARSE_ERROR_HPP_INCLUDED
#include <stdexcept> #include <stdexcept>
#include <sstream>
#include <debug_assert.hpp> #include <debug_assert.hpp>
#include <cppast/diagnostic.hpp> #include <cppast/diagnostic.hpp>
@ -78,15 +77,6 @@ namespace cppast
throw parse_error(type, std::move(message)); throw parse_error(type, std::move(message));
} }
}; };
template <typename... Args>
std::string format(Args&&... args)
{
std::ostringstream stream;
int dummy[] = {(stream << std::forward<Args>(args), 0)...};
(void)dummy;
return stream.str();
}
} }
} // namespace cppast::detail } // namespace cppast::detail

View file

@ -113,11 +113,10 @@ std::unique_ptr<cpp_entity> detail::parse_entity(const detail::parse_context& co
{ {
if (context.logger->is_verbose()) if (context.logger->is_verbose())
{ {
auto message = detail::format("parsing cursor of type '",
detail::get_cursor_kind_spelling(cur).c_str(), "'");
context.logger->log("libclang parser", context.logger->log("libclang parser",
diagnostic{std::move(message), detail::make_location(cur), format_diagnostic(severity::debug, detail::make_location(cur),
severity::debug}); "parsing cursor of type '",
detail::get_cursor_kind_spelling(cur).c_str(), "'"));
} }
auto kind = clang_getCursorKind(cur); auto kind = clang_getCursorKind(cur);
@ -211,8 +210,9 @@ std::unique_ptr<cpp_entity> detail::parse_entity(const detail::parse_context& co
auto msg = detail::format("unhandled cursor of kind '", auto msg = detail::format("unhandled cursor of kind '",
detail::get_cursor_kind_spelling(cur).c_str(), "'"); detail::get_cursor_kind_spelling(cur).c_str(), "'");
context.logger->log("libclang parser", context.logger->log("libclang parser",
diagnostic{std::move(msg), detail::make_location(cur), format_diagnostic(severity::warning, detail::make_location(cur),
severity::warning}); "unhandled cursor of kind '",
detail::get_cursor_kind_spelling(cur).c_str(), "'"));
// build unexposed entity // build unexposed entity
auto name = detail::get_cursor_name(cur); auto name = detail::get_cursor_name(cur);

View file

@ -708,13 +708,10 @@ detail::preprocessor_output detail::preprocess(const libclang_compile_config& co
else if (auto macro = parse_macro(p, result, file_depth == 0u)) else if (auto macro = parse_macro(p, result, file_depth == 0u))
{ {
if (logger.is_verbose()) if (logger.is_verbose())
{
auto message = detail::format("parsing macro '", macro->name(), "'");
logger.log("preprocessor", logger.log("preprocessor",
diagnostic{std::move(message), format_diagnostic(severity::debug,
source_location::make_file(path, p.cur_line()), source_location::make_file(path, p.cur_line()),
severity::debug}); "parsing macro '", macro->name(), "'"));
}
result.macros.push_back({std::move(macro), p.cur_line()}); result.macros.push_back({std::move(macro), p.cur_line()});
} }
@ -723,13 +720,11 @@ detail::preprocessor_output detail::preprocess(const libclang_compile_config& co
if (file_depth == 0u) if (file_depth == 0u)
{ {
if (logger.is_verbose()) if (logger.is_verbose())
{
auto message = detail::format("undefining macro '", undef.value(), "'");
logger.log("preprocessor", logger.log("preprocessor",
diagnostic{std::move(message), format_diagnostic(severity::debug,
source_location::make_file(path, p.cur_line()), source_location::make_file(path, p.cur_line()),
severity::debug}); "undefining macro '", undef.value(), "'"));
}
result.macros.erase(std::remove_if(result.macros.begin(), result.macros.end(), result.macros.erase(std::remove_if(result.macros.begin(), result.macros.end(),
[&](const pp_macro& e) { [&](const pp_macro& e) {
return e.macro->name() == undef.value(); return e.macro->name() == undef.value();
@ -740,14 +735,12 @@ detail::preprocessor_output detail::preprocess(const libclang_compile_config& co
else if (auto include = parse_include(p, file_depth == 0u)) else if (auto include = parse_include(p, file_depth == 0u))
{ {
if (logger.is_verbose()) if (logger.is_verbose())
{
auto message =
detail::format("parsing include '", include.value().file.name(), "'");
logger.log("preprocessor", logger.log("preprocessor",
diagnostic{std::move(message), format_diagnostic(severity::debug,
source_location::make_file(path, p.cur_line()), source_location::make_file(path, p.cur_line()),
severity::debug}); "parsing include '", include.value().file.name(),
} "'"));
result.includes.push_back(std::move(include.value())); result.includes.push_back(std::move(include.value()));
} }
else if (bump_pragma(p)) else if (bump_pragma(p))

View file

@ -552,12 +552,11 @@ namespace
case CXType_OCLQueue: case CXType_OCLQueue:
case CXType_OCLReserveID: case CXType_OCLReserveID:
#endif #endif
{ context.logger->log("libclang parser",
auto msg = detail::format("unexpected type of kind '", format_diagnostic(severity::warning, detail::make_location(type),
detail::get_type_kind_spelling(type).c_str(), "'"); "unexpected type of kind '",
auto location = detail::make_location(type); detail::get_type_kind_spelling(type).c_str(),
context.logger->log("libclang parser", diagnostic{msg, location, severity::warning}); "'"));
}
// fallthrough // fallthrough
case CXType_Dependent: // seems to have something to do with expressions, just ignore that (for now?) case CXType_Dependent: // seems to have something to do with expressions, just ignore that (for now?)
case CXType_Unexposed: case CXType_Unexposed: