PrincipalDecl->setObjectOfFriendDecl(PrevDecl != 0);
DC->makeDeclVisibleInContext(PrincipalDecl, /*Recoverable=*/ false);
-
+
+ bool queuedInstantiation = false;
+
if (!SemaRef.getLangOptions().CPlusPlus0x &&
D->isThisDeclarationADefinition()) {
// Check for a function body.
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)) {
}
}
}
-
}
if (Function->isOverloadedOperator() && !DC->isRecord() &&
// 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
{
typedef struct Foo {} Foo;
std_ostream& operator << (std_ostream&, const Streamer<Foo>&);
+
void test(const Streamer<Foo>& foo)
{
cout << foo;
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}}
{
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