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);
441 bool ArrayLiteral =
false) {
461 return Seq.Perform(S, Entity, Kind, Element);
464 Expr *OrigElement = Element;
475 bool Recovered =
false;
504 else if (
StringLiteral *String = dyn_cast<StringLiteral>(OrigElement)) {
505 if (String->isOrdinary()) {
528 dyn_cast<ObjCStringLiteral>(OrigElement)) {
530 unsigned numConcat = SL->getNumConcatenated();
533 bool hasMacro =
false;
534 for (
unsigned i = 0; i < numConcat ; ++i)
535 if (SL->getStrTokenLoc(i).isMacroID()) {
541 diag::warn_concatenated_nsarray_literal)
572 const bool IsConstInitLiteral =
575 ValueExpr = RValue.
get();
579 if (Context.hasSameUnqualifiedType(PointeeType, Context.CharTy)) {
593 if (
auto *CE = dyn_cast<ImplicitCastExpr>(ValueExpr))
594 if (CE->getCastKind() == CK_ArrayToPointerDecay)
596 dyn_cast<StringLiteral>(CE->getSubExpr()->IgnoreParens())) {
597 assert((SL->isOrdinary() || SL->isUTF8()) &&
598 "unexpected character encoding");
599 StringRef Str = SL->getString();
600 const llvm::UTF8 *StrBegin = Str.bytes_begin();
601 const llvm::UTF8 *StrEnd = Str.bytes_end();
603 if (llvm::isLegalUTF8String(&StrBegin, StrEnd)) {
610 Diag(SL->getBeginLoc(), diag::warn_objc_boxing_invalid_utf8_string)
616 Selector stringWithUTF8String = Context.Selectors.getUnarySelector(II);
619 BoxingMethod =
NSStringDecl->lookupClassMethod(stringWithUTF8String);
620 if (!BoxingMethod &&
getLangOpts().DebuggerObjCLiteral) {
636 &Context.Idents.get(
"value"),
637 Context.getPointerType(ConstCharType),
645 stringWithUTF8String, BoxingMethod))
658 Context.getAttributedType(*Nullability, BoxedType, BoxedType);
660 }
else if (ValueType->isBuiltinType()) {
668 dyn_cast<CharacterLiteral>(ValueExpr->
IgnoreParens())) {
671 switch (Char->getKind()) {
674 ValueType = Context.CharTy;
678 ValueType = Context.getWideCharType();
682 ValueType = Context.Char16Ty;
686 ValueType = Context.Char32Ty;
693 }
else if (
const auto *ED = ValueType->getAsEnumDecl()) {
694 if (!ED->isComplete()) {
695 Diag(Loc, diag::err_objc_incomplete_boxed_expression_type)
702 }
else if (ValueType->isObjCBoxableRecordType()) {
720 const IdentifierInfo *II[] = {&Context.Idents.get(
"valueWithBytes"),
721 &Context.Idents.get(
"objCType")};
722 Selector ValueWithBytesObjCType = Context.Selectors.getSelector(2, II);
725 BoxingMethod =
NSValueDecl->lookupClassMethod(ValueWithBytesObjCType);
726 if (!BoxingMethod &&
getLangOpts().DebuggerObjCLiteral) {
745 &Context.Idents.get(
"bytes"),
746 Context.VoidPtrTy.withConst(),
749 Params.push_back(
bytes);
755 &Context.Idents.get(
"type"),
756 Context.getPointerType(ConstCharType),
759 Params.push_back(
type);
766 ValueWithBytesObjCType, BoxingMethod))
772 if (!ValueType.isTriviallyCopyableType(Context)) {
773 Diag(Loc, diag::err_objc_non_trivially_copyable_boxed_expression_type)
783 Diag(Loc, diag::err_objc_illegal_boxed_expression_type)
788 SemaRef.DiagnoseUseOfDecl(BoxingMethod, Loc);
791 if (ValueType->isObjCBoxableRecordType()) {
793 ConvertedValueExpr =
SemaRef.PerformCopyInitialization(
798 ValueExpr = ConvertedValueExpr.
get();
799 }
else if (BoxingMethod->
parameters().size() > 0) {
809 ValueExpr = ConvertedValueExpr.
get();
813 ObjCBoxedExpr(ValueExpr, BoxedType, BoxingMethod, IsConstInitLiteral, SR);
815 return SemaRef.MaybeBindToTemporary(BoxedExpr);
823 assert(!
getLangOpts().isSubscriptPointerArithmetic());
829 "base or index cannot have dependent type here");
847 getterMethod, setterMethod, RB);
864 QualType IdT = Context.getObjCIdType();
873 Context.getTranslationUnitDecl(),
false ,
882 &Context.Idents.get(
"objects"),
883 Context.getPointerType(IdT),
886 Params.push_back(objects);
890 &Context.Idents.get(
"cnt"),
891 Context.UnsignedLongTy,
894 Params.push_back(cnt);
895 Method->setMethodParams(Context, Params, {});
909 diag::note_objc_literal_method_param)
911 << Context.getPointerType(IdT.
withConst());
916 if (!
Method->parameters()[1]->getType()->isIntegerType()) {
920 diag::note_objc_literal_method_param)
922 <<
Method->parameters()[1]->getType()
936 bool ExpressibleAsConstantInitLiteral = LangOpts.ConstantNSArrayLiterals;
939 if (ExpressibleAsConstantInitLiteral &&
940 llvm::any_of(Elements,
942 ExpressibleAsConstantInitLiteral =
false;
945 if (LangOpts.ObjCConstantLiterals && Elements.size() == 0) {
947 "The current ABI doesn't support an empty constant NSArray "
949 ExpressibleAsConstantInitLiteral =
true;
954 Expr **ElementsBuffer = Elements.data();
955 for (
unsigned I = 0, N = Elements.size(); I != N; ++I) {
957 SemaRef, ElementsBuffer[I], RequiredType,
true);
961 ElementsBuffer[I] = Converted.
get();
965 if (ExpressibleAsConstantInitLiteral &&
967 !ElementsBuffer[I]->isConstantInitializer(Context)))
968 ExpressibleAsConstantInitLiteral =
false;
972 = Context.getObjCObjectPointerType(
977 ExpressibleAsConstantInitLiteral, SR);
979 return SemaRef.MaybeBindToTemporary(ArrayLiteral);
987 if (Literal->isValueDependent() || Literal->isTypeDependent())
993 struct APSIntCompare {
994 bool operator()(
const llvm::APSInt &LHS,
const llvm::APSInt &RHS)
const {
995 return llvm::APSInt::compareValues(LHS, RHS) < 0;
999 llvm::DenseMap<StringRef, SourceLocation> StringKeys;
1000 std::map<llvm::APSInt, SourceLocation, APSIntCompare> IntegralKeys;
1002 auto checkOneKey = [&](
auto &Map,
const auto &Key,
SourceLocation Loc) {
1003 auto Pair = Map.insert({Key, Loc});
1005 S.
Diag(Loc, diag::warn_nsdictionary_duplicate_key);
1006 S.
Diag(Pair.first->second, diag::note_nsdictionary_duplicate_key_here);
1010 for (
unsigned Idx = 0, End = Literal->getNumElements(); Idx != End; ++Idx) {
1011 Expr *Key = Literal->getKeyValueElement(Idx).Key->IgnoreParenImpCasts();
1013 if (
auto *StrLit = dyn_cast<ObjCStringLiteral>(Key)) {
1014 StringRef Bytes = StrLit->getString()->getBytes();
1016 checkOneKey(StringKeys, Bytes, Loc);
1019 if (
auto *BE = dyn_cast<ObjCBoxedExpr>(Key)) {
1020 Expr *Boxed = BE->getSubExpr();
1025 checkOneKey(StringKeys, Str->getBytes(), Loc);
1032 checkOneKey(IntegralKeys,
Result.Val.getInt(), Loc);
1049 if (!Literal->isExpressibleAsConstantInitializer())
1051 if (Literal->isValueDependent() || Literal->isTypeDependent())
1060 for (
unsigned Idx = 0, End = Literal->getNumElements(); Idx != End; ++Idx) {
1061 Expr *Key = Literal->getKeyValueElement(Idx).Key->IgnoreParenImpCasts();
1062 auto *StrLit = dyn_cast<ObjCStringLiteral>(Key);
1065 StringRef Bytes = StrLit->getString()->getBytes();
1066 const llvm::UTF8 *Begin = Bytes.bytes_begin();
1067 const llvm::UTF8 *End2 = Bytes.bytes_end();
1068 if (!llvm::isLegalUTF8String(&Begin, End2))
1069 S.
Diag(StrLit->getExprLoc(),
1070 diag::warn_objc_dictionary_ill_formed_utf8_key)
1071 << StrLit->getSourceRange();
1090 QualType IdT = Context.getObjCIdType();
1098 nullptr , Context.getTranslationUnitDecl(),
1108 &Context.Idents.get(
"objects"),
1109 Context.getPointerType(IdT),
1112 Params.push_back(objects);
1116 &Context.Idents.get(
"keys"),
1117 Context.getPointerType(IdT),
1120 Params.push_back(keys);
1124 &Context.Idents.get(
"cnt"),
1125 Context.UnsignedLongTy,
1128 Params.push_back(cnt);
1129 Method->setMethodParams(Context, Params, {});
1140 !Context.hasSameUnqualifiedType(PtrValue->
getPointeeType(), IdT)) {
1144 diag::note_objc_literal_method_param)
1146 << Context.getPointerType(IdT.
withConst());
1164 Context.ObjCBuiltinIdTy, {},
1178 diag::note_objc_literal_method_param)
1180 << Context.getPointerType(IdT.
withConst());
1191 diag::note_objc_literal_method_param)
1208 bool HasPackExpansions =
false;
1212 bool ExpressibleAsConstantInitLiteral = LangOpts.ConstantNSDictionaryLiterals;
1217 if (!ExpressibleAsConstantInitLiteral)
1219 if (Elem.Key->isValueDependent() || Elem.Value->isValueDependent())
1220 ExpressibleAsConstantInitLiteral =
false;
1224 if (LangOpts.ObjCConstantLiterals && Elements.size() == 0) {
1226 "The current ABI doesn't support an empty constant NSDictionary "
1228 ExpressibleAsConstantInitLiteral =
true;
1241 if (
Value.isInvalid())
1244 Element.Key = Key.
get();
1245 Element.Value =
Value.get();
1247 if (ExpressibleAsConstantInitLiteral &&
1248 !Element.Key->isConstantInitializer(Context))
1249 ExpressibleAsConstantInitLiteral =
false;
1252 if (ExpressibleAsConstantInitLiteral &&
1254 ExpressibleAsConstantInitLiteral =
false;
1258 if (ExpressibleAsConstantInitLiteral &&
1260 !Element.Value->isConstantInitializer(Context)))
1261 ExpressibleAsConstantInitLiteral =
false;
1263 if (Element.EllipsisLoc.isInvalid())
1266 if (!Element.Key->containsUnexpandedParameterPack() &&
1267 !Element.Value->containsUnexpandedParameterPack()) {
1268 Diag(Element.EllipsisLoc,
1269 diag::err_pack_expansion_without_parameter_packs)
1271 Element.Value->getEndLoc());
1275 HasPackExpansions =
true;
1278 QualType Ty = Context.getObjCObjectPointerType(
1283 ExpressibleAsConstantInitLiteral, SR);
1288 return SemaRef.MaybeBindToTemporary(DictionaryLiteral);
1298 StrTy = Context.DependentTy;
1302 if (
SemaRef.RequireCompleteType(AtLoc, EncodedType,
1303 diag::err_incomplete_type_objc_at_encode,
1309 Context.getObjCEncodingForType(EncodedType, Str,
nullptr, &NotEncodedT);
1310 if (!NotEncodedT.
isNull())
1311 Diag(AtLoc, diag::warn_incomplete_encoded_type)
1312 << EncodedType << NotEncodedT;
1316 StrTy = Context.getStringLiteralArrayType(Context.CharTy, Str.size());
1319 return new (Context)
ObjCEncodeExpr(StrTy, EncodedTypeInfo, AtLoc, RParenLoc);
1332 TInfo = Context.getTrivialTypeSourceInfo(
1333 EncodedType,
SemaRef.getLocForEndOfToken(LParenLoc));
1345 bool Warned =
false;
1348 if (MatchingMethodDecl == Method ||
1350 MatchingMethodDecl->
getSelector() != Method->getSelector())
1356 S.
Diag(AtLoc, diag::warn_multiple_selectors)
1359 S.
Diag(Method->getLocation(), diag::note_method_declared_at)
1360 << Method->getDeclName();
1362 S.
Diag(MatchingMethodDecl->
getLocation(), diag::note_method_declared_at)
1373 bool WarnMultipleSelectors) {
1374 if (!WarnMultipleSelectors ||
1377 bool Warned =
false;
1378 for (SemaObjC::GlobalMethodPool::iterator b = S.
ObjC().
MethodPool.begin(),
1384 Method, InstMethList))
1390 Method, ClsMethList) || Warned)
1406 assert(Method->getSelector() == Sel &&
"Method with wrong selector in method list");
1407 if (Method->isDirectMethod()) {
1409 DirectMethod = Method;
1414 return DirectMethod;
1429 S, Sel, Iter->second.first, onlyDirect, anyDirect);
1431 S, Sel, Iter->second.second, onlyDirect, anyDirect);
1433 return DirectInstance ? DirectInstance : DirectClass;
1469 Selector MatchedSel = OM->getSelector();
1472 Diag(SelKWLoc, diag::warn_undeclared_selector_with_typo)
1473 << Sel << MatchedSel
1478 Diag(SelKWLoc, diag::warn_undeclared_selector) << Sel;
1481 WarnMultipleSelectors);
1483 bool onlyDirect =
true;
1484 bool anyDirect =
false;
1489 Diag(AtLoc, diag::err_direct_selector_expression)
1490 <<
Method->getSelector();
1491 Diag(
Method->getLocation(), diag::note_direct_method_declared_at)
1492 <<
Method->getDeclName();
1493 }
else if (anyDirect) {
1499 if (LikelyTargetMethod && LikelyTargetMethod->
isDirectMethod()) {
1500 Diag(AtLoc, diag::warn_potentially_direct_selector_expression) << Sel;
1502 diag::note_direct_method_declared_at)
1504 }
else if (!LikelyTargetMethod) {
1507 Diag(AtLoc, diag::warn_strict_potentially_direct_selector_expression)
1510 diag::note_direct_method_declared_at)
1517 Method->getImplementationControl() !=
1519 !
SemaRef.getSourceManager().isInSystemHeader(
Method->getLocation()))
1531 Diag(AtLoc, diag::err_arc_illegal_selector) <<
1548 QualType Ty = Context.getObjCSelType();
1549 return new (Context)
ObjCSelectorExpr(Ty, Sel, AtLoc, SelNameLoc, RParenLoc);
1561 Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;
1565 Diag(ProtoLoc, diag::err_objc_non_runtime_protocol_in_protocol_expr)
1568 Diag(ProtoLoc, diag::err_atprotocol_protocol) << PDecl;
1574 QualType Ty = Context.getObjCProtoType();
1577 Ty = Context.getObjCObjectPointerType(Ty);
1578 return new (Context)
ObjCProtocolExpr(Ty, PDecl, AtLoc, ProtoIdLoc, RParenLoc);
1599 if (
auto nullability = AttributedType::stripOuterNullability(
T)) {
1600 if (
T == Context.getObjCInstanceType()) {
1601 return Context.getAttributedType(*nullability, Context.getObjCIdType(),
1602 Context.getObjCIdType());
1608 if (
T == Context.getObjCInstanceType())
1609 return Context.getObjCIdType();
1622 bool isClassMessage,
1623 bool isSuperMessage) {
1624 assert(Method &&
"Must have a method");
1625 if (!Method->hasRelatedResultType())
1626 return Method->getSendResultType(ReceiverType);
1634 if (
auto nullability =
1635 Method->getSendResultType(ReceiverType)->getNullability()) {
1637 (void)AttributedType::stripOuterNullability(
type);
1640 return Context.getAttributedType(*nullability,
type,
type);
1650 if (Method->isInstanceMethod() && isClassMessage)
1652 Method->getSendResultType(ReceiverType));
1656 if (isSuperMessage) {
1659 return transferNullability(
1660 Context.getObjCObjectPointerType(
1661 Context.getObjCInterfaceType(Class)));
1667 return transferNullability(Context.getObjCObjectPointerType(ReceiverType));
1673 Method->getSendResultType(ReceiverType));
1678 return transferNullability(ReceiverType);
1684 bool isClassMessage,
1685 bool isSuperMessage) {
1689 SemaRef, ReceiverType,
Method, isClassMessage, isSuperMessage);
1692 if (isClassMessage) {
1701 AttributedType::stripOuterNullability(
T);
1702 if (
T == Context.getObjCInstanceType()) {
1706 ->getDeclContext());
1708 QualType NewResultType = Context.getObjCObjectPointerType(
1711 NewResultType = Context.getAttributedType(*Nullability, NewResultType,
1713 return NewResultType;
1725 unsigned receiverNullabilityIdx = 0;
1729 receiverNullabilityIdx = 1 +
static_cast<unsigned>(*nullability);
1732 unsigned resultNullabilityIdx = 0;
1736 resultNullabilityIdx = 1 +
static_cast<unsigned>(*nullability);
1741 static const uint8_t
None = 0;
1742 static const uint8_t
NonNull = 1;
1745 static const uint8_t nullabilityMap[4][4] = {
1753 unsigned newResultNullabilityIdx
1754 = nullabilityMap[receiverNullabilityIdx][resultNullabilityIdx];
1755 if (newResultNullabilityIdx == resultNullabilityIdx)
1761 if (
auto attributed = dyn_cast<AttributedType>(resultType.
getTypePtr())) {
1762 resultType = attributed->getModifiedType();
1769 if (newResultNullabilityIdx > 0) {
1772 return Context.getAttributedType(newNullability, resultType, resultType);
1791 dyn_cast<ObjCCategoryImplDecl>(impl)) {
1792 iface = catImpl->getCategoryDecl();
1794 iface = impl->getClassInterface();
1804 for (
unsigned i = 0, e = overrides.size(); i != e; ++i) {
1819 Context.hasSameUnqualifiedType(destType, MD->
getReturnType()))
1826 SourceRange range = overridden->getReturnTypeSourceRange();
1829 loc = overridden->getLocation();
1830 Diag(loc, diag::note_related_result_type_explicit)
1854 if (!
Method->hasRelatedResultType())
1857 if (Context.hasSameUnqualifiedType(
1858 Method->getReturnType().getNonReferenceType(), MsgSend->
getType()))
1861 if (!Context.hasSameUnqualifiedType(
Method->getReturnType(),
1862 Context.getObjCInstanceType()))
1865 Diag(
Method->getLocation(), diag::note_related_result_type_inferred)
1878 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
1879 SelLoc = SelectorLocs.front();
1885 for (
unsigned i = 0, e = Args.size(); i != e; i++) {
1886 if (Args[i]->isTypeDependent())
1892 result =
SemaRef.checkUnknownAnyArg(SelLoc, Args[i], paramTy);
1894 result =
SemaRef.DefaultArgumentPromotion(Args[i]);
1898 Args[i] = result.
get();
1903 DiagID = diag::err_arc_method_not_found;
1905 DiagID = isClassMessage ? diag::warn_class_method_not_found
1906 : diag::warn_inst_method_not_found;
1911 DiagID = diag::err_method_not_found_with_typo;
1913 DiagID = isClassMessage ? diag::warn_class_method_not_found_with_typo
1914 : diag::warn_instance_method_not_found_with_typo;
1916 SourceRange SelectorRange(SelectorLocs.front(), SelectorLocs.back());
1918 Diag(SelLoc, DiagID)
1919 << Sel<< isClassMessage << MatchedSel
1922 Diag(SelLoc, DiagID) << Sel<< isClassMessage << MatchedSel;
1925 Diag(SelLoc, DiagID)
1926 << Sel << isClassMessage <<
SourceRange(SelectorLocs.front(),
1927 SelectorLocs.back());
1931 Diag(ThisClass->getLocation(), diag::note_receiver_class_declared);
1933 if (ThisClass->lookupClassMethod(Sel))
1934 Diag(RecRange.
getBegin(), diag::note_receiver_expr_here)
1936 ThisClass->getNameAsString());
1944 ReturnType = Context.UnknownAnyTy;
1946 ReturnType = Context.getObjCIdType();
1953 isClassMessage, isSuperMessage);
1960 NumNamedArgs =
Method->param_size();
1962 if (Args.size() < NumNamedArgs) {
1963 Diag(SelLoc, diag::err_typecheck_call_too_few_args)
1964 << 2 << NumNamedArgs << static_cast<unsigned>(Args.size())
1971 std::optional<ArrayRef<QualType>> typeArgs =
1973 bool IsError =
false;
1974 for (
unsigned i = 0; i < NumNamedArgs; i++) {
1976 if (Args[i]->isTypeDependent())
1979 Expr *argExpr = Args[i];
1982 assert(argExpr &&
"CheckMessageArgumentTypes(): missing expression");
1984 if (param->
hasAttr<NoEscapeAttr>() &&
1986 if (
auto *BE = dyn_cast<BlockExpr>(
1988 BE->getBlockDecl()->setDoesNotEscape();
1993 !param->
hasAttr<CFConsumedAttr>())
1998 if (param->
getType() == Context.UnknownAnyTy) {
2004 Args[i] = argE.
get();
2020 if (
SemaRef.RequireCompleteType(
2022 diag::err_call_incomplete_argument, argExpr))
2038 Args[i]->getType()->isBlockPointerType() &&
2041 SemaRef.maybeExtendBlockObject(arg);
2042 Args[i] = arg.get();
2048 if (
Method->isVariadic()) {
2049 for (
unsigned i = NumNamedArgs, e = Args.size(); i < e; ++i) {
2050 if (Args[i]->isTypeDependent())
2056 Args[i] = Arg.
get();
2060 if (Args.size() != NumNamedArgs) {
2061 Diag(Args[NumNamedArgs]->getBeginLoc(),
2062 diag::err_typecheck_call_too_many_args)
2063 << 2 << NumNamedArgs << static_cast<unsigned>(Args.size())
2064 <<
Method->getSourceRange() << 0
2066 Args.back()->getEndLoc());
2082 SemaRef.CurContext->getNonClosureAncestor());
2087 if (!method)
return false;
2090 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(receiver))
2102 if (
ObjCMethodDecl *method = iface->lookupMethod(sel, isInstance))
2107 if (
ObjCMethodDecl *method = iface->lookupPrivateMethod(sel, isInstance))
2112 for (
const auto *I : objType->quals())
2124 for (
const auto *PROTO : OPT->
quals()) {
2125 if ((MD = PROTO->lookupMethod(Sel, Instance))) {
2140 assert(IFaceT &&
"Expected an Interface");
2144 Diag(MemberLoc, diag::err_invalid_property_name)
2154 diag::err_property_not_found_forward_class,
2155 MemberName, BaseRange))
2161 if (
SemaRef.DiagnoseUseOfDecl(PD, MemberLoc))
2164 return new (Context)
2168 return new (Context)
2173 for (
const auto *I : OPT->
quals())
2177 if (
SemaRef.DiagnoseUseOfDecl(PD, MemberLoc))
2183 SuperLoc, SuperType);
2185 return new (Context)
2208 if (
SemaRef.DiagnoseUseOfDecl(Getter, MemberLoc))
2227 if (Setter &&
SemaRef.DiagnoseUseOfDecl(Setter, MemberLoc))
2239 if (!(PDecl->getPropertyAttributes() &
2242 diag::warn_property_access_suggest)
2243 << MemberName <<
QualType(OPT, 0) << PDecl->getName()
2248 if (Getter || Setter) {
2250 return new (Context)
2254 return new (Context)
2271 Corrected.isKeyword() ?
nullptr : Corrected.getFoundDecl();
2276 Diag(MemberLoc, diag::err_class_property_found) << MemberName
2283 SemaRef.diagnoseTypo(Corrected,
2284 PDiag(diag::err_property_not_found_suggest)
2285 << MemberName <<
QualType(OPT, 0));
2287 TypoResult, MemberLoc,
2288 SuperLoc, SuperType, Super);
2296 T->getAsObjCInterfacePointerType()) {
2297 if (
SemaRef.RequireCompleteType(MemberLoc, OBJPT->getPointeeType(),
2298 diag::err_property_not_as_forward_class,
2299 MemberName, BaseExpr))
2303 diag::err_ivar_access_using_property_syntax_suggest)
2304 << MemberName <<
QualType(OPT, 0) << Ivar->getDeclName()
2309 Diag(MemberLoc, diag::err_property_not_found)
2329 if (receiverNamePtr->
isStr(
"super")) {
2331 if (
auto classDecl = CurMethod->getClassInterface()) {
2332 SuperType =
QualType(classDecl->getSuperClassType(), 0);
2333 if (CurMethod->isInstanceMethod()) {
2334 if (SuperType.
isNull()) {
2336 Diag(receiverNameLoc, diag::err_root_class_cannot_use_super)
2337 << CurMethod->getClassInterface()->getIdentifier();
2340 QualType T = Context.getObjCObjectPointerType(SuperType);
2347 receiverNameLoc,
T,
true);
2358 Diag(receiverNameLoc, diag::err_expected_either) << tok::identifier
2368 GetterSel = PD->getGetterName();
2369 SetterSel = PD->getSetterName();
2371 GetterSel =
SemaRef.PP.getSelectorTable().getNullarySelector(&propertyName);
2387 if (
SemaRef.DiagnoseUseOfDecl(Getter, propertyNameLoc))
2402 if (Setter &&
SemaRef.DiagnoseUseOfDecl(Setter, propertyNameLoc))
2405 if (Getter || Setter) {
2407 return new (Context)
2414 propertyNameLoc, receiverNameLoc, IFace);
2416 return ExprError(
Diag(propertyNameLoc, diag::err_property_not_found)
2417 << &propertyName << Context.getObjCInterfaceType(IFace));
2427 WantObjCSuper =
Method->getClassInterface()->getSuperClass();
2430 bool ValidateCandidate(
const TypoCorrection &candidate)
override {
2435 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
2436 return std::make_unique<ObjCInterfaceOrSuperCCC>(*
this);
2445 bool HasTrailingDot,
ParsedType &ReceiverType) {
2447 ReceiverType =
nullptr;
2458 switch (
Result.getResultKind()) {
2465 if (!
Method->getClassInterface()) {
2471 if (
Method->getClassInterface()->lookupInstanceVariable(Name,
2483 Result.suppressDiagnostics();
2496 T = Context.getObjCInterfaceType(
Class);
2500 std::nullopt,
Type);
2506 TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(
T, NameLoc);
2507 ReceiverType =
SemaRef.CreateParsedType(
T, TSInfo);
2512 ObjCInterfaceOrSuperCCC CCC(
SemaRef.getCurMethodDecl());
2514 Result.getLookupNameInfo(),
Result.getLookupKind(), S,
nullptr, CCC,
2516 if (Corrected.isKeyword()) {
2519 SemaRef.diagnoseTypo(Corrected,
PDiag(diag::err_unknown_receiver_suggest)
2526 SemaRef.diagnoseTypo(Corrected,
PDiag(diag::err_unknown_receiver_suggest)
2529 TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(
T, NameLoc);
2530 ReceiverType =
SemaRef.CreateParsedType(
T, TSInfo);
2548 Diag(SuperLoc, diag::err_invalid_receiver_to_message_super);
2554 Diag(SuperLoc, diag::err_no_super_class_message)
2555 <<
Method->getDeclName();
2562 Diag(SuperLoc, diag::err_root_class_cannot_use_super)
2563 <<
Class->getIdentifier();
2569 if (
Method->getSelector() == Sel)
2570 SemaRef.getCurFunction()->ObjCShouldCallSuper =
false;
2572 if (
Method->isInstanceMethod()) {
2575 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2578 LBracLoc, SelectorLocs, RBracLoc, Args);
2585 SuperLoc, Sel,
nullptr,
2586 LBracLoc, SelectorLocs, RBracLoc, Args);
2590 bool isSuperReceiver,
2596 if (!ReceiverType.
isNull())
2597 receiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType);
2599 assert(((isSuperReceiver && Loc.
isValid()) || receiverTypeInfo) &&
2600 "Either the super receiver location needs to be valid or the receiver "
2601 "needs valid type source information");
2604 Sel,
Method, Loc, Loc, Loc, Args,
2619 auto Builder = S.
Diag(MsgLoc, DiagID)
2627 switch (Edit.
Kind) {
2634 Builder.AddFixItHint(
2655 bool IsClassObjectCall) {
2661 const auto *SE = dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens());
2665 if (!IsClassObjectCall) {
2667 if (!OPT || !OPT->getInterfaceDecl())
2670 OPT->getInterfaceDecl()->lookupInstanceMethod(SE->getSelector());
2673 OPT->getInterfaceDecl()->lookupPrivateMethod(SE->getSelector());
2678 ImpliedMethod = IT->getDecl()->lookupClassMethod(SE->getSelector());
2681 IT->getDecl()->lookupPrivateClassMethod(SE->getSelector());
2686 if (Ret->isRecordType() || Ret->isVectorType() || Ret->isExtVectorType()) {
2687 S.
Diag(Loc, diag::warn_objc_unsafe_perform_selector)
2688 << Method->getSelector()
2689 << (!Ret->isRecordType()
2691 : Ret->isUnionType() ? 1 : 0);
2693 diag::note_objc_unsafe_perform_selector_method_declared_here)
2704 Expr **Args,
unsigned NumArgs) {
2706 bool Format =
false;
2713 for (
const auto *I : Method->specific_attrs<FormatAttr>()) {
2720 if (!Format || NumArgs <= Idx)
2723 Expr *FormatExpr = Args[Idx];
2728 S.
Diag(FormatExpr->
getExprLoc(), diag::warn_objc_cdirective_format_string)
2731 S.
Diag(Method->getLocation(), diag::note_method_declared_at)
2732 << Method->getDeclName();
2774 Diag(Loc, diag::err_missing_open_square_message_send)
2779 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
2780 SelectorSlotLocs = SelectorLocs;
2782 SelectorSlotLocs = Loc;
2788 unsigned NumArgs = ArgsIn.size();
2789 Expr **Args = ArgsIn.data();
2790 assert(SuperLoc.
isInvalid() &&
"Message to super with dependent type");
2792 ReceiverTypeInfo, Sel, SelectorLocs,
2794 RBracLoc, isImplicit);
2800 if (!ClassType || !(
Class = ClassType->getInterface())) {
2801 Diag(Loc, diag::err_invalid_receiver_class_message)
2805 assert(
Class &&
"We don't know which class we're messaging?");
2808 (void)
SemaRef.DiagnoseUseOfDecl(
Class, SelectorSlotLocs);
2814 if (
SemaRef.RequireCompleteType(Loc, Context.getObjCInterfaceType(
Class),
2816 ? diag::err_arc_receiver_forward_class
2817 : diag::warn_receiver_forward_class),
2823 Diag(
Method->getLocation(), diag::note_method_sent_forward_class)
2824 <<
Method->getDeclName();
2834 false,
false,
Class))
2842 unsigned NumArgs = ArgsIn.size();
2843 Expr **Args = ArgsIn.data();
2850 if (
Method && !
Method->getReturnType()->isVoidType() &&
2852 LBracLoc,
Method->getReturnType(),
2853 diag::err_illegal_message_expr_incomplete_type))
2857 Diag(SuperLoc, diag::err_messaging_super_with_direct_method)
2861 :
Method->getClassInterface()->getName());
2862 Diag(
Method->getLocation(), diag::note_direct_method_declared_at)
2863 <<
Method->getDeclName();
2870 dyn_cast<ObjCInterfaceDecl>(
Method->getDeclContext());
2872 Diag(Loc, diag::warn_direct_initialize_call);
2873 Diag(
Method->getLocation(), diag::note_method_declared_at)
2874 <<
Method->getDeclName();
2879 Diag(Loc, diag::warn_direct_super_initialize_call);
2880 Diag(
Method->getLocation(), diag::note_method_declared_at)
2881 <<
Method->getDeclName();
2882 Diag(CurMeth->getLocation(), diag::note_method_declared_at)
2883 << CurMeth->getDeclName();
2894 Context, ReturnType,
VK, LBracLoc, SuperLoc,
false,
2895 ReceiverType, Sel, SelectorLocs,
Method,
ArrayRef(Args, NumArgs),
2896 RBracLoc, isImplicit);
2899 Context, ReturnType,
VK, LBracLoc, ReceiverTypeInfo, Sel, SelectorLocs,
2906 ReceiverType,
true);
2921 SemaRef.GetTypeFromParser(Receiver, &ReceiverTypeInfo);
2922 if (ReceiverType.
isNull())
2925 if (!ReceiverTypeInfo)
2926 ReceiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType, LBracLoc);
2930 nullptr, LBracLoc, SelectorLocs, RBracLoc,
2939 Sel,
Method, Loc, Loc, Loc, Args,
2946 const auto *Protocol = dyn_cast<ObjCProtocolDecl>(M->
getDeclContext());
2951 if (
const auto *RootClass = dyn_cast_or_null<ObjCInterfaceDecl>(
2955 if (P->getCanonicalDecl() == Protocol->getCanonicalDecl())
2995 assert((Receiver || SuperLoc.
isValid()) &&
"If the Receiver is null, the "
2996 "SuperLoc must be valid so we can "
3005 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
3006 SelectorSlotLocs = SelectorLocs;
3008 SelectorSlotLocs = Loc;
3012 Diag(Loc, diag::err_missing_open_square_message_send)
3022 if (Receiver->
getType() == Context.UnknownAnyTy)
3024 SemaRef.forceUnknownAnyToType(Receiver, Context.getObjCIdType());
3034 unsigned NumArgs = ArgsIn.size();
3035 Expr **Args = ArgsIn.data();
3036 assert(SuperLoc.
isInvalid() &&
"Message to super with dependent type");
3038 Context, Context.DependentTy,
VK_PRValue, LBracLoc, Receiver, Sel,
3039 SelectorLocs,
nullptr,
ArrayRef(Args, NumArgs), RBracLoc,
3049 ReceiverType = Receiver->
getType();
3057 !Context.getObjCIdType().isNull() &&
3062 Diag(Loc, diag::warn_bad_receiver_type) << ReceiverType << RecRange;
3065 .ImpCastExprToType(Receiver, Context.getObjCIdType(),
3066 CK_CPointerToObjCPointerCast)
3072 CastKind Kind =
IsNull ? CK_NullToPointer : CK_IntegralToPointer;
3074 SemaRef.ImpCastExprToType(Receiver, Context.getObjCIdType(), Kind)
3077 ReceiverType = Receiver->
getType();
3081 diag::err_incomplete_receiver_type))
3085 SemaRef.PerformContextuallyConvertToObjCPointer(Receiver);
3087 Receiver = result.
get();
3088 ReceiverType = Receiver->
getType();
3104 (Receiver && Context.isObjCNSObjectType(Receiver->
getType()))) {
3109 if (!Methods.empty()) {
3115 Sel, ArgsIn,
Method->isInstanceMethod(), Methods))
3120 receiverIsIdLike, Methods))
3138 Diag(SelLoc, diag::warn_instance_method_on_class_found)
3139 <<
Method->getSelector() << Sel;
3140 Diag(
Method->getLocation(), diag::note_method_declared_at)
3141 <<
Method->getDeclName();
3151 Method = ClassDecl->lookupClassMethod(Sel);
3154 Method = ClassDecl->lookupPrivateClassMethod(Sel);
3169 if (!Methods.empty()) {
3175 if (
Method->isInstanceMethod()) {
3177 dyn_cast<ObjCInterfaceDecl>(
Method->getDeclContext())) {
3178 if (ID->getSuperClass())
3179 Diag(SelLoc, diag::warn_root_inst_method_not_found)
3185 Sel, ArgsIn,
Method->isInstanceMethod(), Methods))
3208 ClassDecl = OCIType->getInterfaceDecl();
3215 if (
SemaRef.RequireCompleteType(
3216 Loc, OCIType->getPointeeType(),
3218 ? diag::err_arc_receiver_forward_instance
3219 : diag::warn_receiver_forward_instance,
3224 forwardClass = OCIType->getInterfaceDecl();
3226 diag::note_receiver_is_id);
3241 Diag(SelLoc, diag::err_arc_may_not_respond)
3242 << OCIType->getPointeeType() << Sel << RecRange
3243 <<
SourceRange(SelectorLocs.front(), SelectorLocs.back());
3251 if (OCIType->qual_empty()) {
3256 if (!Methods.empty()) {
3262 Sel, ArgsIn,
Method->isInstanceMethod(), Methods))
3270 if (
Method && !forwardClass)
3271 Diag(SelLoc, diag::warn_maynot_respond)
3272 << OCIType->getInterfaceDecl()->getIdentifier()
3278 SemaRef.DiagnoseUseOfDecl(
Method, SelectorSlotLocs, forwardClass))
3282 Diag(Loc, diag::err_bad_receiver_type) << ReceiverType << RecRange;
3290 ?
SemaRef.getEnclosingFunction()
3296 diag::err_messaging_unqualified_id_with_direct_method);
3297 Diag(
Method->getLocation(), diag::note_direct_method_declared_at)
3298 <<
Method->getDeclName();
3308 diag::err_messaging_class_with_direct_method);
3311 RecRange,
Method->getClassInterface()->getName()));
3314 Diag(
Method->getLocation(), diag::note_direct_method_declared_at)
3315 <<
Method->getDeclName();
3321 Diag(SuperLoc, diag::err_messaging_super_with_direct_method);
3324 SuperLoc,
Method->getClassInterface()->getName()));
3329 Diag(
Method->getLocation(), diag::note_direct_method_declared_at)
3330 <<
Method->getDeclName();
3332 }
else if (ReceiverType->
isObjCIdType() && !isImplicit) {
3333 Diag(Receiver->
getExprLoc(), diag::warn_messaging_unqualified_id);
3336 if (DIFunctionScopeInfo &&
3339 bool isDesignatedInitChain =
false;
3346 if (!ID->declaresOrInheritsDesignatedInitializers() ||
3347 ID->isDesignatedInitializer(Sel)) {
3348 isDesignatedInitChain =
true;
3354 if (!isDesignatedInitChain) {
3356 auto *CurMD =
SemaRef.getCurMethodDecl();
3357 assert(CurMD &&
"Current method declaration should not be null");
3359 CurMD->isDesignatedInitializerForTheInterface(&InitMethod);
3360 assert(isDesignated && InitMethod);
3363 diag::warn_objc_designated_init_non_designated_init_call :
3364 diag::warn_objc_designated_init_non_super_designated_init_call);
3366 diag::note_objc_designated_init_marked_here);
3370 if (DIFunctionScopeInfo &&
3374 Diag(SelLoc, diag::warn_objc_secondary_init_super_init_call);
3381 unsigned NumArgs = ArgsIn.size();
3382 Expr **Args = ArgsIn.data();
3390 LBracLoc, RBracLoc, RecRange, ReturnType,
VK))
3393 if (
Method && !
Method->getReturnType()->isVoidType() &&
3395 LBracLoc,
Method->getReturnType(),
3396 diag::err_illegal_message_expr_incomplete_type))
3425 Diag(SelLoc, diag::err_arc_illegal_explicit_message)
3430 if (
Method && NumArgs >= 1) {
3431 if (
const auto *SelExp =
3432 dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens())) {
3433 Selector ArgSel = SelExp->getSelector();
3436 SelExp->getSourceRange());
3440 SelExp->getSourceRange());
3443 switch (SelFamily) {
3450 if (!SelMethod->
hasAttr<NSReturnsNotRetainedAttr>()) {
3453 diag::err_arc_perform_selector_retains);
3460 if (SelMethod->
hasAttr<NSReturnsRetainedAttr>()) {
3463 diag::err_arc_perform_selector_retains);
3472 Diag(SelLoc, diag::warn_arc_perform_selector_leaks);
3473 Diag(Args[0]->getExprLoc(), diag::note_used_here);
3486 Context, ReturnType,
VK, LBracLoc, SuperLoc,
true,
3487 ReceiverType, Sel, SelectorLocs,
Method,
ArrayRef(Args, NumArgs),
3488 RBracLoc, isImplicit);
3491 Context, ReturnType,
VK, LBracLoc, Receiver, Sel, SelectorLocs,
Method,
3492 ArrayRef(Args, NumArgs), RBracLoc, isImplicit);
3497 bool IsClassObjectCall = ClassMessage;
3504 if (OPT->getObjectType()->isObjCClass()) {
3505 if (
const auto *CurMeth =
SemaRef.getCurMethodDecl()) {
3506 IsClassObjectCall =
true;
3508 Context.getObjCInterfaceType(CurMeth->getClassInterface());
3514 ReceiverType, IsClassObjectCall);
3527 Result->setDelegateInitCall(
true);
3538 if (!isImplicit &&
Method) {
3544 if (IsWeak && !
SemaRef.isUnevaluatedContext() &&
3583 SemaRef.MaybeConvertParenListExprToParenExpr(S, Receiver);
3589 IdentifierInfo *SelectorId = &Context.Idents.get(
"respondsToSelector");
3597 nullptr, LBracLoc, SelectorLocs,
3631 bool isIndirect =
false;
3635 type = ref->getPointeeType();
3642 type = ptr->getPointeeType();
3649 }
else if (
const ArrayType *array =
type->getAsArrayTypeUnsafe()) {
3650 type =
QualType(array->getElementType()->getBaseElementTypeUnsafe(), 0);
3658 if (
type->isObjCARCBridgableType())
3663 if (
type->isObjCARCBridgableType())
3684 ACCResult
merge(ACCResult left, ACCResult right) {
3685 if (left == right)
return left;
3686 if (left == ACC_bottom)
return right;
3687 if (right == ACC_bottom)
return left;
3693 class ARCCastChecker :
public StmtVisitor<ARCCastChecker, ACCResult> {
3694 typedef StmtVisitor<ARCCastChecker, ACCResult> super;
3696 ASTContext &Context;
3701 static bool isCFType(QualType
type) {
3703 return type->isCARCBridgableType();
3709 : Context(Context), SourceClass(source), TargetClass(target),
3710 Diagnose(diagnose) {}
3713 ACCResult Visit(Expr *e) {
3717 ACCResult VisitStmt(Stmt *s) {
3722 ACCResult VisitExpr(Expr *e) {
3729 ACCResult VisitObjCObjectLiteral(ObjCObjectLiteral *OL) {
3738 ACCResult VisitObjCStringLiteral(ObjCStringLiteral *SL) {
3739 return VisitObjCObjectLiteral(SL);
3742 ACCResult VisitObjCBoxedExpr(ObjCBoxedExpr *OBE) {
3743 return VisitObjCObjectLiteral(OBE);
3746 ACCResult VisitObjCArrayLiteral(ObjCArrayLiteral *AL) {
3747 return VisitObjCObjectLiteral(AL);
3750 ACCResult VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *DL) {
3751 return VisitObjCObjectLiteral(DL);
3755 ACCResult VisitCastExpr(
CastExpr *e) {
3757 case CK_NullToPointer:
3761 case CK_LValueToRValue:
3763 case CK_CPointerToObjCPointerCast:
3764 case CK_BlockPointerToObjCPointerCast:
3765 case CK_AnyPointerToBlockPointerCast:
3774 ACCResult VisitUnaryExtension(UnaryOperator *e) {
3779 ACCResult VisitBinComma(BinaryOperator *e) {
3780 return Visit(e->
getRHS());
3784 ACCResult VisitConditionalOperator(ConditionalOperator *e) {
3786 if (left == ACC_invalid)
return ACC_invalid;
3791 ACCResult VisitPseudoObjectExpr(PseudoObjectExpr *e) {
3797 ACCResult VisitStmtExpr(StmtExpr *e) {
3802 ACCResult VisitDeclRefExpr(DeclRefExpr *e) {
3803 VarDecl *
var = dyn_cast<VarDecl>(e->
getDecl());
3808 !
var->hasDefinition(Context) &&
3809 var->getType().isConstQualified()) {
3816 return ACC_plusZero;
3824 ACCResult VisitCallExpr(CallExpr *e) {
3826 if (ACCResult result = checkCallToFunction(fn))
3829 return super::VisitCallExpr(e);
3832 ACCResult checkCallToFunction(FunctionDecl *fn) {
3841 if (fn->
hasAttr<CFReturnsNotRetainedAttr>())
3842 return ACC_plusZero;
3847 if (fn->
hasAttr<CFReturnsRetainedAttr>())
3848 return Diagnose ? ACC_plusOne
3853 if (builtinID == Builtin::BI__builtin___CFStringMakeConstantString)
3857 if (!fn->
hasAttr<CFAuditedTransferAttr>())
3862 return Diagnose ? ACC_plusOne
3865 return ACC_plusZero;
3868 ACCResult VisitObjCMessageExpr(ObjCMessageExpr *e) {
3872 ACCResult VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *e) {
3873 ObjCMethodDecl *method;
3878 return checkCallToMethod(method);
3881 ACCResult checkCallToMethod(ObjCMethodDecl *method) {
3882 if (!method)
return ACC_invalid;
3891 if (method->
hasAttr<CFReturnsNotRetainedAttr>())
3892 return ACC_plusZero;
3896 if (method->
hasAttr<CFReturnsRetainedAttr>())
3908 return ACC_plusZero;
3923template <
typename DiagBuilderT>
3927 Expr *realCast,
const char *bridgeKeyword,
const char *CFBridgeName) {
3943 NCE->getAngleBrackets().getEnd());
3947 char PrevChar = *SM.
getCharacterData(range.getBegin().getLocWithOffset(-1));
3951 BridgeCall += CFBridgeName;
3958 castedE = CCE->getSubExpr();
3965 char PrevChar = *SM.
getCharacterData(range.getBegin().getLocWithOffset(-1));
3969 BridgeCall += CFBridgeName;
3989 std::string castCode =
"(";
3990 castCode += bridgeKeyword;
3994 NCE->getAngleBrackets().getEnd());
3998 std::string castCode =
"(";
3999 castCode += bridgeKeyword;
4018template <
typename T>
4025 for (
auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) {
4026 if (
auto *
attr = Redecl->getAttr<
T>())
4037 TDNDecl = TD->getDecl();
4038 if (ObjCBridgeRelatedAttr *ObjCBAttr =
4056 UnavailableAttr::IR_ARCForbiddenConversion))
4069 unsigned srcKind = 0;
4093 S.
Diag(loc, diag::err_arc_cast_requires_bridge)
4102 ACCResult CreateRule =
4104 assert(CreateRule != ACC_bottom &&
"This cast should already be accepted.");
4105 if (CreateRule != ACC_plusOne)
4108 ? S.
Diag(noteLoc, diag::note_arc_bridge)
4109 : S.
Diag(noteLoc, diag::note_arc_cstyle_bridge);
4112 castType,
castExpr, realCast,
"__bridge ",
4115 if (CreateRule != ACC_plusZero)
4118 ? S.
Diag(noteLoc, diag::note_arc_cstyle_bridge_transfer)
4121 diag::note_arc_bridge_transfer)
4122 << castExprType << br;
4125 castType,
castExpr, realCast,
"__bridge_transfer ",
4126 br ?
"CFBridgingRelease" :
nullptr);
4135 S.
Diag(loc, diag::err_arc_cast_requires_bridge)
4143 ACCResult CreateRule =
4145 assert(CreateRule != ACC_bottom &&
"This cast should already be accepted.");
4146 if (CreateRule != ACC_plusOne)
4149 ? S.
Diag(noteLoc, diag::note_arc_bridge)
4150 : S.
Diag(noteLoc, diag::note_arc_cstyle_bridge);
4152 castType,
castExpr, realCast,
"__bridge ",
4155 if (CreateRule != ACC_plusZero)
4158 ? S.
Diag(noteLoc, diag::note_arc_cstyle_bridge_retained)
4161 diag::note_arc_bridge_retained)
4165 castType,
castExpr, realCast,
"__bridge_retained ",
4166 br ?
"CFBridgingRetain" :
nullptr);
4172 S.
Diag(loc, diag::err_arc_mismatched_cast)
4174 << srcKind << castExprType << castType
4175 << castRange <<
castExpr->getSourceRange();
4178template <
typename TB>
4180 bool &HadTheAttribute,
bool warn) {
4182 HadTheAttribute =
false;
4187 HadTheAttribute =
true;
4188 if (Parm->isStr(
"id"))
4201 = InterfacePointerType->getObjectType()->getInterface();
4202 if ((CastClass == ExprClass) ||
4206 S.
Diag(
castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)
4211 castType, ExprClass)))
4218 S.
Diag(
castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)
4219 <<
T <<
Target->getName() << castType;
4221 S.
Diag(
Target->getBeginLoc(), diag::note_declared_at);
4228 diag::err_objc_cf_bridged_not_interface)
4241template <
typename TB>
4243 bool &HadTheAttribute,
bool warn) {
4245 HadTheAttribute =
false;
4250 HadTheAttribute =
true;
4251 if (Parm->isStr(
"id"))
4259 Target = R.getFoundDecl();
4263 castExpr->getType()->getAsObjCInterfacePointerType()) {
4265 = InterfacePointerType->getObjectType()->getInterface();
4266 if ((CastClass == ExprClass) ||
4271 diag::warn_objc_invalid_bridge_to_cf)
4272 <<
castExpr->getType()->getPointeeType() <<
T;
4276 }
else if (
castExpr->getType()->isObjCIdType() ||
4286 diag::warn_objc_invalid_bridge_to_cf)
4287 <<
castExpr->getType() << castType;
4289 S.
Diag(
Target->getBeginLoc(), diag::note_declared_at);
4296 diag::err_objc_ns_bridged_invalid_cfobject)
4297 <<
castExpr->getType() << castType;
4300 S.
Diag(
Target->getBeginLoc(), diag::note_declared_at);
4317 bool HasObjCBridgeAttr;
4320 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
4322 bool HasObjCBridgeMutableAttr;
4323 bool ObjCBridgeMutableAttrWillNotWarn =
4326 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
4329 if (HasObjCBridgeAttr)
4331 HasObjCBridgeAttr,
true);
4332 else if (HasObjCBridgeMutableAttr)
4337 bool HasObjCBridgeAttr;
4340 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
4342 bool HasObjCBridgeMutableAttr;
4343 bool ObjCBridgeMutableAttrWillNotWarn =
4346 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
4349 if (HasObjCBridgeAttr)
4351 HasObjCBridgeAttr,
true);
4352 else if (HasObjCBridgeMutableAttr)
4361 if (PRE->isExplicitProperty()) {
4363 SrcType = PDecl->getType();
4365 else if (PRE->isImplicitProperty()) {
4367 SrcType = Getter->getReturnType();
4390 : CK_CPointerToObjCPointerCast;
4402 QualType T = CfToNs ? SrcType : DestType;
4418 Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId
4419 << SrcType << DestType;
4424 Target = R.getFoundDecl();
4429 Diag(Loc, diag::err_objc_bridged_related_invalid_class_name) << RCId
4430 << SrcType << DestType;
4433 Diag(
Target->getBeginLoc(), diag::note_declared_at);
4439 if (CfToNs && CMId) {
4440 Selector Sel = Context.Selectors.getUnarySelector(CMId);
4444 Diag(Loc, diag::err_objc_bridged_related_known_method)
4445 << SrcType << DestType << Sel <<
false;
4453 if (!CfToNs && IMId) {
4454 Selector Sel = Context.Selectors.getNullarySelector(IMId);
4455 InstanceMethod = RelatedClass->
lookupMethod(Sel,
true);
4456 if (!InstanceMethod) {
4458 Diag(Loc, diag::err_objc_bridged_related_known_method)
4459 << SrcType << DestType << Sel <<
true;
4478 if (!CfToNs && !NsToCf)
4486 ClassMethod, InstanceMethod, TDNDecl,
4494 std::string ExpressionString =
"[";
4496 ExpressionString +=
" ";
4497 ExpressionString += ClassMethod->getSelector().getAsString();
4501 Diag(Loc, diag::err_objc_bridged_related_known_method)
4502 << SrcType << DestType << ClassMethod->getSelector() <<
false
4509 QualType receiverType = Context.getObjCInterfaceType(RelatedClass);
4511 Expr *args[] = { SrcExpr };
4513 ClassMethod->getLocation(),
4514 ClassMethod->getSelector(), ClassMethod,
4516 SrcExpr = msg.
get();
4523 if (InstanceMethod) {
4525 std::string ExpressionString;
4528 if (InstanceMethod->isPropertyAccessor())
4530 InstanceMethod->findPropertyDecl()) {
4532 ExpressionString =
".";
4533 ExpressionString += PDecl->getNameAsString();
4534 Diag(Loc, diag::err_objc_bridged_related_known_method)
4535 << SrcType << DestType << InstanceMethod->getSelector() <<
true
4538 if (ExpressionString.empty()) {
4540 ExpressionString =
" ";
4541 ExpressionString += InstanceMethod->getSelector().getAsString();
4542 ExpressionString +=
"]";
4544 Diag(Loc, diag::err_objc_bridged_related_known_method)
4545 << SrcType << DestType << InstanceMethod->getSelector() <<
true
4553 SrcExpr, SrcType, InstanceMethod->getLocation(),
4554 InstanceMethod->getSelector(), InstanceMethod, {});
4555 SrcExpr = msg.
get();
4566 bool Diagnose,
bool DiagnoseCFAudited,
4579 if (exprACTC == castACTC) {
4585 castType != castExprType) {
4591 if (
const ParenType *PT = dyn_cast<ParenType>(DT))
4592 QDT = PT->desugar();
4593 else if (
const TypeOfType *TP = dyn_cast<TypeOfType>(DT))
4594 QDT = TP->desugar();
4595 else if (
const AttributedType *AT = dyn_cast<AttributedType>(DT))
4596 QDT = AT->desugar();
4597 if (QDT != castType &&
4602 Diag(loc, diag::err_arc_nolifetime_behavior);
4640 switch (ARCCastChecker(Context, exprACTC, castACTC,
false).Visit(
castExpr)) {
4653 CK_ARCConsumeObject,
castExpr,
nullptr,
4655 SemaRef.Cleanup.setExprNeedsCleanups(
true);
4680 (Opc == BO_NE || Opc == BO_EQ))) {
4702 castType =
cast->getTypeAsWritten();
4705 castRange =
cast->getTypeInfoAsWritten()->getTypeLoc().getSourceRange();
4706 castType =
cast->getTypeAsWritten();
4709 llvm_unreachable(
"Unexpected ImplicitCastExpr");
4728 if (
ParenExpr *pe = dyn_cast<ParenExpr>(e)) {
4730 return new (Context)
ParenExpr(pe->getLParen(), pe->getRParen(), sub);
4731 }
else if (
UnaryOperator *uo = dyn_cast<UnaryOperator>(e)) {
4732 assert(uo->getOpcode() == UO_Extension);
4736 uo->getOperatorLoc(),
false,
4737 SemaRef.CurFPFeatureOverrides());
4739 assert(!gse->isResultDependent());
4740 assert(!gse->isTypePredicate());
4742 unsigned n = gse->getNumAssocs();
4745 subExprs.reserve(n);
4746 subTypes.reserve(n);
4748 subTypes.push_back(assoc.getTypeSourceInfo());
4749 Expr *sub = assoc.getAssociationExpr();
4750 if (assoc.isSelected())
4752 subExprs.push_back(sub);
4756 Context, gse->getGenericLoc(), gse->getControllingExpr(), subTypes,
4757 subExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
4758 gse->containsUnexpandedParameterPack(), gse->getResultIndex());
4778 return !ObjI->isArcWeakrefUnavailable();
4785 Expr *curExpr = e, *prevExpr =
nullptr;
4790 if (
auto *pe = dyn_cast<ParenExpr>(curExpr)) {
4792 curExpr = pe->getSubExpr();
4796 if (
auto *ce = dyn_cast<CastExpr>(curExpr)) {
4797 if (
auto *ice = dyn_cast<ImplicitCastExpr>(ce))
4798 if (ice->getCastKind() == CK_ARCReclaimReturnedObject) {
4800 return ice->getSubExpr();
4801 if (
auto *pe = dyn_cast<ParenExpr>(prevExpr))
4802 pe->setSubExpr(ice->getSubExpr());
4809 curExpr = ce->getSubExpr();
4828 SubExpr = SubResult.
get();
4835 bool MustConsume =
false;
4841 CK = (
T->isBlockPointerType() ? CK_AnyPointerToBlockPointerCast
4842 : CK_CPointerToObjCPointerCast);
4849 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
4852 << (
T->isBlockPointerType()? 1 : 0)
4856 Diag(BridgeKeywordLoc, diag::note_arc_bridge)
4858 Diag(BridgeKeywordLoc, diag::note_arc_bridge_transfer)
4861 br ?
"CFBridgingRelease "
4862 :
"__bridge_transfer ");
4892 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
4900 Diag(BridgeKeywordLoc, diag::note_arc_bridge)
4902 Diag(BridgeKeywordLoc, diag::note_arc_bridge_retained)
4905 br ?
"CFBridgingRetain " :
"__bridge_retained");
4912 Diag(LParenLoc, diag::err_arc_bridge_cast_incompatible)
4913 << FromType <<
T << Kind
4924 SemaRef.Cleanup.setExprNeedsCleanups(
true);
4944 TSInfo = Context.getTrivialTypeSourceInfo(
T, LParenLoc);
4971 LookForIvars =
true;
4972 else if (IsClassMethod)
4973 LookForIvars =
false;
4984 if (IsClassMethod) {
5005 Diag(Loc, diag::warn_ivar_use_hidden) << IV->getDeclName();
5013 Diag(Loc, diag::err_ivar_use_in_class_method) << IV->getDeclName();
5024 bool AllowBuiltinCreation) {
5033 if (Lookup.
empty() && II && AllowBuiltinCreation)
5034 SemaRef.LookupBuiltin(Lookup);
5045 "should not reference ivar from this context");
5048 assert(IFace &&
"should not reference ivar from this context");
5056 if (
SemaRef.DiagnoseUseOfDecl(IV, Loc))
5067 SemaRef.ActOnIdExpression(S, SelfScopeSpec, TemplateKWLoc, SelfName,
5073 SelfExpr =
SemaRef.DefaultLvalueConversion(SelfExpr.
get());
5077 SemaRef.MarkAnyDeclReferenced(Loc, IV,
true);
5089 if (!
SemaRef.isUnevaluatedContext() &&
5090 !
getDiagnostics().isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
5095 SemaRef.ImplicitlyRetainedSelfLocs.push_back({Loc, BD});
5111 (Context.hasSameType(RHSTy, Context.getObjCClassRedefinitionType()))) {
5112 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), LHSTy,
5113 CK_CPointerToObjCPointerCast);
5117 (Context.hasSameType(LHSTy, Context.getObjCClassRedefinitionType()))) {
5118 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), RHSTy,
5119 CK_CPointerToObjCPointerCast);
5124 (Context.hasSameType(RHSTy, Context.getObjCIdRedefinitionType()))) {
5125 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), LHSTy,
5126 CK_CPointerToObjCPointerCast);
5130 (Context.hasSameType(LHSTy, Context.getObjCIdRedefinitionType()))) {
5131 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), RHSTy,
5132 CK_CPointerToObjCPointerCast);
5136 if (Context.isObjCSelType(LHSTy) &&
5137 (Context.hasSameType(RHSTy, Context.getObjCSelRedefinitionType()))) {
5138 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), LHSTy, CK_BitCast);
5141 if (Context.isObjCSelType(RHSTy) &&
5142 (Context.hasSameType(LHSTy, Context.getObjCSelRedefinitionType()))) {
5143 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), RHSTy, CK_BitCast);
5149 if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {
5172 if (!(compositeType = Context.areCommonBaseCompatible(LHSOPT, RHSOPT))
5175 }
else if (Context.canAssignObjCInterfaces(LHSOPT, RHSOPT)) {
5176 compositeType = RHSOPT->isObjCBuiltinType() ? RHSTy : LHSTy;
5177 }
else if (Context.canAssignObjCInterfaces(RHSOPT, LHSOPT)) {
5180 RHSOPT->isObjCQualifiedIdType()) &&
5181 Context.ObjCQualifiedIdTypesAreCompatible(LHSOPT, RHSOPT,
5187 compositeType = Context.getObjCIdType();
5189 compositeType = Context.getObjCIdType();
5191 Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands)
5194 QualType incompatTy = Context.getObjCIdType();
5195 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), incompatTy, CK_BitCast);
5196 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), incompatTy, CK_BitCast);
5200 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), compositeType, CK_BitCast);
5201 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), compositeType, CK_BitCast);
5202 return compositeType;
5209 Diag(QuestionLoc, diag::err_cond_voidptr_arc)
5219 QualType destType = Context.getPointerType(destPointee);
5221 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), destType, CK_NoOp);
5223 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), destType, CK_BitCast);
5230 Diag(QuestionLoc, diag::err_cond_voidptr_arc)
5240 QualType destType = Context.getPointerType(destPointee);
5242 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), destType, CK_NoOp);
5244 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), destType, CK_BitCast);
5265 if (OV->getSourceExpr())
5268 if (
auto *SL = dyn_cast<StringLiteral>(SrcExpr)) {
5269 if (!PT->
isObjCIdType() && !(ID && ID->getIdentifier()->isStr(
"NSString")))
5271 if (!SL->isOrdinary())
5275 Diag(SL->getBeginLoc(), diag::err_missing_atsign_prefix)
5287 if (!ID || !ID->getIdentifier()->isStr(
"NSNumber"))
5307 assert((Kind == tok::kw___objc_yes || Kind == tok::kw___objc_no) &&
5308 "Unknown Objective-C Boolean value!");
5310 QualType BoolT = Context.ObjCBuiltinBoolTy;
5311 if (!Context.getBOOLDecl()) {
5315 Result.isSingleResult()) {
5318 Context.setBOOLDecl(TD);
5321 if (Context.getBOOLDecl())
5322 BoolT = Context.getBOOLType();
5323 return new (Context)
5331 auto FindSpecVersion =
5332 [&](StringRef Platform,
5333 const llvm::Triple::OSType &OS) -> std::optional<VersionTuple> {
5339 if (Spec == AvailSpecs.end() && Platform ==
"maccatalyst") {
5346 if (Spec == AvailSpecs.end()) {
5348 const llvm::Triple &Triple = Context.getTargetInfo().getTriple();
5349 if (Triple.isOSDarwin()) {
5355 if (Spec == AvailSpecs.end())
5356 return std::nullopt;
5358 return llvm::Triple::getCanonicalVersionForOS(
5360 llvm::Triple::isValidVersionForOS(OS, Spec->
getVersion()));
5363 VersionTuple Version;
5364 if (
auto MaybeVersion =
5365 FindSpecVersion(Context.getTargetInfo().getPlatformName(),
5366 Context.getTargetInfo().getTriple().getOS()))
5367 Version = *MaybeVersion;
5372 Context->HasPotentialAvailabilityViolations =
true;
5374 return new (Context)
5382 if (
type->isObjCObjectPointerType()) {
5384 }
else if (
type->isBlockPointerType()) {
5385 SemaRef.maybeExtendBlockObject(E);
5386 return CK_BlockPointerToObjCPointerCast;
5388 assert(
type->isPointerType());
5389 return CK_CPointerToObjCPointerCast;
5398 case Stmt::ObjCStringLiteralClass:
5401 case Stmt::ObjCArrayLiteralClass:
5404 case Stmt::ObjCDictionaryLiteralClass:
5407 case Stmt::BlockExprClass:
5409 case Stmt::ObjCBoxedExprClass: {
5412 case Stmt::IntegerLiteralClass:
5413 case Stmt::FloatingLiteralClass:
5414 case Stmt::CharacterLiteralClass:
5415 case Stmt::ObjCBoolLiteralExprClass:
5416 case Stmt::CXXBoolLiteralExprClass:
5419 case Stmt::ImplicitCastExprClass: {
5422 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.
Result
Implement __builtin_bit_cast and related operations.
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 void CheckObjCDictionaryLiteralUTF8Keys(Sema &S, ObjCDictionaryLiteral *Literal)
Warn about string keys of a constant dictionary literal that are not well-formed UTF-8.
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.
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 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)
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)
ExprResult ParseObjCSelectorExpression(Selector Sel, SourceLocation AtLoc, SourceLocation SelKWLoc, SourceLocation SelNameLoc, SourceLocation LParenLoc, SourceLocation RParenLoc, bool WarnMultipleSelectors)
ParseObjCSelectorExpression - Build selector expression for @selector.
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.
ExprResult ActOnObjCBoolLiteral(SourceLocation AtLoc, SourceLocation ValueLoc, bool Value)
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.
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer.
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.
Top level wrappers for InstallAPI frontend operations.
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.
const FunctionProtoType * T
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)
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