我有一个带有要弃用的函数声明的示例文件。我想添加此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 我可以实现该结果,但似乎情况并非如此?