clang API Documentation

FileMatchTrie.h
Go to the documentation of this file.
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