From bd94d442f6801a4d2a25d53c1843690533180a6d Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 19 Feb 2010 20:58:54 +0000 Subject: [PATCH] Start supporting declaration of ivars in @implementation blocks. WIP. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96696 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 6 ++++++ lib/Sema/SemaDeclObjC.cpp | 21 ++++++++++++++++++++- test/SemaObjC/ivar-in-implementations.m | 22 ++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 test/SemaObjC/ivar-in-implementations.m diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index a8b295abb2..682f20348d 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -253,6 +253,12 @@ def err_dup_implementation_category : Error< "reimplementation of category %1 for class %0">; def err_conflicting_ivar_type : Error< "instance variable %0 has conflicting type: %1 vs %2">; +def err_duplicate_ivar_declaration : Error< + "instance variable is already declared">; +def warn_on_superclass_use : Warning< + "class implementation may not have super class">; +def err_non_private_ivar_declaration : Error< + "only private ivars may be declared in implementation">; def err_conflicting_ivar_bitwidth : Error< "instance variable %0 has conflicting bit-field width">; def err_conflicting_ivar_name : Error< diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index cd64e66481..5f69dc4462 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -836,7 +836,26 @@ void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, return; assert(ivars && "missing @implementation ivars"); - + if (LangOpts.ObjCNonFragileABI2) { + if (ImpDecl->getSuperClass()) + Diag(ImpDecl->getLocation(), diag::warn_on_superclass_use); + for (unsigned i = 0; i < numIvars; i++) { + ObjCIvarDecl* ImplIvar = ivars[i]; + if (const ObjCIvarDecl *ClsIvar = + IDecl->getIvarDecl(ImplIvar->getIdentifier())) { + Diag(ImplIvar->getLocation(), diag::err_duplicate_ivar_declaration); + Diag(ClsIvar->getLocation(), diag::note_previous_definition); + continue; + } + if (ImplIvar->getAccessControl() != ObjCIvarDecl::Private) + Diag(ImplIvar->getLocation(), diag::err_non_private_ivar_declaration); + // Instance ivar to Implementation's DeclContext. + ImplIvar->setLexicalDeclContext(ImpDecl); + IDecl->makeDeclVisibleInContext(ImplIvar, false); + ImpDecl->addDecl(ImplIvar); + } + return; + } // Check interface's Ivar list against those in the implementation. // names and types must match. // diff --git a/test/SemaObjC/ivar-in-implementations.m b/test/SemaObjC/ivar-in-implementations.m new file mode 100644 index 0000000000..32d3c353d0 --- /dev/null +++ b/test/SemaObjC/ivar-in-implementations.m @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-nonfragile-abi2 -verify %s + +@interface Super @end + +@interface INTFSTANDALONE : Super +{ + id IVAR; // expected-note {{previous definition is here}} +} + +@end + +@implementation INTFSTANDALONE : Super // expected-warning {{class implementation may not have super class}} +{ +@private + id IVAR1; +@protected + id IVAR2; // expected-error {{only private ivars may be declared in implementation}} +@private + id IVAR3; + int IVAR; // expected-error {{instance variable is already declared}} +} +@end -- 2.40.0