diff options
author | Ulf Magnusson <ulfalizer@gmail.com> | 2017-10-05 14:01:14 +0200 |
---|---|---|
committer | Masahiro Yamada <yamada.masahiro@socionext.com> | 2017-12-15 00:21:31 +0100 |
commit | fa8cedaef814ceced8b55e0d2bbd404ccbc2b786 (patch) | |
tree | 9ddbdb601050597defb84ab28dd38a4af1bb0356 /scripts | |
parent | kconfig: Rename menu_check_dep() to rewrite_m() (diff) | |
download | linux-fa8cedaef814ceced8b55e0d2bbd404ccbc2b786.tar.xz linux-fa8cedaef814ceced8b55e0d2bbd404ccbc2b786.zip |
kconfig: Clarify expression rewriting
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 <ulfalizer@gmail.com>
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/kconfig/menu.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 912c77645583..c8cec26c2535 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -306,6 +306,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 */ @@ -329,24 +334,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, @@ -358,6 +405,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) { |