[cfe-commits] r42360 - in /cfe/trunk: AST/Decl.cpp Sema/Sema.h Sema/SemaDecl.cpp include/clang/AST/Decl.h include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Action.h test/Sema/conflicting-ivar-test-1.m
Fariborz Jahanian
fjahanian at apple.com
Wed Sep 26 11:27:26 PDT 2007
Author: fjahanian
Date: Wed Sep 26 13:27:25 2007
New Revision: 42360
URL: http://llvm.org/viewvc/llvm-project?rev=42360&view=rev
Log:
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.
Added:
cfe/trunk/test/Sema/conflicting-ivar-test-1.m
Modified:
cfe/trunk/AST/Decl.cpp
cfe/trunk/Sema/Sema.h
cfe/trunk/Sema/SemaDecl.cpp
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/trunk/include/clang/Parse/Action.h
Modified: cfe/trunk/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Decl.cpp?rev=42360&r1=42359&r2=42360&view=diff
==============================================================================
--- cfe/trunk/AST/Decl.cpp (original)
+++ cfe/trunk/AST/Decl.cpp Wed Sep 26 13:27:25 2007
@@ -294,6 +294,19 @@
}
}
+/// 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.
///
Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=42360&r1=42359&r2=42360&view=diff
==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Wed Sep 26 13:27:25 2007
@@ -386,6 +386,10 @@
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,
Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=42360&r1=42359&r2=42360&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Wed Sep 26 13:27:25 2007
@@ -1129,6 +1129,51 @@
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 @@
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());
+ }
}
}
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=42360&r1=42359&r2=42360&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Wed Sep 26 13:27:25 2007
@@ -587,6 +587,9 @@
NumIntfRefProtocols = numRefProtos;
}
}
+ ObjcIvarDecl **getIntfDeclIvars() const { return Ivars; }
+ int getIntfDeclNumIvars() const { return NumIvars; }
+
void ObjcAddInstanceVariablesToClass(ObjcIvarDecl **ivars,
unsigned numIvars);
@@ -883,8 +886,8 @@
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);
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=42360&r1=42359&r2=42360&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Sep 26 13:27:25 2007
@@ -426,6 +426,13 @@
"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
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=42360&r1=42359&r2=42360&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Wed Sep 26 13:27:25 2007
@@ -448,6 +448,10 @@
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,
Added: cfe/trunk/test/Sema/conflicting-ivar-test-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/conflicting-ivar-test-1.m?rev=42360&view=auto
==============================================================================
--- cfe/trunk/test/Sema/conflicting-ivar-test-1.m (added)
+++ cfe/trunk/test/Sema/conflicting-ivar-test-1.m Wed Sep 26 13:27:25 2007
@@ -0,0 +1,84 @@
+ at interface INTF
+{
+ at public
+ int IVAR; // expected-error {{previous definition is here}}
+}
+ at end
+
+ at implementation INTF
+{
+ at private
+
+ int XIVAR; // expected-error {{conflicting instance variable name 'XIVAR'}}
+}
+ at end
+
+
+
+ at interface INTF1
+{
+ at public
+ int IVAR;
+ int IVAR1; // expected-error {{inconsistent instance variable specification}}
+}
+ at end
+
+ at implementation INTF1
+{
+ at private
+
+ int IVAR;
+}
+ at end
+
+
+ at interface INTF2
+{
+ at public
+ int IVAR;
+}
+ at end
+
+ at implementation INTF2
+{
+ at private
+
+ int IVAR;
+ int IVAR1; // expected-error {{inconsistent instance variable specification}}
+}
+ at end
+
+
+ at interface INTF3
+{
+ at public
+ int IVAR; // expected-error {{previous definition is here}}
+}
+ at end
+
+ at implementation INTF3
+{
+ at private
+
+ short IVAR; // expected-error {{conflicting instance variable type}}
+}
+ at end
+
+ at implementation INTF4 // expected-warning {{cannot find interface declaration for 'INTF4'}}
+{
+ at private
+
+ short IVAR;
+}
+ at end
+
+ at interface INTF5
+{
+ char * ch;
+}
+ at end
+
+ at implementation INTF5
+{
+}
+ at end
More information about the cfe-commits
mailing list