forked from OSchip/llvm-project
[flang] Pass tests
Original-commit: flang-compiler/f18@ffb057f262 Reviewed-on: https://github.com/flang-compiler/f18/pull/371 Tree-same-pre-rewrite: false
This commit is contained in:
parent
b35f4a98e2
commit
9e9b9f0776
flang
lib
test
|
@ -30,7 +30,7 @@ Addressable_impl *GetAddressable(Statement *stmt) {
|
||||||
|
|
||||||
static std::string dump(const Expression &e) {
|
static std::string dump(const Expression &e) {
|
||||||
std::stringstream stringStream;
|
std::stringstream stringStream;
|
||||||
stringStream << e.v;
|
stringStream << e;
|
||||||
return stringStream.str();
|
return stringStream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
// Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -133,50 +133,52 @@ std::ostream &ProcedureRef::AsFortran(std::ostream &o) const {
|
||||||
// Operator precedence formatting; insert parentheses around operands
|
// Operator precedence formatting; insert parentheses around operands
|
||||||
// only when necessary.
|
// only when necessary.
|
||||||
|
|
||||||
enum class Precedence {
|
enum class Precedence { // in increasing order of precedence
|
||||||
Primary, // don't parenthesize
|
DefinedBinary,
|
||||||
Constant, // parenthesize if negative integer/real operand
|
NOT, // which binds *less* tightly in Fortran than logicals & relations
|
||||||
Parenthesize, // (x), (real, imaginary)
|
|
||||||
DefinedUnary,
|
|
||||||
Negate,
|
|
||||||
Power, // ** which is right-associative
|
|
||||||
Multiplicative, // *, /
|
|
||||||
Additive, // +, -, //
|
|
||||||
Relational,
|
|
||||||
Logical, // .OR., .AND., .EQV., .NEQV.
|
Logical, // .OR., .AND., .EQV., .NEQV.
|
||||||
NOT, // yes, this binds less tightly in Fortran than .OR./.AND./&c. do
|
Relational,
|
||||||
DefinedBinary
|
Additive, // +, -, //
|
||||||
|
Multiplicative, // *, /
|
||||||
|
Power, // **, which is right-associative unlike the other dyadic operators
|
||||||
|
Negate,
|
||||||
|
DefinedUnary,
|
||||||
|
Parenthesize, // (x), (real, imaginary)
|
||||||
|
Constant, // parenthesize if negative integer/real operand
|
||||||
|
Primary, // don't parenthesize
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename A> constexpr Precedence ToPrecedence{Precedence::Primary};
|
template<typename A> constexpr Precedence ToPrecedence{Precedence::Primary};
|
||||||
template<typename T> constexpr Precedence ToPrecedence<Constant<T>>{Precedence::Constant};
|
|
||||||
|
template<int KIND>
|
||||||
|
constexpr Precedence ToPrecedence<Not<KIND>>{Precedence::NOT};
|
||||||
|
template<int KIND>
|
||||||
|
constexpr Precedence ToPrecedence<LogicalOperation<KIND>>{Precedence::Logical};
|
||||||
|
template<typename T>
|
||||||
|
constexpr Precedence ToPrecedence<Relational<T>>{Precedence::Relational};
|
||||||
|
template<int KIND>
|
||||||
|
constexpr Precedence ToPrecedence<Concat<KIND>>{Precedence::Additive};
|
||||||
|
template<typename T>
|
||||||
|
constexpr Precedence ToPrecedence<Subtract<T>>{Precedence::Additive};
|
||||||
|
template<typename T>
|
||||||
|
constexpr Precedence ToPrecedence<Add<T>>{Precedence::Additive};
|
||||||
|
template<typename T>
|
||||||
|
constexpr Precedence ToPrecedence<Divide<T>>{Precedence::Multiplicative};
|
||||||
|
template<typename T>
|
||||||
|
constexpr Precedence ToPrecedence<Multiply<T>>{Precedence::Multiplicative};
|
||||||
|
template<typename T>
|
||||||
|
constexpr Precedence ToPrecedence<RealToIntPower<T>>{Precedence::Power};
|
||||||
|
template<typename T>
|
||||||
|
constexpr Precedence ToPrecedence<Power<T>>{Precedence::Power};
|
||||||
|
template<typename T>
|
||||||
|
constexpr Precedence ToPrecedence<Negate<T>>{Precedence::Negate};
|
||||||
|
template<typename T>
|
||||||
|
constexpr Precedence ToPrecedence<Constant<T>>{Precedence::Constant};
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr Precedence ToPrecedence<Parentheses<T>>{Precedence::Parenthesize};
|
constexpr Precedence ToPrecedence<Parentheses<T>>{Precedence::Parenthesize};
|
||||||
template<int KIND>
|
template<int KIND>
|
||||||
constexpr Precedence ToPrecedence<ComplexConstructor<KIND>>{
|
constexpr Precedence ToPrecedence<ComplexConstructor<KIND>>{
|
||||||
Precedence::Parenthesize};
|
Precedence::Parenthesize};
|
||||||
template<typename T>
|
|
||||||
constexpr Precedence ToPrecedence<Negate<T>>{Precedence::Negate};
|
|
||||||
template<typename T>
|
|
||||||
constexpr Precedence ToPrecedence<Power<T>>{Precedence::Power};
|
|
||||||
template<typename T>
|
|
||||||
constexpr Precedence ToPrecedence<RealToIntPower<T>>{Precedence::Power};
|
|
||||||
template<typename T>
|
|
||||||
constexpr Precedence ToPrecedence<Multiply<T>>{Precedence::Multiplicative};
|
|
||||||
template<typename T>
|
|
||||||
constexpr Precedence ToPrecedence<Divide<T>>{Precedence::Multiplicative};
|
|
||||||
template<typename T>
|
|
||||||
constexpr Precedence ToPrecedence<Add<T>>{Precedence::Additive};
|
|
||||||
template<typename T>
|
|
||||||
constexpr Precedence ToPrecedence<Subtract<T>>{Precedence::Additive};
|
|
||||||
template<int KIND>
|
|
||||||
constexpr Precedence ToPrecedence<Concat<KIND>>{Precedence::Additive};
|
|
||||||
template<typename T>
|
|
||||||
constexpr Precedence ToPrecedence<Relational<T>>{Precedence::Relational};
|
|
||||||
template<int KIND>
|
|
||||||
constexpr Precedence ToPrecedence<LogicalOperation<KIND>>{Precedence::Logical};
|
|
||||||
template<int KIND>
|
|
||||||
constexpr Precedence ToPrecedence<Not<KIND>>{Precedence::NOT};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static constexpr Precedence GetPrecedence(const Expr<T> &expr) {
|
static constexpr Precedence GetPrecedence(const Expr<T> &expr) {
|
||||||
|
@ -203,55 +205,45 @@ static constexpr Precedence GetPrecedence(const Expr<SomeType> &expr) {
|
||||||
expr.u);
|
expr.u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T> static bool IsNegatedScalarConstant(const Expr<T> &expr) {
|
||||||
|
static constexpr TypeCategory cat{T::category};
|
||||||
|
if constexpr (cat == TypeCategory::Integer || cat == TypeCategory::Real) {
|
||||||
|
if (expr.Rank() == 0) {
|
||||||
|
if (const auto *p{UnwrapExpr<Constant<T>>(expr)}) {
|
||||||
|
CHECK(p->size() == 1);
|
||||||
|
return (**p).IsNegative();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<TypeCategory CAT>
|
||||||
|
static bool IsNegatedScalarConstant(const Expr<SomeKind<CAT>> &expr) {
|
||||||
|
return std::visit(
|
||||||
|
[](const auto &x) { return IsNegatedScalarConstant(x); }, expr.u);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename D, typename R, typename... O>
|
template<typename D, typename R, typename... O>
|
||||||
std::ostream &Operation<D, R, O...>::AsFortran(std::ostream &o) const {
|
std::ostream &Operation<D, R, O...>::AsFortran(std::ostream &o) const {
|
||||||
static constexpr Precedence lhsPrec{ToPrecedence<Operand<0>>};
|
Precedence lhsPrec{GetPrecedence(left())};
|
||||||
o << derived().Prefix();
|
o << derived().Prefix();
|
||||||
if constexpr (operands == 1) {
|
if constexpr (operands == 1) {
|
||||||
bool parens{lhsPrec != Precedence::Primary};
|
bool parens{lhsPrec < Precedence::Constant};
|
||||||
if (parens) {
|
o << (parens ? "(" : "") << left() << (parens ? ")" : "");
|
||||||
o << '(';
|
|
||||||
}
|
|
||||||
o << left();
|
|
||||||
if (parens) {
|
|
||||||
o << ')';
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
static constexpr Precedence thisPrec{ToPrecedence<D>};
|
static constexpr Precedence thisPrec{ToPrecedence<D>};
|
||||||
bool lhsParens{lhsPrec == Precedence::Parenthesize || lhsPrec > thisPrec ||
|
bool lhsParens{lhsPrec == Precedence::Parenthesize || lhsPrec < thisPrec ||
|
||||||
(lhsPrec == thisPrec && lhsPrec == Precedence::Power)};
|
(lhsPrec == thisPrec && lhsPrec == Precedence::Power) ||
|
||||||
if constexpr (lhsPrec == Precedence::Constant && thisPrec != Precedence::Additive) {
|
(thisPrec != Precedence::Additive && lhsPrec == Precedence::Constant &&
|
||||||
static constexpr TypeCategory cat{Operand<0>::Result::category};
|
IsNegatedScalarConstant(left()))};
|
||||||
if constexpr (cat == TypeCategory::Integer || cat == TypeCategory::Real) {
|
o << (lhsParens ? "(" : "") << left() << (lhsParens ? ")" : "");
|
||||||
const auto *p{UnwrapExpr<Constant<Operand<0>>>(left())};
|
o << derived().Infix();
|
||||||
CHECK(p != nullptr);
|
Precedence rhsPrec{GetPrecedence(right())};
|
||||||
lhsParens |= p->size() == 1 && (*p)->IsNegative();
|
bool rhsParens{rhsPrec == Precedence::Parenthesize ||
|
||||||
}
|
rhsPrec == Precedence::Negate || rhsPrec < thisPrec ||
|
||||||
}
|
(rhsPrec == Precedence::Constant && IsNegatedScalarConstant(right()))};
|
||||||
if (lhsParens) {
|
o << (rhsParens ? "(" : "") << right() << (rhsParens ? ")" : "");
|
||||||
o << '(';
|
|
||||||
}
|
|
||||||
o << left();
|
|
||||||
if (lhsParens) {
|
|
||||||
o << ')';
|
|
||||||
}
|
|
||||||
static constexpr Precedence rhsPrec{ToPrecedence<Operand<1>>};
|
|
||||||
bool rhsParens{rhsPrec == Precedence::Parenthesize || rhsPrec == Precedence::Negate || rhsPrec > thisPrec};
|
|
||||||
if constexpr (rhsPrec == Precedence::Constant) {
|
|
||||||
static constexpr TypeCategory cat{Operand<1>::Result::category};
|
|
||||||
if constexpr (cat == TypeCategory::Integer || cat == TypeCategory::Real) {
|
|
||||||
const auto *p{UnwrapExpr<Constant<Operand<1>>>(right())};
|
|
||||||
CHECK(p != nullptr);
|
|
||||||
rhsParens |= p->size() == 1 && (*p)->IsNegative();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rhsParens) {
|
|
||||||
o << '(';
|
|
||||||
}
|
|
||||||
o << derived().Infix() << right();
|
|
||||||
if (rhsParens) {
|
|
||||||
o << ')';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return o << derived().Suffix();
|
return o << derived().Suffix();
|
||||||
}
|
}
|
||||||
|
@ -323,7 +315,8 @@ std::ostream &EmitArray(std::ostream &o, const ImpliedDo<T> &implDo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::ostream &EmitArray(std::ostream &o, const ArrayConstructorValues<T> &values) {
|
std::ostream &EmitArray(
|
||||||
|
std::ostream &o, const ArrayConstructorValues<T> &values) {
|
||||||
const char *sep{""};
|
const char *sep{""};
|
||||||
for (const auto &value : values.values()) {
|
for (const auto &value : values.values()) {
|
||||||
o << sep;
|
o << sep;
|
||||||
|
@ -498,7 +491,9 @@ std::ostream &Triplet::AsFortran(std::ostream &o) const {
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream &Subscript::AsFortran(std::ostream &o) const { return EmitVar(o, u); }
|
std::ostream &Subscript::AsFortran(std::ostream &o) const {
|
||||||
|
return EmitVar(o, u);
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream &ArrayRef::AsFortran(std::ostream &o) const {
|
std::ostream &ArrayRef::AsFortran(std::ostream &o) const {
|
||||||
EmitVar(o, base_);
|
EmitVar(o, base_);
|
||||||
|
@ -532,12 +527,15 @@ std::ostream &CoarrayRef::AsFortran(std::ostream &o) const {
|
||||||
separator = ',';
|
separator = ',';
|
||||||
}
|
}
|
||||||
if (team_.has_value()) {
|
if (team_.has_value()) {
|
||||||
EmitVar(o << separator, team_, teamIsTeamNumber_ ? "TEAM_NUMBER=" : "TEAM=");
|
EmitVar(
|
||||||
|
o << separator, team_, teamIsTeamNumber_ ? "TEAM_NUMBER=" : "TEAM=");
|
||||||
}
|
}
|
||||||
return o << ']';
|
return o << ']';
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream &DataRef::AsFortran(std::ostream &o) const { return EmitVar(o, u); }
|
std::ostream &DataRef::AsFortran(std::ostream &o) const {
|
||||||
|
return EmitVar(o, u);
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream &Substring::AsFortran(std::ostream &o) const {
|
std::ostream &Substring::AsFortran(std::ostream &o) const {
|
||||||
EmitVar(o, parent_) << '(';
|
EmitVar(o, parent_) << '(';
|
||||||
|
|
|
@ -15,6 +15,15 @@
|
||||||
#ifndef FORTRAN_EVALUATE_FORMATTING_H_
|
#ifndef FORTRAN_EVALUATE_FORMATTING_H_
|
||||||
#define FORTRAN_EVALUATE_FORMATTING_H_
|
#define FORTRAN_EVALUATE_FORMATTING_H_
|
||||||
|
|
||||||
|
// It is inconvenient in C++ to have std::ostream::operator<<() as a direct
|
||||||
|
// friend function of a class template with many instantiations, so the
|
||||||
|
// various representational class templates in lib/evaluate format themselves
|
||||||
|
// via AsFortran(std::ostream &) member functions, which the operator<<()
|
||||||
|
// overload below will call.
|
||||||
|
//
|
||||||
|
// This header is meant to be included by the headers that define the several
|
||||||
|
// representational class templates that need it, not by external clients.
|
||||||
|
|
||||||
#include "../common/indirection.h"
|
#include "../common/indirection.h"
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
// Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
// Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1951,7 +1951,7 @@ void ExprChecker::Enter(const parser::Expr &expr) {
|
||||||
if (!expr.typedExpr) {
|
if (!expr.typedExpr) {
|
||||||
if (MaybeExpr checked{AnalyzeExpr(context_, expr)}) {
|
if (MaybeExpr checked{AnalyzeExpr(context_, expr)}) {
|
||||||
#if PMKDEBUG
|
#if PMKDEBUG
|
||||||
// checked->AsFortran(std::cout << "checked expression: ") << '\n';
|
// std::cout << "checked expression: " << *checked << '\n';
|
||||||
#endif
|
#endif
|
||||||
expr.typedExpr.reset(
|
expr.typedExpr.reset(
|
||||||
new evaluate::GenericExprWrapper{std::move(*checked)});
|
new evaluate::GenericExprWrapper{std::move(*checked)});
|
||||||
|
@ -1967,7 +1967,7 @@ void ExprChecker::Enter(const parser::Expr &expr) {
|
||||||
void ExprChecker::Enter(const parser::Variable &var) {
|
void ExprChecker::Enter(const parser::Variable &var) {
|
||||||
#if PMKDEBUG
|
#if PMKDEBUG
|
||||||
if (MaybeExpr checked{AnalyzeExpr(context_, var)}) {
|
if (MaybeExpr checked{AnalyzeExpr(context_, var)}) {
|
||||||
// checked->AsFortran(std::cout << "checked variable: ") << '\n';
|
// std::cout << "checked variable: " << *checked << '\n';
|
||||||
#else
|
#else
|
||||||
if (AnalyzeExpr(context_, var)) {
|
if (AnalyzeExpr(context_, var)) {
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
// Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -37,7 +37,7 @@ int main() {
|
||||||
MATCH("-1_4", AsFortran(-DefaultIntegerExpr{1}));
|
MATCH("-1_4", AsFortran(-DefaultIntegerExpr{1}));
|
||||||
auto ex1{
|
auto ex1{
|
||||||
DefaultIntegerExpr{2} + DefaultIntegerExpr{3} * -DefaultIntegerExpr{4}};
|
DefaultIntegerExpr{2} + DefaultIntegerExpr{3} * -DefaultIntegerExpr{4}};
|
||||||
MATCH("2_4+3_4*(-4_4))", AsFortran(ex1));
|
MATCH("2_4+3_4*(-4_4)", AsFortran(ex1));
|
||||||
Fortran::parser::CharBlock src;
|
Fortran::parser::CharBlock src;
|
||||||
Fortran::parser::ContextualMessages messages{src, nullptr};
|
Fortran::parser::ContextualMessages messages{src, nullptr};
|
||||||
FoldingContext context{messages};
|
FoldingContext context{messages};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
! Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
! Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
|
||||||
!
|
!
|
||||||
! Licensed under the Apache License, Version 2.0 (the "License");
|
! Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
! you may not use this file except in compliance with the License.
|
! you may not use this file except in compliance with the License.
|
||||||
|
|
Loading…
Reference in New Issue