diff options
-rw-r--r-- | lib/AST/DeclBase.cpp | 5 | ||||
-rw-r--r-- | lib/AST/DeclPrinter.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 10 | ||||
-rw-r--r-- | test/CXX/class/class.friend/p1.cpp | 2 | ||||
-rw-r--r-- | test/SemaCXX/friend-class-nodecl.cpp | 10 |
5 files changed, 20 insertions, 11 deletions
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index c24dac9104..acdbdbe422 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -385,11 +385,6 @@ void Decl::CheckAccessDeclContext() const { !isa<CXXRecordDecl>(getDeclContext())) return; - // FIXME: This check should not be necessary - If a friend decl refers to an - // undeclared decl, then that decl shouldn't be in any decl context. - if (getFriendObjectKind() == FOK_Undeclared) - return; - assert(Access != AS_none && "Access specifier is AS_none inside a record decl"); } diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index 275f2db82b..275fa69723 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -203,9 +203,7 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) { if (PrintAccess) { AccessSpecifier AS = D->getAccess(); - if (AS != CurAS && - // FIXME: This check shouldn't be necessary. - D->getFriendObjectKind() == Decl::FOK_Undeclared) { + if (AS != CurAS) { Print(AS); Out << ":\n"; CurAS = AS; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 8eb2c717b4..86222ffe14 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -4328,7 +4328,15 @@ CreateNewDecl: New->startDefinition(); // If this has an identifier, add it to the scope stack. - if (Name && TUK != TUK_Friend) { + if (TUK == TUK_Friend) { + // Friend tag decls are visible in fairly strange ways. + if (!CurContext->isDependentContext()) { + DeclContext *DC = New->getDeclContext()->getLookupContext(); + DC->makeDeclVisibleInContext(New, /* Recoverable = */ false); + if (Scope *EnclosingScope = getScopeForDeclContext(S, DC)) + PushOnScopeChains(New, EnclosingScope, /* AddToContext = */ false); + } + } else if (Name) { S = getNonFieldDeclScope(S); PushOnScopeChains(New, S); } else { diff --git a/test/CXX/class/class.friend/p1.cpp b/test/CXX/class/class.friend/p1.cpp index 5a9114006f..9ba02727a0 100644 --- a/test/CXX/class/class.friend/p1.cpp +++ b/test/CXX/class/class.friend/p1.cpp @@ -63,8 +63,6 @@ class A { friend ftypedef typedeffed_function; // okay (because it's not declared as a member) }; -class UndeclaredSoFar { }; - A::UndeclaredSoFar y; // expected-error {{ unknown type name 'UndeclaredSoFar' }} class PreDeclared; diff --git a/test/SemaCXX/friend-class-nodecl.cpp b/test/SemaCXX/friend-class-nodecl.cpp new file mode 100644 index 0000000000..de12eaf741 --- /dev/null +++ b/test/SemaCXX/friend-class-nodecl.cpp @@ -0,0 +1,10 @@ +// RUN: clang-cc -ast-print %s -o %t && +// RUN: not grep '^ *class B' %t + +// Tests that the tag decls in friend declarations aren't added to the +// declaring class's decl chain. + +class A { + friend class B; +}; + |