@@ -43,102 +43,149 @@ enum class ParsedLifetimeDependenceKind : uint8_t {
43
43
44
44
enum class LifetimeDependenceKind : uint8_t { Inherit = 0 , Scope };
45
45
46
- enum class LifetimeEntryKind { Named, Ordered, Self, Immortal };
47
-
48
- class LifetimeEntry {
49
- private:
50
- SourceLoc loc;
51
- LifetimeEntryKind lifetimeEntryKind;
52
- ParsedLifetimeDependenceKind parsedLifetimeDependenceKind;
46
+ struct LifetimeDescriptor {
53
47
union Value {
54
48
struct {
55
- Identifier name;
49
+ StringRef name;
56
50
} Named;
57
51
struct {
58
52
unsigned index;
59
53
} Ordered;
60
54
struct {
61
- } self ;
62
- Value (Identifier name) : Named ({name}) {}
55
+ } Self ;
56
+ Value (StringRef name) : Named ({name}) {}
63
57
Value (unsigned index ) : Ordered ({index }) {}
64
- Value () {}
58
+ Value () : Self () {}
65
59
} value;
66
60
67
- LifetimeEntry (SourceLoc loc, LifetimeEntryKind lifetimeEntryKind,
68
- ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
69
- Value value)
70
- : loc(loc), lifetimeEntryKind(lifetimeEntryKind),
71
- parsedLifetimeDependenceKind (parsedLifetimeDependenceKind),
72
- value(value) {}
61
+ enum class DescriptorKind { Named, Ordered, Self } kind;
73
62
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
- }
63
+ ParsedLifetimeDependenceKind parsedLifetimeDependenceKind;
81
64
82
- static LifetimeEntry getImmortalLifetimeEntry (SourceLoc loc) {
83
- return {loc, LifetimeEntryKind::Immortal, {}, {}};
84
- }
65
+ SourceLoc loc;
85
66
86
- static LifetimeEntry
87
- getOrderedLifetimeEntry (SourceLoc loc, unsigned index,
88
- ParsedLifetimeDependenceKind kind =
89
- ParsedLifetimeDependenceKind::Default) {
90
- return {loc, LifetimeEntryKind::Ordered, kind, index };
91
- }
67
+ private:
68
+ LifetimeDescriptor (StringRef name,
69
+ ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
70
+ SourceLoc loc)
71
+ : value{name}, kind(DescriptorKind::Named),
72
+ parsedLifetimeDependenceKind (parsedLifetimeDependenceKind), loc(loc) {}
73
+ LifetimeDescriptor (unsigned index,
74
+ ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
75
+ SourceLoc loc)
76
+ : value{index }, kind(DescriptorKind::Ordered),
77
+ parsedLifetimeDependenceKind (parsedLifetimeDependenceKind), loc(loc) {}
78
+ LifetimeDescriptor (ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
79
+ SourceLoc loc)
80
+ : value{}, kind(DescriptorKind::Self),
81
+ parsedLifetimeDependenceKind (parsedLifetimeDependenceKind), loc(loc) {}
92
82
93
- static LifetimeEntry
94
- getSelfLifetimeEntry (SourceLoc loc,
95
- ParsedLifetimeDependenceKind kind =
96
- ParsedLifetimeDependenceKind::Default) {
97
- return {loc, LifetimeEntryKind::Self, kind, {}};
83
+ public:
84
+ static LifetimeDescriptor
85
+ forNamed (StringRef name,
86
+ ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
87
+ SourceLoc loc) {
88
+ return {name, parsedLifetimeDependenceKind, loc};
89
+ }
90
+ static LifetimeDescriptor
91
+ forOrdered (unsigned index,
92
+ ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
93
+ SourceLoc loc) {
94
+ return {index , parsedLifetimeDependenceKind, loc};
95
+ }
96
+ static LifetimeDescriptor
97
+ forSelf (ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
98
+ SourceLoc loc) {
99
+ return {parsedLifetimeDependenceKind, loc};
98
100
}
99
-
100
- SourceLoc getLoc () const { return loc; }
101
-
102
- LifetimeEntryKind getLifetimeEntryKind () const { return lifetimeEntryKind; }
103
101
104
102
ParsedLifetimeDependenceKind getParsedLifetimeDependenceKind () const {
105
103
return parsedLifetimeDependenceKind;
106
104
}
107
105
108
- Identifier getName () const {
109
- assert (lifetimeEntryKind == LifetimeEntryKind ::Named);
106
+ StringRef getName () const {
107
+ assert (kind == DescriptorKind ::Named);
110
108
return value.Named .name ;
111
109
}
112
110
113
111
unsigned getIndex () const {
114
- assert (lifetimeEntryKind == LifetimeEntryKind ::Ordered);
112
+ assert (kind == DescriptorKind ::Ordered);
115
113
return value.Ordered .index ;
116
114
}
117
115
118
- std::string getParamString () const {
119
- switch (lifetimeEntryKind) {
120
- case LifetimeEntryKind::Named:
121
- return value.Named .name .str ().str ();
122
- case LifetimeEntryKind::Self:
116
+ DescriptorKind getDescriptorKind () const { return kind; }
117
+
118
+ SourceLoc getLoc () const { return loc; }
119
+
120
+ bool isImmortal () const {
121
+ if (getDescriptorKind () != LifetimeDescriptor::DescriptorKind::Named) {
122
+ return false ;
123
+ }
124
+ return getName () == " immortal" ;
125
+ }
126
+
127
+ std::string getString () const {
128
+ switch (kind) {
129
+ case DescriptorKind::Named:
130
+ return getName ().str ();
131
+ case DescriptorKind::Ordered:
132
+ return std::to_string (getIndex ());
133
+ case DescriptorKind::Self:
123
134
return " self" ;
124
- case LifetimeEntryKind::Ordered:
125
- return std::to_string (value.Ordered .index );
126
- case LifetimeEntryKind::Immortal:
127
- return " immortal" ;
128
135
}
129
- llvm_unreachable (" Invalid LifetimeEntryKind " );
136
+ llvm_unreachable (" Invalid DescriptorKind " );
130
137
}
138
+ };
139
+
140
+ // TODO: Use TrailingObjects to tail allocate sources
141
+ class LifetimeEntry {
142
+ private:
143
+ SourceLoc startLoc, endLoc;
144
+ ArrayRef<LifetimeDescriptor> sources;
145
+ std::optional<LifetimeDescriptor> targetDescriptor;
146
+
147
+ LifetimeEntry (
148
+ SourceLoc startLoc, SourceLoc endLoc,
149
+ ArrayRef<LifetimeDescriptor> sources,
150
+ std::optional<LifetimeDescriptor> targetDescriptor = std::nullopt)
151
+ : startLoc(startLoc), endLoc(endLoc), sources(sources),
152
+ targetDescriptor (targetDescriptor) {}
153
+
154
+ public:
155
+ // / \p sources should be allocated on the ASTContext
156
+ static LifetimeEntry *
157
+ create (const ASTContext &ctx, SourceLoc startLoc, SourceLoc endLoc,
158
+ ArrayRef<LifetimeDescriptor> sources,
159
+ std::optional<LifetimeDescriptor> targetDescriptor = std::nullopt);
160
+
161
+ SourceLoc getLoc () const { return startLoc; }
162
+ SourceLoc getStartLoc () const { return startLoc; }
163
+ SourceLoc getEndLoc () const { return endLoc; }
164
+
165
+ ArrayRef<LifetimeDescriptor> getSources () const { return sources; }
166
+
167
+ std::optional<LifetimeDescriptor> getTargetDescriptor () const {
168
+ return targetDescriptor;
169
+ }
170
+
171
+ bool empty () const { return !sources.empty (); }
172
+
173
+ std::string getString () const {
174
+ std::string result = " @lifetime(" ;
175
+ if (targetDescriptor.has_value ()) {
176
+ result += targetDescriptor->getString ();
177
+ result += " : " ;
178
+ }
131
179
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 () + " )" ;
180
+ for (auto source : sources) {
181
+ if (source.getParsedLifetimeDependenceKind () ==
182
+ ParsedLifetimeDependenceKind::Scope) {
183
+ result += " borrow " ;
184
+ }
185
+ result += source.getString ();
140
186
}
141
- llvm_unreachable (" Invalid LifetimeEntry::ParsedLifetimeDependenceKind" );
187
+ result += " )" ;
188
+ return result;
142
189
}
143
190
};
144
191
0 commit comments