indexer: llvm::sys::fs::UniqueID -> clang::FileID

This commit is contained in:
Fangrui Song 2019-08-21 23:46:02 -07:00
parent 459091af4f
commit 646aca5b7f
5 changed files with 142 additions and 168 deletions

View File

@ -25,11 +25,8 @@ limitations under the License.
using namespace clang; using namespace clang;
namespace ccls { namespace ccls {
std::string PathFromFileEntry(const FileEntry &file) { std::string pathFromFileEntry(const FileEntry &file) {
StringRef Name = file.tryGetRealPathName(); std::string ret = NormalizePath(file.getName());
if (Name.empty())
Name = file.getName();
std::string ret = NormalizePath(Name);
// Resolve symlinks outside of workspace folders, e.g. /usr/include/c++/7.3.0 // Resolve symlinks outside of workspace folders, e.g. /usr/include/c++/7.3.0
return NormalizeFolder(ret) ? ret : RealPath(ret); return NormalizeFolder(ret) ? ret : RealPath(ret);
} }
@ -52,45 +49,33 @@ static Pos Decomposed2LineAndCol(const SourceManager &SM,
(int16_t)std::min<int>(c, INT16_MAX)}; (int16_t)std::min<int>(c, INT16_MAX)};
} }
Range FromCharSourceRange(const SourceManager &SM, const LangOptions &LangOpts, Range fromCharSourceRange(const SourceManager &sm, const LangOptions &lang,
CharSourceRange R, CharSourceRange csr, FileID *fid) {
llvm::sys::fs::UniqueID *UniqueID) { SourceLocation BLoc = csr.getBegin(), ELoc = csr.getEnd();
SourceLocation BLoc = R.getBegin(), ELoc = R.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 (R.isTokenRange()) EInfo.second += Lexer::MeasureTokenLength(ELoc, sm, lang);
EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, LangOpts); if (fid)
if (UniqueID) { *fid = BInfo.first;
if (const FileEntry *F = SM.getFileEntryForID(BInfo.first)) return {Decomposed2LineAndCol(sm, BInfo), Decomposed2LineAndCol(sm, EInfo)};
*UniqueID = F->getUniqueID();
else
*UniqueID = llvm::sys::fs::UniqueID(0, 0);
}
return {Decomposed2LineAndCol(SM, BInfo), Decomposed2LineAndCol(SM, EInfo)};
} }
Range FromCharRange(const SourceManager &SM, const LangOptions &Lang, Range fromTokenRange(const SourceManager &sm, const LangOptions &lang,
SourceRange R, llvm::sys::fs::UniqueID *UniqueID) { SourceRange sr, FileID *fid) {
return FromCharSourceRange(SM, Lang, CharSourceRange::getCharRange(R), return fromCharSourceRange(sm, lang, CharSourceRange::getTokenRange(sr), fid);
UniqueID);
} }
Range FromTokenRange(const SourceManager &SM, const LangOptions &Lang, Range fromTokenRangeDefaulted(const SourceManager &sm, const LangOptions &lang,
SourceRange R, llvm::sys::fs::UniqueID *UniqueID) { SourceRange sr, FileID fid, Range range) {
return FromCharSourceRange(SM, Lang, CharSourceRange::getTokenRange(R), auto decomposed = sm.getDecomposedLoc(sm.getExpansionLoc(sr.getBegin()));
UniqueID); if (decomposed.first == fid)
} range.start = Decomposed2LineAndCol(sm, decomposed);
SourceLocation loc = sm.getExpansionLoc(sr.getEnd());
Range FromTokenRangeDefaulted(const SourceManager &SM, const LangOptions &Lang, decomposed = sm.getDecomposedLoc(loc);
SourceRange R, const FileEntry *FE, Range range) { if (decomposed.first == fid) {
auto I = SM.getDecomposedLoc(SM.getExpansionLoc(R.getBegin())); decomposed.second += Lexer::MeasureTokenLength(loc, sm, lang);
if (SM.getFileEntryForID(I.first) == FE) range.end = Decomposed2LineAndCol(sm, decomposed);
range.start = Decomposed2LineAndCol(SM, I);
SourceLocation L = SM.getExpansionLoc(R.getEnd());
I = SM.getDecomposedLoc(L);
if (SM.getFileEntryForID(I.first) == FE) {
I.second += Lexer::MeasureTokenLength(L, SM, Lang);
range.end = Decomposed2LineAndCol(SM, I);
} }
return range; return range;
} }

View File

@ -30,24 +30,20 @@ namespace vfs = clang::vfs;
#endif #endif
namespace ccls { namespace ccls {
std::string PathFromFileEntry(const clang::FileEntry &file); std::string pathFromFileEntry(const clang::FileEntry &file);
Range FromCharSourceRange(const clang::SourceManager &SM, Range fromCharSourceRange(const clang::SourceManager &sm,
const clang::LangOptions &LangOpts, const clang::LangOptions &lang,
clang::CharSourceRange R, clang::CharSourceRange csr,
llvm::sys::fs::UniqueID *UniqueID = nullptr); clang::FileID *fid = nullptr);
Range FromCharRange(const clang::SourceManager &SM, Range fromTokenRange(const clang::SourceManager &sm,
const clang::LangOptions &LangOpts, clang::SourceRange R, const clang::LangOptions &lang, clang::SourceRange sr,
llvm::sys::fs::UniqueID *UniqueID = nullptr); clang::FileID *fid = nullptr);
Range FromTokenRange(const clang::SourceManager &SM, Range fromTokenRangeDefaulted(const clang::SourceManager &sm,
const clang::LangOptions &LangOpts, clang::SourceRange R, const clang::LangOptions &lang,
llvm::sys::fs::UniqueID *UniqueID = nullptr); clang::SourceRange sr, clang::FileID fid,
Range FromTokenRangeDefaulted(const clang::SourceManager &SM,
const clang::LangOptions &Lang,
clang::SourceRange R, const clang::FileEntry *FE,
Range range); Range range);
std::unique_ptr<clang::CompilerInvocation> std::unique_ptr<clang::CompilerInvocation>

View File

@ -51,8 +51,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;
@ -61,18 +61,21 @@ struct IndexParam {
std::unordered_map<const Decl *, DeclInfo> Decl2Info; std::unordered_map<const Decl *, DeclInfo> Decl2Info;
VFS &vfs; VFS &vfs;
ASTContext *Ctx; ASTContext *ctx;
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;
@ -86,15 +89,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;
} }
}; };
@ -620,31 +624,31 @@ 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())
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;
SmallString<256> path = fe->tryGetRealPathName();
if (path.empty())
path = fe->getName();
if (!llvm::sys::path::is_absolute(path) &&
!SM.getFileManager().makeAbsolutePath(path))
return -1;
it->second.second = llvm::sys::path::convert_to_slash(path.str());
} }
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 Spell) const { SourceLocation sl) const {
const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Spell)); 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 = Range spell = fromTokenRange(sm, Ctx->getLangOpts(), SourceRange(sl, sl));
FromTokenRange(SM, Ctx->getLangOpts(), SourceRange(Spell, Spell));
Use use{{spell, Role::Dynamic}, lid}; Use use{{spell, Role::Dynamic}, lid};
switch (kind) { switch (kind) {
case Kind::Func: case Kind::Func:
@ -687,11 +691,7 @@ public:
public: public:
IndexDataConsumer(IndexParam &param) : param(param) {} IndexDataConsumer(IndexParam &param) : param(param) {}
void initialize(ASTContext &Ctx) override { void initialize(ASTContext &ctx) override { this->Ctx = param.ctx = &ctx; }
this->Ctx = param.Ctx = &Ctx;
SourceManager &SM = Ctx.getSourceManager();
(void)param.ConsumeFile(*SM.getFileEntryForID(SM.getMainFileID()));
}
bool handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles, bool handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles,
ArrayRef<index::SymbolRelation> Relations, ArrayRef<index::SymbolRelation> Relations,
SourceLocation Loc, ASTNodeInfo ASTNode) override { SourceLocation Loc, ASTNodeInfo ASTNode) override {
@ -703,28 +703,26 @@ public:
} }
SourceManager &SM = Ctx->getSourceManager(); SourceManager &SM = Ctx->getSourceManager();
const LangOptions &Lang = Ctx->getLangOpts(); const LangOptions &Lang = Ctx->getLangOpts();
FileID LocFID; FileID fid;
SourceLocation Spell = SM.getSpellingLoc(Loc); SourceLocation Spell = SM.getSpellingLoc(Loc);
const FileEntry *FE;
Range loc; Range loc;
auto R = SM.isMacroArgExpansion(Loc) ? CharSourceRange::getTokenRange(Spell) auto R = SM.isMacroArgExpansion(Loc) ? CharSourceRange::getTokenRange(Spell)
: SM.getExpansionRange(Loc); : SM.getExpansionRange(Loc);
loc = FromCharSourceRange(SM, Lang, R); loc = fromCharSourceRange(SM, Lang, R);
LocFID = SM.getFileID(R.getBegin()); fid = SM.getFileID(R.getBegin());
FE = SM.getFileEntryForID(LocFID); 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;
} }
@ -765,7 +763,7 @@ public:
SourceRange R = SourceRange R =
cast<FunctionDecl>(OrigD)->getNameInfo().getSourceRange(); cast<FunctionDecl>(OrigD)->getNameInfo().getSourceRange();
if (R.getEnd().isFileID()) if (R.getEnd().isFileID())
loc = FromTokenRange(SM, Lang, R); loc = fromTokenRange(SM, Lang, R);
} }
break; break;
default: default:
@ -786,12 +784,12 @@ public:
if (is_def) { if (is_def) {
SourceRange R = OrigD->getSourceRange(); SourceRange R = OrigD->getSourceRange();
entity->def.spell = {use, entity->def.spell = {use,
FromTokenRangeDefaulted(SM, Lang, R, FE, loc)}; fromTokenRangeDefaulted(SM, Lang, R, fid, loc)};
GetKind(cast<Decl>(SemDC), entity->def.parent_kind); GetKind(cast<Decl>(SemDC), entity->def.parent_kind);
} else if (is_decl) { } else if (is_decl) {
SourceRange R = OrigD->getSourceRange(); SourceRange R = OrigD->getSourceRange();
entity->declarations.push_back( entity->declarations.push_back(
{use, FromTokenRangeDefaulted(SM, Lang, R, FE, loc)}); {use, fromTokenRangeDefaulted(SM, Lang, R, fid, loc)});
} else { } else {
entity->uses.push_back(use); entity->uses.push_back(use);
return; return;
@ -882,15 +880,15 @@ public:
// e.g. TemplateTypeParmDecl is not handled by // e.g. TemplateTypeParmDecl is not handled by
// handleDeclOccurence. // handleDeclOccurence.
SourceRange R1 = D1->getSourceRange(); SourceRange R1 = D1->getSourceRange();
if (SM.getFileID(R1.getBegin()) == LocFID) { if (SM.getFileID(R1.getBegin()) == fid) {
IndexParam::DeclInfo *info1; IndexParam::DeclInfo *info1;
Usr usr1 = GetUsr(D1, &info1); Usr usr1 = GetUsr(D1, &info1);
IndexType &type1 = db->ToType(usr1); IndexType &type1 = db->ToType(usr1);
SourceLocation L1 = D1->getLocation(); SourceLocation L1 = D1->getLocation();
type1.def.spell = { type1.def.spell = {
Use{{FromTokenRange(SM, Lang, {L1, L1}), Role::Definition}, Use{{fromTokenRange(SM, Lang, {L1, L1}), Role::Definition},
lid}, lid},
FromTokenRange(SM, Lang, R1)}; fromTokenRange(SM, Lang, R1)};
type1.def.detailed_name = Intern(info1->short_name); type1.def.detailed_name = Intern(info1->short_name);
type1.def.short_name_size = int16_t(info1->short_name.size()); type1.def.short_name_size = int16_t(info1->short_name.size());
type1.def.kind = SymbolKind::TypeParameter; type1.def.kind = SymbolKind::TypeParameter;
@ -912,10 +910,10 @@ public:
} else if (!var->def.spell && var->declarations.empty()) { } else if (!var->def.spell && var->declarations.empty()) {
// e.g. lambda parameter // e.g. lambda parameter
SourceLocation L = D->getLocation(); SourceLocation L = D->getLocation();
if (SM.getFileID(L) == LocFID) { if (SM.getFileID(L) == fid) {
var->def.spell = { var->def.spell = {
Use{{FromTokenRange(SM, Lang, {L, L}), Role::Definition}, lid}, Use{{fromTokenRange(SM, Lang, {L, L}), Role::Definition}, lid},
FromTokenRange(SM, Lang, D->getSourceRange())}; fromTokenRange(SM, Lang, D->getSourceRange())};
var->def.parent_kind = SymbolKind::Method; var->def.parent_kind = SymbolKind::Method;
} }
} }
@ -1026,9 +1024,9 @@ public:
if (specialization) { if (specialization) {
const TypeSourceInfo *TSI = TD->getTypeSourceInfo(); const TypeSourceInfo *TSI = TD->getTypeSourceInfo();
SourceLocation L1 = TSI->getTypeLoc().getBeginLoc(); SourceLocation L1 = TSI->getTypeLoc().getBeginLoc();
if (SM.getFileID(L1) == LocFID) if (SM.getFileID(L1) == fid)
type1.uses.push_back( type1.uses.push_back(
{{FromTokenRange(SM, Lang, {L1, L1}), Role::Reference}, lid}); {{fromTokenRange(SM, Lang, {L1, L1}), Role::Reference}, lid});
} }
} }
} }
@ -1064,7 +1062,7 @@ public:
}; };
class IndexPPCallbacks : public PPCallbacks { class IndexPPCallbacks : public PPCallbacks {
SourceManager &SM; SourceManager &sm;
IndexParam &param; IndexParam &param;
std::pair<StringRef, Usr> GetMacro(const Token &Tok) const { std::pair<StringRef, Usr> GetMacro(const Token &Tok) const {
@ -1076,7 +1074,12 @@ class IndexPPCallbacks : public PPCallbacks {
public: public:
IndexPPCallbacks(SourceManager &SM, IndexParam &param) IndexPPCallbacks(SourceManager &SM, IndexParam &param)
: 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,
@ -1085,76 +1088,66 @@ public:
SrcMgr::CharacteristicKind FileType) override { SrcMgr::CharacteristicKind FileType) override {
if (!File) if (!File)
return; return;
llvm::sys::fs::UniqueID UniqueID; auto spell = fromCharSourceRange(sm, param.ctx->getLangOpts(),
auto spell = FromCharSourceRange(SM, param.Ctx->getLangOpts(), FilenameRange, nullptr);
FilenameRange, &UniqueID); FileID fid = sm.getFileID(FilenameRange.getBegin());
const FileEntry *FE = if (IndexFile *db = param.consumeFile(fid)) {
SM.getFileEntryForID(SM.getFileID(FilenameRange.getBegin())); std::string path = pathFromFileEntry(*File);
if (!FE)
return;
if (IndexFile *db = param.ConsumeFile(*FE)) {
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)});
} }
} }
void MacroDefined(const Token &Tok, const MacroDirective *MD) override { void MacroDefined(const Token &Tok, const MacroDirective *MD) override {
llvm::sys::fs::UniqueID UniqueID; const LangOptions &lang = param.ctx->getLangOpts();
const LangOptions &Lang = param.Ctx->getLangOpts(); SourceLocation sl = MD->getLocation();
SourceLocation L = MD->getLocation(); FileID fid = sm.getFileID(sl);
const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(L)); if (IndexFile *db = param.consumeFile(fid)) {
if (!FE)
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, {L, L}, &UniqueID); Range range = fromTokenRange(sm, lang, {sl, sl}, nullptr);
var.def.kind = SymbolKind::Macro; var.def.kind = SymbolKind::Macro;
var.def.parent_kind = SymbolKind::File; var.def.parent_kind = SymbolKind::File;
if (var.def.spell) if (var.def.spell)
var.declarations.push_back(*var.def.spell); var.declarations.push_back(*var.def.spell);
const MacroInfo *MI = MD->getMacroInfo(); const MacroInfo *MI = MD->getMacroInfo();
SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc()); SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc());
Range extent = FromTokenRange(SM, param.Ctx->getLangOpts(), R); Range extent = fromTokenRange(sm, param.ctx->getLangOpts(), R);
var.def.spell = {Use{{range, Role::Definition}}, extent}; var.def.spell = {Use{{range, Role::Definition}}, extent};
if (var.def.detailed_name[0] == '\0') { if (var.def.detailed_name[0] == '\0') {
var.def.detailed_name = Intern(Name); var.def.detailed_name = Intern(Name);
var.def.short_name_size = Name.size(); var.def.short_name_size = Name.size();
StringRef Buf = GetSourceInRange(SM, Lang, R); StringRef Buf = GetSourceInRange(sm, lang, R);
var.def.hover = var.def.hover =
Intern(Buf.count('\n') <= g_config->index.maxInitializerLines - 1 Intern(Buf.count('\n') <= g_config->index.maxInitializerLines - 1
? Twine("#define ", GetSourceInRange(SM, Lang, R)).str() ? Twine("#define ", GetSourceInRange(sm, lang, R)).str()
: Twine("#define ", Name).str()); : Twine("#define ", Name).str());
} }
} }
} }
void MacroExpands(const Token &Tok, const MacroDefinition &MD, SourceRange R, void MacroExpands(const Token &tok, const MacroDefinition &, SourceRange sr,
const MacroArgs *Args) override { const MacroArgs *) override {
llvm::sys::fs::UniqueID UniqueID; SourceLocation sl = sm.getSpellingLoc(sr.getBegin());
SourceLocation L = SM.getSpellingLoc(R.getBegin()); FileID fid = sm.getFileID(sl);
const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(L)); if (IndexFile *db = param.consumeFile(fid)) {
if (!FE) IndexVar &var = db->ToVar(GetMacro(tok).second);
return;
if (IndexFile *db = param.ConsumeFile(*FE)) {
IndexVar &var = db->ToVar(GetMacro(Tok).second);
var.uses.push_back( var.uses.push_back(
{{FromTokenRange(SM, param.Ctx->getLangOpts(), {L, L}, &UniqueID), {{fromTokenRange(sm, param.ctx->getLangOpts(), {sl, sl}, nullptr),
Role::Dynamic}}); Role::Dynamic}});
} }
} }
void MacroUndefined(const Token &Tok, const MacroDefinition &MD, void MacroUndefined(const Token &tok, const MacroDefinition &md,
const MacroDirective *UD) override { const MacroDirective *ud) override {
if (UD) { if (ud) {
SourceLocation L = UD->getLocation(); SourceLocation sl = ud->getLocation();
MacroExpands(Tok, MD, {L, L}, nullptr); MacroExpands(tok, md, {sl, sl}, nullptr);
} }
} }
void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override { void SourceRangeSkipped(SourceRange r, SourceLocation EndifLoc) override {
llvm::sys::fs::UniqueID UniqueID; Range range = fromCharSourceRange(sm, param.ctx->getLangOpts(),
auto range = FromCharRange(SM, param.Ctx->getLangOpts(), Range, &UniqueID); CharSourceRange::getCharRange(r));
if (const FileEntry *FE = FileID fid = sm.getFileID(r.getBegin());
SM.getFileEntryForID(SM.getFileID(Range.getBegin()))) if (fid.isValid())
if (IndexFile *db = param.ConsumeFile(*FE)) if (IndexFile *db = param.consumeFile(fid))
db->skipped_ranges.push_back(range); db->skipped_ranges.push_back(range);
} }
}; };
@ -1315,7 +1308,7 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs,
} }
std::vector<std::unique_ptr<IndexFile>> result; std::vector<std::unique_ptr<IndexFile>> result;
for (auto &it : param.UID2File) { for (auto &it : param.uid2file) {
if (!it.second.db) if (!it.second.db)
continue; continue;
std::unique_ptr<IndexFile> &entry = it.second.db; std::unique_ptr<IndexFile> &entry = it.second.db;
@ -1340,8 +1333,10 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs,
Uniquify(it.second.uses); Uniquify(it.second.uses);
// 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)

View File

@ -20,7 +20,7 @@ limitations under the License.
#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>
@ -31,11 +31,9 @@ limitations under the License.
#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 {
size_t ret = ID.getDevice(); return fid.getHashValue();
ccls::hash_combine(ret, ID.getFile());
return ret;
} }
}; };
} // namespace std } // namespace std
@ -307,7 +305,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;

View File

@ -76,7 +76,7 @@ TextEdit ToTextEdit(const clang::SourceManager &SM, const clang::LangOptions &L,
const clang::FixItHint &FixIt) { const clang::FixItHint &FixIt) {
TextEdit edit; TextEdit edit;
edit.newText = FixIt.CodeToInsert; edit.newText = FixIt.CodeToInsert;
auto r = FromCharSourceRange(SM, L, FixIt.RemoveRange); auto r = fromCharSourceRange(SM, L, FixIt.RemoveRange);
edit.range = edit.range =
lsRange{{r.start.line, r.start.column}, {r.end.line, r.end.column}}; lsRange{{r.start.line, r.start.column}, {r.end.line, r.end.column}};
return edit; return edit;
@ -194,7 +194,7 @@ public:
SrcMgr::CharacteristicKind FileKind) override { SrcMgr::CharacteristicKind FileKind) override {
(void)SM; (void)SM;
if (File && Seen.insert(File).second) if (File && Seen.insert(File).second)
out.emplace_back(PathFromFileEntry(*File), File->getModificationTime()); out.emplace_back(pathFromFileEntry(*File), File->getModificationTime());
} }
}; };
@ -238,7 +238,7 @@ public:
auto it = FID2concerned.try_emplace(FID.getHashValue()); auto it = FID2concerned.try_emplace(FID.getHashValue());
if (it.second) { if (it.second) {
const FileEntry *FE = SM.getFileEntryForID(FID); const FileEntry *FE = SM.getFileEntryForID(FID);
it.first->second = FE && PathFromFileEntry(*FE) == path; it.first->second = FE && pathFromFileEntry(*FE) == path;
} }
return it.first->second; return it.first->second;
} }
@ -260,7 +260,7 @@ public:
llvm::SmallString<64> Message; llvm::SmallString<64> Message;
Info.FormatDiagnostic(Message); Info.FormatDiagnostic(Message);
d.range = d.range =
FromCharSourceRange(SM, *LangOpts, DiagnosticRange(Info, *LangOpts)); fromCharSourceRange(SM, *LangOpts, DiagnosticRange(Info, *LangOpts));
d.message = Message.str(); d.message = Message.str();
d.concerned = concerned; d.concerned = concerned;
d.file = Filename; d.file = Filename;