Keep macro definitions when preprocessing
Other includes libclang encounters might depend on them.
This commit is contained in:
parent
599f2bbff8
commit
f359885e87
1 changed files with 48 additions and 16 deletions
|
|
@ -17,6 +17,8 @@
|
||||||
#include <cppast/cpp_entity_kind.hpp>
|
#include <cppast/cpp_entity_kind.hpp>
|
||||||
#include <cppast/diagnostic.hpp>
|
#include <cppast/diagnostic.hpp>
|
||||||
|
|
||||||
|
#include "parse_error.hpp"
|
||||||
|
|
||||||
using namespace cppast;
|
using namespace cppast;
|
||||||
namespace ts = type_safe;
|
namespace ts = type_safe;
|
||||||
|
|
||||||
|
|
@ -415,10 +417,13 @@ namespace
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void skip_spaces(position& p)
|
void skip_spaces(position& p, bool bump = false)
|
||||||
{
|
{
|
||||||
while (starts_with(p, " "))
|
while (starts_with(p, " "))
|
||||||
p.skip();
|
if (bump)
|
||||||
|
p.bump();
|
||||||
|
else
|
||||||
|
p.skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<cpp_macro_definition> parse_macro(position& p,
|
std::unique_ptr<cpp_macro_definition> parse_macro(position& p,
|
||||||
|
|
@ -427,31 +432,34 @@ namespace
|
||||||
{
|
{
|
||||||
// format (at new line): #define <name> [replacement]
|
// format (at new line): #define <name> [replacement]
|
||||||
// or: #define <name>(<args>) [replacement]
|
// or: #define <name>(<args>) [replacement]
|
||||||
|
// note: keep macro definition in file
|
||||||
if (!p.was_newl() || !starts_with(p, "#define"))
|
if (!p.was_newl() || !starts_with(p, "#define"))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
p.skip(std::strlen("#define"));
|
// read line here for comment matching
|
||||||
skip_spaces(p);
|
auto cur_line = p.cur_line();
|
||||||
|
p.bump(std::strlen("#define"));
|
||||||
|
skip_spaces(p, true);
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
while (!starts_with(p, "(") && !starts_with(p, " ") && !starts_with(p, "\n"))
|
while (!starts_with(p, "(") && !starts_with(p, " ") && !starts_with(p, "\n"))
|
||||||
{
|
{
|
||||||
name += *p.ptr();
|
name += *p.ptr();
|
||||||
p.skip();
|
p.bump();
|
||||||
}
|
}
|
||||||
|
|
||||||
ts::optional<std::string> args;
|
ts::optional<std::string> args;
|
||||||
if (starts_with(p, "("))
|
if (starts_with(p, "("))
|
||||||
{
|
{
|
||||||
std::string str;
|
std::string str;
|
||||||
for (p.skip(); !starts_with(p, ")"); p.skip())
|
for (p.bump(); !starts_with(p, ")"); p.bump())
|
||||||
str += *p.ptr();
|
str += *p.ptr();
|
||||||
p.skip();
|
p.bump();
|
||||||
args = std::move(str);
|
args = std::move(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string rep;
|
std::string rep;
|
||||||
auto in_c_comment = false;
|
auto in_c_comment = false;
|
||||||
for (skip_spaces(p); in_c_comment || !starts_with(p, "\n"); p.skip())
|
for (skip_spaces(p, true); in_c_comment || !starts_with(p, "\n"); p.bump())
|
||||||
{
|
{
|
||||||
if (starts_with(p, "/*"))
|
if (starts_with(p, "/*"))
|
||||||
in_c_comment = true;
|
in_c_comment = true;
|
||||||
|
|
@ -466,7 +474,7 @@ namespace
|
||||||
|
|
||||||
auto result = cpp_macro_definition::build(std::move(name), std::move(args), std::move(rep));
|
auto result = cpp_macro_definition::build(std::move(name), std::move(args), std::move(rep));
|
||||||
// match comment directly
|
// match comment directly
|
||||||
if (!output.comments.empty() && output.comments.back().matches(*result, p.cur_line()))
|
if (!output.comments.empty() && output.comments.back().matches(*result, cur_line))
|
||||||
{
|
{
|
||||||
result->set_comment(std::move(output.comments.back().comment));
|
result->set_comment(std::move(output.comments.back().comment));
|
||||||
output.comments.pop_back();
|
output.comments.pop_back();
|
||||||
|
|
@ -483,10 +491,10 @@ namespace
|
||||||
// however, this kind of usage should be rare™
|
// however, this kind of usage should be rare™
|
||||||
if (/*!p.was_newl() ||*/ !starts_with(p, "#undef"))
|
if (/*!p.was_newl() ||*/ !starts_with(p, "#undef"))
|
||||||
return ts::nullopt;
|
return ts::nullopt;
|
||||||
p.skip(std::strlen("#undef"));
|
p.bump(std::strlen("#undef"));
|
||||||
|
|
||||||
std::string result;
|
std::string result;
|
||||||
for (skip_spaces(p); !starts_with(p, "\n"); p.skip())
|
for (skip_spaces(p, true); !starts_with(p, "\n"); p.bump())
|
||||||
result += *p.ptr();
|
result += *p.ptr();
|
||||||
// don't skip newline
|
// don't skip newline
|
||||||
|
|
||||||
|
|
@ -499,6 +507,7 @@ namespace
|
||||||
{
|
{
|
||||||
// format (at new line, literal <>): #include <filename>
|
// format (at new line, literal <>): #include <filename>
|
||||||
// or: #include "filename"
|
// or: #include "filename"
|
||||||
|
// note: don't write include back
|
||||||
if (!p.was_newl() || !starts_with(p, "#include"))
|
if (!p.was_newl() || !starts_with(p, "#include"))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
p.skip(std::strlen("#include"));
|
p.skip(std::strlen("#include"));
|
||||||
|
|
@ -544,14 +553,14 @@ namespace
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool skip_pragma(position& p)
|
bool bump_pragma(position& p)
|
||||||
{
|
{
|
||||||
// format (at new line): #pragma <stuff..>\n
|
// format (at new line): #pragma <stuff..>\n
|
||||||
if (!p.was_newl() || !starts_with(p, "#pragma"))
|
if (!p.was_newl() || !starts_with(p, "#pragma"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
while (!starts_with(p, "\n"))
|
while (!starts_with(p, "\n"))
|
||||||
p.skip();
|
p.bump();
|
||||||
// don't skip newline
|
// don't skip newline
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -645,11 +654,27 @@ detail::preprocessor_output detail::preprocess(const libclang_compile_config& co
|
||||||
{
|
{
|
||||||
if (auto macro = parse_macro(p, result, file_depth == 0u))
|
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),
|
||||||
|
severity::debug});
|
||||||
|
}
|
||||||
|
|
||||||
result.entities.push_back({std::move(macro), p.cur_line()});
|
result.entities.push_back({std::move(macro), p.cur_line()});
|
||||||
}
|
}
|
||||||
else if (auto undef = parse_undef(p))
|
else if (auto undef = parse_undef(p))
|
||||||
{
|
{
|
||||||
if (file_depth == 0u)
|
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),
|
||||||
|
severity::debug});
|
||||||
|
}
|
||||||
result.entities
|
result.entities
|
||||||
.erase(std::remove_if(result.entities.begin(), result.entities.end(),
|
.erase(std::remove_if(result.entities.begin(), result.entities.end(),
|
||||||
[&](const pp_entity& e) {
|
[&](const pp_entity& e) {
|
||||||
|
|
@ -658,13 +683,20 @@ detail::preprocessor_output detail::preprocess(const libclang_compile_config& co
|
||||||
&& e.entity->name() == undef.value();
|
&& e.entity->name() == undef.value();
|
||||||
}),
|
}),
|
||||||
result.entities.end());
|
result.entities.end());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (auto include = parse_include(p, result, file_depth == 0u))
|
else if (auto include = parse_include(p, result, file_depth == 0u))
|
||||||
{
|
{
|
||||||
if (file_depth == 0u)
|
if (logger.is_verbose())
|
||||||
result.entities.push_back({std::move(include), p.cur_line()});
|
{
|
||||||
|
auto message = detail::format("parsing include '", include->name(), "'");
|
||||||
|
logger.log("preprocessor",
|
||||||
|
diagnostic{std::move(message), source_location::make_file(path),
|
||||||
|
severity::debug});
|
||||||
|
}
|
||||||
|
result.entities.push_back({std::move(include), p.cur_line()});
|
||||||
}
|
}
|
||||||
else if (skip_pragma(p))
|
else if (bump_pragma(p))
|
||||||
continue;
|
continue;
|
||||||
else if (auto lm = parse_linemarker(p))
|
else if (auto lm = parse_linemarker(p))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue