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