1

I want to retrieve macro names within a source file but avoid the ones that are defined within included header files.
Right now I am using

PPCallbacks::MacroDefined

to get the macro token.

Is there a way to skip this callback when defined macro is within some included header file?

Bhushan
  • 354
  • 9
  • 25

1 Answers1

0

The MacroDefined method of PPCallbacks is passed a MacroDirective, which has a getLocation method that yields a SourceLocation. That is the location where the macro is defined.

You can pass that location to the isWrittenInMainFile method of SourceManager to check if it is defined in the main source file.

Beware: There is also isInMainFile (no Written), which works a little differently. In clang+llvm-14 at least, the latter method reports true for predefined macros as well as those in the main file, which seems like a bug to me.

To demonstrate filtering for macros defined in the main file, I modified the pp-trace program included in the clang-tools-extra package so it only reports MacroDefinitions in the main file:

--- a/PPCallbacksTracker.cpp
+++ b/PPCallbacksTracker.cpp
@@ -336,9 +336,15 @@ void PPCallbacksTracker::MacroExpands(const Token &MacroNameTok,
 // Hook called whenever a macro definition is seen.
 void PPCallbacksTracker::MacroDefined(const Token &MacroNameTok,
                                       const MacroDirective *MacroDirective) {
+  SourceLocation loc = MacroDirective->getLocation();
+  if (!PP.getSourceManager().isWrittenInMainFile(loc)) {
+    return;  // skip
+  }
+
   beginCallback("MacroDefined");
   appendArgument("MacroNameTok", MacroNameTok);
   appendArgument("MacroDirective", MacroDirective);
+  appendArgument("Location", loc.printToString(PP.getSourceManager()));
 }
 
 // Hook called whenever a macro #undef is seen.

This change also causes the output to report the location of each defined macro. You should be able to grab the sources for pp-trace, apply this diff, and see the behavior. Or just add the if test to your own code.

Example run:

$ cat test.cpp
// test.cpp
// Simple test of pp-trace-mod.exe

// Pull in a few macros.
#include <stddef.h>

// Define a macro in the main file.
#define MY_MACRO 0

int main()
{
  return MY_MACRO;
}

// EOF

$ ./pp-trace-mod.exe  --extra-arg=-I/home/scott/opt/clang+llvm-14.0.0-x86_64-linux-gnu-ubuntu-18.04/lib/clang/14.0.0/include --callbacks=MacroDefined test.cpp
Error while trying to load a compilation database:
Could not auto-detect compilation database for file "test.cpp"
No compilation database found in /home/scott/wrk/learn/clang/pp-trace-mod or any parent directory
fixed-compilation-database: Error while opening fixed database: No such file or directory
json-compilation-database: Error while opening JSON database: No such file or directory
Running without flags.
---
- Callback: MacroDefined
  MacroNameTok: MY_MACRO
  MacroDirective: MD_Define
  Location: /home/scott/wrk/learn/clang/pp-trace-mod/test.cpp:8:9
...

Observe that the only macro definition reported is the one in the main file, even though stddef.h defines a bunch too.

Scott McPeak
  • 8,803
  • 2
  • 40
  • 79