xref: /freebsd/contrib/llvm-project/clang/include/clang/AST/NSAPI.h (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
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  
16  namespace clang {
17    class ASTContext;
18    class ObjCInterfaceDecl;
19    class QualType;
20    class Expr;
21  
22  // Provides info and caches identifiers/selectors for NSFoundation API.
23  class NSAPI {
24  public:
25    explicit NSAPI(ASTContext &Ctx);
26  
getASTContext()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.
isNSUTF8StringEncodingConstant(const Expr * E)60    bool isNSUTF8StringEncodingConstant(const Expr *E) const {
61      return isObjCEnumerator(E, "NSUTF8StringEncoding", NSUTF8StringEncodingId);
62    }
63  
64    /// Returns true if the expression \param E is a reference of
65    /// "NSASCIIStringEncoding" enum constant.
isNSASCIIStringEncodingConstant(const Expr * E)66    bool isNSASCIIStringEncodingConstant(const Expr *E) const {
67      return isObjCEnumerator(E, "NSASCIIStringEncoding",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:".
getObjectForKeyedSubscriptSelector()137    Selector getObjectForKeyedSubscriptSelector() const {
138      return getOrInitSelector(StringRef("objectForKeyedSubscript"),
139                               objectForKeyedSubscriptSel);
140    }
141  
142    /// Returns selector for "objectAtIndexedSubscript:".
getObjectAtIndexedSubscriptSelector()143    Selector getObjectAtIndexedSubscriptSelector() const {
144      return getOrInitSelector(StringRef("objectAtIndexedSubscript"),
145                               objectAtIndexedSubscriptSel);
146    }
147  
148    /// Returns selector for "setObject:forKeyedSubscript".
getSetObjectForKeyedSubscriptSelector()149    Selector getSetObjectForKeyedSubscriptSelector() const {
150      StringRef Ids[] = { "setObject", "forKeyedSubscript" };
151      return getOrInitSelector(Ids, setObjectForKeyedSubscriptSel);
152    }
153  
154    /// Returns selector for "setObject:atIndexedSubscript".
getSetObjectAtIndexedSubscriptSelector()155    Selector getSetObjectAtIndexedSubscriptSelector() const {
156      StringRef Ids[] = { "setObject", "atIndexedSubscript" };
157      return getOrInitSelector(Ids, setObjectAtIndexedSubscriptSel);
158    }
159  
160    /// Returns selector for "isEqual:".
getIsEqualSelector()161    Selector getIsEqualSelector() const {
162      return getOrInitSelector(StringRef("isEqual"), isEqualSel);
163    }
164  
getNewSelector()165    Selector getNewSelector() const {
166      return getOrInitNullarySelector("new", NewSel);
167    }
168  
getInitSelector()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  
isNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,Selector Sel)199    bool isNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
200                                   Selector Sel) const {
201      return Sel == getNSNumberLiteralSelector(MK, false) ||
202             Sel == getNSNumberLiteralSelector(MK, 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  
231  private:
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