如何利用Clang AST Matcher正确获取静态函数CallExpr的源位置?
解决clang-tidy获取静态成员函数CallExpr正确源位置的问题
我在构建用于重构的自定义clang-tidy工具时,遇到了获取静态成员函数CallExpr正确源位置的问题:
示例C++代码
class Test { public: static void foo(){} };
对应的clang-tidy匹配代码
Finder->addMatcher( traverse(TraversalKind::TK_IgnoreUnlessSpelledInSource, callExpr(callee(functionDecl(hasAncestor( namespaceDecl(hasName("my_namespace")))))) .bind("call_expr")), this);
当前输出(使用MatchedCallExpr->getExprLoc())
Test::foo() ~~~~ ^ This function name should blahblahblah
期望输出
Test::foo() ~~~ ^ This function name should blahblahblah
解决方案
问题核心是getExprLoc()返回的是整个调用表达式的起始位置(即Test的位置),而非目标函数名foo的位置。要精准定位到函数名,需要从CallExpr中提取被调用函数的声明,再获取函数名的具体位置:
修改后的核心代码
const auto *CallExpr = Result.Nodes.getNodeAs<clang::CallExpr>("call_expr"); if (!CallExpr) return; const auto *CalleeDecl = CallExpr->getCalleeDecl(); const auto *FuncDecl = llvm::dyn_cast<clang::FunctionDecl>(CalleeDecl); if (!FuncDecl || !FuncDecl->getIdentifier()) return; // 获取函数名的起始位置 clang::SourceLocation FuncNameLoc = FuncDecl->getIdentifier()->getLocation(); // 获取函数名的长度,用于标记波浪线范围 unsigned int FuncNameLength = FuncDecl->getName().size(); // 生成诊断信息 Diag(FuncNameLoc, "This function name should blahblahblah") << clang::FixItHint::CreateReplacement( clang::SourceRange(FuncNameLoc, FuncNameLoc.getLocWithOffset(FuncNameLength)), /* 按需填写替换内容 */);
关键说明
CallExpr->getCalleeDecl():获取被调用函数的声明对象,转换为FunctionDecl后可访问函数名相关信息。FuncDecl->getIdentifier()->getLocation():精准定位到函数名(如foo)的起始字符位置。FuncDecl->getName().size():获取函数名的长度,用于生成覆盖整个函数名的波浪线标记范围。
内容的提问来源于stack exchange,提问作者armques
相关产品推荐
相关产品推荐

