Hey all,
In IWYU we have very naive expansion of unused macros to be able to track macros that are used inside other macros, for the purposes of tracking include dependencies. A simple example is something like:
// my_assert.h
#include <assert.h>
#define MY_ASSERT(x) assert(x)
We want to note assert as used in this file even though MY_ASSERT is never expanded.
I was surprised to see that Clang accepts this:
// foo.h
#include <cassert>
void foo(bool x) {
assert(x);
}
namespace top { namespace assert {
void bar();
}
}
// t.cc
#include "foo.h"
#define BAR top::assert::bar()
The namespace assert declaration and use seem to work because assert() is a function-like macro and won’t be expanded without the call-syntax.
However, when we peek into the BAR macro definition, the Clang preprocessor still thinks the identifier assert is a macro. I haven’t fully got my head around the Clang preprocessor, so I was hoping someone could give me a thread to start pulling on…
Where does Clang decide whether to expand assert or leave it as a non-macro identifier? If I could replicate that logic, I should be able to analyze this more true to the language.
Thanks!