1

我有一个带有要弃用的函数声明的示例文件。我想添加此C++ 标记以使编译器在调用此函数时发出警告,如下所示:

...simple_test.cpp:45:5: warning: 'free_fun' is deprecated [-Wdeprecated-declarations]
    free_fun();
    ^
...simple_test.cpp:40:3: note: 'free_fun' has been explicitly marked deprecated here
[[deprecated]]
  ^
1 warning generated.

我写了一个示例插件:

#include <clang/Frontend/FrontendPluginRegistry.h>
#include <clang/AST/AST.h>
#include <clang/AST/ASTConsumer.h>
#include <llvm/Support/raw_ostream.h>
#include <clang/ASTMatchers/ASTMatchFinder.h>
#include <clang/ASTMatchers/ASTMatchers.h>



using namespace clang;
using namespace ast_matchers;


DeclarationMatcher methodMatch   = cxxMethodDecl().bind("method");
DeclarationMatcher freeFuncMatch = functionDecl().bind("method");

class SymbolCollector : public MatchFinder::MatchCallback {
public:
  virtual void run(const MatchFinder::MatchResult &Result){
    auto* decl = Result.Nodes.getNodeAs<FunctionDecl>("method");
    auto attr = DeprecatedAttr::CreateImplicit(decl->getASTContext(),"Dont use this!", "");
    auto* mod_decl = const_cast<FunctionDecl*>(decl);
    mod_decl->addAttr(attr);
  }
};

class AnnotateDeprecationConsumer : public ASTConsumer {
public:

  AnnotateDeprecationConsumer() {
    d_matcher.addMatcher(methodMatch, &d_collector);
    d_matcher.addMatcher(freeFuncMatch, &d_collector);
  }

  void HandleTranslationUnit(ASTContext &Context) override {
    d_matcher.matchAST(Context);
  }

  // bool HandleTopLevelDecl(DeclGroupRef DG) override {
  //  for (auto D : DG) {
  //      if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
  //        auto attr = DeprecatedAttr::CreateImplicit(FD->getASTContext(),"Dont use this!", "");
  //        FD->addAttr(attr);
  //      }
  //  }
  //  return true;
  //}

private:
  MatchFinder     d_matcher;
  SymbolCollector d_collector;
};

class AnnotateDeprecationAction : public PluginASTAction {
public:
  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
                                                 llvm::StringRef) override {
    return llvm::make_unique<AnnotateDeprecationConsumer>();
  }

  bool ParseArgs(const CompilerInstance &CI,
                 const std::vector<std::string> &args) override {
    return true;
  }

  PluginASTAction::ActionType getActionType() override {
    return AddBeforeMainAction;
  }
};


static FrontendPluginRegistry::Add<AnnotateDeprecationAction>X("annotate-dep", "annotate functions with deprecated tag");

但是当我调用它时,它不会发出任何警告。如果我转储 ast,我会看到已添加弃用属性,但我没有收到任何警告。

如果我使用 HandleTopLevelDecls 它可以工作,但我需要匹配器来实现我想要的。

我的猜测是在遍历 ast 之后添加标签(第一个提示:getNodeAs 返回一个 const obj),因此添加标签为时已晚。

但是我认为通过覆盖 getActionType 我可以实现该结果,但似乎情况并非如此?

4

0 回答 0