0

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?

Jani
  • 853
  • 8
  • 20

0 Answers0