2012-12-18 14:30:41 +00:00
|
|
|
//===--- NSAPI.cpp - NSFoundation APIs ------------------------------------===//
|
|
|
|
//
|
2019-01-19 08:50:56 +00:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2012-12-18 14:30:41 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "clang/AST/NSAPI.h"
|
|
|
|
#include "clang/AST/ASTContext.h"
|
2015-08-06 04:51:14 +00:00
|
|
|
#include "clang/AST/DeclObjC.h"
|
2012-12-18 14:30:41 +00:00
|
|
|
#include "clang/AST/Expr.h"
|
2014-10-06 23:50:37 +00:00
|
|
|
#include "llvm/ADT/StringSwitch.h"
|
2012-12-18 14:30:41 +00:00
|
|
|
|
|
|
|
using namespace clang;
|
|
|
|
|
|
|
|
NSAPI::NSAPI(ASTContext &ctx)
|
2014-05-12 05:36:57 +00:00
|
|
|
: Ctx(ctx), ClassIds(), BOOLId(nullptr), NSIntegerId(nullptr),
|
|
|
|
NSUIntegerId(nullptr), NSASCIIStringEncodingId(nullptr),
|
|
|
|
NSUTF8StringEncodingId(nullptr) {}
|
2012-12-18 14:30:41 +00:00
|
|
|
|
|
|
|
IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
|
|
|
|
static const char *ClassName[NumClassIds] = {
|
|
|
|
"NSObject",
|
|
|
|
"NSString",
|
|
|
|
"NSArray",
|
|
|
|
"NSMutableArray",
|
|
|
|
"NSDictionary",
|
|
|
|
"NSMutableDictionary",
|
2015-03-04 17:55:52 +00:00
|
|
|
"NSNumber",
|
|
|
|
"NSMutableSet",
|
2015-06-26 05:28:36 +00:00
|
|
|
"NSMutableOrderedSet",
|
|
|
|
"NSValue"
|
2012-12-18 14:30:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
if (!ClassIds[K])
|
|
|
|
return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));
|
|
|
|
|
|
|
|
return ClassIds[K];
|
|
|
|
}
|
|
|
|
|
|
|
|
Selector NSAPI::getNSStringSelector(NSStringMethodKind MK) const {
|
|
|
|
if (NSStringSelectors[MK].isNull()) {
|
|
|
|
Selector Sel;
|
|
|
|
switch (MK) {
|
|
|
|
case NSStr_stringWithString:
|
|
|
|
Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithString"));
|
|
|
|
break;
|
|
|
|
case NSStr_stringWithUTF8String:
|
|
|
|
Sel = Ctx.Selectors.getUnarySelector(
|
|
|
|
&Ctx.Idents.get("stringWithUTF8String"));
|
|
|
|
break;
|
2014-08-25 20:22:25 +00:00
|
|
|
case NSStr_initWithUTF8String:
|
|
|
|
Sel = Ctx.Selectors.getUnarySelector(
|
|
|
|
&Ctx.Idents.get("initWithUTF8String"));
|
|
|
|
break;
|
2012-12-18 14:30:41 +00:00
|
|
|
case NSStr_stringWithCStringEncoding: {
|
|
|
|
IdentifierInfo *KeyIdents[] = {
|
|
|
|
&Ctx.Idents.get("stringWithCString"),
|
|
|
|
&Ctx.Idents.get("encoding")
|
|
|
|
};
|
|
|
|
Sel = Ctx.Selectors.getSelector(2, KeyIdents);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NSStr_stringWithCString:
|
|
|
|
Sel= Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithCString"));
|
|
|
|
break;
|
|
|
|
case NSStr_initWithString:
|
|
|
|
Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString"));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return (NSStringSelectors[MK] = Sel);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NSStringSelectors[MK];
|
|
|
|
}
|
|
|
|
|
|
|
|
Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const {
|
|
|
|
if (NSArraySelectors[MK].isNull()) {
|
|
|
|
Selector Sel;
|
|
|
|
switch (MK) {
|
|
|
|
case NSArr_array:
|
|
|
|
Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array"));
|
|
|
|
break;
|
|
|
|
case NSArr_arrayWithArray:
|
|
|
|
Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray"));
|
|
|
|
break;
|
|
|
|
case NSArr_arrayWithObject:
|
|
|
|
Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject"));
|
|
|
|
break;
|
|
|
|
case NSArr_arrayWithObjects:
|
|
|
|
Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects"));
|
|
|
|
break;
|
|
|
|
case NSArr_arrayWithObjectsCount: {
|
|
|
|
IdentifierInfo *KeyIdents[] = {
|
|
|
|
&Ctx.Idents.get("arrayWithObjects"),
|
|
|
|
&Ctx.Idents.get("count")
|
|
|
|
};
|
|
|
|
Sel = Ctx.Selectors.getSelector(2, KeyIdents);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NSArr_initWithArray:
|
|
|
|
Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray"));
|
|
|
|
break;
|
|
|
|
case NSArr_initWithObjects:
|
|
|
|
Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects"));
|
|
|
|
break;
|
|
|
|
case NSArr_objectAtIndex:
|
|
|
|
Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex"));
|
|
|
|
break;
|
|
|
|
case NSMutableArr_replaceObjectAtIndex: {
|
|
|
|
IdentifierInfo *KeyIdents[] = {
|
|
|
|
&Ctx.Idents.get("replaceObjectAtIndex"),
|
|
|
|
&Ctx.Idents.get("withObject")
|
|
|
|
};
|
|
|
|
Sel = Ctx.Selectors.getSelector(2, KeyIdents);
|
|
|
|
break;
|
|
|
|
}
|
2015-03-04 17:55:52 +00:00
|
|
|
case NSMutableArr_addObject:
|
|
|
|
Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
|
|
|
|
break;
|
|
|
|
case NSMutableArr_insertObjectAtIndex: {
|
|
|
|
IdentifierInfo *KeyIdents[] = {
|
|
|
|
&Ctx.Idents.get("insertObject"),
|
|
|
|
&Ctx.Idents.get("atIndex")
|
|
|
|
};
|
|
|
|
Sel = Ctx.Selectors.getSelector(2, KeyIdents);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NSMutableArr_setObjectAtIndexedSubscript: {
|
|
|
|
IdentifierInfo *KeyIdents[] = {
|
|
|
|
&Ctx.Idents.get("setObject"),
|
|
|
|
&Ctx.Idents.get("atIndexedSubscript")
|
|
|
|
};
|
|
|
|
Sel = Ctx.Selectors.getSelector(2, KeyIdents);
|
|
|
|
break;
|
|
|
|
}
|
2012-12-18 14:30:41 +00:00
|
|
|
}
|
|
|
|
return (NSArraySelectors[MK] = Sel);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NSArraySelectors[MK];
|
|
|
|
}
|
|
|
|
|
2013-02-20 22:23:23 +00:00
|
|
|
Optional<NSAPI::NSArrayMethodKind> NSAPI::getNSArrayMethodKind(Selector Sel) {
|
2012-12-18 14:30:41 +00:00
|
|
|
for (unsigned i = 0; i != NumNSArrayMethods; ++i) {
|
|
|
|
NSArrayMethodKind MK = NSArrayMethodKind(i);
|
|
|
|
if (Sel == getNSArraySelector(MK))
|
|
|
|
return MK;
|
|
|
|
}
|
|
|
|
|
2022-12-03 11:13:41 -08:00
|
|
|
return std::nullopt;
|
2012-12-18 14:30:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Selector NSAPI::getNSDictionarySelector(
|
|
|
|
NSDictionaryMethodKind MK) const {
|
|
|
|
if (NSDictionarySelectors[MK].isNull()) {
|
|
|
|
Selector Sel;
|
|
|
|
switch (MK) {
|
|
|
|
case NSDict_dictionary:
|
|
|
|
Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary"));
|
|
|
|
break;
|
|
|
|
case NSDict_dictionaryWithDictionary:
|
|
|
|
Sel = Ctx.Selectors.getUnarySelector(
|
|
|
|
&Ctx.Idents.get("dictionaryWithDictionary"));
|
|
|
|
break;
|
|
|
|
case NSDict_dictionaryWithObjectForKey: {
|
|
|
|
IdentifierInfo *KeyIdents[] = {
|
|
|
|
&Ctx.Idents.get("dictionaryWithObject"),
|
|
|
|
&Ctx.Idents.get("forKey")
|
|
|
|
};
|
|
|
|
Sel = Ctx.Selectors.getSelector(2, KeyIdents);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NSDict_dictionaryWithObjectsForKeys: {
|
|
|
|
IdentifierInfo *KeyIdents[] = {
|
|
|
|
&Ctx.Idents.get("dictionaryWithObjects"),
|
|
|
|
&Ctx.Idents.get("forKeys")
|
|
|
|
};
|
|
|
|
Sel = Ctx.Selectors.getSelector(2, KeyIdents);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NSDict_dictionaryWithObjectsForKeysCount: {
|
|
|
|
IdentifierInfo *KeyIdents[] = {
|
|
|
|
&Ctx.Idents.get("dictionaryWithObjects"),
|
|
|
|
&Ctx.Idents.get("forKeys"),
|
|
|
|
&Ctx.Idents.get("count")
|
|
|
|
};
|
|
|
|
Sel = Ctx.Selectors.getSelector(3, KeyIdents);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NSDict_dictionaryWithObjectsAndKeys:
|
|
|
|
Sel = Ctx.Selectors.getUnarySelector(
|
|
|
|
&Ctx.Idents.get("dictionaryWithObjectsAndKeys"));
|
|
|
|
break;
|
|
|
|
case NSDict_initWithDictionary:
|
|
|
|
Sel = Ctx.Selectors.getUnarySelector(
|
|
|
|
&Ctx.Idents.get("initWithDictionary"));
|
|
|
|
break;
|
|
|
|
case NSDict_initWithObjectsAndKeys:
|
|
|
|
Sel = Ctx.Selectors.getUnarySelector(
|
|
|
|
&Ctx.Idents.get("initWithObjectsAndKeys"));
|
|
|
|
break;
|
2013-01-16 23:54:48 +00:00
|
|
|
case NSDict_initWithObjectsForKeys: {
|
|
|
|
IdentifierInfo *KeyIdents[] = {
|
|
|
|
&Ctx.Idents.get("initWithObjects"),
|
|
|
|
&Ctx.Idents.get("forKeys")
|
|
|
|
};
|
|
|
|
Sel = Ctx.Selectors.getSelector(2, KeyIdents);
|
|
|
|
break;
|
|
|
|
}
|
2012-12-18 14:30:41 +00:00
|
|
|
case NSDict_objectForKey:
|
|
|
|
Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey"));
|
|
|
|
break;
|
|
|
|
case NSMutableDict_setObjectForKey: {
|
|
|
|
IdentifierInfo *KeyIdents[] = {
|
|
|
|
&Ctx.Idents.get("setObject"),
|
|
|
|
&Ctx.Idents.get("forKey")
|
|
|
|
};
|
|
|
|
Sel = Ctx.Selectors.getSelector(2, KeyIdents);
|
|
|
|
break;
|
|
|
|
}
|
2015-03-04 17:55:52 +00:00
|
|
|
case NSMutableDict_setObjectForKeyedSubscript: {
|
|
|
|
IdentifierInfo *KeyIdents[] = {
|
|
|
|
&Ctx.Idents.get("setObject"),
|
|
|
|
&Ctx.Idents.get("forKeyedSubscript")
|
|
|
|
};
|
|
|
|
Sel = Ctx.Selectors.getSelector(2, KeyIdents);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NSMutableDict_setValueForKey: {
|
|
|
|
IdentifierInfo *KeyIdents[] = {
|
|
|
|
&Ctx.Idents.get("setValue"),
|
|
|
|
&Ctx.Idents.get("forKey")
|
|
|
|
};
|
|
|
|
Sel = Ctx.Selectors.getSelector(2, KeyIdents);
|
|
|
|
break;
|
|
|
|
}
|
2012-12-18 14:30:41 +00:00
|
|
|
}
|
|
|
|
return (NSDictionarySelectors[MK] = Sel);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NSDictionarySelectors[MK];
|
|
|
|
}
|
|
|
|
|
2013-02-20 22:23:23 +00:00
|
|
|
Optional<NSAPI::NSDictionaryMethodKind>
|
2012-12-18 14:30:41 +00:00
|
|
|
NSAPI::getNSDictionaryMethodKind(Selector Sel) {
|
|
|
|
for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) {
|
|
|
|
NSDictionaryMethodKind MK = NSDictionaryMethodKind(i);
|
|
|
|
if (Sel == getNSDictionarySelector(MK))
|
|
|
|
return MK;
|
|
|
|
}
|
|
|
|
|
2022-12-03 11:13:41 -08:00
|
|
|
return std::nullopt;
|
2012-12-18 14:30:41 +00:00
|
|
|
}
|
|
|
|
|
2015-03-04 17:55:52 +00:00
|
|
|
Selector NSAPI::getNSSetSelector(NSSetMethodKind MK) const {
|
|
|
|
if (NSSetSelectors[MK].isNull()) {
|
|
|
|
Selector Sel;
|
|
|
|
switch (MK) {
|
|
|
|
case NSMutableSet_addObject:
|
|
|
|
Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
|
|
|
|
break;
|
|
|
|
case NSOrderedSet_insertObjectAtIndex: {
|
|
|
|
IdentifierInfo *KeyIdents[] = {
|
|
|
|
&Ctx.Idents.get("insertObject"),
|
|
|
|
&Ctx.Idents.get("atIndex")
|
|
|
|
};
|
|
|
|
Sel = Ctx.Selectors.getSelector(2, KeyIdents);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NSOrderedSet_setObjectAtIndex: {
|
|
|
|
IdentifierInfo *KeyIdents[] = {
|
|
|
|
&Ctx.Idents.get("setObject"),
|
|
|
|
&Ctx.Idents.get("atIndex")
|
|
|
|
};
|
|
|
|
Sel = Ctx.Selectors.getSelector(2, KeyIdents);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NSOrderedSet_setObjectAtIndexedSubscript: {
|
|
|
|
IdentifierInfo *KeyIdents[] = {
|
|
|
|
&Ctx.Idents.get("setObject"),
|
|
|
|
&Ctx.Idents.get("atIndexedSubscript")
|
|
|
|
};
|
|
|
|
Sel = Ctx.Selectors.getSelector(2, KeyIdents);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NSOrderedSet_replaceObjectAtIndexWithObject: {
|
|
|
|
IdentifierInfo *KeyIdents[] = {
|
|
|
|
&Ctx.Idents.get("replaceObjectAtIndex"),
|
|
|
|
&Ctx.Idents.get("withObject")
|
|
|
|
};
|
|
|
|
Sel = Ctx.Selectors.getSelector(2, KeyIdents);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return (NSSetSelectors[MK] = Sel);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NSSetSelectors[MK];
|
|
|
|
}
|
|
|
|
|
|
|
|
Optional<NSAPI::NSSetMethodKind>
|
|
|
|
NSAPI::getNSSetMethodKind(Selector Sel) {
|
|
|
|
for (unsigned i = 0; i != NumNSSetMethods; ++i) {
|
|
|
|
NSSetMethodKind MK = NSSetMethodKind(i);
|
|
|
|
if (Sel == getNSSetSelector(MK))
|
|
|
|
return MK;
|
|
|
|
}
|
|
|
|
|
2022-12-03 11:13:41 -08:00
|
|
|
return std::nullopt;
|
2015-03-04 17:55:52 +00:00
|
|
|
}
|
|
|
|
|
2012-12-18 14:30:41 +00:00
|
|
|
Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
|
|
|
|
bool Instance) const {
|
|
|
|
static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {
|
|
|
|
"numberWithChar",
|
|
|
|
"numberWithUnsignedChar",
|
|
|
|
"numberWithShort",
|
|
|
|
"numberWithUnsignedShort",
|
|
|
|
"numberWithInt",
|
|
|
|
"numberWithUnsignedInt",
|
|
|
|
"numberWithLong",
|
|
|
|
"numberWithUnsignedLong",
|
|
|
|
"numberWithLongLong",
|
|
|
|
"numberWithUnsignedLongLong",
|
|
|
|
"numberWithFloat",
|
|
|
|
"numberWithDouble",
|
|
|
|
"numberWithBool",
|
|
|
|
"numberWithInteger",
|
|
|
|
"numberWithUnsignedInteger"
|
|
|
|
};
|
|
|
|
static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {
|
|
|
|
"initWithChar",
|
|
|
|
"initWithUnsignedChar",
|
|
|
|
"initWithShort",
|
|
|
|
"initWithUnsignedShort",
|
|
|
|
"initWithInt",
|
|
|
|
"initWithUnsignedInt",
|
|
|
|
"initWithLong",
|
|
|
|
"initWithUnsignedLong",
|
|
|
|
"initWithLongLong",
|
|
|
|
"initWithUnsignedLongLong",
|
|
|
|
"initWithFloat",
|
|
|
|
"initWithDouble",
|
|
|
|
"initWithBool",
|
|
|
|
"initWithInteger",
|
|
|
|
"initWithUnsignedInteger"
|
|
|
|
};
|
|
|
|
|
|
|
|
Selector *Sels;
|
|
|
|
const char **Names;
|
|
|
|
if (Instance) {
|
|
|
|
Sels = NSNumberInstanceSelectors;
|
|
|
|
Names = InstanceSelectorName;
|
|
|
|
} else {
|
|
|
|
Sels = NSNumberClassSelectors;
|
|
|
|
Names = ClassSelectorName;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Sels[MK].isNull())
|
|
|
|
Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK]));
|
|
|
|
return Sels[MK];
|
|
|
|
}
|
|
|
|
|
2013-02-20 22:23:23 +00:00
|
|
|
Optional<NSAPI::NSNumberLiteralMethodKind>
|
2012-12-18 14:30:41 +00:00
|
|
|
NSAPI::getNSNumberLiteralMethodKind(Selector Sel) const {
|
|
|
|
for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) {
|
|
|
|
NSNumberLiteralMethodKind MK = NSNumberLiteralMethodKind(i);
|
|
|
|
if (isNSNumberLiteralSelector(MK, Sel))
|
|
|
|
return MK;
|
|
|
|
}
|
|
|
|
|
2022-12-03 11:13:41 -08:00
|
|
|
return std::nullopt;
|
2012-12-18 14:30:41 +00:00
|
|
|
}
|
|
|
|
|
2013-02-20 22:23:23 +00:00
|
|
|
Optional<NSAPI::NSNumberLiteralMethodKind>
|
2012-12-18 14:30:41 +00:00
|
|
|
NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
|
|
|
|
const BuiltinType *BT = T->getAs<BuiltinType>();
|
|
|
|
if (!BT)
|
2022-12-03 11:13:41 -08:00
|
|
|
return std::nullopt;
|
2012-12-18 14:30:41 +00:00
|
|
|
|
|
|
|
const TypedefType *TDT = T->getAs<TypedefType>();
|
|
|
|
if (TDT) {
|
|
|
|
QualType TDTTy = QualType(TDT, 0);
|
|
|
|
if (isObjCBOOLType(TDTTy))
|
|
|
|
return NSAPI::NSNumberWithBool;
|
|
|
|
if (isObjCNSIntegerType(TDTTy))
|
|
|
|
return NSAPI::NSNumberWithInteger;
|
|
|
|
if (isObjCNSUIntegerType(TDTTy))
|
|
|
|
return NSAPI::NSNumberWithUnsignedInteger;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (BT->getKind()) {
|
|
|
|
case BuiltinType::Char_S:
|
|
|
|
case BuiltinType::SChar:
|
|
|
|
return NSAPI::NSNumberWithChar;
|
|
|
|
case BuiltinType::Char_U:
|
|
|
|
case BuiltinType::UChar:
|
|
|
|
return NSAPI::NSNumberWithUnsignedChar;
|
|
|
|
case BuiltinType::Short:
|
|
|
|
return NSAPI::NSNumberWithShort;
|
|
|
|
case BuiltinType::UShort:
|
|
|
|
return NSAPI::NSNumberWithUnsignedShort;
|
|
|
|
case BuiltinType::Int:
|
|
|
|
return NSAPI::NSNumberWithInt;
|
|
|
|
case BuiltinType::UInt:
|
|
|
|
return NSAPI::NSNumberWithUnsignedInt;
|
|
|
|
case BuiltinType::Long:
|
|
|
|
return NSAPI::NSNumberWithLong;
|
|
|
|
case BuiltinType::ULong:
|
|
|
|
return NSAPI::NSNumberWithUnsignedLong;
|
|
|
|
case BuiltinType::LongLong:
|
|
|
|
return NSAPI::NSNumberWithLongLong;
|
|
|
|
case BuiltinType::ULongLong:
|
|
|
|
return NSAPI::NSNumberWithUnsignedLongLong;
|
|
|
|
case BuiltinType::Float:
|
|
|
|
return NSAPI::NSNumberWithFloat;
|
|
|
|
case BuiltinType::Double:
|
|
|
|
return NSAPI::NSNumberWithDouble;
|
|
|
|
case BuiltinType::Bool:
|
|
|
|
return NSAPI::NSNumberWithBool;
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2012-12-18 14:30:41 +00:00
|
|
|
case BuiltinType::Void:
|
|
|
|
case BuiltinType::WChar_U:
|
|
|
|
case BuiltinType::WChar_S:
|
2018-05-01 05:02:45 +00:00
|
|
|
case BuiltinType::Char8:
|
2012-12-18 14:30:41 +00:00
|
|
|
case BuiltinType::Char16:
|
|
|
|
case BuiltinType::Char32:
|
|
|
|
case BuiltinType::Int128:
|
|
|
|
case BuiltinType::LongDouble:
|
2018-06-04 16:07:52 +00:00
|
|
|
case BuiltinType::ShortAccum:
|
|
|
|
case BuiltinType::Accum:
|
|
|
|
case BuiltinType::LongAccum:
|
|
|
|
case BuiltinType::UShortAccum:
|
|
|
|
case BuiltinType::UAccum:
|
|
|
|
case BuiltinType::ULongAccum:
|
2018-06-14 14:53:51 +00:00
|
|
|
case BuiltinType::ShortFract:
|
|
|
|
case BuiltinType::Fract:
|
|
|
|
case BuiltinType::LongFract:
|
|
|
|
case BuiltinType::UShortFract:
|
|
|
|
case BuiltinType::UFract:
|
|
|
|
case BuiltinType::ULongFract:
|
|
|
|
case BuiltinType::SatShortAccum:
|
|
|
|
case BuiltinType::SatAccum:
|
|
|
|
case BuiltinType::SatLongAccum:
|
|
|
|
case BuiltinType::SatUShortAccum:
|
|
|
|
case BuiltinType::SatUAccum:
|
|
|
|
case BuiltinType::SatULongAccum:
|
|
|
|
case BuiltinType::SatShortFract:
|
|
|
|
case BuiltinType::SatFract:
|
|
|
|
case BuiltinType::SatLongFract:
|
|
|
|
case BuiltinType::SatUShortFract:
|
|
|
|
case BuiltinType::SatUFract:
|
|
|
|
case BuiltinType::SatULongFract:
|
2012-12-18 14:30:41 +00:00
|
|
|
case BuiltinType::UInt128:
|
2017-09-08 15:15:00 +00:00
|
|
|
case BuiltinType::Float16:
|
2016-05-09 08:52:33 +00:00
|
|
|
case BuiltinType::Float128:
|
2021-09-06 17:49:23 +08:00
|
|
|
case BuiltinType::Ibm128:
|
2012-12-18 14:30:41 +00:00
|
|
|
case BuiltinType::NullPtr:
|
|
|
|
case BuiltinType::ObjCClass:
|
|
|
|
case BuiltinType::ObjCId:
|
|
|
|
case BuiltinType::ObjCSel:
|
2016-04-08 13:40:33 +00:00
|
|
|
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
|
|
|
|
case BuiltinType::Id:
|
2016-04-13 08:33:41 +00:00
|
|
|
#include "clang/Basic/OpenCLImageTypes.def"
|
2018-11-08 11:25:41 +00:00
|
|
|
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
|
|
|
|
case BuiltinType::Id:
|
|
|
|
#include "clang/Basic/OpenCLExtensionTypes.def"
|
2013-02-07 10:55:47 +00:00
|
|
|
case BuiltinType::OCLSampler:
|
2013-01-20 12:31:11 +00:00
|
|
|
case BuiltinType::OCLEvent:
|
2015-09-15 11:18:52 +00:00
|
|
|
case BuiltinType::OCLClkEvent:
|
|
|
|
case BuiltinType::OCLQueue:
|
|
|
|
case BuiltinType::OCLReserveID:
|
2019-08-09 08:52:54 +00:00
|
|
|
#define SVE_TYPE(Name, Id, SingletonId) \
|
|
|
|
case BuiltinType::Id:
|
|
|
|
#include "clang/Basic/AArch64SVEACLETypes.def"
|
2020-12-15 15:08:09 -06:00
|
|
|
#define PPC_VECTOR_TYPE(Name, Id, Size) \
|
2020-10-28 13:14:48 -05:00
|
|
|
case BuiltinType::Id:
|
|
|
|
#include "clang/Basic/PPCTypes.def"
|
2021-02-04 12:57:36 +08:00
|
|
|
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
|
|
|
|
#include "clang/Basic/RISCVVTypes.def"
|
2012-12-18 14:30:41 +00:00
|
|
|
case BuiltinType::BoundMember:
|
|
|
|
case BuiltinType::Dependent:
|
|
|
|
case BuiltinType::Overload:
|
|
|
|
case BuiltinType::UnknownAny:
|
|
|
|
case BuiltinType::ARCUnbridgedCast:
|
|
|
|
case BuiltinType::Half:
|
|
|
|
case BuiltinType::PseudoObject:
|
|
|
|
case BuiltinType::BuiltinFn:
|
[Matrix] Implement matrix index expressions ([][]).
This patch implements matrix index expressions
(matrix[RowIdx][ColumnIdx]).
It does so by introducing a new MatrixSubscriptExpr(Base, RowIdx, ColumnIdx).
MatrixSubscriptExprs are built in 2 steps in ActOnMatrixSubscriptExpr. First,
if the base of a subscript is of matrix type, we create a incomplete
MatrixSubscriptExpr(base, idx, nullptr). Second, if the base is an incomplete
MatrixSubscriptExpr, we create a complete
MatrixSubscriptExpr(base->getBase(), base->getRowIdx(), idx)
Similar to vector elements, it is not possible to take the address of
a MatrixSubscriptExpr.
For CodeGen, a new MatrixElt type is added to LValue, which is very
similar to VectorElt. The only difference is that we may need to cast
the type of the base from an array to a vector type when accessing it.
Reviewers: rjmccall, anemet, Bigcheese, rsmith, martong
Reviewed By: rjmccall
Differential Revision: https://reviews.llvm.org/D76791
2020-06-01 19:42:03 +01:00
|
|
|
case BuiltinType::IncompleteMatrixIdx:
|
2015-08-25 14:24:04 +00:00
|
|
|
case BuiltinType::OMPArraySection:
|
[OPENMP50]Add basic support for array-shaping operation.
Summary:
Added basic representation and parsing/sema handling of array-shaping
operations. Array shaping expression is an expression of form ([s0]..[sn])base,
where s0, ..., sn must be a positive integer, base - a pointer. This
expression is a kind of cast operation that converts pointer expression
into an array-like kind of expression.
Reviewers: rjmccall, rsmith, jdoerfert
Subscribers: guansong, arphaman, cfe-commits, caomhin, kkwli0
Tags: #clang
Differential Revision: https://reviews.llvm.org/D74144
2020-02-05 09:33:05 -05:00
|
|
|
case BuiltinType::OMPArrayShaping:
|
2020-04-01 15:06:38 -04:00
|
|
|
case BuiltinType::OMPIterator:
|
[ARM] Add __bf16 as new Bfloat16 C Type
Summary:
This patch upstreams support for a new storage only bfloat16 C type.
This type is used to implement primitive support for bfloat16 data, in
line with the Bfloat16 extension of the Armv8.6-a architecture, as
detailed here:
https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/arm-architecture-developments-armv8-6-a
The bfloat type, and its properties are specified in the Arm Architecture
Reference Manual:
https://developer.arm.com/docs/ddi0487/latest/arm-architecture-reference-manual-armv8-for-armv8-a-architecture-profile
In detail this patch:
- introduces an opaque, storage-only C-type __bf16, which introduces a new bfloat IR type.
This is part of a patch series, starting with command-line and Bfloat16
assembly support. The subsequent patches will upstream intrinsics
support for BFloat16, followed by Matrix Multiplication and the
remaining Virtualization features of the armv8.6-a architecture.
The following people contributed to this patch:
- Luke Cheeseman
- Momchil Velikov
- Alexandros Lamprineas
- Luke Geeson
- Simon Tatham
- Ties Stuij
Reviewers: SjoerdMeijer, rjmccall, rsmith, liutianle, RKSimon, craig.topper, jfb, LukeGeeson, fpetrogalli
Reviewed By: SjoerdMeijer
Subscribers: labrinea, majnemer, asmith, dexonsmith, kristof.beyls, arphaman, danielkiss, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D76077
2020-06-05 00:20:02 +01:00
|
|
|
case BuiltinType::BFloat16:
|
2012-12-18 14:30:41 +00:00
|
|
|
break;
|
|
|
|
}
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2022-12-03 11:13:41 -08:00
|
|
|
return std::nullopt;
|
2012-12-18 14:30:41 +00:00
|
|
|
}
|
|
|
|
|
2018-05-09 01:00:01 +00:00
|
|
|
/// Returns true if \param T is a typedef of "BOOL" in objective-c.
|
2012-12-18 14:30:41 +00:00
|
|
|
bool NSAPI::isObjCBOOLType(QualType T) const {
|
|
|
|
return isObjCTypedef(T, "BOOL", BOOLId);
|
|
|
|
}
|
2018-05-09 01:00:01 +00:00
|
|
|
/// Returns true if \param T is a typedef of "NSInteger" in objective-c.
|
2012-12-18 14:30:41 +00:00
|
|
|
bool NSAPI::isObjCNSIntegerType(QualType T) const {
|
|
|
|
return isObjCTypedef(T, "NSInteger", NSIntegerId);
|
|
|
|
}
|
2018-05-09 01:00:01 +00:00
|
|
|
/// Returns true if \param T is a typedef of "NSUInteger" in objective-c.
|
2012-12-18 14:30:41 +00:00
|
|
|
bool NSAPI::isObjCNSUIntegerType(QualType T) const {
|
|
|
|
return isObjCTypedef(T, "NSUInteger", NSUIntegerId);
|
|
|
|
}
|
|
|
|
|
2014-10-06 23:50:37 +00:00
|
|
|
StringRef NSAPI::GetNSIntegralKind(QualType T) const {
|
2018-10-30 20:31:30 +00:00
|
|
|
if (!Ctx.getLangOpts().ObjC || T.isNull())
|
2014-10-06 23:50:37 +00:00
|
|
|
return StringRef();
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2014-10-06 23:50:37 +00:00
|
|
|
while (const TypedefType *TDT = T->getAs<TypedefType>()) {
|
|
|
|
StringRef NSIntegralResust =
|
|
|
|
llvm::StringSwitch<StringRef>(
|
|
|
|
TDT->getDecl()->getDeclName().getAsIdentifierInfo()->getName())
|
|
|
|
.Case("int8_t", "int8_t")
|
|
|
|
.Case("int16_t", "int16_t")
|
|
|
|
.Case("int32_t", "int32_t")
|
|
|
|
.Case("NSInteger", "NSInteger")
|
|
|
|
.Case("int64_t", "int64_t")
|
|
|
|
.Case("uint8_t", "uint8_t")
|
|
|
|
.Case("uint16_t", "uint16_t")
|
|
|
|
.Case("uint32_t", "uint32_t")
|
|
|
|
.Case("NSUInteger", "NSUInteger")
|
|
|
|
.Case("uint64_t", "uint64_t")
|
|
|
|
.Default(StringRef());
|
|
|
|
if (!NSIntegralResust.empty())
|
|
|
|
return NSIntegralResust;
|
|
|
|
T = TDT->desugar();
|
|
|
|
}
|
|
|
|
return StringRef();
|
|
|
|
}
|
|
|
|
|
2015-04-29 23:20:19 +00:00
|
|
|
bool NSAPI::isMacroDefined(StringRef Id) const {
|
|
|
|
// FIXME: Check whether the relevant module macros are visible.
|
|
|
|
return Ctx.Idents.get(Id).hasMacroDefinition();
|
|
|
|
}
|
|
|
|
|
2015-08-06 04:51:14 +00:00
|
|
|
bool NSAPI::isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl,
|
|
|
|
NSClassIdKindKind NSClassKind) const {
|
|
|
|
if (!InterfaceDecl) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
IdentifierInfo *NSClassID = getNSClassId(NSClassKind);
|
|
|
|
|
|
|
|
bool IsSubclass = false;
|
|
|
|
do {
|
|
|
|
IsSubclass = NSClassID == InterfaceDecl->getIdentifier();
|
|
|
|
|
|
|
|
if (IsSubclass) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while ((InterfaceDecl = InterfaceDecl->getSuperClass()));
|
|
|
|
|
|
|
|
return IsSubclass;
|
|
|
|
}
|
|
|
|
|
2012-12-18 14:30:41 +00:00
|
|
|
bool NSAPI::isObjCTypedef(QualType T,
|
|
|
|
StringRef name, IdentifierInfo *&II) const {
|
2018-10-30 20:31:30 +00:00
|
|
|
if (!Ctx.getLangOpts().ObjC)
|
2012-12-18 14:30:41 +00:00
|
|
|
return false;
|
|
|
|
if (T.isNull())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!II)
|
|
|
|
II = &Ctx.Idents.get(name);
|
|
|
|
|
|
|
|
while (const TypedefType *TDT = T->getAs<TypedefType>()) {
|
|
|
|
if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
|
|
|
|
return true;
|
|
|
|
T = TDT->desugar();
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool NSAPI::isObjCEnumerator(const Expr *E,
|
|
|
|
StringRef name, IdentifierInfo *&II) const {
|
2018-10-30 20:31:30 +00:00
|
|
|
if (!Ctx.getLangOpts().ObjC)
|
2012-12-18 14:30:41 +00:00
|
|
|
return false;
|
|
|
|
if (!E)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!II)
|
|
|
|
II = &Ctx.Idents.get(name);
|
|
|
|
|
|
|
|
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
|
|
|
|
if (const EnumConstantDecl *
|
|
|
|
EnumD = dyn_cast_or_null<EnumConstantDecl>(DRE->getDecl()))
|
|
|
|
return EnumD->getIdentifier() == II;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
Selector NSAPI::getOrInitSelector(ArrayRef<StringRef> Ids,
|
|
|
|
Selector &Sel) const {
|
|
|
|
if (Sel.isNull()) {
|
|
|
|
SmallVector<IdentifierInfo *, 4> Idents;
|
|
|
|
for (ArrayRef<StringRef>::const_iterator
|
|
|
|
I = Ids.begin(), E = Ids.end(); I != E; ++I)
|
|
|
|
Idents.push_back(&Ctx.Idents.get(*I));
|
|
|
|
Sel = Ctx.Selectors.getSelector(Idents.size(), Idents.data());
|
|
|
|
}
|
|
|
|
return Sel;
|
|
|
|
}
|
2018-09-10 22:20:09 +00:00
|
|
|
|
|
|
|
Selector NSAPI::getOrInitNullarySelector(StringRef Id, Selector &Sel) const {
|
|
|
|
if (Sel.isNull()) {
|
|
|
|
IdentifierInfo *Ident = &Ctx.Idents.get(Id);
|
|
|
|
Sel = Ctx.Selectors.getSelector(0, &Ident);
|
|
|
|
}
|
|
|
|
return Sel;
|
|
|
|
}
|