-- Shows addresses of local variables in called routines decreasing
-- Scope of pointers can't be larger than scope of accessed item so
--    must define local pointer types, and also convert routines
-- Outputs addresses in hex
with Unchecked_Conversion;
with Text_IO; use Text_IO;
procedure aliasedLocal2 is

    type IntPointer is access all Integer;
    -- all is required when accessing local variables

    type AddressType is mod 2**32;
    package Address_IO is new Text_IO.Modular_IO (Num => AddressType);
    use Address_IO;
    procedure put_line(s: String; a: AddressType) is 
    begin put(s); put(a, width=>1, base=>16); new_line; end put_line;

    procedure foo is
        -- New pointer type required to access local variable
        type IntPointer2 is access all Integer;
        function Convert2 is new Unchecked_Conversion (IntPointer2, AddressType);
        f, g: aliased integer;
    begin
        put_line("f's address: ", convert2(f'access));
        put_line("g's address: ", convert2(g'access));
    end foo; 

    procedure foo2 is
        -- New pointer type required to access local variable
        type IntPointer2 is access all Integer;
        function Convert2 is new Unchecked_Conversion (IntPointer2, AddressType);
        d, e: aliased integer;
    begin
        put_line("d's address: ", convert2(d'access));
        put_line("e's address: ", convert2(e'access));

        foo;
    end foo2; 

    function Convert is new Unchecked_Conversion(IntPointer, AddressType);

    a, b, c: aliased Integer := 99;

begin
    put_line("a's address: ", convert(a'access));
    put_line("b's address: ", convert(b'access));
    put_line("c's address: ", convert(c'access));

    foo2;

end aliasedLocal2;
-- a's address: 16#BF87A9CC#
-- b's address: 16#BF87A9C8#
-- c's address: 16#BF87A9C4#
-- d's address: 16#BF87A984#
-- e's address: 16#BF87A980#
-- f's address: 16#BF87A944#
-- g's address: 16#BF87A940#