decl list, and remove some workarounds that were due to this. Thanks to Eli for
pointing this out and providing the test case.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80745
91177308-0d34-0410-b5e6-
96231b3b80d8
!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");
}
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;
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 {
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;
--- /dev/null
+// 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;
+};
+