2626#include " swift/Basic/SourceLoc.h"
2727
2828#include " llvm/ADT/ArrayRef.h"
29+ #include " llvm/Support/TrailingObjects.h"
2930
3031namespace swift {
3132
@@ -43,102 +44,162 @@ enum class ParsedLifetimeDependenceKind : uint8_t {
4344
4445enum class LifetimeDependenceKind : uint8_t { Inherit = 0 , Scope };
4546
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 {
5348 union Value {
5449 struct {
55- Identifier name;
50+ StringRef name;
5651 } Named;
5752 struct {
5853 unsigned index;
5954 } Ordered;
6055 struct {
61- } self ;
62- Value (Identifier name) : Named ({name}) {}
56+ } Self ;
57+ Value (StringRef name) : Named ({name}) {}
6358 Value (unsigned index) : Ordered ({index}) {}
64- Value () {}
59+ Value () : Self () {}
6560 } value;
6661
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;
7363
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;
8165
82- static LifetimeEntry getImmortalLifetimeEntry (SourceLoc loc) {
83- return {loc, LifetimeEntryKind::Immortal, {}, {}};
84- }
66+ SourceLoc loc;
8567
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) {}
9283
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};
98101 }
99-
100- SourceLoc getLoc () const { return loc; }
101-
102- LifetimeEntryKind getLifetimeEntryKind () const { return lifetimeEntryKind; }
103102
104103 ParsedLifetimeDependenceKind getParsedLifetimeDependenceKind () const {
105104 return parsedLifetimeDependenceKind;
106105 }
107106
108- Identifier getName () const {
109- assert (lifetimeEntryKind == LifetimeEntryKind ::Named);
107+ StringRef getName () const {
108+ assert (kind == DescriptorKind ::Named);
110109 return value.Named .name ;
111110 }
112111
113112 unsigned getIndex () const {
114- assert (lifetimeEntryKind == LifetimeEntryKind ::Ordered);
113+ assert (kind == DescriptorKind ::Ordered);
115114 return value.Ordered .index ;
116115 }
117116
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:
123135 return " self" ;
124- case LifetimeEntryKind::Ordered:
125- return std::to_string (value.Ordered .index );
126- case LifetimeEntryKind::Immortal:
127- return " immortal" ;
128136 }
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;
130180 }
131181
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 ;
140200 }
141- llvm_unreachable (" Invalid LifetimeEntry::ParsedLifetimeDependenceKind" );
201+ result += " )" ;
202+ return result;
142203 }
143204};
144205
@@ -157,11 +218,6 @@ class LifetimeDependenceInfo {
157218 static std::optional<ArrayRef<LifetimeDependenceInfo>>
158219 fromLifetimeAttribute (AbstractFunctionDecl *afd);
159220
160- // / Builds LifetimeDependenceInfo from dependsOn type modifier
161- static std::optional<LifetimeDependenceInfo>
162- fromDependsOn (AbstractFunctionDecl *afd, TypeRepr *targetRepr,
163- Type targetType, unsigned targetIndex);
164-
165221 // / Infer LifetimeDependenceInfo on result
166222 static std::optional<LifetimeDependenceInfo> infer (AbstractFunctionDecl *afd);
167223
0 commit comments