[cfe-commits] r45561 - in /cfe/trunk: Sema/Sema.cpp Sema/Sema.h Sema/SemaExpr.cpp Sema/SemaStmt.cpp include/clang/Basic/DiagnosticKinds.def test/Parser/objc-forcollection-1.m test/Parser/objc-forcollection-neg.m
Fariborz Jahanian
fjahanian at apple.com
Thu Jan 3 16:27:46 PST 2008
Author: fjahanian
Date: Thu Jan 3 18:27:46 2008
New Revision: 45561
URL: http://llvm.org/viewvc/llvm-project?rev=45561&view=rev
Log:
Patch to add semantics check for ObjC2's foreacn statement.
Added:
cfe/trunk/test/Parser/objc-forcollection-1.m
cfe/trunk/test/Parser/objc-forcollection-neg.m
Modified:
cfe/trunk/Sema/Sema.cpp
cfe/trunk/Sema/Sema.h
cfe/trunk/Sema/SemaExpr.cpp
cfe/trunk/Sema/SemaStmt.cpp
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
Modified: cfe/trunk/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.cpp?rev=45561&r1=45560&r2=45561&view=diff
==============================================================================
--- cfe/trunk/Sema/Sema.cpp (original)
+++ cfe/trunk/Sema/Sema.cpp Thu Jan 3 18:27:46 2008
@@ -26,6 +26,20 @@
strcmp(typeName, "SEL") == 0 || strcmp(typeName, "Protocol") == 0;
}
+bool Sema::isObjcObjectPointerType(QualType type) const {
+ if (!type->isPointerType() && !type->isObjcQualifiedIdType())
+ return false;
+ if (type == Context.getObjcIdType() || type == Context.getObjcClassType() ||
+ type->isObjcQualifiedIdType())
+ return true;
+
+ while (type->isPointerType()) {
+ PointerType *pointerType = static_cast<PointerType*>(type.getTypePtr());
+ type = pointerType->getPointeeType();
+ }
+ return (type->isObjcInterfaceType() || type->isObjcQualifiedIdType());
+}
+
void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
TUScope = S;
if (PP.getLangOptions().ObjC1) {
Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=45561&r1=45560&r2=45561&view=diff
==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Thu Jan 3 18:27:46 2008
@@ -285,6 +285,10 @@
/// isBuiltinObjcType - Returns true of the type is "id", "SEL", "Class"
/// or "Protocol".
bool isBuiltinObjcType(TypedefDecl *TD);
+
+ /// isObjcObjectPointerType - Returns tru if type is an objective-c pointer
+ /// to an object type; such as "id", "Class", Intf*, id<P>, etc.
+ bool isObjcObjectPointerType(QualType type) const;
/// AddInstanceMethodToGlobalPool - All instance methods in a translation
/// unit are added to a global pool. This allows us to efficiently associate
Modified: cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=45561&r1=45560&r2=45561&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Thu Jan 3 18:27:46 2008
@@ -2350,8 +2350,7 @@
return true;
}
} else {
- bool receiverIsQualId =
- dyn_cast<ObjcQualifiedIdType>(RExpr->getType()) != 0;
+ bool receiverIsQualId = dyn_cast<ObjcQualifiedIdType>(receiverType) != 0;
// FIXME (snaroff): checking in this code from Patrick. Needs to be
// revisited. how do we get the ClassDecl from the receiver expression?
if (!receiverIsQualId)
Modified: cfe/trunk/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaStmt.cpp?rev=45561&r1=45560&r2=45561&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/Sema/SemaStmt.cpp Thu Jan 3 18:27:46 2008
@@ -538,8 +538,9 @@
Stmt *First = static_cast<Stmt*>(first);
Expr *Second = static_cast<Expr*>(second);
Stmt *Body = static_cast<Stmt*>(body);
-
+ QualType FirstType;
if (DeclStmt *DS = dyn_cast_or_null<DeclStmt>(First)) {
+ FirstType = dyn_cast<ValueDecl>(DS->getDecl())->getType();
// C99 6.8.5p3: The declaration part of a 'for' statement shall only declare
// identifiers for objects having storage class 'auto' or 'register'.
for (ScopedDecl *D = DS->getDecl(); D; D = D->getNextDeclarator()) {
@@ -547,19 +548,21 @@
if (BVD && !BVD->hasLocalStorage())
BVD = 0;
if (BVD == 0)
- Diag(dyn_cast<ScopedDecl>(D)->getLocation(),
- diag::err_non_variable_decl_in_for);
- // FIXME: mark decl erroneous!
+ return Diag(dyn_cast<ScopedDecl>(D)->getLocation(),
+ diag::err_non_variable_decl_in_for);
}
}
+ else
+ FirstType = static_cast<Expr*>(first)->getType();
+ if (!isObjcObjectPointerType(FirstType))
+ Diag(ForColLoc, diag::err_selector_element_type,
+ FirstType.getAsString(), First->getSourceRange());
if (Second) {
DefaultFunctionArrayConversion(Second);
QualType SecondType = Second->getType();
-#if 0
- if (!SecondType->isScalarType()) // C99 6.8.5p2
- return Diag(ForColLoc, diag::err_typecheck_statement_requires_scalar,
- SecondType.getAsString(), Second->getSourceRange());
-#endif
+ if (!isObjcObjectPointerType(SecondType))
+ Diag(ForColLoc, diag::err_collection_expr_type,
+ SecondType.getAsString(), Second->getSourceRange());
}
return new ObjcForCollectionStmt(First, Second, Body, ForColLoc);
}
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=45561&r1=45560&r2=45561&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Thu Jan 3 18:27:46 2008
@@ -472,6 +472,10 @@
"method '%0%1' not found (return type defaults to 'id')")
DIAG(warn_method_not_found_in_protocol, WARNING,
"method '%0%1' not found in protocol (return type defaults to 'id')")
+DIAG(err_collection_expr_type, ERROR,
+ "collection expression is not of valid object type (its type is '%0')")
+DIAG(err_selector_element_type, ERROR,
+ "selector element is not of valid object type (its type is '%0')")
//===----------------------------------------------------------------------===//
// Semantic Analysis
Added: cfe/trunk/test/Parser/objc-forcollection-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/objc-forcollection-1.m?rev=45561&view=auto
==============================================================================
--- cfe/trunk/test/Parser/objc-forcollection-1.m (added)
+++ cfe/trunk/test/Parser/objc-forcollection-1.m Thu Jan 3 18:27:46 2008
@@ -0,0 +1,43 @@
+// RUN: clang -fsyntax-only %s
+
+typedef struct objc_class *Class;
+typedef struct objc_object {
+ Class isa;
+} *id;
+
+
+ at protocol P @end
+
+ at interface MyList
+ at end
+
+ at implementation MyList
+- (unsigned int)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state objects: (id *)items count:(unsigned int)stackcount
+{
+ return 0;
+}
+ at end
+
+ at interface MyList (BasicTest)
+- (void)compilerTestAgainst;
+ at end
+
+ at implementation MyList (BasicTest)
+- (void)compilerTestAgainst {
+ int i;
+ for (id elem in self)
+ ++i;
+ for (MyList *elem in self)
+ ++i;
+ for (id<P> se in self)
+ ++i;
+
+ MyList<P> *p;
+ for (p in self)
+ ++i;
+
+ for (p in p)
+ ++i;
+}
+ at end
+
Added: cfe/trunk/test/Parser/objc-forcollection-neg.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/objc-forcollection-neg.m?rev=45561&view=auto
==============================================================================
--- cfe/trunk/test/Parser/objc-forcollection-neg.m (added)
+++ cfe/trunk/test/Parser/objc-forcollection-neg.m Thu Jan 3 18:27:46 2008
@@ -0,0 +1,37 @@
+// RUN: clang -fsyntax-only -verify %s
+
+typedef struct objc_class *Class;
+typedef struct objc_object {
+ Class isa;
+} *id;
+
+
+ at interface MyList
+ at end
+
+ at implementation MyList
+- (unsigned int)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state objects: (id *)items count:(unsigned int)stackcount
+{
+ return 0;
+}
+ at end
+
+ at interface MyList (BasicTest)
+- (void)compilerTestAgainst;
+ at end
+
+ at implementation MyList (BasicTest)
+- (void)compilerTestAgainst {
+
+ int i=0;
+ for (int * elem in elem) // expected-error {{selector element is not of valid object type (its type is 'int *')}} \
+ expected-error {{collection expression is not of valid object type (its type is 'int *')}}
+ ++i;
+ for (i in elem) // expected-error {{use of undeclared identifier 'elem'}} \
+ expected-error {{selector element is not of valid object type (its type is 'int')}}
+ ++i;
+ for (id se in i) // expected-error {{collection expression is not of valid object type (its type is 'int')}}
+ ++i;
+}
+ at end
+
More information about the cfe-commits
mailing list