aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-02-08 21:58:10 +0000
committerDouglas Gregor <dgregor@apple.com>2011-02-08 21:58:10 +0000
commit4800a5c79023271408af49797e09be32aca93232 (patch)
tree679c5b4c020a3b77b93b8a01425e2b7c4fa41a3d /lib
parentcc324ad80ab940efca006b0064f7ca70a6181816 (diff)
Split the serialized representation for the detailed preprocessing
record away from the core processor record. The tangling of these two data structures led to some inefficiencies (e.g., deserializing all of the detailed preprocessing record when we didn't need it, such as while performing code completion) along with some unnecessary ugliness. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125117 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Serialization/ASTReader.cpp237
-rw-r--r--lib/Serialization/ASTWriter.cpp178
2 files changed, 225 insertions, 190 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index d2d20bfdbd..0fc62ab96a 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -1462,111 +1462,113 @@ PreprocessedEntity *ASTReader::ReadMacroRecord(PerFileData &F, uint64_t Offset)
Macro->AddTokenToBody(Tok);
break;
}
+ }
+ }
+
+ return 0;
+}
- case PP_MACRO_INSTANTIATION: {
- // If we already have a macro, that means that we've hit the end
- // of the definition of the macro we were looking for. We're
- // done.
- if (Macro)
- return 0;
-
- if (!PP->getPreprocessingRecord()) {
- Error("missing preprocessing record in AST file");
- return 0;
- }
+PreprocessedEntity *ASTReader::LoadPreprocessedEntity(PerFileData &F) {
+ assert(PP && "Forgot to set Preprocessor ?");
+ unsigned Code = F.PreprocessorDetailCursor.ReadCode();
+ switch (Code) {
+ case llvm::bitc::END_BLOCK:
+ return 0;
+
+ case llvm::bitc::ENTER_SUBBLOCK:
+ Error("unexpected subblock record in preprocessor detail block");
+ return 0;
+
+ case llvm::bitc::DEFINE_ABBREV:
+ Error("unexpected abbrevation record in preprocessor detail block");
+ return 0;
+
+ default:
+ break;
+ }
- PreprocessingRecord &PPRec = *PP->getPreprocessingRecord();
- if (PreprocessedEntity *PE = PPRec.getPreprocessedEntity(Record[0]))
- return PE;
-
- MacroInstantiation *MI
- = new (PPRec) MacroInstantiation(DecodeIdentifierInfo(Record[3]),
- SourceRange(ReadSourceLocation(F, Record[1]),
- ReadSourceLocation(F, Record[2])),
- getMacroDefinition(Record[4]));
- PPRec.SetPreallocatedEntity(Record[0], MI);
- return MI;
+ if (!PP->getPreprocessingRecord()) {
+ Error("no preprocessing record");
+ return 0;
+ }
+
+ // Read the record.
+ PreprocessingRecord &PPRec = *PP->getPreprocessingRecord();
+ const char *BlobStart = 0;
+ unsigned BlobLen = 0;
+ RecordData Record;
+ PreprocessorDetailRecordTypes RecType =
+ (PreprocessorDetailRecordTypes)F.PreprocessorDetailCursor.ReadRecord(
+ Code, Record, BlobStart, BlobLen);
+ switch (RecType) {
+ case PPD_MACRO_INSTANTIATION: {
+ if (PreprocessedEntity *PE = PPRec.getPreprocessedEntity(Record[0]))
+ return PE;
+
+ MacroInstantiation *MI
+ = new (PPRec) MacroInstantiation(DecodeIdentifierInfo(Record[3]),
+ SourceRange(ReadSourceLocation(F, Record[1]),
+ ReadSourceLocation(F, Record[2])),
+ getMacroDefinition(Record[4]));
+ PPRec.SetPreallocatedEntity(Record[0], MI);
+ return MI;
+ }
+
+ case PPD_MACRO_DEFINITION: {
+ if (PreprocessedEntity *PE = PPRec.getPreprocessedEntity(Record[0]))
+ return PE;
+
+ if (Record[1] > MacroDefinitionsLoaded.size()) {
+ Error("out-of-bounds macro definition record");
+ return 0;
}
-
- case PP_MACRO_DEFINITION: {
- // If we already have a macro, that means that we've hit the end
- // of the definition of the macro we were looking for. We're
- // done.
- if (Macro)
- return 0;
-
- if (!PP->getPreprocessingRecord()) {
- Error("missing preprocessing record in AST file");
- return 0;
- }
-
- PreprocessingRecord &PPRec = *PP->getPreprocessingRecord();
- if (PreprocessedEntity *PE = PPRec.getPreprocessedEntity(Record[0]))
- return PE;
-
- if (Record[1] > MacroDefinitionsLoaded.size()) {
- Error("out-of-bounds macro definition record");
- return 0;
- }
-
- // Decode the identifier info and then check again; if the macro is
- // still defined and associated with the identifier,
- IdentifierInfo *II = DecodeIdentifierInfo(Record[4]);
- if (!MacroDefinitionsLoaded[Record[1] - 1]) {
- MacroDefinition *MD
- = new (PPRec) MacroDefinition(II,
- ReadSourceLocation(F, Record[5]),
- SourceRange(
- ReadSourceLocation(F, Record[2]),
- ReadSourceLocation(F, Record[3])));
-
- PPRec.SetPreallocatedEntity(Record[0], MD);
- MacroDefinitionsLoaded[Record[1] - 1] = MD;
-
- if (DeserializationListener)
- DeserializationListener->MacroDefinitionRead(Record[1], MD);
- }
-
- return MacroDefinitionsLoaded[Record[1] - 1];
+
+ // Decode the identifier info and then check again; if the macro is
+ // still defined and associated with the identifier,
+ IdentifierInfo *II = DecodeIdentifierInfo(Record[4]);
+ if (!MacroDefinitionsLoaded[Record[1] - 1]) {
+ MacroDefinition *MD
+ = new (PPRec) MacroDefinition(II,
+ ReadSourceLocation(F, Record[5]),
+ SourceRange(
+ ReadSourceLocation(F, Record[2]),
+ ReadSourceLocation(F, Record[3])));
+
+ PPRec.SetPreallocatedEntity(Record[0], MD);
+ MacroDefinitionsLoaded[Record[1] - 1] = MD;
+
+ if (DeserializationListener)
+ DeserializationListener->MacroDefinitionRead(Record[1], MD);
}
-
- case PP_INCLUSION_DIRECTIVE: {
- // If we already have a macro, that means that we've hit the end
- // of the definition of the macro we were looking for. We're
- // done.
- if (Macro)
- return 0;
-
- if (!PP->getPreprocessingRecord()) {
- Error("missing preprocessing record in AST file");
- return 0;
- }
-
- PreprocessingRecord &PPRec = *PP->getPreprocessingRecord();
- if (PreprocessedEntity *PE = PPRec.getPreprocessedEntity(Record[0]))
- return PE;
-
- const char *FullFileNameStart = BlobStart + Record[3];
- const FileEntry *File
- = PP->getFileManager().getFile(llvm::StringRef(FullFileNameStart,
- BlobLen - Record[3]));
-
- // FIXME: Stable encoding
- InclusionDirective::InclusionKind Kind
- = static_cast<InclusionDirective::InclusionKind>(Record[5]);
- InclusionDirective *ID
- = new (PPRec) InclusionDirective(PPRec, Kind,
- llvm::StringRef(BlobStart, Record[3]),
- Record[4],
- File,
+
+ return MacroDefinitionsLoaded[Record[1] - 1];
+ }
+
+ case PPD_INCLUSION_DIRECTIVE: {
+ if (PreprocessedEntity *PE = PPRec.getPreprocessedEntity(Record[0]))
+ return PE;
+
+ const char *FullFileNameStart = BlobStart + Record[3];
+ const FileEntry *File
+ = PP->getFileManager().getFile(llvm::StringRef(FullFileNameStart,
+ BlobLen - Record[3]));
+
+ // FIXME: Stable encoding
+ InclusionDirective::InclusionKind Kind
+ = static_cast<InclusionDirective::InclusionKind>(Record[5]);
+ InclusionDirective *ID
+ = new (PPRec) InclusionDirective(PPRec, Kind,
+ llvm::StringRef(BlobStart, Record[3]),
+ Record[4],
+ File,
SourceRange(ReadSourceLocation(F, Record[1]),
ReadSourceLocation(F, Record[2])));
- PPRec.SetPreallocatedEntity(Record[0], ID);
- return ID;
- }
- }
+ PPRec.SetPreallocatedEntity(Record[0], ID);
+ return ID;
+ }
}
+ Error("invalid offset in preprocessor detail block");
return 0;
}
@@ -1600,7 +1602,6 @@ void ASTReader::ReadDefinedMacros() {
RecordData Record;
while (true) {
- uint64_t Offset = Cursor.GetCurrentBitNo();
unsigned Code = Cursor.ReadCode();
if (Code == llvm::bitc::END_BLOCK)
break;
@@ -1636,14 +1637,6 @@ void ASTReader::ReadDefinedMacros() {
case PP_TOKEN:
// Ignore tokens.
break;
-
- case PP_MACRO_INSTANTIATION:
- case PP_MACRO_DEFINITION:
- case PP_INCLUSION_DIRECTIVE:
- // Read the macro record.
- // FIXME: That's a stupid way to do this. We should reuse this cursor.
- ReadMacroRecord(F, Offset);
- break;
}
}
}
@@ -1691,7 +1684,9 @@ MacroDefinition *ASTReader::getMacroDefinition(MacroID ID) {
for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
PerFileData &F = *Chain[N - I - 1];
if (Index < F.LocalNumMacroDefinitions) {
- ReadMacroRecord(F, F.MacroDefinitionOffsets[Index]);
+ SavedStreamPosition SavedPosition(F.PreprocessorDetailCursor);
+ F.PreprocessorDetailCursor.JumpToBit(F.MacroDefinitionOffsets[Index]);
+ LoadPreprocessedEntity(F);
break;
}
Index -= F.LocalNumMacroDefinitions;
@@ -1785,6 +1780,18 @@ ASTReader::ReadASTBlock(PerFileData &F) {
F.MacroStartOffset = F.MacroCursor.GetCurrentBitNo();
break;
+ case PREPROCESSOR_DETAIL_BLOCK_ID:
+ F.PreprocessorDetailCursor = Stream;
+ if (Stream.SkipBlock() ||
+ ReadBlockAbbrevs(F.PreprocessorDetailCursor,
+ PREPROCESSOR_DETAIL_BLOCK_ID)) {
+ Error("malformed preprocessor detail record in AST file");
+ return Failure;
+ }
+ F.PreprocessorDetailStartOffset
+ = F.PreprocessorDetailCursor.GetCurrentBitNo();
+ break;
+
case SOURCE_MANAGER_BLOCK_ID:
switch (ReadSourceManagerBlock(F)) {
case Success:
@@ -2656,7 +2663,15 @@ bool ASTReader::ParseLanguageOptions(
}
void ASTReader::ReadPreprocessedEntities() {
- ReadDefinedMacros();
+ for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+ PerFileData &F = *Chain[I];
+ if (!F.PreprocessorDetailCursor.getBitStreamReader())
+ continue;
+
+ SavedStreamPosition SavedPosition(F.PreprocessorDetailCursor);
+ F.PreprocessorDetailCursor.JumpToBit(F.PreprocessorDetailStartOffset);
+ while (LoadPreprocessedEntity(F)) { }
+ }
}
PreprocessedEntity *ASTReader::ReadPreprocessedEntity(uint64_t Offset) {
@@ -2675,7 +2690,11 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntity(uint64_t Offset) {
return 0;
}
- return ReadMacroRecord(*F, Offset);
+ // Keep track of where we are in the stream, then jump back there
+ // after reading this entity.
+ SavedStreamPosition SavedPosition(F->PreprocessorDetailCursor);
+ F->PreprocessorDetailCursor.JumpToBit(Offset);
+ return LoadPreprocessedEntity(*F);
}
void ASTReader::ReadPragmaDiagnosticMappings(Diagnostic &Diag) {
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 14604a2c2f..fdd5800e9c 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -752,9 +752,6 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(PP_MACRO_OBJECT_LIKE);
RECORD(PP_MACRO_FUNCTION_LIKE);
RECORD(PP_TOKEN);
- RECORD(PP_MACRO_INSTANTIATION);
- RECORD(PP_MACRO_DEFINITION);
- RECORD(PP_INCLUSION_DIRECTIVE);
// Decls and Types block.
BLOCK(DECLTYPES_BLOCK);
@@ -850,6 +847,11 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(DECL_INDIRECTFIELD);
RECORD(DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK);
+ BLOCK(PREPROCESSOR_DETAIL_BLOCK);
+ RECORD(PPD_MACRO_INSTANTIATION);
+ RECORD(PPD_MACRO_DEFINITION);
+ RECORD(PPD_INCLUSION_DIRECTIVE);
+
// Statements and Exprs can occur in the Decls and Types block.
AddStmtsExprs(Stream, Record);
#undef RECORD
@@ -1409,21 +1411,8 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP) {
// Loop over all the macro definitions that are live at the end of the file,
// emitting each to the PP section.
PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
- unsigned InclusionAbbrev = 0;
- if (PPRec) {
- using namespace llvm;
- BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
- Abbrev->Add(BitCodeAbbrevOp(PP_INCLUSION_DIRECTIVE));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // index
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // start location
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // end location
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // filename length
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // in quotes
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // kind
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
- InclusionAbbrev = Stream.EmitAbbrev(Abbrev);
- }
+ // FIXME: If we are chaining, don't visit all of the macros!
for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end();
I != E; ++I) {
// FIXME: This emits macros in hash table order, we should do it in a stable
@@ -1493,82 +1482,109 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP) {
}
++NumMacros;
}
+ Stream.ExitBlock();
+
+ if (PPRec)
+ WritePreprocessorDetail(*PPRec);
+}
+
+void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) {
+ if (PPRec.begin(Chain) == PPRec.end(Chain))
+ return;
+
+ // Enter the preprocessor block.
+ Stream.EnterSubblock(PREPROCESSOR_DETAIL_BLOCK_ID, 3);
// If the preprocessor has a preprocessing record, emit it.
unsigned NumPreprocessingRecords = 0;
- if (PPRec) {
- unsigned IndexBase = Chain ? PPRec->getNumPreallocatedEntities() : 0;
- for (PreprocessingRecord::iterator E = PPRec->begin(Chain),
- EEnd = PPRec->end(Chain);
- E != EEnd; ++E) {
- Record.clear();
+ using namespace llvm;
+
+ // Set up the abbreviation for
+ unsigned InclusionAbbrev = 0;
+ {
+ BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+ Abbrev->Add(BitCodeAbbrevOp(PPD_INCLUSION_DIRECTIVE));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // index
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // start location
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // end location
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // filename length
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // in quotes
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // kind
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+ InclusionAbbrev = Stream.EmitAbbrev(Abbrev);
+ }
+
+ unsigned IndexBase = Chain ? PPRec.getNumPreallocatedEntities() : 0;
+ RecordData Record;
+ for (PreprocessingRecord::iterator E = PPRec.begin(Chain),
+ EEnd = PPRec.end(Chain);
+ E != EEnd; ++E) {
+ Record.clear();
- if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
- // Record this macro definition's location.
- MacroID ID = getMacroDefinitionID(MD);
-
- // Don't write the macro definition if it is from another AST file.
- if (ID < FirstMacroID)
- continue;
-
- // Notify the serialization listener that we're serializing this entity.
- if (SerializationListener)
- SerializationListener->SerializedPreprocessedEntity(*E,
- Stream.GetCurrentBitNo());
-
- unsigned Position = ID - FirstMacroID;
- if (Position != MacroDefinitionOffsets.size()) {
- if (Position > MacroDefinitionOffsets.size())
- MacroDefinitionOffsets.resize(Position + 1);
-
- MacroDefinitionOffsets[Position] = Stream.GetCurrentBitNo();
- } else
- MacroDefinitionOffsets.push_back(Stream.GetCurrentBitNo());
-
- Record.push_back(IndexBase + NumPreprocessingRecords++);
- Record.push_back(ID);
- AddSourceLocation(MD->getSourceRange().getBegin(), Record);
- AddSourceLocation(MD->getSourceRange().getEnd(), Record);
- AddIdentifierRef(MD->getName(), Record);
- AddSourceLocation(MD->getLocation(), Record);
- Stream.EmitRecord(PP_MACRO_DEFINITION, Record);
+ if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
+ // Record this macro definition's location.
+ MacroID ID = getMacroDefinitionID(MD);
+
+ // Don't write the macro definition if it is from another AST file.
+ if (ID < FirstMacroID)
continue;
- }
-
+
// Notify the serialization listener that we're serializing this entity.
if (SerializationListener)
SerializationListener->SerializedPreprocessedEntity(*E,
- Stream.GetCurrentBitNo());
-
- if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
- Record.push_back(IndexBase + NumPreprocessingRecords++);
- AddSourceLocation(MI->getSourceRange().getBegin(), Record);
- AddSourceLocation(MI->getSourceRange().getEnd(), Record);
- AddIdentifierRef(MI->getName(), Record);
- Record.push_back(getMacroDefinitionID(MI->getDefinition()));
- Stream.EmitRecord(PP_MACRO_INSTANTIATION, Record);
- continue;
- }
+ Stream.GetCurrentBitNo());
- if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) {
- Record.push_back(PP_INCLUSION_DIRECTIVE);
- Record.push_back(IndexBase + NumPreprocessingRecords++);
- AddSourceLocation(ID->getSourceRange().getBegin(), Record);
- AddSourceLocation(ID->getSourceRange().getEnd(), Record);
- Record.push_back(ID->getFileName().size());
- Record.push_back(ID->wasInQuotes());
- Record.push_back(static_cast<unsigned>(ID->getKind()));
- llvm::SmallString<64> Buffer;
- Buffer += ID->getFileName();
- Buffer += ID->getFile()->getName();
- Stream.EmitRecordWithBlob(InclusionAbbrev, Record, Buffer);
- continue;
- }
+ unsigned Position = ID - FirstMacroID;
+ if (Position != MacroDefinitionOffsets.size()) {
+ if (Position > MacroDefinitionOffsets.size())
+ MacroDefinitionOffsets.resize(Position + 1);
+
+ MacroDefinitionOffsets[Position] = Stream.GetCurrentBitNo();
+ } else
+ MacroDefinitionOffsets.push_back(Stream.GetCurrentBitNo());
- llvm_unreachable("Unhandled PreprocessedEntity in ASTWriter");
+ Record.push_back(IndexBase + NumPreprocessingRecords++);
+ Record.push_back(ID);
+ AddSourceLocation(MD->getSourceRange().getBegin(), Record);
+ AddSourceLocation(MD->getSourceRange().getEnd(), Record);
+ AddIdentifierRef(MD->getName(), Record);
+ AddSourceLocation(MD->getLocation(), Record);
+ Stream.EmitRecord(PPD_MACRO_DEFINITION, Record);
+ continue;
}
- }
+ // Notify the serialization listener that we're serializing this entity.
+ if (SerializationListener)
+ SerializationListener->SerializedPreprocessedEntity(*E,
+ Stream.GetCurrentBitNo());
+
+ if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
+ Record.push_back(IndexBase + NumPreprocessingRecords++);
+ AddSourceLocation(MI->getSourceRange().getBegin(), Record);
+ AddSourceLocation(MI->getSourceRange().getEnd(), Record);
+ AddIdentifierRef(MI->getName(), Record);
+ Record.push_back(getMacroDefinitionID(MI->getDefinition()));
+ Stream.EmitRecord(PPD_MACRO_INSTANTIATION, Record);
+ continue;
+ }
+
+ if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) {
+ Record.push_back(PPD_INCLUSION_DIRECTIVE);
+ Record.push_back(IndexBase + NumPreprocessingRecords++);
+ AddSourceLocation(ID->getSourceRange().getBegin(), Record);
+ AddSourceLocation(ID->getSourceRange().getEnd(), Record);
+ Record.push_back(ID->getFileName().size());
+ Record.push_back(ID->wasInQuotes());
+ Record.push_back(static_cast<unsigned>(ID->getKind()));
+ llvm::SmallString<64> Buffer;
+ Buffer += ID->getFileName();
+ Buffer += ID->getFile()->getName();
+ Stream.EmitRecordWithBlob(InclusionAbbrev, Record, Buffer);
+ continue;
+ }
+
+ llvm_unreachable("Unhandled PreprocessedEntity in ASTWriter");
+ }
Stream.ExitBlock();
// Write the offsets table for the preprocessing record.