From 51d4f79ffae8a4b7b04dc35937af63a762492087 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Wed, 22 Jul 2009 16:07:01 +0000 Subject: [PATCH] Fix Support Class syntax. llvm-svn: 76741 --- clang/include/clang/AST/Type.h | 8 +++++++- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 -- clang/lib/AST/ASTContext.cpp | 3 --- clang/lib/AST/Type.cpp | 2 +- clang/lib/Sema/SemaExprObjC.cpp | 9 ++++++--- clang/lib/Sema/SemaType.cpp | 8 ++++---- clang/test/SemaObjC/call-super-2.m | 4 ++-- clang/test/SemaObjC/protocol-archane.m | 3 +-- clang/test/SemaObjC/protocol-attribute.m | 4 ++-- .../test/SemaObjC/protocol-qualified-class-unsupported.m | 2 +- 10 files changed, 24 insertions(+), 21 deletions(-) diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 82efb0a23b92..8500676d78c0 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -402,6 +402,7 @@ public: bool isObjCInterfaceType() const; // NSString or NSString bool isObjCQualifiedInterfaceType() const; // NSString bool isObjCQualifiedIdType() const; // id + bool isObjCQualifiedClassType() const; // Class 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

". - 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(); diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5a8ffb1bb7c9..3553a0386b52 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -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< diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 304799cf91b9..174e183d530e 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -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); diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index ffcaf42ef927..4d57680da2b9 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -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(); diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 068b386980e4..2d144100e5d0 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -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; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 3964f767ebf9..a686e1db5963 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -101,7 +101,7 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS, case DeclSpec::TST_unspecified: // "" 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 - 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 - 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(); diff --git a/clang/test/SemaObjC/call-super-2.m b/clang/test/SemaObjC/call-super-2.m index 92bec27c6783..a481cffd2886 100644 --- a/clang/test/SemaObjC/call-super-2.m +++ b/clang/test/SemaObjC/call-super-2.m @@ -40,8 +40,8 @@ id objc_getClass(const char *s); { int i = [(id )self class_func0]; i += [(id )super class_func0]; // expected-error {{cannot cast 'super' (it isn't an expression)}} - i += [(Class )self class_func0]; // expected-error {{protocol qualified 'Class' is unsupported}} - return i + [(Class )super class_func0]; // expected-error {{protocol qualified 'Class' is unsupported}} // expected-error {{cannot cast 'super' (it isn't an expression)}} + i += [(Class )self class_func0]; // + return i + [(Class )super class_func0]; // // expected-error {{cannot cast 'super' (it isn't an expression)}} } + (int) class_func3 { diff --git a/clang/test/SemaObjC/protocol-archane.m b/clang/test/SemaObjC/protocol-archane.m index 3e70c0509652..05f5103178f2 100644 --- a/clang/test/SemaObjC/protocol-archane.m +++ b/clang/test/SemaObjC/protocol-archane.m @@ -28,8 +28,7 @@ typedef int NotAnObjCObjectType; // GCC doesn't diagnose this. NotAnObjCObjectType *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 UnfortunateGCCExtension; // expected-error {{protocol qualified 'Class' is unsupported}} +Class UnfortunateGCCExtension; diff --git a/clang/test/SemaObjC/protocol-attribute.m b/clang/test/SemaObjC/protocol-attribute.m index ae8441132c77..6bd58dd9a03a 100644 --- a/clang/test/SemaObjC/protocol-attribute.m +++ b/clang/test/SemaObjC/protocol-attribute.m @@ -3,7 +3,7 @@ __attribute ((unavailable)) @protocol FwProto; // expected-note{{marked unavailable}} -Class cFw = 0; // expected-warning {{'FwProto' is unavailable}} expected-error{{protocol qualified 'Class' is unsupported}} +Class cFw = 0; // expected-warning {{'FwProto' is unavailable}} __attribute ((deprecated)) @protocol MyProto1 @@ -31,7 +31,7 @@ __attribute ((deprecated)) @protocol MyProto1 -Class clsP1 = 0; // expected-warning {{'MyProto1' is deprecated}} expected-error{{protocol qualified 'Class' is unsupported}} +Class clsP1 = 0; // expected-warning {{'MyProto1' is deprecated}} @protocol FwProto @end // expected-note{{marked unavailable}} diff --git a/clang/test/SemaObjC/protocol-qualified-class-unsupported.m b/clang/test/SemaObjC/protocol-qualified-class-unsupported.m index ad1ed5dc9411..6e344c1f4414 100644 --- a/clang/test/SemaObjC/protocol-qualified-class-unsupported.m +++ b/clang/test/SemaObjC/protocol-qualified-class-unsupported.m @@ -23,7 +23,7 @@ id objc_getClass(const char *s); @interface Derived2: Object @end -static void doSomething(Class unsupportedObjectType) { // expected-error {{protocol qualified 'Class' is unsupported}} +static void doSomething(Class unsupportedObjectType) { [unsupportedObjectType class_func0]; }