FLANG
resolve-names-utils.h
1//===-- lib/Semantics/resolve-names-utils.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_RESOLVE_NAMES_UTILS_H_
10#define FORTRAN_SEMANTICS_RESOLVE_NAMES_UTILS_H_
11
12// Utility functions and class for use in resolve-names.cpp.
13
14#include "flang/Evaluate/fold.h"
15#include "flang/Parser/message.h"
16#include "flang/Parser/tools.h"
17#include "flang/Semantics/expression.h"
18#include "flang/Semantics/scope.h"
19#include "flang/Semantics/semantics.h"
20#include "flang/Semantics/symbol.h"
21#include "flang/Semantics/type.h"
22#include "llvm/Support/raw_ostream.h"
23#include <forward_list>
24
25namespace Fortran::parser {
26class CharBlock;
27struct ArraySpec;
28struct CoarraySpec;
29struct ComponentArraySpec;
30struct DataRef;
31struct DefinedOpName;
32struct Designator;
33struct Expr;
34struct GenericSpec;
35struct Name;
36} // namespace Fortran::parser
37
38namespace Fortran::semantics {
39
40using SourceName = parser::CharBlock;
41class SemanticsContext;
42
43// Record that a Name has been resolved to a Symbol
44Symbol &Resolve(const parser::Name &, Symbol &);
45Symbol *Resolve(const parser::Name &, Symbol *);
46
47// Create a copy of msg with a new severity.
48parser::MessageFixedText WithSeverity(
49 const parser::MessageFixedText &msg, parser::Severity);
50
51bool IsIntrinsicOperator(const SemanticsContext &, const SourceName &);
52bool IsLogicalConstant(const SemanticsContext &, const SourceName &);
53
54template <typename T>
55MaybeIntExpr EvaluateIntExpr(SemanticsContext &context, const T &expr) {
56 if (MaybeExpr maybeExpr{
57 Fold(context.foldingContext(), AnalyzeExpr(context, expr))}) {
58 if (auto *intExpr{evaluate::UnwrapExpr<SomeIntExpr>(*maybeExpr)}) {
59 return std::move(*intExpr);
60 }
61 }
62 return std::nullopt;
63}
64
65template <typename T>
66std::optional<std::int64_t> EvaluateInt64(
67 SemanticsContext &context, const T &expr) {
68 return evaluate::ToInt64(EvaluateIntExpr(context, expr));
69}
70
71// Analyze a generic-spec and generate a symbol name and GenericKind for it.
73public:
74 explicit GenericSpecInfo(const parser::DefinedOpName &x) { Analyze(x); }
75 explicit GenericSpecInfo(const parser::GenericSpec &x) { Analyze(x); }
76
77 GenericKind kind() const { return kind_; }
78 const SourceName &symbolName() const { return symbolName_.value(); }
79 // Set the GenericKind in this symbol and resolve the corresponding
80 // name if there is one
81 void Resolve(Symbol *) const;
82 friend llvm::raw_ostream &operator<<(
83 llvm::raw_ostream &, const GenericSpecInfo &);
84
85private:
86 void Analyze(const parser::DefinedOpName &);
87 void Analyze(const parser::GenericSpec &);
88
89 GenericKind kind_;
90 const parser::Name *parseName_{nullptr};
91 std::optional<SourceName> symbolName_;
92};
93
94// Analyze a parser::ArraySpec or parser::CoarraySpec
95ArraySpec AnalyzeArraySpec(SemanticsContext &, const parser::ArraySpec &);
96ArraySpec AnalyzeArraySpec(
98ArraySpec AnalyzeDeferredShapeSpecList(
99 SemanticsContext &, const parser::DeferredShapeSpecList &);
100ArraySpec AnalyzeCoarraySpec(
101 SemanticsContext &context, const parser::CoarraySpec &);
102
103// Perform consistency checks on equivalence sets
105public:
106 EquivalenceSets(SemanticsContext &context) : context_{context} {}
107 std::vector<EquivalenceSet> &sets() { return sets_; };
108 // Resolve this designator and add to the current equivalence set
109 void AddToSet(const parser::Designator &);
110 // Finish the current equivalence set: determine if it overlaps
111 // with any of the others and perform necessary merges if it does.
112 void FinishSet(const parser::CharBlock &);
113
114private:
115 bool CheckCanEquivalence(
116 const parser::CharBlock &, const Symbol &, const Symbol &);
117 void MergeInto(const parser::CharBlock &, EquivalenceSet &, std::size_t);
118 const EquivalenceObject *Find(const EquivalenceSet &, const Symbol &);
119 bool CheckDesignator(const parser::Designator &);
120 bool CheckDataRef(const parser::CharBlock &, const parser::DataRef &);
121 bool CheckObject(const parser::Name &);
122 bool CheckArrayBound(const parser::Expr &);
123 bool CheckSubstringBound(const parser::Expr &, bool);
124 bool IsCharacterSequenceType(const DeclTypeSpec *);
125 bool IsDefaultKindNumericType(const IntrinsicTypeSpec &);
126 bool IsDefaultNumericSequenceType(const DeclTypeSpec *);
127 static bool IsAnyNumericSequenceType(const DeclTypeSpec *);
128 static bool IsSequenceType(
129 const DeclTypeSpec *, std::function<bool(const IntrinsicTypeSpec &)>);
130
131 SemanticsContext &context_;
132 std::vector<EquivalenceSet> sets_; // all equivalence sets in this scope
133 // Map object to index of set it is in
134 std::map<EquivalenceObject, std::size_t> objectToSet_;
135 EquivalenceSet currSet_; // equivalence set currently being constructed
136 struct {
137 Symbol *symbol{nullptr};
138 std::vector<ConstantSubscript> subscripts;
139 std::optional<ConstantSubscript> substringStart;
140 } currObject_; // equivalence object currently being constructed
141};
142
143// Duplicates a subprogram's dummy arguments and result, if any, and
144// maps all of the symbols in their expressions.
146void MapSubprogramToNewSymbols(const Symbol &oldSymbol, Symbol &newSymbol,
147 Scope &newScope, SymbolAndTypeMappings * = nullptr);
148
149} // namespace Fortran::semantics
150#endif // FORTRAN_SEMANTICS_RESOLVE_NAMES_H_
Definition: char-block.h:28
Definition: type.h:353
Definition: resolve-names-utils.h:104
Definition: resolve-names-utils.h:72
Definition: scope.h:58
Definition: semantics.h:67
Definition: symbol.h:712
Definition: check-expression.h:19
Definition: parse-tree.h:1358
Definition: parse-tree.h:984
Definition: parse-tree.h:995
Definition: parse-tree.h:1818
Definition: parse-tree.h:1857
Definition: parse-tree.h:1700
Definition: parse-tree.h:3040
Definition: parse-tree.h:580
Definition: type.h:238
Definition: symbol.h:630
Definition: resolve-names-utils.cpp:669