Index: include/lldb/Host/FileSpec.h =================================================================== --- include/lldb/Host/FileSpec.h +++ include/lldb/Host/FileSpec.h @@ -22,6 +22,8 @@ #include "lldb/Core/STLUtils.h" #include "lldb/Host/TimeValue.h" +#include "llvm/ADT/Triple.h" + namespace lldb_private { //---------------------------------------------------------------------- @@ -66,6 +68,8 @@ FileSpec(); + explicit FileSpec(bool case_sensitive); + //------------------------------------------------------------------ /// Constructor with path. /// @@ -274,10 +278,7 @@ /// if case insensitive (Windows). //------------------------------------------------------------------ bool - IsCaseSensitive() const - { - return m_syntax != ePathSyntaxWindows; - } + IsCaseSensitive() const; //------------------------------------------------------------------ /// Dump this object to a Stream. @@ -700,9 +701,18 @@ /// @param[in] resolve_path /// If \b true, then we will try to resolve links the path using /// the static FileSpec::Resolve. + /// + /// @param[in] triple + /// If \b provided, then used for a more precise case sensitivity detection. //------------------------------------------------------------------ void - SetFile (const char *path, bool resolve_path, PathSyntax syntax = ePathSyntaxHostNative); + SetFile (const char *path, + bool resolve_path, + PathSyntax syntax = ePathSyntaxHostNative, + llvm::Triple *triple = nullptr); + + void + SetFile(const char *path, bool resolve_path, bool case_sensitive, PathSyntax syntax = ePathSyntaxHostNative); void SetFile(const char *path, bool resolve_path, ArchSpec arch); @@ -838,6 +848,8 @@ ForEachItemInDirectory (const char *dir_path, DirectoryCallback const &callback); protected: + static bool + IsCaseSensitive(PathSyntax syntax, const llvm::Triple *triple = nullptr); //------------------------------------------------------------------ // Member variables //------------------------------------------------------------------ @@ -845,6 +857,7 @@ ConstString m_filename; ///< The uniqued filename path mutable bool m_is_resolved; ///< True if this path has been resolved. PathSyntax m_syntax; ///< The syntax that this path uses (e.g. Windows / Posix) + bool m_case_sensitive; }; //---------------------------------------------------------------------- Index: packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_case_sensitivity/TestBreakpointCaseSensitivity.py =================================================================== --- packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_case_sensitivity/TestBreakpointCaseSensitivity.py +++ packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_case_sensitivity/TestBreakpointCaseSensitivity.py @@ -18,14 +18,13 @@ TestBase.setUp(self) self.line = line_number('main.c', self.BREAKPOINT_TEXT) - @skipIf(oslist=no_match(['windows'])) # Skip for non-windows platforms + @skipIf(oslist=['linux']) def test_breakpoint_matches_file_with_different_case(self): """Set breakpoint on file, should match files with different case on Windows""" self.build() self.case_sensitivity_breakpoint(True) - @skipIf(oslist=['windows']) # Skip for windows platforms - @expectedFailureAll() # Failing for unknown reason on non-Windows platforms. + @skipIf(oslist=no_match(['linux'])) def test_breakpoint_doesnt_match_file_with_different_case(self): """Set breakpoint on file, shouldn't match files with different case on POSIX systems""" self.build() @@ -86,15 +85,15 @@ lldb.SBFileSpec(file)) else: breakpoint = self.target.BreakpointCreateByLocation(file, self.line) - - self.assertEqual(breakpoint and breakpoint.GetNumLocations() == 1, + + self.assertEqual(breakpoint.GetNumLocations() == 1, should_hit, VALID_BREAKPOINT + desc) # Get the breakpoint location from breakpoint after we verified that, # indeed, it has one location. location = breakpoint.GetLocationAtIndex(0) - self.assertEqual(location and location.IsEnabled(), + self.assertEqual(location.IsEnabled(), should_hit, VALID_BREAKPOINT_LOCATION + desc) @@ -108,14 +107,12 @@ self.assertEqual(len(threads), 1, "There should be a thread stopped at breakpoint" + desc) # The hit count for the breakpoint should be 1. self.assertEqual(breakpoint.GetHitCount(), 1) - + # let process finish + process.Continue() else: # check the breakpoint was not hit self.assertEqual(lldb.eStateExited, process.GetState()) self.assertEqual(breakpoint.GetHitCount(), 0) - # let process finish - process.Continue() - # cleanup self.target.BreakpointDelete(breakpoint.GetID()) Index: source/Host/common/FileSpec.cpp =================================================================== --- source/Host/common/FileSpec.cpp +++ source/Host/common/FileSpec.cpp @@ -36,6 +36,7 @@ #include "lldb/Host/FileSpec.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Utility/CleanUp.h" #include "llvm/ADT/StringRef.h" @@ -304,9 +305,15 @@ } FileSpec::FileSpec() : + FileSpec{IsCaseSensitive(ePathSyntaxHostNative)} +{ +} + +FileSpec::FileSpec(bool case_sensitive) : m_directory(), m_filename(), - m_syntax(FileSystem::GetNativePathSyntax()) + m_syntax(FileSystem::GetNativePathSyntax()), + m_case_sensitive(case_sensitive) { } @@ -318,15 +325,17 @@ m_directory(), m_filename(), m_is_resolved(false), - m_syntax(syntax) + m_syntax(syntax), + m_case_sensitive(IsCaseSensitive(syntax)) { if (pathname && pathname[0]) - SetFile(pathname, resolve_path, syntax); + SetFile(pathname, resolve_path, m_case_sensitive, syntax); } FileSpec::FileSpec(const char *pathname, bool resolve_path, ArchSpec arch) : FileSpec{pathname, resolve_path, arch.GetTriple().isOSWindows() ? ePathSyntaxWindows : ePathSyntaxPosix} { + m_case_sensitive = IsCaseSensitive(m_syntax, &arch.GetTriple()); } FileSpec::FileSpec(const std::string &path, bool resolve_path, PathSyntax syntax) : @@ -346,7 +355,8 @@ m_directory (rhs.m_directory), m_filename (rhs.m_filename), m_is_resolved (rhs.m_is_resolved), - m_syntax (rhs.m_syntax) + m_syntax (rhs.m_syntax), + m_case_sensitive (rhs.m_case_sensitive) { } @@ -380,6 +390,7 @@ m_filename = rhs.m_filename; m_is_resolved = rhs.m_is_resolved; m_syntax = rhs.m_syntax; + m_case_sensitive = rhs.m_case_sensitive; } return *this; } @@ -390,11 +401,12 @@ // string values for quick comparison and efficient memory usage. //------------------------------------------------------------------ void -FileSpec::SetFile (const char *pathname, bool resolve, PathSyntax syntax) +FileSpec::SetFile(const char *pathname, bool resolve, bool case_sensitive, PathSyntax syntax) { m_filename.Clear(); m_directory.Clear(); m_is_resolved = false; + m_case_sensitive = case_sensitive; m_syntax = (syntax == ePathSyntaxHostNative) ? FileSystem::GetNativePathSyntax() : syntax; if (pathname == NULL || pathname[0] == '\0') @@ -431,12 +443,19 @@ } void +FileSpec::SetFile (const char *pathname, bool resolve, PathSyntax syntax, llvm::Triple *triple) +{ + return SetFile(pathname, resolve, IsCaseSensitive(syntax, triple), syntax); +} + +void FileSpec::SetFile(const char *pathname, bool resolve, ArchSpec arch) { return SetFile(pathname, resolve, arch.GetTriple().isOSWindows() ? ePathSyntaxWindows - : ePathSyntaxPosix); + : ePathSyntaxPosix, + &arch.GetTriple()); } void @@ -850,7 +869,7 @@ if (!GetPath (path_buf, PATH_MAX, false)) return false; // SetFile(...) will set m_is_resolved correctly if it can resolve the path - SetFile (path_buf, true); + SetFile(path_buf, true, m_case_sensitive, m_syntax); return m_is_resolved; } @@ -1507,7 +1526,7 @@ const bool resolve = false; if (m_filename.IsEmpty() && m_directory.IsEmpty()) { - SetFile(new_path, resolve); + SetFile(new_path, resolve, m_case_sensitive, m_syntax); return; } StreamString stream; @@ -1517,7 +1536,7 @@ stream.Printf("%s/%s", new_path, m_filename.GetCString()); else stream.Printf("%s/%s/%s", new_path, m_directory.GetCString(), m_filename.GetCString()); - SetFile(stream.GetData(), resolve); + SetFile(stream.GetData(), resolve, m_case_sensitive, m_syntax); } void @@ -1555,7 +1574,7 @@ stream.PutCString(new_path); const bool resolve = false; - SetFile(stream.GetData(), resolve, m_syntax); + SetFile(stream.GetData(), resolve, m_case_sensitive, m_syntax); } void @@ -1576,12 +1595,12 @@ const bool resolve = false; if (m_filename.IsEmpty() && m_directory.IsEmpty()) { - SetFile("",resolve); + SetFile("", resolve, m_case_sensitive, m_syntax); return; } if (m_directory.IsEmpty()) { - SetFile("",resolve); + SetFile("", resolve, m_case_sensitive, m_syntax); return; } if (m_filename.IsEmpty()) @@ -1592,20 +1611,20 @@ // check for obvious cases before doing the full thing if (!last_slash_ptr) { - SetFile("",resolve); + SetFile("", resolve, m_case_sensitive, m_syntax); return; } if (last_slash_ptr == dir_cstr) { - SetFile("/",resolve); + SetFile("/", resolve, m_case_sensitive, m_syntax); return; } size_t last_slash_pos = last_slash_ptr - dir_cstr+1; ConstString new_path(dir_cstr,last_slash_pos); - SetFile(new_path.GetCString(),resolve); + SetFile(new_path.GetCString(), resolve, m_case_sensitive, m_syntax); } else - SetFile(m_directory.GetCString(),resolve); + SetFile(m_directory.GetCString(), resolve, m_case_sensitive, m_syntax); } //------------------------------------------------------------------ /// Returns true if the filespec represents an implementation source @@ -1670,3 +1689,25 @@ { return !FileSpec::IsRelative(); } + +bool +FileSpec::IsCaseSensitive() const +{ + return m_case_sensitive; +} + +bool +FileSpec::IsCaseSensitive(PathSyntax syntax, const llvm::Triple *triple) +{ + switch (syntax) + { + case ePathSyntaxPosix: + return triple == nullptr || !triple->isMacOSX(); + case ePathSyntaxWindows: + return false; + case ePathSyntaxHostNative: + return IsCaseSensitive(FileSystem::GetNativePathSyntax(), &HostInfo::GetArchitecture().GetTriple()); + default: + return true; + } +} Index: source/Host/common/HostInfoBase.cpp =================================================================== --- source/Host/common/HostInfoBase.cpp +++ source/Host/common/HostInfoBase.cpp @@ -59,15 +59,15 @@ ArchSpec m_host_arch_32; ArchSpec m_host_arch_64; - FileSpec m_lldb_so_dir; - FileSpec m_lldb_support_exe_dir; - FileSpec m_lldb_headers_dir; - FileSpec m_lldb_python_dir; - FileSpec m_lldb_clang_resource_dir; - FileSpec m_lldb_system_plugin_dir; - FileSpec m_lldb_user_plugin_dir; - FileSpec m_lldb_process_tmp_dir; - FileSpec m_lldb_global_tmp_dir; + FileSpec m_lldb_so_dir = FileSpec(false); + FileSpec m_lldb_support_exe_dir = FileSpec(false); + FileSpec m_lldb_headers_dir = FileSpec(false); + FileSpec m_lldb_python_dir = FileSpec(false); + FileSpec m_lldb_clang_resource_dir = FileSpec(false); + FileSpec m_lldb_system_plugin_dir = FileSpec(false); + FileSpec m_lldb_user_plugin_dir = FileSpec(false); + FileSpec m_lldb_process_tmp_dir = FileSpec(false); + FileSpec m_lldb_global_tmp_dir = FileSpec(false); }; HostInfoBaseFields *g_fields = nullptr;