15
15
#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
16
16
#define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
17
17
18
+ #include " clang/Basic/Builtins.h"
18
19
#include " clang/Basic/DiagnosticIDs.h"
19
20
#include " clang/Basic/LLVM.h"
20
21
#include " clang/Basic/TokenKinds.h"
@@ -86,19 +87,26 @@ enum { IdentifierInfoAlignment = 8 };
86
87
static constexpr int ObjCOrBuiltinIDBits = 16 ;
87
88
88
89
// / The "layout" of ObjCOrBuiltinID is:
89
- // / - The first value (0) represents "not a special identifier".
90
- // / - The next (NUM_OBJC_KEYWORDS - 1) values represent ObjCKeywordKinds (not
91
- // / including objc_not_keyword).
92
- // / - The next (NUM_INTERESTING_IDENTIFIERS - 1) values represent
93
- // / InterestingIdentifierKinds (not including not_interesting).
94
- // / - The rest of the values represent builtin IDs (not including NotBuiltin).
95
- static constexpr int FirstObjCKeywordID = 1 ;
96
- static constexpr int LastObjCKeywordID =
97
- FirstObjCKeywordID + tok::NUM_OBJC_KEYWORDS - 2 ;
98
- static constexpr int FirstInterestingIdentifierID = LastObjCKeywordID + 1 ;
99
- static constexpr int LastInterestingIdentifierID =
100
- FirstInterestingIdentifierID + tok::NUM_INTERESTING_IDENTIFIERS - 2 ;
101
- static constexpr int FirstBuiltinID = LastInterestingIdentifierID + 1 ;
90
+ // / - ObjCKeywordKind enumerators
91
+ // / - InterestingIdentifierKind enumerators
92
+ // / - Builtin::ID enumerators
93
+ // / - NonSpecialIdentifier
94
+ enum class ObjCKeywordOrInterestingOrBuiltin {
95
+ #define OBJC_AT_KEYWORD (X ) objc_##X,
96
+ #include " clang/Basic/TokenKinds.def"
97
+ NUM_OBJC_KEYWORDS,
98
+
99
+ #define INTERESTING_IDENTIFIER (X ) X,
100
+ #include " clang/Basic/TokenKinds.def"
101
+ NUM_OBJC_KEYWORDS_AND_INTERESTING_IDENTIFIERS,
102
+
103
+ NotBuiltin,
104
+ #define BUILTIN (ID, TYPE, ATTRS ) BI##ID,
105
+ #include " clang/Basic/Builtins.inc"
106
+ FirstTSBuiltin,
107
+
108
+ NonSpecialIdentifier = 65534
109
+ };
102
110
103
111
// / One of these records is kept for each identifier that
104
112
// / is lexed. This contains information about whether the token was \#define'd,
@@ -113,9 +121,7 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo {
113
121
LLVM_PREFERRED_TYPE (tok::TokenKind)
114
122
unsigned TokenID : 9 ;
115
123
116
- // ObjC keyword ('protocol' in '@protocol') or builtin (__builtin_inf).
117
- // First NUM_OBJC_KEYWORDS values are for Objective-C,
118
- // the remaining values are for builtins.
124
+ LLVM_PREFERRED_TYPE (ObjCKeywordOrInterestingOrBuiltin)
119
125
unsigned ObjCOrBuiltinID : ObjCOrBuiltinIDBits;
120
126
121
127
// True if there is a #define for this.
@@ -198,13 +204,16 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo {
198
204
llvm::StringMapEntry<IdentifierInfo *> *Entry = nullptr ;
199
205
200
206
IdentifierInfo ()
201
- : TokenID (tok::identifier), ObjCOrBuiltinID (0 ), HasMacro (false ),
202
- HadMacro (false ), IsExtension (false ), IsFutureCompatKeyword (false ),
203
- IsPoisoned (false ), IsCPPOperatorKeyword (false ),
204
- NeedsHandleIdentifier (false ), IsFromAST (false ), ChangedAfterLoad (false ),
205
- FEChangedAfterLoad (false ), RevertedTokenID (false ), OutOfDate (false ),
206
- IsModulesImport (false ), IsMangledOpenMPVariantName (false ),
207
- IsDeprecatedMacro (false ), IsRestrictExpansion (false ), IsFinal (false ) {}
207
+ : TokenID (tok::identifier),
208
+ ObjCOrBuiltinID (llvm::to_underlying (
209
+ ObjCKeywordOrInterestingOrBuiltin::NonSpecialIdentifier)),
210
+ HasMacro (false ), HadMacro (false ), IsExtension (false ),
211
+ IsFutureCompatKeyword (false ), IsPoisoned (false ),
212
+ IsCPPOperatorKeyword (false ), NeedsHandleIdentifier (false ),
213
+ IsFromAST (false ), ChangedAfterLoad (false ), FEChangedAfterLoad (false ),
214
+ RevertedTokenID (false ), OutOfDate (false ), IsModulesImport (false ),
215
+ IsMangledOpenMPVariantName (false ), IsDeprecatedMacro (false ),
216
+ IsRestrictExpansion (false ), IsFinal (false ) {}
208
217
209
218
public:
210
219
IdentifierInfo (const IdentifierInfo &) = delete ;
@@ -332,42 +341,66 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo {
332
341
// /
333
342
// / For example, 'class' will return tok::objc_class if ObjC is enabled.
334
343
tok::ObjCKeywordKind getObjCKeywordID () const {
335
- static_assert (FirstObjCKeywordID == 1 ,
336
- " hard-coding this assumption to simplify code" );
337
- if (ObjCOrBuiltinID <= LastObjCKeywordID)
338
- return tok::ObjCKeywordKind (ObjCOrBuiltinID);
339
- else
340
- return tok::objc_not_keyword;
344
+ assert (0 == llvm::to_underlying (
345
+ ObjCKeywordOrInterestingOrBuiltin::objc_not_keyword));
346
+ auto Value =
347
+ static_cast <ObjCKeywordOrInterestingOrBuiltin>(ObjCOrBuiltinID);
348
+ if (Value < ObjCKeywordOrInterestingOrBuiltin::NUM_OBJC_KEYWORDS)
349
+ return static_cast <tok::ObjCKeywordKind>(ObjCOrBuiltinID);
350
+ return tok::objc_not_keyword;
351
+ }
352
+ void setObjCKeywordID (tok::ObjCKeywordKind ID) {
353
+ assert (0 == llvm::to_underlying (
354
+ ObjCKeywordOrInterestingOrBuiltin::objc_not_keyword));
355
+ ObjCOrBuiltinID = ID;
356
+ assert (getObjCKeywordID () == ID && " ID too large for field!" );
341
357
}
342
- void setObjCKeywordID (tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; }
343
358
344
359
// / Return a value indicating whether this is a builtin function.
345
- // /
346
- // / 0 is not-built-in. 1+ are specific builtin functions.
347
360
unsigned getBuiltinID () const {
348
- if (ObjCOrBuiltinID >= FirstBuiltinID)
349
- return 1 + (ObjCOrBuiltinID - FirstBuiltinID);
350
- else
351
- return 0 ;
361
+ auto Value =
362
+ static_cast <ObjCKeywordOrInterestingOrBuiltin>(ObjCOrBuiltinID);
363
+ if (Value > ObjCKeywordOrInterestingOrBuiltin::
364
+ NUM_OBJC_KEYWORDS_AND_INTERESTING_IDENTIFIERS &&
365
+ Value != ObjCKeywordOrInterestingOrBuiltin::NonSpecialIdentifier) {
366
+ auto FirstBuiltin =
367
+ llvm::to_underlying (ObjCKeywordOrInterestingOrBuiltin::NotBuiltin);
368
+ return static_cast <Builtin::ID>(ObjCOrBuiltinID - FirstBuiltin);
369
+ }
370
+ return Builtin::ID::NotBuiltin;
352
371
}
353
372
void setBuiltinID (unsigned ID) {
354
- assert (ID != 0 );
355
- ObjCOrBuiltinID = FirstBuiltinID + (ID - 1 );
373
+ assert (ID != Builtin::ID::NotBuiltin);
374
+ auto FirstBuiltin =
375
+ llvm::to_underlying (ObjCKeywordOrInterestingOrBuiltin::NotBuiltin);
376
+ ObjCOrBuiltinID = ID + FirstBuiltin;
356
377
assert (getBuiltinID () == ID && " ID too large for field!" );
357
378
}
358
- void clearBuiltinID () { ObjCOrBuiltinID = 0 ; }
379
+ void clearBuiltinID () {
380
+ ObjCOrBuiltinID = llvm::to_underlying (
381
+ ObjCKeywordOrInterestingOrBuiltin::NonSpecialIdentifier);
382
+ }
359
383
360
384
tok::InterestingIdentifierKind getInterestingIdentifierID () const {
361
- if (ObjCOrBuiltinID >= FirstInterestingIdentifierID &&
362
- ObjCOrBuiltinID <= LastInterestingIdentifierID)
363
- return tok::InterestingIdentifierKind (
364
- 1 + (ObjCOrBuiltinID - FirstInterestingIdentifierID));
365
- else
366
- return tok::not_interesting;
385
+ auto Value =
386
+ static_cast <ObjCKeywordOrInterestingOrBuiltin>(ObjCOrBuiltinID);
387
+ if (Value > ObjCKeywordOrInterestingOrBuiltin::NUM_OBJC_KEYWORDS &&
388
+ Value < ObjCKeywordOrInterestingOrBuiltin::
389
+ NUM_OBJC_KEYWORDS_AND_INTERESTING_IDENTIFIERS) {
390
+ auto FirstInterestingIdentifier =
391
+ 1 + llvm::to_underlying (
392
+ ObjCKeywordOrInterestingOrBuiltin::NUM_OBJC_KEYWORDS);
393
+ return static_cast <tok::InterestingIdentifierKind>(
394
+ ObjCOrBuiltinID - FirstInterestingIdentifier);
395
+ }
396
+ return tok::not_interesting;
367
397
}
368
398
void setInterestingIdentifierID (unsigned ID) {
369
399
assert (ID != tok::not_interesting);
370
- ObjCOrBuiltinID = FirstInterestingIdentifierID + (ID - 1 );
400
+ auto FirstInterestingIdentifier =
401
+ 1 + llvm::to_underlying (
402
+ ObjCKeywordOrInterestingOrBuiltin::NUM_OBJC_KEYWORDS);
403
+ ObjCOrBuiltinID = ID + FirstInterestingIdentifier;
371
404
assert (getInterestingIdentifierID () == ID && " ID too large for field!" );
372
405
}
373
406
0 commit comments