xref: /netbsd-src/external/apache2/llvm/dist/clang/examples/AnnotateFunctions/AnnotateFunctions.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
17330f729Sjoerg //===- AnnotateFunctions.cpp ----------------------------------------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // Example clang plugin which adds an annotation to every function in
107330f729Sjoerg // translation units that start with #pragma enable_annotate.
117330f729Sjoerg //
127330f729Sjoerg //===----------------------------------------------------------------------===//
137330f729Sjoerg 
147330f729Sjoerg #include "clang/Frontend/FrontendPluginRegistry.h"
157330f729Sjoerg #include "clang/AST/AST.h"
167330f729Sjoerg #include "clang/AST/ASTConsumer.h"
17*e038c9c4Sjoerg #include "clang/AST/Attr.h"
187330f729Sjoerg #include "clang/Lex/Preprocessor.h"
197330f729Sjoerg #include "clang/Lex/LexDiagnostic.h"
207330f729Sjoerg using namespace clang;
217330f729Sjoerg 
227330f729Sjoerg namespace {
237330f729Sjoerg 
247330f729Sjoerg static bool EnableAnnotate = false;
257330f729Sjoerg static bool HandledDecl = false;
267330f729Sjoerg 
277330f729Sjoerg class AnnotateFunctionsConsumer : public ASTConsumer {
287330f729Sjoerg public:
HandleTopLevelDecl(DeclGroupRef DG)297330f729Sjoerg   bool HandleTopLevelDecl(DeclGroupRef DG) override {
307330f729Sjoerg     HandledDecl = true;
317330f729Sjoerg     if (!EnableAnnotate)
327330f729Sjoerg       return true;
337330f729Sjoerg     for (auto D : DG)
347330f729Sjoerg       if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
35*e038c9c4Sjoerg         FD->addAttr(AnnotateAttr::CreateImplicit(
36*e038c9c4Sjoerg             FD->getASTContext(), "example_annotation", nullptr, 0));
377330f729Sjoerg     return true;
387330f729Sjoerg   }
397330f729Sjoerg };
407330f729Sjoerg 
417330f729Sjoerg class AnnotateFunctionsAction : public PluginASTAction {
427330f729Sjoerg public:
CreateASTConsumer(CompilerInstance & CI,llvm::StringRef)437330f729Sjoerg   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
447330f729Sjoerg                                                  llvm::StringRef) override {
457330f729Sjoerg     return std::make_unique<AnnotateFunctionsConsumer>();
467330f729Sjoerg   }
477330f729Sjoerg 
ParseArgs(const CompilerInstance & CI,const std::vector<std::string> & args)487330f729Sjoerg   bool ParseArgs(const CompilerInstance &CI,
497330f729Sjoerg                  const std::vector<std::string> &args) override {
507330f729Sjoerg     return true;
517330f729Sjoerg   }
527330f729Sjoerg 
getActionType()537330f729Sjoerg   PluginASTAction::ActionType getActionType() override {
547330f729Sjoerg     return AddBeforeMainAction;
557330f729Sjoerg   }
567330f729Sjoerg };
577330f729Sjoerg 
587330f729Sjoerg class PragmaAnnotateHandler : public PragmaHandler {
597330f729Sjoerg public:
PragmaAnnotateHandler()607330f729Sjoerg   PragmaAnnotateHandler() : PragmaHandler("enable_annotate") { }
617330f729Sjoerg 
HandlePragma(Preprocessor & PP,PragmaIntroducer Introducer,Token & PragmaTok)627330f729Sjoerg   void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
637330f729Sjoerg                     Token &PragmaTok) override {
647330f729Sjoerg 
657330f729Sjoerg     Token Tok;
667330f729Sjoerg     PP.LexUnexpandedToken(Tok);
677330f729Sjoerg     if (Tok.isNot(tok::eod))
687330f729Sjoerg       PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
697330f729Sjoerg 
707330f729Sjoerg     if (HandledDecl) {
717330f729Sjoerg       DiagnosticsEngine &D = PP.getDiagnostics();
727330f729Sjoerg       unsigned ID = D.getCustomDiagID(
737330f729Sjoerg         DiagnosticsEngine::Error,
747330f729Sjoerg         "#pragma enable_annotate not allowed after declarations");
757330f729Sjoerg       D.Report(PragmaTok.getLocation(), ID);
767330f729Sjoerg     }
777330f729Sjoerg 
787330f729Sjoerg     EnableAnnotate = true;
797330f729Sjoerg   }
807330f729Sjoerg };
817330f729Sjoerg 
827330f729Sjoerg }
837330f729Sjoerg 
847330f729Sjoerg static FrontendPluginRegistry::Add<AnnotateFunctionsAction>
857330f729Sjoerg X("annotate-fns", "annotate functions");
867330f729Sjoerg 
877330f729Sjoerg static PragmaHandlerRegistry::Add<PragmaAnnotateHandler>
887330f729Sjoerg Y("enable_annotate","enable annotation");
89