diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2018-05-16 09:28:54 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2018-05-19 21:32:11 +0200 |
commit | 6ac83797e033dd0b799455d552c61abd202160b4 (patch) | |
tree | 4cb546067ea3d3c8f389c018b054418f5949da2c /compilerplugins | |
parent | 2c244e6f533067d6c3affbd83759c71bc910ae99 (diff) |
improve unusedfields loplugin to find constructor-only fields
ie. fields that are only touched in the constructor
Change-Id: Ia714cbfed9710e47e69ca9f0eb0eac4f7e8b8a86
Reviewed-on: https://gerrit.libreoffice.org/54412
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/unusedfields.cxx | 5 | ||||
-rwxr-xr-x | compilerplugins/clang/unusedfields.py | 47 |
2 files changed, 50 insertions, 2 deletions
diff --git a/compilerplugins/clang/unusedfields.cxx b/compilerplugins/clang/unusedfields.cxx index 4095b23324c0..159d8544b635 100644 --- a/compilerplugins/clang/unusedfields.cxx +++ b/compilerplugins/clang/unusedfields.cxx @@ -67,6 +67,7 @@ bool operator < (const MyFieldInfo &lhs, const MyFieldInfo &rhs) // try to limit the voluminous output a little static std::set<MyFieldInfo> touchedFromInsideSet; static std::set<MyFieldInfo> touchedFromOutsideSet; +static std::set<MyFieldInfo> touchedFromOutsideConstructorSet; static std::set<MyFieldInfo> readFromSet; static std::set<MyFieldInfo> writeToSet; static std::set<MyFieldInfo> definitionSet; @@ -186,6 +187,8 @@ void UnusedFields::run() output += "inside:\t" + s.parentClass + "\t" + s.fieldName + "\n"; for (const MyFieldInfo & s : touchedFromOutsideSet) output += "outside:\t" + s.parentClass + "\t" + s.fieldName + "\n"; + for (const MyFieldInfo & s : touchedFromOutsideConstructorSet) + output += "outside-constructor:\t" + s.parentClass + "\t" + s.fieldName + "\n"; for (const MyFieldInfo & s : readFromSet) output += "read:\t" + s.parentClass + "\t" + s.fieldName + "\n"; for (const MyFieldInfo & s : writeToSet) @@ -989,6 +992,8 @@ void UnusedFields::checkTouchedFromOutside(const FieldDecl* fieldDecl, const Exp } else { if (memberExprParentFunction->getParent() == fieldDecl->getParent()) { touchedFromInsideSet.insert(fieldInfo); + if (!constructorDecl) + touchedFromOutsideConstructorSet.insert(fieldInfo); } else { touchedFromOutsideSet.insert(fieldInfo); } diff --git a/compilerplugins/clang/unusedfields.py b/compilerplugins/clang/unusedfields.py index 1178d0da0b80..072284576a6a 100755 --- a/compilerplugins/clang/unusedfields.py +++ b/compilerplugins/clang/unusedfields.py @@ -9,10 +9,11 @@ protectedAndPublicDefinitionSet = set() # set of tuple(type, name) definitionToSourceLocationMap = dict() definitionToTypeMap = dict() touchedFromInsideSet = set() +touchedFromOutsideSet = set() +touchedFromOutsideConstructorSet = set() readFromSet = set() writeToSet = set() sourceLocationSet = set() -touchedFromOutsideSet = set() # 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. @@ -48,6 +49,8 @@ with io.open("workdir/loplugin.unusedfields.log", "rb", buffering=1024*1024) as touchedFromInsideSet.add(parseFieldInfo(tokens)) elif tokens[0] == "outside:": touchedFromOutsideSet.add(parseFieldInfo(tokens)) + elif tokens[0] == "outside-constructor:": + touchedFromOutsideConstructorSet.add(parseFieldInfo(tokens)) elif tokens[0] == "read:": readFromSet.add(parseFieldInfo(tokens)) elif tokens[0] == "write:": @@ -67,7 +70,7 @@ for k, definitions in sourceLocationToDefinitionMap.iteritems(): for d in definitions: definitionSet.remove(d) -# Calculate untouched or untouched-except-for-in-constructor +# Calculate untouched untouchedSet = set() untouchedSetD = set() for d in definitionSet: @@ -103,6 +106,41 @@ for d in definitionSet: untouchedSet.add((d[0] + " " + d[1] + " " + fieldType, srcLoc)) untouchedSetD.add(d) +# Calculate only-touched-in-constructor set +onlyUsedInConstructorSet = set() +for d in definitionSet: + if d in touchedFromOutsideSet or d in touchedFromOutsideConstructorSet: + continue + srcLoc = definitionToSourceLocationMap[d]; + # this is all representations of on-disk data structures + if (srcLoc.startswith("sc/source/filter/inc/scflt.hxx") + or srcLoc.startswith("sw/source/filter/ww8/") + or srcLoc.startswith("vcl/source/filter/sgvmain.hxx") + or srcLoc.startswith("vcl/source/filter/sgfbram.hxx") + or srcLoc.startswith("vcl/inc/unx/XIM.h") + or srcLoc.startswith("vcl/inc/unx/gtk/gloactiongroup.h") + or srcLoc.startswith("include/svl/svdde.hxx") + or srcLoc.startswith("lotuswordpro/source/filter/lwpsdwdrawheader.hxx") + or srcLoc.startswith("hwpfilter/") + or srcLoc.startswith("embeddedobj/source/inc/") + or srcLoc.startswith("svtools/source/dialogs/insdlg.cxx") + or srcLoc.startswith("bridges/")): + continue + fieldType = definitionToTypeMap[d] + if "std::unique_ptr" in fieldType: + continue + if "std::shared_ptr" in fieldType: + continue + if "Reference<" in fieldType: + continue + if "VclPtr<" in fieldType: + continue + if "osl::Mutex" in fieldType: + continue + if "::sfx2::sidebar::ControllerItem" in fieldType: + continue + onlyUsedInConstructorSet.add((d[0] + " " + d[1] + " " + fieldType, srcLoc)) + writeonlySet = set() for d in definitionSet: parentClazz = d[0]; @@ -196,6 +234,7 @@ tmp1list = sorted(untouchedSet, key=lambda v: natural_sort_key(v[1])) tmp2list = sorted(writeonlySet, key=lambda v: natural_sort_key(v[1])) tmp3list = sorted(canBePrivateSet, key=lambda v: natural_sort_key(v[1])) tmp4list = sorted(readonlySet, key=lambda v: natural_sort_key(v[1])) +tmp5list = sorted(onlyUsedInConstructorSet, key=lambda v: natural_sort_key(v[1])) # print out the results with open("compilerplugins/clang/unusedfields.untouched.results", "wt") as f: @@ -215,5 +254,9 @@ with open("compilerplugins/clang/unusedfields.readonly.results", "wt") as f: for t in tmp4list: f.write( t[1] + "\n" ) f.write( " " + t[0] + "\n" ) +with open("compilerplugins/clang/unusedfields.only-used-in-constructor.results", "wt") as f: + for t in tmp5list: + f.write( t[1] + "\n" ) + f.write( " " + t[0] + "\n" ) |