// FIXME: A callback should disable checkers at the start of functions. static bool shouldRunOnFunctionOrMethod(const NamedDecl *ND) { if (!ND) return false; const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(ND); if (!MD) return false; if (!isInitializationMethod(MD)) return false; // self = [super init] applies only to NSObject subclasses. // For instance, NSProxy doesn't implement -init. ASTContext &Ctx = MD->getASTContext(); IdentifierInfo* NSObjectII = &Ctx.Idents.get("NSObject"); ObjCInterfaceDecl *ID = MD->getClassInterface()->getSuperClass(); for ( ; ID ; ID = ID->getSuperClass()) { IdentifierInfo *II = ID->getIdentifier(); if (II == NSObjectII) break; } if (!ID) return false; return true; }
/// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super /// class whose name is passed as argument. If it is not one of the super classes /// the it returns NULL. ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass( const IdentifierInfo*ICName) { ObjCInterfaceDecl* ClassDecl = this; while (ClassDecl != NULL) { if (ClassDecl->getIdentifier() == ICName) return ClassDecl; ClassDecl = ClassDecl->getSuperClass(); } return NULL; }
void CGObjCJit::GenerateClass(const ObjCImplementationDecl *ClassDecl) { if (isUsable) { const char* ClassName = ClassDecl->getIdentifier()->getNameStart(); void* Superclass = 0; ObjCInterfaceDecl *superClassDecl = ClassDecl->getClassInterface()->getSuperClass(); if (superClassDecl) { const char* superClassName = superClassDecl->getIdentifier()->getNameStart(); Superclass = _objc_getClass(superClassName); } void *theClass = _objc_allocateClassPair(Superclass, ClassName, 0); // TODO: always zero? // Add methods AddMethodsToClass(theClass); // Add interface ivars const ObjCInterfaceDecl *classInterfaceDecl = ClassDecl->getClassInterface(); AddIvarsToClass(theClass, classInterfaceDecl->ivar_begin(), classInterfaceDecl->ivar_end()); // Add implementation ivars AddIvarsToClass(theClass, ClassDecl->ivar_begin(), ClassDecl->ivar_end()); // Add protocols ObjCInterfaceDecl::protocol_iterator protocol = classInterfaceDecl->protocol_begin(); const ObjCInterfaceDecl::protocol_iterator protocol_end = classInterfaceDecl->protocol_end(); while (protocol != protocol_end) { void *theProtocol = 0; // Search "locally" first, then from runtime llvm::StringMap<void*>::iterator proto_local = DefinedProtocols.find((*protocol)->getName()); if (proto_local != DefinedProtocols.end()) { theProtocol = proto_local->second; } else { theProtocol = _objc_getProtocol((*protocol)->getNameAsString().c_str()); } _class_addProtocol(theClass, theProtocol); protocol++; } // Finalize class (adding methods later, at runtime, in init function) _objc_registerClassPair(theClass); } }
ExprResult Sema::ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, Selector Sel, SourceLocation LBracLoc, SourceLocation SelectorLoc, SourceLocation RBracLoc, MultiExprArg Args) { // Determine whether we are inside a method or not. ObjCMethodDecl *Method = tryCaptureObjCSelf(); if (!Method) { Diag(SuperLoc, diag::err_invalid_receiver_to_message_super); return ExprError(); } ObjCInterfaceDecl *Class = Method->getClassInterface(); if (!Class) { Diag(SuperLoc, diag::error_no_super_class_message) << Method->getDeclName(); return ExprError(); } ObjCInterfaceDecl *Super = Class->getSuperClass(); if (!Super) { // The current class does not have a superclass. Diag(SuperLoc, diag::error_root_class_cannot_use_super) << Class->getIdentifier(); return ExprError(); } // We are in a method whose class has a superclass, so 'super' // is acting as a keyword. if (Method->isInstanceMethod()) { // Since we are in an instance method, this is an instance // message to the superclass instance. QualType SuperTy = Context.getObjCInterfaceType(Super); SuperTy = Context.getObjCObjectPointerType(SuperTy); return BuildInstanceMessage(0, SuperTy, SuperLoc, Sel, /*Method=*/0, LBracLoc, SelectorLoc, RBracLoc, move(Args)); } // Since we are in a class method, this is a class message to // the superclass. return BuildClassMessage(/*ReceiverTypeInfo=*/0, Context.getObjCInterfaceType(Super), SuperLoc, Sel, /*Method=*/0, LBracLoc, SelectorLoc, RBracLoc, move(Args)); }
/// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super /// class whose name is passed as argument. If it is not one of the super classes /// the it returns NULL. ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass( const IdentifierInfo*ICName) { // FIXME: Should make sure no callers ever do this. if (!hasDefinition()) return 0; if (data().ExternallyCompleted) LoadExternalDefinition(); ObjCInterfaceDecl* ClassDecl = this; while (ClassDecl != NULL) { if (ClassDecl->getIdentifier() == ICName) return ClassDecl; ClassDecl = ClassDecl->getSuperClass(); } return NULL; }