/// Class interface for this category implementation
ObjCInterfaceDecl *ClassInterface;
- /// implemented instance methods
- llvm::SmallVector<ObjCMethodDecl*, 16> InstanceMethods;
-
- /// implemented class methods
- llvm::SmallVector<ObjCMethodDecl*, 16> ClassMethods;
-
- /// Property Implementations in this category
- llvm::SmallVector<ObjCPropertyImplDecl*, 8> PropertyImplementations;
-
SourceLocation EndLoc;
protected:
const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
- void addInstanceMethod(ObjCMethodDecl *method) {
- InstanceMethods.push_back(method);
+ void addInstanceMethod(ASTContext &Context, ObjCMethodDecl *method) {
+ method->setLexicalDeclContext(this);
+ addDecl(Context, method);
}
- void addClassMethod(ObjCMethodDecl *method) {
- ClassMethods.push_back(method);
- }
-
- // Get the local instance/class method declared in this interface.
- ObjCMethodDecl *getInstanceMethod(Selector Sel) const;
- ObjCMethodDecl *getClassMethod(Selector Sel) const;
- ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const {
- return isInstance ? getInstanceMethod(Sel) : getClassMethod(Sel);
+ void addClassMethod(ASTContext &Context, ObjCMethodDecl *method) {
+ method->setLexicalDeclContext(this);
+ addDecl(Context, method);
}
- void addPropertyImplementation(ObjCPropertyImplDecl *property) {
- PropertyImplementations.push_back(property);
+ // Get the local instance/class method declared in this interface.
+ ObjCMethodDecl *getInstanceMethod(ASTContext &Context, Selector Sel) const;
+ ObjCMethodDecl *getClassMethod(ASTContext &Context, Selector Sel) const;
+ ObjCMethodDecl *getMethod(ASTContext &Context, Selector Sel,
+ bool isInstance) const {
+ return isInstance ? getInstanceMethod(Context, Sel)
+ : getClassMethod(Context, Sel);
}
- ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
- ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
+ void addPropertyImplementation(ASTContext &Context,
+ ObjCPropertyImplDecl *property);
- typedef llvm::SmallVector<ObjCPropertyImplDecl*, 8>::const_iterator
- propimpl_iterator;
- propimpl_iterator propimpl_begin() const {
- return PropertyImplementations.begin();
+ ObjCPropertyImplDecl *FindPropertyImplDecl(ASTContext &Context,
+ IdentifierInfo *propertyId) const;
+ ObjCPropertyImplDecl *FindPropertyImplIvarDecl(ASTContext &Context,
+ IdentifierInfo *ivarId) const;
+
+ // Iterator access to properties.
+ typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator;
+ propimpl_iterator propimpl_begin(ASTContext &Context) const {
+ return propimpl_iterator(decls_begin(Context));
}
- propimpl_iterator propimpl_end() const {
- return PropertyImplementations.end();
+ propimpl_iterator propimpl_end(ASTContext &Context) const {
+ return propimpl_iterator(decls_end(Context));
}
-
- typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
+
+ typedef filtered_decl_iterator<ObjCMethodDecl,
+ &ObjCMethodDecl::isInstanceMethod>
instmeth_iterator;
- instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); }
- instmeth_iterator instmeth_end() const { return InstanceMethods.end(); }
-
- typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
+ instmeth_iterator instmeth_begin(ASTContext &Context) const {
+ return instmeth_iterator(decls_begin(Context));
+ }
+ instmeth_iterator instmeth_end(ASTContext &Context) const {
+ return instmeth_iterator(decls_end(Context));
+ }
+
+ typedef filtered_decl_iterator<ObjCMethodDecl,
+ &ObjCMethodDecl::isClassMethod>
classmeth_iterator;
- classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); }
- classmeth_iterator classmeth_end() const { return ClassMethods.end(); }
-
+ classmeth_iterator classmeth_begin(ASTContext &Context) const {
+ return classmeth_iterator(decls_begin(Context));
+ }
+ classmeth_iterator classmeth_end(ASTContext &Context) const {
+ return classmeth_iterator(decls_end(Context));
+ }
+
// Location information, modeled after the Stmt API.
SourceLocation getLocStart() const { return getLocation(); }
SourceLocation getLocEnd() const { return EndLoc; }
if (const ObjCCategoryImplDecl *CID =
dyn_cast<ObjCCategoryImplDecl>(Container)) {
for (ObjCCategoryImplDecl::propimpl_iterator
- i = CID->propimpl_begin(), e = CID->propimpl_end(); i != e; ++i) {
+ i = CID->propimpl_begin(*this), e = CID->propimpl_end(*this);
+ i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyDecl() == PD) {
if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
} else {
const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container);
for (ObjCCategoryImplDecl::propimpl_iterator
- i = OID->propimpl_begin(), e = OID->propimpl_end(); i != e; ++i) {
+ i = OID->propimpl_begin(*this), e = OID->propimpl_end(*this);
+ i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyDecl() == PD) {
if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
}
+void ObjCImplDecl::addPropertyImplementation(ASTContext &Context,
+ ObjCPropertyImplDecl *property) {
+ property->setLexicalDeclContext(this);
+ addDecl(Context, property);
+}
+
/// 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.
///
ObjCPropertyImplDecl *ObjCImplDecl::
-FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
- for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
+FindPropertyImplIvarDecl(ASTContext &Context, IdentifierInfo *ivarId) const {
+ for (propimpl_iterator i = propimpl_begin(Context), e = propimpl_end(Context);
+ i != e; ++i){
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyIvarDecl() &&
PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
/// category @implementation block.
///
ObjCPropertyImplDecl *ObjCImplDecl::
-FindPropertyImplDecl(IdentifierInfo *Id) const {
- for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
+FindPropertyImplDecl(ASTContext &Context, IdentifierInfo *Id) const {
+ for (propimpl_iterator i = propimpl_begin(Context), e = propimpl_end(Context);
+ i != e; ++i){
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyDecl()->getIdentifier() == Id)
return PID;
// 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 {
- for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
- if ((*I)->getSelector() == Sel)
- return *I;
- return NULL;
+ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(ASTContext &Context,
+ 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(Context, 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 {
- for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
- I != E; ++I)
- if ((*I)->getSelector() == Sel)
- return *I;
- return NULL;
+ObjCMethodDecl *ObjCImplDecl::getClassMethod(ASTContext &Context,
+ 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(Context, Sel);
+ Meth != MethEnd; ++Meth) {
+ ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
+ if (MD && MD->isClassMethod())
+ return MD;
+ }
+ return 0;
}
//===----------------------------------------------------------------------===//
ObjCMethodDecl* MD = 0;
// Scan the instance methods for "dealloc".
- for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(),
- E = D->instmeth_end(); I!=E; ++I) {
+ for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(Ctx),
+ E = D->instmeth_end(Ctx); I!=E; ++I) {
if ((*I)->getSelector() == S) {
MD = *I;
// Scan for missing and extra releases of ivars used by implementations
// of synthesized properties
- for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(),
- E = D->propimpl_end(); I!=E; ++I) {
+ for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(Ctx),
+ E = D->propimpl_end(Ctx); I!=E; ++I) {
// We can only check the synthesized properties
if((*I)->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize)
if (!C)
return;
+ ASTContext& Ctx = BR.getContext();
+
// Build a DenseMap of the methods for quick querying.
typedef llvm::DenseMap<Selector,ObjCMethodDecl*> MapTy;
MapTy IMeths;
unsigned NumMethods = 0;
- for (ObjCImplementationDecl::instmeth_iterator I=ID->instmeth_begin(),
- E=ID->instmeth_end(); I!=E; ++I) {
+ for (ObjCImplementationDecl::instmeth_iterator I=ID->instmeth_begin(Ctx),
+ E=ID->instmeth_end(Ctx); I!=E; ++I) {
ObjCMethodDecl* M = *I;
IMeths[M->getSelector()] = M;
// Now recurse the class hierarchy chain looking for methods with the
// same signatures.
- ASTContext& Ctx = BR.getContext();
-
while (C && NumMethods) {
for (ObjCInterfaceDecl::instmeth_iterator I=C->instmeth_begin(Ctx),
E=C->instmeth_end(Ctx); I!=E; ++I) {
IvarUsageMap M;
-
+ ASTContext &Ctx = BR.getContext();
+
// Iterate over the ivars.
for (ObjCInterfaceDecl::ivar_iterator I=ID->ivar_begin(), E=ID->ivar_end();
I!=E; ++I) {
return;
// Now scan the methods for accesses.
- for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(),
- E = D->instmeth_end(); I!=E; ++I)
- Scan(M, (*I)->getBody(BR.getContext()));
+ for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(Ctx),
+ E = D->instmeth_end(Ctx); I!=E; ++I)
+ Scan(M, (*I)->getBody(Ctx));
// Scan for @synthesized property methods that act as setters/getters
// to an ivar.
- for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(),
- E = D->propimpl_end(); I!=E; ++I)
+ for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(Ctx),
+ E = D->propimpl_end(Ctx); I!=E; ++I)
Scan(M, *I);
// Find ivars that are unused.
// Collect information about instance methods
llvm::SmallVector<Selector, 16> InstanceMethodSels;
llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
- for (ObjCCategoryImplDecl::instmeth_iterator iter = OCD->instmeth_begin(),
- endIter = OCD->instmeth_end() ; iter != endIter ; iter++) {
+ for (ObjCCategoryImplDecl::instmeth_iterator
+ iter = OCD->instmeth_begin(CGM.getContext()),
+ endIter = OCD->instmeth_end(CGM.getContext());
+ iter != endIter ; iter++) {
InstanceMethodSels.push_back((*iter)->getSelector());
std::string TypeStr;
CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr);
// Collect information about class methods
llvm::SmallVector<Selector, 16> ClassMethodSels;
llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
- for (ObjCCategoryImplDecl::classmeth_iterator iter = OCD->classmeth_begin(),
- endIter = OCD->classmeth_end() ; iter != endIter ; iter++) {
+ for (ObjCCategoryImplDecl::classmeth_iterator
+ iter = OCD->classmeth_begin(CGM.getContext()),
+ endIter = OCD->classmeth_end(CGM.getContext());
+ iter != endIter ; iter++) {
ClassMethodSels.push_back((*iter)->getSelector());
std::string TypeStr;
CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr);
// Collect information about instance methods
llvm::SmallVector<Selector, 16> InstanceMethodSels;
llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
- for (ObjCImplementationDecl::instmeth_iterator iter = OID->instmeth_begin(),
- endIter = OID->instmeth_end() ; iter != endIter ; iter++) {
+ for (ObjCImplementationDecl::instmeth_iterator
+ iter = OID->instmeth_begin(CGM.getContext()),
+ endIter = OID->instmeth_end(CGM.getContext());
+ iter != endIter ; iter++) {
InstanceMethodSels.push_back((*iter)->getSelector());
std::string TypeStr;
Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
// Collect information about class methods
llvm::SmallVector<Selector, 16> ClassMethodSels;
llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
- for (ObjCImplementationDecl::classmeth_iterator iter = OID->classmeth_begin(),
- endIter = OID->classmeth_end() ; iter != endIter ; iter++) {
+ for (ObjCImplementationDecl::classmeth_iterator
+ iter = OID->classmeth_begin(CGM.getContext()),
+ endIter = OID->classmeth_end(CGM.getContext());
+ iter != endIter ; iter++) {
ClassMethodSels.push_back((*iter)->getSelector());
std::string TypeStr;
Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
OCD->getNameAsString());
std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
- for (ObjCCategoryImplDecl::instmeth_iterator i = OCD->instmeth_begin(),
- e = OCD->instmeth_end(); i != e; ++i) {
+ for (ObjCCategoryImplDecl::instmeth_iterator
+ i = OCD->instmeth_begin(CGM.getContext()),
+ e = OCD->instmeth_end(CGM.getContext()); i != e; ++i) {
// Instance methods should always be defined.
InstanceMethods.push_back(GetMethodConstant(*i));
}
- for (ObjCCategoryImplDecl::classmeth_iterator i = OCD->classmeth_begin(),
- e = OCD->classmeth_end(); i != e; ++i) {
+ for (ObjCCategoryImplDecl::classmeth_iterator
+ i = OCD->classmeth_begin(CGM.getContext()),
+ e = OCD->classmeth_end(CGM.getContext()); i != e; ++i) {
// Class methods should always be defined.
ClassMethods.push_back(GetMethodConstant(*i));
}
Flags |= eClassFlags_Hidden;
std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
- for (ObjCImplementationDecl::instmeth_iterator i = ID->instmeth_begin(),
- e = ID->instmeth_end(); i != e; ++i) {
+ for (ObjCImplementationDecl::instmeth_iterator
+ i = ID->instmeth_begin(CGM.getContext()),
+ e = ID->instmeth_end(CGM.getContext()); i != e; ++i) {
// Instance methods should always be defined.
InstanceMethods.push_back(GetMethodConstant(*i));
}
- for (ObjCImplementationDecl::classmeth_iterator i = ID->classmeth_begin(),
- e = ID->classmeth_end(); i != e; ++i) {
+ for (ObjCImplementationDecl::classmeth_iterator
+ i = ID->classmeth_begin(CGM.getContext()),
+ e = ID->classmeth_end(CGM.getContext()); i != e; ++i) {
// Class methods should always be defined.
ClassMethods.push_back(GetMethodConstant(*i));
}
- for (ObjCImplementationDecl::propimpl_iterator i = ID->propimpl_begin(),
- e = ID->propimpl_end(); i != e; ++i) {
+ for (ObjCImplementationDecl::propimpl_iterator
+ i = ID->propimpl_begin(CGM.getContext()),
+ e = ID->propimpl_end(CGM.getContext()); i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
std::string MethodListName("\01l_OBJC_$_");
if (flags & CLS_META) {
MethodListName += "CLASS_METHODS_" + ID->getNameAsString();
- for (ObjCImplementationDecl::classmeth_iterator i = ID->classmeth_begin(),
- e = ID->classmeth_end(); i != e; ++i) {
+ for (ObjCImplementationDecl::classmeth_iterator
+ i = ID->classmeth_begin(CGM.getContext()),
+ e = ID->classmeth_end(CGM.getContext()); i != e; ++i) {
// Class methods should always be defined.
Methods.push_back(GetMethodConstant(*i));
}
} else {
MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString();
- for (ObjCImplementationDecl::instmeth_iterator i = ID->instmeth_begin(),
- e = ID->instmeth_end(); i != e; ++i) {
+ for (ObjCImplementationDecl::instmeth_iterator
+ i = ID->instmeth_begin(CGM.getContext()),
+ e = ID->instmeth_end(CGM.getContext()); i != e; ++i) {
// Instance methods should always be defined.
Methods.push_back(GetMethodConstant(*i));
}
- for (ObjCImplementationDecl::propimpl_iterator i = ID->propimpl_begin(),
- e = ID->propimpl_end(); i != e; ++i) {
+ for (ObjCImplementationDecl::propimpl_iterator
+ i = ID->propimpl_begin(CGM.getContext()),
+ e = ID->propimpl_end(CGM.getContext()); i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() +
"_$_" + OCD->getNameAsString();
- for (ObjCCategoryImplDecl::instmeth_iterator i = OCD->instmeth_begin(),
- e = OCD->instmeth_end(); i != e; ++i) {
+ for (ObjCCategoryImplDecl::instmeth_iterator
+ i = OCD->instmeth_begin(CGM.getContext()),
+ e = OCD->instmeth_end(CGM.getContext()); i != e; ++i) {
// Instance methods should always be defined.
Methods.push_back(GetMethodConstant(*i));
}
MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" +
OCD->getNameAsString();
Methods.clear();
- for (ObjCCategoryImplDecl::classmeth_iterator i = OCD->classmeth_begin(),
- e = OCD->classmeth_end(); i != e; ++i) {
+ for (ObjCCategoryImplDecl::classmeth_iterator
+ i = OCD->classmeth_begin(CGM.getContext()),
+ e = OCD->classmeth_end(CGM.getContext()); i != e; ++i) {
// Class methods should always be defined.
Methods.push_back(GetMethodConstant(*i));
}
/// properties for an implementation.
void CodeGenModule::EmitObjCPropertyImplementations(const
ObjCImplementationDecl *D) {
- for (ObjCImplementationDecl::propimpl_iterator i = D->propimpl_begin(),
- e = D->propimpl_end(); i != e; ++i) {
+ for (ObjCImplementationDecl::propimpl_iterator
+ i = D->propimpl_begin(getContext()),
+ e = D->propimpl_end(getContext()); i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
// Dynamic is just for type-checking.
// we want, that just indicates if the decl came from a
// property. What we want to know is if the method is defined in
// this implementation.
- if (!D->getInstanceMethod(PD->getGetterName()))
+ if (!D->getInstanceMethod(getContext(), PD->getGetterName()))
CodeGenFunction(*this).GenerateObjCGetter(
const_cast<ObjCImplementationDecl *>(D), PID);
if (!PD->isReadOnly() &&
- !D->getInstanceMethod(PD->getSetterName()))
+ !D->getInstanceMethod(getContext(), PD->getSetterName()))
CodeGenFunction(*this).GenerateObjCSetter(
const_cast<ObjCImplementationDecl *>(D), PID);
}
if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurContext)) {
if (ObjCImplementationDecl *IMD =
dyn_cast<ObjCImplementationDecl>(OMD->getDeclContext())) {
- if (IMD->getInstanceMethod(PDecl->getSetterName()))
+ if (IMD->getInstanceMethod(Context, PDecl->getSetterName()))
return false;
}
else if (ObjCCategoryImplDecl *CIMD =
dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
- if (CIMD->getInstanceMethod(PDecl->getSetterName()))
+ if (CIMD->getInstanceMethod(Context, PDecl->getSetterName()))
return false;
}
}
// Lastly, look through the implementation (if one is in scope).
if (ObjCImplementationDecl *ImpDecl =
ObjCImplementations[IDecl->getIdentifier()])
- if (ImpDecl->getInstanceMethod(PDecl->getSetterName()))
+ if (ImpDecl->getInstanceMethod(Context, PDecl->getSetterName()))
return false;
// If all fails, look at the super class.
if (ObjCInterfaceDecl *SIDecl = IDecl->getSuperClass())
llvm::DenseSet<Selector> InsMap;
// Check and see if instance methods in class interface have been
// implemented in the implementation class.
- for (ObjCImplementationDecl::instmeth_iterator I = IMPDecl->instmeth_begin(),
- E = IMPDecl->instmeth_end(); I != E; ++I)
+ for (ObjCImplementationDecl::instmeth_iterator
+ I = IMPDecl->instmeth_begin(Context),
+ E = IMPDecl->instmeth_end(Context); I != E; ++I)
InsMap.insert((*I)->getSelector());
// Check and see if properties declared in the interface have either 1)
continue;
ObjCPropertyImplDecl *PI = 0;
// Is there a matching propery synthesize/dynamic?
- for (ObjCImplDecl::propimpl_iterator I = IMPDecl->propimpl_begin(),
- EI = IMPDecl->propimpl_end(); I != EI; ++I)
+ for (ObjCImplDecl::propimpl_iterator
+ I = IMPDecl->propimpl_begin(Context),
+ EI = IMPDecl->propimpl_end(Context); I != EI; ++I)
if ((*I)->getPropertyDecl() == Prop) {
PI = (*I);
break;
}
ObjCMethodDecl *ImpMethodDecl =
- IMPDecl->getInstanceMethod((*I)->getSelector());
+ IMPDecl->getInstanceMethod(Context, (*I)->getSelector());
ObjCMethodDecl *IntfMethodDecl =
CDecl->getInstanceMethod(Context, (*I)->getSelector());
assert(IntfMethodDecl &&
llvm::DenseSet<Selector> ClsMap;
// Check and see if class methods in class interface have been
// implemented in the implementation class.
- for (ObjCImplementationDecl::classmeth_iterator I =IMPDecl->classmeth_begin(),
- E = IMPDecl->classmeth_end(); I != E; ++I)
+ for (ObjCImplementationDecl::classmeth_iterator
+ I = IMPDecl->classmeth_begin(Context),
+ E = IMPDecl->classmeth_end(Context); I != E; ++I)
ClsMap.insert((*I)->getSelector());
for (ObjCInterfaceDecl::classmeth_iterator
WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
else {
ObjCMethodDecl *ImpMethodDecl =
- IMPDecl->getClassMethod((*I)->getSelector());
+ IMPDecl->getClassMethod(Context, (*I)->getSelector());
ObjCMethodDecl *IntfMethodDecl =
CDecl->getClassMethod(Context, (*I)->getSelector());
WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
if (ObjCImplementationDecl *ImpDecl =
dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
if (MethodType == tok::minus) {
- PrevMethod = ImpDecl->getInstanceMethod(Sel);
- ImpDecl->addInstanceMethod(ObjCMethod);
+ PrevMethod = ImpDecl->getInstanceMethod(Context, Sel);
+ ImpDecl->addInstanceMethod(Context, ObjCMethod);
} else {
- PrevMethod = ImpDecl->getClassMethod(Sel);
- ImpDecl->addClassMethod(ObjCMethod);
+ PrevMethod = ImpDecl->getClassMethod(Context, Sel);
+ ImpDecl->addClassMethod(Context, ObjCMethod);
}
}
else if (ObjCCategoryImplDecl *CatImpDecl =
dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
if (MethodType == tok::minus) {
- PrevMethod = CatImpDecl->getInstanceMethod(Sel);
- CatImpDecl->addInstanceMethod(ObjCMethod);
+ PrevMethod = CatImpDecl->getInstanceMethod(Context, Sel);
+ CatImpDecl->addInstanceMethod(Context, ObjCMethod);
} else {
- PrevMethod = CatImpDecl->getClassMethod(Sel);
- CatImpDecl->addClassMethod(ObjCMethod);
+ PrevMethod = CatImpDecl->getClassMethod(Context, Sel);
+ CatImpDecl->addClassMethod(Context, ObjCMethod);
}
}
if (PrevMethod) {
ObjCPropertyImplDecl::Synthesize
: ObjCPropertyImplDecl::Dynamic),
Ivar);
- CurContext->addDecl(Context, PIDecl);
if (IC) {
if (Synthesize)
if (ObjCPropertyImplDecl *PPIDecl =
- IC->FindPropertyImplIvarDecl(PropertyIvar)) {
+ IC->FindPropertyImplIvarDecl(Context, PropertyIvar)) {
Diag(PropertyLoc, diag::error_duplicate_ivar_use)
<< PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
<< PropertyIvar;
Diag(PPIDecl->getLocation(), diag::note_previous_use);
}
- if (ObjCPropertyImplDecl *PPIDecl = IC->FindPropertyImplDecl(PropertyId)) {
+ if (ObjCPropertyImplDecl *PPIDecl
+ = IC->FindPropertyImplDecl(Context, PropertyId)) {
Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
return DeclPtrTy();
}
- IC->addPropertyImplementation(PIDecl);
+ IC->addPropertyImplementation(Context, PIDecl);
}
else {
if (Synthesize)
if (ObjCPropertyImplDecl *PPIDecl =
- CatImplClass->FindPropertyImplIvarDecl(PropertyIvar)) {
+ CatImplClass->FindPropertyImplIvarDecl(Context, PropertyIvar)) {
Diag(PropertyLoc, diag::error_duplicate_ivar_use)
<< PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
<< PropertyIvar;
}
if (ObjCPropertyImplDecl *PPIDecl =
- CatImplClass->FindPropertyImplDecl(PropertyId)) {
+ CatImplClass->FindPropertyImplDecl(Context, PropertyId)) {
Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
return DeclPtrTy();
}
- CatImplClass->addPropertyImplementation(PIDecl);
+ CatImplClass->addPropertyImplementation(Context, PIDecl);
}
return DeclPtrTy::make(PIDecl);
ObjCMethodDecl *Method = 0;
if (ObjCImplementationDecl *ImpDecl =
Sema::ObjCImplementations[IFace->getIdentifier()])
- Method = ImpDecl->getInstanceMethod(Sel);
+ Method = ImpDecl->getInstanceMethod(Context, Sel);
if (!Method && IFace->getSuperClass())
return FindMethodInNestedImplementations(IFace->getSuperClass(), Sel);
if (!Getter) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Getter; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
- Getter = ObjCCategoryImpls[i]->getInstanceMethod(Sel);
+ Getter = ObjCCategoryImpls[i]->getInstanceMethod(Context, Sel);
}
}
if (Getter) {
if (!Setter) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
- Setter = ObjCCategoryImpls[i]->getInstanceMethod(SetterSel);
+ Setter = ObjCCategoryImpls[i]->getInstanceMethod(Context, SetterSel);
}
}
if (!Setter) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
- Setter = ObjCCategoryImpls[i]->getClassMethod(SetterSel);
+ Setter = ObjCCategoryImpls[i]->getClassMethod(Context, SetterSel);
}
}
while (ClassDecl && !Method) {
if (ObjCImplementationDecl *ImpDecl =
ObjCImplementations[ClassDecl->getIdentifier()])
- Method = ImpDecl->getClassMethod(Sel);
+ Method = ImpDecl->getClassMethod(Context, Sel);
// Look through local category implementations associated with the class.
if (!Method) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl)
- Method = ObjCCategoryImpls[i]->getClassMethod(Sel);
+ Method = ObjCCategoryImpls[i]->getClassMethod(Context, Sel);
}
}
// If we have implementations in scope, check "private" methods.
if (ObjCImplementationDecl *ImpDecl =
ObjCImplementations[ClassDecl->getIdentifier()])
- Method = ImpDecl->getInstanceMethod(Sel);
+ Method = ImpDecl->getInstanceMethod(Context, Sel);
// Look through local category implementations associated with the class.
if (!Method) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl)
- Method = ObjCCategoryImpls[i]->getInstanceMethod(Sel);
+ Method = ObjCCategoryImpls[i]->getInstanceMethod(Context, Sel);
}
}
ClassDecl = ClassDecl->getSuperClass();
if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
if (ObjCImplementationDecl *ImpDecl =
ObjCImplementations[ClassDecl->getIdentifier()])
- Getter = ImpDecl->getClassMethod(Sel);
+ Getter = ImpDecl->getClassMethod(Context, Sel);
if (Getter) {
// FIXME: refactor/share with ActOnMemberReference().
if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
if (ObjCImplementationDecl *ImpDecl =
ObjCImplementations[ClassDecl->getIdentifier()])
- Setter = ImpDecl->getClassMethod(SetterSel);
+ Setter = ImpDecl->getClassMethod(Context, SetterSel);
}
// Look through local category implementations associated with the class.
if (!Setter) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
- Setter = ObjCCategoryImpls[i]->getClassMethod(SetterSel);
+ Setter = ObjCCategoryImpls[i]->getClassMethod(Context, SetterSel);
}
}
else
Out << "@implementation " << I;
- for (ObjCImplementationDecl::instmeth_iterator I = OID->instmeth_begin(),
- E = OID->instmeth_end(); I != E; ++I) {
+ // FIXME: Don't use a NULL context
+ ASTContext *Context = 0;
+ for (ObjCImplementationDecl::instmeth_iterator
+ I = OID->instmeth_begin(*Context),
+ E = OID->instmeth_end(*Context);
+ I != E; ++I) {
ObjCMethodDecl *OMD = *I;
PrintObjCMethodDecl(OMD);
if (OMD->getBody()) {
}
}
- for (ObjCImplementationDecl::classmeth_iterator I = OID->classmeth_begin(),
- E = OID->classmeth_end(); I != E; ++I) {
+ for (ObjCImplementationDecl::classmeth_iterator
+ I = OID->classmeth_begin(*Context),
+ E = OID->classmeth_end(*Context);
+ I != E; ++I) {
ObjCMethodDecl *OMD = *I;
PrintObjCMethodDecl(OMD);
if (OMD->getBody()) {
}
}
- for (ObjCImplementationDecl::propimpl_iterator I = OID->propimpl_begin(),
- E = OID->propimpl_end(); I != E; ++I)
+ for (ObjCImplementationDecl::propimpl_iterator
+ I = OID->propimpl_begin(*Context),
+ E = OID->propimpl_end(*Context); I != E; ++I)
PrintObjCPropertyImplDecl(*I);
Out << "@end\n";
Out << "@implementation "
<< PID->getClassInterface()->getNameAsString()
<< '(' << PID->getNameAsString() << ");\n";
- for (ObjCCategoryImplDecl::propimpl_iterator I = PID->propimpl_begin(),
- E = PID->propimpl_end(); I != E; ++I)
+
+ // FIXME: Don't use a NULL context here
+ ASTContext *Context = 0;
+ for (ObjCCategoryImplDecl::propimpl_iterator
+ I = PID->propimpl_begin(*Context),
+ E = PID->propimpl_end(*Context); I != E; ++I)
PrintObjCPropertyImplDecl(*I);
Out << "@end\n";
// FIXME: implement the rest...
void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl,
std::string &Result);
- typedef ObjCCategoryImplDecl::instmeth_iterator instmeth_iterator;
- void RewriteObjCMethodsMetaData(instmeth_iterator MethodBegin,
- instmeth_iterator MethodEnd,
+ template<typename MethodIterator>
+ void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
+ MethodIterator MethodEnd,
bool IsInstanceMethod,
const char *prefix,
const char *ClassName,
Getr += "; }";
InsertText(onePastSemiLoc, Getr.c_str(), Getr.size());
- // Add the rewritten getter to trigger meta data generation. An alternate, and
- // possibly cleaner approach is to hack RewriteObjCMethodsMetaData() to deal
- // with properties explicitly. The following addInstanceMethod() required far
- // less code change (and actually models what the rewriter is doing).
- if (IMD)
- IMD->addInstanceMethod(PD->getGetterMethodDecl());
- else
- CID->addInstanceMethod(PD->getGetterMethodDecl());
-
if (PD->isReadOnly())
return;
Setr += PD->getNameAsCString();
Setr += "; }";
InsertText(onePastSemiLoc, Setr.c_str(), Setr.size());
-
- // Add the rewritten setter to trigger meta data generation.
- if (IMD)
- IMD->addInstanceMethod(PD->getSetterMethodDecl());
- else
- CID->addInstanceMethod(PD->getSetterMethodDecl());
}
void RewriteObjC::RewriteForwardClassDecl(ObjCClassDecl *ClassDecl) {
InsertText(CID->getLocStart(), "// ", 3);
for (ObjCCategoryImplDecl::instmeth_iterator
- I = IMD ? IMD->instmeth_begin() : CID->instmeth_begin(),
- E = IMD ? IMD->instmeth_end() : CID->instmeth_end(); I != E; ++I) {
+ I = IMD ? IMD->instmeth_begin(*Context) : CID->instmeth_begin(*Context),
+ E = IMD ? IMD->instmeth_end(*Context) : CID->instmeth_end(*Context);
+ I != E; ++I) {
std::string ResultStr;
ObjCMethodDecl *OMD = *I;
RewriteObjCMethodDecl(OMD, ResultStr);
}
for (ObjCCategoryImplDecl::classmeth_iterator
- I = IMD ? IMD->classmeth_begin() : CID->classmeth_begin(),
- E = IMD ? IMD->classmeth_end() : CID->classmeth_end(); I != E; ++I) {
+ I = IMD ? IMD->classmeth_begin(*Context) : CID->classmeth_begin(*Context),
+ E = IMD ? IMD->classmeth_end(*Context) : CID->classmeth_end(*Context);
+ I != E; ++I) {
std::string ResultStr;
ObjCMethodDecl *OMD = *I;
RewriteObjCMethodDecl(OMD, ResultStr);
ResultStr.c_str(), ResultStr.size());
}
for (ObjCCategoryImplDecl::propimpl_iterator
- I = IMD ? IMD->propimpl_begin() : CID->propimpl_begin(),
- E = IMD ? IMD->propimpl_end() : CID->propimpl_end(); I != E; ++I) {
+ I = IMD ? IMD->propimpl_begin(*Context) : CID->propimpl_begin(*Context),
+ E = IMD ? IMD->propimpl_end(*Context) : CID->propimpl_end(*Context);
+ I != E; ++I) {
RewritePropertyImplDecl(*I, IMD, CID);
}
// RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or
/// class methods.
-void RewriteObjC::RewriteObjCMethodsMetaData(instmeth_iterator MethodBegin,
- instmeth_iterator MethodEnd,
+template<typename MethodIterator>
+void RewriteObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
+ MethodIterator MethodEnd,
bool IsInstanceMethod,
const char *prefix,
const char *ClassName,
struct _objc_method method_list[];
}
*/
+ unsigned NumMethods = std::distance(MethodBegin, MethodEnd);
Result += "\nstatic struct {\n";
Result += "\tstruct _objc_method_list *next_method;\n";
Result += "\tint method_count;\n";
Result += "\tstruct _objc_method method_list[";
- Result += utostr(MethodEnd-MethodBegin);
+ Result += utostr(NumMethods);
Result += "];\n} _OBJC_";
Result += prefix;
Result += IsInstanceMethod ? "INSTANCE" : "CLASS";
Result += " __attribute__ ((used, section (\"__OBJC, __";
Result += IsInstanceMethod ? "inst" : "cls";
Result += "_meth\")))= ";
- Result += "{\n\t0, " + utostr(MethodEnd-MethodBegin) + "\n";
+ Result += "{\n\t0, " + utostr(NumMethods) + "\n";
Result += "\t,{{(SEL)\"";
Result += (*MethodBegin)->getSelector().getAsString().c_str();
std::string FullCategoryName = ClassDecl->getNameAsString();
FullCategoryName += '_';
FullCategoryName += IDecl->getNameAsString();
-
+
// Build _objc_method_list for class's instance methods if needed
- RewriteObjCMethodsMetaData(IDecl->instmeth_begin(), IDecl->instmeth_end(),
+ llvm::SmallVector<ObjCMethodDecl *, 32>
+ InstanceMethods(IDecl->instmeth_begin(*Context),
+ IDecl->instmeth_end(*Context));
+
+ // If any of our property implementations have associated getters or
+ // setters, produce metadata for them as well.
+ for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(*Context),
+ PropEnd = IDecl->propimpl_end(*Context);
+ Prop != PropEnd; ++Prop) {
+ if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+ continue;
+ if (!(*Prop)->getPropertyIvarDecl())
+ continue;
+ ObjCPropertyDecl *PD = (*Prop)->getPropertyDecl();
+ if (!PD)
+ continue;
+ if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
+ InstanceMethods.push_back(Getter);
+ if (PD->isReadOnly())
+ continue;
+ if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
+ InstanceMethods.push_back(Setter);
+ }
+ RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
true, "CATEGORY_", FullCategoryName.c_str(),
Result);
// Build _objc_method_list for class's class methods if needed
- RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
+ RewriteObjCMethodsMetaData(IDecl->classmeth_begin(*Context),
+ IDecl->classmeth_end(*Context),
false, "CATEGORY_", FullCategoryName.c_str(),
Result);
Result += ClassDecl->getNameAsString();
Result += "\"\n";
- if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
+ if (IDecl->instmeth_begin(*Context) != IDecl->instmeth_end(*Context)) {
Result += "\t, (struct _objc_method_list *)"
"&_OBJC_CATEGORY_INSTANCE_METHODS_";
Result += FullCategoryName;
}
else
Result += "\t, 0\n";
- if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
+ if (IDecl->classmeth_begin(*Context) != IDecl->classmeth_end(*Context)) {
Result += "\t, (struct _objc_method_list *)"
"&_OBJC_CATEGORY_CLASS_METHODS_";
Result += FullCategoryName;
}
// Build _objc_method_list for class's instance methods if needed
- RewriteObjCMethodsMetaData(IDecl->instmeth_begin(), IDecl->instmeth_end(),
+ llvm::SmallVector<ObjCMethodDecl *, 32>
+ InstanceMethods(IDecl->instmeth_begin(*Context),
+ IDecl->instmeth_end(*Context));
+
+ // If any of our property implementations have associated getters or
+ // setters, produce metadata for them as well.
+ for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(*Context),
+ PropEnd = IDecl->propimpl_end(*Context);
+ Prop != PropEnd; ++Prop) {
+ if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+ continue;
+ if (!(*Prop)->getPropertyIvarDecl())
+ continue;
+ ObjCPropertyDecl *PD = (*Prop)->getPropertyDecl();
+ if (!PD)
+ continue;
+ if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
+ InstanceMethods.push_back(Getter);
+ if (PD->isReadOnly())
+ continue;
+ if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
+ InstanceMethods.push_back(Setter);
+ }
+ RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
true, "", IDecl->getNameAsCString(), Result);
// Build _objc_method_list for class's class methods if needed
- RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
+ RewriteObjCMethodsMetaData(IDecl->classmeth_begin(*Context),
+ IDecl->classmeth_end(*Context),
false, "", IDecl->getNameAsCString(), Result);
// Protocols referenced in class declaration?
// Set 'ivars' field for root class to 0. ObjC1 runtime does not use it.
// 'info' field is initialized to CLS_META(2) for metaclass
Result += ", 0,2, sizeof(struct _objc_class), 0";
- if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
+ if (IDecl->classmeth_begin(*Context) != IDecl->classmeth_end(*Context)) {
Result += "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_";
Result += IDecl->getNameAsString();
Result += "\n";
}
else
Result += ",0";
- if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
+ if (IDecl->instmeth_begin(*Context) != IDecl->instmeth_end(*Context)) {
Result += ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_";
Result += CDecl->getNameAsString();
Result += ", 0\n\t";