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