diff options
author | Sean Hunt <scshunt@csclub.uwaterloo.ca> | 2011-05-01 07:04:31 +0000 |
---|---|---|
committer | Sean Hunt <scshunt@csclub.uwaterloo.ca> | 2011-05-01 07:04:31 +0000 |
commit | 059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0b (patch) | |
tree | 58267829b727c3e865f7dab09b5ac08a42e4fe30 /lib/Sema/SemaDeclCXX.cpp | |
parent | ccb4ecf9b11d7b652515780253253db976d0447f (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.cpp | 28 |
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; } } |