Implement serialization of delegating constructors.

llvm-svn: 130822
This commit is contained in:
Alexis Hunt 2011-05-04 01:19:08 +00:00
parent 159bdaa50e
commit 37a477f7eb
5 changed files with 54 additions and 15 deletions

View File

@ -1003,6 +1003,15 @@ namespace clang {
DESIG_ARRAY_RANGE = 3
};
/// \brief The different kinds of data that can occur in a
/// CtorInitializer.
enum CtorInitializerType {
CTOR_INITIALIZER_BASE,
CTOR_INITIALIZER_DELEGATING,
CTOR_INITIALIZER_MEMBER,
CTOR_INITIALIZER_INDIRECT_MEMBER
};
/// @}
}
} // end namespace clang

View File

@ -4711,18 +4711,28 @@ ASTReader::ReadCXXCtorInitializers(PerFileData &F, const RecordData &Record,
bool IsBaseVirtual = false;
FieldDecl *Member = 0;
IndirectFieldDecl *IndirectMember = 0;
CXXConstructorDecl *Target = 0;
bool IsBaseInitializer = Record[Idx++];
if (IsBaseInitializer) {
CtorInitializerType Type = (CtorInitializerType)Record[Idx++];
switch (Type) {
case CTOR_INITIALIZER_BASE:
BaseClassInfo = GetTypeSourceInfo(F, Record, Idx);
IsBaseVirtual = Record[Idx++];
} else {
bool IsIndirectMemberInitializer = Record[Idx++];
if (IsIndirectMemberInitializer)
IndirectMember = cast<IndirectFieldDecl>(GetDecl(Record[Idx++]));
else
Member = cast<FieldDecl>(GetDecl(Record[Idx++]));
break;
case CTOR_INITIALIZER_DELEGATING:
Target = cast<CXXConstructorDecl>(GetDecl(Record[Idx++]));
break;
case CTOR_INITIALIZER_MEMBER:
Member = cast<FieldDecl>(GetDecl(Record[Idx++]));
break;
case CTOR_INITIALIZER_INDIRECT_MEMBER:
IndirectMember = cast<IndirectFieldDecl>(GetDecl(Record[Idx++]));
break;
}
SourceLocation MemberOrEllipsisLoc = ReadSourceLocation(F, Record, Idx);
Expr *Init = ReadExpr(F);
SourceLocation LParenLoc = ReadSourceLocation(F, Record, Idx);
@ -4740,10 +4750,13 @@ ASTReader::ReadCXXCtorInitializers(PerFileData &F, const RecordData &Record,
}
CXXCtorInitializer *BOMInit;
if (IsBaseInitializer) {
if (Type == CTOR_INITIALIZER_BASE) {
BOMInit = new (C) CXXCtorInitializer(C, BaseClassInfo, IsBaseVirtual,
LParenLoc, Init, RParenLoc,
MemberOrEllipsisLoc);
} else if (Type == CTOR_INITIALIZER_DELEGATING) {
BOMInit = new (C) CXXCtorInitializer(C, MemberOrEllipsisLoc, LParenLoc,
Target, Init, RParenLoc);
} else if (IsWritten) {
if (Member)
BOMInit = new (C) CXXCtorInitializer(C, Member, MemberOrEllipsisLoc,

View File

@ -3744,16 +3744,19 @@ void ASTWriter::AddCXXCtorInitializers(
for (unsigned i=0; i != NumCtorInitializers; ++i) {
const CXXCtorInitializer *Init = CtorInitializers[i];
Record.push_back(Init->isBaseInitializer());
if (Init->isBaseInitializer()) {
Record.push_back(CTOR_INITIALIZER_BASE);
AddTypeSourceInfo(Init->getBaseClassInfo(), Record);
Record.push_back(Init->isBaseVirtual());
} else if (Init->isDelegatingInitializer()) {
Record.push_back(CTOR_INITIALIZER_DELEGATING);
AddDeclRef(Init->getTargetConstructor(), Record);
} else if (Init->isMemberInitializer()){
Record.push_back(CTOR_INITIALIZER_MEMBER);
AddDeclRef(Init->getMember(), Record);
} else {
Record.push_back(Init->isIndirectMemberInitializer());
if (Init->isIndirectMemberInitializer())
AddDeclRef(Init->getIndirectMember(), Record);
else
AddDeclRef(Init->getMember(), Record);
Record.push_back(CTOR_INITIALIZER_INDIRECT_MEMBER);
AddDeclRef(Init->getIndirectMember(), Record);
}
AddSourceLocation(Init->getMemberLocation(), Record);

View File

@ -0,0 +1,8 @@
// Test this without pch.
// RUN: %clang_cc1 -include %S/cxx0x-delegating-ctors.h -std=c++0x -fsyntax-only -verify %s
// Test with pch.
// RUN: %clang_cc1 -x c++-header -std=c++0x -emit-pch -o %t %S/cxx0x-delegating-ctors.h
// RUN: %clang_cc1 -std=c++0x -include-pch %t -fsyntax-only -verify %s
foo::foo() : foo(1) { } // expected-error{{delegates to itself}}

View File

@ -0,0 +1,6 @@
// Header for PCH test cxx0x-delegating-ctors.cpp
struct foo {
foo(int) : foo() { }
foo();
};