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 /// MultiKeywordSelector - 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.
390  : public DeclarationNameExtra, public llvm::FoldingSetNode {
391  MultiKeywordSelector(unsigned nKeys) {
392  ExtraKindOrNumArgs = NUM_EXTRA_KINDS + nKeys;
393  }
394 
395 public:
396  // Constructor for keyword selectors.
397  MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV) {
398  assert((nKeys > 1) && "not a multi-keyword selector");
399  ExtraKindOrNumArgs = NUM_EXTRA_KINDS + nKeys;
400 
401  // Fill in the trailing keyword array.
402  IdentifierInfo **KeyInfo = reinterpret_cast<IdentifierInfo **>(this+1);
403  for (unsigned i = 0; i != nKeys; ++i)
404  KeyInfo[i] = IIV[i];
405  }
406 
407  // getName - Derive the full selector name and return it.
408  std::string getName() const;
409 
410  unsigned getNumArgs() const { return ExtraKindOrNumArgs - NUM_EXTRA_KINDS; }
411 
413 
415  return reinterpret_cast<keyword_iterator>(this+1);
416  }
417 
419  return keyword_begin()+getNumArgs();
420  }
421 
423  assert(i < getNumArgs() && "getIdentifierInfoForSlot(): illegal index");
424  return keyword_begin()[i];
425  }
426 
427  static void Profile(llvm::FoldingSetNodeID &ID,
428  keyword_iterator ArgTys, unsigned NumArgs) {
429  ID.AddInteger(NumArgs);
430  for (unsigned i = 0; i != NumArgs; ++i)
431  ID.AddPointer(ArgTys[i]);
432  }
433 
434  void Profile(llvm::FoldingSetNodeID &ID) {
435  Profile(ID, keyword_begin(), getNumArgs());
436  }
437 };
438 
439 } // namespace clang.
440 
441 unsigned Selector::getNumArgs() const {
442  unsigned IIF = getIdentifierInfoFlag();
443  if (IIF <= ZeroArg)
444  return 0;
445  if (IIF == OneArg)
446  return 1;
447  // We point to a MultiKeywordSelector.
448  MultiKeywordSelector *SI = getMultiKeywordSelector();
449  return SI->getNumArgs();
450 }
451 
453  if (getIdentifierInfoFlag() < MultiArg) {
454  assert(argIndex == 0 && "illegal keyword index");
455  return getAsIdentifierInfo();
456  }
457 
458  // We point to a MultiKeywordSelector.
459  MultiKeywordSelector *SI = getMultiKeywordSelector();
460  return SI->getIdentifierInfoForSlot(argIndex);
461 }
462 
463 StringRef Selector::getNameForSlot(unsigned int argIndex) const {
464  IdentifierInfo *II = getIdentifierInfoForSlot(argIndex);
465  return II? II->getName() : StringRef();
466 }
467 
468 std::string MultiKeywordSelector::getName() const {
469  SmallString<256> Str;
470  llvm::raw_svector_ostream OS(Str);
471  for (keyword_iterator I = keyword_begin(), E = keyword_end(); I != E; ++I) {
472  if (*I)
473  OS << (*I)->getName();
474  OS << ':';
475  }
476 
477  return OS.str();
478 }
479 
480 std::string Selector::getAsString() const {
481  if (InfoPtr == 0)
482  return "<null selector>";
483 
484  if (getIdentifierInfoFlag() < MultiArg) {
485  IdentifierInfo *II = getAsIdentifierInfo();
486 
487  if (getNumArgs() == 0) {
488  assert(II && "If the number of arguments is 0 then II is guaranteed to "
489  "not be null.");
490  return II->getName();
491  }
492 
493  if (!II)
494  return ":";
495 
496  return II->getName().str() + ":";
497  }
498 
499  // We have a multiple keyword selector.
500  return getMultiKeywordSelector()->getName();
501 }
502 
503 void Selector::print(llvm::raw_ostream &OS) const {
504  OS << getAsString();
505 }
506 
507 LLVM_DUMP_METHOD void Selector::dump() const { print(llvm::errs()); }
508 
509 /// Interpreting the given string using the normal CamelCase
510 /// conventions, determine whether the given string starts with the
511 /// given "word", which is assumed to end in a lowercase letter.
512 static bool startsWithWord(StringRef name, StringRef word) {
513  if (name.size() < word.size()) return false;
514  return ((name.size() == word.size() || !isLowercase(name[word.size()])) &&
515  name.startswith(word));
516 }
517 
518 ObjCMethodFamily Selector::getMethodFamilyImpl(Selector sel) {
520  if (!first) return OMF_None;
521 
522  StringRef name = first->getName();
523  if (sel.isUnarySelector()) {
524  if (name == "autorelease") return OMF_autorelease;
525  if (name == "dealloc") return OMF_dealloc;
526  if (name == "finalize") return OMF_finalize;
527  if (name == "release") return OMF_release;
528  if (name == "retain") return OMF_retain;
529  if (name == "retainCount") return OMF_retainCount;
530  if (name == "self") return OMF_self;
531  if (name == "initialize") return OMF_initialize;
532  }
533 
534  if (name == "performSelector" || name == "performSelectorInBackground" ||
535  name == "performSelectorOnMainThread")
536  return OMF_performSelector;
537 
538  // The other method families may begin with a prefix of underscores.
539  while (!name.empty() && name.front() == '_')
540  name = name.substr(1);
541 
542  if (name.empty()) return OMF_None;
543  switch (name.front()) {
544  case 'a':
545  if (startsWithWord(name, "alloc")) return OMF_alloc;
546  break;
547  case 'c':
548  if (startsWithWord(name, "copy")) return OMF_copy;
549  break;
550  case 'i':
551  if (startsWithWord(name, "init")) return OMF_init;
552  break;
553  case 'm':
554  if (startsWithWord(name, "mutableCopy")) return OMF_mutableCopy;
555  break;
556  case 'n':
557  if (startsWithWord(name, "new")) return OMF_new;
558  break;
559  default:
560  break;
561  }
562 
563  return OMF_None;
564 }
565 
568  if (!first) return OIT_None;
569 
570  StringRef name = first->getName();
571 
572  if (name.empty()) return OIT_None;
573  switch (name.front()) {
574  case 'a':
575  if (startsWithWord(name, "array")) return OIT_Array;
576  break;
577  case 'd':
578  if (startsWithWord(name, "default")) return OIT_ReturnsSelf;
579  if (startsWithWord(name, "dictionary")) return OIT_Dictionary;
580  break;
581  case 's':
582  if (startsWithWord(name, "shared")) return OIT_ReturnsSelf;
583  if (startsWithWord(name, "standard")) return OIT_Singleton;
584  break;
585  case 'i':
586  if (startsWithWord(name, "init")) return OIT_Init;
587  default:
588  break;
589  }
590  return OIT_None;
591 }
592 
593 ObjCStringFormatFamily Selector::getStringFormatFamilyImpl(Selector sel) {
595  if (!first) return SFF_None;
596 
597  StringRef name = first->getName();
598 
599  switch (name.front()) {
600  case 'a':
601  if (name == "appendFormat") return SFF_NSString;
602  break;
603 
604  case 'i':
605  if (name == "initWithFormat") return SFF_NSString;
606  break;
607 
608  case 'l':
609  if (name == "localizedStringWithFormat") return SFF_NSString;
610  break;
611 
612  case 's':
613  if (name == "stringByAppendingFormat" ||
614  name == "stringWithFormat") return SFF_NSString;
615  break;
616  }
617  return SFF_None;
618 }
619 
620 namespace {
621 
622 struct SelectorTableImpl {
623  llvm::FoldingSet<MultiKeywordSelector> Table;
624  llvm::BumpPtrAllocator Allocator;
625 };
626 
627 } // namespace
628 
629 static SelectorTableImpl &getSelectorTableImpl(void *P) {
630  return *static_cast<SelectorTableImpl*>(P);
631 }
632 
635  SmallString<64> SetterName("set");
636  SetterName += Name;
637  SetterName[3] = toUppercase(SetterName[3]);
638  return SetterName;
639 }
640 
641 Selector
643  SelectorTable &SelTable,
644  const IdentifierInfo *Name) {
645  IdentifierInfo *SetterName =
646  &Idents.get(constructSetterName(Name->getName()));
647  return SelTable.getUnarySelector(SetterName);
648 }
649 
651  StringRef Name = Sel.getNameForSlot(0);
652  assert(Name.startswith("set") && "invalid setter name");
653  return (Twine(toLowercase(Name[3])) + Name.drop_front(4)).str();
654 }
655 
657  SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl);
658  return SelTabImpl.Allocator.getTotalMemory();
659 }
660 
662  if (nKeys < 2)
663  return Selector(IIV[0], nKeys);
664 
665  SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl);
666 
667  // Unique selector, to guarantee there is one per name.
668  llvm::FoldingSetNodeID ID;
669  MultiKeywordSelector::Profile(ID, IIV, nKeys);
670 
671  void *InsertPos = nullptr;
672  if (MultiKeywordSelector *SI =
673  SelTabImpl.Table.FindNodeOrInsertPos(ID, InsertPos))
674  return Selector(SI);
675 
676  // MultiKeywordSelector objects are not allocated with new because they have a
677  // variable size array (for parameter types) at the end of them.
678  unsigned Size = sizeof(MultiKeywordSelector) + nKeys*sizeof(IdentifierInfo *);
680  (MultiKeywordSelector *)SelTabImpl.Allocator.Allocate(
681  Size, alignof(MultiKeywordSelector));
682  new (SI) MultiKeywordSelector(nKeys, IIV);
683  SelTabImpl.Table.InsertNode(SI, InsertPos);
684  return Selector(SI);
685 }
686 
688  Impl = new SelectorTableImpl();
689 }
690 
692  delete &getSelectorTableImpl(Impl);
693 }
694 
696  switch (Operator) {
697  case OO_None:
699  return nullptr;
700 
701 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
702  case OO_##Name: return Spelling;
703 #include "clang/Basic/OperatorKinds.def"
704  }
705 
706  llvm_unreachable("Invalid OverloadedOperatorKind!");
707 }
708 
710  bool isContextSensitive) {
711  switch (kind) {
713  return isContextSensitive ? "nonnull" : "_Nonnull";
714 
716  return isContextSensitive ? "nullable" : "_Nullable";
717 
719  return isContextSensitive ? "null_unspecified" : "_Null_unspecified";
720  }
721  llvm_unreachable("Unknown nullability kind.");
722 }
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.
void * getAsOpaquePtr() const
bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const
Definition: LangOptions.h:245
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)
DeclarationNameExtra - Common base of the MultiKeywordSelector, CXXSpecialName, and CXXOperatorIdName...
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...
MultiKeywordSelector - One of these variable length records is kept for each selector containing more...
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.