[cfe-commits] r101047 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaTemplateInstantiate.cpp test/SemaCXX/implicit-member-functions.cpp

Douglas Gregor dgregor at apple.com
Mon Apr 12 10:09:21 PDT 2010


Author: dgregor
Date: Mon Apr 12 12:09:20 2010
New Revision: 101047

URL: http://llvm.org/viewvc/llvm-project?rev=101047&view=rev
Log:
When creating the implicitly-declared special member functions, be
sure to introduce them into the current Scope (when we have one) in
addition to the DeclContext for the class, so that they can be found
by name lookup for inline members of the class. Fixes PR6570.

Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/test/SemaCXX/implicit-member-functions.cpp

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=101047&r1=101046&r2=101047&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Apr 12 12:09:20 2010
@@ -2511,14 +2511,14 @@
   /// Returns false if no work was done.
   bool ProcessPendingClassesWithUnmarkedVirtualMembers();
   
-  void AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl);
+  void AddImplicitlyDeclaredMembersToClass(Scope *S, CXXRecordDecl *ClassDecl);
 
   virtual void ActOnMemInitializers(DeclPtrTy ConstructorDecl,
                                     SourceLocation ColonLoc,
                                     MemInitTy **MemInits, unsigned NumMemInits,
                                     bool AnyErrors);
 
-  void CheckCompletedCXXClass(CXXRecordDecl *Record);
+  void CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record);
   virtual void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
                                                  DeclPtrTy TagDecl,
                                                  SourceLocation LBrac,

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=101047&r1=101046&r2=101047&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Apr 12 12:09:20 2010
@@ -2136,12 +2136,12 @@
 /// \brief Perform semantic checks on a class definition that has been
 /// completing, introducing implicitly-declared members, checking for
 /// abstract types, etc.
-void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
+void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) {
   if (!Record || Record->isInvalidDecl())
     return;
 
   if (!Record->isDependentType())
-    AddImplicitlyDeclaredMembersToClass(Record);
+    AddImplicitlyDeclaredMembersToClass(S, Record);
   
   if (Record->isInvalidDecl())
     return;
@@ -2233,7 +2233,7 @@
               (DeclPtrTy*)FieldCollector->getCurFields(),
               FieldCollector->getCurNumFields(), LBrac, RBrac, AttrList);
 
-  CheckCompletedCXXClass(
+  CheckCompletedCXXClass(S, 
                       dyn_cast_or_null<CXXRecordDecl>(TagDecl.getAs<Decl>()));
 }
 
@@ -2242,7 +2242,10 @@
 /// constructor, or destructor, to the given C++ class (C++
 /// [special]p1).  This routine can only be executed just before the
 /// definition of the class is complete.
-void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
+///
+/// The scope, if provided, is the class scope.
+void Sema::AddImplicitlyDeclaredMembersToClass(Scope *S, 
+                                               CXXRecordDecl *ClassDecl) {
   CanQualType ClassType
     = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
 
@@ -2273,7 +2276,10 @@
     DefaultCon->setAccess(AS_public);
     DefaultCon->setImplicit();
     DefaultCon->setTrivial(ClassDecl->hasTrivialConstructor());
-    ClassDecl->addDecl(DefaultCon);
+    if (S)
+      PushOnScopeChains(DefaultCon, S, true);
+    else
+      ClassDecl->addDecl(DefaultCon);
   }
 
   if (!ClassDecl->hasUserDeclaredCopyConstructor()) {
@@ -2356,7 +2362,10 @@
                                                  ArgType, /*TInfo=*/0,
                                                  VarDecl::None, 0);
     CopyConstructor->setParams(&FromParam, 1);
-    ClassDecl->addDecl(CopyConstructor);
+    if (S)
+      PushOnScopeChains(CopyConstructor, S, true);
+    else
+      ClassDecl->addDecl(CopyConstructor);
   }
 
   if (!ClassDecl->hasUserDeclaredCopyAssignment()) {
@@ -2446,7 +2455,10 @@
 
     // Don't call addedAssignmentOperator. There is no way to distinguish an
     // implicit from an explicit assignment operator.
-    ClassDecl->addDecl(CopyAssignment);
+    if (S)
+      PushOnScopeChains(CopyAssignment, S, true);
+    else
+      ClassDecl->addDecl(CopyAssignment);
     AddOverriddenMethods(ClassDecl, CopyAssignment);
   }
 
@@ -2470,7 +2482,10 @@
     Destructor->setAccess(AS_public);
     Destructor->setImplicit();
     Destructor->setTrivial(ClassDecl->hasTrivialDestructor());
-    ClassDecl->addDecl(Destructor);
+    if (S)
+      PushOnScopeChains(Destructor, S, true);
+    else
+      ClassDecl->addDecl(Destructor);
 
     // This could be uniqued if it ever proves significant.
     Destructor->setTypeSourceInfo(Context.getTrivialTypeSourceInfo(Ty));

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=101047&r1=101046&r2=101047&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Mon Apr 12 12:09:20 2010
@@ -1169,7 +1169,7 @@
   ActOnFields(0, Instantiation->getLocation(), DeclPtrTy::make(Instantiation),
               Fields.data(), Fields.size(), SourceLocation(), SourceLocation(),
               0);
-  CheckCompletedCXXClass(Instantiation);
+  CheckCompletedCXXClass(/*Scope=*/0, Instantiation);
   if (Instantiation->isInvalidDecl())
     Invalid = true;
   

Modified: cfe/trunk/test/SemaCXX/implicit-member-functions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/implicit-member-functions.cpp?rev=101047&r1=101046&r2=101047&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/implicit-member-functions.cpp (original)
+++ cfe/trunk/test/SemaCXX/implicit-member-functions.cpp Mon Apr 12 12:09:20 2010
@@ -12,3 +12,30 @@
 struct D { }; // expected-note {{previous implicit declaration is here}}
 D::~D() { } // expected-error {{definition of implicitly declared destructor}}
 
+// Make sure that the special member functions are introduced for
+// name-lookup purposes and overload with user-declared
+// constructors and assignment operators.
+namespace PR6570 {
+  class A { };
+
+  class B {
+  public:
+    B() {}
+
+    B(const A& a) {
+      operator = (CONST);
+      operator = (a);
+    }
+
+    B& operator = (const A& a) {
+      return *this;
+    }
+
+    void f(const A &a) {
+      B b(a);
+    };
+
+    static const B CONST;
+  };
+
+}





More information about the cfe-commits mailing list