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