forked from OSchip/llvm-project
[flang] Reformat with latest clang-format and .clang-format
Original-commit: flang-compiler/f18@9fe84f45d7 Reviewed-on: https://github.com/flang-compiler/f18/pull/1094
This commit is contained in:
parent
10b1addcef
commit
1f8790050b
flang
include/flang
Common
Fortran-features.hFortran.hbit-population-count.hconstexpr-bitset.hdefault-kinds.henum-set.hformat.hidioms.hindirection.hinterval.hleading-zero-bit-count.hreal.hreference-counted.hreference.hrestorer.htemplate.huint128.hunsigned-const-division.hunwrap.h
Decimal
Evaluate
call.hcharacteristics.hcheck-expression.hcommon.hcomplex.hconstant.hexpression.hfold.hformatting.hintrinsics-library.hintrinsics.hreal.hrounding-bits.hshape.hstatic-data.htraverse.htype.hvariable.h
ISO_Fortran_binding.hParser
char-block.hchar-buffer.hchar-set.hcharacters.hdump-parse-tree.hformat-specification.hinstrumented-parser.hmessage.hparse-state.hparse-tree-visitor.hparse-tree.hparsing.hprovenance.hsource.htools.hunparse.huser-state.h
Semantics
lib
Common
Decimal
Evaluate
call.cppcharacter.hcharacteristics.cppcheck-expression.cppcommon.cppcomplex.cppconstant.cppexpression.cppfold-character.cppfold-complex.cppfold-implementation.hfold-integer.cppfold-logical.cppfold-real.cppfold.cppformatting.cpphost.cpphost.hint-power.hinteger.cppintrinsics-library-templates.hintrinsics-library.cppintrinsics.cpplogical.cppreal.cppshape.cppstatic-data.cpptools.cpptype.cpp
|
@ -61,5 +61,5 @@ private:
|
|||
LanguageFeatures warn_;
|
||||
bool warnAll_{false};
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
#endif // FORTRAN_COMMON_FORTRAN_FEATURES_H_
|
||||
|
|
|
@ -68,5 +68,5 @@ enum class RoundingMode : std::uint8_t {
|
|||
|
||||
// Fortran arrays may have up to 15 dimensions (See Fortran 2018 section 5.4.6).
|
||||
static constexpr int maxRank{15};
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
#endif // FORTRAN_COMMON_FORTRAN_H_
|
||||
|
|
|
@ -70,18 +70,18 @@ inline constexpr int BitPopulationCount(std::uint8_t x) {
|
|||
return (x & 0xf) + (x >> 4);
|
||||
}
|
||||
|
||||
template<typename UINT> inline constexpr bool Parity(UINT x) {
|
||||
template <typename UINT> inline constexpr bool Parity(UINT x) {
|
||||
return BitPopulationCount(x) & 1;
|
||||
}
|
||||
|
||||
// "Parity is for farmers." -- Seymour R. Cray
|
||||
|
||||
template<typename UINT> inline constexpr int TrailingZeroBitCount(UINT x) {
|
||||
template <typename UINT> inline constexpr int TrailingZeroBitCount(UINT x) {
|
||||
if ((x & 1) != 0) {
|
||||
return 0; // fast path for odd values
|
||||
} else {
|
||||
return BitPopulationCount(static_cast<UINT>(x ^ (x - 1))) - !!x;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
#endif // FORTRAN_COMMON_BIT_POPULATION_COUNT_H_
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
namespace Fortran::common {
|
||||
|
||||
template<int BITS> class BitSet {
|
||||
template <int BITS> class BitSet {
|
||||
static_assert(BITS > 0 && BITS <= 64);
|
||||
static constexpr bool partialWord{BITS != 32 && BITS != 64};
|
||||
using Word = std::conditional_t<(BITS > 32), std::uint64_t, std::uint32_t>;
|
||||
|
@ -143,5 +143,5 @@ public:
|
|||
private:
|
||||
Word bits_{0};
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
#endif // FORTRAN_COMMON_CONSTEXPR_BITSET_H_
|
||||
|
|
|
@ -57,5 +57,5 @@ private:
|
|||
int defaultCharacterKind_{1};
|
||||
int defaultLogicalKind_{defaultIntegerKind_};
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
#endif // FORTRAN_COMMON_DEFAULT_KINDS_H_
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
namespace Fortran::common {
|
||||
|
||||
template<typename ENUM, std::size_t BITS> class EnumSet {
|
||||
template <typename ENUM, std::size_t BITS> class EnumSet {
|
||||
static_assert(BITS > 0);
|
||||
|
||||
public:
|
||||
|
@ -191,7 +191,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template<typename FUNC> void IterateOverMembers(const FUNC &f) const {
|
||||
template <typename FUNC> void IterateOverMembers(const FUNC &f) const {
|
||||
EnumSet copy{*this};
|
||||
while (auto least{copy.LeastElement()}) {
|
||||
f(*least);
|
||||
|
@ -212,9 +212,9 @@ public:
|
|||
private:
|
||||
bitsetType bitset_{};
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
|
||||
template<typename ENUM, std::size_t values>
|
||||
template <typename ENUM, std::size_t values>
|
||||
struct std::hash<Fortran::common::EnumSet<ENUM, values>> {
|
||||
std::size_t operator()(
|
||||
const Fortran::common::EnumSet<ENUM, values> &x) const {
|
||||
|
|
|
@ -46,13 +46,13 @@ ENUM_CLASS(TokenKind, None, A, B, BN, BZ, D, DC, DP, DT, E, EN, ES, EX, F, G, I,
|
|||
UnsignedInteger, // value in integerValue_
|
||||
String) // char-literal-constant or Hollerith constant
|
||||
|
||||
template<typename CHAR = char> class FormatValidator {
|
||||
template <typename CHAR = char> class FormatValidator {
|
||||
public:
|
||||
using Reporter = std::function<bool(const FormatMessage &)>;
|
||||
FormatValidator(const CHAR *format, size_t length, Reporter reporter,
|
||||
IoStmtKind stmt = IoStmtKind::None)
|
||||
: format_{format}, end_{format + length}, reporter_{reporter}, stmt_{stmt},
|
||||
cursor_{format - 1} {
|
||||
: format_{format}, end_{format + length}, reporter_{reporter},
|
||||
stmt_{stmt}, cursor_{format - 1} {
|
||||
CHECK(format);
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ private:
|
|||
int maxNesting_{0}; // max level of nested parentheses
|
||||
};
|
||||
|
||||
template<typename CHAR> CHAR FormatValidator<CHAR>::NextChar() {
|
||||
template <typename CHAR> CHAR FormatValidator<CHAR>::NextChar() {
|
||||
for (++cursor_; cursor_ < end_; ++cursor_) {
|
||||
if (*cursor_ != ' ') {
|
||||
return toupper(*cursor_);
|
||||
|
@ -159,7 +159,7 @@ template<typename CHAR> CHAR FormatValidator<CHAR>::NextChar() {
|
|||
return ' ';
|
||||
}
|
||||
|
||||
template<typename CHAR> CHAR FormatValidator<CHAR>::LookAheadChar() {
|
||||
template <typename CHAR> CHAR FormatValidator<CHAR>::LookAheadChar() {
|
||||
for (laCursor_ = cursor_ + 1; laCursor_ < end_; ++laCursor_) {
|
||||
if (*laCursor_ != ' ') {
|
||||
return toupper(*laCursor_);
|
||||
|
@ -170,12 +170,12 @@ template<typename CHAR> CHAR FormatValidator<CHAR>::LookAheadChar() {
|
|||
}
|
||||
|
||||
// After a call to LookAheadChar, set token kind and advance cursor to laCursor.
|
||||
template<typename CHAR> void FormatValidator<CHAR>::Advance(TokenKind tk) {
|
||||
template <typename CHAR> void FormatValidator<CHAR>::Advance(TokenKind tk) {
|
||||
cursor_ = laCursor_;
|
||||
token_.set_kind(tk);
|
||||
}
|
||||
|
||||
template<typename CHAR> void FormatValidator<CHAR>::NextToken() {
|
||||
template <typename CHAR> void FormatValidator<CHAR>::NextToken() {
|
||||
// At entry, cursor_ points before the start of the next token.
|
||||
// At exit, cursor_ points to last CHAR of token_.
|
||||
|
||||
|
@ -241,72 +241,154 @@ template<typename CHAR> void FormatValidator<CHAR>::NextToken() {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case 'A': token_.set_kind(TokenKind::A); break;
|
||||
case 'A':
|
||||
token_.set_kind(TokenKind::A);
|
||||
break;
|
||||
case 'B':
|
||||
switch (LookAheadChar()) {
|
||||
case 'N': Advance(TokenKind::BN); break;
|
||||
case 'Z': Advance(TokenKind::BZ); break;
|
||||
default: token_.set_kind(TokenKind::B); break;
|
||||
case 'N':
|
||||
Advance(TokenKind::BN);
|
||||
break;
|
||||
case 'Z':
|
||||
Advance(TokenKind::BZ);
|
||||
break;
|
||||
default:
|
||||
token_.set_kind(TokenKind::B);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'D':
|
||||
switch (LookAheadChar()) {
|
||||
case 'C': Advance(TokenKind::DC); break;
|
||||
case 'P': Advance(TokenKind::DP); break;
|
||||
case 'T': Advance(TokenKind::DT); break;
|
||||
default: token_.set_kind(TokenKind::D); break;
|
||||
case 'C':
|
||||
Advance(TokenKind::DC);
|
||||
break;
|
||||
case 'P':
|
||||
Advance(TokenKind::DP);
|
||||
break;
|
||||
case 'T':
|
||||
Advance(TokenKind::DT);
|
||||
break;
|
||||
default:
|
||||
token_.set_kind(TokenKind::D);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'E':
|
||||
switch (LookAheadChar()) {
|
||||
case 'N': Advance(TokenKind::EN); break;
|
||||
case 'S': Advance(TokenKind::ES); break;
|
||||
case 'X': Advance(TokenKind::EX); break;
|
||||
default: token_.set_kind(TokenKind::E); break;
|
||||
case 'N':
|
||||
Advance(TokenKind::EN);
|
||||
break;
|
||||
case 'S':
|
||||
Advance(TokenKind::ES);
|
||||
break;
|
||||
case 'X':
|
||||
Advance(TokenKind::EX);
|
||||
break;
|
||||
default:
|
||||
token_.set_kind(TokenKind::E);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'F': token_.set_kind(TokenKind::F); break;
|
||||
case 'G': token_.set_kind(TokenKind::G); break;
|
||||
case 'I': token_.set_kind(TokenKind::I); break;
|
||||
case 'L': token_.set_kind(TokenKind::L); break;
|
||||
case 'O': token_.set_kind(TokenKind::O); break;
|
||||
case 'P': token_.set_kind(TokenKind::P); break;
|
||||
case 'F':
|
||||
token_.set_kind(TokenKind::F);
|
||||
break;
|
||||
case 'G':
|
||||
token_.set_kind(TokenKind::G);
|
||||
break;
|
||||
case 'I':
|
||||
token_.set_kind(TokenKind::I);
|
||||
break;
|
||||
case 'L':
|
||||
token_.set_kind(TokenKind::L);
|
||||
break;
|
||||
case 'O':
|
||||
token_.set_kind(TokenKind::O);
|
||||
break;
|
||||
case 'P':
|
||||
token_.set_kind(TokenKind::P);
|
||||
break;
|
||||
case 'R':
|
||||
switch (LookAheadChar()) {
|
||||
case 'C': Advance(TokenKind::RC); break;
|
||||
case 'D': Advance(TokenKind::RD); break;
|
||||
case 'N': Advance(TokenKind::RN); break;
|
||||
case 'P': Advance(TokenKind::RP); break;
|
||||
case 'U': Advance(TokenKind::RU); break;
|
||||
case 'Z': Advance(TokenKind::RZ); break;
|
||||
default: token_.set_kind(TokenKind::None); break;
|
||||
case 'C':
|
||||
Advance(TokenKind::RC);
|
||||
break;
|
||||
case 'D':
|
||||
Advance(TokenKind::RD);
|
||||
break;
|
||||
case 'N':
|
||||
Advance(TokenKind::RN);
|
||||
break;
|
||||
case 'P':
|
||||
Advance(TokenKind::RP);
|
||||
break;
|
||||
case 'U':
|
||||
Advance(TokenKind::RU);
|
||||
break;
|
||||
case 'Z':
|
||||
Advance(TokenKind::RZ);
|
||||
break;
|
||||
default:
|
||||
token_.set_kind(TokenKind::None);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
switch (LookAheadChar()) {
|
||||
case 'P': Advance(TokenKind::SP); break;
|
||||
case 'S': Advance(TokenKind::SS); break;
|
||||
default: token_.set_kind(TokenKind::S); break;
|
||||
case 'P':
|
||||
Advance(TokenKind::SP);
|
||||
break;
|
||||
case 'S':
|
||||
Advance(TokenKind::SS);
|
||||
break;
|
||||
default:
|
||||
token_.set_kind(TokenKind::S);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'T':
|
||||
switch (LookAheadChar()) {
|
||||
case 'L': Advance(TokenKind::TL); break;
|
||||
case 'R': Advance(TokenKind::TR); break;
|
||||
default: token_.set_kind(TokenKind::T); break;
|
||||
case 'L':
|
||||
Advance(TokenKind::TL);
|
||||
break;
|
||||
case 'R':
|
||||
Advance(TokenKind::TR);
|
||||
break;
|
||||
default:
|
||||
token_.set_kind(TokenKind::T);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'X': token_.set_kind(TokenKind::X); break;
|
||||
case 'Z': token_.set_kind(TokenKind::Z); break;
|
||||
case 'X':
|
||||
token_.set_kind(TokenKind::X);
|
||||
break;
|
||||
case 'Z':
|
||||
token_.set_kind(TokenKind::Z);
|
||||
break;
|
||||
case '-':
|
||||
case '+': token_.set_kind(TokenKind::Sign); break;
|
||||
case '/': token_.set_kind(TokenKind::Slash); break;
|
||||
case '(': token_.set_kind(TokenKind::LParen); break;
|
||||
case ')': token_.set_kind(TokenKind::RParen); break;
|
||||
case '.': token_.set_kind(TokenKind::Point); break;
|
||||
case ':': token_.set_kind(TokenKind::Colon); break;
|
||||
case '\\': token_.set_kind(TokenKind::Backslash); break;
|
||||
case '$': token_.set_kind(TokenKind::Dollar); break;
|
||||
case '+':
|
||||
token_.set_kind(TokenKind::Sign);
|
||||
break;
|
||||
case '/':
|
||||
token_.set_kind(TokenKind::Slash);
|
||||
break;
|
||||
case '(':
|
||||
token_.set_kind(TokenKind::LParen);
|
||||
break;
|
||||
case ')':
|
||||
token_.set_kind(TokenKind::RParen);
|
||||
break;
|
||||
case '.':
|
||||
token_.set_kind(TokenKind::Point);
|
||||
break;
|
||||
case ':':
|
||||
token_.set_kind(TokenKind::Colon);
|
||||
break;
|
||||
case '\\':
|
||||
token_.set_kind(TokenKind::Backslash);
|
||||
break;
|
||||
case '$':
|
||||
token_.set_kind(TokenKind::Dollar);
|
||||
break;
|
||||
case '*':
|
||||
token_.set_kind(LookAheadChar() == '(' ? TokenKind::Star : TokenKind::None);
|
||||
break;
|
||||
|
@ -353,7 +435,7 @@ template<typename CHAR> void FormatValidator<CHAR>::NextToken() {
|
|||
SetLength();
|
||||
}
|
||||
|
||||
template<typename CHAR> void FormatValidator<CHAR>::check_r(bool allowed) {
|
||||
template <typename CHAR> void FormatValidator<CHAR>::check_r(bool allowed) {
|
||||
if (!allowed && knrValue_ >= 0) {
|
||||
ReportError("Repeat specifier before '%s' edit descriptor", knrToken_);
|
||||
} else if (knrValue_ == 0) {
|
||||
|
@ -363,7 +445,7 @@ template<typename CHAR> void FormatValidator<CHAR>::check_r(bool allowed) {
|
|||
}
|
||||
|
||||
// Return the predicate "w value is present" to control further processing.
|
||||
template<typename CHAR> bool FormatValidator<CHAR>::check_w() {
|
||||
template <typename CHAR> bool FormatValidator<CHAR>::check_w() {
|
||||
if (token_.kind() == TokenKind::UnsignedInteger) {
|
||||
wValue_ = integerValue_;
|
||||
if (wValue_ == 0 &&
|
||||
|
@ -380,7 +462,7 @@ template<typename CHAR> bool FormatValidator<CHAR>::check_w() {
|
|||
return false;
|
||||
}
|
||||
|
||||
template<typename CHAR> void FormatValidator<CHAR>::check_m() {
|
||||
template <typename CHAR> void FormatValidator<CHAR>::check_m() {
|
||||
if (token_.kind() != TokenKind::Point) {
|
||||
return;
|
||||
}
|
||||
|
@ -397,7 +479,7 @@ template<typename CHAR> void FormatValidator<CHAR>::check_m() {
|
|||
}
|
||||
|
||||
// Return the predicate "d value is present" to control further processing.
|
||||
template<typename CHAR> bool FormatValidator<CHAR>::check_d() {
|
||||
template <typename CHAR> bool FormatValidator<CHAR>::check_d() {
|
||||
if (token_.kind() != TokenKind::Point) {
|
||||
ReportError("Expected '%s' edit descriptor '.d' value");
|
||||
return false;
|
||||
|
@ -411,7 +493,7 @@ template<typename CHAR> bool FormatValidator<CHAR>::check_d() {
|
|||
return true;
|
||||
}
|
||||
|
||||
template<typename CHAR> void FormatValidator<CHAR>::check_e() {
|
||||
template <typename CHAR> void FormatValidator<CHAR>::check_e() {
|
||||
if (token_.kind() != TokenKind::E) {
|
||||
return;
|
||||
}
|
||||
|
@ -423,7 +505,7 @@ template<typename CHAR> void FormatValidator<CHAR>::check_e() {
|
|||
NextToken();
|
||||
}
|
||||
|
||||
template<typename CHAR> bool FormatValidator<CHAR>::Check() {
|
||||
template <typename CHAR> bool FormatValidator<CHAR>::Check() {
|
||||
if (!*format_) {
|
||||
ReportError("Empty format expression");
|
||||
return formatHasErrors_;
|
||||
|
@ -616,7 +698,9 @@ template<typename CHAR> bool FormatValidator<CHAR>::Check() {
|
|||
case TokenKind::ES:
|
||||
case TokenKind::EX:
|
||||
case TokenKind::F:
|
||||
case TokenKind::G: commaRequired = false; break;
|
||||
case TokenKind::G:
|
||||
commaRequired = false;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
cursor_ = saveCursor;
|
||||
|
@ -718,7 +802,9 @@ template<typename CHAR> bool FormatValidator<CHAR>::Check() {
|
|||
break;
|
||||
}
|
||||
[[fallthrough]];
|
||||
default: ReportError("Unexpected '%s' in format expression"); NextToken();
|
||||
default:
|
||||
ReportError("Unexpected '%s' in format expression");
|
||||
NextToken();
|
||||
}
|
||||
|
||||
// Process comma separator and exit an incomplete format.
|
||||
|
@ -755,5 +841,5 @@ template<typename CHAR> bool FormatValidator<CHAR>::Check() {
|
|||
return formatHasErrors_; // error reporter (message threshold) exit
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
#endif // FORTRAN_COMMON_FORMAT_H_
|
||||
|
|
|
@ -34,11 +34,11 @@
|
|||
#if __GNUC__ == 7
|
||||
// Avoid a deduction bug in GNU 7.x headers by forcing the answer.
|
||||
namespace std {
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
struct is_trivially_copy_constructible<list<A>> : false_type {};
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
struct is_trivially_copy_constructible<optional<list<A>>> : false_type {};
|
||||
}
|
||||
} // namespace std
|
||||
#endif
|
||||
|
||||
// enable "this is a std::string"s with the 's' suffix
|
||||
|
@ -54,11 +54,11 @@ namespace Fortran::common {
|
|||
// ...
|
||||
// [&](const auto &catchAll) { ... }}, variantObject);
|
||||
|
||||
template<typename... LAMBDAS> struct visitors : LAMBDAS... {
|
||||
template <typename... LAMBDAS> struct visitors : LAMBDAS... {
|
||||
using LAMBDAS::operator()...;
|
||||
};
|
||||
|
||||
template<typename... LAMBDAS> visitors(LAMBDAS... x)->visitors<LAMBDAS...>;
|
||||
template <typename... LAMBDAS> visitors(LAMBDAS... x) -> visitors<LAMBDAS...>;
|
||||
|
||||
// Calls std::fprintf(stderr, ...), then abort().
|
||||
[[noreturn]] void die(const char *, ...);
|
||||
|
@ -93,11 +93,11 @@ template<typename... LAMBDAS> visitors(LAMBDAS... x)->visitors<LAMBDAS...>;
|
|||
// in template specialization definitions.
|
||||
#define CLASS_TRAIT(T) \
|
||||
namespace class_trait_ns_##T { \
|
||||
template<typename A> std::true_type test(typename A::T *); \
|
||||
template<typename A> std::false_type test(...); \
|
||||
template<typename A> \
|
||||
template <typename A> std::true_type test(typename A::T *); \
|
||||
template <typename A> std::false_type test(...); \
|
||||
template <typename A> \
|
||||
constexpr bool has_trait{decltype(test<A>(nullptr))::value}; \
|
||||
template<typename A> constexpr bool trait_value() { \
|
||||
template <typename A> constexpr bool trait_value() { \
|
||||
if constexpr (has_trait<A>) { \
|
||||
using U = typename A::T; \
|
||||
return U::value; \
|
||||
|
@ -106,7 +106,7 @@ template<typename... LAMBDAS> visitors(LAMBDAS... x)->visitors<LAMBDAS...>;
|
|||
} \
|
||||
} \
|
||||
} \
|
||||
template<typename A> constexpr bool T{class_trait_ns_##T::trait_value<A>()};
|
||||
template <typename A> constexpr bool T{class_trait_ns_##T::trait_value<A>()};
|
||||
|
||||
#if !defined ATTRIBUTE_UNUSED && (__clang__ || __GNUC__)
|
||||
#define ATTRIBUTE_UNUSED __attribute__((unused))
|
||||
|
@ -119,7 +119,7 @@ template<typename... LAMBDAS> visitors(LAMBDAS... x)->visitors<LAMBDAS...>;
|
|||
|
||||
std::string EnumIndexToString(int index, const char *names);
|
||||
|
||||
template<typename A> struct ListItemCount {
|
||||
template <typename A> struct ListItemCount {
|
||||
constexpr ListItemCount(std::initializer_list<A> list) : value{list.size()} {}
|
||||
const std::size_t value;
|
||||
};
|
||||
|
@ -138,7 +138,7 @@ template<typename A> struct ListItemCount {
|
|||
// Check that a pointer is non-null and dereference it
|
||||
#define DEREF(p) Fortran::common::Deref(p, __FILE__, __LINE__)
|
||||
|
||||
template<typename T> constexpr T &Deref(T *p, const char *file, int line) {
|
||||
template <typename T> constexpr T &Deref(T *p, const char *file, int line) {
|
||||
if (!p) {
|
||||
Fortran::common::die("nullptr dereference at %s(%d)", file, line);
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ template<typename T> constexpr T &Deref(T *p, const char *file, int line) {
|
|||
}
|
||||
|
||||
// Given a const reference to a value, return a copy of the value.
|
||||
template<typename A> A Clone(const A &x) { return x; }
|
||||
template <typename A> A Clone(const A &x) { return x; }
|
||||
|
||||
// C++ does a weird and dangerous thing when deducing template type parameters
|
||||
// from function arguments: lvalue references are allowed to match rvalue
|
||||
|
@ -159,8 +159,8 @@ template<typename A> A Clone(const A &x) { return x; }
|
|||
// or, for constructors,
|
||||
// template<typename A, typename = common::NoLvalue<A>> int foo(A &&);
|
||||
// This works with parameter packs too.
|
||||
template<typename A, typename... B>
|
||||
template <typename A, typename... B>
|
||||
using IfNoLvalue = std::enable_if_t<(... && !std::is_lvalue_reference_v<B>), A>;
|
||||
template<typename... RVREF> using NoLvalue = IfNoLvalue<void, RVREF...>;
|
||||
}
|
||||
template <typename... RVREF> using NoLvalue = IfNoLvalue<void, RVREF...>;
|
||||
} // namespace Fortran::common
|
||||
#endif // FORTRAN_COMMON_IDIOMS_H_
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
namespace Fortran::common {
|
||||
|
||||
// The default case does not support (deep) copy construction or assignment.
|
||||
template<typename A, bool COPY = false> class Indirection {
|
||||
template <typename A, bool COPY = false> class Indirection {
|
||||
public:
|
||||
using element_type = A;
|
||||
Indirection() = delete;
|
||||
|
@ -59,7 +59,7 @@ public:
|
|||
bool operator==(const A &that) const { return *p_ == that; }
|
||||
bool operator==(const Indirection &that) const { return *p_ == *that.p_; }
|
||||
|
||||
template<typename... ARGS>
|
||||
template <typename... ARGS>
|
||||
static common::IfNoLvalue<Indirection, ARGS...> Make(ARGS &&... args) {
|
||||
return {new A(std::move(args)...)};
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ private:
|
|||
};
|
||||
|
||||
// Variant with copy construction and assignment
|
||||
template<typename A> class Indirection<A, true> {
|
||||
template <typename A> class Indirection<A, true> {
|
||||
public:
|
||||
using element_type = A;
|
||||
|
||||
|
@ -111,7 +111,7 @@ public:
|
|||
bool operator==(const A &that) const { return *p_ == that; }
|
||||
bool operator==(const Indirection &that) const { return *p_ == *that.p_; }
|
||||
|
||||
template<typename... ARGS>
|
||||
template <typename... ARGS>
|
||||
static common::IfNoLvalue<Indirection, ARGS...> Make(ARGS &&... args) {
|
||||
return {new A(std::move(args)...)};
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ private:
|
|||
A *p_{nullptr};
|
||||
};
|
||||
|
||||
template<typename A> using CopyableIndirection = Indirection<A, true>;
|
||||
template <typename A> using CopyableIndirection = Indirection<A, true>;
|
||||
|
||||
// For use with std::unique_ptr<> when declaring owning pointers to
|
||||
// forward-referenced types, here's a minimal custom deleter that avoids
|
||||
|
@ -129,13 +129,13 @@ template<typename A> using CopyableIndirection = Indirection<A, true>;
|
|||
// type is visible. Be advised, std::unique_ptr<> does not have copy
|
||||
// semantics; if you need ownership, copy semantics, and nullability,
|
||||
// std::optional<CopyableIndirection<>> works.
|
||||
template<typename A> class Deleter {
|
||||
template <typename A> class Deleter {
|
||||
public:
|
||||
void operator()(A *) const;
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
#define DEFINE_DELETER(A) \
|
||||
template<> void Fortran::common::Deleter<A>::operator()(A *p) const { \
|
||||
template <> void Fortran::common::Deleter<A>::operator()(A *p) const { \
|
||||
delete p; \
|
||||
}
|
||||
#endif // FORTRAN_COMMON_INDIRECTION_H_
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
namespace Fortran::common {
|
||||
|
||||
template<typename A> class Interval {
|
||||
template <typename A> class Interval {
|
||||
public:
|
||||
using type = A;
|
||||
constexpr Interval() {}
|
||||
|
@ -111,5 +111,5 @@ private:
|
|||
A start_;
|
||||
std::size_t size_{0};
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
#endif // FORTRAN_COMMON_INTERVAL_H_
|
||||
|
|
|
@ -40,7 +40,7 @@ static constexpr std::uint8_t mapping[64]{63, 0, 58, 1, 59, 47, 53, 2, 60, 39,
|
|||
48, 27, 54, 33, 42, 3, 61, 51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43,
|
||||
14, 22, 4, 62, 57, 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21,
|
||||
56, 45, 25, 31, 35, 16, 9, 12, 44, 24, 15, 8, 23, 7, 6, 5};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
inline constexpr int LeadingZeroBitCount(std::uint64_t x) {
|
||||
if (x == 0) {
|
||||
|
@ -89,8 +89,8 @@ inline constexpr int LeadingZeroBitCount(std::uint8_t x) {
|
|||
return eightBitLeadingZeroBitCount[x];
|
||||
}
|
||||
|
||||
template<typename A> inline constexpr int BitsNeededFor(A x) {
|
||||
template <typename A> inline constexpr int BitsNeededFor(A x) {
|
||||
return 8 * sizeof x - LeadingZeroBitCount(x);
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
#endif // FORTRAN_COMMON_LEADING_ZERO_BIT_COUNT_H_
|
||||
|
|
|
@ -20,14 +20,22 @@ namespace Fortran::common {
|
|||
// Total representation size in bits for each type
|
||||
static constexpr int BitsForBinaryPrecision(int binaryPrecision) {
|
||||
switch (binaryPrecision) {
|
||||
case 8: return 16; // IEEE single (truncated): 1+8+7
|
||||
case 11: return 16; // IEEE half precision: 1+5+10
|
||||
case 24: return 32; // IEEE single precision: 1+8+23
|
||||
case 53: return 64; // IEEE double precision: 1+11+52
|
||||
case 64: return 80; // x87 extended precision: 1+15+64
|
||||
case 106: return 128; // "double-double": 2*(1+11+52)
|
||||
case 113: return 128; // IEEE quad precision: 1+15+112
|
||||
default: return -1;
|
||||
case 8:
|
||||
return 16; // IEEE single (truncated): 1+8+7
|
||||
case 11:
|
||||
return 16; // IEEE half precision: 1+5+10
|
||||
case 24:
|
||||
return 32; // IEEE single precision: 1+8+23
|
||||
case 53:
|
||||
return 64; // IEEE double precision: 1+11+52
|
||||
case 64:
|
||||
return 80; // x87 extended precision: 1+15+64
|
||||
case 106:
|
||||
return 128; // "double-double": 2*(1+11+52)
|
||||
case 113:
|
||||
return 128; // IEEE quad precision: 1+15+112
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,18 +45,26 @@ static constexpr int BitsForBinaryPrecision(int binaryPrecision) {
|
|||
// exactly with FORMAT(E0.22981).
|
||||
static constexpr int MaxDecimalConversionDigits(int binaryPrecision) {
|
||||
switch (binaryPrecision) {
|
||||
case 8: return 93;
|
||||
case 11: return 17;
|
||||
case 24: return 105;
|
||||
case 53: return 751;
|
||||
case 64: return 11495;
|
||||
case 106: return 2 * 751;
|
||||
case 113: return 11530;
|
||||
default: return -1;
|
||||
case 8:
|
||||
return 93;
|
||||
case 11:
|
||||
return 17;
|
||||
case 24:
|
||||
return 105;
|
||||
case 53:
|
||||
return 751;
|
||||
case 64:
|
||||
return 11495;
|
||||
case 106:
|
||||
return 2 * 751;
|
||||
case 113:
|
||||
return 11530;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
template<int BINARY_PRECISION> class RealDetails {
|
||||
template <int BINARY_PRECISION> class RealDetails {
|
||||
private:
|
||||
// Converts bit widths to whole decimal digits
|
||||
static constexpr int LogBaseTwoToLogBaseTen(int logb2) {
|
||||
|
@ -82,5 +98,5 @@ public:
|
|||
static_assert(exponentBits <= 15);
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
#endif // FORTRAN_COMMON_REAL_H_
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
namespace Fortran::common {
|
||||
|
||||
// A base class for reference-counted objects. Must be public.
|
||||
template<typename A> class ReferenceCounted {
|
||||
template <typename A> class ReferenceCounted {
|
||||
public:
|
||||
ReferenceCounted() {}
|
||||
void TakeReference() { ++references_; }
|
||||
|
@ -31,7 +31,7 @@ private:
|
|||
};
|
||||
|
||||
// A reference to a reference-counted object.
|
||||
template<typename A> class CountedReference {
|
||||
template <typename A> class CountedReference {
|
||||
public:
|
||||
using type = A;
|
||||
CountedReference() {}
|
||||
|
@ -72,5 +72,5 @@ private:
|
|||
|
||||
type *p_{nullptr};
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
#endif // FORTRAN_COMMON_REFERENCE_COUNTED_H_
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#define FORTRAN_COMMON_REFERENCE_H_
|
||||
#include <type_traits>
|
||||
namespace Fortran::common {
|
||||
template<typename A> class Reference {
|
||||
template <typename A> class Reference {
|
||||
public:
|
||||
using type = A;
|
||||
Reference(type &x) : p_{&x} {}
|
||||
|
@ -35,8 +35,8 @@ public:
|
|||
// creation of a temporary copy in cases like:
|
||||
// Reference<type> ref;
|
||||
// const Type &x{ref}; // creates ref to temp copy!
|
||||
operator std::conditional_t<std::is_const_v<type>, type &, void>() const
|
||||
noexcept {
|
||||
operator std::conditional_t<std::is_const_v<type>, type &, void>()
|
||||
const noexcept {
|
||||
if constexpr (std::is_const_v<type>) {
|
||||
return *p_;
|
||||
}
|
||||
|
@ -58,6 +58,6 @@ public:
|
|||
private:
|
||||
type *p_; // never null
|
||||
};
|
||||
template<typename A> Reference(A &)->Reference<A>;
|
||||
}
|
||||
template <typename A> Reference(A &) -> Reference<A>;
|
||||
} // namespace Fortran::common
|
||||
#endif
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#define FORTRAN_COMMON_RESTORER_H_
|
||||
#include "idioms.h"
|
||||
namespace Fortran::common {
|
||||
template<typename A> class Restorer {
|
||||
template <typename A> class Restorer {
|
||||
public:
|
||||
explicit Restorer(A &p) : p_{p}, original_{std::move(p)} {}
|
||||
~Restorer() { p_ = std::move(original_); }
|
||||
|
@ -30,17 +30,17 @@ private:
|
|||
A original_;
|
||||
};
|
||||
|
||||
template<typename A, typename B>
|
||||
template <typename A, typename B>
|
||||
common::IfNoLvalue<Restorer<A>, B> ScopedSet(A &to, B &&from) {
|
||||
Restorer<A> result{to};
|
||||
to = std::move(from);
|
||||
return result;
|
||||
}
|
||||
template<typename A, typename B>
|
||||
template <typename A, typename B>
|
||||
common::IfNoLvalue<Restorer<A>, B> ScopedSet(A &to, const B &from) {
|
||||
Restorer<A> result{to};
|
||||
to = from;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
#endif // FORTRAN_COMMON_RESTORER_H_
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace Fortran::common {
|
|||
// index of the first type T in the list for which PREDICATE<T>::value() is
|
||||
// true is returned, or -1 if the predicate is false for every type in the list.
|
||||
// This is a compile-time operation; see SearchTypes below for a run-time form.
|
||||
template<int N, template<typename> class PREDICATE, typename TUPLE>
|
||||
template <int N, template <typename> class PREDICATE, typename TUPLE>
|
||||
struct SearchTypeListHelper {
|
||||
static constexpr int value() {
|
||||
if constexpr (N >= std::tuple_size_v<TUPLE>) {
|
||||
|
@ -39,41 +39,41 @@ struct SearchTypeListHelper {
|
|||
}
|
||||
};
|
||||
|
||||
template<template<typename> class PREDICATE, typename... TYPES>
|
||||
template <template <typename> class PREDICATE, typename... TYPES>
|
||||
constexpr int SearchTypeList{
|
||||
SearchTypeListHelper<0, PREDICATE, std::tuple<TYPES...>>::value()};
|
||||
|
||||
// TypeIndex<A, TYPES...> scans a list of types for simple type equality.
|
||||
// The zero-based index of A in the list is returned, or -1 if A is not present.
|
||||
template<typename A> struct MatchType {
|
||||
template<typename B> struct Match {
|
||||
template <typename A> struct MatchType {
|
||||
template <typename B> struct Match {
|
||||
static constexpr bool value() {
|
||||
return std::is_same_v<std::decay_t<A>, std::decay_t<B>>;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template<typename A, typename... TYPES>
|
||||
template <typename A, typename... TYPES>
|
||||
constexpr int TypeIndex{SearchTypeList<MatchType<A>::template Match, TYPES...>};
|
||||
|
||||
// IsTypeInList<A, TYPES...> is a simple presence predicate.
|
||||
template<typename A, typename... TYPES>
|
||||
template <typename A, typename... TYPES>
|
||||
constexpr bool IsTypeInList{TypeIndex<A, TYPES...> >= 0};
|
||||
|
||||
// OverMembers extracts the list of types that constitute the alternatives
|
||||
// of a std::variant or elements of a std::tuple and passes that list as
|
||||
// parameter types to a given variadic template.
|
||||
template<template<typename...> class, typename> struct OverMembersHelper;
|
||||
template<template<typename...> class T, typename... Ts>
|
||||
template <template <typename...> class, typename> struct OverMembersHelper;
|
||||
template <template <typename...> class T, typename... Ts>
|
||||
struct OverMembersHelper<T, std::variant<Ts...>> {
|
||||
using type = T<Ts...>;
|
||||
};
|
||||
template<template<typename...> class T, typename... Ts>
|
||||
template <template <typename...> class T, typename... Ts>
|
||||
struct OverMembersHelper<T, std::tuple<Ts...>> {
|
||||
using type = T<Ts...>;
|
||||
};
|
||||
|
||||
template<template<typename...> class T, typename TUPLEorVARIANT>
|
||||
template <template <typename...> class T, typename TUPLEorVARIANT>
|
||||
using OverMembers =
|
||||
typename OverMembersHelper<T, std::decay_t<TUPLEorVARIANT>>::type;
|
||||
|
||||
|
@ -82,23 +82,23 @@ using OverMembers =
|
|||
// The zero-based index of the first type T among the alternatives for which
|
||||
// PREDICATE<T>::value() is true is returned, or -1 when the predicate is false
|
||||
// for every type in the set.
|
||||
template<template<typename> class PREDICATE> struct SearchMembersHelper {
|
||||
template<typename... Ts> struct Scanner {
|
||||
template <template <typename> class PREDICATE> struct SearchMembersHelper {
|
||||
template <typename... Ts> struct Scanner {
|
||||
static constexpr int value() { return SearchTypeList<PREDICATE, Ts...>; }
|
||||
};
|
||||
};
|
||||
|
||||
template<template<typename> class PREDICATE, typename TUPLEorVARIANT>
|
||||
template <template <typename> class PREDICATE, typename TUPLEorVARIANT>
|
||||
constexpr int SearchMembers{
|
||||
OverMembers<SearchMembersHelper<PREDICATE>::template Scanner,
|
||||
TUPLEorVARIANT>::value()};
|
||||
|
||||
template<typename A, typename TUPLEorVARIANT>
|
||||
template <typename A, typename TUPLEorVARIANT>
|
||||
constexpr bool HasMember{
|
||||
SearchMembers<MatchType<A>::template Match, TUPLEorVARIANT> >= 0};
|
||||
|
||||
// std::optional<std::optional<A>> -> std::optional<A>
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
std::optional<A> JoinOptional(std::optional<std::optional<A>> &&x) {
|
||||
if (x) {
|
||||
return std::move(*x);
|
||||
|
@ -107,7 +107,7 @@ std::optional<A> JoinOptional(std::optional<std::optional<A>> &&x) {
|
|||
}
|
||||
|
||||
// Convert an std::optional to an ordinary pointer
|
||||
template<typename A> const A *GetPtrFromOptional(const std::optional<A> &x) {
|
||||
template <typename A> const A *GetPtrFromOptional(const std::optional<A> &x) {
|
||||
if (x) {
|
||||
return &*x;
|
||||
} else {
|
||||
|
@ -117,13 +117,13 @@ template<typename A> const A *GetPtrFromOptional(const std::optional<A> &x) {
|
|||
|
||||
// Copy a value from one variant type to another. The types allowed in the
|
||||
// source variant must all be allowed in the destination variant type.
|
||||
template<typename TOV, typename FROMV> TOV CopyVariant(const FROMV &u) {
|
||||
template <typename TOV, typename FROMV> TOV CopyVariant(const FROMV &u) {
|
||||
return std::visit([](const auto &x) -> TOV { return {x}; }, u);
|
||||
}
|
||||
|
||||
// Move a value from one variant type to another. The types allowed in the
|
||||
// source variant must all be allowed in the destination variant type.
|
||||
template<typename TOV, typename FROMV>
|
||||
template <typename TOV, typename FROMV>
|
||||
common::IfNoLvalue<TOV, FROMV> MoveVariant(FROMV &&u) {
|
||||
return std::visit(
|
||||
[](auto &&x) -> TOV { return {std::move(x)}; }, std::move(u));
|
||||
|
@ -134,26 +134,26 @@ common::IfNoLvalue<TOV, FROMV> MoveVariant(FROMV &&u) {
|
|||
// types. E.g.,
|
||||
// CombineTuples<std::tuple<char, int>, std::tuple<float, double>>
|
||||
// is std::tuple<char, int, float, double>.
|
||||
template<typename... TUPLES> struct CombineTuplesHelper {
|
||||
template <typename... TUPLES> struct CombineTuplesHelper {
|
||||
static decltype(auto) f(TUPLES *... a) {
|
||||
return std::tuple_cat(std::move(*a)...);
|
||||
}
|
||||
using type = decltype(f(static_cast<TUPLES *>(nullptr)...));
|
||||
};
|
||||
template<typename... TUPLES>
|
||||
template <typename... TUPLES>
|
||||
using CombineTuples = typename CombineTuplesHelper<TUPLES...>::type;
|
||||
|
||||
// CombineVariants takes a list of std::variant<> instantiations and constructs
|
||||
// a new instantiation that holds all of their alternatives, which must be
|
||||
// pairwise distinct.
|
||||
template<typename> struct VariantToTupleHelper;
|
||||
template<typename... Ts> struct VariantToTupleHelper<std::variant<Ts...>> {
|
||||
template <typename> struct VariantToTupleHelper;
|
||||
template <typename... Ts> struct VariantToTupleHelper<std::variant<Ts...>> {
|
||||
using type = std::tuple<Ts...>;
|
||||
};
|
||||
template<typename VARIANT>
|
||||
template <typename VARIANT>
|
||||
using VariantToTuple = typename VariantToTupleHelper<VARIANT>::type;
|
||||
|
||||
template<typename A, typename... REST> struct AreTypesDistinctHelper {
|
||||
template <typename A, typename... REST> struct AreTypesDistinctHelper {
|
||||
static constexpr bool value() {
|
||||
if constexpr (sizeof...(REST) > 0) {
|
||||
// extra () for clang-format
|
||||
|
@ -163,10 +163,10 @@ template<typename A, typename... REST> struct AreTypesDistinctHelper {
|
|||
return true;
|
||||
}
|
||||
};
|
||||
template<typename... Ts>
|
||||
template <typename... Ts>
|
||||
constexpr bool AreTypesDistinct{AreTypesDistinctHelper<Ts...>::value()};
|
||||
|
||||
template<typename A, typename... Ts> struct AreSameTypeHelper {
|
||||
template <typename A, typename... Ts> struct AreSameTypeHelper {
|
||||
using type = A;
|
||||
static constexpr bool value() {
|
||||
if constexpr (sizeof...(Ts) == 0) {
|
||||
|
@ -178,53 +178,53 @@ template<typename A, typename... Ts> struct AreSameTypeHelper {
|
|||
}
|
||||
};
|
||||
|
||||
template<typename... Ts>
|
||||
template <typename... Ts>
|
||||
constexpr bool AreSameType{AreSameTypeHelper<Ts...>::value()};
|
||||
|
||||
template<typename> struct TupleToVariantHelper;
|
||||
template<typename... Ts> struct TupleToVariantHelper<std::tuple<Ts...>> {
|
||||
template <typename> struct TupleToVariantHelper;
|
||||
template <typename... Ts> struct TupleToVariantHelper<std::tuple<Ts...>> {
|
||||
static_assert(AreTypesDistinct<Ts...>,
|
||||
"TupleToVariant: types are not pairwise distinct");
|
||||
using type = std::variant<Ts...>;
|
||||
};
|
||||
template<typename TUPLE>
|
||||
template <typename TUPLE>
|
||||
using TupleToVariant = typename TupleToVariantHelper<TUPLE>::type;
|
||||
|
||||
template<typename... VARIANTS> struct CombineVariantsHelper {
|
||||
template <typename... VARIANTS> struct CombineVariantsHelper {
|
||||
using type = TupleToVariant<CombineTuples<VariantToTuple<VARIANTS>...>>;
|
||||
};
|
||||
template<typename... VARIANTS>
|
||||
template <typename... VARIANTS>
|
||||
using CombineVariants = typename CombineVariantsHelper<VARIANTS...>::type;
|
||||
|
||||
// SquashVariantOfVariants: given a std::variant whose alternatives are
|
||||
// all std::variant instantiations, form a new union over their alternatives.
|
||||
template<typename VARIANT>
|
||||
template <typename VARIANT>
|
||||
using SquashVariantOfVariants = OverMembers<CombineVariants, VARIANT>;
|
||||
|
||||
// Given a type function, MapTemplate applies it to each of the types
|
||||
// in a tuple or variant, and collect the results in a given variadic
|
||||
// template (typically a std::variant).
|
||||
template<template<typename> class, template<typename...> class, typename...>
|
||||
template <template <typename> class, template <typename...> class, typename...>
|
||||
struct MapTemplateHelper;
|
||||
template<template<typename> class F, template<typename...> class PACKAGE,
|
||||
template <template <typename> class F, template <typename...> class PACKAGE,
|
||||
typename... Ts>
|
||||
struct MapTemplateHelper<F, PACKAGE, std::tuple<Ts...>> {
|
||||
using type = PACKAGE<F<Ts>...>;
|
||||
};
|
||||
template<template<typename> class F, template<typename...> class PACKAGE,
|
||||
template <template <typename> class F, template <typename...> class PACKAGE,
|
||||
typename... Ts>
|
||||
struct MapTemplateHelper<F, PACKAGE, std::variant<Ts...>> {
|
||||
using type = PACKAGE<F<Ts>...>;
|
||||
};
|
||||
template<template<typename> class F, typename TUPLEorVARIANT,
|
||||
template<typename...> class PACKAGE = std::variant>
|
||||
template <template <typename> class F, typename TUPLEorVARIANT,
|
||||
template <typename...> class PACKAGE = std::variant>
|
||||
using MapTemplate =
|
||||
typename MapTemplateHelper<F, PACKAGE, TUPLEorVARIANT>::type;
|
||||
|
||||
// std::tuple<std::optional<>...> -> std::optional<std::tuple<...>>
|
||||
// i.e., inverts a tuple of optional values into an optional tuple that has
|
||||
// a value only if all of the original elements were present.
|
||||
template<typename... A, std::size_t... J>
|
||||
template <typename... A, std::size_t... J>
|
||||
std::optional<std::tuple<A...>> AllElementsPresentHelper(
|
||||
std::tuple<std::optional<A>...> &&t, std::index_sequence<J...>) {
|
||||
bool present[]{std::get<J>(t).has_value()...};
|
||||
|
@ -236,7 +236,7 @@ std::optional<std::tuple<A...>> AllElementsPresentHelper(
|
|||
return {std::make_tuple(*std::get<J>(t)...)};
|
||||
}
|
||||
|
||||
template<typename... A>
|
||||
template <typename... A>
|
||||
std::optional<std::tuple<A...>> AllElementsPresent(
|
||||
std::tuple<std::optional<A>...> &&t) {
|
||||
return AllElementsPresentHelper(
|
||||
|
@ -246,7 +246,7 @@ std::optional<std::tuple<A...>> AllElementsPresent(
|
|||
// std::vector<std::optional<A>> -> std::optional<std::vector<A>>
|
||||
// i.e., inverts a vector of optional values into an optional vector that
|
||||
// will have a value only when all of the original elements are present.
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
std::optional<std::vector<A>> AllElementsPresent(
|
||||
std::vector<std::optional<A>> &&v) {
|
||||
for (const auto &maybeA : v) {
|
||||
|
@ -264,7 +264,7 @@ std::optional<std::vector<A>> AllElementsPresent(
|
|||
// (std::optional<>...) -> std::optional<std::tuple<...>>
|
||||
// i.e., given some number of optional values, return a optional tuple of
|
||||
// those values that is present only of all of the values were so.
|
||||
template<typename... A>
|
||||
template <typename... A>
|
||||
std::optional<std::tuple<A...>> AllPresent(std::optional<A> &&... x) {
|
||||
return AllElementsPresent(std::make_tuple(std::move(x)...));
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ std::optional<std::tuple<A...>> AllPresent(std::optional<A> &&... x) {
|
|||
// N.B. If the function returns std::optional, MapOptional will return
|
||||
// std::optional<std::optional<...>> and you will probably want to
|
||||
// run it through JoinOptional to "squash" it.
|
||||
template<typename R, typename... A>
|
||||
template <typename R, typename... A>
|
||||
std::optional<R> MapOptional(
|
||||
std::function<R(A &&...)> &&f, std::optional<A> &&... x) {
|
||||
if (auto args{AllPresent(std::move(x)...)}) {
|
||||
|
@ -282,7 +282,7 @@ std::optional<R> MapOptional(
|
|||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
template<typename R, typename... A>
|
||||
template <typename R, typename... A>
|
||||
std::optional<R> MapOptional(R (*f)(A &&...), std::optional<A> &&... x) {
|
||||
return MapOptional(std::function<R(A && ...)>{f}, std::move(x)...);
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ std::optional<R> MapOptional(R (*f)(A &&...), std::optional<A> &&... x) {
|
|||
// and invoke VISITOR::Test<T>() on each until it returns a value that
|
||||
// casts to true. If no invocation of Test succeeds, SearchTypes will
|
||||
// return a default value.
|
||||
template<std::size_t J, typename VISITOR>
|
||||
template <std::size_t J, typename VISITOR>
|
||||
common::IfNoLvalue<typename VISITOR::Result, VISITOR> SearchTypesHelper(
|
||||
VISITOR &&visitor, typename VISITOR::Result &&defaultResult) {
|
||||
using Tuple = typename VISITOR::Types;
|
||||
|
@ -312,12 +312,12 @@ common::IfNoLvalue<typename VISITOR::Result, VISITOR> SearchTypesHelper(
|
|||
}
|
||||
}
|
||||
|
||||
template<typename VISITOR>
|
||||
template <typename VISITOR>
|
||||
common::IfNoLvalue<typename VISITOR::Result, VISITOR> SearchTypes(
|
||||
VISITOR &&visitor,
|
||||
typename VISITOR::Result defaultResult = typename VISITOR::Result{}) {
|
||||
return SearchTypesHelper<0, VISITOR>(
|
||||
std::move(visitor), std::move(defaultResult));
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
#endif // FORTRAN_COMMON_TEMPLATE_H_
|
||||
|
|
|
@ -261,14 +261,14 @@ using uint128_t = __uint128_t;
|
|||
using uint128_t = UnsignedInt128;
|
||||
#endif
|
||||
|
||||
template<int BITS> struct HostUnsignedIntTypeHelper {
|
||||
template <int BITS> struct HostUnsignedIntTypeHelper {
|
||||
using type = std::conditional_t<(BITS <= 8), std::uint8_t,
|
||||
std::conditional_t<(BITS <= 16), std::uint16_t,
|
||||
std::conditional_t<(BITS <= 32), std::uint32_t,
|
||||
std::conditional_t<(BITS <= 64), std::uint64_t, uint128_t>>>>;
|
||||
};
|
||||
template<int BITS>
|
||||
template <int BITS>
|
||||
using HostUnsignedIntType = typename HostUnsignedIntTypeHelper<BITS>::type;
|
||||
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
#endif
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
namespace Fortran::common {
|
||||
|
||||
template<typename UINT> class FixedPointReciprocal {
|
||||
template <typename UINT> class FixedPointReciprocal {
|
||||
public:
|
||||
using type = UINT;
|
||||
|
||||
|
@ -60,7 +60,7 @@ static_assert(FixedPointReciprocal<std::uint32_t>::For(5).Divide(2000000000u) ==
|
|||
static_assert(FixedPointReciprocal<std::uint64_t>::For(10).Divide(
|
||||
10000000000000000u) == 1000000000000000u);
|
||||
|
||||
template<typename UINT, std::uint64_t DENOM>
|
||||
template <typename UINT, std::uint64_t DENOM>
|
||||
inline constexpr UINT DivideUnsignedBy(UINT n) {
|
||||
if constexpr (std::is_same_v<UINT, uint128_t>) {
|
||||
return n / static_cast<UINT>(DENOM);
|
||||
|
@ -73,5 +73,5 @@ inline constexpr UINT DivideUnsignedBy(UINT n) {
|
|||
return recip.Divide(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
#endif
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
namespace Fortran::common {
|
||||
|
||||
// Utility: Produces "const A" if B is const and A is not already so.
|
||||
template<typename A, typename B>
|
||||
template <typename A, typename B>
|
||||
using Constify = std::conditional_t<std::is_const_v<B> && !std::is_const_v<A>,
|
||||
std::add_const_t<A>, A>;
|
||||
|
||||
|
@ -46,7 +46,7 @@ using Constify = std::conditional_t<std::is_const_v<B> && !std::is_const_v<A>,
|
|||
struct UnwrapperHelper {
|
||||
|
||||
// Base case
|
||||
template<typename A, typename B>
|
||||
template <typename A, typename B>
|
||||
static auto Unwrap(B &x) -> Constify<A, B> * {
|
||||
if constexpr (std::is_same_v<std::decay_t<A>, std::decay_t<B>>) {
|
||||
return &x;
|
||||
|
@ -56,7 +56,7 @@ struct UnwrapperHelper {
|
|||
}
|
||||
|
||||
// Implementations of specializations
|
||||
template<typename A, typename B>
|
||||
template <typename A, typename B>
|
||||
static auto Unwrap(B *p) -> Constify<A, B> * {
|
||||
if (p) {
|
||||
return Unwrap<A>(*p);
|
||||
|
@ -65,7 +65,7 @@ struct UnwrapperHelper {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename A, typename B>
|
||||
template <typename A, typename B>
|
||||
static auto Unwrap(const std::unique_ptr<B> &p) -> Constify<A, B> * {
|
||||
if (p.get()) {
|
||||
return Unwrap<A>(*p);
|
||||
|
@ -74,7 +74,7 @@ struct UnwrapperHelper {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename A, typename B>
|
||||
template <typename A, typename B>
|
||||
static auto Unwrap(const std::shared_ptr<B> &p) -> Constify<A, B> * {
|
||||
if (p.get()) {
|
||||
return Unwrap<A>(*p);
|
||||
|
@ -83,7 +83,7 @@ struct UnwrapperHelper {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename A, typename B>
|
||||
template <typename A, typename B>
|
||||
static auto Unwrap(std::optional<B> &x) -> Constify<A, B> * {
|
||||
if (x) {
|
||||
return Unwrap<A>(*x);
|
||||
|
@ -92,7 +92,7 @@ struct UnwrapperHelper {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename A, typename B>
|
||||
template <typename A, typename B>
|
||||
static auto Unwrap(const std::optional<B> &x) -> Constify<A, B> * {
|
||||
if (x) {
|
||||
return Unwrap<A>(*x);
|
||||
|
@ -101,7 +101,7 @@ struct UnwrapperHelper {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename A, typename... Bs>
|
||||
template <typename A, typename... Bs>
|
||||
static A *Unwrap(std::variant<Bs...> &u) {
|
||||
return std::visit(
|
||||
[](auto &x) -> A * {
|
||||
|
@ -115,23 +115,23 @@ struct UnwrapperHelper {
|
|||
u);
|
||||
}
|
||||
|
||||
template<typename A, typename... Bs>
|
||||
template <typename A, typename... Bs>
|
||||
static auto Unwrap(const std::variant<Bs...> &u) -> std::add_const_t<A> * {
|
||||
return std::visit(
|
||||
[](const auto &x) -> std::add_const_t<A> * { return Unwrap<A>(x); }, u);
|
||||
}
|
||||
|
||||
template<typename A, typename B>
|
||||
template <typename A, typename B>
|
||||
static auto Unwrap(const Reference<B> &ref) -> Constify<A, B> * {
|
||||
return Unwrap<A>(*ref);
|
||||
}
|
||||
|
||||
template<typename A, typename B, bool COPY>
|
||||
template <typename A, typename B, bool COPY>
|
||||
static auto Unwrap(const Indirection<B, COPY> &p) -> Constify<A, B> * {
|
||||
return Unwrap<A>(*p);
|
||||
}
|
||||
|
||||
template<typename A, typename B>
|
||||
template <typename A, typename B>
|
||||
static auto Unwrap(const CountedReference<B> &p) -> Constify<A, B> * {
|
||||
if (p.get()) {
|
||||
return Unwrap<A>(*p);
|
||||
|
@ -141,17 +141,17 @@ struct UnwrapperHelper {
|
|||
}
|
||||
};
|
||||
|
||||
template<typename A, typename B> auto Unwrap(B &x) -> Constify<A, B> * {
|
||||
template <typename A, typename B> auto Unwrap(B &x) -> Constify<A, B> * {
|
||||
return UnwrapperHelper::Unwrap<A>(x);
|
||||
}
|
||||
|
||||
// Returns a copy of a wrapped value, if present, otherwise a vacant optional.
|
||||
template<typename A, typename B> std::optional<A> UnwrapCopy(const B &x) {
|
||||
template <typename A, typename B> std::optional<A> UnwrapCopy(const B &x) {
|
||||
if (const A * p{Unwrap<A>(x)}) {
|
||||
return std::make_optional<A>(*p);
|
||||
} else {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
#endif // FORTRAN_COMMON_UNWRAP_H_
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
namespace Fortran::decimal {
|
||||
|
||||
template<int BINARY_PRECISION>
|
||||
template <int BINARY_PRECISION>
|
||||
struct BinaryFloatingPointNumber
|
||||
: public common::RealDetails<BINARY_PRECISION> {
|
||||
|
||||
|
@ -50,7 +50,7 @@ struct BinaryFloatingPointNumber
|
|||
constexpr BinaryFloatingPointNumber &operator=(
|
||||
BinaryFloatingPointNumber &&that) = default;
|
||||
|
||||
template<typename A> explicit constexpr BinaryFloatingPointNumber(A x) {
|
||||
template <typename A> explicit constexpr BinaryFloatingPointNumber(A x) {
|
||||
static_assert(sizeof raw <= sizeof x);
|
||||
std::memcpy(reinterpret_cast<void *>(&raw),
|
||||
reinterpret_cast<const void *>(&x), sizeof raw);
|
||||
|
@ -92,5 +92,5 @@ struct BinaryFloatingPointNumber
|
|||
|
||||
RawType raw{0};
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::decimal
|
||||
#endif
|
||||
|
|
|
@ -72,7 +72,7 @@ enum DecimalConversionFlags {
|
|||
#define EXTRA_DECIMAL_CONVERSION_SPACE (1 + 1 + 16 - 1)
|
||||
|
||||
#ifdef __cplusplus
|
||||
template<int PREC>
|
||||
template <int PREC>
|
||||
ConversionToDecimalResult ConvertToDecimal(char *, size_t,
|
||||
DecimalConversionFlags, int digits, enum FortranRounding rounding,
|
||||
BinaryFloatingPointNumber<PREC> x);
|
||||
|
@ -96,12 +96,12 @@ extern template ConversionToDecimalResult ConvertToDecimal<113>(char *, size_t,
|
|||
enum DecimalConversionFlags, int, enum FortranRounding,
|
||||
BinaryFloatingPointNumber<113>);
|
||||
|
||||
template<int PREC> struct ConversionToBinaryResult {
|
||||
template <int PREC> struct ConversionToBinaryResult {
|
||||
BinaryFloatingPointNumber<PREC> binary;
|
||||
enum ConversionResultFlags flags { Exact };
|
||||
};
|
||||
|
||||
template<int PREC>
|
||||
template <int PREC>
|
||||
ConversionToBinaryResult<PREC> ConvertToBinary(
|
||||
const char *&, enum FortranRounding = RoundNearest);
|
||||
|
||||
|
|
|
@ -33,11 +33,11 @@ class Symbol;
|
|||
namespace Fortran::evaluate {
|
||||
class Component;
|
||||
class IntrinsicProcTable;
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
namespace Fortran::evaluate::characteristics {
|
||||
struct DummyArgument;
|
||||
struct Procedure;
|
||||
}
|
||||
} // namespace Fortran::evaluate::characteristics
|
||||
|
||||
extern template class Fortran::common::Indirection<Fortran::evaluate::Component,
|
||||
true>;
|
||||
|
@ -210,7 +210,7 @@ protected:
|
|||
ActualArguments arguments_;
|
||||
};
|
||||
|
||||
template<typename A> class FunctionRef : public ProcedureRef {
|
||||
template <typename A> class FunctionRef : public ProcedureRef {
|
||||
public:
|
||||
using Result = A;
|
||||
CLASS_BOILERPLATE(FunctionRef)
|
||||
|
@ -223,5 +223,5 @@ public:
|
|||
};
|
||||
|
||||
FOR_EACH_SPECIFIC_TYPE(extern template class FunctionRef, )
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
#endif // FORTRAN_EVALUATE_CALL_H_
|
||||
|
|
|
@ -91,7 +91,7 @@ public:
|
|||
static std::optional<TypeAndShape> Characterize(
|
||||
const semantics::DeclTypeSpec &);
|
||||
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
static std::optional<TypeAndShape> Characterize(
|
||||
const A &x, FoldingContext &context) {
|
||||
if (const auto *symbol{UnwrapWholeSymbolDataRef(x)}) {
|
||||
|
@ -301,5 +301,5 @@ private:
|
|||
Procedure() {}
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Fortran::evaluate::characteristics
|
||||
#endif // FORTRAN_EVALUATE_CHARACTERISTICS_H_
|
||||
|
|
|
@ -28,7 +28,7 @@ class IntrinsicProcTable;
|
|||
// Predicate: true when an expression is a constant expression (in the
|
||||
// strict sense of the Fortran standard); it may not (yet) be a hard
|
||||
// constant value.
|
||||
template<typename A> bool IsConstantExpr(const A &);
|
||||
template <typename A> bool IsConstantExpr(const A &);
|
||||
extern template bool IsConstantExpr(const Expr<SomeType> &);
|
||||
extern template bool IsConstantExpr(const Expr<SomeInteger> &);
|
||||
extern template bool IsConstantExpr(const Expr<SubscriptInteger> &);
|
||||
|
@ -40,7 +40,7 @@ bool IsInitialDataTarget(const Expr<SomeType> &, parser::ContextualMessages &);
|
|||
// Check whether an expression is a specification expression
|
||||
// (10.1.11(2), C1010). Constant expressions are always valid
|
||||
// specification expressions.
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
void CheckSpecificationExpr(
|
||||
const A &, parser::ContextualMessages &, const semantics::Scope &);
|
||||
extern template void CheckSpecificationExpr(const Expr<SomeType> &x,
|
||||
|
@ -60,10 +60,10 @@ extern template void CheckSpecificationExpr(
|
|||
parser::ContextualMessages &, const semantics::Scope &);
|
||||
|
||||
// Simple contiguity (9.5.4)
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
bool IsSimplyContiguous(const A &, const IntrinsicProcTable &);
|
||||
extern template bool IsSimplyContiguous(
|
||||
const Expr<SomeType> &, const IntrinsicProcTable &);
|
||||
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
#endif
|
||||
|
|
|
@ -35,7 +35,8 @@ using common::RelationalOperator;
|
|||
ENUM_CLASS(Ordering, Less, Equal, Greater)
|
||||
ENUM_CLASS(Relation, Less, Equal, Greater, Unordered)
|
||||
|
||||
template<typename A> static constexpr Ordering Compare(const A &x, const A &y) {
|
||||
template <typename A>
|
||||
static constexpr Ordering Compare(const A &x, const A &y) {
|
||||
if (x < y) {
|
||||
return Ordering::Less;
|
||||
} else if (x > y) {
|
||||
|
@ -92,10 +93,14 @@ static constexpr bool Satisfies(RelationalOperator op, Ordering order) {
|
|||
|
||||
static constexpr bool Satisfies(RelationalOperator op, Relation relation) {
|
||||
switch (relation) {
|
||||
case Relation::Less: return Satisfies(op, Ordering::Less);
|
||||
case Relation::Equal: return Satisfies(op, Ordering::Equal);
|
||||
case Relation::Greater: return Satisfies(op, Ordering::Greater);
|
||||
case Relation::Unordered: return false;
|
||||
case Relation::Less:
|
||||
return Satisfies(op, Ordering::Less);
|
||||
case Relation::Equal:
|
||||
return Satisfies(op, Ordering::Equal);
|
||||
case Relation::Greater:
|
||||
return Satisfies(op, Ordering::Greater);
|
||||
case Relation::Unordered:
|
||||
return false;
|
||||
}
|
||||
return false; // silence g++ warning
|
||||
}
|
||||
|
@ -105,7 +110,7 @@ ENUM_CLASS(
|
|||
|
||||
using RealFlags = common::EnumSet<RealFlag, RealFlag_enumSize>;
|
||||
|
||||
template<typename A> struct ValueWithRealFlags {
|
||||
template <typename A> struct ValueWithRealFlags {
|
||||
A AccumulateFlags(RealFlags &f) {
|
||||
f |= flags;
|
||||
return value;
|
||||
|
@ -139,20 +144,20 @@ constexpr bool isHostLittleEndian{true};
|
|||
|
||||
// HostUnsignedInt<BITS> finds the smallest native unsigned integer type
|
||||
// whose size is >= BITS.
|
||||
template<bool LE8, bool LE16, bool LE32, bool LE64> struct SmallestUInt {};
|
||||
template<> struct SmallestUInt<true, true, true, true> {
|
||||
template <bool LE8, bool LE16, bool LE32, bool LE64> struct SmallestUInt {};
|
||||
template <> struct SmallestUInt<true, true, true, true> {
|
||||
using type = std::uint8_t;
|
||||
};
|
||||
template<> struct SmallestUInt<false, true, true, true> {
|
||||
template <> struct SmallestUInt<false, true, true, true> {
|
||||
using type = std::uint16_t;
|
||||
};
|
||||
template<> struct SmallestUInt<false, false, true, true> {
|
||||
template <> struct SmallestUInt<false, false, true, true> {
|
||||
using type = std::uint32_t;
|
||||
};
|
||||
template<> struct SmallestUInt<false, false, false, true> {
|
||||
template <> struct SmallestUInt<false, false, false, true> {
|
||||
using type = std::uint64_t;
|
||||
};
|
||||
template<int BITS>
|
||||
template <int BITS>
|
||||
using HostUnsignedInt =
|
||||
typename SmallestUInt<BITS <= 8, BITS <= 16, BITS <= 32, BITS <= 64>::type;
|
||||
|
||||
|
@ -188,8 +193,8 @@ using HostUnsignedInt =
|
|||
DEFAULT_CONSTRUCTORS_AND_ASSIGNMENTS(t)
|
||||
|
||||
#define UNION_CONSTRUCTORS(t) \
|
||||
template<typename _A> explicit t(const _A &x) : u{x} {} \
|
||||
template<typename _A, typename = common::NoLvalue<_A>> \
|
||||
template <typename _A> explicit t(const _A &x) : u{x} {} \
|
||||
template <typename _A, typename = common::NoLvalue<_A>> \
|
||||
explicit t(_A &&x) : u(std::move(x)) {}
|
||||
|
||||
#define EVALUATE_UNION_CLASS_BOILERPLATE(t) \
|
||||
|
@ -199,7 +204,7 @@ using HostUnsignedInt =
|
|||
|
||||
// Forward definition of Expr<> so that it can be indirectly used in its own
|
||||
// definition
|
||||
template<typename A> class Expr;
|
||||
template <typename A> class Expr;
|
||||
|
||||
class FoldingContext {
|
||||
public:
|
||||
|
@ -263,5 +268,5 @@ private:
|
|||
};
|
||||
|
||||
void RealFlagWarnings(FoldingContext &, const RealFlags &, const char *op);
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
#endif // FORTRAN_EVALUATE_COMMON_H_
|
||||
|
|
|
@ -19,7 +19,7 @@ class raw_ostream;
|
|||
|
||||
namespace Fortran::evaluate::value {
|
||||
|
||||
template<typename REAL_TYPE> class Complex {
|
||||
template <typename REAL_TYPE> class Complex {
|
||||
public:
|
||||
using Part = REAL_TYPE;
|
||||
static constexpr int bits{2 * Part::bits};
|
||||
|
@ -59,7 +59,7 @@ public:
|
|||
return re_.IsSignalingNaN() || im_.IsSignalingNaN();
|
||||
}
|
||||
|
||||
template<typename INT>
|
||||
template <typename INT>
|
||||
static ValueWithRealFlags<Complex> FromInteger(
|
||||
const INT &n, Rounding rounding = defaultRounding) {
|
||||
ValueWithRealFlags<Complex> result;
|
||||
|
@ -101,5 +101,5 @@ extern template class Complex<Real<Integer<32>, 24>>;
|
|||
extern template class Complex<Real<Integer<64>, 53>>;
|
||||
extern template class Complex<Real<Integer<80>, 64>>;
|
||||
extern template class Complex<Real<Integer<128>, 113>>;
|
||||
}
|
||||
} // namespace Fortran::evaluate::value
|
||||
#endif // FORTRAN_EVALUATE_COMPLEX_H_
|
||||
|
|
|
@ -37,7 +37,7 @@ using SymbolRef = common::Reference<const Symbol>;
|
|||
// constants, use a generic expression like Expr<SomeInteger> &
|
||||
// Expr<SomeType>) to wrap the appropriate instantiation of Constant<>.
|
||||
|
||||
template<typename> class Constant;
|
||||
template <typename> class Constant;
|
||||
|
||||
// When describing shapes of constants or specifying 1-based subscript
|
||||
// values as indices into constants, use a vector of integers.
|
||||
|
@ -87,7 +87,7 @@ private:
|
|||
// Constant<> is specialized for Character kinds and SomeDerived.
|
||||
// The non-Character intrinsic types, and SomeDerived, share enough
|
||||
// common behavior that they use this common base class.
|
||||
template<typename RESULT, typename ELEMENT = Scalar<RESULT>>
|
||||
template <typename RESULT, typename ELEMENT = Scalar<RESULT>>
|
||||
class ConstantBase : public ConstantBounds {
|
||||
static_assert(RESULT::category != TypeCategory::Character);
|
||||
|
||||
|
@ -95,9 +95,9 @@ public:
|
|||
using Result = RESULT;
|
||||
using Element = ELEMENT;
|
||||
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
ConstantBase(const A &x, Result res = Result{}) : result_{res}, values_{x} {}
|
||||
template<typename A, typename = common::NoLvalue<A>>
|
||||
template <typename A, typename = common::NoLvalue<A>>
|
||||
ConstantBase(A &&x, Result res = Result{})
|
||||
: result_{res}, values_{std::move(x)} {}
|
||||
ConstantBase(
|
||||
|
@ -124,7 +124,7 @@ protected:
|
|||
std::vector<Element> values_;
|
||||
};
|
||||
|
||||
template<typename T> class Constant : public ConstantBase<T> {
|
||||
template <typename T> class Constant : public ConstantBase<T> {
|
||||
public:
|
||||
using Result = T;
|
||||
using Base = ConstantBase<T>;
|
||||
|
@ -149,7 +149,7 @@ public:
|
|||
ConstantSubscripts &resultSubscripts, const std::vector<int> *dimOrder);
|
||||
};
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
class Constant<Type<TypeCategory::Character, KIND>> : public ConstantBounds {
|
||||
public:
|
||||
using Result = Type<TypeCategory::Character, KIND>;
|
||||
|
@ -199,7 +199,7 @@ class StructureConstructor;
|
|||
using StructureConstructorValues =
|
||||
std::map<SymbolRef, common::CopyableIndirection<Expr<SomeType>>>;
|
||||
|
||||
template<>
|
||||
template <>
|
||||
class Constant<SomeDerived>
|
||||
: public ConstantBase<SomeDerived, StructureConstructorValues> {
|
||||
public:
|
||||
|
@ -231,5 +231,5 @@ FOR_EACH_INTRINSIC_KIND(extern template class Constant, )
|
|||
FOR_EACH_LENGTHLESS_INTRINSIC_KIND(template class ConstantBase, ) \
|
||||
template class ConstantBase<SomeDerived, StructureConstructorValues>; \
|
||||
FOR_EACH_INTRINSIC_KIND(template class Constant, )
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
#endif // FORTRAN_EVALUATE_CONSTANT_H_
|
||||
|
|
|
@ -60,10 +60,10 @@ using common::RelationalOperator;
|
|||
// represented with an instance of some class containing a Result typedef that
|
||||
// maps to some instantiation of Type<CATEGORY, KIND>, SomeKind<CATEGORY>,
|
||||
// or SomeType. (Exception: BOZ literal constants in generic Expr<SomeType>.)
|
||||
template<typename A> using ResultType = typename std::decay_t<A>::Result;
|
||||
template <typename A> using ResultType = typename std::decay_t<A>::Result;
|
||||
|
||||
// Common Expr<> behaviors: every Expr<T> derives from ExpressionBase<T>.
|
||||
template<typename RESULT> class ExpressionBase {
|
||||
template <typename RESULT> class ExpressionBase {
|
||||
public:
|
||||
using Result = RESULT;
|
||||
|
||||
|
@ -78,13 +78,13 @@ private:
|
|||
#endif
|
||||
|
||||
public:
|
||||
template<typename A> Derived &operator=(const A &x) {
|
||||
template <typename A> Derived &operator=(const A &x) {
|
||||
Derived &d{derived()};
|
||||
d.u = x;
|
||||
return d;
|
||||
}
|
||||
|
||||
template<typename A> common::IfNoLvalue<Derived &, A> operator=(A &&x) {
|
||||
template <typename A> common::IfNoLvalue<Derived &, A> operator=(A &&x) {
|
||||
Derived &d{derived()};
|
||||
d.u = std::move(x);
|
||||
return d;
|
||||
|
@ -106,7 +106,7 @@ public:
|
|||
// struct Add : public Operation<Add, ...>. Uses of instances of Operation<>,
|
||||
// including its own member functions, can access each specific class derived
|
||||
// from it via its derived() member function with compile-time type safety.
|
||||
template<typename DERIVED, typename RESULT, typename... OPERANDS>
|
||||
template <typename DERIVED, typename RESULT, typename... OPERANDS>
|
||||
class Operation {
|
||||
// The extra final member is a dummy that allows a safe unused reference
|
||||
// to element 1 to arise indirectly in the definition of "right()" below
|
||||
|
@ -118,7 +118,7 @@ public:
|
|||
using Result = RESULT;
|
||||
static_assert(IsSpecificIntrinsicType<Result>);
|
||||
static constexpr std::size_t operands{sizeof...(OPERANDS)};
|
||||
template<int J> using Operand = std::tuple_element_t<J, OperandTypes>;
|
||||
template <int J> using Operand = std::tuple_element_t<J, OperandTypes>;
|
||||
|
||||
// Unary operations wrap a single Expr with a CopyableIndirection.
|
||||
// Binary operations wrap a tuple of CopyableIndirections to Exprs.
|
||||
|
@ -140,7 +140,7 @@ public:
|
|||
// which must be spelled like "this->template operand<0>()" when
|
||||
// inherited in a derived class template. There are convenience aliases
|
||||
// left() and right() that are not templates.
|
||||
template<int J> Expr<Operand<J>> &operand() {
|
||||
template <int J> Expr<Operand<J>> &operand() {
|
||||
if constexpr (operands == 1) {
|
||||
static_assert(J == 0);
|
||||
return operand_.value();
|
||||
|
@ -148,7 +148,7 @@ public:
|
|||
return std::get<J>(operand_).value();
|
||||
}
|
||||
}
|
||||
template<int J> const Expr<Operand<J>> &operand() const {
|
||||
template <int J> const Expr<Operand<J>> &operand() const {
|
||||
if constexpr (operands == 1) {
|
||||
static_assert(J == 0);
|
||||
return operand_.value();
|
||||
|
@ -198,7 +198,7 @@ private:
|
|||
|
||||
// Conversions to specific types from expressions of known category and
|
||||
// dynamic kind.
|
||||
template<typename TO, TypeCategory FROMCAT = TO::category>
|
||||
template <typename TO, TypeCategory FROMCAT = TO::category>
|
||||
struct Convert : public Operation<Convert<TO, FROMCAT>, TO, SomeKind<FROMCAT>> {
|
||||
// Fortran doesn't have conversions between kinds of CHARACTER apart from
|
||||
// assignments, and in those the data must be convertible to/from 7-bit ASCII.
|
||||
|
@ -218,7 +218,7 @@ struct Convert : public Operation<Convert<TO, FROMCAT>, TO, SomeKind<FROMCAT>> {
|
|||
llvm::raw_ostream &AsFortran(llvm::raw_ostream &) const;
|
||||
};
|
||||
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
struct Parentheses : public Operation<Parentheses<A>, A, A> {
|
||||
using Result = A;
|
||||
using Operand = A;
|
||||
|
@ -226,14 +226,14 @@ struct Parentheses : public Operation<Parentheses<A>, A, A> {
|
|||
using Base::Base;
|
||||
};
|
||||
|
||||
template<typename A> struct Negate : public Operation<Negate<A>, A, A> {
|
||||
template <typename A> struct Negate : public Operation<Negate<A>, A, A> {
|
||||
using Result = A;
|
||||
using Operand = A;
|
||||
using Base = Operation<Negate, A, A>;
|
||||
using Base::Base;
|
||||
};
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
struct ComplexComponent
|
||||
: public Operation<ComplexComponent<KIND>, Type<TypeCategory::Real, KIND>,
|
||||
Type<TypeCategory::Complex, KIND>> {
|
||||
|
@ -249,7 +249,7 @@ struct ComplexComponent
|
|||
bool isImaginaryPart{true};
|
||||
};
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
struct Not : public Operation<Not<KIND>, Type<TypeCategory::Logical, KIND>,
|
||||
Type<TypeCategory::Logical, KIND>> {
|
||||
using Result = Type<TypeCategory::Logical, KIND>;
|
||||
|
@ -262,7 +262,7 @@ struct Not : public Operation<Not<KIND>, Type<TypeCategory::Logical, KIND>,
|
|||
// have explicit syntax for changing them. Expressions represent
|
||||
// changes of length (e.g., for assignments and structure constructors)
|
||||
// with this operation.
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
struct SetLength
|
||||
: public Operation<SetLength<KIND>, Type<TypeCategory::Character, KIND>,
|
||||
Type<TypeCategory::Character, KIND>, SubscriptInteger> {
|
||||
|
@ -275,42 +275,42 @@ struct SetLength
|
|||
|
||||
// Binary operations
|
||||
|
||||
template<typename A> struct Add : public Operation<Add<A>, A, A, A> {
|
||||
template <typename A> struct Add : public Operation<Add<A>, A, A, A> {
|
||||
using Result = A;
|
||||
using Operand = A;
|
||||
using Base = Operation<Add, A, A, A>;
|
||||
using Base::Base;
|
||||
};
|
||||
|
||||
template<typename A> struct Subtract : public Operation<Subtract<A>, A, A, A> {
|
||||
template <typename A> struct Subtract : public Operation<Subtract<A>, A, A, A> {
|
||||
using Result = A;
|
||||
using Operand = A;
|
||||
using Base = Operation<Subtract, A, A, A>;
|
||||
using Base::Base;
|
||||
};
|
||||
|
||||
template<typename A> struct Multiply : public Operation<Multiply<A>, A, A, A> {
|
||||
template <typename A> struct Multiply : public Operation<Multiply<A>, A, A, A> {
|
||||
using Result = A;
|
||||
using Operand = A;
|
||||
using Base = Operation<Multiply, A, A, A>;
|
||||
using Base::Base;
|
||||
};
|
||||
|
||||
template<typename A> struct Divide : public Operation<Divide<A>, A, A, A> {
|
||||
template <typename A> struct Divide : public Operation<Divide<A>, A, A, A> {
|
||||
using Result = A;
|
||||
using Operand = A;
|
||||
using Base = Operation<Divide, A, A, A>;
|
||||
using Base::Base;
|
||||
};
|
||||
|
||||
template<typename A> struct Power : public Operation<Power<A>, A, A, A> {
|
||||
template <typename A> struct Power : public Operation<Power<A>, A, A, A> {
|
||||
using Result = A;
|
||||
using Operand = A;
|
||||
using Base = Operation<Power, A, A, A>;
|
||||
using Base::Base;
|
||||
};
|
||||
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
struct RealToIntPower : public Operation<RealToIntPower<A>, A, A, SomeInteger> {
|
||||
using Base = Operation<RealToIntPower, A, A, SomeInteger>;
|
||||
using Result = A;
|
||||
|
@ -319,7 +319,7 @@ struct RealToIntPower : public Operation<RealToIntPower<A>, A, A, SomeInteger> {
|
|||
using Base::Base;
|
||||
};
|
||||
|
||||
template<typename A> struct Extremum : public Operation<Extremum<A>, A, A, A> {
|
||||
template <typename A> struct Extremum : public Operation<Extremum<A>, A, A, A> {
|
||||
using Result = A;
|
||||
using Operand = A;
|
||||
using Base = Operation<Extremum, A, A, A>;
|
||||
|
@ -331,7 +331,7 @@ template<typename A> struct Extremum : public Operation<Extremum<A>, A, A, A> {
|
|||
Ordering ordering{Ordering::Greater};
|
||||
};
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
struct ComplexConstructor
|
||||
: public Operation<ComplexConstructor<KIND>,
|
||||
Type<TypeCategory::Complex, KIND>, Type<TypeCategory::Real, KIND>,
|
||||
|
@ -342,7 +342,7 @@ struct ComplexConstructor
|
|||
using Base::Base;
|
||||
};
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
struct Concat
|
||||
: public Operation<Concat<KIND>, Type<TypeCategory::Character, KIND>,
|
||||
Type<TypeCategory::Character, KIND>,
|
||||
|
@ -353,10 +353,11 @@ struct Concat
|
|||
using Base::Base;
|
||||
};
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
struct LogicalOperation
|
||||
: public Operation<LogicalOperation<KIND>, Type<TypeCategory::Logical, KIND>,
|
||||
Type<TypeCategory::Logical, KIND>, Type<TypeCategory::Logical, KIND>> {
|
||||
: public Operation<LogicalOperation<KIND>,
|
||||
Type<TypeCategory::Logical, KIND>, Type<TypeCategory::Logical, KIND>,
|
||||
Type<TypeCategory::Logical, KIND>> {
|
||||
using Result = Type<TypeCategory::Logical, KIND>;
|
||||
using Operand = Result;
|
||||
using Base = Operation<LogicalOperation, Result, Operand, Operand>;
|
||||
|
@ -370,7 +371,7 @@ struct LogicalOperation
|
|||
};
|
||||
|
||||
// Array constructors
|
||||
template<typename RESULT> class ArrayConstructorValues;
|
||||
template <typename RESULT> class ArrayConstructorValues;
|
||||
|
||||
struct ImpliedDoIndex {
|
||||
using Result = SubscriptInteger;
|
||||
|
@ -379,7 +380,7 @@ struct ImpliedDoIndex {
|
|||
parser::CharBlock name; // nested implied DOs must use distinct names
|
||||
};
|
||||
|
||||
template<typename RESULT> class ImpliedDo {
|
||||
template <typename RESULT> class ImpliedDo {
|
||||
public:
|
||||
using Result = RESULT;
|
||||
using Index = ResultType<ImpliedDoIndex>;
|
||||
|
@ -407,13 +408,13 @@ private:
|
|||
common::CopyableIndirection<ArrayConstructorValues<Result>> values_;
|
||||
};
|
||||
|
||||
template<typename RESULT> struct ArrayConstructorValue {
|
||||
template <typename RESULT> struct ArrayConstructorValue {
|
||||
using Result = RESULT;
|
||||
EVALUATE_UNION_CLASS_BOILERPLATE(ArrayConstructorValue)
|
||||
std::variant<Expr<Result>, ImpliedDo<Result>> u;
|
||||
};
|
||||
|
||||
template<typename RESULT> class ArrayConstructorValues {
|
||||
template <typename RESULT> class ArrayConstructorValues {
|
||||
public:
|
||||
using Result = RESULT;
|
||||
using Values = std::vector<ArrayConstructorValue<Result>>;
|
||||
|
@ -422,7 +423,7 @@ public:
|
|||
|
||||
bool operator==(const ArrayConstructorValues &) const;
|
||||
static constexpr int Rank() { return 1; }
|
||||
template<typename A> common::NoLvalue<A> Push(A &&x) {
|
||||
template <typename A> common::NoLvalue<A> Push(A &&x) {
|
||||
values_.emplace_back(std::move(x));
|
||||
}
|
||||
|
||||
|
@ -439,20 +440,20 @@ protected:
|
|||
// and derived types, since they must carry additional type information,
|
||||
// but that an empty ArrayConstructor can be constructed for any type
|
||||
// given an expression from which such type information may be gleaned.
|
||||
template<typename RESULT>
|
||||
template <typename RESULT>
|
||||
class ArrayConstructor : public ArrayConstructorValues<RESULT> {
|
||||
public:
|
||||
using Result = RESULT;
|
||||
using Base = ArrayConstructorValues<Result>;
|
||||
DEFAULT_CONSTRUCTORS_AND_ASSIGNMENTS(ArrayConstructor)
|
||||
explicit ArrayConstructor(Base &&values) : Base{std::move(values)} {}
|
||||
template<typename T> explicit ArrayConstructor(const Expr<T> &) {}
|
||||
template <typename T> explicit ArrayConstructor(const Expr<T> &) {}
|
||||
static constexpr Result result() { return Result{}; }
|
||||
static constexpr DynamicType GetType() { return Result::GetType(); }
|
||||
llvm::raw_ostream &AsFortran(llvm::raw_ostream &) const;
|
||||
};
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
class ArrayConstructor<Type<TypeCategory::Character, KIND>>
|
||||
: public ArrayConstructorValues<Type<TypeCategory::Character, KIND>> {
|
||||
public:
|
||||
|
@ -461,7 +462,7 @@ public:
|
|||
CLASS_BOILERPLATE(ArrayConstructor)
|
||||
ArrayConstructor(Expr<SubscriptInteger> &&len, Base &&v)
|
||||
: Base{std::move(v)}, length_{std::move(len)} {}
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
explicit ArrayConstructor(const A &prototype)
|
||||
: length_{prototype.LEN().value()} {}
|
||||
bool operator==(const ArrayConstructor &) const;
|
||||
|
@ -474,7 +475,7 @@ private:
|
|||
common::CopyableIndirection<Expr<SubscriptInteger>> length_;
|
||||
};
|
||||
|
||||
template<>
|
||||
template <>
|
||||
class ArrayConstructor<SomeDerived>
|
||||
: public ArrayConstructorValues<SomeDerived> {
|
||||
public:
|
||||
|
@ -484,7 +485,7 @@ public:
|
|||
|
||||
ArrayConstructor(const semantics::DerivedTypeSpec &spec, Base &&v)
|
||||
: Base{std::move(v)}, result_{spec} {}
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
explicit ArrayConstructor(const A &prototype)
|
||||
: result_{prototype.GetType().value().GetDerivedTypeSpec()} {}
|
||||
|
||||
|
@ -499,7 +500,7 @@ private:
|
|||
|
||||
// Expression representations for each type category.
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
class Expr<Type<TypeCategory::Integer, KIND>>
|
||||
: public ExpressionBase<Type<TypeCategory::Integer, KIND>> {
|
||||
public:
|
||||
|
@ -527,7 +528,7 @@ public:
|
|||
u;
|
||||
};
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
class Expr<Type<TypeCategory::Real, KIND>>
|
||||
: public ExpressionBase<Type<TypeCategory::Real, KIND>> {
|
||||
public:
|
||||
|
@ -552,7 +553,7 @@ public:
|
|||
common::CombineVariants<Operations, Conversions, Others> u;
|
||||
};
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
class Expr<Type<TypeCategory::Complex, KIND>>
|
||||
: public ExpressionBase<Type<TypeCategory::Complex, KIND>> {
|
||||
public:
|
||||
|
@ -576,7 +577,7 @@ FOR_EACH_INTEGER_KIND(extern template class Expr, )
|
|||
FOR_EACH_REAL_KIND(extern template class Expr, )
|
||||
FOR_EACH_COMPLEX_KIND(extern template class Expr, )
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
class Expr<Type<TypeCategory::Character, KIND>>
|
||||
: public ExpressionBase<Type<TypeCategory::Character, KIND>> {
|
||||
public:
|
||||
|
@ -603,7 +604,7 @@ FOR_EACH_CHARACTER_KIND(extern template class Expr, )
|
|||
// addition operator. Character relations must have the same kind.
|
||||
// There are no relations between LOGICAL values.
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
struct Relational : public Operation<Relational<T>, LogicalResult, T, T> {
|
||||
using Result = LogicalResult;
|
||||
using Base = Operation<Relational, LogicalResult, T, T>;
|
||||
|
@ -620,7 +621,7 @@ struct Relational : public Operation<Relational<T>, LogicalResult, T, T> {
|
|||
RelationalOperator opr;
|
||||
};
|
||||
|
||||
template<> class Relational<SomeType> {
|
||||
template <> class Relational<SomeType> {
|
||||
// COMPLEX data are compared piecewise.
|
||||
using DirectlyComparableTypes =
|
||||
common::CombineTuples<IntegerTypes, RealTypes, CharacterTypes>;
|
||||
|
@ -645,7 +646,7 @@ extern template struct Relational<SomeType>;
|
|||
// do not include Relational<> operations as possibilities,
|
||||
// since the results of Relationals are always LogicalResult
|
||||
// (kind=1).
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
class Expr<Type<TypeCategory::Logical, KIND>>
|
||||
: public ExpressionBase<Type<TypeCategory::Logical, KIND>> {
|
||||
public:
|
||||
|
@ -726,7 +727,7 @@ private:
|
|||
};
|
||||
|
||||
// An expression whose result has a derived type.
|
||||
template<> class Expr<SomeDerived> : public ExpressionBase<SomeDerived> {
|
||||
template <> class Expr<SomeDerived> : public ExpressionBase<SomeDerived> {
|
||||
public:
|
||||
using Result = SomeDerived;
|
||||
EVALUATE_UNION_CLASS_BOILERPLATE(Expr)
|
||||
|
@ -738,7 +739,7 @@ public:
|
|||
// A polymorphic expression of known intrinsic type category, but dynamic
|
||||
// kind, represented as a discriminated union over Expr<Type<CAT, K>>
|
||||
// for each supported kind K in the category.
|
||||
template<TypeCategory CAT>
|
||||
template <TypeCategory CAT>
|
||||
class Expr<SomeKind<CAT>> : public ExpressionBase<SomeKind<CAT>> {
|
||||
public:
|
||||
using Result = SomeKind<CAT>;
|
||||
|
@ -747,7 +748,7 @@ public:
|
|||
common::MapTemplate<Expr, CategoryTypes<CAT>> u;
|
||||
};
|
||||
|
||||
template<> class Expr<SomeCharacter> : public ExpressionBase<SomeCharacter> {
|
||||
template <> class Expr<SomeCharacter> : public ExpressionBase<SomeCharacter> {
|
||||
public:
|
||||
using Result = SomeCharacter;
|
||||
EVALUATE_UNION_CLASS_BOILERPLATE(Expr)
|
||||
|
@ -780,7 +781,7 @@ using TypelessExpression = std::variant<BOZLiteralConstant, NullPointer,
|
|||
|
||||
// A completely generic expression, polymorphic across all of the intrinsic type
|
||||
// categories and each of their kinds.
|
||||
template<> class Expr<SomeType> : public ExpressionBase<SomeType> {
|
||||
template <> class Expr<SomeType> : public ExpressionBase<SomeType> {
|
||||
public:
|
||||
using Result = SomeType;
|
||||
EVALUATE_UNION_CLASS_BOILERPLATE(Expr)
|
||||
|
@ -790,20 +791,20 @@ public:
|
|||
// its destructor is externalized to reduce redundant default instances.
|
||||
~Expr();
|
||||
|
||||
template<TypeCategory CAT, int KIND>
|
||||
template <TypeCategory CAT, int KIND>
|
||||
explicit Expr(const Expr<Type<CAT, KIND>> &x) : u{Expr<SomeKind<CAT>>{x}} {}
|
||||
|
||||
template<TypeCategory CAT, int KIND>
|
||||
template <TypeCategory CAT, int KIND>
|
||||
explicit Expr(Expr<Type<CAT, KIND>> &&x)
|
||||
: u{Expr<SomeKind<CAT>>{std::move(x)}} {}
|
||||
|
||||
template<TypeCategory CAT, int KIND>
|
||||
template <TypeCategory CAT, int KIND>
|
||||
Expr &operator=(const Expr<Type<CAT, KIND>> &x) {
|
||||
u = Expr<SomeKind<CAT>>{x};
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<TypeCategory CAT, int KIND>
|
||||
template <TypeCategory CAT, int KIND>
|
||||
Expr &operator=(Expr<Type<CAT, KIND>> &&x) {
|
||||
u = Expr<SomeKind<CAT>>{std::move(x)};
|
||||
return *this;
|
||||
|
@ -867,5 +868,5 @@ FOR_EACH_INTRINSIC_KIND(extern template class ArrayConstructor, )
|
|||
FOR_EACH_TYPE_AND_KIND(template class ExpressionBase, ) \
|
||||
FOR_EACH_INTRINSIC_KIND(template class ArrayConstructorValues, ) \
|
||||
FOR_EACH_INTRINSIC_KIND(template class ArrayConstructor, )
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
#endif // FORTRAN_EVALUATE_EXPRESSION_H_
|
||||
|
|
|
@ -28,11 +28,11 @@ using namespace Fortran::parser::literals;
|
|||
// be able to extract it.
|
||||
// Note the rvalue reference argument: the rewrites are performed in place
|
||||
// for efficiency.
|
||||
template<typename T> Expr<T> Fold(FoldingContext &context, Expr<T> &&expr) {
|
||||
template <typename T> Expr<T> Fold(FoldingContext &context, Expr<T> &&expr) {
|
||||
return Expr<T>::Rewrite(context, std::move(expr));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
std::optional<Expr<T>> Fold(
|
||||
FoldingContext &context, std::optional<Expr<T>> &&expr) {
|
||||
if (expr) {
|
||||
|
@ -46,7 +46,7 @@ std::optional<Expr<T>> Fold(
|
|||
// an expression, if it has one. It returns a pointer, which is
|
||||
// const-qualified when the expression is so. The value can be
|
||||
// parenthesized.
|
||||
template<typename T, typename EXPR>
|
||||
template <typename T, typename EXPR>
|
||||
auto UnwrapConstantValue(EXPR &expr) -> common::Constify<Constant<T>, EXPR> * {
|
||||
if (auto *c{UnwrapExpr<Constant<T>>(expr)}) {
|
||||
return c;
|
||||
|
@ -62,7 +62,7 @@ auto UnwrapConstantValue(EXPR &expr) -> common::Constify<Constant<T>, EXPR> * {
|
|||
|
||||
// GetScalarConstantValue() extracts the known scalar constant value of
|
||||
// an expression, if it has one. The value can be parenthesized.
|
||||
template<typename T, typename EXPR>
|
||||
template <typename T, typename EXPR>
|
||||
auto GetScalarConstantValue(const EXPR &expr) -> std::optional<Scalar<T>> {
|
||||
if (const Constant<T> *constant{UnwrapConstantValue<T>(expr)}) {
|
||||
return constant->GetScalarValue();
|
||||
|
@ -74,7 +74,7 @@ auto GetScalarConstantValue(const EXPR &expr) -> std::optional<Scalar<T>> {
|
|||
// When an expression is a constant integer, ToInt64() extracts its value.
|
||||
// Ensure that the expression has been folded beforehand when folding might
|
||||
// be required.
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
std::optional<std::int64_t> ToInt64(
|
||||
const Expr<Type<TypeCategory::Integer, KIND>> &expr) {
|
||||
if (auto scalar{
|
||||
|
@ -88,7 +88,7 @@ std::optional<std::int64_t> ToInt64(
|
|||
std::optional<std::int64_t> ToInt64(const Expr<SomeInteger> &);
|
||||
std::optional<std::int64_t> ToInt64(const Expr<SomeType> &);
|
||||
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
std::optional<std::int64_t> ToInt64(const std::optional<A> &x) {
|
||||
if (x) {
|
||||
return ToInt64(*x);
|
||||
|
@ -96,5 +96,5 @@ std::optional<std::int64_t> ToInt64(const std::optional<A> &x) {
|
|||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
#endif // FORTRAN_EVALUATE_FOLD_H_
|
||||
|
|
|
@ -26,24 +26,25 @@
|
|||
|
||||
namespace Fortran::evaluate {
|
||||
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
auto operator<<(llvm::raw_ostream &o, const A &x) -> decltype(x.AsFortran(o)) {
|
||||
return x.AsFortran(o);
|
||||
}
|
||||
|
||||
template<typename A>
|
||||
auto operator<<(llvm::raw_ostream &o, const A &x) -> decltype(o << x.AsFortran()) {
|
||||
template <typename A>
|
||||
auto operator<<(llvm::raw_ostream &o, const A &x)
|
||||
-> decltype(o << x.AsFortran()) {
|
||||
return o << x.AsFortran();
|
||||
}
|
||||
|
||||
template<typename A, bool COPYABLE>
|
||||
template <typename A, bool COPYABLE>
|
||||
auto operator<<(
|
||||
llvm::raw_ostream &o, const Fortran::common::Indirection<A, COPYABLE> &x)
|
||||
-> decltype(o << x.value()) {
|
||||
return o << x.value();
|
||||
}
|
||||
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
auto operator<<(llvm::raw_ostream &o, const std::optional<A> &x)
|
||||
-> decltype(o << *x) {
|
||||
if (x) {
|
||||
|
@ -53,5 +54,5 @@ auto operator<<(llvm::raw_ostream &o, const std::optional<A> &x)
|
|||
}
|
||||
return o;
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
#endif // FORTRAN_EVALUATE_FORMATTING_H_
|
||||
|
|
|
@ -28,17 +28,17 @@ class FoldingContext;
|
|||
|
||||
using TypeCode = unsigned char;
|
||||
|
||||
template<typename TR, typename... TA> using FuncPointer = TR (*)(TA...);
|
||||
template <typename TR, typename... TA> using FuncPointer = TR (*)(TA...);
|
||||
// This specific type signature prevents GCC complaining about function casts.
|
||||
using GenericFunctionPointer = void (*)(void);
|
||||
|
||||
enum class PassBy { Ref, Val };
|
||||
template<typename TA, PassBy Pass = PassBy::Ref> struct ArgumentInfo {
|
||||
template <typename TA, PassBy Pass = PassBy::Ref> struct ArgumentInfo {
|
||||
using Type = TA;
|
||||
static constexpr PassBy pass{Pass};
|
||||
};
|
||||
|
||||
template<typename TR, typename... ArgInfo> struct Signature {
|
||||
template <typename TR, typename... ArgInfo> struct Signature {
|
||||
// Note valid template argument are of form
|
||||
//<TR, ArgumentInfo<TA, PassBy>...> where TA and TR belong to RuntimeTypes.
|
||||
// RuntimeTypes is a type union defined in intrinsics-library-templates.h to
|
||||
|
@ -55,7 +55,7 @@ struct IntrinsicProcedureRuntimeDescription {
|
|||
const bool isElemental;
|
||||
const GenericFunctionPointer callable;
|
||||
// Construct from description using host independent types (RuntimeTypes)
|
||||
template<typename TR, typename... ArgInfo>
|
||||
template <typename TR, typename... ArgInfo>
|
||||
IntrinsicProcedureRuntimeDescription(
|
||||
const Signature<TR, ArgInfo...> &signature, bool isElemental = false);
|
||||
};
|
||||
|
@ -64,7 +64,7 @@ struct IntrinsicProcedureRuntimeDescription {
|
|||
// constant folding.
|
||||
struct HostRuntimeIntrinsicProcedure : IntrinsicProcedureRuntimeDescription {
|
||||
// Construct from runtime pointer with host types (float, double....)
|
||||
template<typename HostTR, typename... HostTA>
|
||||
template <typename HostTR, typename... HostTA>
|
||||
HostRuntimeIntrinsicProcedure(const std::string &name,
|
||||
FuncPointer<HostTR, HostTA...> func, bool isElemental = false);
|
||||
HostRuntimeIntrinsicProcedure(
|
||||
|
@ -76,7 +76,7 @@ struct HostRuntimeIntrinsicProcedure : IntrinsicProcedureRuntimeDescription {
|
|||
|
||||
// Defines a wrapper type that indirects calls to host runtime functions.
|
||||
// Valid ConstantContainer are Scalar (only for elementals) and Constant.
|
||||
template<template<typename> typename ConstantContainer, typename TR,
|
||||
template <template <typename> typename ConstantContainer, typename TR,
|
||||
typename... TA>
|
||||
using HostProcedureWrapper = std::function<ConstantContainer<TR>(
|
||||
FoldingContext &, ConstantContainer<TA>...)>;
|
||||
|
@ -95,7 +95,7 @@ public:
|
|||
}
|
||||
bool HasEquivalentProcedure(
|
||||
const IntrinsicProcedureRuntimeDescription &sym) const;
|
||||
template<template<typename> typename ConstantContainer, typename TR,
|
||||
template <template <typename> typename ConstantContainer, typename TR,
|
||||
typename... TA>
|
||||
std::optional<HostProcedureWrapper<ConstantContainer, TR, TA...>>
|
||||
GetHostProcedureWrapper(const std::string &name) const;
|
||||
|
@ -104,5 +104,5 @@ private:
|
|||
std::multimap<std::string, const HostRuntimeIntrinsicProcedure> procedures_;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
#endif // FORTRAN_EVALUATE_INTRINSICS_LIBRARY_H_
|
||||
|
|
|
@ -84,5 +84,5 @@ public:
|
|||
private:
|
||||
Implementation *impl_{nullptr}; // owning pointer
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
#endif // FORTRAN_EVALUATE_INTRINSICS_H_
|
||||
|
|
|
@ -35,7 +35,7 @@ static constexpr std::int64_t ScaledLogBaseTenOfTwo{301029995664};
|
|||
// class template must be (or look like) an instance of Integer<>;
|
||||
// the second specifies the number of effective bits (binary precision)
|
||||
// in the fraction.
|
||||
template<typename WORD, int PREC>
|
||||
template <typename WORD, int PREC>
|
||||
class Real : public common::RealDetails<PREC> {
|
||||
public:
|
||||
using Word = WORD;
|
||||
|
@ -51,7 +51,7 @@ public:
|
|||
static_assert(bits >= Details::bits);
|
||||
using Fraction = Integer<binaryPrecision>; // all bits made explicit
|
||||
|
||||
template<typename W, int P> friend class Real;
|
||||
template <typename W, int P> friend class Real;
|
||||
|
||||
constexpr Real() {} // +0.0
|
||||
constexpr Real(const Real &) = default;
|
||||
|
@ -122,7 +122,7 @@ public:
|
|||
ValueWithRealFlags<Real> HYPOT(
|
||||
const Real &, Rounding rounding = defaultRounding) const;
|
||||
|
||||
template<typename INT> constexpr INT EXPONENT() const {
|
||||
template <typename INT> constexpr INT EXPONENT() const {
|
||||
if (Exponent() == maxExponent) {
|
||||
return INT::HUGE();
|
||||
} else {
|
||||
|
@ -177,7 +177,7 @@ public:
|
|||
return {infinity};
|
||||
}
|
||||
|
||||
template<typename INT>
|
||||
template <typename INT>
|
||||
static ValueWithRealFlags<Real> FromInteger(
|
||||
const INT &n, Rounding rounding = defaultRounding) {
|
||||
bool isNegative{n.IsNegative()};
|
||||
|
@ -211,7 +211,7 @@ public:
|
|||
common::RoundingMode = common::RoundingMode::ToZero) const;
|
||||
|
||||
// Conversion to an integer (INT(), NINT(), FLOOR(), CEILING())
|
||||
template<typename INT>
|
||||
template <typename INT>
|
||||
constexpr ValueWithRealFlags<INT> ToInteger(
|
||||
common::RoundingMode mode = common::RoundingMode::ToZero) const {
|
||||
ValueWithRealFlags<INT> result;
|
||||
|
@ -244,7 +244,7 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
static ValueWithRealFlags<Real> Convert(
|
||||
const A &x, Rounding rounding = defaultRounding) {
|
||||
bool isNegative{x.IsNegative()};
|
||||
|
@ -312,7 +312,8 @@ public:
|
|||
|
||||
// Emits a character representation for an equivalent Fortran constant
|
||||
// or parenthesized constant expression that produces this value.
|
||||
llvm::raw_ostream &AsFortran(llvm::raw_ostream &, int kind, bool minimal = false) const;
|
||||
llvm::raw_ostream &AsFortran(
|
||||
llvm::raw_ostream &, int kind, bool minimal = false) const;
|
||||
|
||||
private:
|
||||
using Significand = Integer<significandBits>; // no implicit bit
|
||||
|
@ -371,5 +372,5 @@ extern template class Real<Integer<64>, 53>; // IEEE double
|
|||
extern template class Real<Integer<80>, 64>; // 80387 extended precision
|
||||
extern template class Real<Integer<128>, 113>; // IEEE quad
|
||||
// N.B. No "double-double" support.
|
||||
}
|
||||
} // namespace Fortran::evaluate::value
|
||||
#endif // FORTRAN_EVALUATE_REAL_H_
|
||||
|
|
|
@ -21,7 +21,7 @@ public:
|
|||
bool guard = false, bool round = false, bool sticky = false)
|
||||
: guard_{guard}, round_{round}, sticky_{sticky} {}
|
||||
|
||||
template<typename FRACTION>
|
||||
template <typename FRACTION>
|
||||
constexpr RoundingBits(const FRACTION &fraction, int rshift) {
|
||||
if (rshift > 0 && rshift < fraction.bits + 1) {
|
||||
guard_ = fraction.BTEST(rshift - 1);
|
||||
|
@ -81,10 +81,17 @@ public:
|
|||
case common::RoundingMode::TiesToEven:
|
||||
round = guard_ && (round_ | sticky_ | isOdd);
|
||||
break;
|
||||
case common::RoundingMode::ToZero: break;
|
||||
case common::RoundingMode::Down: round = isNegative && !empty(); break;
|
||||
case common::RoundingMode::Up: round = !isNegative && !empty(); break;
|
||||
case common::RoundingMode::TiesAwayFromZero: round = guard_; break;
|
||||
case common::RoundingMode::ToZero:
|
||||
break;
|
||||
case common::RoundingMode::Down:
|
||||
round = isNegative && !empty();
|
||||
break;
|
||||
case common::RoundingMode::Up:
|
||||
round = !isNegative && !empty();
|
||||
break;
|
||||
case common::RoundingMode::TiesAwayFromZero:
|
||||
round = guard_;
|
||||
break;
|
||||
}
|
||||
return round;
|
||||
}
|
||||
|
@ -94,5 +101,5 @@ private:
|
|||
bool round_{false}; // 0.25 * ulp
|
||||
bool sticky_{false}; // true if any lesser-valued bit would be set
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::evaluate::value
|
||||
#endif // FORTRAN_EVALUATE_ROUNDING_BITS_H_
|
||||
|
|
|
@ -53,7 +53,8 @@ std::optional<ConstantSubscripts> AsConstantExtents(
|
|||
|
||||
inline int GetRank(const Shape &s) { return static_cast<int>(s.size()); }
|
||||
|
||||
template<typename A> std::optional<Shape> GetShape(FoldingContext &, const A &);
|
||||
template <typename A>
|
||||
std::optional<Shape> GetShape(FoldingContext &, const A &);
|
||||
|
||||
// The dimension argument to these inquiries is zero-based,
|
||||
// unlike the DIM= arguments to many intrinsics.
|
||||
|
@ -92,7 +93,7 @@ public:
|
|||
|
||||
Result operator()(const ImpliedDoIndex &) const { return Scalar(); }
|
||||
Result operator()(const DescriptorInquiry &) const { return Scalar(); }
|
||||
template<int KIND> Result operator()(const TypeParamInquiry<KIND> &) const {
|
||||
template <int KIND> Result operator()(const TypeParamInquiry<KIND> &) const {
|
||||
return Scalar();
|
||||
}
|
||||
Result operator()(const BOZLiteralConstant &) const { return Scalar(); }
|
||||
|
@ -101,7 +102,7 @@ public:
|
|||
}
|
||||
Result operator()(const StructureConstructor &) const { return Scalar(); }
|
||||
|
||||
template<typename T> Result operator()(const Constant<T> &c) const {
|
||||
template <typename T> Result operator()(const Constant<T> &c) const {
|
||||
return AsShape(c.SHAPE());
|
||||
}
|
||||
|
||||
|
@ -112,11 +113,11 @@ public:
|
|||
Result operator()(const Substring &) const;
|
||||
Result operator()(const ProcedureRef &) const;
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Result operator()(const ArrayConstructor<T> &aconst) const {
|
||||
return Shape{GetArrayConstructorExtent(aconst)};
|
||||
}
|
||||
template<typename D, typename R, typename LO, typename RO>
|
||||
template <typename D, typename R, typename LO, typename RO>
|
||||
Result operator()(const Operation<D, R, LO, RO> &operation) const {
|
||||
if (operation.right().Rank() > 0) {
|
||||
return (*this)(operation.right());
|
||||
|
@ -128,7 +129,7 @@ public:
|
|||
private:
|
||||
static Result Scalar() { return Shape{}; }
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
MaybeExtentExpr GetArrayConstructorValueExtent(
|
||||
const ArrayConstructorValue<T> &value) const {
|
||||
return std::visit(
|
||||
|
@ -159,7 +160,7 @@ private:
|
|||
value.u);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
MaybeExtentExpr GetArrayConstructorExtent(
|
||||
const ArrayConstructorValues<T> &values) const {
|
||||
ExtentExpr result{0};
|
||||
|
@ -176,7 +177,7 @@ private:
|
|||
FoldingContext &context_;
|
||||
};
|
||||
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
std::optional<Shape> GetShape(FoldingContext &context, const A &x) {
|
||||
return GetShapeHelper{context}(x);
|
||||
}
|
||||
|
@ -187,5 +188,5 @@ bool CheckConformance(parser::ContextualMessages &, const Shape &left,
|
|||
const Shape &right, const char *leftIs = "left operand",
|
||||
const char *rightIs = "right operand");
|
||||
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
#endif // FORTRAN_EVALUATE_SHAPE_H_
|
||||
|
|
|
@ -78,5 +78,5 @@ private:
|
|||
int itemBytes_{1};
|
||||
std::vector<std::uint8_t> data_;
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
#endif // FORTRAN_EVALUATE_STATIC_DATA_H_
|
||||
|
|
|
@ -41,42 +41,43 @@
|
|||
#include <type_traits>
|
||||
|
||||
namespace Fortran::evaluate {
|
||||
template<typename Visitor, typename Result> class Traverse {
|
||||
template <typename Visitor, typename Result> class Traverse {
|
||||
public:
|
||||
explicit Traverse(Visitor &v) : visitor_{v} {}
|
||||
|
||||
// Packaging
|
||||
template<typename A, bool C>
|
||||
template <typename A, bool C>
|
||||
Result operator()(const common::Indirection<A, C> &x) const {
|
||||
return visitor_(x.value());
|
||||
}
|
||||
template<typename A> Result operator()(SymbolRef x) const {
|
||||
template <typename A> Result operator()(SymbolRef x) const {
|
||||
return visitor_(*x);
|
||||
}
|
||||
template<typename A> Result operator()(const std::unique_ptr<A> &x) const {
|
||||
template <typename A> Result operator()(const std::unique_ptr<A> &x) const {
|
||||
return visitor_(x.get());
|
||||
}
|
||||
template<typename A> Result operator()(const std::shared_ptr<A> &x) const {
|
||||
template <typename A> Result operator()(const std::shared_ptr<A> &x) const {
|
||||
return visitor_(x.get());
|
||||
}
|
||||
template<typename A> Result operator()(const A *x) const {
|
||||
template <typename A> Result operator()(const A *x) const {
|
||||
if (x) {
|
||||
return visitor_(*x);
|
||||
} else {
|
||||
return visitor_.Default();
|
||||
}
|
||||
}
|
||||
template<typename A> Result operator()(const std::optional<A> &x) const {
|
||||
template <typename A> Result operator()(const std::optional<A> &x) const {
|
||||
if (x) {
|
||||
return visitor_(*x);
|
||||
} else {
|
||||
return visitor_.Default();
|
||||
}
|
||||
}
|
||||
template<typename... A> Result operator()(const std::variant<A...> &u) const {
|
||||
template <typename... A>
|
||||
Result operator()(const std::variant<A...> &u) const {
|
||||
return std::visit(visitor_, u);
|
||||
}
|
||||
template<typename A> Result operator()(const std::vector<A> &x) const {
|
||||
template <typename A> Result operator()(const std::vector<A> &x) const {
|
||||
return CombineContents(x);
|
||||
}
|
||||
|
||||
|
@ -85,7 +86,7 @@ public:
|
|||
return visitor_.Default();
|
||||
}
|
||||
Result operator()(const NullPointer &) const { return visitor_.Default(); }
|
||||
template<typename T> Result operator()(const Constant<T> &x) const {
|
||||
template <typename T> Result operator()(const Constant<T> &x) const {
|
||||
if constexpr (T::category == TypeCategory::Derived) {
|
||||
std::optional<Result> result;
|
||||
for (const StructureConstructorValues &map : x.values()) {
|
||||
|
@ -119,7 +120,7 @@ public:
|
|||
return visitor_(x.GetFirstSymbol());
|
||||
}
|
||||
}
|
||||
template<int KIND> Result operator()(const TypeParamInquiry<KIND> &x) const {
|
||||
template <int KIND> Result operator()(const TypeParamInquiry<KIND> &x) const {
|
||||
return visitor_(x.base());
|
||||
}
|
||||
Result operator()(const Triplet &x) const {
|
||||
|
@ -140,10 +141,10 @@ public:
|
|||
Result operator()(const ComplexPart &x) const {
|
||||
return visitor_(x.complex());
|
||||
}
|
||||
template<typename T> Result operator()(const Designator<T> &x) const {
|
||||
template <typename T> Result operator()(const Designator<T> &x) const {
|
||||
return visitor_(x.u);
|
||||
}
|
||||
template<typename T> Result operator()(const Variable<T> &x) const {
|
||||
template <typename T> Result operator()(const Variable<T> &x) const {
|
||||
return visitor_(x.u);
|
||||
}
|
||||
Result operator()(const DescriptorInquiry &x) const {
|
||||
|
@ -173,20 +174,20 @@ public:
|
|||
Result operator()(const ProcedureRef &x) const {
|
||||
return Combine(x.proc(), x.arguments());
|
||||
}
|
||||
template<typename T> Result operator()(const FunctionRef<T> &x) const {
|
||||
template <typename T> Result operator()(const FunctionRef<T> &x) const {
|
||||
return visitor_(static_cast<const ProcedureRef &>(x));
|
||||
}
|
||||
|
||||
// Other primaries
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Result operator()(const ArrayConstructorValue<T> &x) const {
|
||||
return visitor_(x.u);
|
||||
}
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Result operator()(const ArrayConstructorValues<T> &x) const {
|
||||
return CombineContents(x);
|
||||
}
|
||||
template<typename T> Result operator()(const ImpliedDo<T> &x) const {
|
||||
template <typename T> Result operator()(const ImpliedDo<T> &x) const {
|
||||
return Combine(x.lower(), x.upper(), x.stride(), x.values());
|
||||
}
|
||||
Result operator()(const semantics::ParamValue &x) const {
|
||||
|
@ -207,23 +208,23 @@ public:
|
|||
}
|
||||
|
||||
// Operations and wrappers
|
||||
template<typename D, typename R, typename O>
|
||||
template <typename D, typename R, typename O>
|
||||
Result operator()(const Operation<D, R, O> &op) const {
|
||||
return visitor_(op.left());
|
||||
}
|
||||
template<typename D, typename R, typename LO, typename RO>
|
||||
template <typename D, typename R, typename LO, typename RO>
|
||||
Result operator()(const Operation<D, R, LO, RO> &op) const {
|
||||
return Combine(op.left(), op.right());
|
||||
}
|
||||
Result operator()(const Relational<SomeType> &x) const {
|
||||
return visitor_(x.u);
|
||||
}
|
||||
template<typename T> Result operator()(const Expr<T> &x) const {
|
||||
template <typename T> Result operator()(const Expr<T> &x) const {
|
||||
return visitor_(x.u);
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename ITER> Result CombineRange(ITER iter, ITER end) const {
|
||||
template <typename ITER> Result CombineRange(ITER iter, ITER end) const {
|
||||
if (iter == end) {
|
||||
return visitor_.Default();
|
||||
} else {
|
||||
|
@ -235,11 +236,11 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
template<typename A> Result CombineContents(const A &x) const {
|
||||
template <typename A> Result CombineContents(const A &x) const {
|
||||
return CombineRange(x.begin(), x.end());
|
||||
}
|
||||
|
||||
template<typename A, typename... Bs>
|
||||
template <typename A, typename... Bs>
|
||||
Result Combine(const A &x, const Bs &... ys) const {
|
||||
if constexpr (sizeof...(Bs) == 0) {
|
||||
return visitor_(x);
|
||||
|
@ -253,7 +254,7 @@ private:
|
|||
|
||||
// For validity checks across an expression: if any operator() result is
|
||||
// false, so is the overall result.
|
||||
template<typename Visitor, bool DefaultValue,
|
||||
template <typename Visitor, bool DefaultValue,
|
||||
typename Base = Traverse<Visitor, bool>>
|
||||
struct AllTraverse : public Base {
|
||||
AllTraverse(Visitor &v) : Base{v} {}
|
||||
|
@ -265,7 +266,7 @@ struct AllTraverse : public Base {
|
|||
// For searches over an expression: the first operator() result that
|
||||
// is truthful is the final result. Works for Booleans, pointers,
|
||||
// and std::optional<>.
|
||||
template<typename Visitor, typename Result = bool,
|
||||
template <typename Visitor, typename Result = bool,
|
||||
typename Base = Traverse<Visitor, Result>>
|
||||
struct AnyTraverse : public Base {
|
||||
AnyTraverse(Visitor &v) : Base{v} {}
|
||||
|
@ -280,7 +281,8 @@ struct AnyTraverse : public Base {
|
|||
}
|
||||
};
|
||||
|
||||
template<typename Visitor, typename Set, typename Base = Traverse<Visitor, Set>>
|
||||
template <typename Visitor, typename Set,
|
||||
typename Base = Traverse<Visitor, Set>>
|
||||
struct SetTraverse : public Base {
|
||||
SetTraverse(Visitor &v) : Base{v} {}
|
||||
using Base::operator();
|
||||
|
@ -298,5 +300,5 @@ struct SetTraverse : public Base {
|
|||
}
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
#endif
|
||||
|
|
|
@ -37,7 +37,7 @@ class DerivedTypeSpec;
|
|||
class ParamValue;
|
||||
class Symbol;
|
||||
bool IsDescriptor(const Symbol &);
|
||||
}
|
||||
} // namespace Fortran::semantics
|
||||
|
||||
namespace Fortran::evaluate {
|
||||
|
||||
|
@ -45,7 +45,7 @@ using common::TypeCategory;
|
|||
|
||||
// Specific intrinsic types are represented by specializations of
|
||||
// this class template Type<CATEGORY, KIND>.
|
||||
template<TypeCategory CATEGORY, int KIND = 0> class Type;
|
||||
template <TypeCategory CATEGORY, int KIND = 0> class Type;
|
||||
|
||||
using SubscriptInteger = Type<TypeCategory::Integer, 8>;
|
||||
using CInteger = Type<TypeCategory::Integer, 4>;
|
||||
|
@ -65,10 +65,12 @@ static constexpr bool IsValidKindOfIntrinsicType(
|
|||
case TypeCategory::Complex:
|
||||
return kind == 2 || kind == 3 || kind == 4 || kind == 8 || kind == 10 ||
|
||||
kind == 16;
|
||||
case TypeCategory::Character: return kind == 1 || kind == 2 || kind == 4;
|
||||
case TypeCategory::Character:
|
||||
return kind == 1 || kind == 2 || kind == 4;
|
||||
case TypeCategory::Logical:
|
||||
return kind == 1 || kind == 2 || kind == 4 || kind == 8;
|
||||
default: return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,17 +176,17 @@ public:
|
|||
static std::optional<DynamicType> From(const semantics::DeclTypeSpec &);
|
||||
static std::optional<DynamicType> From(const semantics::Symbol &);
|
||||
|
||||
template<typename A> static std::optional<DynamicType> From(const A &x) {
|
||||
template <typename A> static std::optional<DynamicType> From(const A &x) {
|
||||
return x.GetType();
|
||||
}
|
||||
template<typename A> static std::optional<DynamicType> From(const A *p) {
|
||||
template <typename A> static std::optional<DynamicType> From(const A *p) {
|
||||
if (!p) {
|
||||
return std::nullopt;
|
||||
} else {
|
||||
return From(*p);
|
||||
}
|
||||
}
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
static std::optional<DynamicType> From(const std::optional<A> &x) {
|
||||
if (x) {
|
||||
return From(*x);
|
||||
|
@ -216,7 +218,7 @@ const semantics::DerivedTypeSpec *GetDerivedTypeSpec(
|
|||
|
||||
std::string DerivedTypeSpecAsFortran(const semantics::DerivedTypeSpec &);
|
||||
|
||||
template<TypeCategory CATEGORY, int KIND = 0> struct TypeBase {
|
||||
template <TypeCategory CATEGORY, int KIND = 0> struct TypeBase {
|
||||
static constexpr TypeCategory category{CATEGORY};
|
||||
static constexpr int kind{KIND};
|
||||
constexpr bool operator==(const TypeBase &) const { return true; }
|
||||
|
@ -224,7 +226,7 @@ template<TypeCategory CATEGORY, int KIND = 0> struct TypeBase {
|
|||
static std::string AsFortran() { return GetType().AsFortran(); }
|
||||
};
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
class Type<TypeCategory::Integer, KIND>
|
||||
: public TypeBase<TypeCategory::Integer, KIND> {
|
||||
public:
|
||||
|
@ -232,7 +234,7 @@ public:
|
|||
};
|
||||
|
||||
// REAL(KIND=2) is IEEE half-precision (16 bits)
|
||||
template<>
|
||||
template <>
|
||||
class Type<TypeCategory::Real, 2> : public TypeBase<TypeCategory::Real, 2> {
|
||||
public:
|
||||
using Scalar =
|
||||
|
@ -241,7 +243,7 @@ public:
|
|||
|
||||
// REAL(KIND=3) identifies the "other" half-precision format, which is
|
||||
// basically REAL(4) without its least-order 16 fraction bits.
|
||||
template<>
|
||||
template <>
|
||||
class Type<TypeCategory::Real, 3> : public TypeBase<TypeCategory::Real, 3> {
|
||||
public:
|
||||
using Scalar =
|
||||
|
@ -249,7 +251,7 @@ public:
|
|||
};
|
||||
|
||||
// REAL(KIND=4) is IEEE-754 single precision (32 bits)
|
||||
template<>
|
||||
template <>
|
||||
class Type<TypeCategory::Real, 4> : public TypeBase<TypeCategory::Real, 4> {
|
||||
public:
|
||||
using Scalar =
|
||||
|
@ -257,7 +259,7 @@ public:
|
|||
};
|
||||
|
||||
// REAL(KIND=8) is IEEE double precision (64 bits)
|
||||
template<>
|
||||
template <>
|
||||
class Type<TypeCategory::Real, 8> : public TypeBase<TypeCategory::Real, 8> {
|
||||
public:
|
||||
using Scalar =
|
||||
|
@ -265,21 +267,21 @@ public:
|
|||
};
|
||||
|
||||
// REAL(KIND=10) is x87 FPU extended precision (80 bits, all explicit)
|
||||
template<>
|
||||
template <>
|
||||
class Type<TypeCategory::Real, 10> : public TypeBase<TypeCategory::Real, 10> {
|
||||
public:
|
||||
using Scalar = value::Real<value::Integer<80>, 64>;
|
||||
};
|
||||
|
||||
// REAL(KIND=16) is IEEE quad precision (128 bits)
|
||||
template<>
|
||||
template <>
|
||||
class Type<TypeCategory::Real, 16> : public TypeBase<TypeCategory::Real, 16> {
|
||||
public:
|
||||
using Scalar = value::Real<value::Integer<128>, 113>;
|
||||
};
|
||||
|
||||
// The KIND type parameter on COMPLEX is the kind of each of its components.
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
class Type<TypeCategory::Complex, KIND>
|
||||
: public TypeBase<TypeCategory::Complex, KIND> {
|
||||
public:
|
||||
|
@ -287,28 +289,28 @@ public:
|
|||
using Scalar = value::Complex<typename Part::Scalar>;
|
||||
};
|
||||
|
||||
template<>
|
||||
template <>
|
||||
class Type<TypeCategory::Character, 1>
|
||||
: public TypeBase<TypeCategory::Character, 1> {
|
||||
public:
|
||||
using Scalar = std::string;
|
||||
};
|
||||
|
||||
template<>
|
||||
template <>
|
||||
class Type<TypeCategory::Character, 2>
|
||||
: public TypeBase<TypeCategory::Character, 2> {
|
||||
public:
|
||||
using Scalar = std::u16string;
|
||||
};
|
||||
|
||||
template<>
|
||||
template <>
|
||||
class Type<TypeCategory::Character, 4>
|
||||
: public TypeBase<TypeCategory::Character, 4> {
|
||||
public:
|
||||
using Scalar = std::u32string;
|
||||
};
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
class Type<TypeCategory::Logical, KIND>
|
||||
: public TypeBase<TypeCategory::Logical, KIND> {
|
||||
public:
|
||||
|
@ -318,7 +320,7 @@ public:
|
|||
// Type functions
|
||||
|
||||
// Given a specific type, find the type of the same kind in another category.
|
||||
template<TypeCategory CATEGORY, typename T>
|
||||
template <TypeCategory CATEGORY, typename T>
|
||||
using SameKind = Type<CATEGORY, std::decay_t<T>::kind>;
|
||||
|
||||
// Many expressions, including subscripts, CHARACTER lengths, array bounds,
|
||||
|
@ -329,16 +331,16 @@ using IndirectSubscriptIntegerExpr =
|
|||
// For each intrinsic type category CAT, CategoryTypes<CAT> is an instantiation
|
||||
// of std::tuple<Type<CAT, K>> that comprises every kind value K in that
|
||||
// category that could possibly be supported on any target.
|
||||
template<TypeCategory CATEGORY, int KIND>
|
||||
template <TypeCategory CATEGORY, int KIND>
|
||||
using CategoryKindTuple =
|
||||
std::conditional_t<IsValidKindOfIntrinsicType(CATEGORY, KIND),
|
||||
std::tuple<Type<CATEGORY, KIND>>, std::tuple<>>;
|
||||
|
||||
template<TypeCategory CATEGORY, int... KINDS>
|
||||
template <TypeCategory CATEGORY, int... KINDS>
|
||||
using CategoryTypesHelper =
|
||||
common::CombineTuples<CategoryKindTuple<CATEGORY, KINDS>...>;
|
||||
|
||||
template<TypeCategory CATEGORY>
|
||||
template <TypeCategory CATEGORY>
|
||||
using CategoryTypes = CategoryTypesHelper<CATEGORY, 1, 2, 3, 4, 8, 10, 16, 32>;
|
||||
|
||||
using IntegerTypes = CategoryTypes<TypeCategory::Integer>;
|
||||
|
@ -355,18 +357,18 @@ using LengthlessIntrinsicTypes =
|
|||
common::CombineTuples<NumericTypes, LogicalTypes>;
|
||||
|
||||
// Predicates: does a type represent a specific intrinsic type?
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
constexpr bool IsSpecificIntrinsicType{common::HasMember<T, AllIntrinsicTypes>};
|
||||
|
||||
// Predicate: is a type an intrinsic type that is completely characterized
|
||||
// by its category and kind parameter value, or might it have a derived type
|
||||
// &/or a length type parameter?
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
constexpr bool IsLengthlessIntrinsicType{
|
||||
common::HasMember<T, LengthlessIntrinsicTypes>};
|
||||
|
||||
// Represents a type of any supported kind within a particular category.
|
||||
template<TypeCategory CATEGORY> struct SomeKind {
|
||||
template <TypeCategory CATEGORY> struct SomeKind {
|
||||
static constexpr TypeCategory category{CATEGORY};
|
||||
constexpr bool operator==(const SomeKind &) const { return true; }
|
||||
};
|
||||
|
@ -384,7 +386,7 @@ struct SomeType {};
|
|||
class StructureConstructor;
|
||||
|
||||
// Represents any derived type, polymorphic or not, as well as CLASS(*).
|
||||
template<> class SomeKind<TypeCategory::Derived> {
|
||||
template <> class SomeKind<TypeCategory::Derived> {
|
||||
public:
|
||||
static constexpr TypeCategory category{TypeCategory::Derived};
|
||||
using Scalar = StructureConstructor;
|
||||
|
@ -427,13 +429,13 @@ using SomeCategory = std::tuple<SomeInteger, SomeReal, SomeComplex,
|
|||
using AllTypes =
|
||||
common::CombineTuples<AllIntrinsicTypes, std::tuple<SomeDerived>>;
|
||||
|
||||
template<typename T> using Scalar = typename std::decay_t<T>::Scalar;
|
||||
template <typename T> using Scalar = typename std::decay_t<T>::Scalar;
|
||||
|
||||
// When Scalar<T> is S, then TypeOf<S> is T.
|
||||
// TypeOf is implemented by scanning all supported types for a match
|
||||
// with Type<T>::Scalar.
|
||||
template<typename CONST> struct TypeOfHelper {
|
||||
template<typename T> struct Predicate {
|
||||
template <typename CONST> struct TypeOfHelper {
|
||||
template <typename T> struct Predicate {
|
||||
static constexpr bool value() {
|
||||
return std::is_same_v<std::decay_t<CONST>,
|
||||
std::decay_t<typename T::Scalar>>;
|
||||
|
@ -445,7 +447,7 @@ template<typename CONST> struct TypeOfHelper {
|
|||
std::tuple_element_t<index, AllIntrinsicTypes>, void>;
|
||||
};
|
||||
|
||||
template<typename CONST> using TypeOf = typename TypeOfHelper<CONST>::type;
|
||||
template <typename CONST> using TypeOf = typename TypeOfHelper<CONST>::type;
|
||||
|
||||
int SelectedCharKind(const std::string &, int defaultKind);
|
||||
int SelectedIntKind(std::int64_t precision = 0);
|
||||
|
@ -511,5 +513,5 @@ bool IsKindTypeParameter(const semantics::Symbol &);
|
|||
#define FOR_EACH_TYPE_AND_KIND(PREFIX, SUFFIX) \
|
||||
FOR_EACH_INTRINSIC_KIND(PREFIX, SUFFIX) \
|
||||
FOR_EACH_CATEGORY_TYPE(PREFIX, SUFFIX)
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
#endif // FORTRAN_EVALUATE_TYPE_H_
|
||||
|
|
|
@ -44,7 +44,7 @@ using SymbolVector = std::vector<SymbolRef>;
|
|||
|
||||
// Forward declarations
|
||||
struct DataRef;
|
||||
template<typename T> struct Variable;
|
||||
template <typename T> struct Variable;
|
||||
|
||||
// Reference a base object in memory. This can be a Fortran symbol,
|
||||
// static data (e.g., CHARACTER literal), or compiler-created temporary.
|
||||
|
@ -128,7 +128,7 @@ private:
|
|||
// KIND(x), which is then folded to a constant value.
|
||||
// "Bare" type parameter references within a derived type definition do
|
||||
// not have base objects.
|
||||
template<int KIND> class TypeParamInquiry {
|
||||
template <int KIND> class TypeParamInquiry {
|
||||
public:
|
||||
using Result = Type<TypeCategory::Integer, KIND>;
|
||||
CLASS_BOILERPLATE(TypeParamInquiry)
|
||||
|
@ -211,7 +211,7 @@ public:
|
|||
int size() const { return static_cast<int>(subscript_.size()); }
|
||||
Subscript &at(int n) { return subscript_.at(n); }
|
||||
const Subscript &at(int n) const { return subscript_.at(n); }
|
||||
template<typename A> common::IfNoLvalue<Subscript &, A> emplace_back(A &&x) {
|
||||
template <typename A> common::IfNoLvalue<Subscript &, A> emplace_back(A &&x) {
|
||||
return subscript_.emplace_back(std::move(x));
|
||||
}
|
||||
|
||||
|
@ -323,7 +323,7 @@ public:
|
|||
Parent &parent() { return parent_; }
|
||||
|
||||
int Rank() const;
|
||||
template<typename A> const A *GetParentIf() const {
|
||||
template <typename A> const A *GetParentIf() const {
|
||||
return std::get_if<A>(&parent_);
|
||||
}
|
||||
BaseObject GetBaseObject() const;
|
||||
|
@ -366,7 +366,7 @@ private:
|
|||
// calls to pointer-valued functions. Its variant holds everything that
|
||||
// a DataRef can, and possibly also a substring reference or a
|
||||
// complex component (%RE/%IM) reference.
|
||||
template<typename T> class Designator {
|
||||
template <typename T> class Designator {
|
||||
using DataRefs = std::decay_t<decltype(DataRef::u)>;
|
||||
using MaybeSubstring =
|
||||
std::conditional_t<T::category == TypeCategory::Character,
|
||||
|
@ -397,7 +397,7 @@ public:
|
|||
|
||||
FOR_EACH_CHARACTER_KIND(extern template class Designator, )
|
||||
|
||||
template<typename T> struct Variable {
|
||||
template <typename T> struct Variable {
|
||||
using Result = T;
|
||||
static_assert(IsSpecificIntrinsicType<Result> ||
|
||||
std::is_same_v<Result, SomeKind<TypeCategory::Derived>>);
|
||||
|
@ -443,5 +443,5 @@ private:
|
|||
EXPAND_FOR_EACH_INTEGER_KIND( \
|
||||
TEMPLATE_INSTANTIATION, template class TypeParamInquiry, ) \
|
||||
FOR_EACH_SPECIFIC_TYPE(template class Designator, )
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
#endif // FORTRAN_EVALUATE_VARIABLE_H_
|
||||
|
|
|
@ -108,13 +108,13 @@ namespace cfi_internal {
|
|||
// The below structure emulates a flexible array. This structure does not take
|
||||
// care of getting the memory storage. Note that it already contains one element
|
||||
// because a struct cannot be empty.
|
||||
template<typename T> struct FlexibleArray : T {
|
||||
template <typename T> struct FlexibleArray : T {
|
||||
T &operator[](int index) { return *(this + index); }
|
||||
const T &operator[](int index) const { return *(this + index); }
|
||||
operator T *() { return this; }
|
||||
operator const T *() const { return this; }
|
||||
};
|
||||
}
|
||||
} // namespace cfi_internal
|
||||
#endif
|
||||
|
||||
/* 18.5.3 generic data descriptor */
|
||||
|
@ -139,13 +139,13 @@ typedef struct CFI_cdesc_t {
|
|||
// The struct below take care of getting the memory storage for C++ CFI_cdesc_t
|
||||
// that contain an emulated flexible array.
|
||||
namespace cfi_internal {
|
||||
template<int r> struct CdescStorage : public CFI_cdesc_t {
|
||||
template <int r> struct CdescStorage : public CFI_cdesc_t {
|
||||
static_assert((r > 1 && r <= CFI_MAX_RANK), "CFI_INVALID_RANK");
|
||||
CFI_dim_t dim[r - 1];
|
||||
};
|
||||
template<> struct CdescStorage<1> : public CFI_cdesc_t {};
|
||||
template<> struct CdescStorage<0> : public CFI_cdesc_t {};
|
||||
}
|
||||
template <> struct CdescStorage<1> : public CFI_cdesc_t {};
|
||||
template <> struct CdescStorage<0> : public CFI_cdesc_t {};
|
||||
} // namespace cfi_internal
|
||||
#define CFI_CDESC_T(rank) cfi_internal::CdescStorage<rank>
|
||||
#else
|
||||
#define CFI_CDESC_T(rank) \
|
||||
|
|
|
@ -140,10 +140,10 @@ inline bool operator>(const char *left, const CharBlock &right) {
|
|||
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const CharBlock &x);
|
||||
|
||||
}
|
||||
} // namespace Fortran::parser
|
||||
|
||||
// Specializations to enable std::unordered_map<CharBlock, ...> &c.
|
||||
template<> struct std::hash<Fortran::parser::CharBlock> {
|
||||
template <> struct std::hash<Fortran::parser::CharBlock> {
|
||||
std::size_t operator()(const Fortran::parser::CharBlock &x) const {
|
||||
std::size_t hash{0}, bytes{x.size()};
|
||||
for (std::size_t j{0}; j < bytes; ++j) {
|
||||
|
|
|
@ -24,8 +24,8 @@ class CharBuffer {
|
|||
public:
|
||||
CharBuffer() {}
|
||||
CharBuffer(CharBuffer &&that)
|
||||
: blocks_(std::move(that.blocks_)), last_{that.last_}, bytes_{that.bytes_},
|
||||
lastBlockEmpty_{that.lastBlockEmpty_} {
|
||||
: blocks_(std::move(that.blocks_)), last_{that.last_},
|
||||
bytes_{that.bytes_}, lastBlockEmpty_{that.lastBlockEmpty_} {
|
||||
that.clear();
|
||||
}
|
||||
CharBuffer &operator=(CharBuffer &&that) {
|
||||
|
@ -73,5 +73,5 @@ private:
|
|||
std::size_t bytes_{0};
|
||||
bool lastBlockEmpty_{false};
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::parser
|
||||
#endif // FORTRAN_PARSER_CHAR_BUFFER_H_
|
||||
|
|
|
@ -75,5 +75,5 @@ private:
|
|||
constexpr SetOfChars(std::uint64_t b) : bits_{b} {}
|
||||
std::uint64_t bits_{0};
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::parser
|
||||
#endif // FORTRAN_PARSER_CHAR_SET_H_
|
||||
|
|
|
@ -103,33 +103,51 @@ inline constexpr char HexadecimalDigitValue(char ch) {
|
|||
|
||||
inline constexpr std::optional<char> BackslashEscapeValue(char ch) {
|
||||
switch (ch) {
|
||||
case 'a': return std::nullopt; // '\a'; PGF90 doesn't know \a
|
||||
case 'b': return '\b';
|
||||
case 'f': return '\f';
|
||||
case 'n': return '\n';
|
||||
case 'r': return '\r';
|
||||
case 't': return '\t';
|
||||
case 'v': return '\v';
|
||||
case 'a':
|
||||
return std::nullopt; // '\a'; PGF90 doesn't know \a
|
||||
case 'b':
|
||||
return '\b';
|
||||
case 'f':
|
||||
return '\f';
|
||||
case 'n':
|
||||
return '\n';
|
||||
case 'r':
|
||||
return '\r';
|
||||
case 't':
|
||||
return '\t';
|
||||
case 'v':
|
||||
return '\v';
|
||||
case '"':
|
||||
case '\'':
|
||||
case '\\': return ch;
|
||||
default: return std::nullopt;
|
||||
case '\\':
|
||||
return ch;
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
inline constexpr std::optional<char> BackslashEscapeChar(char ch) {
|
||||
switch (ch) {
|
||||
case '\a': return std::nullopt; // 'a'; PGF90 doesn't know \a
|
||||
case '\b': return 'b';
|
||||
case '\f': return 'f';
|
||||
case '\n': return 'n';
|
||||
case '\r': return 'r';
|
||||
case '\t': return 't';
|
||||
case '\v': return 'v';
|
||||
case '\a':
|
||||
return std::nullopt; // 'a'; PGF90 doesn't know \a
|
||||
case '\b':
|
||||
return 'b';
|
||||
case '\f':
|
||||
return 'f';
|
||||
case '\n':
|
||||
return 'n';
|
||||
case '\r':
|
||||
return 'r';
|
||||
case '\t':
|
||||
return 't';
|
||||
case '\v':
|
||||
return 'v';
|
||||
case '"':
|
||||
case '\'':
|
||||
case '\\': return ch;
|
||||
default: return std::nullopt;
|
||||
case '\\':
|
||||
return ch;
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,13 +157,13 @@ struct EncodedCharacter {
|
|||
int bytes{0};
|
||||
};
|
||||
|
||||
template<Encoding ENCODING> EncodedCharacter EncodeCharacter(char32_t ucs);
|
||||
template<> EncodedCharacter EncodeCharacter<Encoding::LATIN_1>(char32_t);
|
||||
template<> EncodedCharacter EncodeCharacter<Encoding::UTF_8>(char32_t);
|
||||
template <Encoding ENCODING> EncodedCharacter EncodeCharacter(char32_t ucs);
|
||||
template <> EncodedCharacter EncodeCharacter<Encoding::LATIN_1>(char32_t);
|
||||
template <> EncodedCharacter EncodeCharacter<Encoding::UTF_8>(char32_t);
|
||||
|
||||
EncodedCharacter EncodeCharacter(Encoding, char32_t ucs);
|
||||
|
||||
template<Encoding ENCODING, typename STRING>
|
||||
template <Encoding ENCODING, typename STRING>
|
||||
std::string EncodeString(const STRING &);
|
||||
extern template std::string EncodeString<Encoding::LATIN_1, std::string>(
|
||||
const std::string &);
|
||||
|
@ -154,7 +172,7 @@ extern template std::string EncodeString<Encoding::UTF_8, std::u32string>(
|
|||
|
||||
// EmitQuotedChar drives callbacks "emit" and "insert" to output the
|
||||
// bytes of an encoding for a codepoint.
|
||||
template<typename NORMAL, typename INSERTED>
|
||||
template <typename NORMAL, typename INSERTED>
|
||||
void EmitQuotedChar(char32_t ch, const NORMAL &emit, const INSERTED &insert,
|
||||
bool backslashEscapes = true, Encoding encoding = Encoding::UTF_8) {
|
||||
auto emitOneByte{[&](std::uint8_t ch) {
|
||||
|
@ -206,17 +224,17 @@ struct DecodedCharacter {
|
|||
int bytes{0}; // signifying failure
|
||||
};
|
||||
|
||||
template<Encoding ENCODING>
|
||||
template <Encoding ENCODING>
|
||||
DecodedCharacter DecodeRawCharacter(const char *, std::size_t);
|
||||
template<>
|
||||
template <>
|
||||
DecodedCharacter DecodeRawCharacter<Encoding::LATIN_1>(
|
||||
const char *, std::size_t);
|
||||
|
||||
template<>
|
||||
template <>
|
||||
DecodedCharacter DecodeRawCharacter<Encoding::UTF_8>(const char *, std::size_t);
|
||||
|
||||
// DecodeCharacter optionally handles backslash escape sequences, too.
|
||||
template<Encoding ENCODING>
|
||||
template <Encoding ENCODING>
|
||||
DecodedCharacter DecodeCharacter(
|
||||
const char *, std::size_t, bool backslashEscapes);
|
||||
extern template DecodedCharacter DecodeCharacter<Encoding::LATIN_1>(
|
||||
|
@ -227,7 +245,7 @@ extern template DecodedCharacter DecodeCharacter<Encoding::UTF_8>(
|
|||
DecodedCharacter DecodeCharacter(
|
||||
Encoding, const char *, std::size_t, bool backslashEscapes);
|
||||
|
||||
template<typename RESULT, Encoding ENCODING>
|
||||
template <typename RESULT, Encoding ENCODING>
|
||||
RESULT DecodeString(const std::string &, bool backslashEscapes);
|
||||
extern template std::string DecodeString<std::string, Encoding::LATIN_1>(
|
||||
const std::string &, bool);
|
||||
|
@ -235,5 +253,5 @@ extern template std::u16string DecodeString<std::u16string, Encoding::UTF_8>(
|
|||
const std::string &, bool);
|
||||
extern template std::u32string DecodeString<std::u32string, Encoding::UTF_8>(
|
||||
const std::string &, bool);
|
||||
}
|
||||
} // namespace Fortran::parser
|
||||
#endif // FORTRAN_PARSER_CHARACTERS_H_
|
||||
|
|
|
@ -23,9 +23,9 @@ namespace Fortran::parser {
|
|||
|
||||
// When SHOW_ALL_SOURCE_MEMBERS is defined, HasSource<T>::value is true if T has
|
||||
// a member named source
|
||||
template<typename T, typename = int> struct HasSource : std::false_type {};
|
||||
template <typename T, typename = int> struct HasSource : std::false_type {};
|
||||
#ifdef SHOW_ALL_SOURCE_MEMBERS
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
struct HasSource<T, decltype((void)T::source, 0)> : std::true_type {};
|
||||
#endif
|
||||
|
||||
|
@ -35,8 +35,8 @@ struct HasSource<T, decltype((void)T::source, 0)> : std::true_type {};
|
|||
|
||||
class ParseTreeDumper {
|
||||
public:
|
||||
explicit ParseTreeDumper(
|
||||
llvm::raw_ostream &out, const AnalyzedObjectsAsFortran *asFortran = nullptr)
|
||||
explicit ParseTreeDumper(llvm::raw_ostream &out,
|
||||
const AnalyzedObjectsAsFortran *asFortran = nullptr)
|
||||
: out_(out), asFortran_{asFortran} {}
|
||||
|
||||
static constexpr const char *GetNodeName(const char *) { return "char *"; }
|
||||
|
@ -682,7 +682,7 @@ public:
|
|||
#undef NODE
|
||||
#undef NODE_NAME
|
||||
|
||||
template<typename T> bool Pre(const T &x) {
|
||||
template <typename T> bool Pre(const T &x) {
|
||||
std::string fortran{AsFortran<T>(x)};
|
||||
if (fortran.empty() && (UnionTrait<T> || WrapperTrait<T>)) {
|
||||
Prefix(GetNodeName(x));
|
||||
|
@ -698,7 +698,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
template<typename T> void Post(const T &x) {
|
||||
template <typename T> void Post(const T &x) {
|
||||
if (AsFortran<T>(x).empty() && (UnionTrait<T> || WrapperTrait<T>)) {
|
||||
EndLineIfNonempty();
|
||||
} else {
|
||||
|
@ -711,55 +711,57 @@ public:
|
|||
bool Pre(const CharBlock &) { return true; }
|
||||
void Post(const CharBlock &) {}
|
||||
|
||||
template<typename T> bool Pre(const Statement<T> &) { return true; }
|
||||
template<typename T> void Post(const Statement<T> &) {}
|
||||
template<typename T> bool Pre(const UnlabeledStatement<T> &) { return true; }
|
||||
template<typename T> void Post(const UnlabeledStatement<T> &) {}
|
||||
template <typename T> bool Pre(const Statement<T> &) { return true; }
|
||||
template <typename T> void Post(const Statement<T> &) {}
|
||||
template <typename T> bool Pre(const UnlabeledStatement<T> &) { return true; }
|
||||
template <typename T> void Post(const UnlabeledStatement<T> &) {}
|
||||
|
||||
template<typename T> bool Pre(const common::Indirection<T> &) { return true; }
|
||||
template<typename T> void Post(const common::Indirection<T> &) {}
|
||||
template <typename T> bool Pre(const common::Indirection<T> &) {
|
||||
return true;
|
||||
}
|
||||
template <typename T> void Post(const common::Indirection<T> &) {}
|
||||
|
||||
template<typename A> bool Pre(const Scalar<A> &) {
|
||||
template <typename A> bool Pre(const Scalar<A> &) {
|
||||
Prefix("Scalar");
|
||||
return true;
|
||||
}
|
||||
template<typename A> void Post(const Scalar<A> &) { EndLineIfNonempty(); }
|
||||
template <typename A> void Post(const Scalar<A> &) { EndLineIfNonempty(); }
|
||||
|
||||
template<typename A> bool Pre(const Constant<A> &) {
|
||||
template <typename A> bool Pre(const Constant<A> &) {
|
||||
Prefix("Constant");
|
||||
return true;
|
||||
}
|
||||
template<typename A> void Post(const Constant<A> &) { EndLineIfNonempty(); }
|
||||
template <typename A> void Post(const Constant<A> &) { EndLineIfNonempty(); }
|
||||
|
||||
template<typename A> bool Pre(const Integer<A> &) {
|
||||
template <typename A> bool Pre(const Integer<A> &) {
|
||||
Prefix("Integer");
|
||||
return true;
|
||||
}
|
||||
template<typename A> void Post(const Integer<A> &) { EndLineIfNonempty(); }
|
||||
template <typename A> void Post(const Integer<A> &) { EndLineIfNonempty(); }
|
||||
|
||||
template<typename A> bool Pre(const Logical<A> &) {
|
||||
template <typename A> bool Pre(const Logical<A> &) {
|
||||
Prefix("Logical");
|
||||
return true;
|
||||
}
|
||||
template<typename A> void Post(const Logical<A> &) { EndLineIfNonempty(); }
|
||||
template <typename A> void Post(const Logical<A> &) { EndLineIfNonempty(); }
|
||||
|
||||
template<typename A> bool Pre(const DefaultChar<A> &) {
|
||||
template <typename A> bool Pre(const DefaultChar<A> &) {
|
||||
Prefix("DefaultChar");
|
||||
return true;
|
||||
}
|
||||
template<typename A> void Post(const DefaultChar<A> &) {
|
||||
template <typename A> void Post(const DefaultChar<A> &) {
|
||||
EndLineIfNonempty();
|
||||
}
|
||||
|
||||
template<typename... A> bool Pre(const std::tuple<A...> &) { return true; }
|
||||
template<typename... A> void Post(const std::tuple<A...> &) {}
|
||||
template <typename... A> bool Pre(const std::tuple<A...> &) { return true; }
|
||||
template <typename... A> void Post(const std::tuple<A...> &) {}
|
||||
|
||||
template<typename... A> bool Pre(const std::variant<A...> &) { return true; }
|
||||
template<typename... A> void Post(const std::variant<A...> &) {}
|
||||
template <typename... A> bool Pre(const std::variant<A...> &) { return true; }
|
||||
template <typename... A> void Post(const std::variant<A...> &) {}
|
||||
|
||||
protected:
|
||||
// Return a Fortran representation of this node to include in the dump
|
||||
template<typename T> std::string AsFortran(const T &x) {
|
||||
template <typename T> std::string AsFortran(const T &x) {
|
||||
std::string buf;
|
||||
llvm::raw_string_ostream ss{buf};
|
||||
if constexpr (std::is_same_v<T, Expr>) {
|
||||
|
@ -835,12 +837,12 @@ private:
|
|||
bool emptyline_{false};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void DumpTree(llvm::raw_ostream &out, const T &x,
|
||||
const AnalyzedObjectsAsFortran *asFortran = nullptr) {
|
||||
ParseTreeDumper dumper{out, asFortran};
|
||||
Walk(x, dumper);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Fortran::parser
|
||||
#endif // FORTRAN_PARSER_DUMP_PARSE_TREE_H_
|
||||
|
|
|
@ -116,10 +116,10 @@ struct FormatItem {
|
|||
FormatItem() = delete;
|
||||
FormatItem(FormatItem &&) = default;
|
||||
FormatItem &operator=(FormatItem &&) = default;
|
||||
template<typename A, typename = common::NoLvalue<A>>
|
||||
template <typename A, typename = common::NoLvalue<A>>
|
||||
FormatItem(std::optional<std::uint64_t> &&r, A &&x)
|
||||
: repeatCount{std::move(r)}, u{std::move(x)} {}
|
||||
template<typename A, typename = common::NoLvalue<A>>
|
||||
template <typename A, typename = common::NoLvalue<A>>
|
||||
explicit FormatItem(A &&x) : u{std::move(x)} {}
|
||||
std::optional<std::uint64_t> repeatCount;
|
||||
std::variant<IntrinsicTypeDataEditDesc, DerivedTypeDataEditDesc,
|
||||
|
@ -141,5 +141,5 @@ struct FormatSpecification {
|
|||
: items(std::move(is)), unlimitedItems(std::move(us)) {}
|
||||
std::list<FormatItem> items, unlimitedItems;
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::format
|
||||
#endif // FORTRAN_PARSER_FORMAT_SPECIFICATION_H_
|
||||
|
|
|
@ -47,7 +47,7 @@ private:
|
|||
std::map<std::size_t, LogForPosition> perPos_;
|
||||
};
|
||||
|
||||
template<typename PA> class InstrumentedParser {
|
||||
template <typename PA> class InstrumentedParser {
|
||||
public:
|
||||
using resultType = typename PA::resultType;
|
||||
constexpr InstrumentedParser(const InstrumentedParser &) = default;
|
||||
|
@ -75,10 +75,10 @@ private:
|
|||
const PA parser_;
|
||||
};
|
||||
|
||||
template<typename PA>
|
||||
template <typename PA>
|
||||
inline constexpr auto instrumented(
|
||||
const MessageFixedText &tag, const PA &parser) {
|
||||
return InstrumentedParser{tag, parser};
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::parser
|
||||
#endif // FORTRAN_PARSER_INSTRUMENTED_PARSER_H_
|
||||
|
|
|
@ -57,7 +57,7 @@ constexpr MessageFixedText operator""_err_en_US(
|
|||
const char str[], std::size_t n) {
|
||||
return MessageFixedText{str, n, true /* fatal */};
|
||||
}
|
||||
}
|
||||
} // namespace literals
|
||||
|
||||
// The construction of a MessageFormattedText uses a MessageFixedText
|
||||
// as a vsnprintf() formatting string that is applied to the
|
||||
|
@ -66,7 +66,7 @@ constexpr MessageFixedText operator""_err_en_US(
|
|||
// char pointers that are suitable for '%s' formatting.
|
||||
class MessageFormattedText {
|
||||
public:
|
||||
template<typename... A>
|
||||
template <typename... A>
|
||||
MessageFormattedText(const MessageFixedText &text, A &&... x)
|
||||
: isFatal_{text.isFatal()} {
|
||||
Format(&text, Convert(std::forward<A>(x))...);
|
||||
|
@ -82,15 +82,15 @@ public:
|
|||
private:
|
||||
void Format(const MessageFixedText *, ...);
|
||||
|
||||
template<typename A> A Convert(const A &x) {
|
||||
template <typename A> A Convert(const A &x) {
|
||||
static_assert(!std::is_class_v<std::decay_t<A>>);
|
||||
return x;
|
||||
}
|
||||
template<typename A> A Convert(A &x) {
|
||||
template <typename A> A Convert(A &x) {
|
||||
static_assert(!std::is_class_v<std::decay_t<A>>);
|
||||
return x;
|
||||
}
|
||||
template<typename A> common::IfNoLvalue<A, A> Convert(A &&x) {
|
||||
template <typename A> common::IfNoLvalue<A, A> Convert(A &&x) {
|
||||
static_assert(!std::is_class_v<std::decay_t<A>>);
|
||||
return std::move(x);
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ public:
|
|||
Message(CharBlock csr, const MessageExpectedText &t)
|
||||
: location_{csr}, text_{t} {}
|
||||
|
||||
template<typename RANGE, typename A, typename... As>
|
||||
template <typename RANGE, typename A, typename... As>
|
||||
Message(RANGE r, const MessageFixedText &t, A &&x, As &&... xs)
|
||||
: location_{r}, text_{MessageFormattedText{
|
||||
t, std::forward<A>(x), std::forward<As>(xs)...}} {}
|
||||
|
@ -177,7 +177,7 @@ public:
|
|||
}
|
||||
Message &Attach(Message *);
|
||||
Message &Attach(std::unique_ptr<Message> &&);
|
||||
template<typename... A> Message &Attach(A &&... args) {
|
||||
template <typename... A> Message &Attach(A &&... args) {
|
||||
return Attach(new Message{std::forward<A>(args)...}); // reference-counted
|
||||
}
|
||||
|
||||
|
@ -185,8 +185,8 @@ public:
|
|||
bool IsFatal() const;
|
||||
std::string ToString() const;
|
||||
std::optional<ProvenanceRange> GetProvenanceRange(const CookedSource &) const;
|
||||
void Emit(
|
||||
llvm::raw_ostream &, const CookedSource &, bool echoSourceLine = true) const;
|
||||
void Emit(llvm::raw_ostream &, const CookedSource &,
|
||||
bool echoSourceLine = true) const;
|
||||
|
||||
// If this Message or any of its attachments locates itself via a CharBlock
|
||||
// within a particular CookedSource, replace its location with the
|
||||
|
@ -232,7 +232,7 @@ public:
|
|||
bool empty() const { return messages_.empty(); }
|
||||
void clear();
|
||||
|
||||
template<typename... A> Message &Say(A &&... args) {
|
||||
template <typename... A> Message &Say(A &&... args) {
|
||||
last_ = messages_.emplace_after(last_, std::forward<A>(args)...);
|
||||
return *last_;
|
||||
}
|
||||
|
@ -296,7 +296,7 @@ public:
|
|||
return common::ScopedSet(messages_, nullptr);
|
||||
}
|
||||
|
||||
template<typename... A> Message *Say(CharBlock at, A &&... args) {
|
||||
template <typename... A> Message *Say(CharBlock at, A &&... args) {
|
||||
if (messages_ != nullptr) {
|
||||
return &messages_->Say(at, std::forward<A>(args)...);
|
||||
} else {
|
||||
|
@ -304,7 +304,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template<typename... A> Message *Say(A &&... args) {
|
||||
template <typename... A> Message *Say(A &&... args) {
|
||||
return Say(at_, std::forward<A>(args)...);
|
||||
}
|
||||
|
||||
|
@ -312,5 +312,5 @@ private:
|
|||
CharBlock at_;
|
||||
Messages *messages_{nullptr};
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::parser
|
||||
#endif // FORTRAN_PARSER_MESSAGE_H_
|
||||
|
|
|
@ -131,17 +131,18 @@ public:
|
|||
context_ = context_->attachment();
|
||||
}
|
||||
|
||||
template<typename... A> void Say(CharBlock range, A &&... args) {
|
||||
template <typename... A> void Say(CharBlock range, A &&... args) {
|
||||
if (deferMessages_) {
|
||||
anyDeferredMessages_ = true;
|
||||
} else {
|
||||
messages_.Say(range, std::forward<A>(args)...).SetContext(context_.get());
|
||||
}
|
||||
}
|
||||
template<typename... A> void Say(const MessageFixedText &text, A &&... args) {
|
||||
template <typename... A>
|
||||
void Say(const MessageFixedText &text, A &&... args) {
|
||||
Say(p_, text, std::forward<A>(args)...);
|
||||
}
|
||||
template<typename... A>
|
||||
template <typename... A>
|
||||
void Say(const MessageExpectedText &text, A &&... args) {
|
||||
Say(p_, text, std::forward<A>(args)...);
|
||||
}
|
||||
|
@ -228,5 +229,5 @@ private:
|
|||
// reflected in the copy and move constructors defined at the top of this
|
||||
// class definition!
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::parser
|
||||
#endif // FORTRAN_PARSER_PARSE_STATE_H_
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace Fortran::parser {
|
|||
|
||||
// Default case for visitation of non-class data members, strings, and
|
||||
// any other non-decomposable values.
|
||||
template<typename A, typename V>
|
||||
template <typename A, typename V>
|
||||
std::enable_if_t<!std::is_class_v<A> || std::is_same_v<std::string, A> ||
|
||||
std::is_same_v<CharBlock, A>>
|
||||
Walk(const A &x, V &visitor) {
|
||||
|
@ -37,7 +37,7 @@ Walk(const A &x, V &visitor) {
|
|||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename A, typename M>
|
||||
template <typename A, typename M>
|
||||
std::enable_if_t<!std::is_class_v<A> || std::is_same_v<std::string, A> ||
|
||||
std::is_same_v<CharBlock, A>>
|
||||
Walk(A &x, M &mutator) {
|
||||
|
@ -46,25 +46,25 @@ Walk(A &x, M &mutator) {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename V> void Walk(const format::ControlEditDesc &, V &);
|
||||
template<typename M> void Walk(format::ControlEditDesc &, M &);
|
||||
template<typename V> void Walk(const format::DerivedTypeDataEditDesc &, V &);
|
||||
template<typename M> void Walk(format::DerivedTypeDataEditDesc &, M &);
|
||||
template<typename V> void Walk(const format::FormatItem &, V &);
|
||||
template<typename M> void Walk(format::FormatItem &, M &);
|
||||
template<typename V> void Walk(const format::FormatSpecification &, V &);
|
||||
template<typename M> void Walk(format::FormatSpecification &, M &);
|
||||
template<typename V> void Walk(const format::IntrinsicTypeDataEditDesc &, V &);
|
||||
template<typename M> void Walk(format::IntrinsicTypeDataEditDesc &, M &);
|
||||
template <typename V> void Walk(const format::ControlEditDesc &, V &);
|
||||
template <typename M> void Walk(format::ControlEditDesc &, M &);
|
||||
template <typename V> void Walk(const format::DerivedTypeDataEditDesc &, V &);
|
||||
template <typename M> void Walk(format::DerivedTypeDataEditDesc &, M &);
|
||||
template <typename V> void Walk(const format::FormatItem &, V &);
|
||||
template <typename M> void Walk(format::FormatItem &, M &);
|
||||
template <typename V> void Walk(const format::FormatSpecification &, V &);
|
||||
template <typename M> void Walk(format::FormatSpecification &, M &);
|
||||
template <typename V> void Walk(const format::IntrinsicTypeDataEditDesc &, V &);
|
||||
template <typename M> void Walk(format::IntrinsicTypeDataEditDesc &, M &);
|
||||
|
||||
// Traversal of needed STL template classes (optional, list, tuple, variant)
|
||||
template<typename T, typename V>
|
||||
template <typename T, typename V>
|
||||
void Walk(const std::optional<T> &x, V &visitor) {
|
||||
if (x) {
|
||||
Walk(*x, visitor);
|
||||
}
|
||||
}
|
||||
template<typename T, typename M> void Walk(std::optional<T> &x, M &mutator) {
|
||||
template <typename T, typename M> void Walk(std::optional<T> &x, M &mutator) {
|
||||
if (x) {
|
||||
Walk(*x, mutator);
|
||||
}
|
||||
|
@ -72,17 +72,17 @@ template<typename T, typename M> void Walk(std::optional<T> &x, M &mutator) {
|
|||
// For most lists, just traverse the elements; but when a list constitutes
|
||||
// a Block (i.e., std::list<ExecutionPartConstruct>), also invoke the
|
||||
// visitor/mutator on the list itself.
|
||||
template<typename T, typename V> void Walk(const std::list<T> &x, V &visitor) {
|
||||
template <typename T, typename V> void Walk(const std::list<T> &x, V &visitor) {
|
||||
for (const auto &elem : x) {
|
||||
Walk(elem, visitor);
|
||||
}
|
||||
}
|
||||
template<typename T, typename M> void Walk(std::list<T> &x, M &mutator) {
|
||||
template <typename T, typename M> void Walk(std::list<T> &x, M &mutator) {
|
||||
for (auto &elem : x) {
|
||||
Walk(elem, mutator);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const Block &x, V &visitor) {
|
||||
template <typename V> void Walk(const Block &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
for (const auto &elem : x) {
|
||||
Walk(elem, visitor);
|
||||
|
@ -90,7 +90,7 @@ template<typename V> void Walk(const Block &x, V &visitor) {
|
|||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(Block &x, M &mutator) {
|
||||
template <typename M> void Walk(Block &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
for (auto &elem : x) {
|
||||
Walk(elem, mutator);
|
||||
|
@ -98,14 +98,14 @@ template<typename M> void Walk(Block &x, M &mutator) {
|
|||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<std::size_t I = 0, typename Func, typename T>
|
||||
template <std::size_t I = 0, typename Func, typename T>
|
||||
void ForEachInTuple(const T &tuple, Func func) {
|
||||
func(std::get<I>(tuple));
|
||||
if constexpr (I + 1 < std::tuple_size_v<T>) {
|
||||
ForEachInTuple<I + 1>(tuple, func);
|
||||
}
|
||||
}
|
||||
template<typename V, typename... A>
|
||||
template <typename V, typename... A>
|
||||
void Walk(const std::tuple<A...> &x, V &visitor) {
|
||||
if (sizeof...(A) > 0) {
|
||||
if (visitor.Pre(x)) {
|
||||
|
@ -114,14 +114,15 @@ void Walk(const std::tuple<A...> &x, V &visitor) {
|
|||
}
|
||||
}
|
||||
}
|
||||
template<std::size_t I = 0, typename Func, typename T>
|
||||
template <std::size_t I = 0, typename Func, typename T>
|
||||
void ForEachInTuple(T &tuple, Func func) {
|
||||
func(std::get<I>(tuple));
|
||||
if constexpr (I + 1 < std::tuple_size_v<T>) {
|
||||
ForEachInTuple<I + 1>(tuple, func);
|
||||
}
|
||||
}
|
||||
template<typename M, typename... A> void Walk(std::tuple<A...> &x, M &mutator) {
|
||||
template <typename M, typename... A>
|
||||
void Walk(std::tuple<A...> &x, M &mutator) {
|
||||
if (sizeof...(A) > 0) {
|
||||
if (mutator.Pre(x)) {
|
||||
ForEachInTuple(x, [&](auto &y) { Walk(y, mutator); });
|
||||
|
@ -129,28 +130,28 @@ template<typename M, typename... A> void Walk(std::tuple<A...> &x, M &mutator) {
|
|||
}
|
||||
}
|
||||
}
|
||||
template<typename V, typename... A>
|
||||
template <typename V, typename... A>
|
||||
void Walk(const std::variant<A...> &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
std::visit([&](const auto &y) { Walk(y, visitor); }, x);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M, typename... A>
|
||||
template <typename M, typename... A>
|
||||
void Walk(std::variant<A...> &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
std::visit([&](auto &y) { Walk(y, mutator); }, x);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename A, typename B, typename V>
|
||||
template <typename A, typename B, typename V>
|
||||
void Walk(const std::pair<A, B> &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.first, visitor);
|
||||
Walk(x.second, visitor);
|
||||
}
|
||||
}
|
||||
template<typename A, typename B, typename M>
|
||||
template <typename A, typename B, typename M>
|
||||
void Walk(std::pair<A, B> &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.first, mutator);
|
||||
|
@ -160,27 +161,27 @@ void Walk(std::pair<A, B> &x, M &mutator) {
|
|||
|
||||
// Trait-determined traversal of empty, tuple, union, wrapper,
|
||||
// and constraint-checking classes.
|
||||
template<typename A, typename V>
|
||||
template <typename A, typename V>
|
||||
std::enable_if_t<EmptyTrait<A>> Walk(const A &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename A, typename M>
|
||||
template <typename A, typename M>
|
||||
std::enable_if_t<EmptyTrait<A>> Walk(A &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename A, typename V>
|
||||
template <typename A, typename V>
|
||||
std::enable_if_t<TupleTrait<A>> Walk(const A &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.t, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename A, typename M>
|
||||
template <typename A, typename M>
|
||||
std::enable_if_t<TupleTrait<A>> Walk(A &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.t, mutator);
|
||||
|
@ -188,14 +189,14 @@ std::enable_if_t<TupleTrait<A>> Walk(A &x, M &mutator) {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename A, typename V>
|
||||
template <typename A, typename V>
|
||||
std::enable_if_t<UnionTrait<A>> Walk(const A &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.u, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename A, typename M>
|
||||
template <typename A, typename M>
|
||||
std::enable_if_t<UnionTrait<A>> Walk(A &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.u, mutator);
|
||||
|
@ -203,14 +204,14 @@ std::enable_if_t<UnionTrait<A>> Walk(A &x, M &mutator) {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename A, typename V>
|
||||
template <typename A, typename V>
|
||||
std::enable_if_t<WrapperTrait<A>> Walk(const A &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.v, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename A, typename M>
|
||||
template <typename A, typename M>
|
||||
std::enable_if_t<WrapperTrait<A>> Walk(A &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.v, mutator);
|
||||
|
@ -218,14 +219,14 @@ std::enable_if_t<WrapperTrait<A>> Walk(A &x, M &mutator) {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename A, typename V>
|
||||
template <typename A, typename V>
|
||||
std::enable_if_t<ConstraintTrait<A>> Walk(const A &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.thing, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename A, typename M>
|
||||
template <typename A, typename M>
|
||||
std::enable_if_t<ConstraintTrait<A>> Walk(A &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.thing, mutator);
|
||||
|
@ -233,16 +234,16 @@ std::enable_if_t<ConstraintTrait<A>> Walk(A &x, M &mutator) {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename T, typename V>
|
||||
template <typename T, typename V>
|
||||
void Walk(const common::Indirection<T> &x, V &visitor) {
|
||||
Walk(x.value(), visitor);
|
||||
}
|
||||
template<typename T, typename M>
|
||||
template <typename T, typename M>
|
||||
void Walk(common::Indirection<T> &x, M &mutator) {
|
||||
Walk(x.value(), mutator);
|
||||
}
|
||||
|
||||
template<typename T, typename V> void Walk(const Statement<T> &x, V &visitor) {
|
||||
template <typename T, typename V> void Walk(const Statement<T> &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
// N.B. The label, if any, is not visited.
|
||||
Walk(x.source, visitor);
|
||||
|
@ -250,7 +251,7 @@ template<typename T, typename V> void Walk(const Statement<T> &x, V &visitor) {
|
|||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename T, typename M> void Walk(Statement<T> &x, M &mutator) {
|
||||
template <typename T, typename M> void Walk(Statement<T> &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
// N.B. The label, if any, is not visited.
|
||||
Walk(x.source, mutator);
|
||||
|
@ -259,7 +260,7 @@ template<typename T, typename M> void Walk(Statement<T> &x, M &mutator) {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename T, typename V>
|
||||
template <typename T, typename V>
|
||||
void Walk(const UnlabeledStatement<T> &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.source, visitor);
|
||||
|
@ -267,7 +268,7 @@ void Walk(const UnlabeledStatement<T> &x, V &visitor) {
|
|||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename T, typename M>
|
||||
template <typename T, typename M>
|
||||
void Walk(UnlabeledStatement<T> &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.source, mutator);
|
||||
|
@ -276,48 +277,48 @@ void Walk(UnlabeledStatement<T> &x, M &mutator) {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename V> void Walk(const Name &x, V &visitor) {
|
||||
template <typename V> void Walk(const Name &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.source, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(Name &x, M &mutator) {
|
||||
template <typename M> void Walk(Name &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.source, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename V> void Walk(const AcSpec &x, V &visitor) {
|
||||
template <typename V> void Walk(const AcSpec &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.type, visitor);
|
||||
Walk(x.values, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(AcSpec &x, M &mutator) {
|
||||
template <typename M> void Walk(AcSpec &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.type, mutator);
|
||||
Walk(x.values, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const ArrayElement &x, V &visitor) {
|
||||
template <typename V> void Walk(const ArrayElement &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.base, visitor);
|
||||
Walk(x.subscripts, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(ArrayElement &x, M &mutator) {
|
||||
template <typename M> void Walk(ArrayElement &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.base, mutator);
|
||||
Walk(x.subscripts, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V>
|
||||
template <typename V>
|
||||
void Walk(const CharSelector::LengthAndKind &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.length, visitor);
|
||||
|
@ -325,130 +326,131 @@ void Walk(const CharSelector::LengthAndKind &x, V &visitor) {
|
|||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(CharSelector::LengthAndKind &x, M &mutator) {
|
||||
template <typename M> void Walk(CharSelector::LengthAndKind &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.length, mutator);
|
||||
Walk(x.kind, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const CaseValueRange::Range &x, V &visitor) {
|
||||
template <typename V> void Walk(const CaseValueRange::Range &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.lower, visitor);
|
||||
Walk(x.upper, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(CaseValueRange::Range &x, M &mutator) {
|
||||
template <typename M> void Walk(CaseValueRange::Range &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.lower, mutator);
|
||||
Walk(x.upper, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const CoindexedNamedObject &x, V &visitor) {
|
||||
template <typename V> void Walk(const CoindexedNamedObject &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.base, visitor);
|
||||
Walk(x.imageSelector, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(CoindexedNamedObject &x, M &mutator) {
|
||||
template <typename M> void Walk(CoindexedNamedObject &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.base, mutator);
|
||||
Walk(x.imageSelector, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V>
|
||||
template <typename V>
|
||||
void Walk(const DeclarationTypeSpec::Class &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.derived, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(DeclarationTypeSpec::Class &x, M &mutator) {
|
||||
template <typename M> void Walk(DeclarationTypeSpec::Class &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.derived, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const DeclarationTypeSpec::Type &x, V &visitor) {
|
||||
template <typename V>
|
||||
void Walk(const DeclarationTypeSpec::Type &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.derived, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(DeclarationTypeSpec::Type &x, M &mutator) {
|
||||
template <typename M> void Walk(DeclarationTypeSpec::Type &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.derived, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const ImportStmt &x, V &visitor) {
|
||||
template <typename V> void Walk(const ImportStmt &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.names, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(ImportStmt &x, M &mutator) {
|
||||
template <typename M> void Walk(ImportStmt &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.names, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V>
|
||||
template <typename V>
|
||||
void Walk(const IntrinsicTypeSpec::Character &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.selector, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(IntrinsicTypeSpec::Character &x, M &mutator) {
|
||||
template <typename M> void Walk(IntrinsicTypeSpec::Character &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.selector, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V>
|
||||
template <typename V>
|
||||
void Walk(const IntrinsicTypeSpec::Complex &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.kind, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(IntrinsicTypeSpec::Complex &x, M &mutator) {
|
||||
template <typename M> void Walk(IntrinsicTypeSpec::Complex &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.kind, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V>
|
||||
template <typename V>
|
||||
void Walk(const IntrinsicTypeSpec::Logical &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.kind, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(IntrinsicTypeSpec::Logical &x, M &mutator) {
|
||||
template <typename M> void Walk(IntrinsicTypeSpec::Logical &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.kind, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const IntrinsicTypeSpec::Real &x, V &visitor) {
|
||||
template <typename V> void Walk(const IntrinsicTypeSpec::Real &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.kind, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(IntrinsicTypeSpec::Real &x, M &mutator) {
|
||||
template <typename M> void Walk(IntrinsicTypeSpec::Real &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.kind, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename A, typename B, typename V>
|
||||
template <typename A, typename B, typename V>
|
||||
void Walk(const LoopBounds<A, B> &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.name, visitor);
|
||||
|
@ -458,7 +460,7 @@ void Walk(const LoopBounds<A, B> &x, V &visitor) {
|
|||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename A, typename B, typename M>
|
||||
template <typename A, typename B, typename M>
|
||||
void Walk(LoopBounds<A, B> &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.name, mutator);
|
||||
|
@ -468,61 +470,61 @@ void Walk(LoopBounds<A, B> &x, M &mutator) {
|
|||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const CommonStmt &x, V &visitor) {
|
||||
template <typename V> void Walk(const CommonStmt &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.blocks, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(CommonStmt &x, M &mutator) {
|
||||
template <typename M> void Walk(CommonStmt &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.blocks, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const Expr &x, V &visitor) {
|
||||
template <typename V> void Walk(const Expr &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.source, visitor);
|
||||
Walk(x.u, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(Expr &x, M &mutator) {
|
||||
template <typename M> void Walk(Expr &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.source, mutator);
|
||||
Walk(x.u, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const Designator &x, V &visitor) {
|
||||
template <typename V> void Walk(const Designator &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.source, visitor);
|
||||
Walk(x.u, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(Designator &x, M &mutator) {
|
||||
template <typename M> void Walk(Designator &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.source, mutator);
|
||||
Walk(x.u, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const Call &x, V &visitor) {
|
||||
template <typename V> void Walk(const Call &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.source, visitor);
|
||||
Walk(x.t, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(Call &x, M &mutator) {
|
||||
template <typename M> void Walk(Call &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.source, mutator);
|
||||
Walk(x.t, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const PartRef &x, V &visitor) {
|
||||
template <typename V> void Walk(const PartRef &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.name, visitor);
|
||||
Walk(x.subscripts, visitor);
|
||||
|
@ -530,7 +532,7 @@ template<typename V> void Walk(const PartRef &x, V &visitor) {
|
|||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(PartRef &x, M &mutator) {
|
||||
template <typename M> void Walk(PartRef &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.name, mutator);
|
||||
Walk(x.subscripts, mutator);
|
||||
|
@ -538,7 +540,7 @@ template<typename M> void Walk(PartRef &x, M &mutator) {
|
|||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const ReadStmt &x, V &visitor) {
|
||||
template <typename V> void Walk(const ReadStmt &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.iounit, visitor);
|
||||
Walk(x.format, visitor);
|
||||
|
@ -547,7 +549,7 @@ template<typename V> void Walk(const ReadStmt &x, V &visitor) {
|
|||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(ReadStmt &x, M &mutator) {
|
||||
template <typename M> void Walk(ReadStmt &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.iounit, mutator);
|
||||
Walk(x.format, mutator);
|
||||
|
@ -556,75 +558,76 @@ template<typename M> void Walk(ReadStmt &x, M &mutator) {
|
|||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const SignedIntLiteralConstant &x, V &visitor) {
|
||||
template <typename V> void Walk(const SignedIntLiteralConstant &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.source, visitor);
|
||||
Walk(x.t, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(SignedIntLiteralConstant &x, M &mutator) {
|
||||
template <typename M> void Walk(SignedIntLiteralConstant &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.source, mutator);
|
||||
Walk(x.t, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const RealLiteralConstant &x, V &visitor) {
|
||||
template <typename V> void Walk(const RealLiteralConstant &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.real, visitor);
|
||||
Walk(x.kind, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(RealLiteralConstant &x, M &mutator) {
|
||||
template <typename M> void Walk(RealLiteralConstant &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.real, mutator);
|
||||
Walk(x.kind, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const RealLiteralConstant::Real &x, V &visitor) {
|
||||
template <typename V>
|
||||
void Walk(const RealLiteralConstant::Real &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.source, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(RealLiteralConstant::Real &x, M &mutator) {
|
||||
template <typename M> void Walk(RealLiteralConstant::Real &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.source, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const StructureComponent &x, V &visitor) {
|
||||
template <typename V> void Walk(const StructureComponent &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.base, visitor);
|
||||
Walk(x.component, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(StructureComponent &x, M &mutator) {
|
||||
template <typename M> void Walk(StructureComponent &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.base, mutator);
|
||||
Walk(x.component, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const Suffix &x, V &visitor) {
|
||||
template <typename V> void Walk(const Suffix &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.binding, visitor);
|
||||
Walk(x.resultName, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(Suffix &x, M &mutator) {
|
||||
template <typename M> void Walk(Suffix &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.binding, mutator);
|
||||
Walk(x.resultName, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V>
|
||||
template <typename V>
|
||||
void Walk(const TypeBoundProcedureStmt::WithInterface &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.interfaceName, visitor);
|
||||
|
@ -633,7 +636,7 @@ void Walk(const TypeBoundProcedureStmt::WithInterface &x, V &visitor) {
|
|||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M>
|
||||
template <typename M>
|
||||
void Walk(TypeBoundProcedureStmt::WithInterface &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.interfaceName, mutator);
|
||||
|
@ -642,7 +645,7 @@ void Walk(TypeBoundProcedureStmt::WithInterface &x, M &mutator) {
|
|||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V>
|
||||
template <typename V>
|
||||
void Walk(const TypeBoundProcedureStmt::WithoutInterface &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.attributes, visitor);
|
||||
|
@ -650,7 +653,7 @@ void Walk(const TypeBoundProcedureStmt::WithoutInterface &x, V &visitor) {
|
|||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M>
|
||||
template <typename M>
|
||||
void Walk(TypeBoundProcedureStmt::WithoutInterface &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.attributes, mutator);
|
||||
|
@ -658,7 +661,7 @@ void Walk(TypeBoundProcedureStmt::WithoutInterface &x, M &mutator) {
|
|||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const UseStmt &x, V &visitor) {
|
||||
template <typename V> void Walk(const UseStmt &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.nature, visitor);
|
||||
Walk(x.moduleName, visitor);
|
||||
|
@ -666,7 +669,7 @@ template<typename V> void Walk(const UseStmt &x, V &visitor) {
|
|||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(UseStmt &x, M &mutator) {
|
||||
template <typename M> void Walk(UseStmt &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.nature, mutator);
|
||||
Walk(x.moduleName, mutator);
|
||||
|
@ -674,7 +677,7 @@ template<typename M> void Walk(UseStmt &x, M &mutator) {
|
|||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const WriteStmt &x, V &visitor) {
|
||||
template <typename V> void Walk(const WriteStmt &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.iounit, visitor);
|
||||
Walk(x.format, visitor);
|
||||
|
@ -683,7 +686,7 @@ template<typename V> void Walk(const WriteStmt &x, V &visitor) {
|
|||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(WriteStmt &x, M &mutator) {
|
||||
template <typename M> void Walk(WriteStmt &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.iounit, mutator);
|
||||
Walk(x.format, mutator);
|
||||
|
@ -692,19 +695,19 @@ template<typename M> void Walk(WriteStmt &x, M &mutator) {
|
|||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const format::ControlEditDesc &x, V &visitor) {
|
||||
template <typename V> void Walk(const format::ControlEditDesc &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.kind, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(format::ControlEditDesc &x, M &mutator) {
|
||||
template <typename M> void Walk(format::ControlEditDesc &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.kind, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V>
|
||||
template <typename V>
|
||||
void Walk(const format::DerivedTypeDataEditDesc &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.type, visitor);
|
||||
|
@ -712,28 +715,29 @@ void Walk(const format::DerivedTypeDataEditDesc &x, V &visitor) {
|
|||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(format::DerivedTypeDataEditDesc &x, M &mutator) {
|
||||
template <typename M>
|
||||
void Walk(format::DerivedTypeDataEditDesc &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.type, mutator);
|
||||
Walk(x.parameters, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const format::FormatItem &x, V &visitor) {
|
||||
template <typename V> void Walk(const format::FormatItem &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.repeatCount, visitor);
|
||||
Walk(x.u, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(format::FormatItem &x, M &mutator) {
|
||||
template <typename M> void Walk(format::FormatItem &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.repeatCount, mutator);
|
||||
Walk(x.u, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V>
|
||||
template <typename V>
|
||||
void Walk(const format::FormatSpecification &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.items, visitor);
|
||||
|
@ -741,14 +745,14 @@ void Walk(const format::FormatSpecification &x, V &visitor) {
|
|||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(format::FormatSpecification &x, M &mutator) {
|
||||
template <typename M> void Walk(format::FormatSpecification &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.items, mutator);
|
||||
Walk(x.unlimitedItems, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V>
|
||||
template <typename V>
|
||||
void Walk(const format::IntrinsicTypeDataEditDesc &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.kind, visitor);
|
||||
|
@ -758,7 +762,7 @@ void Walk(const format::IntrinsicTypeDataEditDesc &x, V &visitor) {
|
|||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M>
|
||||
template <typename M>
|
||||
void Walk(format::IntrinsicTypeDataEditDesc &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.kind, mutator);
|
||||
|
@ -768,21 +772,21 @@ void Walk(format::IntrinsicTypeDataEditDesc &x, M &mutator) {
|
|||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const CompilerDirective &x, V &visitor) {
|
||||
template <typename V> void Walk(const CompilerDirective &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.source, visitor);
|
||||
Walk(x.u, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(CompilerDirective &x, M &mutator) {
|
||||
template <typename M> void Walk(CompilerDirective &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.source, mutator);
|
||||
Walk(x.u, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V>
|
||||
template <typename V>
|
||||
void Walk(const OmpLinearClause::WithModifier &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.modifier, visitor);
|
||||
|
@ -791,7 +795,7 @@ void Walk(const OmpLinearClause::WithModifier &x, V &visitor) {
|
|||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M> void Walk(OmpLinearClause::WithModifier &x, M &mutator) {
|
||||
template <typename M> void Walk(OmpLinearClause::WithModifier &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.modifier, mutator);
|
||||
Walk(x.names, mutator);
|
||||
|
@ -799,7 +803,7 @@ template<typename M> void Walk(OmpLinearClause::WithModifier &x, M &mutator) {
|
|||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V>
|
||||
template <typename V>
|
||||
void Walk(const OmpLinearClause::WithoutModifier &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.names, visitor);
|
||||
|
@ -807,7 +811,7 @@ void Walk(const OmpLinearClause::WithoutModifier &x, V &visitor) {
|
|||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename M>
|
||||
template <typename M>
|
||||
void Walk(OmpLinearClause::WithoutModifier &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.names, mutator);
|
||||
|
@ -815,5 +819,5 @@ void Walk(OmpLinearClause::WithoutModifier &x, M &mutator) {
|
|||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::parser
|
||||
#endif // FORTRAN_PARSER_PARSE_TREE_VISITOR_H_
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace Fortran::semantics {
|
|||
class Symbol;
|
||||
class DeclTypeSpec;
|
||||
class DerivedTypeSpec;
|
||||
}
|
||||
} // namespace Fortran::semantics
|
||||
|
||||
// Expressions in the parse tree have owning pointers that can be set to
|
||||
// type-checked generic expression representations by semantic analysis.
|
||||
|
@ -66,7 +66,7 @@ namespace Fortran::evaluate {
|
|||
struct GenericExprWrapper; // forward definition, wraps Expr<SomeType>
|
||||
struct GenericAssignmentWrapper; // forward definition, represent assignment
|
||||
class ProcedureRef; // forward definition, represents a CALL statement
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
|
||||
// Most non-template classes in this file use these default definitions
|
||||
// for their move constructor and move assignment operator=, and disable
|
||||
|
@ -97,7 +97,7 @@ class ProcedureRef; // forward definition, represents a CALL statement
|
|||
// Many classes below simply wrap a std::variant<> discriminated union,
|
||||
// which is conventionally named "u".
|
||||
#define UNION_CLASS_BOILERPLATE(classname) \
|
||||
template<typename A, typename = common::NoLvalue<A>> \
|
||||
template <typename A, typename = common::NoLvalue<A>> \
|
||||
classname(A &&x) : u(std::move(x)) {} \
|
||||
using UnionTrait = std::true_type; \
|
||||
BOILERPLATE(classname)
|
||||
|
@ -105,7 +105,7 @@ class ProcedureRef; // forward definition, represents a CALL statement
|
|||
// Many other classes below simply wrap a std::tuple<> structure, which
|
||||
// is conventionally named "t".
|
||||
#define TUPLE_CLASS_BOILERPLATE(classname) \
|
||||
template<typename... Ts, typename = common::NoLvalue<Ts...>> \
|
||||
template <typename... Ts, typename = common::NoLvalue<Ts...>> \
|
||||
classname(Ts &&... args) : t(std::move(args)...) {} \
|
||||
using TupleTrait = std::true_type; \
|
||||
BOILERPLATE(classname)
|
||||
|
@ -274,7 +274,7 @@ struct Verbatim {
|
|||
// R403 scalar-xyz -> xyz
|
||||
// These template class wrappers correspond to the Standard's modifiers
|
||||
// scalar-xyz, constant-xzy, int-xzy, default-char-xyz, & logical-xyz.
|
||||
template<typename A> struct Scalar {
|
||||
template <typename A> struct Scalar {
|
||||
using ConstraintTrait = std::true_type;
|
||||
Scalar(Scalar &&that) = default;
|
||||
Scalar(A &&that) : thing(std::move(that)) {}
|
||||
|
@ -282,7 +282,7 @@ template<typename A> struct Scalar {
|
|||
A thing;
|
||||
};
|
||||
|
||||
template<typename A> struct Constant {
|
||||
template <typename A> struct Constant {
|
||||
using ConstraintTrait = std::true_type;
|
||||
Constant(Constant &&that) = default;
|
||||
Constant(A &&that) : thing(std::move(that)) {}
|
||||
|
@ -290,7 +290,7 @@ template<typename A> struct Constant {
|
|||
A thing;
|
||||
};
|
||||
|
||||
template<typename A> struct Integer {
|
||||
template <typename A> struct Integer {
|
||||
using ConstraintTrait = std::true_type;
|
||||
Integer(Integer &&that) = default;
|
||||
Integer(A &&that) : thing(std::move(that)) {}
|
||||
|
@ -298,7 +298,7 @@ template<typename A> struct Integer {
|
|||
A thing;
|
||||
};
|
||||
|
||||
template<typename A> struct Logical {
|
||||
template <typename A> struct Logical {
|
||||
using ConstraintTrait = std::true_type;
|
||||
Logical(Logical &&that) = default;
|
||||
Logical(A &&that) : thing(std::move(that)) {}
|
||||
|
@ -306,7 +306,7 @@ template<typename A> struct Logical {
|
|||
A thing;
|
||||
};
|
||||
|
||||
template<typename A> struct DefaultChar {
|
||||
template <typename A> struct DefaultChar {
|
||||
using ConstraintTrait = std::true_type;
|
||||
DefaultChar(DefaultChar &&that) = default;
|
||||
DefaultChar(A &&that) : thing(std::move(that)) {}
|
||||
|
@ -332,12 +332,12 @@ using Label = std::uint64_t; // validated later, must be in [1..99999]
|
|||
|
||||
// A wrapper for xzy-stmt productions that are statements, so that
|
||||
// source provenances and labels have a uniform representation.
|
||||
template<typename A> struct UnlabeledStatement {
|
||||
template <typename A> struct UnlabeledStatement {
|
||||
explicit UnlabeledStatement(A &&s) : statement(std::move(s)) {}
|
||||
CharBlock source;
|
||||
A statement;
|
||||
};
|
||||
template<typename A> struct Statement : public UnlabeledStatement<A> {
|
||||
template <typename A> struct Statement : public UnlabeledStatement<A> {
|
||||
Statement(std::optional<long> &&lab, A &&s)
|
||||
: UnlabeledStatement<A>{std::move(s)}, label(std::move(lab)) {}
|
||||
std::optional<Label> label;
|
||||
|
@ -1210,7 +1210,7 @@ WRAPPER_CLASS(ArrayConstructor, AcSpec);
|
|||
// R1124 do-variable -> scalar-int-variable-name
|
||||
using DoVariable = Scalar<Integer<Name>>;
|
||||
|
||||
template<typename VAR, typename BOUND> struct LoopBounds {
|
||||
template <typename VAR, typename BOUND> struct LoopBounds {
|
||||
LoopBounds(LoopBounds &&that) = default;
|
||||
LoopBounds(
|
||||
VAR &&name, BOUND &&lower, BOUND &&upper, std::optional<BOUND> &&step)
|
||||
|
@ -1624,8 +1624,7 @@ struct Expr {
|
|||
using IntrinsicUnary::IntrinsicUnary;
|
||||
};
|
||||
|
||||
WRAPPER_CLASS(
|
||||
PercentLoc, common::Indirection<Variable>); // %LOC(v) extension
|
||||
WRAPPER_CLASS(PercentLoc, common::Indirection<Variable>); // %LOC(v) extension
|
||||
|
||||
struct DefinedUnary {
|
||||
TUPLE_CLASS_BOILERPLATE(DefinedUnary);
|
||||
|
@ -2948,7 +2947,7 @@ struct Only {
|
|||
struct UseStmt {
|
||||
BOILERPLATE(UseStmt);
|
||||
ENUM_CLASS(ModuleNature, Intrinsic, Non_Intrinsic) // R1410
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
UseStmt(std::optional<ModuleNature> &&nat, Name &&n, std::list<A> &&x)
|
||||
: nature(std::move(nat)), moduleName(std::move(n)), u(std::move(x)) {}
|
||||
std::optional<ModuleNature> nature;
|
||||
|
@ -3787,5 +3786,5 @@ struct OpenMPConstruct {
|
|||
OpenMPCriticalConstruct>
|
||||
u;
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::parser
|
||||
#endif // FORTRAN_PARSER_PARSE_TREE_H_
|
||||
|
|
|
@ -56,8 +56,8 @@ public:
|
|||
void Parse(llvm::raw_ostream &debugOutput);
|
||||
void ClearLog();
|
||||
|
||||
void EmitMessage(llvm::raw_ostream &o, const char *at, const std::string &message,
|
||||
bool echoSourceLine = false) const {
|
||||
void EmitMessage(llvm::raw_ostream &o, const char *at,
|
||||
const std::string &message, bool echoSourceLine = false) const {
|
||||
cooked_.allSources().EmitMessage(
|
||||
o, cooked_.GetProvenanceRange(CharBlock(at)), message, echoSourceLine);
|
||||
}
|
||||
|
@ -73,5 +73,5 @@ private:
|
|||
std::optional<Program> parseTree_;
|
||||
ParsingLog log_;
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::parser
|
||||
#endif // FORTRAN_PARSER_PARSING_H_
|
||||
|
|
|
@ -268,5 +268,5 @@ private:
|
|||
OffsetToProvenanceMappings provenanceMap_;
|
||||
ProvenanceRangeToOffsetMappings invertedMap_;
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::parser
|
||||
#endif // FORTRAN_PARSER_PROVENANCE_H_
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
// - A Unicode byte order mark is recognized if present.
|
||||
|
||||
#include "characters.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
|
||||
namespace llvm {
|
||||
class raw_ostream;
|
||||
|
@ -43,7 +43,9 @@ public:
|
|||
explicit SourceFile(Encoding e) : encoding_{e} {}
|
||||
~SourceFile();
|
||||
std::string path() const { return path_; }
|
||||
llvm::ArrayRef<char> content() const { return buf_->getBuffer().slice(bom_end_, buf_end_ - bom_end_); }
|
||||
llvm::ArrayRef<char> content() const {
|
||||
return buf_->getBuffer().slice(bom_end_, buf_end_ - bom_end_);
|
||||
}
|
||||
std::size_t bytes() const { return content().size(); }
|
||||
std::size_t lines() const { return lineStart_.size(); }
|
||||
Encoding encoding() const { return encoding_; }
|
||||
|
@ -64,9 +66,9 @@ private:
|
|||
std::string path_;
|
||||
std::unique_ptr<llvm::WritableMemoryBuffer> buf_;
|
||||
std::vector<std::size_t> lineStart_;
|
||||
std::size_t bom_end_ {0};
|
||||
std::size_t bom_end_{0};
|
||||
std::size_t buf_end_;
|
||||
Encoding encoding_;
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::parser
|
||||
#endif // FORTRAN_PARSER_SOURCE_H_
|
||||
|
|
|
@ -34,7 +34,7 @@ const Name &GetLastName(const AllocateObject &);
|
|||
// wrapped in a struct to avoid prototypes.
|
||||
struct UnwrapperHelper {
|
||||
|
||||
template<typename A, typename B> static const A *Unwrap(B *p) {
|
||||
template <typename A, typename B> static const A *Unwrap(B *p) {
|
||||
if (p) {
|
||||
return Unwrap<A>(*p);
|
||||
} else {
|
||||
|
@ -42,17 +42,17 @@ struct UnwrapperHelper {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename A, typename B, bool COPY>
|
||||
template <typename A, typename B, bool COPY>
|
||||
static const A *Unwrap(const common::Indirection<B, COPY> &x) {
|
||||
return Unwrap<A>(x.value());
|
||||
}
|
||||
|
||||
template<typename A, typename... Bs>
|
||||
template <typename A, typename... Bs>
|
||||
static const A *Unwrap(const std::variant<Bs...> &x) {
|
||||
return std::visit([](const auto &y) { return Unwrap<A>(y); }, x);
|
||||
}
|
||||
|
||||
template<typename A, typename B>
|
||||
template <typename A, typename B>
|
||||
static const A *Unwrap(const std::optional<B> &o) {
|
||||
if (o) {
|
||||
return Unwrap<A>(*o);
|
||||
|
@ -61,7 +61,7 @@ struct UnwrapperHelper {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename A, typename B> static const A *Unwrap(B &x) {
|
||||
template <typename A, typename B> static const A *Unwrap(B &x) {
|
||||
if constexpr (std::is_same_v<std::decay_t<A>, std::decay_t<B>>) {
|
||||
return &x;
|
||||
} else if constexpr (ConstraintTrait<B>) {
|
||||
|
@ -76,10 +76,10 @@ struct UnwrapperHelper {
|
|||
}
|
||||
};
|
||||
|
||||
template<typename A, typename B> const A *Unwrap(const B &x) {
|
||||
template <typename A, typename B> const A *Unwrap(const B &x) {
|
||||
return UnwrapperHelper::Unwrap<A>(x);
|
||||
}
|
||||
template<typename A, typename B> A *Unwrap(B &x) {
|
||||
template <typename A, typename B> A *Unwrap(B &x) {
|
||||
return const_cast<A *>(Unwrap<A, B>(const_cast<const B &>(x)));
|
||||
}
|
||||
|
||||
|
@ -87,5 +87,5 @@ template<typename A, typename B> A *Unwrap(B &x) {
|
|||
const CoindexedNamedObject *GetCoindexedNamedObject(const AllocateObject &);
|
||||
const CoindexedNamedObject *GetCoindexedNamedObject(const DataRef &);
|
||||
|
||||
}
|
||||
} // namespace Fortran::parser
|
||||
#endif // FORTRAN_PARSER_TOOLS_H_
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace Fortran::evaluate {
|
|||
struct GenericExprWrapper;
|
||||
struct GenericAssignmentWrapper;
|
||||
class ProcedureRef;
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
|
||||
namespace Fortran::parser {
|
||||
|
||||
|
@ -48,6 +48,6 @@ void Unparse(llvm::raw_ostream &out, const Program &program,
|
|||
Encoding encoding = Encoding::UTF_8, bool capitalizeKeywords = true,
|
||||
bool backslashEscapes = true, preStatementType *preStatement = nullptr,
|
||||
AnalyzedObjectsAsFortran * = nullptr);
|
||||
}
|
||||
} // namespace Fortran::parser
|
||||
|
||||
#endif
|
||||
|
|
|
@ -139,5 +139,5 @@ struct StructureComponents {
|
|||
using resultType = DataComponentDefStmt;
|
||||
static std::optional<DataComponentDefStmt> Parse(ParseState &);
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::parser
|
||||
#endif // FORTRAN_PARSER_USER_STATE_H_
|
||||
|
|
|
@ -50,5 +50,5 @@ std::string AttrToString(Attr attr);
|
|||
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &o, Attr attr);
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &o, const Attrs &attrs);
|
||||
}
|
||||
} // namespace Fortran::semantics
|
||||
#endif // FORTRAN_SEMANTICS_ATTR_H_
|
||||
|
|
|
@ -29,8 +29,8 @@ using namespace Fortran::parser::literals;
|
|||
|
||||
namespace Fortran::parser {
|
||||
struct SourceLocationFindingVisitor {
|
||||
template<typename A> bool Pre(const A &) { return true; }
|
||||
template<typename A> void Post(const A &) {}
|
||||
template <typename A> bool Pre(const A &) { return true; }
|
||||
template <typename A> void Post(const A &) {}
|
||||
bool Pre(const Expr &x) {
|
||||
source = x.source;
|
||||
return false;
|
||||
|
@ -51,7 +51,7 @@ struct SourceLocationFindingVisitor {
|
|||
source = x.source;
|
||||
return false;
|
||||
}
|
||||
template<typename A> bool Pre(const UnlabeledStatement<A> &stmt) {
|
||||
template <typename A> bool Pre(const UnlabeledStatement<A> &stmt) {
|
||||
source = stmt.source;
|
||||
return false;
|
||||
}
|
||||
|
@ -60,12 +60,12 @@ struct SourceLocationFindingVisitor {
|
|||
CharBlock source;
|
||||
};
|
||||
|
||||
template<typename A> CharBlock FindSourceLocation(const A &x) {
|
||||
template <typename A> CharBlock FindSourceLocation(const A &x) {
|
||||
SourceLocationFindingVisitor visitor;
|
||||
Walk(x, visitor);
|
||||
return visitor.source;
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::parser
|
||||
|
||||
using namespace Fortran::parser::literals;
|
||||
|
||||
|
@ -89,10 +89,10 @@ struct SetExprHelper {
|
|||
}
|
||||
void Set(const parser::Expr &x) { Set(x.typedExpr); }
|
||||
void Set(const parser::Variable &x) { Set(x.typedExpr); }
|
||||
template<typename T> void Set(const common::Indirection<T> &x) {
|
||||
template <typename T> void Set(const common::Indirection<T> &x) {
|
||||
Set(x.value());
|
||||
}
|
||||
template<typename T> void Set(const T &x) {
|
||||
template <typename T> void Set(const T &x) {
|
||||
if constexpr (ConstraintTrait<T>) {
|
||||
Set(x.thing);
|
||||
} else if constexpr (WrapperTrait<T>) {
|
||||
|
@ -103,11 +103,11 @@ struct SetExprHelper {
|
|||
GenericExprWrapper expr_;
|
||||
};
|
||||
|
||||
template<typename T> void ResetExpr(const T &x) {
|
||||
template <typename T> void ResetExpr(const T &x) {
|
||||
SetExprHelper{GenericExprWrapper{/* error indicator */}}.Set(x);
|
||||
}
|
||||
|
||||
template<typename T> void SetExpr(const T &x, Expr<SomeType> &&expr) {
|
||||
template <typename T> void SetExpr(const T &x, Expr<SomeType> &&expr) {
|
||||
SetExprHelper{GenericExprWrapper{std::move(expr)}}.Set(x);
|
||||
}
|
||||
|
||||
|
@ -128,11 +128,11 @@ public:
|
|||
return foldingContext_.messages();
|
||||
}
|
||||
|
||||
template<typename... A> parser::Message *Say(A &&... args) {
|
||||
template <typename... A> parser::Message *Say(A &&... args) {
|
||||
return GetContextualMessages().Say(std::forward<A>(args)...);
|
||||
}
|
||||
|
||||
template<typename T, typename... A>
|
||||
template <typename T, typename... A>
|
||||
parser::Message *SayAt(const T &parsed, A &&... args) {
|
||||
return Say(parser::FindSourceLocation(parsed), std::forward<A>(args)...);
|
||||
}
|
||||
|
@ -156,10 +156,10 @@ public:
|
|||
MaybeExpr Analyze(const parser::Variable &);
|
||||
MaybeExpr Analyze(const parser::Designator &);
|
||||
|
||||
template<typename A> MaybeExpr Analyze(const common::Indirection<A> &x) {
|
||||
template <typename A> MaybeExpr Analyze(const common::Indirection<A> &x) {
|
||||
return Analyze(x.value());
|
||||
}
|
||||
template<typename A> MaybeExpr Analyze(const std::optional<A> &x) {
|
||||
template <typename A> MaybeExpr Analyze(const std::optional<A> &x) {
|
||||
if (x) {
|
||||
return Analyze(*x);
|
||||
} else {
|
||||
|
@ -168,7 +168,7 @@ public:
|
|||
}
|
||||
|
||||
// Implement constraint-checking wrappers from the Fortran grammar.
|
||||
template<typename A> MaybeExpr Analyze(const parser::Scalar<A> &x) {
|
||||
template <typename A> MaybeExpr Analyze(const parser::Scalar<A> &x) {
|
||||
auto result{Analyze(x.thing)};
|
||||
if (result) {
|
||||
if (int rank{result->Rank()}; rank != 0) {
|
||||
|
@ -180,7 +180,7 @@ public:
|
|||
}
|
||||
return result;
|
||||
}
|
||||
template<typename A> MaybeExpr Analyze(const parser::Constant<A> &x) {
|
||||
template <typename A> MaybeExpr Analyze(const parser::Constant<A> &x) {
|
||||
auto restorer{
|
||||
GetFoldingContext().messages().SetLocation(FindSourceLocation(x))};
|
||||
auto result{Analyze(x.thing)};
|
||||
|
@ -197,7 +197,7 @@ public:
|
|||
}
|
||||
return result;
|
||||
}
|
||||
template<typename A> MaybeExpr Analyze(const parser::Integer<A> &x) {
|
||||
template <typename A> MaybeExpr Analyze(const parser::Integer<A> &x) {
|
||||
auto result{Analyze(x.thing)};
|
||||
if (!EnforceTypeConstraint(
|
||||
parser::FindSourceLocation(x), result, TypeCategory::Integer)) {
|
||||
|
@ -206,7 +206,7 @@ public:
|
|||
}
|
||||
return result;
|
||||
}
|
||||
template<typename A> MaybeExpr Analyze(const parser::Logical<A> &x) {
|
||||
template <typename A> MaybeExpr Analyze(const parser::Logical<A> &x) {
|
||||
auto result{Analyze(x.thing)};
|
||||
if (!EnforceTypeConstraint(
|
||||
parser::FindSourceLocation(x), result, TypeCategory::Logical)) {
|
||||
|
@ -215,7 +215,7 @@ public:
|
|||
}
|
||||
return result;
|
||||
}
|
||||
template<typename A> MaybeExpr Analyze(const parser::DefaultChar<A> &x) {
|
||||
template <typename A> MaybeExpr Analyze(const parser::DefaultChar<A> &x) {
|
||||
auto result{Analyze(x.thing)};
|
||||
if (!EnforceTypeConstraint(parser::FindSourceLocation(x), result,
|
||||
TypeCategory::Character, true /* default kind */)) {
|
||||
|
@ -283,10 +283,10 @@ private:
|
|||
MaybeExpr Analyze(const parser::Expr::EQV &);
|
||||
MaybeExpr Analyze(const parser::Expr::NEQV &);
|
||||
MaybeExpr Analyze(const parser::Expr::DefinedBinary &);
|
||||
template<typename A> MaybeExpr Analyze(const A &x) {
|
||||
template <typename A> MaybeExpr Analyze(const A &x) {
|
||||
return Analyze(x.u); // default case
|
||||
}
|
||||
template<typename... As> MaybeExpr Analyze(const std::variant<As...> &u) {
|
||||
template <typename... As> MaybeExpr Analyze(const std::variant<As...> &u) {
|
||||
return std::visit(
|
||||
[&](const auto &x) {
|
||||
using Ty = std::decay_t<decltype(x)>;
|
||||
|
@ -321,8 +321,8 @@ private:
|
|||
// Analysis subroutines
|
||||
int AnalyzeKindParam(
|
||||
const std::optional<parser::KindParam> &, int defaultKind);
|
||||
template<typename PARSED> MaybeExpr ExprOrVariable(const PARSED &);
|
||||
template<typename PARSED> MaybeExpr IntLiteralConstant(const PARSED &);
|
||||
template <typename PARSED> MaybeExpr ExprOrVariable(const PARSED &);
|
||||
template <typename PARSED> MaybeExpr IntLiteralConstant(const PARSED &);
|
||||
MaybeExpr AnalyzeString(std::string &&, int kind);
|
||||
std::optional<Expr<SubscriptInteger>> AsSubscript(MaybeExpr &&);
|
||||
std::optional<Expr<SubscriptInteger>> TripletPart(
|
||||
|
@ -370,7 +370,7 @@ private:
|
|||
MaybeExpr MakeFunctionRef(
|
||||
parser::CharBlock, ProcedureDesignator &&, ActualArguments &&);
|
||||
MaybeExpr MakeFunctionRef(parser::CharBlock intrinsic, ActualArguments &&);
|
||||
template<typename T> T Fold(T &&expr) {
|
||||
template <typename T> T Fold(T &&expr) {
|
||||
return evaluate::Fold(foldingContext_, std::move(expr));
|
||||
}
|
||||
|
||||
|
@ -385,12 +385,12 @@ inline bool AreConformable(int leftRank, int rightRank) {
|
|||
return leftRank == 0 || rightRank == 0 || leftRank == rightRank;
|
||||
}
|
||||
|
||||
template<typename L, typename R>
|
||||
template <typename L, typename R>
|
||||
bool AreConformable(const L &left, const R &right) {
|
||||
return AreConformable(left.Rank(), right.Rank());
|
||||
}
|
||||
|
||||
template<typename L, typename R>
|
||||
template <typename L, typename R>
|
||||
void ConformabilityCheck(
|
||||
parser::ContextualMessages &context, const L &left, const R &right) {
|
||||
if (!AreConformable(left, right)) {
|
||||
|
@ -403,7 +403,7 @@ void ConformabilityCheck(
|
|||
namespace Fortran::semantics {
|
||||
|
||||
// Semantic analysis of one expression, variable, or designator.
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
std::optional<evaluate::Expr<evaluate::SomeType>> AnalyzeExpr(
|
||||
SemanticsContext &context, const A &expr) {
|
||||
return evaluate::ExpressionAnalyzer{context}.Analyze(expr);
|
||||
|
@ -426,8 +426,8 @@ class ExprChecker {
|
|||
public:
|
||||
explicit ExprChecker(SemanticsContext &);
|
||||
|
||||
template<typename A> bool Pre(const A &) { return true; }
|
||||
template<typename A> void Post(const A &) {}
|
||||
template <typename A> bool Pre(const A &) { return true; }
|
||||
template <typename A> void Post(const A &) {}
|
||||
bool Walk(const parser::Program &);
|
||||
|
||||
bool Pre(const parser::Expr &x) {
|
||||
|
@ -452,23 +452,23 @@ public:
|
|||
}
|
||||
bool Pre(const parser::DataStmtConstant &);
|
||||
|
||||
template<typename A> bool Pre(const parser::Scalar<A> &x) {
|
||||
template <typename A> bool Pre(const parser::Scalar<A> &x) {
|
||||
AnalyzeExpr(context_, x);
|
||||
return false;
|
||||
}
|
||||
template<typename A> bool Pre(const parser::Constant<A> &x) {
|
||||
template <typename A> bool Pre(const parser::Constant<A> &x) {
|
||||
AnalyzeExpr(context_, x);
|
||||
return false;
|
||||
}
|
||||
template<typename A> bool Pre(const parser::Integer<A> &x) {
|
||||
template <typename A> bool Pre(const parser::Integer<A> &x) {
|
||||
AnalyzeExpr(context_, x);
|
||||
return false;
|
||||
}
|
||||
template<typename A> bool Pre(const parser::Logical<A> &x) {
|
||||
template <typename A> bool Pre(const parser::Logical<A> &x) {
|
||||
AnalyzeExpr(context_, x);
|
||||
return false;
|
||||
}
|
||||
template<typename A> bool Pre(const parser::DefaultChar<A> &x) {
|
||||
template <typename A> bool Pre(const parser::DefaultChar<A> &x) {
|
||||
AnalyzeExpr(context_, x);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,8 @@ class SemanticsContext;
|
|||
struct EquivalenceObject {
|
||||
EquivalenceObject(Symbol &symbol, std::vector<ConstantSubscript> subscripts,
|
||||
std::optional<ConstantSubscript> substringStart)
|
||||
: symbol{symbol}, subscripts{subscripts}, substringStart{substringStart} {}
|
||||
: symbol{symbol}, subscripts{subscripts}, substringStart{substringStart} {
|
||||
}
|
||||
bool operator==(const EquivalenceObject &) const;
|
||||
bool operator<(const EquivalenceObject &) const;
|
||||
std::string AsFortran() const;
|
||||
|
@ -127,13 +128,13 @@ public:
|
|||
return try_emplace(name, attrs, UnknownDetails());
|
||||
}
|
||||
/// Make a Symbol with provided details.
|
||||
template<typename D>
|
||||
template <typename D>
|
||||
common::IfNoLvalue<std::pair<iterator, bool>, D> try_emplace(
|
||||
const SourceName &name, D &&details) {
|
||||
return try_emplace(name, Attrs(), std::move(details));
|
||||
}
|
||||
/// Make a Symbol with attrs and details
|
||||
template<typename D>
|
||||
template <typename D>
|
||||
common::IfNoLvalue<std::pair<iterator, bool>, D> try_emplace(
|
||||
const SourceName &name, Attrs attrs, D &&details) {
|
||||
Symbol &symbol{MakeSymbol(name, attrs, std::move(details))};
|
||||
|
@ -153,7 +154,7 @@ public:
|
|||
Symbol *FindCommonBlock(const SourceName &);
|
||||
|
||||
/// Make a Symbol but don't add it to the scope.
|
||||
template<typename D>
|
||||
template <typename D>
|
||||
common::IfNoLvalue<Symbol &, D> MakeSymbol(
|
||||
const SourceName &name, Attrs attrs, D &&details) {
|
||||
return allSymbols.Make(*this, name, attrs, std::move(details));
|
||||
|
@ -240,5 +241,5 @@ private:
|
|||
|
||||
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Scope &);
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::semantics
|
||||
#endif // FORTRAN_SEMANTICS_SCOPE_H_
|
||||
|
|
|
@ -43,7 +43,7 @@ struct SelectRankConstruct;
|
|||
struct SelectTypeConstruct;
|
||||
struct Variable;
|
||||
struct WhereConstruct;
|
||||
}
|
||||
} // namespace Fortran::parser
|
||||
|
||||
namespace Fortran::semantics {
|
||||
|
||||
|
@ -133,18 +133,18 @@ public:
|
|||
bool HasError(const parser::Name &);
|
||||
void SetError(Symbol &, bool = true);
|
||||
|
||||
template<typename... A> parser::Message &Say(A &&... args) {
|
||||
template <typename... A> parser::Message &Say(A &&... args) {
|
||||
CHECK(location_);
|
||||
return messages_.Say(*location_, std::forward<A>(args)...);
|
||||
}
|
||||
template<typename... A>
|
||||
template <typename... A>
|
||||
parser::Message &Say(parser::CharBlock at, A &&... args) {
|
||||
return messages_.Say(at, std::forward<A>(args)...);
|
||||
}
|
||||
parser::Message &Say(parser::Message &&msg) {
|
||||
return messages_.Say(std::move(msg));
|
||||
}
|
||||
template<typename... A>
|
||||
template <typename... A>
|
||||
void SayWithDecl(const Symbol &symbol, const parser::CharBlock &at,
|
||||
parser::MessageFixedText &&msg, A &&... args) {
|
||||
auto &message{Say(at, std::move(msg), args...)};
|
||||
|
@ -155,7 +155,7 @@ public:
|
|||
Scope &FindScope(parser::CharBlock);
|
||||
|
||||
const ConstructStack &constructStack() const { return constructStack_; }
|
||||
template<typename N> void PushConstruct(const N &node) {
|
||||
template <typename N> void PushConstruct(const N &node) {
|
||||
constructStack_.emplace_back(&node);
|
||||
}
|
||||
void PopConstruct();
|
||||
|
@ -225,8 +225,8 @@ private:
|
|||
|
||||
// Base class for semantics checkers.
|
||||
struct BaseChecker {
|
||||
template<typename N> void Enter(const N &) {}
|
||||
template<typename N> void Leave(const N &) {}
|
||||
template <typename N> void Enter(const N &) {}
|
||||
template <typename N> void Leave(const N &) {}
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::semantics
|
||||
#endif
|
||||
|
|
|
@ -386,7 +386,7 @@ struct GenericKind {
|
|||
ENUM_CLASS(DefinedIo, // defined io
|
||||
ReadFormatted, ReadUnformatted, WriteFormatted, WriteUnformatted)
|
||||
GenericKind() : u{OtherKind::Name} {}
|
||||
template<typename T> GenericKind(const T &x) { u = x; }
|
||||
template <typename T> GenericKind(const T &x) { u = x; }
|
||||
bool IsName() const { return Is(OtherKind::Name); }
|
||||
bool IsAssignment() const { return Is(OtherKind::Assignment); }
|
||||
bool IsDefinedOperator() const { return Is(OtherKind::DefinedOp); }
|
||||
|
@ -398,7 +398,9 @@ struct GenericKind {
|
|||
u;
|
||||
|
||||
private:
|
||||
template<typename T> bool Has() const { return std::holds_alternative<T>(u); }
|
||||
template <typename T> bool Has() const {
|
||||
return std::holds_alternative<T>(u);
|
||||
}
|
||||
bool Is(OtherKind) const;
|
||||
};
|
||||
|
||||
|
@ -501,21 +503,21 @@ public:
|
|||
void ReplaceName(const SourceName &);
|
||||
|
||||
// Does symbol have this type of details?
|
||||
template<typename D> bool has() const {
|
||||
template <typename D> bool has() const {
|
||||
return std::holds_alternative<D>(details_);
|
||||
}
|
||||
|
||||
// Return a non-owning pointer to details if it is type D, else nullptr.
|
||||
template<typename D> D *detailsIf() { return std::get_if<D>(&details_); }
|
||||
template<typename D> const D *detailsIf() const {
|
||||
template <typename D> D *detailsIf() { return std::get_if<D>(&details_); }
|
||||
template <typename D> const D *detailsIf() const {
|
||||
return std::get_if<D>(&details_);
|
||||
}
|
||||
|
||||
// Return a reference to the details which must be of type D.
|
||||
template<typename D> D &get() {
|
||||
template <typename D> D &get() {
|
||||
return const_cast<D &>(const_cast<const Symbol *>(this)->get<D>());
|
||||
}
|
||||
template<typename D> const D &get() const {
|
||||
template <typename D> const D &get() const {
|
||||
const auto *p{detailsIf<D>()};
|
||||
CHECK(p);
|
||||
return *p;
|
||||
|
@ -582,12 +584,12 @@ public:
|
|||
bool IsSubprogram() const;
|
||||
bool IsFromModFile() const;
|
||||
bool HasExplicitInterface() const {
|
||||
return std::visit(
|
||||
common::visitors{
|
||||
return std::visit(common::visitors{
|
||||
[](const SubprogramDetails &) { return true; },
|
||||
[](const SubprogramNameDetails &) { return true; },
|
||||
[&](const ProcEntityDetails &x) {
|
||||
return attrs_.test(Attr::INTRINSIC) || x.HasExplicitInterface();
|
||||
return attrs_.test(Attr::INTRINSIC) ||
|
||||
x.HasExplicitInterface();
|
||||
},
|
||||
[](const ProcBindingDetails &x) {
|
||||
return x.symbol().HasExplicitInterface();
|
||||
|
@ -679,8 +681,8 @@ private:
|
|||
// can be overridden.
|
||||
const Symbol *GetParentComponent(const Scope * = nullptr) const;
|
||||
|
||||
template<std::size_t> friend class Symbols;
|
||||
template<class, std::size_t> friend struct std::array;
|
||||
template <std::size_t> friend class Symbols;
|
||||
template <class, std::size_t> friend struct std::array;
|
||||
};
|
||||
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &, Symbol::Flag);
|
||||
|
@ -688,7 +690,7 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &, Symbol::Flag);
|
|||
// Manage memory for all symbols. BLOCK_SIZE symbols at a time are allocated.
|
||||
// Make() returns a reference to the next available one. They are never
|
||||
// deleted.
|
||||
template<std::size_t BLOCK_SIZE> class Symbols {
|
||||
template <std::size_t BLOCK_SIZE> class Symbols {
|
||||
public:
|
||||
Symbol &Make(const Scope &owner, const SourceName &name, const Attrs &attrs,
|
||||
Details &&details) {
|
||||
|
@ -733,5 +735,5 @@ inline bool ProcEntityDetails::HasExplicitInterface() const {
|
|||
inline bool operator<(SymbolRef x, SymbolRef y) { return *x < *y; }
|
||||
using SymbolSet = std::set<SymbolRef>;
|
||||
|
||||
}
|
||||
} // namespace Fortran::semantics
|
||||
#endif // FORTRAN_SEMANTICS_SYMBOL_H_
|
||||
|
|
|
@ -211,12 +211,12 @@ const Symbol *FindSeparateModuleSubprogramInterface(const Symbol *);
|
|||
// diagnostic purposes if so.
|
||||
const Symbol *FindExternallyVisibleObject(const Symbol &, const Scope &);
|
||||
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
const Symbol *FindExternallyVisibleObject(const A &, const Scope &) {
|
||||
return nullptr; // default base case
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
const Symbol *FindExternallyVisibleObject(
|
||||
const evaluate::Designator<T> &designator, const Scope &scope) {
|
||||
if (const Symbol * symbol{designator.GetBaseObject().symbol()}) {
|
||||
|
@ -229,7 +229,7 @@ const Symbol *FindExternallyVisibleObject(
|
|||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
const Symbol *FindExternallyVisibleObject(
|
||||
const evaluate::Expr<T> &expr, const Scope &scope) {
|
||||
return std::visit(
|
||||
|
@ -247,13 +247,13 @@ bool ExprTypeKindIsDefault(
|
|||
struct GetExprHelper {
|
||||
const SomeExpr *Get(const parser::Expr &);
|
||||
const SomeExpr *Get(const parser::Variable &);
|
||||
template<typename T> const SomeExpr *Get(const common::Indirection<T> &x) {
|
||||
template <typename T> const SomeExpr *Get(const common::Indirection<T> &x) {
|
||||
return Get(x.value());
|
||||
}
|
||||
template<typename T> const SomeExpr *Get(const std::optional<T> &x) {
|
||||
template <typename T> const SomeExpr *Get(const std::optional<T> &x) {
|
||||
return x ? Get(*x) : nullptr;
|
||||
}
|
||||
template<typename T> const SomeExpr *Get(const T &x) {
|
||||
template <typename T> const SomeExpr *Get(const T &x) {
|
||||
if constexpr (ConstraintTrait<T>) {
|
||||
return Get(x.thing);
|
||||
} else if constexpr (WrapperTrait<T>) {
|
||||
|
@ -264,7 +264,7 @@ struct GetExprHelper {
|
|||
}
|
||||
};
|
||||
|
||||
template<typename T> const SomeExpr *GetExpr(const T &x) {
|
||||
template <typename T> const SomeExpr *GetExpr(const T &x) {
|
||||
return GetExprHelper{}.Get(x);
|
||||
}
|
||||
|
||||
|
@ -272,7 +272,7 @@ const evaluate::Assignment *GetAssignment(const parser::AssignmentStmt &);
|
|||
const evaluate::Assignment *GetAssignment(
|
||||
const parser::PointerAssignmentStmt &);
|
||||
|
||||
template<typename T> std::optional<std::int64_t> GetIntValue(const T &x) {
|
||||
template <typename T> std::optional<std::int64_t> GetIntValue(const T &x) {
|
||||
if (const auto *expr{GetExpr(x)}) {
|
||||
return evaluate::ToInt64(*expr);
|
||||
} else {
|
||||
|
@ -280,7 +280,7 @@ template<typename T> std::optional<std::int64_t> GetIntValue(const T &x) {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename T> bool IsZero(const T &expr) {
|
||||
template <typename T> bool IsZero(const T &expr) {
|
||||
auto value{GetIntValue(expr)};
|
||||
return value && *value == 0;
|
||||
}
|
||||
|
@ -347,7 +347,7 @@ template<typename T> bool IsZero(const T &expr) {
|
|||
|
||||
ENUM_CLASS(ComponentKind, Ordered, Direct, Ultimate, Potential, Scope)
|
||||
|
||||
template<ComponentKind componentKind> class ComponentIterator {
|
||||
template <ComponentKind componentKind> class ComponentIterator {
|
||||
public:
|
||||
ComponentIterator(const DerivedTypeSpec &derived) : derived_{derived} {}
|
||||
class const_iterator {
|
||||
|
@ -496,15 +496,15 @@ public:
|
|||
LabelEnforce(SemanticsContext &context, std::set<parser::Label> &&labels,
|
||||
parser::CharBlock constructSourcePosition, const char *construct)
|
||||
: context_{context}, labels_{labels},
|
||||
constructSourcePosition_{constructSourcePosition}, construct_{construct} {
|
||||
}
|
||||
template<typename T> bool Pre(const T &) { return true; }
|
||||
template<typename T> bool Pre(const parser::Statement<T> &statement) {
|
||||
constructSourcePosition_{constructSourcePosition}, construct_{
|
||||
construct} {}
|
||||
template <typename T> bool Pre(const T &) { return true; }
|
||||
template <typename T> bool Pre(const parser::Statement<T> &statement) {
|
||||
currentStatementSourcePosition_ = statement.source;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T> void Post(const T &) {}
|
||||
template <typename T> void Post(const T &) {}
|
||||
|
||||
void Post(const parser::GotoStmt &gotoStmt);
|
||||
void Post(const parser::ComputedGotoStmt &computedGotoStmt);
|
||||
|
@ -529,5 +529,5 @@ private:
|
|||
parser::CharBlock stmtLocation, parser::MessageFormattedText &&message,
|
||||
parser::CharBlock constructLocation);
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::semantics
|
||||
#endif // FORTRAN_SEMANTICS_TOOLS_H_
|
||||
|
|
|
@ -130,7 +130,8 @@ protected:
|
|||
private:
|
||||
TypeCategory category_;
|
||||
KindExpr kind_;
|
||||
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const IntrinsicTypeSpec &x);
|
||||
friend llvm::raw_ostream &operator<<(
|
||||
llvm::raw_ostream &os, const IntrinsicTypeSpec &x);
|
||||
};
|
||||
|
||||
class NumericTypeSpec : public IntrinsicTypeSpec {
|
||||
|
@ -157,7 +158,8 @@ public:
|
|||
|
||||
private:
|
||||
ParamValue length_;
|
||||
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const CharacterTypeSpec &x);
|
||||
friend llvm::raw_ostream &operator<<(
|
||||
llvm::raw_ostream &os, const CharacterTypeSpec &x);
|
||||
};
|
||||
|
||||
class ShapeSpec {
|
||||
|
@ -224,7 +226,7 @@ struct ArraySpec : public std::vector<ShapeSpec> {
|
|||
|
||||
private:
|
||||
// Check non-empty and predicate is true for each element.
|
||||
template<typename P> bool CheckAll(P predicate) const {
|
||||
template <typename P> bool CheckAll(P predicate) const {
|
||||
return !empty() && std::all_of(begin(), end(), predicate);
|
||||
}
|
||||
};
|
||||
|
@ -293,7 +295,8 @@ private:
|
|||
bool instantiated_{false};
|
||||
RawParameters rawParameters_;
|
||||
ParameterMapType parameters_;
|
||||
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &, const DerivedTypeSpec &);
|
||||
friend llvm::raw_ostream &operator<<(
|
||||
llvm::raw_ostream &, const DerivedTypeSpec &);
|
||||
};
|
||||
|
||||
class DeclTypeSpec {
|
||||
|
@ -351,18 +354,24 @@ public:
|
|||
IntrinsicTypeSpec *AsIntrinsic();
|
||||
const IntrinsicTypeSpec *AsIntrinsic() const {
|
||||
switch (category_) {
|
||||
case Numeric: return &std::get<NumericTypeSpec>(typeSpec_);
|
||||
case Logical: return &std::get<LogicalTypeSpec>(typeSpec_);
|
||||
case Character: return &std::get<CharacterTypeSpec>(typeSpec_);
|
||||
default: return nullptr;
|
||||
case Numeric:
|
||||
return &std::get<NumericTypeSpec>(typeSpec_);
|
||||
case Logical:
|
||||
return &std::get<LogicalTypeSpec>(typeSpec_);
|
||||
case Character:
|
||||
return &std::get<CharacterTypeSpec>(typeSpec_);
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const DerivedTypeSpec *AsDerived() const {
|
||||
switch (category_) {
|
||||
case TypeDerived:
|
||||
case ClassDerived: return &std::get<DerivedTypeSpec>(typeSpec_);
|
||||
default: return nullptr;
|
||||
case ClassDerived:
|
||||
return &std::get<DerivedTypeSpec>(typeSpec_);
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -390,5 +399,5 @@ private:
|
|||
const Symbol *symbol_{nullptr};
|
||||
const DeclTypeSpec *type_{nullptr};
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::semantics
|
||||
#endif // FORTRAN_SEMANTICS_TYPE_H_
|
||||
|
|
|
@ -22,15 +22,22 @@ std::vector<const char *> LanguageFeatureControl::GetNames(
|
|||
if (IsEnabled(LanguageFeature::LogicalAbbreviations)) {
|
||||
switch (opr) {
|
||||
SWITCH_COVERS_ALL_CASES
|
||||
case LogicalOperator::And: result.push_back(".a."); break;
|
||||
case LogicalOperator::Or: result.push_back(".o."); break;
|
||||
case LogicalOperator::Not: result.push_back(".n."); break;
|
||||
case LogicalOperator::And:
|
||||
result.push_back(".a.");
|
||||
break;
|
||||
case LogicalOperator::Or:
|
||||
result.push_back(".o.");
|
||||
break;
|
||||
case LogicalOperator::Not:
|
||||
result.push_back(".n.");
|
||||
break;
|
||||
case LogicalOperator::Neqv:
|
||||
if (IsEnabled(LanguageFeature::XOROperator)) {
|
||||
result.push_back(".x.");
|
||||
}
|
||||
break;
|
||||
case LogicalOperator::Eqv: break;
|
||||
case LogicalOperator::Eqv:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -40,11 +47,16 @@ std::vector<const char *> LanguageFeatureControl::GetNames(
|
|||
RelationalOperator opr) const {
|
||||
switch (opr) {
|
||||
SWITCH_COVERS_ALL_CASES
|
||||
case RelationalOperator::LT: return {".lt.", "<"};
|
||||
case RelationalOperator::LE: return {".le.", "<="};
|
||||
case RelationalOperator::EQ: return {".eq.", "=="};
|
||||
case RelationalOperator::GE: return {".ge.", ">="};
|
||||
case RelationalOperator::GT: return {".gt.", ">"};
|
||||
case RelationalOperator::LT:
|
||||
return {".lt.", "<"};
|
||||
case RelationalOperator::LE:
|
||||
return {".le.", "<="};
|
||||
case RelationalOperator::EQ:
|
||||
return {".eq.", "=="};
|
||||
case RelationalOperator::GE:
|
||||
return {".ge.", ">="};
|
||||
case RelationalOperator::GT:
|
||||
return {".gt.", ">"};
|
||||
case RelationalOperator::NE:
|
||||
if (IsEnabled(LanguageFeature::AlternativeNE)) {
|
||||
return {".ne.", "/=", "<>"};
|
||||
|
@ -54,4 +66,4 @@ std::vector<const char *> LanguageFeatureControl::GetNames(
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
|
|
|
@ -13,35 +13,51 @@ namespace Fortran::common {
|
|||
const char *AsFortran(NumericOperator opr) {
|
||||
switch (opr) {
|
||||
SWITCH_COVERS_ALL_CASES
|
||||
case NumericOperator::Power: return "**";
|
||||
case NumericOperator::Multiply: return "*";
|
||||
case NumericOperator::Divide: return "/";
|
||||
case NumericOperator::Add: return "+";
|
||||
case NumericOperator::Subtract: return "-";
|
||||
case NumericOperator::Power:
|
||||
return "**";
|
||||
case NumericOperator::Multiply:
|
||||
return "*";
|
||||
case NumericOperator::Divide:
|
||||
return "/";
|
||||
case NumericOperator::Add:
|
||||
return "+";
|
||||
case NumericOperator::Subtract:
|
||||
return "-";
|
||||
}
|
||||
}
|
||||
|
||||
const char *AsFortran(LogicalOperator opr) {
|
||||
switch (opr) {
|
||||
SWITCH_COVERS_ALL_CASES
|
||||
case LogicalOperator::And: return ".and.";
|
||||
case LogicalOperator::Or: return ".or.";
|
||||
case LogicalOperator::Eqv: return ".eqv.";
|
||||
case LogicalOperator::Neqv: return ".neqv.";
|
||||
case LogicalOperator::Not: return ".not.";
|
||||
case LogicalOperator::And:
|
||||
return ".and.";
|
||||
case LogicalOperator::Or:
|
||||
return ".or.";
|
||||
case LogicalOperator::Eqv:
|
||||
return ".eqv.";
|
||||
case LogicalOperator::Neqv:
|
||||
return ".neqv.";
|
||||
case LogicalOperator::Not:
|
||||
return ".not.";
|
||||
}
|
||||
}
|
||||
|
||||
const char *AsFortran(RelationalOperator opr) {
|
||||
switch (opr) {
|
||||
SWITCH_COVERS_ALL_CASES
|
||||
case RelationalOperator::LT: return "<";
|
||||
case RelationalOperator::LE: return "<=";
|
||||
case RelationalOperator::EQ: return "==";
|
||||
case RelationalOperator::NE: return "/=";
|
||||
case RelationalOperator::GE: return ">=";
|
||||
case RelationalOperator::GT: return ">";
|
||||
case RelationalOperator::LT:
|
||||
return "<";
|
||||
case RelationalOperator::LE:
|
||||
return "<=";
|
||||
case RelationalOperator::EQ:
|
||||
return "==";
|
||||
case RelationalOperator::NE:
|
||||
return "/=";
|
||||
case RelationalOperator::GE:
|
||||
return ">=";
|
||||
case RelationalOperator::GT:
|
||||
return ">";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
|
|
|
@ -67,12 +67,18 @@ IntrinsicTypeDefaultKinds &IntrinsicTypeDefaultKinds::set_defaultLogicalKind(
|
|||
|
||||
int IntrinsicTypeDefaultKinds::GetDefaultKind(TypeCategory category) const {
|
||||
switch (category) {
|
||||
case TypeCategory::Integer: return defaultIntegerKind_;
|
||||
case TypeCategory::Integer:
|
||||
return defaultIntegerKind_;
|
||||
case TypeCategory::Real:
|
||||
case TypeCategory::Complex: return defaultRealKind_;
|
||||
case TypeCategory::Character: return defaultCharacterKind_;
|
||||
case TypeCategory::Logical: return defaultLogicalKind_;
|
||||
default: CRASH_NO_CASE; return 0;
|
||||
case TypeCategory::Complex:
|
||||
return defaultRealKind_;
|
||||
case TypeCategory::Character:
|
||||
return defaultCharacterKind_;
|
||||
case TypeCategory::Logical:
|
||||
return defaultLogicalKind_;
|
||||
default:
|
||||
CRASH_NO_CASE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
|
|
|
@ -40,4 +40,4 @@ std::string EnumIndexToString(int index, const char *enumNames) {
|
|||
}
|
||||
return std::string(p, q - p);
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::common
|
||||
|
|
|
@ -40,7 +40,7 @@ static constexpr std::uint64_t TenToThe(int power) {
|
|||
// 10**(LOG10RADIX + 3) must be < 2**wordbits, and LOG10RADIX must be
|
||||
// even, so that pairs of decimal digits do not straddle Digits.
|
||||
// So LOG10RADIX must be 16 or 6.
|
||||
template<int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
|
||||
template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
|
||||
public:
|
||||
using Real = BinaryFloatingPointNumber<PREC>;
|
||||
static constexpr int log10Radix{LOG10RADIX};
|
||||
|
@ -140,7 +140,7 @@ private:
|
|||
|
||||
// Sets *this to an unsigned integer value.
|
||||
// Returns any remainder.
|
||||
template<typename UINT> UINT SetTo(UINT n) {
|
||||
template <typename UINT> UINT SetTo(UINT n) {
|
||||
static_assert(
|
||||
std::is_same_v<UINT, common::uint128_t> || std::is_unsigned_v<UINT>);
|
||||
SetToZero();
|
||||
|
@ -198,12 +198,12 @@ private:
|
|||
|
||||
// This limited divisibility test only works for even divisors of the radix,
|
||||
// which is fine since it's only ever used with 2 and 5.
|
||||
template<int N> bool IsDivisibleBy() const {
|
||||
template <int N> bool IsDivisibleBy() const {
|
||||
static_assert(N > 1 && radix % N == 0, "bad modulus");
|
||||
return digits_ == 0 || (digit_[0] % N) == 0;
|
||||
}
|
||||
|
||||
template<unsigned DIVISOR> int DivideBy() {
|
||||
template <unsigned DIVISOR> int DivideBy() {
|
||||
Digit remainder{0};
|
||||
for (int j{digits_ - 1}; j >= 0; --j) {
|
||||
Digit q{common::DivideUnsignedBy<Digit, DIVISOR>(digit_[j])};
|
||||
|
@ -253,7 +253,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
template<int N> int MultiplyByHelper(int carry = 0) {
|
||||
template <int N> int MultiplyByHelper(int carry = 0) {
|
||||
for (int j{0}; j < digits_; ++j) {
|
||||
auto v{N * digit_[j] + carry};
|
||||
carry = common::DivideUnsignedBy<Digit, radix>(v);
|
||||
|
@ -262,7 +262,7 @@ private:
|
|||
return carry;
|
||||
}
|
||||
|
||||
template<int N> int MultiplyBy(int carry = 0) {
|
||||
template <int N> int MultiplyBy(int carry = 0) {
|
||||
if (int newCarry{MultiplyByHelper<N>(carry)}) {
|
||||
return AddCarry(digits_, newCarry);
|
||||
} else {
|
||||
|
@ -270,7 +270,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
template<int N> int MultiplyWithoutNormalization() {
|
||||
template <int N> int MultiplyWithoutNormalization() {
|
||||
if (int carry{MultiplyByHelper<N>(0)}) {
|
||||
if (digits_ < digitLimit_) {
|
||||
digit_[digits_++] = carry;
|
||||
|
@ -283,7 +283,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
template<int N> void MultiplyByRounded() {
|
||||
template <int N> void MultiplyByRounded() {
|
||||
if (int carry{MultiplyBy<N>()}) {
|
||||
LoseLeastSignificantDigit();
|
||||
digit_[digits_ - 1] += carry;
|
||||
|
@ -326,5 +326,5 @@ private:
|
|||
bool isNegative_{false};
|
||||
enum FortranRounding rounding_ { RoundDefault };
|
||||
};
|
||||
}
|
||||
} // namespace Fortran::decimal
|
||||
#endif
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
namespace Fortran::decimal {
|
||||
|
||||
template<int PREC, int LOG10RADIX>
|
||||
template <int PREC, int LOG10RADIX>
|
||||
BigRadixFloatingPointNumber<PREC, LOG10RADIX>::BigRadixFloatingPointNumber(
|
||||
BinaryFloatingPointNumber<PREC> x, enum FortranRounding rounding)
|
||||
: rounding_{rounding} {
|
||||
|
@ -104,7 +104,7 @@ BigRadixFloatingPointNumber<PREC, LOG10RADIX>::BigRadixFloatingPointNumber(
|
|||
Normalize();
|
||||
}
|
||||
|
||||
template<int PREC, int LOG10RADIX>
|
||||
template <int PREC, int LOG10RADIX>
|
||||
ConversionToDecimalResult
|
||||
BigRadixFloatingPointNumber<PREC, LOG10RADIX>::ConvertToDecimal(char *buffer,
|
||||
std::size_t n, enum DecimalConversionFlags flags, int maxDigits) const {
|
||||
|
@ -176,10 +176,17 @@ BigRadixFloatingPointNumber<PREC, LOG10RADIX>::ConvertToDecimal(char *buffer,
|
|||
incr = *end > '5' ||
|
||||
(*end == '5' && (p > end + 1 || ((end[-1] - '0') & 1) != 0));
|
||||
break;
|
||||
case RoundUp: incr = !isNegative_; break;
|
||||
case RoundDown: incr = isNegative_; break;
|
||||
case RoundToZero: break;
|
||||
case RoundCompatible: incr = *end >= '5'; break;
|
||||
case RoundUp:
|
||||
incr = !isNegative_;
|
||||
break;
|
||||
case RoundDown:
|
||||
incr = isNegative_;
|
||||
break;
|
||||
case RoundToZero:
|
||||
break;
|
||||
case RoundCompatible:
|
||||
incr = *end >= '5';
|
||||
break;
|
||||
}
|
||||
p = end;
|
||||
if (incr) {
|
||||
|
@ -199,7 +206,7 @@ BigRadixFloatingPointNumber<PREC, LOG10RADIX>::ConvertToDecimal(char *buffer,
|
|||
}
|
||||
}
|
||||
|
||||
template<int PREC, int LOG10RADIX>
|
||||
template <int PREC, int LOG10RADIX>
|
||||
bool BigRadixFloatingPointNumber<PREC, LOG10RADIX>::Mean(
|
||||
const BigRadixFloatingPointNumber &that) {
|
||||
while (digits_ < that.digits_) {
|
||||
|
@ -222,7 +229,7 @@ bool BigRadixFloatingPointNumber<PREC, LOG10RADIX>::Mean(
|
|||
return DivideBy<2>() != 0;
|
||||
}
|
||||
|
||||
template<int PREC, int LOG10RADIX>
|
||||
template <int PREC, int LOG10RADIX>
|
||||
void BigRadixFloatingPointNumber<PREC, LOG10RADIX>::Minimize(
|
||||
BigRadixFloatingPointNumber &&less, BigRadixFloatingPointNumber &&more) {
|
||||
int leastExponent{exponent_};
|
||||
|
@ -292,7 +299,7 @@ void BigRadixFloatingPointNumber<PREC, LOG10RADIX>::Minimize(
|
|||
Normalize();
|
||||
}
|
||||
|
||||
template<int PREC, int LOG10RADIX>
|
||||
template <int PREC, int LOG10RADIX>
|
||||
void BigRadixFloatingPointNumber<PREC,
|
||||
LOG10RADIX>::LoseLeastSignificantDigit() {
|
||||
Digit LSD{digit_[0]};
|
||||
|
@ -306,17 +313,24 @@ void BigRadixFloatingPointNumber<PREC,
|
|||
case RoundDefault:
|
||||
incr = LSD > radix / 2 || (LSD == radix / 2 && digit_[0] % 2 != 0);
|
||||
break;
|
||||
case RoundUp: incr = LSD > 0 && !isNegative_; break;
|
||||
case RoundDown: incr = LSD > 0 && isNegative_; break;
|
||||
case RoundToZero: break;
|
||||
case RoundCompatible: incr = LSD >= radix / 2; break;
|
||||
case RoundUp:
|
||||
incr = LSD > 0 && !isNegative_;
|
||||
break;
|
||||
case RoundDown:
|
||||
incr = LSD > 0 && isNegative_;
|
||||
break;
|
||||
case RoundToZero:
|
||||
break;
|
||||
case RoundCompatible:
|
||||
incr = LSD >= radix / 2;
|
||||
break;
|
||||
}
|
||||
for (int j{0}; (digit_[j] += incr) == radix; ++j) {
|
||||
digit_[j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<int PREC>
|
||||
template <int PREC>
|
||||
ConversionToDecimalResult ConvertToDecimal(char *buffer, std::size_t size,
|
||||
enum DecimalConversionFlags flags, int digits,
|
||||
enum FortranRounding rounding, BinaryFloatingPointNumber<PREC> x) {
|
||||
|
@ -398,4 +412,4 @@ ConversionToDecimalResult ConvertLongDoubleToDecimal(char *buffer,
|
|||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::decimal
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
namespace Fortran::decimal {
|
||||
|
||||
template<int PREC, int LOG10RADIX>
|
||||
template <int PREC, int LOG10RADIX>
|
||||
bool BigRadixFloatingPointNumber<PREC, LOG10RADIX>::ParseNumber(
|
||||
const char *&p, bool &inexact) {
|
||||
SetToZero();
|
||||
|
@ -133,7 +133,8 @@ bool BigRadixFloatingPointNumber<PREC, LOG10RADIX>::ParseNumber(
|
|||
}
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -142,7 +143,7 @@ bool BigRadixFloatingPointNumber<PREC, LOG10RADIX>::ParseNumber(
|
|||
// binary floating-point value with an unbiased (i.e., signed)
|
||||
// binary exponent, an integer value (not a fraction) with an implied
|
||||
// binary point to its *right*, and some guard bits for rounding.
|
||||
template<int PREC> class IntermediateFloat {
|
||||
template <int PREC> class IntermediateFloat {
|
||||
public:
|
||||
static constexpr int precision{PREC};
|
||||
using IntType = common::HostUnsignedIntType<precision>;
|
||||
|
@ -154,7 +155,7 @@ public:
|
|||
|
||||
// Assumes that exponent_ is valid on entry, and may increment it.
|
||||
// Returns the number of guard_ bits that have been determined.
|
||||
template<typename UINT> bool SetTo(UINT n) {
|
||||
template <typename UINT> bool SetTo(UINT n) {
|
||||
static constexpr int nBits{CHAR_BIT * sizeof n};
|
||||
if constexpr (precision >= nBits) {
|
||||
value_ = n;
|
||||
|
@ -196,7 +197,7 @@ private:
|
|||
int exponent_{0};
|
||||
};
|
||||
|
||||
template<int PREC>
|
||||
template <int PREC>
|
||||
ConversionToBinaryResult<PREC> IntermediateFloat<PREC>::ToBinary(
|
||||
bool isNegative, FortranRounding rounding) const {
|
||||
using Binary = BinaryFloatingPointNumber<PREC>;
|
||||
|
@ -231,10 +232,17 @@ ConversionToBinaryResult<PREC> IntermediateFloat<PREC>::ToBinary(
|
|||
case RoundDefault:
|
||||
incr = guard > oneHalf || (guard == oneHalf && (fraction & 1));
|
||||
break;
|
||||
case RoundUp: incr = guard != 0 && !isNegative; break;
|
||||
case RoundDown: incr = guard != 0 && isNegative; break;
|
||||
case RoundToZero: break;
|
||||
case RoundCompatible: incr = guard >= oneHalf; break;
|
||||
case RoundUp:
|
||||
incr = guard != 0 && !isNegative;
|
||||
break;
|
||||
case RoundDown:
|
||||
incr = guard != 0 && isNegative;
|
||||
break;
|
||||
case RoundToZero:
|
||||
break;
|
||||
case RoundCompatible:
|
||||
incr = guard >= oneHalf;
|
||||
break;
|
||||
}
|
||||
if (incr) {
|
||||
if (fraction == mask) {
|
||||
|
@ -263,7 +271,7 @@ ConversionToBinaryResult<PREC> IntermediateFloat<PREC>::ToBinary(
|
|||
return {Binary(raw), static_cast<enum ConversionResultFlags>(flags)};
|
||||
}
|
||||
|
||||
template<int PREC, int LOG10RADIX>
|
||||
template <int PREC, int LOG10RADIX>
|
||||
ConversionToBinaryResult<PREC>
|
||||
BigRadixFloatingPointNumber<PREC, LOG10RADIX>::ConvertToBinary() {
|
||||
// On entry, *this holds a multi-precision integer value in a radix of a
|
||||
|
@ -346,7 +354,7 @@ BigRadixFloatingPointNumber<PREC, LOG10RADIX>::ConvertToBinary() {
|
|||
return f.ToBinary(isNegative_, rounding_);
|
||||
}
|
||||
|
||||
template<int PREC, int LOG10RADIX>
|
||||
template <int PREC, int LOG10RADIX>
|
||||
ConversionToBinaryResult<PREC>
|
||||
BigRadixFloatingPointNumber<PREC, LOG10RADIX>::ConvertToBinary(const char *&p) {
|
||||
bool inexact{false};
|
||||
|
@ -383,7 +391,7 @@ BigRadixFloatingPointNumber<PREC, LOG10RADIX>::ConvertToBinary(const char *&p) {
|
|||
}
|
||||
}
|
||||
|
||||
template<int PREC>
|
||||
template <int PREC>
|
||||
ConversionToBinaryResult<PREC> ConvertToBinary(
|
||||
const char *&p, enum FortranRounding rounding) {
|
||||
return BigRadixFloatingPointNumber<PREC>{rounding}.ConvertToBinary(p);
|
||||
|
@ -427,4 +435,4 @@ enum ConversionResultFlags ConvertDecimalToLongDouble(
|
|||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::decimal
|
||||
|
|
|
@ -65,8 +65,8 @@ void ActualArgument::Parenthesize() {
|
|||
|
||||
SpecificIntrinsic::SpecificIntrinsic(
|
||||
IntrinsicProcedure n, characteristics::Procedure &&chars)
|
||||
: name{n}, characteristics{new characteristics::Procedure{std::move(chars)}} {
|
||||
}
|
||||
: name{n}, characteristics{
|
||||
new characteristics::Procedure{std::move(chars)}} {}
|
||||
|
||||
DEFINE_DEFAULT_CONSTRUCTORS_AND_ASSIGNMENTS(SpecificIntrinsic)
|
||||
|
||||
|
@ -150,8 +150,7 @@ const Component *ProcedureDesignator::GetComponent() const {
|
|||
}
|
||||
|
||||
const Symbol *ProcedureDesignator::GetSymbol() const {
|
||||
return std::visit(
|
||||
common::visitors{
|
||||
return std::visit(common::visitors{
|
||||
[](SymbolRef symbol) { return &*symbol; },
|
||||
[](const common::CopyableIndirection<Component> &c) {
|
||||
return &c.value().GetLastSymbol();
|
||||
|
@ -213,5 +212,5 @@ int ProcedureRef::Rank() const {
|
|||
ProcedureRef::~ProcedureRef() {}
|
||||
|
||||
FOR_EACH_SPECIFIC_TYPE(template class FunctionRef, )
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
DEFINE_DELETER(Fortran::evaluate::ProcedureRef)
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
namespace Fortran::evaluate {
|
||||
|
||||
template<int KIND> class CharacterUtils {
|
||||
template <int KIND> class CharacterUtils {
|
||||
using Character = Scalar<Type<TypeCategory::Character, KIND>>;
|
||||
using CharT = typename Character::value_type;
|
||||
|
||||
|
@ -117,6 +117,6 @@ private:
|
|||
static constexpr CharT NewLine() { return 0x0a; }
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
|
||||
#endif // FORTRAN_EVALUATE_CHARACTER_H_
|
||||
|
|
|
@ -24,7 +24,7 @@ using namespace Fortran::parser::literals;
|
|||
namespace Fortran::evaluate::characteristics {
|
||||
|
||||
// Copy attributes from a symbol to dst based on the mapping in pairs.
|
||||
template<typename A, typename B>
|
||||
template <typename A, typename B>
|
||||
static void CopyAttrs(const semantics::Symbol &src, A &dst,
|
||||
const std::initializer_list<std::pair<semantics::Attr, B>> &pairs) {
|
||||
for (const auto &pair : pairs) {
|
||||
|
@ -398,8 +398,7 @@ bool DummyArgument::IsOptional() const {
|
|||
}
|
||||
|
||||
void DummyArgument::SetOptional(bool value) {
|
||||
std::visit(
|
||||
common::visitors{
|
||||
std::visit(common::visitors{
|
||||
[value](DummyDataObject &data) {
|
||||
data.attrs.set(DummyDataObject::Attr::Optional, value);
|
||||
},
|
||||
|
@ -497,7 +496,8 @@ bool FunctionResult::CanBeReturnedViaImplicitInterface() const {
|
|||
return true;
|
||||
}
|
||||
return false;
|
||||
default: return true;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -507,8 +507,7 @@ bool FunctionResult::CanBeReturnedViaImplicitInterface() const {
|
|||
|
||||
llvm::raw_ostream &FunctionResult::Dump(llvm::raw_ostream &o) const {
|
||||
attrs.Dump(o, EnumToString);
|
||||
std::visit(
|
||||
common::visitors{
|
||||
std::visit(common::visitors{
|
||||
[&](const TypeAndShape &ts) { ts.Dump(o); },
|
||||
[&](const CopyableIndirection<Procedure> &p) {
|
||||
p.value().Dump(o << " procedure(") << ')';
|
||||
|
@ -519,7 +518,8 @@ llvm::raw_ostream &FunctionResult::Dump(llvm::raw_ostream &o) const {
|
|||
}
|
||||
|
||||
Procedure::Procedure(FunctionResult &&fr, DummyArguments &&args, Attrs a)
|
||||
: functionResult{std::move(fr)}, dummyArguments{std::move(args)}, attrs{a} {}
|
||||
: functionResult{std::move(fr)}, dummyArguments{std::move(args)}, attrs{a} {
|
||||
}
|
||||
Procedure::Procedure(DummyArguments &&args, Attrs a)
|
||||
: dummyArguments{std::move(args)}, attrs{a} {}
|
||||
Procedure::~Procedure() {}
|
||||
|
@ -1020,7 +1020,7 @@ DEFINE_DEFAULT_CONSTRUCTORS_AND_ASSIGNMENTS(DummyArgument)
|
|||
DEFINE_DEFAULT_CONSTRUCTORS_AND_ASSIGNMENTS(DummyProcedure)
|
||||
DEFINE_DEFAULT_CONSTRUCTORS_AND_ASSIGNMENTS(FunctionResult)
|
||||
DEFINE_DEFAULT_CONSTRUCTORS_AND_ASSIGNMENTS(Procedure)
|
||||
}
|
||||
} // namespace Fortran::evaluate::characteristics
|
||||
|
||||
template class Fortran::common::Indirection<
|
||||
Fortran::evaluate::characteristics::Procedure, true>;
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
IsConstantExprHelper() : Base{*this} {}
|
||||
using Base::operator();
|
||||
|
||||
template<int KIND> bool operator()(const TypeParamInquiry<KIND> &inq) const {
|
||||
template <int KIND> bool operator()(const TypeParamInquiry<KIND> &inq) const {
|
||||
return IsKindTypeParameter(inq.parameter());
|
||||
}
|
||||
bool operator()(const semantics::Symbol &symbol) const {
|
||||
|
@ -36,7 +36,7 @@ public:
|
|||
bool operator()(const semantics::ParamValue ¶m) const {
|
||||
return param.isExplicit() && (*this)(param.GetExplicit());
|
||||
}
|
||||
template<typename T> bool operator()(const FunctionRef<T> &call) const {
|
||||
template <typename T> bool operator()(const FunctionRef<T> &call) const {
|
||||
if (const auto *intrinsic{std::get_if<SpecificIntrinsic>(&call.proc().u)}) {
|
||||
return intrinsic->name == "kind";
|
||||
// TODO: other inquiry intrinsics
|
||||
|
@ -46,7 +46,7 @@ public:
|
|||
}
|
||||
|
||||
// Forbid integer division by zero in constants.
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
bool operator()(
|
||||
const Divide<Type<TypeCategory::Integer, KIND>> &division) const {
|
||||
using T = Type<TypeCategory::Integer, KIND>;
|
||||
|
@ -58,7 +58,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
template<typename A> bool IsConstantExpr(const A &x) {
|
||||
template <typename A> bool IsConstantExpr(const A &x) {
|
||||
return IsConstantExprHelper{}(x);
|
||||
}
|
||||
template bool IsConstantExpr(const Expr<SomeType> &);
|
||||
|
@ -77,7 +77,7 @@ struct IsInitialDataTargetHelper
|
|||
|
||||
bool operator()(const BOZLiteralConstant &) const { return false; }
|
||||
bool operator()(const NullPointer &) const { return true; }
|
||||
template<typename T> bool operator()(const Constant<T> &) const {
|
||||
template <typename T> bool operator()(const Constant<T> &) const {
|
||||
return false;
|
||||
}
|
||||
bool operator()(const semantics::Symbol &symbol) const {
|
||||
|
@ -102,7 +102,7 @@ struct IsInitialDataTargetHelper
|
|||
return true;
|
||||
}
|
||||
bool operator()(const StaticDataObject &) const { return false; }
|
||||
template<int KIND> bool operator()(const TypeParamInquiry<KIND> &) const {
|
||||
template <int KIND> bool operator()(const TypeParamInquiry<KIND> &) const {
|
||||
return false;
|
||||
}
|
||||
bool operator()(const Triplet &x) const {
|
||||
|
@ -110,11 +110,11 @@ struct IsInitialDataTargetHelper
|
|||
IsConstantExpr(x.stride());
|
||||
}
|
||||
bool operator()(const Subscript &x) const {
|
||||
return std::visit(
|
||||
common::visitors{
|
||||
return std::visit(common::visitors{
|
||||
[&](const Triplet &t) { return (*this)(t); },
|
||||
[&](const auto &y) {
|
||||
return y.value().Rank() == 0 && IsConstantExpr(y.value());
|
||||
return y.value().Rank() == 0 &&
|
||||
IsConstantExpr(y.value());
|
||||
},
|
||||
},
|
||||
x.u);
|
||||
|
@ -125,16 +125,18 @@ struct IsInitialDataTargetHelper
|
|||
(*this)(x.parent());
|
||||
}
|
||||
bool operator()(const DescriptorInquiry &) const { return false; }
|
||||
template<typename T> bool operator()(const ArrayConstructor<T> &) const {
|
||||
template <typename T> bool operator()(const ArrayConstructor<T> &) const {
|
||||
return false;
|
||||
}
|
||||
bool operator()(const StructureConstructor &) const { return false; }
|
||||
template<typename T> bool operator()(const FunctionRef<T> &) { return false; }
|
||||
template<typename D, typename R, typename... O>
|
||||
template <typename T> bool operator()(const FunctionRef<T> &) {
|
||||
return false;
|
||||
}
|
||||
template <typename D, typename R, typename... O>
|
||||
bool operator()(const Operation<D, R, O...> &) const {
|
||||
return false;
|
||||
}
|
||||
template<typename T> bool operator()(const Parentheses<T> &x) const {
|
||||
template <typename T> bool operator()(const Parentheses<T> &x) const {
|
||||
return (*this)(x.left());
|
||||
}
|
||||
bool operator()(const Relational<SomeType> &) const { return false; }
|
||||
|
@ -211,7 +213,7 @@ public:
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
template<typename T> Result operator()(const FunctionRef<T> &x) const {
|
||||
template <typename T> Result operator()(const FunctionRef<T> &x) const {
|
||||
if (const auto *symbol{x.proc().GetSymbol()}) {
|
||||
if (!semantics::IsPureProcedure(*symbol)) {
|
||||
return "reference to impure function '"s + symbol->name().ToString() +
|
||||
|
@ -235,7 +237,7 @@ private:
|
|||
const semantics::Scope &scope_;
|
||||
};
|
||||
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
void CheckSpecificationExpr(const A &x, parser::ContextualMessages &messages,
|
||||
const semantics::Scope &scope) {
|
||||
if (auto why{CheckSpecificationExprHelper{scope}(x)}) {
|
||||
|
@ -303,7 +305,7 @@ public:
|
|||
Result operator()(const ComplexPart &) const { return false; }
|
||||
Result operator()(const Substring &) const { return false; }
|
||||
|
||||
template<typename T> Result operator()(const FunctionRef<T> &x) const {
|
||||
template <typename T> Result operator()(const FunctionRef<T> &x) const {
|
||||
if (auto chars{
|
||||
characteristics::Procedure::Characterize(x.proc(), table_)}) {
|
||||
if (chars->functionResult) {
|
||||
|
@ -347,7 +349,7 @@ private:
|
|||
const IntrinsicProcTable &table_;
|
||||
};
|
||||
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
bool IsSimplyContiguous(const A &x, const IntrinsicProcTable &table) {
|
||||
if (IsVariable(x)) {
|
||||
auto known{IsSimplyContiguousHelper{table}(x)};
|
||||
|
@ -360,4 +362,4 @@ bool IsSimplyContiguous(const A &x, const IntrinsicProcTable &table) {
|
|||
template bool IsSimplyContiguous(
|
||||
const Expr<SomeType> &, const IntrinsicProcTable &);
|
||||
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
|
|
|
@ -51,4 +51,4 @@ void FoldingContext::EndImpliedDo(parser::CharBlock name) {
|
|||
impliedDos_.erase(iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
namespace Fortran::evaluate::value {
|
||||
|
||||
template<typename R>
|
||||
template <typename R>
|
||||
ValueWithRealFlags<Complex<R>> Complex<R>::Add(
|
||||
const Complex &that, Rounding rounding) const {
|
||||
RealFlags flags;
|
||||
|
@ -20,7 +20,7 @@ ValueWithRealFlags<Complex<R>> Complex<R>::Add(
|
|||
return {Complex{reSum, imSum}, flags};
|
||||
}
|
||||
|
||||
template<typename R>
|
||||
template <typename R>
|
||||
ValueWithRealFlags<Complex<R>> Complex<R>::Subtract(
|
||||
const Complex &that, Rounding rounding) const {
|
||||
RealFlags flags;
|
||||
|
@ -29,7 +29,7 @@ ValueWithRealFlags<Complex<R>> Complex<R>::Subtract(
|
|||
return {Complex{reDiff, imDiff}, flags};
|
||||
}
|
||||
|
||||
template<typename R>
|
||||
template <typename R>
|
||||
ValueWithRealFlags<Complex<R>> Complex<R>::Multiply(
|
||||
const Complex &that, Rounding rounding) const {
|
||||
// (a + ib)*(c + id) -> ac - bd + i(ad + bc)
|
||||
|
@ -43,7 +43,7 @@ ValueWithRealFlags<Complex<R>> Complex<R>::Multiply(
|
|||
return {Complex{acbd, adbc}, flags};
|
||||
}
|
||||
|
||||
template<typename R>
|
||||
template <typename R>
|
||||
ValueWithRealFlags<Complex<R>> Complex<R>::Divide(
|
||||
const Complex &that, Rounding rounding) const {
|
||||
// (a + ib)/(c + id) -> [(a+ib)*(c-id)] / [(c+id)*(c-id)]
|
||||
|
@ -81,7 +81,7 @@ ValueWithRealFlags<Complex<R>> Complex<R>::Divide(
|
|||
return {Complex{re, im}, flags};
|
||||
}
|
||||
|
||||
template<typename R> std::string Complex<R>::DumpHexadecimal() const {
|
||||
template <typename R> std::string Complex<R>::DumpHexadecimal() const {
|
||||
std::string result{'('};
|
||||
result += re_.DumpHexadecimal();
|
||||
result += ',';
|
||||
|
@ -90,7 +90,7 @@ template<typename R> std::string Complex<R>::DumpHexadecimal() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
template<typename R>
|
||||
template <typename R>
|
||||
llvm::raw_ostream &Complex<R>::AsFortran(llvm::raw_ostream &o, int kind) const {
|
||||
re_.AsFortran(o << '(', kind);
|
||||
im_.AsFortran(o << ',', kind);
|
||||
|
@ -103,4 +103,4 @@ template class Complex<Real<Integer<32>, 24>>;
|
|||
template class Complex<Real<Integer<64>, 53>>;
|
||||
template class Complex<Real<Integer<80>, 64>>;
|
||||
template class Complex<Real<Integer<128>, 113>>;
|
||||
}
|
||||
} // namespace Fortran::evaluate::value
|
||||
|
|
|
@ -102,22 +102,22 @@ bool IsValidShape(const ConstantSubscripts &shape) {
|
|||
return shape.size() <= common::maxRank;
|
||||
}
|
||||
|
||||
template<typename RESULT, typename ELEMENT>
|
||||
template <typename RESULT, typename ELEMENT>
|
||||
ConstantBase<RESULT, ELEMENT>::ConstantBase(
|
||||
std::vector<Element> &&x, ConstantSubscripts &&sh, Result res)
|
||||
: ConstantBounds(std::move(sh)), result_{res}, values_(std::move(x)) {
|
||||
CHECK(size() == TotalElementCount(shape()));
|
||||
}
|
||||
|
||||
template<typename RESULT, typename ELEMENT>
|
||||
template <typename RESULT, typename ELEMENT>
|
||||
ConstantBase<RESULT, ELEMENT>::~ConstantBase() {}
|
||||
|
||||
template<typename RESULT, typename ELEMENT>
|
||||
template <typename RESULT, typename ELEMENT>
|
||||
bool ConstantBase<RESULT, ELEMENT>::operator==(const ConstantBase &that) const {
|
||||
return shape() == that.shape() && values_ == that.values_;
|
||||
}
|
||||
|
||||
template<typename RESULT, typename ELEMENT>
|
||||
template <typename RESULT, typename ELEMENT>
|
||||
auto ConstantBase<RESULT, ELEMENT>::Reshape(
|
||||
const ConstantSubscripts &dims) const -> std::vector<Element> {
|
||||
std::size_t n{TotalElementCount(dims)};
|
||||
|
@ -133,7 +133,7 @@ auto ConstantBase<RESULT, ELEMENT>::Reshape(
|
|||
return elements;
|
||||
}
|
||||
|
||||
template<typename RESULT, typename ELEMENT>
|
||||
template <typename RESULT, typename ELEMENT>
|
||||
std::size_t ConstantBase<RESULT, ELEMENT>::CopyFrom(
|
||||
const ConstantBase<RESULT, ELEMENT> &source, std::size_t count,
|
||||
ConstantSubscripts &resultSubscripts, const std::vector<int> *dimOrder) {
|
||||
|
@ -149,34 +149,34 @@ std::size_t ConstantBase<RESULT, ELEMENT>::CopyFrom(
|
|||
return copied;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
auto Constant<T>::At(const ConstantSubscripts &index) const -> Element {
|
||||
return Base::values_.at(Base::SubscriptsToOffset(index));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
auto Constant<T>::Reshape(ConstantSubscripts &&dims) const -> Constant {
|
||||
return {Base::Reshape(dims), std::move(dims)};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
std::size_t Constant<T>::CopyFrom(const Constant<T> &source, std::size_t count,
|
||||
ConstantSubscripts &resultSubscripts, const std::vector<int> *dimOrder) {
|
||||
return Base::CopyFrom(source, count, resultSubscripts, dimOrder);
|
||||
}
|
||||
|
||||
// Constant<Type<TypeCategory::Character, KIND> specializations
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Constant<Type<TypeCategory::Character, KIND>>::Constant(
|
||||
const Scalar<Result> &str)
|
||||
: values_{str}, length_{static_cast<ConstantSubscript>(values_.size())} {}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Constant<Type<TypeCategory::Character, KIND>>::Constant(Scalar<Result> &&str)
|
||||
: values_{std::move(str)}, length_{static_cast<ConstantSubscript>(
|
||||
values_.size())} {}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Constant<Type<TypeCategory::Character, KIND>>::Constant(ConstantSubscript len,
|
||||
std::vector<Scalar<Result>> &&strings, ConstantSubscripts &&sh)
|
||||
: ConstantBounds(std::move(sh)), length_{len} {
|
||||
|
@ -196,14 +196,15 @@ Constant<Type<TypeCategory::Character, KIND>>::Constant(ConstantSubscript len,
|
|||
CHECK(at == static_cast<ConstantSubscript>(values_.size()));
|
||||
}
|
||||
|
||||
template<int KIND> Constant<Type<TypeCategory::Character, KIND>>::~Constant() {}
|
||||
template <int KIND>
|
||||
Constant<Type<TypeCategory::Character, KIND>>::~Constant() {}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
bool Constant<Type<TypeCategory::Character, KIND>>::empty() const {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
std::size_t Constant<Type<TypeCategory::Character, KIND>>::size() const {
|
||||
if (length_ == 0) {
|
||||
return TotalElementCount(shape());
|
||||
|
@ -212,14 +213,14 @@ std::size_t Constant<Type<TypeCategory::Character, KIND>>::size() const {
|
|||
}
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
auto Constant<Type<TypeCategory::Character, KIND>>::At(
|
||||
const ConstantSubscripts &index) const -> Scalar<Result> {
|
||||
auto offset{SubscriptsToOffset(index)};
|
||||
return values_.substr(offset * length_, length_);
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
auto Constant<Type<TypeCategory::Character, KIND>>::Reshape(
|
||||
ConstantSubscripts &&dims) const -> Constant<Result> {
|
||||
std::size_t n{TotalElementCount(dims)};
|
||||
|
@ -237,7 +238,7 @@ auto Constant<Type<TypeCategory::Character, KIND>>::Reshape(
|
|||
return {length_, std::move(elements), std::move(dims)};
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
std::size_t Constant<Type<TypeCategory::Character, KIND>>::CopyFrom(
|
||||
const Constant<Type<TypeCategory::Character, KIND>> &source,
|
||||
std::size_t count, ConstantSubscripts &resultSubscripts,
|
||||
|
@ -308,4 +309,4 @@ std::size_t Constant<SomeDerived>::CopyFrom(const Constant<SomeDerived> &source,
|
|||
}
|
||||
|
||||
INSTANTIATE_CONSTANT_TEMPLATES
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
|
|
|
@ -21,7 +21,7 @@ using namespace Fortran::parser::literals;
|
|||
|
||||
namespace Fortran::evaluate {
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
std::optional<Expr<SubscriptInteger>>
|
||||
Expr<Type<TypeCategory::Character, KIND>>::LEN() const {
|
||||
using T = std::optional<Expr<SubscriptInteger>>;
|
||||
|
@ -63,18 +63,18 @@ Expr<Type<TypeCategory::Character, KIND>>::LEN() const {
|
|||
Expr<SomeType>::~Expr() = default;
|
||||
|
||||
#if defined(__APPLE__) && defined(__GNUC__)
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
typename ExpressionBase<A>::Derived &ExpressionBase<A>::derived() {
|
||||
return *static_cast<Derived *>(this);
|
||||
}
|
||||
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
const typename ExpressionBase<A>::Derived &ExpressionBase<A>::derived() const {
|
||||
return *static_cast<const Derived *>(this);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
std::optional<DynamicType> ExpressionBase<A>::GetType() const {
|
||||
if constexpr (IsLengthlessIntrinsicType<Result>) {
|
||||
return Result::GetType();
|
||||
|
@ -90,7 +90,7 @@ std::optional<DynamicType> ExpressionBase<A>::GetType() const {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename A> int ExpressionBase<A>::Rank() const {
|
||||
template <typename A> int ExpressionBase<A>::Rank() const {
|
||||
return std::visit(
|
||||
[](const auto &x) {
|
||||
if constexpr (common::HasMember<decltype(x), TypelessExpression>) {
|
||||
|
@ -108,26 +108,26 @@ bool ImpliedDoIndex::operator==(const ImpliedDoIndex &that) const {
|
|||
return name == that.name;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
bool ImpliedDo<T>::operator==(const ImpliedDo<T> &that) const {
|
||||
return name_ == that.name_ && lower_ == that.lower_ &&
|
||||
upper_ == that.upper_ && stride_ == that.stride_ &&
|
||||
values_ == that.values_;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
bool ArrayConstructorValue<T>::operator==(
|
||||
const ArrayConstructorValue<T> &that) const {
|
||||
return u == that.u;
|
||||
}
|
||||
|
||||
template<typename R>
|
||||
template <typename R>
|
||||
bool ArrayConstructorValues<R>::operator==(
|
||||
const ArrayConstructorValues<R> &that) const {
|
||||
return values_ == that.values_;
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
bool ArrayConstructor<Type<TypeCategory::Character, KIND>>::operator==(
|
||||
const ArrayConstructor &that) const {
|
||||
return length_ == that.length_ &&
|
||||
|
@ -157,37 +157,37 @@ bool Relational<SomeType>::operator==(const Relational<SomeType> &that) const {
|
|||
return u == that.u;
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
bool Expr<Type<TypeCategory::Integer, KIND>>::operator==(
|
||||
const Expr<Type<TypeCategory::Integer, KIND>> &that) const {
|
||||
return u == that.u;
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
bool Expr<Type<TypeCategory::Real, KIND>>::operator==(
|
||||
const Expr<Type<TypeCategory::Real, KIND>> &that) const {
|
||||
return u == that.u;
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
bool Expr<Type<TypeCategory::Complex, KIND>>::operator==(
|
||||
const Expr<Type<TypeCategory::Complex, KIND>> &that) const {
|
||||
return u == that.u;
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
bool Expr<Type<TypeCategory::Logical, KIND>>::operator==(
|
||||
const Expr<Type<TypeCategory::Logical, KIND>> &that) const {
|
||||
return u == that.u;
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
bool Expr<Type<TypeCategory::Character, KIND>>::operator==(
|
||||
const Expr<Type<TypeCategory::Character, KIND>> &that) const {
|
||||
return u == that.u;
|
||||
}
|
||||
|
||||
template<TypeCategory CAT>
|
||||
template <TypeCategory CAT>
|
||||
bool Expr<SomeKind<CAT>>::operator==(const Expr<SomeKind<CAT>> &that) const {
|
||||
return u == that.u;
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ GenericExprWrapper::~GenericExprWrapper() {}
|
|||
|
||||
GenericAssignmentWrapper::~GenericAssignmentWrapper() {}
|
||||
|
||||
template<TypeCategory CAT> int Expr<SomeKind<CAT>>::GetKind() const {
|
||||
template <TypeCategory CAT> int Expr<SomeKind<CAT>>::GetKind() const {
|
||||
return std::visit(
|
||||
[](const auto &kx) { return std::decay_t<decltype(kx)>::Result::kind; },
|
||||
u);
|
||||
|
@ -242,6 +242,6 @@ std::optional<Expr<SubscriptInteger>> Expr<SomeCharacter>::LEN() const {
|
|||
}
|
||||
|
||||
INSTANTIATE_EXPRESSION_TEMPLATES
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
DEFINE_DELETER(Fortran::evaluate::GenericExprWrapper)
|
||||
DEFINE_DELETER(Fortran::evaluate::GenericAssignmentWrapper)
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
namespace Fortran::evaluate {
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Character, KIND>> FoldIntrinsicFunction(
|
||||
FoldingContext &context,
|
||||
FunctionRef<Type<TypeCategory::Character, KIND>> &&funcRef) {
|
||||
|
@ -57,7 +57,7 @@ Expr<Type<TypeCategory::Character, KIND>> FoldIntrinsicFunction(
|
|||
return Expr<T>{std::move(funcRef)};
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Character, KIND>> FoldOperation(
|
||||
FoldingContext &context, Concat<KIND> &&x) {
|
||||
if (auto array{ApplyElementwise(context, x)}) {
|
||||
|
@ -70,7 +70,7 @@ Expr<Type<TypeCategory::Character, KIND>> FoldOperation(
|
|||
return Expr<Result>{std::move(x)};
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Character, KIND>> FoldOperation(
|
||||
FoldingContext &context, SetLength<KIND> &&x) {
|
||||
if (auto array{ApplyElementwise(context, x)}) {
|
||||
|
@ -93,4 +93,4 @@ Expr<Type<TypeCategory::Character, KIND>> FoldOperation(
|
|||
|
||||
FOR_EACH_CHARACTER_KIND(template class ExpressionBase, )
|
||||
template class ExpressionBase<SomeCharacter>;
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
namespace Fortran::evaluate {
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Complex, KIND>> FoldIntrinsicFunction(
|
||||
FoldingContext &context,
|
||||
FunctionRef<Type<TypeCategory::Complex, KIND>> &&funcRef) {
|
||||
|
@ -61,7 +61,7 @@ Expr<Type<TypeCategory::Complex, KIND>> FoldIntrinsicFunction(
|
|||
return Expr<T>{std::move(funcRef)};
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Complex, KIND>> FoldOperation(
|
||||
FoldingContext &context, ComplexConstructor<KIND> &&x) {
|
||||
if (auto array{ApplyElementwise(context, x)}) {
|
||||
|
@ -77,4 +77,4 @@ Expr<Type<TypeCategory::Complex, KIND>> FoldOperation(
|
|||
|
||||
FOR_EACH_COMPLEX_KIND(template class ExpressionBase, )
|
||||
template class ExpressionBase<SomeComplex>;
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
namespace Fortran::evaluate {
|
||||
|
||||
// Utilities
|
||||
template<typename T> class Folder {
|
||||
template <typename T> class Folder {
|
||||
public:
|
||||
explicit Folder(FoldingContext &c) : context_{c} {}
|
||||
std::optional<Expr<T>> GetNamedConstantValue(const Symbol &);
|
||||
|
@ -76,7 +76,7 @@ std::optional<Constant<SubscriptInteger>> GetConstantSubscript(
|
|||
// specific type.
|
||||
|
||||
// no-op base case
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
common::IfNoLvalue<Expr<ResultType<A>>, A> FoldOperation(
|
||||
FoldingContext &, A &&x) {
|
||||
static_assert(!std::is_same_v<A, Expr<ResultType<A>>>,
|
||||
|
@ -94,36 +94,36 @@ DataRef FoldOperation(FoldingContext &, DataRef &&);
|
|||
Substring FoldOperation(FoldingContext &, Substring &&);
|
||||
ComplexPart FoldOperation(FoldingContext &, ComplexPart &&);
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Expr<T> FoldOperation(FoldingContext &context, FunctionRef<T> &&);
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
|
||||
FoldingContext &context, FunctionRef<Type<TypeCategory::Integer, KIND>> &&);
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Real, KIND>> FoldIntrinsicFunction(
|
||||
FoldingContext &context, FunctionRef<Type<TypeCategory::Real, KIND>> &&);
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Complex, KIND>> FoldIntrinsicFunction(
|
||||
FoldingContext &context, FunctionRef<Type<TypeCategory::Complex, KIND>> &&);
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Logical, KIND>> FoldIntrinsicFunction(
|
||||
FoldingContext &context, FunctionRef<Type<TypeCategory::Logical, KIND>> &&);
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Expr<T> FoldOperation(FoldingContext &context, Designator<T> &&designator) {
|
||||
return Folder<T>{context}.Folding(std::move(designator));
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Integer, KIND>> FoldOperation(
|
||||
FoldingContext &, TypeParamInquiry<KIND> &&);
|
||||
Expr<ImpliedDoIndex::Result> FoldOperation(
|
||||
FoldingContext &context, ImpliedDoIndex &&);
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Expr<T> FoldOperation(FoldingContext &, ArrayConstructor<T> &&);
|
||||
Expr<SomeDerived> FoldOperation(FoldingContext &, StructureConstructor &&);
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
std::optional<Expr<T>> Folder<T>::GetNamedConstantValue(const Symbol &symbol0) {
|
||||
const Symbol &symbol{ResolveAssociations(symbol0)};
|
||||
if (IsNamedConstant(symbol)) {
|
||||
|
@ -200,7 +200,7 @@ std::optional<Expr<T>> Folder<T>::GetNamedConstantValue(const Symbol &symbol0) {
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
std::optional<Constant<T>> Folder<T>::GetFoldedNamedConstantValue(
|
||||
const Symbol &symbol) {
|
||||
if (auto value{GetNamedConstantValue(symbol)}) {
|
||||
|
@ -212,7 +212,7 @@ std::optional<Constant<T>> Folder<T>::GetFoldedNamedConstantValue(
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
std::optional<Constant<T>> Folder<T>::Folding(ArrayRef &aRef) {
|
||||
std::vector<Constant<SubscriptInteger>> subscripts;
|
||||
int dim{0};
|
||||
|
@ -233,7 +233,7 @@ std::optional<Constant<T>> Folder<T>::Folding(ArrayRef &aRef) {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
std::optional<Constant<T>> Folder<T>::ApplySubscripts(const Constant<T> &array,
|
||||
const std::vector<Constant<SubscriptInteger>> &subscripts) {
|
||||
const auto &shape{array.shape()};
|
||||
|
@ -293,7 +293,7 @@ std::optional<Constant<T>> Folder<T>::ApplySubscripts(const Constant<T> &array,
|
|||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
std::optional<Constant<T>> Folder<T>::ApplyComponent(
|
||||
Constant<SomeDerived> &&structures, const Symbol &component,
|
||||
const std::vector<Constant<SubscriptInteger>> *subscripts) {
|
||||
|
@ -351,7 +351,7 @@ std::optional<Constant<T>> Folder<T>::ApplyComponent(
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
std::optional<Constant<T>> Folder<T>::GetConstantComponent(Component &component,
|
||||
const std::vector<Constant<SubscriptInteger>> *subscripts) {
|
||||
if (std::optional<Constant<SomeDerived>> structures{std::visit(
|
||||
|
@ -378,7 +378,7 @@ std::optional<Constant<T>> Folder<T>::GetConstantComponent(Component &component,
|
|||
}
|
||||
}
|
||||
|
||||
template<typename T> Expr<T> Folder<T>::Folding(Designator<T> &&designator) {
|
||||
template <typename T> Expr<T> Folder<T>::Folding(Designator<T> &&designator) {
|
||||
if constexpr (T::category == TypeCategory::Character) {
|
||||
if (auto *substring{common::Unwrap<Substring>(designator.u)}) {
|
||||
if (std::optional<Expr<SomeCharacter>> folded{
|
||||
|
@ -428,7 +428,7 @@ template<typename T> Expr<T> Folder<T>::Folding(Designator<T> &&designator) {
|
|||
|
||||
// Apply type conversion and re-folding if necessary.
|
||||
// This is where BOZ arguments are converted.
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Constant<T> *Folder<T>::Folding(std::optional<ActualArgument> &arg) {
|
||||
if (auto *expr{UnwrapExpr<Expr<SomeType>>(arg)}) {
|
||||
if (!UnwrapExpr<Expr<T>>(*expr)) {
|
||||
|
@ -441,7 +441,7 @@ Constant<T> *Folder<T>::Folding(std::optional<ActualArgument> &arg) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename... A, std::size_t... I>
|
||||
template <typename... A, std::size_t... I>
|
||||
std::optional<std::tuple<const Constant<A> *...>> GetConstantArgumentsHelper(
|
||||
FoldingContext &context, ActualArguments &arguments,
|
||||
std::index_sequence<I...>) {
|
||||
|
@ -457,14 +457,14 @@ std::optional<std::tuple<const Constant<A> *...>> GetConstantArgumentsHelper(
|
|||
}
|
||||
}
|
||||
|
||||
template<typename... A>
|
||||
template <typename... A>
|
||||
std::optional<std::tuple<const Constant<A> *...>> GetConstantArguments(
|
||||
FoldingContext &context, ActualArguments &args) {
|
||||
return GetConstantArgumentsHelper<A...>(
|
||||
context, args, std::index_sequence_for<A...>{});
|
||||
}
|
||||
|
||||
template<typename... A, std::size_t... I>
|
||||
template <typename... A, std::size_t... I>
|
||||
std::optional<std::tuple<Scalar<A>...>> GetScalarConstantArgumentsHelper(
|
||||
FoldingContext &context, ActualArguments &args, std::index_sequence<I...>) {
|
||||
if (auto constArgs{GetConstantArguments<A...>(context, args)}) {
|
||||
|
@ -475,7 +475,7 @@ std::optional<std::tuple<Scalar<A>...>> GetScalarConstantArgumentsHelper(
|
|||
}
|
||||
}
|
||||
|
||||
template<typename... A>
|
||||
template <typename... A>
|
||||
std::optional<std::tuple<Scalar<A>...>> GetScalarConstantArguments(
|
||||
FoldingContext &context, ActualArguments &args) {
|
||||
return GetScalarConstantArgumentsHelper<A...>(
|
||||
|
@ -486,13 +486,13 @@ std::optional<std::tuple<Scalar<A>...>> GetScalarConstantArguments(
|
|||
// Define callable types used in a common utility that
|
||||
// takes care of array and cast/conversion aspects for elemental intrinsics
|
||||
|
||||
template<typename TR, typename... TArgs>
|
||||
template <typename TR, typename... TArgs>
|
||||
using ScalarFunc = std::function<Scalar<TR>(const Scalar<TArgs> &...)>;
|
||||
template<typename TR, typename... TArgs>
|
||||
template <typename TR, typename... TArgs>
|
||||
using ScalarFuncWithContext =
|
||||
std::function<Scalar<TR>(FoldingContext &, const Scalar<TArgs> &...)>;
|
||||
|
||||
template<template<typename, typename...> typename WrapperType, typename TR,
|
||||
template <template <typename, typename...> typename WrapperType, typename TR,
|
||||
typename... TA, std::size_t... I>
|
||||
Expr<TR> FoldElementalIntrinsicHelper(FoldingContext &context,
|
||||
FunctionRef<TR> &&funcRef, WrapperType<TR, TA...> func,
|
||||
|
@ -556,13 +556,13 @@ Expr<TR> FoldElementalIntrinsicHelper(FoldingContext &context,
|
|||
return Expr<TR>{std::move(funcRef)};
|
||||
}
|
||||
|
||||
template<typename TR, typename... TA>
|
||||
template <typename TR, typename... TA>
|
||||
Expr<TR> FoldElementalIntrinsic(FoldingContext &context,
|
||||
FunctionRef<TR> &&funcRef, ScalarFunc<TR, TA...> func) {
|
||||
return FoldElementalIntrinsicHelper<ScalarFunc, TR, TA...>(
|
||||
context, std::move(funcRef), func, std::index_sequence_for<TA...>{});
|
||||
}
|
||||
template<typename TR, typename... TA>
|
||||
template <typename TR, typename... TA>
|
||||
Expr<TR> FoldElementalIntrinsic(FoldingContext &context,
|
||||
FunctionRef<TR> &&funcRef, ScalarFuncWithContext<TR, TA...> func) {
|
||||
return FoldElementalIntrinsicHelper<ScalarFuncWithContext, TR, TA...>(
|
||||
|
@ -573,7 +573,7 @@ std::optional<std::int64_t> GetInt64Arg(const std::optional<ActualArgument> &);
|
|||
std::optional<std::int64_t> GetInt64ArgOr(
|
||||
const std::optional<ActualArgument> &, std::int64_t defaultValue);
|
||||
|
||||
template<typename A, typename B>
|
||||
template <typename A, typename B>
|
||||
std::optional<std::vector<A>> GetIntegerVector(const B &x) {
|
||||
static_assert(std::is_integral_v<A>);
|
||||
if (const auto *someInteger{UnwrapExpr<Expr<SomeInteger>>(x)}) {
|
||||
|
@ -600,14 +600,14 @@ std::optional<std::vector<A>> GetIntegerVector(const B &x) {
|
|||
// into an intrinsic with the same characteristic but the "invalid" name.
|
||||
// This to prevent generating warnings over and over if the expression
|
||||
// gets re-folded.
|
||||
template<typename T> Expr<T> MakeInvalidIntrinsic(FunctionRef<T> &&funcRef) {
|
||||
template <typename T> Expr<T> MakeInvalidIntrinsic(FunctionRef<T> &&funcRef) {
|
||||
SpecificIntrinsic invalid{std::get<SpecificIntrinsic>(funcRef.proc().u)};
|
||||
invalid.name = "(invalid intrinsic function call)";
|
||||
return Expr<T>{FunctionRef<T>{ProcedureDesignator{std::move(invalid)},
|
||||
ActualArguments{ActualArgument{AsGenericExpr(std::move(funcRef))}}}};
|
||||
}
|
||||
|
||||
template<typename T> Expr<T> Folder<T>::Reshape(FunctionRef<T> &&funcRef) {
|
||||
template <typename T> Expr<T> Folder<T>::Reshape(FunctionRef<T> &&funcRef) {
|
||||
auto args{funcRef.arguments()};
|
||||
CHECK(args.size() == 4);
|
||||
const auto *source{UnwrapConstantValue<T>(args[0])};
|
||||
|
@ -652,7 +652,7 @@ template<typename T> Expr<T> Folder<T>::Reshape(FunctionRef<T> &&funcRef) {
|
|||
return MakeInvalidIntrinsic(std::move(funcRef));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Expr<T> FoldMINorMAX(
|
||||
FoldingContext &context, FunctionRef<T> &&funcRef, Ordering order) {
|
||||
std::vector<Constant<T> *> constantArgs;
|
||||
|
@ -672,7 +672,7 @@ Expr<T> FoldMINorMAX(
|
|||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Expr<T> FoldOperation(FoldingContext &context, FunctionRef<T> &&funcRef) {
|
||||
ActualArguments &args{funcRef.arguments()};
|
||||
for (std::optional<ActualArgument> &arg : args) {
|
||||
|
@ -693,7 +693,7 @@ Expr<T> FoldOperation(FoldingContext &context, FunctionRef<T> &&funcRef) {
|
|||
return Expr<T>{std::move(funcRef)};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Expr<T> FoldMerge(FoldingContext &context, FunctionRef<T> &&funcRef) {
|
||||
return FoldElementalIntrinsic<T, T, T, LogicalResult>(context,
|
||||
std::move(funcRef),
|
||||
|
@ -707,7 +707,7 @@ Expr<T> FoldMerge(FoldingContext &context, FunctionRef<T> &&funcRef) {
|
|||
Expr<ImpliedDoIndex::Result> FoldOperation(FoldingContext &, ImpliedDoIndex &&);
|
||||
|
||||
// Array constructor folding
|
||||
template<typename T> class ArrayConstructorFolder {
|
||||
template <typename T> class ArrayConstructorFolder {
|
||||
public:
|
||||
explicit ArrayConstructorFolder(const FoldingContext &c) : context_{c} {}
|
||||
|
||||
|
@ -797,7 +797,7 @@ private:
|
|||
std::vector<Scalar<T>> elements_;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Expr<T> FoldOperation(FoldingContext &context, ArrayConstructor<T> &&array) {
|
||||
return ArrayConstructorFolder<T>{context}.FoldArray(std::move(array));
|
||||
}
|
||||
|
@ -810,7 +810,7 @@ Expr<T> FoldOperation(FoldingContext &context, ArrayConstructor<T> &&array) {
|
|||
|
||||
// If possible, restructures an array expression into an array constructor
|
||||
// that comprises a "flat" ArrayConstructorValues with no implied DO loops.
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
bool ArrayConstructorIsFlat(const ArrayConstructorValues<T> &values) {
|
||||
for (const ArrayConstructorValue<T> &x : values) {
|
||||
if (!std::holds_alternative<Expr<T>>(x.u)) {
|
||||
|
@ -820,7 +820,7 @@ bool ArrayConstructorIsFlat(const ArrayConstructorValues<T> &values) {
|
|||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
std::optional<Expr<T>> AsFlatArrayConstructor(const Expr<T> &expr) {
|
||||
if (const auto *c{UnwrapConstantValue<T>(expr)}) {
|
||||
ArrayConstructor<T> result{expr};
|
||||
|
@ -841,7 +841,7 @@ std::optional<Expr<T>> AsFlatArrayConstructor(const Expr<T> &expr) {
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
template<TypeCategory CAT>
|
||||
template <TypeCategory CAT>
|
||||
std::enable_if_t<CAT != TypeCategory::Derived,
|
||||
std::optional<Expr<SomeKind<CAT>>>>
|
||||
AsFlatArrayConstructor(const Expr<SomeKind<CAT>> &expr) {
|
||||
|
@ -860,7 +860,7 @@ AsFlatArrayConstructor(const Expr<SomeKind<CAT>> &expr) {
|
|||
// Given a flat ArrayConstructor<T> and a shape, it wraps the array
|
||||
// into an Expr<T>, folds it, and returns the resulting wrapped
|
||||
// array constructor or constant array value.
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Expr<T> FromArrayConstructor(FoldingContext &context,
|
||||
ArrayConstructor<T> &&values, std::optional<ConstantSubscripts> &&shape) {
|
||||
Expr<T> result{Fold(context, Expr<T>{std::move(values)})};
|
||||
|
@ -880,7 +880,7 @@ Expr<T> FromArrayConstructor(FoldingContext &context,
|
|||
// Preserves shape.
|
||||
|
||||
// Unary case
|
||||
template<typename RESULT, typename OPERAND>
|
||||
template <typename RESULT, typename OPERAND>
|
||||
Expr<RESULT> MapOperation(FoldingContext &context,
|
||||
std::function<Expr<RESULT>(Expr<OPERAND> &&)> &&f, const Shape &shape,
|
||||
Expr<OPERAND> &&values) {
|
||||
|
@ -908,7 +908,7 @@ Expr<RESULT> MapOperation(FoldingContext &context,
|
|||
}
|
||||
|
||||
// array * array case
|
||||
template<typename RESULT, typename LEFT, typename RIGHT>
|
||||
template <typename RESULT, typename LEFT, typename RIGHT>
|
||||
Expr<RESULT> MapOperation(FoldingContext &context,
|
||||
std::function<Expr<RESULT>(Expr<LEFT> &&, Expr<RIGHT> &&)> &&f,
|
||||
const Shape &shape, Expr<LEFT> &&leftValues, Expr<RIGHT> &&rightValues) {
|
||||
|
@ -948,7 +948,7 @@ Expr<RESULT> MapOperation(FoldingContext &context,
|
|||
}
|
||||
|
||||
// array * scalar case
|
||||
template<typename RESULT, typename LEFT, typename RIGHT>
|
||||
template <typename RESULT, typename LEFT, typename RIGHT>
|
||||
Expr<RESULT> MapOperation(FoldingContext &context,
|
||||
std::function<Expr<RESULT>(Expr<LEFT> &&, Expr<RIGHT> &&)> &&f,
|
||||
const Shape &shape, Expr<LEFT> &&leftValues,
|
||||
|
@ -965,7 +965,7 @@ Expr<RESULT> MapOperation(FoldingContext &context,
|
|||
}
|
||||
|
||||
// scalar * array case
|
||||
template<typename RESULT, typename LEFT, typename RIGHT>
|
||||
template <typename RESULT, typename LEFT, typename RIGHT>
|
||||
Expr<RESULT> MapOperation(FoldingContext &context,
|
||||
std::function<Expr<RESULT>(Expr<LEFT> &&, Expr<RIGHT> &&)> &&f,
|
||||
const Shape &shape, const Expr<LEFT> &leftScalar,
|
||||
|
@ -1000,7 +1000,7 @@ Expr<RESULT> MapOperation(FoldingContext &context,
|
|||
// operation, then attempts to apply the operation to the (corresponding)
|
||||
// scalar element(s) of those operands. Returns std::nullopt for scalars
|
||||
// or unlinearizable operands.
|
||||
template<typename DERIVED, typename RESULT, typename OPERAND>
|
||||
template <typename DERIVED, typename RESULT, typename OPERAND>
|
||||
auto ApplyElementwise(FoldingContext &context,
|
||||
Operation<DERIVED, RESULT, OPERAND> &operation,
|
||||
std::function<Expr<RESULT>(Expr<OPERAND> &&)> &&f)
|
||||
|
@ -1017,7 +1017,7 @@ auto ApplyElementwise(FoldingContext &context,
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
template<typename DERIVED, typename RESULT, typename OPERAND>
|
||||
template <typename DERIVED, typename RESULT, typename OPERAND>
|
||||
auto ApplyElementwise(
|
||||
FoldingContext &context, Operation<DERIVED, RESULT, OPERAND> &operation)
|
||||
-> std::optional<Expr<RESULT>> {
|
||||
|
@ -1036,15 +1036,15 @@ struct UnexpandabilityFindingVisitor
|
|||
using Base = AnyTraverse<UnexpandabilityFindingVisitor>;
|
||||
using Base::operator();
|
||||
UnexpandabilityFindingVisitor() : Base{*this} {}
|
||||
template<typename T> bool operator()(const FunctionRef<T> &) { return true; }
|
||||
template <typename T> bool operator()(const FunctionRef<T> &) { return true; }
|
||||
bool operator()(const CoarrayRef &) { return true; }
|
||||
};
|
||||
|
||||
template<typename T> bool IsExpandableScalar(const Expr<T> &expr) {
|
||||
template <typename T> bool IsExpandableScalar(const Expr<T> &expr) {
|
||||
return !UnexpandabilityFindingVisitor{}(expr);
|
||||
}
|
||||
|
||||
template<typename DERIVED, typename RESULT, typename LEFT, typename RIGHT>
|
||||
template <typename DERIVED, typename RESULT, typename LEFT, typename RIGHT>
|
||||
auto ApplyElementwise(FoldingContext &context,
|
||||
Operation<DERIVED, RESULT, LEFT, RIGHT> &operation,
|
||||
std::function<Expr<RESULT>(Expr<LEFT> &&, Expr<RIGHT> &&)> &&f)
|
||||
|
@ -1081,7 +1081,7 @@ auto ApplyElementwise(FoldingContext &context,
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
template<typename DERIVED, typename RESULT, typename LEFT, typename RIGHT>
|
||||
template <typename DERIVED, typename RESULT, typename LEFT, typename RIGHT>
|
||||
auto ApplyElementwise(
|
||||
FoldingContext &context, Operation<DERIVED, RESULT, LEFT, RIGHT> &operation)
|
||||
-> std::optional<Expr<RESULT>> {
|
||||
|
@ -1094,7 +1094,7 @@ auto ApplyElementwise(
|
|||
|
||||
// Unary operations
|
||||
|
||||
template<typename TO, typename FROM>
|
||||
template <typename TO, typename FROM>
|
||||
common::IfNoLvalue<std::optional<TO>, FROM> ConvertString(FROM &&s) {
|
||||
if constexpr (std::is_same_v<TO, FROM>) {
|
||||
return std::make_optional<TO>(std::move(s));
|
||||
|
@ -1112,7 +1112,7 @@ common::IfNoLvalue<std::optional<TO>, FROM> ConvertString(FROM &&s) {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename TO, TypeCategory FROMCAT>
|
||||
template <typename TO, TypeCategory FROMCAT>
|
||||
Expr<TO> FoldOperation(
|
||||
FoldingContext &context, Convert<TO, FROMCAT> &&convert) {
|
||||
if (auto array{ApplyElementwise(context, convert)}) {
|
||||
|
@ -1185,7 +1185,7 @@ Expr<TO> FoldOperation(
|
|||
convert.left().u);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Expr<T> FoldOperation(FoldingContext &context, Parentheses<T> &&x) {
|
||||
auto &operand{x.left()};
|
||||
operand = Fold(context, std::move(operand));
|
||||
|
@ -1200,7 +1200,7 @@ Expr<T> FoldOperation(FoldingContext &context, Parentheses<T> &&x) {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Expr<T> FoldOperation(FoldingContext &context, Negate<T> &&x) {
|
||||
if (auto array{ApplyElementwise(context, x)}) {
|
||||
return *array;
|
||||
|
@ -1224,7 +1224,7 @@ Expr<T> FoldOperation(FoldingContext &context, Negate<T> &&x) {
|
|||
|
||||
// Binary (dyadic) operations
|
||||
|
||||
template<typename LEFT, typename RIGHT>
|
||||
template <typename LEFT, typename RIGHT>
|
||||
std::optional<std::pair<Scalar<LEFT>, Scalar<RIGHT>>> OperandsAreConstants(
|
||||
const Expr<LEFT> &x, const Expr<RIGHT> &y) {
|
||||
if (auto xvalue{GetScalarConstantValue<LEFT>(x)}) {
|
||||
|
@ -1235,13 +1235,13 @@ std::optional<std::pair<Scalar<LEFT>, Scalar<RIGHT>>> OperandsAreConstants(
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
template<typename DERIVED, typename RESULT, typename LEFT, typename RIGHT>
|
||||
template <typename DERIVED, typename RESULT, typename LEFT, typename RIGHT>
|
||||
std::optional<std::pair<Scalar<LEFT>, Scalar<RIGHT>>> OperandsAreConstants(
|
||||
const Operation<DERIVED, RESULT, LEFT, RIGHT> &operation) {
|
||||
return OperandsAreConstants(operation.left(), operation.right());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Expr<T> FoldOperation(FoldingContext &context, Add<T> &&x) {
|
||||
if (auto array{ApplyElementwise(context, x)}) {
|
||||
return *array;
|
||||
|
@ -1266,7 +1266,7 @@ Expr<T> FoldOperation(FoldingContext &context, Add<T> &&x) {
|
|||
return Expr<T>{std::move(x)};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Expr<T> FoldOperation(FoldingContext &context, Subtract<T> &&x) {
|
||||
if (auto array{ApplyElementwise(context, x)}) {
|
||||
return *array;
|
||||
|
@ -1292,7 +1292,7 @@ Expr<T> FoldOperation(FoldingContext &context, Subtract<T> &&x) {
|
|||
return Expr<T>{std::move(x)};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Expr<T> FoldOperation(FoldingContext &context, Multiply<T> &&x) {
|
||||
if (auto array{ApplyElementwise(context, x)}) {
|
||||
return *array;
|
||||
|
@ -1317,7 +1317,7 @@ Expr<T> FoldOperation(FoldingContext &context, Multiply<T> &&x) {
|
|||
return Expr<T>{std::move(x)};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Expr<T> FoldOperation(FoldingContext &context, Divide<T> &&x) {
|
||||
if (auto array{ApplyElementwise(context, x)}) {
|
||||
return *array;
|
||||
|
@ -1346,7 +1346,7 @@ Expr<T> FoldOperation(FoldingContext &context, Divide<T> &&x) {
|
|||
return Expr<T>{std::move(x)};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Expr<T> FoldOperation(FoldingContext &context, Power<T> &&x) {
|
||||
if (auto array{ApplyElementwise(context, x)}) {
|
||||
return *array;
|
||||
|
@ -1378,7 +1378,7 @@ Expr<T> FoldOperation(FoldingContext &context, Power<T> &&x) {
|
|||
return Expr<T>{std::move(x)};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Expr<T> FoldOperation(FoldingContext &context, RealToIntPower<T> &&x) {
|
||||
if (auto array{ApplyElementwise(context, x)}) {
|
||||
return *array;
|
||||
|
@ -1399,7 +1399,7 @@ Expr<T> FoldOperation(FoldingContext &context, RealToIntPower<T> &&x) {
|
|||
x.right().u);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Expr<T> FoldOperation(FoldingContext &context, Extremum<T> &&x) {
|
||||
if (auto array{ApplyElementwise(context, x,
|
||||
std::function<Expr<T>(Expr<T> &&, Expr<T> &&)>{[=](Expr<T> &&l,
|
||||
|
@ -1436,7 +1436,7 @@ Expr<T> FoldOperation(FoldingContext &context, Extremum<T> &&x) {
|
|||
return Expr<T>{std::move(x)};
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Real, KIND>> ToReal(
|
||||
FoldingContext &context, Expr<SomeType> &&expr) {
|
||||
using Result = Type<TypeCategory::Real, KIND>;
|
||||
|
@ -1466,7 +1466,7 @@ Expr<Type<TypeCategory::Real, KIND>> ToReal(
|
|||
return result.value();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Expr<T> ExpressionBase<T>::Rewrite(FoldingContext &context, Expr<T> &&expr) {
|
||||
return std::visit(
|
||||
[&](auto &&x) -> Expr<T> {
|
||||
|
@ -1486,5 +1486,5 @@ Expr<T> ExpressionBase<T>::Rewrite(FoldingContext &context, Expr<T> &&expr) {
|
|||
|
||||
FOR_EACH_TYPE_AND_KIND(extern template class ExpressionBase, )
|
||||
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
#endif // FORTRAN_EVALUATE_FOLD_IMPLEMENTATION_H_
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
namespace Fortran::evaluate {
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Integer, KIND>> LBOUND(FoldingContext &context,
|
||||
FunctionRef<Type<TypeCategory::Integer, KIND>> &&funcRef) {
|
||||
using T = Type<TypeCategory::Integer, KIND>;
|
||||
|
@ -65,7 +65,7 @@ Expr<Type<TypeCategory::Integer, KIND>> LBOUND(FoldingContext &context,
|
|||
return Expr<T>{std::move(funcRef)};
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Integer, KIND>> UBOUND(FoldingContext &context,
|
||||
FunctionRef<Type<TypeCategory::Integer, KIND>> &&funcRef) {
|
||||
using T = Type<TypeCategory::Integer, KIND>;
|
||||
|
@ -132,7 +132,7 @@ Expr<Type<TypeCategory::Integer, KIND>> UBOUND(FoldingContext &context,
|
|||
return Expr<T>{std::move(funcRef)};
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
|
||||
FoldingContext &context,
|
||||
FunctionRef<Type<TypeCategory::Integer, KIND>> &&funcRef) {
|
||||
|
@ -597,7 +597,7 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
|
|||
}
|
||||
|
||||
// Substitute a bare type parameter reference with its value if it has one now
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Integer, KIND>> FoldOperation(
|
||||
FoldingContext &context, TypeParamInquiry<KIND> &&inquiry) {
|
||||
using IntKIND = Type<TypeCategory::Integer, KIND>;
|
||||
|
@ -644,4 +644,4 @@ std::optional<std::int64_t> ToInt64(const Expr<SomeType> &expr) {
|
|||
|
||||
FOR_EACH_INTEGER_KIND(template class ExpressionBase, )
|
||||
template class ExpressionBase<SomeInteger>;
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
namespace Fortran::evaluate {
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Logical, KIND>> FoldIntrinsicFunction(
|
||||
FoldingContext &context,
|
||||
FunctionRef<Type<TypeCategory::Logical, KIND>> &&funcRef) {
|
||||
|
@ -95,7 +95,7 @@ Expr<Type<TypeCategory::Logical, KIND>> FoldIntrinsicFunction(
|
|||
return Expr<T>{std::move(funcRef)};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Expr<LogicalResult> FoldOperation(
|
||||
FoldingContext &context, Relational<T> &&relation) {
|
||||
if (auto array{ApplyElementwise(context, relation,
|
||||
|
@ -133,7 +133,7 @@ Expr<LogicalResult> FoldOperation(
|
|||
std::move(relation.u));
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Logical, KIND>> FoldOperation(
|
||||
FoldingContext &context, Not<KIND> &&x) {
|
||||
if (auto array{ApplyElementwise(context, x)}) {
|
||||
|
@ -147,7 +147,7 @@ Expr<Type<TypeCategory::Logical, KIND>> FoldOperation(
|
|||
return Expr<Ty>{x};
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Logical, KIND>> FoldOperation(
|
||||
FoldingContext &context, LogicalOperation<KIND> &&operation) {
|
||||
using LOGICAL = Type<TypeCategory::Logical, KIND>;
|
||||
|
@ -162,11 +162,20 @@ Expr<Type<TypeCategory::Logical, KIND>> FoldOperation(
|
|||
if (auto folded{OperandsAreConstants(operation)}) {
|
||||
bool xt{folded->first.IsTrue()}, yt{folded->second.IsTrue()}, result{};
|
||||
switch (operation.logicalOperator) {
|
||||
case LogicalOperator::And: result = xt && yt; break;
|
||||
case LogicalOperator::Or: result = xt || yt; break;
|
||||
case LogicalOperator::Eqv: result = xt == yt; break;
|
||||
case LogicalOperator::Neqv: result = xt != yt; break;
|
||||
case LogicalOperator::Not: DIE("not a binary operator");
|
||||
case LogicalOperator::And:
|
||||
result = xt && yt;
|
||||
break;
|
||||
case LogicalOperator::Or:
|
||||
result = xt || yt;
|
||||
break;
|
||||
case LogicalOperator::Eqv:
|
||||
result = xt == yt;
|
||||
break;
|
||||
case LogicalOperator::Neqv:
|
||||
result = xt != yt;
|
||||
break;
|
||||
case LogicalOperator::Not:
|
||||
DIE("not a binary operator");
|
||||
}
|
||||
return Expr<LOGICAL>{Constant<LOGICAL>{result}};
|
||||
}
|
||||
|
@ -175,4 +184,4 @@ Expr<Type<TypeCategory::Logical, KIND>> FoldOperation(
|
|||
|
||||
FOR_EACH_LOGICAL_KIND(template class ExpressionBase, )
|
||||
template class ExpressionBase<SomeLogical>;
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
namespace Fortran::evaluate {
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Real, KIND>> FoldIntrinsicFunction(
|
||||
FoldingContext &context,
|
||||
FunctionRef<Type<TypeCategory::Real, KIND>> &&funcRef) {
|
||||
|
@ -135,7 +135,7 @@ Expr<Type<TypeCategory::Real, KIND>> FoldIntrinsicFunction(
|
|||
return Expr<T>{std::move(funcRef)};
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Real, KIND>> FoldOperation(
|
||||
FoldingContext &context, ComplexComponent<KIND> &&x) {
|
||||
using Operand = Type<TypeCategory::Complex, KIND>;
|
||||
|
@ -162,4 +162,4 @@ Expr<Type<TypeCategory::Real, KIND>> FoldOperation(
|
|||
|
||||
FOR_EACH_REAL_KIND(template class ExpressionBase, )
|
||||
template class ExpressionBase<SomeReal>;
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
|
|
|
@ -85,14 +85,14 @@ Triplet FoldOperation(FoldingContext &context, Triplet &&triplet) {
|
|||
}
|
||||
|
||||
Subscript FoldOperation(FoldingContext &context, Subscript &&subscript) {
|
||||
return std::visit(
|
||||
common::visitors{
|
||||
return std::visit(common::visitors{
|
||||
[&](IndirectSubscriptIntegerExpr &&expr) {
|
||||
expr.value() = Fold(context, std::move(expr.value()));
|
||||
return Subscript(std::move(expr));
|
||||
},
|
||||
[&](Triplet &&triplet) {
|
||||
return Subscript(FoldOperation(context, std::move(triplet)));
|
||||
return Subscript(
|
||||
FoldOperation(context, std::move(triplet)));
|
||||
},
|
||||
},
|
||||
std::move(subscript.u));
|
||||
|
@ -128,8 +128,7 @@ CoarrayRef FoldOperation(FoldingContext &context, CoarrayRef &&coarrayRef) {
|
|||
}
|
||||
|
||||
DataRef FoldOperation(FoldingContext &context, DataRef &&dataRef) {
|
||||
return std::visit(
|
||||
common::visitors{
|
||||
return std::visit(common::visitors{
|
||||
[&](SymbolRef symbol) { return DataRef{*symbol}; },
|
||||
[&](auto &&x) {
|
||||
return DataRef{FoldOperation(context, std::move(x))};
|
||||
|
@ -188,4 +187,4 @@ Expr<ImpliedDoIndex::Result> FoldOperation(
|
|||
template class ExpressionBase<SomeDerived>;
|
||||
template class ExpressionBase<SomeType>;
|
||||
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
|
|
|
@ -31,7 +31,7 @@ static void ShapeAsFortran(
|
|||
}
|
||||
}
|
||||
|
||||
template<typename RESULT, typename VALUE>
|
||||
template <typename RESULT, typename VALUE>
|
||||
llvm::raw_ostream &ConstantBase<RESULT, VALUE>::AsFortran(
|
||||
llvm::raw_ostream &o) const {
|
||||
if (Rank() > 1) {
|
||||
|
@ -72,7 +72,7 @@ llvm::raw_ostream &ConstantBase<RESULT, VALUE>::AsFortran(
|
|||
return o;
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
llvm::raw_ostream &Constant<Type<TypeCategory::Character, KIND>>::AsFortran(
|
||||
llvm::raw_ostream &o) const {
|
||||
if (Rank() > 1) {
|
||||
|
@ -161,52 +161,56 @@ enum class Precedence { // in increasing order for sane comparisons
|
|||
Top,
|
||||
};
|
||||
|
||||
template<typename A> constexpr Precedence ToPrecedence(const A &) {
|
||||
template <typename A> constexpr Precedence ToPrecedence(const A &) {
|
||||
return Precedence::Top;
|
||||
}
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
static Precedence ToPrecedence(const LogicalOperation<KIND> &x) {
|
||||
switch (x.logicalOperator) {
|
||||
SWITCH_COVERS_ALL_CASES
|
||||
case LogicalOperator::And: return Precedence::And;
|
||||
case LogicalOperator::Or: return Precedence::Or;
|
||||
case LogicalOperator::Not: return Precedence::Not;
|
||||
case LogicalOperator::And:
|
||||
return Precedence::And;
|
||||
case LogicalOperator::Or:
|
||||
return Precedence::Or;
|
||||
case LogicalOperator::Not:
|
||||
return Precedence::Not;
|
||||
case LogicalOperator::Eqv:
|
||||
case LogicalOperator::Neqv: return Precedence::Equivalence;
|
||||
case LogicalOperator::Neqv:
|
||||
return Precedence::Equivalence;
|
||||
}
|
||||
}
|
||||
template<int KIND> constexpr Precedence ToPrecedence(const Not<KIND> &) {
|
||||
template <int KIND> constexpr Precedence ToPrecedence(const Not<KIND> &) {
|
||||
return Precedence::Not;
|
||||
}
|
||||
template<typename T> constexpr Precedence ToPrecedence(const Relational<T> &) {
|
||||
template <typename T> constexpr Precedence ToPrecedence(const Relational<T> &) {
|
||||
return Precedence::Relational;
|
||||
}
|
||||
template<typename T> constexpr Precedence ToPrecedence(const Add<T> &) {
|
||||
template <typename T> constexpr Precedence ToPrecedence(const Add<T> &) {
|
||||
return Precedence::Additive;
|
||||
}
|
||||
template<typename T> constexpr Precedence ToPrecedence(const Subtract<T> &) {
|
||||
template <typename T> constexpr Precedence ToPrecedence(const Subtract<T> &) {
|
||||
return Precedence::Additive;
|
||||
}
|
||||
template<int KIND> constexpr Precedence ToPrecedence(const Concat<KIND> &) {
|
||||
template <int KIND> constexpr Precedence ToPrecedence(const Concat<KIND> &) {
|
||||
return Precedence::Additive;
|
||||
}
|
||||
template<typename T> constexpr Precedence ToPrecedence(const Negate<T> &) {
|
||||
template <typename T> constexpr Precedence ToPrecedence(const Negate<T> &) {
|
||||
return Precedence::Negate;
|
||||
}
|
||||
template<typename T> constexpr Precedence ToPrecedence(const Multiply<T> &) {
|
||||
template <typename T> constexpr Precedence ToPrecedence(const Multiply<T> &) {
|
||||
return Precedence::Multiplicative;
|
||||
}
|
||||
template<typename T> constexpr Precedence ToPrecedence(const Divide<T> &) {
|
||||
template <typename T> constexpr Precedence ToPrecedence(const Divide<T> &) {
|
||||
return Precedence::Multiplicative;
|
||||
}
|
||||
template<typename T> constexpr Precedence ToPrecedence(const Power<T> &) {
|
||||
template <typename T> constexpr Precedence ToPrecedence(const Power<T> &) {
|
||||
return Precedence::Power;
|
||||
}
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
constexpr Precedence ToPrecedence(const RealToIntPower<T> &) {
|
||||
return Precedence::Power;
|
||||
}
|
||||
template<typename T> static Precedence ToPrecedence(const Constant<T> &x) {
|
||||
template <typename T> static Precedence ToPrecedence(const Constant<T> &x) {
|
||||
static constexpr TypeCategory cat{T::category};
|
||||
if constexpr (cat == TypeCategory::Integer || cat == TypeCategory::Real) {
|
||||
if (auto n{GetScalarConstantValue<T>(x)}) {
|
||||
|
@ -217,11 +221,11 @@ template<typename T> static Precedence ToPrecedence(const Constant<T> &x) {
|
|||
}
|
||||
return Precedence::Top;
|
||||
}
|
||||
template<typename T> static Precedence ToPrecedence(const Expr<T> &expr) {
|
||||
template <typename T> static Precedence ToPrecedence(const Expr<T> &expr) {
|
||||
return std::visit([](const auto &x) { return ToPrecedence(x); }, expr.u);
|
||||
}
|
||||
|
||||
template<typename T> static bool IsNegatedScalarConstant(const Expr<T> &expr) {
|
||||
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 (auto n{GetScalarConstantValue<T>(expr)}) {
|
||||
|
@ -231,7 +235,7 @@ template<typename T> static bool IsNegatedScalarConstant(const Expr<T> &expr) {
|
|||
return false;
|
||||
}
|
||||
|
||||
template<TypeCategory CAT>
|
||||
template <TypeCategory CAT>
|
||||
static bool IsNegatedScalarConstant(const Expr<SomeKind<CAT>> &expr) {
|
||||
return std::visit(
|
||||
[](const auto &x) { return IsNegatedScalarConstant(x); }, expr.u);
|
||||
|
@ -241,74 +245,75 @@ struct OperatorSpelling {
|
|||
const char *prefix{""}, *infix{","}, *suffix{""};
|
||||
};
|
||||
|
||||
template<typename A> constexpr OperatorSpelling SpellOperator(const A &) {
|
||||
template <typename A> constexpr OperatorSpelling SpellOperator(const A &) {
|
||||
return OperatorSpelling{};
|
||||
}
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
constexpr OperatorSpelling SpellOperator(const Negate<A> &) {
|
||||
return OperatorSpelling{"-", "", ""};
|
||||
}
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
constexpr OperatorSpelling SpellOperator(const Parentheses<A> &) {
|
||||
return OperatorSpelling{"(", "", ")"};
|
||||
}
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
static OperatorSpelling SpellOperator(const ComplexComponent<KIND> &x) {
|
||||
return {x.isImaginaryPart ? "aimag(" : "real(", "", ")"};
|
||||
}
|
||||
template<int KIND> constexpr OperatorSpelling SpellOperator(const Not<KIND> &) {
|
||||
template <int KIND>
|
||||
constexpr OperatorSpelling SpellOperator(const Not<KIND> &) {
|
||||
return OperatorSpelling{".NOT.", "", ""};
|
||||
}
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
constexpr OperatorSpelling SpellOperator(const SetLength<KIND> &) {
|
||||
return OperatorSpelling{"%SET_LENGTH(", ",", ")"};
|
||||
}
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
constexpr OperatorSpelling SpellOperator(const ComplexConstructor<KIND> &) {
|
||||
return OperatorSpelling{"(", ",", ")"};
|
||||
}
|
||||
template<typename A> constexpr OperatorSpelling SpellOperator(const Add<A> &) {
|
||||
template <typename A> constexpr OperatorSpelling SpellOperator(const Add<A> &) {
|
||||
return OperatorSpelling{"", "+", ""};
|
||||
}
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
constexpr OperatorSpelling SpellOperator(const Subtract<A> &) {
|
||||
return OperatorSpelling{"", "-", ""};
|
||||
}
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
constexpr OperatorSpelling SpellOperator(const Multiply<A> &) {
|
||||
return OperatorSpelling{"", "*", ""};
|
||||
}
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
constexpr OperatorSpelling SpellOperator(const Divide<A> &) {
|
||||
return OperatorSpelling{"", "/", ""};
|
||||
}
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
constexpr OperatorSpelling SpellOperator(const Power<A> &) {
|
||||
return OperatorSpelling{"", "**", ""};
|
||||
}
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
constexpr OperatorSpelling SpellOperator(const RealToIntPower<A> &) {
|
||||
return OperatorSpelling{"", "**", ""};
|
||||
}
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
static OperatorSpelling SpellOperator(const Extremum<A> &x) {
|
||||
return OperatorSpelling{
|
||||
x.ordering == Ordering::Less ? "min(" : "max(", ",", ")"};
|
||||
}
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
constexpr OperatorSpelling SpellOperator(const Concat<KIND> &) {
|
||||
return OperatorSpelling{"", "//", ""};
|
||||
}
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
static OperatorSpelling SpellOperator(const LogicalOperation<KIND> &x) {
|
||||
return OperatorSpelling{"", AsFortran(x.logicalOperator), ""};
|
||||
}
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
static OperatorSpelling SpellOperator(const Relational<T> &x) {
|
||||
return OperatorSpelling{"", AsFortran(x.opr), ""};
|
||||
}
|
||||
|
||||
template<typename D, typename R, typename... O>
|
||||
template <typename D, typename R, typename... O>
|
||||
llvm::raw_ostream &Operation<D, R, O...>::AsFortran(
|
||||
llvm::raw_ostream &o) const {
|
||||
Precedence lhsPrec{ToPrecedence(left())};
|
||||
|
@ -340,7 +345,7 @@ llvm::raw_ostream &Operation<D, R, O...>::AsFortran(
|
|||
return o << spelling.suffix;
|
||||
}
|
||||
|
||||
template<typename TO, TypeCategory FROMCAT>
|
||||
template <typename TO, TypeCategory FROMCAT>
|
||||
llvm::raw_ostream &Convert<TO, FROMCAT>::AsFortran(llvm::raw_ostream &o) const {
|
||||
static_assert(TO::category == TypeCategory::Integer ||
|
||||
TO::category == TypeCategory::Real ||
|
||||
|
@ -364,16 +369,16 @@ llvm::raw_ostream &Relational<SomeType>::AsFortran(llvm::raw_ostream &o) const {
|
|||
return o;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
llvm::raw_ostream &EmitArray(llvm::raw_ostream &o, const Expr<T> &expr) {
|
||||
return expr.AsFortran(o);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
llvm::raw_ostream &EmitArray(
|
||||
llvm::raw_ostream &, const ArrayConstructorValues<T> &);
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
llvm::raw_ostream &EmitArray(llvm::raw_ostream &o, const ImpliedDo<T> &implDo) {
|
||||
o << '(';
|
||||
EmitArray(o, implDo.values());
|
||||
|
@ -385,7 +390,7 @@ llvm::raw_ostream &EmitArray(llvm::raw_ostream &o, const ImpliedDo<T> &implDo) {
|
|||
return o;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
llvm::raw_ostream &EmitArray(
|
||||
llvm::raw_ostream &o, const ArrayConstructorValues<T> &values) {
|
||||
const char *sep{""};
|
||||
|
@ -397,14 +402,14 @@ llvm::raw_ostream &EmitArray(
|
|||
return o;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
llvm::raw_ostream &ArrayConstructor<T>::AsFortran(llvm::raw_ostream &o) const {
|
||||
o << '[' << GetType().AsFortran() << "::";
|
||||
EmitArray(o, *this);
|
||||
return o << ']';
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
llvm::raw_ostream &
|
||||
ArrayConstructor<Type<TypeCategory::Character, KIND>>::AsFortran(
|
||||
llvm::raw_ostream &o) const {
|
||||
|
@ -420,7 +425,7 @@ llvm::raw_ostream &ArrayConstructor<SomeDerived>::AsFortran(
|
|||
return o << ']';
|
||||
}
|
||||
|
||||
template<typename RESULT>
|
||||
template <typename RESULT>
|
||||
std::string ExpressionBase<RESULT>::AsFortran() const {
|
||||
std::string buf;
|
||||
llvm::raw_string_ostream ss{buf};
|
||||
|
@ -428,11 +433,10 @@ std::string ExpressionBase<RESULT>::AsFortran() const {
|
|||
return ss.str();
|
||||
}
|
||||
|
||||
template<typename RESULT>
|
||||
template <typename RESULT>
|
||||
llvm::raw_ostream &ExpressionBase<RESULT>::AsFortran(
|
||||
llvm::raw_ostream &o) const {
|
||||
std::visit(
|
||||
common::visitors{
|
||||
std::visit(common::visitors{
|
||||
[&](const BOZLiteralConstant &x) {
|
||||
o << "z'" << x.Hexadecimal() << "'";
|
||||
},
|
||||
|
@ -542,17 +546,17 @@ llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const std::u32string &lit) {
|
|||
return o << parser::QuoteCharacterLiteral(lit);
|
||||
}
|
||||
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const A &x) {
|
||||
return x.AsFortran(o);
|
||||
}
|
||||
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, common::Reference<A> x) {
|
||||
return EmitVar(o, *x);
|
||||
}
|
||||
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
llvm::raw_ostream &EmitVar(
|
||||
llvm::raw_ostream &o, const A *p, const char *kw = nullptr) {
|
||||
if (p) {
|
||||
|
@ -564,7 +568,7 @@ llvm::raw_ostream &EmitVar(
|
|||
return o;
|
||||
}
|
||||
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
llvm::raw_ostream &EmitVar(
|
||||
llvm::raw_ostream &o, const std::optional<A> &x, const char *kw = nullptr) {
|
||||
if (x) {
|
||||
|
@ -576,7 +580,7 @@ llvm::raw_ostream &EmitVar(
|
|||
return o;
|
||||
}
|
||||
|
||||
template<typename A, bool COPY>
|
||||
template <typename A, bool COPY>
|
||||
llvm::raw_ostream &EmitVar(llvm::raw_ostream &o,
|
||||
const common::Indirection<A, COPY> &p, const char *kw = nullptr) {
|
||||
if (kw) {
|
||||
|
@ -586,13 +590,13 @@ llvm::raw_ostream &EmitVar(llvm::raw_ostream &o,
|
|||
return o;
|
||||
}
|
||||
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const std::shared_ptr<A> &p) {
|
||||
CHECK(p);
|
||||
return EmitVar(o, *p);
|
||||
}
|
||||
|
||||
template<typename... A>
|
||||
template <typename... A>
|
||||
llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const std::variant<A...> &u) {
|
||||
std::visit([&](const auto &x) { EmitVar(o, x); }, u);
|
||||
return o;
|
||||
|
@ -602,7 +606,7 @@ llvm::raw_ostream &BaseObject::AsFortran(llvm::raw_ostream &o) const {
|
|||
return EmitVar(o, u);
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
llvm::raw_ostream &TypeParamInquiry<KIND>::AsFortran(
|
||||
llvm::raw_ostream &o) const {
|
||||
if (base_) {
|
||||
|
@ -617,8 +621,7 @@ llvm::raw_ostream &Component::AsFortran(llvm::raw_ostream &o) const {
|
|||
}
|
||||
|
||||
llvm::raw_ostream &NamedEntity::AsFortran(llvm::raw_ostream &o) const {
|
||||
std::visit(
|
||||
common::visitors{
|
||||
std::visit(common::visitors{
|
||||
[&](SymbolRef s) { EmitVar(o, s); },
|
||||
[&](const Component &c) { c.AsFortran(o); },
|
||||
},
|
||||
|
@ -699,10 +702,9 @@ llvm::raw_ostream &ProcedureDesignator::AsFortran(llvm::raw_ostream &o) const {
|
|||
return EmitVar(o, u);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
llvm::raw_ostream &Designator<T>::AsFortran(llvm::raw_ostream &o) const {
|
||||
std::visit(
|
||||
common::visitors{
|
||||
std::visit(common::visitors{
|
||||
[&](SymbolRef symbol) { EmitVar(o, symbol); },
|
||||
[&](const auto &x) { x.AsFortran(o); },
|
||||
},
|
||||
|
@ -712,11 +714,20 @@ llvm::raw_ostream &Designator<T>::AsFortran(llvm::raw_ostream &o) const {
|
|||
|
||||
llvm::raw_ostream &DescriptorInquiry::AsFortran(llvm::raw_ostream &o) const {
|
||||
switch (field_) {
|
||||
case Field::LowerBound: o << "lbound("; break;
|
||||
case Field::Extent: o << "size("; break;
|
||||
case Field::Stride: o << "%STRIDE("; break;
|
||||
case Field::Rank: o << "rank("; break;
|
||||
case Field::Len: break;
|
||||
case Field::LowerBound:
|
||||
o << "lbound(";
|
||||
break;
|
||||
case Field::Extent:
|
||||
o << "size(";
|
||||
break;
|
||||
case Field::Stride:
|
||||
o << "%STRIDE(";
|
||||
break;
|
||||
case Field::Rank:
|
||||
o << "rank(";
|
||||
break;
|
||||
case Field::Len:
|
||||
break;
|
||||
}
|
||||
base_.AsFortran(o);
|
||||
if (field_ == Field::Len) {
|
||||
|
@ -769,4 +780,4 @@ llvm::raw_ostream &Assignment::AsFortran(llvm::raw_ostream &o) const {
|
|||
INSTANTIATE_CONSTANT_TEMPLATES
|
||||
INSTANTIATE_EXPRESSION_TEMPLATES
|
||||
INSTANTIATE_VARIABLE_TEMPLATES
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
|
|
|
@ -76,10 +76,18 @@ void HostFloatingPointEnvironment::SetUpHostFloatingPointEnvironment(
|
|||
return;
|
||||
}
|
||||
switch (context.rounding().mode) {
|
||||
case common::RoundingMode::TiesToEven: fesetround(FE_TONEAREST); break;
|
||||
case common::RoundingMode::ToZero: fesetround(FE_TOWARDZERO); break;
|
||||
case common::RoundingMode::Up: fesetround(FE_UPWARD); break;
|
||||
case common::RoundingMode::Down: fesetround(FE_DOWNWARD); break;
|
||||
case common::RoundingMode::TiesToEven:
|
||||
fesetround(FE_TONEAREST);
|
||||
break;
|
||||
case common::RoundingMode::ToZero:
|
||||
fesetround(FE_TOWARDZERO);
|
||||
break;
|
||||
case common::RoundingMode::Up:
|
||||
fesetround(FE_UPWARD);
|
||||
break;
|
||||
case common::RoundingMode::Down:
|
||||
fesetround(FE_DOWNWARD);
|
||||
break;
|
||||
case common::RoundingMode::TiesAwayFromZero:
|
||||
fesetround(FE_TONEAREST);
|
||||
context.messages().Say(
|
||||
|
@ -135,4 +143,4 @@ void HostFloatingPointEnvironment::CheckAndRestoreFloatingPointEnvironment(
|
|||
}
|
||||
errno = 0;
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::evaluate::host
|
||||
|
|
|
@ -50,12 +50,12 @@ private:
|
|||
// Type mapping from F18 types to host types
|
||||
struct UnsupportedType {}; // There is no host type for the F18 type
|
||||
|
||||
template<typename FTN_T> struct HostTypeHelper {
|
||||
template <typename FTN_T> struct HostTypeHelper {
|
||||
using Type = UnsupportedType;
|
||||
};
|
||||
template<typename FTN_T> using HostType = typename HostTypeHelper<FTN_T>::Type;
|
||||
template <typename FTN_T> using HostType = typename HostTypeHelper<FTN_T>::Type;
|
||||
|
||||
template<typename... T> constexpr inline bool HostTypeExists() {
|
||||
template <typename... T> constexpr inline bool HostTypeExists() {
|
||||
return (... && (!std::is_same_v<HostType<T>, UnsupportedType>));
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ template<typename... T> constexpr inline bool HostTypeExists() {
|
|||
// duplication.
|
||||
|
||||
// Scalar conversion utilities from host scalars to F18 scalars
|
||||
template<typename FTN_T>
|
||||
template <typename FTN_T>
|
||||
inline constexpr Scalar<FTN_T> CastHostToFortran(const HostType<FTN_T> &x) {
|
||||
static_assert(HostTypeExists<FTN_T>());
|
||||
if constexpr (FTN_T::category == TypeCategory::Complex &&
|
||||
|
@ -79,7 +79,7 @@ inline constexpr Scalar<FTN_T> CastHostToFortran(const HostType<FTN_T> &x) {
|
|||
}
|
||||
|
||||
// Scalar conversion utilities from F18 scalars to host scalars
|
||||
template<typename FTN_T>
|
||||
template <typename FTN_T>
|
||||
inline constexpr HostType<FTN_T> CastFortranToHost(const Scalar<FTN_T> &x) {
|
||||
static_assert(HostTypeExists<FTN_T>());
|
||||
if constexpr (FTN_T::category == TypeCategory::Complex &&
|
||||
|
@ -93,40 +93,40 @@ inline constexpr HostType<FTN_T> CastFortranToHost(const Scalar<FTN_T> &x) {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename T> struct BiggerOrSameHostTypeHelper {
|
||||
template <typename T> struct BiggerOrSameHostTypeHelper {
|
||||
using Type =
|
||||
std::conditional_t<HostTypeExists<T>(), HostType<T>, UnsupportedType>;
|
||||
using FortranType = T;
|
||||
};
|
||||
|
||||
template<typename FTN_T>
|
||||
template <typename FTN_T>
|
||||
using BiggerOrSameHostType = typename BiggerOrSameHostTypeHelper<FTN_T>::Type;
|
||||
template<typename FTN_T>
|
||||
template <typename FTN_T>
|
||||
using BiggerOrSameFortranTypeSupportedOnHost =
|
||||
typename BiggerOrSameHostTypeHelper<FTN_T>::FortranType;
|
||||
|
||||
template<typename... T> constexpr inline bool BiggerOrSameHostTypeExists() {
|
||||
template <typename... T> constexpr inline bool BiggerOrSameHostTypeExists() {
|
||||
return (... && (!std::is_same_v<BiggerOrSameHostType<T>, UnsupportedType>));
|
||||
}
|
||||
|
||||
// Defining the actual mapping
|
||||
template<> struct HostTypeHelper<Type<TypeCategory::Integer, 1>> {
|
||||
template <> struct HostTypeHelper<Type<TypeCategory::Integer, 1>> {
|
||||
using Type = std::int8_t;
|
||||
};
|
||||
|
||||
template<> struct HostTypeHelper<Type<TypeCategory::Integer, 2>> {
|
||||
template <> struct HostTypeHelper<Type<TypeCategory::Integer, 2>> {
|
||||
using Type = std::int16_t;
|
||||
};
|
||||
|
||||
template<> struct HostTypeHelper<Type<TypeCategory::Integer, 4>> {
|
||||
template <> struct HostTypeHelper<Type<TypeCategory::Integer, 4>> {
|
||||
using Type = std::int32_t;
|
||||
};
|
||||
|
||||
template<> struct HostTypeHelper<Type<TypeCategory::Integer, 8>> {
|
||||
template <> struct HostTypeHelper<Type<TypeCategory::Integer, 8>> {
|
||||
using Type = std::int64_t;
|
||||
};
|
||||
|
||||
template<> struct HostTypeHelper<Type<TypeCategory::Integer, 16>> {
|
||||
template <> struct HostTypeHelper<Type<TypeCategory::Integer, 16>> {
|
||||
#if (defined(__GNUC__) || defined(__clang__)) && defined(__SIZEOF_INT128__)
|
||||
using Type = __int128_t;
|
||||
#else
|
||||
|
@ -137,21 +137,21 @@ template<> struct HostTypeHelper<Type<TypeCategory::Integer, 16>> {
|
|||
// TODO no mapping to host types are defined currently for 16bits float
|
||||
// It should be defined when gcc/clang have a better support for it.
|
||||
|
||||
template<> struct HostTypeHelper<Type<TypeCategory::Real, 4>> {
|
||||
template <> struct HostTypeHelper<Type<TypeCategory::Real, 4>> {
|
||||
// IEE 754 64bits
|
||||
using Type = std::conditional_t<sizeof(float) == 4 &&
|
||||
std::numeric_limits<float>::is_iec559,
|
||||
float, UnsupportedType>;
|
||||
};
|
||||
|
||||
template<> struct HostTypeHelper<Type<TypeCategory::Real, 8>> {
|
||||
template <> struct HostTypeHelper<Type<TypeCategory::Real, 8>> {
|
||||
// IEE 754 64bits
|
||||
using Type = std::conditional_t<sizeof(double) == 8 &&
|
||||
std::numeric_limits<double>::is_iec559,
|
||||
double, UnsupportedType>;
|
||||
};
|
||||
|
||||
template<> struct HostTypeHelper<Type<TypeCategory::Real, 10>> {
|
||||
template <> struct HostTypeHelper<Type<TypeCategory::Real, 10>> {
|
||||
// X87 80bits
|
||||
using Type = std::conditional_t<sizeof(long double) >= 10 &&
|
||||
std::numeric_limits<long double>::digits == 64 &&
|
||||
|
@ -159,7 +159,7 @@ template<> struct HostTypeHelper<Type<TypeCategory::Real, 10>> {
|
|||
long double, UnsupportedType>;
|
||||
};
|
||||
|
||||
template<> struct HostTypeHelper<Type<TypeCategory::Real, 16>> {
|
||||
template <> struct HostTypeHelper<Type<TypeCategory::Real, 16>> {
|
||||
// IEE 754 128bits
|
||||
using Type = std::conditional_t<sizeof(long double) == 16 &&
|
||||
std::numeric_limits<long double>::digits == 113 &&
|
||||
|
@ -167,30 +167,30 @@ template<> struct HostTypeHelper<Type<TypeCategory::Real, 16>> {
|
|||
long double, UnsupportedType>;
|
||||
};
|
||||
|
||||
template<int KIND> struct HostTypeHelper<Type<TypeCategory::Complex, KIND>> {
|
||||
template <int KIND> struct HostTypeHelper<Type<TypeCategory::Complex, KIND>> {
|
||||
using RealT = Fortran::evaluate::Type<TypeCategory::Real, KIND>;
|
||||
using Type = std::conditional_t<HostTypeExists<RealT>(),
|
||||
std::complex<HostType<RealT>>, UnsupportedType>;
|
||||
};
|
||||
|
||||
template<int KIND> struct HostTypeHelper<Type<TypeCategory::Logical, KIND>> {
|
||||
template <int KIND> struct HostTypeHelper<Type<TypeCategory::Logical, KIND>> {
|
||||
using Type = std::conditional_t<KIND <= 8, std::uint8_t, UnsupportedType>;
|
||||
};
|
||||
|
||||
template<int KIND> struct HostTypeHelper<Type<TypeCategory::Character, KIND>> {
|
||||
template <int KIND> struct HostTypeHelper<Type<TypeCategory::Character, KIND>> {
|
||||
using Type =
|
||||
Scalar<typename Fortran::evaluate::Type<TypeCategory::Character, KIND>>;
|
||||
};
|
||||
|
||||
// Type mapping from host types to F18 types. This need to be placed after all
|
||||
// HostTypeHelper specializations.
|
||||
template<typename T, typename... TT> struct IndexInTupleHelper {};
|
||||
template<typename T, typename... TT>
|
||||
template <typename T, typename... TT> struct IndexInTupleHelper {};
|
||||
template <typename T, typename... TT>
|
||||
struct IndexInTupleHelper<T, std::tuple<TT...>> {
|
||||
static constexpr int value{common::TypeIndex<T, TT...>};
|
||||
};
|
||||
struct UnknownType {}; // the host type does not match any F18 types
|
||||
template<typename HOST_T> struct FortranTypeHelper {
|
||||
template <typename HOST_T> struct FortranTypeHelper {
|
||||
using HostTypeMapping =
|
||||
common::MapTemplate<HostType, AllIntrinsicTypes, std::tuple>;
|
||||
static constexpr int index{
|
||||
|
@ -202,38 +202,38 @@ template<typename HOST_T> struct FortranTypeHelper {
|
|||
UnknownType>;
|
||||
};
|
||||
|
||||
template<typename HOST_T>
|
||||
template <typename HOST_T>
|
||||
using FortranType = typename FortranTypeHelper<HOST_T>::Type;
|
||||
|
||||
template<typename... HT> constexpr inline bool FortranTypeExists() {
|
||||
template <typename... HT> constexpr inline bool FortranTypeExists() {
|
||||
return (... && (!std::is_same_v<FortranType<HT>, UnknownType>));
|
||||
}
|
||||
|
||||
// Utility to find "bigger" types that exist on host. By bigger, it is meant
|
||||
// that the bigger type can represent all the values of the smaller types
|
||||
// without information loss.
|
||||
template<TypeCategory cat, int KIND> struct NextBiggerReal {
|
||||
template <TypeCategory cat, int KIND> struct NextBiggerReal {
|
||||
using Type = void;
|
||||
};
|
||||
template<TypeCategory cat> struct NextBiggerReal<cat, 2> {
|
||||
template <TypeCategory cat> struct NextBiggerReal<cat, 2> {
|
||||
using Type = Fortran::evaluate::Type<cat, 4>;
|
||||
};
|
||||
template<TypeCategory cat> struct NextBiggerReal<cat, 3> {
|
||||
template <TypeCategory cat> struct NextBiggerReal<cat, 3> {
|
||||
using Type = Fortran::evaluate::Type<cat, 4>;
|
||||
};
|
||||
template<TypeCategory cat> struct NextBiggerReal<cat, 4> {
|
||||
template <TypeCategory cat> struct NextBiggerReal<cat, 4> {
|
||||
using Type = Fortran::evaluate::Type<cat, 8>;
|
||||
};
|
||||
|
||||
template<TypeCategory cat> struct NextBiggerReal<cat, 8> {
|
||||
template <TypeCategory cat> struct NextBiggerReal<cat, 8> {
|
||||
using Type = Fortran::evaluate::Type<cat, 10>;
|
||||
};
|
||||
|
||||
template<TypeCategory cat> struct NextBiggerReal<cat, 10> {
|
||||
template <TypeCategory cat> struct NextBiggerReal<cat, 10> {
|
||||
using Type = Fortran::evaluate::Type<cat, 16>;
|
||||
};
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
struct BiggerOrSameHostTypeHelper<Type<TypeCategory::Real, KIND>> {
|
||||
using T = Fortran::evaluate::Type<TypeCategory::Real, KIND>;
|
||||
using NextT = typename NextBiggerReal<TypeCategory::Real, KIND>::Type;
|
||||
|
@ -243,7 +243,7 @@ struct BiggerOrSameHostTypeHelper<Type<TypeCategory::Real, KIND>> {
|
|||
typename BiggerOrSameHostTypeHelper<NextT>::FortranType>;
|
||||
};
|
||||
|
||||
template<int KIND>
|
||||
template <int KIND>
|
||||
struct BiggerOrSameHostTypeHelper<Type<TypeCategory::Complex, KIND>> {
|
||||
using T = Fortran::evaluate::Type<TypeCategory::Complex, KIND>;
|
||||
using NextT = typename NextBiggerReal<TypeCategory::Complex, KIND>::Type;
|
||||
|
@ -252,7 +252,7 @@ struct BiggerOrSameHostTypeHelper<Type<TypeCategory::Complex, KIND>> {
|
|||
using FortranType = std::conditional_t<HostTypeExists<T>(), T,
|
||||
typename BiggerOrSameHostTypeHelper<NextT>::FortranType>;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace host
|
||||
} // namespace Fortran::evaluate
|
||||
|
||||
#endif // FORTRAN_EVALUATE_HOST_H_
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
namespace Fortran::evaluate {
|
||||
|
||||
template<typename REAL, typename INT>
|
||||
template <typename REAL, typename INT>
|
||||
ValueWithRealFlags<REAL> TimesIntPowerOf(const REAL &factor, const REAL &base,
|
||||
const INT &power, Rounding rounding = defaultRounding) {
|
||||
ValueWithRealFlags<REAL> result{factor};
|
||||
|
@ -48,11 +48,11 @@ ValueWithRealFlags<REAL> TimesIntPowerOf(const REAL &factor, const REAL &base,
|
|||
return result;
|
||||
}
|
||||
|
||||
template<typename REAL, typename INT>
|
||||
template <typename REAL, typename INT>
|
||||
ValueWithRealFlags<REAL> IntPower(
|
||||
const REAL &base, const INT &power, Rounding rounding = defaultRounding) {
|
||||
REAL one{REAL::FromInteger(INT{1}).value};
|
||||
return TimesIntPowerOf(one, base, power, rounding);
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
#endif // FORTRAN_EVALUATE_INT_POWER_H_
|
||||
|
|
|
@ -28,4 +28,4 @@ static_assert(Integer<64>::partBits == 32);
|
|||
static_assert(std::is_same_v<typename Integer<64>::Part, std::uint32_t>);
|
||||
static_assert(Integer<128>::partBits == 32);
|
||||
static_assert(std::is_same_v<typename Integer<128>::Part, std::uint32_t>);
|
||||
}
|
||||
} // namespace Fortran::evaluate::value
|
||||
|
|
|
@ -29,8 +29,8 @@ namespace Fortran::evaluate {
|
|||
// Define meaningful types for the runtime
|
||||
using RuntimeTypes = evaluate::AllIntrinsicTypes;
|
||||
|
||||
template<typename T, typename... TT> struct IndexInTupleHelper {};
|
||||
template<typename T, typename... TT>
|
||||
template <typename T, typename... TT> struct IndexInTupleHelper {};
|
||||
template <typename T, typename... TT>
|
||||
struct IndexInTupleHelper<T, std::tuple<TT...>> {
|
||||
static constexpr TypeCode value{common::TypeIndex<T, TT...>};
|
||||
};
|
||||
|
@ -38,36 +38,36 @@ struct IndexInTupleHelper<T, std::tuple<TT...>> {
|
|||
static_assert(
|
||||
std::tuple_size_v<RuntimeTypes> < std::numeric_limits<TypeCode>::max(),
|
||||
"TypeCode is too small");
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
inline constexpr TypeCode typeCodeOf{
|
||||
IndexInTupleHelper<T, RuntimeTypes>::value};
|
||||
|
||||
template<TypeCode n>
|
||||
template <TypeCode n>
|
||||
using RuntimeTypeOf = typename std::tuple_element_t<n, RuntimeTypes>;
|
||||
|
||||
template<typename TA, PassBy Pass>
|
||||
template <typename TA, PassBy Pass>
|
||||
using HostArgType = std::conditional_t<Pass == PassBy::Ref,
|
||||
std::add_lvalue_reference_t<std::add_const_t<host::HostType<TA>>>,
|
||||
host::HostType<TA>>;
|
||||
|
||||
template<typename TR, typename... ArgInfo>
|
||||
template <typename TR, typename... ArgInfo>
|
||||
using HostFuncPointer = FuncPointer<host::HostType<TR>,
|
||||
HostArgType<typename ArgInfo::Type, ArgInfo::pass>...>;
|
||||
|
||||
// Software Subnormal Flushing helper.
|
||||
template<typename T> struct Flusher {
|
||||
template <typename T> struct Flusher {
|
||||
// Only flush floating-points. Forward other scalars untouched.
|
||||
static constexpr inline const Scalar<T> &FlushSubnormals(const Scalar<T> &x) {
|
||||
return x;
|
||||
}
|
||||
};
|
||||
template<int Kind> struct Flusher<Type<TypeCategory::Real, Kind>> {
|
||||
template <int Kind> struct Flusher<Type<TypeCategory::Real, Kind>> {
|
||||
using T = Type<TypeCategory::Real, Kind>;
|
||||
static constexpr inline Scalar<T> FlushSubnormals(const Scalar<T> &x) {
|
||||
return x.FlushSubnormalToZero();
|
||||
}
|
||||
};
|
||||
template<int Kind> struct Flusher<Type<TypeCategory::Complex, Kind>> {
|
||||
template <int Kind> struct Flusher<Type<TypeCategory::Complex, Kind>> {
|
||||
using T = Type<TypeCategory::Complex, Kind>;
|
||||
static constexpr inline Scalar<T> FlushSubnormals(const Scalar<T> &x) {
|
||||
return x.FlushSubnormalToZero();
|
||||
|
@ -75,7 +75,7 @@ template<int Kind> struct Flusher<Type<TypeCategory::Complex, Kind>> {
|
|||
};
|
||||
|
||||
// Callable factory
|
||||
template<typename TR, typename... ArgInfo> struct CallableHostWrapper {
|
||||
template <typename TR, typename... ArgInfo> struct CallableHostWrapper {
|
||||
static Scalar<TR> scalarCallable(FoldingContext &context,
|
||||
HostFuncPointer<TR, ArgInfo...> func,
|
||||
const Scalar<typename ArgInfo::Type> &... x) {
|
||||
|
@ -120,19 +120,19 @@ template<typename TR, typename... ArgInfo> struct CallableHostWrapper {
|
|||
}
|
||||
};
|
||||
|
||||
template<typename TR, typename... TA>
|
||||
template <typename TR, typename... TA>
|
||||
inline GenericFunctionPointer ToGenericFunctionPointer(
|
||||
FuncPointer<TR, TA...> f) {
|
||||
return reinterpret_cast<GenericFunctionPointer>(f);
|
||||
}
|
||||
|
||||
template<typename TR, typename... TA>
|
||||
template <typename TR, typename... TA>
|
||||
inline FuncPointer<TR, TA...> FromGenericFunctionPointer(
|
||||
GenericFunctionPointer g) {
|
||||
return reinterpret_cast<FuncPointer<TR, TA...>>(g);
|
||||
}
|
||||
|
||||
template<typename TR, typename... ArgInfo>
|
||||
template <typename TR, typename... ArgInfo>
|
||||
IntrinsicProcedureRuntimeDescription::IntrinsicProcedureRuntimeDescription(
|
||||
const Signature<TR, ArgInfo...> &signature, bool isElemental)
|
||||
: name{signature.name}, returnType{typeCodeOf<TR>},
|
||||
|
@ -141,7 +141,7 @@ IntrinsicProcedureRuntimeDescription::IntrinsicProcedureRuntimeDescription(
|
|||
callable{ToGenericFunctionPointer(
|
||||
CallableHostWrapper<TR, ArgInfo...>::MakeScalarCallable())} {}
|
||||
|
||||
template<typename HostTA> static constexpr inline PassBy PassByMethod() {
|
||||
template <typename HostTA> static constexpr inline PassBy PassByMethod() {
|
||||
if constexpr (std::is_pointer_v<std::decay_t<HostTA>> ||
|
||||
std::is_lvalue_reference_v<HostTA>) {
|
||||
return PassBy::Ref;
|
||||
|
@ -149,16 +149,16 @@ template<typename HostTA> static constexpr inline PassBy PassByMethod() {
|
|||
return PassBy::Val;
|
||||
}
|
||||
|
||||
template<typename HostTA>
|
||||
template <typename HostTA>
|
||||
using ArgInfoFromHostType =
|
||||
ArgumentInfo<host::FortranType<std::remove_pointer_t<std::decay_t<HostTA>>>,
|
||||
PassByMethod<HostTA>()>;
|
||||
|
||||
template<typename HostTR, typename... HostTA>
|
||||
template <typename HostTR, typename... HostTA>
|
||||
using SignatureFromHostFuncPointer =
|
||||
Signature<host::FortranType<HostTR>, ArgInfoFromHostType<HostTA>...>;
|
||||
|
||||
template<typename HostTR, typename... HostTA>
|
||||
template <typename HostTR, typename... HostTA>
|
||||
HostRuntimeIntrinsicProcedure::HostRuntimeIntrinsicProcedure(
|
||||
const std::string &name, FuncPointer<HostTR, HostTA...> func,
|
||||
bool isElemental)
|
||||
|
@ -166,7 +166,7 @@ HostRuntimeIntrinsicProcedure::HostRuntimeIntrinsicProcedure(
|
|||
SignatureFromHostFuncPointer<HostTR, HostTA...>{name}, isElemental),
|
||||
handle{ToGenericFunctionPointer(func)} {}
|
||||
|
||||
template<template<typename> typename ConstantContainer, typename TR,
|
||||
template <template <typename> typename ConstantContainer, typename TR,
|
||||
typename... TA>
|
||||
std::optional<HostProcedureWrapper<ConstantContainer, TR, TA...>>
|
||||
HostIntrinsicProceduresLibrary::GetHostProcedureWrapper(
|
||||
|
@ -205,5 +205,5 @@ HostIntrinsicProceduresLibrary::GetHostProcedureWrapper(
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
#endif // FORTRAN_EVALUATE_INTRINSICS_LIBRARY_TEMPLATES_H_
|
||||
|
|
|
@ -46,7 +46,7 @@ bool HostIntrinsicProceduresLibrary::HasEquivalentProcedure(
|
|||
|
||||
// Define which host runtime functions will be used for folding
|
||||
|
||||
template<typename HostT>
|
||||
template <typename HostT>
|
||||
static void AddLibmRealHostProcedures(
|
||||
HostIntrinsicProceduresLibrary &hostIntrinsicLibrary) {
|
||||
using F = FuncPointer<HostT, HostT>;
|
||||
|
@ -96,7 +96,7 @@ static void AddLibmRealHostProcedures(
|
|||
}
|
||||
}
|
||||
|
||||
template<typename HostT>
|
||||
template <typename HostT>
|
||||
static void AddLibmComplexHostProcedures(
|
||||
HostIntrinsicProceduresLibrary &hostIntrinsicLibrary) {
|
||||
using F = FuncPointer<std::complex<HostT>, const std::complex<HostT> &>;
|
||||
|
@ -207,21 +207,21 @@ enum class I {
|
|||
enum class L { F, R, P };
|
||||
|
||||
struct NoSuchRuntimeSymbol {};
|
||||
template<L, I, typename> constexpr auto Sym{NoSuchRuntimeSymbol{}};
|
||||
template <L, I, typename> constexpr auto Sym{NoSuchRuntimeSymbol{}};
|
||||
|
||||
// Macros to declare fast/relaxed/precise libpgmath variants.
|
||||
#define DECLARE_PGMATH_FAST_REAL(func) \
|
||||
extern "C" float __fs_##func##_1(float); \
|
||||
extern "C" double __fd_##func##_1(double); \
|
||||
template<> constexpr auto Sym<L::F, I::func, float>{__fs_##func##_1}; \
|
||||
template<> constexpr auto Sym<L::F, I::func, double>{__fd_##func##_1};
|
||||
template <> constexpr auto Sym<L::F, I::func, float>{__fs_##func##_1}; \
|
||||
template <> constexpr auto Sym<L::F, I::func, double>{__fd_##func##_1};
|
||||
|
||||
#define DECLARE_PGMATH_FAST_COMPLEX(func) \
|
||||
extern "C" float _Complex __fc_##func##_1(float _Complex); \
|
||||
extern "C" double _Complex __fz_##func##_1(double _Complex); \
|
||||
template<> \
|
||||
template <> \
|
||||
constexpr auto Sym<L::F, I::func, std::complex<float>>{__fc_##func##_1}; \
|
||||
template<> \
|
||||
template <> \
|
||||
constexpr auto Sym<L::F, I::func, std::complex<double>>{__fz_##func##_1};
|
||||
|
||||
#define DECLARE_PGMATH_FAST_ALL_FP(func) \
|
||||
|
@ -231,15 +231,15 @@ template<L, I, typename> constexpr auto Sym{NoSuchRuntimeSymbol{}};
|
|||
#define DECLARE_PGMATH_PRECISE_REAL(func) \
|
||||
extern "C" float __ps_##func##_1(float); \
|
||||
extern "C" double __pd_##func##_1(double); \
|
||||
template<> constexpr auto Sym<L::P, I::func, float>{__ps_##func##_1}; \
|
||||
template<> constexpr auto Sym<L::P, I::func, double>{__pd_##func##_1};
|
||||
template <> constexpr auto Sym<L::P, I::func, float>{__ps_##func##_1}; \
|
||||
template <> constexpr auto Sym<L::P, I::func, double>{__pd_##func##_1};
|
||||
|
||||
#define DECLARE_PGMATH_PRECISE_COMPLEX(func) \
|
||||
extern "C" float _Complex __pc_##func##_1(float _Complex); \
|
||||
extern "C" double _Complex __pz_##func##_1(double _Complex); \
|
||||
template<> \
|
||||
template <> \
|
||||
constexpr auto Sym<L::P, I::func, std::complex<float>>{__pc_##func##_1}; \
|
||||
template<> \
|
||||
template <> \
|
||||
constexpr auto Sym<L::P, I::func, std::complex<double>>{__pz_##func##_1};
|
||||
|
||||
#define DECLARE_PGMATH_PRECISE_ALL_FP(func) \
|
||||
|
@ -249,15 +249,15 @@ template<L, I, typename> constexpr auto Sym{NoSuchRuntimeSymbol{}};
|
|||
#define DECLARE_PGMATH_RELAXED_REAL(func) \
|
||||
extern "C" float __rs_##func##_1(float); \
|
||||
extern "C" double __rd_##func##_1(double); \
|
||||
template<> constexpr auto Sym<L::R, I::func, float>{__rs_##func##_1}; \
|
||||
template<> constexpr auto Sym<L::R, I::func, double>{__rd_##func##_1};
|
||||
template <> constexpr auto Sym<L::R, I::func, float>{__rs_##func##_1}; \
|
||||
template <> constexpr auto Sym<L::R, I::func, double>{__rd_##func##_1};
|
||||
|
||||
#define DECLARE_PGMATH_RELAXED_COMPLEX(func) \
|
||||
extern "C" float _Complex __rc_##func##_1(float _Complex); \
|
||||
extern "C" double _Complex __rz_##func##_1(double _Complex); \
|
||||
template<> \
|
||||
template <> \
|
||||
constexpr auto Sym<L::R, I::func, std::complex<float>>{__rc_##func##_1}; \
|
||||
template<> \
|
||||
template <> \
|
||||
constexpr auto Sym<L::R, I::func, std::complex<double>>{__rz_##func##_1};
|
||||
|
||||
#define DECLARE_PGMATH_RELAXED_ALL_FP(func) \
|
||||
|
@ -282,16 +282,16 @@ template<L, I, typename> constexpr auto Sym{NoSuchRuntimeSymbol{}};
|
|||
#define DECLARE_PGMATH_FAST_REAL2(func) \
|
||||
extern "C" float __fs_##func##_1(float, float); \
|
||||
extern "C" double __fd_##func##_1(double, double); \
|
||||
template<> constexpr auto Sym<L::F, I::func, float>{__fs_##func##_1}; \
|
||||
template<> constexpr auto Sym<L::F, I::func, double>{__fd_##func##_1};
|
||||
template <> constexpr auto Sym<L::F, I::func, float>{__fs_##func##_1}; \
|
||||
template <> constexpr auto Sym<L::F, I::func, double>{__fd_##func##_1};
|
||||
|
||||
#define DECLARE_PGMATH_FAST_COMPLEX2(func) \
|
||||
extern "C" float _Complex __fc_##func##_1(float _Complex, float _Complex); \
|
||||
extern "C" double _Complex __fz_##func##_1( \
|
||||
double _Complex, double _Complex); \
|
||||
template<> \
|
||||
template <> \
|
||||
constexpr auto Sym<L::F, I::func, std::complex<float>>{__fc_##func##_1}; \
|
||||
template<> \
|
||||
template <> \
|
||||
constexpr auto Sym<L::F, I::func, std::complex<double>>{__fz_##func##_1};
|
||||
|
||||
#define DECLARE_PGMATH_FAST_ALL_FP2(func) \
|
||||
|
@ -301,16 +301,16 @@ template<L, I, typename> constexpr auto Sym{NoSuchRuntimeSymbol{}};
|
|||
#define DECLARE_PGMATH_PRECISE_REAL2(func) \
|
||||
extern "C" float __ps_##func##_1(float, float); \
|
||||
extern "C" double __pd_##func##_1(double, double); \
|
||||
template<> constexpr auto Sym<L::P, I::func, float>{__ps_##func##_1}; \
|
||||
template<> constexpr auto Sym<L::P, I::func, double>{__pd_##func##_1};
|
||||
template <> constexpr auto Sym<L::P, I::func, float>{__ps_##func##_1}; \
|
||||
template <> constexpr auto Sym<L::P, I::func, double>{__pd_##func##_1};
|
||||
|
||||
#define DECLARE_PGMATH_PRECISE_COMPLEX2(func) \
|
||||
extern "C" float _Complex __pc_##func##_1(float _Complex, float _Complex); \
|
||||
extern "C" double _Complex __pz_##func##_1( \
|
||||
double _Complex, double _Complex); \
|
||||
template<> \
|
||||
template <> \
|
||||
constexpr auto Sym<L::P, I::func, std::complex<float>>{__pc_##func##_1}; \
|
||||
template<> \
|
||||
template <> \
|
||||
constexpr auto Sym<L::P, I::func, std::complex<double>>{__pz_##func##_1};
|
||||
|
||||
#define DECLARE_PGMATH_PRECISE_ALL_FP2(func) \
|
||||
|
@ -320,16 +320,16 @@ template<L, I, typename> constexpr auto Sym{NoSuchRuntimeSymbol{}};
|
|||
#define DECLARE_PGMATH_RELAXED_REAL2(func) \
|
||||
extern "C" float __rs_##func##_1(float, float); \
|
||||
extern "C" double __rd_##func##_1(double, double); \
|
||||
template<> constexpr auto Sym<L::R, I::func, float>{__rs_##func##_1}; \
|
||||
template<> constexpr auto Sym<L::R, I::func, double>{__rd_##func##_1};
|
||||
template <> constexpr auto Sym<L::R, I::func, float>{__rs_##func##_1}; \
|
||||
template <> constexpr auto Sym<L::R, I::func, double>{__rd_##func##_1};
|
||||
|
||||
#define DECLARE_PGMATH_RELAXED_COMPLEX2(func) \
|
||||
extern "C" float _Complex __rc_##func##_1(float _Complex, float _Complex); \
|
||||
extern "C" double _Complex __rz_##func##_1( \
|
||||
double _Complex, double _Complex); \
|
||||
template<> \
|
||||
template <> \
|
||||
constexpr auto Sym<L::R, I::func, std::complex<float>>{__rc_##func##_1}; \
|
||||
template<> \
|
||||
template <> \
|
||||
constexpr auto Sym<L::R, I::func, std::complex<double>>{__rz_##func##_1};
|
||||
|
||||
#define DECLARE_PGMATH_RELAXED_ALL_FP2(func) \
|
||||
|
@ -354,12 +354,12 @@ template<L, I, typename> constexpr auto Sym{NoSuchRuntimeSymbol{}};
|
|||
#define DECLARE_PGMATH_MTH_VERSION_REAL(func) \
|
||||
extern "C" float __mth_i_##func(float); \
|
||||
extern "C" double __mth_i_d##func(double); \
|
||||
template<> constexpr auto Sym<L::F, I::func, float>{__mth_i_##func}; \
|
||||
template<> constexpr auto Sym<L::F, I::func, double>{__mth_i_d##func}; \
|
||||
template<> constexpr auto Sym<L::P, I::func, float>{__mth_i_##func}; \
|
||||
template<> constexpr auto Sym<L::P, I::func, double>{__mth_i_d##func}; \
|
||||
template<> constexpr auto Sym<L::R, I::func, float>{__mth_i_##func}; \
|
||||
template<> constexpr auto Sym<L::R, I::func, double>{__mth_i_d##func};
|
||||
template <> constexpr auto Sym<L::F, I::func, float>{__mth_i_##func}; \
|
||||
template <> constexpr auto Sym<L::F, I::func, double>{__mth_i_d##func}; \
|
||||
template <> constexpr auto Sym<L::P, I::func, float>{__mth_i_##func}; \
|
||||
template <> constexpr auto Sym<L::P, I::func, double>{__mth_i_d##func}; \
|
||||
template <> constexpr auto Sym<L::R, I::func, float>{__mth_i_##func}; \
|
||||
template <> constexpr auto Sym<L::R, I::func, double>{__mth_i_d##func};
|
||||
|
||||
// Actual libpgmath declarations
|
||||
DECLARE_PGMATH_ALL(acos)
|
||||
|
@ -376,20 +376,20 @@ DECLARE_PGMATH_MTH_VERSION_REAL(bessel_y1)
|
|||
// bessel_jn and bessel_yn takes an int as first arg
|
||||
extern "C" float __mth_i_bessel_jn(int, float);
|
||||
extern "C" double __mth_i_dbessel_jn(int, double);
|
||||
template<> constexpr auto Sym<L::F, I::bessel_jn, float>{__mth_i_bessel_jn};
|
||||
template<> constexpr auto Sym<L::F, I::bessel_jn, double>{__mth_i_dbessel_jn};
|
||||
template<> constexpr auto Sym<L::P, I::bessel_jn, float>{__mth_i_bessel_jn};
|
||||
template<> constexpr auto Sym<L::P, I::bessel_jn, double>{__mth_i_dbessel_jn};
|
||||
template<> constexpr auto Sym<L::R, I::bessel_jn, float>{__mth_i_bessel_jn};
|
||||
template<> constexpr auto Sym<L::R, I::bessel_jn, double>{__mth_i_dbessel_jn};
|
||||
template <> constexpr auto Sym<L::F, I::bessel_jn, float>{__mth_i_bessel_jn};
|
||||
template <> constexpr auto Sym<L::F, I::bessel_jn, double>{__mth_i_dbessel_jn};
|
||||
template <> constexpr auto Sym<L::P, I::bessel_jn, float>{__mth_i_bessel_jn};
|
||||
template <> constexpr auto Sym<L::P, I::bessel_jn, double>{__mth_i_dbessel_jn};
|
||||
template <> constexpr auto Sym<L::R, I::bessel_jn, float>{__mth_i_bessel_jn};
|
||||
template <> constexpr auto Sym<L::R, I::bessel_jn, double>{__mth_i_dbessel_jn};
|
||||
extern "C" float __mth_i_bessel_yn(int, float);
|
||||
extern "C" double __mth_i_dbessel_yn(int, double);
|
||||
template<> constexpr auto Sym<L::F, I::bessel_yn, float>{__mth_i_bessel_yn};
|
||||
template<> constexpr auto Sym<L::F, I::bessel_yn, double>{__mth_i_dbessel_yn};
|
||||
template<> constexpr auto Sym<L::P, I::bessel_yn, float>{__mth_i_bessel_yn};
|
||||
template<> constexpr auto Sym<L::P, I::bessel_yn, double>{__mth_i_dbessel_yn};
|
||||
template<> constexpr auto Sym<L::R, I::bessel_yn, float>{__mth_i_bessel_yn};
|
||||
template<> constexpr auto Sym<L::R, I::bessel_yn, double>{__mth_i_dbessel_yn};
|
||||
template <> constexpr auto Sym<L::F, I::bessel_yn, float>{__mth_i_bessel_yn};
|
||||
template <> constexpr auto Sym<L::F, I::bessel_yn, double>{__mth_i_dbessel_yn};
|
||||
template <> constexpr auto Sym<L::P, I::bessel_yn, float>{__mth_i_bessel_yn};
|
||||
template <> constexpr auto Sym<L::P, I::bessel_yn, double>{__mth_i_dbessel_yn};
|
||||
template <> constexpr auto Sym<L::R, I::bessel_yn, float>{__mth_i_bessel_yn};
|
||||
template <> constexpr auto Sym<L::R, I::bessel_yn, double>{__mth_i_dbessel_yn};
|
||||
DECLARE_PGMATH_ALL(cos)
|
||||
DECLARE_PGMATH_ALL(cosh)
|
||||
DECLARE_PGMATH_MTH_VERSION_REAL(erf)
|
||||
|
@ -399,24 +399,24 @@ DECLARE_PGMATH_ALL(exp)
|
|||
DECLARE_PGMATH_MTH_VERSION_REAL(gamma)
|
||||
extern "C" float __mth_i_hypot(float, float);
|
||||
extern "C" double __mth_i_dhypot(double, double);
|
||||
template<> constexpr auto Sym<L::F, I::hypot, float>{__mth_i_hypot};
|
||||
template<> constexpr auto Sym<L::F, I::hypot, double>{__mth_i_dhypot};
|
||||
template<> constexpr auto Sym<L::P, I::hypot, float>{__mth_i_hypot};
|
||||
template<> constexpr auto Sym<L::P, I::hypot, double>{__mth_i_dhypot};
|
||||
template<> constexpr auto Sym<L::R, I::hypot, float>{__mth_i_hypot};
|
||||
template<> constexpr auto Sym<L::R, I::hypot, double>{__mth_i_dhypot};
|
||||
template <> constexpr auto Sym<L::F, I::hypot, float>{__mth_i_hypot};
|
||||
template <> constexpr auto Sym<L::F, I::hypot, double>{__mth_i_dhypot};
|
||||
template <> constexpr auto Sym<L::P, I::hypot, float>{__mth_i_hypot};
|
||||
template <> constexpr auto Sym<L::P, I::hypot, double>{__mth_i_dhypot};
|
||||
template <> constexpr auto Sym<L::R, I::hypot, float>{__mth_i_hypot};
|
||||
template <> constexpr auto Sym<L::R, I::hypot, double>{__mth_i_dhypot};
|
||||
DECLARE_PGMATH_ALL(log)
|
||||
DECLARE_PGMATH_REAL(log10)
|
||||
DECLARE_PGMATH_MTH_VERSION_REAL(log_gamma)
|
||||
// no function for modulo in libpgmath
|
||||
extern "C" float __fs_mod_1(float, float);
|
||||
extern "C" double __fd_mod_1(double, double);
|
||||
template<> constexpr auto Sym<L::F, I::mod, float>{__fs_mod_1};
|
||||
template<> constexpr auto Sym<L::F, I::mod, double>{__fd_mod_1};
|
||||
template<> constexpr auto Sym<L::P, I::mod, float>{__fs_mod_1};
|
||||
template<> constexpr auto Sym<L::P, I::mod, double>{__fd_mod_1};
|
||||
template<> constexpr auto Sym<L::R, I::mod, float>{__fs_mod_1};
|
||||
template<> constexpr auto Sym<L::R, I::mod, double>{__fd_mod_1};
|
||||
template <> constexpr auto Sym<L::F, I::mod, float>{__fs_mod_1};
|
||||
template <> constexpr auto Sym<L::F, I::mod, double>{__fd_mod_1};
|
||||
template <> constexpr auto Sym<L::P, I::mod, float>{__fs_mod_1};
|
||||
template <> constexpr auto Sym<L::P, I::mod, double>{__fd_mod_1};
|
||||
template <> constexpr auto Sym<L::R, I::mod, float>{__fs_mod_1};
|
||||
template <> constexpr auto Sym<L::R, I::mod, double>{__fd_mod_1};
|
||||
DECLARE_PGMATH_ALL2(pow)
|
||||
DECLARE_PGMATH_ALL(sin)
|
||||
DECLARE_PGMATH_ALL(sinh)
|
||||
|
@ -426,7 +426,7 @@ DECLARE_PGMATH_ALL(tan)
|
|||
DECLARE_PGMATH_ALL(tanh)
|
||||
|
||||
// Fill the function map used for folding with libpgmath symbols
|
||||
template<L Lib, typename HostT>
|
||||
template <L Lib, typename HostT>
|
||||
static void AddLibpgmathRealHostProcedures(
|
||||
HostIntrinsicProceduresLibrary &hostIntrinsicLibrary) {
|
||||
static_assert(std::is_same_v<HostT, float> || std::is_same_v<HostT, double>);
|
||||
|
@ -475,19 +475,19 @@ static void AddLibpgmathRealHostProcedures(
|
|||
// by a pair of register but std::complex<float> is returned by structure
|
||||
// address. To fix the issue, wrapper around C _Complex functions are defined
|
||||
// below.
|
||||
template<FuncPointer<float _Complex, float _Complex> func>
|
||||
template <FuncPointer<float _Complex, float _Complex> func>
|
||||
static std::complex<float> ComplexCFuncWrapper(std::complex<float> &arg) {
|
||||
float _Complex res{func(*reinterpret_cast<float _Complex *>(&arg))};
|
||||
return *reinterpret_cast<std::complex<float> *>(&res);
|
||||
}
|
||||
|
||||
template<FuncPointer<double _Complex, double _Complex> func>
|
||||
template <FuncPointer<double _Complex, double _Complex> func>
|
||||
static std::complex<double> ComplexCFuncWrapper(std::complex<double> &arg) {
|
||||
double _Complex res{func(*reinterpret_cast<double _Complex *>(&arg))};
|
||||
return *reinterpret_cast<std::complex<double> *>(&res);
|
||||
}
|
||||
|
||||
template<FuncPointer<float _Complex, float _Complex, float _Complex> func>
|
||||
template <FuncPointer<float _Complex, float _Complex, float _Complex> func>
|
||||
static std::complex<float> ComplexCFuncWrapper(
|
||||
std::complex<float> &arg1, std::complex<float> &arg2) {
|
||||
float _Complex res{func(*reinterpret_cast<float _Complex *>(&arg1),
|
||||
|
@ -495,7 +495,7 @@ static std::complex<float> ComplexCFuncWrapper(
|
|||
return *reinterpret_cast<std::complex<float> *>(&res);
|
||||
}
|
||||
|
||||
template<FuncPointer<double _Complex, double _Complex, double _Complex> func>
|
||||
template <FuncPointer<double _Complex, double _Complex, double _Complex> func>
|
||||
static std::complex<double> ComplexCFuncWrapper(
|
||||
std::complex<double> &arg1, std::complex<double> &arg2) {
|
||||
double _Complex res{func(*reinterpret_cast<double _Complex *>(&arg1),
|
||||
|
@ -503,7 +503,7 @@ static std::complex<double> ComplexCFuncWrapper(
|
|||
return *reinterpret_cast<std::complex<double> *>(&res);
|
||||
}
|
||||
|
||||
template<L Lib, typename HostT>
|
||||
template <L Lib, typename HostT>
|
||||
static void AddLibpgmathComplexHostProcedures(
|
||||
HostIntrinsicProceduresLibrary &hostIntrinsicLibrary) {
|
||||
static_assert(std::is_same_v<HostT, float> || std::is_same_v<HostT, double>);
|
||||
|
@ -535,7 +535,7 @@ static void AddLibpgmathComplexHostProcedures(
|
|||
}
|
||||
}
|
||||
|
||||
template<L Lib>
|
||||
template <L Lib>
|
||||
static void InitHostIntrinsicLibraryWithLibpgmath(
|
||||
HostIntrinsicProceduresLibrary &lib) {
|
||||
if constexpr (host::FortranTypeExists<float>()) {
|
||||
|
@ -558,7 +558,7 @@ static void InitHostIntrinsicLibraryWithLibpgmath(
|
|||
AddLibmComplexHostProcedures<long double>(lib);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace pgmath
|
||||
#endif // LINK_WITH_LIBPGMATH
|
||||
|
||||
// Define which host runtime functions will be used for folding
|
||||
|
@ -581,4 +581,4 @@ HostIntrinsicProceduresLibrary::HostIntrinsicProceduresLibrary() {
|
|||
InitHostIntrinsicLibraryWithLibm(*this);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
|
|
|
@ -1138,7 +1138,9 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
|
|||
case KindCode::defaultLogicalKind:
|
||||
argOk = type->kind() == defaults.GetDefaultKind(TypeCategory::Logical);
|
||||
break;
|
||||
case KindCode::any: argOk = true; break;
|
||||
case KindCode::any:
|
||||
argOk = true;
|
||||
break;
|
||||
case KindCode::kindArg:
|
||||
CHECK(type->category() == TypeCategory::Integer);
|
||||
CHECK(!kindArg);
|
||||
|
@ -1175,8 +1177,11 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
|
|||
"for intrinsic '%s'",
|
||||
d.keyword, name);
|
||||
break;
|
||||
case KindCode::addressable: argOk = true; break;
|
||||
default: CRASH_NO_CASE;
|
||||
case KindCode::addressable:
|
||||
argOk = true;
|
||||
break;
|
||||
default:
|
||||
CRASH_NO_CASE;
|
||||
}
|
||||
if (!argOk) {
|
||||
messages.Say(
|
||||
|
@ -1210,8 +1215,12 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
|
|||
}
|
||||
argOk = rank == 0 || rank == elementalRank;
|
||||
break;
|
||||
case Rank::scalar: argOk = rank == 0; break;
|
||||
case Rank::vector: argOk = rank == 1; break;
|
||||
case Rank::scalar:
|
||||
argOk = rank == 0;
|
||||
break;
|
||||
case Rank::vector:
|
||||
argOk = rank == 1;
|
||||
break;
|
||||
case Rank::shape:
|
||||
CHECK(!shapeArgSize);
|
||||
if (rank == 1) {
|
||||
|
@ -1229,7 +1238,9 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
|
|||
return std::nullopt;
|
||||
}
|
||||
break;
|
||||
case Rank::matrix: argOk = rank == 2; break;
|
||||
case Rank::matrix:
|
||||
argOk = rank == 2;
|
||||
break;
|
||||
case Rank::array:
|
||||
argOk = rank > 0;
|
||||
if (!arrayArg) {
|
||||
|
@ -1244,7 +1255,9 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
|
|||
}
|
||||
argOk = rank == knownArg->Rank();
|
||||
break;
|
||||
case Rank::anyOrAssumedRank: argOk = true; break;
|
||||
case Rank::anyOrAssumedRank:
|
||||
argOk = true;
|
||||
break;
|
||||
case Rank::conformable:
|
||||
CHECK(arrayArg);
|
||||
argOk = rank == 0 || rank == arrayArg->Rank();
|
||||
|
@ -1383,7 +1396,8 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
|
|||
common::die(
|
||||
"INTERNAL: bad KindCode appears on intrinsic '%s' result", name);
|
||||
break;
|
||||
default: CRASH_NO_CASE;
|
||||
default:
|
||||
CRASH_NO_CASE;
|
||||
}
|
||||
} else {
|
||||
if (!call.isSubroutineCall) {
|
||||
|
@ -1396,10 +1410,18 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
|
|||
// Determine the rank of the function result.
|
||||
int resultRank{0};
|
||||
switch (rank) {
|
||||
case Rank::elemental: resultRank = elementalRank; break;
|
||||
case Rank::scalar: resultRank = 0; break;
|
||||
case Rank::vector: resultRank = 1; break;
|
||||
case Rank::matrix: resultRank = 2; break;
|
||||
case Rank::elemental:
|
||||
resultRank = elementalRank;
|
||||
break;
|
||||
case Rank::scalar:
|
||||
resultRank = 0;
|
||||
break;
|
||||
case Rank::vector:
|
||||
resultRank = 1;
|
||||
break;
|
||||
case Rank::matrix:
|
||||
resultRank = 2;
|
||||
break;
|
||||
case Rank::conformable:
|
||||
CHECK(arrayArg);
|
||||
resultRank = arrayArg->Rank();
|
||||
|
@ -1798,10 +1820,14 @@ static DynamicType GetReturnType(const SpecificIntrinsicInterface &interface,
|
|||
const common::IntrinsicTypeDefaultKinds &defaults) {
|
||||
TypeCategory category{TypeCategory::Integer};
|
||||
switch (interface.result.kindCode) {
|
||||
case KindCode::defaultIntegerKind: break;
|
||||
case KindCode::defaultIntegerKind:
|
||||
break;
|
||||
case KindCode::doublePrecision:
|
||||
case KindCode::defaultRealKind: category = TypeCategory::Real; break;
|
||||
default: CRASH_NO_CASE;
|
||||
case KindCode::defaultRealKind:
|
||||
category = TypeCategory::Real;
|
||||
break;
|
||||
default:
|
||||
CRASH_NO_CASE;
|
||||
}
|
||||
int kind{interface.result.kindCode == KindCode::doublePrecision
|
||||
? defaults.doublePrecisionKind()
|
||||
|
@ -2063,4 +2089,4 @@ llvm::raw_ostream &IntrinsicProcTable::Implementation::Dump(
|
|||
llvm::raw_ostream &IntrinsicProcTable::Dump(llvm::raw_ostream &o) const {
|
||||
return impl_->Dump(o);
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
|
|
|
@ -14,4 +14,4 @@ template class Logical<8>;
|
|||
template class Logical<16>;
|
||||
template class Logical<32>;
|
||||
template class Logical<64>;
|
||||
}
|
||||
} // namespace Fortran::evaluate::value
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
namespace Fortran::evaluate::value {
|
||||
|
||||
template<typename W, int P> Relation Real<W, P>::Compare(const Real &y) const {
|
||||
template <typename W, int P> Relation Real<W, P>::Compare(const Real &y) const {
|
||||
if (IsNotANumber() || y.IsNotANumber()) { // NaN vs x, x vs NaN
|
||||
return Relation::Unordered;
|
||||
} else if (IsInfinite()) {
|
||||
|
@ -53,7 +53,7 @@ template<typename W, int P> Relation Real<W, P>::Compare(const Real &y) const {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename W, int P>
|
||||
template <typename W, int P>
|
||||
ValueWithRealFlags<Real<W, P>> Real<W, P>::Add(
|
||||
const Real &y, Rounding rounding) const {
|
||||
ValueWithRealFlags<Real> result;
|
||||
|
@ -133,7 +133,7 @@ ValueWithRealFlags<Real<W, P>> Real<W, P>::Add(
|
|||
return result;
|
||||
}
|
||||
|
||||
template<typename W, int P>
|
||||
template <typename W, int P>
|
||||
ValueWithRealFlags<Real<W, P>> Real<W, P>::Multiply(
|
||||
const Real &y, Rounding rounding) const {
|
||||
ValueWithRealFlags<Real> result;
|
||||
|
@ -193,7 +193,7 @@ ValueWithRealFlags<Real<W, P>> Real<W, P>::Multiply(
|
|||
return result;
|
||||
}
|
||||
|
||||
template<typename W, int P>
|
||||
template <typename W, int P>
|
||||
ValueWithRealFlags<Real<W, P>> Real<W, P>::Divide(
|
||||
const Real &y, Rounding rounding) const {
|
||||
ValueWithRealFlags<Real> result;
|
||||
|
@ -261,7 +261,7 @@ ValueWithRealFlags<Real<W, P>> Real<W, P>::Divide(
|
|||
return result;
|
||||
}
|
||||
|
||||
template<typename W, int P>
|
||||
template <typename W, int P>
|
||||
ValueWithRealFlags<Real<W, P>> Real<W, P>::ToWholeNumber(
|
||||
common::RoundingMode mode) const {
|
||||
ValueWithRealFlags<Real> result{*this};
|
||||
|
@ -287,7 +287,7 @@ ValueWithRealFlags<Real<W, P>> Real<W, P>::ToWholeNumber(
|
|||
return result;
|
||||
}
|
||||
|
||||
template<typename W, int P>
|
||||
template <typename W, int P>
|
||||
RealFlags Real<W, P>::Normalize(bool negative, int exponent,
|
||||
const Fraction &fraction, Rounding rounding, RoundingBits *roundingBits) {
|
||||
int lshift{fraction.LEADZ()};
|
||||
|
@ -347,7 +347,7 @@ RealFlags Real<W, P>::Normalize(bool negative, int exponent,
|
|||
return {};
|
||||
}
|
||||
|
||||
template<typename W, int P>
|
||||
template <typename W, int P>
|
||||
RealFlags Real<W, P>::Round(
|
||||
Rounding rounding, const RoundingBits &bits, bool multiply) {
|
||||
int origExponent{Exponent()};
|
||||
|
@ -388,7 +388,7 @@ RealFlags Real<W, P>::Round(
|
|||
return flags;
|
||||
}
|
||||
|
||||
template<typename W, int P>
|
||||
template <typename W, int P>
|
||||
void Real<W, P>::NormalizeAndRound(ValueWithRealFlags<Real> &result,
|
||||
bool isNegative, int exponent, const Fraction &fraction, Rounding rounding,
|
||||
RoundingBits roundingBits, bool multiply) {
|
||||
|
@ -400,11 +400,16 @@ void Real<W, P>::NormalizeAndRound(ValueWithRealFlags<Real> &result,
|
|||
inline enum decimal::FortranRounding MapRoundingMode(
|
||||
common::RoundingMode rounding) {
|
||||
switch (rounding) {
|
||||
case common::RoundingMode::TiesToEven: break;
|
||||
case common::RoundingMode::ToZero: return decimal::RoundToZero;
|
||||
case common::RoundingMode::Down: return decimal::RoundDown;
|
||||
case common::RoundingMode::Up: return decimal::RoundUp;
|
||||
case common::RoundingMode::TiesAwayFromZero: return decimal::RoundCompatible;
|
||||
case common::RoundingMode::TiesToEven:
|
||||
break;
|
||||
case common::RoundingMode::ToZero:
|
||||
return decimal::RoundToZero;
|
||||
case common::RoundingMode::Down:
|
||||
return decimal::RoundDown;
|
||||
case common::RoundingMode::Up:
|
||||
return decimal::RoundUp;
|
||||
case common::RoundingMode::TiesAwayFromZero:
|
||||
return decimal::RoundCompatible;
|
||||
}
|
||||
return decimal::RoundNearest; // dodge gcc warning about lack of result
|
||||
}
|
||||
|
@ -423,7 +428,7 @@ inline RealFlags MapFlags(decimal::ConversionResultFlags flags) {
|
|||
return result;
|
||||
}
|
||||
|
||||
template<typename W, int P>
|
||||
template <typename W, int P>
|
||||
ValueWithRealFlags<Real<W, P>> Real<W, P>::Read(
|
||||
const char *&p, Rounding rounding) {
|
||||
auto converted{
|
||||
|
@ -432,7 +437,7 @@ ValueWithRealFlags<Real<W, P>> Real<W, P>::Read(
|
|||
return {*value, MapFlags(converted.flags)};
|
||||
}
|
||||
|
||||
template<typename W, int P> std::string Real<W, P>::DumpHexadecimal() const {
|
||||
template <typename W, int P> std::string Real<W, P>::DumpHexadecimal() const {
|
||||
if (IsNotANumber()) {
|
||||
return "NaN 0x"s + word_.Hexadecimal();
|
||||
} else if (IsNegative()) {
|
||||
|
@ -478,7 +483,7 @@ template<typename W, int P> std::string Real<W, P>::DumpHexadecimal() const {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename W, int P>
|
||||
template <typename W, int P>
|
||||
llvm::raw_ostream &Real<W, P>::AsFortran(
|
||||
llvm::raw_ostream &o, int kind, bool minimal) const {
|
||||
if (IsNotANumber()) {
|
||||
|
@ -522,4 +527,4 @@ template class Real<Integer<32>, 24>;
|
|||
template class Real<Integer<64>, 53>;
|
||||
template class Real<Integer<80>, 64>;
|
||||
template class Real<Integer<128>, 113>;
|
||||
}
|
||||
} // namespace Fortran::evaluate::value
|
||||
|
|
|
@ -653,4 +653,4 @@ bool CheckConformance(parser::ContextualMessages &messages, const Shape &left,
|
|||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
|
|
|
@ -93,4 +93,4 @@ std::optional<std::u32string> StaticDataObject::AsU32String() const {
|
|||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
|
|
|
@ -705,8 +705,7 @@ bool IsProcedure(const Expr<SomeType> &expr) {
|
|||
}
|
||||
|
||||
bool IsProcedurePointer(const Expr<SomeType> &expr) {
|
||||
return std::visit(
|
||||
common::visitors{
|
||||
return std::visit(common::visitors{
|
||||
[](const NullPointer &) { return true; },
|
||||
[](const ProcedureDesignator &) { return true; },
|
||||
[](const ProcedureRef &) { return true; },
|
||||
|
|
|
@ -80,11 +80,11 @@ bool IsDescriptor(const Symbol &symbol) {
|
|||
},
|
||||
symbol.details());
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::semantics
|
||||
|
||||
namespace Fortran::evaluate {
|
||||
|
||||
template<typename A> inline bool PointeeComparison(const A *x, const A *y) {
|
||||
template <typename A> inline bool PointeeComparison(const A *x, const A *y) {
|
||||
return x == y || (x && y && *x == *y);
|
||||
}
|
||||
|
||||
|
@ -256,7 +256,7 @@ static bool AreSameComponent(const semantics::Symbol &x,
|
|||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
else {
|
||||
// TODO: non-object components
|
||||
return true;
|
||||
|
@ -387,37 +387,45 @@ DynamicType DynamicType::ResultTypeForMultiply(const DynamicType &that) const {
|
|||
case TypeCategory::Integer:
|
||||
return DynamicType{TypeCategory::Integer, std::max(kind_, that.kind_)};
|
||||
case TypeCategory::Real:
|
||||
case TypeCategory::Complex: return that;
|
||||
default: CRASH_NO_CASE;
|
||||
case TypeCategory::Complex:
|
||||
return that;
|
||||
default:
|
||||
CRASH_NO_CASE;
|
||||
}
|
||||
break;
|
||||
case TypeCategory::Real:
|
||||
switch (that.category_) {
|
||||
case TypeCategory::Integer: return *this;
|
||||
case TypeCategory::Integer:
|
||||
return *this;
|
||||
case TypeCategory::Real:
|
||||
return DynamicType{TypeCategory::Real, std::max(kind_, that.kind_)};
|
||||
case TypeCategory::Complex:
|
||||
return DynamicType{TypeCategory::Complex, std::max(kind_, that.kind_)};
|
||||
default: CRASH_NO_CASE;
|
||||
default:
|
||||
CRASH_NO_CASE;
|
||||
}
|
||||
break;
|
||||
case TypeCategory::Complex:
|
||||
switch (that.category_) {
|
||||
case TypeCategory::Integer: return *this;
|
||||
case TypeCategory::Integer:
|
||||
return *this;
|
||||
case TypeCategory::Real:
|
||||
case TypeCategory::Complex:
|
||||
return DynamicType{TypeCategory::Complex, std::max(kind_, that.kind_)};
|
||||
default: CRASH_NO_CASE;
|
||||
default:
|
||||
CRASH_NO_CASE;
|
||||
}
|
||||
break;
|
||||
case TypeCategory::Logical:
|
||||
switch (that.category_) {
|
||||
case TypeCategory::Logical:
|
||||
return DynamicType{TypeCategory::Logical, std::max(kind_, that.kind_)};
|
||||
default: CRASH_NO_CASE;
|
||||
default:
|
||||
CRASH_NO_CASE;
|
||||
}
|
||||
break;
|
||||
default: CRASH_NO_CASE;
|
||||
default:
|
||||
CRASH_NO_CASE;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -491,7 +499,7 @@ public:
|
|||
explicit SelectedIntKindVisitor(std::int64_t p) : precision_{p} {}
|
||||
using Result = std::optional<int>;
|
||||
using Types = IntegerTypes;
|
||||
template<typename T> Result Test() const {
|
||||
template <typename T> Result Test() const {
|
||||
if (Scalar<T>::RANGE >= precision_) {
|
||||
return T::kind;
|
||||
} else {
|
||||
|
@ -517,7 +525,7 @@ public:
|
|||
: precision_{p}, range_{r} {}
|
||||
using Result = std::optional<int>;
|
||||
using Types = RealTypes;
|
||||
template<typename T> Result Test() const {
|
||||
template <typename T> Result Test() const {
|
||||
if (Scalar<T>::PRECISION >= precision_ && Scalar<T>::RANGE >= range_) {
|
||||
return {T::kind};
|
||||
} else {
|
||||
|
@ -557,4 +565,4 @@ int SelectedRealKind(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace Fortran::evaluate
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue