Ahh, makes sense.  I don't think llvm would accept a patch that did that anyway, I think they want to stick with the assumption that you're always using Host paths.  So the way you did it is probably the only way that makes sense.<br><br><div class="gmail_quote">On Mon Nov 17 2014 at 11:36:57 AM <<a href="mailto:jingham@apple.com">jingham@apple.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Thanks for the reminder.  I did check llvm::sys::path before I headed into this.  It doesn't have a routine that did exactly that I wanted, though it did have a little tokenizer/iterator that I could have used.  But the path utility in llvm currently hard-codes the assumption that the paths you are manipulating are all Host paths - it's pretty free with the assumption that they exist.  You can't make either of those assumptions about include paths in DWARF.  Of course, the llvm::sys::path code could be reworked to remove these assumptions, etc.  But that would have turned a fairly simple patch into a much bigger deal, and I've spend all the time I can afford on this bug for now.<br>
<br>
Jim<br>
<br>
<br>
> On Nov 14, 2014, at 6:55 PM, Zachary Turner <<a href="mailto:zturner@google.com" target="_blank">zturner@google.com</a>> wrote:<br>
><br>
> You might check if llvm has a method to remove all the dots and stuff already.  I think it does, but I could be wrong.<br>
><br>
> On Fri Nov 14 2014 at 5:58:15 PM Jim Ingham <<a href="mailto:jingham@apple.com" target="_blank">jingham@apple.com</a>> wrote:<br>
> Author: jingham<br>
> Date: Fri Nov 14 19:54:26 2014<br>
> New Revision: 222075<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=222075&view=rev" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project?rev=222075&view=rev</a><br>
> Log:<br>
> For some reason, sometimes the directory paths that clang emits have internal<br>
> relative paths, like:<br>
><br>
> /whatever/llvm/lib/Sema/../../<u></u>include/llvm/Sema/<br>
><br>
> That causes problems with our type uniquing, since we use the declaration file<br>
> and line as one component of the uniquing, and different ways of getting to the<br>
> same file will have different directory spellings, though they are functionally<br>
> equivalent.  We end up with two copies of the exact same type because of this,<br>
> and that makes the expression parser give "duplicate type" errors.<br>
><br>
> I added a method to resolve paths with ../ in them and used that in the FileSpec::Equals,<br>
> for comparing Declarations and for doing Breakpoint compares as well, since they also<br>
> suffer from this if you specify breakpoints by full path (since nobody knows what<br>
> ../'s to insert...)<br>
><br>
> <rdar://problem/18765814><br>
><br>
> Modified:<br>
>     lldb/trunk/include/lldb/Core/<u></u>FileSpecList.h<br>
>     lldb/trunk/include/lldb/Host/<u></u>FileSpec.h<br>
>     lldb/trunk/source/Core/<u></u>FileSpecList.cpp<br>
>     lldb/trunk/source/Host/common/<u></u>FileSpec.cpp<br>
>     lldb/trunk/source/Symbol/<u></u>CompileUnit.cpp<br>
>     lldb/trunk/source/Symbol/<u></u>Declaration.cpp<br>
><br>
> Modified: lldb/trunk/include/lldb/Core/<u></u>FileSpecList.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FileSpecList.h?rev=222075&r1=222074&r2=222075&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/lldb/trunk/include/<u></u>lldb/Core/FileSpecList.h?rev=<u></u>222075&r1=222074&r2=222075&<u></u>view=diff</a><br>
> ==============================<u></u>==============================<u></u>==================<br>
> --- lldb/trunk/include/lldb/Core/<u></u>FileSpecList.h (original)<br>
> +++ lldb/trunk/include/lldb/Core/<u></u>FileSpecList.h Fri Nov 14 19:54:26 2014<br>
> @@ -119,12 +119,15 @@ public:<br>
>      /// @param[in] full<br>
>      ///     Should FileSpec::Equal be called with "full" true or false.<br>
>      ///<br>
> +    /// @param[in] remove_backup_dots<br>
> +    ///     Should FileSpec::Equal be called with "remove_backup_dots" true or false.<br>
> +    ///<br>
>      /// @return<br>
>      ///     The index of the file that matches \a file if it is found,<br>
>      ///     else UINT32_MAX is returned.<br>
>      //----------------------------<u></u>------------------------------<u></u>--------<br>
>      size_t<br>
> -    FindFileIndex (size_t idx, const FileSpec &file, bool full) const;<br>
> +    FindFileIndex (size_t idx, const FileSpec &file, bool full, bool remove_backup_dots = false) const;<br>
><br>
>      //----------------------------<u></u>------------------------------<u></u>--------<br>
>      /// Get file at index.<br>
><br>
> Modified: lldb/trunk/include/lldb/Host/<u></u>FileSpec.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/FileSpec.h?rev=222075&r1=222074&r2=222075&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/lldb/trunk/include/<u></u>lldb/Host/FileSpec.h?rev=<u></u>222075&r1=222074&r2=222075&<u></u>view=diff</a><br>
> ==============================<u></u>==============================<u></u>==================<br>
> --- lldb/trunk/include/lldb/Host/<u></u>FileSpec.h (original)<br>
> +++ lldb/trunk/include/lldb/Host/<u></u>FileSpec.h Fri Nov 14 19:54:26 2014<br>
> @@ -246,7 +246,7 @@ public:<br>
>      Compare (const FileSpec& lhs, const FileSpec& rhs, bool full);<br>
><br>
>      static bool<br>
> -    Equal (const FileSpec& a, const FileSpec& b, bool full);<br>
> +    Equal (const FileSpec& a, const FileSpec& b, bool full, bool remove_backups = false);<br>
><br>
>      //----------------------------<u></u>------------------------------<u></u>--------<br>
>      /// Dump this object to a Stream.<br>
> @@ -582,6 +582,20 @@ public:<br>
>      static void Normalize(llvm::<u></u>SmallVectorImpl<char> &path, PathSyntax syntax = ePathSyntaxHostNative);<br>
>      static void DeNormalize(llvm::<u></u>SmallVectorImpl<char> &path, PathSyntax syntax = ePathSyntaxHostNative);<br>
><br>
> +<br>
> +    //----------------------------<u></u>------------------------------<u></u>--------<br>
> +    /// Run through the input string, replaying the effect of any ".." and produce<br>
> +    /// the resultant path.  The input path is not required to be in the host file system<br>
> +    /// format, but it is required to be normalized to that system.<br>
> +    ///<br>
> +    /// @param[in] input<br>
> +    ///     The input path to analyze.<br>
> +    ///<br>
> +    /// @param[out] result<br>
> +    ///     The backup-resolved path will be written here.<br>
> +    //----------------------------<u></u>------------------------------<u></u>--------<br>
> +    static void RemoveBackupDots (const ConstString &input_const_str, ConstString &result_const_str);<br>
> +<br>
>      //----------------------------<u></u>------------------------------<u></u>--------<br>
>      /// Change the file specified with a new path.<br>
>      ///<br>
><br>
> Modified: lldb/trunk/source/Core/<u></u>FileSpecList.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FileSpecList.cpp?rev=222075&r1=222074&r2=222075&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/lldb/trunk/source/<u></u>Core/FileSpecList.cpp?rev=<u></u>222075&r1=222074&r2=222075&<u></u>view=diff</a><br>
> ==============================<u></u>==============================<u></u>==================<br>
> --- lldb/trunk/source/Core/<u></u>FileSpecList.cpp (original)<br>
> +++ lldb/trunk/source/Core/<u></u>FileSpecList.cpp Fri Nov 14 19:54:26 2014<br>
> @@ -107,7 +107,7 @@ FileSpecList::Dump(Stream *s, const char<br>
>  // it is found, else UINT32_MAX is returned.<br>
>  //----------------------------<u></u>------------------------------<u></u>--------<br>
>  size_t<br>
> -FileSpecList::FindFileIndex (size_t start_idx, const FileSpec &file_spec, bool full) const<br>
> +FileSpecList::FindFileIndex (size_t start_idx, const FileSpec &file_spec, bool full, bool remove_dots) const<br>
>  {<br>
>      const size_t num_files = m_files.size();<br>
><br>
> @@ -124,7 +124,7 @@ FileSpecList::FindFileIndex (size_t star<br>
>          }<br>
>          else<br>
>          {<br>
> -            if (FileSpec::Equal (m_files[idx], file_spec, full))<br>
> +            if (FileSpec::Equal (m_files[idx], file_spec, full, remove_dots))<br>
>                  return idx;<br>
>          }<br>
>      }<br>
><br>
> Modified: lldb/trunk/source/Host/common/<u></u>FileSpec.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/FileSpec.cpp?rev=222075&r1=222074&r2=222075&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/lldb/trunk/source/<u></u>Host/common/FileSpec.cpp?rev=<u></u>222075&r1=222074&r2=222075&<u></u>view=diff</a><br>
> ==============================<u></u>==============================<u></u>==================<br>
> --- lldb/trunk/source/Host/common/<u></u>FileSpec.cpp (original)<br>
> +++ lldb/trunk/source/Host/common/<u></u>FileSpec.cpp Fri Nov 14 19:54:26 2014<br>
> @@ -448,15 +448,129 @@ FileSpec::Compare(const FileSpec& a, con<br>
>  }<br>
><br>
>  bool<br>
> -FileSpec::Equal (const FileSpec& a, const FileSpec& b, bool full)<br>
> +FileSpec::Equal (const FileSpec& a, const FileSpec& b, bool full, bool remove_backups)<br>
>  {<br>
>      if (!full && (a.GetDirectory().IsEmpty() || b.GetDirectory().IsEmpty()))<br>
>          return a.m_filename == b.m_filename;<br>
> -    else<br>
> +    else if (remove_backups == false)<br>
>          return a == b;<br>
> +    else<br>
> +    {<br>
> +        if (a.m_filename != b.m_filename)<br>
> +            return false;<br>
> +        if (a.m_directory == b.m_directory)<br>
> +            return true;<br>
> +        ConstString a_without_dots;<br>
> +        ConstString b_without_dots;<br>
> +<br>
> +        RemoveBackupDots (a.m_directory, a_without_dots);<br>
> +        RemoveBackupDots (b.m_directory, b_without_dots);<br>
> +        return a_without_dots == b_without_dots;<br>
> +    }<br>
>  }<br>
><br>
> +void<br>
> +FileSpec::RemoveBackupDots (const ConstString &input_const_str, ConstString &result_const_str)<br>
> +{<br>
> +    const char *input = input_const_str.GetCString();<br>
> +    result_const_str.Clear();<br>
> +    if (!input || input[0] == '\0')<br>
> +        return;<br>
> +<br>
> +    const char win_sep = '\\';<br>
> +    const char unix_sep = '/';<br>
> +    char found_sep;<br>
> +    const char *win_backup = "\\..";<br>
> +    const char *unix_backup = "/..";<br>
> +<br>
> +    bool is_win = false;<br>
> +<br>
> +    // Determine the platform for the path (win or unix):<br>
> +<br>
> +    if (input[0] == win_sep)<br>
> +        is_win = true;<br>
> +    else if (input[0] == unix_sep)<br>
> +        is_win = false;<br>
> +    else if (input[1] == ':')<br>
> +        is_win = true;<br>
> +    else if (strchr(input, unix_sep) != nullptr)<br>
> +        is_win = false;<br>
> +    else if (strchr(input, win_sep) != nullptr)<br>
> +        is_win = true;<br>
> +    else<br>
> +    {<br>
> +        // No separators at all, no reason to do any work here.<br>
> +        result_const_str = input_const_str;<br>
> +        return;<br>
> +    }<br>
> +<br>
> +    llvm::StringRef backup_sep;<br>
> +    if (is_win)<br>
> +    {<br>
> +        found_sep = win_sep;<br>
> +        backup_sep = win_backup;<br>
> +    }<br>
> +    else<br>
> +    {<br>
> +        found_sep = unix_sep;<br>
> +        backup_sep = unix_backup;<br>
> +    }<br>
> +<br>
> +    llvm::StringRef input_ref(input);<br>
> +    llvm::StringRef curpos(input);<br>
> +<br>
> +    bool had_dots = false;<br>
> +    std::string result;<br>
> +<br>
> +    while (1)<br>
> +    {<br>
> +        // Start of loop<br>
> +        llvm::StringRef before_sep;<br>
> +        std::pair<llvm::StringRef, llvm::StringRef> around_sep = curpos.split(backup_sep);<br>
> +<br>
> +        before_sep = around_sep.first;<br>
> +        curpos     = around_sep.second;<br>
><br>
> +        if (curpos.empty())<br>
> +        {<br>
> +            if (had_dots)<br>
> +            {<br>
> +                if (!before_sep.empty())<br>
> +                {<br>
> +                    result.append(before_sep.data(<u></u>), before_sep.size());<br>
> +                }<br>
> +            }<br>
> +            break;<br>
> +        }<br>
> +        had_dots = true;<br>
> +<br>
> +        unsigned num_backups = 1;<br>
> +        while (curpos.startswith(backup_sep)<u></u>)<br>
> +        {<br>
> +            num_backups++;<br>
> +            curpos = curpos.slice(backup_sep.size()<u></u>, curpos.size());<br>
> +        }<br>
> +<br>
> +        size_t end_pos = before_sep.size();<br>
> +        while (num_backups-- > 0)<br>
> +        {<br>
> +            end_pos = before_sep.rfind(found_sep, end_pos);<br>
> +            if (end_pos == llvm::StringRef::npos)<br>
> +            {<br>
> +                result_const_str = input_const_str;<br>
> +                return;<br>
> +            }<br>
> +        }<br>
> +        result.append(before_sep.data(<u></u>), end_pos);<br>
> +    }<br>
> +<br>
> +    if (had_dots)<br>
> +        result_const_str.SetCString(<u></u>result.c_str());<br>
> +    else<br>
> +        result_const_str = input_const_str;<br>
> +<br>
> +    return;<br>
> +}<br>
><br>
>  //----------------------------<u></u>------------------------------<u></u>--------<br>
>  // Dump the object to the supplied stream. If the object contains<br>
><br>
> Modified: lldb/trunk/source/Symbol/<u></u>CompileUnit.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/CompileUnit.cpp?rev=222075&r1=222074&r2=222075&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/lldb/trunk/source/<u></u>Symbol/CompileUnit.cpp?rev=<u></u>222075&r1=222074&r2=222075&<u></u>view=diff</a><br>
> ==============================<u></u>==============================<u></u>==================<br>
> --- lldb/trunk/source/Symbol/<u></u>CompileUnit.cpp (original)<br>
> +++ lldb/trunk/source/Symbol/<u></u>CompileUnit.cpp Fri Nov 14 19:54:26 2014<br>
> @@ -325,18 +325,19 @@ CompileUnit::<u></u>ResolveSymbolContext<br>
>      // when finding file indexes<br>
>      std::vector<uint32_t> file_indexes;<br>
>      const bool full_match = (bool)file_spec.GetDirectory()<u></u>;<br>
> -    bool file_spec_matches_cu_file_spec = FileSpec::Equal(file_spec, *this, full_match);<br>
> +    const bool remove_backup_dots = true;<br>
> +    bool file_spec_matches_cu_file_spec = FileSpec::Equal(file_spec, *this, full_match, remove_backup_dots);<br>
><br>
>      // If we are not looking for inlined functions and our file spec doesn't<br>
>      // match then we are done...<br>
>      if (file_spec_matches_cu_file_<u></u>spec == false && check_inlines == false)<br>
>          return 0;<br>
><br>
> -    uint32_t file_idx = GetSupportFiles().<u></u>FindFileIndex (1, file_spec, true);<br>
> +    uint32_t file_idx = GetSupportFiles().<u></u>FindFileIndex (1, file_spec, true, remove_backup_dots);<br>
>      while (file_idx != UINT32_MAX)<br>
>      {<br>
>          file_indexes.push_back (file_idx);<br>
> -        file_idx = GetSupportFiles().<u></u>FindFileIndex (file_idx + 1, file_spec, true);<br>
> +        file_idx = GetSupportFiles().<u></u>FindFileIndex (file_idx + 1, file_spec, true, remove_backup_dots);<br>
>      }<br>
><br>
>      const size_t num_file_indexes = file_indexes.size();<br>
><br>
> Modified: lldb/trunk/source/Symbol/<u></u>Declaration.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Declaration.cpp?rev=222075&r1=222074&r2=222075&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/lldb/trunk/source/<u></u>Symbol/Declaration.cpp?rev=<u></u>222075&r1=222074&r2=222075&<u></u>view=diff</a><br>
> ==============================<u></u>==============================<u></u>==================<br>
> --- lldb/trunk/source/Symbol/<u></u>Declaration.cpp (original)<br>
> +++ lldb/trunk/source/Symbol/<u></u>Declaration.cpp Fri Nov 14 19:54:26 2014<br>
> @@ -110,7 +110,7 @@ lldb_private::operator == (const Declara<br>
>              return lhs.GetFile() == rhs.GetFile();<br>
>  #else<br>
>      if (lhs.GetLine () == rhs.GetLine ())<br>
> -        return lhs.GetFile() == rhs.GetFile();<br>
> +        return FileSpec::Equal(lhs.GetFile(),<u></u>rhs.GetFile(), true, true);<br>
>  #endif<br>
>      return false;<br>
>  }<br>
><br>
><br>
> ______________________________<u></u>_________________<br>
> lldb-commits mailing list<br>
> <a href="mailto:lldb-commits@cs.uiuc.edu" target="_blank">lldb-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits" target="_blank">http://lists.cs.uiuc.edu/<u></u>mailman/listinfo/lldb-commits</a><br>
<br>
</blockquote></div>