I'm using python-clang to parse C code. I want to distinguish between bool
and _Bool
. <stdbool.h>
defines bool
as a macro, not a typedef. For variables, it works to look at the tokens of the cursor. For members in struct declarations, it does not work. How do I figure out if the declaration had bool
or _Bool
?
Python sample code, requires libclang and its python bindings and clang:
#!/usr/bin/env python3
import argparse
from clang.cindex import TokenKind, CursorKind, TypeKind
from clang.cindex import Index, TranslationUnit
def main():
parser = argparse.ArgumentParser()
parser.add_argument('file', type=str, action='store')
args = parser.parse_args()
index = Index.create()
tu = index.parse(args.file,
options=TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD |
TranslationUnit.PARSE_SKIP_FUNCTION_BODIES)
for cursor in tu.cursor.walk_preorder():
if cursor.kind not in [CursorKind.VAR_DECL, CursorKind.FIELD_DECL]:
continue
print(f'{cursor.kind} {cursor.type.spelling} {cursor.spelling}')
print(f'\t{[t.spelling for t in cursor.get_tokens()]}')
if __name__ == '__main__':
main()
Given this input, passed as the only argument to the above:
#include <stdbool.h>
static bool bool_var;
static _Bool _Bool_var;
struct foo {
bool bool_member;
_Bool _Bool_member;
};
I get this output:
CursorKind.VAR_DECL _Bool bool_var
['static', 'bool', 'bool_var']
CursorKind.VAR_DECL _Bool _Bool_var
['static', '_Bool', '_Bool_var']
CursorKind.FIELD_DECL _Bool bool_member
[]
CursorKind.FIELD_DECL _Bool _Bool_member
['_Bool', '_Bool_member']
Note the empty token list for the bool
member. I believe it must be related to the macro instantiation, but why are the tokens lost? Given a cursor, how do I figure out what the original type was in the source?