Skip to content

Commit 3033822

Browse files
authored
[clang] Refactor IdentifierInfo::ObjcOrBuiltinID (#71709)
This patch refactors how values are stored inside `IdentifierInfo::ObjcOrBuiltinID` bit-field, and annotates it with `preferred_type`. In order to make the value easier to interpret by debuggers, a new `ObjCKeywordOrInterestingOrBuiltin` enum is added. Previous "layout" of this fields couldn't be represented with this new enum, because it skipped over some arbitrary enumerators, so a new "layout" was invented, which is reflected in `ObjCKeywordOrInterestingOrBuiltin` enum. I believe the new layout is simpler than the new one.
1 parent cf55e61 commit 3033822

File tree

3 files changed

+92
-50
lines changed

3 files changed

+92
-50
lines changed

clang/include/clang/Basic/IdentifierTable.h

Lines changed: 79 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
1616
#define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
1717

18+
#include "clang/Basic/Builtins.h"
1819
#include "clang/Basic/DiagnosticIDs.h"
1920
#include "clang/Basic/LLVM.h"
2021
#include "clang/Basic/TokenKinds.h"
@@ -86,19 +87,26 @@ enum { IdentifierInfoAlignment = 8 };
8687
static constexpr int ObjCOrBuiltinIDBits = 16;
8788

8889
/// 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+
};
102110

103111
/// One of these records is kept for each identifier that
104112
/// is lexed. This contains information about whether the token was \#define'd,
@@ -113,9 +121,7 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo {
113121
LLVM_PREFERRED_TYPE(tok::TokenKind)
114122
unsigned TokenID : 9;
115123

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)
119125
unsigned ObjCOrBuiltinID : ObjCOrBuiltinIDBits;
120126

121127
// True if there is a #define for this.
@@ -198,13 +204,16 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo {
198204
llvm::StringMapEntry<IdentifierInfo *> *Entry = nullptr;
199205

200206
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) {}
208217

209218
public:
210219
IdentifierInfo(const IdentifierInfo &) = delete;
@@ -332,42 +341,66 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo {
332341
///
333342
/// For example, 'class' will return tok::objc_class if ObjC is enabled.
334343
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!");
341357
}
342-
void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; }
343358

344359
/// Return a value indicating whether this is a builtin function.
345-
///
346-
/// 0 is not-built-in. 1+ are specific builtin functions.
347360
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;
352371
}
353372
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;
356377
assert(getBuiltinID() == ID && "ID too large for field!");
357378
}
358-
void clearBuiltinID() { ObjCOrBuiltinID = 0; }
379+
void clearBuiltinID() {
380+
ObjCOrBuiltinID = llvm::to_underlying(
381+
ObjCKeywordOrInterestingOrBuiltin::NonSpecialIdentifier);
382+
}
359383

360384
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;
367397
}
368398
void setInterestingIdentifierID(unsigned ID) {
369399
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;
371404
assert(getInterestingIdentifierID() == ID && "ID too large for field!");
372405
}
373406

clang/lib/Serialization/ASTReader.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -987,9 +987,13 @@ ASTIdentifierLookupTraitBase::ReadKey(const unsigned char* d, unsigned n) {
987987
/// Whether the given identifier is "interesting".
988988
static bool isInterestingIdentifier(ASTReader &Reader, IdentifierInfo &II,
989989
bool IsModule) {
990+
bool IsInteresting =
991+
II.getInterestingIdentifierID() !=
992+
tok::InterestingIdentifierKind::not_interesting ||
993+
II.getBuiltinID() != Builtin::ID::NotBuiltin ||
994+
II.getObjCKeywordID() != tok::ObjCKeywordKind::objc_not_keyword;
990995
return II.hadMacroDefinition() || II.isPoisoned() ||
991-
(!IsModule && II.getObjCOrBuiltinID()) ||
992-
II.hasRevertedTokenIDToIdentifier() ||
996+
(!IsModule && IsInteresting) || II.hasRevertedTokenIDToIdentifier() ||
993997
(!(IsModule && Reader.getPreprocessor().getLangOpts().CPlusPlus) &&
994998
II.getFETokenInfo());
995999
}

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3597,8 +3597,13 @@ class ASTIdentifierTableTrait {
35973597
/// doesn't check whether the name has macros defined; use PublicMacroIterator
35983598
/// to check that.
35993599
bool isInterestingIdentifier(const IdentifierInfo *II, uint64_t MacroOffset) {
3600-
if (MacroOffset || II->isPoisoned() ||
3601-
(!IsModule && II->getObjCOrBuiltinID()) ||
3600+
II->getObjCOrBuiltinID();
3601+
bool IsInteresting =
3602+
II->getInterestingIdentifierID() !=
3603+
tok::InterestingIdentifierKind::not_interesting ||
3604+
II->getBuiltinID() != Builtin::ID::NotBuiltin ||
3605+
II->getObjCKeywordID() != tok::ObjCKeywordKind::objc_not_keyword;
3606+
if (MacroOffset || II->isPoisoned() || (!IsModule && IsInteresting) ||
36023607
II->hasRevertedTokenIDToIdentifier() ||
36033608
(NeedDecls && II->getFETokenInfo()))
36043609
return true;

0 commit comments

Comments
 (0)