This patch includes a conceptually simple, but very intrusive/pervasive change. 

The idea is to segregate Objective-C "object" pointers from general C pointers (utilizing the recently added ObjCObjectPointerType). The fun starts in Sema::GetTypeForDeclarator(), where "SomeInterface *" is now represented by a single AST node (rather than a PointerType whose Pointee is an ObjCInterfaceType). Since a significant amount of code assumed ObjC object pointers where based on C pointers/structs, this patch is very tedious. It should also explain why it is hard to accomplish this in smaller, self-contained patches.

This patch does most of the "heavy lifting" related to moving from PointerType->ObjCObjectPointerType. It doesn't include all potential "cleanups". The good news is additional cleanups can be done later (some are noted in the code). This patch is so large that I didn't want to include any changes that are purely aesthetic.

By making the ObjC types truly built-in, they are much easier to work with (and require fewer "hacks"). For example, there is no need for ASTContext::isObjCIdStructType() or ASTContext::isObjCClassStructType()! We believe this change (and the follow-up cleanups) will pay dividends over time. 

Given the amount of code change, I do expect some fallout from this change (though it does pass all of the clang tests). If you notice any problems, please let us know asap! Thanks.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@75314 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 6cbb1c3..9b58e47 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -53,9 +53,9 @@
       
         // Don't desugar magic Objective-C types.
         Ty.getUnqualifiedType() != Context.getObjCIdType() &&
+        Ty.getUnqualifiedType() != Context.getObjCClassType() &&
         Ty.getUnqualifiedType() != Context.getObjCSelType() &&
         Ty.getUnqualifiedType() != Context.getObjCProtoType() &&
-        Ty.getUnqualifiedType() != Context.getObjCClassType() &&
         
         // Not va_list.
         Ty.getUnqualifiedType() != Context.getBuiltinVaListType()) {
@@ -140,17 +140,6 @@
     Context.setObjCSelType(Context.getTypeDeclType(SelTypedef));
   }
 
-  if (Context.getObjCClassType().isNull()) {
-    RecordDecl *ClassTag = CreateStructDecl(Context, "objc_class");
-    QualType ClassT = Context.getPointerType(Context.getTagDeclType(ClassTag));
-    TypedefDecl *ClassTypedef = 
-      TypedefDecl::Create(Context, CurContext, SourceLocation(),
-                          &Context.Idents.get("Class"), ClassT);
-    PushOnScopeChains(ClassTag, TUScope);
-    PushOnScopeChains(ClassTypedef, TUScope);
-    Context.setObjCClassType(Context.getTypeDeclType(ClassTypedef));
-  }
-
   // Synthesize "@class Protocol;
   if (Context.getObjCProtoType().isNull()) {
     ObjCInterfaceDecl *ProtocolDecl =
@@ -160,20 +149,38 @@
     Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));
     PushOnScopeChains(ProtocolDecl, TUScope);
   }
-
-  // Synthesize "typedef struct objc_object { Class isa; } *id;"
+  // Create the built-in decls/typedefs for 'id' and 'Class'.
   if (Context.getObjCIdType().isNull()) {
-    RecordDecl *ObjectTag = CreateStructDecl(Context, "objc_object");
+    ObjCInterfaceDecl *IdIDecl =
+      ObjCInterfaceDecl::Create(Context, CurContext, SourceLocation(),
+                                &Context.Idents.get("id"), 
+                                SourceLocation(), true);
+    QualType IdIType = Context.getObjCInterfaceType(IdIDecl);
+    QualType ObjCIdType = Context.getObjCObjectPointerType(IdIType);
 
-    QualType ObjT = Context.getPointerType(Context.getTagDeclType(ObjectTag));
-    PushOnScopeChains(ObjectTag, TUScope);
     TypedefDecl *IdTypedef = TypedefDecl::Create(Context, CurContext,
                                                  SourceLocation(),
                                                  &Context.Idents.get("id"),
-                                                 ObjT);
+                                                 ObjCIdType);
     PushOnScopeChains(IdTypedef, TUScope);
     Context.setObjCIdType(Context.getTypeDeclType(IdTypedef));
   }
+  // Create the built-in decls/typedefs and type for "Class".
+  if (Context.getObjCClassType().isNull()) {
+    ObjCInterfaceDecl *ClassIDecl =
+      ObjCInterfaceDecl::Create(Context, CurContext, SourceLocation(),
+                                &Context.Idents.get("Class"), 
+                                SourceLocation(), true);
+    QualType ClassIType = Context.getObjCInterfaceType(ClassIDecl);
+    QualType ObjCClassType = Context.getObjCObjectPointerType(ClassIType);
+    
+    TypedefDecl *ClassTypedef = TypedefDecl::Create(Context, CurContext,
+                                                    SourceLocation(),
+                                                    &Context.Idents.get("Class"),
+                                                    ObjCClassType);
+    PushOnScopeChains(ClassTypedef, TUScope);
+    Context.setObjCClassType(Context.getTypeDeclType(ClassTypedef));
+  }
 }
 
 Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,