clang API Documentation

Pragma.h
Go to the documentation of this file.
00001 //===--- Pragma.h - Pragma registration and handling ------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines the PragmaHandler and PragmaTable interfaces.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_CLANG_LEX_PRAGMA_H
00015 #define LLVM_CLANG_LEX_PRAGMA_H
00016 
00017 #include "clang/Basic/LLVM.h"
00018 #include "llvm/ADT/StringMap.h"
00019 #include "llvm/ADT/StringRef.h"
00020 #include <cassert>
00021 
00022 namespace clang {
00023   class Preprocessor;
00024   class Token;
00025   class IdentifierInfo;
00026   class PragmaNamespace;
00027 
00028   /**
00029    * \brief Describes how the pragma was introduced, e.g., with \#pragma,
00030    * _Pragma, or __pragma.
00031    */
00032   enum PragmaIntroducerKind {
00033     /**
00034      * \brief The pragma was introduced via \#pragma.
00035      */
00036     PIK_HashPragma,
00037     
00038     /**
00039      * \brief The pragma was introduced via the C99 _Pragma(string-literal).
00040      */
00041     PIK__Pragma,
00042     
00043     /**
00044      * \brief The pragma was introduced via the Microsoft 
00045      * __pragma(token-string).
00046      */
00047     PIK___pragma
00048   };
00049   
00050 /// PragmaHandler - Instances of this interface defined to handle the various
00051 /// pragmas that the language front-end uses.  Each handler optionally has a
00052 /// name (e.g. "pack") and the HandlePragma method is invoked when a pragma with
00053 /// that identifier is found.  If a handler does not match any of the declared
00054 /// pragmas the handler with a null identifier is invoked, if it exists.
00055 ///
00056 /// Note that the PragmaNamespace class can be used to subdivide pragmas, e.g.
00057 /// we treat "\#pragma STDC" and "\#pragma GCC" as namespaces that contain other
00058 /// pragmas.
00059 class PragmaHandler {
00060   std::string Name;
00061 public:
00062   explicit PragmaHandler(StringRef name) : Name(name) {}
00063   PragmaHandler() {}
00064   virtual ~PragmaHandler();
00065 
00066   StringRef getName() const { return Name; }
00067   virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00068                             Token &FirstToken) = 0;
00069 
00070   /// getIfNamespace - If this is a namespace, return it.  This is equivalent to
00071   /// using a dynamic_cast, but doesn't require RTTI.
00072   virtual PragmaNamespace *getIfNamespace() { return nullptr; }
00073 };
00074 
00075 /// EmptyPragmaHandler - A pragma handler which takes no action, which can be
00076 /// used to ignore particular pragmas.
00077 class EmptyPragmaHandler : public PragmaHandler {
00078 public:
00079   EmptyPragmaHandler();
00080 
00081   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00082                     Token &FirstToken) override;
00083 };
00084 
00085 /// PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas,
00086 /// allowing hierarchical pragmas to be defined.  Common examples of namespaces
00087 /// are "\#pragma GCC", "\#pragma STDC", and "\#pragma omp", but any namespaces
00088 /// may be (potentially recursively) defined.
00089 class PragmaNamespace : public PragmaHandler {
00090   /// Handlers - This is a map of the handlers in this namespace with their name
00091   /// as key.
00092   ///
00093   llvm::StringMap<PragmaHandler*> Handlers;
00094 public:
00095   explicit PragmaNamespace(StringRef Name) : PragmaHandler(Name) {}
00096   virtual ~PragmaNamespace();
00097 
00098   /// FindHandler - Check to see if there is already a handler for the
00099   /// specified name.  If not, return the handler for the null name if it
00100   /// exists, otherwise return null.  If IgnoreNull is true (the default) then
00101   /// the null handler isn't returned on failure to match.
00102   PragmaHandler *FindHandler(StringRef Name,
00103                              bool IgnoreNull = true) const;
00104 
00105   /// AddPragma - Add a pragma to this namespace.
00106   ///
00107   void AddPragma(PragmaHandler *Handler);
00108 
00109   /// RemovePragmaHandler - Remove the given handler from the
00110   /// namespace.
00111   void RemovePragmaHandler(PragmaHandler *Handler);
00112 
00113   bool IsEmpty() {
00114     return Handlers.empty();
00115   }
00116 
00117   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00118                     Token &FirstToken) override;
00119 
00120   PragmaNamespace *getIfNamespace() override { return this; }
00121 };
00122 
00123 
00124 }  // end namespace clang
00125 
00126 #endif