clang: lib/Basic/IdentifierTable.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
22#include "llvm/ADT/DenseMapInfo.h"
23#include "llvm/ADT/FoldingSet.h"
24#include "llvm/ADT/SmallString.h"
25#include "llvm/ADT/StringMap.h"
26#include "llvm/ADT/StringRef.h"
27#include "llvm/Support/Allocator.h"
28#include "llvm/Support/raw_ostream.h"
29#include
30#include
31#include
32#include
33
34using namespace clang;
35
36
37
38
40 "Insufficient ObjCOrBuiltinID Bits");
41
42
43
44
45
47
49
50namespace {
51
52
53
55public:
56 StringRef Next() override { return StringRef(); }
57};
58
59}
60
62 return new EmptyLookupIterator();
63}
64
66 : HashTable(8192),
67 ExternalLookup(ExternalLookup) {}
68
72
73
75}
76
77
78
79
80
81
82namespace {
83
84enum TokenKey : unsigned {
85 KEYC99 = 0x1,
86 KEYCXX = 0x2,
87 KEYCXX11 = 0x4,
88 KEYGNU = 0x8,
89 KEYMS = 0x10,
90 BOOLSUPPORT = 0x20,
91 KEYALTIVEC = 0x40,
92 KEYNOCXX = 0x80,
93 KEYBORLAND = 0x100,
94 KEYOPENCLC = 0x200,
95 KEYC23 = 0x400,
96 KEYNOMS18 = 0x800,
97 KEYNOOPENCL = 0x1000,
98 WCHARSUPPORT = 0x2000,
99 HALFSUPPORT = 0x4000,
100 CHAR8SUPPORT = 0x8000,
101 KEYOBJC = 0x10000,
102 KEYZVECTOR = 0x20000,
103 KEYCOROUTINES = 0x40000,
104 KEYMODULES = 0x80000,
105 KEYCXX20 = 0x100000,
106 KEYOPENCLCXX = 0x200000,
107 KEYMSCOMPAT = 0x400000,
108 KEYSYCL = 0x800000,
109 KEYCUDA = 0x1000000,
110 KEYZOS = 0x2000000,
111 KEYNOZOS = 0x4000000,
112 KEYHLSL = 0x8000000,
113 KEYFIXEDPOINT = 0x10000000,
114 KEYMAX = KEYFIXEDPOINT,
115 KEYALLCXX = KEYCXX | KEYCXX11 | KEYCXX20,
116 KEYALL = (KEYMAX | (KEYMAX - 1)) & ~KEYNOMS18 & ~KEYNOOPENCL &
117 ~KEYNOZOS
118};
119
120
121
122enum KeywordStatus {
123 KS_Unknown,
124 KS_Disabled,
125 KS_Future,
126 KS_Extension,
127 KS_Enabled,
128};
129
130}
131
132
133
134
135
136
137
139 TokenKey Flag) {
140
141
142 assert((Flag & ~(Flag - 1)) == Flag && "Multiple bits set?");
143
144 switch (Flag) {
145 case KEYC99:
146 if (LangOpts.C99)
147 return KS_Enabled;
148 return !LangOpts.CPlusPlus ? KS_Future : KS_Unknown;
149 case KEYC23:
150 if (LangOpts.C23)
151 return KS_Enabled;
152 return !LangOpts.CPlusPlus ? KS_Future : KS_Unknown;
153 case KEYCXX:
154 return LangOpts.CPlusPlus ? KS_Enabled : KS_Unknown;
155 case KEYCXX11:
156 if (LangOpts.CPlusPlus11)
157 return KS_Enabled;
158 return LangOpts.CPlusPlus ? KS_Future : KS_Unknown;
159 case KEYCXX20:
160 if (LangOpts.CPlusPlus20)
161 return KS_Enabled;
162 return LangOpts.CPlusPlus ? KS_Future : KS_Unknown;
163 case KEYGNU:
164 return LangOpts.GNUKeywords ? KS_Extension : KS_Unknown;
165 case KEYMS:
166 return LangOpts.MicrosoftExt ? KS_Extension : KS_Unknown;
167 case BOOLSUPPORT:
168 if (LangOpts.Bool) return KS_Enabled;
169 return !LangOpts.CPlusPlus ? KS_Future : KS_Unknown;
170 case KEYALTIVEC:
171 return LangOpts.AltiVec ? KS_Enabled : KS_Unknown;
172 case KEYBORLAND:
173 return LangOpts.Borland ? KS_Extension : KS_Unknown;
174 case KEYOPENCLC:
175 return LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus ? KS_Enabled
176 : KS_Unknown;
177 case WCHARSUPPORT:
178 return LangOpts.WChar ? KS_Enabled : KS_Unknown;
179 case HALFSUPPORT:
180 return LangOpts.Half ? KS_Enabled : KS_Unknown;
181 case CHAR8SUPPORT:
182 if (LangOpts.Char8) return KS_Enabled;
183 if (LangOpts.CPlusPlus20) return KS_Unknown;
184 if (LangOpts.CPlusPlus) return KS_Future;
185 return KS_Unknown;
186 case KEYOBJC:
187
188
189 return LangOpts.ObjC ? KS_Enabled : KS_Unknown;
190 case KEYZVECTOR:
191 return LangOpts.ZVector ? KS_Enabled : KS_Unknown;
192 case KEYCOROUTINES:
193 return LangOpts.Coroutines ? KS_Enabled : KS_Unknown;
194 case KEYMODULES:
195 return KS_Unknown;
196 case KEYOPENCLCXX:
197 return LangOpts.OpenCLCPlusPlus ? KS_Enabled : KS_Unknown;
198 case KEYMSCOMPAT:
199 return LangOpts.MSVCCompat ? KS_Enabled : KS_Unknown;
200 case KEYSYCL:
201 return LangOpts.isSYCL() ? KS_Enabled : KS_Unknown;
202 case KEYCUDA:
203 return LangOpts.CUDA ? KS_Enabled : KS_Unknown;
204 case KEYZOS:
205 return LangOpts.ZOSExt ? KS_Enabled : KS_Unknown;
206 case KEYHLSL:
207 return LangOpts.HLSL ? KS_Enabled : KS_Unknown;
208 case KEYNOCXX:
209
210
211 return LangOpts.CPlusPlus ? KS_Unknown : KS_Enabled;
212 case KEYNOOPENCL:
213 case KEYNOMS18:
214 case KEYNOZOS:
215
216 return KS_Unknown;
217 case KEYFIXEDPOINT:
218 return LangOpts.FixedPoint ? KS_Enabled : KS_Disabled;
219 default:
220 llvm_unreachable("Unknown KeywordStatus flag");
221 }
222}
223
224
225
227 unsigned Flags) {
228
229 if (Flags == KEYALL) return KS_Enabled;
230
231
232 if (LangOpts.OpenCL && (Flags & KEYNOOPENCL)) return KS_Disabled;
233 if (LangOpts.MSVCCompat && (Flags & KEYNOMS18) &&
235 return KS_Disabled;
236 if (LangOpts.ZOSExt && (Flags & KEYNOZOS))
237 return KS_Disabled;
238 KeywordStatus CurStatus = KS_Unknown;
239
240 while (Flags != 0) {
241 unsigned CurFlag = Flags & ~(Flags - 1);
242 Flags = Flags & ~CurFlag;
243 CurStatus = std::max(
244 CurStatus,
246 }
247
248 if (CurStatus == KS_Unknown)
249 return KS_Disabled;
250 return CurStatus;
251}
252
253
254
255
260
261
262 if (AddResult == KS_Disabled) return;
263
265 Table.get(Keyword, AddResult == KS_Future ? tok::identifier : TokenCode);
268}
269
270
271
277}
278
279
280
285}
286
290
291 if (BTID != tok::not_notable) {
294 }
295}
296
297
298
300
301#define KEYWORD(NAME, FLAGS) \
302 AddKeyword(StringRef(#NAME), tok::kw_ ## NAME, \
303 FLAGS, LangOpts, *this);
304#define ALIAS(NAME, TOK, FLAGS) \
305 AddKeyword(StringRef(NAME), tok::kw_ ## TOK, \
306 FLAGS, LangOpts, *this);
307#define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \
308 if (LangOpts.CXXOperatorNames) \
309 AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this);
310#define OBJC_AT_KEYWORD(NAME) \
311 if (LangOpts.ObjC) \
312 AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
313#define NOTABLE_IDENTIFIER(NAME) \
314 AddNotableIdentifier(StringRef(#NAME), tok::NAME, *this);
315
316#define TESTING_KEYWORD(NAME, FLAGS)
317#include "clang/Basic/TokenKinds.def"
318
319 if (LangOpts.ParseUnknownAnytype)
320 AddKeyword("__unknown_anytype", tok::kw___unknown_anytype, KEYALL,
321 LangOpts, *this);
322
323 if (LangOpts.DeclSpecKeyword)
324 AddKeyword("__declspec", tok::kw___declspec, KEYALL, LangOpts, *this);
325
326 if (LangOpts.IEEE128)
327 AddKeyword("__ieee128", tok::kw___float128, KEYALL, LangOpts, *this);
328
329
331}
332
333
334
335
338 switch (K) {
339#define KEYWORD(NAME, FLAGS) \
340 case tok::kw_##NAME: return getKeywordStatus(LangOpts, FLAGS);
341#include "clang/Basic/TokenKinds.def"
342 default: return KS_Disabled;
343 }
344}
345
346
347
350 case KS_Enabled:
351 case KS_Extension:
352 return true;
353 default:
354 return false;
355 }
356}
357
358
359
361 if (!LangOpts.CPlusPlus || (LangOpts))
362 return false;
363
364
366 LangOptsNoCPP.CPlusPlus = false;
367 LangOptsNoCPP.CPlusPlus11 = false;
368 LangOptsNoCPP.CPlusPlus20 = false;
369 return (LangOptsNoCPP);
370}
371
374 StringRef Name = getName();
375
376
377
378 if (Name.size() <= 1)
380
381
382 if (Name[0] == '_') {
383
384
385
386 if (Name[1] == '_')
388
389 if ('A' <= Name[1] && Name[1] <= 'Z')
392
393
394
396 }
397
398
399 if (LangOpts.CPlusPlus && Name.contains("__"))
401
403}
404
407 StringRef Name = getName();
408
409
410
411
412 if (Name[0] != '_')
414
415 if (Name.contains("__"))
417
419}
420
422 StringRef Name = getName();
423 if (Name.size() >= 2 && Name.front() == '_' &&
424 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
425 return Name.ltrim('_');
426 return Name;
427}
428
430
431
432
433
434
435#define HASH(LEN, FIRST, THIRD) \
436 (LEN << 6) + (((FIRST - 'a') - (THIRD - 'a')) & 63)
437#define CASE(LEN, FIRST, THIRD, NAME) \
438 case HASH(LEN, FIRST, THIRD): \
439 return memcmp(Name, #NAME, LEN) ? tok::pp_not_keyword : tok::pp_ ## NAME
440
442 if (Len < 2) return tok::pp_not_keyword;
444 switch (HASH(Len, Name[0], Name[2])) {
445 default: return tok::pp_not_keyword;
446 CASE( 2, 'i', '\0', if);
447 CASE( 4, 'e', 'i', elif);
448 CASE( 4, 'e', 's', else);
449 CASE( 4, 'l', 'n', line);
450 CASE( 4, 's', 'c', sccs);
451 CASE( 5, 'e', 'b', embed);
452 CASE( 5, 'e', 'd', endif);
453 CASE( 5, 'e', 'r', error);
454 CASE( 5, 'i', 'e', ident);
455 CASE( 5, 'i', 'd', ifdef);
456 CASE( 5, 'u', 'd', undef);
457
458 CASE( 6, 'a', 's', assert);
459 CASE( 6, 'd', 'f', define);
460 CASE( 6, 'i', 'n', ifndef);
461 CASE( 6, 'i', 'p', import);
462 CASE( 6, 'p', 'a', pragma);
463
464 CASE( 7, 'd', 'f', defined);
465 CASE( 7, 'e', 'i', elifdef);
466 CASE( 7, 'i', 'c', include);
467 CASE( 7, 'w', 'r', warning);
468
469 CASE( 8, 'e', 'i', elifndef);
470 CASE( 8, 'u', 'a', unassert);
471 CASE(12, 'i', 'c', include_next);
472
473 CASE(14, '_', 'p', __public_macro);
474
475 CASE(15, '_', 'p', __private_macro);
476
477 CASE(16, '_', 'i', __include_macros);
478#undef CASE
479#undef HASH
480 }
481}
482
483
484
485
486
487
488
490 unsigned NumBuckets = HashTable.getNumBuckets();
491 unsigned NumIdentifiers = HashTable.getNumItems();
492 unsigned NumEmptyBuckets = NumBuckets-NumIdentifiers;
493 unsigned AverageIdentifierSize = 0;
494 unsigned MaxIdentifierLength = 0;
495
496
497 for (llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator>::const_iterator
498 I = HashTable.begin(), E = HashTable.end(); I != E; ++I) {
499 unsigned IdLen = I->getKeyLength();
500 AverageIdentifierSize += IdLen;
501 if (MaxIdentifierLength < IdLen)
502 MaxIdentifierLength = IdLen;
503 }
504
505 fprintf(stderr, "\n*** Identifier Table Stats:\n");
506 fprintf(stderr, "# Identifiers: %d\n", NumIdentifiers);
507 fprintf(stderr, "# Empty Buckets: %d\n", NumEmptyBuckets);
508 fprintf(stderr, "Hash density (#identifiers per bucket): %f\n",
509 NumIdentifiers/(double)NumBuckets);
510 fprintf(stderr, "Ave identifier length: %f\n",
511 (AverageIdentifierSize/(double)NumIdentifiers));
512 fprintf(stderr, "Max identifier length: %d\n", MaxIdentifierLength);
513
514
515 HashTable.getAllocator().PrintStats();
516}
517
518
519
520
521
522unsigned llvm::DenseMapInfoclang::Selector::getHashValue(clang::Selector S) {
523 return DenseMapInfo<void*>::getHashValue(S.getAsOpaquePtr());
524}
525
527 assert(!Names.empty() && "must have >= 1 selector slots");
529 return false;
530 for (unsigned I = 0, E = Names.size(); I != E; ++I) {
532 return false;
533 }
534 return true;
535}
536
539}
540
542 unsigned IIF = getIdentifierInfoFlag();
543 if (IIF <= ZeroArg)
544 return 0;
545 if (IIF == OneArg)
546 return 1;
547
550}
551
554 if (getIdentifierInfoFlag() < MultiArg) {
555 assert(argIndex == 0 && "illegal keyword index");
556 return getAsIdentifierInfo();
557 }
558
559
562}
563
566 return II ? II->getName() : StringRef();
567}
568
571 llvm::raw_svector_ostream OS(Str);
573 if (*I)
574 OS << (*I)->getName();
575 OS << ':';
576 }
577
578 return std::string(OS.str());
579}
580
583 return "";
584
585 if (getIdentifierInfoFlag() < MultiArg) {
587
589 assert(II && "If the number of arguments is 0 then II is guaranteed to "
590 "not be null.");
591 return std::string(II->getName());
592 }
593
594 if (!II)
595 return ":";
596
597 return II->getName().str() + ":";
598 }
599
600
601 return getMultiKeywordSelector()->getName();
602}
603
606}
607
609
610
611
612
614 if (name.size() < word.size()) return false;
615 return ((name.size() == word.size() || (name[word.size()])) &&
616 name.starts_with(word));
617}
618
622
626 if (name == "dealloc") return OMF_dealloc;
628 if (name == "release") return OMF_release;
629 if (name == "retain") return OMF_retain;
631 if (name == "self") return OMF_self;
633 }
634
635 if (name == "performSelector" || name == "performSelectorInBackground" ||
636 name == "performSelectorOnMainThread")
638
639
641
643 switch (name.front()) {
644 case 'a':
646 break;
647 case 'c':
649 break;
650 case 'i':
652 break;
653 case 'm':
655 break;
656 case 'n':
658 break;
659 default:
660 break;
661 }
662
664}
665
669
670 StringRef name = first->getName();
671
672 if (name.empty()) return OIT_None;
673 switch (name.front()) {
674 case 'a':
676 break;
677 case 'd':
680 break;
681 case 's':
684 break;
685 case 'i':
687 break;
688 default:
689 break;
690 }
692}
693
697
698 StringRef name = first->getName();
699
700 switch (name.front()) {
701 case 'a':
702 if (name == "appendFormat") return SFF_NSString;
703 break;
704
705 case 'i':
706 if (name == "initWithFormat") return SFF_NSString;
707 break;
708
709 case 'l':
710 if (name == "localizedStringWithFormat") return SFF_NSString;
711 break;
712
713 case 's':
714 if (name == "stringByAppendingFormat" ||
715 name == "stringWithFormat") return SFF_NSString;
716 break;
717 }
719}
720
721namespace {
722
723struct SelectorTableImpl {
724 llvm::FoldingSet Table;
725 llvm::BumpPtrAllocator Allocator;
726};
727
728}
729
731 return *static_cast<SelectorTableImpl*>(P);
732}
733
737 SetterName += Name;
738 SetterName[3] = toUppercase(SetterName[3]);
739 return SetterName;
740}
741
749}
750
753 assert(Name.starts_with("set") && "invalid setter name");
754 return (Twine(toLowercase(Name[3])) + Name.drop_front(4)).str();
755}
756
759 return SelTabImpl.Allocator.getTotalMemory();
760}
761
764 if (nKeys < 2)
765 return Selector(IIV[0], nKeys);
766
768
769
770 llvm::FoldingSetNodeID ID;
772
773 void *InsertPos = nullptr;
775 SelTabImpl.Table.FindNodeOrInsertPos(ID, InsertPos))
777
778
779
785 SelTabImpl.Table.InsertNode(SI, InsertPos);
787}
788
790 Impl = new SelectorTableImpl();
791}
792
795}
796
798 switch (Operator) {
801 return nullptr;
802
803#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
804 case OO_##Name: return Spelling;
805#include "clang/Basic/OperatorKinds.def"
806 }
807
808 llvm_unreachable("Invalid OverloadedOperatorKind!");
809}
810
812 bool isContextSensitive) {
813 switch (kind) {
815 return isContextSensitive ? "nonnull" : "_Nonnull";
816
818 return isContextSensitive ? "nullable" : "_Nullable";
819
821 assert(!isContextSensitive &&
822 "_Nullable_result isn't supported as context-sensitive keyword");
823 return "_Nullable_result";
824
826 return isContextSensitive ? "null_unspecified" : "_Null_unspecified";
827 }
828 llvm_unreachable("Unknown nullability kind.");
829}
830
833 switch (NK) {
835 return OS << "NonNull";
837 return OS << "Nullable";
839 return OS << "NullableResult";
841 return OS << "Unspecified";
842 }
843 llvm_unreachable("Unknown nullability kind.");
844}
845
850
851 unsigned Flags = llvm::StringSwitch(II.getName())
852#define KEYWORD(NAME, FLAGS) .Case(#NAME, FLAGS)
853#include "clang/Basic/TokenKinds.def"
854#undef KEYWORD
855 ;
856
857 if (LangOpts.CPlusPlus) {
858 if ((Flags & KEYCXX11) == KEYCXX11)
859 return diag::warn_cxx11_keyword;
860
861
862
863
864 if (((Flags & KEYCXX20) == KEYCXX20) ||
865 ((Flags & CHAR8SUPPORT) == CHAR8SUPPORT))
866 return diag::warn_cxx20_keyword;
867 } else {
868 if ((Flags & KEYC99) == KEYC99)
869 return diag::warn_c99_keyword;
870 if ((Flags & KEYC23) == KEYC23)
871 return diag::warn_c23_keyword;
872 }
873
874 llvm_unreachable(
875 "Keyword not known to come from a newer Standard or proposed Standard");
876}
static void AddObjCKeyword(StringRef Name, tok::ObjCKeywordKind ObjCID, IdentifierTable &Table)
AddObjCKeyword - Register an Objective-C @keyword like "class" "selector" or "property".
static void AddCXXOperatorKeyword(StringRef Keyword, tok::TokenKind TokenCode, IdentifierTable &Table)
AddCXXOperatorKeyword - Register a C++ operator keyword alternative representations.
static void AddNotableIdentifier(StringRef Name, tok::NotableIdentifierKind BTID, IdentifierTable &Table)
static KeywordStatus getKeywordStatusHelper(const LangOptions &LangOpts, TokenKey Flag)
static KeywordStatus getTokenKwStatus(const LangOptions &LangOpts, tok::TokenKind K)
Checks if the specified token kind represents 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...
#define CASE(LEN, FIRST, THIRD, NAME)
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...
static SelectorTableImpl & getSelectorTableImpl(void *P)
static KeywordStatus getKeywordStatus(const LangOptions &LangOpts, unsigned Flags)
Translates flags as specified in TokenKinds.def into keyword status in the given language standard.
#define HASH(LEN, FIRST, THIRD)
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Defines the clang::LangOptions interface.
Defines an enumeration for C++ overloaded operators.
Defines various enumerations that describe declaration and type specifiers.
Enumerates target-specific builtins in their own namespaces within namespace clang.
Defines the clang::TokenKind enum and support functions.
Provides lookups to, and iteration over, IdentiferInfo objects.
virtual ~IdentifierInfoLookup()
virtual IdentifierIterator * getIdentifiers()
Retrieve an iterator into the set of all identifiers known to this identifier lookup source.
One of these records is kept for each identifier that is lexed.
bool isCPlusPlusKeyword(const LangOptions &LangOpts) const
Return true if this token is a C++ keyword in the specified language.
unsigned getLength() const
Efficiently return the length of this identifier info.
void setModulesImport(bool I)
Set whether this identifier is the contextual keyword import.
void setNotableIdentifierID(unsigned ID)
void setIsExtensionToken(bool Val)
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
void setObjCKeywordID(tok::ObjCKeywordKind ID)
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
bool isKeyword(const LangOptions &LangOpts) const
Return true if this token is a keyword in the specified language.
ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const
Determine whether this is a name reserved for the implementation (C99 7.1.3, C++ [lib....
void setIsCPlusPlusOperatorKeyword(bool Val=true)
isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether this identifier is a C++ al...
ReservedLiteralSuffixIdStatus isReservedLiteralSuffixId() const
Determine whether this is a name reserved for future standardization or the implementation (C++ [usrl...
void setIsFutureCompatKeyword(bool Val)
StringRef deuglifiedName() const
If the identifier is an "uglified" reserved name, return a cleaned form.
StringRef getName() const
Return the actual identifier string.
bool isFutureCompatKeyword() const
is/setIsFutureCompatKeyword - Initialize information about whether or not this language token is a ke...
An iterator that walks over all of the known identifiers in the lookup table.
virtual StringRef Next()=0
Retrieve the next string in the identifier table and advances the iterator for the following string.
virtual ~IdentifierIterator()
Implements an efficient mapping from strings to IdentifierInfo nodes.
IdentifierTable(IdentifierInfoLookup *ExternalLookup=nullptr)
Create the identifier table.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
void PrintStats() const
Print some statistics to stderr that indicate how well the hashing is doing.
void AddKeywords(const LangOptions &LangOpts)
Populate the identifier table with info about the language keywords for the language specified by Lan...
diag::kind getFutureCompatDiagKind(const IdentifierInfo &II, const LangOptions &LangOpts)
Returns the correct diagnostic to issue for a future-compat diagnostic warning.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const
One of these variable length records is kept for each selector containing more than one keyword.
keyword_iterator keyword_end() const
const IdentifierInfo *const * keyword_iterator
std::string getName() const
static void Profile(llvm::FoldingSetNodeID &ID, keyword_iterator ArgTys, unsigned NumArgs)
keyword_iterator keyword_begin() const
const IdentifierInfo * getIdentifierInfoForSlot(unsigned i) const
This table allows us to fully hide how we implement multi-keyword caching.
static std::string getPropertyNameFromSetterSelector(Selector Sel)
Return the property name for the given setter selector.
static Selector constructSetterSelector(IdentifierTable &Idents, SelectorTable &SelTable, const IdentifierInfo *Name)
Return the default setter selector for the given identifier.
size_t getTotalMemory() const
Return the total amount of memory allocated for managing selectors.
Selector getSelector(unsigned NumArgs, const IdentifierInfo **IIV)
Can create any sort of selector.
Selector getUnarySelector(const IdentifierInfo *ID)
static SmallString< 64 > constructSetterName(StringRef Name)
Return the default setter name for the given identifier.
Smart pointer class that efficiently represents Objective-C method names.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
const IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
std::string getAsString() const
Derive the full selector name (e.g.
void print(llvm::raw_ostream &OS) const
Prints the full selector name (e.g. "foo:bar:").
bool isKeywordSelector() const
static ObjCInstanceTypeFamily getInstTypeMethodFamily(Selector sel)
bool isUnarySelector() const
bool isNull() const
Determine whether this is the empty selector.
unsigned getNumArgs() const
unsigned kind
All of the diagnostics that can be emitted by the frontend.
NotableIdentifierKind
Provides a namespace for notable identifers such as float_t and double_t.
ObjCKeywordKind
Provides a namespace for Objective-C keywords which start with an '@'.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
PPKeywordKind
Provides a namespace for preprocessor keywords which start with a '#' at the beginning of the line.
RangeSelector name(std::string ID)
Given a node with a "name", (like NamedDecl, DeclRefExpr, CxxCtorInitializer, and TypeLoc) selects th...
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
@ NUM_OVERLOADED_OPERATORS
NullabilityKind
Describes the nullability of a particular type.
@ Nullable
Values of this type can be null.
@ Unspecified
Whether values of this type can be null is (explicitly) unspecified.
@ NonNull
Values of this type can never be null.
LLVM_READONLY char toLowercase(char c)
Converts the given ASCII character to its lowercase equivalent.
ObjCMethodFamily
A family of Objective-C methods.
@ OMF_None
No particular method family.
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)
Insertion operator for diagnostics.
llvm::StringRef getNullabilitySpelling(NullabilityKind kind, bool isContextSensitive=false)
Retrieve the spelling of the given nullability kind.
ObjCInstanceTypeFamily
A family of Objective-C methods.
ReservedLiteralSuffixIdStatus
@ NotStartsWithUnderscore
@ ContainsDoubleUnderscore
LLVM_READONLY bool isLowercase(unsigned char c)
Return true if this character is a lowercase ASCII letter: [a-z].
LLVM_READONLY char toUppercase(char c)
Converts the given ASCII character to its uppercase equivalent.
static constexpr int InterestingIdentifierBits
static constexpr uint64_t LargestBuiltinID
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.
@ StartsWithDoubleUnderscore
@ StartsWithUnderscoreFollowedByCapitalLetter
@ ContainsDoubleUnderscore
@ StartsWithUnderscoreAtGlobalScope