NSAPI.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. //===--- NSAPI.cpp - NSFoundation APIs ------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "clang/AST/NSAPI.h"
  9. #include "clang/AST/ASTContext.h"
  10. #include "clang/AST/DeclObjC.h"
  11. #include "clang/AST/Expr.h"
  12. #include "llvm/ADT/StringSwitch.h"
  13. #include <optional>
  14. using namespace clang;
  15. NSAPI::NSAPI(ASTContext &ctx)
  16. : Ctx(ctx), ClassIds(), BOOLId(nullptr), NSIntegerId(nullptr),
  17. NSUIntegerId(nullptr), NSASCIIStringEncodingId(nullptr),
  18. NSUTF8StringEncodingId(nullptr) {}
  19. IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
  20. static const char *ClassName[NumClassIds] = {
  21. "NSObject",
  22. "NSString",
  23. "NSArray",
  24. "NSMutableArray",
  25. "NSDictionary",
  26. "NSMutableDictionary",
  27. "NSNumber",
  28. "NSMutableSet",
  29. "NSMutableOrderedSet",
  30. "NSValue"
  31. };
  32. if (!ClassIds[K])
  33. return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));
  34. return ClassIds[K];
  35. }
  36. Selector NSAPI::getNSStringSelector(NSStringMethodKind MK) const {
  37. if (NSStringSelectors[MK].isNull()) {
  38. Selector Sel;
  39. switch (MK) {
  40. case NSStr_stringWithString:
  41. Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithString"));
  42. break;
  43. case NSStr_stringWithUTF8String:
  44. Sel = Ctx.Selectors.getUnarySelector(
  45. &Ctx.Idents.get("stringWithUTF8String"));
  46. break;
  47. case NSStr_initWithUTF8String:
  48. Sel = Ctx.Selectors.getUnarySelector(
  49. &Ctx.Idents.get("initWithUTF8String"));
  50. break;
  51. case NSStr_stringWithCStringEncoding: {
  52. IdentifierInfo *KeyIdents[] = {
  53. &Ctx.Idents.get("stringWithCString"),
  54. &Ctx.Idents.get("encoding")
  55. };
  56. Sel = Ctx.Selectors.getSelector(2, KeyIdents);
  57. break;
  58. }
  59. case NSStr_stringWithCString:
  60. Sel= Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithCString"));
  61. break;
  62. case NSStr_initWithString:
  63. Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString"));
  64. break;
  65. }
  66. return (NSStringSelectors[MK] = Sel);
  67. }
  68. return NSStringSelectors[MK];
  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. case NSMutableArr_addObject:
  112. Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
  113. break;
  114. case NSMutableArr_insertObjectAtIndex: {
  115. IdentifierInfo *KeyIdents[] = {
  116. &Ctx.Idents.get("insertObject"),
  117. &Ctx.Idents.get("atIndex")
  118. };
  119. Sel = Ctx.Selectors.getSelector(2, KeyIdents);
  120. break;
  121. }
  122. case NSMutableArr_setObjectAtIndexedSubscript: {
  123. IdentifierInfo *KeyIdents[] = {
  124. &Ctx.Idents.get("setObject"),
  125. &Ctx.Idents.get("atIndexedSubscript")
  126. };
  127. Sel = Ctx.Selectors.getSelector(2, KeyIdents);
  128. break;
  129. }
  130. }
  131. return (NSArraySelectors[MK] = Sel);
  132. }
  133. return NSArraySelectors[MK];
  134. }
  135. std::optional<NSAPI::NSArrayMethodKind>
  136. NSAPI::getNSArrayMethodKind(Selector Sel) {
  137. for (unsigned i = 0; i != NumNSArrayMethods; ++i) {
  138. NSArrayMethodKind MK = NSArrayMethodKind(i);
  139. if (Sel == getNSArraySelector(MK))
  140. return MK;
  141. }
  142. return std::nullopt;
  143. }
  144. Selector NSAPI::getNSDictionarySelector(
  145. NSDictionaryMethodKind MK) const {
  146. if (NSDictionarySelectors[MK].isNull()) {
  147. Selector Sel;
  148. switch (MK) {
  149. case NSDict_dictionary:
  150. Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary"));
  151. break;
  152. case NSDict_dictionaryWithDictionary:
  153. Sel = Ctx.Selectors.getUnarySelector(
  154. &Ctx.Idents.get("dictionaryWithDictionary"));
  155. break;
  156. case NSDict_dictionaryWithObjectForKey: {
  157. IdentifierInfo *KeyIdents[] = {
  158. &Ctx.Idents.get("dictionaryWithObject"),
  159. &Ctx.Idents.get("forKey")
  160. };
  161. Sel = Ctx.Selectors.getSelector(2, KeyIdents);
  162. break;
  163. }
  164. case NSDict_dictionaryWithObjectsForKeys: {
  165. IdentifierInfo *KeyIdents[] = {
  166. &Ctx.Idents.get("dictionaryWithObjects"),
  167. &Ctx.Idents.get("forKeys")
  168. };
  169. Sel = Ctx.Selectors.getSelector(2, KeyIdents);
  170. break;
  171. }
  172. case NSDict_dictionaryWithObjectsForKeysCount: {
  173. IdentifierInfo *KeyIdents[] = {
  174. &Ctx.Idents.get("dictionaryWithObjects"),
  175. &Ctx.Idents.get("forKeys"),
  176. &Ctx.Idents.get("count")
  177. };
  178. Sel = Ctx.Selectors.getSelector(3, KeyIdents);
  179. break;
  180. }
  181. case NSDict_dictionaryWithObjectsAndKeys:
  182. Sel = Ctx.Selectors.getUnarySelector(
  183. &Ctx.Idents.get("dictionaryWithObjectsAndKeys"));
  184. break;
  185. case NSDict_initWithDictionary:
  186. Sel = Ctx.Selectors.getUnarySelector(
  187. &Ctx.Idents.get("initWithDictionary"));
  188. break;
  189. case NSDict_initWithObjectsAndKeys:
  190. Sel = Ctx.Selectors.getUnarySelector(
  191. &Ctx.Idents.get("initWithObjectsAndKeys"));
  192. break;
  193. case NSDict_initWithObjectsForKeys: {
  194. IdentifierInfo *KeyIdents[] = {
  195. &Ctx.Idents.get("initWithObjects"),
  196. &Ctx.Idents.get("forKeys")
  197. };
  198. Sel = Ctx.Selectors.getSelector(2, KeyIdents);
  199. break;
  200. }
  201. case NSDict_objectForKey:
  202. Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey"));
  203. break;
  204. case NSMutableDict_setObjectForKey: {
  205. IdentifierInfo *KeyIdents[] = {
  206. &Ctx.Idents.get("setObject"),
  207. &Ctx.Idents.get("forKey")
  208. };
  209. Sel = Ctx.Selectors.getSelector(2, KeyIdents);
  210. break;
  211. }
  212. case NSMutableDict_setObjectForKeyedSubscript: {
  213. IdentifierInfo *KeyIdents[] = {
  214. &Ctx.Idents.get("setObject"),
  215. &Ctx.Idents.get("forKeyedSubscript")
  216. };
  217. Sel = Ctx.Selectors.getSelector(2, KeyIdents);
  218. break;
  219. }
  220. case NSMutableDict_setValueForKey: {
  221. IdentifierInfo *KeyIdents[] = {
  222. &Ctx.Idents.get("setValue"),
  223. &Ctx.Idents.get("forKey")
  224. };
  225. Sel = Ctx.Selectors.getSelector(2, KeyIdents);
  226. break;
  227. }
  228. }
  229. return (NSDictionarySelectors[MK] = Sel);
  230. }
  231. return NSDictionarySelectors[MK];
  232. }
  233. std::optional<NSAPI::NSDictionaryMethodKind>
  234. NSAPI::getNSDictionaryMethodKind(Selector Sel) {
  235. for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) {
  236. NSDictionaryMethodKind MK = NSDictionaryMethodKind(i);
  237. if (Sel == getNSDictionarySelector(MK))
  238. return MK;
  239. }
  240. return std::nullopt;
  241. }
  242. Selector NSAPI::getNSSetSelector(NSSetMethodKind MK) const {
  243. if (NSSetSelectors[MK].isNull()) {
  244. Selector Sel;
  245. switch (MK) {
  246. case NSMutableSet_addObject:
  247. Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
  248. break;
  249. case NSOrderedSet_insertObjectAtIndex: {
  250. IdentifierInfo *KeyIdents[] = {
  251. &Ctx.Idents.get("insertObject"),
  252. &Ctx.Idents.get("atIndex")
  253. };
  254. Sel = Ctx.Selectors.getSelector(2, KeyIdents);
  255. break;
  256. }
  257. case NSOrderedSet_setObjectAtIndex: {
  258. IdentifierInfo *KeyIdents[] = {
  259. &Ctx.Idents.get("setObject"),
  260. &Ctx.Idents.get("atIndex")
  261. };
  262. Sel = Ctx.Selectors.getSelector(2, KeyIdents);
  263. break;
  264. }
  265. case NSOrderedSet_setObjectAtIndexedSubscript: {
  266. IdentifierInfo *KeyIdents[] = {
  267. &Ctx.Idents.get("setObject"),
  268. &Ctx.Idents.get("atIndexedSubscript")
  269. };
  270. Sel = Ctx.Selectors.getSelector(2, KeyIdents);
  271. break;
  272. }
  273. case NSOrderedSet_replaceObjectAtIndexWithObject: {
  274. IdentifierInfo *KeyIdents[] = {
  275. &Ctx.Idents.get("replaceObjectAtIndex"),
  276. &Ctx.Idents.get("withObject")
  277. };
  278. Sel = Ctx.Selectors.getSelector(2, KeyIdents);
  279. break;
  280. }
  281. }
  282. return (NSSetSelectors[MK] = Sel);
  283. }
  284. return NSSetSelectors[MK];
  285. }
  286. std::optional<NSAPI::NSSetMethodKind> NSAPI::getNSSetMethodKind(Selector Sel) {
  287. for (unsigned i = 0; i != NumNSSetMethods; ++i) {
  288. NSSetMethodKind MK = NSSetMethodKind(i);
  289. if (Sel == getNSSetSelector(MK))
  290. return MK;
  291. }
  292. return std::nullopt;
  293. }
  294. Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
  295. bool Instance) const {
  296. static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {
  297. "numberWithChar",
  298. "numberWithUnsignedChar",
  299. "numberWithShort",
  300. "numberWithUnsignedShort",
  301. "numberWithInt",
  302. "numberWithUnsignedInt",
  303. "numberWithLong",
  304. "numberWithUnsignedLong",
  305. "numberWithLongLong",
  306. "numberWithUnsignedLongLong",
  307. "numberWithFloat",
  308. "numberWithDouble",
  309. "numberWithBool",
  310. "numberWithInteger",
  311. "numberWithUnsignedInteger"
  312. };
  313. static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {
  314. "initWithChar",
  315. "initWithUnsignedChar",
  316. "initWithShort",
  317. "initWithUnsignedShort",
  318. "initWithInt",
  319. "initWithUnsignedInt",
  320. "initWithLong",
  321. "initWithUnsignedLong",
  322. "initWithLongLong",
  323. "initWithUnsignedLongLong",
  324. "initWithFloat",
  325. "initWithDouble",
  326. "initWithBool",
  327. "initWithInteger",
  328. "initWithUnsignedInteger"
  329. };
  330. Selector *Sels;
  331. const char **Names;
  332. if (Instance) {
  333. Sels = NSNumberInstanceSelectors;
  334. Names = InstanceSelectorName;
  335. } else {
  336. Sels = NSNumberClassSelectors;
  337. Names = ClassSelectorName;
  338. }
  339. if (Sels[MK].isNull())
  340. Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK]));
  341. return Sels[MK];
  342. }
  343. std::optional<NSAPI::NSNumberLiteralMethodKind>
  344. NSAPI::getNSNumberLiteralMethodKind(Selector Sel) const {
  345. for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) {
  346. NSNumberLiteralMethodKind MK = NSNumberLiteralMethodKind(i);
  347. if (isNSNumberLiteralSelector(MK, Sel))
  348. return MK;
  349. }
  350. return std::nullopt;
  351. }
  352. std::optional<NSAPI::NSNumberLiteralMethodKind>
  353. NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
  354. const BuiltinType *BT = T->getAs<BuiltinType>();
  355. if (!BT)
  356. return std::nullopt;
  357. const TypedefType *TDT = T->getAs<TypedefType>();
  358. if (TDT) {
  359. QualType TDTTy = QualType(TDT, 0);
  360. if (isObjCBOOLType(TDTTy))
  361. return NSAPI::NSNumberWithBool;
  362. if (isObjCNSIntegerType(TDTTy))
  363. return NSAPI::NSNumberWithInteger;
  364. if (isObjCNSUIntegerType(TDTTy))
  365. return NSAPI::NSNumberWithUnsignedInteger;
  366. }
  367. switch (BT->getKind()) {
  368. case BuiltinType::Char_S:
  369. case BuiltinType::SChar:
  370. return NSAPI::NSNumberWithChar;
  371. case BuiltinType::Char_U:
  372. case BuiltinType::UChar:
  373. return NSAPI::NSNumberWithUnsignedChar;
  374. case BuiltinType::Short:
  375. return NSAPI::NSNumberWithShort;
  376. case BuiltinType::UShort:
  377. return NSAPI::NSNumberWithUnsignedShort;
  378. case BuiltinType::Int:
  379. return NSAPI::NSNumberWithInt;
  380. case BuiltinType::UInt:
  381. return NSAPI::NSNumberWithUnsignedInt;
  382. case BuiltinType::Long:
  383. return NSAPI::NSNumberWithLong;
  384. case BuiltinType::ULong:
  385. return NSAPI::NSNumberWithUnsignedLong;
  386. case BuiltinType::LongLong:
  387. return NSAPI::NSNumberWithLongLong;
  388. case BuiltinType::ULongLong:
  389. return NSAPI::NSNumberWithUnsignedLongLong;
  390. case BuiltinType::Float:
  391. return NSAPI::NSNumberWithFloat;
  392. case BuiltinType::Double:
  393. return NSAPI::NSNumberWithDouble;
  394. case BuiltinType::Bool:
  395. return NSAPI::NSNumberWithBool;
  396. case BuiltinType::Void:
  397. case BuiltinType::WChar_U:
  398. case BuiltinType::WChar_S:
  399. case BuiltinType::Char8:
  400. case BuiltinType::Char16:
  401. case BuiltinType::Char32:
  402. case BuiltinType::Int128:
  403. case BuiltinType::LongDouble:
  404. case BuiltinType::ShortAccum:
  405. case BuiltinType::Accum:
  406. case BuiltinType::LongAccum:
  407. case BuiltinType::UShortAccum:
  408. case BuiltinType::UAccum:
  409. case BuiltinType::ULongAccum:
  410. case BuiltinType::ShortFract:
  411. case BuiltinType::Fract:
  412. case BuiltinType::LongFract:
  413. case BuiltinType::UShortFract:
  414. case BuiltinType::UFract:
  415. case BuiltinType::ULongFract:
  416. case BuiltinType::SatShortAccum:
  417. case BuiltinType::SatAccum:
  418. case BuiltinType::SatLongAccum:
  419. case BuiltinType::SatUShortAccum:
  420. case BuiltinType::SatUAccum:
  421. case BuiltinType::SatULongAccum:
  422. case BuiltinType::SatShortFract:
  423. case BuiltinType::SatFract:
  424. case BuiltinType::SatLongFract:
  425. case BuiltinType::SatUShortFract:
  426. case BuiltinType::SatUFract:
  427. case BuiltinType::SatULongFract:
  428. case BuiltinType::UInt128:
  429. case BuiltinType::Float16:
  430. case BuiltinType::Float128:
  431. case BuiltinType::Ibm128:
  432. case BuiltinType::NullPtr:
  433. case BuiltinType::ObjCClass:
  434. case BuiltinType::ObjCId:
  435. case BuiltinType::ObjCSel:
  436. #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
  437. case BuiltinType::Id:
  438. #include "clang/Basic/OpenCLImageTypes.def"
  439. #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
  440. case BuiltinType::Id:
  441. #include "clang/Basic/OpenCLExtensionTypes.def"
  442. case BuiltinType::OCLSampler:
  443. case BuiltinType::OCLEvent:
  444. case BuiltinType::OCLClkEvent:
  445. case BuiltinType::OCLQueue:
  446. case BuiltinType::OCLReserveID:
  447. #define SVE_TYPE(Name, Id, SingletonId) \
  448. case BuiltinType::Id:
  449. #include "clang/Basic/AArch64SVEACLETypes.def"
  450. #define PPC_VECTOR_TYPE(Name, Id, Size) \
  451. case BuiltinType::Id:
  452. #include "clang/Basic/PPCTypes.def"
  453. #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
  454. #include "clang/Basic/RISCVVTypes.def"
  455. case BuiltinType::BoundMember:
  456. case BuiltinType::Dependent:
  457. case BuiltinType::Overload:
  458. case BuiltinType::UnknownAny:
  459. case BuiltinType::ARCUnbridgedCast:
  460. case BuiltinType::Half:
  461. case BuiltinType::PseudoObject:
  462. case BuiltinType::BuiltinFn:
  463. case BuiltinType::IncompleteMatrixIdx:
  464. case BuiltinType::OMPArraySection:
  465. case BuiltinType::OMPArrayShaping:
  466. case BuiltinType::OMPIterator:
  467. case BuiltinType::BFloat16:
  468. break;
  469. }
  470. return std::nullopt;
  471. }
  472. /// Returns true if \param T is a typedef of "BOOL" in objective-c.
  473. bool NSAPI::isObjCBOOLType(QualType T) const {
  474. return isObjCTypedef(T, "BOOL", BOOLId);
  475. }
  476. /// Returns true if \param T is a typedef of "NSInteger" in objective-c.
  477. bool NSAPI::isObjCNSIntegerType(QualType T) const {
  478. return isObjCTypedef(T, "NSInteger", NSIntegerId);
  479. }
  480. /// Returns true if \param T is a typedef of "NSUInteger" in objective-c.
  481. bool NSAPI::isObjCNSUIntegerType(QualType T) const {
  482. return isObjCTypedef(T, "NSUInteger", NSUIntegerId);
  483. }
  484. StringRef NSAPI::GetNSIntegralKind(QualType T) const {
  485. if (!Ctx.getLangOpts().ObjC || T.isNull())
  486. return StringRef();
  487. while (const TypedefType *TDT = T->getAs<TypedefType>()) {
  488. StringRef NSIntegralResust =
  489. llvm::StringSwitch<StringRef>(
  490. TDT->getDecl()->getDeclName().getAsIdentifierInfo()->getName())
  491. .Case("int8_t", "int8_t")
  492. .Case("int16_t", "int16_t")
  493. .Case("int32_t", "int32_t")
  494. .Case("NSInteger", "NSInteger")
  495. .Case("int64_t", "int64_t")
  496. .Case("uint8_t", "uint8_t")
  497. .Case("uint16_t", "uint16_t")
  498. .Case("uint32_t", "uint32_t")
  499. .Case("NSUInteger", "NSUInteger")
  500. .Case("uint64_t", "uint64_t")
  501. .Default(StringRef());
  502. if (!NSIntegralResust.empty())
  503. return NSIntegralResust;
  504. T = TDT->desugar();
  505. }
  506. return StringRef();
  507. }
  508. bool NSAPI::isMacroDefined(StringRef Id) const {
  509. // FIXME: Check whether the relevant module macros are visible.
  510. return Ctx.Idents.get(Id).hasMacroDefinition();
  511. }
  512. bool NSAPI::isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl,
  513. NSClassIdKindKind NSClassKind) const {
  514. if (!InterfaceDecl) {
  515. return false;
  516. }
  517. IdentifierInfo *NSClassID = getNSClassId(NSClassKind);
  518. bool IsSubclass = false;
  519. do {
  520. IsSubclass = NSClassID == InterfaceDecl->getIdentifier();
  521. if (IsSubclass) {
  522. break;
  523. }
  524. } while ((InterfaceDecl = InterfaceDecl->getSuperClass()));
  525. return IsSubclass;
  526. }
  527. bool NSAPI::isObjCTypedef(QualType T,
  528. StringRef name, IdentifierInfo *&II) const {
  529. if (!Ctx.getLangOpts().ObjC)
  530. return false;
  531. if (T.isNull())
  532. return false;
  533. if (!II)
  534. II = &Ctx.Idents.get(name);
  535. while (const TypedefType *TDT = T->getAs<TypedefType>()) {
  536. if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
  537. return true;
  538. T = TDT->desugar();
  539. }
  540. return false;
  541. }
  542. bool NSAPI::isObjCEnumerator(const Expr *E,
  543. StringRef name, IdentifierInfo *&II) const {
  544. if (!Ctx.getLangOpts().ObjC)
  545. return false;
  546. if (!E)
  547. return false;
  548. if (!II)
  549. II = &Ctx.Idents.get(name);
  550. if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
  551. if (const EnumConstantDecl *
  552. EnumD = dyn_cast_or_null<EnumConstantDecl>(DRE->getDecl()))
  553. return EnumD->getIdentifier() == II;
  554. return false;
  555. }
  556. Selector NSAPI::getOrInitSelector(ArrayRef<StringRef> Ids,
  557. Selector &Sel) const {
  558. if (Sel.isNull()) {
  559. SmallVector<IdentifierInfo *, 4> Idents;
  560. for (ArrayRef<StringRef>::const_iterator
  561. I = Ids.begin(), E = Ids.end(); I != E; ++I)
  562. Idents.push_back(&Ctx.Idents.get(*I));
  563. Sel = Ctx.Selectors.getSelector(Idents.size(), Idents.data());
  564. }
  565. return Sel;
  566. }
  567. Selector NSAPI::getOrInitNullarySelector(StringRef Id, Selector &Sel) const {
  568. if (Sel.isNull()) {
  569. IdentifierInfo *Ident = &Ctx.Idents.get(Id);
  570. Sel = Ctx.Selectors.getSelector(0, &Ident);
  571. }
  572. return Sel;
  573. }