2929#include " swift/AST/PrintOptions.h"
3030#include " swift/AST/SourceFile.h"
3131#include " swift/AST/Stmt.h"
32+ #include " swift/AST/TypeCheckRequests.h"
3233#include " swift/AST/TypeRepr.h"
3334#include " swift/Basic/Assertions.h"
3435#include " swift/Basic/SourceManager.h"
@@ -1306,20 +1307,6 @@ void DiagnosticEngine::forwardTentativeDiagnosticsTo(
13061307 clearTentativeDiagnostics ();
13071308}
13081309
1309- // / Returns the access level of the least accessible PrettyPrintedDeclarations
1310- // / buffer that \p decl should appear in.
1311- // /
1312- // / This is always \c Public unless \p decl is a \c ValueDecl and its
1313- // / access level is below \c Public. (That can happen with @testable and
1314- // / @_private imports.)
1315- static AccessLevel getBufferAccessLevel (const Decl *decl) {
1316- AccessLevel level = AccessLevel::Public;
1317- if (auto *VD = dyn_cast<ValueDecl>(decl))
1318- level = VD->getFormalAccessScope ().accessLevelForDiagnostics ();
1319- if (level > AccessLevel::Public) level = AccessLevel::Public;
1320- return level;
1321- }
1322-
13231310std::optional<DiagnosticInfo>
13241311DiagnosticEngine::diagnosticInfoForDiagnostic (const Diagnostic &diagnostic) {
13251312 auto behavior = state.determineBehavior (diagnostic);
@@ -1334,154 +1321,12 @@ DiagnosticEngine::diagnosticInfoForDiagnostic(const Diagnostic &diagnostic) {
13341321 // has a location we can point to, use that location.
13351322 loc = decl->getLoc ();
13361323
1324+ // If the location of the decl is invalid still, try to pretty-print the
1325+ // declaration into a buffer and capture the source location there.
13371326 if (loc.isInvalid ()) {
1338- // There is no location we can point to. Pretty-print the declaration
1339- // so we can point to it.
1340- SourceLoc ppLoc = PrettyPrintedDeclarations[decl];
1341- if (ppLoc.isInvalid ()) {
1342- class TrackingPrinter : public StreamPrinter {
1343- SmallVectorImpl<std::pair<const Decl *, uint64_t >> &Entries;
1344- AccessLevel bufferAccessLevel;
1345-
1346- public:
1347- TrackingPrinter (
1348- SmallVectorImpl<std::pair<const Decl *, uint64_t >> &Entries,
1349- raw_ostream &OS, AccessLevel bufferAccessLevel) :
1350- StreamPrinter (OS), Entries(Entries),
1351- bufferAccessLevel (bufferAccessLevel) {}
1352-
1353- void printDeclLoc (const Decl *D) override {
1354- if (getBufferAccessLevel (D) == bufferAccessLevel)
1355- Entries.push_back ({ D, OS.tell () });
1356- }
1357- };
1358- SmallVector<std::pair<const Decl *, uint64_t >, 8 > entries;
1359- llvm::SmallString<128 > buffer;
1360- llvm::SmallString<128 > bufferName;
1361- const Decl *ppDecl = decl;
1362- {
1363- // The access level of the buffer we want to print. Declarations below
1364- // this access level will be omitted from the buffer; declarations
1365- // above it will be printed, but (except for Open declarations in the
1366- // Public buffer) will not be recorded in PrettyPrintedDeclarations as
1367- // the "true" SourceLoc for the declaration.
1368- AccessLevel bufferAccessLevel = getBufferAccessLevel (decl);
1369-
1370- // Figure out which declaration to print. It's the top-most
1371- // declaration (not a module).
1372- auto dc = decl->getDeclContext ();
1373-
1374- // FIXME: Horrible, horrible hackaround. We're not getting a
1375- // DeclContext everywhere we should.
1376- if (!dc) {
1377- return std::nullopt ;
1378- }
1379-
1380- while (!dc->isModuleContext ()) {
1381- switch (dc->getContextKind ()) {
1382- case DeclContextKind::Package:
1383- llvm_unreachable (" Not in a package context!" );
1384- break ;
1385- case DeclContextKind::Module:
1386- llvm_unreachable (" Not in a module context!" );
1387- break ;
1388-
1389- case DeclContextKind::FileUnit:
1390- case DeclContextKind::TopLevelCodeDecl:
1391- case DeclContextKind::SerializedTopLevelCodeDecl:
1392- break ;
1393-
1394- case DeclContextKind::ExtensionDecl:
1395- ppDecl = cast<ExtensionDecl>(dc);
1396- break ;
1397-
1398- case DeclContextKind::GenericTypeDecl:
1399- ppDecl = cast<GenericTypeDecl>(dc);
1400- break ;
1401-
1402- case DeclContextKind::Initializer:
1403- case DeclContextKind::AbstractClosureExpr:
1404- case DeclContextKind::SerializedAbstractClosure:
1405- case DeclContextKind::AbstractFunctionDecl:
1406- case DeclContextKind::SubscriptDecl:
1407- case DeclContextKind::EnumElementDecl:
1408- case DeclContextKind::MacroDecl:
1409- break ;
1410- }
1411-
1412- dc = dc->getParent ();
1413- }
1414-
1415- // Build the module name path (in reverse), which we use to
1416- // build the name of the buffer.
1417- SmallVector<StringRef, 4 > nameComponents;
1418- while (dc) {
1419- auto publicName = cast<ModuleDecl>(dc)->
1420- getPublicModuleName (/* onlyIfImported*/ true );
1421- nameComponents.push_back (publicName.str ());
1422- dc = dc->getParent ();
1423- }
1424-
1425- for (unsigned i = nameComponents.size (); i; --i) {
1426- bufferName += nameComponents[i-1 ];
1427- bufferName += ' .' ;
1428- }
1429-
1430- if (auto value = dyn_cast<ValueDecl>(ppDecl)) {
1431- bufferName += value->getBaseName ().userFacingName ();
1432- } else if (auto ext = dyn_cast<ExtensionDecl>(ppDecl)) {
1433- bufferName += ext->getExtendedType ().getString ();
1434- }
1435-
1436- // If we're using a lowered access level, give the buffer a distinct
1437- // name.
1438- if (bufferAccessLevel != AccessLevel::Public) {
1439- assert (bufferAccessLevel < AccessLevel::Public
1440- && " Above-public access levels should use public buffer" );
1441- bufferName += " (" ;
1442- bufferName += getAccessLevelSpelling (bufferAccessLevel);
1443- bufferName += " )" ;
1444- }
1445-
1446- // Pretty-print the declaration we've picked.
1447- llvm::raw_svector_ostream out (buffer);
1448- TrackingPrinter printer (entries, out, bufferAccessLevel);
1449- llvm::SaveAndRestore<bool > isPrettyPrinting (
1450- IsPrettyPrintingDecl, true );
1451- ppDecl->print (
1452- printer,
1453- PrintOptions::printForDiagnostics (
1454- bufferAccessLevel,
1455- decl->getASTContext ().TypeCheckerOpts .PrintFullConvention ));
1456- }
1457-
1458- // Build a buffer with the pretty-printed declaration.
1459- auto bufferID = SourceMgr.addMemBufferCopy (buffer, bufferName);
1460- auto memBufferStartLoc = SourceMgr.getLocForBufferStart (bufferID);
1461-
1462- SourceMgr.setGeneratedSourceInfo (
1463- bufferID,
1464- GeneratedSourceInfo{
1465- GeneratedSourceInfo::PrettyPrinted,
1466- CharSourceRange (),
1467- CharSourceRange (memBufferStartLoc, buffer.size ()),
1468- ASTNode (const_cast <Decl *>(ppDecl)).getOpaqueValue (),
1469- nullptr
1470- }
1471- );
1472-
1473- // Go through all of the pretty-printed entries and record their
1474- // locations.
1475- for (auto entry : entries) {
1476- PrettyPrintedDeclarations[entry.first ] =
1477- memBufferStartLoc.getAdvancedLoc (entry.second );
1478- }
1479-
1480- // Grab the pretty-printed location.
1481- ppLoc = PrettyPrintedDeclarations[decl];
1482- }
1483-
1484- loc = ppLoc;
1327+ loc = evaluateOrDefault (
1328+ decl->getASTContext ().evaluator , PrettyPrintDeclRequest{decl},
1329+ SourceLoc ());
14851330 }
14861331 }
14871332
0 commit comments