Pragma.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- Pragma.h - Pragma registration and handling --------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file defines the PragmaHandler and PragmaTable interfaces.
  15. //
  16. //===----------------------------------------------------------------------===//
  17. #ifndef LLVM_CLANG_LEX_PRAGMA_H
  18. #define LLVM_CLANG_LEX_PRAGMA_H
  19. #include "clang/Basic/LLVM.h"
  20. #include "clang/Basic/SourceLocation.h"
  21. #include "llvm/ADT/StringMap.h"
  22. #include "llvm/ADT/StringRef.h"
  23. #include <string>
  24. namespace clang {
  25. class PragmaNamespace;
  26. class Preprocessor;
  27. class Token;
  28. /**
  29. * Describes how the pragma was introduced, e.g., with \#pragma,
  30. * _Pragma, or __pragma.
  31. */
  32. enum PragmaIntroducerKind {
  33. /**
  34. * The pragma was introduced via \#pragma.
  35. */
  36. PIK_HashPragma,
  37. /**
  38. * The pragma was introduced via the C99 _Pragma(string-literal).
  39. */
  40. PIK__Pragma,
  41. /**
  42. * The pragma was introduced via the Microsoft
  43. * __pragma(token-string).
  44. */
  45. PIK___pragma
  46. };
  47. /// Describes how and where the pragma was introduced.
  48. struct PragmaIntroducer {
  49. PragmaIntroducerKind Kind;
  50. SourceLocation Loc;
  51. };
  52. /// PragmaHandler - Instances of this interface defined to handle the various
  53. /// pragmas that the language front-end uses. Each handler optionally has a
  54. /// name (e.g. "pack") and the HandlePragma method is invoked when a pragma with
  55. /// that identifier is found. If a handler does not match any of the declared
  56. /// pragmas the handler with a null identifier is invoked, if it exists.
  57. ///
  58. /// Note that the PragmaNamespace class can be used to subdivide pragmas, e.g.
  59. /// we treat "\#pragma STDC" and "\#pragma GCC" as namespaces that contain other
  60. /// pragmas.
  61. class PragmaHandler {
  62. std::string Name;
  63. public:
  64. PragmaHandler() = default;
  65. explicit PragmaHandler(StringRef name) : Name(name) {}
  66. virtual ~PragmaHandler();
  67. StringRef getName() const { return Name; }
  68. virtual void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  69. Token &FirstToken) = 0;
  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. /// 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. explicit EmptyPragmaHandler(StringRef Name = StringRef());
  79. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  80. Token &FirstToken) override;
  81. };
  82. /// PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas,
  83. /// allowing hierarchical pragmas to be defined. Common examples of namespaces
  84. /// are "\#pragma GCC", "\#pragma STDC", and "\#pragma omp", but any namespaces
  85. /// may be (potentially recursively) defined.
  86. class PragmaNamespace : public PragmaHandler {
  87. /// Handlers - This is a map of the handlers in this namespace with their name
  88. /// as key.
  89. llvm::StringMap<std::unique_ptr<PragmaHandler>> Handlers;
  90. public:
  91. explicit PragmaNamespace(StringRef Name) : PragmaHandler(Name) {}
  92. /// FindHandler - Check to see if there is already a handler for the
  93. /// specified name. If not, return the handler for the null name if it
  94. /// exists, otherwise return null. If IgnoreNull is true (the default) then
  95. /// the null handler isn't returned on failure to match.
  96. PragmaHandler *FindHandler(StringRef Name,
  97. bool IgnoreNull = true) const;
  98. /// AddPragma - Add a pragma to this namespace.
  99. void AddPragma(PragmaHandler *Handler);
  100. /// RemovePragmaHandler - Remove the given handler from the
  101. /// namespace.
  102. void RemovePragmaHandler(PragmaHandler *Handler);
  103. bool IsEmpty() const { return Handlers.empty(); }
  104. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  105. Token &Tok) override;
  106. PragmaNamespace *getIfNamespace() override { return this; }
  107. };
  108. } // namespace clang
  109. #endif // LLVM_CLANG_LEX_PRAGMA_H
  110. #ifdef __GNUC__
  111. #pragma GCC diagnostic pop
  112. #endif