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/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index ad9bfcb..96fc7d6 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -382,7 +382,7 @@
 }
 
 Expr *PCHReader::ReadTypeExpr() {
-  return dyn_cast_or_null<Expr>(ReadStmt(Stream));
+  return dyn_cast_or_null<Expr>(ReadStmt(DeclsCursor));
 }
 
 
@@ -1157,15 +1157,7 @@
 
     if (Code == llvm::bitc::ENTER_SUBBLOCK) {
       switch (Stream.ReadSubBlockID()) {
-      case pch::TYPES_BLOCK_ID: // Skip types block (lazily loaded)
-      default:  // Skip unknown content.
-        if (Stream.SkipBlock()) {
-          Error("malformed block record in PCH file");
-          return Failure;
-        }
-        break;
-
-      case pch::DECLS_BLOCK_ID:
+      case pch::DECLTYPES_BLOCK_ID:
         // We lazily load the decls block, but we want to set up the
         // DeclsCursor cursor to point into it.  Clone our current bitcode
         // cursor to it, enter the block and read the abbrevs in that block.
@@ -1173,7 +1165,7 @@
         DeclsCursor = Stream;
         if (Stream.SkipBlock() ||  // Skip with the main cursor.
             // Read the abbrevs.
-            ReadBlockAbbrevs(DeclsCursor, pch::DECLS_BLOCK_ID)) {
+            ReadBlockAbbrevs(DeclsCursor, pch::DECLTYPES_BLOCK_ID)) {
           Error("malformed block record in PCH file");
           return Failure;
         }
@@ -1773,15 +1765,15 @@
 QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
   // Keep track of where we are in the stream, then jump back there
   // after reading this type.
-  SavedStreamPosition SavedPosition(Stream);
+  SavedStreamPosition SavedPosition(DeclsCursor);
 
   // Note that we are loading a type record.
   LoadingTypeOrDecl Loading(*this);
 
-  Stream.JumpToBit(Offset);
+  DeclsCursor.JumpToBit(Offset);
   RecordData Record;
-  unsigned Code = Stream.ReadCode();
-  switch ((pch::TypeCode)Stream.ReadRecord(Code, Record)) {
+  unsigned Code = DeclsCursor.ReadCode();
+  switch ((pch::TypeCode)DeclsCursor.ReadRecord(Code, Record)) {
   case pch::TYPE_EXT_QUAL: {
     assert(Record.size() == 2 &&
            "Incorrect encoding of extended qualifier type");
@@ -2045,6 +2037,8 @@
   TyLoc.setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
   if (Record[Idx++])
     TyLoc.setSizeExpr(Reader.ReadDeclExpr());
+  else
+    TyLoc.setSizeExpr(0);
 }
 
 DeclaratorInfo *PCHReader::GetDeclaratorInfo(const RecordData &Record,
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 91c47a3..73ce4be 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -461,8 +461,8 @@
   RECORD(PP_MACRO_FUNCTION_LIKE);
   RECORD(PP_TOKEN);
 
-  // Types block.
-  BLOCK(TYPES_BLOCK);
+  // Decls and Types block.
+  BLOCK(DECLTYPES_BLOCK);
   RECORD(TYPE_EXT_QUAL);
   RECORD(TYPE_FIXED_WIDTH_INT);
   RECORD(TYPE_COMPLEX);
@@ -486,11 +486,6 @@
   RECORD(TYPE_OBJC_INTERFACE);
   RECORD(TYPE_OBJC_OBJECT_POINTER);
   RECORD(TYPE_OBJC_PROTOCOL_LIST);
-  // Statements and Exprs can occur in the Types block.
-  AddStmtsExprs(Stream, Record);
-
-  // Decls block.
-  BLOCK(DECLS_BLOCK);
   RECORD(DECL_ATTR);
   RECORD(DECL_TRANSLATION_UNIT);
   RECORD(DECL_TYPEDEF);
@@ -520,7 +515,7 @@
   RECORD(DECL_BLOCK);
   RECORD(DECL_CONTEXT_LEXICAL);
   RECORD(DECL_CONTEXT_VISIBLE);
-  // Statements and Exprs can occur in the Decls block.
+  // Statements and Exprs can occur in the Decls and Types block.
   AddStmtsExprs(Stream, Record);
 #undef RECORD
 #undef BLOCK
@@ -1201,22 +1196,6 @@
   FlushStmts();
 }
 
-/// \brief Write a block containing all of the types.
-void PCHWriter::WriteTypesBlock(ASTContext &Context) {
-  // Enter the types block.
-  Stream.EnterSubblock(pch::TYPES_BLOCK_ID, 2);
-
-  // Emit all of the types that need to be emitted (so far).
-  while (!TypesToEmit.empty()) {
-    QualType T = TypesToEmit.front();
-    TypesToEmit.pop();
-    WriteType(T);
-  }
-
-  // Exit the types block
-  Stream.ExitBlock();
-}
-
 //===----------------------------------------------------------------------===//
 // Declaration Serialization
 //===----------------------------------------------------------------------===//
@@ -1859,7 +1838,7 @@
 
   // The translation unit is the first declaration we'll emit.
   DeclIDs[Context.getTranslationUnitDecl()] = 1;
-  DeclsToEmit.push(Context.getTranslationUnitDecl());
+  DeclTypesToEmit.push(Context.getTranslationUnitDecl());
 
   // Make sure that we emit IdentifierInfos (and any attached
   // declarations) for builtins.
@@ -1928,13 +1907,18 @@
 
   // Keep writing types and declarations until all types and
   // declarations have been written.
-  do {
-    if (!DeclsToEmit.empty())
-      WriteDeclsBlock(Context);
-    if (!TypesToEmit.empty())
-      WriteTypesBlock(Context);
-  } while (!(DeclsToEmit.empty() && TypesToEmit.empty()));
-
+  Stream.EnterSubblock(pch::DECLTYPES_BLOCK_ID, 3);
+  WriteDeclsBlockAbbrevs();
+  while (!DeclTypesToEmit.empty()) {
+    DeclOrType DOT = DeclTypesToEmit.front();
+    DeclTypesToEmit.pop();
+    if (DOT.isType())
+      WriteType(DOT.getType());
+    else
+      WriteDecl(Context, DOT.getDecl());
+  }
+  Stream.ExitBlock();
+  
   WriteMethodPool(SemaRef);
   WriteIdentifierTable(PP);
 
@@ -2068,7 +2052,7 @@
       // Assign it a new ID.  This is the only time we enqueue a
       // qualified type, and it has no CV qualifiers.
       ID = NextTypeID++;
-      TypesToEmit.push(T);
+      DeclTypesToEmit.push(T);
     }
     
     // Encode the type qualifiers in the type reference.
@@ -2122,7 +2106,7 @@
     // We haven't seen this type before. Assign it a new ID and put it
     // into the queue of types to emit.
     ID = NextTypeID++;
-    TypesToEmit.push(T);
+    DeclTypesToEmit.push(T);
   }
 
   // Encode the type qualifiers in the type reference.
@@ -2140,7 +2124,7 @@
     // We haven't seen this declaration before. Give it a new ID and
     // enqueue it in the list of declarations to emit.
     ID = DeclIDs.size();
-    DeclsToEmit.push(const_cast<Decl *>(D));
+    DeclTypesToEmit.push(const_cast<Decl *>(D));
   }
 
   Record.push_back(ID);
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);
 }