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 KEYALL = (0x7ffff & ~KEYNOMS18 &
131 if (Flags == KEYALL)
return KS_Enabled;
132 if (LangOpts.CPlusPlus && (Flags & KEYCXX))
return KS_Enabled;
133 if (LangOpts.CPlusPlus11 && (Flags & KEYCXX11))
return KS_Enabled;
134 if (LangOpts.C99 && (Flags & KEYC99))
return KS_Enabled;
135 if (LangOpts.GNUKeywords && (Flags & KEYGNU))
return KS_Extension;
136 if (LangOpts.MicrosoftExt && (Flags & KEYMS))
return KS_Extension;
137 if (LangOpts.Borland && (Flags & KEYBORLAND))
return KS_Extension;
138 if (LangOpts.Bool && (Flags & BOOLSUPPORT))
return KS_Enabled;
139 if (LangOpts.Half && (Flags & HALFSUPPORT))
return KS_Enabled;
140 if (LangOpts.WChar && (Flags & WCHARSUPPORT))
return KS_Enabled;
141 if (LangOpts.AltiVec && (Flags & KEYALTIVEC))
return KS_Enabled;
142 if (LangOpts.OpenCL && (Flags & KEYOPENCL))
return KS_Enabled;
143 if (!LangOpts.CPlusPlus && (Flags & KEYNOCXX))
return KS_Enabled;
144 if (LangOpts.C11 && (Flags & KEYC11))
return KS_Enabled;
147 if (LangOpts.ObjC2 && (Flags & KEYARC))
return KS_Enabled;
148 if (LangOpts.ConceptsTS && (Flags & KEYCONCEPTS))
return KS_Enabled;
149 if (LangOpts.ObjC2 && (Flags & KEYOBJC2))
return KS_Enabled;
150 if (LangOpts.CPlusPlus && (Flags & KEYCXX11))
return KS_Future;
163 if (LangOpts.MSVCCompat && (Flags & KEYNOMS18) &&
168 if (LangOpts.OpenCL && (Flags & KEYNOOPENCL))
172 if (AddResult == KS_Disabled)
return;
175 Table.
get(Keyword, AddResult == KS_Future ? tok::identifier : TokenCode);
201 #define KEYWORD(NAME, FLAGS) \
202 AddKeyword(StringRef(#NAME), tok::kw_ ## NAME, \
203 FLAGS, LangOpts, *this);
204 #define ALIAS(NAME, TOK, FLAGS) \
205 AddKeyword(StringRef(NAME), tok::kw_ ## TOK, \
206 FLAGS, LangOpts, *this);
207 #define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \
208 if (LangOpts.CXXOperatorNames) \
209 AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this);
210 #define OBJC1_AT_KEYWORD(NAME) \
211 if (LangOpts.ObjC1) \
212 AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
213 #define OBJC2_AT_KEYWORD(NAME) \
214 if (LangOpts.ObjC2) \
215 AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
216 #define TESTING_KEYWORD(NAME, FLAGS)
217 #include "clang/Basic/TokenKinds.def"
219 if (LangOpts.ParseUnknownAnytype)
220 AddKeyword(
"__unknown_anytype", tok::kw___unknown_anytype, KEYALL,
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)
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)
keyword_iterator keyword_end() const
Selector getUnarySelector(IdentifierInfo *ID)
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)
tok::TokenKind getTokenID() const
Values of this type can never be null.
static void AddCXXOperatorKeyword(StringRef Keyword, tok::TokenKind TokenCode, IdentifierTable &Table)
void print(llvm::raw_ostream &OS) const
Prints the full selector name (e.g. "foo:bar:").
Provides lookups to, and iteration over, IdentiferInfo objects.
void setIsCPlusPlusOperatorKeyword(bool Val=true)
ID
Defines the set of possible language-specific address spaces.
bool isUnarySelector() const
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.
ObjCKeywordKind
Provides a namespace for Objective-C keywords which start with an '@'.
void setObjCKeywordID(tok::ObjCKeywordKind ID)
static bool startsWithWord(StringRef name, StringRef word)
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. "foo:bar:") and return it as an std::string.
static void AddObjCKeyword(StringRef Name, tok::ObjCKeywordKind ObjCID, IdentifierTable &Table)
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
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)
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.