IdentifierTable.h revision 28bbe4b8acc338476fe0825769b41fb32b423c72
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//===----------------------------------------------------------------------===// 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 10c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner// This file defines the IdentifierInfo, IdentifierTable, and Selector 11c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner// interfaces. 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 15c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H 16c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H 175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 181cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor#include "clang/Basic/OperatorKinds.h" 195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/TokenKinds.h" 205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/StringMap.h" 21700030ebddb987936d4fee14d9412821d96e4840Kovarththanan Rajaratnam#include "llvm/ADT/StringRef.h" 2268d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff#include "llvm/ADT/SmallString.h" 2372b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek#include "llvm/ADT/OwningPtr.h" 241734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor#include "llvm/Support/PointerLikeTypeTraits.h" 251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#include <cassert> 26403ba3522d1b1c97ae5fad81c1a2c4b3a754e1c1Nick Lewycky#include <cctype> 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 417caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner /// IdentifierLocPair - A simple pair of identifier info and location. 427caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair; 431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierInfo - One of these records is kept for each identifier that 465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 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 { 518e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek // Note: DON'T make TokenID a 'tok::TokenKind'; MSVC will treat it as a 528e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek // signed char and TokenKinds > 127 won't be handled correctly. 531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump unsigned TokenID : 8; // Front-end token ID or tok::identifier. 545142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor // Objective-C keyword ('protocol' in '@protocol') or builtin (__builtin_inf). 555142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor // First NUM_OBJC_KEYWORDS values are for Objective-C, the remaining values 565142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor // are for builtins. 57c81ca9852806e75972bbb246fa916152e8fba541Ted Kremenek unsigned ObjCOrBuiltinID :11; 584365a7e46822700357a272d839ee2656d9603d5aChris Lattner bool HasMacro : 1; // True if there is a #define for this. 595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsExtension : 1; // True if identifier is a lang extension. 605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsPoisoned : 1; // True if identifier is poisoned. 615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword. 626a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner bool NeedsHandleIdentifier : 1; // See "RecomputeNeedsHandleIdentifier". 633c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl bool IsFromAST : 1; // True if identfier first appeared in an AST 643c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl // file and wasn't modified since. 65646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis bool RevertedTokenID : 1; // True if RevertTokenIDToIdentifier was 66646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis // called. 67c81ca9852806e75972bbb246fa916152e8fba541Ted Kremenek // 6 bits left in 32-bit word. 685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void *FETokenInfo; // Managed by the language front-end. 69ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek llvm::StringMapEntry<IdentifierInfo*> *Entry; 701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IdentifierInfo(const IdentifierInfo&); // NONCOPYABLE. 724365a7e46822700357a272d839ee2656d9603d5aChris Lattner void operator=(const IdentifierInfo&); // NONASSIGNABLE. 73ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek 741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump friend class IdentifierTable; 75295a2a617ac335f590e430ab7fcd98f8ce109251Douglas Gregor 765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic: 77ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek IdentifierInfo(); 785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8092e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner /// isStr - Return true if this is the identifier for the specified string. 8192e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner /// This is intended to be used for string literals only: II->isStr("foo"). 8292e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner template <std::size_t StrLen> 8392e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner bool isStr(const char (&Str)[StrLen]) const { 847fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar return getLength() == StrLen-1 && !memcmp(getNameStart(), Str, StrLen-1); 85845222ccd992282bf74b2fca53e7c3b84a81c098Chris Lattner } 861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 877fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar /// getNameStart - Return the beginning of the actual string for this 887fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar /// identifier. The returned string is properly null terminated. 895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 907fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar const char *getNameStart() const { 91ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek if (Entry) return Entry->getKeyData(); 927e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // FIXME: This is gross. It would be best not to embed specific details 937e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // of the PTH file format here. 941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // The 'this' pointer really points to a 95ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek // std::pair<IdentifierInfo, const char*>, where internal pointer 96ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek // points to the external string data. 9740844a8b5a89676fb61898d61ea4a7fa98eb9b6bGabor Greif typedef std::pair<IdentifierInfo, const char*> actualtype; 9840844a8b5a89676fb61898d61ea4a7fa98eb9b6bGabor Greif return ((const actualtype*) this)->second; 991f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner } 1001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1011f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner /// getLength - Efficiently return the length of this identifier info. 1021f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner /// 1031f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner unsigned getLength() const { 104ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek if (Entry) return Entry->getKeyLength(); 1057e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // FIXME: This is gross. It would be best not to embed specific details 1067e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // of the PTH file format here. 1071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // The 'this' pointer really points to a 108ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek // std::pair<IdentifierInfo, const char*>, where internal pointer 109ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek // points to the external string data. 11040844a8b5a89676fb61898d61ea4a7fa98eb9b6bGabor Greif typedef std::pair<IdentifierInfo, const char*> actualtype; 11140844a8b5a89676fb61898d61ea4a7fa98eb9b6bGabor Greif const char* p = ((const actualtype*) this)->second - 2; 1127fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar return (((unsigned) p[0]) | (((unsigned) p[1]) << 8)) - 1; 1137fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar } 1147fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar 11501eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar /// getName - Return the actual identifier string. 11601eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar llvm::StringRef getName() const { 1177fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar return llvm::StringRef(getNameStart(), getLength()); 1185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1209c46de446d18f4a28446cb798d4131bd05515699Chris Lattner /// hasMacroDefinition - Return true if this identifier is #defined to some 1219c46de446d18f4a28446cb798d4131bd05515699Chris Lattner /// other value. 1229c46de446d18f4a28446cb798d4131bd05515699Chris Lattner bool hasMacroDefinition() const { 1239c46de446d18f4a28446cb798d4131bd05515699Chris Lattner return HasMacro; 1249c46de446d18f4a28446cb798d4131bd05515699Chris Lattner } 1256a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void setHasMacroDefinition(bool Val) { 1266a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (HasMacro == Val) return; 1271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1286a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner HasMacro = Val; 1296a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (Val) 1306a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 1; 1316a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner else 1326a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner RecomputeNeedsHandleIdentifier(); 1333c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl IsFromAST = false; 1346a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 1351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 136646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis /// getTokenID - If this is a source-language token (e.g. 'for'), this API 1375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// can be used to cause the lexer to map identifiers to source-language 1385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// tokens. 1398e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; } 140646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis 141646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis /// \brief True if RevertTokenIDToIdentifier() was called. 142646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis bool hasRevertedTokenIDToIdentifier() const { return RevertedTokenID; } 143646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis 144646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis /// \brief Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2 145f573084db5807f6003282bdf53ca9d58bab1ddc4Argyrios Kyrtzidis /// compatibility. 146f573084db5807f6003282bdf53ca9d58bab1ddc4Argyrios Kyrtzidis /// 147f573084db5807f6003282bdf53ca9d58bab1ddc4Argyrios Kyrtzidis /// TokenID is normally read-only but there are 2 instances where we revert it 148f573084db5807f6003282bdf53ca9d58bab1ddc4Argyrios Kyrtzidis /// to tok::identifier for libstdc++ 4.2. Keep track of when this happens 1493c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl /// using this method so we can inform serialization about it. 150646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis void RevertTokenIDToIdentifier() { 151646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis assert(TokenID != tok::identifier && "Already at tok::identifier"); 152646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis TokenID = tok::identifier; 153646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis RevertedTokenID = true; 154646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis } 1551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getPPKeywordID - Return the preprocessor keyword ID for this identifier. 1576d9a3e648d6bf6b347174152f191bd1377528f8cChris Lattner /// For example, "define" will return tok::pp_define. 158387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner tok::PPKeywordKind getPPKeywordID() const; 1591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getObjCKeywordID - Return the Objective-C keyword ID for the this 1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// identifier. For example, 'class' will return tok::objc_class if ObjC is 1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// enabled. 163ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek tok::ObjCKeywordKind getObjCKeywordID() const { 1641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (ObjCOrBuiltinID < tok::NUM_OBJC_KEYWORDS) 1655142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor return tok::ObjCKeywordKind(ObjCOrBuiltinID); 1665142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor else 1675142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor return tok::objc_not_keyword; 168ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek } 1695142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; } 1703251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor 1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getBuiltinID - Return a value indicating whether this is a builtin 1725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// function. 0 is not-built-in. 1 is builtin-for-some-nonprimary-target. 1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 2+ are specific builtin functions. 1741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump unsigned getBuiltinID() const { 1755142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS) 1761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS; 1775142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor else 1785142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor return 0; 1795142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor } 1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setBuiltinID(unsigned ID) { 1815142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor ObjCOrBuiltinID = ID + tok::NUM_OBJC_KEYWORDS; 1821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump assert(ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS) == ID 1835142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor && "ID too large for field!"); 1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1853251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor 1863251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor unsigned getObjCOrBuiltinID() const { return ObjCOrBuiltinID; } 1873251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor void setObjCOrBuiltinID(unsigned ID) { ObjCOrBuiltinID = ID; } 1883251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor 1895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// get/setExtension - Initialize information about whether or not this 1905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// language token is an extension. This controls extension warnings, and is 1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// only valid if a custom token ID is set. 1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isExtensionToken() const { return IsExtension; } 1936a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void setIsExtensionToken(bool Val) { 1946a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner IsExtension = Val; 1956a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (Val) 1966a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 1; 1976a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner else 1986a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner RecomputeNeedsHandleIdentifier(); 1996a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// setIsPoisoned - Mark this identifier as poisoned. After poisoning, the 2025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// Preprocessor will emit an error every time this token is used. 2036a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void setIsPoisoned(bool Value = true) { 2046a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner IsPoisoned = Value; 2056a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (Value) 2066a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 1; 2076a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner else 2086a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner RecomputeNeedsHandleIdentifier(); 2093c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl IsFromAST = false; 2106a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 2111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// isPoisoned - Return true if this token has been poisoned. 2135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isPoisoned() const { return IsPoisoned; } 2141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether 2165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// this identifier is a C++ alternate representation of an operator. 2176a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void setIsCPlusPlusOperatorKeyword(bool Val = true) { 2186a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner IsCPPOperatorKeyword = Val; 2196a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (Val) 2206a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 1; 2216a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner else 2226a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner RecomputeNeedsHandleIdentifier(); 2236a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 2245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; } 2255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getFETokenInfo/setFETokenInfo - The language front-end is allowed to 2275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// associate arbitrary metadata with this token. 2285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer template<typename T> 2295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); } 2305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setFETokenInfo(void *T) { FETokenInfo = T; } 2316a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner 2326a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// isHandleIdentifierCase - Return true if the Preprocessor::HandleIdentifier 2336a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// must be called on a token of this identifier. If this returns false, we 2346a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// know that HandleIdentifier will not affect the token. 2356a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner bool isHandleIdentifierCase() const { return NeedsHandleIdentifier; } 2361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2373c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl /// isFromAST - Return true if the identifier in its current state was loaded 2383c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl /// from an AST file. 2393c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl bool isFromAST() const { return IsFromAST; } 240ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl 2413c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl void setIsFromAST(bool FromAST = true) { IsFromAST = FromAST; } 242ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl 2436a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattnerprivate: 2446a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// RecomputeNeedsHandleIdentifier - The Preprocessor::HandleIdentifier does 2456a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// several special (but rare) things to identifiers of various sorts. For 2466a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// example, it changes the "for" keyword token from tok::identifier to 2476a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// tok::for. 2486a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// 2496a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// This method is very tied to the definition of HandleIdentifier. Any 2506a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// change to it should be reflected here. 2516a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void RecomputeNeedsHandleIdentifier() { 2526a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 2536a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() | 254863c486fcb6162495a94fddf7ac8409de2638995Chris Lattner isExtensionToken()); 2556a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 2565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 2575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 25828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// \brief an RAII object for [un]poisoning an identifier 25928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// within a certain scope. II is allowed to be null, in 26028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// which case, objects of this type have no effect. 26128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegleyclass PoisonIdentifierRAIIObject { 26228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley IdentifierInfo *const II; 26328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley const bool OldValue; 26428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegleypublic: 26528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley PoisonIdentifierRAIIObject(IdentifierInfo *II, bool NewValue) 26628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley : II(II), OldValue(II ? II->isPoisoned() : false) { 26728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley if(II) 26828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley II->setIsPoisoned(NewValue); 26928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley } 27028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley 27128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley ~PoisonIdentifierRAIIObject() { 27228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley if(II) 27328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley II->setIsPoisoned(OldValue); 27428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley } 27528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley}; 27628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley 27795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// \brief An iterator that walks over all of the known identifiers 27895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// in the lookup table. 27995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// 28095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// Since this iterator uses an abstract interface via virtual 28195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// functions, it uses an object-oriented interface rather than the 28295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// more standard C++ STL iterator interface. In this OO-style 28395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// iteration, the single function \c Next() provides dereference, 28495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// advance, and end-of-sequence checking in a single 28595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// operation. Subclasses of this iterator type will provide the 28695f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// actual functionality. 28795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregorclass IdentifierIterator { 28895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregorprivate: 28995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor IdentifierIterator(const IdentifierIterator&); // Do not implement 29095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor IdentifierIterator &operator=(const IdentifierIterator&); // Do not implement 29195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 29295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregorprotected: 29395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor IdentifierIterator() { } 29495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 29595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregorpublic: 29695f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor virtual ~IdentifierIterator(); 29795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 29895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// \brief Retrieve the next string in the identifier table and 29995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// advances the iterator for the following string. 30095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// 30195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// \returns The next string in the identifier table. If there is 30295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// no such string, returns an empty \c llvm::StringRef. 30395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor virtual llvm::StringRef Next() = 0; 30495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor}; 30595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 30672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek/// IdentifierInfoLookup - An abstract class used by IdentifierTable that 307668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor/// provides an interface for performing lookups from strings 30872b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek/// (const char *) to IdentiferInfo objects. 30972b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenekclass IdentifierInfoLookup { 31072b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenekpublic: 31172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek virtual ~IdentifierInfoLookup(); 3121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 31372b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek /// get - Return the identifier token info for the specified named identifier. 31472b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek /// Unlike the version in IdentifierTable, this returns a pointer instead 31572b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek /// of a reference. If the pointer is NULL then the IdentifierInfo cannot 31672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek /// be found. 317700030ebddb987936d4fee14d9412821d96e4840Kovarththanan Rajaratnam virtual IdentifierInfo* get(llvm::StringRef Name) = 0; 31895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 31995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// \brief Retrieve an iterator into the set of all identifiers 32095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// known to this identifier lookup source. 32195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// 32295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// This routine provides access to all of the identifiers known to 32395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// the identifier lookup, allowing access to the contents of the 32495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// identifiers without introducing the overhead of constructing 32595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// IdentifierInfo objects for each. 32695f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// 32795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// \returns A new iterator into the set of known identifiers. The 32895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// caller is responsible for deleting this iterator. 32995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor virtual IdentifierIterator *getIdentifiers() const; 3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}; 3318c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 3328c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// \brief An abstract class used to resolve numerical identifier 3338c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// references (meaningful only to some external source) into 3348c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// IdentifierInfo pointers. 3358c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorclass ExternalIdentifierLookup { 3368c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorpublic: 3378c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor virtual ~ExternalIdentifierLookup(); 3388c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 3398c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor /// \brief Return the identifier associated with the given ID number. 3408c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor /// 3418c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor /// The ID 0 is associated with the NULL identifier. 3428c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor virtual IdentifierInfo *GetIdentifier(unsigned ID) = 0; 3438c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor}; 3448c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 3455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierTable - This table implements an efficient mapping from strings to 3465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierInfo nodes. It has no other purpose, but this is an 347fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner/// extremely performance-critical piece of the code, as each occurrence of 3485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// every identifier goes through here when lexed. 3495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierTable { 3505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Shark shows that using MallocAllocator is *much* slower than using this 3515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // BumpPtrAllocator! 352ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek typedef llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator> HashTableTy; 3535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer HashTableTy HashTable; 3541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 35572b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek IdentifierInfoLookup* ExternalLookup; 3561cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 3575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic: 3585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// IdentifierTable ctor - Create the identifier table, populating it with 3595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// info about the language keywords for the language specified by LangOpts. 36072b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek IdentifierTable(const LangOptions &LangOpts, 36172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek IdentifierInfoLookup* externalLookup = 0); 3621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 363668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor /// \brief Set the external identifier lookup mechanism. 364668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor void setExternalIdentifierLookup(IdentifierInfoLookup *IILookup) { 365668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor ExternalLookup = IILookup; 366668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor } 367668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor 36895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// \brief Retrieve the external identifier lookup object, if any. 36995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor IdentifierInfoLookup *getExternalIdentifierLookup() const { 37095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor return ExternalLookup; 37195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor } 37295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 37372b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek llvm::BumpPtrAllocator& getAllocator() { 37472b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek return HashTable.getAllocator(); 37572b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek } 3761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// get - Return the identifier token info for the specified named identifier. 3785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 3796488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam IdentifierInfo &get(llvm::StringRef Name) { 380ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek llvm::StringMapEntry<IdentifierInfo*> &Entry = 3816488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam HashTable.GetOrCreateValue(Name); 3821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 383ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek IdentifierInfo *II = Entry.getValue(); 384d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar if (II) return *II; 3851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 386d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // No entry; if we have an external lookup, look there first. 387d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar if (ExternalLookup) { 3886488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam II = ExternalLookup->get(Name); 389d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar if (II) { 390d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // Cache in the StringMap for subsequent lookups. 391d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar Entry.setValue(II); 392d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar return *II; 393ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek } 394d42ffbd22fc7eb61321f6a88173ee424991f01c6Ted Kremenek } 395ccb9bac3adb35a2dc78c1737e7b2dc6537a16393Daniel Dunbar 396d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // Lookups failed, make a new IdentifierInfo. 397d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar void *Mem = getAllocator().Allocate<IdentifierInfo>(); 398d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar II = new (Mem) IdentifierInfo(); 399d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar Entry.setValue(II); 400d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar 401d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // Make sure getName() knows how to find the IdentifierInfo 402d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // contents. 403d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar II->Entry = &Entry; 404d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar 405ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek return *II; 4065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 4071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 408646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis IdentifierInfo &get(llvm::StringRef Name, tok::TokenKind TokenCode) { 409646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis IdentifierInfo &II = get(Name); 410646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis II.TokenID = TokenCode; 411646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis return II; 412646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis } 413646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis 4146488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam IdentifierInfo &get(const char *NameStart, const char *NameEnd) { 4156488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam return get(llvm::StringRef(NameStart, NameEnd-NameStart)); 416811f4267aa1ebd727c31594b8ed94048e2c10ad6Kovarththanan Rajaratnam } 417811f4267aa1ebd727c31594b8ed94048e2c10ad6Kovarththanan Rajaratnam 418811f4267aa1ebd727c31594b8ed94048e2c10ad6Kovarththanan Rajaratnam IdentifierInfo &get(const char *Name, size_t NameLen) { 419811f4267aa1ebd727c31594b8ed94048e2c10ad6Kovarththanan Rajaratnam return get(llvm::StringRef(Name, NameLen)); 420811f4267aa1ebd727c31594b8ed94048e2c10ad6Kovarththanan Rajaratnam } 421811f4267aa1ebd727c31594b8ed94048e2c10ad6Kovarththanan Rajaratnam 422ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl /// \brief Gets an IdentifierInfo for the given name without consulting 423ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl /// external sources. 4245f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor /// 425ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl /// This is a version of get() meant for external sources that want to 426ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl /// introduce or modify an identifier. If they called get(), they would 427ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl /// likely end up in a recursion. 428ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl IdentifierInfo &getOwn(const char *NameStart, const char *NameEnd) { 4295f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor llvm::StringMapEntry<IdentifierInfo*> &Entry = 4305f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor HashTable.GetOrCreateValue(NameStart, NameEnd); 4311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4325f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor IdentifierInfo *II = Entry.getValue(); 433ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl if (!II) { 4341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 435ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl // Lookups failed, make a new IdentifierInfo. 436ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl void *Mem = getAllocator().Allocate<IdentifierInfo>(); 437ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl II = new (Mem) IdentifierInfo(); 438ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl Entry.setValue(II); 4395f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor 440ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl // Make sure getName() knows how to find the IdentifierInfo 441ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl // contents. 442ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl II->Entry = &Entry; 443ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl } 4445f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor 4455f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor return *II; 4465f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor } 447ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl IdentifierInfo &getOwn(llvm::StringRef Name) { 448ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl return getOwn(Name.begin(), Name.end()); 44983885f7e3bf68d271e1e96726931814b836353a3Daniel Dunbar } 4505f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor 4515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer typedef HashTableTy::const_iterator iterator; 4525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer typedef HashTableTy::const_iterator const_iterator; 4531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer iterator begin() const { return HashTable.begin(); } 4555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer iterator end() const { return HashTable.end(); } 456c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek unsigned size() const { return HashTable.size(); } 4571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// PrintStats - Print some statistics to stderr that indicate how well the 4595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// hashing is doing. 4605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void PrintStats() const; 4611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void AddKeywords(const LangOptions &LangOpts); 4635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 4645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 46585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// ObjCMethodFamily - A family of Objective-C methods. These 46685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// families have no inherent meaning in the language, but are 46785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// nonetheless central enough in the existing implementations to 46885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// merit direct AST support. While, in theory, arbitrary methods can 46985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// be considered to form families, we focus here on the methods 47085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// involving allocation and retain-count management, as these are the 47185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// most "core" and the most likely to be useful to diverse clients 47285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// without extra information. 47385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// 47485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// Both selectors and actual method declarations may be classified 47585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// into families. Method families may impose additional restrictions 47685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// beyond their selector name; for example, a method called '_init' 47785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// that returns void is not considered to be in the 'init' family 47885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// (but would be if it returned 'id'). It is also possible to 47985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// explicitly change or remove a method's family. Therefore the 48085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// method's family should be considered the single source of truth. 48185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCallenum ObjCMethodFamily { 48285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall /// \brief No particular method family. 48385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_None, 48485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 48585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall // Selectors in these families may have arbitrary arity, may be 48685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall // written with arbitrary leading underscores, and may have 48785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall // additional CamelCase "words" in their first selector chunk 48885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall // following the family name. 48985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_alloc, 49085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_copy, 49185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_init, 49285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_mutableCopy, 49385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_new, 49485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 49585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall // These families are singletons consisting only of the nullary 49685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall // selector with the given name. 49785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_autorelease, 49885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_dealloc, 49985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_release, 50085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_retain, 50185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_retainCount 50285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall}; 50385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 50485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// Enough bits to store any enumerator in ObjCMethodFamily or 50585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// InvalidObjCMethodFamily. 50685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCallenum { ObjCMethodFamilyBitWidth = 4 }; 50785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 50885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// An invalid value of ObjCMethodFamily. 50985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCallenum { InvalidObjCMethodFamily = (1 << ObjCMethodFamilyBitWidth) - 1 }; 51085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 51129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// Selector - This smart pointer class efficiently represents Objective-C 51229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// method names. This class will either point to an IdentifierInfo or a 51329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// MultiKeywordSelector (which is private). This enables us to optimize 5141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// selectors that take no arguments and selectors that take 1 argument, which 51529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// accounts for 78% of all selectors in Cocoa.h. 516bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroffclass Selector { 5178af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek friend class DiagnosticInfo; 5181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 519bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff enum IdentifierInfoFlag { 5200e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner // MultiKeywordSelector = 0. 521bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff ZeroArg = 0x1, 522bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff OneArg = 0x2, 523bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff ArgFlags = ZeroArg|OneArg 524bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff }; 525bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff uintptr_t InfoPtr; // a pointer to the MultiKeywordSelector or IdentifierInfo. 5261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 527bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff Selector(IdentifierInfo *II, unsigned nArgs) { 528bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff InfoPtr = reinterpret_cast<uintptr_t>(II); 5290e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo"); 5300e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner assert(nArgs < 2 && "nArgs not equal to 0/1"); 5310e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner InfoPtr |= nArgs+1; 532bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 533bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff Selector(MultiKeywordSelector *SI) { 534bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff InfoPtr = reinterpret_cast<uintptr_t>(SI); 5350e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo"); 536bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 5371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 538bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff IdentifierInfo *getAsIdentifierInfo() const { 5390e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner if (getIdentifierInfoFlag()) 540bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags); 541bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return 0; 542bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 543bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff unsigned getIdentifierInfoFlag() const { 544bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return InfoPtr & ArgFlags; 545bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 5468af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek 54785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall static ObjCMethodFamily getMethodFamilyImpl(Selector sel); 54885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 5498af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenekpublic: 5508af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek friend class SelectorTable; // only the SelectorTable can create these 5518af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek friend class DeclarationName; // and the AST's DeclarationName. 5528af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek 5538af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek /// The default ctor should only be used when creating data structures that 5548af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek /// will contain selectors. 5558af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek Selector() : InfoPtr(0) {} 55690cd1bb1baac2a0221f3642de0cbea3244b116e5Steve Naroff Selector(uintptr_t V) : InfoPtr(V) {} 5578af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek 558bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff /// operator==/!= - Indicate whether the specified selectors are identical. 55997b7f26a92d87e514530a5b652460190ce48c974Ted Kremenek bool operator==(Selector RHS) const { 560bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return InfoPtr == RHS.InfoPtr; 561bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 56297b7f26a92d87e514530a5b652460190ce48c974Ted Kremenek bool operator!=(Selector RHS) const { 563bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return InfoPtr != RHS.InfoPtr; 564bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 565bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff void *getAsOpaquePtr() const { 566bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return reinterpret_cast<void*>(InfoPtr); 567bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 568405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor 569405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor /// \brief Determine whether this is the empty selector. 570405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor bool isNull() const { return InfoPtr == 0; } 571405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor 572bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff // Predicates to identify the selector type. 5731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bool isKeywordSelector() const { 5741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return getIdentifierInfoFlag() != ZeroArg; 575bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 5761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bool isUnarySelector() const { 577bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return getIdentifierInfoFlag() == ZeroArg; 578bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 5795b6b72f53ad164497cf62484b60cdbb4361f1978Steve Naroff unsigned getNumArgs() const; 580813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor 581813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor 582813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// \brief Retrieve the identifier at a given position in the selector. 583813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// 584813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// Note that the identifier pointer returned may be NULL. Clients that only 585813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// care about the text of the identifier string, and not the specific, 586813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// uniqued identifier pointer, should use \c getNameForSlot(), which returns 587813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// an empty string when the identifier pointer would be NULL. 588813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// 589813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// \param argIndex The index for which we want to retrieve the identifier. 590813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// This index shall be less than \c getNumArgs() unless this is a keyword 591813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// selector, in which case 0 is the only permissible value. 592813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// 593813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// \returns the uniqued identifier for this slot, or NULL if this slot has 594813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// no corresponding identifier. 595f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const; 596813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor 597813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// \brief Retrieve the name at a given position in the selector. 598813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// 599813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// \param argIndex The index for which we want to retrieve the name. 600813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// This index shall be less than \c getNumArgs() unless this is a keyword 601813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// selector, in which case 0 is the only permissible value. 602813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// 603813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// \returns the name for this slot, which may be the empty string if no 604813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// name was supplied. 605813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor llvm::StringRef getNameForSlot(unsigned argIndex) const; 606813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor 607077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner /// getAsString - Derive the full selector name (e.g. "foo:bar:") and return 608077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner /// it as an std::string. 609077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner std::string getAsString() const; 6101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 61185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall /// getMethodFamily - Derive the conventional family of this method. 61285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall ObjCMethodFamily getMethodFamily() const { 61385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall return getMethodFamilyImpl(*this); 61485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall } 61585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 61685994260c41a54cab061a434ed378fc448333a4eChris Lattner static Selector getEmptyMarker() { 61785994260c41a54cab061a434ed378fc448333a4eChris Lattner return Selector(uintptr_t(-1)); 61885994260c41a54cab061a434ed378fc448333a4eChris Lattner } 61985994260c41a54cab061a434ed378fc448333a4eChris Lattner static Selector getTombstoneMarker() { 62085994260c41a54cab061a434ed378fc448333a4eChris Lattner return Selector(uintptr_t(-2)); 62185994260c41a54cab061a434ed378fc448333a4eChris Lattner } 622bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff}; 623bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff 62429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// SelectorTable - This table allows us to fully hide how we implement 62529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// multi-keyword caching. 62629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffclass SelectorTable { 6275f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner void *Impl; // Actually a SelectorTableImpl 62829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff SelectorTable(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT 62929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff void operator=(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT 63029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffpublic: 63129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff SelectorTable(); 63229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff ~SelectorTable(); 63329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 634ff38491c18b060526d754765b952f4a497a89416Chris Lattner /// getSelector - This can create any sort of selector. NumArgs indicates 635ff38491c18b060526d754765b952f4a497a89416Chris Lattner /// whether this is a no argument selector "foo", a single argument selector 636ff38491c18b060526d754765b952f4a497a89416Chris Lattner /// "foo:" or multi-argument "foo:bar:". 637ff38491c18b060526d754765b952f4a497a89416Chris Lattner Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV); 6381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 639ff38491c18b060526d754765b952f4a497a89416Chris Lattner Selector getUnarySelector(IdentifierInfo *ID) { 640ff38491c18b060526d754765b952f4a497a89416Chris Lattner return Selector(ID, 1); 641ff38491c18b060526d754765b952f4a497a89416Chris Lattner } 642ff38491c18b060526d754765b952f4a497a89416Chris Lattner Selector getNullarySelector(IdentifierInfo *ID) { 643ff38491c18b060526d754765b952f4a497a89416Chris Lattner return Selector(ID, 0); 644ff38491c18b060526d754765b952f4a497a89416Chris Lattner } 64561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 64697f55d6ffd548d1777d790c84b358030682f9de2Ted Kremenek /// Return the total amount of memory allocated for managing selectors. 64797f55d6ffd548d1777d790c84b358030682f9de2Ted Kremenek size_t getTotalMemory() const; 64897f55d6ffd548d1777d790c84b358030682f9de2Ted Kremenek 64961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff /// constructSetterName - Return the setter name for the given 65061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff /// identifier, i.e. "set" + Name where the initial character of Name 65161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff /// has been capitalized. 652fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff static Selector constructSetterName(IdentifierTable &Idents, 653fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff SelectorTable &SelTable, 654fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff const IdentifierInfo *Name) { 65561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff llvm::SmallString<100> SelectorName; 65661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff SelectorName = "set"; 65701eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar SelectorName += Name->getName(); 65861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff SelectorName[3] = toupper(SelectorName[3]); 6592781deb126663ca1bd412044a1e66577585987b3Kovarththanan Rajaratnam IdentifierInfo *SetterName = &Idents.get(SelectorName); 660fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff return SelTable.getUnarySelector(SetterName); 66161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff } 66229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff}; 66329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 664e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// DeclarationNameExtra - Common base of the MultiKeywordSelector, 665e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// CXXSpecialName, and CXXOperatorIdName classes, all of which are 666e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// private classes that describe different kinds of names. 6672e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorclass DeclarationNameExtra { 6682e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorpublic: 6692e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// ExtraKind - The kind of "extra" information stored in the 6702e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// DeclarationName. See @c ExtraKindOrNumArgs for an explanation of 6712e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// how these enumerator values are used. 6722e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor enum ExtraKind { 6732e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor CXXConstructor = 0, 6742e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor CXXDestructor, 6752e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor CXXConversionFunction, 676e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 677e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor CXXOperator##Name, 678e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor#include "clang/Basic/OperatorKinds.def" 6793e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt CXXLiteralOperator, 6802a3009a432bdcec59e6383d7b2b17494d6f91649Douglas Gregor CXXUsingDirective, 6812e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor NUM_EXTRA_KINDS 6822e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor }; 6835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 684e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor /// ExtraKindOrNumArgs - Either the kind of C++ special name or 685e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor /// operator-id (if the value is one of the CXX* enumerators of 686e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor /// ExtraKind), in which case the DeclarationNameExtra is also a 6873e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt /// CXXSpecialName, (for CXXConstructor, CXXDestructor, or 6883e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt /// CXXConversionFunction) CXXOperatorIdName, or CXXLiteralOperatorName, 6893e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt /// it may be also name common to C++ using-directives (CXXUsingDirective), 6903e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt /// otherwise it is NUM_EXTRA_KINDS+NumArgs, where NumArgs is the number of 6912e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// arguments in the Objective-C selector, in which case the 6922e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// DeclarationNameExtra is also a MultiKeywordSelector. 6932e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor unsigned ExtraKindOrNumArgs; 6942e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}; 6952e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor 6962e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor} // end namespace clang 6974365a7e46822700357a272d839ee2656d9603d5aChris Lattner 6982e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregornamespace llvm { 6994365a7e46822700357a272d839ee2656d9603d5aChris Lattner/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and 7004365a7e46822700357a272d839ee2656d9603d5aChris Lattner/// DenseSets. 70185994260c41a54cab061a434ed378fc448333a4eChris Lattnertemplate <> 70285994260c41a54cab061a434ed378fc448333a4eChris Lattnerstruct DenseMapInfo<clang::Selector> { 70385994260c41a54cab061a434ed378fc448333a4eChris Lattner static inline clang::Selector getEmptyKey() { 70485994260c41a54cab061a434ed378fc448333a4eChris Lattner return clang::Selector::getEmptyMarker(); 70585994260c41a54cab061a434ed378fc448333a4eChris Lattner } 70685994260c41a54cab061a434ed378fc448333a4eChris Lattner static inline clang::Selector getTombstoneKey() { 7071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return clang::Selector::getTombstoneMarker(); 70885994260c41a54cab061a434ed378fc448333a4eChris Lattner } 7091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 71085994260c41a54cab061a434ed378fc448333a4eChris Lattner static unsigned getHashValue(clang::Selector S); 7111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 71285994260c41a54cab061a434ed378fc448333a4eChris Lattner static bool isEqual(clang::Selector LHS, clang::Selector RHS) { 71385994260c41a54cab061a434ed378fc448333a4eChris Lattner return LHS == RHS; 71485994260c41a54cab061a434ed378fc448333a4eChris Lattner } 71585994260c41a54cab061a434ed378fc448333a4eChris Lattner}; 716700030ebddb987936d4fee14d9412821d96e4840Kovarththanan Rajaratnam 71706159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnertemplate <> 71806159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnerstruct isPodLike<clang::Selector> { static const bool value = true; }; 71906159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner 720d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregortemplate<> 721d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregorclass PointerLikeTypeTraits<clang::Selector> { 722d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregorpublic: 723d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor static inline const void *getAsVoidPointer(clang::Selector P) { 724d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor return P.getAsOpaquePtr(); 725d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor } 726d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor static inline clang::Selector getFromVoidPointer(const void *P) { 727d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor return clang::Selector(reinterpret_cast<uintptr_t>(P)); 728d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor } 729d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor enum { NumLowBitsAvailable = 0 }; 730d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor}; 73185994260c41a54cab061a434ed378fc448333a4eChris Lattner 7321734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor// Provide PointerLikeTypeTraits for IdentifierInfo pointers, which 7331734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor// are not guaranteed to be 8-byte aligned. 7341734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregortemplate<> 7351734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorclass PointerLikeTypeTraits<clang::IdentifierInfo*> { 7361734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorpublic: 7371734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor static inline void *getAsVoidPointer(clang::IdentifierInfo* P) { 7381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return P; 7391734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor } 7401734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor static inline clang::IdentifierInfo *getFromVoidPointer(void *P) { 7411734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor return static_cast<clang::IdentifierInfo*>(P); 7421734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor } 7431734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor enum { NumLowBitsAvailable = 1 }; 7441734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor}; 7451734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor 7461734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregortemplate<> 7471734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorclass PointerLikeTypeTraits<const clang::IdentifierInfo*> { 7481734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorpublic: 7491734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor static inline const void *getAsVoidPointer(const clang::IdentifierInfo* P) { 7501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return P; 7511734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor } 7521734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor static inline const clang::IdentifierInfo *getFromVoidPointer(const void *P) { 7531734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor return static_cast<const clang::IdentifierInfo*>(P); 7541734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor } 7551734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor enum { NumLowBitsAvailable = 1 }; 7561734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor}; 7571734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor 7582e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor} // end namespace llvm 7595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif 760