diff --git a/include/cppast/cpp_type.hpp b/include/cppast/cpp_type.hpp index b5ed571..deca509 100644 --- a/include/cppast/cpp_type.hpp +++ b/include/cppast/cpp_type.hpp @@ -18,6 +18,8 @@ namespace cppast builtin, user_defined, + auto_, + cv_qualified, pointer, reference, @@ -176,6 +178,25 @@ namespace cppast cpp_type_ref entity_; }; + /// A [cppast::cpp_type]() that isn't given but deduced by `auto`. + class cpp_auto_type final : public cpp_type + { + public: + /// \returns A newly created `auto` type. + static std::unique_ptr build() + { + return std::unique_ptr(new cpp_auto_type); + } + + private: + cpp_auto_type() = default; + + cpp_type_kind do_get_kind() const noexcept override + { + return cpp_type_kind::auto_; + } + }; + class cpp_template_parameter_type; class cpp_template_instantiation_type; diff --git a/src/cpp_type.cpp b/src/cpp_type.cpp index 55f245d..a8e5f96 100644 --- a/src/cpp_type.cpp +++ b/src/cpp_type.cpp @@ -122,6 +122,7 @@ bool cppast::is_valid(const cpp_type& type) noexcept case cpp_type_kind::builtin: case cpp_type_kind::user_defined: + case cpp_type_kind::auto_: case cpp_type_kind::template_parameter: case cpp_type_kind::template_instantiation: case cpp_type_kind::unexposed: diff --git a/src/libclang/type_parser.cpp b/src/libclang/type_parser.cpp index ba34a08..970eb20 100644 --- a/src/libclang/type_parser.cpp +++ b/src/libclang/type_parser.cpp @@ -544,9 +544,8 @@ namespace case CXType_MemberPointer: return cpp_pointer_type::build(parse_member_pointee_type(context, cur, type)); - // TODO: auto/decltype case CXType_Auto: - break; + return make_leave_type(type, [](std::string&&) { return cpp_auto_type::build(); }); } DEBUG_UNREACHABLE(detail::assert_handler{}); diff --git a/test/cpp_type_alias.cpp b/test/cpp_type_alias.cpp index af70eaa..add39b4 100644 --- a/test/cpp_type_alias.cpp +++ b/test/cpp_type_alias.cpp @@ -31,6 +31,9 @@ bool equal_types(const cpp_entity_index& idx, const cpp_type& parsed, const cpp_ return equal_ref(idx, user_parsed.entity(), user_synthesized.entity()); } + case cpp_type_kind::auto_: + return true; + case cpp_type_kind::cv_qualified: { auto& cv_a = static_cast(parsed); diff --git a/test/cpp_variable.cpp b/test/cpp_variable.cpp index d6add83..81ed152 100644 --- a/test/cpp_variable.cpp +++ b/test/cpp_variable.cpp @@ -30,6 +30,10 @@ struct foo {} i; const struct bar {} j = bar(); struct baz {} k{}; static struct {} l; + +// auto +auto m = 128; +const auto& n = m; )"; cpp_entity_index idx; @@ -122,10 +126,25 @@ static struct {} l; else if (var.name() == "l") check_variable(var, *cpp_user_defined_type::build(cpp_type_ref(cpp_entity_id(""), "")), nullptr, cpp_storage_class_static, false, false); + else if (var.name() == "m") + check_variable(var, *cpp_auto_type::build(), + type_safe::ref( + *cpp_literal_expression::build(cpp_builtin_type::build("int"), + "128")), + cpp_storage_class_none, false, false); + else if (var.name() == "n") + check_variable(var, *cpp_reference_type:: + build(cpp_cv_qualified_type::build(cpp_auto_type::build(), + cpp_cv_const), + cpp_ref_lvalue), + type_safe::ref( + *cpp_unexposed_expression::build(cpp_builtin_type::build("int"), + "m")), + cpp_storage_class_none, false, false); else REQUIRE(false); }); - REQUIRE(count == 12u); + REQUIRE(count == 14u); } TEST_CASE("static cpp_variable")