IdentifierTable.h revision 1cd1b1e987f5e2f060d7972b13d83239b36d77d6
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" 2168d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff#include "llvm/ADT/SmallString.h" 2293a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek#include "llvm/Bitcode/SerializationFwd.h" 235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <string> 249dc62f044a6ba21f503bd56607d94b32704e7945Chris Lattner#include <cassert> 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2685994260c41a54cab061a434ed378fc448333a4eChris Lattnernamespace llvm { 2785994260c41a54cab061a434ed378fc448333a4eChris Lattner template <typename T> struct DenseMapInfo; 2885994260c41a54cab061a434ed378fc448333a4eChris Lattner} 2929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang { 31b8128140956c6f8f0ab143818775a81f4b4aa477Chris Lattner struct LangOptions; 3285994260c41a54cab061a434ed378fc448333a4eChris Lattner class MultiKeywordSelector; // a private class used by Selector. 337caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner class IdentifierInfo; 347caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner class SourceLocation; 357caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner 367caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner /// IdentifierLocPair - A simple pair of identifier info and location. 377caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair; 387caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner 395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierInfo - One of these records is kept for each identifier that 415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is lexed. This contains information about whether the token was #define'd, 425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is a language keyword, or if it is a front-end token of some sort (e.g. a 435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// variable or function name). The preprocessor keeps this information in a 445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// set, and all tok::identifier tokens have a pointer to one of these. 455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierInfo { 468e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek // Note: DON'T make TokenID a 'tok::TokenKind'; MSVC will treat it as a 478e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek // signed char and TokenKinds > 127 won't be handled correctly. 488e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek unsigned TokenID : 8; // Front-end token ID or tok::identifier. 495142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor // Objective-C keyword ('protocol' in '@protocol') or builtin (__builtin_inf). 505142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor // First NUM_OBJC_KEYWORDS values are for Objective-C, the remaining values 515142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor // are for builtins. 525142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor unsigned ObjCOrBuiltinID :10; 531cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor unsigned OperatorID : 6; // C++ overloaded operator. 544365a7e46822700357a272d839ee2656d9603d5aChris Lattner bool HasMacro : 1; // True if there is a #define for this. 555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsExtension : 1; // True if identifier is a lang extension. 565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsPoisoned : 1; // True if identifier is poisoned. 575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword. 581cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor // 4 bits left in 32-bit word. 595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void *FETokenInfo; // Managed by the language front-end. 605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IdentifierInfo(const IdentifierInfo&); // NONCOPYABLE. 614365a7e46822700357a272d839ee2656d9603d5aChris Lattner void operator=(const IdentifierInfo&); // NONASSIGNABLE. 625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic: 635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IdentifierInfo(); 645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 653f128ad2691d299b96663da85a9e069c4081ea7cSteve Naroff /// getName - Return the actual string for this identifier. The returned 663f128ad2691d299b96663da85a9e069c4081ea7cSteve Naroff /// string is properly null terminated. 675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *getName() const { 691f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner // We know that this is embedded into a StringMapEntry, and it knows how to 701f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner // efficiently find the string. 711f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner return llvm::StringMapEntry<IdentifierInfo>:: 721f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner GetStringMapEntryFromValue(*this).getKeyData(); 731f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner } 741f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner 751f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner /// getLength - Efficiently return the length of this identifier info. 761f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner /// 771f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner unsigned getLength() const { 781f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner return llvm::StringMapEntry<IdentifierInfo>:: 791f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner GetStringMapEntryFromValue(*this).getKeyLength(); 805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 829c46de446d18f4a28446cb798d4131bd05515699Chris Lattner /// hasMacroDefinition - Return true if this identifier is #defined to some 839c46de446d18f4a28446cb798d4131bd05515699Chris Lattner /// other value. 849c46de446d18f4a28446cb798d4131bd05515699Chris Lattner bool hasMacroDefinition() const { 859c46de446d18f4a28446cb798d4131bd05515699Chris Lattner return HasMacro; 869c46de446d18f4a28446cb798d4131bd05515699Chris Lattner } 87cc1a875f94630e58d24a55577ffbf0e89b7da8c7Chris Lattner void setHasMacroDefinition(bool Val) { HasMacro = Val; } 885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// get/setTokenID - If this is a source-language token (e.g. 'for'), this API 905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// can be used to cause the lexer to map identifiers to source-language 915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// tokens. 928e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; } 935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setTokenID(tok::TokenKind ID) { TokenID = ID; } 945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getPPKeywordID - Return the preprocessor keyword ID for this identifier. 966d9a3e648d6bf6b347174152f191bd1377528f8cChris Lattner /// For example, "define" will return tok::pp_define. 97387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner tok::PPKeywordKind getPPKeywordID() const; 985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getObjCKeywordID - Return the Objective-C keyword ID for the this 1005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// identifier. For example, 'class' will return tok::objc_class if ObjC is 1015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// enabled. 102ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek tok::ObjCKeywordKind getObjCKeywordID() const { 1035142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor if (ObjCOrBuiltinID < tok::NUM_OBJC_KEYWORDS) 1045142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor return tok::ObjCKeywordKind(ObjCOrBuiltinID); 1055142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor else 1065142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor return tok::objc_not_keyword; 107ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek } 1085142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; } 1095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getBuiltinID - Return a value indicating whether this is a builtin 1115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// function. 0 is not-built-in. 1 is builtin-for-some-nonprimary-target. 1125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 2+ are specific builtin functions. 1135142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor unsigned getBuiltinID() const { 1145142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS) 1155142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS; 1165142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor else 1175142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor return 0; 1185142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor } 1195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setBuiltinID(unsigned ID) { 1205142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor ObjCOrBuiltinID = ID + tok::NUM_OBJC_KEYWORDS; 1215142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor assert(ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS == ID 1225142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor && "ID too large for field!"); 1235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1251cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor /// getOverloadedOperatorID - Get the C++ overloaded operator that 1261cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor /// corresponds to this identifier. 1271cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor OverloadedOperatorKind getOverloadedOperatorID() const { 1281cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor return OverloadedOperatorKind(OperatorID); 1291cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 1301cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor void setOverloadedOperatorID(OverloadedOperatorKind ID) { 1311cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor OperatorID = ID; 1321cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor assert(OperatorID == (unsigned)ID && "ID too large for field!"); 1331cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 1341cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 1355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// get/setExtension - Initialize information about whether or not this 1365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// language token is an extension. This controls extension warnings, and is 1375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// only valid if a custom token ID is set. 1385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isExtensionToken() const { return IsExtension; } 1395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setIsExtensionToken(bool Val) { IsExtension = Val; } 1405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// setIsPoisoned - Mark this identifier as poisoned. After poisoning, the 1425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// Preprocessor will emit an error every time this token is used. 1435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setIsPoisoned(bool Value = true) { IsPoisoned = Value; } 1445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// isPoisoned - Return true if this token has been poisoned. 1465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isPoisoned() const { return IsPoisoned; } 1475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether 1495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// this identifier is a C++ alternate representation of an operator. 150c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek void setIsCPlusPlusOperatorKeyword(bool Val = true) 1515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer { IsCPPOperatorKeyword = Val; } 1525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; } 1535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getFETokenInfo/setFETokenInfo - The language front-end is allowed to 1555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// associate arbitrary metadata with this token. 1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer template<typename T> 1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); } 1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setFETokenInfo(void *T) { FETokenInfo = T; } 15993a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek 16093a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek /// Emit - Serialize this IdentifierInfo to a bitstream. 16193a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek void Emit(llvm::Serializer& S) const; 16293a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek 16393a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek /// Read - Deserialize an IdentifierInfo object from a bitstream. 16493a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek void Read(llvm::Deserializer& D); 1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 1665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierTable - This table implements an efficient mapping from strings to 1685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierInfo nodes. It has no other purpose, but this is an 1695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// extremely performance-critical piece of the code, as each occurrance of 1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// every identifier goes through here when lexed. 1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierTable { 1725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Shark shows that using MallocAllocator is *much* slower than using this 1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // BumpPtrAllocator! 1745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer typedef llvm::StringMap<IdentifierInfo, llvm::BumpPtrAllocator> HashTableTy; 1755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer HashTableTy HashTable; 1761cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 1771cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor /// OverloadedOperators - Identifiers corresponding to each of the 1781cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor /// overloadable operators in C++. 1791cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor IdentifierInfo *OverloadedOperators[NUM_OVERLOADED_OPERATORS]; 1801cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 1815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic: 1825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// IdentifierTable ctor - Create the identifier table, populating it with 1835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// info about the language keywords for the language specified by LangOpts. 1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IdentifierTable(const LangOptions &LangOpts); 1855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// get - Return the identifier token info for the specified named identifier. 1875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 1885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IdentifierInfo &get(const char *NameStart, const char *NameEnd) { 1895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return HashTable.GetOrCreateValue(NameStart, NameEnd).getValue(); 1905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IdentifierInfo &get(const char *Name) { 1935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return get(Name, Name+strlen(Name)); 1945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IdentifierInfo &get(const std::string &Name) { 1965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Don't use c_str() here: no need to be null terminated. 1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *NameBytes = &Name[0]; 1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return get(NameBytes, NameBytes+Name.size()); 1995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2001cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 2011cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor /// getOverloadedOperator - Retrieve the identifier 2021cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor IdentifierInfo &getOverloadedOperator(OverloadedOperatorKind Op) { 2031cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor return *OverloadedOperators[Op]; 2041cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 2051cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer typedef HashTableTy::const_iterator iterator; 2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer typedef HashTableTy::const_iterator const_iterator; 2085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer iterator begin() const { return HashTable.begin(); } 2105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer iterator end() const { return HashTable.end(); } 2115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 212c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek unsigned size() const { return HashTable.size(); } 213c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek 2145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// PrintStats - Print some statistics to stderr that indicate how well the 2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// hashing is doing. 2165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void PrintStats() const; 217bfa82c4c23ce96fdcf357a8f7ef70a9b71b69144Ted Kremenek 2185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void AddKeywords(const LangOptions &LangOpts); 2191cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor void AddOverloadedOperators(); 220c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek 22193a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek /// Emit - Serialize this IdentifierTable to a bitstream. This should 22293a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek /// be called AFTER objects that externally reference the identifiers in the 22393a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek /// table have been serialized. This is because only the identifiers that 22493a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek /// are actually referenced are serialized. 22593a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek void Emit(llvm::Serializer& S) const; 22693a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek 2270f84c0059cec39fd1c73ac05bc2864dca664e7f4Ted Kremenek /// Create - Deserialize an IdentifierTable from a bitstream. 228bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek static IdentifierTable* CreateAndRegister(llvm::Deserializer& D); 22993a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek 230c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenekprivate: 231c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek /// This ctor is not intended to be used by anyone except for object 232c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek /// serialization. 23393a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek IdentifierTable(); 2345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 2355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 23629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// Selector - This smart pointer class efficiently represents Objective-C 23729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// method names. This class will either point to an IdentifierInfo or a 23829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// MultiKeywordSelector (which is private). This enables us to optimize 239dee8ecc93825062eb441bfeb7a338d3f2c5ea3f0Nico Weber/// selectors that take no arguments and selectors that take 1 argument, which 24029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// accounts for 78% of all selectors in Cocoa.h. 241bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroffclass Selector { 242bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff enum IdentifierInfoFlag { 2430e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner // MultiKeywordSelector = 0. 244bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff ZeroArg = 0x1, 245bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff OneArg = 0x2, 246bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff ArgFlags = ZeroArg|OneArg 247bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff }; 248bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff uintptr_t InfoPtr; // a pointer to the MultiKeywordSelector or IdentifierInfo. 249bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff 250bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff Selector(IdentifierInfo *II, unsigned nArgs) { 251bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff InfoPtr = reinterpret_cast<uintptr_t>(II); 2520e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo"); 2530e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner assert(nArgs < 2 && "nArgs not equal to 0/1"); 2540e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner InfoPtr |= nArgs+1; 255bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 256bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff Selector(MultiKeywordSelector *SI) { 257bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff InfoPtr = reinterpret_cast<uintptr_t>(SI); 2580e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo"); 259bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 260bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek Selector(uintptr_t V) : InfoPtr(V) {} 26129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffpublic: 26229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff friend class SelectorTable; // only the SelectorTable can create these. 263bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff 264c65b8a3e1f8da6117a2b9ba57afe8b7a2ec887ccTed Kremenek /// The default ctor should only be used when creating data structures that 265c65b8a3e1f8da6117a2b9ba57afe8b7a2ec887ccTed Kremenek /// will contain selectors. 266c65b8a3e1f8da6117a2b9ba57afe8b7a2ec887ccTed Kremenek Selector() : InfoPtr(0) {} 267c65b8a3e1f8da6117a2b9ba57afe8b7a2ec887ccTed Kremenek 268bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff IdentifierInfo *getAsIdentifierInfo() const { 2690e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner if (getIdentifierInfoFlag()) 270bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags); 271bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return 0; 272bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 273bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff unsigned getIdentifierInfoFlag() const { 274bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return InfoPtr & ArgFlags; 275bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 276bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff /// operator==/!= - Indicate whether the specified selectors are identical. 27797b7f26a92d87e514530a5b652460190ce48c974Ted Kremenek bool operator==(Selector RHS) const { 278bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return InfoPtr == RHS.InfoPtr; 279bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 28097b7f26a92d87e514530a5b652460190ce48c974Ted Kremenek bool operator!=(Selector RHS) const { 281bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return InfoPtr != RHS.InfoPtr; 282bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 283bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff void *getAsOpaquePtr() const { 284bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return reinterpret_cast<void*>(InfoPtr); 285bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 286bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff // Predicates to identify the selector type. 287bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff bool isKeywordSelector() const { 288bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return getIdentifierInfoFlag() != ZeroArg; 289bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 290bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff bool isUnarySelector() const { 291bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return getIdentifierInfoFlag() == ZeroArg; 292bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 2935b6b72f53ad164497cf62484b60cdbb4361f1978Steve Naroff unsigned getNumArgs() const; 294f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const; 2955b6b72f53ad164497cf62484b60cdbb4361f1978Steve Naroff 296f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner /// getName - Derive the full selector name (e.g. "foo:bar:") and return it. 297f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner /// 298f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner std::string getName() const; 29985994260c41a54cab061a434ed378fc448333a4eChris Lattner 30085994260c41a54cab061a434ed378fc448333a4eChris Lattner static Selector getEmptyMarker() { 30185994260c41a54cab061a434ed378fc448333a4eChris Lattner return Selector(uintptr_t(-1)); 30285994260c41a54cab061a434ed378fc448333a4eChris Lattner } 30385994260c41a54cab061a434ed378fc448333a4eChris Lattner static Selector getTombstoneMarker() { 30485994260c41a54cab061a434ed378fc448333a4eChris Lattner return Selector(uintptr_t(-2)); 30585994260c41a54cab061a434ed378fc448333a4eChris Lattner } 306bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek 307bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek // Emit - Emit a selector to bitcode. 308bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek void Emit(llvm::Serializer& S) const; 309bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek 310bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek // ReadVal - Read a selector from bitcode. 311bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek static Selector ReadVal(llvm::Deserializer& D); 312bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff}; 313bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff 31429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// SelectorTable - This table allows us to fully hide how we implement 31529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// multi-keyword caching. 31629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffclass SelectorTable { 31729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff void *Impl; // Actually a FoldingSet<MultiKeywordSelector>* 31829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff SelectorTable(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT 31929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff void operator=(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT 32029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffpublic: 32129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff SelectorTable(); 32229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff ~SelectorTable(); 32329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 324ff38491c18b060526d754765b952f4a497a89416Chris Lattner /// getSelector - This can create any sort of selector. NumArgs indicates 325ff38491c18b060526d754765b952f4a497a89416Chris Lattner /// whether this is a no argument selector "foo", a single argument selector 326ff38491c18b060526d754765b952f4a497a89416Chris Lattner /// "foo:" or multi-argument "foo:bar:". 327ff38491c18b060526d754765b952f4a497a89416Chris Lattner Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV); 328ff38491c18b060526d754765b952f4a497a89416Chris Lattner 329ff38491c18b060526d754765b952f4a497a89416Chris Lattner Selector getUnarySelector(IdentifierInfo *ID) { 330ff38491c18b060526d754765b952f4a497a89416Chris Lattner return Selector(ID, 1); 331ff38491c18b060526d754765b952f4a497a89416Chris Lattner } 332ff38491c18b060526d754765b952f4a497a89416Chris Lattner Selector getNullarySelector(IdentifierInfo *ID) { 333ff38491c18b060526d754765b952f4a497a89416Chris Lattner return Selector(ID, 0); 334ff38491c18b060526d754765b952f4a497a89416Chris Lattner } 335bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek 336bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek // Emit - Emit a SelectorTable to bitcode. 337bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek void Emit(llvm::Serializer& S) const; 338bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek 339bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek // Create - Reconstitute a SelectorTable from bitcode. 340bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek static SelectorTable* CreateAndRegister(llvm::Deserializer& D); 34129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff}; 34229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 3435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} // end namespace clang 3445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3454365a7e46822700357a272d839ee2656d9603d5aChris Lattner 3464365a7e46822700357a272d839ee2656d9603d5aChris Lattner/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and 3474365a7e46822700357a272d839ee2656d9603d5aChris Lattner/// DenseSets. 34885994260c41a54cab061a434ed378fc448333a4eChris Lattnernamespace llvm { 34985994260c41a54cab061a434ed378fc448333a4eChris Lattnertemplate <> 35085994260c41a54cab061a434ed378fc448333a4eChris Lattnerstruct DenseMapInfo<clang::Selector> { 35185994260c41a54cab061a434ed378fc448333a4eChris Lattner static inline clang::Selector getEmptyKey() { 35285994260c41a54cab061a434ed378fc448333a4eChris Lattner return clang::Selector::getEmptyMarker(); 35385994260c41a54cab061a434ed378fc448333a4eChris Lattner } 35485994260c41a54cab061a434ed378fc448333a4eChris Lattner static inline clang::Selector getTombstoneKey() { 35585994260c41a54cab061a434ed378fc448333a4eChris Lattner return clang::Selector::getTombstoneMarker(); 35685994260c41a54cab061a434ed378fc448333a4eChris Lattner } 35785994260c41a54cab061a434ed378fc448333a4eChris Lattner 35885994260c41a54cab061a434ed378fc448333a4eChris Lattner static unsigned getHashValue(clang::Selector S); 35985994260c41a54cab061a434ed378fc448333a4eChris Lattner 36085994260c41a54cab061a434ed378fc448333a4eChris Lattner static bool isEqual(clang::Selector LHS, clang::Selector RHS) { 36185994260c41a54cab061a434ed378fc448333a4eChris Lattner return LHS == RHS; 36285994260c41a54cab061a434ed378fc448333a4eChris Lattner } 36385994260c41a54cab061a434ed378fc448333a4eChris Lattner 36485994260c41a54cab061a434ed378fc448333a4eChris Lattner static bool isPod() { return true; } 36585994260c41a54cab061a434ed378fc448333a4eChris Lattner}; 36685994260c41a54cab061a434ed378fc448333a4eChris Lattner} // end namespace llvm 36785994260c41a54cab061a434ed378fc448333a4eChris Lattner 3685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif 369