16c78974bSJohn Brawn //===- AnnotateFunctions.cpp ----------------------------------------------===// 26c78974bSJohn Brawn // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 66c78974bSJohn Brawn // 76c78974bSJohn Brawn //===----------------------------------------------------------------------===// 86c78974bSJohn Brawn // 98e62db32SJohn Brawn // Example clang plugin which adds an annotation to every function in 108e62db32SJohn Brawn // translation units that start with #pragma enable_annotate. 116c78974bSJohn Brawn // 126c78974bSJohn Brawn //===----------------------------------------------------------------------===// 136c78974bSJohn Brawn 146c78974bSJohn Brawn #include "clang/Frontend/FrontendPluginRegistry.h" 156c78974bSJohn Brawn #include "clang/AST/AST.h" 166c78974bSJohn Brawn #include "clang/AST/ASTConsumer.h" 17f7e7a5f1SDavid Green #include "clang/AST/Attr.h" 188e62db32SJohn Brawn #include "clang/Lex/Preprocessor.h" 198e62db32SJohn Brawn #include "clang/Lex/LexDiagnostic.h" 206c78974bSJohn Brawn using namespace clang; 216c78974bSJohn Brawn 226c78974bSJohn Brawn namespace { 236c78974bSJohn Brawn 248e62db32SJohn Brawn static bool EnableAnnotate = false; 258e62db32SJohn Brawn static bool HandledDecl = false; 268e62db32SJohn Brawn 276c78974bSJohn Brawn class AnnotateFunctionsConsumer : public ASTConsumer { 286c78974bSJohn Brawn public: HandleTopLevelDecl(DeclGroupRef DG)296c78974bSJohn Brawn bool HandleTopLevelDecl(DeclGroupRef DG) override { 308e62db32SJohn Brawn HandledDecl = true; 318e62db32SJohn Brawn if (!EnableAnnotate) 328e62db32SJohn Brawn return true; 336c78974bSJohn Brawn for (auto D : DG) 346c78974bSJohn Brawn if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 35*2618247cSTyker FD->addAttr(AnnotateAttr::CreateImplicit( 36*2618247cSTyker FD->getASTContext(), "example_annotation", nullptr, 0)); 376c78974bSJohn Brawn return true; 386c78974bSJohn Brawn } 396c78974bSJohn Brawn }; 406c78974bSJohn Brawn 416c78974bSJohn Brawn class AnnotateFunctionsAction : public PluginASTAction { 426c78974bSJohn Brawn public: CreateASTConsumer(CompilerInstance & CI,llvm::StringRef)436c78974bSJohn Brawn std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, 446c78974bSJohn Brawn llvm::StringRef) override { 452b3d49b6SJonas Devlieghere return std::make_unique<AnnotateFunctionsConsumer>(); 466c78974bSJohn Brawn } 476c78974bSJohn Brawn ParseArgs(const CompilerInstance & CI,const std::vector<std::string> & args)486c78974bSJohn Brawn bool ParseArgs(const CompilerInstance &CI, 496c78974bSJohn Brawn const std::vector<std::string> &args) override { 506c78974bSJohn Brawn return true; 516c78974bSJohn Brawn } 526c78974bSJohn Brawn getActionType()536c78974bSJohn Brawn PluginASTAction::ActionType getActionType() override { 546c78974bSJohn Brawn return AddBeforeMainAction; 556c78974bSJohn Brawn } 566c78974bSJohn Brawn }; 576c78974bSJohn Brawn 588e62db32SJohn Brawn class PragmaAnnotateHandler : public PragmaHandler { 598e62db32SJohn Brawn public: PragmaAnnotateHandler()608e62db32SJohn Brawn PragmaAnnotateHandler() : PragmaHandler("enable_annotate") { } 618e62db32SJohn Brawn HandlePragma(Preprocessor & PP,PragmaIntroducer Introducer,Token & PragmaTok)62ddde0ec1SJoel E. Denny void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, 638e62db32SJohn Brawn Token &PragmaTok) override { 648e62db32SJohn Brawn 658e62db32SJohn Brawn Token Tok; 668e62db32SJohn Brawn PP.LexUnexpandedToken(Tok); 678e62db32SJohn Brawn if (Tok.isNot(tok::eod)) 688e62db32SJohn Brawn PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma"; 698e62db32SJohn Brawn 708e62db32SJohn Brawn if (HandledDecl) { 718e62db32SJohn Brawn DiagnosticsEngine &D = PP.getDiagnostics(); 728e62db32SJohn Brawn unsigned ID = D.getCustomDiagID( 738e62db32SJohn Brawn DiagnosticsEngine::Error, 748e62db32SJohn Brawn "#pragma enable_annotate not allowed after declarations"); 758e62db32SJohn Brawn D.Report(PragmaTok.getLocation(), ID); 768e62db32SJohn Brawn } 778e62db32SJohn Brawn 788e62db32SJohn Brawn EnableAnnotate = true; 798e62db32SJohn Brawn } 808e62db32SJohn Brawn }; 818e62db32SJohn Brawn 826c78974bSJohn Brawn } 836c78974bSJohn Brawn 846c78974bSJohn Brawn static FrontendPluginRegistry::Add<AnnotateFunctionsAction> 856c78974bSJohn Brawn X("annotate-fns", "annotate functions"); 868e62db32SJohn Brawn 878e62db32SJohn Brawn static PragmaHandlerRegistry::Add<PragmaAnnotateHandler> 888e62db32SJohn Brawn Y("enable_annotate","enable annotation"); 89