mirror of
https://github.com/MaskRay/ccls.git
synced 2025-01-18 19:45:49 +00:00
fixes, print diagnostics
This commit is contained in:
parent
8a13acd3b8
commit
f3c8500fa9
2
clang_args
Normal file
2
clang_args
Normal file
@ -0,0 +1,2 @@
|
||||
-std=c++11
|
||||
-Ithird_party/rapidjson/include
|
154
indexer.cpp
154
indexer.cpp
@ -97,6 +97,28 @@ void IndexedTypeDef::AddUsage(Location loc, bool insert_if_not_present) {
|
||||
uses.push_back(loc);
|
||||
}
|
||||
|
||||
|
||||
std::string Location::ToPrettyString(IdCache* id_cache) {
|
||||
// Output looks like this:
|
||||
//
|
||||
// *1:2:3
|
||||
//
|
||||
// * => interesting
|
||||
// 1 => file id
|
||||
// 2 => line
|
||||
// 3 => column
|
||||
|
||||
std::string result;
|
||||
if (interesting)
|
||||
result += '*';
|
||||
result += id_cache->file_id_to_file_path[raw_file_id];
|
||||
result += ':';
|
||||
result += std::to_string(line);
|
||||
result += ':';
|
||||
result += std::to_string(column);
|
||||
return result;
|
||||
}
|
||||
|
||||
IdCache::IdCache() {
|
||||
// Reserve id 0 for unfound.
|
||||
file_path_to_file_id[""] = FileId(0);
|
||||
@ -154,7 +176,53 @@ bool Contains(const std::vector<T>& vec, const T& element) {
|
||||
|
||||
|
||||
|
||||
struct NamespaceHelper {
|
||||
std::unordered_map<std::string, std::string> container_usr_to_qualified_name;
|
||||
|
||||
void RegisterQualifiedName(std::string usr, const CXIdxContainerInfo* container, std::string qualified_name) {
|
||||
if (container) {
|
||||
std::string container_usr = clang::Cursor(container->cursor).get_usr();
|
||||
auto it = container_usr_to_qualified_name.find(container_usr);
|
||||
if (it != container_usr_to_qualified_name.end()) {
|
||||
container_usr_to_qualified_name[usr] = it->second + qualified_name + "::";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
container_usr_to_qualified_name[usr] = qualified_name + "::";
|
||||
}
|
||||
|
||||
std::string QualifiedName(const CXIdxContainerInfo* container, std::string unqualified_name) {
|
||||
if (container) {
|
||||
std::string container_usr = clang::Cursor(container->cursor).get_usr();
|
||||
auto it = container_usr_to_qualified_name.find(container_usr);
|
||||
if (it != container_usr_to_qualified_name.end())
|
||||
return it->second + unqualified_name;
|
||||
|
||||
// Anonymous namespaces are not processed by indexDeclaration. If we
|
||||
// encounter one insert it into map.
|
||||
if (container->cursor.kind == CXCursor_Namespace) {
|
||||
//assert(clang::Cursor(container->cursor).get_spelling() == "");
|
||||
container_usr_to_qualified_name[container_usr] = "::";
|
||||
return "::" + unqualified_name;
|
||||
}
|
||||
}
|
||||
return unqualified_name;
|
||||
}
|
||||
};
|
||||
|
||||
struct IndexParam {
|
||||
IndexedFile* db;
|
||||
NamespaceHelper* ns;
|
||||
|
||||
// Record the last type usage location we recorded. Clang will sometimes
|
||||
// visit the same expression twice so we wan't to avoid double-reporting
|
||||
// usage information for those locations.
|
||||
Location last_type_usage_location;
|
||||
Location last_func_usage_location;
|
||||
|
||||
IndexParam(IndexedFile* db, NamespaceHelper* ns) : db(db), ns(ns) {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -166,7 +234,38 @@ int abortQuery(CXClientData client_data, void *reserved) {
|
||||
// 0 -> continue
|
||||
return 0;
|
||||
}
|
||||
void diagnostic(CXClientData client_data, CXDiagnosticSet, void *reserved) {}
|
||||
void diagnostic(CXClientData client_data, CXDiagnosticSet diagnostics, void *reserved) {
|
||||
IndexParam* param = static_cast<IndexParam*>(client_data);
|
||||
|
||||
std::cerr << "!! Got diagnostic" << std::endl;
|
||||
/**
|
||||
* \brief Determine the number of diagnostics in a CXDiagnosticSet.
|
||||
*/
|
||||
//CINDEX_LINKAGE unsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags);
|
||||
|
||||
for (unsigned i = 0; i < clang_getNumDiagnosticsInSet(diagnostics); ++i) {
|
||||
CXDiagnostic diagnostic = clang_getDiagnosticInSet(diagnostics, i);
|
||||
|
||||
std::string spelling = clang::ToString(clang_getDiagnosticSpelling(diagnostic));
|
||||
Location location = param->db->id_cache.Resolve(clang_getDiagnosticLocation(diagnostic), false /*interesting*/);
|
||||
|
||||
std::cerr << location.ToPrettyString(¶m->db->id_cache) << ": " << spelling << std::endl;
|
||||
|
||||
clang_disposeDiagnostic(diagnostic);
|
||||
}
|
||||
/**
|
||||
* \brief Retrieve a diagnostic associated with the given CXDiagnosticSet.
|
||||
*
|
||||
* \param Diags the CXDiagnosticSet to query.
|
||||
* \param Index the zero-based diagnostic number to retrieve.
|
||||
*
|
||||
* \returns the requested diagnostic. This diagnostic must be freed
|
||||
* via a call to \c clang_disposeDiagnostic().
|
||||
*/
|
||||
// CINDEX_LINKAGE CXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags,
|
||||
// unsigned Index);
|
||||
|
||||
}
|
||||
|
||||
CXIdxClientFile enteredMainFile(CXClientData client_data, CXFile mainFile, void *reserved) {
|
||||
return nullptr;
|
||||
@ -258,53 +357,6 @@ optional<clang::Cursor> FindType(clang::Cursor cursor) {
|
||||
|
||||
|
||||
|
||||
struct NamespaceHelper {
|
||||
std::unordered_map<std::string, std::string> container_usr_to_qualified_name;
|
||||
|
||||
void RegisterQualifiedName(std::string usr, const CXIdxContainerInfo* container, std::string qualified_name) {
|
||||
if (container) {
|
||||
std::string container_usr = clang::Cursor(container->cursor).get_usr();
|
||||
auto it = container_usr_to_qualified_name.find(container_usr);
|
||||
if (it != container_usr_to_qualified_name.end()) {
|
||||
container_usr_to_qualified_name[usr] = it->second + qualified_name + "::";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
container_usr_to_qualified_name[usr] = qualified_name + "::";
|
||||
}
|
||||
|
||||
std::string QualifiedName(const CXIdxContainerInfo* container, std::string unqualified_name) {
|
||||
if (container) {
|
||||
std::string container_usr = clang::Cursor(container->cursor).get_usr();
|
||||
auto it = container_usr_to_qualified_name.find(container_usr);
|
||||
if (it != container_usr_to_qualified_name.end())
|
||||
return it->second + unqualified_name;
|
||||
|
||||
// Anonymous namespaces are not processed by indexDeclaration. If we
|
||||
// encounter one insert it into map.
|
||||
if (container->cursor.kind == CXCursor_Namespace) {
|
||||
//assert(clang::Cursor(container->cursor).get_spelling() == "");
|
||||
container_usr_to_qualified_name[container_usr] = "::";
|
||||
return "::" + unqualified_name;
|
||||
}
|
||||
}
|
||||
return unqualified_name;
|
||||
}
|
||||
};
|
||||
|
||||
struct IndexParam {
|
||||
IndexedFile* db;
|
||||
NamespaceHelper* ns;
|
||||
|
||||
// Record the last type usage location we recorded. Clang will sometimes
|
||||
// visit the same expression twice so we wan't to avoid double-reporting
|
||||
// usage information for those locations.
|
||||
Location last_type_usage_location;
|
||||
Location last_func_usage_location;
|
||||
|
||||
IndexParam(IndexedFile* db, NamespaceHelper* ns) : db(db), ns(ns) {}
|
||||
};
|
||||
|
||||
/*
|
||||
std::string GetNamespacePrefx(const CXIdxDeclInfo* decl) {
|
||||
@ -1031,6 +1083,12 @@ struct Timer {
|
||||
};
|
||||
|
||||
IndexedFile Parse(std::string filename, std::vector<std::string> args, bool dump_ast) {
|
||||
args.push_back("-std=c++11");
|
||||
args.push_back("-fms-compatibility");
|
||||
args.push_back("-fdelayed-template-parsing");
|
||||
//args.push_back("-isystem C:\\Users\\jacob\\Desktop\\superindex\\indexer\\libcxx-3.9.1\\include");
|
||||
//args.push_back("--sysroot C:\\Users\\jacob\\Desktop\\superindex\\indexer\\libcxx-3.9.1");
|
||||
|
||||
clang::Index index(0 /*excludeDeclarationsFromPCH*/, 0 /*displayDiagnostics*/);
|
||||
clang::TranslationUnit tu(index, filename, args);
|
||||
|
||||
|
@ -64,6 +64,8 @@ using TypeId = Id<IndexedTypeDef>;
|
||||
using FuncId = Id<IndexedFuncDef>;
|
||||
using VarId = Id<IndexedVarDef>;
|
||||
|
||||
class IdCache;
|
||||
|
||||
struct Location {
|
||||
bool interesting;
|
||||
int raw_file_id;
|
||||
@ -113,6 +115,8 @@ struct Location {
|
||||
column = atoi(encoded);
|
||||
}
|
||||
|
||||
std::string ToPrettyString(IdCache* id_cache);
|
||||
|
||||
std::string ToString() {
|
||||
// Output looks like this:
|
||||
//
|
||||
|
6
test.cc
6
test.cc
@ -95,9 +95,9 @@ void RunTests() {
|
||||
return 0;
|
||||
*/
|
||||
|
||||
for (std::string path : GetFilesInFolder("tests", true /*add_folder_to_path*/)) {
|
||||
for (std::string path : GetFilesInFolder("tests", true /*recursive*/, true /*add_folder_to_path*/)) {
|
||||
//if (path != "tests/templates/specialized_func_definition.cc") continue;
|
||||
if (path != "tests/outline/outline.cc") continue;
|
||||
if (path != "tests/outline/outline2.h") continue;
|
||||
//if (path == "tests/inheritance/class_inherit_templated_parent.cc") continue;
|
||||
//if (path != "tests/namespaces/namespace_reference.cc") continue;
|
||||
//if (path != "tests/stl.cc") continue;
|
||||
@ -113,7 +113,7 @@ void RunTests() {
|
||||
|
||||
// Run test.
|
||||
std::cout << "[START] " << path << std::endl;
|
||||
IndexedFile db = Parse(path, {}, true /*dump_ast*/);
|
||||
IndexedFile db = Parse(path, {}, false /*dump_ast*/);
|
||||
VerifySerializeToFrom(db);
|
||||
std::string actual_output = db.ToString();
|
||||
|
||||
|
16
utils.cc
16
utils.cc
@ -6,7 +6,7 @@
|
||||
|
||||
#include "tinydir.h"
|
||||
|
||||
static std::vector<std::string> GetFilesInFolderHelper(std::string folder, std::string output_prefix) {
|
||||
static std::vector<std::string> GetFilesInFolderHelper(std::string folder, bool recursive, std::string output_prefix) {
|
||||
std::vector<std::string> result;
|
||||
|
||||
tinydir_dir dir;
|
||||
@ -25,10 +25,12 @@ static std::vector<std::string> GetFilesInFolderHelper(std::string folder, std::
|
||||
// Skip all dot files.
|
||||
if (file.name[0] != '.') {
|
||||
if (file.is_dir) {
|
||||
// Note that we must always ignore the '.' and '..' directories, otherwise
|
||||
// this will loop infinitely. The above check handles that for us.
|
||||
for (std::string nested_file : GetFilesInFolderHelper(file.path, output_prefix + file.name + "/"))
|
||||
result.push_back(nested_file);
|
||||
if (recursive) {
|
||||
// Note that we must always ignore the '.' and '..' directories, otherwise
|
||||
// this will loop infinitely. The above check handles that for us.
|
||||
for (std::string nested_file : GetFilesInFolderHelper(file.path, true /*recursive*/, output_prefix + file.name + "/"))
|
||||
result.push_back(nested_file);
|
||||
}
|
||||
}
|
||||
else {
|
||||
result.push_back(output_prefix + file.name);
|
||||
@ -46,12 +48,12 @@ bail:
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> GetFilesInFolder(std::string folder, bool add_folder_to_path) {
|
||||
std::vector<std::string> GetFilesInFolder(std::string folder, bool recursive, bool add_folder_to_path) {
|
||||
assert(folder.size() > 0);
|
||||
if (folder[folder.size() - 1] != '/')
|
||||
folder += '/';
|
||||
|
||||
return GetFilesInFolderHelper(folder, add_folder_to_path ? folder : "");
|
||||
return GetFilesInFolderHelper(folder, recursive, add_folder_to_path ? folder : "");
|
||||
}
|
||||
|
||||
// http://stackoverflow.com/a/6089413
|
||||
|
2
utils.h
2
utils.h
@ -5,7 +5,7 @@
|
||||
#include <memory>
|
||||
|
||||
// Finds all files in the given folder. This is recursive.
|
||||
std::vector<std::string> GetFilesInFolder(std::string folder, bool add_folder_to_path);
|
||||
std::vector<std::string> GetFilesInFolder(std::string folder, bool recursive, bool add_folder_to_path);
|
||||
std::vector<std::string> ReadLines(std::string filename);
|
||||
void ParseTestExpectation(std::string filename, std::string* expected_output);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user