FLANG

expression.h
1 //===-- include/flang/Semantics/expression.h --------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef FORTRAN_SEMANTICS_EXPRESSION_H_
10 #define FORTRAN_SEMANTICS_EXPRESSION_H_
11
12 #include "semantics.h"
13 #include "flang/Common/Fortran.h"
14 #include "flang/Common/indirection.h"
15 #include "flang/Evaluate/characteristics.h"
16 #include "flang/Evaluate/check-expression.h"
17 #include "flang/Evaluate/expression.h"
18 #include "flang/Evaluate/fold.h"
19 #include "flang/Evaluate/tools.h"
20 #include "flang/Evaluate/type.h"
21 #include "flang/Parser/char-block.h"
22 #include "flang/Parser/parse-tree-visitor.h"
23 #include "flang/Parser/parse-tree.h"
24 #include "flang/Parser/tools.h"
25 #include <map>
26 #include <optional>
27 #include <type_traits>
28 #include <variant>
29
30 using namespace Fortran::parser::literals;
31
32 namespace Fortran::parser {
33 struct SourceLocationFindingVisitor {
34 template <typename A> bool Pre(const A &x) {
35 if constexpr (HasSource<A>::value) {
36 source.ExtendToCover(x.source);
37 return false;
38 } else {
39 return true;
40 }
41 }
42 template <typename A> void Post(const A &) {}
43 void Post(const CharBlock &at) { source.ExtendToCover(at); }
44
45 CharBlock source;
46 };
47
48 template <typename A> CharBlock FindSourceLocation(const A &x) {
49 SourceLocationFindingVisitor visitor;
50 Walk(x, visitor);
51 return visitor.source;
52 }
53 } // namespace Fortran::parser
54
55 using namespace Fortran::parser::literals;
56
57 // The expression semantic analysis code has its implementation in
58 // namespace Fortran::evaluate, but the exposed API to it is in the
59 // namespace Fortran::semantics (below).
60 //
61 // The ExpressionAnalyzer wraps a SemanticsContext reference
62 // and implements constraint checking on expressions using the
63 // parse tree node wrappers that mirror the grammar annotations used
64 // in the Fortran standard (i.e., scalar-, constant-, &c.).
65
66 namespace Fortran::evaluate {
67
68 class IntrinsicProcTable;
69
70 struct SetExprHelper {
71 explicit SetExprHelper(GenericExprWrapper &&expr) : expr_{std::move(expr)} {}
72 void Set(parser::TypedExpr &x) {
73 x.Reset(new GenericExprWrapper{std::move(expr_)},
74 evaluate::GenericExprWrapper::Deleter);
75 }
76 void Set(const parser::Expr &x) { Set(x.typedExpr); }
77 void Set(const parser::Variable &x) { Set(x.typedExpr); }
78 void Set(const parser::DataStmtConstant &x) { Set(x.typedExpr); }
79 template <typename T> void Set(const common::Indirection<T> &x) {
80 Set(x.value());
81 }
82 template <typename T> void Set(const T &x) {
83 if constexpr (ConstraintTrait<T>) {
84 Set(x.thing);
85 } else if constexpr (WrapperTrait<T>) {
86 Set(x.v);
87 }
88 }
89
90 GenericExprWrapper expr_;
91 };
92
93 template <typename T> void ResetExpr(const T &x) {
94 SetExprHelper{GenericExprWrapper{/* error indicator */}}.Set(x);
95 }
96
97 template <typename T> void SetExpr(const T &x, Expr<SomeType> &&expr) {
98 SetExprHelper{GenericExprWrapper{std::move(expr)}}.Set(x);
99 }
100
101 class ExpressionAnalyzer {
102 public:
103 using MaybeExpr = std::optional<Expr<SomeType>>;
104
105 explicit ExpressionAnalyzer(semantics::SemanticsContext &sc) : context_{sc} {}
106 ExpressionAnalyzer(semantics::SemanticsContext &sc, FoldingContext &fc)
107 : context_{sc}, foldingContext_{fc} {}
108 ExpressionAnalyzer(ExpressionAnalyzer &) = default;
109
110 semantics::SemanticsContext &context() const { return context_; }
111
112 FoldingContext &GetFoldingContext() const { return foldingContext_; }
113
114 parser::ContextualMessages &GetContextualMessages() {
115 return foldingContext_.messages();
116 }
117
118 template <typename... A> parser::Message *Say(A &&... args) {
119 return GetContextualMessages().Say(std::forward<A>(args)...);
120 }
121
122 template <typename T, typename... A>
123 parser::Message *SayAt(const T &parsed, A &&... args) {
124 return Say(parser::FindSourceLocation(parsed), std::forward<A>(args)...);
125 }
126
127 int GetDefaultKind(common::TypeCategory);
128 DynamicType GetDefaultKindOfType(common::TypeCategory);
129
130 // Return false and emit error if these checks fail:
131 bool CheckIntrinsicKind(TypeCategory, std::int64_t kind);
132 bool CheckIntrinsicSize(TypeCategory, std::int64_t size);
133
134 // Manage a set of active implied DO loops.
135 bool AddImpliedDo(parser::CharBlock, int kind);
136 void RemoveImpliedDo(parser::CharBlock);
137
138 // When the argument is the name of an active implied DO index, returns
139 // its INTEGER kind type parameter.
140 std::optional<int> IsImpliedDo(parser::CharBlock) const;
141
142 Expr<SubscriptInteger> AnalyzeKindSelector(common::TypeCategory category,
143 const std::optional<parser::KindSelector> &);
144
145 MaybeExpr Analyze(const parser::Expr &);
146 MaybeExpr Analyze(const parser::Variable &);
147 MaybeExpr Analyze(const parser::Designator &);
148 MaybeExpr Analyze(const parser::DataStmtValue &);
149
150 template <typename A> MaybeExpr Analyze(const common::Indirection<A> &x) {
151 return Analyze(x.value());
152 }
153 template <typename A> MaybeExpr Analyze(const std::optional<A> &x) {
154 if (x) {
155 return Analyze(*x);
156 } else {
157 return std::nullopt;
158 }
159 }
160
161 // Implement constraint-checking wrappers from the Fortran grammar.
162 template <typename A> MaybeExpr Analyze(const parser::Scalar<A> &x) {
163 auto result{Analyze(x.thing)};
164 if (result) {
165 if (int rank{result->Rank()}; rank != 0) {
166 SayAt(x, "Must be a scalar value, but is a rank-%d array"_err_en_US,
167 rank);
168 ResetExpr(x);
169 return std::nullopt;
170 }
171 }
172 return result;
173 }
174 template <typename A> MaybeExpr Analyze(const parser::Constant<A> &x) {
175 auto restorer{
176 GetFoldingContext().messages().SetLocation(FindSourceLocation(x))};
177 auto result{Analyze(x.thing)};
178 if (result) {
179 *result = Fold(std::move(*result));
180 if (!IsConstantExpr(*result)) { // C886, C887, C713
181 SayAt(x, "Must be a constant value"_err_en_US);
182 ResetExpr(x);
183 return std::nullopt;
184 } else {
185 // Save folded expression for later use
186 SetExpr(x, common::Clone(*result));
187 }
188 }
189 return result;
190 }
191 template <typename A> MaybeExpr Analyze(const parser::Integer<A> &x) {
192 auto result{Analyze(x.thing)};
193 if (!EnforceTypeConstraint(
194 parser::FindSourceLocation(x), result, TypeCategory::Integer)) {
195 ResetExpr(x);
196 return std::nullopt;
197 }
198 return result;
199 }
200 template <typename A> MaybeExpr Analyze(const parser::Logical<A> &x) {
201 auto result{Analyze(x.thing)};
202 if (!EnforceTypeConstraint(
203 parser::FindSourceLocation(x), result, TypeCategory::Logical)) {
204 ResetExpr(x);
205 return std::nullopt;
206 }
207 return result;
208 }
209 template <typename A> MaybeExpr Analyze(const parser::DefaultChar<A> &x) {
210 auto result{Analyze(x.thing)};
211 if (!EnforceTypeConstraint(parser::FindSourceLocation(x), result,
212 TypeCategory::Character, true /* default kind */)) {
213 ResetExpr(x);
214 return std::nullopt;
215 }
216 return result;
217 }
218
219 MaybeExpr Analyze(const parser::Name &);
220 MaybeExpr Analyze(const parser::DataRef &dr) {
221 return Analyze<parser::DataRef>(dr);
222 }
223 MaybeExpr Analyze(const parser::StructureComponent &);
224 MaybeExpr Analyze(const parser::SignedIntLiteralConstant &);
225 MaybeExpr Analyze(const parser::SignedRealLiteralConstant &);
226 MaybeExpr Analyze(const parser::SignedComplexLiteralConstant &);
227 MaybeExpr Analyze(const parser::StructureConstructor &);
228 MaybeExpr Analyze(const parser::InitialDataTarget &);
229
230 void Analyze(const parser::CallStmt &);
231 const Assignment *Analyze(const parser::AssignmentStmt &);
232 const Assignment *Analyze(const parser::PointerAssignmentStmt &);
233
234 protected:
235 int IntegerTypeSpecKind(const parser::IntegerTypeSpec &);
236
237 private:
238 MaybeExpr Analyze(const parser::IntLiteralConstant &);
239 MaybeExpr Analyze(const parser::RealLiteralConstant &);
240 MaybeExpr Analyze(const parser::ComplexPart &);
241 MaybeExpr Analyze(const parser::ComplexLiteralConstant &);
242 MaybeExpr Analyze(const parser::LogicalLiteralConstant &);
243 MaybeExpr Analyze(const parser::CharLiteralConstant &);
244 MaybeExpr Analyze(const parser::HollerithLiteralConstant &);
245 MaybeExpr Analyze(const parser::BOZLiteralConstant &);
246 MaybeExpr Analyze(const parser::NamedConstant &);
247 MaybeExpr Analyze(const parser::NullInit &);
248 MaybeExpr Analyze(const parser::DataStmtConstant &);
249 MaybeExpr Analyze(const parser::Substring &);
250 MaybeExpr Analyze(const parser::ArrayElement &);
251 MaybeExpr Analyze(const parser::CoindexedNamedObject &);
252 MaybeExpr Analyze(const parser::CharLiteralConstantSubstring &);
253 MaybeExpr Analyze(const parser::ArrayConstructor &);
254 MaybeExpr Analyze(const parser::FunctionReference &,
255 std::optional<parser::StructureConstructor> * = nullptr);
256 MaybeExpr Analyze(const parser::Expr::Parentheses &);
257 MaybeExpr Analyze(const parser::Expr::UnaryPlus &);
258 MaybeExpr Analyze(const parser::Expr::Negate &);
259 MaybeExpr Analyze(const parser::Expr::NOT &);
260 MaybeExpr Analyze(const parser::Expr::PercentLoc &);
261 MaybeExpr Analyze(const parser::Expr::DefinedUnary &);
262 MaybeExpr Analyze(const parser::Expr::Power &);
263 MaybeExpr Analyze(const parser::Expr::Multiply &);
264 MaybeExpr Analyze(const parser::Expr::Divide &);
265 MaybeExpr Analyze(const parser::Expr::Add &);
266 MaybeExpr Analyze(const parser::Expr::Subtract &);
267 MaybeExpr Analyze(const parser::Expr::ComplexConstructor &);
268 MaybeExpr Analyze(const parser::Expr::Concat &);
269 MaybeExpr Analyze(const parser::Expr::LT &);
270 MaybeExpr Analyze(const parser::Expr::LE &);
271 MaybeExpr Analyze(const parser::Expr::EQ &);
272 MaybeExpr Analyze(const parser::Expr::NE &);
273 MaybeExpr Analyze(const parser::Expr::GE &);
274 MaybeExpr Analyze(const parser::Expr::GT &);
275 MaybeExpr Analyze(const parser::Expr::AND &);
276 MaybeExpr Analyze(const parser::Expr::OR &);
277 MaybeExpr Analyze(const parser::Expr::EQV &);
278 MaybeExpr Analyze(const parser::Expr::NEQV &);
279 MaybeExpr Analyze(const parser::Expr::DefinedBinary &);
280 template <typename A> MaybeExpr Analyze(const A &x) {
281 return Analyze(x.u); // default case
282 }
283 template <typename... As> MaybeExpr Analyze(const std::variant<As...> &u) {
284 return std::visit(
285 [&](const auto &x) {
286 using Ty = std::decay_t<decltype(x)>;
287 // Function references might turn out to be misparsed structure
288 // constructors; we have to try generic procedure resolution
289 // first to be sure.
290 if constexpr (common::IsTypeInList<parser::StructureConstructor,
291 As...>) {
292 std::optional<parser::StructureConstructor> ctor;
293 MaybeExpr result;
294 if constexpr (std::is_same_v<Ty,
295 common::Indirection<parser::FunctionReference>>) {
296 result = Analyze(x.value(), &ctor);
297 } else if constexpr (std::is_same_v<Ty,
298 parser::FunctionReference>) {
299 result = Analyze(x, &ctor);
300 } else {
301 return Analyze(x);
302 }
303 if (ctor) {
304 // A misparsed function reference is really a structure
305 // constructor. Repair the parse tree in situ.
306 const_cast<std::variant<As...> &>(u) = std::move(*ctor);
307 }
308 return result;
309 }
310 return Analyze(x);
311 },
312 u);
313 }
314
315 // Analysis subroutines
316 int AnalyzeKindParam(
317 const std::optional<parser::KindParam> &, int defaultKind);
318 template <typename PARSED> MaybeExpr ExprOrVariable(const PARSED &);
319 template <typename PARSED> MaybeExpr IntLiteralConstant(const PARSED &);
320 MaybeExpr AnalyzeString(std::string &&, int kind);
321 std::optional<Expr<SubscriptInteger>> AsSubscript(MaybeExpr &&);
322 std::optional<Expr<SubscriptInteger>> TripletPart(
323 const std::optional<parser::Subscript> &);
324 std::optional<Subscript> AnalyzeSectionSubscript(
325 const parser::SectionSubscript &);
326 std::vector<Subscript> AnalyzeSectionSubscripts(
327 const std::list<parser::SectionSubscript> &);
328 MaybeExpr Designate(DataRef &&);
329 MaybeExpr CompleteSubscripts(ArrayRef &&);
330 MaybeExpr ApplySubscripts(DataRef &&, std::vector<Subscript> &&);
331 MaybeExpr TopLevelChecks(DataRef &&);
332 std::optional<Expr<SubscriptInteger>> GetSubstringBound(
333 const std::optional<parser::ScalarIntExpr> &);
334 MaybeExpr AnalyzeDefinedOp(const parser::Name &, ActualArguments &&);
335
336 struct CalleeAndArguments {
337 // A non-component function reference may constitute a misparsed
338 // structure constructor, in which case its derived type's Symbol
339 // will appear here.
340 std::variant<ProcedureDesignator, SymbolRef> u;
341 ActualArguments arguments;
342 };
343
344 std::optional<CalleeAndArguments> AnalyzeProcedureComponentRef(
345 const parser::ProcComponentRef &, ActualArguments &&);
346 std::optional<characteristics::Procedure> CheckCall(
347 parser::CharBlock, const ProcedureDesignator &, ActualArguments &);
348 using AdjustActuals =
349 std::optional<std::function<bool(const Symbol &, ActualArguments &)>>;
350 bool ResolveForward(const Symbol &);
351 const Symbol *ResolveGeneric(const Symbol &, const ActualArguments &,
352 const AdjustActuals &, bool mightBeStructureConstructor = false);
353 void EmitGenericResolutionError(const Symbol &);
354 std::optional<CalleeAndArguments> GetCalleeAndArguments(const parser::Name &,
355 ActualArguments &&, bool isSubroutine = false,
356 bool mightBeStructureConstructor = false);
357 std::optional<CalleeAndArguments> GetCalleeAndArguments(
358 const parser::ProcedureDesignator &, ActualArguments &&,
359 bool isSubroutine, bool mightBeStructureConstructor = false);
360
361 void CheckForBadRecursion(parser::CharBlock, const semantics::Symbol &);
362 bool EnforceTypeConstraint(parser::CharBlock, const MaybeExpr &, TypeCategory,
363 bool defaultKind = false);
364 MaybeExpr MakeFunctionRef(
365 parser::CharBlock, ProcedureDesignator &&, ActualArguments &&);
366 MaybeExpr MakeFunctionRef(parser::CharBlock intrinsic, ActualArguments &&);
367 template <typename T> T Fold(T &&expr) {
368 return evaluate::Fold(foldingContext_, std::move(expr));
369 }
370
371 semantics::SemanticsContext &context_;
372 FoldingContext &foldingContext_{context_.foldingContext()};
373 std::map<parser::CharBlock, int> impliedDos_; // values are INTEGER kinds
374 bool fatalErrors_{false};
375 friend class ArgumentAnalyzer;
376 };
377
378 inline bool AreConformable(int leftRank, int rightRank) {
379 return leftRank == 0 || rightRank == 0 || leftRank == rightRank;
380 }
381
382 template <typename L, typename R>
383 bool AreConformable(const L &left, const R &right) {
384 return AreConformable(left.Rank(), right.Rank());
385 }
386
387 template <typename L, typename R>
388 void ConformabilityCheck(
389 parser::ContextualMessages &context, const L &left, const R &right) {
390 if (!AreConformable(left, right)) {
391 context.Say("left operand has rank %d, right operand has rank %d"_err_en_US,
392 left.Rank(), right.Rank());
393 }
394 }
395 } // namespace Fortran::evaluate
396
397 namespace Fortran::semantics {
398
399 // Semantic analysis of one expression, variable, or designator.
400 template <typename A>
401 std::optional<evaluate::Expr<evaluate::SomeType>> AnalyzeExpr(
402 SemanticsContext &context, const A &expr) {
403 return evaluate::ExpressionAnalyzer{context}.Analyze(expr);
404 }
405
406 // Semantic analysis of an intrinsic type's KIND parameter expression.
407 evaluate::Expr<evaluate::SubscriptInteger> AnalyzeKindSelector(
408 SemanticsContext &, common::TypeCategory,
409 const std::optional<parser::KindSelector> &);
410
411 void AnalyzeCallStmt(SemanticsContext &, const parser::CallStmt &);
412 const evaluate::Assignment *AnalyzeAssignmentStmt(
413 SemanticsContext &, const parser::AssignmentStmt &);
414 const evaluate::Assignment *AnalyzePointerAssignmentStmt(
415 SemanticsContext &, const parser::PointerAssignmentStmt &);
416
417 // Semantic analysis of all expressions in a parse tree, which becomes
418 // decorated with typed representations for top-level expressions.
419 class ExprChecker {
420 public:
421 explicit ExprChecker(SemanticsContext &);
422
423 template <typename A> bool Pre(const A &) { return true; }
424 template <typename A> void Post(const A &) {}
425 bool Walk(const parser::Program &);
426
427 bool Pre(const parser::Expr &x) {
428 exprAnalyzer_.Analyze(x);
429 return false;
430 }
431 bool Pre(const parser::Variable &x) {
432 exprAnalyzer_.Analyze(x);
433 return false;
434 }
435 bool Pre(const parser::DataStmtValue &x) {
436 exprAnalyzer_.Analyze(x);
437 return false;
438 }
439 bool Pre(const parser::DataImpliedDo &);
440
441 bool Pre(const parser::CallStmt &x) {
442 AnalyzeCallStmt(context_, x);
443 return false;
444 }
445 bool Pre(const parser::AssignmentStmt &x) {
446 AnalyzeAssignmentStmt(context_, x);
447 return false;
448 }
449 bool Pre(const parser::PointerAssignmentStmt &x) {
450 AnalyzePointerAssignmentStmt(context_, x);
451 return false;
452 }
453
454 template <typename A> bool Pre(const parser::Scalar<A> &x) {
455 exprAnalyzer_.Analyze(x);
456 return false;
457 }
458 template <typename A> bool Pre(const parser::Constant<A> &x) {
459 exprAnalyzer_.Analyze(x);
460 return false;
461 }
462 template <typename A> bool Pre(const parser::Integer<A> &x) {
463 exprAnalyzer_.Analyze(x);
464 return false;
465 }
466 template <typename A> bool Pre(const parser::Logical<A> &x) {
467 exprAnalyzer_.Analyze(x);
468 return false;
469 }
470 template <typename A> bool Pre(const parser::DefaultChar<A> &x) {
471 exprAnalyzer_.Analyze(x);
472 return false;
473 }
474
475 private:
476 SemanticsContext &context_;
477 evaluate::ExpressionAnalyzer exprAnalyzer_{context_};
478 };
479 } // namespace Fortran::semantics
480 #endif // FORTRAN_SEMANTICS_EXPRESSION_H_
Fortran::parser::SourceLocationFindingVisitor
Definition: expression.h:33
Fortran::evaluate::GenericExprWrapper
Definition: expression.h:839
Fortran::parser::ComplexPart
Definition: parse-tree.h:797
Fortran::parser::Expr::ComplexConstructor
Definition: parse-tree.h:1702
Fortran::evaluate::SetExprHelper
Definition: expression.h:70
Fortran::common::ForwardOwningPointer< evaluate::GenericExprWrapper >
Fortran::parser::HollerithLiteralConstant
Definition: parse-tree.h:826
Fortran::parser::DataStmtValue
Definition: parse-tree.h:1432
Fortran::parser::FunctionReference
Definition: parse-tree.h:3138
Fortran::semantics::SemanticsContext
Definition: semantics.h:60
Fortran::parser::ContextualMessages
Definition: message.h:271
Fortran::semantics::ExprChecker
Definition: expression.h:419
Fortran::parser::StructureConstructor
Definition: parse-tree.h:1162
Fortran::parser::Integer
Definition: parse-tree.h:297
Fortran::parser::HasSource
Definition: tools.h:106
Fortran::evaluate::DynamicType
Definition: type.h:85
Fortran::parser::ArrayElement
Definition: parse-tree.h:1826
Fortran::parser::Expr::Negate
Definition: parse-tree.h:1634
Fortran::semantics::Symbol
Definition: symbol.h:479
Fortran::parser::Expr::DefinedUnary
Definition: parse-tree.h:1643
Fortran::parser::Logical
Definition: parse-tree.h:305
Fortran::evaluate::DataRef
Definition: variable.h:286
Fortran::parser::Expr::Add
Definition: parse-tree.h:1661
Fortran::evaluate::ArrayRef
Definition: variable.h:196
Fortran::evaluate::FoldingContext
Definition: common.h:209
Fortran::parser::Substring
Definition: parse-tree.h:1759
Fortran::parser::Expr::Multiply
Definition: parse-tree.h:1655
Fortran::parser::Expr::Subtract
Definition: parse-tree.h:1664
Fortran::parser::Message
Definition: message.h:141
Fortran::parser::CoindexedNamedObject
Definition: parse-tree.h:1817
Fortran::parser::Expr::NOT
Definition: parse-tree.h:1637
Fortran::parser::Variable
Definition: parse-tree.h:1780
Fortran::evaluate::ProcedureDesignator
Definition: call.h:159
Fortran::parser::Expr::Concat
Definition: parse-tree.h:1667
Fortran::parser::Scalar
Definition: parse-tree.h:281
Fortran::parser::Expr::EQ
Definition: parse-tree.h:1676
Fortran::parser::Expr::LT
Definition: parse-tree.h:1670
Fortran::parser::Name
Definition: parse-tree.h:555
Fortran::parser::Expr::UnaryPlus
Definition: parse-tree.h:1631
Fortran::parser::SignedIntLiteralConstant
Definition: parse-tree.h:752
Fortran::common::Indirection
Definition: indirection.h:31
Fortran::parser::DataStmtConstant
Definition: parse-tree.h:1411
Fortran::parser::ProcedureDesignator
Definition: parse-tree.h:3105
Fortran::parser::IntLiteralConstant
Definition: parse-tree.h:759
Fortran::parser::Constant
Definition: parse-tree.h:289
Fortran::parser::SectionSubscript
Definition: parse-tree.h:1595
Fortran::evaluate::Assignment
Definition: expression.h:821
Fortran::parser::CharBlock
Definition: char-block.h:28
Fortran::evaluate::ArgumentAnalyzer
Definition: expression.cpp:98
Fortran::parser::RealLiteralConstant
Definition: parse-tree.h:772
Fortran::parser::ComplexLiteralConstant
Definition: parse-tree.h:805
Fortran::parser::Expr::AND
Definition: parse-tree.h:1688
Fortran::parser::SignedRealLiteralConstant
Definition: parse-tree.h:786
Fortran::evaluate::ExpressionAnalyzer
Definition: expression.h:101
Fortran::parser::LogicalLiteralConstant
Definition: parse-tree.h:833
Fortran::parser::Expr::NE
Definition: parse-tree.h:1679
Fortran::parser::Expr::Divide
Definition: parse-tree.h:1658
Fortran::parser::CallStmt
Definition: parse-tree.h:3146
Fortran::parser::CharLiteralConstant
Definition: parse-tree.h:819
Fortran::parser::Expr::Power
Definition: parse-tree.h:1652
Fortran::parser::DataRef
Definition: parse-tree.h:1742
Fortran::parser::Expr::NEQV
Definition: parse-tree.h:1697
Fortran::parser::Expr::GE
Definition: parse-tree.h:1682
Fortran::parser::Expr
Definition: parse-tree.h:1624
Fortran::parser::Expr::LE
Definition: parse-tree.h:1673
Fortran::parser
Definition: check-expression.h:19
Fortran::evaluate::Expr
Definition: common.h:207
Fortran::parser::CharLiteralConstantSubstring
Definition: parse-tree.h:1764
Fortran::parser::Expr::GT
Definition: parse-tree.h:1685
Fortran::parser::SignedComplexLiteralConstant
Definition: parse-tree.h:811
Fortran::parser::ProcComponentRef
Definition: parse-tree.h:1812
Fortran::parser::DataImpliedDo
Definition: parse-tree.h:1452
Fortran::parser::StructureComponent
Definition: parse-tree.h:1802
Fortran::parser::DefaultChar
Definition: parse-tree.h:313
Fortran::parser::AssignmentStmt
Definition: parse-tree.h:1925
Fortran::parser::Expr::Parentheses
Definition: parse-tree.h:1628
Fortran::parser::Expr::EQV
Definition: parse-tree.h:1694
Fortran::parser::Expr::OR
Definition: parse-tree.h:1691
Fortran::parser::PointerAssignmentStmt
Definition: parse-tree.h:1949
Fortran::parser::Designator
Definition: parse-tree.h:1772
Fortran::parser::Expr::DefinedBinary
Definition: parse-tree.h:1706