[cfe-commits] r107483 - in /cfe/trunk: include/clang/AST/DeclCXX.h lib/Frontend/PCHReaderDecl.cpp lib/Frontend/PCHWriterDecl.cpp
Argyrios Kyrtzidis
akyrtzi at gmail.com
Fri Jul 2 08:58:43 PDT 2010
Author: akirtzidis
Date: Fri Jul 2 10:58:43 2010
New Revision: 107483
URL: http://llvm.org/viewvc/llvm-project?rev=107483&view=rev
Log:
Handle CXXConstructorDecl, CXXDestructorDecl, and CXXConversionDecl for PCH.
<vector> header can be used correctly through PCH now.
Modified:
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=107483&r1=107482&r2=107483&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Fri Jul 2 10:58:43 2010
@@ -1455,6 +1455,9 @@
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXConstructorDecl *D) { return true; }
static bool classofKind(Kind K) { return K == CXXConstructor; }
+
+ friend class PCHDeclReader;
+ friend class PCHDeclWriter;
};
/// CXXDestructorDecl - Represents a C++ destructor within a
@@ -1518,6 +1521,9 @@
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXDestructorDecl *D) { return true; }
static bool classofKind(Kind K) { return K == CXXDestructor; }
+
+ friend class PCHDeclReader;
+ friend class PCHDeclWriter;
};
/// CXXConversionDecl - Represents a C++ conversion function within a
@@ -1572,6 +1578,9 @@
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXConversionDecl *D) { return true; }
static bool classofKind(Kind K) { return K == CXXConversion; }
+
+ friend class PCHDeclReader;
+ friend class PCHDeclWriter;
};
/// LinkageSpecDecl - This represents a linkage specification. For example:
Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=107483&r1=107482&r2=107483&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Fri Jul 2 10:58:43 2010
@@ -113,9 +113,14 @@
void PCHDeclReader::Visit(Decl *D) {
DeclVisitor<PCHDeclReader, void>::Visit(D);
- // if we have a fully initialized TypeDecl, we can safely read its type now.
- if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
+ if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) {
+ // if we have a fully initialized TypeDecl, we can safely read its type now.
TD->setTypeForDecl(Reader.GetType(TypeIDForTypeDecl).getTypePtr());
+ } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ // FunctionDecl's body was written last after all other Stmts/Exprs.
+ if (Record[Idx++])
+ FD->setLazyBody(Reader.getDeclsCursor().GetCurrentBitNo());
+ }
}
void PCHDeclReader::VisitDecl(Decl *D) {
@@ -272,8 +277,9 @@
}
}
- if (Record[Idx++])
- FD->setLazyBody(Reader.getDeclsCursor().GetCurrentBitNo());
+ // FunctionDecl's body is handled last at PCHReaderDecl::Visit,
+ // after everything else is read.
+
FD->setPreviousDeclaration(
cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++])));
FD->setStorageClass((FunctionDecl::StorageClass)Record[Idx++]);
@@ -710,23 +716,83 @@
}
void PCHDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {
- // assert(false && "cannot read CXXMethodDecl");
VisitFunctionDecl(D);
}
void PCHDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
- // assert(false && "cannot read CXXConstructorDecl");
VisitCXXMethodDecl(D);
+
+ D->IsExplicitSpecified = Record[Idx++];
+ D->ImplicitlyDefined = Record[Idx++];
+
+ unsigned NumInitializers = Record[Idx++];
+ D->NumBaseOrMemberInitializers = NumInitializers;
+ if (NumInitializers) {
+ ASTContext &C = *Reader.getContext();
+
+ D->BaseOrMemberInitializers
+ = new (C) CXXBaseOrMemberInitializer*[NumInitializers];
+ for (unsigned i=0; i != NumInitializers; ++i) {
+ TypeSourceInfo *BaseClassInfo;
+ bool IsBaseVirtual;
+ FieldDecl *Member;
+
+ bool IsBaseInitializer = Record[Idx++];
+ if (IsBaseInitializer) {
+ BaseClassInfo = Reader.GetTypeSourceInfo(Record, Idx);
+ IsBaseVirtual = Record[Idx++];
+ } else {
+ Member = cast<FieldDecl>(Reader.GetDecl(Record[Idx++]));
+ }
+ SourceLocation MemberLoc = Reader.ReadSourceLocation(Record, Idx);
+ Expr *Init = Reader.ReadExpr();
+ FieldDecl *AnonUnionMember
+ = cast_or_null<FieldDecl>(Reader.GetDecl(Record[Idx++]));
+ SourceLocation LParenLoc = Reader.ReadSourceLocation(Record, Idx);
+ SourceLocation RParenLoc = Reader.ReadSourceLocation(Record, Idx);
+ bool IsWritten = Record[Idx++];
+ unsigned SourceOrderOrNumArrayIndices;
+ llvm::SmallVector<VarDecl *, 8> Indices;
+ if (IsWritten) {
+ SourceOrderOrNumArrayIndices = Record[Idx++];
+ } else {
+ SourceOrderOrNumArrayIndices = Record[Idx++];
+ Indices.reserve(SourceOrderOrNumArrayIndices);
+ for (unsigned i=0; i != SourceOrderOrNumArrayIndices; ++i)
+ Indices.push_back(cast<VarDecl>(Reader.GetDecl(Record[Idx++])));
+ }
+
+ CXXBaseOrMemberInitializer *BOMInit;
+ if (IsBaseInitializer) {
+ BOMInit = new (C) CXXBaseOrMemberInitializer(C, BaseClassInfo,
+ IsBaseVirtual, LParenLoc,
+ Init, RParenLoc);
+ } else if (IsWritten) {
+ BOMInit = new (C) CXXBaseOrMemberInitializer(C, Member, MemberLoc,
+ LParenLoc, Init, RParenLoc);
+ } else {
+ BOMInit = CXXBaseOrMemberInitializer::Create(C, Member, MemberLoc,
+ LParenLoc, Init, RParenLoc,
+ Indices.data(),
+ Indices.size());
+ }
+
+ BOMInit->setAnonUnionMember(AnonUnionMember);
+ D->BaseOrMemberInitializers[i] = BOMInit;
+ }
+ }
}
void PCHDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
- // assert(false && "cannot read CXXDestructorDecl");
VisitCXXMethodDecl(D);
+
+ D->ImplicitlyDefined = Record[Idx++];
+ D->OperatorDelete = cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++]));
}
void PCHDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) {
- // assert(false && "cannot read CXXConversionDecl");
VisitCXXMethodDecl(D);
+ D->IsExplicitSpecified = Record[Idx++];
}
void PCHDeclReader::VisitAccessSpecDecl(AccessSpecDecl *D) {
Modified: cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterDecl.cpp?rev=107483&r1=107482&r2=107483&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterDecl.cpp Fri Jul 2 10:58:43 2010
@@ -40,6 +40,8 @@
PCHWriter::RecordData &Record)
: Writer(Writer), Context(Context), Record(Record) {
}
+
+ void Visit(Decl *D);
void VisitDecl(Decl *D);
void VisitTranslationUnitDecl(TranslationUnitDecl *D);
@@ -112,6 +114,19 @@
};
}
+void PCHDeclWriter::Visit(Decl *D) {
+ DeclVisitor<PCHDeclWriter>::Visit(D);
+
+ // Handle FunctionDecl's body here and write it after all other Stmts/Exprs
+ // have been written. We want it last because we will not read it back when
+ // retrieving it from the PCH, we'll just lazily set the offset.
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ Record.push_back(FD->isThisDeclarationADefinition());
+ if (FD->isThisDeclarationADefinition())
+ Writer.AddStmt(FD->getBody());
+ }
+}
+
void PCHDeclWriter::VisitDecl(Decl *D) {
Writer.AddDeclRef(cast_or_null<Decl>(D->getDeclContext()), Record);
Writer.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()), Record);
@@ -255,11 +270,8 @@
}
}
- // Make sure no Exprs are emitted after the body, because when reading the
- // function, the body doesn't get read so the cursor doesn't advance.
- Record.push_back(D->isThisDeclarationADefinition());
- if (D->isThisDeclarationADefinition())
- Writer.AddStmt(D->getBody());
+ // FunctionDecl's body is handled last at PCHWriterDecl::Visit,
+ // after everything else is written.
Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
Record.push_back(D->getStorageClass()); // FIXME: stable encoding
@@ -691,26 +703,57 @@
}
void PCHDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
- // assert(false && "cannot write CXXMethodDecl");
VisitFunctionDecl(D);
Code = pch::DECL_CXX_METHOD;
}
void PCHDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
- // assert(false && "cannot write CXXConstructorDecl");
VisitCXXMethodDecl(D);
+
+ Record.push_back(D->IsExplicitSpecified);
+ Record.push_back(D->ImplicitlyDefined);
+
+ Record.push_back(D->NumBaseOrMemberInitializers);
+ for (unsigned i=0; i != D->NumBaseOrMemberInitializers; ++i) {
+ CXXBaseOrMemberInitializer *Init = D->BaseOrMemberInitializers[i];
+
+ Record.push_back(Init->isBaseInitializer());
+ if (Init->isBaseInitializer()) {
+ Writer.AddTypeSourceInfo(Init->getBaseClassInfo(), Record);
+ Record.push_back(Init->isBaseVirtual());
+ } else {
+ Writer.AddDeclRef(Init->getMember(), Record);
+ }
+ Writer.AddSourceLocation(Init->getMemberLocation(), Record);
+ Writer.AddStmt(Init->getInit());
+ Writer.AddDeclRef(Init->getAnonUnionMember(), Record);
+ Writer.AddSourceLocation(Init->getLParenLoc(), Record);
+ Writer.AddSourceLocation(Init->getRParenLoc(), Record);
+ Record.push_back(Init->isWritten());
+ if (Init->isWritten()) {
+ Record.push_back(Init->getSourceOrder());
+ } else {
+ Record.push_back(Init->getNumArrayIndices());
+ for (unsigned i=0, e=Init->getNumArrayIndices(); i != e; ++i)
+ Writer.AddDeclRef(Init->getArrayIndex(i), Record);
+ }
+ }
+
Code = pch::DECL_CXX_CONSTRUCTOR;
}
void PCHDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
- // assert(false && "cannot write CXXDestructorDecl");
VisitCXXMethodDecl(D);
+
+ Record.push_back(D->ImplicitlyDefined);
+ Writer.AddDeclRef(D->OperatorDelete, Record);
+
Code = pch::DECL_CXX_DESTRUCTOR;
}
void PCHDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) {
- // assert(false && "cannot write CXXConversionDecl");
VisitCXXMethodDecl(D);
+ Record.push_back(D->IsExplicitSpecified);
Code = pch::DECL_CXX_CONVERSION;
}
More information about the cfe-commits
mailing list