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)