summaryrefslogtreecommitdiffstats
path: root/lib/AST/DeclObjC.cpp
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2009-10-14 18:03:49 +0000
committerrdivacky <rdivacky@FreeBSD.org>2009-10-14 18:03:49 +0000
commit9092c3e0fa01f3139b016d05d267a89e3b07747a (patch)
tree137ebebcae16fb0ce7ab4af456992bbd8d22fced /lib/AST/DeclObjC.cpp
parent4981926bf654fe5a2c3893f24ca44106b217e71e (diff)
downloadFreeBSD-src-9092c3e0fa01f3139b016d05d267a89e3b07747a.zip
FreeBSD-src-9092c3e0fa01f3139b016d05d267a89e3b07747a.tar.gz
Update clang to r84119.
Diffstat (limited to 'lib/AST/DeclObjC.cpp')
-rw-r--r--lib/AST/DeclObjC.cpp440
1 files changed, 256 insertions, 184 deletions
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 54f13e1..7f38ac1 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -30,8 +30,8 @@ void ObjCListBase::Destroy(ASTContext &Ctx) {
void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
assert(List == 0 && "Elements already set!");
if (Elts == 0) return; // Setting to an empty list is a noop.
-
-
+
+
List = new (Ctx) void*[Elts];
NumElts = Elts;
memcpy(List, InList, sizeof(void*)*Elts);
@@ -54,29 +54,9 @@ ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const {
return 0;
}
-// Get the local instance method declared in this interface.
-ObjCMethodDecl *
-ObjCContainerDecl::getInstanceMethod(Selector Sel) const {
- // Since instance & class methods can have the same name, the loop below
- // ensures we get the correct method.
- //
- // @interface Whatever
- // - (int) class_method;
- // + (float) class_method;
- // @end
- //
- lookup_const_iterator Meth, MethEnd;
- for (llvm::tie(Meth, MethEnd) = lookup(Sel); Meth != MethEnd; ++Meth) {
- ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
- if (MD && MD->isInstanceMethod())
- return MD;
- }
- return 0;
-}
-
-// Get the local class method declared in this interface.
+// Get the local instance/class method declared in this interface.
ObjCMethodDecl *
-ObjCContainerDecl::getClassMethod(Selector Sel) const {
+ObjCContainerDecl::getMethod(Selector Sel, bool isInstance) const {
// Since instance & class methods can have the same name, the loop below
// ensures we get the correct method.
//
@@ -88,7 +68,7 @@ ObjCContainerDecl::getClassMethod(Selector Sel) const {
lookup_const_iterator Meth, MethEnd;
for (llvm::tie(Meth, MethEnd) = lookup(Sel); Meth != MethEnd; ++Meth) {
ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
- if (MD && MD->isClassMethod())
+ if (MD && MD->isInstanceMethod() == isInstance)
return MD;
}
return 0;
@@ -103,15 +83,15 @@ ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I)
if ((*I)->getIdentifier() == PropertyId)
return *I;
-
+
const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
if (PID) {
- for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
+ for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
E = PID->protocol_end(); I != E; ++I)
if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
return P;
}
-
+
if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this)) {
// Look through categories.
for (ObjCCategoryDecl *Category = OID->getCategoryList();
@@ -138,6 +118,45 @@ ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
return 0;
}
+void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
+ ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
+ ASTContext &C)
+{
+ if (ReferencedProtocols.empty()) {
+ ReferencedProtocols.set(ExtList, ExtNum, C);
+ return;
+ }
+ // Check for duplicate protocol in class's protocol list.
+ // This is (O)2. But it is extremely rare and number of protocols in
+ // class or its extension are very few.
+ llvm::SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs;
+ for (unsigned i = 0; i < ExtNum; i++) {
+ bool protocolExists = false;
+ ObjCProtocolDecl *ProtoInExtension = ExtList[i];
+ for (protocol_iterator p = protocol_begin(), e = protocol_end();
+ p != e; p++) {
+ ObjCProtocolDecl *Proto = (*p);
+ if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
+ protocolExists = true;
+ break;
+ }
+ }
+ // Do we want to warn on a protocol in extension class which
+ // already exist in the class? Probably not.
+ if (!protocolExists)
+ ProtocolRefs.push_back(ProtoInExtension);
+ }
+ if (ProtocolRefs.empty())
+ return;
+ // Merge ProtocolRefs into class's protocol list;
+ for (protocol_iterator p = protocol_begin(), e = protocol_end();
+ p != e; p++)
+ ProtocolRefs.push_back(*p);
+ ReferencedProtocols.Destroy(C);
+ unsigned NumProtoRefs = ProtocolRefs.size();
+ setProtocolList((ObjCProtocolDecl**)&ProtocolRefs[0], NumProtoRefs, C);
+}
+
ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
ObjCInterfaceDecl *&clsDeclared) {
ObjCInterfaceDecl* ClassDecl = this;
@@ -165,72 +184,37 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
return NULL;
}
-/// lookupInstanceMethod - This method returns an instance method by looking in
+/// lookupMethod - This method returns an instance/class method by looking in
/// the class, its categories, and its super classes (using a linear search).
-ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
- ObjCInterfaceDecl* ClassDecl = this;
+ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
+ bool isInstance) const {
+ const ObjCInterfaceDecl* ClassDecl = this;
ObjCMethodDecl *MethodDecl = 0;
-
+
while (ClassDecl != NULL) {
- if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
+ if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
return MethodDecl;
-
+
// Didn't find one yet - look through protocols.
const ObjCList<ObjCProtocolDecl> &Protocols =
ClassDecl->getReferencedProtocols();
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
E = Protocols.end(); I != E; ++I)
- if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
- return MethodDecl;
-
- // Didn't find one yet - now look through categories.
- ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
- while (CatDecl) {
- if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
+ if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
return MethodDecl;
-
- // Didn't find one yet - look through protocols.
- const ObjCList<ObjCProtocolDecl> &Protocols =
- CatDecl->getReferencedProtocols();
- for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
- E = Protocols.end(); I != E; ++I)
- if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
- return MethodDecl;
- CatDecl = CatDecl->getNextClassCategory();
- }
- ClassDecl = ClassDecl->getSuperClass();
- }
- return NULL;
-}
-
-// lookupClassMethod - This method returns a class method by looking in the
-// class, its categories, and its super classes (using a linear search).
-ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
- ObjCInterfaceDecl* ClassDecl = this;
- ObjCMethodDecl *MethodDecl = 0;
-
- while (ClassDecl != NULL) {
- if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
- return MethodDecl;
- // Didn't find one yet - look through protocols.
- for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
- E = ClassDecl->protocol_end(); I != E; ++I)
- if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
- return MethodDecl;
-
// Didn't find one yet - now look through categories.
ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
while (CatDecl) {
- if ((MethodDecl = CatDecl->getClassMethod(Sel)))
+ if ((MethodDecl = CatDecl->getMethod(Sel, isInstance)))
return MethodDecl;
-
+
// Didn't find one yet - look through protocols.
const ObjCList<ObjCProtocolDecl> &Protocols =
CatDecl->getReferencedProtocols();
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
E = Protocols.end(); I != E; ++I)
- if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
+ if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
return MethodDecl;
CatDecl = CatDecl->getNextClassCategory();
}
@@ -239,14 +223,23 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
return NULL;
}
-
+ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateInstanceMethod(
+ const Selector &Sel) {
+ ObjCMethodDecl *Method = 0;
+ if (ObjCImplementationDecl *ImpDecl = getImplementation())
+ Method = ImpDecl->getInstanceMethod(Sel);
+
+ if (!Method && getSuperClass())
+ return getSuperClass()->lookupPrivateInstanceMethod(Sel);
+ return Method;
+}
//===----------------------------------------------------------------------===//
// ObjCMethodDecl
//===----------------------------------------------------------------------===//
ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
- SourceLocation beginLoc,
+ SourceLocation beginLoc,
SourceLocation endLoc,
Selector SelInfo, QualType T,
DeclContext *contextDecl,
@@ -256,14 +249,14 @@ ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
ImplementationControl impControl) {
return new (C) ObjCMethodDecl(beginLoc, endLoc,
SelInfo, T, contextDecl,
- isInstance,
+ isInstance,
isVariadic, isSynthesized, impControl);
}
void ObjCMethodDecl::Destroy(ASTContext &C) {
if (Body) Body->Destroy(C);
if (SelfDecl) SelfDecl->Destroy(C);
-
+
for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
if (*I) (*I)->Destroy(C);
@@ -272,7 +265,57 @@ void ObjCMethodDecl::Destroy(ASTContext &C) {
Decl::Destroy(C);
}
-void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
+/// \brief A definition will return its interface declaration.
+/// An interface declaration will return its definition.
+/// Otherwise it will return itself.
+ObjCMethodDecl *ObjCMethodDecl::getNextRedeclaration() {
+ ASTContext &Ctx = getASTContext();
+ ObjCMethodDecl *Redecl = 0;
+ Decl *CtxD = cast<Decl>(getDeclContext());
+
+ if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
+ if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
+ Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
+
+ } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
+ if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
+ Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
+
+ } else if (ObjCImplementationDecl *ImplD =
+ dyn_cast<ObjCImplementationDecl>(CtxD)) {
+ if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
+ Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
+
+ } else if (ObjCCategoryImplDecl *CImplD =
+ dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
+ if (ObjCCategoryDecl *CatD = CImplD->getCategoryClass())
+ Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
+ }
+
+ return Redecl ? Redecl : this;
+}
+
+ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
+ Decl *CtxD = cast<Decl>(getDeclContext());
+
+ if (ObjCImplementationDecl *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
+ if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
+ if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(),
+ isInstanceMethod()))
+ return MD;
+
+ } else if (ObjCCategoryImplDecl *CImplD =
+ dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
+ if (ObjCCategoryDecl *CatD = CImplD->getCategoryClass())
+ if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(),
+ isInstanceMethod()))
+ return MD;
+ }
+
+ return this;
+}
+
+void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
const ObjCInterfaceDecl *OID) {
QualType selfTy;
if (isInstanceMethod()) {
@@ -280,49 +323,30 @@ void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
// of the interface (which has been reported). Recover gracefully.
if (OID) {
selfTy = Context.getObjCInterfaceType(OID);
- selfTy = Context.getPointerType(selfTy);
+ selfTy = Context.getObjCObjectPointerType(selfTy);
} else {
selfTy = Context.getObjCIdType();
}
} else // we have a factory method.
selfTy = Context.getObjCClassType();
- setSelfDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
+ setSelfDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
&Context.Idents.get("self"), selfTy));
- setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
- &Context.Idents.get("_cmd"),
+ setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
+ &Context.Idents.get("_cmd"),
Context.getObjCSelType()));
}
-
-
-/// getSynthesizedMethodSize - Compute size of synthesized method name
-/// as done be the rewrite.
-///
-unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
- // syntesized method name is a concatenation of -/+[class-name selector]
- // Get length of this name.
- unsigned length = 3; // _I_ or _C_
- length += getClassInterface()->getNameAsString().size()+1; // extra for _
- if (const ObjCCategoryImplDecl *CID =
- dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
- length += CID->getNameAsString().size()+1;
- length += getSelector().getAsString().size(); // selector name
- return length;
-}
-
ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
return ID;
if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
return CD->getClassInterface();
- if (ObjCImplementationDecl *IMD =
- dyn_cast<ObjCImplementationDecl>(getDeclContext()))
+ if (ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
return IMD->getClassInterface();
- if (ObjCCategoryImplDecl *CID =
- dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
- return CID->getClassInterface();
+
+ assert(!isa<ObjCProtocolDecl>(getDeclContext()) && "It's a protocol method");
assert(false && "unknown method context");
return 0;
}
@@ -334,7 +358,7 @@ ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
DeclContext *DC,
SourceLocation atLoc,
- IdentifierInfo *Id,
+ IdentifierInfo *Id,
SourceLocation ClassLoc,
bool ForwardDecl, bool isInternal){
return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
@@ -350,19 +374,28 @@ ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
ClassLoc(CLoc) {
}
-void ObjCInterfaceDecl::Destroy(ASTContext &C) {
+void ObjCInterfaceDecl::Destroy(ASTContext &C) {
for (ivar_iterator I = ivar_begin(), E = ivar_end(); I != E; ++I)
if (*I) (*I)->Destroy(C);
-
+
IVars.Destroy(C);
// FIXME: CategoryList?
-
+
// FIXME: Because there is no clear ownership
// role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
// reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
Decl::Destroy(C);
}
+ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
+ return getASTContext().getObjCImplementation(
+ const_cast<ObjCInterfaceDecl*>(this));
+}
+
+void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
+ getASTContext().setObjCImplementation(this, ImplD);
+}
+
/// FindCategoryDeclaration - Finds category declaration in the list of
/// categories for this class and returns it. Name of the category is passed
@@ -377,14 +410,79 @@ ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
return 0;
}
+ObjCMethodDecl *
+ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
+ for (ObjCCategoryDecl *Category = getCategoryList();
+ Category; Category = Category->getNextClassCategory())
+ if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
+ if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
+ return MD;
+ return 0;
+}
+
+ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
+ for (ObjCCategoryDecl *Category = getCategoryList();
+ Category; Category = Category->getNextClassCategory())
+ if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
+ if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
+ return MD;
+ return 0;
+}
+
+/// ClassImplementsProtocol - Checks that 'lProto' protocol
+/// has been implemented in IDecl class, its super class or categories (if
+/// lookupCategory is true).
+bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
+ bool lookupCategory,
+ bool RHSIsQualifiedID) {
+ ObjCInterfaceDecl *IDecl = this;
+ // 1st, look up the class.
+ const ObjCList<ObjCProtocolDecl> &Protocols =
+ IDecl->getReferencedProtocols();
+
+ for (ObjCList<ObjCProtocolDecl>::iterator PI = Protocols.begin(),
+ E = Protocols.end(); PI != E; ++PI) {
+ if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
+ return true;
+ // This is dubious and is added to be compatible with gcc. In gcc, it is
+ // also allowed assigning a protocol-qualified 'id' type to a LHS object
+ // when protocol in qualified LHS is in list of protocols in the rhs 'id'
+ // object. This IMO, should be a bug.
+ // FIXME: Treat this as an extension, and flag this as an error when GCC
+ // extensions are not enabled.
+ if (RHSIsQualifiedID &&
+ getASTContext().ProtocolCompatibleWithProtocol(*PI, lProto))
+ return true;
+ }
+
+ // 2nd, look up the category.
+ if (lookupCategory)
+ for (ObjCCategoryDecl *CDecl = IDecl->getCategoryList(); CDecl;
+ CDecl = CDecl->getNextClassCategory()) {
+ for (ObjCCategoryDecl::protocol_iterator PI = CDecl->protocol_begin(),
+ E = CDecl->protocol_end(); PI != E; ++PI)
+ if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
+ return true;
+ }
+
+ // 3rd, look up the super class(s)
+ if (IDecl->getSuperClass())
+ return
+ IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
+ RHSIsQualifiedID);
+
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// ObjCIvarDecl
//===----------------------------------------------------------------------===//
ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
- QualType T, AccessControl ac, Expr *BW) {
- return new (C) ObjCIvarDecl(DC, L, Id, T, ac, BW);
+ QualType T, DeclaratorInfo *DInfo,
+ AccessControl ac, Expr *BW) {
+ return new (C) ObjCIvarDecl(DC, L, Id, T, DInfo, ac, BW);
}
@@ -401,7 +499,7 @@ ObjCAtDefsFieldDecl
void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
this->~ObjCAtDefsFieldDecl();
- C.Deallocate((void *)this);
+ C.Deallocate((void *)this);
}
//===----------------------------------------------------------------------===//
@@ -409,7 +507,7 @@ void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
//===----------------------------------------------------------------------===//
ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
+ SourceLocation L,
IdentifierInfo *Id) {
return new (C) ObjCProtocolDecl(DC, L, Id);
}
@@ -428,34 +526,21 @@ ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
if ((PDecl = (*I)->lookupProtocolNamed(Name)))
return PDecl;
-
- return NULL;
-}
-// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
-// it inherited.
-ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
- ObjCMethodDecl *MethodDecl = NULL;
-
- if ((MethodDecl = getInstanceMethod(Sel)))
- return MethodDecl;
-
- for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
- if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
- return MethodDecl;
return NULL;
}
-// lookupInstanceMethod - Lookup a class method in the protocol and protocols
+// lookupMethod - Lookup a instance/class method in the protocol and protocols
// it inherited.
-ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
+ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
+ bool isInstance) const {
ObjCMethodDecl *MethodDecl = NULL;
-
- if ((MethodDecl = getClassMethod(Sel)))
+
+ if ((MethodDecl = getMethod(Sel, isInstance)))
return MethodDecl;
-
+
for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
- if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
+ if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
return MethodDecl;
return NULL;
}
@@ -464,7 +549,7 @@ ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
// ObjCClassDecl
//===----------------------------------------------------------------------===//
-ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L,
+ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L,
ObjCInterfaceDecl *const *Elts, unsigned nElts,
ASTContext &C)
: Decl(ObjCClass, DC, L) {
@@ -480,7 +565,7 @@ ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
}
void ObjCClassDecl::Destroy(ASTContext &C) {
-
+
// FIXME: There is no clear ownership policy now for referenced
// ObjCInterfaceDecls. Some of them can be forward declarations that
// are never later defined (in which case the ObjCClassDecl owns them)
@@ -488,7 +573,7 @@ void ObjCClassDecl::Destroy(ASTContext &C) {
// we should have separate objects for forward declarations and definitions,
// obviating this problem. Because of this situation, referenced
// ObjCInterfaceDecls are destroyed in ~TranslationUnit.
-
+
ForwardDecls.Destroy(C);
Decl::Destroy(C);
}
@@ -501,14 +586,14 @@ ObjCForwardProtocolDecl::
ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
ObjCProtocolDecl *const *Elts, unsigned nElts,
ASTContext &C)
-: Decl(ObjCForwardProtocol, DC, L) {
+: Decl(ObjCForwardProtocol, DC, L) {
ReferencedProtocols.set(Elts, nElts, C);
}
ObjCForwardProtocolDecl *
ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
+ SourceLocation L,
ObjCProtocolDecl *const *Elts,
unsigned NumElts) {
return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, C);
@@ -529,6 +614,16 @@ ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
return new (C) ObjCCategoryDecl(DC, L, Id);
}
+ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
+ return getASTContext().getObjCImplementation(
+ const_cast<ObjCCategoryDecl*>(this));
+}
+
+void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) {
+ getASTContext().setObjCImplementation(this, ImplD);
+}
+
+
//===----------------------------------------------------------------------===//
// ObjCCategoryImplDecl
//===----------------------------------------------------------------------===//
@@ -540,6 +635,10 @@ ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
}
+ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryClass() const {
+ return getClassInterface()->FindCategoryDeclaration(getIdentifier());
+}
+
void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
// FIXME: The context should be correct before we get here.
@@ -547,6 +646,23 @@ void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
addDecl(property);
}
+void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {
+ ASTContext &Ctx = getASTContext();
+
+ if (ObjCImplementationDecl *ImplD
+ = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
+ if (IFace)
+ Ctx.setObjCImplementation(IFace, ImplD);
+
+ } else if (ObjCCategoryImplDecl *ImplD =
+ dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
+ if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier()))
+ Ctx.setObjCImplementation(CD, ImplD);
+ }
+
+ ClassInterface = IFace;
+}
+
/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
/// properties implemented in this category @implementation block and returns
/// the implemented property that uses it.
@@ -576,56 +692,12 @@ FindPropertyImplDecl(IdentifierInfo *Id) const {
return 0;
}
-// getInstanceMethod - This method returns an instance method by looking in
-// the class implementation. Unlike interfaces, we don't look outside the
-// implementation.
-ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(Selector Sel) const {
- // Since instance & class methods can have the same name, the loop below
- // ensures we get the correct method.
- //
- // @interface Whatever
- // - (int) class_method;
- // + (float) class_method;
- // @end
- //
- lookup_const_iterator Meth, MethEnd;
- for (llvm::tie(Meth, MethEnd) = lookup(Sel);
- Meth != MethEnd; ++Meth) {
- ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
- if (MD && MD->isInstanceMethod())
- return MD;
- }
- return 0;
-}
-
-// getClassMethod - This method returns an instance method by looking in
-// the class implementation. Unlike interfaces, we don't look outside the
-// implementation.
-ObjCMethodDecl *ObjCImplDecl::getClassMethod(Selector Sel) const {
- // Since instance & class methods can have the same name, the loop below
- // ensures we get the correct method.
- //
- // @interface Whatever
- // - (int) class_method;
- // + (float) class_method;
- // @end
- //
- lookup_const_iterator Meth, MethEnd;
- for (llvm::tie(Meth, MethEnd) = lookup(Sel);
- Meth != MethEnd; ++Meth) {
- ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
- if (MD && MD->isClassMethod())
- return MD;
- }
- return 0;
-}
-
//===----------------------------------------------------------------------===//
// ObjCImplementationDecl
//===----------------------------------------------------------------------===//
ObjCImplementationDecl *
-ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
+ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
ObjCInterfaceDecl *ClassInterface,
ObjCInterfaceDecl *SuperDecl) {
@@ -639,7 +711,7 @@ ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
ObjCCompatibleAliasDecl *
ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
- IdentifierInfo *Id,
+ IdentifierInfo *Id,
ObjCInterfaceDecl* AliasedClass) {
return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
}
OpenPOWER on IntegriCloud