An `elaboration circularity' occurs whenever the elaboration of a set of units enters a deadlocked state, where each unit is waiting for another unit to be elaborated. This situation may be the result of improper use of `with' clauses, elaboration-control pragmas, or invocations in elaboration code.
The following example exhibits an elaboration circularity.
with B; pragma Elaborate (B); package A is end A;package B is procedure Force_Body; end B;with C; package body B is procedure Force_Body is null; Elab : constant Integer := C.Func; end B;package C is function Func return Integer; end C;with A; package body C is function Func return Integer is begin ... end Func; end C;
The binder emits the following diagnostic:
error: Elaboration circularity detected info: info: Reason: info: info: unit "a (spec)" depends on its own elaboration info: info: Circularity: info: info: unit "a (spec)" has with clause and pragma Elaborate for unit "b (spec)" info: unit "b (body)" is in the closure of pragma Elaborate info: unit "b (body)" invokes a construct of unit "c (body)" at elaboration time info: unit "c (body)" has with clause for unit "a (spec)" info: info: Suggestions: info: info: remove pragma Elaborate for unit "b (body)" in unit "a (spec)" info: use the dynamic elaboration model (compiler switch -gnatE)
The diagnostic consist of the following sections:
This section provides a short explanation describing why the set of units could not be ordered.
This section enumerates the units comprising the deadlocked set, along with their interdependencies.
This section enumerates various tactics for eliminating the circularity.