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