xref: /llvm-project-15.0.7/clang/lib/AST/NSAPI.cpp (revision 900893d2)
1 //===--- NSAPI.cpp - NSFoundation APIs ------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "clang/AST/NSAPI.h"
11 #include "clang/AST/ASTContext.h"
12 
13 using namespace clang;
14 
15 NSAPI::NSAPI(ASTContext &ctx)
16   : Ctx(ctx), ClassIds() {
17 }
18 
19 IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
20   static const char *ClassName[NumClassIds] = {
21     "NSString",
22     "NSArray",
23     "NSMutableArray",
24     "NSDictionary",
25     "NSMutableDictionary",
26     "NSNumber"
27   };
28 
29   if (!ClassIds[K])
30     return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));
31 
32   return ClassIds[K];
33 }
34 
35 Selector NSAPI::getNSStringSelector(NSStringMethodKind MK) const {
36   if (NSStringSelectors[MK].isNull()) {
37     Selector Sel;
38     switch (MK) {
39     case NSStr_stringWithString:
40       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithString"));
41       break;
42     case NSStr_initWithString:
43       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString"));
44       break;
45     }
46     return (NSStringSelectors[MK] = Sel);
47   }
48 
49   return NSStringSelectors[MK];
50 }
51 
52 Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const {
53   if (NSArraySelectors[MK].isNull()) {
54     Selector Sel;
55     switch (MK) {
56     case NSArr_array:
57       Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array"));
58       break;
59     case NSArr_arrayWithArray:
60       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray"));
61       break;
62     case NSArr_arrayWithObject:
63       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject"));
64       break;
65     case NSArr_arrayWithObjects:
66       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects"));
67       break;
68     case NSArr_arrayWithObjectsCount: {
69       IdentifierInfo *KeyIdents[] = {
70         &Ctx.Idents.get("arrayWithObjects"),
71         &Ctx.Idents.get("count")
72       };
73       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
74       break;
75     }
76     case NSArr_initWithArray:
77       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray"));
78       break;
79     case NSArr_initWithObjects:
80       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects"));
81       break;
82     case NSArr_objectAtIndex:
83       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex"));
84       break;
85     case NSMutableArr_replaceObjectAtIndex: {
86       IdentifierInfo *KeyIdents[] = {
87         &Ctx.Idents.get("replaceObjectAtIndex"),
88         &Ctx.Idents.get("withObject")
89       };
90       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
91       break;
92     }
93     }
94     return (NSArraySelectors[MK] = Sel);
95   }
96 
97   return NSArraySelectors[MK];
98 }
99 
100 llvm::Optional<NSAPI::NSArrayMethodKind>
101 NSAPI::getNSArrayMethodKind(Selector Sel) {
102   for (unsigned i = 0; i != NumNSArrayMethods; ++i) {
103     NSArrayMethodKind MK = NSArrayMethodKind(i);
104     if (Sel == getNSArraySelector(MK))
105       return MK;
106   }
107 
108   return llvm::Optional<NSArrayMethodKind>();
109 }
110 
111 Selector NSAPI::getNSDictionarySelector(
112                                        NSDictionaryMethodKind MK) const {
113   if (NSDictionarySelectors[MK].isNull()) {
114     Selector Sel;
115     switch (MK) {
116     case NSDict_dictionary:
117       Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary"));
118       break;
119     case NSDict_dictionaryWithDictionary:
120       Sel = Ctx.Selectors.getUnarySelector(
121                                    &Ctx.Idents.get("dictionaryWithDictionary"));
122       break;
123     case NSDict_dictionaryWithObjectForKey: {
124       IdentifierInfo *KeyIdents[] = {
125         &Ctx.Idents.get("dictionaryWithObject"),
126         &Ctx.Idents.get("forKey")
127       };
128       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
129       break;
130     }
131     case NSDict_dictionaryWithObjectsForKeys: {
132       IdentifierInfo *KeyIdents[] = {
133         &Ctx.Idents.get("dictionaryWithObjects"),
134         &Ctx.Idents.get("forKeys")
135       };
136       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
137       break;
138     }
139     case NSDict_dictionaryWithObjectsForKeysCount: {
140       IdentifierInfo *KeyIdents[] = {
141         &Ctx.Idents.get("dictionaryWithObjects"),
142         &Ctx.Idents.get("forKeys"),
143         &Ctx.Idents.get("count")
144       };
145       Sel = Ctx.Selectors.getSelector(3, KeyIdents);
146       break;
147     }
148     case NSDict_dictionaryWithObjectsAndKeys:
149       Sel = Ctx.Selectors.getUnarySelector(
150                                &Ctx.Idents.get("dictionaryWithObjectsAndKeys"));
151       break;
152     case NSDict_initWithDictionary:
153       Sel = Ctx.Selectors.getUnarySelector(
154                                          &Ctx.Idents.get("initWithDictionary"));
155       break;
156     case NSDict_initWithObjectsAndKeys:
157       Sel = Ctx.Selectors.getUnarySelector(
158                                      &Ctx.Idents.get("initWithObjectsAndKeys"));
159       break;
160     case NSDict_objectForKey:
161       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey"));
162       break;
163     case NSMutableDict_setObjectForKey: {
164       IdentifierInfo *KeyIdents[] = {
165         &Ctx.Idents.get("setObject"),
166         &Ctx.Idents.get("forKey")
167       };
168       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
169       break;
170     }
171     }
172     return (NSDictionarySelectors[MK] = Sel);
173   }
174 
175   return NSDictionarySelectors[MK];
176 }
177 
178 llvm::Optional<NSAPI::NSDictionaryMethodKind>
179 NSAPI::getNSDictionaryMethodKind(Selector Sel) {
180   for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) {
181     NSDictionaryMethodKind MK = NSDictionaryMethodKind(i);
182     if (Sel == getNSDictionarySelector(MK))
183       return MK;
184   }
185 
186   return llvm::Optional<NSDictionaryMethodKind>();
187 }
188 
189 Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
190                                            bool Instance) const {
191   static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {
192     "numberWithChar",
193     "numberWithUnsignedChar",
194     "numberWithShort",
195     "numberWithUnsignedShort",
196     "numberWithInt",
197     "numberWithUnsignedInt",
198     "numberWithLong",
199     "numberWithUnsignedLong",
200     "numberWithLongLong",
201     "numberWithUnsignedLongLong",
202     "numberWithFloat",
203     "numberWithDouble",
204     "numberWithBool",
205     "numberWithInteger",
206     "numberWithUnsignedInteger"
207   };
208   static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {
209     "initWithChar",
210     "initWithUnsignedChar",
211     "initWithShort",
212     "initWithUnsignedShort",
213     "initWithInt",
214     "initWithUnsignedInt",
215     "initWithLong",
216     "initWithUnsignedLong",
217     "initWithLongLong",
218     "initWithUnsignedLongLong",
219     "initWithFloat",
220     "initWithDouble",
221     "initWithBool",
222     "initWithInteger",
223     "initWithUnsignedInteger"
224   };
225 
226   Selector *Sels;
227   const char **Names;
228   if (Instance) {
229     Sels = NSNumberInstanceSelectors;
230     Names = InstanceSelectorName;
231   } else {
232     Sels = NSNumberClassSelectors;
233     Names = ClassSelectorName;
234   }
235 
236   if (Sels[MK].isNull())
237     Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK]));
238   return Sels[MK];
239 }
240 
241 llvm::Optional<NSAPI::NSNumberLiteralMethodKind>
242 NSAPI::getNSNumberLiteralMethodKind(Selector Sel) const {
243   for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) {
244     NSNumberLiteralMethodKind MK = NSNumberLiteralMethodKind(i);
245     if (isNSNumberLiteralSelector(MK, Sel))
246       return MK;
247   }
248 
249   return llvm::Optional<NSNumberLiteralMethodKind>();
250 }
251 
252 llvm::Optional<NSAPI::NSNumberLiteralMethodKind>
253 NSAPI::getNSNumberFactoryMethodKind(QualType T) {
254   const BuiltinType *BT = T->getAs<BuiltinType>();
255   if (!BT)
256     return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>();
257 
258   switch (BT->getKind()) {
259   case BuiltinType::Char_S:
260   case BuiltinType::SChar:
261     return NSAPI::NSNumberWithChar;
262   case BuiltinType::Char_U:
263   case BuiltinType::UChar:
264     return NSAPI::NSNumberWithUnsignedChar;
265   case BuiltinType::Short:
266     return NSAPI::NSNumberWithShort;
267   case BuiltinType::UShort:
268     return NSAPI::NSNumberWithUnsignedShort;
269   case BuiltinType::Int:
270     return NSAPI::NSNumberWithInt;
271   case BuiltinType::UInt:
272     return NSAPI::NSNumberWithUnsignedInt;
273   case BuiltinType::Long:
274     return NSAPI::NSNumberWithLong;
275   case BuiltinType::ULong:
276     return NSAPI::NSNumberWithUnsignedLong;
277   case BuiltinType::LongLong:
278     return NSAPI::NSNumberWithLongLong;
279   case BuiltinType::ULongLong:
280     return NSAPI::NSNumberWithUnsignedLongLong;
281   case BuiltinType::Float:
282     return NSAPI::NSNumberWithFloat;
283   case BuiltinType::Double:
284     return NSAPI::NSNumberWithDouble;
285   case BuiltinType::Bool:
286     return NSAPI::NSNumberWithBool;
287 
288   case BuiltinType::Void:
289   case BuiltinType::WChar_U:
290   case BuiltinType::WChar_S:
291   case BuiltinType::Char16:
292   case BuiltinType::Char32:
293   case BuiltinType::Int128:
294   case BuiltinType::LongDouble:
295   case BuiltinType::UInt128:
296   case BuiltinType::NullPtr:
297   case BuiltinType::ObjCClass:
298   case BuiltinType::ObjCId:
299   case BuiltinType::ObjCSel:
300   case BuiltinType::BoundMember:
301   case BuiltinType::Dependent:
302   case BuiltinType::Overload:
303   case BuiltinType::UnknownAny:
304   case BuiltinType::ARCUnbridgedCast:
305   case BuiltinType::Half:
306   case BuiltinType::PseudoObject:
307     break;
308   }
309 
310   return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>();
311 }
312