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