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