@@ -90,6 +90,54 @@ struct DeclEffects {
90
90
}
91
91
};
92
92
93
+ // / Describes the relationship between a given type and the declaration it
94
+ // / belongs to--e.g. is this its result type? a parameter type? etc. Used with
95
+ // / a couple of \c \@abi diagnostics.
96
+ class TypeOrigin {
97
+ public:
98
+ // Cases must be kept in sync with DiagnosticsSema TYPE_ORIGIN
99
+ enum class Kind : uint8_t {
100
+ Unspecified = 0 ,
101
+ Parameter = 1 ,
102
+ SelfParameter = 2 ,
103
+ Result = 3 ,
104
+ ThrowsEffect = 4 ,
105
+ };
106
+
107
+ private:
108
+ llvm::PointerIntPair<Decl *, 3 , Kind> declAndKind;
109
+
110
+ TypeOrigin (Decl *decl, Kind kind)
111
+ : declAndKind(decl, kind) {}
112
+
113
+ public:
114
+ static TypeOrigin forUnspecified () {
115
+ return TypeOrigin (nullptr , Kind::Unspecified);
116
+ }
117
+
118
+ static TypeOrigin forParameter (ParamDecl *paramDecl) {
119
+ return TypeOrigin (paramDecl,
120
+ paramDecl->isSelfParameter () ? Kind::SelfParameter
121
+ : Kind::Parameter);
122
+ }
123
+
124
+ static TypeOrigin forResult () {
125
+ return TypeOrigin (nullptr , Kind::Result);
126
+ }
127
+
128
+ static TypeOrigin forThrowsEffect () {
129
+ return TypeOrigin (nullptr , Kind::ThrowsEffect);
130
+ }
131
+
132
+ Kind getKind () const {
133
+ return declAndKind.getInt ();
134
+ }
135
+
136
+ Decl *getDecl () const {
137
+ return declAndKind.getPointer ();
138
+ }
139
+ };
140
+
93
141
// / Emit a fix-it replacing \p charRange with \p newText , inserting or
94
142
// / removing whitespace after \c charRange in a way suitable for editing a
95
143
// / sequence of whitespce-separated keywords.
@@ -217,8 +265,10 @@ class ABIDeclChecker : public ASTComparisonVisitor<ABIDeclChecker> {
217
265
ParameterTypeFlags abiOrig,
218
266
Type apiType, Type abiType,
219
267
SourceLoc apiTypeLoc, SourceLoc abiTypeLoc,
220
- DescriptiveDeclKind declKind,
221
- bool isSelfParam) {
268
+ TypeOrigin origin) {
269
+ // Some keywords are spelled differently for a `self` parameter.
270
+ bool isSelfParam = origin.getKind () == TypeOrigin::Kind::SelfParameter;
271
+
222
272
bool didDiagnose = false ;
223
273
224
274
auto noteShouldMatch = [&](bool isModifier) {
@@ -255,7 +305,8 @@ class ABIDeclChecker : public ASTComparisonVisitor<ABIDeclChecker> {
255
305
ctx.Diags .diagnose (abiTypeLoc, diag::attr_abi_mismatched_param_modifier,
256
306
getSpelling (abiOrig.getOwnershipSpecifier ()),
257
307
getSpelling (apiOrig.getOwnershipSpecifier ()),
258
- /* isModifier=*/ true , declKind);
308
+ /* isModifier=*/ true , unsigned (origin.getKind ()),
309
+ origin.getDecl ());
259
310
noteShouldMatch (/* isModifier=*/ true );
260
311
didDiagnose = true ;
261
312
}
@@ -264,7 +315,8 @@ class ABIDeclChecker : public ASTComparisonVisitor<ABIDeclChecker> {
264
315
ctx.Diags .diagnose (abiTypeLoc, diag::attr_abi_mismatched_param_modifier,
265
316
abiOrig.isNoDerivative () ? " noDerivative" : " " ,
266
317
apiOrig.isNoDerivative () ? " noDerivative" : " " ,
267
- /* isModifier=*/ false , declKind);
318
+ /* isModifier=*/ false , unsigned (origin.getKind ()),
319
+ origin.getDecl ());
268
320
noteShouldMatch (/* isModifier=*/ false );
269
321
didDiagnose = true ;
270
322
}
@@ -274,14 +326,16 @@ class ABIDeclChecker : public ASTComparisonVisitor<ABIDeclChecker> {
274
326
ctx.Diags .diagnose (abiTypeLoc, diag::attr_abi_mismatched_param_modifier,
275
327
abiOrig.isAddressable () ? spelling : " " ,
276
328
apiOrig.isAddressable () ? spelling : " " ,
277
- /* isModifier=*/ false , declKind);
329
+ /* isModifier=*/ false , unsigned (origin.getKind ()),
330
+ origin.getDecl ());
278
331
noteShouldMatch (/* isModifier=*/ false );
279
332
didDiagnose = true ;
280
333
}
281
334
282
335
if (!didDiagnose && api != abi) {
283
336
// Flag difference not otherwise diagnosed. This is a fallback diagnostic.
284
337
ctx.Diags .diagnose (abiTypeLoc, diag::attr_abi_mismatched_type,
338
+ unsigned (origin.getKind ()), origin.getDecl (),
285
339
abiType, apiType);
286
340
ctx.Diags .diagnose (apiTypeLoc, diag::attr_abi_should_match_type_here);
287
341
didDiagnose = true ;
@@ -316,10 +370,8 @@ class ABIDeclChecker : public ASTComparisonVisitor<ABIDeclChecker> {
316
370
SourceLoc abiTypeLoc = getTypeLoc (abi, abiDecl);
317
371
318
372
didDiagnose |= checkType (apiNorm.getPlainType (), abiNorm.getPlainType (),
319
- apiTypeLoc, abiTypeLoc);
320
-
321
- auto declKind = api->isSelfParameter () ? apiDecl->getDescriptiveKind ()
322
- : DescriptiveDeclKind::Param;
373
+ apiTypeLoc, abiTypeLoc,
374
+ TypeOrigin::forParameter (abi));
323
375
324
376
didDiagnose |= checkParameterFlags (apiNorm.getParameterFlags (),
325
377
abiNorm.getParameterFlags (),
@@ -328,7 +380,7 @@ class ABIDeclChecker : public ASTComparisonVisitor<ABIDeclChecker> {
328
380
apiNorm.getPlainType (),
329
381
abiNorm.getPlainType (),
330
382
apiTypeLoc, abiTypeLoc,
331
- declKind, api-> isSelfParameter ( ));
383
+ TypeOrigin::forParameter (abi ));
332
384
333
385
didDiagnose |= checkAttrs (api->getAttrs (), abi->getAttrs (), api, abi);
334
386
@@ -642,7 +694,8 @@ class ABIDeclChecker : public ASTComparisonVisitor<ABIDeclChecker> {
642
694
return checkType (api->getResultInterfaceType (),
643
695
abi->getResultInterfaceType (),
644
696
api->getResultTypeSourceRange ().Start ,
645
- abi->getResultTypeSourceRange ().Start );
697
+ abi->getResultTypeSourceRange ().Start ,
698
+ TypeOrigin::forResult ());
646
699
}
647
700
648
701
bool visitConstructorDecl (ConstructorDecl *api, ConstructorDecl *abi) {
@@ -658,7 +711,8 @@ class ABIDeclChecker : public ASTComparisonVisitor<ABIDeclChecker> {
658
711
return true ;
659
712
660
713
if (checkType (api->getValueInterfaceType (), abi->getValueInterfaceType (),
661
- getTypeLoc (api), getTypeLoc (abi)))
714
+ getTypeLoc (api), getTypeLoc (abi),
715
+ TypeOrigin::forUnspecified ()))
662
716
return true ;
663
717
664
718
return false ;
@@ -868,7 +922,8 @@ class ABIDeclChecker : public ASTComparisonVisitor<ABIDeclChecker> {
868
922
869
923
// MARK: @abi checking - types
870
924
871
- bool checkType (Type api, Type abi, SourceLoc apiLoc, SourceLoc abiLoc) {
925
+ bool checkType (Type api, Type abi, SourceLoc apiLoc, SourceLoc abiLoc,
926
+ TypeOrigin origin) {
872
927
if (!api.isNull () && !abi.isNull ()) {
873
928
Type apiNorm = normalizeType (api);
874
929
Type abiNorm = normalizeType (abi);
@@ -877,7 +932,8 @@ class ABIDeclChecker : public ASTComparisonVisitor<ABIDeclChecker> {
877
932
}
878
933
}
879
934
880
- ctx.Diags .diagnose (abiLoc, diag::attr_abi_mismatched_type, abi, api);
935
+ ctx.Diags .diagnose (abiLoc, diag::attr_abi_mismatched_type,
936
+ unsigned (origin.getKind ()), origin.getDecl (), abi, api);
881
937
ctx.Diags .diagnose (apiLoc, diag::attr_abi_should_match_type_here);
882
938
return true ;
883
939
}
0 commit comments