diff options
author | Owen Reynolds <gbreynoo@gmail.com> | 2019-06-04 10:13:03 +0000 |
---|---|---|
committer | Owen Reynolds <gbreynoo@gmail.com> | 2019-06-04 10:13:03 +0000 |
commit | 5d5078e341f593944d9badd53e374e6b319282da (patch) | |
tree | fb8ff535fd53402c5d82253f8c11143aed9ca321 /llvm/lib/Object/ArchiveWriter.cpp | |
parent | 3018d505a3643f1b191da1e2cc99493708ede186 (diff) | |
download | bcm5719-llvm-5d5078e341f593944d9badd53e374e6b319282da.tar.gz bcm5719-llvm-5d5078e341f593944d9badd53e374e6b319282da.zip |
[llvm-ar] Reapply Fix relative thin archive path handling
Includes a fix for an introduced build failure due to a post c++11 use of std::mismatch.
This fixes some thin archive relative path issues, paths are shortened where possible and paths are output correctly when using the display table command.
Differential Revision: https://reviews.llvm.org/D59491
llvm-svn: 362484
Diffstat (limited to 'llvm/lib/Object/ArchiveWriter.cpp')
-rw-r--r-- | llvm/lib/Object/ArchiveWriter.cpp | 51 |
1 files changed, 34 insertions, 17 deletions
diff --git a/llvm/lib/Object/ArchiveWriter.cpp b/llvm/lib/Object/ArchiveWriter.cpp index 849d2835772..201ff1326f0 100644 --- a/llvm/lib/Object/ArchiveWriter.cpp +++ b/llvm/lib/Object/ArchiveWriter.cpp @@ -494,29 +494,46 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames, } namespace llvm { + +static ErrorOr<SmallString<128>> canonicalizePath(StringRef P) { + SmallString<128> Ret = P; + std::error_code Err = sys::fs::make_absolute(Ret); + if (Err) + return Err; + sys::path::remove_dots(Ret, /*removedotdot*/ true); + return Ret; +} + // Compute the relative path from From to To. -std::string computeArchiveRelativePath(StringRef From, StringRef To) { - if (sys::path::is_absolute(From) || sys::path::is_absolute(To)) - return To; - - StringRef DirFrom = sys::path::parent_path(From); - auto FromI = sys::path::begin(DirFrom); - auto ToI = sys::path::begin(To); - while (*FromI == *ToI) { - ++FromI; - ++ToI; - } +Expected<std::string> computeArchiveRelativePath(StringRef From, StringRef To) { + ErrorOr<SmallString<128>> PathToOrErr = canonicalizePath(To); + ErrorOr<SmallString<128>> DirFromOrErr = canonicalizePath(From); + if (!PathToOrErr || !DirFromOrErr) + return errorCodeToError(std::error_code(errno, std::generic_category())); + + const SmallString<128> &PathTo = *PathToOrErr; + const SmallString<128> &DirFrom = sys::path::parent_path(*DirFromOrErr); + + // Can't construct a relative path between different roots + if (sys::path::root_name(PathTo) != sys::path::root_name(DirFrom)) + return sys::path::convert_to_slash(PathTo); + + // Skip common prefixes + auto FromTo = + std::mismatch(sys::path::begin(DirFrom), sys::path::end(DirFrom), + sys::path::begin(PathTo)); + auto FromI = FromTo.first; + auto ToI = FromTo.second; + // Construct relative path SmallString<128> Relative; for (auto FromE = sys::path::end(DirFrom); FromI != FromE; ++FromI) - sys::path::append(Relative, ".."); + sys::path::append(Relative, sys::path::Style::posix, ".."); - for (auto ToE = sys::path::end(To); ToI != ToE; ++ToI) - sys::path::append(Relative, *ToI); + for (auto ToE = sys::path::end(PathTo); ToI != ToE; ++ToI) + sys::path::append(Relative, sys::path::Style::posix, *ToI); - // Replace backslashes with slashes so that the path is portable between *nix - // and Windows. - return sys::path::convert_to_slash(Relative); + return Relative.str(); } Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers, |