mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-25 17:11:59 +00:00
indexer: llvm::sys::fs::UniqueID -> clang::FileID
This commit is contained in:
parent
459091af4f
commit
646aca5b7f
@ -25,11 +25,8 @@ limitations under the License.
|
||||
using namespace clang;
|
||||
|
||||
namespace ccls {
|
||||
std::string PathFromFileEntry(const FileEntry &file) {
|
||||
StringRef Name = file.tryGetRealPathName();
|
||||
if (Name.empty())
|
||||
Name = file.getName();
|
||||
std::string ret = NormalizePath(Name);
|
||||
std::string pathFromFileEntry(const FileEntry &file) {
|
||||
std::string ret = NormalizePath(file.getName());
|
||||
// Resolve symlinks outside of workspace folders, e.g. /usr/include/c++/7.3.0
|
||||
return NormalizeFolder(ret) ? ret : RealPath(ret);
|
||||
}
|
||||
@ -52,45 +49,33 @@ static Pos Decomposed2LineAndCol(const SourceManager &SM,
|
||||
(int16_t)std::min<int>(c, INT16_MAX)};
|
||||
}
|
||||
|
||||
Range FromCharSourceRange(const SourceManager &SM, const LangOptions &LangOpts,
|
||||
CharSourceRange R,
|
||||
llvm::sys::fs::UniqueID *UniqueID) {
|
||||
SourceLocation BLoc = R.getBegin(), ELoc = R.getEnd();
|
||||
std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(BLoc),
|
||||
EInfo = SM.getDecomposedLoc(ELoc);
|
||||
if (R.isTokenRange())
|
||||
EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, LangOpts);
|
||||
if (UniqueID) {
|
||||
if (const FileEntry *F = SM.getFileEntryForID(BInfo.first))
|
||||
*UniqueID = F->getUniqueID();
|
||||
else
|
||||
*UniqueID = llvm::sys::fs::UniqueID(0, 0);
|
||||
}
|
||||
return {Decomposed2LineAndCol(SM, BInfo), Decomposed2LineAndCol(SM, EInfo)};
|
||||
Range fromCharSourceRange(const SourceManager &sm, const LangOptions &lang,
|
||||
CharSourceRange csr, FileID *fid) {
|
||||
SourceLocation BLoc = csr.getBegin(), ELoc = csr.getEnd();
|
||||
std::pair<FileID, unsigned> BInfo = sm.getDecomposedLoc(BLoc),
|
||||
EInfo = sm.getDecomposedLoc(ELoc);
|
||||
if (csr.isTokenRange())
|
||||
EInfo.second += Lexer::MeasureTokenLength(ELoc, sm, lang);
|
||||
if (fid)
|
||||
*fid = BInfo.first;
|
||||
return {Decomposed2LineAndCol(sm, BInfo), Decomposed2LineAndCol(sm, EInfo)};
|
||||
}
|
||||
|
||||
Range FromCharRange(const SourceManager &SM, const LangOptions &Lang,
|
||||
SourceRange R, llvm::sys::fs::UniqueID *UniqueID) {
|
||||
return FromCharSourceRange(SM, Lang, CharSourceRange::getCharRange(R),
|
||||
UniqueID);
|
||||
Range fromTokenRange(const SourceManager &sm, const LangOptions &lang,
|
||||
SourceRange sr, FileID *fid) {
|
||||
return fromCharSourceRange(sm, lang, CharSourceRange::getTokenRange(sr), fid);
|
||||
}
|
||||
|
||||
Range FromTokenRange(const SourceManager &SM, const LangOptions &Lang,
|
||||
SourceRange R, llvm::sys::fs::UniqueID *UniqueID) {
|
||||
return FromCharSourceRange(SM, Lang, CharSourceRange::getTokenRange(R),
|
||||
UniqueID);
|
||||
}
|
||||
|
||||
Range FromTokenRangeDefaulted(const SourceManager &SM, const LangOptions &Lang,
|
||||
SourceRange R, const FileEntry *FE, Range range) {
|
||||
auto I = SM.getDecomposedLoc(SM.getExpansionLoc(R.getBegin()));
|
||||
if (SM.getFileEntryForID(I.first) == FE)
|
||||
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);
|
||||
Range fromTokenRangeDefaulted(const SourceManager &sm, const LangOptions &lang,
|
||||
SourceRange sr, FileID fid, Range range) {
|
||||
auto decomposed = sm.getDecomposedLoc(sm.getExpansionLoc(sr.getBegin()));
|
||||
if (decomposed.first == fid)
|
||||
range.start = Decomposed2LineAndCol(sm, decomposed);
|
||||
SourceLocation loc = sm.getExpansionLoc(sr.getEnd());
|
||||
decomposed = sm.getDecomposedLoc(loc);
|
||||
if (decomposed.first == fid) {
|
||||
decomposed.second += Lexer::MeasureTokenLength(loc, sm, lang);
|
||||
range.end = Decomposed2LineAndCol(sm, decomposed);
|
||||
}
|
||||
return range;
|
||||
}
|
||||
|
@ -30,24 +30,20 @@ namespace vfs = clang::vfs;
|
||||
#endif
|
||||
|
||||
namespace ccls {
|
||||
std::string PathFromFileEntry(const clang::FileEntry &file);
|
||||
std::string pathFromFileEntry(const clang::FileEntry &file);
|
||||
|
||||
Range FromCharSourceRange(const clang::SourceManager &SM,
|
||||
const clang::LangOptions &LangOpts,
|
||||
clang::CharSourceRange R,
|
||||
llvm::sys::fs::UniqueID *UniqueID = nullptr);
|
||||
Range fromCharSourceRange(const clang::SourceManager &sm,
|
||||
const clang::LangOptions &lang,
|
||||
clang::CharSourceRange csr,
|
||||
clang::FileID *fid = nullptr);
|
||||
|
||||
Range FromCharRange(const clang::SourceManager &SM,
|
||||
const clang::LangOptions &LangOpts, clang::SourceRange R,
|
||||
llvm::sys::fs::UniqueID *UniqueID = nullptr);
|
||||
Range fromTokenRange(const clang::SourceManager &sm,
|
||||
const clang::LangOptions &lang, clang::SourceRange sr,
|
||||
clang::FileID *fid = nullptr);
|
||||
|
||||
Range FromTokenRange(const clang::SourceManager &SM,
|
||||
const clang::LangOptions &LangOpts, clang::SourceRange R,
|
||||
llvm::sys::fs::UniqueID *UniqueID = nullptr);
|
||||
|
||||
Range FromTokenRangeDefaulted(const clang::SourceManager &SM,
|
||||
const clang::LangOptions &Lang,
|
||||
clang::SourceRange R, const clang::FileEntry *FE,
|
||||
Range fromTokenRangeDefaulted(const clang::SourceManager &sm,
|
||||
const clang::LangOptions &lang,
|
||||
clang::SourceRange sr, clang::FileID fid,
|
||||
Range range);
|
||||
|
||||
std::unique_ptr<clang::CompilerInvocation>
|
||||
|
199
src/indexer.cc
199
src/indexer.cc
@ -51,8 +51,8 @@ struct File {
|
||||
};
|
||||
|
||||
struct IndexParam {
|
||||
std::unordered_map<llvm::sys::fs::UniqueID, File> UID2File;
|
||||
std::unordered_map<llvm::sys::fs::UniqueID, bool> UID2multi;
|
||||
std::unordered_map<FileID, File> uid2file;
|
||||
std::unordered_map<FileID, bool> uid2multi;
|
||||
struct DeclInfo {
|
||||
Usr usr;
|
||||
std::string short_name;
|
||||
@ -61,18 +61,21 @@ struct IndexParam {
|
||||
std::unordered_map<const Decl *, DeclInfo> Decl2Info;
|
||||
|
||||
VFS &vfs;
|
||||
ASTContext *Ctx;
|
||||
ASTContext *ctx;
|
||||
bool 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
|
||||
// generating an index for it):
|
||||
auto [it, inserted] = UID2File.try_emplace(File.getUniqueID());
|
||||
auto [it, inserted] = uid2file.try_emplace(fid);
|
||||
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.mtime = File.getModificationTime();
|
||||
it->second.mtime = fe->getModificationTime();
|
||||
if (!it->second.mtime)
|
||||
if (auto tim = LastWriteTime(path))
|
||||
it->second.mtime = *tim;
|
||||
@ -86,15 +89,16 @@ struct IndexParam {
|
||||
}
|
||||
}
|
||||
|
||||
IndexFile *ConsumeFile(const FileEntry &FE) {
|
||||
SeenFile(FE);
|
||||
return UID2File[FE.getUniqueID()].db.get();
|
||||
IndexFile *consumeFile(FileID fid) {
|
||||
seenFile(fid);
|
||||
return uid2file[fid].db.get();
|
||||
}
|
||||
|
||||
bool UseMultiVersion(const FileEntry &FE) {
|
||||
auto it = UID2multi.try_emplace(FE.getUniqueID());
|
||||
bool useMultiVersion(FileID fid) {
|
||||
auto it = uid2multi.try_emplace(fid);
|
||||
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;
|
||||
}
|
||||
};
|
||||
@ -620,31 +624,31 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
static int GetFileLID(IndexFile *db, SourceManager &SM, const FileEntry &FE) {
|
||||
auto [it, inserted] = db->uid2lid_and_path.try_emplace(FE.getUniqueID());
|
||||
static int getFileLID(IndexFile *db, SourceManager &SM, FileID fid) {
|
||||
auto [it, inserted] = db->uid2lid_and_path.try_emplace(fid);
|
||||
if (inserted) {
|
||||
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))
|
||||
const FileEntry *fe = SM.getFileEntryForID(fid);
|
||||
if (!fe)
|
||||
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;
|
||||
}
|
||||
|
||||
void AddMacroUse(IndexFile *db, SourceManager &SM, Usr usr, Kind kind,
|
||||
SourceLocation Spell) const {
|
||||
const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Spell));
|
||||
if (!FE)
|
||||
return;
|
||||
int lid = GetFileLID(db, SM, *FE);
|
||||
void AddMacroUse(IndexFile *db, SourceManager &sm, Usr usr, Kind kind,
|
||||
SourceLocation sl) const {
|
||||
FileID fid = sm.getFileID(sl);
|
||||
int lid = getFileLID(db, sm, fid);
|
||||
if (lid < 0)
|
||||
return;
|
||||
Range spell =
|
||||
FromTokenRange(SM, Ctx->getLangOpts(), SourceRange(Spell, Spell));
|
||||
Range spell = fromTokenRange(sm, Ctx->getLangOpts(), SourceRange(sl, sl));
|
||||
Use use{{spell, Role::Dynamic}, lid};
|
||||
switch (kind) {
|
||||
case Kind::Func:
|
||||
@ -687,11 +691,7 @@ public:
|
||||
|
||||
public:
|
||||
IndexDataConsumer(IndexParam ¶m) : param(param) {}
|
||||
void initialize(ASTContext &Ctx) override {
|
||||
this->Ctx = param.Ctx = &Ctx;
|
||||
SourceManager &SM = Ctx.getSourceManager();
|
||||
(void)param.ConsumeFile(*SM.getFileEntryForID(SM.getMainFileID()));
|
||||
}
|
||||
void initialize(ASTContext &ctx) override { this->Ctx = param.ctx = &ctx; }
|
||||
bool handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles,
|
||||
ArrayRef<index::SymbolRelation> Relations,
|
||||
SourceLocation Loc, ASTNodeInfo ASTNode) override {
|
||||
@ -703,28 +703,26 @@ public:
|
||||
}
|
||||
SourceManager &SM = Ctx->getSourceManager();
|
||||
const LangOptions &Lang = Ctx->getLangOpts();
|
||||
FileID LocFID;
|
||||
FileID fid;
|
||||
SourceLocation Spell = SM.getSpellingLoc(Loc);
|
||||
const FileEntry *FE;
|
||||
Range loc;
|
||||
auto R = SM.isMacroArgExpansion(Loc) ? CharSourceRange::getTokenRange(Spell)
|
||||
: SM.getExpansionRange(Loc);
|
||||
loc = FromCharSourceRange(SM, Lang, R);
|
||||
LocFID = SM.getFileID(R.getBegin());
|
||||
FE = SM.getFileEntryForID(LocFID);
|
||||
if (!FE)
|
||||
loc = fromCharSourceRange(SM, Lang, R);
|
||||
fid = SM.getFileID(R.getBegin());
|
||||
if (fid.isInvalid())
|
||||
return true;
|
||||
int lid = -1;
|
||||
IndexFile *db;
|
||||
if (g_config->index.multiVersion && param.UseMultiVersion(*FE)) {
|
||||
db = param.ConsumeFile(*SM.getFileEntryForID(SM.getMainFileID()));
|
||||
if (g_config->index.multiVersion && param.useMultiVersion(fid)) {
|
||||
db = param.consumeFile(SM.getMainFileID());
|
||||
if (!db)
|
||||
return true;
|
||||
param.SeenFile(*FE);
|
||||
param.seenFile(fid);
|
||||
if (!SM.isWrittenInMainFile(R.getBegin()))
|
||||
lid = GetFileLID(db, SM, *FE);
|
||||
lid = getFileLID(db, SM, fid);
|
||||
} else {
|
||||
db = param.ConsumeFile(*FE);
|
||||
db = param.consumeFile(fid);
|
||||
if (!db)
|
||||
return true;
|
||||
}
|
||||
@ -765,7 +763,7 @@ public:
|
||||
SourceRange R =
|
||||
cast<FunctionDecl>(OrigD)->getNameInfo().getSourceRange();
|
||||
if (R.getEnd().isFileID())
|
||||
loc = FromTokenRange(SM, Lang, R);
|
||||
loc = fromTokenRange(SM, Lang, R);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -786,12 +784,12 @@ public:
|
||||
if (is_def) {
|
||||
SourceRange R = OrigD->getSourceRange();
|
||||
entity->def.spell = {use,
|
||||
FromTokenRangeDefaulted(SM, Lang, R, FE, loc)};
|
||||
fromTokenRangeDefaulted(SM, Lang, R, fid, loc)};
|
||||
GetKind(cast<Decl>(SemDC), entity->def.parent_kind);
|
||||
} else if (is_decl) {
|
||||
SourceRange R = OrigD->getSourceRange();
|
||||
entity->declarations.push_back(
|
||||
{use, FromTokenRangeDefaulted(SM, Lang, R, FE, loc)});
|
||||
{use, fromTokenRangeDefaulted(SM, Lang, R, fid, loc)});
|
||||
} else {
|
||||
entity->uses.push_back(use);
|
||||
return;
|
||||
@ -882,15 +880,15 @@ public:
|
||||
// e.g. TemplateTypeParmDecl is not handled by
|
||||
// handleDeclOccurence.
|
||||
SourceRange R1 = D1->getSourceRange();
|
||||
if (SM.getFileID(R1.getBegin()) == LocFID) {
|
||||
if (SM.getFileID(R1.getBegin()) == fid) {
|
||||
IndexParam::DeclInfo *info1;
|
||||
Usr usr1 = GetUsr(D1, &info1);
|
||||
IndexType &type1 = db->ToType(usr1);
|
||||
SourceLocation L1 = D1->getLocation();
|
||||
type1.def.spell = {
|
||||
Use{{FromTokenRange(SM, Lang, {L1, L1}), Role::Definition},
|
||||
Use{{fromTokenRange(SM, Lang, {L1, L1}), Role::Definition},
|
||||
lid},
|
||||
FromTokenRange(SM, Lang, R1)};
|
||||
fromTokenRange(SM, Lang, R1)};
|
||||
type1.def.detailed_name = Intern(info1->short_name);
|
||||
type1.def.short_name_size = int16_t(info1->short_name.size());
|
||||
type1.def.kind = SymbolKind::TypeParameter;
|
||||
@ -912,10 +910,10 @@ public:
|
||||
} else if (!var->def.spell && var->declarations.empty()) {
|
||||
// e.g. lambda parameter
|
||||
SourceLocation L = D->getLocation();
|
||||
if (SM.getFileID(L) == LocFID) {
|
||||
if (SM.getFileID(L) == fid) {
|
||||
var->def.spell = {
|
||||
Use{{FromTokenRange(SM, Lang, {L, L}), Role::Definition}, lid},
|
||||
FromTokenRange(SM, Lang, D->getSourceRange())};
|
||||
Use{{fromTokenRange(SM, Lang, {L, L}), Role::Definition}, lid},
|
||||
fromTokenRange(SM, Lang, D->getSourceRange())};
|
||||
var->def.parent_kind = SymbolKind::Method;
|
||||
}
|
||||
}
|
||||
@ -1026,9 +1024,9 @@ public:
|
||||
if (specialization) {
|
||||
const TypeSourceInfo *TSI = TD->getTypeSourceInfo();
|
||||
SourceLocation L1 = TSI->getTypeLoc().getBeginLoc();
|
||||
if (SM.getFileID(L1) == LocFID)
|
||||
if (SM.getFileID(L1) == fid)
|
||||
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 {
|
||||
SourceManager &SM;
|
||||
SourceManager &sm;
|
||||
IndexParam ¶m;
|
||||
|
||||
std::pair<StringRef, Usr> GetMacro(const Token &Tok) const {
|
||||
@ -1076,7 +1074,12 @@ class IndexPPCallbacks : public PPCallbacks {
|
||||
|
||||
public:
|
||||
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,
|
||||
StringRef Included, bool IsAngled,
|
||||
CharSourceRange FilenameRange, const FileEntry *File,
|
||||
@ -1085,76 +1088,66 @@ public:
|
||||
SrcMgr::CharacteristicKind FileType) override {
|
||||
if (!File)
|
||||
return;
|
||||
llvm::sys::fs::UniqueID UniqueID;
|
||||
auto spell = FromCharSourceRange(SM, param.Ctx->getLangOpts(),
|
||||
FilenameRange, &UniqueID);
|
||||
const FileEntry *FE =
|
||||
SM.getFileEntryForID(SM.getFileID(FilenameRange.getBegin()));
|
||||
if (!FE)
|
||||
return;
|
||||
if (IndexFile *db = param.ConsumeFile(*FE)) {
|
||||
std::string path = PathFromFileEntry(*File);
|
||||
auto spell = fromCharSourceRange(sm, param.ctx->getLangOpts(),
|
||||
FilenameRange, nullptr);
|
||||
FileID fid = sm.getFileID(FilenameRange.getBegin());
|
||||
if (IndexFile *db = param.consumeFile(fid)) {
|
||||
std::string path = pathFromFileEntry(*File);
|
||||
if (path.size())
|
||||
db->includes.push_back({spell.start.line, Intern(path)});
|
||||
}
|
||||
}
|
||||
void MacroDefined(const Token &Tok, const MacroDirective *MD) override {
|
||||
llvm::sys::fs::UniqueID UniqueID;
|
||||
const LangOptions &Lang = param.Ctx->getLangOpts();
|
||||
SourceLocation L = MD->getLocation();
|
||||
const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(L));
|
||||
if (!FE)
|
||||
return;
|
||||
if (IndexFile *db = param.ConsumeFile(*FE)) {
|
||||
const LangOptions &lang = param.ctx->getLangOpts();
|
||||
SourceLocation sl = MD->getLocation();
|
||||
FileID fid = sm.getFileID(sl);
|
||||
if (IndexFile *db = param.consumeFile(fid)) {
|
||||
auto [Name, usr] = GetMacro(Tok);
|
||||
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.parent_kind = SymbolKind::File;
|
||||
if (var.def.spell)
|
||||
var.declarations.push_back(*var.def.spell);
|
||||
const MacroInfo *MI = MD->getMacroInfo();
|
||||
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};
|
||||
if (var.def.detailed_name[0] == '\0') {
|
||||
var.def.detailed_name = Intern(Name);
|
||||
var.def.short_name_size = Name.size();
|
||||
StringRef Buf = GetSourceInRange(SM, Lang, R);
|
||||
StringRef Buf = GetSourceInRange(sm, lang, R);
|
||||
var.def.hover =
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
void MacroExpands(const Token &Tok, const MacroDefinition &MD, SourceRange R,
|
||||
const MacroArgs *Args) override {
|
||||
llvm::sys::fs::UniqueID UniqueID;
|
||||
SourceLocation L = SM.getSpellingLoc(R.getBegin());
|
||||
const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(L));
|
||||
if (!FE)
|
||||
return;
|
||||
if (IndexFile *db = param.ConsumeFile(*FE)) {
|
||||
IndexVar &var = db->ToVar(GetMacro(Tok).second);
|
||||
void MacroExpands(const Token &tok, const MacroDefinition &, SourceRange sr,
|
||||
const MacroArgs *) override {
|
||||
SourceLocation sl = sm.getSpellingLoc(sr.getBegin());
|
||||
FileID fid = sm.getFileID(sl);
|
||||
if (IndexFile *db = param.consumeFile(fid)) {
|
||||
IndexVar &var = db->ToVar(GetMacro(tok).second);
|
||||
var.uses.push_back(
|
||||
{{FromTokenRange(SM, param.Ctx->getLangOpts(), {L, L}, &UniqueID),
|
||||
{{fromTokenRange(sm, param.ctx->getLangOpts(), {sl, sl}, nullptr),
|
||||
Role::Dynamic}});
|
||||
}
|
||||
}
|
||||
void MacroUndefined(const Token &Tok, const MacroDefinition &MD,
|
||||
const MacroDirective *UD) override {
|
||||
if (UD) {
|
||||
SourceLocation L = UD->getLocation();
|
||||
MacroExpands(Tok, MD, {L, L}, nullptr);
|
||||
void MacroUndefined(const Token &tok, const MacroDefinition &md,
|
||||
const MacroDirective *ud) override {
|
||||
if (ud) {
|
||||
SourceLocation sl = ud->getLocation();
|
||||
MacroExpands(tok, md, {sl, sl}, nullptr);
|
||||
}
|
||||
}
|
||||
void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override {
|
||||
llvm::sys::fs::UniqueID UniqueID;
|
||||
auto range = FromCharRange(SM, param.Ctx->getLangOpts(), Range, &UniqueID);
|
||||
if (const FileEntry *FE =
|
||||
SM.getFileEntryForID(SM.getFileID(Range.getBegin())))
|
||||
if (IndexFile *db = param.ConsumeFile(*FE))
|
||||
void SourceRangeSkipped(SourceRange r, SourceLocation EndifLoc) override {
|
||||
Range range = fromCharSourceRange(sm, param.ctx->getLangOpts(),
|
||||
CharSourceRange::getCharRange(r));
|
||||
FileID fid = sm.getFileID(r.getBegin());
|
||||
if (fid.isValid())
|
||||
if (IndexFile *db = param.consumeFile(fid))
|
||||
db->skipped_ranges.push_back(range);
|
||||
}
|
||||
};
|
||||
@ -1315,7 +1308,7 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs,
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<IndexFile>> result;
|
||||
for (auto &it : param.UID2File) {
|
||||
for (auto &it : param.uid2file) {
|
||||
if (!it.second.db)
|
||||
continue;
|
||||
std::unique_ptr<IndexFile> &entry = it.second.db;
|
||||
@ -1340,8 +1333,10 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs,
|
||||
Uniquify(it.second.uses);
|
||||
|
||||
// Update dependencies for the file.
|
||||
for (auto &[_, file] : param.UID2File) {
|
||||
for (auto &[_, file] : param.uid2file) {
|
||||
const std::string &path = file.path;
|
||||
if (path.empty())
|
||||
continue;
|
||||
if (path == entry->path)
|
||||
entry->mtime = file.mtime;
|
||||
else if (path != entry->import_file)
|
||||
|
@ -20,7 +20,7 @@ limitations under the License.
|
||||
#include "serializer.hh"
|
||||
#include "utils.hh"
|
||||
|
||||
#include <clang/Basic/FileManager.h>
|
||||
#include <clang/Basic/SourceLocation.h>
|
||||
#include <clang/Basic/Specifiers.h>
|
||||
#include <llvm/ADT/CachedHashString.h>
|
||||
#include <llvm/ADT/DenseMap.h>
|
||||
@ -31,11 +31,9 @@ limitations under the License.
|
||||
#include <vector>
|
||||
|
||||
namespace std {
|
||||
template <> struct hash<llvm::sys::fs::UniqueID> {
|
||||
std::size_t operator()(llvm::sys::fs::UniqueID ID) const {
|
||||
size_t ret = ID.getDevice();
|
||||
ccls::hash_combine(ret, ID.getFile());
|
||||
return ret;
|
||||
template <> struct hash<clang::FileID> {
|
||||
std::size_t operator()(clang::FileID fid) const {
|
||||
return fid.getHashValue();
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
@ -307,7 +305,7 @@ struct IndexFile {
|
||||
bool no_linkage;
|
||||
|
||||
// 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;
|
||||
std::vector<std::pair<int, std::string>> lid2path;
|
||||
|
||||
|
@ -76,7 +76,7 @@ TextEdit ToTextEdit(const clang::SourceManager &SM, const clang::LangOptions &L,
|
||||
const clang::FixItHint &FixIt) {
|
||||
TextEdit edit;
|
||||
edit.newText = FixIt.CodeToInsert;
|
||||
auto r = FromCharSourceRange(SM, L, FixIt.RemoveRange);
|
||||
auto r = fromCharSourceRange(SM, L, FixIt.RemoveRange);
|
||||
edit.range =
|
||||
lsRange{{r.start.line, r.start.column}, {r.end.line, r.end.column}};
|
||||
return edit;
|
||||
@ -194,7 +194,7 @@ public:
|
||||
SrcMgr::CharacteristicKind FileKind) override {
|
||||
(void)SM;
|
||||
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());
|
||||
if (it.second) {
|
||||
const FileEntry *FE = SM.getFileEntryForID(FID);
|
||||
it.first->second = FE && PathFromFileEntry(*FE) == path;
|
||||
it.first->second = FE && pathFromFileEntry(*FE) == path;
|
||||
}
|
||||
return it.first->second;
|
||||
}
|
||||
@ -260,7 +260,7 @@ public:
|
||||
llvm::SmallString<64> Message;
|
||||
Info.FormatDiagnostic(Message);
|
||||
d.range =
|
||||
FromCharSourceRange(SM, *LangOpts, DiagnosticRange(Info, *LangOpts));
|
||||
fromCharSourceRange(SM, *LangOpts, DiagnosticRange(Info, *LangOpts));
|
||||
d.message = Message.str();
|
||||
d.concerned = concerned;
|
||||
d.file = Filename;
|
||||
|
Loading…
Reference in New Issue
Block a user