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;
41 TokenID = tok::identifier;
46 IsFutureCompatKeyword =
false;
48 IsCPPOperatorKeyword =
false;
49 NeedsHandleIdentifier =
false;
51 ChangedAfterLoad =
false;
52 FEChangedAfterLoad =
false;
53 RevertedTokenID =
false;
55 IsModulesImport =
false;
73 StringRef Next()
override {
return StringRef(); }
79 return new EmptyLookupIterator();
85 ExternalLookup(externalLookup) {
91 get(
"import").setModulesImport(
true);
115 KEYNOOPENCL = 0x02000,
116 WCHARSUPPORT = 0x04000,
117 HALFSUPPORT = 0x08000,
118 KEYCONCEPTS = 0x10000,
120 KEYZVECTOR = 0x40000,
121 KEYCOROUTINES = 0x80000,
122 KEYMODULES = 0x100000,
124 KEYALLCXX = KEYCXX | KEYCXX11 | KEYCXX2A,
125 KEYALL = (0x3fffff & ~KEYNOMS18 &
143 if (Flags == KEYALL)
return KS_Enabled;
144 if (LangOpts.CPlusPlus && (Flags & KEYCXX))
return KS_Enabled;
145 if (LangOpts.CPlusPlus11 && (Flags & KEYCXX11))
return KS_Enabled;
146 if (LangOpts.CPlusPlus2a && (Flags & KEYCXX2A))
return KS_Enabled;
147 if (LangOpts.C99 && (Flags & KEYC99))
return KS_Enabled;
148 if (LangOpts.GNUKeywords && (Flags & KEYGNU))
return KS_Extension;
149 if (LangOpts.MicrosoftExt && (Flags & KEYMS))
return KS_Extension;
150 if (LangOpts.Borland && (Flags & KEYBORLAND))
return KS_Extension;
151 if (LangOpts.Bool && (Flags & BOOLSUPPORT))
return KS_Enabled;
152 if (LangOpts.Half && (Flags & HALFSUPPORT))
return KS_Enabled;
153 if (LangOpts.WChar && (Flags & WCHARSUPPORT))
return KS_Enabled;
154 if (LangOpts.AltiVec && (Flags & KEYALTIVEC))
return KS_Enabled;
155 if (LangOpts.OpenCL && (Flags & KEYOPENCL))
return KS_Enabled;
156 if (!LangOpts.CPlusPlus && (Flags & KEYNOCXX))
return KS_Enabled;
157 if (LangOpts.C11 && (Flags & KEYC11))
return KS_Enabled;
160 if (LangOpts.ObjC2 && (Flags & KEYARC))
return KS_Enabled;
161 if (LangOpts.ObjC2 && (Flags & KEYOBJC2))
return KS_Enabled;
162 if (LangOpts.ConceptsTS && (Flags & KEYCONCEPTS))
return KS_Enabled;
163 if (LangOpts.CoroutinesTS && (Flags & KEYCOROUTINES))
return KS_Enabled;
164 if (LangOpts.ModulesTS && (Flags & KEYMODULES))
return KS_Enabled;
165 if (LangOpts.CPlusPlus && (Flags & KEYALLCXX))
return KS_Future;
178 if (LangOpts.MSVCCompat && (Flags & KEYNOMS18) &&
183 if (LangOpts.OpenCL && (Flags & KEYNOOPENCL))
187 if (AddResult == KS_Disabled)
return;
190 Table.
get(Keyword, AddResult == KS_Future ? tok::identifier : TokenCode);
216 #define KEYWORD(NAME, FLAGS) \ 217 AddKeyword(StringRef(#NAME), tok::kw_ ## NAME, \ 218 FLAGS, LangOpts, *this); 219 #define ALIAS(NAME, TOK, FLAGS) \ 220 AddKeyword(StringRef(NAME), tok::kw_ ## TOK, \ 221 FLAGS, LangOpts, *this); 222 #define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \ 223 if (LangOpts.CXXOperatorNames) \ 224 AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this); 225 #define OBJC1_AT_KEYWORD(NAME) \ 226 if (LangOpts.ObjC1) \ 227 AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this); 228 #define OBJC2_AT_KEYWORD(NAME) \ 229 if (LangOpts.ObjC2) \ 230 AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this); 231 #define TESTING_KEYWORD(NAME, FLAGS) 232 #include "clang/Basic/TokenKinds.def" 234 if (LangOpts.ParseUnknownAnytype)
235 AddKeyword(
"__unknown_anytype", tok::kw___unknown_anytype, KEYALL,
238 if (LangOpts.DeclSpecKeyword)
239 AddKeyword(
"__declspec", tok::kw___declspec, KEYALL, LangOpts, *
this);
248 #define KEYWORD(NAME, FLAGS) \ 249 case tok::kw_##NAME: return getKeywordStatus(LangOpts, FLAGS); 250 #include "clang/Basic/TokenKinds.def" 251 default:
return KS_Disabled;
270 if (!LangOpts.CPlusPlus || !isKeyword(LangOpts))
275 LangOptsNoCPP.CPlusPlus =
false;
276 LangOptsNoCPP.CPlusPlus11 =
false;
277 LangOptsNoCPP.CPlusPlus2a =
false;
278 return !isKeyword(LangOptsNoCPP);
287 #define HASH(LEN, FIRST, THIRD) \ 288 (LEN << 5) + (((FIRST-'a') + (THIRD-'a')) & 31) 289 #define CASE(LEN, FIRST, THIRD, NAME) \ 290 case HASH(LEN, FIRST, THIRD): \ 291 return memcmp(Name, #NAME, LEN) ? tok::pp_not_keyword : tok::pp_ ## NAME 293 unsigned Len = getLength();
294 if (Len < 2)
return tok::pp_not_keyword;
295 const char *Name = getNameStart();
296 switch (
HASH(Len, Name[0], Name[2])) {
297 default:
return tok::pp_not_keyword;
298 CASE( 2,
'i',
'\0',
if);
299 CASE( 4,
'e',
'i', elif);
300 CASE( 4,
'e',
's',
else);
301 CASE( 4,
'l',
'n', line);
302 CASE( 4,
's',
'c', sccs);
303 CASE( 5,
'e',
'd', endif);
304 CASE( 5,
'e',
'r', error);
305 CASE( 5,
'i',
'e', ident);
306 CASE( 5,
'i',
'd', ifdef);
307 CASE( 5,
'u',
'd', undef);
309 CASE( 6,
'a',
's', assert);
310 CASE( 6,
'd',
'f', define);
311 CASE( 6,
'i',
'n', ifndef);
312 CASE( 6,
'i',
'p',
import);
313 CASE( 6,
'p',
'a', pragma);
315 CASE( 7,
'd',
'f', defined);
316 CASE( 7,
'i',
'c', include);
317 CASE( 7,
'w',
'r', warning);
319 CASE( 8,
'u',
'a', unassert);
320 CASE(12,
'i',
'c', include_next);
322 CASE(14,
'_',
'p', __public_macro);
324 CASE(15,
'_',
'p', __private_macro);
326 CASE(16,
'_',
'i', __include_macros);
339 unsigned NumBuckets = HashTable.getNumBuckets();
340 unsigned NumIdentifiers = HashTable.getNumItems();
341 unsigned NumEmptyBuckets = NumBuckets-NumIdentifiers;
342 unsigned AverageIdentifierSize = 0;
343 unsigned MaxIdentifierLength = 0;
346 for (llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator>::const_iterator
347 I = HashTable.begin(), E = HashTable.end(); I != E; ++I) {
348 unsigned IdLen = I->getKeyLength();
349 AverageIdentifierSize += IdLen;
350 if (MaxIdentifierLength < IdLen)
351 MaxIdentifierLength = IdLen;
354 fprintf(stderr,
"\n*** Identifier Table Stats:\n");
355 fprintf(stderr,
"# Identifiers: %d\n", NumIdentifiers);
356 fprintf(stderr,
"# Empty Buckets: %d\n", NumEmptyBuckets);
357 fprintf(stderr,
"Hash density (#identifiers per bucket): %f\n",
358 NumIdentifiers/(
double)NumBuckets);
359 fprintf(stderr,
"Ave identifier length: %f\n",
360 (AverageIdentifierSize/(
double)NumIdentifiers));
361 fprintf(stderr,
"Max identifier length: %d\n", MaxIdentifierLength);
364 HashTable.getAllocator().PrintStats();
384 ExtraKindOrNumArgs = NUM_EXTRA_KINDS + nKeys;
390 assert((nKeys > 1) &&
"not a multi-keyword selector");
391 ExtraKindOrNumArgs = NUM_EXTRA_KINDS + nKeys;
395 for (
unsigned i = 0; i != nKeys; ++i)
400 std::string getName()
const;
402 unsigned getNumArgs()
const {
return ExtraKindOrNumArgs - NUM_EXTRA_KINDS; }
411 return keyword_begin()+getNumArgs();
415 assert(i < getNumArgs() &&
"getIdentifierInfoForSlot(): illegal index");
416 return keyword_begin()[i];
421 ID.AddInteger(NumArgs);
422 for (
unsigned i = 0; i != NumArgs; ++i)
423 ID.AddPointer(ArgTys[i]);
427 Profile(ID, keyword_begin(), getNumArgs());
434 unsigned IIF = getIdentifierInfoFlag();
445 if (getIdentifierInfoFlag() < MultiArg) {
446 assert(argIndex == 0 &&
"illegal keyword index");
447 return getAsIdentifierInfo();
457 return II? II->
getName() : StringRef();
462 llvm::raw_svector_ostream OS(Str);
463 for (
keyword_iterator I = keyword_begin(), E = keyword_end(); I != E; ++I) {
465 OS << (*I)->getName();
474 return "<null selector>";
476 if (getIdentifierInfoFlag() < MultiArg) {
479 if (getNumArgs() == 0) {
480 assert(II &&
"If the number of arguments is 0 then II is guaranteed to " 488 return II->
getName().str() +
":";
492 return getMultiKeywordSelector()->getName();
503 if (name.size() < word.size())
return false;
504 return ((name.size() == word.size() || !
isLowercase(name[word.size()])) &&
505 name.startswith(word));
512 StringRef name = first->
getName();
520 if (name ==
"self")
return OMF_self;
524 if (name ==
"performSelector" || name ==
"performSelectorInBackground" ||
525 name ==
"performSelectorOnMainThread")
529 while (!name.empty() && name.front() ==
'_')
530 name = name.substr(1);
533 switch (name.front()) {
560 StringRef name = first->
getName();
563 switch (name.front()) {
587 StringRef name = first->
getName();
589 switch (name.front()) {
599 if (name ==
"localizedStringWithFormat")
return SFF_NSString;
603 if (name ==
"stringByAppendingFormat" ||
612 struct SelectorTableImpl {
613 llvm::FoldingSet<MultiKeywordSelector> Table;
614 llvm::BumpPtrAllocator Allocator;
620 return *
static_cast<SelectorTableImpl*
>(
P);
636 &Idents.
get(constructSetterName(Name->
getName()));
642 return SelTabImpl.Allocator.getTotalMemory();
652 llvm::FoldingSetNodeID
ID;
655 void *InsertPos =
nullptr;
657 SelTabImpl.Table.FindNodeOrInsertPos(ID, InsertPos))
667 SelTabImpl.Table.InsertNode(SI, InsertPos);
672 Impl =
new SelectorTableImpl();
685 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 686 case OO_##Name: return Spelling; 687 #include "clang/Basic/OperatorKinds.def" 690 llvm_unreachable(
"Invalid OverloadedOperatorKind!");
694 bool isContextSensitive) {
697 return isContextSensitive ?
"nonnull" :
"_Nonnull";
700 return isContextSensitive ?
"nullable" :
"_Nullable";
703 return isContextSensitive ?
"null_unspecified" :
"_Null_unspecified";
705 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.
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
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.
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...
MultiKeywordSelector - One of these variable length records is kept for each selector containing more...
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
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.
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()
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.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
unsigned getNumArgs() const
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.