首页 > 解决方案 > Clang tidy:在表达式末尾添加括号

问题描述

我正在尝试编写一个clang tidy matcher,它在函数调用中替换给定宏的使用。让我们举一个例子来更好地解释我的情况。

#define ADD(a, b) \
    (a + b)

int foo(int a, int b, int c) {
    return a + b + c;
}

int add(int a, int b, int c) {
    return a + b + c;
}

需要更换:

foo(1, ADD(2, 3), 4);

进入

foo(1, add(2, 3, 4));

为了匹配ADD宏,我定义了一个继承自的类,PPCallbacks我重写了MacroExpands获取参数列表并用函数替换的方法add

static bool isAdd_Macro(StringRef MacroName) {
  static const llvm::StringSet<> MacroNames = {"ADD"};

  return MacroNames.find(MacroName) != MacroNames.end();
}

class ReplaceMacroCallback : public PPCallbacks {
public:
  ReplaceMacroCallback(ReplaceMacro *Check, Preprocessor *PP) : Check(Check), PP(PP) {}

  void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) override {
    IdentifierInfo *NameIdentifierInfo = MacroNameTok.getIdentifierInfo();
    if (!NameIdentifierInfo)
      return;

    auto MacroName = NameIdentifierInfo->getName();

    if (!isAdd_Macro(MacroName) || !Args || Args->getNumMacroArguments() != 2) {
      return;
    }

    SourceRange LocationToBeReplaced(Range.getBegin(), Range.getEnd());

    const auto *FirstArgToken = Args->getUnexpArgument(0);
    const auto *SecondArgToken= Args->getUnexpArgument(1);
    if (!FirstArgToken || !SecondArgToken) {
      return;
    }

    auto FirstArg = PP->getSpelling(*FirstArgToken);
    auto SecondArg = PP->getSpelling(*SecondArgToken);

    std::ostringstream CodeReplacement;
    CodeReplacement << "add(" << FirstArg << ", " << SecondArg;

    Check->diag(Range.getBegin(), "Replace \"%0\" with add")
      << MacroName << FixItHint::CreateReplacement(LocationToBeReplaced, CodeReplacement.str());
  }

private:
  ReplaceMacro *Check;
  Preprocessor *PP;
};

到目前为止,一切都清楚了。现在我要解决的问题是如何add在表达式末尾添加右括号。

foo(1, add(2, 3, 4));
                  ^

有人知道怎么做吗?

标签: c++clangclang-tidy

解决方案


推荐阅读