Skip to content

Commit

Permalink
[ObjC] Fix non-canonical types preventing type arguments substitution.
Browse files Browse the repository at this point in the history
`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
  • Loading branch information
vsapsai committed Feb 15, 2019
1 parent 7875841 commit 4b512c3
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 9 deletions.
30 changes: 21 additions & 9 deletions clang/lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,17 @@ struct SimpleTransformVisitor

#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)

Expand Down Expand Up @@ -955,8 +966,8 @@ struct SimpleTransformVisitor
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());
Expand Down Expand Up @@ -987,15 +998,15 @@ struct SimpleTransformVisitor
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());
Expand Down Expand Up @@ -1030,7 +1041,7 @@ struct SimpleTransformVisitor
}

// 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())
Expand All @@ -1049,7 +1060,7 @@ struct SimpleTransformVisitor
}

// 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());
Expand Down Expand Up @@ -1107,6 +1118,7 @@ struct SimpleTransformVisitor
}

#undef TRIVIAL_TYPE_CLASS
#undef SUGARED_TYPE_CLASS
};

} // namespace
Expand Down
8 changes: 8 additions & 0 deletions clang/test/SemaObjC/parameterized_classes_subst.m
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ @interface NSViewController<ViewType : NSView *> : NSObject
@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
// --------------------------------------------------------------------------
Expand Down Expand Up @@ -190,6 +196,7 @@ void test_message_send_param(
MutableSetOfArrays<NSString *> *mutStringArraySet,
NSMutableSet *mutSet,
MutableSetOfArrays *mutArraySet,
TypedefTypeParam<NSString *> *typedefTypeParam,
void (^block)(void)) {
Window *window;

Expand All @@ -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>'}}
}

Expand Down

0 comments on commit 4b512c3

Please sign in to comment.