24#include "llvm/Support/ConvertUTF.h"
29 :
SemaBase(S), NSNumberDecl(nullptr), NSValueDecl(nullptr),
30 NSStringDecl(nullptr), StringWithUTF8StringMethod(nullptr),
31 ValueWithBytesObjCTypeMethod(nullptr), NSArrayDecl(nullptr),
32 ArrayWithObjectsMethod(nullptr), NSDictionaryDecl(nullptr),
33 DictionaryWithObjectsMethod(nullptr) {}
47 if (!DS->isSingleDecl())
49 diag::err_toomany_element_decls));
51 VarDecl *
D = dyn_cast<VarDecl>(DS->getSingleDecl());
52 if (!
D ||
D->isInvalidDecl())
55 FirstType =
D->getType();
59 if (!
D->hasLocalStorage())
61 Diag(
D->getLocation(), diag::err_non_local_variable_decl_in_for));
67 Expr *DeducedInit = &OpaqueId;
71 D->getTypeSourceInfo()->getTypeLoc(), DeducedInit, FirstType, Info);
80 D->setType(FirstType);
84 D->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
85 Diag(
Loc, diag::warn_auto_var_is_id) <<
D->getDeclName();
93 Diag(
First->getBeginLoc(), diag::err_selector_element_not_lvalue)
94 <<
First->getSourceRange());
96 FirstType =
static_cast<Expr *
>(
First)->getType();
98 Diag(ForLoc, diag::err_selector_element_const_type)
99 << FirstType <<
First->getSourceRange();
104 return StmtError(
Diag(ForLoc, diag::err_selector_element_type)
105 << FirstType <<
First->getSourceRange());
117 nullptr, ForLoc, RParenLoc);
129 collection = result.
get();
139 collection = result.
get();
146 return Diag(forLoc, diag::err_collection_expr_type)
159 diag::err_arc_collection_forward,
164 }
else if (iface || !objectType->
qual_empty()) {
166 &Context.Idents.get(
"countByEnumeratingWithState"),
167 &Context.Idents.get(
"objects"), &Context.Idents.get(
"count")};
168 Selector selector = Context.Selectors.getSelector(3, &selectorIdents[0]);
186 Diag(forLoc, diag::warn_collection_expr_type)
210 VarDecl *Var = cast_or_null<VarDecl>(Parm);
227 Diag(AtLoc, diag::err_objc_exceptions_disabled) <<
"@try";
232 Diag(AtLoc, diag::err_mixing_cxx_try_seh_try) << 1;
237 unsigned NumCatchStmts = CatchStmts.size();
239 NumCatchStmts, Finally);
261 return StmtError(
Diag(AtLoc, diag::err_objc_throw_expects_object)
272 Diag(AtLoc, diag::err_objc_exceptions_disabled) <<
"@throw";
277 Scope *AtCatchParent = CurScope;
279 AtCatchParent = AtCatchParent->
getParent();
281 return StmtError(
Diag(AtLoc, diag::err_rethrow_used_outside_catch));
291 operand = result.
get();
295 if (!
type->isDependentType() && !
type->isObjCObjectPointerType()) {
300 diag::err_incomplete_receiver_type))
301 return Diag(atLoc, diag::err_objc_synchronized_expects_object)
309 return Diag(atLoc, diag::err_objc_synchronized_expects_object)
312 operand = result.
get();
314 return Diag(atLoc, diag::err_objc_synchronized_expects_object)
346 Context.ObjCBuiltinIdTy, {},
368 ObjCObjectTL.setProtocolLAngleLoc(lAngleLoc);
369 ObjCObjectTL.setProtocolRAngleLoc(rAngleLoc);
370 for (
unsigned i = 0, n = protocols.size(); i != n; ++i)
371 ObjCObjectTL.setProtocolLoc(i, protocolLocs[i]);
391 BaseTypeInfo = Context.getTrivialTypeSourceInfo(
T,
Loc);
395 for (
unsigned i = 0, n = TypeArgs.size(); i != n; ++i) {
399 ActualTypeArgInfos.clear();
403 assert(TypeArgInfo &&
"No type source info?");
404 ActualTypeArgInfos.push_back(TypeArgInfo);
410 TypeArgsLAngleLoc, ActualTypeArgInfos, TypeArgsRAngleLoc,
414 ProtocolLocs, ProtocolRAngleLoc,
430 ResultTL = ObjCObjectPointerTL.getPointeeLoc();
435 if (OTPTL.getNumProtocols() > 0) {
436 assert(OTPTL.getNumProtocols() == Protocols.size());
437 OTPTL.setProtocolLAngleLoc(ProtocolLAngleLoc);
438 OTPTL.setProtocolRAngleLoc(ProtocolRAngleLoc);
439 for (
unsigned i = 0, n = Protocols.size(); i != n; ++i)
440 OTPTL.setProtocolLoc(i, ProtocolLocs[i]);
450 if (ObjCObjectTL.getNumTypeArgs() > 0) {
451 assert(ObjCObjectTL.getNumTypeArgs() == ActualTypeArgInfos.size());
452 ObjCObjectTL.setTypeArgsLAngleLoc(TypeArgsLAngleLoc);
453 ObjCObjectTL.setTypeArgsRAngleLoc(TypeArgsRAngleLoc);
454 for (
unsigned i = 0, n = ActualTypeArgInfos.size(); i != n; ++i)
455 ObjCObjectTL.setTypeArgTInfo(i, ActualTypeArgInfos[i]);
462 if (ObjCObjectTL.getNumProtocols() > 0) {
463 assert(ObjCObjectTL.getNumProtocols() == Protocols.size());
464 ObjCObjectTL.setProtocolLAngleLoc(ProtocolLAngleLoc);
465 ObjCObjectTL.setProtocolRAngleLoc(ProtocolRAngleLoc);
466 for (
unsigned i = 0, n = Protocols.size(); i != n; ++i)
467 ObjCObjectTL.setProtocolLoc(i, ProtocolLocs[i]);
474 ObjCObjectTL.setHasBaseTypeAsWritten(
true);
475 if (ObjCObjectTL.getType() ==
T)
476 ObjCObjectTL.getBaseLoc().initializeFullCopy(BaseTypeInfo->
getTypeLoc());
478 ObjCObjectTL.getBaseLoc().initialize(Context,
Loc);
491 if (!Protocols.empty()) {
493 Result = Context.applyObjCProtocolQualifiers(
Result, Protocols, HasError);
496 <<
SourceRange(ProtocolLAngleLoc, ProtocolRAngleLoc);
500 if (FailOnError &&
Result.isNull())
514 if (!objcObjectType || !objcObjectType->getInterface()) {
515 S.
Diag(loc, diag::err_objc_type_args_non_class) <<
type << typeArgsRange;
526 S.
Diag(loc, diag::err_objc_type_args_non_parameterized_class)
536 if (objcObjectType->isSpecialized()) {
537 S.
Diag(loc, diag::err_objc_type_args_specialized_class)
548 unsigned numTypeParams = typeParams->
size();
549 bool anyPackExpansions =
false;
550 for (
unsigned i = 0, n = typeArgs.size(); i != n; ++i) {
558 bool diagnosed =
false;
561 rangeToRemove =
attr.getLocalSourceRange();
562 if (
attr.getTypePtr()->getImmediateNullability()) {
563 typeArg =
attr.getTypePtr()->getModifiedType();
565 diag::err_objc_type_arg_explicit_nullability)
573 if (!rebuilding && !diagnosed) {
574 S.
Diag(qual.getBeginLoc(), diag::err_objc_type_arg_qualified)
583 finalTypeArgs.push_back(typeArg);
586 anyPackExpansions =
true;
590 if (!anyPackExpansions) {
591 if (i < numTypeParams) {
592 typeParam = typeParams->
begin()[i];
595 S.
Diag(loc, diag::err_objc_type_args_wrong_arity)
598 S.
Diag(objcClass->
getLocation(), diag::note_previous_decl) << objcClass;
613 assert(anyPackExpansions &&
"Too many arguments?");
622 if (typeArgObjC->isObjCIdType()) {
625 if (boundObjC->isObjCIdType())
634 diag::err_objc_type_arg_does_not_match_bound)
651 assert(anyPackExpansions &&
"Too many arguments?");
662 diag::err_objc_type_arg_does_not_match_bound)
685 diag::err_objc_type_arg_not_id_compatible)
695 if (!anyPackExpansions && finalTypeArgs.size() != numTypeParams) {
696 S.
Diag(loc, diag::err_objc_type_args_wrong_arity)
699 S.
Diag(objcClass->
getLocation(), diag::note_previous_decl) << objcClass;
716 bool FailOnError,
bool Rebuilding) {
719 if (!TypeArgs.empty()) {
723 FailOnError, Rebuilding);
724 if (FailOnError &&
Result.isNull())
728 if (!Protocols.empty()) {
730 Result = Context.applyObjCProtocolQualifiers(
Result, Protocols, HasError);
732 Diag(
Loc, diag::err_invalid_protocol_qualifiers)
733 <<
SourceRange(ProtocolLAngleLoc, ProtocolRAngleLoc);
737 if (FailOnError &&
Result.isNull())
746 QualType T = Context.getObjCInstanceType();
755struct RetainCycleOwner {
756 VarDecl *Variable =
nullptr;
761 RetainCycleOwner() =
default;
763 void setLocsFrom(Expr *e) {
764 Loc = e->getExprLoc();
765 Range = e->getSourceRange();
780 owner.Variable = var;
782 owner.setLocsFrom(ref);
790 switch (
cast->getCastKind()) {
792 case CK_LValueBitCast:
793 case CK_LValueToRValue:
794 case CK_ARCReclaimReturnedObject:
795 e =
cast->getSubExpr();
812 if (ref->isFreeIvar())
813 owner.setLocsFrom(ref);
814 owner.Indirect =
true;
819 VarDecl *var = dyn_cast<VarDecl>(ref->getDecl());
825 if (
MemberExpr *member = dyn_cast<MemberExpr>(e)) {
826 if (member->isArrow())
830 e = member->getBase();
837 pseudo->getSyntacticForm()->IgnoreParens());
843 if (!property->isRetaining() &&
844 !(property->getPropertyIvarDecl() &&
845 property->getPropertyIvarDecl()->getType().getObjCLifetime() ==
849 owner.Indirect =
true;
858 e =
const_cast<Expr *
>(
859 cast<OpaqueValueExpr>(pre->
getBase())->getSourceExpr());
871struct FindCaptureVisitor : EvaluatedExprVisitor<FindCaptureVisitor> {
876 FindCaptureVisitor(ASTContext &Context, VarDecl *variable)
877 : EvaluatedExprVisitor<FindCaptureVisitor>(Context), Variable(variable) {}
879 void VisitDeclRefExpr(DeclRefExpr *ref) {
880 if (ref->getDecl() == Variable && !Capturer)
884 void VisitObjCIvarRefExpr(ObjCIvarRefExpr *ref) {
887 Visit(ref->getBase());
888 if (Capturer && ref->isFreeIvar())
892 void VisitBlockExpr(BlockExpr *block) {
894 if (block->getBlockDecl()->capturesVariable(Variable))
895 Visit(block->getBlockDecl()->getBody());
898 void VisitOpaqueValueExpr(OpaqueValueExpr *OVE) {
901 if (OVE->getSourceExpr())
902 Visit(OVE->getSourceExpr());
905 void VisitBinaryOperator(BinaryOperator *BinOp) {
906 if (!Variable || VarWillBeReased || BinOp->getOpcode() != BO_Assign)
908 Expr *LHS = BinOp->getLHS();
909 if (
const DeclRefExpr *DRE = dyn_cast_or_null<DeclRefExpr>(LHS)) {
910 if (DRE->getDecl() != Variable)
912 if (Expr *RHS = BinOp->getRHS()) {
913 RHS = RHS->IgnoreParenCasts();
914 std::optional<llvm::APSInt>
Value;
916 (RHS && (
Value = RHS->getIntegerConstantExpr(Context)) &&
928 assert(owner.Variable && owner.Loc.isValid());
935 if (
Cmd.isUnarySelector() &&
Cmd.getNameForSlot(0) ==
"copy") {
936 e = ME->getInstanceReceiver();
941 }
else if (
CallExpr *CE = dyn_cast<CallExpr>(e)) {
942 if (CE->getNumArgs() == 1) {
943 FunctionDecl *Fn = dyn_cast_or_null<FunctionDecl>(CE->getCalleeDecl());
946 if (FnI && FnI->
isStr(
"_Block_copy")) {
953 BlockExpr *block = dyn_cast<BlockExpr>(e);
957 FindCaptureVisitor visitor(S.
Context, owner.Variable);
959 return visitor.VarWillBeReased ? nullptr : visitor.Capturer;
963 RetainCycleOwner &owner) {
965 assert(owner.Variable && owner.Loc.isValid());
969 S.
Diag(owner.Loc, diag::note_arc_retain_cycle_owner)
970 << owner.Indirect << owner.Range;
980 str = str.ltrim(
'_');
981 if (str.starts_with(
"set"))
983 else if (str.starts_with(
"add")) {
985 if (sel.
getNumArgs() == 1 && str.starts_with(
"addOperationWithBlock"))
996static std::optional<int>
998 bool IsMutableArray = S.NSAPIObj->isSubclassOfNSClass(
1000 if (!IsMutableArray) {
1001 return std::nullopt;
1004 Selector Sel = Message->getSelector();
1006 std::optional<NSAPI::NSArrayMethodKind> MKOpt =
1007 S.NSAPIObj->getNSArrayMethodKind(Sel);
1009 return std::nullopt;
1023 return std::nullopt;
1026 return std::nullopt;
1029static std::optional<int>
1031 bool IsMutableDictionary = S.NSAPIObj->isSubclassOfNSClass(
1033 if (!IsMutableDictionary) {
1034 return std::nullopt;
1037 Selector Sel = Message->getSelector();
1039 std::optional<NSAPI::NSDictionaryMethodKind> MKOpt =
1040 S.NSAPIObj->getNSDictionaryMethodKind(Sel);
1042 return std::nullopt;
1054 return std::nullopt;
1057 return std::nullopt;
1062 bool IsMutableSet = S.NSAPIObj->isSubclassOfNSClass(
1065 bool IsMutableOrderedSet = S.NSAPIObj->isSubclassOfNSClass(
1067 if (!IsMutableSet && !IsMutableOrderedSet) {
1068 return std::nullopt;
1071 Selector Sel = Message->getSelector();
1073 std::optional<NSAPI::NSSetMethodKind> MKOpt =
1074 S.NSAPIObj->getNSSetMethodKind(Sel);
1076 return std::nullopt;
1091 return std::nullopt;
1095 if (!Message->isInstanceMessage()) {
1099 std::optional<int> ArgOpt;
1107 int ArgIndex = *ArgOpt;
1109 Expr *Arg = Message->getArg(ArgIndex)->IgnoreImpCasts();
1115 if (
DeclRefExpr *ArgRE = dyn_cast<DeclRefExpr>(Arg)) {
1116 if (ArgRE->isObjCSelfExpr()) {
1117 Diag(Message->getSourceRange().getBegin(),
1118 diag::warn_objc_circular_container)
1119 << ArgRE->getDecl() << StringRef(
"'super'");
1123 Expr *Receiver = Message->getInstanceReceiver()->IgnoreImpCasts();
1129 if (
DeclRefExpr *ReceiverRE = dyn_cast<DeclRefExpr>(Receiver)) {
1130 if (
DeclRefExpr *ArgRE = dyn_cast<DeclRefExpr>(Arg)) {
1131 if (ReceiverRE->getDecl() == ArgRE->getDecl()) {
1133 Diag(Message->getSourceRange().getBegin(),
1134 diag::warn_objc_circular_container)
1136 if (!ArgRE->isObjCSelfExpr()) {
1138 diag::note_objc_circular_container_declared_here)
1143 }
else if (
ObjCIvarRefExpr *IvarRE = dyn_cast<ObjCIvarRefExpr>(Receiver)) {
1145 if (IvarRE->getDecl() == IvarArgRE->getDecl()) {
1147 Diag(Message->getSourceRange().getBegin(),
1148 diag::warn_objc_circular_container)
1151 diag::note_objc_circular_container_declared_here)
1166 RetainCycleOwner owner;
1179 for (
unsigned i = 0, e = msg->
getNumArgs(); i != e; ++i) {
1182 if (MD && MD->
parameters()[i]->hasAttr<NoEscapeAttr>())
1191 RetainCycleOwner owner;
1200 RetainCycleOwner Owner;
1221 if (!Literal || !Literal->isOrdinary()) {
1222 Diag(Arg->
getBeginLoc(), diag::err_cfstring_literal_not_string_constant)
1227 if (Literal->containsNonAsciiOrNull()) {
1228 StringRef String = Literal->getString();
1229 unsigned NumBytes = String.size();
1231 const llvm::UTF8 *FromPtr = (
const llvm::UTF8 *)String.data();
1232 llvm::UTF16 *ToPtr = &ToBuf[0];
1234 llvm::ConversionResult
Result =
1235 llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumBytes, &ToPtr,
1236 ToPtr + NumBytes, llvm::strictConversion);
1238 if (
Result != llvm::conversionOK)
1263 DC = CatD->getClassInterface();
1272 return Ident_NSError;
1278 "The next DeclContext should be lexically contained in the current one.");
1305 return cast_or_null<ObjCProtocolDecl>(
D);
1321 Context.hasSameUnqualifiedType(FromType, ToType))
1362 bool IncompatibleObjC;
1363 if (Context.typesAreCompatible(FromPointee, ToPointee))
1364 FromPointee = ToPointee;
1371 FromPointee = Context.getQualifiedType(FromPointee, FromQuals);
1372 ConvertedType = Context.getPointerType(FromPointee);
1394 if (isa<StringLiteral>(IndexExpr))
1398 Diag(FromE->
getExprLoc(), diag::err_objc_subscript_type_conversion) <<
T;
1404 diag::err_objc_index_incomplete_class_type,
1410 int NoIntegrals = 0, NoObjCIdPointers = 0;
1414 ->getVisibleConversionFunctions()) {
1416 dyn_cast<CXXConversionDecl>(
D->getUnderlyingDecl())) {
1417 QualType CT = Conversion->getConversionType().getNonReferenceType();
1420 ConversionDecls.push_back(Conversion);
1423 ConversionDecls.push_back(Conversion);
1427 if (NoIntegrals == 1 && NoObjCIdPointers == 0)
1429 if (NoIntegrals == 0 && NoObjCIdPointers == 1)
1431 if (NoIntegrals == 0 && NoObjCIdPointers == 0) {
1433 Diag(FromE->
getExprLoc(), diag::err_objc_subscript_type_conversion)
1437 Diag(FromE->
getExprLoc(), diag::err_objc_multiple_subscript_type_conversion)
1439 for (
unsigned int i = 0; i < ConversionDecls.size(); i++)
1440 Diag(ConversionDecls[i]->getLocation(),
1441 diag::note_conv_function_declared_at);
1455 if (
D->hasAttr<CFAuditedTransferAttr>() ||
1456 D->hasAttr<CFUnknownTransferAttr>())
1461 D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Info));
1475 if (
auto bridgeAttr = RD->
getAttr<ObjCBridgeAttr>())
1476 bridgedType = bridgeAttr->getBridgedType();
1477 else if (
auto bridgeAttr = RD->
getAttr<ObjCBridgeMutableAttr>())
1478 bridgedType = bridgeAttr->getBridgedType();
1500 if (AllowNSAttributedString &&
1528 if (
const auto *VD = dyn_cast<ObjCIvarDecl>(
D)) {
1530 S.
Diag(AL.
getLoc(), diag::warn_iboutlet_object_type)
1531 << AL << VD->getType() << 0;
1534 }
else if (
const auto *PD = dyn_cast<ObjCPropertyDecl>(
D)) {
1536 S.
Diag(AL.
getLoc(), diag::warn_iboutlet_object_type)
1537 << AL << PD->getType() << 1;
1541 S.
Diag(AL.
getLoc(), diag::warn_attribute_iboutlet) << AL;
1560 Diag(AL.
getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
1573 Context.Idents.get(
"NSObject"), AL.
getLoc(),
1576 Diag(AL.
getLoc(), diag::err_iboutletcollection_type) <<
"NSObject";
1584 QTLoc = Context.getTrivialTypeSourceInfo(QT, AL.
getLoc());
1592 ? diag::err_iboutletcollection_builtintype
1593 : diag::err_iboutletcollection_type)
1598 D->addAttr(::new (Context) IBOutletCollectionAttr(Context, AL, QTLoc));
1602 if (!cast<ObjCProtocolDecl>(
D)->isThisDeclarationADefinition()) {
1603 Diag(AL.
getLoc(), diag::err_objc_attr_protocol_requires_definition)
1614 if (isa<ObjCProtocolDecl>(
D->getDeclContext())) {
1615 Diag(AL.
getLoc(), diag::err_objc_direct_on_protocol) <<
false;
1620 handleSimpleAttribute<ObjCDirectAttr>(*
this,
D, AL);
1622 Diag(AL.
getLoc(), diag::warn_objc_direct_ignored) << AL;
1628 handleSimpleAttribute<ObjCDirectMembersAttr>(*
this,
D, AL);
1630 Diag(AL.
getLoc(), diag::warn_objc_direct_ignored) << AL;
1635 const auto *M = cast<ObjCMethodDecl>(
D);
1637 Diag(AL.
getLoc(), diag::err_attribute_argument_n_type)
1643 ObjCMethodFamilyAttr::FamilyKind F;
1644 if (!ObjCMethodFamilyAttr::ConvertStrToFamilyKind(IL->
Ident->
getName(), F)) {
1645 Diag(IL->
Loc, diag::warn_attribute_type_not_supported) << AL << IL->
Ident;
1649 if (F == ObjCMethodFamilyAttr::OMF_init &&
1650 !M->getReturnType()->isObjCObjectPointerType()) {
1651 Diag(M->getLocation(), diag::err_init_method_bad_return_type)
1652 << M->getReturnType();
1662 if (
const auto *TD = dyn_cast<TypedefNameDecl>(
D)) {
1665 Diag(TD->getLocation(), diag::err_nsobject_attribute);
1668 }
else if (
const auto *PD = dyn_cast<ObjCPropertyDecl>(
D)) {
1671 Diag(PD->getLocation(), diag::err_nsobject_attribute);
1681 Diag(
D->getLocation(), diag::warn_nsobject_attribute);
1687 if (
const auto *TD = dyn_cast<TypedefNameDecl>(
D)) {
1690 Diag(TD->getLocation(), diag::warn_ptr_independentclass_attribute);
1694 Diag(
D->getLocation(), diag::warn_independentclass_attribute);
1703 Diag(AL.
getLoc(), diag::err_attribute_argument_n_type)
1709 BlocksAttr::BlockType
type;
1710 if (!BlocksAttr::ConvertStrToBlockType(II->
getName(),
type)) {
1711 Diag(AL.
getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
1741 bool IsTemplateInstantiation) {
1745 handleSimpleAttributeOrDiagnose<OSConsumedAttr>(
1747 diag::warn_ns_attribute_wrong_parameter_type,
1751 handleSimpleAttributeOrDiagnose<NSConsumedAttr>(
1758 ((IsTemplateInstantiation &&
getLangOpts().ObjCAutoRefCount)
1759 ? diag::err_ns_attribute_wrong_parameter_type
1760 : diag::warn_ns_attribute_wrong_parameter_type),
1764 handleSimpleAttributeOrDiagnose<CFConsumedAttr>(
1766 diag::warn_ns_attribute_wrong_parameter_type,
1775 case ParsedAttr::AT_CFConsumed:
1776 case ParsedAttr::AT_CFReturnsRetained:
1777 case ParsedAttr::AT_CFReturnsNotRetained:
1779 case ParsedAttr::AT_OSConsumesThis:
1780 case ParsedAttr::AT_OSConsumed:
1781 case ParsedAttr::AT_OSReturnsRetained:
1782 case ParsedAttr::AT_OSReturnsNotRetained:
1783 case ParsedAttr::AT_OSReturnsRetainedOnZero:
1784 case ParsedAttr::AT_OSReturnsRetainedOnNonZero:
1786 case ParsedAttr::AT_NSConsumesSelf:
1787 case ParsedAttr::AT_NSConsumed:
1788 case ParsedAttr::AT_NSReturnsRetained:
1789 case ParsedAttr::AT_NSReturnsNotRetained:
1790 case ParsedAttr::AT_NSReturnsAutoreleased:
1793 llvm_unreachable(
"Wrong argument supplied");
1802 Diag(
Loc, diag::warn_ns_attribute_wrong_return_type)
1803 <<
"'ns_returns_retained'" << 0 << 0;
1809 const auto *PVD = dyn_cast<ParmVarDecl>(
D);
1821 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(
D)) {
1822 ReturnType = MD->getReturnType();
1824 (AL.
getKind() == ParsedAttr::AT_NSReturnsRetained)) {
1826 }
else if (
const auto *PD = dyn_cast<ObjCPropertyDecl>(
D)) {
1827 ReturnType = PD->getType();
1828 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(
D)) {
1829 ReturnType = FD->getReturnType();
1830 }
else if (
const auto *Param = dyn_cast<ParmVarDecl>(
D)) {
1837 if (ReturnType.
isNull()) {
1838 Diag(
D->getBeginLoc(), diag::warn_ns_attribute_wrong_parameter_type)
1848 llvm_unreachable(
"invalid ownership attribute");
1849 case ParsedAttr::AT_NSReturnsRetained:
1850 case ParsedAttr::AT_NSReturnsAutoreleased:
1851 case ParsedAttr::AT_NSReturnsNotRetained:
1855 case ParsedAttr::AT_OSReturnsRetained:
1856 case ParsedAttr::AT_OSReturnsNotRetained:
1857 case ParsedAttr::AT_CFReturnsRetained:
1858 case ParsedAttr::AT_CFReturnsNotRetained:
1862 Diag(
D->getBeginLoc(), diag::warn_attribute_wrong_decl_type)
1864 << ExpectedDeclKind;
1870 unsigned ParmDiagID = 2;
1873 llvm_unreachable(
"invalid ownership attribute");
1874 case ParsedAttr::AT_NSReturnsRetained:
1879 case ParsedAttr::AT_NSReturnsAutoreleased:
1880 case ParsedAttr::AT_NSReturnsNotRetained:
1885 case ParsedAttr::AT_CFReturnsRetained:
1886 case ParsedAttr::AT_CFReturnsNotRetained:
1891 case ParsedAttr::AT_OSReturnsRetained:
1892 case ParsedAttr::AT_OSReturnsNotRetained:
1903 if (isa<ParmVarDecl>(
D)) {
1904 Diag(
D->getBeginLoc(), diag::warn_ns_attribute_wrong_parameter_type)
1905 << AL << ParmDiagID << AL.
getRange();
1909 if (isa<ObjCMethodDecl>(
D))
1910 SubjectKind = Method;
1911 else if (isa<ObjCPropertyDecl>(
D))
1913 Diag(
D->getBeginLoc(), diag::warn_ns_attribute_wrong_return_type)
1914 << AL << SubjectKind << Cf << AL.
getRange();
1921 llvm_unreachable(
"invalid ownership attribute");
1922 case ParsedAttr::AT_NSReturnsAutoreleased:
1923 handleSimpleAttribute<NSReturnsAutoreleasedAttr>(*
this,
D, AL);
1925 case ParsedAttr::AT_CFReturnsNotRetained:
1926 handleSimpleAttribute<CFReturnsNotRetainedAttr>(*
this,
D, AL);
1928 case ParsedAttr::AT_NSReturnsNotRetained:
1929 handleSimpleAttribute<NSReturnsNotRetainedAttr>(*
this,
D, AL);
1931 case ParsedAttr::AT_CFReturnsRetained:
1932 handleSimpleAttribute<CFReturnsRetainedAttr>(*
this,
D, AL);
1934 case ParsedAttr::AT_NSReturnsRetained:
1935 handleSimpleAttribute<NSReturnsRetainedAttr>(*
this,
D, AL);
1937 case ParsedAttr::AT_OSReturnsRetained:
1938 handleSimpleAttribute<OSReturnsRetainedAttr>(*
this,
D, AL);
1940 case ParsedAttr::AT_OSReturnsNotRetained:
1941 handleSimpleAttribute<OSReturnsNotRetainedAttr>(*
this,
D, AL);
1947 const int EP_ObjCMethod = 1;
1948 const int EP_ObjCProperty = 2;
1952 if (isa<ObjCMethodDecl>(
D))
1953 resultType = cast<ObjCMethodDecl>(
D)->getReturnType();
1955 resultType = cast<ObjCPropertyDecl>(
D)->getType();
1959 Diag(
D->getBeginLoc(), diag::warn_ns_attribute_wrong_return_type)
1961 << (isa<ObjCMethodDecl>(
D) ? EP_ObjCMethod : EP_ObjCProperty)
1973 const auto *Method = cast<ObjCMethodDecl>(
D);
1976 if (
const auto *PDecl = dyn_cast_if_present<ObjCProtocolDecl>(DC)) {
1977 Diag(
D->getBeginLoc(), diag::warn_objc_requires_super_protocol)
1979 Diag(PDecl->getLocation(), diag::note_protocol_decl);
1983 Diag(
D->getBeginLoc(), diag::warn_objc_requires_super_protocol)
1993 if (!isa<TagDecl>(
D)) {
1994 Diag(
D->getBeginLoc(), diag::err_nserrordomain_invalid_decl) << 0;
1999 Attr.isArgIdent(0) ?
Attr.getArgAsIdent(0) :
nullptr;
2000 if (!IdentLoc || !IdentLoc->
Ident) {
2003 if (
Attr.isArgExpr(0) &&
Attr.getArgAsExpr(0))
2004 Loc =
Attr.getArgAsExpr(0)->getBeginLoc();
2006 Diag(
Loc, diag::err_nserrordomain_invalid_decl) << 0;
2016 Diag(IdentLoc->
Loc, diag::err_nserrordomain_invalid_decl)
2017 << 1 << IdentLoc->
Ident;
2029 Diag(
D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0;
2034 if (
const auto *TD = dyn_cast<TypedefNameDecl>(
D)) {
2036 Diag(AL.
getLoc(), diag::err_objc_attr_typedef_not_id) << AL;
2043 Diag(AL.
getLoc(), diag::err_objc_attr_typedef_not_void_pointer);
2056 Diag(
D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0;
2067 if (!RelatedClass) {
2068 Diag(
D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0;
2076 getASTContext(), AL, RelatedClass, ClassMethod, InstanceMethod));
2084 if (!isa<ObjCInterfaceDecl>(Ctx) &&
2085 !(isa<ObjCCategoryDecl>(Ctx) &&
2086 cast<ObjCCategoryDecl>(Ctx)->IsClassExtension())) {
2087 Diag(
D->getLocation(), diag::err_designated_init_attr_non_init);
2092 if (
auto *CatDecl = dyn_cast<ObjCCategoryDecl>(Ctx))
2093 IFace = CatDecl->getClassInterface();
2095 IFace = cast<ObjCInterfaceDecl>(Ctx);
2106 StringRef MetaDataName;
2118 bool notify =
false;
2120 auto *RD = dyn_cast<RecordDecl>(
D);
2121 if (RD && RD->getDefinition()) {
2122 RD = RD->getDefinition();
2127 ObjCBoxableAttr *BoxableAttr =
2129 RD->addAttr(BoxableAttr);
2134 L->AddedAttributeToRecord(BoxableAttr, RD);
2143 Diag(
D->getBeginLoc(), diag::err_attribute_wrong_decl_type)
2149 const auto *VD = cast<ValueDecl>(
D);
2153 Diag(AL.
getLoc(), diag::err_objc_precise_lifetime_bad_type) << QT;
2167 "didn't infer lifetime for non-dependent type?");
2176 Diag(AL.
getLoc(), diag::warn_objc_precise_lifetime_meaningless)
2186 bool DiagnoseFailure) {
2189 if (DiagnoseFailure) {
2190 S.
Diag(VD->
getBeginLoc(), diag::warn_ignored_objc_externally_retained)
2207 if (DiagnoseFailure) {
2208 S.
Diag(VD->
getBeginLoc(), diag::warn_ignored_objc_externally_retained)
2223 if (
auto *VD = dyn_cast<VarDecl>(
D)) {
2224 assert(!isa<ParmVarDecl>(VD) &&
"should be diagnosed automatically");
2225 if (!VD->hasLocalStorage()) {
2226 Diag(
D->getBeginLoc(), diag::warn_ignored_objc_externally_retained) << 0;
2233 handleSimpleAttribute<ObjCExternallyRetainedAttr>(*
this,
D, AL);
2239 unsigned NumParams =
2241 for (
unsigned I = 0; I != NumParams; ++I) {
2255 handleSimpleAttribute<ObjCExternallyRetainedAttr>(*
this,
D, AL);
2274 bool Format =
false;
2286 if (!Format || NumArgs <= Idx)
2288 const Expr *FormatExpr = Args[Idx];
2289 if (
const CStyleCastExpr *CSCE = dyn_cast<CStyleCastExpr>(FormatExpr))
2290 FormatExpr = CSCE->getSubExpr();
2300 Diag(FormatExpr->
getExprLoc(), diag::warn_objc_cdirective_format_string)
2315 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(Ignored))
2316 Ignored = OVE->getSourceExpr();
2317 bool NeedsParens = isa<AbstractConditionalOperator>(Ignored) ||
2318 isa<BinaryOperator>(Ignored) ||
2319 isa<CXXOperatorCallExpr>(Ignored);
2330 Expr *Element,
unsigned ElementKind) {
2332 if (
auto ICE = dyn_cast<ImplicitCastExpr>(Element)) {
2333 if (ICE->getCastKind() == CK_BitCast &&
2335 Element = ICE->getSubExpr();
2338 QualType ElementType = Element->getType();
2343 S.
Diag(Element->getBeginLoc(), diag::warn_objc_collection_literal_element)
2344 << ElementType << ElementKind << TargetElementType
2345 << Element->getSourceRange();
2348 if (
auto ArrayLiteral = dyn_cast<ObjCArrayLiteral>(Element))
2350 else if (
auto DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(Element))
2365 if (TargetObjCPtr->isUnspecialized() ||
2366 TargetObjCPtr->getInterfaceDecl()->getCanonicalDecl() !=
2371 if (TypeArgs.size() != 1)
2374 QualType TargetElementType = TypeArgs[0];
2375 for (
unsigned I = 0, N = ArrayLiteral->
getNumElements(); I != N; ++I) {
2390 if (TargetObjCPtr->isUnspecialized() ||
2391 TargetObjCPtr->getInterfaceDecl()->getCanonicalDecl() !=
2396 if (TypeArgs.size() != 2)
2399 QualType TargetKeyType = TypeArgs[0];
2400 QualType TargetObjectType = TypeArgs[1];
2401 for (
unsigned I = 0, N = DictionaryLiteral->
getNumElements(); I != N; ++I) {
Defines the clang::Preprocessor interface.
RedeclarationKind
Specifies whether (or how) name lookup is being performed for a redeclaration (vs.
This file declares semantic analysis for Objective-C.
Defines the Objective-C statement AST node classes.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT)
canAssignObjCInterfaces - Return true if the two interface types are compatible for assignment from R...
QualType getObjCObjectType(QualType Base, ObjCProtocolDecl *const *Protocols, unsigned NumProtocols) const
Legacy interface: cannot provide type arguments or __kindof.
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
Attr - This represents one attribute.
SourceRange getRange() const
bool isRegularKeywordAttribute() const
SourceLocation getLoc() const
Type source information for an attributed type.
Stmt * getBody() const override
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
bool capturesVariable(const VarDecl *var) const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
const BlockDecl * getBlockDecl() const
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Represents a C++ conversion function within a class.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
bool isInvalidDecl() const
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
The name of a declaration.
SourceLocation getBeginLoc() const LLVM_READONLY
This represents one expression.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
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.
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Represents a function declaration or definition.
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.
Represents the results of name lookup.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
@ ClassId_NSMutableOrderedSet
@ ClassId_NSMutableDictionary
NSSetMethodKind
Enumerates the NSMutableSet/NSOrderedSet methods used to apply some checks.
@ NSOrderedSet_setObjectAtIndex
@ NSOrderedSet_replaceObjectAtIndexWithObject
@ NSOrderedSet_setObjectAtIndexedSubscript
@ NSOrderedSet_insertObjectAtIndex
NSDictionaryMethodKind
Enumerates the NSDictionary/NSMutableDictionary methods used to generate literals and to apply some c...
@ NSMutableDict_setValueForKey
@ NSMutableDict_setObjectForKey
@ NSMutableDict_setObjectForKeyedSubscript
NSArrayMethodKind
Enumerates the NSArray/NSMutableArray methods used to generate literals and to apply some checks.
@ NSMutableArr_setObjectAtIndexedSubscript
@ NSMutableArr_insertObjectAtIndex
@ NSMutableArr_replaceObjectAtIndex
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
ObjCStringFormatFamily getObjCFStringFormattingFamily() const
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
Expr * getElement(unsigned Index)
getElement - Return the Element at the specified index.
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c array literal.
Represents Objective-C's @catch statement.
Represents Objective-C's @finally statement.
Represents Objective-C's @synchronized statement.
Represents Objective-C's @throw statement.
static ObjCAtTryStmt * Create(const ASTContext &Context, SourceLocation atTryLoc, Stmt *atTryStmt, Stmt **CatchStmts, unsigned NumCatchStmts, Stmt *atFinallyStmt)
Represents Objective-C's @autoreleasepool Statement.
ObjCCategoryDecl - Represents a category declaration.
ObjCContainerDecl - Represents a container for method declarations.
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c dictionary literal.
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
Represents Objective-C's collection statement.
Represents an ObjC class declaration.
ObjCTypeParamList * getTypeParamList() const
Retrieve the type parameters of this class.
ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const
Lookup an instance method for a given selector.
ObjCMethodDecl * lookupPrivateMethod(const Selector &Sel, bool Instance=true) const
Lookup a method in the classes implementation hierarchy.
ObjCInterfaceDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C class.
void setHasDesignatedInitializers()
Indicate that this interface decl contains at least one initializer marked with the 'objc_designated_...
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
An expression that sends a message to the given Objective-C object or class.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
SourceLocation getSuperLoc() const
Retrieve the location of the 'super' keyword for a class or instance message to 'super',...
Selector getSelector() const
@ SuperInstance
The receiver is the instance of the superclass object.
@ Instance
The receiver is an object instance.
bool isInstanceMessage() const
Determine whether this is an instance message to either a computed object or to super.
const ObjCMethodDecl * getMethodDecl() const
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver.
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
ArrayRef< ParmVarDecl * > parameters() const
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Wraps an ObjCPointerType with source location information.
void setStarLoc(SourceLocation Loc)
Represents a pointer to an Objective C object.
ArrayRef< QualType > getTypeArgs() const
Retrieve the type arguments for this type.
void setHasBaseTypeAsWritten(bool HasBaseType)
Represents a class type in Objective C.
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
Represents one property declaration in an Objective-C interface.
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
ObjCPropertyDecl * getExplicitProperty() const
const Expr * getBase() const
bool isImplicitProperty() const
SourceLocation getLocation() const
bool isSuperReceiver() const
Represents an Objective-C protocol declaration.
The basic abstraction for the target Objective-C runtime.
bool allowsDirectDispatch() const
Does this runtime supports direct dispatch.
ObjCStringLiteral, used for Objective-C string literals i.e.
Represents the declaration of an Objective-C type parameter.
Stores a list of Objective-C type parameters for a parameterized class or a category/extension thereo...
unsigned size() const
Determine the number of type parameters in this list.
ProtocolLAngleLoc, ProtocolRAngleLoc, and the source locations for protocol qualifiers are stored aft...
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Represents a pack expansion of types.
Represents a parameter to a function.
ParsedAttr - Represents a syntactic attribute.
IdentifierLoc * getArgAsIdent(unsigned Arg) const
bool hasParsedType() const
const ParsedType & getTypeArg() const
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this attribute.
bool isArgIdent(unsigned Arg) const
bool isUsedAsTypeAttr() const
AttributeCommonInfo::Kind getKind() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
std::pair< IdentifierInfo *, SourceLocation > getPragmaARCCFCodeAuditedInfo() const
The location of the currently-active #pragma clang arc_cf_code_audited begin.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
A (possibly-)qualified type.
QualType withConst() const
QualType getLocalUnqualifiedType() const
Return this type with all of the instance-specific qualifiers removed, but without removing any quali...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool isConstQualified() const
Determine whether this type is const-qualified.
The collection of all-type qualifiers we support.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
ObjCLifetime getObjCLifetime() const
Qualifiers withoutObjCLifetime() const
std::string getAsString() const
bool compatiblyIncludes(Qualifiers other) const
Determines if these qualifiers compatibly include another set.
void setObjCLifetime(ObjCLifetime type)
Represents a struct/union/class.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
Scope - A scope is a transient data structure that is used while parsing the program.
bool isAtCatchScope() const
isAtCatchScope - Return true if this scope is @catch.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
Smart pointer class that efficiently represents Objective-C method names.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
bool isUnarySelector() const
unsigned getNumArgs() const
A generic diagnostic builder for errors which may or may not be deferred.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
bool isCFError(RecordDecl *D)
void ActOnObjCReenterContainerContext(ObjCContainerDecl *ObjCCtx)
void ActOnObjCTemporaryExitContainerContext(ObjCContainerDecl *ObjCCtx)
Invoked when we must temporarily exit the objective-c container scope for parsing/looking-up C constr...
void handleRuntimeName(Decl *D, const ParsedAttr &AL)
void handleNSObject(Decl *D, const ParsedAttr &AL)
bool isValidOSObjectOutParameter(const Decl *D)
StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc, Stmt *First, Expr *collection, SourceLocation RParenLoc)
StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body)
FinishObjCForCollectionStmt - Attach the body to a objective-C foreach statement.
void handleNSErrorDomain(Decl *D, const ParsedAttr &Attr)
void handleXReturnsXRetainedAttr(Decl *D, const ParsedAttr &AL)
QualType BuildObjCTypeParamType(const ObjCTypeParamDecl *Decl, SourceLocation ProtocolLAngleLoc, ArrayRef< ObjCProtocolDecl * > Protocols, ArrayRef< SourceLocation > ProtocolLocs, SourceLocation ProtocolRAngleLoc, bool FailOnError=false)
Build an Objective-C type parameter type.
TypeResult actOnObjCTypeArgsAndProtocolQualifiers(Scope *S, SourceLocation Loc, ParsedType BaseType, SourceLocation TypeArgsLAngleLoc, ArrayRef< ParsedType > TypeArgs, SourceLocation TypeArgsRAngleLoc, SourceLocation ProtocolLAngleLoc, ArrayRef< Decl * > Protocols, ArrayRef< SourceLocation > ProtocolLocs, SourceLocation ProtocolRAngleLoc)
Build a specialized and/or protocol-qualified Objective-C type.
void checkArrayLiteral(QualType TargetType, ObjCArrayLiteral *ArrayLiteral)
Check an Objective-C array literal being converted to the given target type.
void handleExternallyRetainedAttr(Decl *D, const ParsedAttr &AL)
ObjCSubscriptKind CheckSubscriptingKind(Expr *FromE)
CheckSubscriptingKind - This routine decide what type of indexing represented by "FromE" is being don...
IdentifierInfo * getNSErrorIdent()
Retrieve the identifier "NSError".
StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SynchExpr, Stmt *SynchBody)
ParsedType ActOnObjCInstanceType(SourceLocation Loc)
The parser has parsed the context-sensitive type 'instancetype' in an Objective-C message declaration...
void handleMethodFamilyAttr(Decl *D, const ParsedAttr &AL)
void handleIndependentClass(Decl *D, const ParsedAttr &AL)
ObjCInterfaceDecl * NSArrayDecl
The declaration of the Objective-C NSArray class.
RecordDecl * CFError
The struct behind the CFErrorRef pointer.
void handleIBOutlet(Decl *D, const ParsedAttr &AL)
void handleReturnsInnerPointerAttr(Decl *D, const ParsedAttr &Attrs)
bool isObjCWritebackConversion(QualType FromType, QualType ToType, QualType &ConvertedType)
Determine whether this is an Objective-C writeback conversion, used for parameter passing when perfor...
void CheckObjCCircularContainer(ObjCMessageExpr *Message)
Check whether receiver is mutable ObjC container which attempts to add itself into the container.
void handleSuppresProtocolAttr(Decl *D, const ParsedAttr &AL)
StmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try, MultiStmtArg Catch, Stmt *Finally)
void handleOwnershipAttr(Decl *D, const ParsedAttr &AL)
bool isSignedCharBool(QualType Ty)
void handleBlocksAttr(Decl *D, const ParsedAttr &AL)
StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body)
void ActOnObjCContainerFinishDefinition()
TypeResult actOnObjCProtocolQualifierType(SourceLocation lAngleLoc, ArrayRef< Decl * > protocols, ArrayRef< SourceLocation > protocolLocs, SourceLocation rAngleLoc)
Build a an Objective-C protocol-qualified 'id' type where no base type was specified.
StmtResult BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw)
void handleBridgeMutableAttr(Decl *D, const ParsedAttr &AL)
Sema::RetainOwnershipKind parsedAttrToRetainOwnershipKind(const ParsedAttr &AL)
void handleRequiresSuperAttr(Decl *D, const ParsedAttr &Attrs)
ObjCInterfaceDecl * NSDictionaryDecl
The declaration of the Objective-C NSDictionary class.
bool CheckObjCString(Expr *Arg)
CheckObjCString - Checks that the argument to the builtin CFString constructor is correct Note: It mi...
QualType BuildObjCObjectType(QualType BaseType, SourceLocation Loc, SourceLocation TypeArgsLAngleLoc, ArrayRef< TypeSourceInfo * > TypeArgs, SourceLocation TypeArgsRAngleLoc, SourceLocation ProtocolLAngleLoc, ArrayRef< ObjCProtocolDecl * > Protocols, ArrayRef< SourceLocation > ProtocolLocs, SourceLocation ProtocolRAngleLoc, bool FailOnError, bool Rebuilding)
Build an Objective-C object pointer type.
ExprResult ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand)
void AddXConsumedAttr(Decl *D, const AttributeCommonInfo &CI, Sema::RetainOwnershipKind K, bool IsTemplateInstantiation)
void adornBoolConversionDiagWithTernaryFixit(Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder)
const DeclContext * getCurObjCLexicalContext() const
void handleDesignatedInitializer(Decl *D, const ParsedAttr &AL)
void handleBridgeRelatedAttr(Decl *D, const ParsedAttr &AL)
void handleIBOutletCollection(Decl *D, const ParsedAttr &AL)
ObjCProtocolDecl * LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Find the protocol with the given name, if any.
void DiagnoseCStringFormatDirectiveInCFAPI(const NamedDecl *FDecl, Expr **Args, unsigned NumArgs)
Diagnose use of s directive in an NSString which is being passed as formatting string to formatting m...
bool isCFStringType(QualType T)
void handleDirectAttr(Decl *D, const ParsedAttr &AL)
StmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, Scope *CurScope)
void checkRetainCycles(ObjCMessageExpr *msg)
checkRetainCycles - Check whether an Objective-C message send might create an obvious retain cycle.
StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc, SourceLocation RParen, Decl *Parm, Stmt *Body)
bool isNSStringType(QualType T, bool AllowNSAttributedString=false)
bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx)
ExprResult CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection)
void AddCFAuditedAttribute(Decl *D)
AddCFAuditedAttribute - Check whether we're currently within '#pragma clang arc_cf_code_audited' and,...
void checkDictionaryLiteral(QualType TargetType, ObjCDictionaryLiteral *DictionaryLiteral)
Check an Objective-C dictionary literal being converted to the given target type.
void handleBoxable(Decl *D, const ParsedAttr &AL)
bool checkNSReturnsRetainedReturnType(SourceLocation loc, QualType type)
ObjCMethodDecl * LookupMethodInQualifiedType(Selector Sel, const ObjCObjectPointerType *OPT, bool IsInstance)
LookupMethodInQualifiedType - Lookups up a method in protocol qualifier list of a qualified objective...
StmtResult ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body)
void handleDirectMembersAttr(Decl *D, const ParsedAttr &AL)
bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, ArrayRef< const Expr * > Args)
void handleBridgeAttr(Decl *D, const ParsedAttr &AL)
void handlePreciseLifetimeAttr(Decl *D, const ParsedAttr &AL)
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
void ActOnObjCContainerStartDefinition(ObjCContainerDecl *IDecl)
Sema - This implements semantic analysis and AST building for C.
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)
Package the given type and TSI into a ParsedType.
ExprResult PerformContextuallyConvertToObjCPointer(Expr *From)
PerformContextuallyConvertToObjCPointer - Perform a contextual conversion of the expression From to a...
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupObjCProtocolName
Look up the name of an Objective-C protocol.
bool FormatStringHasSArg(const StringLiteral *FExpr)
static bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember, bool IsVariadic, FormatStringInfo *FSI)
Given a FunctionDecl's FormatAttr, attempts to populate the FomatStringInfo parameter with the Format...
Scope * getScopeForContext(DeclContext *Ctx)
Determines the active Scope associated with the given declaration context.
NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Look up a name, looking for a single declaration.
static FormatStringType GetFormatStringType(const FormatAttr *Format)
bool isObjCPointerConversion(QualType FromType, QualType ToType, QualType &ConvertedType, bool &IncompatibleObjC)
isObjCPointerConversion - Determines whether this is an Objective-C pointer conversion.
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
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()
DeclContext * getCurLexicalContext() const
sema::FunctionScopeInfo * getCurFunction() const
AssignConvertType CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, bool Diagnose=true, bool DiagnoseCFAudited=false, bool ConvertRHS=true)
Check assignment constraints for an assignment of RHS to LHSType.
ExprResult DefaultLvalueConversion(Expr *E)
void CheckTCBEnforcement(const SourceLocation CallExprLoc, const NamedDecl *Callee)
Enforce the bounds of a TCB CheckTCBEnforcement - Enforces that every function in a named TCB only di...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
@ Compatible
Compatible - the types are compatible according to the standard.
DeclContext * OriginalLexicalContext
Generally null except when we temporarily switch decl contexts, like in.
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
bool isCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind=CompleteTypeKind::Default)
void setFunctionHasBranchProtectedScope()
ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS=nullptr, bool isClassName=false, bool HasTrailingDot=false, ParsedType ObjectType=nullptr, bool IsCtorOrDtorName=false, bool WantNontrivialTypeSourceInfo=false, bool IsClassTemplateDeductionContext=true, ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No, IdentifierInfo **CorrectedII=nullptr)
If the identifier refers to a type name within this scope, return the declaration of that type.
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
void DiagnoseAutoDeductionFailure(const VarDecl *VDecl, const Expr *Init)
TemplateDeductionResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *Initializer, QualType &Result, sema::TemplateDeductionInfo &Info, bool DependentDeduction=false, bool IgnoreConstraints=false, TemplateSpecCandidateSet *FailedTSC=nullptr)
Deduce the type for an auto type-specifier (C++11 [dcl.spec.auto]p6)
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
bool checkStringLiteralArgumentAttr(const AttributeCommonInfo &CI, const Expr *E, StringRef &Str, SourceLocation *ArgLocation=nullptr)
Check if the argument E is a ASCII string literal.
ASTMutationListener * getASTMutationListener() const
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, const Expr *ThisArg, ArrayRef< const Expr * > Args, bool IsMemberFunction, SourceLocation Loc, SourceRange Range, VariadicCallType CallType)
Handles the checks for format strings, non-POD arguments to vararg functions, NULL arguments passed t...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
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.
StringRef getString() const
TagKind getTagKind() const
Base wrapper for a particular "section" of type source info.
TypeLoc findExplicitQualifierLoc() const
Find a type with the location of an explicit type qualifier.
T getAs() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
T castAs() const
Convert to the specified TypeLoc type, asserting that this TypeLoc is of the desired type.
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
SourceLocation getBeginLoc() const
Get the begin source location.
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.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isBlockPointerType() const
bool isVoidPointerType() const
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isObjCNSObjectType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isBuiltinType() const
Helper methods to distinguish type categories.
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 isObjCObjectType() const
bool isBlockCompatibleObjCPointerType(ASTContext &ctx) const
bool isObjCLifetimeType() const
Returns true if objects of this type have lifetime semantics under ARC.
Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const
Return the implicit lifetime for this type, which must not be dependent.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isObjCObjectPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isObjCRetainableType() const
QualType getUnderlyingType() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
void setType(QualType newType)
Represents a variable declaration or definition.
void setARCPseudoStrong(bool PS)
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Retains information about a function, method, or block that is currently being parsed.
void setHasObjCTry(SourceLocation TryLoc)
SourceLocation FirstSEHTryLoc
First SEH '__try' statement in the current function.
Provides information about an attempted template argument deduction, whose success or failure was des...
const AstTypeMatcher< PointerType > pointerType
Matches pointer types, but does not match Objective-C object pointer types.
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
The JSON file list parser is used to communicate input to InstallAPI.
static void checkCollectionLiteralElement(Sema &S, QualType TargetElementType, Expr *Element, unsigned ElementKind)
Check a single element within a collection literal against the target element type.
AttributeDeclKind
These constants match the enumerated choices of warn_attribute_wrong_decl_type and err_attribute_wron...
@ ExpectedFunctionMethodOrParameter
@ ExpectedFunctionOrMethod
bool hasDeclarator(const Decl *D)
Return true if the given decl has a declarator that should have been processed by Sema::GetTypeForDec...
static bool isValidSubjectOfOSAttribute(QualType QT)
static void diagnoseRetainCycle(Sema &S, Expr *capturer, RetainCycleOwner &owner)
const ParmVarDecl * getFunctionOrMethodParam(const Decl *D, unsigned Idx)
static bool isSetterLikeSelector(Selector sel)
Check for a keyword selector that starts with the word 'add' or 'set'.
static Expr * findCapturingExpr(Sema &S, Expr *e, RetainCycleOwner &owner)
Check whether the given argument is a block which captures a variable.
static bool considerVariable(VarDecl *var, Expr *ref, RetainCycleOwner &owner)
Consider whether capturing the given variable can possibly lead to a retain cycle.
static std::optional< int > GetNSMutableDictionaryArgumentIndex(SemaObjC &S, ObjCMessageExpr *Message)
@ AANT_ArgumentIdentifier
@ Property
The type of a property.
@ Result
The result type of a method or function.
static bool checkIBOutletCommon(Sema &S, Decl *D, const ParsedAttr &AL)
LLVM_READONLY bool isLowercase(unsigned char c)
Return true if this character is a lowercase ASCII letter: [a-z].
@ Struct
The "struct" keyword.
static QualType applyObjCTypeArgs(Sema &S, SourceLocation loc, QualType type, ArrayRef< TypeSourceInfo * > typeArgs, SourceRange typeArgsRange, bool failOnError, bool rebuilding)
Apply Objective-C type arguments to the given type.
static bool isValidSubjectOfNSAttribute(QualType QT)
static bool isValidSubjectOfCFAttribute(QualType QT)
static std::optional< int > GetNSSetArgumentIndex(SemaObjC &S, ObjCMessageExpr *Message)
static bool tryMakeVariablePseudoStrong(Sema &S, VarDecl *VD, bool DiagnoseFailure)
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
const FunctionProtoType * T
static bool isValidSubjectOfNSReturnsRetainedAttribute(QualType QT)
bool hasFunctionProto(const Decl *D)
hasFunctionProto - Return true if the given decl has a argument information.
static bool findRetainCycleOwner(Sema &S, Expr *e, RetainCycleOwner &owner)
unsigned getFunctionOrMethodNumParams(const Decl *D)
getFunctionOrMethodNumParams - Return number of function or method parameters.
TemplateDeductionResult
Describes the result of template argument deduction.
@ Success
Template argument deduction was successful.
@ AlreadyDiagnosed
Some error which was already diagnosed.
U cast(CodeGen::Address addr)
static std::optional< int > GetNSMutableArrayArgumentIndex(SemaObjC &S, ObjCMessageExpr *Message)
Wraps an identifier and optional source location for the identifier.