1 //===- IdentifierTable.cpp - Hash table for identifier lookup -------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements the IdentifierInfo, IdentifierVisitor, and
10 // IdentifierTable interfaces.
12 //===----------------------------------------------------------------------===//
14 #include "clang/Basic/IdentifierTable.h"
15 #include "clang/Basic/CharInfo.h"
16 #include "clang/Basic/DiagnosticLex.h"
17 #include "clang/Basic/LangOptions.h"
18 #include "clang/Basic/OperatorKinds.h"
19 #include "clang/Basic/Specifiers.h"
20 #include "clang/Basic/TargetBuiltins.h"
21 #include "clang/Basic/TokenKinds.h"
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"
34 using namespace clang
;
36 // A check to make sure the ObjCOrBuiltinID has sufficient room to store the
37 // largest possible target/aux-target combination. If we exceed this, we likely
38 // need to just change the ObjCOrBuiltinIDBits value in IdentifierTable.h.
39 static_assert(2 * LargestBuiltinID
< (2 << (ObjCOrBuiltinIDBits
- 1)),
40 "Insufficient ObjCOrBuiltinID Bits");
42 //===----------------------------------------------------------------------===//
43 // IdentifierTable Implementation
44 //===----------------------------------------------------------------------===//
46 IdentifierIterator::~IdentifierIterator() = default;
48 IdentifierInfoLookup::~IdentifierInfoLookup() = default;
52 /// A simple identifier lookup iterator that represents an
53 /// empty sequence of identifiers.
54 class EmptyLookupIterator
: public IdentifierIterator
{
56 StringRef
Next() override
{ return StringRef(); }
61 IdentifierIterator
*IdentifierInfoLookup::getIdentifiers() {
62 return new EmptyLookupIterator();
65 IdentifierTable::IdentifierTable(IdentifierInfoLookup
*ExternalLookup
)
66 : HashTable(8192), // Start with space for 8K identifiers.
67 ExternalLookup(ExternalLookup
) {}
69 IdentifierTable::IdentifierTable(const LangOptions
&LangOpts
,
70 IdentifierInfoLookup
*ExternalLookup
)
71 : IdentifierTable(ExternalLookup
) {
72 // Populate the identifier table with info about keywords for the current
74 AddKeywords(LangOpts
);
77 //===----------------------------------------------------------------------===//
78 // Language Keyword Implementation
79 //===----------------------------------------------------------------------===//
81 // Constants for TokenKinds.def
84 enum TokenKey
: unsigned {
98 WCHARSUPPORT
= 0x2000,
100 CHAR8SUPPORT
= 0x8000,
102 KEYZVECTOR
= 0x20000,
103 KEYCOROUTINES
= 0x40000,
104 KEYMODULES
= 0x80000,
106 KEYOPENCLCXX
= 0x200000,
107 KEYMSCOMPAT
= 0x400000,
111 KEYMAX
= KEYHLSL
, // The maximum key
112 KEYALLCXX
= KEYCXX
| KEYCXX11
| KEYCXX20
,
113 KEYALL
= (KEYMAX
| (KEYMAX
-1)) & ~KEYNOMS18
&
114 ~KEYNOOPENCL
// KEYNOMS18 and KEYNOOPENCL are used to exclude.
117 /// How a keyword is treated in the selected standard. This enum is ordered
118 /// intentionally so that the value that 'wins' is the most 'permissive'.
120 KS_Unknown
, // Not yet calculated. Used when figuring out the status.
121 KS_Disabled
, // Disabled
122 KS_Future
, // Is a keyword in future standard
123 KS_Extension
, // Is an extension
124 KS_Enabled
, // Enabled
129 // This works on a single TokenKey flag and checks the LangOpts to get the
130 // KeywordStatus based exclusively on this flag, so that it can be merged in
131 // getKeywordStatus. Most should be enabled/disabled, but some might imply
132 // 'future' versions, or extensions. Returns 'unknown' unless this is KNOWN to
133 // be disabled, and the calling function makes it 'disabled' if no other flag
134 // changes it. This is necessary for the KEYNOCXX and KEYNOOPENCL flags.
135 static KeywordStatus
getKeywordStatusHelper(const LangOptions
&LangOpts
,
137 // Flag is a single bit version of TokenKey (that is, not
138 // KEYALL/KEYALLCXX/etc), so we can check with == throughout this function.
139 assert((Flag
& ~(Flag
- 1)) == Flag
&& "Multiple bits set?");
145 return !LangOpts
.CPlusPlus
? KS_Future
: KS_Unknown
;
149 return !LangOpts
.CPlusPlus
? KS_Future
: KS_Unknown
;
151 return LangOpts
.CPlusPlus
? KS_Enabled
: KS_Unknown
;
153 if (LangOpts
.CPlusPlus11
)
155 return LangOpts
.CPlusPlus
? KS_Future
: KS_Unknown
;
157 if (LangOpts
.CPlusPlus20
)
159 return LangOpts
.CPlusPlus
? KS_Future
: KS_Unknown
;
161 return LangOpts
.GNUKeywords
? KS_Extension
: KS_Unknown
;
163 return LangOpts
.MicrosoftExt
? KS_Extension
: KS_Unknown
;
165 if (LangOpts
.Bool
) return KS_Enabled
;
166 return !LangOpts
.CPlusPlus
? KS_Future
: KS_Unknown
;
168 return LangOpts
.AltiVec
? KS_Enabled
: KS_Unknown
;
170 return LangOpts
.Borland
? KS_Extension
: KS_Unknown
;
172 return LangOpts
.OpenCL
&& !LangOpts
.OpenCLCPlusPlus
? KS_Enabled
175 return LangOpts
.WChar
? KS_Enabled
: KS_Unknown
;
177 return LangOpts
.Half
? KS_Enabled
: KS_Unknown
;
179 if (LangOpts
.Char8
) return KS_Enabled
;
180 if (LangOpts
.CPlusPlus20
) return KS_Unknown
;
181 if (LangOpts
.CPlusPlus
) return KS_Future
;
184 // We treat bridge casts as objective-C keywords so we can warn on them
186 return LangOpts
.ObjC
? KS_Enabled
: KS_Unknown
;
188 return LangOpts
.ZVector
? KS_Enabled
: KS_Unknown
;
190 return LangOpts
.Coroutines
? KS_Enabled
: KS_Unknown
;
194 return LangOpts
.OpenCLCPlusPlus
? KS_Enabled
: KS_Unknown
;
196 return LangOpts
.MSVCCompat
? KS_Enabled
: KS_Unknown
;
198 return LangOpts
.isSYCL() ? KS_Enabled
: KS_Unknown
;
200 return LangOpts
.CUDA
? KS_Enabled
: KS_Unknown
;
202 return LangOpts
.HLSL
? KS_Enabled
: KS_Unknown
;
204 // This is enabled in all non-C++ modes, but might be enabled for other
206 return LangOpts
.CPlusPlus
? KS_Unknown
: KS_Enabled
;
208 // The disable behavior for this is handled in getKeywordStatus.
211 // The disable behavior for this is handled in getKeywordStatus.
214 llvm_unreachable("Unknown KeywordStatus flag");
218 /// Translates flags as specified in TokenKinds.def into keyword status
219 /// in the given language standard.
220 static KeywordStatus
getKeywordStatus(const LangOptions
&LangOpts
,
222 // KEYALL means always enabled, so special case this one.
223 if (Flags
== KEYALL
) return KS_Enabled
;
224 // These are tests that need to 'always win', as they are special in that they
225 // disable based on certain conditions.
226 if (LangOpts
.OpenCL
&& (Flags
& KEYNOOPENCL
)) return KS_Disabled
;
227 if (LangOpts
.MSVCCompat
&& (Flags
& KEYNOMS18
) &&
228 !LangOpts
.isCompatibleWithMSVC(LangOptions::MSVC2015
))
231 KeywordStatus CurStatus
= KS_Unknown
;
234 unsigned CurFlag
= Flags
& ~(Flags
- 1);
235 Flags
= Flags
& ~CurFlag
;
236 CurStatus
= std::max(
238 getKeywordStatusHelper(LangOpts
, static_cast<TokenKey
>(CurFlag
)));
241 if (CurStatus
== KS_Unknown
)
246 /// AddKeyword - This method is used to associate a token ID with specific
247 /// identifiers because they are language keywords. This causes the lexer to
248 /// automatically map matching identifiers to specialized token codes.
249 static void AddKeyword(StringRef Keyword
,
250 tok::TokenKind TokenCode
, unsigned Flags
,
251 const LangOptions
&LangOpts
, IdentifierTable
&Table
) {
252 KeywordStatus AddResult
= getKeywordStatus(LangOpts
, Flags
);
254 // Don't add this keyword if disabled in this language.
255 if (AddResult
== KS_Disabled
) return;
257 IdentifierInfo
&Info
=
258 Table
.get(Keyword
, AddResult
== KS_Future
? tok::identifier
: TokenCode
);
259 Info
.setIsExtensionToken(AddResult
== KS_Extension
);
260 Info
.setIsFutureCompatKeyword(AddResult
== KS_Future
);
263 /// AddCXXOperatorKeyword - Register a C++ operator keyword alternative
265 static void AddCXXOperatorKeyword(StringRef Keyword
,
266 tok::TokenKind TokenCode
,
267 IdentifierTable
&Table
) {
268 IdentifierInfo
&Info
= Table
.get(Keyword
, TokenCode
);
269 Info
.setIsCPlusPlusOperatorKeyword();
272 /// AddObjCKeyword - Register an Objective-C \@keyword like "class" "selector"
274 static void AddObjCKeyword(StringRef Name
,
275 tok::ObjCKeywordKind ObjCID
,
276 IdentifierTable
&Table
) {
277 Table
.get(Name
).setObjCKeywordID(ObjCID
);
280 static void AddInterestingIdentifier(StringRef Name
,
281 tok::InterestingIdentifierKind BTID
,
282 IdentifierTable
&Table
) {
283 // Don't add 'not_interesting' identifier.
284 if (BTID
!= tok::not_interesting
) {
285 IdentifierInfo
&Info
= Table
.get(Name
, tok::identifier
);
286 Info
.setInterestingIdentifierID(BTID
);
290 /// AddKeywords - Add all keywords to the symbol table.
292 void IdentifierTable::AddKeywords(const LangOptions
&LangOpts
) {
293 // Add keywords and tokens for the current language.
294 #define KEYWORD(NAME, FLAGS) \
295 AddKeyword(StringRef(#NAME), tok::kw_ ## NAME, \
296 FLAGS, LangOpts, *this);
297 #define ALIAS(NAME, TOK, FLAGS) \
298 AddKeyword(StringRef(NAME), tok::kw_ ## TOK, \
299 FLAGS, LangOpts, *this);
300 #define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \
301 if (LangOpts.CXXOperatorNames) \
302 AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this);
303 #define OBJC_AT_KEYWORD(NAME) \
305 AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
306 #define INTERESTING_IDENTIFIER(NAME) \
307 AddInterestingIdentifier(StringRef(#NAME), tok::NAME, *this);
309 #define TESTING_KEYWORD(NAME, FLAGS)
310 #include "clang/Basic/TokenKinds.def"
312 if (LangOpts
.ParseUnknownAnytype
)
313 AddKeyword("__unknown_anytype", tok::kw___unknown_anytype
, KEYALL
,
316 if (LangOpts
.DeclSpecKeyword
)
317 AddKeyword("__declspec", tok::kw___declspec
, KEYALL
, LangOpts
, *this);
319 if (LangOpts
.IEEE128
)
320 AddKeyword("__ieee128", tok::kw___float128
, KEYALL
, LangOpts
, *this);
322 // Add the 'import' contextual keyword.
323 get("import").setModulesImport(true);
326 /// Checks if the specified token kind represents a keyword in the
327 /// specified language.
328 /// \returns Status of the keyword in the language.
329 static KeywordStatus
getTokenKwStatus(const LangOptions
&LangOpts
,
332 #define KEYWORD(NAME, FLAGS) \
333 case tok::kw_##NAME: return getKeywordStatus(LangOpts, FLAGS);
334 #include "clang/Basic/TokenKinds.def"
335 default: return KS_Disabled
;
339 /// Returns true if the identifier represents a keyword in the
340 /// specified language.
341 bool IdentifierInfo::isKeyword(const LangOptions
&LangOpts
) const {
342 switch (getTokenKwStatus(LangOpts
, getTokenID())) {
351 /// Returns true if the identifier represents a C++ keyword in the
352 /// specified language.
353 bool IdentifierInfo::isCPlusPlusKeyword(const LangOptions
&LangOpts
) const {
354 if (!LangOpts
.CPlusPlus
|| !isKeyword(LangOpts
))
356 // This is a C++ keyword if this identifier is not a keyword when checked
357 // using LangOptions without C++ support.
358 LangOptions LangOptsNoCPP
= LangOpts
;
359 LangOptsNoCPP
.CPlusPlus
= false;
360 LangOptsNoCPP
.CPlusPlus11
= false;
361 LangOptsNoCPP
.CPlusPlus20
= false;
362 return !isKeyword(LangOptsNoCPP
);
365 ReservedIdentifierStatus
366 IdentifierInfo::isReserved(const LangOptions
&LangOpts
) const {
367 StringRef Name
= getName();
369 // '_' is a reserved identifier, but its use is so common (e.g. to store
370 // ignored values) that we don't warn on it.
371 if (Name
.size() <= 1)
372 return ReservedIdentifierStatus::NotReserved
;
375 if (Name
[0] == '_') {
377 // Each name that begins with an underscore followed by an uppercase letter
378 // or another underscore is reserved.
380 return ReservedIdentifierStatus::StartsWithDoubleUnderscore
;
382 if ('A' <= Name
[1] && Name
[1] <= 'Z')
383 return ReservedIdentifierStatus::
384 StartsWithUnderscoreFollowedByCapitalLetter
;
386 // This is a bit misleading: it actually means it's only reserved if we're
387 // at global scope because it starts with an underscore.
388 return ReservedIdentifierStatus::StartsWithUnderscoreAtGlobalScope
;
391 // Each name that contains a double underscore (__) is reserved.
392 if (LangOpts
.CPlusPlus
&& Name
.contains("__"))
393 return ReservedIdentifierStatus::ContainsDoubleUnderscore
;
395 return ReservedIdentifierStatus::NotReserved
;
398 ReservedLiteralSuffixIdStatus
399 IdentifierInfo::isReservedLiteralSuffixId() const {
400 StringRef Name
= getName();
403 return ReservedLiteralSuffixIdStatus::NotStartsWithUnderscore
;
405 if (Name
.contains("__"))
406 return ReservedLiteralSuffixIdStatus::ContainsDoubleUnderscore
;
408 return ReservedLiteralSuffixIdStatus::NotReserved
;
411 StringRef
IdentifierInfo::deuglifiedName() const {
412 StringRef Name
= getName();
413 if (Name
.size() >= 2 && Name
.front() == '_' &&
414 (Name
[1] == '_' || (Name
[1] >= 'A' && Name
[1] <= 'Z')))
415 return Name
.ltrim('_');
419 tok::PPKeywordKind
IdentifierInfo::getPPKeywordID() const {
420 // We use a perfect hash function here involving the length of the keyword,
421 // the first and third character. For preprocessor ID's there are no
422 // collisions (if there were, the switch below would complain about duplicate
423 // case values). Note that this depends on 'if' being null terminated.
425 #define HASH(LEN, FIRST, THIRD) \
426 (LEN << 5) + (((FIRST-'a') + (THIRD-'a')) & 31)
427 #define CASE(LEN, FIRST, THIRD, NAME) \
428 case HASH(LEN, FIRST, THIRD): \
429 return memcmp(Name, #NAME, LEN) ? tok::pp_not_keyword : tok::pp_ ## NAME
431 unsigned Len
= getLength();
432 if (Len
< 2) return tok::pp_not_keyword
;
433 const char *Name
= getNameStart();
434 switch (HASH(Len
, Name
[0], Name
[2])) {
435 default: return tok::pp_not_keyword
;
436 CASE( 2, 'i', '\0', if);
437 CASE( 4, 'e', 'i', elif
);
438 CASE( 4, 'e', 's', else);
439 CASE( 4, 'l', 'n', line
);
440 CASE( 4, 's', 'c', sccs
);
441 CASE( 5, 'e', 'd', endif
);
442 CASE( 5, 'e', 'r', error
);
443 CASE( 5, 'i', 'e', ident
);
444 CASE( 5, 'i', 'd', ifdef
);
445 CASE( 5, 'u', 'd', undef
);
447 CASE( 6, 'a', 's', assert);
448 CASE( 6, 'd', 'f', define
);
449 CASE( 6, 'i', 'n', ifndef
);
450 CASE( 6, 'i', 'p', import
);
451 CASE( 6, 'p', 'a', pragma
);
453 CASE( 7, 'd', 'f', defined
);
454 CASE( 7, 'e', 'i', elifdef
);
455 CASE( 7, 'i', 'c', include
);
456 CASE( 7, 'w', 'r', warning
);
458 CASE( 8, 'e', 'i', elifndef
);
459 CASE( 8, 'u', 'a', unassert
);
460 CASE(12, 'i', 'c', include_next
);
462 CASE(14, '_', 'p', __public_macro
);
464 CASE(15, '_', 'p', __private_macro
);
466 CASE(16, '_', 'i', __include_macros
);
472 //===----------------------------------------------------------------------===//
473 // Stats Implementation
474 //===----------------------------------------------------------------------===//
476 /// PrintStats - Print statistics about how well the identifier table is doing
477 /// at hashing identifiers.
478 void IdentifierTable::PrintStats() const {
479 unsigned NumBuckets
= HashTable
.getNumBuckets();
480 unsigned NumIdentifiers
= HashTable
.getNumItems();
481 unsigned NumEmptyBuckets
= NumBuckets
-NumIdentifiers
;
482 unsigned AverageIdentifierSize
= 0;
483 unsigned MaxIdentifierLength
= 0;
485 // TODO: Figure out maximum times an identifier had to probe for -stats.
486 for (llvm::StringMap
<IdentifierInfo
*, llvm::BumpPtrAllocator
>::const_iterator
487 I
= HashTable
.begin(), E
= HashTable
.end(); I
!= E
; ++I
) {
488 unsigned IdLen
= I
->getKeyLength();
489 AverageIdentifierSize
+= IdLen
;
490 if (MaxIdentifierLength
< IdLen
)
491 MaxIdentifierLength
= IdLen
;
494 fprintf(stderr
, "\n*** Identifier Table Stats:\n");
495 fprintf(stderr
, "# Identifiers: %d\n", NumIdentifiers
);
496 fprintf(stderr
, "# Empty Buckets: %d\n", NumEmptyBuckets
);
497 fprintf(stderr
, "Hash density (#identifiers per bucket): %f\n",
498 NumIdentifiers
/(double)NumBuckets
);
499 fprintf(stderr
, "Ave identifier length: %f\n",
500 (AverageIdentifierSize
/(double)NumIdentifiers
));
501 fprintf(stderr
, "Max identifier length: %d\n", MaxIdentifierLength
);
503 // Compute statistics about the memory allocated for identifiers.
504 HashTable
.getAllocator().PrintStats();
507 //===----------------------------------------------------------------------===//
508 // SelectorTable Implementation
509 //===----------------------------------------------------------------------===//
511 unsigned llvm::DenseMapInfo
<clang::Selector
>::getHashValue(clang::Selector S
) {
512 return DenseMapInfo
<void*>::getHashValue(S
.getAsOpaquePtr());
515 bool Selector::isKeywordSelector(ArrayRef
<StringRef
> Names
) const {
516 assert(!Names
.empty() && "must have >= 1 selector slots");
517 if (getNumArgs() != Names
.size())
519 for (unsigned I
= 0, E
= Names
.size(); I
!= E
; ++I
) {
520 if (getNameForSlot(I
) != Names
[I
])
526 bool Selector::isUnarySelector(StringRef Name
) const {
527 return isUnarySelector() && getNameForSlot(0) == Name
;
530 unsigned Selector::getNumArgs() const {
531 unsigned IIF
= getIdentifierInfoFlag();
536 // We point to a MultiKeywordSelector.
537 MultiKeywordSelector
*SI
= getMultiKeywordSelector();
538 return SI
->getNumArgs();
541 IdentifierInfo
*Selector::getIdentifierInfoForSlot(unsigned argIndex
) const {
542 if (getIdentifierInfoFlag() < MultiArg
) {
543 assert(argIndex
== 0 && "illegal keyword index");
544 return getAsIdentifierInfo();
547 // We point to a MultiKeywordSelector.
548 MultiKeywordSelector
*SI
= getMultiKeywordSelector();
549 return SI
->getIdentifierInfoForSlot(argIndex
);
552 StringRef
Selector::getNameForSlot(unsigned int argIndex
) const {
553 IdentifierInfo
*II
= getIdentifierInfoForSlot(argIndex
);
554 return II
? II
->getName() : StringRef();
557 std::string
MultiKeywordSelector::getName() const {
558 SmallString
<256> Str
;
559 llvm::raw_svector_ostream
OS(Str
);
560 for (keyword_iterator I
= keyword_begin(), E
= keyword_end(); I
!= E
; ++I
) {
562 OS
<< (*I
)->getName();
566 return std::string(OS
.str());
569 std::string
Selector::getAsString() const {
571 return "<null selector>";
573 if (getIdentifierInfoFlag() < MultiArg
) {
574 IdentifierInfo
*II
= getAsIdentifierInfo();
576 if (getNumArgs() == 0) {
577 assert(II
&& "If the number of arguments is 0 then II is guaranteed to "
579 return std::string(II
->getName());
585 return II
->getName().str() + ":";
588 // We have a multiple keyword selector.
589 return getMultiKeywordSelector()->getName();
592 void Selector::print(llvm::raw_ostream
&OS
) const {
596 LLVM_DUMP_METHOD
void Selector::dump() const { print(llvm::errs()); }
598 /// Interpreting the given string using the normal CamelCase
599 /// conventions, determine whether the given string starts with the
600 /// given "word", which is assumed to end in a lowercase letter.
601 static bool startsWithWord(StringRef name
, StringRef word
) {
602 if (name
.size() < word
.size()) return false;
603 return ((name
.size() == word
.size() || !isLowercase(name
[word
.size()])) &&
604 name
.startswith(word
));
607 ObjCMethodFamily
Selector::getMethodFamilyImpl(Selector sel
) {
608 IdentifierInfo
*first
= sel
.getIdentifierInfoForSlot(0);
609 if (!first
) return OMF_None
;
611 StringRef name
= first
->getName();
612 if (sel
.isUnarySelector()) {
613 if (name
== "autorelease") return OMF_autorelease
;
614 if (name
== "dealloc") return OMF_dealloc
;
615 if (name
== "finalize") return OMF_finalize
;
616 if (name
== "release") return OMF_release
;
617 if (name
== "retain") return OMF_retain
;
618 if (name
== "retainCount") return OMF_retainCount
;
619 if (name
== "self") return OMF_self
;
620 if (name
== "initialize") return OMF_initialize
;
623 if (name
== "performSelector" || name
== "performSelectorInBackground" ||
624 name
== "performSelectorOnMainThread")
625 return OMF_performSelector
;
627 // The other method families may begin with a prefix of underscores.
628 while (!name
.empty() && name
.front() == '_')
629 name
= name
.substr(1);
631 if (name
.empty()) return OMF_None
;
632 switch (name
.front()) {
634 if (startsWithWord(name
, "alloc")) return OMF_alloc
;
637 if (startsWithWord(name
, "copy")) return OMF_copy
;
640 if (startsWithWord(name
, "init")) return OMF_init
;
643 if (startsWithWord(name
, "mutableCopy")) return OMF_mutableCopy
;
646 if (startsWithWord(name
, "new")) return OMF_new
;
655 ObjCInstanceTypeFamily
Selector::getInstTypeMethodFamily(Selector sel
) {
656 IdentifierInfo
*first
= sel
.getIdentifierInfoForSlot(0);
657 if (!first
) return OIT_None
;
659 StringRef name
= first
->getName();
661 if (name
.empty()) return OIT_None
;
662 switch (name
.front()) {
664 if (startsWithWord(name
, "array")) return OIT_Array
;
667 if (startsWithWord(name
, "default")) return OIT_ReturnsSelf
;
668 if (startsWithWord(name
, "dictionary")) return OIT_Dictionary
;
671 if (startsWithWord(name
, "shared")) return OIT_ReturnsSelf
;
672 if (startsWithWord(name
, "standard")) return OIT_Singleton
;
675 if (startsWithWord(name
, "init")) return OIT_Init
;
683 ObjCStringFormatFamily
Selector::getStringFormatFamilyImpl(Selector sel
) {
684 IdentifierInfo
*first
= sel
.getIdentifierInfoForSlot(0);
685 if (!first
) return SFF_None
;
687 StringRef name
= first
->getName();
689 switch (name
.front()) {
691 if (name
== "appendFormat") return SFF_NSString
;
695 if (name
== "initWithFormat") return SFF_NSString
;
699 if (name
== "localizedStringWithFormat") return SFF_NSString
;
703 if (name
== "stringByAppendingFormat" ||
704 name
== "stringWithFormat") return SFF_NSString
;
712 struct SelectorTableImpl
{
713 llvm::FoldingSet
<MultiKeywordSelector
> Table
;
714 llvm::BumpPtrAllocator Allocator
;
719 static SelectorTableImpl
&getSelectorTableImpl(void *P
) {
720 return *static_cast<SelectorTableImpl
*>(P
);
724 SelectorTable::constructSetterName(StringRef Name
) {
725 SmallString
<64> SetterName("set");
727 SetterName
[3] = toUppercase(SetterName
[3]);
732 SelectorTable::constructSetterSelector(IdentifierTable
&Idents
,
733 SelectorTable
&SelTable
,
734 const IdentifierInfo
*Name
) {
735 IdentifierInfo
*SetterName
=
736 &Idents
.get(constructSetterName(Name
->getName()));
737 return SelTable
.getUnarySelector(SetterName
);
740 std::string
SelectorTable::getPropertyNameFromSetterSelector(Selector Sel
) {
741 StringRef Name
= Sel
.getNameForSlot(0);
742 assert(Name
.startswith("set") && "invalid setter name");
743 return (Twine(toLowercase(Name
[3])) + Name
.drop_front(4)).str();
746 size_t SelectorTable::getTotalMemory() const {
747 SelectorTableImpl
&SelTabImpl
= getSelectorTableImpl(Impl
);
748 return SelTabImpl
.Allocator
.getTotalMemory();
751 Selector
SelectorTable::getSelector(unsigned nKeys
, IdentifierInfo
**IIV
) {
753 return Selector(IIV
[0], nKeys
);
755 SelectorTableImpl
&SelTabImpl
= getSelectorTableImpl(Impl
);
757 // Unique selector, to guarantee there is one per name.
758 llvm::FoldingSetNodeID ID
;
759 MultiKeywordSelector::Profile(ID
, IIV
, nKeys
);
761 void *InsertPos
= nullptr;
762 if (MultiKeywordSelector
*SI
=
763 SelTabImpl
.Table
.FindNodeOrInsertPos(ID
, InsertPos
))
766 // MultiKeywordSelector objects are not allocated with new because they have a
767 // variable size array (for parameter types) at the end of them.
768 unsigned Size
= sizeof(MultiKeywordSelector
) + nKeys
*sizeof(IdentifierInfo
*);
769 MultiKeywordSelector
*SI
=
770 (MultiKeywordSelector
*)SelTabImpl
.Allocator
.Allocate(
771 Size
, alignof(MultiKeywordSelector
));
772 new (SI
) MultiKeywordSelector(nKeys
, IIV
);
773 SelTabImpl
.Table
.InsertNode(SI
, InsertPos
);
777 SelectorTable::SelectorTable() {
778 Impl
= new SelectorTableImpl();
781 SelectorTable::~SelectorTable() {
782 delete &getSelectorTableImpl(Impl
);
785 const char *clang::getOperatorSpelling(OverloadedOperatorKind Operator
) {
788 case NUM_OVERLOADED_OPERATORS
:
791 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
792 case OO_##Name: return Spelling;
793 #include "clang/Basic/OperatorKinds.def"
796 llvm_unreachable("Invalid OverloadedOperatorKind!");
799 StringRef
clang::getNullabilitySpelling(NullabilityKind kind
,
800 bool isContextSensitive
) {
802 case NullabilityKind::NonNull
:
803 return isContextSensitive
? "nonnull" : "_Nonnull";
805 case NullabilityKind::Nullable
:
806 return isContextSensitive
? "nullable" : "_Nullable";
808 case NullabilityKind::NullableResult
:
809 assert(!isContextSensitive
&&
810 "_Nullable_result isn't supported as context-sensitive keyword");
811 return "_Nullable_result";
813 case NullabilityKind::Unspecified
:
814 return isContextSensitive
? "null_unspecified" : "_Null_unspecified";
816 llvm_unreachable("Unknown nullability kind.");
819 llvm::raw_ostream
&clang::operator<<(llvm::raw_ostream
&OS
,
820 NullabilityKind NK
) {
822 case NullabilityKind::NonNull
:
823 return OS
<< "NonNull";
824 case NullabilityKind::Nullable
:
825 return OS
<< "Nullable";
826 case NullabilityKind::NullableResult
:
827 return OS
<< "NullableResult";
828 case NullabilityKind::Unspecified
:
829 return OS
<< "Unspecified";
831 llvm_unreachable("Unknown nullability kind.");
835 IdentifierTable::getFutureCompatDiagKind(const IdentifierInfo
&II
,
836 const LangOptions
&LangOpts
) {
837 assert(II
.isFutureCompatKeyword() && "diagnostic should not be needed");
839 unsigned Flags
= llvm::StringSwitch
<unsigned>(II
.getName())
840 #define KEYWORD(NAME, FLAGS) .Case(#NAME, FLAGS)
841 #include "clang/Basic/TokenKinds.def"
845 if (LangOpts
.CPlusPlus
) {
846 if ((Flags
& KEYCXX11
) == KEYCXX11
)
847 return diag::warn_cxx11_keyword
;
849 // char8_t is not modeled as a CXX20_KEYWORD because it's not
850 // unconditionally enabled in C++20 mode. (It can be disabled
852 if (((Flags
& KEYCXX20
) == KEYCXX20
) ||
853 ((Flags
& CHAR8SUPPORT
) == CHAR8SUPPORT
))
854 return diag::warn_cxx20_keyword
;
856 if ((Flags
& KEYC99
) == KEYC99
)
857 return diag::warn_c99_keyword
;
858 if ((Flags
& KEYC23
) == KEYC23
)
859 return diag::warn_c23_keyword
;
863 "Keyword not known to come from a newer Standard or proposed Standard");