@@ -596,6 +596,35 @@ class ASTVisitor
596
596
return FTD->getAccessUnsafe ();
597
597
}
598
598
599
+ // KRYSTIAN NOTE: since friend declarations are not members,
600
+ // this horrible hack computes their access based on the default
601
+ // access for the tag they appear in, and any AccessSpecDecls which
602
+ // appear lexically before them
603
+ if (const auto * FD = dyn_cast<FriendDecl>(D))
604
+ {
605
+ const auto * RD = dyn_cast<CXXRecordDecl>(
606
+ FD->getLexicalDeclContext ());
607
+ // RD should never be null in well-formed code,
608
+ // but clang error recovery may build an AST
609
+ // where the assumption will not hold
610
+ if (! RD)
611
+ return AccessSpecifier::AS_public;
612
+ auto access = RD->isClass () ?
613
+ AccessSpecifier::AS_private :
614
+ AccessSpecifier::AS_public;
615
+ for (auto * M : RD->decls ())
616
+ {
617
+ if (auto * AD = dyn_cast<AccessSpecDecl>(M))
618
+ access = AD->getAccessUnsafe ();
619
+ else if (M == FD)
620
+ return access ;
621
+ }
622
+ // KRYSTIAN FIXME: will this ever be hit?
623
+ // it would require a friend declaration that is
624
+ // not in the lexical traversal of its lexical context
625
+ MRDOCS_UNREACHABLE ();
626
+ }
627
+
599
628
// in all other cases, use the access of this declaration
600
629
return D->getAccessUnsafe ();
601
630
}
0 commit comments