FileMatchTrie.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- FileMatchTrie.h ------------------------------------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file implements a match trie to find the matching file in a compilation
  15. // database based on a given path in the presence of symlinks.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_CLANG_TOOLING_FILEMATCHTRIE_H
  19. #define LLVM_CLANG_TOOLING_FILEMATCHTRIE_H
  20. #include "clang/Basic/LLVM.h"
  21. #include "llvm/ADT/StringRef.h"
  22. #include <memory>
  23. namespace clang {
  24. namespace tooling {
  25. class FileMatchTrieNode;
  26. struct PathComparator {
  27. virtual ~PathComparator() = default;
  28. virtual bool equivalent(StringRef FileA, StringRef FileB) const = 0;
  29. };
  30. /// A trie to efficiently match against the entries of the compilation
  31. /// database in order of matching suffix length.
  32. ///
  33. /// When a clang tool is supposed to operate on a specific file, we have to
  34. /// find the corresponding file in the compilation database. Although entries
  35. /// in the compilation database are keyed by filename, a simple string match
  36. /// is insufficient because of symlinks. Commonly, a project hierarchy looks
  37. /// like this:
  38. /// /<project-root>/src/<path>/<somefile>.cc (used as input for the tool)
  39. /// /<project-root>/build/<symlink-to-src>/<path>/<somefile>.cc (stored in DB)
  40. ///
  41. /// Furthermore, there might be symlinks inside the source folder or inside the
  42. /// database, so that the same source file is translated with different build
  43. /// options.
  44. ///
  45. /// For a given input file, the \c FileMatchTrie finds its entries in order
  46. /// of matching suffix length. For each suffix length, there might be one or
  47. /// more entries in the database. For each of those entries, it calls
  48. /// \c llvm::sys::fs::equivalent() (injected as \c PathComparator). There might
  49. /// be zero or more entries with the same matching suffix length that are
  50. /// equivalent to the input file. Three cases are distinguished:
  51. /// 0 equivalent files: Continue with the next suffix length.
  52. /// 1 equivalent file: Best match found, return it.
  53. /// >1 equivalent files: Match is ambiguous, return error.
  54. class FileMatchTrie {
  55. public:
  56. FileMatchTrie();
  57. /// Construct a new \c FileMatchTrie with the given \c PathComparator.
  58. ///
  59. /// The \c FileMatchTrie takes ownership of 'Comparator'. Used for testing.
  60. FileMatchTrie(PathComparator* Comparator);
  61. ~FileMatchTrie();
  62. /// Insert a new absolute path. Relative paths are ignored.
  63. void insert(StringRef NewPath);
  64. /// Finds the corresponding file in this trie.
  65. ///
  66. /// Returns file name stored in this trie that is equivalent to 'FileName'
  67. /// according to 'Comparator', if it can be uniquely identified. If there
  68. /// are no matches an empty \c StringRef is returned. If there are ambiguous
  69. /// matches, an empty \c StringRef is returned and a corresponding message
  70. /// written to 'Error'.
  71. StringRef findEquivalent(StringRef FileName,
  72. raw_ostream &Error) const;
  73. private:
  74. FileMatchTrieNode *Root;
  75. std::unique_ptr<PathComparator> Comparator;
  76. };
  77. } // namespace tooling
  78. } // namespace clang
  79. #endif // LLVM_CLANG_TOOLING_FILEMATCHTRIE_H
  80. #ifdef __GNUC__
  81. #pragma GCC diagnostic pop
  82. #endif