PCH support for record decls/types and their fields. Now that we can
handle the definition of __builtin_va_list on x86-64, eliminate the
forced -triple in PCH tests to get better coverage.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68988 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index f735dd9..adb4e5f 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -50,8 +50,10 @@
     void VisitTypedefDecl(TypedefDecl *TD);
     void VisitTagDecl(TagDecl *TD);
     void VisitEnumDecl(EnumDecl *ED);
+    void VisitRecordDecl(RecordDecl *RD);
     void VisitValueDecl(ValueDecl *VD);
     void VisitEnumConstantDecl(EnumConstantDecl *ECD);
+    void VisitFieldDecl(FieldDecl *FD);
     void VisitVarDecl(VarDecl *VD);
 
     std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
@@ -106,6 +108,12 @@
   ED->setIntegerType(Reader.GetType(Record[Idx++]));
 }
 
+void PCHDeclReader::VisitRecordDecl(RecordDecl *RD) {
+  VisitTagDecl(RD);
+  RD->setHasFlexibleArrayMember(Record[Idx++]);
+  RD->setAnonymousStructOrUnion(Record[Idx++]);
+}
+
 void PCHDeclReader::VisitValueDecl(ValueDecl *VD) {
   VisitNamedDecl(VD);
   VD->setType(Reader.GetType(Record[Idx++]));
@@ -113,10 +121,16 @@
 
 void PCHDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) {
   VisitValueDecl(ECD);
-  // FIXME: initialization expression
+  // FIXME: read the initialization expression
   ECD->setInitVal(Reader.ReadAPSInt(Record, Idx));
 }
 
+void PCHDeclReader::VisitFieldDecl(FieldDecl *FD) {
+  VisitValueDecl(FD);
+  FD->setMutable(Record[Idx++]);
+  // FIXME: Read the bit width.
+}
+
 void PCHDeclReader::VisitVarDecl(VarDecl *VD) {
   VisitValueDecl(VD);
   VD->setStorageClass((VarDecl::StorageClass)Record[Idx++]);
@@ -911,9 +925,8 @@
   }
     
   case pch::TYPE_RECORD:
-    // FIXME: Deserialize RecordType
-    assert(false && "Cannot de-serialize record types yet");
-    return QualType();
+    assert(Record.size() == 1 && "Incorrect encoding of record type");
+    return Context.getTypeDeclType(cast<RecordDecl>(GetDecl(Record[0])));
 
   case pch::TYPE_ENUM:
     assert(Record.size() == 1 && "Incorrect encoding of enum type");
@@ -989,6 +1002,15 @@
     break;
   }
 
+  case pch::DECL_RECORD: {
+    RecordDecl *Record = RecordDecl::Create(Context, TagDecl::TK_struct, 
+                                            0, SourceLocation(), 0, 0);
+    LoadedDecl(Index, Record);
+    Reader.VisitRecordDecl(Record);
+    D = Record;
+    break;
+  }
+
   case pch::DECL_ENUM_CONSTANT: {
     EnumConstantDecl *ECD = EnumConstantDecl::Create(Context, 0, 
                                                      SourceLocation(), 0,
@@ -1000,6 +1022,15 @@
     break;
   }
 
+  case pch::DECL_FIELD: {
+    FieldDecl *Field = FieldDecl::Create(Context, 0, SourceLocation(), 0,
+                                         QualType(), 0, false);
+    LoadedDecl(Index, Field);
+    Reader.VisitFieldDecl(Field);
+    D = Field;
+    break;
+  }
+
   case pch::DECL_VAR: {
     VarDecl *Var = VarDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
                                    VarDecl::None, SourceLocation());
@@ -1132,12 +1163,10 @@
   Decls.clear();
 
   unsigned Idx = 0;
-  //  llvm::SmallVector<uintptr_t, 16> DeclIDs;
   while (Idx < Record.size()) {
     Decls.push_back(VisibleDeclaration());
     Decls.back().Name = ReadDeclarationName(Record, Idx);
 
-    // FIXME: Don't actually read anything here!
     unsigned Size = Record[Idx++];
     llvm::SmallVector<unsigned, 4> & LoadedDecls
       = Decls.back().Declarations;