aboutsummaryrefslogtreecommitdiff
path: root/flang/include/flang/Common/Fortran.h
blob: 5b2ed43a8f99c0405ea7b9c0b4375959a6069577 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//===-- include/flang/Common/Fortran.h --------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef FORTRAN_COMMON_FORTRAN_H_
#define FORTRAN_COMMON_FORTRAN_H_

// Fortran language concepts that are used in many phases are defined
// once here to avoid redundancy and needless translation.

#include "enum-set.h"
#include "idioms.h"
#include <cinttypes>
#include <optional>
#include <string>

namespace Fortran::common {
class LanguageFeatureControl;

// Fortran has five kinds of intrinsic data types, plus the derived types.
ENUM_CLASS(TypeCategory, Integer, Real, Complex, Character, Logical, Derived)
ENUM_CLASS(VectorElementCategory, Integer, Unsigned, Real)

constexpr bool IsNumericTypeCategory(TypeCategory category) {
  return category == TypeCategory::Integer || category == TypeCategory::Real ||
      category == TypeCategory::Complex;
}

// Kinds of IMPORT statements. Default means IMPORT or IMPORT :: names.
ENUM_CLASS(ImportKind, Default, Only, None, All)

// The attribute on a type parameter can be KIND or LEN.
ENUM_CLASS(TypeParamAttr, Kind, Len)

ENUM_CLASS(NumericOperator, Power, Multiply, Divide, Add, Subtract)
const char *AsFortran(NumericOperator);

ENUM_CLASS(LogicalOperator, And, Or, Eqv, Neqv, Not)
const char *AsFortran(LogicalOperator);

ENUM_CLASS(RelationalOperator, LT, LE, EQ, NE, GE, GT)
const char *AsFortran(RelationalOperator);

ENUM_CLASS(Intent, Default, In, Out, InOut)

ENUM_CLASS(IoStmtKind, None, Backspace, Close, Endfile, Flush, Inquire, Open,
    Print, Read, Rewind, Wait, Write)

// Union of specifiers for all I/O statements.
ENUM_CLASS(IoSpecKind, Access, Action, Advance, Asynchronous, Blank, Decimal,
    Delim, Direct, Encoding, End, Eor, Err, Exist, File, Fmt, Form, Formatted,
    Id, Iomsg, Iostat, Name, Named, Newunit, Nextrec, Nml, Number, Opened, Pad,
    Pending, Pos, Position, Read, Readwrite, Rec, Recl, Round, Sequential, Sign,
    Size, Status, Stream, Unformatted, Unit, Write,
    Carriagecontrol, // nonstandard
    Convert, // nonstandard
    Dispose, // nonstandard
)

// Defined I/O variants
ENUM_CLASS(
    DefinedIo, ReadFormatted, ReadUnformatted, WriteFormatted, WriteUnformatted)
const char *AsFortran(DefinedIo);

// Floating-point rounding modes; these are packed into a byte to save
// room in the runtime's format processing context structure.  These
// enumerators are defined with the corresponding values returned from
// llvm.get.rounding.
enum class RoundingMode : std::uint8_t {
  ToZero, // ROUND=ZERO, RZ - truncation
  TiesToEven, // ROUND=NEAREST, RN - default IEEE rounding
  Up, // ROUND=UP, RU
  Down, // ROUND=DOWN, RD
  TiesAwayFromZero, // ROUND=COMPATIBLE, RC - ties round away from zero
};

// Fortran label. Must be in [1..99999].
using Label = std::uint64_t;

// Fortran arrays may have up to 15 dimensions (See Fortran 2018 section 5.4.6).
static constexpr int maxRank{15};

// CUDA subprogram attribute combinations
ENUM_CLASS(CUDASubprogramAttrs, Host, Device, HostDevice, Global, Grid_Global)

// CUDA data attributes; mutually exclusive
ENUM_CLASS(
    CUDADataAttr, Constant, Device, Managed, Pinned, Shared, Texture, Unified)

// OpenACC device types
ENUM_CLASS(
    OpenACCDeviceType, Star, Default, Nvidia, Radeon, Host, Multicore, None)

// OpenMP atomic_default_mem_order clause allowed values
ENUM_CLASS(OmpAtomicDefaultMemOrderType, SeqCst, AcqRel, Relaxed)

// Fortran names may have up to 63 characters (See Fortran 2018 C601).
static constexpr int maxNameLen{63};

// !DIR$ IGNORE_TKR [[(letters) name] ... letters
// "A" expands to all of TKRDM
ENUM_CLASS(IgnoreTKR,
    Type, // T - don't check type category
    Kind, // K - don't check kind
    Rank, // R - don't check ranks
    Device, // D - don't check host/device residence
    Managed, // M - don't check managed storage
    Contiguous) // C - don't check for storage sequence association with a
                // potentially non-contiguous object
using IgnoreTKRSet = EnumSet<IgnoreTKR, 8>;
// IGNORE_TKR(A) = IGNORE_TKR(TKRDM)
static constexpr IgnoreTKRSet ignoreTKRAll{IgnoreTKR::Type, IgnoreTKR::Kind,
    IgnoreTKR::Rank, IgnoreTKR::Device, IgnoreTKR::Managed};
std::string AsFortran(IgnoreTKRSet);

bool AreCompatibleCUDADataAttrs(std::optional<CUDADataAttr>,
    std::optional<CUDADataAttr>, IgnoreTKRSet, bool allowUnifiedMatchingRule,
    const LanguageFeatureControl *features = nullptr);

static constexpr char blankCommonObjectName[] = "__BLNK__";

// Get the assembly name for a non BIND(C) external symbol other than the blank
// common block.
inline std::string GetExternalAssemblyName(
    std::string symbolName, bool underscoring) {
  return underscoring ? std::move(symbolName) + "_" : std::move(symbolName);
}

} // namespace Fortran::common
#endif // FORTRAN_COMMON_FORTRAN_H_