Browse Source

building

pull/2/head
Jacob Dufault 8 years ago
parent
commit
18aa28bdea
  1. 3
      .gitignore
  2. 41
      indexer.cpp
  3. 105
      indexer.h
  4. 46
      query.cc
  5. 72
      query.h
  6. 1
      wscript

3
.gitignore

@ -1,6 +1,9 @@
.vs
Debug
x64
build
waf-*
.lock-waf*
*.swp
*.sln
*.vcxproj

41
indexer.cpp

@ -2,8 +2,8 @@
#include "serializer.h"
IndexedFile::IndexedFile(IdCache* id_cache, FileDb* file_db)
: id_cache(id_cache), file_db(file_db) {
IndexedFile::IndexedFile(IdCache* id_cache)
: id_cache(id_cache) {
// TODO: Reconsider if we should still be reusing the same id_cache.
// Preallocate any existing resolved ids.
@ -322,7 +322,7 @@ void VisitDeclForTypeUsageVisitorHandler(clang::Cursor cursor, VisitDeclForTypeU
if (param->is_interesting) {
IndexedTypeDef* ref_type_def = db->Resolve(ref_type_id);
Location loc = db->file_db->Resolve(cursor, true /*interesting*/);
Location loc = db->id_cache->Resolve(cursor, true /*interesting*/);
ref_type_def->AddUsage(loc);
}
}
@ -445,7 +445,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
var_def->def.qualified_name = ns->QualifiedName(decl->semanticContainer, var_def->def.short_name);
//}
Location decl_loc = db->file_db->Resolve(decl->loc, false /*interesting*/);
Location decl_loc = db->id_cache->Resolve(decl->loc, false /*interesting*/);
if (decl->isDefinition)
var_def->def.definition = decl_loc;
else
@ -491,7 +491,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
func_def->def.qualified_name = ns->QualifiedName(decl->semanticContainer, func_def->def.short_name);
//}
Location decl_loc = db->file_db->Resolve(decl->loc, false /*interesting*/);
Location decl_loc = db->id_cache->Resolve(decl->loc, false /*interesting*/);
if (decl->isDefinition)
func_def->def.definition = decl_loc;
else
@ -608,7 +608,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
type_def->def.short_name = decl->entityInfo->name;
type_def->def.qualified_name = ns->QualifiedName(decl->semanticContainer, type_def->def.short_name);
Location decl_loc = db->file_db->Resolve(decl->loc, true /*interesting*/);
Location decl_loc = db->id_cache->Resolve(decl->loc, true /*interesting*/);
type_def->def.definition = decl_loc.WithInteresting(false);
type_def->AddUsage(decl_loc);
break;
@ -642,7 +642,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
// }
assert(decl->isDefinition);
Location decl_loc = db->file_db->Resolve(decl->loc, true /*interesting*/);
Location decl_loc = db->id_cache->Resolve(decl->loc, true /*interesting*/);
type_def->def.definition = decl_loc.WithInteresting(false);
type_def->AddUsage(decl_loc);
@ -671,7 +671,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
}
default:
std::cout << "!! Unhandled indexDeclaration: " << clang::Cursor(decl->cursor).ToString() << " at " << db->file_db->Resolve(decl->loc, false /*interesting*/).ToString() << std::endl;
std::cout << "!! Unhandled indexDeclaration: " << clang::Cursor(decl->cursor).ToString() << " at " << db->id_cache->Resolve(decl->loc, false /*interesting*/).ToString() << std::endl;
std::cout << " entityInfo->kind = " << decl->entityInfo->kind << std::endl;
std::cout << " entityInfo->USR = " << decl->entityInfo->USR << std::endl;
if (decl->declAsContainer)
@ -707,7 +707,7 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
{
VarId var_id = db->ToVarId(ref->referencedEntity->cursor);
IndexedVarDef* var_def = db->Resolve(var_id);
var_def->uses.push_back(db->file_db->Resolve(ref->loc, false /*interesting*/));
var_def->uses.push_back(db->id_cache->Resolve(ref->loc, false /*interesting*/));
break;
}
@ -729,7 +729,7 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
// Don't report duplicate usages.
// TODO: search full history?
Location loc = db->file_db->Resolve(ref->loc, false /*interesting*/);
Location loc = db->id_cache->Resolve(ref->loc, false /*interesting*/);
if (param->last_func_usage_location == loc) break;
param->last_func_usage_location = loc;
@ -757,8 +757,8 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
if (ref->referencedEntity->kind == CXIdxEntity_CXXConstructor ||
ref->referencedEntity->kind == CXIdxEntity_CXXDestructor) {
Location parent_loc = db->file_db->Resolve(ref->parentEntity->cursor, true /*interesting*/);
Location our_loc = db->file_db->Resolve(ref->loc, true /*is_interesting*/);
Location parent_loc = db->id_cache->Resolve(ref->parentEntity->cursor, true /*interesting*/);
Location our_loc = db->id_cache->Resolve(ref->loc, true /*is_interesting*/);
if (!parent_loc.IsEqualTo(our_loc)) {
IndexedFuncDef* called_def = db->Resolve(called_id);
assert(called_def->def.declaring_type.has_value());
@ -778,12 +778,12 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
{
TypeId referenced_id = db->ToTypeId(ref->referencedEntity->USR);
IndexedTypeDef* referenced_def = db->Resolve(referenced_id);
// We will not get a declaration visit for forward declared types. Try to mark them as non-bad
// defs here so we will output usages/etc.
if (referenced_def->is_bad_def) {
bool is_system_def = clang_Location_isInSystemHeader(clang_getCursorLocation(ref->referencedEntity->cursor));
Location loc = db->file_db->Resolve(ref->referencedEntity->cursor, false /*interesting*/);
Location loc = db->id_cache->Resolve(ref->referencedEntity->cursor, false /*interesting*/);
if (!is_system_def && loc.raw_file_id != -1)
referenced_def->is_bad_def = false;
}
@ -802,16 +802,16 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
// Foo f;
// }
//
referenced_def->AddUsage(db->file_db->Resolve(ref->loc, false /*interesting*/));
referenced_def->AddUsage(db->id_cache->Resolve(ref->loc, false /*interesting*/));
break;
}
default:
std::cout << "!! Unhandled indexEntityReference: " << cursor.ToString() << " at " << db->file_db->Resolve(ref->loc, false /*interesting*/).ToString() << std::endl;
std::cout << "!! Unhandled indexEntityReference: " << cursor.ToString() << " at " << db->id_cache->Resolve(ref->loc, false /*interesting*/).ToString() << std::endl;
std::cout << " ref->referencedEntity->kind = " << ref->referencedEntity->kind << std::endl;
if (ref->parentEntity)
std::cout << " ref->parentEntity->kind = " << ref->parentEntity->kind << std::endl;
std::cout << " ref->loc = " << db->file_db->Resolve(ref->loc, false /*interesting*/).ToString() << std::endl;
std::cout << " ref->loc = " << db->id_cache->Resolve(ref->loc, false /*interesting*/).ToString() << std::endl;
std::cout << " ref->kind = " << ref->kind << std::endl;
if (ref->parentEntity)
std::cout << " parentEntity = " << clang::Cursor(ref->parentEntity->cursor).ToString() << std::endl;
@ -826,7 +826,7 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
static bool DUMP_AST = true;
IndexedFile Parse(IdCache* id_cache, FileDb* file_db, std::string filename, std::vector<std::string> args) {
IndexedFile Parse(IdCache* id_cache, std::string filename, std::vector<std::string> args) {
clang::Index index(0 /*excludeDeclarationsFromPCH*/, 0 /*displayDiagnostics*/);
clang::TranslationUnit tu(index, filename, args);
@ -849,7 +849,7 @@ IndexedFile Parse(IdCache* id_cache, FileDb* file_db, std::string filename, std:
*/
};
IndexedFile db(id_cache, file_db);
IndexedFile db(id_cache);
NamespaceHelper ns;
IndexParam param(&db, &ns);
clang_indexTranslationUnit(index_action, &param, callbacks, sizeof(callbacks),
@ -991,8 +991,7 @@ int main55555(int argc, char** argv) {
// Run test.
std::cout << "[START] " << path << std::endl;
IdCache id_cache(1);
FileDb file_db(1);
IndexedFile db = Parse(&id_cache, &file_db, path, {});
IndexedFile db = Parse(&id_cache, path, {});
std::string actual_output = db.ToString();
//WriteToFile("output.json", actual_output);

105
indexer.h

@ -209,55 +209,6 @@ Location WithInteresting(bool interesting) {
END_BITFIELD_TYPE()
#endif
struct FileDb {
GroupId group;
std::unordered_map<std::string, FileId> file_path_to_file_id;
std::unordered_map<FileId, std::string> file_id_to_file_path;
FileDb(GroupId group) : group(group) {
// Reserve id 0 for unfound.
file_path_to_file_id[""] = FileId(group, 0);
file_id_to_file_path[FileId(group, 0)] = "";
}
Location Resolve(const CXSourceLocation& cx_loc, bool interesting) {
CXFile file;
unsigned int line, column, offset;
clang_getSpellingLocation(cx_loc, &file, &line, &column, &offset);
FileId file_id(-1, -1);
if (file != nullptr) {
std::string path = clang::ToString(clang_getFileName(file));
auto it = file_path_to_file_id.find(path);
if (it != file_path_to_file_id.end()) {
file_id = it->second;
}
else {
file_id = FileId(group, file_path_to_file_id.size());
file_path_to_file_id[path] = file_id;
file_id_to_file_path[file_id] = path;
}
}
return Location(interesting, file_id, line, column);
}
Location Resolve(const CXIdxLoc& cx_idx_loc, bool interesting) {
CXSourceLocation cx_loc = clang_indexLoc_getCXSourceLocation(cx_idx_loc);
return Resolve(cx_loc, interesting);
}
Location Resolve(const CXCursor& cx_cursor, bool interesting) {
return Resolve(clang_getCursorLocation(cx_cursor), interesting);
}
Location Resolve(const clang::Cursor& cursor, bool interesting) {
return Resolve(cursor.cx_cursor, interesting);
}
};
template<typename T>
struct Ref {
Id<T> id;
@ -295,7 +246,7 @@ using VarRef = Ref<IndexedVarDef>;
// TODO: Either eliminate the defs created as a by-product of cross-referencing,
// or do not emit things we don't have definitions for.
template<typename TypeId = TypeId, typename FuncId = FuncId, typename VarId = VarId>
template<typename TypeId = TypeId, typename FuncId = FuncId, typename VarId = VarId, typename Location = Location>
struct TypeDefDefinitionData {
// General metadata.
TypeId id;
@ -376,7 +327,7 @@ namespace std {
};
}
template<typename TypeId = TypeId, typename FuncId = FuncId, typename VarId = VarId, typename FuncRef = FuncRef>
template<typename TypeId = TypeId, typename FuncId = FuncId, typename VarId = VarId, typename FuncRef = FuncRef, typename Location = Location>
struct FuncDefDefinitionData {
// General metadata.
FuncId id;
@ -459,7 +410,7 @@ namespace std {
};
}
template<typename TypeId = TypeId, typename FuncId = FuncId, typename VarId = VarId>
template<typename TypeId = TypeId, typename FuncId = FuncId, typename VarId = VarId, typename Location = Location>
struct VarDefDefinitionData {
// General metadata.
VarId id;
@ -526,25 +477,67 @@ struct IdCache {
// NOTE: Every Id is resolved to a file_id of 0. The correct file_id needs
// to get fixed up when inserting into the real db.
GroupId group;
std::unordered_map<std::string, FileId> file_path_to_file_id;
std::unordered_map<std::string, TypeId> usr_to_type_id;
std::unordered_map<std::string, FuncId> usr_to_func_id;
std::unordered_map<std::string, VarId> usr_to_var_id;
std::unordered_map<FileId, std::string> file_id_to_file_path;
std::unordered_map<TypeId, std::string> type_id_to_usr;
std::unordered_map<FuncId, std::string> func_id_to_usr;
std::unordered_map<VarId, std::string> var_id_to_usr;
IdCache(GroupId group) : group(group) {}
IdCache(GroupId group) : group(group) {
// Reserve id 0 for unfound.
file_path_to_file_id[""] = FileId(group, 0);
file_id_to_file_path[FileId(group, 0)] = "";
}
Location Resolve(const CXSourceLocation& cx_loc, bool interesting) {
CXFile file;
unsigned int line, column, offset;
clang_getSpellingLocation(cx_loc, &file, &line, &column, &offset);
FileId file_id(-1, -1);
if (file != nullptr) {
std::string path = clang::ToString(clang_getFileName(file));
auto it = file_path_to_file_id.find(path);
if (it != file_path_to_file_id.end()) {
file_id = it->second;
}
else {
file_id = FileId(group, file_path_to_file_id.size());
file_path_to_file_id[path] = file_id;
file_id_to_file_path[file_id] = path;
}
}
return Location(interesting, file_id, line, column);
}
Location Resolve(const CXIdxLoc& cx_idx_loc, bool interesting) {
CXSourceLocation cx_loc = clang_indexLoc_getCXSourceLocation(cx_idx_loc);
return Resolve(cx_loc, interesting);
}
Location Resolve(const CXCursor& cx_cursor, bool interesting) {
return Resolve(clang_getCursorLocation(cx_cursor), interesting);
}
Location Resolve(const clang::Cursor& cursor, bool interesting) {
return Resolve(cursor.cx_cursor, interesting);
}
};
struct IndexedFile {
FileDb* file_db;
IdCache* id_cache;
std::vector<IndexedTypeDef> types;
std::vector<IndexedFuncDef> funcs;
std::vector<IndexedVarDef> vars;
IndexedFile(IdCache* id_cache, FileDb* file_db);
IndexedFile(IdCache* id_cache);
TypeId ToTypeId(const std::string& usr);
FuncId ToFuncId(const std::string& usr);
@ -562,4 +555,4 @@ struct IndexedFile {
IndexedFile Parse(IdCache* id_cache, FileDb* file_db, std::string filename, std::vector<std::string> args);
IndexedFile Parse(IdCache* id_cache, std::string filename, std::vector<std::string> args);

46
query.cc

@ -290,23 +290,6 @@ struct IdMap {
// TODO: Switch over to QueryableLocation. Figure out if there is
// a good way to get the indexer using it. I don't think so
// since we may discover more files while indexing a file.
//
// We could also reuse planned USR caching system for file
// paths.
struct CachedFileDb {
using Id = int64_t;
std::vector<std::string> file_names;
};
struct QueryableLocation {
CachedFileDb::Id id;
int line;
int column;
bool is_interesting;
};
@ -337,7 +320,9 @@ Usr MapIdToUsr(IdCache& id_cache, FuncId& id) {
Usr MapIdToUsr(IdCache& id_cache, VarId& id) {
return id_cache.var_id_to_usr[id];
}
Location MapIdToUsr(IdCache& id_cache, Location& ids); // FIXME: We will need additional data to map locations.
QueryableLocation MapIdToUsr(IdCache& id_cache, Location& id) {
return QueryableLocation(id_cache.file_id_to_file_path[id.file_id()], id.line, id.column, id.interesting);
}
std::vector<Usr> MapIdToUsr(IdCache& id_cache, std::vector<TypeId>& ids) {
return Transform<TypeId, Usr>(ids, [&](TypeId id) { return id_cache.type_id_to_usr[id]; });
@ -351,12 +336,16 @@ std::vector<Usr> MapIdToUsr(IdCache& id_cache, std::vector<VarId>& ids) {
std::vector<UsrRef> MapIdToUsr(IdCache& id_cache, std::vector<FuncRef>& ids) {
return Transform<FuncRef, UsrRef>(ids, [&](FuncRef ref) {
UsrRef result;
result.loc = ref.loc; // FIXME: Patch proper location. Fix when fixing MapIdToUsr(Location). I'm thinking we will have a GlobalLocation type.
result.loc = MapIdToUsr(id_cache, ref.loc);
result.usr = id_cache.func_id_to_usr[ref.id];
return result;
});
}
std::vector<Location> MapIdToUsr(IdCache& id_cache, std::vector<Location>& ids); // FIXME: We will need additional data to map locations.
std::vector<QueryableLocation> MapIdToUsr(IdCache& id_cache, std::vector<Location>& ids) {
return Transform<Location, QueryableLocation>(ids, [&](Location id) {
return QueryableLocation(id_cache.file_id_to_file_path[id.file_id()], id.line, id.column, id.interesting);
});
}
QueryableTypeDef::DefUpdate MapIdToUsr(IdCache& id_cache, TypeDefDefinitionData<>& def) {
QueryableTypeDef::DefUpdate result(def.usr, def.usr);
if (result.definition)
@ -788,6 +777,7 @@ struct QueryableDatabase {
std::vector<SymbolIdx> symbols;
// Raw data storage.
std::vector<QueryableFile> files; // File path is stored as a Usr.
std::vector<QueryableTypeDef> types;
std::vector<QueryableFuncDef> funcs;
std::vector<QueryableVarDef> vars;
@ -795,13 +785,6 @@ struct QueryableDatabase {
// Lookup symbol based on a usr.
std::unordered_map<Usr, SymbolIdx> usr_to_symbol;
// |files| is indexed by FileId. Retrieve a FileId from a path using
// |file_db|.
FileDb file_db;
std::vector<QueryableFile> files;
QueryableDatabase(GroupId group);
// Insert the contents of |update| into |db|.
void ApplyIndexUpdate(IndexUpdate* update);
@ -909,8 +892,6 @@ void ApplyUpdates(std::unordered_map<TId, int>* id_map, std::vector<TDef>* defs,
}
}
QueryableDatabase::QueryableDatabase(GroupId group) : file_db(group) {}
void QueryableDatabase::ApplyIndexUpdate(IndexUpdate* update) {
#define JOIN(a, b) a##b
#define HANDLE_MERGEABLE(update_var_name, def_var_name, storage_name) \
@ -956,13 +937,12 @@ void QueryableDatabase::ApplyIndexUpdate(IndexUpdate* update) {
int main(int argc, char** argv) {
// TODO: Unify UserToIdResolver and FileDb
IdCache id_cache(1);
FileDb file_db(1);
IndexedFile indexed_file_a = Parse(&id_cache, &file_db, "full_tests/index_delta/a_v0.cc", {});
IndexedFile indexed_file_a = Parse(&id_cache, "full_tests/index_delta/a_v0.cc", {});
std::cout << indexed_file_a.ToString() << std::endl;
std::cout << std::endl;
IndexedFile indexed_file_b = Parse(&id_cache, &file_db, "full_tests/index_delta/a_v1.cc", {});
IndexedFile indexed_file_b = Parse(&id_cache, "full_tests/index_delta/a_v1.cc", {});
std::cout << indexed_file_b.ToString() << std::endl;
// TODO: We don't need to do ID remapping when computting a diff. Well, we need to do it for the IndexUpdate.
IndexUpdate import(indexed_file_a);
@ -970,7 +950,7 @@ int main(int argc, char** argv) {
dest_ids.Import(indexed_file_b.file_db, indexed_file_b.id_cache);
IndexUpdate update = ComputeDiff(indexed_file_a, indexed_file_b);
*/
QueryableDatabase db(5);
QueryableDatabase db;
db.ApplyIndexUpdate(&import);
//db.ApplyIndexUpdate(&update);

72
query.h

@ -23,15 +23,45 @@ enum class PreferredSymbolLocation {
};
using Usr = std::string;
// TODO: Switch over to QueryableLocation. Figure out if there is
// a good way to get the indexer using it. I don't think so
// since we may discover more files while indexing a file.
//
// We could also reuse planned USR caching system for file
// paths.
struct QueryableLocation {
Usr path;
int line;
int column;
bool interesting;
QueryableLocation()
: path(""), line(-1), column(-1), interesting(false) {}
QueryableLocation(Usr path, int line, int column, bool interesting)
: path(path), line(line), column(column), interesting(interesting) {}
bool operator==(const QueryableLocation& other) const {
// Note: We ignore |is_interesting|.
return
path == other.path &&
line == other.line &&
column == other.column;
}
};
struct UsrRef {
Usr usr;
Location loc;
QueryableLocation loc;
bool operator==(const UsrRef& other) const {
return usr == other.usr && loc == other.loc;
}
};
// There are two sources of reindex updates: the (single) definition of a
// symbol has changed, or one of many users of the symbol has changed.
//
@ -52,45 +82,45 @@ struct MergeableUpdate {
};
struct QueryableTypeDef {
TypeDefDefinitionData<Usr, Usr, Usr> def;
std::vector<Usr> derived;
std::vector<Location> uses;
using DefUpdate = TypeDefDefinitionData<Usr, Usr, Usr>;
using DefUpdate = TypeDefDefinitionData<Usr, Usr, Usr, QueryableLocation>;
using DerivedUpdate = MergeableUpdate<Usr>;
using UsesUpdate = MergeableUpdate<Location>;
using UsesUpdate = MergeableUpdate<QueryableLocation>;
DefUpdate def;
std::vector<Usr> derived;
std::vector<QueryableLocation> uses;
QueryableTypeDef(IdCache& id_cache, IndexedTypeDef& indexed);
};
struct QueryableFuncDef {
FuncDefDefinitionData<Usr, Usr, Usr, UsrRef> def;
std::vector<Location> declarations;
std::vector<Usr> derived;
std::vector<UsrRef> callers;
std::vector<Location> uses;
using DefUpdate = FuncDefDefinitionData<Usr, Usr, Usr, UsrRef>;
using DeclarationsUpdate = MergeableUpdate<Location>;
using DefUpdate = FuncDefDefinitionData<Usr, Usr, Usr, UsrRef, QueryableLocation>;
using DeclarationsUpdate = MergeableUpdate<QueryableLocation>;
using DerivedUpdate = MergeableUpdate<Usr>;
using CallersUpdate = MergeableUpdate<UsrRef>;
using UsesUpdate = MergeableUpdate<Location>;
using UsesUpdate = MergeableUpdate<QueryableLocation>;
DefUpdate def;
std::vector<QueryableLocation> declarations;
std::vector<Usr> derived;
std::vector<UsrRef> callers;
std::vector<QueryableLocation> uses;
QueryableFuncDef(IdCache& id_cache, IndexedFuncDef& indexed);
};
struct QueryableVarDef {
VarDefDefinitionData<Usr, Usr, Usr> def;
std::vector<Location> uses;
using DefUpdate = VarDefDefinitionData<Usr, Usr, Usr, QueryableLocation>;
using UsesUpdate = MergeableUpdate<QueryableLocation>;
using DefUpdate = VarDefDefinitionData<Usr, Usr, Usr>;
using UsesUpdate = MergeableUpdate<Location>;
DefUpdate def;
std::vector<QueryableLocation> uses;
QueryableVarDef(IdCache& id_cache, IndexedVarDef& indexed);
};
enum class SymbolKind { Invalid, Type, Func, Var };
enum class SymbolKind { Invalid, File, Type, Func, Var };
struct SymbolIdx {
SymbolKind kind;
uint64_t idx;

1
wscript

@ -17,6 +17,7 @@ def configure(conf):
# https://github.com/Andersbakken/rtags/blob/master/scripts/getclang.sh
def download_clang():
#'http://releases.llvm.org/3.9.0/clang+llvm-3.9.0-x86_64-apple-darwin.tar.xz'
pass
def build(bld):
cc_files = bld.path.ant_glob(['**/*.cpp', '**/*.cc'],

Loading…
Cancel
Save