data: recording function pointers
* added recording of references to the ASTVisitor. * refactored reference recording in ASTVisitor. * merged all the onXxxUsageParsed methods of the ParserClient.
This commit is contained in:
@@ -4,10 +4,10 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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(
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -1158,6 +1158,24 @@ void ASTVisitor::RecordDeclRef(
|
||||
|
||||
bool fallback = false;
|
||||
|
||||
|
||||
if (symbolType == ST_LocalVariable || symbolType == ST_Parameter)
|
||||
{
|
||||
if (clang::VarDecl* varDecl = clang::dyn_cast<clang::VarDecl>(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<clang::VarDecl>(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<clang::VarDecl>(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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<TestParserClient> 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<TestParserClient> 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<TestParserClient> 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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user