Home | History | Annotate | Download | only in Lex
      1 //===--- Pragma.h - Pragma registration and handling ------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines the PragmaHandler and PragmaTable interfaces.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_CLANG_LEX_PRAGMA_H
     15 #define LLVM_CLANG_LEX_PRAGMA_H
     16 
     17 #include "clang/Basic/LLVM.h"
     18 #include "llvm/ADT/StringMap.h"
     19 #include "llvm/ADT/StringRef.h"
     20 #include <cassert>
     21 
     22 namespace clang {
     23   class Preprocessor;
     24   class Token;
     25   class IdentifierInfo;
     26   class PragmaNamespace;
     27 
     28   /**
     29    * \brief Describes how the pragma was introduced, e.g., with \#pragma,
     30    * _Pragma, or __pragma.
     31    */
     32   enum PragmaIntroducerKind {
     33     /**
     34      * \brief The pragma was introduced via \#pragma.
     35      */
     36     PIK_HashPragma,
     37 
     38     /**
     39      * \brief The pragma was introduced via the C99 _Pragma(string-literal).
     40      */
     41     PIK__Pragma,
     42 
     43     /**
     44      * \brief The pragma was introduced via the Microsoft
     45      * __pragma(token-string).
     46      */
     47     PIK___pragma
     48   };
     49 
     50 /// PragmaHandler - Instances of this interface defined to handle the various
     51 /// pragmas that the language front-end uses.  Each handler optionally has a
     52 /// name (e.g. "pack") and the HandlePragma method is invoked when a pragma with
     53 /// that identifier is found.  If a handler does not match any of the declared
     54 /// pragmas the handler with a null identifier is invoked, if it exists.
     55 ///
     56 /// Note that the PragmaNamespace class can be used to subdivide pragmas, e.g.
     57 /// we treat "\#pragma STDC" and "\#pragma GCC" as namespaces that contain other
     58 /// pragmas.
     59 class PragmaHandler {
     60   std::string Name;
     61 public:
     62   explicit PragmaHandler(StringRef name) : Name(name) {}
     63   PragmaHandler() {}
     64   virtual ~PragmaHandler();
     65 
     66   StringRef getName() const { return Name; }
     67   virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
     68                             Token &FirstToken) = 0;
     69 
     70   /// getIfNamespace - If this is a namespace, return it.  This is equivalent to
     71   /// using a dynamic_cast, but doesn't require RTTI.
     72   virtual PragmaNamespace *getIfNamespace() { return nullptr; }
     73 };
     74 
     75 /// EmptyPragmaHandler - A pragma handler which takes no action, which can be
     76 /// used to ignore particular pragmas.
     77 class EmptyPragmaHandler : public PragmaHandler {
     78 public:
     79   explicit EmptyPragmaHandler(StringRef Name = StringRef());
     80 
     81   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
     82                     Token &FirstToken) override;
     83 };
     84 
     85 /// PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas,
     86 /// allowing hierarchical pragmas to be defined.  Common examples of namespaces
     87 /// are "\#pragma GCC", "\#pragma STDC", and "\#pragma omp", but any namespaces
     88 /// may be (potentially recursively) defined.
     89 class PragmaNamespace : public PragmaHandler {
     90   /// Handlers - This is a map of the handlers in this namespace with their name
     91   /// as key.
     92   ///
     93   llvm::StringMap<PragmaHandler*> Handlers;
     94 public:
     95   explicit PragmaNamespace(StringRef Name) : PragmaHandler(Name) {}
     96   ~PragmaNamespace() override;
     97 
     98   /// FindHandler - Check to see if there is already a handler for the
     99   /// specified name.  If not, return the handler for the null name if it
    100   /// exists, otherwise return null.  If IgnoreNull is true (the default) then
    101   /// the null handler isn't returned on failure to match.
    102   PragmaHandler *FindHandler(StringRef Name,
    103                              bool IgnoreNull = true) const;
    104 
    105   /// AddPragma - Add a pragma to this namespace.
    106   ///
    107   void AddPragma(PragmaHandler *Handler);
    108 
    109   /// RemovePragmaHandler - Remove the given handler from the
    110   /// namespace.
    111   void RemovePragmaHandler(PragmaHandler *Handler);
    112 
    113   bool IsEmpty() {
    114     return Handlers.empty();
    115   }
    116 
    117   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
    118                     Token &FirstToken) override;
    119 
    120   PragmaNamespace *getIfNamespace() override { return this; }
    121 };
    122 
    123 
    124 }  // end namespace clang
    125 
    126 #endif
    127