15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- IdentifierTable.cpp - Hash table for identifier lookup -----------===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file implements the IdentifierInfo, IdentifierVisitor, and
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// IdentifierTable interfaces.
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1580e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl#include "clang/Basic/CharInfo.h"
166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "clang/Basic/IdentifierTable.h"
17651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/Basic/LangOptions.h"
186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "clang/Basic/OperatorKinds.h"
1985994260c41a54cab061a434ed378fc448333a4eChris Lattner#include "llvm/ADT/DenseMap.h"
2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/ADT/FoldingSet.h"
216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/ADT/SmallString.h"
227530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie#include "llvm/Support/ErrorHandling.h"
2355fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/raw_ostream.h"
243daed52a57d03765223021f5f921bdc280c8f3ccChris Lattner#include <cstdio>
25c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek
265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang;
275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// IdentifierInfo Implementation
305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
32ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted KremenekIdentifierInfo::IdentifierInfo() {
335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  TokenID = tok::identifier;
345142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor  ObjCOrBuiltinID = 0;
354365a7e46822700357a272d839ee2656d9603d5aChris Lattner  HasMacro = false;
364d7e0ced7f16a04aabe2d8d91cbbb52fb1162810Alexander Kornienko  HadMacro = false;
375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  IsExtension = false;
3898d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith  IsCXX11CompatKeyword = false;
395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  IsPoisoned = false;
405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  IsCPPOperatorKeyword = false;
416a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner  NeedsHandleIdentifier = false;
423c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl  IsFromAST = false;
43eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  ChangedAfterLoad = false;
44646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis  RevertedTokenID = false;
45eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  OutOfDate = false;
4632ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek  IsModulesImport = false;
476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  FETokenInfo = nullptr;
486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Entry = nullptr;
495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// IdentifierTable Implementation
535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas GregorIdentifierIterator::~IdentifierIterator() { }
5695f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor
5772b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted KremenekIdentifierInfoLookup::~IdentifierInfoLookup() {}
5872b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek
5995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregornamespace {
6095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// \brief A simple identifier lookup iterator that represents an
6195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  /// empty sequence of identifiers.
6295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  class EmptyLookupIterator : public IdentifierIterator
6395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  {
6495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  public:
65651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    StringRef Next() override { return StringRef(); }
6695f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  };
6795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor}
6895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor
6987f9d81d0ab806dcf6ca50a0c068dcb2ba7f51b3Argyrios KyrtzidisIdentifierIterator *IdentifierInfoLookup::getIdentifiers() {
7095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  return new EmptyLookupIterator();
7195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor}
7295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor
738c5a760b82e73ed90b560090772db97e2ae27b09Douglas GregorExternalIdentifierLookup::~ExternalIdentifierLookup() {}
748c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
7572b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted KremenekIdentifierTable::IdentifierTable(const LangOptions &LangOpts,
7672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek                                 IdentifierInfoLookup* externalLookup)
7772b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  : HashTable(8192), // Start with space for 8K identifiers.
7872b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek    ExternalLookup(externalLookup) {
795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Populate the identifier table with info about keywords for the current
815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // language.
825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  AddKeywords(LangOpts);
83f15e1143dcb39396a1b62e509e59cacaabbc4880Ted Kremenek
84f15e1143dcb39396a1b62e509e59cacaabbc4880Ted Kremenek
85f15e1143dcb39396a1b62e509e59cacaabbc4880Ted Kremenek  // Add the '_experimental_modules_import' contextual keyword.
861b257afbae854c6817f26b7d61c4fed8ff7aebadDouglas Gregor  get("import").setModulesImport(true);
875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Language Keyword Implementation
915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
93eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman// Constants for TokenKinds.def
94eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedmannamespace {
95eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman  enum {
9667922922cf3d9a2c5b4a02b1ee27e81da3850b53Dylan Noblesmith    KEYC99 = 0x1,
9767922922cf3d9a2c5b4a02b1ee27e81da3850b53Dylan Noblesmith    KEYCXX = 0x2,
984e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith    KEYCXX11 = 0x4,
9967922922cf3d9a2c5b4a02b1ee27e81da3850b53Dylan Noblesmith    KEYGNU = 0x8,
10067922922cf3d9a2c5b4a02b1ee27e81da3850b53Dylan Noblesmith    KEYMS = 0x10,
10167922922cf3d9a2c5b4a02b1ee27e81da3850b53Dylan Noblesmith    BOOLSUPPORT = 0x20,
10267922922cf3d9a2c5b4a02b1ee27e81da3850b53Dylan Noblesmith    KEYALTIVEC = 0x40,
10367922922cf3d9a2c5b4a02b1ee27e81da3850b53Dylan Noblesmith    KEYNOCXX = 0x80,
10467922922cf3d9a2c5b4a02b1ee27e81da3850b53Dylan Noblesmith    KEYBORLAND = 0x100,
10567922922cf3d9a2c5b4a02b1ee27e81da3850b53Dylan Noblesmith    KEYOPENCL = 0x200,
106ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer    KEYC11 = 0x400,
107f85e193739c953358c865005855253af4f68a497John McCall    KEYARC = 0x800,
108a5a4cba88796cb1b8365ed523e8b6fdce9e512bdFrancois Pichet    KEYNOMS = 0x01000,
1095b86ffd219bdee7720217d5755b772726668b242Abramo Bagnara    WCHARSUPPORT = 0x02000,
110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    HALFSUPPORT = 0x04000,
111a5a4cba88796cb1b8365ed523e8b6fdce9e512bdFrancois Pichet    KEYALL = (0xffff & ~KEYNOMS) // Because KEYNOMS is used to exclude.
112eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman  };
113eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman}
114eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman
1155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// AddKeyword - This method is used to associate a token ID with specific
1165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// identifiers because they are language keywords.  This causes the lexer to
1175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// automatically map matching identifiers to specialized token codes.
1185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
11998d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith/// The C90/C99/CPP/CPP0x flags are set to 3 if the token is a keyword in a
12098d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith/// future language standard, set to 2 if the token should be enabled in the
1210be8fb5bdfe7e07a57f07a740649ec8bfb690284Nick Lewycky/// specified language, set to 1 if it is an extension in the specified
12298d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith/// language, and set to 0 if disabled in the specified language.
1235f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic void AddKeyword(StringRef Keyword,
124eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman                       tok::TokenKind TokenCode, unsigned Flags,
1255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                       const LangOptions &LangOpts, IdentifierTable &Table) {
126eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman  unsigned AddResult = 0;
12767922922cf3d9a2c5b4a02b1ee27e81da3850b53Dylan Noblesmith  if (Flags == KEYALL) AddResult = 2;
128eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman  else if (LangOpts.CPlusPlus && (Flags & KEYCXX)) AddResult = 2;
1294e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith  else if (LangOpts.CPlusPlus11 && (Flags & KEYCXX11)) AddResult = 2;
130eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman  else if (LangOpts.C99 && (Flags & KEYC99)) AddResult = 2;
131eb5d7b752651283de5abfcc2f91df7227582a08dChandler Carruth  else if (LangOpts.GNUKeywords && (Flags & KEYGNU)) AddResult = 1;
13262ec1f2fd7368542bb926c04797fb07023547694Francois Pichet  else if (LangOpts.MicrosoftExt && (Flags & KEYMS)) AddResult = 1;
13352fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  else if (LangOpts.Borland && (Flags & KEYBORLAND)) AddResult = 1;
134e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  else if (LangOpts.Bool && (Flags & BOOLSUPPORT)) AddResult = 2;
135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  else if (LangOpts.Half && (Flags & HALFSUPPORT)) AddResult = 2;
1365b86ffd219bdee7720217d5755b772726668b242Abramo Bagnara  else if (LangOpts.WChar && (Flags & WCHARSUPPORT)) AddResult = 2;
13782287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson  else if (LangOpts.AltiVec && (Flags & KEYALTIVEC)) AddResult = 2;
138f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  else if (LangOpts.OpenCL && (Flags & KEYOPENCL)) AddResult = 2;
1393a43d8df596a0af13379c3d2a78e2f7e7b156f30Douglas Gregor  else if (!LangOpts.CPlusPlus && (Flags & KEYNOCXX)) AddResult = 2;
140ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer  else if (LangOpts.C11 && (Flags & KEYC11)) AddResult = 2;
14100852e41261f9860233d3b407fce0506346cdacbFariborz Jahanian  // We treat bridge casts as objective-C keywords so we can warn on them
14200852e41261f9860233d3b407fce0506346cdacbFariborz Jahanian  // in non-arc mode.
14300852e41261f9860233d3b407fce0506346cdacbFariborz Jahanian  else if (LangOpts.ObjC2 && (Flags & KEYARC)) AddResult = 2;
1444e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith  else if (LangOpts.CPlusPlus && (Flags & KEYCXX11)) AddResult = 3;
14598d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith
146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Don't add this keyword under MSVCCompat.
147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (LangOpts.MSVCCompat && (Flags & KEYNOMS))
148dfd110ce5e64077ec94df195233e7a39895bf15eFrancois Pichet     return;
149eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman  // Don't add this keyword if disabled in this language.
150eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman  if (AddResult == 0) return;
151eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman
15298d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith  IdentifierInfo &Info =
15398d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith      Table.get(Keyword, AddResult == 3 ? tok::identifier : TokenCode);
154eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman  Info.setIsExtensionToken(AddResult == 1);
15598d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith  Info.setIsCXX11CompatKeyword(AddResult == 3);
1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// AddCXXOperatorKeyword - Register a C++ operator keyword alternative
1595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// representations.
1605f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic void AddCXXOperatorKeyword(StringRef Keyword,
1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                  tok::TokenKind TokenCode,
1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                  IdentifierTable &Table) {
163646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis  IdentifierInfo &Info = Table.get(Keyword, TokenCode);
164c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek  Info.setIsCPlusPlusOperatorKeyword();
1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1676557d1304c84233edd854288d4f80b987ad10ed9James Dennett/// AddObjCKeyword - Register an Objective-C \@keyword like "class" "selector"
1686557d1304c84233edd854288d4f80b987ad10ed9James Dennett/// or "property".
1695f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic void AddObjCKeyword(StringRef Name,
17050acf24b717a05a509e340f0ad0556de68fa4d5dKovarththanan Rajaratnam                           tok::ObjCKeywordKind ObjCID,
1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                           IdentifierTable &Table) {
17250acf24b717a05a509e340f0ad0556de68fa4d5dKovarththanan Rajaratnam  Table.get(Name).setObjCKeywordID(ObjCID);
1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// AddKeywords - Add all keywords to the symbol table.
1765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
1775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid IdentifierTable::AddKeywords(const LangOptions &LangOpts) {
1785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Add keywords and tokens for the current language.
1795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define KEYWORD(NAME, FLAGS) \
1805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  AddKeyword(StringRef(#NAME), tok::kw_ ## NAME,  \
181eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman             FLAGS, LangOpts, *this);
182eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman#define ALIAS(NAME, TOK, FLAGS) \
1835f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  AddKeyword(StringRef(NAME), tok::kw_ ## TOK,  \
184eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman             FLAGS, LangOpts, *this);
1855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \
1865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (LangOpts.CXXOperatorNames)          \
1875f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this);
1885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define OBJC1_AT_KEYWORD(NAME) \
1895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (LangOpts.ObjC1)          \
1905f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define OBJC2_AT_KEYWORD(NAME) \
1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (LangOpts.ObjC2)          \
1935f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
194a5fc472b353b88be3b4981da946fb01f5a5cc0c6John McCall#define TESTING_KEYWORD(NAME, FLAGS)
1955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/TokenKinds.def"
196a5fc472b353b88be3b4981da946fb01f5a5cc0c6John McCall
197a5fc472b353b88be3b4981da946fb01f5a5cc0c6John McCall  if (LangOpts.ParseUnknownAnytype)
198a5fc472b353b88be3b4981da946fb01f5a5cc0c6John McCall    AddKeyword("__unknown_anytype", tok::kw___unknown_anytype, KEYALL,
199a5fc472b353b88be3b4981da946fb01f5a5cc0c6John McCall               LangOpts, *this);
2005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
2015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
202387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattnertok::PPKeywordKind IdentifierInfo::getPPKeywordID() const {
203387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  // We use a perfect hash function here involving the length of the keyword,
204387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  // the first and third character.  For preprocessor ID's there are no
205387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  // collisions (if there were, the switch below would complain about duplicate
206387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  // case values).  Note that this depends on 'if' being null terminated.
2071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
208387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner#define HASH(LEN, FIRST, THIRD) \
209387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  (LEN << 5) + (((FIRST-'a') + (THIRD-'a')) & 31)
210387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner#define CASE(LEN, FIRST, THIRD, NAME) \
211387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  case HASH(LEN, FIRST, THIRD): \
212387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner    return memcmp(Name, #NAME, LEN) ? tok::pp_not_keyword : tok::pp_ ## NAME
2131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
214387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  unsigned Len = getLength();
215a31f030d5c2bca6567ecfc7fa9367aeb19de7037Chris Lattner  if (Len < 2) return tok::pp_not_keyword;
21676b61ccc603fad1c631948bf1e49f31343de76e9Daniel Dunbar  const char *Name = getNameStart();
217387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  switch (HASH(Len, Name[0], Name[2])) {
218387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  default: return tok::pp_not_keyword;
219387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  CASE( 2, 'i', '\0', if);
220387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  CASE( 4, 'e', 'i', elif);
221387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  CASE( 4, 'e', 's', else);
222387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  CASE( 4, 'l', 'n', line);
223387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  CASE( 4, 's', 'c', sccs);
224387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  CASE( 5, 'e', 'd', endif);
225387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  CASE( 5, 'e', 'r', error);
226387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  CASE( 5, 'i', 'e', ident);
227387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  CASE( 5, 'i', 'd', ifdef);
228387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  CASE( 5, 'u', 'd', undef);
229387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner
230387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  CASE( 6, 'a', 's', assert);
231387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  CASE( 6, 'd', 'f', define);
232387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  CASE( 6, 'i', 'n', ifndef);
233387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  CASE( 6, 'i', 'p', import);
234387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  CASE( 6, 'p', 'a', pragma);
23594ad28b31433058445a27db722f60402ee820beaDouglas Gregor
236387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  CASE( 7, 'd', 'f', defined);
237387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  CASE( 7, 'i', 'c', include);
238387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  CASE( 7, 'w', 'r', warning);
239387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner
240387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  CASE( 8, 'u', 'a', unassert);
241387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  CASE(12, 'i', 'c', include_next);
2421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2431ac13c37d8af0145b7e03fea70b7b1476b8828c9Douglas Gregor  CASE(14, '_', 'p', __public_macro);
2441ac13c37d8af0145b7e03fea70b7b1476b8828c9Douglas Gregor
2451ac13c37d8af0145b7e03fea70b7b1476b8828c9Douglas Gregor  CASE(15, '_', 'p', __private_macro);
2461ac13c37d8af0145b7e03fea70b7b1476b8828c9Douglas Gregor
247b8e240ed8b8f58c7b7fe82776bd6147b437f5d53Chris Lattner  CASE(16, '_', 'i', __include_macros);
248387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner#undef CASE
249387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner#undef HASH
250387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner  }
251387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner}
2525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
2545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Stats Implementation
2555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
2565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// PrintStats - Print statistics about how well the identifier table is doing
2585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// at hashing identifiers.
2595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid IdentifierTable::PrintStats() const {
2605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumBuckets = HashTable.getNumBuckets();
2615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumIdentifiers = HashTable.getNumItems();
2625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumEmptyBuckets = NumBuckets-NumIdentifiers;
2635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned AverageIdentifierSize = 0;
2645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned MaxIdentifierLength = 0;
2651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // TODO: Figure out maximum times an identifier had to probe for -stats.
267ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek  for (llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator>::const_iterator
2685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer       I = HashTable.begin(), E = HashTable.end(); I != E; ++I) {
2695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    unsigned IdLen = I->getKeyLength();
2705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    AverageIdentifierSize += IdLen;
2715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (MaxIdentifierLength < IdLen)
2725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      MaxIdentifierLength = IdLen;
2735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "\n*** Identifier Table Stats:\n");
2765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "# Identifiers:   %d\n", NumIdentifiers);
2775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "# Empty Buckets: %d\n", NumEmptyBuckets);
2785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "Hash density (#identifiers per bucket): %f\n",
2795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          NumIdentifiers/(double)NumBuckets);
2805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "Ave identifier length: %f\n",
2815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          (AverageIdentifierSize/(double)NumIdentifiers));
2825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "Max identifier length: %d\n", MaxIdentifierLength);
2831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Compute statistics about the memory allocated for identifiers.
2855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  HashTable.getAllocator().PrintStats();
2865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
28768d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff
28829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff//===----------------------------------------------------------------------===//
28929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff// SelectorTable Implementation
29029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff//===----------------------------------------------------------------------===//
29129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
29285994260c41a54cab061a434ed378fc448333a4eChris Lattnerunsigned llvm::DenseMapInfo<clang::Selector>::getHashValue(clang::Selector S) {
29385994260c41a54cab061a434ed378fc448333a4eChris Lattner  return DenseMapInfo<void*>::getHashValue(S.getAsOpaquePtr());
29485994260c41a54cab061a434ed378fc448333a4eChris Lattner}
29585994260c41a54cab061a434ed378fc448333a4eChris Lattner
2962e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregornamespace clang {
29729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// MultiKeywordSelector - One of these variable length records is kept for each
29829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// selector containing more than one keyword. We use a folding set
2991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// to unique aggregate names (keyword selectors in ObjC parlance). Access to
30029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// this class is provided strictly through Selector.
3011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass MultiKeywordSelector
3022e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  : public DeclarationNameExtra, public llvm::FoldingSetNode {
3032e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  MultiKeywordSelector(unsigned nKeys) {
3042e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    ExtraKindOrNumArgs = NUM_EXTRA_KINDS + nKeys;
3052e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  }
3061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumppublic:
30729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  // Constructor for keyword selectors.
30829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV) {
30929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff    assert((nKeys > 1) && "not a multi-keyword selector");
3102e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    ExtraKindOrNumArgs = NUM_EXTRA_KINDS + nKeys;
3111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
31229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff    // Fill in the trailing keyword array.
31329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff    IdentifierInfo **KeyInfo = reinterpret_cast<IdentifierInfo **>(this+1);
31429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff    for (unsigned i = 0; i != nKeys; ++i)
31529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff      KeyInfo[i] = IIV[i];
3161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
3171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
318f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner  // getName - Derive the full selector name and return it.
319f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner  std::string getName() const;
3201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3212e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  unsigned getNumArgs() const { return ExtraKindOrNumArgs - NUM_EXTRA_KINDS; }
3221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
32329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  typedef IdentifierInfo *const *keyword_iterator;
32429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  keyword_iterator keyword_begin() const {
32529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff    return reinterpret_cast<keyword_iterator>(this+1);
32629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  }
3271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  keyword_iterator keyword_end() const {
3281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return keyword_begin()+getNumArgs();
32929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  }
330f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner  IdentifierInfo *getIdentifierInfoForSlot(unsigned i) const {
3312e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    assert(i < getNumArgs() && "getIdentifierInfoForSlot(): illegal index");
33229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff    return keyword_begin()[i];
33329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  }
3341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void Profile(llvm::FoldingSetNodeID &ID,
33529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff                      keyword_iterator ArgTys, unsigned NumArgs) {
33629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff    ID.AddInteger(NumArgs);
337f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner    for (unsigned i = 0; i != NumArgs; ++i)
338f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner      ID.AddPointer(ArgTys[i]);
33929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  }
34029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  void Profile(llvm::FoldingSetNodeID &ID) {
3412e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    Profile(ID, keyword_begin(), getNumArgs());
34229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  }
34329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff};
34485994260c41a54cab061a434ed378fc448333a4eChris Lattner} // end namespace clang.
34529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
34629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffunsigned Selector::getNumArgs() const {
34729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  unsigned IIF = getIdentifierInfoFlag();
34851603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor  if (IIF <= ZeroArg)
34929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff    return 0;
35029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  if (IIF == OneArg)
35129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff    return 1;
35251603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor  // We point to a MultiKeywordSelector.
35351603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor  MultiKeywordSelector *SI = getMultiKeywordSelector();
3541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return SI->getNumArgs();
35529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff}
35629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
357f836e3fea2c77fdbb18170fb313ee0d45551320bChris LattnerIdentifierInfo *Selector::getIdentifierInfoForSlot(unsigned argIndex) const {
35851603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor  if (getIdentifierInfoFlag() < MultiArg) {
359f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner    assert(argIndex == 0 && "illegal keyword index");
360405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor    return getAsIdentifierInfo();
36129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  }
36251603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor  // We point to a MultiKeywordSelector.
36351603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor  MultiKeywordSelector *SI = getMultiKeywordSelector();
36429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  return SI->getIdentifierInfoForSlot(argIndex);
36529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff}
36629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
3675f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerStringRef Selector::getNameForSlot(unsigned int argIndex) const {
368813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor  IdentifierInfo *II = getIdentifierInfoForSlot(argIndex);
3695f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  return II? II->getName() : StringRef();
370813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor}
371813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor
372f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattnerstd::string MultiKeywordSelector::getName() const {
373f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<256> Str;
37476b61ccc603fad1c631948bf1e49f31343de76e9Daniel Dunbar  llvm::raw_svector_ostream OS(Str);
375f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner  for (keyword_iterator I = keyword_begin(), E = keyword_end(); I != E; ++I) {
376f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner    if (*I)
37701eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      OS << (*I)->getName();
37876b61ccc603fad1c631948bf1e49f31343de76e9Daniel Dunbar    OS << ':';
379f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner  }
3801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
38176b61ccc603fad1c631948bf1e49f31343de76e9Daniel Dunbar  return OS.str();
38229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff}
38329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
384077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattnerstd::string Selector::getAsString() const {
385405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor  if (InfoPtr == 0)
386405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor    return "<null selector>";
387405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor
38851603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor  if (getIdentifierInfoFlag() < MultiArg) {
389f5ed3961d21450c4fe98a00d7170da71b485328eTed Kremenek    IdentifierInfo *II = getAsIdentifierInfo();
3901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
391150ec292a6e7995a711cedbe7a10a25d664a6c6bTed Kremenek    // If the number of arguments is 0 then II is guaranteed to not be null.
392f5ed3961d21450c4fe98a00d7170da71b485328eTed Kremenek    if (getNumArgs() == 0)
39301eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      return II->getName();
39476b61ccc603fad1c631948bf1e49f31343de76e9Daniel Dunbar
39576b61ccc603fad1c631948bf1e49f31343de76e9Daniel Dunbar    if (!II)
39676b61ccc603fad1c631948bf1e49f31343de76e9Daniel Dunbar      return ":";
397f5ed3961d21450c4fe98a00d7170da71b485328eTed Kremenek
39801eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar    return II->getName().str() + ":";
39929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  }
4001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
40151603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor  // We have a multiple keyword selector.
40251603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor  return getMultiKeywordSelector()->getName();
40329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff}
40429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
405651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Selector::print(llvm::raw_ostream &OS) const {
406651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  OS << getAsString();
407651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
408651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
40985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// Interpreting the given string using the normal CamelCase
41085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// conventions, determine whether the given string starts with the
41185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// given "word", which is assumed to end in a lowercase letter.
4125f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic bool startsWithWord(StringRef name, StringRef word) {
41385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  if (name.size() < word.size()) return false;
4143f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose  return ((name.size() == word.size() || !isLowercase(name[word.size()])) &&
4153f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose          name.startswith(word));
41685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall}
41785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
41885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCallObjCMethodFamily Selector::getMethodFamilyImpl(Selector sel) {
41985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  IdentifierInfo *first = sel.getIdentifierInfoForSlot(0);
42085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  if (!first) return OMF_None;
42185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
4225f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef name = first->getName();
42385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  if (sel.isUnarySelector()) {
42485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    if (name == "autorelease") return OMF_autorelease;
42585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    if (name == "dealloc") return OMF_dealloc;
42680cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber    if (name == "finalize") return OMF_finalize;
42785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    if (name == "release") return OMF_release;
42885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    if (name == "retain") return OMF_retain;
42985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    if (name == "retainCount") return OMF_retainCount;
430926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    if (name == "self") return OMF_self;
43185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  }
4329670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian
4339670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian  if (name == "performSelector") return OMF_performSelector;
43485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
43585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // The other method families may begin with a prefix of underscores.
43685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  while (!name.empty() && name.front() == '_')
43785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    name = name.substr(1);
43885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
43985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  if (name.empty()) return OMF_None;
44085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  switch (name.front()) {
44185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  case 'a':
44285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    if (startsWithWord(name, "alloc")) return OMF_alloc;
44385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    break;
44485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  case 'c':
44585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    if (startsWithWord(name, "copy")) return OMF_copy;
44685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    break;
44785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  case 'i':
44885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    if (startsWithWord(name, "init")) return OMF_init;
44985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    break;
45085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  case 'm':
45185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    if (startsWithWord(name, "mutableCopy")) return OMF_mutableCopy;
45285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    break;
45385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  case 'n':
45485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    if (startsWithWord(name, "new")) return OMF_new;
45585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    break;
45685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  default:
45785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    break;
45885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  }
45985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
46085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  return OMF_None;
46185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall}
46229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
46311638f7b922aa0182ab2028ec819001ed2fe8085Fariborz JahanianObjCInstanceTypeFamily Selector::getInstTypeMethodFamily(Selector sel) {
4648d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian  IdentifierInfo *first = sel.getIdentifierInfoForSlot(0);
4658d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian  if (!first) return OIT_None;
4668d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian
4678d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian  StringRef name = first->getName();
4688d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian
4698d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian  if (name.empty()) return OIT_None;
4708d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian  switch (name.front()) {
4718d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian    case 'a':
472d0f2921c3211299a80c043a3251e6b34dddba061Fariborz Jahanian      if (startsWithWord(name, "array")) return OIT_Array;
4738d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian      break;
4748d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian    case 'd':
4759fcbd5e55a8029a0ca8a5d64457278ec716a8705Fariborz Jahanian      if (startsWithWord(name, "default")) return OIT_ReturnsSelf;
4768d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian      if (startsWithWord(name, "dictionary")) return OIT_Dictionary;
4778d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian      break;
4788d3794e06a63578093bd71c3c2520bd01e6197a3Fariborz Jahanian    case 's':
4799fcbd5e55a8029a0ca8a5d64457278ec716a8705Fariborz Jahanian      if (startsWithWord(name, "shared")) return OIT_ReturnsSelf;
4809fcbd5e55a8029a0ca8a5d64457278ec716a8705Fariborz Jahanian      if (startsWithWord(name, "standard")) return OIT_Singleton;
481a346eb1188419d3f1698092edfbd66890b74163cFariborz Jahanian    case 'i':
482a346eb1188419d3f1698092edfbd66890b74163cFariborz Jahanian      if (startsWithWord(name, "init")) return OIT_Init;
4838d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian    default:
4848d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian      break;
4858d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian  }
4868d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian  return OIT_None;
4878d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian}
4888d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian
4895f7d2284c4b2f08d155732454002e68dc40c33efChris Lattnernamespace {
4905f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner  struct SelectorTableImpl {
4915f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner    llvm::FoldingSet<MultiKeywordSelector> Table;
4925f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner    llvm::BumpPtrAllocator Allocator;
4935f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner  };
4945f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner} // end anonymous namespace.
4955f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner
4965f7d2284c4b2f08d155732454002e68dc40c33efChris Lattnerstatic SelectorTableImpl &getSelectorTableImpl(void *P) {
4975f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner  return *static_cast<SelectorTableImpl*>(P);
4985f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner}
4995f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner
5007044668ecb518496e463ea2dacae100d4badfd19Adrian PrantlSmallString<64>
50180e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian PrantlSelectorTable::constructSetterName(StringRef Name) {
5027044668ecb518496e463ea2dacae100d4badfd19Adrian Prantl  SmallString<64> SetterName("set");
5037044668ecb518496e463ea2dacae100d4badfd19Adrian Prantl  SetterName += Name;
5047044668ecb518496e463ea2dacae100d4badfd19Adrian Prantl  SetterName[3] = toUppercase(SetterName[3]);
5057044668ecb518496e463ea2dacae100d4badfd19Adrian Prantl  return SetterName;
50680e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl}
50780e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl
5087044668ecb518496e463ea2dacae100d4badfd19Adrian PrantlSelector
50980e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian PrantlSelectorTable::constructSetterSelector(IdentifierTable &Idents,
51080e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl                                       SelectorTable &SelTable,
51180e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl                                       const IdentifierInfo *Name) {
51280e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl  IdentifierInfo *SetterName =
51380e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl    &Idents.get(constructSetterName(Name->getName()));
5148fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer  return SelTable.getUnarySelector(SetterName);
5158fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer}
5168fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer
51797f55d6ffd548d1777d790c84b358030682f9de2Ted Kremeneksize_t SelectorTable::getTotalMemory() const {
51897f55d6ffd548d1777d790c84b358030682f9de2Ted Kremenek  SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl);
51997f55d6ffd548d1777d790c84b358030682f9de2Ted Kremenek  return SelTabImpl.Allocator.getTotalMemory();
52097f55d6ffd548d1777d790c84b358030682f9de2Ted Kremenek}
5215f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner
522ff38491c18b060526d754765b952f4a497a89416Chris LattnerSelector SelectorTable::getSelector(unsigned nKeys, IdentifierInfo **IIV) {
523ff38491c18b060526d754765b952f4a497a89416Chris Lattner  if (nKeys < 2)
524ff38491c18b060526d754765b952f4a497a89416Chris Lattner    return Selector(IIV[0], nKeys);
5251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5265f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner  SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl);
5271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
52829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  // Unique selector, to guarantee there is one per name.
52929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  llvm::FoldingSetNodeID ID;
53029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  MultiKeywordSelector::Profile(ID, IIV, nKeys);
53129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
5326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void *InsertPos = nullptr;
5335f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner  if (MultiKeywordSelector *SI =
5345f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner        SelTabImpl.Table.FindNodeOrInsertPos(ID, InsertPos))
53529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff    return Selector(SI);
5361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
53729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  // MultiKeywordSelector objects are not allocated with new because they have a
53829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  // variable size array (for parameter types) at the end of them.
5395f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner  unsigned Size = sizeof(MultiKeywordSelector) + nKeys*sizeof(IdentifierInfo *);
5405f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner  MultiKeywordSelector *SI =
5411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    (MultiKeywordSelector*)SelTabImpl.Allocator.Allocate(Size,
5423248854a5d16e1de17c58e05f726bdef9f042df2Chris Lattner                                         llvm::alignOf<MultiKeywordSelector>());
54329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  new (SI) MultiKeywordSelector(nKeys, IIV);
5445f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner  SelTabImpl.Table.InsertNode(SI, InsertPos);
54529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  return Selector(SI);
54629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff}
54729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
54829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve NaroffSelectorTable::SelectorTable() {
5495f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner  Impl = new SelectorTableImpl();
55029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff}
55129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
55229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve NaroffSelectorTable::~SelectorTable() {
5535f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner  delete &getSelectorTableImpl(Impl);
55429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff}
55529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff
556ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregorconst char *clang::getOperatorSpelling(OverloadedOperatorKind Operator) {
557ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor  switch (Operator) {
558ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor  case OO_None:
559ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor  case NUM_OVERLOADED_OPERATORS:
5606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
56150acf24b717a05a509e340f0ad0556de68fa4d5dKovarththanan Rajaratnam
562ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
563ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor  case OO_##Name: return Spelling;
564ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor#include "clang/Basic/OperatorKinds.def"
565ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor  }
56650acf24b717a05a509e340f0ad0556de68fa4d5dKovarththanan Rajaratnam
5677530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  llvm_unreachable("Invalid OverloadedOperatorKind!");
568ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor}
569