clang API Documentation
00001 //===--- FileMatchTrie.h - --------------------------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements a match trie to find the matching file in a compilation 00011 // database based on a given path in the presence of symlinks. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_CLANG_TOOLING_FILEMATCHTRIE_H 00016 #define LLVM_CLANG_TOOLING_FILEMATCHTRIE_H 00017 00018 #include "clang/Basic/LLVM.h" 00019 #include "llvm/ADT/StringRef.h" 00020 #include <memory> 00021 #include <string> 00022 #include <vector> 00023 00024 namespace clang { 00025 namespace tooling { 00026 00027 struct PathComparator { 00028 virtual ~PathComparator() {} 00029 virtual bool equivalent(StringRef FileA, StringRef FileB) const = 0; 00030 }; 00031 class FileMatchTrieNode; 00032 00033 /// \brief A trie to efficiently match against the entries of the compilation 00034 /// database in order of matching suffix length. 00035 /// 00036 /// When a clang tool is supposed to operate on a specific file, we have to 00037 /// find the corresponding file in the compilation database. Although entries 00038 /// in the compilation database are keyed by filename, a simple string match 00039 /// is insufficient because of symlinks. Commonly, a project hierarchy looks 00040 /// like this: 00041 /// /<project-root>/src/<path>/<somefile>.cc (used as input for the tool) 00042 /// /<project-root>/build/<symlink-to-src>/<path>/<somefile>.cc (stored in DB) 00043 /// 00044 /// Furthermore, there might be symlinks inside the source folder or inside the 00045 /// database, so that the same source file is translated with different build 00046 /// options. 00047 /// 00048 /// For a given input file, the \c FileMatchTrie finds its entries in order 00049 /// of matching suffix length. For each suffix length, there might be one or 00050 /// more entries in the database. For each of those entries, it calls 00051 /// \c llvm::sys::fs::equivalent() (injected as \c PathComparator). There might 00052 /// be zero or more entries with the same matching suffix length that are 00053 /// equivalent to the input file. Three cases are distinguished: 00054 /// 0 equivalent files: Continue with the next suffix length. 00055 /// 1 equivalent file: Best match found, return it. 00056 /// >1 equivalent files: Match is ambiguous, return error. 00057 class FileMatchTrie { 00058 public: 00059 FileMatchTrie(); 00060 00061 /// \brief Construct a new \c FileMatchTrie with the given \c PathComparator. 00062 /// 00063 /// The \c FileMatchTrie takes ownership of 'Comparator'. Used for testing. 00064 FileMatchTrie(PathComparator* Comparator); 00065 00066 ~FileMatchTrie(); 00067 00068 /// \brief Insert a new absolute path. Relative paths are ignored. 00069 void insert(StringRef NewPath); 00070 00071 /// \brief Finds the corresponding file in this trie. 00072 /// 00073 /// Returns file name stored in this trie that is equivalent to 'FileName' 00074 /// according to 'Comparator', if it can be uniquely identified. If there 00075 /// are no matches an empty \c StringRef is returned. If there are ambigious 00076 /// matches, an empty \c StringRef is returned and a corresponding message 00077 /// written to 'Error'. 00078 StringRef findEquivalent(StringRef FileName, 00079 raw_ostream &Error) const; 00080 private: 00081 FileMatchTrieNode *Root; 00082 std::unique_ptr<PathComparator> Comparator; 00083 }; 00084 00085 00086 } // end namespace tooling 00087 } // end namespace clang 00088 00089 #endif