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