clang 22.0.0git
SemaObjC.cpp
Go to the documentation of this file.
1//===----- SemaObjC.cpp ---- Semantic Analysis for Objective-C ------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements semantic analysis for Objective-C.
10///
11//===----------------------------------------------------------------------===//
12
13#include "clang/Sema/SemaObjC.h"
16#include "clang/AST/StmtObjC.h"
19#include "clang/Sema/Attr.h"
20#include "clang/Sema/Lookup.h"
23#include "clang/Sema/Sema.h"
25#include "llvm/Support/ConvertUTF.h"
26
27namespace clang {
28
30 : SemaBase(S), NSNumberDecl(nullptr), NSValueDecl(nullptr),
31 NSStringDecl(nullptr), StringWithUTF8StringMethod(nullptr),
32 ValueWithBytesObjCTypeMethod(nullptr), NSArrayDecl(nullptr),
33 ArrayWithObjectsMethod(nullptr), NSDictionaryDecl(nullptr),
34 DictionaryWithObjectsMethod(nullptr) {}
35
37 Stmt *First, Expr *collection,
38 SourceLocation RParenLoc) {
39 ASTContext &Context = getASTContext();
41
42 ExprResult CollectionExprResult =
43 CheckObjCForCollectionOperand(ForLoc, collection);
44
45 if (First) {
46 QualType FirstType;
47 if (DeclStmt *DS = dyn_cast<DeclStmt>(First)) {
48 if (!DS->isSingleDecl())
49 return StmtError(Diag((*DS->decl_begin())->getLocation(),
50 diag::err_toomany_element_decls));
51
52 VarDecl *D = dyn_cast<VarDecl>(DS->getSingleDecl());
53 if (!D || D->isInvalidDecl())
54 return StmtError();
55
56 FirstType = D->getType();
57 // C99 6.8.5p3: The declaration part of a 'for' statement shall only
58 // declare identifiers for objects having storage class 'auto' or
59 // 'register'.
60 if (!D->hasLocalStorage())
61 return StmtError(
62 Diag(D->getLocation(), diag::err_non_local_variable_decl_in_for));
63
64 // If the type contained 'auto', deduce the 'auto' to 'id'.
65 if (FirstType->getContainedAutoType()) {
66 SourceLocation Loc = D->getLocation();
67 OpaqueValueExpr OpaqueId(Loc, Context.getObjCIdType(), VK_PRValue);
68 Expr *DeducedInit = &OpaqueId;
70 FirstType = QualType();
72 D->getTypeSourceInfo()->getTypeLoc(), DeducedInit, FirstType, Info);
76 if (FirstType.isNull()) {
77 D->setInvalidDecl();
78 return StmtError();
79 }
80
81 D->setType(FirstType);
82
85 D->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
86 Diag(Loc, diag::warn_auto_var_is_id) << D->getDeclName();
87 }
88 }
89
90 } else {
91 Expr *FirstE = cast<Expr>(First);
92 if (!FirstE->isTypeDependent() && !FirstE->isLValue())
93 return StmtError(
94 Diag(First->getBeginLoc(), diag::err_selector_element_not_lvalue)
95 << First->getSourceRange());
96
97 FirstType = static_cast<Expr *>(First)->getType();
98 if (FirstType.isConstQualified())
99 Diag(ForLoc, diag::err_selector_element_const_type)
100 << FirstType << First->getSourceRange();
101 }
102 if (!FirstType->isDependentType() &&
103 !FirstType->isObjCObjectPointerType() &&
104 !FirstType->isBlockPointerType())
105 return StmtError(Diag(ForLoc, diag::err_selector_element_type)
106 << FirstType << First->getSourceRange());
107 }
108
109 if (CollectionExprResult.isInvalid())
110 return StmtError();
111
112 CollectionExprResult = SemaRef.ActOnFinishFullExpr(CollectionExprResult.get(),
113 /*DiscardedValue*/ false);
114 if (CollectionExprResult.isInvalid())
115 return StmtError();
116
117 return new (Context) ObjCForCollectionStmt(First, CollectionExprResult.get(),
118 nullptr, ForLoc, RParenLoc);
119}
120
122 Expr *collection) {
123 ASTContext &Context = getASTContext();
124 if (!collection)
125 return ExprError();
126
127 // Bail out early if we've got a type-dependent expression.
128 if (collection->isTypeDependent())
129 return collection;
130
131 // Perform normal l-value conversion.
133 if (result.isInvalid())
134 return ExprError();
135 collection = result.get();
136
137 // The operand needs to have object-pointer type.
138 // TODO: should we do a contextual conversion?
140 collection->getType()->getAs<ObjCObjectPointerType>();
141 if (!pointerType)
142 return Diag(forLoc, diag::err_collection_expr_type)
143 << collection->getType() << collection->getSourceRange();
144
145 // Check that the operand provides
146 // - countByEnumeratingWithState:objects:count:
147 const ObjCObjectType *objectType = pointerType->getObjectType();
148 ObjCInterfaceDecl *iface = objectType->getInterface();
149
150 // If we have a forward-declared type, we can't do this check.
151 // Under ARC, it is an error not to have a forward-declared class.
152 if (iface &&
153 (getLangOpts().ObjCAutoRefCount
154 ? SemaRef.RequireCompleteType(forLoc, QualType(objectType, 0),
155 diag::err_arc_collection_forward,
156 collection)
157 : !SemaRef.isCompleteType(forLoc, QualType(objectType, 0)))) {
158 // Otherwise, if we have any useful type information, check that
159 // the type declares the appropriate method.
160 } else if (iface || !objectType->qual_empty()) {
161 const IdentifierInfo *selectorIdents[] = {
162 &Context.Idents.get("countByEnumeratingWithState"),
163 &Context.Idents.get("objects"), &Context.Idents.get("count")};
164 Selector selector = Context.Selectors.getSelector(3, &selectorIdents[0]);
165
166 ObjCMethodDecl *method = nullptr;
167
168 // If there's an interface, look in both the public and private APIs.
169 if (iface) {
170 method = iface->lookupInstanceMethod(selector);
171 if (!method)
172 method = iface->lookupPrivateMethod(selector);
173 }
174
175 // Also check protocol qualifiers.
176 if (!method)
177 method = LookupMethodInQualifiedType(selector, pointerType,
178 /*instance*/ true);
179
180 // If we didn't find it anywhere, give up.
181 if (!method) {
182 Diag(forLoc, diag::warn_collection_expr_type)
183 << collection->getType() << selector << collection->getSourceRange();
184 }
185
186 // TODO: check for an incompatible signature?
187 }
188
189 // Wrap up any cleanups in the expression.
190 return collection;
191}
192
194 if (!S || !B)
195 return StmtError();
196 ObjCForCollectionStmt *ForStmt = cast<ObjCForCollectionStmt>(S);
197
198 ForStmt->setBody(B);
199 return S;
200}
201
203 SourceLocation RParen, Decl *Parm,
204 Stmt *Body) {
205 ASTContext &Context = getASTContext();
206 VarDecl *Var = cast_or_null<VarDecl>(Parm);
207 if (Var && Var->isInvalidDecl())
208 return StmtError();
209
210 return new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, Body);
211}
212
214 ASTContext &Context = getASTContext();
215 return new (Context) ObjCAtFinallyStmt(AtLoc, Body);
216}
217
219 MultiStmtArg CatchStmts,
220 Stmt *Finally) {
221 ASTContext &Context = getASTContext();
222 if (!getLangOpts().ObjCExceptions)
223 Diag(AtLoc, diag::err_objc_exceptions_disabled) << "@try";
224
225 // Objective-C try is incompatible with SEH __try.
227 if (FSI->FirstSEHTryLoc.isValid()) {
228 Diag(AtLoc, diag::err_mixing_cxx_try_seh_try) << 1;
229 Diag(FSI->FirstSEHTryLoc, diag::note_conflicting_try_here) << "'__try'";
230 }
231
232 FSI->setHasObjCTry(AtLoc);
233 unsigned NumCatchStmts = CatchStmts.size();
234 return ObjCAtTryStmt::Create(Context, AtLoc, Try, CatchStmts.data(),
235 NumCatchStmts, Finally);
236}
237
239 ASTContext &Context = getASTContext();
240 if (Throw) {
242 if (Result.isInvalid())
243 return StmtError();
244
245 Result =
246 SemaRef.ActOnFinishFullExpr(Result.get(), /*DiscardedValue*/ false);
247 if (Result.isInvalid())
248 return StmtError();
249 Throw = Result.get();
250
251 QualType ThrowType = Throw->getType();
252 // Make sure the expression type is an ObjC pointer or "void *".
253 if (!ThrowType->isDependentType() &&
254 !ThrowType->isObjCObjectPointerType()) {
255 const PointerType *PT = ThrowType->getAs<PointerType>();
256 if (!PT || !PT->getPointeeType()->isVoidType())
257 return StmtError(Diag(AtLoc, diag::err_objc_throw_expects_object)
258 << Throw->getType() << Throw->getSourceRange());
259 }
260 }
261
262 return new (Context) ObjCAtThrowStmt(AtLoc, Throw);
263}
264
266 Scope *CurScope) {
267 if (!getLangOpts().ObjCExceptions)
268 Diag(AtLoc, diag::err_objc_exceptions_disabled) << "@throw";
269
270 if (!Throw) {
271 // @throw without an expression designates a rethrow (which must occur
272 // in the context of an @catch clause).
273 Scope *AtCatchParent = CurScope;
274 while (AtCatchParent && !AtCatchParent->isAtCatchScope())
275 AtCatchParent = AtCatchParent->getParent();
276 if (!AtCatchParent)
277 return StmtError(Diag(AtLoc, diag::err_rethrow_used_outside_catch));
278 }
279 return BuildObjCAtThrowStmt(AtLoc, Throw);
280}
281
283 Expr *operand) {
285 if (result.isInvalid())
286 return ExprError();
287 operand = result.get();
288
289 // Make sure the expression type is an ObjC pointer or "void *".
290 QualType type = operand->getType();
291 if (!type->isDependentType() && !type->isObjCObjectPointerType()) {
292 const PointerType *pointerType = type->getAs<PointerType>();
293 if (!pointerType || !pointerType->getPointeeType()->isVoidType()) {
294 if (getLangOpts().CPlusPlus) {
296 diag::err_incomplete_receiver_type))
297 return Diag(atLoc, diag::err_objc_synchronized_expects_object)
298 << type << operand->getSourceRange();
299
300 ExprResult result =
302 if (result.isInvalid())
303 return ExprError();
304 if (!result.isUsable())
305 return Diag(atLoc, diag::err_objc_synchronized_expects_object)
306 << type << operand->getSourceRange();
307
308 operand = result.get();
309 } else {
310 return Diag(atLoc, diag::err_objc_synchronized_expects_object)
311 << type << operand->getSourceRange();
312 }
313 }
314 }
315
316 // The operand to @synchronized is a full-expression.
317 return SemaRef.ActOnFinishFullExpr(operand, /*DiscardedValue*/ false);
318}
319
321 Expr *SyncExpr,
322 Stmt *SyncBody) {
323 ASTContext &Context = getASTContext();
324 // We can't jump into or indirect-jump out of a @synchronized block.
326 return new (Context) ObjCAtSynchronizedStmt(AtLoc, SyncExpr, SyncBody);
327}
328
330 Stmt *Body) {
331 ASTContext &Context = getASTContext();
333 return new (Context) ObjCAutoreleasePoolStmt(AtLoc, Body);
334}
335
337 SourceLocation lAngleLoc, ArrayRef<Decl *> protocols,
338 ArrayRef<SourceLocation> protocolLocs, SourceLocation rAngleLoc) {
339 ASTContext &Context = getASTContext();
340 // Form id<protocol-list>.
341 QualType Result = Context.getObjCObjectType(
342 Context.ObjCBuiltinIdTy, {},
343 llvm::ArrayRef((ObjCProtocolDecl *const *)protocols.data(),
344 protocols.size()),
345 false);
346 Result = Context.getObjCObjectPointerType(Result);
347
348 TypeSourceInfo *ResultTInfo = Context.CreateTypeSourceInfo(Result);
349 TypeLoc ResultTL = ResultTInfo->getTypeLoc();
350
351 auto ObjCObjectPointerTL = ResultTL.castAs<ObjCObjectPointerTypeLoc>();
352 ObjCObjectPointerTL.setStarLoc(SourceLocation()); // implicit
353
354 auto ObjCObjectTL =
355 ObjCObjectPointerTL.getPointeeLoc().castAs<ObjCObjectTypeLoc>();
356 ObjCObjectTL.setHasBaseTypeAsWritten(false);
357 ObjCObjectTL.getBaseLoc().initialize(Context, SourceLocation());
358
359 // No type arguments.
360 ObjCObjectTL.setTypeArgsLAngleLoc(SourceLocation());
361 ObjCObjectTL.setTypeArgsRAngleLoc(SourceLocation());
362
363 // Fill in protocol qualifiers.
364 ObjCObjectTL.setProtocolLAngleLoc(lAngleLoc);
365 ObjCObjectTL.setProtocolRAngleLoc(rAngleLoc);
366 for (unsigned i = 0, n = protocols.size(); i != n; ++i)
367 ObjCObjectTL.setProtocolLoc(i, protocolLocs[i]);
368
369 // We're done. Return the completed type to the parser.
370 return SemaRef.CreateParsedType(Result, ResultTInfo);
371}
372
374 Scope *S, SourceLocation Loc, ParsedType BaseType,
375 SourceLocation TypeArgsLAngleLoc, ArrayRef<ParsedType> TypeArgs,
376 SourceLocation TypeArgsRAngleLoc, SourceLocation ProtocolLAngleLoc,
377 ArrayRef<Decl *> Protocols, ArrayRef<SourceLocation> ProtocolLocs,
378 SourceLocation ProtocolRAngleLoc) {
379 ASTContext &Context = getASTContext();
380 TypeSourceInfo *BaseTypeInfo = nullptr;
381 QualType T = SemaRef.GetTypeFromParser(BaseType, &BaseTypeInfo);
382 if (T.isNull())
383 return true;
384
385 // Handle missing type-source info.
386 if (!BaseTypeInfo)
387 BaseTypeInfo = Context.getTrivialTypeSourceInfo(T, Loc);
388
389 // Extract type arguments.
390 SmallVector<TypeSourceInfo *, 4> ActualTypeArgInfos;
391 for (unsigned i = 0, n = TypeArgs.size(); i != n; ++i) {
392 TypeSourceInfo *TypeArgInfo = nullptr;
393 QualType TypeArg = SemaRef.GetTypeFromParser(TypeArgs[i], &TypeArgInfo);
394 if (TypeArg.isNull()) {
395 ActualTypeArgInfos.clear();
396 break;
397 }
398
399 assert(TypeArgInfo && "No type source info?");
400 ActualTypeArgInfos.push_back(TypeArgInfo);
401 }
402
403 // Build the object type.
405 T, BaseTypeInfo->getTypeLoc().getSourceRange().getBegin(),
406 TypeArgsLAngleLoc, ActualTypeArgInfos, TypeArgsRAngleLoc,
407 ProtocolLAngleLoc,
408 llvm::ArrayRef((ObjCProtocolDecl *const *)Protocols.data(),
409 Protocols.size()),
410 ProtocolLocs, ProtocolRAngleLoc,
411 /*FailOnError=*/false,
412 /*Rebuilding=*/false);
413
414 if (Result == T)
415 return BaseType;
416
417 // Create source information for this type.
418 TypeSourceInfo *ResultTInfo = Context.CreateTypeSourceInfo(Result);
419 TypeLoc ResultTL = ResultTInfo->getTypeLoc();
420
421 // For id<Proto1, Proto2> or Class<Proto1, Proto2>, we'll have an
422 // object pointer type. Fill in source information for it.
423 if (auto ObjCObjectPointerTL = ResultTL.getAs<ObjCObjectPointerTypeLoc>()) {
424 // The '*' is implicit.
425 ObjCObjectPointerTL.setStarLoc(SourceLocation());
426 ResultTL = ObjCObjectPointerTL.getPointeeLoc();
427 }
428
429 if (auto OTPTL = ResultTL.getAs<ObjCTypeParamTypeLoc>()) {
430 // Protocol qualifier information.
431 if (OTPTL.getNumProtocols() > 0) {
432 assert(OTPTL.getNumProtocols() == Protocols.size());
433 OTPTL.setProtocolLAngleLoc(ProtocolLAngleLoc);
434 OTPTL.setProtocolRAngleLoc(ProtocolRAngleLoc);
435 for (unsigned i = 0, n = Protocols.size(); i != n; ++i)
436 OTPTL.setProtocolLoc(i, ProtocolLocs[i]);
437 }
438
439 // We're done. Return the completed type to the parser.
440 return SemaRef.CreateParsedType(Result, ResultTInfo);
441 }
442
443 auto ObjCObjectTL = ResultTL.castAs<ObjCObjectTypeLoc>();
444
445 // Type argument information.
446 if (ObjCObjectTL.getNumTypeArgs() > 0) {
447 assert(ObjCObjectTL.getNumTypeArgs() == ActualTypeArgInfos.size());
448 ObjCObjectTL.setTypeArgsLAngleLoc(TypeArgsLAngleLoc);
449 ObjCObjectTL.setTypeArgsRAngleLoc(TypeArgsRAngleLoc);
450 for (unsigned i = 0, n = ActualTypeArgInfos.size(); i != n; ++i)
451 ObjCObjectTL.setTypeArgTInfo(i, ActualTypeArgInfos[i]);
452 } else {
453 ObjCObjectTL.setTypeArgsLAngleLoc(SourceLocation());
454 ObjCObjectTL.setTypeArgsRAngleLoc(SourceLocation());
455 }
456
457 // Protocol qualifier information.
458 if (ObjCObjectTL.getNumProtocols() > 0) {
459 assert(ObjCObjectTL.getNumProtocols() == Protocols.size());
460 ObjCObjectTL.setProtocolLAngleLoc(ProtocolLAngleLoc);
461 ObjCObjectTL.setProtocolRAngleLoc(ProtocolRAngleLoc);
462 for (unsigned i = 0, n = Protocols.size(); i != n; ++i)
463 ObjCObjectTL.setProtocolLoc(i, ProtocolLocs[i]);
464 } else {
465 ObjCObjectTL.setProtocolLAngleLoc(SourceLocation());
466 ObjCObjectTL.setProtocolRAngleLoc(SourceLocation());
467 }
468
469 // Base type.
470 ObjCObjectTL.setHasBaseTypeAsWritten(true);
471 if (ObjCObjectTL.getType() == T)
472 ObjCObjectTL.getBaseLoc().initializeFullCopy(BaseTypeInfo->getTypeLoc());
473 else
474 ObjCObjectTL.getBaseLoc().initialize(Context, Loc);
475
476 // We're done. Return the completed type to the parser.
477 return SemaRef.CreateParsedType(Result, ResultTInfo);
478}
479
481 const ObjCTypeParamDecl *Decl, SourceLocation ProtocolLAngleLoc,
483 ArrayRef<SourceLocation> ProtocolLocs, SourceLocation ProtocolRAngleLoc,
484 bool FailOnError) {
485 ASTContext &Context = getASTContext();
486 QualType Result = QualType(Decl->getTypeForDecl(), 0);
487 if (!Protocols.empty()) {
488 bool HasError;
489 Result = Context.applyObjCProtocolQualifiers(Result, Protocols, HasError);
490 if (HasError) {
491 Diag(SourceLocation(), diag::err_invalid_protocol_qualifiers)
492 << SourceRange(ProtocolLAngleLoc, ProtocolRAngleLoc);
493 if (FailOnError)
494 Result = QualType();
495 }
496 if (FailOnError && Result.isNull())
497 return QualType();
498 }
499
500 return Result;
501}
502
503/// Apply Objective-C type arguments to the given type.
506 SourceRange typeArgsRange, bool failOnError,
507 bool rebuilding) {
508 // We can only apply type arguments to an Objective-C class type.
509 const auto *objcObjectType = type->getAs<ObjCObjectType>();
510 if (!objcObjectType || !objcObjectType->getInterface()) {
511 S.Diag(loc, diag::err_objc_type_args_non_class) << type << typeArgsRange;
512
513 if (failOnError)
514 return QualType();
515 return type;
516 }
517
518 // The class type must be parameterized.
519 ObjCInterfaceDecl *objcClass = objcObjectType->getInterface();
520 ObjCTypeParamList *typeParams = objcClass->getTypeParamList();
521 if (!typeParams) {
522 S.Diag(loc, diag::err_objc_type_args_non_parameterized_class)
523 << objcClass->getDeclName() << FixItHint::CreateRemoval(typeArgsRange);
524
525 if (failOnError)
526 return QualType();
527
528 return type;
529 }
530
531 // The type must not already be specialized.
532 if (objcObjectType->isSpecialized()) {
533 S.Diag(loc, diag::err_objc_type_args_specialized_class)
534 << type << FixItHint::CreateRemoval(typeArgsRange);
535
536 if (failOnError)
537 return QualType();
538
539 return type;
540 }
541
542 // Check the type arguments.
543 SmallVector<QualType, 4> finalTypeArgs;
544 unsigned numTypeParams = typeParams->size();
545 bool anyPackExpansions = false;
546 for (unsigned i = 0, n = typeArgs.size(); i != n; ++i) {
547 TypeSourceInfo *typeArgInfo = typeArgs[i];
548 QualType typeArg = typeArgInfo->getType();
549
550 // Type arguments cannot have explicit qualifiers or nullability.
551 // We ignore indirect sources of these, e.g. behind typedefs or
552 // template arguments.
553 if (TypeLoc qual = typeArgInfo->getTypeLoc().findExplicitQualifierLoc()) {
554 bool diagnosed = false;
555 SourceRange rangeToRemove;
556 if (auto attr = qual.getAs<AttributedTypeLoc>()) {
557 rangeToRemove = attr.getLocalSourceRange();
558 if (attr.getTypePtr()->getImmediateNullability()) {
559 typeArg = attr.getTypePtr()->getModifiedType();
560 S.Diag(attr.getBeginLoc(),
561 diag::err_objc_type_arg_explicit_nullability)
562 << typeArg << FixItHint::CreateRemoval(rangeToRemove);
563 diagnosed = true;
564 }
565 }
566
567 // When rebuilding, qualifiers might have gotten here through a
568 // final substitution.
569 if (!rebuilding && !diagnosed) {
570 S.Diag(qual.getBeginLoc(), diag::err_objc_type_arg_qualified)
571 << typeArg << typeArg.getQualifiers().getAsString()
572 << FixItHint::CreateRemoval(rangeToRemove);
573 }
574 }
575
576 // Remove qualifiers even if they're non-local.
577 typeArg = typeArg.getUnqualifiedType();
578
579 finalTypeArgs.push_back(typeArg);
580
581 if (typeArg->getAs<PackExpansionType>())
582 anyPackExpansions = true;
583
584 // Find the corresponding type parameter, if there is one.
585 ObjCTypeParamDecl *typeParam = nullptr;
586 if (!anyPackExpansions) {
587 if (i < numTypeParams) {
588 typeParam = typeParams->begin()[i];
589 } else {
590 // Too many arguments.
591 S.Diag(loc, diag::err_objc_type_args_wrong_arity)
592 << false << objcClass->getDeclName() << (unsigned)typeArgs.size()
593 << numTypeParams;
594 S.Diag(objcClass->getLocation(), diag::note_previous_decl) << objcClass;
595
596 if (failOnError)
597 return QualType();
598
599 return type;
600 }
601 }
602
603 // Objective-C object pointer types must be substitutable for the bounds.
604 if (const auto *typeArgObjC = typeArg->getAs<ObjCObjectPointerType>()) {
605 // If we don't have a type parameter to match against, assume
606 // everything is fine. There was a prior pack expansion that
607 // means we won't be able to match anything.
608 if (!typeParam) {
609 assert(anyPackExpansions && "Too many arguments?");
610 continue;
611 }
612
613 // Retrieve the bound.
614 QualType bound = typeParam->getUnderlyingType();
615 const auto *boundObjC = bound->castAs<ObjCObjectPointerType>();
616
617 // Determine whether the type argument is substitutable for the bound.
618 if (typeArgObjC->isObjCIdType()) {
619 // When the type argument is 'id', the only acceptable type
620 // parameter bound is 'id'.
621 if (boundObjC->isObjCIdType())
622 continue;
623 } else if (S.Context.canAssignObjCInterfaces(boundObjC, typeArgObjC)) {
624 // Otherwise, we follow the assignability rules.
625 continue;
626 }
627
628 // Diagnose the mismatch.
629 S.Diag(typeArgInfo->getTypeLoc().getBeginLoc(),
630 diag::err_objc_type_arg_does_not_match_bound)
631 << typeArg << bound << typeParam->getDeclName();
632 S.Diag(typeParam->getLocation(), diag::note_objc_type_param_here)
633 << typeParam->getDeclName();
634
635 if (failOnError)
636 return QualType();
637
638 return type;
639 }
640
641 // Block pointer types are permitted for unqualified 'id' bounds.
642 if (typeArg->isBlockPointerType()) {
643 // If we don't have a type parameter to match against, assume
644 // everything is fine. There was a prior pack expansion that
645 // means we won't be able to match anything.
646 if (!typeParam) {
647 assert(anyPackExpansions && "Too many arguments?");
648 continue;
649 }
650
651 // Retrieve the bound.
652 QualType bound = typeParam->getUnderlyingType();
654 continue;
655
656 // Diagnose the mismatch.
657 S.Diag(typeArgInfo->getTypeLoc().getBeginLoc(),
658 diag::err_objc_type_arg_does_not_match_bound)
659 << typeArg << bound << typeParam->getDeclName();
660 S.Diag(typeParam->getLocation(), diag::note_objc_type_param_here)
661 << typeParam->getDeclName();
662
663 if (failOnError)
664 return QualType();
665
666 return type;
667 }
668
669 // Types that have __attribute__((NSObject)) are permitted.
670 if (typeArg->isObjCNSObjectType()) {
671 continue;
672 }
673
674 // Dependent types will be checked at instantiation time.
675 if (typeArg->isDependentType()) {
676 continue;
677 }
678
679 // Diagnose non-id-compatible type arguments.
680 S.Diag(typeArgInfo->getTypeLoc().getBeginLoc(),
681 diag::err_objc_type_arg_not_id_compatible)
682 << typeArg << typeArgInfo->getTypeLoc().getSourceRange();
683
684 if (failOnError)
685 return QualType();
686
687 return type;
688 }
689
690 // Make sure we didn't have the wrong number of arguments.
691 if (!anyPackExpansions && finalTypeArgs.size() != numTypeParams) {
692 S.Diag(loc, diag::err_objc_type_args_wrong_arity)
693 << (typeArgs.size() < typeParams->size()) << objcClass->getDeclName()
694 << (unsigned)finalTypeArgs.size() << numTypeParams;
695 S.Diag(objcClass->getLocation(), diag::note_previous_decl) << objcClass;
696
697 if (failOnError)
698 return QualType();
699
700 return type;
701 }
702
703 // Success. Form the specialized type.
704 return S.Context.getObjCObjectType(type, finalTypeArgs, {}, false);
705}
706
708 QualType BaseType, SourceLocation Loc, SourceLocation TypeArgsLAngleLoc,
709 ArrayRef<TypeSourceInfo *> TypeArgs, SourceLocation TypeArgsRAngleLoc,
710 SourceLocation ProtocolLAngleLoc, ArrayRef<ObjCProtocolDecl *> Protocols,
711 ArrayRef<SourceLocation> ProtocolLocs, SourceLocation ProtocolRAngleLoc,
712 bool FailOnError, bool Rebuilding) {
713 ASTContext &Context = getASTContext();
714 QualType Result = BaseType;
715 if (!TypeArgs.empty()) {
716 Result =
718 SourceRange(TypeArgsLAngleLoc, TypeArgsRAngleLoc),
719 FailOnError, Rebuilding);
720 if (FailOnError && Result.isNull())
721 return QualType();
722 }
723
724 if (!Protocols.empty()) {
725 bool HasError;
726 Result = Context.applyObjCProtocolQualifiers(Result, Protocols, HasError);
727 if (HasError) {
728 Diag(Loc, diag::err_invalid_protocol_qualifiers)
729 << SourceRange(ProtocolLAngleLoc, ProtocolRAngleLoc);
730 if (FailOnError)
731 Result = QualType();
732 }
733 if (FailOnError && Result.isNull())
734 return QualType();
735 }
736
737 return Result;
738}
739
741 ASTContext &Context = getASTContext();
742 QualType T = Context.getObjCInstanceType();
743 TypeSourceInfo *TInfo = Context.getTrivialTypeSourceInfo(T, Loc);
744 return SemaRef.CreateParsedType(T, TInfo);
745}
746
747//===--- CHECK: Objective-C retain cycles ----------------------------------//
748
749namespace {
750
751struct RetainCycleOwner {
752 VarDecl *Variable = nullptr;
753 SourceRange Range;
754 SourceLocation Loc;
755 bool Indirect = false;
756
757 RetainCycleOwner() = default;
758
759 void setLocsFrom(Expr *e) {
760 Loc = e->getExprLoc();
761 Range = e->getSourceRange();
762 }
763};
764
765} // namespace
766
767/// Consider whether capturing the given variable can possibly lead to
768/// a retain cycle.
769static bool considerVariable(VarDecl *var, Expr *ref, RetainCycleOwner &owner) {
770 // In ARC, it's captured strongly iff the variable has __strong
771 // lifetime. In MRR, it's captured strongly if the variable is
772 // __block and has an appropriate type.
773 if (var->getType().getObjCLifetime() != Qualifiers::OCL_Strong)
774 return false;
775
776 owner.Variable = var;
777 if (ref)
778 owner.setLocsFrom(ref);
779 return true;
780}
781
782static bool findRetainCycleOwner(Sema &S, Expr *e, RetainCycleOwner &owner) {
783 while (true) {
784 e = e->IgnoreParens();
785 if (CastExpr *cast = dyn_cast<CastExpr>(e)) {
786 switch (cast->getCastKind()) {
787 case CK_BitCast:
788 case CK_LValueBitCast:
789 case CK_LValueToRValue:
790 case CK_ARCReclaimReturnedObject:
791 e = cast->getSubExpr();
792 continue;
793
794 default:
795 return false;
796 }
797 }
798
799 if (ObjCIvarRefExpr *ref = dyn_cast<ObjCIvarRefExpr>(e)) {
800 ObjCIvarDecl *ivar = ref->getDecl();
802 return false;
803
804 // Try to find a retain cycle in the base.
805 if (!findRetainCycleOwner(S, ref->getBase(), owner))
806 return false;
807
808 if (ref->isFreeIvar())
809 owner.setLocsFrom(ref);
810 owner.Indirect = true;
811 return true;
812 }
813
814 if (DeclRefExpr *ref = dyn_cast<DeclRefExpr>(e)) {
815 VarDecl *var = dyn_cast<VarDecl>(ref->getDecl());
816 if (!var)
817 return false;
818 return considerVariable(var, ref, owner);
819 }
820
821 if (MemberExpr *member = dyn_cast<MemberExpr>(e)) {
822 if (member->isArrow())
823 return false;
824
825 // Don't count this as an indirect ownership.
826 e = member->getBase();
827 continue;
828 }
829
830 if (PseudoObjectExpr *pseudo = dyn_cast<PseudoObjectExpr>(e)) {
831 // Only pay attention to pseudo-objects on property references.
832 ObjCPropertyRefExpr *pre = dyn_cast<ObjCPropertyRefExpr>(
833 pseudo->getSyntacticForm()->IgnoreParens());
834 if (!pre)
835 return false;
836 if (pre->isImplicitProperty())
837 return false;
838 ObjCPropertyDecl *property = pre->getExplicitProperty();
839 if (!property->isRetaining() &&
840 !(property->getPropertyIvarDecl() &&
841 property->getPropertyIvarDecl()->getType().getObjCLifetime() ==
843 return false;
844
845 owner.Indirect = true;
846 if (pre->isSuperReceiver()) {
847 owner.Variable = S.getCurMethodDecl()->getSelfDecl();
848 if (!owner.Variable)
849 return false;
850 owner.Loc = pre->getLocation();
851 owner.Range = pre->getSourceRange();
852 return true;
853 }
854 e = const_cast<Expr *>(
855 cast<OpaqueValueExpr>(pre->getBase())->getSourceExpr());
856 continue;
857 }
858
859 // Array ivars?
860
861 return false;
862 }
863}
864
865namespace {
866
867struct FindCaptureVisitor : EvaluatedExprVisitor<FindCaptureVisitor> {
868 VarDecl *Variable;
869 Expr *Capturer = nullptr;
870 bool VarWillBeReased = false;
871
872 FindCaptureVisitor(ASTContext &Context, VarDecl *variable)
873 : EvaluatedExprVisitor<FindCaptureVisitor>(Context), Variable(variable) {}
874
875 void VisitDeclRefExpr(DeclRefExpr *ref) {
876 if (ref->getDecl() == Variable && !Capturer)
877 Capturer = ref;
878 }
879
880 void VisitObjCIvarRefExpr(ObjCIvarRefExpr *ref) {
881 if (Capturer)
882 return;
883 Visit(ref->getBase());
884 if (Capturer && ref->isFreeIvar())
885 Capturer = ref;
886 }
887
888 void VisitBlockExpr(BlockExpr *block) {
889 // Look inside nested blocks
890 if (block->getBlockDecl()->capturesVariable(Variable))
891 Visit(block->getBlockDecl()->getBody());
892 }
893
894 void VisitOpaqueValueExpr(OpaqueValueExpr *OVE) {
895 if (Capturer)
896 return;
897 if (OVE->getSourceExpr())
898 Visit(OVE->getSourceExpr());
899 }
900
901 void VisitBinaryOperator(BinaryOperator *BinOp) {
902 if (!Variable || VarWillBeReased || BinOp->getOpcode() != BO_Assign)
903 return;
904 Expr *LHS = BinOp->getLHS();
905 if (const DeclRefExpr *DRE = dyn_cast_or_null<DeclRefExpr>(LHS)) {
906 if (DRE->getDecl() != Variable)
907 return;
908 if (Expr *RHS = BinOp->getRHS()) {
909 RHS = RHS->IgnoreParenCasts();
910 std::optional<llvm::APSInt> Value;
912 (RHS && (Value = RHS->getIntegerConstantExpr(Context)) &&
913 *Value == 0);
914 }
915 }
916 }
917};
918
919} // namespace
920
921/// Check whether the given argument is a block which captures a
922/// variable.
923static Expr *findCapturingExpr(Sema &S, Expr *e, RetainCycleOwner &owner) {
924 assert(owner.Variable && owner.Loc.isValid());
925
926 e = e->IgnoreParenCasts();
927
928 // Look through [^{...} copy] and Block_copy(^{...}).
929 if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(e)) {
930 Selector Cmd = ME->getSelector();
931 if (Cmd.isUnarySelector() && Cmd.getNameForSlot(0) == "copy") {
932 e = ME->getInstanceReceiver();
933 if (!e)
934 return nullptr;
935 e = e->IgnoreParenCasts();
936 }
937 } else if (CallExpr *CE = dyn_cast<CallExpr>(e)) {
938 if (CE->getNumArgs() == 1) {
939 FunctionDecl *Fn = dyn_cast_or_null<FunctionDecl>(CE->getCalleeDecl());
940 if (Fn) {
941 const IdentifierInfo *FnI = Fn->getIdentifier();
942 if (FnI && FnI->isStr("_Block_copy")) {
943 e = CE->getArg(0)->IgnoreParenCasts();
944 }
945 }
946 }
947 }
948
949 BlockExpr *block = dyn_cast<BlockExpr>(e);
950 if (!block || !block->getBlockDecl()->capturesVariable(owner.Variable))
951 return nullptr;
952
953 FindCaptureVisitor visitor(S.Context, owner.Variable);
954 visitor.Visit(block->getBlockDecl()->getBody());
955 return visitor.VarWillBeReased ? nullptr : visitor.Capturer;
956}
957
958static void diagnoseRetainCycle(Sema &S, Expr *capturer,
959 RetainCycleOwner &owner) {
960 assert(capturer);
961 assert(owner.Variable && owner.Loc.isValid());
962
963 S.Diag(capturer->getExprLoc(), diag::warn_arc_retain_cycle)
964 << owner.Variable << capturer->getSourceRange();
965 S.Diag(owner.Loc, diag::note_arc_retain_cycle_owner)
966 << owner.Indirect << owner.Range;
967}
968
969/// Check for a keyword selector that starts with the word 'add' or
970/// 'set'.
972 if (sel.isUnarySelector())
973 return false;
974
975 StringRef str = sel.getNameForSlot(0);
976 str = str.ltrim('_');
977 if (str.starts_with("set"))
978 str = str.substr(3);
979 else if (str.starts_with("add")) {
980 // Specially allow 'addOperationWithBlock:'.
981 if (sel.getNumArgs() == 1 && str.starts_with("addOperationWithBlock"))
982 return false;
983 str = str.substr(3);
984 } else
985 return false;
986
987 if (str.empty())
988 return true;
989 return !isLowercase(str.front());
990}
991
992static std::optional<int>
994 bool IsMutableArray = S.NSAPIObj->isSubclassOfNSClass(
995 Message->getReceiverInterface(), NSAPI::ClassId_NSMutableArray);
996 if (!IsMutableArray) {
997 return std::nullopt;
998 }
999
1000 Selector Sel = Message->getSelector();
1001
1002 std::optional<NSAPI::NSArrayMethodKind> MKOpt =
1003 S.NSAPIObj->getNSArrayMethodKind(Sel);
1004 if (!MKOpt) {
1005 return std::nullopt;
1006 }
1007
1008 NSAPI::NSArrayMethodKind MK = *MKOpt;
1009
1010 switch (MK) {
1014 return 0;
1016 return 1;
1017
1018 default:
1019 return std::nullopt;
1020 }
1021
1022 return std::nullopt;
1023}
1024
1025static std::optional<int>
1027 bool IsMutableDictionary = S.NSAPIObj->isSubclassOfNSClass(
1028 Message->getReceiverInterface(), NSAPI::ClassId_NSMutableDictionary);
1029 if (!IsMutableDictionary) {
1030 return std::nullopt;
1031 }
1032
1033 Selector Sel = Message->getSelector();
1034
1035 std::optional<NSAPI::NSDictionaryMethodKind> MKOpt =
1036 S.NSAPIObj->getNSDictionaryMethodKind(Sel);
1037 if (!MKOpt) {
1038 return std::nullopt;
1039 }
1040
1042
1043 switch (MK) {
1047 return 0;
1048
1049 default:
1050 return std::nullopt;
1051 }
1052
1053 return std::nullopt;
1054}
1055
1056static std::optional<int> GetNSSetArgumentIndex(SemaObjC &S,
1057 ObjCMessageExpr *Message) {
1058 bool IsMutableSet = S.NSAPIObj->isSubclassOfNSClass(
1059 Message->getReceiverInterface(), NSAPI::ClassId_NSMutableSet);
1060
1061 bool IsMutableOrderedSet = S.NSAPIObj->isSubclassOfNSClass(
1062 Message->getReceiverInterface(), NSAPI::ClassId_NSMutableOrderedSet);
1063 if (!IsMutableSet && !IsMutableOrderedSet) {
1064 return std::nullopt;
1065 }
1066
1067 Selector Sel = Message->getSelector();
1068
1069 std::optional<NSAPI::NSSetMethodKind> MKOpt =
1070 S.NSAPIObj->getNSSetMethodKind(Sel);
1071 if (!MKOpt) {
1072 return std::nullopt;
1073 }
1074
1075 NSAPI::NSSetMethodKind MK = *MKOpt;
1076
1077 switch (MK) {
1082 return 0;
1084 return 1;
1085 }
1086
1087 return std::nullopt;
1088}
1089
1091 if (!Message->isInstanceMessage()) {
1092 return;
1093 }
1094
1095 std::optional<int> ArgOpt;
1096
1097 if (!(ArgOpt = GetNSMutableArrayArgumentIndex(*this, Message)) &&
1098 !(ArgOpt = GetNSMutableDictionaryArgumentIndex(*this, Message)) &&
1099 !(ArgOpt = GetNSSetArgumentIndex(*this, Message))) {
1100 return;
1101 }
1102
1103 int ArgIndex = *ArgOpt;
1104
1105 Expr *Arg = Message->getArg(ArgIndex)->IgnoreImpCasts();
1106 if (OpaqueValueExpr *OE = dyn_cast<OpaqueValueExpr>(Arg)) {
1107 Arg = OE->getSourceExpr()->IgnoreImpCasts();
1108 }
1109
1110 if (Message->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
1111 if (DeclRefExpr *ArgRE = dyn_cast<DeclRefExpr>(Arg)) {
1112 if (ArgRE->isObjCSelfExpr()) {
1113 Diag(Message->getSourceRange().getBegin(),
1114 diag::warn_objc_circular_container)
1115 << ArgRE->getDecl() << StringRef("'super'");
1116 }
1117 }
1118 } else {
1119 Expr *Receiver = Message->getInstanceReceiver()->IgnoreImpCasts();
1120
1121 if (OpaqueValueExpr *OE = dyn_cast<OpaqueValueExpr>(Receiver)) {
1122 Receiver = OE->getSourceExpr()->IgnoreImpCasts();
1123 }
1124
1125 if (DeclRefExpr *ReceiverRE = dyn_cast<DeclRefExpr>(Receiver)) {
1126 if (DeclRefExpr *ArgRE = dyn_cast<DeclRefExpr>(Arg)) {
1127 if (ReceiverRE->getDecl() == ArgRE->getDecl()) {
1128 ValueDecl *Decl = ReceiverRE->getDecl();
1129 Diag(Message->getSourceRange().getBegin(),
1130 diag::warn_objc_circular_container)
1131 << Decl << Decl;
1132 if (!ArgRE->isObjCSelfExpr()) {
1134 diag::note_objc_circular_container_declared_here)
1135 << Decl;
1136 }
1137 }
1138 }
1139 } else if (ObjCIvarRefExpr *IvarRE = dyn_cast<ObjCIvarRefExpr>(Receiver)) {
1140 if (ObjCIvarRefExpr *IvarArgRE = dyn_cast<ObjCIvarRefExpr>(Arg)) {
1141 if (IvarRE->getDecl() == IvarArgRE->getDecl()) {
1142 ObjCIvarDecl *Decl = IvarRE->getDecl();
1143 Diag(Message->getSourceRange().getBegin(),
1144 diag::warn_objc_circular_container)
1145 << Decl << Decl;
1147 diag::note_objc_circular_container_declared_here)
1148 << Decl;
1149 }
1150 }
1151 }
1152 }
1153}
1154
1155/// Check a message send to see if it's likely to cause a retain cycle.
1157 // Only check instance methods whose selector looks like a setter.
1158 if (!msg->isInstanceMessage() || !isSetterLikeSelector(msg->getSelector()))
1159 return;
1160
1161 // Try to find a variable that the receiver is strongly owned by.
1162 RetainCycleOwner owner;
1165 return;
1166 } else {
1168 owner.Variable = SemaRef.getCurMethodDecl()->getSelfDecl();
1169 owner.Loc = msg->getSuperLoc();
1170 owner.Range = msg->getSuperLoc();
1171 }
1172
1173 // Check whether the receiver is captured by any of the arguments.
1174 const ObjCMethodDecl *MD = msg->getMethodDecl();
1175 for (unsigned i = 0, e = msg->getNumArgs(); i != e; ++i) {
1176 if (Expr *capturer = findCapturingExpr(SemaRef, msg->getArg(i), owner)) {
1177 // noescape blocks should not be retained by the method.
1178 if (MD && MD->parameters()[i]->hasAttr<NoEscapeAttr>())
1179 continue;
1180 return diagnoseRetainCycle(SemaRef, capturer, owner);
1181 }
1182 }
1183}
1184
1185/// Check a property assign to see if it's likely to cause a retain cycle.
1186void SemaObjC::checkRetainCycles(Expr *receiver, Expr *argument) {
1187 RetainCycleOwner owner;
1188 if (!findRetainCycleOwner(SemaRef, receiver, owner))
1189 return;
1190
1191 if (Expr *capturer = findCapturingExpr(SemaRef, argument, owner))
1192 diagnoseRetainCycle(SemaRef, capturer, owner);
1193}
1194
1196 RetainCycleOwner Owner;
1197 if (!considerVariable(Var, /*DeclRefExpr=*/nullptr, Owner))
1198 return;
1199
1200 // Because we don't have an expression for the variable, we have to set the
1201 // location explicitly here.
1202 Owner.Loc = Var->getLocation();
1203 Owner.Range = Var->getSourceRange();
1204
1205 if (Expr *Capturer = findCapturingExpr(SemaRef, Init, Owner))
1207}
1208
1209/// CheckObjCString - Checks that the argument to the builtin
1210/// CFString constructor is correct
1211/// Note: It might also make sense to do the UTF-16 conversion here (would
1212/// simplify the backend).
1214 Arg = Arg->IgnoreParenCasts();
1215 StringLiteral *Literal = dyn_cast<StringLiteral>(Arg);
1216
1217 if (!Literal || !Literal->isOrdinary()) {
1218 Diag(Arg->getBeginLoc(), diag::err_cfstring_literal_not_string_constant)
1219 << Arg->getSourceRange();
1220 return true;
1221 }
1222
1223 if (Literal->containsNonAsciiOrNull()) {
1224 StringRef String = Literal->getString();
1225 unsigned NumBytes = String.size();
1226 SmallVector<llvm::UTF16, 128> ToBuf(NumBytes);
1227 const llvm::UTF8 *FromPtr = (const llvm::UTF8 *)String.data();
1228 llvm::UTF16 *ToPtr = &ToBuf[0];
1229
1230 llvm::ConversionResult Result =
1231 llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumBytes, &ToPtr,
1232 ToPtr + NumBytes, llvm::strictConversion);
1233 // Check for conversion failure.
1234 if (Result != llvm::conversionOK)
1235 Diag(Arg->getBeginLoc(), diag::warn_cfstring_truncated)
1236 << Arg->getSourceRange();
1237 }
1238 return false;
1239}
1240
1243 VariadicCallType CallType = Method->isVariadic()
1246
1247 SemaRef.checkCall(Method, nullptr, /*ThisArg=*/nullptr, Args,
1248 /*IsMemberFunction=*/false, lbrac, Method->getSourceRange(),
1249 CallType);
1250
1252
1253 return false;
1254}
1255
1258 // A category implicitly has the attribute of the interface.
1259 if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(DC))
1260 DC = CatD->getClassInterface();
1261 return DC;
1262}
1263
1264/// Retrieve the identifier "NSError".
1266 if (!Ident_NSError)
1267 Ident_NSError = SemaRef.PP.getIdentifierInfo("NSError");
1268
1269 return Ident_NSError;
1270}
1271
1273 assert(
1274 IDecl->getLexicalParent() == SemaRef.CurContext &&
1275 "The next DeclContext should be lexically contained in the current one.");
1276 SemaRef.CurContext = IDecl;
1277}
1278
1280 // Exit this scope of this interface definition.
1282}
1283
1285 ObjCContainerDecl *ObjCCtx) {
1286 assert(ObjCCtx == SemaRef.CurContext && "Mismatch of container contexts");
1289}
1290
1294}
1295
1296/// Find the protocol with the given name, if any.
1298 SourceLocation IdLoc,
1299 RedeclarationKind Redecl) {
1302 return cast_or_null<ObjCProtocolDecl>(D);
1303}
1304
1305/// Determine whether this is an Objective-C writeback conversion,
1306/// used for parameter passing when performing automatic reference counting.
1307///
1308/// \param FromType The type we're converting form.
1309///
1310/// \param ToType The type we're converting to.
1311///
1312/// \param ConvertedType The type that will be produced after applying
1313/// this conversion.
1315 QualType &ConvertedType) {
1316 ASTContext &Context = getASTContext();
1317 if (!getLangOpts().ObjCAutoRefCount ||
1318 Context.hasSameUnqualifiedType(FromType, ToType))
1319 return false;
1320
1321 // Parameter must be a pointer to __autoreleasing (with no other qualifiers).
1322 QualType ToPointee;
1323 if (const PointerType *ToPointer = ToType->getAs<PointerType>())
1324 ToPointee = ToPointer->getPointeeType();
1325 else
1326 return false;
1327
1328 Qualifiers ToQuals = ToPointee.getQualifiers();
1329 if (!ToPointee->isObjCLifetimeType() ||
1331 !ToQuals.withoutObjCLifetime().empty())
1332 return false;
1333
1334 // Argument must be a pointer to __strong to __weak.
1335 QualType FromPointee;
1336 if (const PointerType *FromPointer = FromType->getAs<PointerType>())
1337 FromPointee = FromPointer->getPointeeType();
1338 else
1339 return false;
1340
1341 Qualifiers FromQuals = FromPointee.getQualifiers();
1342 if (!FromPointee->isObjCLifetimeType() ||
1343 (FromQuals.getObjCLifetime() != Qualifiers::OCL_Strong &&
1344 FromQuals.getObjCLifetime() != Qualifiers::OCL_Weak))
1345 return false;
1346
1347 // Make sure that we have compatible qualifiers.
1349 if (!ToQuals.compatiblyIncludes(FromQuals, getASTContext()))
1350 return false;
1351
1352 // Remove qualifiers from the pointee type we're converting from; they
1353 // aren't used in the compatibility check belong, and we'll be adding back
1354 // qualifiers (with __autoreleasing) if the compatibility check succeeds.
1355 FromPointee = FromPointee.getUnqualifiedType();
1356
1357 // The unqualified form of the pointee types must be compatible.
1358 ToPointee = ToPointee.getUnqualifiedType();
1359 bool IncompatibleObjC;
1360 if (Context.typesAreCompatible(FromPointee, ToPointee))
1361 FromPointee = ToPointee;
1362 else if (!SemaRef.isObjCPointerConversion(FromPointee, ToPointee, FromPointee,
1363 IncompatibleObjC))
1364 return false;
1365
1366 /// Construct the type we're converting to, which is a pointer to
1367 /// __autoreleasing pointee.
1368 FromPointee = Context.getQualifiedType(FromPointee, FromQuals);
1369 ConvertedType = Context.getPointerType(FromPointee);
1370 return true;
1371}
1372
1373/// CheckSubscriptingKind - This routine decide what type
1374/// of indexing represented by "FromE" is being done.
1376 // If the expression already has integral or enumeration type, we're golden.
1377 QualType T = FromE->getType();
1379 return SemaObjC::OS_Array;
1380
1381 // If we don't have a class type in C++, there's no way we can get an
1382 // expression of integral or enumeration type.
1383 const RecordType *RecordTy = T->getAsCanonical<RecordType>();
1384 if (!RecordTy && (T->isObjCObjectPointerType() || T->isVoidPointerType()))
1385 // All other scalar cases are assumed to be dictionary indexing which
1386 // caller handles, with diagnostics if needed.
1388 if (!getLangOpts().CPlusPlus || !RecordTy || RecordTy->isIncompleteType()) {
1389 // No indexing can be done. Issue diagnostics and quit.
1390 const Expr *IndexExpr = FromE->IgnoreParenImpCasts();
1391 if (isa<StringLiteral>(IndexExpr))
1392 Diag(FromE->getExprLoc(), diag::err_objc_subscript_pointer)
1393 << T << FixItHint::CreateInsertion(FromE->getExprLoc(), "@");
1394 else
1395 Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion) << T;
1396 return SemaObjC::OS_Error;
1397 }
1398
1399 // We must have a complete class type.
1401 diag::err_objc_index_incomplete_class_type,
1402 FromE))
1403 return SemaObjC::OS_Error;
1404
1405 // Look for a conversion to an integral, enumeration type, or
1406 // objective-C pointer type.
1407 int NoIntegrals = 0, NoObjCIdPointers = 0;
1409
1410 for (NamedDecl *D : cast<CXXRecordDecl>(RecordTy->getOriginalDecl())
1411 ->getDefinitionOrSelf()
1412 ->getVisibleConversionFunctions()) {
1413 if (CXXConversionDecl *Conversion =
1414 dyn_cast<CXXConversionDecl>(D->getUnderlyingDecl())) {
1415 QualType CT = Conversion->getConversionType().getNonReferenceType();
1416 if (CT->isIntegralOrEnumerationType()) {
1417 ++NoIntegrals;
1418 ConversionDecls.push_back(Conversion);
1419 } else if (CT->isObjCIdType() || CT->isBlockPointerType()) {
1420 ++NoObjCIdPointers;
1421 ConversionDecls.push_back(Conversion);
1422 }
1423 }
1424 }
1425 if (NoIntegrals == 1 && NoObjCIdPointers == 0)
1426 return SemaObjC::OS_Array;
1427 if (NoIntegrals == 0 && NoObjCIdPointers == 1)
1429 if (NoIntegrals == 0 && NoObjCIdPointers == 0) {
1430 // No conversion function was found. Issue diagnostic and return.
1431 Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion)
1432 << FromE->getType();
1433 return SemaObjC::OS_Error;
1434 }
1435 Diag(FromE->getExprLoc(), diag::err_objc_multiple_subscript_type_conversion)
1436 << FromE->getType();
1437 for (unsigned int i = 0; i < ConversionDecls.size(); i++)
1438 Diag(ConversionDecls[i]->getLocation(),
1439 diag::note_conv_function_declared_at);
1440
1441 return SemaObjC::OS_Error;
1442}
1443
1445 ASTContext &Context = getASTContext();
1447 if (!IdLoc.getLoc().isValid())
1448 return;
1449
1450 // Don't add a redundant or conflicting attribute.
1451 if (D->hasAttr<CFAuditedTransferAttr>() ||
1452 D->hasAttr<CFUnknownTransferAttr>())
1453 return;
1454
1455 AttributeCommonInfo Info(IdLoc.getIdentifierInfo(),
1456 SourceRange(IdLoc.getLoc()),
1458 D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Info));
1459}
1460
1462 // If we already know about CFError, test it directly.
1463 if (CFError)
1464 return CFError == RD;
1465
1466 // Check whether this is CFError, which we identify based on its bridge to
1467 // NSError. CFErrorRef used to be declared with "objc_bridge" but is now
1468 // declared with "objc_bridge_mutable", so look for either one of the two
1469 // attributes.
1470 if (RD->getTagKind() == TagTypeKind::Struct) {
1471 IdentifierInfo *bridgedType = nullptr;
1472 if (auto bridgeAttr = RD->getAttr<ObjCBridgeAttr>())
1473 bridgedType = bridgeAttr->getBridgedType();
1474 else if (auto bridgeAttr = RD->getAttr<ObjCBridgeMutableAttr>())
1475 bridgedType = bridgeAttr->getBridgedType();
1476
1477 if (bridgedType == getNSErrorIdent()) {
1478 CFError = RD;
1479 return true;
1480 }
1481 }
1482
1483 return false;
1484}
1485
1486bool SemaObjC::isNSStringType(QualType T, bool AllowNSAttributedString) {
1487 const auto *PT = T->getAs<ObjCObjectPointerType>();
1488 if (!PT)
1489 return false;
1490
1491 ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
1492 if (!Cls)
1493 return false;
1494
1495 IdentifierInfo *ClsName = Cls->getIdentifier();
1496
1497 if (AllowNSAttributedString &&
1498 ClsName == &getASTContext().Idents.get("NSAttributedString"))
1499 return true;
1500 // FIXME: Should we walk the chain of classes?
1501 return ClsName == &getASTContext().Idents.get("NSString") ||
1502 ClsName == &getASTContext().Idents.get("NSMutableString");
1503}
1504
1506 const auto *PT = T->getAs<PointerType>();
1507 if (!PT)
1508 return false;
1509
1510 const auto *RT = PT->getPointeeType()->getAsCanonical<RecordType>();
1511 if (!RT)
1512 return false;
1513
1514 const RecordDecl *RD = RT->getOriginalDecl();
1515 if (RD->getTagKind() != TagTypeKind::Struct)
1516 return false;
1517
1518 return RD->getIdentifier() == &getASTContext().Idents.get("__CFString");
1519}
1520
1521static bool checkIBOutletCommon(Sema &S, Decl *D, const ParsedAttr &AL) {
1522 // The IBOutlet/IBOutletCollection attributes only apply to instance
1523 // variables or properties of Objective-C classes. The outlet must also
1524 // have an object reference type.
1525 if (const auto *VD = dyn_cast<ObjCIvarDecl>(D)) {
1526 if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
1527 S.Diag(AL.getLoc(), diag::warn_iboutlet_object_type)
1528 << AL << VD->getType() << 0;
1529 return false;
1530 }
1531 } else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) {
1532 if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
1533 S.Diag(AL.getLoc(), diag::warn_iboutlet_object_type)
1534 << AL << PD->getType() << 1;
1535 return false;
1536 }
1537 } else {
1538 S.Diag(AL.getLoc(), diag::warn_attribute_iboutlet) << AL;
1539 return false;
1540 }
1541
1542 return true;
1543}
1544
1546 if (!checkIBOutletCommon(SemaRef, D, AL))
1547 return;
1548
1549 D->addAttr(::new (getASTContext()) IBOutletAttr(getASTContext(), AL));
1550}
1551
1553
1554 ASTContext &Context = getASTContext();
1555 // The iboutletcollection attribute can have zero or one arguments.
1556 if (AL.getNumArgs() > 1) {
1557 Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
1558 return;
1559 }
1560
1561 if (!checkIBOutletCommon(SemaRef, D, AL))
1562 return;
1563
1564 ParsedType PT;
1565
1566 if (AL.hasParsedType())
1567 PT = AL.getTypeArg();
1568 else {
1569 PT = SemaRef.getTypeName(
1570 Context.Idents.get("NSObject"), AL.getLoc(),
1571 SemaRef.getScopeForContext(D->getDeclContext()->getParent()));
1572 if (!PT) {
1573 Diag(AL.getLoc(), diag::err_iboutletcollection_type) << "NSObject";
1574 return;
1575 }
1576 }
1577
1578 TypeSourceInfo *QTLoc = nullptr;
1579 QualType QT = SemaRef.GetTypeFromParser(PT, &QTLoc);
1580 if (!QTLoc)
1581 QTLoc = Context.getTrivialTypeSourceInfo(QT, AL.getLoc());
1582
1583 // Diagnose use of non-object type in iboutletcollection attribute.
1584 // FIXME. Gnu attribute extension ignores use of builtin types in
1585 // attributes. So, __attribute__((iboutletcollection(char))) will be
1586 // treated as __attribute__((iboutletcollection())).
1587 if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {
1588 Diag(AL.getLoc(), QT->isBuiltinType()
1589 ? diag::err_iboutletcollection_builtintype
1590 : diag::err_iboutletcollection_type)
1591 << QT;
1592 return;
1593 }
1594
1595 D->addAttr(::new (Context) IBOutletCollectionAttr(Context, AL, QTLoc));
1596}
1597
1599 if (!cast<ObjCProtocolDecl>(D)->isThisDeclarationADefinition()) {
1600 Diag(AL.getLoc(), diag::err_objc_attr_protocol_requires_definition)
1601 << AL << AL.getRange();
1602 return;
1603 }
1604
1605 D->addAttr(::new (getASTContext())
1606 ObjCExplicitProtocolImplAttr(getASTContext(), AL));
1607}
1608
1610 // objc_direct cannot be set on methods declared in the context of a protocol
1611 if (isa<ObjCProtocolDecl>(D->getDeclContext())) {
1612 Diag(AL.getLoc(), diag::err_objc_direct_on_protocol) << false;
1613 return;
1614 }
1615
1617 handleSimpleAttribute<ObjCDirectAttr>(*this, D, AL);
1618 } else {
1619 Diag(AL.getLoc(), diag::warn_objc_direct_ignored) << AL;
1620 }
1621}
1622
1625 handleSimpleAttribute<ObjCDirectMembersAttr>(*this, D, AL);
1626 } else {
1627 Diag(AL.getLoc(), diag::warn_objc_direct_ignored) << AL;
1628 }
1629}
1630
1632 const auto *M = cast<ObjCMethodDecl>(D);
1633 if (!AL.isArgIdent(0)) {
1634 Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
1635 << AL << 1 << AANT_ArgumentIdentifier;
1636 return;
1637 }
1638
1639 IdentifierLoc *IL = AL.getArgAsIdent(0);
1640 ObjCMethodFamilyAttr::FamilyKind F;
1641 if (!ObjCMethodFamilyAttr::ConvertStrToFamilyKind(
1642 IL->getIdentifierInfo()->getName(), F)) {
1643 Diag(IL->getLoc(), diag::warn_attribute_type_not_supported)
1644 << AL << IL->getIdentifierInfo();
1645 return;
1646 }
1647
1648 if (F == ObjCMethodFamilyAttr::OMF_init &&
1649 !M->getReturnType()->isObjCObjectPointerType()) {
1650 Diag(M->getLocation(), diag::err_init_method_bad_return_type)
1651 << M->getReturnType();
1652 // Ignore the attribute.
1653 return;
1654 }
1655
1656 D->addAttr(new (getASTContext())
1657 ObjCMethodFamilyAttr(getASTContext(), AL, F));
1658}
1659
1661 if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) {
1662 QualType T = TD->getUnderlyingType();
1663 if (!T->isCARCBridgableType()) {
1664 Diag(TD->getLocation(), diag::err_nsobject_attribute);
1665 return;
1666 }
1667 } else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) {
1668 QualType T = PD->getType();
1669 if (!T->isCARCBridgableType()) {
1670 Diag(PD->getLocation(), diag::err_nsobject_attribute);
1671 return;
1672 }
1673 } else {
1674 // It is okay to include this attribute on properties, e.g.:
1675 //
1676 // @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
1677 //
1678 // In this case it follows tradition and suppresses an error in the above
1679 // case.
1680 Diag(D->getLocation(), diag::warn_nsobject_attribute);
1681 }
1682 D->addAttr(::new (getASTContext()) ObjCNSObjectAttr(getASTContext(), AL));
1683}
1684
1686 if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) {
1687 QualType T = TD->getUnderlyingType();
1688 if (!T->isObjCObjectPointerType()) {
1689 Diag(TD->getLocation(), diag::warn_ptr_independentclass_attribute);
1690 return;
1691 }
1692 } else {
1693 Diag(D->getLocation(), diag::warn_independentclass_attribute);
1694 return;
1695 }
1696 D->addAttr(::new (getASTContext())
1697 ObjCIndependentClassAttr(getASTContext(), AL));
1698}
1699
1701 if (!AL.isArgIdent(0)) {
1702 Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
1703 << AL << 1 << AANT_ArgumentIdentifier;
1704 return;
1705 }
1706
1708 BlocksAttr::BlockType type;
1709 if (!BlocksAttr::ConvertStrToBlockType(II->getName(), type)) {
1710 Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
1711 return;
1712 }
1713
1714 D->addAttr(::new (getASTContext()) BlocksAttr(getASTContext(), AL, type));
1715}
1716
1718 return QT->isDependentType() || QT->isObjCRetainableType();
1719}
1720
1722 return QT->isDependentType() || QT->isObjCObjectPointerType() ||
1723 QT->isObjCNSObjectType();
1724}
1725
1727 return QT->isDependentType() || QT->isPointerType() ||
1729}
1730
1732 if (QT->isDependentType())
1733 return true;
1734 QualType PT = QT->getPointeeType();
1735 return !PT.isNull() && PT->getAsCXXRecordDecl() != nullptr;
1736}
1737
1740 bool IsTemplateInstantiation) {
1741 ValueDecl *VD = cast<ValueDecl>(D);
1742 switch (K) {
1744 handleSimpleAttributeOrDiagnose<OSConsumedAttr>(
1745 *this, VD, CI, isValidSubjectOfOSAttribute(VD->getType()),
1746 diag::warn_ns_attribute_wrong_parameter_type,
1747 /*ExtraArgs=*/CI.getRange(), "os_consumed", /*pointers*/ 1);
1748 return;
1750 handleSimpleAttributeOrDiagnose<NSConsumedAttr>(
1751 *this, VD, CI, isValidSubjectOfNSAttribute(VD->getType()),
1752
1753 // These attributes are normally just advisory, but in ARC, ns_consumed
1754 // is significant. Allow non-dependent code to contain inappropriate
1755 // attributes even in ARC, but require template instantiations to be
1756 // set up correctly.
1757 ((IsTemplateInstantiation && getLangOpts().ObjCAutoRefCount)
1758 ? diag::err_ns_attribute_wrong_parameter_type
1759 : diag::warn_ns_attribute_wrong_parameter_type),
1760 /*ExtraArgs=*/CI.getRange(), "ns_consumed", /*objc pointers*/ 0);
1761 return;
1763 handleSimpleAttributeOrDiagnose<CFConsumedAttr>(
1764 *this, VD, CI, isValidSubjectOfCFAttribute(VD->getType()),
1765 diag::warn_ns_attribute_wrong_parameter_type,
1766 /*ExtraArgs=*/CI.getRange(), "cf_consumed", /*pointers*/ 1);
1767 return;
1768 }
1769}
1770
1773 switch (AL.getKind()) {
1774 case ParsedAttr::AT_CFConsumed:
1775 case ParsedAttr::AT_CFReturnsRetained:
1776 case ParsedAttr::AT_CFReturnsNotRetained:
1778 case ParsedAttr::AT_OSConsumesThis:
1779 case ParsedAttr::AT_OSConsumed:
1780 case ParsedAttr::AT_OSReturnsRetained:
1781 case ParsedAttr::AT_OSReturnsNotRetained:
1782 case ParsedAttr::AT_OSReturnsRetainedOnZero:
1783 case ParsedAttr::AT_OSReturnsRetainedOnNonZero:
1785 case ParsedAttr::AT_NSConsumesSelf:
1786 case ParsedAttr::AT_NSConsumed:
1787 case ParsedAttr::AT_NSReturnsRetained:
1788 case ParsedAttr::AT_NSReturnsNotRetained:
1789 case ParsedAttr::AT_NSReturnsAutoreleased:
1791 default:
1792 llvm_unreachable("Wrong argument supplied");
1793 }
1794}
1795
1797 QualType QT) {
1799 return false;
1800
1801 Diag(Loc, diag::warn_ns_attribute_wrong_return_type)
1802 << "'ns_returns_retained'" << 0 << 0;
1803 return true;
1804}
1805
1806/// \return whether the parameter is a pointer to OSObject pointer.
1808 const auto *PVD = dyn_cast<ParmVarDecl>(D);
1809 if (!PVD)
1810 return false;
1811 QualType QT = PVD->getType();
1812 QualType PT = QT->getPointeeType();
1813 return !PT.isNull() && isValidSubjectOfOSAttribute(PT);
1814}
1815
1817 QualType ReturnType;
1819
1820 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
1821 ReturnType = MD->getReturnType();
1822 } else if (getLangOpts().ObjCAutoRefCount && hasDeclarator(D) &&
1823 (AL.getKind() == ParsedAttr::AT_NSReturnsRetained)) {
1824 return; // ignore: was handled as a type attribute
1825 } else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) {
1826 ReturnType = PD->getType();
1827 } else if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
1828 ReturnType = FD->getReturnType();
1829 } else if (const auto *Param = dyn_cast<ParmVarDecl>(D)) {
1830 // Attributes on parameters are used for out-parameters,
1831 // passed as pointers-to-pointers.
1832 unsigned DiagID = K == Sema::RetainOwnershipKind::CF
1833 ? /*pointer-to-CF-pointer*/ 2
1834 : /*pointer-to-OSObject-pointer*/ 3;
1835 ReturnType = Param->getType()->getPointeeType();
1836 if (ReturnType.isNull()) {
1837 Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_parameter_type)
1838 << AL << DiagID << AL.getRange();
1839 return;
1840 }
1841 } else if (AL.isUsedAsTypeAttr()) {
1842 return;
1843 } else {
1844 AttributeDeclKind ExpectedDeclKind;
1845 switch (AL.getKind()) {
1846 default:
1847 llvm_unreachable("invalid ownership attribute");
1848 case ParsedAttr::AT_NSReturnsRetained:
1849 case ParsedAttr::AT_NSReturnsAutoreleased:
1850 case ParsedAttr::AT_NSReturnsNotRetained:
1851 ExpectedDeclKind = ExpectedFunctionOrMethod;
1852 break;
1853
1854 case ParsedAttr::AT_OSReturnsRetained:
1855 case ParsedAttr::AT_OSReturnsNotRetained:
1856 case ParsedAttr::AT_CFReturnsRetained:
1857 case ParsedAttr::AT_CFReturnsNotRetained:
1858 ExpectedDeclKind = ExpectedFunctionMethodOrParameter;
1859 break;
1860 }
1861 Diag(D->getBeginLoc(), diag::warn_attribute_wrong_decl_type)
1862 << AL.getRange() << AL << AL.isRegularKeywordAttribute()
1863 << ExpectedDeclKind;
1864 return;
1865 }
1866
1867 bool TypeOK;
1868 bool Cf;
1869 unsigned ParmDiagID = 2; // Pointer-to-CF-pointer
1870 switch (AL.getKind()) {
1871 default:
1872 llvm_unreachable("invalid ownership attribute");
1873 case ParsedAttr::AT_NSReturnsRetained:
1874 TypeOK = isValidSubjectOfNSReturnsRetainedAttribute(ReturnType);
1875 Cf = false;
1876 break;
1877
1878 case ParsedAttr::AT_NSReturnsAutoreleased:
1879 case ParsedAttr::AT_NSReturnsNotRetained:
1880 TypeOK = isValidSubjectOfNSAttribute(ReturnType);
1881 Cf = false;
1882 break;
1883
1884 case ParsedAttr::AT_CFReturnsRetained:
1885 case ParsedAttr::AT_CFReturnsNotRetained:
1886 TypeOK = isValidSubjectOfCFAttribute(ReturnType);
1887 Cf = true;
1888 break;
1889
1890 case ParsedAttr::AT_OSReturnsRetained:
1891 case ParsedAttr::AT_OSReturnsNotRetained:
1892 TypeOK = isValidSubjectOfOSAttribute(ReturnType);
1893 Cf = true;
1894 ParmDiagID = 3; // Pointer-to-OSObject-pointer
1895 break;
1896 }
1897
1898 if (!TypeOK) {
1899 if (AL.isUsedAsTypeAttr())
1900 return;
1901
1902 if (isa<ParmVarDecl>(D)) {
1903 Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_parameter_type)
1904 << AL << ParmDiagID << AL.getRange();
1905 } else {
1906 // Needs to be kept in sync with warn_ns_attribute_wrong_return_type.
1907 enum : unsigned { Function, Method, Property } SubjectKind = Function;
1908 if (isa<ObjCMethodDecl>(D))
1909 SubjectKind = Method;
1910 else if (isa<ObjCPropertyDecl>(D))
1911 SubjectKind = Property;
1912 Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_return_type)
1913 << AL << SubjectKind << Cf << AL.getRange();
1914 }
1915 return;
1916 }
1917
1918 switch (AL.getKind()) {
1919 default:
1920 llvm_unreachable("invalid ownership attribute");
1921 case ParsedAttr::AT_NSReturnsAutoreleased:
1922 handleSimpleAttribute<NSReturnsAutoreleasedAttr>(*this, D, AL);
1923 return;
1924 case ParsedAttr::AT_CFReturnsNotRetained:
1925 handleSimpleAttribute<CFReturnsNotRetainedAttr>(*this, D, AL);
1926 return;
1927 case ParsedAttr::AT_NSReturnsNotRetained:
1928 handleSimpleAttribute<NSReturnsNotRetainedAttr>(*this, D, AL);
1929 return;
1930 case ParsedAttr::AT_CFReturnsRetained:
1931 handleSimpleAttribute<CFReturnsRetainedAttr>(*this, D, AL);
1932 return;
1933 case ParsedAttr::AT_NSReturnsRetained:
1934 handleSimpleAttribute<NSReturnsRetainedAttr>(*this, D, AL);
1935 return;
1936 case ParsedAttr::AT_OSReturnsRetained:
1937 handleSimpleAttribute<OSReturnsRetainedAttr>(*this, D, AL);
1938 return;
1939 case ParsedAttr::AT_OSReturnsNotRetained:
1940 handleSimpleAttribute<OSReturnsNotRetainedAttr>(*this, D, AL);
1941 return;
1942 };
1943}
1944
1946 const int EP_ObjCMethod = 1;
1947 const int EP_ObjCProperty = 2;
1948
1949 SourceLocation loc = Attrs.getLoc();
1950 QualType resultType;
1951 if (isa<ObjCMethodDecl>(D))
1952 resultType = cast<ObjCMethodDecl>(D)->getReturnType();
1953 else
1954 resultType = cast<ObjCPropertyDecl>(D)->getType();
1955
1956 if (!resultType->isReferenceType() &&
1957 (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
1958 Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_return_type)
1959 << SourceRange(loc) << Attrs
1960 << (isa<ObjCMethodDecl>(D) ? EP_ObjCMethod : EP_ObjCProperty)
1961 << /*non-retainable pointer*/ 2;
1962
1963 // Drop the attribute.
1964 return;
1965 }
1966
1967 D->addAttr(::new (getASTContext())
1968 ObjCReturnsInnerPointerAttr(getASTContext(), Attrs));
1969}
1970
1972 const auto *Method = cast<ObjCMethodDecl>(D);
1973
1974 const DeclContext *DC = Method->getDeclContext();
1975 if (const auto *PDecl = dyn_cast_if_present<ObjCProtocolDecl>(DC)) {
1976 Diag(D->getBeginLoc(), diag::warn_objc_requires_super_protocol)
1977 << Attrs << 0;
1978 Diag(PDecl->getLocation(), diag::note_protocol_decl);
1979 return;
1980 }
1981 if (Method->getMethodFamily() == OMF_dealloc) {
1982 Diag(D->getBeginLoc(), diag::warn_objc_requires_super_protocol)
1983 << Attrs << 1;
1984 return;
1985 }
1986
1987 D->addAttr(::new (getASTContext())
1988 ObjCRequiresSuperAttr(getASTContext(), Attrs));
1989}
1990
1992 if (!isa<TagDecl>(D)) {
1993 Diag(D->getBeginLoc(), diag::err_nserrordomain_invalid_decl) << 0;
1994 return;
1995 }
1996
1997 IdentifierLoc *IdentLoc =
1998 Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : nullptr;
1999 if (!IdentLoc || !IdentLoc->getIdentifierInfo()) {
2000 // Try to locate the argument directly.
2002 if (Attr.isArgExpr(0) && Attr.getArgAsExpr(0))
2003 Loc = Attr.getArgAsExpr(0)->getBeginLoc();
2004
2005 Diag(Loc, diag::err_nserrordomain_invalid_decl) << 0;
2006 return;
2007 }
2008
2009 // Verify that the identifier is a valid decl in the C decl namespace.
2014 !Result.getAsSingle<VarDecl>()) {
2015 Diag(IdentLoc->getLoc(), diag::err_nserrordomain_invalid_decl)
2016 << 1 << IdentLoc->getIdentifierInfo();
2017 return;
2018 }
2019
2020 D->addAttr(::new (getASTContext()) NSErrorDomainAttr(
2021 getASTContext(), Attr, IdentLoc->getIdentifierInfo()));
2022}
2023
2025 IdentifierLoc *Parm = AL.isArgIdent(0) ? AL.getArgAsIdent(0) : nullptr;
2026
2027 if (!Parm) {
2028 Diag(D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0;
2029 return;
2030 }
2031
2032 // Typedefs only allow objc_bridge(id) and have some additional checking.
2033 if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) {
2034 if (!Parm->getIdentifierInfo()->isStr("id")) {
2035 Diag(AL.getLoc(), diag::err_objc_attr_typedef_not_id) << AL;
2036 return;
2037 }
2038
2039 // Only allow 'cv void *'.
2040 QualType T = TD->getUnderlyingType();
2041 if (!T->isVoidPointerType()) {
2042 Diag(AL.getLoc(), diag::err_objc_attr_typedef_not_void_pointer);
2043 return;
2044 }
2045 }
2046
2047 D->addAttr(::new (getASTContext()) ObjCBridgeAttr(getASTContext(), AL,
2048 Parm->getIdentifierInfo()));
2049}
2050
2052 IdentifierLoc *Parm = AL.isArgIdent(0) ? AL.getArgAsIdent(0) : nullptr;
2053
2054 if (!Parm) {
2055 Diag(D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0;
2056 return;
2057 }
2058
2059 D->addAttr(::new (getASTContext()) ObjCBridgeMutableAttr(
2060 getASTContext(), AL, Parm->getIdentifierInfo()));
2061}
2062
2064 IdentifierInfo *RelatedClass =
2065 AL.isArgIdent(0) ? AL.getArgAsIdent(0)->getIdentifierInfo() : nullptr;
2066 if (!RelatedClass) {
2067 Diag(D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0;
2068 return;
2069 }
2070 IdentifierInfo *ClassMethod =
2071 AL.getArgAsIdent(1) ? AL.getArgAsIdent(1)->getIdentifierInfo() : nullptr;
2072 IdentifierInfo *InstanceMethod =
2073 AL.getArgAsIdent(2) ? AL.getArgAsIdent(2)->getIdentifierInfo() : nullptr;
2074 D->addAttr(::new (getASTContext()) ObjCBridgeRelatedAttr(
2075 getASTContext(), AL, RelatedClass, ClassMethod, InstanceMethod));
2076}
2077
2079 DeclContext *Ctx = D->getDeclContext();
2080
2081 // This attribute can only be applied to methods in interfaces or class
2082 // extensions.
2083 if (!isa<ObjCInterfaceDecl>(Ctx) &&
2084 !(isa<ObjCCategoryDecl>(Ctx) &&
2085 cast<ObjCCategoryDecl>(Ctx)->IsClassExtension())) {
2086 Diag(D->getLocation(), diag::err_designated_init_attr_non_init);
2087 return;
2088 }
2089
2090 ObjCInterfaceDecl *IFace;
2091 if (auto *CatDecl = dyn_cast<ObjCCategoryDecl>(Ctx))
2092 IFace = CatDecl->getClassInterface();
2093 else
2094 IFace = cast<ObjCInterfaceDecl>(Ctx);
2095
2096 if (!IFace)
2097 return;
2098
2100 D->addAttr(::new (getASTContext())
2101 ObjCDesignatedInitializerAttr(getASTContext(), AL));
2102}
2103
2105 StringRef MetaDataName;
2106 if (!SemaRef.checkStringLiteralArgumentAttr(AL, 0, MetaDataName))
2107 return;
2108 D->addAttr(::new (getASTContext())
2109 ObjCRuntimeNameAttr(getASTContext(), AL, MetaDataName));
2110}
2111
2112// When a user wants to use objc_boxable with a union or struct
2113// but they don't have access to the declaration (legacy/third-party code)
2114// then they can 'enable' this feature with a typedef:
2115// typedef struct __attribute((objc_boxable)) legacy_struct legacy_struct;
2117 bool notify = false;
2118
2119 auto *RD = dyn_cast<RecordDecl>(D);
2120 if (RD && RD->getDefinition()) {
2121 RD = RD->getDefinition();
2122 notify = true;
2123 }
2124
2125 if (RD) {
2126 ObjCBoxableAttr *BoxableAttr =
2127 ::new (getASTContext()) ObjCBoxableAttr(getASTContext(), AL);
2128 RD->addAttr(BoxableAttr);
2129 if (notify) {
2130 // we need to notify ASTReader/ASTWriter about
2131 // modification of existing declaration
2133 L->AddedAttributeToRecord(BoxableAttr, RD);
2134 }
2135 }
2136}
2137
2139 if (hasDeclarator(D))
2140 return;
2141
2142 Diag(D->getBeginLoc(), diag::err_attribute_wrong_decl_type)
2143 << AL.getRange() << AL << AL.isRegularKeywordAttribute()
2145}
2146
2148 const auto *VD = cast<ValueDecl>(D);
2149 QualType QT = VD->getType();
2150
2151 if (!QT->isDependentType() && !QT->isObjCLifetimeType()) {
2152 Diag(AL.getLoc(), diag::err_objc_precise_lifetime_bad_type) << QT;
2153 return;
2154 }
2155
2157
2158 // If we have no lifetime yet, check the lifetime we're presumably
2159 // going to infer.
2160 if (Lifetime == Qualifiers::OCL_None && !QT->isDependentType())
2161 Lifetime = QT->getObjCARCImplicitLifetime();
2162
2163 switch (Lifetime) {
2165 assert(QT->isDependentType() &&
2166 "didn't infer lifetime for non-dependent type?");
2167 break;
2168
2169 case Qualifiers::OCL_Weak: // meaningful
2170 case Qualifiers::OCL_Strong: // meaningful
2171 break;
2172
2175 Diag(AL.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
2176 << (Lifetime == Qualifiers::OCL_Autoreleasing);
2177 break;
2178 }
2179
2180 D->addAttr(::new (getASTContext())
2181 ObjCPreciseLifetimeAttr(getASTContext(), AL));
2182}
2183
2185 bool DiagnoseFailure) {
2186 QualType Ty = VD->getType();
2187 if (!Ty->isObjCRetainableType()) {
2188 if (DiagnoseFailure) {
2189 S.Diag(VD->getBeginLoc(), diag::warn_ignored_objc_externally_retained)
2190 << 0;
2191 }
2192 return false;
2193 }
2194
2196
2197 // SemaObjC::inferObjCARCLifetime must run after processing decl attributes
2198 // (because __block lowers to an attribute), so if the lifetime hasn't been
2199 // explicitly specified, infer it locally now.
2200 if (LifetimeQual == Qualifiers::OCL_None)
2201 LifetimeQual = Ty->getObjCARCImplicitLifetime();
2202
2203 // The attributes only really makes sense for __strong variables; ignore any
2204 // attempts to annotate a parameter with any other lifetime qualifier.
2205 if (LifetimeQual != Qualifiers::OCL_Strong) {
2206 if (DiagnoseFailure) {
2207 S.Diag(VD->getBeginLoc(), diag::warn_ignored_objc_externally_retained)
2208 << 1;
2209 }
2210 return false;
2211 }
2212
2213 // Tampering with the type of a VarDecl here is a bit of a hack, but we need
2214 // to ensure that the variable is 'const' so that we can error on
2215 // modification, which can otherwise over-release.
2216 VD->setType(Ty.withConst());
2217 VD->setARCPseudoStrong(true);
2218 return true;
2219}
2220
2222 if (auto *VD = dyn_cast<VarDecl>(D)) {
2223 assert(!isa<ParmVarDecl>(VD) && "should be diagnosed automatically");
2224 if (!VD->hasLocalStorage()) {
2225 Diag(D->getBeginLoc(), diag::warn_ignored_objc_externally_retained) << 0;
2226 return;
2227 }
2228
2229 if (!tryMakeVariablePseudoStrong(SemaRef, VD, /*DiagnoseFailure=*/true))
2230 return;
2231
2232 handleSimpleAttribute<ObjCExternallyRetainedAttr>(*this, D, AL);
2233 return;
2234 }
2235
2236 // If D is a function-like declaration (method, block, or function), then we
2237 // make every parameter psuedo-strong.
2238 unsigned NumParams =
2240 for (unsigned I = 0; I != NumParams; ++I) {
2241 auto *PVD = const_cast<ParmVarDecl *>(getFunctionOrMethodParam(D, I));
2242 QualType Ty = PVD->getType();
2243
2244 // If a user wrote a parameter with __strong explicitly, then assume they
2245 // want "real" strong semantics for that parameter. This works because if
2246 // the parameter was written with __strong, then the strong qualifier will
2247 // be non-local.
2250 continue;
2251
2252 tryMakeVariablePseudoStrong(SemaRef, PVD, /*DiagnoseFailure=*/false);
2253 }
2254 handleSimpleAttribute<ObjCExternallyRetainedAttr>(*this, D, AL);
2255}
2256
2257bool SemaObjC::GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx) {
2260 SemaRef.getFormatStringInfo(Format->getFormatIdx(), Format->getFirstArg(),
2261 false, true, &FSI)) {
2262 Idx = FSI.FormatIdx;
2263 return true;
2264 }
2265 return false;
2266}
2267
2268/// Diagnose use of %s directive in an NSString which is being passed
2269/// as formatting string to formatting method.
2271 Expr **Args,
2272 unsigned NumArgs) {
2273 unsigned Idx = 0;
2274 bool Format = false;
2276 if (SFFamily == ObjCStringFormatFamily::SFF_CFString) {
2277 Idx = 2;
2278 Format = true;
2279 } else
2280 for (const auto *I : FDecl->specific_attrs<FormatAttr>()) {
2281 if (GetFormatNSStringIdx(I, Idx)) {
2282 Format = true;
2283 break;
2284 }
2285 }
2286 if (!Format || NumArgs <= Idx)
2287 return;
2288 const Expr *FormatExpr = Args[Idx];
2289 if (const CStyleCastExpr *CSCE = dyn_cast<CStyleCastExpr>(FormatExpr))
2290 FormatExpr = CSCE->getSubExpr();
2291 const StringLiteral *FormatString;
2292 if (const ObjCStringLiteral *OSL =
2293 dyn_cast<ObjCStringLiteral>(FormatExpr->IgnoreParenImpCasts()))
2294 FormatString = OSL->getString();
2295 else
2296 FormatString = dyn_cast<StringLiteral>(FormatExpr->IgnoreParenImpCasts());
2297 if (!FormatString)
2298 return;
2299 if (SemaRef.FormatStringHasSArg(FormatString)) {
2300 Diag(FormatExpr->getExprLoc(), diag::warn_objc_cdirective_format_string)
2301 << "%s" << 1 << 1;
2302 Diag(FDecl->getLocation(), diag::note_entity_declared_at)
2303 << FDecl->getDeclName();
2304 }
2305}
2306
2308 return Ty->isSpecificBuiltinType(BuiltinType::SChar) && getLangOpts().ObjC &&
2309 NSAPIObj->isObjCBOOLType(Ty);
2310}
2311
2313 const Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder) {
2314 const Expr *Ignored = SourceExpr->IgnoreImplicit();
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);
2320 SourceLocation EndLoc = SemaRef.getLocForEndOfToken(SourceExpr->getEndLoc());
2321 if (NeedsParens)
2322 Builder << FixItHint::CreateInsertion(SourceExpr->getBeginLoc(), "(")
2323 << FixItHint::CreateInsertion(EndLoc, ")");
2324 Builder << FixItHint::CreateInsertion(EndLoc, " ? YES : NO");
2325}
2326
2327/// Check a single element within a collection literal against the
2328/// target element type.
2329static void checkCollectionLiteralElement(Sema &S, QualType TargetElementType,
2330 Expr *Element, unsigned ElementKind) {
2331 // Skip a bitcast to 'id' or qualified 'id'.
2332 if (auto ICE = dyn_cast<ImplicitCastExpr>(Element)) {
2333 if (ICE->getCastKind() == CK_BitCast &&
2334 ICE->getSubExpr()->getType()->getAs<ObjCObjectPointerType>())
2335 Element = ICE->getSubExpr();
2336 }
2337
2338 QualType ElementType = Element->getType();
2339 ExprResult ElementResult(Element);
2340 if (ElementType->getAs<ObjCObjectPointerType>() &&
2342 TargetElementType, ElementResult, false, false))) {
2343 S.Diag(Element->getBeginLoc(), diag::warn_objc_collection_literal_element)
2344 << ElementType << ElementKind << TargetElementType
2345 << Element->getSourceRange();
2346 }
2347
2348 if (auto ArrayLiteral = dyn_cast<ObjCArrayLiteral>(Element))
2349 S.ObjC().checkArrayLiteral(TargetElementType, ArrayLiteral);
2350 else if (auto DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(Element))
2351 S.ObjC().checkDictionaryLiteral(TargetElementType, DictionaryLiteral);
2352}
2353
2354/// Check an Objective-C array literal being converted to the given
2355/// target type.
2357 ObjCArrayLiteral *ArrayLiteral) {
2358 if (!NSArrayDecl)
2359 return;
2360
2361 const auto *TargetObjCPtr = TargetType->getAs<ObjCObjectPointerType>();
2362 if (!TargetObjCPtr)
2363 return;
2364
2365 if (TargetObjCPtr->isUnspecialized() ||
2366 TargetObjCPtr->getInterfaceDecl()->getCanonicalDecl() !=
2368 return;
2369
2370 auto TypeArgs = TargetObjCPtr->getTypeArgs();
2371 if (TypeArgs.size() != 1)
2372 return;
2373
2374 QualType TargetElementType = TypeArgs[0];
2375 for (unsigned I = 0, N = ArrayLiteral->getNumElements(); I != N; ++I) {
2376 checkCollectionLiteralElement(SemaRef, TargetElementType,
2377 ArrayLiteral->getElement(I), 0);
2378 }
2379}
2380
2382 QualType TargetType, ObjCDictionaryLiteral *DictionaryLiteral) {
2383 if (!NSDictionaryDecl)
2384 return;
2385
2386 const auto *TargetObjCPtr = TargetType->getAs<ObjCObjectPointerType>();
2387 if (!TargetObjCPtr)
2388 return;
2389
2390 if (TargetObjCPtr->isUnspecialized() ||
2391 TargetObjCPtr->getInterfaceDecl()->getCanonicalDecl() !=
2393 return;
2394
2395 auto TypeArgs = TargetObjCPtr->getTypeArgs();
2396 if (TypeArgs.size() != 2)
2397 return;
2398
2399 QualType TargetKeyType = TypeArgs[0];
2400 QualType TargetObjectType = TypeArgs[1];
2401 for (unsigned I = 0, N = DictionaryLiteral->getNumElements(); I != N; ++I) {
2402 auto Element = DictionaryLiteral->getKeyValueElement(I);
2403 checkCollectionLiteralElement(SemaRef, TargetKeyType, Element.Key, 1);
2404 checkCollectionLiteralElement(SemaRef, TargetObjectType, Element.Value, 2);
2405 }
2406}
2407
2408} // namespace clang
const Decl * D
CompileCommand Cmd
Defines the clang::Preprocessor interface.
RedeclarationKind
Specifies whether (or how) name lookup is being performed for a redeclaration (vs.
Definition: Redeclaration.h:18
Expr * Capturer
Definition: SemaObjC.cpp:869
SourceRange Range
Definition: SemaObjC.cpp:753
bool VarWillBeReased
Definition: SemaObjC.cpp:870
SourceLocation Loc
Definition: SemaObjC.cpp:754
bool Indirect
Definition: SemaObjC.cpp:755
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 ...
Definition: ASTContext.h:188
bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT)
canAssignObjCInterfaces - Return true if the two interface types are compatible for assignment from R...
IdentifierTable & Idents
Definition: ASTContext.h:740
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...
PtrTy get() const
Definition: Ownership.h:171
bool isInvalid() const
Definition: Ownership.h:167
bool isUsable() const
Definition: Ownership.h:169
Attr - This represents one attribute.
Definition: Attr.h:44
SourceLocation getLoc() const
Type source information for an attributed type.
Definition: TypeLoc.h:1017
Stmt * getBody() const override
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
Definition: Decl.h:4709
bool capturesVariable(const VarDecl *var) const
Definition: Decl.cpp:5334
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:6560
const BlockDecl * getBlockDecl() const
Definition: Expr.h:6572
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Definition: Expr.h:3905
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2937
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2879
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:3612
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1449
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
Definition: DeclBase.h:2125
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1272
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition: Stmt.h:1622
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
T * getAttr() const
Definition: DeclBase.h:573
bool isInvalidDecl() const
Definition: DeclBase.h:588
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
Definition: DeclBase.h:559
SourceLocation getLocation() const
Definition: DeclBase.h:439
The name of a declaration.
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Decl.h:830
This represents one expression.
Definition: Expr.h:112
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Definition: Expr.cpp:3078
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition: Expr.h:194
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition: Expr.cpp:3073
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:3061
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:3069
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
Definition: Expr.h:284
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:3053
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition: Expr.cpp:273
QualType getType() const
Definition: Expr.h:144
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
Definition: Diagnostic.h:128
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.
Definition: Diagnostic.h:102
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition: Stmt.h:2891
void setBody(Stmt *S)
Definition: Stmt.h:2945
Represents a function declaration or definition.
Definition: Decl.h:1999
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.
A simple pair of identifier info and location.
SourceLocation getLoc() const
IdentifierInfo * getIdentifierInfo() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Represents the results of name lookup.
Definition: Lookup.h:147
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3300
@ ClassId_NSMutableArray
Definition: NSAPI.h:33
@ ClassId_NSMutableOrderedSet
Definition: NSAPI.h:38
@ ClassId_NSMutableSet
Definition: NSAPI.h:37
@ ClassId_NSMutableDictionary
Definition: NSAPI.h:35
NSSetMethodKind
Enumerates the NSMutableSet/NSOrderedSet methods used to apply some checks.
Definition: NSAPI.h:121
@ NSOrderedSet_setObjectAtIndex
Definition: NSAPI.h:124
@ NSMutableSet_addObject
Definition: NSAPI.h:122
@ NSOrderedSet_replaceObjectAtIndexWithObject
Definition: NSAPI.h:126
@ NSOrderedSet_setObjectAtIndexedSubscript
Definition: NSAPI.h:125
@ NSOrderedSet_insertObjectAtIndex
Definition: NSAPI.h:123
NSDictionaryMethodKind
Enumerates the NSDictionary/NSMutableDictionary methods used to generate literals and to apply some c...
Definition: NSAPI.h:96
@ NSMutableDict_setValueForKey
Definition: NSAPI.h:109
@ NSMutableDict_setObjectForKey
Definition: NSAPI.h:107
@ NSMutableDict_setObjectForKeyedSubscript
Definition: NSAPI.h:108
NSArrayMethodKind
Enumerates the NSArray/NSMutableArray methods used to generate literals and to apply some checks.
Definition: NSAPI.h:72
@ NSMutableArr_setObjectAtIndexedSubscript
Definition: NSAPI.h:84
@ NSMutableArr_insertObjectAtIndex
Definition: NSAPI.h:83
@ NSMutableArr_addObject
Definition: NSAPI.h:82
@ NSMutableArr_replaceObjectAtIndex
Definition: NSAPI.h:81
This represents a decl that may have a name.
Definition: Decl.h:273
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:294
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:339
ObjCStringFormatFamily getObjCFStringFormattingFamily() const
Definition: Decl.cpp:1169
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
Definition: ExprObjC.h:192
Expr * getElement(unsigned Index)
getElement - Return the Element at the specified index.
Definition: ExprObjC.h:230
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c array literal.
Definition: ExprObjC.h:227
Represents Objective-C's @catch statement.
Definition: StmtObjC.h:77
Represents Objective-C's @finally statement.
Definition: StmtObjC.h:127
Represents Objective-C's @synchronized statement.
Definition: StmtObjC.h:303
Represents Objective-C's @throw statement.
Definition: StmtObjC.h:358
static ObjCAtTryStmt * Create(const ASTContext &Context, SourceLocation atTryLoc, Stmt *atTryStmt, Stmt **CatchStmts, unsigned NumCatchStmts, Stmt *atFinallyStmt)
Definition: StmtObjC.cpp:45
Represents Objective-C's @autoreleasepool Statement.
Definition: StmtObjC.h:394
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2329
ObjCContainerDecl - Represents a container for method declarations.
Definition: DeclObjC.h:948
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition: ExprObjC.h:308
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c dictionary literal.
Definition: ExprObjC.h:359
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
Definition: ExprObjC.h:361
Represents Objective-C's collection statement.
Definition: StmtObjC.h:23
Represents an ObjC class declaration.
Definition: DeclObjC.h:1154
ObjCTypeParamList * getTypeParamList() const
Retrieve the type parameters of this class.
Definition: DeclObjC.cpp:319
ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const
Lookup an instance method for a given selector.
Definition: DeclObjC.h:1847
ObjCMethodDecl * lookupPrivateMethod(const Selector &Sel, bool Instance=true) const
Lookup a method in the classes implementation hierarchy.
Definition: DeclObjC.cpp:753
ObjCInterfaceDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C class.
Definition: DeclObjC.h:1915
void setHasDesignatedInitializers()
Indicate that this interface decl contains at least one initializer marked with the 'objc_designated_...
Definition: DeclObjC.cpp:1592
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1952
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition: ExprObjC.h:548
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:940
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition: ExprObjC.h:1403
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
Definition: ExprObjC.h:1268
SourceLocation getSuperLoc() const
Retrieve the location of the 'super' keyword for a class or instance message to 'super',...
Definition: ExprObjC.h:1309
Selector getSelector() const
Definition: ExprObjC.cpp:289
@ SuperInstance
The receiver is the instance of the superclass object.
Definition: ExprObjC.h:954
@ Instance
The receiver is an object instance.
Definition: ExprObjC.h:948
bool isInstanceMessage() const
Determine whether this is an instance message to either a computed object or to super.
Definition: ExprObjC.h:1256
const ObjCMethodDecl * getMethodDecl() const
Definition: ExprObjC.h:1364
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
Definition: ExprObjC.h:1229
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver.
Definition: ExprObjC.h:1390
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:140
ImplicitParamDecl * getSelfDecl() const
Definition: DeclObjC.h:418
ArrayRef< ParmVarDecl * > parameters() const
Definition: DeclObjC.h:373
Wraps an ObjCPointerType with source location information.
Definition: TypeLoc.h:1566
void setStarLoc(SourceLocation Loc)
Definition: TypeLoc.h:1572
Represents a pointer to an Objective C object.
Definition: TypeBase.h:7961
ArrayRef< QualType > getTypeArgs() const
Retrieve the type arguments for this type.
Definition: TypeBase.h:8065
void setHasBaseTypeAsWritten(bool HasBaseType)
Definition: TypeLoc.h:1238
Represents a class type in Objective C.
Definition: TypeBase.h:7707
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
Definition: TypeBase.h:7940
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:731
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
Definition: ExprObjC.h:616
ObjCPropertyDecl * getExplicitProperty() const
Definition: ExprObjC.h:705
const Expr * getBase() const
Definition: ExprObjC.h:754
bool isImplicitProperty() const
Definition: ExprObjC.h:702
SourceLocation getLocation() const
Definition: ExprObjC.h:757
bool isSuperReceiver() const
Definition: ExprObjC.h:770
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2084
The basic abstraction for the target Objective-C runtime.
Definition: ObjCRuntime.h:28
bool allowsDirectDispatch() const
Does this runtime supports direct dispatch.
Definition: ObjCRuntime.h:467
ObjCStringLiteral, used for Objective-C string literals i.e.
Definition: ExprObjC.h:52
Represents the declaration of an Objective-C type parameter.
Definition: DeclObjC.h:578
Stores a list of Objective-C type parameters for a parameterized class or a category/extension thereo...
Definition: DeclObjC.h:662
unsigned size() const
Determine the number of type parameters in this list.
Definition: DeclObjC.h:689
ProtocolLAngleLoc, ProtocolRAngleLoc, and the source locations for protocol qualifiers are stored aft...
Definition: TypeLoc.h:904
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition: Expr.h:1180
Represents a pack expansion of types.
Definition: TypeBase.h:7524
Represents a parameter to a function.
Definition: Decl.h:1789
ParsedAttr - Represents a syntactic attribute.
Definition: ParsedAttr.h:119
IdentifierLoc * getArgAsIdent(unsigned Arg) const
Definition: ParsedAttr.h:389
bool hasParsedType() const
Definition: ParsedAttr.h:337
const ParsedType & getTypeArg() const
Definition: ParsedAttr.h:459
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this attribute.
Definition: ParsedAttr.h:371
bool isArgIdent(unsigned Arg) const
Definition: ParsedAttr.h:385
bool isUsedAsTypeAttr() const
Definition: ParsedAttr.h:359
AttributeCommonInfo::Kind getKind() const
Definition: ParsedAttr.h:610
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: TypeBase.h:3346
QualType getPointeeType() const
Definition: TypeBase.h:3356
IdentifierLoc 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.
Definition: Expr.h:6692
A (possibly-)qualified type.
Definition: TypeBase.h:937
QualType withConst() const
Definition: TypeBase.h:1159
QualType getLocalUnqualifiedType() const
Return this type with all of the instance-specific qualifiers removed, but without removing any quali...
Definition: TypeBase.h:1225
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: TypeBase.h:1004
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition: TypeBase.h:8383
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
Definition: TypeBase.h:1438
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: TypeBase.h:8437
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: TypeBase.h:8416
The collection of all-type qualifiers we support.
Definition: TypeBase.h:331
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Definition: TypeBase.h:361
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
Definition: TypeBase.h:354
@ OCL_None
There is no lifetime qualification on this type.
Definition: TypeBase.h:350
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Definition: TypeBase.h:364
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
Definition: TypeBase.h:367
bool compatiblyIncludes(Qualifiers other, const ASTContext &Ctx) const
Determines if these qualifiers compatibly include another set.
Definition: TypeBase.h:727
ObjCLifetime getObjCLifetime() const
Definition: TypeBase.h:545
Qualifiers withoutObjCLifetime() const
Definition: TypeBase.h:533
bool empty() const
Definition: TypeBase.h:647
std::string getAsString() const
void setObjCLifetime(ObjCLifetime type)
Definition: TypeBase.h:548
Represents a struct/union/class.
Definition: Decl.h:4305
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: TypeBase.h:6502
RecordDecl * getOriginalDecl() const
Definition: TypeBase.h:6509
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:41
bool isAtCatchScope() const
isAtCatchScope - Return true if this scope is @catch.
Definition: Scope.h:486
const Scope * getParent() const
getParent - Return the scope that this is nested in.
Definition: Scope.h:275
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.
Definition: SemaBase.h:111
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: SemaBase.cpp:61
ASTContext & getASTContext() const
Definition: SemaBase.cpp:9
Sema & SemaRef
Definition: SemaBase.h:40
const LangOptions & getLangOpts() const
Definition: SemaBase.cpp:11
bool isCFError(RecordDecl *D)
Definition: SemaObjC.cpp:1461
void ActOnObjCReenterContainerContext(ObjCContainerDecl *ObjCCtx)
Definition: SemaObjC.cpp:1291
void ActOnObjCTemporaryExitContainerContext(ObjCContainerDecl *ObjCCtx)
Invoked when we must temporarily exit the objective-c container scope for parsing/looking-up C constr...
Definition: SemaObjC.cpp:1284
void handleRuntimeName(Decl *D, const ParsedAttr &AL)
Definition: SemaObjC.cpp:2104
void handleNSObject(Decl *D, const ParsedAttr &AL)
Definition: SemaObjC.cpp:1660
bool isValidOSObjectOutParameter(const Decl *D)
Definition: SemaObjC.cpp:1807
StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc, Stmt *First, Expr *collection, SourceLocation RParenLoc)
Definition: SemaObjC.cpp:36
StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body)
FinishObjCForCollectionStmt - Attach the body to a objective-C foreach statement.
Definition: SemaObjC.cpp:193
void handleNSErrorDomain(Decl *D, const ParsedAttr &Attr)
Definition: SemaObjC.cpp:1991
void handleXReturnsXRetainedAttr(Decl *D, const ParsedAttr &AL)
Definition: SemaObjC.cpp:1816
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.
Definition: SemaObjC.cpp:480
SemaObjC(Sema &S)
Definition: SemaObjC.cpp:29
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.
Definition: SemaObjC.cpp:373
void checkArrayLiteral(QualType TargetType, ObjCArrayLiteral *ArrayLiteral)
Check an Objective-C array literal being converted to the given target type.
Definition: SemaObjC.cpp:2356
void handleExternallyRetainedAttr(Decl *D, const ParsedAttr &AL)
Definition: SemaObjC.cpp:2221
ObjCSubscriptKind CheckSubscriptingKind(Expr *FromE)
CheckSubscriptingKind - This routine decide what type of indexing represented by "FromE" is being don...
Definition: SemaObjC.cpp:1375
IdentifierInfo * getNSErrorIdent()
Retrieve the identifier "NSError".
Definition: SemaObjC.cpp:1265
StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SynchExpr, Stmt *SynchBody)
Definition: SemaObjC.cpp:320
ParsedType ActOnObjCInstanceType(SourceLocation Loc)
The parser has parsed the context-sensitive type 'instancetype' in an Objective-C message declaration...
Definition: SemaObjC.cpp:740
void handleMethodFamilyAttr(Decl *D, const ParsedAttr &AL)
Definition: SemaObjC.cpp:1631
void handleIndependentClass(Decl *D, const ParsedAttr &AL)
Definition: SemaObjC.cpp:1685
ObjCInterfaceDecl * NSArrayDecl
The declaration of the Objective-C NSArray class.
Definition: SemaObjC.h:621
RecordDecl * CFError
The struct behind the CFErrorRef pointer.
Definition: SemaObjC.h:158
void handleIBOutlet(Decl *D, const ParsedAttr &AL)
Definition: SemaObjC.cpp:1545
void handleReturnsInnerPointerAttr(Decl *D, const ParsedAttr &Attrs)
Definition: SemaObjC.cpp:1945
bool isObjCWritebackConversion(QualType FromType, QualType ToType, QualType &ConvertedType)
Determine whether this is an Objective-C writeback conversion, used for parameter passing when perfor...
Definition: SemaObjC.cpp:1314
void CheckObjCCircularContainer(ObjCMessageExpr *Message)
Check whether receiver is mutable ObjC container which attempts to add itself into the container.
Definition: SemaObjC.cpp:1090
void adornBoolConversionDiagWithTernaryFixit(const Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder)
Definition: SemaObjC.cpp:2312
void handleSuppresProtocolAttr(Decl *D, const ParsedAttr &AL)
Definition: SemaObjC.cpp:1598
StmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try, MultiStmtArg Catch, Stmt *Finally)
Definition: SemaObjC.cpp:218
void handleOwnershipAttr(Decl *D, const ParsedAttr &AL)
Definition: SemaObjC.cpp:2138
bool isSignedCharBool(QualType Ty)
Definition: SemaObjC.cpp:2307
void handleBlocksAttr(Decl *D, const ParsedAttr &AL)
Definition: SemaObjC.cpp:1700
StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body)
Definition: SemaObjC.cpp:213
void ActOnObjCContainerFinishDefinition()
Definition: SemaObjC.cpp:1279
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.
Definition: SemaObjC.cpp:336
StmtResult BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw)
Definition: SemaObjC.cpp:238
void handleBridgeMutableAttr(Decl *D, const ParsedAttr &AL)
Definition: SemaObjC.cpp:2051
Sema::RetainOwnershipKind parsedAttrToRetainOwnershipKind(const ParsedAttr &AL)
Definition: SemaObjC.cpp:1772
void handleRequiresSuperAttr(Decl *D, const ParsedAttr &Attrs)
Definition: SemaObjC.cpp:1971
ObjCInterfaceDecl * NSDictionaryDecl
The declaration of the Objective-C NSDictionary class.
Definition: SemaObjC.h:627
bool CheckObjCString(Expr *Arg)
CheckObjCString - Checks that the argument to the builtin CFString constructor is correct Note: It mi...
Definition: SemaObjC.cpp:1213
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.
Definition: SemaObjC.cpp:707
ExprResult ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand)
Definition: SemaObjC.cpp:282
void AddXConsumedAttr(Decl *D, const AttributeCommonInfo &CI, Sema::RetainOwnershipKind K, bool IsTemplateInstantiation)
Definition: SemaObjC.cpp:1738
const DeclContext * getCurObjCLexicalContext() const
Definition: SemaObjC.cpp:1256
void handleDesignatedInitializer(Decl *D, const ParsedAttr &AL)
Definition: SemaObjC.cpp:2078
void handleBridgeRelatedAttr(Decl *D, const ParsedAttr &AL)
Definition: SemaObjC.cpp:2063
void handleIBOutletCollection(Decl *D, const ParsedAttr &AL)
Definition: SemaObjC.cpp:1552
ObjCProtocolDecl * LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Find the protocol with the given name, if any.
Definition: SemaObjC.cpp:1297
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...
Definition: SemaObjC.cpp:2270
bool isCFStringType(QualType T)
Definition: SemaObjC.cpp:1505
void handleDirectAttr(Decl *D, const ParsedAttr &AL)
Definition: SemaObjC.cpp:1609
StmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, Scope *CurScope)
Definition: SemaObjC.cpp:265
void checkRetainCycles(ObjCMessageExpr *msg)
checkRetainCycles - Check whether an Objective-C message send might create an obvious retain cycle.
Definition: SemaObjC.cpp:1156
StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc, SourceLocation RParen, Decl *Parm, Stmt *Body)
Definition: SemaObjC.cpp:202
bool isNSStringType(QualType T, bool AllowNSAttributedString=false)
Definition: SemaObjC.cpp:1486
bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx)
Definition: SemaObjC.cpp:2257
ExprResult CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection)
Definition: SemaObjC.cpp:121
void AddCFAuditedAttribute(Decl *D)
AddCFAuditedAttribute - Check whether we're currently within '#pragma clang arc_cf_code_audited' and,...
Definition: SemaObjC.cpp:1444
void checkDictionaryLiteral(QualType TargetType, ObjCDictionaryLiteral *DictionaryLiteral)
Check an Objective-C dictionary literal being converted to the given target type.
Definition: SemaObjC.cpp:2381
void handleBoxable(Decl *D, const ParsedAttr &AL)
Definition: SemaObjC.cpp:2116
bool checkNSReturnsRetainedReturnType(SourceLocation loc, QualType type)
Definition: SemaObjC.cpp:1796
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)
Definition: SemaObjC.cpp:329
void handleDirectMembersAttr(Decl *D, const ParsedAttr &AL)
Definition: SemaObjC.cpp:1623
bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, ArrayRef< const Expr * > Args)
Definition: SemaObjC.cpp:1241
void handleBridgeAttr(Decl *D, const ParsedAttr &AL)
Definition: SemaObjC.cpp:2024
void handlePreciseLifetimeAttr(Decl *D, const ParsedAttr &AL)
Definition: SemaObjC.cpp:2147
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
Definition: SemaObjC.h:591
void ActOnObjCContainerStartDefinition(ObjCContainerDecl *IDecl)
Definition: SemaObjC.cpp:1272
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:850
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)
Package the given type and TSI into a ParsedType.
Definition: SemaType.cpp:6383
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....
Definition: Sema.h:9281
@ LookupObjCProtocolName
Look up the name of an Objective-C protocol.
Definition: Sema.h:9318
RetainOwnershipKind
Definition: Sema.h:5005
bool FormatStringHasSArg(const StringLiteral *FExpr)
Scope * getScopeForContext(DeclContext *Ctx)
Determines the active Scope associated with the given declaration context.
Definition: Sema.cpp:2311
NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Look up a name, looking for a single declaration.
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.
Definition: SemaExpr.cpp:9762
ASTContext & Context
Definition: Sema.h:1276
bool isObjCPointerConversion(QualType FromType, QualType ToType, QualType &ConvertedType, bool &IncompatibleObjC)
isObjCPointerConversion - Determines whether this is an Objective-C pointer conversion.
SemaObjC & ObjC()
Definition: Sema.h:1483
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
Definition: SemaExpr.cpp:748
ObjCMethodDecl * getCurMethodDecl()
getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...
Definition: Sema.cpp:1652
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
Definition: Sema.cpp:83
Preprocessor & PP
Definition: Sema.h:1275
DeclContext * getCurLexicalContext() const
Definition: Sema.h:1117
sema::FunctionScopeInfo * getCurFunction() const
Definition: Sema.h:1307
ExprResult DefaultLvalueConversion(Expr *E)
Definition: SemaExpr.cpp:633
bool IsAssignConvertCompatible(AssignConvertType ConvTy)
Definition: Sema.h:7997
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.
Definition: Sema.h:1411
DeclContext * OriginalLexicalContext
Generally null except when we temporarily switch decl contexts, like in.
Definition: Sema.h:3564
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
Definition: Sema.h:13785
static FormatStringType GetFormatStringType(StringRef FormatFlavor)
bool isCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind=CompleteTypeKind::Default)
Definition: Sema.h:15273
void setFunctionHasBranchProtectedScope()
Definition: Sema.cpp:2497
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.
Definition: SemaDecl.cpp:270
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Definition: SemaType.cpp:9241
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
Definition: Sema.h:1239
static bool getFormatStringInfo(const Decl *Function, unsigned FormatIdx, unsigned FirstArg, FormatStringInfo *FSI)
Given a function and its FormatAttr or FormatMatchesAttr info, attempts to populate the FomatStringIn...
void PopDeclContext()
Definition: SemaDecl.cpp:1373
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)
Definition: SemaType.cpp:2773
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
Definition: Sema.cpp:653
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
Definition: Sema.h:8599
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.
Definition: Stmt.h:85
SourceLocation getEndLoc() const LLVM_READONLY
Definition: Stmt.cpp:358
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:334
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:346
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1801
StringRef getString() const
Definition: Expr.h:1869
TagKind getTagKind() const
Definition: Decl.h:3904
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:59
TypeLoc findExplicitQualifierLoc() const
Find a type with the location of an explicit type qualifier.
Definition: TypeLoc.cpp:453
T getAs() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition: TypeLoc.h:89
T castAs() const
Convert to the specified TypeLoc type, asserting that this TypeLoc is of the desired type.
Definition: TypeLoc.h:78
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
Definition: TypeLoc.h:154
SourceLocation getBeginLoc() const
Get the begin source location.
Definition: TypeLoc.cpp:193
A container of type source information.
Definition: TypeBase.h:8314
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:272
QualType getType() const
Return the type wrapped by this type source info.
Definition: TypeBase.h:8325
bool isBlockPointerType() const
Definition: TypeBase.h:8600
bool isVoidType() const
Definition: TypeBase.h:8936
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.h:26
bool isVoidPointerType() const
Definition: Type.cpp:712
bool isPointerType() const
Definition: TypeBase.h:8580
const T * castAs() const
Member-template castAs<specific type>.
Definition: TypeBase.h:9226
bool isReferenceType() const
Definition: TypeBase.h:8604
bool isObjCNSObjectType() const
Definition: Type.cpp:5324
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:752
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition: TypeBase.h:9054
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition: TypeBase.h:2917
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
Definition: TypeBase.h:8905
bool isBuiltinType() const
Helper methods to distinguish type categories.
Definition: TypeBase.h:8703
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: TypeBase.h:2800
bool isCARCBridgableType() const
Determine whether the given type T is a "bridgeable" C type.
Definition: Type.cpp:5369
bool isObjCIdType() const
Definition: TypeBase.h:8782
bool isObjCObjectType() const
Definition: TypeBase.h:8753
bool isBlockCompatibleObjCPointerType(ASTContext &ctx) const
Definition: Type.cpp:5266
bool isObjCLifetimeType() const
Returns true if objects of this type have lifetime semantics under ARC.
Definition: Type.cpp:5355
Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const
Return the implicit lifetime for this type, which must not be dependent.
Definition: Type.cpp:5299
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
Definition: Type.cpp:2440
bool isObjCObjectPointerType() const
Definition: TypeBase.h:8749
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition: TypeBase.h:2939
const T * getAs() const
Member-template getAs<specific type>'.
Definition: TypeBase.h:9159
bool isObjCRetainableType() const
Definition: Type.cpp:5336
QualType getUnderlyingType() const
Definition: Decl.h:3610
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:711
void setType(QualType newType)
Definition: Decl.h:723
QualType getType() const
Definition: Decl.h:722
Represents a variable declaration or definition.
Definition: Decl.h:925
void setARCPseudoStrong(bool PS)
Definition: Decl.h:1547
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:2190
Retains information about a function, method, or block that is currently being parsed.
Definition: ScopeInfo.h:104
void setHasObjCTry(SourceLocation TryLoc)
Definition: ScopeInfo.h:471
SourceLocation FirstSEHTryLoc
First SEH '__try' statement in the current function.
Definition: ScopeInfo.h:193
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.
Definition: SemaObjC.cpp:2329
ObjCStringFormatFamily
AttributeDeclKind
These constants match the enumerated choices of warn_attribute_wrong_decl_type and err_attribute_wron...
Definition: ParsedAttr.h:1074
@ ExpectedFunctionMethodOrParameter
Definition: ParsedAttr.h:1080
@ ExpectedFunctionOrMethod
Definition: ParsedAttr.h:1078
@ ExpectedVariable
Definition: ParsedAttr.h:1081
VariadicCallType
Definition: Sema.h:511
bool hasDeclarator(const Decl *D)
Return true if the given decl has a declarator that should have been processed by Sema::GetTypeForDec...
Definition: Attr.h:46
static bool isValidSubjectOfOSAttribute(QualType QT)
Definition: SemaObjC.cpp:1731
static void diagnoseRetainCycle(Sema &S, Expr *capturer, RetainCycleOwner &owner)
Definition: SemaObjC.cpp:958
const ParmVarDecl * getFunctionOrMethodParam(const Decl *D, unsigned Idx)
Definition: Attr.h:72
static bool isSetterLikeSelector(Selector sel)
Check for a keyword selector that starts with the word 'add' or 'set'.
Definition: SemaObjC.cpp:971
static Expr * findCapturingExpr(Sema &S, Expr *e, RetainCycleOwner &owner)
Check whether the given argument is a block which captures a variable.
Definition: SemaObjC.cpp:923
static bool considerVariable(VarDecl *var, Expr *ref, RetainCycleOwner &owner)
Consider whether capturing the given variable can possibly lead to a retain cycle.
Definition: SemaObjC.cpp:769
static std::optional< int > GetNSMutableDictionaryArgumentIndex(SemaObjC &S, ObjCMessageExpr *Message)
Definition: SemaObjC.cpp:1026
@ AANT_ArgumentIdentifier
Definition: ParsedAttr.h:1067
StmtResult StmtError()
Definition: Ownership.h:266
@ 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)
Definition: SemaObjC.cpp:1521
LLVM_READONLY bool isLowercase(unsigned char c)
Return true if this character is a lowercase ASCII letter: [a-z].
Definition: CharInfo.h:120
@ 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.
Definition: SemaObjC.cpp:504
ExprResult ExprError()
Definition: Ownership.h:265
static bool isValidSubjectOfNSAttribute(QualType QT)
Definition: SemaObjC.cpp:1721
static bool isValidSubjectOfCFAttribute(QualType QT)
Definition: SemaObjC.cpp:1726
static std::optional< int > GetNSSetArgumentIndex(SemaObjC &S, ObjCMessageExpr *Message)
Definition: SemaObjC.cpp:1056
static bool tryMakeVariablePseudoStrong(Sema &S, VarDecl *VD, bool DiagnoseFailure)
Definition: SemaObjC.cpp:2184
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:135
const FunctionProtoType * T
static bool isValidSubjectOfNSReturnsRetainedAttribute(QualType QT)
Definition: SemaObjC.cpp:1717
bool hasFunctionProto(const Decl *D)
hasFunctionProto - Return true if the given decl has a argument information.
Definition: Attr.h:55
static bool findRetainCycleOwner(Sema &S, Expr *e, RetainCycleOwner &owner)
Definition: SemaObjC.cpp:782
unsigned getFunctionOrMethodNumParams(const Decl *D)
getFunctionOrMethodNumParams - Return number of function or method parameters.
Definition: Attr.h:64
TemplateDeductionResult
Describes the result of template argument deduction.
Definition: Sema.h:366
@ Success
Template argument deduction was successful.
@ AlreadyDiagnosed
Some error which was already diagnosed.
U cast(CodeGen::Address addr)
Definition: Address.h:327
static std::optional< int > GetNSMutableArrayArgumentIndex(SemaObjC &S, ObjCMessageExpr *Message)
Definition: SemaObjC.cpp:993