diff --git a/cpp/ast.py b/cpp/ast.py index 1fbdc30..3243143 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): @@ -230,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 @@ -372,7 +381,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 +425,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 +447,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 +569,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 +625,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 +699,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 35e05b9..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): @@ -328,6 +333,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, @@ -335,6 +342,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 @@ -362,7 +372,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) @@ -409,6 +419,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 +437,12 @@ 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: + 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 namespace = namespace_stack + node.namespace