Skip to content

Commit 80eea3f

Browse files
klauslerjeanPerier
authored andcommitted
[flang] Represent (parentheses around derived types)
The strongly typed expression representation classes supported a representation of parentheses only around intrinsic types with specific kinds. Parentheses around derived type variables must also be preserved so that expressions may be distinguished from variables; this distinction matters for actual arguments & construct associations. Differential Revision: https://reviews.llvm.org/D110355
1 parent 22830e6 commit 80eea3f

File tree

4 files changed

+61
-6
lines changed

4 files changed

+61
-6
lines changed

flang/include/flang/Evaluate/expression.h

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,10 @@ class Operation {
118118
public:
119119
using Derived = DERIVED;
120120
using Result = RESULT;
121-
static_assert(IsSpecificIntrinsicType<Result>);
122121
static constexpr std::size_t operands{sizeof...(OPERANDS)};
122+
// Allow specific intrinsic types and Parentheses<SomeDerived>
123+
static_assert(IsSpecificIntrinsicType<Result> ||
124+
(operands == 1 && std::is_same_v<Result, SomeDerived>));
123125
template <int J> using Operand = std::tuple_element_t<J, OperandTypes>;
124126

125127
// Unary operations wrap a single Expr with a CopyableIndirection.
@@ -174,7 +176,9 @@ class Operation {
174176
}
175177
}
176178

177-
static constexpr std::optional<DynamicType> GetType() {
179+
static constexpr std::conditional_t<Result::category != TypeCategory::Derived,
180+
std::optional<DynamicType>, void>
181+
GetType() {
178182
return Result::GetType();
179183
}
180184
int Rank() const {
@@ -224,6 +228,17 @@ struct Parentheses : public Operation<Parentheses<A>, A, A> {
224228
using Base::Base;
225229
};
226230

231+
template <>
232+
struct Parentheses<SomeDerived>
233+
: public Operation<Parentheses<SomeDerived>, SomeDerived, SomeDerived> {
234+
public:
235+
using Result = SomeDerived;
236+
using Operand = SomeDerived;
237+
using Base = Operation<Parentheses, SomeDerived, SomeDerived>;
238+
using Base::Base;
239+
DynamicType GetType() const;
240+
};
241+
227242
template <typename A> struct Negate : public Operation<Negate<A>, A, A> {
228243
using Result = A;
229244
using Operand = A;
@@ -732,7 +747,7 @@ template <> class Expr<SomeDerived> : public ExpressionBase<SomeDerived> {
732747
using Result = SomeDerived;
733748
EVALUATE_UNION_CLASS_BOILERPLATE(Expr)
734749
std::variant<Constant<Result>, ArrayConstructor<Result>, StructureConstructor,
735-
Designator<Result>, FunctionRef<Result>>
750+
Designator<Result>, FunctionRef<Result>, Parentheses<Result>>
736751
u;
737752
};
738753

flang/lib/Evaluate/expression.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,14 @@ template <typename A> int ExpressionBase<A>::Rank() const {
107107
derived().u);
108108
}
109109

110+
DynamicType Parentheses<SomeDerived>::GetType() const {
111+
return left().GetType().value();
112+
}
113+
110114
template <typename A> LLVM_DUMP_METHOD void ExpressionBase<A>::dump() const {
111115
llvm::errs() << "Ev::Expr is <{" << AsFortran() << "}>\n";
112116
}
117+
113118
// Equality testing
114119

115120
bool ImpliedDoIndex::operator==(const ImpliedDoIndex &that) const {

flang/lib/Evaluate/tools.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@ Expr<SomeType> Parenthesize(Expr<SomeType> &&expr) {
3535
return std::visit(
3636
[&](auto &&x) {
3737
using T = std::decay_t<decltype(x)>;
38-
if constexpr (common::HasMember<T, TypelessExpression> ||
39-
std::is_same_v<T, Expr<SomeDerived>>) {
40-
return expr; // no parentheses around typeless or derived type
38+
if constexpr (common::HasMember<T, TypelessExpression>) {
39+
return expr; // no parentheses around typeless
40+
} else if constexpr (std::is_same_v<T, Expr<SomeDerived>>) {
41+
return AsGenericExpr(Parentheses<SomeDerived>{std::move(x)});
4142
} else {
4243
return std::visit(
4344
[](auto &&y) {

flang/test/Evaluate/expr01.f90

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
! RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
2+
! Ensures that parentheses are preserved with derived types
3+
module m
4+
type :: t
5+
integer :: n
6+
end type
7+
contains
8+
subroutine sub(x)
9+
type(t), intent(in) :: x
10+
end subroutine
11+
function f(m)
12+
type(t), pointer :: f
13+
integer, intent(in) :: m
14+
type(t), save, target :: res
15+
res%n = m
16+
f => res
17+
end function
18+
subroutine test
19+
type(t) :: x
20+
x = t(1)
21+
!CHECK: CALL sub(t(n=1_4))
22+
call sub(t(1))
23+
!CHECK: CALL sub((t(n=1_4)))
24+
call sub((t(1)))
25+
!CHECK: CALL sub(x)
26+
call sub(x)
27+
!CHECK: CALL sub((x))
28+
call sub((x))
29+
!CHECK: CALL sub(f(2_4))
30+
call sub(f(2))
31+
!CHECK: CALL sub((f(2_4)))
32+
call sub((f(2)))
33+
end subroutine
34+
end module

0 commit comments

Comments
 (0)