IdentifierTable.h revision 8af2c16571f3aade6d47ce81fa3857d01d375719
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" 2272b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek#include "llvm/ADT/OwningPtr.h" 2393a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek#include "llvm/Bitcode/SerializationFwd.h" 245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <string> 259dc62f044a6ba21f503bd56607d94b32704e7945Chris Lattner#include <cassert> 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2785994260c41a54cab061a434ed378fc448333a4eChris Lattnernamespace llvm { 2885994260c41a54cab061a434ed378fc448333a4eChris Lattner template <typename T> struct DenseMapInfo; 2985994260c41a54cab061a434ed378fc448333a4eChris Lattner} 3029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang { 32ea684e699ea84e61711e279f5fa7a1b9f3d46bc2Cedric Venet class LangOptions; 337caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner class IdentifierInfo; 34ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek class IdentifierTable; 357caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner class SourceLocation; 362e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor class MultiKeywordSelector; // private class used by Selector 372e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor class DeclarationName; // AST class that stores declaration names 382e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor 397caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner /// IdentifierLocPair - A simple pair of identifier info and location. 407caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair; 417caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner 425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierInfo - One of these records is kept for each identifier that 445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is lexed. This contains information about whether the token was #define'd, 455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is a language keyword, or if it is a front-end token of some sort (e.g. a 465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// variable or function name). The preprocessor keeps this information in a 475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// set, and all tok::identifier tokens have a pointer to one of these. 485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierInfo { 498e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek // Note: DON'T make TokenID a 'tok::TokenKind'; MSVC will treat it as a 508e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek // signed char and TokenKinds > 127 won't be handled correctly. 518e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek unsigned TokenID : 8; // Front-end token ID or tok::identifier. 525142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor // Objective-C keyword ('protocol' in '@protocol') or builtin (__builtin_inf). 535142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor // First NUM_OBJC_KEYWORDS values are for Objective-C, the remaining values 545142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor // are for builtins. 555142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor unsigned ObjCOrBuiltinID :10; 564365a7e46822700357a272d839ee2656d9603d5aChris Lattner bool HasMacro : 1; // True if there is a #define for this. 575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsExtension : 1; // True if identifier is a lang extension. 585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsPoisoned : 1; // True if identifier is poisoned. 595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword. 606a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner bool NeedsHandleIdentifier : 1; // See "RecomputeNeedsHandleIdentifier". 6140b9b50b16e4728389bca78ded783d18d3adc1c9Ted Kremenek // 9 bits left in 32-bit word. 625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void *FETokenInfo; // Managed by the language front-end. 63ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek llvm::StringMapEntry<IdentifierInfo*> *Entry; 64ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek 655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IdentifierInfo(const IdentifierInfo&); // NONCOPYABLE. 664365a7e46822700357a272d839ee2656d9603d5aChris Lattner void operator=(const IdentifierInfo&); // NONASSIGNABLE. 67ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek 68ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek friend class IdentifierTable; 69ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek 705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic: 71ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek IdentifierInfo(); 725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 73ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek 7492e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner /// isStr - Return true if this is the identifier for the specified string. 7592e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner /// This is intended to be used for string literals only: II->isStr("foo"). 7692e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner template <std::size_t StrLen> 7792e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner bool isStr(const char (&Str)[StrLen]) const { 7892e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner return getLength() == StrLen-1 && !memcmp(getName(), Str, StrLen-1); 79845222ccd992282bf74b2fca53e7c3b84a81c098Chris Lattner } 80845222ccd992282bf74b2fca53e7c3b84a81c098Chris Lattner 813f128ad2691d299b96663da85a9e069c4081ea7cSteve Naroff /// getName - Return the actual string for this identifier. The returned 823f128ad2691d299b96663da85a9e069c4081ea7cSteve Naroff /// string is properly null terminated. 835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 84ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek const char *getName() const { 85ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek if (Entry) return Entry->getKeyData(); 867e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // FIXME: This is gross. It would be best not to embed specific details 877e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // of the PTH file format here. 88ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek // The 'this' pointer really points to a 89ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek // std::pair<IdentifierInfo, const char*>, where internal pointer 90ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek // points to the external string data. 917e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek return ((std::pair<IdentifierInfo, const char*>*) this)->second; 921f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner } 931f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner 941f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner /// getLength - Efficiently return the length of this identifier info. 951f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner /// 961f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner unsigned getLength() const { 97ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek if (Entry) return Entry->getKeyLength(); 987e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // FIXME: This is gross. It would be best not to embed specific details 997e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // of the PTH file format here. 100ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek // The 'this' pointer really points to a 101ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek // std::pair<IdentifierInfo, const char*>, where internal pointer 102ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek // points to the external string data. 1037e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek const char* p = ((std::pair<IdentifierInfo, const char*>*) this)->second-2; 1047e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek return (((unsigned) p[0]) 1057e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek | (((unsigned) p[1]) << 8)) - 1; 1065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1089c46de446d18f4a28446cb798d4131bd05515699Chris Lattner /// hasMacroDefinition - Return true if this identifier is #defined to some 1099c46de446d18f4a28446cb798d4131bd05515699Chris Lattner /// other value. 1109c46de446d18f4a28446cb798d4131bd05515699Chris Lattner bool hasMacroDefinition() const { 1119c46de446d18f4a28446cb798d4131bd05515699Chris Lattner return HasMacro; 1129c46de446d18f4a28446cb798d4131bd05515699Chris Lattner } 1136a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void setHasMacroDefinition(bool Val) { 1146a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (HasMacro == Val) return; 1156a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner 1166a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner HasMacro = Val; 1176a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (Val) 1186a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 1; 1196a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner else 1206a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner RecomputeNeedsHandleIdentifier(); 1216a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 1225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// get/setTokenID - If this is a source-language token (e.g. 'for'), this API 1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// can be used to cause the lexer to map identifiers to source-language 1255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// tokens. 1268e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; } 127863c486fcb6162495a94fddf7ac8409de2638995Chris Lattner void setTokenID(tok::TokenKind ID) { TokenID = ID; } 1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getPPKeywordID - Return the preprocessor keyword ID for this identifier. 1306d9a3e648d6bf6b347174152f191bd1377528f8cChris Lattner /// For example, "define" will return tok::pp_define. 131387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner tok::PPKeywordKind getPPKeywordID() const; 1325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getObjCKeywordID - Return the Objective-C keyword ID for the this 1345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// identifier. For example, 'class' will return tok::objc_class if ObjC is 1355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// enabled. 136ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek tok::ObjCKeywordKind getObjCKeywordID() const { 1375142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor if (ObjCOrBuiltinID < tok::NUM_OBJC_KEYWORDS) 1385142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor return tok::ObjCKeywordKind(ObjCOrBuiltinID); 1395142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor else 1405142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor return tok::objc_not_keyword; 141ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek } 1425142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; } 1435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getBuiltinID - Return a value indicating whether this is a builtin 1455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// function. 0 is not-built-in. 1 is builtin-for-some-nonprimary-target. 1465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 2+ are specific builtin functions. 1475142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor unsigned getBuiltinID() const { 1485142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS) 1495142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS; 1505142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor else 1515142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor return 0; 1525142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor } 1535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setBuiltinID(unsigned ID) { 1545142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor ObjCOrBuiltinID = ID + tok::NUM_OBJC_KEYWORDS; 155bf8cb361038c71a76f8ffa0f9986cebc43732e87Argyrios Kyrtzidis assert(ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS) == ID 1565142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor && "ID too large for field!"); 1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// get/setExtension - Initialize information about whether or not this 1605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// language token is an extension. This controls extension warnings, and is 1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// only valid if a custom token ID is set. 1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isExtensionToken() const { return IsExtension; } 1636a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void setIsExtensionToken(bool Val) { 1646a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner IsExtension = Val; 1656a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (Val) 1666a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 1; 1676a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner else 1686a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner RecomputeNeedsHandleIdentifier(); 1696a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// setIsPoisoned - Mark this identifier as poisoned. After poisoning, the 1725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// Preprocessor will emit an error every time this token is used. 1736a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void setIsPoisoned(bool Value = true) { 1746a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner IsPoisoned = Value; 1756a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (Value) 1766a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 1; 1776a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner else 1786a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner RecomputeNeedsHandleIdentifier(); 1796a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// isPoisoned - Return true if this token has been poisoned. 1825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isPoisoned() const { return IsPoisoned; } 1835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether 1855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// this identifier is a C++ alternate representation of an operator. 1866a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void setIsCPlusPlusOperatorKeyword(bool Val = true) { 1876a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner IsCPPOperatorKeyword = Val; 1886a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (Val) 1896a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 1; 1906a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner else 1916a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner RecomputeNeedsHandleIdentifier(); 1926a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 1935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; } 1945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getFETokenInfo/setFETokenInfo - The language front-end is allowed to 1965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// associate arbitrary metadata with this token. 1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer template<typename T> 1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); } 1995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setFETokenInfo(void *T) { FETokenInfo = T; } 2006a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner 2016a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// isHandleIdentifierCase - Return true if the Preprocessor::HandleIdentifier 2026a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// must be called on a token of this identifier. If this returns false, we 2036a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// know that HandleIdentifier will not affect the token. 2046a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner bool isHandleIdentifierCase() const { return NeedsHandleIdentifier; } 20593a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek 20693a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek /// Emit - Serialize this IdentifierInfo to a bitstream. 20793a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek void Emit(llvm::Serializer& S) const; 20893a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek 20993a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek /// Read - Deserialize an IdentifierInfo object from a bitstream. 21093a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek void Read(llvm::Deserializer& D); 2116a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner 2126a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattnerprivate: 2136a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// RecomputeNeedsHandleIdentifier - The Preprocessor::HandleIdentifier does 2146a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// several special (but rare) things to identifiers of various sorts. For 2156a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// example, it changes the "for" keyword token from tok::identifier to 2166a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// tok::for. 2176a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// 2186a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// This method is very tied to the definition of HandleIdentifier. Any 2196a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// change to it should be reflected here. 2206a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void RecomputeNeedsHandleIdentifier() { 2216a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 2226a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() | 223863c486fcb6162495a94fddf7ac8409de2638995Chris Lattner isExtensionToken()); 2246a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 2255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 2265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 22772b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek/// IdentifierInfoLookup - An abstract class used by IdentifierTable that 22872b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek/// provides an interface for for performing lookups from strings 22972b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek/// (const char *) to IdentiferInfo objects. 23072b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenekclass IdentifierInfoLookup { 23172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenekpublic: 23272b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek virtual ~IdentifierInfoLookup(); 23372b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek 23472b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek /// get - Return the identifier token info for the specified named identifier. 23572b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek /// Unlike the version in IdentifierTable, this returns a pointer instead 23672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek /// of a reference. If the pointer is NULL then the IdentifierInfo cannot 23772b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek /// be found. 23872b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek virtual IdentifierInfo* get(const char *NameStart, const char *NameEnd) = 0; 23972b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek}; 24072b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek 2415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierTable - This table implements an efficient mapping from strings to 2425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierInfo nodes. It has no other purpose, but this is an 2435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// extremely performance-critical piece of the code, as each occurrance of 2445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// every identifier goes through here when lexed. 2455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierTable { 2465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Shark shows that using MallocAllocator is *much* slower than using this 2475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // BumpPtrAllocator! 248ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek typedef llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator> HashTableTy; 2495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer HashTableTy HashTable; 25072b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek 25172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek IdentifierInfoLookup* ExternalLookup; 2521cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 2535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic: 2545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// IdentifierTable ctor - Create the identifier table, populating it with 2555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// info about the language keywords for the language specified by LangOpts. 25672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek IdentifierTable(const LangOptions &LangOpts, 25772b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek IdentifierInfoLookup* externalLookup = 0); 25872b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek 25972b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek llvm::BumpPtrAllocator& getAllocator() { 26072b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek return HashTable.getAllocator(); 26172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek } 2625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// get - Return the identifier token info for the specified named identifier. 2645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 2655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IdentifierInfo &get(const char *NameStart, const char *NameEnd) { 266ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek llvm::StringMapEntry<IdentifierInfo*> &Entry = 267a3824c6348794788094f8afa44dc1d2cf67ba440Chris Lattner HashTable.GetOrCreateValue(NameStart, NameEnd); 268ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek 269ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek IdentifierInfo *II = Entry.getValue(); 270d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar if (II) return *II; 271ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek 272d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // No entry; if we have an external lookup, look there first. 273d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar if (ExternalLookup) { 274d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar II = ExternalLookup->get(NameStart, NameEnd); 275d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar if (II) { 276d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // Cache in the StringMap for subsequent lookups. 277d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar Entry.setValue(II); 278d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar return *II; 279ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek } 280d42ffbd22fc7eb61321f6a88173ee424991f01c6Ted Kremenek } 281ccb9bac3adb35a2dc78c1737e7b2dc6537a16393Daniel Dunbar 282d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // Lookups failed, make a new IdentifierInfo. 283d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar void *Mem = getAllocator().Allocate<IdentifierInfo>(); 284d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar II = new (Mem) IdentifierInfo(); 285d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar Entry.setValue(II); 286d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar 287d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // Make sure getName() knows how to find the IdentifierInfo 288d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // contents. 289d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar II->Entry = &Entry; 290d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar 291ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek return *II; 2925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IdentifierInfo &get(const char *Name) { 2955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return get(Name, Name+strlen(Name)); 2965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IdentifierInfo &get(const std::string &Name) { 2985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Don't use c_str() here: no need to be null terminated. 2995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *NameBytes = &Name[0]; 3005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return get(NameBytes, NameBytes+Name.size()); 3015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 3021cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 303ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenekprivate: 3045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer typedef HashTableTy::const_iterator iterator; 3055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer typedef HashTableTy::const_iterator const_iterator; 3065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer iterator begin() const { return HashTable.begin(); } 3085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer iterator end() const { return HashTable.end(); } 309ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenekpublic: 3105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 311c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek unsigned size() const { return HashTable.size(); } 312c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek 3135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// PrintStats - Print some statistics to stderr that indicate how well the 3145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// hashing is doing. 3155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void PrintStats() const; 316bfa82c4c23ce96fdcf357a8f7ef70a9b71b69144Ted Kremenek 3175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void AddKeywords(const LangOptions &LangOpts); 318c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek 31993a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek /// Emit - Serialize this IdentifierTable to a bitstream. This should 32093a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek /// be called AFTER objects that externally reference the identifiers in the 32193a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek /// table have been serialized. This is because only the identifiers that 32293a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek /// are actually referenced are serialized. 32393a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek void Emit(llvm::Serializer& S) const; 32493a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek 3250f84c0059cec39fd1c73ac05bc2864dca664e7f4Ted Kremenek /// Create - Deserialize an IdentifierTable from a bitstream. 326bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek static IdentifierTable* CreateAndRegister(llvm::Deserializer& D); 32793a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek 328c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenekprivate: 329c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek /// This ctor is not intended to be used by anyone except for object 330c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek /// serialization. 33193a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek IdentifierTable(); 3325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 3335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 33429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// Selector - This smart pointer class efficiently represents Objective-C 33529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// method names. This class will either point to an IdentifierInfo or a 33629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// MultiKeywordSelector (which is private). This enables us to optimize 337dee8ecc93825062eb441bfeb7a338d3f2c5ea3f0Nico Weber/// selectors that take no arguments and selectors that take 1 argument, which 33829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// accounts for 78% of all selectors in Cocoa.h. 339bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroffclass Selector { 3408af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek friend class DiagnosticInfo; 3418af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek 342bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff enum IdentifierInfoFlag { 3430e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner // MultiKeywordSelector = 0. 344bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff ZeroArg = 0x1, 345bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff OneArg = 0x2, 346bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff ArgFlags = ZeroArg|OneArg 347bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff }; 348bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff uintptr_t InfoPtr; // a pointer to the MultiKeywordSelector or IdentifierInfo. 349bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff 350bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff Selector(IdentifierInfo *II, unsigned nArgs) { 351bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff InfoPtr = reinterpret_cast<uintptr_t>(II); 3520e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo"); 3530e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner assert(nArgs < 2 && "nArgs not equal to 0/1"); 3540e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner InfoPtr |= nArgs+1; 355bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 356bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff Selector(MultiKeywordSelector *SI) { 357bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff InfoPtr = reinterpret_cast<uintptr_t>(SI); 3580e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo"); 359bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 360bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek Selector(uintptr_t V) : InfoPtr(V) {} 361c65b8a3e1f8da6117a2b9ba57afe8b7a2ec887ccTed Kremenek 362bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff IdentifierInfo *getAsIdentifierInfo() const { 3630e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner if (getIdentifierInfoFlag()) 364bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags); 365bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return 0; 366bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 367bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff unsigned getIdentifierInfoFlag() const { 368bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return InfoPtr & ArgFlags; 369bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 3708af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek 3718af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenekpublic: 3728af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek friend class SelectorTable; // only the SelectorTable can create these 3738af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek friend class DeclarationName; // and the AST's DeclarationName. 3748af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek 3758af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek /// The default ctor should only be used when creating data structures that 3768af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek /// will contain selectors. 3778af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek Selector() : InfoPtr(0) {} 3788af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek 379bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff /// operator==/!= - Indicate whether the specified selectors are identical. 38097b7f26a92d87e514530a5b652460190ce48c974Ted Kremenek bool operator==(Selector RHS) const { 381bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return InfoPtr == RHS.InfoPtr; 382bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 38397b7f26a92d87e514530a5b652460190ce48c974Ted Kremenek bool operator!=(Selector RHS) const { 384bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return InfoPtr != RHS.InfoPtr; 385bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 386bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff void *getAsOpaquePtr() const { 387bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return reinterpret_cast<void*>(InfoPtr); 388bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 389bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff // Predicates to identify the selector type. 390bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff bool isKeywordSelector() const { 391bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return getIdentifierInfoFlag() != ZeroArg; 392bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 393bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff bool isUnarySelector() const { 394bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return getIdentifierInfoFlag() == ZeroArg; 395bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 3965b6b72f53ad164497cf62484b60cdbb4361f1978Steve Naroff unsigned getNumArgs() const; 397f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const; 3985b6b72f53ad164497cf62484b60cdbb4361f1978Steve Naroff 399077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner /// getAsString - Derive the full selector name (e.g. "foo:bar:") and return 400077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner /// it as an std::string. 401077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner std::string getAsString() const; 40285994260c41a54cab061a434ed378fc448333a4eChris Lattner 40385994260c41a54cab061a434ed378fc448333a4eChris Lattner static Selector getEmptyMarker() { 40485994260c41a54cab061a434ed378fc448333a4eChris Lattner return Selector(uintptr_t(-1)); 40585994260c41a54cab061a434ed378fc448333a4eChris Lattner } 40685994260c41a54cab061a434ed378fc448333a4eChris Lattner static Selector getTombstoneMarker() { 40785994260c41a54cab061a434ed378fc448333a4eChris Lattner return Selector(uintptr_t(-2)); 40885994260c41a54cab061a434ed378fc448333a4eChris Lattner } 409bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek 410bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek // Emit - Emit a selector to bitcode. 411bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek void Emit(llvm::Serializer& S) const; 412bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek 413bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek // ReadVal - Read a selector from bitcode. 414bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek static Selector ReadVal(llvm::Deserializer& D); 415bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff}; 416bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff 41729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// SelectorTable - This table allows us to fully hide how we implement 41829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// multi-keyword caching. 41929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffclass SelectorTable { 4205f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner void *Impl; // Actually a SelectorTableImpl 42129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff SelectorTable(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT 42229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff void operator=(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT 42329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffpublic: 42429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff SelectorTable(); 42529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff ~SelectorTable(); 42629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 427ff38491c18b060526d754765b952f4a497a89416Chris Lattner /// getSelector - This can create any sort of selector. NumArgs indicates 428ff38491c18b060526d754765b952f4a497a89416Chris Lattner /// whether this is a no argument selector "foo", a single argument selector 429ff38491c18b060526d754765b952f4a497a89416Chris Lattner /// "foo:" or multi-argument "foo:bar:". 430ff38491c18b060526d754765b952f4a497a89416Chris Lattner Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV); 431ff38491c18b060526d754765b952f4a497a89416Chris Lattner 432ff38491c18b060526d754765b952f4a497a89416Chris Lattner Selector getUnarySelector(IdentifierInfo *ID) { 433ff38491c18b060526d754765b952f4a497a89416Chris Lattner return Selector(ID, 1); 434ff38491c18b060526d754765b952f4a497a89416Chris Lattner } 435ff38491c18b060526d754765b952f4a497a89416Chris Lattner Selector getNullarySelector(IdentifierInfo *ID) { 436ff38491c18b060526d754765b952f4a497a89416Chris Lattner return Selector(ID, 0); 437ff38491c18b060526d754765b952f4a497a89416Chris Lattner } 43861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 43961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff /// constructSetterName - Return the setter name for the given 44061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff /// identifier, i.e. "set" + Name where the initial character of Name 44161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff /// has been capitalized. 442fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff static Selector constructSetterName(IdentifierTable &Idents, 443fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff SelectorTable &SelTable, 444fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff const IdentifierInfo *Name) { 44561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff llvm::SmallString<100> SelectorName; 44661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff SelectorName = "set"; 44761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff SelectorName.append(Name->getName(), Name->getName()+Name->getLength()); 44861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff SelectorName[3] = toupper(SelectorName[3]); 449fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff IdentifierInfo *SetterName = 450fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff &Idents.get(&SelectorName[0], &SelectorName[SelectorName.size()]); 451fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff return SelTable.getUnarySelector(SetterName); 45261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff } 45361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 454bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek // Emit - Emit a SelectorTable to bitcode. 455bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek void Emit(llvm::Serializer& S) const; 456bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek 457bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek // Create - Reconstitute a SelectorTable from bitcode. 458bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek static SelectorTable* CreateAndRegister(llvm::Deserializer& D); 45929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff}; 46029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 461e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// DeclarationNameExtra - Common base of the MultiKeywordSelector, 462e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// CXXSpecialName, and CXXOperatorIdName classes, all of which are 463e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// private classes that describe different kinds of names. 4642e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorclass DeclarationNameExtra { 4652e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorpublic: 4662e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// ExtraKind - The kind of "extra" information stored in the 4672e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// DeclarationName. See @c ExtraKindOrNumArgs for an explanation of 4682e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// how these enumerator values are used. 4692e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor enum ExtraKind { 4702e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor CXXConstructor = 0, 4712e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor CXXDestructor, 4722e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor CXXConversionFunction, 473e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 474e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor CXXOperator##Name, 475e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor#include "clang/Basic/OperatorKinds.def" 4762a3009a432bdcec59e6383d7b2b17494d6f91649Douglas Gregor CXXUsingDirective, 4772e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor NUM_EXTRA_KINDS 4782e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor }; 4795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 480e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor /// ExtraKindOrNumArgs - Either the kind of C++ special name or 481e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor /// operator-id (if the value is one of the CXX* enumerators of 482e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor /// ExtraKind), in which case the DeclarationNameExtra is also a 483e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor /// CXXSpecialName (for CXXConstructor, CXXDestructor, or 4842a3009a432bdcec59e6383d7b2b17494d6f91649Douglas Gregor /// CXXConversionFunction) or CXXOperatorIdName, it may be also 4852a3009a432bdcec59e6383d7b2b17494d6f91649Douglas Gregor /// name common to C++ using-directives (CXXUsingDirective), otherwise 4862a3009a432bdcec59e6383d7b2b17494d6f91649Douglas Gregor /// it is NUM_EXTRA_KINDS+NumArgs, where NumArgs is the number of 4872e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// arguments in the Objective-C selector, in which case the 4882e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// DeclarationNameExtra is also a MultiKeywordSelector. 4892e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor unsigned ExtraKindOrNumArgs; 4902e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}; 4912e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor 4922e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor} // end namespace clang 4934365a7e46822700357a272d839ee2656d9603d5aChris Lattner 4942e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregornamespace llvm { 4954365a7e46822700357a272d839ee2656d9603d5aChris Lattner/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and 4964365a7e46822700357a272d839ee2656d9603d5aChris Lattner/// DenseSets. 49785994260c41a54cab061a434ed378fc448333a4eChris Lattnertemplate <> 49885994260c41a54cab061a434ed378fc448333a4eChris Lattnerstruct DenseMapInfo<clang::Selector> { 49985994260c41a54cab061a434ed378fc448333a4eChris Lattner static inline clang::Selector getEmptyKey() { 50085994260c41a54cab061a434ed378fc448333a4eChris Lattner return clang::Selector::getEmptyMarker(); 50185994260c41a54cab061a434ed378fc448333a4eChris Lattner } 50285994260c41a54cab061a434ed378fc448333a4eChris Lattner static inline clang::Selector getTombstoneKey() { 50385994260c41a54cab061a434ed378fc448333a4eChris Lattner return clang::Selector::getTombstoneMarker(); 50485994260c41a54cab061a434ed378fc448333a4eChris Lattner } 50585994260c41a54cab061a434ed378fc448333a4eChris Lattner 50685994260c41a54cab061a434ed378fc448333a4eChris Lattner static unsigned getHashValue(clang::Selector S); 50785994260c41a54cab061a434ed378fc448333a4eChris Lattner 50885994260c41a54cab061a434ed378fc448333a4eChris Lattner static bool isEqual(clang::Selector LHS, clang::Selector RHS) { 50985994260c41a54cab061a434ed378fc448333a4eChris Lattner return LHS == RHS; 51085994260c41a54cab061a434ed378fc448333a4eChris Lattner } 51185994260c41a54cab061a434ed378fc448333a4eChris Lattner 51285994260c41a54cab061a434ed378fc448333a4eChris Lattner static bool isPod() { return true; } 51385994260c41a54cab061a434ed378fc448333a4eChris Lattner}; 51485994260c41a54cab061a434ed378fc448333a4eChris Lattner 5152e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor} // end namespace llvm 5165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif 517