1e5dd7070Spatrick //===- AnnotateFunctions.cpp ----------------------------------------------===// 2e5dd7070Spatrick // 3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information. 5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e5dd7070Spatrick // 7e5dd7070Spatrick //===----------------------------------------------------------------------===// 8e5dd7070Spatrick // 9e5dd7070Spatrick // Example clang plugin which adds an annotation to every function in 10e5dd7070Spatrick // translation units that start with #pragma enable_annotate. 11e5dd7070Spatrick // 12e5dd7070Spatrick //===----------------------------------------------------------------------===// 13e5dd7070Spatrick 14e5dd7070Spatrick #include "clang/Frontend/FrontendPluginRegistry.h" 15e5dd7070Spatrick #include "clang/AST/AST.h" 16e5dd7070Spatrick #include "clang/AST/ASTConsumer.h" 17e5dd7070Spatrick #include "clang/AST/Attr.h" 18e5dd7070Spatrick #include "clang/Lex/Preprocessor.h" 19e5dd7070Spatrick #include "clang/Lex/LexDiagnostic.h" 20e5dd7070Spatrick using namespace clang; 21e5dd7070Spatrick 22e5dd7070Spatrick namespace { 23e5dd7070Spatrick 24e5dd7070Spatrick static bool EnableAnnotate = false; 25e5dd7070Spatrick static bool HandledDecl = false; 26e5dd7070Spatrick 27e5dd7070Spatrick class AnnotateFunctionsConsumer : public ASTConsumer { 28e5dd7070Spatrick public: HandleTopLevelDecl(DeclGroupRef DG)29e5dd7070Spatrick bool HandleTopLevelDecl(DeclGroupRef DG) override { 30e5dd7070Spatrick HandledDecl = true; 31e5dd7070Spatrick if (!EnableAnnotate) 32e5dd7070Spatrick return true; 33e5dd7070Spatrick for (auto D : DG) 34e5dd7070Spatrick if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 35*a9ac8606Spatrick FD->addAttr(AnnotateAttr::CreateImplicit( 36*a9ac8606Spatrick FD->getASTContext(), "example_annotation", nullptr, 0)); 37e5dd7070Spatrick return true; 38e5dd7070Spatrick } 39e5dd7070Spatrick }; 40e5dd7070Spatrick 41e5dd7070Spatrick class AnnotateFunctionsAction : public PluginASTAction { 42e5dd7070Spatrick public: CreateASTConsumer(CompilerInstance & CI,llvm::StringRef)43e5dd7070Spatrick std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, 44e5dd7070Spatrick llvm::StringRef) override { 45e5dd7070Spatrick return std::make_unique<AnnotateFunctionsConsumer>(); 46e5dd7070Spatrick } 47e5dd7070Spatrick ParseArgs(const CompilerInstance & CI,const std::vector<std::string> & args)48e5dd7070Spatrick bool ParseArgs(const CompilerInstance &CI, 49e5dd7070Spatrick const std::vector<std::string> &args) override { 50e5dd7070Spatrick return true; 51e5dd7070Spatrick } 52e5dd7070Spatrick getActionType()53e5dd7070Spatrick PluginASTAction::ActionType getActionType() override { 54e5dd7070Spatrick return AddBeforeMainAction; 55e5dd7070Spatrick } 56e5dd7070Spatrick }; 57e5dd7070Spatrick 58e5dd7070Spatrick class PragmaAnnotateHandler : public PragmaHandler { 59e5dd7070Spatrick public: PragmaAnnotateHandler()60e5dd7070Spatrick PragmaAnnotateHandler() : PragmaHandler("enable_annotate") { } 61e5dd7070Spatrick HandlePragma(Preprocessor & PP,PragmaIntroducer Introducer,Token & PragmaTok)62e5dd7070Spatrick void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, 63e5dd7070Spatrick Token &PragmaTok) override { 64e5dd7070Spatrick 65e5dd7070Spatrick Token Tok; 66e5dd7070Spatrick PP.LexUnexpandedToken(Tok); 67e5dd7070Spatrick if (Tok.isNot(tok::eod)) 68e5dd7070Spatrick PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma"; 69e5dd7070Spatrick 70e5dd7070Spatrick if (HandledDecl) { 71e5dd7070Spatrick DiagnosticsEngine &D = PP.getDiagnostics(); 72e5dd7070Spatrick unsigned ID = D.getCustomDiagID( 73e5dd7070Spatrick DiagnosticsEngine::Error, 74e5dd7070Spatrick "#pragma enable_annotate not allowed after declarations"); 75e5dd7070Spatrick D.Report(PragmaTok.getLocation(), ID); 76e5dd7070Spatrick } 77e5dd7070Spatrick 78e5dd7070Spatrick EnableAnnotate = true; 79e5dd7070Spatrick } 80e5dd7070Spatrick }; 81e5dd7070Spatrick 82e5dd7070Spatrick } 83e5dd7070Spatrick 84e5dd7070Spatrick static FrontendPluginRegistry::Add<AnnotateFunctionsAction> 85e5dd7070Spatrick X("annotate-fns", "annotate functions"); 86e5dd7070Spatrick 87e5dd7070Spatrick static PragmaHandlerRegistry::Add<PragmaAnnotateHandler> 88e5dd7070Spatrick Y("enable_annotate","enable annotation"); 89