forked from OSchip/llvm-project
Fix <rdar://problem/6770276> Support Class<Proto> syntax.
llvm-svn: 76741
This commit is contained in:
parent
a3a4dd5d03
commit
51d4f79ffa
|
@ -402,6 +402,7 @@ public:
|
|||
bool isObjCInterfaceType() const; // NSString or NSString<foo>
|
||||
bool isObjCQualifiedInterfaceType() const; // NSString<foo>
|
||||
bool isObjCQualifiedIdType() const; // id<foo>
|
||||
bool isObjCQualifiedClassType() const; // Class<foo>
|
||||
bool isObjCIdType() const; // id
|
||||
bool isObjCClassType() const; // Class
|
||||
bool isObjCBuiltinType() const; // 'id' or 'Class'
|
||||
|
@ -1950,7 +1951,7 @@ public:
|
|||
Protocols.size();
|
||||
}
|
||||
/// isObjCQualifiedClassType - true for "Class <p>".
|
||||
bool isQualifiedClassType() const {
|
||||
bool isObjCQualifiedClassType() const {
|
||||
return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) &&
|
||||
Protocols.size();
|
||||
}
|
||||
|
@ -2137,6 +2138,11 @@ inline bool Type::isObjCQualifiedIdType() const {
|
|||
return OPT->isObjCQualifiedIdType();
|
||||
return false;
|
||||
}
|
||||
inline bool Type::isObjCQualifiedClassType() const {
|
||||
if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType())
|
||||
return OPT->isObjCQualifiedClassType();
|
||||
return false;
|
||||
}
|
||||
inline bool Type::isObjCIdType() const {
|
||||
if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType())
|
||||
return OPT->isObjCIdType();
|
||||
|
|
|
@ -1961,8 +1961,6 @@ def ext_c99_array_usage : Extension<
|
|||
"use of C99-specific array features, accepted as an extension">;
|
||||
def err_invalid_protocol_qualifiers : Error<
|
||||
"invalid protocol qualifiers on non-ObjC type">;
|
||||
def err_qualified_class_unsupported : Error<
|
||||
"protocol qualified 'Class' is unsupported">;
|
||||
def warn_ivar_use_hidden : Warning<
|
||||
"local declaration of %0 hides instance variable">;
|
||||
def error_ivar_use_in_class_method : Error<
|
||||
|
|
|
@ -1742,9 +1742,6 @@ static void SortAndUniqueProtocols(ObjCProtocolDecl **&Protocols,
|
|||
QualType ASTContext::getObjCObjectPointerType(QualType InterfaceT,
|
||||
ObjCProtocolDecl **Protocols,
|
||||
unsigned NumProtocols) {
|
||||
if (InterfaceT.isNull())
|
||||
InterfaceT = ObjCBuiltinIdTy;
|
||||
|
||||
// Sort the protocol list alphabetically to canonicalize it.
|
||||
if (NumProtocols)
|
||||
SortAndUniqueProtocols(Protocols, NumProtocols);
|
||||
|
|
|
@ -1603,7 +1603,7 @@ void ObjCObjectPointerType::getAsStringInternal(std::string &InnerString,
|
|||
|
||||
if (isObjCIdType() || isObjCQualifiedIdType())
|
||||
ObjCQIString = "id";
|
||||
else if (isObjCClassType())
|
||||
else if (isObjCClassType() || isObjCQualifiedClassType())
|
||||
ObjCQIString = "Class";
|
||||
else
|
||||
ObjCQIString = getInterfaceDecl()->getNameAsString();
|
||||
|
|
|
@ -512,8 +512,7 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
|
|||
}
|
||||
|
||||
// Handle messages to id.
|
||||
if (ReceiverCType == Context.getCanonicalType(Context.getObjCIdType()) ||
|
||||
ReceiverCType->isBlockPointerType() ||
|
||||
if (ReceiverCType->isObjCIdType() || ReceiverCType->isBlockPointerType() ||
|
||||
Context.isObjCNSObjectType(RExpr->getType())) {
|
||||
ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(
|
||||
Sel, SourceRange(lbrac,rbrac));
|
||||
|
@ -528,7 +527,8 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
|
|||
}
|
||||
|
||||
// Handle messages to Class.
|
||||
if (ReceiverCType == Context.getCanonicalType(Context.getObjCClassType())) {
|
||||
if (ReceiverCType->isObjCClassType() ||
|
||||
ReceiverCType->isObjCQualifiedClassType()) {
|
||||
ObjCMethodDecl *Method = 0;
|
||||
|
||||
if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
|
||||
|
@ -538,6 +538,9 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
|
|||
|
||||
if (!Method)
|
||||
Method = LookupPrivateClassMethod(Sel, ClassDecl);
|
||||
|
||||
// FIXME: if we still haven't found a method, we need to look in
|
||||
// protocols (if we have qualifiers).
|
||||
}
|
||||
if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
|
||||
return true;
|
||||
|
|
|
@ -101,7 +101,7 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS,
|
|||
case DeclSpec::TST_unspecified:
|
||||
// "<proto1,proto2>" is an objc qualified ID with a missing id.
|
||||
if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) {
|
||||
Result = Context.getObjCObjectPointerType(QualType(),
|
||||
Result = Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy,
|
||||
(ObjCProtocolDecl**)PQ,
|
||||
DS.getNumProtocolQualifiers());
|
||||
break;
|
||||
|
@ -220,14 +220,14 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS,
|
|||
DS.getNumProtocolQualifiers());
|
||||
else if (Result->isObjCIdType())
|
||||
// id<protocol-list>
|
||||
Result = Context.getObjCObjectPointerType(QualType(),
|
||||
Result = Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy,
|
||||
(ObjCProtocolDecl**)PQ, DS.getNumProtocolQualifiers());
|
||||
else if (Result->isObjCClassType()) {
|
||||
if (DeclLoc.isInvalid())
|
||||
DeclLoc = DS.getSourceRange().getBegin();
|
||||
// Class<protocol-list>
|
||||
Diag(DeclLoc, diag::err_qualified_class_unsupported)
|
||||
<< DS.getSourceRange();
|
||||
Result = Context.getObjCObjectPointerType(Context.ObjCBuiltinClassTy,
|
||||
(ObjCProtocolDecl**)PQ, DS.getNumProtocolQualifiers());
|
||||
} else {
|
||||
if (DeclLoc.isInvalid())
|
||||
DeclLoc = DS.getSourceRange().getBegin();
|
||||
|
|
|
@ -40,8 +40,8 @@ id objc_getClass(const char *s);
|
|||
{
|
||||
int i = [(id <Func>)self class_func0];
|
||||
i += [(id <Func>)super class_func0]; // expected-error {{cannot cast 'super' (it isn't an expression)}}
|
||||
i += [(Class <Func>)self class_func0]; // expected-error {{protocol qualified 'Class' is unsupported}}
|
||||
return i + [(Class <Func>)super class_func0]; // expected-error {{protocol qualified 'Class' is unsupported}} // expected-error {{cannot cast 'super' (it isn't an expression)}}
|
||||
i += [(Class <Func>)self class_func0]; //
|
||||
return i + [(Class <Func>)super class_func0]; // // expected-error {{cannot cast 'super' (it isn't an expression)}}
|
||||
}
|
||||
+ (int) class_func3
|
||||
{
|
||||
|
|
|
@ -28,8 +28,7 @@ typedef int NotAnObjCObjectType;
|
|||
// GCC doesn't diagnose this.
|
||||
NotAnObjCObjectType <SomeProtocol> *obj; // expected-error {{invalid protocol qualifiers on non-ObjC type}}
|
||||
|
||||
// Decided not to support the following GCC extension. Found while researching rdar://6497631
|
||||
typedef struct objc_class *Class;
|
||||
|
||||
Class <SomeProtocol> UnfortunateGCCExtension; // expected-error {{protocol qualified 'Class' is unsupported}}
|
||||
Class <SomeProtocol> UnfortunateGCCExtension;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
__attribute ((unavailable))
|
||||
@protocol FwProto; // expected-note{{marked unavailable}}
|
||||
|
||||
Class <FwProto> cFw = 0; // expected-warning {{'FwProto' is unavailable}} expected-error{{protocol qualified 'Class' is unsupported}}
|
||||
Class <FwProto> cFw = 0; // expected-warning {{'FwProto' is unavailable}}
|
||||
|
||||
|
||||
__attribute ((deprecated)) @protocol MyProto1
|
||||
|
@ -31,7 +31,7 @@ __attribute ((deprecated)) @protocol MyProto1
|
|||
|
||||
|
||||
|
||||
Class <MyProto1> clsP1 = 0; // expected-warning {{'MyProto1' is deprecated}} expected-error{{protocol qualified 'Class' is unsupported}}
|
||||
Class <MyProto1> clsP1 = 0; // expected-warning {{'MyProto1' is deprecated}}
|
||||
|
||||
@protocol FwProto @end // expected-note{{marked unavailable}}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ id objc_getClass(const char *s);
|
|||
@interface Derived2: Object <Func>
|
||||
@end
|
||||
|
||||
static void doSomething(Class <Func> unsupportedObjectType) { // expected-error {{protocol qualified 'Class' is unsupported}}
|
||||
static void doSomething(Class <Func> unsupportedObjectType) {
|
||||
[unsupportedObjectType class_func0];
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue