mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-29 11:01:57 +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;
|
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;
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
199
src/indexer.cc
199
src/indexer.cc
@ -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 ¶m) : param(param) {}
|
IndexDataConsumer(IndexParam ¶m) : 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 ¶m;
|
IndexParam ¶m;
|
||||||
|
|
||||||
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 ¶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,
|
||||||
@ -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)
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user