Index: flang/include/flang/Common/indirection.h =================================================================== --- flang/include/flang/Common/indirection.h +++ flang/include/flang/Common/indirection.h @@ -28,7 +28,8 @@ namespace Fortran::common { // The default case does not support (deep) copy construction or assignment. -template class Indirection { +template +class Indirection : public std::in_place_t { public: using element_type = A; Indirection() = delete; @@ -69,7 +70,7 @@ }; // Variant with copy construction and assignment -template class Indirection { +template class Indirection : public std::in_place_t { public: using element_type = A; @@ -122,20 +123,28 @@ template using CopyableIndirection = Indirection; -// A variation of std::unique_ptr<> with a reified deletion routine. +// A variation of std::unique_ptr<> with reified deletion and +// copying routines. // Used to avoid dependence cycles between shared libraries. template class ForwardOwningPointer { public: ForwardOwningPointer() {} - ForwardOwningPointer(A *p, void (*del)(A *)) : p_{p}, deleter_{del} {} + ForwardOwningPointer(A *p, void (*del)(A *), A *(*copy)(const A *)) + : p_{p}, deleter_{del}, copier_{copy} {} ForwardOwningPointer(ForwardOwningPointer &&that) - : p_{that.p_}, deleter_{that.deleter_} { + : p_{that.p_}, deleter_{that.deleter_}, copier_{that.copier_} { that.p_ = nullptr; } ForwardOwningPointer &operator=(ForwardOwningPointer &&that) { - p_ = that.p_; + Reset(that.p_, that.deleter_, that.copier_); that.p_ = nullptr; - deleter_ = that.deleter_; + return *this; + } + ForwardOwningPointer(const ForwardOwningPointer &that) + : p_{that.copier_(that.p_)}, deleter_{that.deleter_}, + copier_{that.copier_} {} + ForwardOwningPointer &operator=(const ForwardOwningPointer &that) { + Reset(that.copier_(that.p_), that.deleter_, that.copier_); return *this; } ~ForwardOwningPointer() { @@ -161,14 +170,16 @@ } p_ = p; } - void Reset(A *p, void (*del)(A *)) { + void Reset(A *p, void (*del)(A *), A *(*copy)(A *)) { Reset(p); deleter_ = del; + copier_ = copy; } private: A *p_{nullptr}; void (*deleter_)(A *){nullptr}; + A *(*copier_)(A *){nullptr}; }; } // namespace Fortran::common #endif // FORTRAN_COMMON_INDIRECTION_H_ Index: flang/include/flang/Evaluate/call.h =================================================================== --- flang/include/flang/Evaluate/call.h +++ flang/include/flang/Evaluate/call.h @@ -220,6 +220,7 @@ hasAlternateReturns_{hasAlternateReturns} {} ~ProcedureRef(); static void Deleter(ProcedureRef *); + static ProcedureRef *Copier(ProcedureRef *); ProcedureDesignator &proc() { return proc_; } const ProcedureDesignator &proc() const { return proc_; } Index: flang/include/flang/Evaluate/expression.h =================================================================== --- flang/include/flang/Evaluate/expression.h +++ flang/include/flang/Evaluate/expression.h @@ -859,6 +859,7 @@ : v{std::move(x)} {} ~GenericExprWrapper(); static void Deleter(GenericExprWrapper *); + static GenericExprWrapper *Copier(GenericExprWrapper *); std::optional> v; // vacant if error }; @@ -870,6 +871,7 @@ : v{std::move(x)} {} ~GenericAssignmentWrapper(); static void Deleter(GenericAssignmentWrapper *); + static GenericAssignmentWrapper *Copier(GenericAssignmentWrapper *); std::optional v; // vacant if error }; Index: flang/include/flang/Lower/Support/Utils.h =================================================================== --- flang/include/flang/Lower/Support/Utils.h +++ flang/include/flang/Lower/Support/Utils.h @@ -41,7 +41,11 @@ return a; } template -const A &removeIndirection(const Fortran::common::Indirection &a) { +const A &removeIndirection(const Fortran::common::Indirection &a) { + return a.value(); +} +template +const A &removeIndirection(const Fortran::common::Indirection &a) { return a.value(); } Index: flang/include/flang/Parser/dump-parse-tree.h =================================================================== --- flang/include/flang/Parser/dump-parse-tree.h +++ flang/include/flang/Parser/dump-parse-tree.h @@ -792,10 +792,8 @@ template bool Pre(const UnlabeledStatement &) { return true; } template void Post(const UnlabeledStatement &) {} - template bool Pre(const common::Indirection &) { - return true; - } - template void Post(const common::Indirection &) {} + template bool Pre(const Indirection &) { return true; } + template void Post(const Indirection &) {} template bool Pre(const Scalar &) { Prefix("Scalar"); Index: flang/include/flang/Parser/format-specification.h =================================================================== --- flang/include/flang/Parser/format-specification.h +++ flang/include/flang/Parser/format-specification.h @@ -39,10 +39,15 @@ IntrinsicTypeDataEditDesc() = delete; IntrinsicTypeDataEditDesc(IntrinsicTypeDataEditDesc &&) = default; IntrinsicTypeDataEditDesc &operator=(IntrinsicTypeDataEditDesc &&) = default; +#ifdef ENABLE_PARSE_TREE_COPYING + IntrinsicTypeDataEditDesc(const IntrinsicTypeDataEditDesc &) = default; + IntrinsicTypeDataEditDesc &operator=( + const IntrinsicTypeDataEditDesc &) = default; +#endif IntrinsicTypeDataEditDesc(Kind &&k, std::optional &&w, std::optional &&d, std::optional &&e) - : kind{k}, width{std::move(w)}, digits{std::move(d)}, exponentWidth{ - std::move(e)} {} + : kind{k}, width{std::move(w)}, digits{std::move(d)}, + exponentWidth{std::move(e)} {} Kind kind; std::optional width; // w std::optional digits; // m or d @@ -56,6 +61,10 @@ DerivedTypeDataEditDesc() = delete; DerivedTypeDataEditDesc(DerivedTypeDataEditDesc &&) = default; DerivedTypeDataEditDesc &operator=(DerivedTypeDataEditDesc &&) = default; +#ifdef ENABLE_PARSE_TREE_COPYING + DerivedTypeDataEditDesc(const DerivedTypeDataEditDesc &) = default; + DerivedTypeDataEditDesc &operator=(const DerivedTypeDataEditDesc &) = default; +#endif DerivedTypeDataEditDesc(std::string &&t, std::list &&p) : type{std::move(t)}, parameters{std::move(p)} {} std::string type; @@ -100,6 +109,10 @@ ControlEditDesc() = delete; ControlEditDesc(ControlEditDesc &&) = default; ControlEditDesc &operator=(ControlEditDesc &&) = default; +#ifdef ENABLE_PARSE_TREE_COPYING + ControlEditDesc(const ControlEditDesc &) = default; + ControlEditDesc &operator=(const ControlEditDesc &) = default; +#endif explicit ControlEditDesc(Kind k) : kind{k} {} ControlEditDesc(Kind k, std::int64_t ct) : kind{k}, count{ct} {} ControlEditDesc(std::int64_t ct, Kind k) : kind{k}, count{ct} {} @@ -116,6 +129,10 @@ FormatItem() = delete; FormatItem(FormatItem &&) = default; FormatItem &operator=(FormatItem &&) = default; +#ifdef ENABLE_PARSE_TREE_COPYING + FormatItem(const FormatItem &) = default; + FormatItem &operator=(const FormatItem &) = default; +#endif template > FormatItem(std::optional &&r, A &&x) : repeatCount{std::move(r)}, u{std::move(x)} {} @@ -135,6 +152,10 @@ FormatSpecification() = delete; FormatSpecification(FormatSpecification &&) = default; FormatSpecification &operator=(FormatSpecification &&) = default; +#ifdef ENABLE_PARSE_TREE_COPYING + FormatSpecification(const FormatSpecification &) = default; + FormatSpecification &operator=(const FormatSpecification &) = default; +#endif explicit FormatSpecification(std::list &&is) : items(std::move(is)) {} FormatSpecification(std::list &&is, std::list &&us) Index: flang/include/flang/Parser/parse-tree-visitor.h =================================================================== --- flang/include/flang/Parser/parse-tree-visitor.h +++ flang/include/flang/Parser/parse-tree-visitor.h @@ -237,11 +237,10 @@ } template -void Walk(const common::Indirection &x, V &visitor) { +void Walk(const Indirection &x, V &visitor) { Walk(x.value(), visitor); } -template -void Walk(common::Indirection &x, M &mutator) { +template void Walk(Indirection &x, M &mutator) { Walk(x.value(), mutator); } Index: flang/include/flang/Parser/parse-tree.h =================================================================== --- flang/include/flang/Parser/parse-tree.h +++ flang/include/flang/Parser/parse-tree.h @@ -17,6 +17,17 @@ // run-time I/O support library have been isolated into a distinct header file // (viz., format-specification.h). +// Parse tree node class types do not, by default, have copy constructors +// or copy assignment operators. They are explicitly declared "= delete; +// to make this clear, although a C++ compiler shouldn't default them anyway +// due to the presence of explicitly defaulted move constructors and move +// assignments. This default behavior ensures that the parser is always +// correctly using fast move semantics and can't be mysteriously slowed +// down by an unintentional deep copy. + +// Include this header with ENABLE_PARSE_TREE_COPYING defined in order +// to enable copy constructors and copy assignment operators. + #include "char-block.h" #include "characters.h" #include "format-specification.h" @@ -42,11 +53,6 @@ // prevents the introduction of what would be a viral requirement to include // std::monostate among most std::variant<> discriminated union members. -// Parse tree node class types do not have copy constructors or copy assignment -// operators. They are explicitly declared "= delete;" to make this clear, -// although a C++ compiler wouldn't default them anyway due to the presence -// of explicitly defaulted move constructors and move assignments. - CLASS_TRAIT(EmptyTrait) CLASS_TRAIT(WrapperTrait) CLASS_TRAIT(UnionTrait) @@ -70,14 +76,26 @@ class ProcedureRef; // forward definition, represents a CALL or function ref } // namespace Fortran::evaluate +namespace Fortran::parser { + // Most non-template classes in this file use these default definitions // for their move constructor and move assignment operator=, and disable // their copy constructor and copy assignment operator=. +#ifdef ENABLE_PARSE_TREE_COPYING +static constexpr bool isCopyingEnabled{true}; #define COPY_AND_ASSIGN_BOILERPLATE(classname) \ classname(classname &&) = default; \ + classname(const classname &) = default; \ classname &operator=(classname &&) = default; \ + classname &operator=(const classname &) = default +#else +static constexpr bool isCopyingEnabled{false}; +#define COPY_AND_ASSIGN_BOILERPLATE(classname) \ + classname(classname &&) = default; \ classname(const classname &) = delete; \ + classname &operator=(classname &&) = default; \ classname &operator=(const classname &) = delete +#endif // Almost all classes in this file have no default constructor. #define BOILERPLATE(classname) \ @@ -125,8 +143,6 @@ WRAPPER_CLASS_BOILERPLATE(classname, type); \ } -namespace Fortran::parser { - // These are the unavoidable recursively-defined productions of Fortran. // Some references to the representations of their parses require // indirection. The Indirect<> pointer wrapper class is used to @@ -270,6 +286,9 @@ // Cooked character stream locations using Location = const char *; +template +using Indirection = common::Indirection; + // A parse tree node with provenance only struct Verbatim { // Allow a no-arg constructor for Verbatim so parsers can return `RESULT{}`. @@ -286,48 +305,43 @@ // scalar-xyz, constant-xzy, int-xzy, default-char-xyz, & logical-xyz. template struct Scalar { using ConstraintTrait = std::true_type; - Scalar(Scalar &&that) = default; Scalar(A &&that) : thing(std::move(that)) {} - Scalar &operator=(Scalar &&) = default; + BOILERPLATE(Scalar); A thing; }; template struct Constant { using ConstraintTrait = std::true_type; - Constant(Constant &&that) = default; Constant(A &&that) : thing(std::move(that)) {} - Constant &operator=(Constant &&) = default; + BOILERPLATE(Constant); A thing; }; template struct Integer { using ConstraintTrait = std::true_type; - Integer(Integer &&that) = default; Integer(A &&that) : thing(std::move(that)) {} - Integer &operator=(Integer &&) = default; + BOILERPLATE(Integer); A thing; }; template struct Logical { using ConstraintTrait = std::true_type; - Logical(Logical &&that) = default; Logical(A &&that) : thing(std::move(that)) {} - Logical &operator=(Logical &&) = default; + BOILERPLATE(Logical); A thing; }; template struct DefaultChar { using ConstraintTrait = std::true_type; - DefaultChar(DefaultChar &&that) = default; DefaultChar(A &&that) : thing(std::move(that)) {} - DefaultChar &operator=(DefaultChar &&) = default; + BOILERPLATE(DefaultChar); A thing; }; -using LogicalExpr = Logical>; // R1024 -using DefaultCharExpr = DefaultChar>; // R1025 -using IntExpr = Integer>; // R1026 -using ConstantExpr = Constant>; // R1029 +using LogicalExpr = Logical>; // R1024 +using DefaultCharExpr = DefaultChar>; // R1025 +using IntExpr = Integer>; // R1026 +using ConstantExpr = Constant>; // R1029 using IntConstantExpr = Integer; // R1031 using ScalarLogicalExpr = Scalar; using ScalarIntExpr = Scalar; @@ -343,13 +357,15 @@ // A wrapper for xzy-stmt productions that are statements, so that // source provenances and labels have a uniform representation. template struct UnlabeledStatement { - explicit UnlabeledStatement(A &&s) : statement(std::move(s)) {} + UnlabeledStatement(A &&s) : statement(std::move(s)) {} + COPY_AND_ASSIGN_BOILERPLATE(UnlabeledStatement); CharBlock source; A statement; }; template struct Statement : public UnlabeledStatement { Statement(std::optional &&lab, A &&s) : UnlabeledStatement{std::move(s)}, label(std::move(lab)) {} + COPY_AND_ASSIGN_BOILERPLATE(Statement); std::optional(x.value()); } @@ -148,10 +148,6 @@ return std::nullopt; } } - template - static Result GetSource(const common::Indirection &x) { - return GetSource(x.value()); - } template static Result GetSource(const common::Indirection &x) { Index: flang/include/flang/Parser/user-state.h =================================================================== --- flang/include/flang/Parser/user-state.h +++ flang/include/flang/Parser/user-state.h @@ -112,12 +112,12 @@ }; struct CapturedLabelDoStmt { - using resultType = Statement>; + using resultType = Statement>; static std::optional Parse(ParseState &); }; struct EndDoStmtForCapturedLabelDoStmt { - using resultType = Statement>; + using resultType = Statement>; static std::optional Parse(ParseState &); }; Index: flang/include/flang/Semantics/expression.h =================================================================== --- flang/include/flang/Semantics/expression.h +++ flang/include/flang/Semantics/expression.h @@ -73,9 +73,11 @@ explicit SetExprHelper(GenericExprWrapper &&expr) : expr_{std::move(expr)} {} void Set(parser::TypedExpr &x) { x.Reset(new GenericExprWrapper{std::move(expr_)}, - evaluate::GenericExprWrapper::Deleter); + evaluate::GenericExprWrapper::Deleter, + evaluate::GenericExprWrapper::Copier); } - template void Set(const common::Indirection &x) { + template + void Set(const common::Indirection &x) { Set(x.value()); } template void Set(const T &x) { @@ -159,7 +161,7 @@ MaybeExpr Analyze(const parser::AllocateObject &); MaybeExpr Analyze(const parser::PointerObject &); - template MaybeExpr Analyze(const common::Indirection &x) { + template MaybeExpr Analyze(const parser::Indirection &x) { return Analyze(x.value()); } template MaybeExpr Analyze(const std::optional &x) { Index: flang/include/flang/Semantics/tools.h =================================================================== --- flang/include/flang/Semantics/tools.h +++ flang/include/flang/Semantics/tools.h @@ -293,7 +293,8 @@ const SomeExpr *Get(const parser::AllocateObject &); const SomeExpr *Get(const parser::PointerObject &); - template const SomeExpr *Get(const common::Indirection &x) { + template + const SomeExpr *Get(const common::Indirection &x) { return Get(x.value()); } template const SomeExpr *Get(const std::optional &x) { @@ -593,8 +594,8 @@ LabelEnforce(SemanticsContext &context, std::set &&labels, parser::CharBlock constructSourcePosition, const char *construct) : context_{context}, labels_{labels}, - constructSourcePosition_{constructSourcePosition}, construct_{ - construct} {} + constructSourcePosition_{constructSourcePosition}, + construct_{construct} {} template bool Pre(const T &) { return true; } template bool Pre(const parser::Statement &statement) { currentStatementSourcePosition_ = statement.source; Index: flang/lib/Evaluate/call.cpp =================================================================== --- flang/lib/Evaluate/call.cpp +++ flang/lib/Evaluate/call.cpp @@ -67,8 +67,8 @@ 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) @@ -247,5 +247,8 @@ ProcedureRef::~ProcedureRef() {} void ProcedureRef::Deleter(ProcedureRef *p) { delete p; } +ProcedureRef *ProcedureRef::Copier(ProcedureRef *p) { + return p ? new ProcedureRef{*p} : nullptr; +} } // namespace Fortran::evaluate Index: flang/lib/Evaluate/expression.cpp =================================================================== --- flang/lib/Evaluate/expression.cpp +++ flang/lib/Evaluate/expression.cpp @@ -314,12 +314,19 @@ GenericExprWrapper::~GenericExprWrapper() {} void GenericExprWrapper::Deleter(GenericExprWrapper *p) { delete p; } +GenericExprWrapper *GenericExprWrapper::Copier(GenericExprWrapper *p) { + return p ? new GenericExprWrapper(*p) : nullptr; +} GenericAssignmentWrapper::~GenericAssignmentWrapper() {} void GenericAssignmentWrapper::Deleter(GenericAssignmentWrapper *p) { delete p; } +GenericAssignmentWrapper *GenericAssignmentWrapper::Copier( + GenericAssignmentWrapper *p) { + return p ? new GenericAssignmentWrapper{*p} : nullptr; +} template int Expr>::GetKind() const { return common::visit( Index: flang/lib/Lower/Bridge.cpp =================================================================== --- flang/lib/Lower/Bridge.cpp +++ flang/lib/Lower/Bridge.cpp @@ -2072,7 +2072,7 @@ void genFIR(const Fortran::parser::ForallStmt &stmt) { const auto &concurrentHeader = std::get< - Fortran::common::Indirection>( + Fortran::parser::Indirection>( stmt.t) .value(); if (lowerToHighLevelFIR()) { @@ -2110,7 +2110,7 @@ std::visit( Fortran::common::visitors{ [&](const Fortran::parser::WhereConstruct &b) { genFIR(b); }, - [&](const Fortran::common::Indirection< + [&](const Fortran::parser::Indirection< Fortran::parser::ForallConstruct> &b) { genFIR(b.value()); }, [&](const auto &b) { genNestedStatement(b); }}, s.u); @@ -2128,7 +2128,7 @@ void genFIR(const Fortran::parser::ForallConstructStmt &stmt) { const auto &concurrentHeader = std::get< - Fortran::common::Indirection>( + Fortran::parser::Indirection>( stmt.t) .value(); if (lowerToHighLevelFIR()) @@ -3694,7 +3694,7 @@ }, [&](const Fortran::parser::Statement &stmt) { genNestedStatement(stmt); }, - [&](const Fortran::common::Indirection< + [&](const Fortran::parser::Indirection< Fortran::parser::WhereConstruct> &c) { genFIR(c.value()); }, }, body.u); @@ -4506,7 +4506,7 @@ } void analyzeExplicitSpace(const Fortran::parser::WhereBodyConstruct &body) { std::visit(Fortran::common::visitors{ - [&](const Fortran::common::Indirection< + [&](const Fortran::parser::Indirection< Fortran::parser::WhereConstruct> &wc) { analyzeExplicitSpace(wc.value()); }, @@ -4538,7 +4538,7 @@ void analyzeExplicitSpace(const Fortran::parser::ForallStmt &forall) { analyzeExplicitSpace( std::get< - Fortran::common::Indirection>( + Fortran::parser::Indirection>( forall.t) .value()); analyzeExplicitSpace(std::get>( + Fortran::parser::Indirection>( forall.t) .value()); } @@ -4563,7 +4563,7 @@ for (const Fortran::parser::ForallBodyConstruct &s : std::get>(forall.t)) { std::visit(Fortran::common::visitors{ - [&](const Fortran::common::Indirection< + [&](const Fortran::parser::Indirection< Fortran::parser::ForallConstruct> &b) { analyzeExplicitSpace(b.value()); }, Index: flang/lib/Lower/OpenMP.cpp =================================================================== --- flang/lib/Lower/OpenMP.cpp +++ flang/lib/Lower/OpenMP.cpp @@ -2644,8 +2644,8 @@ // Check if the assignment statement has a single variable on the RHS const Fortran::parser::Expr &expr{ std::get(assignmentStmt.t)}; - const Fortran::common::Indirection *designator = - std::get_if>( + const Fortran::parser::Indirection *designator = + std::get_if>( &expr.u); const Fortran::parser::Name *name = designator Index: flang/lib/Lower/PFTBuilder.cpp =================================================================== --- flang/lib/Lower/PFTBuilder.cpp +++ flang/lib/Lower/PFTBuilder.cpp @@ -34,7 +34,11 @@ using Type = A; }; template -struct RemoveIndirectionHelper> { +struct RemoveIndirectionHelper> { + using Type = A; +}; +template +struct RemoveIndirectionHelper> { using Type = A; }; @@ -105,14 +109,14 @@ } else if constexpr (std::is_same_v) { return std::visit( common::visitors{ - [&](const common::Indirection &x) { + [&](const parser::Indirection &x) { addEvaluation(lower::pft::Evaluation{ removeIndirection(x), pftParentStack.back(), stmt.position, stmt.label}); checkForRoundingModeCall(x.value()); return true; }, - [&](const common::Indirection &x) { + [&](const parser::Indirection &x) { convertIfStmt(x.value(), stmt.position, stmt.label); return false; }, @@ -1642,9 +1646,8 @@ Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit( const parser::MainProgram &func, const lower::pft::PftNode &parent, const semantics::SemanticsContext &semanticsContext) - : ProgramUnit{func, parent}, endStmt{ - getFunctionStmt( - func)} { + : ProgramUnit{func, parent}, + endStmt{getFunctionStmt(func)} { const auto &programStmt = std::get>>(func.t); if (programStmt.has_value()) { @@ -1728,8 +1731,8 @@ Fortran::lower::pft::ModuleLikeUnit::ModuleLikeUnit( const parser::Submodule &m, const lower::pft::PftNode &parent) - : ProgramUnit{m, parent}, beginStmt{getModuleStmt( - m)}, + : ProgramUnit{m, parent}, + beginStmt{getModuleStmt(m)}, endStmt{getModuleStmt(m)} {} parser::CharBlock Index: flang/lib/Parser/basic-parsers.h =================================================================== --- flang/lib/Parser/basic-parsers.h +++ flang/lib/Parser/basic-parsers.h @@ -770,7 +770,7 @@ // For a parser p, indirect(p) returns a parser that builds an indirect // reference to p's return type. template inline constexpr auto indirect(PA p) { - return construct>(p); + return construct>(p); } // If a and b are parsers, then nonemptySeparated(a, b) returns a parser Index: flang/lib/Parser/parse-tree.cpp =================================================================== --- flang/lib/Parser/parse-tree.cpp +++ flang/lib/Parser/parse-tree.cpp @@ -8,7 +8,6 @@ #include "flang/Parser/parse-tree.h" #include "flang/Common/idioms.h" -#include "flang/Common/indirection.h" #include "flang/Parser/tools.h" #include "flang/Parser/user-state.h" #include "llvm/Support/raw_ostream.h" @@ -36,8 +35,7 @@ common::visitors{ [](const DataRef &dr) { return std::holds_alternative(dr.u) || - std::holds_alternative>( - dr.u); + std::holds_alternative>(dr.u); }, [](const Substring &) { return false; }, }, @@ -49,25 +47,24 @@ for (bool first{true}; !prl.empty(); first = false, prl.pop_front()) { PartRef &pr{prl.front()}; if (!first) { - u = common::Indirection::Make( + u = Indirection::Make( std::move(*this), std::move(pr.name)); } if (!pr.subscripts.empty()) { - u = common::Indirection::Make( + u = Indirection::Make( std::move(*this), std::move(pr.subscripts)); } if (pr.imageSelector) { - u = common::Indirection::Make( + u = Indirection::Make( std::move(*this), std::move(*pr.imageSelector)); } } } // R1001 - R1022 expression -Expr::Expr(Designator &&x) - : u{common::Indirection::Make(std::move(x))} {} +Expr::Expr(Designator &&x) : u{Indirection::Make(std::move(x))} {} Expr::Expr(FunctionReference &&x) - : u{common::Indirection::Make(std::move(x))} {} + : u{Indirection::Make(std::move(x))} {} const std::optional &DoConstruct::GetLoopControl() const { const NonLabelDoStmt &doStmt{ @@ -97,20 +94,23 @@ ArrayElement arrayElement{DataRef{Name{name}}, std::list{}}; for (Expr &expr : subscripts) { arrayElement.subscripts.push_back( - SectionSubscript{Integer{common::Indirection{std::move(expr)}}}); + SectionSubscript{Integer{Indirection{std::move(expr)}}}); } - return Designator{DataRef{common::Indirection{std::move(arrayElement)}}}; + return Designator{ + DataRef{Indirection{std::move(arrayElement)}}}; } static Designator MakeArrayElementRef( StructureComponent &&sc, std::list &&subscripts) { - ArrayElement arrayElement{DataRef{common::Indirection{std::move(sc)}}, + ArrayElement arrayElement{ + DataRef{Indirection{std::move(sc)}}, std::list{}}; for (Expr &expr : subscripts) { arrayElement.subscripts.push_back( - SectionSubscript{Integer{common::Indirection{std::move(expr)}}}); + SectionSubscript{Integer{Indirection{std::move(expr)}}}); } - return Designator{DataRef{common::Indirection{std::move(arrayElement)}}}; + return Designator{ + DataRef{Indirection{std::move(arrayElement)}}}; } // Set source in any type of node that has it. @@ -122,19 +122,18 @@ static Expr ActualArgToExpr(ActualArgSpec &arg) { return common::visit( common::visitors{ - [&](common::Indirection &y) { return std::move(y.value()); }, - [&](common::Indirection &y) { - return common::visit( - common::visitors{ - [&](common::Indirection &z) { - return WithSource( - z.value().source, Expr{std::move(z.value())}); - }, - [&](common::Indirection &z) { - return WithSource( - z.value().source, Expr{std::move(z.value())}); - }, - }, + [&](Indirection &y) { return std::move(y.value()); }, + [&](Indirection &y) { + return common::visit(common::visitors{ + [&](Indirection &z) { + return WithSource(z.value().source, + Expr{std::move(z.value())}); + }, + [&](Indirection &z) { + return WithSource(z.value().source, + Expr{std::move(z.value())}); + }, + }, y.value().u); }, [&](auto &) -> Expr { common::die("unexpected type"); }, @@ -163,7 +162,7 @@ StructureConstructor FunctionReference::ConvertToStructureConstructor( const semantics::DerivedTypeSpec &derived) { - Name name{std::get(std::get(v.t).u)}; + Name name{std::get(std::get(v.t).u)}; std::list components; for (auto &arg : std::get>(v.t)) { std::optional keyword; @@ -180,7 +179,7 @@ StructureConstructor ArrayElement::ConvertToStructureConstructor( const semantics::DerivedTypeSpec &derived) { - Name name{std::get(base.u)}; + Name name{std::get(base.u)}; std::list components; for (auto &subscript : subscripts) { components.emplace_back(std::optional{}, @@ -230,22 +229,21 @@ Call{ProcedureDesignator{Name{funcName.source, funcName.symbol}}, std::move(actuals)}}; funcRef.source = source; - auto variable{Variable{common::Indirection{std::move(funcRef)}}}; + auto variable{Variable{Indirection{std::move(funcRef)}}}; return Statement{std::nullopt, - ActionStmt{common::Indirection{ + ActionStmt{Indirection{ AssignmentStmt{std::move(variable), std::move(funcExpr)}}}}; } CharBlock Variable::GetSource() const { - return common::visit( - common::visitors{ - [&](const common::Indirection &des) { - return des.value().source; - }, - [&](const common::Indirection &call) { - return call.value().source; - }, - }, + return common::visit(common::visitors{ + [&](const Indirection &des) { + return des.value().source; + }, + [&](const Indirection &call) { + return call.value().source; + }, + }, u); } Index: flang/lib/Parser/tools.cpp =================================================================== --- flang/lib/Parser/tools.cpp +++ flang/lib/Parser/tools.cpp @@ -20,13 +20,15 @@ return common::visit( common::visitors{ [](const Name &name) -> const Name & { return name; }, - [](const common::Indirection &sc) - -> const Name & { return GetLastName(sc.value()); }, - [](const common::Indirection &sc) -> const Name & { + [](const Indirection &sc) -> const Name & { + return GetLastName(sc.value()); + }, + [](const Indirection &sc) -> const Name & { return GetLastName(sc.value().base); }, - [](const common::Indirection &ci) - -> const Name & { return GetLastName(ci.value().base); }, + [](const Indirection &ci) -> const Name & { + return GetLastName(ci.value().base); + }, }, x.u); } @@ -78,13 +80,15 @@ return common::visit( common::visitors{ [](const Name &name) -> const Name & { return name; }, - [](const common::Indirection &sc) - -> const Name & { return GetFirstName(sc.value()); }, - [](const common::Indirection &sc) -> const Name & { + [](const Indirection &sc) -> const Name & { + return GetFirstName(sc.value()); + }, + [](const Indirection &sc) -> const Name & { return GetFirstName(sc.value().base); }, - [](const common::Indirection &ci) - -> const Name & { return GetFirstName(ci.value().base); }, + [](const Indirection &ci) -> const Name & { + return GetFirstName(ci.value().base); + }, }, x.u); } @@ -127,7 +131,7 @@ return common::visit( common::visitors{ [](const Name &) -> const CoindexedNamedObject * { return nullptr; }, - [](const common::Indirection &x) + [](const Indirection &x) -> const CoindexedNamedObject * { return &x.value(); }, [](const auto &x) -> const CoindexedNamedObject * { return GetCoindexedNamedObject(x.value().base); @@ -151,7 +155,7 @@ const CoindexedNamedObject *GetCoindexedNamedObject(const Variable &variable) { return common::visit( common::visitors{ - [](const common::Indirection &designator) + [](const Indirection &designator) -> const CoindexedNamedObject * { return GetCoindexedNamedObject(designator.value()); }, Index: flang/lib/Parser/unparse.cpp =================================================================== --- flang/lib/Parser/unparse.cpp +++ flang/lib/Parser/unparse.cpp @@ -286,8 +286,8 @@ const auto &init{ std::get>(d.t)}; return init && - std::holds_alternative>>( + std::holds_alternative< + std::list>>( init->u); }, [](const FillDecl &) { return false; }, @@ -350,15 +350,14 @@ } void Unparse(const Pass &x) { Word("PASS"), Walk("(", x.v, ")"); } void Unparse(const Initialization &x) { // R743 & R805 - common::visit( - common::visitors{ - [&](const ConstantExpr &y) { Put(" = "), Walk(y); }, - [&](const NullInit &y) { Put(" => "), Walk(y); }, - [&](const InitialDataTarget &y) { Put(" => "), Walk(y); }, - [&](const std::list> &y) { - Walk("/", y, ", ", "/"); - }, - }, + common::visit(common::visitors{ + [&](const ConstantExpr &y) { Put(" = "), Walk(y); }, + [&](const NullInit &y) { Put(" => "), Walk(y); }, + [&](const InitialDataTarget &y) { Put(" => "), Walk(y); }, + [&](const std::list> &y) { + Walk("/", y, ", ", "/"); + }, + }, x.u); } void Unparse(const PrivateStmt &) { // R745 @@ -379,7 +378,7 @@ } void Unparse(const TypeBoundGenericStmt &x) { // R751 Word("GENERIC"), Walk(", ", std::get>(x.t)); - Put(" :: "), Walk(std::get>(x.t)); + Put(" :: "), Walk(std::get>(x.t)); Put(" => "), Walk(std::get>(x.t), ", "); } void Post(const BindAttr::Deferred &) { Word("DEFERRED"); } // R752 @@ -449,8 +448,7 @@ Walk(dts), Walk(", ", attrs, ", "); static const auto isInitializerOldStyle{[](const Initialization &i) { - return std::holds_alternative< - std::list>>(i.u); + return std::holds_alternative>>(i.u); }}; static const auto hasAssignmentInitializer{[](const EntityDecl &d) { // Does a declaration have a new-style =x initializer? @@ -945,7 +943,7 @@ } void Unparse(const ForallConstructStmt &x) { // R1051 Walk(std::get>(x.t), ": "); - Word("FORALL"), Walk(std::get>(x.t)); + Word("FORALL"), Walk(std::get>(x.t)); Indent(); } void Unparse(const EndForallStmt &x) { // R1054 Index: flang/lib/Semantics/canonicalize-do.cpp =================================================================== --- flang/lib/Semantics/canonicalize-do.cpp +++ flang/lib/Semantics/canonicalize-do.cpp @@ -29,59 +29,59 @@ [](auto &) {}, // Labels on end-stmt of constructs are accepted by f18 as an // extension. - [&](common::Indirection &associate) { + [&](Indirection &associate) { CanonicalizeIfMatch(block, stack, i, std::get>( associate.value().t)); }, - [&](common::Indirection &blockConstruct) { + [&](Indirection &blockConstruct) { CanonicalizeIfMatch(block, stack, i, std::get>( blockConstruct.value().t)); }, - [&](common::Indirection &changeTeam) { + [&](Indirection &changeTeam) { CanonicalizeIfMatch(block, stack, i, std::get>( changeTeam.value().t)); }, - [&](common::Indirection &critical) { + [&](Indirection &critical) { CanonicalizeIfMatch(block, stack, i, std::get>(critical.value().t)); }, - [&](common::Indirection &doConstruct) { + [&](Indirection &doConstruct) { CanonicalizeIfMatch(block, stack, i, std::get>(doConstruct.value().t)); }, - [&](common::Indirection &ifConstruct) { + [&](Indirection &ifConstruct) { CanonicalizeIfMatch(block, stack, i, std::get>(ifConstruct.value().t)); }, - [&](common::Indirection &caseConstruct) { + [&](Indirection &caseConstruct) { CanonicalizeIfMatch(block, stack, i, std::get>( caseConstruct.value().t)); }, - [&](common::Indirection &selectRank) { + [&](Indirection &selectRank) { CanonicalizeIfMatch(block, stack, i, std::get>(selectRank.value().t)); }, - [&](common::Indirection &selectType) { + [&](Indirection &selectType) { CanonicalizeIfMatch(block, stack, i, std::get>(selectType.value().t)); }, - [&](common::Indirection &forall) { + [&](Indirection &forall) { CanonicalizeIfMatch(block, stack, i, std::get>(forall.value().t)); }, - [&](common::Indirection &where) { + [&](Indirection &where) { CanonicalizeIfMatch(block, stack, i, std::get>(where.value().t)); }, - [&](Statement> &labelDoStmt) { + [&](Statement> &labelDoStmt) { auto &label{std::get &x) { + template + static MaybeMsg WhyNotOk(const common::Indirection &x) { return WhyNotOk(x.value()); } template @@ -232,17 +232,17 @@ common::visit( common::visitors{ [&](const parser::ExecutableConstruct &x) { Check(x); }, - [&](const parser::Statement> + [&](const parser::Statement> &x) { context_.Say(x.source, "Device code may not contain an ENTRY statement"_err_en_US); }, - [](const parser::Statement> + [](const parser::Statement> &) {}, - [](const parser::Statement> + [](const parser::Statement> &) {}, [](const parser::Statement< - common::Indirection> &) {}, + parser::Indirection> &) {}, [](const parser::ErrorRecovery &) {}, }, epc.u); @@ -253,17 +253,17 @@ [&](const parser::Statement &stmt) { Check(stmt.statement, stmt.source); }, - [&](const common::Indirection &x) { + [&](const parser::Indirection &x) { if (const std::optional &control{ x.value().GetLoopControl()}) { common::visit([&](const auto &y) { Check(y); }, control->u); } Check(std::get(x.value().t)); }, - [&](const common::Indirection &x) { + [&](const parser::Indirection &x) { Check(std::get(x.value().t)); }, - [&](const common::Indirection &x) { + [&](const parser::Indirection &x) { Check(x.value()); }, [&](const auto &x) { @@ -376,7 +376,7 @@ if (const auto *execConstruct{ std::get_if(&innerBlock->front().u)}) { if (const auto *next{ - std::get_if>( + std::get_if>( &execConstruct->u)}) { return 1 + DoConstructTightNesting(&next->value(), innerBlock); } Index: flang/lib/Semantics/check-data.cpp =================================================================== --- flang/lib/Semantics/check-data.cpp +++ flang/lib/Semantics/check-data.cpp @@ -187,7 +187,7 @@ void DataChecker::Leave(const parser::DataIDoObject &object) { if (const auto *designator{ - std::get_if>>( + std::get_if>>( &object.u)}) { if (MaybeExpr expr{exprAnalyzer_.Analyze(*designator)}) { auto source{designator->thing.value().source}; @@ -243,7 +243,7 @@ std::get>(decl.t)}) { const Symbol *name{std::get(decl.t).symbol}; const auto *list{ - std::get_if>>( + std::get_if>>( &init->u)}; if (name && list) { AccumulateDataInitializations(inits_, exprAnalyzer_, *name, *list); Index: flang/lib/Semantics/check-do-forall.cpp =================================================================== --- flang/lib/Semantics/check-do-forall.cpp +++ flang/lib/Semantics/check-do-forall.cpp @@ -48,13 +48,13 @@ const parser::ForallConstruct &construct) { const auto &stmt{ std::get>(construct.t)}; - return std::get>( + return std::get>( stmt.statement.t) .value(); } static const parser::ConcurrentHeader &GetConcurrentHeader( const parser::ForallStmt &stmt) { - return std::get>(stmt.t) + return std::get>(stmt.t) .value(); } template @@ -88,8 +88,8 @@ public: DoConcurrentBodyEnforce( SemanticsContext &context, parser::CharBlock doConcurrentSourcePosition) - : context_{context}, doConcurrentSourcePosition_{ - doConcurrentSourcePosition} {} + : context_{context}, + doConcurrentSourcePosition_{doConcurrentSourcePosition} {} std::set labels() { return labels_; } template bool Pre(const T &x) { if (const auto *expr{GetExpr(context_, x)}) { @@ -987,7 +987,7 @@ if (checkedOptionalArg) { const evaluate::ActualArgument &checkedArg{*checkedOptionalArg}; if (const auto *parsedExpr{ - std::get_if>(&parsedArg.u)}) { + std::get_if>(&parsedArg.u)}) { CheckIfArgIsDoVar(checkedArg, parsedExpr->value().source, context_); } } Index: flang/lib/Semantics/check-if-stmt.cpp =================================================================== --- flang/lib/Semantics/check-if-stmt.cpp +++ flang/lib/Semantics/check-if-stmt.cpp @@ -17,7 +17,7 @@ // C1143 Check that the action stmt is not an if stmt const auto &body{ std::get>(ifStmt.t)}; - if (std::holds_alternative>( + if (std::holds_alternative>( body.statement.u)) { context_.Say( body.source, "IF statement is not allowed in IF statement"_err_en_US); Index: flang/lib/Semantics/check-io.h =================================================================== --- flang/lib/Semantics/check-io.h +++ flang/lib/Semantics/check-io.h @@ -36,7 +36,7 @@ void Enter(const parser::WriteStmt &) { Init(IoStmtKind::Write); } void Enter( - const parser::Statement> &); + const parser::Statement> &); void Enter(const parser::ConnectSpec &); void Enter(const parser::ConnectSpec::CharExpr &); Index: flang/lib/Semantics/check-io.cpp =================================================================== --- flang/lib/Semantics/check-io.cpp +++ flang/lib/Semantics/check-io.cpp @@ -58,7 +58,7 @@ } void IoChecker::Enter( - const parser::Statement> &stmt) { + const parser::Statement> &stmt) { if (!stmt.label) { context_.Say("Format statement must be labeled"_err_en_US); // C1301 } Index: flang/lib/Semantics/check-omp-structure.h =================================================================== --- flang/lib/Semantics/check-omp-structure.h +++ flang/lib/Semantics/check-omp-structure.h @@ -210,7 +210,7 @@ void CheckDependList(const parser::DataRef &); void CheckDependArraySection( - const common::Indirection &, const parser::Name &); + const parser::Indirection &, const parser::Name &); bool IsDataRefTypeParamInquiry(const parser::DataRef *dataRef); void CheckIsVarPartOfAnotherVar( const parser::CharBlock &source, const parser::OmpObjectList &objList); Index: flang/lib/Semantics/check-omp-structure.cpp =================================================================== --- flang/lib/Semantics/check-omp-structure.cpp +++ flang/lib/Semantics/check-omp-structure.cpp @@ -1617,7 +1617,7 @@ const auto &var{std::get(assignment.t)}; common::visit( common::visitors{ - [&](const common::Indirection &x) { + [&](const parser::Indirection &x) { const auto &procedureDesignator{ std::get(x.value().v.t)}; const parser::Name *name{ @@ -1632,7 +1632,7 @@ } else if (name) { bool foundMatch{false}; if (auto varDesignatorIndirection = - std::get_if>(&var.u)) { const auto &varDesignator = varDesignatorIndirection->value(); if (const auto *dataRef = std::get_if( @@ -2492,7 +2492,7 @@ if (const auto *dataRef{std::get_if(&ele.u)}) { CheckDependList(*dataRef); if (const auto *arr{ - std::get_if>( + std::get_if>( &dataRef->u)}) { CheckArraySection(arr->value(), GetLastName(*dataRef), llvm::omp::Clause::OMPC_depend); @@ -2569,18 +2569,18 @@ void OmpStructureChecker::CheckDependList(const parser::DataRef &d) { common::visit( common::visitors{ - [&](const common::Indirection &elem) { + [&](const parser::Indirection &elem) { // Check if the base element is valid on Depend Clause CheckDependList(elem.value().base); }, - [&](const common::Indirection &) { + [&](const parser::Indirection &) { context_.Say(GetContext().clauseSource, "A variable that is part of another variable " "(such as an element of a structure) but is not an array " "element or an array section cannot appear in a DEPEND " "clause"_err_en_US); }, - [&](const common::Indirection &) { + [&](const parser::Indirection &) { context_.Say(GetContext().clauseSource, "Coarrays are not supported in DEPEND clause"_err_en_US); }, Index: flang/lib/Semantics/data-to-inits.h =================================================================== --- flang/lib/Semantics/data-to-inits.h +++ flang/lib/Semantics/data-to-inits.h @@ -12,13 +12,10 @@ #include "flang/Common/default-kinds.h" #include "flang/Common/interval.h" #include "flang/Evaluate/initial-image.h" +#include "flang/Parser/parse-tree.h" #include #include -namespace Fortran::parser { -struct DataStmtSet; -struct DataStmtValue; -} // namespace Fortran::parser namespace Fortran::evaluate { class ExpressionAnalyzer; } @@ -44,7 +41,7 @@ // For legacy DATA-style initialization extension: integer n(2)/1,2/ void AccumulateDataInitializations(DataInitializations &, evaluate::ExpressionAnalyzer &, const Symbol &, - const std::list> &); + const std::list> &); void ConvertToInitializers( DataInitializations &, evaluate::ExpressionAnalyzer &); Index: flang/lib/Semantics/data-to-inits.cpp =================================================================== --- flang/lib/Semantics/data-to-inits.cpp +++ flang/lib/Semantics/data-to-inits.cpp @@ -136,7 +136,7 @@ const parser::DataStmtObject &object) { return common::visit( common::visitors{ - [&](const common::Indirection &var) { + [&](const parser::Indirection &var) { return Scan(var.value()); }, [&](const parser::DataImpliedDo &ido) { return Scan(ido); }, @@ -241,9 +241,9 @@ const parser::DataIDoObject &object) { return common::visit( common::visitors{ - [&](const parser::Scalar> + [&](const parser::Scalar> &var) { return Scan(var.thing.value()); }, - [&](const common::Indirection &ido) { + [&](const parser::Indirection &ido) { return Scan(ido.value()); }, }, @@ -488,8 +488,8 @@ void AccumulateDataInitializations(DataInitializations &inits, evaluate::ExpressionAnalyzer &exprAnalyzer, const Symbol &symbol, - const std::list> &list) { - DataInitializationCompiler> + const std::list> &list) { + DataInitializationCompiler> scanner{inits, exprAnalyzer, list}; if (scanner.Scan(symbol) && scanner.HasSurplusValues()) { exprAnalyzer.context().Say( Index: flang/lib/Semantics/expression.cpp =================================================================== --- flang/lib/Semantics/expression.cpp +++ flang/lib/Semantics/expression.cpp @@ -65,12 +65,12 @@ static std::optional AnalyzeTypeSpec( const std::optional &spec) { if (spec) { - if (const semantics::DeclTypeSpec *typeSpec{spec->declTypeSpec}) { + if (const semantics::DeclTypeSpec * typeSpec{spec->declTypeSpec}) { // Name resolution sets TypeSpec::declTypeSpec only when it's valid // (viz., an intrinsic type with valid known kind or a non-polymorphic // & non-ABSTRACT derived type). - if (const semantics::IntrinsicTypeSpec *intrinsic{ - typeSpec->AsIntrinsic()}) { + if (const semantics::IntrinsicTypeSpec * + intrinsic{typeSpec->AsIntrinsic()}) { TypeCategory category{intrinsic->category()}; if (auto optKind{ToInt64(intrinsic->kind())}) { int kind{static_cast(*optKind)}; @@ -85,8 +85,8 @@ return DynamicTypeWithLength{DynamicType{category, kind}}; } } - } else if (const semantics::DerivedTypeSpec *derived{ - typeSpec->AsDerived()}) { + } else if (const semantics::DerivedTypeSpec * + derived{typeSpec->AsDerived()}) { return DynamicTypeWithLength{DynamicType{*derived}}; } } @@ -131,7 +131,7 @@ Expr &&MoveExpr(std::size_t i) { return std::move(DEREF(actuals_.at(i).value().UnwrapExpr())); } - void Analyze(const common::Indirection &x) { + void Analyze(const parser::Indirection &x) { Analyze(x.value()); } void Analyze(const parser::Expr &x) { @@ -263,7 +263,7 @@ } else if (const auto *object{ symbol.detailsIf()}) { // C928 & C1002 - if (Triplet *last{std::get_if(&ref.subscript().back().u)}) { + if (Triplet * last{std::get_if(&ref.subscript().back().u)}) { if (!last->upper() && object->IsAssumedSize()) { Say("Assumed-size array '%s' must have explicit final " "subscript upper bound value"_err_en_US, @@ -497,17 +497,17 @@ static std::optional FixMisparsedSubstringDataRef( parser::DataRef &dataRef) { if (auto *ae{ - std::get_if>(&dataRef.u)}) { + std::get_if>(&dataRef.u)}) { // ...%a(j:k) and "a" is a character scalar parser::ArrayElement &arrElement{ae->value()}; if (arrElement.subscripts.size() == 1) { if (auto *triplet{std::get_if( &arrElement.subscripts.front().u)}) { if (!std::get<2 /*stride*/>(triplet->t).has_value()) { - if (const Symbol *symbol{ - parser::GetLastName(arrElement.base).symbol}) { + if (const Symbol * + symbol{parser::GetLastName(arrElement.base).symbol}) { const Symbol &ultimate{symbol->GetUltimate()}; - if (const semantics::DeclTypeSpec *type{ultimate.GetType()}) { + if (const semantics::DeclTypeSpec * type{ultimate.GetType()}) { if (!ultimate.IsObjectArray() && type->category() == semantics::DeclTypeSpec::Character) { // The ambiguous S(j:k) was parsed as an array section @@ -533,7 +533,7 @@ const parser::Designator &d) { auto &mutate{const_cast(d)}; if (auto *dataRef{std::get_if(&mutate.u)}) { - if (auto *sc{std::get_if>( + if (auto *sc{std::get_if>( &dataRef->u)}) { parser::StructureComponent &structComponent{sc->value()}; parser::CharBlock which{structComponent.component.source}; @@ -930,7 +930,8 @@ ultimate, AsGenericExpr(TypeParamInquiry{std::nullopt, ultimate}))); } else { if (n.symbol->attrs().test(semantics::Attr::VOLATILE)) { - if (const semantics::Scope *pure{semantics::FindPureProcedureContaining( + if (const semantics::Scope * + pure{semantics::FindPureProcedureContaining( context_.FindScope(n.source))}) { SayAt(n, "VOLATILE variable '%s' may not be referenced in pure subprogram '%s'"_err_en_US, @@ -1199,7 +1200,7 @@ if (ae.subscripts.empty()) { // will be converted to function call later or error reported } else if (baseExpr->Rank() == 0) { - if (const Symbol *symbol{GetLastSymbol(*baseExpr)}) { + if (const Symbol * symbol{GetLastSymbol(*baseExpr)}) { if (!context_.HasError(symbol)) { if (inDataStmtConstant_) { // Better error for NULL(X) with a MOLD= argument @@ -1251,13 +1252,14 @@ if (&component.owner() == &scope) { return Component{std::move(base), component}; } - if (const Symbol *typeSymbol{scope.GetSymbol()}) { - if (const Symbol *parentComponent{typeSymbol->GetParentComponent(&scope)}) { + if (const Symbol * typeSymbol{scope.GetSymbol()}) { + if (const Symbol * + parentComponent{typeSymbol->GetParentComponent(&scope)}) { if (const auto *object{ parentComponent->detailsIf()}) { if (const auto *parentType{object->type()}) { - if (const semantics::Scope *parentScope{ - parentType->derivedTypeSpec().scope()}) { + if (const semantics::Scope * + parentScope{parentType->derivedTypeSpec().scope()}) { return CreateComponent( DataRef{Component{std::move(base), *parentComponent}}, component, *parentScope); @@ -1357,7 +1359,7 @@ if (auto *aRef{std::get_if(&dataRef->u)}) { subscripts = std::move(aRef->subscript()); reversed.push_back(aRef->GetLastSymbol()); - if (Component *component{aRef->base().UnwrapComponent()}) { + if (Component * component{aRef->base().UnwrapComponent()}) { dataRef = &component->base(); } else { dataRef = nullptr; @@ -1682,10 +1684,10 @@ common::visit( common::visitors{ [&](const parser::AcValue::Triplet &triplet) { Add(triplet); }, - [&](const common::Indirection &expr) { + [&](const parser::Indirection &expr) { Add(expr.value()); }, - [&](const common::Indirection &impliedDo) { + [&](const parser::Indirection &impliedDo) { Add(impliedDo.value()); }, }, @@ -1842,7 +1844,7 @@ auto &parsedType{std::get(structure.t)}; parser::Name structureType{std::get(parsedType.t)}; parser::CharBlock &typeName{structureType.source}; - if (semantics::Symbol *typeSymbol{structureType.symbol}) { + if (semantics::Symbol * typeSymbol{structureType.symbol}) { if (typeSymbol->has()) { semantics::DerivedTypeSpec dtSpec{typeName, typeSymbol->GetUltimate()}; if (!CheckIsValidForwardReference(dtSpec)) { @@ -2149,9 +2151,7 @@ static std::optional GetPassIndex(const Symbol &proc) { CHECK(!proc.attrs().test(semantics::Attr::NOPASS)); std::optional passName{GetPassName(proc)}; - const auto *interface { - semantics::FindInterface(proc) - }; + const auto *interface{semantics::FindInterface(proc)}; if (!passName || !interface) { return 0; // first argument is passed-object } @@ -2219,7 +2219,7 @@ bool isSubroutine) -> std::optional { const parser::StructureComponent &sc{pcr.v.thing}; if (MaybeExpr base{Analyze(sc.base)}) { - if (const Symbol *sym{sc.component.symbol}) { + if (const Symbol * sym{sc.component.symbol}) { if (context_.HasError(sym)) { return std::nullopt; } @@ -2299,8 +2299,8 @@ "Base of procedure component reference must be scalar"_err_en_US); } } - if (const Symbol *resolution{ - GetBindingResolution(dtExpr->GetType(), *sym)}) { + if (const Symbol * + resolution{GetBindingResolution(dtExpr->GetType(), *sym)}) { AddPassArg(arguments, std::move(*dtExpr), *sym, false); return CalleeAndArguments{ ProcedureDesignator{*resolution}, std::move(arguments)}; @@ -2480,7 +2480,7 @@ } // Check parent derived type if (const auto *parentScope{symbol.owner().GetDerivedTypeParent()}) { - if (const Symbol *extended{parentScope->FindComponent(symbol.name())}) { + if (const Symbol * extended{parentScope->FindComponent(symbol.name())}) { auto pair{ResolveGeneric( *extended, actuals, adjustActuals, isSubroutine, false)}; if (pair.first) { @@ -2496,7 +2496,7 @@ // See 15.5.5.2 for details. if (!symbol.owner().IsGlobal() && !symbol.owner().IsDerivedType()) { for (const std::string &n : GetAllNames(context_, symbol.name())) { - if (const Symbol *outer{symbol.owner().parent().FindSymbol(n)}) { + if (const Symbol * outer{symbol.owner().parent().FindSymbol(n)}) { auto pair{ResolveGeneric(*outer, actuals, adjustActuals, isSubroutine, mightBeStructureConstructor)}; if (pair.first) { @@ -2698,7 +2698,7 @@ template static const Symbol *AssumedTypeDummy(const A &x) { if (const auto *designator{ - std::get_if>(&x.u)}) { + std::get_if>(&x.u)}) { if (const auto *dataRef{ std::get_if(&designator->value().u)}) { if (const auto *name{std::get_if(&dataRef->u)}) { @@ -2710,7 +2710,7 @@ } template <> const Symbol *AssumedTypeDummy(const parser::Name &name) { - if (const Symbol *symbol{name.symbol}) { + if (const Symbol * symbol{name.symbol}) { if (const auto *type{symbol->GetType()}) { if (type->category() == semantics::DeclTypeSpec::TypeStar) { return symbol; @@ -2903,7 +2903,7 @@ callStmt.typedCall.Reset( new ProcedureRef{std::move(*proc), std::move(callee->arguments), HasAlternateReturns(callee->arguments)}, - ProcedureRef::Deleter); + ProcedureRef::Deleter, ProcedureRef::Copier); DEREF(callStmt.typedCall.get()).set_chevrons(std::move(*chevrons)); return; } @@ -2950,7 +2950,7 @@ } } x.typedAssignment.Reset(new GenericAssignmentWrapper{std::move(assignment)}, - GenericAssignmentWrapper::Deleter); + GenericAssignmentWrapper::Deleter, GenericAssignmentWrapper::Copier); } return common::GetPtrFromOptional(x.typedAssignment->v); } @@ -2965,8 +2965,8 @@ rhs = Analyze(std::get(x.t)); } if (!lhs || !rhs) { - x.typedAssignment.Reset( - new GenericAssignmentWrapper{}, GenericAssignmentWrapper::Deleter); + x.typedAssignment.Reset(new GenericAssignmentWrapper{}, + GenericAssignmentWrapper::Deleter, GenericAssignmentWrapper::Copier); } else { Assignment assignment{std::move(*lhs), std::move(*rhs)}; common::visit( @@ -2996,7 +2996,7 @@ std::get(x.t).u); x.typedAssignment.Reset( new GenericAssignmentWrapper{std::move(assignment)}, - GenericAssignmentWrapper::Deleter); + GenericAssignmentWrapper::Deleter, GenericAssignmentWrapper::Copier); } } return common::GetPtrFromOptional(x.typedAssignment->v); @@ -3081,7 +3081,7 @@ } if (ok && !treatExternalAsImplicit && procSymbol && !(chars && chars->HasExplicitInterface())) { - if (const Symbol *global{FindGlobal(*procSymbol)}; + if (const Symbol * global{FindGlobal(*procSymbol)}; global && global != procSymbol && IsProcedure(*global)) { // Check a known global definition behind a local interface if (auto globalChars{characteristics::Procedure::Characterize( @@ -3099,8 +3099,8 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::Parentheses &x) { if (MaybeExpr operand{Analyze(x.v.value())}) { - if (const semantics::Symbol *symbol{GetLastSymbol(*operand)}) { - if (const semantics::Symbol *result{FindFunctionResult(*symbol)}) { + if (const semantics::Symbol * symbol{GetLastSymbol(*operand)}) { + if (const semantics::Symbol * result{FindFunctionResult(*symbol)}) { if (semantics::IsProcedurePointer(*result)) { Say("A function reference that returns a procedure " "pointer may not be parenthesized"_err_en_US); // C1003 @@ -3168,7 +3168,7 @@ // intrinsic function. // Use the actual source for the name of the call for error reporting. std::optional arg; - if (const Symbol *assumedTypeDummy{AssumedTypeDummy(x.v.value())}) { + if (const Symbol * assumedTypeDummy{AssumedTypeDummy(x.v.value())}) { arg = ActualArgument{ActualArgument::AssumedType{*assumedTypeDummy}}; } else if (MaybeExpr argExpr{Analyze(x.v.value())}) { arg = ActualArgument{std::move(*argExpr)}; @@ -3391,7 +3391,8 @@ if (!name->symbol) { return false; } else if (name->symbol->Rank() == 0) { - if (const Symbol *function{ + if (const Symbol * + function{ semantics::IsFunctionResultWithSameNameAsFunction(*name->symbol)}) { auto &msg{context.Say(funcRef.source, function->flags().test(Symbol::Flag::StmtFunction) @@ -3426,7 +3427,7 @@ using uType = std::decay_t; auto &u{const_cast(constU)}; if (auto *func{ - std::get_if>(&u)}) { + std::get_if>(&u)}) { parser::FunctionReference &funcRef{func->value()}; // Ensure that there are no argument keywords for (const auto &arg : @@ -3436,7 +3437,8 @@ } } auto &proc{std::get(funcRef.v.t)}; - if (Symbol *origSymbol{ + if (Symbol * + origSymbol{ common::visit(common::visitors{ [&](parser::Name &name) { return name.symbol; }, [&](parser::ProcComponentRef &pcr) { @@ -3449,10 +3451,11 @@ symbol.has()) { // Note that expression in AssocEntityDetails cannot be a procedure // pointer as per C1105 so this cannot be a function reference. - if constexpr (common::HasMember, + if constexpr (common::HasMember, uType>) { if (CheckFuncRefToArrayElement(context, funcRef)) { - u = common::Indirection{funcRef.ConvertToArrayElementRef()}; + u = parser::Indirection{ + funcRef.ConvertToArrayElementRef()}; } } else { DIE("can't fix misparsed function as array reference"); @@ -3480,10 +3483,10 @@ MaybeExpr result; if constexpr (common::HasMember> && - common::HasMember, + common::HasMember, std::decay_t>) { if (const auto *funcRef{ - std::get_if>( + std::get_if>( &x.u)}) { // Function references in Exprs might turn out to be misparsed structure // constructors; we have to try generic procedure resolution @@ -3610,7 +3613,7 @@ auto restorer{GetContextualMessages().SetLocation(source)}; FixMisparsedFunctionReference(context_, var->u); if (const auto *funcRef{ - std::get_if>( + std::get_if>( &var->u)}) { // A Selector that parsed as a Variable might turn out during analysis // to actually be a structure constructor. In that case, repair the @@ -3798,7 +3801,7 @@ return Expr{NullPointer{}}; } } - if (const Symbol *symbol{proc.GetSymbol()}) { + if (const Symbol * symbol{proc.GetSymbol()}) { if (!ResolveForward(*symbol)) { return std::nullopt; } @@ -3885,7 +3888,7 @@ // TODO: C1534: Don't allow a "restricted" specific intrinsic to be passed. std::optional actual; common::visit(common::visitors{ - [&](const common::Indirection &x) { + [&](const parser::Indirection &x) { actual = AnalyzeExpr(x.value()); SetArgSourceLocation(actual, x.value().source); }, @@ -4046,7 +4049,7 @@ parser::Messages buffer; auto restorer{context_.GetContextualMessages().SetMessages(buffer)}; const auto &scope{context_.context().FindScope(source_)}; - if (Symbol *symbol{scope.FindSymbol(oprName)}) { + if (Symbol * symbol{scope.FindSymbol(oprName)}) { anyPossibilities = true; parser::Name name{symbol->name(), symbol}; result = context_.AnalyzeDefinedOp(name, GetActuals()); @@ -4063,8 +4066,8 @@ for (std::size_t passIndex{0}; passIndex < actuals_.size(); ++passIndex) { buffer.clear(); const Symbol *generic{nullptr}; - if (const Symbol *binding{ - FindBoundOp(oprName, passIndex, generic, false)}) { + if (const Symbol * + binding{FindBoundOp(oprName, passIndex, generic, false)}) { anyPossibilities = true; if (MaybeExpr thisResult{TryBoundOp(*binding, passIndex)}) { if (auto thisInaccessible{ @@ -4220,14 +4223,14 @@ // diagnosed. { auto restorer{context_.GetContextualMessages().DiscardMessages()}; - if (const Symbol *symbol{scope.FindSymbol(oprName)}) { + if (const Symbol * symbol{scope.FindSymbol(oprName)}) { ExpressionAnalyzer::AdjustActuals noAdjustment; proc = context_.ResolveGeneric(*symbol, actuals_, noAdjustment, true).first; } for (std::size_t i{0}; !proc && i < actuals_.size(); ++i) { const Symbol *generic{nullptr}; - if (const Symbol *binding{FindBoundOp(oprName, i, generic, true)}) { + if (const Symbol * binding{FindBoundOp(oprName, i, generic, true)}) { if (CheckAccessibleSymbol(scope, DEREF(generic))) { // ignore inaccessible type-bound ASSIGNMENT(=) generic } else if (const Symbol * @@ -4271,7 +4274,7 @@ for (const auto &actual : actuals_) { if (!actual.has_value()) { os << "- error\n"; - } else if (const Symbol *symbol{actual->GetAssumedTypeDummy()}) { + } else if (const Symbol * symbol{actual->GetAssumedTypeDummy()}) { os << "- assumed type: " << symbol->name().ToString() << '\n'; } else if (const Expr *expr{actual->UnwrapExpr()}) { expr->AsFortran(os << "- expr: ") << '\n'; @@ -4284,7 +4287,7 @@ std::optional ArgumentAnalyzer::AnalyzeExpr( const parser::Expr &expr) { source_.ExtendToCover(expr.source); - if (const Symbol *assumedTypeDummy{AssumedTypeDummy(expr)}) { + if (const Symbol * assumedTypeDummy{AssumedTypeDummy(expr)}) { ResetExpr(expr); if (isProcedureCall_) { ActualArgument arg{ActualArgument::AssumedType{*assumedTypeDummy}}; @@ -4347,7 +4350,7 @@ }}; auto pair{ context_.ResolveGeneric(*generic, actuals_, adjustment, isSubroutine)}; - if (const Symbol *binding{pair.first}) { + if (const Symbol * binding{pair.first}) { CHECK(binding->has()); // Use the most recent override of the binding, if any return scope->FindComponent(binding->name()); Index: flang/lib/Semantics/mod-file.cpp =================================================================== --- flang/lib/Semantics/mod-file.cpp +++ flang/lib/Semantics/mod-file.cpp @@ -1150,7 +1150,7 @@ const parser::Program &program) { CHECK(program.v.size() == 1); auto &unit{program.v.front()}; - auto &submod{std::get>(unit.u)}; + auto &submod{std::get>(unit.u)}; auto &stmt{ std::get>(submod.value().t)}; auto &parentId{std::get(stmt.statement.t)}; @@ -1185,7 +1185,7 @@ needed = needed || (spec && useSet_.count(*spec) > 0) || (dt && useSet_.count(*dt) > 0); } else if (const auto *subp{ultimate.detailsIf()}) { - const Symbol *interface { subp->moduleInterface() }; + const Symbol *interface{subp->moduleInterface()}; needed = needed || (interface && useSet_.count(*interface) > 0); } if (needed) { @@ -1327,7 +1327,7 @@ return false; } else if (symbol.owner().Contains(scope_)) { return true; - } else if (const Symbol *found{scope_.FindSymbol(name)}) { + } else if (const Symbol * found{scope_.FindSymbol(name)}) { // detect import from ancestor of use-associated symbol return found->has() && found->owner() != scope_; } else { Index: flang/lib/Semantics/program-tree.cpp =================================================================== --- flang/lib/Semantics/program-tree.cpp +++ flang/lib/Semantics/program-tree.cpp @@ -18,7 +18,7 @@ const auto &implicitPart{std::get(spec.t)}; for (const parser::ImplicitPartStmt &stmt : implicitPart.v) { if (const auto *entryStmt{std::get_if< - parser::Statement>>( + parser::Statement>>( &stmt.u)}) { node.AddEntry(entryStmt->statement.value()); } @@ -26,7 +26,7 @@ for (const auto &decl : std::get>(spec.t)) { if (const auto *entryStmt{std::get_if< - parser::Statement>>( + parser::Statement>>( &decl.u)}) { node.AddEntry(entryStmt->statement.value()); } @@ -37,7 +37,7 @@ ProgramTree &node, const parser::ExecutionPart &exec) { for (const auto &epConstruct : exec.v) { if (const auto *entryStmt{std::get_if< - parser::Statement>>( + parser::Statement>>( &epConstruct.u)}) { node.AddEntry(entryStmt->statement.value()); } @@ -53,13 +53,13 @@ if (const auto *spec{ std::get_if(&decl.u)}) { if (const auto *generic{std::get_if< - parser::Statement>>( + parser::Statement>>( &spec->u)}) { const parser::GenericStmt &genericStmt{generic->statement.value()}; const auto &genericSpec{std::get(genericStmt.t)}; node.AddGeneric(genericSpec); } else if (const auto *interface{ - std::get_if>( + std::get_if>( &spec->u)}) { const parser::InterfaceBlock &interfaceBlock{interface->value()}; const parser::InterfaceStmt &interfaceStmt{ Index: flang/lib/Semantics/resolve-labels.cpp =================================================================== --- flang/lib/Semantics/resolve-labels.cpp +++ flang/lib/Semantics/resolve-labels.cpp @@ -58,7 +58,7 @@ // F18:R1131 template constexpr Legality IsLegalDoTerm(const parser::Statement &) { - if (std::is_same_v> || + if (std::is_same_v> || std::is_same_v) { return Legality::always; } else if (std::is_same_v || @@ -78,18 +78,18 @@ // See F08:C816 return Legality::always; } else if (!(std::holds_alternative< - common::Indirection>( + parser::Indirection>( actionStmt.statement.u) || - std::holds_alternative>( + std::holds_alternative>( actionStmt.statement.u) || - std::holds_alternative>( + std::holds_alternative>( actionStmt.statement.u) || - std::holds_alternative>( + std::holds_alternative>( actionStmt.statement.u) || - std::holds_alternative>( + std::holds_alternative>( actionStmt.statement.u) || std::holds_alternative< - common::Indirection>( + parser::Indirection>( actionStmt.statement.u))) { return Legality::formerly; } else { @@ -98,7 +98,7 @@ } template constexpr bool IsFormat(const parser::Statement &) { - return std::is_same_v>; + return std::is_same_v>; } template @@ -112,10 +112,10 @@ std::is_same_v || std::is_same_v || std::is_same_v || - std::is_same_v> || + std::is_same_v> || std::is_same_v || std::is_same_v || - std::is_same_v> || + std::is_same_v> || std::is_same_v || std::is_same_v || std::is_same_v || Index: flang/lib/Semantics/resolve-names-utils.cpp =================================================================== --- flang/lib/Semantics/resolve-names-utils.cpp +++ flang/lib/Semantics/resolve-names-utils.cpp @@ -533,13 +533,13 @@ return common::visit( common::visitors{ [&](const parser::Name &name) { return CheckObject(name); }, - [&](const common::Indirection &) { + [&](const parser::Indirection &) { context_.Say(source, // C8107 "Derived type component '%s' is not allowed in an equivalence set"_err_en_US, source); return false; }, - [&](const common::Indirection &elem) { + [&](const parser::Indirection &elem) { bool ok{CheckDataRef(source, elem.value().base)}; for (const auto &subscript : elem.value().subscripts) { ok &= common::visit( @@ -558,7 +558,7 @@ } return ok; }, - [&](const common::Indirection &) { + [&](const parser::Indirection &) { context_.Say(source, // C924 (R872) "Coindexed object '%s' is not allowed in an equivalence set"_err_en_US, source); @@ -767,7 +767,7 @@ : Base{*this}, scope_{scope}, map_{map} {} using Base::operator(); bool operator()(const SymbolRef &ref) const { - if (const Symbol *mapped{MapSymbol(*ref)}) { + if (const Symbol * mapped{MapSymbol(*ref)}) { const_cast(ref) = *mapped; } return false; @@ -799,8 +799,8 @@ void SymbolMapper::MapSymbolExprs(Symbol &symbol) { if (auto *object{symbol.detailsIf()}) { - if (const DeclTypeSpec *type{object->type()}) { - if (const DeclTypeSpec *newType{MapType(*type)}) { + if (const DeclTypeSpec * type{object->type()}) { + if (const DeclTypeSpec * newType{MapType(*type)}) { object->ReplaceType(*newType); } } @@ -860,7 +860,7 @@ newType = &scope_.MakeCharacterType( std::move(newLen), KindExpr{charType.kind()}); } - } else if (const DerivedTypeSpec *derived{type.AsDerived()}) { + } else if (const DerivedTypeSpec * derived{type.AsDerived()}) { if (!derived->parameters().empty()) { DerivedTypeSpec newDerived{derived->name(), derived->typeSymbol()}; newDerived.CookParameters(scope_.context().foldingContext()); @@ -884,7 +884,7 @@ } const Symbol *SymbolMapper::MapInterface(const Symbol *interface) { - if (const Symbol *mapped{MapSymbol(interface)}) { + if (const Symbol * mapped{MapSymbol(interface)}) { return mapped; } if (interface) { @@ -892,7 +892,7 @@ return interface; } else if (const auto *subp{interface->detailsIf()}; subp && subp->isInterface()) { - if (Symbol *newSymbol{scope_.CopySymbol(*interface)}) { + if (Symbol * newSymbol{scope_.CopySymbol(*interface)}) { newSymbol->get().set_isInterface(true); map_.symbolMap[interface] = newSymbol; Scope &newScope{scope_.MakeScope(Scope::Kind::Subprogram, newSymbol)}; @@ -916,14 +916,14 @@ for (const Symbol *dummyArg : oldDetails.dummyArgs()) { if (!dummyArg) { newDetails.add_alternateReturn(); - } else if (Symbol *copy{newScope.CopySymbol(*dummyArg)}) { + } else if (Symbol * copy{newScope.CopySymbol(*dummyArg)}) { newDetails.add_dummyArg(*copy); mappings->symbolMap[dummyArg] = copy; } } if (oldDetails.isFunction()) { newScope.erase(newSymbol.name()); - if (Symbol *copy{newScope.CopySymbol(oldDetails.result())}) { + if (Symbol * copy{newScope.CopySymbol(oldDetails.result())}) { newDetails.set_result(*copy); mappings->symbolMap[&oldDetails.result()] = copy; } Index: flang/lib/Semantics/resolve-names.cpp =================================================================== --- flang/lib/Semantics/resolve-names.cpp +++ flang/lib/Semantics/resolve-names.cpp @@ -16,7 +16,6 @@ #include "rewrite-parse-tree.h" #include "flang/Common/Fortran.h" #include "flang/Common/default-kinds.h" -#include "flang/Common/indirection.h" #include "flang/Common/restorer.h" #include "flang/Common/visit.h" #include "flang/Evaluate/characteristics.h" @@ -47,7 +46,7 @@ using namespace parser::literals; -template using Indirection = common::Indirection; +template using Indirection = parser::Indirection; using Message = parser::Message; using Messages = parser::Messages; using MessageFixedText = parser::MessageFixedText; @@ -7901,7 +7900,7 @@ currScope().InstantiateDerivedTypes(); for (const auto &decl : decls) { if (const auto *statement{std::get_if< - parser::Statement>>( + parser::Statement>>( &decl.u)}) { AnalyzeStmtFunctionStmt(statement->statement.value()); } @@ -8191,7 +8190,7 @@ } bool ResolveNamesVisitor::Pre(const parser::ProgramUnit &x) { - if (std::holds_alternative>( + if (std::holds_alternative>( x.u)) { // TODO: global directives return true; @@ -8211,7 +8210,7 @@ if constexpr (!std::is_same_v) { const auto &spec{std::get(x.t)}; const auto &unitUses{std::get< - std::list>>>( + std::list>>>( spec.t)}; for (const auto &u : unitUses) { uses.insert(u.statement.value().moduleName.source); @@ -8226,7 +8225,7 @@ bool disordered{false}; for (const auto &progUnit : x.v) { if (const auto *indMod{ - std::get_if>(&progUnit.u)}) { + std::get_if>(&progUnit.u)}) { const parser::Module &mod{indMod->value()}; const auto &moduleStmt{ std::get>(mod.t)}; @@ -8262,7 +8261,7 @@ const SourceName &name{pair.first}; const parser::ProgramUnit &progUnit{*pair.second}; const parser::Module &m{ - std::get>(progUnit.u).value()}; + std::get>(progUnit.u).value()}; ok = true; for (const SourceName &use : GetUses(m)) { if (modules.find(use) != modules.end()) { @@ -8295,7 +8294,7 @@ Walk(*progUnit); } for (const auto &progUnit : x.v) { - if (!std::get_if>(&progUnit.u)) { + if (!std::get_if>(&progUnit.u)) { Walk(progUnit); } } Index: flang/lib/Semantics/rewrite-parse-tree.cpp =================================================================== --- flang/lib/Semantics/rewrite-parse-tree.cpp +++ flang/lib/Semantics/rewrite-parse-tree.cpp @@ -64,7 +64,7 @@ private: using stmtFuncType = - parser::Statement>; + parser::Statement>; bool errorOnUnresolvedName_{true}; parser::Messages &messages_; std::list stmtFuncsToConvert_; Index: flang/lib/Semantics/semantics.cpp =================================================================== --- flang/lib/Semantics/semantics.cpp +++ flang/lib/Semantics/semantics.cpp @@ -508,7 +508,7 @@ // (e.g., __builtin_team_type) are available to semantics, esp. for // intrinsic checking. if (!program_.v.empty()) { - const auto *frontModule{std::get_if>( + const auto *frontModule{std::get_if>( &program_.v.front().u)}; if (frontModule && (std::get>(frontModule->value().t) Index: flang/lib/Semantics/tools.cpp =================================================================== --- flang/lib/Semantics/tools.cpp +++ flang/lib/Semantics/tools.cpp @@ -457,9 +457,7 @@ return common::visit( common::visitors{ [](const ProcEntityDetails &details) { - const Symbol *interface { - details.procInterface() - }; + const Symbol *interface{details.procInterface()}; return interface ? FindInterface(*interface) : nullptr; }, [](const ProcBindingDetails &details) { @@ -904,7 +902,8 @@ template bool operator()(const T &) { return common::HasMember; } - template bool operator()(const common::Indirection &x) { + template + bool operator()(const common::Indirection &x) { return (*this)(x.value()); } template bool operator()(const parser::Statement &x) { @@ -943,7 +942,7 @@ const parser::ActualArg &actualArg{ std::get(args.front().t)}; if (const auto *argExpr{ - std::get_if>( + std::get_if>( &actualArg.u)}) { return HasCoarray(argExpr->value()); } @@ -983,17 +982,17 @@ std::get_if>(&construct.u)}) { return common::visit( common::visitors{ - [](const common::Indirection &) + [](const parser::Indirection &) -> std::optional { return "ALLOCATE of a coarray is an image control" " statement"_en_US; }, - [](const common::Indirection &) + [](const parser::Indirection &) -> std::optional { return "DEALLOCATE of a coarray is an image control" " statement"_en_US; }, - [](const common::Indirection &) + [](const parser::Indirection &) -> std::optional { return "MOVE_ALLOC of a coarray is an image control" " statement "_en_US; @@ -1011,13 +1010,13 @@ const parser::ExecutableConstruct &executableConstruct) { return common::visit( common::visitors{ - [](const common::Indirection + [](const parser::Indirection &construct) { return std::get>( construct.value().t) .source; }, - [](const common::Indirection &construct) { + [](const parser::Indirection &construct) { return std::get>( construct.value().t) .source; Index: flang/tools/f18-parse-demo/stub-evaluate.cpp =================================================================== --- flang/tools/f18-parse-demo/stub-evaluate.cpp +++ flang/tools/f18-parse-demo/stub-evaluate.cpp @@ -9,19 +9,30 @@ // The parse tree has slots in which pointers to the results of semantic // analysis may be placed. When using the parser without the semantics // libraries, as here, we need to stub out the dependences on the external -// deleters, which will never actually be called. +// deleters and copiers, which will never actually be called. namespace Fortran::evaluate { struct GenericExprWrapper { static void Deleter(GenericExprWrapper *); + static GenericExprWrapper *Copier(GenericExprWrapper *); }; void GenericExprWrapper::Deleter(GenericExprWrapper *) {} +GenericExprWrapper *GenericExprWrapper::Copier(GenericExprWrapper *) { + return nullptr; +} struct GenericAssignmentWrapper { static void Deleter(GenericAssignmentWrapper *); + static GenericAssignmentWrapper *Copier(GenericAssignmentWrapper *); }; void GenericAssignmentWrapper::Deleter(GenericAssignmentWrapper *) {} +GenericAssignmentWrapper *GenericAssignmentWrapper::Copier( + GenericAssignmentWrapper *) { + return nullptr; +} struct ProcedureRef { static void Deleter(ProcedureRef *); + static ProcedureRef *Copier(ProcedureRef *); }; void ProcedureRef::Deleter(ProcedureRef *) {} +ProcedureRef *ProcedureRef::Copier(ProcedureRef *) { return nullptr; } } // namespace Fortran::evaluate