37
37
#include " swift/AST/Requirement.h"
38
38
#include " swift/AST/StorageImpl.h"
39
39
#include " swift/AST/TrailingCallArguments.h"
40
+ #include " llvm/ADT/iterator_range.h"
40
41
#include " llvm/ADT/SmallVector.h"
41
42
#include " llvm/ADT/StringRef.h"
42
43
#include " llvm/Support/ErrorHandling.h"
@@ -47,6 +48,7 @@ namespace swift {
47
48
class ASTPrinter ;
48
49
class ASTContext ;
49
50
struct PrintOptions ;
51
+ class CustomAttr ;
50
52
class Decl ;
51
53
class AbstractFunctionDecl ;
52
54
class FuncDecl ;
@@ -58,133 +60,6 @@ class PatternBindingInitializer;
58
60
class TrailingWhereClause ;
59
61
class TypeExpr ;
60
62
61
- // / TypeAttributes - These are attributes that may be applied to types.
62
- class TypeAttributes {
63
- // Get a SourceLoc for every possible attribute that can be parsed in source.
64
- // the presence of the attribute is indicated by its location being set.
65
- SourceLoc AttrLocs[TAK_Count];
66
- public:
67
- // / AtLoc - This is the location of the first '@' in the attribute specifier.
68
- // / If this is an empty attribute specifier, then this will be an invalid loc.
69
- SourceLoc AtLoc;
70
-
71
- struct Convention {
72
- StringRef Name = {};
73
- DeclNameRef WitnessMethodProtocol = {};
74
- Located<StringRef> ClangType = Located<StringRef>(StringRef(), {});
75
- // / Convenience factory function to create a Swift convention.
76
- // /
77
- // / Don't use this function if you are creating a C convention as you
78
- // / probably need a ClangType field as well.
79
- static Convention makeSwiftConvention (StringRef name) {
80
- return {name, DeclNameRef (), Located<StringRef>(" " , {})};
81
- }
82
- };
83
-
84
- Optional<Convention> ConventionArguments;
85
-
86
- // Indicates whether the type's '@differentiable' attribute has a 'linear'
87
- // argument.
88
- DifferentiabilityKind differentiabilityKind =
89
- DifferentiabilityKind::NonDifferentiable;
90
-
91
- // For an opened existential type, the known ID.
92
- Optional<UUID> OpenedID;
93
-
94
- // For a reference to an opaque return type, the mangled name and argument
95
- // index into the generic signature.
96
- struct OpaqueReturnTypeRef {
97
- StringRef mangledName;
98
- unsigned index;
99
- };
100
- Optional<OpaqueReturnTypeRef> OpaqueReturnTypeOf;
101
-
102
- TypeAttributes () {}
103
-
104
- bool isValid () const { return AtLoc.isValid (); }
105
-
106
- void clearAttribute (TypeAttrKind A) {
107
- AttrLocs[A] = SourceLoc ();
108
- }
109
-
110
- bool has (TypeAttrKind A) const {
111
- return getLoc (A).isValid ();
112
- }
113
-
114
- SourceLoc getLoc (TypeAttrKind A) const {
115
- return AttrLocs[A];
116
- }
117
-
118
- void setOpaqueReturnTypeOf (StringRef mangling, unsigned index) {
119
- OpaqueReturnTypeOf = OpaqueReturnTypeRef{mangling, index};
120
- }
121
-
122
- void setAttr (TypeAttrKind A, SourceLoc L) {
123
- assert (!L.isInvalid () && " Cannot clear attribute with this method" );
124
- AttrLocs[A] = L;
125
- }
126
-
127
- void getAttrLocs (SmallVectorImpl<SourceLoc> &Locs) const {
128
- for (auto Loc : AttrLocs) {
129
- if (Loc.isValid ())
130
- Locs.push_back (Loc);
131
- }
132
- }
133
-
134
- // This attribute list is empty if no attributes are specified. Note that
135
- // the presence of the leading @ is not enough to tell, because we want
136
- // clients to be able to remove attributes they process until they get to
137
- // an empty list.
138
- bool empty () const {
139
- for (SourceLoc elt : AttrLocs)
140
- if (elt.isValid ())
141
- return false ;
142
-
143
- return true ;
144
- }
145
-
146
- bool hasConvention () const { return ConventionArguments.hasValue (); }
147
-
148
- // / Returns the primary calling convention string.
149
- // /
150
- // / Note: For C conventions, this may not represent the full convention.
151
- StringRef getConventionName () const {
152
- return ConventionArguments.getValue ().Name ;
153
- }
154
-
155
- // / Show the string enclosed between @convention(..)'s parentheses.
156
- // /
157
- // / For example, @convention(foo, bar) will give the string "foo, bar".
158
- void getConventionArguments (SmallVectorImpl<char > &buffer) const ;
159
-
160
- bool hasOwnership () const {
161
- return getOwnership () != ReferenceOwnership::Strong;
162
- }
163
- ReferenceOwnership getOwnership () const {
164
- #define REF_STORAGE (Name, name, ...) \
165
- if (has (TAK_sil_##name)) return ReferenceOwnership::Name;
166
- #include " swift/AST/ReferenceStorage.def"
167
- return ReferenceOwnership::Strong;
168
- }
169
-
170
- void clearOwnership () {
171
- #define REF_STORAGE (Name, name, ...) \
172
- clearAttribute (TAK_sil_##name);
173
- #include " swift/AST/ReferenceStorage.def"
174
- }
175
-
176
- bool hasOpenedID () const { return OpenedID.hasValue (); }
177
- UUID getOpenedID () const { return *OpenedID; }
178
-
179
- // / Given a name like "autoclosure", return the type attribute ID that
180
- // / corresponds to it. This returns TAK_Count on failure.
181
- // /
182
- static TypeAttrKind getAttrKindFromString (StringRef Str);
183
-
184
- // / Return the name (like "autoclosure") for an attribute ID.
185
- static const char *getAttrName (TypeAttrKind kind);
186
- };
187
-
188
63
class alignas (1 << AttrAlignInBits) AttributeBase {
189
64
public:
190
65
// / The location of the '@'.
@@ -229,6 +104,7 @@ enum class DeclKind : uint8_t;
229
104
// / Represents one declaration attribute.
230
105
class DeclAttribute : public AttributeBase {
231
106
friend class DeclAttributes ;
107
+ friend class TypeAttributes ;
232
108
233
109
protected:
234
110
union {
@@ -2409,6 +2285,170 @@ class DeclAttributes {
2409
2285
SourceLoc getStartLoc (bool forModifiers = false ) const ;
2410
2286
};
2411
2287
2288
+ // / TypeAttributes - These are attributes that may be applied to types.
2289
+ class TypeAttributes {
2290
+ // Get a SourceLoc for every possible attribute that can be parsed in source.
2291
+ // the presence of the attribute is indicated by its location being set.
2292
+ SourceLoc AttrLocs[TAK_Count];
2293
+
2294
+ // / The custom attributes, in a linked list.
2295
+ CustomAttr *CustomAttrs = nullptr ;
2296
+
2297
+ public:
2298
+ // / AtLoc - This is the location of the first '@' in the attribute specifier.
2299
+ // / If this is an empty attribute specifier, then this will be an invalid loc.
2300
+ SourceLoc AtLoc;
2301
+
2302
+ struct Convention {
2303
+ StringRef Name = {};
2304
+ DeclNameRef WitnessMethodProtocol = {};
2305
+ Located<StringRef> ClangType = Located<StringRef>(StringRef(), {});
2306
+ // / Convenience factory function to create a Swift convention.
2307
+ // /
2308
+ // / Don't use this function if you are creating a C convention as you
2309
+ // / probably need a ClangType field as well.
2310
+ static Convention makeSwiftConvention (StringRef name) {
2311
+ return {name, DeclNameRef (), Located<StringRef>(" " , {})};
2312
+ }
2313
+ };
2314
+
2315
+ Optional<Convention> ConventionArguments;
2316
+
2317
+ // Indicates whether the type's '@differentiable' attribute has a 'linear'
2318
+ // argument.
2319
+ DifferentiabilityKind differentiabilityKind =
2320
+ DifferentiabilityKind::NonDifferentiable;
2321
+
2322
+ // For an opened existential type, the known ID.
2323
+ Optional<UUID> OpenedID;
2324
+
2325
+ // For a reference to an opaque return type, the mangled name and argument
2326
+ // index into the generic signature.
2327
+ struct OpaqueReturnTypeRef {
2328
+ StringRef mangledName;
2329
+ unsigned index;
2330
+ };
2331
+ Optional<OpaqueReturnTypeRef> OpaqueReturnTypeOf;
2332
+
2333
+ TypeAttributes () {}
2334
+
2335
+ bool isValid () const { return AtLoc.isValid (); }
2336
+
2337
+ void clearAttribute (TypeAttrKind A) {
2338
+ AttrLocs[A] = SourceLoc ();
2339
+ }
2340
+
2341
+ bool has (TypeAttrKind A) const {
2342
+ return getLoc (A).isValid ();
2343
+ }
2344
+
2345
+ SourceLoc getLoc (TypeAttrKind A) const {
2346
+ return AttrLocs[A];
2347
+ }
2348
+
2349
+ void setOpaqueReturnTypeOf (StringRef mangling, unsigned index) {
2350
+ OpaqueReturnTypeOf = OpaqueReturnTypeRef{mangling, index};
2351
+ }
2352
+
2353
+ void setAttr (TypeAttrKind A, SourceLoc L) {
2354
+ assert (!L.isInvalid () && " Cannot clear attribute with this method" );
2355
+ AttrLocs[A] = L;
2356
+ }
2357
+
2358
+ void getAttrLocs (SmallVectorImpl<SourceLoc> &Locs) const {
2359
+ for (auto Loc : AttrLocs) {
2360
+ if (Loc.isValid ())
2361
+ Locs.push_back (Loc);
2362
+ }
2363
+ }
2364
+
2365
+ // This attribute list is empty if no attributes are specified. Note that
2366
+ // the presence of the leading @ is not enough to tell, because we want
2367
+ // clients to be able to remove attributes they process until they get to
2368
+ // an empty list.
2369
+ bool empty () const {
2370
+ if (CustomAttrs)
2371
+ return false ;
2372
+
2373
+ for (SourceLoc elt : AttrLocs)
2374
+ if (elt.isValid ())
2375
+ return false ;
2376
+
2377
+ return true ;
2378
+ }
2379
+
2380
+ bool hasConvention () const { return ConventionArguments.hasValue (); }
2381
+
2382
+ // / Returns the primary calling convention string.
2383
+ // /
2384
+ // / Note: For C conventions, this may not represent the full convention.
2385
+ StringRef getConventionName () const {
2386
+ return ConventionArguments.getValue ().Name ;
2387
+ }
2388
+
2389
+ // / Show the string enclosed between @convention(..)'s parentheses.
2390
+ // /
2391
+ // / For example, @convention(foo, bar) will give the string "foo, bar".
2392
+ void getConventionArguments (SmallVectorImpl<char > &buffer) const ;
2393
+
2394
+ bool hasOwnership () const {
2395
+ return getOwnership () != ReferenceOwnership::Strong;
2396
+ }
2397
+ ReferenceOwnership getOwnership () const {
2398
+ #define REF_STORAGE (Name, name, ...) \
2399
+ if (has (TAK_sil_##name)) return ReferenceOwnership::Name;
2400
+ #include " swift/AST/ReferenceStorage.def"
2401
+ return ReferenceOwnership::Strong;
2402
+ }
2403
+
2404
+ void clearOwnership () {
2405
+ #define REF_STORAGE (Name, name, ...) \
2406
+ clearAttribute (TAK_sil_##name);
2407
+ #include " swift/AST/ReferenceStorage.def"
2408
+ }
2409
+
2410
+ bool hasOpenedID () const { return OpenedID.hasValue (); }
2411
+ UUID getOpenedID () const { return *OpenedID; }
2412
+
2413
+ // / Given a name like "autoclosure", return the type attribute ID that
2414
+ // / corresponds to it. This returns TAK_Count on failure.
2415
+ // /
2416
+ static TypeAttrKind getAttrKindFromString (StringRef Str);
2417
+
2418
+ // / Return the name (like "autoclosure") for an attribute ID.
2419
+ static const char *getAttrName (TypeAttrKind kind);
2420
+
2421
+ void addCustomAttr (CustomAttr *attr) {
2422
+ attr->Next = CustomAttrs;
2423
+ CustomAttrs = attr;
2424
+ }
2425
+
2426
+ // Iterator for the custom type attributes.
2427
+ class iterator
2428
+ : public std::iterator<std::forward_iterator_tag, CustomAttr *> {
2429
+ CustomAttr *attr;
2430
+
2431
+ public:
2432
+ iterator () : attr(nullptr ) { }
2433
+ explicit iterator (CustomAttr *attr) : attr(attr) { }
2434
+
2435
+ iterator &operator ++() {
2436
+ attr = static_cast <CustomAttr *>(attr->Next );
2437
+ return *this ;
2438
+ }
2439
+
2440
+ bool operator ==(iterator x) const { return x.attr == attr; }
2441
+ bool operator !=(iterator x) const { return x.attr != attr; }
2442
+
2443
+ CustomAttr *operator *() const { return attr; }
2444
+ CustomAttr &operator ->() const { return *attr; }
2445
+ };
2446
+
2447
+ llvm::iterator_range<iterator> getCustomAttrs () const {
2448
+ return llvm::make_range (iterator (CustomAttrs), iterator ());
2449
+ }
2450
+ };
2451
+
2412
2452
void simple_display (llvm::raw_ostream &out, const DeclAttribute *attr);
2413
2453
2414
2454
inline SourceLoc extractNearestSourceLoc (const DeclAttribute *attr) {
0 commit comments