1234287Sdim//===--- NSAPI.h - NSFoundation APIs ----------------------------*- C++ -*-===//
2234287Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6234287Sdim//
7234287Sdim//===----------------------------------------------------------------------===//
8234287Sdim
9234287Sdim#ifndef LLVM_CLANG_AST_NSAPI_H
10234287Sdim#define LLVM_CLANG_AST_NSAPI_H
11234287Sdim
12234287Sdim#include "clang/Basic/IdentifierTable.h"
13239462Sdim#include "llvm/ADT/ArrayRef.h"
14234287Sdim#include "llvm/ADT/Optional.h"
15234287Sdim
16234287Sdimnamespace clang {
17234287Sdim  class ASTContext;
18288943Sdim  class ObjCInterfaceDecl;
19234287Sdim  class QualType;
20239462Sdim  class Expr;
21234287Sdim
22341825Sdim// Provides info and caches identifiers/selectors for NSFoundation API.
23234287Sdimclass NSAPI {
24234287Sdimpublic:
25234287Sdim  explicit NSAPI(ASTContext &Ctx);
26234287Sdim
27234287Sdim  ASTContext &getASTContext() const { return Ctx; }
28234287Sdim
29234287Sdim  enum NSClassIdKindKind {
30234287Sdim    ClassId_NSObject,
31234287Sdim    ClassId_NSString,
32234287Sdim    ClassId_NSArray,
33234287Sdim    ClassId_NSMutableArray,
34234287Sdim    ClassId_NSDictionary,
35234287Sdim    ClassId_NSMutableDictionary,
36288943Sdim    ClassId_NSNumber,
37288943Sdim    ClassId_NSMutableSet,
38288943Sdim    ClassId_NSMutableOrderedSet,
39288943Sdim    ClassId_NSValue
40234287Sdim  };
41288943Sdim  static const unsigned NumClassIds = 10;
42234287Sdim
43234287Sdim  enum NSStringMethodKind {
44234287Sdim    NSStr_stringWithString,
45239462Sdim    NSStr_stringWithUTF8String,
46239462Sdim    NSStr_stringWithCStringEncoding,
47239462Sdim    NSStr_stringWithCString,
48280031Sdim    NSStr_initWithString,
49280031Sdim    NSStr_initWithUTF8String
50234287Sdim  };
51321369Sdim  static const unsigned NumNSStringMethods = 6;
52234287Sdim
53234287Sdim  IdentifierInfo *getNSClassId(NSClassIdKindKind K) const;
54234287Sdim
55341825Sdim  /// The Objective-C NSString selectors.
56234287Sdim  Selector getNSStringSelector(NSStringMethodKind MK) const;
57234287Sdim
58341825Sdim  /// Returns true if the expression \param E is a reference of
59239462Sdim  /// "NSUTF8StringEncoding" enum constant.
60239462Sdim  bool isNSUTF8StringEncodingConstant(const Expr *E) const {
61239462Sdim    return isObjCEnumerator(E, "NSUTF8StringEncoding", NSUTF8StringEncodingId);
62239462Sdim  }
63239462Sdim
64341825Sdim  /// Returns true if the expression \param E is a reference of
65239462Sdim  /// "NSASCIIStringEncoding" enum constant.
66239462Sdim  bool isNSASCIIStringEncodingConstant(const Expr *E) const {
67239462Sdim    return isObjCEnumerator(E, "NSASCIIStringEncoding",NSASCIIStringEncodingId);
68239462Sdim  }
69239462Sdim
70341825Sdim  /// Enumerates the NSArray/NSMutableArray methods used to generate
71288943Sdim  /// literals and to apply some checks.
72234287Sdim  enum NSArrayMethodKind {
73234287Sdim    NSArr_array,
74234287Sdim    NSArr_arrayWithArray,
75234287Sdim    NSArr_arrayWithObject,
76234287Sdim    NSArr_arrayWithObjects,
77234287Sdim    NSArr_arrayWithObjectsCount,
78234287Sdim    NSArr_initWithArray,
79234287Sdim    NSArr_initWithObjects,
80234287Sdim    NSArr_objectAtIndex,
81288943Sdim    NSMutableArr_replaceObjectAtIndex,
82288943Sdim    NSMutableArr_addObject,
83288943Sdim    NSMutableArr_insertObjectAtIndex,
84288943Sdim    NSMutableArr_setObjectAtIndexedSubscript
85234287Sdim  };
86288943Sdim  static const unsigned NumNSArrayMethods = 12;
87234287Sdim
88341825Sdim  /// The Objective-C NSArray selectors.
89234287Sdim  Selector getNSArraySelector(NSArrayMethodKind MK) const;
90234287Sdim
91341825Sdim  /// Return NSArrayMethodKind if \p Sel is such a selector.
92249423Sdim  Optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel);
93234287Sdim
94341825Sdim  /// Enumerates the NSDictionary/NSMutableDictionary methods used
95288943Sdim  /// to generate literals and to apply some checks.
96234287Sdim  enum NSDictionaryMethodKind {
97234287Sdim    NSDict_dictionary,
98234287Sdim    NSDict_dictionaryWithDictionary,
99234287Sdim    NSDict_dictionaryWithObjectForKey,
100234287Sdim    NSDict_dictionaryWithObjectsForKeys,
101234287Sdim    NSDict_dictionaryWithObjectsForKeysCount,
102234287Sdim    NSDict_dictionaryWithObjectsAndKeys,
103234287Sdim    NSDict_initWithDictionary,
104234287Sdim    NSDict_initWithObjectsAndKeys,
105249423Sdim    NSDict_initWithObjectsForKeys,
106234287Sdim    NSDict_objectForKey,
107288943Sdim    NSMutableDict_setObjectForKey,
108288943Sdim    NSMutableDict_setObjectForKeyedSubscript,
109288943Sdim    NSMutableDict_setValueForKey
110234287Sdim  };
111321369Sdim  static const unsigned NumNSDictionaryMethods = 13;
112341825Sdim
113341825Sdim  /// The Objective-C NSDictionary selectors.
114234287Sdim  Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const;
115234287Sdim
116341825Sdim  /// Return NSDictionaryMethodKind if \p Sel is such a selector.
117249423Sdim  Optional<NSDictionaryMethodKind> getNSDictionaryMethodKind(Selector Sel);
118234287Sdim
119341825Sdim  /// Enumerates the NSMutableSet/NSOrderedSet methods used
120288943Sdim  /// to apply some checks.
121288943Sdim  enum NSSetMethodKind {
122288943Sdim    NSMutableSet_addObject,
123288943Sdim    NSOrderedSet_insertObjectAtIndex,
124288943Sdim    NSOrderedSet_setObjectAtIndex,
125288943Sdim    NSOrderedSet_setObjectAtIndexedSubscript,
126288943Sdim    NSOrderedSet_replaceObjectAtIndexWithObject
127288943Sdim  };
128288943Sdim  static const unsigned NumNSSetMethods = 5;
129288943Sdim
130341825Sdim  /// The Objective-C NSSet selectors.
131288943Sdim  Selector getNSSetSelector(NSSetMethodKind MK) const;
132288943Sdim
133341825Sdim  /// Return NSSetMethodKind if \p Sel is such a selector.
134288943Sdim  Optional<NSSetMethodKind> getNSSetMethodKind(Selector Sel);
135288943Sdim
136341825Sdim  /// Returns selector for "objectForKeyedSubscript:".
137239462Sdim  Selector getObjectForKeyedSubscriptSelector() const {
138239462Sdim    return getOrInitSelector(StringRef("objectForKeyedSubscript"),
139239462Sdim                             objectForKeyedSubscriptSel);
140239462Sdim  }
141239462Sdim
142341825Sdim  /// Returns selector for "objectAtIndexedSubscript:".
143239462Sdim  Selector getObjectAtIndexedSubscriptSelector() const {
144239462Sdim    return getOrInitSelector(StringRef("objectAtIndexedSubscript"),
145239462Sdim                             objectAtIndexedSubscriptSel);
146239462Sdim  }
147239462Sdim
148341825Sdim  /// Returns selector for "setObject:forKeyedSubscript".
149239462Sdim  Selector getSetObjectForKeyedSubscriptSelector() const {
150239462Sdim    StringRef Ids[] = { "setObject", "forKeyedSubscript" };
151239462Sdim    return getOrInitSelector(Ids, setObjectForKeyedSubscriptSel);
152239462Sdim  }
153239462Sdim
154341825Sdim  /// Returns selector for "setObject:atIndexedSubscript".
155239462Sdim  Selector getSetObjectAtIndexedSubscriptSelector() const {
156239462Sdim    StringRef Ids[] = { "setObject", "atIndexedSubscript" };
157239462Sdim    return getOrInitSelector(Ids, setObjectAtIndexedSubscriptSel);
158239462Sdim  }
159239462Sdim
160341825Sdim  /// Returns selector for "isEqual:".
161239462Sdim  Selector getIsEqualSelector() const {
162239462Sdim    return getOrInitSelector(StringRef("isEqual"), isEqualSel);
163239462Sdim  }
164239462Sdim
165344779Sdim  Selector getNewSelector() const {
166344779Sdim    return getOrInitNullarySelector("new", NewSel);
167344779Sdim  }
168344779Sdim
169344779Sdim  Selector getInitSelector() const {
170344779Sdim    return getOrInitNullarySelector("init", InitSel);
171344779Sdim  }
172344779Sdim
173341825Sdim  /// Enumerates the NSNumber methods used to generate literals.
174234287Sdim  enum NSNumberLiteralMethodKind {
175234287Sdim    NSNumberWithChar,
176234287Sdim    NSNumberWithUnsignedChar,
177234287Sdim    NSNumberWithShort,
178234287Sdim    NSNumberWithUnsignedShort,
179234287Sdim    NSNumberWithInt,
180234287Sdim    NSNumberWithUnsignedInt,
181234287Sdim    NSNumberWithLong,
182234287Sdim    NSNumberWithUnsignedLong,
183234287Sdim    NSNumberWithLongLong,
184234287Sdim    NSNumberWithUnsignedLongLong,
185234287Sdim    NSNumberWithFloat,
186234287Sdim    NSNumberWithDouble,
187234287Sdim    NSNumberWithBool,
188234287Sdim    NSNumberWithInteger,
189234287Sdim    NSNumberWithUnsignedInteger
190234287Sdim  };
191234287Sdim  static const unsigned NumNSNumberLiteralMethods = 15;
192234287Sdim
193341825Sdim  /// The Objective-C NSNumber selectors used to create NSNumber literals.
194234287Sdim  /// \param Instance if true it will return the selector for the init* method
195234287Sdim  /// otherwise it will return the selector for the number* method.
196234287Sdim  Selector getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
197234287Sdim                                      bool Instance) const;
198234287Sdim
199234287Sdim  bool isNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
200234287Sdim                                 Selector Sel) const {
201234287Sdim    return Sel == getNSNumberLiteralSelector(MK, false) ||
202234287Sdim           Sel == getNSNumberLiteralSelector(MK, true);
203234287Sdim  }
204234287Sdim
205341825Sdim  /// Return NSNumberLiteralMethodKind if \p Sel is such a selector.
206249423Sdim  Optional<NSNumberLiteralMethodKind>
207234287Sdim      getNSNumberLiteralMethodKind(Selector Sel) const;
208234287Sdim
209341825Sdim  /// Determine the appropriate NSNumber factory method kind for a
210234287Sdim  /// literal of the given type.
211249423Sdim  Optional<NSNumberLiteralMethodKind>
212239462Sdim      getNSNumberFactoryMethodKind(QualType T) const;
213234287Sdim
214341825Sdim  /// Returns true if \param T is a typedef of "BOOL" in objective-c.
215239462Sdim  bool isObjCBOOLType(QualType T) const;
216341825Sdim  /// Returns true if \param T is a typedef of "NSInteger" in objective-c.
217239462Sdim  bool isObjCNSIntegerType(QualType T) const;
218341825Sdim  /// Returns true if \param T is a typedef of "NSUInteger" in objective-c.
219239462Sdim  bool isObjCNSUIntegerType(QualType T) const;
220341825Sdim  /// Returns one of NSIntegral typedef names if \param T is a typedef
221280031Sdim  /// of that name in objective-c.
222280031Sdim  StringRef GetNSIntegralKind(QualType T) const;
223239462Sdim
224341825Sdim  /// Returns \c true if \p Id is currently defined as a macro.
225288943Sdim  bool isMacroDefined(StringRef Id) const;
226288943Sdim
227341825Sdim  /// Returns \c true if \p InterfaceDecl is subclass of \p NSClassKind
228288943Sdim  bool isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl,
229288943Sdim                           NSClassIdKindKind NSClassKind) const;
230288943Sdim
231234287Sdimprivate:
232239462Sdim  bool isObjCTypedef(QualType T, StringRef name, IdentifierInfo *&II) const;
233239462Sdim  bool isObjCEnumerator(const Expr *E,
234239462Sdim                        StringRef name, IdentifierInfo *&II) const;
235239462Sdim  Selector getOrInitSelector(ArrayRef<StringRef> Ids, Selector &Sel) const;
236344779Sdim  Selector getOrInitNullarySelector(StringRef Id, Selector &Sel) const;
237239462Sdim
238234287Sdim  ASTContext &Ctx;
239234287Sdim
240234287Sdim  mutable IdentifierInfo *ClassIds[NumClassIds];
241234287Sdim
242234287Sdim  mutable Selector NSStringSelectors[NumNSStringMethods];
243234287Sdim
244341825Sdim  /// The selectors for Objective-C NSArray methods.
245234287Sdim  mutable Selector NSArraySelectors[NumNSArrayMethods];
246234287Sdim
247341825Sdim  /// The selectors for Objective-C NSDictionary methods.
248234287Sdim  mutable Selector NSDictionarySelectors[NumNSDictionaryMethods];
249234287Sdim
250341825Sdim  /// The selectors for Objective-C NSSet methods.
251288943Sdim  mutable Selector NSSetSelectors[NumNSSetMethods];
252288943Sdim
253341825Sdim  /// The Objective-C NSNumber selectors used to create NSNumber literals.
254234287Sdim  mutable Selector NSNumberClassSelectors[NumNSNumberLiteralMethods];
255234287Sdim  mutable Selector NSNumberInstanceSelectors[NumNSNumberLiteralMethods];
256239462Sdim
257239462Sdim  mutable Selector objectForKeyedSubscriptSel, objectAtIndexedSubscriptSel,
258239462Sdim                   setObjectForKeyedSubscriptSel,setObjectAtIndexedSubscriptSel,
259344779Sdim                   isEqualSel, InitSel, NewSel;
260239462Sdim
261239462Sdim  mutable IdentifierInfo *BOOLId, *NSIntegerId, *NSUIntegerId;
262239462Sdim  mutable IdentifierInfo *NSASCIIStringEncodingId, *NSUTF8StringEncodingId;
263234287Sdim};
264234287Sdim
265234287Sdim}  // end namespace clang
266234287Sdim
267234287Sdim#endif // LLVM_CLANG_AST_NSAPI_H
268