Determining macro expansion for VarDecl in clang

335 Views Asked by At

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?

1

There are 1 best solutions below

0
On

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 of Lexer. 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 by getSourceText of the Lexer .