Index: clang/lib/AST/Type.cpp =================================================================== --- clang/lib/AST/Type.cpp +++ clang/lib/AST/Type.cpp @@ -751,6 +751,17 @@ #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) @@ -954,8 +965,8 @@ 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()); @@ -986,15 +997,15 @@ 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()); @@ -1029,7 +1040,7 @@ } // 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()) @@ -1048,7 +1059,7 @@ } // 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()); @@ -1106,6 +1117,7 @@ } #undef TRIVIAL_TYPE_CLASS +#undef SUGARED_TYPE_CLASS }; } // namespace Index: clang/test/SemaObjC/parameterized_classes_subst.m =================================================================== --- clang/test/SemaObjC/parameterized_classes_subst.m +++ clang/test/SemaObjC/parameterized_classes_subst.m @@ -104,6 +104,12 @@ @property (nonatomic,retain) ViewType view; @end +@interface TypedefTypeParam : NSObject +typedef T AliasT; +- (void)test:(AliasT)object; +// expected-note@-1 {{parameter 'object' here}} +@end + // -------------------------------------------------------------------------- // Nullability // -------------------------------------------------------------------------- @@ -190,6 +196,7 @@ MutableSetOfArrays *mutStringArraySet, NSMutableSet *mutSet, MutableSetOfArrays *mutArraySet, + TypedefTypeParam *typedefTypeParam, void (^block)(void)) { Window *window; @@ -199,6 +206,7 @@ [mutStringArraySet addObject: window]; // expected-warning{{parameter of type 'NSArray *'}} [mutSet addObject: window]; // expected-warning{{parameter of incompatible type 'id'}} [mutArraySet addObject: window]; // expected-warning{{parameter of incompatible type 'id'}} + [typedefTypeParam test: window]; // expected-warning{{parameter of type 'NSString *'}} [block addObject: window]; // expected-warning{{parameter of incompatible type 'id'}} }