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
#define CPPAST_DIAGNOSTIC_HPP_INCLUDED
#include <sstream>
#include <string>
#include <type_safe/optional.hpp>
@ -112,6 +113,27 @@ namespace cppast
source_location location;
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
#endif // CPPAST_DIAGNOSTIC_HPP_INCLUDED

View file

@ -6,7 +6,6 @@
#define CPPAST_PARSE_ERROR_HPP_INCLUDED
#include <stdexcept>
#include <sstream>
#include <debug_assert.hpp>
#include <cppast/diagnostic.hpp>
@ -78,15 +77,6 @@ namespace cppast
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

View file

@ -113,11 +113,10 @@ std::unique_ptr<cpp_entity> detail::parse_entity(const detail::parse_context& co
{
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",
diagnostic{std::move(message), detail::make_location(cur),
severity::debug});
format_diagnostic(severity::debug, detail::make_location(cur),
"parsing cursor of type '",
detail::get_cursor_kind_spelling(cur).c_str(), "'"));
}
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 '",
detail::get_cursor_kind_spelling(cur).c_str(), "'");
context.logger->log("libclang parser",
diagnostic{std::move(msg), detail::make_location(cur),
severity::warning});
format_diagnostic(severity::warning, detail::make_location(cur),
"unhandled cursor of kind '",
detail::get_cursor_kind_spelling(cur).c_str(), "'"));
// build unexposed entity
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))
{
if (logger.is_verbose())
{
auto message = detail::format("parsing macro '", macro->name(), "'");
logger.log("preprocessor",
diagnostic{std::move(message),
source_location::make_file(path, p.cur_line()),
severity::debug});
}
format_diagnostic(severity::debug,
source_location::make_file(path, p.cur_line()),
"parsing macro '", macro->name(), "'"));
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 (logger.is_verbose())
{
auto message = detail::format("undefining macro '", undef.value(), "'");
logger.log("preprocessor",
diagnostic{std::move(message),
source_location::make_file(path, p.cur_line()),
severity::debug});
}
format_diagnostic(severity::debug,
source_location::make_file(path, p.cur_line()),
"undefining macro '", undef.value(), "'"));
result.macros.erase(std::remove_if(result.macros.begin(), result.macros.end(),
[&](const pp_macro& e) {
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))
{
if (logger.is_verbose())
{
auto message =
detail::format("parsing include '", include.value().file.name(), "'");
logger.log("preprocessor",
diagnostic{std::move(message),
source_location::make_file(path, p.cur_line()),
severity::debug});
}
format_diagnostic(severity::debug,
source_location::make_file(path, p.cur_line()),
"parsing include '", include.value().file.name(),
"'"));
result.includes.push_back(std::move(include.value()));
}
else if (bump_pragma(p))

View file

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