This revision was automatically updated to reflect the committed changes.
Closed by commit rL265295: Add a PragmaHandler Registry for plugins to add 
PragmaHandlers to (authored by john.brawn).

Changed prior to commit:
  http://reviews.llvm.org/D18319?vs=51168&id=52553#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D18319

Files:
  cfe/trunk/docs/ClangPlugins.rst
  cfe/trunk/examples/AnnotateFunctions/AnnotateFunctions.cpp
  cfe/trunk/include/clang/Lex/Preprocessor.h
  cfe/trunk/lib/Lex/Pragma.cpp
  cfe/trunk/test/Frontend/plugin-annotate-functions.c

Index: cfe/trunk/docs/ClangPlugins.rst
===================================================================
--- cfe/trunk/docs/ClangPlugins.rst
+++ cfe/trunk/docs/ClangPlugins.rst
@@ -43,6 +43,26 @@
 
   static FrontendPluginRegistry::Add<MyPlugin> X("my-plugin-name", "my plugin description");
 
+Defining pragmas
+================
+
+Plugins can also define pragmas by declaring a ``PragmaHandler`` and
+registering it using ``PragmaHandlerRegistry::Add<>``:
+
+.. code-block:: c++
+
+  // Define a pragma handler for #pragma example_pragma
+  class ExamplePragmaHandler : public PragmaHandler {
+  public:
+    ExamplePragmaHandler() : PragmaHandler("example_pragma") { }
+    void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                      Token &PragmaTok) {
+      // Handle the pragma
+    }
+  };
+
+  static PragmaHandlerRegistry::Add<ExamplePragmaHandler> Y("example_pragma","example pragma description");
+
 Putting it all together
 =======================
 
Index: cfe/trunk/include/clang/Lex/Preprocessor.h
===================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h
+++ cfe/trunk/include/clang/Lex/Preprocessor.h
@@ -32,6 +32,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/TinyPtrVector.h"
 #include "llvm/Support/Allocator.h"
+#include "llvm/Support/Registry.h"
 #include <memory>
 #include <vector>
 
@@ -1937,6 +1938,9 @@
   virtual bool HandleComment(Preprocessor &PP, SourceRange Comment) = 0;
 };
 
+/// \brief Registry of pragma handlers added by plugins
+typedef llvm::Registry<PragmaHandler> PragmaHandlerRegistry;
+
 }  // end namespace clang
 
 #endif
Index: cfe/trunk/test/Frontend/plugin-annotate-functions.c
===================================================================
--- cfe/trunk/test/Frontend/plugin-annotate-functions.c
+++ cfe/trunk/test/Frontend/plugin-annotate-functions.c
@@ -1,7 +1,25 @@
-// RUN: %clang -fplugin=%llvmshlibdir/AnnotateFunctions%pluginext -emit-llvm -S %s -o - | FileCheck %s
+// RUN: %clang -fplugin=%llvmshlibdir/AnnotateFunctions%pluginext -emit-llvm -DPRAGMA_ON -S %s -o - | FileCheck %s --check-prefix=PRAGMA
+// RUN: %clang -fplugin=%llvmshlibdir/AnnotateFunctions%pluginext -emit-llvm -S %s -o - | FileCheck %s --check-prefix=NOPRAGMA
+// RUN: not %clang -fplugin=%llvmshlibdir/AnnotateFunctions%pluginext -emit-llvm -DBAD_PRAGMA -S %s -o - 2>&1 | FileCheck %s --check-prefix=BADPRAGMA
 // REQUIRES: plugins, examples
 
-// CHECK: [[STR_VAR:@.+]] = private unnamed_addr constant [19 x i8] c"example_annotation\00"
-// CHECK: @llvm.global.annotations = {{.*}}@fn1{{.*}}[[STR_VAR]]{{.*}}@fn2{{.*}}[[STR_VAR]]
+#ifdef PRAGMA_ON
+#pragma enable_annotate
+#endif
+
+// BADPRAGMA: warning: extra tokens at end of #pragma directive
+#ifdef BAD_PRAGMA
+#pragma enable_annotate something
+#endif
+
+// PRAGMA: [[STR_VAR:@.+]] = private unnamed_addr constant [19 x i8] c"example_annotation\00"
+// PRAGMA: @llvm.global.annotations = {{.*}}@fn1{{.*}}[[STR_VAR]]{{.*}}@fn2{{.*}}[[STR_VAR]]
+// NOPRAGMA-NOT: [[STR_VAR:@.+]] = private unnamed_addr constant [19 x i8] c"example_annotation\00"
+// NOPRAGMA-NOT: @llvm.global.annotations = {{.*}}@fn1{{.*}}[[STR_VAR]]{{.*}}@fn2{{.*}}[[STR_VAR]]
 void fn1() { }
 void fn2() { }
+
+// BADPRAGMA: error: #pragma enable_annotate not allowed after declarations
+#ifdef BAD_PRAGMA
+#pragma enable_annotate
+#endif
Index: cfe/trunk/examples/AnnotateFunctions/AnnotateFunctions.cpp
===================================================================
--- cfe/trunk/examples/AnnotateFunctions/AnnotateFunctions.cpp
+++ cfe/trunk/examples/AnnotateFunctions/AnnotateFunctions.cpp
@@ -7,20 +7,29 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// Example clang plugin which adds an annotation to every function.
+// Example clang plugin which adds an annotation to every function in
+// translation units that start with #pragma enable_annotate.
 //
 //===----------------------------------------------------------------------===//
 
 #include "clang/Frontend/FrontendPluginRegistry.h"
 #include "clang/AST/AST.h"
 #include "clang/AST/ASTConsumer.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/LexDiagnostic.h"
 using namespace clang;
 
 namespace {
 
+static bool EnableAnnotate = false;
+static bool HandledDecl = false;
+
 class AnnotateFunctionsConsumer : public ASTConsumer {
 public:
   bool HandleTopLevelDecl(DeclGroupRef DG) override {
+    HandledDecl = true;
+    if (!EnableAnnotate)
+      return true;
     for (auto D : DG)
       if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
         FD->addAttr(AnnotateAttr::CreateImplicit(FD->getASTContext(),
@@ -46,7 +55,34 @@
   }
 };
 
+class PragmaAnnotateHandler : public PragmaHandler {
+public:
+  PragmaAnnotateHandler() : PragmaHandler("enable_annotate") { }
+
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &PragmaTok) override {
+
+    Token Tok;
+    PP.LexUnexpandedToken(Tok);
+    if (Tok.isNot(tok::eod))
+      PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
+
+    if (HandledDecl) {
+      DiagnosticsEngine &D = PP.getDiagnostics();
+      unsigned ID = D.getCustomDiagID(
+        DiagnosticsEngine::Error,
+        "#pragma enable_annotate not allowed after declarations");
+      D.Report(PragmaTok.getLocation(), ID);
+    }
+
+    EnableAnnotate = true;
+  }
+};
+
 }
 
 static FrontendPluginRegistry::Add<AnnotateFunctionsAction>
 X("annotate-fns", "annotate functions");
+
+static PragmaHandlerRegistry::Add<PragmaAnnotateHandler>
+Y("enable_annotate","enable annotation");
Index: cfe/trunk/lib/Lex/Pragma.cpp
===================================================================
--- cfe/trunk/lib/Lex/Pragma.cpp
+++ cfe/trunk/lib/Lex/Pragma.cpp
@@ -1490,6 +1490,13 @@
     AddPragmaHandler(new PragmaRegionHandler("region"));
     AddPragmaHandler(new PragmaRegionHandler("endregion"));
   }
+
+  // Pragmas added by plugins
+  for (PragmaHandlerRegistry::iterator it = PragmaHandlerRegistry::begin(),
+                                       ie = PragmaHandlerRegistry::end();
+       it != ie; ++it) {
+    AddPragmaHandler(it->instantiate().release());
+  }
 }
 
 /// Ignore all pragmas, useful for modes such as -Eonly which would otherwise
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to