[PCH] Overhaul how preprocessed entities are [de]serialized.
-Use an array of offsets for all preprocessed entities
-Get rid of the separate array of offsets for just macro definitions;
for references to macro definitions use an index inside the preprocessed
entities array.
-Deserialize each preprocessed entity lazily, at first request; not in bulk.
Paves the way for binary searching of preprocessed entities that will offer
efficiency and will simplify things on the libclang side a lot.
llvm-svn: 139809
diff --git a/clang/lib/Lex/PreprocessingRecord.cpp b/clang/lib/Lex/PreprocessingRecord.cpp
index d02db25..8d96fb0 100644
--- a/clang/lib/Lex/PreprocessingRecord.cpp
+++ b/clang/lib/Lex/PreprocessingRecord.cpp
@@ -37,17 +37,9 @@
this->FileName = StringRef(Memory, FileName.size());
}
-void PreprocessingRecord::MaybeLoadPreallocatedEntities() const {
- if (!ExternalSource || LoadedPreallocatedEntities)
- return;
-
- LoadedPreallocatedEntities = true;
- ExternalSource->ReadPreprocessedEntities();
-}
-
PreprocessingRecord::PreprocessingRecord(bool IncludeNestedMacroExpansions)
: IncludeNestedMacroExpansions(IncludeNestedMacroExpansions),
- ExternalSource(0), LoadedPreallocatedEntities(false)
+ ExternalSource(0)
{
}
@@ -56,14 +48,10 @@
if (OnlyLocalEntities)
return iterator(this, 0);
- MaybeLoadPreallocatedEntities();
return iterator(this, -(int)LoadedPreprocessedEntities.size());
}
PreprocessingRecord::iterator PreprocessingRecord::end(bool OnlyLocalEntities) {
- if (!OnlyLocalEntities)
- MaybeLoadPreallocatedEntities();
-
return iterator(this, PreprocessedEntities.size());
}
@@ -85,26 +73,49 @@
return Result;
}
-void
-PreprocessingRecord::setLoadedPreallocatedEntity(unsigned Index,
- PreprocessedEntity *Entity) {
- assert(Index < LoadedPreprocessedEntities.size() &&
- "Out-of-bounds preallocated entity");
- LoadedPreprocessedEntities[Index] = Entity;
+void PreprocessingRecord::RegisterMacroDefinition(MacroInfo *Macro,
+ PPEntityID PPID) {
+ MacroDefinitions[Macro] = PPID;
}
-void PreprocessingRecord::RegisterMacroDefinition(MacroInfo *Macro,
- MacroDefinition *MD) {
- MacroDefinitions[Macro] = MD;
+/// \brief Retrieve the preprocessed entity at the given ID.
+PreprocessedEntity *PreprocessingRecord::getPreprocessedEntity(PPEntityID PPID){
+ if (PPID < 0) {
+ assert(unsigned(-PPID-1) < LoadedPreprocessedEntities.size() &&
+ "Out-of bounds loaded preprocessed entity");
+ return getLoadedPreprocessedEntity(LoadedPreprocessedEntities.size()+PPID);
+ }
+ assert(unsigned(PPID) < PreprocessedEntities.size() &&
+ "Out-of bounds local preprocessed entity");
+ return PreprocessedEntities[PPID];
+}
+
+/// \brief Retrieve the loaded preprocessed entity at the given index.
+PreprocessedEntity *
+PreprocessingRecord::getLoadedPreprocessedEntity(unsigned Index) {
+ assert(Index < LoadedPreprocessedEntities.size() &&
+ "Out-of bounds loaded preprocessed entity");
+ assert(ExternalSource && "No external source to load from");
+ PreprocessedEntity *&Entity = LoadedPreprocessedEntities[Index];
+ if (!Entity) {
+ Entity = ExternalSource->ReadPreprocessedEntity(Index);
+ if (!Entity) // Failed to load.
+ Entity = new (*this)
+ PreprocessedEntity(PreprocessedEntity::InvalidKind, SourceRange());
+ }
+ return Entity;
}
MacroDefinition *PreprocessingRecord::findMacroDefinition(const MacroInfo *MI) {
- llvm::DenseMap<const MacroInfo *, MacroDefinition *>::iterator Pos
+ llvm::DenseMap<const MacroInfo *, PPEntityID>::iterator Pos
= MacroDefinitions.find(MI);
if (Pos == MacroDefinitions.end())
return 0;
- return Pos->second;
+ PreprocessedEntity *Entity = getPreprocessedEntity(Pos->second);
+ if (Entity->isInvalid())
+ return 0;
+ return cast<MacroDefinition>(Entity);
}
void PreprocessingRecord::MacroExpands(const Token &Id, const MacroInfo* MI,
@@ -127,13 +138,14 @@
= new (*this) MacroDefinition(Id.getIdentifierInfo(),
MI->getDefinitionLoc(),
R);
- MacroDefinitions[MI] = Def;
PreprocessedEntities.push_back(Def);
+ MacroDefinitions[MI] = getPPEntityID(PreprocessedEntities.size()-1,
+ /*isLoaded=*/false);
}
void PreprocessingRecord::MacroUndefined(const Token &Id,
const MacroInfo *MI) {
- llvm::DenseMap<const MacroInfo *, MacroDefinition *>::iterator Pos
+ llvm::DenseMap<const MacroInfo *, PPEntityID>::iterator Pos
= MacroDefinitions.find(MI);
if (Pos != MacroDefinitions.end())
MacroDefinitions.erase(Pos);