clang  10.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 '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 
416  assert(!Names.empty() && "must have >= 1 selector slots");
417  if (getNumArgs() != Names.size())
418  return false;
419  for (unsigned I = 0, E = Names.size(); I != E; ++I) {
420  if (getNameForSlot(I) != Names[I])
421  return false;
422  }
423  return true;
424 }
425 
426 bool Selector::isUnarySelector(StringRef Name) const {
427  return isUnarySelector() && getNameForSlot(0) == Name;
428 }
429 
430 unsigned Selector::getNumArgs() const {
431  unsigned IIF = getIdentifierInfoFlag();
432  if (IIF <= ZeroArg)
433  return 0;
434  if (IIF == OneArg)
435  return 1;
436  // We point to a MultiKeywordSelector.
437  MultiKeywordSelector *SI = getMultiKeywordSelector();
438  return SI->getNumArgs();
439 }
440 
442  if (getIdentifierInfoFlag() < MultiArg) {
443  assert(argIndex == 0 && "illegal keyword index");
444  return getAsIdentifierInfo();
445  }
446 
447  // We point to a MultiKeywordSelector.
448  MultiKeywordSelector *SI = getMultiKeywordSelector();
449  return SI->getIdentifierInfoForSlot(argIndex);
450 }
451 
452 StringRef Selector::getNameForSlot(unsigned int argIndex) const {
453  IdentifierInfo *II = getIdentifierInfoForSlot(argIndex);
454  return II ? II->getName() : StringRef();
455 }
456 
457 std::string MultiKeywordSelector::getName() const {
458  SmallString<256> Str;
459  llvm::raw_svector_ostream OS(Str);
460  for (keyword_iterator I = keyword_begin(), E = keyword_end(); I != E; ++I) {
461  if (*I)
462  OS << (*I)->getName();
463  OS << ':';
464  }
465 
466  return OS.str();
467 }
468 
469 std::string Selector::getAsString() const {
470  if (InfoPtr == 0)
471  return "<null selector>";
472 
473  if (getIdentifierInfoFlag() < MultiArg) {
474  IdentifierInfo *II = getAsIdentifierInfo();
475 
476  if (getNumArgs() == 0) {
477  assert(II && "If the number of arguments is 0 then II is guaranteed to "
478  "not be null.");
479  return II->getName();
480  }
481 
482  if (!II)
483  return ":";
484 
485  return II->getName().str() + ":";
486  }
487 
488  // We have a multiple keyword selector.
489  return getMultiKeywordSelector()->getName();
490 }
491 
492 void Selector::print(llvm::raw_ostream &OS) const {
493  OS << getAsString();
494 }
495 
496 LLVM_DUMP_METHOD void Selector::dump() const { print(llvm::errs()); }
497 
498 /// Interpreting the given string using the normal CamelCase
499 /// conventions, determine whether the given string starts with the
500 /// given "word", which is assumed to end in a lowercase letter.
501 static bool startsWithWord(StringRef name, StringRef word) {
502  if (name.size() < word.size()) return false;
503  return ((name.size() == word.size() || !isLowercase(name[word.size()])) &&
504  name.startswith(word));
505 }
506 
507 ObjCMethodFamily Selector::getMethodFamilyImpl(Selector sel) {
509  if (!first) return OMF_None;
510 
511  StringRef name = first->getName();
512  if (sel.isUnarySelector()) {
513  if (name == "autorelease") return OMF_autorelease;
514  if (name == "dealloc") return OMF_dealloc;
515  if (name == "finalize") return OMF_finalize;
516  if (name == "release") return OMF_release;
517  if (name == "retain") return OMF_retain;
518  if (name == "retainCount") return OMF_retainCount;
519  if (name == "self") return OMF_self;
520  if (name == "initialize") return OMF_initialize;
521  }
522 
523  if (name == "performSelector" || name == "performSelectorInBackground" ||
524  name == "performSelectorOnMainThread")
525  return OMF_performSelector;
526 
527  // The other method families may begin with a prefix of underscores.
528  while (!name.empty() && name.front() == '_')
529  name = name.substr(1);
530 
531  if (name.empty()) return OMF_None;
532  switch (name.front()) {
533  case 'a':
534  if (startsWithWord(name, "alloc")) return OMF_alloc;
535  break;
536  case 'c':
537  if (startsWithWord(name, "copy")) return OMF_copy;
538  break;
539  case 'i':
540  if (startsWithWord(name, "init")) return OMF_init;
541  break;
542  case 'm':
543  if (startsWithWord(name, "mutableCopy")) return OMF_mutableCopy;
544  break;
545  case 'n':
546  if (startsWithWord(name, "new")) return OMF_new;
547  break;
548  default:
549  break;
550  }
551 
552  return OMF_None;
553 }
554 
557  if (!first) return OIT_None;
558 
559  StringRef name = first->getName();
560 
561  if (name.empty()) return OIT_None;
562  switch (name.front()) {
563  case 'a':
564  if (startsWithWord(name, "array")) return OIT_Array;
565  break;
566  case 'd':
567  if (startsWithWord(name, "default")) return OIT_ReturnsSelf;
568  if (startsWithWord(name, "dictionary")) return OIT_Dictionary;
569  break;
570  case 's':
571  if (startsWithWord(name, "shared")) return OIT_ReturnsSelf;
572  if (startsWithWord(name, "standard")) return OIT_Singleton;
573  break;
574  case 'i':
575  if (startsWithWord(name, "init")) return OIT_Init;
576  break;
577  default:
578  break;
579  }
580  return OIT_None;
581 }
582 
583 ObjCStringFormatFamily Selector::getStringFormatFamilyImpl(Selector sel) {
585  if (!first) return SFF_None;
586 
587  StringRef name = first->getName();
588 
589  switch (name.front()) {
590  case 'a':
591  if (name == "appendFormat") return SFF_NSString;
592  break;
593 
594  case 'i':
595  if (name == "initWithFormat") return SFF_NSString;
596  break;
597 
598  case 'l':
599  if (name == "localizedStringWithFormat") return SFF_NSString;
600  break;
601 
602  case 's':
603  if (name == "stringByAppendingFormat" ||
604  name == "stringWithFormat") return SFF_NSString;
605  break;
606  }
607  return SFF_None;
608 }
609 
610 namespace {
611 
612 struct SelectorTableImpl {
613  llvm::FoldingSet<MultiKeywordSelector> Table;
614  llvm::BumpPtrAllocator Allocator;
615 };
616 
617 } // namespace
618 
619 static SelectorTableImpl &getSelectorTableImpl(void *P) {
620  return *static_cast<SelectorTableImpl*>(P);
621 }
622 
625  SmallString<64> SetterName("set");
626  SetterName += Name;
627  SetterName[3] = toUppercase(SetterName[3]);
628  return SetterName;
629 }
630 
631 Selector
633  SelectorTable &SelTable,
634  const IdentifierInfo *Name) {
635  IdentifierInfo *SetterName =
636  &Idents.get(constructSetterName(Name->getName()));
637  return SelTable.getUnarySelector(SetterName);
638 }
639 
641  StringRef Name = Sel.getNameForSlot(0);
642  assert(Name.startswith("set") && "invalid setter name");
643  return (Twine(toLowercase(Name[3])) + Name.drop_front(4)).str();
644 }
645 
647  SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl);
648  return SelTabImpl.Allocator.getTotalMemory();
649 }
650 
652  if (nKeys < 2)
653  return Selector(IIV[0], nKeys);
654 
655  SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl);
656 
657  // Unique selector, to guarantee there is one per name.
658  llvm::FoldingSetNodeID ID;
659  MultiKeywordSelector::Profile(ID, IIV, nKeys);
660 
661  void *InsertPos = nullptr;
662  if (MultiKeywordSelector *SI =
663  SelTabImpl.Table.FindNodeOrInsertPos(ID, InsertPos))
664  return Selector(SI);
665 
666  // MultiKeywordSelector objects are not allocated with new because they have a
667  // variable size array (for parameter types) at the end of them.
668  unsigned Size = sizeof(MultiKeywordSelector) + nKeys*sizeof(IdentifierInfo *);
670  (MultiKeywordSelector *)SelTabImpl.Allocator.Allocate(
671  Size, alignof(MultiKeywordSelector));
672  new (SI) MultiKeywordSelector(nKeys, IIV);
673  SelTabImpl.Table.InsertNode(SI, InsertPos);
674  return Selector(SI);
675 }
676 
678  Impl = new SelectorTableImpl();
679 }
680 
682  delete &getSelectorTableImpl(Impl);
683 }
684 
686  switch (Operator) {
687  case OO_None:
689  return nullptr;
690 
691 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
692  case OO_##Name: return Spelling;
693 #include "clang/Basic/OperatorKinds.def"
694  }
695 
696  llvm_unreachable("Invalid OverloadedOperatorKind!");
697 }
698 
700  bool isContextSensitive) {
701  switch (kind) {
703  return isContextSensitive ? "nonnull" : "_Nonnull";
704 
706  return isContextSensitive ? "nullable" : "_Nullable";
707 
709  return isContextSensitive ? "null_unspecified" : "_Null_unspecified";
710  }
711  llvm_unreachable("Unknown nullability kind.");
712 }
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:281
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:314
void setIsExtensionToken(bool Val)
StringRef P
static SelectorTableImpl & getSelectorTableImpl(void *P)
RangeSelector name(std::string ID)
Given a node with a "name", (like NamedDecl, DeclRefExpr or CxxCtorInitializer) selects the name&#39;s to...
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
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.
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.
static std::string getName(const CallEvent &Call)
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:21
bool isKeywordSelector() const
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.