diff --git a/include/cppast/libclang_parser.hpp b/include/cppast/libclang_parser.hpp index 6ff4b48..5b02037 100644 --- a/include/cppast/libclang_parser.hpp +++ b/include/cppast/libclang_parser.hpp @@ -23,6 +23,8 @@ namespace cppast static int clang_version(const libclang_compile_config& config); static const std::vector& flags(const libclang_compile_config& config); + + static bool write_preprocessed(const libclang_compile_config& config); }; void for_each_file(const libclang_compilation_database& database, void* user_data, @@ -34,9 +36,7 @@ namespace cppast { public: /// \effects Creates it with a message. - libclang_error(std::string msg) : std::runtime_error(std::move(msg)) - { - } + libclang_error(std::string msg) : std::runtime_error(std::move(msg)) {} }; /// A compilation database. @@ -121,6 +121,13 @@ namespace cppast clang_version_ = major * 10000 + minor * 100 + patch; } + /// \effects Sets whether or not the preprocessed file will be written out. + /// Default value is `false`. + void write_preprocessed(bool b) noexcept + { + write_preprocessed_ = b; + } + private: void do_set_flags(cpp_standard standard, compile_flags flags) override; @@ -137,6 +144,7 @@ namespace cppast std::string clang_binary_; int clang_version_; + bool write_preprocessed_; friend detail::libclang_compile_config_access; }; diff --git a/src/libclang/libclang_parser.cpp b/src/libclang/libclang_parser.cpp index 08628a6..4fcae1e 100644 --- a/src/libclang/libclang_parser.cpp +++ b/src/libclang/libclang_parser.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -35,6 +36,12 @@ const std::vector& detail::libclang_compile_config_access::flags( return config.get_flags(); } +bool detail::libclang_compile_config_access::write_preprocessed( + const libclang_compile_config& config) +{ + return config.write_preprocessed_; +} + libclang_compilation_database::libclang_compilation_database(const std::string& build_directory) { static_assert(std::is_same::value, "forgot to update type"); @@ -74,7 +81,7 @@ namespace } } -libclang_compile_config::libclang_compile_config() : compile_config({}) +libclang_compile_config::libclang_compile_config() : compile_config({}), write_preprocessed_(false) { // set given clang binary auto ptr = CPPAST_CLANG_VERSION_STRING; @@ -446,8 +453,15 @@ std::unique_ptr libclang_parser::do_parse(const cpp_entity_index& idx, "config has mismatched type"); auto& config = static_cast(c); - // preprocess + parse + // preprocess auto preprocessed = detail::preprocess(config, path.c_str(), logger()); + if (detail::libclang_compile_config_access::write_preprocessed(config)) + { + std::ofstream file(path + ".pp"); + file << preprocessed.source; + } + + // parse auto tu = get_cxunit(logger(), pimpl_->index, config, path.c_str(), preprocessed.source); auto file = clang_getFile(tu.get(), path.c_str()); diff --git a/tool/main.cpp b/tool/main.cpp index 9affd3d..8a1ebbb 100644 --- a/tool/main.cpp +++ b/tool/main.cpp @@ -87,12 +87,8 @@ void print_entity(std::ostream& out, const cppast::cpp_entity& e) } // no need to handle indentation, as only a single line is used - void do_indent() override - { - } - void do_unindent() override - { - } + void do_indent() override {} + void do_unindent() override {} // called when a generic token sequence should be generated // there are specialized callbacks for various token kinds, @@ -249,6 +245,9 @@ int main(int argc, char* argv[]) try cppast::libclang_compile_config(database, options["file"].as()); } + if (options.count("verbose")) + config.write_preprocessed(true); + if (options.count("include_directory")) for (auto& include : options["include_directory"].as>()) config.add_include_dir(include);