[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