2016-03-15 20:51:40 +08:00
|
|
|
//===- AnnotateFunctions.cpp ----------------------------------------------===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// 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
|
2016-03-15 20:51:40 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2016-04-04 22:22:58 +08:00
|
|
|
// Example clang plugin which adds an annotation to every function in
|
|
|
|
// translation units that start with #pragma enable_annotate.
|
2016-03-15 20:51:40 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "clang/Frontend/FrontendPluginRegistry.h"
|
|
|
|
#include "clang/AST/AST.h"
|
|
|
|
#include "clang/AST/ASTConsumer.h"
|
2019-12-09 20:43:37 +08:00
|
|
|
#include "clang/AST/Attr.h"
|
2016-04-04 22:22:58 +08:00
|
|
|
#include "clang/Lex/Preprocessor.h"
|
|
|
|
#include "clang/Lex/LexDiagnostic.h"
|
2016-03-15 20:51:40 +08:00
|
|
|
using namespace clang;
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2016-04-04 22:22:58 +08:00
|
|
|
static bool EnableAnnotate = false;
|
|
|
|
static bool HandledDecl = false;
|
|
|
|
|
2016-03-15 20:51:40 +08:00
|
|
|
class AnnotateFunctionsConsumer : public ASTConsumer {
|
|
|
|
public:
|
|
|
|
bool HandleTopLevelDecl(DeclGroupRef DG) override {
|
2016-04-04 22:22:58 +08:00
|
|
|
HandledDecl = true;
|
|
|
|
if (!EnableAnnotate)
|
|
|
|
return true;
|
2016-03-15 20:51:40 +08:00
|
|
|
for (auto D : DG)
|
|
|
|
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
|
|
|
|
FD->addAttr(AnnotateAttr::CreateImplicit(FD->getASTContext(),
|
|
|
|
"example_annotation"));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class AnnotateFunctionsAction : public PluginASTAction {
|
|
|
|
public:
|
|
|
|
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
|
|
|
|
llvm::StringRef) override {
|
2019-08-15 07:04:18 +08:00
|
|
|
return std::make_unique<AnnotateFunctionsConsumer>();
|
2016-03-15 20:51:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ParseArgs(const CompilerInstance &CI,
|
|
|
|
const std::vector<std::string> &args) override {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
PluginASTAction::ActionType getActionType() override {
|
|
|
|
return AddBeforeMainAction;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-04-04 22:22:58 +08:00
|
|
|
class PragmaAnnotateHandler : public PragmaHandler {
|
|
|
|
public:
|
|
|
|
PragmaAnnotateHandler() : PragmaHandler("enable_annotate") { }
|
|
|
|
|
2019-05-22 07:51:38 +08:00
|
|
|
void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
|
2016-04-04 22:22:58 +08:00
|
|
|
Token &PragmaTok) override {
|
|
|
|
|
|
|
|
Token Tok;
|
|
|
|
PP.LexUnexpandedToken(Tok);
|
|
|
|
if (Tok.isNot(tok::eod))
|
|
|
|
PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
|
|
|
|
|
|
|
|
if (HandledDecl) {
|
|
|
|
DiagnosticsEngine &D = PP.getDiagnostics();
|
|
|
|
unsigned ID = D.getCustomDiagID(
|
|
|
|
DiagnosticsEngine::Error,
|
|
|
|
"#pragma enable_annotate not allowed after declarations");
|
|
|
|
D.Report(PragmaTok.getLocation(), ID);
|
|
|
|
}
|
|
|
|
|
|
|
|
EnableAnnotate = true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-03-15 20:51:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static FrontendPluginRegistry::Add<AnnotateFunctionsAction>
|
|
|
|
X("annotate-fns", "annotate functions");
|
2016-04-04 22:22:58 +08:00
|
|
|
|
|
|
|
static PragmaHandlerRegistry::Add<PragmaAnnotateHandler>
|
|
|
|
Y("enable_annotate","enable annotation");
|