diff options
-rw-r--r-- | compilerplugins/clang/unusedenumvalues.cxx | 135 | ||||
-rwxr-xr-x | compilerplugins/clang/unusedenumvalues.py | 110 |
2 files changed, 0 insertions, 245 deletions
diff --git a/compilerplugins/clang/unusedenumvalues.cxx b/compilerplugins/clang/unusedenumvalues.cxx deleted file mode 100644 index bfde9608cce2..000000000000 --- a/compilerplugins/clang/unusedenumvalues.cxx +++ /dev/null @@ -1,135 +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 <cassert> -#include <string> -#include <iostream> -#include <fstream> -#include <set> -#include "plugin.hxx" -#include "compat.hxx" - -/** -Looks for enums with unused constants. - -Be warned that it produces around 5G of log file. - -The process goes something like this: - $ make check - $ make FORCE_COMPILE_ALL=1 COMPILER_PLUGIN_TOOL='unusedenumconstants' check - $ ./compilerplugins/clang/unusedenumconstants.py - -Note that the actual process may involve a fair amount of undoing, hand editing, and general messing around -to get it to work :-) - -TODO ignore constants when we are only testing for them, not actually storing them somewhere - -*/ - -namespace { - -struct MyEnumValueInfo -{ - std::string parentClass; - std::string constantName; - std::string sourceLocation; -}; -bool operator < (const MyEnumValueInfo &lhs, const MyEnumValueInfo &rhs) -{ - return std::tie(lhs.parentClass, lhs.constantName) - < std::tie(rhs.parentClass, rhs.constantName); -} - - -// try to limit the voluminous output a little -static std::set<MyEnumValueInfo> touchedSet; -static std::set<MyEnumValueInfo> definitionSet; - - -class UnusedEnumValues: - public RecursiveASTVisitor<UnusedEnumValues>, public loplugin::Plugin -{ -public: - explicit UnusedEnumValues(InstantiationData const & data): Plugin(data) {} - - virtual void run() override - { - TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); - - // dump all our output in one write call - this is to try and limit IO "crosstalk" between multiple processes - // writing to the same logfile - std::string output; - for (const MyEnumValueInfo & s : touchedSet) - output += "touch:\t" + s.parentClass + "\t" + s.constantName + "\n"; - for (const MyEnumValueInfo & s : definitionSet) - { - output += "definition:\t" + s.parentClass + "\t" + s.constantName + "\t" + s.sourceLocation + "\n"; - } - ofstream myfile; - myfile.open( SRCDIR "/loplugin.unusedenumvalues.log", ios::app | ios::out); - myfile << output; - myfile.close(); - } - - bool shouldVisitTemplateInstantiations () const { return true; } - bool shouldVisitImplicitCode() const { return true; } - - bool VisitEnumDecl( const EnumDecl* ); - bool VisitDeclRefExpr( const DeclRefExpr* ); -private: - MyEnumValueInfo niceName(const EnumConstantDecl*); -}; - -MyEnumValueInfo UnusedEnumValues::niceName(const EnumConstantDecl* enumDecl) -{ - MyEnumValueInfo aInfo; - const EnumType* enumType = dyn_cast<EnumType>(enumDecl->getType()); - if (enumType && enumType->getDecl()) - { - aInfo.parentClass = enumType->getDecl()->getNameAsString(); - } else { - aInfo.parentClass = "unknown"; - } - aInfo.constantName = enumDecl->getNameAsString(); - - SourceLocation expansionLoc = compiler.getSourceManager().getExpansionLoc( enumDecl->getLocation() ); - StringRef name = compiler.getSourceManager().getFilename(expansionLoc); - aInfo.sourceLocation = std::string(name.substr(strlen(SRCDIR)+1)) + ":" + std::to_string(compiler.getSourceManager().getSpellingLineNumber(expansionLoc)); - normalizeDotDotInFilePath(aInfo.sourceLocation); - - return aInfo; -} - -bool UnusedEnumValues::VisitEnumDecl( const EnumDecl* enumDecl ) -{ - enumDecl = enumDecl->getCanonicalDecl(); - - if( ignoreLocation( enumDecl )) - return true; - - for (auto it = enumDecl->enumerator_begin(); it != enumDecl->enumerator_end(); ++it) - definitionSet.insert(niceName(*it)); - return true; -} - -bool UnusedEnumValues::VisitDeclRefExpr( const DeclRefExpr* declRefExpr ) -{ - const Decl* decl = declRefExpr->getDecl(); - if (!isa<EnumConstantDecl>(decl)) { - return true; - } - touchedSet.insert(niceName(dyn_cast<EnumConstantDecl>(decl))); - return true; -} - -loplugin::Plugin::Registration< UnusedEnumValues > X("unusedenumvalues", false); - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/compilerplugins/clang/unusedenumvalues.py b/compilerplugins/clang/unusedenumvalues.py deleted file mode 100755 index 76c9fe619eb3..000000000000 --- a/compilerplugins/clang/unusedenumvalues.py +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/python - -import sys -import re -import io - -definitionSet = set() -definitionToSourceLocationMap = dict() -touchSet = set() -# exclude some stuff, mostly because they are some kind of definition of external file formats -excludedSourceFiles = set([ - "include/svx/msdffdef.hxx", - "sw/source/filter/ww8/fields.hxx", - "sw/source/filter/inc/wwstyles.hxx", - "sw/inc/toxe.hxx", - "sw/inc/poolfmt.hxx", - "sw/inc/hintids.hxx", - "vcl/inc/unx/XIM.h", - ]) -excludedTypes = set([ - "SwVarFormat", "RES_FIELDS", "SwFillOrder", "SwIoDetect", "SwDocumentSettingsPropertyHandles", - "SalGenericDataType", "SwDateSubFormat", "XclFutureRecType", "ds_status", "MediaCommand", - "EmfPlusHatchStyle" - ]) - -# clang does not always use exactly the same numbers in the type-parameter vars it generates -# so I need to substitute them to ensure we can match correctly. -normalizeTypeParamsRegex = re.compile(r"type-parameter-\d+-\d+") -def normalizeTypeParams( line ): - return normalizeTypeParamsRegex.sub("type-parameter-?-?", line) - -# The parsing here is designed to avoid grabbing stuff which is mixed in from gbuild. -# I have not yet found a way of suppressing the gbuild output. -with io.open("loplugin.unusedenumvalues.log", "rb", buffering=1024*1024) as txt: - for line in txt: - tokens = line.strip().split("\t") - if tokens[0] == "definition:": - funcInfo = (normalizeTypeParams(tokens[1]), tokens[2]) - definitionSet.add(funcInfo) - definitionToSourceLocationMap[funcInfo] = tokens[3] - elif tokens[0] == "touch:": - callInfo = (normalizeTypeParams(tokens[1]), tokens[2]) - touchSet.add(callInfo) - -# Invert the definitionToSourceLocationMap -# If we see more than one method at the same sourceLocation, it's being autogenerated as part of a template -# and we should just ignore -sourceLocationToDefinitionMap = {} -for k, v in definitionToSourceLocationMap.iteritems(): - sourceLocationToDefinitionMap[v] = sourceLocationToDefinitionMap.get(v, []) - sourceLocationToDefinitionMap[v].append(k) -for k, definitions in sourceLocationToDefinitionMap.iteritems(): - if len(definitions) > 1: - for d in definitions: - definitionSet.remove(d) - -untouchedSet = set() -for d in definitionSet: - clazz = d[0] + " " + d[1] - if d in touchSet: - continue - srcLoc = definitionToSourceLocationMap[d] - srcLocWithoutLineNo = srcLoc.split(":")[0] - # ignore external source code - if (srcLoc.startswith("external/")): - continue - # ignore build folder - if (srcLoc.startswith("workdir/")): - continue - # ignore our stable/URE/UNO api - if (srcLoc.startswith("include/com/") - or srcLoc.startswith("include/cppu/") - or srcLoc.startswith("include/cppuhelper/") - or srcLoc.startswith("include/osl/") - or srcLoc.startswith("include/rtl/") - or srcLoc.startswith("include/sal/") - or srcLoc.startswith("include/salhelper/") - or srcLoc.startswith("include/systools/") - or srcLoc.startswith("include/typelib/") - or srcLoc.startswith("include/uno/")): - continue - if srcLocWithoutLineNo in excludedSourceFiles or d[0] in excludedTypes: - continue - # structure definitions - if srcLoc.startswith("lotuswordpro/"): - continue - - # used in templates to find the last member of an enum - if d[1] == "LAST" or d[1].endswith("_END"): - continue - # used to aid in alignment of enum values - if d[1].endswith("FORCE_EQUAL_SIZE"): - continue - - untouchedSet.add((clazz, srcLoc)) - -# sort the results using a "natural order" so sequences like [item1,item2,item10] sort nicely -def natural_sort_key(s, _nsre=re.compile('([0-9]+)')): - return [int(text) if text.isdigit() else text.lower() - for text in re.split(_nsre, s)] - -# sort results by name and line number -tmp1list = sorted(untouchedSet, key=lambda v: natural_sort_key(v[1])) - -# print out the results -with open("loplugin.unusedenumvalues.report-untouched", "wt") as f: - for t in tmp1list: - f.write( t[1] + "\n" ) - f.write( " " + t[0] + "\n" ) - |