Skip to content

Commit e8f756e

Browse files
committed
[Serialization] No transitive identifier change
1 parent 799ae77 commit e8f756e

11 files changed

+286
-112
lines changed

clang/include/clang/Lex/ExternalPreprocessorSource.h

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,64 @@ class ExternalPreprocessorSource {
3636
/// Return the identifier associated with the given ID number.
3737
///
3838
/// The ID 0 is associated with the NULL identifier.
39-
virtual IdentifierInfo *GetIdentifier(unsigned ID) = 0;
39+
virtual IdentifierInfo *GetIdentifier(uint64_t ID) = 0;
4040

4141
/// Map a module ID to a module.
4242
virtual Module *getModule(unsigned ModuleID) = 0;
4343
};
4444

45+
// Either a pointer to an IdentifierInfo of the controlling macro or the ID
46+
// number of the controlling macro.
47+
class LazyIdentifierInfoPtr {
48+
// If the low bit is clear, a pointer to the IdentifierInfo. If the low
49+
// bit is set, the upper 63 bits are the ID number.
50+
mutable uint64_t Ptr = 0;
51+
52+
public:
53+
LazyIdentifierInfoPtr() = default;
54+
55+
explicit LazyIdentifierInfoPtr(const IdentifierInfo *Ptr)
56+
: Ptr(reinterpret_cast<uint64_t>(Ptr)) {}
57+
58+
explicit LazyIdentifierInfoPtr(uint64_t ID) : Ptr((ID << 1) | 0x01) {
59+
assert((ID << 1 >> 1) == ID && "ID must require < 63 bits");
60+
if (ID == 0)
61+
Ptr = 0;
62+
}
63+
64+
LazyIdentifierInfoPtr &operator=(const IdentifierInfo *Ptr) {
65+
this->Ptr = reinterpret_cast<uint64_t>(Ptr);
66+
return *this;
67+
}
68+
69+
LazyIdentifierInfoPtr &operator=(uint64_t ID) {
70+
assert((ID << 1 >> 1) == ID && "IDs must require < 63 bits");
71+
if (ID == 0)
72+
Ptr = 0;
73+
else
74+
Ptr = (ID << 1) | 0x01;
75+
76+
return *this;
77+
}
78+
79+
/// Whether this pointer is non-NULL.
80+
///
81+
/// This operation does not require the AST node to be deserialized.
82+
bool isValid() const { return Ptr != 0; }
83+
84+
/// Whether this pointer is currently stored as ID.
85+
bool isID() const { return Ptr & 0x01; }
86+
87+
IdentifierInfo *getPtr() const {
88+
assert(!isID());
89+
return reinterpret_cast<IdentifierInfo *>(Ptr);
90+
}
91+
92+
uint64_t getID() const {
93+
assert(isID());
94+
return Ptr >> 1;
95+
}
96+
};
4597
}
4698

4799
#endif

clang/include/clang/Lex/HeaderSearch.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "clang/Basic/SourceLocation.h"
1717
#include "clang/Basic/SourceManager.h"
1818
#include "clang/Lex/DirectoryLookup.h"
19+
#include "clang/Lex/ExternalPreprocessorSource.h"
1920
#include "clang/Lex/HeaderMap.h"
2021
#include "clang/Lex/ModuleMap.h"
2122
#include "llvm/ADT/ArrayRef.h"
@@ -119,13 +120,6 @@ struct HeaderFileInfo {
119120
LLVM_PREFERRED_TYPE(bool)
120121
unsigned IsValid : 1;
121122

122-
/// The ID number of the controlling macro.
123-
///
124-
/// This ID number will be non-zero when there is a controlling
125-
/// macro whose IdentifierInfo may not yet have been loaded from
126-
/// external storage.
127-
unsigned ControllingMacroID = 0;
128-
129123
/// If this file has a \#ifndef XXX (or equivalent) guard that
130124
/// protects the entire contents of the file, this is the identifier
131125
/// for the macro that controls whether or not it has any effect.
@@ -134,7 +128,7 @@ struct HeaderFileInfo {
134128
/// the controlling macro of this header, since
135129
/// getControllingMacro() is able to load a controlling macro from
136130
/// external storage.
137-
const IdentifierInfo *ControllingMacro = nullptr;
131+
LazyIdentifierInfoPtr LazyControllingMacro;
138132

139133
/// If this header came from a framework include, this is the name
140134
/// of the framework.
@@ -580,7 +574,7 @@ class HeaderSearch {
580574
/// no-op \#includes.
581575
void SetFileControllingMacro(FileEntryRef File,
582576
const IdentifierInfo *ControllingMacro) {
583-
getFileInfo(File).ControllingMacro = ControllingMacro;
577+
getFileInfo(File).LazyControllingMacro = ControllingMacro;
584578
}
585579

586580
/// Determine whether this file is intended to be safe from

clang/include/clang/Serialization/ASTBitCodes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ const unsigned VERSION_MINOR = 1;
5959
///
6060
/// The ID numbers of identifiers are consecutive (in order of discovery)
6161
/// and start at 1. 0 is reserved for NULL.
62-
using IdentifierID = uint32_t;
62+
using IdentifierID = uint64_t;
6363

6464
/// The number of predefined identifier IDs.
6565
const unsigned int NUM_PREDEF_IDENT_IDS = 1;

clang/include/clang/Serialization/ASTReader.h

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -660,14 +660,6 @@ class ASTReader
660660
/// been loaded.
661661
std::vector<IdentifierInfo *> IdentifiersLoaded;
662662

663-
using GlobalIdentifierMapType =
664-
ContinuousRangeMap<serialization::IdentifierID, ModuleFile *, 4>;
665-
666-
/// Mapping from global identifier IDs to the module in which the
667-
/// identifier resides along with the offset that should be added to the
668-
/// global identifier ID to produce a local ID.
669-
GlobalIdentifierMapType GlobalIdentifierMap;
670-
671663
/// A vector containing macros that have already been
672664
/// loaded.
673665
///
@@ -1539,6 +1531,11 @@ class ASTReader
15391531
/// Translate a \param GlobalDeclID to the index of DeclsLoaded array.
15401532
unsigned translateGlobalDeclIDToIndex(GlobalDeclID ID) const;
15411533

1534+
/// Translate an \param IdentifierID ID to the index of IdentifiersLoaded
1535+
/// array and the corresponding module file.
1536+
std::pair<ModuleFile *, unsigned>
1537+
translateIdentifierIDToIndex(serialization::IdentifierID ID) const;
1538+
15421539
public:
15431540
/// Load the AST file and validate its contents against the given
15441541
/// Preprocessor.
@@ -2123,7 +2120,7 @@ class ASTReader
21232120
/// Load a selector from disk, registering its ID if it exists.
21242121
void LoadSelector(Selector Sel);
21252122

2126-
void SetIdentifierInfo(unsigned ID, IdentifierInfo *II);
2123+
void SetIdentifierInfo(serialization::IdentifierID ID, IdentifierInfo *II);
21272124
void SetGloballyVisibleDecls(IdentifierInfo *II,
21282125
const SmallVectorImpl<GlobalDeclID> &DeclIDs,
21292126
SmallVectorImpl<Decl *> *Decls = nullptr);
@@ -2150,10 +2147,10 @@ class ASTReader
21502147
return DecodeIdentifierInfo(ID);
21512148
}
21522149

2153-
IdentifierInfo *getLocalIdentifier(ModuleFile &M, unsigned LocalID);
2150+
IdentifierInfo *getLocalIdentifier(ModuleFile &M, uint64_t LocalID);
21542151

21552152
serialization::IdentifierID getGlobalIdentifierID(ModuleFile &M,
2156-
unsigned LocalID);
2153+
uint64_t LocalID);
21572154

21582155
void resolvePendingMacro(IdentifierInfo *II, const PendingMacroInfo &PMInfo);
21592156

clang/include/clang/Serialization/ModuleFile.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,9 +310,6 @@ class ModuleFile {
310310
/// Base identifier ID for identifiers local to this module.
311311
serialization::IdentifierID BaseIdentifierID = 0;
312312

313-
/// Remapping table for identifier IDs in this module.
314-
ContinuousRangeMap<uint32_t, int, 2> IdentifierRemap;
315-
316313
/// Actual data for the on-disk hash table of identifiers.
317314
///
318315
/// This pointer points into a memory buffer, where the on-disk hash

clang/lib/Lex/HeaderSearch.cpp

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,21 @@ ALWAYS_ENABLED_STATISTIC(NumSubFrameworkLookups,
6060

6161
const IdentifierInfo *
6262
HeaderFileInfo::getControllingMacro(ExternalPreprocessorSource *External) {
63-
if (ControllingMacro) {
64-
if (ControllingMacro->isOutOfDate()) {
65-
assert(External && "We must have an external source if we have a "
66-
"controlling macro that is out of date.");
67-
External->updateOutOfDateIdentifier(*ControllingMacro);
68-
}
69-
return ControllingMacro;
70-
}
63+
if (LazyControllingMacro.isID()) {
64+
if (!External)
65+
return nullptr;
7166

72-
if (!ControllingMacroID || !External)
73-
return nullptr;
67+
LazyControllingMacro =
68+
External->GetIdentifier(LazyControllingMacro.getID());
69+
return LazyControllingMacro.getPtr();
70+
}
7471

75-
ControllingMacro = External->GetIdentifier(ControllingMacroID);
72+
IdentifierInfo *ControllingMacro = LazyControllingMacro.getPtr();
73+
if (ControllingMacro && ControllingMacro->isOutOfDate()) {
74+
assert(External && "We must have an external source if we have a "
75+
"controlling macro that is out of date.");
76+
External->updateOutOfDateIdentifier(*ControllingMacro);
77+
}
7678
return ControllingMacro;
7779
}
7880

@@ -1341,10 +1343,8 @@ static void mergeHeaderFileInfo(HeaderFileInfo &HFI,
13411343
mergeHeaderFileInfoModuleBits(HFI, OtherHFI.isModuleHeader,
13421344
OtherHFI.isTextualModuleHeader);
13431345

1344-
if (!HFI.ControllingMacro && !HFI.ControllingMacroID) {
1345-
HFI.ControllingMacro = OtherHFI.ControllingMacro;
1346-
HFI.ControllingMacroID = OtherHFI.ControllingMacroID;
1347-
}
1346+
if (!HFI.LazyControllingMacro.isValid())
1347+
HFI.LazyControllingMacro = OtherHFI.LazyControllingMacro;
13481348

13491349
HFI.DirInfo = OtherHFI.DirInfo;
13501350
HFI.External = (!HFI.IsValid || HFI.External);
@@ -1419,8 +1419,7 @@ bool HeaderSearch::isFileMultipleIncludeGuarded(FileEntryRef File) const {
14191419
// once. Note that we dor't check for #import, because that's not a property
14201420
// of the file itself.
14211421
if (auto *HFI = getExistingFileInfo(File))
1422-
return HFI->isPragmaOnce || HFI->ControllingMacro ||
1423-
HFI->ControllingMacroID;
1422+
return HFI->isPragmaOnce || HFI->LazyControllingMacro.isValid();
14241423
return false;
14251424
}
14261425

0 commit comments

Comments
 (0)