Galaxy
Galaxy

Reputation: 2481

clang::ast_matchers::thisPointerType ambiguous call to overloaded function

I am working on a project involving Clang AST matchers. This is one such AST matcher that I'm having.

StatementMatcher getNumUses_matcher1 = binaryOperator(
    hasOperatorName(">"),
    hasLHS(ignoringParenImpCasts(
        cxxMemberCallExpr(
            thisPointerType(hasDeclaration(cxxRecordDecl(isSameOrDerivedFrom("Value")))),
            hasDeclaration(cxxMethodDecl(hasName("getNumUses")))
        )
    )),
    hasRHS(ignoringParenImpCasts(
        integerLiteral(equals(0))
    ))
).bind("type1");

I'm compiling the project on Windows using Microsoft Visual Studio Compiler. I checked, and the matcher looks syntactically ok. But the compiler complains.

cxxMemberCallExpr term does not evaluate to a function taking 2 arguments
thisPointerType more than one instance of overloaded function "thisPointerType" matches the argument list
thisPointerType 'clang::ast_matchers::thisPointerType': ambiguous call to overloaded function

enter image description here

enter image description here

So it seems that this is a compiler syntax error. But here's the strange part.

Whenever I run this exact same ast matcher through clang-query it just works! clang-query also checks the syntax, but here there is no syntax error being reported. It runms the ast matcher and successfully matcher the desired expressions as expected.

clang-query> match binaryOperator(hasOperatorName(">"),hasLHS(ignoringParenImpCasts(cxxMemberCallExpr(thisPointerType(hasDeclaration(cxxRecordDecl(isSameOrDerivedFrom("Value")))),hasDeclaration(cxxMethodDecl(hasName("getNumUses")))))),hasRHS(ignoringParenImpCasts(integerLiteral(equals(0)))))

Match #1:

C:\work\sample_example\sample_example.cpp:77:9: note: "root" binds here
        pGlobalVar->getNumUses() > 0
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

If I try to compile the same code with clang++ compiler:

ReplaceGetNumUses.cpp:62:17: error: call to 'thisPointerType' is ambiguous
                thisPointerType(hasDeclaration(cxxRecordDecl(isSameOrDerivedFrom("Value")))),
                ^~~~~~~~~~~~~~~
C:\clang_llvm\llvm-project-master\clang\include\clang/ASTMatchers/ASTMatchers.h:3741:43: note: candidate function
AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType,
                                          ^
C:\clang_llvm\llvm-project-master\clang\include\clang/ASTMatchers/ASTMatchers.h:3749:43: note: candidate function
AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType,
                                          ^

Upvotes: 2

Views: 302

Answers (1)

Galaxy
Galaxy

Reputation: 2481

I'm not sure why clang-query accepts the AST matcher above, while both clang++ and Microsoft Visual Studio cl compiler mark it as a syntax error. I found a solution though.

I restructured my AST matcher. I used a slightly different syntax for it. Now this one compiles, and also clang-query accepts it, generating the same results as the AST matcher above.

StatementMatcher getNumUses_matcher1 = binaryOperator(
    hasOperatorName(">"),
    hasLHS(ignoringParenImpCasts(
        cxxMemberCallExpr(hasDeclaration(cxxMethodDecl(
            hasName("getNumUses"),
            ofClass(isSameOrDerivedFrom("Value"))
        )))
    )),
    hasRHS(ignoringParenImpCasts(
        integerLiteral(equals(0))
    ))
).bind("type1");

Now in this approach I search for the name of the class by applying an ofClass() to the cxxMethodDecl() instead of using a thisPointerType() on the cxxMemberCallExpr().

The problem may be in that thisPointerType() has two overloads. According to the AST Matcher Reference.

Return type                 Name             Parameters

Matcher<CXXMemberCallExpr>  thisPointerType Matcher<Decl> InnerMatcher

Matcher<CXXMemberCallExpr>  thisPointerType Matcher<QualType> InnerMatcher

But I don't know enough about this to say for certain. Can anyone explain to me why that is?

Upvotes: 1

Related Questions