Skip to content

Commit

Permalink
[flang] Fix kind of REAL(complex) to be the same as the argument by d…
Browse files Browse the repository at this point in the history
…efault

Fixes for expression formatting

Original-commit: flang-compiler/f18@13e8909
Reviewed-on: flang-compiler/f18#885
  • Loading branch information
klausler committed Dec 20, 2019
1 parent 8db76ec commit d67fbce
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 38 deletions.
49 changes: 11 additions & 38 deletions flang/lib/evaluate/formatting.cc
Expand Up @@ -162,8 +162,6 @@ enum class Precedence { // in increasing order for sane comparisons
Multiplicative, // *, /
Power, // **, which is right-associative unlike the other dyadic operators
DefinedUnary,
Parenthesize, // (x), (real, imaginary)
Literal,
Top,
};

Expand Down Expand Up @@ -221,16 +219,8 @@ template<typename T> static Precedence ToPrecedence(const Constant<T> &x) {
}
}
}
return Precedence::Literal;
}
template<typename T> constexpr Precedence ToPrecedence(const Parentheses<T> &) {
return Precedence::Parenthesize;
}
template<int KIND>
constexpr Precedence ToPrecedence(const ComplexConstructor<KIND> &) {
return Precedence::Parenthesize;
return Precedence::Top;
}

template<typename T> static Precedence ToPrecedence(const Expr<T> &expr) {
return std::visit([](const auto &x) { return ToPrecedence(x); }, expr.u);
}
Expand Down Expand Up @@ -262,27 +252,13 @@ template<typename A>
constexpr OperatorSpelling SpellOperator(const Negate<A> &) {
return OperatorSpelling{"-", "", ""};
}
template<typename A>
constexpr OperatorSpelling SpellOperator(const Parentheses<A> &) {
return OperatorSpelling{"(", "", ")"};
}
template<int KIND>
static OperatorSpelling SpellOperator(const ComplexComponent<KIND> &x) {
if (x.isImaginaryPart) {
return {"aimag(", "", ")"};
} else if constexpr (KIND == 2) {
return {"real(", "", ",kind=2)"};
} else if constexpr (KIND == 3) {
return {"real(", "", ",kind=3)"};
} else if constexpr (KIND == 4) {
return {"real(", "", ",kind=4)"};
} else if constexpr (KIND == 8) {
return {"real(", "", ",kind=8)"};
} else if constexpr (KIND == 10) {
return {"real(", "", ",kind=10)"};
} else if constexpr (KIND == 16) {
return {"real(", "", ",kind=16)"};
} else {
static_assert(KIND == 2 || KIND == 3 || KIND == 4 || KIND == 8 ||
KIND == 10 || KIND == 16,
"bad KIND");
}
return {x.isImaginaryPart ? "aimag(" : "real(", "", ")"};
}
template<int KIND> constexpr OperatorSpelling SpellOperator(const Not<KIND> &) {
return OperatorSpelling{".NOT.", "", ""};
Expand Down Expand Up @@ -343,25 +319,22 @@ std::ostream &Operation<D, R, O...>::AsFortran(std::ostream &o) const {
o << spelling.prefix;
Precedence thisPrec{ToPrecedence(derived())};
if constexpr (operands == 1) {
if (lhsPrec <= thisPrec) {
if (thisPrec != Precedence::Top && lhsPrec < thisPrec) {
o << '(' << left() << ')';
} else {
o << left();
}
} else {
if (lhsPrec == Precedence::Parenthesize) {
o << left();
} else if (lhsPrec < thisPrec ||
(lhsPrec == Precedence::Power && thisPrec == Precedence::Power)) {
if (thisPrec != Precedence::Top &&
(lhsPrec < thisPrec ||
(lhsPrec == Precedence::Power && thisPrec == Precedence::Power))) {
o << '(' << left() << ')';
} else {
o << left();
}
o << spelling.infix;
Precedence rhsPrec{ToPrecedence(right())};
if (rhsPrec == Precedence::Parenthesize) {
o << right();
} else if (rhsPrec < thisPrec) {
if (thisPrec != Precedence::Top && rhsPrec < thisPrec) {
o << '(' << right() << ')';
} else {
o << right();
Expand Down
1 change: 1 addition & 0 deletions flang/lib/evaluate/intrinsics.cc
Expand Up @@ -600,6 +600,7 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
Rank::scalar},
{"rank", {{"a", AnyData, Rank::anyOrAssumedRank}}, DefaultInt,
Rank::scalar},
{"real", {{"a", SameComplex, Rank::elemental}}, SameReal}, // 16.9.160(4)(ii)
{"real", {{"a", AnyNumeric, Rank::elementalOrBOZ}, DefaultingKIND},
KINDReal},
{"reduce",
Expand Down

0 comments on commit d67fbce

Please sign in to comment.