// 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 #include "test_parser.hpp" using namespace cppast; TEST_CASE("cpp_enum") { auto code = R"( /// enum a{ /// a_a, /// a_b=42, /// a_c, /// a_d=a_a+2 /// }; enum a { a_a, a_b = 42, a_c, a_d = a_a + 2, }; /// enum class b; enum class b; // forward declaration /// enum class b /// :int{ /// b_a, /// b_b=42, /// b_c /// }; enum class b : int { b_a, b_b = 42, b_c }; /// enum c /// :int; enum c : int; )"; cpp_entity_index idx; auto file = parse(idx, "cpp_enum.cpp", code); auto count = test_visit(*file, [&](const cpp_enum& e) { if (e.name() == "a") { REQUIRE(e.is_definition()); REQUIRE(!e.is_declaration()); REQUIRE(!e.is_scoped()); REQUIRE(!e.underlying_type()); auto no_vals = 0u; for (auto& val : e) { if (val.name() == "a_a" || val.name() == "a_c") { ++no_vals; REQUIRE(!val.value()); } else if (val.name() == "a_b") { ++no_vals; REQUIRE(val.value()); auto& expr = val.value().value(); REQUIRE(expr.kind() == cpp_expression_kind::unexposed_t); REQUIRE(static_cast(expr).expression() == "42"); REQUIRE(equal_types(idx, expr.type(), *cpp_builtin_type::build(cpp_uint))); } else if (val.name() == "a_d") { ++no_vals; REQUIRE(val.value()); auto& expr = val.value().value(); // this is unexposed for some reason REQUIRE(expr.kind() == cpp_expression_kind::unexposed_t); REQUIRE(static_cast(expr).expression() == "a_a+2"); REQUIRE(equal_types(idx, expr.type(), *cpp_builtin_type::build(cpp_uint))); } else REQUIRE(false); } REQUIRE(no_vals == 4u); } else if (e.name() == "b") { REQUIRE(e.is_scoped()); if (e.is_definition()) { REQUIRE(e.underlying_type()); REQUIRE(equal_types(idx, e.underlying_type().value(), *cpp_builtin_type::build(cpp_int))); auto no_vals = 0u; for (auto& val : e) { REQUIRE(full_name(val) == "b::" + val.name()); if (val.name() == "b_a" || val.name() == "b_c") { ++no_vals; REQUIRE(!val.value()); } else if (val.name() == "b_b") { ++no_vals; REQUIRE(val.value()); auto& expr = val.value().value(); REQUIRE(expr.kind() == cpp_expression_kind::literal_t); REQUIRE(static_cast(expr).value() == "42"); REQUIRE(equal_types(idx, expr.type(), *cpp_builtin_type::build(cpp_int))); } else REQUIRE(false); } REQUIRE(no_vals == 3u); } else if (e.is_declaration()) { REQUIRE(!e.underlying_type()); // no underlying type, implicit int REQUIRE(count_children(e) == 0u); auto definition = get_definition(idx, e); REQUIRE(definition); REQUIRE(definition.value().name() == "b"); REQUIRE(count_children(definition.value()) == 3u); } else REQUIRE(false); } else if (e.name() == "c") { REQUIRE(e.is_declaration()); REQUIRE(!e.is_definition()); REQUIRE(!e.is_scoped()); REQUIRE( equal_types(idx, e.underlying_type().value(), *cpp_builtin_type::build(cpp_int))); REQUIRE(count_children(e) == 0u); auto definition = get_definition(idx, e); REQUIRE(!definition); } else REQUIRE(false); }); REQUIRE(count == 4u); }