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/ErrorHandling.h"
29 #include "llvm/Support/raw_ostream.h"
35 using namespace clang
;
37 // A check to make sure the ObjCOrBuiltinID has sufficient room to store the
38 // largest possible target/aux-target combination. If we exceed this, we likely
39 // need to just change the ObjCOrBuiltinIDBits value in IdentifierTable.h.
40 static_assert(2 * LargestBuiltinID
< (2 << (ObjCOrBuiltinIDBits
- 1)),
41 "Insufficient ObjCOrBuiltinID Bits");
43 //===----------------------------------------------------------------------===//
44 // IdentifierTable Implementation
45 //===----------------------------------------------------------------------===//
47 IdentifierIterator::~IdentifierIterator() = default;
49 IdentifierInfoLookup::~IdentifierInfoLookup() = default;
53 /// A simple identifier lookup iterator that represents an
54 /// empty sequence of identifiers.
55 class EmptyLookupIterator
: public IdentifierIterator
58 StringRef
Next() override
{ return StringRef(); }
63 IdentifierIterator
*IdentifierInfoLookup::getIdentifiers() {
64 return new EmptyLookupIterator();
67 IdentifierTable::IdentifierTable(IdentifierInfoLookup
*ExternalLookup
)
68 : HashTable(8192), // Start with space for 8K identifiers.
69 ExternalLookup(ExternalLookup
) {}
71 IdentifierTable::IdentifierTable(const LangOptions
&LangOpts
,
72 IdentifierInfoLookup
*ExternalLookup
)
73 : IdentifierTable(ExternalLookup
) {
74 // Populate the identifier table with info about keywords for the current
76 AddKeywords(LangOpts
);
79 //===----------------------------------------------------------------------===//
80 // Language Keyword Implementation
81 //===----------------------------------------------------------------------===//
83 // Constants for TokenKinds.def
86 enum TokenKey
: unsigned {
100 WCHARSUPPORT
= 0x2000,
101 HALFSUPPORT
= 0x4000,
102 CHAR8SUPPORT
= 0x8000,
104 KEYZVECTOR
= 0x20000,
105 KEYCOROUTINES
= 0x40000,
106 KEYMODULES
= 0x80000,
108 KEYOPENCLCXX
= 0x200000,
109 KEYMSCOMPAT
= 0x400000,
112 KEYMAX
= KEYCUDA
, // The maximum key
113 KEYALLCXX
= KEYCXX
| KEYCXX11
| KEYCXX20
,
114 KEYALL
= (KEYMAX
| (KEYMAX
-1)) & ~KEYNOMS18
&
115 ~KEYNOOPENCL
// KEYNOMS18 and KEYNOOPENCL are used to exclude.
118 /// How a keyword is treated in the selected standard. This enum is ordered
119 /// intentionally so that the value that 'wins' is the most 'permissive'.
121 KS_Unknown
, // Not yet calculated. Used when figuring out the status.
122 KS_Disabled
, // Disabled
123 KS_Future
, // Is a keyword in future standard
124 KS_Extension
, // Is an extension
125 KS_Enabled
, // Enabled
130 // This works on a single TokenKey flag and checks the LangOpts to get the
131 // KeywordStatus based exclusively on this flag, so that it can be merged in
132 // getKeywordStatus. Most should be enabled/disabled, but some might imply
133 // 'future' versions, or extensions. Returns 'unknown' unless this is KNOWN to
134 // be disabled, and the calling function makes it 'disabled' if no other flag
135 // changes it. This is necessary for the KEYNOCXX and KEYNOOPENCL flags.
136 static KeywordStatus
getKeywordStatusHelper(const LangOptions
&LangOpts
,
138 // Flag is a single bit version of TokenKey (that is, not
139 // KEYALL/KEYALLCXX/etc), so we can check with == throughout this function.
140 assert((Flag
& ~(Flag
- 1)) == Flag
&& "Multiple bits set?");
146 return !LangOpts
.CPlusPlus
? KS_Future
: KS_Unknown
;
150 return !LangOpts
.CPlusPlus
? KS_Future
: KS_Unknown
;
152 return LangOpts
.CPlusPlus
? KS_Enabled
: KS_Unknown
;
154 if (LangOpts
.CPlusPlus11
)
156 return LangOpts
.CPlusPlus
? KS_Future
: KS_Unknown
;
158 if (LangOpts
.CPlusPlus20
)
160 return LangOpts
.CPlusPlus
? KS_Future
: KS_Unknown
;
162 return LangOpts
.GNUKeywords
? KS_Extension
: KS_Unknown
;
164 return LangOpts
.MicrosoftExt
? KS_Extension
: KS_Unknown
;
166 if (LangOpts
.Bool
) return KS_Enabled
;
167 return !LangOpts
.CPlusPlus
? KS_Future
: KS_Unknown
;
169 return LangOpts
.AltiVec
? KS_Enabled
: KS_Unknown
;
171 return LangOpts
.Borland
? KS_Extension
: KS_Unknown
;
173 return LangOpts
.OpenCL
&& !LangOpts
.OpenCLCPlusPlus
? KS_Enabled
176 return LangOpts
.WChar
? KS_Enabled
: KS_Unknown
;
178 return LangOpts
.Half
? KS_Enabled
: KS_Unknown
;
180 if (LangOpts
.Char8
) return KS_Enabled
;
181 if (LangOpts
.CPlusPlus20
) return KS_Unknown
;
182 if (LangOpts
.CPlusPlus
) return KS_Future
;
185 // We treat bridge casts as objective-C keywords so we can warn on them
187 return LangOpts
.ObjC
? KS_Enabled
: KS_Unknown
;
189 return LangOpts
.ZVector
? KS_Enabled
: KS_Unknown
;
191 return LangOpts
.Coroutines
? KS_Enabled
: KS_Unknown
;
193 return LangOpts
.ModulesTS
? KS_Enabled
: KS_Unknown
;
195 return LangOpts
.OpenCLCPlusPlus
? KS_Enabled
: KS_Unknown
;
197 return LangOpts
.MSVCCompat
? KS_Enabled
: KS_Unknown
;
199 return LangOpts
.isSYCL() ? KS_Enabled
: KS_Unknown
;
201 return LangOpts
.CUDA
? KS_Enabled
: KS_Unknown
;
203 // This is enabled in all non-C++ modes, but might be enabled for other
205 return LangOpts
.CPlusPlus
? KS_Unknown
: KS_Enabled
;
207 // The disable behavior for this is handled in getKeywordStatus.
210 // The disable behavior for this is handled in getKeywordStatus.
213 llvm_unreachable("Unknown KeywordStatus flag");
217 /// Translates flags as specified in TokenKinds.def into keyword status
218 /// in the given language standard.
219 static KeywordStatus
getKeywordStatus(const LangOptions
&LangOpts
,
221 // KEYALL means always enabled, so special case this one.
222 if (Flags
== KEYALL
) return KS_Enabled
;
223 // These are tests that need to 'always win', as they are special in that they
224 // disable based on certain conditions.
225 if (LangOpts
.OpenCL
&& (Flags
& KEYNOOPENCL
)) return KS_Disabled
;
226 if (LangOpts
.MSVCCompat
&& (Flags
& KEYNOMS18
) &&
227 !LangOpts
.isCompatibleWithMSVC(LangOptions::MSVC2015
))
230 KeywordStatus CurStatus
= KS_Unknown
;
233 unsigned CurFlag
= Flags
& ~(Flags
- 1);
234 Flags
= Flags
& ~CurFlag
;
235 CurStatus
= std::max(
237 getKeywordStatusHelper(LangOpts
, static_cast<TokenKey
>(CurFlag
)));
240 if (CurStatus
== KS_Unknown
)
245 /// AddKeyword - This method is used to associate a token ID with specific
246 /// identifiers because they are language keywords. This causes the lexer to
247 /// automatically map matching identifiers to specialized token codes.
248 static void AddKeyword(StringRef Keyword
,
249 tok::TokenKind TokenCode
, unsigned Flags
,
250 const LangOptions
&LangOpts
, IdentifierTable
&Table
) {
251 KeywordStatus AddResult
= getKeywordStatus(LangOpts
, Flags
);
253 // Don't add this keyword if disabled in this language.
254 if (AddResult
== KS_Disabled
) return;
256 IdentifierInfo
&Info
=
257 Table
.get(Keyword
, AddResult
== KS_Future
? tok::identifier
: TokenCode
);
258 Info
.setIsExtensionToken(AddResult
== KS_Extension
);
259 Info
.setIsFutureCompatKeyword(AddResult
== KS_Future
);
262 /// AddCXXOperatorKeyword - Register a C++ operator keyword alternative
264 static void AddCXXOperatorKeyword(StringRef Keyword
,
265 tok::TokenKind TokenCode
,
266 IdentifierTable
&Table
) {
267 IdentifierInfo
&Info
= Table
.get(Keyword
, TokenCode
);
268 Info
.setIsCPlusPlusOperatorKeyword();
271 /// AddObjCKeyword - Register an Objective-C \@keyword like "class" "selector"
273 static void AddObjCKeyword(StringRef Name
,
274 tok::ObjCKeywordKind ObjCID
,
275 IdentifierTable
&Table
) {
276 Table
.get(Name
).setObjCKeywordID(ObjCID
);
279 /// AddKeywords - Add all keywords to the symbol table.
281 void IdentifierTable::AddKeywords(const LangOptions
&LangOpts
) {
282 // Add keywords and tokens for the current language.
283 #define KEYWORD(NAME, FLAGS) \
284 AddKeyword(StringRef(#NAME), tok::kw_ ## NAME, \
285 FLAGS, LangOpts, *this);
286 #define ALIAS(NAME, TOK, FLAGS) \
287 AddKeyword(StringRef(NAME), tok::kw_ ## TOK, \
288 FLAGS, LangOpts, *this);
289 #define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \
290 if (LangOpts.CXXOperatorNames) \
291 AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this);
292 #define OBJC_AT_KEYWORD(NAME) \
294 AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
295 #define TESTING_KEYWORD(NAME, FLAGS)
296 #include "clang/Basic/TokenKinds.def"
298 if (LangOpts
.ParseUnknownAnytype
)
299 AddKeyword("__unknown_anytype", tok::kw___unknown_anytype
, KEYALL
,
302 if (LangOpts
.DeclSpecKeyword
)
303 AddKeyword("__declspec", tok::kw___declspec
, KEYALL
, LangOpts
, *this);
305 if (LangOpts
.IEEE128
)
306 AddKeyword("__ieee128", tok::kw___float128
, KEYALL
, LangOpts
, *this);
308 // Add the 'import' contextual keyword.
309 get("import").setModulesImport(true);
312 /// Checks if the specified token kind represents a keyword in the
313 /// specified language.
314 /// \returns Status of the keyword in the language.
315 static KeywordStatus
getTokenKwStatus(const LangOptions
&LangOpts
,
318 #define KEYWORD(NAME, FLAGS) \
319 case tok::kw_##NAME: return getKeywordStatus(LangOpts, FLAGS);
320 #include "clang/Basic/TokenKinds.def"
321 default: return KS_Disabled
;
325 /// Returns true if the identifier represents a keyword in the
326 /// specified language.
327 bool IdentifierInfo::isKeyword(const LangOptions
&LangOpts
) const {
328 switch (getTokenKwStatus(LangOpts
, getTokenID())) {
337 /// Returns true if the identifier represents a C++ keyword in the
338 /// specified language.
339 bool IdentifierInfo::isCPlusPlusKeyword(const LangOptions
&LangOpts
) const {
340 if (!LangOpts
.CPlusPlus
|| !isKeyword(LangOpts
))
342 // This is a C++ keyword if this identifier is not a keyword when checked
343 // using LangOptions without C++ support.
344 LangOptions LangOptsNoCPP
= LangOpts
;
345 LangOptsNoCPP
.CPlusPlus
= false;
346 LangOptsNoCPP
.CPlusPlus11
= false;
347 LangOptsNoCPP
.CPlusPlus20
= false;
348 return !isKeyword(LangOptsNoCPP
);
351 ReservedIdentifierStatus
352 IdentifierInfo::isReserved(const LangOptions
&LangOpts
) const {
353 StringRef Name
= getName();
355 // '_' is a reserved identifier, but its use is so common (e.g. to store
356 // ignored values) that we don't warn on it.
357 if (Name
.size() <= 1)
358 return ReservedIdentifierStatus::NotReserved
;
361 if (Name
[0] == '_') {
363 // Each name that begins with an underscore followed by an uppercase letter
364 // or another underscore is reserved.
366 return ReservedIdentifierStatus::StartsWithDoubleUnderscore
;
368 if ('A' <= Name
[1] && Name
[1] <= 'Z')
369 return ReservedIdentifierStatus::
370 StartsWithUnderscoreFollowedByCapitalLetter
;
372 // This is a bit misleading: it actually means it's only reserved if we're
373 // at global scope because it starts with an underscore.
374 return ReservedIdentifierStatus::StartsWithUnderscoreAtGlobalScope
;
377 // Each name that contains a double underscore (__) is reserved.
378 if (LangOpts
.CPlusPlus
&& Name
.contains("__"))
379 return ReservedIdentifierStatus::ContainsDoubleUnderscore
;
381 return ReservedIdentifierStatus::NotReserved
;
384 StringRef
IdentifierInfo::deuglifiedName() const {
385 StringRef Name
= getName();
386 if (Name
.size() >= 2 && Name
.front() == '_' &&
387 (Name
[1] == '_' || (Name
[1] >= 'A' && Name
[1] <= 'Z')))
388 return Name
.ltrim('_');
392 tok::PPKeywordKind
IdentifierInfo::getPPKeywordID() const {
393 // We use a perfect hash function here involving the length of the keyword,
394 // the first and third character. For preprocessor ID's there are no
395 // collisions (if there were, the switch below would complain about duplicate
396 // case values). Note that this depends on 'if' being null terminated.
398 #define HASH(LEN, FIRST, THIRD) \
399 (LEN << 5) + (((FIRST-'a') + (THIRD-'a')) & 31)
400 #define CASE(LEN, FIRST, THIRD, NAME) \
401 case HASH(LEN, FIRST, THIRD): \
402 return memcmp(Name, #NAME, LEN) ? tok::pp_not_keyword : tok::pp_ ## NAME
404 unsigned Len
= getLength();
405 if (Len
< 2) return tok::pp_not_keyword
;
406 const char *Name
= getNameStart();
407 switch (HASH(Len
, Name
[0], Name
[2])) {
408 default: return tok::pp_not_keyword
;
409 CASE( 2, 'i', '\0', if);
410 CASE( 4, 'e', 'i', elif
);
411 CASE( 4, 'e', 's', else);
412 CASE( 4, 'l', 'n', line
);
413 CASE( 4, 's', 'c', sccs
);
414 CASE( 5, 'e', 'd', endif
);
415 CASE( 5, 'e', 'r', error
);
416 CASE( 5, 'i', 'e', ident
);
417 CASE( 5, 'i', 'd', ifdef
);
418 CASE( 5, 'u', 'd', undef
);
420 CASE( 6, 'a', 's', assert);
421 CASE( 6, 'd', 'f', define
);
422 CASE( 6, 'i', 'n', ifndef
);
423 CASE( 6, 'i', 'p', import
);
424 CASE( 6, 'p', 'a', pragma
);
426 CASE( 7, 'd', 'f', defined
);
427 CASE( 7, 'e', 'i', elifdef
);
428 CASE( 7, 'i', 'c', include
);
429 CASE( 7, 'w', 'r', warning
);
431 CASE( 8, 'e', 'i', elifndef
);
432 CASE( 8, 'u', 'a', unassert
);
433 CASE(12, 'i', 'c', include_next
);
435 CASE(14, '_', 'p', __public_macro
);
437 CASE(15, '_', 'p', __private_macro
);
439 CASE(16, '_', 'i', __include_macros
);
445 //===----------------------------------------------------------------------===//
446 // Stats Implementation
447 //===----------------------------------------------------------------------===//
449 /// PrintStats - Print statistics about how well the identifier table is doing
450 /// at hashing identifiers.
451 void IdentifierTable::PrintStats() const {
452 unsigned NumBuckets
= HashTable
.getNumBuckets();
453 unsigned NumIdentifiers
= HashTable
.getNumItems();
454 unsigned NumEmptyBuckets
= NumBuckets
-NumIdentifiers
;
455 unsigned AverageIdentifierSize
= 0;
456 unsigned MaxIdentifierLength
= 0;
458 // TODO: Figure out maximum times an identifier had to probe for -stats.
459 for (llvm::StringMap
<IdentifierInfo
*, llvm::BumpPtrAllocator
>::const_iterator
460 I
= HashTable
.begin(), E
= HashTable
.end(); I
!= E
; ++I
) {
461 unsigned IdLen
= I
->getKeyLength();
462 AverageIdentifierSize
+= IdLen
;
463 if (MaxIdentifierLength
< IdLen
)
464 MaxIdentifierLength
= IdLen
;
467 fprintf(stderr
, "\n*** Identifier Table Stats:\n");
468 fprintf(stderr
, "# Identifiers: %d\n", NumIdentifiers
);
469 fprintf(stderr
, "# Empty Buckets: %d\n", NumEmptyBuckets
);
470 fprintf(stderr
, "Hash density (#identifiers per bucket): %f\n",
471 NumIdentifiers
/(double)NumBuckets
);
472 fprintf(stderr
, "Ave identifier length: %f\n",
473 (AverageIdentifierSize
/(double)NumIdentifiers
));
474 fprintf(stderr
, "Max identifier length: %d\n", MaxIdentifierLength
);
476 // Compute statistics about the memory allocated for identifiers.
477 HashTable
.getAllocator().PrintStats();
480 //===----------------------------------------------------------------------===//
481 // SelectorTable Implementation
482 //===----------------------------------------------------------------------===//
484 unsigned llvm::DenseMapInfo
<clang::Selector
>::getHashValue(clang::Selector S
) {
485 return DenseMapInfo
<void*>::getHashValue(S
.getAsOpaquePtr());
490 /// One of these variable length records is kept for each
491 /// selector containing more than one keyword. We use a folding set
492 /// to unique aggregate names (keyword selectors in ObjC parlance). Access to
493 /// this class is provided strictly through Selector.
494 class alignas(IdentifierInfoAlignment
) MultiKeywordSelector
495 : public detail::DeclarationNameExtra
,
496 public llvm::FoldingSetNode
{
497 MultiKeywordSelector(unsigned nKeys
) : DeclarationNameExtra(nKeys
) {}
500 // Constructor for keyword selectors.
501 MultiKeywordSelector(unsigned nKeys
, IdentifierInfo
**IIV
)
502 : DeclarationNameExtra(nKeys
) {
503 assert((nKeys
> 1) && "not a multi-keyword selector");
505 // Fill in the trailing keyword array.
506 IdentifierInfo
**KeyInfo
= reinterpret_cast<IdentifierInfo
**>(this + 1);
507 for (unsigned i
= 0; i
!= nKeys
; ++i
)
511 // getName - Derive the full selector name and return it.
512 std::string
getName() const;
514 using DeclarationNameExtra::getNumArgs
;
516 using keyword_iterator
= IdentifierInfo
*const *;
518 keyword_iterator
keyword_begin() const {
519 return reinterpret_cast<keyword_iterator
>(this + 1);
522 keyword_iterator
keyword_end() const {
523 return keyword_begin() + getNumArgs();
526 IdentifierInfo
*getIdentifierInfoForSlot(unsigned i
) const {
527 assert(i
< getNumArgs() && "getIdentifierInfoForSlot(): illegal index");
528 return keyword_begin()[i
];
531 static void Profile(llvm::FoldingSetNodeID
&ID
, keyword_iterator ArgTys
,
533 ID
.AddInteger(NumArgs
);
534 for (unsigned i
= 0; i
!= NumArgs
; ++i
)
535 ID
.AddPointer(ArgTys
[i
]);
538 void Profile(llvm::FoldingSetNodeID
&ID
) {
539 Profile(ID
, keyword_begin(), getNumArgs());
543 } // namespace clang.
545 bool Selector::isKeywordSelector(ArrayRef
<StringRef
> Names
) const {
546 assert(!Names
.empty() && "must have >= 1 selector slots");
547 if (getNumArgs() != Names
.size())
549 for (unsigned I
= 0, E
= Names
.size(); I
!= E
; ++I
) {
550 if (getNameForSlot(I
) != Names
[I
])
556 bool Selector::isUnarySelector(StringRef Name
) const {
557 return isUnarySelector() && getNameForSlot(0) == Name
;
560 unsigned Selector::getNumArgs() const {
561 unsigned IIF
= getIdentifierInfoFlag();
566 // We point to a MultiKeywordSelector.
567 MultiKeywordSelector
*SI
= getMultiKeywordSelector();
568 return SI
->getNumArgs();
571 IdentifierInfo
*Selector::getIdentifierInfoForSlot(unsigned argIndex
) const {
572 if (getIdentifierInfoFlag() < MultiArg
) {
573 assert(argIndex
== 0 && "illegal keyword index");
574 return getAsIdentifierInfo();
577 // We point to a MultiKeywordSelector.
578 MultiKeywordSelector
*SI
= getMultiKeywordSelector();
579 return SI
->getIdentifierInfoForSlot(argIndex
);
582 StringRef
Selector::getNameForSlot(unsigned int argIndex
) const {
583 IdentifierInfo
*II
= getIdentifierInfoForSlot(argIndex
);
584 return II
? II
->getName() : StringRef();
587 std::string
MultiKeywordSelector::getName() const {
588 SmallString
<256> Str
;
589 llvm::raw_svector_ostream
OS(Str
);
590 for (keyword_iterator I
= keyword_begin(), E
= keyword_end(); I
!= E
; ++I
) {
592 OS
<< (*I
)->getName();
596 return std::string(OS
.str());
599 std::string
Selector::getAsString() const {
601 return "<null selector>";
603 if (getIdentifierInfoFlag() < MultiArg
) {
604 IdentifierInfo
*II
= getAsIdentifierInfo();
606 if (getNumArgs() == 0) {
607 assert(II
&& "If the number of arguments is 0 then II is guaranteed to "
609 return std::string(II
->getName());
615 return II
->getName().str() + ":";
618 // We have a multiple keyword selector.
619 return getMultiKeywordSelector()->getName();
622 void Selector::print(llvm::raw_ostream
&OS
) const {
626 LLVM_DUMP_METHOD
void Selector::dump() const { print(llvm::errs()); }
628 /// Interpreting the given string using the normal CamelCase
629 /// conventions, determine whether the given string starts with the
630 /// given "word", which is assumed to end in a lowercase letter.
631 static bool startsWithWord(StringRef name
, StringRef word
) {
632 if (name
.size() < word
.size()) return false;
633 return ((name
.size() == word
.size() || !isLowercase(name
[word
.size()])) &&
634 name
.startswith(word
));
637 ObjCMethodFamily
Selector::getMethodFamilyImpl(Selector sel
) {
638 IdentifierInfo
*first
= sel
.getIdentifierInfoForSlot(0);
639 if (!first
) return OMF_None
;
641 StringRef name
= first
->getName();
642 if (sel
.isUnarySelector()) {
643 if (name
== "autorelease") return OMF_autorelease
;
644 if (name
== "dealloc") return OMF_dealloc
;
645 if (name
== "finalize") return OMF_finalize
;
646 if (name
== "release") return OMF_release
;
647 if (name
== "retain") return OMF_retain
;
648 if (name
== "retainCount") return OMF_retainCount
;
649 if (name
== "self") return OMF_self
;
650 if (name
== "initialize") return OMF_initialize
;
653 if (name
== "performSelector" || name
== "performSelectorInBackground" ||
654 name
== "performSelectorOnMainThread")
655 return OMF_performSelector
;
657 // The other method families may begin with a prefix of underscores.
658 while (!name
.empty() && name
.front() == '_')
659 name
= name
.substr(1);
661 if (name
.empty()) return OMF_None
;
662 switch (name
.front()) {
664 if (startsWithWord(name
, "alloc")) return OMF_alloc
;
667 if (startsWithWord(name
, "copy")) return OMF_copy
;
670 if (startsWithWord(name
, "init")) return OMF_init
;
673 if (startsWithWord(name
, "mutableCopy")) return OMF_mutableCopy
;
676 if (startsWithWord(name
, "new")) return OMF_new
;
685 ObjCInstanceTypeFamily
Selector::getInstTypeMethodFamily(Selector sel
) {
686 IdentifierInfo
*first
= sel
.getIdentifierInfoForSlot(0);
687 if (!first
) return OIT_None
;
689 StringRef name
= first
->getName();
691 if (name
.empty()) return OIT_None
;
692 switch (name
.front()) {
694 if (startsWithWord(name
, "array")) return OIT_Array
;
697 if (startsWithWord(name
, "default")) return OIT_ReturnsSelf
;
698 if (startsWithWord(name
, "dictionary")) return OIT_Dictionary
;
701 if (startsWithWord(name
, "shared")) return OIT_ReturnsSelf
;
702 if (startsWithWord(name
, "standard")) return OIT_Singleton
;
705 if (startsWithWord(name
, "init")) return OIT_Init
;
713 ObjCStringFormatFamily
Selector::getStringFormatFamilyImpl(Selector sel
) {
714 IdentifierInfo
*first
= sel
.getIdentifierInfoForSlot(0);
715 if (!first
) return SFF_None
;
717 StringRef name
= first
->getName();
719 switch (name
.front()) {
721 if (name
== "appendFormat") return SFF_NSString
;
725 if (name
== "initWithFormat") return SFF_NSString
;
729 if (name
== "localizedStringWithFormat") return SFF_NSString
;
733 if (name
== "stringByAppendingFormat" ||
734 name
== "stringWithFormat") return SFF_NSString
;
742 struct SelectorTableImpl
{
743 llvm::FoldingSet
<MultiKeywordSelector
> Table
;
744 llvm::BumpPtrAllocator Allocator
;
749 static SelectorTableImpl
&getSelectorTableImpl(void *P
) {
750 return *static_cast<SelectorTableImpl
*>(P
);
754 SelectorTable::constructSetterName(StringRef Name
) {
755 SmallString
<64> SetterName("set");
757 SetterName
[3] = toUppercase(SetterName
[3]);
762 SelectorTable::constructSetterSelector(IdentifierTable
&Idents
,
763 SelectorTable
&SelTable
,
764 const IdentifierInfo
*Name
) {
765 IdentifierInfo
*SetterName
=
766 &Idents
.get(constructSetterName(Name
->getName()));
767 return SelTable
.getUnarySelector(SetterName
);
770 std::string
SelectorTable::getPropertyNameFromSetterSelector(Selector Sel
) {
771 StringRef Name
= Sel
.getNameForSlot(0);
772 assert(Name
.startswith("set") && "invalid setter name");
773 return (Twine(toLowercase(Name
[3])) + Name
.drop_front(4)).str();
776 size_t SelectorTable::getTotalMemory() const {
777 SelectorTableImpl
&SelTabImpl
= getSelectorTableImpl(Impl
);
778 return SelTabImpl
.Allocator
.getTotalMemory();
781 Selector
SelectorTable::getSelector(unsigned nKeys
, IdentifierInfo
**IIV
) {
783 return Selector(IIV
[0], nKeys
);
785 SelectorTableImpl
&SelTabImpl
= getSelectorTableImpl(Impl
);
787 // Unique selector, to guarantee there is one per name.
788 llvm::FoldingSetNodeID ID
;
789 MultiKeywordSelector::Profile(ID
, IIV
, nKeys
);
791 void *InsertPos
= nullptr;
792 if (MultiKeywordSelector
*SI
=
793 SelTabImpl
.Table
.FindNodeOrInsertPos(ID
, InsertPos
))
796 // MultiKeywordSelector objects are not allocated with new because they have a
797 // variable size array (for parameter types) at the end of them.
798 unsigned Size
= sizeof(MultiKeywordSelector
) + nKeys
*sizeof(IdentifierInfo
*);
799 MultiKeywordSelector
*SI
=
800 (MultiKeywordSelector
*)SelTabImpl
.Allocator
.Allocate(
801 Size
, alignof(MultiKeywordSelector
));
802 new (SI
) MultiKeywordSelector(nKeys
, IIV
);
803 SelTabImpl
.Table
.InsertNode(SI
, InsertPos
);
807 SelectorTable::SelectorTable() {
808 Impl
= new SelectorTableImpl();
811 SelectorTable::~SelectorTable() {
812 delete &getSelectorTableImpl(Impl
);
815 const char *clang::getOperatorSpelling(OverloadedOperatorKind Operator
) {
818 case NUM_OVERLOADED_OPERATORS
:
821 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
822 case OO_##Name: return Spelling;
823 #include "clang/Basic/OperatorKinds.def"
826 llvm_unreachable("Invalid OverloadedOperatorKind!");
829 StringRef
clang::getNullabilitySpelling(NullabilityKind kind
,
830 bool isContextSensitive
) {
832 case NullabilityKind::NonNull
:
833 return isContextSensitive
? "nonnull" : "_Nonnull";
835 case NullabilityKind::Nullable
:
836 return isContextSensitive
? "nullable" : "_Nullable";
838 case NullabilityKind::NullableResult
:
839 assert(!isContextSensitive
&&
840 "_Nullable_result isn't supported as context-sensitive keyword");
841 return "_Nullable_result";
843 case NullabilityKind::Unspecified
:
844 return isContextSensitive
? "null_unspecified" : "_Null_unspecified";
846 llvm_unreachable("Unknown nullability kind.");
850 IdentifierTable::getFutureCompatDiagKind(const IdentifierInfo
&II
,
851 const LangOptions
&LangOpts
) {
852 assert(II
.isFutureCompatKeyword() && "diagnostic should not be needed");
854 unsigned Flags
= llvm::StringSwitch
<unsigned>(II
.getName())
855 #define KEYWORD(NAME, FLAGS) .Case(#NAME, FLAGS)
856 #include "clang/Basic/TokenKinds.def"
860 if (LangOpts
.CPlusPlus
) {
861 if ((Flags
& KEYCXX11
) == KEYCXX11
)
862 return diag::warn_cxx11_keyword
;
864 // char8_t is not modeled as a CXX20_KEYWORD because it's not
865 // unconditionally enabled in C++20 mode. (It can be disabled
867 if (((Flags
& KEYCXX20
) == KEYCXX20
) ||
868 ((Flags
& CHAR8SUPPORT
) == CHAR8SUPPORT
))
869 return diag::warn_cxx20_keyword
;
871 if ((Flags
& KEYC99
) == KEYC99
)
872 return diag::warn_c99_keyword
;
873 if ((Flags
& KEYC2X
) == KEYC2X
)
874 return diag::warn_c2x_keyword
;
878 "Keyword not known to come from a newer Standard or proposed Standard");