30#include "llvm/Support/ConvertUTF.h"
48 if (Strings.size() != 1) {
53 for (
Expr *E : Strings) {
73 assert(CAT &&
"String literal not of constant array type!");
74 QualType StrTy = Context.getConstantArrayType(
75 CAT->
getElementType(), llvm::APInt(32, StrBuf.size() + 1),
nullptr,
78 false, StrTy, StrLocs);
95 QualType Ty = Context.getObjCConstantStringInterface();
97 Ty = Context.getObjCObjectPointerType(Ty);
100 std::string StringClass(
getLangOpts().ObjCConstantStringClass);
102 if (StringClass.empty())
103 NSIdent = &Context.Idents.get(
"NSConstantString");
105 NSIdent = &Context.Idents.get(StringClass);
110 Context.setObjCConstantStringInterface(StrIF);
111 Ty = Context.getObjCConstantStringInterface();
112 Ty = Context.getObjCObjectPointerType(Ty);
118 Ty = Context.getObjCIdType();
125 Context.setObjCConstantStringInterface(StrIF);
126 Ty = Context.getObjCConstantStringInterface();
127 Ty = Context.getObjCObjectPointerType(Ty);
133 Ty = Context.getObjCNSStringType();
137 Context.getTranslationUnitDecl(),
140 Ty = Context.getObjCInterfaceType(NSStringIDecl);
141 Context.setObjCNSStringType(Ty);
143 Ty = Context.getObjCObjectPointerType(Ty);
157 S.
Diag(Loc, diag::err_undeclared_boxing_method) << Sel << Class->getName();
162 QualType ReturnType = Method->getReturnType();
164 S.
Diag(Loc, diag::err_objc_literal_method_sig)
166 S.
Diag(Method->getLocation(), diag::note_objc_literal_method_return)
177 switch (LiteralKind) {
195 llvm_unreachable(
"LiteralKind can't be converted into a ClassKind");
208 S.
Diag(Loc, diag::err_undeclared_objc_literal_class)
209 << II->
getName() << LiteralKind;
211 }
else if (!
Decl->hasDefinition() && !S.
getLangOpts().DebuggerObjCLiteral) {
212 S.
Diag(Loc, diag::err_undeclared_objc_literal_class)
213 <<
Decl->getName() << LiteralKind;
250 bool isLiteral =
false,
252 std::optional<NSAPI::NSNumberLiteralMethodKind> Kind =
253 S.
NSAPIObj->getNSNumberFactoryMethodKind(NumberType);
257 S.
Diag(Loc, diag::err_invalid_nsnumber_type)
290 if (!Method && S.
getLangOpts().DebuggerObjCLiteral) {
305 NumberType,
nullptr,
SC_None,
nullptr);
322 if (!LangOpts.ObjCConstantLiterals)
325 const QualType Ty = Number->IgnoreParens()->getType();
328 if (Number->isValueDependent())
331 if (!Number->isEvaluatable(Context))
342 "The current ABI doesn't support the constant CFBooleanTrue "
344 const bool IsBoolType =
351 if (!LangOpts.ConstantNSNumberLiterals)
357 if (Number->EvaluateAsInt(IntResult, Context))
362 APFloat FloatValue(0.0);
363 if (Number->EvaluateAsFloat(FloatValue, Context)) {
366 if (&FloatValue.getSemantics() == &APFloat::IEEEsingle())
368 if (&FloatValue.getSemantics() == &APFloat::IEEEdouble())
372 "NSNumber only supports `float` or `double` floating-point types.");
384 QualType NumberType = Number->getType();
388 switch (Char->getKind()) {
391 NumberType = Context.CharTy;
395 NumberType = Context.getWideCharType();
399 NumberType = Context.Char16Ty;
403 NumberType = Context.Char32Ty;
424 Number = ConvertedNumber.
get();
426 const bool IsConstInitLiteral =
429 auto *NumberLiteral =
new (Context)
434 return SemaRef.MaybeBindToTemporary(NumberLiteral);
442 Inner =
SemaRef.ActOnCXXBoolLiteral(ValueLoc,
443 Value ? tok::kw_true : tok::kw_false);
447 Inner =
SemaRef.ActOnIntegerConstant(ValueLoc,
Value ? 1 : 0);
448 Inner =
SemaRef.ImpCastExprToType(Inner.
get(), Context.BoolTy,
449 CK_IntegralToBoolean);
459 bool ArrayLiteral =
false) {
465 if (Result.isInvalid())
467 Element = Result.get();
479 return Seq.Perform(S, Entity, Kind, Element);
482 Expr *OrigElement = Element;
486 if (Result.isInvalid())
488 Element = Result.get();
493 bool Recovered =
false;
514 if (Result.isInvalid())
517 Element = Result.get();
522 else if (
StringLiteral *String = dyn_cast<StringLiteral>(OrigElement)) {
523 if (String->isOrdinary()) {
530 if (Result.isInvalid())
533 Element = Result.get();
546 dyn_cast<ObjCStringLiteral>(OrigElement)) {
548 unsigned numConcat = SL->getNumConcatenated();
551 bool hasMacro =
false;
552 for (
unsigned i = 0; i < numConcat ; ++i)
553 if (SL->getStrTokenLoc(i).isMacroID()) {
559 diag::warn_concatenated_nsarray_literal)
590 const bool IsConstInitLiteral =
593 ValueExpr = RValue.
get();
597 if (Context.hasSameUnqualifiedType(PointeeType, Context.CharTy)) {
611 if (
auto *CE = dyn_cast<ImplicitCastExpr>(ValueExpr))
612 if (CE->getCastKind() == CK_ArrayToPointerDecay)
614 dyn_cast<StringLiteral>(CE->getSubExpr()->IgnoreParens())) {
615 assert((SL->isOrdinary() || SL->isUTF8()) &&
616 "unexpected character encoding");
617 StringRef Str = SL->getString();
618 const llvm::UTF8 *StrBegin = Str.bytes_begin();
619 const llvm::UTF8 *StrEnd = Str.bytes_end();
621 if (llvm::isLegalUTF8String(&StrBegin, StrEnd)) {
628 Diag(SL->getBeginLoc(), diag::warn_objc_boxing_invalid_utf8_string)
634 Selector stringWithUTF8String = Context.Selectors.getUnarySelector(II);
637 BoxingMethod =
NSStringDecl->lookupClassMethod(stringWithUTF8String);
638 if (!BoxingMethod &&
getLangOpts().DebuggerObjCLiteral) {
654 &Context.Idents.get(
"value"),
655 Context.getPointerType(ConstCharType),
663 stringWithUTF8String, BoxingMethod))
676 Context.getAttributedType(*Nullability, BoxedType, BoxedType);
678 }
else if (ValueType->isBuiltinType()) {
686 dyn_cast<CharacterLiteral>(ValueExpr->
IgnoreParens())) {
689 switch (Char->getKind()) {
692 ValueType = Context.CharTy;
696 ValueType = Context.getWideCharType();
700 ValueType = Context.Char16Ty;
704 ValueType = Context.Char32Ty;
711 }
else if (
const auto *ED = ValueType->getAsEnumDecl()) {
712 if (!ED->isComplete()) {
713 Diag(Loc, diag::err_objc_incomplete_boxed_expression_type)
720 }
else if (ValueType->isObjCBoxableRecordType()) {
738 const IdentifierInfo *II[] = {&Context.Idents.get(
"valueWithBytes"),
739 &Context.Idents.get(
"objCType")};
740 Selector ValueWithBytesObjCType = Context.Selectors.getSelector(2, II);
743 BoxingMethod =
NSValueDecl->lookupClassMethod(ValueWithBytesObjCType);
744 if (!BoxingMethod &&
getLangOpts().DebuggerObjCLiteral) {
763 &Context.Idents.get(
"bytes"),
764 Context.VoidPtrTy.withConst(),
767 Params.push_back(
bytes);
773 &Context.Idents.get(
"type"),
774 Context.getPointerType(ConstCharType),
777 Params.push_back(
type);
784 ValueWithBytesObjCType, BoxingMethod))
790 if (!ValueType.isTriviallyCopyableType(Context)) {
791 Diag(Loc, diag::err_objc_non_trivially_copyable_boxed_expression_type)
801 Diag(Loc, diag::err_objc_illegal_boxed_expression_type)
806 SemaRef.DiagnoseUseOfDecl(BoxingMethod, Loc);
809 if (ValueType->isObjCBoxableRecordType()) {
811 ConvertedValueExpr =
SemaRef.PerformCopyInitialization(
816 ValueExpr = ConvertedValueExpr.
get();
817 }
else if (BoxingMethod->
parameters().size() > 0) {
827 ValueExpr = ConvertedValueExpr.
get();
831 ObjCBoxedExpr(ValueExpr, BoxedType, BoxingMethod, IsConstInitLiteral, SR);
833 return SemaRef.MaybeBindToTemporary(BoxedExpr);
841 assert(!
getLangOpts().isSubscriptPointerArithmetic());
847 "base or index cannot have dependent type here");
865 getterMethod, setterMethod, RB);
882 QualType IdT = Context.getObjCIdType();
891 Context.getTranslationUnitDecl(),
false ,
900 &Context.Idents.get(
"objects"),
901 Context.getPointerType(IdT),
904 Params.push_back(objects);
908 &Context.Idents.get(
"cnt"),
909 Context.UnsignedLongTy,
912 Params.push_back(cnt);
913 Method->setMethodParams(Context, Params, {});
927 diag::note_objc_literal_method_param)
929 << Context.getPointerType(IdT.
withConst());
934 if (!
Method->parameters()[1]->getType()->isIntegerType()) {
938 diag::note_objc_literal_method_param)
940 <<
Method->parameters()[1]->getType()
954 bool ExpressibleAsConstantInitLiteral = LangOpts.ConstantNSArrayLiterals;
957 if (ExpressibleAsConstantInitLiteral &&
958 llvm::any_of(Elements,
960 ExpressibleAsConstantInitLiteral =
false;
963 if (LangOpts.ObjCConstantLiterals && Elements.size() == 0) {
965 "The current ABI doesn't support an empty constant NSArray "
967 ExpressibleAsConstantInitLiteral =
true;
972 Expr **ElementsBuffer = Elements.data();
973 for (
unsigned I = 0, N = Elements.size(); I != N; ++I) {
975 SemaRef, ElementsBuffer[I], RequiredType,
true);
979 ElementsBuffer[I] = Converted.
get();
983 if (ExpressibleAsConstantInitLiteral &&
985 !ElementsBuffer[I]->isConstantInitializer(Context)))
986 ExpressibleAsConstantInitLiteral =
false;
990 = Context.getObjCObjectPointerType(
995 ExpressibleAsConstantInitLiteral, SR);
997 return SemaRef.MaybeBindToTemporary(ArrayLiteral);
1005 if (Literal->isValueDependent() || Literal->isTypeDependent())
1011 struct APSIntCompare {
1012 bool operator()(
const llvm::APSInt &LHS,
const llvm::APSInt &RHS)
const {
1013 return llvm::APSInt::compareValues(LHS, RHS) < 0;
1017 llvm::DenseMap<StringRef, SourceLocation> StringKeys;
1018 std::map<llvm::APSInt, SourceLocation, APSIntCompare> IntegralKeys;
1020 auto checkOneKey = [&](
auto &Map,
const auto &Key,
SourceLocation Loc) {
1021 auto Pair = Map.insert({Key, Loc});
1023 S.
Diag(Loc, diag::warn_nsdictionary_duplicate_key);
1024 S.
Diag(Pair.first->second, diag::note_nsdictionary_duplicate_key_here);
1028 for (
unsigned Idx = 0, End = Literal->getNumElements(); Idx != End; ++Idx) {
1029 Expr *Key = Literal->getKeyValueElement(Idx).Key->IgnoreParenImpCasts();
1031 if (
auto *StrLit = dyn_cast<ObjCStringLiteral>(Key)) {
1032 StringRef Bytes = StrLit->getString()->getBytes();
1034 checkOneKey(StringKeys, Bytes, Loc);
1037 if (
auto *BE = dyn_cast<ObjCBoxedExpr>(Key)) {
1038 Expr *Boxed = BE->getSubExpr();
1043 checkOneKey(StringKeys, Str->getBytes(), Loc);
1050 checkOneKey(IntegralKeys, Result.Val.getInt(), Loc);
1071 QualType IdT = Context.getObjCIdType();
1079 nullptr , Context.getTranslationUnitDecl(),
1089 &Context.Idents.get(
"objects"),
1090 Context.getPointerType(IdT),
1093 Params.push_back(objects);
1097 &Context.Idents.get(
"keys"),
1098 Context.getPointerType(IdT),
1101 Params.push_back(keys);
1105 &Context.Idents.get(
"cnt"),
1106 Context.UnsignedLongTy,
1109 Params.push_back(cnt);
1110 Method->setMethodParams(Context, Params, {});
1121 !Context.hasSameUnqualifiedType(PtrValue->
getPointeeType(), IdT)) {
1125 diag::note_objc_literal_method_param)
1127 << Context.getPointerType(IdT.
withConst());
1145 Context.ObjCBuiltinIdTy, {},
1159 diag::note_objc_literal_method_param)
1161 << Context.getPointerType(IdT.
withConst());
1172 diag::note_objc_literal_method_param)
1189 bool HasPackExpansions =
false;
1193 bool ExpressibleAsConstantInitLiteral = LangOpts.ConstantNSDictionaryLiterals;
1198 if (!ExpressibleAsConstantInitLiteral)
1200 if (Elem.Key->isValueDependent() || Elem.Value->isValueDependent())
1201 ExpressibleAsConstantInitLiteral =
false;
1205 if (LangOpts.ObjCConstantLiterals && Elements.size() == 0) {
1207 "The current ABI doesn't support an empty constant NSDictionary "
1209 ExpressibleAsConstantInitLiteral =
true;
1222 if (
Value.isInvalid())
1225 Element.Key = Key.
get();
1226 Element.Value =
Value.get();
1228 if (ExpressibleAsConstantInitLiteral &&
1229 !Element.Key->isConstantInitializer(Context))
1230 ExpressibleAsConstantInitLiteral =
false;
1233 if (ExpressibleAsConstantInitLiteral &&
1235 ExpressibleAsConstantInitLiteral =
false;
1239 if (ExpressibleAsConstantInitLiteral &&
1241 !Element.Value->isConstantInitializer(Context)))
1242 ExpressibleAsConstantInitLiteral =
false;
1244 if (Element.EllipsisLoc.isInvalid())
1247 if (!Element.Key->containsUnexpandedParameterPack() &&
1248 !Element.Value->containsUnexpandedParameterPack()) {
1249 Diag(Element.EllipsisLoc,
1250 diag::err_pack_expansion_without_parameter_packs)
1252 Element.Value->getEndLoc());
1256 HasPackExpansions =
true;
1259 QualType Ty = Context.getObjCObjectPointerType(
1264 ExpressibleAsConstantInitLiteral, SR);
1268 return SemaRef.MaybeBindToTemporary(DictionaryLiteral);
1278 StrTy = Context.DependentTy;
1282 if (
SemaRef.RequireCompleteType(AtLoc, EncodedType,
1283 diag::err_incomplete_type_objc_at_encode,
1289 Context.getObjCEncodingForType(EncodedType, Str,
nullptr, &NotEncodedT);
1290 if (!NotEncodedT.
isNull())
1291 Diag(AtLoc, diag::warn_incomplete_encoded_type)
1292 << EncodedType << NotEncodedT;
1296 StrTy = Context.getStringLiteralArrayType(Context.CharTy, Str.size());
1299 return new (Context)
ObjCEncodeExpr(StrTy, EncodedTypeInfo, AtLoc, RParenLoc);
1312 TInfo = Context.getTrivialTypeSourceInfo(
1313 EncodedType,
SemaRef.getLocForEndOfToken(LParenLoc));
1325 bool Warned =
false;
1328 if (MatchingMethodDecl == Method ||
1330 MatchingMethodDecl->
getSelector() != Method->getSelector())
1336 S.
Diag(AtLoc, diag::warn_multiple_selectors)
1339 S.
Diag(Method->getLocation(), diag::note_method_declared_at)
1340 << Method->getDeclName();
1342 S.
Diag(MatchingMethodDecl->
getLocation(), diag::note_method_declared_at)
1353 bool WarnMultipleSelectors) {
1354 if (!WarnMultipleSelectors ||
1357 bool Warned =
false;
1358 for (SemaObjC::GlobalMethodPool::iterator
b = S.
ObjC().
MethodPool.begin(),
1364 Method, InstMethList))
1370 Method, ClsMethList) || Warned)
1386 assert(Method->getSelector() == Sel &&
"Method with wrong selector in method list");
1387 if (Method->isDirectMethod()) {
1389 DirectMethod = Method;
1394 return DirectMethod;
1409 S, Sel, Iter->second.first, onlyDirect, anyDirect);
1411 S, Sel, Iter->second.second, onlyDirect, anyDirect);
1413 return DirectInstance ? DirectInstance : DirectClass;
1442 bool WarnMultipleSelectors) {
1451 Selector MatchedSel = OM->getSelector();
1454 Diag(SelLoc, diag::warn_undeclared_selector_with_typo)
1455 << Sel << MatchedSel
1459 Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
1462 WarnMultipleSelectors);
1464 bool onlyDirect =
true;
1465 bool anyDirect =
false;
1470 Diag(AtLoc, diag::err_direct_selector_expression)
1471 <<
Method->getSelector();
1472 Diag(
Method->getLocation(), diag::note_direct_method_declared_at)
1473 <<
Method->getDeclName();
1474 }
else if (anyDirect) {
1480 if (LikelyTargetMethod && LikelyTargetMethod->
isDirectMethod()) {
1481 Diag(AtLoc, diag::warn_potentially_direct_selector_expression) << Sel;
1483 diag::note_direct_method_declared_at)
1485 }
else if (!LikelyTargetMethod) {
1488 Diag(AtLoc, diag::warn_strict_potentially_direct_selector_expression)
1491 diag::note_direct_method_declared_at)
1498 Method->getImplementationControl() !=
1500 !
SemaRef.getSourceManager().isInSystemHeader(
Method->getLocation()))
1512 Diag(AtLoc, diag::err_arc_illegal_selector) <<
1529 QualType Ty = Context.getObjCSelType();
1542 Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;
1546 Diag(ProtoLoc, diag::err_objc_non_runtime_protocol_in_protocol_expr)
1549 Diag(ProtoLoc, diag::err_atprotocol_protocol) << PDecl;
1555 QualType Ty = Context.getObjCProtoType();
1558 Ty = Context.getObjCObjectPointerType(Ty);
1559 return new (Context)
ObjCProtocolExpr(Ty, PDecl, AtLoc, ProtoIdLoc, RParenLoc);
1580 if (
auto nullability = AttributedType::stripOuterNullability(T)) {
1581 if (T == Context.getObjCInstanceType()) {
1582 return Context.getAttributedType(*nullability, Context.getObjCIdType(),
1583 Context.getObjCIdType());
1589 if (T == Context.getObjCInstanceType())
1590 return Context.getObjCIdType();
1603 bool isClassMessage,
1604 bool isSuperMessage) {
1605 assert(Method &&
"Must have a method");
1606 if (!Method->hasRelatedResultType())
1607 return Method->getSendResultType(ReceiverType);
1615 if (
auto nullability =
1616 Method->getSendResultType(ReceiverType)->getNullability()) {
1618 (void)AttributedType::stripOuterNullability(
type);
1621 return Context.getAttributedType(*nullability,
type,
type);
1631 if (Method->isInstanceMethod() && isClassMessage)
1633 Method->getSendResultType(ReceiverType));
1637 if (isSuperMessage) {
1640 return transferNullability(
1641 Context.getObjCObjectPointerType(
1642 Context.getObjCInterfaceType(Class)));
1648 return transferNullability(Context.getObjCObjectPointerType(ReceiverType));
1654 Method->getSendResultType(ReceiverType));
1659 return transferNullability(ReceiverType);
1665 bool isClassMessage,
1666 bool isSuperMessage) {
1670 SemaRef, ReceiverType,
Method, isClassMessage, isSuperMessage);
1673 if (isClassMessage) {
1682 AttributedType::stripOuterNullability(T);
1683 if (T == Context.getObjCInstanceType()) {
1687 ->getDeclContext());
1689 QualType NewResultType = Context.getObjCObjectPointerType(
1692 NewResultType = Context.getAttributedType(*Nullability, NewResultType,
1694 return NewResultType;
1706 unsigned receiverNullabilityIdx = 0;
1710 receiverNullabilityIdx = 1 +
static_cast<unsigned>(*nullability);
1713 unsigned resultNullabilityIdx = 0;
1717 resultNullabilityIdx = 1 +
static_cast<unsigned>(*nullability);
1722 static const uint8_t
None = 0;
1723 static const uint8_t
NonNull = 1;
1726 static const uint8_t nullabilityMap[4][4] = {
1734 unsigned newResultNullabilityIdx
1735 = nullabilityMap[receiverNullabilityIdx][resultNullabilityIdx];
1736 if (newResultNullabilityIdx == resultNullabilityIdx)
1742 if (
auto attributed = dyn_cast<AttributedType>(resultType.
getTypePtr())) {
1743 resultType = attributed->getModifiedType();
1750 if (newResultNullabilityIdx > 0) {
1753 return Context.getAttributedType(newNullability, resultType, resultType);
1772 dyn_cast<ObjCCategoryImplDecl>(impl)) {
1773 iface = catImpl->getCategoryDecl();
1775 iface = impl->getClassInterface();
1785 for (
unsigned i = 0, e = overrides.size(); i != e; ++i) {
1800 Context.hasSameUnqualifiedType(destType, MD->
getReturnType()))
1807 SourceRange range = overridden->getReturnTypeSourceRange();
1810 loc = overridden->getLocation();
1811 Diag(loc, diag::note_related_result_type_explicit)
1835 if (!
Method->hasRelatedResultType())
1838 if (Context.hasSameUnqualifiedType(
1839 Method->getReturnType().getNonReferenceType(), MsgSend->
getType()))
1842 if (!Context.hasSameUnqualifiedType(
Method->getReturnType(),
1843 Context.getObjCInstanceType()))
1846 Diag(
Method->getLocation(), diag::note_related_result_type_inferred)
1859 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
1860 SelLoc = SelectorLocs.front();
1866 for (
unsigned i = 0, e = Args.size(); i != e; i++) {
1867 if (Args[i]->isTypeDependent())
1873 result =
SemaRef.checkUnknownAnyArg(SelLoc, Args[i], paramTy);
1875 result =
SemaRef.DefaultArgumentPromotion(Args[i]);
1879 Args[i] = result.
get();
1884 DiagID = diag::err_arc_method_not_found;
1886 DiagID = isClassMessage ? diag::warn_class_method_not_found
1887 : diag::warn_inst_method_not_found;
1892 DiagID = diag::err_method_not_found_with_typo;
1894 DiagID = isClassMessage ? diag::warn_class_method_not_found_with_typo
1895 : diag::warn_instance_method_not_found_with_typo;
1897 SourceRange SelectorRange(SelectorLocs.front(), SelectorLocs.back());
1899 Diag(SelLoc, DiagID)
1900 << Sel<< isClassMessage << MatchedSel
1903 Diag(SelLoc, DiagID) << Sel<< isClassMessage << MatchedSel;
1906 Diag(SelLoc, DiagID)
1907 << Sel << isClassMessage <<
SourceRange(SelectorLocs.front(),
1908 SelectorLocs.back());
1912 Diag(ThisClass->getLocation(), diag::note_receiver_class_declared);
1914 if (ThisClass->lookupClassMethod(Sel))
1915 Diag(RecRange.
getBegin(), diag::note_receiver_expr_here)
1917 ThisClass->getNameAsString());
1925 ReturnType = Context.UnknownAnyTy;
1927 ReturnType = Context.getObjCIdType();
1934 isClassMessage, isSuperMessage);
1941 NumNamedArgs =
Method->param_size();
1943 if (Args.size() < NumNamedArgs) {
1944 Diag(SelLoc, diag::err_typecheck_call_too_few_args)
1945 << 2 << NumNamedArgs << static_cast<unsigned>(Args.size())
1952 std::optional<ArrayRef<QualType>> typeArgs =
1954 bool IsError =
false;
1955 for (
unsigned i = 0; i < NumNamedArgs; i++) {
1957 if (Args[i]->isTypeDependent())
1960 Expr *argExpr = Args[i];
1963 assert(argExpr &&
"CheckMessageArgumentTypes(): missing expression");
1965 if (param->
hasAttr<NoEscapeAttr>() &&
1967 if (
auto *BE = dyn_cast<BlockExpr>(
1969 BE->getBlockDecl()->setDoesNotEscape();
1974 !param->
hasAttr<CFConsumedAttr>())
1979 if (param->
getType() == Context.UnknownAnyTy) {
1985 Args[i] = argE.
get();
2001 if (
SemaRef.RequireCompleteType(
2003 diag::err_call_incomplete_argument, argExpr))
2019 Args[i]->getType()->isBlockPointerType() &&
2022 SemaRef.maybeExtendBlockObject(arg);
2023 Args[i] = arg.get();
2029 if (
Method->isVariadic()) {
2030 for (
unsigned i = NumNamedArgs, e = Args.size(); i < e; ++i) {
2031 if (Args[i]->isTypeDependent())
2037 Args[i] = Arg.
get();
2041 if (Args.size() != NumNamedArgs) {
2042 Diag(Args[NumNamedArgs]->getBeginLoc(),
2043 diag::err_typecheck_call_too_many_args)
2044 << 2 << NumNamedArgs << static_cast<unsigned>(Args.size())
2045 <<
Method->getSourceRange() << 0
2047 Args.back()->getEndLoc());
2063 SemaRef.CurContext->getNonClosureAncestor());
2068 if (!method)
return false;
2071 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(receiver))
2083 if (
ObjCMethodDecl *method = iface->lookupMethod(sel, isInstance))
2088 if (
ObjCMethodDecl *method = iface->lookupPrivateMethod(sel, isInstance))
2093 for (
const auto *I : objType->quals())
2105 for (
const auto *PROTO : OPT->
quals()) {
2106 if ((MD = PROTO->lookupMethod(Sel, Instance))) {
2121 assert(IFaceT &&
"Expected an Interface");
2125 Diag(MemberLoc, diag::err_invalid_property_name)
2135 diag::err_property_not_found_forward_class,
2136 MemberName, BaseRange))
2142 if (
SemaRef.DiagnoseUseOfDecl(PD, MemberLoc))
2145 return new (Context)
2149 return new (Context)
2154 for (
const auto *I : OPT->
quals())
2158 if (
SemaRef.DiagnoseUseOfDecl(PD, MemberLoc))
2164 SuperLoc, SuperType);
2166 return new (Context)
2189 if (
SemaRef.DiagnoseUseOfDecl(Getter, MemberLoc))
2208 if (Setter &&
SemaRef.DiagnoseUseOfDecl(Setter, MemberLoc))
2220 if (!(PDecl->getPropertyAttributes() &
2223 diag::warn_property_access_suggest)
2224 << MemberName <<
QualType(OPT, 0) << PDecl->getName()
2229 if (Getter || Setter) {
2231 return new (Context)
2235 return new (Context)
2252 Corrected.isKeyword() ?
nullptr : Corrected.getFoundDecl();
2257 Diag(MemberLoc, diag::err_class_property_found) << MemberName
2264 SemaRef.diagnoseTypo(Corrected,
2265 PDiag(diag::err_property_not_found_suggest)
2266 << MemberName <<
QualType(OPT, 0));
2268 TypoResult, MemberLoc,
2269 SuperLoc, SuperType, Super);
2278 if (
SemaRef.RequireCompleteType(MemberLoc, OBJPT->getPointeeType(),
2279 diag::err_property_not_as_forward_class,
2280 MemberName, BaseExpr))
2284 diag::err_ivar_access_using_property_syntax_suggest)
2285 << MemberName <<
QualType(OPT, 0) << Ivar->getDeclName()
2290 Diag(MemberLoc, diag::err_property_not_found)
2310 if (receiverNamePtr->
isStr(
"super")) {
2312 if (
auto classDecl = CurMethod->getClassInterface()) {
2313 SuperType =
QualType(classDecl->getSuperClassType(), 0);
2314 if (CurMethod->isInstanceMethod()) {
2315 if (SuperType.
isNull()) {
2317 Diag(receiverNameLoc, diag::err_root_class_cannot_use_super)
2318 << CurMethod->getClassInterface()->getIdentifier();
2321 QualType T = Context.getObjCObjectPointerType(SuperType);
2328 receiverNameLoc, T,
true);
2339 Diag(receiverNameLoc, diag::err_expected_either) << tok::identifier
2349 GetterSel = PD->getGetterName();
2350 SetterSel = PD->getSetterName();
2352 GetterSel =
SemaRef.PP.getSelectorTable().getNullarySelector(&propertyName);
2368 if (
SemaRef.DiagnoseUseOfDecl(Getter, propertyNameLoc))
2383 if (Setter &&
SemaRef.DiagnoseUseOfDecl(Setter, propertyNameLoc))
2386 if (Getter || Setter) {
2388 return new (Context)
2395 propertyNameLoc, receiverNameLoc, IFace);
2397 return ExprError(
Diag(propertyNameLoc, diag::err_property_not_found)
2398 << &propertyName << Context.getObjCInterfaceType(IFace));
2408 WantObjCSuper =
Method->getClassInterface()->getSuperClass();
2411 bool ValidateCandidate(
const TypoCorrection &candidate)
override {
2416 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
2417 return std::make_unique<ObjCInterfaceOrSuperCCC>(*
this);
2426 bool HasTrailingDot,
ParsedType &ReceiverType) {
2428 ReceiverType =
nullptr;
2439 switch (
Result.getResultKind()) {
2446 if (!
Method->getClassInterface()) {
2452 if (
Method->getClassInterface()->lookupInstanceVariable(Name,
2464 Result.suppressDiagnostics();
2477 T = Context.getObjCInterfaceType(
Class);
2481 std::nullopt,
Type);
2487 TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
2488 ReceiverType =
SemaRef.CreateParsedType(T, TSInfo);
2493 ObjCInterfaceOrSuperCCC CCC(
SemaRef.getCurMethodDecl());
2495 Result.getLookupNameInfo(),
Result.getLookupKind(), S,
nullptr, CCC,
2497 if (Corrected.isKeyword()) {
2500 SemaRef.diagnoseTypo(Corrected,
PDiag(diag::err_unknown_receiver_suggest)
2507 SemaRef.diagnoseTypo(Corrected,
PDiag(diag::err_unknown_receiver_suggest)
2510 TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
2511 ReceiverType =
SemaRef.CreateParsedType(T, TSInfo);
2529 Diag(SuperLoc, diag::err_invalid_receiver_to_message_super);
2535 Diag(SuperLoc, diag::err_no_super_class_message)
2536 <<
Method->getDeclName();
2543 Diag(SuperLoc, diag::err_root_class_cannot_use_super)
2544 <<
Class->getIdentifier();
2550 if (
Method->getSelector() == Sel)
2551 SemaRef.getCurFunction()->ObjCShouldCallSuper =
false;
2553 if (
Method->isInstanceMethod()) {
2556 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2559 LBracLoc, SelectorLocs, RBracLoc, Args);
2566 SuperLoc, Sel,
nullptr,
2567 LBracLoc, SelectorLocs, RBracLoc, Args);
2571 bool isSuperReceiver,
2577 if (!ReceiverType.
isNull())
2578 receiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType);
2580 assert(((isSuperReceiver && Loc.
isValid()) || receiverTypeInfo) &&
2581 "Either the super receiver location needs to be valid or the receiver "
2582 "needs valid type source information");
2585 Sel,
Method, Loc, Loc, Loc, Args,
2600 auto Builder = S.
Diag(MsgLoc, DiagID)
2608 switch (Edit.
Kind) {
2615 Builder.AddFixItHint(
2636 bool IsClassObjectCall) {
2642 const auto *SE = dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens());
2646 if (!IsClassObjectCall) {
2648 if (!OPT || !OPT->getInterfaceDecl())
2651 OPT->getInterfaceDecl()->lookupInstanceMethod(SE->getSelector());
2654 OPT->getInterfaceDecl()->lookupPrivateMethod(SE->getSelector());
2659 ImpliedMethod = IT->getDecl()->lookupClassMethod(SE->getSelector());
2662 IT->getDecl()->lookupPrivateClassMethod(SE->getSelector());
2667 if (Ret->isRecordType() || Ret->isVectorType() || Ret->isExtVectorType()) {
2668 S.
Diag(Loc, diag::warn_objc_unsafe_perform_selector)
2669 << Method->getSelector()
2670 << (!Ret->isRecordType()
2672 : Ret->isUnionType() ? 1 : 0);
2674 diag::note_objc_unsafe_perform_selector_method_declared_here)
2685 Expr **Args,
unsigned NumArgs) {
2687 bool Format =
false;
2694 for (
const auto *I : Method->specific_attrs<FormatAttr>()) {
2701 if (!Format || NumArgs <= Idx)
2704 Expr *FormatExpr = Args[Idx];
2709 S.
Diag(FormatExpr->
getExprLoc(), diag::warn_objc_cdirective_format_string)
2712 S.
Diag(Method->getLocation(), diag::note_method_declared_at)
2713 << Method->getDeclName();
2755 Diag(Loc, diag::err_missing_open_square_message_send)
2760 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
2761 SelectorSlotLocs = SelectorLocs;
2763 SelectorSlotLocs = Loc;
2769 unsigned NumArgs = ArgsIn.size();
2770 Expr **Args = ArgsIn.data();
2771 assert(SuperLoc.
isInvalid() &&
"Message to super with dependent type");
2773 ReceiverTypeInfo, Sel, SelectorLocs,
2775 RBracLoc, isImplicit);
2781 if (!ClassType || !(
Class = ClassType->getInterface())) {
2782 Diag(Loc, diag::err_invalid_receiver_class_message)
2786 assert(
Class &&
"We don't know which class we're messaging?");
2789 (void)
SemaRef.DiagnoseUseOfDecl(
Class, SelectorSlotLocs);
2795 if (
SemaRef.RequireCompleteType(Loc, Context.getObjCInterfaceType(
Class),
2797 ? diag::err_arc_receiver_forward_class
2798 : diag::warn_receiver_forward_class),
2804 Diag(
Method->getLocation(), diag::note_method_sent_forward_class)
2805 <<
Method->getDeclName();
2815 false,
false,
Class))
2823 unsigned NumArgs = ArgsIn.size();
2824 Expr **Args = ArgsIn.data();
2831 if (
Method && !
Method->getReturnType()->isVoidType() &&
2833 LBracLoc,
Method->getReturnType(),
2834 diag::err_illegal_message_expr_incomplete_type))
2838 Diag(SuperLoc, diag::err_messaging_super_with_direct_method)
2842 :
Method->getClassInterface()->getName());
2843 Diag(
Method->getLocation(), diag::note_direct_method_declared_at)
2844 <<
Method->getDeclName();
2851 dyn_cast<ObjCInterfaceDecl>(
Method->getDeclContext());
2853 Diag(Loc, diag::warn_direct_initialize_call);
2854 Diag(
Method->getLocation(), diag::note_method_declared_at)
2855 <<
Method->getDeclName();
2860 Diag(Loc, diag::warn_direct_super_initialize_call);
2861 Diag(
Method->getLocation(), diag::note_method_declared_at)
2862 <<
Method->getDeclName();
2863 Diag(CurMeth->getLocation(), diag::note_method_declared_at)
2864 << CurMeth->getDeclName();
2875 Context, ReturnType,
VK, LBracLoc, SuperLoc,
false,
2876 ReceiverType, Sel, SelectorLocs,
Method,
ArrayRef(Args, NumArgs),
2877 RBracLoc, isImplicit);
2880 Context, ReturnType,
VK, LBracLoc, ReceiverTypeInfo, Sel, SelectorLocs,
2887 ReceiverType,
true);
2902 SemaRef.GetTypeFromParser(Receiver, &ReceiverTypeInfo);
2903 if (ReceiverType.
isNull())
2906 if (!ReceiverTypeInfo)
2907 ReceiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType, LBracLoc);
2911 nullptr, LBracLoc, SelectorLocs, RBracLoc,
2920 Sel,
Method, Loc, Loc, Loc, Args,
2927 const auto *Protocol = dyn_cast<ObjCProtocolDecl>(M->
getDeclContext());
2932 if (
const auto *RootClass = dyn_cast_or_null<ObjCInterfaceDecl>(
2936 if (P->getCanonicalDecl() == Protocol->getCanonicalDecl())
2976 assert((Receiver || SuperLoc.
isValid()) &&
"If the Receiver is null, the "
2977 "SuperLoc must be valid so we can "
2986 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
2987 SelectorSlotLocs = SelectorLocs;
2989 SelectorSlotLocs = Loc;
2993 Diag(Loc, diag::err_missing_open_square_message_send)
3003 if (Receiver->
getType() == Context.UnknownAnyTy)
3005 SemaRef.forceUnknownAnyToType(Receiver, Context.getObjCIdType());
3015 unsigned NumArgs = ArgsIn.size();
3016 Expr **Args = ArgsIn.data();
3017 assert(SuperLoc.
isInvalid() &&
"Message to super with dependent type");
3019 Context, Context.DependentTy,
VK_PRValue, LBracLoc, Receiver, Sel,
3020 SelectorLocs,
nullptr,
ArrayRef(Args, NumArgs), RBracLoc,
3030 ReceiverType = Receiver->
getType();
3038 !Context.getObjCIdType().isNull() &&
3043 Diag(Loc, diag::warn_bad_receiver_type) << ReceiverType << RecRange;
3046 .ImpCastExprToType(Receiver, Context.getObjCIdType(),
3047 CK_CPointerToObjCPointerCast)
3053 CastKind Kind =
IsNull ? CK_NullToPointer : CK_IntegralToPointer;
3055 SemaRef.ImpCastExprToType(Receiver, Context.getObjCIdType(), Kind)
3058 ReceiverType = Receiver->
getType();
3062 diag::err_incomplete_receiver_type))
3066 SemaRef.PerformContextuallyConvertToObjCPointer(Receiver);
3068 Receiver = result.
get();
3069 ReceiverType = Receiver->
getType();
3085 (Receiver && Context.isObjCNSObjectType(Receiver->
getType()))) {
3090 if (!Methods.empty()) {
3096 Sel, ArgsIn,
Method->isInstanceMethod(), Methods))
3101 receiverIsIdLike, Methods))
3119 Diag(SelLoc, diag::warn_instance_method_on_class_found)
3120 <<
Method->getSelector() << Sel;
3121 Diag(
Method->getLocation(), diag::note_method_declared_at)
3122 <<
Method->getDeclName();
3132 Method = ClassDecl->lookupClassMethod(Sel);
3135 Method = ClassDecl->lookupPrivateClassMethod(Sel);
3150 if (!Methods.empty()) {
3156 if (
Method->isInstanceMethod()) {
3158 dyn_cast<ObjCInterfaceDecl>(
Method->getDeclContext())) {
3159 if (ID->getSuperClass())
3160 Diag(SelLoc, diag::warn_root_inst_method_not_found)
3166 Sel, ArgsIn,
Method->isInstanceMethod(), Methods))
3189 ClassDecl = OCIType->getInterfaceDecl();
3196 if (
SemaRef.RequireCompleteType(
3197 Loc, OCIType->getPointeeType(),
3199 ? diag::err_arc_receiver_forward_instance
3200 : diag::warn_receiver_forward_instance,
3205 forwardClass = OCIType->getInterfaceDecl();
3207 diag::note_receiver_is_id);
3222 Diag(SelLoc, diag::err_arc_may_not_respond)
3223 << OCIType->getPointeeType() << Sel << RecRange
3224 <<
SourceRange(SelectorLocs.front(), SelectorLocs.back());
3232 if (OCIType->qual_empty()) {
3237 if (!Methods.empty()) {
3243 Sel, ArgsIn,
Method->isInstanceMethod(), Methods))
3251 if (
Method && !forwardClass)
3252 Diag(SelLoc, diag::warn_maynot_respond)
3253 << OCIType->getInterfaceDecl()->getIdentifier()
3259 SemaRef.DiagnoseUseOfDecl(
Method, SelectorSlotLocs, forwardClass))
3263 Diag(Loc, diag::err_bad_receiver_type) << ReceiverType << RecRange;
3271 ?
SemaRef.getEnclosingFunction()
3277 diag::err_messaging_unqualified_id_with_direct_method);
3278 Diag(
Method->getLocation(), diag::note_direct_method_declared_at)
3279 <<
Method->getDeclName();
3289 diag::err_messaging_class_with_direct_method);
3292 RecRange,
Method->getClassInterface()->getName()));
3295 Diag(
Method->getLocation(), diag::note_direct_method_declared_at)
3296 <<
Method->getDeclName();
3302 Diag(SuperLoc, diag::err_messaging_super_with_direct_method);
3305 SuperLoc,
Method->getClassInterface()->getName()));
3310 Diag(
Method->getLocation(), diag::note_direct_method_declared_at)
3311 <<
Method->getDeclName();
3313 }
else if (ReceiverType->
isObjCIdType() && !isImplicit) {
3314 Diag(Receiver->
getExprLoc(), diag::warn_messaging_unqualified_id);
3317 if (DIFunctionScopeInfo &&
3320 bool isDesignatedInitChain =
false;
3327 if (!ID->declaresOrInheritsDesignatedInitializers() ||
3328 ID->isDesignatedInitializer(Sel)) {
3329 isDesignatedInitChain =
true;
3335 if (!isDesignatedInitChain) {
3337 auto *CurMD =
SemaRef.getCurMethodDecl();
3338 assert(CurMD &&
"Current method declaration should not be null");
3340 CurMD->isDesignatedInitializerForTheInterface(&InitMethod);
3341 assert(isDesignated && InitMethod);
3344 diag::warn_objc_designated_init_non_designated_init_call :
3345 diag::warn_objc_designated_init_non_super_designated_init_call);
3347 diag::note_objc_designated_init_marked_here);
3351 if (DIFunctionScopeInfo &&
3355 Diag(SelLoc, diag::warn_objc_secondary_init_super_init_call);
3362 unsigned NumArgs = ArgsIn.size();
3363 Expr **Args = ArgsIn.data();
3371 LBracLoc, RBracLoc, RecRange, ReturnType,
VK))
3374 if (
Method && !
Method->getReturnType()->isVoidType() &&
3376 LBracLoc,
Method->getReturnType(),
3377 diag::err_illegal_message_expr_incomplete_type))
3406 Diag(SelLoc, diag::err_arc_illegal_explicit_message)
3411 if (
Method && NumArgs >= 1) {
3412 if (
const auto *SelExp =
3413 dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens())) {
3414 Selector ArgSel = SelExp->getSelector();
3417 SelExp->getSourceRange());
3421 SelExp->getSourceRange());
3424 switch (SelFamily) {
3431 if (!SelMethod->
hasAttr<NSReturnsNotRetainedAttr>()) {
3434 diag::err_arc_perform_selector_retains);
3441 if (SelMethod->
hasAttr<NSReturnsRetainedAttr>()) {
3444 diag::err_arc_perform_selector_retains);
3453 Diag(SelLoc, diag::warn_arc_perform_selector_leaks);
3454 Diag(Args[0]->getExprLoc(), diag::note_used_here);
3467 Context, ReturnType,
VK, LBracLoc, SuperLoc,
true,
3468 ReceiverType, Sel, SelectorLocs,
Method,
ArrayRef(Args, NumArgs),
3469 RBracLoc, isImplicit);
3472 Context, ReturnType,
VK, LBracLoc, Receiver, Sel, SelectorLocs,
Method,
3473 ArrayRef(Args, NumArgs), RBracLoc, isImplicit);
3478 bool IsClassObjectCall = ClassMessage;
3485 if (OPT->getObjectType()->isObjCClass()) {
3486 if (
const auto *CurMeth =
SemaRef.getCurMethodDecl()) {
3487 IsClassObjectCall =
true;
3489 Context.getObjCInterfaceType(CurMeth->getClassInterface());
3495 ReceiverType, IsClassObjectCall);
3508 Result->setDelegateInitCall(
true);
3519 if (!isImplicit &&
Method) {
3525 if (IsWeak && !
SemaRef.isUnevaluatedContext() &&
3564 SemaRef.MaybeConvertParenListExprToParenExpr(S, Receiver);
3570 IdentifierInfo *SelectorId = &Context.Idents.get(
"respondsToSelector");
3578 nullptr, LBracLoc, SelectorLocs,
3612 bool isIndirect =
false;
3616 type = ref->getPointeeType();
3623 type = ptr->getPointeeType();
3630 }
else if (
const ArrayType *array =
type->getAsArrayTypeUnsafe()) {
3631 type =
QualType(array->getElementType()->getBaseElementTypeUnsafe(), 0);
3639 if (
type->isObjCARCBridgableType())
3644 if (
type->isObjCARCBridgableType())
3665 ACCResult
merge(ACCResult left, ACCResult right) {
3666 if (left == right)
return left;
3667 if (left == ACC_bottom)
return right;
3668 if (right == ACC_bottom)
return left;
3674 class ARCCastChecker :
public StmtVisitor<ARCCastChecker, ACCResult> {
3675 typedef StmtVisitor<ARCCastChecker, ACCResult> super;
3677 ASTContext &Context;
3682 static bool isCFType(QualType
type) {
3684 return type->isCARCBridgableType();
3690 : Context(Context), SourceClass(source), TargetClass(target),
3691 Diagnose(diagnose) {}
3694 ACCResult Visit(Expr *e) {
3698 ACCResult VisitStmt(Stmt *
s) {
3703 ACCResult VisitExpr(Expr *e) {
3710 ACCResult VisitObjCObjectLiteral(ObjCObjectLiteral *OL) {
3719 ACCResult VisitObjCStringLiteral(ObjCStringLiteral *SL) {
3720 return VisitObjCObjectLiteral(SL);
3723 ACCResult VisitObjCBoxedExpr(ObjCBoxedExpr *OBE) {
3724 return VisitObjCObjectLiteral(OBE);
3727 ACCResult VisitObjCArrayLiteral(ObjCArrayLiteral *AL) {
3728 return VisitObjCObjectLiteral(AL);
3731 ACCResult VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *DL) {
3732 return VisitObjCObjectLiteral(DL);
3736 ACCResult VisitCastExpr(
CastExpr *e) {
3738 case CK_NullToPointer:
3742 case CK_LValueToRValue:
3744 case CK_CPointerToObjCPointerCast:
3745 case CK_BlockPointerToObjCPointerCast:
3746 case CK_AnyPointerToBlockPointerCast:
3755 ACCResult VisitUnaryExtension(UnaryOperator *e) {
3760 ACCResult VisitBinComma(BinaryOperator *e) {
3761 return Visit(e->
getRHS());
3765 ACCResult VisitConditionalOperator(ConditionalOperator *e) {
3767 if (left == ACC_invalid)
return ACC_invalid;
3772 ACCResult VisitPseudoObjectExpr(PseudoObjectExpr *e) {
3778 ACCResult VisitStmtExpr(StmtExpr *e) {
3783 ACCResult VisitDeclRefExpr(DeclRefExpr *e) {
3784 VarDecl *
var = dyn_cast<VarDecl>(e->
getDecl());
3789 !
var->hasDefinition(Context) &&
3790 var->getType().isConstQualified()) {
3797 return ACC_plusZero;
3805 ACCResult VisitCallExpr(CallExpr *e) {
3807 if (ACCResult result = checkCallToFunction(fn))
3810 return super::VisitCallExpr(e);
3813 ACCResult checkCallToFunction(FunctionDecl *fn) {
3822 if (fn->
hasAttr<CFReturnsNotRetainedAttr>())
3823 return ACC_plusZero;
3828 if (fn->
hasAttr<CFReturnsRetainedAttr>())
3829 return Diagnose ? ACC_plusOne
3834 if (builtinID == Builtin::BI__builtin___CFStringMakeConstantString)
3838 if (!fn->
hasAttr<CFAuditedTransferAttr>())
3843 return Diagnose ? ACC_plusOne
3846 return ACC_plusZero;
3849 ACCResult VisitObjCMessageExpr(ObjCMessageExpr *e) {
3853 ACCResult VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *e) {
3854 ObjCMethodDecl *method;
3859 return checkCallToMethod(method);
3862 ACCResult checkCallToMethod(ObjCMethodDecl *method) {
3863 if (!method)
return ACC_invalid;
3872 if (method->
hasAttr<CFReturnsNotRetainedAttr>())
3873 return ACC_plusZero;
3877 if (method->
hasAttr<CFReturnsRetainedAttr>())
3889 return ACC_plusZero;
3904template <
typename DiagBuilderT>
3908 Expr *realCast,
const char *bridgeKeyword,
const char *CFBridgeName) {
3924 NCE->getAngleBrackets().getEnd());
3928 char PrevChar = *
SM.getCharacterData(range.getBegin().getLocWithOffset(-1));
3932 BridgeCall += CFBridgeName;
3939 castedE = CCE->getSubExpr();
3946 char PrevChar = *
SM.getCharacterData(range.getBegin().getLocWithOffset(-1));
3950 BridgeCall += CFBridgeName;
3970 std::string castCode =
"(";
3971 castCode += bridgeKeyword;
3975 NCE->getAngleBrackets().getEnd());
3979 std::string castCode =
"(";
3980 castCode += bridgeKeyword;
3999template <
typename T>
4006 for (
auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) {
4007 if (
auto *
attr = Redecl->getAttr<T>())
4017 while (
const auto *TD = T->getAs<
TypedefType>()) {
4018 TDNDecl = TD->getDecl();
4019 if (ObjCBridgeRelatedAttr *ObjCBAttr =
4037 UnavailableAttr::IR_ARCForbiddenConversion))
4050 unsigned srcKind = 0;
4074 S.
Diag(loc, diag::err_arc_cast_requires_bridge)
4083 ACCResult CreateRule =
4085 assert(CreateRule != ACC_bottom &&
"This cast should already be accepted.");
4086 if (CreateRule != ACC_plusOne)
4089 ? S.
Diag(noteLoc, diag::note_arc_bridge)
4090 : S.
Diag(noteLoc, diag::note_arc_cstyle_bridge);
4093 castType,
castExpr, realCast,
"__bridge ",
4096 if (CreateRule != ACC_plusZero)
4099 ? S.
Diag(noteLoc, diag::note_arc_cstyle_bridge_transfer)
4102 diag::note_arc_bridge_transfer)
4103 << castExprType << br;
4106 castType,
castExpr, realCast,
"__bridge_transfer ",
4107 br ?
"CFBridgingRelease" :
nullptr);
4116 S.
Diag(loc, diag::err_arc_cast_requires_bridge)
4124 ACCResult CreateRule =
4126 assert(CreateRule != ACC_bottom &&
"This cast should already be accepted.");
4127 if (CreateRule != ACC_plusOne)
4130 ? S.
Diag(noteLoc, diag::note_arc_bridge)
4131 : S.
Diag(noteLoc, diag::note_arc_cstyle_bridge);
4133 castType,
castExpr, realCast,
"__bridge ",
4136 if (CreateRule != ACC_plusZero)
4139 ? S.
Diag(noteLoc, diag::note_arc_cstyle_bridge_retained)
4142 diag::note_arc_bridge_retained)
4146 castType,
castExpr, realCast,
"__bridge_retained ",
4147 br ?
"CFBridgingRetain" :
nullptr);
4153 S.
Diag(loc, diag::err_arc_mismatched_cast)
4155 << srcKind << castExprType << castType
4156 << castRange <<
castExpr->getSourceRange();
4159template <
typename TB>
4161 bool &HadTheAttribute,
bool warn) {
4163 HadTheAttribute =
false;
4164 while (
const auto *TD = T->getAs<
TypedefType>()) {
4168 HadTheAttribute =
true;
4169 if (Parm->isStr(
"id"))
4182 = InterfacePointerType->getObjectType()->getInterface();
4183 if ((CastClass == ExprClass) ||
4187 S.
Diag(
castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)
4192 castType, ExprClass)))
4199 S.
Diag(
castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)
4200 << T <<
Target->getName() << castType;
4202 S.
Diag(
Target->getBeginLoc(), diag::note_declared_at);
4209 diag::err_objc_cf_bridged_not_interface)
4222template <
typename TB>
4224 bool &HadTheAttribute,
bool warn) {
4226 HadTheAttribute =
false;
4227 while (
const auto *TD = T->getAs<
TypedefType>()) {
4231 HadTheAttribute =
true;
4232 if (Parm->isStr(
"id"))
4240 Target = R.getFoundDecl();
4244 castExpr->getType()->getAsObjCInterfacePointerType()) {
4246 = InterfacePointerType->getObjectType()->getInterface();
4247 if ((CastClass == ExprClass) ||
4252 diag::warn_objc_invalid_bridge_to_cf)
4253 <<
castExpr->getType()->getPointeeType() << T;
4257 }
else if (
castExpr->getType()->isObjCIdType() ||
4267 diag::warn_objc_invalid_bridge_to_cf)
4268 <<
castExpr->getType() << castType;
4270 S.
Diag(
Target->getBeginLoc(), diag::note_declared_at);
4277 diag::err_objc_ns_bridged_invalid_cfobject)
4278 <<
castExpr->getType() << castType;
4281 S.
Diag(
Target->getBeginLoc(), diag::note_declared_at);
4298 bool HasObjCBridgeAttr;
4301 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
4303 bool HasObjCBridgeMutableAttr;
4304 bool ObjCBridgeMutableAttrWillNotWarn =
4307 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
4310 if (HasObjCBridgeAttr)
4312 HasObjCBridgeAttr,
true);
4313 else if (HasObjCBridgeMutableAttr)
4318 bool HasObjCBridgeAttr;
4321 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
4323 bool HasObjCBridgeMutableAttr;
4324 bool ObjCBridgeMutableAttrWillNotWarn =
4327 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
4330 if (HasObjCBridgeAttr)
4332 HasObjCBridgeAttr,
true);
4333 else if (HasObjCBridgeMutableAttr)
4342 if (PRE->isExplicitProperty()) {
4344 SrcType = PDecl->getType();
4346 else if (PRE->isImplicitProperty()) {
4348 SrcType = Getter->getReturnType();
4371 : CK_CPointerToObjCPointerCast;
4383 QualType T = CfToNs ? SrcType : DestType;
4399 Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId
4400 << SrcType << DestType;
4405 Target = R.getFoundDecl();
4410 Diag(Loc, diag::err_objc_bridged_related_invalid_class_name) << RCId
4411 << SrcType << DestType;
4414 Diag(
Target->getBeginLoc(), diag::note_declared_at);
4420 if (CfToNs && CMId) {
4421 Selector Sel = Context.Selectors.getUnarySelector(CMId);
4425 Diag(Loc, diag::err_objc_bridged_related_known_method)
4426 << SrcType << DestType << Sel <<
false;
4434 if (!CfToNs && IMId) {
4435 Selector Sel = Context.Selectors.getNullarySelector(IMId);
4436 InstanceMethod = RelatedClass->
lookupMethod(Sel,
true);
4437 if (!InstanceMethod) {
4439 Diag(Loc, diag::err_objc_bridged_related_known_method)
4440 << SrcType << DestType << Sel <<
true;
4459 if (!CfToNs && !NsToCf)
4467 ClassMethod, InstanceMethod, TDNDecl,
4475 std::string ExpressionString =
"[";
4477 ExpressionString +=
" ";
4478 ExpressionString += ClassMethod->getSelector().getAsString();
4482 Diag(Loc, diag::err_objc_bridged_related_known_method)
4483 << SrcType << DestType << ClassMethod->getSelector() <<
false
4490 QualType receiverType = Context.getObjCInterfaceType(RelatedClass);
4492 Expr *args[] = { SrcExpr };
4494 ClassMethod->getLocation(),
4495 ClassMethod->getSelector(), ClassMethod,
4497 SrcExpr = msg.
get();
4504 if (InstanceMethod) {
4506 std::string ExpressionString;
4509 if (InstanceMethod->isPropertyAccessor())
4511 InstanceMethod->findPropertyDecl()) {
4513 ExpressionString =
".";
4514 ExpressionString += PDecl->getNameAsString();
4515 Diag(Loc, diag::err_objc_bridged_related_known_method)
4516 << SrcType << DestType << InstanceMethod->getSelector() <<
true
4519 if (ExpressionString.empty()) {
4521 ExpressionString =
" ";
4522 ExpressionString += InstanceMethod->getSelector().getAsString();
4523 ExpressionString +=
"]";
4525 Diag(Loc, diag::err_objc_bridged_related_known_method)
4526 << SrcType << DestType << InstanceMethod->getSelector() <<
true
4534 SrcExpr, SrcType, InstanceMethod->getLocation(),
4535 InstanceMethod->getSelector(), InstanceMethod, {});
4536 SrcExpr = msg.
get();
4547 bool Diagnose,
bool DiagnoseCFAudited,
4560 if (exprACTC == castACTC) {
4566 castType != castExprType) {
4572 if (
const ParenType *PT = dyn_cast<ParenType>(DT))
4573 QDT = PT->desugar();
4574 else if (
const TypeOfType *TP = dyn_cast<TypeOfType>(DT))
4575 QDT = TP->desugar();
4576 else if (
const AttributedType *AT = dyn_cast<AttributedType>(DT))
4577 QDT = AT->desugar();
4578 if (QDT != castType &&
4583 Diag(loc, diag::err_arc_nolifetime_behavior);
4621 switch (ARCCastChecker(Context, exprACTC, castACTC,
false).Visit(
castExpr)) {
4634 CK_ARCConsumeObject,
castExpr,
nullptr,
4636 SemaRef.Cleanup.setExprNeedsCleanups(
true);
4661 (Opc == BO_NE || Opc == BO_EQ))) {
4683 castType =
cast->getTypeAsWritten();
4686 castRange =
cast->getTypeInfoAsWritten()->getTypeLoc().getSourceRange();
4687 castType =
cast->getTypeAsWritten();
4690 llvm_unreachable(
"Unexpected ImplicitCastExpr");
4709 if (
ParenExpr *pe = dyn_cast<ParenExpr>(e)) {
4711 return new (Context)
ParenExpr(pe->getLParen(), pe->getRParen(), sub);
4712 }
else if (
UnaryOperator *uo = dyn_cast<UnaryOperator>(e)) {
4713 assert(uo->getOpcode() == UO_Extension);
4717 uo->getOperatorLoc(),
false,
4718 SemaRef.CurFPFeatureOverrides());
4720 assert(!gse->isResultDependent());
4721 assert(!gse->isTypePredicate());
4723 unsigned n = gse->getNumAssocs();
4726 subExprs.reserve(n);
4727 subTypes.reserve(n);
4729 subTypes.push_back(assoc.getTypeSourceInfo());
4730 Expr *sub = assoc.getAssociationExpr();
4731 if (assoc.isSelected())
4733 subExprs.push_back(sub);
4737 Context, gse->getGenericLoc(), gse->getControllingExpr(), subTypes,
4738 subExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
4739 gse->containsUnexpandedParameterPack(), gse->getResultIndex());
4759 return !ObjI->isArcWeakrefUnavailable();
4766 Expr *curExpr = e, *prevExpr =
nullptr;
4771 if (
auto *pe = dyn_cast<ParenExpr>(curExpr)) {
4773 curExpr = pe->getSubExpr();
4777 if (
auto *ce = dyn_cast<CastExpr>(curExpr)) {
4778 if (
auto *ice = dyn_cast<ImplicitCastExpr>(ce))
4779 if (ice->getCastKind() == CK_ARCReclaimReturnedObject) {
4781 return ice->getSubExpr();
4782 if (
auto *pe = dyn_cast<ParenExpr>(prevExpr))
4783 pe->setSubExpr(ice->getSubExpr());
4790 curExpr = ce->getSubExpr();
4809 SubExpr = SubResult.
get();
4816 bool MustConsume =
false;
4822 CK = (T->isBlockPointerType() ? CK_AnyPointerToBlockPointerCast
4823 : CK_CPointerToObjCPointerCast);
4830 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
4833 << (T->isBlockPointerType()? 1 : 0)
4837 Diag(BridgeKeywordLoc, diag::note_arc_bridge)
4839 Diag(BridgeKeywordLoc, diag::note_arc_bridge_transfer)
4842 br ?
"CFBridgingRelease "
4843 :
"__bridge_transfer ");
4873 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
4881 Diag(BridgeKeywordLoc, diag::note_arc_bridge)
4883 Diag(BridgeKeywordLoc, diag::note_arc_bridge_retained)
4886 br ?
"CFBridgingRetain " :
"__bridge_retained");
4893 Diag(LParenLoc, diag::err_arc_bridge_cast_incompatible)
4894 << FromType << T << Kind
4905 SemaRef.Cleanup.setExprNeedsCleanups(
true);
4925 TSInfo = Context.getTrivialTypeSourceInfo(T, LParenLoc);
4952 LookForIvars =
true;
4953 else if (IsClassMethod)
4954 LookForIvars =
false;
4965 if (IsClassMethod) {
4986 Diag(Loc, diag::warn_ivar_use_hidden) << IV->getDeclName();
4994 Diag(Loc, diag::err_ivar_use_in_class_method) << IV->getDeclName();
5005 bool AllowBuiltinCreation) {
5014 if (Lookup.
empty() && II && AllowBuiltinCreation)
5015 SemaRef.LookupBuiltin(Lookup);
5026 "should not reference ivar from this context");
5029 assert(IFace &&
"should not reference ivar from this context");
5037 if (
SemaRef.DiagnoseUseOfDecl(IV, Loc))
5048 SemaRef.ActOnIdExpression(S, SelfScopeSpec, TemplateKWLoc, SelfName,
5054 SelfExpr =
SemaRef.DefaultLvalueConversion(SelfExpr.
get());
5058 SemaRef.MarkAnyDeclReferenced(Loc, IV,
true);
5070 if (!
SemaRef.isUnevaluatedContext() &&
5071 !
getDiagnostics().isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
5076 SemaRef.ImplicitlyRetainedSelfLocs.push_back({Loc, BD});
5092 (Context.hasSameType(RHSTy, Context.getObjCClassRedefinitionType()))) {
5093 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), LHSTy,
5094 CK_CPointerToObjCPointerCast);
5098 (Context.hasSameType(LHSTy, Context.getObjCClassRedefinitionType()))) {
5099 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), RHSTy,
5100 CK_CPointerToObjCPointerCast);
5105 (Context.hasSameType(RHSTy, Context.getObjCIdRedefinitionType()))) {
5106 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), LHSTy,
5107 CK_CPointerToObjCPointerCast);
5111 (Context.hasSameType(LHSTy, Context.getObjCIdRedefinitionType()))) {
5112 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), RHSTy,
5113 CK_CPointerToObjCPointerCast);
5117 if (Context.isObjCSelType(LHSTy) &&
5118 (Context.hasSameType(RHSTy, Context.getObjCSelRedefinitionType()))) {
5119 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), LHSTy, CK_BitCast);
5122 if (Context.isObjCSelType(RHSTy) &&
5123 (Context.hasSameType(LHSTy, Context.getObjCSelRedefinitionType()))) {
5124 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), RHSTy, CK_BitCast);
5130 if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {
5153 if (!(compositeType = Context.areCommonBaseCompatible(LHSOPT, RHSOPT))
5156 }
else if (Context.canAssignObjCInterfaces(LHSOPT, RHSOPT)) {
5157 compositeType = RHSOPT->isObjCBuiltinType() ? RHSTy : LHSTy;
5158 }
else if (Context.canAssignObjCInterfaces(RHSOPT, LHSOPT)) {
5161 RHSOPT->isObjCQualifiedIdType()) &&
5162 Context.ObjCQualifiedIdTypesAreCompatible(LHSOPT, RHSOPT,
5168 compositeType = Context.getObjCIdType();
5170 compositeType = Context.getObjCIdType();
5172 Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands)
5175 QualType incompatTy = Context.getObjCIdType();
5176 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), incompatTy, CK_BitCast);
5177 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), incompatTy, CK_BitCast);
5181 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), compositeType, CK_BitCast);
5182 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), compositeType, CK_BitCast);
5183 return compositeType;
5190 Diag(QuestionLoc, diag::err_cond_voidptr_arc)
5200 QualType destType = Context.getPointerType(destPointee);
5202 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), destType, CK_NoOp);
5204 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), destType, CK_BitCast);
5211 Diag(QuestionLoc, diag::err_cond_voidptr_arc)
5221 QualType destType = Context.getPointerType(destPointee);
5223 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), destType, CK_NoOp);
5225 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), destType, CK_BitCast);
5246 if (OV->getSourceExpr())
5249 if (
auto *SL = dyn_cast<StringLiteral>(SrcExpr)) {
5250 if (!PT->
isObjCIdType() && !(ID && ID->getIdentifier()->isStr(
"NSString")))
5252 if (!SL->isOrdinary())
5256 Diag(SL->getBeginLoc(), diag::err_missing_atsign_prefix)
5268 if (!ID || !ID->getIdentifier()->isStr(
"NSNumber"))
5288 assert((Kind == tok::kw___objc_yes || Kind == tok::kw___objc_no) &&
5289 "Unknown Objective-C Boolean value!");
5291 QualType BoolT = Context.ObjCBuiltinBoolTy;
5292 if (!Context.getBOOLDecl()) {
5296 Result.isSingleResult()) {
5299 Context.setBOOLDecl(TD);
5302 if (Context.getBOOLDecl())
5303 BoolT = Context.getBOOLType();
5304 return new (Context)
5312 auto FindSpecVersion =
5313 [&](StringRef Platform,
5314 const llvm::Triple::OSType &OS) -> std::optional<VersionTuple> {
5320 if (Spec == AvailSpecs.end() && Platform ==
"maccatalyst") {
5327 if (Spec == AvailSpecs.end()) {
5329 const llvm::Triple &Triple = Context.getTargetInfo().getTriple();
5330 if (Triple.isOSDarwin()) {
5336 if (Spec == AvailSpecs.end())
5337 return std::nullopt;
5339 return llvm::Triple::getCanonicalVersionForOS(
5341 llvm::Triple::isValidVersionForOS(OS, Spec->
getVersion()));
5344 VersionTuple Version;
5345 if (
auto MaybeVersion =
5346 FindSpecVersion(Context.getTargetInfo().getPlatformName(),
5347 Context.getTargetInfo().getTriple().getOS()))
5348 Version = *MaybeVersion;
5353 Context->HasPotentialAvailabilityViolations =
true;
5355 return new (Context)
5363 if (
type->isObjCObjectPointerType()) {
5365 }
else if (
type->isBlockPointerType()) {
5366 SemaRef.maybeExtendBlockObject(E);
5367 return CK_BlockPointerToObjCPointerCast;
5369 assert(
type->isPointerType());
5370 return CK_CPointerToObjCPointerCast;
5379 case Stmt::ObjCStringLiteralClass:
5382 case Stmt::ObjCArrayLiteralClass:
5385 case Stmt::ObjCDictionaryLiteralClass:
5388 case Stmt::BlockExprClass:
5390 case Stmt::ObjCBoxedExprClass: {
5393 case Stmt::IntegerLiteralClass:
5394 case Stmt::FloatingLiteralClass:
5395 case Stmt::CharacterLiteralClass:
5396 case Stmt::ObjCBoolLiteralExprClass:
5397 case Stmt::CXXBoolLiteralExprClass:
5400 case Stmt::ImplicitCastExprClass: {
5403 if (CK == CK_IntegralToBoolean || CK == CK_IntegralCast)
Defines the clang::ASTContext interface.
static StringRef bytes(const std::vector< T, Allocator > &v)
Defines enum values for all the target-independent builtin functions.
llvm::MachO::Target Target
Defines the clang::Preprocessor interface.
static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr, bool &HadTheAttribute, bool warn)
static ObjCMethodDecl * getNSNumberFactoryMethod(SemaObjC &S, SourceLocation Loc, QualType NumberType, bool isLiteral=false, SourceRange R=SourceRange())
Retrieve the NSNumber factory method that should be used to create an Objective-C literal for the giv...
static QualType stripObjCInstanceType(ASTContext &Context, QualType T)
static void diagnoseObjCARCConversion(Sema &S, SourceRange castRange, QualType castType, ARCConversionTypeClass castACTC, Expr *castExpr, Expr *realCast, ARCConversionTypeClass exprACTC, CheckedConversionKind CCK)
static ObjCInterfaceDecl * LookupObjCInterfaceDeclForLiteral(Sema &S, SourceLocation Loc, SemaObjC::ObjCLiteralKind LiteralKind)
Looks up ObjCInterfaceDecl of a given NSClassIdKindKind.
static ObjCMethodDecl * findMethodInCurrentClass(Sema &S, Selector Sel)
static void checkCocoaAPI(Sema &S, const ObjCMessageExpr *Msg)
static bool CheckObjCNumberExpressionIsConstant(Sema &S, Expr *Number)
static ObjCMethodDecl * LookupDirectMethodInGlobalPool(Sema &S, Selector Sel, bool &onlyDirect, bool &anyDirect)
static Expr * maybeUndoReclaimObject(Expr *e)
Look for an ObjCReclaimReturnedObject cast and destroy it.
static bool CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr, bool &HadTheAttribute, bool warn)
static void CheckObjCDictionaryLiteralDuplicateKeys(Sema &S, ObjCDictionaryLiteral *Literal)
Check for duplicate keys in an ObjC dictionary literal.
static bool ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl, SourceLocation Loc, SemaObjC::ObjCLiteralKind LiteralKind)
Validates ObjCInterfaceDecl availability.
static NSAPI::NSClassIdKindKind ClassKindFromLiteralKind(SemaObjC::ObjCLiteralKind LiteralKind)
Maps ObjCLiteralKind to NSClassIdKindKind.
static bool isAnyCLike(ARCConversionTypeClass ACTC)
static void DiagnoseMismatchedSelectors(Sema &S, SourceLocation AtLoc, ObjCMethodDecl *Method, SourceLocation LParenLoc, SourceLocation RParenLoc, bool WarnMultipleSelectors)
static bool HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S, SourceLocation AtLoc, SourceLocation LParenLoc, SourceLocation RParenLoc, ObjCMethodDecl *Method, ObjCMethodList &MethList)
static void applyCocoaAPICheck(Sema &S, const ObjCMessageExpr *Msg, unsigned DiagID, bool(*refactor)(const ObjCMessageExpr *, const NSAPI &, edit::Commit &))
static ObjCMethodDecl * LookupDirectMethodInMethodList(Sema &S, Selector Sel, ObjCMethodList &MethList, bool &onlyDirect, bool &anyDirect)
static ObjCBridgeRelatedAttr * ObjCBridgeRelatedAttrFromType(QualType T, TypedefNameDecl *&TDNDecl)
static T * getObjCBridgeAttr(const TypedefType *TD)
static ARCConversionTypeClass classifyTypeForARCConversion(QualType type)
static bool isAnyRetainable(ARCConversionTypeClass ACTC)
static void RemoveSelectorFromWarningCache(SemaObjC &S, Expr *Arg)
@ ACTC_voidPtr
void* might be a normal C type, or it might a CF type.
@ ACTC_retainable
id, void (^)()
@ ACTC_coreFoundation
struct A*
@ ACTC_indirectRetainable
id*, id***, void (^*)(),
@ ACTC_none
int, void, struct A
static QualType getBaseMessageSendResultType(Sema &S, QualType ReceiverType, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage)
Determine the result type of a message send based on the receiver type, method, and the kind of messa...
static const ObjCMethodDecl * findExplicitInstancetypeDeclarer(const ObjCMethodDecl *MD, QualType instancetype)
Look for an ObjC method whose result type exactly matches the given type.
static void DiagnoseCStringFormatDirectiveInObjCAPI(Sema &S, ObjCMethodDecl *Method, Selector Sel, Expr **Args, unsigned NumArgs)
Diagnose use of s directive in an NSString which is being passed as formatting string to formatting m...
static bool isMethodDeclaredInRootProtocol(Sema &S, const ObjCMethodDecl *M)
static bool validateBoxingMethod(Sema &S, SourceLocation Loc, const ObjCInterfaceDecl *Class, Selector Sel, const ObjCMethodDecl *Method)
Emits an error if the given method does not exist, or if the return type is not an Objective-C object...
static void checkFoundationAPI(Sema &S, SourceLocation Loc, const ObjCMethodDecl *Method, ArrayRef< Expr * > Args, QualType ReceiverType, bool IsClassObjectCall)
static void addFixitForObjCARCConversion(Sema &S, DiagBuilderT &DiagB, CheckedConversionKind CCK, SourceLocation afterLParen, QualType castType, Expr *castExpr, Expr *realCast, const char *bridgeKeyword, const char *CFBridgeName)
static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element, QualType T, bool ArrayLiteral=false)
Check that the given expression is a valid element of an Objective-C collection literal.
This file declares semantic analysis for Objective-C.
static QualType getPointeeType(const MemRegion *R)
Defines the clang::TypeLoc interface and its subclasses.
__device__ __2f16 float __ockl_bool s
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
bool QIdProtocolsAdoptObjCObjectProtocols(QualType QT, ObjCInterfaceDecl *IDecl)
QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in QT's qualified-id protocol list adopt...
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl)
ObjCObjectAdoptsQTypeProtocols - Checks that protocols in IC's protocol list adopt all protocols in Q...
Represents an array type, per C99 6.7.5.2 - Array Declarators.
ArraySizeModifier getSizeModifier() const
QualType getElementType() const
unsigned getIndexTypeCVRQualifiers() const
One specifier in an @available expression.
StringRef getPlatform() const
VersionTuple getVersion() const
Represents a block literal declaration, which is like an unnamed FunctionDecl.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Abstract class common to all of the C++ "named"/"keyword" casts.
Represents a C++ nested-name-specifier or a global scope specifier.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Represents the canonical version of C arrays with a specified constant size.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Simple template class for restricting typo correction candidates to ones having a single Decl* of the...
A reference to a declared variable, function, enum, etc.
Decl - This represents one declaration (or definition), e.g.
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
bool isInvalidDecl() const
SourceLocation getLocation() const
bool isDefinedOutsideFunctionOrMethod() const
isDefinedOutsideFunctionOrMethod - This predicate returns true if this scoped decl is defined outside...
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
TranslationUnitDecl * getTranslationUnitDecl()
The name of a declaration.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
bool isIdentifier() const
Predicate functions for querying what type of name this is.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
ExplicitCastExpr - An explicit cast written in the source code.
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
Expr * IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY
Skip past any parentheses and casts which do not change the value (including ptr->int casts of the sa...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Skip past any parentheses and lvalue casts which might surround this expression until reaching a fixe...
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool isObjCSelfExpr() const
Check if this expression is the ObjC 'self' implicit parameter.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
@ NPC_ValueDependentIsNull
Specifies that a value-dependent expression of integral or dependent type should be considered a null...
@ NPC_NeverValueDependent
Specifies that the expression should never be value-dependent.
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
static ExprValueKind getValueKindForType(QualType T)
getValueKindForType - Given a formal return or parameter type, give its value kind.
Represents difference between two FPOptions values.
static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc, CharSourceRange FromRange, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code from FromRange at a specific location.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
QualType getReturnType() const
Represents a C11 generic selection.
AssociationTy< false > Association
static GenericSelectionExpr * Create(const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr, ArrayRef< TypeSourceInfo * > AssocTypes, ArrayRef< Expr * > AssocExprs, SourceLocation DefaultLoc, SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack, unsigned ResultIndex)
Create a non-result-dependent generic selection expression accepting an expression predicate.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
Describes the sequence of initializations required to initialize a given object or reference with a s...
Describes an entity that is being initialized.
static InitializedEntity InitializeTemporary(QualType Type)
Create the initialization entity for a temporary.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
static bool isAsciiIdentifierContinueChar(char c, const LangOptions &LangOpts)
Returns true if the given character could appear in an identifier.
Represents the results of name lookup.
bool empty() const
Return true if no decls were found.
SourceLocation getNameLoc() const
Gets the location of the identifier.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
@ NSDict_dictionaryWithObjectsForKeysCount
@ NSArr_arrayWithObjectsCount
This represents a decl that may have a name.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
static ObjCArrayLiteral * Create(const ASTContext &C, ArrayRef< Expr * > Elements, QualType T, ObjCMethodDecl *Method, bool ExpressibleAsConstantInitializer, SourceRange SR)
A runtime availability query.
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
An Objective-C "bridged" cast expression, which casts between Objective-C pointers and C pointers,...
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCContainerDecl - Represents a container for method declarations.
ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const
ObjCPropertyDecl * FindPropertyDeclaration(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyDeclaration - Finds declaration of the property given its name in 'PropertyId' and return...
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
static ObjCDictionaryLiteral * Create(const ASTContext &C, ArrayRef< ObjCDictionaryElement > VK, bool HasPackExpansions, QualType T, ObjCMethodDecl *Method, bool ExpressibleAsConstantInitializer, SourceRange SR)
ObjCEncodeExpr, used for @encode in Objective-C.
Represents an ObjC class declaration.
ObjCMethodDecl * lookupClassMethod(Selector Sel) const
Lookup a class method for a given selector.
static ObjCInterfaceDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation atLoc, const IdentifierInfo *Id, ObjCTypeParamList *typeParamList, ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc=SourceLocation(), bool isInternal=false)
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const
Lookup an instance method for a given selector.
ObjCMethodDecl * lookupPrivateClassMethod(const Selector &Sel)
ObjCMethodDecl * getCategoryClassMethod(Selector Sel) const
ObjCMethodDecl * lookupPrivateMethod(const Selector &Sel, bool Instance=true) const
Lookup a method in the classes implementation hierarchy.
ObjCMethodDecl * lookupMethod(Selector Sel, bool isInstance, bool shallowCategoryLookup=false, bool followSuper=true, const ObjCCategoryDecl *C=nullptr) const
lookupMethod - This method returns an instance/class method by looking in the class,...
ObjCInterfaceDecl * getSuperClass() const
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCIvarDecl - Represents an ObjC instance variable.
AccessControl getAccessControl() const
QualType getUsageType(QualType objectType) const
Retrieve the type of this instance variable when viewed as a member of a specific object type.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
An expression that sends a message to the given Objective-C object or class.
static ObjCMessageExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, SourceLocation LBracLoc, SourceLocation SuperLoc, bool IsInstanceSuper, QualType SuperType, Selector Sel, ArrayRef< SourceLocation > SelLocs, ObjCMethodDecl *Method, ArrayRef< Expr * > Args, SourceLocation RBracLoc, bool isImplicit)
Create a message send to super.
Selector getSelector() const
const ObjCMethodDecl * getMethodDecl() const
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
ArrayRef< ParmVarDecl * > parameters() const
bool isPropertyAccessor() const
void getOverriddenMethods(SmallVectorImpl< const ObjCMethodDecl * > &Overridden) const
Return overridden methods for the given Method.
static ObjCMethodDecl * Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl, bool isInstance=true, bool isVariadic=false, bool isPropertyAccessor=false, bool isSynthesizedAccessorStub=false, bool isImplicitlyDeclared=false, bool isDefined=false, ObjCImplementationControl impControl=ObjCImplementationControl::None, bool HasRelatedResultType=false)
const ObjCPropertyDecl * findPropertyDecl(bool CheckOverrides=true) const
Returns the property associated with this method's selector.
void setMethodParams(ASTContext &C, ArrayRef< ParmVarDecl * > Params, ArrayRef< SourceLocation > SelLocs={})
Sets the method's parameters and selector source locations.
bool hasRelatedResultType() const
Determine whether this method has a result type that is related to the message receiver's type.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
bool isInstanceMethod() const
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
QualType getReturnType() const
bool isClassMethod() const
ObjCInterfaceDecl * getClassInterface()
bool isGlobalAllocation() const
Represents a pointer to an Objective C object.
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
bool isObjCIdType() const
True if this is equivalent to the 'id' type, i.e.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
ObjCInterfaceDecl * getInterfaceDecl() const
If this pointer points to an Objective @interface type, gets the declaration for that interface.
const ObjCInterfaceType * getInterfaceType() const
If this pointer points to an Objective C @interface type, gets the type for that interface.
Represents one property declaration in an Objective-C interface.
ObjCMethodDecl * getGetterMethodDecl() const
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
ObjCPropertyDecl * getExplicitProperty() const
ObjCMethodDecl * getImplicitPropertyGetter() const
bool isExplicitProperty() const
Represents an Objective-C protocol declaration.
bool hasDefinition() const
Determine whether this protocol has a definition.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
bool isNonRuntimeProtocol() const
This is true iff the protocol is tagged with the objc_non_runtime_protocol attribute.
ObjCProtocolExpr used for protocol expression in Objective-C.
bool hasConstantEmptyCollections() const
bool hasConstantCFBooleans() const
ObjCSelectorExpr used for @selector in Objective-C.
ObjCStringLiteral, used for Objective-C string literals i.e.
ObjCSubscriptRefExpr - used for array and dictionary subscripting.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
ParenExpr - This represents a parenthesized expression, e.g.
Sugar for parentheses used when specifying types.
Represents a parameter to a function.
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
A (possibly-)qualified type.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
QualType withConst() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
QualType substObjCTypeArgs(ASTContext &ctx, ArrayRef< QualType > typeArgs, ObjCSubstitutionContext context) const
Substitute type arguments for the Objective-C type parameters used in the subject type.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Base for LValueReferenceType and RValueReferenceType.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isInObjcMethodScope() const
isInObjcMethodScope - Return true if this scope is, or is contained in, an Objective-C method body.
static Selector constructSetterSelector(IdentifierTable &Idents, SelectorTable &SelTable, const IdentifierInfo *Name)
Return the default setter selector for the given identifier.
Smart pointer class that efficiently represents Objective-C method names.
std::string getAsString() const
Derive the full selector name (e.g.
ObjCMethodFamily getMethodFamily() const
Derive the conventional family of this method.
bool isUnarySelector() const
ObjCStringFormatFamily getStringFormatFamily() const
unsigned getNumArgs() const
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
DiagnosticsEngine & getDiagnostics() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
ObjCMessageKind getObjCMessageKind(Scope *S, IdentifierInfo *Name, SourceLocation NameLoc, bool IsSuper, bool HasTrailingDot, ParsedType &ReceiverType)
ObjCMethodDecl * ValueWithBytesObjCTypeMethod
The declaration of the valueWithBytes:objCType: method.
ExprResult BuildObjCDictionaryLiteral(SourceRange SR, MutableArrayRef< ObjCDictionaryElement > Elements)
ExprResult HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, Expr *BaseExpr, SourceLocation OpLoc, DeclarationName MemberName, SourceLocation MemberLoc, SourceLocation SuperLoc, QualType SuperType, bool Super)
HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an objective C interface.
ExprResult BuildInstanceMessage(Expr *Receiver, QualType ReceiverType, SourceLocation SuperLoc, Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args, bool isImplicit=false)
Build an Objective-C instance message expression.
const ObjCMethodDecl * SelectorsForTypoCorrection(Selector Sel, QualType ObjectType=QualType())
ExprResult ParseObjCSelectorExpression(Selector Sel, SourceLocation AtLoc, SourceLocation SelLoc, SourceLocation LParenLoc, SourceLocation RParenLoc, bool WarnMultipleSelectors)
ParseObjCSelectorExpression - Build selector expression for @selector.
ExprResult BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, QualType ReceiverType, SourceLocation SuperLoc, Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args, bool isImplicit=false)
Build an Objective-C class message expression.
ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number)
BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the numeric literal expression.
bool AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod, SourceRange R, bool receiverIdOrClass, SmallVectorImpl< ObjCMethodDecl * > &Methods)
ObjCMethodDecl * LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass=false)
LookupInstanceMethodInGlobalPool - Returns the method and warns if there are multiple signatures.
ExprResult ActOnObjCBridgedCast(Scope *S, SourceLocation LParenLoc, ObjCBridgeCastKind Kind, SourceLocation BridgeKeywordLoc, ParsedType Type, SourceLocation RParenLoc, Expr *SubExpr)
ObjCLiteralKind CheckLiteralKind(Expr *FromE)
ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc, TypeSourceInfo *EncodedTypeInfo, SourceLocation RParenLoc)
bool CheckObjCBridgeRelatedConversions(SourceLocation Loc, QualType DestType, QualType SrcType, Expr *&SrcExpr, bool Diagnose=true)
ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements)
ObjCInterfaceDecl * NSArrayDecl
The declaration of the Objective-C NSArray class.
ExprResult ActOnClassPropertyRefExpr(const IdentifierInfo &receiverName, const IdentifierInfo &propertyName, SourceLocation receiverNameLoc, SourceLocation propertyNameLoc)
void CheckObjCCircularContainer(ObjCMessageExpr *Message)
Check whether receiver is mutable ObjC container which attempts to add itself into the container.
ObjCInterfaceDecl * getObjCInterfaceDecl(const IdentifierInfo *&Id, SourceLocation IdLoc, bool TypoCorrection=false)
Look for an Objective-C class in the translation unit.
ObjCMethodDecl * LookupMethodInObjectType(Selector Sel, QualType Ty, bool IsInstance)
LookupMethodInType - Look up a method in an ObjCObjectType.
bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, ObjCMethodDecl *Method, ObjCIvarDecl *IV)
IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is an ivar synthesized for 'Meth...
ExprResult BuildClassMessageImplicit(QualType ReceiverType, bool isSuperReceiver, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)
ObjCInterfaceDecl * NSNumberDecl
The declaration of the Objective-C NSNumber class.
void CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr)
ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr)
BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the '@' prefixed parenthesized expression.
ObjCInterfaceDecl * NSValueDecl
The declaration of the Objective-C NSValue class.
Selector RespondsToSelectorSel
will hold 'respondsToSelector:'
bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method, const ObjCMethodDecl *PrevMethod, MethodMatchStrategy strategy=MMS_strict)
MatchTwoMethodDeclarations - Checks if two methods' type match and returns true, or false,...
bool CheckMessageArgumentTypes(const Expr *Receiver, QualType ReceiverType, MultiExprArg Args, Selector Sel, ArrayRef< SourceLocation > SelectorLocs, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage, SourceLocation lbrac, SourceLocation rbrac, SourceRange RecRange, QualType &ReturnType, ExprValueKind &VK)
CheckMessageArgumentTypes - Check types in an Obj-C message send.
ObjCInterfaceDecl * NSStringDecl
The declaration of the Objective-C NSString class.
llvm::MapVector< Selector, SourceLocation > ReferencedSelectors
Method selectors used in a @selector expression.
ObjCMethodDecl * LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass=false)
LookupFactoryMethodInGlobalPool - Returns the method and warns if there are multiple signatures.
ObjCMethodDecl * StringWithUTF8StringMethod
The declaration of the stringWithUTF8String: method.
bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall)
Check whether the given method, which must be in the 'init' family, is a valid member of that family.
QualType FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, SourceLocation QuestionLoc)
FindCompositeObjCPointerType - Helper method to find composite type of two objective-c pointer types ...
ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S)
ObjCInterfaceDecl * NSDictionaryDecl
The declaration of the Objective-C NSDictionary class.
ObjCMethodDecl * ArrayWithObjectsMethod
The declaration of the arrayWithObjects:count: method.
ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc, SourceLocation EncodeLoc, SourceLocation LParenLoc, ParsedType Ty, SourceLocation RParenLoc)
QualType QIDNSCopying
id<NSCopying> type.
bool CheckObjCString(Expr *Arg)
CheckObjCString - Checks that the argument to the builtin CFString constructor is correct Note: It mi...
ExprResult ActOnClassMessage(Scope *S, ParsedType Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr)
bool CheckConversionToObjCLiteral(QualType DstType, Expr *&SrcExpr, bool Diagnose=true)
ObjCMethodDecl * tryCaptureObjCSelf(SourceLocation Loc)
Try to capture an implicit reference to 'self'.
ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs, ArrayRef< Expr * > Strings)
ExprResult ActOnObjCBoolLiteral(SourceLocation AtLoc, SourceLocation ValueLoc, bool Value)
ObjCMethodDecl * DictionaryWithObjectsMethod
The declaration of the dictionaryWithObjects:forKeys:count: method.
QualType NSStringPointer
Pointer to NSString type (NSString *).
ExprResult BuildObjCBridgedCast(SourceLocation LParenLoc, ObjCBridgeCastKind Kind, SourceLocation BridgeKeywordLoc, TypeSourceInfo *TSInfo, Expr *SubExpr)
ObjCProtocolDecl * LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Find the protocol with the given name, if any.
QualType NSNumberPointer
Pointer to NSNumber type (NSNumber *).
DeclResult LookupIvarInObjCMethod(LookupResult &Lookup, Scope *S, IdentifierInfo *II)
The parser has read a name in, and Sema has detected that we're currently inside an ObjC method.
ObjCMethodDecl * NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods]
The Objective-C NSNumber methods used to create NSNumber literals.
GlobalMethodPool MethodPool
Method Pool - allows efficient lookup when typechecking messages to "id".
QualType getMessageSendResultType(const Expr *Receiver, QualType ReceiverType, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage)
Determine the result of a message send expression based on the type of the receiver,...
ExprResult ParseObjCProtocolExpression(IdentifierInfo *ProtocolName, SourceLocation AtLoc, SourceLocation ProtoLoc, SourceLocation LParenLoc, SourceLocation ProtoIdLoc, SourceLocation RParenLoc)
ParseObjCProtocolExpression - Build protocol expression for @protocol.
ExprResult BuildInstanceMessageImplicit(Expr *Receiver, QualType ReceiverType, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)
void checkRetainCycles(ObjCMessageExpr *msg)
checkRetainCycles - Check whether an Objective-C message send might create an obvious retain cycle.
ObjCMessageKind
Describes the kind of message expression indicated by a message send that starts with an identifier.
@ ObjCClassMessage
The message is a class message, and the identifier is a type name.
@ ObjCInstanceMessage
The message is an instance message.
@ ObjCSuperMessage
The message is sent to 'super'.
ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S, IdentifierInfo *II, bool AllowBuiltinCreation=false)
The parser has read a name in, and Sema has detected that we're currently inside an ObjC method.
QualType NSValuePointer
Pointer to NSValue type (NSValue *).
void EmitRelatedResultTypeNote(const Expr *E)
If the given expression involves a message send to a method with a related result type,...
ExprResult ActOnInstanceMessage(Scope *S, Expr *Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx)
ExprResult BuildIvarRefExpr(Scope *S, SourceLocation Loc, ObjCIvarDecl *IV)
ExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
CastKind PrepareCastToObjCObjectPointer(ExprResult &E)
Prepare a conversion of the given expression to an ObjC object pointer type.
bool CollectMultipleMethodsInGlobalPool(Selector Sel, SmallVectorImpl< ObjCMethodDecl * > &Methods, bool InstanceFirst, bool CheckTheOther, const ObjCObjectType *TypeBound=nullptr)
We first select the type of the method: Instance or Factory, then collect all methods with that type.
bool checkObjCBridgeRelatedComponents(SourceLocation Loc, QualType DestType, QualType SrcType, ObjCInterfaceDecl *&RelatedClass, ObjCMethodDecl *&ClassMethod, ObjCMethodDecl *&InstanceMethod, TypedefNameDecl *&TDNDecl, bool CfToNs, bool Diagnose=true)
void EmitRelatedResultTypeNoteForReturn(QualType destType)
Given that we had incompatible pointer types in a return statement, check whether we're in a method w...
void diagnoseARCUnbridgedCast(Expr *e)
Given that we saw an expression with the ARCUnbridgedCastTy placeholder type, complain bitterly.
ObjCMethodDecl * LookupMethodInQualifiedType(Selector Sel, const ObjCObjectPointerType *OPT, bool IsInstance)
LookupMethodInQualifiedType - Lookups up a method in protocol qualifier list of a qualified objective...
ARCConversionResult CheckObjCConversion(SourceRange castRange, QualType castType, Expr *&op, CheckedConversionKind CCK, bool Diagnose=true, bool DiagnoseCFAudited=false, BinaryOperatorKind Opc=BO_PtrMemD, bool IsReinterpretCast=false)
Checks for invalid conversions and casts between retainable pointers and other pointer kinds for ARC ...
bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, CastKind &Kind)
bool CheckObjCARCUnavailableWeakConversion(QualType castType, QualType ExprType)
bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, ArrayRef< const Expr * > Args)
Expr * stripARCUnbridgedCast(Expr *e)
stripARCUnbridgedCast - Given an expression of ARCUnbridgedCast type, remove the placeholder cast.
ExprResult BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr, Expr *IndexExpr, ObjCMethodDecl *getterMethod, ObjCMethodDecl *setterMethod)
Build an ObjC subscript pseudo-object expression, given that that's supported by the runtime.
bool isSelfExpr(Expr *RExpr)
Private Helper predicate to check for 'self'.
ExprResult ActOnObjCAvailabilityCheckExpr(llvm::ArrayRef< AvailabilitySpec > AvailSpecs, SourceLocation AtLoc, SourceLocation RParen)
bool isKnownName(StringRef name)
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
Sema - This implements semantic analysis and AST building for C.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
bool FormatStringHasSArg(const StringLiteral *FExpr)
NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Look up a name, looking for a single declaration.
ASTContext & getASTContext() const
ObjCMethodDecl * getCurMethodDecl()
getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
const LangOptions & getLangOpts() const
const LangOptions & LangOpts
ExprResult DefaultLvalueConversion(Expr *E)
static bool isCast(CheckedConversionKind CCK)
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
SourceManager & getSourceManager() const
bool makeUnavailableInSystemHeader(SourceLocation loc, UnavailableAttr::ImplicitReason reason)
makeUnavailableInSystemHeader - There is an error in the current context.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
SourceManager & SourceMgr
DiagnosticsEngine & Diags
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
CompoundStmt * getSubStmt()
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
SourceLocation getEndLoc() const LLVM_READONLY
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
tokloc_iterator tokloc_begin() const
tokloc_iterator tokloc_end() const
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, ArrayRef< SourceLocation > Locs)
This is the "fully general" constructor that allows representation of strings formed from one or more...
StringRef getString() const
The top declaration context.
Represents a declaration of a type.
SourceLocation getBeginLoc() const LLVM_READONLY
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
bool isBlockPointerType() const
const ObjCObjectPointerType * getAsObjCQualifiedClassType() const
bool isBooleanType() const
const ObjCObjectPointerType * getAsObjCQualifiedIdType() const
bool isObjCBuiltinType() const
bool isVoidPointerType() const
bool isObjCARCBridgableType() const
Determine whether the given type T is a "bridgable" Objective-C type, which is either an Objective-C ...
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool canHaveNullability(bool ResultIfUnknown=true) const
Determine whether the given type can have a nullability specifier applied to it, i....
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isCARCBridgableType() const
Determine whether the given type T is a "bridgeable" C type.
bool isObjCIdType() const
bool isObjCClassOrClassKindOfType() const
Whether the type is Objective-C 'Class' or a __kindof type of an Class type, e.g.,...
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isObjCObjectPointerType() const
bool isObjCQualifiedClassType() const
bool isObjCClassType() const
std::optional< ArrayRef< QualType > > getObjCSubstitutions(const DeclContext *dc) const
Retrieve the set of substitutions required when accessing a member of the Objective-C receiver type t...
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
const ObjCObjectType * getAsObjCInterfaceType() const
bool isAnyPointerType() const
bool isObjCIdOrObjectKindOfType(const ASTContext &ctx, const ObjCObjectType *&bound) const
Whether the type is Objective-C 'id' or a __kindof type of an object type, e.g., __kindof NSView * or...
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
bool isObjCRetainableType() const
NullabilityKindOrNone getNullability() const
Determine the nullability of the given type.
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Base class for declarations which introduce a typedef-name.
QualType getUnderlyingType() const
TypedefNameDecl * getDecl() const
Simple class containing the result of Sema::CorrectTypo.
DeclClass * getCorrectionDeclAs() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
static UnaryOperator * Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, FPOptionsOverride FPFeatures)
Represents a C++ unqualified-id that has been parsed.
void setImplicitSelfParam(const IdentifierInfo *Id)
Specify that this unqualified-id is an implicit 'self' parameter.
void setType(QualType newType)
bool isCommitable() const
edit_iterator edit_begin() const
SmallVectorImpl< Edit >::const_iterator edit_iterator
edit_iterator edit_end() const
Retains information about a function, method, or block that is currently being parsed.
bool ObjCIsDesignatedInit
True when this is a method marked as a designated initializer.
bool ObjCWarnForNoInitDelegation
This starts true for a secondary initializer method and will be set to false if there is an invocatio...
bool ObjCIsSecondaryInit
True when this is an initializer method not marked as a designated initializer within a class that ha...
bool ObjCWarnForNoDesignatedInitChain
This starts true for a method marked as designated initializer and will be set to false if there is a...
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
constexpr Variable var(Literal L)
Returns the variable of L.
bool rewriteObjCRedundantCallWithLiteral(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
bool followsCreateRule(const FunctionDecl *FD)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
@ Ambiguous
Name lookup results in an ambiguity; use getAmbiguityKind to figure out what kind of ambiguity we hav...
@ NotFound
No entity found met the criteria.
@ FoundOverloaded
Name lookup found a set of overloaded functions that met the criteria.
@ Found
Name lookup found a single declaration that met the criteria.
@ FoundUnresolvedValue
Name lookup found an unresolvable value declaration and cannot yet complete.
@ NotFoundInCurrentInstantiation
No entity found met the criteria within the current instantiation,, but there were dependent base cla...
NullabilityKind
Describes the nullability of a particular type.
@ Nullable
Values of this type can be null.
@ NonNull
Values of this type can never be null.
@ OK_ObjCProperty
An Objective-C property is a logical field of an Objective-C object which is read and written via Obj...
@ OK_ObjCSubscript
An Objective-C array/dictionary subscripting which reads an object or writes at the subscripted array...
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
ActionResult< Decl * > DeclResult
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
ObjCMethodFamily
A family of Objective-C methods.
@ OMF_None
No particular method family.
MutableArrayRef< Expr * > MultiExprArg
@ Parameter
The parameter type of a method or function.
@ Result
The result type of a method or function.
ObjCBridgeCastKind
The kind of bridging performed by the Objective-C bridge cast.
@ OBC_Bridge
Bridging via __bridge, which does nothing but reinterpret the bits.
@ OBC_BridgeTransfer
Bridging via __bridge_transfer, which transfers ownership of an Objective-C pointer into ARC.
@ OBC_BridgeRetained
Bridging via __bridge_retain, which makes an ARC object available as a +1 C pointer.
CastKind
CastKind - The kind of operation required for a conversion.
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
U cast(CodeGen::Address addr)
@ None
The alignment was not explicit in code.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
@ None
No keyword precedes the qualified type name.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
CheckedConversionKind
The kind of conversion being performed.
@ Implicit
An implicit conversion.
@ CStyleCast
A C-style cast.
@ ForBuiltinOverloadedOp
A conversion for an operand of a builtin overloaded operator.
@ OtherCast
A cast other than a C-style cast.
@ FunctionalCast
A functional-style cast.
OptionalUnsigned< NullabilityKind > NullabilityKindOrNone
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
EvalResult is a struct with detailed info about an evaluated expression.
An element in an Objective-C dictionary literal.
a linked list of methods with the same selector name but different signatures.
ObjCMethodDecl * getMethod() const
ObjCMethodList * getNext() const
CharSourceRange getFileRange(SourceManager &SM) const
CharSourceRange getInsertFromRange(SourceManager &SM) const