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 KEYALL = (0xfffff & ~KEYNOMS18 &
133 if (Flags == KEYALL)
return KS_Enabled;
134 if (LangOpts.CPlusPlus && (Flags & KEYCXX))
return KS_Enabled;
135 if (LangOpts.CPlusPlus11 && (Flags & KEYCXX11))
return KS_Enabled;
136 if (LangOpts.C99 && (Flags & KEYC99))
return KS_Enabled;
137 if (LangOpts.GNUKeywords && (Flags & KEYGNU))
return KS_Extension;
138 if (LangOpts.MicrosoftExt && (Flags & KEYMS))
return KS_Extension;
139 if (LangOpts.Borland && (Flags & KEYBORLAND))
return KS_Extension;
140 if (LangOpts.Bool && (Flags & BOOLSUPPORT))
return KS_Enabled;
141 if (LangOpts.Half && (Flags & HALFSUPPORT))
return KS_Enabled;
142 if (LangOpts.WChar && (Flags & WCHARSUPPORT))
return KS_Enabled;
143 if (LangOpts.AltiVec && (Flags & KEYALTIVEC))
return KS_Enabled;
144 if (LangOpts.OpenCL && (Flags & KEYOPENCL))
return KS_Enabled;
145 if (!LangOpts.CPlusPlus && (Flags & KEYNOCXX))
return KS_Enabled;
146 if (LangOpts.C11 && (Flags & KEYC11))
return KS_Enabled;
149 if (LangOpts.ObjC2 && (Flags & KEYARC))
return KS_Enabled;
150 if (LangOpts.ConceptsTS && (Flags & KEYCONCEPTS))
return KS_Enabled;
151 if (LangOpts.ObjC2 && (Flags & KEYOBJC2))
return KS_Enabled;
152 if (LangOpts.Coroutines && (Flags & KEYCOROUTINES))
return KS_Enabled;
153 if (LangOpts.CPlusPlus && (Flags & KEYCXX11))
return KS_Future;
166 if (LangOpts.MSVCCompat && (Flags & KEYNOMS18) &&
171 if (LangOpts.OpenCL && (Flags & KEYNOOPENCL))
175 if (AddResult == KS_Disabled)
return;
178 Table.
get(Keyword, AddResult == KS_Future ? tok::identifier : TokenCode);
204 #define KEYWORD(NAME, FLAGS) \
205 AddKeyword(StringRef(#NAME), tok::kw_ ## NAME, \
206 FLAGS, LangOpts, *this);
207 #define ALIAS(NAME, TOK, FLAGS) \
208 AddKeyword(StringRef(NAME), tok::kw_ ## TOK, \
209 FLAGS, LangOpts, *this);
210 #define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \
211 if (LangOpts.CXXOperatorNames) \
212 AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this);
213 #define OBJC1_AT_KEYWORD(NAME) \
214 if (LangOpts.ObjC1) \
215 AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
216 #define OBJC2_AT_KEYWORD(NAME) \
217 if (LangOpts.ObjC2) \
218 AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
219 #define TESTING_KEYWORD(NAME, FLAGS)
220 #include "clang/Basic/TokenKinds.def"
222 if (LangOpts.ParseUnknownAnytype)
223 AddKeyword(
"__unknown_anytype", tok::kw___unknown_anytype, KEYALL,
226 if (LangOpts.DeclSpecKeyword)
227 AddKeyword(
"__declspec", tok::kw___declspec, KEYALL, LangOpts, *
this);
236 #define KEYWORD(NAME, FLAGS) \
237 case tok::kw_##NAME: return getKeywordStatus(LangOpts, FLAGS);
238 #include "clang/Basic/TokenKinds.def"
239 default:
return KS_Disabled;
261 #define HASH(LEN, FIRST, THIRD) \
262 (LEN << 5) + (((FIRST-'a') + (THIRD-'a')) & 31)
263 #define CASE(LEN, FIRST, THIRD, NAME) \
264 case HASH(LEN, FIRST, THIRD): \
265 return memcmp(Name, #NAME, LEN) ? tok::pp_not_keyword : tok::pp_ ## NAME
268 if (Len < 2)
return tok::pp_not_keyword;
270 switch (
HASH(Len, Name[0], Name[2])) {
271 default:
return tok::pp_not_keyword;
272 CASE( 2,
'i',
'\0',
if);
273 CASE( 4,
'e',
'i', elif);
274 CASE( 4,
'e',
's',
else);
275 CASE( 4,
'l',
'n', line);
276 CASE( 4,
's',
'c', sccs);
277 CASE( 5,
'e',
'd', endif);
278 CASE( 5,
'e',
'r', error);
279 CASE( 5,
'i',
'e', ident);
280 CASE( 5,
'i',
'd', ifdef);
281 CASE( 5,
'u',
'd', undef);
283 CASE( 6,
'a',
's', assert);
284 CASE( 6,
'd',
'f', define);
285 CASE( 6,
'i',
'n', ifndef);
286 CASE( 6,
'i',
'p',
import);
287 CASE( 6,
'p',
'a', pragma);
289 CASE( 7,
'd',
'f', defined);
290 CASE( 7,
'i',
'c', include);
291 CASE( 7,
'w',
'r', warning);
293 CASE( 8,
'u',
'a', unassert);
294 CASE(12,
'i',
'c', include_next);
296 CASE(14,
'_',
'p', __public_macro);
298 CASE(15,
'_',
'p', __private_macro);
300 CASE(16,
'_',
'i', __include_macros);
313 unsigned NumBuckets = HashTable.getNumBuckets();
314 unsigned NumIdentifiers = HashTable.getNumItems();
315 unsigned NumEmptyBuckets = NumBuckets-NumIdentifiers;
316 unsigned AverageIdentifierSize = 0;
317 unsigned MaxIdentifierLength = 0;
320 for (llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator>::const_iterator
321 I = HashTable.begin(),
E = HashTable.end();
I !=
E; ++
I) {
322 unsigned IdLen =
I->getKeyLength();
323 AverageIdentifierSize += IdLen;
324 if (MaxIdentifierLength < IdLen)
325 MaxIdentifierLength = IdLen;
328 fprintf(stderr,
"\n*** Identifier Table Stats:\n");
329 fprintf(stderr,
"# Identifiers: %d\n", NumIdentifiers);
330 fprintf(stderr,
"# Empty Buckets: %d\n", NumEmptyBuckets);
331 fprintf(stderr,
"Hash density (#identifiers per bucket): %f\n",
332 NumIdentifiers/(
double)NumBuckets);
333 fprintf(stderr,
"Ave identifier length: %f\n",
334 (AverageIdentifierSize/(
double)NumIdentifiers));
335 fprintf(stderr,
"Max identifier length: %d\n", MaxIdentifierLength);
338 HashTable.getAllocator().PrintStats();
362 assert((nKeys > 1) &&
"not a multi-keyword selector");
367 for (
unsigned i = 0; i != nKeys; ++i)
384 assert(i <
getNumArgs() &&
"getIdentifierInfoForSlot(): illegal index");
389 ID.AddInteger(NumArgs);
390 for (
unsigned i = 0; i !=
NumArgs; ++i)
391 ID.AddPointer(ArgTys[i]);
400 unsigned IIF = getIdentifierInfoFlag();
411 if (getIdentifierInfoFlag() < MultiArg) {
412 assert(argIndex == 0 &&
"illegal keyword index");
413 return getAsIdentifierInfo();
422 return II? II->
getName() : StringRef();
427 llvm::raw_svector_ostream OS(Str);
430 OS << (*I)->getName();
439 return "<null selector>";
441 if (getIdentifierInfoFlag() < MultiArg) {
451 return II->
getName().str() +
":";
455 return getMultiKeywordSelector()->
getName();
466 if (name.size() < word.size())
return false;
467 return ((name.size() == word.size() || !
isLowercase(name[word.size()])) &&
468 name.startswith(word));
475 StringRef name = first->
getName();
483 if (name ==
"self")
return OMF_self;
490 while (!name.empty() && name.front() ==
'_')
491 name = name.substr(1);
494 switch (name.front()) {
521 StringRef name = first->
getName();
524 switch (name.front()) {
547 StringRef name = first->
getName();
549 switch (name.front()) {
559 if (name ==
"localizedStringWithFormat")
return SFF_NSString;
563 if (name ==
"stringByAppendingFormat" ||
571 struct SelectorTableImpl {
572 llvm::FoldingSet<MultiKeywordSelector> Table;
578 return *
static_cast<SelectorTableImpl*
>(
P);
600 return SelTabImpl.Allocator.getTotalMemory();
610 llvm::FoldingSetNodeID
ID;
613 void *InsertPos =
nullptr;
615 SelTabImpl.Table.FindNodeOrInsertPos(ID, InsertPos))
623 llvm::alignOf<MultiKeywordSelector>());
625 SelTabImpl.Table.InsertNode(SI, InsertPos);
630 Impl =
new SelectorTableImpl();
643 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
644 case OO_##Name: return Spelling;
645 #include "clang/Basic/OperatorKinds.def"
648 llvm_unreachable(
"Invalid OverloadedOperatorKind!");
652 bool isContextSensitive) {
655 return isContextSensitive ?
"nonnull" :
"_Nonnull";
658 return isContextSensitive ?
"nullable" :
"_Nullable";
661 return isContextSensitive ?
"null_unspecified" :
"_Null_unspecified";
663 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...
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.