aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorSean Hunt <scshunt@csclub.uwaterloo.ca>2011-05-01 07:04:31 +0000
committerSean Hunt <scshunt@csclub.uwaterloo.ca>2011-05-01 07:04:31 +0000
commit059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0b (patch)
tree58267829b727c3e865f7dab09b5ac08a42e4fe30 /lib/Sema/SemaDeclCXX.cpp
parentccb4ecf9b11d7b652515780253253db976d0447f (diff)
Fully implement delegating constructors!
As far as I know, this implementation is complete but might be missing a few optimizations. Exceptions and virtual bases are handled correctly. Because I'm an optimist, the web page has appropriately been updated. If I'm wrong, feel free to downgrade its support categories. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130642 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--lib/Sema/SemaDeclCXX.cpp28
1 files changed, 28 insertions, 0 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index bd4aac8985..dc0a41e79e 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -2068,6 +2068,30 @@ static bool CollectFieldInitializer(BaseAndFieldInfo &Info,
return false;
}
+
+bool
+Sema::SetDelegatingInitializer(CXXConstructorDecl *Constructor,
+ CXXCtorInitializer *Initializer) {
+ Constructor->setNumCtorInitializers(1);
+ CXXCtorInitializer **initializer =
+ new (Context) CXXCtorInitializer*[1];
+ memcpy(initializer, &Initializer, sizeof (CXXCtorInitializer*));
+ Constructor->setCtorInitializers(initializer);
+
+ // FIXME: This doesn't catch indirect loops yet
+ CXXConstructorDecl *Target = Initializer->getTargetConstructor();
+ while (Target) {
+ if (Target == Constructor) {
+ Diag(Initializer->getSourceLocation(), diag::err_delegating_ctor_loop)
+ << Constructor;
+ return true;
+ }
+ Target = Target->getTargetConstructor();
+ }
+
+ return false;
+}
+
bool
Sema::SetCtorInitializers(CXXConstructorDecl *Constructor,
@@ -2442,7 +2466,11 @@ void Sema::ActOnMemInitializers(Decl *ConstructorDecl,
diag::err_delegating_initializer_alone)
<< MemInits[0]->getSourceRange();
HadError = true;
+ // We will treat this as being the only initializer.
}
+ SetDelegatingInitializer(Constructor, *MemInits);
+ // Return immediately as the initializer is set.
+ return;
}
}