@@ -195,68 +195,10 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
195
195
IGNORED_ATTR(Unsafe)
196
196
#undef IGNORED_ATTR
197
197
198
- private:
199
- static unsigned getABIArity (AbstractFunctionDecl *afd) {
200
- unsigned arity = afd->getParameters ()->size ();
201
- arity += afd->getGenericSignature ().getGenericParams ().size ();
202
- if (afd->hasImplicitSelfDecl ())
203
- arity += 1 ;
204
- return arity;
205
- }
206
-
207
- void checkABIAttrPBD (PatternBindingDecl *APBD, VarDecl *VD) {
208
- auto PBD = VD->getParentPatternBinding ();
209
-
210
- // To make sure we only diagnose this stuff once, check that VD is the first
211
- // anchoring variable in the PBD.
212
- bool isFirstAnchor = false ;
213
- for (auto i : range (PBD->getNumPatternEntries ())) {
214
- auto anchorVD = PBD->getAnchoringVarDecl (i);
215
- if (anchorVD) {
216
- isFirstAnchor = (anchorVD == VD);
217
- break ;
218
- }
219
- }
220
-
221
- if (!isFirstAnchor)
222
- return ;
223
-
224
- // Check that the PBDs have the same number of patterns.
225
- if (PBD->getNumPatternEntries () < APBD->getNumPatternEntries ()) {
226
- diagnose (APBD->getPattern (PBD->getNumPatternEntries ())->getLoc (),
227
- diag::attr_abi_mismatched_pbd_size, /* abiHasExtra=*/ false );
228
- return ;
229
- }
230
- if (PBD->getNumPatternEntries () > APBD->getNumPatternEntries ()) {
231
- diagnose (PBD->getPattern (APBD->getNumPatternEntries ())->getLoc (),
232
- diag::attr_abi_mismatched_pbd_size, /* abiHasExtra=*/ true );
233
- return ;
234
- }
235
-
236
- // Check that each pattern has the same number of variables.
237
- for (auto i : range (PBD->getNumPatternEntries ())) {
238
- SmallVector<VarDecl *, 8 > VDs;
239
- SmallVector<VarDecl *, 8 > AVDs;
240
-
241
- PBD->getPattern (i)->collectVariables (VDs);
242
- APBD->getPattern (i)->collectVariables (AVDs);
243
-
244
- if (VDs.size () < AVDs.size ()) {
245
- for (auto AVD : drop_begin (AVDs, VDs.size ())) {
246
- AVD->diagnose (diag::attr_abi_mismatched_var,
247
- AVD, /* isABI=*/ true );
248
- }
249
- }
250
- else if (VDs.size () > AVDs.size ()) {
251
- for (auto VD : drop_begin (VDs, AVDs.size ())) {
252
- VD->diagnose (diag::attr_abi_mismatched_var,
253
- VD, /* isABI=*/ false );
254
- }
255
- }
256
- }
198
+ void visitABIAttr (ABIAttr *attr) {
199
+ TypeChecker::checkDeclABIAttribute (D, attr);
257
200
}
258
201
259
- public:
260
202
void visitExecutionAttr (ExecutionAttr *attr) {
261
203
auto *F = dyn_cast<AbstractFunctionDecl>(D);
262
204
if (!F)
@@ -295,81 +237,6 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
295
237
}
296
238
}
297
239
298
- void visitABIAttr (ABIAttr *attr) {
299
- Decl *AD = attr->abiDecl ;
300
- if (isa<VarDecl>(D) && isa<PatternBindingDecl>(AD)) {
301
- auto VD = cast<VarDecl>(D);
302
- auto APBD = cast<PatternBindingDecl>(AD);
303
-
304
- // Diagnose dissimilar PBD structures.
305
- checkABIAttrPBD (APBD, VD);
306
-
307
- // Do the rest of this checking on the corresponding VarDecl, not the
308
- // PBD that's actually in the attribute. Note that `AD` will become null
309
- // if they're too dissimilar to match up.
310
- AD = APBD->getVarAtSimilarStructuralPosition (VD);
311
- }
312
- // TODO: EnumElementDecl?
313
-
314
- if (!AD)
315
- return ;
316
-
317
- // Check the ABI decl and bail if there was a problem with it.
318
- TypeChecker::typeCheckDecl (AD);
319
- if (AD->isInvalid ())
320
- return ;
321
-
322
- // Do the declarations have the same kind, broadly speaking? Many kinds have
323
- // special mangling behavior (e.g. inits vs normal funcs) that make it
324
- // unrealistic to treat one kind as though it were another.
325
- if (D->getKind () != AD->getKind ()) {
326
- // FIXME: DescriptiveDeclKind is overly specific; we really just want to
327
- // say that e.g. a `func` can't have the ABI of a `var`.
328
- diagnoseAndRemoveAttr (attr, diag::attr_abi_mismatched_kind,
329
- D, AD->getDescriptiveKind ());
330
- return ;
331
- }
332
-
333
- if (isa<AbstractFunctionDecl>(D)) {
334
- auto AFD = cast<AbstractFunctionDecl>(D);
335
- auto AAFD = cast<AbstractFunctionDecl>(AD);
336
-
337
- // FIXME: How much should we diagnose in IRGen for more precise ABI info?
338
-
339
- // Do the declarations have roughly the same number of parameters? We'll
340
- // allow some fuzziness for what these parameters *are*, since there isn't
341
- // always an ABI difference between e.g. a free function with N parameters
342
- // and an instance method with N-1 parameters (plus an implicit `self`).
343
- if (getABIArity (AFD) != getABIArity (AAFD)) {
344
- diagnoseAndRemoveAttr (attr, diag::attr_abi_mismatched_arity,
345
- AFD);
346
- }
347
-
348
- // Do the declarations match in throwing behavior? We don't care about
349
- // `throws` vs. `rethrows` here, just whether callers will account for an
350
- // error return.
351
- // FIXME: Typed throws?
352
- if (AFD->hasThrows () != AAFD->hasThrows ()) {
353
- diagnoseAndRemoveAttr (attr, diag::attr_abi_mismatched_throws,
354
- AFD, /* abiCanThrow=*/ AAFD->hasThrows ());
355
- }
356
-
357
- // Do the declarations match in async-ness?
358
- if (AFD->hasAsync () != AAFD->hasAsync ()) {
359
- diagnoseAndRemoveAttr (attr, diag::attr_abi_mismatched_async,
360
- AFD, /* abiHasAsync=*/ AAFD->hasAsync ());
361
- }
362
- }
363
-
364
- // TODO: Diagnose if Protocol::isMarkerProtocol() - contradiction in terms
365
- // (and mangler can't handle invertible protocols with @abi)
366
-
367
- // TODO: Validate more
368
- // FIXME: The list of properties that have to match is practically endless
369
- // and will grow as new features are added to the compiler. We might want to
370
- // write an AttributeVisitor just to help us catch omissions over time.
371
- }
372
-
373
240
void visitAlignmentAttr (AlignmentAttr *attr) {
374
241
// Alignment must be a power of two.
375
242
auto value = attr->getValue ();
0 commit comments