Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:57

0001 //===- Pragma.h - Pragma registration and handling --------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines the PragmaHandler and PragmaTable interfaces.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_CLANG_LEX_PRAGMA_H
0014 #define LLVM_CLANG_LEX_PRAGMA_H
0015 
0016 #include "clang/Basic/LLVM.h"
0017 #include "clang/Basic/SourceLocation.h"
0018 #include "llvm/ADT/StringMap.h"
0019 #include "llvm/ADT/StringRef.h"
0020 #include <string>
0021 
0022 namespace clang {
0023 
0024 class PragmaNamespace;
0025 class Preprocessor;
0026 class Token;
0027 
0028   /**
0029    * Describes how the pragma was introduced, e.g., with \#pragma,
0030    * _Pragma, or __pragma.
0031    */
0032   enum PragmaIntroducerKind {
0033     /**
0034      * The pragma was introduced via \#pragma.
0035      */
0036     PIK_HashPragma,
0037 
0038     /**
0039      * The pragma was introduced via the C99 _Pragma(string-literal).
0040      */
0041     PIK__Pragma,
0042 
0043     /**
0044      * The pragma was introduced via the Microsoft
0045      * __pragma(token-string).
0046      */
0047     PIK___pragma
0048   };
0049 
0050   /// Describes how and where the pragma was introduced.
0051   struct PragmaIntroducer {
0052     PragmaIntroducerKind Kind;
0053     SourceLocation Loc;
0054   };
0055 
0056 /// PragmaHandler - Instances of this interface defined to handle the various
0057 /// pragmas that the language front-end uses.  Each handler optionally has a
0058 /// name (e.g. "pack") and the HandlePragma method is invoked when a pragma with
0059 /// that identifier is found.  If a handler does not match any of the declared
0060 /// pragmas the handler with a null identifier is invoked, if it exists.
0061 ///
0062 /// Note that the PragmaNamespace class can be used to subdivide pragmas, e.g.
0063 /// we treat "\#pragma STDC" and "\#pragma GCC" as namespaces that contain other
0064 /// pragmas.
0065 class PragmaHandler {
0066   std::string Name;
0067 
0068 public:
0069   PragmaHandler() = default;
0070   explicit PragmaHandler(StringRef name) : Name(name) {}
0071   virtual ~PragmaHandler();
0072 
0073   StringRef getName() const { return Name; }
0074   virtual void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
0075                             Token &FirstToken) = 0;
0076 
0077   /// getIfNamespace - If this is a namespace, return it.  This is equivalent to
0078   /// using a dynamic_cast, but doesn't require RTTI.
0079   virtual PragmaNamespace *getIfNamespace() { return nullptr; }
0080 };
0081 
0082 /// EmptyPragmaHandler - A pragma handler which takes no action, which can be
0083 /// used to ignore particular pragmas.
0084 class EmptyPragmaHandler : public PragmaHandler {
0085 public:
0086   explicit EmptyPragmaHandler(StringRef Name = StringRef());
0087 
0088   void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
0089                     Token &FirstToken) override;
0090 };
0091 
0092 /// PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas,
0093 /// allowing hierarchical pragmas to be defined.  Common examples of namespaces
0094 /// are "\#pragma GCC", "\#pragma STDC", and "\#pragma omp", but any namespaces
0095 /// may be (potentially recursively) defined.
0096 class PragmaNamespace : public PragmaHandler {
0097   /// Handlers - This is a map of the handlers in this namespace with their name
0098   /// as key.
0099   llvm::StringMap<std::unique_ptr<PragmaHandler>> Handlers;
0100 
0101 public:
0102   explicit PragmaNamespace(StringRef Name) : PragmaHandler(Name) {}
0103 
0104   /// FindHandler - Check to see if there is already a handler for the
0105   /// specified name.  If not, return the handler for the null name if it
0106   /// exists, otherwise return null.  If IgnoreNull is true (the default) then
0107   /// the null handler isn't returned on failure to match.
0108   PragmaHandler *FindHandler(StringRef Name,
0109                              bool IgnoreNull = true) const;
0110 
0111   /// AddPragma - Add a pragma to this namespace.
0112   void AddPragma(PragmaHandler *Handler);
0113 
0114   /// RemovePragmaHandler - Remove the given handler from the
0115   /// namespace.
0116   void RemovePragmaHandler(PragmaHandler *Handler);
0117 
0118   bool IsEmpty() const { return Handlers.empty(); }
0119 
0120   void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
0121                     Token &Tok) override;
0122 
0123   PragmaNamespace *getIfNamespace() override { return this; }
0124 };
0125 
0126 /// Destringize a \c _Pragma("") string according to C11 6.10.9.1:
0127 /// "The string literal is destringized by deleting any encoding prefix,
0128 /// deleting the leading and trailing double-quotes, replacing each escape
0129 /// sequence \" by a double-quote, and replacing each escape sequence \\ by a
0130 /// single backslash."
0131 void prepare_PragmaString(SmallVectorImpl<char> &StrVal);
0132 
0133 } // namespace clang
0134 
0135 #endif // LLVM_CLANG_LEX_PRAGMA_H