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:
malte_langkabel
2016-04-19 13:32:09 +02:00
parent 5d71536bb1
commit 29ef349f61
5 changed files with 126 additions and 159 deletions
+4 -8
View File
@@ -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(
+5 -31
View File
@@ -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));
+2 -6
View File
@@ -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(
+84 -87
View File
@@ -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;
}
}
+31 -27
View File
@@ -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;
}