IdentifierTable.h revision 6488292f5e204fed99bb43ab23b8342ddc03ce89
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 <string> 261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#include <cassert> 275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2885994260c41a54cab061a434ed378fc448333a4eChris Lattnernamespace llvm { 2985994260c41a54cab061a434ed378fc448333a4eChris Lattner template <typename T> struct DenseMapInfo; 3085994260c41a54cab061a434ed378fc448333a4eChris Lattner} 3129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang { 33ea684e699ea84e61711e279f5fa7a1b9f3d46bc2Cedric Venet class LangOptions; 347caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner class IdentifierInfo; 35ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek class IdentifierTable; 367caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner class SourceLocation; 372e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor class MultiKeywordSelector; // private class used by Selector 382e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor class DeclarationName; // AST class that stores declaration names 392e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor 407caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner /// IdentifierLocPair - A simple pair of identifier info and location. 417caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair; 421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierInfo - One of these records is kept for each identifier that 455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is lexed. This contains information about whether the token was #define'd, 465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is a language keyword, or if it is a front-end token of some sort (e.g. a 475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// variable or function name). The preprocessor keeps this information in a 481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// set, and all tok::identifier tokens have a pointer to one of these. 495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierInfo { 508e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek // Note: DON'T make TokenID a 'tok::TokenKind'; MSVC will treat it as a 518e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek // signed char and TokenKinds > 127 won't be handled correctly. 521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump unsigned TokenID : 8; // Front-end token ID or tok::identifier. 535142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor // Objective-C keyword ('protocol' in '@protocol') or builtin (__builtin_inf). 545142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor // First NUM_OBJC_KEYWORDS values are for Objective-C, the remaining values 555142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor // are for builtins. 561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump unsigned ObjCOrBuiltinID :10; 574365a7e46822700357a272d839ee2656d9603d5aChris Lattner bool HasMacro : 1; // True if there is a #define for this. 585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsExtension : 1; // True if identifier is a lang extension. 595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsPoisoned : 1; // True if identifier is poisoned. 605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword. 616a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner bool NeedsHandleIdentifier : 1; // See "RecomputeNeedsHandleIdentifier". 6240b9b50b16e4728389bca78ded783d18d3adc1c9Ted Kremenek // 9 bits left in 32-bit word. 635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void *FETokenInfo; // Managed by the language front-end. 64ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek llvm::StringMapEntry<IdentifierInfo*> *Entry; 651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IdentifierInfo(const IdentifierInfo&); // NONCOPYABLE. 674365a7e46822700357a272d839ee2656d9603d5aChris Lattner void operator=(const IdentifierInfo&); // NONASSIGNABLE. 68ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek 691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump friend class IdentifierTable; 70ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek 715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic: 72ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek IdentifierInfo(); 735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7592e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner /// isStr - Return true if this is the identifier for the specified string. 7692e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner /// This is intended to be used for string literals only: II->isStr("foo"). 7792e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner template <std::size_t StrLen> 7892e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner bool isStr(const char (&Str)[StrLen]) const { 797fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar return getLength() == StrLen-1 && !memcmp(getNameStart(), Str, StrLen-1); 80845222ccd992282bf74b2fca53e7c3b84a81c098Chris Lattner } 811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 827fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar /// getNameStart - Return the beginning of the actual string for this 837fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar /// identifier. The returned string is properly null terminated. 845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 857fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar const char *getNameStart() const { 86ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek if (Entry) return Entry->getKeyData(); 877e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // FIXME: This is gross. It would be best not to embed specific details 887e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // of the PTH file format here. 891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // The 'this' pointer really points to a 90ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek // std::pair<IdentifierInfo, const char*>, where internal pointer 91ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek // points to the external string data. 927e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek return ((std::pair<IdentifierInfo, const char*>*) this)->second; 931f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner } 941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 951f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner /// getLength - Efficiently return the length of this identifier info. 961f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner /// 971f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner unsigned getLength() const { 98ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek if (Entry) return Entry->getKeyLength(); 997e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // FIXME: This is gross. It would be best not to embed specific details 1007e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // of the PTH file format here. 1011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // The 'this' pointer really points to a 102ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek // std::pair<IdentifierInfo, const char*>, where internal pointer 103ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek // points to the external string data. 1047e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek const char* p = ((std::pair<IdentifierInfo, const char*>*) this)->second-2; 1057fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar return (((unsigned) p[0]) | (((unsigned) p[1]) << 8)) - 1; 1067fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar } 1077fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar 10801eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar /// getName - Return the actual identifier string. 10901eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar llvm::StringRef getName() const { 1107fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar return llvm::StringRef(getNameStart(), getLength()); 1115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1139c46de446d18f4a28446cb798d4131bd05515699Chris Lattner /// hasMacroDefinition - Return true if this identifier is #defined to some 1149c46de446d18f4a28446cb798d4131bd05515699Chris Lattner /// other value. 1159c46de446d18f4a28446cb798d4131bd05515699Chris Lattner bool hasMacroDefinition() const { 1169c46de446d18f4a28446cb798d4131bd05515699Chris Lattner return HasMacro; 1179c46de446d18f4a28446cb798d4131bd05515699Chris Lattner } 1186a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void setHasMacroDefinition(bool Val) { 1196a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (HasMacro == Val) return; 1201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1216a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner HasMacro = Val; 1226a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (Val) 1236a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 1; 1246a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner else 1256a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner RecomputeNeedsHandleIdentifier(); 1266a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 1271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// get/setTokenID - If this is a source-language token (e.g. 'for'), this API 1295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// can be used to cause the lexer to map identifiers to source-language 1305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// tokens. 1318e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; } 132863c486fcb6162495a94fddf7ac8409de2638995Chris Lattner void setTokenID(tok::TokenKind ID) { TokenID = ID; } 1331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getPPKeywordID - Return the preprocessor keyword ID for this identifier. 1356d9a3e648d6bf6b347174152f191bd1377528f8cChris Lattner /// For example, "define" will return tok::pp_define. 136387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner tok::PPKeywordKind getPPKeywordID() const; 1371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getObjCKeywordID - Return the Objective-C keyword ID for the this 1395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// identifier. For example, 'class' will return tok::objc_class if ObjC is 1405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// enabled. 141ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek tok::ObjCKeywordKind getObjCKeywordID() const { 1421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (ObjCOrBuiltinID < tok::NUM_OBJC_KEYWORDS) 1435142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor return tok::ObjCKeywordKind(ObjCOrBuiltinID); 1445142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor else 1455142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor return tok::objc_not_keyword; 146ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek } 1475142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; } 1483251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor 1495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getBuiltinID - Return a value indicating whether this is a builtin 1505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// function. 0 is not-built-in. 1 is builtin-for-some-nonprimary-target. 1515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 2+ are specific builtin functions. 1521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump unsigned getBuiltinID() const { 1535142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS) 1541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS; 1555142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor else 1565142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor return 0; 1575142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor } 1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setBuiltinID(unsigned ID) { 1595142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor ObjCOrBuiltinID = ID + tok::NUM_OBJC_KEYWORDS; 1601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump assert(ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS) == ID 1615142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor && "ID too large for field!"); 1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1633251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor 1643251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor unsigned getObjCOrBuiltinID() const { return ObjCOrBuiltinID; } 1653251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor void setObjCOrBuiltinID(unsigned ID) { ObjCOrBuiltinID = ID; } 1663251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor 1675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// get/setExtension - Initialize information about whether or not this 1685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// language token is an extension. This controls extension warnings, and is 1695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// only valid if a custom token ID is set. 1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isExtensionToken() const { return IsExtension; } 1716a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void setIsExtensionToken(bool Val) { 1726a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner IsExtension = Val; 1736a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (Val) 1746a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 1; 1756a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner else 1766a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner RecomputeNeedsHandleIdentifier(); 1776a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 1781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// setIsPoisoned - Mark this identifier as poisoned. After poisoning, the 1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// Preprocessor will emit an error every time this token is used. 1816a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void setIsPoisoned(bool Value = true) { 1826a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner IsPoisoned = Value; 1836a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (Value) 1846a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 1; 1856a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner else 1866a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner RecomputeNeedsHandleIdentifier(); 1876a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 1881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// isPoisoned - Return true if this token has been poisoned. 1905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isPoisoned() const { return IsPoisoned; } 1911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether 1935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// this identifier is a C++ alternate representation of an operator. 1946a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void setIsCPlusPlusOperatorKeyword(bool Val = true) { 1956a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner IsCPPOperatorKeyword = Val; 1966a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (Val) 1976a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 1; 1986a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner else 1996a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner RecomputeNeedsHandleIdentifier(); 2006a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 2015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; } 2025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getFETokenInfo/setFETokenInfo - The language front-end is allowed to 2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// associate arbitrary metadata with this token. 2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer template<typename T> 2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); } 2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setFETokenInfo(void *T) { FETokenInfo = T; } 2086a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner 2096a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// isHandleIdentifierCase - Return true if the Preprocessor::HandleIdentifier 2106a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// must be called on a token of this identifier. If this returns false, we 2116a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// know that HandleIdentifier will not affect the token. 2126a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner bool isHandleIdentifierCase() const { return NeedsHandleIdentifier; } 2131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2146a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattnerprivate: 2156a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// RecomputeNeedsHandleIdentifier - The Preprocessor::HandleIdentifier does 2166a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// several special (but rare) things to identifiers of various sorts. For 2176a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// example, it changes the "for" keyword token from tok::identifier to 2186a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// tok::for. 2196a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// 2206a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// This method is very tied to the definition of HandleIdentifier. Any 2216a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// change to it should be reflected here. 2226a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void RecomputeNeedsHandleIdentifier() { 2236a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 2246a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() | 225863c486fcb6162495a94fddf7ac8409de2638995Chris Lattner isExtensionToken()); 2266a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 2275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 2285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 22972b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek/// IdentifierInfoLookup - An abstract class used by IdentifierTable that 230668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor/// provides an interface for performing lookups from strings 23172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek/// (const char *) to IdentiferInfo objects. 23272b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenekclass IdentifierInfoLookup { 23372b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenekpublic: 23472b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek virtual ~IdentifierInfoLookup(); 2351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 23672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek /// get - Return the identifier token info for the specified named identifier. 23772b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek /// Unlike the version in IdentifierTable, this returns a pointer instead 23872b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek /// of a reference. If the pointer is NULL then the IdentifierInfo cannot 23972b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek /// be found. 240700030ebddb987936d4fee14d9412821d96e4840Kovarththanan Rajaratnam virtual IdentifierInfo* get(llvm::StringRef Name) = 0; 2411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}; 2428c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 2438c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// \brief An abstract class used to resolve numerical identifier 2448c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// references (meaningful only to some external source) into 2458c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// IdentifierInfo pointers. 2468c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorclass ExternalIdentifierLookup { 2478c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorpublic: 2488c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor virtual ~ExternalIdentifierLookup(); 2498c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 2508c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor /// \brief Return the identifier associated with the given ID number. 2518c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor /// 2528c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor /// The ID 0 is associated with the NULL identifier. 2538c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor virtual IdentifierInfo *GetIdentifier(unsigned ID) = 0; 2548c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor}; 2558c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 2565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierTable - This table implements an efficient mapping from strings to 2575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierInfo nodes. It has no other purpose, but this is an 2585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// extremely performance-critical piece of the code, as each occurrance of 2595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// every identifier goes through here when lexed. 2605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierTable { 2615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Shark shows that using MallocAllocator is *much* slower than using this 2625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // BumpPtrAllocator! 263ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek typedef llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator> HashTableTy; 2645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer HashTableTy HashTable; 2651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 26672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek IdentifierInfoLookup* ExternalLookup; 2671cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 2685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic: 2695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// IdentifierTable ctor - Create the identifier table, populating it with 2705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// info about the language keywords for the language specified by LangOpts. 27172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek IdentifierTable(const LangOptions &LangOpts, 27272b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek IdentifierInfoLookup* externalLookup = 0); 2731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 274668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor /// \brief Set the external identifier lookup mechanism. 275668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor void setExternalIdentifierLookup(IdentifierInfoLookup *IILookup) { 276668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor ExternalLookup = IILookup; 277668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor } 278668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor 27972b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek llvm::BumpPtrAllocator& getAllocator() { 28072b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek return HashTable.getAllocator(); 28172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek } 2821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// get - Return the identifier token info for the specified named identifier. 2845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 2856488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam IdentifierInfo &get(llvm::StringRef Name) { 286ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek llvm::StringMapEntry<IdentifierInfo*> &Entry = 2876488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam HashTable.GetOrCreateValue(Name); 2881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 289ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek IdentifierInfo *II = Entry.getValue(); 290d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar if (II) return *II; 2911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 292d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // No entry; if we have an external lookup, look there first. 293d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar if (ExternalLookup) { 2946488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam II = ExternalLookup->get(Name); 295d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar if (II) { 296d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // Cache in the StringMap for subsequent lookups. 297d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar Entry.setValue(II); 298d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar return *II; 299ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek } 300d42ffbd22fc7eb61321f6a88173ee424991f01c6Ted Kremenek } 301ccb9bac3adb35a2dc78c1737e7b2dc6537a16393Daniel Dunbar 302d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // Lookups failed, make a new IdentifierInfo. 303d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar void *Mem = getAllocator().Allocate<IdentifierInfo>(); 304d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar II = new (Mem) IdentifierInfo(); 305d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar Entry.setValue(II); 306d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar 307d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // Make sure getName() knows how to find the IdentifierInfo 308d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // contents. 309d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar II->Entry = &Entry; 310d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar 311ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek return *II; 3125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 3131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3146488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam IdentifierInfo &get(const char *NameStart, const char *NameEnd) { 3156488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam return get(llvm::StringRef(NameStart, NameEnd-NameStart)); 316811f4267aa1ebd727c31594b8ed94048e2c10ad6Kovarththanan Rajaratnam } 317811f4267aa1ebd727c31594b8ed94048e2c10ad6Kovarththanan Rajaratnam 318811f4267aa1ebd727c31594b8ed94048e2c10ad6Kovarththanan Rajaratnam IdentifierInfo &get(const char *Name, size_t NameLen) { 319811f4267aa1ebd727c31594b8ed94048e2c10ad6Kovarththanan Rajaratnam return get(llvm::StringRef(Name, NameLen)); 320811f4267aa1ebd727c31594b8ed94048e2c10ad6Kovarththanan Rajaratnam } 321811f4267aa1ebd727c31594b8ed94048e2c10ad6Kovarththanan Rajaratnam 3225f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor /// \brief Creates a new IdentifierInfo from the given string. 3235f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor /// 3245f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor /// This is a lower-level version of get() that requires that this 3255f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor /// identifier not be known previously and that does not consult an 3265f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor /// external source for identifiers. In particular, external 3275f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor /// identifier sources can use this routine to build IdentifierInfo 3285f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor /// nodes and then introduce additional information about those 3295f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor /// identifiers. 3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump IdentifierInfo &CreateIdentifierInfo(const char *NameStart, 3315f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor const char *NameEnd) { 3325f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor llvm::StringMapEntry<IdentifierInfo*> &Entry = 3335f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor HashTable.GetOrCreateValue(NameStart, NameEnd); 3341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3355f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor IdentifierInfo *II = Entry.getValue(); 3365f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor assert(!II && "IdentifierInfo already exists"); 3371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3385f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor // Lookups failed, make a new IdentifierInfo. 3395f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor void *Mem = getAllocator().Allocate<IdentifierInfo>(); 3405f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor II = new (Mem) IdentifierInfo(); 3415f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor Entry.setValue(II); 3425f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor 3435f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor // Make sure getName() knows how to find the IdentifierInfo 3445f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor // contents. 3455f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor II->Entry = &Entry; 3465f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor 3475f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor return *II; 3485f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor } 34983885f7e3bf68d271e1e96726931814b836353a3Daniel Dunbar IdentifierInfo &CreateIdentifierInfo(llvm::StringRef Name) { 35083885f7e3bf68d271e1e96726931814b836353a3Daniel Dunbar return CreateIdentifierInfo(Name.begin(), Name.end()); 35183885f7e3bf68d271e1e96726931814b836353a3Daniel Dunbar } 3525f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor 3535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer typedef HashTableTy::const_iterator iterator; 3545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer typedef HashTableTy::const_iterator const_iterator; 3551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer iterator begin() const { return HashTable.begin(); } 3575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer iterator end() const { return HashTable.end(); } 358c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek unsigned size() const { return HashTable.size(); } 3591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// PrintStats - Print some statistics to stderr that indicate how well the 3615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// hashing is doing. 3625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void PrintStats() const; 3631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void AddKeywords(const LangOptions &LangOpts); 3655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 3665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 36729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// Selector - This smart pointer class efficiently represents Objective-C 36829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// method names. This class will either point to an IdentifierInfo or a 36929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// MultiKeywordSelector (which is private). This enables us to optimize 3701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// selectors that take no arguments and selectors that take 1 argument, which 37129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// accounts for 78% of all selectors in Cocoa.h. 372bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroffclass Selector { 3738af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek friend class DiagnosticInfo; 3741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 375bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff enum IdentifierInfoFlag { 3760e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner // MultiKeywordSelector = 0. 377bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff ZeroArg = 0x1, 378bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff OneArg = 0x2, 379bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff ArgFlags = ZeroArg|OneArg 380bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff }; 381bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff uintptr_t InfoPtr; // a pointer to the MultiKeywordSelector or IdentifierInfo. 3821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 383bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff Selector(IdentifierInfo *II, unsigned nArgs) { 384bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff InfoPtr = reinterpret_cast<uintptr_t>(II); 3850e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo"); 3860e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner assert(nArgs < 2 && "nArgs not equal to 0/1"); 3870e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner InfoPtr |= nArgs+1; 388bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 389bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff Selector(MultiKeywordSelector *SI) { 390bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff InfoPtr = reinterpret_cast<uintptr_t>(SI); 3910e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo"); 392bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 3931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 394bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff IdentifierInfo *getAsIdentifierInfo() const { 3950e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner if (getIdentifierInfoFlag()) 396bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags); 397bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return 0; 398bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 399bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff unsigned getIdentifierInfoFlag() const { 400bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return InfoPtr & ArgFlags; 401bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 4028af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek 4038af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenekpublic: 4048af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek friend class SelectorTable; // only the SelectorTable can create these 4058af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek friend class DeclarationName; // and the AST's DeclarationName. 4068af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek 4078af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek /// The default ctor should only be used when creating data structures that 4088af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek /// will contain selectors. 4098af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek Selector() : InfoPtr(0) {} 41090cd1bb1baac2a0221f3642de0cbea3244b116e5Steve Naroff Selector(uintptr_t V) : InfoPtr(V) {} 4118af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek 412bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff /// operator==/!= - Indicate whether the specified selectors are identical. 41397b7f26a92d87e514530a5b652460190ce48c974Ted Kremenek bool operator==(Selector RHS) const { 414bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return InfoPtr == RHS.InfoPtr; 415bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 41697b7f26a92d87e514530a5b652460190ce48c974Ted Kremenek bool operator!=(Selector RHS) const { 417bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return InfoPtr != RHS.InfoPtr; 418bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 419bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff void *getAsOpaquePtr() const { 420bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return reinterpret_cast<void*>(InfoPtr); 421bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 422405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor 423405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor /// \brief Determine whether this is the empty selector. 424405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor bool isNull() const { return InfoPtr == 0; } 425405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor 426bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff // Predicates to identify the selector type. 4271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bool isKeywordSelector() const { 4281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return getIdentifierInfoFlag() != ZeroArg; 429bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 4301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bool isUnarySelector() const { 431bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return getIdentifierInfoFlag() == ZeroArg; 432bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 4335b6b72f53ad164497cf62484b60cdbb4361f1978Steve Naroff unsigned getNumArgs() const; 434f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const; 4351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 436077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner /// getAsString - Derive the full selector name (e.g. "foo:bar:") and return 437077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner /// it as an std::string. 438077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner std::string getAsString() const; 4391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 44085994260c41a54cab061a434ed378fc448333a4eChris Lattner static Selector getEmptyMarker() { 44185994260c41a54cab061a434ed378fc448333a4eChris Lattner return Selector(uintptr_t(-1)); 44285994260c41a54cab061a434ed378fc448333a4eChris Lattner } 44385994260c41a54cab061a434ed378fc448333a4eChris Lattner static Selector getTombstoneMarker() { 44485994260c41a54cab061a434ed378fc448333a4eChris Lattner return Selector(uintptr_t(-2)); 44585994260c41a54cab061a434ed378fc448333a4eChris Lattner } 446bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff}; 447bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff 44829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// SelectorTable - This table allows us to fully hide how we implement 44929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// multi-keyword caching. 45029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffclass SelectorTable { 4515f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner void *Impl; // Actually a SelectorTableImpl 45229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff SelectorTable(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT 45329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff void operator=(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT 45429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffpublic: 45529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff SelectorTable(); 45629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff ~SelectorTable(); 45729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 458ff38491c18b060526d754765b952f4a497a89416Chris Lattner /// getSelector - This can create any sort of selector. NumArgs indicates 459ff38491c18b060526d754765b952f4a497a89416Chris Lattner /// whether this is a no argument selector "foo", a single argument selector 460ff38491c18b060526d754765b952f4a497a89416Chris Lattner /// "foo:" or multi-argument "foo:bar:". 461ff38491c18b060526d754765b952f4a497a89416Chris Lattner Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV); 4621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 463ff38491c18b060526d754765b952f4a497a89416Chris Lattner Selector getUnarySelector(IdentifierInfo *ID) { 464ff38491c18b060526d754765b952f4a497a89416Chris Lattner return Selector(ID, 1); 465ff38491c18b060526d754765b952f4a497a89416Chris Lattner } 466ff38491c18b060526d754765b952f4a497a89416Chris Lattner Selector getNullarySelector(IdentifierInfo *ID) { 467ff38491c18b060526d754765b952f4a497a89416Chris Lattner return Selector(ID, 0); 468ff38491c18b060526d754765b952f4a497a89416Chris Lattner } 46961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 47061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff /// constructSetterName - Return the setter name for the given 47161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff /// identifier, i.e. "set" + Name where the initial character of Name 47261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff /// has been capitalized. 473fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff static Selector constructSetterName(IdentifierTable &Idents, 474fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff SelectorTable &SelTable, 475fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff const IdentifierInfo *Name) { 47661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff llvm::SmallString<100> SelectorName; 47761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff SelectorName = "set"; 47801eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar SelectorName += Name->getName(); 47961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff SelectorName[3] = toupper(SelectorName[3]); 4802781deb126663ca1bd412044a1e66577585987b3Kovarththanan Rajaratnam IdentifierInfo *SetterName = &Idents.get(SelectorName); 481fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff return SelTable.getUnarySelector(SetterName); 48261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff } 48329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff}; 48429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 485e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// DeclarationNameExtra - Common base of the MultiKeywordSelector, 486e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// CXXSpecialName, and CXXOperatorIdName classes, all of which are 487e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// private classes that describe different kinds of names. 4882e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorclass DeclarationNameExtra { 4892e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorpublic: 4902e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// ExtraKind - The kind of "extra" information stored in the 4912e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// DeclarationName. See @c ExtraKindOrNumArgs for an explanation of 4922e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// how these enumerator values are used. 4932e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor enum ExtraKind { 4942e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor CXXConstructor = 0, 4952e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor CXXDestructor, 4962e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor CXXConversionFunction, 497e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 498e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor CXXOperator##Name, 499e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor#include "clang/Basic/OperatorKinds.def" 5003e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt CXXLiteralOperator, 5012a3009a432bdcec59e6383d7b2b17494d6f91649Douglas Gregor CXXUsingDirective, 5022e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor NUM_EXTRA_KINDS 5032e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor }; 5045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 505e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor /// ExtraKindOrNumArgs - Either the kind of C++ special name or 506e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor /// operator-id (if the value is one of the CXX* enumerators of 507e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor /// ExtraKind), in which case the DeclarationNameExtra is also a 5083e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt /// CXXSpecialName, (for CXXConstructor, CXXDestructor, or 5093e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt /// CXXConversionFunction) CXXOperatorIdName, or CXXLiteralOperatorName, 5103e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt /// it may be also name common to C++ using-directives (CXXUsingDirective), 5113e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt /// otherwise it is NUM_EXTRA_KINDS+NumArgs, where NumArgs is the number of 5122e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// arguments in the Objective-C selector, in which case the 5132e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// DeclarationNameExtra is also a MultiKeywordSelector. 5142e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor unsigned ExtraKindOrNumArgs; 5152e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}; 5162e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor 5172e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor} // end namespace clang 5184365a7e46822700357a272d839ee2656d9603d5aChris Lattner 5192e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregornamespace llvm { 5204365a7e46822700357a272d839ee2656d9603d5aChris Lattner/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and 5214365a7e46822700357a272d839ee2656d9603d5aChris Lattner/// DenseSets. 52285994260c41a54cab061a434ed378fc448333a4eChris Lattnertemplate <> 52385994260c41a54cab061a434ed378fc448333a4eChris Lattnerstruct DenseMapInfo<clang::Selector> { 52485994260c41a54cab061a434ed378fc448333a4eChris Lattner static inline clang::Selector getEmptyKey() { 52585994260c41a54cab061a434ed378fc448333a4eChris Lattner return clang::Selector::getEmptyMarker(); 52685994260c41a54cab061a434ed378fc448333a4eChris Lattner } 52785994260c41a54cab061a434ed378fc448333a4eChris Lattner static inline clang::Selector getTombstoneKey() { 5281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return clang::Selector::getTombstoneMarker(); 52985994260c41a54cab061a434ed378fc448333a4eChris Lattner } 5301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 53185994260c41a54cab061a434ed378fc448333a4eChris Lattner static unsigned getHashValue(clang::Selector S); 5321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 53385994260c41a54cab061a434ed378fc448333a4eChris Lattner static bool isEqual(clang::Selector LHS, clang::Selector RHS) { 53485994260c41a54cab061a434ed378fc448333a4eChris Lattner return LHS == RHS; 53585994260c41a54cab061a434ed378fc448333a4eChris Lattner } 53685994260c41a54cab061a434ed378fc448333a4eChris Lattner}; 537700030ebddb987936d4fee14d9412821d96e4840Kovarththanan Rajaratnam 53806159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnertemplate <> 53906159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnerstruct isPodLike<clang::Selector> { static const bool value = true; }; 54006159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner 54185994260c41a54cab061a434ed378fc448333a4eChris Lattner 5421734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor// Provide PointerLikeTypeTraits for IdentifierInfo pointers, which 5431734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor// are not guaranteed to be 8-byte aligned. 5441734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregortemplate<> 5451734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorclass PointerLikeTypeTraits<clang::IdentifierInfo*> { 5461734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorpublic: 5471734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor static inline void *getAsVoidPointer(clang::IdentifierInfo* P) { 5481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return P; 5491734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor } 5501734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor static inline clang::IdentifierInfo *getFromVoidPointer(void *P) { 5511734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor return static_cast<clang::IdentifierInfo*>(P); 5521734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor } 5531734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor enum { NumLowBitsAvailable = 1 }; 5541734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor}; 5551734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor 5561734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregortemplate<> 5571734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorclass PointerLikeTypeTraits<const clang::IdentifierInfo*> { 5581734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorpublic: 5591734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor static inline const void *getAsVoidPointer(const clang::IdentifierInfo* P) { 5601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return P; 5611734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor } 5621734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor static inline const clang::IdentifierInfo *getFromVoidPointer(const void *P) { 5631734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor return static_cast<const clang::IdentifierInfo*>(P); 5641734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor } 5651734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor enum { NumLowBitsAvailable = 1 }; 5661734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor}; 5671734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor 5682e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor} // end namespace llvm 5695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif 570