NSAPI.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. //===--- NSAPI.cpp - NSFoundation APIs ------------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "clang/AST/NSAPI.h"
  10. #include "clang/AST/ASTContext.h"
  11. #include "clang/AST/Expr.h"
  12. using namespace clang;
  13. NSAPI::NSAPI(ASTContext &ctx)
  14. : Ctx(ctx), ClassIds(), BOOLId(0), NSIntegerId(0), NSUIntegerId(0),
  15. NSASCIIStringEncodingId(0), NSUTF8StringEncodingId(0) {
  16. }
  17. IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
  18. static const char *ClassName[NumClassIds] = {
  19. "NSObject",
  20. "NSString",
  21. "NSArray",
  22. "NSMutableArray",
  23. "NSDictionary",
  24. "NSMutableDictionary",
  25. "NSNumber"
  26. };
  27. if (!ClassIds[K])
  28. return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));
  29. return ClassIds[K];
  30. }
  31. Selector NSAPI::getNSStringSelector(NSStringMethodKind MK) const {
  32. if (NSStringSelectors[MK].isNull()) {
  33. Selector Sel;
  34. switch (MK) {
  35. case NSStr_stringWithString:
  36. Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithString"));
  37. break;
  38. case NSStr_stringWithUTF8String:
  39. Sel = Ctx.Selectors.getUnarySelector(
  40. &Ctx.Idents.get("stringWithUTF8String"));
  41. break;
  42. case NSStr_stringWithCStringEncoding: {
  43. IdentifierInfo *KeyIdents[] = {
  44. &Ctx.Idents.get("stringWithCString"),
  45. &Ctx.Idents.get("encoding")
  46. };
  47. Sel = Ctx.Selectors.getSelector(2, KeyIdents);
  48. break;
  49. }
  50. case NSStr_stringWithCString:
  51. Sel= Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithCString"));
  52. break;
  53. case NSStr_initWithString:
  54. Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString"));
  55. break;
  56. }
  57. return (NSStringSelectors[MK] = Sel);
  58. }
  59. return NSStringSelectors[MK];
  60. }
  61. llvm::Optional<NSAPI::NSStringMethodKind>
  62. NSAPI::getNSStringMethodKind(Selector Sel) const {
  63. for (unsigned i = 0; i != NumNSStringMethods; ++i) {
  64. NSStringMethodKind MK = NSStringMethodKind(i);
  65. if (Sel == getNSStringSelector(MK))
  66. return MK;
  67. }
  68. return llvm::Optional<NSStringMethodKind>();
  69. }
  70. Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const {
  71. if (NSArraySelectors[MK].isNull()) {
  72. Selector Sel;
  73. switch (MK) {
  74. case NSArr_array:
  75. Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array"));
  76. break;
  77. case NSArr_arrayWithArray:
  78. Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray"));
  79. break;
  80. case NSArr_arrayWithObject:
  81. Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject"));
  82. break;
  83. case NSArr_arrayWithObjects:
  84. Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects"));
  85. break;
  86. case NSArr_arrayWithObjectsCount: {
  87. IdentifierInfo *KeyIdents[] = {
  88. &Ctx.Idents.get("arrayWithObjects"),
  89. &Ctx.Idents.get("count")
  90. };
  91. Sel = Ctx.Selectors.getSelector(2, KeyIdents);
  92. break;
  93. }
  94. case NSArr_initWithArray:
  95. Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray"));
  96. break;
  97. case NSArr_initWithObjects:
  98. Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects"));
  99. break;
  100. case NSArr_objectAtIndex:
  101. Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex"));
  102. break;
  103. case NSMutableArr_replaceObjectAtIndex: {
  104. IdentifierInfo *KeyIdents[] = {
  105. &Ctx.Idents.get("replaceObjectAtIndex"),
  106. &Ctx.Idents.get("withObject")
  107. };
  108. Sel = Ctx.Selectors.getSelector(2, KeyIdents);
  109. break;
  110. }
  111. }
  112. return (NSArraySelectors[MK] = Sel);
  113. }
  114. return NSArraySelectors[MK];
  115. }
  116. llvm::Optional<NSAPI::NSArrayMethodKind>
  117. NSAPI::getNSArrayMethodKind(Selector Sel) {
  118. for (unsigned i = 0; i != NumNSArrayMethods; ++i) {
  119. NSArrayMethodKind MK = NSArrayMethodKind(i);
  120. if (Sel == getNSArraySelector(MK))
  121. return MK;
  122. }
  123. return llvm::Optional<NSArrayMethodKind>();
  124. }
  125. Selector NSAPI::getNSDictionarySelector(
  126. NSDictionaryMethodKind MK) const {
  127. if (NSDictionarySelectors[MK].isNull()) {
  128. Selector Sel;
  129. switch (MK) {
  130. case NSDict_dictionary:
  131. Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary"));
  132. break;
  133. case NSDict_dictionaryWithDictionary:
  134. Sel = Ctx.Selectors.getUnarySelector(
  135. &Ctx.Idents.get("dictionaryWithDictionary"));
  136. break;
  137. case NSDict_dictionaryWithObjectForKey: {
  138. IdentifierInfo *KeyIdents[] = {
  139. &Ctx.Idents.get("dictionaryWithObject"),
  140. &Ctx.Idents.get("forKey")
  141. };
  142. Sel = Ctx.Selectors.getSelector(2, KeyIdents);
  143. break;
  144. }
  145. case NSDict_dictionaryWithObjectsForKeys: {
  146. IdentifierInfo *KeyIdents[] = {
  147. &Ctx.Idents.get("dictionaryWithObjects"),
  148. &Ctx.Idents.get("forKeys")
  149. };
  150. Sel = Ctx.Selectors.getSelector(2, KeyIdents);
  151. break;
  152. }
  153. case NSDict_dictionaryWithObjectsForKeysCount: {
  154. IdentifierInfo *KeyIdents[] = {
  155. &Ctx.Idents.get("dictionaryWithObjects"),
  156. &Ctx.Idents.get("forKeys"),
  157. &Ctx.Idents.get("count")
  158. };
  159. Sel = Ctx.Selectors.getSelector(3, KeyIdents);
  160. break;
  161. }
  162. case NSDict_dictionaryWithObjectsAndKeys:
  163. Sel = Ctx.Selectors.getUnarySelector(
  164. &Ctx.Idents.get("dictionaryWithObjectsAndKeys"));
  165. break;
  166. case NSDict_initWithDictionary:
  167. Sel = Ctx.Selectors.getUnarySelector(
  168. &Ctx.Idents.get("initWithDictionary"));
  169. break;
  170. case NSDict_initWithObjectsAndKeys:
  171. Sel = Ctx.Selectors.getUnarySelector(
  172. &Ctx.Idents.get("initWithObjectsAndKeys"));
  173. break;
  174. case NSDict_initWithObjectsForKeys: {
  175. IdentifierInfo *KeyIdents[] = {
  176. &Ctx.Idents.get("initWithObjects"),
  177. &Ctx.Idents.get("forKeys")
  178. };
  179. Sel = Ctx.Selectors.getSelector(2, KeyIdents);
  180. break;
  181. }
  182. case NSDict_objectForKey:
  183. Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey"));
  184. break;
  185. case NSMutableDict_setObjectForKey: {
  186. IdentifierInfo *KeyIdents[] = {
  187. &Ctx.Idents.get("setObject"),
  188. &Ctx.Idents.get("forKey")
  189. };
  190. Sel = Ctx.Selectors.getSelector(2, KeyIdents);
  191. break;
  192. }
  193. }
  194. return (NSDictionarySelectors[MK] = Sel);
  195. }
  196. return NSDictionarySelectors[MK];
  197. }
  198. llvm::Optional<NSAPI::NSDictionaryMethodKind>
  199. NSAPI::getNSDictionaryMethodKind(Selector Sel) {
  200. for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) {
  201. NSDictionaryMethodKind MK = NSDictionaryMethodKind(i);
  202. if (Sel == getNSDictionarySelector(MK))
  203. return MK;
  204. }
  205. return llvm::Optional<NSDictionaryMethodKind>();
  206. }
  207. Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
  208. bool Instance) const {
  209. static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {
  210. "numberWithChar",
  211. "numberWithUnsignedChar",
  212. "numberWithShort",
  213. "numberWithUnsignedShort",
  214. "numberWithInt",
  215. "numberWithUnsignedInt",
  216. "numberWithLong",
  217. "numberWithUnsignedLong",
  218. "numberWithLongLong",
  219. "numberWithUnsignedLongLong",
  220. "numberWithFloat",
  221. "numberWithDouble",
  222. "numberWithBool",
  223. "numberWithInteger",
  224. "numberWithUnsignedInteger"
  225. };
  226. static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {
  227. "initWithChar",
  228. "initWithUnsignedChar",
  229. "initWithShort",
  230. "initWithUnsignedShort",
  231. "initWithInt",
  232. "initWithUnsignedInt",
  233. "initWithLong",
  234. "initWithUnsignedLong",
  235. "initWithLongLong",
  236. "initWithUnsignedLongLong",
  237. "initWithFloat",
  238. "initWithDouble",
  239. "initWithBool",
  240. "initWithInteger",
  241. "initWithUnsignedInteger"
  242. };
  243. Selector *Sels;
  244. const char **Names;
  245. if (Instance) {
  246. Sels = NSNumberInstanceSelectors;
  247. Names = InstanceSelectorName;
  248. } else {
  249. Sels = NSNumberClassSelectors;
  250. Names = ClassSelectorName;
  251. }
  252. if (Sels[MK].isNull())
  253. Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK]));
  254. return Sels[MK];
  255. }
  256. llvm::Optional<NSAPI::NSNumberLiteralMethodKind>
  257. NSAPI::getNSNumberLiteralMethodKind(Selector Sel) const {
  258. for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) {
  259. NSNumberLiteralMethodKind MK = NSNumberLiteralMethodKind(i);
  260. if (isNSNumberLiteralSelector(MK, Sel))
  261. return MK;
  262. }
  263. return llvm::Optional<NSNumberLiteralMethodKind>();
  264. }
  265. llvm::Optional<NSAPI::NSNumberLiteralMethodKind>
  266. NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
  267. const BuiltinType *BT = T->getAs<BuiltinType>();
  268. if (!BT)
  269. return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>();
  270. const TypedefType *TDT = T->getAs<TypedefType>();
  271. if (TDT) {
  272. QualType TDTTy = QualType(TDT, 0);
  273. if (isObjCBOOLType(TDTTy))
  274. return NSAPI::NSNumberWithBool;
  275. if (isObjCNSIntegerType(TDTTy))
  276. return NSAPI::NSNumberWithInteger;
  277. if (isObjCNSUIntegerType(TDTTy))
  278. return NSAPI::NSNumberWithUnsignedInteger;
  279. }
  280. switch (BT->getKind()) {
  281. case BuiltinType::Char_S:
  282. case BuiltinType::SChar:
  283. return NSAPI::NSNumberWithChar;
  284. case BuiltinType::Char_U:
  285. case BuiltinType::UChar:
  286. return NSAPI::NSNumberWithUnsignedChar;
  287. case BuiltinType::Short:
  288. return NSAPI::NSNumberWithShort;
  289. case BuiltinType::UShort:
  290. return NSAPI::NSNumberWithUnsignedShort;
  291. case BuiltinType::Int:
  292. return NSAPI::NSNumberWithInt;
  293. case BuiltinType::UInt:
  294. return NSAPI::NSNumberWithUnsignedInt;
  295. case BuiltinType::Long:
  296. return NSAPI::NSNumberWithLong;
  297. case BuiltinType::ULong:
  298. return NSAPI::NSNumberWithUnsignedLong;
  299. case BuiltinType::LongLong:
  300. return NSAPI::NSNumberWithLongLong;
  301. case BuiltinType::ULongLong:
  302. return NSAPI::NSNumberWithUnsignedLongLong;
  303. case BuiltinType::Float:
  304. return NSAPI::NSNumberWithFloat;
  305. case BuiltinType::Double:
  306. return NSAPI::NSNumberWithDouble;
  307. case BuiltinType::Bool:
  308. return NSAPI::NSNumberWithBool;
  309. case BuiltinType::Void:
  310. case BuiltinType::WChar_U:
  311. case BuiltinType::WChar_S:
  312. case BuiltinType::Char16:
  313. case BuiltinType::Char32:
  314. case BuiltinType::Int128:
  315. case BuiltinType::LongDouble:
  316. case BuiltinType::UInt128:
  317. case BuiltinType::NullPtr:
  318. case BuiltinType::ObjCClass:
  319. case BuiltinType::ObjCId:
  320. case BuiltinType::ObjCSel:
  321. case BuiltinType::OCLImage1d:
  322. case BuiltinType::OCLImage1dArray:
  323. case BuiltinType::OCLImage1dBuffer:
  324. case BuiltinType::OCLImage2d:
  325. case BuiltinType::OCLImage2dArray:
  326. case BuiltinType::OCLImage3d:
  327. case BuiltinType::OCLSampler:
  328. case BuiltinType::OCLEvent:
  329. case BuiltinType::BoundMember:
  330. case BuiltinType::Dependent:
  331. case BuiltinType::Overload:
  332. case BuiltinType::UnknownAny:
  333. case BuiltinType::ARCUnbridgedCast:
  334. case BuiltinType::Half:
  335. case BuiltinType::PseudoObject:
  336. case BuiltinType::BuiltinFn:
  337. break;
  338. }
  339. return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>();
  340. }
  341. /// \brief Returns true if \param T is a typedef of "BOOL" in objective-c.
  342. bool NSAPI::isObjCBOOLType(QualType T) const {
  343. return isObjCTypedef(T, "BOOL", BOOLId);
  344. }
  345. /// \brief Returns true if \param T is a typedef of "NSInteger" in objective-c.
  346. bool NSAPI::isObjCNSIntegerType(QualType T) const {
  347. return isObjCTypedef(T, "NSInteger", NSIntegerId);
  348. }
  349. /// \brief Returns true if \param T is a typedef of "NSUInteger" in objective-c.
  350. bool NSAPI::isObjCNSUIntegerType(QualType T) const {
  351. return isObjCTypedef(T, "NSUInteger", NSUIntegerId);
  352. }
  353. bool NSAPI::isObjCTypedef(QualType T,
  354. StringRef name, IdentifierInfo *&II) const {
  355. if (!Ctx.getLangOpts().ObjC1)
  356. return false;
  357. if (T.isNull())
  358. return false;
  359. if (!II)
  360. II = &Ctx.Idents.get(name);
  361. while (const TypedefType *TDT = T->getAs<TypedefType>()) {
  362. if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
  363. return true;
  364. T = TDT->desugar();
  365. }
  366. return false;
  367. }
  368. bool NSAPI::isObjCEnumerator(const Expr *E,
  369. StringRef name, IdentifierInfo *&II) const {
  370. if (!Ctx.getLangOpts().ObjC1)
  371. return false;
  372. if (!E)
  373. return false;
  374. if (!II)
  375. II = &Ctx.Idents.get(name);
  376. if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
  377. if (const EnumConstantDecl *
  378. EnumD = dyn_cast_or_null<EnumConstantDecl>(DRE->getDecl()))
  379. return EnumD->getIdentifier() == II;
  380. return false;
  381. }
  382. Selector NSAPI::getOrInitSelector(ArrayRef<StringRef> Ids,
  383. Selector &Sel) const {
  384. if (Sel.isNull()) {
  385. SmallVector<IdentifierInfo *, 4> Idents;
  386. for (ArrayRef<StringRef>::const_iterator
  387. I = Ids.begin(), E = Ids.end(); I != E; ++I)
  388. Idents.push_back(&Ctx.Idents.get(*I));
  389. Sel = Ctx.Selectors.getSelector(Idents.size(), Idents.data());
  390. }
  391. return Sel;
  392. }