Index: llvm/tools/dsymutil/DwarfLinker.cpp =================================================================== --- llvm/tools/dsymutil/DwarfLinker.cpp +++ llvm/tools/dsymutil/DwarfLinker.cpp @@ -100,6 +100,31 @@ namespace { +/// Small helper that resolves and caches file paths. +class CachedPathResolver { +public: + /// Resolve a path and cache its result. + std::string resolve(std::string Path) { + StringRef FileName = sys::path::filename(Path); + SmallString<256> ParentPath = sys::path::parent_path(Path); + + // If the ParentPath has not yet been resolved, resolve and cache it for + // future look-ups. + if(!ResolvedPaths.count(ParentPath)) { + SmallString<256> RealPath; + sys::fs::real_path(ParentPath, RealPath); + ResolvedPaths.insert({ParentPath, RealPath}); + } + + // Join the file name again with the resolved path. + SmallString<256> ResolvedPath = ResolvedPaths[ParentPath]; + sys::path::append(ResolvedPath, FileName); + return StringRef(ResolvedPath); + } +private: + StringMap> ResolvedPaths; +}; + /// Retrieve the section named \a SecName in \a Obj. /// /// To accommodate for platform discrepancies, the name passed should be @@ -234,6 +259,8 @@ DeclContext Root; DeclContext::Map Contexts; + /// Cache resolved paths from the line table. + CachedPathResolver PathResolver; public: /// Get the child of \a Context described by \a DIE in \a Unit. The /// required strings will be interned in \a StringPool. @@ -428,21 +455,6 @@ const std::vector &getNamespaces() const { return Namespaces; } const std::vector &getObjC() const { return ObjC; } - /// Get the full path for file \a FileNum in the line table - StringRef getResolvedPath(unsigned FileNum) { - if (FileNum >= ResolvedPaths.size()) - return StringRef(); - return ResolvedPaths[FileNum]; - } - - /// Set the fully resolved path for the line-table's file \a FileNum - /// to \a Path. - void setResolvedPath(unsigned FileNum, StringRef Path) { - if (ResolvedPaths.size() <= FileNum) - ResolvedPaths.resize(FileNum + 1); - ResolvedPaths[FileNum] = Path; - } - private: DWARFUnit &OrigUnit; unsigned ID; @@ -493,12 +505,6 @@ std::vector ObjC; /// @} - /// Cached resolved paths from the line table. - /// Note, the StringRefs here point in to the intern (uniquing) string pool. - /// This means that a StringRef returned here doesn't need to then be uniqued - /// for the purposes of getting a unique address for each string. - std::vector ResolvedPaths; - /// Is this unit subject to the ODR rule? bool HasODR; @@ -1380,7 +1386,6 @@ void reportWarning(const Twine &Warning, const DWARFDie *DIE = nullptr) const; - private: /// Called at the start of a debug object link. void startDebugObject(DWARFContext &, DebugMapObject &); @@ -1763,6 +1768,7 @@ bool ModuleCacheHintDisplayed = false; bool ArchiveHintDisplayed = false; + }; } // end anonymous namespace @@ -1933,32 +1939,21 @@ if (!Name && Tag == dwarf::DW_TAG_namespace) FileNum = 1; - // FIXME: Passing U.getOrigUnit().getCompilationDir() - // instead of "" would allow more uniquing, but for now, do - // it this way to match dsymutil-classic. if (LT->hasFileAtIndex(FileNum)) { Line = dwarf::toUnsigned(DIE.find(dwarf::DW_AT_decl_line), 0); - // Cache the resolved paths, because calling realpath is expansive. - StringRef ResolvedPath = U.getResolvedPath(FileNum); - if (!ResolvedPath.empty()) { - FileRef = ResolvedPath; - } else { - std::string File; - bool gotFileName = - LT->getFileNameByIndex(FileNum, "", - DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, - File); - (void)gotFileName; - assert(gotFileName && "Must get file name from line table"); -#ifdef HAVE_REALPATH - char RealPath[PATH_MAX + 1]; - RealPath[PATH_MAX] = 0; - if (::realpath(File.c_str(), RealPath)) - File = RealPath; -#endif - FileRef = StringPool.internString(File); - U.setResolvedPath(FileNum, FileRef); - } + + // FIXME: Passing U.getOrigUnit().getCompilationDir() + // instead of "" would allow more uniquing, but for now, do + // it this way to match dsymutil-classic. + std::string File; + bool FoundFile = + LT->getFileNameByIndex(FileNum, "", + DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, + File); + (void)FoundFile; + assert(FoundFile && "Must get file name from line table"); + + FileRef = StringPool.internString(PathResolver.resolve(File)); } } }