1//===--- NSAPI.h - NSFoundation APIs ----------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_CLANG_AST_NSAPI_H
10#define LLVM_CLANG_AST_NSAPI_H
11
12#include "clang/Basic/IdentifierTable.h"
13#include "llvm/ADT/ArrayRef.h"
14#include <optional>
15
16namespace clang {
17 class ASTContext;
18 class ObjCInterfaceDecl;
19 class QualType;
20 class Expr;
21
22// Provides info and caches identifiers/selectors for NSFoundation API.
23class NSAPI {
24public:
25 explicit NSAPI(ASTContext &Ctx);
26
27 ASTContext &getASTContext() const { return Ctx; }
28
29 enum NSClassIdKindKind {
30 ClassId_NSObject,
31 ClassId_NSString,
32 ClassId_NSArray,
33 ClassId_NSMutableArray,
34 ClassId_NSDictionary,
35 ClassId_NSMutableDictionary,
36 ClassId_NSNumber,
37 ClassId_NSMutableSet,
38 ClassId_NSMutableOrderedSet,
39 ClassId_NSValue
40 };
41 static const unsigned NumClassIds = 10;
42
43 enum NSStringMethodKind {
44 NSStr_stringWithString,
45 NSStr_stringWithUTF8String,
46 NSStr_stringWithCStringEncoding,
47 NSStr_stringWithCString,
48 NSStr_initWithString,
49 NSStr_initWithUTF8String
50 };
51 static const unsigned NumNSStringMethods = 6;
52
53 IdentifierInfo *getNSClassId(NSClassIdKindKind K) const;
54
55 /// The Objective-C NSString selectors.
56 Selector getNSStringSelector(NSStringMethodKind MK) const;
57
58 /// Returns true if the expression \param E is a reference of
59 /// "NSUTF8StringEncoding" enum constant.
60 bool isNSUTF8StringEncodingConstant(const Expr *E) const {
61 return isObjCEnumerator(E, name: "NSUTF8StringEncoding", II&: NSUTF8StringEncodingId);
62 }
63
64 /// Returns true if the expression \param E is a reference of
65 /// "NSASCIIStringEncoding" enum constant.
66 bool isNSASCIIStringEncodingConstant(const Expr *E) const {
67 return isObjCEnumerator(E, name: "NSASCIIStringEncoding",II&: NSASCIIStringEncodingId);
68 }
69
70 /// Enumerates the NSArray/NSMutableArray methods used to generate
71 /// literals and to apply some checks.
72 enum NSArrayMethodKind {
73 NSArr_array,
74 NSArr_arrayWithArray,
75 NSArr_arrayWithObject,
76 NSArr_arrayWithObjects,
77 NSArr_arrayWithObjectsCount,
78 NSArr_initWithArray,
79 NSArr_initWithObjects,
80 NSArr_objectAtIndex,
81 NSMutableArr_replaceObjectAtIndex,
82 NSMutableArr_addObject,
83 NSMutableArr_insertObjectAtIndex,
84 NSMutableArr_setObjectAtIndexedSubscript
85 };
86 static const unsigned NumNSArrayMethods = 12;
87
88 /// The Objective-C NSArray selectors.
89 Selector getNSArraySelector(NSArrayMethodKind MK) const;
90
91 /// Return NSArrayMethodKind if \p Sel is such a selector.
92 std::optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel);
93
94 /// Enumerates the NSDictionary/NSMutableDictionary methods used
95 /// to generate literals and to apply some checks.
96 enum NSDictionaryMethodKind {
97 NSDict_dictionary,
98 NSDict_dictionaryWithDictionary,
99 NSDict_dictionaryWithObjectForKey,
100 NSDict_dictionaryWithObjectsForKeys,
101 NSDict_dictionaryWithObjectsForKeysCount,
102 NSDict_dictionaryWithObjectsAndKeys,
103 NSDict_initWithDictionary,
104 NSDict_initWithObjectsAndKeys,
105 NSDict_initWithObjectsForKeys,
106 NSDict_objectForKey,
107 NSMutableDict_setObjectForKey,
108 NSMutableDict_setObjectForKeyedSubscript,
109 NSMutableDict_setValueForKey
110 };
111 static const unsigned NumNSDictionaryMethods = 13;
112
113 /// The Objective-C NSDictionary selectors.
114 Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const;
115
116 /// Return NSDictionaryMethodKind if \p Sel is such a selector.
117 std::optional<NSDictionaryMethodKind> getNSDictionaryMethodKind(Selector Sel);
118
119 /// Enumerates the NSMutableSet/NSOrderedSet methods used
120 /// to apply some checks.
121 enum NSSetMethodKind {
122 NSMutableSet_addObject,
123 NSOrderedSet_insertObjectAtIndex,
124 NSOrderedSet_setObjectAtIndex,
125 NSOrderedSet_setObjectAtIndexedSubscript,
126 NSOrderedSet_replaceObjectAtIndexWithObject
127 };
128 static const unsigned NumNSSetMethods = 5;
129
130 /// The Objective-C NSSet selectors.
131 Selector getNSSetSelector(NSSetMethodKind MK) const;
132
133 /// Return NSSetMethodKind if \p Sel is such a selector.
134 std::optional<NSSetMethodKind> getNSSetMethodKind(Selector Sel);
135
136 /// Returns selector for "objectForKeyedSubscript:".
137 Selector getObjectForKeyedSubscriptSelector() const {
138 return getOrInitSelector(StringRef("objectForKeyedSubscript"),
139 objectForKeyedSubscriptSel);
140 }
141
142 /// Returns selector for "objectAtIndexedSubscript:".
143 Selector getObjectAtIndexedSubscriptSelector() const {
144 return getOrInitSelector(StringRef("objectAtIndexedSubscript"),
145 objectAtIndexedSubscriptSel);
146 }
147
148 /// Returns selector for "setObject:forKeyedSubscript".
149 Selector getSetObjectForKeyedSubscriptSelector() const {
150 StringRef Ids[] = { "setObject", "forKeyedSubscript" };
151 return getOrInitSelector(Ids, setObjectForKeyedSubscriptSel);
152 }
153
154 /// Returns selector for "setObject:atIndexedSubscript".
155 Selector getSetObjectAtIndexedSubscriptSelector() const {
156 StringRef Ids[] = { "setObject", "atIndexedSubscript" };
157 return getOrInitSelector(Ids, setObjectAtIndexedSubscriptSel);
158 }
159
160 /// Returns selector for "isEqual:".
161 Selector getIsEqualSelector() const {
162 return getOrInitSelector(StringRef("isEqual"), isEqualSel);
163 }
164
165 Selector getNewSelector() const {
166 return getOrInitNullarySelector("new", NewSel);
167 }
168
169 Selector getInitSelector() const {
170 return getOrInitNullarySelector("init", InitSel);
171 }
172
173 /// Enumerates the NSNumber methods used to generate literals.
174 enum NSNumberLiteralMethodKind {
175 NSNumberWithChar,
176 NSNumberWithUnsignedChar,
177 NSNumberWithShort,
178 NSNumberWithUnsignedShort,
179 NSNumberWithInt,
180 NSNumberWithUnsignedInt,
181 NSNumberWithLong,
182 NSNumberWithUnsignedLong,
183 NSNumberWithLongLong,
184 NSNumberWithUnsignedLongLong,
185 NSNumberWithFloat,
186 NSNumberWithDouble,
187 NSNumberWithBool,
188 NSNumberWithInteger,
189 NSNumberWithUnsignedInteger
190 };
191 static const unsigned NumNSNumberLiteralMethods = 15;
192
193 /// The Objective-C NSNumber selectors used to create NSNumber literals.
194 /// \param Instance if true it will return the selector for the init* method
195 /// otherwise it will return the selector for the number* method.
196 Selector getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
197 bool Instance) const;
198
199 bool isNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
200 Selector Sel) const {
201 return Sel == getNSNumberLiteralSelector(MK, Instance: false) ||
202 Sel == getNSNumberLiteralSelector(MK, Instance: true);
203 }
204
205 /// Return NSNumberLiteralMethodKind if \p Sel is such a selector.
206 std::optional<NSNumberLiteralMethodKind>
207 getNSNumberLiteralMethodKind(Selector Sel) const;
208
209 /// Determine the appropriate NSNumber factory method kind for a
210 /// literal of the given type.
211 std::optional<NSNumberLiteralMethodKind>
212 getNSNumberFactoryMethodKind(QualType T) const;
213
214 /// Returns true if \param T is a typedef of "BOOL" in objective-c.
215 bool isObjCBOOLType(QualType T) const;
216 /// Returns true if \param T is a typedef of "NSInteger" in objective-c.
217 bool isObjCNSIntegerType(QualType T) const;
218 /// Returns true if \param T is a typedef of "NSUInteger" in objective-c.
219 bool isObjCNSUIntegerType(QualType T) const;
220 /// Returns one of NSIntegral typedef names if \param T is a typedef
221 /// of that name in objective-c.
222 StringRef GetNSIntegralKind(QualType T) const;
223
224 /// Returns \c true if \p Id is currently defined as a macro.
225 bool isMacroDefined(StringRef Id) const;
226
227 /// Returns \c true if \p InterfaceDecl is subclass of \p NSClassKind
228 bool isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl,
229 NSClassIdKindKind NSClassKind) const;
230
231private:
232 bool isObjCTypedef(QualType T, StringRef name, IdentifierInfo *&II) const;
233 bool isObjCEnumerator(const Expr *E,
234 StringRef name, IdentifierInfo *&II) const;
235 Selector getOrInitSelector(ArrayRef<StringRef> Ids, Selector &Sel) const;
236 Selector getOrInitNullarySelector(StringRef Id, Selector &Sel) const;
237
238 ASTContext &Ctx;
239
240 mutable IdentifierInfo *ClassIds[NumClassIds];
241
242 mutable Selector NSStringSelectors[NumNSStringMethods];
243
244 /// The selectors for Objective-C NSArray methods.
245 mutable Selector NSArraySelectors[NumNSArrayMethods];
246
247 /// The selectors for Objective-C NSDictionary methods.
248 mutable Selector NSDictionarySelectors[NumNSDictionaryMethods];
249
250 /// The selectors for Objective-C NSSet methods.
251 mutable Selector NSSetSelectors[NumNSSetMethods];
252
253 /// The Objective-C NSNumber selectors used to create NSNumber literals.
254 mutable Selector NSNumberClassSelectors[NumNSNumberLiteralMethods];
255 mutable Selector NSNumberInstanceSelectors[NumNSNumberLiteralMethods];
256
257 mutable Selector objectForKeyedSubscriptSel, objectAtIndexedSubscriptSel,
258 setObjectForKeyedSubscriptSel,setObjectAtIndexedSubscriptSel,
259 isEqualSel, InitSel, NewSel;
260
261 mutable IdentifierInfo *BOOLId, *NSIntegerId, *NSUIntegerId;
262 mutable IdentifierInfo *NSASCIIStringEncodingId, *NSUTF8StringEncodingId;
263};
264
265} // end namespace clang
266
267#endif // LLVM_CLANG_AST_NSAPI_H
268

source code of clang/include/clang/AST/NSAPI.h