diff --git a/include/cppast/cpp_namespace.hpp b/include/cppast/cpp_namespace.hpp index 166d1ae..90b5f8d 100644 --- a/include/cppast/cpp_namespace.hpp +++ b/include/cppast/cpp_namespace.hpp @@ -60,6 +60,12 @@ namespace cppast return inline_; } + /// \returns Whether or not the namespace is anonymous. + bool is_anonymous() const noexcept + { + return name().empty(); + } + private: cpp_namespace(std::string name, bool is_inline) : cpp_entity(std::move(name)), inline_(is_inline) diff --git a/src/libclang/namespace_parser.cpp b/src/libclang/namespace_parser.cpp index 7f19c01..250dcda 100644 --- a/src/libclang/namespace_parser.cpp +++ b/src/libclang/namespace_parser.cpp @@ -27,9 +27,12 @@ namespace skip_attribute(stream); // { + // or when anonymous: { + if (detail::skip_if(stream, "{")) + return cpp_namespace::builder("", is_inline); + auto& name = stream.get().value(); skip(stream, "{"); - return cpp_namespace::builder(name.c_str(), is_inline); } } diff --git a/test/cpp_namespace.cpp b/test/cpp_namespace.cpp index 59ab733..4b08ba7 100644 --- a/test/cpp_namespace.cpp +++ b/test/cpp_namespace.cpp @@ -29,6 +29,10 @@ namespace c /// } namespace d {} } + +/// namespace { +/// } +namespace {} )"; auto file = parse({}, "cpp_namespace.cpp", code); @@ -36,29 +40,39 @@ namespace c auto no_children = count_children(ns); if (ns.name() == "a") { + REQUIRE(!ns.is_anonymous()); REQUIRE(!ns.is_inline()); REQUIRE(no_children == 0u); } else if (ns.name() == "b") { + REQUIRE(!ns.is_anonymous()); REQUIRE(ns.is_inline()); REQUIRE(no_children == 0u); } else if (ns.name() == "c") { + REQUIRE(!ns.is_anonymous()); REQUIRE(!ns.is_inline()); REQUIRE(no_children == 1u); } else if (ns.name() == "d") { + REQUIRE(!ns.is_anonymous()); check_parent(ns, "c", "c::d"); REQUIRE(!ns.is_inline()); REQUIRE(no_children == 0u); } + else if (ns.name() == "") + { + REQUIRE(ns.is_anonymous()); + REQUIRE(!ns.is_inline()); + REQUIRE(no_children == 0u); + } else REQUIRE(false); }); - REQUIRE(count == 4u); + REQUIRE(count == 5u); } TEST_CASE("cpp_namespace_alias")