diff --git a/bin/test/data/log/test_log.txt b/bin/test/data/log/test_log.txt index 41b51725..2bfb2e81 100644 --- a/bin/test/data/log/test_log.txt +++ b/bin/test/data/log/test_log.txt @@ -1,25 +1,4 @@ ConfigManager.cpp ERROR: value path/to/nowhere is not present in config. -Token.cpp ERROR: Location Id was not referenced by this Token. -Node.cpp WARNING: Cannot change NodeType after it was already set from namespace to class -Edge.cpp ERROR: Nodes are not plain copies. -Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined -Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined -Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined -Storage.cpp INFO: class: A -Storage.cpp INFO: method: A::A -Storage.cpp INFO: global usage: A::A -> A::count -Storage.cpp INFO: method: A::getCount -Storage.cpp INFO: global usage: A::getCount -> A::count -Storage.cpp INFO: method: A::process -Storage.cpp INFO: field: A::count -Storage.cpp INFO: class: B -Storage.cpp INFO: inheritance: B : A -Storage.cpp INFO: method: B::process -Storage.cpp INFO: type usage: B::process -> int -Storage.cpp INFO: function: main -Storage.cpp INFO: type usage: main -> B -Storage.cpp INFO: call: main -> B::B -Storage.cpp INFO: call: main -> A::getCount Storage.cpp INFO: class: A Storage.cpp INFO: method: A::A Storage.cpp INFO: global usage: A::A -> A::count @@ -52,6 +31,27 @@ SearchMatch.cpp INFO: 237 A::A ^^^^ +Storage.cpp INFO: class: A +Storage.cpp INFO: method: A::A +Storage.cpp INFO: global usage: A::A -> A::count +Storage.cpp INFO: method: A::getCount +Storage.cpp INFO: global usage: A::getCount -> A::count +Storage.cpp INFO: method: A::process +Storage.cpp INFO: field: A::count +Storage.cpp INFO: class: B +Storage.cpp INFO: inheritance: B : A +Storage.cpp INFO: method: B::process +Storage.cpp INFO: type usage: B::process -> int +Storage.cpp INFO: function: main +Storage.cpp INFO: type usage: main -> B +Storage.cpp INFO: call: main -> B::B +Storage.cpp INFO: call: main -> A::getCount +Token.cpp ERROR: Location Id was not referenced by this Token. +Node.cpp WARNING: Cannot change NodeType after it was already set from namespace to class +Edge.cpp ERROR: Nodes are not plain copies. +Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined +Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined +Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined Settings.cpp WARNING: File for Settings not found. ConfigManager.cpp ERROR: value Bool is not present in config. ConfigManager.cpp ERROR: value Int is not present in config. @@ -67,6 +67,7 @@ ConfigManager.cpp ERROR: value Int is not present in config. ConfigManager.cpp ERROR: value Float is not present in config. ConfigManager.cpp ERROR: value String is not present in config. ConfigManager.cpp ERROR: value NewBool is not present in config. +Graph.cpp ERROR: Can't remove member edge, without removing the child node. Storage.cpp INFO: typedef: type -> int Storage.cpp INFO: class: Class Storage.cpp INFO: struct: Struct @@ -119,7 +120,6 @@ Storage.cpp INFO: call: main -> isTrue Storage.cpp INFO: function: isTrue Storage.cpp INFO: function: main Storage.cpp INFO: call: main -> isTrue -Graph.cpp ERROR: Can't remove member edge, without removing the child node. TextAccess.cpp WARNING: Index 'firstLine' has to be lower or equal index 'lastLine', is 3 > 2 TextAccess.cpp WARNING: Tried to access index 10. Maximum index is 8 TextAccess.cpp WARNING: Tried to access index 10. Maximum index is 8 diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index e4e46d37..f0e86fc3 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -412,6 +412,20 @@ Id Storage::onGlobalVariableUsageParsed( // or static variable used return onVariableUsageParsed("global usage", location, user, usedNameHierarchy); } +Id Storage::onGlobalVariableUsageParsed( + const ParseLocation& location, const ParseVariable& user, const std::vector& usedNameHierarchy) +{ + log("global usage", user.getFullName() + " -> " + utility::join(usedNameHierarchy, "::"), location); + + Node* userNode = addNodeHierarchy(Node::NODE_UNDEFINED_VARIABLE, user.nameHierarchy); + Node* usedNode = addNodeHierarchy(Node::NODE_UNDEFINED_VARIABLE, usedNameHierarchy); + + Edge* edge = m_graph.createEdge(Edge::EDGE_USAGE, userNode, usedNode); + addTokenLocation(edge, location); + + return edge->getId(); +} + Id Storage::onEnumFieldUsageParsed( const ParseLocation& location, const ParseFunction& user, const std::vector& usedNameHierarchy ){ diff --git a/src/lib/data/Storage.h b/src/lib/data/Storage.h index 057b013a..1fd233e2 100644 --- a/src/lib/data/Storage.h +++ b/src/lib/data/Storage.h @@ -74,6 +74,8 @@ public: const ParseLocation& location, const ParseFunction& user, const std::vector& usedNameHierarchy); virtual Id onGlobalVariableUsageParsed( const ParseLocation& location, const ParseFunction& user, const std::vector& usedNameHierarchy); + virtual Id onGlobalVariableUsageParsed( + const ParseLocation& location, const ParseVariable& user, const std::vector& usedNameHierarchy); virtual Id onEnumFieldUsageParsed( const ParseLocation& location, const ParseFunction& user, const std::vector& usedNameHierarchy); virtual Id onEnumFieldUsageParsed( diff --git a/src/lib/data/parser/ParserClient.h b/src/lib/data/parser/ParserClient.h index b52a7668..33a0f277 100644 --- a/src/lib/data/parser/ParserClient.h +++ b/src/lib/data/parser/ParserClient.h @@ -90,6 +90,8 @@ public: const ParseLocation& location, const ParseFunction& user, const std::vector& usedNameHierarchy) = 0; virtual Id onGlobalVariableUsageParsed( const ParseLocation& location, const ParseFunction& user, const std::vector& usedNameHierarchy) = 0; + virtual Id onGlobalVariableUsageParsed( + const ParseLocation& location, const ParseVariable& user, const std::vector& usedNameHierarchy) = 0; virtual Id onEnumFieldUsageParsed( const ParseLocation& location, const ParseFunction& user, const std::vector& usedNameHierarchy) = 0; virtual Id onEnumFieldUsageParsed( diff --git a/src/lib/data/parser/cxx/ASTBodyVisitor.cpp b/src/lib/data/parser/cxx/ASTBodyVisitor.cpp index 2c4408e8..ff2c2ceb 100644 --- a/src/lib/data/parser/cxx/ASTBodyVisitor.cpp +++ b/src/lib/data/parser/cxx/ASTBodyVisitor.cpp @@ -89,7 +89,14 @@ void ASTBodyVisitor::VisitDeclRefExpr(clang::make_ptr::type { if (expr->getDecl()->getKind() == clang::Decl::Var && expr->getDecl()->isDefinedOutsideFunctionOrMethod()) { - m_client->VisitGlobalVariableExprInDeclBody(m_functionDecl, expr); + if (m_functionDecl) + { + m_client->VisitGlobalVariableExprInDeclBody(m_functionDecl, expr); + } + else + { + m_client->VisitGlobalVariableExprInDeclBody(m_varDecl, expr); + } } else if (expr->getDecl()->getKind() == clang::Decl::EnumConstant) { diff --git a/src/lib/data/parser/cxx/ASTBodyVisitorClient.h b/src/lib/data/parser/cxx/ASTBodyVisitorClient.h index 7743d5df..48bd1fe5 100644 --- a/src/lib/data/parser/cxx/ASTBodyVisitorClient.h +++ b/src/lib/data/parser/cxx/ASTBodyVisitorClient.h @@ -19,6 +19,7 @@ public: virtual void VisitCXXNewExprInDeclBody(clang::VarDecl* decl, clang::CXXNewExpr* expr) = 0; virtual void VisitMemberExprInDeclBody(clang::FunctionDecl* decl, clang::MemberExpr* expr) = 0; virtual void VisitGlobalVariableExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr) = 0; + virtual void VisitGlobalVariableExprInDeclBody(clang::VarDecl* decl, clang::DeclRefExpr* expr) = 0; virtual void VisitEnumExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr) = 0; virtual void VisitEnumExprInDeclBody(clang::VarDecl* decl, clang::DeclRefExpr* expr) = 0; virtual void VisitVarDeclInDeclBody(clang::FunctionDecl* decl, clang::VarDecl* varDecl) = 0; diff --git a/src/lib/data/parser/cxx/ASTVisitor.cpp b/src/lib/data/parser/cxx/ASTVisitor.cpp index b3e4b9af..cba0f003 100644 --- a/src/lib/data/parser/cxx/ASTVisitor.cpp +++ b/src/lib/data/parser/cxx/ASTVisitor.cpp @@ -554,6 +554,20 @@ void ASTVisitor::VisitGlobalVariableExprInDeclBody(clang::FunctionDecl* decl, cl ); } +void ASTVisitor::VisitGlobalVariableExprInDeclBody(clang::VarDecl* decl, clang::DeclRefExpr* expr) +{ + ParseLocation parseLocation = getParseLocation(expr->getSourceRange()); + + const std::string exprName = expr->getNameInfo().getAsString(); + parseLocation.endColumnNumber += exprName.size() - 1; + + m_client->onGlobalVariableUsageParsed( + parseLocation, + getParseVariable(decl), + utility::getDeclNameHierarchy(expr->getDecl()) + ); +} + void ASTVisitor::VisitEnumExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr) { ParseLocation parseLocation = getParseLocation(expr->getSourceRange()); diff --git a/src/lib/data/parser/cxx/ASTVisitor.h b/src/lib/data/parser/cxx/ASTVisitor.h index 32b684e7..f4ca6361 100644 --- a/src/lib/data/parser/cxx/ASTVisitor.h +++ b/src/lib/data/parser/cxx/ASTVisitor.h @@ -50,6 +50,7 @@ public: virtual void VisitCXXNewExprInDeclBody(clang::VarDecl* decl, clang::CXXNewExpr* expr); // type use of new operator in global space virtual void VisitMemberExprInDeclBody(clang::FunctionDecl* decl, clang::MemberExpr* expr); // field usages virtual void VisitGlobalVariableExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr); // global variable usage + virtual void VisitGlobalVariableExprInDeclBody(clang::VarDecl* decl, clang::DeclRefExpr* expr); // global variable usage virtual void VisitEnumExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr); // enum field usage virtual void VisitEnumExprInDeclBody(clang::VarDecl* decl, clang::DeclRefExpr* expr); // enum field usage in global variable virtual void VisitVarDeclInDeclBody(clang::FunctionDecl* decl, clang::VarDecl* varDecl); // type usages diff --git a/src/test/CxxParserTestSuite.h b/src/test/CxxParserTestSuite.h index f2735de2..a8caf8b9 100644 --- a/src/test/CxxParserTestSuite.h +++ b/src/test/CxxParserTestSuite.h @@ -875,6 +875,17 @@ public: TS_ASSERT_EQUALS(client->usages[0], "int main() -> bar <5:2 5:4>"); } + void test_cxx_parser_finds_usage_of_global_variable_in_global_variable_initialization() + { + std::shared_ptr client = parseCode( + "int a = 0;\n" + "int b[] = {a};\n" + ); + + TS_ASSERT_EQUALS(client->usages.size(), 1); + TS_ASSERT_EQUALS(client->usages[0], "int [] b -> a <2:12 2:12>"); + } + void test_cxx_parser_finds_usage_of_global_variable_in_method() { std::shared_ptr client = parseCode( @@ -1692,6 +1703,13 @@ private: return 0; } + virtual Id onGlobalVariableUsageParsed( + const ParseLocation& location, const ParseVariable& user, const std::vector& usedNameHierarchy) + { + usages.push_back(addLocationSuffix(variableStr(user) + " -> " + utility::join(usedNameHierarchy, "::"), location)); + return 0; + } + virtual Id onEnumFieldUsageParsed( const ParseLocation& location, const ParseFunction& user, const std::vector& usedNameHierarchy) {