annotate flang/lib/Semantics/check-data.cpp @ 207:2e18cbf3894f

LLVM12
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 08 Jun 2021 06:07:14 +0900
parents 0572611fdcc8
children c4bab56944e8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 //===-- lib/Semantics/check-data.cpp --------------------------------------===//
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 //
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 //
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
8
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
9 // DATA statement semantic analysis.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
10 // - Applies static semantic checks to the variables in each data-stmt-set with
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
11 // class DataVarChecker;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
12 // - Invokes conversion of DATA statement values to static initializers
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
13
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 #include "check-data.h"
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
15 #include "data-to-inits.h"
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 #include "flang/Evaluate/traverse.h"
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
17 #include "flang/Parser/parse-tree.h"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
18 #include "flang/Parser/tools.h"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
19 #include "flang/Semantics/tools.h"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
20 #include <algorithm>
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
21 #include <vector>
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
22
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 namespace Fortran::semantics {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
24
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 // Ensures that references to an implied DO loop control variable are
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 // represented as such in the "body" of the implied DO loop.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 void DataChecker::Enter(const parser::DataImpliedDo &x) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 auto name{std::get<parser::DataImpliedDo::Bounds>(x.t).name.thing.thing};
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 int kind{evaluate::ResultType<evaluate::ImpliedDoIndex>::kind};
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 if (const auto dynamicType{evaluate::DynamicType::From(*name.symbol)}) {
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
31 if (dynamicType->category() == TypeCategory::Integer) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
32 kind = dynamicType->kind();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
33 }
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 exprAnalyzer_.AddImpliedDo(name.source, kind);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
37
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 void DataChecker::Leave(const parser::DataImpliedDo &x) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 auto name{std::get<parser::DataImpliedDo::Bounds>(x.t).name.thing.thing};
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 exprAnalyzer_.RemoveImpliedDo(name.source);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
42
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
43 // DataVarChecker applies static checks once to each variable that appears
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
44 // in a data-stmt-set. These checks are independent of the values that
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
45 // correspond to the variables.
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 class DataVarChecker : public evaluate::AllTraverse<DataVarChecker, true> {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 public:
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 using Base = evaluate::AllTraverse<DataVarChecker, true>;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 DataVarChecker(SemanticsContext &c, parser::CharBlock src)
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 : Base{*this}, context_{c}, source_{src} {}
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 using Base::operator();
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 bool HasComponentWithoutSubscripts() const {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 return hasComponent_ && !hasSubscript_;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 }
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
55 bool operator()(const Symbol &symbol) { // C876
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
56 // 8.6.7p(2) - precludes non-pointers of derived types with
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
57 // default component values
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
58 const Scope &scope{context_.FindScope(source_)};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
59 bool isFirstSymbol{isFirstSymbol_};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
60 isFirstSymbol_ = false;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
61 if (const char *whyNot{IsAutomatic(symbol) ? "Automatic variable"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
62 : IsDummy(symbol) ? "Dummy argument"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
63 : IsFunctionResult(symbol) ? "Function result"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
64 : IsAllocatable(symbol) ? "Allocatable"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
65 : IsInitialized(symbol, true) ? "Default-initialized"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
66 : IsInBlankCommon(symbol) ? "Blank COMMON object"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
67 : IsProcedure(symbol) && !IsPointer(symbol) ? "Procedure"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
68 // remaining checks don't apply to components
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
69 : !isFirstSymbol ? nullptr
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
70 : IsHostAssociated(symbol, scope) ? "Host-associated object"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
71 : IsUseAssociated(symbol, scope) ? "USE-associated object"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
72 : symbol.has<AssocEntityDetails>() ? "Construct association"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
73 : nullptr}) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
74 context_.Say(source_,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
75 "%s '%s' must not be initialized in a DATA statement"_err_en_US,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
76 whyNot, symbol.name());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
77 return false;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
78 } else if (IsProcedurePointer(symbol)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
79 context_.Say(source_,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
80 "Procedure pointer '%s' in a DATA statement is not standard"_en_US,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
81 symbol.name());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
82 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
83 return true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
84 }
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 bool operator()(const evaluate::Component &component) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 hasComponent_ = true;
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
87 const Symbol &lastSymbol{component.GetLastSymbol()};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
88 if (isPointerAllowed_) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
89 if (IsPointer(lastSymbol) && hasSubscript_) { // C877
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
90 context_.Say(source_,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
91 "Rightmost data object pointer '%s' must not be subscripted"_err_en_US,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
92 lastSymbol.name().ToString());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
93 return false;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
94 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
95 RestrictPointer();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
96 } else {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
97 if (IsPointer(lastSymbol)) { // C877
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
98 context_.Say(source_,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
99 "Data object must not contain pointer '%s' as a non-rightmost part"_err_en_US,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
100 lastSymbol.name().ToString());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
101 return false;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
102 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
103 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
104 return (*this)(component.base()) && (*this)(lastSymbol);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
105 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
106 bool operator()(const evaluate::ArrayRef &arrayRef) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
107 hasSubscript_ = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
108 return (*this)(arrayRef.base()) && (*this)(arrayRef.subscript());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
109 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
110 bool operator()(const evaluate::Substring &substring) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
111 hasSubscript_ = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
112 return (*this)(substring.parent()) && (*this)(substring.lower()) &&
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
113 (*this)(substring.upper());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
114 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
115 bool operator()(const evaluate::CoarrayRef &) { // C874
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
116 context_.Say(
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
117 source_, "Data object must not be a coindexed variable"_err_en_US);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
118 return false;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 bool operator()(const evaluate::Subscript &subs) {
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
121 DataVarChecker subscriptChecker{context_, source_};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
122 subscriptChecker.RestrictPointer();
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 return std::visit(
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
124 common::visitors{
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
125 [&](const evaluate::IndirectSubscriptIntegerExpr &expr) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
126 return CheckSubscriptExpr(expr);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
127 },
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
128 [&](const evaluate::Triplet &triplet) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
129 return CheckSubscriptExpr(triplet.lower()) &&
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
130 CheckSubscriptExpr(triplet.upper()) &&
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
131 CheckSubscriptExpr(triplet.stride());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
132 },
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
133 },
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
134 subs.u) &&
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
135 subscriptChecker(subs.u);
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
137 template <typename T>
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 bool operator()(const evaluate::FunctionRef<T> &) const { // C875
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 context_.Say(source_,
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 "Data object variable must not be a function reference"_err_en_US);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
141 return false;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
142 }
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
143 void RestrictPointer() { isPointerAllowed_ = false; }
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
144
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 private:
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
146 bool CheckSubscriptExpr(
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
147 const std::optional<evaluate::IndirectSubscriptIntegerExpr> &x) const {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 return !x || CheckSubscriptExpr(*x);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
149 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 bool CheckSubscriptExpr(
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 const evaluate::IndirectSubscriptIntegerExpr &expr) const {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
152 return CheckSubscriptExpr(expr.value());
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
153 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
154 bool CheckSubscriptExpr(
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 const evaluate::Expr<evaluate::SubscriptInteger> &expr) const {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
156 if (!evaluate::IsConstantExpr(expr)) { // C875,C881
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
157 context_.Say(
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
158 source_, "Data object must have constant subscripts"_err_en_US);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
159 return false;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
160 } else {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
161 return true;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
162 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
163 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
164
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
165 SemanticsContext &context_;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
166 parser::CharBlock source_;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
167 bool hasComponent_{false};
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
168 bool hasSubscript_{false};
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
169 bool isPointerAllowed_{true};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
170 bool isFirstSymbol_{true};
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
171 };
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
172
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
173 void DataChecker::Leave(const parser::DataIDoObject &object) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
174 if (const auto *designator{
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
175 std::get_if<parser::Scalar<common::Indirection<parser::Designator>>>(
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
176 &object.u)}) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
177 if (MaybeExpr expr{exprAnalyzer_.Analyze(*designator)}) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
178 auto source{designator->thing.value().source};
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
179 if (evaluate::IsConstantExpr(*expr)) { // C878,C879
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
180 exprAnalyzer_.context().Say(
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
181 source, "Data implied do object must be a variable"_err_en_US);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
182 } else {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
183 DataVarChecker checker{exprAnalyzer_.context(), source};
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
184 if (checker(*expr)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
185 if (checker.HasComponentWithoutSubscripts()) { // C880
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
186 exprAnalyzer_.context().Say(source,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
187 "Data implied do structure component must be subscripted"_err_en_US);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
188 } else {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
189 return;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
190 }
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
191 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
192 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
193 }
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
194 currentSetHasFatalErrors_ = true;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
196 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
197
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
198 void DataChecker::Leave(const parser::DataStmtObject &dataObject) {
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
199 std::visit(common::visitors{
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
200 [](const parser::DataImpliedDo &) { // has own Enter()/Leave()
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
201 },
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
202 [&](const auto &var) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
203 auto expr{exprAnalyzer_.Analyze(var)};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
204 if (!expr ||
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
205 !DataVarChecker{exprAnalyzer_.context(),
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
206 parser::FindSourceLocation(dataObject)}(*expr)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
207 currentSetHasFatalErrors_ = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
208 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
209 },
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
210 },
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
211 dataObject.u);
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
212 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
213
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
214 void DataChecker::Leave(const parser::DataStmtSet &set) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
215 if (!currentSetHasFatalErrors_) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
216 AccumulateDataInitializations(inits_, exprAnalyzer_, set);
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
217 }
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
218 currentSetHasFatalErrors_ = false;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
219 }
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
220
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
221 void DataChecker::CompileDataInitializationsIntoInitializers() {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
222 ConvertToInitializers(inits_, exprAnalyzer_);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
223 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
224
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
225 } // namespace Fortran::semantics