Skip to content

Commit

Permalink
#2422 add Fortran backend support for the new symbol
Browse files Browse the repository at this point in the history
  • Loading branch information
arporter committed Dec 11, 2023
1 parent 5b5d422 commit f944a70
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 18 deletions.
29 changes: 21 additions & 8 deletions src/psyclone/psyir/backend/fortran.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@
Operation, Range, Routine, Schedule, UnaryOperation)
from psyclone.psyir.symbols import (
ArgumentInterface, ArrayType, ContainerSymbol, DataSymbol, DataTypeSymbol,
DeferredType, RoutineSymbol, ScalarType, Symbol, IntrinsicSymbol,
SymbolTable, UnknownFortranType, UnknownType, UnresolvedInterface,
StructureType)
DeferredType, GenericInterfaceSymbol, IntrinsicSymbol, RoutineSymbol,
ScalarType, StructureType, Symbol, SymbolTable, UnknownFortranType,
UnknownType, UnresolvedInterface)


# Mapping from PSyIR types to Fortran data types. Simply reverse the
Expand Down Expand Up @@ -528,15 +528,25 @@ def gen_vardecl(self, symbol, include_visibility=False):
f" from a Fortran USE statement and should be "
f"generated by 'gen_use' instead of "
f"'gen_vardecl'.")
if isinstance(symbol, RoutineSymbol) and not \
isinstance(symbol.datatype, UnknownFortranType):
if (isinstance(symbol, RoutineSymbol) and
not isinstance(symbol, GenericInterfaceSymbol) and
not isinstance(symbol.datatype, UnknownFortranType)):
raise InternalError(f"Symbol '{symbol.name}' is a RoutineSymbol "
f"which is not imported nor an interface "
f"(UnknownFortranType). This is already "
f"implicitly declared by the routine itself "
f"and should not be provided to 'gen_vardecl'."
)

if isinstance(symbol, GenericInterfaceSymbol):
decln = f"{self._nindent}interface {symbol.name}\n"
routines = ", ".join(sym.name for sym in symbol.maps_to)
self._depth += 1
decln += f"{self._nindent}procedure :: {routines}\n"
self._depth -= 1
decln += f"{self._nindent}end interface {symbol.name}\n"
return decln

# Whether we're dealing with an array declaration and, if so, the
# shape of that array.
if isinstance(symbol.datatype, ArrayType):
Expand Down Expand Up @@ -935,10 +945,13 @@ def gen_decls(self, symbol_table, is_module_scope=False):

# 1: Routines (Interfaces)
for sym in all_symbols[:]:
# Interfaces to module procedures are captured by the frontend
# as either GenericInterfaceSymbols or RoutineSymbols of
# UnknownFortranType. These must therefore be declared.
if isinstance(sym, GenericInterfaceSymbol):
declarations += self.gen_vardecl(
sym, include_visibility=is_module_scope)
if isinstance(sym, RoutineSymbol):
# Interfaces to module procedures are captured by the frontend
# as RoutineSymbols of UnknownFortranType. These must therefore
# be declared.
if isinstance(sym.datatype, UnknownType):
declarations += self.gen_vardecl(
sym, include_visibility=is_module_scope)
Expand Down
4 changes: 1 addition & 3 deletions src/psyclone/psyir/frontend/fparser2.py
Original file line number Diff line number Diff line change
Expand Up @@ -2377,15 +2377,13 @@ def _process_interface_block(self, node, symbol_table, visibility_map):
# with that name.)
symbol_table.add(GenericInterfaceSymbol(
name, rsymbols,
interface=UnknownInterface(),
visibility=vis))
else:
# We've not been able to determine the list of
# RoutineSymbols that this interface maps to so we just
# create a RoutineSymbol of UnknownFortranType.
symbol_table.add(RoutineSymbol(
name,
interface=UnknownInterface(),
datatype=UnknownFortranType(str(node).lower()),
visibility=vis))
except KeyError:
Expand All @@ -2398,7 +2396,7 @@ def _process_interface_block(self, node, symbol_table, visibility_map):
symbol_table.new_symbol(
root_name=f"_psyclone_internal_{name}",
symbol_type=RoutineSymbol,
interface=UnknownInterface(),
#interface=UnknownInterface(),
datatype=UnknownFortranType(str(node).lower()),
visibility=vis)

Expand Down
32 changes: 25 additions & 7 deletions src/psyclone/tests/psyir/backend/fortran_gen_decls_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@
from psyclone.psyir.backend.visitor import VisitorError
from psyclone.psyir.nodes import (Literal, Reference, BinaryOperation,
Container, Routine, Return)
from psyclone.psyir.symbols import (Symbol, DataSymbol, DataTypeSymbol,
SymbolTable, ContainerSymbol, ScalarType,
DeferredType, StructureType, RoutineSymbol,
ImportInterface, UnresolvedInterface,
ArgumentInterface, INTEGER_TYPE, REAL_TYPE,
StaticInterface)
from psyclone.psyir.symbols import (
ArgumentInterface, ContainerSymbol, DataSymbol, DataTypeSymbol,
DeferredType, GenericInterfaceSymbol, ImportInterface,
INTEGER_TYPE, REAL_TYPE,
RoutineSymbol, Symbol, SymbolTable, ScalarType, StaticInterface,
StructureType, UnresolvedInterface)


def test_gen_param_decls_dependencies(fortran_writer):
Expand Down Expand Up @@ -283,7 +283,8 @@ def test_gen_decls_static_variables(fortran_writer):


@pytest.mark.parametrize("visibility", ["public", "private"])
def test_visibility_interface(fortran_reader, fortran_writer, visibility):
def test_visibility_abstract_interface(fortran_reader, fortran_writer,
visibility):
'''Test that PSyclone's Fortran backend successfully writes out
public/private clauses and symbols when the symbol's declaration
is hidden in an abstract interface.
Expand Down Expand Up @@ -311,3 +312,20 @@ def test_visibility_interface(fortran_reader, fortran_writer, visibility):
assert "public :: update_interface" not in result
if visibility == "private":
assert "private :: update_interface" in result


def test_procedure_interface(fortran_reader, fortran_writer):
'''Test that the Fortran backend correctly recreates an interface
declaration from a GenericInterfaceSymbol.
'''
symbol_table = SymbolTable()
sub1 = RoutineSymbol("sub1")
symbol_table.add(sub1)
sub2 = RoutineSymbol("sub2")
symbol_table.add(sub2)
isub = GenericInterfaceSymbol("subx", [sub1, sub2])
symbol_table.add(isub)
out = fortran_writer.gen_decls(symbol_table)
assert "interface subx" in out
assert "procedure :: sub1, sub2" in out
assert "end interface subx" in out

0 comments on commit f944a70

Please sign in to comment.