diff --git a/src/lib/data/parser/ParserClient.h b/src/lib/data/parser/ParserClient.h index 13a3fbd1..7bc982e4 100644 --- a/src/lib/data/parser/ParserClient.h +++ b/src/lib/data/parser/ParserClient.h @@ -4,10 +4,10 @@ #include #include -#include "utility/types.h" +#include "data/graph/Node.h" #include "data/name/NameHierarchy.h" - #include "utility/file/FileInfo.h" +#include "utility/types.h" struct ParseLocation; class DataType; @@ -85,12 +85,8 @@ public: const ParseLocation& location, const NameHierarchy& overridden, const NameHierarchy& overrider) = 0; virtual Id onCallParsed( const ParseLocation& location, const NameHierarchy& caller, const NameHierarchy& callee) = 0; - virtual Id onFieldUsageParsed( - const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy) = 0; - virtual Id onGlobalVariableUsageParsed( - const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy) = 0; - virtual Id onEnumConstantUsageParsed( - const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy) = 0; + virtual Id onUsageParsed( + const ParseLocation& location, const NameHierarchy& userName, Node::NodeType usedType, const NameHierarchy& usedName) = 0; virtual Id onTypeUsageParsed(const ParseLocation& location, const NameHierarchy& user, const NameHierarchy& used) = 0; virtual Id onTemplateArgumentTypeParsed( diff --git a/src/lib/data/parser/ParserClientImpl.cpp b/src/lib/data/parser/ParserClientImpl.cpp index 27bd9830..01ac7f4c 100644 --- a/src/lib/data/parser/ParserClientImpl.cpp +++ b/src/lib/data/parser/ParserClientImpl.cpp @@ -239,39 +239,13 @@ Id ParserClientImpl::onCallParsed(const ParseLocation& location, const NameHiera return edgeId; } -Id ParserClientImpl::onFieldUsageParsed( - const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy) +Id ParserClientImpl::onUsageParsed( + const ParseLocation& location, const NameHierarchy& userName, Node::NodeType usedType, const NameHierarchy& usedName) { - log("field usage", userNameHierarchy.getQualifiedNameWithSignature() + " -> " + usedNameHierarchy.getQualifiedName(), location); + log("usage", userName.getQualifiedNameWithSignature() + " -> " + usedName.getQualifiedName(), location); - Id userNodeId = addNodeHierarchy(Node::NODE_FUNCTION, userNameHierarchy, DEFINITION_NONE); - Id usedNodeId = addNodeHierarchy(Node::NODE_FIELD, usedNameHierarchy, DEFINITION_NONE); - Id edgeId = addEdge(Edge::EDGE_USAGE, userNodeId, usedNodeId); - addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN)); - - return edgeId; -} - -Id ParserClientImpl::onGlobalVariableUsageParsed( // or static variable used - const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy) -{ - log("global usage", userNameHierarchy.getQualifiedNameWithSignature() + " -> " + usedNameHierarchy.getQualifiedNameWithSignature(), location); - - Id userNodeId = addNodeHierarchy(Node::NODE_FUNCTION, userNameHierarchy, DEFINITION_NONE); - Id usedNodeId = addNodeHierarchy(Node::NODE_GLOBAL_VARIABLE, usedNameHierarchy, DEFINITION_NONE); - Id edgeId = addEdge(Edge::EDGE_USAGE, userNodeId, usedNodeId); - addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN)); - - return edgeId; -} - -Id ParserClientImpl::onEnumConstantUsageParsed( - const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy) -{ - log("enum constant usage", userNameHierarchy.getQualifiedNameWithSignature() + " -> " + usedNameHierarchy.getQualifiedNameWithSignature(), location); - - Id userNodeId = addNodeHierarchy(Node::NODE_UNDEFINED, userNameHierarchy, DEFINITION_NONE); - Id usedNodeId = addNodeHierarchy(Node::NODE_ENUM_CONSTANT, usedNameHierarchy, DEFINITION_NONE); + Id userNodeId = addNodeHierarchy(Node::NODE_UNDEFINED, userName, DEFINITION_NONE); + Id usedNodeId = addNodeHierarchy(usedType, usedName, DEFINITION_NONE); Id edgeId = addEdge(Edge::EDGE_USAGE, userNodeId, usedNodeId); addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN)); diff --git a/src/lib/data/parser/ParserClientImpl.h b/src/lib/data/parser/ParserClientImpl.h index c8b986f8..66ce3038 100644 --- a/src/lib/data/parser/ParserClientImpl.h +++ b/src/lib/data/parser/ParserClientImpl.h @@ -58,12 +58,8 @@ public: const ParseLocation& location, const NameHierarchy& overridden, const NameHierarchy& overrider); virtual Id onCallParsed( const ParseLocation& location, const NameHierarchy& caller, const NameHierarchy& callee); - virtual Id onFieldUsageParsed( - const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy); - virtual Id onGlobalVariableUsageParsed( - const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy); - virtual Id onEnumConstantUsageParsed( - const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy); + virtual Id onUsageParsed( + const ParseLocation& location, const NameHierarchy& userName, Node::NodeType usedType, const NameHierarchy& usedName); virtual Id onTypeUsageParsed(const ParseLocation& location, const NameHierarchy& user, const NameHierarchy& used); virtual Id onTemplateArgumentTypeParsed( diff --git a/src/lib_parser/data/parser/cxx/ASTVisitor.cpp b/src/lib_parser/data/parser/cxx/ASTVisitor.cpp index 3c74b727..b2a3da1a 100644 --- a/src/lib_parser/data/parser/cxx/ASTVisitor.cpp +++ b/src/lib_parser/data/parser/cxx/ASTVisitor.cpp @@ -1158,6 +1158,24 @@ void ASTVisitor::RecordDeclRef( bool fallback = false; + + if (symbolType == ST_LocalVariable || symbolType == ST_Parameter) + { + if (clang::VarDecl* varDecl = clang::dyn_cast(d)) + { + ParseLocation declLocation = getParseLocation(varDecl->getSourceRange()); + std::string name = + declLocation.filePath.str() + "::" + + varDecl->getNameAsString() + "<" + + std::to_string(declLocation.startLineNumber) + ":" + + std::to_string(declLocation.startColumnNumber) + ">"; + m_client->onLocalSymbolParsed( + name, + parseLocation); + } + return; + } + switch (refType) { case RT_Declaration: @@ -1303,21 +1321,6 @@ void ASTVisitor::RecordDeclRef( declIsImplicit); } break; - case ST_LocalVariable: - case ST_Parameter: - if (clang::VarDecl* varDecl = clang::dyn_cast(d)) - { - ParseLocation declLocation = getParseLocation(varDecl->getSourceRange()); // i think we dont need this since this is the decl/def - std::string name = - declLocation.filePath.str() + "::" + - varDecl->getNameAsString() + "<" + - std::to_string(declLocation.startLineNumber) + ":" + - std::to_string(declLocation.startColumnNumber) + ">"; - m_client->onLocalSymbolParsed( - name, - parseLocation); - } - break; default: fallback = true; break; @@ -1353,91 +1356,85 @@ void ASTVisitor::RecordDeclRef( } break; } - default: + case RT_TemplateArgument: { const NameHierarchy contextNameHierarchy = getContextName(); + m_client->onTemplateArgumentTypeParsed( + parseLocation, declNameHierarchy, contextNameHierarchy); + break; + } + + case RT_Called: + { + const NameHierarchy contextNameHierarchy = getContextName(); + m_client->onCallParsed( + parseLocation, contextNameHierarchy, declNameHierarchy); + break; + } + case RT_Reference: + { + const NameHierarchy contextNameHierarchy = getContextName(); + m_client->onTypeUsageParsed( + parseLocation, contextNameHierarchy, declNameHierarchy); + break; + } + case RT_TemplateDefaultArgument: + { + const NameHierarchy contextNameHierarchy = getContextName(); + m_client->onTemplateDefaultArgumentTypeParsed( + parseLocation, declNameHierarchy, contextNameHierarchy); + break; + } + case RT_BaseClass: + { + const NameHierarchy contextNameHierarchy = getContextName(); + m_client->onInheritanceParsed( + parseLocation, contextNameHierarchy, declNameHierarchy, m_contextAccess); + break; + } + case RT_Assigned: + case RT_Read: + case RT_Initialized: + case RT_Modified: + case RT_Other: + case RT_AddressTaken: + { + const NameHierarchy contextNameHierarchy = getContextName(); + Node::NodeType usedType = Node::NODE_UNDEFINED; switch (symbolType) { case ST_Field: - m_client->onFieldUsageParsed( - parseLocation, - contextNameHierarchy, - declNameHierarchy - ); + usedType = Node::NODE_FIELD; break; case ST_GlobalVariable: - if (refType == RT_TemplateArgument) - { - m_client->onTemplateArgumentTypeParsed( - parseLocation, declNameHierarchy, contextNameHierarchy); - } - else - { - m_client->onGlobalVariableUsageParsed( - parseLocation, - contextNameHierarchy, - declNameHierarchy); - } + usedType = Node::NODE_GLOBAL_VARIABLE; break; case ST_Enumerator: - m_client->onEnumConstantUsageParsed( - parseLocation, - contextNameHierarchy, - declNameHierarchy); + usedType = Node::NODE_ENUM_CONSTANT; break; - case ST_LocalVariable: - case ST_Parameter: - if (clang::VarDecl* varDecl = clang::dyn_cast(d)) - { - ParseLocation declLocation = getParseLocation(varDecl->getSourceRange()); // i think we dont need this since this is the decl/def - std::string name = - declLocation.filePath.str() + "::" + - varDecl->getNameAsString() + "<" + - std::to_string(declLocation.startLineNumber) + ":" + - std::to_string(declLocation.startColumnNumber) + ">"; - m_client->onLocalSymbolParsed( - name, - parseLocation); - } + case ST_Function: + usedType = Node::NODE_FUNCTION; break; - case ST_Max: - switch (refType) - { - case RT_Called: - m_client->onCallParsed( - parseLocation, contextNameHierarchy, declNameHierarchy); - break; - case RT_Reference: - m_client->onTypeUsageParsed( - parseLocation, contextNameHierarchy, declNameHierarchy); - break; - case RT_TemplateArgument: - m_client->onTemplateArgumentTypeParsed( - parseLocation, declNameHierarchy, contextNameHierarchy); - break; - case RT_TemplateDefaultArgument: - m_client->onTemplateDefaultArgumentTypeParsed( - parseLocation, declNameHierarchy, contextNameHierarchy); - break; - case RT_BaseClass: - m_client->onInheritanceParsed( - parseLocation, contextNameHierarchy, declNameHierarchy, m_contextAccess); - break; - case RT_Assigned: - case RT_AddressTaken: - case RT_Read: - case RT_Qualifier: - // Do nothing. - break; - default: - fallback = true; - break; - } - break; - default: - fallback = true; + case ST_Method: + usedType = Node::NODE_METHOD; break; } + + m_client->onUsageParsed( + parseLocation, + contextNameHierarchy, + usedType, + declNameHierarchy + ); + break; + } + case RT_Qualifier: + // Do nothing. + break; + default: + { + fallback = true; + break; } } diff --git a/src/test/CxxParserTestSuite.h b/src/test/CxxParserTestSuite.h index 65a8b86e..15a453fe 100644 --- a/src/test/CxxParserTestSuite.h +++ b/src/test/CxxParserTestSuite.h @@ -1284,7 +1284,7 @@ public: TS_ASSERT_EQUALS(client->calls[0], "int main() -> int sum(int, int) <7:2 7:4>"); } - void test_cxx_parser_finds_call_in_function_with_right_signature() + void test_cxx_parser_finds_call_in_function_with_correct_signature() { std::shared_ptr client = parseCode( "int sum(int a, int b)\n" @@ -1509,6 +1509,24 @@ public: TS_ASSERT_EQUALS(client->calls[1], "int main() -> void App::operator+(int) <11:6 11:6>"); } + void test_cxx_parser_finds_usage_of_function_pointer() + { + std::shared_ptr client = parseCode( + "void my_int_func(int x)\n" + "{\n" + "}\n" + "\n" + "void test()\n" + "{\n" + " void (*foo)(int);\n" + " foo = &my_int_func;\n" + "}\n" + ); + + TS_ASSERT_EQUALS(client->usages.size(), 1); + TS_ASSERT_EQUALS(client->usages[0], "void test() -> my_int_func <8:9 8:19>"); + } + void test_cxx_parser_finds_usage_of_global_variable_in_function() { std::shared_ptr client = parseCode( @@ -2946,6 +2964,15 @@ private: return 0; } + virtual Id onTemplateParameterTypeParsed( + const ParseLocation& location, const NameHierarchy& templateParameterTypeNameHierarchy, bool isImplicit) + { + templateParameterTypes.push_back( + addLocationSuffix(templateParameterTypeNameHierarchy.getQualifiedName(), location) + ); + return 0; + } + virtual Id onInheritanceParsed( const ParseLocation& location, const NameHierarchy& childNameHierarchy, const NameHierarchy& parentNameHierarchy, AccessType access) @@ -2970,33 +2997,10 @@ private: return 0; } - virtual Id onFieldUsageParsed( - const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy) + virtual Id onUsageParsed( + const ParseLocation& location, const NameHierarchy& userName, Node::NodeType usedType, const NameHierarchy& usedName) { - usages.push_back(addLocationSuffix(userNameHierarchy.getQualifiedNameWithSignature() + " -> " + usedNameHierarchy.getQualifiedName(), location)); - return 0; - } - - virtual Id onGlobalVariableUsageParsed( - const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy) - { - usages.push_back(addLocationSuffix(userNameHierarchy.getQualifiedNameWithSignature() + " -> " + usedNameHierarchy.getQualifiedName(), location)); - return 0; - } - - virtual Id onEnumConstantUsageParsed( - const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy) - { - usages.push_back(addLocationSuffix(userNameHierarchy.getQualifiedNameWithSignature() + " -> " + usedNameHierarchy.getQualifiedName(), location)); - return 0; - } - - virtual Id onTemplateParameterTypeParsed( - const ParseLocation& location, const NameHierarchy& templateParameterTypeNameHierarchy, bool isImplicit) - { - templateParameterTypes.push_back( - addLocationSuffix(templateParameterTypeNameHierarchy.getQualifiedName(), location) - ); + usages.push_back(addLocationSuffix(userName.getQualifiedNameWithSignature() + " -> " + usedName.getQualifiedName(), location)); return 0; }