diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-02-26 00:31:33 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-02-26 00:31:33 +0000 |
commit | 0d1f3cb1b5d2c89d12d01bfa1b729a11b4864d49 (patch) | |
tree | 5ee4df5a90fbb60432c035c9aa272419ab1c34c4 /clang/lib/Sema/SemaDeclCXX.cpp | |
parent | 8d4677ad266da163861264717fc40e0bf24a9fea (diff) | |
download | bcm5719-llvm-0d1f3cb1b5d2c89d12d01bfa1b729a11b4864d49.tar.gz bcm5719-llvm-0d1f3cb1b5d2c89d12d01bfa1b729a11b4864d49.zip |
Special members which are defaulted or deleted on their first declaration are
trivial if the implicit declaration would be. Don't forget to set the Trivial
flag on the special member as well as on the class. It doesn't seem ideal that
we have two separate mechanisms for storing this information, but this patch
does not attempt to address that.
This leaves us in an interesting position where the has_trivial_X trait for a
class says 'yes' for a deleted but trivial X, but is_trivially_Xable says 'no'.
This seems to be what the standard requires.
llvm-svn: 151465
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 1f5255dae7f..9a31dd8ef87 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -3871,6 +3871,10 @@ void Sema::CheckExplicitlyDefaultedDefaultConstructor(CXXConstructorDecl *CD) { // FIXME: a compatible, but different, explicit exception specification // will be silently overridden. We should issue a warning if this happens. EPI.ExtInfo = CtorType->getExtInfo(); + + // Such a function is also trivial if the implicitly-declared function + // would have been. + CD->setTrivial(CD->getParent()->hasTrivialDefaultConstructor()); } if (HadError) { @@ -3966,6 +3970,10 @@ void Sema::CheckExplicitlyDefaultedCopyConstructor(CXXConstructorDecl *CD) { // -- [...] it shall have the same parameter type as if it had been // implicitly declared. CD->setType(Context.getFunctionType(Context.VoidTy, &ArgType, 1, EPI)); + + // Such a function is also trivial if the implicitly-declared function + // would have been. + CD->setTrivial(CD->getParent()->hasTrivialCopyConstructor()); } if (HadError) { @@ -4053,6 +4061,10 @@ void Sema::CheckExplicitlyDefaultedCopyAssignment(CXXMethodDecl *MD) { EPI.RefQualifier = OperType->getRefQualifier(); EPI.ExtInfo = OperType->getExtInfo(); MD->setType(Context.getFunctionType(ReturnType, &ArgType, 1, EPI)); + + // Such a function is also trivial if the implicitly-declared function + // would have been. + MD->setTrivial(MD->getParent()->hasTrivialCopyAssignment()); } if (HadError) { @@ -4146,6 +4158,10 @@ void Sema::CheckExplicitlyDefaultedMoveConstructor(CXXConstructorDecl *CD) { // -- [...] it shall have the same parameter type as if it had been // implicitly declared. CD->setType(Context.getFunctionType(Context.VoidTy, &ArgType, 1, EPI)); + + // Such a function is also trivial if the implicitly-declared function + // would have been. + CD->setTrivial(CD->getParent()->hasTrivialMoveConstructor()); } if (HadError) { @@ -4231,6 +4247,10 @@ void Sema::CheckExplicitlyDefaultedMoveAssignment(CXXMethodDecl *MD) { EPI.RefQualifier = OperType->getRefQualifier(); EPI.ExtInfo = OperType->getExtInfo(); MD->setType(Context.getFunctionType(ReturnType, &ArgType, 1, EPI)); + + // Such a function is also trivial if the implicitly-declared function + // would have been. + MD->setTrivial(MD->getParent()->hasTrivialMoveAssignment()); } if (HadError) { @@ -4278,6 +4298,10 @@ void Sema::CheckExplicitlyDefaultedDestructor(CXXDestructorDecl *DD) { // There are no parameters. EPI.ExtInfo = DtorType->getExtInfo(); DD->setType(Context.getFunctionType(Context.VoidTy, 0, 0, EPI)); + + // Such a function is also trivial if the implicitly-declared function + // would have been. + DD->setTrivial(DD->getParent()->hasTrivialDestructor()); } if (ShouldDeleteSpecialMember(DD, CXXDestructor)) { @@ -10254,6 +10278,35 @@ void Sema::SetDeclDeleted(Decl *Dcl, SourceLocation DelLoc) { // recovery. } Fn->setDeletedAsWritten(); + + CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Dcl); + if (!MD) + return; + + // A deleted special member function is trivial if the corresponding + // implicitly-declared function would have been. + switch (getSpecialMember(MD)) { + case CXXInvalid: + break; + case CXXDefaultConstructor: + MD->setTrivial(MD->getParent()->hasTrivialDefaultConstructor()); + break; + case CXXCopyConstructor: + MD->setTrivial(MD->getParent()->hasTrivialCopyConstructor()); + break; + case CXXMoveConstructor: + MD->setTrivial(MD->getParent()->hasTrivialMoveConstructor()); + break; + case CXXCopyAssignment: + MD->setTrivial(MD->getParent()->hasTrivialCopyAssignment()); + break; + case CXXMoveAssignment: + MD->setTrivial(MD->getParent()->hasTrivialMoveAssignment()); + break; + case CXXDestructor: + MD->setTrivial(MD->getParent()->hasTrivialDestructor()); + break; + } } void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation DefaultLoc) { |