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