@@ -610,36 +610,50 @@ case DeclKind::ID: return cast<ID##Decl>(this)->getLocFromSource();
610610 llvm_unreachable (" Unknown decl kind" );
611611}
612612
613- const Decl::CachedExternalSourceLocs *Decl::getSerializedLocs () const {
614- if (CachedSerializedLocs) {
615- return CachedSerializedLocs;
616- }
613+ const ExternalSourceLocs *Decl::getSerializedLocs () const {
614+ auto &Context = getASTContext ();
615+ if (auto EL = Context.getExternalSourceLocs (this ).getValueOr (nullptr ))
616+ return EL;
617+
618+ static ExternalSourceLocs NullLocs{};
619+
617620 auto *File = cast<FileUnit>(getDeclContext ()->getModuleScopeContext ());
618- assert (File->getKind () == FileUnitKind::SerializedAST &&
619- " getSerializedLocs() should only be called on decls in "
620- " a 'SerializedASTFile'" );
621- auto Locs = File->getBasicLocsForDecl (this );
622- if (!Locs.hasValue ()) {
623- static const Decl::CachedExternalSourceLocs NullLocs{};
621+ if (File->getKind () != FileUnitKind::SerializedAST)
622+ return &NullLocs;
623+
624+ auto RawLocs = File->getExternalRawLocsForDecl (this );
625+ if (!RawLocs.hasValue ()) {
626+ // Don't read .swiftsourceinfo again on failure
627+ Context.setExternalSourceLocs (this , &NullLocs);
624628 return &NullLocs;
625629 }
626- auto *Result = getASTContext ().Allocate <Decl::CachedExternalSourceLocs>();
627- auto &SM = getASTContext ().SourceMgr ;
628- #define CASE (X ) \
629- Result->X = SM.getLocFromExternalSource (Locs->SourceFilePath , Locs->X .Line , \
630- Locs->X .Column );
631- CASE (Loc)
632- CASE (StartLoc)
633- CASE (EndLoc)
634- #undef CASE
635630
636- for (const auto &LineColumnAndLength : Locs->DocRanges ) {
637- auto Start = SM.getLocFromExternalSource (Locs->SourceFilePath ,
638- LineColumnAndLength.first .Line ,
639- LineColumnAndLength.first .Column );
640- Result->DocRanges .push_back ({ Start, LineColumnAndLength.second });
631+ auto &SM = getASTContext ().SourceMgr ;
632+ unsigned BufferID = SM.getExternalSourceBufferID (RawLocs->SourceFilePath );
633+ if (!BufferID) {
634+ // Don't try open the file again on failure
635+ Context.setExternalSourceLocs (this , &NullLocs);
636+ return &NullLocs;
641637 }
642638
639+ auto ResolveLoc = [&](const ExternalSourceLocs::RawLoc &Raw) -> SourceLoc {
640+ // If the decl had a presumed loc, create its virtual file so that
641+ // getPresumedLineAndColForLoc works from serialized locations as well.
642+ if (Raw.Directive .isValid ()) {
643+ auto &LD = Raw.Directive ;
644+ SourceLoc Loc = SM.getLocForOffset (BufferID, LD.Offset );
645+ SM.createVirtualFile (Loc, LD.Name , LD.LineOffset , LD.Length );
646+ }
647+ return SM.getLocForOffset (BufferID, Raw.Offset );
648+ };
649+
650+ auto *Result = getASTContext ().Allocate <ExternalSourceLocs>();
651+ Result->BufferID = BufferID;
652+ Result->Loc = ResolveLoc (RawLocs->Loc );
653+ for (auto &Range : RawLocs->DocRanges ) {
654+ Result->DocRanges .emplace_back (ResolveLoc (Range.first ), Range.second );
655+ }
656+ Context.setExternalSourceLocs (this , Result);
643657 return Result;
644658}
645659
0 commit comments