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/Parser/message.h"
15 #include "flang/Semantics/scope.h"
16 #include "flang/Semantics/symbol.h"
17 #include "flang/Semantics/type.h"
18 #include <forward_list>
19
20 namespace Fortran::parser {
21 class CharBlock;
22 struct ArraySpec;
23 struct CoarraySpec;
24 struct ComponentArraySpec;
25 struct DataRef;
26 struct DefinedOpName;
27 struct Designator;
28 struct Expr;
29 struct GenericSpec;
30 struct Name;
31 } // namespace Fortran::parser
32
33 namespace Fortran::semantics {
34
35 using SourceName = parser::CharBlock;
36 class SemanticsContext;
37
38 // Record that a Name has been resolved to a Symbol
39 Symbol &Resolve(const parser::Name &, Symbol &);
40 Symbol *Resolve(const parser::Name &, Symbol *);
41
42 // Create a copy of msg with a new isFatal value.
43 parser::MessageFixedText WithIsFatal(
44 const parser::MessageFixedText &msg, bool isFatal);
45
46 // Is this the name of a defined operator, e.g. ".foo."
47 bool IsDefinedOperator(const SourceName &);
48 bool IsIntrinsicOperator(const SemanticsContext &, const SourceName &);
49 bool IsLogicalConstant(const SemanticsContext &, const SourceName &);
50
51 // Analyze a generic-spec and generate a symbol name and GenericKind for it.
52 class GenericSpecInfo {
53 public:
54 GenericSpecInfo(const parser::DefinedOpName &x) { Analyze(x); }
55 GenericSpecInfo(const parser::GenericSpec &x) { Analyze(x); }
56
57 GenericKind kind() const { return kind_; }
58 const SourceName &symbolName() const { return symbolName_.value(); }
59 // Some intrinsic operators have more than one name (e.g. `operator(.eq.)` and
60 // `operator(==)`). GetAllNames() returns them all, including symbolName.
61 std::forward_list<std::string> GetAllNames(SemanticsContext &) const;
62 // Set the GenericKind in this symbol and resolve the corresponding
63 // name if there is one
64 void Resolve(Symbol *) const;
65 Symbol *FindInScope(SemanticsContext &, const Scope &) const;
66
67 private:
68 GenericKind kind_;
69 const parser::Name *parseName_{nullptr};
70 std::optional<SourceName> symbolName_;
71
72 void Analyze(const parser::DefinedOpName &);
73 void Analyze(const parser::GenericSpec &);
74 };
75
76 // Analyze a parser::ArraySpec or parser::CoarraySpec
77 ArraySpec AnalyzeArraySpec(SemanticsContext &, const parser::ArraySpec &);
78 ArraySpec AnalyzeArraySpec(
79 SemanticsContext &, const parser::ComponentArraySpec &);
80 ArraySpec AnalyzeCoarraySpec(
81 SemanticsContext &context, const parser::CoarraySpec &);
82
83 // Perform consistency checks on equivalence sets
84 class EquivalenceSets {
85 public:
86 EquivalenceSets(SemanticsContext &context) : context_{context} {}
87 std::vector<EquivalenceSet> &sets() { return sets_; };
88 // Resolve this designator and add to the current equivalence set
89 void AddToSet(const parser::Designator &);
90 // Finish the current equivalence set: determine if it overlaps
91 // with any of the others and perform necessary merges if it does.
92 void FinishSet(const parser::CharBlock &);
93
94 private:
95 bool CheckCanEquivalence(
96 const parser::CharBlock &, const Symbol &, const Symbol &);
97 void MergeInto(const parser::CharBlock &, EquivalenceSet &, std::size_t);
98 const EquivalenceObject *Find(const EquivalenceSet &, const Symbol &);
99 bool CheckDesignator(const parser::Designator &);
100 bool CheckDataRef(const parser::CharBlock &, const parser::DataRef &);
101 bool CheckObject(const parser::Name &);
102 bool CheckArrayBound(const parser::Expr &);
103 bool CheckSubstringBound(const parser::Expr &, bool);
104 bool IsCharacterSequenceType(const DeclTypeSpec *);
105 bool IsDefaultKindNumericType(const IntrinsicTypeSpec &);
106 bool IsNumericSequenceType(const DeclTypeSpec *);
107 bool IsSequenceType(
108 const DeclTypeSpec *, std::function<bool(const IntrinsicTypeSpec &)>);
109
110 SemanticsContext &context_;
111 std::vector<EquivalenceSet> sets_; // all equivalence sets in this scope
112 // Map object to index of set it is in
113 std::map<EquivalenceObject, std::size_t> objectToSet_;
114 EquivalenceSet currSet_; // equivalence set currently being constructed
115 struct {
116 Symbol *symbol{nullptr};
117 std::vector<ConstantSubscript> subscripts;
118 std::optional<ConstantSubscript> substringStart;
119 } currObject_; // equivalence object currently being constructed
120 };
121
122 } // namespace Fortran::semantics
123 #endif // FORTRAN_SEMANTICS_RESOLVE_NAMES_H_
Fortran::semantics::SemanticsContext
Definition: semantics.h:60
Fortran::semantics::GenericSpecInfo
Definition: resolve-names-utils.h:52
Fortran::parser::ComponentArraySpec
Definition: parse-tree.h:953
Fortran::semantics::DeclTypeSpec
Definition: type.h:302
Fortran::semantics::Symbol
Definition: symbol.h:479
Fortran::semantics::EquivalenceSets
Definition: resolve-names-utils.h:84
Fortran::parser::GenericSpec
Definition: parse-tree.h:2919
Fortran::semantics::GenericKind
Definition: symbol.h:399
Fortran::parser::Name
Definition: parse-tree.h:555
Fortran::semantics::ArraySpec
Definition: type.h:217
Fortran::parser::CharBlock
Definition: char-block.h:28
Fortran::parser::ArraySpec
Definition: parse-tree.h:1291
Fortran::semantics::Scope
Definition: scope.h:56
Fortran::parser::CoarraySpec
Definition: parse-tree.h:942
Fortran::parser::DataRef
Definition: parse-tree.h:1742
Fortran::parser::Expr
Definition: parse-tree.h:1624
Fortran::parser
Definition: check-expression.h:19
Fortran::semantics::IntrinsicTypeSpec
Definition: type.h:117
Fortran::semantics::EquivalenceObject
Definition: scope.h:39
Fortran::parser::Designator
Definition: parse-tree.h:1772