data: Parsing functions with ParseFunction for signature comparing
This change switches function and method parsing to use the structure ParseFunction, which holds all important values of the function. This structure is then used also in call and usage parsing to allow distinction between signatures.
This commit is contained in:
@@ -102,6 +102,8 @@ add_files(
|
||||
data/location/TokenLocationLine.cpp
|
||||
data/location/TokenLocationLine.h
|
||||
|
||||
data/parser/ParseFunction.cpp
|
||||
data/parser/ParseFunction.h
|
||||
data/parser/ParseLocation.cpp
|
||||
data/parser/ParseLocation.h
|
||||
data/parser/Parser.cpp
|
||||
|
||||
+46
-33
@@ -6,6 +6,7 @@
|
||||
#include "data/location/TokenLocation.h"
|
||||
#include "data/location/TokenLocationFile.h"
|
||||
#include "data/location/TokenLocationLine.h"
|
||||
#include "data/parser/ParseFunction.h"
|
||||
#include "data/parser/ParseLocation.h"
|
||||
#include "data/parser/ParseTypeUsage.h"
|
||||
#include "data/parser/ParseVariable.h"
|
||||
@@ -109,45 +110,40 @@ void Storage::onFieldParsed(const ParseLocation& location, const ParseVariable&
|
||||
}
|
||||
|
||||
void Storage::onFunctionParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType,
|
||||
const std::vector<ParseTypeUsage>& parameters, const ParseLocation& scopeLocation
|
||||
)
|
||||
{
|
||||
log("function", fullName, location);
|
||||
const ParseLocation& location, const ParseFunction& function, const ParseLocation& scopeLocation
|
||||
){
|
||||
log("function", function.fullName, location);
|
||||
|
||||
Node* node = m_graph.createNodeHierarchyWithDistinctSignature(
|
||||
Node::NODE_FUNCTION, fullName,
|
||||
ParserClient::functionSignatureStr(returnType.dataType, fullName, parameters, false)
|
||||
Node::NODE_FUNCTION, function.fullName, ParserClient::functionSignatureStr(function)
|
||||
);
|
||||
|
||||
addTokenLocation(node, location);
|
||||
addTokenLocation(node, scopeLocation, true);
|
||||
|
||||
addTypeEdge(node, Edge::EDGE_RETURN_TYPE_OF, returnType);
|
||||
for (const ParseTypeUsage& parameter : parameters)
|
||||
addTypeEdge(node, Edge::EDGE_RETURN_TYPE_OF, function.returnType);
|
||||
for (const ParseTypeUsage& parameter : function.parameters)
|
||||
{
|
||||
addTypeEdge(node, Edge::EDGE_PARAMETER_TYPE_OF, parameter);
|
||||
}
|
||||
}
|
||||
|
||||
void Storage::onMethodParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType,
|
||||
const std::vector<ParseTypeUsage>& parameters, AccessType access, AbstractionType abstraction,
|
||||
bool isConst, bool isStatic, const ParseLocation& scopeLocation
|
||||
)
|
||||
{
|
||||
log("method", fullName, location);
|
||||
const ParseLocation& location, const ParseFunction& method, AccessType access, AbstractionType abstraction,
|
||||
const ParseLocation& scopeLocation
|
||||
){
|
||||
log("method", method.fullName, location);
|
||||
|
||||
Node* node = m_graph.createNodeHierarchyWithDistinctSignature(
|
||||
Node::NODE_METHOD, fullName,
|
||||
ParserClient::functionSignatureStr(returnType.dataType, fullName, parameters, isConst)
|
||||
Node::NODE_METHOD, method.fullName, ParserClient::functionSignatureStr(method)
|
||||
);
|
||||
|
||||
if (isConst)
|
||||
if (method.isConst)
|
||||
{
|
||||
node->addComponentConst(std::make_shared<TokenComponentConst>());
|
||||
}
|
||||
|
||||
if (isStatic)
|
||||
if (method.isStatic)
|
||||
{
|
||||
node->addComponentStatic(std::make_shared<TokenComponentStatic>());
|
||||
}
|
||||
@@ -162,8 +158,8 @@ void Storage::onMethodParsed(
|
||||
addTokenLocation(node, location);
|
||||
addTokenLocation(node, scopeLocation, true);
|
||||
|
||||
addTypeEdge(node, Edge::EDGE_RETURN_TYPE_OF, returnType);
|
||||
for (const ParseTypeUsage& parameter : parameters)
|
||||
addTypeEdge(node, Edge::EDGE_RETURN_TYPE_OF, method.returnType);
|
||||
for (const ParseTypeUsage& parameter : method.parameters)
|
||||
{
|
||||
addTypeEdge(node, Edge::EDGE_PARAMETER_TYPE_OF, parameter);
|
||||
}
|
||||
@@ -212,23 +208,40 @@ void Storage::onInheritanceParsed(
|
||||
addTokenLocation(edge, location);
|
||||
}
|
||||
|
||||
void Storage::onCallParsed(const ParseLocation& location, const std::string& callerName, const std::string& calleeName)
|
||||
void Storage::onCallParsed(const ParseLocation& location, const ParseFunction& caller, const ParseFunction& callee)
|
||||
{
|
||||
log("call", callerName + " -> " + calleeName, location);
|
||||
log("call", caller.fullName + " -> " + callee.fullName, location);
|
||||
|
||||
Node* callerNode = m_graph.createNodeHierarchy(callerName);
|
||||
Node* calleeNode = m_graph.createNodeHierarchy(calleeName);
|
||||
Node* callerNode =
|
||||
m_graph.createNodeHierarchyWithDistinctSignature(caller.fullName, ParserClient::functionSignatureStr(caller));
|
||||
Node* calleeNode =
|
||||
m_graph.createNodeHierarchyWithDistinctSignature(callee.fullName, ParserClient::functionSignatureStr(callee));
|
||||
|
||||
Edge* edge = m_graph.createEdge(Edge::EDGE_CALL, callerNode, calleeNode);
|
||||
|
||||
addTokenLocation(edge, location);
|
||||
}
|
||||
|
||||
void Storage::onFieldUsageParsed(const ParseLocation& location, const std::string& userName, const std::string& usedName)
|
||||
void Storage::onCallParsed(const ParseLocation& location, const ParseVariable& caller, const ParseFunction& callee)
|
||||
{
|
||||
log("usage", userName + " -> " + usedName, location);
|
||||
log("call", caller.fullName + " -> " + callee.fullName, location);
|
||||
|
||||
Node* userNode = m_graph.createNodeHierarchy(userName);
|
||||
Node* callerNode =
|
||||
m_graph.createNodeHierarchy(caller.fullName);
|
||||
Node* calleeNode =
|
||||
m_graph.createNodeHierarchyWithDistinctSignature(callee.fullName, ParserClient::functionSignatureStr(callee));
|
||||
|
||||
Edge* edge = m_graph.createEdge(Edge::EDGE_CALL, callerNode, calleeNode);
|
||||
|
||||
addTokenLocation(edge, location);
|
||||
}
|
||||
|
||||
void Storage::onFieldUsageParsed(const ParseLocation& location, const ParseFunction& user, const std::string& usedName)
|
||||
{
|
||||
log("usage", user.fullName + " -> " + usedName, location);
|
||||
|
||||
Node* userNode =
|
||||
m_graph.createNodeHierarchyWithDistinctSignature(user.fullName, ParserClient::functionSignatureStr(user));
|
||||
Node* usedNode = m_graph.createNodeHierarchy(usedName);
|
||||
|
||||
Edge* edge = m_graph.createEdge(Edge::EDGE_USAGE, userNode, usedNode);
|
||||
@@ -236,12 +249,12 @@ void Storage::onFieldUsageParsed(const ParseLocation& location, const std::strin
|
||||
}
|
||||
|
||||
void Storage::onGlobalVariableUsageParsed(
|
||||
const ParseLocation& location, const std::string& userName, const std::string& usedName
|
||||
)
|
||||
{
|
||||
log("usage", userName + " -> " + usedName, location);
|
||||
const ParseLocation& location, const ParseFunction& user, const std::string& usedName
|
||||
){
|
||||
log("usage", user.fullName + " -> " + usedName, location);
|
||||
|
||||
Node* userNode = m_graph.createNodeHierarchy(userName);
|
||||
Node* userNode =
|
||||
m_graph.createNodeHierarchyWithDistinctSignature(user.fullName, ParserClient::functionSignatureStr(user));;
|
||||
Node* usedNode = m_graph.createNodeHierarchy(usedName);
|
||||
|
||||
Edge* edge = m_graph.createEdge(Edge::EDGE_USAGE, userNode, usedNode);
|
||||
|
||||
+10
-16
@@ -28,8 +28,7 @@ public:
|
||||
// ParserClient implementation
|
||||
virtual void onTypedefParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& underlyingType,
|
||||
AccessType access
|
||||
);
|
||||
AccessType access);
|
||||
virtual void onClassParsed(
|
||||
const ParseLocation& location, const std::string& fullName, AccessType access, const ParseLocation& scopeLocation);
|
||||
virtual void onStructParsed(
|
||||
@@ -39,14 +38,10 @@ public:
|
||||
virtual void onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access);
|
||||
|
||||
virtual void onFunctionParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType,
|
||||
const std::vector<ParseTypeUsage>& parameters, const ParseLocation& scopeLocation
|
||||
);
|
||||
const ParseLocation& location, const ParseFunction& function, const ParseLocation& scopeLocation);
|
||||
virtual void onMethodParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType,
|
||||
const std::vector<ParseTypeUsage>& parameters, AccessType access, AbstractionType abstraction,
|
||||
bool isConst, bool isStatic, const ParseLocation& scopeLocation
|
||||
);
|
||||
const ParseLocation& location, const ParseFunction& method, AccessType access, AbstractionType abstraction,
|
||||
const ParseLocation& scopeLocation);
|
||||
|
||||
virtual void onNamespaceParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const ParseLocation& scopeLocation);
|
||||
@@ -56,16 +51,15 @@ public:
|
||||
virtual void onEnumFieldParsed(const ParseLocation& location, const std::string& fullName);
|
||||
|
||||
virtual void onInheritanceParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const std::string& baseName, AccessType access
|
||||
);
|
||||
const ParseLocation& location, const std::string& fullName, const std::string& baseName, AccessType access);
|
||||
virtual void onCallParsed(
|
||||
const ParseLocation& location, const std::string& callerName, const std::string& calleeName
|
||||
);
|
||||
const ParseLocation& location, const ParseFunction& caller, const ParseFunction& callee);
|
||||
virtual void onCallParsed(
|
||||
const ParseLocation& location, const ParseVariable& caller, const ParseFunction& callee);
|
||||
virtual void onFieldUsageParsed(
|
||||
const ParseLocation& location, const std::string& userName, const std::string& usedName
|
||||
);
|
||||
const ParseLocation& location, const ParseFunction& user, const std::string& usedName);
|
||||
virtual void onGlobalVariableUsageParsed(
|
||||
const ParseLocation& location, const std::string& userName, const std::string& usedName);
|
||||
const ParseLocation& location, const ParseFunction& user, const std::string& usedName);
|
||||
|
||||
// GraphAccess implementation
|
||||
virtual Id getIdForNodeWithName(const std::string& fullName) const;
|
||||
|
||||
@@ -90,7 +90,7 @@ Node* Graph::createNodeHierarchy(Node::NodeType type, const std::string& fullNam
|
||||
|
||||
Node* Graph::createNodeHierarchyWithDistinctSignature(const std::string& fullName, const std::string& signature)
|
||||
{
|
||||
return createNodeHierarchyWithDistinctSignature(Node::NODE_UNDEFINED, fullName, signature);
|
||||
return createNodeHierarchyWithDistinctSignature(Node::NODE_UNDEFINED_FUNCTION, fullName, signature);
|
||||
}
|
||||
|
||||
Node* Graph::createNodeHierarchyWithDistinctSignature(
|
||||
@@ -103,7 +103,7 @@ Node* Graph::createNodeHierarchyWithDistinctSignature(
|
||||
TokenComponentSignature* sigComponent = node->getComponent<TokenComponentSignature>();
|
||||
if (sigComponent && sigComponent->getSignature() == signature)
|
||||
{
|
||||
if (type != Node::NODE_UNDEFINED)
|
||||
if (type != Node::NODE_UNDEFINED && type != Node::NODE_UNDEFINED_FUNCTION)
|
||||
{
|
||||
node->setType(type);
|
||||
}
|
||||
|
||||
@@ -31,10 +31,10 @@ Node::NodeType Node::getType() const
|
||||
|
||||
void Node::setType(NodeType type)
|
||||
{
|
||||
if (type != m_type && m_type != NODE_UNDEFINED)
|
||||
if (type != m_type && m_type != NODE_UNDEFINED && m_type != NODE_UNDEFINED_FUNCTION)
|
||||
{
|
||||
LOG_WARNING(
|
||||
"Changing NodeType after it was already set, from " + getTypeString(m_type) + " to " + getTypeString(type)
|
||||
"Cannot change NodeType after it was already set from " + getTypeString(m_type) + " to " + getTypeString(type)
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -229,7 +229,7 @@ void Node::addComponentSignature(std::shared_ptr<TokenComponentSignature> compon
|
||||
{
|
||||
LOG_ERROR("TokenComponentSignature has been set before!");
|
||||
}
|
||||
else if (m_type != NODE_FUNCTION && m_type != NODE_METHOD)
|
||||
else if (m_type != NODE_UNDEFINED_FUNCTION && m_type != NODE_FUNCTION && m_type != NODE_METHOD)
|
||||
{
|
||||
LOG_ERROR("TokenComponentSignature can't be set on node of type: " + getTypeString(m_type));
|
||||
}
|
||||
@@ -245,6 +245,8 @@ std::string Node::getTypeString(NodeType type) const
|
||||
{
|
||||
case NODE_UNDEFINED:
|
||||
return "undefined";
|
||||
case NODE_UNDEFINED_FUNCTION:
|
||||
return "undefined function";
|
||||
case NODE_CLASS:
|
||||
return "class";
|
||||
case NODE_STRUCT:
|
||||
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
enum NodeType
|
||||
{
|
||||
NODE_UNDEFINED,
|
||||
NODE_UNDEFINED_FUNCTION,
|
||||
NODE_CLASS,
|
||||
NODE_STRUCT,
|
||||
NODE_GLOBAL_VARIABLE,
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "data/parser/ParseFunction.h"
|
||||
|
||||
ParseFunction::ParseFunction(
|
||||
const ParseTypeUsage& returnType,
|
||||
const std::string& fullName,
|
||||
const std::vector<ParseTypeUsage>& parameters,
|
||||
bool isStatic,
|
||||
bool isConst
|
||||
)
|
||||
: returnType(returnType)
|
||||
, fullName(fullName)
|
||||
, parameters(parameters)
|
||||
, isStatic(isStatic)
|
||||
, isConst(isConst)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef PARSE_FUNCTION_H
|
||||
#define PARSE_FUNCTION_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "data/parser/ParseTypeUsage.h"
|
||||
|
||||
struct ParseFunction
|
||||
{
|
||||
ParseFunction(
|
||||
const ParseTypeUsage& returnType,
|
||||
const std::string& fullName,
|
||||
const std::vector<ParseTypeUsage>& parameters,
|
||||
bool isStatic = false,
|
||||
bool isConst = false
|
||||
);
|
||||
|
||||
const ParseTypeUsage returnType;
|
||||
const std::string fullName;
|
||||
const std::vector<ParseTypeUsage> parameters;
|
||||
const bool isStatic;
|
||||
const bool isConst;
|
||||
};
|
||||
|
||||
#endif // PARSE_FUNCTION_H
|
||||
@@ -16,7 +16,7 @@ struct ParseLocation
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
const std::string filePath;
|
||||
std::string filePath;
|
||||
uint startLineNumber;
|
||||
uint startColumnNumber;
|
||||
uint endLineNumber;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "data/parser/ParseFunction.h"
|
||||
#include "data/parser/ParseLocation.h"
|
||||
#include "data/parser/ParseTypeUsage.h"
|
||||
#include "data/parser/ParseVariable.h"
|
||||
@@ -103,26 +104,16 @@ std::string ParserClient::parameterStr(const std::vector<ParseTypeUsage> paramet
|
||||
return str + ")";
|
||||
}
|
||||
|
||||
std::string ParserClient::functionStr(
|
||||
const DataType& returnType,
|
||||
const std::string& fullName,
|
||||
const std::vector<ParseTypeUsage>& parameters,
|
||||
bool isConst
|
||||
){
|
||||
return addConstPrefix(
|
||||
returnType.getFullTypeName() + " " + fullName + parameterStr(parameters),
|
||||
isConst,
|
||||
false
|
||||
);
|
||||
std::string ParserClient::functionStr(const ParseFunction& function)
|
||||
{
|
||||
std::string str =
|
||||
function.returnType.dataType.getFullTypeName() + " " + function.fullName + parameterStr(function.parameters);
|
||||
return addConstPrefix(addStaticPrefix(str, function.isStatic), function.isConst, false);
|
||||
}
|
||||
|
||||
std::string ParserClient::functionSignatureStr(
|
||||
const DataType& returnType,
|
||||
const std::string& fullName,
|
||||
const std::vector<ParseTypeUsage>& parameters,
|
||||
bool isConst
|
||||
){
|
||||
return addConstPrefix(fullName + parameterStr(parameters), isConst, false);
|
||||
std::string ParserClient::functionSignatureStr(const ParseFunction& function)
|
||||
{
|
||||
return addConstPrefix(function.fullName + parameterStr(function.parameters), function.isConst, false);
|
||||
}
|
||||
|
||||
ParserClient::ParserClient()
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct ParseFunction;
|
||||
struct ParseLocation;
|
||||
struct ParseTypeUsage;
|
||||
struct ParseVariable;
|
||||
@@ -35,18 +36,8 @@ public:
|
||||
|
||||
static std::string variableStr(const ParseVariable& variable);
|
||||
static std::string parameterStr(const std::vector<ParseTypeUsage> parameters);
|
||||
static std::string functionStr(
|
||||
const DataType& returnType,
|
||||
const std::string& fullName,
|
||||
const std::vector<ParseTypeUsage>& parameters,
|
||||
bool isConst
|
||||
);
|
||||
static std::string functionSignatureStr(
|
||||
const DataType& returnType,
|
||||
const std::string& fullName,
|
||||
const std::vector<ParseTypeUsage>& parameters,
|
||||
bool isConst
|
||||
);
|
||||
static std::string functionStr(const ParseFunction& function);
|
||||
static std::string functionSignatureStr(const ParseFunction& function);
|
||||
|
||||
ParserClient();
|
||||
virtual ~ParserClient();
|
||||
@@ -65,12 +56,10 @@ public:
|
||||
virtual void onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access) = 0;
|
||||
|
||||
virtual void onFunctionParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType,
|
||||
const std::vector<ParseTypeUsage>& parameters, const ParseLocation& scopeLocation) = 0;
|
||||
const ParseLocation& location, const ParseFunction& function, const ParseLocation& scopeLocation) = 0;
|
||||
virtual void onMethodParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType,
|
||||
const std::vector<ParseTypeUsage>& parameters, AccessType access, AbstractionType abstraction,
|
||||
bool isConst, bool isStatic, const ParseLocation& scopeLocation) = 0;
|
||||
const ParseLocation& location, const ParseFunction& method, AccessType access, AbstractionType abstraction,
|
||||
const ParseLocation& scopeLocation) = 0;
|
||||
|
||||
virtual void onNamespaceParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const ParseLocation& scopeLocation) = 0;
|
||||
@@ -83,11 +72,13 @@ public:
|
||||
virtual void onInheritanceParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const std::string& baseName, AccessType access) = 0;
|
||||
virtual void onCallParsed(
|
||||
const ParseLocation& location, const std::string& callerName, const std::string& calleeName) = 0;
|
||||
const ParseLocation& location, const ParseFunction& caller, const ParseFunction& callee) = 0;
|
||||
virtual void onCallParsed(
|
||||
const ParseLocation& location, const ParseVariable& caller, const ParseFunction& callee) = 0;
|
||||
virtual void onFieldUsageParsed(
|
||||
const ParseLocation& location, const std::string& userName, const std::string& usedName) = 0;
|
||||
const ParseLocation& location, const ParseFunction& user, const std::string& usedName) = 0;
|
||||
virtual void onGlobalVariableUsageParsed(
|
||||
const ParseLocation& location, const std::string& userName, const std::string& usedName) = 0;
|
||||
const ParseLocation& location, const ParseFunction& user, const std::string& usedName) = 0;
|
||||
};
|
||||
|
||||
#endif // PARSER_CLIENT_H
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
#include "data/parser/cxx/ASTBodyVisitor.h"
|
||||
|
||||
ASTBodyVisitor::ASTBodyVisitor(ASTBodyVisitorClient* client, clang::NamedDecl* parentDecl)
|
||||
ASTBodyVisitor::ASTBodyVisitor(ASTBodyVisitorClient* client, clang::FunctionDecl* functionDecl)
|
||||
: m_client(client)
|
||||
, m_parentDecl(parentDecl)
|
||||
, m_functionDecl(functionDecl)
|
||||
, m_varDecl(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
ASTBodyVisitor::ASTBodyVisitor(ASTBodyVisitorClient* client, clang::VarDecl* varDecl)
|
||||
: m_client(client)
|
||||
, m_functionDecl(nullptr)
|
||||
, m_varDecl(varDecl)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -28,14 +36,28 @@ void ASTBodyVisitor::VisitChildren(clang::Stmt* stmt)
|
||||
|
||||
void ASTBodyVisitor::VisitCallExpr(clang::CallExpr* expr)
|
||||
{
|
||||
m_client->VisitCallExprInDeclBody(m_parentDecl, expr);
|
||||
if (m_functionDecl)
|
||||
{
|
||||
m_client->VisitCallExprInDeclBody(m_functionDecl, expr);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_client->VisitCallExprInDeclBody(m_varDecl, expr);
|
||||
}
|
||||
|
||||
VisitStmt(expr);
|
||||
}
|
||||
|
||||
void ASTBodyVisitor::VisitCXXConstructExpr(clang::CXXConstructExpr* expr)
|
||||
{
|
||||
m_client->VisitCXXConstructExprInDeclBody(m_parentDecl, expr);
|
||||
if (m_functionDecl)
|
||||
{
|
||||
m_client->VisitCXXConstructExprInDeclBody(m_functionDecl, expr);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_client->VisitCXXConstructExprInDeclBody(m_varDecl, expr);
|
||||
}
|
||||
|
||||
VisitStmt(expr);
|
||||
}
|
||||
@@ -44,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_parentDecl, expr);
|
||||
m_client->VisitFieldUsageExprInDeclBody(m_functionDecl, expr);
|
||||
}
|
||||
VisitStmt(expr);
|
||||
}
|
||||
@@ -53,7 +75,7 @@ void ASTBodyVisitor::VisitDeclRefExpr(clang::make_ptr<clang::DeclRefExpr>::type
|
||||
{
|
||||
if (expr->getDecl()->getKind() == clang::Decl::Var && expr->getDecl()->isDefinedOutsideFunctionOrMethod())
|
||||
{
|
||||
m_client->VisitGlobalVariableUsageExprInDeclBody(m_parentDecl, expr);
|
||||
m_client->VisitGlobalVariableUsageExprInDeclBody(m_functionDecl, expr);
|
||||
}
|
||||
VisitStmt(expr);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
class ASTBodyVisitor: public clang::StmtVisitor<ASTBodyVisitor>
|
||||
{
|
||||
public:
|
||||
ASTBodyVisitor(ASTBodyVisitorClient* client, clang::NamedDecl* parentDecl);
|
||||
ASTBodyVisitor(ASTBodyVisitorClient* client, clang::FunctionDecl* functionDecl);
|
||||
ASTBodyVisitor(ASTBodyVisitorClient* client, clang::VarDecl* varDecl);
|
||||
virtual ~ASTBodyVisitor();
|
||||
|
||||
void VisitStmt(clang::Stmt* stmt);
|
||||
@@ -19,7 +20,8 @@ public:
|
||||
|
||||
private:
|
||||
ASTBodyVisitorClient* m_client;
|
||||
clang::NamedDecl* m_parentDecl;
|
||||
clang::FunctionDecl* m_functionDecl;
|
||||
clang::VarDecl* m_varDecl;
|
||||
};
|
||||
|
||||
#endif // AST_BODY_VISITOR
|
||||
|
||||
@@ -11,10 +11,12 @@ public:
|
||||
ASTBodyVisitorClient();
|
||||
virtual ~ASTBodyVisitorClient();
|
||||
|
||||
virtual void VisitCallExprInDeclBody(clang::NamedDecl* decl, clang::CallExpr* expr) = 0;
|
||||
virtual void VisitCXXConstructExprInDeclBody(clang::NamedDecl* decl, clang::CXXConstructExpr* expr) = 0;
|
||||
virtual void VisitFieldUsageExprInDeclBody(clang::NamedDecl* decl, clang::MemberExpr* expr) = 0;
|
||||
virtual void VisitGlobalVariableUsageExprInDeclBody(clang::NamedDecl* decl, clang::DeclRefExpr* expr) = 0;
|
||||
virtual void VisitCallExprInDeclBody(clang::FunctionDecl* decl, clang::CallExpr* expr) = 0;
|
||||
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;
|
||||
};
|
||||
|
||||
#endif // AST_BODY_VISITOR_CLIENT_H
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "data/parser/cxx/ASTBodyVisitor.h"
|
||||
#include "data/parser/cxx/utilityCxx.h"
|
||||
#include "data/parser/ParseFunction.h"
|
||||
#include "data/parser/ParseLocation.h"
|
||||
#include "data/parser/ParseTypeUsage.h"
|
||||
#include "data/parser/ParseVariable.h"
|
||||
@@ -141,9 +142,7 @@ bool ASTVisitor::VisitFunctionDecl(clang::FunctionDecl* declaration)
|
||||
{
|
||||
m_client->onFunctionParsed(
|
||||
getParseLocationForNamedDecl(declaration),
|
||||
declaration->getQualifiedNameAsString(),
|
||||
getParseTypeUsageOfReturnType(declaration),
|
||||
getParameters(declaration),
|
||||
getParseFunction(declaration),
|
||||
getParseLocationOfFunctionBody(declaration)
|
||||
);
|
||||
|
||||
@@ -173,13 +172,9 @@ bool ASTVisitor::VisitCXXMethodDecl(clang::CXXMethodDecl* declaration)
|
||||
|
||||
m_client->onMethodParsed(
|
||||
getParseLocationForNamedDecl(declaration),
|
||||
declaration->getQualifiedNameAsString(),
|
||||
getParseTypeUsageOfReturnType(declaration),
|
||||
getParameters(declaration),
|
||||
getParseFunction(declaration),
|
||||
convertAccessType(declaration->getAccess()),
|
||||
abstraction,
|
||||
declaration->isConst(),
|
||||
declaration->isStatic(),
|
||||
getParseLocationOfFunctionBody(declaration)
|
||||
);
|
||||
|
||||
@@ -206,9 +201,8 @@ bool ASTVisitor::VisitCXXConstructorDecl(clang::CXXConstructorDecl* declaration)
|
||||
if (init->isMemberInitializer())
|
||||
{
|
||||
m_client->onFieldUsageParsed(
|
||||
// getParseLocation(init->getSourceRange()),
|
||||
getParseLocationForNamedDecl(init->getMember(), init->getMemberLocation()),
|
||||
declaration->getQualifiedNameAsString(),
|
||||
getParseFunction(declaration),
|
||||
init->getMember()->getQualifiedNameAsString()
|
||||
);
|
||||
}
|
||||
@@ -264,7 +258,7 @@ bool ASTVisitor::VisitEnumConstantDecl(clang::EnumConstantDecl* declaration)
|
||||
return true;
|
||||
}
|
||||
|
||||
void ASTVisitor::VisitCallExprInDeclBody(clang::NamedDecl* decl, clang::CallExpr* expr)
|
||||
void ASTVisitor::VisitCallExprInDeclBody(clang::FunctionDecl* decl, clang::CallExpr* expr)
|
||||
{
|
||||
// if (clang::FunctionDecl *CalleeDecl = CE->getDirectCallee())
|
||||
// {
|
||||
@@ -282,21 +276,39 @@ void ASTVisitor::VisitCallExprInDeclBody(clang::NamedDecl* decl, clang::CallExpr
|
||||
|
||||
m_client->onCallParsed(
|
||||
getParseLocation(expr->getSourceRange()),
|
||||
decl->getQualifiedNameAsString(),
|
||||
expr->getDirectCallee()->getQualifiedNameAsString()
|
||||
getParseFunction(decl),
|
||||
getParseFunction(expr->getDirectCallee())
|
||||
);
|
||||
}
|
||||
|
||||
void ASTVisitor::VisitCXXConstructExprInDeclBody(clang::NamedDecl* decl, clang::CXXConstructExpr* expr)
|
||||
void ASTVisitor::VisitCallExprInDeclBody(clang::VarDecl* decl, clang::CallExpr* expr)
|
||||
{
|
||||
m_client->onCallParsed(
|
||||
getParseLocation(expr->getSourceRange()),
|
||||
decl->getQualifiedNameAsString(),
|
||||
expr->getConstructor()->getQualifiedNameAsString()
|
||||
getParseVariable(decl),
|
||||
getParseFunction(expr->getDirectCallee())
|
||||
);
|
||||
}
|
||||
|
||||
void ASTVisitor::VisitFieldUsageExprInDeclBody(clang::NamedDecl* decl, clang::MemberExpr* expr)
|
||||
void ASTVisitor::VisitCXXConstructExprInDeclBody(clang::FunctionDecl* decl, clang::CXXConstructExpr* expr)
|
||||
{
|
||||
m_client->onCallParsed(
|
||||
getParseLocation(expr->getSourceRange()),
|
||||
getParseFunction(decl),
|
||||
getParseFunction(expr->getConstructor())
|
||||
);
|
||||
}
|
||||
|
||||
void ASTVisitor::VisitCXXConstructExprInDeclBody(clang::VarDecl* decl, clang::CXXConstructExpr* expr)
|
||||
{
|
||||
m_client->onCallParsed(
|
||||
getParseLocation(expr->getSourceRange()),
|
||||
getParseVariable(decl),
|
||||
getParseFunction(expr->getConstructor())
|
||||
);
|
||||
}
|
||||
|
||||
void ASTVisitor::VisitFieldUsageExprInDeclBody(clang::FunctionDecl* decl, clang::MemberExpr* expr)
|
||||
{
|
||||
ParseLocation parseLocation = getParseLocation(expr->getSourceRange());
|
||||
|
||||
@@ -305,12 +317,12 @@ void ASTVisitor::VisitFieldUsageExprInDeclBody(clang::NamedDecl* decl, clang::Me
|
||||
|
||||
m_client->onFieldUsageParsed(
|
||||
parseLocation,
|
||||
decl->getQualifiedNameAsString(),
|
||||
getParseFunction(decl),
|
||||
expr->getMemberDecl()->getQualifiedNameAsString()
|
||||
);
|
||||
}
|
||||
|
||||
void ASTVisitor::VisitGlobalVariableUsageExprInDeclBody(clang::NamedDecl* decl, clang::DeclRefExpr* expr)
|
||||
void ASTVisitor::VisitGlobalVariableUsageExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr)
|
||||
{
|
||||
ParseLocation parseLocation = getParseLocation(expr->getSourceRange());
|
||||
|
||||
@@ -319,7 +331,7 @@ void ASTVisitor::VisitGlobalVariableUsageExprInDeclBody(clang::NamedDecl* decl,
|
||||
|
||||
m_client->onGlobalVariableUsageParsed(
|
||||
parseLocation,
|
||||
decl->getQualifiedNameAsString(),
|
||||
getParseFunction(decl),
|
||||
expr->getDecl()->getQualifiedNameAsString()
|
||||
);
|
||||
}
|
||||
@@ -330,6 +342,27 @@ bool ASTVisitor::hasValidLocation(const clang::Decl* declaration) const
|
||||
return location.isValid() && m_context->getSourceManager().isWrittenInMainFile(location);
|
||||
}
|
||||
|
||||
std::string ASTVisitor::getTypeName(const clang::QualType& qualType) const
|
||||
{
|
||||
DataType dataType = utility::qualTypeToDataType(qualType);
|
||||
return dataType.getRawTypeName();
|
||||
}
|
||||
|
||||
ParserClient::AccessType ASTVisitor::convertAccessType(clang::AccessSpecifier access) const
|
||||
{
|
||||
switch (access)
|
||||
{
|
||||
case clang::AS_public:
|
||||
return ParserClient::ACCESS_PUBLIC;
|
||||
case clang::AS_protected:
|
||||
return ParserClient::ACCESS_PROTECTED;
|
||||
case clang::AS_private:
|
||||
return ParserClient::ACCESS_PRIVATE;
|
||||
case clang::AS_none:
|
||||
return ParserClient::ACCESS_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
ParseLocation ASTVisitor::getParseLocation(const clang::SourceRange& sourceRange) const
|
||||
{
|
||||
if (sourceRange.isInvalid())
|
||||
@@ -389,33 +422,21 @@ ParseLocation ASTVisitor::getParseLocationOfRecordBody(clang::CXXRecordDecl* dec
|
||||
return ParseLocation();
|
||||
}
|
||||
|
||||
ParseVariable ASTVisitor::getParseVariable(clang::DeclaratorDecl* declaration) const
|
||||
{
|
||||
bool isStatic = false;
|
||||
if (clang::isa<clang::VarDecl>(declaration))
|
||||
{
|
||||
clang::VarDecl* varDecl = static_cast<clang::VarDecl*>(declaration);
|
||||
isStatic = varDecl->isStaticDataMember() || varDecl->getStorageClass() == clang::SC_Static;
|
||||
}
|
||||
|
||||
return ParseVariable(
|
||||
getParseTypeUsage(declaration->getTypeSourceInfo()->getTypeLoc(), declaration->getType()),
|
||||
declaration->getQualifiedNameAsString(),
|
||||
isStatic
|
||||
);
|
||||
}
|
||||
|
||||
ParseTypeUsage ASTVisitor::getParseTypeUsage(clang::TypeLoc typeLoc, const clang::QualType& type) const
|
||||
{
|
||||
while (typeLoc.getNextTypeLoc())
|
||||
{
|
||||
typeLoc = typeLoc.getNextTypeLoc();
|
||||
}
|
||||
|
||||
ParseLocation parseLocation = getParseLocation(typeLoc.getSourceRange());
|
||||
DataType dataType = utility::qualTypeToDataType(type);
|
||||
ParseLocation parseLocation;
|
||||
|
||||
parseLocation.endColumnNumber += dataType.getRawTypeName().size() - 1;
|
||||
if (!typeLoc.isNull())
|
||||
{
|
||||
while (typeLoc.getNextTypeLoc())
|
||||
{
|
||||
typeLoc = typeLoc.getNextTypeLoc();
|
||||
}
|
||||
|
||||
parseLocation = getParseLocation(typeLoc.getSourceRange());
|
||||
parseLocation.endColumnNumber += dataType.getRawTypeName().size() - 1;
|
||||
}
|
||||
|
||||
return ParseTypeUsage(parseLocation, dataType);
|
||||
}
|
||||
@@ -423,10 +444,16 @@ ParseTypeUsage ASTVisitor::getParseTypeUsage(clang::TypeLoc typeLoc, const clang
|
||||
ParseTypeUsage ASTVisitor::getParseTypeUsageOfReturnType(clang::FunctionDecl* declaration) const
|
||||
{
|
||||
// TODO: use FunctionDecl::getReturnTypeSourceRange() in newer clang version
|
||||
const clang::TypeSourceInfo *TSI = declaration->getTypeSourceInfo();
|
||||
const clang::FunctionTypeLoc FTL = TSI->getTypeLoc().IgnoreParens().getAs<clang::FunctionTypeLoc>();
|
||||
clang::TypeLoc typeLoc;
|
||||
|
||||
return getParseTypeUsage(FTL.getReturnLoc(), declaration->getReturnType());
|
||||
const clang::TypeSourceInfo *TSI = declaration->getTypeSourceInfo();
|
||||
if (TSI)
|
||||
{
|
||||
const clang::FunctionTypeLoc FTL = TSI->getTypeLoc().IgnoreParens().getAs<clang::FunctionTypeLoc>();
|
||||
typeLoc = FTL.getReturnLoc();
|
||||
}
|
||||
|
||||
return getParseTypeUsage(typeLoc, declaration->getReturnType());
|
||||
}
|
||||
|
||||
std::vector<ParseTypeUsage> ASTVisitor::getParameters(clang::FunctionDecl* declaration) const
|
||||
@@ -442,23 +469,42 @@ std::vector<ParseTypeUsage> ASTVisitor::getParameters(clang::FunctionDecl* decla
|
||||
return parameters;
|
||||
}
|
||||
|
||||
std::string ASTVisitor::getTypeName(const clang::QualType& qualType) const
|
||||
ParseVariable ASTVisitor::getParseVariable(clang::DeclaratorDecl* declaration) const
|
||||
{
|
||||
DataType dataType = utility::qualTypeToDataType(qualType);
|
||||
return dataType.getRawTypeName();
|
||||
bool isStatic = false;
|
||||
if (clang::isa<clang::VarDecl>(declaration))
|
||||
{
|
||||
clang::VarDecl* varDecl = clang::dyn_cast<clang::VarDecl>(declaration);
|
||||
isStatic = varDecl->isStaticDataMember() || varDecl->getStorageClass() == clang::SC_Static;
|
||||
}
|
||||
|
||||
return ParseVariable(
|
||||
getParseTypeUsage(declaration->getTypeSourceInfo()->getTypeLoc(), declaration->getType()),
|
||||
declaration->getQualifiedNameAsString(),
|
||||
isStatic
|
||||
);
|
||||
}
|
||||
|
||||
ParserClient::AccessType ASTVisitor::convertAccessType(clang::AccessSpecifier access) const
|
||||
ParseFunction ASTVisitor::getParseFunction(clang::FunctionDecl* declaration) const
|
||||
{
|
||||
switch (access)
|
||||
bool isStatic = false;
|
||||
bool isConst = false;
|
||||
if (clang::isa<clang::CXXMethodDecl>(declaration))
|
||||
{
|
||||
case clang::AS_public:
|
||||
return ParserClient::ACCESS_PUBLIC;
|
||||
case clang::AS_protected:
|
||||
return ParserClient::ACCESS_PROTECTED;
|
||||
case clang::AS_private:
|
||||
return ParserClient::ACCESS_PRIVATE;
|
||||
case clang::AS_none:
|
||||
return ParserClient::ACCESS_NONE;
|
||||
clang::CXXMethodDecl* methodDecl = clang::dyn_cast<clang::CXXMethodDecl>(declaration);
|
||||
isStatic = methodDecl->isStatic();
|
||||
isConst = methodDecl->isConst();
|
||||
}
|
||||
else
|
||||
{
|
||||
isStatic = declaration->getStorageClass() == clang::SC_Static;
|
||||
}
|
||||
|
||||
return ParseFunction(
|
||||
getParseTypeUsageOfReturnType(declaration),
|
||||
declaration->getQualifiedNameAsString(),
|
||||
getParameters(declaration),
|
||||
isStatic,
|
||||
isConst
|
||||
);
|
||||
}
|
||||
|
||||
@@ -39,25 +39,30 @@ public:
|
||||
virtual bool VisitEnumConstantDecl(clang::EnumConstantDecl* declaration); // enum fields
|
||||
|
||||
// ASTBodyVisitorClient implementation
|
||||
virtual void VisitCallExprInDeclBody(clang::NamedDecl* decl, clang::CallExpr* expr); // calls
|
||||
virtual void VisitCXXConstructExprInDeclBody(clang::NamedDecl* decl, clang::CXXConstructExpr* expr); // constructor calls
|
||||
virtual void VisitFieldUsageExprInDeclBody(clang::NamedDecl* decl, clang::MemberExpr* expr); // field usages
|
||||
virtual void VisitGlobalVariableUsageExprInDeclBody(clang::NamedDecl* decl, clang::DeclRefExpr* expr); // global variable usage
|
||||
virtual void VisitCallExprInDeclBody(clang::FunctionDecl* decl, clang::CallExpr* expr); // calls
|
||||
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
|
||||
|
||||
private:
|
||||
bool hasValidLocation(const clang::Decl* declaration) const;
|
||||
std::string getTypeName(const clang::QualType& qualType) const;
|
||||
ParserClient::AccessType convertAccessType(clang::AccessSpecifier) const;
|
||||
|
||||
ParseLocation getParseLocation(const clang::SourceRange& sourceRange) const;
|
||||
ParseLocation getParseLocationForNamedDecl(clang::NamedDecl* decl, const clang::SourceLocation& loc) const;
|
||||
ParseLocation getParseLocationForNamedDecl(clang::NamedDecl* decl) const;
|
||||
ParseLocation getParseLocationOfFunctionBody(clang::FunctionDecl* decl) const;
|
||||
ParseLocation getParseLocationOfRecordBody(clang::CXXRecordDecl* decl) const;
|
||||
ParseVariable getParseVariable(clang::DeclaratorDecl* declaration) const;
|
||||
|
||||
ParseTypeUsage getParseTypeUsage(clang::TypeLoc typeLoc, const clang::QualType& type) const;
|
||||
ParseTypeUsage getParseTypeUsageOfReturnType(clang::FunctionDecl* declaration) const;
|
||||
std::vector<ParseTypeUsage> getParameters(clang::FunctionDecl* declaration) const;
|
||||
DataType qualTypeToDataType(clang::QualType qualType);
|
||||
std::string getTypeName(const clang::QualType& qualType) const;
|
||||
ParserClient::AccessType convertAccessType(clang::AccessSpecifier) const;
|
||||
|
||||
ParseVariable getParseVariable(clang::DeclaratorDecl* declaration) const;
|
||||
ParseFunction getParseFunction(clang::FunctionDecl* declaration) const;
|
||||
|
||||
clang::ASTContext* m_context;
|
||||
std::shared_ptr<ParserClient> m_client;
|
||||
|
||||
Reference in New Issue
Block a user