clang API Documentation
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