15#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
16#define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
22#include "llvm/ADT/DenseMapInfo.h"
23#include "llvm/ADT/FoldingSet.h"
24#include "llvm/ADT/PointerIntPair.h"
25#include "llvm/ADT/PointerUnion.h"
26#include "llvm/ADT/SmallString.h"
27#include "llvm/ADT/StringMap.h"
28#include "llvm/ADT/StringRef.h"
29#include "llvm/Support/Allocator.h"
30#include "llvm/Support/PointerLikeTypeTraits.h"
31#include "llvm/Support/type_traits.h"
42class DeclarationNameTable;
45class MultiKeywordSelector;
95#define OBJC_AT_KEYWORD(X) objc_##X,
96#include "clang/Basic/TokenKinds.def"
99#define NOTABLE_IDENTIFIER(X) X,
100#include "clang/Basic/TokenKinds.def"
104#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
105#include "clang/Basic/Builtins.inc"
122 unsigned TokenID : 9;
128 LLVM_PREFERRED_TYPE(
bool)
129 unsigned HasMacro : 1;
132 LLVM_PREFERRED_TYPE(
bool)
133 unsigned HadMacro : 1;
136 LLVM_PREFERRED_TYPE(
bool)
137 unsigned IsExtension : 1;
140 LLVM_PREFERRED_TYPE(
bool)
141 unsigned IsFutureCompatKeyword : 1;
144 LLVM_PREFERRED_TYPE(
bool)
145 unsigned IsPoisoned : 1;
148 LLVM_PREFERRED_TYPE(
bool)
149 unsigned IsCPPOperatorKeyword : 1;
153 LLVM_PREFERRED_TYPE(
bool)
154 unsigned NeedsHandleIdentifier : 1;
157 LLVM_PREFERRED_TYPE(
bool)
158 unsigned IsFromAST : 1;
162 LLVM_PREFERRED_TYPE(
bool)
163 unsigned ChangedAfterLoad : 1;
167 LLVM_PREFERRED_TYPE(
bool)
168 unsigned FEChangedAfterLoad : 1;
171 LLVM_PREFERRED_TYPE(
bool)
172 unsigned RevertedTokenID : 1;
176 LLVM_PREFERRED_TYPE(
bool)
177 unsigned OutOfDate : 1;
180 LLVM_PREFERRED_TYPE(
bool)
181 unsigned IsModulesImport : 1;
184 LLVM_PREFERRED_TYPE(
bool)
185 unsigned IsMangledOpenMPVariantName : 1;
188 LLVM_PREFERRED_TYPE(
bool)
189 unsigned IsDeprecatedMacro : 1;
192 LLVM_PREFERRED_TYPE(
bool)
193 unsigned IsRestrictExpansion : 1;
196 LLVM_PREFERRED_TYPE(
bool)
197 unsigned IsFinal : 1;
202 void *FETokenInfo =
nullptr;
204 llvm::StringMapEntry<IdentifierInfo *> *Entry =
nullptr;
207 : TokenID(tok::identifier),
208 InterestingIdentifierID(
llvm::to_underlying(
211 IsFutureCompatKeyword(
false), IsPoisoned(
false),
212 IsCPPOperatorKeyword(
false), NeedsHandleIdentifier(
false),
215 IsMangledOpenMPVariantName(
false), IsDeprecatedMacro(
false),
227 template <std::
size_t StrLen>
228 bool isStr(
const char (&Str)[StrLen])
const {
229 return getLength() == StrLen-1 &&
230 memcmp(getNameStart(), Str, StrLen-1) == 0;
234 bool isStr(llvm::StringRef Str)
const {
235 llvm::StringRef ThisStr(getNameStart(), getLength());
236 return ThisStr == Str;
244 unsigned getLength()
const {
return Entry->getKeyLength(); }
248 return StringRef(getNameStart(), getLength());
257 if (HasMacro == Val)
return;
261 NeedsHandleIdentifier =
true;
269 IsDeprecatedMacro =
false;
270 IsRestrictExpansion =
false;
272 RecomputeNeedsHandleIdentifier();
285 if (IsDeprecatedMacro == Val)
287 IsDeprecatedMacro = Val;
289 NeedsHandleIdentifier =
true;
291 RecomputeNeedsHandleIdentifier();
297 if (IsRestrictExpansion == Val)
299 IsRestrictExpansion = Val;
301 NeedsHandleIdentifier =
true;
303 RecomputeNeedsHandleIdentifier();
325 assert(TokenID != tok::identifier &&
"Already at tok::identifier");
326 TokenID = tok::identifier;
327 RevertedTokenID =
true;
330 assert(TokenID == tok::identifier &&
"Should be at tok::identifier");
332 RevertedTokenID =
false;
344 assert(0 == llvm::to_underlying(InterestingIdentifier::objc_not_keyword));
346 if (
Value < InterestingIdentifier::NUM_OBJC_KEYWORDS)
348 return tok::objc_not_keyword;
351 assert(0 == llvm::to_underlying(InterestingIdentifier::objc_not_keyword));
352 InterestingIdentifierID =
ID;
353 assert(getObjCKeywordID() ==
ID &&
"ID too large for field!");
360 InterestingIdentifier::NUM_OBJC_KEYWORDS_AND_NOTABLE_IDENTIFIERS &&
361 Value != InterestingIdentifier::NotInterestingIdentifier) {
363 llvm::to_underlying(InterestingIdentifier::NotBuiltin);
364 return static_cast<Builtin::ID>(InterestingIdentifierID - FirstBuiltin);
366 return Builtin::ID::NotBuiltin;
369 assert(
ID != Builtin::ID::NotBuiltin);
370 auto FirstBuiltin = llvm::to_underlying(InterestingIdentifier::NotBuiltin);
371 InterestingIdentifierID =
ID + FirstBuiltin;
372 assert(getBuiltinID() ==
ID &&
"ID too large for field!");
375 InterestingIdentifierID =
376 llvm::to_underlying(InterestingIdentifier::NotInterestingIdentifier);
381 if (
Value > InterestingIdentifier::NUM_OBJC_KEYWORDS &&
383 InterestingIdentifier::NUM_OBJC_KEYWORDS_AND_NOTABLE_IDENTIFIERS) {
384 auto FirstNotableIdentifier =
385 1 + llvm::to_underlying(InterestingIdentifier::NUM_OBJC_KEYWORDS);
387 FirstNotableIdentifier);
389 return tok::not_notable;
392 assert(
ID != tok::not_notable);
393 auto FirstNotableIdentifier =
394 1 + llvm::to_underlying(InterestingIdentifier::NUM_OBJC_KEYWORDS);
395 InterestingIdentifierID =
ID + FirstNotableIdentifier;
396 assert(getNotableIdentifierID() ==
ID &&
"ID too large for field!");
409 NeedsHandleIdentifier =
true;
411 RecomputeNeedsHandleIdentifier();
421 IsFutureCompatKeyword = Val;
423 NeedsHandleIdentifier =
true;
425 RecomputeNeedsHandleIdentifier();
433 NeedsHandleIdentifier =
true;
435 RecomputeNeedsHandleIdentifier();
444 IsCPPOperatorKeyword = Val;
453 bool isCPlusPlusKeyword(
const LangOptions &LangOpts)
const;
476 return ChangedAfterLoad;
482 ChangedAfterLoad =
true;
488 return FEChangedAfterLoad;
494 FEChangedAfterLoad =
true;
506 NeedsHandleIdentifier =
true;
508 RecomputeNeedsHandleIdentifier();
518 NeedsHandleIdentifier =
true;
520 RecomputeNeedsHandleIdentifier();
552 StringRef deuglifiedName()
const;
554 return getLength() == 1 && getNameStart()[0] ==
'_';
569 void RecomputeNeedsHandleIdentifier() {
570 NeedsHandleIdentifier = isPoisoned() || hasMacroDefinition() ||
571 isExtensionToken() || isFutureCompatKeyword() ||
572 isOutOfDate() || isModulesImport();
586 : II(II), OldValue(II ? II->isPoisoned() :
false) {
658 using HashTableTy = llvm::StringMap<IdentifierInfo *, llvm::BumpPtrAllocator>;
659 HashTableTy HashTable;
674 ExternalLookup = IILookup;
679 return ExternalLookup;
683 return HashTable.getAllocator();
689 auto &Entry = *HashTable.try_emplace(Name,
nullptr).first;
695 if (ExternalLookup) {
696 II = ExternalLookup->
get(Name);
714 II.TokenID = TokenCode;
715 assert(II.TokenID == (
unsigned) TokenCode &&
"TokenCode too large");
726 auto &Entry = *HashTable.insert(std::make_pair(Name,
nullptr)).first;
741 if (Name ==
"import")
752 unsigned size()
const {
return HashTable.size(); }
758 void PrintStats()
const;
884 : ExtraKindOrNumArgs(ObjCMultiArgSelector + NumArgs) {}
888 return static_cast<ExtraKind>(ExtraKindOrNumArgs >
890 ? (
unsigned)ObjCMultiArgSelector
891 : ExtraKindOrNumArgs);
897 assert(ExtraKindOrNumArgs >= (
unsigned)ObjCMultiArgSelector &&
898 "getNumArgs called but this is not an ObjC selector!");
899 return ExtraKindOrNumArgs - (
unsigned)ObjCMultiArgSelector;
911 public llvm::FoldingSetNode {
917 : DeclarationNameExtra(nKeys) {
918 assert((nKeys > 1) &&
"not a multi-keyword selector");
923 for (
unsigned i = 0; i != nKeys; ++i)
930 using DeclarationNameExtra::getNumArgs;
939 return keyword_begin() + getNumArgs();
943 assert(i < getNumArgs() &&
"getIdentifierInfoForSlot(): illegal index");
944 return keyword_begin()[i];
949 ID.AddInteger(NumArgs);
950 for (
unsigned i = 0; i != NumArgs; ++i)
951 ID.AddPointer(ArgTys[i]);
955 Profile(
ID, keyword_begin(), getNumArgs());
971 enum IdentifierInfoFlag {
994 llvm::PointerIntPair<
995 llvm::PointerUnion<const IdentifierInfo *, MultiKeywordSelector *>, 2>
999 assert(nArgs < 2 &&
"nArgs not equal to 0/1");
1000 InfoPtr.setPointerAndInt(II, nArgs + 1);
1003 Selector(MultiKeywordSelector *SI) {
1007 InfoPtr.setPointerAndInt(SI, MultiArg & 0b11);
1010 const IdentifierInfo *getAsIdentifierInfo()
const {
1011 return InfoPtr.getPointer().dyn_cast<
const IdentifierInfo *>();
1014 MultiKeywordSelector *getMultiKeywordSelector()
const {
1015 return InfoPtr.getPointer().get<MultiKeywordSelector *>();
1018 unsigned getIdentifierInfoFlag()
const {
1019 unsigned new_flags = InfoPtr.getInt();
1023 if (InfoPtr.getPointer().is<MultiKeywordSelector *>())
1024 new_flags |= MultiArg;
1037 InfoPtr.setFromOpaqueValue(
reinterpret_cast<void *
>(
V));
1042 return InfoPtr.getOpaqueValue() == RHS.InfoPtr.getOpaqueValue();
1045 return InfoPtr.getOpaqueValue() != RHS.InfoPtr.getOpaqueValue();
1051 bool isNull()
const {
return InfoPtr.getOpaqueValue() ==
nullptr; }
1062 bool isUnarySelector(StringRef Name)
const;
1064 unsigned getNumArgs()
const;
1079 const IdentifierInfo *getIdentifierInfoForSlot(
unsigned argIndex)
const;
1089 StringRef getNameForSlot(
unsigned argIndex)
const;
1096 void print(llvm::raw_ostream &OS)
const;
1102 return getMethodFamilyImpl(*
this);
1106 return getStringFormatFamilyImpl(*
this);
1147 size_t getTotalMemory()
const;
1164 static std::string getPropertyNameFromSetterSelector(
Selector Sel);
1193 return P.getAsOpaquePtr();
1200 static constexpr int NumLowBitsAvailable = 0;
Defines enum values for all the target-independent builtin functions.
enum clang::sema::@1653::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 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.
static std::string getName(const CallEvent &Call)
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) ...
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.
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.
bool isFromAST() const
Return true if the identifier in its current state was loaded from an AST file.
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
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
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.
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.
@ ObjCMethodFamilyBitWidth
@ IdentifierInfoAlignment
ObjCInstanceTypeFamily
A family of Objective-C methods.
ReservedLiteralSuffixIdStatus
@ NotStartsWithUnderscore
static constexpr int InterestingIdentifierBits
const FunctionProtoType * T
bool isReservedAtGlobalScope(ReservedIdentifierStatus Status)
Determine whether an identifier is reserved for use as a name at global scope.
@ InvalidObjCMethodFamily
llvm::StringRef getAsString(SyncScope S)
std::pair< IdentifierInfo *, SourceLocation > IdentifierLocPair
A simple pair of identifier info and location.
@ 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)