aboutsummaryrefslogtreecommitdiff
path: root/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2007-09-26 18:27:25 +0000
committerFariborz Jahanian <fjahanian@apple.com>2007-09-26 18:27:25 +0000
commitd0b90bff98bafb72ea9809f509bf37c93c60e74e (patch)
treed24b1c4e75fd7cca92f339e0735ef44e6c33e201 /Sema/SemaDecl.cpp
parent095ffca8c5f69df5826fea8714b7f50a1313d7c6 (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.cpp61
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());
+ }
}
}