From 37a477f7eb484aaaf3f714d119412f5ab46b6b6d Mon Sep 17 00:00:00 2001 From: Alexis Hunt Date: Wed, 4 May 2011 01:19:08 +0000 Subject: [PATCH] Implement serialization of delegating constructors. llvm-svn: 130822 --- .../include/clang/Serialization/ASTBitCodes.h | 9 ++++++ clang/lib/Serialization/ASTReader.cpp | 31 +++++++++++++------ clang/lib/Serialization/ASTWriter.cpp | 15 +++++---- clang/test/PCH/cxx0x-delegating-ctors.cpp | 8 +++++ clang/test/PCH/cxx0x-delegating-ctors.h | 6 ++++ 5 files changed, 54 insertions(+), 15 deletions(-) create mode 100644 clang/test/PCH/cxx0x-delegating-ctors.cpp create mode 100644 clang/test/PCH/cxx0x-delegating-ctors.h diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 1cfd458a3864..0905b43f878f 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -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 diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 5a4c59e3cde2..3227cfc457fa 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -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(GetDecl(Record[Idx++])); - else - Member = cast(GetDecl(Record[Idx++])); + break; + + case CTOR_INITIALIZER_DELEGATING: + Target = cast(GetDecl(Record[Idx++])); + break; + + case CTOR_INITIALIZER_MEMBER: + Member = cast(GetDecl(Record[Idx++])); + break; + + case CTOR_INITIALIZER_INDIRECT_MEMBER: + IndirectMember = cast(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, diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index e711351add48..30b55c2591d3 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -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); diff --git a/clang/test/PCH/cxx0x-delegating-ctors.cpp b/clang/test/PCH/cxx0x-delegating-ctors.cpp new file mode 100644 index 000000000000..97f2f684fc29 --- /dev/null +++ b/clang/test/PCH/cxx0x-delegating-ctors.cpp @@ -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}} diff --git a/clang/test/PCH/cxx0x-delegating-ctors.h b/clang/test/PCH/cxx0x-delegating-ctors.h new file mode 100644 index 000000000000..598982fdd274 --- /dev/null +++ b/clang/test/PCH/cxx0x-delegating-ctors.h @@ -0,0 +1,6 @@ +// Header for PCH test cxx0x-delegating-ctors.cpp + +struct foo { + foo(int) : foo() { } + foo(); +};