CastXML / pygccxml

pygccxml is a specialized XML reader that reads the output from CastXML or GCCXML. It provides a simple framework to navigate C++ declarations, using Python classes.
Boost Software License 1.0
129 stars 44 forks source link

std::function causes "Unable to find out actual class definition: 'type'." #137

Open AntonShalgachev opened 3 years ago

AntonShalgachev commented 3 years ago

Hey, pygccxml is having troubles parsing the following C++ code:

#include <functional>
int main()
{
    std::function<void()> func = [](){};
}

If parsed from file, this code results in the following error:

Unable to find out actual class definition: 'type'.
Class definition has been changed from one compilation to an other.
Why did it happen to me? Here is a short list of reasons: 
    1. There are different preprocessor definitions applied on same file during compilation
    2. Bug in pygccxml.

When parsing the same code from string I don't get any errors. Adding compilation_mode=parser.COMPILATION_MODE.ALL_AT_ONCE to the parser.parse also helps

Platform: Windows XML generator: castxml Python: 3.7.0

Full python code:

from pygccxml import parser
from pygccxml import declarations
from pygccxml import utils

# specific to my setup
compiler_path = r'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\Hostx86\x86\cl.exe'
include_paths = [
    r'C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/include',
    r'C:/Program Files (x86)/Windows Kits/10/Include/10.0.19041.0/ucrt',
]

filename = r'example.cpp'

code = """
#include <functional>
int main()
{
    std::function<void()> func = [](){};
}
"""

file_content = ''
with open(filename, 'w') as f:
    f.write(code)

generator_path, generator_name = utils.find_xml_generator('castxml')

xml_generator_config = parser.xml_generator_configuration_t(
    xml_generator_path=generator_path,
    xml_generator=generator_name,
    compiler_path=compiler_path,
    include_paths=include_paths)

decls = parser.parse_string(code, xml_generator_config)  # succeeds
decls = parser.parse([filename], xml_generator_config)  # fails

This issue might be relevant: #105