clang  8.0.0svn
IdentifierTable.cpp
Go to the documentation of this file.
1 //===- IdentifierTable.cpp - Hash table for identifier lookup -------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the IdentifierInfo, IdentifierVisitor, and
11 // IdentifierTable interfaces.
12 //
13 //===----------------------------------------------------------------------===//
14 
16 #include "clang/Basic/CharInfo.h"
19 #include "clang/Basic/Specifiers.h"
20 #include "clang/Basic/TokenKinds.h"
21 #include "llvm/ADT/DenseMapInfo.h"
22 #include "llvm/ADT/FoldingSet.h"
23 #include "llvm/ADT/SmallString.h"
24 #include "llvm/ADT/StringMap.h"
25 #include "llvm/ADT/StringRef.h"
26 #include "llvm/Support/Allocator.h"
27 #include "llvm/Support/ErrorHandling.h"
28 #include "llvm/Support/raw_ostream.h"
29 #include <cassert>
30 #include <cstdio>
31 #include <cstring>
32 #include <string>
33 
34 using namespace clang;
35 
36 //===----------------------------------------------------------------------===//
37 // IdentifierInfo Implementation
38 //===----------------------------------------------------------------------===//
39 
41  TokenID = tok::identifier;
42  ObjCOrBuiltinID = 0;
43  HasMacro = false;
44  HadMacro = false;
45  IsExtension = false;
46  IsFutureCompatKeyword = false;
47  IsPoisoned = false;
48  IsCPPOperatorKeyword = false;
49  NeedsHandleIdentifier = false;
50  IsFromAST = false;
51  ChangedAfterLoad = false;
52  FEChangedAfterLoad = false;
53  RevertedTokenID = false;
54  OutOfDate = false;
55  IsModulesImport = false;
56 }
57 
58 //===----------------------------------------------------------------------===//
59 // IdentifierTable Implementation
60 //===----------------------------------------------------------------------===//
61 
63 
65 
66 namespace {
67 
68 /// A simple identifier lookup iterator that represents an
69 /// empty sequence of identifiers.
70 class EmptyLookupIterator : public IdentifierIterator
71 {
72 public:
73  StringRef Next() override { return StringRef(); }
74 };
75 
76 } // namespace
77 
79  return new EmptyLookupIterator();
80 }
81 
83  : HashTable(8192), // Start with space for 8K identifiers.
84  ExternalLookup(ExternalLookup) {}
85 
87  IdentifierInfoLookup *ExternalLookup)
88  : IdentifierTable(ExternalLookup) {
89  // Populate the identifier table with info about keywords for the current
90  // language.
91  AddKeywords(LangOpts);
92 }
93 
94 //===----------------------------------------------------------------------===//
95 // Language Keyword Implementation
96 //===----------------------------------------------------------------------===//
97 
98 // Constants for TokenKinds.def
99 namespace {
100 
101  enum {
102  KEYC99 = 0x1,
103  KEYCXX = 0x2,
104  KEYCXX11 = 0x4,
105  KEYGNU = 0x8,
106  KEYMS = 0x10,
107  BOOLSUPPORT = 0x20,
108  KEYALTIVEC = 0x40,
109  KEYNOCXX = 0x80,
110  KEYBORLAND = 0x100,
111  KEYOPENCLC = 0x200,
112  KEYC11 = 0x400,
113  KEYARC = 0x800,
114  KEYNOMS18 = 0x01000,
115  KEYNOOPENCL = 0x02000,
116  WCHARSUPPORT = 0x04000,
117  HALFSUPPORT = 0x08000,
118  CHAR8SUPPORT = 0x10000,
119  KEYCONCEPTS = 0x20000,
120  KEYOBJC2 = 0x40000,
121  KEYZVECTOR = 0x80000,
122  KEYCOROUTINES = 0x100000,
123  KEYMODULES = 0x200000,
124  KEYCXX2A = 0x400000,
125  KEYOPENCLCXX = 0x800000,
126  KEYALLCXX = KEYCXX | KEYCXX11 | KEYCXX2A,
127  KEYALL = (0xffffff & ~KEYNOMS18 &
128  ~KEYNOOPENCL) // KEYNOMS18 and KEYNOOPENCL are used to exclude.
129  };
130 
131  /// How a keyword is treated in the selected standard.
133  KS_Disabled, // Disabled
134  KS_Extension, // Is an extension
135  KS_Enabled, // Enabled
136  KS_Future // Is a keyword in future standard
137  };
138 
139 } // namespace
140 
141 /// Translates flags as specified in TokenKinds.def into keyword status
142 /// in the given language standard.
144  unsigned Flags) {
145  if (Flags == KEYALL) return KS_Enabled;
146  if (LangOpts.CPlusPlus && (Flags & KEYCXX)) return KS_Enabled;
147  if (LangOpts.CPlusPlus11 && (Flags & KEYCXX11)) return KS_Enabled;
148  if (LangOpts.CPlusPlus2a && (Flags & KEYCXX2A)) return KS_Enabled;
149  if (LangOpts.C99 && (Flags & KEYC99)) return KS_Enabled;
150  if (LangOpts.GNUKeywords && (Flags & KEYGNU)) return KS_Extension;
151  if (LangOpts.MicrosoftExt && (Flags & KEYMS)) return KS_Extension;
152  if (LangOpts.Borland && (Flags & KEYBORLAND)) return KS_Extension;
153  if (LangOpts.Bool && (Flags & BOOLSUPPORT)) return KS_Enabled;
154  if (LangOpts.Half && (Flags & HALFSUPPORT)) return KS_Enabled;
155  if (LangOpts.WChar && (Flags & WCHARSUPPORT)) return KS_Enabled;
156  if (LangOpts.Char8 && (Flags & CHAR8SUPPORT)) return KS_Enabled;
157  if (LangOpts.AltiVec && (Flags & KEYALTIVEC)) return KS_Enabled;
158  if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus && (Flags & KEYOPENCLC))
159  return KS_Enabled;
160  if (LangOpts.OpenCLCPlusPlus && (Flags & KEYOPENCLCXX)) return KS_Enabled;
161  if (!LangOpts.CPlusPlus && (Flags & KEYNOCXX)) return KS_Enabled;
162  if (LangOpts.C11 && (Flags & KEYC11)) return KS_Enabled;
163  // We treat bridge casts as objective-C keywords so we can warn on them
164  // in non-arc mode.
165  if (LangOpts.ObjC2 && (Flags & KEYARC)) return KS_Enabled;
166  if (LangOpts.ObjC2 && (Flags & KEYOBJC2)) return KS_Enabled;
167  if (LangOpts.ConceptsTS && (Flags & KEYCONCEPTS)) return KS_Enabled;
168  if (LangOpts.CoroutinesTS && (Flags & KEYCOROUTINES)) return KS_Enabled;
169  if (LangOpts.ModulesTS && (Flags & KEYMODULES)) return KS_Enabled;
170  if (LangOpts.CPlusPlus && (Flags & KEYALLCXX)) return KS_Future;
171  return KS_Disabled;
172 }
173 
174 /// AddKeyword - This method is used to associate a token ID with specific
175 /// identifiers because they are language keywords. This causes the lexer to
176 /// automatically map matching identifiers to specialized token codes.
177 static void AddKeyword(StringRef Keyword,
178  tok::TokenKind TokenCode, unsigned Flags,
179  const LangOptions &LangOpts, IdentifierTable &Table) {
180  KeywordStatus AddResult = getKeywordStatus(LangOpts, Flags);
181 
182  // Don't add this keyword under MSVCCompat.
183  if (LangOpts.MSVCCompat && (Flags & KEYNOMS18) &&
185  return;
186 
187  // Don't add this keyword under OpenCL.
188  if (LangOpts.OpenCL && (Flags & KEYNOOPENCL))
189  return;
190 
191  // Don't add this keyword if disabled in this language.
192  if (AddResult == KS_Disabled) return;
193 
194  IdentifierInfo &Info =
195  Table.get(Keyword, AddResult == KS_Future ? tok::identifier : TokenCode);
196  Info.setIsExtensionToken(AddResult == KS_Extension);
197  Info.setIsFutureCompatKeyword(AddResult == KS_Future);
198 }
199 
200 /// AddCXXOperatorKeyword - Register a C++ operator keyword alternative
201 /// representations.
202 static void AddCXXOperatorKeyword(StringRef Keyword,
203  tok::TokenKind TokenCode,
204  IdentifierTable &Table) {
205  IdentifierInfo &Info = Table.get(Keyword, TokenCode);
207 }
208 
209 /// AddObjCKeyword - Register an Objective-C \@keyword like "class" "selector"
210 /// or "property".
211 static void AddObjCKeyword(StringRef Name,
212  tok::ObjCKeywordKind ObjCID,
213  IdentifierTable &Table) {
214  Table.get(Name).setObjCKeywordID(ObjCID);
215 }
216 
217 /// AddKeywords - Add all keywords to the symbol table.
218 ///
220  // Add keywords and tokens for the current language.
221 #define KEYWORD(NAME, FLAGS) \
222  AddKeyword(StringRef(#NAME), tok::kw_ ## NAME, \
223  FLAGS, LangOpts, *this);
224 #define ALIAS(NAME, TOK, FLAGS) \
225  AddKeyword(StringRef(NAME), tok::kw_ ## TOK, \
226  FLAGS, LangOpts, *this);
227 #define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \
228  if (LangOpts.CXXOperatorNames) \
229  AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this);
230 #define OBJC1_AT_KEYWORD(NAME) \
231  if (LangOpts.ObjC1) \
232  AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
233 #define OBJC2_AT_KEYWORD(NAME) \
234  if (LangOpts.ObjC2) \
235  AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
236 #define TESTING_KEYWORD(NAME, FLAGS)
237 #include "clang/Basic/TokenKinds.def"
238 
239  if (LangOpts.ParseUnknownAnytype)
240  AddKeyword("__unknown_anytype", tok::kw___unknown_anytype, KEYALL,
241  LangOpts, *this);
242 
243  if (LangOpts.DeclSpecKeyword)
244  AddKeyword("__declspec", tok::kw___declspec, KEYALL, LangOpts, *this);
245 
246  // Add the '_experimental_modules_import' contextual keyword.
247  get("import").setModulesImport(true);
248 }
249 
250 /// Checks if the specified token kind represents a keyword in the
251 /// specified language.
252 /// \returns Status of the keyword in the language.
254  tok::TokenKind K) {
255  switch (K) {
256 #define KEYWORD(NAME, FLAGS) \
257  case tok::kw_##NAME: return getKeywordStatus(LangOpts, FLAGS);
258 #include "clang/Basic/TokenKinds.def"
259  default: return KS_Disabled;
260  }
261 }
262 
263 /// Returns true if the identifier represents a keyword in the
264 /// specified language.
265 bool IdentifierInfo::isKeyword(const LangOptions &LangOpts) const {
266  switch (getTokenKwStatus(LangOpts, getTokenID())) {
267  case KS_Enabled:
268  case KS_Extension:
269  return true;
270  default:
271  return false;
272  }
273 }
274 
275 /// Returns true if the identifier represents a C++ keyword in the
276 /// specified language.
277 bool IdentifierInfo::isCPlusPlusKeyword(const LangOptions &LangOpts) const {
278  if (!LangOpts.CPlusPlus || !isKeyword(LangOpts))
279  return false;
280  // This is a C++ keyword if this identifier is not a keyword when checked
281  // using LangOptions without C++ support.
282  LangOptions LangOptsNoCPP = LangOpts;
283  LangOptsNoCPP.CPlusPlus = false;
284  LangOptsNoCPP.CPlusPlus11 = false;
285  LangOptsNoCPP.CPlusPlus2a = false;
286  return !isKeyword(LangOptsNoCPP);
287 }
288 
290  // We use a perfect hash function here involving the length of the keyword,
291  // the first and third character. For preprocessor ID's there are no
292  // collisions (if there were, the switch below would complain about duplicate
293  // case values). Note that this depends on 'if' being null terminated.
294 
295 #define HASH(LEN, FIRST, THIRD) \
296  (LEN << 5) + (((FIRST-'a') + (THIRD-'a')) & 31)
297 #define CASE(LEN, FIRST, THIRD, NAME) \
298  case HASH(LEN, FIRST, THIRD): \
299  return memcmp(Name, #NAME, LEN) ? tok::pp_not_keyword : tok::pp_ ## NAME
300 
301  unsigned Len = getLength();
302  if (Len < 2) return tok::pp_not_keyword;
303  const char *Name = getNameStart();
304  switch (HASH(Len, Name[0], Name[2])) {
305  default: return tok::pp_not_keyword;
306  CASE( 2, 'i', '\0', if);
307  CASE( 4, 'e', 'i', elif);
308  CASE( 4, 'e', 's', else);
309  CASE( 4, 'l', 'n', line);
310  CASE( 4, 's', 'c', sccs);
311  CASE( 5, 'e', 'd', endif);
312  CASE( 5, 'e', 'r', error);
313  CASE( 5, 'i', 'e', ident);
314  CASE( 5, 'i', 'd', ifdef);
315  CASE( 5, 'u', 'd', undef);
316 
317  CASE( 6, 'a', 's', assert);
318  CASE( 6, 'd', 'f', define);
319  CASE( 6, 'i', 'n', ifndef);
320  CASE( 6, 'i', 'p', import);
321  CASE( 6, 'p', 'a', pragma);
322 
323  CASE( 7, 'd', 'f', defined);
324  CASE( 7, 'i', 'c', include);
325  CASE( 7, 'w', 'r', warning);
326 
327  CASE( 8, 'u', 'a', unassert);
328  CASE(12, 'i', 'c', include_next);
329 
330  CASE(14, '_', 'p', __public_macro);
331 
332  CASE(15, '_', 'p', __private_macro);
333 
334  CASE(16, '_', 'i', __include_macros);
335 #undef CASE
336 #undef HASH
337  }
338 }
339 
340 //===----------------------------------------------------------------------===//
341 // Stats Implementation
342 //===----------------------------------------------------------------------===//
343 
344 /// PrintStats - Print statistics about how well the identifier table is doing
345 /// at hashing identifiers.
347  unsigned NumBuckets = HashTable.getNumBuckets();
348  unsigned NumIdentifiers = HashTable.getNumItems();
349  unsigned NumEmptyBuckets = NumBuckets-NumIdentifiers;
350  unsigned AverageIdentifierSize = 0;
351  unsigned MaxIdentifierLength = 0;
352 
353  // TODO: Figure out maximum times an identifier had to probe for -stats.
354  for (llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator>::const_iterator
355  I = HashTable.begin(), E = HashTable.end(); I != E; ++I) {
356  unsigned IdLen = I->getKeyLength();
357  AverageIdentifierSize += IdLen;
358  if (MaxIdentifierLength < IdLen)
359  MaxIdentifierLength = IdLen;
360  }
361 
362  fprintf(stderr, "\n*** Identifier Table Stats:\n");
363  fprintf(stderr, "# Identifiers: %d\n", NumIdentifiers);
364  fprintf(stderr, "# Empty Buckets: %d\n", NumEmptyBuckets);
365  fprintf(stderr, "Hash density (#identifiers per bucket): %f\n",
366  NumIdentifiers/(double)NumBuckets);
367  fprintf(stderr, "Ave identifier length: %f\n",
368  (AverageIdentifierSize/(double)NumIdentifiers));
369  fprintf(stderr, "Max identifier length: %d\n", MaxIdentifierLength);
370 
371  // Compute statistics about the memory allocated for identifiers.
372  HashTable.getAllocator().PrintStats();
373 }
374 
375 //===----------------------------------------------------------------------===//
376 // SelectorTable Implementation
377 //===----------------------------------------------------------------------===//
378 
381 }
382 
383 namespace clang {
384 
385 /// One of these variable length records is kept for each
386 /// selector containing more than one keyword. We use a folding set
387 /// to unique aggregate names (keyword selectors in ObjC parlance). Access to
388 /// this class is provided strictly through Selector.
389 class alignas(IdentifierInfoAlignment) MultiKeywordSelector
391  public llvm::FoldingSetNode {
392  MultiKeywordSelector(unsigned nKeys) : DeclarationNameExtra(nKeys) {}
393 
394 public:
395  // Constructor for keyword selectors.
396  MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV)
397  : DeclarationNameExtra(nKeys) {
398  assert((nKeys > 1) && "not a multi-keyword selector");
399 
400  // Fill in the trailing keyword array.
401  IdentifierInfo **KeyInfo = reinterpret_cast<IdentifierInfo **>(this + 1);
402  for (unsigned i = 0; i != nKeys; ++i)
403  KeyInfo[i] = IIV[i];
404  }
405 
406  // getName - Derive the full selector name and return it.
407  std::string getName() const;
408 
409  using DeclarationNameExtra::getNumArgs;
410 
412 
414  return reinterpret_cast<keyword_iterator>(this + 1);
415  }
416 
418  return keyword_begin() + getNumArgs();
419  }
420 
422  assert(i < getNumArgs() && "getIdentifierInfoForSlot(): illegal index");
423  return keyword_begin()[i];
424  }
425 
426  static void Profile(llvm::FoldingSetNodeID &ID, keyword_iterator ArgTys,
427  unsigned NumArgs) {
428  ID.AddInteger(NumArgs);
429  for (unsigned i = 0; i != NumArgs; ++i)
430  ID.AddPointer(ArgTys[i]);
431  }
432 
433  void Profile(llvm::FoldingSetNodeID &ID) {
434  Profile(ID, keyword_begin(), getNumArgs());
435  }
436 };
437 
438 } // namespace clang.
439 
440 unsigned Selector::getNumArgs() const {
441  unsigned IIF = getIdentifierInfoFlag();
442  if (IIF <= ZeroArg)
443  return 0;
444  if (IIF == OneArg)
445  return 1;
446  // We point to a MultiKeywordSelector.
447  MultiKeywordSelector *SI = getMultiKeywordSelector();
448  return SI->getNumArgs();
449 }
450 
452  if (getIdentifierInfoFlag() < MultiArg) {
453  assert(argIndex == 0 && "illegal keyword index");
454  return getAsIdentifierInfo();
455  }
456 
457  // We point to a MultiKeywordSelector.
458  MultiKeywordSelector *SI = getMultiKeywordSelector();
459  return SI->getIdentifierInfoForSlot(argIndex);
460 }
461 
462 StringRef Selector::getNameForSlot(unsigned int argIndex) const {
463  IdentifierInfo *II = getIdentifierInfoForSlot(argIndex);
464  return II ? II->getName() : StringRef();
465 }
466 
467 std::string MultiKeywordSelector::getName() const {
468  SmallString<256> Str;
469  llvm::raw_svector_ostream OS(Str);
470  for (keyword_iterator I = keyword_begin(), E = keyword_end(); I != E; ++I) {
471  if (*I)
472  OS << (*I)->getName();
473  OS << ':';
474  }
475 
476  return OS.str();
477 }
478 
479 std::string Selector::getAsString() const {
480  if (InfoPtr == 0)
481  return "<null selector>";
482 
483  if (getIdentifierInfoFlag() < MultiArg) {
484  IdentifierInfo *II = getAsIdentifierInfo();
485 
486  if (getNumArgs() == 0) {
487  assert(II && "If the number of arguments is 0 then II is guaranteed to "
488  "not be null.");
489  return II->getName();
490  }
491 
492  if (!II)
493  return ":";
494 
495  return II->getName().str() + ":";
496  }
497 
498  // We have a multiple keyword selector.
499  return getMultiKeywordSelector()->getName();
500 }
501 
502 void Selector::print(llvm::raw_ostream &OS) const {
503  OS << getAsString();
504 }
505 
506 LLVM_DUMP_METHOD void Selector::dump() const { print(llvm::errs()); }
507 
508 /// Interpreting the given string using the normal CamelCase
509 /// conventions, determine whether the given string starts with the
510 /// given "word", which is assumed to end in a lowercase letter.
511 static bool startsWithWord(StringRef name, StringRef word) {
512  if (name.size() < word.size()) return false;
513  return ((name.size() == word.size() || !isLowercase(name[word.size()])) &&
514  name.startswith(word));
515 }
516 
517 ObjCMethodFamily Selector::getMethodFamilyImpl(Selector sel) {
519  if (!first) return OMF_None;
520 
521  StringRef name = first->getName();
522  if (sel.isUnarySelector()) {
523  if (name == "autorelease") return OMF_autorelease;
524  if (name == "dealloc") return OMF_dealloc;
525  if (name == "finalize") return OMF_finalize;
526  if (name == "release") return OMF_release;
527  if (name == "retain") return OMF_retain;
528  if (name == "retainCount") return OMF_retainCount;
529  if (name == "self") return OMF_self;
530  if (name == "initialize") return OMF_initialize;
531  }
532 
533  if (name == "performSelector" || name == "performSelectorInBackground" ||
534  name == "performSelectorOnMainThread")
535  return OMF_performSelector;
536 
537  // The other method families may begin with a prefix of underscores.
538  while (!name.empty() && name.front() == '_')
539  name = name.substr(1);
540 
541  if (name.empty()) return OMF_None;
542  switch (name.front()) {
543  case 'a':
544  if (startsWithWord(name, "alloc")) return OMF_alloc;
545  break;
546  case 'c':
547  if (startsWithWord(name, "copy")) return OMF_copy;
548  break;
549  case 'i':
550  if (startsWithWord(name, "init")) return OMF_init;
551  break;
552  case 'm':
553  if (startsWithWord(name, "mutableCopy")) return OMF_mutableCopy;
554  break;
555  case 'n':
556  if (startsWithWord(name, "new")) return OMF_new;
557  break;
558  default:
559  break;
560  }
561 
562  return OMF_None;
563 }
564 
567  if (!first) return OIT_None;
568 
569  StringRef name = first->getName();
570 
571  if (name.empty()) return OIT_None;
572  switch (name.front()) {
573  case 'a':
574  if (startsWithWord(name, "array")) return OIT_Array;
575  break;
576  case 'd':
577  if (startsWithWord(name, "default")) return OIT_ReturnsSelf;
578  if (startsWithWord(name, "dictionary")) return OIT_Dictionary;
579  break;
580  case 's':
581  if (startsWithWord(name, "shared")) return OIT_ReturnsSelf;
582  if (startsWithWord(name, "standard")) return OIT_Singleton;
583  break;
584  case 'i':
585  if (startsWithWord(name, "init")) return OIT_Init;
586  default:
587  break;
588  }
589  return OIT_None;
590 }
591 
592 ObjCStringFormatFamily Selector::getStringFormatFamilyImpl(Selector sel) {
594  if (!first) return SFF_None;
595 
596  StringRef name = first->getName();
597 
598  switch (name.front()) {
599  case 'a':
600  if (name == "appendFormat") return SFF_NSString;
601  break;
602 
603  case 'i':
604  if (name == "initWithFormat") return SFF_NSString;
605  break;
606 
607  case 'l':
608  if (name == "localizedStringWithFormat") return SFF_NSString;
609  break;
610 
611  case 's':
612  if (name == "stringByAppendingFormat" ||
613  name == "stringWithFormat") return SFF_NSString;
614  break;
615  }
616  return SFF_None;
617 }
618 
619 namespace {
620 
621 struct SelectorTableImpl {
622  llvm::FoldingSet<MultiKeywordSelector> Table;
623  llvm::BumpPtrAllocator Allocator;
624 };
625 
626 } // namespace
627 
628 static SelectorTableImpl &getSelectorTableImpl(void *P) {
629  return *static_cast<SelectorTableImpl*>(P);
630 }
631 
634  SmallString<64> SetterName("set");
635  SetterName += Name;
636  SetterName[3] = toUppercase(SetterName[3]);
637  return SetterName;
638 }
639 
640 Selector
642  SelectorTable &SelTable,
643  const IdentifierInfo *Name) {
644  IdentifierInfo *SetterName =
645  &Idents.get(constructSetterName(Name->getName()));
646  return SelTable.getUnarySelector(SetterName);
647 }
648 
650  StringRef Name = Sel.getNameForSlot(0);
651  assert(Name.startswith("set") && "invalid setter name");
652  return (Twine(toLowercase(Name[3])) + Name.drop_front(4)).str();
653 }
654 
656  SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl);
657  return SelTabImpl.Allocator.getTotalMemory();
658 }
659 
661  if (nKeys < 2)
662  return Selector(IIV[0], nKeys);
663 
664  SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl);
665 
666  // Unique selector, to guarantee there is one per name.
667  llvm::FoldingSetNodeID ID;
668  MultiKeywordSelector::Profile(ID, IIV, nKeys);
669 
670  void *InsertPos = nullptr;
671  if (MultiKeywordSelector *SI =
672  SelTabImpl.Table.FindNodeOrInsertPos(ID, InsertPos))
673  return Selector(SI);
674 
675  // MultiKeywordSelector objects are not allocated with new because they have a
676  // variable size array (for parameter types) at the end of them.
677  unsigned Size = sizeof(MultiKeywordSelector) + nKeys*sizeof(IdentifierInfo *);
679  (MultiKeywordSelector *)SelTabImpl.Allocator.Allocate(
680  Size, alignof(MultiKeywordSelector));
681  new (SI) MultiKeywordSelector(nKeys, IIV);
682  SelTabImpl.Table.InsertNode(SI, InsertPos);
683  return Selector(SI);
684 }
685 
687  Impl = new SelectorTableImpl();
688 }
689 
691  delete &getSelectorTableImpl(Impl);
692 }
693 
695  switch (Operator) {
696  case OO_None:
698  return nullptr;
699 
700 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
701  case OO_##Name: return Spelling;
702 #include "clang/Basic/OperatorKinds.def"
703  }
704 
705  llvm_unreachable("Invalid OverloadedOperatorKind!");
706 }
707 
709  bool isContextSensitive) {
710  switch (kind) {
712  return isContextSensitive ? "nonnull" : "_Nonnull";
713 
715  return isContextSensitive ? "nullable" : "_Nullable";
716 
718  return isContextSensitive ? "null_unspecified" : "_Null_unspecified";
719  }
720  llvm_unreachable("Unknown nullability kind.");
721 }
ObjCStringFormatFamily
void AddKeywords(const LangOptions &LangOpts)
Populate the identifier table with info about the language keywords for the language specified by Lan...
Smart pointer class that efficiently represents Objective-C method names.
DeclarationNameExtra is used as a base of various uncommon special names.
void * getAsOpaquePtr() const
unsigned getNumArgs() const
Return the number of arguments in an ObjC selector.
bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const
Definition: LangOptions.h:248
void PrintStats() const
Print some statistics to stderr that indicate how well the hashing is doing.
NullabilityKind
Describes the nullability of a particular type.
Definition: Specifiers.h:285
void setIsExtensionToken(bool Val)
StringRef P
static SelectorTableImpl & getSelectorTableImpl(void *P)
virtual IdentifierIterator * getIdentifiers()
Retrieve an iterator into the set of all identifiers known to this identifier lookup source...
KeywordStatus
How a keyword is treated in the selected standard.
static void AddKeyword(StringRef Keyword, tok::TokenKind TokenCode, unsigned Flags, const LangOptions &LangOpts, IdentifierTable &Table)
AddKeyword - This method is used to associate a token ID with specific identifiers because they are l...
IdentifierInfo * getIdentifierInfoForSlot(unsigned i) const
std::string getName(ArrayRef< StringRef > Parts) const
Get the platform-specific name separator.
Selector getUnarySelector(IdentifierInfo *ID)
One of these records is kept for each identifier that is lexed.
static ObjCInstanceTypeFamily getInstTypeMethodFamily(Selector sel)
This table allows us to fully hide how we implement multi-keyword caching.
ObjCMethodFamily
A family of Objective-C methods.
IdentifierInfo *const * keyword_iterator
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:50
static KeywordStatus getTokenKwStatus(const LangOptions &LangOpts, tok::TokenKind K)
Checks if the specified token kind represents a keyword in the specified language.
IdentifierTable(IdentifierInfoLookup *ExternalLookup=nullptr)
Create the identifier table.
Values of this type can be null.
bool isUnarySelector() const
void setIsFutureCompatKeyword(bool Val)
static SmallString< 64 > constructSetterName(StringRef Name)
Return the default setter name for the given identifier.
static Selector constructSetterSelector(IdentifierTable &Idents, SelectorTable &SelTable, const IdentifierInfo *Name)
Return the default setter selector for the given identifier.
void Profile(llvm::FoldingSetNodeID &ID)
Whether values of this type can be null is (explicitly) unspecified.
Values of this type can never be null.
static void AddCXXOperatorKeyword(StringRef Keyword, tok::TokenKind TokenCode, IdentifierTable &Table)
AddCXXOperatorKeyword - Register a C++ operator keyword alternative representations.
size_t getTotalMemory() const
Return the total amount of memory allocated for managing selectors.
bool isCPlusPlusKeyword(const LangOptions &LangOpts) const
Return true if this token is a C++ keyword in the specified language.
Provides lookups to, and iteration over, IdentiferInfo objects.
void setIsCPlusPlusOperatorKeyword(bool Val=true)
isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether this identifier is a C++ al...
One of these variable length records is kept for each selector containing more than one keyword...
Defines the clang::LangOptions interface.
llvm::StringRef getAsString(SyncScope S)
Definition: SyncScope.h:51
Implements an efficient mapping from strings to IdentifierInfo nodes.
Defines an enumeration for C++ overloaded operators.
PPKeywordKind
Provides a namespace for preprocessor keywords which start with a &#39;#&#39; at the beginning of the line...
Definition: TokenKinds.h:33
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
#define CASE(LEN, FIRST, THIRD, NAME)
ObjCInstanceTypeFamily
A family of Objective-C methods.
static KeywordStatus getKeywordStatus(const LangOptions &LangOpts, unsigned Flags)
Translates flags as specified in TokenKinds.def into keyword status in the given language standard...
An iterator that walks over all of the known identifiers in the lookup table.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
void print(llvm::raw_ostream &OS) const
Prints the full selector name (e.g. "foo:bar:").
unsigned getNumArgs() const
ObjCKeywordKind
Provides a namespace for Objective-C keywords which start with an &#39;@&#39;.
Definition: TokenKinds.h:41
void setObjCKeywordID(tok::ObjCKeywordKind ID)
bool isKeyword(const LangOptions &LangOpts) const
Return true if this token is a keyword in the specified language.
static bool startsWithWord(StringRef name, StringRef word)
Interpreting the given string using the normal CamelCase conventions, determine whether the given str...
static void Profile(llvm::FoldingSetNodeID &ID, keyword_iterator ArgTys, unsigned NumArgs)
std::string getAsString() const
Derive the full selector name (e.g.
LLVM_READONLY char toLowercase(char c)
Converts the given ASCII character to its lowercase equivalent.
Definition: CharInfo.h:165
IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Definition: TokenKinds.h:25
keyword_iterator keyword_begin() const
static void AddObjCKeyword(StringRef Name, tok::ObjCKeywordKind ObjCID, IdentifierTable &Table)
AddObjCKeyword - Register an Objective-C @keyword like "class" "selector" or "property".
LLVM_READONLY bool isLowercase(unsigned char c)
Return true if this character is a lowercase ASCII letter: [a-z].
Definition: CharInfo.h:100
Defines various enumerations that describe declaration and type specifiers.
StringRef getName() const
Return the actual identifier string.
Dataflow Directional Tag Classes.
static std::string getPropertyNameFromSetterSelector(Selector Sel)
Return the property name for the given setter selector.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:22
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
Not an overloaded operator.
Definition: OperatorKinds.h:23
MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV)
Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV)
Can create any sort of selector.
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword...
#define HASH(LEN, FIRST, THIRD)
Defines the clang::TokenKind enum and support functions.
No particular method family.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
Definition: DiagnosticIDs.h:61
keyword_iterator keyword_end() const
LLVM_READONLY char toUppercase(char c)
Converts the given ASCII character to its uppercase equivalent.
Definition: CharInfo.h:174
llvm::StringRef getNullabilitySpelling(NullabilityKind kind, bool isContextSensitive=false)
Retrieve the spelling of the given nullability kind.