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);
1053 QualType IdT = Context.getObjCIdType();
1061 nullptr , Context.getTranslationUnitDecl(),
1071 &Context.Idents.get(
"objects"),
1072 Context.getPointerType(IdT),
1075 Params.push_back(objects);
1079 &Context.Idents.get(
"keys"),
1080 Context.getPointerType(IdT),
1083 Params.push_back(keys);
1087 &Context.Idents.get(
"cnt"),
1088 Context.UnsignedLongTy,
1091 Params.push_back(cnt);
1092 Method->setMethodParams(Context, Params, {});
1103 !Context.hasSameUnqualifiedType(PtrValue->
getPointeeType(), IdT)) {
1107 diag::note_objc_literal_method_param)
1109 << Context.getPointerType(IdT.
withConst());
1127 Context.ObjCBuiltinIdTy, {},
1141 diag::note_objc_literal_method_param)
1143 << Context.getPointerType(IdT.
withConst());
1154 diag::note_objc_literal_method_param)
1171 bool HasPackExpansions =
false;
1175 bool ExpressibleAsConstantInitLiteral = LangOpts.ConstantNSDictionaryLiterals;
1180 if (!ExpressibleAsConstantInitLiteral)
1182 if (Elem.Key->isValueDependent() || Elem.Value->isValueDependent())
1183 ExpressibleAsConstantInitLiteral =
false;
1187 if (LangOpts.ObjCConstantLiterals && Elements.size() == 0) {
1189 "The current ABI doesn't support an empty constant NSDictionary "
1191 ExpressibleAsConstantInitLiteral =
true;
1204 if (
Value.isInvalid())
1207 Element.Key = Key.
get();
1208 Element.Value =
Value.get();
1210 if (ExpressibleAsConstantInitLiteral &&
1211 !Element.Key->isConstantInitializer(Context))
1212 ExpressibleAsConstantInitLiteral =
false;
1215 if (ExpressibleAsConstantInitLiteral &&
1217 ExpressibleAsConstantInitLiteral =
false;
1221 if (ExpressibleAsConstantInitLiteral &&
1223 !Element.Value->isConstantInitializer(Context)))
1224 ExpressibleAsConstantInitLiteral =
false;
1226 if (Element.EllipsisLoc.isInvalid())
1229 if (!Element.Key->containsUnexpandedParameterPack() &&
1230 !Element.Value->containsUnexpandedParameterPack()) {
1231 Diag(Element.EllipsisLoc,
1232 diag::err_pack_expansion_without_parameter_packs)
1234 Element.Value->getEndLoc());
1238 HasPackExpansions =
true;
1241 QualType Ty = Context.getObjCObjectPointerType(
1246 ExpressibleAsConstantInitLiteral, SR);
1250 return SemaRef.MaybeBindToTemporary(DictionaryLiteral);
1260 StrTy = Context.DependentTy;
1264 if (
SemaRef.RequireCompleteType(AtLoc, EncodedType,
1265 diag::err_incomplete_type_objc_at_encode,
1271 Context.getObjCEncodingForType(EncodedType, Str,
nullptr, &NotEncodedT);
1272 if (!NotEncodedT.
isNull())
1273 Diag(AtLoc, diag::warn_incomplete_encoded_type)
1274 << EncodedType << NotEncodedT;
1278 StrTy = Context.getStringLiteralArrayType(Context.CharTy, Str.size());
1281 return new (Context)
ObjCEncodeExpr(StrTy, EncodedTypeInfo, AtLoc, RParenLoc);
1294 TInfo = Context.getTrivialTypeSourceInfo(
1295 EncodedType,
SemaRef.getLocForEndOfToken(LParenLoc));
1307 bool Warned =
false;
1310 if (MatchingMethodDecl == Method ||
1312 MatchingMethodDecl->
getSelector() != Method->getSelector())
1318 S.
Diag(AtLoc, diag::warn_multiple_selectors)
1321 S.
Diag(Method->getLocation(), diag::note_method_declared_at)
1322 << Method->getDeclName();
1324 S.
Diag(MatchingMethodDecl->
getLocation(), diag::note_method_declared_at)
1335 bool WarnMultipleSelectors) {
1336 if (!WarnMultipleSelectors ||
1339 bool Warned =
false;
1340 for (SemaObjC::GlobalMethodPool::iterator
b = S.
ObjC().
MethodPool.begin(),
1346 Method, InstMethList))
1352 Method, ClsMethList) || Warned)
1368 assert(Method->getSelector() == Sel &&
"Method with wrong selector in method list");
1369 if (Method->isDirectMethod()) {
1371 DirectMethod = Method;
1376 return DirectMethod;
1391 S, Sel, Iter->second.first, onlyDirect, anyDirect);
1393 S, Sel, Iter->second.second, onlyDirect, anyDirect);
1395 return DirectInstance ? DirectInstance : DirectClass;
1424 bool WarnMultipleSelectors) {
1433 Selector MatchedSel = OM->getSelector();
1436 Diag(SelLoc, diag::warn_undeclared_selector_with_typo)
1437 << Sel << MatchedSel
1441 Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
1444 WarnMultipleSelectors);
1446 bool onlyDirect =
true;
1447 bool anyDirect =
false;
1452 Diag(AtLoc, diag::err_direct_selector_expression)
1453 <<
Method->getSelector();
1454 Diag(
Method->getLocation(), diag::note_direct_method_declared_at)
1455 <<
Method->getDeclName();
1456 }
else if (anyDirect) {
1462 if (LikelyTargetMethod && LikelyTargetMethod->
isDirectMethod()) {
1463 Diag(AtLoc, diag::warn_potentially_direct_selector_expression) << Sel;
1465 diag::note_direct_method_declared_at)
1467 }
else if (!LikelyTargetMethod) {
1470 Diag(AtLoc, diag::warn_strict_potentially_direct_selector_expression)
1473 diag::note_direct_method_declared_at)
1480 Method->getImplementationControl() !=
1482 !
SemaRef.getSourceManager().isInSystemHeader(
Method->getLocation()))
1494 Diag(AtLoc, diag::err_arc_illegal_selector) <<
1511 QualType Ty = Context.getObjCSelType();
1524 Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;
1528 Diag(ProtoLoc, diag::err_objc_non_runtime_protocol_in_protocol_expr)
1531 Diag(ProtoLoc, diag::err_atprotocol_protocol) << PDecl;
1537 QualType Ty = Context.getObjCProtoType();
1540 Ty = Context.getObjCObjectPointerType(Ty);
1541 return new (Context)
ObjCProtocolExpr(Ty, PDecl, AtLoc, ProtoIdLoc, RParenLoc);
1562 if (
auto nullability = AttributedType::stripOuterNullability(T)) {
1563 if (T == Context.getObjCInstanceType()) {
1564 return Context.getAttributedType(*nullability, Context.getObjCIdType(),
1565 Context.getObjCIdType());
1571 if (T == Context.getObjCInstanceType())
1572 return Context.getObjCIdType();
1585 bool isClassMessage,
1586 bool isSuperMessage) {
1587 assert(Method &&
"Must have a method");
1588 if (!Method->hasRelatedResultType())
1589 return Method->getSendResultType(ReceiverType);
1597 if (
auto nullability =
1598 Method->getSendResultType(ReceiverType)->getNullability()) {
1600 (void)AttributedType::stripOuterNullability(
type);
1603 return Context.getAttributedType(*nullability,
type,
type);
1613 if (Method->isInstanceMethod() && isClassMessage)
1615 Method->getSendResultType(ReceiverType));
1619 if (isSuperMessage) {
1622 return transferNullability(
1623 Context.getObjCObjectPointerType(
1624 Context.getObjCInterfaceType(Class)));
1630 return transferNullability(Context.getObjCObjectPointerType(ReceiverType));
1636 Method->getSendResultType(ReceiverType));
1641 return transferNullability(ReceiverType);
1647 bool isClassMessage,
1648 bool isSuperMessage) {
1652 SemaRef, ReceiverType,
Method, isClassMessage, isSuperMessage);
1655 if (isClassMessage) {
1664 AttributedType::stripOuterNullability(T);
1665 if (T == Context.getObjCInstanceType()) {
1669 ->getDeclContext());
1671 QualType NewResultType = Context.getObjCObjectPointerType(
1674 NewResultType = Context.getAttributedType(*Nullability, NewResultType,
1676 return NewResultType;
1688 unsigned receiverNullabilityIdx = 0;
1692 receiverNullabilityIdx = 1 +
static_cast<unsigned>(*nullability);
1695 unsigned resultNullabilityIdx = 0;
1699 resultNullabilityIdx = 1 +
static_cast<unsigned>(*nullability);
1704 static const uint8_t
None = 0;
1705 static const uint8_t
NonNull = 1;
1708 static const uint8_t nullabilityMap[4][4] = {
1716 unsigned newResultNullabilityIdx
1717 = nullabilityMap[receiverNullabilityIdx][resultNullabilityIdx];
1718 if (newResultNullabilityIdx == resultNullabilityIdx)
1724 if (
auto attributed = dyn_cast<AttributedType>(resultType.
getTypePtr())) {
1725 resultType = attributed->getModifiedType();
1732 if (newResultNullabilityIdx > 0) {
1735 return Context.getAttributedType(newNullability, resultType, resultType);
1754 dyn_cast<ObjCCategoryImplDecl>(impl)) {
1755 iface = catImpl->getCategoryDecl();
1757 iface = impl->getClassInterface();
1767 for (
unsigned i = 0, e = overrides.size(); i != e; ++i) {
1782 Context.hasSameUnqualifiedType(destType, MD->
getReturnType()))
1789 SourceRange range = overridden->getReturnTypeSourceRange();
1792 loc = overridden->getLocation();
1793 Diag(loc, diag::note_related_result_type_explicit)
1817 if (!
Method->hasRelatedResultType())
1820 if (Context.hasSameUnqualifiedType(
1821 Method->getReturnType().getNonReferenceType(), MsgSend->
getType()))
1824 if (!Context.hasSameUnqualifiedType(
Method->getReturnType(),
1825 Context.getObjCInstanceType()))
1828 Diag(
Method->getLocation(), diag::note_related_result_type_inferred)
1841 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
1842 SelLoc = SelectorLocs.front();
1848 for (
unsigned i = 0, e = Args.size(); i != e; i++) {
1849 if (Args[i]->isTypeDependent())
1855 result =
SemaRef.checkUnknownAnyArg(SelLoc, Args[i], paramTy);
1857 result =
SemaRef.DefaultArgumentPromotion(Args[i]);
1861 Args[i] = result.
get();
1866 DiagID = diag::err_arc_method_not_found;
1868 DiagID = isClassMessage ? diag::warn_class_method_not_found
1869 : diag::warn_inst_method_not_found;
1874 DiagID = diag::err_method_not_found_with_typo;
1876 DiagID = isClassMessage ? diag::warn_class_method_not_found_with_typo
1877 : diag::warn_instance_method_not_found_with_typo;
1879 SourceRange SelectorRange(SelectorLocs.front(), SelectorLocs.back());
1881 Diag(SelLoc, DiagID)
1882 << Sel<< isClassMessage << MatchedSel
1885 Diag(SelLoc, DiagID) << Sel<< isClassMessage << MatchedSel;
1888 Diag(SelLoc, DiagID)
1889 << Sel << isClassMessage <<
SourceRange(SelectorLocs.front(),
1890 SelectorLocs.back());
1894 Diag(ThisClass->getLocation(), diag::note_receiver_class_declared);
1896 if (ThisClass->lookupClassMethod(Sel))
1897 Diag(RecRange.
getBegin(), diag::note_receiver_expr_here)
1899 ThisClass->getNameAsString());
1907 ReturnType = Context.UnknownAnyTy;
1909 ReturnType = Context.getObjCIdType();
1916 isClassMessage, isSuperMessage);
1923 NumNamedArgs =
Method->param_size();
1925 if (Args.size() < NumNamedArgs) {
1926 Diag(SelLoc, diag::err_typecheck_call_too_few_args)
1927 << 2 << NumNamedArgs << static_cast<unsigned>(Args.size())
1934 std::optional<ArrayRef<QualType>> typeArgs =
1936 bool IsError =
false;
1937 for (
unsigned i = 0; i < NumNamedArgs; i++) {
1939 if (Args[i]->isTypeDependent())
1942 Expr *argExpr = Args[i];
1945 assert(argExpr &&
"CheckMessageArgumentTypes(): missing expression");
1947 if (param->
hasAttr<NoEscapeAttr>() &&
1949 if (
auto *BE = dyn_cast<BlockExpr>(
1951 BE->getBlockDecl()->setDoesNotEscape();
1956 !param->
hasAttr<CFConsumedAttr>())
1961 if (param->
getType() == Context.UnknownAnyTy) {
1967 Args[i] = argE.
get();
1983 if (
SemaRef.RequireCompleteType(
1985 diag::err_call_incomplete_argument, argExpr))
2001 Args[i]->getType()->isBlockPointerType() &&
2004 SemaRef.maybeExtendBlockObject(arg);
2005 Args[i] = arg.get();
2011 if (
Method->isVariadic()) {
2012 for (
unsigned i = NumNamedArgs, e = Args.size(); i < e; ++i) {
2013 if (Args[i]->isTypeDependent())
2019 Args[i] = Arg.
get();
2023 if (Args.size() != NumNamedArgs) {
2024 Diag(Args[NumNamedArgs]->getBeginLoc(),
2025 diag::err_typecheck_call_too_many_args)
2026 << 2 << NumNamedArgs << static_cast<unsigned>(Args.size())
2027 <<
Method->getSourceRange() << 0
2029 Args.back()->getEndLoc());
2045 SemaRef.CurContext->getNonClosureAncestor());
2050 if (!method)
return false;
2053 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(receiver))
2065 if (
ObjCMethodDecl *method = iface->lookupMethod(sel, isInstance))
2070 if (
ObjCMethodDecl *method = iface->lookupPrivateMethod(sel, isInstance))
2075 for (
const auto *I : objType->quals())
2087 for (
const auto *PROTO : OPT->
quals()) {
2088 if ((MD = PROTO->lookupMethod(Sel, Instance))) {
2103 assert(IFaceT &&
"Expected an Interface");
2107 Diag(MemberLoc, diag::err_invalid_property_name)
2117 diag::err_property_not_found_forward_class,
2118 MemberName, BaseRange))
2124 if (
SemaRef.DiagnoseUseOfDecl(PD, MemberLoc))
2127 return new (Context)
2131 return new (Context)
2136 for (
const auto *I : OPT->
quals())
2140 if (
SemaRef.DiagnoseUseOfDecl(PD, MemberLoc))
2146 SuperLoc, SuperType);
2148 return new (Context)
2171 if (
SemaRef.DiagnoseUseOfDecl(Getter, MemberLoc))
2190 if (Setter &&
SemaRef.DiagnoseUseOfDecl(Setter, MemberLoc))
2202 if (!(PDecl->getPropertyAttributes() &
2205 diag::warn_property_access_suggest)
2206 << MemberName <<
QualType(OPT, 0) << PDecl->getName()
2211 if (Getter || Setter) {
2213 return new (Context)
2217 return new (Context)
2234 Corrected.isKeyword() ?
nullptr : Corrected.getFoundDecl();
2239 Diag(MemberLoc, diag::err_class_property_found) << MemberName
2246 SemaRef.diagnoseTypo(Corrected,
2247 PDiag(diag::err_property_not_found_suggest)
2248 << MemberName <<
QualType(OPT, 0));
2250 TypoResult, MemberLoc,
2251 SuperLoc, SuperType, Super);
2260 if (
SemaRef.RequireCompleteType(MemberLoc, OBJPT->getPointeeType(),
2261 diag::err_property_not_as_forward_class,
2262 MemberName, BaseExpr))
2266 diag::err_ivar_access_using_property_syntax_suggest)
2267 << MemberName <<
QualType(OPT, 0) << Ivar->getDeclName()
2272 Diag(MemberLoc, diag::err_property_not_found)
2292 if (receiverNamePtr->
isStr(
"super")) {
2294 if (
auto classDecl = CurMethod->getClassInterface()) {
2295 SuperType =
QualType(classDecl->getSuperClassType(), 0);
2296 if (CurMethod->isInstanceMethod()) {
2297 if (SuperType.
isNull()) {
2299 Diag(receiverNameLoc, diag::err_root_class_cannot_use_super)
2300 << CurMethod->getClassInterface()->getIdentifier();
2303 QualType T = Context.getObjCObjectPointerType(SuperType);
2310 receiverNameLoc, T,
true);
2321 Diag(receiverNameLoc, diag::err_expected_either) << tok::identifier
2331 GetterSel = PD->getGetterName();
2332 SetterSel = PD->getSetterName();
2334 GetterSel =
SemaRef.PP.getSelectorTable().getNullarySelector(&propertyName);
2350 if (
SemaRef.DiagnoseUseOfDecl(Getter, propertyNameLoc))
2365 if (Setter &&
SemaRef.DiagnoseUseOfDecl(Setter, propertyNameLoc))
2368 if (Getter || Setter) {
2370 return new (Context)
2377 propertyNameLoc, receiverNameLoc, IFace);
2379 return ExprError(
Diag(propertyNameLoc, diag::err_property_not_found)
2380 << &propertyName << Context.getObjCInterfaceType(IFace));
2390 WantObjCSuper =
Method->getClassInterface()->getSuperClass();
2393 bool ValidateCandidate(
const TypoCorrection &candidate)
override {
2398 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
2399 return std::make_unique<ObjCInterfaceOrSuperCCC>(*
this);
2408 bool HasTrailingDot,
ParsedType &ReceiverType) {
2410 ReceiverType =
nullptr;
2421 switch (
Result.getResultKind()) {
2428 if (!
Method->getClassInterface()) {
2434 if (
Method->getClassInterface()->lookupInstanceVariable(Name,
2446 Result.suppressDiagnostics();
2459 T = Context.getObjCInterfaceType(
Class);
2463 std::nullopt,
Type);
2469 TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
2470 ReceiverType =
SemaRef.CreateParsedType(T, TSInfo);
2475 ObjCInterfaceOrSuperCCC CCC(
SemaRef.getCurMethodDecl());
2477 Result.getLookupNameInfo(),
Result.getLookupKind(), S,
nullptr, CCC,
2479 if (Corrected.isKeyword()) {
2482 SemaRef.diagnoseTypo(Corrected,
PDiag(diag::err_unknown_receiver_suggest)
2489 SemaRef.diagnoseTypo(Corrected,
PDiag(diag::err_unknown_receiver_suggest)
2492 TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
2493 ReceiverType =
SemaRef.CreateParsedType(T, TSInfo);
2511 Diag(SuperLoc, diag::err_invalid_receiver_to_message_super);
2517 Diag(SuperLoc, diag::err_no_super_class_message)
2518 <<
Method->getDeclName();
2525 Diag(SuperLoc, diag::err_root_class_cannot_use_super)
2526 <<
Class->getIdentifier();
2532 if (
Method->getSelector() == Sel)
2533 SemaRef.getCurFunction()->ObjCShouldCallSuper =
false;
2535 if (
Method->isInstanceMethod()) {
2538 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2541 LBracLoc, SelectorLocs, RBracLoc, Args);
2548 SuperLoc, Sel,
nullptr,
2549 LBracLoc, SelectorLocs, RBracLoc, Args);
2553 bool isSuperReceiver,
2559 if (!ReceiverType.
isNull())
2560 receiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType);
2562 assert(((isSuperReceiver && Loc.
isValid()) || receiverTypeInfo) &&
2563 "Either the super receiver location needs to be valid or the receiver "
2564 "needs valid type source information");
2567 Sel,
Method, Loc, Loc, Loc, Args,
2582 auto Builder = S.
Diag(MsgLoc, DiagID)
2590 switch (Edit.
Kind) {
2597 Builder.AddFixItHint(
2618 bool IsClassObjectCall) {
2624 const auto *SE = dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens());
2628 if (!IsClassObjectCall) {
2630 if (!OPT || !OPT->getInterfaceDecl())
2633 OPT->getInterfaceDecl()->lookupInstanceMethod(SE->getSelector());
2636 OPT->getInterfaceDecl()->lookupPrivateMethod(SE->getSelector());
2641 ImpliedMethod = IT->getDecl()->lookupClassMethod(SE->getSelector());
2644 IT->getDecl()->lookupPrivateClassMethod(SE->getSelector());
2649 if (Ret->isRecordType() || Ret->isVectorType() || Ret->isExtVectorType()) {
2650 S.
Diag(Loc, diag::warn_objc_unsafe_perform_selector)
2651 << Method->getSelector()
2652 << (!Ret->isRecordType()
2654 : Ret->isUnionType() ? 1 : 0);
2656 diag::note_objc_unsafe_perform_selector_method_declared_here)
2667 Expr **Args,
unsigned NumArgs) {
2669 bool Format =
false;
2676 for (
const auto *I : Method->specific_attrs<FormatAttr>()) {
2683 if (!Format || NumArgs <= Idx)
2686 Expr *FormatExpr = Args[Idx];
2691 S.
Diag(FormatExpr->
getExprLoc(), diag::warn_objc_cdirective_format_string)
2694 S.
Diag(Method->getLocation(), diag::note_method_declared_at)
2695 << Method->getDeclName();
2737 Diag(Loc, diag::err_missing_open_square_message_send)
2742 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
2743 SelectorSlotLocs = SelectorLocs;
2745 SelectorSlotLocs = Loc;
2751 unsigned NumArgs = ArgsIn.size();
2752 Expr **Args = ArgsIn.data();
2753 assert(SuperLoc.
isInvalid() &&
"Message to super with dependent type");
2755 ReceiverTypeInfo, Sel, SelectorLocs,
2757 RBracLoc, isImplicit);
2763 if (!ClassType || !(
Class = ClassType->getInterface())) {
2764 Diag(Loc, diag::err_invalid_receiver_class_message)
2768 assert(
Class &&
"We don't know which class we're messaging?");
2771 (void)
SemaRef.DiagnoseUseOfDecl(
Class, SelectorSlotLocs);
2777 if (
SemaRef.RequireCompleteType(Loc, Context.getObjCInterfaceType(
Class),
2779 ? diag::err_arc_receiver_forward_class
2780 : diag::warn_receiver_forward_class),
2786 Diag(
Method->getLocation(), diag::note_method_sent_forward_class)
2787 <<
Method->getDeclName();
2797 false,
false,
Class))
2805 unsigned NumArgs = ArgsIn.size();
2806 Expr **Args = ArgsIn.data();
2813 if (
Method && !
Method->getReturnType()->isVoidType() &&
2815 LBracLoc,
Method->getReturnType(),
2816 diag::err_illegal_message_expr_incomplete_type))
2820 Diag(SuperLoc, diag::err_messaging_super_with_direct_method)
2824 :
Method->getClassInterface()->getName());
2825 Diag(
Method->getLocation(), diag::note_direct_method_declared_at)
2826 <<
Method->getDeclName();
2833 dyn_cast<ObjCInterfaceDecl>(
Method->getDeclContext());
2835 Diag(Loc, diag::warn_direct_initialize_call);
2836 Diag(
Method->getLocation(), diag::note_method_declared_at)
2837 <<
Method->getDeclName();
2842 Diag(Loc, diag::warn_direct_super_initialize_call);
2843 Diag(
Method->getLocation(), diag::note_method_declared_at)
2844 <<
Method->getDeclName();
2845 Diag(CurMeth->getLocation(), diag::note_method_declared_at)
2846 << CurMeth->getDeclName();
2857 Context, ReturnType,
VK, LBracLoc, SuperLoc,
false,
2858 ReceiverType, Sel, SelectorLocs,
Method,
ArrayRef(Args, NumArgs),
2859 RBracLoc, isImplicit);
2862 Context, ReturnType,
VK, LBracLoc, ReceiverTypeInfo, Sel, SelectorLocs,
2869 ReceiverType,
true);
2884 SemaRef.GetTypeFromParser(Receiver, &ReceiverTypeInfo);
2885 if (ReceiverType.
isNull())
2888 if (!ReceiverTypeInfo)
2889 ReceiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType, LBracLoc);
2893 nullptr, LBracLoc, SelectorLocs, RBracLoc,
2902 Sel,
Method, Loc, Loc, Loc, Args,
2909 const auto *Protocol = dyn_cast<ObjCProtocolDecl>(M->
getDeclContext());
2914 if (
const auto *RootClass = dyn_cast_or_null<ObjCInterfaceDecl>(
2918 if (P->getCanonicalDecl() == Protocol->getCanonicalDecl())
2958 assert((Receiver || SuperLoc.
isValid()) &&
"If the Receiver is null, the "
2959 "SuperLoc must be valid so we can "
2968 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
2969 SelectorSlotLocs = SelectorLocs;
2971 SelectorSlotLocs = Loc;
2975 Diag(Loc, diag::err_missing_open_square_message_send)
2985 if (Receiver->
getType() == Context.UnknownAnyTy)
2987 SemaRef.forceUnknownAnyToType(Receiver, Context.getObjCIdType());
2997 unsigned NumArgs = ArgsIn.size();
2998 Expr **Args = ArgsIn.data();
2999 assert(SuperLoc.
isInvalid() &&
"Message to super with dependent type");
3001 Context, Context.DependentTy,
VK_PRValue, LBracLoc, Receiver, Sel,
3002 SelectorLocs,
nullptr,
ArrayRef(Args, NumArgs), RBracLoc,
3012 ReceiverType = Receiver->
getType();
3020 !Context.getObjCIdType().isNull() &&
3025 Diag(Loc, diag::warn_bad_receiver_type) << ReceiverType << RecRange;
3028 .ImpCastExprToType(Receiver, Context.getObjCIdType(),
3029 CK_CPointerToObjCPointerCast)
3035 CastKind Kind =
IsNull ? CK_NullToPointer : CK_IntegralToPointer;
3037 SemaRef.ImpCastExprToType(Receiver, Context.getObjCIdType(), Kind)
3040 ReceiverType = Receiver->
getType();
3044 diag::err_incomplete_receiver_type))
3048 SemaRef.PerformContextuallyConvertToObjCPointer(Receiver);
3050 Receiver = result.
get();
3051 ReceiverType = Receiver->
getType();
3067 (Receiver && Context.isObjCNSObjectType(Receiver->
getType()))) {
3072 if (!Methods.empty()) {
3078 Sel, ArgsIn,
Method->isInstanceMethod(), Methods))
3083 receiverIsIdLike, Methods))
3101 Diag(SelLoc, diag::warn_instance_method_on_class_found)
3102 <<
Method->getSelector() << Sel;
3103 Diag(
Method->getLocation(), diag::note_method_declared_at)
3104 <<
Method->getDeclName();
3114 Method = ClassDecl->lookupClassMethod(Sel);
3117 Method = ClassDecl->lookupPrivateClassMethod(Sel);
3132 if (!Methods.empty()) {
3138 if (
Method->isInstanceMethod()) {
3140 dyn_cast<ObjCInterfaceDecl>(
Method->getDeclContext())) {
3141 if (ID->getSuperClass())
3142 Diag(SelLoc, diag::warn_root_inst_method_not_found)
3148 Sel, ArgsIn,
Method->isInstanceMethod(), Methods))
3171 ClassDecl = OCIType->getInterfaceDecl();
3178 if (
SemaRef.RequireCompleteType(
3179 Loc, OCIType->getPointeeType(),
3181 ? diag::err_arc_receiver_forward_instance
3182 : diag::warn_receiver_forward_instance,
3187 forwardClass = OCIType->getInterfaceDecl();
3189 diag::note_receiver_is_id);
3204 Diag(SelLoc, diag::err_arc_may_not_respond)
3205 << OCIType->getPointeeType() << Sel << RecRange
3206 <<
SourceRange(SelectorLocs.front(), SelectorLocs.back());
3214 if (OCIType->qual_empty()) {
3219 if (!Methods.empty()) {
3225 Sel, ArgsIn,
Method->isInstanceMethod(), Methods))
3233 if (
Method && !forwardClass)
3234 Diag(SelLoc, diag::warn_maynot_respond)
3235 << OCIType->getInterfaceDecl()->getIdentifier()
3241 SemaRef.DiagnoseUseOfDecl(
Method, SelectorSlotLocs, forwardClass))
3245 Diag(Loc, diag::err_bad_receiver_type) << ReceiverType << RecRange;
3253 ?
SemaRef.getEnclosingFunction()
3259 diag::err_messaging_unqualified_id_with_direct_method);
3260 Diag(
Method->getLocation(), diag::note_direct_method_declared_at)
3261 <<
Method->getDeclName();
3271 diag::err_messaging_class_with_direct_method);
3274 RecRange,
Method->getClassInterface()->getName()));
3277 Diag(
Method->getLocation(), diag::note_direct_method_declared_at)
3278 <<
Method->getDeclName();
3284 Diag(SuperLoc, diag::err_messaging_super_with_direct_method);
3287 SuperLoc,
Method->getClassInterface()->getName()));
3292 Diag(
Method->getLocation(), diag::note_direct_method_declared_at)
3293 <<
Method->getDeclName();
3295 }
else if (ReceiverType->
isObjCIdType() && !isImplicit) {
3296 Diag(Receiver->
getExprLoc(), diag::warn_messaging_unqualified_id);
3299 if (DIFunctionScopeInfo &&
3302 bool isDesignatedInitChain =
false;
3309 if (!ID->declaresOrInheritsDesignatedInitializers() ||
3310 ID->isDesignatedInitializer(Sel)) {
3311 isDesignatedInitChain =
true;
3317 if (!isDesignatedInitChain) {
3319 auto *CurMD =
SemaRef.getCurMethodDecl();
3320 assert(CurMD &&
"Current method declaration should not be null");
3322 CurMD->isDesignatedInitializerForTheInterface(&InitMethod);
3323 assert(isDesignated && InitMethod);
3326 diag::warn_objc_designated_init_non_designated_init_call :
3327 diag::warn_objc_designated_init_non_super_designated_init_call);
3329 diag::note_objc_designated_init_marked_here);
3333 if (DIFunctionScopeInfo &&
3337 Diag(SelLoc, diag::warn_objc_secondary_init_super_init_call);
3344 unsigned NumArgs = ArgsIn.size();
3345 Expr **Args = ArgsIn.data();
3353 LBracLoc, RBracLoc, RecRange, ReturnType,
VK))
3356 if (
Method && !
Method->getReturnType()->isVoidType() &&
3358 LBracLoc,
Method->getReturnType(),
3359 diag::err_illegal_message_expr_incomplete_type))
3388 Diag(SelLoc, diag::err_arc_illegal_explicit_message)
3393 if (
Method && NumArgs >= 1) {
3394 if (
const auto *SelExp =
3395 dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens())) {
3396 Selector ArgSel = SelExp->getSelector();
3399 SelExp->getSourceRange());
3403 SelExp->getSourceRange());
3406 switch (SelFamily) {
3413 if (!SelMethod->
hasAttr<NSReturnsNotRetainedAttr>()) {
3416 diag::err_arc_perform_selector_retains);
3423 if (SelMethod->
hasAttr<NSReturnsRetainedAttr>()) {
3426 diag::err_arc_perform_selector_retains);
3435 Diag(SelLoc, diag::warn_arc_perform_selector_leaks);
3436 Diag(Args[0]->getExprLoc(), diag::note_used_here);
3449 Context, ReturnType,
VK, LBracLoc, SuperLoc,
true,
3450 ReceiverType, Sel, SelectorLocs,
Method,
ArrayRef(Args, NumArgs),
3451 RBracLoc, isImplicit);
3454 Context, ReturnType,
VK, LBracLoc, Receiver, Sel, SelectorLocs,
Method,
3455 ArrayRef(Args, NumArgs), RBracLoc, isImplicit);
3460 bool IsClassObjectCall = ClassMessage;
3467 if (OPT->getObjectType()->isObjCClass()) {
3468 if (
const auto *CurMeth =
SemaRef.getCurMethodDecl()) {
3469 IsClassObjectCall =
true;
3471 Context.getObjCInterfaceType(CurMeth->getClassInterface());
3477 ReceiverType, IsClassObjectCall);
3490 Result->setDelegateInitCall(
true);
3501 if (!isImplicit &&
Method) {
3507 if (IsWeak && !
SemaRef.isUnevaluatedContext() &&
3546 SemaRef.MaybeConvertParenListExprToParenExpr(S, Receiver);
3552 IdentifierInfo *SelectorId = &Context.Idents.get(
"respondsToSelector");
3560 nullptr, LBracLoc, SelectorLocs,
3594 bool isIndirect =
false;
3598 type = ref->getPointeeType();
3605 type = ptr->getPointeeType();
3612 }
else if (
const ArrayType *array =
type->getAsArrayTypeUnsafe()) {
3613 type =
QualType(array->getElementType()->getBaseElementTypeUnsafe(), 0);
3621 if (
type->isObjCARCBridgableType())
3626 if (
type->isObjCARCBridgableType())
3647 ACCResult
merge(ACCResult left, ACCResult right) {
3648 if (left == right)
return left;
3649 if (left == ACC_bottom)
return right;
3650 if (right == ACC_bottom)
return left;
3656 class ARCCastChecker :
public StmtVisitor<ARCCastChecker, ACCResult> {
3657 typedef StmtVisitor<ARCCastChecker, ACCResult> super;
3659 ASTContext &Context;
3664 static bool isCFType(QualType
type) {
3666 return type->isCARCBridgableType();
3672 : Context(Context), SourceClass(source), TargetClass(target),
3673 Diagnose(diagnose) {}
3676 ACCResult Visit(Expr *e) {
3680 ACCResult VisitStmt(Stmt *
s) {
3685 ACCResult VisitExpr(Expr *e) {
3692 ACCResult VisitObjCObjectLiteral(ObjCObjectLiteral *OL) {
3701 ACCResult VisitObjCStringLiteral(ObjCStringLiteral *SL) {
3702 return VisitObjCObjectLiteral(SL);
3705 ACCResult VisitObjCBoxedExpr(ObjCBoxedExpr *OBE) {
3706 return VisitObjCObjectLiteral(OBE);
3709 ACCResult VisitObjCArrayLiteral(ObjCArrayLiteral *AL) {
3710 return VisitObjCObjectLiteral(AL);
3713 ACCResult VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *DL) {
3714 return VisitObjCObjectLiteral(DL);
3718 ACCResult VisitCastExpr(
CastExpr *e) {
3720 case CK_NullToPointer:
3724 case CK_LValueToRValue:
3726 case CK_CPointerToObjCPointerCast:
3727 case CK_BlockPointerToObjCPointerCast:
3728 case CK_AnyPointerToBlockPointerCast:
3737 ACCResult VisitUnaryExtension(UnaryOperator *e) {
3742 ACCResult VisitBinComma(BinaryOperator *e) {
3743 return Visit(e->
getRHS());
3747 ACCResult VisitConditionalOperator(ConditionalOperator *e) {
3749 if (left == ACC_invalid)
return ACC_invalid;
3754 ACCResult VisitPseudoObjectExpr(PseudoObjectExpr *e) {
3760 ACCResult VisitStmtExpr(StmtExpr *e) {
3765 ACCResult VisitDeclRefExpr(DeclRefExpr *e) {
3766 VarDecl *
var = dyn_cast<VarDecl>(e->
getDecl());
3771 !
var->hasDefinition(Context) &&
3772 var->getType().isConstQualified()) {
3779 return ACC_plusZero;
3787 ACCResult VisitCallExpr(CallExpr *e) {
3789 if (ACCResult result = checkCallToFunction(fn))
3792 return super::VisitCallExpr(e);
3795 ACCResult checkCallToFunction(FunctionDecl *fn) {
3804 if (fn->
hasAttr<CFReturnsNotRetainedAttr>())
3805 return ACC_plusZero;
3810 if (fn->
hasAttr<CFReturnsRetainedAttr>())
3811 return Diagnose ? ACC_plusOne
3816 if (builtinID == Builtin::BI__builtin___CFStringMakeConstantString)
3820 if (!fn->
hasAttr<CFAuditedTransferAttr>())
3825 return Diagnose ? ACC_plusOne
3828 return ACC_plusZero;
3831 ACCResult VisitObjCMessageExpr(ObjCMessageExpr *e) {
3835 ACCResult VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *e) {
3836 ObjCMethodDecl *method;
3841 return checkCallToMethod(method);
3844 ACCResult checkCallToMethod(ObjCMethodDecl *method) {
3845 if (!method)
return ACC_invalid;
3854 if (method->
hasAttr<CFReturnsNotRetainedAttr>())
3855 return ACC_plusZero;
3859 if (method->
hasAttr<CFReturnsRetainedAttr>())
3871 return ACC_plusZero;
3886template <
typename DiagBuilderT>
3890 Expr *realCast,
const char *bridgeKeyword,
const char *CFBridgeName) {
3906 NCE->getAngleBrackets().getEnd());
3910 char PrevChar = *
SM.getCharacterData(range.getBegin().getLocWithOffset(-1));
3914 BridgeCall += CFBridgeName;
3921 castedE = CCE->getSubExpr();
3928 char PrevChar = *
SM.getCharacterData(range.getBegin().getLocWithOffset(-1));
3932 BridgeCall += CFBridgeName;
3952 std::string castCode =
"(";
3953 castCode += bridgeKeyword;
3957 NCE->getAngleBrackets().getEnd());
3961 std::string castCode =
"(";
3962 castCode += bridgeKeyword;
3981template <
typename T>
3988 for (
auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) {
3989 if (
auto *
attr = Redecl->getAttr<T>())
3999 while (
const auto *TD = T->getAs<
TypedefType>()) {
4000 TDNDecl = TD->getDecl();
4001 if (ObjCBridgeRelatedAttr *ObjCBAttr =
4019 UnavailableAttr::IR_ARCForbiddenConversion))
4032 unsigned srcKind = 0;
4056 S.
Diag(loc, diag::err_arc_cast_requires_bridge)
4065 ACCResult CreateRule =
4067 assert(CreateRule != ACC_bottom &&
"This cast should already be accepted.");
4068 if (CreateRule != ACC_plusOne)
4071 ? S.
Diag(noteLoc, diag::note_arc_bridge)
4072 : S.
Diag(noteLoc, diag::note_arc_cstyle_bridge);
4075 castType,
castExpr, realCast,
"__bridge ",
4078 if (CreateRule != ACC_plusZero)
4081 ? S.
Diag(noteLoc, diag::note_arc_cstyle_bridge_transfer)
4084 diag::note_arc_bridge_transfer)
4085 << castExprType << br;
4088 castType,
castExpr, realCast,
"__bridge_transfer ",
4089 br ?
"CFBridgingRelease" :
nullptr);
4098 S.
Diag(loc, diag::err_arc_cast_requires_bridge)
4106 ACCResult CreateRule =
4108 assert(CreateRule != ACC_bottom &&
"This cast should already be accepted.");
4109 if (CreateRule != ACC_plusOne)
4112 ? S.
Diag(noteLoc, diag::note_arc_bridge)
4113 : S.
Diag(noteLoc, diag::note_arc_cstyle_bridge);
4115 castType,
castExpr, realCast,
"__bridge ",
4118 if (CreateRule != ACC_plusZero)
4121 ? S.
Diag(noteLoc, diag::note_arc_cstyle_bridge_retained)
4124 diag::note_arc_bridge_retained)
4128 castType,
castExpr, realCast,
"__bridge_retained ",
4129 br ?
"CFBridgingRetain" :
nullptr);
4135 S.
Diag(loc, diag::err_arc_mismatched_cast)
4137 << srcKind << castExprType << castType
4138 << castRange <<
castExpr->getSourceRange();
4141template <
typename TB>
4143 bool &HadTheAttribute,
bool warn) {
4145 HadTheAttribute =
false;
4146 while (
const auto *TD = T->getAs<
TypedefType>()) {
4150 HadTheAttribute =
true;
4151 if (Parm->isStr(
"id"))
4164 = InterfacePointerType->getObjectType()->getInterface();
4165 if ((CastClass == ExprClass) ||
4169 S.
Diag(
castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)
4174 castType, ExprClass)))
4181 S.
Diag(
castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)
4182 << T <<
Target->getName() << castType;
4184 S.
Diag(
Target->getBeginLoc(), diag::note_declared_at);
4191 diag::err_objc_cf_bridged_not_interface)
4204template <
typename TB>
4206 bool &HadTheAttribute,
bool warn) {
4208 HadTheAttribute =
false;
4209 while (
const auto *TD = T->getAs<
TypedefType>()) {
4213 HadTheAttribute =
true;
4214 if (Parm->isStr(
"id"))
4222 Target = R.getFoundDecl();
4226 castExpr->getType()->getAsObjCInterfacePointerType()) {
4228 = InterfacePointerType->getObjectType()->getInterface();
4229 if ((CastClass == ExprClass) ||
4234 diag::warn_objc_invalid_bridge_to_cf)
4235 <<
castExpr->getType()->getPointeeType() << T;
4239 }
else if (
castExpr->getType()->isObjCIdType() ||
4249 diag::warn_objc_invalid_bridge_to_cf)
4250 <<
castExpr->getType() << castType;
4252 S.
Diag(
Target->getBeginLoc(), diag::note_declared_at);
4259 diag::err_objc_ns_bridged_invalid_cfobject)
4260 <<
castExpr->getType() << castType;
4263 S.
Diag(
Target->getBeginLoc(), diag::note_declared_at);
4280 bool HasObjCBridgeAttr;
4283 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
4285 bool HasObjCBridgeMutableAttr;
4286 bool ObjCBridgeMutableAttrWillNotWarn =
4289 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
4292 if (HasObjCBridgeAttr)
4294 HasObjCBridgeAttr,
true);
4295 else if (HasObjCBridgeMutableAttr)
4300 bool HasObjCBridgeAttr;
4303 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
4305 bool HasObjCBridgeMutableAttr;
4306 bool ObjCBridgeMutableAttrWillNotWarn =
4309 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
4312 if (HasObjCBridgeAttr)
4314 HasObjCBridgeAttr,
true);
4315 else if (HasObjCBridgeMutableAttr)
4324 if (PRE->isExplicitProperty()) {
4326 SrcType = PDecl->getType();
4328 else if (PRE->isImplicitProperty()) {
4330 SrcType = Getter->getReturnType();
4353 : CK_CPointerToObjCPointerCast;
4365 QualType T = CfToNs ? SrcType : DestType;
4381 Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId
4382 << SrcType << DestType;
4387 Target = R.getFoundDecl();
4392 Diag(Loc, diag::err_objc_bridged_related_invalid_class_name) << RCId
4393 << SrcType << DestType;
4396 Diag(
Target->getBeginLoc(), diag::note_declared_at);
4402 if (CfToNs && CMId) {
4403 Selector Sel = Context.Selectors.getUnarySelector(CMId);
4407 Diag(Loc, diag::err_objc_bridged_related_known_method)
4408 << SrcType << DestType << Sel <<
false;
4416 if (!CfToNs && IMId) {
4417 Selector Sel = Context.Selectors.getNullarySelector(IMId);
4418 InstanceMethod = RelatedClass->
lookupMethod(Sel,
true);
4419 if (!InstanceMethod) {
4421 Diag(Loc, diag::err_objc_bridged_related_known_method)
4422 << SrcType << DestType << Sel <<
true;
4441 if (!CfToNs && !NsToCf)
4449 ClassMethod, InstanceMethod, TDNDecl,
4457 std::string ExpressionString =
"[";
4459 ExpressionString +=
" ";
4460 ExpressionString += ClassMethod->getSelector().getAsString();
4464 Diag(Loc, diag::err_objc_bridged_related_known_method)
4465 << SrcType << DestType << ClassMethod->getSelector() <<
false
4472 QualType receiverType = Context.getObjCInterfaceType(RelatedClass);
4474 Expr *args[] = { SrcExpr };
4476 ClassMethod->getLocation(),
4477 ClassMethod->getSelector(), ClassMethod,
4479 SrcExpr = msg.
get();
4486 if (InstanceMethod) {
4488 std::string ExpressionString;
4491 if (InstanceMethod->isPropertyAccessor())
4493 InstanceMethod->findPropertyDecl()) {
4495 ExpressionString =
".";
4496 ExpressionString += PDecl->getNameAsString();
4497 Diag(Loc, diag::err_objc_bridged_related_known_method)
4498 << SrcType << DestType << InstanceMethod->getSelector() <<
true
4501 if (ExpressionString.empty()) {
4503 ExpressionString =
" ";
4504 ExpressionString += InstanceMethod->getSelector().getAsString();
4505 ExpressionString +=
"]";
4507 Diag(Loc, diag::err_objc_bridged_related_known_method)
4508 << SrcType << DestType << InstanceMethod->getSelector() <<
true
4516 SrcExpr, SrcType, InstanceMethod->getLocation(),
4517 InstanceMethod->getSelector(), InstanceMethod, {});
4518 SrcExpr = msg.
get();
4529 bool Diagnose,
bool DiagnoseCFAudited,
4542 if (exprACTC == castACTC) {
4548 castType != castExprType) {
4554 if (
const ParenType *PT = dyn_cast<ParenType>(DT))
4555 QDT = PT->desugar();
4556 else if (
const TypeOfType *TP = dyn_cast<TypeOfType>(DT))
4557 QDT = TP->desugar();
4558 else if (
const AttributedType *AT = dyn_cast<AttributedType>(DT))
4559 QDT = AT->desugar();
4560 if (QDT != castType &&
4565 Diag(loc, diag::err_arc_nolifetime_behavior);
4603 switch (ARCCastChecker(Context, exprACTC, castACTC,
false).Visit(
castExpr)) {
4616 CK_ARCConsumeObject,
castExpr,
nullptr,
4618 SemaRef.Cleanup.setExprNeedsCleanups(
true);
4643 (Opc == BO_NE || Opc == BO_EQ))) {
4665 castType =
cast->getTypeAsWritten();
4668 castRange =
cast->getTypeInfoAsWritten()->getTypeLoc().getSourceRange();
4669 castType =
cast->getTypeAsWritten();
4672 llvm_unreachable(
"Unexpected ImplicitCastExpr");
4691 if (
ParenExpr *pe = dyn_cast<ParenExpr>(e)) {
4693 return new (Context)
ParenExpr(pe->getLParen(), pe->getRParen(), sub);
4694 }
else if (
UnaryOperator *uo = dyn_cast<UnaryOperator>(e)) {
4695 assert(uo->getOpcode() == UO_Extension);
4699 uo->getOperatorLoc(),
false,
4700 SemaRef.CurFPFeatureOverrides());
4702 assert(!gse->isResultDependent());
4703 assert(!gse->isTypePredicate());
4705 unsigned n = gse->getNumAssocs();
4708 subExprs.reserve(n);
4709 subTypes.reserve(n);
4711 subTypes.push_back(assoc.getTypeSourceInfo());
4712 Expr *sub = assoc.getAssociationExpr();
4713 if (assoc.isSelected())
4715 subExprs.push_back(sub);
4719 Context, gse->getGenericLoc(), gse->getControllingExpr(), subTypes,
4720 subExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
4721 gse->containsUnexpandedParameterPack(), gse->getResultIndex());
4741 return !ObjI->isArcWeakrefUnavailable();
4748 Expr *curExpr = e, *prevExpr =
nullptr;
4753 if (
auto *pe = dyn_cast<ParenExpr>(curExpr)) {
4755 curExpr = pe->getSubExpr();
4759 if (
auto *ce = dyn_cast<CastExpr>(curExpr)) {
4760 if (
auto *ice = dyn_cast<ImplicitCastExpr>(ce))
4761 if (ice->getCastKind() == CK_ARCReclaimReturnedObject) {
4763 return ice->getSubExpr();
4764 if (
auto *pe = dyn_cast<ParenExpr>(prevExpr))
4765 pe->setSubExpr(ice->getSubExpr());
4772 curExpr = ce->getSubExpr();
4791 SubExpr = SubResult.
get();
4798 bool MustConsume =
false;
4804 CK = (T->isBlockPointerType() ? CK_AnyPointerToBlockPointerCast
4805 : CK_CPointerToObjCPointerCast);
4812 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
4815 << (T->isBlockPointerType()? 1 : 0)
4819 Diag(BridgeKeywordLoc, diag::note_arc_bridge)
4821 Diag(BridgeKeywordLoc, diag::note_arc_bridge_transfer)
4824 br ?
"CFBridgingRelease "
4825 :
"__bridge_transfer ");
4855 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
4863 Diag(BridgeKeywordLoc, diag::note_arc_bridge)
4865 Diag(BridgeKeywordLoc, diag::note_arc_bridge_retained)
4868 br ?
"CFBridgingRetain " :
"__bridge_retained");
4875 Diag(LParenLoc, diag::err_arc_bridge_cast_incompatible)
4876 << FromType << T << Kind
4887 SemaRef.Cleanup.setExprNeedsCleanups(
true);
4907 TSInfo = Context.getTrivialTypeSourceInfo(T, LParenLoc);
4934 LookForIvars =
true;
4935 else if (IsClassMethod)
4936 LookForIvars =
false;
4947 if (IsClassMethod) {
4968 Diag(Loc, diag::warn_ivar_use_hidden) << IV->getDeclName();
4976 Diag(Loc, diag::err_ivar_use_in_class_method) << IV->getDeclName();
4987 bool AllowBuiltinCreation) {
4996 if (Lookup.
empty() && II && AllowBuiltinCreation)
4997 SemaRef.LookupBuiltin(Lookup);
5008 "should not reference ivar from this context");
5011 assert(IFace &&
"should not reference ivar from this context");
5019 if (
SemaRef.DiagnoseUseOfDecl(IV, Loc))
5030 SemaRef.ActOnIdExpression(S, SelfScopeSpec, TemplateKWLoc, SelfName,
5036 SelfExpr =
SemaRef.DefaultLvalueConversion(SelfExpr.
get());
5040 SemaRef.MarkAnyDeclReferenced(Loc, IV,
true);
5052 if (!
SemaRef.isUnevaluatedContext() &&
5053 !
getDiagnostics().isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
5058 SemaRef.ImplicitlyRetainedSelfLocs.push_back({Loc, BD});
5074 (Context.hasSameType(RHSTy, Context.getObjCClassRedefinitionType()))) {
5075 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), LHSTy,
5076 CK_CPointerToObjCPointerCast);
5080 (Context.hasSameType(LHSTy, Context.getObjCClassRedefinitionType()))) {
5081 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), RHSTy,
5082 CK_CPointerToObjCPointerCast);
5087 (Context.hasSameType(RHSTy, Context.getObjCIdRedefinitionType()))) {
5088 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), LHSTy,
5089 CK_CPointerToObjCPointerCast);
5093 (Context.hasSameType(LHSTy, Context.getObjCIdRedefinitionType()))) {
5094 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), RHSTy,
5095 CK_CPointerToObjCPointerCast);
5099 if (Context.isObjCSelType(LHSTy) &&
5100 (Context.hasSameType(RHSTy, Context.getObjCSelRedefinitionType()))) {
5101 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), LHSTy, CK_BitCast);
5104 if (Context.isObjCSelType(RHSTy) &&
5105 (Context.hasSameType(LHSTy, Context.getObjCSelRedefinitionType()))) {
5106 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), RHSTy, CK_BitCast);
5112 if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {
5135 if (!(compositeType = Context.areCommonBaseCompatible(LHSOPT, RHSOPT))
5138 }
else if (Context.canAssignObjCInterfaces(LHSOPT, RHSOPT)) {
5139 compositeType = RHSOPT->isObjCBuiltinType() ? RHSTy : LHSTy;
5140 }
else if (Context.canAssignObjCInterfaces(RHSOPT, LHSOPT)) {
5143 RHSOPT->isObjCQualifiedIdType()) &&
5144 Context.ObjCQualifiedIdTypesAreCompatible(LHSOPT, RHSOPT,
5150 compositeType = Context.getObjCIdType();
5152 compositeType = Context.getObjCIdType();
5154 Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands)
5157 QualType incompatTy = Context.getObjCIdType();
5158 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), incompatTy, CK_BitCast);
5159 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), incompatTy, CK_BitCast);
5163 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), compositeType, CK_BitCast);
5164 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), compositeType, CK_BitCast);
5165 return compositeType;
5172 Diag(QuestionLoc, diag::err_cond_voidptr_arc)
5182 QualType destType = Context.getPointerType(destPointee);
5184 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), destType, CK_NoOp);
5186 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), destType, CK_BitCast);
5193 Diag(QuestionLoc, diag::err_cond_voidptr_arc)
5203 QualType destType = Context.getPointerType(destPointee);
5205 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), destType, CK_NoOp);
5207 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), destType, CK_BitCast);
5228 if (OV->getSourceExpr())
5231 if (
auto *SL = dyn_cast<StringLiteral>(SrcExpr)) {
5232 if (!PT->
isObjCIdType() && !(ID && ID->getIdentifier()->isStr(
"NSString")))
5234 if (!SL->isOrdinary())
5238 Diag(SL->getBeginLoc(), diag::err_missing_atsign_prefix)
5250 if (!ID || !ID->getIdentifier()->isStr(
"NSNumber"))
5270 assert((Kind == tok::kw___objc_yes || Kind == tok::kw___objc_no) &&
5271 "Unknown Objective-C Boolean value!");
5273 QualType BoolT = Context.ObjCBuiltinBoolTy;
5274 if (!Context.getBOOLDecl()) {
5278 Result.isSingleResult()) {
5281 Context.setBOOLDecl(TD);
5284 if (Context.getBOOLDecl())
5285 BoolT = Context.getBOOLType();
5286 return new (Context)
5294 auto FindSpecVersion =
5295 [&](StringRef Platform,
5296 const llvm::Triple::OSType &OS) -> std::optional<VersionTuple> {
5302 if (Spec == AvailSpecs.end() && Platform ==
"maccatalyst") {
5309 if (Spec == AvailSpecs.end()) {
5311 const llvm::Triple &Triple = Context.getTargetInfo().getTriple();
5312 if (Triple.isOSDarwin()) {
5318 if (Spec == AvailSpecs.end())
5319 return std::nullopt;
5321 return llvm::Triple::getCanonicalVersionForOS(
5323 llvm::Triple::isValidVersionForOS(OS, Spec->
getVersion()));
5326 VersionTuple Version;
5327 if (
auto MaybeVersion =
5328 FindSpecVersion(Context.getTargetInfo().getPlatformName(),
5329 Context.getTargetInfo().getTriple().getOS()))
5330 Version = *MaybeVersion;
5335 Context->HasPotentialAvailabilityViolations =
true;
5337 return new (Context)
5345 if (
type->isObjCObjectPointerType()) {
5347 }
else if (
type->isBlockPointerType()) {
5348 SemaRef.maybeExtendBlockObject(E);
5349 return CK_BlockPointerToObjCPointerCast;
5351 assert(
type->isPointerType());
5352 return CK_CPointerToObjCPointerCast;
5361 case Stmt::ObjCStringLiteralClass:
5364 case Stmt::ObjCArrayLiteralClass:
5367 case Stmt::ObjCDictionaryLiteralClass:
5370 case Stmt::BlockExprClass:
5372 case Stmt::ObjCBoxedExprClass: {
5375 case Stmt::IntegerLiteralClass:
5376 case Stmt::FloatingLiteralClass:
5377 case Stmt::CharacterLiteralClass:
5378 case Stmt::ObjCBoolLiteralExprClass:
5379 case Stmt::CXXBoolLiteralExprClass:
5382 case Stmt::ImplicitCastExprClass: {
5385 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 ARCConversionTypeClass classifyTypeForARCConversion(QualType type)
static bool isAnyRetainable(ARCConversionTypeClass ACTC)
static void RemoveSelectorFromWarningCache(SemaObjC &S, Expr *Arg)
@ ACTC_voidPtr
void* might be a normal C type, or it might a CF type.
@ ACTC_retainable
id, void (^)()
@ ACTC_coreFoundation
struct A*
@ ACTC_indirectRetainable
id*, id***, void (^*)(),
@ ACTC_none
int, void, struct A
static QualType getBaseMessageSendResultType(Sema &S, QualType ReceiverType, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage)
Determine the result type of a message send based on the receiver type, method, and the kind of messa...
static const ObjCMethodDecl * findExplicitInstancetypeDeclarer(const ObjCMethodDecl *MD, QualType instancetype)
Look for an ObjC method whose result type exactly matches the given type.
static void DiagnoseCStringFormatDirectiveInObjCAPI(Sema &S, ObjCMethodDecl *Method, Selector Sel, Expr **Args, unsigned NumArgs)
Diagnose use of s directive in an NSString which is being passed as formatting string to formatting m...
static bool isMethodDeclaredInRootProtocol(Sema &S, const ObjCMethodDecl *M)
static bool validateBoxingMethod(Sema &S, SourceLocation Loc, const ObjCInterfaceDecl *Class, Selector Sel, const ObjCMethodDecl *Method)
Emits an error if the given method does not exist, or if the return type is not an Objective-C object...
static void checkFoundationAPI(Sema &S, SourceLocation Loc, const ObjCMethodDecl *Method, ArrayRef< Expr * > Args, QualType ReceiverType, bool IsClassObjectCall)
static void addFixitForObjCARCConversion(Sema &S, DiagBuilderT &DiagB, CheckedConversionKind CCK, SourceLocation afterLParen, QualType castType, Expr *castExpr, Expr *realCast, const char *bridgeKeyword, const char *CFBridgeName)
static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element, QualType T, bool ArrayLiteral=false)
Check that the given expression is a valid element of an Objective-C collection literal.
This file declares semantic analysis for Objective-C.
static QualType getPointeeType(const MemRegion *R)
Defines the clang::TypeLoc interface and its subclasses.
__device__ __2f16 float __ockl_bool s
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
bool QIdProtocolsAdoptObjCObjectProtocols(QualType QT, ObjCInterfaceDecl *IDecl)
QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in QT's qualified-id protocol list adopt...
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl)
ObjCObjectAdoptsQTypeProtocols - Checks that protocols in IC's protocol list adopt all protocols in Q...
Represents an array type, per C99 6.7.5.2 - Array Declarators.
ArraySizeModifier getSizeModifier() const
QualType getElementType() const
unsigned getIndexTypeCVRQualifiers() const
One specifier in an @available expression.
StringRef getPlatform() const
VersionTuple getVersion() const
Represents a block literal declaration, which is like an unnamed FunctionDecl.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Abstract class common to all of the C++ "named"/"keyword" casts.
Represents a C++ nested-name-specifier or a global scope specifier.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Represents the canonical version of C arrays with a specified constant size.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Simple template class for restricting typo correction candidates to ones having a single Decl* of the...
A reference to a declared variable, function, enum, etc.
Decl - This represents one declaration (or definition), e.g.
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
bool isInvalidDecl() const
SourceLocation getLocation() const
bool isDefinedOutsideFunctionOrMethod() const
isDefinedOutsideFunctionOrMethod - This predicate returns true if this scoped decl is defined outside...
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
TranslationUnitDecl * getTranslationUnitDecl()
The name of a declaration.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
bool isIdentifier() const
Predicate functions for querying what type of name this is.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
ExplicitCastExpr - An explicit cast written in the source code.
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
Expr * IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY
Skip past any parentheses and casts which do not change the value (including ptr->int casts of the sa...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Skip past any parentheses and lvalue casts which might surround this expression until reaching a fixe...
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool isObjCSelfExpr() const
Check if this expression is the ObjC 'self' implicit parameter.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
@ NPC_ValueDependentIsNull
Specifies that a value-dependent expression of integral or dependent type should be considered a null...
@ NPC_NeverValueDependent
Specifies that the expression should never be value-dependent.
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
static ExprValueKind getValueKindForType(QualType T)
getValueKindForType - Given a formal return or parameter type, give its value kind.
Represents difference between two FPOptions values.
static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc, CharSourceRange FromRange, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code from FromRange at a specific location.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
QualType getReturnType() const
Represents a C11 generic selection.
AssociationTy< false > Association
static GenericSelectionExpr * Create(const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr, ArrayRef< TypeSourceInfo * > AssocTypes, ArrayRef< Expr * > AssocExprs, SourceLocation DefaultLoc, SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack, unsigned ResultIndex)
Create a non-result-dependent generic selection expression accepting an expression predicate.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
Describes the sequence of initializations required to initialize a given object or reference with a s...
Describes an entity that is being initialized.
static InitializedEntity InitializeTemporary(QualType Type)
Create the initialization entity for a temporary.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
static bool isAsciiIdentifierContinueChar(char c, const LangOptions &LangOpts)
Returns true if the given character could appear in an identifier.
Represents the results of name lookup.
bool empty() const
Return true if no decls were found.
SourceLocation getNameLoc() const
Gets the location of the identifier.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
@ NSDict_dictionaryWithObjectsForKeysCount
@ NSArr_arrayWithObjectsCount
This represents a decl that may have a name.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
static ObjCArrayLiteral * Create(const ASTContext &C, ArrayRef< Expr * > Elements, QualType T, ObjCMethodDecl *Method, bool ExpressibleAsConstantInitializer, SourceRange SR)
A runtime availability query.
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
An Objective-C "bridged" cast expression, which casts between Objective-C pointers and C pointers,...
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCContainerDecl - Represents a container for method declarations.
ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const
ObjCPropertyDecl * FindPropertyDeclaration(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyDeclaration - Finds declaration of the property given its name in 'PropertyId' and return...
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
static ObjCDictionaryLiteral * Create(const ASTContext &C, ArrayRef< ObjCDictionaryElement > VK, bool HasPackExpansions, QualType T, ObjCMethodDecl *Method, bool ExpressibleAsConstantInitializer, SourceRange SR)
ObjCEncodeExpr, used for @encode in Objective-C.
Represents an ObjC class declaration.
ObjCMethodDecl * lookupClassMethod(Selector Sel) const
Lookup a class method for a given selector.
static ObjCInterfaceDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation atLoc, const IdentifierInfo *Id, ObjCTypeParamList *typeParamList, ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc=SourceLocation(), bool isInternal=false)
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const
Lookup an instance method for a given selector.
ObjCMethodDecl * lookupPrivateClassMethod(const Selector &Sel)
ObjCMethodDecl * getCategoryClassMethod(Selector Sel) const
ObjCMethodDecl * lookupPrivateMethod(const Selector &Sel, bool Instance=true) const
Lookup a method in the classes implementation hierarchy.
ObjCMethodDecl * lookupMethod(Selector Sel, bool isInstance, bool shallowCategoryLookup=false, bool followSuper=true, const ObjCCategoryDecl *C=nullptr) const
lookupMethod - This method returns an instance/class method by looking in the class,...
ObjCInterfaceDecl * getSuperClass() const
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCIvarDecl - Represents an ObjC instance variable.
AccessControl getAccessControl() const
QualType getUsageType(QualType objectType) const
Retrieve the type of this instance variable when viewed as a member of a specific object type.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
An expression that sends a message to the given Objective-C object or class.
static ObjCMessageExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, SourceLocation LBracLoc, SourceLocation SuperLoc, bool IsInstanceSuper, QualType SuperType, Selector Sel, ArrayRef< SourceLocation > SelLocs, ObjCMethodDecl *Method, ArrayRef< Expr * > Args, SourceLocation RBracLoc, bool isImplicit)
Create a message send to super.
Selector getSelector() const
const ObjCMethodDecl * getMethodDecl() const
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
ArrayRef< ParmVarDecl * > parameters() const
bool isPropertyAccessor() const
void getOverriddenMethods(SmallVectorImpl< const ObjCMethodDecl * > &Overridden) const
Return overridden methods for the given Method.
static ObjCMethodDecl * Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl, bool isInstance=true, bool isVariadic=false, bool isPropertyAccessor=false, bool isSynthesizedAccessorStub=false, bool isImplicitlyDeclared=false, bool isDefined=false, ObjCImplementationControl impControl=ObjCImplementationControl::None, bool HasRelatedResultType=false)
const ObjCPropertyDecl * findPropertyDecl(bool CheckOverrides=true) const
Returns the property associated with this method's selector.
void setMethodParams(ASTContext &C, ArrayRef< ParmVarDecl * > Params, ArrayRef< SourceLocation > SelLocs={})
Sets the method's parameters and selector source locations.
bool hasRelatedResultType() const
Determine whether this method has a result type that is related to the message receiver's type.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
bool isInstanceMethod() const
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
QualType getReturnType() const
bool isClassMethod() const
ObjCInterfaceDecl * getClassInterface()
bool isGlobalAllocation() const
Represents a pointer to an Objective C object.
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
bool isObjCIdType() const
True if this is equivalent to the 'id' type, i.e.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
ObjCInterfaceDecl * getInterfaceDecl() const
If this pointer points to an Objective @interface type, gets the declaration for that interface.
const ObjCInterfaceType * getInterfaceType() const
If this pointer points to an Objective C @interface type, gets the type for that interface.
Represents one property declaration in an Objective-C interface.
ObjCMethodDecl * getGetterMethodDecl() const
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
ObjCPropertyDecl * getExplicitProperty() const
ObjCMethodDecl * getImplicitPropertyGetter() const
bool isExplicitProperty() const
Represents an Objective-C protocol declaration.
bool hasDefinition() const
Determine whether this protocol has a definition.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
bool isNonRuntimeProtocol() const
This is true iff the protocol is tagged with the objc_non_runtime_protocol attribute.
ObjCProtocolExpr used for protocol expression in Objective-C.
bool hasConstantEmptyCollections() const
bool hasConstantCFBooleans() const
ObjCSelectorExpr used for @selector in Objective-C.
ObjCStringLiteral, used for Objective-C string literals i.e.
ObjCSubscriptRefExpr - used for array and dictionary subscripting.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
ParenExpr - This represents a parenthesized expression, e.g.
Sugar for parentheses used when specifying types.
Represents a parameter to a function.
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
A (possibly-)qualified type.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
QualType withConst() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
QualType substObjCTypeArgs(ASTContext &ctx, ArrayRef< QualType > typeArgs, ObjCSubstitutionContext context) const
Substitute type arguments for the Objective-C type parameters used in the subject type.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Base for LValueReferenceType and RValueReferenceType.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isInObjcMethodScope() const
isInObjcMethodScope - Return true if this scope is, or is contained in, an Objective-C method body.
static Selector constructSetterSelector(IdentifierTable &Idents, SelectorTable &SelTable, const IdentifierInfo *Name)
Return the default setter selector for the given identifier.
Smart pointer class that efficiently represents Objective-C method names.
std::string getAsString() const
Derive the full selector name (e.g.
ObjCMethodFamily getMethodFamily() const
Derive the conventional family of this method.
bool isUnarySelector() const
ObjCStringFormatFamily getStringFormatFamily() const
unsigned getNumArgs() const
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
DiagnosticsEngine & getDiagnostics() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
ObjCMessageKind getObjCMessageKind(Scope *S, IdentifierInfo *Name, SourceLocation NameLoc, bool IsSuper, bool HasTrailingDot, ParsedType &ReceiverType)
ObjCMethodDecl * ValueWithBytesObjCTypeMethod
The declaration of the valueWithBytes:objCType: method.
ExprResult BuildObjCDictionaryLiteral(SourceRange SR, MutableArrayRef< ObjCDictionaryElement > Elements)
ExprResult HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, Expr *BaseExpr, SourceLocation OpLoc, DeclarationName MemberName, SourceLocation MemberLoc, SourceLocation SuperLoc, QualType SuperType, bool Super)
HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an objective C interface.
ExprResult BuildInstanceMessage(Expr *Receiver, QualType ReceiverType, SourceLocation SuperLoc, Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args, bool isImplicit=false)
Build an Objective-C instance message expression.
const ObjCMethodDecl * SelectorsForTypoCorrection(Selector Sel, QualType ObjectType=QualType())
ExprResult ParseObjCSelectorExpression(Selector Sel, SourceLocation AtLoc, SourceLocation SelLoc, SourceLocation LParenLoc, SourceLocation RParenLoc, bool WarnMultipleSelectors)
ParseObjCSelectorExpression - Build selector expression for @selector.
ExprResult BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, QualType ReceiverType, SourceLocation SuperLoc, Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args, bool isImplicit=false)
Build an Objective-C class message expression.
ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number)
BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the numeric literal expression.
bool AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod, SourceRange R, bool receiverIdOrClass, SmallVectorImpl< ObjCMethodDecl * > &Methods)
ObjCMethodDecl * LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass=false)
LookupInstanceMethodInGlobalPool - Returns the method and warns if there are multiple signatures.
ExprResult ActOnObjCBridgedCast(Scope *S, SourceLocation LParenLoc, ObjCBridgeCastKind Kind, SourceLocation BridgeKeywordLoc, ParsedType Type, SourceLocation RParenLoc, Expr *SubExpr)
ObjCLiteralKind CheckLiteralKind(Expr *FromE)
ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc, TypeSourceInfo *EncodedTypeInfo, SourceLocation RParenLoc)
bool CheckObjCBridgeRelatedConversions(SourceLocation Loc, QualType DestType, QualType SrcType, Expr *&SrcExpr, bool Diagnose=true)
ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements)
ObjCInterfaceDecl * NSArrayDecl
The declaration of the Objective-C NSArray class.
ExprResult ActOnClassPropertyRefExpr(const IdentifierInfo &receiverName, const IdentifierInfo &propertyName, SourceLocation receiverNameLoc, SourceLocation propertyNameLoc)
void CheckObjCCircularContainer(ObjCMessageExpr *Message)
Check whether receiver is mutable ObjC container which attempts to add itself into the container.
ObjCInterfaceDecl * getObjCInterfaceDecl(const IdentifierInfo *&Id, SourceLocation IdLoc, bool TypoCorrection=false)
Look for an Objective-C class in the translation unit.
ObjCMethodDecl * LookupMethodInObjectType(Selector Sel, QualType Ty, bool IsInstance)
LookupMethodInType - Look up a method in an ObjCObjectType.
bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, ObjCMethodDecl *Method, ObjCIvarDecl *IV)
IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is an ivar synthesized for 'Meth...
ExprResult BuildClassMessageImplicit(QualType ReceiverType, bool isSuperReceiver, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)
ObjCInterfaceDecl * NSNumberDecl
The declaration of the Objective-C NSNumber class.
void CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr)
ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr)
BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the '@' prefixed parenthesized expression.
ObjCInterfaceDecl * NSValueDecl
The declaration of the Objective-C NSValue class.
Selector RespondsToSelectorSel
will hold 'respondsToSelector:'
bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method, const ObjCMethodDecl *PrevMethod, MethodMatchStrategy strategy=MMS_strict)
MatchTwoMethodDeclarations - Checks if two methods' type match and returns true, or false,...
bool CheckMessageArgumentTypes(const Expr *Receiver, QualType ReceiverType, MultiExprArg Args, Selector Sel, ArrayRef< SourceLocation > SelectorLocs, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage, SourceLocation lbrac, SourceLocation rbrac, SourceRange RecRange, QualType &ReturnType, ExprValueKind &VK)
CheckMessageArgumentTypes - Check types in an Obj-C message send.
ObjCInterfaceDecl * NSStringDecl
The declaration of the Objective-C NSString class.
llvm::MapVector< Selector, SourceLocation > ReferencedSelectors
Method selectors used in a @selector expression.
ObjCMethodDecl * LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass=false)
LookupFactoryMethodInGlobalPool - Returns the method and warns if there are multiple signatures.
ObjCMethodDecl * StringWithUTF8StringMethod
The declaration of the stringWithUTF8String: method.
bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall)
Check whether the given method, which must be in the 'init' family, is a valid member of that family.
QualType FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, SourceLocation QuestionLoc)
FindCompositeObjCPointerType - Helper method to find composite type of two objective-c pointer types ...
ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S)
ObjCInterfaceDecl * NSDictionaryDecl
The declaration of the Objective-C NSDictionary class.
ObjCMethodDecl * ArrayWithObjectsMethod
The declaration of the arrayWithObjects:count: method.
ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc, SourceLocation EncodeLoc, SourceLocation LParenLoc, ParsedType Ty, SourceLocation RParenLoc)
QualType QIDNSCopying
id<NSCopying> type.
bool CheckObjCString(Expr *Arg)
CheckObjCString - Checks that the argument to the builtin CFString constructor is correct Note: It mi...
ExprResult ActOnClassMessage(Scope *S, ParsedType Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr)
bool CheckConversionToObjCLiteral(QualType DstType, Expr *&SrcExpr, bool Diagnose=true)
ObjCMethodDecl * tryCaptureObjCSelf(SourceLocation Loc)
Try to capture an implicit reference to 'self'.
ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs, ArrayRef< Expr * > Strings)
ObjCMethodDecl * DictionaryWithObjectsMethod
The declaration of the dictionaryWithObjects:forKeys:count: method.
QualType NSStringPointer
Pointer to NSString type (NSString *).
ExprResult BuildObjCBridgedCast(SourceLocation LParenLoc, ObjCBridgeCastKind Kind, SourceLocation BridgeKeywordLoc, TypeSourceInfo *TSInfo, Expr *SubExpr)
ObjCProtocolDecl * LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Find the protocol with the given name, if any.
QualType NSNumberPointer
Pointer to NSNumber type (NSNumber *).
DeclResult LookupIvarInObjCMethod(LookupResult &Lookup, Scope *S, IdentifierInfo *II)
The parser has read a name in, and Sema has detected that we're currently inside an ObjC method.
ObjCMethodDecl * NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods]
The Objective-C NSNumber methods used to create NSNumber literals.
GlobalMethodPool MethodPool
Method Pool - allows efficient lookup when typechecking messages to "id".
QualType getMessageSendResultType(const Expr *Receiver, QualType ReceiverType, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage)
Determine the result of a message send expression based on the type of the receiver,...
ExprResult ParseObjCProtocolExpression(IdentifierInfo *ProtocolName, SourceLocation AtLoc, SourceLocation ProtoLoc, SourceLocation LParenLoc, SourceLocation ProtoIdLoc, SourceLocation RParenLoc)
ParseObjCProtocolExpression - Build protocol expression for @protocol.
ExprResult BuildInstanceMessageImplicit(Expr *Receiver, QualType ReceiverType, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)
void checkRetainCycles(ObjCMessageExpr *msg)
checkRetainCycles - Check whether an Objective-C message send might create an obvious retain cycle.
ObjCMessageKind
Describes the kind of message expression indicated by a message send that starts with an identifier.
@ ObjCClassMessage
The message is a class message, and the identifier is a type name.
@ ObjCInstanceMessage
The message is an instance message.
@ ObjCSuperMessage
The message is sent to 'super'.
ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S, IdentifierInfo *II, bool AllowBuiltinCreation=false)
The parser has read a name in, and Sema has detected that we're currently inside an ObjC method.
QualType NSValuePointer
Pointer to NSValue type (NSValue *).
void EmitRelatedResultTypeNote(const Expr *E)
If the given expression involves a message send to a method with a related result type,...
ExprResult ActOnInstanceMessage(Scope *S, Expr *Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx)
ExprResult BuildIvarRefExpr(Scope *S, SourceLocation Loc, ObjCIvarDecl *IV)
ExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
CastKind PrepareCastToObjCObjectPointer(ExprResult &E)
Prepare a conversion of the given expression to an ObjC object pointer type.
bool CollectMultipleMethodsInGlobalPool(Selector Sel, SmallVectorImpl< ObjCMethodDecl * > &Methods, bool InstanceFirst, bool CheckTheOther, const ObjCObjectType *TypeBound=nullptr)
We first select the type of the method: Instance or Factory, then collect all methods with that type.
bool checkObjCBridgeRelatedComponents(SourceLocation Loc, QualType DestType, QualType SrcType, ObjCInterfaceDecl *&RelatedClass, ObjCMethodDecl *&ClassMethod, ObjCMethodDecl *&InstanceMethod, TypedefNameDecl *&TDNDecl, bool CfToNs, bool Diagnose=true)
void EmitRelatedResultTypeNoteForReturn(QualType destType)
Given that we had incompatible pointer types in a return statement, check whether we're in a method w...
void diagnoseARCUnbridgedCast(Expr *e)
Given that we saw an expression with the ARCUnbridgedCastTy placeholder type, complain bitterly.
ObjCMethodDecl * LookupMethodInQualifiedType(Selector Sel, const ObjCObjectPointerType *OPT, bool IsInstance)
LookupMethodInQualifiedType - Lookups up a method in protocol qualifier list of a qualified objective...
ARCConversionResult CheckObjCConversion(SourceRange castRange, QualType castType, Expr *&op, CheckedConversionKind CCK, bool Diagnose=true, bool DiagnoseCFAudited=false, BinaryOperatorKind Opc=BO_PtrMemD, bool IsReinterpretCast=false)
Checks for invalid conversions and casts between retainable pointers and other pointer kinds for ARC ...
bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, CastKind &Kind)
bool CheckObjCARCUnavailableWeakConversion(QualType castType, QualType ExprType)
bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, ArrayRef< const Expr * > Args)
Expr * stripARCUnbridgedCast(Expr *e)
stripARCUnbridgedCast - Given an expression of ARCUnbridgedCast type, remove the placeholder cast.
ExprResult BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr, Expr *IndexExpr, ObjCMethodDecl *getterMethod, ObjCMethodDecl *setterMethod)
Build an ObjC subscript pseudo-object expression, given that that's supported by the runtime.
bool isSelfExpr(Expr *RExpr)
Private Helper predicate to check for 'self'.
ExprResult ActOnObjCAvailabilityCheckExpr(llvm::ArrayRef< AvailabilitySpec > AvailSpecs, SourceLocation AtLoc, SourceLocation RParen)
bool isKnownName(StringRef name)
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
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.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
CompoundStmt * getSubStmt()
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
SourceLocation getEndLoc() const LLVM_READONLY
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
tokloc_iterator tokloc_begin() const
tokloc_iterator tokloc_end() const
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, ArrayRef< SourceLocation > Locs)
This is the "fully general" constructor that allows representation of strings formed from one or more...
StringRef getString() const
The top declaration context.
Represents a declaration of a type.
SourceLocation getBeginLoc() const LLVM_READONLY
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
bool isBlockPointerType() const
const ObjCObjectPointerType * getAsObjCQualifiedClassType() const
bool isBooleanType() const
const ObjCObjectPointerType * getAsObjCQualifiedIdType() const
bool isObjCBuiltinType() const
bool isVoidPointerType() const
bool isObjCARCBridgableType() const
Determine whether the given type T is a "bridgable" Objective-C type, which is either an Objective-C ...
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool canHaveNullability(bool ResultIfUnknown=true) const
Determine whether the given type can have a nullability specifier applied to it, i....
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isCARCBridgableType() const
Determine whether the given type T is a "bridgeable" C type.
bool isObjCIdType() const
bool isObjCClassOrClassKindOfType() const
Whether the type is Objective-C 'Class' or a __kindof type of an Class type, e.g.,...
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isObjCObjectPointerType() const
bool isObjCQualifiedClassType() const
bool isObjCClassType() const
std::optional< ArrayRef< QualType > > getObjCSubstitutions(const DeclContext *dc) const
Retrieve the set of substitutions required when accessing a member of the Objective-C receiver type t...
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
const ObjCObjectType * getAsObjCInterfaceType() const
bool isAnyPointerType() const
bool isObjCIdOrObjectKindOfType(const ASTContext &ctx, const ObjCObjectType *&bound) const
Whether the type is Objective-C 'id' or a __kindof type of an object type, e.g., __kindof NSView * or...
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
bool isObjCRetainableType() const
NullabilityKindOrNone getNullability() const
Determine the nullability of the given type.
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Base class for declarations which introduce a typedef-name.
QualType getUnderlyingType() const
TypedefNameDecl * getDecl() const
Simple class containing the result of Sema::CorrectTypo.
DeclClass * getCorrectionDeclAs() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
static UnaryOperator * Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, FPOptionsOverride FPFeatures)
Represents a C++ unqualified-id that has been parsed.
void setImplicitSelfParam(const IdentifierInfo *Id)
Specify that this unqualified-id is an implicit 'self' parameter.
void setType(QualType newType)
bool isCommitable() const
edit_iterator edit_begin() const
SmallVectorImpl< Edit >::const_iterator edit_iterator
edit_iterator edit_end() const
Retains information about a function, method, or block that is currently being parsed.
bool ObjCIsDesignatedInit
True when this is a method marked as a designated initializer.
bool ObjCWarnForNoInitDelegation
This starts true for a secondary initializer method and will be set to false if there is an invocatio...
bool ObjCIsSecondaryInit
True when this is an initializer method not marked as a designated initializer within a class that ha...
bool ObjCWarnForNoDesignatedInitChain
This starts true for a method marked as designated initializer and will be set to false if there is a...
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
constexpr Variable var(Literal L)
Returns the variable of L.
bool rewriteObjCRedundantCallWithLiteral(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
bool followsCreateRule(const FunctionDecl *FD)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
@ Ambiguous
Name lookup results in an ambiguity; use getAmbiguityKind to figure out what kind of ambiguity we hav...
@ NotFound
No entity found met the criteria.
@ FoundOverloaded
Name lookup found a set of overloaded functions that met the criteria.
@ Found
Name lookup found a single declaration that met the criteria.
@ FoundUnresolvedValue
Name lookup found an unresolvable value declaration and cannot yet complete.
@ NotFoundInCurrentInstantiation
No entity found met the criteria within the current instantiation,, but there were dependent base cla...
NullabilityKind
Describes the nullability of a particular type.
@ Nullable
Values of this type can be null.
@ NonNull
Values of this type can never be null.
@ OK_ObjCProperty
An Objective-C property is a logical field of an Objective-C object which is read and written via Obj...
@ OK_ObjCSubscript
An Objective-C array/dictionary subscripting which reads an object or writes at the subscripted array...
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
ActionResult< Decl * > DeclResult
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
ObjCMethodFamily
A family of Objective-C methods.
@ OMF_None
No particular method family.
MutableArrayRef< Expr * > MultiExprArg
@ Parameter
The parameter type of a method or function.
@ Result
The result type of a method or function.
ObjCBridgeCastKind
The kind of bridging performed by the Objective-C bridge cast.
@ OBC_Bridge
Bridging via __bridge, which does nothing but reinterpret the bits.
@ OBC_BridgeTransfer
Bridging via __bridge_transfer, which transfers ownership of an Objective-C pointer into ARC.
@ OBC_BridgeRetained
Bridging via __bridge_retain, which makes an ARC object available as a +1 C pointer.
CastKind
CastKind - The kind of operation required for a conversion.
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
U cast(CodeGen::Address addr)
@ None
The alignment was not explicit in code.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
@ None
No keyword precedes the qualified type name.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
CheckedConversionKind
The kind of conversion being performed.
@ Implicit
An implicit conversion.
@ CStyleCast
A C-style cast.
@ ForBuiltinOverloadedOp
A conversion for an operand of a builtin overloaded operator.
@ OtherCast
A cast other than a C-style cast.
@ FunctionalCast
A functional-style cast.
OptionalUnsigned< NullabilityKind > NullabilityKindOrNone
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
EvalResult is a struct with detailed info about an evaluated expression.
An element in an Objective-C dictionary literal.
a linked list of methods with the same selector name but different signatures.
ObjCMethodDecl * getMethod() const
ObjCMethodList * getNext() const
CharSourceRange getFileRange(SourceManager &SM) const
CharSourceRange getInsertFromRange(SourceManager &SM) const