summaryrefslogtreecommitdiff
path: root/compilerplugins/clang/store/oncevar.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'compilerplugins/clang/store/oncevar.cxx')
-rw-r--r--compilerplugins/clang/store/oncevar.cxx166
1 files changed, 0 insertions, 166 deletions
diff --git a/compilerplugins/clang/store/oncevar.cxx b/compilerplugins/clang/store/oncevar.cxx
deleted file mode 100644
index 1947515cd749..000000000000
--- a/compilerplugins/clang/store/oncevar.cxx
+++ /dev/null
@@ -1,166 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-#include <string>
-#include <iostream>
-#include <unordered_map>
-
-#include "plugin.hxx"
-#include "check.hxx"
-#include "clang/AST/CXXInheritance.h"
-
-// Idea from tml.
-// Check for OUString/char[] variables that are
-// (1) initialised from a string literal
-// (2) only used in one spot
-// In which case, we might as well inline it.
-
-namespace
-{
-
-class OnceVar:
- public RecursiveASTVisitor<OnceVar>, public loplugin::Plugin
-{
-public:
- explicit OnceVar(InstantiationData const & data): Plugin(data) {}
-
- virtual void run() override {
- // ignore some files with problematic macros
- std::string fn( compiler.getSourceManager().getFileEntryForID(
- compiler.getSourceManager().getMainFileID())->getName() );
- normalizeDotDotInFilePath(fn);
- // TODO not possible here, need to figure out how to ignore cases where we index
- // into the string
- if (fn == SRCDIR "/vcl/source/filter/ixpm/xpmread.cxx")
- return;
- if (fn == SRCDIR "/sc/source/filter/excel/xiescher.cxx")
- return;
- // all the constants are nicely lined up at the top of the file, seems
- // a pity to just inline a handful.
- if (fn == SRCDIR "/sc/source/ui/docshell/docsh.cxx")
- return;
- if (fn == SRCDIR "/sw/source/core/text/EnhancedPDFExportHelper.cxx")
- return;
- if (fn == SRCDIR "/svgio/source/svgreader/svgtoken.cxx")
- return;
- // TODO explicit length array
- if (fn == SRCDIR "/sal/qa/osl/file/osl_File.cxx")
- return;
-
- TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
-
- for (auto it = maVarUsesMap.cbegin(); it != maVarUsesMap.cend(); ++it)
- {
- if (it->second == 1)
- {
- report(DiagnosticsEngine::Warning,
- "string/char[] var used only once, should be inlined",
- it->first)
- << maVarDeclSourceRangeMap[it->first];
- report(DiagnosticsEngine::Note,
- "to this spot",
- maVarUseSourceRangeMap[it->first].getBegin())
- << maVarUseSourceRangeMap[it->first];
- }
- }
- }
-
- bool VisitDeclRefExpr( const DeclRefExpr* );
-
-private:
- StringRef getFilename(SourceLocation loc);
-
- struct SourceLocationHash
- {
- size_t operator()( SourceLocation const & sl ) const
- {
- return sl.getRawEncoding();
- }
- };
- std::unordered_map<SourceLocation, int, SourceLocationHash> maVarUsesMap;
- std::unordered_map<SourceLocation, SourceRange, SourceLocationHash> maVarDeclSourceRangeMap;
- std::unordered_map<SourceLocation, SourceRange, SourceLocationHash> maVarUseSourceRangeMap;
-};
-
-StringRef OnceVar::getFilename(SourceLocation loc)
-{
- SourceLocation spellingLocation = compiler.getSourceManager().getSpellingLoc(loc);
- StringRef name { compiler.getSourceManager().getFilename(spellingLocation) };
- return name;
-}
-
-bool OnceVar::VisitDeclRefExpr( const DeclRefExpr* declRefExpr )
-{
- if (ignoreLocation(declRefExpr)) {
- return true;
- }
- const Decl* decl = declRefExpr->getDecl();
- if (!isa<VarDecl>(decl) || isa<ParmVarDecl>(decl)) {
- return true;
- }
- const VarDecl * varDecl = dyn_cast<VarDecl>(decl)->getCanonicalDecl();
- // ignore stuff in header files (which should really not be there, but anyhow)
- if (!compiler.getSourceManager().isInMainFile(varDecl->getLocation())) {
- return true;
- }
- if (!varDecl->hasInit()) {
- return true;
- }
- if (const StringLiteral* stringLit = dyn_cast<StringLiteral>(varDecl->getInit())) {
- // ignore long literals, helps to make the code more legible
- if (stringLit->getLength() > 40) {
- return true;
- }
- // ok
- } else {
- const CXXConstructExpr* constructExpr = dyn_cast<CXXConstructExpr>(varDecl->getInit());
- if (!constructExpr || constructExpr->getNumArgs() != 1) {
- return true;
- }
- const StringLiteral* stringLit2 = dyn_cast<StringLiteral>(varDecl->getInit());
- if (!stringLit2) {
- return true;
- }
- // ignore long literals, helps to make the code more legible
- if (stringLit2->getLength() > 40) {
- return true;
- }
- }
- SourceLocation loc = varDecl->getLocation();
-
- // ignore cases like:
- // const OUString("xxx") xxx;
- // rtl_something(xxx.pData);
- // and
- // foo(&xxx);
- // where we cannot inline the declaration.
- auto const tc = loplugin::TypeCheck(varDecl->getType());
- if (tc.Class("OUString").Namespace("rtl").GlobalNamespace()
- && (isa<MemberExpr>(parentStmt(declRefExpr))
- || isa<UnaryOperator>(parentStmt(declRefExpr))))
- {
- maVarUsesMap[loc] = 2;
- return true;
- }
-
- if (maVarUsesMap.find(loc) == maVarUsesMap.end()) {
- maVarUsesMap[loc] = 1;
- maVarDeclSourceRangeMap[loc] = varDecl->getSourceRange();
- maVarUseSourceRangeMap[loc] = declRefExpr->getSourceRange();
- } else {
- maVarUsesMap[loc]++;
- }
- return true;
-}
-
-loplugin::Plugin::Registration< OnceVar > X("oncevar");
-
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */