standardese / cppast

Library to parse and work with the C++ AST
Other
1.7k stars 164 forks source link

Weird underscore in array of reference type #169

Open deadlocklogic opened 1 year ago

deadlocklogic commented 1 year ago

Explanation of the error: Consider parsing: https://github.com/foonathan/cppast/blob/f00df6675d87c6983033d270728c57a55cd3db22/include/cppast/code_generator.hpp#L30-L32

Input:

std::string _cppastRootPath = CPPAST_SOURCE_DIR + std::string("/");
std::string _cppastBuildPath = CMAKE_BINARY_DIR + std::string("/");
cppast::cpp_entity_index _idx;
cppast::simple_file_parser<cppast::libclang_parser> _parser(type_safe::ref(_idx), cppast::default_logger());
cppast::libclang_compile_config _config;

_config.set_flags(cppast::cpp_standard::cpp_17);
_config.fast_preprocessing(false);
_config.add_include_dir(_cppastRootPath);
_config.add_include_dir(_cppastBuildPath + "_deps/type_safe-src/include/");
_config.add_include_dir(_cppastBuildPath + "_deps/type_safe-src/external/debug_assert/");
cppast::parse_files(_parser, std::vector<std::string>{ _cppastRootPath + "cppast/code_generator.hpp"},
                    _config);

for (auto& _file : _parser.files()) {
    cppast::visit(
        _file, [](const cppast::cpp_entity& e) { return true; },
        [](const cppast::cpp_entity& e, const cppast::visitor_info& info) {
            if (info.event != cppast::visitor_info::event_type::container_entity_exit) {
                auto _parent = e.parent();
                if (_parent && _parent.value().kind() == cppast::cpp_entity_kind::function_template_t) {
                    if (e.kind() == cppast::cpp_entity_kind::constructor_t) {
                        if (e.name() == "string_view") {
                            auto& fn = dynamic_cast<const cppast::cpp_constructor&>(e);
                            for (auto& param : fn.parameters()) {
                                auto& _cpp_type = param.type();
                                auto& _cpp_reference_type =
                                    dynamic_cast<const cppast::cpp_reference_type&>(_cpp_type).referee();
                                auto& _cpp_array_type =
                                    dynamic_cast<const cppast::cpp_array_type&>(_cpp_reference_type);
                                std::cout
                                    << dynamic_cast<const cpp_unexposed_expression&>(_cpp_array_type.size().value())
                                            .expression()
                                            .as_string()
                                    << std::endl;
                                std::cout << cppast::to_string(_cpp_type) << " " << (int)_cpp_type.kind()
                                            << std::endl;
                            }
                        }
                    }
                }
            }
            return true;
        });
}

Output:

_Size
char const(&)[_Size] 7

Expected result:

Size
char const(&)[Size] 7

Where the underscore come from? Thanks.

deadlocklogic commented 1 year ago

After some digging, (including trying cindex python), I noticed that the compiler generates some synthetic typenames. A quick fix could be in: https://github.com/foonathan/cppast/blob/f00df6675d87c6983033d270728c57a55cd3db22/src/libclang/type_parser.cpp#L310-L330 by simply not using auto canonical = type; // clang_getCanonicalType(type); but the type directly. So maybe it is a hint because I haven't dug enough to know if it is code breaking or sufficient, but a quick and dirty patch worked for now.

If you want I can submit a PR. Actually I noticed few simple bugs which make the compilation fail with clang on windows (few CMake bugs). And I was considering harvesting more infos from libclang for example: 1- if the constructor is default/copy/move 2- source location of the entity (we talked about it previously)