22#include "llvm/ADT/DenseMapInfo.h"
23#include "llvm/ADT/FoldingSet.h"
24#include "llvm/ADT/StringMap.h"
25#include "llvm/ADT/StringRef.h"
26#include "llvm/Support/Allocator.h"
27#include "llvm/Support/raw_ostream.h"
39 "Insufficient ObjCOrBuiltinID Bits");
55 StringRef
Next()
override {
return StringRef(); }
61 return new EmptyLookupIterator();
66 ExternalLookup(ExternalLookup) {}
90 assert((Flag & ~(Flag - 1)) == Flag &&
"Multiple bits set?");
104 if (LangOpts.CPlusPlus11)
108 if (LangOpts.CPlusPlus20)
123 return LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus ?
KS_Enabled
132 if (LangOpts.CPlusPlus)
return KS_Future;
171 llvm_unreachable(
"Unknown KeywordStatus flag");
182 if (LangOpts.HLSL && (Flags &
KEYNOHLSL))
184 if (LangOpts.MSVCCompat && (Flags &
KEYNOMS18) &&
187 if (LangOpts.ZOSExt && (Flags &
KEYNOZOS))
192 unsigned CurFlag = Flags & ~(Flags - 1);
193 Flags = Flags & ~CurFlag;
194 CurStatus = std::max(
264 if (BTID != tok::not_notable) {
274#define KEYWORD(NAME, FLAGS) \
275 AddKeyword(StringRef(#NAME), tok::kw_ ## NAME, \
276 FLAGS, LangOpts, *this);
277#define ALIAS(NAME, TOK, FLAGS) \
278 AddKeyword(StringRef(NAME), tok::kw_ ## TOK, \
279 FLAGS, LangOpts, *this);
280#define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \
281 if (LangOpts.CXXOperatorNames) \
282 AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this); \
284 MarkIdentifierAsKeywordInCpp(*this, StringRef(#NAME));
285#define OBJC_AT_KEYWORD(NAME) \
287 AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
288#define NOTABLE_IDENTIFIER(NAME) \
289 AddNotableIdentifier(StringRef(#NAME), tok::NAME, *this);
291#define TESTING_KEYWORD(NAME, FLAGS)
292#include "clang/Basic/TokenKinds.def"
294 if (LangOpts.ParseUnknownAnytype)
298 if (LangOpts.DeclSpecKeyword)
301 if (LangOpts.IEEE128)
317#define KEYWORD(NAME, FLAGS) \
318 case tok::kw_##NAME: return getKeywordStatus(LangOpts, FLAGS);
319#include "clang/Basic/TokenKinds.def"
339 if (!LangOpts.CPlusPlus || !
isKeyword(LangOpts))
344 LangOptsNoCPP.CPlusPlus =
false;
345 LangOptsNoCPP.CPlusPlus11 =
false;
346 LangOptsNoCPP.CPlusPlus20 =
false;
356 if (Name.size() <= 1)
360 if (Name[0] ==
'_') {
367 if (
'A' <= Name[1] && Name[1] <=
'Z')
368 return ReservedIdentifierStatus::
369 StartsWithUnderscoreFollowedByCapitalLetter;
377 if (LangOpts.CPlusPlus && Name.contains(
"__"))
393 if (Name.contains(
"__"))
401 if (Name.size() >= 2 && Name.front() ==
'_' &&
402 (Name[1] ==
'_' || (Name[1] >=
'A' && Name[1] <=
'Z')))
403 return Name.ltrim(
'_');
413#define HASH(LEN, FIRST, THIRD) \
414 (LEN << 6) + (((FIRST - 'a') - (THIRD - 'a')) & 63)
415#define CASE(LEN, FIRST, THIRD, NAME) \
416 case HASH(LEN, FIRST, THIRD): \
417 return memcmp(Name, #NAME, LEN) ? tok::pp_not_keyword : tok::pp_ ## NAME
420 if (Len < 2)
return tok::pp_not_keyword;
424 return tok::pp___preprocessed_import;
426 return tok::pp___preprocessed_module;
429 switch (
HASH(Len, Name[0], Name[2])) {
430 default:
return tok::pp_not_keyword;
431 CASE( 2,
'i',
'\0',
if);
432 CASE( 4,
'e',
'i', elif);
433 CASE( 4,
'e',
's',
else);
434 CASE( 4,
'l',
'n', line);
435 CASE( 4,
's',
'c', sccs);
436 CASE( 5,
'e',
'b', embed);
437 CASE( 5,
'e',
'd', endif);
438 CASE( 5,
'e',
'r', error);
439 CASE( 5,
'i',
'e', ident);
440 CASE( 5,
'i',
'd', ifdef);
441 CASE( 5,
'u',
'd', undef);
443 CASE( 6,
'a',
's', assert);
444 CASE( 6,
'd',
'f', define);
445 CASE( 6,
'i',
'n', ifndef);
446 CASE( 6,
'i',
'p',
import);
447 CASE( 6,
'm',
'd', module);
448 CASE( 6,
'p',
'a', pragma);
450 CASE( 7,
'd',
'f', defined);
451 CASE( 7,
'e',
'i', elifdef);
452 CASE( 7,
'i',
'c', include);
453 CASE( 7,
'w',
'r', warning);
455 CASE( 8,
'e',
'i', elifndef);
456 CASE( 8,
'u',
'a', unassert);
457 CASE(12,
'i',
'c', include_next);
459 CASE(14,
'_',
'p', __public_macro);
461 CASE(15,
'_',
'p', __private_macro);
463 CASE(16,
'_',
'i', __include_macros);
477 unsigned NumBuckets = HashTable.getNumBuckets();
478 unsigned NumIdentifiers = HashTable.getNumItems();
479 unsigned NumEmptyBuckets = NumBuckets-NumIdentifiers;
480 unsigned AverageIdentifierSize = 0;
481 unsigned MaxIdentifierLength = 0;
484 for (llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator>::const_iterator
485 I = HashTable.begin(), E = HashTable.end(); I != E; ++I) {
486 unsigned IdLen = I->getKeyLength();
487 AverageIdentifierSize += IdLen;
488 if (MaxIdentifierLength < IdLen)
489 MaxIdentifierLength = IdLen;
492 fprintf(
stderr,
"\n*** Identifier Table Stats:\n");
493 fprintf(
stderr,
"# Identifiers: %d\n", NumIdentifiers);
494 fprintf(
stderr,
"# Empty Buckets: %d\n", NumEmptyBuckets);
495 fprintf(
stderr,
"Hash density (#identifiers per bucket): %f\n",
496 NumIdentifiers/(
double)NumBuckets);
497 fprintf(
stderr,
"Ave identifier length: %f\n",
498 (AverageIdentifierSize/(
double)NumIdentifiers));
499 fprintf(
stderr,
"Max identifier length: %d\n", MaxIdentifierLength);
502 HashTable.getAllocator().PrintStats();
514 assert(!Names.empty() &&
"must have >= 1 selector slots");
517 for (
unsigned I = 0, E = Names.size(); I != E; ++I) {
529 unsigned IIF = getIdentifierInfoFlag();
541 if (getIdentifierInfoFlag() < MultiArg) {
542 assert(argIndex == 0 &&
"illegal keyword index");
543 return getAsIdentifierInfo();
553 return II ? II->
getName() : StringRef();
558 llvm::raw_svector_ostream OS(Str);
561 OS << (*I)->getName();
565 return std::string(OS.str());
570 return "<null selector>";
572 if (getIdentifierInfoFlag() < MultiArg) {
576 assert(II &&
"If the number of arguments is 0 then II is guaranteed to "
578 return std::string(II->
getName());
584 return II->
getName().str() +
":";
588 return getMultiKeywordSelector()->getName();
601 if (name.size() < word.size())
return false;
602 return ((name.size() == word.size() || !
isLowercase(name[word.size()])) &&
603 name.starts_with(word));
618 if (name ==
"self")
return OMF_self;
622 if (name ==
"performSelector" || name ==
"performSelectorInBackground" ||
623 name ==
"performSelectorOnMainThread")
630 switch (
name.front()) {
657 StringRef name = first->
getName();
660 switch (name.front()) {
685 StringRef name = first->
getName();
687 switch (name.front()) {
697 if (name ==
"localizedStringWithFormat")
return SFF_NSString;
701 if (name ==
"stringByAppendingFormat" ||
710struct SelectorTableImpl {
711 llvm::FoldingSet<MultiKeywordSelector> Table;
712 llvm::BumpPtrAllocator Allocator;
718 return *
static_cast<SelectorTableImpl*
>(P);
740 assert(Name.starts_with(
"set") &&
"invalid setter name");
741 return (Twine(
toLowercase(Name[3])) + Name.drop_front(4)).str();
746 return SelTabImpl.Allocator.getTotalMemory();
757 llvm::FoldingSetNodeID ID;
760 void *InsertPos =
nullptr;
762 SelTabImpl.Table.FindNodeOrInsertPos(ID, InsertPos))
772 SelTabImpl.Table.InsertNode(SI, InsertPos);
777 Impl =
new SelectorTableImpl();
790#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
791 case OO_##Name: return Spelling;
792#include "clang/Basic/OperatorKinds.def"
795 llvm_unreachable(
"Invalid OverloadedOperatorKind!");
799 bool isContextSensitive) {
802 return isContextSensitive ?
"nonnull" :
"_Nonnull";
805 return isContextSensitive ?
"nullable" :
"_Nullable";
808 assert(!isContextSensitive &&
809 "_Nullable_result isn't supported as context-sensitive keyword");
810 return "_Nullable_result";
813 return isContextSensitive ?
"null_unspecified" :
"_Null_unspecified";
815 llvm_unreachable(
"Unknown nullability kind.");
822 return OS <<
"NonNull";
824 return OS <<
"Nullable";
826 return OS <<
"NullableResult";
828 return OS <<
"Unspecified";
830 llvm_unreachable(
"Unknown nullability kind.");
838 unsigned Flags = llvm::StringSwitch<unsigned>(II.
getName())
839#define KEYWORD(NAME, FLAGS) .Case(#NAME, FLAGS)
840#include "clang/Basic/TokenKinds.def"
844 if (LangOpts.CPlusPlus) {
846 return diag::warn_cxx11_keyword;
853 return diag::warn_cxx20_keyword;
856 return diag::warn_c99_keyword;
858 return diag::warn_c23_keyword;
862 "Keyword not known to come from a newer Standard or proposed Standard");
static void AddObjCKeyword(StringRef Name, tok::ObjCKeywordKind ObjCID, IdentifierTable &Table)
AddObjCKeyword - Register an Objective-C @keyword like "class" "selector" or "property".
static bool IsKeywordInCpp(unsigned Flags)
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 void MarkIdentifierAsKeywordInCpp(IdentifierTable &Table, StringRef Name)
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)
#define HASH(LEN, FIRST, THIRD)
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Defines the clang::LangOptions interface.
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
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.
bool isModuleKeyword() const
Determine whether this is the contextual keyword module.
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)
void setModuleKeyword(bool Val)
Set whether this identifier is the contextual keyword module.
void setHandleIdentifierCase(bool Val=true)
void setIsKeywordInCPlusPlus(bool Val=true)
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.
bool isImportKeyword() const
Determine whether this is the contextual keyword import.
ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const
Determine whether this is a name reserved for the implementation (C99 7.1.3, C++ [lib....
void setKeywordImport(bool Val)
Set whether this identifier is the contextual keyword import.
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 ~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() 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
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:").
void * getAsOpaquePtr() const
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.
The JSON file list parser is used to communicate input to InstallAPI.
TokenKey
Constants for TokenKinds.def.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
@ NUM_OVERLOADED_OPERATORS
KeywordStatus getKeywordStatus(const LangOptions &LangOpts, unsigned Flags)
Translates flags as specified in TokenKinds.def into keyword status in the given language standard.
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.
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.
@ Keyword
The name has been typo-corrected to a keyword.
static constexpr int InterestingIdentifierBits
KeywordStatus
How a keyword is treated in the selected standard.
static constexpr uint64_t LargestBuiltinID
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ConceptReference *C)
Insertion operator for diagnostics.
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.
@ StartsWithDoubleUnderscore
@ ContainsDoubleUnderscore
@ StartsWithUnderscoreAtGlobalScope
__LIBC_ATTRS FILE * stderr