[cfe-commits] r42360 - in /cfe/trunk: AST/Decl.cpp Sema/Sema.h Sema/SemaDecl.cpp include/clang/AST/Decl.h include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Action.h test/Sema/conflicting-ivar-test-1.m

Fariborz Jahanian fjahanian at apple.com
Wed Sep 26 11:27:26 PDT 2007


Author: fjahanian
Date: Wed Sep 26 13:27:25 2007
New Revision: 42360

URL: http://llvm.org/viewvc/llvm-project?rev=42360&view=rev
Log:
This patch inserts ivars declared in @implementation in its object and verifies 
that they conform(in type, name and numbers) to those declared in @interface. 
Test case highlights kind of checking we do here.

Added:
    cfe/trunk/test/Sema/conflicting-ivar-test-1.m
Modified:
    cfe/trunk/AST/Decl.cpp
    cfe/trunk/Sema/Sema.h
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/trunk/include/clang/Parse/Action.h

Modified: cfe/trunk/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Decl.cpp?rev=42360&r1=42359&r2=42360&view=diff

==============================================================================
--- cfe/trunk/AST/Decl.cpp (original)
+++ cfe/trunk/AST/Decl.cpp Wed Sep 26 13:27:25 2007
@@ -294,6 +294,19 @@
   }
 }
 
+/// ObjcAddInstanceVariablesToClassImpl - Checks for correctness of Instance 
+/// Variables (Ivars) relative to what declared in @implementation;s class. 
+/// Ivars into ObjcImplementationDecl's fields.
+///
+void ObjcImplementationDecl::ObjcAddInstanceVariablesToClassImpl(
+			       ObjcIvarDecl **ivars, unsigned numIvars) {
+  NumIvars = numIvars;
+  if (numIvars) {
+    Ivars = new ObjcIvarDecl*[numIvars];
+    memcpy(Ivars, ivars, numIvars*sizeof(ObjcIvarDecl*));
+  }
+}
+
 /// addObjcMethods - Insert instance and methods declarations into
 /// ObjcInterfaceDecl's InsMethods and ClsMethods fields.
 ///

Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=42360&r1=42359&r2=42360&view=diff

==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Wed Sep 26 13:27:25 2007
@@ -386,6 +386,10 @@
 
   virtual void ObjcAddMethodsToClass(DeclTy *ClassDecl, 
 				     DeclTy **allMethods, unsigned allNum);
+  
+  virtual void ActOnImpleIvarVsClassIvars(DeclTy *ClassDecl,
+                                          DeclTy **Fields, unsigned NumFields);
+  
   virtual DeclTy *ObjcBuildMethodDeclaration(SourceLocation MethodLoc, 
 	            tok::TokenKind MethodType, TypeTy *ReturnType,
      		    ObjcKeywordDecl *Keywords, unsigned NumKeywords, 

Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=42360&r1=42359&r2=42360&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Wed Sep 26 13:27:25 2007
@@ -1129,6 +1129,51 @@
   return IMPDecl;
 }
 
+void Sema::ActOnImpleIvarVsClassIvars(DeclTy *ClassDecl,
+                                      DeclTy **Fields, unsigned numIvars) {
+  ObjcInterfaceDecl* IDecl = 
+    cast<ObjcInterfaceDecl>(static_cast<Decl*>(ClassDecl));
+  assert(IDecl && "missing named interface class decl");
+  ObjcIvarDecl** ivars = reinterpret_cast<ObjcIvarDecl**>(Fields);
+  assert(ivars && "missing @implementation ivars");
+  
+    // Check interface's Ivar list against those in the implementation.
+    // names and types must match.
+    //
+  ObjcIvarDecl** IntfIvars = IDecl->getIntfDeclIvars();
+  int IntfNumIvars = IDecl->getIntfDeclNumIvars();
+  unsigned j = 0;
+  bool err = false;
+  while (numIvars > 0 && IntfNumIvars > 0) {
+    ObjcIvarDecl* ImplIvar = ivars[j];
+    ObjcIvarDecl* ClsIvar = IntfIvars[j++];
+    assert (ImplIvar && "missing implementation ivar");
+    assert (ClsIvar && "missing class ivar");
+    if (ImplIvar->getCanonicalType() != ClsIvar->getCanonicalType()) {
+      Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_type,
+           ImplIvar->getIdentifier()->getName());
+      Diag(ClsIvar->getLocation(), diag::err_previous_definition,
+           ClsIvar->getIdentifier()->getName());
+    }
+    // TODO: Two mismatched (unequal width) Ivar bitfields should be diagnosed 
+    // as error.
+    else if (ImplIvar->getIdentifier() != ClsIvar->getIdentifier()) {
+      Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_name,
+           ImplIvar->getIdentifier()->getName());
+      Diag(ClsIvar->getLocation(), diag::err_previous_definition,
+           ClsIvar->getIdentifier()->getName());
+      err = true;
+      break;
+    }
+    --numIvars;
+    --IntfNumIvars;
+  }
+  if (!err && (numIvars > 0 || IntfNumIvars > 0))
+    Diag(numIvars > 0 ? ivars[j]->getLocation() : IntfIvars[j]->getLocation(), 
+         diag::err_inconsistant_ivar);
+      
+}
+
 /// ObjcClassDeclaration - 
 /// Scope will always be top level file scope. 
 Action::DeclTy *
@@ -1463,8 +1508,20 @@
   else {
     ObjcIvarDecl **ClsFields = 
                     reinterpret_cast<ObjcIvarDecl**>(&RecFields[0]);
-    cast<ObjcInterfaceDecl>(static_cast<Decl*>(RecDecl))->
-      ObjcAddInstanceVariablesToClass(ClsFields, RecFields.size());
+    if (isa<ObjcInterfaceDecl>(static_cast<Decl*>(RecDecl)))
+      cast<ObjcInterfaceDecl>(static_cast<Decl*>(RecDecl))->
+        ObjcAddInstanceVariablesToClass(ClsFields, RecFields.size());
+    else if (isa<ObjcImplementationDecl>(static_cast<Decl*>(RecDecl))) {
+      ObjcImplementationDecl* IMPDecl = 
+	cast<ObjcImplementationDecl>(static_cast<Decl*>(RecDecl));
+      assert(IMPDecl && "ActOnFields - missing ObjcImplementationDecl");
+      IMPDecl->ObjcAddInstanceVariablesToClassImpl(ClsFields, RecFields.size());
+      ObjcInterfaceDecl* IDecl = 
+        Context.getObjCInterfaceDecl(IMPDecl->getIdentifier());
+      if (IDecl)
+        ActOnImpleIvarVsClassIvars(static_cast<DeclTy*>(IDecl), 
+          reinterpret_cast<DeclTy**>(&RecFields[0]), RecFields.size());
+    }
   }
 }
 

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=42360&r1=42359&r2=42360&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Wed Sep 26 13:27:25 2007
@@ -587,6 +587,9 @@
       NumIntfRefProtocols = numRefProtos;
     }
   }
+  ObjcIvarDecl **getIntfDeclIvars() const { return Ivars; }
+  int getIntfDeclNumIvars() const { return NumIvars; }
+  
   void ObjcAddInstanceVariablesToClass(ObjcIvarDecl **ivars, 
 				       unsigned numIvars);
 
@@ -883,8 +886,8 @@
       Ivars(0), NumIvars(-1),
       InsMethods(0), NumInsMethods(-1), ClsMethods(0), NumClsMethods(-1) {}
   
-  void ObjcAddInstanceVariablesToClass(ObjcIvarDecl **ivars, 
-                                       unsigned numIvars);
+  void ObjcAddInstanceVariablesToClassImpl(ObjcIvarDecl **ivars, 
+                                           unsigned numIvars);
     
   void ObjcAddMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers,
                         ObjcMethodDecl **clsMethods, unsigned numClsMembers);

Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=42360&r1=42359&r2=42360&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Sep 26 13:27:25 2007
@@ -426,6 +426,13 @@
      "reimplementation of class '%0'")
 DIAG(err_conflicting_super_class, ERROR,
      "conflicting super class name '%0'")
+DIAG(err_conflicting_ivar_name, ERROR,
+     "conflicting instance variable name '%0'")
+DIAG(err_inconsistant_ivar, ERROR,
+     "inconsistent instance variable specification")
+DIAG(err_conflicting_ivar_type, ERROR,
+     "conflicting instance variable type")
+
 
 //===----------------------------------------------------------------------===//
 // Semantic Analysis

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=42360&r1=42359&r2=42360&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Wed Sep 26 13:27:25 2007
@@ -448,6 +448,10 @@
 				     DeclTy **allMethods, unsigned allNum) {
     return;
   }
+  virtual void ActOnImpleIvarVsClassIvars(DeclTy *ClassDecl,
+                                          DeclTy **Fields, unsigned NumFields) {
+    return;
+  }
   virtual DeclTy *ObjcStartProtoInterface(Scope* S,
 		    SourceLocation AtProtoInterfaceLoc,
                     IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,

Added: cfe/trunk/test/Sema/conflicting-ivar-test-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/conflicting-ivar-test-1.m?rev=42360&view=auto

==============================================================================
--- cfe/trunk/test/Sema/conflicting-ivar-test-1.m (added)
+++ cfe/trunk/test/Sema/conflicting-ivar-test-1.m Wed Sep 26 13:27:25 2007
@@ -0,0 +1,84 @@
+ at interface INTF 
+{
+ at public
+	int IVAR; // expected-error {{previous definition is here}}
+}
+ at end
+
+ at implementation INTF
+{
+ at private
+
+        int XIVAR; // expected-error {{conflicting instance variable name 'XIVAR'}}
+}
+ at end
+
+
+
+ at interface INTF1 
+{
+ at public
+	int IVAR;
+	int IVAR1; // expected-error {{inconsistent instance variable specification}}
+}
+ at end
+
+ at implementation INTF1
+{
+ at private
+
+        int IVAR;
+}
+ at end
+
+
+ at interface INTF2 
+{
+ at public
+	int IVAR;
+}
+ at end
+
+ at implementation INTF2
+{
+ at private
+
+        int IVAR;
+	int IVAR1; // expected-error {{inconsistent instance variable specification}}
+}
+ at end
+
+
+ at interface INTF3
+{
+ at public
+	int IVAR; // expected-error {{previous definition is here}}
+}
+ at end
+
+ at implementation INTF3
+{
+ at private
+
+        short IVAR; // expected-error {{conflicting instance variable type}}
+}
+ at end
+
+ at implementation  INTF4 // expected-warning {{cannot find interface declaration for 'INTF4'}}
+{
+ at private
+
+        short IVAR;
+}
+ at end
+
+ at interface INTF5
+{
+  char * ch;
+}
+ at end
+
+ at implementation  INTF5
+{
+}
+ at end





More information about the cfe-commits mailing list