blob: 569f62ddaf130f25b6c385f7f784a13c8e60a8dc [file] [log] [blame]
// Copyright 2017 The Goma Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef DEVTOOLS_GOMA_CLIENT_INCLUDE_FILE_FINDER_H_
#define DEVTOOLS_GOMA_CLIENT_INCLUDE_FILE_FINDER_H_
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using std::string;
namespace devtools_goma {
class FileStatCache;
class IncludeFileFinder {
public:
static void Init(bool gch_hack);
static bool gch_hack_enabled() {
return gch_hack_;
}
IncludeFileFinder(const IncludeFileFinder&) = delete;
IncludeFileFinder& operator=(const IncludeFileFinder&) = delete;
IncludeFileFinder(string cwd,
bool ignore_case,
const std::vector<string>* include_dirs,
const std::vector<string>* framework_dirs,
FileStatCache* file_stat_cache);
// Search included file and set to |filepath| if path is found.
// If |path_in_directive| is found in an include directory,
// Lookup(...) returns true.
bool Lookup(const string& path_in_directive,
string* filepath,
int* include_dir_index);
// Calculate |top| component in include directive.
// e.g.
// #include <foo/bar.h> -> |top| is "foo"
// #include "bar.h" -> |top| is "bar.h"
// #include <hoge\\fuga.h> -> |top| is "hoge"
// #include <foo/bar/baz.h> -> |top| is "foo"
// #include "../bar.h" -> |top| is ".."
// #include <foo\\bar\\baz.h> -> |top| is "foo"
// #include <WinBase.h> -> |top| is "winbase.h" in Windows
static string TopPathComponent(string path_in_directive, bool ignore_case);
// TODO: Make this function private
// when we can stop fallback to IncludeDirCache.
bool LookupSubframework(const string& path_in_directive,
const string& current_directory,
string* filepath);
private:
bool LookupFramework(const string& path_in_directive, string* filepath);
static bool gch_hack_;
// Defining this since no std::hash<std::pair<S, T>>.
template<typename S, typename T>
struct PairHasher {
size_t operator()(const std::pair<S, T>& p) const {
return std::hash<S>()(p.first) * 37 + std::hash<T>()(p.second);
}
};
const string cwd_;
const bool ignore_case_;
const std::vector<string>* const include_dirs_;
const std::vector<string>* const framework_dirs_;
FileStatCache* file_stat_cache_;
// Holds entries in i-th include directory.
// |files_in_include_dirs_[i]| is set of file/directory name in
// i-th include directory.
std::vector<std::unordered_set<string>> files_in_include_dirs_;
// Holds the minimum include directories index for each entries in
// include directories.
// e.g. |include_dir_index_lowerbound_["stdio.h"]| represents minimum index
// of include directory containing "stdio.h".
std::unordered_map<string, size_t> include_dir_index_lowerbound_;
// Cache for (path_in_directive, include_dir_index_start) ->
// (filepath, used_include_dir_index).
std::unordered_map<std::pair<string, int>,
std::pair<string, int>,
PairHasher<string, int>>
include_path_cache_;
// Map for "include_dir idx + (key in .hmap file)" -> filename in .hmap file.
std::unordered_map<std::pair<int, string>, string, PairHasher<int, string>>
hmap_map_;
};
} // namespace devtools_goma
#endif // DEVTOOLS_GOMA_CLIENT_INCLUDE_FILE_FINDER_H_