mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-22 07:35:08 +00:00
indexer: llvm::sys::fs::UniqueID -> clang::FileID
Fix a minor issue that an empty included file is not recorded. Note, we need to skip invalid uid2lid_and_path because otherwise lid2path may contain invalid entries with lid: 0, which will cause the file entry with file_id 0 to have an empty path.
This commit is contained in:
parent
0f0e679edb
commit
65f86d0498
@ -42,42 +42,30 @@ static Pos decomposed2LineAndCol(const SourceManager &sm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Range fromCharSourceRange(const SourceManager &sm, const LangOptions &lang,
|
Range fromCharSourceRange(const SourceManager &sm, const LangOptions &lang,
|
||||||
CharSourceRange csr,
|
CharSourceRange csr, FileID *fid) {
|
||||||
llvm::sys::fs::UniqueID *uniqueID) {
|
|
||||||
SourceLocation bloc = csr.getBegin(), eloc = csr.getEnd();
|
SourceLocation bloc = csr.getBegin(), eloc = csr.getEnd();
|
||||||
std::pair<FileID, unsigned> binfo = sm.getDecomposedLoc(bloc),
|
std::pair<FileID, unsigned> binfo = sm.getDecomposedLoc(bloc),
|
||||||
einfo = sm.getDecomposedLoc(eloc);
|
einfo = sm.getDecomposedLoc(eloc);
|
||||||
if (csr.isTokenRange())
|
if (csr.isTokenRange())
|
||||||
einfo.second += Lexer::MeasureTokenLength(eloc, sm, lang);
|
einfo.second += Lexer::MeasureTokenLength(eloc, sm, lang);
|
||||||
if (uniqueID) {
|
if (fid)
|
||||||
if (const FileEntry *F = sm.getFileEntryForID(binfo.first))
|
*fid = binfo.first;
|
||||||
*uniqueID = F->getUniqueID();
|
|
||||||
else
|
|
||||||
*uniqueID = llvm::sys::fs::UniqueID(0, 0);
|
|
||||||
}
|
|
||||||
return {decomposed2LineAndCol(sm, binfo), decomposed2LineAndCol(sm, einfo)};
|
return {decomposed2LineAndCol(sm, binfo), decomposed2LineAndCol(sm, einfo)};
|
||||||
}
|
}
|
||||||
|
|
||||||
Range fromCharRange(const SourceManager &sm, const LangOptions &lang,
|
|
||||||
SourceRange sr, llvm::sys::fs::UniqueID *uniqueID) {
|
|
||||||
return fromCharSourceRange(sm, lang, CharSourceRange::getCharRange(sr),
|
|
||||||
uniqueID);
|
|
||||||
}
|
|
||||||
|
|
||||||
Range fromTokenRange(const SourceManager &sm, const LangOptions &lang,
|
Range fromTokenRange(const SourceManager &sm, const LangOptions &lang,
|
||||||
SourceRange sr, llvm::sys::fs::UniqueID *uniqueID) {
|
SourceRange sr, FileID *fid) {
|
||||||
return fromCharSourceRange(sm, lang, CharSourceRange::getTokenRange(sr),
|
return fromCharSourceRange(sm, lang, CharSourceRange::getTokenRange(sr), fid);
|
||||||
uniqueID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Range fromTokenRangeDefaulted(const SourceManager &sm, const LangOptions &lang,
|
Range fromTokenRangeDefaulted(const SourceManager &sm, const LangOptions &lang,
|
||||||
SourceRange sr, const FileEntry *fe, Range range) {
|
SourceRange sr, FileID fid, Range range) {
|
||||||
auto decomposed = sm.getDecomposedLoc(sm.getExpansionLoc(sr.getBegin()));
|
auto decomposed = sm.getDecomposedLoc(sm.getExpansionLoc(sr.getBegin()));
|
||||||
if (sm.getFileEntryForID(decomposed.first) == fe)
|
if (decomposed.first == fid)
|
||||||
range.start = decomposed2LineAndCol(sm, decomposed);
|
range.start = decomposed2LineAndCol(sm, decomposed);
|
||||||
SourceLocation sl = sm.getExpansionLoc(sr.getEnd());
|
SourceLocation sl = sm.getExpansionLoc(sr.getEnd());
|
||||||
decomposed = sm.getDecomposedLoc(sl);
|
decomposed = sm.getDecomposedLoc(sl);
|
||||||
if (sm.getFileEntryForID(decomposed.first) == fe) {
|
if (decomposed.first == fid) {
|
||||||
decomposed.second += Lexer::MeasureTokenLength(sl, sm, lang);
|
decomposed.second += Lexer::MeasureTokenLength(sl, sm, lang);
|
||||||
range.end = decomposed2LineAndCol(sm, decomposed);
|
range.end = decomposed2LineAndCol(sm, decomposed);
|
||||||
}
|
}
|
||||||
|
@ -22,20 +22,16 @@ std::string pathFromFileEntry(const clang::FileEntry &file);
|
|||||||
|
|
||||||
Range fromCharSourceRange(const clang::SourceManager &sm,
|
Range fromCharSourceRange(const clang::SourceManager &sm,
|
||||||
const clang::LangOptions &lang,
|
const clang::LangOptions &lang,
|
||||||
clang::CharSourceRange sr,
|
clang::CharSourceRange csr,
|
||||||
llvm::sys::fs::UniqueID *uniqueID = nullptr);
|
clang::FileID *fid = nullptr);
|
||||||
|
|
||||||
Range fromCharRange(const clang::SourceManager &sm,
|
|
||||||
const clang::LangOptions &lang, clang::SourceRange sr,
|
|
||||||
llvm::sys::fs::UniqueID *uniqueID = nullptr);
|
|
||||||
|
|
||||||
Range fromTokenRange(const clang::SourceManager &sm,
|
Range fromTokenRange(const clang::SourceManager &sm,
|
||||||
const clang::LangOptions &lang, clang::SourceRange sr,
|
const clang::LangOptions &lang, clang::SourceRange sr,
|
||||||
llvm::sys::fs::UniqueID *uniqueID = nullptr);
|
clang::FileID *fid = nullptr);
|
||||||
|
|
||||||
Range fromTokenRangeDefaulted(const clang::SourceManager &sm,
|
Range fromTokenRangeDefaulted(const clang::SourceManager &sm,
|
||||||
const clang::LangOptions &lang,
|
const clang::LangOptions &lang,
|
||||||
clang::SourceRange sr, const clang::FileEntry *fe,
|
clang::SourceRange sr, clang::FileID fid,
|
||||||
Range range);
|
Range range);
|
||||||
|
|
||||||
std::unique_ptr<clang::CompilerInvocation>
|
std::unique_ptr<clang::CompilerInvocation>
|
||||||
|
106
src/indexer.cc
106
src/indexer.cc
@ -40,8 +40,8 @@ struct File {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct IndexParam {
|
struct IndexParam {
|
||||||
std::unordered_map<llvm::sys::fs::UniqueID, File> uid2file;
|
std::unordered_map<FileID, File> uid2file;
|
||||||
std::unordered_map<llvm::sys::fs::UniqueID, bool> uid2multi;
|
std::unordered_map<FileID, bool> uid2multi;
|
||||||
struct DeclInfo {
|
struct DeclInfo {
|
||||||
Usr usr;
|
Usr usr;
|
||||||
std::string short_name;
|
std::string short_name;
|
||||||
@ -54,14 +54,17 @@ struct IndexParam {
|
|||||||
bool no_linkage;
|
bool no_linkage;
|
||||||
IndexParam(VFS &vfs, bool no_linkage) : vfs(vfs), no_linkage(no_linkage) {}
|
IndexParam(VFS &vfs, bool no_linkage) : vfs(vfs), no_linkage(no_linkage) {}
|
||||||
|
|
||||||
void seenFile(const FileEntry &file) {
|
void seenFile(FileID fid) {
|
||||||
// If this is the first time we have seen the file (ignoring if we are
|
// If this is the first time we have seen the file (ignoring if we are
|
||||||
// generating an index for it):
|
// generating an index for it):
|
||||||
auto [it, inserted] = uid2file.try_emplace(file.getUniqueID());
|
auto [it, inserted] = uid2file.try_emplace(fid);
|
||||||
if (inserted) {
|
if (inserted) {
|
||||||
std::string path = pathFromFileEntry(file);
|
const FileEntry *fe = ctx->getSourceManager().getFileEntryForID(fid);
|
||||||
|
if (!fe)
|
||||||
|
return;
|
||||||
|
std::string path = pathFromFileEntry(*fe);
|
||||||
it->second.path = path;
|
it->second.path = path;
|
||||||
it->second.mtime = file.getModificationTime();
|
it->second.mtime = fe->getModificationTime();
|
||||||
if (!it->second.mtime)
|
if (!it->second.mtime)
|
||||||
if (auto tim = lastWriteTime(path))
|
if (auto tim = lastWriteTime(path))
|
||||||
it->second.mtime = *tim;
|
it->second.mtime = *tim;
|
||||||
@ -75,15 +78,16 @@ struct IndexParam {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexFile *consumeFile(const FileEntry &fe) {
|
IndexFile *consumeFile(FileID fid) {
|
||||||
seenFile(fe);
|
seenFile(fid);
|
||||||
return uid2file[fe.getUniqueID()].db.get();
|
return uid2file[fid].db.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool useMultiVersion(const FileEntry &fe) {
|
bool useMultiVersion(FileID fid) {
|
||||||
auto it = uid2multi.try_emplace(fe.getUniqueID());
|
auto it = uid2multi.try_emplace(fid);
|
||||||
if (it.second)
|
if (it.second)
|
||||||
it.first->second = multiVersionMatcher->matches(pathFromFileEntry(fe));
|
if (const FileEntry *fe = ctx->getSourceManager().getFileEntryForID(fid))
|
||||||
|
it.first->second = multiVersionMatcher->matches(pathFromFileEntry(*fe));
|
||||||
return it.first->second;
|
return it.first->second;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -609,27 +613,24 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getFileLID(IndexFile *db, SourceManager &sm, const FileEntry &fe) {
|
static int getFileLID(IndexFile *db, SourceManager &sm, FileID fid) {
|
||||||
auto [it, inserted] = db->uid2lid_and_path.try_emplace(fe.getUniqueID());
|
auto [it, inserted] = db->uid2lid_and_path.try_emplace(fid);
|
||||||
if (inserted) {
|
if (inserted) {
|
||||||
it->second.first = db->uid2lid_and_path.size() - 1;
|
const FileEntry *fe = sm.getFileEntryForID(fid);
|
||||||
SmallString<256> path = fe.tryGetRealPathName();
|
if (!fe) {
|
||||||
if (path.empty())
|
it->second.first = -1;
|
||||||
path = fe.getName();
|
|
||||||
if (!llvm::sys::path::is_absolute(path) &&
|
|
||||||
!sm.getFileManager().makeAbsolutePath(path))
|
|
||||||
return -1;
|
return -1;
|
||||||
it->second.second = llvm::sys::path::convert_to_slash(path.str());
|
}
|
||||||
|
it->second.first = db->uid2lid_and_path.size() - 1;
|
||||||
|
it->second.second = pathFromFileEntry(*fe);
|
||||||
}
|
}
|
||||||
return it->second.first;
|
return it->second.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addMacroUse(IndexFile *db, SourceManager &sm, Usr usr, Kind kind,
|
void addMacroUse(IndexFile *db, SourceManager &sm, Usr usr, Kind kind,
|
||||||
SourceLocation sl) const {
|
SourceLocation sl) const {
|
||||||
const FileEntry *FE = sm.getFileEntryForID(sm.getFileID(sl));
|
FileID fid = sm.getFileID(sl);
|
||||||
if (!FE)
|
int lid = getFileLID(db, sm, fid);
|
||||||
return;
|
|
||||||
int lid = getFileLID(db, sm, *FE);
|
|
||||||
if (lid < 0)
|
if (lid < 0)
|
||||||
return;
|
return;
|
||||||
Range spell = fromTokenRange(sm, ctx->getLangOpts(), SourceRange(sl, sl));
|
Range spell = fromTokenRange(sm, ctx->getLangOpts(), SourceRange(sl, sl));
|
||||||
@ -693,27 +694,25 @@ public:
|
|||||||
const LangOptions &lang = ctx->getLangOpts();
|
const LangOptions &lang = ctx->getLangOpts();
|
||||||
FileID fid;
|
FileID fid;
|
||||||
SourceLocation spell = sm.getSpellingLoc(src_loc);
|
SourceLocation spell = sm.getSpellingLoc(src_loc);
|
||||||
const FileEntry *fe;
|
|
||||||
Range loc;
|
Range loc;
|
||||||
auto r = sm.isMacroArgExpansion(src_loc)
|
auto r = sm.isMacroArgExpansion(src_loc)
|
||||||
? CharSourceRange::getTokenRange(spell)
|
? CharSourceRange::getTokenRange(spell)
|
||||||
: sm.getExpansionRange(src_loc);
|
: sm.getExpansionRange(src_loc);
|
||||||
loc = fromCharSourceRange(sm, lang, r);
|
loc = fromCharSourceRange(sm, lang, r);
|
||||||
fid = sm.getFileID(r.getBegin());
|
fid = sm.getFileID(r.getBegin());
|
||||||
fe = sm.getFileEntryForID(fid);
|
if (fid.isInvalid())
|
||||||
if (!fe)
|
|
||||||
return true;
|
return true;
|
||||||
int lid = -1;
|
int lid = -1;
|
||||||
IndexFile *db;
|
IndexFile *db;
|
||||||
if (g_config->index.multiVersion && param.useMultiVersion(*fe)) {
|
if (g_config->index.multiVersion && param.useMultiVersion(fid)) {
|
||||||
db = param.consumeFile(*sm.getFileEntryForID(sm.getMainFileID()));
|
db = param.consumeFile(sm.getMainFileID());
|
||||||
if (!db)
|
if (!db)
|
||||||
return true;
|
return true;
|
||||||
param.seenFile(*fe);
|
param.seenFile(fid);
|
||||||
if (!sm.isWrittenInMainFile(r.getBegin()))
|
if (!sm.isWrittenInMainFile(r.getBegin()))
|
||||||
lid = getFileLID(db, sm, *fe);
|
lid = getFileLID(db, sm, fid);
|
||||||
} else {
|
} else {
|
||||||
db = param.consumeFile(*fe);
|
db = param.consumeFile(fid);
|
||||||
if (!db)
|
if (!db)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -775,13 +774,13 @@ public:
|
|||||||
if (is_def) {
|
if (is_def) {
|
||||||
SourceRange sr = origD->getSourceRange();
|
SourceRange sr = origD->getSourceRange();
|
||||||
entity->def.spell = {use,
|
entity->def.spell = {use,
|
||||||
fromTokenRangeDefaulted(sm, lang, sr, fe, loc)};
|
fromTokenRangeDefaulted(sm, lang, sr, fid, loc)};
|
||||||
entity->def.parent_kind = SymbolKind::File;
|
entity->def.parent_kind = SymbolKind::File;
|
||||||
getKind(cast<Decl>(sem_dc), entity->def.parent_kind);
|
getKind(cast<Decl>(sem_dc), entity->def.parent_kind);
|
||||||
} else if (is_decl) {
|
} else if (is_decl) {
|
||||||
SourceRange sr = origD->getSourceRange();
|
SourceRange sr = origD->getSourceRange();
|
||||||
entity->declarations.push_back(
|
entity->declarations.push_back(
|
||||||
{use, fromTokenRangeDefaulted(sm, lang, sr, fe, loc)});
|
{use, fromTokenRangeDefaulted(sm, lang, sr, fid, loc)});
|
||||||
} else {
|
} else {
|
||||||
entity->uses.push_back(use);
|
entity->uses.push_back(use);
|
||||||
return;
|
return;
|
||||||
@ -1077,6 +1076,11 @@ class IndexPPCallbacks : public PPCallbacks {
|
|||||||
public:
|
public:
|
||||||
IndexPPCallbacks(SourceManager &sm, IndexParam ¶m)
|
IndexPPCallbacks(SourceManager &sm, IndexParam ¶m)
|
||||||
: sm(sm), param(param) {}
|
: sm(sm), param(param) {}
|
||||||
|
void FileChanged(SourceLocation sl, FileChangeReason reason,
|
||||||
|
SrcMgr::CharacteristicKind, FileID) override {
|
||||||
|
if (reason == FileChangeReason::EnterFile)
|
||||||
|
(void)param.consumeFile(sm.getFileID(sl));
|
||||||
|
}
|
||||||
void InclusionDirective(SourceLocation hashLoc, const Token &tok,
|
void InclusionDirective(SourceLocation hashLoc, const Token &tok,
|
||||||
StringRef included, bool isAngled,
|
StringRef included, bool isAngled,
|
||||||
CharSourceRange filenameRange, const FileEntry *file,
|
CharSourceRange filenameRange, const FileEntry *file,
|
||||||
@ -1087,11 +1091,8 @@ public:
|
|||||||
return;
|
return;
|
||||||
auto spell = fromCharSourceRange(sm, param.ctx->getLangOpts(),
|
auto spell = fromCharSourceRange(sm, param.ctx->getLangOpts(),
|
||||||
filenameRange, nullptr);
|
filenameRange, nullptr);
|
||||||
const FileEntry *fe =
|
FileID fid = sm.getFileID(filenameRange.getBegin());
|
||||||
sm.getFileEntryForID(sm.getFileID(filenameRange.getBegin()));
|
if (IndexFile *db = param.consumeFile(fid)) {
|
||||||
if (!fe)
|
|
||||||
return;
|
|
||||||
if (IndexFile *db = param.consumeFile(*fe)) {
|
|
||||||
std::string path = pathFromFileEntry(*file);
|
std::string path = pathFromFileEntry(*file);
|
||||||
if (path.size())
|
if (path.size())
|
||||||
db->includes.push_back({spell.start.line, intern(path)});
|
db->includes.push_back({spell.start.line, intern(path)});
|
||||||
@ -1100,10 +1101,8 @@ public:
|
|||||||
void MacroDefined(const Token &tok, const MacroDirective *md) override {
|
void MacroDefined(const Token &tok, const MacroDirective *md) override {
|
||||||
const LangOptions &lang = param.ctx->getLangOpts();
|
const LangOptions &lang = param.ctx->getLangOpts();
|
||||||
SourceLocation sl = md->getLocation();
|
SourceLocation sl = md->getLocation();
|
||||||
const FileEntry *fe = sm.getFileEntryForID(sm.getFileID(sl));
|
FileID fid = sm.getFileID(sl);
|
||||||
if (!fe)
|
if (IndexFile *db = param.consumeFile(fid)) {
|
||||||
return;
|
|
||||||
if (IndexFile *db = param.consumeFile(*fe)) {
|
|
||||||
auto [name, usr] = getMacro(tok);
|
auto [name, usr] = getMacro(tok);
|
||||||
IndexVar &var = db->toVar(usr);
|
IndexVar &var = db->toVar(usr);
|
||||||
Range range = fromTokenRange(sm, lang, {sl, sl}, nullptr);
|
Range range = fromTokenRange(sm, lang, {sl, sl}, nullptr);
|
||||||
@ -1128,15 +1127,12 @@ public:
|
|||||||
}
|
}
|
||||||
void MacroExpands(const Token &tok, const MacroDefinition &, SourceRange sr,
|
void MacroExpands(const Token &tok, const MacroDefinition &, SourceRange sr,
|
||||||
const MacroArgs *) override {
|
const MacroArgs *) override {
|
||||||
llvm::sys::fs::UniqueID uniqueID;
|
|
||||||
SourceLocation sl = sm.getSpellingLoc(sr.getBegin());
|
SourceLocation sl = sm.getSpellingLoc(sr.getBegin());
|
||||||
const FileEntry *fe = sm.getFileEntryForID(sm.getFileID(sl));
|
FileID fid = sm.getFileID(sl);
|
||||||
if (!fe)
|
if (IndexFile *db = param.consumeFile(fid)) {
|
||||||
return;
|
|
||||||
if (IndexFile *db = param.consumeFile(*fe)) {
|
|
||||||
IndexVar &var = db->toVar(getMacro(tok).second);
|
IndexVar &var = db->toVar(getMacro(tok).second);
|
||||||
var.uses.push_back(
|
var.uses.push_back(
|
||||||
{{fromTokenRange(sm, param.ctx->getLangOpts(), {sl, sl}, &uniqueID),
|
{{fromTokenRange(sm, param.ctx->getLangOpts(), {sl, sl}, nullptr),
|
||||||
Role::Dynamic}});
|
Role::Dynamic}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1150,8 +1146,9 @@ public:
|
|||||||
void SourceRangeSkipped(SourceRange sr, SourceLocation) override {
|
void SourceRangeSkipped(SourceRange sr, SourceLocation) override {
|
||||||
Range range = fromCharSourceRange(sm, param.ctx->getLangOpts(),
|
Range range = fromCharSourceRange(sm, param.ctx->getLangOpts(),
|
||||||
CharSourceRange::getCharRange(sr));
|
CharSourceRange::getCharRange(sr));
|
||||||
if (const FileEntry *fe = sm.getFileEntryForID(sm.getFileID(sr.getBegin())))
|
FileID fid = sm.getFileID(sr.getBegin());
|
||||||
if (IndexFile *db = param.consumeFile(*fe))
|
if (fid.isValid())
|
||||||
|
if (IndexFile *db = param.consumeFile(fid))
|
||||||
db->skipped_ranges.push_back(range);
|
db->skipped_ranges.push_back(range);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1321,7 +1318,8 @@ index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs,
|
|||||||
entry->import_file = main;
|
entry->import_file = main;
|
||||||
entry->args = args;
|
entry->args = args;
|
||||||
for (auto &[_, it] : entry->uid2lid_and_path)
|
for (auto &[_, it] : entry->uid2lid_and_path)
|
||||||
entry->lid2path.emplace_back(it.first, std::move(it.second));
|
if (it.first >= 0)
|
||||||
|
entry->lid2path.emplace_back(it.first, std::move(it.second));
|
||||||
entry->uid2lid_and_path.clear();
|
entry->uid2lid_and_path.clear();
|
||||||
for (auto &it : entry->usr2func) {
|
for (auto &it : entry->usr2func) {
|
||||||
// e.g. declaration + out-of-line definition
|
// e.g. declaration + out-of-line definition
|
||||||
@ -1341,6 +1339,8 @@ index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs,
|
|||||||
// Update dependencies for the file.
|
// Update dependencies for the file.
|
||||||
for (auto &[_, file] : param.uid2file) {
|
for (auto &[_, file] : param.uid2file) {
|
||||||
const std::string &path = file.path;
|
const std::string &path = file.path;
|
||||||
|
if (path.empty())
|
||||||
|
continue;
|
||||||
if (path == entry->path)
|
if (path == entry->path)
|
||||||
entry->mtime = file.mtime;
|
entry->mtime = file.mtime;
|
||||||
else if (path != entry->import_file)
|
else if (path != entry->import_file)
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "serializer.hh"
|
#include "serializer.hh"
|
||||||
#include "utils.hh"
|
#include "utils.hh"
|
||||||
|
|
||||||
#include <clang/Basic/FileManager.h>
|
#include <clang/Basic/SourceLocation.h>
|
||||||
#include <clang/Basic/Specifiers.h>
|
#include <clang/Basic/Specifiers.h>
|
||||||
#include <llvm/ADT/CachedHashString.h>
|
#include <llvm/ADT/CachedHashString.h>
|
||||||
#include <llvm/ADT/DenseMap.h>
|
#include <llvm/ADT/DenseMap.h>
|
||||||
@ -19,12 +19,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
template <> struct hash<llvm::sys::fs::UniqueID> {
|
template <> struct hash<clang::FileID> {
|
||||||
std::size_t operator()(llvm::sys::fs::UniqueID ID) const {
|
std::size_t operator()(clang::FileID fid) const { return fid.getHashValue(); }
|
||||||
size_t ret = ID.getDevice();
|
|
||||||
ccls::hash_combine(ret, ID.getFile());
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
} // namespace std
|
} // namespace std
|
||||||
|
|
||||||
@ -294,7 +290,7 @@ struct IndexFile {
|
|||||||
bool no_linkage;
|
bool no_linkage;
|
||||||
|
|
||||||
// uid2lid_and_path is used to generate lid2path, but not serialized.
|
// uid2lid_and_path is used to generate lid2path, but not serialized.
|
||||||
std::unordered_map<llvm::sys::fs::UniqueID, std::pair<int, std::string>>
|
std::unordered_map<clang::FileID, std::pair<int, std::string>>
|
||||||
uid2lid_and_path;
|
uid2lid_and_path;
|
||||||
std::vector<std::pair<int, std::string>> lid2path;
|
std::vector<std::pair<int, std::string>> lid2path;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user