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.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76979 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index bfde991..66e73f9 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -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);
diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp
index 5e664ad..dcf2ebc 100644
--- a/lib/Sema/SemaTemplateInstantiateExpr.cpp
+++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp
@@ -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);