diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2017-04-04 16:35:25 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2017-04-05 06:49:56 +0000 |
commit | e3eadc96cc05135880b72c42358eb3fe51ea94c4 (patch) | |
tree | 6478330637b3d6b12882fcb4ca60790b5800a87c /compilerplugins | |
parent | ff339c89b51ed571d55c762e43aa1a6ee9ada1cb (diff) |
teach constantparam plugin to find always on and always off bitmask values
Change-Id: If56a483494bd3d7feb3fa67c01000dddd0d34421
Reviewed-on: https://gerrit.libreoffice.org/36085
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins')
-rwxr-xr-x | compilerplugins/clang/constantparam.py | 67 |
1 files changed, 65 insertions, 2 deletions
diff --git a/compilerplugins/clang/constantparam.py b/compilerplugins/clang/constantparam.py index 2f930187666f..5550c51c34f3 100755 --- a/compilerplugins/clang/constantparam.py +++ b/compilerplugins/clang/constantparam.py @@ -4,7 +4,7 @@ import sys import re import io -callDict = dict() +callDict = dict() # callInfo tuple -> callValue # 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. @@ -38,7 +38,7 @@ for callInfo, callValues in callDict.iteritems(): sourceLoc = callInfo[4] functionSig = callInfo[0] + " " + callInfo[1] - # try and ignore setter methods + # try to ignore setter methods if ("," not in nameAndParams) and (("::set" in nameAndParams) or ("::Set" in nameAndParams)): continue # ignore code that follows a common pattern @@ -67,4 +67,67 @@ with open("loplugin.constantparam.report", "wt") as f: f.write(" " + v[1] + "\n") f.write(" " + v[2] + "\n") +# ------------------------------------------------------------- +# Now a fun set of heuristics to look for methods that +# take bitmask parameters where one or more of the bits in the +# bitmask is always one or always zero +# integer to hext str +def hex(i): + return "0x%x" % i +# I can't use python's ~ operator, because that produces negative numbers +def negate(i): + return (1 << 32) - 1 - i + +tmp2list = list() +for callInfo, callValues in callDict.iteritems(): + nameAndParams = callInfo[1] + if len(callValues) < 2: + continue + # we are only interested in enum parameters + if not "enum" in callInfo[3]: continue + if not "Flag" in callInfo[3] and not "flag" in callInfo[3] and not "Bit" in callInfo[3] and not "State" in callInfo[3]: continue + # try to ignore setter methods + if ("," not in nameAndParams) and (("::set" in nameAndParams) or ("::Set" in nameAndParams)): + continue + + setBits = 0 + clearBits = 0 + continue_flag = False + first = True + for callValue in callValues: + if "unknown" == callValue or not callValue.isdigit(): + continue_flag = True + break + if first: + setBits = int(callValue) + clearBits = negate(int(callValue)) + first = False + else: + setBits = setBits & int(callValue) + clearBits = clearBits & negate(int(callValue)) + + # estimate allBits by using the highest bit we have seen + # TODO dump more precise information about the allBits values of enums + allBits = (1 << setBits.bit_length()) - 1 + clearBits = clearBits & allBits + if continue_flag or (setBits == 0 and clearBits == 0): continue + + sourceLoc = callInfo[4] + functionSig = callInfo[0] + " " + callInfo[1] + + v2 = callInfo[3] + " " + callInfo[2] + if setBits != 0: v2 += " setBits=" + hex(setBits) + if clearBits != 0: v2 += " clearBits=" + hex(clearBits) + tmp2list.append((sourceLoc, functionSig, v2)) + + +# sort results by filename:lineno +tmp2list.sort(key=lambda v: natural_sort_key(v[0])) + +# print out the results +with open("loplugin.constantparam.report-bitmask-params", "wt") as f: + for v in tmp2list: + f.write(v[0] + "\n") + f.write(" " + v[1] + "\n") + f.write(" " + v[2] + "\n") |