我正在开发一个清晰的检查器,以在大型代码库中发现一些有问题的习语。我需要查看结构体中声明的常量大小数组,并确定大小是否作为整数文字给出,或者大小是否来自宏扩展。
例如,在这段代码中:
#define ARRSZ 392
typedef struct Foo {
int a;
int litsz[392];
int macsz[ARRSZ];
} Foo;
字段 litsz
和 macsz
的大小相同 (392)。但是,我的检查员需要区别对待它们。当然,在 AST 中,预处理完成后,这些 FieldDecls 在各个方面看起来都是相同的。不知怎的,我不得不使用预处理器来区分这些。
我很确定可行的一种方法是注册预处理器回调,并为发生的每个宏扩展缓存 SourceLocation。然后,当我查看字段时,我可以获得大小为 Expr 的 SourceLocation,并尝试在我的宏扩展缓存中找到该位置。如果我找到了位置,则是宏扩展,如果没有,则不是。虽然我认为我可以让它发挥作用,但它似乎效率极低。
我尝试在不构建所有宏扩展缓存的情况下执行此操作,方法是获取大小为 Expr 的 SourceLocation,然后调用 Preprocessor::isAtStartOfMacroExpansion()
。但这会触发 litsz
的断言——显然,如果您已经知道自己有一个宏,则只能使用预处理器的该方法。与 Preprocessor::getImmediateMacroName()
...
我怎样才能有效地做到这一点? (而且,理想情况下,只是...)