def _check_public_functions(self, primary_header, all_headers):
        """Verify all the public functions are also declared in a header
        file."""
        public_symbols = {}
        declared_only_symbols = {}
        if primary_header:
            for name, symbol in primary_header.public_symbols.items():
                if isinstance(symbol, ast.Function):
                    public_symbols[name] = symbol
            declared_only_symbols = dict.fromkeys(public_symbols, True)

        for node in self.ast_list:
            # Make sure we have a function that should be exported.
            if not isinstance(node, ast.Function):
                continue
            if isinstance(node, ast.Method):
                # Ensure that for Foo::Bar, Foo is *not* a namespace.
                # If Foo is a namespace, we have a function and not a method.
                names = [n.name for n in node.in_class]
                if names != self.symbol_table.get_namespace(names):
                    continue
            if not (node.is_definition() and node.is_exportable()):
                continue

            # This function should be declared in a header file.
            name = node.name
            if name in public_symbols:
                declared_only_symbols[name] = False
            else:
                self._find_public_function_warnings(node,
                                                    name,
                                                    primary_header,
                                                    all_headers)

        for name, declared_only in declared_only_symbols.items():
            if declared_only:
                node = public_symbols[name]
                if node.templated_types is None:
                    msg = "'{}' declared but not defined".format(name)
                    self._add_warning(msg, node, primary_header.filename)
Verify all the public functions are also declared in a header
        file.