xref: /llvm-project-15.0.7/clang/lib/AST/NSAPI.cpp (revision fae0dfa6)
1e65b086eSTed Kremenek //===--- NSAPI.cpp - NSFoundation APIs ------------------------------------===//
2e65b086eSTed Kremenek //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e65b086eSTed Kremenek //
7e65b086eSTed Kremenek //===----------------------------------------------------------------------===//
8e65b086eSTed Kremenek 
9e65b086eSTed Kremenek #include "clang/AST/NSAPI.h"
10e65b086eSTed Kremenek #include "clang/AST/ASTContext.h"
115dfac81cSAlex Denisov #include "clang/AST/DeclObjC.h"
127bd957c1SArgyrios Kyrtzidis #include "clang/AST/Expr.h"
1335ee87deSFariborz Jahanian #include "llvm/ADT/StringSwitch.h"
14e65b086eSTed Kremenek 
15e65b086eSTed Kremenek using namespace clang;
16e65b086eSTed Kremenek 
NSAPI(ASTContext & ctx)17e65b086eSTed Kremenek NSAPI::NSAPI(ASTContext &ctx)
1836250ad6SCraig Topper   : Ctx(ctx), ClassIds(), BOOLId(nullptr), NSIntegerId(nullptr),
1936250ad6SCraig Topper     NSUIntegerId(nullptr), NSASCIIStringEncodingId(nullptr),
2036250ad6SCraig Topper     NSUTF8StringEncodingId(nullptr) {}
21e65b086eSTed Kremenek 
getNSClassId(NSClassIdKindKind K) const22e65b086eSTed Kremenek IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
23e65b086eSTed Kremenek   static const char *ClassName[NumClassIds] = {
24acfbe9e1SPatrick Beard     "NSObject",
25e65b086eSTed Kremenek     "NSString",
26e65b086eSTed Kremenek     "NSArray",
27e65b086eSTed Kremenek     "NSMutableArray",
28e65b086eSTed Kremenek     "NSDictionary",
29e65b086eSTed Kremenek     "NSMutableDictionary",
30e1d882c7SAlex Denisov     "NSNumber",
31e1d882c7SAlex Denisov     "NSMutableSet",
32fde64956SAlex Denisov     "NSMutableOrderedSet",
33fde64956SAlex Denisov     "NSValue"
34e65b086eSTed Kremenek   };
35e65b086eSTed Kremenek 
36e65b086eSTed Kremenek   if (!ClassIds[K])
37e65b086eSTed Kremenek     return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));
38e65b086eSTed Kremenek 
39e65b086eSTed Kremenek   return ClassIds[K];
40e65b086eSTed Kremenek }
41e65b086eSTed Kremenek 
getNSStringSelector(NSStringMethodKind MK) const42e65b086eSTed Kremenek Selector NSAPI::getNSStringSelector(NSStringMethodKind MK) const {
43e65b086eSTed Kremenek   if (NSStringSelectors[MK].isNull()) {
44e65b086eSTed Kremenek     Selector Sel;
45e65b086eSTed Kremenek     switch (MK) {
46e65b086eSTed Kremenek     case NSStr_stringWithString:
47e65b086eSTed Kremenek       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithString"));
48e65b086eSTed Kremenek       break;
497bd957c1SArgyrios Kyrtzidis     case NSStr_stringWithUTF8String:
507bd957c1SArgyrios Kyrtzidis       Sel = Ctx.Selectors.getUnarySelector(
517bd957c1SArgyrios Kyrtzidis                                        &Ctx.Idents.get("stringWithUTF8String"));
527bd957c1SArgyrios Kyrtzidis       break;
53be7bf728SFariborz Jahanian     case NSStr_initWithUTF8String:
54be7bf728SFariborz Jahanian       Sel = Ctx.Selectors.getUnarySelector(
55be7bf728SFariborz Jahanian                                        &Ctx.Idents.get("initWithUTF8String"));
56be7bf728SFariborz Jahanian       break;
577bd957c1SArgyrios Kyrtzidis     case NSStr_stringWithCStringEncoding: {
587bd957c1SArgyrios Kyrtzidis       IdentifierInfo *KeyIdents[] = {
597bd957c1SArgyrios Kyrtzidis         &Ctx.Idents.get("stringWithCString"),
607bd957c1SArgyrios Kyrtzidis         &Ctx.Idents.get("encoding")
617bd957c1SArgyrios Kyrtzidis       };
627bd957c1SArgyrios Kyrtzidis       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
637bd957c1SArgyrios Kyrtzidis       break;
647bd957c1SArgyrios Kyrtzidis     }
657bd957c1SArgyrios Kyrtzidis     case NSStr_stringWithCString:
667bd957c1SArgyrios Kyrtzidis       Sel= Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithCString"));
677bd957c1SArgyrios Kyrtzidis       break;
68e65b086eSTed Kremenek     case NSStr_initWithString:
69e65b086eSTed Kremenek       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString"));
70e65b086eSTed Kremenek       break;
71e65b086eSTed Kremenek     }
72e65b086eSTed Kremenek     return (NSStringSelectors[MK] = Sel);
73e65b086eSTed Kremenek   }
74e65b086eSTed Kremenek 
75e65b086eSTed Kremenek   return NSStringSelectors[MK];
76e65b086eSTed Kremenek }
77e65b086eSTed Kremenek 
getNSArraySelector(NSArrayMethodKind MK) const78e65b086eSTed Kremenek Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const {
79e65b086eSTed Kremenek   if (NSArraySelectors[MK].isNull()) {
80e65b086eSTed Kremenek     Selector Sel;
81e65b086eSTed Kremenek     switch (MK) {
82e65b086eSTed Kremenek     case NSArr_array:
83e65b086eSTed Kremenek       Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array"));
84e65b086eSTed Kremenek       break;
85e65b086eSTed Kremenek     case NSArr_arrayWithArray:
86e65b086eSTed Kremenek       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray"));
87e65b086eSTed Kremenek       break;
88e65b086eSTed Kremenek     case NSArr_arrayWithObject:
89e65b086eSTed Kremenek       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject"));
90e65b086eSTed Kremenek       break;
91e65b086eSTed Kremenek     case NSArr_arrayWithObjects:
92e65b086eSTed Kremenek       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects"));
93e65b086eSTed Kremenek       break;
94e65b086eSTed Kremenek     case NSArr_arrayWithObjectsCount: {
95e65b086eSTed Kremenek       IdentifierInfo *KeyIdents[] = {
96e65b086eSTed Kremenek         &Ctx.Idents.get("arrayWithObjects"),
97e65b086eSTed Kremenek         &Ctx.Idents.get("count")
98e65b086eSTed Kremenek       };
99e65b086eSTed Kremenek       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
100e65b086eSTed Kremenek       break;
101e65b086eSTed Kremenek     }
102e65b086eSTed Kremenek     case NSArr_initWithArray:
103e65b086eSTed Kremenek       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray"));
104e65b086eSTed Kremenek       break;
105e65b086eSTed Kremenek     case NSArr_initWithObjects:
106e65b086eSTed Kremenek       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects"));
107e65b086eSTed Kremenek       break;
108e65b086eSTed Kremenek     case NSArr_objectAtIndex:
109e65b086eSTed Kremenek       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex"));
110e65b086eSTed Kremenek       break;
111e65b086eSTed Kremenek     case NSMutableArr_replaceObjectAtIndex: {
112e65b086eSTed Kremenek       IdentifierInfo *KeyIdents[] = {
113e65b086eSTed Kremenek         &Ctx.Idents.get("replaceObjectAtIndex"),
114e65b086eSTed Kremenek         &Ctx.Idents.get("withObject")
115e65b086eSTed Kremenek       };
116e65b086eSTed Kremenek       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
117e65b086eSTed Kremenek       break;
118e65b086eSTed Kremenek     }
119e1d882c7SAlex Denisov     case NSMutableArr_addObject:
120e1d882c7SAlex Denisov       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
121e1d882c7SAlex Denisov       break;
122e1d882c7SAlex Denisov     case NSMutableArr_insertObjectAtIndex: {
123e1d882c7SAlex Denisov       IdentifierInfo *KeyIdents[] = {
124e1d882c7SAlex Denisov         &Ctx.Idents.get("insertObject"),
125e1d882c7SAlex Denisov         &Ctx.Idents.get("atIndex")
126e1d882c7SAlex Denisov       };
127e1d882c7SAlex Denisov       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
128e1d882c7SAlex Denisov       break;
129e1d882c7SAlex Denisov     }
130e1d882c7SAlex Denisov     case NSMutableArr_setObjectAtIndexedSubscript: {
131e1d882c7SAlex Denisov       IdentifierInfo *KeyIdents[] = {
132e1d882c7SAlex Denisov         &Ctx.Idents.get("setObject"),
133e1d882c7SAlex Denisov         &Ctx.Idents.get("atIndexedSubscript")
134e1d882c7SAlex Denisov       };
135e1d882c7SAlex Denisov       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
136e1d882c7SAlex Denisov       break;
137e1d882c7SAlex Denisov     }
138e65b086eSTed Kremenek     }
139e65b086eSTed Kremenek     return (NSArraySelectors[MK] = Sel);
140e65b086eSTed Kremenek   }
141e65b086eSTed Kremenek 
142e65b086eSTed Kremenek   return NSArraySelectors[MK];
143e65b086eSTed Kremenek }
144e65b086eSTed Kremenek 
getNSArrayMethodKind(Selector Sel)14505785d16SDavid Blaikie Optional<NSAPI::NSArrayMethodKind> NSAPI::getNSArrayMethodKind(Selector Sel) {
146e65b086eSTed Kremenek   for (unsigned i = 0; i != NumNSArrayMethods; ++i) {
147e65b086eSTed Kremenek     NSArrayMethodKind MK = NSArrayMethodKind(i);
148e65b086eSTed Kremenek     if (Sel == getNSArraySelector(MK))
149e65b086eSTed Kremenek       return MK;
150e65b086eSTed Kremenek   }
151e65b086eSTed Kremenek 
1527a30dc53SDavid Blaikie   return None;
153e65b086eSTed Kremenek }
154e65b086eSTed Kremenek 
getNSDictionarySelector(NSDictionaryMethodKind MK) const155e65b086eSTed Kremenek Selector NSAPI::getNSDictionarySelector(
156e65b086eSTed Kremenek                                        NSDictionaryMethodKind MK) const {
157e65b086eSTed Kremenek   if (NSDictionarySelectors[MK].isNull()) {
158e65b086eSTed Kremenek     Selector Sel;
159e65b086eSTed Kremenek     switch (MK) {
160e65b086eSTed Kremenek     case NSDict_dictionary:
161e65b086eSTed Kremenek       Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary"));
162e65b086eSTed Kremenek       break;
163e65b086eSTed Kremenek     case NSDict_dictionaryWithDictionary:
164e65b086eSTed Kremenek       Sel = Ctx.Selectors.getUnarySelector(
165e65b086eSTed Kremenek                                    &Ctx.Idents.get("dictionaryWithDictionary"));
166e65b086eSTed Kremenek       break;
167e65b086eSTed Kremenek     case NSDict_dictionaryWithObjectForKey: {
168e65b086eSTed Kremenek       IdentifierInfo *KeyIdents[] = {
169e65b086eSTed Kremenek         &Ctx.Idents.get("dictionaryWithObject"),
170e65b086eSTed Kremenek         &Ctx.Idents.get("forKey")
171e65b086eSTed Kremenek       };
172e65b086eSTed Kremenek       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
173e65b086eSTed Kremenek       break;
174e65b086eSTed Kremenek     }
175e65b086eSTed Kremenek     case NSDict_dictionaryWithObjectsForKeys: {
176e65b086eSTed Kremenek       IdentifierInfo *KeyIdents[] = {
177e65b086eSTed Kremenek         &Ctx.Idents.get("dictionaryWithObjects"),
178e65b086eSTed Kremenek         &Ctx.Idents.get("forKeys")
179e65b086eSTed Kremenek       };
180e65b086eSTed Kremenek       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
181e65b086eSTed Kremenek       break;
182e65b086eSTed Kremenek     }
183e65b086eSTed Kremenek     case NSDict_dictionaryWithObjectsForKeysCount: {
184e65b086eSTed Kremenek       IdentifierInfo *KeyIdents[] = {
185e65b086eSTed Kremenek         &Ctx.Idents.get("dictionaryWithObjects"),
186e65b086eSTed Kremenek         &Ctx.Idents.get("forKeys"),
187e65b086eSTed Kremenek         &Ctx.Idents.get("count")
188e65b086eSTed Kremenek       };
189e65b086eSTed Kremenek       Sel = Ctx.Selectors.getSelector(3, KeyIdents);
190e65b086eSTed Kremenek       break;
191e65b086eSTed Kremenek     }
192e65b086eSTed Kremenek     case NSDict_dictionaryWithObjectsAndKeys:
193e65b086eSTed Kremenek       Sel = Ctx.Selectors.getUnarySelector(
194e65b086eSTed Kremenek                                &Ctx.Idents.get("dictionaryWithObjectsAndKeys"));
195e65b086eSTed Kremenek       break;
196e65b086eSTed Kremenek     case NSDict_initWithDictionary:
197e65b086eSTed Kremenek       Sel = Ctx.Selectors.getUnarySelector(
198e65b086eSTed Kremenek                                          &Ctx.Idents.get("initWithDictionary"));
199e65b086eSTed Kremenek       break;
200e65b086eSTed Kremenek     case NSDict_initWithObjectsAndKeys:
201e65b086eSTed Kremenek       Sel = Ctx.Selectors.getUnarySelector(
202e65b086eSTed Kremenek                                      &Ctx.Idents.get("initWithObjectsAndKeys"));
203e65b086eSTed Kremenek       break;
2046b4f341eSArgyrios Kyrtzidis     case NSDict_initWithObjectsForKeys: {
2056b4f341eSArgyrios Kyrtzidis       IdentifierInfo *KeyIdents[] = {
2066b4f341eSArgyrios Kyrtzidis         &Ctx.Idents.get("initWithObjects"),
2076b4f341eSArgyrios Kyrtzidis         &Ctx.Idents.get("forKeys")
2086b4f341eSArgyrios Kyrtzidis       };
2096b4f341eSArgyrios Kyrtzidis       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
2106b4f341eSArgyrios Kyrtzidis       break;
2116b4f341eSArgyrios Kyrtzidis     }
212e65b086eSTed Kremenek     case NSDict_objectForKey:
213e65b086eSTed Kremenek       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey"));
214e65b086eSTed Kremenek       break;
215e65b086eSTed Kremenek     case NSMutableDict_setObjectForKey: {
216e65b086eSTed Kremenek       IdentifierInfo *KeyIdents[] = {
217e65b086eSTed Kremenek         &Ctx.Idents.get("setObject"),
218e65b086eSTed Kremenek         &Ctx.Idents.get("forKey")
219e65b086eSTed Kremenek       };
220e65b086eSTed Kremenek       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
221e65b086eSTed Kremenek       break;
222e65b086eSTed Kremenek     }
223e1d882c7SAlex Denisov     case NSMutableDict_setObjectForKeyedSubscript: {
224e1d882c7SAlex Denisov       IdentifierInfo *KeyIdents[] = {
225e1d882c7SAlex Denisov         &Ctx.Idents.get("setObject"),
226e1d882c7SAlex Denisov         &Ctx.Idents.get("forKeyedSubscript")
227e1d882c7SAlex Denisov       };
228e1d882c7SAlex Denisov       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
229e1d882c7SAlex Denisov       break;
230e1d882c7SAlex Denisov     }
231e1d882c7SAlex Denisov     case NSMutableDict_setValueForKey: {
232e1d882c7SAlex Denisov       IdentifierInfo *KeyIdents[] = {
233e1d882c7SAlex Denisov         &Ctx.Idents.get("setValue"),
234e1d882c7SAlex Denisov         &Ctx.Idents.get("forKey")
235e1d882c7SAlex Denisov       };
236e1d882c7SAlex Denisov       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
237e1d882c7SAlex Denisov       break;
238e1d882c7SAlex Denisov     }
239e65b086eSTed Kremenek     }
240e65b086eSTed Kremenek     return (NSDictionarySelectors[MK] = Sel);
241e65b086eSTed Kremenek   }
242e65b086eSTed Kremenek 
243e65b086eSTed Kremenek   return NSDictionarySelectors[MK];
244e65b086eSTed Kremenek }
245e65b086eSTed Kremenek 
24605785d16SDavid Blaikie Optional<NSAPI::NSDictionaryMethodKind>
getNSDictionaryMethodKind(Selector Sel)247e65b086eSTed Kremenek NSAPI::getNSDictionaryMethodKind(Selector Sel) {
248e65b086eSTed Kremenek   for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) {
249e65b086eSTed Kremenek     NSDictionaryMethodKind MK = NSDictionaryMethodKind(i);
250e65b086eSTed Kremenek     if (Sel == getNSDictionarySelector(MK))
251e65b086eSTed Kremenek       return MK;
252e65b086eSTed Kremenek   }
253e65b086eSTed Kremenek 
2547a30dc53SDavid Blaikie   return None;
255e65b086eSTed Kremenek }
256e65b086eSTed Kremenek 
getNSSetSelector(NSSetMethodKind MK) const257e1d882c7SAlex Denisov Selector NSAPI::getNSSetSelector(NSSetMethodKind MK) const {
258e1d882c7SAlex Denisov   if (NSSetSelectors[MK].isNull()) {
259e1d882c7SAlex Denisov     Selector Sel;
260e1d882c7SAlex Denisov     switch (MK) {
261e1d882c7SAlex Denisov     case NSMutableSet_addObject:
262e1d882c7SAlex Denisov       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
263e1d882c7SAlex Denisov       break;
264e1d882c7SAlex Denisov     case NSOrderedSet_insertObjectAtIndex: {
265e1d882c7SAlex Denisov       IdentifierInfo *KeyIdents[] = {
266e1d882c7SAlex Denisov         &Ctx.Idents.get("insertObject"),
267e1d882c7SAlex Denisov         &Ctx.Idents.get("atIndex")
268e1d882c7SAlex Denisov       };
269e1d882c7SAlex Denisov       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
270e1d882c7SAlex Denisov       break;
271e1d882c7SAlex Denisov     }
272e1d882c7SAlex Denisov     case NSOrderedSet_setObjectAtIndex: {
273e1d882c7SAlex Denisov       IdentifierInfo *KeyIdents[] = {
274e1d882c7SAlex Denisov         &Ctx.Idents.get("setObject"),
275e1d882c7SAlex Denisov         &Ctx.Idents.get("atIndex")
276e1d882c7SAlex Denisov       };
277e1d882c7SAlex Denisov       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
278e1d882c7SAlex Denisov       break;
279e1d882c7SAlex Denisov     }
280e1d882c7SAlex Denisov     case NSOrderedSet_setObjectAtIndexedSubscript: {
281e1d882c7SAlex Denisov       IdentifierInfo *KeyIdents[] = {
282e1d882c7SAlex Denisov         &Ctx.Idents.get("setObject"),
283e1d882c7SAlex Denisov         &Ctx.Idents.get("atIndexedSubscript")
284e1d882c7SAlex Denisov       };
285e1d882c7SAlex Denisov       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
286e1d882c7SAlex Denisov       break;
287e1d882c7SAlex Denisov     }
288e1d882c7SAlex Denisov     case NSOrderedSet_replaceObjectAtIndexWithObject: {
289e1d882c7SAlex Denisov       IdentifierInfo *KeyIdents[] = {
290e1d882c7SAlex Denisov         &Ctx.Idents.get("replaceObjectAtIndex"),
291e1d882c7SAlex Denisov         &Ctx.Idents.get("withObject")
292e1d882c7SAlex Denisov       };
293e1d882c7SAlex Denisov       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
294e1d882c7SAlex Denisov       break;
295e1d882c7SAlex Denisov     }
296e1d882c7SAlex Denisov     }
297e1d882c7SAlex Denisov     return (NSSetSelectors[MK] = Sel);
298e1d882c7SAlex Denisov   }
299e1d882c7SAlex Denisov 
300e1d882c7SAlex Denisov   return NSSetSelectors[MK];
301e1d882c7SAlex Denisov }
302e1d882c7SAlex Denisov 
303e1d882c7SAlex Denisov Optional<NSAPI::NSSetMethodKind>
getNSSetMethodKind(Selector Sel)304e1d882c7SAlex Denisov NSAPI::getNSSetMethodKind(Selector Sel) {
305e1d882c7SAlex Denisov   for (unsigned i = 0; i != NumNSSetMethods; ++i) {
306e1d882c7SAlex Denisov     NSSetMethodKind MK = NSSetMethodKind(i);
307e1d882c7SAlex Denisov     if (Sel == getNSSetSelector(MK))
308e1d882c7SAlex Denisov       return MK;
309e1d882c7SAlex Denisov   }
310e1d882c7SAlex Denisov 
311e1d882c7SAlex Denisov   return None;
312e1d882c7SAlex Denisov }
313e1d882c7SAlex Denisov 
getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,bool Instance) const314e65b086eSTed Kremenek Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
315e65b086eSTed Kremenek                                            bool Instance) const {
316e65b086eSTed Kremenek   static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {
317e65b086eSTed Kremenek     "numberWithChar",
318e65b086eSTed Kremenek     "numberWithUnsignedChar",
319e65b086eSTed Kremenek     "numberWithShort",
320e65b086eSTed Kremenek     "numberWithUnsignedShort",
321e65b086eSTed Kremenek     "numberWithInt",
322e65b086eSTed Kremenek     "numberWithUnsignedInt",
323e65b086eSTed Kremenek     "numberWithLong",
324e65b086eSTed Kremenek     "numberWithUnsignedLong",
325e65b086eSTed Kremenek     "numberWithLongLong",
326e65b086eSTed Kremenek     "numberWithUnsignedLongLong",
327e65b086eSTed Kremenek     "numberWithFloat",
328e65b086eSTed Kremenek     "numberWithDouble",
329e65b086eSTed Kremenek     "numberWithBool",
330e65b086eSTed Kremenek     "numberWithInteger",
331e65b086eSTed Kremenek     "numberWithUnsignedInteger"
332e65b086eSTed Kremenek   };
333e65b086eSTed Kremenek   static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {
334e65b086eSTed Kremenek     "initWithChar",
335e65b086eSTed Kremenek     "initWithUnsignedChar",
336e65b086eSTed Kremenek     "initWithShort",
337e65b086eSTed Kremenek     "initWithUnsignedShort",
338e65b086eSTed Kremenek     "initWithInt",
339e65b086eSTed Kremenek     "initWithUnsignedInt",
340e65b086eSTed Kremenek     "initWithLong",
341e65b086eSTed Kremenek     "initWithUnsignedLong",
342e65b086eSTed Kremenek     "initWithLongLong",
343e65b086eSTed Kremenek     "initWithUnsignedLongLong",
344e65b086eSTed Kremenek     "initWithFloat",
345e65b086eSTed Kremenek     "initWithDouble",
346e65b086eSTed Kremenek     "initWithBool",
347e65b086eSTed Kremenek     "initWithInteger",
348e65b086eSTed Kremenek     "initWithUnsignedInteger"
349e65b086eSTed Kremenek   };
350e65b086eSTed Kremenek 
351e65b086eSTed Kremenek   Selector *Sels;
352e65b086eSTed Kremenek   const char **Names;
353e65b086eSTed Kremenek   if (Instance) {
354e65b086eSTed Kremenek     Sels = NSNumberInstanceSelectors;
355e65b086eSTed Kremenek     Names = InstanceSelectorName;
356e65b086eSTed Kremenek   } else {
357e65b086eSTed Kremenek     Sels = NSNumberClassSelectors;
358e65b086eSTed Kremenek     Names = ClassSelectorName;
359e65b086eSTed Kremenek   }
360e65b086eSTed Kremenek 
361e65b086eSTed Kremenek   if (Sels[MK].isNull())
362e65b086eSTed Kremenek     Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK]));
363e65b086eSTed Kremenek   return Sels[MK];
364e65b086eSTed Kremenek }
365e65b086eSTed Kremenek 
36605785d16SDavid Blaikie Optional<NSAPI::NSNumberLiteralMethodKind>
getNSNumberLiteralMethodKind(Selector Sel) const367e65b086eSTed Kremenek NSAPI::getNSNumberLiteralMethodKind(Selector Sel) const {
368e65b086eSTed Kremenek   for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) {
369e65b086eSTed Kremenek     NSNumberLiteralMethodKind MK = NSNumberLiteralMethodKind(i);
370e65b086eSTed Kremenek     if (isNSNumberLiteralSelector(MK, Sel))
371e65b086eSTed Kremenek       return MK;
372e65b086eSTed Kremenek   }
373e65b086eSTed Kremenek 
3747a30dc53SDavid Blaikie   return None;
375e65b086eSTed Kremenek }
376e65b086eSTed Kremenek 
37705785d16SDavid Blaikie Optional<NSAPI::NSNumberLiteralMethodKind>
getNSNumberFactoryMethodKind(QualType T) const3786062da47SArgyrios Kyrtzidis NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
379e65b086eSTed Kremenek   const BuiltinType *BT = T->getAs<BuiltinType>();
380e65b086eSTed Kremenek   if (!BT)
3817a30dc53SDavid Blaikie     return None;
382e65b086eSTed Kremenek 
3836062da47SArgyrios Kyrtzidis   const TypedefType *TDT = T->getAs<TypedefType>();
3846062da47SArgyrios Kyrtzidis   if (TDT) {
3856062da47SArgyrios Kyrtzidis     QualType TDTTy = QualType(TDT, 0);
3866062da47SArgyrios Kyrtzidis     if (isObjCBOOLType(TDTTy))
3876062da47SArgyrios Kyrtzidis       return NSAPI::NSNumberWithBool;
3886062da47SArgyrios Kyrtzidis     if (isObjCNSIntegerType(TDTTy))
3896062da47SArgyrios Kyrtzidis       return NSAPI::NSNumberWithInteger;
3906062da47SArgyrios Kyrtzidis     if (isObjCNSUIntegerType(TDTTy))
3916062da47SArgyrios Kyrtzidis       return NSAPI::NSNumberWithUnsignedInteger;
3926062da47SArgyrios Kyrtzidis   }
3936062da47SArgyrios Kyrtzidis 
394e65b086eSTed Kremenek   switch (BT->getKind()) {
395e65b086eSTed Kremenek   case BuiltinType::Char_S:
396e65b086eSTed Kremenek   case BuiltinType::SChar:
397e65b086eSTed Kremenek     return NSAPI::NSNumberWithChar;
398e65b086eSTed Kremenek   case BuiltinType::Char_U:
399e65b086eSTed Kremenek   case BuiltinType::UChar:
400e65b086eSTed Kremenek     return NSAPI::NSNumberWithUnsignedChar;
401e65b086eSTed Kremenek   case BuiltinType::Short:
402e65b086eSTed Kremenek     return NSAPI::NSNumberWithShort;
403e65b086eSTed Kremenek   case BuiltinType::UShort:
404e65b086eSTed Kremenek     return NSAPI::NSNumberWithUnsignedShort;
405e65b086eSTed Kremenek   case BuiltinType::Int:
406e65b086eSTed Kremenek     return NSAPI::NSNumberWithInt;
407e65b086eSTed Kremenek   case BuiltinType::UInt:
408e65b086eSTed Kremenek     return NSAPI::NSNumberWithUnsignedInt;
409e65b086eSTed Kremenek   case BuiltinType::Long:
410e65b086eSTed Kremenek     return NSAPI::NSNumberWithLong;
411e65b086eSTed Kremenek   case BuiltinType::ULong:
412e65b086eSTed Kremenek     return NSAPI::NSNumberWithUnsignedLong;
413e65b086eSTed Kremenek   case BuiltinType::LongLong:
414e65b086eSTed Kremenek     return NSAPI::NSNumberWithLongLong;
415e65b086eSTed Kremenek   case BuiltinType::ULongLong:
416e65b086eSTed Kremenek     return NSAPI::NSNumberWithUnsignedLongLong;
417e65b086eSTed Kremenek   case BuiltinType::Float:
418e65b086eSTed Kremenek     return NSAPI::NSNumberWithFloat;
419e65b086eSTed Kremenek   case BuiltinType::Double:
420e65b086eSTed Kremenek     return NSAPI::NSNumberWithDouble;
421e65b086eSTed Kremenek   case BuiltinType::Bool:
422e65b086eSTed Kremenek     return NSAPI::NSNumberWithBool;
423e65b086eSTed Kremenek 
424e65b086eSTed Kremenek   case BuiltinType::Void:
425e65b086eSTed Kremenek   case BuiltinType::WChar_U:
426e65b086eSTed Kremenek   case BuiltinType::WChar_S:
4273a8244dfSRichard Smith   case BuiltinType::Char8:
428e65b086eSTed Kremenek   case BuiltinType::Char16:
429e65b086eSTed Kremenek   case BuiltinType::Char32:
430e65b086eSTed Kremenek   case BuiltinType::Int128:
431e65b086eSTed Kremenek   case BuiltinType::LongDouble:
432f921d854SLeonard Chan   case BuiltinType::ShortAccum:
433f921d854SLeonard Chan   case BuiltinType::Accum:
434f921d854SLeonard Chan   case BuiltinType::LongAccum:
435f921d854SLeonard Chan   case BuiltinType::UShortAccum:
436f921d854SLeonard Chan   case BuiltinType::UAccum:
437f921d854SLeonard Chan   case BuiltinType::ULongAccum:
438ab80f3c8SLeonard Chan   case BuiltinType::ShortFract:
439ab80f3c8SLeonard Chan   case BuiltinType::Fract:
440ab80f3c8SLeonard Chan   case BuiltinType::LongFract:
441ab80f3c8SLeonard Chan   case BuiltinType::UShortFract:
442ab80f3c8SLeonard Chan   case BuiltinType::UFract:
443ab80f3c8SLeonard Chan   case BuiltinType::ULongFract:
444ab80f3c8SLeonard Chan   case BuiltinType::SatShortAccum:
445ab80f3c8SLeonard Chan   case BuiltinType::SatAccum:
446ab80f3c8SLeonard Chan   case BuiltinType::SatLongAccum:
447ab80f3c8SLeonard Chan   case BuiltinType::SatUShortAccum:
448ab80f3c8SLeonard Chan   case BuiltinType::SatUAccum:
449ab80f3c8SLeonard Chan   case BuiltinType::SatULongAccum:
450ab80f3c8SLeonard Chan   case BuiltinType::SatShortFract:
451ab80f3c8SLeonard Chan   case BuiltinType::SatFract:
452ab80f3c8SLeonard Chan   case BuiltinType::SatLongFract:
453ab80f3c8SLeonard Chan   case BuiltinType::SatUShortFract:
454ab80f3c8SLeonard Chan   case BuiltinType::SatUFract:
455ab80f3c8SLeonard Chan   case BuiltinType::SatULongFract:
456e65b086eSTed Kremenek   case BuiltinType::UInt128:
457cc623ad0SSjoerd Meijer   case BuiltinType::Float16:
458bb1ea2d6SNemanja Ivanovic   case BuiltinType::Float128:
459*fae0dfa6SQiu Chaofan   case BuiltinType::Ibm128:
460e65b086eSTed Kremenek   case BuiltinType::NullPtr:
461e65b086eSTed Kremenek   case BuiltinType::ObjCClass:
462e65b086eSTed Kremenek   case BuiltinType::ObjCId:
463e65b086eSTed Kremenek   case BuiltinType::ObjCSel:
464954ba21fSAlexey Bader #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
465954ba21fSAlexey Bader   case BuiltinType::Id:
466b62f1440SAlexey Bader #include "clang/Basic/OpenCLImageTypes.def"
4673fee3518SAndrew Savonichev #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
4683fee3518SAndrew Savonichev   case BuiltinType::Id:
4693fee3518SAndrew Savonichev #include "clang/Basic/OpenCLExtensionTypes.def"
47061054198SGuy Benyei   case BuiltinType::OCLSampler:
4711b4fb3e0SGuy Benyei   case BuiltinType::OCLEvent:
4729c8453fbSAlexey Bader   case BuiltinType::OCLClkEvent:
4739c8453fbSAlexey Bader   case BuiltinType::OCLQueue:
4749c8453fbSAlexey Bader   case BuiltinType::OCLReserveID:
475eb485fbcSRichard Sandiford #define SVE_TYPE(Name, Id, SingletonId) \
476eb485fbcSRichard Sandiford   case BuiltinType::Id:
477eb485fbcSRichard Sandiford #include "clang/Basic/AArch64SVEACLETypes.def"
47857d83c3aSBaptiste Saleil #define PPC_VECTOR_TYPE(Name, Id, Size) \
47940dd4d52SBaptiste Saleil   case BuiltinType::Id:
48040dd4d52SBaptiste Saleil #include "clang/Basic/PPCTypes.def"
481766ee109SHsiangkai Wang #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
482766ee109SHsiangkai Wang #include "clang/Basic/RISCVVTypes.def"
483e65b086eSTed Kremenek   case BuiltinType::BoundMember:
484e65b086eSTed Kremenek   case BuiltinType::Dependent:
485e65b086eSTed Kremenek   case BuiltinType::Overload:
486e65b086eSTed Kremenek   case BuiltinType::UnknownAny:
487e65b086eSTed Kremenek   case BuiltinType::ARCUnbridgedCast:
488e65b086eSTed Kremenek   case BuiltinType::Half:
489e65b086eSTed Kremenek   case BuiltinType::PseudoObject:
49034866c77SEli Friedman   case BuiltinType::BuiltinFn:
4918f3f88d2SFlorian Hahn   case BuiltinType::IncompleteMatrixIdx:
4921a3320e4SAlexey Bataev   case BuiltinType::OMPArraySection:
4937ac9efb0SAlexey Bataev   case BuiltinType::OMPArrayShaping:
49413a1504fSAlexey Bataev   case BuiltinType::OMPIterator:
495ecd682bbSTies Stuij   case BuiltinType::BFloat16:
496e65b086eSTed Kremenek     break;
497e65b086eSTed Kremenek   }
498e65b086eSTed Kremenek 
4997a30dc53SDavid Blaikie   return None;
500e65b086eSTed Kremenek }
5016062da47SArgyrios Kyrtzidis 
5029fc8faf9SAdrian Prantl /// Returns true if \param T is a typedef of "BOOL" in objective-c.
isObjCBOOLType(QualType T) const5036062da47SArgyrios Kyrtzidis bool NSAPI::isObjCBOOLType(QualType T) const {
5046062da47SArgyrios Kyrtzidis   return isObjCTypedef(T, "BOOL", BOOLId);
5056062da47SArgyrios Kyrtzidis }
5069fc8faf9SAdrian Prantl /// Returns true if \param T is a typedef of "NSInteger" in objective-c.
isObjCNSIntegerType(QualType T) const5076062da47SArgyrios Kyrtzidis bool NSAPI::isObjCNSIntegerType(QualType T) const {
5086062da47SArgyrios Kyrtzidis   return isObjCTypedef(T, "NSInteger", NSIntegerId);
5096062da47SArgyrios Kyrtzidis }
5109fc8faf9SAdrian Prantl /// Returns true if \param T is a typedef of "NSUInteger" in objective-c.
isObjCNSUIntegerType(QualType T) const5116062da47SArgyrios Kyrtzidis bool NSAPI::isObjCNSUIntegerType(QualType T) const {
5126062da47SArgyrios Kyrtzidis   return isObjCTypedef(T, "NSUInteger", NSUIntegerId);
5136062da47SArgyrios Kyrtzidis }
5146062da47SArgyrios Kyrtzidis 
GetNSIntegralKind(QualType T) const51535ee87deSFariborz Jahanian StringRef NSAPI::GetNSIntegralKind(QualType T) const {
516fa98390bSErik Pilkington   if (!Ctx.getLangOpts().ObjC || T.isNull())
51735ee87deSFariborz Jahanian     return StringRef();
51835ee87deSFariborz Jahanian 
51935ee87deSFariborz Jahanian   while (const TypedefType *TDT = T->getAs<TypedefType>()) {
52035ee87deSFariborz Jahanian     StringRef NSIntegralResust =
52135ee87deSFariborz Jahanian       llvm::StringSwitch<StringRef>(
52235ee87deSFariborz Jahanian         TDT->getDecl()->getDeclName().getAsIdentifierInfo()->getName())
52335ee87deSFariborz Jahanian     .Case("int8_t", "int8_t")
52435ee87deSFariborz Jahanian     .Case("int16_t", "int16_t")
52535ee87deSFariborz Jahanian     .Case("int32_t", "int32_t")
52635ee87deSFariborz Jahanian     .Case("NSInteger", "NSInteger")
52735ee87deSFariborz Jahanian     .Case("int64_t", "int64_t")
52835ee87deSFariborz Jahanian     .Case("uint8_t", "uint8_t")
52935ee87deSFariborz Jahanian     .Case("uint16_t", "uint16_t")
53035ee87deSFariborz Jahanian     .Case("uint32_t", "uint32_t")
53135ee87deSFariborz Jahanian     .Case("NSUInteger", "NSUInteger")
53235ee87deSFariborz Jahanian     .Case("uint64_t", "uint64_t")
53335ee87deSFariborz Jahanian     .Default(StringRef());
53435ee87deSFariborz Jahanian     if (!NSIntegralResust.empty())
53535ee87deSFariborz Jahanian       return NSIntegralResust;
53635ee87deSFariborz Jahanian     T = TDT->desugar();
53735ee87deSFariborz Jahanian   }
53835ee87deSFariborz Jahanian   return StringRef();
53935ee87deSFariborz Jahanian }
54035ee87deSFariborz Jahanian 
isMacroDefined(StringRef Id) const54120e883e5SRichard Smith bool NSAPI::isMacroDefined(StringRef Id) const {
54220e883e5SRichard Smith   // FIXME: Check whether the relevant module macros are visible.
54320e883e5SRichard Smith   return Ctx.Idents.get(Id).hasMacroDefinition();
54420e883e5SRichard Smith }
54520e883e5SRichard Smith 
isSubclassOfNSClass(ObjCInterfaceDecl * InterfaceDecl,NSClassIdKindKind NSClassKind) const5465dfac81cSAlex Denisov bool NSAPI::isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl,
5475dfac81cSAlex Denisov                                 NSClassIdKindKind NSClassKind) const {
5485dfac81cSAlex Denisov   if (!InterfaceDecl) {
5495dfac81cSAlex Denisov     return false;
5505dfac81cSAlex Denisov   }
5515dfac81cSAlex Denisov 
5525dfac81cSAlex Denisov   IdentifierInfo *NSClassID = getNSClassId(NSClassKind);
5535dfac81cSAlex Denisov 
5545dfac81cSAlex Denisov   bool IsSubclass = false;
5555dfac81cSAlex Denisov   do {
5565dfac81cSAlex Denisov     IsSubclass = NSClassID == InterfaceDecl->getIdentifier();
5575dfac81cSAlex Denisov 
5585dfac81cSAlex Denisov     if (IsSubclass) {
5595dfac81cSAlex Denisov       break;
5605dfac81cSAlex Denisov     }
5615dfac81cSAlex Denisov   } while ((InterfaceDecl = InterfaceDecl->getSuperClass()));
5625dfac81cSAlex Denisov 
5635dfac81cSAlex Denisov   return IsSubclass;
5645dfac81cSAlex Denisov }
5655dfac81cSAlex Denisov 
isObjCTypedef(QualType T,StringRef name,IdentifierInfo * & II) const5666062da47SArgyrios Kyrtzidis bool NSAPI::isObjCTypedef(QualType T,
5676062da47SArgyrios Kyrtzidis                           StringRef name, IdentifierInfo *&II) const {
568fa98390bSErik Pilkington   if (!Ctx.getLangOpts().ObjC)
5696062da47SArgyrios Kyrtzidis     return false;
5706062da47SArgyrios Kyrtzidis   if (T.isNull())
5716062da47SArgyrios Kyrtzidis     return false;
5726062da47SArgyrios Kyrtzidis 
5736062da47SArgyrios Kyrtzidis   if (!II)
5746062da47SArgyrios Kyrtzidis     II = &Ctx.Idents.get(name);
5756062da47SArgyrios Kyrtzidis 
5766062da47SArgyrios Kyrtzidis   while (const TypedefType *TDT = T->getAs<TypedefType>()) {
5776062da47SArgyrios Kyrtzidis     if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
5786062da47SArgyrios Kyrtzidis       return true;
5796062da47SArgyrios Kyrtzidis     T = TDT->desugar();
5806062da47SArgyrios Kyrtzidis   }
5816062da47SArgyrios Kyrtzidis 
5826062da47SArgyrios Kyrtzidis   return false;
5836062da47SArgyrios Kyrtzidis }
5847bd957c1SArgyrios Kyrtzidis 
isObjCEnumerator(const Expr * E,StringRef name,IdentifierInfo * & II) const5857bd957c1SArgyrios Kyrtzidis bool NSAPI::isObjCEnumerator(const Expr *E,
5867bd957c1SArgyrios Kyrtzidis                              StringRef name, IdentifierInfo *&II) const {
587fa98390bSErik Pilkington   if (!Ctx.getLangOpts().ObjC)
5887bd957c1SArgyrios Kyrtzidis     return false;
5897bd957c1SArgyrios Kyrtzidis   if (!E)
5907bd957c1SArgyrios Kyrtzidis     return false;
5917bd957c1SArgyrios Kyrtzidis 
5927bd957c1SArgyrios Kyrtzidis   if (!II)
5937bd957c1SArgyrios Kyrtzidis     II = &Ctx.Idents.get(name);
5947bd957c1SArgyrios Kyrtzidis 
5957bd957c1SArgyrios Kyrtzidis   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
5967bd957c1SArgyrios Kyrtzidis     if (const EnumConstantDecl *
5977bd957c1SArgyrios Kyrtzidis           EnumD = dyn_cast_or_null<EnumConstantDecl>(DRE->getDecl()))
5987bd957c1SArgyrios Kyrtzidis       return EnumD->getIdentifier() == II;
5997bd957c1SArgyrios Kyrtzidis 
6007bd957c1SArgyrios Kyrtzidis   return false;
6017bd957c1SArgyrios Kyrtzidis }
6026310fdd9SArgyrios Kyrtzidis 
getOrInitSelector(ArrayRef<StringRef> Ids,Selector & Sel) const6036310fdd9SArgyrios Kyrtzidis Selector NSAPI::getOrInitSelector(ArrayRef<StringRef> Ids,
6046310fdd9SArgyrios Kyrtzidis                                   Selector &Sel) const {
6056310fdd9SArgyrios Kyrtzidis   if (Sel.isNull()) {
6066310fdd9SArgyrios Kyrtzidis     SmallVector<IdentifierInfo *, 4> Idents;
6076310fdd9SArgyrios Kyrtzidis     for (ArrayRef<StringRef>::const_iterator
6086310fdd9SArgyrios Kyrtzidis            I = Ids.begin(), E = Ids.end(); I != E; ++I)
6096310fdd9SArgyrios Kyrtzidis       Idents.push_back(&Ctx.Idents.get(*I));
6106310fdd9SArgyrios Kyrtzidis     Sel = Ctx.Selectors.getSelector(Idents.size(), Idents.data());
6116310fdd9SArgyrios Kyrtzidis   }
6126310fdd9SArgyrios Kyrtzidis   return Sel;
6136310fdd9SArgyrios Kyrtzidis }
6144257857bSErik Pilkington 
getOrInitNullarySelector(StringRef Id,Selector & Sel) const6154257857bSErik Pilkington Selector NSAPI::getOrInitNullarySelector(StringRef Id, Selector &Sel) const {
6164257857bSErik Pilkington   if (Sel.isNull()) {
6174257857bSErik Pilkington     IdentifierInfo *Ident = &Ctx.Idents.get(Id);
6184257857bSErik Pilkington     Sel = Ctx.Selectors.getSelector(0, &Ident);
6194257857bSErik Pilkington   }
6204257857bSErik Pilkington   return Sel;
6214257857bSErik Pilkington }
622