@@ -574,6 +574,56 @@ SymbolGraph::serializeDeclarationFragments(StringRef Key, Type T,
574574 T->print (Printer, Options);
575575}
576576
577+ namespace {
578+
579+ // / Returns the first satisfied protocol requirement for the given decl.
580+ const ValueDecl *getProtocolRequirement (const ValueDecl *VD) {
581+ auto reqs = VD->getSatisfiedProtocolRequirements ();
582+
583+ if (!reqs.empty ())
584+ return reqs.front ();
585+ else
586+ return nullptr ;
587+ }
588+
589+ // / Returns the protocol that the given decl is a requirement or conformance of, if any.
590+ const ProtocolDecl *getSourceProtocol (const Decl *D) {
591+ const auto *DC = D->getDeclContext ();
592+
593+ // First check to see whether it's declared directly in the protocol decl
594+ if (const auto *P = dyn_cast<ProtocolDecl>(DC))
595+ return P;
596+
597+ // Next look at whether it's an extension on a protocol
598+ if (const auto *Extension = dyn_cast<ExtensionDecl>(DC)) {
599+ if (const auto *ExtendedProtocol = Extension->getExtendedProtocolDecl ()) {
600+ return ExtendedProtocol;
601+ }
602+ }
603+
604+ // Then check to see whether it's an implementation of a protocol requirement
605+ if (const auto *VD = dyn_cast<ValueDecl>(D)) {
606+ if (const auto *Requirement = getProtocolRequirement (VD)) {
607+ if (const auto *P = dyn_cast<ProtocolDecl>(Requirement->getDeclContext ())) {
608+ return P;
609+ }
610+ }
611+ }
612+
613+ // If all those didn't work, there's no protocol to fetch
614+ return nullptr ;
615+ }
616+
617+ // / Returns whether the given decl is from a protocol, and that protocol has an underscored name.
618+ bool isFromUnderscoredProtocol (const Decl *D) {
619+ if (const auto *P = getSourceProtocol (D))
620+ return P->hasUnderscoredNaming ();
621+
622+ return false ;
623+ }
624+
625+ }
626+
577627bool SymbolGraph::isImplicitlyPrivate (const Decl *D,
578628 bool IgnoreContext) const {
579629 // Don't record unconditionally private declarations
@@ -582,7 +632,7 @@ bool SymbolGraph::isImplicitlyPrivate(const Decl *D,
582632 }
583633
584634 // Don't record effectively internal declarations if specified
585- if (D->hasUnderscoredNaming ()) {
635+ if (D->hasUnderscoredNaming () || isFromUnderscoredProtocol (D) ) {
586636 // Some implicit decls from Clang with underscored names sneak in, so throw those out
587637 if (const auto *clangD = D->getClangDecl ()) {
588638 if (clangD->isImplicit ())
0 commit comments