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