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