diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-07-06 15:36:58 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-07-06 15:36:58 +0000 |
commit | 0f47bb98cbc52a6ead2aef8a2f8315c0b6167e6c (patch) | |
tree | 1534bed8b27cfb07ac08fe4997515c2492198136 /lib/Frontend/PCHWriterDecl.cpp | |
parent | 74228274ba9b27a26a311010b02c371f558e3bfc (diff) |
Allow a CXXRecordDecl to get a DefinitionData pointer even when its owner is still initializing.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107663 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Frontend/PCHWriterDecl.cpp')
-rw-r--r-- | lib/Frontend/PCHWriterDecl.cpp | 95 |
1 files changed, 55 insertions, 40 deletions
diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp index f1adc5b6fc..2dc59726ea 100644 --- a/lib/Frontend/PCHWriterDecl.cpp +++ b/lib/Frontend/PCHWriterDecl.cpp @@ -659,48 +659,63 @@ void PCHDeclWriter::VisitUnresolvedUsingTypenameDecl( } 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 { |