menu_finalize() is one of the more opaque parts of Kconfig, and I need
to make some changes to it to fix an issue related to modules. Add some
comments related to expression rewriting and dependency propagation as a
review aid. They will also help other people trying to understand the
code.

Signed-off-by: Ulf Magnusson <[email protected]>
---
 scripts/kconfig/menu.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 8354dfa..94f192de 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -296,6 +296,11 @@ void menu_finalize(struct menu *parent)
 
        sym = parent->sym;
        if (parent->list) {
+               /*
+                * This menu node has children. We (recursively) process them
+                * and propagate parent dependencies before moving on.
+                */
+
                if (sym && sym_is_choice(sym)) {
                        if (sym->type == S_UNKNOWN) {
                                /* find the first choice value to find out 
choice type */
@@ -319,24 +324,66 @@ void menu_finalize(struct menu *parent)
                else
                        parentdep = parent->dep;
 
+               /* For each child menu node... */
                for (menu = parent->list; menu; menu = menu->next) {
+                       /*
+                        * Propagate parent dependencies to the child menu
+                        * node, also rewriting and simplifying expressions
+                        */
                        basedep = expr_transform(menu->dep);
                        basedep = expr_alloc_and(expr_copy(parentdep), basedep);
                        basedep = expr_eliminate_dups(basedep);
                        menu->dep = basedep;
+
                        if (menu->sym)
+                               /*
+                                * Note: For symbols, all prompts are included
+                                * too in the symbol's own property list
+                                */
                                prop = menu->sym->prop;
                        else
+                               /*
+                                * For non-symbol menu nodes, we just need to
+                                * handle the prompt
+                                */
                                prop = menu->prompt;
+
+                       /* For each property... */
                        for (; prop; prop = prop->next) {
                                if (prop->menu != menu)
+                                       /*
+                                        * Two possibilities:
+                                        *
+                                        * 1. The property lacks dependencies
+                                        *    and so isn't location-specific,
+                                        *    e.g. an 'option'
+                                        *
+                                        * 2. The property belongs to a symbol
+                                        *    defined in multiple locations and
+                                        *    is from some other location. It
+                                        *    will be handled there in that
+                                        *    case.
+                                        *
+                                        * Skip the property.
+                                        */
                                        continue;
+
+                               /*
+                                * Propagate parent dependencies to the
+                                * property's condition, rewriting and
+                                * simplifying expressions at the same time
+                                */
                                dep = expr_transform(prop->visible.expr);
                                dep = expr_alloc_and(expr_copy(basedep), dep);
                                dep = expr_eliminate_dups(dep);
                                if (menu->sym && menu->sym->type != S_TRISTATE)
                                        dep = expr_trans_bool(dep);
                                prop->visible.expr = dep;
+
+                               /*
+                                * Handle selects and implies, which modify the
+                                * dependencies of the selected/implied symbol
+                                */
                                if (prop->type == P_SELECT) {
                                        struct symbol *es = 
prop_get_symbol(prop);
                                        es->rev_dep.expr = 
expr_alloc_or(es->rev_dep.expr,
@@ -348,6 +395,11 @@ void menu_finalize(struct menu *parent)
                                }
                        }
                }
+
+               /*
+                * Recursively process children in the same fashion before
+                * moving on
+                */
                for (menu = parent->list; menu; menu = menu->next)
                        menu_finalize(menu);
        } else if (sym) {
-- 
2.7.4

Reply via email to