diff options
Diffstat (limited to 'gnu/llvm/clang/examples/AnnotateFunctions/AnnotateFunctions.cpp')
-rw-r--r-- | gnu/llvm/clang/examples/AnnotateFunctions/AnnotateFunctions.cpp | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/gnu/llvm/clang/examples/AnnotateFunctions/AnnotateFunctions.cpp b/gnu/llvm/clang/examples/AnnotateFunctions/AnnotateFunctions.cpp new file mode 100644 index 00000000000..1724704fe12 --- /dev/null +++ b/gnu/llvm/clang/examples/AnnotateFunctions/AnnotateFunctions.cpp @@ -0,0 +1,88 @@ +//===- AnnotateFunctions.cpp ----------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Example clang plugin which adds an annotation to every function in +// translation units that start with #pragma enable_annotate. +// +//===----------------------------------------------------------------------===// + +#include "clang/Frontend/FrontendPluginRegistry.h" +#include "clang/AST/AST.h" +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/Attr.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Lex/LexDiagnostic.h" +using namespace clang; + +namespace { + +static bool EnableAnnotate = false; +static bool HandledDecl = false; + +class AnnotateFunctionsConsumer : public ASTConsumer { +public: + bool HandleTopLevelDecl(DeclGroupRef DG) override { + HandledDecl = true; + if (!EnableAnnotate) + return true; + 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 { + return std::make_unique<AnnotateFunctionsConsumer>(); + } + + bool ParseArgs(const CompilerInstance &CI, + const std::vector<std::string> &args) override { + return true; + } + + PluginASTAction::ActionType getActionType() override { + return AddBeforeMainAction; + } +}; + +class PragmaAnnotateHandler : public PragmaHandler { +public: + PragmaAnnotateHandler() : PragmaHandler("enable_annotate") { } + + void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, + 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; + } +}; + +} + +static FrontendPluginRegistry::Add<AnnotateFunctionsAction> +X("annotate-fns", "annotate functions"); + +static PragmaHandlerRegistry::Add<PragmaAnnotateHandler> +Y("enable_annotate","enable annotation"); |