]> granicus.if.org Git - clang/commitdiff
Issue error if variables are defined inside an objc class,
authorFariborz Jahanian <fjahanian@apple.com>
Sat, 21 Mar 2009 18:06:45 +0000 (18:06 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Sat, 21 Mar 2009 18:06:45 +0000 (18:06 +0000)
category or protocol.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67450 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclObjC.h
include/clang/Basic/DiagnosticSemaKinds.def
include/clang/Basic/DiagnosticSemaKinds.td
lib/CodeGen/CodeGenModule.cpp
lib/Sema/SemaDeclObjC.cpp
test/CodeGenObjC/interface-tu-variable.m [deleted file]
test/SemaObjC/interface-tu-variable.m [new file with mode: 0644]

index cab61fc86932363f96022bfa15bac52024236288..5002a929c718bc39ba48688c872d31b8601939ce 100644 (file)
@@ -246,11 +246,6 @@ public:
 ///
 class ObjCContainerDecl : public NamedDecl, public DeclContext {
   SourceLocation AtEndLoc; // marks the end of the method container.
-  // FIXME. In the long term, all TU variables declared in class scope belong
-  // to class's decl context. This waits till we can establish class's
-  // context before processing all decls in the class.
-  /// Instance variables in the interface.
-  ObjCList<VarDecl> TUVars;
 public:
 
   ObjCContainerDecl(Kind DK, DeclContext *DC, SourceLocation L, 
@@ -303,15 +298,7 @@ public:
   ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const {
     return isInstance ? getInstanceMethod(Sel) : getClassMethod(Sel);
   }
-  
-  typedef ObjCList<VarDecl>::iterator tuvar_iterator;
-  tuvar_iterator tuvar_begin() const { return TUVars.begin(); }
-  tuvar_iterator tuvar_end() const { return TUVars.end(); }
-  unsigned tuvar_size() const { return TUVars.size(); }
-  void setTUVarList(VarDecl * const *List, unsigned Num, ASTContext &C) {
-    TUVars.set(List, Num, C);
-  }
-  
+    
   ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
 
   // Marks the end of the container.
index 0cacb77cc9a32b24b372d39adb8fe6e684576a3c..819a456c5bd4a72e7a2fbabea0e1a9d0179d9c03 100644 (file)
@@ -1025,6 +1025,8 @@ DIAG(err_illegal_qualifiers_on_catch_parm, ERROR,
      "illegal qualifiers on @catch parameter")
 DIAG(err_illegal_super_cast, ERROR,
      "cannot cast 'super' (it isn't an expression)")
+DIAG(err_objc_var_decl_inclass, ERROR,
+     "cannot declare variable inside a class, protocol or category %0")
 
 
 // C++ casts
index 0518094e4c5d6a2c6c99b4c0143ecad473602598..f3961844db860edb8c3cddfc17e56b5a272ca57b 100644 (file)
@@ -161,6 +161,8 @@ def err_accessor_property_type_mismatch : Error<
 def note_declared_at : Note<"declared at">;
 def err_setter_type_void : Error<"type of setter must be void">;
 def err_duplicate_method_decl : Error<"duplicate declaration of method %0">;
+def err_objc_var_decl_inclass : 
+    Error<"cannot declare variable inside a class, protocol or category %0">;
 def error_missing_method_context : Error<
   "missing context for method declaration">;
 def err_objc_property_attr_mutually_exclusive : Error<
index 93bf6dd8f00fc139fe8d8d39885b2b34d3b027ea..b259a5dc2cf897ecfd14fd13d03a4e16120815dd 100644 (file)
@@ -1270,21 +1270,13 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
   // Forward declarations, no (immediate) code generation.
   case Decl::ObjCClass:
   case Decl::ObjCForwardProtocol:
+  case Decl::ObjCCategory:
+  case Decl::ObjCInterface:
     break;
       
   case Decl::ObjCProtocol:
-  case Decl::ObjCCategory:
-  case Decl::ObjCInterface: {
-    ObjCContainerDecl *OCD = cast<ObjCContainerDecl>(D);
-    for (ObjCContainerDecl::tuvar_iterator i = OCD->tuvar_begin(),
-         e = OCD->tuvar_end(); i != e; ++i) {
-        VarDecl *VD = *i;
-        EmitGlobal(VD);
-    }
-    if (D->getKind() == Decl::ObjCProtocol) 
-      Runtime->GenerateProtocol(cast<ObjCProtocolDecl>(D));
+    Runtime->GenerateProtocol(cast<ObjCProtocolDecl>(D));
     break;
-  }
 
   case Decl::ObjCCategoryImpl:
     // Categories have properties but don't support synthesize so we
index 931413416156e071c0dc34193037a93df5ee8833..ba35333fe52c0c4ef5eba425e8e51158ac0f00a1 100644 (file)
@@ -1339,14 +1339,16 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
       }
     }
   }
-  llvm::SmallVector<VarDecl*, 8> allTUVariables;
-  for (unsigned i = 0; i < tuvNum; i++) {
-    if (VarDecl *VD = dyn_cast<VarDecl>((Decl*)allTUVars[i]))
-      allTUVariables.push_back(VD);
-  }
-  if (!allTUVariables.empty() && isInterfaceDeclKind) {
-    ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(ClassDecl);
-    OCD->setTUVarList(&allTUVariables[0], allTUVariables.size(), Context);
+  if (isInterfaceDeclKind)
+    for (unsigned i = 0; i < tuvNum; i++) {
+      if (VarDecl *VDecl = dyn_cast<VarDecl>((Decl*)allTUVars[i])) {
+        if (VDecl->getStorageClass() != VarDecl::Extern &&
+            VDecl->getStorageClass() != VarDecl::PrivateExtern) {
+          NamedDecl  *ClassNameDecl = dyn_cast<NamedDecl>(ClassDecl);
+          Diag(VDecl->getLocation(), diag::err_objc_var_decl_inclass) 
+            << ClassNameDecl->getIdentifier();
+        }
+     }
   }
 }
 
diff --git a/test/CodeGenObjC/interface-tu-variable.m b/test/CodeGenObjC/interface-tu-variable.m
deleted file mode 100644 (file)
index 423a05f..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: clang -fnext-runtime -emit-llvm -o %t %s
-// RUN: grep 'two = global' %t &&
-// RUN: grep 'ddd = common' %t &&
-// RUN: grep 'III = common' %t
-
-@interface XX
-int x; 
-int one=1; 
-int two = 2; 
-@end
-
-@protocol PPP
-int ddd;
-@end
-
-@interface XX(CAT)
-  char * III;
-@end
-
-
-int main( int argc, const char *argv[] ) {
-    return x+one+two;
-}
-
diff --git a/test/SemaObjC/interface-tu-variable.m b/test/SemaObjC/interface-tu-variable.m
new file mode 100644 (file)
index 0000000..f992996
--- /dev/null
@@ -0,0 +1,21 @@
+// RUN: clang -fsyntax-only -verify %s
+
+@interface XX
+int x;  // expected-error {{cannot declare variable inside a class, protocol or category}}
+int one=1;  // expected-error {{cannot declare variable inside a class, protocol or category}}
+@end
+
+@protocol PPP
+int ddd; // expected-error {{cannot declare variable inside a class, protocol or category}}
+@end
+
+@interface XX(CAT)
+  char * III; // expected-error {{cannot declare variable inside a class, protocol or category}}
+  extern int OK;
+@end
+
+
+int main( int argc, const char *argv[] ) {
+    return x+one;
+}
+