[cfe-commits] r112524 - in /cfe/trunk: lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaTemplate/inject-templated-friend-post.cpp
Gabor Greif
ggreif at gmail.com
Mon Aug 30 14:10:05 PDT 2010
Author: ggreif
Date: Mon Aug 30 16:10:05 2010
New Revision: 112524
URL: http://llvm.org/viewvc/llvm-project?rev=112524&view=rev
Log:
fix dual aspect of PR8007,
namely when the friend function prototype is already used
at the point of the template definition that is supposed
to inject the friend function. Testcase verifies four
scenarios.
I would like receive some code review for this.
Modified:
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/SemaTemplate/inject-templated-friend-post.cpp
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=112524&r1=112523&r2=112524&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Aug 30 16:10:05 2010
@@ -1166,7 +1166,9 @@
PrincipalDecl->setObjectOfFriendDecl(PrevDecl != 0);
DC->makeDeclVisibleInContext(PrincipalDecl, /*Recoverable=*/ false);
-
+
+ bool queuedInstantiation = false;
+
if (!SemaRef.getLangOptions().CPlusPlus0x &&
D->isThisDeclarationADefinition()) {
// Check for a function body.
@@ -1185,7 +1187,22 @@
R != REnd; ++R) {
if (*R == Function)
continue;
- if (R->getFriendObjectKind() != Decl::FOK_None) {
+ switch (R->getFriendObjectKind()) {
+ case Decl::FOK_None:
+ if (!queuedInstantiation && R->isUsed(false)) {
+ if (MemberSpecializationInfo *MSInfo
+ = Function->getMemberSpecializationInfo()) {
+ if (MSInfo->getPointOfInstantiation().isInvalid()) {
+ SourceLocation Loc = R->getLocation(); // FIXME
+ MSInfo->setPointOfInstantiation(Loc);
+ SemaRef.PendingLocalImplicitInstantiations.push_back(
+ std::make_pair(Function, Loc));
+ queuedInstantiation = true;
+ }
+ }
+ }
+ break;
+ default:
if (const FunctionDecl *RPattern
= R->getTemplateInstantiationPattern())
if (RPattern->hasBody(RPattern)) {
@@ -1198,7 +1215,6 @@
}
}
}
-
}
if (Function->isOverloadedOperator() && !DC->isRecord() &&
Modified: cfe/trunk/test/SemaTemplate/inject-templated-friend-post.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/inject-templated-friend-post.cpp?rev=112524&r1=112523&r2=112524&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/inject-templated-friend-post.cpp (original)
+++ cfe/trunk/test/SemaTemplate/inject-templated-friend-post.cpp Mon Aug 30 16:10:05 2010
@@ -1,8 +1,9 @@
// RUN: %clang %s -S -emit-llvm -o - | grep -e "define linkonce_odr.*_ZlsR11std_ostreamRK8StreamerI3FooE"
+// RUN: %clang %s -S -emit-llvm -o - -DPROTOTYPE | grep -e "define linkonce_odr.*_ZlsR11std_ostreamRK8StreamerI3FooE"
// RUN: %clang -cc1 %s -DREDEFINE -verify
+// RUN: %clang -cc1 %s -DPROTOTYPE -DREDEFINE -verify
// PR8007: friend function not instantiated, reordered version.
// Corresponds to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38392
-// XFAIL: *
struct std_ostream
{
@@ -17,6 +18,7 @@
typedef struct Foo {} Foo;
std_ostream& operator << (std_ostream&, const Streamer<Foo>&);
+
void test(const Streamer<Foo>& foo)
{
cout << foo;
@@ -38,6 +40,21 @@
void operator () (std_ostream&) const;
};
+#ifdef PROTOTYPE
+std_ostream& operator << (std_ostream&, const Streamer<Foo>&);
+#endif
+
+#ifdef INSTANTIATE
+template struct Streamer<Foo>;
+#endif
+
+#ifdef REDEFINE
+std_ostream& operator << (std_ostream& o, const Streamer<Foo>&) // expected-note{{is here}}
+{
+ return o;
+}
+#endif
+
template <>
void Streamer<Foo>::operator () (std_ostream& o) const // expected-note{{requested here}}
{
@@ -49,10 +66,3 @@
test(foo);
}
-#ifdef REDEFINE
-std_ostream& operator << (std_ostream& o, const Streamer<Foo>&) // expected-note{{is here}}
-{
- // Sema should flag this as a redefinition
- return o;
-}
-#endif
More information about the cfe-commits
mailing list