I have very strange problem. I have simple python c++ parser that looks for certain macro instantiations in my c++ code. And I have very strange problem
I have two files, test.cpp and macro.hpp, I'm parsing test.cpp
//macro.hpp
#define REGISTER_MODULE_INITIALIZER( Type ) \
namespace module_registrator { \
void Type##__Register() \
{ \
} \
}
//test.cpp
#include <iostream>
#include <macro.hpp>
namespace something
{
class MyClass
{
};
REGISTER_MODULE_INITIALIZER( MyClass );
}
}
If I remove #include , put it after #include <macro.hpp> or define macro direct in test.cpp - everything is fine, in ast I see function MyClass__Register(). But with iostream parser sees just some variable with name MyClass, like it couldn't find macro include (include directive is present in ast)
Parser looks like this, adding stdc++ include path to parser_args changed nothing.
def traverse(node):
if node.kind == clang.cindex.CursorKind.MACRO_INSTANTIATION:
if node.displayname == 'REGISTER_MODULE_INITIALIZER':
macro_locations.append([node.extent.start.line, node.extent.start.column, node.extent.start.file.name])
elif node.kind == clang.cindex.CursorKind.FUNCTION_DECL:
if [node.extent.start.line, node.extent.start.column, node.extent.start.file.name] in macro_locations \
and node.displayname.endswith('__Register()'):
nsp = get_namespace(node.lexical_parent)
nsp.objects.append(node.displayname)
print(str(node.kind) + ' ' + node.displayname)
for child in node.get_children():
traverse(child)
parser_args = ['-std=c++17']
clang.cindex.Config.set_library_path(clang_lib_path)
index = clang.cindex.Index.create()
tu = index.parse('test.cpp',
options=clang.cindex.TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD |
clang.cindex.TranslationUnit.PARSE_INCOMPLETE,
args=parser_args)
traverse(tu.cursor)
Clang 7.0.1 OS CentOS Python 3.7
UPD: If I add several std headers (I've tried memory and string), first of them will be parsed, all other std and my headers after it will be ignored. If I add several local headers they all are parsed normally.