15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- IdentifierTable.h - Hash table for identifier lookup ---*- C++ -*-===// 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// The LLVM Compiler Infrastructure 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 92f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// 102f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// \file 112f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// \brief Defines the clang::IdentifierInfo, clang::IdentifierTable, and 122f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// clang::Selector interfaces. 132f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// 145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 16c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H 17c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H 185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1930a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "clang/Basic/LLVM.h" 205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/TokenKinds.h" 215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/StringMap.h" 22700030ebddb987936d4fee14d9412821d96e4840Kovarththanan Rajaratnam#include "llvm/ADT/StringRef.h" 231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#include <cassert> 24403ba3522d1b1c97ae5fad81c1a2c4b3a754e1c1Nick Lewycky#include <string> 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2685994260c41a54cab061a434ed378fc448333a4eChris Lattnernamespace llvm { 2785994260c41a54cab061a434ed378fc448333a4eChris Lattner template <typename T> struct DenseMapInfo; 2885994260c41a54cab061a434ed378fc448333a4eChris Lattner} 2929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang { 31ea684e699ea84e61711e279f5fa7a1b9f3d46bc2Cedric Venet class LangOptions; 327caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner class IdentifierInfo; 33ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek class IdentifierTable; 347caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner class SourceLocation; 352e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor class MultiKeywordSelector; // private class used by Selector 362e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor class DeclarationName; // AST class that stores declaration names 372e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor 38af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// \brief A simple pair of identifier info and location. 397caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair; 401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 42af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// One of these records is kept for each identifier that 4355bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett/// is lexed. This contains information about whether the token was \#define'd, 445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is a language keyword, or if it is a front-end token of some sort (e.g. a 455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// variable or function name). The preprocessor keeps this information in a 461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// set, and all tok::identifier tokens have a pointer to one of these. 475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierInfo { 485cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor unsigned TokenID : 9; // Front-end token ID or tok::identifier. 495142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor // Objective-C keyword ('protocol' in '@protocol') or builtin (__builtin_inf). 505142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor // First NUM_OBJC_KEYWORDS values are for Objective-C, the remaining values 515142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor // are for builtins. 52c81ca9852806e75972bbb246fa916152e8fba541Ted Kremenek unsigned ObjCOrBuiltinID :11; 534365a7e46822700357a272d839ee2656d9603d5aChris Lattner bool HasMacro : 1; // True if there is a #define for this. 544d7e0ced7f16a04aabe2d8d91cbbb52fb1162810Alexander Kornienko bool HadMacro : 1; // True if there was a #define for this. 555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsExtension : 1; // True if identifier is a lang extension. 5698d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith bool IsCXX11CompatKeyword : 1; // True if identifier is a keyword in C++11. 575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsPoisoned : 1; // True if identifier is poisoned. 585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword. 596a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner bool NeedsHandleIdentifier : 1; // See "RecomputeNeedsHandleIdentifier". 60eee242ff426bf79149f221798966e58688383c1eDouglas Gregor bool IsFromAST : 1; // True if identifier was loaded (at least 61eee242ff426bf79149f221798966e58688383c1eDouglas Gregor // partially) from an AST file. 62eee242ff426bf79149f221798966e58688383c1eDouglas Gregor bool ChangedAfterLoad : 1; // True if identifier has changed from the 63eee242ff426bf79149f221798966e58688383c1eDouglas Gregor // definition loaded from an AST file. 64646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis bool RevertedTokenID : 1; // True if RevertTokenIDToIdentifier was 65646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis // called. 66eee242ff426bf79149f221798966e58688383c1eDouglas Gregor bool OutOfDate : 1; // True if there may be additional 67eee242ff426bf79149f221798966e58688383c1eDouglas Gregor // information about this identifier 68eee242ff426bf79149f221798966e58688383c1eDouglas Gregor // stored externally. 6955bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett bool IsModulesImport : 1; // True if this is the 'import' contextual 70c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor // keyword. 714d7e0ced7f16a04aabe2d8d91cbbb52fb1162810Alexander Kornienko // 32-bit word is filled. 724d7e0ced7f16a04aabe2d8d91cbbb52fb1162810Alexander Kornienko 735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void *FETokenInfo; // Managed by the language front-end. 74ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek llvm::StringMapEntry<IdentifierInfo*> *Entry; 751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 76be2fa7ebf01259b63dc52fe46c8d101c18e72269Craig Topper IdentifierInfo(const IdentifierInfo&) LLVM_DELETED_FUNCTION; 77be2fa7ebf01259b63dc52fe46c8d101c18e72269Craig Topper void operator=(const IdentifierInfo&) LLVM_DELETED_FUNCTION; 78ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek 791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump friend class IdentifierTable; 80295a2a617ac335f590e430ab7fcd98f8ce109251Douglas Gregor 815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic: 82ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek IdentifierInfo(); 835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8555bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// \brief Return true if this is the identifier for the specified string. 8655bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// 8792e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner /// This is intended to be used for string literals only: II->isStr("foo"). 8892e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner template <std::size_t StrLen> 8992e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner bool isStr(const char (&Str)[StrLen]) const { 907fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar return getLength() == StrLen-1 && !memcmp(getNameStart(), Str, StrLen-1); 91845222ccd992282bf74b2fca53e7c3b84a81c098Chris Lattner } 921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9355bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// \brief Return the beginning of the actual null-terminated string for this 9455bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// identifier. 955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 967fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar const char *getNameStart() const { 97ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek if (Entry) return Entry->getKeyData(); 987e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // FIXME: This is gross. It would be best not to embed specific details 997e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // of the PTH file format here. 1001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // 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. 10340844a8b5a89676fb61898d61ea4a7fa98eb9b6bGabor Greif typedef std::pair<IdentifierInfo, const char*> actualtype; 10440844a8b5a89676fb61898d61ea4a7fa98eb9b6bGabor Greif return ((const actualtype*) this)->second; 1051f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner } 1061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10755bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// \brief Efficiently return the length of this identifier info. 1081f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner /// 1091f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner unsigned getLength() const { 110ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek if (Entry) return Entry->getKeyLength(); 1117e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // FIXME: This is gross. It would be best not to embed specific details 1127e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // of the PTH file format here. 1131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // The 'this' pointer really points to a 114ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek // std::pair<IdentifierInfo, const char*>, where internal pointer 115ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek // points to the external string data. 11640844a8b5a89676fb61898d61ea4a7fa98eb9b6bGabor Greif typedef std::pair<IdentifierInfo, const char*> actualtype; 11740844a8b5a89676fb61898d61ea4a7fa98eb9b6bGabor Greif const char* p = ((const actualtype*) this)->second - 2; 1187fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar return (((unsigned) p[0]) | (((unsigned) p[1]) << 8)) - 1; 1197fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar } 1207fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar 12155bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// \brief Return the actual identifier string. 122686775deca8b8685eb90801495880e3abdd844c2Chris Lattner StringRef getName() const { 123686775deca8b8685eb90801495880e3abdd844c2Chris Lattner return StringRef(getNameStart(), getLength()); 1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12655bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// \brief Return true if this identifier is \#defined to some other value. 1279c46de446d18f4a28446cb798d4131bd05515699Chris Lattner bool hasMacroDefinition() const { 1289c46de446d18f4a28446cb798d4131bd05515699Chris Lattner return HasMacro; 1299c46de446d18f4a28446cb798d4131bd05515699Chris Lattner } 1306a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void setHasMacroDefinition(bool Val) { 1316a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (HasMacro == Val) return; 1321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1336a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner HasMacro = Val; 1344d7e0ced7f16a04aabe2d8d91cbbb52fb1162810Alexander Kornienko if (Val) { 1356a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 1; 1364d7e0ced7f16a04aabe2d8d91cbbb52fb1162810Alexander Kornienko HadMacro = true; 1374d7e0ced7f16a04aabe2d8d91cbbb52fb1162810Alexander Kornienko } else { 1386a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner RecomputeNeedsHandleIdentifier(); 1394d7e0ced7f16a04aabe2d8d91cbbb52fb1162810Alexander Kornienko } 1404d7e0ced7f16a04aabe2d8d91cbbb52fb1162810Alexander Kornienko } 1414d7e0ced7f16a04aabe2d8d91cbbb52fb1162810Alexander Kornienko /// \brief Returns true if this identifier was \#defined to some value at any 1424d7e0ced7f16a04aabe2d8d91cbbb52fb1162810Alexander Kornienko /// moment. In this case there should be an entry for the identifier in the 1434d7e0ced7f16a04aabe2d8d91cbbb52fb1162810Alexander Kornienko /// macro history table in Preprocessor. 1444d7e0ced7f16a04aabe2d8d91cbbb52fb1162810Alexander Kornienko bool hadMacroDefinition() const { 1454d7e0ced7f16a04aabe2d8d91cbbb52fb1162810Alexander Kornienko return HadMacro; 1466a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 1471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 148d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// If this is a source-language token (e.g. 'for'), this API 1495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// can be used to cause the lexer to map identifiers to source-language 1505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// tokens. 1518e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; } 152646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis 153646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis /// \brief True if RevertTokenIDToIdentifier() was called. 154646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis bool hasRevertedTokenIDToIdentifier() const { return RevertedTokenID; } 155646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis 156646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis /// \brief Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2 157f573084db5807f6003282bdf53ca9d58bab1ddc4Argyrios Kyrtzidis /// compatibility. 158f573084db5807f6003282bdf53ca9d58bab1ddc4Argyrios Kyrtzidis /// 159f573084db5807f6003282bdf53ca9d58bab1ddc4Argyrios Kyrtzidis /// TokenID is normally read-only but there are 2 instances where we revert it 160f573084db5807f6003282bdf53ca9d58bab1ddc4Argyrios Kyrtzidis /// to tok::identifier for libstdc++ 4.2. Keep track of when this happens 1613c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl /// using this method so we can inform serialization about it. 162646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis void RevertTokenIDToIdentifier() { 163646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis assert(TokenID != tok::identifier && "Already at tok::identifier"); 164646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis TokenID = tok::identifier; 165646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis RevertedTokenID = true; 166646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis } 1671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 16855bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// \brief Return the preprocessor keyword ID for this identifier. 16955bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// 1706d9a3e648d6bf6b347174152f191bd1377528f8cChris Lattner /// For example, "define" will return tok::pp_define. 171387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner tok::PPKeywordKind getPPKeywordID() const; 1721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17355bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// \brief Return the Objective-C keyword ID for the this identifier. 17455bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// 17555bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett /// For example, 'class' will return tok::objc_class if ObjC is enabled. 176ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek tok::ObjCKeywordKind getObjCKeywordID() const { 1771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (ObjCOrBuiltinID < tok::NUM_OBJC_KEYWORDS) 1785142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor return tok::ObjCKeywordKind(ObjCOrBuiltinID); 1795142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor else 1805142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor return tok::objc_not_keyword; 181ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek } 1825142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; } 1833251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor 184d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// \brief Return a value indicating whether this is a builtin function. 185d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// 186d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// 0 is not-built-in. 1 is builtin-for-some-nonprimary-target. 1875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 2+ are specific builtin functions. 1881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump unsigned getBuiltinID() const { 1895142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS) 1901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS; 1915142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor else 1925142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor return 0; 1935142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor } 1945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setBuiltinID(unsigned ID) { 1955142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor ObjCOrBuiltinID = ID + tok::NUM_OBJC_KEYWORDS; 1961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump assert(ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS) == ID 1975142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor && "ID too large for field!"); 1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1993251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor 2003251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor unsigned getObjCOrBuiltinID() const { return ObjCOrBuiltinID; } 2013251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor void setObjCOrBuiltinID(unsigned ID) { ObjCOrBuiltinID = ID; } 2023251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor 2035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// get/setExtension - Initialize information about whether or not this 2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// language token is an extension. This controls extension warnings, and is 2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// only valid if a custom token ID is set. 2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isExtensionToken() const { return IsExtension; } 2076a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void setIsExtensionToken(bool Val) { 2086a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner IsExtension = Val; 2096a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (Val) 2106a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 1; 2116a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner else 2126a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner RecomputeNeedsHandleIdentifier(); 2136a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 2141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 21598d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith /// is/setIsCXX11CompatKeyword - Initialize information about whether or not 21698d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith /// this language token is a keyword in C++11. This controls compatibility 21798d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith /// warnings, and is only true when not parsing C++11. Once a compatibility 21898d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith /// problem has been diagnosed with this keyword, the flag will be cleared. 21998d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith bool isCXX11CompatKeyword() const { return IsCXX11CompatKeyword; } 22098d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith void setIsCXX11CompatKeyword(bool Val) { 22198d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith IsCXX11CompatKeyword = Val; 22298d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith if (Val) 22398d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith NeedsHandleIdentifier = 1; 22498d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith else 22598d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith RecomputeNeedsHandleIdentifier(); 22698d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith } 22798d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith 2285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// setIsPoisoned - Mark this identifier as poisoned. After poisoning, the 2295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// Preprocessor will emit an error every time this token is used. 2306a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void setIsPoisoned(bool Value = true) { 2316a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner IsPoisoned = Value; 2326a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (Value) 2336a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 1; 2346a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner else 2356a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner RecomputeNeedsHandleIdentifier(); 2366a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 2371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 238d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// \brief Return true if this token has been poisoned. 2395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isPoisoned() const { return IsPoisoned; } 2401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether 2425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// this identifier is a C++ alternate representation of an operator. 2436a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void setIsCPlusPlusOperatorKeyword(bool Val = true) { 2446a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner IsCPPOperatorKeyword = Val; 2456a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner if (Val) 2466a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 1; 2476a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner else 2486a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner RecomputeNeedsHandleIdentifier(); 2496a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 2505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; } 2515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getFETokenInfo/setFETokenInfo - The language front-end is allowed to 2535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// associate arbitrary metadata with this token. 2545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer template<typename T> 2555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); } 2565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setFETokenInfo(void *T) { FETokenInfo = T; } 2576a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner 258d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// \brief Return true if the Preprocessor::HandleIdentifier must be called 259d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// on a token of this identifier. 260d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// 261d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// If this returns false, we know that HandleIdentifier will not affect 262d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// the token. 2636a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner bool isHandleIdentifierCase() const { return NeedsHandleIdentifier; } 2641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 265d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// \brief Return true if the identifier in its current state was loaded 2663c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl /// from an AST file. 2673c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl bool isFromAST() const { return IsFromAST; } 268ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl 269eee242ff426bf79149f221798966e58688383c1eDouglas Gregor void setIsFromAST() { IsFromAST = true; } 270eee242ff426bf79149f221798966e58688383c1eDouglas Gregor 271eee242ff426bf79149f221798966e58688383c1eDouglas Gregor /// \brief Determine whether this identifier has changed since it was loaded 272eee242ff426bf79149f221798966e58688383c1eDouglas Gregor /// from an AST file. 273eee242ff426bf79149f221798966e58688383c1eDouglas Gregor bool hasChangedSinceDeserialization() const { 274eee242ff426bf79149f221798966e58688383c1eDouglas Gregor return ChangedAfterLoad; 275eee242ff426bf79149f221798966e58688383c1eDouglas Gregor } 276eee242ff426bf79149f221798966e58688383c1eDouglas Gregor 277eee242ff426bf79149f221798966e58688383c1eDouglas Gregor /// \brief Note that this identifier has changed since it was loaded from 278eee242ff426bf79149f221798966e58688383c1eDouglas Gregor /// an AST file. 279eee242ff426bf79149f221798966e58688383c1eDouglas Gregor void setChangedSinceDeserialization() { 280eee242ff426bf79149f221798966e58688383c1eDouglas Gregor ChangedAfterLoad = true; 281eee242ff426bf79149f221798966e58688383c1eDouglas Gregor } 282ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl 283eee242ff426bf79149f221798966e58688383c1eDouglas Gregor /// \brief Determine whether the information for this identifier is out of 284eee242ff426bf79149f221798966e58688383c1eDouglas Gregor /// date with respect to the external source. 285eee242ff426bf79149f221798966e58688383c1eDouglas Gregor bool isOutOfDate() const { return OutOfDate; } 286eee242ff426bf79149f221798966e58688383c1eDouglas Gregor 287eee242ff426bf79149f221798966e58688383c1eDouglas Gregor /// \brief Set whether the information for this identifier is out of 288eee242ff426bf79149f221798966e58688383c1eDouglas Gregor /// date with respect to the external source. 289eee242ff426bf79149f221798966e58688383c1eDouglas Gregor void setOutOfDate(bool OOD) { 290eee242ff426bf79149f221798966e58688383c1eDouglas Gregor OutOfDate = OOD; 291eee242ff426bf79149f221798966e58688383c1eDouglas Gregor if (OOD) 292eee242ff426bf79149f221798966e58688383c1eDouglas Gregor NeedsHandleIdentifier = true; 293eee242ff426bf79149f221798966e58688383c1eDouglas Gregor else 294eee242ff426bf79149f221798966e58688383c1eDouglas Gregor RecomputeNeedsHandleIdentifier(); 295eee242ff426bf79149f221798966e58688383c1eDouglas Gregor } 296eee242ff426bf79149f221798966e58688383c1eDouglas Gregor 297d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// \brief Determine whether this is the contextual keyword \c import. 29832ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek bool isModulesImport() const { return IsModulesImport; } 299c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor 300d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// \brief Set whether this identifier is the contextual keyword \c import. 30132ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek void setModulesImport(bool I) { 30232ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek IsModulesImport = I; 303c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor if (I) 304c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor NeedsHandleIdentifier = true; 305c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor else 306c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor RecomputeNeedsHandleIdentifier(); 307c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor } 308c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor 3096a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattnerprivate: 310d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// The Preprocessor::HandleIdentifier does several special (but rare) 311d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// things to identifiers of various sorts. For example, it changes the 312d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// \c for keyword token from tok::identifier to tok::for. 3136a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// 3146a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// This method is very tied to the definition of HandleIdentifier. Any 3156a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner /// change to it should be reflected here. 3166a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner void RecomputeNeedsHandleIdentifier() { 3176a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = 3186a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() | 319eee242ff426bf79149f221798966e58688383c1eDouglas Gregor isExtensionToken() | isCXX11CompatKeyword() || isOutOfDate() || 32032ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek isModulesImport()); 3216a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner } 3225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 3235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 324d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett/// \brief An RAII object for [un]poisoning an identifier within a scope. 325d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett/// 326d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett/// \p II is allowed to be null, in which case objects of this type have 327d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett/// no effect. 32828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegleyclass PoisonIdentifierRAIIObject { 32928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley IdentifierInfo *const II; 33028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley const bool OldValue; 33128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegleypublic: 33228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley PoisonIdentifierRAIIObject(IdentifierInfo *II, bool NewValue) 33328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley : II(II), OldValue(II ? II->isPoisoned() : false) { 33428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley if(II) 33528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley II->setIsPoisoned(NewValue); 33628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley } 33728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley 33828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley ~PoisonIdentifierRAIIObject() { 33928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley if(II) 34028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley II->setIsPoisoned(OldValue); 34128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley } 34228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley}; 34328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley 34495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// \brief An iterator that walks over all of the known identifiers 34595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// in the lookup table. 34695f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// 34795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// Since this iterator uses an abstract interface via virtual 34895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// functions, it uses an object-oriented interface rather than the 34995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// more standard C++ STL iterator interface. In this OO-style 35095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// iteration, the single function \c Next() provides dereference, 35195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// advance, and end-of-sequence checking in a single 35295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// operation. Subclasses of this iterator type will provide the 35395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// actual functionality. 35495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregorclass IdentifierIterator { 35595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregorprivate: 356f56faa01936b9cf909623d7f06e3c2569ca4a78eDmitri Gribenko IdentifierIterator(const IdentifierIterator &) LLVM_DELETED_FUNCTION; 357f56faa01936b9cf909623d7f06e3c2569ca4a78eDmitri Gribenko void operator=(const IdentifierIterator &) LLVM_DELETED_FUNCTION; 35895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 35995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregorprotected: 36095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor IdentifierIterator() { } 36195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 36295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregorpublic: 36395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor virtual ~IdentifierIterator(); 36495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 36595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// \brief Retrieve the next string in the identifier table and 36695f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// advances the iterator for the following string. 36795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// 36895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// \returns The next string in the identifier table. If there is 369686775deca8b8685eb90801495880e3abdd844c2Chris Lattner /// no such string, returns an empty \c StringRef. 370686775deca8b8685eb90801495880e3abdd844c2Chris Lattner virtual StringRef Next() = 0; 37195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor}; 37295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 373d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett/// \brief Provides lookups to, and iteration over, IdentiferInfo objects. 37472b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenekclass IdentifierInfoLookup { 37572b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenekpublic: 37672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek virtual ~IdentifierInfoLookup(); 3771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 378d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// \brief Return the IdentifierInfo for the specified named identifier. 379d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// 380d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// Unlike the version in IdentifierTable, this returns a pointer instead 381d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// of a reference. If the pointer is null then the IdentifierInfo cannot 382d8e135876604c847d6e35be4d62a28e35cc776eeJames Dennett /// be found. 383686775deca8b8685eb90801495880e3abdd844c2Chris Lattner virtual IdentifierInfo* get(StringRef Name) = 0; 38495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 38595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// \brief Retrieve an iterator into the set of all identifiers 38695f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// known to this identifier lookup source. 38795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// 38895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// This routine provides access to all of the identifiers known to 38995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// the identifier lookup, allowing access to the contents of the 39095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// identifiers without introducing the overhead of constructing 39195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// IdentifierInfo objects for each. 39295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// 39395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// \returns A new iterator into the set of known identifiers. The 39495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// caller is responsible for deleting this iterator. 39587f9d81d0ab806dcf6ca50a0c068dcb2ba7f51b3Argyrios Kyrtzidis virtual IdentifierIterator *getIdentifiers(); 3961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}; 3978c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 3988c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// \brief An abstract class used to resolve numerical identifier 3998c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// references (meaningful only to some external source) into 4008c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// IdentifierInfo pointers. 4018c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorclass ExternalIdentifierLookup { 4028c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorpublic: 4038c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor virtual ~ExternalIdentifierLookup(); 4048c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 4058c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor /// \brief Return the identifier associated with the given ID number. 4068c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor /// 4078c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor /// The ID 0 is associated with the NULL identifier. 4088c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor virtual IdentifierInfo *GetIdentifier(unsigned ID) = 0; 4098c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor}; 4108c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 411af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// \brief Implements an efficient mapping from strings to IdentifierInfo nodes. 412af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// 413af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// This has no other purpose, but this is an extremely performance-critical 414af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// piece of the code, as each occurrence of every identifier goes through 415af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// here when lexed. 4165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierTable { 4175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Shark shows that using MallocAllocator is *much* slower than using this 4185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // BumpPtrAllocator! 419ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek typedef llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator> HashTableTy; 4205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer HashTableTy HashTable; 4211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 42272b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek IdentifierInfoLookup* ExternalLookup; 4231cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 4245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic: 425af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// \brief Create the identifier table, populating it with info about the 426af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// language keywords for the language specified by \p LangOpts. 42772b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek IdentifierTable(const LangOptions &LangOpts, 4286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines IdentifierInfoLookup* externalLookup = nullptr); 4291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 430668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor /// \brief Set the external identifier lookup mechanism. 431668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor void setExternalIdentifierLookup(IdentifierInfoLookup *IILookup) { 432668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor ExternalLookup = IILookup; 433668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor } 434668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor 43595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// \brief Retrieve the external identifier lookup object, if any. 43695f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor IdentifierInfoLookup *getExternalIdentifierLookup() const { 43795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor return ExternalLookup; 43895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor } 43995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 44072b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek llvm::BumpPtrAllocator& getAllocator() { 44172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek return HashTable.getAllocator(); 44272b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek } 4431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 444af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// \brief Return the identifier token info for the specified named 445af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// identifier. 446686775deca8b8685eb90801495880e3abdd844c2Chris Lattner IdentifierInfo &get(StringRef Name) { 447ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek llvm::StringMapEntry<IdentifierInfo*> &Entry = 4486488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam HashTable.GetOrCreateValue(Name); 4491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 450ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek IdentifierInfo *II = Entry.getValue(); 451d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar if (II) return *II; 4521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 453d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // No entry; if we have an external lookup, look there first. 454d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar if (ExternalLookup) { 4556488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam II = ExternalLookup->get(Name); 456d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar if (II) { 457d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // Cache in the StringMap for subsequent lookups. 458d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar Entry.setValue(II); 459d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar return *II; 460ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek } 461d42ffbd22fc7eb61321f6a88173ee424991f01c6Ted Kremenek } 462ccb9bac3adb35a2dc78c1737e7b2dc6537a16393Daniel Dunbar 463d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // Lookups failed, make a new IdentifierInfo. 464d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar void *Mem = getAllocator().Allocate<IdentifierInfo>(); 465d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar II = new (Mem) IdentifierInfo(); 466d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar Entry.setValue(II); 467d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar 468d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // Make sure getName() knows how to find the IdentifierInfo 469d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar // contents. 470d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar II->Entry = &Entry; 471d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar 472ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek return *II; 4735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 4741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 475686775deca8b8685eb90801495880e3abdd844c2Chris Lattner IdentifierInfo &get(StringRef Name, tok::TokenKind TokenCode) { 476646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis IdentifierInfo &II = get(Name); 477646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis II.TokenID = TokenCode; 478d648d373d6c14dccadd3bef7b560f6a7296f949ePeter Collingbourne assert(II.TokenID == (unsigned) TokenCode && "TokenCode too large"); 479646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis return II; 480646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis } 481646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis 482ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl /// \brief Gets an IdentifierInfo for the given name without consulting 483ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl /// external sources. 4845f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor /// 485ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl /// This is a version of get() meant for external sources that want to 486ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl /// introduce or modify an identifier. If they called get(), they would 487ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl /// likely end up in a recursion. 488686775deca8b8685eb90801495880e3abdd844c2Chris Lattner IdentifierInfo &getOwn(StringRef Name) { 4895f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor llvm::StringMapEntry<IdentifierInfo*> &Entry = 49065aa6885818d4b4eea2e5a9d12085b2398148662Jay Foad HashTable.GetOrCreateValue(Name); 4911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4925f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor IdentifierInfo *II = Entry.getValue(); 493ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl if (!II) { 4941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 495ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl // Lookups failed, make a new IdentifierInfo. 496ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl void *Mem = getAllocator().Allocate<IdentifierInfo>(); 497ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl II = new (Mem) IdentifierInfo(); 498ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl Entry.setValue(II); 4995f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor 500ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl // Make sure getName() knows how to find the IdentifierInfo 501ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl // contents. 502ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl II->Entry = &Entry; 503c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor 504c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor // If this is the 'import' contextual keyword, mark it as such. 505c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor if (Name.equals("import")) 50632ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek II->setModulesImport(true); 507ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl } 5085f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor 5095f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor return *II; 5105f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor } 5115f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor 5125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer typedef HashTableTy::const_iterator iterator; 5135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer typedef HashTableTy::const_iterator const_iterator; 5141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer iterator begin() const { return HashTable.begin(); } 5165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer iterator end() const { return HashTable.end(); } 517c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek unsigned size() const { return HashTable.size(); } 5181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 519af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// \brief Print some statistics to stderr that indicate how well the 5205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// hashing is doing. 5215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void PrintStats() const; 5221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void AddKeywords(const LangOptions &LangOpts); 5245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 5255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 526af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// \brief A family of Objective-C methods. 527af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// 528af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// These families have no inherent meaning in the language, but are 52985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// nonetheless central enough in the existing implementations to 53085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// merit direct AST support. While, in theory, arbitrary methods can 53185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// be considered to form families, we focus here on the methods 53285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// involving allocation and retain-count management, as these are the 53385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// most "core" and the most likely to be useful to diverse clients 53485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// without extra information. 53585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// 53685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// Both selectors and actual method declarations may be classified 53785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// into families. Method families may impose additional restrictions 53885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// beyond their selector name; for example, a method called '_init' 53985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// that returns void is not considered to be in the 'init' family 54085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// (but would be if it returned 'id'). It is also possible to 54185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// explicitly change or remove a method's family. Therefore the 54285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// method's family should be considered the single source of truth. 54385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCallenum ObjCMethodFamily { 54485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall /// \brief No particular method family. 54585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_None, 54685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 54785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall // Selectors in these families may have arbitrary arity, may be 54885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall // written with arbitrary leading underscores, and may have 54985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall // additional CamelCase "words" in their first selector chunk 55085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall // following the family name. 55185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_alloc, 55285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_copy, 55385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_init, 55485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_mutableCopy, 55585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_new, 55685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 55785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall // These families are singletons consisting only of the nullary 55885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall // selector with the given name. 55985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_autorelease, 56085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_dealloc, 56180cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber OMF_finalize, 56285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_release, 56385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall OMF_retain, 564926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor OMF_retainCount, 5659670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian OMF_self, 5669670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian 5679670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian // performSelector families 5689670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian OMF_performSelector 56985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall}; 57085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 57185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// Enough bits to store any enumerator in ObjCMethodFamily or 57285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// InvalidObjCMethodFamily. 57385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCallenum { ObjCMethodFamilyBitWidth = 4 }; 57485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 575af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// \brief An invalid value of ObjCMethodFamily. 57685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCallenum { InvalidObjCMethodFamily = (1 << ObjCMethodFamilyBitWidth) - 1 }; 57785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 5788d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian/// \brief A family of Objective-C methods. 5798d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian/// 5808d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian/// These are family of methods whose result type is initially 'id', but 5818d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian/// but are candidate for the result type to be changed to 'instancetype'. 5828d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanianenum ObjCInstanceTypeFamily { 5838d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian OIT_None, 5848d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian OIT_Array, 5858d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian OIT_Dictionary, 586a346eb1188419d3f1698092edfbd66890b74163cFariborz Jahanian OIT_Singleton, 5879fcbd5e55a8029a0ca8a5d64457278ec716a8705Fariborz Jahanian OIT_Init, 5889fcbd5e55a8029a0ca8a5d64457278ec716a8705Fariborz Jahanian OIT_ReturnsSelf 5898d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian}; 5908d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian 591af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// \brief Smart pointer class that efficiently represents Objective-C method 592af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// names. 593af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// 594af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// This class will either point to an IdentifierInfo or a 59529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// MultiKeywordSelector (which is private). This enables us to optimize 5961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// selectors that take no arguments and selectors that take 1 argument, which 59729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// accounts for 78% of all selectors in Cocoa.h. 598bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroffclass Selector { 59940847cfb58acc3cac7d68727df9455ac45f2e118David Blaikie friend class Diagnostic; 6001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 601bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff enum IdentifierInfoFlag { 60251603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor // Empty selector = 0. 603bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff ZeroArg = 0x1, 604bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff OneArg = 0x2, 60551603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor MultiArg = 0x3, 606bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff ArgFlags = ZeroArg|OneArg 607bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff }; 608bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff uintptr_t InfoPtr; // a pointer to the MultiKeywordSelector or IdentifierInfo. 6091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 610bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff Selector(IdentifierInfo *II, unsigned nArgs) { 611bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff InfoPtr = reinterpret_cast<uintptr_t>(II); 6120e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo"); 6130e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner assert(nArgs < 2 && "nArgs not equal to 0/1"); 6140e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner InfoPtr |= nArgs+1; 615bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 616bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff Selector(MultiKeywordSelector *SI) { 617bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff InfoPtr = reinterpret_cast<uintptr_t>(SI); 6180e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo"); 61951603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor InfoPtr |= MultiArg; 620bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 6211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 622bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff IdentifierInfo *getAsIdentifierInfo() const { 62351603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor if (getIdentifierInfoFlag() < MultiArg) 624bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags); 6256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 626bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 62751603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor MultiKeywordSelector *getMultiKeywordSelector() const { 62851603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor return reinterpret_cast<MultiKeywordSelector *>(InfoPtr & ~ArgFlags); 62951603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor } 63051603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor 631bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff unsigned getIdentifierInfoFlag() const { 632bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return InfoPtr & ArgFlags; 633bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 6348af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek 63585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall static ObjCMethodFamily getMethodFamilyImpl(Selector sel); 63685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 6378af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenekpublic: 6388af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek friend class SelectorTable; // only the SelectorTable can create these 6398af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek friend class DeclarationName; // and the AST's DeclarationName. 6408af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek 6418af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek /// The default ctor should only be used when creating data structures that 6428af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek /// will contain selectors. 6438af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek Selector() : InfoPtr(0) {} 64490cd1bb1baac2a0221f3642de0cbea3244b116e5Steve Naroff Selector(uintptr_t V) : InfoPtr(V) {} 6458af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek 646bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff /// operator==/!= - Indicate whether the specified selectors are identical. 64797b7f26a92d87e514530a5b652460190ce48c974Ted Kremenek bool operator==(Selector RHS) const { 648bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return InfoPtr == RHS.InfoPtr; 649bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 65097b7f26a92d87e514530a5b652460190ce48c974Ted Kremenek bool operator!=(Selector RHS) const { 651bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return InfoPtr != RHS.InfoPtr; 652bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 653bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff void *getAsOpaquePtr() const { 654bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return reinterpret_cast<void*>(InfoPtr); 655bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 656405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor 657405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor /// \brief Determine whether this is the empty selector. 658405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor bool isNull() const { return InfoPtr == 0; } 659405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor 660bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff // Predicates to identify the selector type. 6611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bool isKeywordSelector() const { 6621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return getIdentifierInfoFlag() != ZeroArg; 663bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 6641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bool isUnarySelector() const { 665bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff return getIdentifierInfoFlag() == ZeroArg; 666bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff } 6675b6b72f53ad164497cf62484b60cdbb4361f1978Steve Naroff unsigned getNumArgs() const; 668813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor 669813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor 670813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// \brief Retrieve the identifier at a given position in the selector. 671813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// 672813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// Note that the identifier pointer returned may be NULL. Clients that only 673813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// care about the text of the identifier string, and not the specific, 674813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// uniqued identifier pointer, should use \c getNameForSlot(), which returns 675813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// an empty string when the identifier pointer would be NULL. 676813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// 677813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// \param argIndex The index for which we want to retrieve the identifier. 678813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// This index shall be less than \c getNumArgs() unless this is a keyword 679813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// selector, in which case 0 is the only permissible value. 680813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// 681813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// \returns the uniqued identifier for this slot, or NULL if this slot has 682813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// no corresponding identifier. 683f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const; 684813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor 685813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// \brief Retrieve the name at a given position in the selector. 686813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// 687813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// \param argIndex The index for which we want to retrieve the name. 688813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// This index shall be less than \c getNumArgs() unless this is a keyword 689813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// selector, in which case 0 is the only permissible value. 690813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// 691813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// \returns the name for this slot, which may be the empty string if no 692813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor /// name was supplied. 693686775deca8b8685eb90801495880e3abdd844c2Chris Lattner StringRef getNameForSlot(unsigned argIndex) const; 694813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor 695af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// \brief Derive the full selector name (e.g. "foo:bar:") and return 696077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner /// it as an std::string. 697077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner std::string getAsString() const; 6981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 699651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \brief Prints the full selector name (e.g. "foo:bar:"). 700651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void print(llvm::raw_ostream &OS) const; 701651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 702af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// \brief Derive the conventional family of this method. 70385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall ObjCMethodFamily getMethodFamily() const { 70485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall return getMethodFamilyImpl(*this); 70585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall } 70685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 70785994260c41a54cab061a434ed378fc448333a4eChris Lattner static Selector getEmptyMarker() { 70885994260c41a54cab061a434ed378fc448333a4eChris Lattner return Selector(uintptr_t(-1)); 70985994260c41a54cab061a434ed378fc448333a4eChris Lattner } 71085994260c41a54cab061a434ed378fc448333a4eChris Lattner static Selector getTombstoneMarker() { 71185994260c41a54cab061a434ed378fc448333a4eChris Lattner return Selector(uintptr_t(-2)); 71285994260c41a54cab061a434ed378fc448333a4eChris Lattner } 71311638f7b922aa0182ab2028ec819001ed2fe8085Fariborz Jahanian 71411638f7b922aa0182ab2028ec819001ed2fe8085Fariborz Jahanian static ObjCInstanceTypeFamily getInstTypeMethodFamily(Selector sel); 715bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff}; 716bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff 717af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// \brief This table allows us to fully hide how we implement 71829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// multi-keyword caching. 71929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffclass SelectorTable { 7205f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner void *Impl; // Actually a SelectorTableImpl 721f56faa01936b9cf909623d7f06e3c2569ca4a78eDmitri Gribenko SelectorTable(const SelectorTable &) LLVM_DELETED_FUNCTION; 722f56faa01936b9cf909623d7f06e3c2569ca4a78eDmitri Gribenko void operator=(const SelectorTable &) LLVM_DELETED_FUNCTION; 72329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffpublic: 72429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff SelectorTable(); 72529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff ~SelectorTable(); 72629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 727af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// \brief Can create any sort of selector. 728af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// 729af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// \p NumArgs indicates whether this is a no argument selector "foo", a 730af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// single argument selector "foo:" or multi-argument "foo:bar:". 731ff38491c18b060526d754765b952f4a497a89416Chris Lattner Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV); 7321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 733ff38491c18b060526d754765b952f4a497a89416Chris Lattner Selector getUnarySelector(IdentifierInfo *ID) { 734ff38491c18b060526d754765b952f4a497a89416Chris Lattner return Selector(ID, 1); 735ff38491c18b060526d754765b952f4a497a89416Chris Lattner } 736ff38491c18b060526d754765b952f4a497a89416Chris Lattner Selector getNullarySelector(IdentifierInfo *ID) { 737ff38491c18b060526d754765b952f4a497a89416Chris Lattner return Selector(ID, 0); 738ff38491c18b060526d754765b952f4a497a89416Chris Lattner } 73961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 740af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// \brief Return the total amount of memory allocated for managing selectors. 74197f55d6ffd548d1777d790c84b358030682f9de2Ted Kremenek size_t getTotalMemory() const; 74297f55d6ffd548d1777d790c84b358030682f9de2Ted Kremenek 74380e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl /// \brief Return the default setter name for the given identifier. 744af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// 745af50aab0c317462129d73ae8000c6394c718598dJames Dennett /// This is "set" + \p Name where the initial character of \p Name 74661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff /// has been capitalized. 7477044668ecb518496e463ea2dacae100d4badfd19Adrian Prantl static SmallString<64> constructSetterName(StringRef Name); 74880e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl 74980e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl /// \brief Return the default setter selector for the given identifier. 75080e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl /// 75180e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl /// This is "set" + \p Name where the initial character of \p Name 75280e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl /// has been capitalized. 75380e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl static Selector constructSetterSelector(IdentifierTable &Idents, 75480e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl SelectorTable &SelTable, 75580e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl const IdentifierInfo *Name); 75629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff}; 75729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 758e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// DeclarationNameExtra - Common base of the MultiKeywordSelector, 759e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// CXXSpecialName, and CXXOperatorIdName classes, all of which are 760e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// private classes that describe different kinds of names. 7612e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorclass DeclarationNameExtra { 7622e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorpublic: 7632e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// ExtraKind - The kind of "extra" information stored in the 7642e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// DeclarationName. See @c ExtraKindOrNumArgs for an explanation of 7652e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// how these enumerator values are used. 7662e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor enum ExtraKind { 7672e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor CXXConstructor = 0, 7682e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor CXXDestructor, 7692e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor CXXConversionFunction, 770e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 771e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor CXXOperator##Name, 772e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor#include "clang/Basic/OperatorKinds.def" 7733e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt CXXLiteralOperator, 7742a3009a432bdcec59e6383d7b2b17494d6f91649Douglas Gregor CXXUsingDirective, 7752e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor NUM_EXTRA_KINDS 7762e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor }; 7775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 778e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor /// ExtraKindOrNumArgs - Either the kind of C++ special name or 779e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor /// operator-id (if the value is one of the CXX* enumerators of 780e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor /// ExtraKind), in which case the DeclarationNameExtra is also a 7813e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt /// CXXSpecialName, (for CXXConstructor, CXXDestructor, or 7823e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt /// CXXConversionFunction) CXXOperatorIdName, or CXXLiteralOperatorName, 7833e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt /// it may be also name common to C++ using-directives (CXXUsingDirective), 7843e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt /// otherwise it is NUM_EXTRA_KINDS+NumArgs, where NumArgs is the number of 7852e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// arguments in the Objective-C selector, in which case the 7862e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor /// DeclarationNameExtra is also a MultiKeywordSelector. 7872e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor unsigned ExtraKindOrNumArgs; 7882e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}; 7892e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor 7902e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor} // end namespace clang 7914365a7e46822700357a272d839ee2656d9603d5aChris Lattner 7922e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregornamespace llvm { 7934365a7e46822700357a272d839ee2656d9603d5aChris Lattner/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and 7944365a7e46822700357a272d839ee2656d9603d5aChris Lattner/// DenseSets. 79585994260c41a54cab061a434ed378fc448333a4eChris Lattnertemplate <> 79685994260c41a54cab061a434ed378fc448333a4eChris Lattnerstruct DenseMapInfo<clang::Selector> { 79785994260c41a54cab061a434ed378fc448333a4eChris Lattner static inline clang::Selector getEmptyKey() { 79885994260c41a54cab061a434ed378fc448333a4eChris Lattner return clang::Selector::getEmptyMarker(); 79985994260c41a54cab061a434ed378fc448333a4eChris Lattner } 80085994260c41a54cab061a434ed378fc448333a4eChris Lattner static inline clang::Selector getTombstoneKey() { 8011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return clang::Selector::getTombstoneMarker(); 80285994260c41a54cab061a434ed378fc448333a4eChris Lattner } 8031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 80485994260c41a54cab061a434ed378fc448333a4eChris Lattner static unsigned getHashValue(clang::Selector S); 8051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 80685994260c41a54cab061a434ed378fc448333a4eChris Lattner static bool isEqual(clang::Selector LHS, clang::Selector RHS) { 80785994260c41a54cab061a434ed378fc448333a4eChris Lattner return LHS == RHS; 80885994260c41a54cab061a434ed378fc448333a4eChris Lattner } 80985994260c41a54cab061a434ed378fc448333a4eChris Lattner}; 810700030ebddb987936d4fee14d9412821d96e4840Kovarththanan Rajaratnam 81106159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnertemplate <> 81206159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnerstruct isPodLike<clang::Selector> { static const bool value = true; }; 81306159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner 8146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinestemplate <typename T> class PointerLikeTypeTraits; 8156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 816d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregortemplate<> 817d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregorclass PointerLikeTypeTraits<clang::Selector> { 818d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregorpublic: 819d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor static inline const void *getAsVoidPointer(clang::Selector P) { 820d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor return P.getAsOpaquePtr(); 821d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor } 822d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor static inline clang::Selector getFromVoidPointer(const void *P) { 823d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor return clang::Selector(reinterpret_cast<uintptr_t>(P)); 824d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor } 825d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor enum { NumLowBitsAvailable = 0 }; 826d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor}; 82785994260c41a54cab061a434ed378fc448333a4eChris Lattner 8281734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor// Provide PointerLikeTypeTraits for IdentifierInfo pointers, which 8291734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor// are not guaranteed to be 8-byte aligned. 8301734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregortemplate<> 8311734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorclass PointerLikeTypeTraits<clang::IdentifierInfo*> { 8321734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorpublic: 8331734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor static inline void *getAsVoidPointer(clang::IdentifierInfo* P) { 8341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return P; 8351734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor } 8361734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor static inline clang::IdentifierInfo *getFromVoidPointer(void *P) { 8371734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor return static_cast<clang::IdentifierInfo*>(P); 8381734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor } 8391734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor enum { NumLowBitsAvailable = 1 }; 8401734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor}; 8411734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor 8421734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregortemplate<> 8431734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorclass PointerLikeTypeTraits<const clang::IdentifierInfo*> { 8441734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorpublic: 8451734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor static inline const void *getAsVoidPointer(const clang::IdentifierInfo* P) { 8461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return P; 8471734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor } 8481734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor static inline const clang::IdentifierInfo *getFromVoidPointer(const void *P) { 8491734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor return static_cast<const clang::IdentifierInfo*>(P); 8501734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor } 8511734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor enum { NumLowBitsAvailable = 1 }; 8521734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor}; 8531734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor 8542e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor} // end namespace llvm 8555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif 856