]> granicus.if.org Git - clang/commitdiff
Added an RAII object that helps set up/tear down the Sema context
authorDouglas Gregor <dgregor@apple.com>
Sat, 1 May 2010 15:04:51 +0000 (15:04 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sat, 1 May 2010 15:04:51 +0000 (15:04 +0000)
information required to implicitly define a C++ special member
function. Use it rather than explicitly setting CurContext on entry
and exit, which is fragile.

Use this RAII object for the implicitly-defined default constructor,
copy constructor, copy assignment operator, and destructor.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102840 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/Sema.h
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaExpr.cpp

index a79b0007f7859f3998d8fb8245761fe47941584b..49b189914890427ca242ed4665ac16754558462d 100644 (file)
@@ -2182,10 +2182,9 @@ public:
                                      CXXConstructorDecl *Constructor,
                                      unsigned TypeQuals);
 
-  /// DefineImplicitOverloadedAssign - Checks for feasibility of
-  /// defining implicit this overloaded assignment operator.
-  void DefineImplicitOverloadedAssign(SourceLocation CurrentLocation,
-                                      CXXMethodDecl *MethodDecl);
+  /// \brief Defined and implicitly-declared copy assignment operator.
+  void DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
+                                    CXXMethodDecl *MethodDecl);
 
   /// getAssignOperatorMethod - Returns the default copy assignmment operator
   /// for the class.
index c73c6caf2973cdd4b80550a3b97e8d5a204d1650..2057b9aa0d22e24ede4b84f89381434e36eca306 100644 (file)
@@ -4033,6 +4033,30 @@ Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S,
   return DeclPtrTy::make(AliasDecl);
 }
 
+namespace {
+  /// \brief Scoped object used to handle the state changes required in Sema
+  /// to implicitly define the body of a C++ member function;
+  class ImplicitlyDefinedFunctionScope {
+    Sema &S;
+    DeclContext *PreviousContext;
+    
+  public:
+    ImplicitlyDefinedFunctionScope(Sema &S, CXXMethodDecl *Method)
+      : S(S), PreviousContext(S.CurContext) 
+    {
+      S.CurContext = Method;
+      S.PushFunctionScope();
+      S.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
+    }
+    
+    ~ImplicitlyDefinedFunctionScope() {
+      S.PopExpressionEvaluationContext();
+      S.PopFunctionOrBlockScope();
+      S.CurContext = PreviousContext;
+    }
+  };
+}
+
 void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
                                             CXXConstructorDecl *Constructor) {
   assert((Constructor->isImplicit() && Constructor->isDefaultConstructor() &&
@@ -4042,8 +4066,7 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
   CXXRecordDecl *ClassDecl = Constructor->getParent();
   assert(ClassDecl && "DefineImplicitDefaultConstructor - invalid constructor");
 
-  DeclContext *PreviousContext = CurContext;
-  CurContext = Constructor;
+  ImplicitlyDefinedFunctionScope Scope(*this, Constructor);
   if (SetBaseOrMemberInitializers(Constructor, 0, 0, /*AnyErrors=*/false)) {
     Diag(CurrentLocation, diag::note_member_synthesized_at) 
       << CXXConstructor << Context.getTagDeclType(ClassDecl);
@@ -4051,7 +4074,6 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
   } else {
     Constructor->setUsed();
   }
-  CurContext = PreviousContext;
 }
 
 void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
@@ -4061,8 +4083,7 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
   CXXRecordDecl *ClassDecl = Destructor->getParent();
   assert(ClassDecl && "DefineImplicitDestructor - invalid destructor");
 
-  DeclContext *PreviousContext = CurContext;
-  CurContext = Destructor;
+  ImplicitlyDefinedFunctionScope Scope(*this, Destructor);
 
   MarkBaseAndMemberDestructorsReferenced(Destructor->getLocation(),
                                          Destructor->getParent());
@@ -4074,27 +4095,23 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
       << CXXDestructor << Context.getTagDeclType(ClassDecl);
 
     Destructor->setInvalidDecl();
-    CurContext = PreviousContext;
-
     return;
   }
-  CurContext = PreviousContext;
 
   Destructor->setUsed();
 }
 
-void Sema::DefineImplicitOverloadedAssign(SourceLocation CurrentLocation,
-                                          CXXMethodDecl *MethodDecl) {
+void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
+                                        CXXMethodDecl *MethodDecl) {
   assert((MethodDecl->isImplicit() && MethodDecl->isOverloadedOperator() &&
           MethodDecl->getOverloadedOperator() == OO_Equal &&
           !MethodDecl->isUsed()) &&
-         "DefineImplicitOverloadedAssign - call it for implicit assignment op");
+         "DefineImplicitCopyAssignment called for wrong function");
 
   CXXRecordDecl *ClassDecl
     = cast<CXXRecordDecl>(MethodDecl->getDeclContext());
 
-  DeclContext *PreviousContext = CurContext;
-  CurContext = MethodDecl;
+  ImplicitlyDefinedFunctionScope Scope(*this, MethodDecl);
 
   // C++[class.copy] p12
   // Before the implicitly-declared copy assignment operator for a class is
@@ -4151,8 +4168,6 @@ void Sema::DefineImplicitOverloadedAssign(SourceLocation CurrentLocation,
   }
   if (!err)
     MethodDecl->setUsed();
-
-  CurContext = PreviousContext;
 }
 
 CXXMethodDecl *
@@ -4195,8 +4210,7 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
   CXXRecordDecl *ClassDecl = CopyConstructor->getParent();
   assert(ClassDecl && "DefineImplicitCopyConstructor - invalid constructor");
 
-  DeclContext *PreviousContext = CurContext;
-  CurContext = CopyConstructor;
+  ImplicitlyDefinedFunctionScope Scope(*this, CopyConstructor);
 
   // C++ [class.copy] p209
   // Before the implicitly-declared copy constructor for a class is
@@ -4238,8 +4252,6 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
     }
   }
   CopyConstructor->setUsed();
-
-  CurContext = PreviousContext;
 }
 
 Sema::OwningExprResult
index a1b66cd94600ba2d6c38147048815fccc23d03a9..10d470a331dd30d63b8ad0830144b1b0e8560737 100644 (file)
@@ -7507,7 +7507,7 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
     if (MethodDecl->isImplicit() && MethodDecl->isOverloadedOperator() &&
         MethodDecl->getOverloadedOperator() == OO_Equal) {
       if (!MethodDecl->isUsed())
-        DefineImplicitOverloadedAssign(Loc, MethodDecl);
+        DefineImplicitCopyAssignment(Loc, MethodDecl);
     }
   }
   if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {