clayborg updated this revision to Diff 143643.
clayborg added a comment.

Fix comment typo


https://reviews.llvm.org/D45977

Files:
  include/lldb/Core/FileSpecList.h
  include/lldb/Utility/FileSpec.h
  source/Breakpoint/BreakpointResolverFileLine.cpp
  source/Core/FileSpecList.cpp
  source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
  source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
  source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  source/Symbol/CompileUnit.cpp
  source/Symbol/Declaration.cpp
  source/Utility/FileSpec.cpp
  unittests/Utility/FileSpecTest.cpp

Index: unittests/Utility/FileSpecTest.cpp
===================================================================
--- unittests/Utility/FileSpecTest.cpp
+++ unittests/Utility/FileSpecTest.cpp
@@ -54,17 +54,14 @@
 
   FileSpec fs_posix_trailing_slash("/foo/bar/", false,
                                    FileSpec::ePathSyntaxPosix);
-  EXPECT_STREQ("/foo/bar/.", fs_posix_trailing_slash.GetCString());
-  EXPECT_STREQ("/foo/bar", fs_posix_trailing_slash.GetDirectory().GetCString());
-  EXPECT_STREQ(".", fs_posix_trailing_slash.GetFilename().GetCString());
+  EXPECT_STREQ("/foo/bar", fs_posix_trailing_slash.GetCString());
+  EXPECT_STREQ("/foo", fs_posix_trailing_slash.GetDirectory().GetCString());
+  EXPECT_STREQ("bar", fs_posix_trailing_slash.GetFilename().GetCString());
 
   FileSpec fs_windows_trailing_slash("F:\\bar\\", false,
                                      FileSpec::ePathSyntaxWindows);
-  EXPECT_STREQ("F:\\bar\\.", fs_windows_trailing_slash.GetCString());
-  // EXPECT_STREQ("F:\\bar",
-  // fs_windows_trailing_slash.GetDirectory().GetCString()); // It returns
-  // "F:/bar"
-  EXPECT_STREQ(".", fs_windows_trailing_slash.GetFilename().GetCString());
+  EXPECT_STREQ("F:\\bar", fs_windows_trailing_slash.GetCString());
+  EXPECT_STREQ("bar", fs_windows_trailing_slash.GetFilename().GetCString());
 }
 
 TEST(FileSpecTest, AppendPathComponent) {
@@ -131,32 +128,13 @@
   EXPECT_STREQ("F:\\bar", fs_windows_root.GetCString());
 }
 
-static void Compare(const FileSpec &one, const FileSpec &two, bool full_match,
-                    bool remove_backup_dots, bool result) {
-  EXPECT_EQ(result, FileSpec::Equal(one, two, full_match, remove_backup_dots))
-      << "File one: " << one.GetCString() << "\nFile two: " << two.GetCString()
-      << "\nFull match: " << full_match
-      << "\nRemove backup dots: " << remove_backup_dots;
-}
-
 TEST(FileSpecTest, EqualSeparator) {
   FileSpec backward("C:\\foo\\bar", false, FileSpec::ePathSyntaxWindows);
   FileSpec forward("C:/foo/bar", false, FileSpec::ePathSyntaxWindows);
   EXPECT_EQ(forward, backward);
-
-  const bool full_match = true;
-  const bool remove_backup_dots = true;
-  const bool match = true;
-  Compare(forward, backward, full_match, remove_backup_dots, match);
-  Compare(forward, backward, full_match, !remove_backup_dots, match);
-  Compare(forward, backward, !full_match, remove_backup_dots, match);
-  Compare(forward, backward, !full_match, !remove_backup_dots, match);
 }
 
 TEST(FileSpecTest, EqualDotsWindows) {
-  const bool full_match = true;
-  const bool remove_backup_dots = true;
-  const bool match = true;
   std::pair<const char *, const char *> tests[] = {
       {R"(C:\foo\bar\baz)", R"(C:\foo\foo\..\bar\baz)"},
       {R"(C:\bar\baz)", R"(C:\foo\..\bar\baz)"},
@@ -170,18 +148,11 @@
   for (const auto &test : tests) {
     FileSpec one(test.first, false, FileSpec::ePathSyntaxWindows);
     FileSpec two(test.second, false, FileSpec::ePathSyntaxWindows);
-    EXPECT_NE(one, two);
-    Compare(one, two, full_match, remove_backup_dots, match);
-    Compare(one, two, full_match, !remove_backup_dots, !match);
-    Compare(one, two, !full_match, remove_backup_dots, match);
-    Compare(one, two, !full_match, !remove_backup_dots, !match);
+    EXPECT_EQ(one, two);
   }
 }
 
 TEST(FileSpecTest, EqualDotsPosix) {
-  const bool full_match = true;
-  const bool remove_backup_dots = true;
-  const bool match = true;
   std::pair<const char *, const char *> tests[] = {
       {R"(/foo/bar/baz)", R"(/foo/foo/../bar/baz)"},
       {R"(/bar/baz)", R"(/foo/../bar/baz)"},
@@ -193,18 +164,11 @@
   for (const auto &test : tests) {
     FileSpec one(test.first, false, FileSpec::ePathSyntaxPosix);
     FileSpec two(test.second, false, FileSpec::ePathSyntaxPosix);
-    EXPECT_NE(one, two);
-    Compare(one, two, full_match, remove_backup_dots, match);
-    Compare(one, two, full_match, !remove_backup_dots, !match);
-    Compare(one, two, !full_match, remove_backup_dots, match);
-    Compare(one, two, !full_match, !remove_backup_dots, !match);
+    EXPECT_EQ(one, two);
   }
 }
 
 TEST(FileSpecTest, EqualDotsPosixRoot) {
-  const bool full_match = true;
-  const bool remove_backup_dots = true;
-  const bool match = true;
   std::pair<const char *, const char *> tests[] = {
       {R"(/)", R"(/..)"},
       {R"(/)", R"(/.)"},
@@ -214,11 +178,7 @@
   for (const auto &test : tests) {
     FileSpec one(test.first, false, FileSpec::ePathSyntaxPosix);
     FileSpec two(test.second, false, FileSpec::ePathSyntaxPosix);
-    EXPECT_NE(one, two);
-    Compare(one, two, full_match, remove_backup_dots, match);
-    Compare(one, two, full_match, !remove_backup_dots, !match);
-    Compare(one, two, !full_match, remove_backup_dots, !match);
-    Compare(one, two, !full_match, !remove_backup_dots, !match);
+    EXPECT_EQ(one, two);
   }
 }
 
@@ -245,12 +205,14 @@
       {"foo/..", "."},
       {"foo/../bar", "bar"},
       {"../foo/..", ".."},
-      {"./foo", "foo"},
+      {"./foo", "./foo"},
+      {"././foo", "./foo"},
+      {"../foo", "../foo"},
+      {"../../foo", "../../foo"},
   };
   for (auto test : posix_tests) {
     EXPECT_EQ(test.second,
               FileSpec(test.first, false, FileSpec::ePathSyntaxPosix)
-                  .GetNormalizedPath()
                   .GetPath());
   }
 
@@ -274,12 +236,14 @@
       {R"(foo\..)", R"(.)"},
       {R"(foo\..\bar)", R"(bar)"},
       {R"(..\foo\..)", R"(..)"},
-      {R"(.\foo)", R"(foo)"},
+      {R"(.\foo)", R"(.\foo)"},
+      {R"(.\.\foo)", R"(.\foo)"},
+      {R"(..\foo)", R"(..\foo)"},
+      {R"(..\..\foo)", R"(..\..\foo)"},
   };
   for (auto test : windows_tests) {
     EXPECT_EQ(test.second,
               FileSpec(test.first, false, FileSpec::ePathSyntaxWindows)
-                  .GetNormalizedPath()
                   .GetPath())
         << "Original path: " << test.first;
   }
Index: source/Utility/FileSpec.cpp
===================================================================
--- source/Utility/FileSpec.cpp
+++ source/Utility/FileSpec.cpp
@@ -62,17 +62,156 @@
   return value == '/' || (!PathSyntaxIsPosix(syntax) && value == '\\');
 }
 
-void Normalize(llvm::SmallVectorImpl<char> &path, FileSpec::PathSyntax syntax) {
-  if (PathSyntaxIsPosix(syntax))
+size_t RootDirStart(llvm::StringRef str, FileSpec::PathSyntax syntax);
+
+//------------------------------------------------------------------
+/// Safely get a character at the specified index.
+///
+/// @param[in] path
+///     A full, partial, or relative path to a file.
+///
+/// @param[in] i
+///     An index into path which may or may not be valid.
+///
+/// @return
+///   The character at index \a i if the index is valid, or 0 if
+///   the index is not valid.
+//------------------------------------------------------------------
+inline char safeCharAtIndex(const llvm::StringRef &path, size_t i) {
+  if (i < path.size())
+    return path[i];
+  return 0;
+}
+
+//------------------------------------------------------------------
+/// Check if a path needs to be normalized.
+///
+/// Check if a path needs to be normalized. We currently consider a
+/// path to need normalization if any of the following are true
+///  - path contains "/./"
+///  - path contains "/../"
+///  - path contains "//"
+///  - path ends with "/"
+/// Paths that start with "./" or with "../" are not considered to
+/// need normalization since we aren't trying to resolve the path,
+/// we are just trying to remove redundant things from the path.
+///
+/// @param[in] path
+///     A full, partial, or relative path to a file.
+///
+/// @return
+///   Returns \b true if the path needs to be normalized.
+//------------------------------------------------------------------
+bool needsNormalization(const llvm::StringRef &path) {
+  for (auto i = path.find('/'); i != llvm::StringRef::npos;
+       i = path.find('/', i + 1)) {
+    const auto nextChar = safeCharAtIndex(path, i+1);
+    switch (nextChar) {
+      case 0:
+        // '/'' at the end of the string which should be stripped unless
+        // it is the one and only character
+        return i > 0;
+      case '/':
+        // "//" in the middle of a path needs to be normalized
+        if (i > 0)
+          return true;
+        ++i;
+        break;
+  
+      case '.': {
+          const auto nextNextChar = safeCharAtIndex(path, i+2);
+          switch (nextNextChar) {
+            default: break;
+            case 0: return true; // ends with "/."
+            case '/': return true; // contains "/./"
+            case '.':
+              switch (safeCharAtIndex(path, i+3)) {
+                default: break;
+                case 0: return true; // ends with "/.."
+                case '/': return true; // contains "/../"
+              }
+              break;
+          }
+        }
+        break;
+
+      default:
+        break;
+    }
+  }
+  return false;
+}
+
+void Normalize(llvm::SmallVectorImpl<char> &path,
+               FileSpec::PathSyntax syntax) {
+  
+  if (syntax == FileSpec::ePathSyntaxWindows) {
+    std::replace(path.begin(), path.end(), '\\', '/');
+    // Windows path can have \\ slashes which can be changed by replace
+    // call above to //. Here we remove the duplicate. Also remove duplicate
+    // '/' chara
+    auto iter = std::unique(path.begin(), path.end(), [](char &c1, char &c2) {
+      return (c1 == '/' && c2 == '/');
+    });
+    path.erase(iter, path.end());
+  }
+  llvm::StringRef path_ref(path.data(), path.size());
+
+  if (!needsNormalization(path_ref))
     return;
 
-  std::replace(path.begin(), path.end(), '\\', '/');
-  // Windows path can have \\ slashes which can be changed by replace
-  // call above to //. Here we remove the duplicate.
-  auto iter = std::unique(path.begin(), path.end(), [](char &c1, char &c2) {
-    return (c1 == '/' && c2 == '/');
-  });
-  path.erase(iter, path.end());
+  llvm::SmallString<64> normalized;
+
+  // We will not go below root dir.
+  size_t root_dir_start = RootDirStart(path_ref, syntax);
+  const bool absolute = root_dir_start != llvm::StringRef::npos;
+  if (absolute) {
+    normalized += path_ref.take_front(root_dir_start + 1);
+    path_ref = path_ref.drop_front(root_dir_start + 1);
+  } else {
+    if (syntax == FileSpec::ePathSyntaxWindows && path.size() > 2 &&
+        path[1] == ':') {
+      normalized += path_ref.take_front(2);
+      path_ref = path_ref.drop_front(2);
+    }
+  }
+  
+  bool anything_added = false;
+  llvm::SmallVector<llvm::StringRef, 0> components, processed;
+  path_ref.split(components, '/', -1, false);
+  processed.reserve(components.size());
+  for (auto component : components) {
+    if (component == ".") {
+      if (!normalized.empty())
+        continue; // Skip '.' unless it is the first thing
+    }
+    else if (component != "..") {
+      processed.push_back(component);
+      continue; // Regular file name.
+    }
+    if (!processed.empty()) {
+      processed.pop_back();
+      continue; // Dots. Go one level up if we can.
+    }
+    if (absolute)
+      continue; // We're at the top level. Cannot go higher than that. Skip.
+    
+    normalized += component; // We're a relative path. We need to keep these.
+    normalized += '/';
+    anything_added = true;
+  }
+  for (auto component : processed) {
+    normalized += component;
+    normalized += '/';
+    anything_added = true;
+  }
+  
+  if (anything_added)
+    normalized.pop_back(); // Pop last '/'.
+  else if (normalized.empty())
+    normalized = ".";
+
+  path.swap(normalized);
 }
 
 void Denormalize(llvm::SmallVectorImpl<char> &path,
@@ -256,10 +395,15 @@
          filename_begin != root_dir_start &&
          IsPathSeparator(resolve_path_ref[filename_begin], m_syntax))
     ++filename_begin;
-  m_filename.SetString((filename_begin == llvm::StringRef::npos ||
-                        filename_begin >= resolve_path_ref.size())
-                           ? "."
-                           : resolve_path_ref.substr(filename_begin));
+  if (filename_begin < resolve_path_ref.size())
+    m_filename.SetString(resolve_path_ref.substr(filename_begin));
+  else {
+    // Make sure we don't end up with "." in both the directory and filename.
+    // If we do, clear the directory. 
+    m_filename.SetString(".");
+    if (m_filename == m_directory)
+      m_directory.Clear();
+  }
 }
 
 void FileSpec::SetFile(llvm::StringRef path, bool resolve,
@@ -408,108 +552,24 @@
   return ConstString::Compare(a.m_filename, b.m_filename, case_sensitive);
 }
 
-bool FileSpec::Equal(const FileSpec &a, const FileSpec &b, bool full,
-                     bool remove_backups) {
-  static ConstString g_dot_string(".");
-  static ConstString g_dot_dot_string("..");
+bool FileSpec::Equal(const FileSpec &a, const FileSpec &b, bool full) {
 
   // case sensitivity of equality test
   const bool case_sensitive = a.IsCaseSensitive() || b.IsCaseSensitive();
   
-  bool filenames_equal = ConstString::Equals(a.m_filename, 
-                                             b.m_filename, 
-                                             case_sensitive);
+  const bool filenames_equal = ConstString::Equals(a.m_filename,
+                                                   b.m_filename,
+                                                   case_sensitive);
 
-  // The only way two FileSpecs can be equal if their filenames are
-  // unequal is if we are removing backups and one or the other filename
-  // is a backup string:
-
-  if (!filenames_equal && !remove_backups)
+  if (!filenames_equal)
       return false;
 
-  bool last_component_is_dot = ConstString::Equals(a.m_filename, g_dot_string) 
-                               || ConstString::Equals(a.m_filename, 
-                                                      g_dot_dot_string)
-                               || ConstString::Equals(b.m_filename, 
-                                                      g_dot_string)
-                               || ConstString::Equals(b.m_filename, 
-                                                      g_dot_dot_string);
-
-  if (!filenames_equal && !last_component_is_dot)
-    return false;
-
   if (!full && (a.GetDirectory().IsEmpty() || b.GetDirectory().IsEmpty()))
     return filenames_equal;
 
-  if (remove_backups == false)
-    return a == b;
-
-  if (a == b)
-    return true;
-
-  return Equal(a.GetNormalizedPath(), b.GetNormalizedPath(), full, false);
+  return a == b;
 }
 
-FileSpec FileSpec::GetNormalizedPath() const {
-  // Fast path. Do nothing if the path is not interesting.
-  if (!m_directory.GetStringRef().contains(".") &&
-      !m_directory.GetStringRef().contains("//") &&
-      m_filename.GetStringRef() != ".." && m_filename.GetStringRef() != ".")
-    return *this;
-
-  llvm::SmallString<64> path, result;
-  const bool normalize = false;
-  GetPath(path, normalize);
-  llvm::StringRef rest(path);
-
-  // We will not go below root dir.
-  size_t root_dir_start = RootDirStart(path, m_syntax);
-  const bool absolute = root_dir_start != llvm::StringRef::npos;
-  if (absolute) {
-    result += rest.take_front(root_dir_start + 1);
-    rest = rest.drop_front(root_dir_start + 1);
-  } else {
-    if (m_syntax == ePathSyntaxWindows && path.size() > 2 && path[1] == ':') {
-      result += rest.take_front(2);
-      rest = rest.drop_front(2);
-    }
-  }
-
-  bool anything_added = false;
-  llvm::SmallVector<llvm::StringRef, 0> components, processed;
-  rest.split(components, '/', -1, false);
-  processed.reserve(components.size());
-  for (auto component : components) {
-    if (component == ".")
-      continue; // Skip these.
-    if (component != "..") {
-      processed.push_back(component);
-      continue; // Regular file name.
-    }
-    if (!processed.empty()) {
-      processed.pop_back();
-      continue; // Dots. Go one level up if we can.
-    }
-    if (absolute)
-      continue; // We're at the top level. Cannot go higher than that. Skip.
-
-    result += component; // We're a relative path. We need to keep these.
-    result += '/';
-    anything_added = true;
-  }
-  for (auto component : processed) {
-    result += component;
-    result += '/';
-    anything_added = true;
-  }
-  if (anything_added)
-    result.pop_back(); // Pop last '/'.
-  else if (result.empty())
-    result = ".";
-
-  return FileSpec(result, false, m_syntax);
-}
-
 //------------------------------------------------------------------
 // Dump the object to the supplied stream. If the object contains
 // a valid directory name, it will be displayed followed by a
@@ -793,7 +853,8 @@
       continue;
     result += components[i];
     if (i != components.size() - 1 &&
-        !IsPathSeparator(components[i].back(), syntax))
+        !IsPathSeparator(components[i].back(), syntax) &&
+        (result.empty() || !IsPathSeparator(result.back(), syntax)))
       result += GetPreferredPathSeparator(syntax);
   }
 
Index: source/Symbol/Declaration.cpp
===================================================================
--- source/Symbol/Declaration.cpp
+++ source/Symbol/Declaration.cpp
@@ -91,7 +91,7 @@
       return lhs.GetFile() == rhs.GetFile();
 #else
   if (lhs.GetLine() == rhs.GetLine())
-    return FileSpec::Equal(lhs.GetFile(), rhs.GetFile(), true, true);
+    return FileSpec::Equal(lhs.GetFile(), rhs.GetFile(), true);
 #endif
   return false;
 }
Index: source/Symbol/CompileUnit.cpp
===================================================================
--- source/Symbol/CompileUnit.cpp
+++ source/Symbol/CompileUnit.cpp
@@ -287,21 +287,19 @@
   // when finding file indexes
   std::vector<uint32_t> file_indexes;
   const bool full_match = (bool)file_spec.GetDirectory();
-  const bool remove_backup_dots = true;
   bool file_spec_matches_cu_file_spec =
-      FileSpec::Equal(file_spec, *this, full_match, remove_backup_dots);
+      FileSpec::Equal(file_spec, *this, full_match);
 
   // If we are not looking for inlined functions and our file spec doesn't
   // match then we are done...
   if (file_spec_matches_cu_file_spec == false && check_inlines == false)
     return 0;
 
   uint32_t file_idx =
-      GetSupportFiles().FindFileIndex(1, file_spec, true, remove_backup_dots);
+      GetSupportFiles().FindFileIndex(1, file_spec, true);
   while (file_idx != UINT32_MAX) {
     file_indexes.push_back(file_idx);
-    file_idx = GetSupportFiles().FindFileIndex(file_idx + 1, file_spec, true,
-                                               remove_backup_dots);
+    file_idx = GetSupportFiles().FindFileIndex(file_idx + 1, file_spec, true);
   }
 
   const size_t num_file_indexes = file_indexes.size();
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -174,38 +174,39 @@
   return colon_pos + 1;
 }
 
-static const char *resolveCompDir(const char *path_from_dwarf) {
+static FileSpec resolveCompDir(const char *path_from_dwarf) {
   if (!path_from_dwarf)
-    return nullptr;
+    return FileSpec();
 
   // DWARF2/3 suggests the form hostname:pathname for compilation directory.
   // Remove the host part if present.
   const char *local_path = removeHostnameFromPathname(path_from_dwarf);
   if (!local_path)
-    return nullptr;
+    return FileSpec();
 
   bool is_symlink = false;
-  FileSpec local_path_spec(local_path, false);
+  // Always normalize our compile unit directory to get rid of redundant
+  // slashes and other path anomalies before we use it for path prepending
+  FileSpec local_spec(local_path, false);
   const auto &file_specs = GetGlobalPluginProperties()->GetSymLinkPaths();
   for (size_t i = 0; i < file_specs.GetSize() && !is_symlink; ++i)
     is_symlink = FileSpec::Equal(file_specs.GetFileSpecAtIndex(i),
-                                 local_path_spec, true);
+                                 local_spec, true);
 
   if (!is_symlink)
-    return local_path;
+    return local_spec;
 
   namespace fs = llvm::sys::fs;
-  if (fs::get_file_type(local_path_spec.GetPath(), false) !=
+  if (fs::get_file_type(local_spec.GetPath(), false) !=
       fs::file_type::symlink_file)
-    return local_path;
+    return local_spec;
 
-  FileSpec resolved_local_path_spec;
-  const auto error =
-      FileSystem::Readlink(local_path_spec, resolved_local_path_spec);
+  FileSpec resolved_symlink;
+  const auto error = FileSystem::Readlink(local_spec, resolved_symlink);
   if (error.Success())
-    return resolved_local_path_spec.GetCString();
+    return resolved_symlink;
 
-  return nullptr;
+  return local_spec;
 }
 
 DWARFUnit *SymbolFileDWARF::GetBaseCompileUnit() {
@@ -912,7 +913,7 @@
     const DWARFDIE cu_die = dwarf_cu->GetUnitDIEOnly();
 
     if (cu_die) {
-      const char *cu_comp_dir = resolveCompDir(
+      FileSpec cu_comp_dir = resolveCompDir(
           cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr));
       const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned(
           DW_AT_stmt_list, DW_INVALID_OFFSET);
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
@@ -90,7 +90,7 @@
       include_directories.clear();
       file_names.clear();
     }
-    bool GetFile(uint32_t file_idx, const char *comp_dir,
+    bool GetFile(uint32_t file_idx, const lldb_private::FileSpec &cu_comp_dir,
                  lldb_private::FileSpec &file) const;
   };
 
@@ -199,7 +199,8 @@
   static bool
   ParseSupportFiles(const lldb::ModuleSP &module_sp,
                     const lldb_private::DWARFDataExtractor &debug_line_data,
-                    const char *cu_comp_dir, dw_offset_t stmt_list,
+                    const lldb_private::FileSpec &cu_comp_dir,
+                    dw_offset_t stmt_list,
                     lldb_private::FileSpecList &support_files);
   static bool
   ParsePrologue(const lldb_private::DWARFDataExtractor &debug_line_data,
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
@@ -444,7 +444,7 @@
 
 bool DWARFDebugLine::ParseSupportFiles(
     const lldb::ModuleSP &module_sp, const DWARFDataExtractor &debug_line_data,
-    const char *cu_comp_dir, dw_offset_t stmt_list,
+    const lldb_private::FileSpec &cu_comp_dir, dw_offset_t stmt_list,
     FileSpecList &support_files) {
   lldb::offset_t offset = stmt_list;
 
@@ -861,8 +861,8 @@
 //  buff.Append8(0);    // Terminate the file names section with empty string
 //}
 
-bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx, const char *comp_dir,
-                                       FileSpec &file) const {
+bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx,
+    const lldb_private::FileSpec &comp_dir, FileSpec &file) const {
   uint32_t idx = file_idx - 1; // File indexes are 1 based...
   if (idx < file_names.size()) {
     file.SetFile(file_names[idx].name, false);
@@ -876,7 +876,7 @@
         }
       }
 
-      if (comp_dir && comp_dir[0])
+      if (comp_dir)
         file.PrependPathComponent(comp_dir);
     }
     return true;
Index: source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
===================================================================
--- source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -5098,9 +5098,6 @@
           // It is OK to resolve this path because we must find a file on
           // disk for us to accept it anyway if it is rpath relative.
           FileSpec file_spec(path, true);
-          // Remove any redundant parts of the path (like "../foo") since
-          // LC_RPATH values often contain "..".
-          file_spec = file_spec.GetNormalizedPath();
           if (file_spec.Exists() && files.AppendIfUnique(file_spec)) {
             count++;
             break;
@@ -5118,7 +5115,6 @@
       for (const auto &at_exec_relative_path : at_exec_relative_paths) {
         FileSpec file_spec = 
             exec_dir.CopyByAppendingPathComponent(at_exec_relative_path);
-        file_spec = file_spec.GetNormalizedPath();
         if (file_spec.Exists() && files.AppendIfUnique(file_spec))
           count++;
       }
Index: source/Core/FileSpecList.cpp
===================================================================
--- source/Core/FileSpecList.cpp
+++ source/Core/FileSpecList.cpp
@@ -82,7 +82,7 @@
 // it is found, else std::numeric_limits<uint32_t>::max() is returned.
 //------------------------------------------------------------------
 size_t FileSpecList::FindFileIndex(size_t start_idx, const FileSpec &file_spec,
-                                   bool full, bool remove_dots) const {
+                                   bool full) const {
   const size_t num_files = m_files.size();
 
   // When looking for files, we will compare only the filename if the
@@ -96,7 +96,7 @@
               file_spec.IsCaseSensitive() || m_files[idx].IsCaseSensitive()))
         return idx;
     } else {
-      if (FileSpec::Equal(m_files[idx], file_spec, full, remove_dots))
+      if (FileSpec::Equal(m_files[idx], file_spec, full))
         return idx;
     }
   }
Index: source/Breakpoint/BreakpointResolverFileLine.cpp
===================================================================
--- source/Breakpoint/BreakpointResolverFileLine.cpp
+++ source/Breakpoint/BreakpointResolverFileLine.cpp
@@ -121,8 +121,15 @@
     return; // Nothing to do. Contexts are precise.
 
   llvm::StringRef relative_path;
-  if (is_relative)
-    relative_path = m_file_spec.GetNormalizedPath().GetDirectory().GetStringRef();
+  if (is_relative) {
+    relative_path = m_file_spec.GetDirectory().GetStringRef();
+    // Don't let any path start with "./" or "../". Since all paths are
+    // normalized now, paths can only start with "./" or "../" if they are
+    // relative. This means we can safely skip any leading "./" or "../" but
+    // we must leave the slash character though.
+    while (relative_path.consume_front("."))
+      /* Do nothing. */;
+  }
 
   Log * log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
   for(uint32_t i = 0; i < sc_list.GetSize(); ++i) {
Index: include/lldb/Utility/FileSpec.h
===================================================================
--- include/lldb/Utility/FileSpec.h
+++ include/lldb/Utility/FileSpec.h
@@ -256,8 +256,7 @@
   //------------------------------------------------------------------
   static int Compare(const FileSpec &lhs, const FileSpec &rhs, bool full);
 
-  static bool Equal(const FileSpec &a, const FileSpec &b, bool full,
-                    bool remove_backups = false);
+  static bool Equal(const FileSpec &a, const FileSpec &b, bool full);
 
   //------------------------------------------------------------------
   /// Case sensitivity of path.
@@ -488,12 +487,6 @@
   size_t MemorySize() const;
 
   //------------------------------------------------------------------
-  /// Normalize a pathname by collapsing redundant separators and
-  /// up-level references.
-  //------------------------------------------------------------------
-  FileSpec GetNormalizedPath() const;
-
-  //------------------------------------------------------------------
   /// Change the file specified with a new path.
   ///
   /// Update the contents of this object with a new path. The path will
Index: include/lldb/Core/FileSpecList.h
===================================================================
--- include/lldb/Core/FileSpecList.h
+++ include/lldb/Core/FileSpecList.h
@@ -119,16 +119,11 @@
   /// @param[in] full
   ///     Should FileSpec::Equal be called with "full" true or false.
   ///
-  /// @param[in] remove_backup_dots
-  ///     Should FileSpec::Equal be called with "remove_backup_dots" true or
-  ///     false.
-  ///
   /// @return
   ///     The index of the file that matches \a file if it is found,
   ///     else UINT32_MAX is returned.
   //------------------------------------------------------------------
-  size_t FindFileIndex(size_t idx, const FileSpec &file, bool full,
-                       bool remove_backup_dots = false) const;
+  size_t FindFileIndex(size_t idx, const FileSpec &file, bool full) const;
 
   //------------------------------------------------------------------
   /// Get file at index.
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to