From 629aed9327049b57d609cf8795bc2a54ce1afee8 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Sat, 21 Mar 2009 18:06:45 +0000 Subject: [PATCH] Issue error if variables are defined inside an objc class, category or protocol. llvm-svn: 67450 --- clang/include/clang/AST/DeclObjC.h | 15 +----------- .../clang/Basic/DiagnosticSemaKinds.def | 2 ++ .../clang/Basic/DiagnosticSemaKinds.td | 2 ++ clang/lib/CodeGen/CodeGenModule.cpp | 14 +++-------- clang/lib/Sema/SemaDeclObjC.cpp | 18 +++++++------- .../test/CodeGenObjC/interface-tu-variable.m | 24 ------------------- clang/test/SemaObjC/interface-tu-variable.m | 21 ++++++++++++++++ 7 files changed, 39 insertions(+), 57 deletions(-) delete mode 100644 clang/test/CodeGenObjC/interface-tu-variable.m create mode 100644 clang/test/SemaObjC/interface-tu-variable.m diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index cab61fc86932..5002a929c718 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -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 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::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. diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.def b/clang/include/clang/Basic/DiagnosticSemaKinds.def index 0cacb77cc9a3..819a456c5bd4 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.def +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.def @@ -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 diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 0518094e4c5d..f3961844db86 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -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< diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 93bf6dd8f00f..b259a5dc2cf8 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -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(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(D)); + Runtime->GenerateProtocol(cast(D)); break; - } case Decl::ObjCCategoryImpl: // Categories have properties but don't support synthesize so we diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 931413416156..ba35333fe52c 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -1339,14 +1339,16 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl, } } } - llvm::SmallVector allTUVariables; - for (unsigned i = 0; i < tuvNum; i++) { - if (VarDecl *VD = dyn_cast((Decl*)allTUVars[i])) - allTUVariables.push_back(VD); - } - if (!allTUVariables.empty() && isInterfaceDeclKind) { - ObjCContainerDecl *OCD = dyn_cast(ClassDecl); - OCD->setTUVarList(&allTUVariables[0], allTUVariables.size(), Context); + if (isInterfaceDeclKind) + for (unsigned i = 0; i < tuvNum; i++) { + if (VarDecl *VDecl = dyn_cast((Decl*)allTUVars[i])) { + if (VDecl->getStorageClass() != VarDecl::Extern && + VDecl->getStorageClass() != VarDecl::PrivateExtern) { + NamedDecl *ClassNameDecl = dyn_cast(ClassDecl); + Diag(VDecl->getLocation(), diag::err_objc_var_decl_inclass) + << ClassNameDecl->getIdentifier(); + } + } } } diff --git a/clang/test/CodeGenObjC/interface-tu-variable.m b/clang/test/CodeGenObjC/interface-tu-variable.m deleted file mode 100644 index 423a05f6dbc1..000000000000 --- a/clang/test/CodeGenObjC/interface-tu-variable.m +++ /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/clang/test/SemaObjC/interface-tu-variable.m b/clang/test/SemaObjC/interface-tu-variable.m new file mode 100644 index 000000000000..f9929964d3bf --- /dev/null +++ b/clang/test/SemaObjC/interface-tu-variable.m @@ -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; +} +