History

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.

Ulf Magnusson committed 9 years ago

Commit fa8ceda1 parent 9a826841 file · +52 −0Browse files

Showing the changes to scripts (1 of 1 file). Show all

Unified · Split

scripts/kconfig/menu.c+52−0
@@ -306,6 +306,11 @@ void menu_finalize(struct menu *parent) · 305 unmodified lines
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) · 17 unmodified lines
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) · 5 unmodified lines
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) {