]> granicus.if.org Git - clang/commitdiff
More work to rewrite synthesize properties (<rdar://problem/6213955>)
authorSteve Naroff <snaroff@apple.com>
Tue, 2 Dec 2008 15:48:25 +0000 (15:48 +0000)
committerSteve Naroff <snaroff@apple.com>
Tue, 2 Dec 2008 15:48:25 +0000 (15:48 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60414 91177308-0d34-0410-b5e6-96231b3b80d8

Driver/RewriteObjC.cpp

index 69797366592e29ef4992a9518c35829ab713f74f..7f55d793d7c73cc237db6006614064a48e8f3f72 100644 (file)
@@ -586,9 +586,59 @@ void RewriteObjC::RewriteTabs() {
   }
 }
 
+static std::string getIvarAccessString(ObjCInterfaceDecl *ClassDecl,
+                                       ObjCIvarDecl *OID) {
+  std::string S;
+  S = "((struct ";
+  S += ClassDecl->getIdentifier()->getName();
+  S += "_IMPL *)self)->";
+  S += OID->getNameAsCString();
+  return S;
+}
+
 void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID) {
   SourceLocation startLoc = PID->getLocStart();
   InsertText(startLoc, "// ", 3);
+  const char *startBuf = SM->getCharacterData(startLoc);
+  assert((*startBuf == '@') && "bogus @synthesize location");
+  const char *semiBuf = strchr(startBuf, ';');
+  assert((*semiBuf == ';') && "@synthesize: can't find ';'");
+  SourceLocation onePastSemiLoc = startLoc.getFileLocWithOffset(semiBuf-startBuf+1);
+
+  if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+    return; // FIXME: is this correct?
+    
+  // Generate the 'getter' function.
+  std::string Getr;
+  ObjCPropertyDecl *PD = PID->getPropertyDecl();
+
+  RewriteObjCMethodDecl(PD->getGetterMethodDecl(), Getr);
+  ObjCInterfaceDecl *ClassDecl = PD->getGetterMethodDecl()->getClassInterface();
+
+  Getr += "{ ";
+  ObjCIvarDecl *OID = PID->getPropertyIvarDecl();
+  if (OID) {
+    // Synthesize an explicit cast to gain access to the ivar.
+    Getr += "return " + getIvarAccessString(ClassDecl, OID);
+    Getr += "; }";
+  } 
+  InsertText(onePastSemiLoc, Getr.c_str(), Getr.size());
+  
+  if (PD->isReadOnly())
+    return;
+    
+  // Generate the 'setter' function.
+  std::string Setr;
+  RewriteObjCMethodDecl(PD->getSetterMethodDecl(), Setr);
+  
+  Setr += "{ ";
+  if (OID) {
+    // Synthesize an explicit cast to initialize the ivar.
+    Setr += getIvarAccessString(ClassDecl, OID) + " = ";
+    Setr += OID->getNameAsCString();
+    Setr += "; }";
+  } 
+  InsertText(onePastSemiLoc, Setr.c_str(), Setr.size());
 }
 
 void RewriteObjC::RewriteForwardClassDecl(ObjCClassDecl *ClassDecl) {