Как установить LangOptions для AST Matcher (bool vs _Bool) - PullRequest
1 голос
/ 26 февраля 2020

Есть ли способ настроить LangOptions для AST matcher? У нас есть следующий подход:

using namespace clang;
using namespace clang::ast_matchers;

static llvm::cl::OptionCategory OptionCategory("options");

class CMatcherCallback : public MatchFinder::MatchCallback
{
public:
    virtual void run(const MatchFinder::MatchResult& result) override
    {
        if (const CXXMethodDecl* method = result.Nodes.getNodeAs<CXXMethodDecl>("id"))
        {
            method->dumpColor();
        }
    }
};

int main(int argc, const char** argv)
{
    tooling::CommonOptionsParser optionsParser(argc, argv, OptionCategory);
    tooling::ClangTool tool(optionsParser.getCompilations(),
                            optionsParser.getSourcePathList());

    CMatcherCallback callback;
    MatchFinder finder;
    finder.addMatcher(cxxMethodDecl(
                          hasName("Method"),
                          hasParameter(0, parmVarDecl(hasType(asString("bool")))))
                          .bind("id"),
                      &callback);
    int ret = tool.run(tooling::newFrontendActionFactory(&finder).get());

    return ret;
}

Этот метод не соответствует:

class CTest
{
  void Method(bool);
};

Он совпадает, когда мы меняем тип с hasParameter(0, parmVarDecl(hasType(asString("bool"))))) на _Bool. Таким образом, кажется, что сопоставитель находится в C вместо режима C ++?

Ответы [ 2 ]

0 голосов
/ 03 марта 2020

Пользовательское совпадение AST в конце концов простое, спасибо Валерии за указание на это.

namespace my_matchers
{
    AST_MATCHER_P2(QualType, asString, std::string, Name, PrintingPolicy, PP)
    {
        return Name == Node.getAsString(PP);
    }
}

...
PrintingPolicy printingPolicy(LangOptions{});
printingPolicy.Bool = 1;
...
hasParameter(0, parmVarDecl(hasType(my_matchers::asString("bool", printingPolicy))))

0 голосов
/ 27 февраля 2020

Ответ на фактический вопрос

Этот ответ не решит исходную проблему (пояснение ниже), но решит проблему, изложенную в вопросе. Это может быть полезно, если кто-то будет искать способ установки параметров.

using namespace clang;
using namespace clang::ast_matchers;

static llvm::cl::OptionCategory OptionCategory("options");

class CMatcherCallback : public MatchFinder::MatchCallback {
public:
  virtual void run(const MatchFinder::MatchResult &result) override {
    if (const CXXMethodDecl *method =
            result.Nodes.getNodeAs<CXXMethodDecl>("id")) {
      method->dumpColor();
    }
  }
};

class FinderFrontendAction : public clang::ASTFrontendAction {
public:
  FinderFrontendAction() {
    Finder.addMatcher(
        cxxMethodDecl(hasName("Method"),
                      hasParameter(0, parmVarDecl(hasType(asString("bool")))))
            .bind("id"),
        &Callback);
  }

  std::unique_ptr<clang::ASTConsumer>
  CreateASTConsumer(clang::CompilerInstance &CI, llvm::StringRef) override {
    auto &LO = CI.getLangOpts();
    LO.CPlusPlus = true;
    LO.Bool = true; // this is the actual option you are interested in
    return Finder.newASTConsumer();
  }

private:
  MatchFinder Finder;
  CMatcherCallback Callback;
};

int main(int argc, const char **argv) {
  tooling::CommonOptionsParser optionsParser(argc, argv, OptionCategory);
  tooling::ClangTool tool(optionsParser.getCompilations(),
                          optionsParser.getSourcePathList());

  int ret =
      tool.run(tooling::newFrontendActionFactory<FinderFrontendAction>().get());

  return ret;
}

Почему это не изменит результат

Clang понимает, что это код C ++ и что он имеет тип bool сам по себе. Так что этот код буквально ничего не меняет. Вы можете видеть, что когда вы печатаете AST, он на самом деле печатает bool.

Так откуда берется _Bool

Это проблема того, как реализовано сопоставление asString. Он использует QualType :: getAsString () метод (без параметров). Параметризованная версия этой функции принимает PrintingPolicy , которая определяет, как должны печататься различные типы.

LangOpts определяет способ печати определенных типов, поскольку из него создается PrintingPolicy, но не при вызове QualType::getAsString без политики печати. Он использует конструктор LangOpts по умолчанию и bool становится "_Bool".

Предлагаемое решение

Просто разберитесь с ним и используйте "_Bool". В противном случае вы можете реализовать свой собственный механизм сопоставления, который устраняет этот недостаток.

Надеюсь, это ответит на ваш вопрос!

...