aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Serialization/ASTBitCodes.h9
-rw-r--r--lib/Serialization/ASTReader.cpp31
-rw-r--r--lib/Serialization/ASTWriter.cpp15
-rw-r--r--test/PCH/cxx0x-delegating-ctors.cpp8
-rw-r--r--test/PCH/cxx0x-delegating-ctors.h6
5 files changed, 54 insertions, 15 deletions
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 1cfd458a38..0905b43f87 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/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/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 5a4c59e3cd..3227cfc457 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/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<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,
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index e711351add..30b55c2591 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/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/test/PCH/cxx0x-delegating-ctors.cpp b/test/PCH/cxx0x-delegating-ctors.cpp
new file mode 100644
index 0000000000..97f2f684fc
--- /dev/null
+++ b/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/test/PCH/cxx0x-delegating-ctors.h b/test/PCH/cxx0x-delegating-ctors.h
new file mode 100644
index 0000000000..598982fdd2
--- /dev/null
+++ b/test/PCH/cxx0x-delegating-ctors.h
@@ -0,0 +1,6 @@
+// Header for PCH test cxx0x-delegating-ctors.cpp
+
+struct foo {
+ foo(int) : foo() { }
+ foo();
+};