IdentifierTable.h revision 3e518bda00d710754ca077cf9be8dd821e16a854
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- IdentifierTable.h - Hash table for identifier lookup ---*- C++ -*-===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
10c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner// This file defines the IdentifierInfo, IdentifierTable, and Selector
11c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner// interfaces.
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
15c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
16c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
181cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor#include "clang/Basic/OperatorKinds.h"
195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/TokenKinds.h"
205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/StringMap.h"
2168d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff#include "llvm/ADT/SmallString.h"
2272b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek#include "llvm/ADT/OwningPtr.h"
231734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor#include "llvm/Support/PointerLikeTypeTraits.h"
241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#include <string>
251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#include <cassert>
265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2785994260c41a54cab061a434ed378fc448333a4eChris Lattnernamespace llvm {
2885994260c41a54cab061a434ed378fc448333a4eChris Lattner  template <typename T> struct DenseMapInfo;
2985994260c41a54cab061a434ed378fc448333a4eChris Lattner}
3029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang {
32ea684e699ea84e61711e279f5fa7a1b9f3d46bc2Cedric Venet  class LangOptions;
337caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner  class IdentifierInfo;
34ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek  class IdentifierTable;
357caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner  class SourceLocation;
362e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  class MultiKeywordSelector; // private class used by Selector
372e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  class DeclarationName;      // AST class that stores declaration names
382e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
397caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner  /// IdentifierLocPair - A simple pair of identifier info and location.
407caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner  typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair;
411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierInfo - One of these records is kept for each identifier that
445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is lexed.  This contains information about whether the token was #define'd,
455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is a language keyword, or if it is a front-end token of some sort (e.g. a
465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// variable or function name).  The preprocessor keeps this information in a
471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// set, and all tok::identifier tokens have a pointer to one of these.
485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierInfo {
498e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek  // Note: DON'T make TokenID a 'tok::TokenKind'; MSVC will treat it as a
508e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek  //       signed char and TokenKinds > 127 won't be handled correctly.
511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  unsigned TokenID            : 8; // Front-end token ID or tok::identifier.
525142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor  // Objective-C keyword ('protocol' in '@protocol') or builtin (__builtin_inf).
535142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor  // First NUM_OBJC_KEYWORDS values are for Objective-C, the remaining values
545142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor  // are for builtins.
551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  unsigned ObjCOrBuiltinID    :10;
564365a7e46822700357a272d839ee2656d9603d5aChris Lattner  bool HasMacro               : 1; // True if there is a #define for this.
575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool IsExtension            : 1; // True if identifier is a lang extension.
585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool IsPoisoned             : 1; // True if identifier is poisoned.
595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool IsCPPOperatorKeyword   : 1; // True if ident is a C++ operator keyword.
606a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  bool NeedsHandleIdentifier  : 1; // See "RecomputeNeedsHandleIdentifier".
6140b9b50b16e4728389bca78ded783d18d3adc1c9Ted Kremenek  // 9 bits left in 32-bit word.
625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void *FETokenInfo;               // Managed by the language front-end.
63ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek  llvm::StringMapEntry<IdentifierInfo*> *Entry;
641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  IdentifierInfo(const IdentifierInfo&);  // NONCOPYABLE.
664365a7e46822700357a272d839ee2656d9603d5aChris Lattner  void operator=(const IdentifierInfo&);  // NONASSIGNABLE.
67ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek
681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  friend class IdentifierTable;
69ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek
705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
71ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek  IdentifierInfo();
725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7492e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  /// isStr - Return true if this is the identifier for the specified string.
7592e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  /// This is intended to be used for string literals only: II->isStr("foo").
7692e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  template <std::size_t StrLen>
7792e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  bool isStr(const char (&Str)[StrLen]) const {
787fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar    return getLength() == StrLen-1 && !memcmp(getNameStart(), Str, StrLen-1);
79845222ccd992282bf74b2fca53e7c3b84a81c098Chris Lattner  }
801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
817fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar  /// getNameStart - Return the beginning of the actual string for this
827fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar  /// identifier.  The returned string is properly null terminated.
835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
847fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar  const char *getNameStart() const {
85ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    if (Entry) return Entry->getKeyData();
867e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek    // FIXME: This is gross. It would be best not to embed specific details
877e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek    // of the PTH file format here.
881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // The 'this' pointer really points to a
89ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    // std::pair<IdentifierInfo, const char*>, where internal pointer
90ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    // points to the external string data.
917e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek    return ((std::pair<IdentifierInfo, const char*>*) this)->second;
921f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner  }
931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
941f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner  /// getLength - Efficiently return the length of this identifier info.
951f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner  ///
961f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner  unsigned getLength() const {
97ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    if (Entry) return Entry->getKeyLength();
987e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek    // FIXME: This is gross. It would be best not to embed specific details
997e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek    // of the PTH file format here.
1001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // The 'this' pointer really points to a
101ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    // std::pair<IdentifierInfo, const char*>, where internal pointer
102ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    // points to the external string data.
1037e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek    const char* p = ((std::pair<IdentifierInfo, const char*>*) this)->second-2;
1047fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar    return (((unsigned) p[0]) | (((unsigned) p[1]) << 8)) - 1;
1057fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar  }
1067fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar
10701eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  /// getName - Return the actual identifier string.
10801eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  llvm::StringRef getName() const {
1097fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar    return llvm::StringRef(getNameStart(), getLength());
1105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1129c46de446d18f4a28446cb798d4131bd05515699Chris Lattner  /// hasMacroDefinition - Return true if this identifier is #defined to some
1139c46de446d18f4a28446cb798d4131bd05515699Chris Lattner  /// other value.
1149c46de446d18f4a28446cb798d4131bd05515699Chris Lattner  bool hasMacroDefinition() const {
1159c46de446d18f4a28446cb798d4131bd05515699Chris Lattner    return HasMacro;
1169c46de446d18f4a28446cb798d4131bd05515699Chris Lattner  }
1176a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  void setHasMacroDefinition(bool Val) {
1186a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    if (HasMacro == Val) return;
1191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1206a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    HasMacro = Val;
1216a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    if (Val)
1226a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      NeedsHandleIdentifier = 1;
1236a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    else
1246a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      RecomputeNeedsHandleIdentifier();
1256a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  }
1261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// get/setTokenID - If this is a source-language token (e.g. 'for'), this API
1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// can be used to cause the lexer to map identifiers to source-language
1295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// tokens.
1308e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek  tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; }
131863c486fcb6162495a94fddf7ac8409de2638995Chris Lattner  void setTokenID(tok::TokenKind ID) { TokenID = ID; }
1321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getPPKeywordID - Return the preprocessor keyword ID for this identifier.
1346d9a3e648d6bf6b347174152f191bd1377528f8cChris Lattner  /// For example, "define" will return tok::pp_define.
135387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  tok::PPKeywordKind getPPKeywordID() const;
1361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getObjCKeywordID - Return the Objective-C keyword ID for the this
1385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// identifier.  For example, 'class' will return tok::objc_class if ObjC is
1395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// enabled.
140ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  tok::ObjCKeywordKind getObjCKeywordID() const {
1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (ObjCOrBuiltinID < tok::NUM_OBJC_KEYWORDS)
1425142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor      return tok::ObjCKeywordKind(ObjCOrBuiltinID);
1435142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor    else
1445142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor      return tok::objc_not_keyword;
145ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  }
1465142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor  void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; }
1473251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor
1485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getBuiltinID - Return a value indicating whether this is a builtin
1495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// function.  0 is not-built-in.  1 is builtin-for-some-nonprimary-target.
1505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// 2+ are specific builtin functions.
1511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  unsigned getBuiltinID() const {
1525142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor    if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS)
1531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS;
1545142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor    else
1555142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor      return 0;
1565142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor  }
1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setBuiltinID(unsigned ID) {
1585142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor    ObjCOrBuiltinID = ID + tok::NUM_OBJC_KEYWORDS;
1591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS) == ID
1605142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor           && "ID too large for field!");
1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1623251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor
1633251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor  unsigned getObjCOrBuiltinID() const { return ObjCOrBuiltinID; }
1643251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor  void setObjCOrBuiltinID(unsigned ID) { ObjCOrBuiltinID = ID; }
1653251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor
1665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// get/setExtension - Initialize information about whether or not this
1675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// language token is an extension.  This controls extension warnings, and is
1685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// only valid if a custom token ID is set.
1695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isExtensionToken() const { return IsExtension; }
1706a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  void setIsExtensionToken(bool Val) {
1716a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    IsExtension = Val;
1726a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    if (Val)
1736a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      NeedsHandleIdentifier = 1;
1746a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    else
1756a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      RecomputeNeedsHandleIdentifier();
1766a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  }
1771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// setIsPoisoned - Mark this identifier as poisoned.  After poisoning, the
1795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Preprocessor will emit an error every time this token is used.
1806a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  void setIsPoisoned(bool Value = true) {
1816a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    IsPoisoned = Value;
1826a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    if (Value)
1836a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      NeedsHandleIdentifier = 1;
1846a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    else
1856a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      RecomputeNeedsHandleIdentifier();
1866a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  }
1871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isPoisoned - Return true if this token has been poisoned.
1895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isPoisoned() const { return IsPoisoned; }
1901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether
1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// this identifier is a C++ alternate representation of an operator.
1936a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  void setIsCPlusPlusOperatorKeyword(bool Val = true) {
1946a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    IsCPPOperatorKeyword = Val;
1956a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    if (Val)
1966a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      NeedsHandleIdentifier = 1;
1976a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    else
1986a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      RecomputeNeedsHandleIdentifier();
1996a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  }
2005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; }
2015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getFETokenInfo/setFETokenInfo - The language front-end is allowed to
2035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// associate arbitrary metadata with this token.
2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  template<typename T>
2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); }
2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setFETokenInfo(void *T) { FETokenInfo = T; }
2076a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner
2086a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// isHandleIdentifierCase - Return true if the Preprocessor::HandleIdentifier
2096a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// must be called on a token of this identifier.  If this returns false, we
2106a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// know that HandleIdentifier will not affect the token.
2116a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  bool isHandleIdentifierCase() const { return NeedsHandleIdentifier; }
2121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2136a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattnerprivate:
2146a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// RecomputeNeedsHandleIdentifier - The Preprocessor::HandleIdentifier does
2156a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// several special (but rare) things to identifiers of various sorts.  For
2166a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// example, it changes the "for" keyword token from tok::identifier to
2176a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// tok::for.
2186a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  ///
2196a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// This method is very tied to the definition of HandleIdentifier.  Any
2206a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// change to it should be reflected here.
2216a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  void RecomputeNeedsHandleIdentifier() {
2226a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    NeedsHandleIdentifier =
2236a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() |
224863c486fcb6162495a94fddf7ac8409de2638995Chris Lattner       isExtensionToken());
2256a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  }
2265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
2275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
22872b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek/// IdentifierInfoLookup - An abstract class used by IdentifierTable that
229668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor///  provides an interface for performing lookups from strings
23072b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek/// (const char *) to IdentiferInfo objects.
23172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenekclass IdentifierInfoLookup {
23272b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenekpublic:
23372b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  virtual ~IdentifierInfoLookup();
2341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23572b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  /// get - Return the identifier token info for the specified named identifier.
23672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  ///  Unlike the version in IdentifierTable, this returns a pointer instead
23772b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  ///  of a reference.  If the pointer is NULL then the IdentifierInfo cannot
23872b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  ///  be found.
239bfec576b1b8882b94670727cac2584b60962a607Daniel Dunbar  //
240bfec576b1b8882b94670727cac2584b60962a607Daniel Dunbar  // FIXME: Move to StringRef API.
24172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  virtual IdentifierInfo* get(const char *NameStart, const char *NameEnd) = 0;
2421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump};
2438c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
2448c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// \brief An abstract class used to resolve numerical identifier
2458c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// references (meaningful only to some external source) into
2468c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// IdentifierInfo pointers.
2478c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorclass ExternalIdentifierLookup {
2488c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorpublic:
2498c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  virtual ~ExternalIdentifierLookup();
2508c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
2518c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// \brief Return the identifier associated with the given ID number.
2528c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  ///
2538c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// The ID 0 is associated with the NULL identifier.
2548c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  virtual IdentifierInfo *GetIdentifier(unsigned ID) = 0;
2558c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor};
2568c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
2575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierTable - This table implements an efficient mapping from strings to
2585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IdentifierInfo nodes.  It has no other purpose, but this is an
2595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// extremely performance-critical piece of the code, as each occurrance of
2605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// every identifier goes through here when lexed.
2615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierTable {
2625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Shark shows that using MallocAllocator is *much* slower than using this
2635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // BumpPtrAllocator!
264ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek  typedef llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator> HashTableTy;
2655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  HashTableTy HashTable;
2661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
26772b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  IdentifierInfoLookup* ExternalLookup;
2681cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor
2695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
2705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// IdentifierTable ctor - Create the identifier table, populating it with
2715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// info about the language keywords for the language specified by LangOpts.
27272b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  IdentifierTable(const LangOptions &LangOpts,
27372b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek                  IdentifierInfoLookup* externalLookup = 0);
2741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
275668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor  /// \brief Set the external identifier lookup mechanism.
276668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor  void setExternalIdentifierLookup(IdentifierInfoLookup *IILookup) {
277668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor    ExternalLookup = IILookup;
278668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor  }
279668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor
28072b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  llvm::BumpPtrAllocator& getAllocator() {
28172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek    return HashTable.getAllocator();
28272b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  }
2831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// get - Return the identifier token info for the specified named identifier.
2855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
2865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  IdentifierInfo &get(const char *NameStart, const char *NameEnd) {
287ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    llvm::StringMapEntry<IdentifierInfo*> &Entry =
288a3824c6348794788094f8afa44dc1d2cf67ba440Chris Lattner      HashTable.GetOrCreateValue(NameStart, NameEnd);
2891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
290ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    IdentifierInfo *II = Entry.getValue();
291d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    if (II) return *II;
2921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
293d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    // No entry; if we have an external lookup, look there first.
294d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    if (ExternalLookup) {
295d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar      II = ExternalLookup->get(NameStart, NameEnd);
296d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar      if (II) {
297d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar        // Cache in the StringMap for subsequent lookups.
298d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar        Entry.setValue(II);
299d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar        return *II;
300ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek      }
301d42ffbd22fc7eb61321f6a88173ee424991f01c6Ted Kremenek    }
302ccb9bac3adb35a2dc78c1737e7b2dc6537a16393Daniel Dunbar
303d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    // Lookups failed, make a new IdentifierInfo.
304d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    void *Mem = getAllocator().Allocate<IdentifierInfo>();
305d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    II = new (Mem) IdentifierInfo();
306d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    Entry.setValue(II);
307d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar
308d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    // Make sure getName() knows how to find the IdentifierInfo
309d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    // contents.
310d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    II->Entry = &Entry;
311d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar
312ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    return *II;
3135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3155f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor  /// \brief Creates a new IdentifierInfo from the given string.
3165f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor  ///
3175f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor  /// This is a lower-level version of get() that requires that this
3185f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor  /// identifier not be known previously and that does not consult an
3195f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor  /// external source for identifiers. In particular, external
3205f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor  /// identifier sources can use this routine to build IdentifierInfo
3215f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor  /// nodes and then introduce additional information about those
3225f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor  /// identifiers.
3231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  IdentifierInfo &CreateIdentifierInfo(const char *NameStart,
3245f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor                                       const char *NameEnd) {
3255f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor    llvm::StringMapEntry<IdentifierInfo*> &Entry =
3265f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor      HashTable.GetOrCreateValue(NameStart, NameEnd);
3271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3285f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor    IdentifierInfo *II = Entry.getValue();
3295f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor    assert(!II && "IdentifierInfo already exists");
3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3315f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor    // Lookups failed, make a new IdentifierInfo.
3325f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor    void *Mem = getAllocator().Allocate<IdentifierInfo>();
3335f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor    II = new (Mem) IdentifierInfo();
3345f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor    Entry.setValue(II);
3355f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor
3365f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor    // Make sure getName() knows how to find the IdentifierInfo
3375f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor    // contents.
3385f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor    II->Entry = &Entry;
3395f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor
3405f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor    return *II;
3415f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor  }
34283885f7e3bf68d271e1e96726931814b836353a3Daniel Dunbar  IdentifierInfo &CreateIdentifierInfo(llvm::StringRef Name) {
34383885f7e3bf68d271e1e96726931814b836353a3Daniel Dunbar    return CreateIdentifierInfo(Name.begin(), Name.end());
34483885f7e3bf68d271e1e96726931814b836353a3Daniel Dunbar  }
3455f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor
34683885f7e3bf68d271e1e96726931814b836353a3Daniel Dunbar  IdentifierInfo &get(llvm::StringRef Name) {
347c2ff3f85481fbfa79f56a444b5726d4ab394bf4dBenjamin Kramer    return get(Name.begin(), Name.end());
3485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3491cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor
3505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef HashTableTy::const_iterator iterator;
3515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef HashTableTy::const_iterator const_iterator;
3521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  iterator begin() const { return HashTable.begin(); }
3545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  iterator end() const   { return HashTable.end(); }
355c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek  unsigned size() const { return HashTable.size(); }
3561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// PrintStats - Print some statistics to stderr that indicate how well the
3585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// hashing is doing.
3595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void PrintStats() const;
3601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void AddKeywords(const LangOptions &LangOpts);
3625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
3635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
36429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// Selector - This smart pointer class efficiently represents Objective-C
36529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// method names. This class will either point to an IdentifierInfo or a
36629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// MultiKeywordSelector (which is private). This enables us to optimize
3671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// selectors that take no arguments and selectors that take 1 argument, which
36829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// accounts for 78% of all selectors in Cocoa.h.
369bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroffclass Selector {
3708af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek  friend class DiagnosticInfo;
3711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
372bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  enum IdentifierInfoFlag {
3730e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    // MultiKeywordSelector = 0.
374bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    ZeroArg  = 0x1,
375bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    OneArg   = 0x2,
376bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    ArgFlags = ZeroArg|OneArg
377bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  };
378bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  uintptr_t InfoPtr; // a pointer to the MultiKeywordSelector or IdentifierInfo.
3791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
380bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  Selector(IdentifierInfo *II, unsigned nArgs) {
381bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    InfoPtr = reinterpret_cast<uintptr_t>(II);
3820e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
3830e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    assert(nArgs < 2 && "nArgs not equal to 0/1");
3840e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    InfoPtr |= nArgs+1;
385bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
386bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  Selector(MultiKeywordSelector *SI) {
387bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    InfoPtr = reinterpret_cast<uintptr_t>(SI);
3880e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
389bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
3901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
391bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  IdentifierInfo *getAsIdentifierInfo() const {
3920e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    if (getIdentifierInfoFlag())
393bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff      return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags);
394bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return 0;
395bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
396bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  unsigned getIdentifierInfoFlag() const {
397bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return InfoPtr & ArgFlags;
398bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
3998af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek
4008af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenekpublic:
4018af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek  friend class SelectorTable; // only the SelectorTable can create these
4028af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek  friend class DeclarationName; // and the AST's DeclarationName.
4038af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek
4048af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek  /// The default ctor should only be used when creating data structures that
4058af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek  ///  will contain selectors.
4068af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek  Selector() : InfoPtr(0) {}
40790cd1bb1baac2a0221f3642de0cbea3244b116e5Steve Naroff  Selector(uintptr_t V) : InfoPtr(V) {}
4088af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek
409bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  /// operator==/!= - Indicate whether the specified selectors are identical.
41097b7f26a92d87e514530a5b652460190ce48c974Ted Kremenek  bool operator==(Selector RHS) const {
411bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return InfoPtr == RHS.InfoPtr;
412bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
41397b7f26a92d87e514530a5b652460190ce48c974Ted Kremenek  bool operator!=(Selector RHS) const {
414bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return InfoPtr != RHS.InfoPtr;
415bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
416bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  void *getAsOpaquePtr() const {
417bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return reinterpret_cast<void*>(InfoPtr);
418bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
419405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor
420405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor  /// \brief Determine whether this is the empty selector.
421405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor  bool isNull() const { return InfoPtr == 0; }
422405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor
423bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  // Predicates to identify the selector type.
4241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool isKeywordSelector() const {
4251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return getIdentifierInfoFlag() != ZeroArg;
426bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
4271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool isUnarySelector() const {
428bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return getIdentifierInfoFlag() == ZeroArg;
429bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
4305b6b72f53ad164497cf62484b60cdbb4361f1978Steve Naroff  unsigned getNumArgs() const;
431f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner  IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const;
4321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
433077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner  /// getAsString - Derive the full selector name (e.g. "foo:bar:") and return
434077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner  /// it as an std::string.
435077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner  std::string getAsString() const;
4361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
43785994260c41a54cab061a434ed378fc448333a4eChris Lattner  static Selector getEmptyMarker() {
43885994260c41a54cab061a434ed378fc448333a4eChris Lattner    return Selector(uintptr_t(-1));
43985994260c41a54cab061a434ed378fc448333a4eChris Lattner  }
44085994260c41a54cab061a434ed378fc448333a4eChris Lattner  static Selector getTombstoneMarker() {
44185994260c41a54cab061a434ed378fc448333a4eChris Lattner    return Selector(uintptr_t(-2));
44285994260c41a54cab061a434ed378fc448333a4eChris Lattner  }
443bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff};
444bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff
44529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// SelectorTable - This table allows us to fully hide how we implement
44629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// multi-keyword caching.
44729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffclass SelectorTable {
4485f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner  void *Impl;  // Actually a SelectorTableImpl
44929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  SelectorTable(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT
45029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  void operator=(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT
45129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffpublic:
45229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  SelectorTable();
45329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  ~SelectorTable();
45429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
455ff38491c18b060526d754765b952f4a497a89416Chris Lattner  /// getSelector - This can create any sort of selector.  NumArgs indicates
456ff38491c18b060526d754765b952f4a497a89416Chris Lattner  /// whether this is a no argument selector "foo", a single argument selector
457ff38491c18b060526d754765b952f4a497a89416Chris Lattner  /// "foo:" or multi-argument "foo:bar:".
458ff38491c18b060526d754765b952f4a497a89416Chris Lattner  Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV);
4591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
460ff38491c18b060526d754765b952f4a497a89416Chris Lattner  Selector getUnarySelector(IdentifierInfo *ID) {
461ff38491c18b060526d754765b952f4a497a89416Chris Lattner    return Selector(ID, 1);
462ff38491c18b060526d754765b952f4a497a89416Chris Lattner  }
463ff38491c18b060526d754765b952f4a497a89416Chris Lattner  Selector getNullarySelector(IdentifierInfo *ID) {
464ff38491c18b060526d754765b952f4a497a89416Chris Lattner    return Selector(ID, 0);
465ff38491c18b060526d754765b952f4a497a89416Chris Lattner  }
46661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
46761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  /// constructSetterName - Return the setter name for the given
46861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  /// identifier, i.e. "set" + Name where the initial character of Name
46961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  /// has been capitalized.
470fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff  static Selector constructSetterName(IdentifierTable &Idents,
471fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff                                      SelectorTable &SelTable,
472fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff                                      const IdentifierInfo *Name) {
47361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    llvm::SmallString<100> SelectorName;
47461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    SelectorName = "set";
47501eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar    SelectorName += Name->getName();
47661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    SelectorName[3] = toupper(SelectorName[3]);
477beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad    IdentifierInfo *SetterName =
478beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad      &Idents.get(SelectorName.data(),
479beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad                  SelectorName.data() + SelectorName.size());
480fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff    return SelTable.getUnarySelector(SetterName);
48161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  }
48229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff};
48329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
484e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// DeclarationNameExtra - Common base of the MultiKeywordSelector,
485e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// CXXSpecialName, and CXXOperatorIdName classes, all of which are
486e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// private classes that describe different kinds of names.
4872e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorclass DeclarationNameExtra {
4882e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorpublic:
4892e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// ExtraKind - The kind of "extra" information stored in the
4902e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// DeclarationName. See @c ExtraKindOrNumArgs for an explanation of
4912e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// how these enumerator values are used.
4922e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  enum ExtraKind {
4932e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    CXXConstructor = 0,
4942e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    CXXDestructor,
4952e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    CXXConversionFunction,
496e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
497e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    CXXOperator##Name,
498e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor#include "clang/Basic/OperatorKinds.def"
4993e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt    CXXLiteralOperator,
5002a3009a432bdcec59e6383d7b2b17494d6f91649Douglas Gregor    CXXUsingDirective,
5012e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    NUM_EXTRA_KINDS
5022e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  };
5035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
504e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor  /// ExtraKindOrNumArgs - Either the kind of C++ special name or
505e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor  /// operator-id (if the value is one of the CXX* enumerators of
506e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor  /// ExtraKind), in which case the DeclarationNameExtra is also a
5073e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt  /// CXXSpecialName, (for CXXConstructor, CXXDestructor, or
5083e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt  /// CXXConversionFunction) CXXOperatorIdName, or CXXLiteralOperatorName,
5093e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt  /// it may be also name common to C++ using-directives (CXXUsingDirective),
5103e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt  /// otherwise it is NUM_EXTRA_KINDS+NumArgs, where NumArgs is the number of
5112e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// arguments in the Objective-C selector, in which case the
5122e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// DeclarationNameExtra is also a MultiKeywordSelector.
5132e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  unsigned ExtraKindOrNumArgs;
5142e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor};
5152e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
5162e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}  // end namespace clang
5174365a7e46822700357a272d839ee2656d9603d5aChris Lattner
5182e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregornamespace llvm {
5194365a7e46822700357a272d839ee2656d9603d5aChris Lattner/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and
5204365a7e46822700357a272d839ee2656d9603d5aChris Lattner/// DenseSets.
52185994260c41a54cab061a434ed378fc448333a4eChris Lattnertemplate <>
52285994260c41a54cab061a434ed378fc448333a4eChris Lattnerstruct DenseMapInfo<clang::Selector> {
52385994260c41a54cab061a434ed378fc448333a4eChris Lattner  static inline clang::Selector getEmptyKey() {
52485994260c41a54cab061a434ed378fc448333a4eChris Lattner    return clang::Selector::getEmptyMarker();
52585994260c41a54cab061a434ed378fc448333a4eChris Lattner  }
52685994260c41a54cab061a434ed378fc448333a4eChris Lattner  static inline clang::Selector getTombstoneKey() {
5271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return clang::Selector::getTombstoneMarker();
52885994260c41a54cab061a434ed378fc448333a4eChris Lattner  }
5291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
53085994260c41a54cab061a434ed378fc448333a4eChris Lattner  static unsigned getHashValue(clang::Selector S);
5311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
53285994260c41a54cab061a434ed378fc448333a4eChris Lattner  static bool isEqual(clang::Selector LHS, clang::Selector RHS) {
53385994260c41a54cab061a434ed378fc448333a4eChris Lattner    return LHS == RHS;
53485994260c41a54cab061a434ed378fc448333a4eChris Lattner  }
5351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
53685994260c41a54cab061a434ed378fc448333a4eChris Lattner  static bool isPod() { return true; }
53785994260c41a54cab061a434ed378fc448333a4eChris Lattner};
53885994260c41a54cab061a434ed378fc448333a4eChris Lattner
5391734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor// Provide PointerLikeTypeTraits for IdentifierInfo pointers, which
5401734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor// are not guaranteed to be 8-byte aligned.
5411734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregortemplate<>
5421734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorclass PointerLikeTypeTraits<clang::IdentifierInfo*> {
5431734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorpublic:
5441734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  static inline void *getAsVoidPointer(clang::IdentifierInfo* P) {
5451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return P;
5461734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  }
5471734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  static inline clang::IdentifierInfo *getFromVoidPointer(void *P) {
5481734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    return static_cast<clang::IdentifierInfo*>(P);
5491734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  }
5501734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  enum { NumLowBitsAvailable = 1 };
5511734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor};
5521734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor
5531734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregortemplate<>
5541734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorclass PointerLikeTypeTraits<const clang::IdentifierInfo*> {
5551734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorpublic:
5561734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  static inline const void *getAsVoidPointer(const clang::IdentifierInfo* P) {
5571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return P;
5581734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  }
5591734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  static inline const clang::IdentifierInfo *getFromVoidPointer(const void *P) {
5601734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    return static_cast<const clang::IdentifierInfo*>(P);
5611734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  }
5621734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  enum { NumLowBitsAvailable = 1 };
5631734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor};
5641734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor
5652e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}  // end namespace llvm
5665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif
567