aboutsummaryrefslogtreecommitdiff
path: root/lib/Frontend
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Frontend')
-rw-r--r--lib/Frontend/PCHReader.cpp11
-rw-r--r--lib/Frontend/PCHReaderDecl.cpp80
-rw-r--r--lib/Frontend/PCHWriter.cpp11
-rw-r--r--lib/Frontend/PCHWriterDecl.cpp50
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;
}