clang API Documentation
00001 //= ObjCNoReturn.cpp - Handling of Cocoa APIs known not to return --*- C++ -*--- 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements special handling of recognizing ObjC API hooks that 00011 // do not return but aren't marked as such in API headers. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "clang/AST/ASTContext.h" 00016 #include "clang/AST/ExprObjC.h" 00017 #include "clang/Analysis/DomainSpecific/ObjCNoReturn.h" 00018 00019 using namespace clang; 00020 00021 static bool isSubclass(const ObjCInterfaceDecl *Class, IdentifierInfo *II) { 00022 if (!Class) 00023 return false; 00024 if (Class->getIdentifier() == II) 00025 return true; 00026 return isSubclass(Class->getSuperClass(), II); 00027 } 00028 00029 ObjCNoReturn::ObjCNoReturn(ASTContext &C) 00030 : RaiseSel(GetNullarySelector("raise", C)), 00031 NSExceptionII(&C.Idents.get("NSException")) 00032 { 00033 // Generate selectors. 00034 SmallVector<IdentifierInfo*, 3> II; 00035 00036 // raise:format: 00037 II.push_back(&C.Idents.get("raise")); 00038 II.push_back(&C.Idents.get("format")); 00039 NSExceptionInstanceRaiseSelectors[0] = 00040 C.Selectors.getSelector(II.size(), &II[0]); 00041 00042 // raise:format:arguments: 00043 II.push_back(&C.Idents.get("arguments")); 00044 NSExceptionInstanceRaiseSelectors[1] = 00045 C.Selectors.getSelector(II.size(), &II[0]); 00046 } 00047 00048 00049 bool ObjCNoReturn::isImplicitNoReturn(const ObjCMessageExpr *ME) { 00050 Selector S = ME->getSelector(); 00051 00052 if (ME->isInstanceMessage()) { 00053 // Check for the "raise" message. 00054 return S == RaiseSel; 00055 } 00056 00057 if (const ObjCInterfaceDecl *ID = ME->getReceiverInterface()) { 00058 if (isSubclass(ID, NSExceptionII)) { 00059 for (unsigned i = 0; i < NUM_RAISE_SELECTORS; ++i) { 00060 if (S == NSExceptionInstanceRaiseSelectors[i]) 00061 return true; 00062 } 00063 } 00064 } 00065 00066 return false; 00067 }