123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- FileMatchTrie.h ------------------------------------------*- C++ -*-===//
- //
- // 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
- //
- //===----------------------------------------------------------------------===//
- //
- // This file implements a match trie to find the matching file in a compilation
- // database based on a given path in the presence of symlinks.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_TOOLING_FILEMATCHTRIE_H
- #define LLVM_CLANG_TOOLING_FILEMATCHTRIE_H
- #include "clang/Basic/LLVM.h"
- #include "llvm/ADT/StringRef.h"
- #include <memory>
- namespace clang {
- namespace tooling {
- class FileMatchTrieNode;
- struct PathComparator {
- virtual ~PathComparator() = default;
- virtual bool equivalent(StringRef FileA, StringRef FileB) const = 0;
- };
- /// A trie to efficiently match against the entries of the compilation
- /// database in order of matching suffix length.
- ///
- /// When a clang tool is supposed to operate on a specific file, we have to
- /// find the corresponding file in the compilation database. Although entries
- /// in the compilation database are keyed by filename, a simple string match
- /// is insufficient because of symlinks. Commonly, a project hierarchy looks
- /// like this:
- /// /<project-root>/src/<path>/<somefile>.cc (used as input for the tool)
- /// /<project-root>/build/<symlink-to-src>/<path>/<somefile>.cc (stored in DB)
- ///
- /// Furthermore, there might be symlinks inside the source folder or inside the
- /// database, so that the same source file is translated with different build
- /// options.
- ///
- /// For a given input file, the \c FileMatchTrie finds its entries in order
- /// of matching suffix length. For each suffix length, there might be one or
- /// more entries in the database. For each of those entries, it calls
- /// \c llvm::sys::fs::equivalent() (injected as \c PathComparator). There might
- /// be zero or more entries with the same matching suffix length that are
- /// equivalent to the input file. Three cases are distinguished:
- /// 0 equivalent files: Continue with the next suffix length.
- /// 1 equivalent file: Best match found, return it.
- /// >1 equivalent files: Match is ambiguous, return error.
- class FileMatchTrie {
- public:
- FileMatchTrie();
- /// Construct a new \c FileMatchTrie with the given \c PathComparator.
- ///
- /// The \c FileMatchTrie takes ownership of 'Comparator'. Used for testing.
- FileMatchTrie(PathComparator* Comparator);
- ~FileMatchTrie();
- /// Insert a new absolute path. Relative paths are ignored.
- void insert(StringRef NewPath);
- /// Finds the corresponding file in this trie.
- ///
- /// Returns file name stored in this trie that is equivalent to 'FileName'
- /// according to 'Comparator', if it can be uniquely identified. If there
- /// are no matches an empty \c StringRef is returned. If there are ambiguous
- /// matches, an empty \c StringRef is returned and a corresponding message
- /// written to 'Error'.
- StringRef findEquivalent(StringRef FileName,
- raw_ostream &Error) const;
- private:
- FileMatchTrieNode *Root;
- std::unique_ptr<PathComparator> Comparator;
- };
- } // namespace tooling
- } // namespace clang
- #endif // LLVM_CLANG_TOOLING_FILEMATCHTRIE_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|