FLANG
designator-path.h
1//===-- include/flang/Evaluate/designator-path.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_EVALUATE_DESIGNATOR_PATH_H_
10#define FORTRAN_EVALUATE_DESIGNATOR_PATH_H_
11
12#include "flang/Evaluate/expression.h"
13#include <cstdint>
14#include <optional>
15#include <string>
16#include <utility>
17#include <vector>
18
19namespace Fortran::evaluate {
20
21enum class DesignatorRelation {
22 Equal,
23 Contains,
24 ContainedBy,
25 Overlaps,
26 Disjoint,
27};
28
30 // A DesignatorPath represents a constrained prefix of a valid Fortran
31 // designator:
32 // - an optional NamedEntity base, and
33 // - zero or more suffix parts.
34 //
35 // The optional base distinguishes the named entity from subsequent part
36 // references. Each suffix part first applies optional subscripts to the
37 // current entity and then optionally selects a component symbol. An empty
38 // subscript list means there is no explicit subscript selector on this part;
39 // a full slice `(:)` is represented as a single Triplet subscript with no
40 // lower or upper bound and stride one. This can later grow a final optional
41 // variant for terminal designator pieces that are not part refs, such as
42 // complex parts, character substrings, or coarray references, while still
43 // preserving a valid designator shape.
44 struct Part {
45 std::vector<Subscript> subscripts;
46 const Symbol *symbol{nullptr};
47 bool operator==(const Part &that) const {
48 return subscripts == that.subscripts && symbol == that.symbol;
49 }
50 };
51
52 static std::optional<DesignatorPath> Get(
53 const std::optional<Expr<SomeType>> &);
54 DesignatorRelation Compare(const DesignatorPath &) const;
55 bool MayContain(const DesignatorPath &) const;
56 std::string AsFortran() const;
57 llvm::raw_ostream &AsFortran(llvm::raw_ostream &) const;
58 void SetBase(NamedEntity);
59 void AddComponent(const Symbol &);
60 void AddSubscripts(std::vector<Subscript>);
61 const std::optional<NamedEntity> &Base() const { return base; }
62 const std::vector<Part> &Parts() const { return parts; }
63 bool empty() const { return !base && parts.empty(); }
64 bool HasBaseOnly() const { return base && parts.empty(); }
65 bool operator==(const DesignatorPath &that) const {
66 return base == that.base && parts == that.parts;
67 }
68
70 std::int64_t lower;
71 std::int64_t upper;
72 };
73
74 static std::optional<ConstantSubscriptRange> GetConstantSubscriptRange(
75 const Subscript &);
76 static bool IsFullTriplet(const Triplet &);
77 static DesignatorRelation CompareSubscripts(
78 const Subscript &, const Subscript &);
79 static DesignatorRelation CompareSubscriptLists(
80 const std::vector<Subscript> &, const std::vector<Subscript> &);
81 static DesignatorRelation CompareParts(const Part &, const Part &);
82 static DesignatorRelation CombineRelations(
83 bool contains, bool containedBy, bool overlaps);
84 static bool SubscriptMayContain(const Subscript &, const Subscript &);
85 static bool SubscriptListMayContain(
86 const std::vector<Subscript> &, const std::vector<Subscript> &);
87 static bool PartMayContain(const Part &, const Part &);
88
89private:
90 void AddDataRef(const DataRef &);
91 void AddComponent(const Component &);
92 void AddNamedEntity(const NamedEntity &);
93 void AddArrayRef(const ArrayRef &);
94 void AddCoarrayRef(const CoarrayRef &);
95
96 std::optional<NamedEntity> base;
97 std::vector<Part> parts;
98};
99
100template <typename A> class DesignatorPathMap {
101public:
102 struct Entry {
103 DesignatorPath path;
104 A value;
105 };
106 using iterator = typename std::vector<Entry>::iterator;
107 using const_iterator = typename std::vector<Entry>::const_iterator;
108
109 iterator begin() { return entries_.begin(); }
110 iterator end() { return entries_.end(); }
111 const_iterator begin() const { return entries_.begin(); }
112 const_iterator end() const { return entries_.end(); }
113 bool empty() const { return entries_.empty(); }
114 void clear() { entries_.clear(); }
115 iterator erase(iterator iter) { return entries_.erase(iter); }
116 void push_back(DesignatorPath path, A value) {
117 entries_.push_back({std::move(path), std::move(value)});
118 }
119
120private:
121 std::vector<Entry> entries_;
122};
123
124} // namespace Fortran::evaluate
125
126#endif // FORTRAN_EVALUATE_DESIGNATOR_PATH_H_
Definition variable.h:205
Definition variable.h:243
Definition variable.h:73
Definition designator-path.h:100
Definition common.h:215
Definition variable.h:101
Definition variable.h:160
Definition symbol.h:907
Definition call.h:34
Definition variable.h:288
Definition designator-path.h:102
Definition designator-path.h:44
Definition designator-path.h:29
Definition variable.h:191