aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Lex/ExternalPreprocessorSource.h52
-rw-r--r--clang/include/clang/Lex/HeaderSearch.h12
-rw-r--r--clang/lib/Lex/HeaderSearch.cpp33
-rw-r--r--clang/lib/Serialization/ASTReader.cpp2
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp7
5 files changed, 76 insertions, 30 deletions
diff --git a/clang/include/clang/Lex/ExternalPreprocessorSource.h b/clang/include/clang/Lex/ExternalPreprocessorSource.h
index 6775841..6672ada 100644
--- a/clang/include/clang/Lex/ExternalPreprocessorSource.h
+++ b/clang/include/clang/Lex/ExternalPreprocessorSource.h
@@ -42,6 +42,58 @@ public:
virtual Module *getModule(unsigned ModuleID) = 0;
};
+// Either a pointer to an IdentifierInfo of the controlling macro or the ID
+// number of the controlling macro.
+class LazyIdentifierInfoPtr {
+ // If the low bit is clear, a pointer to the IdentifierInfo. If the low
+ // bit is set, the upper 63 bits are the ID number.
+ mutable uint64_t Ptr = 0;
+
+public:
+ LazyIdentifierInfoPtr() = default;
+
+ explicit LazyIdentifierInfoPtr(const IdentifierInfo *Ptr)
+ : Ptr(reinterpret_cast<uint64_t>(Ptr)) {}
+
+ explicit LazyIdentifierInfoPtr(uint64_t ID) : Ptr((ID << 1) | 0x01) {
+ assert((ID << 1 >> 1) == ID && "ID must require < 63 bits");
+ if (ID == 0)
+ Ptr = 0;
+ }
+
+ LazyIdentifierInfoPtr &operator=(const IdentifierInfo *Ptr) {
+ this->Ptr = reinterpret_cast<uint64_t>(Ptr);
+ return *this;
+ }
+
+ LazyIdentifierInfoPtr &operator=(uint64_t ID) {
+ assert((ID << 1 >> 1) == ID && "IDs must require < 63 bits");
+ if (ID == 0)
+ Ptr = 0;
+ else
+ Ptr = (ID << 1) | 0x01;
+
+ return *this;
+ }
+
+ /// Whether this pointer is non-NULL.
+ ///
+ /// This operation does not require the AST node to be deserialized.
+ bool isValid() const { return Ptr != 0; }
+
+ /// Whether this pointer is currently stored as ID.
+ bool isID() const { return Ptr & 0x01; }
+
+ IdentifierInfo *getPtr() const {
+ assert(!isID());
+ return reinterpret_cast<IdentifierInfo *>(Ptr);
+ }
+
+ uint64_t getID() const {
+ assert(isID());
+ return Ptr >> 1;
+ }
+};
}
#endif
diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h
index d8ca1c5..df75c19 100644
--- a/clang/include/clang/Lex/HeaderSearch.h
+++ b/clang/include/clang/Lex/HeaderSearch.h
@@ -16,6 +16,7 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/DirectoryLookup.h"
+#include "clang/Lex/ExternalPreprocessorSource.h"
#include "clang/Lex/HeaderMap.h"
#include "clang/Lex/ModuleMap.h"
#include "llvm/ADT/ArrayRef.h"
@@ -121,13 +122,6 @@ struct HeaderFileInfo {
LLVM_PREFERRED_TYPE(bool)
unsigned IsValid : 1;
- /// The ID number of the controlling macro.
- ///
- /// This ID number will be non-zero when there is a controlling
- /// macro whose IdentifierInfo may not yet have been loaded from
- /// external storage.
- unsigned ControllingMacroID = 0;
-
/// If this file has a \#ifndef XXX (or equivalent) guard that
/// protects the entire contents of the file, this is the identifier
/// for the macro that controls whether or not it has any effect.
@@ -136,7 +130,7 @@ struct HeaderFileInfo {
/// the controlling macro of this header, since
/// getControllingMacro() is able to load a controlling macro from
/// external storage.
- const IdentifierInfo *ControllingMacro = nullptr;
+ LazyIdentifierInfoPtr LazyControllingMacro;
/// If this header came from a framework include, this is the name
/// of the framework.
@@ -582,7 +576,7 @@ public:
/// no-op \#includes.
void SetFileControllingMacro(FileEntryRef File,
const IdentifierInfo *ControllingMacro) {
- getFileInfo(File).ControllingMacro = ControllingMacro;
+ getFileInfo(File).LazyControllingMacro = ControllingMacro;
}
/// Determine whether this file is intended to be safe from
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index 9321a36..3bd3aa4 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -60,19 +60,21 @@ ALWAYS_ENABLED_STATISTIC(NumSubFrameworkLookups,
const IdentifierInfo *
HeaderFileInfo::getControllingMacro(ExternalPreprocessorSource *External) {
- if (ControllingMacro) {
- if (ControllingMacro->isOutOfDate()) {
- assert(External && "We must have an external source if we have a "
- "controlling macro that is out of date.");
- External->updateOutOfDateIdentifier(*ControllingMacro);
- }
- return ControllingMacro;
- }
+ if (LazyControllingMacro.isID()) {
+ if (!External)
+ return nullptr;
- if (!ControllingMacroID || !External)
- return nullptr;
+ LazyControllingMacro =
+ External->GetIdentifier(LazyControllingMacro.getID());
+ return LazyControllingMacro.getPtr();
+ }
- ControllingMacro = External->GetIdentifier(ControllingMacroID);
+ IdentifierInfo *ControllingMacro = LazyControllingMacro.getPtr();
+ if (ControllingMacro && ControllingMacro->isOutOfDate()) {
+ assert(External && "We must have an external source if we have a "
+ "controlling macro that is out of date.");
+ External->updateOutOfDateIdentifier(*ControllingMacro);
+ }
return ControllingMacro;
}
@@ -1348,10 +1350,8 @@ static void mergeHeaderFileInfo(HeaderFileInfo &HFI,
mergeHeaderFileInfoModuleBits(HFI, OtherHFI.isModuleHeader,
OtherHFI.isTextualModuleHeader);
- if (!HFI.ControllingMacro && !HFI.ControllingMacroID) {
- HFI.ControllingMacro = OtherHFI.ControllingMacro;
- HFI.ControllingMacroID = OtherHFI.ControllingMacroID;
- }
+ if (!HFI.LazyControllingMacro.isValid())
+ HFI.LazyControllingMacro = OtherHFI.LazyControllingMacro;
HFI.DirInfo = OtherHFI.DirInfo;
HFI.External = (!HFI.IsValid || HFI.External);
@@ -1426,8 +1426,7 @@ bool HeaderSearch::isFileMultipleIncludeGuarded(FileEntryRef File) const {
// once. Note that we dor't check for #import, because that's not a property
// of the file itself.
if (auto *HFI = getExistingFileInfo(File))
- return HFI->isPragmaOnce || HFI->ControllingMacro ||
- HFI->ControllingMacroID;
+ return HFI->isPragmaOnce || HFI->LazyControllingMacro.isValid();
return false;
}
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 973475c..0afbc44 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -2092,7 +2092,7 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d,
HFI.isPragmaOnce |= (Flags >> 4) & 0x01;
HFI.DirInfo = (Flags >> 1) & 0x07;
HFI.IndexHeaderMapHeader = Flags & 0x01;
- HFI.ControllingMacroID = Reader.getGlobalIdentifierID(
+ HFI.LazyControllingMacro = Reader.getGlobalIdentifierID(
M, endian::readNext<uint32_t, llvm::endianness::little>(d));
if (unsigned FrameworkOffset =
endian::readNext<uint32_t, llvm::endianness::little>(d)) {
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 50fa44d..a60092a 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -2028,10 +2028,11 @@ namespace {
| Data.HFI.IndexHeaderMapHeader;
LE.write<uint8_t>(Flags);
- if (!Data.HFI.ControllingMacro)
- LE.write<uint32_t>(Data.HFI.ControllingMacroID);
+ if (Data.HFI.LazyControllingMacro.isID())
+ LE.write<IdentifierID>(Data.HFI.LazyControllingMacro.getID());
else
- LE.write<uint32_t>(Writer.getIdentifierRef(Data.HFI.ControllingMacro));
+ LE.write<IdentifierID>(
+ Writer.getIdentifierRef(Data.HFI.LazyControllingMacro.getPtr()));
unsigned Offset = 0;
if (!Data.HFI.Framework.empty()) {