diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2017-07-26 13:28:09 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2017-07-27 12:39:38 +0200 |
commit | 370c71f5b1e2618c49881ac221993692143d4e58 (patch) | |
tree | 4dc9cccb3029f81d395b02b617b3133a77d5bbe0 /compilerplugins | |
parent | f0684222540b96d8366ce175c522b64472361b80 (diff) |
simplify unusedfields plugin
using some wrappers around callee and caller AST nodes
Change-Id: I599a04a18caa3ada70bcb266e228208b7a81f1a1
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/unusedfields.cxx | 75 |
1 files changed, 38 insertions, 37 deletions
diff --git a/compilerplugins/clang/unusedfields.cxx b/compilerplugins/clang/unusedfields.cxx index fb7f7df35418..b8af5aa7d896 100644 --- a/compilerplugins/clang/unusedfields.cxx +++ b/compilerplugins/clang/unusedfields.cxx @@ -66,6 +66,33 @@ static std::set<MyFieldInfo> readFromSet; static std::set<MyFieldInfo> writeToSet; static std::set<MyFieldInfo> definitionSet; +/** + * Wrap the different kinds of callable and callee objects in the clang AST so I can define methods that handle everything. + */ +class CallerWrapper +{ + const CallExpr * m_callExpr; + const CXXConstructExpr * m_cxxConstructExpr; +public: + CallerWrapper(const CallExpr * callExpr) : m_callExpr(callExpr), m_cxxConstructExpr(nullptr) {} + CallerWrapper(const CXXConstructExpr * cxxConstructExpr) : m_callExpr(nullptr), m_cxxConstructExpr(cxxConstructExpr) {} + unsigned getNumArgs () const + { return m_callExpr ? m_callExpr->getNumArgs() : m_cxxConstructExpr->getNumArgs(); } + const Expr * getArg (unsigned i) const + { return m_callExpr ? m_callExpr->getArg(i) : m_cxxConstructExpr->getArg(i); } +}; +class CalleeWrapper +{ + const FunctionDecl * m_calleeFunctionDecl; + const CXXConstructorDecl * m_cxxConstructorDecl; +public: + CalleeWrapper(const FunctionDecl * calleeFunctionDecl) : m_calleeFunctionDecl(calleeFunctionDecl), m_cxxConstructorDecl(nullptr) {} + CalleeWrapper(const CXXConstructExpr * cxxConstructExpr) : m_calleeFunctionDecl(nullptr), m_cxxConstructorDecl(cxxConstructExpr->getConstructor()) {} + unsigned getNumParams () const + { return m_calleeFunctionDecl ? m_calleeFunctionDecl->getNumParams() : m_cxxConstructorDecl->getNumParams(); } + const ParmVarDecl * getParamDecl (unsigned i) const + { return m_calleeFunctionDecl ? m_calleeFunctionDecl->getParamDecl(i) : m_cxxConstructorDecl->getParamDecl(i); } +}; class UnusedFields: public RecursiveASTVisitor<UnusedFields>, public loplugin::Plugin @@ -93,9 +120,8 @@ private: void checkWriteOnly(const FieldDecl* fieldDecl, const Expr* memberExpr); void checkReadOnly(const FieldDecl* fieldDecl, const Expr* memberExpr); bool isSomeKindOfZero(const Expr* arg); - bool IsPassedByNonConst(const FieldDecl* fieldDecl, const Stmt * child, const CallExpr * callExpr, - const FunctionDecl * calleeFunctionDecl); - bool IsPassedByNonConst(const FieldDecl* fieldDecl, const Stmt * child, const CXXConstructExpr * cxxConstructExpr); + bool IsPassedByNonConst(const FieldDecl* fieldDecl, const Stmt * child, CallerWrapper callExpr, + CalleeWrapper calleeFunctionDecl); RecordDecl * insideMoveOrCopyDeclParent; RecordDecl * insideStreamOutputOperator; @@ -655,7 +681,7 @@ void UnusedFields::checkReadOnly(const FieldDecl* fieldDecl, const Expr* memberE } else if (auto cxxConstructExpr = dyn_cast<CXXConstructExpr>(parent)) { - if (IsPassedByNonConst(fieldDecl, child, cxxConstructExpr)) + if (IsPassedByNonConst(fieldDecl, child, cxxConstructExpr, cxxConstructExpr)) bPotentiallyWrittenTo = true; break; } @@ -750,55 +776,30 @@ void UnusedFields::checkReadOnly(const FieldDecl* fieldDecl, const Expr* memberE writeToSet.insert(fieldInfo); } -bool UnusedFields::IsPassedByNonConst(const FieldDecl* fieldDecl, const Stmt * child, const CallExpr * callExpr, - const FunctionDecl * calleeFunctionDecl) +bool UnusedFields::IsPassedByNonConst(const FieldDecl* fieldDecl, const Stmt * child, CallerWrapper callExpr, + CalleeWrapper calleeFunctionDecl) { - unsigned len = std::min(callExpr->getNumArgs(), - calleeFunctionDecl->getNumParams()); + unsigned len = std::min(callExpr.getNumArgs(), + calleeFunctionDecl.getNumParams()); // if it's an array, passing it by value to a method typically means the // callee takes a pointer and can modify the array if (fieldDecl->getType()->isConstantArrayType()) { for (unsigned i = 0; i < len; ++i) - if (callExpr->getArg(i) == child) - if (loplugin::TypeCheck(calleeFunctionDecl->getParamDecl(i)->getType()).NonConst().Pointer()) + if (callExpr.getArg(i) == child) + if (loplugin::TypeCheck(calleeFunctionDecl.getParamDecl(i)->getType()).NonConst().Pointer()) return true; } else { for (unsigned i = 0; i < len; ++i) - if (callExpr->getArg(i) == child) - if (loplugin::TypeCheck(calleeFunctionDecl->getParamDecl(i)->getType()).NonConst().LvalueReference()) + if (callExpr.getArg(i) == child) + if (loplugin::TypeCheck(calleeFunctionDecl.getParamDecl(i)->getType()).NonConst().LvalueReference()) return true; } return false; } -bool UnusedFields::IsPassedByNonConst(const FieldDecl* fieldDecl, const Stmt * child, const CXXConstructExpr * cxxConstructExpr) -{ - const CXXConstructorDecl * cxxConstructorDecl = cxxConstructExpr->getConstructor(); - unsigned len = std::min(cxxConstructExpr->getNumArgs(), - cxxConstructorDecl->getNumParams()); - // if it's an array, passing it by value to a method typically means the - // callee takes a pointer and can modify the array - if (fieldDecl->getType()->isConstantArrayType()) - { - for (unsigned i = 0; i < len; ++i) - if (cxxConstructExpr->getArg(i) == child) - if (loplugin::TypeCheck(cxxConstructorDecl->getParamDecl(i)->getType()).NonConst().Pointer()) - return true; - } - else - { - for (unsigned i = 0; i < len; ++i) - if (cxxConstructExpr->getArg(i) == child) - if (loplugin::TypeCheck(cxxConstructorDecl->getParamDecl(i)->getType()).NonConst().LvalueReference()) - return true; - - } - return false; -} - // fields that are assigned via member initialisers do not get visited in VisitDeclRef, so // have to do it here bool UnusedFields::VisitCXXConstructorDecl( const CXXConstructorDecl* cxxConstructorDecl ) |