Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to extract preprocessor information from clang's parse tree?

Consider the following simple header, demo.h:

#define PERSIST
struct Serialised
{
    int someTransientValue ;
    PERSIST int aNumberToPersist ;
};

I use the following code and Clang's python API to iterate over the header:

import sys, clang.cindex
def callexpr_visitor(node, parent, userdata):
    if node.location.file: print node.location.file, node.displayname, node.kind
    return 2
tu = clang.cindex.Index.create().parse(sys.argv[1], args=['-x', 'c++'])
clang.cindex.Cursor_visit(tu.cursor, clang.cindex.Cursor_visit_callback(callexpr_visitor), None)

This prints out the elements of Clang's AST, producing the following output:

demo.h Serialised CursorKind.STRUCT_DECL
demo.h someTransientValue CursorKind.FIELD_DECL
demo.h aNumberToPersist CursorKind.FIELD_DECL

Does anyone know how I can extract the preprocessor declaration associated with the member variable called 'aNumberToPersist'?, is there a better way to 'tag' variables in a manner that manifests clearly in the parse tree?

Xubuntu 12.04, clang version 3.1 (tags/RELEASE_31/final), Target: x86_64-unknown-linux-gnu Thread model: posix.

like image 331
Gearoid Murphy Avatar asked Sep 30 '12 15:09

Gearoid Murphy


1 Answers

I would probably say: not this way.

Macros are not represented in the AST per se. Types, Attributes, etc... all those elements that have semantic values are represented (and comments), and optionally you can query whether some of them were expanded from a macro and get back that original macro spelling; however macros in themselves do not appear in the AST, at all.

If you could, it might be more interesting to extend Clang with a new attribute, especially in C++11: [[gearoid::persist]]. C++11 requires that compilers ignore attributes they know not about, so by "namespacing" your own attributes you pretty much guarantee that only you will care about their meaning.

I know not, unfortunately, whether you will need to teach Clang about your attributes so they are represented in the AST (Michael Han is working on always memorizing them). In any case, you may get more useful answers on the Clang DEV mailing list (unfortunately, there is no Clang Users mailing list).

EDIT: Just landed today! Clang will now retain all attributes (even those it does not understand) in its AST.

like image 196
Matthieu M. Avatar answered Oct 10 '22 03:10

Matthieu M.