data: Parsing type usages within function and method bodies

This change parses type usages in function and method bodies and saves them with an edge of type EDGE_TYPE_USAGE. This
also includes base class types used in initialization lists of derived class constructors.
This commit is contained in:
Eberhard Graether
2014-07-30 22:35:30 +02:00
parent dc09860680
commit 890575cd90
14 changed files with 190 additions and 23 deletions
+11 -2
View File
@@ -238,7 +238,7 @@ void Storage::onCallParsed(const ParseLocation& location, const ParseVariable& c
void Storage::onFieldUsageParsed(const ParseLocation& location, const ParseFunction& user, const std::string& usedName)
{
log("usage", user.fullName + " -> " + usedName, location);
log("field usage", user.fullName + " -> " + usedName, location);
Node* userNode =
m_graph.createNodeHierarchyWithDistinctSignature(user.fullName, ParserClient::functionSignatureStr(user));
@@ -251,7 +251,7 @@ void Storage::onFieldUsageParsed(const ParseLocation& location, const ParseFunct
void Storage::onGlobalVariableUsageParsed(
const ParseLocation& location, const ParseFunction& user, const std::string& usedName
){
log("usage", user.fullName + " -> " + usedName, location);
log("global usage", user.fullName + " -> " + usedName, location);
Node* userNode =
m_graph.createNodeHierarchyWithDistinctSignature(user.fullName, ParserClient::functionSignatureStr(user));;
@@ -261,6 +261,15 @@ void Storage::onGlobalVariableUsageParsed(
addTokenLocation(edge, location);
}
void Storage::onTypeUsageParsed(const ParseTypeUsage& type, const ParseFunction& function)
{
log("type usage", function.fullName + " -> " + type.dataType.getRawTypeName(), type.location);
Node* functionNode =
m_graph.createNodeHierarchyWithDistinctSignature(function.fullName, ParserClient::functionSignatureStr(function));
addTypeEdge(functionNode, Edge::EDGE_TYPE_USAGE, type);
}
Id Storage::getIdForNodeWithName(const std::string& fullName) const
{
Node* node = m_graph.getNode(fullName);
+1
View File
@@ -60,6 +60,7 @@ public:
const ParseLocation& location, const ParseFunction& user, const std::string& usedName);
virtual void onGlobalVariableUsageParsed(
const ParseLocation& location, const ParseFunction& user, const std::string& usedName);
virtual void onTypeUsageParsed(const ParseTypeUsage& type, const ParseFunction& function);
// GraphAccess implementation
virtual Id getIdForNodeWithName(const std::string& fullName) const;
+5 -2
View File
@@ -90,8 +90,9 @@ void Edge::addComponentDataType(std::shared_ptr<TokenComponentDataType> componen
{
LOG_ERROR("TokenComponentDataType has been set before!");
}
else if (m_type != EDGE_TYPEDEF_OF && m_type != EDGE_TYPE_OF
&& m_type != EDGE_RETURN_TYPE_OF && m_type != EDGE_PARAMETER_TYPE_OF)
else if (m_type != EDGE_TYPEDEF_OF && m_type != EDGE_TYPE_OF &&
m_type != EDGE_RETURN_TYPE_OF && m_type != EDGE_PARAMETER_TYPE_OF &&
m_type != EDGE_TYPE_USAGE)
{
LOG_ERROR("TokenComponentDataType can't be set on edge of type: " + getTypeString());
}
@@ -113,6 +114,8 @@ std::string Edge::getTypeString() const
return "return type";
case EDGE_PARAMETER_TYPE_OF:
return "parameter type";
case EDGE_TYPE_USAGE:
return "type usage";
case EDGE_INHERITANCE:
return "inheritance";
case EDGE_CALL:
+1
View File
@@ -19,6 +19,7 @@ public:
EDGE_TYPE_OF,
EDGE_RETURN_TYPE_OF,
EDGE_PARAMETER_TYPE_OF,
EDGE_TYPE_USAGE,
EDGE_USAGE,
EDGE_CALL,
EDGE_INHERITANCE,
+1
View File
@@ -79,6 +79,7 @@ public:
const ParseLocation& location, const ParseFunction& user, const std::string& usedName) = 0;
virtual void onGlobalVariableUsageParsed(
const ParseLocation& location, const ParseFunction& user, const std::string& usedName) = 0;
virtual void onTypeUsageParsed(const ParseTypeUsage& type, const ParseFunction& function) = 0;
};
#endif // PARSER_CLIENT_H
+14 -2
View File
@@ -66,7 +66,7 @@ void ASTBodyVisitor::VisitMemberExpr(clang::make_ptr<clang::MemberExpr>::type ex
{
if (expr->getMemberDecl()->getKind() == clang::Decl::Kind::Field)
{
m_client->VisitFieldUsageExprInDeclBody(m_functionDecl, expr);
m_client->VisitMemberExprInDeclBody(m_functionDecl, expr);
}
VisitStmt(expr);
}
@@ -75,7 +75,19 @@ void ASTBodyVisitor::VisitDeclRefExpr(clang::make_ptr<clang::DeclRefExpr>::type
{
if (expr->getDecl()->getKind() == clang::Decl::Var && expr->getDecl()->isDefinedOutsideFunctionOrMethod())
{
m_client->VisitGlobalVariableUsageExprInDeclBody(m_functionDecl, expr);
m_client->VisitDeclRefExprInDeclBody(m_functionDecl, expr);
}
VisitStmt(expr);
}
void ASTBodyVisitor::VisitDeclStmt(clang::DeclStmt* stmt)
{
for (clang::Decl* decl : stmt->decls())
{
if (clang::isa<clang::VarDecl>(decl))
{
m_client->VisitVarDeclInDeclBody(m_functionDecl, clang::dyn_cast<clang::VarDecl>(decl));
}
}
VisitStmt(stmt);
}
+1
View File
@@ -17,6 +17,7 @@ public:
void VisitCXXConstructExpr(clang::CXXConstructExpr* expr);
void VisitMemberExpr(clang::make_ptr<clang::MemberExpr>::type expr);
void VisitDeclRefExpr(clang::make_ptr<clang::DeclRefExpr>::type expr);
void VisitDeclStmt(clang::DeclStmt* stmt);
private:
ASTBodyVisitorClient* m_client;
@@ -15,8 +15,9 @@ public:
virtual void VisitCallExprInDeclBody(clang::VarDecl* decl, clang::CallExpr* expr) = 0;
virtual void VisitCXXConstructExprInDeclBody(clang::FunctionDecl* decl, clang::CXXConstructExpr* expr) = 0;
virtual void VisitCXXConstructExprInDeclBody(clang::VarDecl* decl, clang::CXXConstructExpr* expr) = 0;
virtual void VisitFieldUsageExprInDeclBody(clang::FunctionDecl* decl, clang::MemberExpr* expr) = 0;
virtual void VisitGlobalVariableUsageExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr) = 0;
virtual void VisitMemberExprInDeclBody(clang::FunctionDecl* decl, clang::MemberExpr* expr) = 0;
virtual void VisitDeclRefExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr) = 0;
virtual void VisitVarDeclInDeclBody(clang::FunctionDecl* decl, clang::VarDecl* varDecl) = 0;
};
#endif // AST_BODY_VISITOR_CLIENT_H
+17 -2
View File
@@ -206,6 +206,13 @@ bool ASTVisitor::VisitCXXConstructorDecl(clang::CXXConstructorDecl* declaration)
init->getMember()->getQualifiedNameAsString()
);
}
else if (init->isBaseInitializer())
{
m_client->onTypeUsageParsed(
getParseTypeUsage(init->getTypeSourceInfo()->getTypeLoc(), init->getTypeSourceInfo()->getType()),
getParseFunction(declaration)
);
}
ASTBodyVisitor bodyVisitor(this, declaration);
bodyVisitor.Visit(init->getInit());
@@ -308,7 +315,7 @@ void ASTVisitor::VisitCXXConstructExprInDeclBody(clang::VarDecl* decl, clang::CX
);
}
void ASTVisitor::VisitFieldUsageExprInDeclBody(clang::FunctionDecl* decl, clang::MemberExpr* expr)
void ASTVisitor::VisitMemberExprInDeclBody(clang::FunctionDecl* decl, clang::MemberExpr* expr)
{
ParseLocation parseLocation = getParseLocation(expr->getSourceRange());
@@ -322,7 +329,7 @@ void ASTVisitor::VisitFieldUsageExprInDeclBody(clang::FunctionDecl* decl, clang:
);
}
void ASTVisitor::VisitGlobalVariableUsageExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr)
void ASTVisitor::VisitDeclRefExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr)
{
ParseLocation parseLocation = getParseLocation(expr->getSourceRange());
@@ -336,6 +343,14 @@ void ASTVisitor::VisitGlobalVariableUsageExprInDeclBody(clang::FunctionDecl* dec
);
}
void ASTVisitor::VisitVarDeclInDeclBody(clang::FunctionDecl* decl, clang::VarDecl* varDecl)
{
m_client->onTypeUsageParsed(
getParseTypeUsage(varDecl->getTypeSourceInfo()->getTypeLoc(), varDecl->getType()),
getParseFunction(decl)
);
}
bool ASTVisitor::hasValidLocation(const clang::Decl* declaration) const
{
const clang::SourceLocation& location = declaration->getLocStart();
+3 -2
View File
@@ -43,8 +43,9 @@ public:
virtual void VisitCallExprInDeclBody(clang::VarDecl* decl, clang::CallExpr* expr); // calls in initialization of global variables
virtual void VisitCXXConstructExprInDeclBody(clang::FunctionDecl* decl, clang::CXXConstructExpr* expr); // constructor calls
virtual void VisitCXXConstructExprInDeclBody(clang::VarDecl* decl, clang::CXXConstructExpr* expr); // constructor calls of global variables
virtual void VisitFieldUsageExprInDeclBody(clang::FunctionDecl* decl, clang::MemberExpr* expr); // field usages
virtual void VisitGlobalVariableUsageExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr); // global variable usage
virtual void VisitMemberExprInDeclBody(clang::FunctionDecl* decl, clang::MemberExpr* expr); // field usages
virtual void VisitDeclRefExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr); // global variable usage
virtual void VisitVarDeclInDeclBody(clang::FunctionDecl* decl, clang::VarDecl* varDecl); // type usages
private:
bool hasValidLocation(const clang::Decl* declaration) const;