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

Add absolute/relative path caching into FileSpec since we will be using it more 
for breakpoints if this patch gets approved. FileSpecList objects are used by 
the line table classes and the support file lists don't change.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D130045/new/

https://reviews.llvm.org/D130045

Files:
  lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h
  lldb/include/lldb/Utility/FileSpec.h
  lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
  lldb/source/Core/FileSpecList.cpp
  lldb/source/Symbol/CompileUnit.cpp
  lldb/source/Utility/FileSpec.cpp
  
lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
  lldb/test/API/functionalities/breakpoint/breakpoint_command/relative.yaml
  lldb/unittests/Core/CMakeLists.txt
  lldb/unittests/Core/FileSpecListTest.cpp

Index: lldb/unittests/Core/FileSpecListTest.cpp
===================================================================
--- /dev/null
+++ lldb/unittests/Core/FileSpecListTest.cpp
@@ -0,0 +1,58 @@
+//===-- FileSpecListTest.cpp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+#include "lldb/Core/FileSpecList.h"
+
+using namespace lldb_private;
+
+static FileSpec PosixSpec(llvm::StringRef path) {
+  return FileSpec(path, FileSpec::Style::posix);
+}
+
+// static FileSpec WindowsSpec(llvm::StringRef path) {
+//   return FileSpec(path, FileSpec::Style::windows);
+// }
+
+TEST(FileSpecListTest, RelativePathMatches) {
+
+  const FileSpec fullpath = PosixSpec("/build/src/main.cpp");
+  const FileSpec relative = PosixSpec("./src/main.cpp");
+  const FileSpec basename = PosixSpec("./main.cpp");
+  const FileSpec full_wrong = PosixSpec("/other/wrong/main.cpp");
+  const FileSpec rel_wrong = PosixSpec("./wrong/main.cpp");
+
+  FileSpecList files;
+  files.Append(fullpath);
+  files.Append(relative);
+  files.Append(basename);
+  files.Append(full_wrong);
+  files.Append(rel_wrong);
+
+  // Make sure the full path only matches the first entry
+  EXPECT_EQ((size_t)0, files.FindFileIndex(0, fullpath, /*full=*/true));
+  EXPECT_EQ((size_t)1, files.FindFileIndex(1, fullpath, /*full=*/true));
+  EXPECT_EQ((size_t)2, files.FindFileIndex(2, fullpath, /*full=*/true));
+  EXPECT_EQ((size_t)UINT32_MAX,
+            files.FindFileIndex(3, fullpath, /*full=*/true));
+  // Make sure the relative path matches the all of the entries that contain
+  // the relative path
+  EXPECT_EQ((size_t)0, files.FindFileIndex(0, relative, /*full=*/true));
+  EXPECT_EQ((size_t)1, files.FindFileIndex(1, relative, /*full=*/true));
+  EXPECT_EQ((size_t)2, files.FindFileIndex(2, relative, /*full=*/true));
+  EXPECT_EQ((size_t)UINT32_MAX,
+            files.FindFileIndex(3, relative, /*full=*/true));
+
+  // Make sure looking file a file using the basename matches all entries
+  EXPECT_EQ((size_t)0, files.FindFileIndex(0, basename, /*full=*/true));
+  EXPECT_EQ((size_t)1, files.FindFileIndex(1, basename, /*full=*/true));
+  EXPECT_EQ((size_t)2, files.FindFileIndex(2, basename, /*full=*/true));
+  EXPECT_EQ((size_t)3, files.FindFileIndex(3, basename, /*full=*/true));
+  EXPECT_EQ((size_t)4, files.FindFileIndex(4, basename, /*full=*/true));
+}
Index: lldb/unittests/Core/CMakeLists.txt
===================================================================
--- lldb/unittests/Core/CMakeLists.txt
+++ lldb/unittests/Core/CMakeLists.txt
@@ -2,6 +2,7 @@
   CommunicationTest.cpp
   DiagnosticEventTest.cpp
   DumpDataExtractorTest.cpp
+  FileSpecListTest.cpp
   FormatEntityTest.cpp
   MangledTest.cpp
   ModuleSpecTest.cpp
Index: lldb/test/API/functionalities/breakpoint/breakpoint_command/relative.yaml
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/breakpoint/breakpoint_command/relative.yaml
@@ -0,0 +1,445 @@
+--- !mach-o
+FileHeader:
+  magic:           0xFEEDFACF
+  cputype:         0x100000C
+  cpusubtype:      0x0
+  filetype:        0xA
+  ncmds:           7
+  sizeofcmds:      1240
+  flags:           0x0
+  reserved:        0x0
+LoadCommands:
+  - cmd:             LC_UUID
+    cmdsize:         24
+    uuid:            030921EA-6D76-3A68-B515-386B9AF6D568
+  - cmd:             LC_BUILD_VERSION
+    cmdsize:         24
+    platform:        1
+    minos:           786432
+    sdk:             787200
+    ntools:          0
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          4096
+    nsyms:           2
+    stroff:          4128
+    strsize:         28
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         72
+    segname:         __PAGEZERO
+    vmaddr:          0
+    vmsize:          4294967296
+    fileoff:         0
+    filesize:        0
+    maxprot:         0
+    initprot:        0
+    nsects:          0
+    flags:           0
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         232
+    segname:         __TEXT
+    vmaddr:          4294967296
+    vmsize:          16384
+    fileoff:         0
+    filesize:        0
+    maxprot:         5
+    initprot:        5
+    nsects:          2
+    flags:           0
+    Sections:
+      - sectname:        __text
+        segname:         __TEXT
+        addr:            0x100003F94
+        size:            36
+        offset:          0x0
+        align:           2
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x80000400
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         CFFAEDFE0C000001000000000A00000007000000D804000000000000000000001B000000
+      - sectname:        __unwind_info
+        segname:         __TEXT
+        addr:            0x100003FB8
+        size:            72
+        offset:          0x0
+        align:           2
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x0
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         CFFAEDFE0C000001000000000A00000007000000D804000000000000000000001B00000018000000030921EA6D763A68B515386B9AF6D56832000000180000000100000000000C00
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         72
+    segname:         __LINKEDIT
+    vmaddr:          4294983680
+    vmsize:          4096
+    fileoff:         4096
+    filesize:        60
+    maxprot:         1
+    initprot:        1
+    nsects:          0
+    flags:           0
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         792
+    segname:         __DWARF
+    vmaddr:          4294987776
+    vmsize:          4096
+    fileoff:         8192
+    filesize:        796
+    maxprot:         7
+    initprot:        3
+    nsects:          9
+    flags:           0
+    Sections:
+      - sectname:        __debug_line
+        segname:         __DWARF
+        addr:            0x100005000
+        size:            64
+        offset:          0x2000
+        align:           0
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x0
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+      - sectname:        __debug_aranges
+        segname:         __DWARF
+        addr:            0x100005040
+        size:            48
+        offset:          0x2040
+        align:           0
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x0
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+      - sectname:        __debug_info
+        segname:         __DWARF
+        addr:            0x100005070
+        size:            148
+        offset:          0x2070
+        align:           0
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x0
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+      - sectname:        __debug_abbrev
+        segname:         __DWARF
+        addr:            0x100005104
+        size:            90
+        offset:          0x2104
+        align:           0
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x0
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+      - sectname:        __debug_str
+        segname:         __DWARF
+        addr:            0x10000515E
+        size:            200
+        offset:          0x215E
+        align:           0
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x0
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+      - sectname:        __apple_names
+        segname:         __DWARF
+        addr:            0x100005226
+        size:            60
+        offset:          0x2226
+        align:           0
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x0
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         485341480100000001000000010000000C000000000000000100000001000600000000006A7F9A7C2C000000AB000000010000003200000000000000
+      - sectname:        __apple_namespac
+        segname:         __DWARF
+        addr:            0x100005262
+        size:            36
+        offset:          0x2262
+        align:           0
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x0
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         485341480100000001000000000000000C000000000000000100000001000600FFFFFFFF
+      - sectname:        __apple_types
+        segname:         __DWARF
+        addr:            0x100005286
+        size:            114
+        offset:          0x2286
+        align:           0
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x0
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         48534148010000000200000002000000180000000000000004000000010006000300050005000B000600060000000000010000003080880B6320957C440000005B000000BF0000000100000076000000240000A4283A0C00000000C3000000010000008C00000024000057D77B9300000000
+      - sectname:        __apple_objc
+        segname:         __DWARF
+        addr:            0x1000052F8
+        size:            36
+        offset:          0x22F8
+        align:           0
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x0
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         485341480100000001000000000000000C000000000000000100000001000600FFFFFFFF
+LinkEditData:
+  NameList:
+    - n_strx:          2
+      n_type:          0xF
+      n_sect:          1
+      n_desc:          16
+      n_value:         4294967296
+    - n_strx:          22
+      n_type:          0xF
+      n_sect:          1
+      n_desc:          0
+      n_value:         4294983572
+  StringTable:
+    - ''
+    - ''
+    - __mh_execute_header
+    - _main
+DWARF:
+  debug_str:
+    - ''
+    - 'Apple clang version 13.1.6 (clang-1316.0.21.2)'
+    - main.cpp
+    - '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk'
+    - MacOSX.sdk
+    - './a/b/c'
+    - main
+    - argc
+    - argv
+    - envp
+    - int
+    - char
+  debug_abbrev:
+    - ID:              0
+      Table:
+        - Code:            0x1
+          Tag:             DW_TAG_compile_unit
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_producer
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_language
+              Form:            DW_FORM_data2
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_LLVM_sysroot
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_APPLE_sdk
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_stmt_list
+              Form:            DW_FORM_sec_offset
+            - Attribute:       DW_AT_comp_dir
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_low_pc
+              Form:            DW_FORM_addr
+            - Attribute:       DW_AT_high_pc
+              Form:            DW_FORM_data4
+        - Code:            0x2
+          Tag:             DW_TAG_subprogram
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_low_pc
+              Form:            DW_FORM_addr
+            - Attribute:       DW_AT_high_pc
+              Form:            DW_FORM_data4
+            - Attribute:       DW_AT_APPLE_omit_frame_ptr
+              Form:            DW_FORM_flag_present
+            - Attribute:       DW_AT_frame_base
+              Form:            DW_FORM_exprloc
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_decl_file
+              Form:            DW_FORM_data1
+            - Attribute:       DW_AT_decl_line
+              Form:            DW_FORM_data1
+            - Attribute:       DW_AT_type
+              Form:            DW_FORM_ref_addr
+            - Attribute:       DW_AT_external
+              Form:            DW_FORM_flag_present
+        - Code:            0x3
+          Tag:             DW_TAG_formal_parameter
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_location
+              Form:            DW_FORM_exprloc
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_decl_file
+              Form:            DW_FORM_data1
+            - Attribute:       DW_AT_decl_line
+              Form:            DW_FORM_data1
+            - Attribute:       DW_AT_type
+              Form:            DW_FORM_ref_addr
+        - Code:            0x4
+          Tag:             DW_TAG_base_type
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_encoding
+              Form:            DW_FORM_data1
+            - Attribute:       DW_AT_byte_size
+              Form:            DW_FORM_data1
+        - Code:            0x5
+          Tag:             DW_TAG_pointer_type
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_type
+              Form:            DW_FORM_ref_addr
+        - Code:            0x6
+          Tag:             DW_TAG_const_type
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_type
+              Form:            DW_FORM_ref_addr
+  debug_aranges:
+    - Length:          0x2C
+      Version:         2
+      CuOffset:        0x0
+      AddressSize:     0x8
+      Descriptors:
+        - Address:         0x100003F94
+          Length:          0x24
+  debug_info:
+    - Length:          0x90
+      Version:         4
+      AbbrevTableID:   0
+      AbbrOffset:      0x0
+      AddrSize:        8
+      Entries:
+        - AbbrCode:        0x1
+          Values:
+            - Value:           0x1
+            - Value:           0x1A
+            - Value:           0x30
+            - Value:           0x39
+            - Value:           0x98
+            - Value:           0x0
+            - Value:           0xA3
+            - Value:           0x100003F94
+            - Value:           0x24
+        - AbbrCode:        0x2
+          Values:
+            - Value:           0x100003F94
+            - Value:           0x24
+            - Value:           0x1
+            - Value:           0x1
+              BlockData:       [ 0x6F ]
+            - Value:           0xAB
+            - Value:           0x1
+            - Value:           0x1
+            - Value:           0x76
+            - Value:           0x1
+        - AbbrCode:        0x3
+          Values:
+            - Value:           0x2
+              BlockData:       [ 0x91, 0x18 ]
+            - Value:           0xB0
+            - Value:           0x1
+            - Value:           0x1
+            - Value:           0x76
+        - AbbrCode:        0x3
+          Values:
+            - Value:           0x2
+              BlockData:       [ 0x91, 0x10 ]
+            - Value:           0xB5
+            - Value:           0x1
+            - Value:           0x1
+            - Value:           0x7D
+        - AbbrCode:        0x3
+          Values:
+            - Value:           0x2
+              BlockData:       [ 0x91, 0x8 ]
+            - Value:           0xBA
+            - Value:           0x1
+            - Value:           0x1
+            - Value:           0x7D
+        - AbbrCode:        0x0
+        - AbbrCode:        0x4
+          Values:
+            - Value:           0xBF
+            - Value:           0x5
+            - Value:           0x4
+        - AbbrCode:        0x5
+          Values:
+            - Value:           0x82
+        - AbbrCode:        0x5
+          Values:
+            - Value:           0x87
+        - AbbrCode:        0x6
+          Values:
+            - Value:           0x8C
+        - AbbrCode:        0x4
+          Values:
+            - Value:           0xC3
+            - Value:           0x6
+            - Value:           0x1
+        - AbbrCode:        0x0
+  debug_line:
+    - Length:          60
+      Version:         4
+      PrologueLength:  32
+      MinInstLength:   1
+      MaxOpsPerInst:   1
+      DefaultIsStmt:   1
+      LineBase:        251
+      LineRange:       14
+      OpcodeBase:      13
+      StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ]
+      Files:
+        - Name:            main.cpp
+          DirIdx:          0
+          ModTime:         0
+          Length:          0
+      Opcodes:
+        - Opcode:          DW_LNS_extended_op
+          ExtLen:          9
+          SubOpcode:       DW_LNE_set_address
+          Data:            4294983572
+        - Opcode:          DW_LNS_copy
+          Data:            0
+        - Opcode:          DW_LNS_set_column
+          Data:            3
+        - Opcode:          DW_LNS_set_prologue_end
+          Data:            0
+        - Opcode:          DW_LNS_const_add_pc
+          Data:            0
+        - Opcode:          0xAD
+          Data:            0
+        - Opcode:          DW_LNS_advance_pc
+          Data:            8
+        - Opcode:          DW_LNS_extended_op
+          ExtLen:          1
+          SubOpcode:       DW_LNE_end_sequence
+          Data:            0
+...
Index: lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
===================================================================
--- lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
+++ lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
@@ -8,9 +8,11 @@
 from lldbsuite.test.decorators import *
 from lldbsuite.test.lldbtest import *
 from lldbsuite.test import lldbutil
+import os
 import side_effect
 
 
+
 class BreakpointCommandTestCase(TestBase):
 
     NO_DEBUG_INFO_TESTCASE = True
@@ -31,6 +33,77 @@
         self.build()
         self.breakpoint_commands_on_creation()
 
+    @skipIf(oslist=["windows"])
+    @no_debug_info_test
+    def test_breakpoints_with_relative_path_line_tables(self):
+        """
+            Test that we can set breakpoints using a full or partial path when
+            line tables in the debug information has relative paths where the
+            relative path is either fully contained in the specified path, or if
+            the specified path also a relative path that is shorter than the
+            path in the debug info.
+
+            The "relative.yaml" contains a line table that is:
+
+            Line table for a/b/c/main.cpp in `a.out
+            0x0000000100003f94: a/b/c/main.cpp:1
+            0x0000000100003fb0: a/b/c/main.cpp:2:3
+            0x0000000100003fb8: a/b/c/main.cpp:2:3
+
+            So the line table contains relative paths. We should be able to set
+            breakpoints with any source path that matches this path which
+            includes paths that are longer than "a/b/c/main.cpp", but also any
+            relative path that is shorter than this while all specified relative
+            path components still match.
+        """
+        src_dir = self.getSourceDir()
+        yaml_path = os.path.join(src_dir, "relative.yaml")
+        yaml_base, ext = os.path.splitext(yaml_path)
+        obj_path = self.getBuildArtifact("a.out")
+        self.yaml2obj(yaml_path, obj_path)
+
+        # Create a target with the object file we just created from YAML
+        target = self.dbg.CreateTarget(obj_path)
+        # We now have debug information with line table paths that start are
+        # "./a/b/c/main.cpp".
+
+        # Make sure that all of the following paths create a breakpoint
+        # successfully. We have paths that are longer than our path, and also
+        # that are shorter where all relative directories still match.
+        valid_paths = [
+            "/x/a/b/c/main.cpp",
+            "/x/y/a/b/c/main.cpp",
+            "./x/y/a/b/c/main.cpp",
+            "x/y/a/b/c/main.cpp",
+            "./y/a/b/c/main.cpp",
+            "y/a/b/c/main.cpp",
+            "./a/b/c/main.cpp",
+            "a/b/c/main.cpp",
+            "./b/c/main.cpp",
+            "b/c/main.cpp",
+            "./c/main.cpp",
+            "c/main.cpp",
+            "./main.cpp",
+            "main.cpp",
+        ]
+        for path in valid_paths:
+            bkpt = target.BreakpointCreateByLocation(path, 2)
+            self.assertTrue(bkpt.GetNumLocations() > 0,
+                'Couldn\'t resolve breakpoint using full path "%s" in executate "%s" with '
+                'debug info that has relative path with matching suffix' % (path, self.getBuildArtifact("a.out")))
+        invalid_paths = [
+            "/x/b/c/main.cpp",
+            "/x/c/main.cpp",
+            "/x/main.cpp",
+            "./x/y/a/d/c/main.cpp",
+        ]
+        for path in invalid_paths:
+            bkpt = target.BreakpointCreateByLocation(path, 2)
+            self.assertTrue(bkpt.GetNumLocations() == 0,
+                'Incorrectly resolved a breakpoint using full path "%s" with '
+                'debug info that has relative path with matching suffix' % (path))
+
+
     def setUp(self):
         # Call super's setUp().
         TestBase.setUp(self)
@@ -307,8 +380,8 @@
         for id in bp_ids:
             self.expect("breakpoint command list {0}".format(id),
                         patterns=["bktptcmd.function"])
-        
-        
+
+
 
     def test_breakpoint_delete_disabled(self):
         """Test 'break delete --disabled' works"""
Index: lldb/source/Utility/FileSpec.cpp
===================================================================
--- lldb/source/Utility/FileSpec.cpp
+++ lldb/source/Utility/FileSpec.cpp
@@ -170,9 +170,7 @@
 // up into a directory and filename and stored as uniqued string values for
 // quick comparison and efficient memory usage.
 void FileSpec::SetFile(llvm::StringRef pathname, Style style) {
-  m_filename.Clear();
-  m_directory.Clear();
-  m_is_resolved = false;
+  Clear();
   m_style = (style == Style::native) ? GetNativeStyle() : style;
 
   if (pathname.empty())
@@ -259,6 +257,8 @@
 void FileSpec::Clear() {
   m_directory.Clear();
   m_filename.Clear();
+  m_is_resolved = false;
+  m_is_absolute_valid = false;
 }
 
 // Compare two FileSpec objects. If "full" is true, then both the directory and
@@ -476,18 +476,28 @@
 }
 
 bool FileSpec::IsAbsolute() const {
+  // Cache the m_is_absolute result as we are using it a lot more in the
+  // breakpoint setting code now.
+  if (m_is_absolute_valid)
+    return m_is_absolute;
+
+  m_is_absolute_valid = true;
+  m_is_absolute = false;
+
   llvm::SmallString<64> current_path;
   GetPath(current_path, false);
 
   // Early return if the path is empty.
   if (current_path.empty())
-    return false;
+    return m_is_absolute;
 
-  // We consider paths starting with ~ to be absolute.
+    // We consider paths starting with ~ to be absolute.
   if (current_path[0] == '~')
-    return true;
+    m_is_absolute = true;
+  else
+    m_is_absolute = llvm::sys::path::is_absolute(current_path, m_style);
 
-  return llvm::sys::path::is_absolute(current_path, m_style);
+  return m_is_absolute;
 }
 
 void FileSpec::MakeAbsolute(const FileSpec &dir) {
Index: lldb/source/Symbol/CompileUnit.cpp
===================================================================
--- lldb/source/Symbol/CompileUnit.cpp
+++ lldb/source/Symbol/CompileUnit.cpp
@@ -216,7 +216,8 @@
   return m_variables;
 }
 
-std::vector<uint32_t> FindFileIndexes(const FileSpecList &files, const FileSpec &file) {
+std::vector<uint32_t> FindFileIndexes(const FileSpecList &files,
+                                      const FileSpec &file) {
   std::vector<uint32_t> result;
   uint32_t idx = -1;
   while ((idx = files.FindFileIndex(idx + 1, file, /*full=*/true)) !=
@@ -230,7 +231,8 @@
                                     LineEntry *line_entry_ptr) {
   if (!file_spec_ptr)
     file_spec_ptr = &GetPrimaryFile();
-  std::vector<uint32_t> file_indexes = FindFileIndexes(GetSupportFiles(), *file_spec_ptr);
+  std::vector<uint32_t> file_indexes = FindFileIndexes(GetSupportFiles(),
+                                                       *file_spec_ptr);
   if (file_indexes.empty())
     return UINT32_MAX;
 
@@ -255,7 +257,6 @@
   // First find all of the file indexes that match our "file_spec". If
   // "file_spec" has an empty directory, then only compare the basenames when
   // finding file indexes
-  std::vector<uint32_t> file_indexes;
   bool file_spec_matches_cu_file_spec =
       FileSpec::Match(file_spec, this->GetPrimaryFile());
 
@@ -276,13 +277,8 @@
     return;
   }
 
-  uint32_t file_idx =
-      GetSupportFiles().FindFileIndex(0, file_spec, true);
-  while (file_idx != UINT32_MAX) {
-    file_indexes.push_back(file_idx);
-    file_idx = GetSupportFiles().FindFileIndex(file_idx + 1, file_spec, true);
-  }
-
+  std::vector<uint32_t> file_indexes = FindFileIndexes(GetSupportFiles(),
+                                                       file_spec);
   const size_t num_file_indexes = file_indexes.size();
   if (num_file_indexes == 0)
     return;
Index: lldb/source/Core/FileSpecList.cpp
===================================================================
--- lldb/source/Core/FileSpecList.cpp
+++ lldb/source/Core/FileSpecList.cpp
@@ -60,20 +60,44 @@
 size_t FileSpecList::FindFileIndex(size_t start_idx, const FileSpec &file_spec,
                                    bool full) const {
   const size_t num_files = m_files.size();
+  if (start_idx >= num_files)
+    return UINT32_MAX;
 
+  const bool file_spec_relative = file_spec.IsRelative();
+  const bool file_spec_case_sensitive = file_spec.IsCaseSensitive();
   // When looking for files, we will compare only the filename if the FILE_SPEC
   // argument is empty
-  bool compare_filename_only = file_spec.GetDirectory().IsEmpty();
+  if (full && file_spec.GetDirectory().IsEmpty())
+    full = false;
 
   for (size_t idx = start_idx; idx < num_files; ++idx) {
-    if (compare_filename_only) {
-      if (ConstString::Equals(
-              m_files[idx].GetFilename(), file_spec.GetFilename(),
-              file_spec.IsCaseSensitive() || m_files[idx].IsCaseSensitive()))
-        return idx;
-    } else {
-      if (FileSpec::Equal(m_files[idx], file_spec, full))
-        return idx;
+    const FileSpec &curr_file = m_files[idx];
+
+    // Always start by matching the filename first
+    if (!curr_file.FileEquals(file_spec))
+      continue;
+
+    // Only compare the full name if the we were asked to and if the current
+    // file entry has the a directory. If it doesn't have a directory then we
+    // only compare the filename.
+    if (FileSpec::Equal(curr_file, file_spec, full)) {
+      return idx;
+    } else if (curr_file.IsRelative() || file_spec_relative) {
+      // Check if we have a relative path in our file list, or if "file_spec" is
+      // relative, if so, check if either ends with the other.
+      llvm::StringRef file_spec_dir = file_spec.GetDirectory().GetStringRef();
+      llvm::StringRef curr_file_dir = curr_file.GetDirectory().GetStringRef();
+      // We have a relative path in our file list, it matches if the
+      // specified path ends with this path
+      if (file_spec_case_sensitive && curr_file.IsCaseSensitive()) {
+        if (file_spec_dir.endswith(curr_file_dir) ||
+            curr_file_dir.endswith(file_spec_dir))
+          return idx;
+      } else {
+        if (file_spec_dir.endswith_insensitive(curr_file_dir) ||
+            curr_file_dir.endswith_insensitive(file_spec_dir))
+          return idx;
+      }
     }
   }
 
Index: lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
===================================================================
--- lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
+++ lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
@@ -119,34 +119,14 @@
 // handling inlined functions -- in this case we need to make sure we look at
 // the declaration line of the inlined function, NOT the function it was
 // inlined into.
-void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list,
-                                                bool is_relative) {
+void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list) {
   if (m_location_spec.GetExactMatch())
     return; // Nothing to do. Contexts are precise.
 
-  llvm::StringRef relative_path;
-  if (is_relative)
-    relative_path = m_location_spec.GetFileSpec().GetDirectory().GetStringRef();
-
   Log *log = GetLog(LLDBLog::Breakpoints);
   for(uint32_t i = 0; i < sc_list.GetSize(); ++i) {
     SymbolContext sc;
     sc_list.GetContextAtIndex(i, sc);
-    if (is_relative) {
-      // If the path was relative, make sure any matches match as long as the
-      // relative parts of the path match the path from support files
-      auto sc_dir = sc.line_entry.file.GetDirectory().GetStringRef();
-      if (!sc_dir.endswith(relative_path)) {
-        // We had a relative path specified and the relative directory doesn't
-        // match so remove this one
-        LLDB_LOG(log, "removing not matching relative path {0} since it "
-                "doesn't end with {1}", sc_dir, relative_path);
-        sc_list.RemoveContextAtIndex(i);
-        --i;
-        continue;
-      }
-    }
-
     if (!sc.block)
       continue;
 
@@ -230,29 +210,17 @@
   const uint32_t line = m_location_spec.GetLine().value_or(0);
   const llvm::Optional<uint16_t> column = m_location_spec.GetColumn();
 
-  // We'll create a new SourceLocationSpec that can take into account the
-  // relative path case, and we'll use it to resolve the symbol context
-  // of the CUs.
-  FileSpec search_file_spec = m_location_spec.GetFileSpec();
-  const bool is_relative = search_file_spec.IsRelative();
-  if (is_relative)
-    search_file_spec.GetDirectory().Clear();
-  SourceLocationSpec search_location_spec(
-      search_file_spec, m_location_spec.GetLine().value_or(0),
-      m_location_spec.GetColumn(), m_location_spec.GetCheckInlines(),
-      m_location_spec.GetExactMatch());
-
   const size_t num_comp_units = context.module_sp->GetNumCompileUnits();
   for (size_t i = 0; i < num_comp_units; i++) {
     CompUnitSP cu_sp(context.module_sp->GetCompileUnitAtIndex(i));
     if (cu_sp) {
       if (filter.CompUnitPasses(*cu_sp))
-        cu_sp->ResolveSymbolContext(search_location_spec,
-                                    eSymbolContextEverything, sc_list);
+        cu_sp->ResolveSymbolContext(m_location_spec, eSymbolContextEverything,
+                                    sc_list);
     }
   }
 
-  FilterContexts(sc_list, is_relative);
+  FilterContexts(sc_list);
 
   StreamString s;
   s.Printf("for %s:%d ",
Index: lldb/include/lldb/Utility/FileSpec.h
===================================================================
--- lldb/include/lldb/Utility/FileSpec.h
+++ lldb/include/lldb/Utility/FileSpec.h
@@ -405,6 +405,8 @@
   ConstString m_directory;            ///< The uniqued directory path
   ConstString m_filename;             ///< The uniqued filename path
   mutable bool m_is_resolved = false; ///< True if this path has been resolved.
+  mutable bool m_is_absolute = false; ///< True if this path is absolute.
+  mutable bool m_is_absolute_valid = false; ///< True if m_is_absolute is valid.
   Style m_style; ///< The syntax that this path uses (e.g. Windows / Posix)
 };
 
Index: lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h
===================================================================
--- lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h
+++ lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h
@@ -56,7 +56,7 @@
   CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override;
 
 protected:
-  void FilterContexts(SymbolContextList &sc_list, bool is_relative);
+  void FilterContexts(SymbolContextList &sc_list);
 
   friend class Breakpoint;
   SourceLocationSpec m_location_spec;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to