Pragma.h revision 6bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===--- Pragma.h - Pragma registration and handling ------------*- C++ -*-===//
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This file defines the PragmaHandler and PragmaTable interfaces.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
12424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)//===----------------------------------------------------------------------===//
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef LLVM_CLANG_PRAGMA_H
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LLVM_CLANG_PRAGMA_H
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/Basic/LLVM.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/ADT/StringMap.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/ADT/StringRef.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cassert>
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace clang {
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  class Preprocessor;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Token;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class IdentifierInfo;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class PragmaNamespace;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /**
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * \brief Describes how the pragma was introduced, e.g., with \#pragma,
30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)   * _Pragma, or __pragma.
31a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)   */
32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  enum PragmaIntroducerKind {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * \brief The pragma was introduced via \#pragma.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PIK_HashPragma,
37a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
38a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    /**
39a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)     * \brief The pragma was introduced via the C99 _Pragma(string-literal).
40a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)     */
41a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    PIK__Pragma,
42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    /**
44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)     * \brief The pragma was introduced via the Microsoft
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * __pragma(token-string).
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PIK___pragma
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// PragmaHandler - Instances of this interface defined to handle the various
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// pragmas that the language front-end uses.  Each handler optionally has a
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// name (e.g. "pack") and the HandlePragma method is invoked when a pragma with
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// that identifier is found.  If a handler does not match any of the declared
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// pragmas the handler with a null identifier is invoked, if it exists.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// Note that the PragmaNamespace class can be used to subdivide pragmas, e.g.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// we treat "\#pragma STDC" and "\#pragma GCC" as namespaces that contain other
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// pragmas.
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PragmaHandler {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string Name;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit PragmaHandler(StringRef name) : Name(name) {}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PragmaHandler() {}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~PragmaHandler();
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringRef getName() const { return Name; }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            Token &FirstToken) = 0;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// getIfNamespace - If this is a namespace, return it.  This is equivalent to
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// using a dynamic_cast, but doesn't require RTTI.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual PragmaNamespace *getIfNamespace() { return nullptr; }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// EmptyPragmaHandler - A pragma handler which takes no action, which can be
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// used to ignore particular pragmas.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EmptyPragmaHandler : public PragmaHandler {
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public:
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EmptyPragmaHandler();
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    Token &FirstToken) override;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// allowing hierarchical pragmas to be defined.  Common examples of namespaces
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// are "\#pragma GCC", "\#pragma STDC", and "\#pragma omp", but any namespaces
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// may be (potentially recursively) defined.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PragmaNamespace : public PragmaHandler {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// Handlers - This is a map of the handlers in this namespace with their name
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// as key.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ///
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  llvm::StringMap<PragmaHandler*> Handlers;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit PragmaNamespace(StringRef Name) : PragmaHandler(Name) {}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~PragmaNamespace();
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// FindHandler - Check to see if there is already a handler for the
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// specified name.  If not, return the handler for the null name if it
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// exists, otherwise return null.  If IgnoreNull is true (the default) then
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// the null handler isn't returned on failure to match.
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PragmaHandler *FindHandler(StringRef Name,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             bool IgnoreNull = true) const;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// AddPragma - Add a pragma to this namespace.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ///
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddPragma(PragmaHandler *Handler);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// RemovePragmaHandler - Remove the given handler from the
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// namespace.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RemovePragmaHandler(PragmaHandler *Handler);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsEmpty() {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Handlers.empty();
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    Token &FirstToken) override;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PragmaNamespace *getIfNamespace() override { return this; }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // end namespace clang
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)