mirror of
https://github.com/MaskRay/ccls.git
synced 2025-02-16 13:48:04 +00:00
Index macros (treat them like variables)
This commit is contained in:
parent
d3bd31604e
commit
529f309c45
@ -12,6 +12,8 @@
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
|
||||
// TODO: See if we can use clang_indexLoc_getFileLocation to get a type ref on |Foobar| in DISALLOW_COPY(Foobar)
|
||||
|
||||
namespace {
|
||||
|
||||
const bool kIndexStdDeclarations = true;
|
||||
@ -22,13 +24,12 @@ void AddFuncRef(std::vector<IndexFuncRef>* result, IndexFuncRef ref) {
|
||||
result->push_back(ref);
|
||||
}
|
||||
|
||||
|
||||
Range Resolve(const CXSourceRange& range) {
|
||||
Range Resolve(const CXSourceRange& range, CXFile* cx_file = nullptr) {
|
||||
CXSourceLocation start = clang_getRangeStart(range);
|
||||
CXSourceLocation end = clang_getRangeEnd(range);
|
||||
|
||||
unsigned int start_line, start_column;
|
||||
clang_getSpellingLocation(start, nullptr, &start_line, &start_column, nullptr);
|
||||
clang_getSpellingLocation(start, cx_file, &start_line, &start_column, nullptr);
|
||||
unsigned int end_line, end_column;
|
||||
clang_getSpellingLocation(end, nullptr, &end_line, &end_column, nullptr);
|
||||
|
||||
@ -37,14 +38,14 @@ Range Resolve(const CXSourceRange& range) {
|
||||
Position(end_line, end_column) /*end*/);
|
||||
}
|
||||
|
||||
Range ResolveSpelling(const CXCursor& cx_cursor) {
|
||||
Range ResolveSpelling(const CXCursor& cx_cursor, CXFile* cx_file = nullptr) {
|
||||
CXSourceRange cx_range = clang_Cursor_getSpellingNameRange(cx_cursor, 0, 0);
|
||||
return Resolve(cx_range);
|
||||
return Resolve(cx_range, cx_file);
|
||||
}
|
||||
|
||||
Range ResolveExtent(const CXCursor& cx_cursor) {
|
||||
Range ResolveExtent(const CXCursor& cx_cursor, CXFile* cx_file = nullptr) {
|
||||
CXSourceRange cx_range = clang_getCursorExtent(cx_cursor);
|
||||
return Resolve(cx_range);
|
||||
return Resolve(cx_range, cx_file);
|
||||
}
|
||||
|
||||
|
||||
@ -716,7 +717,48 @@ bool AreEqualLocations(CXIdxLoc loc, CXCursor cursor) {
|
||||
|
||||
|
||||
|
||||
clang::VisiterResult VisitMacroDefinitionAndExpansions(clang::Cursor cursor, clang::Cursor parent, IndexParam* param) {
|
||||
switch (cursor.get_kind()) {
|
||||
case CXCursor_MacroDefinition:
|
||||
case CXCursor_MacroExpansion:
|
||||
// Resolve location, find IndexFile instance.
|
||||
CXSourceRange cx_source_range = clang_Cursor_getSpellingNameRange(cursor.cx_cursor, 0, 0);
|
||||
CXSourceLocation start = clang_getRangeStart(cx_source_range);
|
||||
if (clang_Location_isInSystemHeader(start))
|
||||
break;
|
||||
CXFile file;
|
||||
Range decl_loc_spelling = Resolve(cx_source_range, &file);
|
||||
IndexFile* db = ConsumeFile(param, file);
|
||||
if (!db)
|
||||
break;
|
||||
|
||||
// TODO: Considering checking clang_Cursor_isMacroFunctionLike, but the
|
||||
// only real difference will be that we show 'callers' instead of 'refs'
|
||||
// (especially since macros cannot have overrides)
|
||||
|
||||
std::string decl_usr;
|
||||
if (cursor.get_kind() == CXCursor_MacroDefinition)
|
||||
decl_usr = cursor.get_usr();
|
||||
else
|
||||
decl_usr = cursor.get_referenced().get_usr();
|
||||
|
||||
IndexVarId var_id = db->ToVarId(decl_usr);
|
||||
IndexVar* var_def = db->Resolve(var_id);
|
||||
UniqueAdd(var_def->uses, decl_loc_spelling);
|
||||
|
||||
if (cursor.get_kind() == CXCursor_MacroDefinition) {
|
||||
var_def->def.short_name = cursor.get_display_name();
|
||||
var_def->def.detailed_name = var_def->def.short_name;
|
||||
var_def->def.is_local = false;
|
||||
var_def->def.definition_spelling = decl_loc_spelling;
|
||||
var_def->def.definition_extent = ResolveExtent(cursor.cx_cursor);;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return clang::VisiterResult::Continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1466,6 +1508,8 @@ std::vector<std::unique_ptr<IndexFile>> Parse(
|
||||
clang_IndexAction_dispose(index_action);
|
||||
//std::cerr << "!! [END] Indexing " << file << std::endl;
|
||||
|
||||
tu.document_cursor().VisitChildren(&VisitMacroDefinitionAndExpansions, ¶m);
|
||||
|
||||
perf->index_build = timer.ElapsedMicrosecondsAndReset();
|
||||
|
||||
auto result = param.file_consumer->TakeLocalState();
|
||||
|
51
tests/macros/foo.cc
Normal file
51
tests/macros/foo.cc
Normal file
@ -0,0 +1,51 @@
|
||||
#define A 5
|
||||
#define DISALLOW(type) type(type&&) = delete;
|
||||
|
||||
struct Foo {
|
||||
DISALLOW(Foo);
|
||||
};
|
||||
|
||||
int x = A;
|
||||
|
||||
/*
|
||||
OUTPUT:
|
||||
{
|
||||
"types": [{
|
||||
"id": 0,
|
||||
"usr": "c:@S@Foo",
|
||||
"short_name": "Foo",
|
||||
"detailed_name": "Foo",
|
||||
"definition_spelling": "4:8-4:11",
|
||||
"definition_extent": "4:1-6:2",
|
||||
"uses": ["4:8-4:11"]
|
||||
}],
|
||||
"vars": [{
|
||||
"id": 0,
|
||||
"usr": "c:@x",
|
||||
"short_name": "x",
|
||||
"detailed_name": "int x",
|
||||
"definition_spelling": "8:5-8:6",
|
||||
"definition_extent": "8:1-8:10",
|
||||
"is_local": false,
|
||||
"uses": ["8:5-8:6"]
|
||||
}, {
|
||||
"id": 1,
|
||||
"usr": "c:foo.cc@8@macro@A",
|
||||
"short_name": "A",
|
||||
"detailed_name": "A",
|
||||
"definition_spelling": "1:9-1:10",
|
||||
"definition_extent": "1:9-1:12",
|
||||
"is_local": false,
|
||||
"uses": ["1:9-1:10", "8:9-8:10"]
|
||||
}, {
|
||||
"id": 2,
|
||||
"usr": "c:foo.cc@21@macro@DISALLOW",
|
||||
"short_name": "DISALLOW",
|
||||
"detailed_name": "DISALLOW",
|
||||
"definition_spelling": "2:9-2:17",
|
||||
"definition_extent": "2:9-2:46",
|
||||
"is_local": false,
|
||||
"uses": ["2:9-2:17", "5:3-5:11"]
|
||||
}]
|
||||
}
|
||||
*/
|
@ -24,6 +24,16 @@ OUTPUT:
|
||||
"definition_spelling": "5:6-5:12",
|
||||
"definition_extent": "5:1-7:2",
|
||||
"callees": ["0@6:14-6:20"]
|
||||
}],
|
||||
"vars": [{
|
||||
"id": 0,
|
||||
"usr": "c:func_called_from_macro_argument.cc@8@macro@MACRO_CALL",
|
||||
"short_name": "MACRO_CALL",
|
||||
"detailed_name": "MACRO_CALL",
|
||||
"definition_spelling": "1:9-1:19",
|
||||
"definition_extent": "1:9-1:24",
|
||||
"is_local": false,
|
||||
"uses": ["1:9-1:19", "6:3-6:13"]
|
||||
}]
|
||||
}
|
||||
*/
|
Loading…
Reference in New Issue
Block a user