Clang Project

clang_source_code/include/clang/Lex/Pragma.h
1//===- Pragma.h - Pragma registration and handling --------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the PragmaHandler and PragmaTable interfaces.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_LEX_PRAGMA_H
14#define LLVM_CLANG_LEX_PRAGMA_H
15
16#include "clang/Basic/LLVM.h"
17#include "llvm/ADT/StringMap.h"
18#include "llvm/ADT/StringRef.h"
19#include <string>
20
21namespace clang {
22
23class PragmaNamespace;
24class Preprocessor;
25class Token;
26
27  /**
28   * Describes how the pragma was introduced, e.g., with \#pragma,
29   * _Pragma, or __pragma.
30   */
31  enum PragmaIntroducerKind {
32    /**
33     * The pragma was introduced via \#pragma.
34     */
35    PIK_HashPragma,
36
37    /**
38     * The pragma was introduced via the C99 _Pragma(string-literal).
39     */
40    PIK__Pragma,
41
42    /**
43     * 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.
58class PragmaHandler {
59  std::string Name;
60
61public:
62  PragmaHandler() = default;
63  explicit PragmaHandler(StringRef name) : Name(name) {}
64  virtual ~PragmaHandler();
65
66  StringRef getName() const { return Name; }
67  virtual void HandlePragma(Preprocessor &PPPragmaIntroducerKind Introducer,
68                            Token &FirstToken) = 0;
69
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
75/// EmptyPragmaHandler - A pragma handler which takes no action, which can be
76/// used to ignore particular pragmas.
77class EmptyPragmaHandler : public PragmaHandler {
78public:
79  explicit EmptyPragmaHandler(StringRef Name = StringRef());
80
81  void HandlePragma(Preprocessor &PPPragmaIntroducerKind Introducer,
82                    Token &FirstToken) override;
83};
84
85/// PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas,
86/// allowing hierarchical pragmas to be defined.  Common examples of namespaces
87/// are "\#pragma GCC", "\#pragma STDC", and "\#pragma omp", but any namespaces
88/// may be (potentially recursively) defined.
89class PragmaNamespace : public PragmaHandler {
90  /// Handlers - This is a map of the handlers in this namespace with their name
91  /// as key.
92  llvm::StringMap<PragmaHandler *> Handlers;
93
94public:
95  explicit PragmaNamespace(StringRef Name) : PragmaHandler(Name) {}
96  ~PragmaNamespace() override;
97
98  /// FindHandler - Check to see if there is already a handler for the
99  /// specified name.  If not, return the handler for the null name if it
100  /// exists, otherwise return null.  If IgnoreNull is true (the default) then
101  /// the null handler isn't returned on failure to match.
102  PragmaHandler *FindHandler(StringRef Name,
103                             bool IgnoreNull = trueconst;
104
105  /// AddPragma - Add a pragma to this namespace.
106  void AddPragma(PragmaHandler *Handler);
107
108  /// RemovePragmaHandler - Remove the given handler from the
109  /// namespace.
110  void RemovePragmaHandler(PragmaHandler *Handler);
111
112  bool IsEmpty() const { return Handlers.empty(); }
113
114  void HandlePragma(Preprocessor &PPPragmaIntroducerKind Introducer,
115                    Token &Tok) override;
116
117  PragmaNamespace *getIfNamespace() override { return this; }
118};
119
120// namespace clang
121
122#endif // LLVM_CLANG_LEX_PRAGMA_H
123
clang::PragmaHandler::Name
clang::PragmaHandler::getName
clang::PragmaHandler::HandlePragma
clang::PragmaHandler::getIfNamespace
clang::EmptyPragmaHandler::HandlePragma
clang::PragmaNamespace::Handlers
clang::PragmaNamespace::FindHandler
clang::PragmaNamespace::AddPragma
clang::PragmaNamespace::RemovePragmaHandler
clang::PragmaNamespace::IsEmpty
clang::PragmaNamespace::HandlePragma
clang::PragmaNamespace::getIfNamespace