I'm a beginner to C++, attempting to lint Objective-C code with clang. I understand that macros are first expanded before nodes and properties are visited with AST.
I have a macro named NIL_CHECK
, which is used in numerous files. While performing the lint, I would like to skip the variable declaration of the line where this macro is expanded/used.
For instance, the first line in this example should be linted, while the second line needs to be skipped such that false positives are not thrown when there's a macro expansion:
// Must be checked
NSDictionary *playerParams = @{ @"videoId" : videoId, @"playerVars" : playerVars };
// Must be skipped since there's a macro
PlayerProfile *const playerProfile = [[PlayerProfile alloc] initWithData:NIL_CHECK(playerParams)];
Here is the VisitVarDecl
visitor method, which traverses through each variable declaration to perform appropriate lint checks:
bool VisitVarDecl(VarDecl *node) {
if (isCollectionType(node -> getType()) && !hasTypeArguments(node -> getType())) {
addViolation(node, this, description(node -> getNameAsString()));
}
return true;
}
How can I determine macros and skip such variable declarations?
Here is a nice answer by Valeriy, I think it covers what you want to achieve.
To summarise: You want to find the string
NIL_CHECK
inside a VarDecl, which has already been expanded when you visit the AST. The original text in your source code can be obtained with the help ofLexer
. You can use the location of the full varDecl expr or only the macro-contained part. Then the macro name can be detected from the string returned bygetSourceText
of the Lexer .