diff --git a/include/cppast/cpp_entity_index.hpp b/include/cppast/cpp_entity_index.hpp index 7e45df3..d5dd545 100644 --- a/include/cppast/cpp_entity_index.hpp +++ b/include/cppast/cpp_entity_index.hpp @@ -17,6 +17,7 @@ namespace cppast { class cpp_entity; + class cpp_file; class cpp_namespace; /// \exclude @@ -78,10 +79,17 @@ namespace cppast void register_definition(cpp_entity_id id, type_safe::object_ref entity) const; + /// \effects Registers a new [cppast::cpp_file](). + /// \returns `true` if the file was not registered before. + /// If it returns `false`, the file was registered before and nothing was changed. + /// \requires The entity must live as long as the index lives. + /// \notes This operation is thread safe. + bool register_file(cpp_entity_id id, type_safe::object_ref file) const; + /// \effects Registers a new [cppast::cpp_entity]() which is a declaration. /// Only the first declaration will be registered. /// \requires The entity must live as long as the index lives. - /// \requires The entity must not be a namespace. + /// \requires The entity must be forward declarable. /// \notes This operation is thread safe. void register_forward_declaration(cpp_entity_id id, type_safe::object_ref entity) const; diff --git a/include/cppast/cpp_file.hpp b/include/cppast/cpp_file.hpp index 0ef4a11..b45ebec 100644 --- a/include/cppast/cpp_file.hpp +++ b/include/cppast/cpp_file.hpp @@ -50,11 +50,11 @@ namespace cppast /// \effects Registers the file in the [cppast::cpp_entity_index](). /// It will use the file name as identifier. - /// \returns The finished file. + /// \returns The finished file, or `nullptr`, if that file was already registered. std::unique_ptr finish(const cpp_entity_index& idx) noexcept { - idx.register_definition(cpp_entity_id(file_->name()), type_safe::ref(*file_)); - return std::move(file_); + auto res = idx.register_file(cpp_entity_id(file_->name()), type_safe::ref(*file_)); + return res ? std::move(file_) : nullptr; } private: diff --git a/include/cppast/parser.hpp b/include/cppast/parser.hpp index 708cc99..63ac895 100644 --- a/include/cppast/parser.hpp +++ b/include/cppast/parser.hpp @@ -84,6 +84,7 @@ namespace cppast /// \effects Parses the given file. /// \returns The [cppast::cpp_file]() object describing it. + /// It can be `nullptr`, if there was an error or the specified file already registered in the index. /// \requires The dynamic type of `config` must match the required config type. std::unique_ptr parse(const cpp_entity_index& idx, std::string path, const compile_config& config) const diff --git a/src/cpp_entity_index.cpp b/src/cpp_entity_index.cpp index da46bb2..521e367 100644 --- a/src/cpp_entity_index.cpp +++ b/src/cpp_entity_index.cpp @@ -7,6 +7,7 @@ #include #include #include +#include using namespace cppast; @@ -33,6 +34,13 @@ void cpp_entity_index::register_definition(cpp_entity_id } } +bool cpp_entity_index::register_file(cpp_entity_id id, + type_safe::object_ref file) const +{ + std::lock_guard lock(mutex_); + return map_.emplace(std::move(id), value(file, true)).second; +} + void cpp_entity_index::register_forward_declaration( cpp_entity_id id, type_safe::object_ref entity) const { diff --git a/src/libclang/libclang_parser.cpp b/src/libclang/libclang_parser.cpp index 44bcb85..cafede5 100644 --- a/src/libclang/libclang_parser.cpp +++ b/src/libclang/libclang_parser.cpp @@ -399,7 +399,7 @@ std::unique_ptr libclang_parser::do_parse(const cpp_entity_index& idx, auto macro_iter = preprocessed.macros.begin(); auto include_iter = preprocessed.includes.begin(); - // convert entity hierachies + // convert entity hierarchies detail::parse_context context{tu.get(), file, type_safe::ref(logger()), type_safe::ref(idx), detail::comment_context(preprocessed.comments)}; detail::visit_tu(tu, path.c_str(), [&](const CXCursor& cur) { @@ -444,5 +444,5 @@ std::unique_ptr libclang_parser::do_parse(const cpp_entity_index& idx, catch (detail::parse_error& ex) { logger().log("libclang parser", ex.get_diagnostic()); - return cpp_file::builder(path).finish(idx); + return nullptr; }