summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorNoel Grandin <noel@peralex.com>2016-09-05 15:37:29 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2016-09-06 12:56:45 +0200
commitd69066115c73986b9956d1dfd070787ff6eebd6a (patch)
treeae4e0df6451c667ff2d759f4a107a388444e367d /compilerplugins
parent180a0eac238ce456771ff20b8d3274b43408f54c (diff)
improve loplugin:countusersofdefaultparams to check constructors
and their call sites Change-Id: Ie068cfe2a8f7c3887d38f186a5e91b0cfdcad236
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/countusersofdefaultparams.cxx42
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;
}