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;
1431 Selector MatchedSel = OM->getSelector();
1434 Diag(SelKWLoc, diag::warn_undeclared_selector_with_typo)
1435 << Sel << MatchedSel
1440 Diag(SelKWLoc, diag::warn_undeclared_selector) << Sel;
1443 WarnMultipleSelectors);
1445 bool onlyDirect =
true;
1446 bool anyDirect =
false;
1451 Diag(AtLoc, diag::err_direct_selector_expression)
1452 <<
Method->getSelector();
1453 Diag(
Method->getLocation(), diag::note_direct_method_declared_at)
1454 <<
Method->getDeclName();
1455 }
else if (anyDirect) {
1461 if (LikelyTargetMethod && LikelyTargetMethod->
isDirectMethod()) {
1462 Diag(AtLoc, diag::warn_potentially_direct_selector_expression) << Sel;
1464 diag::note_direct_method_declared_at)
1466 }
else if (!LikelyTargetMethod) {
1469 Diag(AtLoc, diag::warn_strict_potentially_direct_selector_expression)
1472 diag::note_direct_method_declared_at)
1479 Method->getImplementationControl() !=
1481 !
SemaRef.getSourceManager().isInSystemHeader(
Method->getLocation()))
1493 Diag(AtLoc, diag::err_arc_illegal_selector) <<
1510 QualType Ty = Context.getObjCSelType();
1511 return new (Context)
ObjCSelectorExpr(Ty, Sel, AtLoc, SelNameLoc, RParenLoc);
1523 Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;
1527 Diag(ProtoLoc, diag::err_objc_non_runtime_protocol_in_protocol_expr)
1530 Diag(ProtoLoc, diag::err_atprotocol_protocol) << PDecl;
1536 QualType Ty = Context.getObjCProtoType();
1539 Ty = Context.getObjCObjectPointerType(Ty);
1540 return new (Context)
ObjCProtocolExpr(Ty, PDecl, AtLoc, ProtoIdLoc, RParenLoc);
1561 if (
auto nullability = AttributedType::stripOuterNullability(
T)) {
1562 if (
T == Context.getObjCInstanceType()) {
1563 return Context.getAttributedType(*nullability, Context.getObjCIdType(),
1564 Context.getObjCIdType());
1570 if (
T == Context.getObjCInstanceType())
1571 return Context.getObjCIdType();
1584 bool isClassMessage,
1585 bool isSuperMessage) {
1586 assert(Method &&
"Must have a method");
1587 if (!Method->hasRelatedResultType())
1588 return Method->getSendResultType(ReceiverType);
1596 if (
auto nullability =
1597 Method->getSendResultType(ReceiverType)->getNullability()) {
1599 (void)AttributedType::stripOuterNullability(
type);
1602 return Context.getAttributedType(*nullability,
type,
type);
1612 if (Method->isInstanceMethod() && isClassMessage)
1614 Method->getSendResultType(ReceiverType));
1618 if (isSuperMessage) {
1621 return transferNullability(
1622 Context.getObjCObjectPointerType(
1623 Context.getObjCInterfaceType(Class)));
1629 return transferNullability(Context.getObjCObjectPointerType(ReceiverType));
1635 Method->getSendResultType(ReceiverType));
1640 return transferNullability(ReceiverType);
1646 bool isClassMessage,
1647 bool isSuperMessage) {
1651 SemaRef, ReceiverType,
Method, isClassMessage, isSuperMessage);
1654 if (isClassMessage) {
1663 AttributedType::stripOuterNullability(
T);
1664 if (
T == Context.getObjCInstanceType()) {
1668 ->getDeclContext());
1670 QualType NewResultType = Context.getObjCObjectPointerType(
1673 NewResultType = Context.getAttributedType(*Nullability, NewResultType,
1675 return NewResultType;
1687 unsigned receiverNullabilityIdx = 0;
1691 receiverNullabilityIdx = 1 +
static_cast<unsigned>(*nullability);
1694 unsigned resultNullabilityIdx = 0;
1698 resultNullabilityIdx = 1 +
static_cast<unsigned>(*nullability);
1703 static const uint8_t
None = 0;
1704 static const uint8_t
NonNull = 1;
1707 static const uint8_t nullabilityMap[4][4] = {
1715 unsigned newResultNullabilityIdx
1716 = nullabilityMap[receiverNullabilityIdx][resultNullabilityIdx];
1717 if (newResultNullabilityIdx == resultNullabilityIdx)
1723 if (
auto attributed = dyn_cast<AttributedType>(resultType.
getTypePtr())) {
1724 resultType = attributed->getModifiedType();
1731 if (newResultNullabilityIdx > 0) {
1734 return Context.getAttributedType(newNullability, resultType, resultType);
1753 dyn_cast<ObjCCategoryImplDecl>(impl)) {
1754 iface = catImpl->getCategoryDecl();
1756 iface = impl->getClassInterface();
1766 for (
unsigned i = 0, e = overrides.size(); i != e; ++i) {
1781 Context.hasSameUnqualifiedType(destType, MD->
getReturnType()))
1788 SourceRange range = overridden->getReturnTypeSourceRange();
1791 loc = overridden->getLocation();
1792 Diag(loc, diag::note_related_result_type_explicit)
1816 if (!
Method->hasRelatedResultType())
1819 if (Context.hasSameUnqualifiedType(
1820 Method->getReturnType().getNonReferenceType(), MsgSend->
getType()))
1823 if (!Context.hasSameUnqualifiedType(
Method->getReturnType(),
1824 Context.getObjCInstanceType()))
1827 Diag(
Method->getLocation(), diag::note_related_result_type_inferred)
1840 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
1841 SelLoc = SelectorLocs.front();
1847 for (
unsigned i = 0, e = Args.size(); i != e; i++) {
1848 if (Args[i]->isTypeDependent())
1854 result =
SemaRef.checkUnknownAnyArg(SelLoc, Args[i], paramTy);
1856 result =
SemaRef.DefaultArgumentPromotion(Args[i]);
1860 Args[i] = result.
get();
1865 DiagID = diag::err_arc_method_not_found;
1867 DiagID = isClassMessage ? diag::warn_class_method_not_found
1868 : diag::warn_inst_method_not_found;
1873 DiagID = diag::err_method_not_found_with_typo;
1875 DiagID = isClassMessage ? diag::warn_class_method_not_found_with_typo
1876 : diag::warn_instance_method_not_found_with_typo;
1878 SourceRange SelectorRange(SelectorLocs.front(), SelectorLocs.back());
1880 Diag(SelLoc, DiagID)
1881 << Sel<< isClassMessage << MatchedSel
1884 Diag(SelLoc, DiagID) << Sel<< isClassMessage << MatchedSel;
1887 Diag(SelLoc, DiagID)
1888 << Sel << isClassMessage <<
SourceRange(SelectorLocs.front(),
1889 SelectorLocs.back());
1893 Diag(ThisClass->getLocation(), diag::note_receiver_class_declared);
1895 if (ThisClass->lookupClassMethod(Sel))
1896 Diag(RecRange.
getBegin(), diag::note_receiver_expr_here)
1898 ThisClass->getNameAsString());
1906 ReturnType = Context.UnknownAnyTy;
1908 ReturnType = Context.getObjCIdType();
1915 isClassMessage, isSuperMessage);
1922 NumNamedArgs =
Method->param_size();
1924 if (Args.size() < NumNamedArgs) {
1925 Diag(SelLoc, diag::err_typecheck_call_too_few_args)
1926 << 2 << NumNamedArgs << static_cast<unsigned>(Args.size())
1933 std::optional<ArrayRef<QualType>> typeArgs =
1935 bool IsError =
false;
1936 for (
unsigned i = 0; i < NumNamedArgs; i++) {
1938 if (Args[i]->isTypeDependent())
1941 Expr *argExpr = Args[i];
1944 assert(argExpr &&
"CheckMessageArgumentTypes(): missing expression");
1946 if (param->
hasAttr<NoEscapeAttr>() &&
1948 if (
auto *BE = dyn_cast<BlockExpr>(
1950 BE->getBlockDecl()->setDoesNotEscape();
1955 !param->
hasAttr<CFConsumedAttr>())
1960 if (param->
getType() == Context.UnknownAnyTy) {
1966 Args[i] = argE.
get();
1982 if (
SemaRef.RequireCompleteType(
1984 diag::err_call_incomplete_argument, argExpr))
2000 Args[i]->getType()->isBlockPointerType() &&
2003 SemaRef.maybeExtendBlockObject(arg);
2004 Args[i] = arg.get();
2010 if (
Method->isVariadic()) {
2011 for (
unsigned i = NumNamedArgs, e = Args.size(); i < e; ++i) {
2012 if (Args[i]->isTypeDependent())
2018 Args[i] = Arg.
get();
2022 if (Args.size() != NumNamedArgs) {
2023 Diag(Args[NumNamedArgs]->getBeginLoc(),
2024 diag::err_typecheck_call_too_many_args)
2025 << 2 << NumNamedArgs << static_cast<unsigned>(Args.size())
2026 <<
Method->getSourceRange() << 0
2028 Args.back()->getEndLoc());
2044 SemaRef.CurContext->getNonClosureAncestor());
2049 if (!method)
return false;
2052 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(receiver))
2064 if (
ObjCMethodDecl *method = iface->lookupMethod(sel, isInstance))
2069 if (
ObjCMethodDecl *method = iface->lookupPrivateMethod(sel, isInstance))
2074 for (
const auto *I : objType->quals())
2086 for (
const auto *PROTO : OPT->
quals()) {
2087 if ((MD = PROTO->lookupMethod(Sel, Instance))) {
2102 assert(IFaceT &&
"Expected an Interface");
2106 Diag(MemberLoc, diag::err_invalid_property_name)
2116 diag::err_property_not_found_forward_class,
2117 MemberName, BaseRange))
2123 if (
SemaRef.DiagnoseUseOfDecl(PD, MemberLoc))
2126 return new (Context)
2130 return new (Context)
2135 for (
const auto *I : OPT->
quals())
2139 if (
SemaRef.DiagnoseUseOfDecl(PD, MemberLoc))
2145 SuperLoc, SuperType);
2147 return new (Context)
2170 if (
SemaRef.DiagnoseUseOfDecl(Getter, MemberLoc))
2189 if (Setter &&
SemaRef.DiagnoseUseOfDecl(Setter, MemberLoc))
2201 if (!(PDecl->getPropertyAttributes() &
2204 diag::warn_property_access_suggest)
2205 << MemberName <<
QualType(OPT, 0) << PDecl->getName()
2210 if (Getter || Setter) {
2212 return new (Context)
2216 return new (Context)
2233 Corrected.isKeyword() ?
nullptr : Corrected.getFoundDecl();
2238 Diag(MemberLoc, diag::err_class_property_found) << MemberName
2245 SemaRef.diagnoseTypo(Corrected,
2246 PDiag(diag::err_property_not_found_suggest)
2247 << MemberName <<
QualType(OPT, 0));
2249 TypoResult, MemberLoc,
2250 SuperLoc, SuperType, Super);
2258 T->getAsObjCInterfacePointerType()) {
2259 if (
SemaRef.RequireCompleteType(MemberLoc, OBJPT->getPointeeType(),
2260 diag::err_property_not_as_forward_class,
2261 MemberName, BaseExpr))
2265 diag::err_ivar_access_using_property_syntax_suggest)
2266 << MemberName <<
QualType(OPT, 0) << Ivar->getDeclName()
2271 Diag(MemberLoc, diag::err_property_not_found)
2291 if (receiverNamePtr->
isStr(
"super")) {
2293 if (
auto classDecl = CurMethod->getClassInterface()) {
2294 SuperType =
QualType(classDecl->getSuperClassType(), 0);
2295 if (CurMethod->isInstanceMethod()) {
2296 if (SuperType.
isNull()) {
2298 Diag(receiverNameLoc, diag::err_root_class_cannot_use_super)
2299 << CurMethod->getClassInterface()->getIdentifier();
2302 QualType T = Context.getObjCObjectPointerType(SuperType);
2309 receiverNameLoc,
T,
true);
2320 Diag(receiverNameLoc, diag::err_expected_either) << tok::identifier
2330 GetterSel = PD->getGetterName();
2331 SetterSel = PD->getSetterName();
2333 GetterSel =
SemaRef.PP.getSelectorTable().getNullarySelector(&propertyName);
2349 if (
SemaRef.DiagnoseUseOfDecl(Getter, propertyNameLoc))
2364 if (Setter &&
SemaRef.DiagnoseUseOfDecl(Setter, propertyNameLoc))
2367 if (Getter || Setter) {
2369 return new (Context)
2376 propertyNameLoc, receiverNameLoc, IFace);
2378 return ExprError(
Diag(propertyNameLoc, diag::err_property_not_found)
2379 << &propertyName << Context.getObjCInterfaceType(IFace));
2389 WantObjCSuper =
Method->getClassInterface()->getSuperClass();
2392 bool ValidateCandidate(
const TypoCorrection &candidate)
override {
2397 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
2398 return std::make_unique<ObjCInterfaceOrSuperCCC>(*
this);
2407 bool HasTrailingDot,
ParsedType &ReceiverType) {
2409 ReceiverType =
nullptr;
2420 switch (
Result.getResultKind()) {
2427 if (!
Method->getClassInterface()) {
2433 if (
Method->getClassInterface()->lookupInstanceVariable(Name,
2445 Result.suppressDiagnostics();
2458 T = Context.getObjCInterfaceType(
Class);
2462 std::nullopt,
Type);
2468 TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(
T, NameLoc);
2469 ReceiverType =
SemaRef.CreateParsedType(
T, TSInfo);
2474 ObjCInterfaceOrSuperCCC CCC(
SemaRef.getCurMethodDecl());
2476 Result.getLookupNameInfo(),
Result.getLookupKind(), S,
nullptr, CCC,
2478 if (Corrected.isKeyword()) {
2481 SemaRef.diagnoseTypo(Corrected,
PDiag(diag::err_unknown_receiver_suggest)
2488 SemaRef.diagnoseTypo(Corrected,
PDiag(diag::err_unknown_receiver_suggest)
2491 TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(
T, NameLoc);
2492 ReceiverType =
SemaRef.CreateParsedType(
T, TSInfo);
2510 Diag(SuperLoc, diag::err_invalid_receiver_to_message_super);
2516 Diag(SuperLoc, diag::err_no_super_class_message)
2517 <<
Method->getDeclName();
2524 Diag(SuperLoc, diag::err_root_class_cannot_use_super)
2525 <<
Class->getIdentifier();
2531 if (
Method->getSelector() == Sel)
2532 SemaRef.getCurFunction()->ObjCShouldCallSuper =
false;
2534 if (
Method->isInstanceMethod()) {
2537 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2540 LBracLoc, SelectorLocs, RBracLoc, Args);
2547 SuperLoc, Sel,
nullptr,
2548 LBracLoc, SelectorLocs, RBracLoc, Args);
2552 bool isSuperReceiver,
2558 if (!ReceiverType.
isNull())
2559 receiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType);
2561 assert(((isSuperReceiver && Loc.
isValid()) || receiverTypeInfo) &&
2562 "Either the super receiver location needs to be valid or the receiver "
2563 "needs valid type source information");
2566 Sel,
Method, Loc, Loc, Loc, Args,
2581 auto Builder = S.
Diag(MsgLoc, DiagID)
2589 switch (Edit.
Kind) {
2596 Builder.AddFixItHint(
2617 bool IsClassObjectCall) {
2623 const auto *SE = dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens());
2627 if (!IsClassObjectCall) {
2629 if (!OPT || !OPT->getInterfaceDecl())
2632 OPT->getInterfaceDecl()->lookupInstanceMethod(SE->getSelector());
2635 OPT->getInterfaceDecl()->lookupPrivateMethod(SE->getSelector());
2640 ImpliedMethod = IT->getDecl()->lookupClassMethod(SE->getSelector());
2643 IT->getDecl()->lookupPrivateClassMethod(SE->getSelector());
2648 if (Ret->isRecordType() || Ret->isVectorType() || Ret->isExtVectorType()) {
2649 S.
Diag(Loc, diag::warn_objc_unsafe_perform_selector)
2650 << Method->getSelector()
2651 << (!Ret->isRecordType()
2653 : Ret->isUnionType() ? 1 : 0);
2655 diag::note_objc_unsafe_perform_selector_method_declared_here)
2666 Expr **Args,
unsigned NumArgs) {
2668 bool Format =
false;
2675 for (
const auto *I : Method->specific_attrs<FormatAttr>()) {
2682 if (!Format || NumArgs <= Idx)
2685 Expr *FormatExpr = Args[Idx];
2690 S.
Diag(FormatExpr->
getExprLoc(), diag::warn_objc_cdirective_format_string)
2693 S.
Diag(Method->getLocation(), diag::note_method_declared_at)
2694 << Method->getDeclName();
2736 Diag(Loc, diag::err_missing_open_square_message_send)
2741 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
2742 SelectorSlotLocs = SelectorLocs;
2744 SelectorSlotLocs = Loc;
2750 unsigned NumArgs = ArgsIn.size();
2751 Expr **Args = ArgsIn.data();
2752 assert(SuperLoc.
isInvalid() &&
"Message to super with dependent type");
2754 ReceiverTypeInfo, Sel, SelectorLocs,
2756 RBracLoc, isImplicit);
2762 if (!ClassType || !(
Class = ClassType->getInterface())) {
2763 Diag(Loc, diag::err_invalid_receiver_class_message)
2767 assert(
Class &&
"We don't know which class we're messaging?");
2770 (void)
SemaRef.DiagnoseUseOfDecl(
Class, SelectorSlotLocs);
2776 if (
SemaRef.RequireCompleteType(Loc, Context.getObjCInterfaceType(
Class),
2778 ? diag::err_arc_receiver_forward_class
2779 : diag::warn_receiver_forward_class),
2785 Diag(
Method->getLocation(), diag::note_method_sent_forward_class)
2786 <<
Method->getDeclName();
2796 false,
false,
Class))
2804 unsigned NumArgs = ArgsIn.size();
2805 Expr **Args = ArgsIn.data();
2812 if (
Method && !
Method->getReturnType()->isVoidType() &&
2814 LBracLoc,
Method->getReturnType(),
2815 diag::err_illegal_message_expr_incomplete_type))
2819 Diag(SuperLoc, diag::err_messaging_super_with_direct_method)
2823 :
Method->getClassInterface()->getName());
2824 Diag(
Method->getLocation(), diag::note_direct_method_declared_at)
2825 <<
Method->getDeclName();
2832 dyn_cast<ObjCInterfaceDecl>(
Method->getDeclContext());
2834 Diag(Loc, diag::warn_direct_initialize_call);
2835 Diag(
Method->getLocation(), diag::note_method_declared_at)
2836 <<
Method->getDeclName();
2841 Diag(Loc, diag::warn_direct_super_initialize_call);
2842 Diag(
Method->getLocation(), diag::note_method_declared_at)
2843 <<
Method->getDeclName();
2844 Diag(CurMeth->getLocation(), diag::note_method_declared_at)
2845 << CurMeth->getDeclName();
2856 Context, ReturnType,
VK, LBracLoc, SuperLoc,
false,
2857 ReceiverType, Sel, SelectorLocs,
Method,
ArrayRef(Args, NumArgs),
2858 RBracLoc, isImplicit);
2861 Context, ReturnType,
VK, LBracLoc, ReceiverTypeInfo, Sel, SelectorLocs,
2868 ReceiverType,
true);
2883 SemaRef.GetTypeFromParser(Receiver, &ReceiverTypeInfo);
2884 if (ReceiverType.
isNull())
2887 if (!ReceiverTypeInfo)
2888 ReceiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType, LBracLoc);
2892 nullptr, LBracLoc, SelectorLocs, RBracLoc,
2901 Sel,
Method, Loc, Loc, Loc, Args,
2908 const auto *Protocol = dyn_cast<ObjCProtocolDecl>(M->
getDeclContext());
2913 if (
const auto *RootClass = dyn_cast_or_null<ObjCInterfaceDecl>(
2917 if (P->getCanonicalDecl() == Protocol->getCanonicalDecl())
2957 assert((Receiver || SuperLoc.
isValid()) &&
"If the Receiver is null, the "
2958 "SuperLoc must be valid so we can "
2967 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
2968 SelectorSlotLocs = SelectorLocs;
2970 SelectorSlotLocs = Loc;
2974 Diag(Loc, diag::err_missing_open_square_message_send)
2984 if (Receiver->
getType() == Context.UnknownAnyTy)
2986 SemaRef.forceUnknownAnyToType(Receiver, Context.getObjCIdType());
2996 unsigned NumArgs = ArgsIn.size();
2997 Expr **Args = ArgsIn.data();
2998 assert(SuperLoc.
isInvalid() &&
"Message to super with dependent type");
3000 Context, Context.DependentTy,
VK_PRValue, LBracLoc, Receiver, Sel,
3001 SelectorLocs,
nullptr,
ArrayRef(Args, NumArgs), RBracLoc,
3011 ReceiverType = Receiver->
getType();
3019 !Context.getObjCIdType().isNull() &&
3024 Diag(Loc, diag::warn_bad_receiver_type) << ReceiverType << RecRange;
3027 .ImpCastExprToType(Receiver, Context.getObjCIdType(),
3028 CK_CPointerToObjCPointerCast)
3034 CastKind Kind =
IsNull ? CK_NullToPointer : CK_IntegralToPointer;
3036 SemaRef.ImpCastExprToType(Receiver, Context.getObjCIdType(), Kind)
3039 ReceiverType = Receiver->
getType();
3043 diag::err_incomplete_receiver_type))
3047 SemaRef.PerformContextuallyConvertToObjCPointer(Receiver);
3049 Receiver = result.
get();
3050 ReceiverType = Receiver->
getType();
3066 (Receiver && Context.isObjCNSObjectType(Receiver->
getType()))) {
3071 if (!Methods.empty()) {
3077 Sel, ArgsIn,
Method->isInstanceMethod(), Methods))
3082 receiverIsIdLike, Methods))
3100 Diag(SelLoc, diag::warn_instance_method_on_class_found)
3101 <<
Method->getSelector() << Sel;
3102 Diag(
Method->getLocation(), diag::note_method_declared_at)
3103 <<
Method->getDeclName();
3113 Method = ClassDecl->lookupClassMethod(Sel);
3116 Method = ClassDecl->lookupPrivateClassMethod(Sel);
3131 if (!Methods.empty()) {
3137 if (
Method->isInstanceMethod()) {
3139 dyn_cast<ObjCInterfaceDecl>(
Method->getDeclContext())) {
3140 if (ID->getSuperClass())
3141 Diag(SelLoc, diag::warn_root_inst_method_not_found)
3147 Sel, ArgsIn,
Method->isInstanceMethod(), Methods))
3170 ClassDecl = OCIType->getInterfaceDecl();
3177 if (
SemaRef.RequireCompleteType(
3178 Loc, OCIType->getPointeeType(),
3180 ? diag::err_arc_receiver_forward_instance
3181 : diag::warn_receiver_forward_instance,
3186 forwardClass = OCIType->getInterfaceDecl();
3188 diag::note_receiver_is_id);
3203 Diag(SelLoc, diag::err_arc_may_not_respond)
3204 << OCIType->getPointeeType() << Sel << RecRange
3205 <<
SourceRange(SelectorLocs.front(), SelectorLocs.back());
3213 if (OCIType->qual_empty()) {
3218 if (!Methods.empty()) {
3224 Sel, ArgsIn,
Method->isInstanceMethod(), Methods))
3232 if (
Method && !forwardClass)
3233 Diag(SelLoc, diag::warn_maynot_respond)
3234 << OCIType->getInterfaceDecl()->getIdentifier()
3240 SemaRef.DiagnoseUseOfDecl(
Method, SelectorSlotLocs, forwardClass))
3244 Diag(Loc, diag::err_bad_receiver_type) << ReceiverType << RecRange;
3252 ?
SemaRef.getEnclosingFunction()
3258 diag::err_messaging_unqualified_id_with_direct_method);
3259 Diag(
Method->getLocation(), diag::note_direct_method_declared_at)
3260 <<
Method->getDeclName();
3270 diag::err_messaging_class_with_direct_method);
3273 RecRange,
Method->getClassInterface()->getName()));
3276 Diag(
Method->getLocation(), diag::note_direct_method_declared_at)
3277 <<
Method->getDeclName();
3283 Diag(SuperLoc, diag::err_messaging_super_with_direct_method);
3286 SuperLoc,
Method->getClassInterface()->getName()));
3291 Diag(
Method->getLocation(), diag::note_direct_method_declared_at)
3292 <<
Method->getDeclName();
3294 }
else if (ReceiverType->
isObjCIdType() && !isImplicit) {
3295 Diag(Receiver->
getExprLoc(), diag::warn_messaging_unqualified_id);
3298 if (DIFunctionScopeInfo &&
3301 bool isDesignatedInitChain =
false;
3308 if (!ID->declaresOrInheritsDesignatedInitializers() ||
3309 ID->isDesignatedInitializer(Sel)) {
3310 isDesignatedInitChain =
true;
3316 if (!isDesignatedInitChain) {
3318 auto *CurMD =
SemaRef.getCurMethodDecl();
3319 assert(CurMD &&
"Current method declaration should not be null");
3321 CurMD->isDesignatedInitializerForTheInterface(&InitMethod);
3322 assert(isDesignated && InitMethod);
3325 diag::warn_objc_designated_init_non_designated_init_call :
3326 diag::warn_objc_designated_init_non_super_designated_init_call);
3328 diag::note_objc_designated_init_marked_here);
3332 if (DIFunctionScopeInfo &&
3336 Diag(SelLoc, diag::warn_objc_secondary_init_super_init_call);
3343 unsigned NumArgs = ArgsIn.size();
3344 Expr **Args = ArgsIn.data();
3352 LBracLoc, RBracLoc, RecRange, ReturnType,
VK))
3355 if (
Method && !
Method->getReturnType()->isVoidType() &&
3357 LBracLoc,
Method->getReturnType(),
3358 diag::err_illegal_message_expr_incomplete_type))
3387 Diag(SelLoc, diag::err_arc_illegal_explicit_message)
3392 if (
Method && NumArgs >= 1) {
3393 if (
const auto *SelExp =
3394 dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens())) {
3395 Selector ArgSel = SelExp->getSelector();
3398 SelExp->getSourceRange());
3402 SelExp->getSourceRange());
3405 switch (SelFamily) {
3412 if (!SelMethod->
hasAttr<NSReturnsNotRetainedAttr>()) {
3415 diag::err_arc_perform_selector_retains);
3422 if (SelMethod->
hasAttr<NSReturnsRetainedAttr>()) {
3425 diag::err_arc_perform_selector_retains);
3434 Diag(SelLoc, diag::warn_arc_perform_selector_leaks);
3435 Diag(Args[0]->getExprLoc(), diag::note_used_here);
3448 Context, ReturnType,
VK, LBracLoc, SuperLoc,
true,
3449 ReceiverType, Sel, SelectorLocs,
Method,
ArrayRef(Args, NumArgs),
3450 RBracLoc, isImplicit);
3453 Context, ReturnType,
VK, LBracLoc, Receiver, Sel, SelectorLocs,
Method,
3454 ArrayRef(Args, NumArgs), RBracLoc, isImplicit);
3459 bool IsClassObjectCall = ClassMessage;
3466 if (OPT->getObjectType()->isObjCClass()) {
3467 if (
const auto *CurMeth =
SemaRef.getCurMethodDecl()) {
3468 IsClassObjectCall =
true;
3470 Context.getObjCInterfaceType(CurMeth->getClassInterface());
3476 ReceiverType, IsClassObjectCall);
3489 Result->setDelegateInitCall(
true);
3500 if (!isImplicit &&
Method) {
3506 if (IsWeak && !
SemaRef.isUnevaluatedContext() &&
3545 SemaRef.MaybeConvertParenListExprToParenExpr(S, Receiver);
3551 IdentifierInfo *SelectorId = &Context.Idents.get(
"respondsToSelector");
3559 nullptr, LBracLoc, SelectorLocs,
3593 bool isIndirect =
false;
3597 type = ref->getPointeeType();
3604 type = ptr->getPointeeType();
3611 }
else if (
const ArrayType *array =
type->getAsArrayTypeUnsafe()) {
3612 type =
QualType(array->getElementType()->getBaseElementTypeUnsafe(), 0);
3620 if (
type->isObjCARCBridgableType())
3625 if (
type->isObjCARCBridgableType())
3646 ACCResult
merge(ACCResult left, ACCResult right) {
3647 if (left == right)
return left;
3648 if (left == ACC_bottom)
return right;
3649 if (right == ACC_bottom)
return left;
3655 class ARCCastChecker :
public StmtVisitor<ARCCastChecker, ACCResult> {
3656 typedef StmtVisitor<ARCCastChecker, ACCResult> super;
3658 ASTContext &Context;
3663 static bool isCFType(QualType
type) {
3665 return type->isCARCBridgableType();
3671 : Context(Context), SourceClass(source), TargetClass(target),
3672 Diagnose(diagnose) {}
3675 ACCResult Visit(Expr *e) {
3679 ACCResult VisitStmt(Stmt *s) {
3684 ACCResult VisitExpr(Expr *e) {
3691 ACCResult VisitObjCObjectLiteral(ObjCObjectLiteral *OL) {
3700 ACCResult VisitObjCStringLiteral(ObjCStringLiteral *SL) {
3701 return VisitObjCObjectLiteral(SL);
3704 ACCResult VisitObjCBoxedExpr(ObjCBoxedExpr *OBE) {
3705 return VisitObjCObjectLiteral(OBE);
3708 ACCResult VisitObjCArrayLiteral(ObjCArrayLiteral *AL) {
3709 return VisitObjCObjectLiteral(AL);
3712 ACCResult VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *DL) {
3713 return VisitObjCObjectLiteral(DL);
3717 ACCResult VisitCastExpr(
CastExpr *e) {
3719 case CK_NullToPointer:
3723 case CK_LValueToRValue:
3725 case CK_CPointerToObjCPointerCast:
3726 case CK_BlockPointerToObjCPointerCast:
3727 case CK_AnyPointerToBlockPointerCast:
3736 ACCResult VisitUnaryExtension(UnaryOperator *e) {
3741 ACCResult VisitBinComma(BinaryOperator *e) {
3742 return Visit(e->
getRHS());
3746 ACCResult VisitConditionalOperator(ConditionalOperator *e) {
3748 if (left == ACC_invalid)
return ACC_invalid;
3753 ACCResult VisitPseudoObjectExpr(PseudoObjectExpr *e) {
3759 ACCResult VisitStmtExpr(StmtExpr *e) {
3764 ACCResult VisitDeclRefExpr(DeclRefExpr *e) {
3765 VarDecl *
var = dyn_cast<VarDecl>(e->
getDecl());
3770 !
var->hasDefinition(Context) &&
3771 var->getType().isConstQualified()) {
3778 return ACC_plusZero;
3786 ACCResult VisitCallExpr(CallExpr *e) {
3788 if (ACCResult result = checkCallToFunction(fn))
3791 return super::VisitCallExpr(e);
3794 ACCResult checkCallToFunction(FunctionDecl *fn) {
3803 if (fn->
hasAttr<CFReturnsNotRetainedAttr>())
3804 return ACC_plusZero;
3809 if (fn->
hasAttr<CFReturnsRetainedAttr>())
3810 return Diagnose ? ACC_plusOne
3815 if (builtinID == Builtin::BI__builtin___CFStringMakeConstantString)
3819 if (!fn->
hasAttr<CFAuditedTransferAttr>())
3824 return Diagnose ? ACC_plusOne
3827 return ACC_plusZero;
3830 ACCResult VisitObjCMessageExpr(ObjCMessageExpr *e) {
3834 ACCResult VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *e) {
3835 ObjCMethodDecl *method;
3840 return checkCallToMethod(method);
3843 ACCResult checkCallToMethod(ObjCMethodDecl *method) {
3844 if (!method)
return ACC_invalid;
3853 if (method->
hasAttr<CFReturnsNotRetainedAttr>())
3854 return ACC_plusZero;
3858 if (method->
hasAttr<CFReturnsRetainedAttr>())
3870 return ACC_plusZero;
3885template <
typename DiagBuilderT>
3889 Expr *realCast,
const char *bridgeKeyword,
const char *CFBridgeName) {
3905 NCE->getAngleBrackets().getEnd());
3909 char PrevChar = *
SM.getCharacterData(range.getBegin().getLocWithOffset(-1));
3913 BridgeCall += CFBridgeName;
3920 castedE = CCE->getSubExpr();
3927 char PrevChar = *
SM.getCharacterData(range.getBegin().getLocWithOffset(-1));
3931 BridgeCall += CFBridgeName;
3951 std::string castCode =
"(";
3952 castCode += bridgeKeyword;
3956 NCE->getAngleBrackets().getEnd());
3960 std::string castCode =
"(";
3961 castCode += bridgeKeyword;
3980template <
typename T>
3987 for (
auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) {
3988 if (
auto *
attr = Redecl->getAttr<
T>())
3999 TDNDecl = TD->getDecl();
4000 if (ObjCBridgeRelatedAttr *ObjCBAttr =
4018 UnavailableAttr::IR_ARCForbiddenConversion))
4031 unsigned srcKind = 0;
4055 S.
Diag(loc, diag::err_arc_cast_requires_bridge)
4064 ACCResult CreateRule =
4066 assert(CreateRule != ACC_bottom &&
"This cast should already be accepted.");
4067 if (CreateRule != ACC_plusOne)
4070 ? S.
Diag(noteLoc, diag::note_arc_bridge)
4071 : S.
Diag(noteLoc, diag::note_arc_cstyle_bridge);
4074 castType,
castExpr, realCast,
"__bridge ",
4077 if (CreateRule != ACC_plusZero)
4080 ? S.
Diag(noteLoc, diag::note_arc_cstyle_bridge_transfer)
4083 diag::note_arc_bridge_transfer)
4084 << castExprType << br;
4087 castType,
castExpr, realCast,
"__bridge_transfer ",
4088 br ?
"CFBridgingRelease" :
nullptr);
4097 S.
Diag(loc, diag::err_arc_cast_requires_bridge)
4105 ACCResult CreateRule =
4107 assert(CreateRule != ACC_bottom &&
"This cast should already be accepted.");
4108 if (CreateRule != ACC_plusOne)
4111 ? S.
Diag(noteLoc, diag::note_arc_bridge)
4112 : S.
Diag(noteLoc, diag::note_arc_cstyle_bridge);
4114 castType,
castExpr, realCast,
"__bridge ",
4117 if (CreateRule != ACC_plusZero)
4120 ? S.
Diag(noteLoc, diag::note_arc_cstyle_bridge_retained)
4123 diag::note_arc_bridge_retained)
4127 castType,
castExpr, realCast,
"__bridge_retained ",
4128 br ?
"CFBridgingRetain" :
nullptr);
4134 S.
Diag(loc, diag::err_arc_mismatched_cast)
4136 << srcKind << castExprType << castType
4137 << castRange <<
castExpr->getSourceRange();
4140template <
typename TB>
4142 bool &HadTheAttribute,
bool warn) {
4144 HadTheAttribute =
false;
4149 HadTheAttribute =
true;
4150 if (Parm->isStr(
"id"))
4163 = InterfacePointerType->getObjectType()->getInterface();
4164 if ((CastClass == ExprClass) ||
4168 S.
Diag(
castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)
4173 castType, ExprClass)))
4180 S.
Diag(
castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)
4181 <<
T <<
Target->getName() << castType;
4183 S.
Diag(
Target->getBeginLoc(), diag::note_declared_at);
4190 diag::err_objc_cf_bridged_not_interface)
4203template <
typename TB>
4205 bool &HadTheAttribute,
bool warn) {
4207 HadTheAttribute =
false;
4212 HadTheAttribute =
true;
4213 if (Parm->isStr(
"id"))
4221 Target = R.getFoundDecl();
4225 castExpr->getType()->getAsObjCInterfacePointerType()) {
4227 = InterfacePointerType->getObjectType()->getInterface();
4228 if ((CastClass == ExprClass) ||
4233 diag::warn_objc_invalid_bridge_to_cf)
4234 <<
castExpr->getType()->getPointeeType() <<
T;
4238 }
else if (
castExpr->getType()->isObjCIdType() ||
4248 diag::warn_objc_invalid_bridge_to_cf)
4249 <<
castExpr->getType() << castType;
4251 S.
Diag(
Target->getBeginLoc(), diag::note_declared_at);
4258 diag::err_objc_ns_bridged_invalid_cfobject)
4259 <<
castExpr->getType() << castType;
4262 S.
Diag(
Target->getBeginLoc(), diag::note_declared_at);
4279 bool HasObjCBridgeAttr;
4282 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
4284 bool HasObjCBridgeMutableAttr;
4285 bool ObjCBridgeMutableAttrWillNotWarn =
4288 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
4291 if (HasObjCBridgeAttr)
4293 HasObjCBridgeAttr,
true);
4294 else if (HasObjCBridgeMutableAttr)
4299 bool HasObjCBridgeAttr;
4302 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
4304 bool HasObjCBridgeMutableAttr;
4305 bool ObjCBridgeMutableAttrWillNotWarn =
4308 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
4311 if (HasObjCBridgeAttr)
4313 HasObjCBridgeAttr,
true);
4314 else if (HasObjCBridgeMutableAttr)
4323 if (PRE->isExplicitProperty()) {
4325 SrcType = PDecl->getType();
4327 else if (PRE->isImplicitProperty()) {
4329 SrcType = Getter->getReturnType();
4352 : CK_CPointerToObjCPointerCast;
4364 QualType T = CfToNs ? SrcType : DestType;
4380 Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId
4381 << SrcType << DestType;
4386 Target = R.getFoundDecl();
4391 Diag(Loc, diag::err_objc_bridged_related_invalid_class_name) << RCId
4392 << SrcType << DestType;
4395 Diag(
Target->getBeginLoc(), diag::note_declared_at);
4401 if (CfToNs && CMId) {
4402 Selector Sel = Context.Selectors.getUnarySelector(CMId);
4406 Diag(Loc, diag::err_objc_bridged_related_known_method)
4407 << SrcType << DestType << Sel <<
false;
4415 if (!CfToNs && IMId) {
4416 Selector Sel = Context.Selectors.getNullarySelector(IMId);
4417 InstanceMethod = RelatedClass->
lookupMethod(Sel,
true);
4418 if (!InstanceMethod) {
4420 Diag(Loc, diag::err_objc_bridged_related_known_method)
4421 << SrcType << DestType << Sel <<
true;
4440 if (!CfToNs && !NsToCf)
4448 ClassMethod, InstanceMethod, TDNDecl,
4456 std::string ExpressionString =
"[";
4458 ExpressionString +=
" ";
4459 ExpressionString += ClassMethod->getSelector().getAsString();
4463 Diag(Loc, diag::err_objc_bridged_related_known_method)
4464 << SrcType << DestType << ClassMethod->getSelector() <<
false
4471 QualType receiverType = Context.getObjCInterfaceType(RelatedClass);
4473 Expr *args[] = { SrcExpr };
4475 ClassMethod->getLocation(),
4476 ClassMethod->getSelector(), ClassMethod,
4478 SrcExpr = msg.
get();
4485 if (InstanceMethod) {
4487 std::string ExpressionString;
4490 if (InstanceMethod->isPropertyAccessor())
4492 InstanceMethod->findPropertyDecl()) {
4494 ExpressionString =
".";
4495 ExpressionString += PDecl->getNameAsString();
4496 Diag(Loc, diag::err_objc_bridged_related_known_method)
4497 << SrcType << DestType << InstanceMethod->getSelector() <<
true
4500 if (ExpressionString.empty()) {
4502 ExpressionString =
" ";
4503 ExpressionString += InstanceMethod->getSelector().getAsString();
4504 ExpressionString +=
"]";
4506 Diag(Loc, diag::err_objc_bridged_related_known_method)
4507 << SrcType << DestType << InstanceMethod->getSelector() <<
true
4515 SrcExpr, SrcType, InstanceMethod->getLocation(),
4516 InstanceMethod->getSelector(), InstanceMethod, {});
4517 SrcExpr = msg.
get();
4528 bool Diagnose,
bool DiagnoseCFAudited,
4541 if (exprACTC == castACTC) {
4547 castType != castExprType) {
4553 if (
const ParenType *PT = dyn_cast<ParenType>(DT))
4554 QDT = PT->desugar();
4555 else if (
const TypeOfType *TP = dyn_cast<TypeOfType>(DT))
4556 QDT = TP->desugar();
4557 else if (
const AttributedType *AT = dyn_cast<AttributedType>(DT))
4558 QDT = AT->desugar();
4559 if (QDT != castType &&
4564 Diag(loc, diag::err_arc_nolifetime_behavior);
4602 switch (ARCCastChecker(Context, exprACTC, castACTC,
false).Visit(
castExpr)) {
4615 CK_ARCConsumeObject,
castExpr,
nullptr,
4617 SemaRef.Cleanup.setExprNeedsCleanups(
true);
4642 (Opc == BO_NE || Opc == BO_EQ))) {
4664 castType =
cast->getTypeAsWritten();
4667 castRange =
cast->getTypeInfoAsWritten()->getTypeLoc().getSourceRange();
4668 castType =
cast->getTypeAsWritten();
4671 llvm_unreachable(
"Unexpected ImplicitCastExpr");
4690 if (
ParenExpr *pe = dyn_cast<ParenExpr>(e)) {
4692 return new (Context)
ParenExpr(pe->getLParen(), pe->getRParen(), sub);
4693 }
else if (
UnaryOperator *uo = dyn_cast<UnaryOperator>(e)) {
4694 assert(uo->getOpcode() == UO_Extension);
4698 uo->getOperatorLoc(),
false,
4699 SemaRef.CurFPFeatureOverrides());
4701 assert(!gse->isResultDependent());
4702 assert(!gse->isTypePredicate());
4704 unsigned n = gse->getNumAssocs();
4707 subExprs.reserve(n);
4708 subTypes.reserve(n);
4710 subTypes.push_back(assoc.getTypeSourceInfo());
4711 Expr *sub = assoc.getAssociationExpr();
4712 if (assoc.isSelected())
4714 subExprs.push_back(sub);
4718 Context, gse->getGenericLoc(), gse->getControllingExpr(), subTypes,
4719 subExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
4720 gse->containsUnexpandedParameterPack(), gse->getResultIndex());
4740 return !ObjI->isArcWeakrefUnavailable();
4747 Expr *curExpr = e, *prevExpr =
nullptr;
4752 if (
auto *pe = dyn_cast<ParenExpr>(curExpr)) {
4754 curExpr = pe->getSubExpr();
4758 if (
auto *ce = dyn_cast<CastExpr>(curExpr)) {
4759 if (
auto *ice = dyn_cast<ImplicitCastExpr>(ce))
4760 if (ice->getCastKind() == CK_ARCReclaimReturnedObject) {
4762 return ice->getSubExpr();
4763 if (
auto *pe = dyn_cast<ParenExpr>(prevExpr))
4764 pe->setSubExpr(ice->getSubExpr());
4771 curExpr = ce->getSubExpr();
4790 SubExpr = SubResult.
get();
4797 bool MustConsume =
false;
4803 CK = (
T->isBlockPointerType() ? CK_AnyPointerToBlockPointerCast
4804 : CK_CPointerToObjCPointerCast);
4811 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
4814 << (
T->isBlockPointerType()? 1 : 0)
4818 Diag(BridgeKeywordLoc, diag::note_arc_bridge)
4820 Diag(BridgeKeywordLoc, diag::note_arc_bridge_transfer)
4823 br ?
"CFBridgingRelease "
4824 :
"__bridge_transfer ");
4854 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
4862 Diag(BridgeKeywordLoc, diag::note_arc_bridge)
4864 Diag(BridgeKeywordLoc, diag::note_arc_bridge_retained)
4867 br ?
"CFBridgingRetain " :
"__bridge_retained");
4874 Diag(LParenLoc, diag::err_arc_bridge_cast_incompatible)
4875 << FromType <<
T << Kind
4886 SemaRef.Cleanup.setExprNeedsCleanups(
true);
4906 TSInfo = Context.getTrivialTypeSourceInfo(
T, LParenLoc);
4933 LookForIvars =
true;
4934 else if (IsClassMethod)
4935 LookForIvars =
false;
4946 if (IsClassMethod) {
4967 Diag(Loc, diag::warn_ivar_use_hidden) << IV->getDeclName();
4975 Diag(Loc, diag::err_ivar_use_in_class_method) << IV->getDeclName();
4986 bool AllowBuiltinCreation) {
4995 if (Lookup.
empty() && II && AllowBuiltinCreation)
4996 SemaRef.LookupBuiltin(Lookup);
5007 "should not reference ivar from this context");
5010 assert(IFace &&
"should not reference ivar from this context");
5018 if (
SemaRef.DiagnoseUseOfDecl(IV, Loc))
5029 SemaRef.ActOnIdExpression(S, SelfScopeSpec, TemplateKWLoc, SelfName,
5035 SelfExpr =
SemaRef.DefaultLvalueConversion(SelfExpr.
get());
5039 SemaRef.MarkAnyDeclReferenced(Loc, IV,
true);
5051 if (!
SemaRef.isUnevaluatedContext() &&
5052 !
getDiagnostics().isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
5057 SemaRef.ImplicitlyRetainedSelfLocs.push_back({Loc, BD});
5073 (Context.hasSameType(RHSTy, Context.getObjCClassRedefinitionType()))) {
5074 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), LHSTy,
5075 CK_CPointerToObjCPointerCast);
5079 (Context.hasSameType(LHSTy, Context.getObjCClassRedefinitionType()))) {
5080 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), RHSTy,
5081 CK_CPointerToObjCPointerCast);
5086 (Context.hasSameType(RHSTy, Context.getObjCIdRedefinitionType()))) {
5087 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), LHSTy,
5088 CK_CPointerToObjCPointerCast);
5092 (Context.hasSameType(LHSTy, Context.getObjCIdRedefinitionType()))) {
5093 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), RHSTy,
5094 CK_CPointerToObjCPointerCast);
5098 if (Context.isObjCSelType(LHSTy) &&
5099 (Context.hasSameType(RHSTy, Context.getObjCSelRedefinitionType()))) {
5100 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), LHSTy, CK_BitCast);
5103 if (Context.isObjCSelType(RHSTy) &&
5104 (Context.hasSameType(LHSTy, Context.getObjCSelRedefinitionType()))) {
5105 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), RHSTy, CK_BitCast);
5111 if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {
5134 if (!(compositeType = Context.areCommonBaseCompatible(LHSOPT, RHSOPT))
5137 }
else if (Context.canAssignObjCInterfaces(LHSOPT, RHSOPT)) {
5138 compositeType = RHSOPT->isObjCBuiltinType() ? RHSTy : LHSTy;
5139 }
else if (Context.canAssignObjCInterfaces(RHSOPT, LHSOPT)) {
5142 RHSOPT->isObjCQualifiedIdType()) &&
5143 Context.ObjCQualifiedIdTypesAreCompatible(LHSOPT, RHSOPT,
5149 compositeType = Context.getObjCIdType();
5151 compositeType = Context.getObjCIdType();
5153 Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands)
5156 QualType incompatTy = Context.getObjCIdType();
5157 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), incompatTy, CK_BitCast);
5158 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), incompatTy, CK_BitCast);
5162 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), compositeType, CK_BitCast);
5163 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), compositeType, CK_BitCast);
5164 return compositeType;
5171 Diag(QuestionLoc, diag::err_cond_voidptr_arc)
5181 QualType destType = Context.getPointerType(destPointee);
5183 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), destType, CK_NoOp);
5185 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), destType, CK_BitCast);
5192 Diag(QuestionLoc, diag::err_cond_voidptr_arc)
5202 QualType destType = Context.getPointerType(destPointee);
5204 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), destType, CK_NoOp);
5206 LHS =
SemaRef.ImpCastExprToType(LHS.
get(), destType, CK_BitCast);
5227 if (OV->getSourceExpr())
5230 if (
auto *SL = dyn_cast<StringLiteral>(SrcExpr)) {
5231 if (!PT->
isObjCIdType() && !(ID && ID->getIdentifier()->isStr(
"NSString")))
5233 if (!SL->isOrdinary())
5237 Diag(SL->getBeginLoc(), diag::err_missing_atsign_prefix)
5249 if (!ID || !ID->getIdentifier()->isStr(
"NSNumber"))
5269 assert((Kind == tok::kw___objc_yes || Kind == tok::kw___objc_no) &&
5270 "Unknown Objective-C Boolean value!");
5272 QualType BoolT = Context.ObjCBuiltinBoolTy;
5273 if (!Context.getBOOLDecl()) {
5277 Result.isSingleResult()) {
5280 Context.setBOOLDecl(TD);
5283 if (Context.getBOOLDecl())
5284 BoolT = Context.getBOOLType();
5285 return new (Context)
5293 auto FindSpecVersion =
5294 [&](StringRef Platform,
5295 const llvm::Triple::OSType &OS) -> std::optional<VersionTuple> {
5301 if (Spec == AvailSpecs.end() && Platform ==
"maccatalyst") {
5308 if (Spec == AvailSpecs.end()) {
5310 const llvm::Triple &Triple = Context.getTargetInfo().getTriple();
5311 if (Triple.isOSDarwin()) {
5317 if (Spec == AvailSpecs.end())
5318 return std::nullopt;
5320 return llvm::Triple::getCanonicalVersionForOS(
5322 llvm::Triple::isValidVersionForOS(OS, Spec->
getVersion()));
5325 VersionTuple Version;
5326 if (
auto MaybeVersion =
5327 FindSpecVersion(Context.getTargetInfo().getPlatformName(),
5328 Context.getTargetInfo().getTriple().getOS()))
5329 Version = *MaybeVersion;
5334 Context->HasPotentialAvailabilityViolations =
true;
5336 return new (Context)
5344 if (
type->isObjCObjectPointerType()) {
5346 }
else if (
type->isBlockPointerType()) {
5347 SemaRef.maybeExtendBlockObject(E);
5348 return CK_BlockPointerToObjCPointerCast;
5350 assert(
type->isPointerType());
5351 return CK_CPointerToObjCPointerCast;
5360 case Stmt::ObjCStringLiteralClass:
5363 case Stmt::ObjCArrayLiteralClass:
5366 case Stmt::ObjCDictionaryLiteralClass:
5369 case Stmt::BlockExprClass:
5371 case Stmt::ObjCBoxedExprClass: {
5374 case Stmt::IntegerLiteralClass:
5375 case Stmt::FloatingLiteralClass:
5376 case Stmt::CharacterLiteralClass:
5377 case Stmt::ObjCBoolLiteralExprClass:
5378 case Stmt::CXXBoolLiteralExprClass:
5381 case Stmt::ImplicitCastExprClass: {
5384 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.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
bool QIdProtocolsAdoptObjCObjectProtocols(QualType QT, ObjCInterfaceDecl *IDecl)
QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in QT's qualified-id protocol list adopt...
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl)
ObjCObjectAdoptsQTypeProtocols - Checks that protocols in IC's protocol list adopt all protocols in Q...
Represents an array type, per C99 6.7.5.2 - Array Declarators.
ArraySizeModifier getSizeModifier() const
QualType getElementType() const
unsigned getIndexTypeCVRQualifiers() const
One specifier in an @available expression.
StringRef getPlatform() const
VersionTuple getVersion() const
Represents a block literal declaration, which is like an unnamed FunctionDecl.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Abstract class common to all of the C++ "named"/"keyword" casts.
Represents a C++ nested-name-specifier or a global scope specifier.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Represents the canonical version of C arrays with a specified constant size.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Simple template class for restricting typo correction candidates to ones having a single Decl* of the...
A reference to a declared variable, function, enum, etc.
Decl - This represents one declaration (or definition), e.g.
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
bool isInvalidDecl() const
SourceLocation getLocation() const
bool isDefinedOutsideFunctionOrMethod() const
isDefinedOutsideFunctionOrMethod - This predicate returns true if this scoped decl is defined outside...
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
TranslationUnitDecl * getTranslationUnitDecl()
The name of a declaration.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
bool isIdentifier() const
Predicate functions for querying what type of name this is.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
ExplicitCastExpr - An explicit cast written in the source code.
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
Expr * IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY
Skip past any parentheses and casts which do not change the value (including ptr->int casts of the sa...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Skip past any parentheses and lvalue casts which might surround this expression until reaching a fixe...
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool isObjCSelfExpr() const
Check if this expression is the ObjC 'self' implicit parameter.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
@ NPC_ValueDependentIsNull
Specifies that a value-dependent expression of integral or dependent type should be considered a null...
@ NPC_NeverValueDependent
Specifies that the expression should never be value-dependent.
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
static ExprValueKind getValueKindForType(QualType T)
getValueKindForType - Given a formal return or parameter type, give its value kind.
Represents difference between two FPOptions values.
static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc, CharSourceRange FromRange, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code from FromRange at a specific location.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
QualType getReturnType() const
Represents a C11 generic selection.
AssociationTy< false > Association
static GenericSelectionExpr * Create(const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr, ArrayRef< TypeSourceInfo * > AssocTypes, ArrayRef< Expr * > AssocExprs, SourceLocation DefaultLoc, SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack, unsigned ResultIndex)
Create a non-result-dependent generic selection expression accepting an expression predicate.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
Describes the sequence of initializations required to initialize a given object or reference with a s...
Describes an entity that is being initialized.
static InitializedEntity InitializeTemporary(QualType Type)
Create the initialization entity for a temporary.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
static bool isAsciiIdentifierContinueChar(char c, const LangOptions &LangOpts)
Returns true if the given character could appear in an identifier.
Represents the results of name lookup.
bool empty() const
Return true if no decls were found.
SourceLocation getNameLoc() const
Gets the location of the identifier.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
@ NSDict_dictionaryWithObjectsForKeysCount
@ NSArr_arrayWithObjectsCount
This represents a decl that may have a name.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
static ObjCArrayLiteral * Create(const ASTContext &C, ArrayRef< Expr * > Elements, QualType T, ObjCMethodDecl *Method, bool ExpressibleAsConstantInitializer, SourceRange SR)
A runtime availability query.
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
An Objective-C "bridged" cast expression, which casts between Objective-C pointers and C pointers,...
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCContainerDecl - Represents a container for method declarations.
ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const
ObjCPropertyDecl * FindPropertyDeclaration(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyDeclaration - Finds declaration of the property given its name in 'PropertyId' and return...
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
static ObjCDictionaryLiteral * Create(const ASTContext &C, ArrayRef< ObjCDictionaryElement > VK, bool HasPackExpansions, QualType T, ObjCMethodDecl *Method, bool ExpressibleAsConstantInitializer, SourceRange SR)
ObjCEncodeExpr, used for @encode in Objective-C.
Represents an ObjC class declaration.
ObjCMethodDecl * lookupClassMethod(Selector Sel) const
Lookup a class method for a given selector.
static ObjCInterfaceDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation atLoc, const IdentifierInfo *Id, ObjCTypeParamList *typeParamList, ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc=SourceLocation(), bool isInternal=false)
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const
Lookup an instance method for a given selector.
ObjCMethodDecl * lookupPrivateClassMethod(const Selector &Sel)
ObjCMethodDecl * getCategoryClassMethod(Selector Sel) const
ObjCMethodDecl * lookupPrivateMethod(const Selector &Sel, bool Instance=true) const
Lookup a method in the classes implementation hierarchy.
ObjCMethodDecl * lookupMethod(Selector Sel, bool isInstance, bool shallowCategoryLookup=false, bool followSuper=true, const ObjCCategoryDecl *C=nullptr) const
lookupMethod - This method returns an instance/class method by looking in the class,...
ObjCInterfaceDecl * getSuperClass() const
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCIvarDecl - Represents an ObjC instance variable.
AccessControl getAccessControl() const
QualType getUsageType(QualType objectType) const
Retrieve the type of this instance variable when viewed as a member of a specific object type.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
An expression that sends a message to the given Objective-C object or class.
static ObjCMessageExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, SourceLocation LBracLoc, SourceLocation SuperLoc, bool IsInstanceSuper, QualType SuperType, Selector Sel, ArrayRef< SourceLocation > SelLocs, ObjCMethodDecl *Method, ArrayRef< Expr * > Args, SourceLocation RBracLoc, bool isImplicit)
Create a message send to super.
Selector getSelector() const
const ObjCMethodDecl * getMethodDecl() const
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
ArrayRef< ParmVarDecl * > parameters() const
bool isPropertyAccessor() const
void getOverriddenMethods(SmallVectorImpl< const ObjCMethodDecl * > &Overridden) const
Return overridden methods for the given Method.
static ObjCMethodDecl * Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl, bool isInstance=true, bool isVariadic=false, bool isPropertyAccessor=false, bool isSynthesizedAccessorStub=false, bool isImplicitlyDeclared=false, bool isDefined=false, ObjCImplementationControl impControl=ObjCImplementationControl::None, bool HasRelatedResultType=false)
const ObjCPropertyDecl * findPropertyDecl(bool CheckOverrides=true) const
Returns the property associated with this method's selector.
void setMethodParams(ASTContext &C, ArrayRef< ParmVarDecl * > Params, ArrayRef< SourceLocation > SelLocs={})
Sets the method's parameters and selector source locations.
bool hasRelatedResultType() const
Determine whether this method has a result type that is related to the message receiver's type.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
bool isInstanceMethod() const
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
QualType getReturnType() const
bool isClassMethod() const
ObjCInterfaceDecl * getClassInterface()
bool isGlobalAllocation() const
Represents a pointer to an Objective C object.
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
bool isObjCIdType() const
True if this is equivalent to the 'id' type, i.e.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
ObjCInterfaceDecl * getInterfaceDecl() const
If this pointer points to an Objective @interface type, gets the declaration for that interface.
const ObjCInterfaceType * getInterfaceType() const
If this pointer points to an Objective C @interface type, gets the type for that interface.
Represents one property declaration in an Objective-C interface.
ObjCMethodDecl * getGetterMethodDecl() const
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
ObjCPropertyDecl * getExplicitProperty() const
ObjCMethodDecl * getImplicitPropertyGetter() const
bool isExplicitProperty() const
Represents an Objective-C protocol declaration.
bool hasDefinition() const
Determine whether this protocol has a definition.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
bool isNonRuntimeProtocol() const
This is true iff the protocol is tagged with the objc_non_runtime_protocol attribute.
ObjCProtocolExpr used for protocol expression in Objective-C.
bool hasConstantEmptyCollections() const
bool hasConstantCFBooleans() const
ObjCSelectorExpr used for @selector in Objective-C.
ObjCStringLiteral, used for Objective-C string literals i.e.
ObjCSubscriptRefExpr - used for array and dictionary subscripting.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
ParenExpr - This represents a parenthesized expression, e.g.
Sugar for parentheses used when specifying types.
Represents a parameter to a function.
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
A (possibly-)qualified type.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
QualType withConst() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
QualType substObjCTypeArgs(ASTContext &ctx, ArrayRef< QualType > typeArgs, ObjCSubstitutionContext context) const
Substitute type arguments for the Objective-C type parameters used in the subject type.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Base for LValueReferenceType and RValueReferenceType.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isInObjcMethodScope() const
isInObjcMethodScope - Return true if this scope is, or is contained in, an Objective-C method body.
static Selector constructSetterSelector(IdentifierTable &Idents, SelectorTable &SelTable, const IdentifierInfo *Name)
Return the default setter selector for the given identifier.
Smart pointer class that efficiently represents Objective-C method names.
std::string getAsString() const
Derive the full selector name (e.g.
ObjCMethodFamily getMethodFamily() const
Derive the conventional family of this method.
bool isUnarySelector() const
ObjCStringFormatFamily getStringFormatFamily() const
unsigned getNumArgs() const
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
DiagnosticsEngine & getDiagnostics() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
ObjCMessageKind getObjCMessageKind(Scope *S, IdentifierInfo *Name, SourceLocation NameLoc, bool IsSuper, bool HasTrailingDot, ParsedType &ReceiverType)
ObjCMethodDecl * ValueWithBytesObjCTypeMethod
The declaration of the valueWithBytes:objCType: method.
ExprResult BuildObjCDictionaryLiteral(SourceRange SR, MutableArrayRef< ObjCDictionaryElement > Elements)
ExprResult HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, Expr *BaseExpr, SourceLocation OpLoc, DeclarationName MemberName, SourceLocation MemberLoc, SourceLocation SuperLoc, QualType SuperType, bool Super)
HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an objective C interface.
ExprResult BuildInstanceMessage(Expr *Receiver, QualType ReceiverType, SourceLocation SuperLoc, Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args, bool isImplicit=false)
Build an Objective-C instance message expression.
const ObjCMethodDecl * SelectorsForTypoCorrection(Selector Sel, QualType ObjectType=QualType())
ExprResult BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, QualType ReceiverType, SourceLocation SuperLoc, Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args, bool isImplicit=false)
Build an Objective-C class message expression.
ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number)
BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the numeric literal expression.
bool AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod, SourceRange R, bool receiverIdOrClass, SmallVectorImpl< ObjCMethodDecl * > &Methods)
ObjCMethodDecl * LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass=false)
LookupInstanceMethodInGlobalPool - Returns the method and warns if there are multiple signatures.
ExprResult ActOnObjCBridgedCast(Scope *S, SourceLocation LParenLoc, ObjCBridgeCastKind Kind, SourceLocation BridgeKeywordLoc, ParsedType Type, SourceLocation RParenLoc, Expr *SubExpr)
ObjCLiteralKind CheckLiteralKind(Expr *FromE)
ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc, TypeSourceInfo *EncodedTypeInfo, SourceLocation RParenLoc)
bool CheckObjCBridgeRelatedConversions(SourceLocation Loc, QualType DestType, QualType SrcType, Expr *&SrcExpr, bool Diagnose=true)
ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements)
ObjCInterfaceDecl * NSArrayDecl
The declaration of the Objective-C NSArray class.
ExprResult ActOnClassPropertyRefExpr(const IdentifierInfo &receiverName, const IdentifierInfo &propertyName, SourceLocation receiverNameLoc, SourceLocation propertyNameLoc)
void CheckObjCCircularContainer(ObjCMessageExpr *Message)
Check whether receiver is mutable ObjC container which attempts to add itself into the container.
ObjCInterfaceDecl * getObjCInterfaceDecl(const IdentifierInfo *&Id, SourceLocation IdLoc, bool TypoCorrection=false)
Look for an Objective-C class in the translation unit.
ObjCMethodDecl * LookupMethodInObjectType(Selector Sel, QualType Ty, bool IsInstance)
LookupMethodInType - Look up a method in an ObjCObjectType.
bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, ObjCMethodDecl *Method, ObjCIvarDecl *IV)
IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is an ivar synthesized for 'Meth...
ExprResult BuildClassMessageImplicit(QualType ReceiverType, bool isSuperReceiver, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)
ObjCInterfaceDecl * NSNumberDecl
The declaration of the Objective-C NSNumber class.
void CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr)
ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr)
BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the '@' prefixed parenthesized expression.
ObjCInterfaceDecl * NSValueDecl
The declaration of the Objective-C NSValue class.
Selector RespondsToSelectorSel
will hold 'respondsToSelector:'
bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method, const ObjCMethodDecl *PrevMethod, MethodMatchStrategy strategy=MMS_strict)
MatchTwoMethodDeclarations - Checks if two methods' type match and returns true, or false,...
bool CheckMessageArgumentTypes(const Expr *Receiver, QualType ReceiverType, MultiExprArg Args, Selector Sel, ArrayRef< SourceLocation > SelectorLocs, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage, SourceLocation lbrac, SourceLocation rbrac, SourceRange RecRange, QualType &ReturnType, ExprValueKind &VK)
CheckMessageArgumentTypes - Check types in an Obj-C message send.
ObjCInterfaceDecl * NSStringDecl
The declaration of the Objective-C NSString class.
llvm::MapVector< Selector, SourceLocation > ReferencedSelectors
Method selectors used in a @selector expression.
ObjCMethodDecl * LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass=false)
LookupFactoryMethodInGlobalPool - Returns the method and warns if there are multiple signatures.
ObjCMethodDecl * StringWithUTF8StringMethod
The declaration of the stringWithUTF8String: method.
bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall)
Check whether the given method, which must be in the 'init' family, is a valid member of that family.
QualType FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, SourceLocation QuestionLoc)
FindCompositeObjCPointerType - Helper method to find composite type of two objective-c pointer types ...
ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S)
ObjCInterfaceDecl * NSDictionaryDecl
The declaration of the Objective-C NSDictionary class.
ObjCMethodDecl * ArrayWithObjectsMethod
The declaration of the arrayWithObjects:count: method.
ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc, SourceLocation EncodeLoc, SourceLocation LParenLoc, ParsedType Ty, SourceLocation RParenLoc)
QualType QIDNSCopying
id<NSCopying> type.
bool CheckObjCString(Expr *Arg)
CheckObjCString - Checks that the argument to the builtin CFString constructor is correct Note: It mi...
ExprResult ActOnClassMessage(Scope *S, ParsedType Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr)
bool CheckConversionToObjCLiteral(QualType DstType, Expr *&SrcExpr, bool Diagnose=true)
ObjCMethodDecl * tryCaptureObjCSelf(SourceLocation Loc)
Try to capture an implicit reference to 'self'.
ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs, ArrayRef< Expr * > Strings)
ObjCMethodDecl * DictionaryWithObjectsMethod
The declaration of the dictionaryWithObjects:forKeys:count: method.
QualType NSStringPointer
Pointer to NSString type (NSString *).
ExprResult BuildObjCBridgedCast(SourceLocation LParenLoc, ObjCBridgeCastKind Kind, SourceLocation BridgeKeywordLoc, TypeSourceInfo *TSInfo, Expr *SubExpr)
ObjCProtocolDecl * LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Find the protocol with the given name, if any.
QualType NSNumberPointer
Pointer to NSNumber type (NSNumber *).
DeclResult LookupIvarInObjCMethod(LookupResult &Lookup, Scope *S, IdentifierInfo *II)
The parser has read a name in, and Sema has detected that we're currently inside an ObjC method.
ObjCMethodDecl * NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods]
The Objective-C NSNumber methods used to create NSNumber literals.
GlobalMethodPool MethodPool
Method Pool - allows efficient lookup when typechecking messages to "id".
QualType getMessageSendResultType(const Expr *Receiver, QualType ReceiverType, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage)
Determine the result of a message send expression based on the type of the receiver,...
ExprResult ParseObjCProtocolExpression(IdentifierInfo *ProtocolName, SourceLocation AtLoc, SourceLocation ProtoLoc, SourceLocation LParenLoc, SourceLocation ProtoIdLoc, SourceLocation RParenLoc)
ParseObjCProtocolExpression - Build protocol expression for @protocol.
ExprResult BuildInstanceMessageImplicit(Expr *Receiver, QualType ReceiverType, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)
void checkRetainCycles(ObjCMessageExpr *msg)
checkRetainCycles - Check whether an Objective-C message send might create an obvious retain cycle.
ObjCMessageKind
Describes the kind of message expression indicated by a message send that starts with an identifier.
@ ObjCClassMessage
The message is a class message, and the identifier is a type name.
@ ObjCInstanceMessage
The message is an instance message.
@ ObjCSuperMessage
The message is sent to 'super'.
ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S, IdentifierInfo *II, bool AllowBuiltinCreation=false)
The parser has read a name in, and Sema has detected that we're currently inside an ObjC method.
QualType NSValuePointer
Pointer to NSValue type (NSValue *).
void EmitRelatedResultTypeNote(const Expr *E)
If the given expression involves a message send to a method with a related result type,...
ExprResult ActOnInstanceMessage(Scope *S, Expr *Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx)
ExprResult BuildIvarRefExpr(Scope *S, SourceLocation Loc, ObjCIvarDecl *IV)
ExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
CastKind PrepareCastToObjCObjectPointer(ExprResult &E)
Prepare a conversion of the given expression to an ObjC object pointer type.
bool CollectMultipleMethodsInGlobalPool(Selector Sel, SmallVectorImpl< ObjCMethodDecl * > &Methods, bool InstanceFirst, bool CheckTheOther, const ObjCObjectType *TypeBound=nullptr)
We first select the type of the method: Instance or Factory, then collect all methods with that type.
bool checkObjCBridgeRelatedComponents(SourceLocation Loc, QualType DestType, QualType SrcType, ObjCInterfaceDecl *&RelatedClass, ObjCMethodDecl *&ClassMethod, ObjCMethodDecl *&InstanceMethod, TypedefNameDecl *&TDNDecl, bool CfToNs, bool Diagnose=true)
void EmitRelatedResultTypeNoteForReturn(QualType destType)
Given that we had incompatible pointer types in a return statement, check whether we're in a method w...
void diagnoseARCUnbridgedCast(Expr *e)
Given that we saw an expression with the ARCUnbridgedCastTy placeholder type, complain bitterly.
ObjCMethodDecl * LookupMethodInQualifiedType(Selector Sel, const ObjCObjectPointerType *OPT, bool IsInstance)
LookupMethodInQualifiedType - Lookups up a method in protocol qualifier list of a qualified objective...
ARCConversionResult CheckObjCConversion(SourceRange castRange, QualType castType, Expr *&op, CheckedConversionKind CCK, bool Diagnose=true, bool DiagnoseCFAudited=false, BinaryOperatorKind Opc=BO_PtrMemD, bool IsReinterpretCast=false)
Checks for invalid conversions and casts between retainable pointers and other pointer kinds for ARC ...
bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, CastKind &Kind)
bool CheckObjCARCUnavailableWeakConversion(QualType castType, QualType ExprType)
ExprResult ParseObjCSelectorExpression(Selector Sel, SourceLocation AtLoc, SourceLocation SelKWLoc, SourceLocation SelNameLoc, SourceLocation LParenLoc, SourceLocation RParenLoc, bool WarnMultipleSelectors)
ParseObjCSelectorExpression - Build selector expression for @selector.
bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, ArrayRef< const Expr * > Args)
Expr * stripARCUnbridgedCast(Expr *e)
stripARCUnbridgedCast - Given an expression of ARCUnbridgedCast type, remove the placeholder cast.
ExprResult BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr, Expr *IndexExpr, ObjCMethodDecl *getterMethod, ObjCMethodDecl *setterMethod)
Build an ObjC subscript pseudo-object expression, given that that's supported by the runtime.
bool isSelfExpr(Expr *RExpr)
Private Helper predicate to check for 'self'.
ExprResult ActOnObjCAvailabilityCheckExpr(llvm::ArrayRef< AvailabilitySpec > AvailSpecs, SourceLocation AtLoc, SourceLocation RParen)
bool isKnownName(StringRef name)
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
ExprResult ActOnObjCBoolLiteral(SourceLocation AtLoc, SourceLocation ValueLoc, bool Value)
Sema - This implements semantic analysis and AST building for C.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
bool FormatStringHasSArg(const StringLiteral *FExpr)
NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Look up a name, looking for a single declaration.
ASTContext & getASTContext() const
ObjCMethodDecl * getCurMethodDecl()
getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
const LangOptions & getLangOpts() const
const LangOptions & LangOpts
ExprResult DefaultLvalueConversion(Expr *E)
static bool isCast(CheckedConversionKind CCK)
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
SourceManager & getSourceManager() const
bool makeUnavailableInSystemHeader(SourceLocation loc, UnavailableAttr::ImplicitReason reason)
makeUnavailableInSystemHeader - There is an error in the current context.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
SourceManager & SourceMgr
DiagnosticsEngine & Diags
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
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.
const FunctionProtoType * T
ObjCBridgeCastKind
The kind of bridging performed by the Objective-C bridge cast.
@ OBC_Bridge
Bridging via __bridge, which does nothing but reinterpret the bits.
@ OBC_BridgeTransfer
Bridging via __bridge_transfer, which transfers ownership of an Objective-C pointer into ARC.
@ OBC_BridgeRetained
Bridging via __bridge_retain, which makes an ARC object available as a +1 C pointer.
CastKind
CastKind - The kind of operation required for a conversion.
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
U cast(CodeGen::Address addr)
@ 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