106f32e7eSjoerg //===--- NSAPI.cpp - NSFoundation APIs ------------------------------------===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg
906f32e7eSjoerg #include "clang/AST/NSAPI.h"
1006f32e7eSjoerg #include "clang/AST/ASTContext.h"
1106f32e7eSjoerg #include "clang/AST/DeclObjC.h"
1206f32e7eSjoerg #include "clang/AST/Expr.h"
1306f32e7eSjoerg #include "llvm/ADT/StringSwitch.h"
1406f32e7eSjoerg
1506f32e7eSjoerg using namespace clang;
1606f32e7eSjoerg
NSAPI(ASTContext & ctx)1706f32e7eSjoerg NSAPI::NSAPI(ASTContext &ctx)
1806f32e7eSjoerg : Ctx(ctx), ClassIds(), BOOLId(nullptr), NSIntegerId(nullptr),
1906f32e7eSjoerg NSUIntegerId(nullptr), NSASCIIStringEncodingId(nullptr),
2006f32e7eSjoerg NSUTF8StringEncodingId(nullptr) {}
2106f32e7eSjoerg
getNSClassId(NSClassIdKindKind K) const2206f32e7eSjoerg IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
2306f32e7eSjoerg static const char *ClassName[NumClassIds] = {
2406f32e7eSjoerg "NSObject",
2506f32e7eSjoerg "NSString",
2606f32e7eSjoerg "NSArray",
2706f32e7eSjoerg "NSMutableArray",
2806f32e7eSjoerg "NSDictionary",
2906f32e7eSjoerg "NSMutableDictionary",
3006f32e7eSjoerg "NSNumber",
3106f32e7eSjoerg "NSMutableSet",
3206f32e7eSjoerg "NSMutableOrderedSet",
3306f32e7eSjoerg "NSValue"
3406f32e7eSjoerg };
3506f32e7eSjoerg
3606f32e7eSjoerg if (!ClassIds[K])
3706f32e7eSjoerg return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));
3806f32e7eSjoerg
3906f32e7eSjoerg return ClassIds[K];
4006f32e7eSjoerg }
4106f32e7eSjoerg
getNSStringSelector(NSStringMethodKind MK) const4206f32e7eSjoerg Selector NSAPI::getNSStringSelector(NSStringMethodKind MK) const {
4306f32e7eSjoerg if (NSStringSelectors[MK].isNull()) {
4406f32e7eSjoerg Selector Sel;
4506f32e7eSjoerg switch (MK) {
4606f32e7eSjoerg case NSStr_stringWithString:
4706f32e7eSjoerg Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithString"));
4806f32e7eSjoerg break;
4906f32e7eSjoerg case NSStr_stringWithUTF8String:
5006f32e7eSjoerg Sel = Ctx.Selectors.getUnarySelector(
5106f32e7eSjoerg &Ctx.Idents.get("stringWithUTF8String"));
5206f32e7eSjoerg break;
5306f32e7eSjoerg case NSStr_initWithUTF8String:
5406f32e7eSjoerg Sel = Ctx.Selectors.getUnarySelector(
5506f32e7eSjoerg &Ctx.Idents.get("initWithUTF8String"));
5606f32e7eSjoerg break;
5706f32e7eSjoerg case NSStr_stringWithCStringEncoding: {
5806f32e7eSjoerg IdentifierInfo *KeyIdents[] = {
5906f32e7eSjoerg &Ctx.Idents.get("stringWithCString"),
6006f32e7eSjoerg &Ctx.Idents.get("encoding")
6106f32e7eSjoerg };
6206f32e7eSjoerg Sel = Ctx.Selectors.getSelector(2, KeyIdents);
6306f32e7eSjoerg break;
6406f32e7eSjoerg }
6506f32e7eSjoerg case NSStr_stringWithCString:
6606f32e7eSjoerg Sel= Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithCString"));
6706f32e7eSjoerg break;
6806f32e7eSjoerg case NSStr_initWithString:
6906f32e7eSjoerg Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString"));
7006f32e7eSjoerg break;
7106f32e7eSjoerg }
7206f32e7eSjoerg return (NSStringSelectors[MK] = Sel);
7306f32e7eSjoerg }
7406f32e7eSjoerg
7506f32e7eSjoerg return NSStringSelectors[MK];
7606f32e7eSjoerg }
7706f32e7eSjoerg
getNSArraySelector(NSArrayMethodKind MK) const7806f32e7eSjoerg Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const {
7906f32e7eSjoerg if (NSArraySelectors[MK].isNull()) {
8006f32e7eSjoerg Selector Sel;
8106f32e7eSjoerg switch (MK) {
8206f32e7eSjoerg case NSArr_array:
8306f32e7eSjoerg Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array"));
8406f32e7eSjoerg break;
8506f32e7eSjoerg case NSArr_arrayWithArray:
8606f32e7eSjoerg Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray"));
8706f32e7eSjoerg break;
8806f32e7eSjoerg case NSArr_arrayWithObject:
8906f32e7eSjoerg Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject"));
9006f32e7eSjoerg break;
9106f32e7eSjoerg case NSArr_arrayWithObjects:
9206f32e7eSjoerg Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects"));
9306f32e7eSjoerg break;
9406f32e7eSjoerg case NSArr_arrayWithObjectsCount: {
9506f32e7eSjoerg IdentifierInfo *KeyIdents[] = {
9606f32e7eSjoerg &Ctx.Idents.get("arrayWithObjects"),
9706f32e7eSjoerg &Ctx.Idents.get("count")
9806f32e7eSjoerg };
9906f32e7eSjoerg Sel = Ctx.Selectors.getSelector(2, KeyIdents);
10006f32e7eSjoerg break;
10106f32e7eSjoerg }
10206f32e7eSjoerg case NSArr_initWithArray:
10306f32e7eSjoerg Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray"));
10406f32e7eSjoerg break;
10506f32e7eSjoerg case NSArr_initWithObjects:
10606f32e7eSjoerg Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects"));
10706f32e7eSjoerg break;
10806f32e7eSjoerg case NSArr_objectAtIndex:
10906f32e7eSjoerg Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex"));
11006f32e7eSjoerg break;
11106f32e7eSjoerg case NSMutableArr_replaceObjectAtIndex: {
11206f32e7eSjoerg IdentifierInfo *KeyIdents[] = {
11306f32e7eSjoerg &Ctx.Idents.get("replaceObjectAtIndex"),
11406f32e7eSjoerg &Ctx.Idents.get("withObject")
11506f32e7eSjoerg };
11606f32e7eSjoerg Sel = Ctx.Selectors.getSelector(2, KeyIdents);
11706f32e7eSjoerg break;
11806f32e7eSjoerg }
11906f32e7eSjoerg case NSMutableArr_addObject:
12006f32e7eSjoerg Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
12106f32e7eSjoerg break;
12206f32e7eSjoerg case NSMutableArr_insertObjectAtIndex: {
12306f32e7eSjoerg IdentifierInfo *KeyIdents[] = {
12406f32e7eSjoerg &Ctx.Idents.get("insertObject"),
12506f32e7eSjoerg &Ctx.Idents.get("atIndex")
12606f32e7eSjoerg };
12706f32e7eSjoerg Sel = Ctx.Selectors.getSelector(2, KeyIdents);
12806f32e7eSjoerg break;
12906f32e7eSjoerg }
13006f32e7eSjoerg case NSMutableArr_setObjectAtIndexedSubscript: {
13106f32e7eSjoerg IdentifierInfo *KeyIdents[] = {
13206f32e7eSjoerg &Ctx.Idents.get("setObject"),
13306f32e7eSjoerg &Ctx.Idents.get("atIndexedSubscript")
13406f32e7eSjoerg };
13506f32e7eSjoerg Sel = Ctx.Selectors.getSelector(2, KeyIdents);
13606f32e7eSjoerg break;
13706f32e7eSjoerg }
13806f32e7eSjoerg }
13906f32e7eSjoerg return (NSArraySelectors[MK] = Sel);
14006f32e7eSjoerg }
14106f32e7eSjoerg
14206f32e7eSjoerg return NSArraySelectors[MK];
14306f32e7eSjoerg }
14406f32e7eSjoerg
getNSArrayMethodKind(Selector Sel)14506f32e7eSjoerg Optional<NSAPI::NSArrayMethodKind> NSAPI::getNSArrayMethodKind(Selector Sel) {
14606f32e7eSjoerg for (unsigned i = 0; i != NumNSArrayMethods; ++i) {
14706f32e7eSjoerg NSArrayMethodKind MK = NSArrayMethodKind(i);
14806f32e7eSjoerg if (Sel == getNSArraySelector(MK))
14906f32e7eSjoerg return MK;
15006f32e7eSjoerg }
15106f32e7eSjoerg
15206f32e7eSjoerg return None;
15306f32e7eSjoerg }
15406f32e7eSjoerg
getNSDictionarySelector(NSDictionaryMethodKind MK) const15506f32e7eSjoerg Selector NSAPI::getNSDictionarySelector(
15606f32e7eSjoerg NSDictionaryMethodKind MK) const {
15706f32e7eSjoerg if (NSDictionarySelectors[MK].isNull()) {
15806f32e7eSjoerg Selector Sel;
15906f32e7eSjoerg switch (MK) {
16006f32e7eSjoerg case NSDict_dictionary:
16106f32e7eSjoerg Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary"));
16206f32e7eSjoerg break;
16306f32e7eSjoerg case NSDict_dictionaryWithDictionary:
16406f32e7eSjoerg Sel = Ctx.Selectors.getUnarySelector(
16506f32e7eSjoerg &Ctx.Idents.get("dictionaryWithDictionary"));
16606f32e7eSjoerg break;
16706f32e7eSjoerg case NSDict_dictionaryWithObjectForKey: {
16806f32e7eSjoerg IdentifierInfo *KeyIdents[] = {
16906f32e7eSjoerg &Ctx.Idents.get("dictionaryWithObject"),
17006f32e7eSjoerg &Ctx.Idents.get("forKey")
17106f32e7eSjoerg };
17206f32e7eSjoerg Sel = Ctx.Selectors.getSelector(2, KeyIdents);
17306f32e7eSjoerg break;
17406f32e7eSjoerg }
17506f32e7eSjoerg case NSDict_dictionaryWithObjectsForKeys: {
17606f32e7eSjoerg IdentifierInfo *KeyIdents[] = {
17706f32e7eSjoerg &Ctx.Idents.get("dictionaryWithObjects"),
17806f32e7eSjoerg &Ctx.Idents.get("forKeys")
17906f32e7eSjoerg };
18006f32e7eSjoerg Sel = Ctx.Selectors.getSelector(2, KeyIdents);
18106f32e7eSjoerg break;
18206f32e7eSjoerg }
18306f32e7eSjoerg case NSDict_dictionaryWithObjectsForKeysCount: {
18406f32e7eSjoerg IdentifierInfo *KeyIdents[] = {
18506f32e7eSjoerg &Ctx.Idents.get("dictionaryWithObjects"),
18606f32e7eSjoerg &Ctx.Idents.get("forKeys"),
18706f32e7eSjoerg &Ctx.Idents.get("count")
18806f32e7eSjoerg };
18906f32e7eSjoerg Sel = Ctx.Selectors.getSelector(3, KeyIdents);
19006f32e7eSjoerg break;
19106f32e7eSjoerg }
19206f32e7eSjoerg case NSDict_dictionaryWithObjectsAndKeys:
19306f32e7eSjoerg Sel = Ctx.Selectors.getUnarySelector(
19406f32e7eSjoerg &Ctx.Idents.get("dictionaryWithObjectsAndKeys"));
19506f32e7eSjoerg break;
19606f32e7eSjoerg case NSDict_initWithDictionary:
19706f32e7eSjoerg Sel = Ctx.Selectors.getUnarySelector(
19806f32e7eSjoerg &Ctx.Idents.get("initWithDictionary"));
19906f32e7eSjoerg break;
20006f32e7eSjoerg case NSDict_initWithObjectsAndKeys:
20106f32e7eSjoerg Sel = Ctx.Selectors.getUnarySelector(
20206f32e7eSjoerg &Ctx.Idents.get("initWithObjectsAndKeys"));
20306f32e7eSjoerg break;
20406f32e7eSjoerg case NSDict_initWithObjectsForKeys: {
20506f32e7eSjoerg IdentifierInfo *KeyIdents[] = {
20606f32e7eSjoerg &Ctx.Idents.get("initWithObjects"),
20706f32e7eSjoerg &Ctx.Idents.get("forKeys")
20806f32e7eSjoerg };
20906f32e7eSjoerg Sel = Ctx.Selectors.getSelector(2, KeyIdents);
21006f32e7eSjoerg break;
21106f32e7eSjoerg }
21206f32e7eSjoerg case NSDict_objectForKey:
21306f32e7eSjoerg Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey"));
21406f32e7eSjoerg break;
21506f32e7eSjoerg case NSMutableDict_setObjectForKey: {
21606f32e7eSjoerg IdentifierInfo *KeyIdents[] = {
21706f32e7eSjoerg &Ctx.Idents.get("setObject"),
21806f32e7eSjoerg &Ctx.Idents.get("forKey")
21906f32e7eSjoerg };
22006f32e7eSjoerg Sel = Ctx.Selectors.getSelector(2, KeyIdents);
22106f32e7eSjoerg break;
22206f32e7eSjoerg }
22306f32e7eSjoerg case NSMutableDict_setObjectForKeyedSubscript: {
22406f32e7eSjoerg IdentifierInfo *KeyIdents[] = {
22506f32e7eSjoerg &Ctx.Idents.get("setObject"),
22606f32e7eSjoerg &Ctx.Idents.get("forKeyedSubscript")
22706f32e7eSjoerg };
22806f32e7eSjoerg Sel = Ctx.Selectors.getSelector(2, KeyIdents);
22906f32e7eSjoerg break;
23006f32e7eSjoerg }
23106f32e7eSjoerg case NSMutableDict_setValueForKey: {
23206f32e7eSjoerg IdentifierInfo *KeyIdents[] = {
23306f32e7eSjoerg &Ctx.Idents.get("setValue"),
23406f32e7eSjoerg &Ctx.Idents.get("forKey")
23506f32e7eSjoerg };
23606f32e7eSjoerg Sel = Ctx.Selectors.getSelector(2, KeyIdents);
23706f32e7eSjoerg break;
23806f32e7eSjoerg }
23906f32e7eSjoerg }
24006f32e7eSjoerg return (NSDictionarySelectors[MK] = Sel);
24106f32e7eSjoerg }
24206f32e7eSjoerg
24306f32e7eSjoerg return NSDictionarySelectors[MK];
24406f32e7eSjoerg }
24506f32e7eSjoerg
24606f32e7eSjoerg Optional<NSAPI::NSDictionaryMethodKind>
getNSDictionaryMethodKind(Selector Sel)24706f32e7eSjoerg NSAPI::getNSDictionaryMethodKind(Selector Sel) {
24806f32e7eSjoerg for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) {
24906f32e7eSjoerg NSDictionaryMethodKind MK = NSDictionaryMethodKind(i);
25006f32e7eSjoerg if (Sel == getNSDictionarySelector(MK))
25106f32e7eSjoerg return MK;
25206f32e7eSjoerg }
25306f32e7eSjoerg
25406f32e7eSjoerg return None;
25506f32e7eSjoerg }
25606f32e7eSjoerg
getNSSetSelector(NSSetMethodKind MK) const25706f32e7eSjoerg Selector NSAPI::getNSSetSelector(NSSetMethodKind MK) const {
25806f32e7eSjoerg if (NSSetSelectors[MK].isNull()) {
25906f32e7eSjoerg Selector Sel;
26006f32e7eSjoerg switch (MK) {
26106f32e7eSjoerg case NSMutableSet_addObject:
26206f32e7eSjoerg Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
26306f32e7eSjoerg break;
26406f32e7eSjoerg case NSOrderedSet_insertObjectAtIndex: {
26506f32e7eSjoerg IdentifierInfo *KeyIdents[] = {
26606f32e7eSjoerg &Ctx.Idents.get("insertObject"),
26706f32e7eSjoerg &Ctx.Idents.get("atIndex")
26806f32e7eSjoerg };
26906f32e7eSjoerg Sel = Ctx.Selectors.getSelector(2, KeyIdents);
27006f32e7eSjoerg break;
27106f32e7eSjoerg }
27206f32e7eSjoerg case NSOrderedSet_setObjectAtIndex: {
27306f32e7eSjoerg IdentifierInfo *KeyIdents[] = {
27406f32e7eSjoerg &Ctx.Idents.get("setObject"),
27506f32e7eSjoerg &Ctx.Idents.get("atIndex")
27606f32e7eSjoerg };
27706f32e7eSjoerg Sel = Ctx.Selectors.getSelector(2, KeyIdents);
27806f32e7eSjoerg break;
27906f32e7eSjoerg }
28006f32e7eSjoerg case NSOrderedSet_setObjectAtIndexedSubscript: {
28106f32e7eSjoerg IdentifierInfo *KeyIdents[] = {
28206f32e7eSjoerg &Ctx.Idents.get("setObject"),
28306f32e7eSjoerg &Ctx.Idents.get("atIndexedSubscript")
28406f32e7eSjoerg };
28506f32e7eSjoerg Sel = Ctx.Selectors.getSelector(2, KeyIdents);
28606f32e7eSjoerg break;
28706f32e7eSjoerg }
28806f32e7eSjoerg case NSOrderedSet_replaceObjectAtIndexWithObject: {
28906f32e7eSjoerg IdentifierInfo *KeyIdents[] = {
29006f32e7eSjoerg &Ctx.Idents.get("replaceObjectAtIndex"),
29106f32e7eSjoerg &Ctx.Idents.get("withObject")
29206f32e7eSjoerg };
29306f32e7eSjoerg Sel = Ctx.Selectors.getSelector(2, KeyIdents);
29406f32e7eSjoerg break;
29506f32e7eSjoerg }
29606f32e7eSjoerg }
29706f32e7eSjoerg return (NSSetSelectors[MK] = Sel);
29806f32e7eSjoerg }
29906f32e7eSjoerg
30006f32e7eSjoerg return NSSetSelectors[MK];
30106f32e7eSjoerg }
30206f32e7eSjoerg
30306f32e7eSjoerg Optional<NSAPI::NSSetMethodKind>
getNSSetMethodKind(Selector Sel)30406f32e7eSjoerg NSAPI::getNSSetMethodKind(Selector Sel) {
30506f32e7eSjoerg for (unsigned i = 0; i != NumNSSetMethods; ++i) {
30606f32e7eSjoerg NSSetMethodKind MK = NSSetMethodKind(i);
30706f32e7eSjoerg if (Sel == getNSSetSelector(MK))
30806f32e7eSjoerg return MK;
30906f32e7eSjoerg }
31006f32e7eSjoerg
31106f32e7eSjoerg return None;
31206f32e7eSjoerg }
31306f32e7eSjoerg
getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,bool Instance) const31406f32e7eSjoerg Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
31506f32e7eSjoerg bool Instance) const {
31606f32e7eSjoerg static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {
31706f32e7eSjoerg "numberWithChar",
31806f32e7eSjoerg "numberWithUnsignedChar",
31906f32e7eSjoerg "numberWithShort",
32006f32e7eSjoerg "numberWithUnsignedShort",
32106f32e7eSjoerg "numberWithInt",
32206f32e7eSjoerg "numberWithUnsignedInt",
32306f32e7eSjoerg "numberWithLong",
32406f32e7eSjoerg "numberWithUnsignedLong",
32506f32e7eSjoerg "numberWithLongLong",
32606f32e7eSjoerg "numberWithUnsignedLongLong",
32706f32e7eSjoerg "numberWithFloat",
32806f32e7eSjoerg "numberWithDouble",
32906f32e7eSjoerg "numberWithBool",
33006f32e7eSjoerg "numberWithInteger",
33106f32e7eSjoerg "numberWithUnsignedInteger"
33206f32e7eSjoerg };
33306f32e7eSjoerg static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {
33406f32e7eSjoerg "initWithChar",
33506f32e7eSjoerg "initWithUnsignedChar",
33606f32e7eSjoerg "initWithShort",
33706f32e7eSjoerg "initWithUnsignedShort",
33806f32e7eSjoerg "initWithInt",
33906f32e7eSjoerg "initWithUnsignedInt",
34006f32e7eSjoerg "initWithLong",
34106f32e7eSjoerg "initWithUnsignedLong",
34206f32e7eSjoerg "initWithLongLong",
34306f32e7eSjoerg "initWithUnsignedLongLong",
34406f32e7eSjoerg "initWithFloat",
34506f32e7eSjoerg "initWithDouble",
34606f32e7eSjoerg "initWithBool",
34706f32e7eSjoerg "initWithInteger",
34806f32e7eSjoerg "initWithUnsignedInteger"
34906f32e7eSjoerg };
35006f32e7eSjoerg
35106f32e7eSjoerg Selector *Sels;
35206f32e7eSjoerg const char **Names;
35306f32e7eSjoerg if (Instance) {
35406f32e7eSjoerg Sels = NSNumberInstanceSelectors;
35506f32e7eSjoerg Names = InstanceSelectorName;
35606f32e7eSjoerg } else {
35706f32e7eSjoerg Sels = NSNumberClassSelectors;
35806f32e7eSjoerg Names = ClassSelectorName;
35906f32e7eSjoerg }
36006f32e7eSjoerg
36106f32e7eSjoerg if (Sels[MK].isNull())
36206f32e7eSjoerg Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK]));
36306f32e7eSjoerg return Sels[MK];
36406f32e7eSjoerg }
36506f32e7eSjoerg
36606f32e7eSjoerg Optional<NSAPI::NSNumberLiteralMethodKind>
getNSNumberLiteralMethodKind(Selector Sel) const36706f32e7eSjoerg NSAPI::getNSNumberLiteralMethodKind(Selector Sel) const {
36806f32e7eSjoerg for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) {
36906f32e7eSjoerg NSNumberLiteralMethodKind MK = NSNumberLiteralMethodKind(i);
37006f32e7eSjoerg if (isNSNumberLiteralSelector(MK, Sel))
37106f32e7eSjoerg return MK;
37206f32e7eSjoerg }
37306f32e7eSjoerg
37406f32e7eSjoerg return None;
37506f32e7eSjoerg }
37606f32e7eSjoerg
37706f32e7eSjoerg Optional<NSAPI::NSNumberLiteralMethodKind>
getNSNumberFactoryMethodKind(QualType T) const37806f32e7eSjoerg NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
37906f32e7eSjoerg const BuiltinType *BT = T->getAs<BuiltinType>();
38006f32e7eSjoerg if (!BT)
38106f32e7eSjoerg return None;
38206f32e7eSjoerg
38306f32e7eSjoerg const TypedefType *TDT = T->getAs<TypedefType>();
38406f32e7eSjoerg if (TDT) {
38506f32e7eSjoerg QualType TDTTy = QualType(TDT, 0);
38606f32e7eSjoerg if (isObjCBOOLType(TDTTy))
38706f32e7eSjoerg return NSAPI::NSNumberWithBool;
38806f32e7eSjoerg if (isObjCNSIntegerType(TDTTy))
38906f32e7eSjoerg return NSAPI::NSNumberWithInteger;
39006f32e7eSjoerg if (isObjCNSUIntegerType(TDTTy))
39106f32e7eSjoerg return NSAPI::NSNumberWithUnsignedInteger;
39206f32e7eSjoerg }
39306f32e7eSjoerg
39406f32e7eSjoerg switch (BT->getKind()) {
39506f32e7eSjoerg case BuiltinType::Char_S:
39606f32e7eSjoerg case BuiltinType::SChar:
39706f32e7eSjoerg return NSAPI::NSNumberWithChar;
39806f32e7eSjoerg case BuiltinType::Char_U:
39906f32e7eSjoerg case BuiltinType::UChar:
40006f32e7eSjoerg return NSAPI::NSNumberWithUnsignedChar;
40106f32e7eSjoerg case BuiltinType::Short:
40206f32e7eSjoerg return NSAPI::NSNumberWithShort;
40306f32e7eSjoerg case BuiltinType::UShort:
40406f32e7eSjoerg return NSAPI::NSNumberWithUnsignedShort;
40506f32e7eSjoerg case BuiltinType::Int:
40606f32e7eSjoerg return NSAPI::NSNumberWithInt;
40706f32e7eSjoerg case BuiltinType::UInt:
40806f32e7eSjoerg return NSAPI::NSNumberWithUnsignedInt;
40906f32e7eSjoerg case BuiltinType::Long:
41006f32e7eSjoerg return NSAPI::NSNumberWithLong;
41106f32e7eSjoerg case BuiltinType::ULong:
41206f32e7eSjoerg return NSAPI::NSNumberWithUnsignedLong;
41306f32e7eSjoerg case BuiltinType::LongLong:
41406f32e7eSjoerg return NSAPI::NSNumberWithLongLong;
41506f32e7eSjoerg case BuiltinType::ULongLong:
41606f32e7eSjoerg return NSAPI::NSNumberWithUnsignedLongLong;
41706f32e7eSjoerg case BuiltinType::Float:
41806f32e7eSjoerg return NSAPI::NSNumberWithFloat;
41906f32e7eSjoerg case BuiltinType::Double:
42006f32e7eSjoerg return NSAPI::NSNumberWithDouble;
42106f32e7eSjoerg case BuiltinType::Bool:
42206f32e7eSjoerg return NSAPI::NSNumberWithBool;
42306f32e7eSjoerg
42406f32e7eSjoerg case BuiltinType::Void:
42506f32e7eSjoerg case BuiltinType::WChar_U:
42606f32e7eSjoerg case BuiltinType::WChar_S:
42706f32e7eSjoerg case BuiltinType::Char8:
42806f32e7eSjoerg case BuiltinType::Char16:
42906f32e7eSjoerg case BuiltinType::Char32:
43006f32e7eSjoerg case BuiltinType::Int128:
43106f32e7eSjoerg case BuiltinType::LongDouble:
43206f32e7eSjoerg case BuiltinType::ShortAccum:
43306f32e7eSjoerg case BuiltinType::Accum:
43406f32e7eSjoerg case BuiltinType::LongAccum:
43506f32e7eSjoerg case BuiltinType::UShortAccum:
43606f32e7eSjoerg case BuiltinType::UAccum:
43706f32e7eSjoerg case BuiltinType::ULongAccum:
43806f32e7eSjoerg case BuiltinType::ShortFract:
43906f32e7eSjoerg case BuiltinType::Fract:
44006f32e7eSjoerg case BuiltinType::LongFract:
44106f32e7eSjoerg case BuiltinType::UShortFract:
44206f32e7eSjoerg case BuiltinType::UFract:
44306f32e7eSjoerg case BuiltinType::ULongFract:
44406f32e7eSjoerg case BuiltinType::SatShortAccum:
44506f32e7eSjoerg case BuiltinType::SatAccum:
44606f32e7eSjoerg case BuiltinType::SatLongAccum:
44706f32e7eSjoerg case BuiltinType::SatUShortAccum:
44806f32e7eSjoerg case BuiltinType::SatUAccum:
44906f32e7eSjoerg case BuiltinType::SatULongAccum:
45006f32e7eSjoerg case BuiltinType::SatShortFract:
45106f32e7eSjoerg case BuiltinType::SatFract:
45206f32e7eSjoerg case BuiltinType::SatLongFract:
45306f32e7eSjoerg case BuiltinType::SatUShortFract:
45406f32e7eSjoerg case BuiltinType::SatUFract:
45506f32e7eSjoerg case BuiltinType::SatULongFract:
45606f32e7eSjoerg case BuiltinType::UInt128:
45706f32e7eSjoerg case BuiltinType::Float16:
45806f32e7eSjoerg case BuiltinType::Float128:
45906f32e7eSjoerg case BuiltinType::NullPtr:
46006f32e7eSjoerg case BuiltinType::ObjCClass:
46106f32e7eSjoerg case BuiltinType::ObjCId:
46206f32e7eSjoerg case BuiltinType::ObjCSel:
46306f32e7eSjoerg #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
46406f32e7eSjoerg case BuiltinType::Id:
46506f32e7eSjoerg #include "clang/Basic/OpenCLImageTypes.def"
46606f32e7eSjoerg #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
46706f32e7eSjoerg case BuiltinType::Id:
46806f32e7eSjoerg #include "clang/Basic/OpenCLExtensionTypes.def"
46906f32e7eSjoerg case BuiltinType::OCLSampler:
47006f32e7eSjoerg case BuiltinType::OCLEvent:
47106f32e7eSjoerg case BuiltinType::OCLClkEvent:
47206f32e7eSjoerg case BuiltinType::OCLQueue:
47306f32e7eSjoerg case BuiltinType::OCLReserveID:
47406f32e7eSjoerg #define SVE_TYPE(Name, Id, SingletonId) \
47506f32e7eSjoerg case BuiltinType::Id:
47606f32e7eSjoerg #include "clang/Basic/AArch64SVEACLETypes.def"
477*13fbcb42Sjoerg #define PPC_VECTOR_TYPE(Name, Id, Size) \
478*13fbcb42Sjoerg case BuiltinType::Id:
479*13fbcb42Sjoerg #include "clang/Basic/PPCTypes.def"
480*13fbcb42Sjoerg #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
481*13fbcb42Sjoerg #include "clang/Basic/RISCVVTypes.def"
48206f32e7eSjoerg case BuiltinType::BoundMember:
48306f32e7eSjoerg case BuiltinType::Dependent:
48406f32e7eSjoerg case BuiltinType::Overload:
48506f32e7eSjoerg case BuiltinType::UnknownAny:
48606f32e7eSjoerg case BuiltinType::ARCUnbridgedCast:
48706f32e7eSjoerg case BuiltinType::Half:
48806f32e7eSjoerg case BuiltinType::PseudoObject:
48906f32e7eSjoerg case BuiltinType::BuiltinFn:
490*13fbcb42Sjoerg case BuiltinType::IncompleteMatrixIdx:
49106f32e7eSjoerg case BuiltinType::OMPArraySection:
492*13fbcb42Sjoerg case BuiltinType::OMPArrayShaping:
493*13fbcb42Sjoerg case BuiltinType::OMPIterator:
494*13fbcb42Sjoerg case BuiltinType::BFloat16:
49506f32e7eSjoerg break;
49606f32e7eSjoerg }
49706f32e7eSjoerg
49806f32e7eSjoerg return None;
49906f32e7eSjoerg }
50006f32e7eSjoerg
50106f32e7eSjoerg /// Returns true if \param T is a typedef of "BOOL" in objective-c.
isObjCBOOLType(QualType T) const50206f32e7eSjoerg bool NSAPI::isObjCBOOLType(QualType T) const {
50306f32e7eSjoerg return isObjCTypedef(T, "BOOL", BOOLId);
50406f32e7eSjoerg }
50506f32e7eSjoerg /// Returns true if \param T is a typedef of "NSInteger" in objective-c.
isObjCNSIntegerType(QualType T) const50606f32e7eSjoerg bool NSAPI::isObjCNSIntegerType(QualType T) const {
50706f32e7eSjoerg return isObjCTypedef(T, "NSInteger", NSIntegerId);
50806f32e7eSjoerg }
50906f32e7eSjoerg /// Returns true if \param T is a typedef of "NSUInteger" in objective-c.
isObjCNSUIntegerType(QualType T) const51006f32e7eSjoerg bool NSAPI::isObjCNSUIntegerType(QualType T) const {
51106f32e7eSjoerg return isObjCTypedef(T, "NSUInteger", NSUIntegerId);
51206f32e7eSjoerg }
51306f32e7eSjoerg
GetNSIntegralKind(QualType T) const51406f32e7eSjoerg StringRef NSAPI::GetNSIntegralKind(QualType T) const {
51506f32e7eSjoerg if (!Ctx.getLangOpts().ObjC || T.isNull())
51606f32e7eSjoerg return StringRef();
51706f32e7eSjoerg
51806f32e7eSjoerg while (const TypedefType *TDT = T->getAs<TypedefType>()) {
51906f32e7eSjoerg StringRef NSIntegralResust =
52006f32e7eSjoerg llvm::StringSwitch<StringRef>(
52106f32e7eSjoerg TDT->getDecl()->getDeclName().getAsIdentifierInfo()->getName())
52206f32e7eSjoerg .Case("int8_t", "int8_t")
52306f32e7eSjoerg .Case("int16_t", "int16_t")
52406f32e7eSjoerg .Case("int32_t", "int32_t")
52506f32e7eSjoerg .Case("NSInteger", "NSInteger")
52606f32e7eSjoerg .Case("int64_t", "int64_t")
52706f32e7eSjoerg .Case("uint8_t", "uint8_t")
52806f32e7eSjoerg .Case("uint16_t", "uint16_t")
52906f32e7eSjoerg .Case("uint32_t", "uint32_t")
53006f32e7eSjoerg .Case("NSUInteger", "NSUInteger")
53106f32e7eSjoerg .Case("uint64_t", "uint64_t")
53206f32e7eSjoerg .Default(StringRef());
53306f32e7eSjoerg if (!NSIntegralResust.empty())
53406f32e7eSjoerg return NSIntegralResust;
53506f32e7eSjoerg T = TDT->desugar();
53606f32e7eSjoerg }
53706f32e7eSjoerg return StringRef();
53806f32e7eSjoerg }
53906f32e7eSjoerg
isMacroDefined(StringRef Id) const54006f32e7eSjoerg bool NSAPI::isMacroDefined(StringRef Id) const {
54106f32e7eSjoerg // FIXME: Check whether the relevant module macros are visible.
54206f32e7eSjoerg return Ctx.Idents.get(Id).hasMacroDefinition();
54306f32e7eSjoerg }
54406f32e7eSjoerg
isSubclassOfNSClass(ObjCInterfaceDecl * InterfaceDecl,NSClassIdKindKind NSClassKind) const54506f32e7eSjoerg bool NSAPI::isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl,
54606f32e7eSjoerg NSClassIdKindKind NSClassKind) const {
54706f32e7eSjoerg if (!InterfaceDecl) {
54806f32e7eSjoerg return false;
54906f32e7eSjoerg }
55006f32e7eSjoerg
55106f32e7eSjoerg IdentifierInfo *NSClassID = getNSClassId(NSClassKind);
55206f32e7eSjoerg
55306f32e7eSjoerg bool IsSubclass = false;
55406f32e7eSjoerg do {
55506f32e7eSjoerg IsSubclass = NSClassID == InterfaceDecl->getIdentifier();
55606f32e7eSjoerg
55706f32e7eSjoerg if (IsSubclass) {
55806f32e7eSjoerg break;
55906f32e7eSjoerg }
56006f32e7eSjoerg } while ((InterfaceDecl = InterfaceDecl->getSuperClass()));
56106f32e7eSjoerg
56206f32e7eSjoerg return IsSubclass;
56306f32e7eSjoerg }
56406f32e7eSjoerg
isObjCTypedef(QualType T,StringRef name,IdentifierInfo * & II) const56506f32e7eSjoerg bool NSAPI::isObjCTypedef(QualType T,
56606f32e7eSjoerg StringRef name, IdentifierInfo *&II) const {
56706f32e7eSjoerg if (!Ctx.getLangOpts().ObjC)
56806f32e7eSjoerg return false;
56906f32e7eSjoerg if (T.isNull())
57006f32e7eSjoerg return false;
57106f32e7eSjoerg
57206f32e7eSjoerg if (!II)
57306f32e7eSjoerg II = &Ctx.Idents.get(name);
57406f32e7eSjoerg
57506f32e7eSjoerg while (const TypedefType *TDT = T->getAs<TypedefType>()) {
57606f32e7eSjoerg if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
57706f32e7eSjoerg return true;
57806f32e7eSjoerg T = TDT->desugar();
57906f32e7eSjoerg }
58006f32e7eSjoerg
58106f32e7eSjoerg return false;
58206f32e7eSjoerg }
58306f32e7eSjoerg
isObjCEnumerator(const Expr * E,StringRef name,IdentifierInfo * & II) const58406f32e7eSjoerg bool NSAPI::isObjCEnumerator(const Expr *E,
58506f32e7eSjoerg StringRef name, IdentifierInfo *&II) const {
58606f32e7eSjoerg if (!Ctx.getLangOpts().ObjC)
58706f32e7eSjoerg return false;
58806f32e7eSjoerg if (!E)
58906f32e7eSjoerg return false;
59006f32e7eSjoerg
59106f32e7eSjoerg if (!II)
59206f32e7eSjoerg II = &Ctx.Idents.get(name);
59306f32e7eSjoerg
59406f32e7eSjoerg if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
59506f32e7eSjoerg if (const EnumConstantDecl *
59606f32e7eSjoerg EnumD = dyn_cast_or_null<EnumConstantDecl>(DRE->getDecl()))
59706f32e7eSjoerg return EnumD->getIdentifier() == II;
59806f32e7eSjoerg
59906f32e7eSjoerg return false;
60006f32e7eSjoerg }
60106f32e7eSjoerg
getOrInitSelector(ArrayRef<StringRef> Ids,Selector & Sel) const60206f32e7eSjoerg Selector NSAPI::getOrInitSelector(ArrayRef<StringRef> Ids,
60306f32e7eSjoerg Selector &Sel) const {
60406f32e7eSjoerg if (Sel.isNull()) {
60506f32e7eSjoerg SmallVector<IdentifierInfo *, 4> Idents;
60606f32e7eSjoerg for (ArrayRef<StringRef>::const_iterator
60706f32e7eSjoerg I = Ids.begin(), E = Ids.end(); I != E; ++I)
60806f32e7eSjoerg Idents.push_back(&Ctx.Idents.get(*I));
60906f32e7eSjoerg Sel = Ctx.Selectors.getSelector(Idents.size(), Idents.data());
61006f32e7eSjoerg }
61106f32e7eSjoerg return Sel;
61206f32e7eSjoerg }
61306f32e7eSjoerg
getOrInitNullarySelector(StringRef Id,Selector & Sel) const61406f32e7eSjoerg Selector NSAPI::getOrInitNullarySelector(StringRef Id, Selector &Sel) const {
61506f32e7eSjoerg if (Sel.isNull()) {
61606f32e7eSjoerg IdentifierInfo *Ident = &Ctx.Idents.get(Id);
61706f32e7eSjoerg Sel = Ctx.Selectors.getSelector(0, &Ident);
61806f32e7eSjoerg }
61906f32e7eSjoerg return Sel;
62006f32e7eSjoerg }
621