Merge the "types" and "declarations" blocks in the precompiled header
format, so that we don't end up with multiple declaration and types
blocks. Also, fix a few obscure bugs with PCH loading and generation:
- If the DeclIDs DenseMap reallocates while we are writing a
declaration (due to recursively writing other declarations), we
could end up writing a bad ID to ExternalDefinitions.
- When loading an ArrayLoc (part of DeclaratorInfo), we need to set
the size expression to NULL if no size expression was provided.
PCH -> AST rewriting is still partly broken, unfortunately.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84293 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp
index 73598ab..fbd9929 100644
--- a/lib/Frontend/PCHWriterDecl.cpp
+++ b/lib/Frontend/PCHWriterDecl.cpp
@@ -535,80 +535,64 @@
}
}
-/// \brief Write a block containing all of the declarations.
-void PCHWriter::WriteDeclsBlock(ASTContext &Context) {
- // Enter the declarations block.
- Stream.EnterSubblock(pch::DECLS_BLOCK_ID, 3);
-
- // Output the abbreviations that we will use in this block.
- WriteDeclsBlockAbbrevs();
-
- // Emit all of the declarations.
+void PCHWriter::WriteDecl(ASTContext &Context, Decl *D) {
RecordData Record;
PCHDeclWriter W(*this, Context, Record);
- while (!DeclsToEmit.empty()) {
- // Pull the next declaration off the queue
- Decl *D = DeclsToEmit.front();
- DeclsToEmit.pop();
- // If this declaration is also a DeclContext, write blocks for the
- // declarations that lexically stored inside its context and those
- // declarations that are visible from its context. These blocks
- // are written before the declaration itself so that we can put
- // their offsets into the record for the declaration.
- uint64_t LexicalOffset = 0;
- uint64_t VisibleOffset = 0;
- DeclContext *DC = dyn_cast<DeclContext>(D);
- if (DC) {
- LexicalOffset = WriteDeclContextLexicalBlock(Context, DC);
- VisibleOffset = WriteDeclContextVisibleBlock(Context, DC);
- }
-
- // Determine the ID for this declaration
- pch::DeclID &ID = DeclIDs[D];
- if (ID == 0)
- ID = DeclIDs.size();
-
- unsigned Index = ID - 1;
-
- // Record the offset for this declaration
- if (DeclOffsets.size() == Index)
- DeclOffsets.push_back(Stream.GetCurrentBitNo());
- else if (DeclOffsets.size() < Index) {
- DeclOffsets.resize(Index+1);
- DeclOffsets[Index] = Stream.GetCurrentBitNo();
- }
-
- // Build and emit a record for this declaration
- Record.clear();
- W.Code = (pch::DeclCode)0;
- W.AbbrevToUse = 0;
- W.Visit(D);
- if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset);
-
- if (!W.Code) {
- fprintf(stderr, "Cannot serialize declaration of kind %s\n",
- D->getDeclKindName());
- assert(false && "Unhandled declaration kind while generating PCH");
- exit(-1);
- }
- Stream.EmitRecord(W.Code, Record, W.AbbrevToUse);
-
- // If the declaration had any attributes, write them now.
- if (D->hasAttrs())
- WriteAttributeRecord(D->getAttrs());
-
- // Flush any expressions that were written as part of this declaration.
- FlushStmts();
-
- // Note "external" declarations so that we can add them to a record in the
- // PCH file later.
- //
- // FIXME: This should be renamed, the predicate is much more complicated.
- if (isRequiredDecl(D, Context))
- ExternalDefinitions.push_back(ID);
+ // If this declaration is also a DeclContext, write blocks for the
+ // declarations that lexically stored inside its context and those
+ // declarations that are visible from its context. These blocks
+ // are written before the declaration itself so that we can put
+ // their offsets into the record for the declaration.
+ uint64_t LexicalOffset = 0;
+ uint64_t VisibleOffset = 0;
+ DeclContext *DC = dyn_cast<DeclContext>(D);
+ if (DC) {
+ LexicalOffset = WriteDeclContextLexicalBlock(Context, DC);
+ VisibleOffset = WriteDeclContextVisibleBlock(Context, DC);
}
- // Exit the declarations block
- Stream.ExitBlock();
+ // Determine the ID for this declaration
+ pch::DeclID &ID = DeclIDs[D];
+ if (ID == 0)
+ ID = DeclIDs.size();
+
+ unsigned Index = ID - 1;
+
+ // Record the offset for this declaration
+ if (DeclOffsets.size() == Index)
+ DeclOffsets.push_back(Stream.GetCurrentBitNo());
+ else if (DeclOffsets.size() < Index) {
+ DeclOffsets.resize(Index+1);
+ DeclOffsets[Index] = Stream.GetCurrentBitNo();
+ }
+
+ // Build and emit a record for this declaration
+ Record.clear();
+ W.Code = (pch::DeclCode)0;
+ W.AbbrevToUse = 0;
+ W.Visit(D);
+ if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset);
+
+ if (!W.Code) {
+ fprintf(stderr, "Cannot serialize declaration of kind %s\n",
+ D->getDeclKindName());
+ assert(false && "Unhandled declaration kind while generating PCH");
+ exit(-1);
+ }
+ Stream.EmitRecord(W.Code, Record, W.AbbrevToUse);
+
+ // If the declaration had any attributes, write them now.
+ if (D->hasAttrs())
+ WriteAttributeRecord(D->getAttrs());
+
+ // Flush any expressions that were written as part of this declaration.
+ FlushStmts();
+
+ // Note "external" declarations so that we can add them to a record in the
+ // PCH file later.
+ //
+ // FIXME: This should be renamed, the predicate is much more complicated.
+ if (isRequiredDecl(D, Context))
+ ExternalDefinitions.push_back(Index + 1);
}