Skip to content

Commit a2fb7f5

Browse files
committed
[Serialization] No transitive identifier change
1 parent 8b7a650 commit a2fb7f5

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
@@ -657,14 +657,6 @@ class ASTReader
657657
/// been loaded.
658658
std::vector<IdentifierInfo *> IdentifiersLoaded;
659659

660-
using GlobalIdentifierMapType =
661-
ContinuousRangeMap<serialization::IdentifierID, ModuleFile *, 4>;
662-
663-
/// Mapping from global identifier IDs to the module in which the
664-
/// identifier resides along with the offset that should be added to the
665-
/// global identifier ID to produce a local ID.
666-
GlobalIdentifierMapType GlobalIdentifierMap;
667-
668660
/// A vector containing macros that have already been
669661
/// loaded.
670662
///
@@ -1536,6 +1528,11 @@ class ASTReader
15361528
/// Translate a \param GlobalDeclID to the index of DeclsLoaded array.
15371529
unsigned translateGlobalDeclIDToIndex(GlobalDeclID ID) const;
15381530

1531+
/// Translate an \param IdentifierID ID to the index of IdentifiersLoaded
1532+
/// array and the corresponding module file.
1533+
std::pair<ModuleFile *, unsigned>
1534+
translateIdentifierIDToIndex(serialization::IdentifierID ID) const;
1535+
15391536
public:
15401537
/// Load the AST file and validate its contents against the given
15411538
/// Preprocessor.
@@ -2120,7 +2117,7 @@ class ASTReader
21202117
/// Load a selector from disk, registering its ID if it exists.
21212118
void LoadSelector(Selector Sel);
21222119

2123-
void SetIdentifierInfo(unsigned ID, IdentifierInfo *II);
2120+
void SetIdentifierInfo(serialization::IdentifierID ID, IdentifierInfo *II);
21242121
void SetGloballyVisibleDecls(IdentifierInfo *II,
21252122
const SmallVectorImpl<GlobalDeclID> &DeclIDs,
21262123
SmallVectorImpl<Decl *> *Decls = nullptr);
@@ -2145,10 +2142,10 @@ class ASTReader
21452142
return DecodeIdentifierInfo(ID);
21462143
}
21472144

2148-
IdentifierInfo *getLocalIdentifier(ModuleFile &M, unsigned LocalID);
2145+
IdentifierInfo *getLocalIdentifier(ModuleFile &M, uint64_t LocalID);
21492146

21502147
serialization::IdentifierID getGlobalIdentifierID(ModuleFile &M,
2151-
unsigned LocalID);
2148+
uint64_t LocalID);
21522149

21532150
void resolvePendingMacro(IdentifierInfo *II, const PendingMacroInfo &PMInfo);
21542151

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)