Initial work for property implementation declarations.
Mostly semantic checking in this patch. This is on going
and incomplete.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49882 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 50842f7..9d60093 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -656,7 +656,13 @@
                       DeclTy **allProperties = 0, unsigned pNum = 0);
   
   virtual DeclTy *ActOnProperty(Scope *S, SourceLocation AtLoc,
-                                FieldDeclarator &FD, ObjCDeclSpec &ODS);  
+                                FieldDeclarator &FD, ObjCDeclSpec &ODS);
+  virtual DeclTy *ActOnPropertyImplDecl(SourceLocation AtLoc, 
+                                        SourceLocation PropertyLoc,
+                                        bool ImplKind, DeclTy *ClassImplDecl,
+                                        IdentifierInfo *PropertyId,
+                                        IdentifierInfo *PropertyIvar);
+  
   virtual DeclTy *ActOnMethodDeclaration(
     SourceLocation BeginLoc, // location of the + or -.
     SourceLocation EndLoc,   // location of the ; or {.
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index eb9fa43..b0ae1f2 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -929,5 +929,116 @@
   return PDecl;
 }
 
-
+/// ActOnPropertyImplDecl - This routine performas semantic checks and
+/// build the AST node for a property implementation declaration; declared
+/// as @synthesize ot @dynamic
+///
+Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc, 
+                                          SourceLocation PropertyLoc,
+                                          bool Synthesize, 
+                                          DeclTy *ClassCatImpDecl,
+                                          IdentifierInfo *PropertyId,
+                                          IdentifierInfo *PropertyIvar) {
+  Decl *ClassImpDecl = static_cast<Decl*>(ClassCatImpDecl);
+  // Make sure we have a context for the property implementation declaration.
+  if (!ClassImpDecl) {
+    Diag(AtLoc, diag::error_missing_property_context);
+    return 0;
+  }
+  ObjCPropertyDecl *property = 0;
+  ObjCInterfaceDecl* IDecl = 0;
+  // Find the class or category class where this property must have
+  // a declaration.
+  if (ObjCImplementationDecl *IC = 
+        dyn_cast<ObjCImplementationDecl>(ClassImpDecl)) {
+    IDecl = getObjCInterfaceDecl(IC->getIdentifier());
+    if (!IDecl) {
+      Diag(AtLoc, diag::error_missing_property_interface);
+      return 0;
+    }
+    // Look for this property declaration in the @implementation's @interface
+    ObjCInterfaceDecl::classprop_iterator I,E;
+    for (I = IDecl->classprop_begin(),
+         E = IDecl->classprop_end(); I != E; ++I) {
+      property = *I;
+      if (property->getIdentifier() == PropertyId)
+        break;
+    }
+    if (I == E) {
+      Diag(PropertyLoc, diag::error_bad_property_decl, IDecl->getName());
+      return 0;
+    }    
+  }
+  else if (ObjCCategoryImplDecl* CatImplClass = 
+            dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl)) {
+    IDecl = CatImplClass->getClassInterface();
+    if (!IDecl) {
+      Diag(AtLoc, diag::error_missing_property_interface);
+      return 0;
+    }
+    ObjCCategoryDecl *Categories;
+    for (ObjCCategoryDecl *Categories = IDecl->getCategoryList();
+         Categories; Categories = Categories->getNextClassCategory())
+      if (Categories->getIdentifier() == CatImplClass->getIdentifier())
+        break;
+    // If category for this implementation not found, it is an error which
+    // has already been reported eralier.
+    if (!Categories)
+      return 0;
+    // Look for this property declaration in @implementation's category
+    ObjCCategoryDecl::classprop_iterator I,E;
+    for (I = Categories->classprop_begin(),
+         E = Categories->classprop_end(); I != E; ++I) {
+      property = *I;
+      if (property->getIdentifier() == PropertyId)
+        break;
+    }
+    if (I == E) {
+      Diag(PropertyLoc, diag::error_bad_property_decl, 
+           Categories->getName());
+      return 0;
+    }
+  }
+  else {
+    Diag(AtLoc, diag::error_bad_property_context);
+    return 0;
+  }
+  
+  // Check that we have a valid, previously declared ivar for @synthesize
+  if (Synthesize) {
+    // @synthesize
+    if (!PropertyIvar) {
+      Diag(PropertyLoc, diag::error_property_ivar_decl);
+      return 0;
+    }
+    // Check that this is a previously declared 'ivar' in 'IDecl' interface
+    ObjCInterfaceDecl::ivar_iterator IVI, IVE;
+    for (IVI = IDecl->ivar_begin(), IVE = IDecl->ivar_end(); 
+         IVI != IVE; ++IVI) {
+      ObjCIvarDecl* ImplIvar = (*IVI);
+      if (ImplIvar->getIdentifier() == PropertyIvar)
+        break;
+    }
+    if (IVI == IVE) {
+      Diag(PropertyLoc, diag::error_missing_property_ivar_decl);
+      return 0;
+    }
+  } else if (PropertyIvar) {
+    // @dynamic
+    Diag(PropertyLoc, diag::error_dynamic_property_ivar_decl);
+    return 0;
+  }
+  // TODO: More diagnostics go here !!
+  assert (property && "ActOnPropertyImplDecl - property declaration missing");
+  // TODO: Build the property implementation AST, pushes it into its 
+  // class/cateogory implementation's vector of property implementations
+#if 0
+  ObjCCategoryImplDecl *PIDecl = 
+    ObjCCategoryImplDecl::Create(AtLoc, PropertyLoc, property, 
+      Synthesize ? ObjCPropertyImplDecl::OBJC_PR_IMPL_SYNTHSIZE 
+                 : ObjCPropertyImplDecl::OBJC_PR_IMPL_DYNAMIC,
+                                 PropertyId, PropertyIvar);
+#endif
+  return 0;
+}