Objective-C @synthesize support.
 - Only supports simple assignment and atomic semantics are ignored.
 - Not quite usable yet because the methods do not actually get added
   to the class metadata.
 - Added ObjCPropertyDecl::getSetterKind (one of Assign, Copy, Retain).
 - Rearrange CodeGenFunction so synthesis can reuse function prolog /
   epilog code.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55365 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 51428c0..57d5377 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -836,6 +836,32 @@
   return GetAddrOfConstantString(str + "\0");
 }
 
+/// EmitObjCPropertyImplementations - Emit information for synthesized
+/// properties for an implementation.
+void CodeGenModule::EmitObjCPropertyImplementations(const 
+                                                    ObjCImplementationDecl *D) {
+  for (ObjCImplementationDecl::propimpl_iterator i = D->propimpl_begin(),
+         e = D->propimpl_end(); i != e; ++i) {
+    ObjCPropertyImplDecl *PID = *i;
+    
+    // Dynamic is just for type-checking.
+    if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
+      ObjCPropertyDecl *PD = PID->getPropertyDecl();
+
+      // Determine which methods need to be implemented, some may have
+      // been overridden. Note that ::isSynthesized is not the method
+      // we want, that just indicates if the decl came from a
+      // property. What we want to know is if the method is defined in
+      // this implementation.
+      if (!D->getInstanceMethod(PD->getGetterName()))
+        CodeGenFunction(*this).GenerateObjCGetter(PID);
+      if (!PD->isReadOnly() &&
+          !D->getInstanceMethod(PD->getSetterName()))
+        CodeGenFunction(*this).GenerateObjCSetter(PID);
+    }
+  }
+}
+
 /// EmitTopLevelDecl - Emit code for a single top level declaration.
 void CodeGenModule::EmitTopLevelDecl(Decl *D) {
   // If an error has occurred, stop code generation, but continue
@@ -868,13 +894,18 @@
     break;
 
   case Decl::ObjCCategoryImpl:
+    // Categories have properties but don't support synthesize so we
+    // can ignore them here.
+
     Runtime->GenerateCategory(cast<ObjCCategoryImplDecl>(D));
     break;
 
-  case Decl::ObjCImplementation:
-    Runtime->GenerateClass(cast<ObjCImplementationDecl>(D));
+  case Decl::ObjCImplementation: {
+    ObjCImplementationDecl *OMD = cast<ObjCImplementationDecl>(D);
+    EmitObjCPropertyImplementations(OMD);
+    Runtime->GenerateClass(OMD);
     break;
-    
+  } 
   case Decl::ObjCMethod: {
     ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(D);
     // If this is not a prototype, emit the body.
@@ -882,9 +913,6 @@
       CodeGenFunction(*this).GenerateObjCMethod(OMD);
     break;
   }
-  case Decl::ObjCPropertyImpl:
-    assert(0 && "FIXME: ObjCPropertyImpl unsupported");
-    break;
   case Decl::ObjCCompatibleAlias: 
     assert(0 && "FIXME: ObjCCompatibleAlias unsupported");
     break;