NSAPI.cpp 18 KB

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