Reputation: 2481
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
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
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