@@ -43,102 +43,149 @@ enum class ParsedLifetimeDependenceKind : uint8_t {
4343
4444enum class LifetimeDependenceKind : uint8_t { Inherit = 0 , Scope };
4545
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 {
5347 union Value {
5448 struct {
55- Identifier name;
49+ StringRef name;
5650 } Named;
5751 struct {
5852 unsigned index;
5953 } Ordered;
6054 struct {
61- } self ;
62- Value (Identifier name) : Named ({name}) {}
55+ } Self ;
56+ Value (StringRef name) : Named ({name}) {}
6357 Value (unsigned index) : Ordered ({index}) {}
64- Value () {}
58+ Value () : Self () {}
6559 } value;
6660
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;
7362
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;
8164
82- static LifetimeEntry getImmortalLifetimeEntry (SourceLoc loc) {
83- return {loc, LifetimeEntryKind::Immortal, {}, {}};
84- }
65+ SourceLoc loc;
8566
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) {}
9282
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};
98100 }
99-
100- SourceLoc getLoc () const { return loc; }
101-
102- LifetimeEntryKind getLifetimeEntryKind () const { return lifetimeEntryKind; }
103101
104102 ParsedLifetimeDependenceKind getParsedLifetimeDependenceKind () const {
105103 return parsedLifetimeDependenceKind;
106104 }
107105
108- Identifier getName () const {
109- assert (lifetimeEntryKind == LifetimeEntryKind ::Named);
106+ StringRef getName () const {
107+ assert (kind == DescriptorKind ::Named);
110108 return value.Named .name ;
111109 }
112110
113111 unsigned getIndex () const {
114- assert (lifetimeEntryKind == LifetimeEntryKind ::Ordered);
112+ assert (kind == DescriptorKind ::Ordered);
115113 return value.Ordered .index ;
116114 }
117115
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:
123134 return " self" ;
124- case LifetimeEntryKind::Ordered:
125- return std::to_string (value.Ordered .index );
126- case LifetimeEntryKind::Immortal:
127- return " immortal" ;
128135 }
129- llvm_unreachable (" Invalid LifetimeEntryKind " );
136+ llvm_unreachable (" Invalid DescriptorKind " );
130137 }
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+ }
131179
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 ();
140186 }
141- llvm_unreachable (" Invalid LifetimeEntry::ParsedLifetimeDependenceKind" );
187+ result += " )" ;
188+ return result;
142189 }
143190};
144191
0 commit comments