首页 > 解决方案 > clang::ast_matchers::thisPointerType 对重载函数的模糊调用

问题描述

我正在从事一个涉及 Clang AST 匹配器的项目。这是我拥有的一个这样的 AST 匹配器。

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

我正在使用 Microsoft Visual Studio 编译器在 Windows 上编译项目。我检查了一下,匹配器在语法上看起来没问题。但是编译器抱怨。

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

在此处输入图像描述

在此处输入图像描述

所以这似乎是一个编译器语法错误。但这是奇怪的部分。

每当我通过它运行这个完全相同的 ast 匹配器时,clang-query它就可以工作!clang-query还检查语法,但这里没有报告语法错误。它运行 ast 匹配器并按预期成功匹配所需的表达式。

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
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

如果我尝试用clang++编译器编译相同的代码:

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,
                                          ^

标签: c++clangabstract-syntax-treellvm-clang

解决方案


我不确定为什么clang-query接受上面的 AST 匹配器,而clang++Microsoft Visual Studiocl编译器都将其标记为语法错误。我找到了一个解决方案。

我重组了我的 AST 匹配器。我使用了稍微不同的语法。现在这个编译器也clang-query接受它,生成与上面的 AST 匹配器相同的结果。

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

现在在这种方法中,我通过将 anofClass()应用于cxxMethodDecl()而不是thisPointerType()cxxMemberCallExpr().

问题可能在于thisPointerType()有两个重载。根据AST Matcher Reference

Return type                 Name             Parameters

Matcher<CXXMemberCallExpr>  thisPointerType Matcher<Decl> InnerMatcher

Matcher<CXXMemberCallExpr>  thisPointerType Matcher<QualType> InnerMatcher

但我对此知之甚少,无法肯定地说。谁能向我解释为什么会这样?


推荐阅读