15#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
16#define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
23#include "llvm/ADT/DenseMapInfo.h"
24#include "llvm/ADT/FoldingSet.h"
25#include "llvm/ADT/PointerIntPair.h"
26#include "llvm/ADT/PointerUnion.h"
27#include "llvm/ADT/SmallString.h"
28#include "llvm/ADT/StringMap.h"
29#include "llvm/ADT/StringRef.h"
30#include "llvm/Support/Allocator.h"
31#include "llvm/Support/PointerLikeTypeTraits.h"
32#include "llvm/Support/type_traits.h"
43class DeclarationNameTable;
46class MultiKeywordSelector;
93#define OBJC_AT_KEYWORD(X) objc_##X,
94#include "clang/Basic/TokenKinds.def"
97#define NOTABLE_IDENTIFIER(X) X,
98#include "clang/Basic/TokenKinds.def"
102#define GET_BUILTIN_ENUMERATORS
103#include "clang/Basic/Builtins.inc"
104#undef GET_BUILTIN_ENUMERATORS
121 unsigned TokenID : 9;
127 LLVM_PREFERRED_TYPE(
bool)
128 unsigned HasMacro : 1;
131 LLVM_PREFERRED_TYPE(
bool)
132 unsigned HadMacro : 1;
135 LLVM_PREFERRED_TYPE(
bool)
136 unsigned IsExtension : 1;
139 LLVM_PREFERRED_TYPE(
bool)
140 unsigned IsFutureCompatKeyword : 1;
143 LLVM_PREFERRED_TYPE(
bool)
144 unsigned IsPoisoned : 1;
147 LLVM_PREFERRED_TYPE(
bool)
148 unsigned IsCPPOperatorKeyword : 1;
152 LLVM_PREFERRED_TYPE(
bool)
153 unsigned NeedsHandleIdentifier : 1;
156 LLVM_PREFERRED_TYPE(
bool)
157 unsigned IsFromAST : 1;
161 LLVM_PREFERRED_TYPE(
bool)
162 unsigned ChangedAfterLoad : 1;
166 LLVM_PREFERRED_TYPE(
bool)
167 unsigned FEChangedAfterLoad : 1;
170 LLVM_PREFERRED_TYPE(
bool)
171 unsigned RevertedTokenID : 1;
175 LLVM_PREFERRED_TYPE(
bool)
176 unsigned OutOfDate : 1;
179 LLVM_PREFERRED_TYPE(
bool)
180 unsigned IsModulesImport : 1;
183 LLVM_PREFERRED_TYPE(
bool)
184 unsigned IsMangledOpenMPVariantName : 1;
187 LLVM_PREFERRED_TYPE(
bool)
188 unsigned IsDeprecatedMacro : 1;
191 LLVM_PREFERRED_TYPE(
bool)
192 unsigned IsRestrictExpansion : 1;
195 LLVM_PREFERRED_TYPE(
bool)
196 unsigned IsFinal : 1;
199 LLVM_PREFERRED_TYPE(
bool)
205 void *FETokenInfo =
nullptr;
207 llvm::StringMapEntry<IdentifierInfo *> *Entry =
nullptr;
210 : TokenID(tok::identifier),
211 InterestingIdentifierID(
llvm::to_underlying(
214 IsFutureCompatKeyword(
false), IsPoisoned(
false),
215 IsCPPOperatorKeyword(
false), NeedsHandleIdentifier(
false),
218 IsMangledOpenMPVariantName(
false), IsDeprecatedMacro(
false),
230 template <std::
size_t StrLen>
231 bool isStr(
const char (&Str)[StrLen])
const {
232 return getLength() == StrLen-1 &&
233 memcmp(getNameStart(), Str, StrLen-1) == 0;
237 bool isStr(llvm::StringRef Str)
const {
238 llvm::StringRef ThisStr(getNameStart(), getLength());
239 return ThisStr == Str;
247 unsigned getLength()
const {
return Entry->getKeyLength(); }
251 return StringRef(getNameStart(), getLength());
260 if (HasMacro == Val)
return;
264 NeedsHandleIdentifier =
true;
272 IsDeprecatedMacro =
false;
273 IsRestrictExpansion =
false;
275 RecomputeNeedsHandleIdentifier();
288 if (IsDeprecatedMacro == Val)
290 IsDeprecatedMacro = Val;
292 NeedsHandleIdentifier =
true;
294 RecomputeNeedsHandleIdentifier();
300 if (IsRestrictExpansion == Val)
302 IsRestrictExpansion = Val;
304 NeedsHandleIdentifier =
true;
306 RecomputeNeedsHandleIdentifier();
328 assert(TokenID != tok::identifier &&
"Already at tok::identifier");
329 TokenID = tok::identifier;
330 RevertedTokenID =
true;
333 assert(TokenID == tok::identifier &&
"Should be at tok::identifier");
335 RevertedTokenID =
false;
347 assert(0 == llvm::to_underlying(InterestingIdentifier::objc_not_keyword));
349 if (
Value < InterestingIdentifier::NUM_OBJC_KEYWORDS)
351 return tok::objc_not_keyword;
354 assert(0 == llvm::to_underlying(InterestingIdentifier::objc_not_keyword));
355 InterestingIdentifierID =
ID;
356 assert(getObjCKeywordID() ==
ID &&
"ID too large for field!");
363 InterestingIdentifier::NUM_OBJC_KEYWORDS_AND_NOTABLE_IDENTIFIERS &&
364 Value != InterestingIdentifier::NotInterestingIdentifier) {
366 llvm::to_underlying(InterestingIdentifier::NotBuiltin);
367 return static_cast<Builtin::ID>(InterestingIdentifierID - FirstBuiltin);
369 return Builtin::ID::NotBuiltin;
372 assert(
ID != Builtin::ID::NotBuiltin);
373 auto FirstBuiltin = llvm::to_underlying(InterestingIdentifier::NotBuiltin);
374 InterestingIdentifierID =
ID + FirstBuiltin;
375 assert(getBuiltinID() ==
ID &&
"ID too large for field!");
378 InterestingIdentifierID =
379 llvm::to_underlying(InterestingIdentifier::NotInterestingIdentifier);
384 if (
Value > InterestingIdentifier::NUM_OBJC_KEYWORDS &&
386 InterestingIdentifier::NUM_OBJC_KEYWORDS_AND_NOTABLE_IDENTIFIERS) {
387 auto FirstNotableIdentifier =
388 1 + llvm::to_underlying(InterestingIdentifier::NUM_OBJC_KEYWORDS);
390 FirstNotableIdentifier);
392 return tok::not_notable;
395 assert(
ID != tok::not_notable);
396 auto FirstNotableIdentifier =
397 1 + llvm::to_underlying(InterestingIdentifier::NUM_OBJC_KEYWORDS);
398 InterestingIdentifierID =
ID + FirstNotableIdentifier;
399 assert(getNotableIdentifierID() ==
ID &&
"ID too large for field!");
412 NeedsHandleIdentifier =
true;
414 RecomputeNeedsHandleIdentifier();
424 IsFutureCompatKeyword = Val;
426 NeedsHandleIdentifier =
true;
428 RecomputeNeedsHandleIdentifier();
436 NeedsHandleIdentifier =
true;
438 RecomputeNeedsHandleIdentifier();
447 IsCPPOperatorKeyword = Val;
460 bool isCPlusPlusKeyword(
const LangOptions &LangOpts)
const;
484 return ChangedAfterLoad;
490 ChangedAfterLoad =
true;
496 return FEChangedAfterLoad;
502 FEChangedAfterLoad =
true;
514 NeedsHandleIdentifier =
true;
516 RecomputeNeedsHandleIdentifier();
526 NeedsHandleIdentifier =
true;
528 RecomputeNeedsHandleIdentifier();
547 return getName().starts_with(
"<#") && getName().ends_with(
"#>");
560 StringRef deuglifiedName()
const;
562 return getLength() == 1 && getNameStart()[0] ==
'_';
567 return getName() < RHS.
getName();
577 void RecomputeNeedsHandleIdentifier() {
578 NeedsHandleIdentifier = isPoisoned() || hasMacroDefinition() ||
579 isExtensionToken() || isFutureCompatKeyword() ||
580 isOutOfDate() || isModulesImport();
594 : II(II), OldValue(II ? II->isPoisoned() :
false) {
666 using HashTableTy = llvm::StringMap<IdentifierInfo *, llvm::BumpPtrAllocator>;
667 HashTableTy HashTable;
682 ExternalLookup = IILookup;
687 return ExternalLookup;
691 return HashTable.getAllocator();
697 auto &Entry = *HashTable.try_emplace(Name,
nullptr).first;
703 if (ExternalLookup) {
704 II = ExternalLookup->
get(Name);
722 II.TokenID = TokenCode;
723 assert(II.TokenID == (
unsigned) TokenCode &&
"TokenCode too large");
734 auto &Entry = *HashTable.try_emplace(Name).first;
749 if (Name ==
"import")
760 unsigned size()
const {
return HashTable.size(); }
766 void PrintStats()
const;
892 : ExtraKindOrNumArgs(ObjCMultiArgSelector + NumArgs) {}
896 return static_cast<ExtraKind>(ExtraKindOrNumArgs >
898 ? (
unsigned)ObjCMultiArgSelector
899 : ExtraKindOrNumArgs);
905 assert(ExtraKindOrNumArgs >= (
unsigned)ObjCMultiArgSelector &&
906 "getNumArgs called but this is not an ObjC selector!");
907 return ExtraKindOrNumArgs - (
unsigned)ObjCMultiArgSelector;
919 public llvm::FoldingSetNode {
925 : DeclarationNameExtra(nKeys) {
926 assert((nKeys > 1) &&
"not a multi-keyword selector");
931 for (
unsigned i = 0; i != nKeys; ++i)
936 std::string getName()
const;
938 using DeclarationNameExtra::getNumArgs;
947 return keyword_begin() + getNumArgs();
951 assert(i < getNumArgs() &&
"getIdentifierInfoForSlot(): illegal index");
952 return keyword_begin()[i];
957 ID.AddInteger(NumArgs);
958 for (
unsigned i = 0; i != NumArgs; ++i)
959 ID.AddPointer(ArgTys[i]);
963 Profile(
ID, keyword_begin(), getNumArgs());
979 enum IdentifierInfoFlag {
1002 llvm::PointerIntPair<
1003 llvm::PointerUnion<const IdentifierInfo *, MultiKeywordSelector *>, 2>
1007 assert(nArgs < 2 &&
"nArgs not equal to 0/1");
1008 InfoPtr.setPointerAndInt(II, nArgs + 1);
1011 Selector(MultiKeywordSelector *SI) {
1015 InfoPtr.setPointerAndInt(SI, MultiArg & 0b11);
1018 const IdentifierInfo *getAsIdentifierInfo()
const {
1019 return dyn_cast_if_present<const IdentifierInfo *>(InfoPtr.getPointer());
1022 MultiKeywordSelector *getMultiKeywordSelector()
const {
1023 return cast<MultiKeywordSelector *>(InfoPtr.getPointer());
1026 unsigned getIdentifierInfoFlag()
const {
1027 unsigned new_flags = InfoPtr.getInt();
1031 if (isa<MultiKeywordSelector *>(InfoPtr.getPointer()))
1032 new_flags |= MultiArg;
1045 InfoPtr.setFromOpaqueValue(
reinterpret_cast<void *
>(
V));
1050 return InfoPtr.getOpaqueValue() == RHS.InfoPtr.getOpaqueValue();
1053 return InfoPtr.getOpaqueValue() != RHS.InfoPtr.getOpaqueValue();
1059 bool isNull()
const {
return InfoPtr.getOpaqueValue() ==
nullptr; }
1070 bool isUnarySelector(StringRef Name)
const;
1072 unsigned getNumArgs()
const;
1087 const IdentifierInfo *getIdentifierInfoForSlot(
unsigned argIndex)
const;
1097 StringRef getNameForSlot(
unsigned argIndex)
const;
1104 void print(llvm::raw_ostream &OS)
const;
1110 return getMethodFamilyImpl(*
this);
1114 return getStringFormatFamilyImpl(*
this);
1155 size_t getTotalMemory()
const;
1172 static std::string getPropertyNameFromSetterSelector(
Selector Sel);
1190 return Loc ==
X.Loc && II ==
X.II;
1194 return Loc !=
X.Loc || II !=
X.II;
1223 return P.getAsOpaquePtr();
1230 static constexpr int NumLowBitsAvailable = 0;
Defines enum values for all the target-independent builtin functions.
enum clang::sema::@1840::IndirectLocalPathEntry::EntryKind Kind
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
Defines the Diagnostic IDs-related interfaces.
static bool IsKeywordInCpp(unsigned Flags)
static void print(llvm::raw_ostream &OS, const T &V, ASTContext &ASTCtx, QualType Ty)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::SourceLocation class and associated facilities.
Defines the clang::TokenKind enum and support functions.
The name of a declaration.
A little helper class (which is basically a smart pointer that forwards info from DiagnosticsEngine a...
Provides lookups to, and iteration over, IdentiferInfo objects.
virtual ~IdentifierInfoLookup()
virtual IdentifierInfo * get(StringRef Name)=0
Return the IdentifierInfo for the specified named identifier.
One of these records is kept for each identifier that is lexed.
bool isHandleIdentifierCase() const
Return true if the Preprocessor::HandleIdentifier must be called on a token of this identifier.
IdentifierInfo(const IdentifierInfo &)=delete
IdentifierInfo(IdentifierInfo &&)=delete
bool isModulesImport() const
Determine whether this is the contextual keyword import.
void revertIdentifierToTokenID(tok::TokenKind TK)
unsigned getLength() const
Efficiently return the length of this identifier info.
unsigned getBuiltinID() const
Return a value indicating whether this is a builtin function.
bool IsKeywordInCPlusPlus() const
Return true if this identifier would be a keyword in C++ mode.
void setModulesImport(bool I)
Set whether this identifier is the contextual keyword import.
void setNotableIdentifierID(unsigned ID)
void setIsExtensionToken(bool Val)
void setIsRestrictExpansion(bool Val)
void setFETokenInfo(void *T)
bool hasChangedSinceDeserialization() const
Determine whether this identifier has changed since it was loaded from an AST file.
bool isCPlusPlusOperatorKeyword() const
IdentifierInfo & operator=(const IdentifierInfo &)=delete
void setIsDeprecatedMacro(bool Val)
bool hasFETokenInfoChangedSinceDeserialization() const
Determine whether the frontend token information for this identifier has changed since it was loaded ...
void setMangledOpenMPVariantName(bool I)
Set whether this is the mangled name of an OpenMP variant.
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
bool hadMacroDefinition() const
Returns true if this identifier was #defined to some value at any moment.
void setIsPoisoned(bool Value=true)
setIsPoisoned - Mark this identifier as poisoned.
void setObjCKeywordID(tok::ObjCKeywordKind ID)
void setIsFinal(bool Val)
IdentifierInfo & operator=(IdentifierInfo &&)=delete
bool hasMacroDefinition() const
Return true if this identifier is #defined to some other value.
void setHandleIdentifierCase(bool Val=true)
bool isFromAST() const
Return true if the identifier in its current state was loaded from an AST file.
void setIsKeywordInCPlusPlus(bool Val=true)
bool isPoisoned() const
Return true if this token has been poisoned.
bool hasRevertedTokenIDToIdentifier() const
True if revertTokenIDToIdentifier() was called.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
tok::NotableIdentifierKind getNotableIdentifierID() const
bool isMangledOpenMPVariantName() const
Determine whether this is the mangled name of an OpenMP variant.
void setOutOfDate(bool OOD)
Set whether the information for this identifier is out of date with respect to the external source.
void setHasMacroDefinition(bool Val)
bool isStr(llvm::StringRef Str) const
Return true if this is the identifier for the specified StringRef.
unsigned getObjCOrBuiltinID() const
tok::ObjCKeywordKind getObjCKeywordID() const
Return the Objective-C keyword ID for the this identifier.
void setObjCOrBuiltinID(unsigned ID)
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
bool isEditorPlaceholder() const
Return true if this identifier is an editor placeholder.
void setIsCPlusPlusOperatorKeyword(bool Val=true)
isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether this identifier is a C++ al...
void setBuiltinID(unsigned ID)
void setFETokenInfoChangedSinceDeserialization()
Note that the frontend token information for this identifier has changed since it was loaded from an ...
bool operator<(const IdentifierInfo &RHS) const
Provide less than operator for lexicographical sorting.
void revertTokenIDToIdentifier()
Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2 compatibility.
bool isDeprecatedMacro() const
bool isOutOfDate() const
Determine whether the information for this identifier is out of date with respect to the external sou...
void setIsFutureCompatKeyword(bool Val)
void setChangedSinceDeserialization()
Note that this identifier has changed since it was loaded from an AST file.
void * getFETokenInfo() const
Get and set FETokenInfo.
bool isPlaceholder() const
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...
bool isExtensionToken() const
get/setExtension - Initialize information about whether or not this language token is an extension.
bool isRestrictExpansion() const
An iterator that walks over all of the known identifiers in the lookup table.
virtual StringRef Next()=0
Retrieve the next string in the identifier table and advances the iterator for the following string.
IdentifierIterator & operator=(const IdentifierIterator &)=delete
IdentifierIterator(const IdentifierIterator &)=delete
virtual ~IdentifierIterator()
IdentifierIterator()=default
A simple pair of identifier info and location.
bool operator!=(const IdentifierLoc &X) const
SourceLocation getLoc() const
bool operator==(const IdentifierLoc &X) const
void setIdentifierInfo(IdentifierInfo *Ident)
void setLoc(SourceLocation L)
IdentifierInfo * getIdentifierInfo() const
IdentifierLoc(SourceLocation L, IdentifierInfo *Ident)
Implements an efficient mapping from strings to IdentifierInfo nodes.
IdentifierInfo & getOwn(StringRef Name)
Gets an IdentifierInfo for the given name without consulting external sources.
iterator find(StringRef Name) const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
IdentifierInfo & get(StringRef Name, tok::TokenKind TokenCode)
IdentifierInfoLookup * getExternalIdentifierLookup() const
Retrieve the external identifier lookup object, if any.
HashTableTy::const_iterator iterator
HashTableTy::const_iterator const_iterator
llvm::BumpPtrAllocator & getAllocator()
void setExternalIdentifierLookup(IdentifierInfoLookup *IILookup)
Set the external identifier lookup mechanism.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
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
MultiKeywordSelector(unsigned nKeys, const IdentifierInfo **IIV)
void Profile(llvm::FoldingSetNodeID &ID)
static void Profile(llvm::FoldingSetNodeID &ID, keyword_iterator ArgTys, unsigned NumArgs)
keyword_iterator keyword_begin() const
const IdentifierInfo * getIdentifierInfoForSlot(unsigned i) const
An RAII object for [un]poisoning an identifier within a scope.
~PoisonIdentifierRAIIObject()
PoisonIdentifierRAIIObject(IdentifierInfo *II, bool NewValue)
This table allows us to fully hide how we implement multi-keyword caching.
SelectorTable(const SelectorTable &)=delete
Selector getNullarySelector(const IdentifierInfo *ID)
Selector getUnarySelector(const IdentifierInfo *ID)
SelectorTable & operator=(const SelectorTable &)=delete
Smart pointer class that efficiently represents Objective-C method names.
Selector()=default
The default ctor should only be used when creating data structures that will contain selectors.
static Selector getEmptyMarker()
static Selector getTombstoneMarker()
void * getAsOpaquePtr() const
bool isKeywordSelector() const
ObjCMethodFamily getMethodFamily() const
Derive the conventional family of this method.
bool operator==(Selector RHS) const
operator==/!= - Indicate whether the specified selectors are identical.
bool isUnarySelector() const
bool operator!=(Selector RHS) const
bool isNull() const
Determine whether this is the empty selector.
ObjCStringFormatFamily getStringFormatFamily() const
Encodes a location in the source.
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.
@ IdentifierInfoAlignment
@ ObjCMethodFamilyBitWidth
bool isReservedInAllContexts(ReservedIdentifierStatus Status)
Determine whether an identifier is reserved in all contexts.
InterestingIdentifier
The "layout" of InterestingIdentifier is:
@ NUM_OBJC_KEYWORDS_AND_NOTABLE_IDENTIFIERS
@ NotInterestingIdentifier
ObjCMethodFamily
A family of Objective-C methods.
@ OMF_None
No particular method family.
ObjCInstanceTypeFamily
A family of Objective-C methods.
ReservedLiteralSuffixIdStatus
@ NotStartsWithUnderscore
static constexpr int InterestingIdentifierBits
@ InvalidObjCMethodFamily
const FunctionProtoType * T
bool isReservedAtGlobalScope(ReservedIdentifierStatus Status)
Determine whether an identifier is reserved for use as a name at global scope.
llvm::StringRef getAsString(SyncScope S)
@ StartsWithDoubleUnderscore
@ StartsWithUnderscoreFollowedByCapitalLetter
@ ContainsDoubleUnderscore
@ StartsWithUnderscoreAtGlobalScope
@ StartsWithUnderscoreAndIsExternC
Diagnostic wrappers for TextAPI types for error reporting.
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
static clang::Selector getEmptyKey()
static bool isEqual(clang::Selector LHS, clang::Selector RHS)
static clang::Selector getTombstoneKey()
static clang::Selector getFromVoidPointer(const void *P)
static const void * getAsVoidPointer(clang::Selector P)