diff options
author | Noel Grandin <noel@peralex.com> | 2016-09-05 15:37:29 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2016-09-06 12:56:45 +0200 |
commit | d69066115c73986b9956d1dfd070787ff6eebd6a (patch) | |
tree | ae4e0df6451c667ff2d759f4a107a388444e367d | |
parent | 180a0eac238ce456771ff20b8d3274b43408f54c (diff) |
improve loplugin:countusersofdefaultparams to check constructors
and their call sites
Change-Id: Ie068cfe2a8f7c3887d38f186a5e91b0cfdcad236
-rw-r--r-- | compilerplugins/clang/countusersofdefaultparams.cxx | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/compilerplugins/clang/countusersofdefaultparams.cxx b/compilerplugins/clang/countusersofdefaultparams.cxx index de8d8e52bb24..a425cfcb89cc 100644 --- a/compilerplugins/clang/countusersofdefaultparams.cxx +++ b/compilerplugins/clang/countusersofdefaultparams.cxx @@ -81,8 +81,9 @@ public: bool shouldVisitTemplateInstantiations () const { return true; } - bool VisitCallExpr(CallExpr * callExpr); - bool VisitFunctionDecl( const FunctionDecl* functionDecl ); + bool VisitCallExpr( const CallExpr * ); + bool VisitFunctionDecl( const FunctionDecl* ); + bool VisitCXXConstructExpr( const CXXConstructExpr * ); private: void niceName(const FunctionDecl* functionDecl, MyFuncInfo&); std::string locationToString(const SourceLocation&); @@ -131,7 +132,7 @@ void CountUsersOfDefaultParams::niceName(const FunctionDecl* functionDecl, MyFun aInfo.sourceLocation = locationToString(functionDecl->getLocation()); } -bool CountUsersOfDefaultParams::VisitCallExpr(CallExpr * callExpr) { +bool CountUsersOfDefaultParams::VisitCallExpr(const CallExpr * callExpr) { if (ignoreLocation(callExpr)) { return true; } @@ -180,6 +181,38 @@ bool CountUsersOfDefaultParams::VisitCallExpr(CallExpr * callExpr) { return true; } +bool CountUsersOfDefaultParams::VisitCXXConstructExpr(const CXXConstructExpr * constructExpr) { + if (ignoreLocation(constructExpr)) { + return true; + } + const CXXConstructorDecl* constructorDecl = constructExpr->getConstructor()->getCanonicalDecl(); + // work our way back to the root definition for template methods + if (constructorDecl->getInstantiatedFromMemberFunction()) + constructorDecl = dyn_cast<CXXConstructorDecl>(constructorDecl->getInstantiatedFromMemberFunction()); + else if (constructorDecl->getClassScopeSpecializationPattern()) + constructorDecl = dyn_cast<CXXConstructorDecl>(constructorDecl->getClassScopeSpecializationPattern()); +// workaround clang-3.5 issue +#if CLANG_VERSION >= 30600 + else if (constructorDecl->getTemplateInstantiationPattern()) + constructorDecl = dyn_cast<CXXConstructorDecl>(constructorDecl->getTemplateInstantiationPattern()); +#endif + int n = constructorDecl->getNumParams() - 1; + if (n < 0 || !constructorDecl->getParamDecl(n)->hasDefaultArg()) { + return true; + } + while (n > 0 && constructorDecl->getParamDecl(n-1)->hasDefaultArg()) { + --n; + } + // look for callsites that are actually using the defaulted values + if ( n < (int)constructExpr->getNumArgs() && constructExpr->getArg(n)->isDefaultArgument()) { + MyCallInfo callInfo; + niceName(constructorDecl, callInfo); + callInfo.sourceLocationOfCall = locationToString(constructExpr->getLocStart()); + callSet.insert(callInfo); + } + return true; +} + std::string CountUsersOfDefaultParams::locationToString(const SourceLocation& sourceLoc) { SourceLocation expansionLoc = compiler.getSourceManager().getExpansionLoc( sourceLoc ); @@ -207,9 +240,6 @@ bool CountUsersOfDefaultParams::VisitFunctionDecl( const FunctionDecl* functionD if (isa<CXXDestructorDecl>(functionDecl)) { return true; } - if (isa<CXXConstructorDecl>(functionDecl)) { - return true; - } if (functionDecl->isDeleted()) { return true; } |