3

I have cut out a piece of code out of a larger (C) project. The code has many many macros defined, in many place - some of them are only used by the original, larger codebase, and not used by the part of the code I cut out.

I want to quickly determine which of these macros are in actual use, and which aren't (so that I can remove those that aren't). I don't care whether the code paths which uses them get taken or not (i.e. if (1+1 == 3) { MY_MACRO(a,b,c); } is a use as far as I'm concerned.

What's a good way to do this? The best I could think of is preprocess everything with -E and look for source position comments which mention the macro somehow.

Notes:

  • If you have a solution that also lists the functions in use, that's fine too.
  • I only directly call certain functions in the code I cut out of the project. If your solution can limit the macros listed to those in functions which many actually get called from the entry-points, that's even better
  • My code compiles and runs (and you can assume gprof output if that helps)
  • Just commenting out all macros, while obviously feasible, is a hassle; so I want a solution which does not require my doing that.
  • Code excluded by the preprocessor is unused; but if you have a solution which does not observe this restriction, that's still better than nothing.
  • I don't want to "dump the list of preprocessor defines" - but rather those defines that are in use.
Community
  • 1
  • 1
einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • 4
    Comment out all `#define` directives and rebuild. Check which symbols are complained about. – Some programmer dude Nov 30 '16 at 09:50
  • 2
    Sidenote: Since your code compiles, remember to compare binaries before and after macro removal. You may accidentally remove macro which is used in conditional compilation, and get no warnings or errors. – user694733 Nov 30 '16 at 09:58
  • @Someprogrammerdude: See edit. I want to be lazier than that. – einpoklum Nov 30 '16 at 10:15
  • 1
    What about code excluded by preprocessor? Should macro `FOO` be listed if it is excluded by, say, `#ifdef DEBUG`? –  Nov 30 '16 at 10:22
  • @deniss: Unused. But see edit. – einpoklum Nov 30 '16 at 12:18
  • One could probably produce a list of all identifiers which are followed by optional whitespace and then a round bracket with grep or similar. That should be a list of all function and macro definitions and calls. Compare those with a list of symbols produced by `objdump` or `nm`. – Peter - Reinstate Monica Nov 30 '16 at 13:07
  • Possible duplicate of [GCC dump preprocessor defines](http://stackoverflow.com/questions/2224334/gcc-dump-preprocessor-defines) – Andrew Henle Nov 30 '16 at 13:16
  • @AndrewHenle Interesting link; although I think the OP wants not the definitions (there are plenty) but only the few *uses* of some of the definitions. – Peter - Reinstate Monica Nov 30 '16 at 14:00
  • @AndrewHenle: Actually, this question is about how to _not_ get the entire dump of preprocessor defines. – einpoklum Nov 30 '16 at 15:55

1 Answers1

3

There exists clang tool named pp-trace. It outputs every preprocessor invocation with its parameters.

You are interested in MacroExpands event, it looks like so in pp-trace output:

...

- Callback: MacroExpands
  MacroNameTok: X_IMPL
  MacroDirective: MD_Define
  Range: [(nonfile), (nonfile)]
  Args: [a <plus> y, b]

...

Extracting MacroNameTok from MacroExpands block should do the trick for you.

  • deniss, is that available in clang-3.8? I'm having trouble locating it on my Kubuntu 16.04 distribution. – einpoklum Dec 02 '16 at 15:07
  • @einpoklum, it should be. Unfortunately, I only ever built it from sources, so unsure if it is redistributed as binary. –  Dec 02 '16 at 22:16
  • Well, just so you know: [it's missing from *buntu 16.04 and nobody knows why.](http://askubuntu.com/posts/comments/1319419?noredirect=1). – einpoklum Dec 04 '16 at 15:25