data: parsing and saving calls
This change parses calls in CxxParser by using the class ASTBodyVisitor which traverses the Stmts and Exprs in the body of the function and method declarations. The calls include: * calls in functions * calls in methods * constructor calls * constructor calls in initialization lists * implicit constructor calls of fields * calls to operators * global constructor calls of global variables * global function calls for global variables The calls don't include: * destructor calls * some calls to implicit constructors and copy constructors fortune cookie message = Don't be afraid to take that big step.
This commit is contained in:
@@ -50,6 +50,8 @@ 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;
|
||||
};
|
||||
|
||||
#endif // PARSER_CLIENT_H
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#include "data/parser/cxx/ASTBodyVisitor.h"
|
||||
|
||||
ASTBodyVisitor::ASTBodyVisitor(ASTBodyVisitorClient* client, clang::NamedDecl* parentDecl)
|
||||
: m_client(client)
|
||||
, m_parentDecl(parentDecl)
|
||||
{
|
||||
}
|
||||
|
||||
ASTBodyVisitor::~ASTBodyVisitor()
|
||||
{
|
||||
}
|
||||
|
||||
void ASTBodyVisitor::VisitStmt(clang::Stmt* stmt)
|
||||
{
|
||||
VisitChildren(stmt);
|
||||
}
|
||||
|
||||
void ASTBodyVisitor::VisitChildren(clang::Stmt* stmt)
|
||||
{
|
||||
for (clang::Stmt::child_range it = stmt->children(); it; it++)
|
||||
{
|
||||
if (*it)
|
||||
{
|
||||
static_cast<ASTBodyVisitor*>(this)->Visit(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ASTBodyVisitor::VisitCallExpr(clang::CallExpr* expr)
|
||||
{
|
||||
m_client->VisitCallExprInDeclBody(m_parentDecl, expr);
|
||||
|
||||
VisitStmt(expr);
|
||||
}
|
||||
|
||||
void ASTBodyVisitor::VisitCXXConstructExpr(clang::CXXConstructExpr* expr)
|
||||
{
|
||||
m_client->VisitCXXConstructExprInDeclBody(m_parentDecl, expr);
|
||||
|
||||
VisitStmt(expr);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef AST_BODY_VISITOR
|
||||
#define AST_BODY_VISITOR
|
||||
|
||||
#include "clang/AST/StmtVisitor.h"
|
||||
#include "data/parser/cxx/ASTBodyVisitorClient.h"
|
||||
|
||||
class ASTBodyVisitor: public clang::StmtVisitor<ASTBodyVisitor>
|
||||
{
|
||||
public:
|
||||
ASTBodyVisitor(ASTBodyVisitorClient* client, clang::NamedDecl* parentDecl);
|
||||
virtual ~ASTBodyVisitor();
|
||||
|
||||
void VisitStmt(clang::Stmt* stmt);
|
||||
void VisitChildren(clang::Stmt* stmt);
|
||||
void VisitCallExpr(clang::CallExpr* expr);
|
||||
void VisitCXXConstructExpr(clang::CXXConstructExpr* expr);
|
||||
|
||||
private:
|
||||
ASTBodyVisitorClient* m_client;
|
||||
clang::NamedDecl* m_parentDecl;
|
||||
};
|
||||
|
||||
#endif // AST_BODY_VISITOR
|
||||
@@ -0,0 +1,9 @@
|
||||
#include "data/parser/cxx/ASTBodyVisitorClient.h"
|
||||
|
||||
ASTBodyVisitorClient::ASTBodyVisitorClient()
|
||||
{
|
||||
}
|
||||
|
||||
ASTBodyVisitorClient::~ASTBodyVisitorClient()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef AST_BODY_VISITOR_CLIENT_H
|
||||
#define AST_BODY_VISITOR_CLIENT_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
|
||||
class ASTBodyVisitorClient
|
||||
{
|
||||
public:
|
||||
ASTBodyVisitorClient();
|
||||
virtual ~ASTBodyVisitorClient();
|
||||
|
||||
virtual void VisitCallExprInDeclBody(clang::NamedDecl* decl, clang::CallExpr* expr) = 0;
|
||||
virtual void VisitCXXConstructExprInDeclBody(clang::NamedDecl* decl, clang::CXXConstructExpr* expr) = 0;
|
||||
};
|
||||
|
||||
#endif // AST_BODY_VISITOR_CLIENT_H
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "data/parser/cxx/ASTVisitor.h"
|
||||
|
||||
#include "data/parser/cxx/ASTBodyVisitor.h"
|
||||
#include "data/parser/ParseLocation.h"
|
||||
#include "data/parser/ParseVariable.h"
|
||||
|
||||
@@ -13,6 +14,11 @@ ASTVisitor::~ASTVisitor()
|
||||
{
|
||||
}
|
||||
|
||||
bool ASTVisitor::VisitStmt(const clang::Stmt* statement)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ASTVisitor::VisitTypedefDecl(const clang::TypedefDecl* declaration)
|
||||
{
|
||||
if (hasValidLocation(declaration))
|
||||
@@ -84,6 +90,12 @@ bool ASTVisitor::VisitVarDecl(clang::VarDecl* declaration)
|
||||
getParseLocation(declaration->getSourceRange()),
|
||||
getParseVariable(declaration)
|
||||
);
|
||||
|
||||
if (declaration->getInit())
|
||||
{
|
||||
ASTBodyVisitor bodyVisitor(this, declaration);
|
||||
bodyVisitor.Visit(declaration->getInit());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -128,6 +140,12 @@ bool ASTVisitor::VisitFunctionDecl(clang::FunctionDecl* declaration)
|
||||
getTypeName(declaration->getReturnType()),
|
||||
getParameters(declaration)
|
||||
);
|
||||
|
||||
if (declaration->hasBody())
|
||||
{
|
||||
ASTBodyVisitor bodyVisitor(this, declaration);
|
||||
bodyVisitor.Visit(declaration->getBody());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -157,6 +175,29 @@ bool ASTVisitor::VisitCXXMethodDecl(clang::CXXMethodDecl* declaration)
|
||||
declaration->isConst(),
|
||||
declaration->isStatic()
|
||||
);
|
||||
|
||||
if (declaration->hasBody())
|
||||
{
|
||||
ASTBodyVisitor bodyVisitor(this, declaration);
|
||||
bodyVisitor.Visit(declaration->getBody());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ASTVisitor::VisitCXXConstructorDecl(clang::CXXConstructorDecl* declaration)
|
||||
{
|
||||
if (hasValidLocation(declaration))
|
||||
{
|
||||
for (clang::CXXConstructorDecl::init_const_iterator it = declaration->init_begin(); it != declaration->init_end(); it++)
|
||||
{
|
||||
if ((*it)->getInit())
|
||||
{
|
||||
ASTBodyVisitor bodyVisitor(this, declaration);
|
||||
bodyVisitor.Visit((*it)->getInit());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -202,6 +243,38 @@ bool ASTVisitor::VisitEnumConstantDecl(clang::EnumConstantDecl* declaration)
|
||||
return true;
|
||||
}
|
||||
|
||||
void ASTVisitor::VisitCallExprInDeclBody(clang::NamedDecl* decl, clang::CallExpr* expr)
|
||||
{
|
||||
// if (clang::FunctionDecl *CalleeDecl = CE->getDirectCallee())
|
||||
// {
|
||||
// return CalleeDecl;
|
||||
// }
|
||||
|
||||
// clang::Expr *CEE = CE->getCallee()->IgnoreParenImpCasts();
|
||||
// if (clang::BlockExpr *Block = clang::dyn_cast<clang::BlockExpr>(CEE))
|
||||
// {
|
||||
// NumBlockCallEdges++;
|
||||
// return Block->getBlockDecl();
|
||||
// }
|
||||
|
||||
// return nullptr;
|
||||
|
||||
m_client->onCallParsed(
|
||||
getParseLocation(expr->getSourceRange()),
|
||||
decl->getQualifiedNameAsString(),
|
||||
expr->getDirectCallee()->getQualifiedNameAsString()
|
||||
);
|
||||
}
|
||||
|
||||
void ASTVisitor::VisitCXXConstructExprInDeclBody(clang::NamedDecl* decl, clang::CXXConstructExpr* expr)
|
||||
{
|
||||
m_client->onCallParsed(
|
||||
getParseLocation(expr->getSourceRange()),
|
||||
decl->getQualifiedNameAsString(),
|
||||
expr->getConstructor()->getQualifiedNameAsString()
|
||||
);
|
||||
}
|
||||
|
||||
bool ASTVisitor::hasValidLocation(const clang::Decl* declaration) const
|
||||
{
|
||||
const clang::SourceLocation& location = declaration->getLocStart();
|
||||
|
||||
@@ -6,32 +6,42 @@
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/RecursiveASTVisitor.h"
|
||||
|
||||
#include "data/parser/cxx/ASTBodyVisitorClient.h"
|
||||
#include "data/parser/ParserClient.h"
|
||||
|
||||
class ASTVisitor: public clang::RecursiveASTVisitor<ASTVisitor>
|
||||
class ASTVisitor
|
||||
: public clang::RecursiveASTVisitor<ASTVisitor>
|
||||
, public ASTBodyVisitorClient
|
||||
{
|
||||
public:
|
||||
ASTVisitor(clang::ASTContext* context, std::shared_ptr<ParserClient> client);
|
||||
virtual ~ASTVisitor();
|
||||
|
||||
// Left for debugging purposes. Uncomment to see a colored ast-dump of the parsed file.
|
||||
// virtual bool VisitDecl(clang::Decl* declaration)
|
||||
// virtual bool VisitTranslationUnitDecl(clang::TranslationUnitDecl* decl)
|
||||
// {
|
||||
// // declaration->print(llvm::outs());
|
||||
// declaration->dump();
|
||||
// return false;
|
||||
// decl->dump();
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// RecursiveASTVisitor implementation
|
||||
virtual bool VisitStmt(const clang::Stmt* statement); // avoid visiting
|
||||
|
||||
virtual bool VisitTypedefDecl(const clang::TypedefDecl* declaration); // typedefs
|
||||
virtual bool VisitCXXRecordDecl(clang::CXXRecordDecl* declaration); // structs, classes and inheritance
|
||||
virtual bool VisitVarDecl(clang::VarDecl* declaration); // global variables and static fields
|
||||
virtual bool VisitFieldDecl(clang::FieldDecl* declaration); // fields
|
||||
virtual bool VisitFunctionDecl(clang::FunctionDecl* declaration); // functions
|
||||
virtual bool VisitCXXMethodDecl(clang::CXXMethodDecl* declaration); // methods
|
||||
virtual bool VisitCXXConstructorDecl(clang::CXXConstructorDecl* declaration); // initialization list
|
||||
virtual bool VisitNamespaceDecl(clang::NamespaceDecl* declaration); // namespaces
|
||||
virtual bool VisitEnumDecl(clang::EnumDecl* declaration); // enums
|
||||
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
|
||||
|
||||
private:
|
||||
bool hasValidLocation(const clang::Decl* declaration) const;
|
||||
ParseLocation getParseLocation(const clang::SourceRange& sourceRange) const;
|
||||
|
||||
Reference in New Issue
Block a user