20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/FoldingSet.h"
22 #include "llvm/ADT/SmallString.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/raw_ostream.h"
27 using namespace clang;
34 TokenID = tok::identifier;
39 IsFutureCompatKeyword =
false;
41 IsCPPOperatorKeyword =
false;
42 NeedsHandleIdentifier =
false;
44 ChangedAfterLoad =
false;
45 FEChangedAfterLoad =
false;
46 RevertedTokenID =
false;
48 IsModulesImport =
false;
49 FETokenInfo =
nullptr;
67 StringRef
Next()
override {
return StringRef(); }
72 return new EmptyLookupIterator();
78 ExternalLookup(externalLookup) {
86 get(
"import").setModulesImport(
true);
109 KEYNOOPENCL = 0x02000,
110 WCHARSUPPORT = 0x04000,
111 HALFSUPPORT = 0x08000,
112 KEYCONCEPTS = 0x10000,
114 KEYZVECTOR = 0x40000,
115 KEYCOROUTINES = 0x80000,
116 KEYMODULES = 0x100000,
117 KEYALL = (0x1fffff & ~KEYNOMS18 &
134 if (Flags == KEYALL)
return KS_Enabled;
135 if (LangOpts.CPlusPlus && (Flags & KEYCXX))
return KS_Enabled;
136 if (LangOpts.CPlusPlus11 && (Flags & KEYCXX11))
return KS_Enabled;
137 if (LangOpts.C99 && (Flags & KEYC99))
return KS_Enabled;
138 if (LangOpts.GNUKeywords && (Flags & KEYGNU))
return KS_Extension;
139 if (LangOpts.MicrosoftExt && (Flags & KEYMS))
return KS_Extension;
140 if (LangOpts.Borland && (Flags & KEYBORLAND))
return KS_Extension;
141 if (LangOpts.Bool && (Flags & BOOLSUPPORT))
return KS_Enabled;
142 if (LangOpts.Half && (Flags & HALFSUPPORT))
return KS_Enabled;
143 if (LangOpts.WChar && (Flags & WCHARSUPPORT))
return KS_Enabled;
144 if (LangOpts.AltiVec && (Flags & KEYALTIVEC))
return KS_Enabled;
145 if (LangOpts.OpenCL && (Flags & KEYOPENCL))
return KS_Enabled;
146 if (!LangOpts.CPlusPlus && (Flags & KEYNOCXX))
return KS_Enabled;
147 if (LangOpts.C11 && (Flags & KEYC11))
return KS_Enabled;
150 if (LangOpts.ObjC2 && (Flags & KEYARC))
return KS_Enabled;
151 if (LangOpts.ObjC2 && (Flags & KEYOBJC2))
return KS_Enabled;
152 if (LangOpts.ConceptsTS && (Flags & KEYCONCEPTS))
return KS_Enabled;
153 if (LangOpts.CoroutinesTS && (Flags & KEYCOROUTINES))
return KS_Enabled;
154 if (LangOpts.ModulesTS && (Flags & KEYMODULES))
return KS_Enabled;
155 if (LangOpts.CPlusPlus && (Flags & KEYCXX11))
return KS_Future;
168 if (LangOpts.MSVCCompat && (Flags & KEYNOMS18) &&
173 if (LangOpts.OpenCL && (Flags & KEYNOOPENCL))
177 if (AddResult == KS_Disabled)
return;
180 Table.
get(Keyword, AddResult == KS_Future ? tok::identifier : TokenCode);
206 #define KEYWORD(NAME, FLAGS) \
207 AddKeyword(StringRef(#NAME), tok::kw_ ## NAME, \
208 FLAGS, LangOpts, *this);
209 #define ALIAS(NAME, TOK, FLAGS) \
210 AddKeyword(StringRef(NAME), tok::kw_ ## TOK, \
211 FLAGS, LangOpts, *this);
212 #define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \
213 if (LangOpts.CXXOperatorNames) \
214 AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this);
215 #define OBJC1_AT_KEYWORD(NAME) \
216 if (LangOpts.ObjC1) \
217 AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
218 #define OBJC2_AT_KEYWORD(NAME) \
219 if (LangOpts.ObjC2) \
220 AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
221 #define TESTING_KEYWORD(NAME, FLAGS)
222 #include "clang/Basic/TokenKinds.def"
224 if (LangOpts.ParseUnknownAnytype)
225 AddKeyword(
"__unknown_anytype", tok::kw___unknown_anytype, KEYALL,
228 if (LangOpts.DeclSpecKeyword)
229 AddKeyword(
"__declspec", tok::kw___declspec, KEYALL, LangOpts, *
this);
238 #define KEYWORD(NAME, FLAGS) \
239 case tok::kw_##NAME: return getKeywordStatus(LangOpts, FLAGS);
240 #include "clang/Basic/TokenKinds.def"
241 default:
return KS_Disabled;
260 if (!LangOpts.CPlusPlus || !
isKeyword(LangOpts))
265 LangOptsNoCPP.CPlusPlus =
false;
266 LangOptsNoCPP.CPlusPlus11 =
false;
276 #define HASH(LEN, FIRST, THIRD) \
277 (LEN << 5) + (((FIRST-'a') + (THIRD-'a')) & 31)
278 #define CASE(LEN, FIRST, THIRD, NAME) \
279 case HASH(LEN, FIRST, THIRD): \
280 return memcmp(Name, #NAME, LEN) ? tok::pp_not_keyword : tok::pp_ ## NAME
283 if (Len < 2)
return tok::pp_not_keyword;
285 switch (
HASH(Len, Name[0], Name[2])) {
286 default:
return tok::pp_not_keyword;
287 CASE( 2,
'i',
'\0',
if);
288 CASE( 4,
'e',
'i', elif);
289 CASE( 4,
'e',
's',
else);
290 CASE( 4,
'l',
'n', line);
291 CASE( 4,
's',
'c', sccs);
292 CASE( 5,
'e',
'd', endif);
293 CASE( 5,
'e',
'r', error);
294 CASE( 5,
'i',
'e', ident);
295 CASE( 5,
'i',
'd', ifdef);
296 CASE( 5,
'u',
'd', undef);
298 CASE( 6,
'a',
's', assert);
299 CASE( 6,
'd',
'f', define);
300 CASE( 6,
'i',
'n', ifndef);
301 CASE( 6,
'i',
'p',
import);
302 CASE( 6,
'p',
'a', pragma);
304 CASE( 7,
'd',
'f', defined);
305 CASE( 7,
'i',
'c', include);
306 CASE( 7,
'w',
'r', warning);
308 CASE( 8,
'u',
'a', unassert);
309 CASE(12,
'i',
'c', include_next);
311 CASE(14,
'_',
'p', __public_macro);
313 CASE(15,
'_',
'p', __private_macro);
315 CASE(16,
'_',
'i', __include_macros);
328 unsigned NumBuckets = HashTable.getNumBuckets();
329 unsigned NumIdentifiers = HashTable.getNumItems();
330 unsigned NumEmptyBuckets = NumBuckets-NumIdentifiers;
331 unsigned AverageIdentifierSize = 0;
332 unsigned MaxIdentifierLength = 0;
335 for (llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator>::const_iterator
336 I = HashTable.begin(),
E = HashTable.end();
I !=
E; ++
I) {
337 unsigned IdLen =
I->getKeyLength();
338 AverageIdentifierSize += IdLen;
339 if (MaxIdentifierLength < IdLen)
340 MaxIdentifierLength = IdLen;
343 fprintf(stderr,
"\n*** Identifier Table Stats:\n");
344 fprintf(stderr,
"# Identifiers: %d\n", NumIdentifiers);
345 fprintf(stderr,
"# Empty Buckets: %d\n", NumEmptyBuckets);
346 fprintf(stderr,
"Hash density (#identifiers per bucket): %f\n",
347 NumIdentifiers/(
double)NumBuckets);
348 fprintf(stderr,
"Ave identifier length: %f\n",
349 (AverageIdentifierSize/(
double)NumIdentifiers));
350 fprintf(stderr,
"Max identifier length: %d\n", MaxIdentifierLength);
353 HashTable.getAllocator().PrintStats();
377 assert((nKeys > 1) &&
"not a multi-keyword selector");
382 for (
unsigned i = 0; i != nKeys; ++i)
399 assert(i <
getNumArgs() &&
"getIdentifierInfoForSlot(): illegal index");
404 ID.AddInteger(NumArgs);
405 for (
unsigned i = 0; i != NumArgs; ++i)
406 ID.AddPointer(ArgTys[i]);
415 unsigned IIF = getIdentifierInfoFlag();
426 if (getIdentifierInfoFlag() < MultiArg) {
427 assert(argIndex == 0 &&
"illegal keyword index");
428 return getAsIdentifierInfo();
437 return II? II->
getName() : StringRef();
442 llvm::raw_svector_ostream OS(Str);
445 OS << (*I)->getName();
454 return "<null selector>";
456 if (getIdentifierInfoFlag() < MultiArg) {
460 assert(II &&
"If the number of arguments is 0 then II is guaranteed to "
468 return II->
getName().str() +
":";
472 return getMultiKeywordSelector()->
getName();
483 if (name.size() < word.size())
return false;
484 return ((name.size() == word.size() || !
isLowercase(name[word.size()])) &&
485 name.startswith(word));
492 StringRef name = first->
getName();
500 if (name ==
"self")
return OMF_self;
504 if (name ==
"performSelector" || name ==
"performSelectorInBackground" ||
505 name ==
"performSelectorOnMainThread")
509 while (!name.empty() && name.front() ==
'_')
510 name = name.substr(1);
513 switch (name.front()) {
540 StringRef name = first->
getName();
543 switch (name.front()) {
567 StringRef name = first->
getName();
569 switch (name.front()) {
579 if (name ==
"localizedStringWithFormat")
return SFF_NSString;
583 if (name ==
"stringByAppendingFormat" ||
591 struct SelectorTableImpl {
592 llvm::FoldingSet<MultiKeywordSelector> Table;
598 return *
static_cast<SelectorTableImpl*
>(
P);
620 return SelTabImpl.Allocator.getTotalMemory();
630 llvm::FoldingSetNodeID
ID;
633 void *InsertPos =
nullptr;
635 SelTabImpl.Table.FindNodeOrInsertPos(ID, InsertPos))
645 SelTabImpl.Table.InsertNode(SI, InsertPos);
650 Impl =
new SelectorTableImpl();
663 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
664 case OO_##Name: return Spelling;
665 #include "clang/Basic/OperatorKinds.def"
668 llvm_unreachable(
"Invalid OverloadedOperatorKind!");
672 bool isContextSensitive) {
675 return isContextSensitive ?
"nonnull" :
"_Nonnull";
678 return isContextSensitive ?
"nullable" :
"_Nullable";
681 return isContextSensitive ?
"null_unspecified" :
"_Null_unspecified";
683 llvm_unreachable(
"Unknown nullability kind.");
void AddKeywords(const LangOptions &LangOpts)
AddKeywords - Add all keywords to the symbol table.
Smart pointer class that efficiently represents Objective-C method names.
IdentifierInfo *const * keyword_iterator
NullabilityKind
Describes the nullability of a particular type.
void setIsExtensionToken(bool Val)
size_t getTotalMemory() const
Return the total amount of memory allocated for managing selectors.
unsigned getLength() const
Efficiently return the length of this identifier info.
static SelectorTableImpl & getSelectorTableImpl(void *P)
void * getAsOpaquePtr() const
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...
keyword_iterator keyword_end() const
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.
IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
ObjCMethodFamily
A family of Objective-C methods.
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.
Values of this type can be null.
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.
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
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.
void print(llvm::raw_ostream &OS) const
Prints the full selector name (e.g. "foo:bar:").
detail::InMemoryDirectory::const_iterator I
Provides lookups to, and iteration over, IdentiferInfo objects.
void setIsCPlusPlusOperatorKeyword(bool Val=true)
isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether this identifier is a C++ al...
bool isUnarySelector() const
MultiKeywordSelector - One of these variable length records is kept for each selector containing more...
Defines the clang::LangOptions interface.
std::string getName() const
StringRef getName() const
Return the actual identifier string.
unsigned getNumArgs() const
Implements an efficient mapping from strings to IdentifierInfo nodes.
bool isKeyword(const LangOptions &LangOpts) const
Return true if this token is a keyword in the specified language.
Defines an enumeration for C++ overloaded operators.
PPKeywordKind
Provides a namespace for preprocessor keywords which start with a '#' at the beginning of the line...
#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.
ObjCKeywordKind
Provides a namespace for Objective-C keywords which start with an '@'.
void setObjCKeywordID(tok::ObjCKeywordKind ID)
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)
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
IdentifierTable(const LangOptions &LangOpts, IdentifierInfoLookup *externalLookup=nullptr)
Create the identifier table, populating it with info about the language keywords for the language spe...
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
virtual ~IdentifierIterator()
std::string getAsString() const
Derive the full selector name (e.g.
static void AddObjCKeyword(StringRef Name, tok::ObjCKeywordKind ObjCID, IdentifierTable &Table)
AddObjCKeyword - Register an Objective-C @keyword like "class" "selector" or "property".
Defines various enumerations that describe declaration and type specifiers.
virtual ~IdentifierInfoLookup()
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
unsigned getNumArgs() const
keyword_iterator keyword_begin() const
detail::InMemoryDirectory::const_iterator E
static LLVM_READONLY bool isLowercase(unsigned char c)
Return true if this character is a lowercase ASCII letter: [a-z].
Not an overloaded operator.
MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV)
bool isCPlusPlusKeyword(const LangOptions &LangOpts) const
Return true if this token is a C++ keyword in the specified language.
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)
void PrintStats() const
Print some statistics to stderr that indicate how well the hashing is doing.
bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const
No particular method family.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
static 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.
IdentifierInfo * getIdentifierInfoForSlot(unsigned i) const
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.