summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp2
-rw-r--r--clang/lib/AST/Type.cpp3
-rw-r--r--clang/lib/CodeGen/CodeGenTypes.cpp1
-rw-r--r--clang/lib/Sema/SemaExpr.cpp4
-rw-r--r--clang/lib/Sema/SemaExprObjC.cpp15
5 files changed, 21 insertions, 4 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index cdd61cd3f4a..605f46b44bf 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -2408,7 +2408,7 @@ bool ASTContext::isObjCNSObjectType(QualType Ty) const {
/// to struct), Interface* (pointer to ObjCInterfaceType) and id<P> (qualified
/// ID type).
bool ASTContext::isObjCObjectPointerType(QualType Ty) const {
- if (Ty->isObjCQualifiedIdType())
+ if (Ty->isObjCQualifiedIdType() || Ty->isObjCQualifiedClassType())
return true;
// Blocks are objects.
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index ba8b463c277..065b626930b 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -693,7 +693,8 @@ bool Type::isScalarType() const {
isa<BlockPointerType>(CanonicalType) ||
isa<MemberPointerType>(CanonicalType) ||
isa<ComplexType>(CanonicalType) ||
- isa<ObjCQualifiedIdType>(CanonicalType);
+ isa<ObjCQualifiedIdType>(CanonicalType) ||
+ isa<ObjCQualifiedClassType>(CanonicalType);
}
/// \brief Determines whether the type is a C++ aggregate type or C
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index a385d8c9d29..47ac79f70b5 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -290,6 +290,7 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
}
case Type::ObjCQualifiedId:
+ case Type::ObjCQualifiedClass:
// Protocols don't influence the LLVM type.
return ConvertTypeRecursive(Context.getObjCIdType());
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index c390f769f59..b17f7bc1ca8 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2734,7 +2734,9 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) {
// C99 6.5.16.1p1: the left operand is a pointer and the right is
// a null pointer constant.
- if ((lhsType->isPointerType() || lhsType->isObjCQualifiedIdType() ||
+ if ((lhsType->isPointerType() ||
+ lhsType->isObjCQualifiedIdType() ||
+ lhsType->isObjCQualifiedClassType() ||
lhsType->isBlockPointerType())
&& rExpr->isNullPointerConstant(Context)) {
ImpCastExprToType(rExpr, lhsType);
diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
index 19dc3821c76..afa025552ad 100644
--- a/clang/lib/Sema/SemaExprObjC.cpp
+++ b/clang/lib/Sema/SemaExprObjC.cpp
@@ -391,7 +391,8 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
// We allow sending a message to a qualified ID ("id<foo>"), which is ok as
// long as one of the protocols implements the selector (if not, warn).
if (ObjCQualifiedIdType *QIT = dyn_cast<ObjCQualifiedIdType>(ReceiverCType)) {
- // Search protocols
+ // Search protocols for instance methods.
+ ReceiverCType.dump();
for (unsigned i = 0; i < QIT->getNumProtocols(); i++) {
ObjCProtocolDecl *PDecl = QIT->getProtocols(i);
if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
@@ -400,6 +401,18 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
if (!Method)
Diag(lbrac, diag::warn_method_not_found_in_protocol)
<< Sel << RExpr->getSourceRange();
+ // Check for GCC extension "Class<foo>".
+ } else if (ObjCQualifiedClassType *QIT =
+ dyn_cast<ObjCQualifiedClassType>(ReceiverCType)) {
+ // Search protocols for class methods.
+ for (unsigned i = 0; i < QIT->getNumProtocols(); i++) {
+ ObjCProtocolDecl *PDecl = QIT->getProtocols(i);
+ if (PDecl && (Method = PDecl->lookupClassMethod(Sel)))
+ break;
+ }
+ if (!Method)
+ Diag(lbrac, diag::warn_method_not_found_in_protocol)
+ << Sel << RExpr->getSourceRange();
} else if (const ObjCInterfaceType *OCIReceiver =
ReceiverCType->getAsPointerToObjCInterfaceType()) {
// We allow sending a message to a pointer to an interface (an object).
OpenPOWER on IntegriCloud