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