[cfe-commits] r101122 - in /cfe/trunk: lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp test/CXX/class.access/class.friend/p1.cpp test/SemaCXX/implicit-member-functions.cpp
John McCall
rjmccall at apple.com
Tue Apr 13 00:45:41 PDT 2010
Author: rjmccall
Date: Tue Apr 13 02:45:41 2010
New Revision: 101122
URL: http://llvm.org/viewvc/llvm-project?rev=101122&view=rev
Log:
Allow classes to befriend implicitly-declared members. Fixes PR6207 for
members of non-templated classes.
Modified:
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/CXX/class.access/class.friend/p1.cpp
cfe/trunk/test/SemaCXX/implicit-member-functions.cpp
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=101122&r1=101121&r2=101122&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Apr 13 02:45:41 2010
@@ -1058,10 +1058,14 @@
}
const CXXMethodDecl* OldMethod = dyn_cast<CXXMethodDecl>(Old);
- const CXXMethodDecl* NewMethod = dyn_cast<CXXMethodDecl>(New);
+ CXXMethodDecl* NewMethod = dyn_cast<CXXMethodDecl>(New);
if (OldMethod && NewMethod) {
- if (!NewMethod->getFriendObjectKind() &&
- NewMethod->getLexicalDeclContext()->isRecord()) {
+ // Preserve triviality.
+ NewMethod->setTrivial(OldMethod->isTrivial());
+
+ bool isFriend = NewMethod->getFriendObjectKind();
+
+ if (!isFriend && NewMethod->getLexicalDeclContext()->isRecord()) {
// -- Member function declarations with the same name and the
// same parameter types cannot be overloaded if any of them
// is a static member function declaration.
@@ -1087,14 +1091,19 @@
Diag(New->getLocation(), NewDiag);
Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
- } else {
- if (OldMethod->isImplicit()) {
+
+ // Complain if this is an explicit declaration of a special
+ // member that was initially declared implicitly.
+ //
+ // As an exception, it's okay to befriend such methods in order
+ // to permit the implicit constructor/destructor/operator calls.
+ } else if (OldMethod->isImplicit()) {
+ if (isFriend) {
+ NewMethod->setImplicit();
+ } else {
Diag(NewMethod->getLocation(),
diag::err_definition_of_implicitly_declared_member)
- << New << getSpecialMember(Context, OldMethod);
-
- Diag(OldMethod->getLocation(),
- diag::note_previous_implicit_declaration);
+ << New << getSpecialMember(Context, OldMethod);
return true;
}
}
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=101122&r1=101121&r2=101122&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Apr 13 02:45:41 2010
@@ -2682,8 +2682,12 @@
}
}
- // Notify the class that we've added a constructor.
- ClassDecl->addedConstructor(Context, Constructor);
+ // Notify the class that we've added a constructor. In principle we
+ // don't need to do this for out-of-line declarations; in practice
+ // we only instantiate the most recent declaration of a method, so
+ // we have to call this for everything but friends.
+ if (!Constructor->getFriendObjectKind())
+ ClassDecl->addedConstructor(Context, Constructor);
}
/// CheckDestructor - Checks a fully-formed destructor for well-formedness,
Modified: cfe/trunk/test/CXX/class.access/class.friend/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class.access/class.friend/p1.cpp?rev=101122&r1=101121&r2=101122&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class.access/class.friend/p1.cpp (original)
+++ cfe/trunk/test/CXX/class.access/class.friend/p1.cpp Tue Apr 13 02:45:41 2010
@@ -211,3 +211,14 @@
};
}
}
+
+// PR6207
+namespace test6 {
+ struct A {};
+
+ struct B {
+ friend A::A();
+ friend A::~A();
+ friend A &A::operator=(const A&);
+ };
+}
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=101122&r1=101121&r2=101122&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/implicit-member-functions.cpp (original)
+++ cfe/trunk/test/SemaCXX/implicit-member-functions.cpp Tue Apr 13 02:45:41 2010
@@ -1,15 +1,15 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-struct A { }; // expected-note {{previous implicit declaration is here}}
+struct A { };
A::A() { } // expected-error {{definition of implicitly declared constructor}}
-struct B { }; // expected-note {{previous implicit declaration is here}}
+struct B { };
B::B(const B&) { } // expected-error {{definition of implicitly declared copy constructor}}
-struct C { }; // expected-note {{previous implicit declaration is here}}
+struct C { };
C& C::operator=(const C&) { return *this; } // expected-error {{definition of implicitly declared copy assignment operator}}
-struct D { }; // expected-note {{previous implicit declaration is here}}
+struct D { };
D::~D() { } // expected-error {{definition of implicitly declared destructor}}
// Make sure that the special member functions are introduced for
More information about the cfe-commits
mailing list