[cfe-commits] r107663 - in /cfe/trunk/lib/Frontend: PCHReaderDecl.cpp PCHWriterDecl.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Tue Jul 6 08:36:58 PDT 2010


Author: akirtzidis
Date: Tue Jul  6 10:36:58 2010
New Revision: 107663

URL: http://llvm.org/viewvc/llvm-project?rev=107663&view=rev
Log:
Allow a CXXRecordDecl to get a DefinitionData pointer even when its owner is still initializing.

Modified:
    cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
    cfe/trunk/lib/Frontend/PCHWriterDecl.cpp

Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=107663&r1=107662&r2=107663&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Tue Jul  6 10:36:58 2010
@@ -655,55 +655,71 @@
 }
 
 void PCHDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) {
-  VisitRecordDecl(D);
-
   ASTContext &C = *Reader.getContext();
 
-  if (D->isFirstDeclaration()) {
-    if (Record[Idx++]) { // DefinitionData != 0
-      D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(0);
-      struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData;
-
-      Data.UserDeclaredConstructor = Record[Idx++];
-      Data.UserDeclaredCopyConstructor = Record[Idx++];
-      Data.UserDeclaredCopyAssignment = Record[Idx++];
-      Data.UserDeclaredDestructor = Record[Idx++];
-      Data.Aggregate = Record[Idx++];
-      Data.PlainOldData = Record[Idx++];
-      Data.Empty = Record[Idx++];
-      Data.Polymorphic = Record[Idx++];
-      Data.Abstract = Record[Idx++];
-      Data.HasTrivialConstructor = Record[Idx++];
-      Data.HasTrivialCopyConstructor = Record[Idx++];
-      Data.HasTrivialCopyAssignment = Record[Idx++];
-      Data.HasTrivialDestructor = Record[Idx++];
-      Data.ComputedVisibleConversions = Record[Idx++];
-      Data.DeclaredDefaultConstructor = Record[Idx++];
-      Data.DeclaredCopyConstructor = Record[Idx++];
-      Data.DeclaredCopyAssignment = Record[Idx++];
-      Data.DeclaredDestructor = Record[Idx++];
-
-      // setBases() is unsuitable since it may try to iterate the bases of an
-      // unitialized base.
-      Data.NumBases = Record[Idx++];
-      Data.Bases = new(C) CXXBaseSpecifier [Data.NumBases];
-      for (unsigned i = 0; i != Data.NumBases; ++i)
-        Data.Bases[i] = Reader.ReadCXXBaseSpecifier(Record, Idx);
-
-      // FIXME: Make VBases lazily computed when needed to avoid storing them.
-      Data.NumVBases = Record[Idx++];
-      Data.VBases = new(C) CXXBaseSpecifier [Data.NumVBases];
-      for (unsigned i = 0; i != Data.NumVBases; ++i)
-        Data.VBases[i] = Reader.ReadCXXBaseSpecifier(Record, Idx);
-
-      Reader.ReadUnresolvedSet(Data.Conversions, Record, Idx);
-      Reader.ReadUnresolvedSet(Data.VisibleConversions, Record, Idx);
-      Data.Definition = cast<CXXRecordDecl>(Reader.GetDecl(Record[Idx++]));
-      Data.FirstFriend
-          = cast_or_null<FriendDecl>(Reader.GetDecl(Record[Idx++]));
-    }
-  } else {
-    D->DefinitionData = D->getPreviousDeclaration()->DefinitionData;
+  // We need to allocate the DefinitionData struct ahead of VisitRecordDecl
+  // so that the other CXXRecordDecls can get a pointer even when the owner
+  // is still initializing.
+  bool OwnsDefinitionData = false;
+  enum DataOwnership { Data_NoDefData, Data_Owner, Data_NotOwner };
+  switch ((DataOwnership)Record[Idx++]) {
+  default:
+    assert(0 && "Out of sync with PCHDeclWriter or messed up reading");
+  case Data_NoDefData:
+    break;
+  case Data_Owner:
+    OwnsDefinitionData = true;
+    D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(D);
+    break;
+  case Data_NotOwner:
+    D->DefinitionData
+        = cast<CXXRecordDecl>(Reader.GetDecl(Record[Idx++]))->DefinitionData;
+    break;
+  }
+
+  VisitRecordDecl(D);
+
+  if (OwnsDefinitionData) {
+    assert(D->DefinitionData);
+    struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData;
+
+    Data.UserDeclaredConstructor = Record[Idx++];
+    Data.UserDeclaredCopyConstructor = Record[Idx++];
+    Data.UserDeclaredCopyAssignment = Record[Idx++];
+    Data.UserDeclaredDestructor = Record[Idx++];
+    Data.Aggregate = Record[Idx++];
+    Data.PlainOldData = Record[Idx++];
+    Data.Empty = Record[Idx++];
+    Data.Polymorphic = Record[Idx++];
+    Data.Abstract = Record[Idx++];
+    Data.HasTrivialConstructor = Record[Idx++];
+    Data.HasTrivialCopyConstructor = Record[Idx++];
+    Data.HasTrivialCopyAssignment = Record[Idx++];
+    Data.HasTrivialDestructor = Record[Idx++];
+    Data.ComputedVisibleConversions = Record[Idx++];
+    Data.DeclaredDefaultConstructor = Record[Idx++];
+    Data.DeclaredCopyConstructor = Record[Idx++];
+    Data.DeclaredCopyAssignment = Record[Idx++];
+    Data.DeclaredDestructor = Record[Idx++];
+
+    // setBases() is unsuitable since it may try to iterate the bases of an
+    // unitialized base.
+    Data.NumBases = Record[Idx++];
+    Data.Bases = new(C) CXXBaseSpecifier [Data.NumBases];
+    for (unsigned i = 0; i != Data.NumBases; ++i)
+      Data.Bases[i] = Reader.ReadCXXBaseSpecifier(Record, Idx);
+
+    // FIXME: Make VBases lazily computed when needed to avoid storing them.
+    Data.NumVBases = Record[Idx++];
+    Data.VBases = new(C) CXXBaseSpecifier [Data.NumVBases];
+    for (unsigned i = 0; i != Data.NumVBases; ++i)
+      Data.VBases[i] = Reader.ReadCXXBaseSpecifier(Record, Idx);
+
+    Reader.ReadUnresolvedSet(Data.Conversions, Record, Idx);
+    Reader.ReadUnresolvedSet(Data.VisibleConversions, Record, Idx);
+    assert(Data.Definition && "Data.Definition should be already set!");
+    Data.FirstFriend
+        = cast_or_null<FriendDecl>(Reader.GetDecl(Record[Idx++]));
   }
 
   enum CXXRecKind {

Modified: cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterDecl.cpp?rev=107663&r1=107662&r2=107663&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterDecl.cpp Tue Jul  6 10:36:58 2010
@@ -659,48 +659,63 @@
 }
 
 void PCHDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) {
+  // See comments at PCHDeclReader::VisitCXXRecordDecl about why this happens
+  // before VisitRecordDecl.
+  enum { Data_NoDefData, Data_Owner, Data_NotOwner };
+  bool OwnsDefinitionData = false;
+  if (D->DefinitionData) {
+    assert(D->DefinitionData->Definition &&
+           "DefinitionData don't point to a definition decl!");
+    OwnsDefinitionData = D->DefinitionData->Definition == D;
+    if (OwnsDefinitionData) {
+      Record.push_back(Data_Owner);
+    } else {
+      Record.push_back(Data_NotOwner);
+      Writer.AddDeclRef(D->DefinitionData->Definition, Record);
+    }
+  } else
+    Record.push_back(Data_NoDefData);
+
   VisitRecordDecl(D);
 
-  if (D->isFirstDeclaration()) {
-    Record.push_back(D->DefinitionData != 0);
-    if (D->DefinitionData) {
-      struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData;
-
-      Record.push_back(Data.UserDeclaredConstructor);
-      Record.push_back(Data.UserDeclaredCopyConstructor);
-      Record.push_back(Data.UserDeclaredCopyAssignment);
-      Record.push_back(Data.UserDeclaredDestructor);
-      Record.push_back(Data.Aggregate);
-      Record.push_back(Data.PlainOldData);
-      Record.push_back(Data.Empty);
-      Record.push_back(Data.Polymorphic);
-      Record.push_back(Data.Abstract);
-      Record.push_back(Data.HasTrivialConstructor);
-      Record.push_back(Data.HasTrivialCopyConstructor);
-      Record.push_back(Data.HasTrivialCopyAssignment);
-      Record.push_back(Data.HasTrivialDestructor);
-      Record.push_back(Data.ComputedVisibleConversions);
-      Record.push_back(Data.DeclaredDefaultConstructor);
-      Record.push_back(Data.DeclaredCopyConstructor);
-      Record.push_back(Data.DeclaredCopyAssignment);
-      Record.push_back(Data.DeclaredDestructor);
-
-      Record.push_back(D->getNumBases());
-      for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
-             E = D->bases_end(); I != E; ++I)
-        Writer.AddCXXBaseSpecifier(*I, Record);
-
-      // FIXME: Make VBases lazily computed when needed to avoid storing them.
-      Record.push_back(D->getNumVBases());
-      for (CXXRecordDecl::base_class_iterator I = D->vbases_begin(),
-             E = D->vbases_end(); I != E; ++I)
-        Writer.AddCXXBaseSpecifier(*I, Record);
-
-      Writer.AddUnresolvedSet(Data.Conversions, Record);
-      Writer.AddUnresolvedSet(Data.VisibleConversions, Record);
-      Writer.AddDeclRef(Data.Definition, Record);
-      Writer.AddDeclRef(Data.FirstFriend, Record);
-    }
+  if (OwnsDefinitionData) {
+    assert(D->DefinitionData);
+    struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData;
+
+    Record.push_back(Data.UserDeclaredConstructor);
+    Record.push_back(Data.UserDeclaredCopyConstructor);
+    Record.push_back(Data.UserDeclaredCopyAssignment);
+    Record.push_back(Data.UserDeclaredDestructor);
+    Record.push_back(Data.Aggregate);
+    Record.push_back(Data.PlainOldData);
+    Record.push_back(Data.Empty);
+    Record.push_back(Data.Polymorphic);
+    Record.push_back(Data.Abstract);
+    Record.push_back(Data.HasTrivialConstructor);
+    Record.push_back(Data.HasTrivialCopyConstructor);
+    Record.push_back(Data.HasTrivialCopyAssignment);
+    Record.push_back(Data.HasTrivialDestructor);
+    Record.push_back(Data.ComputedVisibleConversions);
+    Record.push_back(Data.DeclaredDefaultConstructor);
+    Record.push_back(Data.DeclaredCopyConstructor);
+    Record.push_back(Data.DeclaredCopyAssignment);
+    Record.push_back(Data.DeclaredDestructor);
+
+    Record.push_back(D->getNumBases());
+    for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
+           E = D->bases_end(); I != E; ++I)
+      Writer.AddCXXBaseSpecifier(*I, Record);
+
+    // FIXME: Make VBases lazily computed when needed to avoid storing them.
+    Record.push_back(D->getNumVBases());
+    for (CXXRecordDecl::base_class_iterator I = D->vbases_begin(),
+           E = D->vbases_end(); I != E; ++I)
+      Writer.AddCXXBaseSpecifier(*I, Record);
+
+    Writer.AddUnresolvedSet(Data.Conversions, Record);
+    Writer.AddUnresolvedSet(Data.VisibleConversions, Record);
+    // Data.Definition is written at the top. 
+    Writer.AddDeclRef(Data.FirstFriend, Record);
   }
 
   enum {





More information about the cfe-commits mailing list