IdentifierTable.h revision 28bbe4b8acc338476fe0825769b41fb32b423c72
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- IdentifierTable.h - Hash table for identifier lookup ---*- C++ -*-===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
10c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner// This file defines the IdentifierInfo, IdentifierTable, and Selector
11c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner// interfaces.
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
15c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
16c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
181cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor#include "clang/Basic/OperatorKinds.h"
195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/TokenKinds.h"
205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/StringMap.h"
21700030ebddb987936d4fee14d9412821d96e4840Kovarththanan Rajaratnam#include "llvm/ADT/StringRef.h"
2268d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff#include "llvm/ADT/SmallString.h"
2372b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek#include "llvm/ADT/OwningPtr.h"
241734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor#include "llvm/Support/PointerLikeTypeTraits.h"
251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#include <cassert>
26403ba3522d1b1c97ae5fad81c1a2c4b3a754e1c1Nick Lewycky#include <cctype>
27403ba3522d1b1c97ae5fad81c1a2c4b3a754e1c1Nick Lewycky#include <string>
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2985994260c41a54cab061a434ed378fc448333a4eChris Lattnernamespace llvm {
3085994260c41a54cab061a434ed378fc448333a4eChris Lattner  template <typename T> struct DenseMapInfo;
3185994260c41a54cab061a434ed378fc448333a4eChris Lattner}
3229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang {
34ea684e699ea84e61711e279f5fa7a1b9f3d46bc2Cedric Venet  class LangOptions;
357caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner  class IdentifierInfo;
36ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek  class IdentifierTable;
377caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner  class SourceLocation;
382e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  class MultiKeywordSelector; // private class used by Selector
392e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  class DeclarationName;      // AST class that stores declaration names
402e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
417caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner  /// IdentifierLocPair - A simple pair of identifier info and location.
427caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner  typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair;
431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierInfo - One of these records is kept for each identifier that
465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is lexed.  This contains information about whether the token was #define'd,
475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is a language keyword, or if it is a front-end token of some sort (e.g. a
485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// variable or function name).  The preprocessor keeps this information in a
491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// set, and all tok::identifier tokens have a pointer to one of these.
505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierInfo {
518e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek  // Note: DON'T make TokenID a 'tok::TokenKind'; MSVC will treat it as a
528e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek  //       signed char and TokenKinds > 127 won't be handled correctly.
531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  unsigned TokenID            : 8; // Front-end token ID or tok::identifier.
545142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor  // Objective-C keyword ('protocol' in '@protocol') or builtin (__builtin_inf).
555142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor  // First NUM_OBJC_KEYWORDS values are for Objective-C, the remaining values
565142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor  // are for builtins.
57c81ca9852806e75972bbb246fa916152e8fba541Ted Kremenek  unsigned ObjCOrBuiltinID    :11;
584365a7e46822700357a272d839ee2656d9603d5aChris Lattner  bool HasMacro               : 1; // True if there is a #define for this.
595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool IsExtension            : 1; // True if identifier is a lang extension.
605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool IsPoisoned             : 1; // True if identifier is poisoned.
615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool IsCPPOperatorKeyword   : 1; // True if ident is a C++ operator keyword.
626a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  bool NeedsHandleIdentifier  : 1; // See "RecomputeNeedsHandleIdentifier".
633c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl  bool IsFromAST              : 1; // True if identfier first appeared in an AST
643c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl                                   // file and wasn't modified since.
65646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis  bool RevertedTokenID        : 1; // True if RevertTokenIDToIdentifier was
66646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis                                   // called.
67c81ca9852806e75972bbb246fa916152e8fba541Ted Kremenek  // 6 bits left in 32-bit word.
685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void *FETokenInfo;               // Managed by the language front-end.
69ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek  llvm::StringMapEntry<IdentifierInfo*> *Entry;
701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  IdentifierInfo(const IdentifierInfo&);  // NONCOPYABLE.
724365a7e46822700357a272d839ee2656d9603d5aChris Lattner  void operator=(const IdentifierInfo&);  // NONASSIGNABLE.
73ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek
741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  friend class IdentifierTable;
75295a2a617ac335f590e430ab7fcd98f8ce109251Douglas Gregor
765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
77ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek  IdentifierInfo();
785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8092e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  /// isStr - Return true if this is the identifier for the specified string.
8192e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  /// This is intended to be used for string literals only: II->isStr("foo").
8292e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  template <std::size_t StrLen>
8392e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  bool isStr(const char (&Str)[StrLen]) const {
847fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar    return getLength() == StrLen-1 && !memcmp(getNameStart(), Str, StrLen-1);
85845222ccd992282bf74b2fca53e7c3b84a81c098Chris Lattner  }
861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
877fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar  /// getNameStart - Return the beginning of the actual string for this
887fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar  /// identifier.  The returned string is properly null terminated.
895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
907fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar  const char *getNameStart() const {
91ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    if (Entry) return Entry->getKeyData();
927e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek    // FIXME: This is gross. It would be best not to embed specific details
937e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek    // of the PTH file format here.
941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // The 'this' pointer really points to a
95ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    // std::pair<IdentifierInfo, const char*>, where internal pointer
96ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    // points to the external string data.
9740844a8b5a89676fb61898d61ea4a7fa98eb9b6bGabor Greif    typedef std::pair<IdentifierInfo, const char*> actualtype;
9840844a8b5a89676fb61898d61ea4a7fa98eb9b6bGabor Greif    return ((const actualtype*) this)->second;
991f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner  }
1001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1011f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner  /// getLength - Efficiently return the length of this identifier info.
1021f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner  ///
1031f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner  unsigned getLength() const {
104ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    if (Entry) return Entry->getKeyLength();
1057e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek    // FIXME: This is gross. It would be best not to embed specific details
1067e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek    // of the PTH file format here.
1071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // The 'this' pointer really points to a
108ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    // std::pair<IdentifierInfo, const char*>, where internal pointer
109ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    // points to the external string data.
11040844a8b5a89676fb61898d61ea4a7fa98eb9b6bGabor Greif    typedef std::pair<IdentifierInfo, const char*> actualtype;
11140844a8b5a89676fb61898d61ea4a7fa98eb9b6bGabor Greif    const char* p = ((const actualtype*) this)->second - 2;
1127fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar    return (((unsigned) p[0]) | (((unsigned) p[1]) << 8)) - 1;
1137fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar  }
1147fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar
11501eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  /// getName - Return the actual identifier string.
11601eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  llvm::StringRef getName() const {
1177fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar    return llvm::StringRef(getNameStart(), getLength());
1185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1209c46de446d18f4a28446cb798d4131bd05515699Chris Lattner  /// hasMacroDefinition - Return true if this identifier is #defined to some
1219c46de446d18f4a28446cb798d4131bd05515699Chris Lattner  /// other value.
1229c46de446d18f4a28446cb798d4131bd05515699Chris Lattner  bool hasMacroDefinition() const {
1239c46de446d18f4a28446cb798d4131bd05515699Chris Lattner    return HasMacro;
1249c46de446d18f4a28446cb798d4131bd05515699Chris Lattner  }
1256a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  void setHasMacroDefinition(bool Val) {
1266a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    if (HasMacro == Val) return;
1271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1286a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    HasMacro = Val;
1296a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    if (Val)
1306a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      NeedsHandleIdentifier = 1;
1316a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    else
1326a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      RecomputeNeedsHandleIdentifier();
1333c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl    IsFromAST = false;
1346a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  }
1351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
136646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis  /// getTokenID - If this is a source-language token (e.g. 'for'), this API
1375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// can be used to cause the lexer to map identifiers to source-language
1385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// tokens.
1398e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek  tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; }
140646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis
141646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis  /// \brief True if RevertTokenIDToIdentifier() was called.
142646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis  bool hasRevertedTokenIDToIdentifier() const { return RevertedTokenID; }
143646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis
144646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis  /// \brief Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2
145f573084db5807f6003282bdf53ca9d58bab1ddc4Argyrios Kyrtzidis  /// compatibility.
146f573084db5807f6003282bdf53ca9d58bab1ddc4Argyrios Kyrtzidis  ///
147f573084db5807f6003282bdf53ca9d58bab1ddc4Argyrios Kyrtzidis  /// TokenID is normally read-only but there are 2 instances where we revert it
148f573084db5807f6003282bdf53ca9d58bab1ddc4Argyrios Kyrtzidis  /// to tok::identifier for libstdc++ 4.2. Keep track of when this happens
1493c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl  /// using this method so we can inform serialization about it.
150646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis  void RevertTokenIDToIdentifier() {
151646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis    assert(TokenID != tok::identifier && "Already at tok::identifier");
152646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis    TokenID = tok::identifier;
153646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis    RevertedTokenID = true;
154646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis  }
1551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getPPKeywordID - Return the preprocessor keyword ID for this identifier.
1576d9a3e648d6bf6b347174152f191bd1377528f8cChris Lattner  /// For example, "define" will return tok::pp_define.
158387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  tok::PPKeywordKind getPPKeywordID() const;
1591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getObjCKeywordID - Return the Objective-C keyword ID for the this
1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// identifier.  For example, 'class' will return tok::objc_class if ObjC is
1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// enabled.
163ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  tok::ObjCKeywordKind getObjCKeywordID() const {
1641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (ObjCOrBuiltinID < tok::NUM_OBJC_KEYWORDS)
1655142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor      return tok::ObjCKeywordKind(ObjCOrBuiltinID);
1665142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor    else
1675142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor      return tok::objc_not_keyword;
168ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  }
1695142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor  void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; }
1703251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor
1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getBuiltinID - Return a value indicating whether this is a builtin
1725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// function.  0 is not-built-in.  1 is builtin-for-some-nonprimary-target.
1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// 2+ are specific builtin functions.
1741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  unsigned getBuiltinID() const {
1755142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor    if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS)
1761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS;
1775142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor    else
1785142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor      return 0;
1795142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor  }
1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setBuiltinID(unsigned ID) {
1815142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor    ObjCOrBuiltinID = ID + tok::NUM_OBJC_KEYWORDS;
1821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS) == ID
1835142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor           && "ID too large for field!");
1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1853251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor
1863251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor  unsigned getObjCOrBuiltinID() const { return ObjCOrBuiltinID; }
1873251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor  void setObjCOrBuiltinID(unsigned ID) { ObjCOrBuiltinID = ID; }
1883251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor
1895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// get/setExtension - Initialize information about whether or not this
1905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// language token is an extension.  This controls extension warnings, and is
1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// only valid if a custom token ID is set.
1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isExtensionToken() const { return IsExtension; }
1936a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  void setIsExtensionToken(bool Val) {
1946a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    IsExtension = Val;
1956a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    if (Val)
1966a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      NeedsHandleIdentifier = 1;
1976a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    else
1986a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      RecomputeNeedsHandleIdentifier();
1996a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  }
2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// setIsPoisoned - Mark this identifier as poisoned.  After poisoning, the
2025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Preprocessor will emit an error every time this token is used.
2036a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  void setIsPoisoned(bool Value = true) {
2046a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    IsPoisoned = Value;
2056a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    if (Value)
2066a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      NeedsHandleIdentifier = 1;
2076a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    else
2086a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      RecomputeNeedsHandleIdentifier();
2093c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl    IsFromAST = false;
2106a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  }
2111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isPoisoned - Return true if this token has been poisoned.
2135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isPoisoned() const { return IsPoisoned; }
2141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether
2165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// this identifier is a C++ alternate representation of an operator.
2176a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  void setIsCPlusPlusOperatorKeyword(bool Val = true) {
2186a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    IsCPPOperatorKeyword = Val;
2196a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    if (Val)
2206a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      NeedsHandleIdentifier = 1;
2216a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    else
2226a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      RecomputeNeedsHandleIdentifier();
2236a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  }
2245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; }
2255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getFETokenInfo/setFETokenInfo - The language front-end is allowed to
2275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// associate arbitrary metadata with this token.
2285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  template<typename T>
2295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); }
2305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setFETokenInfo(void *T) { FETokenInfo = T; }
2316a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner
2326a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// isHandleIdentifierCase - Return true if the Preprocessor::HandleIdentifier
2336a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// must be called on a token of this identifier.  If this returns false, we
2346a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// know that HandleIdentifier will not affect the token.
2356a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  bool isHandleIdentifierCase() const { return NeedsHandleIdentifier; }
2361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2373c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl  /// isFromAST - Return true if the identifier in its current state was loaded
2383c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl  /// from an AST file.
2393c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl  bool isFromAST() const { return IsFromAST; }
240ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl
2413c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl  void setIsFromAST(bool FromAST = true) { IsFromAST = FromAST; }
242ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl
2436a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattnerprivate:
2446a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// RecomputeNeedsHandleIdentifier - The Preprocessor::HandleIdentifier does
2456a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// several special (but rare) things to identifiers of various sorts.  For
2466a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// example, it changes the "for" keyword token from tok::identifier to
2476a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// tok::for.
2486a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  ///
2496a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// This method is very tied to the definition of HandleIdentifier.  Any
2506a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// change to it should be reflected here.
2516a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  void RecomputeNeedsHandleIdentifier() {
2526a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    NeedsHandleIdentifier =
2536a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() |
254863c486fcb6162495a94fddf7ac8409de2638995Chris Lattner       isExtensionToken());
2556a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  }
2565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
2575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
25828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// \brief an RAII object for [un]poisoning an identifier
25928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// within a certain scope. II is allowed to be null, in
26028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// which case, objects of this type have no effect.
26128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegleyclass PoisonIdentifierRAIIObject {
26228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  IdentifierInfo *const II;
26328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  const bool OldValue;
26428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegleypublic:
26528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  PoisonIdentifierRAIIObject(IdentifierInfo *II, bool NewValue)
26628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    : II(II), OldValue(II ? II->isPoisoned() : false) {
26728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    if(II)
26828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      II->setIsPoisoned(NewValue);
26928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  }
27028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
27128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  ~PoisonIdentifierRAIIObject() {
27228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    if(II)
27328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      II->setIsPoisoned(OldValue);
27428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  }
27528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley};
27628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
27795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// \brief An iterator that walks over all of the known identifiers
27895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// in the lookup table.
27995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor///
28095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// Since this iterator uses an abstract interface via virtual
28195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// functions, it uses an object-oriented interface rather than the
28295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// more standard C++ STL iterator interface. In this OO-style
28395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// iteration, the single function \c Next() provides dereference,
28495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// advance, and end-of-sequence checking in a single
28595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// operation. Subclasses of this iterator type will provide the
28695f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// actual functionality.
28795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregorclass IdentifierIterator {
28895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregorprivate:
28995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  IdentifierIterator(const IdentifierIterator&); // Do not implement
29095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  IdentifierIterator &operator=(const IdentifierIterator&); // Do not implement
29195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor
29295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregorprotected:
29395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  IdentifierIterator() { }
29495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor
29595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregorpublic:
29695f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  virtual ~IdentifierIterator();
29795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor
29895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// \brief Retrieve the next string in the identifier table and
29995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// advances the iterator for the following string.
30095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  ///
30195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// \returns The next string in the identifier table. If there is
30295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// no such string, returns an empty \c llvm::StringRef.
30395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  virtual llvm::StringRef Next() = 0;
30495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor};
30595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor
30672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek/// IdentifierInfoLookup - An abstract class used by IdentifierTable that
307668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor///  provides an interface for performing lookups from strings
30872b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek/// (const char *) to IdentiferInfo objects.
30972b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenekclass IdentifierInfoLookup {
31072b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenekpublic:
31172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  virtual ~IdentifierInfoLookup();
3121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
31372b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  /// get - Return the identifier token info for the specified named identifier.
31472b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  ///  Unlike the version in IdentifierTable, this returns a pointer instead
31572b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  ///  of a reference.  If the pointer is NULL then the IdentifierInfo cannot
31672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  ///  be found.
317700030ebddb987936d4fee14d9412821d96e4840Kovarththanan Rajaratnam  virtual IdentifierInfo* get(llvm::StringRef Name) = 0;
31895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor
31995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// \brief Retrieve an iterator into the set of all identifiers
32095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// known to this identifier lookup source.
32195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  ///
32295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// This routine provides access to all of the identifiers known to
32395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// the identifier lookup, allowing access to the contents of the
32495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// identifiers without introducing the overhead of constructing
32595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// IdentifierInfo objects for each.
32695f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  ///
32795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// \returns A new iterator into the set of known identifiers. The
32895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// caller is responsible for deleting this iterator.
32995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  virtual IdentifierIterator *getIdentifiers() const;
3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump};
3318c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
3328c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// \brief An abstract class used to resolve numerical identifier
3338c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// references (meaningful only to some external source) into
3348c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// IdentifierInfo pointers.
3358c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorclass ExternalIdentifierLookup {
3368c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorpublic:
3378c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  virtual ~ExternalIdentifierLookup();
3388c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
3398c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// \brief Return the identifier associated with the given ID number.
3408c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  ///
3418c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// The ID 0 is associated with the NULL identifier.
3428c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  virtual IdentifierInfo *GetIdentifier(unsigned ID) = 0;
3438c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor};
3448c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
3455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierTable - This table implements an efficient mapping from strings to
3465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierInfo nodes.  It has no other purpose, but this is an
347fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner/// extremely performance-critical piece of the code, as each occurrence of
3485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// every identifier goes through here when lexed.
3495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierTable {
3505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Shark shows that using MallocAllocator is *much* slower than using this
3515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // BumpPtrAllocator!
352ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek  typedef llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator> HashTableTy;
3535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  HashTableTy HashTable;
3541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
35572b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  IdentifierInfoLookup* ExternalLookup;
3561cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor
3575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
3585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// IdentifierTable ctor - Create the identifier table, populating it with
3595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// info about the language keywords for the language specified by LangOpts.
36072b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  IdentifierTable(const LangOptions &LangOpts,
36172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek                  IdentifierInfoLookup* externalLookup = 0);
3621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
363668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor  /// \brief Set the external identifier lookup mechanism.
364668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor  void setExternalIdentifierLookup(IdentifierInfoLookup *IILookup) {
365668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor    ExternalLookup = IILookup;
366668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor  }
367668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor
36895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// \brief Retrieve the external identifier lookup object, if any.
36995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  IdentifierInfoLookup *getExternalIdentifierLookup() const {
37095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor    return ExternalLookup;
37195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  }
37295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor
37372b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  llvm::BumpPtrAllocator& getAllocator() {
37472b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek    return HashTable.getAllocator();
37572b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  }
3761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// get - Return the identifier token info for the specified named identifier.
3785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
3796488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam  IdentifierInfo &get(llvm::StringRef Name) {
380ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    llvm::StringMapEntry<IdentifierInfo*> &Entry =
3816488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam      HashTable.GetOrCreateValue(Name);
3821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
383ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    IdentifierInfo *II = Entry.getValue();
384d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    if (II) return *II;
3851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
386d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    // No entry; if we have an external lookup, look there first.
387d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    if (ExternalLookup) {
3886488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam      II = ExternalLookup->get(Name);
389d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar      if (II) {
390d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar        // Cache in the StringMap for subsequent lookups.
391d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar        Entry.setValue(II);
392d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar        return *II;
393ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek      }
394d42ffbd22fc7eb61321f6a88173ee424991f01c6Ted Kremenek    }
395ccb9bac3adb35a2dc78c1737e7b2dc6537a16393Daniel Dunbar
396d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    // Lookups failed, make a new IdentifierInfo.
397d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    void *Mem = getAllocator().Allocate<IdentifierInfo>();
398d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    II = new (Mem) IdentifierInfo();
399d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    Entry.setValue(II);
400d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar
401d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    // Make sure getName() knows how to find the IdentifierInfo
402d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    // contents.
403d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    II->Entry = &Entry;
404d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar
405ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    return *II;
4065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
408646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis  IdentifierInfo &get(llvm::StringRef Name, tok::TokenKind TokenCode) {
409646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis    IdentifierInfo &II = get(Name);
410646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis    II.TokenID = TokenCode;
411646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis    return II;
412646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis  }
413646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis
4146488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam  IdentifierInfo &get(const char *NameStart, const char *NameEnd) {
4156488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam    return get(llvm::StringRef(NameStart, NameEnd-NameStart));
416811f4267aa1ebd727c31594b8ed94048e2c10ad6Kovarththanan Rajaratnam  }
417811f4267aa1ebd727c31594b8ed94048e2c10ad6Kovarththanan Rajaratnam
418811f4267aa1ebd727c31594b8ed94048e2c10ad6Kovarththanan Rajaratnam  IdentifierInfo &get(const char *Name, size_t NameLen) {
419811f4267aa1ebd727c31594b8ed94048e2c10ad6Kovarththanan Rajaratnam    return get(llvm::StringRef(Name, NameLen));
420811f4267aa1ebd727c31594b8ed94048e2c10ad6Kovarththanan Rajaratnam  }
421811f4267aa1ebd727c31594b8ed94048e2c10ad6Kovarththanan Rajaratnam
422ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl  /// \brief Gets an IdentifierInfo for the given name without consulting
423ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl  ///        external sources.
4245f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor  ///
425ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl  /// This is a version of get() meant for external sources that want to
426ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl  /// introduce or modify an identifier. If they called get(), they would
427ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl  /// likely end up in a recursion.
428ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl  IdentifierInfo &getOwn(const char *NameStart, const char *NameEnd) {
4295f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor    llvm::StringMapEntry<IdentifierInfo*> &Entry =
4305f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor      HashTable.GetOrCreateValue(NameStart, NameEnd);
4311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4325f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor    IdentifierInfo *II = Entry.getValue();
433ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl    if (!II) {
4341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
435ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl      // Lookups failed, make a new IdentifierInfo.
436ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl      void *Mem = getAllocator().Allocate<IdentifierInfo>();
437ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl      II = new (Mem) IdentifierInfo();
438ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl      Entry.setValue(II);
4395f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor
440ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl      // Make sure getName() knows how to find the IdentifierInfo
441ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl      // contents.
442ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl      II->Entry = &Entry;
443ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl    }
4445f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor
4455f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor    return *II;
4465f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor  }
447ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl  IdentifierInfo &getOwn(llvm::StringRef Name) {
448ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl    return getOwn(Name.begin(), Name.end());
44983885f7e3bf68d271e1e96726931814b836353a3Daniel Dunbar  }
4505f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor
4515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef HashTableTy::const_iterator iterator;
4525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef HashTableTy::const_iterator const_iterator;
4531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  iterator begin() const { return HashTable.begin(); }
4555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  iterator end() const   { return HashTable.end(); }
456c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek  unsigned size() const { return HashTable.size(); }
4571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// PrintStats - Print some statistics to stderr that indicate how well the
4595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// hashing is doing.
4605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void PrintStats() const;
4611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void AddKeywords(const LangOptions &LangOpts);
4635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
4645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
46585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// ObjCMethodFamily - A family of Objective-C methods.  These
46685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// families have no inherent meaning in the language, but are
46785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// nonetheless central enough in the existing implementations to
46885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// merit direct AST support.  While, in theory, arbitrary methods can
46985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// be considered to form families, we focus here on the methods
47085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// involving allocation and retain-count management, as these are the
47185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// most "core" and the most likely to be useful to diverse clients
47285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// without extra information.
47385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall///
47485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// Both selectors and actual method declarations may be classified
47585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// into families.  Method families may impose additional restrictions
47685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// beyond their selector name; for example, a method called '_init'
47785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// that returns void is not considered to be in the 'init' family
47885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// (but would be if it returned 'id').  It is also possible to
47985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// explicitly change or remove a method's family.  Therefore the
48085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// method's family should be considered the single source of truth.
48185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCallenum ObjCMethodFamily {
48285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  /// \brief No particular method family.
48385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_None,
48485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
48585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // Selectors in these families may have arbitrary arity, may be
48685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // written with arbitrary leading underscores, and may have
48785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // additional CamelCase "words" in their first selector chunk
48885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // following the family name.
48985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_alloc,
49085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_copy,
49185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_init,
49285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_mutableCopy,
49385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_new,
49485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
49585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // These families are singletons consisting only of the nullary
49685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // selector with the given name.
49785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_autorelease,
49885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_dealloc,
49985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_release,
50085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_retain,
50185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_retainCount
50285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall};
50385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
50485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// Enough bits to store any enumerator in ObjCMethodFamily or
50585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// InvalidObjCMethodFamily.
50685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCallenum { ObjCMethodFamilyBitWidth = 4 };
50785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
50885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// An invalid value of ObjCMethodFamily.
50985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCallenum { InvalidObjCMethodFamily = (1 << ObjCMethodFamilyBitWidth) - 1 };
51085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
51129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// Selector - This smart pointer class efficiently represents Objective-C
51229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// method names. This class will either point to an IdentifierInfo or a
51329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// MultiKeywordSelector (which is private). This enables us to optimize
5141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// selectors that take no arguments and selectors that take 1 argument, which
51529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// accounts for 78% of all selectors in Cocoa.h.
516bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroffclass Selector {
5178af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek  friend class DiagnosticInfo;
5181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
519bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  enum IdentifierInfoFlag {
5200e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    // MultiKeywordSelector = 0.
521bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    ZeroArg  = 0x1,
522bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    OneArg   = 0x2,
523bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    ArgFlags = ZeroArg|OneArg
524bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  };
525bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  uintptr_t InfoPtr; // a pointer to the MultiKeywordSelector or IdentifierInfo.
5261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
527bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  Selector(IdentifierInfo *II, unsigned nArgs) {
528bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    InfoPtr = reinterpret_cast<uintptr_t>(II);
5290e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
5300e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    assert(nArgs < 2 && "nArgs not equal to 0/1");
5310e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    InfoPtr |= nArgs+1;
532bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
533bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  Selector(MultiKeywordSelector *SI) {
534bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    InfoPtr = reinterpret_cast<uintptr_t>(SI);
5350e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
536bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
5371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
538bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  IdentifierInfo *getAsIdentifierInfo() const {
5390e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    if (getIdentifierInfoFlag())
540bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff      return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags);
541bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return 0;
542bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
543bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  unsigned getIdentifierInfoFlag() const {
544bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return InfoPtr & ArgFlags;
545bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
5468af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek
54785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  static ObjCMethodFamily getMethodFamilyImpl(Selector sel);
54885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
5498af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenekpublic:
5508af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek  friend class SelectorTable; // only the SelectorTable can create these
5518af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek  friend class DeclarationName; // and the AST's DeclarationName.
5528af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek
5538af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek  /// The default ctor should only be used when creating data structures that
5548af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek  ///  will contain selectors.
5558af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek  Selector() : InfoPtr(0) {}
55690cd1bb1baac2a0221f3642de0cbea3244b116e5Steve Naroff  Selector(uintptr_t V) : InfoPtr(V) {}
5578af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek
558bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  /// operator==/!= - Indicate whether the specified selectors are identical.
55997b7f26a92d87e514530a5b652460190ce48c974Ted Kremenek  bool operator==(Selector RHS) const {
560bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return InfoPtr == RHS.InfoPtr;
561bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
56297b7f26a92d87e514530a5b652460190ce48c974Ted Kremenek  bool operator!=(Selector RHS) const {
563bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return InfoPtr != RHS.InfoPtr;
564bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
565bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  void *getAsOpaquePtr() const {
566bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return reinterpret_cast<void*>(InfoPtr);
567bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
568405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor
569405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor  /// \brief Determine whether this is the empty selector.
570405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor  bool isNull() const { return InfoPtr == 0; }
571405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor
572bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  // Predicates to identify the selector type.
5731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool isKeywordSelector() const {
5741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return getIdentifierInfoFlag() != ZeroArg;
575bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
5761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool isUnarySelector() const {
577bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return getIdentifierInfoFlag() == ZeroArg;
578bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
5795b6b72f53ad164497cf62484b60cdbb4361f1978Steve Naroff  unsigned getNumArgs() const;
580813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor
581813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor
582813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// \brief Retrieve the identifier at a given position in the selector.
583813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  ///
584813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// Note that the identifier pointer returned may be NULL. Clients that only
585813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// care about the text of the identifier string, and not the specific,
586813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// uniqued identifier pointer, should use \c getNameForSlot(), which returns
587813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// an empty string when the identifier pointer would be NULL.
588813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  ///
589813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// \param argIndex The index for which we want to retrieve the identifier.
590813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// This index shall be less than \c getNumArgs() unless this is a keyword
591813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// selector, in which case 0 is the only permissible value.
592813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  ///
593813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// \returns the uniqued identifier for this slot, or NULL if this slot has
594813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// no corresponding identifier.
595f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner  IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const;
596813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor
597813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// \brief Retrieve the name at a given position in the selector.
598813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  ///
599813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// \param argIndex The index for which we want to retrieve the name.
600813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// This index shall be less than \c getNumArgs() unless this is a keyword
601813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// selector, in which case 0 is the only permissible value.
602813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  ///
603813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// \returns the name for this slot, which may be the empty string if no
604813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// name was supplied.
605813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  llvm::StringRef getNameForSlot(unsigned argIndex) const;
606813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor
607077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner  /// getAsString - Derive the full selector name (e.g. "foo:bar:") and return
608077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner  /// it as an std::string.
609077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner  std::string getAsString() const;
6101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
61185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  /// getMethodFamily - Derive the conventional family of this method.
61285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  ObjCMethodFamily getMethodFamily() const {
61385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    return getMethodFamilyImpl(*this);
61485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  }
61585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
61685994260c41a54cab061a434ed378fc448333a4eChris Lattner  static Selector getEmptyMarker() {
61785994260c41a54cab061a434ed378fc448333a4eChris Lattner    return Selector(uintptr_t(-1));
61885994260c41a54cab061a434ed378fc448333a4eChris Lattner  }
61985994260c41a54cab061a434ed378fc448333a4eChris Lattner  static Selector getTombstoneMarker() {
62085994260c41a54cab061a434ed378fc448333a4eChris Lattner    return Selector(uintptr_t(-2));
62185994260c41a54cab061a434ed378fc448333a4eChris Lattner  }
622bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff};
623bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff
62429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// SelectorTable - This table allows us to fully hide how we implement
62529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// multi-keyword caching.
62629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffclass SelectorTable {
6275f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner  void *Impl;  // Actually a SelectorTableImpl
62829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  SelectorTable(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT
62929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  void operator=(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT
63029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffpublic:
63129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  SelectorTable();
63229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  ~SelectorTable();
63329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
634ff38491c18b060526d754765b952f4a497a89416Chris Lattner  /// getSelector - This can create any sort of selector.  NumArgs indicates
635ff38491c18b060526d754765b952f4a497a89416Chris Lattner  /// whether this is a no argument selector "foo", a single argument selector
636ff38491c18b060526d754765b952f4a497a89416Chris Lattner  /// "foo:" or multi-argument "foo:bar:".
637ff38491c18b060526d754765b952f4a497a89416Chris Lattner  Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV);
6381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
639ff38491c18b060526d754765b952f4a497a89416Chris Lattner  Selector getUnarySelector(IdentifierInfo *ID) {
640ff38491c18b060526d754765b952f4a497a89416Chris Lattner    return Selector(ID, 1);
641ff38491c18b060526d754765b952f4a497a89416Chris Lattner  }
642ff38491c18b060526d754765b952f4a497a89416Chris Lattner  Selector getNullarySelector(IdentifierInfo *ID) {
643ff38491c18b060526d754765b952f4a497a89416Chris Lattner    return Selector(ID, 0);
644ff38491c18b060526d754765b952f4a497a89416Chris Lattner  }
64561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
64697f55d6ffd548d1777d790c84b358030682f9de2Ted Kremenek  /// Return the total amount of memory allocated for managing selectors.
64797f55d6ffd548d1777d790c84b358030682f9de2Ted Kremenek  size_t getTotalMemory() const;
64897f55d6ffd548d1777d790c84b358030682f9de2Ted Kremenek
64961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  /// constructSetterName - Return the setter name for the given
65061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  /// identifier, i.e. "set" + Name where the initial character of Name
65161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  /// has been capitalized.
652fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff  static Selector constructSetterName(IdentifierTable &Idents,
653fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff                                      SelectorTable &SelTable,
654fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff                                      const IdentifierInfo *Name) {
65561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    llvm::SmallString<100> SelectorName;
65661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    SelectorName = "set";
65701eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar    SelectorName += Name->getName();
65861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    SelectorName[3] = toupper(SelectorName[3]);
6592781deb126663ca1bd412044a1e66577585987b3Kovarththanan Rajaratnam    IdentifierInfo *SetterName = &Idents.get(SelectorName);
660fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff    return SelTable.getUnarySelector(SetterName);
66161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  }
66229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff};
66329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
664e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// DeclarationNameExtra - Common base of the MultiKeywordSelector,
665e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// CXXSpecialName, and CXXOperatorIdName classes, all of which are
666e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// private classes that describe different kinds of names.
6672e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorclass DeclarationNameExtra {
6682e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorpublic:
6692e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// ExtraKind - The kind of "extra" information stored in the
6702e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// DeclarationName. See @c ExtraKindOrNumArgs for an explanation of
6712e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// how these enumerator values are used.
6722e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  enum ExtraKind {
6732e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    CXXConstructor = 0,
6742e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    CXXDestructor,
6752e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    CXXConversionFunction,
676e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
677e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    CXXOperator##Name,
678e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor#include "clang/Basic/OperatorKinds.def"
6793e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt    CXXLiteralOperator,
6802a3009a432bdcec59e6383d7b2b17494d6f91649Douglas Gregor    CXXUsingDirective,
6812e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    NUM_EXTRA_KINDS
6822e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  };
6835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
684e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor  /// ExtraKindOrNumArgs - Either the kind of C++ special name or
685e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor  /// operator-id (if the value is one of the CXX* enumerators of
686e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor  /// ExtraKind), in which case the DeclarationNameExtra is also a
6873e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt  /// CXXSpecialName, (for CXXConstructor, CXXDestructor, or
6883e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt  /// CXXConversionFunction) CXXOperatorIdName, or CXXLiteralOperatorName,
6893e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt  /// it may be also name common to C++ using-directives (CXXUsingDirective),
6903e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt  /// otherwise it is NUM_EXTRA_KINDS+NumArgs, where NumArgs is the number of
6912e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// arguments in the Objective-C selector, in which case the
6922e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// DeclarationNameExtra is also a MultiKeywordSelector.
6932e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  unsigned ExtraKindOrNumArgs;
6942e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor};
6952e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
6962e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}  // end namespace clang
6974365a7e46822700357a272d839ee2656d9603d5aChris Lattner
6982e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregornamespace llvm {
6994365a7e46822700357a272d839ee2656d9603d5aChris Lattner/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and
7004365a7e46822700357a272d839ee2656d9603d5aChris Lattner/// DenseSets.
70185994260c41a54cab061a434ed378fc448333a4eChris Lattnertemplate <>
70285994260c41a54cab061a434ed378fc448333a4eChris Lattnerstruct DenseMapInfo<clang::Selector> {
70385994260c41a54cab061a434ed378fc448333a4eChris Lattner  static inline clang::Selector getEmptyKey() {
70485994260c41a54cab061a434ed378fc448333a4eChris Lattner    return clang::Selector::getEmptyMarker();
70585994260c41a54cab061a434ed378fc448333a4eChris Lattner  }
70685994260c41a54cab061a434ed378fc448333a4eChris Lattner  static inline clang::Selector getTombstoneKey() {
7071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return clang::Selector::getTombstoneMarker();
70885994260c41a54cab061a434ed378fc448333a4eChris Lattner  }
7091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
71085994260c41a54cab061a434ed378fc448333a4eChris Lattner  static unsigned getHashValue(clang::Selector S);
7111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
71285994260c41a54cab061a434ed378fc448333a4eChris Lattner  static bool isEqual(clang::Selector LHS, clang::Selector RHS) {
71385994260c41a54cab061a434ed378fc448333a4eChris Lattner    return LHS == RHS;
71485994260c41a54cab061a434ed378fc448333a4eChris Lattner  }
71585994260c41a54cab061a434ed378fc448333a4eChris Lattner};
716700030ebddb987936d4fee14d9412821d96e4840Kovarththanan Rajaratnam
71706159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnertemplate <>
71806159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnerstruct isPodLike<clang::Selector> { static const bool value = true; };
71906159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner
720d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregortemplate<>
721d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregorclass PointerLikeTypeTraits<clang::Selector> {
722d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregorpublic:
723d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor  static inline const void *getAsVoidPointer(clang::Selector P) {
724d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor    return P.getAsOpaquePtr();
725d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor  }
726d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor  static inline clang::Selector getFromVoidPointer(const void *P) {
727d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor    return clang::Selector(reinterpret_cast<uintptr_t>(P));
728d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor  }
729d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor  enum { NumLowBitsAvailable = 0 };
730d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor};
73185994260c41a54cab061a434ed378fc448333a4eChris Lattner
7321734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor// Provide PointerLikeTypeTraits for IdentifierInfo pointers, which
7331734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor// are not guaranteed to be 8-byte aligned.
7341734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregortemplate<>
7351734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorclass PointerLikeTypeTraits<clang::IdentifierInfo*> {
7361734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorpublic:
7371734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  static inline void *getAsVoidPointer(clang::IdentifierInfo* P) {
7381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return P;
7391734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  }
7401734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  static inline clang::IdentifierInfo *getFromVoidPointer(void *P) {
7411734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    return static_cast<clang::IdentifierInfo*>(P);
7421734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  }
7431734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  enum { NumLowBitsAvailable = 1 };
7441734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor};
7451734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor
7461734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregortemplate<>
7471734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorclass PointerLikeTypeTraits<const clang::IdentifierInfo*> {
7481734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorpublic:
7491734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  static inline const void *getAsVoidPointer(const clang::IdentifierInfo* P) {
7501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return P;
7511734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  }
7521734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  static inline const clang::IdentifierInfo *getFromVoidPointer(const void *P) {
7531734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    return static_cast<const clang::IdentifierInfo*>(P);
7541734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  }
7551734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  enum { NumLowBitsAvailable = 1 };
7561734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor};
7571734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor
7582e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}  // end namespace llvm
7595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif
760