[ObjC] Fix non-canonical types preventing type arguments substitution.

`QualType::substObjCTypeArgs` doesn't go past non-canonical types and as
the result misses some of the substitutions like `ObjCTypeParamType`.

Update `SimpleTransformVisitor` to traverse past the type sugar.

Reviewers: ahatanak, erik.pilkington

Reviewed By: erik.pilkington

Subscribers: jkorous, dexonsmith, cfe-commits

Differential Revision: https://reviews.llvm.org/D57270

llvm-svn: 354164
This commit is contained in:
Volodymyr Sapsai 2019-02-15 20:17:45 +00:00
parent 7875841121
commit 4b512c36b6
2 changed files with 29 additions and 9 deletions

View File

@ -752,6 +752,17 @@ public:
#define TRIVIAL_TYPE_CLASS(Class) \
QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); }
#define SUGARED_TYPE_CLASS(Class) \
QualType Visit##Class##Type(const Class##Type *T) { \
if (!T->isSugared()) \
return QualType(T, 0); \
QualType desugaredType = recurse(T->desugar()); \
if (desugaredType.isNull()) \
return {}; \
if (desugaredType.getAsOpaquePtr() == T->desugar().getAsOpaquePtr()) \
return QualType(T, 0); \
return desugaredType; \
}
TRIVIAL_TYPE_CLASS(Builtin)
@ -955,8 +966,8 @@ public:
return Ctx.getParenType(innerType);
}
TRIVIAL_TYPE_CLASS(Typedef)
TRIVIAL_TYPE_CLASS(ObjCTypeParam)
SUGARED_TYPE_CLASS(Typedef)
SUGARED_TYPE_CLASS(ObjCTypeParam)
QualType VisitAdjustedType(const AdjustedType *T) {
QualType originalType = recurse(T->getOriginalType());
@ -987,15 +998,15 @@ public:
return Ctx.getDecayedType(originalType);
}
TRIVIAL_TYPE_CLASS(TypeOfExpr)
TRIVIAL_TYPE_CLASS(TypeOf)
TRIVIAL_TYPE_CLASS(Decltype)
TRIVIAL_TYPE_CLASS(UnaryTransform)
SUGARED_TYPE_CLASS(TypeOfExpr)
SUGARED_TYPE_CLASS(TypeOf)
SUGARED_TYPE_CLASS(Decltype)
SUGARED_TYPE_CLASS(UnaryTransform)
TRIVIAL_TYPE_CLASS(Record)
TRIVIAL_TYPE_CLASS(Enum)
// FIXME: Non-trivial to implement, but important for C++
TRIVIAL_TYPE_CLASS(Elaborated)
SUGARED_TYPE_CLASS(Elaborated)
QualType VisitAttributedType(const AttributedType *T) {
QualType modifiedType = recurse(T->getModifiedType());
@ -1030,7 +1041,7 @@ public:
}
// FIXME: Non-trivial to implement, but important for C++
TRIVIAL_TYPE_CLASS(TemplateSpecialization)
SUGARED_TYPE_CLASS(TemplateSpecialization)
QualType VisitAutoType(const AutoType *T) {
if (!T->isDeduced())
@ -1049,7 +1060,7 @@ public:
}
// FIXME: Non-trivial to implement, but important for C++
TRIVIAL_TYPE_CLASS(PackExpansion)
SUGARED_TYPE_CLASS(PackExpansion)
QualType VisitObjCObjectType(const ObjCObjectType *T) {
QualType baseType = recurse(T->getBaseType());
@ -1107,6 +1118,7 @@ public:
}
#undef TRIVIAL_TYPE_CLASS
#undef SUGARED_TYPE_CLASS
};
} // namespace

View File

@ -104,6 +104,12 @@ __attribute__((objc_root_class))
@property (nonatomic,retain) ViewType view;
@end
@interface TypedefTypeParam<T> : NSObject
typedef T AliasT;
- (void)test:(AliasT)object;
// expected-note@-1 {{parameter 'object' here}}
@end
// --------------------------------------------------------------------------
// Nullability
// --------------------------------------------------------------------------
@ -190,6 +196,7 @@ void test_message_send_param(
MutableSetOfArrays<NSString *> *mutStringArraySet,
NSMutableSet *mutSet,
MutableSetOfArrays *mutArraySet,
TypedefTypeParam<NSString *> *typedefTypeParam,
void (^block)(void)) {
Window *window;
@ -199,6 +206,7 @@ void test_message_send_param(
[mutStringArraySet addObject: window]; // expected-warning{{parameter of type 'NSArray<NSString *> *'}}
[mutSet addObject: window]; // expected-warning{{parameter of incompatible type 'id<NSCopying>'}}
[mutArraySet addObject: window]; // expected-warning{{parameter of incompatible type 'id<NSCopying>'}}
[typedefTypeParam test: window]; // expected-warning{{parameter of type 'NSString *'}}
[block addObject: window]; // expected-warning{{parameter of incompatible type 'id<NSCopying>'}}
}