Kaydet (Commit) 442dd6a1 authored tarafından Noel Grandin's avatar Noel Grandin

loplugin: move parentFunctionDecl() into common code

Change-Id: Ia10a76a98a63c6ea3b516d9146281f672b213ab3
üst e3e79246
......@@ -75,6 +75,33 @@ Stmt* Plugin::parentStmt( Stmt* stmt )
return const_cast< Stmt* >( parents[ stmt ] );
}
static const Decl* getDeclContext(ASTContext& context, const Stmt* stmt)
{
auto it = context.getParents(*stmt).begin();
if (it == context.getParents(*stmt).end())
return nullptr;
const Decl *aDecl = it->get<Decl>();
if (aDecl)
return aDecl;
const Stmt *aStmt = it->get<Stmt>();
if (aStmt)
return getDeclContext(context, aStmt);
return nullptr;
}
const FunctionDecl* Plugin::parentFunctionDecl( const Stmt* stmt )
{
const Decl *decl = getDeclContext(compiler.getASTContext(), stmt);
if (decl)
return static_cast<const FunctionDecl*>(decl->getNonClosureContext());
return nullptr;
}
bool Plugin::isInUnoIncludeFile(SourceLocation spellingLocation) const {
StringRef name {
......
......@@ -69,6 +69,7 @@ class Plugin
*/
const Stmt* parentStmt( const Stmt* stmt );
Stmt* parentStmt( Stmt* stmt );
const FunctionDecl* parentFunctionDecl( const Stmt* stmt );
/**
Checks if the location is inside an UNO file, more specifically, if it forms part of the URE stable interface,
which is not allowed to be changed.
......
......@@ -155,33 +155,6 @@ bool SingleValFields::VisitCXXConstructorDecl( const CXXConstructorDecl* decl )
return true;
}
const Decl* get_DeclContext_from_Stmt(ASTContext& context, const Stmt& stmt)
{
auto it = context.getParents(stmt).begin();
if (it == context.getParents(stmt).end())
return nullptr;
const Decl *aDecl = it->get<Decl>();
if (aDecl)
return aDecl;
const Stmt *aStmt = it->get<Stmt>();
if (aStmt)
return get_DeclContext_from_Stmt(context, *aStmt);
return nullptr;
}
const FunctionDecl* SingleValFields::get_top_FunctionDecl_from_Stmt(const Stmt& stmt)
{
const Decl *decl = get_DeclContext_from_Stmt(compiler.getASTContext(), stmt);
if (decl)
return static_cast<const FunctionDecl*>(decl->getNonClosureContext());
return nullptr;
}
/**
* Check for calls to methods where a pointer to something is cast to a pointer to void.
* At which case it could have anything written to it.
......@@ -269,8 +242,8 @@ bool SingleValFields::VisitMemberExpr( const MemberExpr* memberExpr )
if (ignoreLocation(memberExpr) || !isInterestingType(fieldDecl->getType()))
return true;
const FunctionDecl* parentFunctionDecl = get_top_FunctionDecl_from_Stmt(*memberExpr);
const CXXMethodDecl* methodDecl = dyn_cast_or_null<CXXMethodDecl>(parentFunctionDecl);
const FunctionDecl* parentFunction = parentFunctionDecl(memberExpr);
const CXXMethodDecl* methodDecl = dyn_cast_or_null<CXXMethodDecl>(parentFunction);
if (methodDecl && (methodDecl->isCopyAssignmentOperator() || methodDecl->isMoveAssignmentOperator()))
return true;
......@@ -285,7 +258,7 @@ bool SingleValFields::VisitMemberExpr( const MemberExpr* memberExpr )
if (parent && isa<ReturnStmt>(parent)) {
const Stmt* parent2 = parentStmt(parent);
if (parent2 && isa<CompoundStmt>(parent2)) {
QualType qt = parentFunctionDecl->getReturnType().getDesugaredType(compiler.getASTContext());
QualType qt = parentFunction->getReturnType().getDesugaredType(compiler.getASTContext());
if (!qt.isConstQualified() && qt->isReferenceType()) {
assignValue = "?";
bPotentiallyAssignedTo = true;
......
......@@ -210,8 +210,15 @@ bool UnusedFields::VisitMemberExpr( const MemberExpr* memberExpr )
if (!fieldDecl) {
return true;
}
MyFieldInfo fieldInfo = niceName(fieldDecl);
touchedSet.insert(fieldInfo);
// ignore move/copy operator, it's self->self
const FunctionDecl* parentFunction = parentFunctionDecl(memberExpr);
const CXXMethodDecl* methodDecl = dyn_cast_or_null<CXXMethodDecl>(parentFunction);
if (!methodDecl || !(methodDecl->isCopyAssignmentOperator() || methodDecl->isMoveAssignmentOperator())) {
touchedSet.insert(fieldInfo);
}
// for the write-only analysis
......
......@@ -221,33 +221,6 @@ void UnusedMethods::logCallToRootMethods(const FunctionDecl* functionDecl, std::
// prevent recursive templates from blowing up the stack
static std::set<std::string> traversedFunctionSet;
const Decl* get_DeclContext_from_Stmt(ASTContext& context, const Stmt& stmt)
{
auto it = context.getParents(stmt).begin();
if (it == context.getParents(stmt).end())
return nullptr;
const Decl *aDecl = it->get<Decl>();
if (aDecl)
return aDecl;
const Stmt *aStmt = it->get<Stmt>();
if (aStmt)
return get_DeclContext_from_Stmt(context, *aStmt);
return nullptr;
}
static const FunctionDecl* get_top_FunctionDecl_from_Stmt(ASTContext& context, const Stmt& stmt)
{
const Decl *decl = get_DeclContext_from_Stmt(context, stmt);
if (decl)
return static_cast<const FunctionDecl*>(decl->getNonClosureContext());
return nullptr;
}
bool UnusedMethods::VisitCallExpr(CallExpr* expr)
{
// Note that I don't ignore ANYTHING here, because I want to get calls to my code that result
......@@ -285,9 +258,9 @@ gotfunc:
CXXMethodDecl* calleeMethodDecl = dyn_cast<CXXMethodDecl>(calleeFunctionDecl);
if (calleeMethodDecl && calleeMethodDecl->getAccess() == AS_public)
{
const FunctionDecl* parentFunctionDecl = get_top_FunctionDecl_from_Stmt(compiler.getASTContext(), *expr);
if (parentFunctionDecl && parentFunctionDecl != calleeFunctionDecl) {
calledFromOutsideSet.insert(niceName(parentFunctionDecl));
const FunctionDecl* parentFunction = parentFunctionDecl(expr);
if (parentFunction && parentFunction != calleeFunctionDecl) {
calledFromOutsideSet.insert(niceName(parentFunction));
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment