Skip to content

Commit fa8ceda

Browse files
ulfalizermasahir0y
authored andcommitted
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 <[email protected]> Signed-off-by: Masahiro Yamada <[email protected]>
1 parent 9a82684 commit fa8ceda

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

scripts/kconfig/menu.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,11 @@ void menu_finalize(struct menu *parent)
306306

307307
sym = parent->sym;
308308
if (parent->list) {
309+
/*
310+
* This menu node has children. We (recursively) process them
311+
* and propagate parent dependencies before moving on.
312+
*/
313+
309314
if (sym && sym_is_choice(sym)) {
310315
if (sym->type == S_UNKNOWN) {
311316
/* find the first choice value to find out choice type */
@@ -329,24 +334,66 @@ void menu_finalize(struct menu *parent)
329334
else
330335
parentdep = parent->dep;
331336

337+
/* For each child menu node... */
332338
for (menu = parent->list; menu; menu = menu->next) {
339+
/*
340+
* Propagate parent dependencies to the child menu
341+
* node, also rewriting and simplifying expressions
342+
*/
333343
basedep = expr_transform(menu->dep);
334344
basedep = expr_alloc_and(expr_copy(parentdep), basedep);
335345
basedep = expr_eliminate_dups(basedep);
336346
menu->dep = basedep;
347+
337348
if (menu->sym)
349+
/*
350+
* Note: For symbols, all prompts are included
351+
* too in the symbol's own property list
352+
*/
338353
prop = menu->sym->prop;
339354
else
355+
/*
356+
* For non-symbol menu nodes, we just need to
357+
* handle the prompt
358+
*/
340359
prop = menu->prompt;
360+
361+
/* For each property... */
341362
for (; prop; prop = prop->next) {
342363
if (prop->menu != menu)
364+
/*
365+
* Two possibilities:
366+
*
367+
* 1. The property lacks dependencies
368+
* and so isn't location-specific,
369+
* e.g. an 'option'
370+
*
371+
* 2. The property belongs to a symbol
372+
* defined in multiple locations and
373+
* is from some other location. It
374+
* will be handled there in that
375+
* case.
376+
*
377+
* Skip the property.
378+
*/
343379
continue;
380+
381+
/*
382+
* Propagate parent dependencies to the
383+
* property's condition, rewriting and
384+
* simplifying expressions at the same time
385+
*/
344386
dep = expr_transform(prop->visible.expr);
345387
dep = expr_alloc_and(expr_copy(basedep), dep);
346388
dep = expr_eliminate_dups(dep);
347389
if (menu->sym && menu->sym->type != S_TRISTATE)
348390
dep = expr_trans_bool(dep);
349391
prop->visible.expr = dep;
392+
393+
/*
394+
* Handle selects and implies, which modify the
395+
* dependencies of the selected/implied symbol
396+
*/
350397
if (prop->type == P_SELECT) {
351398
struct symbol *es = prop_get_symbol(prop);
352399
es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr,
@@ -358,6 +405,11 @@ void menu_finalize(struct menu *parent)
358405
}
359406
}
360407
}
408+
409+
/*
410+
* Recursively process children in the same fashion before
411+
* moving on
412+
*/
361413
for (menu = parent->list; menu; menu = menu->next)
362414
menu_finalize(menu);
363415
} else if (sym) {

0 commit comments

Comments
 (0)