aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2009-01-08 17:28:14 +0000
committerSteve Naroff <snaroff@apple.com>2009-01-08 17:28:14 +0000
commit0701bbb228dfd87e1fe82a0a4b7b9facfecb43da (patch)
tree0e6483e9a1755c00b458662c0cd52c26d132b70e
parent7e5d6ed47dcedce35043de59ee00464b681bc786 (diff)
This is a large/messy diff that unifies the ObjC AST's with DeclContext.
- ObjCContainerDecl's (ObjCInterfaceDecl/ObjCCategoryDecl/ObjCProtocolDecl), ObjCCategoryImpl, & ObjCImplementation are all DeclContexts. - ObjCMethodDecl is now a ScopedDecl (so it can play nicely with DeclContext). - ObjCContainerDecl now does iteration/lookup using DeclContext infrastructure (no more linear search:-) - Removed ASTContext argument to DeclContext::lookup(). It wasn't being used and complicated it's use from an ObjC AST perspective. - Added Sema::ProcessPropertyDecl() and removed Sema::diagnosePropertySetterGetterMismatch(). - Simplified Sema::ActOnAtEnd() considerably. Still more work to do. - Fixed an incorrect casting assumption in Sema::getCurFunctionOrMethodDecl(), now that ObjCMethodDecl is a ScopedDecl. - Removed addPropertyMethods from ObjCInterfaceDecl/ObjCCategoryDecl/ObjCProtocolDecl. This passes all the tests on my machine. Since many of the changes are central to the way ObjC finds it's methods, I expect some fallout (and there are still a handful of FIXME's). Nevertheless, this should be a step in the right direction. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61929 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--Driver/RewriteObjC.cpp3
-rw-r--r--include/clang/AST/DeclBase.h40
-rw-r--r--include/clang/AST/DeclObjC.h239
-rw-r--r--lib/AST/DeclBase.cpp30
-rw-r--r--lib/AST/DeclCXX.cpp4
-rw-r--r--lib/AST/DeclObjC.cpp127
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp4
-rw-r--r--lib/Sema/IdentifierResolver.cpp2
-rw-r--r--lib/Sema/Sema.cpp2
-rw-r--r--lib/Sema/Sema.h5
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp2
-rw-r--r--lib/Sema/SemaDecl.cpp4
-rw-r--r--lib/Sema/SemaDeclCXX.cpp4
-rw-r--r--lib/Sema/SemaDeclObjC.cpp109
-rw-r--r--lib/Sema/SemaExprCXX.cpp4
-rw-r--r--lib/Sema/SemaOverload.cpp8
16 files changed, 334 insertions, 253 deletions
diff --git a/Driver/RewriteObjC.cpp b/Driver/RewriteObjC.cpp
index 801b24b9f3..f135e0475a 100644
--- a/Driver/RewriteObjC.cpp
+++ b/Driver/RewriteObjC.cpp
@@ -881,9 +881,8 @@ void RewriteObjC::RewriteObjCMethodDecl(ObjCMethodDecl *OMD,
NameStr += OMD->getClassInterface()->getNameAsString();
NameStr += "_";
- NamedDecl *MethodContext = OMD->getMethodContext();
if (ObjCCategoryImplDecl *CID =
- dyn_cast<ObjCCategoryImplDecl>(MethodContext)) {
+ dyn_cast<ObjCCategoryImplDecl>(OMD->getMethodContext())) {
NameStr += CID->getNameAsString();
NameStr += "_";
}
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 21239e377b..38d8add29d 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -31,6 +31,10 @@ class CXXRecordDecl;
class EnumDecl;
class ObjCMethodDecl;
class ObjCInterfaceDecl;
+class ObjCCategoryDecl;
+class ObjCProtocolDecl;
+class ObjCImplementationDecl;
+class ObjCCategoryImplDecl;
class LinkageSpecDecl;
class BlockDecl;
class DeclarationName;
@@ -49,14 +53,13 @@ public:
// Decl
TranslationUnit, // [DeclContext]
// NamedDecl
- // ObjCContainerDecl
+ // ObjCContainerDecl // [DeclContext]
ObjCCategory,
ObjCProtocol,
- ObjCInterface, // [DeclContext]
+ ObjCInterface,
OverloadedFunction,
- ObjCCategoryImpl,
- ObjCImplementation,
- ObjCMethod, // [DeclContext]
+ ObjCCategoryImpl, // [DeclContext]
+ ObjCImplementation, // [DeclContext]
ObjCProperty,
// ScopedDecl
Field,
@@ -84,6 +87,7 @@ public:
OriginalParmVar,
NonTypeTemplateParm,
LinkageSpec, // [DeclContext]
+ ObjCMethod, // [DeclContext]
ObjCCompatibleAlias,
ObjCClass,
ObjCForwardProtocol,
@@ -95,7 +99,7 @@ public:
// of the class, to allow efficient classof.
NamedFirst = OverloadedFunction , NamedLast = NonTypeTemplateParm,
FieldFirst = Field , FieldLast = ObjCAtDefsField,
- ScopedFirst = Field , ScopedLast = LinkageSpec,
+ ScopedFirst = Field , ScopedLast = ObjCMethod,
TypeFirst = Typedef , TypeLast = TemplateTypeParm,
TagFirst = Enum , TagLast = CXXRecord,
RecordFirst = Record , RecordLast = CXXRecord,
@@ -329,6 +333,14 @@ class DeclContext {
return static_cast<ObjCMethodDecl*>(const_cast<From*>(D));
case Decl::ObjCInterface:
return static_cast<ObjCInterfaceDecl*>(const_cast<From*>(D));
+ case Decl::ObjCCategory:
+ return static_cast<ObjCCategoryDecl*>(const_cast<From*>(D));
+ case Decl::ObjCProtocol:
+ return static_cast<ObjCProtocolDecl*>(const_cast<From*>(D));
+ case Decl::ObjCImplementation:
+ return static_cast<ObjCImplementationDecl*>(const_cast<From*>(D));
+ case Decl::ObjCCategoryImpl:
+ return static_cast<ObjCCategoryImplDecl*>(const_cast<From*>(D));
case Decl::LinkageSpec:
return static_cast<LinkageSpecDecl*>(const_cast<From*>(D));
case Decl::Block:
@@ -434,7 +446,7 @@ public:
/// a different set of declarations. This routine returns the
/// "primary" DeclContext structure, which will contain the
/// information needed to perform name lookup into this context.
- DeclContext *getPrimaryContext(ASTContext &Context);
+ DeclContext *getPrimaryContext();
/// getLookupContext - Retrieve the innermost non-transparent
/// context of this context, which corresponds to the innermost
@@ -481,7 +493,7 @@ public:
/// declaration into data structure for name lookup.
void addDecl(ASTContext &Context, ScopedDecl *D, bool AllowLookup = true);
- void buildLookup(ASTContext &Context, DeclContext *DCtx);
+ void buildLookup(DeclContext *DCtx);
/// lookup_iterator - An iterator that provides access to the results
/// of looking up a name within this context.
@@ -503,8 +515,8 @@ public:
/// declaration in the "tag" identifier namespace (e.g., values
/// before types). Note that this routine will not look into parent
/// contexts.
- lookup_result lookup(ASTContext &Context, DeclarationName Name);
- lookup_const_result lookup(ASTContext &Context, DeclarationName Name) const;
+ lookup_result lookup(DeclarationName Name);
+ lookup_const_result lookup(DeclarationName Name) const;
/// insert - Insert the declaration D into this context. Up to two
/// declarations with the same name can be inserted into a single
@@ -527,6 +539,10 @@ public:
case Decl::CXXRecord:
case Decl::ObjCMethod:
case Decl::ObjCInterface:
+ case Decl::ObjCCategory:
+ case Decl::ObjCProtocol:
+ case Decl::ObjCImplementation:
+ case Decl::ObjCCategoryImpl:
case Decl::LinkageSpec:
case Decl::Block:
return true;
@@ -546,6 +562,10 @@ public:
static bool classof(const EnumDecl *D) { return true; }
static bool classof(const ObjCMethodDecl *D) { return true; }
static bool classof(const ObjCInterfaceDecl *D) { return true; }
+ static bool classof(const ObjCCategoryDecl *D) { return true; }
+ static bool classof(const ObjCProtocolDecl *D) { return true; }
+ static bool classof(const ObjCImplementationDecl *D) { return true; }
+ static bool classof(const ObjCCategoryImplDecl *D) { return true; }
static bool classof(const LinkageSpecDecl *D) { return true; }
static bool classof(const BlockDecl *D) { return true; }
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 99c275df32..0acb88dc0d 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -93,7 +93,7 @@ public:
/// A selector represents a unique name for a method. The selector names for
/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
///
-class ObjCMethodDecl : public NamedDecl, public DeclContext {
+class ObjCMethodDecl : public ScopedDecl, public DeclContext {
public:
enum ImplementationControl { None, Required, Optional };
private:
@@ -115,7 +115,7 @@ private:
unsigned objcDeclQualifier : 6;
// Context this method is declared in.
- NamedDecl *MethodContext;
+ DeclContext *MethodContext;
// Type of this method.
QualType MethodDeclType;
@@ -140,17 +140,17 @@ private:
ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
Selector SelInfo, QualType T,
- Decl *contextDecl,
+ DeclContext *contextDecl,
bool isInstance = true,
bool isVariadic = false,
bool isSynthesized = false,
ImplementationControl impControl = None)
- : NamedDecl(ObjCMethod, beginLoc, SelInfo),
+ : ScopedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo, 0),
DeclContext(ObjCMethod),
IsInstance(isInstance), IsVariadic(isVariadic),
IsSynthesized(isSynthesized),
DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
- MethodContext(static_cast<NamedDecl*>(contextDecl)),
+ MethodContext(contextDecl),
MethodDeclType(T),
ParamInfo(0), NumMethodParams(0),
EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {}
@@ -165,7 +165,7 @@ public:
static ObjCMethodDecl *Create(ASTContext &C,
SourceLocation beginLoc,
SourceLocation endLoc, Selector SelInfo,
- QualType T, Decl *contextDecl,
+ QualType T, DeclContext *contextDecl,
bool isInstance = true,
bool isVariadic = false,
bool isSynthesized = false,
@@ -183,7 +183,7 @@ public:
return SourceRange(getLocation(), EndLoc);
}
- NamedDecl *getMethodContext() const { return MethodContext; }
+ DeclContext *getMethodContext() const { return MethodContext; }
ObjCInterfaceDecl *getClassInterface();
const ObjCInterfaceDecl *getClassInterface() const {
@@ -252,68 +252,177 @@ public:
/// ObjCContainerDecl - Represents a container for method declarations.
/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl, and
-/// ObjCProtocolDecl. FIXME: Use for ObjC implementation decls.
-/// STILL UNDER CONSTRUCTION...
+/// ObjCProtocolDecl.
+/// FIXME: Use for ObjC implementation decls.
+/// FIXME: Consider properties.
+/// FIXME: It would be nice to reduce amount of "boilerplate" iterator code
+/// below. For now, the iterators are modeled after RecordDecl::field_iterator().
+/// If DeclContext ends up providing some support for creating more strongly
+/// typed iterators, the code below should be reduced considerably.
///
-class ObjCContainerDecl : public NamedDecl {
- /// instance methods
- ObjCMethodDecl **InstanceMethods; // Null if not defined
- unsigned NumInstanceMethods; // 0 if none.
-
- /// class methods
- ObjCMethodDecl **ClassMethods; // Null if not defined
- unsigned NumClassMethods; // 0 if none
-
+class ObjCContainerDecl : public NamedDecl, public DeclContext {
SourceLocation AtEndLoc; // marks the end of the method container.
public:
ObjCContainerDecl(Kind DK, SourceLocation L, IdentifierInfo *Id)
- : NamedDecl(DK, L, Id),
- InstanceMethods(0), NumInstanceMethods(0),
- ClassMethods(0), NumClassMethods(0) {}
+ : NamedDecl(DK, L, Id), DeclContext(DK) {}
virtual ~ObjCContainerDecl();
- typedef ObjCMethodDecl * const * instmeth_iterator;
- instmeth_iterator instmeth_begin() const { return InstanceMethods; }
- instmeth_iterator instmeth_end() const {
- return InstanceMethods+NumInstanceMethods;
+ // Iterator access to instance/class methods.
+ class method_iterator {
+ protected:
+ /// Current - Current position within the sequence of declarations
+ /// in this record.
+ DeclContext::decl_iterator Current;
+
+ /// End - Last position in the sequence of declarations in this
+ /// record.
+ DeclContext::decl_iterator End;
+
+ /// IsInstance - If true, we are iterating through instance methods.
+ /// If false, we are iteratring through class methods.
+ bool IsInstance;
+
+ /// SkipToNextMethod - Advances the current position up to the next
+ /// ObjCMethodDecl.
+ void SkipToNextMethod() {
+ while (Current != End) {
+ ObjCMethodDecl *M = dyn_cast<ObjCMethodDecl>(*Current);
+ if (M &&
+ (IsInstance && M->isInstance() || !IsInstance && !M->isInstance()))
+ return;
+ ++Current;
+ }
+ }
+
+ public:
+ typedef ObjCMethodDecl const * value_type;
+ typedef ObjCMethodDecl const * reference;
+ typedef ObjCMethodDecl const * pointer;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+
+ method_iterator() : Current(), End(), IsInstance(true) { }
+
+ method_iterator(DeclContext::decl_iterator C,
+ DeclContext::decl_iterator E, bool I)
+ : Current(C), End(E), IsInstance(I) {
+ SkipToNextMethod();
+ }
+
+ reference operator*() const { return cast<ObjCMethodDecl>(*Current); }
+
+ pointer operator->() const { return cast<ObjCMethodDecl>(*Current); }
+
+ method_iterator& operator++() {
+ ++Current;
+ SkipToNextMethod();
+ return *this;
+ }
+
+ method_iterator operator++(int) {
+ method_iterator tmp(*this);
+ ++(*this);
+ return tmp;
+ }
+
+ friend bool
+ operator==(const method_iterator& x, const method_iterator& y) {
+ return x.Current == y.Current;
+ }
+
+ friend bool
+ operator!=(const method_iterator& x, const method_iterator& y) {
+ return x.Current != y.Current;
+ }
+ };
+
+ class instmeth_iterator : public method_iterator {
+ public:
+ typedef ObjCMethodDecl* value_type;
+ typedef ObjCMethodDecl* reference;
+ typedef ObjCMethodDecl* pointer;
+
+ instmeth_iterator() : method_iterator() { }
+
+ instmeth_iterator(DeclContext::decl_iterator C, DeclContext::decl_iterator E)
+ : method_iterator(C, E, true) { }
+
+ reference operator*() const { return cast<ObjCMethodDecl>(*Current); }
+
+ pointer operator->() const { return cast<ObjCMethodDecl>(*Current); }
+
+ instmeth_iterator& operator++() {
+ ++Current;
+ SkipToNextMethod();
+ return *this;
+ }
+
+ instmeth_iterator operator++(int) {
+ instmeth_iterator tmp(*this);
+ ++(*this);
+ return tmp;
+ }
+ };
+
+ instmeth_iterator instmeth_begin() const {
+ return instmeth_iterator(decls_begin(), decls_end());
}
-
- typedef ObjCMethodDecl * const * classmeth_iterator;
- classmeth_iterator classmeth_begin() const { return ClassMethods; }
- classmeth_iterator classmeth_end() const {
- return ClassMethods+NumClassMethods;
+ instmeth_iterator instmeth_end() const {
+ return instmeth_iterator(decls_end(), decls_end());
}
- // Get the local instance method declared in this interface.
- ObjCMethodDecl *getInstanceMethod(Selector Sel) const {
- for (instmeth_iterator I = instmeth_begin(), E = instmeth_end();
- I != E; ++I) {
- if ((*I)->getSelector() == Sel)
- return *I;
+ class classmeth_iterator : public method_iterator {
+ public:
+ typedef ObjCMethodDecl* value_type;
+ typedef ObjCMethodDecl* reference;
+ typedef ObjCMethodDecl* pointer;
+
+ classmeth_iterator() : method_iterator() { }
+
+ classmeth_iterator(DeclContext::decl_iterator C, DeclContext::decl_iterator E)
+ : method_iterator(C, E, false) { }
+
+ reference operator*() const { return cast<ObjCMethodDecl>(*Current); }
+
+ pointer operator->() const { return cast<ObjCMethodDecl>(*Current); }
+
+ classmeth_iterator& operator++() {
+ ++Current;
+ SkipToNextMethod();
+ return *this;
}
- return 0;
- }
- // Get the local class method declared in this interface.
- ObjCMethodDecl *getClassMethod(Selector Sel) const {
- for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
- I != E; ++I) {
- if ((*I)->getSelector() == Sel)
- return *I;
+
+ classmeth_iterator operator++(int) {
+ classmeth_iterator tmp(*this);
+ ++(*this);
+ return tmp;
}
- return 0;
+ };
+ classmeth_iterator classmeth_begin() const {
+ return classmeth_iterator(decls_begin(), decls_end());
}
+ classmeth_iterator classmeth_end() const {
+ return classmeth_iterator(decls_end(), decls_end());
+ }
+
+ // Get the local instance/class method declared in this interface.
+ ObjCMethodDecl *getInstanceMethod(Selector Sel) const;
+ ObjCMethodDecl *getClassMethod(Selector Sel) const;
- void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers,
- ObjCMethodDecl **clsMethods, unsigned numClsMembers,
- SourceLocation AtEndLoc);
-
- unsigned getNumInstanceMethods() const { return NumInstanceMethods; }
- unsigned getNumClassMethods() const { return NumClassMethods; }
+ // Get the number of instance/class methods.
+ unsigned getNumInstanceMethods() const;
+ unsigned getNumClassMethods() const;
// Marks the end of the container.
SourceLocation getAtEndLoc() const { return AtEndLoc; }
+ void setAtEndLoc(SourceLocation L) { AtEndLoc = L; }
+
+ // This method synthesizes the getter/setter method for the property.
+ // FIXME: Shouldn't this be part of Sema?.
+ void getPropertyMethods(ASTContext &Context, ObjCPropertyDecl* Property,
+ ObjCMethodDecl *& Getter, ObjCMethodDecl *&Setter);
};
/// ObjCInterfaceDecl - Represents an ObjC class declaration. For example:
@@ -337,7 +446,7 @@ public:
/// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
/// typically inherit from NSObject (an exception is NSProxy).
///
-class ObjCInterfaceDecl : public ObjCContainerDecl, public DeclContext {
+class ObjCInterfaceDecl : public ObjCContainerDecl {
/// TypeForDecl - This indicates the Type object that represents this
/// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType
Type *TypeForDecl;
@@ -369,7 +478,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl, public DeclContext {
ObjCInterfaceDecl(SourceLocation atLoc, IdentifierInfo *Id,
SourceLocation CLoc, bool FD, bool isInternal)
- : ObjCContainerDecl(ObjCInterface, atLoc, Id), DeclContext(ObjCInterface),
+ : ObjCContainerDecl(ObjCInterface, atLoc, Id),
TypeForDecl(0), SuperClass(0),
Ivars(0), NumIvars(0),
CategoryList(0), PropertyDecl(0), NumPropertyDecl(0),
@@ -424,11 +533,6 @@ public:
void mergeProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
- void addPropertyMethods(ASTContext &Context,
- ObjCPropertyDecl* Property,
- llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
- llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap);
-
typedef ObjCPropertyDecl * const * classprop_iterator;
classprop_iterator classprop_begin() const { return PropertyDecl; }
classprop_iterator classprop_end() const {
@@ -644,11 +748,6 @@ public:
void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
- void addPropertyMethods(ASTContext &Context,
- ObjCPropertyDecl* Property,
- llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
- llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap);
-
typedef ObjCPropertyDecl * const * classprop_iterator;
classprop_iterator classprop_begin() const { return PropertyDecl; }
classprop_iterator classprop_end() const {
@@ -839,11 +938,6 @@ public:
void mergeProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
- void addPropertyMethods(ASTContext &Context,
- ObjCPropertyDecl* Property,
- llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
- llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap);
-
ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
typedef ObjCPropertyDecl * const * classprop_iterator;
@@ -878,7 +972,7 @@ public:
/// @dynamic p1,d1;
/// @end
///
-class ObjCCategoryImplDecl : public NamedDecl {
+class ObjCCategoryImplDecl : public NamedDecl, public DeclContext {
/// Class interface for this category implementation
ObjCInterfaceDecl *ClassInterface;
@@ -895,7 +989,8 @@ class ObjCCategoryImplDecl : public NamedDecl {
ObjCCategoryImplDecl(SourceLocation L, IdentifierInfo *Id,
ObjCInterfaceDecl *classInterface)
- : NamedDecl(ObjCCategoryImpl, L, Id), ClassInterface(classInterface) {}
+ : NamedDecl(ObjCCategoryImpl, L, Id), DeclContext(ObjCCategoryImpl),
+ ClassInterface(classInterface) {}
public:
static ObjCCategoryImplDecl *Create(ASTContext &C,
SourceLocation L, IdentifierInfo *Id,
@@ -974,7 +1069,7 @@ public:
/// the legacy semantics and allow developers to move private ivar declarations
/// from the class interface to the class implementation (but I digress:-)
///
-class ObjCImplementationDecl : public NamedDecl {
+class ObjCImplementationDecl : public NamedDecl, public DeclContext {
/// Class interface for this implementation
ObjCInterfaceDecl *ClassInterface;
@@ -999,7 +1094,7 @@ class ObjCImplementationDecl : public NamedDecl {
ObjCImplementationDecl(SourceLocation L, IdentifierInfo *Id,
ObjCInterfaceDecl *classInterface,
ObjCInterfaceDecl *superDecl)
- : NamedDecl(ObjCImplementation, L, Id),
+ : NamedDecl(ObjCImplementation, L, Id), DeclContext(ObjCImplementation),
ClassInterface(classInterface), SuperClass(superDecl),
Ivars(0), NumIvars(0) {}
public:
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index f14dc3c717..49890144a9 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -419,7 +419,7 @@ bool DeclContext::isTransparentContext() const {
return false;
}
-DeclContext *DeclContext::getPrimaryContext(ASTContext &Context) {
+DeclContext *DeclContext::getPrimaryContext() {
switch (DeclKind) {
case Decl::TranslationUnit:
case Decl::LinkageSpec:
@@ -468,9 +468,15 @@ DeclContext *DeclContext::getPrimaryContext(ASTContext &Context) {
return this;
case Decl::ObjCInterface:
+ case Decl::ObjCProtocol:
+ case Decl::ObjCCategory:
// FIXME: Can Objective-C interfaces be forward-declared?
return this;
+ case Decl::ObjCImplementation:
+ case Decl::ObjCCategoryImpl:
+ return this;
+
default:
assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
"Unknown DeclContext kind");
@@ -486,6 +492,10 @@ DeclContext *DeclContext::getNextContext() {
case Decl::CXXRecord:
case Decl::ObjCMethod:
case Decl::ObjCInterface:
+ case Decl::ObjCCategory:
+ case Decl::ObjCProtocol:
+ case Decl::ObjCImplementation:
+ case Decl::ObjCCategoryImpl:
case Decl::LinkageSpec:
case Decl::Block:
// There is only one DeclContext for these entities.
@@ -511,7 +521,7 @@ void DeclContext::addDecl(ASTContext &Context, ScopedDecl *D, bool AllowLookup)
/// buildLookup - Build the lookup data structure with all of the
/// declarations in DCtx (and any other contexts linked to it or
/// transparent contexts nested within it).
-void DeclContext::buildLookup(ASTContext &Context, DeclContext *DCtx) {
+void DeclContext::buildLookup(DeclContext *DCtx) {
for (; DCtx; DCtx = DCtx->getNextContext()) {
for (decl_iterator D = DCtx->decls_begin(), DEnd = DCtx->decls_end();
D != DEnd; ++D) {
@@ -522,22 +532,22 @@ void DeclContext::buildLookup(ASTContext &Context, DeclContext *DCtx) {
// add its members (recursively).
if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D))
if (InnerCtx->isTransparentContext())
- buildLookup(Context, InnerCtx->getPrimaryContext(Context));
+ buildLookup(InnerCtx->getPrimaryContext());
}
}
}
DeclContext::lookup_result
-DeclContext::lookup(ASTContext &Context, DeclarationName Name) {
- DeclContext *PrimaryContext = getPrimaryContext(Context);
+DeclContext::lookup(DeclarationName Name) {
+ DeclContext *PrimaryContext = getPrimaryContext();
if (PrimaryContext != this)
- return PrimaryContext->lookup(Context, Name);
+ return PrimaryContext->lookup(Name);
/// If there is no lookup data structure, build one now by walking
/// all of the linked DeclContexts (in declaration order!) and
/// inserting their values.
if (LookupPtr.getPointer() == 0)
- buildLookup(Context, this);
+ buildLookup(this);
if (isLookupMap()) {
StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
@@ -563,8 +573,8 @@ DeclContext::lookup(ASTContext &Context, DeclarationName Name) {
}
DeclContext::lookup_const_result
-DeclContext::lookup(ASTContext &Context, DeclarationName Name) const {
- return const_cast<DeclContext*>(this)->lookup(Context, Name);
+DeclContext::lookup(DeclarationName Name) const {
+ return const_cast<DeclContext*>(this)->lookup(Name);
}
const DeclContext *DeclContext::getLookupContext() const {
@@ -575,7 +585,7 @@ const DeclContext *DeclContext::getLookupContext() const {
}
void DeclContext::insert(ASTContext &Context, ScopedDecl *D) {
- DeclContext *PrimaryContext = getPrimaryContext(Context);
+ DeclContext *PrimaryContext = getPrimaryContext();
if (PrimaryContext != this) {
PrimaryContext->insert(Context, D);
return;
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 7f787de75f..e3d753490a 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -98,7 +98,7 @@ bool CXXRecordDecl::hasConstCopyConstructor(ASTContext &Context) const {
Context.getCanonicalType(ClassType));
unsigned TypeQuals;
DeclContext::lookup_const_iterator Con, ConEnd;
- for (llvm::tie(Con, ConEnd) = this->lookup(Context, ConstructorName);
+ for (llvm::tie(Con, ConEnd) = this->lookup(ConstructorName);
Con != ConEnd; ++Con) {
if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(Context, TypeQuals) &&
(TypeQuals & QualType::Const) != 0)
@@ -114,7 +114,7 @@ bool CXXRecordDecl::hasConstCopyAssignment(ASTContext &Context) const {
DeclarationName OpName =Context.DeclarationNames.getCXXOperatorName(OO_Equal);
DeclContext::lookup_const_iterator Op, OpEnd;
- for (llvm::tie(Op, OpEnd) = this->lookup(Context, OpName);
+ for (llvm::tie(Op, OpEnd) = this->lookup(OpName);
Op != OpEnd; ++Op) {
// C++ [class.copy]p9:
// A user-declared copy assignment operator is a non-static non-template
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 2bfad5a7be..0b6eff1af5 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -24,7 +24,7 @@ ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
SourceLocation beginLoc,
SourceLocation endLoc,
Selector SelInfo, QualType T,
- Decl *contextDecl,
+ DeclContext *contextDecl,
bool isInstance,
bool isVariadic,
bool isSynthesized,
@@ -61,8 +61,6 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
}
ObjCContainerDecl::~ObjCContainerDecl() {
- delete [] InstanceMethods;
- delete [] ClassMethods;
}
ObjCInterfaceDecl::~ObjCInterfaceDecl() {
@@ -362,7 +360,7 @@ FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context,
assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
DeclarationName Member = ivar->getDeclName();
DeclContext::lookup_result Lookup = (const_cast< RecordDecl *>(RecordForDecl))
- ->lookup(Context, Member);
+ ->lookup(Member);
assert((Lookup.first != Lookup.second) && "field decl not found");
FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
assert(MemberDecl && "field decl not found");
@@ -382,27 +380,6 @@ void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
}
}
-/// addMethods - Insert instance and methods declarations into
-/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
-///
-void ObjCContainerDecl::addMethods(ObjCMethodDecl **insMethods,
- unsigned numInsMembers,
- ObjCMethodDecl **clsMethods,
- unsigned numClsMembers,
- SourceLocation endLoc) {
- 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*));
- }
- AtEndLoc = endLoc;
-}
-
/// addProperties - Insert property declaration AST nodes into
/// ObjCInterfaceDecl's PropertyDecl field.
///
@@ -440,18 +417,45 @@ void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties,
}
}
-static void
-addPropertyMethods(Decl *D,
- ASTContext &Context,
- ObjCPropertyDecl *property,
- llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
- llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
- ObjCMethodDecl *GetterDecl, *SetterDecl = 0;
-
- GetterDecl = const_cast<ObjCMethodDecl*>(InsMap[property->getGetterName()]);
- if (!property->isReadOnly())
- SetterDecl = const_cast<ObjCMethodDecl*>(InsMap[property->getSetterName()]);
-
+// Get the local instance method declared in this interface.
+// FIXME: handle overloading, instance & class methods can have the same name.
+ObjCMethodDecl *ObjCContainerDecl::getInstanceMethod(Selector Sel) const {
+ lookup_const_result MethodResult = lookup(Sel);
+ if (MethodResult.first)
+ return const_cast<ObjCMethodDecl*>(
+ dyn_cast<ObjCMethodDecl>(*MethodResult.first));
+ return 0;
+}
+
+// Get the local class method declared in this interface.
+ObjCMethodDecl *ObjCContainerDecl::getClassMethod(Selector Sel) const {
+ lookup_const_result MethodResult = lookup(Sel);
+ if (MethodResult.first)
+ return const_cast<ObjCMethodDecl*>(
+ dyn_cast<ObjCMethodDecl>(*MethodResult.first));
+ return 0;
+}
+
+unsigned ObjCContainerDecl::getNumInstanceMethods() const {
+ unsigned sum = 0;
+ for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I != E; ++I)
+ sum++;
+ return sum;
+}
+unsigned ObjCContainerDecl::getNumClassMethods() const {
+ unsigned sum = 0;
+ for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I != E; ++I)
+ sum++;
+ return sum;
+}
+
+/// addPropertyMethods - Goes through list of properties declared in this class
+/// and builds setter/getter method declartions depending on the setter/getter
+/// attributes of the property.
+///
+void ObjCContainerDecl::getPropertyMethods(
+ ASTContext &Context, ObjCPropertyDecl *property,
+ ObjCMethodDecl *& GetterDecl, ObjCMethodDecl *&SetterDecl) {
// FIXME: The synthesized property we set here is misleading. We
// almost always synthesize these methods unless the user explicitly
// provided prototypes (which is odd, but allowed). Sema should be
@@ -467,15 +471,12 @@ addPropertyMethods(Decl *D,
ObjCMethodDecl::Create(Context, property->getLocation(),
property->getLocation(),
property->getGetterName(),
- property->getType(),
- D,
+ property->getType(), this,
true, false, true,
(property->getPropertyImplementation() ==
ObjCPropertyDecl::Optional) ?
ObjCMethodDecl::Optional :
ObjCMethodDecl::Required);
- insMethods.push_back(GetterDecl);
- InsMap[property->getGetterName()] = GetterDecl;
}
else
// A user declared getter will be synthesize when @synthesize of
@@ -496,15 +497,12 @@ addPropertyMethods(Decl *D,
ObjCMethodDecl::Create(Context, property->getLocation(),
property->getLocation(),
property->getSetterName(),
- Context.VoidTy,
- D,
+ Context.VoidTy, this,
true, false, true,
(property->getPropertyImplementation() ==
ObjCPropertyDecl::Optional) ?
ObjCMethodDecl::Optional :
ObjCMethodDecl::Required);
- insMethods.push_back(SetterDecl);
- InsMap[property->getSetterName()] = SetterDecl;
// Invent the arguments for the setter. We don't bother making a
// nice name for the argument.
ParmVarDecl *Argument = ParmVarDecl::Create(Context,
@@ -523,30 +521,6 @@ addPropertyMethods(Decl *D,
property->setSetterMethodDecl(SetterDecl);
}
-/// addPropertyMethods - Goes through list of properties declared in this class
-/// and builds setter/getter method declartions depending on the setter/getter
-/// attributes of the property.
-///
-void ObjCInterfaceDecl::addPropertyMethods(
- ASTContext &Context,
- ObjCPropertyDecl *property,
- llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
- llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
- ::addPropertyMethods(this, Context, property, insMethods, InsMap);
-}
-
-/// addPropertyMethods - Goes through list of properties declared in this class
-/// and builds setter/getter method declartions depending on the setter/getter
-/// attributes of the property.
-///
-void ObjCCategoryDecl::addPropertyMethods(
- ASTContex