15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- IdentifierTable.h - Hash table for identifier lookup ---*- C++ -*-===// 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// The LLVM Compiler Infrastructure 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 92f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// 102f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// \file 112f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// \brief Defines the clang::IdentifierInfo, clang::IdentifierTable, and 122f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// clang::Selector interfaces. 132f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// 145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 16c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H 17c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H 185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 191cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor#include "clang/Basic/OperatorKinds.h" 205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/TokenKinds.h" 21686775deca8b8685eb90801495880e3abdd844c2Chris Lattner#include "clang/Basic/LLVM.h" 225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/StringMap.h" 23700030ebddb987936d4fee14d9412821d96e4840Kovarththanan Rajaratnam#include "llvm/ADT/StringRef.h" 2472b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek#include "llvm/ADT/OwningPtr.h" 251734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor#include "llvm/Support/PointerLikeTypeTraits.h" 261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#include <cassert> 27403ba3522d1b1c97ae5fad81c1a2c4b3a754e1c1Nick Lewycky#include <string> 285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2985994260c41a54cab061a434ed378fc448333a4eChris Lattnernamespace llvm { 3085994260c41a54cab061a434ed378fc448333a4eChris Lattner template <typename T> struct DenseMapInfo; 3185994260c41a54cab061a434ed378fc448333a4eChris Lattner} 3229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang { 34ea684e699ea84e61711e279f5fa7a1b9f3d46bc2Cedric Venet class LangOptions; 357caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner class IdentifierInfo; 36ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek class IdentifierTable; 377caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner class SourceLocation; 382e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor class MultiKeywordSelector; // private class used by Selector 392e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor class DeclarationName; // AST class that stores declaration names 402e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor 41af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// \brief A simple pair of identifier info and location. 427caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair; 431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 45af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// One of these records is kept for each identifier that 4655bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett/// is lexed. This contains information about whether the token was \#define'd, 475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is a language keyword, or if it is a front-end token of some sort (e.g. a 485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// variable or function name). The preprocessor keeps this information in a 491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// set, and all tok::identifier tokens have a pointer to one of these. 505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierInfo { 515cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor unsigned TokenID : 9; // Front-end token ID or tok::identifier. 525142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor // Objective-C keyword ('protocol' in '@protocol') or builtin (__builtin_inf). 535142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor // First NUM_OBJC_KEYWORDS values are for Objective-C, the remaining values 545142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor // are for builtins. 55c81ca9852806e75972bbb246fa916152e8fba541Ted Kremenek unsigned ObjCOrBuiltinID :11; 564365a7e46822700357a272d839ee2656d9603d5aChris Lattner bool HasMacro : 1; // True if there is a #define for this. 575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsExtension : 1; // True if identifier is a lang extension. 5898d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith bool IsCXX11CompatKeyword : 1; // True if identifier is a keyword in C++11. 595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsPoisoned : 1; // True if identifier is poisoned. 605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword. 616a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner bool NeedsHandleIdentifier : 1; // See "RecomputeNeedsHandleIdentifier". 62eee242ff426bf79149f221798966e58688383c1eDouglas Gregor bool IsFromAST : 1; // True if identifier was loaded (at least 63eee242ff426bf79149f221798966e58688383c1eDouglas Gregor // partially) from an AST file. 64eee242ff426bf79149f221798966e58688383c1eDouglas Gregor bool ChangedAfterLoad : 1; // True if identifier has changed from the 65eee242ff426bf79149f221798966e58688383c1eDouglas Gregor // definition loaded from an AST file. 66646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis bool RevertedTokenID : 1; // True if RevertTokenIDToIdentifier was 67646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis // called. 68eee242ff426bf79149f221798966e58688383c1eDouglas Gregor bool OutOfDate : 1; // True if there may be additional 69eee242ff426bf79149f221798966e58688383c1eDouglas Gregor // information about this identifier 70eee242ff426bf79149f221798966e58688383c1eDouglas Gregor // stored externally. 7155bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett bool IsModulesImport : 1; // True if this is the 'import' contextual 72c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor // keyword. 73c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor // 1 bit left in 32-bit word. 74eee242ff426bf79149f221798966e58688383c1eDouglas Gregor 755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void *FETokenInfo; // Managed by the language front-end. 76ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek llvm::StringMapEntry<IdentifierInfo*> *Entry; 771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IdentifierInfo(const IdentifierInfo&); // NONCOPYABLE. 794365a7e46822700357a272d839ee2656d9603d5aChris Lattner void operator=(const IdentifierInfo&); // NONASSIGNABLE. 80ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek 811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump friend class IdentifierTable; 82295a2a617ac335f590e430ab7fcd98f8ce109251Douglas Gregor 835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic: 84ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek IdentifierInfo(); 855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8755bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// \brief Return true if this is the identifier for the specified string. 8855bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// 8992e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner /// This is intended to be used for string literals only: II->isStr("foo"). 9092e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner template <std::size_t StrLen> 9192e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner bool isStr(const char (&Str)[StrLen]) const { 927fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar return getLength() == StrLen-1 && !memcmp(getNameStart(), Str, StrLen-1); 93845222ccd992282bf74b2fca53e7c3b84a81c098Chris Lattner } 941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9555bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// \brief Return the beginning of the actual null-terminated string for this 9655bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// identifier. 975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 987fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar const char *getNameStart() const { 99ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek if (Entry) return Entry->getKeyData(); 1007e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // FIXME: This is gross. It would be best not to embed specific details 1017e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // of the PTH file format here. 1021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // The 'this' pointer really points to a 103ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek // std::pair<IdentifierInfo, const char*>, where internal pointer 104ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek // points to the external string data. 10540844a8b5a89676fb61898d61ea4a7fa98eb9b6bGabor Greif typedef std::pair<IdentifierInfo, const char*> actualtype; 10640844a8b5a89676fb61898d61ea4a7fa98eb9b6bGabor Greif return ((const actualtype*) this)->second; 1071f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner } 1081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10955bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// \brief Efficiently return the length of this identifier info. 1101f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner /// 1111f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner unsigned getLength() const { 112ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek if (Entry) return Entry->getKeyLength(); 1137e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // FIXME: This is gross. It would be best not to embed specific details 1147e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // of the PTH file format here. 1151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // The 'this' pointer really points to a 116ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek // std::pair<IdentifierInfo, const char*>, where internal pointer 117ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek // points to the external string data. 11840844a8b5a89676fb61898d61ea4a7fa98eb9b6bGabor Greif typedef std::pair<IdentifierInfo, const char*> actualtype; 11940844a8b5a89676fb61898d61ea4a7fa98eb9b6bGabor Greif const char* p = ((const actualtype*) this)->second - 2; 1207fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar return (((unsigned) p[0]) | (((unsigned) p[1]) << 8)) - 1; 1217fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar } 1227fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar 12355bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// \brief Return the actual identifier string. 124686775deca8b8685eb90801495880e3abdd844c2Chris Lattner StringRef getName() const { 125686775deca8b8685eb90801495880e3abdd844c2Chris Lattner return StringRef(getNameStart(), getLength()); 1265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12855bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// \brief Return true if this identifier is \#defined to some other value. 1299c46de446d18f4a28446cb798d4131bd05515699Chris Lattner bool hasMacroDefinition() const { 1309c46de446d18f4a28446cb798d4131bd05515699Chris Lattner return HasMacro; 1319c46de446d18f4a28446cb798d4131bd05515699Chris Lattner } 1326a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void setHasMacroDefinition(bool Val) { 1336a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (HasMacro == Val) return; 1341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1356a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner HasMacro = Val; 1366a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (Val) 1376a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 1; 1386a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner else 1396a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner RecomputeNeedsHandleIdentifier(); 1406a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 142646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis /// getTokenID - If this is a source-language token (e.g. 'for'), this API 1435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// can be used to cause the lexer to map identifiers to source-language 1445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// tokens. 1458e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; } 146646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis 147646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis /// \brief True if RevertTokenIDToIdentifier() was called. 148646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis bool hasRevertedTokenIDToIdentifier() const { return RevertedTokenID; } 149646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis 150646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis /// \brief Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2 151f573084db5807f6003282bdf53ca9d58bab1ddc4Argyrios Kyrtzidis /// compatibility. 152f573084db5807f6003282bdf53ca9d58bab1ddc4Argyrios Kyrtzidis /// 153f573084db5807f6003282bdf53ca9d58bab1ddc4Argyrios Kyrtzidis /// TokenID is normally read-only but there are 2 instances where we revert it 154f573084db5807f6003282bdf53ca9d58bab1ddc4Argyrios Kyrtzidis /// to tok::identifier for libstdc++ 4.2. Keep track of when this happens 1553c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl /// using this method so we can inform serialization about it. 156646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis void RevertTokenIDToIdentifier() { 157646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis assert(TokenID != tok::identifier && "Already at tok::identifier"); 158646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis TokenID = tok::identifier; 159646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis RevertedTokenID = true; 160646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis } 1611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 16255bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// \brief Return the preprocessor keyword ID for this identifier. 16355bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// 1646d9a3e648d6bf6b347174152f191bd1377528f8cChris Lattner /// For example, "define" will return tok::pp_define. 165387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner tok::PPKeywordKind getPPKeywordID() const; 1661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 16755bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// \brief Return the Objective-C keyword ID for the this identifier. 16855bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// 16955bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// For example, 'class' will return tok::objc_class if ObjC is enabled. 170ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek tok::ObjCKeywordKind getObjCKeywordID() const { 1711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (ObjCOrBuiltinID < tok::NUM_OBJC_KEYWORDS) 1725142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor return tok::ObjCKeywordKind(ObjCOrBuiltinID); 1735142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor else 1745142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor return tok::objc_not_keyword; 175ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek } 1765142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; } 1773251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor 1785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getBuiltinID - Return a value indicating whether this is a builtin 1795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// function. 0 is not-built-in. 1 is builtin-for-some-nonprimary-target. 1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 2+ are specific builtin functions. 1811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump unsigned getBuiltinID() const { 1825142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS) 1831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS; 1845142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor else 1855142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor return 0; 1865142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor } 1875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setBuiltinID(unsigned ID) { 1885142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor ObjCOrBuiltinID = ID + tok::NUM_OBJC_KEYWORDS; 1891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump assert(ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS) == ID 1905142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor && "ID too large for field!"); 1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1923251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor 1933251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor unsigned getObjCOrBuiltinID() const { return ObjCOrBuiltinID; } 1943251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor void setObjCOrBuiltinID(unsigned ID) { ObjCOrBuiltinID = ID; } 1953251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor 1965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// get/setExtension - Initialize information about whether or not this 1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// language token is an extension. This controls extension warnings, and is 1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// only valid if a custom token ID is set. 1995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isExtensionToken() const { return IsExtension; } 2006a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void setIsExtensionToken(bool Val) { 2016a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner IsExtension = Val; 2026a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (Val) 2036a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 1; 2046a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner else 2056a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner RecomputeNeedsHandleIdentifier(); 2066a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 2071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20898d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith /// is/setIsCXX11CompatKeyword - Initialize information about whether or not 20998d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith /// this language token is a keyword in C++11. This controls compatibility 21098d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith /// warnings, and is only true when not parsing C++11. Once a compatibility 21198d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith /// problem has been diagnosed with this keyword, the flag will be cleared. 21298d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith bool isCXX11CompatKeyword() const { return IsCXX11CompatKeyword; } 21398d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith void setIsCXX11CompatKeyword(bool Val) { 21498d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith IsCXX11CompatKeyword = Val; 21598d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith if (Val) 21698d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith NeedsHandleIdentifier = 1; 21798d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith else 21898d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith RecomputeNeedsHandleIdentifier(); 21998d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith } 22098d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith 2215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// setIsPoisoned - Mark this identifier as poisoned. After poisoning, the 2225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// Preprocessor will emit an error every time this token is used. 2236a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void setIsPoisoned(bool Value = true) { 2246a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner IsPoisoned = Value; 2256a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (Value) 2266a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 1; 2276a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner else 2286a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner RecomputeNeedsHandleIdentifier(); 2296a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 2301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// isPoisoned - Return true if this token has been poisoned. 2325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isPoisoned() const { return IsPoisoned; } 2331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether 2355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// this identifier is a C++ alternate representation of an operator. 2366a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void setIsCPlusPlusOperatorKeyword(bool Val = true) { 2376a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner IsCPPOperatorKeyword = Val; 2386a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (Val) 2396a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 1; 2406a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner else 2416a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner RecomputeNeedsHandleIdentifier(); 2426a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 2435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; } 2445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getFETokenInfo/setFETokenInfo - The language front-end is allowed to 2465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// associate arbitrary metadata with this token. 2475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer template<typename T> 2485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); } 2495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setFETokenInfo(void *T) { FETokenInfo = T; } 2506a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner 2516a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// isHandleIdentifierCase - Return true if the Preprocessor::HandleIdentifier 2526a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// must be called on a token of this identifier. If this returns false, we 2536a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// know that HandleIdentifier will not affect the token. 2546a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner bool isHandleIdentifierCase() const { return NeedsHandleIdentifier; } 2551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2563c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl /// isFromAST - Return true if the identifier in its current state was loaded 2573c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl /// from an AST file. 2583c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl bool isFromAST() const { return IsFromAST; } 259ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl 260eee242ff426bf79149f221798966e58688383c1eDouglas Gregor void setIsFromAST() { IsFromAST = true; } 261eee242ff426bf79149f221798966e58688383c1eDouglas Gregor 262eee242ff426bf79149f221798966e58688383c1eDouglas Gregor /// \brief Determine whether this identifier has changed since it was loaded 263eee242ff426bf79149f221798966e58688383c1eDouglas Gregor /// from an AST file. 264eee242ff426bf79149f221798966e58688383c1eDouglas Gregor bool hasChangedSinceDeserialization() const { 265eee242ff426bf79149f221798966e58688383c1eDouglas Gregor return ChangedAfterLoad; 266eee242ff426bf79149f221798966e58688383c1eDouglas Gregor } 267eee242ff426bf79149f221798966e58688383c1eDouglas Gregor 268eee242ff426bf79149f221798966e58688383c1eDouglas Gregor /// \brief Note that this identifier has changed since it was loaded from 269eee242ff426bf79149f221798966e58688383c1eDouglas Gregor /// an AST file. 270eee242ff426bf79149f221798966e58688383c1eDouglas Gregor void setChangedSinceDeserialization() { 271eee242ff426bf79149f221798966e58688383c1eDouglas Gregor ChangedAfterLoad = true; 272eee242ff426bf79149f221798966e58688383c1eDouglas Gregor } 273ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl 274eee242ff426bf79149f221798966e58688383c1eDouglas Gregor /// \brief Determine whether the information for this identifier is out of 275eee242ff426bf79149f221798966e58688383c1eDouglas Gregor /// date with respect to the external source. 276eee242ff426bf79149f221798966e58688383c1eDouglas Gregor bool isOutOfDate() const { return OutOfDate; } 277eee242ff426bf79149f221798966e58688383c1eDouglas Gregor 278eee242ff426bf79149f221798966e58688383c1eDouglas Gregor /// \brief Set whether the information for this identifier is out of 279eee242ff426bf79149f221798966e58688383c1eDouglas Gregor /// date with respect to the external source. 280eee242ff426bf79149f221798966e58688383c1eDouglas Gregor void setOutOfDate(bool OOD) { 281eee242ff426bf79149f221798966e58688383c1eDouglas Gregor OutOfDate = OOD; 282eee242ff426bf79149f221798966e58688383c1eDouglas Gregor if (OOD) 283eee242ff426bf79149f221798966e58688383c1eDouglas Gregor NeedsHandleIdentifier = true; 284eee242ff426bf79149f221798966e58688383c1eDouglas Gregor else 285eee242ff426bf79149f221798966e58688383c1eDouglas Gregor RecomputeNeedsHandleIdentifier(); 286eee242ff426bf79149f221798966e58688383c1eDouglas Gregor } 287eee242ff426bf79149f221798966e58688383c1eDouglas Gregor 28832ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek /// \brief Determine whether this is the contextual keyword 28932ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek /// '__experimental_modules_import'. 29032ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek bool isModulesImport() const { return IsModulesImport; } 291c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor 29232ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek /// \brief Set whether this identifier is the contextual keyword 29332ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek /// '__experimental_modules_import'. 29432ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek void setModulesImport(bool I) { 29532ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek IsModulesImport = I; 296c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor if (I) 297c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor NeedsHandleIdentifier = true; 298c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor else 299c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor RecomputeNeedsHandleIdentifier(); 300c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor } 301c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor 3026a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattnerprivate: 3036a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// RecomputeNeedsHandleIdentifier - The Preprocessor::HandleIdentifier does 3046a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// several special (but rare) things to identifiers of various sorts. For 3056a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// example, it changes the "for" keyword token from tok::identifier to 3066a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// tok::for. 3076a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// 3086a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// This method is very tied to the definition of HandleIdentifier. Any 3096a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// change to it should be reflected here. 3106a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void RecomputeNeedsHandleIdentifier() { 3116a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 3126a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() | 313eee242ff426bf79149f221798966e58688383c1eDouglas Gregor isExtensionToken() | isCXX11CompatKeyword() || isOutOfDate() || 31432ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek isModulesImport()); 3156a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 3165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 3175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 31828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// \brief an RAII object for [un]poisoning an identifier 31928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// within a certain scope. II is allowed to be null, in 32028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// which case, objects of this type have no effect. 32128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegleyclass PoisonIdentifierRAIIObject { 32228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley IdentifierInfo *const II; 32328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley const bool OldValue; 32428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegleypublic: 32528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley PoisonIdentifierRAIIObject(IdentifierInfo *II, bool NewValue) 32628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley : II(II), OldValue(II ? II->isPoisoned() : false) { 32728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley if(II) 32828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley II->setIsPoisoned(NewValue); 32928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley } 33028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley 33128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley ~PoisonIdentifierRAIIObject() { 33228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley if(II) 33328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley II->setIsPoisoned(OldValue); 33428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley } 33528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley}; 33628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley 33795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// \brief An iterator that walks over all of the known identifiers 33895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// in the lookup table. 33995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// 34095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// Since this iterator uses an abstract interface via virtual 34195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// functions, it uses an object-oriented interface rather than the 34295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// more standard C++ STL iterator interface. In this OO-style 34395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// iteration, the single function \c Next() provides dereference, 34495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// advance, and end-of-sequence checking in a single 34595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// operation. Subclasses of this iterator type will provide the 34695f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// actual functionality. 34795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregorclass IdentifierIterator { 34895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregorprivate: 34995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor IdentifierIterator(const IdentifierIterator&); // Do not implement 35095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor IdentifierIterator &operator=(const IdentifierIterator&); // Do not implement 35195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 35295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregorprotected: 35395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor IdentifierIterator() { } 35495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 35595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregorpublic: 35695f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor virtual ~IdentifierIterator(); 35795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 35895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// \brief Retrieve the next string in the identifier table and 35995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// advances the iterator for the following string. 36095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// 36195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// \returns The next string in the identifier table. If there is 362686775deca8b8685eb90801495880e3abdd844c2Chris Lattner /// no such string, returns an empty \c StringRef. 363686775deca8b8685eb90801495880e3abdd844c2Chris Lattner virtual StringRef Next() = 0; 36495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor}; 36595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 36672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek/// IdentifierInfoLookup - An abstract class used by IdentifierTable that 367668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor/// provides an interface for performing lookups from strings 36872b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek/// (const char *) to IdentiferInfo objects. 36972b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenekclass IdentifierInfoLookup { 37072b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenekpublic: 37172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek virtual ~IdentifierInfoLookup(); 3721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 37372b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek /// get - Return the identifier token info for the specified named identifier. 37472b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek /// Unlike the version in IdentifierTable, this returns a pointer instead 37572b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek /// of a reference. If the pointer is NULL then the IdentifierInfo cannot 37672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek /// be found. 377686775deca8b8685eb90801495880e3abdd844c2Chris Lattner virtual IdentifierInfo* get(StringRef Name) = 0; 37895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 37995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// \brief Retrieve an iterator into the set of all identifiers 38095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// known to this identifier lookup source. 38195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// 38295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// This routine provides access to all of the identifiers known to 38395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// the identifier lookup, allowing access to the contents of the 38495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// identifiers without introducing the overhead of constructing 38595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// IdentifierInfo objects for each. 38695f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// 38795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// \returns A new iterator into the set of known identifiers. The 38895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// caller is responsible for deleting this iterator. 38995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor virtual IdentifierIterator *getIdentifiers() const; 3901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}; 3918c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 3928c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// \brief An abstract class used to resolve numerical identifier 3938c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// references (meaningful only to some external source) into 3948c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// IdentifierInfo pointers. 3958c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorclass ExternalIdentifierLookup { 3968c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorpublic: 3978c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor virtual ~ExternalIdentifierLookup(); 3988c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 3998c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor /// \brief Return the identifier associated with the given ID number. 4008c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor /// 4018c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor /// The ID 0 is associated with the NULL identifier. 4028c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor virtual IdentifierInfo *GetIdentifier(unsigned ID) = 0; 4038c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor}; 4048c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 405af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// \brief Implements an efficient mapping from strings to IdentifierInfo nodes. 406af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// 407af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// This has no other purpose, but this is an extremely performance-critical 408af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// piece of the code, as each occurrence of every identifier goes through 409af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// here when lexed. 4105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierTable { 4115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Shark shows that using MallocAllocator is *much* slower than using this 4125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // BumpPtrAllocator! 413ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek typedef llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator> HashTableTy; 4145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer HashTableTy HashTable; 4151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 41672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek IdentifierInfoLookup* ExternalLookup; 4171cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 4185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic: 419af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// \brief Create the identifier table, populating it with info about the 420af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// language keywords for the language specified by \p LangOpts. 42172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek IdentifierTable(const LangOptions &LangOpts, 42272b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek IdentifierInfoLookup* externalLookup = 0); 4231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 424668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor /// \brief Set the external identifier lookup mechanism. 425668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor void setExternalIdentifierLookup(IdentifierInfoLookup *IILookup) { 426668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor ExternalLookup = IILookup; 427668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor } 428668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor 42995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// \brief Retrieve the external identifier lookup object, if any. 43095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor IdentifierInfoLookup *getExternalIdentifierLookup() const { 43195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor return ExternalLookup; 43295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor } 43395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 43472b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek llvm::BumpPtrAllocator& getAllocator() { 43572b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek return HashTable.getAllocator(); 43672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek } 4371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 438af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// \brief Return the identifier token info for the specified named 439af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// identifier. 440686775deca8b8685eb90801495880e3abdd844c2Chris Lattner IdentifierInfo &get(StringRef Name) { 441ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek llvm::StringMapEntry<IdentifierInfo*> &Entry = 4426488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam HashTable.GetOrCreateValue(Name); 4431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 444ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek IdentifierInfo *II = Entry.getValue(); 445d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar if (II) return *II; 4461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 447d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // No entry; if we have an external lookup, look there first. 448d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar if (ExternalLookup) { 4496488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam II = ExternalLookup->get(Name); 450d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar if (II) { 451d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // Cache in the StringMap for subsequent lookups. 452d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar Entry.setValue(II); 453d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar return *II; 454ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek } 455d42ffbd22fc7eb61321f6a88173ee424991f01c6Ted Kremenek } 456ccb9bac3adb35a2dc78c1737e7b2dc6537a16393Daniel Dunbar 457d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // Lookups failed, make a new IdentifierInfo. 458d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar void *Mem = getAllocator().Allocate<IdentifierInfo>(); 459d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar II = new (Mem) IdentifierInfo(); 460d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar Entry.setValue(II); 461d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar 462d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // Make sure getName() knows how to find the IdentifierInfo 463d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // contents. 464d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar II->Entry = &Entry; 465d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar 466ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek return *II; 4675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 4681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 469686775deca8b8685eb90801495880e3abdd844c2Chris Lattner IdentifierInfo &get(StringRef Name, tok::TokenKind TokenCode) { 470646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis IdentifierInfo &II = get(Name); 471646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis II.TokenID = TokenCode; 472d648d373d6c14dccadd3bef7b560f6a7296f949ePeter Collingbourne assert(II.TokenID == (unsigned) TokenCode && "TokenCode too large"); 473646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis return II; 474646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis } 475646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis 476ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl /// \brief Gets an IdentifierInfo for the given name without consulting 477ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl /// external sources. 4785f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor /// 479ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl /// This is a version of get() meant for external sources that want to 480ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl /// introduce or modify an identifier. If they called get(), they would 481ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl /// likely end up in a recursion. 482686775deca8b8685eb90801495880e3abdd844c2Chris Lattner IdentifierInfo &getOwn(StringRef Name) { 4835f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor llvm::StringMapEntry<IdentifierInfo*> &Entry = 48465aa6885818d4b4eea2e5a9d12085b2398148662Jay Foad HashTable.GetOrCreateValue(Name); 4851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4865f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor IdentifierInfo *II = Entry.getValue(); 487ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl if (!II) { 4881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 489ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl // Lookups failed, make a new IdentifierInfo. 490ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl void *Mem = getAllocator().Allocate<IdentifierInfo>(); 491ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl II = new (Mem) IdentifierInfo(); 492ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl Entry.setValue(II); 4935f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor 494ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl // Make sure getName() knows how to find the IdentifierInfo 495ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl // contents. 496ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl II->Entry = &Entry; 497c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor 498c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor // If this is the 'import' contextual keyword, mark it as such. 499c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor if (Name.equals("import")) 50032ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek II->setModulesImport(true); 501ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl } 5025f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor 5035f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor return *II; 5045f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor } 5055f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor 5065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer typedef HashTableTy::const_iterator iterator; 5075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer typedef HashTableTy::const_iterator const_iterator; 5081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer iterator begin() const { return HashTable.begin(); } 5105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer iterator end() const { return HashTable.end(); } 511c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek unsigned size() const { return HashTable.size(); } 5121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 513af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// \brief Print some statistics to stderr that indicate how well the 5145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// hashing is doing. 5155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void PrintStats() const; 5161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void AddKeywords(const LangOptions &LangOpts); 5185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 5195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 520af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// \brief A family of Objective-C methods. 521af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// 522af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// These families have no inherent meaning in the language, but are 52385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// nonetheless central enough in the existing implementations to 52485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// merit direct AST support. While, in theory, arbitrary methods can 52585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// be considered to form families, we focus here on the methods 52685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// involving allocation and retain-count management, as these are the 52785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// most "core" and the most likely to be useful to diverse clients 52885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// without extra information. 52985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// 53085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// Both selectors and actual method declarations may be classified 53185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// into families. Method families may impose additional restrictions 53285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// beyond their selector name; for example, a method called '_init' 53385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// that returns void is not considered to be in the 'init' family 53485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// (but would be if it returned 'id'). It is also possible to 53585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// explicitly change or remove a method's family. Therefore the 53685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// method's family should be considered the single source of truth. 53785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCallenum ObjCMethodFamily { 53885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall /// \brief No particular method family. 53985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_None, 54085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 54185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall // Selectors in these families may have arbitrary arity, may be 54285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall // written with arbitrary leading underscores, and may have 54385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall // additional CamelCase "words" in their first selector chunk 54485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall // following the family name. 54585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_alloc, 54685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_copy, 54785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_init, 54885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_mutableCopy, 54985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_new, 55085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 55185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall // These families are singletons consisting only of the nullary 55285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall // selector with the given name. 55385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_autorelease, 55485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_dealloc, 55580cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber OMF_finalize, 55685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_release, 55785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_retain, 558926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor OMF_retainCount, 5599670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian OMF_self, 5609670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian 5619670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian // performSelector families 5629670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian OMF_performSelector 56385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall}; 56485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 56585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// Enough bits to store any enumerator in ObjCMethodFamily or 56685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// InvalidObjCMethodFamily. 56785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCallenum { ObjCMethodFamilyBitWidth = 4 }; 56885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 569af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// \brief An invalid value of ObjCMethodFamily. 57085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCallenum { InvalidObjCMethodFamily = (1 << ObjCMethodFamilyBitWidth) - 1 }; 57185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 572af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// \brief Smart pointer class that efficiently represents Objective-C method 573af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// names. 574af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// 575af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// This class will either point to an IdentifierInfo or a 57629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// MultiKeywordSelector (which is private). This enables us to optimize 5771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// selectors that take no arguments and selectors that take 1 argument, which 57829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// accounts for 78% of all selectors in Cocoa.h. 579bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroffclass Selector { 58040847cfb58acc3cac7d68727df9455ac45f2e118David Blaikie friend class Diagnostic; 5811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 582bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff enum IdentifierInfoFlag { 58351603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor // Empty selector = 0. 584bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff ZeroArg = 0x1, 585bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff OneArg = 0x2, 58651603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor MultiArg = 0x3, 587bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff ArgFlags = ZeroArg|OneArg 588bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff }; 589bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff uintptr_t InfoPtr; // a pointer to the MultiKeywordSelector or IdentifierInfo. 5901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 591bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff Selector(IdentifierInfo *II, unsigned nArgs) { 592bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff InfoPtr = reinterpret_cast<uintptr_t>(II); 5930e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo"); 5940e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner assert(nArgs < 2 && "nArgs not equal to 0/1"); 5950e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner InfoPtr |= nArgs+1; 596bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 597bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff Selector(MultiKeywordSelector *SI) { 598bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff InfoPtr = reinterpret_cast<uintptr_t>(SI); 5990e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo"); 60051603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor InfoPtr |= MultiArg; 601bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 6021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 603bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff IdentifierInfo *getAsIdentifierInfo() const { 60451603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor if (getIdentifierInfoFlag() < MultiArg) 605bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags); 606bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return 0; 607bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 60851603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor MultiKeywordSelector *getMultiKeywordSelector() const { 60951603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor return reinterpret_cast<MultiKeywordSelector *>(InfoPtr & ~ArgFlags); 61051603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor } 61151603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor 612bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff unsigned getIdentifierInfoFlag() const { 613bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return InfoPtr & ArgFlags; 614bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 6158af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek 61685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall static ObjCMethodFamily getMethodFamilyImpl(Selector sel); 61785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 6188af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenekpublic: 6198af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek friend class SelectorTable; // only the SelectorTable can create these 6208af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek friend class DeclarationName; // and the AST's DeclarationName. 6218af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek 6228af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek /// The default ctor should only be used when creating data structures that 6238af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek /// will contain selectors. 6248af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek Selector() : InfoPtr(0) {} 62590cd1bb1baac2a0221f3642de0cbea3244b116e5Steve Naroff Selector(uintptr_t V) : InfoPtr(V) {} 6268af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek 627bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff /// operator==/!= - Indicate whether the specified selectors are identical. 62897b7f26a92d87e514530a5b652460190ce48c974Ted Kremenek bool operator==(Selector RHS) const { 629bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return InfoPtr == RHS.InfoPtr; 630bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 63197b7f26a92d87e514530a5b652460190ce48c974Ted Kremenek bool operator!=(Selector RHS) const { 632bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return InfoPtr != RHS.InfoPtr; 633bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 634bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff void *getAsOpaquePtr() const { 635bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return reinterpret_cast<void*>(InfoPtr); 636bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 637405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor 638405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor /// \brief Determine whether this is the empty selector. 639405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor bool isNull() const { return InfoPtr == 0; } 640405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor 641bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff // Predicates to identify the selector type. 6421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bool isKeywordSelector() const { 6431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return getIdentifierInfoFlag() != ZeroArg; 644bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 6451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bool isUnarySelector() const { 646bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return getIdentifierInfoFlag() == ZeroArg; 647bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 6485b6b72f53ad164497cf62484b60cdbb4361f1978Steve Naroff unsigned getNumArgs() const; 649813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor 650813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor 651813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// \brief Retrieve the identifier at a given position in the selector. 652813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// 653813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// Note that the identifier pointer returned may be NULL. Clients that only 654813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// care about the text of the identifier string, and not the specific, 655813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// uniqued identifier pointer, should use \c getNameForSlot(), which returns 656813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// an empty string when the identifier pointer would be NULL. 657813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// 658813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// \param argIndex The index for which we want to retrieve the identifier. 659813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// This index shall be less than \c getNumArgs() unless this is a keyword 660813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// selector, in which case 0 is the only permissible value. 661813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// 662813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// \returns the uniqued identifier for this slot, or NULL if this slot has 663813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// no corresponding identifier. 664f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const; 665813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor 666813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// \brief Retrieve the name at a given position in the selector. 667813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// 668813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// \param argIndex The index for which we want to retrieve the name. 669813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// This index shall be less than \c getNumArgs() unless this is a keyword 670813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// selector, in which case 0 is the only permissible value. 671813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// 672813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// \returns the name for this slot, which may be the empty string if no 673813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// name was supplied. 674686775deca8b8685eb90801495880e3abdd844c2Chris Lattner StringRef getNameForSlot(unsigned argIndex) const; 675813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor 676af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// \brief Derive the full selector name (e.g. "foo:bar:") and return 677077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner /// it as an std::string. 6787ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis // FIXME: Add a print method that uses a raw_ostream. 679077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner std::string getAsString() const; 6801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 681af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// \brief Derive the conventional family of this method. 68285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall ObjCMethodFamily getMethodFamily() const { 68385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall return getMethodFamilyImpl(*this); 68485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall } 68585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 68685994260c41a54cab061a434ed378fc448333a4eChris Lattner static Selector getEmptyMarker() { 68785994260c41a54cab061a434ed378fc448333a4eChris Lattner return Selector(uintptr_t(-1)); 68885994260c41a54cab061a434ed378fc448333a4eChris Lattner } 68985994260c41a54cab061a434ed378fc448333a4eChris Lattner static Selector getTombstoneMarker() { 69085994260c41a54cab061a434ed378fc448333a4eChris Lattner return Selector(uintptr_t(-2)); 69185994260c41a54cab061a434ed378fc448333a4eChris Lattner } 692bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff}; 693bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff 694af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// \brief This table allows us to fully hide how we implement 69529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// multi-keyword caching. 69629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffclass SelectorTable { 6975f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner void *Impl; // Actually a SelectorTableImpl 69829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff SelectorTable(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT 69929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff void operator=(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT 70029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffpublic: 70129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff SelectorTable(); 70229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff ~SelectorTable(); 70329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 704af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// \brief Can create any sort of selector. 705af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// 706af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// \p NumArgs indicates whether this is a no argument selector "foo", a 707af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// single argument selector "foo:" or multi-argument "foo:bar:". 708ff38491c18b060526d754765b952f4a497a89416Chris Lattner Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV); 7091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 710ff38491c18b060526d754765b952f4a497a89416Chris Lattner Selector getUnarySelector(IdentifierInfo *ID) { 711ff38491c18b060526d754765b952f4a497a89416Chris Lattner return Selector(ID, 1); 712ff38491c18b060526d754765b952f4a497a89416Chris Lattner } 713ff38491c18b060526d754765b952f4a497a89416Chris Lattner Selector getNullarySelector(IdentifierInfo *ID) { 714ff38491c18b060526d754765b952f4a497a89416Chris Lattner return Selector(ID, 0); 715ff38491c18b060526d754765b952f4a497a89416Chris Lattner } 71661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 717af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// \brief Return the total amount of memory allocated for managing selectors. 71897f55d6ffd548d1777d790c84b358030682f9de2Ted Kremenek size_t getTotalMemory() const; 71997f55d6ffd548d1777d790c84b358030682f9de2Ted Kremenek 720af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// \brief Return the setter name for the given identifier. 721af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// 722af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// This is "set" + \p Name where the initial character of \p Name 72361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff /// has been capitalized. 724fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff static Selector constructSetterName(IdentifierTable &Idents, 725fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff SelectorTable &SelTable, 7268fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer const IdentifierInfo *Name); 72729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff}; 72829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 729e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// DeclarationNameExtra - Common base of the MultiKeywordSelector, 730e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// CXXSpecialName, and CXXOperatorIdName classes, all of which are 731e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// private classes that describe different kinds of names. 7322e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorclass DeclarationNameExtra { 7332e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorpublic: 7342e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// ExtraKind - The kind of "extra" information stored in the 7352e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// DeclarationName. See @c ExtraKindOrNumArgs for an explanation of 7362e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// how these enumerator values are used. 7372e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor enum ExtraKind { 7382e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor CXXConstructor = 0, 7392e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor CXXDestructor, 7402e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor CXXConversionFunction, 741e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 742e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor CXXOperator##Name, 743e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor#include "clang/Basic/OperatorKinds.def" 7443e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt CXXLiteralOperator, 7452a3009a432bdcec59e6383d7b2b17494d6f91649Douglas Gregor CXXUsingDirective, 7462e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor NUM_EXTRA_KINDS 7472e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor }; 7485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 749e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor /// ExtraKindOrNumArgs - Either the kind of C++ special name or 750e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor /// operator-id (if the value is one of the CXX* enumerators of 751e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor /// ExtraKind), in which case the DeclarationNameExtra is also a 7523e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt /// CXXSpecialName, (for CXXConstructor, CXXDestructor, or 7533e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt /// CXXConversionFunction) CXXOperatorIdName, or CXXLiteralOperatorName, 7543e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt /// it may be also name common to C++ using-directives (CXXUsingDirective), 7553e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt /// otherwise it is NUM_EXTRA_KINDS+NumArgs, where NumArgs is the number of 7562e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// arguments in the Objective-C selector, in which case the 7572e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// DeclarationNameExtra is also a MultiKeywordSelector. 7582e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor unsigned ExtraKindOrNumArgs; 7592e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}; 7602e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor 7612e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor} // end namespace clang 7624365a7e46822700357a272d839ee2656d9603d5aChris Lattner 7632e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregornamespace llvm { 7644365a7e46822700357a272d839ee2656d9603d5aChris Lattner/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and 7654365a7e46822700357a272d839ee2656d9603d5aChris Lattner/// DenseSets. 76685994260c41a54cab061a434ed378fc448333a4eChris Lattnertemplate <> 76785994260c41a54cab061a434ed378fc448333a4eChris Lattnerstruct DenseMapInfo<clang::Selector> { 76885994260c41a54cab061a434ed378fc448333a4eChris Lattner static inline clang::Selector getEmptyKey() { 76985994260c41a54cab061a434ed378fc448333a4eChris Lattner return clang::Selector::getEmptyMarker(); 77085994260c41a54cab061a434ed378fc448333a4eChris Lattner } 77185994260c41a54cab061a434ed378fc448333a4eChris Lattner static inline clang::Selector getTombstoneKey() { 7721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return clang::Selector::getTombstoneMarker(); 77385994260c41a54cab061a434ed378fc448333a4eChris Lattner } 7741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 77585994260c41a54cab061a434ed378fc448333a4eChris Lattner static unsigned getHashValue(clang::Selector S); 7761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 77785994260c41a54cab061a434ed378fc448333a4eChris Lattner static bool isEqual(clang::Selector LHS, clang::Selector RHS) { 77885994260c41a54cab061a434ed378fc448333a4eChris Lattner return LHS == RHS; 77985994260c41a54cab061a434ed378fc448333a4eChris Lattner } 78085994260c41a54cab061a434ed378fc448333a4eChris Lattner}; 781700030ebddb987936d4fee14d9412821d96e4840Kovarththanan Rajaratnam 78206159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnertemplate <> 78306159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnerstruct isPodLike<clang::Selector> { static const bool value = true; }; 78406159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner 785d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregortemplate<> 786d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregorclass PointerLikeTypeTraits<clang::Selector> { 787d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregorpublic: 788d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor static inline const void *getAsVoidPointer(clang::Selector P) { 789d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor return P.getAsOpaquePtr(); 790d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor } 791d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor static inline clang::Selector getFromVoidPointer(const void *P) { 792d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor return clang::Selector(reinterpret_cast<uintptr_t>(P)); 793d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor } 794d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor enum { NumLowBitsAvailable = 0 }; 795d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor}; 79685994260c41a54cab061a434ed378fc448333a4eChris Lattner 7971734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor// Provide PointerLikeTypeTraits for IdentifierInfo pointers, which 7981734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor// are not guaranteed to be 8-byte aligned. 7991734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregortemplate<> 8001734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorclass PointerLikeTypeTraits<clang::IdentifierInfo*> { 8011734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorpublic: 8021734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor static inline void *getAsVoidPointer(clang::IdentifierInfo* P) { 8031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return P; 8041734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor } 8051734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor static inline clang::IdentifierInfo *getFromVoidPointer(void *P) { 8061734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor return static_cast<clang::IdentifierInfo*>(P); 8071734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor } 8081734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor enum { NumLowBitsAvailable = 1 }; 8091734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor}; 8101734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor 8111734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregortemplate<> 8121734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorclass PointerLikeTypeTraits<const clang::IdentifierInfo*> { 8131734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorpublic: 8141734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor static inline const void *getAsVoidPointer(const clang::IdentifierInfo* P) { 8151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return P; 8161734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor } 8171734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor static inline const clang::IdentifierInfo *getFromVoidPointer(const void *P) { 8181734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor return static_cast<const clang::IdentifierInfo*>(P); 8191734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor } 8201734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor enum { NumLowBitsAvailable = 1 }; 8211734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor}; 8221734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor 8232e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor} // end namespace llvm 8245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif 825