From 8d864bdbe12b902344ef7677607b7972d1092d5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Wed, 22 Feb 2017 20:44:19 +0100 Subject: [PATCH] Parse cpp_language_linkage --- include/cppast/cpp_language_linkage.hpp | 2 ++ src/cpp_language_linkage.cpp | 7 +++- src/libclang/language_linkage_parser.cpp | 46 ++++++++++++++++++++++++ src/libclang/namespace_parser.cpp | 1 - src/libclang/parse_functions.cpp | 6 ++++ src/libclang/parse_functions.hpp | 8 +++++ test/cpp_language_linkage.cpp | 12 +++++++ 7 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 src/libclang/language_linkage_parser.cpp create mode 100644 test/cpp_language_linkage.cpp diff --git a/include/cppast/cpp_language_linkage.hpp b/include/cppast/cpp_language_linkage.hpp index 6f5227b..ed183c4 100644 --- a/include/cppast/cpp_language_linkage.hpp +++ b/include/cppast/cpp_language_linkage.hpp @@ -15,6 +15,8 @@ namespace cppast public cpp_entity_container { public: + static cpp_entity_kind kind() noexcept; + /// Builds a [cppast::cpp_language_linkage](). class builder { diff --git a/src/cpp_language_linkage.cpp b/src/cpp_language_linkage.cpp index 6cf92ca..457d91a 100644 --- a/src/cpp_language_linkage.cpp +++ b/src/cpp_language_linkage.cpp @@ -8,6 +8,11 @@ using namespace cppast; +cpp_entity_kind cpp_language_linkage::kind() noexcept +{ + return cpp_entity_kind::language_linkage_t; +} + bool cpp_language_linkage::is_block() const noexcept { DEBUG_ASSERT(begin() != end(), detail::assert_handler{}, "empty container"); @@ -16,5 +21,5 @@ bool cpp_language_linkage::is_block() const noexcept cpp_entity_kind cpp_language_linkage::do_get_entity_kind() const noexcept { - return cpp_entity_kind::language_linkage_t; + return kind(); } diff --git a/src/libclang/language_linkage_parser.cpp b/src/libclang/language_linkage_parser.cpp new file mode 100644 index 0000000..1e907fc --- /dev/null +++ b/src/libclang/language_linkage_parser.cpp @@ -0,0 +1,46 @@ +// Copyright (C) 2017 Jonathan Müller +// This file is subject to the license terms in the LICENSE file +// found in the top-level directory of this distribution. + +#include "parse_functions.hpp" + +#include +#include + +#include "libclang_visitor.hpp" + +using namespace cppast; + +namespace +{ + cpp_language_linkage::builder make_ll_builder(const detail::parse_context& context, + const CXCursor& cur) + { + } +} + +std::unique_ptr detail::try_parse_cpp_language_linkage(const parse_context& context, + const CXCursor& cur) +{ + DEBUG_ASSERT(cur.kind == CXCursor_UnexposedDecl, + detail::assert_handler{}); // not exposed currently + + detail::tokenizer tokenizer(context.tu, context.file, cur); + detail::token_stream stream(tokenizer, cur); + + // extern ... + if (!detail::skip_if(stream, "extern")) + return nullptr; + // unexposed variable starting with extern - must be a language linkage + // (function, variables are not unexposed) + auto& name = stream.get().value(); + + auto builder = cpp_language_linkage::builder(name.c_str()); + detail::visit_children(cur, [&](const CXCursor& child) { + auto entity = parse_entity(context, child); + if (entity) + builder.add_child(std::move(entity)); + }); + + return builder.finish(); +} diff --git a/src/libclang/namespace_parser.cpp b/src/libclang/namespace_parser.cpp index 3e74331..4d28f2c 100644 --- a/src/libclang/namespace_parser.cpp +++ b/src/libclang/namespace_parser.cpp @@ -5,7 +5,6 @@ #include "parse_functions.hpp" #include -#include #include "libclang_visitor.hpp" diff --git a/src/libclang/parse_functions.cpp b/src/libclang/parse_functions.cpp index 6be879b..99eb48f 100644 --- a/src/libclang/parse_functions.cpp +++ b/src/libclang/parse_functions.cpp @@ -19,6 +19,12 @@ std::unique_ptr detail::parse_entity(const detail::parse_context& co auto kind = clang_getCursorKind(cur); switch (kind) { + case CXCursor_UnexposedDecl: + // go through all the try_parse_XXX functions + if (auto entity = try_parse_cpp_language_linkage(context, cur)) + return std::move(entity); + break; + case CXCursor_Namespace: return parse_cpp_namespace(context, cur); case CXCursor_NamespaceAlias: diff --git a/src/libclang/parse_functions.hpp b/src/libclang/parse_functions.hpp index 38bb12f..b86d57c 100644 --- a/src/libclang/parse_functions.hpp +++ b/src/libclang/parse_functions.hpp @@ -26,6 +26,14 @@ namespace cppast type_safe::object_ref idx; }; + // parse_entity() dispatches on the cursor type + // it calls one of the other parse functions defined elsewhere + // try_parse_XXX are not exposed entities + // they are called on an unexposed cursor and see whether they match + + std::unique_ptr try_parse_cpp_language_linkage(const parse_context& context, + const CXCursor& cur); + std::unique_ptr parse_cpp_namespace(const parse_context& context, const CXCursor& cur); std::unique_ptr parse_cpp_namespace_alias(const parse_context& context, diff --git a/test/cpp_language_linkage.cpp b/test/cpp_language_linkage.cpp new file mode 100644 index 0000000..5a1b475 --- /dev/null +++ b/test/cpp_language_linkage.cpp @@ -0,0 +1,12 @@ +// Copyright (C) 2017 Jonathan Müller +// This file is subject to the license terms in the LICENSE file +// found in the top-level directory of this distribution. + +#include "test_parser.hpp" + +using namespace cppast; + +TEST_CASE("cpp_language_linkage") +{ + // TODO: need actual entities to parse +}