From f0f973da8560e16cba85d2c9465c3a8c4c0ebbb3 Mon Sep 17 00:00:00 2001 From: Noel Grandin Date: Wed, 16 Mar 2016 08:49:35 +0200 Subject: loplugin:constantparams in vcl/ also some improvements to the plugin Change-Id: I0e3a519d70756e577fcb1bd47dd66864b5b4c871 Reviewed-on: https://gerrit.libreoffice.org/23289 Reviewed-by: Noel Grandin Tested-by: Noel Grandin --- compilerplugins/clang/constantparam.cxx | 115 +++++++++++++++++++++++--------- 1 file changed, 83 insertions(+), 32 deletions(-) (limited to 'compilerplugins') diff --git a/compilerplugins/clang/constantparam.cxx b/compilerplugins/clang/constantparam.cxx index 3385265a877a..570cb96ca9f5 100644 --- a/compilerplugins/clang/constantparam.cxx +++ b/compilerplugins/clang/constantparam.cxx @@ -32,6 +32,7 @@ struct MyCallSiteInfo std::string returnType; std::string nameAndParams; std::string paramName; + int paramIndex; // because in some declarations the names are empty std::string callValue; std::string sourceLocation; }; @@ -41,6 +42,10 @@ bool operator < (const MyCallSiteInfo &lhs, const MyCallSiteInfo &rhs) return true; else if (lhs.sourceLocation > rhs.sourceLocation) return false; + else if (lhs.paramIndex < rhs.paramIndex) + return true; + else if (lhs.paramIndex > rhs.paramIndex) + return false; else return lhs.callValue < rhs.callValue; } @@ -59,7 +64,21 @@ public: // there is a crash here that I can't seem to workaround // clang-3.8: /home/noel/clang/src/tools/clang/lib/AST/Type.cpp:1878: bool clang::Type::isConstantSizeType() const: Assertion `!isDependentType() && "This doesn't make sense for dependent types"' failed. FileID mainFileID = compiler.getSourceManager().getMainFileID(); - if (strstr(compiler.getSourceManager().getFileEntryForID(mainFileID)->getDir()->getName(), "oox/source/dump") != 0) { + static const char* prefix = SRCDIR "/oox/source"; + const FileEntry * fe = compiler.getSourceManager().getFileEntryForID(mainFileID); + if (strncmp(prefix, fe->getDir()->getName(), strlen(prefix)) == 0) { + return; + } + if (strcmp(fe->getDir()->getName(), SRCDIR "/sw/source/filter/ww8") == 0) + { + return; + } + if (strcmp(fe->getDir()->getName(), SRCDIR "/sc/source/filter/oox") == 0) + { + return; + } + if (strcmp(fe->getDir()->getName(), SRCDIR "/sd/source/filter/eppt") == 0) + { return; } @@ -79,14 +98,17 @@ public: } bool shouldVisitTemplateInstantiations () const { return true; } + bool shouldVisitImplicitCode () const { return true; } - bool VisitCallExpr(CallExpr * callExpr); - bool VisitDeclRefExpr( const DeclRefExpr* declRefExpr ); + bool VisitCallExpr( const CallExpr* ); + bool VisitDeclRefExpr( const DeclRefExpr* ); + bool VisitCXXConstructExpr( const CXXConstructExpr* ); private: - MyCallSiteInfo niceName(const FunctionDecl* functionDecl, const ParmVarDecl* parmVarDecl, const std::string& callValue); + MyCallSiteInfo niceName(const FunctionDecl* functionDecl, int paramIndex, const ParmVarDecl* parmVarDecl, const std::string& callValue); + std::string getCallValue(const Expr* arg); }; -MyCallSiteInfo ConstantParam::niceName(const FunctionDecl* functionDecl, const ParmVarDecl* parmVarDecl, const std::string& callValue) +MyCallSiteInfo ConstantParam::niceName(const FunctionDecl* functionDecl, int paramIndex, const ParmVarDecl* parmVarDecl, const std::string& callValue) { if (functionDecl->getInstantiatedFromMemberFunction()) functionDecl = functionDecl->getInstantiatedFromMemberFunction(); @@ -120,6 +142,7 @@ MyCallSiteInfo ConstantParam::niceName(const FunctionDecl* functionDecl, const P aInfo.nameAndParams += " const"; } aInfo.paramName = parmVarDecl->getName(); + aInfo.paramIndex = paramIndex; aInfo.callValue = callValue; SourceLocation expansionLoc = compiler.getSourceManager().getExpansionLoc( functionDecl->getLocation() ); @@ -129,7 +152,22 @@ MyCallSiteInfo ConstantParam::niceName(const FunctionDecl* functionDecl, const P return aInfo; } -bool ConstantParam::VisitCallExpr(CallExpr * callExpr) { +std::string ConstantParam::getCallValue(const Expr* arg) +{ + arg = arg->IgnoreParenCasts(); + // ignore this, it seems to trigger an infinite recursion + if (isa(arg)) { + return "unknown"; + } + APSInt x1; + if (arg->EvaluateAsInt(x1, compiler.getASTContext())) + { + return x1.toString(10); + } + return "unknown"; +} + +bool ConstantParam::VisitCallExpr(const CallExpr * callExpr) { if (ignoreLocation(callExpr)) { return true; } @@ -175,29 +213,11 @@ bool ConstantParam::VisitCallExpr(CallExpr * callExpr) { for (unsigned i = 0; i < callExpr->getNumArgs(); ++i) { if (i >= functionDecl->getNumParams()) // can happen in template code break; - Expr* arg = callExpr->getArg(i); - bool found = false; - std::string callValue; - // ignore this, it seems to trigger an infinite recursion - if (isa(arg->IgnoreParenCasts())) { - found = true; - callValue = "unknown"; - } - if (!found) - { - APSInt x1; - if (arg->EvaluateAsInt(x1, compiler.getASTContext())) - { - found = true; - callValue = x1.toString(10); - } - } - if (!found) - callValue = "unknown"; + const Expr* arg = callExpr->getArg(i); + std::string callValue = getCallValue(arg); const ParmVarDecl* parmVarDecl = functionDecl->getParamDecl(i); - MyCallSiteInfo funcInfo = niceName(functionDecl, parmVarDecl, callValue); + MyCallSiteInfo funcInfo = niceName(functionDecl, i, parmVarDecl, callValue); callSet.insert(funcInfo); - break; } return true; } @@ -205,16 +225,47 @@ bool ConstantParam::VisitCallExpr(CallExpr * callExpr) { // this catches places that take the address of a method bool ConstantParam::VisitDeclRefExpr( const DeclRefExpr* declRefExpr ) { - const Decl* functionDecl = declRefExpr->getDecl(); - if (!isa(functionDecl)) { + const Decl* decl = declRefExpr->getDecl(); + if (!isa(decl)) { return true; } -// TODO -// MyCallSiteInfo funcInfo = niceName(dyn_cast(functionDecl)); -// callSet.insert(funcInfo); + const FunctionDecl* functionDecl = dyn_cast(decl); + for (unsigned i = 0; i < functionDecl->getNumParams(); ++i) + { + MyCallSiteInfo funcInfo = niceName(functionDecl, i, functionDecl->getParamDecl(i), "unknown"); + callSet.insert(funcInfo); + } + return true; +} + +bool ConstantParam::VisitCXXConstructExpr( const CXXConstructExpr* constructExpr ) +{ + const CXXConstructorDecl* constructorDecl = constructExpr->getConstructor(); + constructorDecl = constructorDecl->getCanonicalDecl(); + + // ignore stuff that forms part of the stable URE interface + if (isInUnoIncludeFile(compiler.getSourceManager().getSpellingLoc( + constructorDecl->getNameInfo().getLoc()))) { + return true; + } + if (constructorDecl->getNameInfo().getLoc().isValid() && ignoreLocation(constructorDecl)) { + return true; + } + + for (unsigned i = 0; i < constructExpr->getNumArgs(); ++i) + { + if (i >= constructorDecl->getNumParams()) // can happen in template code + break; + const Expr* arg = constructExpr->getArg(i); + std::string callValue = getCallValue(arg); + const ParmVarDecl* parmVarDecl = constructorDecl->getParamDecl(i); + MyCallSiteInfo funcInfo = niceName(constructorDecl, i, parmVarDecl, callValue); + callSet.insert(funcInfo); + } return true; } + loplugin::Plugin::Registration< ConstantParam > X("constantparam", false); } -- cgit