]> granicus.if.org Git - clang/commitdiff
Implement serialization of delegating constructors.
authorSean Hunt <scshunt@csclub.uwaterloo.ca>
Wed, 4 May 2011 01:19:08 +0000 (01:19 +0000)
committerSean Hunt <scshunt@csclub.uwaterloo.ca>
Wed, 4 May 2011 01:19:08 +0000 (01:19 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130822 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Serialization/ASTBitCodes.h
lib/Serialization/ASTReader.cpp
lib/Serialization/ASTWriter.cpp
test/PCH/cxx0x-delegating-ctors.cpp [new file with mode: 0644]
test/PCH/cxx0x-delegating-ctors.h [new file with mode: 0644]

index 1cfd458a38647425fb0050ce5bdebbc196f8cbff..0905b43f878f9b88bfd56add68d73a4ff138642f 100644 (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
index 5a4c59e3cde247e1fd82367a52159ef4be694141..3227cfc457fa44ebefaa17b10c3ce47a65a4e332 100644 (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,
index e711351add48818ab82f8b1c55ea1314712f29ce..30b55c2591d348b1ccf03649c2b8987e6939e2a3 100644 (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);
diff --git a/test/PCH/cxx0x-delegating-ctors.cpp b/test/PCH/cxx0x-delegating-ctors.cpp
new file mode 100644 (file)
index 0000000..97f2f68
--- /dev/null
@@ -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 (file)
index 0000000..598982f
--- /dev/null
@@ -0,0 +1,6 @@
+// Header for PCH test cxx0x-delegating-ctors.cpp
+
+struct foo {
+  foo(int) : foo() { }
+  foo();
+};