diff options
Diffstat (limited to 'lib/Frontend')
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 11 | ||||
-rw-r--r-- | lib/Frontend/PCHReaderDecl.cpp | 80 | ||||
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 11 | ||||
-rw-r--r-- | lib/Frontend/PCHWriterDecl.cpp | 50 |
4 files changed, 109 insertions, 43 deletions
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 811db509af..5f00c677ba 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -3090,6 +3090,17 @@ ReadTemplateArgumentList(llvm::SmallVector<TemplateArgument, 8> &TemplArgs, TemplArgs.push_back(ReadTemplateArgument(Record, Idx)); } +/// \brief Read a UnresolvedSet structure. +void PCHReader::ReadUnresolvedSet(UnresolvedSetImpl &Set, + const RecordData &Record, unsigned &Idx) { + unsigned NumDecls = Record[Idx++]; + while (NumDecls--) { + NamedDecl *D = cast<NamedDecl>(GetDecl(Record[Idx++])); + AccessSpecifier AS = (AccessSpecifier)Record[Idx++]; + Set.addDecl(D, AS); + } +} + NestedNameSpecifier * PCHReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) { unsigned N = Record[Idx++]; diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index 443842d342..ea99ff249d 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -39,7 +39,7 @@ namespace clang { unsigned &Idx) : Reader(Reader), Record(Record), Idx(Idx), TypeIDForTypeDecl(0) { } - CXXBaseSpecifier *ReadCXXBaseSpecifier(); + CXXBaseSpecifier ReadCXXBaseSpecifier(); void Visit(Decl *D); @@ -628,20 +628,63 @@ void PCHDeclReader::VisitUnresolvedUsingTypenameDecl( D->setTargetNestedNameSpecifier(Reader.ReadNestedNameSpecifier(Record, Idx)); } -CXXBaseSpecifier *PCHDeclReader::ReadCXXBaseSpecifier() { +CXXBaseSpecifier PCHDeclReader::ReadCXXBaseSpecifier() { bool isVirtual = static_cast<bool>(Record[Idx++]); bool isBaseOfClass = static_cast<bool>(Record[Idx++]); AccessSpecifier AS = static_cast<AccessSpecifier>(Record[Idx++]); QualType T = Reader.GetType(Record[Idx++]); SourceRange Range = Reader.ReadSourceRange(Record, Idx); - return new (*Reader.getContext()) - CXXBaseSpecifier(Range, isVirtual, isBaseOfClass, AS, T); + return CXXBaseSpecifier(Range, isVirtual, isBaseOfClass, AS, T); } void PCHDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) { - // assert(false && "cannot read CXXRecordDecl"); 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++]; + + // 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] = ReadCXXBaseSpecifier(); + + // 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] = ReadCXXBaseSpecifier(); + + 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; + } + enum CXXRecKind { CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization }; @@ -663,31 +706,6 @@ void PCHDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) { break; } } - - // FIXME: Hack. See PCHDeclWriter::VisitTypeDecl. - D->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr()); - - // FIXME: this is far from complete - - if (D->isDefinition()) { - D->setDefinition(false); // make peace with an assertion - D->startDefinition(); - - unsigned NumBases = Record[Idx++]; - - llvm::SmallVector<CXXBaseSpecifier*, 4> Bases; - Bases.reserve(NumBases); - for (unsigned I = 0; I != NumBases; ++I) - Bases.push_back(ReadCXXBaseSpecifier()); - D->setBases(Bases.begin(), NumBases); - - D->data().FirstFriend - = cast_or_null<FriendDecl>(Reader.GetDecl(Record[Idx++])); - - // FIXME: there's a lot of stuff we do here that's kindof sketchy - // if we're leaving the context incomplete. - D->completeDefinition(); - } } void PCHDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) { diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 99d228b6c0..65e8849adb 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -2621,3 +2621,14 @@ PCHWriter::AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs, for (int i=0, e = TemplateArgs->flat_size(); i != e; ++i) AddTemplateArgument(TemplateArgs->get(i), Record); } + + +void +PCHWriter::AddUnresolvedSet(const UnresolvedSetImpl &Set, RecordData &Record) { + Record.push_back(Set.size()); + for (UnresolvedSetImpl::const_iterator + I = Set.begin(), E = Set.end(); I != E; ++I) { + AddDeclRef(I.getDecl(), Record); + Record.push_back(I.getAccess()); + } +} diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp index 000c2d8ba8..86af50b0bc 100644 --- a/lib/Frontend/PCHWriterDecl.cpp +++ b/lib/Frontend/PCHWriterDecl.cpp @@ -632,6 +632,44 @@ void PCHDeclWriter::WriteCXXBaseSpecifier(const CXXBaseSpecifier *Base) { void PCHDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) { 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(D->getNumBases()); + for (CXXRecordDecl::base_class_iterator I = D->bases_begin(), + E = D->bases_end(); I != E; ++I) + WriteCXXBaseSpecifier(&*I); + + // 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) + WriteCXXBaseSpecifier(&*I); + + Writer.AddUnresolvedSet(Data.Conversions, Record); + Writer.AddUnresolvedSet(Data.VisibleConversions, Record); + Writer.AddDeclRef(Data.Definition, Record); + Writer.AddDeclRef(Data.FirstFriend, Record); + } + } + enum { CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization }; @@ -648,18 +686,6 @@ void PCHDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) { Record.push_back(CXXRecNotTemplate); } - // FIXME: Hack. See PCHDeclWriter::VisitTypeDecl. - Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record); - - if (D->isDefinition()) { - unsigned NumBases = D->getNumBases(); - Record.push_back(NumBases); - for (CXXRecordDecl::base_class_iterator I = D->bases_begin(), - E = D->bases_end(); I != E; ++I) - WriteCXXBaseSpecifier(&*I); - - Writer.AddDeclRef(D->data().FirstFriend, Record); - } Code = pch::DECL_CXX_RECORD; } |