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 RevertedTokenID =
false;
47 IsModulesImport =
false;
48 FETokenInfo =
nullptr;
66 StringRef
Next()
override {
return StringRef(); }
71 return new EmptyLookupIterator();
77 ExternalLookup(externalLookup) {
85 get(
"import").setModulesImport(
true);
108 KEYNOOPENCL = 0x02000,
109 WCHARSUPPORT = 0x04000,
110 HALFSUPPORT = 0x08000,
111 KEYCONCEPTS = 0x10000,
113 KEYZVECTOR = 0x40000,
114 KEYCOROUTINES = 0x80000,
115 KEYALL = (0xfffff & ~KEYNOMS18 &
132 if (Flags == KEYALL)
return KS_Enabled;
133 if (LangOpts.CPlusPlus && (Flags & KEYCXX))
return KS_Enabled;
134 if (LangOpts.CPlusPlus11 && (Flags & KEYCXX11))
return KS_Enabled;
135 if (LangOpts.C99 && (Flags & KEYC99))
return KS_Enabled;
136 if (LangOpts.GNUKeywords && (Flags & KEYGNU))
return KS_Extension;
137 if (LangOpts.MicrosoftExt && (Flags & KEYMS))
return KS_Extension;
138 if (LangOpts.Borland && (Flags & KEYBORLAND))
return KS_Extension;
139 if (LangOpts.Bool && (Flags & BOOLSUPPORT))
return KS_Enabled;
140 if (LangOpts.Half && (Flags & HALFSUPPORT))
return KS_Enabled;
141 if (LangOpts.WChar && (Flags & WCHARSUPPORT))
return KS_Enabled;
142 if (LangOpts.AltiVec && (Flags & KEYALTIVEC))
return KS_Enabled;
143 if (LangOpts.OpenCL && (Flags & KEYOPENCL))
return KS_Enabled;
144 if (!LangOpts.CPlusPlus && (Flags & KEYNOCXX))
return KS_Enabled;
145 if (LangOpts.C11 && (Flags & KEYC11))
return KS_Enabled;
148 if (LangOpts.ObjC2 && (Flags & KEYARC))
return KS_Enabled;
149 if (LangOpts.ConceptsTS && (Flags & KEYCONCEPTS))
return KS_Enabled;
150 if (LangOpts.ObjC2 && (Flags & KEYOBJC2))
return KS_Enabled;
151 if (LangOpts.Coroutines && (Flags & KEYCOROUTINES))
return KS_Enabled;
152 if (LangOpts.CPlusPlus && (Flags & KEYCXX11))
return KS_Future;
165 if (LangOpts.MSVCCompat && (Flags & KEYNOMS18) &&
170 if (LangOpts.OpenCL && (Flags & KEYNOOPENCL))
174 if (AddResult == KS_Disabled)
return;
177 Table.
get(Keyword, AddResult == KS_Future ? tok::identifier : TokenCode);
203 #define KEYWORD(NAME, FLAGS) \
204 AddKeyword(StringRef(#NAME), tok::kw_ ## NAME, \
205 FLAGS, LangOpts, *this);
206 #define ALIAS(NAME, TOK, FLAGS) \
207 AddKeyword(StringRef(NAME), tok::kw_ ## TOK, \
208 FLAGS, LangOpts, *this);
209 #define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \
210 if (LangOpts.CXXOperatorNames) \
211 AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this);
212 #define OBJC1_AT_KEYWORD(NAME) \
213 if (LangOpts.ObjC1) \
214 AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
215 #define OBJC2_AT_KEYWORD(NAME) \
216 if (LangOpts.ObjC2) \
217 AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
218 #define TESTING_KEYWORD(NAME, FLAGS)
219 #include "clang/Basic/TokenKinds.def"
221 if (LangOpts.ParseUnknownAnytype)
222 AddKeyword(
"__unknown_anytype", tok::kw___unknown_anytype, KEYALL,
225 if (LangOpts.DeclSpecKeyword)
226 AddKeyword(
"__declspec", tok::kw___declspec, KEYALL, LangOpts, *
this);
235 #define KEYWORD(NAME, FLAGS) \
236 case tok::kw_##NAME: return getKeywordStatus(LangOpts, FLAGS);
237 #include "clang/Basic/TokenKinds.def"
238 default:
return KS_Disabled;
260 #define HASH(LEN, FIRST, THIRD) \
261 (LEN << 5) + (((FIRST-'a') + (THIRD-'a')) & 31)
262 #define CASE(LEN, FIRST, THIRD, NAME) \
263 case HASH(LEN, FIRST, THIRD): \
264 return memcmp(Name, #NAME, LEN) ? tok::pp_not_keyword : tok::pp_ ## NAME
267 if (Len < 2)
return tok::pp_not_keyword;
269 switch (
HASH(Len, Name[0], Name[2])) {
270 default:
return tok::pp_not_keyword;
271 CASE( 2,
'i',
'\0',
if);
272 CASE( 4,
'e',
'i', elif);
273 CASE( 4,
'e',
's',
else);
274 CASE( 4,
'l',
'n', line);
275 CASE( 4,
's',
'c', sccs);
276 CASE( 5,
'e',
'd', endif);
277 CASE( 5,
'e',
'r', error);
278 CASE( 5,
'i',
'e', ident);
279 CASE( 5,
'i',
'd', ifdef);
280 CASE( 5,
'u',
'd', undef);
282 CASE( 6,
'a',
's', assert);
283 CASE( 6,
'd',
'f', define);
284 CASE( 6,
'i',
'n', ifndef);
285 CASE( 6,
'i',
'p',
import);
286 CASE( 6,
'p',
'a', pragma);
288 CASE( 7,
'd',
'f', defined);
289 CASE( 7,
'i',
'c', include);
290 CASE( 7,
'w',
'r', warning);
292 CASE( 8,
'u',
'a', unassert);
293 CASE(12,
'i',
'c', include_next);
295 CASE(14,
'_',
'p', __public_macro);
297 CASE(15,
'_',
'p', __private_macro);
299 CASE(16,
'_',
'i', __include_macros);
312 unsigned NumBuckets = HashTable.getNumBuckets();
313 unsigned NumIdentifiers = HashTable.getNumItems();
314 unsigned NumEmptyBuckets = NumBuckets-NumIdentifiers;
315 unsigned AverageIdentifierSize = 0;
316 unsigned MaxIdentifierLength = 0;
319 for (llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator>::const_iterator
320 I = HashTable.begin(),
E = HashTable.end();
I !=
E; ++
I) {
321 unsigned IdLen =
I->getKeyLength();
322 AverageIdentifierSize += IdLen;
323 if (MaxIdentifierLength < IdLen)
324 MaxIdentifierLength = IdLen;
327 fprintf(stderr,
"\n*** Identifier Table Stats:\n");
328 fprintf(stderr,
"# Identifiers: %d\n", NumIdentifiers);
329 fprintf(stderr,
"# Empty Buckets: %d\n", NumEmptyBuckets);
330 fprintf(stderr,
"Hash density (#identifiers per bucket): %f\n",
331 NumIdentifiers/(
double)NumBuckets);
332 fprintf(stderr,
"Ave identifier length: %f\n",
333 (AverageIdentifierSize/(
double)NumIdentifiers));
334 fprintf(stderr,
"Max identifier length: %d\n", MaxIdentifierLength);
337 HashTable.getAllocator().PrintStats();
361 assert((nKeys > 1) &&
"not a multi-keyword selector");
366 for (
unsigned i = 0; i != nKeys; ++i)
383 assert(i <
getNumArgs() &&
"getIdentifierInfoForSlot(): illegal index");
388 ID.AddInteger(NumArgs);
389 for (
unsigned i = 0; i !=
NumArgs; ++i)
390 ID.AddPointer(ArgTys[i]);
399 unsigned IIF = getIdentifierInfoFlag();
410 if (getIdentifierInfoFlag() < MultiArg) {
411 assert(argIndex == 0 &&
"illegal keyword index");
412 return getAsIdentifierInfo();
421 return II? II->
getName() : StringRef();
426 llvm::raw_svector_ostream OS(Str);
429 OS << (*I)->getName();
438 return "<null selector>";
440 if (getIdentifierInfoFlag() < MultiArg) {
450 return II->
getName().str() +
":";
454 return getMultiKeywordSelector()->
getName();
465 if (name.size() < word.size())
return false;
466 return ((name.size() == word.size() || !
isLowercase(name[word.size()])) &&
467 name.startswith(word));
474 StringRef name = first->
getName();
482 if (name ==
"self")
return OMF_self;
489 while (!name.empty() && name.front() ==
'_')
490 name = name.substr(1);
493 switch (name.front()) {
520 StringRef name = first->
getName();
523 switch (name.front()) {
546 StringRef name = first->
getName();
548 switch (name.front()) {
558 if (name ==
"localizedStringWithFormat")
return SFF_NSString;
562 if (name ==
"stringByAppendingFormat" ||
570 struct SelectorTableImpl {
571 llvm::FoldingSet<MultiKeywordSelector> Table;
577 return *
static_cast<SelectorTableImpl*
>(
P);
599 return SelTabImpl.Allocator.getTotalMemory();
609 llvm::FoldingSetNodeID
ID;
612 void *InsertPos =
nullptr;
614 SelTabImpl.Table.FindNodeOrInsertPos(ID, InsertPos))
622 llvm::alignOf<MultiKeywordSelector>());
624 SelTabImpl.Table.InsertNode(SI, InsertPos);
629 Impl =
new SelectorTableImpl();
642 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
643 case OO_##Name: return Spelling;
644 #include "clang/Basic/OperatorKinds.def"
647 llvm_unreachable(
"Invalid OverloadedOperatorKind!");
651 bool isContextSensitive) {
654 return isContextSensitive ?
"nonnull" :
"_Nonnull";
657 return isContextSensitive ?
"nullable" :
"_Nullable";
660 return isContextSensitive ?
"null_unspecified" :
"_Null_unspecified";
662 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.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
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...
ID
Defines the set of possible language-specific address spaces.
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.
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.
class LLVM_ALIGNAS(8) TemplateSpecializationType unsigned NumArgs
Represents a type template specialization; the template must be a class template, a type alias templa...
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.
bool isKeyword(const LangOptions &LangOpts)
Return true if this token is a keyword in the specified language.
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)
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.