From f6967eee48f48c2b100538b40a58e3cb53829d3e Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Sun, 5 Mar 2017 17:09:08 -0800 Subject: [PATCH] fix usage on specialized template parameters --- indexer.cpp | 29 +++- test.cc | 5 +- tests/constructors/invalid_reference.cc | 29 ++++ tests/foobar.cc | 105 ------------- tests/stl.cc | 142 ++++++++++++++++++ .../func_specialized_template_param.cc | 41 +++++ 6 files changed, 238 insertions(+), 113 deletions(-) create mode 100644 tests/constructors/invalid_reference.cc create mode 100644 tests/stl.cc create mode 100644 tests/templates/func_specialized_template_param.cc diff --git a/indexer.cpp b/indexer.cpp index 086bf161..6a90313f 100644 --- a/indexer.cpp +++ b/indexer.cpp @@ -509,9 +509,25 @@ optional AddDeclUsages(IndexedFile* db, clang::Cursor decl_cursor, // The second TypeRef is an uninteresting usage. bool process_last_type_ref = true; if (IsTypeDefinition(semantic_container) && !IsTypeDefinition(lexical_container)) { - //if (!decl_cursor.is_definition()) - // decl_cursor = decl_cursor.get_definition(); - assert(decl_cursor.is_definition()); + + // + // In some code, such as the following example, we receive a cursor which is not + // a definition and is not associated with a definition due to an error condition. + // In this case, it is the Foo::Foo constructor. + // + // struct Foo {}; + // + // template + // Foo::Foo() {} + // + if (!decl_cursor.is_definition()) { + // TODO: I don't think this resolution ever works. + clang::Cursor def = decl_cursor.get_definition(); + if (def.get_kind() != CXCursor_FirstInvalid) { + std::cerr << "Successful resolution of decl usage to definition" << std::endl; + decl_cursor = def; + } + } process_last_type_ref = false; } @@ -683,8 +699,9 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { switch (arg.get_kind()) { case CXCursor_ParmDecl: // We don't need to know the arg type, but we do want to mark it as - // an interesting usage. - AddDeclUsages(db, arg, true /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer); + // an interesting usage. Note that we use semanticContainer twice + // because a parameter is not really part of the lexical container. + AddDeclUsages(db, arg, true /*is_interesting*/, decl->semanticContainer, decl->semanticContainer); //TypeResolution arg_type = ResolveToType(db, arg.get_type()); //if (arg_type.resolved_type) @@ -1006,4 +1023,4 @@ IndexedFile Parse(std::string filename, std::vector args, bool dump clang_IndexAction_dispose(index_action); return db; -} +} \ No newline at end of file diff --git a/test.cc b/test.cc index c5abb6ed..100e57ae 100644 --- a/test.cc +++ b/test.cc @@ -94,9 +94,10 @@ int main(int argc, char** argv) { */ for (std::string path : GetFilesInFolder("tests", true /*add_folder_to_path*/)) { - //if (path != "tests/usage/var_usage_cstyle_cast.cc") continue; + //if (path != "tests/templates/func_specialized_template_param.cc") continue; + //if (path != "tests/constructors/invalid_reference.cc") continue; //if (path == "tests/inheritance/class_inherit_templated_parent.cc") continue; - //if (path != "tests/templates/template_class_type_usage_folded_into_one.cc") continue; + if (path == "tests/stl.cc") continue; //if (path != "tests/templates/template_class_type_usage_folded_into_one.cc") continue; //path = "C:/Users/jacob/Desktop/superindex/indexer/" + path; diff --git a/tests/constructors/invalid_reference.cc b/tests/constructors/invalid_reference.cc new file mode 100644 index 00000000..31ea4c05 --- /dev/null +++ b/tests/constructors/invalid_reference.cc @@ -0,0 +1,29 @@ +struct Foo {}; + +template +Foo::Foo() {} + +/* +OUTPUT: +{ + "types": [{ + "id": 0, + "usr": "c:@S@Foo", + "short_name": "Foo", + "qualified_name": "Foo", + "definition": "1:1:8", + "funcs": [0], + "uses": ["*1:1:8", "1:4:6", "1:4:1"] + }], + "functions": [{ + "id": 0, + "usr": "c:@S@Foo@FT@>1#TFoo#v#", + "short_name": "Foo", + "qualified_name": "Foo::Foo", + "definition": "1:4:6", + "declaring_type": 0, + "uses": ["1:4:6"] + }], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/foobar.cc b/tests/foobar.cc index b0188667..a5d923df 100644 --- a/tests/foobar.cc +++ b/tests/foobar.cc @@ -8,33 +8,6 @@ struct Foo { Foo::Inner a; Foo b; - -//#include - - - -#if false -// We could store how many template parameters Foo has and then skip that many TypeRefs..., -// if there was still a TypeRef after (and we are not ignoring it) then we know -// that is the variable type. - -EnumDecl A -EnumDecl B -ClassTemplate Foo - TemplateTypeParameter T - StructDecl Inner -VarDecl a - TemplateRef Foo - TypeRef enum A - TypeRef struct Foo::Inner - CallExpr Inner -VarDecl b - TemplateRef Foo - TypeRef enum B - CallExpr Foo -#endif - - /* OUTPUT: { @@ -115,34 +88,6 @@ namespace ns { } #endif -// TODO: we are not marking interesting usage for a CStyleCastExpr -// TODO: we are resoling templates in a weird way (should be 1 type) -#if false -Namespace ns - EnumDecl VarType - ClassTemplate Holder - TemplateTypeParameter _ - VarDecl static_var - TypeRef enum ns::VarType - CStyleCastExpr - TypeRef enum ns::VarType - IntegerLiteral - VarDecl static_var - TemplateTypeParameter _ - TypeRef enum ns::VarType - TemplateRef Holder - TypeRef _ - VarDecl Foo - UnexposedExpr static_var - UnexposedExpr static_var - DeclRefExpr static_var - TemplateRef Holder - VarDecl static_var - TypeRef enum ns::VarType - TemplateRef Holder -#endif - - /* OUTPUT: { @@ -218,53 +163,3 @@ OUTPUT: - - - - - - -//#include -//#include - -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include \ No newline at end of file diff --git a/tests/stl.cc b/tests/stl.cc new file mode 100644 index 00000000..fef6bdb7 --- /dev/null +++ b/tests/stl.cc @@ -0,0 +1,142 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/templates/func_specialized_template_param.cc b/tests/templates/func_specialized_template_param.cc new file mode 100644 index 00000000..7005a5e0 --- /dev/null +++ b/tests/templates/func_specialized_template_param.cc @@ -0,0 +1,41 @@ +template +class Template {}; + +struct Foo { + void Bar(Template&); +}; + +void Foo::Bar(Template&) {} + +/* +OUTPUT: +{ + "types": [{ + "id": 0, + "usr": "c:@ST>1#T@Template", + "short_name": "Template", + "qualified_name": "Template", + "definition": "1:2:7", + "uses": ["*1:2:7", "1:5:12", "*1:8:15"] + }, { + "id": 1, + "usr": "c:@S@Foo", + "short_name": "Foo", + "qualified_name": "Foo", + "definition": "1:4:8", + "funcs": [0], + "uses": ["*1:4:8", "1:8:6"] + }], + "functions": [{ + "id": 0, + "usr": "c:@S@Foo@F@Bar#&$@S@Template>#d#", + "short_name": "Bar", + "qualified_name": "Foo::Bar", + "declarations": ["1:5:8"], + "definition": "1:8:11", + "declaring_type": 1, + "uses": ["1:5:8", "1:8:11"] + }], + "variables": [] +} +*/ \ No newline at end of file