IdentifierTable.h revision ea9c26b3dbd74a1497f5609ae6e19a85f42b6073
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- IdentifierTable.h - Hash table for identifier lookup ---*- C++ -*-===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
10c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner// This file defines the IdentifierInfo, IdentifierTable, and Selector
11c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner// interfaces.
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
15c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
16c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
181cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor#include "clang/Basic/OperatorKinds.h"
195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/TokenKinds.h"
205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/StringMap.h"
2168d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff#include "llvm/ADT/SmallString.h"
2272b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek#include "llvm/ADT/OwningPtr.h"
2393a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek#include "llvm/Bitcode/SerializationFwd.h"
245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <string>
259dc62f044a6ba21f503bd56607d94b32704e7945Chris Lattner#include <cassert>
265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2785994260c41a54cab061a434ed378fc448333a4eChris Lattnernamespace llvm {
2885994260c41a54cab061a434ed378fc448333a4eChris Lattner  template <typename T> struct DenseMapInfo;
2985994260c41a54cab061a434ed378fc448333a4eChris Lattner}
3029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang {
32b8128140956c6f8f0ab143818775a81f4b4aa477Chris Lattner  struct LangOptions;
337caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner  class IdentifierInfo;
34ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek  class IdentifierTable;
357caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner  class SourceLocation;
362e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  class MultiKeywordSelector; // private class used by Selector
372e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  class DeclarationName;      // AST class that stores declaration names
382e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
397caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner  /// IdentifierLocPair - A simple pair of identifier info and location.
407caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner  typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair;
417caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner
425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierInfo - One of these records is kept for each identifier that
445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is lexed.  This contains information about whether the token was #define'd,
455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is a language keyword, or if it is a front-end token of some sort (e.g. a
465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// variable or function name).  The preprocessor keeps this information in a
475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// set, and all tok::identifier tokens have a pointer to one of these.
485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierInfo {
498e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek  // Note: DON'T make TokenID a 'tok::TokenKind'; MSVC will treat it as a
508e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek  //       signed char and TokenKinds > 127 won't be handled correctly.
518e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek  unsigned TokenID            : 8; // Front-end token ID or tok::identifier.
525142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor  // Objective-C keyword ('protocol' in '@protocol') or builtin (__builtin_inf).
535142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor  // First NUM_OBJC_KEYWORDS values are for Objective-C, the remaining values
545142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor  // are for builtins.
555142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor  unsigned ObjCOrBuiltinID    :10;
564365a7e46822700357a272d839ee2656d9603d5aChris Lattner  bool HasMacro               : 1; // True if there is a #define for this.
575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool IsExtension            : 1; // True if identifier is a lang extension.
585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool IsPoisoned             : 1; // True if identifier is poisoned.
595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool IsCPPOperatorKeyword   : 1; // True if ident is a C++ operator keyword.
6072b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  // 9 bits left in 32-bit word.
615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void *FETokenInfo;               // Managed by the language front-end.
62ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek  llvm::StringMapEntry<IdentifierInfo*> *Entry;
63ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek
645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  IdentifierInfo(const IdentifierInfo&);  // NONCOPYABLE.
654365a7e46822700357a272d839ee2656d9603d5aChris Lattner  void operator=(const IdentifierInfo&);  // NONASSIGNABLE.
66ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek
67ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek  friend class IdentifierTable;
68ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek
695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
70ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek  IdentifierInfo();
715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
72ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek
7392e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  /// isStr - Return true if this is the identifier for the specified string.
7492e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  /// This is intended to be used for string literals only: II->isStr("foo").
7592e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  template <std::size_t StrLen>
7692e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  bool isStr(const char (&Str)[StrLen]) const {
7792e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner    return getLength() == StrLen-1 && !memcmp(getName(), Str, StrLen-1);
78845222ccd992282bf74b2fca53e7c3b84a81c098Chris Lattner  }
79845222ccd992282bf74b2fca53e7c3b84a81c098Chris Lattner
803f128ad2691d299b96663da85a9e069c4081ea7cSteve Naroff  /// getName - Return the actual string for this identifier.  The returned
813f128ad2691d299b96663da85a9e069c4081ea7cSteve Naroff  /// string is properly null terminated.
825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
83ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek  const char *getName() const {
84ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    if (Entry) return Entry->getKeyData();
85ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    // The 'this' pointer really points to a
86ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    // std::pair<IdentifierInfo, const char*>, where internal pointer
87ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    // points to the external string data.
88ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    return ((std::pair<IdentifierInfo, const char*>*) this)->second + 4;
891f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner  }
901f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner
911f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner  /// getLength - Efficiently return the length of this identifier info.
921f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner  ///
931f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner  unsigned getLength() const {
94ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    if (Entry) return Entry->getKeyLength();
95ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    // The 'this' pointer really points to a
96ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    // std::pair<IdentifierInfo, const char*>, where internal pointer
97ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    // points to the external string data.
98ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    const char* p = ((std::pair<IdentifierInfo, const char*>*) this)->second;
99ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    return ((unsigned) p[0])
100ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek      | (((unsigned) p[1]) << 8)
101ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek      | (((unsigned) p[2]) << 16)
102ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek      | (((unsigned) p[3]) << 24);
1035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1059c46de446d18f4a28446cb798d4131bd05515699Chris Lattner  /// hasMacroDefinition - Return true if this identifier is #defined to some
1069c46de446d18f4a28446cb798d4131bd05515699Chris Lattner  /// other value.
1079c46de446d18f4a28446cb798d4131bd05515699Chris Lattner  bool hasMacroDefinition() const {
1089c46de446d18f4a28446cb798d4131bd05515699Chris Lattner    return HasMacro;
1099c46de446d18f4a28446cb798d4131bd05515699Chris Lattner  }
110cc1a875f94630e58d24a55577ffbf0e89b7da8c7Chris Lattner  void setHasMacroDefinition(bool Val) { HasMacro = Val; }
1115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// get/setTokenID - If this is a source-language token (e.g. 'for'), this API
1135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// can be used to cause the lexer to map identifiers to source-language
1145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// tokens.
1158e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek  tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; }
1165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setTokenID(tok::TokenKind ID) { TokenID = ID; }
1175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getPPKeywordID - Return the preprocessor keyword ID for this identifier.
1196d9a3e648d6bf6b347174152f191bd1377528f8cChris Lattner  /// For example, "define" will return tok::pp_define.
120387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  tok::PPKeywordKind getPPKeywordID() const;
1215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getObjCKeywordID - Return the Objective-C keyword ID for the this
1235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// identifier.  For example, 'class' will return tok::objc_class if ObjC is
1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// enabled.
125ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  tok::ObjCKeywordKind getObjCKeywordID() const {
1265142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor    if (ObjCOrBuiltinID < tok::NUM_OBJC_KEYWORDS)
1275142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor      return tok::ObjCKeywordKind(ObjCOrBuiltinID);
1285142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor    else
1295142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor      return tok::objc_not_keyword;
130ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  }
1315142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor  void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; }
1325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getBuiltinID - Return a value indicating whether this is a builtin
1345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// function.  0 is not-built-in.  1 is builtin-for-some-nonprimary-target.
1355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// 2+ are specific builtin functions.
1365142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor  unsigned getBuiltinID() const {
1375142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor    if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS)
1385142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor      return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS;
1395142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor    else
1405142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor      return 0;
1415142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor  }
1425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setBuiltinID(unsigned ID) {
1435142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor    ObjCOrBuiltinID = ID + tok::NUM_OBJC_KEYWORDS;
144bf8cb361038c71a76f8ffa0f9986cebc43732e87Argyrios Kyrtzidis    assert(ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS) == ID
1455142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor           && "ID too large for field!");
1465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// get/setExtension - Initialize information about whether or not this
1495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// language token is an extension.  This controls extension warnings, and is
1505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// only valid if a custom token ID is set.
1515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isExtensionToken() const { return IsExtension; }
1525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setIsExtensionToken(bool Val) { IsExtension = Val; }
1535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// setIsPoisoned - Mark this identifier as poisoned.  After poisoning, the
1555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Preprocessor will emit an error every time this token is used.
1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setIsPoisoned(bool Value = true) { IsPoisoned = Value; }
1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isPoisoned - Return true if this token has been poisoned.
1595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isPoisoned() const { return IsPoisoned; }
1605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether
1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// this identifier is a C++ alternate representation of an operator.
163c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek  void setIsCPlusPlusOperatorKeyword(bool Val = true)
1645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    { IsCPPOperatorKeyword = Val; }
1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; }
1665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getFETokenInfo/setFETokenInfo - The language front-end is allowed to
1685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// associate arbitrary metadata with this token.
1695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  template<typename T>
1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); }
1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setFETokenInfo(void *T) { FETokenInfo = T; }
17293a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek
17393a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek  /// Emit - Serialize this IdentifierInfo to a bitstream.
17493a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek  void Emit(llvm::Serializer& S) const;
17593a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek
17693a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek  /// Read - Deserialize an IdentifierInfo object from a bitstream.
17793a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek  void Read(llvm::Deserializer& D);
1785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
1795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
18072b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek/// IdentifierInfoLookup - An abstract class used by IdentifierTable that
18172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek///  provides an interface for for performing lookups from strings
18272b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek/// (const char *) to IdentiferInfo objects.
18372b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenekclass IdentifierInfoLookup {
18472b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenekpublic:
18572b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  virtual ~IdentifierInfoLookup();
18672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek
18772b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  /// get - Return the identifier token info for the specified named identifier.
18872b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  ///  Unlike the version in IdentifierTable, this returns a pointer instead
18972b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  ///  of a reference.  If the pointer is NULL then the IdentifierInfo cannot
19072b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  ///  be found.
19172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  virtual IdentifierInfo* get(const char *NameStart, const char *NameEnd) = 0;
19272b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek};
19372b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek
1945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierTable - This table implements an efficient mapping from strings to
1955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierInfo nodes.  It has no other purpose, but this is an
1965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// extremely performance-critical piece of the code, as each occurrance of
1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// every identifier goes through here when lexed.
1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierTable {
1995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Shark shows that using MallocAllocator is *much* slower than using this
2005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // BumpPtrAllocator!
201ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek  typedef llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator> HashTableTy;
2025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  HashTableTy HashTable;
20372b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek
20472b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  IdentifierInfoLookup* ExternalLookup;
2051cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor
2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// IdentifierTable ctor - Create the identifier table, populating it with
2085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// info about the language keywords for the language specified by LangOpts.
20972b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  IdentifierTable(const LangOptions &LangOpts,
21072b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek                  IdentifierInfoLookup* externalLookup = 0);
21172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek
21272b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  llvm::BumpPtrAllocator& getAllocator() {
21372b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek    return HashTable.getAllocator();
21472b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  }
2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// get - Return the identifier token info for the specified named identifier.
2175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
2185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  IdentifierInfo &get(const char *NameStart, const char *NameEnd) {
219ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    llvm::StringMapEntry<IdentifierInfo*> &Entry =
220ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek      HashTable.GetOrCreateValue(NameStart, NameEnd, 0);
221ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek
222ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    IdentifierInfo *II = Entry.getValue();
223ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek
224ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    if (!II) {
225ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek      while (1) {
226ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek        if (ExternalLookup) {
227ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek          II = ExternalLookup->get(NameStart, NameEnd);
228ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek          if (II) break;
229ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek        }
230ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek
231ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek        void *Mem = getAllocator().Allocate<IdentifierInfo>();
232ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek        II = new (Mem) IdentifierInfo();
233ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek        break;
234ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek      }
235ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek
236ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek      Entry.setValue(II);
237ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek      II->Entry = &Entry;
23872b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek    }
23972b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek
240ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    assert(II->Entry != 0);
241ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    return *II;
2425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  IdentifierInfo &get(const char *Name) {
2455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return get(Name, Name+strlen(Name));
2465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  IdentifierInfo &get(const std::string &Name) {
2485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Don't use c_str() here: no need to be null terminated.
2495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const char *NameBytes = &Name[0];
2505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return get(NameBytes, NameBytes+Name.size());
2515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2521cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor
253ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenekprivate:
2545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef HashTableTy::const_iterator iterator;
2555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef HashTableTy::const_iterator const_iterator;
2565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  iterator begin() const { return HashTable.begin(); }
2585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  iterator end() const   { return HashTable.end(); }
259ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenekpublic:
2605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
261c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek  unsigned size() const { return HashTable.size(); }
262c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek
2635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// PrintStats - Print some statistics to stderr that indicate how well the
2645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// hashing is doing.
2655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void PrintStats() const;
266bfa82c4c23ce96fdcf357a8f7ef70a9b71b69144Ted Kremenek
2675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void AddKeywords(const LangOptions &LangOpts);
268c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek
26993a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek  /// Emit - Serialize this IdentifierTable to a bitstream.  This should
27093a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek  ///  be called AFTER objects that externally reference the identifiers in the
27193a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek  ///  table have been serialized.  This is because only the identifiers that
27293a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek  ///  are actually referenced are serialized.
27393a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek  void Emit(llvm::Serializer& S) const;
27493a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek
2750f84c0059cec39fd1c73ac05bc2864dca664e7f4Ted Kremenek  /// Create - Deserialize an IdentifierTable from a bitstream.
276bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek  static IdentifierTable* CreateAndRegister(llvm::Deserializer& D);
27793a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek
278c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenekprivate:
279c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek  /// This ctor is not intended to be used by anyone except for object
280c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek  /// serialization.
28193a9ab4bdc607b12fdcf6aa5cf56950dd45ae0f5Ted Kremenek  IdentifierTable();
2825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
2835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
28429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// Selector - This smart pointer class efficiently represents Objective-C
28529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// method names. This class will either point to an IdentifierInfo or a
28629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// MultiKeywordSelector (which is private). This enables us to optimize
287dee8ecc93825062eb441bfeb7a338d3f2c5ea3f0Nico Weber/// selectors that take no arguments and selectors that take 1 argument, which
28829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// accounts for 78% of all selectors in Cocoa.h.
289bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroffclass Selector {
290bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  enum IdentifierInfoFlag {
2910e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    // MultiKeywordSelector = 0.
292bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    ZeroArg  = 0x1,
293bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    OneArg   = 0x2,
294bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    ArgFlags = ZeroArg|OneArg
295bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  };
296bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  uintptr_t InfoPtr; // a pointer to the MultiKeywordSelector or IdentifierInfo.
297bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff
298bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  Selector(IdentifierInfo *II, unsigned nArgs) {
299bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    InfoPtr = reinterpret_cast<uintptr_t>(II);
3000e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
3010e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    assert(nArgs < 2 && "nArgs not equal to 0/1");
3020e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    InfoPtr |= nArgs+1;
303bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
304bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  Selector(MultiKeywordSelector *SI) {
305bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    InfoPtr = reinterpret_cast<uintptr_t>(SI);
3060e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
307bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
308bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek  Selector(uintptr_t V) : InfoPtr(V) {}
30929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffpublic:
3102e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  friend class SelectorTable; // only the SelectorTable can create these
3112e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  friend class DeclarationName; // and the AST's DeclarationName.
3122e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
313c65b8a3e1f8da6117a2b9ba57afe8b7a2ec887ccTed Kremenek  /// The default ctor should only be used when creating data structures that
314c65b8a3e1f8da6117a2b9ba57afe8b7a2ec887ccTed Kremenek  ///  will contain selectors.
315c65b8a3e1f8da6117a2b9ba57afe8b7a2ec887ccTed Kremenek  Selector() : InfoPtr(0) {}
316c65b8a3e1f8da6117a2b9ba57afe8b7a2ec887ccTed Kremenek
317bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  IdentifierInfo *getAsIdentifierInfo() const {
3180e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    if (getIdentifierInfoFlag())
319bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff      return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags);
320bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return 0;
321bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
322bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  unsigned getIdentifierInfoFlag() const {
323bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return InfoPtr & ArgFlags;
324bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
325bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  /// operator==/!= - Indicate whether the specified selectors are identical.
32697b7f26a92d87e514530a5b652460190ce48c974Ted Kremenek  bool operator==(Selector RHS) const {
327bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return InfoPtr == RHS.InfoPtr;
328bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
32997b7f26a92d87e514530a5b652460190ce48c974Ted Kremenek  bool operator!=(Selector RHS) const {
330bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return InfoPtr != RHS.InfoPtr;
331bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
332bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  void *getAsOpaquePtr() const {
333bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return reinterpret_cast<void*>(InfoPtr);
334bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
335bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  // Predicates to identify the selector type.
336bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  bool isKeywordSelector() const {
337bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return getIdentifierInfoFlag() != ZeroArg;
338bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
339bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  bool isUnarySelector() const {
340bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return getIdentifierInfoFlag() == ZeroArg;
341bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
3425b6b72f53ad164497cf62484b60cdbb4361f1978Steve Naroff  unsigned getNumArgs() const;
343f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner  IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const;
3445b6b72f53ad164497cf62484b60cdbb4361f1978Steve Naroff
345077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner  /// getAsString - Derive the full selector name (e.g. "foo:bar:") and return
346077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner  /// it as an std::string.
347077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner  std::string getAsString() const;
34885994260c41a54cab061a434ed378fc448333a4eChris Lattner
34985994260c41a54cab061a434ed378fc448333a4eChris Lattner  static Selector getEmptyMarker() {
35085994260c41a54cab061a434ed378fc448333a4eChris Lattner    return Selector(uintptr_t(-1));
35185994260c41a54cab061a434ed378fc448333a4eChris Lattner  }
35285994260c41a54cab061a434ed378fc448333a4eChris Lattner  static Selector getTombstoneMarker() {
35385994260c41a54cab061a434ed378fc448333a4eChris Lattner    return Selector(uintptr_t(-2));
35485994260c41a54cab061a434ed378fc448333a4eChris Lattner  }
355bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek
356bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek  // Emit - Emit a selector to bitcode.
357bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek  void Emit(llvm::Serializer& S) const;
358bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek
359bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek  // ReadVal - Read a selector from bitcode.
360bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek  static Selector ReadVal(llvm::Deserializer& D);
361bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff};
362bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff
36329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// SelectorTable - This table allows us to fully hide how we implement
36429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// multi-keyword caching.
36529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffclass SelectorTable {
36629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  void *Impl;  // Actually a FoldingSet<MultiKeywordSelector>*
36729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  SelectorTable(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT
36829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  void operator=(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT
36929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffpublic:
37029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  SelectorTable();
37129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  ~SelectorTable();
37229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
373ff38491c18b060526d754765b952f4a497a89416Chris Lattner  /// getSelector - This can create any sort of selector.  NumArgs indicates
374ff38491c18b060526d754765b952f4a497a89416Chris Lattner  /// whether this is a no argument selector "foo", a single argument selector
375ff38491c18b060526d754765b952f4a497a89416Chris Lattner  /// "foo:" or multi-argument "foo:bar:".
376ff38491c18b060526d754765b952f4a497a89416Chris Lattner  Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV);
377ff38491c18b060526d754765b952f4a497a89416Chris Lattner
378ff38491c18b060526d754765b952f4a497a89416Chris Lattner  Selector getUnarySelector(IdentifierInfo *ID) {
379ff38491c18b060526d754765b952f4a497a89416Chris Lattner    return Selector(ID, 1);
380ff38491c18b060526d754765b952f4a497a89416Chris Lattner  }
381ff38491c18b060526d754765b952f4a497a89416Chris Lattner  Selector getNullarySelector(IdentifierInfo *ID) {
382ff38491c18b060526d754765b952f4a497a89416Chris Lattner    return Selector(ID, 0);
383ff38491c18b060526d754765b952f4a497a89416Chris Lattner  }
384bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek
385bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek  // Emit - Emit a SelectorTable to bitcode.
386bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek  void Emit(llvm::Serializer& S) const;
387bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek
388bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek  // Create - Reconstitute a SelectorTable from bitcode.
389bdbb285aed1bb1e20090a16929f4c1da33d2d5c5Ted Kremenek  static SelectorTable* CreateAndRegister(llvm::Deserializer& D);
39029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff};
39129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
392e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// DeclarationNameExtra - Common base of the MultiKeywordSelector,
393e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// CXXSpecialName, and CXXOperatorIdName classes, all of which are
394e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// private classes that describe different kinds of names.
3952e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorclass DeclarationNameExtra {
3962e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorpublic:
3972e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// ExtraKind - The kind of "extra" information stored in the
3982e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// DeclarationName. See @c ExtraKindOrNumArgs for an explanation of
3992e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// how these enumerator values are used.
4002e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  enum ExtraKind {
4012e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    CXXConstructor = 0,
4022e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    CXXDestructor,
4032e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    CXXConversionFunction,
404e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
405e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    CXXOperator##Name,
406e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor#include "clang/Basic/OperatorKinds.def"
4072e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    NUM_EXTRA_KINDS
4082e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  };
4095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
410e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor  /// ExtraKindOrNumArgs - Either the kind of C++ special name or
411e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor  /// operator-id (if the value is one of the CXX* enumerators of
412e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor  /// ExtraKind), in which case the DeclarationNameExtra is also a
413e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor  /// CXXSpecialName (for CXXConstructor, CXXDestructor, or
414e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor  /// CXXConversionFunction) or CXXOperatorIdName, otherwise it is
4152e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// NUM_EXTRA_KINDS+NumArgs, where NumArgs is the number of
4162e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// arguments in the Objective-C selector, in which case the
4172e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// DeclarationNameExtra is also a MultiKeywordSelector.
4182e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  unsigned ExtraKindOrNumArgs;
4192e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor};
4202e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
4212e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}  // end namespace clang
4224365a7e46822700357a272d839ee2656d9603d5aChris Lattner
4232e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregornamespace llvm {
4244365a7e46822700357a272d839ee2656d9603d5aChris Lattner/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and
4254365a7e46822700357a272d839ee2656d9603d5aChris Lattner/// DenseSets.
42685994260c41a54cab061a434ed378fc448333a4eChris Lattnertemplate <>
42785994260c41a54cab061a434ed378fc448333a4eChris Lattnerstruct DenseMapInfo<clang::Selector> {
42885994260c41a54cab061a434ed378fc448333a4eChris Lattner  static inline clang::Selector getEmptyKey() {
42985994260c41a54cab061a434ed378fc448333a4eChris Lattner    return clang::Selector::getEmptyMarker();
43085994260c41a54cab061a434ed378fc448333a4eChris Lattner  }
43185994260c41a54cab061a434ed378fc448333a4eChris Lattner  static inline clang::Selector getTombstoneKey() {
43285994260c41a54cab061a434ed378fc448333a4eChris Lattner    return clang::Selector::getTombstoneMarker();
43385994260c41a54cab061a434ed378fc448333a4eChris Lattner  }
43485994260c41a54cab061a434ed378fc448333a4eChris Lattner
43585994260c41a54cab061a434ed378fc448333a4eChris Lattner  static unsigned getHashValue(clang::Selector S);
43685994260c41a54cab061a434ed378fc448333a4eChris Lattner
43785994260c41a54cab061a434ed378fc448333a4eChris Lattner  static bool isEqual(clang::Selector LHS, clang::Selector RHS) {
43885994260c41a54cab061a434ed378fc448333a4eChris Lattner    return LHS == RHS;
43985994260c41a54cab061a434ed378fc448333a4eChris Lattner  }
44085994260c41a54cab061a434ed378fc448333a4eChris Lattner
44185994260c41a54cab061a434ed378fc448333a4eChris Lattner  static bool isPod() { return true; }
44285994260c41a54cab061a434ed378fc448333a4eChris Lattner};
44385994260c41a54cab061a434ed378fc448333a4eChris Lattner
4442e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}  // end namespace llvm
4455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif
446