]> granicus.if.org Git - clang/commitdiff
Implement defaulting of destructors.
authorSean Hunt <scshunt@csclub.uwaterloo.ca>
Thu, 12 May 2011 22:46:29 +0000 (22:46 +0000)
committerSean Hunt <scshunt@csclub.uwaterloo.ca>
Thu, 12 May 2011 22:46:29 +0000 (22:46 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131260 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Sema.h
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaInit.cpp
lib/Serialization/ASTReaderDecl.cpp
lib/Serialization/ASTWriterDecl.cpp

index 137121a05c6797ba72972b529dd9ddf9f3d7ce2e..8f4bfac323cfea1f7e5fb495e8340c2cfb078d0d 100644 (file)
@@ -1293,6 +1293,8 @@ public:
                                              QualType ResultType,
                                              Expr *Value);
   
+  bool CanPerformCopyInitialization(const InitializedEntity &Entity,
+                                    ExprResult Init);
   ExprResult PerformCopyInitialization(const InitializedEntity &Entity,
                                        SourceLocation EqualLoc,
                                        ExprResult Init);
@@ -2795,7 +2797,8 @@ public:
   bool FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
                               DeclarationName Name, Expr** Args,
                               unsigned NumArgs, DeclContext *Ctx,
-                              bool AllowMissing, FunctionDecl *&Operator);
+                              bool AllowMissing, FunctionDecl *&Operator,
+                              bool Diagnose = true);
   void DeclareGlobalNewDelete();
   void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return,
                                        QualType Argument,
@@ -2803,7 +2806,7 @@ public:
 
   bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
                                 DeclarationName Name, FunctionDecl* &Operator,
-                                bool AllowMissing = false);
+                                bool Diagnose = true);
 
   /// ActOnCXXDelete - Parsed a C++ 'delete' expression
   ExprResult ActOnCXXDelete(SourceLocation StartLoc,
index d80bfb9b7e5afb98df4ff392745e68e1ad28e141..b78f01c94dfabba2c4209451c79642b772acc989 100644 (file)
@@ -3109,8 +3109,6 @@ void Sema::CheckExplicitlyDefaultedDestructor(CXXDestructorDecl *DD) {
       Diag(DD->getLocation(), diag::err_out_of_line_default_deletes)
         << 3 /* destructor */;
   }
-
-  CheckDestructor(DD);
 }
 
 bool Sema::ShouldDeleteDefaultConstructor(CXXConstructorDecl *CD) {
@@ -3257,7 +3255,7 @@ bool Sema::ShouldDeleteDefaultConstructor(CXXConstructorDecl *CD) {
               !UnionFieldRecord->hasTrivialDefaultConstructor())
             return true;
         }
-        
+
         if (AllConst)
           return true;
 
index 867bd3515b6d24e7fa80bc9b3d3dfad0bc85addd..a843ba428499a2b5a1aff3614baab92b96adb759 100644 (file)
@@ -1327,11 +1327,12 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
 bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
                                   DeclarationName Name, Expr** Args,
                                   unsigned NumArgs, DeclContext *Ctx,
-                                  bool AllowMissing, FunctionDecl *&Operator) {
+                                  bool AllowMissing, FunctionDecl *&Operator,
+                                  bool Diagnose) {
   LookupResult R(*this, Name, StartLoc, LookupOrdinaryName);
   LookupQualifiedName(R, Ctx);
   if (R.empty()) {
-    if (AllowMissing)
+    if (AllowMissing || !Diagnose)
       return false;
     return Diag(StartLoc, diag::err_ovl_no_viable_function_in_call)
       << Name << Range;
@@ -1375,40 +1376,46 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
     // Watch out for variadic allocator function.
     unsigned NumArgsInFnDecl = FnDecl->getNumParams();
     for (unsigned i = 0; (i < NumArgs && i < NumArgsInFnDecl); ++i) {
+      InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
+                                                       FnDecl->getParamDecl(i));
+
+      if (!Diagnose && !CanPerformCopyInitialization(Entity, Owned(Args[i])))
+        return true;
+
       ExprResult Result
-        = PerformCopyInitialization(InitializedEntity::InitializeParameter(
-                                                       Context,
-                                                       FnDecl->getParamDecl(i)),
-                                    SourceLocation(),
-                                    Owned(Args[i]));
+        = PerformCopyInitialization(Entity, SourceLocation(), Owned(Args[i]));
       if (Result.isInvalid())
         return true;
 
       Args[i] = Result.takeAs<Expr>();
     }
     Operator = FnDecl;
-    CheckAllocationAccess(StartLoc, Range, R.getNamingClass(), Best->FoundDecl);
+    CheckAllocationAccess(StartLoc, Range, R.getNamingClass(), Best->FoundDecl,
+                          Diagnose);
     return false;
   }
 
   case OR_No_Viable_Function:
-    Diag(StartLoc, diag::err_ovl_no_viable_function_in_call)
-      << Name << Range;
+    if (Diagnose)
+      Diag(StartLoc, diag::err_ovl_no_viable_function_in_call)
+        << Name << Range;
     Candidates.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
     return true;
 
   case OR_Ambiguous:
-    Diag(StartLoc, diag::err_ovl_ambiguous_call)
-      << Name << Range;
+    if (Diagnose)
+      Diag(StartLoc, diag::err_ovl_ambiguous_call)
+        << Name << Range;
     Candidates.NoteCandidates(*this, OCD_ViableCandidates, Args, NumArgs);
     return true;
 
   case OR_Deleted: {
-    Diag(StartLoc, diag::err_ovl_deleted_call)
-      << Best->Function->isDeleted()
-      << Name 
-      << getDeletedOrUnavailableSuffix(Best->Function)
-      << Range;
+    if (Diagnose)
+      Diag(StartLoc, diag::err_ovl_deleted_call)
+        << Best->Function->isDeleted()
+        << Name 
+        << getDeletedOrUnavailableSuffix(Best->Function)
+        << Range;
     Candidates.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
     return true;
   }
@@ -1569,7 +1576,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
 
 bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
                                     DeclarationName Name,
-                                    FunctionDecl* &Operator, bool AllowMissing) {
+                                    FunctionDecl* &Operator, bool Diagnose) {
   LookupResult Found(*this, Name, StartLoc, LookupOrdinaryName);
   // Try to find operator delete/operator delete[] in class scope.
   LookupQualifiedName(Found, RD);
@@ -1596,13 +1603,22 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
   // There's exactly one suitable operator;  pick it.
   if (Matches.size() == 1) {
     Operator = cast<CXXMethodDecl>(Matches[0]->getUnderlyingDecl());
+
+    if (Operator->isDeleted()) {
+      if (Diagnose) {
+        Diag(StartLoc, diag::err_deleted_function_use);
+        Diag(Operator->getLocation(), diag::note_unavailable_here) << true;
+      }
+      return true;
+    }
+
     CheckAllocationAccess(StartLoc, SourceRange(), Found.getNamingClass(),
-                          Matches[0], !AllowMissing);
+                          Matches[0], Diagnose);
     return false;
 
   // We found multiple suitable operators;  complain about the ambiguity.
   } else if (!Matches.empty()) {
-    if (!AllowMissing) {
+    if (Diagnose) {
       Diag(StartLoc, diag::err_ambiguous_suitable_delete_member_function_found)
         << Name << RD;
 
@@ -1617,7 +1633,7 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
   // We did find operator delete/operator delete[] declarations, but
   // none of them were suitable.
   if (!Found.empty()) {
-    if (!AllowMissing) {
+    if (Diagnose) {
       Diag(StartLoc, diag::err_no_suitable_delete_member_function_found)
         << Name << RD;
 
@@ -1637,8 +1653,8 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
   Expr* DeallocArgs[1];
   DeallocArgs[0] = &Null;
   if (FindAllocationOverload(StartLoc, SourceRange(), Name,
-                             DeallocArgs, 1, TUDecl, AllowMissing,
-                             Operator))
+                             DeallocArgs, 1, TUDecl, !Diagnose,
+                             Operator, Diagnose))
     return true;
 
   assert(Operator && "Did not find a deallocation function!");
index 26d030419a2212622aa5d369a8836103e5900bfd..cfa8f33fad4a0582f8103a21fa041dd1f15f5d65 100644 (file)
@@ -4723,6 +4723,21 @@ void InitializationSequence::dump() const {
 //===----------------------------------------------------------------------===//
 // Initialization helper functions
 //===----------------------------------------------------------------------===//
+bool
+Sema::CanPerformCopyInitialization(const InitializedEntity &Entity,
+                                   ExprResult Init) {
+  if (Init.isInvalid())
+    return false;
+
+  Expr *InitE = Init.get();
+  assert(InitE && "No initialization expression");
+
+  InitializationKind Kind = InitializationKind::CreateCopy(SourceLocation(),
+                                                           SourceLocation());
+  InitializationSequence Seq(*this, Entity, Kind, &InitE, 1);
+  return Seq.getKind() != InitializationSequence::FailedSequence;
+}
+
 ExprResult
 Sema::PerformCopyInitialization(const InitializedEntity &Entity,
                                 SourceLocation EqualLoc,
index 6c6a65a57078123036f02fc4b90e5802f7824b98..85c8f079c006fd17659b5b4a10bda77106f0f2bf 100644 (file)
@@ -429,6 +429,8 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
   FD->HasWrittenPrototype = Record[Idx++];
   FD->IsDeleted = Record[Idx++];
   FD->IsTrivial = Record[Idx++];
+  FD->IsDefaulted = Record[Idx++];
+  FD->IsExplicitlyDefaulted = Record[Idx++];
   FD->HasImplicitReturnZero = Record[Idx++];
   FD->EndRangeLoc = ReadSourceLocation(Record, Idx);
 
index 8c1774a0302f3636275d4a2ee453c9763b2ebc3f..b0ca826e4f431b78ebaf3534222e3d0f50d379e5 100644 (file)
@@ -324,6 +324,8 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
   Record.push_back(D->hasWrittenPrototype());
   Record.push_back(D->isDeletedAsWritten());
   Record.push_back(D->isTrivial());
+  Record.push_back(D->isDefaulted());
+  Record.push_back(D->isExplicitlyDefaulted());
   Record.push_back(D->hasImplicitReturnZero());
   Writer.AddSourceLocation(D->getLocEnd(), Record);