Skip to content

Commit

Permalink
Merge branch 'topic/resolve_overloaded_actual' into 'master'
Browse files Browse the repository at this point in the history
Fix resolution of generic subprogram actuals.

Closes #1161

See merge request eng/libadalang/libadalang!1482
  • Loading branch information
Roldak committed Dec 4, 2023
2 parents 4f66758 + c053022 commit 9068990
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 2 deletions.
25 changes: 23 additions & 2 deletions ada/ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -12422,6 +12422,26 @@ class FormalSubpDecl(ClassicSubpDecl):
), default_val=LogicTrue())
)

@langkit_property(return_type=T.BasicDecl.entity, memoized=True)
def resolve_actual_name(name=T.Expr.entity):
"""
Given the name used in the instantiation for this formal subp decl,
resolve it at the instantiation site to the corresponding declaration.
This property basically replaces ``AdaNode.resolve_generic_actual`` but
is more precise because we have access to the formal spec, which means
we can disambiguate between overloaded actuals.
Note that we cannot simply call ``referenced_decl`` here as this would
cause name resolution recursions which we want to avoid at all cost.
"""
return origin.bind(name.node, name.cast(AttributeRef).then(
lambda attr: attr.attribute_subprogram,
default_val=name.cast(Name).all_env_elements.find(
lambda el: el.cast(BasicDecl)._.subp_decl_match_signature(
Entity
)
)
)).cast(BasicDecl)

@langkit_property(return_type=T.BasicDecl.entity)
def corresponding_actual_impl(rb=T.EnvRebindings):
"""
Expand All @@ -12443,8 +12463,9 @@ def corresponding_actual_impl(rb=T.EnvRebindings):
from_rebound=False
)
)
).actual_for_formal(Entity.defining_name.node)
._.resolve_generic_actual.cast(BasicDecl).then(
).actual_for_formal(Entity.defining_name.node).then(
lambda name: Entity.resolve_actual_name(name)
).then(
lambda actual: actual.corresponding_actual
)._or(Entity),

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
procedure Test is
generic
with procedure Foo (X : Integer);
procedure Gen;

procedure Gen is
begin
Foo (42);
end Gen;

-- Define three potential candidates for the actual in the instantiation
-- below.
procedure Bar (X : Boolean) is null;
procedure Bar (X : Integer) is null;
procedure Bar (X : Float) is null;

procedure My_Gen is new Gen (Foo => Bar);
--% gen = node.p_designated_generic_decl.p_body_part()
--% gen.find(lal.CallExpr).f_name.p_referenced_decl()
begin
null;
end Test;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Working on node <GenericSubpInstantiation ["My_Gen"] test.adb:17:4-17:45>
=========================================================================

Set 'gen' to 'node.p_designated_generic_decl.p_body_part()'
Result: <| SubpBody ["Gen"] test.adb:6:4-9:12 [test.adb:17:4] |>

Eval 'gen.find(lal.CallExpr).f_name.p_referenced_decl()'
Result: <NullSubpDecl ["Bar"] test.adb:14:4-14:40>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
driver: inline-playground
input_sources: [test.adb]

0 comments on commit 9068990

Please sign in to comment.