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
191cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor#include "clang/Basic/OperatorKinds.h"
205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/TokenKinds.h"
21686775deca8b8685eb90801495880e3abdd844c2Chris Lattner#include "clang/Basic/LLVM.h"
225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/StringMap.h"
23700030ebddb987936d4fee14d9412821d96e4840Kovarththanan Rajaratnam#include "llvm/ADT/StringRef.h"
2472b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek#include "llvm/ADT/OwningPtr.h"
251734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor#include "llvm/Support/PointerLikeTypeTraits.h"
261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#include <cassert>
27403ba3522d1b1c97ae5fad81c1a2c4b3a754e1c1Nick Lewycky#include <string>
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2985994260c41a54cab061a434ed378fc448333a4eChris Lattnernamespace llvm {
3085994260c41a54cab061a434ed378fc448333a4eChris Lattner  template <typename T> struct DenseMapInfo;
3185994260c41a54cab061a434ed378fc448333a4eChris Lattner}
3229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang {
34ea684e699ea84e61711e279f5fa7a1b9f3d46bc2Cedric Venet  class LangOptions;
357caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner  class IdentifierInfo;
36ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek  class IdentifierTable;
377caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner  class SourceLocation;
382e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  class MultiKeywordSelector; // private class used by Selector
392e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  class DeclarationName;      // AST class that stores declaration names
402e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
41af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief A simple pair of identifier info and location.
427caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner  typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair;
431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
45af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// One of these records is kept for each identifier that
4655bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett/// is lexed.  This contains information about whether the token was \#define'd,
475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is a language keyword, or if it is a front-end token of some sort (e.g. a
485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// variable or function name).  The preprocessor keeps this information in a
491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// set, and all tok::identifier tokens have a pointer to one of these.
505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierInfo {
515cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  unsigned TokenID            : 9; // 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.
55c81ca9852806e75972bbb246fa916152e8fba541Ted Kremenek  unsigned ObjCOrBuiltinID    :11;
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.
5898d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith  bool IsCXX11CompatKeyword   : 1; // True if identifier is a keyword in C++11.
595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool IsPoisoned             : 1; // True if identifier is poisoned.
605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool IsCPPOperatorKeyword   : 1; // True if ident is a C++ operator keyword.
616a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  bool NeedsHandleIdentifier  : 1; // See "RecomputeNeedsHandleIdentifier".
62eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  bool IsFromAST              : 1; // True if identifier was loaded (at least
63eee242ff426bf79149f221798966e58688383c1eDouglas Gregor                                   // partially) from an AST file.
64eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  bool ChangedAfterLoad       : 1; // True if identifier has changed from the
65eee242ff426bf79149f221798966e58688383c1eDouglas Gregor                                   // definition loaded from an AST file.
66646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis  bool RevertedTokenID        : 1; // True if RevertTokenIDToIdentifier was
67646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis                                   // called.
68eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  bool OutOfDate              : 1; // True if there may be additional
69eee242ff426bf79149f221798966e58688383c1eDouglas Gregor                                   // information about this identifier
70eee242ff426bf79149f221798966e58688383c1eDouglas Gregor                                   // stored externally.
7155bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett  bool IsModulesImport        : 1; // True if this is the 'import' contextual
72c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor                                   // keyword.
73c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor  // 1 bit left in 32-bit word.
74eee242ff426bf79149f221798966e58688383c1eDouglas Gregor
755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void *FETokenInfo;               // Managed by the language front-end.
76ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek  llvm::StringMapEntry<IdentifierInfo*> *Entry;
771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  IdentifierInfo(const IdentifierInfo&);  // NONCOPYABLE.
794365a7e46822700357a272d839ee2656d9603d5aChris Lattner  void operator=(const IdentifierInfo&);  // NONASSIGNABLE.
80ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek
811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  friend class IdentifierTable;
82295a2a617ac335f590e430ab7fcd98f8ce109251Douglas Gregor
835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
84ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek  IdentifierInfo();
855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8755bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett  /// \brief Return true if this is the identifier for the specified string.
8855bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett  ///
8992e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  /// This is intended to be used for string literals only: II->isStr("foo").
9092e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  template <std::size_t StrLen>
9192e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  bool isStr(const char (&Str)[StrLen]) const {
927fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar    return getLength() == StrLen-1 && !memcmp(getNameStart(), Str, StrLen-1);
93845222ccd992282bf74b2fca53e7c3b84a81c098Chris Lattner  }
941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9555bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett  /// \brief Return the beginning of the actual null-terminated string for this
9655bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett  /// identifier.
975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
987fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar  const char *getNameStart() const {
99ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    if (Entry) return Entry->getKeyData();
1007e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek    // FIXME: This is gross. It would be best not to embed specific details
1017e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek    // of the PTH file format here.
1021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // The 'this' pointer really points to a
103ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    // std::pair<IdentifierInfo, const char*>, where internal pointer
104ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    // points to the external string data.
10540844a8b5a89676fb61898d61ea4a7fa98eb9b6bGabor Greif    typedef std::pair<IdentifierInfo, const char*> actualtype;
10640844a8b5a89676fb61898d61ea4a7fa98eb9b6bGabor Greif    return ((const actualtype*) this)->second;
1071f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner  }
1081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10955bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett  /// \brief Efficiently return the length of this identifier info.
1101f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner  ///
1111f945f632ae993bbb9f9e69d908f7526924c1a88Chris Lattner  unsigned getLength() const {
112ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    if (Entry) return Entry->getKeyLength();
1137e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek    // FIXME: This is gross. It would be best not to embed specific details
1147e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek    // of the PTH file format here.
1151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // The 'this' pointer really points to a
116ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    // std::pair<IdentifierInfo, const char*>, where internal pointer
117ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    // points to the external string data.
11840844a8b5a89676fb61898d61ea4a7fa98eb9b6bGabor Greif    typedef std::pair<IdentifierInfo, const char*> actualtype;
11940844a8b5a89676fb61898d61ea4a7fa98eb9b6bGabor Greif    const char* p = ((const actualtype*) this)->second - 2;
1207fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar    return (((unsigned) p[0]) | (((unsigned) p[1]) << 8)) - 1;
1217fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar  }
1227fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar
12355bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett  /// \brief Return the actual identifier string.
124686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  StringRef getName() const {
125686775deca8b8685eb90801495880e3abdd844c2Chris Lattner    return StringRef(getNameStart(), getLength());
1265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12855bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett  /// \brief Return true if this identifier is \#defined to some other value.
1299c46de446d18f4a28446cb798d4131bd05515699Chris Lattner  bool hasMacroDefinition() const {
1309c46de446d18f4a28446cb798d4131bd05515699Chris Lattner    return HasMacro;
1319c46de446d18f4a28446cb798d4131bd05515699Chris Lattner  }
1326a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  void setHasMacroDefinition(bool Val) {
1336a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    if (HasMacro == Val) return;
1341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1356a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    HasMacro = Val;
1366a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    if (Val)
1376a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      NeedsHandleIdentifier = 1;
1386a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    else
1396a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      RecomputeNeedsHandleIdentifier();
1406a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  }
1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
142646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis  /// getTokenID - If this is a source-language token (e.g. 'for'), this API
1435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// can be used to cause the lexer to map identifiers to source-language
1445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// tokens.
1458e748ab52395328f2905855b295a22e33dc800b2Ted Kremenek  tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; }
146646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis
147646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis  /// \brief True if RevertTokenIDToIdentifier() was called.
148646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis  bool hasRevertedTokenIDToIdentifier() const { return RevertedTokenID; }
149646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis
150646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis  /// \brief Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2
151f573084db5807f6003282bdf53ca9d58bab1ddc4Argyrios Kyrtzidis  /// compatibility.
152f573084db5807f6003282bdf53ca9d58bab1ddc4Argyrios Kyrtzidis  ///
153f573084db5807f6003282bdf53ca9d58bab1ddc4Argyrios Kyrtzidis  /// TokenID is normally read-only but there are 2 instances where we revert it
154f573084db5807f6003282bdf53ca9d58bab1ddc4Argyrios Kyrtzidis  /// to tok::identifier for libstdc++ 4.2. Keep track of when this happens
1553c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl  /// using this method so we can inform serialization about it.
156646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis  void RevertTokenIDToIdentifier() {
157646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis    assert(TokenID != tok::identifier && "Already at tok::identifier");
158646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis    TokenID = tok::identifier;
159646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis    RevertedTokenID = true;
160646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis  }
1611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16255bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett  /// \brief Return the preprocessor keyword ID for this identifier.
16355bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett  ///
1646d9a3e648d6bf6b347174152f191bd1377528f8cChris Lattner  /// For example, "define" will return tok::pp_define.
165387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  tok::PPKeywordKind getPPKeywordID() const;
1661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16755bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett  /// \brief Return the Objective-C keyword ID for the this identifier.
16855bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett  ///
16955bf69900afbd5dfb971c346b3712361e27e7b7fJames Dennett  /// For example, 'class' will return tok::objc_class if ObjC is enabled.
170ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  tok::ObjCKeywordKind getObjCKeywordID() const {
1711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (ObjCOrBuiltinID < tok::NUM_OBJC_KEYWORDS)
1725142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor      return tok::ObjCKeywordKind(ObjCOrBuiltinID);
1735142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor    else
1745142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor      return tok::objc_not_keyword;
175ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  }
1765142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor  void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; }
1773251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor
1785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getBuiltinID - Return a value indicating whether this is a builtin
1795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// function.  0 is not-built-in.  1 is builtin-for-some-nonprimary-target.
1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// 2+ are specific builtin functions.
1811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  unsigned getBuiltinID() const {
1825142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor    if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS)
1831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS;
1845142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor    else
1855142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor      return 0;
1865142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor  }
1875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setBuiltinID(unsigned ID) {
1885142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor    ObjCOrBuiltinID = ID + tok::NUM_OBJC_KEYWORDS;
1891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS) == ID
1905142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor           && "ID too large for field!");
1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1923251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor
1933251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor  unsigned getObjCOrBuiltinID() const { return ObjCOrBuiltinID; }
1943251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor  void setObjCOrBuiltinID(unsigned ID) { ObjCOrBuiltinID = ID; }
1953251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor
1965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// get/setExtension - Initialize information about whether or not this
1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// language token is an extension.  This controls extension warnings, and is
1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// only valid if a custom token ID is set.
1995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isExtensionToken() const { return IsExtension; }
2006a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  void setIsExtensionToken(bool Val) {
2016a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    IsExtension = Val;
2026a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    if (Val)
2036a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      NeedsHandleIdentifier = 1;
2046a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    else
2056a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      RecomputeNeedsHandleIdentifier();
2066a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  }
2071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20898d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith  /// is/setIsCXX11CompatKeyword - Initialize information about whether or not
20998d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith  /// this language token is a keyword in C++11. This controls compatibility
21098d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith  /// warnings, and is only true when not parsing C++11. Once a compatibility
21198d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith  /// problem has been diagnosed with this keyword, the flag will be cleared.
21298d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith  bool isCXX11CompatKeyword() const { return IsCXX11CompatKeyword; }
21398d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith  void setIsCXX11CompatKeyword(bool Val) {
21498d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith    IsCXX11CompatKeyword = Val;
21598d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith    if (Val)
21698d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith      NeedsHandleIdentifier = 1;
21798d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith    else
21898d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith      RecomputeNeedsHandleIdentifier();
21998d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith  }
22098d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith
2215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// setIsPoisoned - Mark this identifier as poisoned.  After poisoning, the
2225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Preprocessor will emit an error every time this token is used.
2236a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  void setIsPoisoned(bool Value = true) {
2246a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    IsPoisoned = Value;
2256a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    if (Value)
2266a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      NeedsHandleIdentifier = 1;
2276a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    else
2286a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      RecomputeNeedsHandleIdentifier();
2296a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  }
2301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isPoisoned - Return true if this token has been poisoned.
2325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isPoisoned() const { return IsPoisoned; }
2331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether
2355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// this identifier is a C++ alternate representation of an operator.
2366a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  void setIsCPlusPlusOperatorKeyword(bool Val = true) {
2376a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    IsCPPOperatorKeyword = Val;
2386a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    if (Val)
2396a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      NeedsHandleIdentifier = 1;
2406a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    else
2416a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      RecomputeNeedsHandleIdentifier();
2426a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  }
2435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; }
2445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getFETokenInfo/setFETokenInfo - The language front-end is allowed to
2465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// associate arbitrary metadata with this token.
2475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  template<typename T>
2485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); }
2495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setFETokenInfo(void *T) { FETokenInfo = T; }
2506a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner
2516a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// isHandleIdentifierCase - Return true if the Preprocessor::HandleIdentifier
2526a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// must be called on a token of this identifier.  If this returns false, we
2536a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// know that HandleIdentifier will not affect the token.
2546a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  bool isHandleIdentifierCase() const { return NeedsHandleIdentifier; }
2551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2563c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl  /// isFromAST - Return true if the identifier in its current state was loaded
2573c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl  /// from an AST file.
2583c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl  bool isFromAST() const { return IsFromAST; }
259ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl
260eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  void setIsFromAST() { IsFromAST = true; }
261eee242ff426bf79149f221798966e58688383c1eDouglas Gregor
262eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  /// \brief Determine whether this identifier has changed since it was loaded
263eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  /// from an AST file.
264eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  bool hasChangedSinceDeserialization() const {
265eee242ff426bf79149f221798966e58688383c1eDouglas Gregor    return ChangedAfterLoad;
266eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  }
267eee242ff426bf79149f221798966e58688383c1eDouglas Gregor
268eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  /// \brief Note that this identifier has changed since it was loaded from
269eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  /// an AST file.
270eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  void setChangedSinceDeserialization() {
271eee242ff426bf79149f221798966e58688383c1eDouglas Gregor    ChangedAfterLoad = true;
272eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  }
273ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl
274eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  /// \brief Determine whether the information for this identifier is out of
275eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  /// date with respect to the external source.
276eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  bool isOutOfDate() const { return OutOfDate; }
277eee242ff426bf79149f221798966e58688383c1eDouglas Gregor
278eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  /// \brief Set whether the information for this identifier is out of
279eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  /// date with respect to the external source.
280eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  void setOutOfDate(bool OOD) {
281eee242ff426bf79149f221798966e58688383c1eDouglas Gregor    OutOfDate = OOD;
282eee242ff426bf79149f221798966e58688383c1eDouglas Gregor    if (OOD)
283eee242ff426bf79149f221798966e58688383c1eDouglas Gregor      NeedsHandleIdentifier = true;
284eee242ff426bf79149f221798966e58688383c1eDouglas Gregor    else
285eee242ff426bf79149f221798966e58688383c1eDouglas Gregor      RecomputeNeedsHandleIdentifier();
286eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  }
287eee242ff426bf79149f221798966e58688383c1eDouglas Gregor
28832ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek  /// \brief Determine whether this is the contextual keyword
28932ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek  /// '__experimental_modules_import'.
29032ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek  bool isModulesImport() const { return IsModulesImport; }
291c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor
29232ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek  /// \brief Set whether this identifier is the contextual keyword
29332ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek  /// '__experimental_modules_import'.
29432ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek  void setModulesImport(bool I) {
29532ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek    IsModulesImport = I;
296c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor    if (I)
297c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor      NeedsHandleIdentifier = true;
298c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor    else
299c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor      RecomputeNeedsHandleIdentifier();
300c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor  }
301c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor
3026a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattnerprivate:
3036a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// RecomputeNeedsHandleIdentifier - The Preprocessor::HandleIdentifier does
3046a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// several special (but rare) things to identifiers of various sorts.  For
3056a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// example, it changes the "for" keyword token from tok::identifier to
3066a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// tok::for.
3076a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  ///
3086a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// This method is very tied to the definition of HandleIdentifier.  Any
3096a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  /// change to it should be reflected here.
3106a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  void RecomputeNeedsHandleIdentifier() {
3116a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner    NeedsHandleIdentifier =
3126a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner      (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() |
313eee242ff426bf79149f221798966e58688383c1eDouglas Gregor       isExtensionToken() | isCXX11CompatKeyword() || isOutOfDate() ||
31432ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek       isModulesImport());
3156a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  }
3165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
3175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
31828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// \brief an RAII object for [un]poisoning an identifier
31928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// within a certain scope. II is allowed to be null, in
32028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// which case, objects of this type have no effect.
32128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegleyclass PoisonIdentifierRAIIObject {
32228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  IdentifierInfo *const II;
32328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  const bool OldValue;
32428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegleypublic:
32528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  PoisonIdentifierRAIIObject(IdentifierInfo *II, bool NewValue)
32628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    : II(II), OldValue(II ? II->isPoisoned() : false) {
32728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    if(II)
32828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      II->setIsPoisoned(NewValue);
32928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  }
33028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
33128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  ~PoisonIdentifierRAIIObject() {
33228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    if(II)
33328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      II->setIsPoisoned(OldValue);
33428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  }
33528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley};
33628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
33795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// \brief An iterator that walks over all of the known identifiers
33895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// in the lookup table.
33995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor///
34095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// Since this iterator uses an abstract interface via virtual
34195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// functions, it uses an object-oriented interface rather than the
34295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// more standard C++ STL iterator interface. In this OO-style
34395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// iteration, the single function \c Next() provides dereference,
34495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// advance, and end-of-sequence checking in a single
34595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// operation. Subclasses of this iterator type will provide the
34695f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor/// actual functionality.
34795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregorclass IdentifierIterator {
34895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregorprivate:
34995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  IdentifierIterator(const IdentifierIterator&); // Do not implement
35095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  IdentifierIterator &operator=(const IdentifierIterator&); // Do not implement
35195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor
35295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregorprotected:
35395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  IdentifierIterator() { }
35495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor
35595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregorpublic:
35695f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  virtual ~IdentifierIterator();
35795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor
35895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// \brief Retrieve the next string in the identifier table and
35995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// advances the iterator for the following string.
36095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  ///
36195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// \returns The next string in the identifier table. If there is
362686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  /// no such string, returns an empty \c StringRef.
363686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  virtual StringRef Next() = 0;
36495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor};
36595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor
36672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek/// IdentifierInfoLookup - An abstract class used by IdentifierTable that
367668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor///  provides an interface for performing lookups from strings
36872b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek/// (const char *) to IdentiferInfo objects.
36972b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenekclass IdentifierInfoLookup {
37072b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenekpublic:
37172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  virtual ~IdentifierInfoLookup();
3721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
37372b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  /// get - Return the identifier token info for the specified named identifier.
37472b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  ///  Unlike the version in IdentifierTable, this returns a pointer instead
37572b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  ///  of a reference.  If the pointer is NULL then the IdentifierInfo cannot
37672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  ///  be found.
377686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  virtual IdentifierInfo* get(StringRef Name) = 0;
37895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor
37995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// \brief Retrieve an iterator into the set of all identifiers
38095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// known to this identifier lookup source.
38195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  ///
38295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// This routine provides access to all of the identifiers known to
38395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// the identifier lookup, allowing access to the contents of the
38495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// identifiers without introducing the overhead of constructing
38595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// IdentifierInfo objects for each.
38695f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  ///
38795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// \returns A new iterator into the set of known identifiers. The
38895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// caller is responsible for deleting this iterator.
38995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  virtual IdentifierIterator *getIdentifiers() const;
3901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump};
3918c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
3928c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// \brief An abstract class used to resolve numerical identifier
3938c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// references (meaningful only to some external source) into
3948c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor/// IdentifierInfo pointers.
3958c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorclass ExternalIdentifierLookup {
3968c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorpublic:
3978c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  virtual ~ExternalIdentifierLookup();
3988c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
3998c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// \brief Return the identifier associated with the given ID number.
4008c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  ///
4018c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// The ID 0 is associated with the NULL identifier.
4028c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  virtual IdentifierInfo *GetIdentifier(unsigned ID) = 0;
4038c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor};
4048c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
405af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// \brief Implements an efficient mapping from strings to IdentifierInfo nodes.
406af50aab0c317462129d73ae8000c6394c718598dJames Dennett///
407af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// This has no other purpose, but this is an extremely performance-critical
408af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// piece of the code, as each occurrence of every identifier goes through
409af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// here when lexed.
4105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierTable {
4115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Shark shows that using MallocAllocator is *much* slower than using this
4125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // BumpPtrAllocator!
413ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek  typedef llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator> HashTableTy;
4145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  HashTableTy HashTable;
4151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
41672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  IdentifierInfoLookup* ExternalLookup;
4171cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor
4185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
419af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Create the identifier table, populating it with info about the
420af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// language keywords for the language specified by \p LangOpts.
42172b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  IdentifierTable(const LangOptions &LangOpts,
42272b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek                  IdentifierInfoLookup* externalLookup = 0);
4231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
424668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor  /// \brief Set the external identifier lookup mechanism.
425668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor  void setExternalIdentifierLookup(IdentifierInfoLookup *IILookup) {
426668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor    ExternalLookup = IILookup;
427668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor  }
428668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor
42995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// \brief Retrieve the external identifier lookup object, if any.
43095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  IdentifierInfoLookup *getExternalIdentifierLookup() const {
43195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor    return ExternalLookup;
43295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  }
43395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor
43472b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  llvm::BumpPtrAllocator& getAllocator() {
43572b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek    return HashTable.getAllocator();
43672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  }
4371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
438af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Return the identifier token info for the specified named
439af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// identifier.
440686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  IdentifierInfo &get(StringRef Name) {
441ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    llvm::StringMapEntry<IdentifierInfo*> &Entry =
4426488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam      HashTable.GetOrCreateValue(Name);
4431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
444ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    IdentifierInfo *II = Entry.getValue();
445d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    if (II) return *II;
4461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
447d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    // No entry; if we have an external lookup, look there first.
448d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    if (ExternalLookup) {
4496488292f5e204fed99bb43ab23b8342ddc03ce89Kovarththanan Rajaratnam      II = ExternalLookup->get(Name);
450d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar      if (II) {
451d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar        // Cache in the StringMap for subsequent lookups.
452d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar        Entry.setValue(II);
453d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar        return *II;
454ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek      }
455d42ffbd22fc7eb61321f6a88173ee424991f01c6Ted Kremenek    }
456ccb9bac3adb35a2dc78c1737e7b2dc6537a16393Daniel Dunbar
457d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    // Lookups failed, make a new IdentifierInfo.
458d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    void *Mem = getAllocator().Allocate<IdentifierInfo>();
459d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    II = new (Mem) IdentifierInfo();
460d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    Entry.setValue(II);
461d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar
462d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    // Make sure getName() knows how to find the IdentifierInfo
463d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    // contents.
464d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar    II->Entry = &Entry;
465d43b333be82438102ff4c459b1fb5dfb764e5f0dDaniel Dunbar
466ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek    return *II;
4675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
469686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  IdentifierInfo &get(StringRef Name, tok::TokenKind TokenCode) {
470646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis    IdentifierInfo &II = get(Name);
471646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis    II.TokenID = TokenCode;
472d648d373d6c14dccadd3bef7b560f6a7296f949ePeter Collingbourne    assert(II.TokenID == (unsigned) TokenCode && "TokenCode too large");
473646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis    return II;
474646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis  }
475646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis
476ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl  /// \brief Gets an IdentifierInfo for the given name without consulting
477ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl  ///        external sources.
4785f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor  ///
479ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl  /// This is a version of get() meant for external sources that want to
480ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl  /// introduce or modify an identifier. If they called get(), they would
481ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl  /// likely end up in a recursion.
482686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  IdentifierInfo &getOwn(StringRef Name) {
4835f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor    llvm::StringMapEntry<IdentifierInfo*> &Entry =
48465aa6885818d4b4eea2e5a9d12085b2398148662Jay Foad      HashTable.GetOrCreateValue(Name);
4851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4865f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor    IdentifierInfo *II = Entry.getValue();
487ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl    if (!II) {
4881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
489ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl      // Lookups failed, make a new IdentifierInfo.
490ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl      void *Mem = getAllocator().Allocate<IdentifierInfo>();
491ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl      II = new (Mem) IdentifierInfo();
492ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl      Entry.setValue(II);
4935f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor
494ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl      // Make sure getName() knows how to find the IdentifierInfo
495ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl      // contents.
496ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl      II->Entry = &Entry;
497c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor
498c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor      // If this is the 'import' contextual keyword, mark it as such.
499c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor      if (Name.equals("import"))
50032ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek        II->setModulesImport(true);
501ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl    }
5025f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor
5035f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor    return *II;
5045f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor  }
5055f8e3302242cf94de2f8e46d10167f57fcf747c3Douglas Gregor
5065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef HashTableTy::const_iterator iterator;
5075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef HashTableTy::const_iterator const_iterator;
5081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  iterator begin() const { return HashTable.begin(); }
5105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  iterator end() const   { return HashTable.end(); }
511c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek  unsigned size() const { return HashTable.size(); }
5121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
513af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Print some statistics to stderr that indicate how well the
5145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// hashing is doing.
5155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void PrintStats() const;
5161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void AddKeywords(const LangOptions &LangOpts);
5185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
5195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
520af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// \brief A family of Objective-C methods.
521af50aab0c317462129d73ae8000c6394c718598dJames Dennett///
522af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// These families have no inherent meaning in the language, but are
52385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// nonetheless central enough in the existing implementations to
52485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// merit direct AST support.  While, in theory, arbitrary methods can
52585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// be considered to form families, we focus here on the methods
52685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// involving allocation and retain-count management, as these are the
52785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// most "core" and the most likely to be useful to diverse clients
52885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// without extra information.
52985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall///
53085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// Both selectors and actual method declarations may be classified
53185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// into families.  Method families may impose additional restrictions
53285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// beyond their selector name; for example, a method called '_init'
53385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// that returns void is not considered to be in the 'init' family
53485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// (but would be if it returned 'id').  It is also possible to
53585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// explicitly change or remove a method's family.  Therefore the
53685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// method's family should be considered the single source of truth.
53785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCallenum ObjCMethodFamily {
53885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  /// \brief No particular method family.
53985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_None,
54085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
54185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // Selectors in these families may have arbitrary arity, may be
54285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // written with arbitrary leading underscores, and may have
54385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // additional CamelCase "words" in their first selector chunk
54485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // following the family name.
54585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_alloc,
54685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_copy,
54785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_init,
54885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_mutableCopy,
54985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_new,
55085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
55185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // These families are singletons consisting only of the nullary
55285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // selector with the given name.
55385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_autorelease,
55485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_dealloc,
55580cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber  OMF_finalize,
55685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_release,
55785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  OMF_retain,
558926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  OMF_retainCount,
5599670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian  OMF_self,
5609670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian
5619670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian  // performSelector families
5629670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian  OMF_performSelector
56385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall};
56485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
56585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// Enough bits to store any enumerator in ObjCMethodFamily or
56685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// InvalidObjCMethodFamily.
56785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCallenum { ObjCMethodFamilyBitWidth = 4 };
56885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
569af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// \brief An invalid value of ObjCMethodFamily.
57085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCallenum { InvalidObjCMethodFamily = (1 << ObjCMethodFamilyBitWidth) - 1 };
57185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
572af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// \brief Smart pointer class that efficiently represents Objective-C method
573af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// names.
574af50aab0c317462129d73ae8000c6394c718598dJames Dennett///
575af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// This class will either point to an IdentifierInfo or a
57629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// MultiKeywordSelector (which is private). This enables us to optimize
5771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// selectors that take no arguments and selectors that take 1 argument, which
57829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// accounts for 78% of all selectors in Cocoa.h.
579bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroffclass Selector {
58040847cfb58acc3cac7d68727df9455ac45f2e118David Blaikie  friend class Diagnostic;
5811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
582bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  enum IdentifierInfoFlag {
58351603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor    // Empty selector = 0.
584bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    ZeroArg  = 0x1,
585bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    OneArg   = 0x2,
58651603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor    MultiArg = 0x3,
587bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    ArgFlags = ZeroArg|OneArg
588bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  };
589bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  uintptr_t InfoPtr; // a pointer to the MultiKeywordSelector or IdentifierInfo.
5901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
591bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  Selector(IdentifierInfo *II, unsigned nArgs) {
592bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    InfoPtr = reinterpret_cast<uintptr_t>(II);
5930e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
5940e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    assert(nArgs < 2 && "nArgs not equal to 0/1");
5950e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    InfoPtr |= nArgs+1;
596bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
597bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  Selector(MultiKeywordSelector *SI) {
598bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    InfoPtr = reinterpret_cast<uintptr_t>(SI);
5990e2dfd3963465d238e791eb8996e4d49fa47b615Chris Lattner    assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
60051603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor    InfoPtr |= MultiArg;
601bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
6021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
603bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  IdentifierInfo *getAsIdentifierInfo() const {
60451603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor    if (getIdentifierInfoFlag() < MultiArg)
605bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff      return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags);
606bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return 0;
607bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
60851603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor  MultiKeywordSelector *getMultiKeywordSelector() const {
60951603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor    return reinterpret_cast<MultiKeywordSelector *>(InfoPtr & ~ArgFlags);
61051603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor  }
61151603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor
612bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  unsigned getIdentifierInfoFlag() const {
613bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return InfoPtr & ArgFlags;
614bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
6158af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek
61685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  static ObjCMethodFamily getMethodFamilyImpl(Selector sel);
61785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
6188af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenekpublic:
6198af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek  friend class SelectorTable; // only the SelectorTable can create these
6208af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek  friend class DeclarationName; // and the AST's DeclarationName.
6218af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek
6228af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek  /// The default ctor should only be used when creating data structures that
6238af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek  ///  will contain selectors.
6248af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek  Selector() : InfoPtr(0) {}
62590cd1bb1baac2a0221f3642de0cbea3244b116e5Steve Naroff  Selector(uintptr_t V) : InfoPtr(V) {}
6268af2c16571f3aade6d47ce81fa3857d01d375719Ted Kremenek
627bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  /// operator==/!= - Indicate whether the specified selectors are identical.
62897b7f26a92d87e514530a5b652460190ce48c974Ted Kremenek  bool operator==(Selector RHS) const {
629bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return InfoPtr == RHS.InfoPtr;
630bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
63197b7f26a92d87e514530a5b652460190ce48c974Ted Kremenek  bool operator!=(Selector RHS) const {
632bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return InfoPtr != RHS.InfoPtr;
633bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
634bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  void *getAsOpaquePtr() const {
635bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return reinterpret_cast<void*>(InfoPtr);
636bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
637405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor
638405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor  /// \brief Determine whether this is the empty selector.
639405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor  bool isNull() const { return InfoPtr == 0; }
640405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor
641bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  // Predicates to identify the selector type.
6421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool isKeywordSelector() const {
6431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return getIdentifierInfoFlag() != ZeroArg;
644bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
6451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool isUnarySelector() const {
646bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff    return getIdentifierInfoFlag() == ZeroArg;
647bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff  }
6485b6b72f53ad164497cf62484b60cdbb4361f1978Steve Naroff  unsigned getNumArgs() const;
649813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor
650813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor
651813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// \brief Retrieve the identifier at a given position in the selector.
652813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  ///
653813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// Note that the identifier pointer returned may be NULL. Clients that only
654813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// care about the text of the identifier string, and not the specific,
655813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// uniqued identifier pointer, should use \c getNameForSlot(), which returns
656813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// an empty string when the identifier pointer would be NULL.
657813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  ///
658813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// \param argIndex The index for which we want to retrieve the identifier.
659813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// This index shall be less than \c getNumArgs() unless this is a keyword
660813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// selector, in which case 0 is the only permissible value.
661813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  ///
662813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// \returns the uniqued identifier for this slot, or NULL if this slot has
663813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// no corresponding identifier.
664f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner  IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const;
665813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor
666813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// \brief Retrieve the name at a given position in the selector.
667813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  ///
668813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// \param argIndex The index for which we want to retrieve the name.
669813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// This index shall be less than \c getNumArgs() unless this is a keyword
670813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// selector, in which case 0 is the only permissible value.
671813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  ///
672813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// \returns the name for this slot, which may be the empty string if no
673813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  /// name was supplied.
674686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  StringRef getNameForSlot(unsigned argIndex) const;
675813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor
676af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Derive the full selector name (e.g. "foo:bar:") and return
677077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner  /// it as an std::string.
6787ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  // FIXME: Add a print method that uses a raw_ostream.
679077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner  std::string getAsString() const;
6801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
681af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Derive the conventional family of this method.
68285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  ObjCMethodFamily getMethodFamily() const {
68385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    return getMethodFamilyImpl(*this);
68485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  }
68585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
68685994260c41a54cab061a434ed378fc448333a4eChris Lattner  static Selector getEmptyMarker() {
68785994260c41a54cab061a434ed378fc448333a4eChris Lattner    return Selector(uintptr_t(-1));
68885994260c41a54cab061a434ed378fc448333a4eChris Lattner  }
68985994260c41a54cab061a434ed378fc448333a4eChris Lattner  static Selector getTombstoneMarker() {
69085994260c41a54cab061a434ed378fc448333a4eChris Lattner    return Selector(uintptr_t(-2));
69185994260c41a54cab061a434ed378fc448333a4eChris Lattner  }
692bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff};
693bcfb06ac6da1aa3c74ac1ef7a49c2807522366e7Steve Naroff
694af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// \brief This table allows us to fully hide how we implement
69529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// multi-keyword caching.
69629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffclass SelectorTable {
6975f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner  void *Impl;  // Actually a SelectorTableImpl
69829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  SelectorTable(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT
69929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  void operator=(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT
70029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffpublic:
70129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  SelectorTable();
70229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  ~SelectorTable();
70329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
704af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Can create any sort of selector.
705af50aab0c317462129d73ae8000c6394c718598dJames Dennett  ///
706af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \p NumArgs indicates whether this is a no argument selector "foo", a
707af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// single argument selector "foo:" or multi-argument "foo:bar:".
708ff38491c18b060526d754765b952f4a497a89416Chris Lattner  Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV);
7091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
710ff38491c18b060526d754765b952f4a497a89416Chris Lattner  Selector getUnarySelector(IdentifierInfo *ID) {
711ff38491c18b060526d754765b952f4a497a89416Chris Lattner    return Selector(ID, 1);
712ff38491c18b060526d754765b952f4a497a89416Chris Lattner  }
713ff38491c18b060526d754765b952f4a497a89416Chris Lattner  Selector getNullarySelector(IdentifierInfo *ID) {
714ff38491c18b060526d754765b952f4a497a89416Chris Lattner    return Selector(ID, 0);
715ff38491c18b060526d754765b952f4a497a89416Chris Lattner  }
71661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
717af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Return the total amount of memory allocated for managing selectors.
71897f55d6ffd548d1777d790c84b358030682f9de2Ted Kremenek  size_t getTotalMemory() const;
71997f55d6ffd548d1777d790c84b358030682f9de2Ted Kremenek
720af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Return the setter name for the given identifier.
721af50aab0c317462129d73ae8000c6394c718598dJames Dennett  ///
722af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// This is "set" + \p Name where the initial character of \p Name
72361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  /// has been capitalized.
724fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff  static Selector constructSetterName(IdentifierTable &Idents,
725fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff                                      SelectorTable &SelTable,
7268fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer                                      const IdentifierInfo *Name);
72729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff};
72829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
729e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// DeclarationNameExtra - Common base of the MultiKeywordSelector,
730e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// CXXSpecialName, and CXXOperatorIdName classes, all of which are
731e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor/// private classes that describe different kinds of names.
7322e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorclass DeclarationNameExtra {
7332e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorpublic:
7342e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// ExtraKind - The kind of "extra" information stored in the
7352e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// DeclarationName. See @c ExtraKindOrNumArgs for an explanation of
7362e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// how these enumerator values are used.
7372e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  enum ExtraKind {
7382e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    CXXConstructor = 0,
7392e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    CXXDestructor,
7402e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    CXXConversionFunction,
741e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
742e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    CXXOperator##Name,
743e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor#include "clang/Basic/OperatorKinds.def"
7443e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt    CXXLiteralOperator,
7452a3009a432bdcec59e6383d7b2b17494d6f91649Douglas Gregor    CXXUsingDirective,
7462e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    NUM_EXTRA_KINDS
7472e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  };
7485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
749e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor  /// ExtraKindOrNumArgs - Either the kind of C++ special name or
750e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor  /// operator-id (if the value is one of the CXX* enumerators of
751e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor  /// ExtraKind), in which case the DeclarationNameExtra is also a
7523e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt  /// CXXSpecialName, (for CXXConstructor, CXXDestructor, or
7533e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt  /// CXXConversionFunction) CXXOperatorIdName, or CXXLiteralOperatorName,
7543e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt  /// it may be also name common to C++ using-directives (CXXUsingDirective),
7553e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt  /// otherwise it is NUM_EXTRA_KINDS+NumArgs, where NumArgs is the number of
7562e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// arguments in the Objective-C selector, in which case the
7572e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  /// DeclarationNameExtra is also a MultiKeywordSelector.
7582e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  unsigned ExtraKindOrNumArgs;
7592e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor};
7602e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
7612e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}  // end namespace clang
7624365a7e46822700357a272d839ee2656d9603d5aChris Lattner
7632e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregornamespace llvm {
7644365a7e46822700357a272d839ee2656d9603d5aChris Lattner/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and
7654365a7e46822700357a272d839ee2656d9603d5aChris Lattner/// DenseSets.
76685994260c41a54cab061a434ed378fc448333a4eChris Lattnertemplate <>
76785994260c41a54cab061a434ed378fc448333a4eChris Lattnerstruct DenseMapInfo<clang::Selector> {
76885994260c41a54cab061a434ed378fc448333a4eChris Lattner  static inline clang::Selector getEmptyKey() {
76985994260c41a54cab061a434ed378fc448333a4eChris Lattner    return clang::Selector::getEmptyMarker();
77085994260c41a54cab061a434ed378fc448333a4eChris Lattner  }
77185994260c41a54cab061a434ed378fc448333a4eChris Lattner  static inline clang::Selector getTombstoneKey() {
7721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return clang::Selector::getTombstoneMarker();
77385994260c41a54cab061a434ed378fc448333a4eChris Lattner  }
7741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
77585994260c41a54cab061a434ed378fc448333a4eChris Lattner  static unsigned getHashValue(clang::Selector S);
7761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
77785994260c41a54cab061a434ed378fc448333a4eChris Lattner  static bool isEqual(clang::Selector LHS, clang::Selector RHS) {
77885994260c41a54cab061a434ed378fc448333a4eChris Lattner    return LHS == RHS;
77985994260c41a54cab061a434ed378fc448333a4eChris Lattner  }
78085994260c41a54cab061a434ed378fc448333a4eChris Lattner};
781700030ebddb987936d4fee14d9412821d96e4840Kovarththanan Rajaratnam
78206159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnertemplate <>
78306159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnerstruct isPodLike<clang::Selector> { static const bool value = true; };
78406159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner
785d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregortemplate<>
786d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregorclass PointerLikeTypeTraits<clang::Selector> {
787d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregorpublic:
788d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor  static inline const void *getAsVoidPointer(clang::Selector P) {
789d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor    return P.getAsOpaquePtr();
790d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor  }
791d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor  static inline clang::Selector getFromVoidPointer(const void *P) {
792d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor    return clang::Selector(reinterpret_cast<uintptr_t>(P));
793d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor  }
794d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor  enum { NumLowBitsAvailable = 0 };
795d36adf553cd71df96fe869204482e0f0d68c6bbfDouglas Gregor};
79685994260c41a54cab061a434ed378fc448333a4eChris Lattner
7971734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor// Provide PointerLikeTypeTraits for IdentifierInfo pointers, which
7981734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor// are not guaranteed to be 8-byte aligned.
7991734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregortemplate<>
8001734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorclass PointerLikeTypeTraits<clang::IdentifierInfo*> {
8011734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorpublic:
8021734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  static inline void *getAsVoidPointer(clang::IdentifierInfo* P) {
8031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return P;
8041734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  }
8051734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  static inline clang::IdentifierInfo *getFromVoidPointer(void *P) {
8061734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    return static_cast<clang::IdentifierInfo*>(P);
8071734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  }
8081734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  enum { NumLowBitsAvailable = 1 };
8091734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor};
8101734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor
8111734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregortemplate<>
8121734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorclass PointerLikeTypeTraits<const clang::IdentifierInfo*> {
8131734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregorpublic:
8141734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  static inline const void *getAsVoidPointer(const clang::IdentifierInfo* P) {
8151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return P;
8161734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  }
8171734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  static inline const clang::IdentifierInfo *getFromVoidPointer(const void *P) {
8181734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    return static_cast<const clang::IdentifierInfo*>(P);
8191734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  }
8201734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  enum { NumLowBitsAvailable = 1 };
8211734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor};
8221734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor
8232e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}  // end namespace llvm
8245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif
825