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,
113 KEYMAX
= KEYHLSL
, // The maximum key
114 KEYALLCXX
= KEYCXX
| KEYCXX11
| KEYCXX20
,
115 KEYALL
= (KEYMAX
| (KEYMAX
-1)) & ~KEYNOMS18
&
116 ~KEYNOOPENCL
// KEYNOMS18 and KEYNOOPENCL are used to exclude.
119 /// How a keyword is treated in the selected standard. This enum is ordered
120 /// intentionally so that the value that 'wins' is the most 'permissive'.
122 KS_Unknown
, // Not yet calculated. Used when figuring out the status.
123 KS_Disabled
, // Disabled
124 KS_Future
, // Is a keyword in future standard
125 KS_Extension
, // Is an extension
126 KS_Enabled
, // Enabled
131 // This works on a single TokenKey flag and checks the LangOpts to get the
132 // KeywordStatus based exclusively on this flag, so that it can be merged in
133 // getKeywordStatus. Most should be enabled/disabled, but some might imply
134 // 'future' versions, or extensions. Returns 'unknown' unless this is KNOWN to
135 // be disabled, and the calling function makes it 'disabled' if no other flag
136 // changes it. This is necessary for the KEYNOCXX and KEYNOOPENCL flags.
137 static KeywordStatus
getKeywordStatusHelper(const LangOptions
&LangOpts
,
139 // Flag is a single bit version of TokenKey (that is, not
140 // KEYALL/KEYALLCXX/etc), so we can check with == throughout this function.
141 assert((Flag
& ~(Flag
- 1)) == Flag
&& "Multiple bits set?");
147 return !LangOpts
.CPlusPlus
? KS_Future
: KS_Unknown
;
151 return !LangOpts
.CPlusPlus
? KS_Future
: KS_Unknown
;
153 return LangOpts
.CPlusPlus
? KS_Enabled
: KS_Unknown
;
155 if (LangOpts
.CPlusPlus11
)
157 return LangOpts
.CPlusPlus
? KS_Future
: KS_Unknown
;
159 if (LangOpts
.CPlusPlus20
)
161 return LangOpts
.CPlusPlus
? KS_Future
: KS_Unknown
;
163 return LangOpts
.GNUKeywords
? KS_Extension
: KS_Unknown
;
165 return LangOpts
.MicrosoftExt
? KS_Extension
: KS_Unknown
;
167 if (LangOpts
.Bool
) return KS_Enabled
;
168 return !LangOpts
.CPlusPlus
? KS_Future
: KS_Unknown
;
170 return LangOpts
.AltiVec
? KS_Enabled
: KS_Unknown
;
172 return LangOpts
.Borland
? KS_Extension
: KS_Unknown
;
174 return LangOpts
.OpenCL
&& !LangOpts
.OpenCLCPlusPlus
? KS_Enabled
177 return LangOpts
.WChar
? KS_Enabled
: KS_Unknown
;
179 return LangOpts
.Half
? KS_Enabled
: KS_Unknown
;
181 if (LangOpts
.Char8
) return KS_Enabled
;
182 if (LangOpts
.CPlusPlus20
) return KS_Unknown
;
183 if (LangOpts
.CPlusPlus
) return KS_Future
;
186 // We treat bridge casts as objective-C keywords so we can warn on them
188 return LangOpts
.ObjC
? KS_Enabled
: KS_Unknown
;
190 return LangOpts
.ZVector
? KS_Enabled
: KS_Unknown
;
192 return LangOpts
.Coroutines
? KS_Enabled
: KS_Unknown
;
194 return LangOpts
.ModulesTS
? KS_Enabled
: KS_Unknown
;
196 return LangOpts
.OpenCLCPlusPlus
? KS_Enabled
: KS_Unknown
;
198 return LangOpts
.MSVCCompat
? KS_Enabled
: KS_Unknown
;
200 return LangOpts
.isSYCL() ? KS_Enabled
: KS_Unknown
;
202 return LangOpts
.CUDA
? KS_Enabled
: KS_Unknown
;
204 return LangOpts
.HLSL
? KS_Enabled
: KS_Unknown
;
206 // This is enabled in all non-C++ modes, but might be enabled for other
208 return LangOpts
.CPlusPlus
? KS_Unknown
: KS_Enabled
;
210 // The disable behavior for this is handled in getKeywordStatus.
213 // The disable behavior for this is handled in getKeywordStatus.
216 llvm_unreachable("Unknown KeywordStatus flag");
220 /// Translates flags as specified in TokenKinds.def into keyword status
221 /// in the given language standard.
222 static KeywordStatus
getKeywordStatus(const LangOptions
&LangOpts
,
224 // KEYALL means always enabled, so special case this one.
225 if (Flags
== KEYALL
) return KS_Enabled
;
226 // These are tests that need to 'always win', as they are special in that they
227 // disable based on certain conditions.
228 if (LangOpts
.OpenCL
&& (Flags
& KEYNOOPENCL
)) return KS_Disabled
;
229 if (LangOpts
.MSVCCompat
&& (Flags
& KEYNOMS18
) &&
230 !LangOpts
.isCompatibleWithMSVC(LangOptions::MSVC2015
))
233 KeywordStatus CurStatus
= KS_Unknown
;
236 unsigned CurFlag
= Flags
& ~(Flags
- 1);
237 Flags
= Flags
& ~CurFlag
;
238 CurStatus
= std::max(
240 getKeywordStatusHelper(LangOpts
, static_cast<TokenKey
>(CurFlag
)));
243 if (CurStatus
== KS_Unknown
)
248 /// AddKeyword - This method is used to associate a token ID with specific
249 /// identifiers because they are language keywords. This causes the lexer to
250 /// automatically map matching identifiers to specialized token codes.
251 static void AddKeyword(StringRef Keyword
,
252 tok::TokenKind TokenCode
, unsigned Flags
,
253 const LangOptions
&LangOpts
, IdentifierTable
&Table
) {
254 KeywordStatus AddResult
= getKeywordStatus(LangOpts
, Flags
);
256 // Don't add this keyword if disabled in this language.
257 if (AddResult
== KS_Disabled
) return;
259 IdentifierInfo
&Info
=
260 Table
.get(Keyword
, AddResult
== KS_Future
? tok::identifier
: TokenCode
);
261 Info
.setIsExtensionToken(AddResult
== KS_Extension
);
262 Info
.setIsFutureCompatKeyword(AddResult
== KS_Future
);
265 /// AddCXXOperatorKeyword - Register a C++ operator keyword alternative
267 static void AddCXXOperatorKeyword(StringRef Keyword
,
268 tok::TokenKind TokenCode
,
269 IdentifierTable
&Table
) {
270 IdentifierInfo
&Info
= Table
.get(Keyword
, TokenCode
);
271 Info
.setIsCPlusPlusOperatorKeyword();
274 /// AddObjCKeyword - Register an Objective-C \@keyword like "class" "selector"
276 static void AddObjCKeyword(StringRef Name
,
277 tok::ObjCKeywordKind ObjCID
,
278 IdentifierTable
&Table
) {
279 Table
.get(Name
).setObjCKeywordID(ObjCID
);
282 /// AddKeywords - Add all keywords to the symbol table.
284 void IdentifierTable::AddKeywords(const LangOptions
&LangOpts
) {
285 // Add keywords and tokens for the current language.
286 #define KEYWORD(NAME, FLAGS) \
287 AddKeyword(StringRef(#NAME), tok::kw_ ## NAME, \
288 FLAGS, LangOpts, *this);
289 #define ALIAS(NAME, TOK, FLAGS) \
290 AddKeyword(StringRef(NAME), tok::kw_ ## TOK, \
291 FLAGS, LangOpts, *this);
292 #define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \
293 if (LangOpts.CXXOperatorNames) \
294 AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this);
295 #define OBJC_AT_KEYWORD(NAME) \
297 AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
298 #define TESTING_KEYWORD(NAME, FLAGS)
299 #include "clang/Basic/TokenKinds.def"
301 if (LangOpts
.ParseUnknownAnytype
)
302 AddKeyword("__unknown_anytype", tok::kw___unknown_anytype
, KEYALL
,
305 if (LangOpts
.DeclSpecKeyword
)
306 AddKeyword("__declspec", tok::kw___declspec
, KEYALL
, LangOpts
, *this);
308 if (LangOpts
.IEEE128
)
309 AddKeyword("__ieee128", tok::kw___float128
, KEYALL
, LangOpts
, *this);
311 // Add the 'import' contextual keyword.
312 get("import").setModulesImport(true);
315 /// Checks if the specified token kind represents a keyword in the
316 /// specified language.
317 /// \returns Status of the keyword in the language.
318 static KeywordStatus
getTokenKwStatus(const LangOptions
&LangOpts
,
321 #define KEYWORD(NAME, FLAGS) \
322 case tok::kw_##NAME: return getKeywordStatus(LangOpts, FLAGS);
323 #include "clang/Basic/TokenKinds.def"
324 default: return KS_Disabled
;
328 /// Returns true if the identifier represents a keyword in the
329 /// specified language.
330 bool IdentifierInfo::isKeyword(const LangOptions
&LangOpts
) const {
331 switch (getTokenKwStatus(LangOpts
, getTokenID())) {
340 /// Returns true if the identifier represents a C++ keyword in the
341 /// specified language.
342 bool IdentifierInfo::isCPlusPlusKeyword(const LangOptions
&LangOpts
) const {
343 if (!LangOpts
.CPlusPlus
|| !isKeyword(LangOpts
))
345 // This is a C++ keyword if this identifier is not a keyword when checked
346 // using LangOptions without C++ support.
347 LangOptions LangOptsNoCPP
= LangOpts
;
348 LangOptsNoCPP
.CPlusPlus
= false;
349 LangOptsNoCPP
.CPlusPlus11
= false;
350 LangOptsNoCPP
.CPlusPlus20
= false;
351 return !isKeyword(LangOptsNoCPP
);
354 ReservedIdentifierStatus
355 IdentifierInfo::isReserved(const LangOptions
&LangOpts
) const {
356 StringRef Name
= getName();
358 // '_' is a reserved identifier, but its use is so common (e.g. to store
359 // ignored values) that we don't warn on it.
360 if (Name
.size() <= 1)
361 return ReservedIdentifierStatus::NotReserved
;
364 if (Name
[0] == '_') {
366 // Each name that begins with an underscore followed by an uppercase letter
367 // or another underscore is reserved.
369 return ReservedIdentifierStatus::StartsWithDoubleUnderscore
;
371 if ('A' <= Name
[1] && Name
[1] <= 'Z')
372 return ReservedIdentifierStatus::
373 StartsWithUnderscoreFollowedByCapitalLetter
;
375 // This is a bit misleading: it actually means it's only reserved if we're
376 // at global scope because it starts with an underscore.
377 return ReservedIdentifierStatus::StartsWithUnderscoreAtGlobalScope
;
380 // Each name that contains a double underscore (__) is reserved.
381 if (LangOpts
.CPlusPlus
&& Name
.contains("__"))
382 return ReservedIdentifierStatus::ContainsDoubleUnderscore
;
384 return ReservedIdentifierStatus::NotReserved
;
387 StringRef
IdentifierInfo::deuglifiedName() const {
388 StringRef Name
= getName();
389 if (Name
.size() >= 2 && Name
.front() == '_' &&
390 (Name
[1] == '_' || (Name
[1] >= 'A' && Name
[1] <= 'Z')))
391 return Name
.ltrim('_');
395 tok::PPKeywordKind
IdentifierInfo::getPPKeywordID() const {
396 // We use a perfect hash function here involving the length of the keyword,
397 // the first and third character. For preprocessor ID's there are no
398 // collisions (if there were, the switch below would complain about duplicate
399 // case values). Note that this depends on 'if' being null terminated.
401 #define HASH(LEN, FIRST, THIRD) \
402 (LEN << 5) + (((FIRST-'a') + (THIRD-'a')) & 31)
403 #define CASE(LEN, FIRST, THIRD, NAME) \
404 case HASH(LEN, FIRST, THIRD): \
405 return memcmp(Name, #NAME, LEN) ? tok::pp_not_keyword : tok::pp_ ## NAME
407 unsigned Len
= getLength();
408 if (Len
< 2) return tok::pp_not_keyword
;
409 const char *Name
= getNameStart();
410 switch (HASH(Len
, Name
[0], Name
[2])) {
411 default: return tok::pp_not_keyword
;
412 CASE( 2, 'i', '\0', if);
413 CASE( 4, 'e', 'i', elif
);
414 CASE( 4, 'e', 's', else);
415 CASE( 4, 'l', 'n', line
);
416 CASE( 4, 's', 'c', sccs
);
417 CASE( 5, 'e', 'd', endif
);
418 CASE( 5, 'e', 'r', error
);
419 CASE( 5, 'i', 'e', ident
);
420 CASE( 5, 'i', 'd', ifdef
);
421 CASE( 5, 'u', 'd', undef
);
423 CASE( 6, 'a', 's', assert);
424 CASE( 6, 'd', 'f', define
);
425 CASE( 6, 'i', 'n', ifndef
);
426 CASE( 6, 'i', 'p', import
);
427 CASE( 6, 'p', 'a', pragma
);
429 CASE( 7, 'd', 'f', defined
);
430 CASE( 7, 'e', 'i', elifdef
);
431 CASE( 7, 'i', 'c', include
);
432 CASE( 7, 'w', 'r', warning
);
434 CASE( 8, 'e', 'i', elifndef
);
435 CASE( 8, 'u', 'a', unassert
);
436 CASE(12, 'i', 'c', include_next
);
438 CASE(14, '_', 'p', __public_macro
);
440 CASE(15, '_', 'p', __private_macro
);
442 CASE(16, '_', 'i', __include_macros
);
448 //===----------------------------------------------------------------------===//
449 // Stats Implementation
450 //===----------------------------------------------------------------------===//
452 /// PrintStats - Print statistics about how well the identifier table is doing
453 /// at hashing identifiers.
454 void IdentifierTable::PrintStats() const {
455 unsigned NumBuckets
= HashTable
.getNumBuckets();
456 unsigned NumIdentifiers
= HashTable
.getNumItems();
457 unsigned NumEmptyBuckets
= NumBuckets
-NumIdentifiers
;
458 unsigned AverageIdentifierSize
= 0;
459 unsigned MaxIdentifierLength
= 0;
461 // TODO: Figure out maximum times an identifier had to probe for -stats.
462 for (llvm::StringMap
<IdentifierInfo
*, llvm::BumpPtrAllocator
>::const_iterator
463 I
= HashTable
.begin(), E
= HashTable
.end(); I
!= E
; ++I
) {
464 unsigned IdLen
= I
->getKeyLength();
465 AverageIdentifierSize
+= IdLen
;
466 if (MaxIdentifierLength
< IdLen
)
467 MaxIdentifierLength
= IdLen
;
470 fprintf(stderr
, "\n*** Identifier Table Stats:\n");
471 fprintf(stderr
, "# Identifiers: %d\n", NumIdentifiers
);
472 fprintf(stderr
, "# Empty Buckets: %d\n", NumEmptyBuckets
);
473 fprintf(stderr
, "Hash density (#identifiers per bucket): %f\n",
474 NumIdentifiers
/(double)NumBuckets
);
475 fprintf(stderr
, "Ave identifier length: %f\n",
476 (AverageIdentifierSize
/(double)NumIdentifiers
));
477 fprintf(stderr
, "Max identifier length: %d\n", MaxIdentifierLength
);
479 // Compute statistics about the memory allocated for identifiers.
480 HashTable
.getAllocator().PrintStats();
483 //===----------------------------------------------------------------------===//
484 // SelectorTable Implementation
485 //===----------------------------------------------------------------------===//
487 unsigned llvm::DenseMapInfo
<clang::Selector
>::getHashValue(clang::Selector S
) {
488 return DenseMapInfo
<void*>::getHashValue(S
.getAsOpaquePtr());
493 /// One of these variable length records is kept for each
494 /// selector containing more than one keyword. We use a folding set
495 /// to unique aggregate names (keyword selectors in ObjC parlance). Access to
496 /// this class is provided strictly through Selector.
497 class alignas(IdentifierInfoAlignment
) MultiKeywordSelector
498 : public detail::DeclarationNameExtra
,
499 public llvm::FoldingSetNode
{
500 MultiKeywordSelector(unsigned nKeys
) : DeclarationNameExtra(nKeys
) {}
503 // Constructor for keyword selectors.
504 MultiKeywordSelector(unsigned nKeys
, IdentifierInfo
**IIV
)
505 : DeclarationNameExtra(nKeys
) {
506 assert((nKeys
> 1) && "not a multi-keyword selector");
508 // Fill in the trailing keyword array.
509 IdentifierInfo
**KeyInfo
= reinterpret_cast<IdentifierInfo
**>(this + 1);
510 for (unsigned i
= 0; i
!= nKeys
; ++i
)
514 // getName - Derive the full selector name and return it.
515 std::string
getName() const;
517 using DeclarationNameExtra::getNumArgs
;
519 using keyword_iterator
= IdentifierInfo
*const *;
521 keyword_iterator
keyword_begin() const {
522 return reinterpret_cast<keyword_iterator
>(this + 1);
525 keyword_iterator
keyword_end() const {
526 return keyword_begin() + getNumArgs();
529 IdentifierInfo
*getIdentifierInfoForSlot(unsigned i
) const {
530 assert(i
< getNumArgs() && "getIdentifierInfoForSlot(): illegal index");
531 return keyword_begin()[i
];
534 static void Profile(llvm::FoldingSetNodeID
&ID
, keyword_iterator ArgTys
,
536 ID
.AddInteger(NumArgs
);
537 for (unsigned i
= 0; i
!= NumArgs
; ++i
)
538 ID
.AddPointer(ArgTys
[i
]);
541 void Profile(llvm::FoldingSetNodeID
&ID
) {
542 Profile(ID
, keyword_begin(), getNumArgs());
546 } // namespace clang.
548 bool Selector::isKeywordSelector(ArrayRef
<StringRef
> Names
) const {
549 assert(!Names
.empty() && "must have >= 1 selector slots");
550 if (getNumArgs() != Names
.size())
552 for (unsigned I
= 0, E
= Names
.size(); I
!= E
; ++I
) {
553 if (getNameForSlot(I
) != Names
[I
])
559 bool Selector::isUnarySelector(StringRef Name
) const {
560 return isUnarySelector() && getNameForSlot(0) == Name
;
563 unsigned Selector::getNumArgs() const {
564 unsigned IIF
= getIdentifierInfoFlag();
569 // We point to a MultiKeywordSelector.
570 MultiKeywordSelector
*SI
= getMultiKeywordSelector();
571 return SI
->getNumArgs();
574 IdentifierInfo
*Selector::getIdentifierInfoForSlot(unsigned argIndex
) const {
575 if (getIdentifierInfoFlag() < MultiArg
) {
576 assert(argIndex
== 0 && "illegal keyword index");
577 return getAsIdentifierInfo();
580 // We point to a MultiKeywordSelector.
581 MultiKeywordSelector
*SI
= getMultiKeywordSelector();
582 return SI
->getIdentifierInfoForSlot(argIndex
);
585 StringRef
Selector::getNameForSlot(unsigned int argIndex
) const {
586 IdentifierInfo
*II
= getIdentifierInfoForSlot(argIndex
);
587 return II
? II
->getName() : StringRef();
590 std::string
MultiKeywordSelector::getName() const {
591 SmallString
<256> Str
;
592 llvm::raw_svector_ostream
OS(Str
);
593 for (keyword_iterator I
= keyword_begin(), E
= keyword_end(); I
!= E
; ++I
) {
595 OS
<< (*I
)->getName();
599 return std::string(OS
.str());
602 std::string
Selector::getAsString() const {
604 return "<null selector>";
606 if (getIdentifierInfoFlag() < MultiArg
) {
607 IdentifierInfo
*II
= getAsIdentifierInfo();
609 if (getNumArgs() == 0) {
610 assert(II
&& "If the number of arguments is 0 then II is guaranteed to "
612 return std::string(II
->getName());
618 return II
->getName().str() + ":";
621 // We have a multiple keyword selector.
622 return getMultiKeywordSelector()->getName();
625 void Selector::print(llvm::raw_ostream
&OS
) const {
629 LLVM_DUMP_METHOD
void Selector::dump() const { print(llvm::errs()); }
631 /// Interpreting the given string using the normal CamelCase
632 /// conventions, determine whether the given string starts with the
633 /// given "word", which is assumed to end in a lowercase letter.
634 static bool startsWithWord(StringRef name
, StringRef word
) {
635 if (name
.size() < word
.size()) return false;
636 return ((name
.size() == word
.size() || !isLowercase(name
[word
.size()])) &&
637 name
.startswith(word
));
640 ObjCMethodFamily
Selector::getMethodFamilyImpl(Selector sel
) {
641 IdentifierInfo
*first
= sel
.getIdentifierInfoForSlot(0);
642 if (!first
) return OMF_None
;
644 StringRef name
= first
->getName();
645 if (sel
.isUnarySelector()) {
646 if (name
== "autorelease") return OMF_autorelease
;
647 if (name
== "dealloc") return OMF_dealloc
;
648 if (name
== "finalize") return OMF_finalize
;
649 if (name
== "release") return OMF_release
;
650 if (name
== "retain") return OMF_retain
;
651 if (name
== "retainCount") return OMF_retainCount
;
652 if (name
== "self") return OMF_self
;
653 if (name
== "initialize") return OMF_initialize
;
656 if (name
== "performSelector" || name
== "performSelectorInBackground" ||
657 name
== "performSelectorOnMainThread")
658 return OMF_performSelector
;
660 // The other method families may begin with a prefix of underscores.
661 while (!name
.empty() && name
.front() == '_')
662 name
= name
.substr(1);
664 if (name
.empty()) return OMF_None
;
665 switch (name
.front()) {
667 if (startsWithWord(name
, "alloc")) return OMF_alloc
;
670 if (startsWithWord(name
, "copy")) return OMF_copy
;
673 if (startsWithWord(name
, "init")) return OMF_init
;
676 if (startsWithWord(name
, "mutableCopy")) return OMF_mutableCopy
;
679 if (startsWithWord(name
, "new")) return OMF_new
;
688 ObjCInstanceTypeFamily
Selector::getInstTypeMethodFamily(Selector sel
) {
689 IdentifierInfo
*first
= sel
.getIdentifierInfoForSlot(0);
690 if (!first
) return OIT_None
;
692 StringRef name
= first
->getName();
694 if (name
.empty()) return OIT_None
;
695 switch (name
.front()) {
697 if (startsWithWord(name
, "array")) return OIT_Array
;
700 if (startsWithWord(name
, "default")) return OIT_ReturnsSelf
;
701 if (startsWithWord(name
, "dictionary")) return OIT_Dictionary
;
704 if (startsWithWord(name
, "shared")) return OIT_ReturnsSelf
;
705 if (startsWithWord(name
, "standard")) return OIT_Singleton
;
708 if (startsWithWord(name
, "init")) return OIT_Init
;
716 ObjCStringFormatFamily
Selector::getStringFormatFamilyImpl(Selector sel
) {
717 IdentifierInfo
*first
= sel
.getIdentifierInfoForSlot(0);
718 if (!first
) return SFF_None
;
720 StringRef name
= first
->getName();
722 switch (name
.front()) {
724 if (name
== "appendFormat") return SFF_NSString
;
728 if (name
== "initWithFormat") return SFF_NSString
;
732 if (name
== "localizedStringWithFormat") return SFF_NSString
;
736 if (name
== "stringByAppendingFormat" ||
737 name
== "stringWithFormat") return SFF_NSString
;
745 struct SelectorTableImpl
{
746 llvm::FoldingSet
<MultiKeywordSelector
> Table
;
747 llvm::BumpPtrAllocator Allocator
;
752 static SelectorTableImpl
&getSelectorTableImpl(void *P
) {
753 return *static_cast<SelectorTableImpl
*>(P
);
757 SelectorTable::constructSetterName(StringRef Name
) {
758 SmallString
<64> SetterName("set");
760 SetterName
[3] = toUppercase(SetterName
[3]);
765 SelectorTable::constructSetterSelector(IdentifierTable
&Idents
,
766 SelectorTable
&SelTable
,
767 const IdentifierInfo
*Name
) {
768 IdentifierInfo
*SetterName
=
769 &Idents
.get(constructSetterName(Name
->getName()));
770 return SelTable
.getUnarySelector(SetterName
);
773 std::string
SelectorTable::getPropertyNameFromSetterSelector(Selector Sel
) {
774 StringRef Name
= Sel
.getNameForSlot(0);
775 assert(Name
.startswith("set") && "invalid setter name");
776 return (Twine(toLowercase(Name
[3])) + Name
.drop_front(4)).str();
779 size_t SelectorTable::getTotalMemory() const {
780 SelectorTableImpl
&SelTabImpl
= getSelectorTableImpl(Impl
);
781 return SelTabImpl
.Allocator
.getTotalMemory();
784 Selector
SelectorTable::getSelector(unsigned nKeys
, IdentifierInfo
**IIV
) {
786 return Selector(IIV
[0], nKeys
);
788 SelectorTableImpl
&SelTabImpl
= getSelectorTableImpl(Impl
);
790 // Unique selector, to guarantee there is one per name.
791 llvm::FoldingSetNodeID ID
;
792 MultiKeywordSelector::Profile(ID
, IIV
, nKeys
);
794 void *InsertPos
= nullptr;
795 if (MultiKeywordSelector
*SI
=
796 SelTabImpl
.Table
.FindNodeOrInsertPos(ID
, InsertPos
))
799 // MultiKeywordSelector objects are not allocated with new because they have a
800 // variable size array (for parameter types) at the end of them.
801 unsigned Size
= sizeof(MultiKeywordSelector
) + nKeys
*sizeof(IdentifierInfo
*);
802 MultiKeywordSelector
*SI
=
803 (MultiKeywordSelector
*)SelTabImpl
.Allocator
.Allocate(
804 Size
, alignof(MultiKeywordSelector
));
805 new (SI
) MultiKeywordSelector(nKeys
, IIV
);
806 SelTabImpl
.Table
.InsertNode(SI
, InsertPos
);
810 SelectorTable::SelectorTable() {
811 Impl
= new SelectorTableImpl();
814 SelectorTable::~SelectorTable() {
815 delete &getSelectorTableImpl(Impl
);
818 const char *clang::getOperatorSpelling(OverloadedOperatorKind Operator
) {
821 case NUM_OVERLOADED_OPERATORS
:
824 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
825 case OO_##Name: return Spelling;
826 #include "clang/Basic/OperatorKinds.def"
829 llvm_unreachable("Invalid OverloadedOperatorKind!");
832 StringRef
clang::getNullabilitySpelling(NullabilityKind kind
,
833 bool isContextSensitive
) {
835 case NullabilityKind::NonNull
:
836 return isContextSensitive
? "nonnull" : "_Nonnull";
838 case NullabilityKind::Nullable
:
839 return isContextSensitive
? "nullable" : "_Nullable";
841 case NullabilityKind::NullableResult
:
842 assert(!isContextSensitive
&&
843 "_Nullable_result isn't supported as context-sensitive keyword");
844 return "_Nullable_result";
846 case NullabilityKind::Unspecified
:
847 return isContextSensitive
? "null_unspecified" : "_Null_unspecified";
849 llvm_unreachable("Unknown nullability kind.");
853 IdentifierTable::getFutureCompatDiagKind(const IdentifierInfo
&II
,
854 const LangOptions
&LangOpts
) {
855 assert(II
.isFutureCompatKeyword() && "diagnostic should not be needed");
857 unsigned Flags
= llvm::StringSwitch
<unsigned>(II
.getName())
858 #define KEYWORD(NAME, FLAGS) .Case(#NAME, FLAGS)
859 #include "clang/Basic/TokenKinds.def"
863 if (LangOpts
.CPlusPlus
) {
864 if ((Flags
& KEYCXX11
) == KEYCXX11
)
865 return diag::warn_cxx11_keyword
;
867 // char8_t is not modeled as a CXX20_KEYWORD because it's not
868 // unconditionally enabled in C++20 mode. (It can be disabled
870 if (((Flags
& KEYCXX20
) == KEYCXX20
) ||
871 ((Flags
& CHAR8SUPPORT
) == CHAR8SUPPORT
))
872 return diag::warn_cxx20_keyword
;
874 if ((Flags
& KEYC99
) == KEYC99
)
875 return diag::warn_c99_keyword
;
876 if ((Flags
& KEYC2X
) == KEYC2X
)
877 return diag::warn_c2x_keyword
;
881 "Keyword not known to come from a newer Standard or proposed Standard");