问题描述
我正在尝试编写一个整洁的规则,该规则将更改函数名称 并修改字符串文字参数。目标是从tinyFormat自动移植到libfmt。
我在这里找到了我认为是很好的匹配者:
finder->addMatcher(
callExpr(
callee(functionDecl(hasName("::tiny::Format"))),optionally(hasArgument(
0,ignoringImpCasts(
declRefExpr(
to(varDecl(hasType(hasUnqualifiedDesugaredType(
recordtype(hasDeclaration(
cxxRecordDecl(isDerivedFrom(
"::std::basic_ostream")))))))))
.bind("streamArg")))),anyOf(hasArgument(0,stringLiteral().bind("fmtLiteral")),hasArgument(1,stringLiteral().bind("fmtLiteral"))))
.bind("call"),this);
麻烦在于编写替换规则。如果我创建了1个fixit来替换名称,并创建了一个单独的替换来更改字符串文字(从%s样式更改为{}样式),则它们会互相tom脚。在尝试编写单个长替换字符串时,我遇到了一个非常棘手的问题:似乎不可能可靠地获取字符串文字的 last 字符。目前我有这个,但是它使文字是否在宏中(例如ASSERT_ALWAYS)感到窒息。我也尝试过使用findLocationAfterToken并没有运气。
fmtDiag << clang::FixItHint::CreateReplacement(
callExpr->getSourceRange(),(llvm::Twine(streamArg ? "fmt::print(" : "fmt::format(") // use fmt::print if we're printing to a stream
+ (streamArg ? clang::tooling::fixit::getText(
streamArg->getSourceRange(),*result.Context)
+ ","
: StringRef())
+ llvm::Twine(TransformFormatString(fmtLiteral->getString()))
+ clang::tooling::fixit::getText(
SourceRange(
// Note(wgray): I have no idea why this is required,but just
// using fmtLiteral->getEndLoc() doesn't work. This magic
// incantation was taken from
// bugprone/NotNullTerminatedResultCheck.cpp
Lexer::getLocForEndOfToken(
fmtLiteral->getEndLoc(),*result.sourceManager,result.Context->getLangOpts()),endLoc,callExpr->getEndLoc()),*result.Context));
```
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)