@@ -846,6 +846,20 @@ void DiagnosticEngine::emitTentativeDiagnostics() {
846846 TentativeDiagnostics.clear ();
847847}
848848
849+ // / Returns the access level of the least accessible PrettyPrintedDeclarations
850+ // / buffer that \p decl should appear in.
851+ // /
852+ // / This is always \c Public unless \p decl is a \c ValueDecl and its
853+ // / access level is below \c Public. (That can happen with @testable and
854+ // / @_private imports.)
855+ static AccessLevel getBufferAccessLevel (const Decl *decl) {
856+ AccessLevel level = AccessLevel::Public;
857+ if (auto *VD = dyn_cast<ValueDecl>(decl))
858+ level = VD->getFormalAccessScope ().accessLevelForDiagnostics ();
859+ if (level > AccessLevel::Public) level = AccessLevel::Public;
860+ return level;
861+ }
862+
849863Optional<DiagnosticInfo>
850864DiagnosticEngine::diagnosticInfoForDiagnostic (const Diagnostic &diagnostic) {
851865 auto behavior = state.determineBehavior (diagnostic.getID ());
@@ -867,21 +881,31 @@ DiagnosticEngine::diagnosticInfoForDiagnostic(const Diagnostic &diagnostic) {
867881 if (ppLoc.isInvalid ()) {
868882 class TrackingPrinter : public StreamPrinter {
869883 SmallVectorImpl<std::pair<const Decl *, uint64_t >> &Entries;
884+ AccessLevel bufferAccessLevel;
870885
871886 public:
872887 TrackingPrinter (
873888 SmallVectorImpl<std::pair<const Decl *, uint64_t >> &Entries,
874- raw_ostream &OS) :
875- StreamPrinter (OS), Entries(Entries) {}
889+ raw_ostream &OS, AccessLevel bufferAccessLevel) :
890+ StreamPrinter (OS), Entries(Entries),
891+ bufferAccessLevel (bufferAccessLevel) {}
876892
877893 void printDeclLoc (const Decl *D) override {
878- Entries.push_back ({ D, OS.tell () });
894+ if (getBufferAccessLevel (D) == bufferAccessLevel)
895+ Entries.push_back ({ D, OS.tell () });
879896 }
880897 };
881898 SmallVector<std::pair<const Decl *, uint64_t >, 8 > entries;
882899 llvm::SmallString<128 > buffer;
883900 llvm::SmallString<128 > bufferName;
884901 {
902+ // The access level of the buffer we want to print. Declarations below
903+ // this access level will be omitted from the buffer; declarations
904+ // above it will be printed, but (except for Open declarations in the
905+ // Public buffer) will not be recorded in PrettyPrintedDeclarations as
906+ // the "true" SourceLoc for the declaration.
907+ AccessLevel bufferAccessLevel = getBufferAccessLevel (decl);
908+
885909 // Figure out which declaration to print. It's the top-most
886910 // declaration (not a module).
887911 const Decl *ppDecl = decl;
@@ -942,10 +966,21 @@ DiagnosticEngine::diagnosticInfoForDiagnostic(const Diagnostic &diagnostic) {
942966 bufferName += ext->getExtendedType ().getString ();
943967 }
944968
969+ // If we're using a lowered access level, give the buffer a distinct
970+ // name.
971+ if (bufferAccessLevel != AccessLevel::Public) {
972+ assert (bufferAccessLevel < AccessLevel::Public
973+ && " Above-public access levels should use public buffer" );
974+ bufferName += " (" ;
975+ bufferName += getAccessLevelSpelling (bufferAccessLevel);
976+ bufferName += " )" ;
977+ }
978+
945979 // Pretty-print the declaration we've picked.
946980 llvm::raw_svector_ostream out (buffer);
947- TrackingPrinter printer (entries, out);
948- ppDecl->print (printer, PrintOptions::printForDiagnostics ());
981+ TrackingPrinter printer (entries, out, bufferAccessLevel);
982+ ppDecl->print (printer,
983+ PrintOptions::printForDiagnostics (bufferAccessLevel));
949984 }
950985
951986 // Build a buffer with the pretty-printed declaration.
0 commit comments