mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-26 01:21:57 +00:00
Support llvm 4
This commit is contained in:
parent
c079ab45b3
commit
ebd467d31b
117
indexer.cpp
117
indexer.cpp
@ -84,7 +84,7 @@ IndexedTypeDef::IndexedTypeDef(TypeId id, const std::string& usr) : id(id), def(
|
|||||||
//std::cerr << "Creating type with usr " << usr << std::endl;
|
//std::cerr << "Creating type with usr " << usr << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IndexedTypeDef::AddUsage(Location loc, bool insert_if_not_present) {
|
void AddUsage(std::vector<Location>& uses, Location loc, bool insert_if_not_present = true) {
|
||||||
for (int i = uses.size() - 1; i >= 0; --i) {
|
for (int i = uses.size() - 1; i >= 0; --i) {
|
||||||
if (uses[i].IsEqualTo(loc)) {
|
if (uses[i].IsEqualTo(loc)) {
|
||||||
if (loc.interesting)
|
if (loc.interesting)
|
||||||
@ -240,7 +240,7 @@ void diagnostic(CXClientData client_data, CXDiagnosticSet diagnostics, void *res
|
|||||||
// Print any diagnostics to std::cerr
|
// Print any diagnostics to std::cerr
|
||||||
for (unsigned i = 0; i < clang_getNumDiagnosticsInSet(diagnostics); ++i) {
|
for (unsigned i = 0; i < clang_getNumDiagnosticsInSet(diagnostics); ++i) {
|
||||||
CXDiagnostic diagnostic = clang_getDiagnosticInSet(diagnostics, i);
|
CXDiagnostic diagnostic = clang_getDiagnosticInSet(diagnostics, i);
|
||||||
|
|
||||||
std::string spelling = clang::ToString(clang_getDiagnosticSpelling(diagnostic));
|
std::string spelling = clang::ToString(clang_getDiagnosticSpelling(diagnostic));
|
||||||
Location location = param->db->id_cache.Resolve(clang_getDiagnosticLocation(diagnostic), false /*interesting*/);
|
Location location = param->db->id_cache.Resolve(clang_getDiagnosticLocation(diagnostic), false /*interesting*/);
|
||||||
|
|
||||||
@ -395,7 +395,7 @@ void VisitDeclForTypeUsageVisitorHandler(clang::Cursor cursor, VisitDeclForTypeU
|
|||||||
if (param->is_interesting) {
|
if (param->is_interesting) {
|
||||||
IndexedTypeDef* ref_type_def = db->Resolve(ref_type_id);
|
IndexedTypeDef* ref_type_def = db->Resolve(ref_type_id);
|
||||||
Location loc = db->id_cache.Resolve(cursor, true /*interesting*/);
|
Location loc = db->id_cache.Resolve(cursor, true /*interesting*/);
|
||||||
ref_type_def->AddUsage(loc);
|
AddUsage(ref_type_def->uses, loc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,7 +455,7 @@ optional<TypeId> ResolveToDeclarationType(IndexedFile* db, clang::Cursor cursor)
|
|||||||
// returns the first seen TypeRef or TemplateRef value, which can be useful if trying
|
// returns the first seen TypeRef or TemplateRef value, which can be useful if trying
|
||||||
// to figure out ie, what a using statement refers to. If trying to generally resolve
|
// to figure out ie, what a using statement refers to. If trying to generally resolve
|
||||||
// a cursor to a type, use ResolveToDeclarationType, which works in more scenarios.
|
// a cursor to a type, use ResolveToDeclarationType, which works in more scenarios.
|
||||||
optional<TypeId> AddDeclUsages(IndexedFile* db, clang::Cursor decl_cursor,
|
optional<TypeId> AddDeclTypeUsages(IndexedFile* db, clang::Cursor decl_cursor,
|
||||||
bool is_interesting, const CXIdxContainerInfo* semantic_container,
|
bool is_interesting, const CXIdxContainerInfo* semantic_container,
|
||||||
const CXIdxContainerInfo* lexical_container) {
|
const CXIdxContainerInfo* lexical_container) {
|
||||||
|
|
||||||
@ -487,15 +487,15 @@ optional<TypeId> AddDeclUsages(IndexedFile* db, clang::Cursor decl_cursor,
|
|||||||
//
|
//
|
||||||
// enum A {};
|
// enum A {};
|
||||||
// enum B {};
|
// enum B {};
|
||||||
//
|
//
|
||||||
// template<typename T>
|
// template<typename T>
|
||||||
// struct Foo {
|
// struct Foo {
|
||||||
// struct Inner {};
|
// struct Inner {};
|
||||||
// };
|
// };
|
||||||
//
|
//
|
||||||
// Foo<A>::Inner a;
|
// Foo<A>::Inner a;
|
||||||
// Foo<B> b;
|
// Foo<B> b;
|
||||||
//
|
//
|
||||||
// =>
|
// =>
|
||||||
//
|
//
|
||||||
// EnumDecl A
|
// EnumDecl A
|
||||||
@ -584,6 +584,70 @@ optional<TypeId> AddDeclUsages(IndexedFile* db, clang::Cursor decl_cursor,
|
|||||||
return param.initial_type;
|
return param.initial_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Various versions of LLVM (ie, 4.0) will not visit inline variable references for template arguments.
|
||||||
|
clang::VisiterResult AddDeclInitializerUsagesVisitor(clang::Cursor cursor, clang::Cursor parent, IndexedFile* db) {
|
||||||
|
/*
|
||||||
|
We need to index the |DeclRefExpr| below (ie, |var| inside of Foo<int>::var).
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Foo {
|
||||||
|
static constexpr int var = 3;
|
||||||
|
};
|
||||||
|
|
||||||
|
int a = Foo<int>::var;
|
||||||
|
|
||||||
|
=>
|
||||||
|
|
||||||
|
VarDecl a
|
||||||
|
UnexposedExpr var
|
||||||
|
DeclRefExpr var
|
||||||
|
TemplateRef Foo
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
switch (cursor.get_kind()) {
|
||||||
|
case CXCursor_DeclRefExpr:
|
||||||
|
CXCursorKind referenced_kind = cursor.get_referenced().get_kind();
|
||||||
|
if (cursor.get_referenced().get_kind() != CXCursor_VarDecl)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// TODO: when we resolve the template type to the definition, we get a different USR.
|
||||||
|
|
||||||
|
//clang::Cursor ref = cursor.get_referenced().template_specialization_to_template_definition().get_type().strip_qualifiers().get_usr();
|
||||||
|
//std::string ref_usr = cursor.get_referenced().template_specialization_to_template_definition().get_type().strip_qualifiers().get_usr();
|
||||||
|
std::string ref_usr = cursor.get_referenced().template_specialization_to_template_definition().get_usr();
|
||||||
|
//std::string ref_usr = ref.get_usr();
|
||||||
|
if (ref_usr == "")
|
||||||
|
break;
|
||||||
|
|
||||||
|
VarId ref_id = db->ToVarId(ref_usr);
|
||||||
|
IndexedVarDef* ref_def = db->Resolve(ref_id);
|
||||||
|
Location loc = db->id_cache.Resolve(cursor, false /*interesting*/);
|
||||||
|
std::cerr << "Adding usage to id=" << ref_id.id << " usr=" << ref_usr << " at " << loc.ToString() << std::endl;
|
||||||
|
AddUsage(ref_def->uses, loc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return clang::VisiterResult::Recurse;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddDeclInitializerUsages(IndexedFile* db, clang::Cursor decl_cursor) {
|
||||||
|
decl_cursor.VisitChildren(&AddDeclInitializerUsagesVisitor, db);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||||
// TODO: we can minimize processing for cursors which return false for clang_Location_isFromMainFile (ie, only add usages)
|
// TODO: we can minimize processing for cursors which return false for clang_Location_isFromMainFile (ie, only add usages)
|
||||||
|
|
||||||
@ -595,6 +659,8 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
IndexedFile* db = param->db;
|
IndexedFile* db = param->db;
|
||||||
NamespaceHelper* ns = param->ns;
|
NamespaceHelper* ns = param->ns;
|
||||||
|
|
||||||
|
// std::cerr << "DECL kind=" << decl->entityInfo->kind << " at " << db->id_cache.Resolve(decl->cursor, false).ToPrettyString(&db->id_cache) << std::endl;
|
||||||
|
|
||||||
switch (decl->entityInfo->kind) {
|
switch (decl->entityInfo->kind) {
|
||||||
case CXIdxEntity_CXXNamespace:
|
case CXIdxEntity_CXXNamespace:
|
||||||
{
|
{
|
||||||
@ -632,16 +698,19 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
var_def->def.definition = decl_loc;
|
var_def->def.definition = decl_loc;
|
||||||
else
|
else
|
||||||
var_def->def.declaration = decl_loc;
|
var_def->def.declaration = decl_loc;
|
||||||
var_def->uses.push_back(decl_loc);
|
AddUsage(var_def->uses, decl_loc);
|
||||||
|
|
||||||
//std::cerr << std::endl << "Visiting declaration" << std::endl;
|
//std::cerr << std::endl << "Visiting declaration" << std::endl;
|
||||||
//Dump(decl_cursor);
|
//Dump(decl_cursor);
|
||||||
|
|
||||||
|
AddDeclInitializerUsages(db, decl_cursor);
|
||||||
|
var_def = db->Resolve(var_id);
|
||||||
|
|
||||||
// Declaring variable type information. Note that we do not insert an
|
// Declaring variable type information. Note that we do not insert an
|
||||||
// interesting reference for parameter declarations - that is handled when
|
// interesting reference for parameter declarations - that is handled when
|
||||||
// the function declaration is encountered since we won't receive ParmDecl
|
// the function declaration is encountered since we won't receive ParmDecl
|
||||||
// declarations for unnamed parameters.
|
// declarations for unnamed parameters.
|
||||||
AddDeclUsages(db, decl_cursor, decl_cursor.get_kind() != CXCursor_ParmDecl /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer);
|
AddDeclTypeUsages(db, decl_cursor, decl_cursor.get_kind() != CXCursor_ParmDecl /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer);
|
||||||
optional<TypeId> var_type = ResolveToDeclarationType(db, decl_cursor);
|
optional<TypeId> var_type = ResolveToDeclarationType(db, decl_cursor);
|
||||||
if (var_type.has_value())
|
if (var_type.has_value())
|
||||||
var_def->def.variable_type = var_type.value();
|
var_def->def.variable_type = var_type.value();
|
||||||
@ -672,10 +741,10 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
|
|
||||||
Location decl_loc = db->id_cache.Resolve(decl->loc, false /*interesting*/);
|
Location decl_loc = db->id_cache.Resolve(decl->loc, false /*interesting*/);
|
||||||
|
|
||||||
func_def->uses.push_back(decl_loc);
|
AddUsage(func_def->uses, decl_loc);
|
||||||
// We don't actually need to know the return type, but we need to mark it
|
// We don't actually need to know the return type, but we need to mark it
|
||||||
// as an interesting usage.
|
// as an interesting usage.
|
||||||
AddDeclUsages(db, decl_cursor, true /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer);
|
AddDeclTypeUsages(db, decl_cursor, true /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer);
|
||||||
|
|
||||||
// TODO: support multiple definitions per function; right now we are hacking the 'declarations' field by
|
// TODO: support multiple definitions per function; right now we are hacking the 'declarations' field by
|
||||||
// adding a definition when we really don't have one.
|
// adding a definition when we really don't have one.
|
||||||
@ -712,7 +781,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
// TODO: Should it be interesting?
|
// TODO: Should it be interesting?
|
||||||
if (is_ctor_or_dtor) {
|
if (is_ctor_or_dtor) {
|
||||||
Location type_usage_loc = decl_loc;
|
Location type_usage_loc = decl_loc;
|
||||||
declaring_type_def->AddUsage(type_usage_loc);
|
AddUsage(declaring_type_def->uses, type_usage_loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register function in declaring type if it hasn't been registered yet.
|
// Register function in declaring type if it hasn't been registered yet.
|
||||||
@ -742,7 +811,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
// We don't need to know the arg type, but we do want to mark it as
|
// We don't need to know the arg type, but we do want to mark it as
|
||||||
// an interesting usage. Note that we use semanticContainer twice
|
// an interesting usage. Note that we use semanticContainer twice
|
||||||
// because a parameter is not really part of the lexical container.
|
// because a parameter is not really part of the lexical container.
|
||||||
AddDeclUsages(db, arg, true /*is_interesting*/, decl->semanticContainer, decl->semanticContainer);
|
AddDeclTypeUsages(db, arg, true /*is_interesting*/, decl->semanticContainer, decl->semanticContainer);
|
||||||
|
|
||||||
//TypeResolution arg_type = ResolveToType(db, arg.get_type());
|
//TypeResolution arg_type = ResolveToType(db, arg.get_type());
|
||||||
//if (arg_type.resolved_type)
|
//if (arg_type.resolved_type)
|
||||||
@ -792,7 +861,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
{
|
{
|
||||||
// Note we want to fetch the first TypeRef. Running ResolveCursorType(decl->cursor) would return
|
// Note we want to fetch the first TypeRef. Running ResolveCursorType(decl->cursor) would return
|
||||||
// the type of the typedef/using, not the type of the referenced type.
|
// the type of the typedef/using, not the type of the referenced type.
|
||||||
optional<TypeId> alias_of = AddDeclUsages(db, decl->cursor, true /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer);
|
optional<TypeId> alias_of = AddDeclTypeUsages(db, decl->cursor, true /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer);
|
||||||
|
|
||||||
TypeId type_id = db->ToTypeId(decl->entityInfo->USR);
|
TypeId type_id = db->ToTypeId(decl->entityInfo->USR);
|
||||||
IndexedTypeDef* type_def = db->Resolve(type_id);
|
IndexedTypeDef* type_def = db->Resolve(type_id);
|
||||||
@ -807,7 +876,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
|
|
||||||
Location decl_loc = db->id_cache.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->def.definition = decl_loc.WithInteresting(false);
|
||||||
type_def->AddUsage(decl_loc);
|
AddUsage(type_def->uses, decl_loc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -841,7 +910,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
assert(decl->isDefinition);
|
assert(decl->isDefinition);
|
||||||
Location decl_loc = db->id_cache.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->def.definition = decl_loc.WithInteresting(false);
|
||||||
type_def->AddUsage(decl_loc);
|
AddUsage(type_def->uses, decl_loc);
|
||||||
|
|
||||||
//type_def->alias_of
|
//type_def->alias_of
|
||||||
//type_def->funcs
|
//type_def->funcs
|
||||||
@ -855,7 +924,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
for (unsigned int i = 0; i < class_info->numBases; ++i) {
|
for (unsigned int i = 0; i < class_info->numBases; ++i) {
|
||||||
const CXIdxBaseClassInfo* base_class = class_info->bases[i];
|
const CXIdxBaseClassInfo* base_class = class_info->bases[i];
|
||||||
|
|
||||||
AddDeclUsages(db, base_class->cursor, true /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer);
|
AddDeclTypeUsages(db, base_class->cursor, true /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer);
|
||||||
optional<TypeId> parent_type_id = ResolveToDeclarationType(db, base_class->cursor);
|
optional<TypeId> parent_type_id = ResolveToDeclarationType(db, base_class->cursor);
|
||||||
IndexedTypeDef* type_def = db->Resolve(type_id); // type_def ptr could be invalidated by ResolveDeclToType.
|
IndexedTypeDef* type_def = db->Resolve(type_id); // type_def ptr could be invalidated by ResolveDeclToType.
|
||||||
if (parent_type_id) {
|
if (parent_type_id) {
|
||||||
@ -901,6 +970,8 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
|
|||||||
IndexedFile* db = param->db;
|
IndexedFile* db = param->db;
|
||||||
clang::Cursor cursor(ref->cursor);
|
clang::Cursor cursor(ref->cursor);
|
||||||
|
|
||||||
|
//std::cerr << "REF kind=" << ref->referencedEntity->kind << " at " << db->id_cache.Resolve(cursor, false).ToPrettyString(&db->id_cache) << std::endl;
|
||||||
|
|
||||||
switch (ref->referencedEntity->kind) {
|
switch (ref->referencedEntity->kind) {
|
||||||
case CXIdxEntity_CXXNamespace:
|
case CXIdxEntity_CXXNamespace:
|
||||||
{
|
{
|
||||||
@ -919,7 +990,7 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
|
|||||||
VarId var_id = db->ToVarId(referenced.get_usr());
|
VarId var_id = db->ToVarId(referenced.get_usr());
|
||||||
IndexedVarDef* var_def = db->Resolve(var_id);
|
IndexedVarDef* var_def = db->Resolve(var_id);
|
||||||
Location loc = db->id_cache.Resolve(ref->loc, false /*interesting*/);
|
Location loc = db->id_cache.Resolve(ref->loc, false /*interesting*/);
|
||||||
var_def->uses.push_back(loc);
|
AddUsage(var_def->uses, loc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -954,11 +1025,11 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
|
|||||||
|
|
||||||
caller_def->def.callees.push_back(FuncRef(called_id, loc));
|
caller_def->def.callees.push_back(FuncRef(called_id, loc));
|
||||||
called_def->callers.push_back(FuncRef(caller_id, loc));
|
called_def->callers.push_back(FuncRef(caller_id, loc));
|
||||||
called_def->uses.push_back(loc);
|
AddUsage(called_def->uses, loc);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
IndexedFuncDef* called_def = db->Resolve(called_id);
|
IndexedFuncDef* called_def = db->Resolve(called_id);
|
||||||
called_def->uses.push_back(loc);
|
AddUsage(called_def->uses, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For constructor/destructor, also add a usage against the type. Clang
|
// For constructor/destructor, also add a usage against the type. Clang
|
||||||
@ -978,7 +1049,7 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
|
|||||||
if (called_def->def.declaring_type) {
|
if (called_def->def.declaring_type) {
|
||||||
//assert(called_def->def.declaring_type.has_value());
|
//assert(called_def->def.declaring_type.has_value());
|
||||||
IndexedTypeDef* type_def = db->Resolve(called_def->def.declaring_type.value());
|
IndexedTypeDef* type_def = db->Resolve(called_def->def.declaring_type.value());
|
||||||
type_def->AddUsage(our_loc);
|
AddUsage(type_def->uses, our_loc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -998,7 +1069,7 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
|
|||||||
|
|
||||||
IndexedTypeDef* referenced_def = db->Resolve(referenced_id);
|
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
|
// 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.
|
// defs here so we will output usages/etc.
|
||||||
if (referenced_def->is_bad_def) {
|
if (referenced_def->is_bad_def) {
|
||||||
bool is_system_def = clang_Location_isInSystemHeader(clang_getCursorLocation(ref->referencedEntity->cursor));
|
bool is_system_def = clang_Location_isInSystemHeader(clang_getCursorLocation(ref->referencedEntity->cursor));
|
||||||
@ -1021,7 +1092,7 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
|
|||||||
// Foo f;
|
// Foo f;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
referenced_def->AddUsage(db->id_cache.Resolve(ref->loc, false /*interesting*/));
|
AddUsage(referenced_def->uses, db->id_cache.Resolve(ref->loc, false /*interesting*/));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,7 +332,6 @@ struct IndexedTypeDef {
|
|||||||
IndexedTypeDef() : def("") {} // For serialization
|
IndexedTypeDef() : def("") {} // For serialization
|
||||||
|
|
||||||
IndexedTypeDef(TypeId id, const std::string& usr);
|
IndexedTypeDef(TypeId id, const std::string& usr);
|
||||||
void AddUsage(Location loc, bool insert_if_not_present = true);
|
|
||||||
|
|
||||||
bool operator<(const IndexedTypeDef& other) const {
|
bool operator<(const IndexedTypeDef& other) const {
|
||||||
return def.usr < other.def.usr;
|
return def.usr < other.def.usr;
|
||||||
|
4
test.cc
4
test.cc
@ -97,10 +97,10 @@ void RunTests() {
|
|||||||
|
|
||||||
for (std::string path : GetFilesInFolder("tests", true /*recursive*/, 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/templates/specialized_func_definition.cc") continue;
|
||||||
//if (path != "tests/outline/outline2.cc") continue;
|
//if (path != "tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc") continue;
|
||||||
//if (path == "tests/inheritance/class_inherit_templated_parent.cc") continue;
|
//if (path == "tests/inheritance/class_inherit_templated_parent.cc") continue;
|
||||||
//if (path != "tests/namespaces/namespace_reference.cc") continue;
|
//if (path != "tests/namespaces/namespace_reference.cc") continue;
|
||||||
//if (path != "tests/stl.cc") continue;
|
//if (path != "tests/templates/implicit_variable_instantiation.cc") continue;
|
||||||
|
|
||||||
//if (path != "tests/templates/template_class_type_usage_folded_into_one.cc") continue;
|
//if (path != "tests/templates/template_class_type_usage_folded_into_one.cc") continue;
|
||||||
//path = "C:/Users/jacob/Desktop/superindex/indexer/" + path;
|
//path = "C:/Users/jacob/Desktop/superindex/indexer/" + path;
|
||||||
|
@ -7,8 +7,7 @@ T var = 3;
|
|||||||
int a = var<A>;
|
int a = var<A>;
|
||||||
int b = var<B>;
|
int b = var<B>;
|
||||||
|
|
||||||
// TODO: No usages of types on var.
|
// NOTE: libclang before 4.0 doesn't expose template usage on |var|.
|
||||||
// libclang doesn't expose the info. File a bug.
|
|
||||||
|
|
||||||
#if false
|
#if false
|
||||||
EnumDecl A
|
EnumDecl A
|
||||||
@ -48,11 +47,11 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": "c:@var",
|
"usr": "c:@VT>1#T@var",
|
||||||
"short_name": "var",
|
"short_name": "var",
|
||||||
"qualified_name": "var",
|
"qualified_name": "var",
|
||||||
"definition": "1:5:3",
|
"definition": "1:5:3",
|
||||||
"uses": ["1:5:3"]
|
"uses": ["1:5:3", "1:7:9", "1:8:9"]
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": "c:@a",
|
"usr": "c:@a",
|
||||||
|
Loading…
Reference in New Issue
Block a user