[cfe-dev] Preprocessor conditional macro's hack

gorny gorny at santarago.org
Thu Jul 5 03:33:44 PDT 2012


Hi all,

I've been messing around with the LLVM/Clang internals, for fun and giggles.
However I quickly ran into problems with the preprocessor. In my opinion the
worst thing about C/C++ is the fact that the preprocessor is completely
decoupled from the rest of the language making it really hard to do proper code
analysis. If you also want to build a code analyzer you also want to properly
track conditional macro's and their dependencies. What I would like to do is
create a dependency graph for the preprocessor macro's in a single .c file.

Example:

#ifdef A
  #ifdef B
  #endif
#endif
#ifdef C
  #ifndef B
   #define D
  #endif
#endif

This should yield, with dependencies between parentheses: A(), B(C), C(), D(!B)

Using Clang's preprocessor it's impossible to go beyond the first level of
a conditional macro if it is undefined. The preprocessor will simply eat
everything within A and thus never deduce that B is conditional on A. I've
also looked at gcc (cpp -E -dU  - < hello.c | egrep "(#undef|#define)")
but that also only tracks first level macro's.

I'm was thinking about a solution where I simply get the first level macro's
and then create all permutations of their conditions and rerun the preprocessor
to find additional levels of used conditional macro's. Rinse and repeat.  I
think that should work relatively well although it might blow up quite quickly
with code bases which are really large. I haven't even thought about
conditional macro's yet. This all could probably be made to work with an
unpatched Clang instance.

For my preferred solution I was thinking about is to create a patch for the
Clang Preprocessor and turn all the relevant functions into virtual ones so I
can override the Preprocessor.  Either that or I create a patch which gives me
the option to record all this information when doing the Preprocessing. I'm not
looking directly to get this into Clang, if at all, since I very well
understand it's quite a limited use-case, but if someone could maybe offer some
guidance here on how to approach this (or share some pitfalls I need to watch
out for) it would be greatly appreciated.

cheers,
Vincent



More information about the cfe-dev mailing list