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