[cfe-commits] r76979 - in /cfe/trunk: include/clang/AST/ExprObjC.h include/clang/AST/StmtNodes.def include/clang/AST/Type.h include/clang/Frontend/PCHBitCodes.h lib/AST/Expr.cpp lib/AST/StmtPrinter.cpp lib/Frontend/PCHReaderStmt.cpp lib/Frontend/PCHWriterStmt.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaTemplateInstantiateExpr.cpp test/SemaObjC/id-isa-ref.m
Steve Naroff
snaroff at apple.com
Fri Jul 24 10:54:57 PDT 2009
Author: snaroff
Date: Fri Jul 24 12:54:45 2009
New Revision: 76979
URL: http://llvm.org/viewvc/llvm-project?rev=76979&view=rev
Log:
Allow front-end 'isa' access on object's of type 'id'.
Enhance test case to cover 'isa' access on interface types (clang produces an error, GCC produces a warning).
Still need back-end CodeGen for ObjCIsaExpr.
Modified:
cfe/trunk/include/clang/AST/ExprObjC.h
cfe/trunk/include/clang/AST/StmtNodes.def
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/include/clang/Frontend/PCHBitCodes.h
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/AST/StmtPrinter.cpp
cfe/trunk/lib/Frontend/PCHReaderStmt.cpp
cfe/trunk/lib/Frontend/PCHWriterStmt.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp
cfe/trunk/test/SemaObjC/id-isa-ref.m
Modified: cfe/trunk/include/clang/AST/ExprObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprObjC.h?rev=76979&r1=76978&r2=76979&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprObjC.h (original)
+++ cfe/trunk/include/clang/AST/ExprObjC.h Fri Jul 24 12:54:45 2009
@@ -496,6 +496,51 @@
virtual child_iterator child_end();
};
+/// ObjCIsaExpr - Represent X->isa and X.isa (similiar in spirit to MemberExpr).
+class ObjCIsaExpr : public Expr {
+ /// Base - the expression for the base object pointer.
+ Stmt *Base;
+
+ /// IsaMemberLoc - This is the location of the 'isa'.
+ SourceLocation IsaMemberLoc;
+
+ /// IsArrow - True if this is "X->F", false if this is "X.F".
+ bool IsArrow;
+public:
+ ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty)
+ : Expr(ObjCIsaExprClass, ty),
+ Base(base), IsaMemberLoc(l), IsArrow(isarrow) {}
+
+ /// \brief Build an empty expression.
+ explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { }
+
+ void setBase(Expr *E) { Base = E; }
+ Expr *getBase() const { return cast<Expr>(Base); }
+
+ bool isArrow() const { return IsArrow; }
+ void setArrow(bool A) { IsArrow = A; }
+
+ /// getMemberLoc - Return the location of the "member", in X->F, it is the
+ /// location of 'F'.
+ SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
+ void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(getBase()->getLocStart(), IsaMemberLoc);
+ }
+
+ virtual SourceLocation getExprLoc() const { return IsaMemberLoc; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCIsaExprClass;
+ }
+ static bool classof(const ObjCIsaExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
} // end namespace clang
#endif
Modified: cfe/trunk/include/clang/AST/StmtNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtNodes.def?rev=76979&r1=76978&r2=76979&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/StmtNodes.def (original)
+++ cfe/trunk/include/clang/AST/StmtNodes.def Fri Jul 24 12:54:45 2009
@@ -141,6 +141,7 @@
EXPR(ObjCPropertyRefExpr , Expr)
EXPR(ObjCKVCRefExpr , Expr)
EXPR(ObjCSuperExpr , Expr)
+EXPR(ObjCIsaExpr , Expr)
// Clang Extensions.
EXPR(ShuffleVectorExpr , Expr)
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=76979&r1=76978&r2=76979&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Fri Jul 24 12:54:45 2009
@@ -2189,7 +2189,6 @@
inline bool Type::isObjCBuiltinType() const {
return isObjCIdType() || isObjCClassType();
}
-
inline bool Type::isTemplateTypeParmType() const {
return isa<TemplateTypeParmType>(CanonicalType.getUnqualifiedType());
}
Modified: cfe/trunk/include/clang/Frontend/PCHBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHBitCodes.h?rev=76979&r1=76978&r2=76979&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHBitCodes.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHBitCodes.h Fri Jul 24 12:54:45 2009
@@ -638,7 +638,9 @@
EXPR_OBJC_MESSAGE_EXPR,
/// \brief An ObjCSuperExpr record.
EXPR_OBJC_SUPER_EXPR,
-
+ /// \brief An ObjCIsa Expr record.
+ EXPR_OBJC_ISA,
+
/// \brief An ObjCForCollectionStmt record.
STMT_OBJC_FOR_COLLECTION,
/// \brief An ObjCAtCatchStmt record.
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=76979&r1=76978&r2=76979&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Fri Jul 24 12:54:45 2009
@@ -1878,6 +1878,10 @@
Stmt::child_iterator ObjCSuperExpr::child_begin() { return child_iterator(); }
Stmt::child_iterator ObjCSuperExpr::child_end() { return child_iterator(); }
+// ObjCIsaExpr
+Stmt::child_iterator ObjCIsaExpr::child_begin() { return &Base; }
+Stmt::child_iterator ObjCIsaExpr::child_end() { return &Base+1; }
+
// PredefinedExpr
Stmt::child_iterator PredefinedExpr::child_begin() { return child_iterator(); }
Stmt::child_iterator PredefinedExpr::child_end() { return child_iterator(); }
Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=76979&r1=76978&r2=76979&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Fri Jul 24 12:54:45 2009
@@ -739,6 +739,11 @@
// representing anonymous unions/structs
OS << Node->getMemberDecl()->getNameAsString();
}
+void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
+ PrintExpr(Node->getBase());
+ OS << (Node->isArrow() ? "->isa" : ".isa");
+}
+
void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
PrintExpr(Node->getBase());
OS << ".";
Modified: cfe/trunk/lib/Frontend/PCHReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderStmt.cpp?rev=76979&r1=76978&r2=76979&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderStmt.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderStmt.cpp Fri Jul 24 12:54:45 2009
@@ -104,6 +104,7 @@
unsigned VisitObjCKVCRefExpr(ObjCKVCRefExpr *E);
unsigned VisitObjCMessageExpr(ObjCMessageExpr *E);
unsigned VisitObjCSuperExpr(ObjCSuperExpr *E);
+ unsigned VisitObjCIsaExpr(ObjCIsaExpr *E);
unsigned VisitObjCForCollectionStmt(ObjCForCollectionStmt *);
unsigned VisitObjCAtCatchStmt(ObjCAtCatchStmt *);
@@ -448,6 +449,14 @@
return 1;
}
+unsigned PCHStmtReader::VisitObjCIsaExpr(ObjCIsaExpr *E) {
+ VisitExpr(E);
+ E->setBase(cast<Expr>(StmtStack.back()));
+ E->setIsaMemberLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ E->setArrow(Record[Idx++]);
+ return 1;
+}
+
unsigned PCHStmtReader::VisitCastExpr(CastExpr *E) {
VisitExpr(E);
E->setSubExpr(cast<Expr>(StmtStack.back()));
@@ -1106,6 +1115,9 @@
case pch::EXPR_OBJC_SUPER_EXPR:
S = new (Context) ObjCSuperExpr(Empty);
break;
+ case pch::EXPR_OBJC_ISA:
+ S = new (Context) ObjCIsaExpr(Empty);
+ break;
case pch::STMT_OBJC_FOR_COLLECTION:
S = new (Context) ObjCForCollectionStmt(Empty);
break;
Modified: cfe/trunk/lib/Frontend/PCHWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterStmt.cpp?rev=76979&r1=76978&r2=76979&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterStmt.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterStmt.cpp Fri Jul 24 12:54:45 2009
@@ -97,6 +97,7 @@
void VisitObjCKVCRefExpr(ObjCKVCRefExpr *E);
void VisitObjCMessageExpr(ObjCMessageExpr *E);
void VisitObjCSuperExpr(ObjCSuperExpr *E);
+ void VisitObjCIsaExpr(ObjCIsaExpr *E);
// Objective-C Statements
void VisitObjCForCollectionStmt(ObjCForCollectionStmt *);
@@ -416,6 +417,14 @@
Code = pch::EXPR_MEMBER;
}
+void PCHStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) {
+ VisitExpr(E);
+ Writer.WriteSubStmt(E->getBase());
+ Writer.AddSourceLocation(E->getIsaMemberLoc(), Record);
+ Record.push_back(E->isArrow());
+ Code = pch::EXPR_OBJC_ISA;
+}
+
void PCHStmtWriter::VisitCastExpr(CastExpr *E) {
VisitExpr(E);
Writer.WriteSubStmt(E->getSubExpr());
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=76979&r1=76978&r2=76979&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Jul 24 12:54:45 2009
@@ -2283,7 +2283,6 @@
const ObjCObjectPointerType *OPT = BaseType->getAsObjCObjectPointerType();
const ObjCInterfaceType *IFaceT =
OPT ? OPT->getInterfaceType() : BaseType->getAsObjCInterfaceType();
-
if (IFaceT) {
ObjCInterfaceDecl *IDecl = IFaceT->getDecl();
ObjCInterfaceDecl *ClassDeclared;
@@ -2340,7 +2339,11 @@
<< IDecl->getDeclName() << &Member
<< BaseExpr->getSourceRange());
}
- // We don't have an interface. FIXME: deal with ObjC builtin 'id' type.
+ // We have an 'id' type. Rather than fall through, we check if this
+ // is a reference to 'isa'.
+ if (&Member == &Context.Idents.get("isa"))
+ return Owned(new (Context) ObjCIsaExpr(BaseExpr, true, MemberLoc,
+ Context.getObjCIdType()));
}
// Handle properties on 'id' and qualified "id".
if (OpKind == tok::period && (BaseType->isObjCIdType() ||
@@ -2472,6 +2475,13 @@
<< &Member << BaseType);
}
+ // Handle the following exceptional case (*Obj).isa.
+ if (OpKind == tok::period &&
+ BaseType->isSpecificBuiltinType(BuiltinType::ObjCId) &&
+ &Member == &Context.Idents.get("isa"))
+ return Owned(new (Context) ObjCIsaExpr(BaseExpr, false, MemberLoc,
+ Context.getObjCIdType()));
+
// Handle 'field access' to vectors, such as 'V.xx'.
if (BaseType->isExtVectorType()) {
QualType ret = CheckExtVectorComponent(BaseType, OpLoc, Member, MemberLoc);
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp?rev=76979&r1=76978&r2=76979&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp Fri Jul 24 12:54:45 2009
@@ -1341,6 +1341,12 @@
}
Sema::OwningExprResult
+TemplateExprInstantiator::VisitObjCIsaExpr(ObjCIsaExpr *E) {
+ assert(false && "FIXME: Template instantiations for ObjC expressions");
+ return SemaRef.ExprError();
+}
+
+Sema::OwningExprResult
Sema::InstantiateExpr(Expr *E, const TemplateArgumentList &TemplateArgs) {
if (!E)
return Owned((Expr *)0);
Modified: cfe/trunk/test/SemaObjC/id-isa-ref.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/id-isa-ref.m?rev=76979&r1=76978&r2=76979&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/id-isa-ref.m (original)
+++ cfe/trunk/test/SemaObjC/id-isa-ref.m Fri Jul 24 12:54:45 2009
@@ -4,7 +4,11 @@
struct objc_class *isa;
} *id;
- at interface Whatever
+ at interface NSObject {
+ struct objc_class *isa;
+}
+ at end
+ at interface Whatever : NSObject
+self;
@end
@@ -12,6 +16,19 @@
id x;
- // FIXME: The following needs to compile without error. I will fix this tomorrow (7/15/09). Until I do, we will produce an error.
- [x->isa self]; // expected-error {{member reference base type 'id' is not a structure or union}}
+ [(*x).isa self];
+ [x->isa self];
+
+ Whatever *y;
+
+ // GCC allows this, with the following warning:
+ // instance variable âisaâ is @protected; this will be a hard error in the future
+ //
+ // FIXME: see if we can avoid the 2 warnings that follow the error.
+ [(*y).isa self]; // expected-error {{instance variable 'isa' is protected}} \
+ expected-warning{{receiver type 'struct objc_class *' is not 'id' or interface pointer, consider casting it to 'id'}} \
+ expected-warning{{method '-self' not found (return type defaults to 'id')}}
+ [y->isa self]; // expected-error {{instance variable 'isa' is protected}} \
+ expected-warning{{receiver type 'struct objc_class *' is not 'id' or interface pointer, consider casting it to 'id'}} \
+ expected-warning{{method '-self' not found (return type defaults to 'id')}}
}
More information about the cfe-commits
mailing list