diff --git a/libclangmm/Cursor.cc b/libclangmm/Cursor.cc index 921e1636..703a843b 100644 --- a/libclangmm/Cursor.cc +++ b/libclangmm/Cursor.cc @@ -174,7 +174,7 @@ std::string Cursor::get_comments() const { } std::string Cursor::ToString() const { - return get_spelling() + " " + clang::ToString(get_kind()); + return clang::ToString(get_kind()) + " " + get_spelling(); } } // namespace clang \ No newline at end of file diff --git a/main.cpp b/main.cpp index 219e523b..c390c304 100644 --- a/main.cpp +++ b/main.cpp @@ -52,6 +52,8 @@ template struct Ref { LocalId id; clang::SourceLocation loc; + + Ref(LocalId id, clang::SourceLocation loc) : id(id), loc(loc) {} }; using TypeRef = Ref; using FuncRef = Ref; @@ -398,11 +400,6 @@ std::string ParsingDatabase::ToString(bool for_test) { writer.String("declaration"); WriteLocation(writer, def.declaration); - if (def.initializations.size() == 0) { - writer.EndObject(); - continue; - } - writer.String("initializations"); WriteLocationArray(writer, def.initializations); @@ -491,7 +488,8 @@ struct NamespaceStack { void Push(const std::string& ns); void Pop(); - std::string ComputeQualifiedPrefix(); + std::string ComputeQualifiedName( + ParsingDatabase* db, std::optional declaring_type, std::string short_name); static NamespaceStack kEmpty; }; @@ -505,10 +503,17 @@ void NamespaceStack::Pop() { stack.pop_back(); } -std::string NamespaceStack::ComputeQualifiedPrefix() { +std::string NamespaceStack::ComputeQualifiedName( + ParsingDatabase* db, std::optional declaring_type, std::string short_name) { + if (declaring_type) { + TypeDef* def = db->Resolve(declaring_type.value()); + return def->qualified_name + "::" + short_name; + } + std::string result; for (const std::string& ns : stack) result += ns + "::"; + result += short_name; return result; } @@ -520,10 +525,9 @@ std::string NamespaceStack::ComputeQualifiedPrefix() { - std::optional ResolveDeclaringType(CXCursorKind kind, ParsingDatabase* db, const clang::Cursor& cursor, std::optional declaring_type) { // Resolve the declaring type for out-of-line method definitions. - if (!declaring_type && cursor.get_kind() == kind) { + if (!declaring_type) { clang::Cursor parent = cursor.get_semantic_parent(); switch (parent.get_kind()) { case CXCursor_ClassDecl: @@ -556,7 +560,7 @@ std::optional ResolveDeclaringType(CXCursorKind kind, ParsingDatabase* d clang::VisiterResult DumpVisitor(clang::Cursor cursor, clang::Cursor parent, int* level) { for (int i = 0; i < *level; ++i) std::cout << " "; - std::cout << cursor.get_spelling() << " " << clang::ToString(cursor.get_kind()) << std::endl; + std::cout << clang::ToString(cursor.get_kind()) << " " << cursor.get_spelling() << std::endl; *level += 1; cursor.VisitChildren(&DumpVisitor, level); @@ -577,7 +581,7 @@ void Dump(clang::Cursor cursor) { void HandleVarDecl(ParsingDatabase* db, NamespaceStack* ns, clang::Cursor var, std::optional declaring_type) { - Dump(var); + //Dump(var); VarId var_id = db->ToVarId(var.get_usr()); @@ -587,7 +591,8 @@ void HandleVarDecl(ParsingDatabase* db, NamespaceStack* ns, clang::Cursor var, s // instance alive. VarDef* var_def = db->Resolve(var_id); var_def->short_name = var.get_spelling(); - var_def->qualified_name = ns->ComputeQualifiedPrefix() + var_def->short_name; + var_def->qualified_name = + ns->ComputeQualifiedName(db, declaring_type, var_def->short_name); if (declaring_type && !var_def->declaration) { db->Resolve(declaring_type.value())->vars.push_back(var_id); @@ -599,7 +604,14 @@ void HandleVarDecl(ParsingDatabase* db, NamespaceStack* ns, clang::Cursor var, s var_def->declaration = var.get_source_location(); return; } + // If we're a definition and there hasn't been a forward decl, just assign + // declaration location to definition location. + else if (!var_def->declaration) { + var_def->declaration = var.get_source_location(); + } + // TODO: Figure out how to scan initializations properly. We probably need + // to scan for assignment statement, or definition+ctor. var_def->initializations.push_back(var.get_source_location()); var_def->variable_type = db->ToTypeId(var.get_type().get_usr()); } @@ -608,36 +620,69 @@ void HandleVarDecl(ParsingDatabase* db, NamespaceStack* ns, clang::Cursor var, s +// |func_id| is the function definition that is currently being processed. +void InsertReference(ParsingDatabase* db, FuncId func_id, clang::Cursor referencer) { + clang::Cursor referenced = referencer.get_referenced(); + switch (referenced.get_kind()) { + case CXCursor_FunctionDecl: + { + FuncId referenced_id = db->ToFuncId(referenced.get_usr()); + clang::SourceLocation loc = referencer.get_source_location(); + + FuncDef* func_def = db->Resolve(func_id); + FuncDef* referenced_def = db->Resolve(referenced_id); + func_def->callees.push_back(FuncRef(referenced_id, loc)); + referenced_def->callers.push_back(FuncRef(func_id, loc)); + referenced_def->uses.push_back(loc); + break; + } + default: + std::cerr << "Unhandled reference from " << referencer.ToString() << " to " + << referenced.ToString() << std::endl; + break; + } +} struct FuncDefinitionParam { ParsingDatabase* db; NamespaceStack* ns; - FuncDefinitionParam(ParsingDatabase* db, NamespaceStack* ns) - : db(db), ns(ns) {} + FuncId func_id; + FuncDefinitionParam(ParsingDatabase* db, NamespaceStack* ns, FuncId func_id) + : db(db), ns(ns), func_id(func_id) {} }; clang::VisiterResult VisitFuncDefinition(clang::Cursor cursor, clang::Cursor parent, FuncDefinitionParam* param) { //std::cout << "VistFunc got " << cursor.ToString() << std::endl; switch (cursor.get_kind()) { + // TODO: Maybe we should default to recurse? + /* case CXCursor_CompoundStmt: case CXCursor_DeclStmt: + case CXCursor_CallExpr: + case CXCursor_UnexposedExpr: + case CXCursor_UnaryExpr: return clang::VisiterResult::Recurse; + */ + + case CXCursor_DeclRefExpr: + InsertReference(param->db, param->func_id, cursor); + break; case CXCursor_VarDecl: case CXCursor_ParmDecl: HandleVarDecl(param->db, param->ns, cursor, std::nullopt); - return clang::VisiterResult::Continue; + return clang::VisiterResult::Recurse; case CXCursor_ReturnStmt: - return clang::VisiterResult::Continue; + return clang::VisiterResult::Recurse; default: - std::cerr << "Unhandled VisitFuncDefinition kind " << clang::ToString(cursor.get_kind()) << std::endl; - return clang::VisiterResult::Continue; + //std::cerr << "Unhandled VisitFuncDefinition kind " << clang::ToString(cursor.get_kind()) << std::endl; + return clang::VisiterResult::Recurse; } } @@ -663,11 +708,8 @@ void HandleFunc(ParsingDatabase* db, NamespaceStack* ns, clang::Cursor func, std FuncDef* func_def = db->Resolve(func_id); func_def->short_name = func.get_spelling(); - std::string type_name; - if (declaring_type) - type_name = db->Resolve(declaring_type.value())->short_name + "::"; func_def->qualified_name = - ns->ComputeQualifiedPrefix() + type_name + func_def->short_name; + ns->ComputeQualifiedName(db, declaring_type, func_def->short_name); if (declaring_type && !func_def->declaration) { db->Resolve(declaring_type.value())->funcs.push_back(func_id); @@ -699,8 +741,8 @@ void HandleFunc(ParsingDatabase* db, NamespaceStack* ns, clang::Cursor func, std //clang::Type return_type_1 = func.get_type().get_result(); //clang::Type return_type_2 = clang_getCursorResultType(func.cx_cursor); - Dump(func); - FuncDefinitionParam funcDefinitionParam(db, &NamespaceStack::kEmpty); + //Dump(func); + FuncDefinitionParam funcDefinitionParam(db, &NamespaceStack::kEmpty, func_id); func.VisitChildren(&VisitFuncDefinition, &funcDefinitionParam); //CXType return_type = clang_getResultType(func.get_type()); @@ -735,6 +777,7 @@ clang::VisiterResult VisitClassDecl(clang::Cursor cursor, clang::Cursor parent, break; case CXCursor_FieldDecl: + case CXCursor_VarDecl: HandleVarDecl(param->db, param->ns, cursor, param->active_type); break; @@ -747,21 +790,23 @@ clang::VisiterResult VisitClassDecl(clang::Cursor cursor, clang::Cursor parent, } void HandleClassDecl(clang::Cursor cursor, ParsingDatabase* db, NamespaceStack* ns) { - TypeId id = db->ToTypeId(cursor.get_usr()); - TypeDef* def = db->Resolve(id); + TypeId func_id = db->ToTypeId(cursor.get_usr()); + TypeDef* func_def = db->Resolve(func_id); - def->short_name = cursor.get_spelling(); - def->qualified_name = ns->ComputeQualifiedPrefix() + cursor.get_spelling(); + func_def->short_name = cursor.get_spelling(); + // TODO: Support nested classes (pass in declaring type insteaad of nullopt!) + func_def->qualified_name = + ns->ComputeQualifiedName(db, std::nullopt, func_def->short_name); if (!cursor.is_definition()) { - if (!def->declaration) - def->declaration = cursor.get_source_location(); + if (!func_def->declaration) + func_def->declaration = cursor.get_source_location(); return; } - def->definition = cursor.get_source_location(); + func_def->definition = cursor.get_source_location(); - ClassDeclParam classDeclParam(db, ns, id); + ClassDeclParam classDeclParam(db, ns, func_id); cursor.VisitChildren(&VisitClassDecl, &classDeclParam); } @@ -797,6 +842,10 @@ clang::VisiterResult VisitFile(clang::Cursor cursor, clang::Cursor parent, FileP HandleFunc(param->db, param->ns, cursor, std::nullopt); break; + case CXCursor_VarDecl: + HandleVarDecl(param->db, param->ns, cursor, std::nullopt); + break; + default: std::cerr << "Unhandled VisitFile kind " << clang::ToString(cursor.get_kind()) << std::endl; break; @@ -821,9 +870,9 @@ ParsingDatabase Parse(std::string filename) { clang::Index index(0 /*excludeDeclarationsFromPCH*/, 0 /*displayDiagnostics*/); clang::TranslationUnit tu(index, filename, args); - //std::cout << "Start document dump" << std::endl; - //Dump(tu.document_cursor()); - //std::cout << "Done document dump" << std::endl << std::endl; + std::cout << "Start document dump" << std::endl; + Dump(tu.document_cursor()); + std::cout << "Done document dump" << std::endl << std::endl; ParsingDatabase db; NamespaceStack ns; @@ -856,7 +905,7 @@ void Write(const std::vector& strs) { int main(int argc, char** argv) { for (std::string path : GetFilesInFolder("tests")) { // TODO: Fix all existing tests. - //if (path != "tests/vars/class_member.cc") continue; + if (path != "tests/usage/func_usage_addr_func.cc") continue; // Parse expected output from the test, parse it into JSON document. std::string expected_output; diff --git a/tests/_empty_test.cc b/tests/_empty_test.cc new file mode 100644 index 00000000..4f70c7a9 --- /dev/null +++ b/tests/_empty_test.cc @@ -0,0 +1,8 @@ +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/namespaces/anonymous_function.cc b/tests/namespaces/anonymous_function.cc new file mode 100644 index 00000000..f47d5cdc --- /dev/null +++ b/tests/namespaces/anonymous_function.cc @@ -0,0 +1,17 @@ +namespace { +void foo(); +} + +/* +OUTPUT: +{ + "types": [], + "functions": [{ + "id": 0, + "short_name": "foo", + "qualified_name": "::foo", + "declaration": "tests/namespaces/anonymous_function.cc:2:6" + }], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/function_declaration_in_namespace.cc b/tests/namespaces/function_declaration.cc similarity index 74% rename from tests/function_declaration_in_namespace.cc rename to tests/namespaces/function_declaration.cc index f9897bf3..143dff84 100644 --- a/tests/function_declaration_in_namespace.cc +++ b/tests/namespaces/function_declaration.cc @@ -10,7 +10,7 @@ OUTPUT: "id": 0, "short_name": "foo", "qualified_name": "hello::foo", - "declaration": "tests/function_declaration_in_namespace.cc:2:6" + "declaration": "tests/namespaces/function_declaration.cc:2:6" }], "variables": [] } diff --git a/tests/function_definition_in_namespace.cc b/tests/namespaces/function_definition.cc similarity index 84% rename from tests/function_definition_in_namespace.cc rename to tests/namespaces/function_definition.cc index 8a87694e..628911e6 100644 --- a/tests/function_definition_in_namespace.cc +++ b/tests/namespaces/function_definition.cc @@ -11,7 +11,7 @@ OUTPUT: "short_name": "foo", "qualified_name": "hello::foo", "declaration": null, - "definition": "tests/function_definition_in_namespace.cc:2:6", + "definition": "tests/namespaces/function_definition.cc:2:6", "declaring_type": null, "base": null, "derived": [], diff --git a/tests/method_declaration_in_namespace.cc b/tests/namespaces/method_declaration.cc similarity index 77% rename from tests/method_declaration_in_namespace.cc rename to tests/namespaces/method_declaration.cc index 35304c14..43f4eb72 100644 --- a/tests/method_declaration_in_namespace.cc +++ b/tests/namespaces/method_declaration.cc @@ -12,7 +12,7 @@ OUTPUT: "short_name": "Foo", "qualified_name": "hello::Foo", "declaration": null, - "definition": "tests/method_declaration_in_namespace.cc:2:7", + "definition": "tests/namespaces/method_declaration.cc:2:7", "parents": [], "derived": [], "types": [], @@ -24,7 +24,7 @@ OUTPUT: "id": 0, "short_name": "foo", "qualified_name": "hello::Foo::foo", - "declaration": "tests/method_declaration_in_namespace.cc:3:8", + "declaration": "tests/namespaces/method_declaration.cc:3:8", "declaring_type": 0 }], "variables": [] diff --git a/tests/method_definition_in_namespace.cc b/tests/namespaces/method_definition.cc similarity index 74% rename from tests/method_definition_in_namespace.cc rename to tests/namespaces/method_definition.cc index e52c463a..b66cba72 100644 --- a/tests/method_definition_in_namespace.cc +++ b/tests/namespaces/method_definition.cc @@ -14,7 +14,7 @@ OUTPUT: "short_name": "Foo", "qualified_name": "hello::Foo", "declaration": null, - "definition": "tests/method_definition_in_namespace.cc:2:7", + "definition": "tests/namespaces/method_definition.cc:2:7", "parents": [], "derived": [], "types": [], @@ -26,8 +26,8 @@ OUTPUT: "id": 0, "short_name": "foo", "qualified_name": "hello::Foo::foo", - "declaration": "tests/method_definition_in_namespace.cc:3:8", - "definition": "tests/method_definition_in_namespace.cc:6:11", + "declaration": "tests/namespaces/method_definition.cc:3:8", + "definition": "tests/namespaces/method_definition.cc:6:11", "declaring_type": 0, "base": null, "derived": [], diff --git a/tests/method_inline_declaration_in_namespace.cc b/tests/namespaces/method_inline_declaration.cc similarity index 80% rename from tests/method_inline_declaration_in_namespace.cc rename to tests/namespaces/method_inline_declaration.cc index 2719943f..1f84442d 100644 --- a/tests/method_inline_declaration_in_namespace.cc +++ b/tests/namespaces/method_inline_declaration.cc @@ -12,7 +12,7 @@ OUTPUT: "short_name": "Foo", "qualified_name": "hello::Foo", "declaration": null, - "definition": "tests/method_inline_declaration_in_namespace.cc:2:7", + "definition": "tests/namespaces/method_inline_declaration.cc:2:7", "parents": [], "derived": [], "types": [], @@ -25,7 +25,7 @@ OUTPUT: "short_name": "foo", "qualified_name": "hello::Foo::foo", "declaration": null, - "definition": "tests/method_inline_declaration_in_namespace.cc:3:8", + "definition": "tests/namespaces/method_inline_declaration.cc:3:8", "declaring_type": 0, "base": null, "derived": [], diff --git a/tests/usage/func_usage_addr_func.cc b/tests/usage/func_usage_addr_func.cc new file mode 100644 index 00000000..a174f5f6 --- /dev/null +++ b/tests/usage/func_usage_addr_func.cc @@ -0,0 +1,79 @@ +void consume(void*) {} + +void used() {} + +void user() { + auto x = &used; + consume(&used); +} + +/* +OUTPUT: +{ + "types": [{ + "id": 0, + "short_name": "", + "qualified_name": "", + "declaration": null + }], + "functions": [{ + "id": 0, + "short_name": "consume", + "qualified_name": "consume", + "declaration": null, + "definition": "tests/usage/func_usage_addr_func.cc:1:6", + "declaring_type": null, + "base": null, + "derived": [], + "locals": [], + "callers": ["2@tests/usage/func_usage_addr_func.cc:7:3"], + "callees": [], + "uses": ["tests/usage/func_usage_addr_func.cc:7:3"] + }, { + "id": 1, + "short_name": "used", + "qualified_name": "used", + "declaration": null, + "definition": "tests/usage/func_usage_addr_func.cc:3:6", + "declaring_type": null, + "base": null, + "derived": [], + "locals": [], + "callers": ["2@tests/usage/func_usage_addr_func.cc:6:13", "2@tests/usage/func_usage_addr_func.cc:7:12"], + "callees": [], + "uses": ["tests/usage/func_usage_addr_func.cc:6:13", "tests/usage/func_usage_addr_func.cc:7:12"] + }, { + "id": 2, + "short_name": "user", + "qualified_name": "user", + "declaration": null, + "definition": "tests/usage/func_usage_addr_func.cc:5:6", + "declaring_type": null, + "base": null, + "derived": [], + "locals": [], + "callers": [], + "callees": ["1@tests/usage/func_usage_addr_func.cc:6:13", "0@tests/usage/func_usage_addr_func.cc:7:3", "1@tests/usage/func_usage_addr_func.cc:7:12"], + "uses": [] + }], + "variables": [{ + "id": 0, + "short_name": "", + "qualified_name": "", + "declaration": "tests/usage/func_usage_addr_func.cc:1:19", + "initializations": ["tests/usage/func_usage_addr_func.cc:1:19"], + "variable_type": 0, + "declaring_type": null, + "uses": [] + }, { + "id": 1, + "short_name": "x", + "qualified_name": "x", + "declaration": "tests/usage/func_usage_addr_func.cc:6:8", + "initializations": ["tests/usage/func_usage_addr_func.cc:6:8"], + "variable_type": 0, + "declaring_type": null, + "uses": [] + }] +} +*/ \ No newline at end of file diff --git a/tests/usage/func_usage_addr_method.cc b/tests/usage/func_usage_addr_method.cc new file mode 100644 index 00000000..4f70c7a9 --- /dev/null +++ b/tests/usage/func_usage_addr_method.cc @@ -0,0 +1,8 @@ +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/usage/func_usage_call_func.cc b/tests/usage/func_usage_call_func.cc new file mode 100644 index 00000000..4f70c7a9 --- /dev/null +++ b/tests/usage/func_usage_call_func.cc @@ -0,0 +1,8 @@ +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/usage/func_usage_call_method.cc b/tests/usage/func_usage_call_method.cc new file mode 100644 index 00000000..4f70c7a9 --- /dev/null +++ b/tests/usage/func_usage_call_method.cc @@ -0,0 +1,8 @@ +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/usage/func_usage_class_inline_var_def.cc b/tests/usage/func_usage_class_inline_var_def.cc new file mode 100644 index 00000000..4f70c7a9 --- /dev/null +++ b/tests/usage/func_usage_class_inline_var_def.cc @@ -0,0 +1,8 @@ +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/usage/func_usage_extern_func.cc b/tests/usage/func_usage_extern_func.cc new file mode 100644 index 00000000..4f70c7a9 --- /dev/null +++ b/tests/usage/func_usage_extern_func.cc @@ -0,0 +1,8 @@ +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/usage/func_usage_extern_method.cc b/tests/usage/func_usage_extern_method.cc new file mode 100644 index 00000000..4f70c7a9 --- /dev/null +++ b/tests/usage/func_usage_extern_method.cc @@ -0,0 +1,8 @@ +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/usage/type_usage_on_extern.cc b/tests/usage/type_usage_on_extern.cc new file mode 100644 index 00000000..4f70c7a9 --- /dev/null +++ b/tests/usage/type_usage_on_extern.cc @@ -0,0 +1,8 @@ +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/usage/type_usage_on_local.cc b/tests/usage/type_usage_on_local.cc new file mode 100644 index 00000000..4f70c7a9 --- /dev/null +++ b/tests/usage/type_usage_on_local.cc @@ -0,0 +1,8 @@ +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/usage/type_usage_on_parameter.cc b/tests/usage/type_usage_on_parameter.cc new file mode 100644 index 00000000..4f70c7a9 --- /dev/null +++ b/tests/usage/type_usage_on_parameter.cc @@ -0,0 +1,8 @@ +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/usage/type_usage_on_return_type.cc b/tests/usage/type_usage_on_return_type.cc new file mode 100644 index 00000000..4f70c7a9 --- /dev/null +++ b/tests/usage/type_usage_on_return_type.cc @@ -0,0 +1,8 @@ +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/usage/type_usage_on_static.cc b/tests/usage/type_usage_on_static.cc new file mode 100644 index 00000000..4f70c7a9 --- /dev/null +++ b/tests/usage/type_usage_on_static.cc @@ -0,0 +1,8 @@ +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/usage/var_usage_class_member.cc b/tests/usage/var_usage_class_member.cc new file mode 100644 index 00000000..4f70c7a9 --- /dev/null +++ b/tests/usage/var_usage_class_member.cc @@ -0,0 +1,8 @@ +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/usage/var_usage_extern.cc b/tests/usage/var_usage_extern.cc new file mode 100644 index 00000000..4f70c7a9 --- /dev/null +++ b/tests/usage/var_usage_extern.cc @@ -0,0 +1,8 @@ +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/usage/var_usage_func_parameter.cc b/tests/usage/var_usage_func_parameter.cc new file mode 100644 index 00000000..4f70c7a9 --- /dev/null +++ b/tests/usage/var_usage_func_parameter.cc @@ -0,0 +1,8 @@ +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/usage/var_usage_local.cc b/tests/usage/var_usage_local.cc new file mode 100644 index 00000000..4f70c7a9 --- /dev/null +++ b/tests/usage/var_usage_local.cc @@ -0,0 +1,8 @@ +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/usage/var_usage_shadowed_class_member.cc b/tests/usage/var_usage_shadowed_class_member.cc new file mode 100644 index 00000000..4f70c7a9 --- /dev/null +++ b/tests/usage/var_usage_shadowed_class_member.cc @@ -0,0 +1,8 @@ +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/usage/var_usage_shadowed_local.cc b/tests/usage/var_usage_shadowed_local.cc new file mode 100644 index 00000000..4f70c7a9 --- /dev/null +++ b/tests/usage/var_usage_shadowed_local.cc @@ -0,0 +1,8 @@ +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/usage/var_usage_shadowed_parameter.cc b/tests/usage/var_usage_shadowed_parameter.cc new file mode 100644 index 00000000..4f70c7a9 --- /dev/null +++ b/tests/usage/var_usage_shadowed_parameter.cc @@ -0,0 +1,8 @@ +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/usage/var_usage_static.cc b/tests/usage/var_usage_static.cc new file mode 100644 index 00000000..4f70c7a9 --- /dev/null +++ b/tests/usage/var_usage_static.cc @@ -0,0 +1,8 @@ +/* +OUTPUT: +{ + "types": [], + "functions": [], + "variables": [] +} +*/ \ No newline at end of file diff --git a/tests/vars/class_member.cc b/tests/vars/class_member.cc index e49d2122..4deaf0dc 100644 --- a/tests/vars/class_member.cc +++ b/tests/vars/class_member.cc @@ -4,8 +4,34 @@ class Foo { /* OUTPUT: { - "types": [], + "types": [{ + "id": 0, + "short_name": "Foo", + "qualified_name": "Foo", + "declaration": null, + "definition": "tests/vars/class_member.cc:1:7", + "parents": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [0], + "uses": [] + }, { + "id": 1, + "short_name": "", + "qualified_name": "", + "declaration": null + }], "functions": [], - "variables": [] + "variables": [{ + "id": 0, + "short_name": "member", + "qualified_name": "Foo::member", + "declaration": "tests/vars/class_member.cc:2:7", + "initializations": ["tests/vars/class_member.cc:2:7"], + "variable_type": 1, + "declaring_type": 0, + "uses": [] + }] } */ \ No newline at end of file diff --git a/tests/vars/class_static_member.cc b/tests/vars/class_static_member.cc index 56daa2fa..0580dc17 100644 --- a/tests/vars/class_static_member.cc +++ b/tests/vars/class_static_member.cc @@ -1,8 +1,38 @@ +class Foo { + static int member; +}; +int Foo::member = 0; /* OUTPUT: { -"types": [], -"functions": [], -"variables": [] + "types": [{ + "id": 0, + "short_name": "Foo", + "qualified_name": "Foo", + "declaration": null, + "definition": "tests/vars/class_static_member.cc:1:7", + "parents": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [0], + "uses": [] + }, { + "id": 1, + "short_name": "", + "qualified_name": "", + "declaration": null + }], + "functions": [], + "variables": [{ + "id": 0, + "short_name": "member", + "qualified_name": "Foo::member", + "declaration": "tests/vars/class_static_member.cc:2:14", + "initializations": ["tests/vars/class_static_member.cc:4:10"], + "variable_type": 1, + "declaring_type": 0, + "uses": [] + }] } */ \ No newline at end of file diff --git a/tests/vars/class_static_member_decl_only.cc b/tests/vars/class_static_member_decl_only.cc index 56daa2fa..e470fa31 100644 --- a/tests/vars/class_static_member_decl_only.cc +++ b/tests/vars/class_static_member_decl_only.cc @@ -1,8 +1,32 @@ +class Foo { + static int member; +}; /* OUTPUT: { -"types": [], -"functions": [], -"variables": [] + "types": [{ + "id": 0, + "short_name": "Foo", + "qualified_name": "Foo", + "declaration": null, + "definition": "tests/vars/class_static_member_decl_only.cc:1:7", + "parents": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [0], + "uses": [] + }], + "functions": [], + "variables": [{ + "id": 0, + "short_name": "member", + "qualified_name": "Foo::member", + "declaration": "tests/vars/class_static_member_decl_only.cc:2:14", + "initializations": [], + "variable_type": null, + "declaring_type": 0, + "uses": [] + }] } */ \ No newline at end of file diff --git a/tests/vars/function_local.cc b/tests/vars/function_local.cc index 56daa2fa..8ef4601b 100644 --- a/tests/vars/function_local.cc +++ b/tests/vars/function_local.cc @@ -1,8 +1,38 @@ +void foo() { + int a; +} /* OUTPUT: { -"types": [], -"functions": [], -"variables": [] + "types": [{ + "id": 0, + "short_name": "", + "qualified_name": "", + "declaration": null + }], + "functions": [{ + "id": 0, + "short_name": "foo", + "qualified_name": "foo", + "declaration": null, + "definition": "tests/vars/function_local.cc:1:6", + "declaring_type": null, + "base": null, + "derived": [], + "locals": [], + "callers": [], + "callees": [], + "uses": [] + }], + "variables": [{ + "id": 0, + "short_name": "a", + "qualified_name": "a", + "declaration": "tests/vars/function_local.cc:2:7", + "initializations": ["tests/vars/function_local.cc:2:7"], + "variable_type": 0, + "declaring_type": null, + "uses": [] + }] } */ \ No newline at end of file diff --git a/tests/vars/function_param.cc b/tests/vars/function_param.cc index 56daa2fa..acde6098 100644 --- a/tests/vars/function_param.cc +++ b/tests/vars/function_param.cc @@ -1,8 +1,45 @@ +void foo(int p0, int p1) {} /* OUTPUT: { -"types": [], -"functions": [], -"variables": [] + "types": [{ + "id": 0, + "short_name": "", + "qualified_name": "", + "declaration": null + }], + "functions": [{ + "id": 0, + "short_name": "foo", + "qualified_name": "foo", + "declaration": null, + "definition": "tests/vars/function_param.cc:1:6", + "declaring_type": null, + "base": null, + "derived": [], + "locals": [], + "callers": [], + "callees": [], + "uses": [] + }], + "variables": [{ + "id": 0, + "short_name": "p0", + "qualified_name": "p0", + "declaration": "tests/vars/function_param.cc:1:14", + "initializations": ["tests/vars/function_param.cc:1:14"], + "variable_type": 0, + "declaring_type": null, + "uses": [] + }, { + "id": 1, + "short_name": "p1", + "qualified_name": "p1", + "declaration": "tests/vars/function_param.cc:1:22", + "initializations": ["tests/vars/function_param.cc:1:22"], + "variable_type": 0, + "declaring_type": null, + "uses": [] + }] } */ \ No newline at end of file diff --git a/tests/vars/function_param_unnamed.cc b/tests/vars/function_param_unnamed.cc new file mode 100644 index 00000000..6aa7d673 --- /dev/null +++ b/tests/vars/function_param_unnamed.cc @@ -0,0 +1,48 @@ +void foo(int, int) {} +/* +// TODO: We should probably not emit variables for unnamed variables. But we +// still need to emit reference information. + +OUTPUT: +{ + "types": [{ + "id": 0, + "short_name": "", + "qualified_name": "", + "declaration": null + }], + "functions": [{ + "id": 0, + "short_name": "foo", + "qualified_name": "foo", + "declaration": null, + "definition": "tests/vars/function_param.cc:1:6", + "declaring_type": null, + "base": null, + "derived": [], + "locals": [], + "callers": [], + "callees": [], + "uses": [] + }], + "variables": [{ + "id": 0, + "short_name": "p0", + "qualified_name": "p0", + "declaration": "tests/vars/function_param.cc:1:14", + "initializations": ["tests/vars/function_param.cc:1:14"], + "variable_type": 0, + "declaring_type": null, + "uses": [] + }, { + "id": 1, + "short_name": "p1", + "qualified_name": "p1", + "declaration": "tests/vars/function_param.cc:1:22", + "initializations": ["tests/vars/function_param.cc:1:22"], + "variable_type": 0, + "declaring_type": null, + "uses": [] + }] +} +*/ \ No newline at end of file diff --git a/tests/vars/function_shadow_local.cc b/tests/vars/function_shadow_local.cc index 56daa2fa..39d8d666 100644 --- a/tests/vars/function_shadow_local.cc +++ b/tests/vars/function_shadow_local.cc @@ -1,8 +1,50 @@ +void foo() { + int a; + { + int a; + } +} /* OUTPUT: { -"types": [], -"functions": [], -"variables": [] + "types": [{ + "id": 0, + "short_name": "", + "qualified_name": "", + "declaration": null + }], + "functions": [{ + "id": 0, + "short_name": "foo", + "qualified_name": "foo", + "declaration": null, + "definition": "tests/vars/function_shadow_local.cc:1:6", + "declaring_type": null, + "base": null, + "derived": [], + "locals": [], + "callers": [], + "callees": [], + "uses": [] + }], + "variables": [{ + "id": 0, + "short_name": "a", + "qualified_name": "a", + "declaration": "tests/vars/function_shadow_local.cc:2:7", + "initializations": ["tests/vars/function_shadow_local.cc:2:7"], + "variable_type": 0, + "declaring_type": null, + "uses": [] + }, { + "id": 1, + "short_name": "a", + "qualified_name": "a", + "declaration": "tests/vars/function_shadow_local.cc:4:9", + "initializations": ["tests/vars/function_shadow_local.cc:4:9"], + "variable_type": 0, + "declaring_type": null, + "uses": [] + }] } */ \ No newline at end of file diff --git a/tests/vars/function_shadow_param.cc b/tests/vars/function_shadow_param.cc index 56daa2fa..4ff7a5dd 100644 --- a/tests/vars/function_shadow_param.cc +++ b/tests/vars/function_shadow_param.cc @@ -1,8 +1,47 @@ +void foo(int p) { + int p = 0; +} /* OUTPUT: { -"types": [], -"functions": [], -"variables": [] + "types": [{ + "id": 0, + "short_name": "", + "qualified_name": "", + "declaration": null + }], + "functions": [{ + "id": 0, + "short_name": "foo", + "qualified_name": "foo", + "declaration": null, + "definition": "tests/vars/function_shadow_param.cc:1:6", + "declaring_type": null, + "base": null, + "derived": [], + "locals": [], + "callers": [], + "callees": [], + "uses": [] + }], + "variables": [{ + "id": 0, + "short_name": "p", + "qualified_name": "p", + "declaration": "tests/vars/function_shadow_param.cc:1:14", + "initializations": ["tests/vars/function_shadow_param.cc:1:14"], + "variable_type": 0, + "declaring_type": null, + "uses": [] + }, { + "id": 1, + "short_name": "p", + "qualified_name": "p", + "declaration": "tests/vars/function_shadow_param.cc:2:7", + "initializations": ["tests/vars/function_shadow_param.cc:2:7"], + "variable_type": 0, + "declaring_type": null, + "uses": [] + }] } */ \ No newline at end of file diff --git a/tests/vars/global_variable.cc b/tests/vars/global_variable.cc index 56daa2fa..43e7f826 100644 --- a/tests/vars/global_variable.cc +++ b/tests/vars/global_variable.cc @@ -1,8 +1,23 @@ +static int global = 0; /* OUTPUT: { -"types": [], -"functions": [], -"variables": [] + "types": [{ + "id": 0, + "short_name": "", + "qualified_name": "", + "declaration": null + }], + "functions": [], + "variables": [{ + "id": 0, + "short_name": "global", + "qualified_name": "global", + "declaration": "tests/vars/global_variable.cc:1:12", + "initializations": ["tests/vars/global_variable.cc:1:12"], + "variable_type": 0, + "declaring_type": null, + "uses": [] + }] } */ \ No newline at end of file diff --git a/tests/vars/global_variable_decl_only.cc b/tests/vars/global_variable_decl_only.cc index 56daa2fa..6fb38349 100644 --- a/tests/vars/global_variable_decl_only.cc +++ b/tests/vars/global_variable_decl_only.cc @@ -1,8 +1,18 @@ +extern int global; /* OUTPUT: { -"types": [], -"functions": [], -"variables": [] + "types": [], + "functions": [], + "variables": [{ + "id": 0, + "short_name": "global", + "qualified_name": "global", + "declaration": "tests/vars/global_variable_decl_only.cc:1:12", + "initializations": [], + "variable_type": null, + "declaring_type": null, + "uses": [] + }] } */ \ No newline at end of file