Fix preprocessor line numbers if includes aren't supported

This commit is contained in:
Jonathan Müller 2017-10-10 21:13:29 +02:00
commit b28fff6c37
2 changed files with 30 additions and 16 deletions

View file

@ -403,9 +403,8 @@ namespace
auto args = get_arguments(config);
CXTranslationUnit tu;
auto flags = CXTranslationUnit_Incomplete | CXTranslationUnit_KeepGoing;
if (detail::libclang_compile_config_access::clang_version(config) >= 40000)
flags |= CXTranslationUnit_DetailedPreprocessingRecord;
auto flags = CXTranslationUnit_Incomplete | CXTranslationUnit_KeepGoing
| CXTranslationUnit_DetailedPreprocessingRecord;
auto error =
clang_parseTranslationUnit2(idx.get(), path, // index and path
@ -479,17 +478,20 @@ std::unique_ptr<cpp_file> libclang_parser::do_parse(const cpp_entity_index& idx,
detail::visit_tu(tu, path.c_str(), [&](const CXCursor& cur) {
if (clang_getCursorKind(cur) == CXCursor_InclusionDirective)
{
DEBUG_ASSERT(include_iter != preprocessed.includes.end()
&& get_line_no(cur) >= include_iter->line,
detail::assert_handler{});
if (!preprocessed.includes.empty())
{
DEBUG_ASSERT(include_iter != preprocessed.includes.end()
&& get_line_no(cur) >= include_iter->line,
detail::assert_handler{});
auto include =
cpp_include_directive::build(std::move(include_iter->file), include_iter->kind,
detail::get_cursor_name(cur).c_str());
context.comments.match(*include, include_iter->line);
builder.add_child(std::move(include));
auto include =
cpp_include_directive::build(std::move(include_iter->file), include_iter->kind,
detail::get_cursor_name(cur).c_str());
context.comments.match(*include, include_iter->line);
builder.add_child(std::move(include));
++include_iter;
++include_iter;
}
}
else if (clang_getCursorKind(cur) != CXCursor_MacroDefinition)
{

View file

@ -30,6 +30,11 @@ namespace
return '"' + std::move(str) + '"';
}
bool support_include(const libclang_compile_config& c)
{
return detail::libclang_compile_config_access::clang_version(c) >= 40000;
}
// build the command that runs the preprocessor
std::string get_command(const libclang_compile_config& c, const char* full_path)
{
@ -39,7 +44,7 @@ namespace
// -C: keep comments
// -dD: print macro definitions as well
auto flags = std::string("-x c++ -I. -E -C -dD");
if (detail::libclang_compile_config_access::clang_version(c) >= 40000)
if (support_include(c))
// -Xclang -dI: print include directives as well (clang >= 4.0.0)
flags += " -Xclang -dI";
// -fno-caret-diagnostics: don't show the source extract in diagnostics
@ -784,9 +789,16 @@ detail::preprocessor_output detail::preprocess(const libclang_compile_config& co
if (file_depth == 0u)
{
DEBUG_ASSERT(lm.value().file == path, detail::assert_handler{});
// difference is 1 if coming from an included file (because newline of include is already written)
// difference is 0 if coming from a builtin file (because no include has been written)
DEBUG_ASSERT(p.cur_line() - lm.value().line <= 1u, detail::assert_handler{});
if (lm.value().line > p.cur_line())
// might happen in weird cases
p.write_str(std::string(lm.value().line - p.cur_line(), '\n'));
else
// difference is 1 if coming from an included file (because newline of include is already written)
// difference is 0 if coming from a builtin file (because no include has been written)
DEBUG_ASSERT(p.cur_line() - lm.value().line <= 1u,
detail::assert_handler{});
p.enable_write();
}
break;