21 #include "llvm/ADT/DenseMapInfo.h" 22 #include "llvm/ADT/FoldingSet.h" 23 #include "llvm/ADT/SmallString.h" 24 #include "llvm/ADT/StringMap.h" 25 #include "llvm/ADT/StringRef.h" 26 #include "llvm/Support/Allocator.h" 27 #include "llvm/Support/ErrorHandling.h" 28 #include "llvm/Support/raw_ostream.h" 34 using namespace clang;
51 StringRef Next()
override {
return StringRef(); }
57 return new EmptyLookupIterator();
62 ExternalLookup(ExternalLookup) {}
93 WCHARSUPPORT = 0x2000,
95 CHAR8SUPPORT = 0x8000,
96 KEYCONCEPTS = 0x10000,
99 KEYCOROUTINES = 0x80000,
100 KEYMODULES = 0x100000,
102 KEYOPENCLCXX = 0x400000,
103 KEYALLCXX = KEYCXX | KEYCXX11 | KEYCXX2A,
104 KEYALL = (0xffffff & ~KEYNOMS18 &
122 if (Flags == KEYALL)
return KS_Enabled;
123 if (LangOpts.CPlusPlus && (Flags & KEYCXX))
return KS_Enabled;
124 if (LangOpts.CPlusPlus11 && (Flags & KEYCXX11))
return KS_Enabled;
125 if (LangOpts.CPlusPlus2a && (Flags & KEYCXX2A))
return KS_Enabled;
126 if (LangOpts.C99 && (Flags & KEYC99))
return KS_Enabled;
127 if (LangOpts.GNUKeywords && (Flags & KEYGNU))
return KS_Extension;
128 if (LangOpts.MicrosoftExt && (Flags & KEYMS))
return KS_Extension;
129 if (LangOpts.Borland && (Flags & KEYBORLAND))
return KS_Extension;
130 if (LangOpts.Bool && (Flags & BOOLSUPPORT))
return KS_Enabled;
131 if (LangOpts.Half && (Flags & HALFSUPPORT))
return KS_Enabled;
132 if (LangOpts.WChar && (Flags & WCHARSUPPORT))
return KS_Enabled;
133 if (LangOpts.Char8 && (Flags & CHAR8SUPPORT))
return KS_Enabled;
134 if (LangOpts.AltiVec && (Flags & KEYALTIVEC))
return KS_Enabled;
135 if (LangOpts.ZVector && (Flags & KEYZVECTOR))
return KS_Enabled;
136 if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus && (Flags & KEYOPENCLC))
138 if (LangOpts.OpenCLCPlusPlus && (Flags & KEYOPENCLCXX))
return KS_Enabled;
139 if (!LangOpts.CPlusPlus && (Flags & KEYNOCXX))
return KS_Enabled;
140 if (LangOpts.C11 && (Flags & KEYC11))
return KS_Enabled;
143 if (LangOpts.ObjC && (Flags & KEYOBJC))
return KS_Enabled;
144 if (LangOpts.ConceptsTS && (Flags & KEYCONCEPTS))
return KS_Enabled;
145 if (LangOpts.CoroutinesTS && (Flags & KEYCOROUTINES))
return KS_Enabled;
146 if (LangOpts.ModulesTS && (Flags & KEYMODULES))
return KS_Enabled;
147 if (LangOpts.CPlusPlus && (Flags & KEYALLCXX))
return KS_Future;
160 if (LangOpts.MSVCCompat && (Flags & KEYNOMS18) &&
165 if (LangOpts.OpenCL && (Flags & KEYNOOPENCL))
169 if (AddResult == KS_Disabled)
return;
172 Table.
get(Keyword, AddResult == KS_Future ? tok::identifier : TokenCode);
198 #define KEYWORD(NAME, FLAGS) \ 199 AddKeyword(StringRef(#NAME), tok::kw_ ## NAME, \ 200 FLAGS, LangOpts, *this); 201 #define ALIAS(NAME, TOK, FLAGS) \ 202 AddKeyword(StringRef(NAME), tok::kw_ ## TOK, \ 203 FLAGS, LangOpts, *this); 204 #define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \ 205 if (LangOpts.CXXOperatorNames) \ 206 AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this); 207 #define OBJC_AT_KEYWORD(NAME) \ 209 AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this); 210 #define TESTING_KEYWORD(NAME, FLAGS) 211 #include "clang/Basic/TokenKinds.def" 213 if (LangOpts.ParseUnknownAnytype)
214 AddKeyword(
"__unknown_anytype", tok::kw___unknown_anytype, KEYALL,
217 if (LangOpts.DeclSpecKeyword)
218 AddKeyword(
"__declspec", tok::kw___declspec, KEYALL, LangOpts, *
this);
221 get(
"import").setModulesImport(
true);
230 #define KEYWORD(NAME, FLAGS) \ 231 case tok::kw_##NAME: return getKeywordStatus(LangOpts, FLAGS); 232 #include "clang/Basic/TokenKinds.def" 233 default:
return KS_Disabled;
252 if (!LangOpts.CPlusPlus || !isKeyword(LangOpts))
257 LangOptsNoCPP.CPlusPlus =
false;
258 LangOptsNoCPP.CPlusPlus11 =
false;
259 LangOptsNoCPP.CPlusPlus2a =
false;
260 return !isKeyword(LangOptsNoCPP);
269 #define HASH(LEN, FIRST, THIRD) \ 270 (LEN << 5) + (((FIRST-'a') + (THIRD-'a')) & 31) 271 #define CASE(LEN, FIRST, THIRD, NAME) \ 272 case HASH(LEN, FIRST, THIRD): \ 273 return memcmp(Name, #NAME, LEN) ? tok::pp_not_keyword : tok::pp_ ## NAME 275 unsigned Len = getLength();
276 if (Len < 2)
return tok::pp_not_keyword;
277 const char *Name = getNameStart();
278 switch (
HASH(Len, Name[0], Name[2])) {
279 default:
return tok::pp_not_keyword;
280 CASE( 2,
'i',
'\0',
if);
281 CASE( 4,
'e',
'i', elif);
282 CASE( 4,
'e',
's',
else);
283 CASE( 4,
'l',
'n', line);
284 CASE( 4,
's',
'c', sccs);
285 CASE( 5,
'e',
'd', endif);
286 CASE( 5,
'e',
'r', error);
287 CASE( 5,
'i',
'e', ident);
288 CASE( 5,
'i',
'd', ifdef);
289 CASE( 5,
'u',
'd', undef);
291 CASE( 6,
'a',
's', assert);
292 CASE( 6,
'd',
'f', define);
293 CASE( 6,
'i',
'n', ifndef);
294 CASE( 6,
'i',
'p',
import);
295 CASE( 6,
'p',
'a', pragma);
297 CASE( 7,
'd',
'f', defined);
298 CASE( 7,
'i',
'c', include);
299 CASE( 7,
'w',
'r', warning);
301 CASE( 8,
'u',
'a', unassert);
302 CASE(12,
'i',
'c', include_next);
304 CASE(14,
'_',
'p', __public_macro);
306 CASE(15,
'_',
'p', __private_macro);
308 CASE(16,
'_',
'i', __include_macros);
321 unsigned NumBuckets = HashTable.getNumBuckets();
322 unsigned NumIdentifiers = HashTable.getNumItems();
323 unsigned NumEmptyBuckets = NumBuckets-NumIdentifiers;
324 unsigned AverageIdentifierSize = 0;
325 unsigned MaxIdentifierLength = 0;
328 for (llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator>::const_iterator
329 I = HashTable.begin(), E = HashTable.end(); I != E; ++I) {
330 unsigned IdLen = I->getKeyLength();
331 AverageIdentifierSize += IdLen;
332 if (MaxIdentifierLength < IdLen)
333 MaxIdentifierLength = IdLen;
336 fprintf(stderr,
"\n*** Identifier Table Stats:\n");
337 fprintf(stderr,
"# Identifiers: %d\n", NumIdentifiers);
338 fprintf(stderr,
"# Empty Buckets: %d\n", NumEmptyBuckets);
339 fprintf(stderr,
"Hash density (#identifiers per bucket): %f\n",
340 NumIdentifiers/(
double)NumBuckets);
341 fprintf(stderr,
"Ave identifier length: %f\n",
342 (AverageIdentifierSize/(
double)NumIdentifiers));
343 fprintf(stderr,
"Max identifier length: %d\n", MaxIdentifierLength);
346 HashTable.getAllocator().PrintStats();
365 public llvm::FoldingSetNode {
371 : DeclarationNameExtra(nKeys) {
372 assert((nKeys > 1) &&
"not a multi-keyword selector");
376 for (
unsigned i = 0; i != nKeys; ++i)
383 using DeclarationNameExtra::getNumArgs;
392 return keyword_begin() + getNumArgs();
396 assert(i < getNumArgs() &&
"getIdentifierInfoForSlot(): illegal index");
397 return keyword_begin()[i];
402 ID.AddInteger(NumArgs);
403 for (
unsigned i = 0; i != NumArgs; ++i)
404 ID.AddPointer(ArgTys[i]);
408 Profile(ID, keyword_begin(), getNumArgs());
415 unsigned IIF = getIdentifierInfoFlag();
426 if (getIdentifierInfoFlag() < MultiArg) {
427 assert(argIndex == 0 &&
"illegal keyword index");
428 return getAsIdentifierInfo();
438 return II ? II->
getName() : StringRef();
443 llvm::raw_svector_ostream OS(Str);
444 for (
keyword_iterator I = keyword_begin(), E = keyword_end(); I != E; ++I) {
446 OS << (*I)->getName();
455 return "<null selector>";
457 if (getIdentifierInfoFlag() < MultiArg) {
460 if (getNumArgs() == 0) {
461 assert(II &&
"If the number of arguments is 0 then II is guaranteed to " 469 return II->
getName().str() +
":";
473 return getMultiKeywordSelector()->getName();
486 if (name.size() < word.size())
return false;
487 return ((name.size() == word.size() || !
isLowercase(name[word.size()])) &&
488 name.startswith(word));
495 StringRef name = first->
getName();
503 if (name ==
"self")
return OMF_self;
507 if (name ==
"performSelector" || name ==
"performSelectorInBackground" ||
508 name ==
"performSelectorOnMainThread")
512 while (!name.empty() && name.front() ==
'_')
513 name = name.substr(1);
516 switch (name.front()) {
543 StringRef name = first->
getName();
546 switch (name.front()) {
571 StringRef name = first->
getName();
573 switch (name.front()) {
583 if (name ==
"localizedStringWithFormat")
return SFF_NSString;
587 if (name ==
"stringByAppendingFormat" ||
596 struct SelectorTableImpl {
597 llvm::FoldingSet<MultiKeywordSelector> Table;
598 llvm::BumpPtrAllocator Allocator;
604 return *
static_cast<SelectorTableImpl*
>(
P);
620 &Idents.
get(constructSetterName(Name->
getName()));
626 assert(Name.startswith(
"set") &&
"invalid setter name");
632 return SelTabImpl.Allocator.getTotalMemory();
642 llvm::FoldingSetNodeID
ID;
645 void *InsertPos =
nullptr;
647 SelTabImpl.Table.FindNodeOrInsertPos(ID, InsertPos))
657 SelTabImpl.Table.InsertNode(SI, InsertPos);
662 Impl =
new SelectorTableImpl();
675 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 676 case OO_##Name: return Spelling; 677 #include "clang/Basic/OperatorKinds.def" 680 llvm_unreachable(
"Invalid OverloadedOperatorKind!");
684 bool isContextSensitive) {
687 return isContextSensitive ?
"nonnull" :
"_Nonnull";
690 return isContextSensitive ?
"nullable" :
"_Nullable";
693 return isContextSensitive ?
"null_unspecified" :
"_Null_unspecified";
695 llvm_unreachable(
"Unknown nullability kind.");
void AddKeywords(const LangOptions &LangOpts)
Populate the identifier table with info about the language keywords for the language specified by Lan...
Smart pointer class that efficiently represents Objective-C method names.
void * getAsOpaquePtr() const
bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const
void PrintStats() const
Print some statistics to stderr that indicate how well the hashing is doing.
NullabilityKind
Describes the nullability of a particular type.
void setIsExtensionToken(bool Val)
static SelectorTableImpl & getSelectorTableImpl(void *P)
virtual IdentifierIterator * getIdentifiers()
Retrieve an iterator into the set of all identifiers known to this identifier lookup source...
KeywordStatus
How a keyword is treated in the selected standard.
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...
IdentifierInfo * getIdentifierInfoForSlot(unsigned i) const
std::string getName(ArrayRef< StringRef > Parts) const
Get the platform-specific name separator.
Selector getUnarySelector(IdentifierInfo *ID)
One of these records is kept for each identifier that is lexed.
static ObjCInstanceTypeFamily getInstTypeMethodFamily(Selector sel)
This table allows us to fully hide how we implement multi-keyword caching.
ObjCMethodFamily
A family of Objective-C methods.
IdentifierInfo *const * keyword_iterator
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
static KeywordStatus getTokenKwStatus(const LangOptions &LangOpts, tok::TokenKind K)
Checks if the specified token kind represents a keyword in the specified language.
IdentifierTable(IdentifierInfoLookup *ExternalLookup=nullptr)
Create the identifier table.
Values of this type can be null.
bool isUnarySelector() const
void setIsFutureCompatKeyword(bool Val)
static SmallString< 64 > constructSetterName(StringRef Name)
Return the default setter name for the given identifier.
static Selector constructSetterSelector(IdentifierTable &Idents, SelectorTable &SelTable, const IdentifierInfo *Name)
Return the default setter selector for the given identifier.
void Profile(llvm::FoldingSetNodeID &ID)
Whether values of this type can be null is (explicitly) unspecified.
Values of this type can never be null.
static void AddCXXOperatorKeyword(StringRef Keyword, tok::TokenKind TokenCode, IdentifierTable &Table)
AddCXXOperatorKeyword - Register a C++ operator keyword alternative representations.
size_t getTotalMemory() const
Return the total amount of memory allocated for managing selectors.
bool isCPlusPlusKeyword(const LangOptions &LangOpts) const
Return true if this token is a C++ keyword in the specified language.
Provides lookups to, and iteration over, IdentiferInfo objects.
void setIsCPlusPlusOperatorKeyword(bool Val=true)
isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether this identifier is a C++ al...
One of these variable length records is kept for each selector containing more than one keyword...
Defines the clang::LangOptions interface.
llvm::StringRef getAsString(SyncScope S)
Implements an efficient mapping from strings to IdentifierInfo nodes.
Defines an enumeration for C++ overloaded operators.
PPKeywordKind
Provides a namespace for preprocessor keywords which start with a '#' at the beginning of the line...
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
#define CASE(LEN, FIRST, THIRD, NAME)
ObjCInstanceTypeFamily
A family of Objective-C methods.
static KeywordStatus getKeywordStatus(const LangOptions &LangOpts, unsigned Flags)
Translates flags as specified in TokenKinds.def into keyword status in the given language standard...
An iterator that walks over all of the known identifiers in the lookup table.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
void print(llvm::raw_ostream &OS) const
Prints the full selector name (e.g. "foo:bar:").
unsigned getNumArgs() const
ObjCKeywordKind
Provides a namespace for Objective-C keywords which start with an '@'.
void setObjCKeywordID(tok::ObjCKeywordKind ID)
bool isKeyword(const LangOptions &LangOpts) const
Return true if this token is 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...
static void Profile(llvm::FoldingSetNodeID &ID, keyword_iterator ArgTys, unsigned NumArgs)
std::string getAsString() const
Derive the full selector name (e.g.
std::string getName() const
LLVM_READONLY char toLowercase(char c)
Converts the given ASCII character to its lowercase equivalent.
IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
virtual ~IdentifierIterator()
keyword_iterator keyword_begin() const
static void AddObjCKeyword(StringRef Name, tok::ObjCKeywordKind ObjCID, IdentifierTable &Table)
AddObjCKeyword - Register an Objective-C @keyword like "class" "selector" or "property".
LLVM_READONLY bool isLowercase(unsigned char c)
Return true if this character is a lowercase ASCII letter: [a-z].
Defines various enumerations that describe declaration and type specifiers.
StringRef getName() const
Return the actual identifier string.
virtual ~IdentifierInfoLookup()
Dataflow Directional Tag Classes.
static std::string getPropertyNameFromSetterSelector(Selector Sel)
Return the property name for the given setter selector.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
Not an overloaded operator.
MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV)
Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV)
Can create any sort of selector.
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword...
#define HASH(LEN, FIRST, THIRD)
Defines the clang::TokenKind enum and support functions.
No particular method family.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
keyword_iterator keyword_end() const
LLVM_READONLY char toUppercase(char c)
Converts the given ASCII character to its uppercase equivalent.
llvm::StringRef getNullabilitySpelling(NullabilityKind kind, bool isContextSensitive=false)
Retrieve the spelling of the given nullability kind.