SEMANTICS_FAILED("construct name not on stack");
return {};
}
+
template<typename T> parser::Label GetErr(const T &stmt) {
if constexpr (std::is_same_v<T, parser::ReadStmt> ||
std::is_same_v<T, parser::WriteStmt>) {
}
return 0;
}
+
template<typename T> parser::Label GetEor(const T &stmt) {
if constexpr (std::is_same_v<T, parser::ReadStmt> ||
std::is_same_v<T, parser::WriteStmt>) {
}
return 0;
}
+
template<typename T> parser::Label GetEnd(const T &stmt) {
if constexpr (std::is_same_v<T, parser::ReadStmt> ||
std::is_same_v<T, parser::WriteStmt>) {
}
return 0;
}
+
template<typename T>
void errLabelSpec(const T &s, std::list<LinearOp> &ops,
const parser::Statement<parser::ActionStmt> &ec, AnalysisData &ad) {
ops.emplace_back(LinearAction{ec});
}
}
+
template<typename T>
void threeLabelSpec(const T &s, std::list<LinearOp> &ops,
const parser::Statement<parser::ActionStmt> &ec, AnalysisData &ad) {
ops.emplace_back(LinearAction{ec});
}
}
+
template<typename T>
std::vector<LinearLabelRef> toLabelRef(AnalysisData &ad, const T &labels) {
std::vector<LinearLabelRef> result;
.statement.t)
.thing.typedExpr.get()};
}
+
template<typename STMTTYPE, typename CT>
const std::optional<parser::Name> &GetSwitchAssociateName(
const CT *selectConstruct) {
return std::get<1>(
std::get<parser::Statement<STMTTYPE>>(selectConstruct->t).statement.t);
}
+
template<typename CONSTRUCT, typename GSF>
void DumpSwitchWithSelector(
const CONSTRUCT *construct, char const *const name, GSF getSelector) {
};
template<typename T>
-static bool IsDefault(const typename T::ValueType &valueType) {
+bool IsDefault(const typename T::ValueType &valueType) {
return std::holds_alternative<typename T::Default>(valueType);
}
+
template<typename T>
void cleanupSwitchPairs(LinearLabelRef &defLab,
std::vector<typename T::ValueType> &values,
}
return result;
}
+
static std::vector<SwitchRankStmt::ValueType> populateSwitchValues(
const std::list<parser::SelectRankConstruct::RankCase> &list) {
std::vector<SwitchRankStmt::ValueType> result;
}
return result;
}
+
static std::vector<SwitchTypeStmt::ValueType> populateSwitchValues(
const std::list<parser::SelectTypeConstruct::TypeCase> &list) {
std::vector<SwitchTypeStmt::ValueType> result;
}
return nullptr;
}
+
const parser::IoUnit *FindReadWriteIoUnit(
const std::optional<parser::IoUnit> &ioUnit,
const std::list<parser::IoControlSpec> &specifiers) {
~FortranIRLowering() { CHECK(!builder_); }
template<typename A> constexpr bool Pre(const A &) { return true; }
+
template<typename A> constexpr void Post(const A &) {}
+
void Post(const parser::MainProgram &mainp) {
std::string mainName{"_MAIN"s};
if (auto &ps{
}
Program *program() { return fir_; }
+
template<typename T>
void ProcessRoutine(const T &here, const std::string &name) {
CHECK(!fir_->containsProcedure(name));
falseBlock, _1));
}
}
+
template<typename SWITCHTYPE, typename F>
void AddOrQueueSwitch(const Evaluation &condition,
LinearLabelRef defaultLabel,
#include <string>
namespace Fortran::parser {
-class Program;
+struct Program;
}
namespace Fortran::semantics {
semantics::SemanticsContext &semanticsContext, bool debugLinearIR = false);
}
-#endif
+#endif // FORTRAN_FIR_AFFORESTATION_H_
return Insert(DeallocateStmt::Create(object));
}
template<typename A> Statement &CreateExpr(const A *a) {
- return Insert(ExprStmt::Create(a));
+ return Insert(ApplyExprStmt::Create(a));
}
Statement &CreateIOCall(
InputOutputCallType call, IOCallArguments &&arguments) {
namespace Fortran::FIR {
class Statement;
class BasicBlock;
-struct Program;
-struct GraphWriter;
+class Program;
+class GraphWriter;
struct Attribute {
enum { IntentIn, IntentOut, IntentInOut } attribute;
namespace Fortran::FIR {
-struct GraphWriter {
+class GraphWriter {
+public:
static void setOutput(llvm::raw_ostream *output) { defaultOutput_ = output; }
static void setOutput(const std::string &filename) {
std::error_code ec;
namespace Fortran::FIR {
+inline constexpr bool has_size(std::size_t size) { return size > 0; }
+
template<typename T, typename E = void> struct SumTypeMixin {};
template<typename T> // T must be std::variant<...>
-struct SumTypeMixin<T, std::enable_if_t<std::variant_size_v<T>>> {
+struct SumTypeMixin<T, std::enable_if_t<has_size(std::variant_size_v<T>)>> {
template<typename A> SumTypeMixin(A &&x) : u{std::move(x)} {}
using SumTypeTrait = std::true_type;
SumTypeMixin(SumTypeMixin &&) = default;
template<typename T, typename E = void> struct SumTypeCopyMixin {};
template<typename T> // T must be std::variant<...>
-struct SumTypeCopyMixin<T, std::enable_if_t<std::variant_size_v<T>>> {
+struct SumTypeCopyMixin<T, std::enable_if_t<has_size(std::variant_size_v<T>)>> {
+ template<typename A> SumTypeCopyMixin(A &&x) : u{std::move(x)} {}
+ template<typename A> SumTypeCopyMixin(const A &x) : u{x} {}
using CopyableSumTypeTrait = std::true_type;
SumTypeCopyMixin(SumTypeCopyMixin &&) = default;
SumTypeCopyMixin &operator=(SumTypeCopyMixin &&) = default;
SumTypeCopyMixin() = delete;
T u;
};
-#define SUM_TYPE_COPY_MIXIN(Derived) \
- Derived(const Derived &derived) : SumTypeCopyMixin(derived) {} \
- Derived &operator=(const Derived &derived) { \
- SumTypeCopyMixin::operator=(derived); \
+#define SUM_TYPE_COPY_MIXIN(DT) \
+ DT(const DT &derived) : SumTypeCopyMixin(derived.u) {} \
+ DT &operator=(const DT &derived) { \
+ SumTypeCopyMixin::operator=(derived.u); \
return *this; \
}
template<typename T, typename E = void> struct ProductTypeMixin {};
template<typename T> // T must be std::tuple<...>
-struct ProductTypeMixin<T, std::enable_if_t<std::tuple_size_v<T>>> {
+struct ProductTypeMixin<T, std::enable_if_t<has_size(std::tuple_size_v<T>)>> {
template<typename A> ProductTypeMixin(A &&x) : t{std::move(x)} {}
using ProductTypeTrait = std::true_type;
ProductTypeMixin(ProductTypeMixin &&) = default;
class Program;
class Region;
-struct GraphWriter;
+class GraphWriter;
class Procedure final : public llvm::ilist_node<Procedure>,
public ChildMixin<Procedure, Program> {
namespace Fortran::FIR {
class Procedure;
-struct GraphWriter;
+class GraphWriter;
class Program final {
public:
#define LAST_TERM_STMT(num)
#endif
-#ifndef FIRST_BINARY_STMT
-#define FIRST_BINARY_STMT(num)
+#ifndef FIRST_COMPUTE_STMT
+#define FIRST_COMPUTE_STMT(num)
#endif
-#ifndef HANDLE_BINARY_STMT
+#ifndef HANDLE_COMPUTE_STMT
#ifndef HANDLE_STMT
-#define HANDLE_BINARY_STMT(num, opcode, instclass)
+#define HANDLE_COMPUTE_STMT(num, opcode, instclass)
#else
-#define HANDLE_BINARY_STMT(num, opcode, Class) HANDLE_STMT(num, opcode, Class)
+#define HANDLE_COMPUTE_STMT(num, opcode, Class) HANDLE_STMT(num, opcode, Class)
#endif
#endif
-#ifndef LAST_BINARY_STMT
-#define LAST_BINARY_STMT(num)
+#ifndef LAST_COMPUTE_STMT
+#define LAST_COMPUTE_STMT(num)
#endif
#ifndef FIRST_MEMORY_STMT
// Standard actions - These instructions capture computations as
// evaluate::expressions
-FIRST_BINARY_STMT(9)
-HANDLE_BINARY_STMT(9, Assign, AssignmentStmt)
-HANDLE_BINARY_STMT(10, PtrAssign, PointerAssignStmt)
-HANDLE_BINARY_STMT(11, LblAssign, LabelAssignStmt)
-HANDLE_BINARY_STMT(12, Expr, ExprStmt)
-LAST_BINARY_STMT(12)
+FIRST_COMPUTE_STMT(9)
+HANDLE_COMPUTE_STMT(9, Assign, AssignmentStmt)
+HANDLE_COMPUTE_STMT(10, PtrAssign, PointerAssignStmt)
+HANDLE_COMPUTE_STMT(11, LblAssign, LabelAssignStmt)
+HANDLE_COMPUTE_STMT(12, ApplyExpr, ApplyExprStmt)
+LAST_COMPUTE_STMT(12)
// Memory operators - These instructions capture ALLOCATE and DEALLOCATE
// Fortran statements
#undef HANDLE_TERM_STMT
#undef LAST_TERM_STMT
-#undef FIRST_BINARY_STMT
-#undef HANDLE_BINARY_STMT
-#undef LAST_BINARY_STMT
+#undef FIRST_COMPUTE_STMT
+#undef HANDLE_COMPUTE_STMT
+#undef LAST_COMPUTE_STMT
#undef FIRST_MEMORY_STMT
#undef HANDLE_MEMORY_STMT
},
[](const LabelAssignStmt &) { return "lblassn"s; },
[](const DisassociateStmt &) { return "NULLIFY"s; },
- [](const ExprStmt &expressionStatement) {
+ [](const ApplyExprStmt &applyExpression) {
return std::visit(
common::visitors{
[](const parser::AssociateStmt *) {
return FIR::dump(genericExpressionWrapper);
},
},
- expressionStatement.u);
+ applyExpression.u);
},
[](const ScopeEnterStmt &) { return "scopeenter"s; },
[](const ScopeExitStmt &) { return "scopeexit"s; },
#define HANDLE_STMT(num, opcode, name) struct name;
#include "statement.def"
-struct Statement;
+class Statement;
CLASS_TRAIT(StatementTrait)
CLASS_TRAIT(TerminatorTrait)
CLASS_TRAIT(ActionTrait)
-struct Evaluation
- : public SumTypeCopyMixin<std::variant<Expression *, Variable *,
- PathVariable *, const semantics::Symbol *>> {
+class Evaluation : public SumTypeCopyMixin<std::variant<Expression *,
+ Variable *, PathVariable *, const semantics::Symbol *>> {
+public:
SUM_TYPE_COPY_MIXIN(Evaluation)
- Evaluation(PathVariable *pv) : SumTypeCopyMixin{pv} {
+ Evaluation(PathVariable *pv) : SumTypeCopyMixin(pv) {
if (const auto *designator{
std::get_if<common::Indirection<parser::Designator>>(&pv->u)}) {
if (const auto *obj{std::get_if<parser::ObjectName>(&(*designator)->u)}) {
};
/// expressions that must be evaluated in various statements
-struct ExprStmt
+struct ApplyExprStmt
: public ActionStmt_impl,
public SumTypeCopyMixin<std::variant<const parser::AssociateStmt *,
const parser::ChangeTeamStmt *, const parser::NonLabelDoStmt *,
const parser::ForallConstructStmt *, const Expression *>> {
- template<typename T> static ExprStmt Create(const T *e) {
- return ExprStmt{e};
+ template<typename T> static ApplyExprStmt Create(const T *e) {
+ return ApplyExprStmt{e};
}
private:
- template<typename T> explicit ExprStmt(const T *e) : SumTypeCopyMixin{e} {}
+ template<typename T>
+ explicit ApplyExprStmt(const T *e) : SumTypeCopyMixin{e} {}
// Evaluation evaluation_;
};
namespace Fortran::FIR {
/// Sum type over all statement classes
-struct Statement : public SumTypeMixin<std::variant<
+class Statement : public SumTypeMixin<std::variant<
#define HANDLE_STMT(num, opcode, name) name,
#define HANDLE_LAST_STMT(num, opcode, name) name
#include "statement.def"
- >>,
- public ChildMixin<Statement, BasicBlock>,
- public llvm::ilist_node<Statement> {
+ >>,
+ public ChildMixin<Statement, BasicBlock>,
+ public llvm::ilist_node<Statement> {
+public:
template<typename A>
Statement(BasicBlock *p, A &&t) : SumTypeMixin{t}, ChildMixin{p} {
parent->insertBefore(this);