def _determine_uses(self, included_files, forward_declarations):
file_uses = dict.fromkeys(included_files, UNUSED)<EOL>decl_uses = dict.fromkeys(forward_declarations, UNUSED)<EOL>symbol_table = self.symbol_table<EOL>for name, node in forward_declarations.items():<EOL><INDENT>try:<EOL><INDENT>symbol_table.lookup_symbol(node.name, node.namespace)<EOL>decl_uses[name] |= USES_REFERENCE<EOL><DEDENT>except symbols.Error:<EOL><INDENT>module = Module(name, None)<EOL>symbol_table.add_symbol(node.name, node.namespace, node,<EOL>module)<EOL><DEDENT><DEDENT>def _do_lookup(name, namespace):<EOL><INDENT>try:<EOL><INDENT>file_use_node = symbol_table.lookup_symbol(name, namespace)<EOL><DEDENT>except symbols.Error:<EOL><INDENT>return<EOL><DEDENT>name = file_use_node[<NUM_LIT:1>].filename<EOL>file_uses[name] = file_uses.get(name, <NUM_LIT:0>) | USES_DECLARATION<EOL><DEDENT>def _add_declaration(name, namespace):<EOL><INDENT>if not name:<EOL><INDENT>return<EOL><DEDENT>names = [n for n in namespace if n is not None]<EOL>if names:<EOL><INDENT>name = '<STR_LIT>'.join(names) + '<STR_LIT>' + name<EOL><DEDENT>if name in decl_uses:<EOL><INDENT>decl_uses[name] |= USES_DECLARATION<EOL><DEDENT><DEDENT>def _add_reference(name, namespace):<EOL><INDENT>try:<EOL><INDENT>file_use_node = symbol_table.lookup_symbol(name, namespace)<EOL><DEDENT>except symbols.Error:<EOL><INDENT>return<EOL><DEDENT>name = file_use_node[<NUM_LIT:1>].filename<EOL>if file_use_node[<NUM_LIT:1>].ast_list is None:<EOL><INDENT>decl_uses[name] |= USES_REFERENCE<EOL><DEDENT>elif name in file_uses:<EOL><INDENT>if isinstance(file_use_node[<NUM_LIT:0>], (ast.Enum, ast.Typedef)):<EOL><INDENT>file_uses[name] |= USES_DECLARATION<EOL><DEDENT>else:<EOL><INDENT>file_uses[name] |= USES_REFERENCE<EOL><DEDENT><DEDENT><DEDENT>def _add_use(node, namespace, name='<STR_LIT>'):<EOL><INDENT>if isinstance(node, basestring):<EOL><INDENT>name = node<EOL><DEDENT>elif isinstance(node, list):<EOL><INDENT>name = '<STR_LIT>'.join([n.name for n in name])<EOL><DEDENT>if name:<EOL><INDENT>_do_lookup(name, namespace)<EOL>return<EOL><DEDENT>obj = getattr(node, '<STR_LIT>', None)<EOL>if obj:<EOL><INDENT>_do_lookup(obj, namespace)<EOL><DEDENT>obj = getattr(node, '<STR_LIT:type>', None)<EOL>if obj and isinstance(obj.name, basestring):<EOL><INDENT>_do_lookup(obj.name, namespace)<EOL><DEDENT>if not isinstance(node, basestring):<EOL><INDENT>return<EOL><DEDENT><DEDENT>def _add_variable(node, namespace, reference=False):<EOL><INDENT>obj = node.type if isinstance(<EOL>node, ast.VariableDeclaration) else node<EOL>if obj.reference or obj.pointer or reference:<EOL><INDENT>_add_reference(obj.name, namespace)<EOL><DEDENT>else:<EOL><INDENT>_add_use(obj.name, namespace)<EOL>_add_use(node, namespace)<EOL><DEDENT>_add_template_use(obj.name,<EOL>obj.templated_types,<EOL>namespace,<EOL>reference)<EOL><DEDENT>def _process_function(function, namespace):<EOL><INDENT>reference = function.body is None<EOL>if function.return_type:<EOL><INDENT>return_type = function.return_type<EOL>_add_variable(return_type, namespace, reference)<EOL><DEDENT>for s in function.specializations:<EOL><INDENT>_add_variable(s, namespace, not function.body)<EOL><DEDENT>templated_types = function.templated_types or ()<EOL>for p in function.parameters:<EOL><INDENT>node = p.type<EOL>if node.name not in templated_types:<EOL><INDENT>if function.body and p.name:<EOL><INDENT>_add_use(node.name, namespace)<EOL><DEDENT>elif (<EOL>p.default and<EOL>p.default[<NUM_LIT:0>].name != '<STR_LIT:0>' and<EOL>p.default[<NUM_LIT:0>].name != '<STR_LIT>' and<EOL>p.default[<NUM_LIT:0>].name != '<STR_LIT>'<EOL>):<EOL><INDENT>_add_use(node.name, namespace)<EOL><DEDENT>elif node.reference or node.pointer or reference:<EOL><INDENT>_add_reference(node.name, namespace)<EOL><DEDENT>else:<EOL><INDENT>_add_use(node.name, namespace)<EOL><DEDENT>_add_template_use(node.name,<EOL>node.templated_types,<EOL>namespace,<EOL>reference)<EOL><DEDENT><DEDENT><DEDENT>def _process_function_body(function, namespace):<EOL><INDENT>previous = None<EOL>save = namespace[:]<EOL>for t in function.body:<EOL><INDENT>if t.token_type == tokenize.NAME:<EOL><INDENT>previous = t<EOL>if not keywords.is_keyword(t.name):<EOL><INDENT>_add_use(t.name, namespace)<EOL><DEDENT><DEDENT>elif t.name == '<STR_LIT>' and previous is not None:<EOL><INDENT>namespace.append(previous.name)<EOL><DEDENT>elif t.name in ('<STR_LIT::>', '<STR_LIT:;>'):<EOL><INDENT>namespace = save[:]<EOL><DEDENT><DEDENT><DEDENT>def _add_template_use(name, types, namespace, reference=False):<EOL><INDENT>for cls in types or ():<EOL><INDENT>if cls.pointer or cls.reference or reference:<EOL><INDENT>_add_reference(cls.name, namespace)<EOL><DEDENT>elif name.endswith('<STR_LIT>'):<EOL><INDENT>_add_reference(cls.name, namespace)<EOL><DEDENT>elif name.startswith('<STR_LIT>') and name.endswith('<STR_LIT>'):<EOL><INDENT>_add_reference(cls.name, namespace)<EOL><DEDENT>else:<EOL><INDENT>_add_use(cls.name, namespace)<EOL><DEDENT>_add_template_use(cls.name, cls.templated_types,<EOL>namespace, reference)<EOL><DEDENT><DEDENT>def _process_types(nodes, namespace):<EOL><INDENT>for node in nodes:<EOL><INDENT>if isinstance(node, ast.Type):<EOL><INDENT>_add_variable(node, namespace)<EOL><DEDENT><DEDENT><DEDENT>ast_seq = [self.ast_list]<EOL>namespace_stack = []<EOL>while ast_seq:<EOL><INDENT>for node in ast_seq.pop():<EOL><INDENT>if isinstance(node, ast.VariableDeclaration):<EOL><INDENT>namespace = namespace_stack + node.namespace<EOL>_add_variable(node, namespace)<EOL><DEDENT>elif isinstance(node, ast.Function):<EOL><INDENT>namespace = namespace_stack + node.namespace<EOL>_process_function(node, namespace)<EOL>if node.body:<EOL><INDENT>_process_function_body(node, namespace)<EOL><DEDENT><DEDENT>elif isinstance(node, ast.Typedef):<EOL><INDENT>namespace = namespace_stack + node.namespace<EOL>_process_types(node.alias, namespace)<EOL><DEDENT>elif isinstance(node, ast.Friend):<EOL><INDENT>expr = node.expr<EOL>namespace = namespace_stack + node.namespace<EOL>if isinstance(expr, ast.Type):<EOL><INDENT>_add_reference(expr.name, namespace)<EOL><DEDENT>elif isinstance(expr, ast.Function):<EOL><INDENT>_process_function(expr, namespace)<EOL><DEDENT><DEDENT>elif isinstance(node, ast.Union) and node.body is not None:<EOL><INDENT>ast_seq.append(node.body)<EOL><DEDENT>elif isinstance(node, ast.Class) and node.body is not None:<EOL><INDENT>_add_declaration(node.name, node.namespace)<EOL>namespace = namespace_stack + node.namespace<EOL>_add_template_use('<STR_LIT>', node.bases, namespace)<EOL>ast_seq.append(node.body)<EOL><DEDENT>elif isinstance(node, ast.Using):<EOL><INDENT>if node.names[<NUM_LIT:0>].name == '<STR_LIT>':<EOL><INDENT>namespace_stack.append(node.names[<NUM_LIT:1>].name)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return file_uses, decl_uses<EOL>
Set up the use type of each symbol.