使用clang AST将表达式替换为宏

使用clang AST将表达式替换为宏,c,abstract-syntax-tree,clang-ast-matchers,C,Abstract Syntax Tree,Clang Ast Matchers,我希望在clang ast matcher的帮助下更改以下代码 foo(NUM << DEV_SHIFT | DEVICE); 与 #定义ADDR(a,b)((a)addMatcher( callExpr(hasArgument( 0,二进制运算符(hasOperatorName(“|”), hasLHS(忽略parenimpcasts)( binaryOperator(hasOperatorName)(这是我非常满意的解决方案。它基于boq在评论中的建议 //===--- Fir

我希望在clang ast matcher的帮助下更改以下代码

foo(NUM << DEV_SHIFT | DEVICE);

#定义ADDR(a,b)((a)addMatcher(
callExpr(hasArgument(
0,二进制运算符(hasOperatorName(“|”),
hasLHS(忽略parenimpcasts)(

binaryOperator(hasOperatorName)(这是我非常满意的解决方案。它基于boq在评论中的建议

//===--- FirstCheckCheck.cpp - clang-tidy ---------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "FirstCheckCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace misc {

void FirstCheckCheck::registerMatchers(MatchFinder *Finder) {
  // FIXME: Add matchers.
  //
  Finder->addMatcher(
      callExpr(hasArgument(
          1,
          binaryOperator(
              hasOperatorName("|"),
              hasRHS(ignoringImplicit(
                  anyOf(declRefExpr().bind("moduleNum"), integerLiteral().bind(
                      "moduleNum")))),
              hasLHS(ignoringParens(
                  binaryOperator(hasOperatorName("<<"),
                                 hasLHS(ignoringImplicit(anyOf(
                                     declRefExpr().bind("deviceNum"),
                                     integerLiteral().bind("deviceNum"))))))))
              .bind("replaceWithMacro"))),
      this);
}

void FirstCheckCheck::check(const MatchFinder::MatchResult &Result) {
  // FIXME: Add callback implementation.
    std::string deviceNumString;
    std::string moduleNumString;
    std::string ReplacementText;

  if (const auto MatchedDecl =
          Result.Nodes.getNodeAs<Expr>("deviceNum")) {

    const LangOptions &Opts = getLangOpts();

    /* get device string */
    deviceNumString = Lexer::getSourceText(
        CharSourceRange::getTokenRange(MatchedDecl->getSourceRange()),
        *Result.SourceManager, Opts);
  }
  /* ((uint16_t)(deviceNum << 8 | moduleNum)) */
  if (const auto MatchedDecl =
          Result.Nodes.getNodeAs<Expr>("moduleNum")) {

    const LangOptions &Opts = getLangOpts();

    moduleNumString = Lexer::getSourceText(
        CharSourceRange::getTokenRange(MatchedDecl->getSourceRange()),
        *Result.SourceManager, Opts);
  }
  if (const auto MatchedDecl =
                 Result.Nodes.getNodeAs<Expr>("replaceWithMacro")) {
    const LangOptions &Opts = getLangOpts();

    ReplacementText = Lexer::getSourceText(
        CharSourceRange::getTokenRange(MatchedDecl->getSourceRange()),
        *Result.SourceManager, Opts);

    std::string replacementString =
        "ADDR(" + deviceNumString + ", " + moduleNumString + ")";

    FixItHint Hint = FixItHint::CreateReplacement(
        MatchedDecl->getSourceRange(), replacementString);

    diag(MatchedDecl->getBeginLoc(), "Replace with ADDR() macro") << Hint;
  }

  /* diag(MatchedDecl->getLocation(), "insert 'awesome'", DiagnosticIDs::Note)
   */
  /*     << FixItHint::CreateInsertion(MatchedDecl->getLocation(), "awesome_");
   */
}

} // namespace misc
} // namespace tidy
} // namespace clang
//==--FirstCheckCheck.cpp-clangtidy---------------------------------===//
//
//LLVM项目的一部分,在Apache许可证v2.0下,有LLVM例外。
//看https://llvm.org/LICENSE.txt 获取许可证信息。
//SPDX许可证标识符:带LLVM异常的Apache-2.0
//
//===----------------------------------------------------------------------===//
#包括“FirstCheckCheck.h”
#包括“clang/AST/ASTContext.h”
#包括“clang/ASTMatchers/ASTMatchFinder.h”
使用名称空间clang::ast_匹配器;
名称空间响声{
命名空间整洁{
命名空间杂项{
void FirstCheckCheck::registerMatchers(MatchFinder*Finder){
//修正:添加匹配器。
//
查找器->添加匹配器(
callExpr(hasArgument)(
1.
二进制运算符(
hasOperatorName(“|”),
hasRHS(忽略输入)(
anyOf(declRefExpr().bind(“moduleNum”),integerLiteral().bind(
“moduleNum”)),
hasLHS(忽略参数)(

binaryOperator(hasOperatorName)(“在展开式中(处理算术或逻辑表达式时)始终在宏参数名称周围加括号)。因此:
#define ADDR(a,b)((a)在我看来,您正试图从表达式中提取两个变量。为什么不添加两个附加绑定?您已经计算出匹配器,只需修改一点以绑定
#define ADDR(a, b) (((a) << NUM_SHIFT) | (b))
Finder->addMatcher(
       callExpr(hasArgument(                                                                                                                                                             
           0, binaryOperator(hasOperatorName("|"),
                             hasLHS(ignoringParenImpCasts(
                                 binaryOperator(hasOperatorName("<<")))))
                  .bind("replaceWithMacro"))),
       this);
void FirstCheckCheck::check(const MatchFinder::MatchResult &Result) {
  // FIXME: Add callback implementation.
  if (const auto MatchedDecl =
          Result.Nodes.getNodeAs<CallExpr>("replaceWithMacro")) {
    diag(MatchedDecl->getExprLoc(), "CallExp");
  } else if (const auto MatchedDecl =
                 Result.Nodes.getNodeAs<Expr>("replaceWithMacro")) {
    diag(MatchedDecl->getExprLoc(), "Expr");
    diag(MatchedDecl->getBeginLoc(), "BeginLOC");
    diag(MatchedDecl->getEndLoc(), "EndLOC");
  }

//===--- FirstCheckCheck.cpp - clang-tidy ---------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "FirstCheckCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace misc {

void FirstCheckCheck::registerMatchers(MatchFinder *Finder) {
  // FIXME: Add matchers.
  //
  Finder->addMatcher(
      callExpr(hasArgument(
          1,
          binaryOperator(
              hasOperatorName("|"),
              hasRHS(ignoringImplicit(
                  anyOf(declRefExpr().bind("moduleNum"), integerLiteral().bind(
                      "moduleNum")))),
              hasLHS(ignoringParens(
                  binaryOperator(hasOperatorName("<<"),
                                 hasLHS(ignoringImplicit(anyOf(
                                     declRefExpr().bind("deviceNum"),
                                     integerLiteral().bind("deviceNum"))))))))
              .bind("replaceWithMacro"))),
      this);
}

void FirstCheckCheck::check(const MatchFinder::MatchResult &Result) {
  // FIXME: Add callback implementation.
    std::string deviceNumString;
    std::string moduleNumString;
    std::string ReplacementText;

  if (const auto MatchedDecl =
          Result.Nodes.getNodeAs<Expr>("deviceNum")) {

    const LangOptions &Opts = getLangOpts();

    /* get device string */
    deviceNumString = Lexer::getSourceText(
        CharSourceRange::getTokenRange(MatchedDecl->getSourceRange()),
        *Result.SourceManager, Opts);
  }
  /* ((uint16_t)(deviceNum << 8 | moduleNum)) */
  if (const auto MatchedDecl =
          Result.Nodes.getNodeAs<Expr>("moduleNum")) {

    const LangOptions &Opts = getLangOpts();

    moduleNumString = Lexer::getSourceText(
        CharSourceRange::getTokenRange(MatchedDecl->getSourceRange()),
        *Result.SourceManager, Opts);
  }
  if (const auto MatchedDecl =
                 Result.Nodes.getNodeAs<Expr>("replaceWithMacro")) {
    const LangOptions &Opts = getLangOpts();

    ReplacementText = Lexer::getSourceText(
        CharSourceRange::getTokenRange(MatchedDecl->getSourceRange()),
        *Result.SourceManager, Opts);

    std::string replacementString =
        "ADDR(" + deviceNumString + ", " + moduleNumString + ")";

    FixItHint Hint = FixItHint::CreateReplacement(
        MatchedDecl->getSourceRange(), replacementString);

    diag(MatchedDecl->getBeginLoc(), "Replace with ADDR() macro") << Hint;
  }

  /* diag(MatchedDecl->getLocation(), "insert 'awesome'", DiagnosticIDs::Note)
   */
  /*     << FixItHint::CreateInsertion(MatchedDecl->getLocation(), "awesome_");
   */
}

} // namespace misc
} // namespace tidy
} // namespace clang