From 568b8e4873b2d04be7ab302246c8e3986ea61176 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 8 Jan 2026 18:26:48 -0600 Subject: [PATCH] [flang] Add traits to several AST nodes (#175065) There are quite a few AST nodes that don't have any of the standard traits (Wrapper/Tuple/etc). Because of that they require special handling in the parse tree visitor. Convert a subset of these nodes to the typical format, and remove the special cases from the parse tree visitor. --- flang/include/flang/Parser/dump-parse-tree.h | 1 + .../include/flang/Parser/parse-tree-visitor.h | 153 ------------------ flang/include/flang/Parser/parse-tree.h | 64 +++----- flang/lib/Lower/Bridge.cpp | 13 +- flang/lib/Parser/parse-tree.cpp | 7 +- flang/lib/Parser/unparse.cpp | 26 +-- flang/lib/Semantics/check-case.cpp | 41 ++--- flang/lib/Semantics/expression.cpp | 5 +- flang/lib/Semantics/resolve-names.cpp | 43 ++--- 9 files changed, 95 insertions(+), 258 deletions(-) diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index 466cec900303..f6e4cce241ad 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -64,6 +64,7 @@ public: NODE(std, uint64_t) NODE_ENUM(common, CUDADataAttr) NODE_ENUM(common, CUDASubprogramAttrs) + NODE_ENUM(common, ImportKind) NODE_ENUM(common, OmpDependenceKind) NODE_ENUM(common, OmpMemoryOrderType) NODE_ENUM(common, OpenACCDeviceType) diff --git a/flang/include/flang/Parser/parse-tree-visitor.h b/flang/include/flang/Parser/parse-tree-visitor.h index 7ebce671c5fd..67f5481144c5 100644 --- a/flang/include/flang/Parser/parse-tree-visitor.h +++ b/flang/include/flang/Parser/parse-tree-visitor.h @@ -296,20 +296,6 @@ struct ParseTreeVisitorLookupScope { } } - template static void Walk(const AcSpec &x, V &visitor) { - if (visitor.Pre(x)) { - Walk(x.type, visitor); - Walk(x.values, visitor); - visitor.Post(x); - } - } - template static void Walk(AcSpec &x, M &mutator) { - if (mutator.Pre(x)) { - Walk(x.type, mutator); - Walk(x.values, mutator); - mutator.Post(x); - } - } template static void Walk(const ArrayElement &x, V &visitor) { if (visitor.Pre(x)) { Walk(x.base, visitor); @@ -325,37 +311,6 @@ struct ParseTreeVisitorLookupScope { } } template - static void Walk(const CharSelector::LengthAndKind &x, V &visitor) { - if (visitor.Pre(x)) { - Walk(x.length, visitor); - Walk(x.kind, visitor); - visitor.Post(x); - } - } - template - static void Walk(CharSelector::LengthAndKind &x, M &mutator) { - if (mutator.Pre(x)) { - Walk(x.length, mutator); - Walk(x.kind, mutator); - mutator.Post(x); - } - } - template - static void Walk(const CaseValueRange::Range &x, V &visitor) { - if (visitor.Pre(x)) { - Walk(x.lower, visitor); - Walk(x.upper, visitor); - visitor.Post(x); - } - } - template static void Walk(CaseValueRange::Range &x, M &mutator) { - if (mutator.Pre(x)) { - Walk(x.lower, mutator); - Walk(x.upper, mutator); - mutator.Post(x); - } - } - template static void Walk(const CoindexedNamedObject &x, V &visitor) { if (visitor.Pre(x)) { Walk(x.base, visitor); @@ -370,102 +325,6 @@ struct ParseTreeVisitorLookupScope { mutator.Post(x); } } - template - static void Walk(const DeclarationTypeSpec::Class &x, V &visitor) { - if (visitor.Pre(x)) { - Walk(x.derived, visitor); - visitor.Post(x); - } - } - template - static void Walk(DeclarationTypeSpec::Class &x, M &mutator) { - if (mutator.Pre(x)) { - Walk(x.derived, mutator); - mutator.Post(x); - } - } - template - static void Walk(const DeclarationTypeSpec::Type &x, V &visitor) { - if (visitor.Pre(x)) { - Walk(x.derived, visitor); - visitor.Post(x); - } - } - template - static void Walk(DeclarationTypeSpec::Type &x, M &mutator) { - if (mutator.Pre(x)) { - Walk(x.derived, mutator); - mutator.Post(x); - } - } - template static void Walk(const ImportStmt &x, V &visitor) { - if (visitor.Pre(x)) { - Walk(x.names, visitor); - visitor.Post(x); - } - } - template static void Walk(ImportStmt &x, M &mutator) { - if (mutator.Pre(x)) { - Walk(x.names, mutator); - mutator.Post(x); - } - } - template - static void Walk(const IntrinsicTypeSpec::Character &x, V &visitor) { - if (visitor.Pre(x)) { - Walk(x.selector, visitor); - visitor.Post(x); - } - } - template - static void Walk(IntrinsicTypeSpec::Character &x, M &mutator) { - if (mutator.Pre(x)) { - Walk(x.selector, mutator); - mutator.Post(x); - } - } - template - static void Walk(const IntrinsicTypeSpec::Complex &x, V &visitor) { - if (visitor.Pre(x)) { - Walk(x.kind, visitor); - visitor.Post(x); - } - } - template - static void Walk(IntrinsicTypeSpec::Complex &x, M &mutator) { - if (mutator.Pre(x)) { - Walk(x.kind, mutator); - mutator.Post(x); - } - } - template - static void Walk(const IntrinsicTypeSpec::Logical &x, V &visitor) { - if (visitor.Pre(x)) { - Walk(x.kind, visitor); - visitor.Post(x); - } - } - template - static void Walk(IntrinsicTypeSpec::Logical &x, M &mutator) { - if (mutator.Pre(x)) { - Walk(x.kind, mutator); - mutator.Post(x); - } - } - template - static void Walk(const IntrinsicTypeSpec::Real &x, V &visitor) { - if (visitor.Pre(x)) { - Walk(x.kind, visitor); - visitor.Post(x); - } - } - template - static void Walk(IntrinsicTypeSpec::Real &x, M &mutator) { - if (mutator.Pre(x)) { - Walk(x.kind, mutator); - mutator.Post(x); - } - } template static void Walk(const LoopBounds &x, V &visitor) { if (visitor.Pre(x)) { @@ -486,18 +345,6 @@ struct ParseTreeVisitorLookupScope { mutator.Post(x); } } - template static void Walk(const CommonStmt &x, V &visitor) { - if (visitor.Pre(x)) { - Walk(x.blocks, visitor); - visitor.Post(x); - } - } - template static void Walk(CommonStmt &x, M &mutator) { - if (mutator.Pre(x)) { - Walk(x.blocks, mutator); - mutator.Post(x); - } - } // Expr traversal uses iteration rather than recursion to avoid // blowing out the stack on very deep expression parse trees. diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 2ab640ed351d..37c0f699361e 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -623,12 +623,12 @@ using ObjectName = Name; // IMPORT [[::] import-name-list] | // IMPORT , ONLY : import-name-list | IMPORT , NONE | IMPORT , ALL struct ImportStmt { - BOILERPLATE(ImportStmt); - ImportStmt(common::ImportKind &&k) : kind{k} {} - ImportStmt(std::list &&n) : names(std::move(n)) {} + TUPLE_CLASS_BOILERPLATE(ImportStmt); + ImportStmt(common::ImportKind &&k) : t(k, std::list{}) {} + ImportStmt(std::list &&n) + : t(common::ImportKind::Default, std::move(n)) {} ImportStmt(common::ImportKind &&, std::list &&); - common::ImportKind kind{common::ImportKind::Default}; - std::list names; + std::tuple> t; }; // R868 namelist-stmt -> @@ -686,11 +686,8 @@ struct LengthSelector { struct CharSelector { UNION_CLASS_BOILERPLATE(CharSelector); struct LengthAndKind { - BOILERPLATE(LengthAndKind); - LengthAndKind(std::optional &&l, ScalarIntConstantExpr &&k) - : length(std::move(l)), kind(std::move(k)) {} - std::optional length; - ScalarIntConstantExpr kind; + TUPLE_CLASS_BOILERPLATE(LengthAndKind); + std::tuple, ScalarIntConstantExpr> t; }; CharSelector(TypeParamValue &&l, ScalarIntConstantExpr &&k) : u{LengthAndKind{std::make_optional(std::move(l)), std::move(k)}} {} @@ -707,25 +704,17 @@ struct CharSelector { struct IntrinsicTypeSpec { UNION_CLASS_BOILERPLATE(IntrinsicTypeSpec); struct Real { - BOILERPLATE(Real); - Real(std::optional &&k) : kind{std::move(k)} {} - std::optional kind; + WRAPPER_CLASS_BOILERPLATE(Real, std::optional); }; EMPTY_CLASS(DoublePrecision); struct Complex { - BOILERPLATE(Complex); - Complex(std::optional &&k) : kind{std::move(k)} {} - std::optional kind; + WRAPPER_CLASS_BOILERPLATE(Complex, std::optional); }; struct Character { - BOILERPLATE(Character); - Character(std::optional &&s) : selector{std::move(s)} {} - std::optional selector; + WRAPPER_CLASS_BOILERPLATE(Character, std::optional); }; struct Logical { - BOILERPLATE(Logical); - Logical(std::optional &&k) : kind{std::move(k)} {} - std::optional kind; + WRAPPER_CLASS_BOILERPLATE(Logical, std::optional); }; EMPTY_CLASS(DoubleComplex); std::variant type-spec :: | [type-spec ::] ac-value-list struct AcSpec { - BOILERPLATE(AcSpec); - AcSpec(std::optional &&ts, std::list &&xs) - : type(std::move(ts)), values(std::move(xs)) {} - explicit AcSpec(TypeSpec &&ts) : type{std::move(ts)} {} - std::optional type; - std::list values; + TUPLE_CLASS_BOILERPLATE(AcSpec); + explicit AcSpec(TypeSpec &&ts) : t(std::move(ts), std::list()) {} + std::tuple, std::list> t; }; // R769 array-constructor -> (/ ac-spec /) | lbracket ac-spec rbracket @@ -1646,11 +1624,10 @@ struct CommonStmt { TUPLE_CLASS_BOILERPLATE(Block); std::tuple, std::list> t; }; - BOILERPLATE(CommonStmt); + WRAPPER_CLASS_BOILERPLATE(CommonStmt, std::list); CommonStmt(std::optional &&, std::list &&, std::list &&); CharBlock source; - std::list blocks; }; // R872 equivalence-object -> variable-name | array-element | substring @@ -2416,10 +2393,9 @@ using CaseValue = Scalar; struct CaseValueRange { UNION_CLASS_BOILERPLATE(CaseValueRange); struct Range { - BOILERPLATE(Range); - Range(std::optional &&l, std::optional &&u) - : lower{std::move(l)}, upper{std::move(u)} {} - std::optional lower, upper; // not both missing + TUPLE_CLASS_BOILERPLATE(Range); + std::tuple, std::optional> + t; // not both missing }; std::variant u; }; diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index 6c3631438a59..9224bc2be102 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -4011,16 +4011,17 @@ private: } const auto &caseRange = std::get(caseValueRange.u); - if (caseRange.lower && caseRange.upper) { + const auto &[lower, upper]{caseRange.t}; + if (lower && upper) { attrList.push_back(fir::ClosedIntervalAttr::get(context)); - addValue(*caseRange.lower); - addValue(*caseRange.upper); - } else if (caseRange.lower) { + addValue(*lower); + addValue(*upper); + } else if (lower) { attrList.push_back(fir::LowerBoundAttr::get(context)); - addValue(*caseRange.lower); + addValue(*lower); } else { attrList.push_back(fir::UpperBoundAttr::get(context)); - addValue(*caseRange.upper); + addValue(*upper); } } } diff --git a/flang/lib/Parser/parse-tree.cpp b/flang/lib/Parser/parse-tree.cpp index 53d4e4e680ca..dae1912afa99 100644 --- a/flang/lib/Parser/parse-tree.cpp +++ b/flang/lib/Parser/parse-tree.cpp @@ -22,7 +22,8 @@ namespace Fortran::parser { // R867 ImportStmt::ImportStmt(common::ImportKind &&k, std::list &&n) - : kind{k}, names(std::move(n)) { + : t(k, std::move(n)) { + const auto &[kind, names]{t}; CHECK(kind == common::ImportKind::Default || kind == common::ImportKind::Only || names.empty()); } @@ -30,8 +31,8 @@ ImportStmt::ImportStmt(common::ImportKind &&k, std::list &&n) // R873 CommonStmt::CommonStmt(std::optional &&name, std::list &&objects, std::list &&others) { - blocks.emplace_front(std::move(name), std::move(objects)); - blocks.splice(blocks.end(), std::move(others)); + v.emplace_front(std::move(name), std::move(objects)); + v.splice(v.end(), std::move(others)); } // R901 designator diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 0a6b0cdf88ef..9b31454537df 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -142,10 +142,10 @@ public: void Post(const Star &) { Put('*'); } // R701 &c. void Post(const TypeParamValue::Deferred &) { Put(':'); } // R701 void Unparse(const DeclarationTypeSpec::Type &x) { // R703 - Word("TYPE("), Walk(x.derived), Put(')'); + Word("TYPE("), Walk(x.v), Put(')'); } void Unparse(const DeclarationTypeSpec::Class &x) { - Word("CLASS("), Walk(x.derived), Put(')'); + Word("CLASS("), Walk(x.v), Put(')'); } void Post(const DeclarationTypeSpec::ClassStar &) { Word("CLASS(*)"); } void Post(const DeclarationTypeSpec::TypeStar &) { Word("TYPE(*)"); } @@ -204,8 +204,11 @@ public: Put('('), Walk(x.t, ","), Put(')'); } void Unparse(const CharSelector::LengthAndKind &x) { // R721 - Put('('), Word("KIND="), Walk(x.kind); - Walk(", LEN=", x.length), Put(')'); + Put('('); + Word("KIND="); + Walk(std::get(x.t)); + Walk(", LEN=", std::get>(x.t)); + Put(')'); } void Unparse(const LengthSelector &x) { // R722 common::visit(common::visitors{ @@ -430,7 +433,8 @@ public: Put('['), Walk(x.v), Put(']'); } void Unparse(const AcSpec &x) { // R770 - Walk(x.type, "::"), Walk(x.values, ", "); + Walk(std::get>(x.t), "::"); + Walk(std::get>(x.t), ", "); } template void Unparse(const LoopBounds &x) { Walk(x.name), Put('='), Walk(x.lower), Put(','), Walk(x.upper); @@ -723,14 +727,15 @@ public: } } void Unparse(const ImportStmt &x) { // R867 + const auto &[kind, names]{x.t}; Word("IMPORT"); - switch (x.kind) { + switch (kind) { case common::ImportKind::Default: - Walk(" :: ", x.names, ", "); + Walk(" :: ", names, ", "); break; case common::ImportKind::Only: Put(", "), Word("ONLY: "); - Walk(x.names, ", "); + Walk(names, ", "); break; case common::ImportKind::None: Word(", NONE"); @@ -757,7 +762,7 @@ public: } void Unparse(const CommonStmt &x) { // R873 Word("COMMON "); - Walk(x.blocks); + Walk(x.v); } void Unparse(const CommonBlockObject &x) { // R874 Walk(std::get(x.t)); @@ -1103,7 +1108,8 @@ public: x.u); } void Unparse(const CaseValueRange::Range &x) { // R1146 - Walk(x.lower), Put(':'), Walk(x.upper); + const auto &[lower, upper]{x.t}; + Walk(lower), Put(':'), Walk(upper); } void Unparse(const SelectRankStmt &x) { // R1149 Walk(std::get<0>(x.t), ": "); diff --git a/flang/lib/Semantics/check-case.cpp b/flang/lib/Semantics/check-case.cpp index 7593154b84c4..9004d8b3a28f 100644 --- a/flang/lib/Semantics/check-case.cpp +++ b/flang/lib/Semantics/check-case.cpp @@ -117,26 +117,27 @@ private: using PairOfValues = std::pair, std::optional>; PairOfValues ComputeBounds(const parser::CaseValueRange &range) { - return common::visit( - common::visitors{ - [&](const parser::CaseValue &x) { - auto value{GetValue(x)}; - return PairOfValues{value, value}; - }, - [&](const parser::CaseValueRange::Range &x) { - std::optional lo, hi; - if (x.lower) { - lo = GetValue(*x.lower); - } - if (x.upper) { - hi = GetValue(*x.upper); - } - if ((x.lower && !lo) || (x.upper && !hi)) { - return PairOfValues{}; // error case - } - return PairOfValues{std::move(lo), std::move(hi)}; - }, - }, + return common::visit(common::visitors{ + [&](const parser::CaseValue &x) { + auto value{GetValue(x)}; + return PairOfValues{value, value}; + }, + [&](const parser::CaseValueRange::Range &x) { + const auto &[lower, upper]{x.t}; + std::optional lo, hi; + if (lower) { + lo = GetValue(*lower); + } + if (upper) { + hi = GetValue(*upper); + } + if ((lower && !lo) || (upper && !hi)) { + return PairOfValues{}; // error case + } + return PairOfValues{ + std::move(lo), std::move(hi)}; + }, + }, range.u); } diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp index 6e301e6ba752..b3643e0d35d5 100644 --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -2076,10 +2076,11 @@ MaybeExpr ArrayConstructorContext::ToExpr() { MaybeExpr ExpressionAnalyzer::Analyze(const parser::ArrayConstructor &array) { const parser::AcSpec &acSpec{array.v}; + const auto &[type, values]{acSpec.t}; bool hadAnyFatalError{context_.AnyFatalError()}; ArrayConstructorContext acContext{ - *this, AnalyzeTypeSpec(acSpec.type, GetFoldingContext())}; - for (const parser::AcValue &value : acSpec.values) { + *this, AnalyzeTypeSpec(type, GetFoldingContext())}; + for (const parser::AcValue &value : values) { acContext.Add(value); } if (!hadAnyFatalError && context_.AnyFatalError()) { diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index ae251476ed59..8086e43b90f2 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -6138,14 +6138,14 @@ void DeclarationVisitor::Post(const parser::UnsignedTypeSpec &x) { } void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Real &x) { if (!isVectorType_) { - SetDeclTypeSpec(MakeNumericType(TypeCategory::Real, x.kind)); + SetDeclTypeSpec(MakeNumericType(TypeCategory::Real, x.v)); } } void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Complex &x) { - SetDeclTypeSpec(MakeNumericType(TypeCategory::Complex, x.kind)); + SetDeclTypeSpec(MakeNumericType(TypeCategory::Complex, x.v)); } void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Logical &x) { - SetDeclTypeSpec(MakeLogicalType(x.kind)); + SetDeclTypeSpec(MakeLogicalType(x.v)); } void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Character &) { if (!charInfo_.length) { @@ -6160,7 +6160,8 @@ void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Character &) { charInfo_ = {}; } void DeclarationVisitor::Post(const parser::CharSelector::LengthAndKind &x) { - charInfo_.kind = EvaluateSubscriptIntExpr(x.kind); + const auto &[length, kind]{x.t}; + charInfo_.kind = EvaluateSubscriptIntExpr(kind); std::optional intKind{ToInt64(charInfo_.kind)}; if (intKind && !context().targetCharacteristics().IsTypeEnabled( @@ -6169,8 +6170,8 @@ void DeclarationVisitor::Post(const parser::CharSelector::LengthAndKind &x) { "KIND value (%jd) not valid for CHARACTER"_err_en_US, *intKind); charInfo_.kind = std::nullopt; // prevent further errors } - if (x.length) { - charInfo_.length = GetParamValue(*x.length, common::TypeParamAttr::Len); + if (length) { + charInfo_.length = GetParamValue(*length, common::TypeParamAttr::Len); } } void DeclarationVisitor::Post(const parser::CharLength &x) { @@ -6245,7 +6246,7 @@ void DeclarationVisitor::Post(const parser::VectorTypeSpec &x) { }, [&](const parser::IntrinsicTypeSpec::Real &z) { vecElemKind = GetVectorElementKind( - TypeCategory::Real, std::move(z.kind)); + TypeCategory::Real, std::move(z.v)); typeParams.push_back( ParamValue(static_cast( common::VectorElementCategory::Real), @@ -6321,7 +6322,7 @@ bool DeclarationVisitor::Pre(const parser::DeclarationTypeSpec::Type &) { } void DeclarationVisitor::Post(const parser::DeclarationTypeSpec::Type &type) { - const parser::Name &derivedName{std::get(type.derived.t)}; + const parser::Name &derivedName{std::get(type.v.t)}; if (const Symbol * derivedSymbol{derivedName.symbol}) { CheckForAbstractType(*derivedSymbol); // C706 } @@ -6334,7 +6335,7 @@ bool DeclarationVisitor::Pre(const parser::DeclarationTypeSpec::Class &) { void DeclarationVisitor::Post( const parser::DeclarationTypeSpec::Class &parsedClass) { - const auto &typeName{std::get(parsedClass.derived.t)}; + const auto &typeName{std::get(parsedClass.v.t)}; if (auto spec{ResolveDerivedType(typeName)}; spec && !IsExtensibleType(&*spec)) { // C705 SayWithDecl(typeName, *typeName.symbol, @@ -7893,8 +7894,9 @@ bool ConstructVisitor::Pre(const parser::LocalitySpec::Shared &x) { } bool ConstructVisitor::Pre(const parser::AcSpec &x) { - ProcessTypeSpec(x.type); - Walk(x.values); + const auto &[type, values]{x.t}; + ProcessTypeSpec(type); + Walk(values); return false; } @@ -8492,12 +8494,12 @@ public: return true; } void Post(const parser::ImportStmt &x) { - if (x.kind == common::ImportKind::None || - x.kind == common::ImportKind::Only) { + const auto &[kind, names]{x.t}; + if (kind == common::ImportKind::None || kind == common::ImportKind::Only) { if (!nestedScopes_.front().importOnly.has_value()) { nestedScopes_.front().importOnly.emplace(); } - for (const auto &name : x.names) { + for (const auto &name : names) { nestedScopes_.front().importOnly->emplace(name.source); } } else { @@ -8709,6 +8711,7 @@ bool ResolveNamesVisitor::Pre(const parser::CallStmt &x) { } bool ResolveNamesVisitor::Pre(const parser::ImportStmt &x) { + const auto &[kind, names]{x.t}; auto &scope{currScope()}; // Check C896 and C899: where IMPORT statements are allowed switch (scope.kind()) { @@ -8716,7 +8719,7 @@ bool ResolveNamesVisitor::Pre(const parser::ImportStmt &x) { if (scope.IsModule()) { Say("IMPORT is not allowed in a module scoping unit"_err_en_US); return false; - } else if (x.kind == common::ImportKind::None) { + } else if (kind == common::ImportKind::None) { Say("IMPORT,NONE is not allowed in a submodule scoping unit"_err_en_US); return false; } @@ -8735,10 +8738,10 @@ bool ResolveNamesVisitor::Pre(const parser::ImportStmt &x) { return false; default:; } - if (auto error{scope.SetImportKind(x.kind)}) { + if (auto error{scope.SetImportKind(kind)}) { Say(std::move(*error)); } - for (auto &name : x.names) { + for (auto &name : names) { if (Symbol * outer{FindSymbol(scope.parent(), name)}) { scope.add_importName(name.source); if (Symbol * symbol{FindInScope(name)}) { @@ -9613,10 +9616,10 @@ void ResolveNamesVisitor::HandleDerivedTypesInImplicitStmts( if (const auto *dtSpec{common::visit( common::visitors{ [](const parser::DeclarationTypeSpec::Type &x) { - return &x.derived; + return &x.v; }, [](const parser::DeclarationTypeSpec::Class &x) { - return &x.derived; + return &x.v; }, [](const auto &) -> const parser::DerivedTypeSpec * { return nullptr; @@ -9783,7 +9786,7 @@ void ResolveNamesVisitor::EarlyDummyTypeDeclaration( void ResolveNamesVisitor::CreateCommonBlockSymbols( const parser::CommonStmt &commonStmt) { - for (const parser::CommonStmt::Block &block : commonStmt.blocks) { + for (const parser::CommonStmt::Block &block : commonStmt.v) { const auto &[name, objects] = block.t; Symbol &commonBlock{MakeCommonBlockSymbol(name, commonStmt.source)}; for (const auto &object : objects) {