[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.
This commit is contained in:
parent
7a22bea512
commit
568b8e4873
@ -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)
|
||||
|
||||
@ -296,20 +296,6 @@ struct ParseTreeVisitorLookupScope {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename V> static void Walk(const AcSpec &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.type, visitor);
|
||||
Walk(x.values, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template <typename M> static void Walk(AcSpec &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.type, mutator);
|
||||
Walk(x.values, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template <typename V> static void Walk(const ArrayElement &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.base, visitor);
|
||||
@ -325,37 +311,6 @@ struct ParseTreeVisitorLookupScope {
|
||||
}
|
||||
}
|
||||
template <typename V>
|
||||
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 <typename M>
|
||||
static void Walk(CharSelector::LengthAndKind &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.length, mutator);
|
||||
Walk(x.kind, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template <typename V>
|
||||
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 <typename M> static void Walk(CaseValueRange::Range &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.lower, mutator);
|
||||
Walk(x.upper, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template <typename V>
|
||||
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 <typename V>
|
||||
static void Walk(const DeclarationTypeSpec::Class &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.derived, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template <typename M>
|
||||
static void Walk(DeclarationTypeSpec::Class &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.derived, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template <typename V>
|
||||
static void Walk(const DeclarationTypeSpec::Type &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.derived, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template <typename M>
|
||||
static void Walk(DeclarationTypeSpec::Type &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.derived, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template <typename V> static void Walk(const ImportStmt &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.names, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template <typename M> static void Walk(ImportStmt &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.names, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template <typename V>
|
||||
static void Walk(const IntrinsicTypeSpec::Character &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.selector, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template <typename M>
|
||||
static void Walk(IntrinsicTypeSpec::Character &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.selector, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template <typename V>
|
||||
static void Walk(const IntrinsicTypeSpec::Complex &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.kind, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template <typename M>
|
||||
static void Walk(IntrinsicTypeSpec::Complex &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.kind, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template <typename V>
|
||||
static void Walk(const IntrinsicTypeSpec::Logical &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.kind, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template <typename M>
|
||||
static void Walk(IntrinsicTypeSpec::Logical &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.kind, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template <typename V>
|
||||
static void Walk(const IntrinsicTypeSpec::Real &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.kind, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template <typename M>
|
||||
static void Walk(IntrinsicTypeSpec::Real &x, M &mutator) {
|
||||
if (mutator.Pre(x)) {
|
||||
Walk(x.kind, mutator);
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template <typename A, typename B, typename V>
|
||||
static void Walk(const LoopBounds<A, B> &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
@ -486,18 +345,6 @@ struct ParseTreeVisitorLookupScope {
|
||||
mutator.Post(x);
|
||||
}
|
||||
}
|
||||
template <typename V> static void Walk(const CommonStmt &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.blocks, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template <typename M> 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.
|
||||
|
||||
@ -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<Name> &&n) : names(std::move(n)) {}
|
||||
TUPLE_CLASS_BOILERPLATE(ImportStmt);
|
||||
ImportStmt(common::ImportKind &&k) : t(k, std::list<Name>{}) {}
|
||||
ImportStmt(std::list<Name> &&n)
|
||||
: t(common::ImportKind::Default, std::move(n)) {}
|
||||
ImportStmt(common::ImportKind &&, std::list<Name> &&);
|
||||
common::ImportKind kind{common::ImportKind::Default};
|
||||
std::list<Name> names;
|
||||
std::tuple<common::ImportKind, std::list<Name>> t;
|
||||
};
|
||||
|
||||
// R868 namelist-stmt ->
|
||||
@ -686,11 +686,8 @@ struct LengthSelector {
|
||||
struct CharSelector {
|
||||
UNION_CLASS_BOILERPLATE(CharSelector);
|
||||
struct LengthAndKind {
|
||||
BOILERPLATE(LengthAndKind);
|
||||
LengthAndKind(std::optional<TypeParamValue> &&l, ScalarIntConstantExpr &&k)
|
||||
: length(std::move(l)), kind(std::move(k)) {}
|
||||
std::optional<TypeParamValue> length;
|
||||
ScalarIntConstantExpr kind;
|
||||
TUPLE_CLASS_BOILERPLATE(LengthAndKind);
|
||||
std::tuple<std::optional<TypeParamValue>, 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<KindSelector> &&k) : kind{std::move(k)} {}
|
||||
std::optional<KindSelector> kind;
|
||||
WRAPPER_CLASS_BOILERPLATE(Real, std::optional<KindSelector>);
|
||||
};
|
||||
EMPTY_CLASS(DoublePrecision);
|
||||
struct Complex {
|
||||
BOILERPLATE(Complex);
|
||||
Complex(std::optional<KindSelector> &&k) : kind{std::move(k)} {}
|
||||
std::optional<KindSelector> kind;
|
||||
WRAPPER_CLASS_BOILERPLATE(Complex, std::optional<KindSelector>);
|
||||
};
|
||||
struct Character {
|
||||
BOILERPLATE(Character);
|
||||
Character(std::optional<CharSelector> &&s) : selector{std::move(s)} {}
|
||||
std::optional<CharSelector> selector;
|
||||
WRAPPER_CLASS_BOILERPLATE(Character, std::optional<CharSelector>);
|
||||
};
|
||||
struct Logical {
|
||||
BOILERPLATE(Logical);
|
||||
Logical(std::optional<KindSelector> &&k) : kind{std::move(k)} {}
|
||||
std::optional<KindSelector> kind;
|
||||
WRAPPER_CLASS_BOILERPLATE(Logical, std::optional<KindSelector>);
|
||||
};
|
||||
EMPTY_CLASS(DoubleComplex);
|
||||
std::variant<IntegerTypeSpec, UnsignedTypeSpec, Real, DoublePrecision,
|
||||
@ -774,16 +763,8 @@ struct TypeSpec {
|
||||
// Legacy extension: RECORD /struct/
|
||||
struct DeclarationTypeSpec {
|
||||
UNION_CLASS_BOILERPLATE(DeclarationTypeSpec);
|
||||
struct Type {
|
||||
BOILERPLATE(Type);
|
||||
Type(DerivedTypeSpec &&dt) : derived(std::move(dt)) {}
|
||||
DerivedTypeSpec derived;
|
||||
};
|
||||
struct Class {
|
||||
BOILERPLATE(Class);
|
||||
Class(DerivedTypeSpec &&dt) : derived(std::move(dt)) {}
|
||||
DerivedTypeSpec derived;
|
||||
};
|
||||
WRAPPER_CLASS(Type, DerivedTypeSpec);
|
||||
WRAPPER_CLASS(Class, DerivedTypeSpec);
|
||||
EMPTY_CLASS(ClassStar);
|
||||
EMPTY_CLASS(TypeStar);
|
||||
WRAPPER_CLASS(Record, Name);
|
||||
@ -1274,12 +1255,9 @@ struct AcValue {
|
||||
|
||||
// R770 ac-spec -> type-spec :: | [type-spec ::] ac-value-list
|
||||
struct AcSpec {
|
||||
BOILERPLATE(AcSpec);
|
||||
AcSpec(std::optional<TypeSpec> &&ts, std::list<AcValue> &&xs)
|
||||
: type(std::move(ts)), values(std::move(xs)) {}
|
||||
explicit AcSpec(TypeSpec &&ts) : type{std::move(ts)} {}
|
||||
std::optional<TypeSpec> type;
|
||||
std::list<AcValue> values;
|
||||
TUPLE_CLASS_BOILERPLATE(AcSpec);
|
||||
explicit AcSpec(TypeSpec &&ts) : t(std::move(ts), std::list<AcValue>()) {}
|
||||
std::tuple<std::optional<TypeSpec>, std::list<AcValue>> t;
|
||||
};
|
||||
|
||||
// R769 array-constructor -> (/ ac-spec /) | lbracket ac-spec rbracket
|
||||
@ -1646,11 +1624,10 @@ struct CommonStmt {
|
||||
TUPLE_CLASS_BOILERPLATE(Block);
|
||||
std::tuple<std::optional<Name>, std::list<CommonBlockObject>> t;
|
||||
};
|
||||
BOILERPLATE(CommonStmt);
|
||||
WRAPPER_CLASS_BOILERPLATE(CommonStmt, std::list<Block>);
|
||||
CommonStmt(std::optional<Name> &&, std::list<CommonBlockObject> &&,
|
||||
std::list<Block> &&);
|
||||
CharBlock source;
|
||||
std::list<Block> blocks;
|
||||
};
|
||||
|
||||
// R872 equivalence-object -> variable-name | array-element | substring
|
||||
@ -2416,10 +2393,9 @@ using CaseValue = Scalar<ConstantExpr>;
|
||||
struct CaseValueRange {
|
||||
UNION_CLASS_BOILERPLATE(CaseValueRange);
|
||||
struct Range {
|
||||
BOILERPLATE(Range);
|
||||
Range(std::optional<CaseValue> &&l, std::optional<CaseValue> &&u)
|
||||
: lower{std::move(l)}, upper{std::move(u)} {}
|
||||
std::optional<CaseValue> lower, upper; // not both missing
|
||||
TUPLE_CLASS_BOILERPLATE(Range);
|
||||
std::tuple<std::optional<CaseValue>, std::optional<CaseValue>>
|
||||
t; // not both missing
|
||||
};
|
||||
std::variant<CaseValue, Range> u;
|
||||
};
|
||||
|
||||
@ -4011,16 +4011,17 @@ private:
|
||||
}
|
||||
const auto &caseRange =
|
||||
std::get<Fortran::parser::CaseValueRange::Range>(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,8 @@ namespace Fortran::parser {
|
||||
|
||||
// R867
|
||||
ImportStmt::ImportStmt(common::ImportKind &&k, std::list<Name> &&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<Name> &&n)
|
||||
// R873
|
||||
CommonStmt::CommonStmt(std::optional<Name> &&name,
|
||||
std::list<CommonBlockObject> &&objects, std::list<Block> &&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
|
||||
|
||||
@ -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<ScalarIntConstantExpr>(x.t));
|
||||
Walk(", LEN=", std::get<std::optional<TypeParamValue>>(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<std::optional<TypeSpec>>(x.t), "::");
|
||||
Walk(std::get<std::list<AcValue>>(x.t), ", ");
|
||||
}
|
||||
template <typename A, typename B> void Unparse(const LoopBounds<A, B> &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<Name>(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), ": ");
|
||||
|
||||
@ -117,26 +117,27 @@ private:
|
||||
|
||||
using PairOfValues = std::pair<std::optional<Value>, std::optional<Value>>;
|
||||
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<Value> 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<Value> 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);
|
||||
}
|
||||
|
||||
|
||||
@ -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()) {
|
||||
|
||||
@ -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<std::int64_t> 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::ConstantSubscript>(
|
||||
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<parser::Name>(type.derived.t)};
|
||||
const parser::Name &derivedName{std::get<parser::Name>(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<parser::Name>(parsedClass.derived.t)};
|
||||
const auto &typeName{std::get<parser::Name>(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) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user