From 19a93e75b0de64451f27249be510a8d2c1233a01 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Mon, 20 Jun 2022 14:51:10 +0200 Subject: [PATCH 1/5] Fix false positive for unused include --- cpp/find_warnings.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cpp/find_warnings.py b/cpp/find_warnings.py index 35e05b9..a93dd29 100644 --- a/cpp/find_warnings.py +++ b/cpp/find_warnings.py @@ -409,6 +409,8 @@ def _process_types(nodes, namespace): for node in nodes: if isinstance(node, ast.Type): _add_variable(node, namespace) + elif isinstance(node, ast.Struct): + return node.body # Iterate through the source AST/tokens, marking each symbols use. ast_seq = [self.ast_list] @@ -425,7 +427,9 @@ def _process_types(nodes, namespace): _process_function_body(node, namespace) elif isinstance(node, ast.Typedef): namespace = namespace_stack + node.namespace - _process_types(node.alias, namespace) + b = _process_types(node.alias, namespace) + if b is not None: + ast_seq.append(b) elif isinstance(node, ast.Friend): expr = node.expr namespace = namespace_stack + node.namespace From f37791eab74af66625cc6c862095db2eb7b9dfa1 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Thu, 7 Jul 2022 11:30:58 +0200 Subject: [PATCH 2/5] use array dimensions --- cpp/ast.py | 18 +++++++++++++----- cpp/find_warnings.py | 2 ++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/cpp/ast.py b/cpp/ast.py index 1fbdc30..6a4f361 100644 --- a/cpp/ast.py +++ b/cpp/ast.py @@ -372,7 +372,7 @@ def __str__(self): suffix += '&' if self.pointer: suffix += '*' - if self.array: + if self.array is not None: suffix += '[]' return self._type_string_helper(suffix) @@ -416,7 +416,7 @@ def to_type(self, tokens): """ result = [] name_tokens = [] - reference = pointer = array = False + reference = pointer = False inside_array = False empty_array = True templated_tokens = [] @@ -438,7 +438,7 @@ def add_type(): templated_types = self.to_type(templated_tokens) result.append(Type(name_tokens[0].start, name_tokens[-1].end, name, templated_types, modifiers, - reference, pointer, array)) + reference, pointer, None)) del name_tokens[:] del templated_tokens[:] @@ -560,7 +560,7 @@ def add_parameter(): if type_name: parameter_type = Type(first_token.start, first_token.end, type_name, templated_types, modifiers, - reference, pointer, False) + reference, pointer, None) p = Parameter(first_token.start, end, name, parameter_type, default) result.append(p) @@ -616,7 +616,10 @@ def create_return_type(self, return_type_seq): names = [n.name for n in other_tokens] reference = '&' in names pointer = '*' in names - array = '[' in names + if '[' in names: + array = True + else: + array = None return Type(start, end, name, templated_types, modifiers, reference, pointer, array) @@ -687,6 +690,11 @@ def _create_variable(self, pos_token, name, type_name, type_modifiers, reference = '&' in ref_pointer_name_seq pointer = '*' in ref_pointer_name_seq array = '[' in ref_pointer_name_seq + if '[' in ref_pointer_name_seq: + array = ref_pointer_name_seq[ref_pointer_name_seq.index('[')+1] + else: + array = None + var_type = Type(pos_token.start, pos_token.end, type_name, templated_types, type_modifiers, reference, pointer, array) diff --git a/cpp/find_warnings.py b/cpp/find_warnings.py index a93dd29..a9e4329 100644 --- a/cpp/find_warnings.py +++ b/cpp/find_warnings.py @@ -328,6 +328,8 @@ def _add_variable(node, namespace, reference=False): # variable value. _add_use(obj.name, namespace) _add_use(node, namespace) + if isinstance(obj.array, str): + _add_use(obj.array, namespace) # This needs to recurse when the node is a templated type. _add_template_use(obj.name, obj.templated_types, From b9b09cd8cfc87912d32c3ed40bc7ff31ffe7785d Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Thu, 7 Jul 2022 11:43:31 +0200 Subject: [PATCH 3/5] use type in function arguments --- cpp/find_warnings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/find_warnings.py b/cpp/find_warnings.py index a9e4329..b0feac8 100644 --- a/cpp/find_warnings.py +++ b/cpp/find_warnings.py @@ -364,7 +364,7 @@ def _process_function(function, namespace): p.default[0].name != 'nullptr' ): _add_use(node.name, namespace) - elif node.reference or node.pointer or reference: + elif node.reference: _add_reference(node.name, namespace) else: _add_use(node.name, namespace) From 815d29b2c2a3f29987072c37f43cdaae0a889144 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Tue, 26 Jul 2022 13:50:09 +0200 Subject: [PATCH 4/5] Allows the use of macros in struct fields --- cpp/ast.py | 1 + cpp/find_warnings.py | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/cpp/ast.py b/cpp/ast.py index 6a4f361..88b0fe1 100644 --- a/cpp/ast.py +++ b/cpp/ast.py @@ -56,6 +56,7 @@ FUNCTION_ATTRIBUTE = 0x20 FUNCTION_UNKNOWN_ANNOTATION = 0x40 FUNCTION_THROW = 0x80 +FUNCTION_INSIDE_STRUCT_MACRO = 0x100 class ParseError(Exception): diff --git a/cpp/find_warnings.py b/cpp/find_warnings.py index b0feac8..d17e8d2 100644 --- a/cpp/find_warnings.py +++ b/cpp/find_warnings.py @@ -337,6 +337,9 @@ def _add_variable(node, namespace, reference=False): reference) def _process_function(function, namespace): + if function.modifiers & ast.FUNCTION_INSIDE_STRUCT_MACRO: + _add_use(function.name, namespace) + return reference = function.body is None if function.return_type: return_type = function.return_type @@ -431,6 +434,9 @@ def _process_types(nodes, namespace): namespace = namespace_stack + node.namespace b = _process_types(node.alias, namespace) if b is not None: + for e in b: + if isinstance(e, ast.Function): + e.modifiers |= ast.FUNCTION_INSIDE_STRUCT_MACRO ast_seq.append(b) elif isinstance(node, ast.Friend): expr = node.expr From b3f97df3a78453abf54eae7ade3c3d8bfd2fc709 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Tue, 26 Jul 2022 15:47:23 +0200 Subject: [PATCH 5/5] use enum values --- cpp/ast.py | 10 +++++++++- cpp/find_warnings.py | 7 ++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/cpp/ast.py b/cpp/ast.py index 88b0fe1..3243143 100644 --- a/cpp/ast.py +++ b/cpp/ast.py @@ -231,7 +231,15 @@ class Enum(_GenericDeclaration): def __init__(self, start, end, name, fields, namespace): _GenericDeclaration.__init__(self, start, end, name, namespace) - self.fields = fields + field = True + self.fields = [] + for f in fields: + if f.name == ",": + field = True + elif field and f.name[0] != '#': + self.fields.append(VariableDeclaration(f.start, f.end, f.name, name, None, namespace)) + field = False + # else = 1 : skip def is_definition(self): return True diff --git a/cpp/find_warnings.py b/cpp/find_warnings.py index d17e8d2..4bf2ef3 100644 --- a/cpp/find_warnings.py +++ b/cpp/find_warnings.py @@ -70,7 +70,12 @@ def __init__(self, filename, ast_list): def _get_exported_symbols(self): if not self.ast_list: return {} - return dict([(n.name, n) for n in self.ast_list if n.is_exportable()]) + r = dict([(n.name, n) for n in self.ast_list if n.is_exportable()]) + for n in self.ast_list: + if isinstance(n, ast.Enum): + for f in n.fields: + r[f.name] = f + return r def is_header_file(filename):