26
26
#include " swift/Basic/SourceLoc.h"
27
27
28
28
#include " llvm/ADT/ArrayRef.h"
29
+ #include " llvm/Support/TrailingObjects.h"
29
30
30
31
namespace swift {
31
32
@@ -43,102 +44,162 @@ enum class ParsedLifetimeDependenceKind : uint8_t {
43
44
44
45
enum class LifetimeDependenceKind : uint8_t { Inherit = 0 , Scope };
45
46
46
- enum class LifetimeEntryKind { Named, Ordered, Self, Immortal };
47
-
48
- class LifetimeEntry {
49
- private:
50
- SourceLoc loc;
51
- LifetimeEntryKind lifetimeEntryKind;
52
- ParsedLifetimeDependenceKind parsedLifetimeDependenceKind;
47
+ struct LifetimeDescriptor {
53
48
union Value {
54
49
struct {
55
- Identifier name;
50
+ StringRef name;
56
51
} Named;
57
52
struct {
58
53
unsigned index;
59
54
} Ordered;
60
55
struct {
61
- } self ;
62
- Value (Identifier name) : Named ({name}) {}
56
+ } Self ;
57
+ Value (StringRef name) : Named ({name}) {}
63
58
Value (unsigned index) : Ordered ({index}) {}
64
- Value () {}
59
+ Value () : Self () {}
65
60
} value;
66
61
67
- LifetimeEntry (SourceLoc loc, LifetimeEntryKind lifetimeEntryKind,
68
- ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
69
- Value value)
70
- : loc(loc), lifetimeEntryKind(lifetimeEntryKind),
71
- parsedLifetimeDependenceKind (parsedLifetimeDependenceKind),
72
- value(value) {}
62
+ enum class DescriptorKind { Named, Ordered, Self } kind;
73
63
74
- public:
75
- static LifetimeEntry
76
- getNamedLifetimeEntry (SourceLoc loc, Identifier name,
77
- ParsedLifetimeDependenceKind kind =
78
- ParsedLifetimeDependenceKind::Default) {
79
- return {loc, LifetimeEntryKind::Named, kind, name};
80
- }
64
+ ParsedLifetimeDependenceKind parsedLifetimeDependenceKind;
81
65
82
- static LifetimeEntry getImmortalLifetimeEntry (SourceLoc loc) {
83
- return {loc, LifetimeEntryKind::Immortal, {}, {}};
84
- }
66
+ SourceLoc loc;
85
67
86
- static LifetimeEntry
87
- getOrderedLifetimeEntry (SourceLoc loc, unsigned index,
88
- ParsedLifetimeDependenceKind kind =
89
- ParsedLifetimeDependenceKind::Default) {
90
- return {loc, LifetimeEntryKind::Ordered, kind, index};
91
- }
68
+ private:
69
+ LifetimeDescriptor (StringRef name,
70
+ ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
71
+ SourceLoc loc)
72
+ : value{name}, kind(DescriptorKind::Named),
73
+ parsedLifetimeDependenceKind (parsedLifetimeDependenceKind), loc(loc) {}
74
+ LifetimeDescriptor (unsigned index,
75
+ ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
76
+ SourceLoc loc)
77
+ : value{index}, kind(DescriptorKind::Ordered),
78
+ parsedLifetimeDependenceKind (parsedLifetimeDependenceKind), loc(loc) {}
79
+ LifetimeDescriptor (ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
80
+ SourceLoc loc)
81
+ : value{}, kind(DescriptorKind::Self),
82
+ parsedLifetimeDependenceKind (parsedLifetimeDependenceKind), loc(loc) {}
92
83
93
- static LifetimeEntry
94
- getSelfLifetimeEntry (SourceLoc loc,
95
- ParsedLifetimeDependenceKind kind =
96
- ParsedLifetimeDependenceKind::Default) {
97
- return {loc, LifetimeEntryKind::Self, kind, {}};
84
+ public:
85
+ static LifetimeDescriptor
86
+ forNamed (StringRef name,
87
+ ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
88
+ SourceLoc loc) {
89
+ return {name, parsedLifetimeDependenceKind, loc};
90
+ }
91
+ static LifetimeDescriptor
92
+ forOrdered (unsigned index,
93
+ ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
94
+ SourceLoc loc) {
95
+ return {index, parsedLifetimeDependenceKind, loc};
96
+ }
97
+ static LifetimeDescriptor
98
+ forSelf (ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
99
+ SourceLoc loc) {
100
+ return {parsedLifetimeDependenceKind, loc};
98
101
}
99
-
100
- SourceLoc getLoc () const { return loc; }
101
-
102
- LifetimeEntryKind getLifetimeEntryKind () const { return lifetimeEntryKind; }
103
102
104
103
ParsedLifetimeDependenceKind getParsedLifetimeDependenceKind () const {
105
104
return parsedLifetimeDependenceKind;
106
105
}
107
106
108
- Identifier getName () const {
109
- assert (lifetimeEntryKind == LifetimeEntryKind ::Named);
107
+ StringRef getName () const {
108
+ assert (kind == DescriptorKind ::Named);
110
109
return value.Named .name ;
111
110
}
112
111
113
112
unsigned getIndex () const {
114
- assert (lifetimeEntryKind == LifetimeEntryKind ::Ordered);
113
+ assert (kind == DescriptorKind ::Ordered);
115
114
return value.Ordered .index ;
116
115
}
117
116
118
- std::string getParamString () const {
119
- switch (lifetimeEntryKind) {
120
- case LifetimeEntryKind::Named:
121
- return value.Named .name .str ().str ();
122
- case LifetimeEntryKind::Self:
117
+ DescriptorKind getDescriptorKind () const { return kind; }
118
+
119
+ SourceLoc getLoc () const { return loc; }
120
+
121
+ bool isImmortal () const {
122
+ if (getDescriptorKind () != LifetimeDescriptor::DescriptorKind::Named) {
123
+ return false ;
124
+ }
125
+ return getName () == " immortal" ;
126
+ }
127
+
128
+ std::string getString () const {
129
+ switch (kind) {
130
+ case DescriptorKind::Named:
131
+ return getName ().str ();
132
+ case DescriptorKind::Ordered:
133
+ return std::to_string (getIndex ());
134
+ case DescriptorKind::Self:
123
135
return " self" ;
124
- case LifetimeEntryKind::Ordered:
125
- return std::to_string (value.Ordered .index );
126
- case LifetimeEntryKind::Immortal:
127
- return " immortal" ;
128
136
}
129
- llvm_unreachable (" Invalid LifetimeEntryKind" );
137
+ llvm_unreachable (" Invalid DescriptorKind" );
138
+ }
139
+ };
140
+
141
+ class LifetimeEntry final
142
+ : private llvm::TrailingObjects<LifetimeEntry, LifetimeDescriptor> {
143
+ friend TrailingObjects;
144
+
145
+ private:
146
+ SourceLoc startLoc, endLoc;
147
+ unsigned numSources;
148
+ std::optional<LifetimeDescriptor> targetDescriptor;
149
+
150
+ LifetimeEntry (
151
+ SourceLoc startLoc, SourceLoc endLoc,
152
+ ArrayRef<LifetimeDescriptor> sources,
153
+ std::optional<LifetimeDescriptor> targetDescriptor = std::nullopt)
154
+ : startLoc(startLoc), endLoc(endLoc), numSources(sources.size()),
155
+ targetDescriptor (targetDescriptor) {
156
+ std::uninitialized_copy (sources.begin (), sources.end (),
157
+ getTrailingObjects<LifetimeDescriptor>());
158
+ }
159
+
160
+ size_t numTrailingObjects (OverloadToken<LifetimeDescriptor>) const {
161
+ return numSources;
162
+ }
163
+
164
+ public:
165
+ static LifetimeEntry *
166
+ create (const ASTContext &ctx, SourceLoc startLoc, SourceLoc endLoc,
167
+ ArrayRef<LifetimeDescriptor> sources,
168
+ std::optional<LifetimeDescriptor> targetDescriptor = std::nullopt);
169
+
170
+ SourceLoc getLoc () const { return startLoc; }
171
+ SourceLoc getStartLoc () const { return startLoc; }
172
+ SourceLoc getEndLoc () const { return endLoc; }
173
+
174
+ ArrayRef<LifetimeDescriptor> getSources () const {
175
+ return {getTrailingObjects<LifetimeDescriptor>(), numSources};
176
+ }
177
+
178
+ std::optional<LifetimeDescriptor> getTargetDescriptor () const {
179
+ return targetDescriptor;
130
180
}
131
181
132
- std::string getDependsOnString () const {
133
- switch (parsedLifetimeDependenceKind) {
134
- case ParsedLifetimeDependenceKind::Default:
135
- return " dependsOn(" + getParamString () + " )" ;
136
- case ParsedLifetimeDependenceKind::Scope:
137
- return " dependsOn(scoped " + getParamString () + " )" ;
138
- case ParsedLifetimeDependenceKind::Inherit:
139
- return " dependsOn(inherited " + getParamString () + " )" ;
182
+ std::string getString () const {
183
+ std::string result = " @lifetime(" ;
184
+ if (targetDescriptor.has_value ()) {
185
+ result += targetDescriptor->getString ();
186
+ result += " : " ;
187
+ }
188
+
189
+ bool firstElem = true ;
190
+ for (auto source : getSources ()) {
191
+ if (!firstElem) {
192
+ result += " , " ;
193
+ }
194
+ if (source.getParsedLifetimeDependenceKind () ==
195
+ ParsedLifetimeDependenceKind::Scope) {
196
+ result += " borrow " ;
197
+ }
198
+ result += source.getString ();
199
+ firstElem = false ;
140
200
}
141
- llvm_unreachable (" Invalid LifetimeEntry::ParsedLifetimeDependenceKind" );
201
+ result += " )" ;
202
+ return result;
142
203
}
143
204
};
144
205
@@ -157,11 +218,6 @@ class LifetimeDependenceInfo {
157
218
static std::optional<ArrayRef<LifetimeDependenceInfo>>
158
219
fromLifetimeAttribute (AbstractFunctionDecl *afd);
159
220
160
- // / Builds LifetimeDependenceInfo from dependsOn type modifier
161
- static std::optional<LifetimeDependenceInfo>
162
- fromDependsOn (AbstractFunctionDecl *afd, TypeRepr *targetRepr,
163
- Type targetType, unsigned targetIndex);
164
-
165
221
// / Infer LifetimeDependenceInfo on result
166
222
static std::optional<LifetimeDependenceInfo> infer (AbstractFunctionDecl *afd);
167
223
0 commit comments