}
}
+/// ObjcAddInstanceVariablesToClassImpl - Checks for correctness of Instance
+/// Variables (Ivars) relative to what declared in @implementation;s class.
+/// Ivars into ObjcImplementationDecl's fields.
+///
+void ObjcImplementationDecl::ObjcAddInstanceVariablesToClassImpl(
+ ObjcIvarDecl **ivars, unsigned numIvars) {
+ NumIvars = numIvars;
+ if (numIvars) {
+ Ivars = new ObjcIvarDecl*[numIvars];
+ memcpy(Ivars, ivars, numIvars*sizeof(ObjcIvarDecl*));
+ }
+}
+
/// addObjcMethods - Insert instance and methods declarations into
/// ObjcInterfaceDecl's InsMethods and ClsMethods fields.
///
virtual void ObjcAddMethodsToClass(DeclTy *ClassDecl,
DeclTy **allMethods, unsigned allNum);
+
+ virtual void ActOnImpleIvarVsClassIvars(DeclTy *ClassDecl,
+ DeclTy **Fields, unsigned NumFields);
+
virtual DeclTy *ObjcBuildMethodDeclaration(SourceLocation MethodLoc,
tok::TokenKind MethodType, TypeTy *ReturnType,
ObjcKeywordDecl *Keywords, unsigned NumKeywords,
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 *
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());
+ }
}
}
NumIntfRefProtocols = numRefProtos;
}
}
+ ObjcIvarDecl **getIntfDeclIvars() const { return Ivars; }
+ int getIntfDeclNumIvars() const { return NumIvars; }
+
void ObjcAddInstanceVariablesToClass(ObjcIvarDecl **ivars,
unsigned numIvars);
Ivars(0), NumIvars(-1),
InsMethods(0), NumInsMethods(-1), ClsMethods(0), NumClsMethods(-1) {}
- void ObjcAddInstanceVariablesToClass(ObjcIvarDecl **ivars,
- unsigned numIvars);
+ void ObjcAddInstanceVariablesToClassImpl(ObjcIvarDecl **ivars,
+ unsigned numIvars);
void ObjcAddMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers,
ObjcMethodDecl **clsMethods, unsigned numClsMembers);
"reimplementation of class '%0'")
DIAG(err_conflicting_super_class, ERROR,
"conflicting super class name '%0'")
+DIAG(err_conflicting_ivar_name, ERROR,
+ "conflicting instance variable name '%0'")
+DIAG(err_inconsistant_ivar, ERROR,
+ "inconsistent instance variable specification")
+DIAG(err_conflicting_ivar_type, ERROR,
+ "conflicting instance variable type")
+
//===----------------------------------------------------------------------===//
// Semantic Analysis
DeclTy **allMethods, unsigned allNum) {
return;
}
+ virtual void ActOnImpleIvarVsClassIvars(DeclTy *ClassDecl,
+ DeclTy **Fields, unsigned NumFields) {
+ return;
+ }
virtual DeclTy *ObjcStartProtoInterface(Scope* S,
SourceLocation AtProtoInterfaceLoc,
IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
--- /dev/null
+@interface INTF
+{
+@public
+ int IVAR; // expected-error {{previous definition is here}}
+}
+@end
+
+@implementation INTF
+{
+@private
+
+ int XIVAR; // expected-error {{conflicting instance variable name 'XIVAR'}}
+}
+@end
+
+
+
+@interface INTF1
+{
+@public
+ int IVAR;
+ int IVAR1; // expected-error {{inconsistent instance variable specification}}
+}
+@end
+
+@implementation INTF1
+{
+@private
+
+ int IVAR;
+}
+@end
+
+
+@interface INTF2
+{
+@public
+ int IVAR;
+}
+@end
+
+@implementation INTF2
+{
+@private
+
+ int IVAR;
+ int IVAR1; // expected-error {{inconsistent instance variable specification}}
+}
+@end
+
+
+@interface INTF3
+{
+@public
+ int IVAR; // expected-error {{previous definition is here}}
+}
+@end
+
+@implementation INTF3
+{
+@private
+
+ short IVAR; // expected-error {{conflicting instance variable type}}
+}
+@end
+
+@implementation INTF4 // expected-warning {{cannot find interface declaration for 'INTF4'}}
+{
+@private
+
+ short IVAR;
+}
+@end
+
+@interface INTF5
+{
+ char * ch;
+}
+@end
+
+@implementation INTF5
+{
+}
+@end