[cfe-commits] r43995 - in /cfe/trunk: AST/Decl.cpp Driver/RewriteTest.cpp Parse/ParseObjc.cpp Parse/Parser.cpp Sema/Sema.h Sema/SemaDecl.cpp include/clang/AST/DeclObjC.h include/clang/Parse/Action.h include/clang/Parse/Parser.h test/Sema/message.m
Steve Naroff
snaroff at apple.com
Sun Nov 11 09:19:15 PST 2007
Author: snaroff
Date: Sun Nov 11 11:19:15 2007
New Revision: 43995
URL: http://llvm.org/viewvc/llvm-project?rev=43995&view=rev
Log:
This is the last 5% of the solution to teaching Sema::ActOnInstanceMessage() about private methods (r43989).
While the diff is large, the idea is very simple. When we parse method definitions (in an @implementation), we need to add them incrementally (rather than wait until the @end).
Other details...
- Renamed Sema::ActOnAddMethodsToObjcDecl() to Sema::ActOnAtEnd(). The methods are now optional arguments.
- Removed Parser::AllImplMethods (a nice cleanup).
- Added location info to ObjcImplementationDecl (since we will need it very soon:-)
- Modified message.m test to no longer allow the bogus diagnostic.
Modified:
cfe/trunk/AST/Decl.cpp
cfe/trunk/Driver/RewriteTest.cpp
cfe/trunk/Parse/ParseObjc.cpp
cfe/trunk/Parse/Parser.cpp
cfe/trunk/Sema/Sema.h
cfe/trunk/Sema/SemaDecl.cpp
cfe/trunk/include/clang/AST/DeclObjC.h
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/test/Sema/message.m
Modified: cfe/trunk/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Decl.cpp?rev=43995&r1=43994&r2=43995&view=diff
==============================================================================
--- cfe/trunk/AST/Decl.cpp (original)
+++ cfe/trunk/AST/Decl.cpp Sun Nov 11 11:19:15 2007
@@ -408,26 +408,6 @@
}
}
-/// ObjcAddImplMethods - Insert instance and methods declarations into
-/// ObjcImplementationDecl's InsMethods and ClsMethods fields.
-///
-void ObjcImplementationDecl::addMethods(ObjcMethodDecl **insMethods,
- unsigned numInsMembers,
- ObjcMethodDecl **clsMethods,
- unsigned numClsMembers,
- SourceLocation AtEndLoc) {
- NumInstanceMethods = numInsMembers;
- if (numInsMembers) {
- InstanceMethods = new ObjcMethodDecl*[numInsMembers];
- memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjcMethodDecl*));
- }
- NumClassMethods = numClsMembers;
- if (numClsMembers) {
- ClassMethods = new ObjcMethodDecl*[numClsMembers];
- memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjcMethodDecl*));
- }
-}
-
// lookupInstanceMethod - This method returns an instance method by looking in
// the class, it's categories, and it's super classes (using a linear search).
ObjcMethodDecl *ObjcInterfaceDecl::lookupInstanceMethod(Selector &Sel) {
@@ -514,7 +494,7 @@
// the class implementation. Unlike interfaces, we don't look outside the
// implementation.
ObjcMethodDecl *ObjcImplementationDecl::lookupInstanceMethod(Selector &Sel) {
- ObjcMethodDecl **methods = getInstanceMethods();
+ ObjcMethodDecl *const*methods = getInstanceMethods();
int methodCount = getNumInstanceMethods();
for (int i = 0; i < methodCount; ++i) {
if (methods[i]->getSelector() == Sel) {
@@ -528,7 +508,7 @@
// the class implementation. Unlike interfaces, we don't look outside the
// implementation.
ObjcMethodDecl *ObjcImplementationDecl::lookupClassMethod(Selector &Sel) {
- ObjcMethodDecl **methods = getClassMethods();
+ ObjcMethodDecl *const*methods = getClassMethods();
int methodCount = getNumClassMethods();
for (int i = 0; i < methodCount; ++i) {
if (methods[i]->getSelector() == Sel) {
Modified: cfe/trunk/Driver/RewriteTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/RewriteTest.cpp?rev=43995&r1=43994&r2=43995&view=diff
==============================================================================
--- cfe/trunk/Driver/RewriteTest.cpp (original)
+++ cfe/trunk/Driver/RewriteTest.cpp Sun Nov 11 11:19:15 2007
@@ -118,7 +118,7 @@
void RewriteObjcCategoryImplDecl(ObjcCategoryImplDecl *CDecl,
std::string &Result);
- void RewriteObjcMethodsMetaData(ObjcMethodDecl **Methods,
+ void RewriteObjcMethodsMetaData(ObjcMethodDecl *const*Methods,
int NumMethods,
bool IsInstanceMethod,
const char *prefix,
@@ -1039,7 +1039,7 @@
// RewriteObjcMethodsMetaData - Rewrite methods metadata for instance or
/// class methods.
-void RewriteTest::RewriteObjcMethodsMetaData(ObjcMethodDecl **Methods,
+void RewriteTest::RewriteObjcMethodsMetaData(ObjcMethodDecl *const*Methods,
int NumMethods,
bool IsInstanceMethod,
const char *prefix,
Modified: cfe/trunk/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseObjc.cpp?rev=43995&r1=43994&r2=43995&view=diff
==============================================================================
--- cfe/trunk/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/Parse/ParseObjc.cpp Sun Nov 11 11:19:15 2007
@@ -275,12 +275,8 @@
}
}
/// Insert collected methods declarations into the @interface object.
- /// This action is executed even if we don't have any methods (so the @end
- /// can be recorded properly).
- Actions.ActOnAddMethodsToObjcDecl(CurScope, interfaceDecl, &allMethods[0],
- allMethods.size(),
- &allProperties[0], allProperties.size(),
- AtEndLoc);
+ Actions.ActOnAtEnd(AtEndLoc, interfaceDecl, &allMethods[0], allMethods.size(),
+ &allProperties[0], allProperties.size());
}
/// Parse property attribute declarations.
@@ -946,12 +942,7 @@
// Checking is not necessary except that a parse error might have caused
// @implementation not to have been parsed to completion and ObjcImpDecl
// could be 0.
- /// Insert collected methods declarations into the @interface object.
- Actions.ActOnAddMethodsToObjcDecl(CurScope, ObjcImpDecl,
- &AllImplMethods[0], AllImplMethods.size(),
- (DeclTy **)0, 0,
- atLoc);
- AllImplMethods.clear();
+ Actions.ActOnAtEnd(atLoc, ObjcImpDecl);
}
return ObjcImpDecl;
@@ -1151,8 +1142,6 @@
void Parser::ParseObjCInstanceMethodDefinition() {
assert(Tok.is(tok::minus) && "Method definitions should start with '-'");
DeclTy *MDecl = ParseObjCMethodPrototype(ObjcImpDecl);
- // FIXME: @optional/@protocol??
- AllImplMethods.push_back(MDecl);
// parse optional ';'
if (Tok.is(tok::semi))
ConsumeToken();
@@ -1169,8 +1158,6 @@
void Parser::ParseObjCClassMethodDefinition() {
assert(Tok.is(tok::plus) && "Class method definitions should start with '+'");
DeclTy *MDecl = ParseObjCMethodPrototype(ObjcImpDecl);
- // FIXME: @optional/@protocol??
- AllImplMethods.push_back(MDecl);
// parse optional ';'
if (Tok.is(tok::semi))
ConsumeToken();
Modified: cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/Parser.cpp?rev=43995&r1=43994&r2=43995&view=diff
==============================================================================
--- cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/trunk/Parse/Parser.cpp Sun Nov 11 11:19:15 2007
@@ -23,7 +23,6 @@
NumCachedScopes = 0;
ParenCount = BracketCount = BraceCount = 0;
ObjcImpDecl = 0;
- AllImplMethods.clear();
}
/// Out-of-line virtual destructor to provide home for Action class.
Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=43995&r1=43994&r2=43995&view=diff
==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Sun Nov 11 11:19:15 2007
@@ -541,10 +541,9 @@
llvm::SmallVector<DeclTy *, 8> &
Protocols);
- virtual void ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *ClassDecl,
- DeclTy **allMethods, unsigned allNum,
- DeclTy **allProperties, unsigned pNum,
- SourceLocation AtEndLoc);
+ virtual void ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
+ DeclTy **allMethods = 0, unsigned allNum = 0,
+ DeclTy **allProperties = 0, unsigned pNum = 0);
virtual DeclTy *ActOnAddObjcProperties(SourceLocation AtLoc,
DeclTy **allProperties,
Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=43995&r1=43994&r2=43995&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Sun Nov 11 11:19:15 2007
@@ -1576,7 +1576,7 @@
llvm::DenseSet<Selector> InsMap;
// Check and see if instance methods in class interface have been
// implemented in the implementation class.
- ObjcMethodDecl **methods = IMPDecl->getInstanceMethods();
+ ObjcMethodDecl *const*methods = IMPDecl->getInstanceMethods();
for (int i=0; i < IMPDecl->getNumInstanceMethods(); i++)
InsMap.insert(methods[i]->getSelector());
@@ -2079,10 +2079,9 @@
}
}
-void Sema::ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *classDecl,
- DeclTy **allMethods, unsigned allNum,
- DeclTy **allProperties, unsigned pNum,
- SourceLocation AtEndLoc) {
+void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
+ DeclTy **allMethods, unsigned allNum,
+ DeclTy **allProperties, unsigned pNum) {
Decl *ClassDecl = static_cast<Decl *>(classDecl);
// FIXME: If we don't have a ClassDecl, we have an error. I (snaroff) would
@@ -2164,8 +2163,7 @@
}
else if (ObjcImplementationDecl *IC =
dyn_cast<ObjcImplementationDecl>(ClassDecl)) {
- IC->addMethods(&insMethods[0], insMethods.size(),
- &clsMethods[0], clsMethods.size(), AtEndLoc);
+ IC->setLocEnd(AtEndLoc);
if (ObjcInterfaceDecl* IDecl = getObjCInterfaceDecl(IC->getIdentifier()))
ImplMethodsVsClassMethods(IC, IDecl);
} else {
@@ -2242,14 +2240,15 @@
Decl *CDecl = static_cast<Decl*>(ClassDecl);
ObjcInterfaceDecl *IDecl = 0;
+ ObjcImplementationDecl *ImpDecl = 0;
if (isa<ObjcInterfaceDecl>(CDecl))
IDecl = cast<ObjcInterfaceDecl>(CDecl);
else if (isa<ObjcCategoryDecl>(CDecl))
- IDecl = cast<ObjcCategoryDecl>(CDecl)->getClassInterface();
- else if (isa<ObjcImplementationDecl>(CDecl))
- IDecl = cast<ObjcImplementationDecl>(CDecl)->getClassInterface();
+ IDecl = cast<ObjcCategoryDecl>(CDecl)->getClassInterface(); // FIXME: what is this? (talk to fariborz)
+ else if ((ImpDecl = dyn_cast<ObjcImplementationDecl>(CDecl)))
+ IDecl = ImpDecl->getClassInterface(); // FIXME: what is this? (talk to fariborz)
else if (isa<ObjcCategoryImplDecl>(CDecl))
- IDecl = cast<ObjcCategoryImplDecl>(CDecl)->getClassInterface();
+ IDecl = cast<ObjcCategoryImplDecl>(CDecl)->getClassInterface(); // FIXME: what is this? (talk to fariborz)
ObjcMethodDecl* ObjcMethod = new ObjcMethodDecl(MethodLoc, EndLoc, Sel,
resultDeclType,
@@ -2262,6 +2261,27 @@
ObjcMethod->setMethodParams(&Params[0], Sel.getNumArgs());
ObjcMethod->setObjcDeclQualifier(
CvtQTToAstBitMask(ReturnQT.getObjcDeclQualifier()));
+ if (ImpDecl) {
+ // For implementations (which can be very "coarse grain"), we add the
+ // method now. This allows the AST to implement lookup methods that work
+ // incrementally (without waiting until we parse the @end). It also allows
+ // us to flag multiple declaration errors as they occur.
+ // FIXME: still need to do this for ObjcCategoryImplDecl.
+ const ObjcMethodDecl *PrevMethod = 0;
+ if (MethodType == tok::minus) {
+ PrevMethod = ImpDecl->lookupInstanceMethod(Sel);
+ ImpDecl->addInstanceMethod(ObjcMethod);
+ } else {
+ PrevMethod = ImpDecl->lookupClassMethod(Sel);
+ ImpDecl->addClassMethod(ObjcMethod);
+ }
+ if (PrevMethod) {
+ // You can never have two method definitions with the same name.
+ Diag(ObjcMethod->getLocation(), diag::error_duplicate_method_decl,
+ ObjcMethod->getSelector().getName());
+ Diag(PrevMethod->getLocation(), diag::err_previous_declaration);
+ }
+ }
return ObjcMethod;
}
Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=43995&r1=43994&r2=43995&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Sun Nov 11 11:19:15 2007
@@ -629,44 +629,53 @@
/// Optional Ivars/NumIvars - This is a new[]'d array of pointers to Decls.
ObjcIvarDecl **Ivars; // Null if not specified
int NumIvars; // -1 if not defined.
-
+
/// implemented instance methods
- ObjcMethodDecl **InstanceMethods; // Null if not defined
- int NumInstanceMethods; // -1 if not defined
-
+ llvm::SmallVector<ObjcMethodDecl*, 32> InstanceMethods;
+
/// implemented class methods
- ObjcMethodDecl **ClassMethods; // Null if not defined
- int NumClassMethods; // -1 if not defined
-
+ llvm::SmallVector<ObjcMethodDecl*, 32> ClassMethods;
+
+ SourceLocation EndLoc;
public:
ObjcImplementationDecl(SourceLocation L, IdentifierInfo *Id,
ObjcInterfaceDecl *classInterface,
ObjcInterfaceDecl *superDecl)
: NamedDecl(ObjcImplementation, L, Id),
- ClassInterface(classInterface),
- SuperClass(superDecl),
- Ivars(0), NumIvars(-1),
- InstanceMethods(0), NumInstanceMethods(-1),
- ClassMethods(0), NumClassMethods(-1) {}
+ ClassInterface(classInterface), SuperClass(superDecl),
+ Ivars(0), NumIvars(-1) {}
void ObjcAddInstanceVariablesToClassImpl(ObjcIvarDecl **ivars,
unsigned numIvars);
- void addMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers,
- ObjcMethodDecl **clsMethods, unsigned numClsMembers,
- SourceLocation AtEndLoc);
-
+ void addInstanceMethod(ObjcMethodDecl *method) {
+ InstanceMethods.push_back(method);
+ }
+ void addClassMethod(ObjcMethodDecl *method) {
+ ClassMethods.push_back(method);
+ }
+ // Location information, modeled after the Stmt API.
+ SourceLocation getLocStart() const { return getLocation(); }
+ SourceLocation getLocEnd() const { return EndLoc; }
+ void setLocEnd(SourceLocation LE) { EndLoc = LE; };
+
ObjcInterfaceDecl *getClassInterface() const { return ClassInterface; }
ObjcInterfaceDecl *getSuperClass() const { return SuperClass; }
void setSuperClass(ObjcInterfaceDecl * superCls)
{ SuperClass = superCls; }
- ObjcMethodDecl **getInstanceMethods() const { return InstanceMethods; }
- int getNumInstanceMethods() const { return NumInstanceMethods; }
+ // FIXME: Figure out how to remove the const pointer below.
+ ObjcMethodDecl *const*getInstanceMethods() const {
+ return &InstanceMethods[0];
+ }
+ int getNumInstanceMethods() const { return InstanceMethods.size(); }
- ObjcMethodDecl **getClassMethods() const { return ClassMethods; }
- int getNumClassMethods() const { return NumClassMethods; }
+ // FIXME: Figure out how to remove the const pointer below.
+ ObjcMethodDecl *const*getClassMethods() const {
+ return &ClassMethods[0];
+ }
+ int getNumClassMethods() const { return ClassMethods.size(); }
ObjcMethodDecl *lookupInstanceMethod(Selector &Sel);
ObjcMethodDecl *lookupClassMethod(Selector &Sel);
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=43995&r1=43994&r2=43995&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Sun Nov 11 11:19:15 2007
@@ -576,19 +576,19 @@
tok::ObjCKeywordKind impKind) {
return 0;
}
- // ActOnAddMethodsToObjcDecl - called to associate methods with an interface,
- // protocol, category, or implementation.
- virtual void ActOnAddMethodsToObjcDecl(
- Scope* S,
- DeclTy *ClassDecl,
- DeclTy **allMethods,
- unsigned allNum,
- DeclTy **allProperties,
- unsigned NumProperties,
- SourceLocation AtEndLoc) {
+ // ActOnAtEnd - called to mark the @end. For declarations (interfaces,
+ // protocols, categories), the parser passes all methods/properties.
+ // For class implementations, these values default to 0. For implementations,
+ // methods are processed incrementally (by ActOnMethodDeclaration above).
+ virtual void ActOnAtEnd(
+ SourceLocation AtEndLoc,
+ DeclTy *classDecl,
+ DeclTy **allMethods = 0,
+ unsigned allNum = 0,
+ DeclTy **allProperties = 0,
+ unsigned pNum = 0) {
return;
}
-
// ActOnAddObjcProperties - called to build one property AST
virtual DeclTy *ActOnAddObjcProperties (SourceLocation AtLoc,
DeclTy **allProperties, unsigned NumProperties, ObjcDeclSpec &DS) {
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=43995&r1=43994&r2=43995&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Sun Nov 11 11:19:15 2007
@@ -269,8 +269,7 @@
DeclTy *ParseObjCAtProtocolDeclaration(SourceLocation atLoc);
DeclTy *ObjcImpDecl;
- /// Vector is used to collect method decls for each @implementation
- llvm::SmallVector<DeclTy*, 32> AllImplMethods;
+
DeclTy *ParseObjCAtImplementationDeclaration(SourceLocation atLoc);
DeclTy *ParseObjCAtEndDeclaration(SourceLocation atLoc);
DeclTy *ParseObjCAtAliasDeclaration(SourceLocation atLoc);
Modified: cfe/trunk/test/Sema/message.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/message.m?rev=43995&r1=43994&r2=43995&view=diff
==============================================================================
--- cfe/trunk/test/Sema/message.m (original)
+++ cfe/trunk/test/Sema/message.m Sun Nov 11 11:19:15 2007
@@ -6,6 +6,6 @@
@implementation foo
- (void) contents {} // No declaration in @interface!
-- (void) meth { [self contents]; } // expected-warning {{method '-contents' not found (return type defaults to 'id')}}
+- (void) meth { [self contents]; }
@end
More information about the cfe-commits
mailing list