6 callDict
= dict() # callInfo tuple -> callValue
7 definitionToSourceLocationMap
= dict()
8 paramSet
= set() # paraminfo tuple
10 # clang does not always use exactly the same numbers in the type-parameter vars it generates
11 # so I need to substitute them to ensure we can match correctly.
12 normalizeTypeParamsRegex
= re
.compile(r
"type-parameter-\d+-\d+")
13 def normalizeTypeParams( line
):
14 return normalizeTypeParamsRegex
.sub("type-parameter-?-?", line
)
16 # reading as binary (since we known it is pure ascii) is much faster than reading as unicode
17 with io
.open("workdir/loplugin.virtualdead.log", "r", encoding
="ascii", errors
="ignore", buffering
=1024*1024) as txt
:
20 tokens
= line
.strip().split("\t")
21 if tokens
[0] == "virtual:":
22 nameAndParams
= normalizeTypeParams(tokens
[1])
23 sourceLocation
= tokens
[2]
24 returnValue
= tokens
[3]
25 callInfo
= (nameAndParams
, sourceLocation
)
26 if callInfo
not in callDict
:
27 callDict
[callInfo
] = set()
28 callDict
[callInfo
].add(returnValue
)
29 definitionToSourceLocationMap
[nameAndParams
] = sourceLocation
30 elif tokens
[0] == "param:":
31 name
= normalizeTypeParams(tokens
[1])
34 paramSet
.add((name
,bitfield
))
36 print( "unknown line: " + line
)
38 print("problem with line " + line
.strip())
42 for callInfo
, callValues
in iter(callDict
.items()):
43 nameAndParams
= callInfo
[1]
44 if len(callValues
) != 1:
46 callValue
= next(iter(callValues
))
47 if "unknown-stmt" in callValue
:
49 if "unknown2" in callValue
:
51 if "unknown3" in callValue
:
53 if "unknown4" in callValue
:
55 if "pure" in callValue
:
58 if srcloc
.startswith("workdir/"): continue
60 if srcloc
.startswith("Gui/"): continue
61 if srcloc
.startswith("Widgets/"): continue
62 if srcloc
.startswith("Core/"): continue
63 if srcloc
.startswith("/Qt"): continue
64 if srcloc
.startswith("Qt"): continue
65 if srcloc
.startswith("64-"): continue
66 functionSig
= callInfo
[0]
67 tmp1list
.append((srcloc
, functionSig
, callValue
))
69 def merge_bitfield(a
, b
):
70 if len(a
) == 0: return b
72 for i
, c
in enumerate(b
):
73 if c
== "1" or a
[i
] == "1":
80 for paramInfo
in paramSet
:
82 bitfield
= paramInfo
[1]
83 if re
.match( r
"\w+ com::", name
): continue
84 if re
.match( r
"\w+ ooo::vba::", name
): continue
85 if re
.match( r
"\w+ orcus::", name
): continue
86 if re
.match( r
"\w+ std::", name
): continue
87 if name
not in tmp2dict
:
88 tmp2dict
[name
] = bitfield
90 tmp2dict
[name
] = merge_bitfield(tmp2dict
[name
], bitfield
)
91 for name
, bitfield
in iter(tmp2dict
.items()):
92 srcloc
= definitionToSourceLocationMap
[name
]
94 if srcloc
.startswith("Gui/"): continue
95 if srcloc
.startswith("Widgets/"): continue
96 if srcloc
.startswith("Core/"): continue
97 if srcloc
.startswith("/Qt"): continue
98 if srcloc
.startswith("Qt"): continue
99 if srcloc
.startswith("64-"): continue
100 # ignore external stuff
101 if srcloc
.startswith("workdir/"): continue
102 # referenced by generated code in workdir/
103 if srcloc
.startswith("sw/source/writerfilter/ooxml/OOXMLFactory.hxx"): continue
105 tmp2list
.append((srcloc
, name
, bitfield
))
107 # sort results by filename:lineno
108 def natural_sort_key(s
, _nsre
=re
.compile('([0-9]+)')):
109 return [int(text
) if text
.isdigit() else text
.lower()
110 for text
in re
.split(_nsre
, s
)]
111 # sort by both the source-line and the datatype, so the output file ordering is stable
112 # when we have multiple items on the same source line
114 return natural_sort_key(v
[0]) + [v
[1]]
115 tmp1list
.sort(key
=lambda v
: v_sort_key(v
))
116 tmp2list
.sort(key
=lambda v
: v_sort_key(v
))
118 # print out the results
119 with
open("compilerplugins/clang/virtualdead.results", "wt") as f
:
122 f
.write(" " + v
[1] + "\n")
123 f
.write(" " + v
[2] + "\n")
124 with
open("compilerplugins/clang/virtualdead.unusedparams.results", "wt") as f
:
127 f
.write(" " + v
[1] + "\n")
128 f
.write(" " + v
[2] + "\n")