diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2007-09-26 18:27:25 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2007-09-26 18:27:25 +0000 |
commit | d0b90bff98bafb72ea9809f509bf37c93c60e74e (patch) | |
tree | d24b1c4e75fd7cca92f339e0735ef44e6c33e201 /Sema/SemaDecl.cpp | |
parent | 095ffca8c5f69df5826fea8714b7f50a1313d7c6 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42360 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'Sema/SemaDecl.cpp')
-rw-r--r-- | Sema/SemaDecl.cpp | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 5470eb456b..1fb4142796 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -1129,6 +1129,51 @@ Sema::DeclTy *Sema::ObjcStartClassImplementation(Scope *S, 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 @@ void Sema::ActOnFields(SourceLocation RecLoc, DeclTy *RecDecl, 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()); + } } } |