clang 23.0.0git
SemaDeclAttr.cpp
Go to the documentation of this file.
1//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
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//
9// This file implements decl-related attribute processing.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/APValue.h"
19#include "clang/AST/Decl.h"
20#include "clang/AST/DeclCXX.h"
21#include "clang/AST/DeclObjC.h"
24#include "clang/AST/Expr.h"
25#include "clang/AST/ExprCXX.h"
26#include "clang/AST/Mangle.h"
27#include "clang/AST/Type.h"
29#include "clang/Basic/Cuda.h"
37#include "clang/Sema/Attr.h"
38#include "clang/Sema/DeclSpec.h"
41#include "clang/Sema/Lookup.h"
43#include "clang/Sema/Scope.h"
45#include "clang/Sema/Sema.h"
47#include "clang/Sema/SemaARM.h"
48#include "clang/Sema/SemaAVR.h"
49#include "clang/Sema/SemaBPF.h"
50#include "clang/Sema/SemaCUDA.h"
51#include "clang/Sema/SemaHLSL.h"
53#include "clang/Sema/SemaM68k.h"
54#include "clang/Sema/SemaMIPS.h"
56#include "clang/Sema/SemaObjC.h"
59#include "clang/Sema/SemaPPC.h"
61#include "clang/Sema/SemaSYCL.h"
63#include "clang/Sema/SemaWasm.h"
64#include "clang/Sema/SemaX86.h"
65#include "llvm/ADT/APSInt.h"
66#include "llvm/ADT/STLExtras.h"
67#include "llvm/ADT/StringExtras.h"
68#include "llvm/Demangle/Demangle.h"
69#include "llvm/IR/DerivedTypes.h"
70#include "llvm/MC/MCSectionMachO.h"
71#include "llvm/Support/Error.h"
72#include "llvm/Support/ErrorHandling.h"
73#include "llvm/Support/MathExtras.h"
74#include "llvm/Support/raw_ostream.h"
75#include "llvm/TargetParser/Triple.h"
76#include <optional>
77
78using namespace clang;
79using namespace sema;
80
82 enum LANG {
86 };
87} // end namespace AttributeLangSupport
88
89static unsigned getNumAttributeArgs(const ParsedAttr &AL) {
90 // FIXME: Include the type in the argument list.
91 return AL.getNumArgs() + AL.hasParsedType();
92}
93
97
98/// Wrapper around checkUInt32Argument, with an extra check to be sure
99/// that the result will fit into a regular (signed) int. All args have the same
100/// purpose as they do in checkUInt32Argument.
101template <typename AttrInfo>
102static bool checkPositiveIntArgument(Sema &S, const AttrInfo &AI, const Expr *Expr,
103 int &Val, unsigned Idx = UINT_MAX) {
104 uint32_t UVal;
105 if (!S.checkUInt32Argument(AI, Expr, UVal, Idx))
106 return false;
107
108 if (UVal > (uint32_t)std::numeric_limits<int>::max()) {
109 llvm::APSInt I(32); // for toString
110 I = UVal;
111 S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
112 << toString(I, 10, false) << 32 << /* Unsigned */ 0;
113 return false;
114 }
115
116 Val = UVal;
117 return true;
118}
119
121 const Expr *E, StringRef &Str,
122 SourceLocation *ArgLocation) {
123 const auto *Literal = dyn_cast<StringLiteral>(E->IgnoreParenCasts());
124 if (ArgLocation)
125 *ArgLocation = E->getBeginLoc();
126
127 if (!Literal || (!Literal->isUnevaluated() && !Literal->isOrdinary())) {
128 Diag(E->getBeginLoc(), diag::err_attribute_argument_type)
129 << CI << AANT_ArgumentString;
130 return false;
131 }
132
133 Str = Literal->getString();
134 return true;
135}
136
137bool Sema::checkStringLiteralArgumentAttr(const ParsedAttr &AL, unsigned ArgNum,
138 StringRef &Str,
139 SourceLocation *ArgLocation) {
140 // Look for identifiers. If we have one emit a hint to fix it to a literal.
141 if (AL.isArgIdent(ArgNum)) {
142 IdentifierLoc *Loc = AL.getArgAsIdent(ArgNum);
143 Diag(Loc->getLoc(), diag::err_attribute_argument_type)
144 << AL << AANT_ArgumentString
145 << FixItHint::CreateInsertion(Loc->getLoc(), "\"")
147 Str = Loc->getIdentifierInfo()->getName();
148 if (ArgLocation)
149 *ArgLocation = Loc->getLoc();
150 return true;
151 }
152
153 // Now check for an actual string literal.
154 Expr *ArgExpr = AL.getArgAsExpr(ArgNum);
155 const auto *Literal = dyn_cast<StringLiteral>(ArgExpr->IgnoreParenCasts());
156 if (ArgLocation)
157 *ArgLocation = ArgExpr->getBeginLoc();
158
159 if (!Literal || (!Literal->isUnevaluated() && !Literal->isOrdinary())) {
160 Diag(ArgExpr->getBeginLoc(), diag::err_attribute_argument_type)
161 << AL << AANT_ArgumentString;
162 return false;
163 }
164 Str = Literal->getString();
165 return checkStringLiteralArgumentAttr(AL, ArgExpr, Str, ArgLocation);
166}
167
168/// Check if the passed-in expression is of type int or bool.
169static bool isIntOrBool(Expr *Exp) {
170 QualType QT = Exp->getType();
171 return QT->isBooleanType() || QT->isIntegerType();
172}
173
174
175// Check to see if the type is a smart pointer of some kind. We assume
176// it's a smart pointer if it defines both operator-> and operator*.
178 auto IsOverloadedOperatorPresent = [&S](const RecordDecl *Record,
182 return !Result.empty();
183 };
184
185 bool foundStarOperator = IsOverloadedOperatorPresent(Record, OO_Star);
186 bool foundArrowOperator = IsOverloadedOperatorPresent(Record, OO_Arrow);
187 if (foundStarOperator && foundArrowOperator)
188 return true;
189
190 const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(Record);
191 if (!CXXRecord)
192 return false;
193
194 for (const auto &BaseSpecifier : CXXRecord->bases()) {
195 if (!foundStarOperator)
196 foundStarOperator = IsOverloadedOperatorPresent(
197 BaseSpecifier.getType()->getAsRecordDecl(), OO_Star);
198 if (!foundArrowOperator)
199 foundArrowOperator = IsOverloadedOperatorPresent(
200 BaseSpecifier.getType()->getAsRecordDecl(), OO_Arrow);
201 }
202
203 if (foundStarOperator && foundArrowOperator)
204 return true;
205
206 return false;
207}
208
209/// Check if passed in Decl is a pointer type.
210/// Note that this function may produce an error message.
211/// \return true if the Decl is a pointer type; false otherwise
212static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
213 const ParsedAttr &AL) {
214 const auto *VD = cast<ValueDecl>(D);
215 QualType QT = VD->getType();
216 if (QT->isAnyPointerType())
217 return true;
218
219 if (const auto *RD = QT->getAsRecordDecl()) {
220 // If it's an incomplete type, it could be a smart pointer; skip it.
221 // (We don't want to force template instantiation if we can avoid it,
222 // since that would alter the order in which templates are instantiated.)
223 if (!RD->isCompleteDefinition())
224 return true;
225
227 return true;
228 }
229
230 S.Diag(AL.getLoc(), diag::warn_thread_attribute_decl_not_pointer) << AL << QT;
231 return false;
232}
233
234/// Checks that the passed in QualType either is of RecordType or points
235/// to RecordType. Returns the relevant RecordType, null if it does not exit.
237 if (const auto *RD = QT->getAsRecordDecl())
238 return RD;
239
240 // Now check if we point to a record.
241 if (const auto *PT = QT->getAsCanonical<PointerType>())
242 return PT->getPointeeType()->getAsRecordDecl();
243
244 return nullptr;
245}
246
247template <typename AttrType>
248static bool checkRecordDeclForAttr(const RecordDecl *RD) {
249 // Check if the record itself has the attribute.
250 if (RD->hasAttr<AttrType>())
251 return true;
252
253 // Else check if any base classes have the attribute.
254 if (const auto *CRD = dyn_cast<CXXRecordDecl>(RD)) {
255 if (!CRD->forallBases([](const CXXRecordDecl *Base) {
256 return !Base->hasAttr<AttrType>();
257 }))
258 return true;
259 }
260 return false;
261}
262
264 const auto *RD = getRecordDecl(Ty);
265
266 if (!RD)
267 return false;
268
269 // Don't check for the capability if the class hasn't been defined yet.
270 if (!RD->isCompleteDefinition())
271 return true;
272
273 // Allow smart pointers to be used as capability objects.
274 // FIXME -- Check the type that the smart pointer points to.
276 return true;
277
279}
280
282 const auto *RD = getRecordDecl(Ty);
283
284 if (!RD)
285 return false;
286
287 // Don't check for the capability if the class hasn't been defined yet.
288 if (!RD->isCompleteDefinition())
289 return true;
290
292}
293
295 const auto *TD = Ty->getAs<TypedefType>();
296 if (!TD)
297 return false;
298
299 TypedefNameDecl *TN = TD->getDecl();
300 if (!TN)
301 return false;
302
303 return TN->hasAttr<CapabilityAttr>();
304}
305
306static bool typeHasCapability(Sema &S, QualType Ty) {
308 return true;
309
311 return true;
312
313 return false;
314}
315
316static bool isCapabilityExpr(Sema &S, const Expr *Ex) {
317 // Capability expressions are simple expressions involving the boolean logic
318 // operators &&, || or !, a simple DeclRefExpr, CastExpr or a ParenExpr. Once
319 // a DeclRefExpr is found, its type should be checked to determine whether it
320 // is a capability or not.
321
322 if (const auto *E = dyn_cast<CastExpr>(Ex))
323 return isCapabilityExpr(S, E->getSubExpr());
324 else if (const auto *E = dyn_cast<ParenExpr>(Ex))
325 return isCapabilityExpr(S, E->getSubExpr());
326 else if (const auto *E = dyn_cast<UnaryOperator>(Ex)) {
327 if (E->getOpcode() == UO_LNot || E->getOpcode() == UO_AddrOf ||
328 E->getOpcode() == UO_Deref)
329 return isCapabilityExpr(S, E->getSubExpr());
330 return false;
331 } else if (const auto *E = dyn_cast<BinaryOperator>(Ex)) {
332 if (E->getOpcode() == BO_LAnd || E->getOpcode() == BO_LOr)
333 return isCapabilityExpr(S, E->getLHS()) &&
334 isCapabilityExpr(S, E->getRHS());
335 return false;
336 }
337
338 return typeHasCapability(S, Ex->getType());
339}
340
341/// Checks that all attribute arguments, starting from Sidx, resolve to
342/// a capability object.
343/// \param Sidx The attribute argument index to start checking with.
344/// \param ParamIdxOk Whether an argument can be indexing into a function
345/// parameter list.
347 const ParsedAttr &AL,
349 unsigned Sidx = 0,
350 bool ParamIdxOk = false) {
351 if (Sidx == AL.getNumArgs()) {
352 // If we don't have any capability arguments, the attribute implicitly
353 // refers to 'this'. So we need to make sure that 'this' exists, i.e. we're
354 // a non-static method, and that the class is a (scoped) capability.
355 const auto *MD = dyn_cast<const CXXMethodDecl>(D);
356 if (MD && !MD->isStatic()) {
357 const CXXRecordDecl *RD = MD->getParent();
358 // FIXME -- need to check this again on template instantiation
361 S.Diag(AL.getLoc(),
362 diag::warn_thread_attribute_not_on_capability_member)
363 << AL << MD->getParent();
364 } else {
365 S.Diag(AL.getLoc(), diag::warn_thread_attribute_not_on_non_static_member)
366 << AL;
367 }
368 }
369
370 for (unsigned Idx = Sidx; Idx < AL.getNumArgs(); ++Idx) {
371 Expr *ArgExp = AL.getArgAsExpr(Idx);
372
373 if (ArgExp->isTypeDependent()) {
374 // FIXME -- need to check this again on template instantiation
375 Args.push_back(ArgExp);
376 continue;
377 }
378
379 if (const auto *StrLit = dyn_cast<StringLiteral>(ArgExp)) {
380 if (StrLit->getLength() == 0 ||
381 (StrLit->isOrdinary() && StrLit->getString() == "*")) {
382 // Pass empty strings to the analyzer without warnings.
383 // Treat "*" as the universal lock.
384 Args.push_back(ArgExp);
385 continue;
386 }
387
388 // We allow constant strings to be used as a placeholder for expressions
389 // that are not valid C++ syntax, but warn that they are ignored.
390 S.Diag(AL.getLoc(), diag::warn_thread_attribute_ignored) << AL;
391 Args.push_back(ArgExp);
392 continue;
393 }
394
395 QualType ArgTy = ArgExp->getType();
396
397 // A pointer to member expression of the form &MyClass::mu is treated
398 // specially -- we need to look at the type of the member.
399 if (const auto *UOp = dyn_cast<UnaryOperator>(ArgExp))
400 if (UOp->getOpcode() == UO_AddrOf)
401 if (const auto *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr()))
402 if (DRE->getDecl()->isCXXInstanceMember())
403 ArgTy = DRE->getDecl()->getType();
404
405 // First see if we can just cast to record type, or pointer to record type.
406 const auto *RD = getRecordDecl(ArgTy);
407
408 // Now check if we index into a record type function param.
409 if (!RD && ParamIdxOk) {
410 const auto *FD = dyn_cast<FunctionDecl>(D);
411 const auto *IL = dyn_cast<IntegerLiteral>(ArgExp);
412 if(FD && IL) {
413 unsigned int NumParams = FD->getNumParams();
414 llvm::APInt ArgValue = IL->getValue();
415 uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
416 uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
417 if (!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
418 S.Diag(AL.getLoc(),
419 diag::err_attribute_argument_out_of_bounds_extra_info)
420 << AL << Idx + 1 << NumParams;
421 continue;
422 }
423 ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
424 }
425 }
426
427 // If the type does not have a capability, see if the components of the
428 // expression have capabilities. This allows for writing C code where the
429 // capability may be on the type, and the expression is a capability
430 // boolean logic expression. Eg) requires_capability(A || B && !C)
431 if (!typeHasCapability(S, ArgTy) && !isCapabilityExpr(S, ArgExp))
432 S.Diag(AL.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
433 << AL << ArgTy;
434
435 Args.push_back(ArgExp);
436 }
437}
438
439/// True if T (or its pointee, after stripping a top-level reference) is a
440/// function pointer or dependent.
442 T = T.getNonReferenceType();
443 return T->isDependentType() || T->isFunctionPointerType();
444}
445
446/// Checks that thread-safety attributes on variables or fields apply only to
447/// function pointer types.
449 const AttributeCommonInfo &A) {
451 return true;
452 S.Diag(A.getLoc(), diag::warn_thread_attribute_not_on_fun_ptr)
453 << A << (isa<FieldDecl>(VD) ? 1 : 0);
454 return false;
455}
456
458 const ParmVarDecl *ParamDecl,
459 const AttributeCommonInfo &AL) {
460 QualType ParamType = ParamDecl->getType();
461 if (ParamType->isDependentType())
462 return true;
463 if (const auto *RefType = ParamType->getAs<ReferenceType>();
464 RefType &&
465 checkRecordTypeForScopedCapability(S, RefType->getPointeeType()))
466 return true;
467 S.Diag(AL.getLoc(), diag::warn_thread_attribute_not_on_scoped_lockable_param)
468 << AL;
469 return false;
470}
471
472static bool checkThreadSafetyAttrSubject(Sema &S, Decl *D, const ParsedAttr &AL,
473 bool CheckParmVar = false) {
474 const auto *VD = dyn_cast<ValueDecl>(D);
475 if (!VD || isa<FunctionDecl>(VD))
476 return true;
477
478 if (CheckParmVar) {
479 if (const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
480 // A function-pointer parameter is also valid here.
481 if (isFunctionPointerOrDependent(PVD->getType()))
482 return true;
483 return checkFunParamsAreScopedLockable(S, PVD, AL);
484 }
485 }
486
487 return checkThreadSafetyValueDeclIsFunPtr(S, VD, AL);
488}
489
491 if (!isa<AssertCapabilityAttr, AcquireCapabilityAttr,
492 TryAcquireCapabilityAttr, ReleaseCapabilityAttr,
493 RequiresCapabilityAttr, LocksExcludedAttr>(A))
494 return true;
495
496 const auto *VD = dyn_cast<ValueDecl>(D);
497 if (!VD)
498 return true;
499
500 // Parameters of template functions need to be re-checked during
501 // instantiation because their types might have been dependent.
502 if (const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
503 if (isFunctionPointerOrDependent(PVD->getType()))
504 return true;
505 return checkFunParamsAreScopedLockable(*this, PVD, *A);
506 }
507
508 if (isa<FunctionDecl>(VD))
509 return true;
510
511 return checkThreadSafetyValueDeclIsFunPtr(*this, VD, *A);
512}
513
514//===----------------------------------------------------------------------===//
515// Attribute Implementations
516//===----------------------------------------------------------------------===//
517
518static void handlePtGuardedVarAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
519 if (!threadSafetyCheckIsPointer(S, D, AL))
520 return;
521
522 D->addAttr(::new (S.Context) PtGuardedVarAttr(S.Context, AL));
523}
524
525static bool checkGuardedByAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
527 if (!AL.checkAtLeastNumArgs(S, 1))
528 return false;
529
530 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
531 return !Args.empty();
532}
533
534static void handleGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
536 if (!checkGuardedByAttrCommon(S, D, AL, Args))
537 return;
538
539 D->addAttr(::new (S.Context)
540 GuardedByAttr(S.Context, AL, Args.data(), Args.size()));
541}
542
543static void handlePtGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
545 if (!checkGuardedByAttrCommon(S, D, AL, Args))
546 return;
547
548 if (!threadSafetyCheckIsPointer(S, D, AL))
549 return;
550
551 D->addAttr(::new (S.Context)
552 PtGuardedByAttr(S.Context, AL, Args.data(), Args.size()));
553}
554
555static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
557 if (!AL.checkAtLeastNumArgs(S, 1))
558 return false;
559
560 // Check that this attribute only applies to lockable types.
561 QualType QT = cast<ValueDecl>(D)->getType();
562 if (!QT->isDependentType() && !typeHasCapability(S, QT)) {
563 S.Diag(AL.getLoc(), diag::warn_thread_attribute_decl_not_lockable) << AL;
564 return false;
565 }
566
567 // Check that all arguments are lockable objects.
568 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
569 if (Args.empty())
570 return false;
571
572 return true;
573}
574
575static void handleAcquiredAfterAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
577 if (!checkAcquireOrderAttrCommon(S, D, AL, Args))
578 return;
579
580 Expr **StartArg = &Args[0];
581 D->addAttr(::new (S.Context)
582 AcquiredAfterAttr(S.Context, AL, StartArg, Args.size()));
583}
584
585static void handleAcquiredBeforeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
587 if (!checkAcquireOrderAttrCommon(S, D, AL, Args))
588 return;
589
590 Expr **StartArg = &Args[0];
591 D->addAttr(::new (S.Context)
592 AcquiredBeforeAttr(S.Context, AL, StartArg, Args.size()));
593}
594
595static bool checkLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
597 // zero or more arguments ok
598 // check that all arguments are lockable objects
599 checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 0, /*ParamIdxOk=*/true);
600
601 return true;
602}
603
604/// Checks to be sure that the given parameter number is in bounds, and
605/// is an integral type. Will emit appropriate diagnostics if this returns
606/// false.
607///
608/// AttrArgNo is used to actually retrieve the argument, so it's base-0.
609template <typename AttrInfo>
610static bool checkParamIsIntegerType(Sema &S, const Decl *D, const AttrInfo &AI,
611 unsigned AttrArgNo) {
612 assert(AI.isArgExpr(AttrArgNo) && "Expected expression argument");
613 Expr *AttrArg = AI.getArgAsExpr(AttrArgNo);
614 ParamIdx Idx;
615 if (!S.checkFunctionOrMethodParameterIndex(D, AI, AttrArgNo + 1, AttrArg,
616 Idx))
617 return false;
618
620 if (!ParamTy->isIntegerType() && !ParamTy->isCharType()) {
621 SourceLocation SrcLoc = AttrArg->getBeginLoc();
622 S.Diag(SrcLoc, diag::err_attribute_integers_only)
624 return false;
625 }
626 return true;
627}
628
629static void handleAllocSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
630 if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 2))
631 return;
632
634
636 if (!RetTy->isPointerType()) {
637 S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only) << AL;
638 return;
639 }
640
641 const Expr *SizeExpr = AL.getArgAsExpr(0);
642 int SizeArgNoVal;
643 // Parameter indices are 1-indexed, hence Index=1
644 if (!checkPositiveIntArgument(S, AL, SizeExpr, SizeArgNoVal, /*Idx=*/1))
645 return;
646 if (!checkParamIsIntegerType(S, D, AL, /*AttrArgNo=*/0))
647 return;
648 ParamIdx SizeArgNo(SizeArgNoVal, D);
649
650 ParamIdx NumberArgNo;
651 if (AL.getNumArgs() == 2) {
652 const Expr *NumberExpr = AL.getArgAsExpr(1);
653 int Val;
654 // Parameter indices are 1-based, hence Index=2
655 if (!checkPositiveIntArgument(S, AL, NumberExpr, Val, /*Idx=*/2))
656 return;
657 if (!checkParamIsIntegerType(S, D, AL, /*AttrArgNo=*/1))
658 return;
659 NumberArgNo = ParamIdx(Val, D);
660 }
661
662 D->addAttr(::new (S.Context)
663 AllocSizeAttr(S.Context, AL, SizeArgNo, NumberArgNo));
664}
665
666static bool checkTryLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
668 if (!AL.checkAtLeastNumArgs(S, 1))
669 return false;
670
671 if (!isIntOrBool(AL.getArgAsExpr(0))) {
672 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
673 << AL << 1 << AANT_ArgumentIntOrBool;
674 return false;
675 }
676
677 // check that all arguments are lockable objects
678 checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 1);
679
680 return true;
681}
682
683static void handleLockReturnedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
684 // check that the argument is lockable object
686 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
687 unsigned Size = Args.size();
688 if (Size == 0)
689 return;
690
691 D->addAttr(::new (S.Context) LockReturnedAttr(S.Context, AL, Args[0]));
692}
693
694static void handleLocksExcludedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
695 if (!checkThreadSafetyAttrSubject(S, D, AL, /*CheckParmVar=*/true))
696 return;
697
698 if (!AL.checkAtLeastNumArgs(S, 1))
699 return;
700
701 // check that all arguments are lockable objects
703 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
704 unsigned Size = Args.size();
705 if (Size == 0)
706 return;
707 Expr **StartArg = &Args[0];
708
709 D->addAttr(::new (S.Context)
710 LocksExcludedAttr(S.Context, AL, StartArg, Size));
711}
712
713static bool checkFunctionConditionAttr(Sema &S, Decl *D, const ParsedAttr &AL,
714 Expr *&Cond, StringRef &Msg) {
715 Cond = AL.getArgAsExpr(0);
716 if (!Cond->isTypeDependent()) {
718 if (Converted.isInvalid())
719 return false;
720 Cond = Converted.get();
721 }
722
723 if (!S.checkStringLiteralArgumentAttr(AL, 1, Msg))
724 return false;
725
726 if (Msg.empty())
727 Msg = "<no message provided>";
728
730 if (isa<FunctionDecl>(D) && !Cond->isValueDependent() &&
732 Diags)) {
733 S.Diag(AL.getLoc(), diag::err_attr_cond_never_constant_expr) << AL;
734 for (const PartialDiagnosticAt &PDiag : Diags)
735 S.Diag(PDiag.first, PDiag.second);
736 return false;
737 }
738 return true;
739}
740
741static void handleEnableIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
742 S.Diag(AL.getLoc(), diag::ext_clang_enable_if);
743
744 Expr *Cond;
745 StringRef Msg;
746 if (checkFunctionConditionAttr(S, D, AL, Cond, Msg))
747 D->addAttr(::new (S.Context) EnableIfAttr(S.Context, AL, Cond, Msg));
748}
749
750static void handleErrorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
751 StringRef NewUserDiagnostic;
752 if (!S.checkStringLiteralArgumentAttr(AL, 0, NewUserDiagnostic))
753 return;
754 if (ErrorAttr *EA = S.mergeErrorAttr(D, AL, NewUserDiagnostic))
755 D->addAttr(EA);
756}
757
759 const ParsedAttr &AL) {
760 const auto *PD = isa<CXXRecordDecl>(D)
763 if (const auto *RD = dyn_cast<CXXRecordDecl>(PD); RD && RD->isLocalClass()) {
764 S.Diag(AL.getLoc(),
765 diag::warn_attribute_exclude_from_explicit_instantiation_local_class)
766 << AL << /*IsMember=*/!isa<CXXRecordDecl>(D);
767 return;
768 }
769
770 if (auto *DA = getDLLAttr(D); DA && !DA->isInherited()) {
771 S.Diag(DA->getLoc(), diag::warn_dllattr_ignored_exclusion_takes_precedence)
772 << DA << AL;
773 D->dropAttrs<DLLExportAttr, DLLImportAttr>();
774 }
775
776 D->addAttr(::new (S.Context)
777 ExcludeFromExplicitInstantiationAttr(S.Context, AL));
778}
779
780namespace {
781/// Determines if a given Expr references any of the given function's
782/// ParmVarDecls, or the function's implicit `this` parameter (if applicable).
783class ArgumentDependenceChecker : public DynamicRecursiveASTVisitor {
784#ifndef NDEBUG
785 const CXXRecordDecl *ClassType;
786#endif
787 llvm::SmallPtrSet<const ParmVarDecl *, 16> Parms;
788 bool Result;
789
790public:
791 ArgumentDependenceChecker(const FunctionDecl *FD) {
792#ifndef NDEBUG
793 if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
794 ClassType = MD->getParent();
795 else
796 ClassType = nullptr;
797#endif
798 Parms.insert(FD->param_begin(), FD->param_end());
799 }
800
801 bool referencesArgs(Expr *E) {
802 Result = false;
803 TraverseStmt(E);
804 return Result;
805 }
806
807 bool VisitCXXThisExpr(CXXThisExpr *E) override {
808 assert(E->getType()->getPointeeCXXRecordDecl() == ClassType &&
809 "`this` doesn't refer to the enclosing class?");
810 Result = true;
811 return false;
812 }
813
814 bool VisitDeclRefExpr(DeclRefExpr *DRE) override {
815 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
816 if (Parms.count(PVD)) {
817 Result = true;
818 return false;
819 }
820 return true;
821 }
822};
823}
824
826 const ParsedAttr &AL) {
827 const auto *DeclFD = cast<FunctionDecl>(D);
828
829 if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(DeclFD))
830 if (!MethodDecl->isStatic()) {
831 S.Diag(AL.getLoc(), diag::err_attribute_no_member_function) << AL;
832 return;
833 }
834
835 auto DiagnoseType = [&](unsigned Index, AttributeArgumentNType T) {
836 SourceLocation Loc = [&]() {
837 auto Union = AL.getArg(Index - 1);
838 if (auto *E = dyn_cast<Expr *>(Union))
839 return E->getBeginLoc();
840 return cast<IdentifierLoc *>(Union)->getLoc();
841 }();
842
843 S.Diag(Loc, diag::err_attribute_argument_n_type) << AL << Index << T;
844 };
845
846 FunctionDecl *AttrFD = [&]() -> FunctionDecl * {
847 if (!AL.isArgExpr(0))
848 return nullptr;
849 auto *F = dyn_cast_if_present<DeclRefExpr>(AL.getArgAsExpr(0));
850 if (!F)
851 return nullptr;
852 return dyn_cast_if_present<FunctionDecl>(F->getFoundDecl());
853 }();
854
855 if (!AttrFD || !AttrFD->getBuiltinID(true)) {
856 DiagnoseType(1, AANT_ArgumentBuiltinFunction);
857 return;
858 }
859
860 if (AttrFD->getNumParams() != AL.getNumArgs() - 1) {
861 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments_for)
862 << AL << AttrFD << AttrFD->getNumParams();
863 return;
864 }
865
867
868 for (unsigned I = 1; I < AL.getNumArgs(); ++I) {
869 if (!AL.isArgExpr(I)) {
870 DiagnoseType(I + 1, AANT_ArgumentIntegerConstant);
871 return;
872 }
873
874 const Expr *IndexExpr = AL.getArgAsExpr(I);
875 uint32_t Index;
876
877 if (!S.checkUInt32Argument(AL, IndexExpr, Index, I + 1, false))
878 return;
879
880 if (Index > DeclFD->getNumParams()) {
881 S.Diag(AL.getLoc(), diag::err_attribute_bounds_for_function)
882 << AL << Index << DeclFD << DeclFD->getNumParams();
883 return;
884 }
885
886 QualType T1 = AttrFD->getParamDecl(I - 1)->getType();
887 QualType T2 = DeclFD->getParamDecl(Index - 1)->getType();
888
891 S.Diag(IndexExpr->getBeginLoc(), diag::err_attribute_parameter_types)
892 << AL << Index << DeclFD << T2 << I << AttrFD << T1;
893 return;
894 }
895
896 Indices.push_back(Index - 1);
897 }
898
899 D->addAttr(::new (S.Context) DiagnoseAsBuiltinAttr(
900 S.Context, AL, AttrFD, Indices.data(), Indices.size()));
901}
902
903static void handleDiagnoseIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
904 S.Diag(AL.getLoc(), diag::ext_clang_diagnose_if);
905
906 Expr *Cond;
907 StringRef Msg;
908 if (!checkFunctionConditionAttr(S, D, AL, Cond, Msg))
909 return;
910
911 StringRef DefaultSevStr;
912 if (!S.checkStringLiteralArgumentAttr(AL, 2, DefaultSevStr))
913 return;
914
915 DiagnoseIfAttr::DefaultSeverity DefaultSev;
916 if (!DiagnoseIfAttr::ConvertStrToDefaultSeverity(DefaultSevStr, DefaultSev)) {
917 S.Diag(AL.getArgAsExpr(2)->getBeginLoc(),
918 diag::err_diagnose_if_invalid_diagnostic_type);
919 return;
920 }
921
922 StringRef WarningGroup;
923 if (AL.getNumArgs() > 3) {
924 if (!S.checkStringLiteralArgumentAttr(AL, 3, WarningGroup))
925 return;
926 if (WarningGroup.empty() ||
927 !S.getDiagnostics().getDiagnosticIDs()->getGroupForWarningOption(
928 WarningGroup)) {
929 S.Diag(AL.getArgAsExpr(3)->getBeginLoc(),
930 diag::err_diagnose_if_unknown_warning)
931 << WarningGroup;
932 return;
933 }
934 }
935
936 bool ArgDependent = false;
937 if (const auto *FD = dyn_cast<FunctionDecl>(D))
938 ArgDependent = ArgumentDependenceChecker(FD).referencesArgs(Cond);
939 D->addAttr(::new (S.Context) DiagnoseIfAttr(
940 S.Context, AL, Cond, Msg, DefaultSev, WarningGroup, ArgDependent,
941 cast<NamedDecl>(D)));
942}
943
945 const ParsedAttr &Attrs) {
946 if (hasDeclarator(D))
947 return;
948
949 if (!isa<ObjCMethodDecl>(D)) {
950 S.Diag(Attrs.getLoc(), diag::warn_attribute_wrong_decl_type)
951 << Attrs << Attrs.isRegularKeywordAttribute()
953 return;
954 }
955
956 D->addAttr(::new (S.Context) CFIUncheckedCalleeAttr(S.Context, Attrs));
957}
958
959static void handleNoBuiltinAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
960 static constexpr const StringRef kWildcard = "*";
961
963 bool HasWildcard = false;
964
965 const auto AddBuiltinName = [&Names, &HasWildcard](StringRef Name) {
966 if (Name == kWildcard)
967 HasWildcard = true;
968 Names.push_back(Name);
969 };
970
971 // Add previously defined attributes.
972 if (const auto *NBA = D->getAttr<NoBuiltinAttr>())
973 for (StringRef BuiltinName : NBA->builtinNames())
974 AddBuiltinName(BuiltinName);
975
976 // Add current attributes.
977 if (AL.getNumArgs() == 0)
978 AddBuiltinName(kWildcard);
979 else
980 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
981 StringRef BuiltinName;
982 SourceLocation LiteralLoc;
983 if (!S.checkStringLiteralArgumentAttr(AL, I, BuiltinName, &LiteralLoc))
984 return;
985
986 if (Builtin::Context::isBuiltinFunc(BuiltinName))
987 AddBuiltinName(BuiltinName);
988 else
989 S.Diag(LiteralLoc, diag::warn_attribute_no_builtin_invalid_builtin_name)
990 << BuiltinName << AL;
991 }
992
993 // Repeating the same attribute is fine.
994 llvm::sort(Names);
995 Names.erase(llvm::unique(Names), Names.end());
996
997 // Empty no_builtin must be on its own.
998 if (HasWildcard && Names.size() > 1)
999 S.Diag(D->getLocation(),
1000 diag::err_attribute_no_builtin_wildcard_or_builtin_name)
1001 << AL;
1002
1003 if (D->hasAttr<NoBuiltinAttr>())
1004 D->dropAttr<NoBuiltinAttr>();
1005 D->addAttr(::new (S.Context)
1006 NoBuiltinAttr(S.Context, AL, Names.data(), Names.size()));
1007}
1008
1009static void handlePassObjectSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1010 if (D->hasAttr<PassObjectSizeAttr>()) {
1011 S.Diag(D->getBeginLoc(), diag::err_attribute_only_once_per_parameter) << AL;
1012 return;
1013 }
1014
1015 Expr *E = AL.getArgAsExpr(0);
1016 uint32_t Type;
1017 if (!S.checkUInt32Argument(AL, E, Type, /*Idx=*/1))
1018 return;
1019
1020 // pass_object_size's argument is passed in as the second argument of
1021 // __builtin_object_size. So, it has the same constraints as that second
1022 // argument; namely, it must be in the range [0, 3].
1023 if (Type > 3) {
1024 S.Diag(E->getBeginLoc(), diag::err_attribute_argument_out_of_range)
1025 << AL << 0 << 3 << E->getSourceRange();
1026 return;
1027 }
1028
1029 // pass_object_size is only supported on constant pointer parameters; as a
1030 // kindness to users, we allow the parameter to be non-const for declarations.
1031 // At this point, we have no clue if `D` belongs to a function declaration or
1032 // definition, so we defer the constness check until later.
1033 if (!cast<ParmVarDecl>(D)->getType()->isPointerType()) {
1034 S.Diag(D->getBeginLoc(), diag::err_attribute_pointers_only) << AL << 1;
1035 return;
1036 }
1037
1038 D->addAttr(::new (S.Context) PassObjectSizeAttr(S.Context, AL, (int)Type));
1039}
1040
1041static void handleConsumableAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1042 ConsumableAttr::ConsumedState DefaultState;
1043
1044 if (AL.isArgIdent(0)) {
1045 IdentifierLoc *IL = AL.getArgAsIdent(0);
1046 if (!ConsumableAttr::ConvertStrToConsumedState(
1047 IL->getIdentifierInfo()->getName(), DefaultState)) {
1048 S.Diag(IL->getLoc(), diag::warn_attribute_type_not_supported)
1049 << AL << IL->getIdentifierInfo();
1050 return;
1051 }
1052 } else {
1053 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1054 << AL << AANT_ArgumentIdentifier;
1055 return;
1056 }
1057
1058 D->addAttr(::new (S.Context) ConsumableAttr(S.Context, AL, DefaultState));
1059}
1060
1062 const ParsedAttr &AL) {
1064
1065 if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) {
1066 if (!RD->hasAttr<ConsumableAttr>()) {
1067 S.Diag(AL.getLoc(), diag::warn_attr_on_unconsumable_class) << RD;
1068
1069 return false;
1070 }
1071 }
1072
1073 return true;
1074}
1075
1076static void handleCallableWhenAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1077 if (!AL.checkAtLeastNumArgs(S, 1))
1078 return;
1079
1081 return;
1082
1084 for (unsigned ArgIndex = 0; ArgIndex < AL.getNumArgs(); ++ArgIndex) {
1085 CallableWhenAttr::ConsumedState CallableState;
1086
1087 StringRef StateString;
1088 SourceLocation Loc;
1089 if (AL.isArgIdent(ArgIndex)) {
1090 IdentifierLoc *Ident = AL.getArgAsIdent(ArgIndex);
1091 StateString = Ident->getIdentifierInfo()->getName();
1092 Loc = Ident->getLoc();
1093 } else {
1094 if (!S.checkStringLiteralArgumentAttr(AL, ArgIndex, StateString, &Loc))
1095 return;
1096 }
1097
1098 if (!CallableWhenAttr::ConvertStrToConsumedState(StateString,
1099 CallableState)) {
1100 S.Diag(Loc, diag::warn_attribute_type_not_supported) << AL << StateString;
1101 return;
1102 }
1103
1104 States.push_back(CallableState);
1105 }
1106
1107 D->addAttr(::new (S.Context)
1108 CallableWhenAttr(S.Context, AL, States.data(), States.size()));
1109}
1110
1111static void handleParamTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1112 ParamTypestateAttr::ConsumedState ParamState;
1113
1114 if (AL.isArgIdent(0)) {
1115 IdentifierLoc *Ident = AL.getArgAsIdent(0);
1116 StringRef StateString = Ident->getIdentifierInfo()->getName();
1117
1118 if (!ParamTypestateAttr::ConvertStrToConsumedState(StateString,
1119 ParamState)) {
1120 S.Diag(Ident->getLoc(), diag::warn_attribute_type_not_supported)
1121 << AL << StateString;
1122 return;
1123 }
1124 } else {
1125 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1126 << AL << AANT_ArgumentIdentifier;
1127 return;
1128 }
1129
1130 // FIXME: This check is currently being done in the analysis. It can be
1131 // enabled here only after the parser propagates attributes at
1132 // template specialization definition, not declaration.
1133 //QualType ReturnType = cast<ParmVarDecl>(D)->getType();
1134 //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1135 //
1136 //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1137 // S.Diag(AL.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1138 // ReturnType.getAsString();
1139 // return;
1140 //}
1141
1142 D->addAttr(::new (S.Context) ParamTypestateAttr(S.Context, AL, ParamState));
1143}
1144
1145static void handleReturnTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1146 ReturnTypestateAttr::ConsumedState ReturnState;
1147
1148 if (AL.isArgIdent(0)) {
1149 IdentifierLoc *IL = AL.getArgAsIdent(0);
1150 if (!ReturnTypestateAttr::ConvertStrToConsumedState(
1151 IL->getIdentifierInfo()->getName(), ReturnState)) {
1152 S.Diag(IL->getLoc(), diag::warn_attribute_type_not_supported)
1153 << AL << IL->getIdentifierInfo();
1154 return;
1155 }
1156 } else {
1157 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1158 << AL << AANT_ArgumentIdentifier;
1159 return;
1160 }
1161
1162 // FIXME: This check is currently being done in the analysis. It can be
1163 // enabled here only after the parser propagates attributes at
1164 // template specialization definition, not declaration.
1165 // QualType ReturnType;
1166 //
1167 // if (const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D)) {
1168 // ReturnType = Param->getType();
1169 //
1170 //} else if (const CXXConstructorDecl *Constructor =
1171 // dyn_cast<CXXConstructorDecl>(D)) {
1172 // ReturnType = Constructor->getFunctionObjectParameterType();
1173 //
1174 //} else {
1175 //
1176 // ReturnType = cast<FunctionDecl>(D)->getCallResultType();
1177 //}
1178 //
1179 // const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1180 //
1181 // if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1182 // S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1183 // ReturnType.getAsString();
1184 // return;
1185 //}
1186
1187 D->addAttr(::new (S.Context) ReturnTypestateAttr(S.Context, AL, ReturnState));
1188}
1189
1190static void handleSetTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1192 return;
1193
1194 SetTypestateAttr::ConsumedState NewState;
1195 if (AL.isArgIdent(0)) {
1196 IdentifierLoc *Ident = AL.getArgAsIdent(0);
1197 StringRef Param = Ident->getIdentifierInfo()->getName();
1198 if (!SetTypestateAttr::ConvertStrToConsumedState(Param, NewState)) {
1199 S.Diag(Ident->getLoc(), diag::warn_attribute_type_not_supported)
1200 << AL << Param;
1201 return;
1202 }
1203 } else {
1204 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1205 << AL << AANT_ArgumentIdentifier;
1206 return;
1207 }
1208
1209 D->addAttr(::new (S.Context) SetTypestateAttr(S.Context, AL, NewState));
1210}
1211
1212static void handleTestTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1214 return;
1215
1216 TestTypestateAttr::ConsumedState TestState;
1217 if (AL.isArgIdent(0)) {
1218 IdentifierLoc *Ident = AL.getArgAsIdent(0);
1219 StringRef Param = Ident->getIdentifierInfo()->getName();
1220 if (!TestTypestateAttr::ConvertStrToConsumedState(Param, TestState)) {
1221 S.Diag(Ident->getLoc(), diag::warn_attribute_type_not_supported)
1222 << AL << Param;
1223 return;
1224 }
1225 } else {
1226 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1227 << AL << AANT_ArgumentIdentifier;
1228 return;
1229 }
1230
1231 D->addAttr(::new (S.Context) TestTypestateAttr(S.Context, AL, TestState));
1232}
1233
1234static void handleExtVectorTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1235 // Remember this typedef decl, we will need it later for diagnostics.
1236 if (isa<TypedefNameDecl>(D))
1238}
1239
1240static void handlePackedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1241 if (auto *TD = dyn_cast<TagDecl>(D))
1242 TD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
1243 else if (auto *FD = dyn_cast<FieldDecl>(D)) {
1244 bool BitfieldByteAligned = (!FD->getType()->isDependentType() &&
1245 !FD->getType()->isIncompleteType() &&
1246 FD->isBitField() &&
1247 S.Context.getTypeAlign(FD->getType()) <= 8);
1248
1249 if (S.getASTContext().getTargetInfo().getTriple().isPS()) {
1250 if (BitfieldByteAligned)
1251 // The PS4/PS5 targets need to maintain ABI backwards compatibility.
1252 S.Diag(AL.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
1253 << AL << FD->getType();
1254 else
1255 FD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
1256 } else {
1257 // Report warning about changed offset in the newer compiler versions.
1258 if (BitfieldByteAligned)
1259 S.Diag(AL.getLoc(), diag::warn_attribute_packed_for_bitfield);
1260
1261 FD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
1262 }
1263
1264 } else
1265 S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
1266}
1267
1268static void handlePreferredName(Sema &S, Decl *D, const ParsedAttr &AL) {
1269 auto *RD = cast<CXXRecordDecl>(D);
1270 ClassTemplateDecl *CTD = RD->getDescribedClassTemplate();
1271 assert(CTD && "attribute does not appertain to this declaration");
1272
1273 ParsedType PT = AL.getTypeArg();
1274 TypeSourceInfo *TSI = nullptr;
1275 QualType T = S.GetTypeFromParser(PT, &TSI);
1276 if (!TSI)
1277 TSI = S.Context.getTrivialTypeSourceInfo(T, AL.getLoc());
1278
1279 if (!T.hasQualifiers() && T->isTypedefNameType()) {
1280 // Find the template name, if this type names a template specialization.
1281 const TemplateDecl *Template = nullptr;
1282 if (const auto *CTSD = dyn_cast_if_present<ClassTemplateSpecializationDecl>(
1283 T->getAsCXXRecordDecl())) {
1284 Template = CTSD->getSpecializedTemplate();
1285 } else if (const auto *TST = T->getAs<TemplateSpecializationType>()) {
1286 while (TST && TST->isTypeAlias())
1287 TST = TST->getAliasedType()->getAs<TemplateSpecializationType>();
1288 if (TST)
1289 Template = TST->getTemplateName().getAsTemplateDecl();
1290 }
1291
1292 if (Template && declaresSameEntity(Template, CTD)) {
1293 D->addAttr(::new (S.Context) PreferredNameAttr(S.Context, AL, TSI));
1294 return;
1295 }
1296 }
1297
1298 S.Diag(AL.getLoc(), diag::err_attribute_not_typedef_for_specialization)
1299 << T << AL << CTD;
1300 if (const auto *TT = T->getAs<TypedefType>())
1301 S.Diag(TT->getDecl()->getLocation(), diag::note_entity_declared_at)
1302 << TT->getDecl();
1303}
1304
1305static void handleNoSpecializations(Sema &S, Decl *D, const ParsedAttr &AL) {
1306 StringRef Message;
1307 if (AL.getNumArgs() != 0)
1308 S.checkStringLiteralArgumentAttr(AL, 0, Message);
1310 NoSpecializationsAttr::Create(S.Context, Message, AL));
1311}
1312
1314 if (T->isDependentType())
1315 return true;
1316 if (RefOkay) {
1317 if (T->isReferenceType())
1318 return true;
1319 } else {
1320 T = T.getNonReferenceType();
1321 }
1322
1323 // The nonnull attribute, and other similar attributes, can be applied to a
1324 // transparent union that contains a pointer type.
1325 if (const RecordType *UT = T->getAsUnionType()) {
1326 RecordDecl *UD = UT->getDecl()->getDefinitionOrSelf();
1327 if (UD->hasAttr<TransparentUnionAttr>()) {
1328 for (const auto *I : UD->fields()) {
1329 QualType QT = I->getType();
1330 if (QT->isAnyPointerType() || QT->isBlockPointerType())
1331 return true;
1332 }
1333 }
1334 }
1335
1336 return T->isAnyPointerType() || T->isBlockPointerType();
1337}
1338
1339static bool attrNonNullArgCheck(Sema &S, QualType T, const ParsedAttr &AL,
1340 SourceRange AttrParmRange,
1341 SourceRange TypeRange,
1342 bool isReturnValue = false) {
1343 if (!S.isValidPointerAttrType(T)) {
1344 if (isReturnValue)
1345 S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only)
1346 << AL << AttrParmRange << TypeRange;
1347 else
1348 S.Diag(AL.getLoc(), diag::warn_attribute_pointers_only)
1349 << AL << AttrParmRange << TypeRange << 0;
1350 return false;
1351 }
1352 return true;
1353}
1354
1355static void handleNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1356 SmallVector<ParamIdx, 8> NonNullArgs;
1357 for (unsigned I = 0; I < AL.getNumArgs(); ++I) {
1358 Expr *Ex = AL.getArgAsExpr(I);
1359 ParamIdx Idx;
1361 D, AL, I + 1, Ex, Idx,
1362 /*CanIndexImplicitThis=*/false,
1363 /*CanIndexVariadicArguments=*/true))
1364 return;
1365
1366 // Is the function argument a pointer type?
1370 Ex->getSourceRange(),
1372 continue;
1373
1374 NonNullArgs.push_back(Idx);
1375 }
1376
1377 // If no arguments were specified to __attribute__((nonnull)) then all pointer
1378 // arguments have a nonnull attribute; warn if there aren't any. Skip this
1379 // check if the attribute came from a macro expansion or a template
1380 // instantiation.
1381 if (NonNullArgs.empty() && AL.getLoc().isFileID() &&
1383 bool AnyPointers = isFunctionOrMethodVariadic(D);
1384 for (unsigned I = 0, E = getFunctionOrMethodNumParams(D);
1385 I != E && !AnyPointers; ++I) {
1387 if (S.isValidPointerAttrType(T))
1388 AnyPointers = true;
1389 }
1390
1391 if (!AnyPointers)
1392 S.Diag(AL.getLoc(), diag::warn_attribute_nonnull_no_pointers);
1393 }
1394
1395 ParamIdx *Start = NonNullArgs.data();
1396 unsigned Size = NonNullArgs.size();
1397 llvm::array_pod_sort(Start, Start + Size);
1398 D->addAttr(::new (S.Context) NonNullAttr(S.Context, AL, Start, Size));
1399}
1400
1402 const ParsedAttr &AL) {
1403 if (AL.getNumArgs() > 0) {
1404 if (D->getFunctionType()) {
1405 handleNonNullAttr(S, D, AL);
1406 } else {
1407 S.Diag(AL.getLoc(), diag::warn_attribute_nonnull_parm_no_args)
1408 << D->getSourceRange();
1409 }
1410 return;
1411 }
1412
1413 // Is the argument a pointer type?
1414 if (!attrNonNullArgCheck(S, D->getType(), AL, SourceRange(),
1415 D->getSourceRange()))
1416 return;
1417
1418 D->addAttr(::new (S.Context) NonNullAttr(S.Context, AL, nullptr, 0));
1419}
1420
1421static void handleReturnsNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1424 if (!attrNonNullArgCheck(S, ResultType, AL, SourceRange(), SR,
1425 /* isReturnValue */ true))
1426 return;
1427
1428 D->addAttr(::new (S.Context) ReturnsNonNullAttr(S.Context, AL));
1429}
1430
1431static void handleNoEscapeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1432 if (D->isInvalidDecl())
1433 return;
1434
1435 // noescape only applies to pointer types.
1436 QualType T = cast<ParmVarDecl>(D)->getType();
1437 if (!S.isValidPointerAttrType(T, /* RefOkay */ true)) {
1438 S.Diag(AL.getLoc(), diag::warn_attribute_pointers_only)
1439 << AL << AL.getRange() << 0;
1440 return;
1441 }
1442
1443 D->addAttr(::new (S.Context) NoEscapeAttr(S.Context, AL));
1444}
1445
1446static void handleAssumeAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1447 Expr *E = AL.getArgAsExpr(0),
1448 *OE = AL.getNumArgs() > 1 ? AL.getArgAsExpr(1) : nullptr;
1449 S.AddAssumeAlignedAttr(D, AL, E, OE);
1450}
1451
1452static void handleAllocAlignAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1453 S.AddAllocAlignAttr(D, AL, AL.getArgAsExpr(0));
1454}
1455
1457 Expr *OE) {
1460 SourceLocation AttrLoc = CI.getLoc();
1461
1462 if (!isValidPointerAttrType(ResultType, /* RefOkay */ true)) {
1463 Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)
1464 << CI << CI.getRange() << SR;
1465 return;
1466 }
1467
1468 if (!E->isValueDependent()) {
1469 std::optional<llvm::APSInt> I = llvm::APSInt(64);
1470 if (!(I = E->getIntegerConstantExpr(Context))) {
1471 if (OE)
1472 Diag(AttrLoc, diag::err_attribute_argument_n_type)
1473 << CI << 1 << AANT_ArgumentIntegerConstant << E->getSourceRange();
1474 else
1475 Diag(AttrLoc, diag::err_attribute_argument_type)
1477 return;
1478 }
1479
1480 if (!I->isPowerOf2()) {
1481 Diag(AttrLoc, diag::err_alignment_not_power_of_two)
1482 << E->getSourceRange();
1483 return;
1484 }
1485
1486 if (*I > Sema::MaximumAlignment)
1487 Diag(CI.getLoc(), diag::warn_assume_aligned_too_great)
1489 }
1490
1491 if (OE && !OE->isValueDependent() && !OE->isIntegerConstantExpr(Context)) {
1492 Diag(AttrLoc, diag::err_attribute_argument_n_type)
1493 << CI << 2 << AANT_ArgumentIntegerConstant << OE->getSourceRange();
1494 return;
1495 }
1496
1497 D->addAttr(::new (Context) AssumeAlignedAttr(Context, CI, E, OE));
1498}
1499
1501 Expr *ParamExpr) {
1503 SourceLocation AttrLoc = CI.getLoc();
1504
1505 if (!isValidPointerAttrType(ResultType, /* RefOkay */ true)) {
1506 Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)
1508 return;
1509 }
1510
1511 ParamIdx Idx;
1512 const auto *FuncDecl = cast<FunctionDecl>(D);
1513 if (!checkFunctionOrMethodParameterIndex(FuncDecl, CI,
1514 /*AttrArgNum=*/1, ParamExpr, Idx))
1515 return;
1516
1518 if (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
1519 !Ty->isAlignValT()) {
1520 Diag(ParamExpr->getBeginLoc(), diag::err_attribute_integers_only)
1521 << CI << FuncDecl->getParamDecl(Idx.getASTIndex())->getSourceRange();
1522 return;
1523 }
1524
1525 D->addAttr(::new (Context) AllocAlignAttr(Context, CI, Idx));
1526}
1527
1528/// Normalize the attribute, __foo__ becomes foo.
1529/// Returns true if normalization was applied.
1530static bool normalizeName(StringRef &AttrName) {
1531 if (AttrName.size() > 4 && AttrName.starts_with("__") &&
1532 AttrName.ends_with("__")) {
1533 AttrName = AttrName.drop_front(2).drop_back(2);
1534 return true;
1535 }
1536 return false;
1537}
1538
1539static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1540 // This attribute must be applied to a function declaration. The first
1541 // argument to the attribute must be an identifier, the name of the resource,
1542 // for example: malloc. The following arguments must be argument indexes, the
1543 // arguments must be of integer type for Returns, otherwise of pointer type.
1544 // The difference between Holds and Takes is that a pointer may still be used
1545 // after being held. free() should be __attribute((ownership_takes)), whereas
1546 // a list append function may well be __attribute((ownership_holds)).
1547
1548 if (!AL.isArgIdent(0)) {
1549 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
1550 << AL << 1 << AANT_ArgumentIdentifier;
1551 return;
1552 }
1553
1554 // Figure out our Kind.
1555 OwnershipAttr::OwnershipKind K =
1556 OwnershipAttr(S.Context, AL, nullptr, nullptr, 0).getOwnKind();
1557
1558 // Check arguments.
1559 switch (K) {
1560 case OwnershipAttr::Takes:
1561 case OwnershipAttr::Holds:
1562 if (AL.getNumArgs() < 2) {
1563 S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) << AL << 2;
1564 return;
1565 }
1566 break;
1567 case OwnershipAttr::Returns:
1568 if (AL.getNumArgs() > 2) {
1569 S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 2;
1570 return;
1571 }
1572 break;
1573 }
1574
1575 // Allow only pointers to be return type for functions with ownership_returns
1576 // attribute. This matches with current OwnershipAttr::Takes semantics
1577 if (K == OwnershipAttr::Returns &&
1578 !getFunctionOrMethodResultType(D)->isPointerType()) {
1579 S.Diag(AL.getLoc(), diag::err_ownership_takes_return_type) << AL;
1580 return;
1581 }
1582
1584
1585 StringRef ModuleName = Module->getName();
1586 if (normalizeName(ModuleName)) {
1587 Module = &S.PP.getIdentifierTable().get(ModuleName);
1588 }
1589
1590 // Check if the new ownership_returns attribute does not contain
1591 // an index, but previous attributes do.
1592 if (K == OwnershipAttr::Returns && AL.getNumArgs() == 1) {
1593 for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
1594 if (I->getOwnKind() == OwnershipAttr::Returns && I->args_size() > 0) {
1595 S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch)
1596 << I->args_begin()->getSourceIndex() << 0;
1597 S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch)
1598 << 0 << 1;
1599 return;
1600 }
1601 }
1602 }
1603
1604 SmallVector<ParamIdx, 8> OwnershipArgs;
1605 for (unsigned i = 1; i < AL.getNumArgs(); ++i) {
1606 Expr *Ex = AL.getArgAsExpr(i);
1607 ParamIdx Idx;
1608 if (!S.checkFunctionOrMethodParameterIndex(D, AL, i, Ex, Idx))
1609 return;
1610
1611 // Is the function argument a pointer type?
1613 int Err = -1; // No error
1614 switch (K) {
1615 case OwnershipAttr::Takes:
1616 case OwnershipAttr::Holds:
1617 if (!T->isAnyPointerType() && !T->isBlockPointerType())
1618 Err = 0;
1619 break;
1620 case OwnershipAttr::Returns:
1621 if (!T->isIntegerType())
1622 Err = 1;
1623 break;
1624 }
1625 if (-1 != Err) {
1626 S.Diag(AL.getLoc(), diag::err_ownership_type) << AL << Err
1627 << Ex->getSourceRange();
1628 return;
1629 }
1630
1631 // Check we don't have a conflict with another ownership attribute.
1632 for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
1633 // Cannot have two ownership attributes of different kinds for the same
1634 // index.
1635 if (I->getOwnKind() != K && llvm::is_contained(I->args(), Idx)) {
1636 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
1637 << AL << I
1638 << (AL.isRegularKeywordAttribute() ||
1639 I->isRegularKeywordAttribute());
1640 return;
1641 }
1642
1643 if (K == OwnershipAttr::Returns &&
1644 I->getOwnKind() == OwnershipAttr::Returns) {
1645 bool IHasArgs = I->args_size() > 0;
1646
1647 if (!IHasArgs || !llvm::is_contained(I->args(), Idx)) {
1648 unsigned IIdx = IHasArgs ? I->args_begin()->getSourceIndex() : 0;
1649
1650 S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch)
1651 << IIdx << (IHasArgs ? 0 : 1);
1652
1653 S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch)
1654 << Idx.getSourceIndex() << 0 << Ex->getSourceRange();
1655 return;
1656 }
1657 } else if (K == OwnershipAttr::Takes &&
1658 I->getOwnKind() == OwnershipAttr::Takes) {
1659 if (I->getModule()->getName() != ModuleName) {
1660 S.Diag(I->getLocation(), diag::err_ownership_takes_class_mismatch)
1661 << I->getModule()->getName();
1662 S.Diag(AL.getLoc(), diag::note_ownership_takes_class_mismatch)
1663 << ModuleName << Ex->getSourceRange();
1664
1665 return;
1666 }
1667 }
1668 }
1669 OwnershipArgs.push_back(Idx);
1670 }
1671
1672 ParamIdx *Start = OwnershipArgs.data();
1673 unsigned Size = OwnershipArgs.size();
1674 llvm::array_pod_sort(Start, Start + Size);
1675 D->addAttr(::new (S.Context)
1676 OwnershipAttr(S.Context, AL, Module, Start, Size));
1677}
1678
1679static void handleWeakRefAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1680 // Check the attribute arguments.
1681 if (AL.getNumArgs() > 1) {
1682 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
1683 return;
1684 }
1685
1686 // gcc rejects
1687 // class c {
1688 // static int a __attribute__((weakref ("v2")));
1689 // static int b() __attribute__((weakref ("f3")));
1690 // };
1691 // and ignores the attributes of
1692 // void f(void) {
1693 // static int a __attribute__((weakref ("v2")));
1694 // }
1695 // we reject them
1696 const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
1697 if (!Ctx->isFileContext()) {
1698 S.Diag(AL.getLoc(), diag::err_attribute_weakref_not_global_context)
1699 << cast<NamedDecl>(D);
1700 return;
1701 }
1702
1703 // The GCC manual says
1704 //
1705 // At present, a declaration to which `weakref' is attached can only
1706 // be `static'.
1707 //
1708 // It also says
1709 //
1710 // Without a TARGET,
1711 // given as an argument to `weakref' or to `alias', `weakref' is
1712 // equivalent to `weak'.
1713 //
1714 // gcc 4.4.1 will accept
1715 // int a7 __attribute__((weakref));
1716 // as
1717 // int a7 __attribute__((weak));
1718 // This looks like a bug in gcc. We reject that for now. We should revisit
1719 // it if this behaviour is actually used.
1720
1721 // GCC rejects
1722 // static ((alias ("y"), weakref)).
1723 // Should we? How to check that weakref is before or after alias?
1724
1725 // FIXME: it would be good for us to keep the WeakRefAttr as-written instead
1726 // of transforming it into an AliasAttr. The WeakRefAttr never uses the
1727 // StringRef parameter it was given anyway.
1728 StringRef Str;
1729 if (AL.getNumArgs() && S.checkStringLiteralArgumentAttr(AL, 0, Str))
1730 // GCC will accept anything as the argument of weakref. Should we
1731 // check for an existing decl?
1732 D->addAttr(::new (S.Context) AliasAttr(S.Context, AL, Str));
1733
1734 D->addAttr(::new (S.Context) WeakRefAttr(S.Context, AL));
1735}
1736
1737// Mark alias/ifunc target as used. Due to name mangling, we look up the
1738// demangled name ignoring parameters (not supported by microsoftDemangle
1739// https://github.com/llvm/llvm-project/issues/88825). This should handle the
1740// majority of use cases while leaving namespace scope names unmarked.
1741static void markUsedForAliasOrIfunc(Sema &S, Decl *D, const ParsedAttr &AL,
1742 StringRef Str) {
1743 std::unique_ptr<char, llvm::FreeDeleter> Demangled;
1744 if (S.getASTContext().getCXXABIKind() != TargetCXXABI::Microsoft)
1745 Demangled.reset(llvm::itaniumDemangle(Str, /*ParseParams=*/false));
1746 std::unique_ptr<MangleContext> MC(S.Context.createMangleContext());
1747 SmallString<256> Name;
1748
1750 &S.Context.Idents.get(Demangled ? Demangled.get() : Str), AL.getLoc());
1752 if (S.LookupName(LR, S.TUScope)) {
1753 for (NamedDecl *ND : LR) {
1754 if (!isa<FunctionDecl>(ND) && !isa<VarDecl>(ND))
1755 continue;
1756 if (MC->shouldMangleDeclName(ND)) {
1757 llvm::raw_svector_ostream Out(Name);
1758 Name.clear();
1759 MC->mangleName(GlobalDecl(ND), Out);
1760 } else {
1761 Name = ND->getIdentifier()->getName();
1762 }
1763 if (Name == Str)
1764 ND->markUsed(S.Context);
1765 }
1766 }
1767}
1768
1769static void handleIFuncAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1770 StringRef Str;
1771 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
1772 return;
1773
1774 // Aliases should be on declarations, not definitions.
1775 const auto *FD = cast<FunctionDecl>(D);
1776 if (FD->isThisDeclarationADefinition()) {
1777 S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 1;
1778 return;
1779 }
1780
1781 markUsedForAliasOrIfunc(S, D, AL, Str);
1782 D->addAttr(::new (S.Context) IFuncAttr(S.Context, AL, Str));
1783}
1784
1785static void handleAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1786 StringRef Str;
1787 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
1788 return;
1789
1790 if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
1791 S.Diag(AL.getLoc(), diag::err_alias_not_supported_on_darwin);
1792 return;
1793 }
1794
1795 if (S.Context.getTargetInfo().getTriple().isNVPTX()) {
1796 CudaVersion Version =
1798 if (Version != CudaVersion::UNKNOWN && Version < CudaVersion::CUDA_100)
1799 S.Diag(AL.getLoc(), diag::err_alias_not_supported_on_nvptx);
1800 }
1801
1802 // Aliases should be on declarations, not definitions.
1803 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
1804 if (FD->isThisDeclarationADefinition()) {
1805 S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 0;
1806 return;
1807 }
1808 } else {
1809 const auto *VD = cast<VarDecl>(D);
1810 if (VD->isThisDeclarationADefinition() && VD->isExternallyVisible()) {
1811 S.Diag(AL.getLoc(), diag::err_alias_is_definition) << VD << 0;
1812 return;
1813 }
1814 }
1815
1816 markUsedForAliasOrIfunc(S, D, AL, Str);
1817 D->addAttr(::new (S.Context) AliasAttr(S.Context, AL, Str));
1818}
1819
1820static void handleTLSModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1821 StringRef Model;
1822 SourceLocation LiteralLoc;
1823 // Check that it is a string.
1824 if (!S.checkStringLiteralArgumentAttr(AL, 0, Model, &LiteralLoc))
1825 return;
1826
1827 // Check that the value.
1828 if (Model != "global-dynamic" && Model != "local-dynamic"
1829 && Model != "initial-exec" && Model != "local-exec") {
1830 S.Diag(LiteralLoc, diag::err_attr_tlsmodel_arg);
1831 return;
1832 }
1833
1834 D->addAttr(::new (S.Context) TLSModelAttr(S.Context, AL, Model));
1835}
1836
1837static void handleRestrictAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1839 if (!ResultType->isAnyPointerType() && !ResultType->isBlockPointerType()) {
1840 S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only)
1842 return;
1843 }
1844
1845 if (AL.getNumArgs() == 0) {
1846 D->addAttr(::new (S.Context) RestrictAttr(S.Context, AL));
1847 return;
1848 }
1849
1850 if (AL.getAttributeSpellingListIndex() == RestrictAttr::Declspec_restrict) {
1851 // __declspec(restrict) accepts no arguments
1852 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 0;
1853 return;
1854 }
1855
1856 // [[gnu::malloc(deallocator)]] with args specifies a deallocator function
1857 Expr *DeallocE = AL.getArgAsExpr(0);
1858 SourceLocation DeallocLoc = DeallocE->getExprLoc();
1859 FunctionDecl *DeallocFD = nullptr;
1860 DeclarationNameInfo DeallocNI;
1861
1862 if (auto *DRE = dyn_cast<DeclRefExpr>(DeallocE)) {
1863 DeallocFD = dyn_cast<FunctionDecl>(DRE->getDecl());
1864 DeallocNI = DRE->getNameInfo();
1865 if (!DeallocFD) {
1866 S.Diag(DeallocLoc, diag::err_attribute_malloc_arg_not_function)
1867 << 1 << DeallocNI.getName();
1868 return;
1869 }
1870 } else if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(DeallocE)) {
1871 DeallocFD = S.ResolveSingleFunctionTemplateSpecialization(ULE, true);
1872 DeallocNI = ULE->getNameInfo();
1873 if (!DeallocFD) {
1874 S.Diag(DeallocLoc, diag::err_attribute_malloc_arg_not_function)
1875 << 2 << DeallocNI.getName();
1876 if (ULE->getType() == S.Context.OverloadTy)
1878 return;
1879 }
1880 } else {
1881 S.Diag(DeallocLoc, diag::err_attribute_malloc_arg_not_function) << 0;
1882 return;
1883 }
1884
1885 // 2nd arg of [[gnu::malloc(deallocator, 2)]] with args specifies the param
1886 // of deallocator that deallocates the pointer (defaults to 1)
1887 ParamIdx DeallocPtrIdx;
1888 if (AL.getNumArgs() == 1) {
1889 DeallocPtrIdx = ParamIdx(1, DeallocFD);
1890
1891 // FIXME: We could probably be better about diagnosing that there IS no
1892 // argument, or that the function doesn't have a prototype, but this is how
1893 // GCC diagnoses this, and is reasonably clear.
1894 if (!DeallocPtrIdx.isValid() || !hasFunctionProto(DeallocFD) ||
1895 getFunctionOrMethodNumParams(DeallocFD) < 1 ||
1896 !getFunctionOrMethodParamType(DeallocFD, DeallocPtrIdx.getASTIndex())
1898 ->isPointerType()) {
1899 S.Diag(DeallocLoc,
1900 diag::err_attribute_malloc_arg_not_function_with_pointer_arg)
1901 << DeallocNI.getName();
1902 return;
1903 }
1904 } else {
1906 DeallocFD, AL, 2, AL.getArgAsExpr(1), DeallocPtrIdx,
1907 /* CanIndexImplicitThis=*/false))
1908 return;
1909
1910 QualType DeallocPtrArgType =
1911 getFunctionOrMethodParamType(DeallocFD, DeallocPtrIdx.getASTIndex());
1912 if (!DeallocPtrArgType.getCanonicalType()->isPointerType()) {
1913 S.Diag(DeallocLoc,
1914 diag::err_attribute_malloc_arg_refers_to_non_pointer_type)
1915 << DeallocPtrIdx.getSourceIndex() << DeallocPtrArgType
1916 << DeallocNI.getName();
1917 return;
1918 }
1919 }
1920
1921 // FIXME: we should add this attribute to Clang's AST, so that clang-analyzer
1922 // can use it, see -Wmismatched-dealloc in GCC for what we can do with this.
1923 S.Diag(AL.getLoc(), diag::warn_attribute_form_ignored) << AL;
1924 D->addAttr(::new (S.Context)
1925 RestrictAttr(S.Context, AL, DeallocE, DeallocPtrIdx));
1926}
1927
1929 const QualType &Ty) {
1930 // Note that there may also be numerous cases of pointer + integer /
1931 // pointer + pointer / integer + pointer structures not actually exhibiting
1932 // a span-like semantics, so sometimes these heuristics expectedly
1933 // lead to false positive results.
1934 auto emitWarning = [this, &CI](unsigned NoteDiagID) {
1935 Diag(CI.getLoc(), diag::warn_attribute_return_span_only) << CI;
1936 return Diag(CI.getLoc(), NoteDiagID);
1937 };
1938 if (Ty->isDependentType())
1939 return false;
1940 // isCompleteType is used to force template class instantiation.
1941 if (!isCompleteType(CI.getLoc(), Ty))
1942 return emitWarning(diag::note_returned_incomplete_type);
1943 const RecordDecl *RD = Ty->getAsRecordDecl();
1944 if (!RD || RD->isUnion())
1945 return emitWarning(diag::note_returned_not_struct);
1946 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
1947 if (CXXRD->getNumBases() > 0) {
1948 return emitWarning(diag::note_type_inherits_from_base);
1949 }
1950 }
1951 auto FieldsBegin = RD->field_begin();
1952 auto FieldsCount = std::distance(FieldsBegin, RD->field_end());
1953 if (FieldsCount != 2)
1954 return emitWarning(diag::note_returned_not_two_field_struct) << FieldsCount;
1955 QualType FirstFieldType = FieldsBegin->getType();
1956 QualType SecondFieldType = std::next(FieldsBegin)->getType();
1957 auto validatePointerType = [](const QualType &T) {
1958 // It must not point to functions.
1959 return T->isPointerType() && !T->isFunctionPointerType();
1960 };
1961 auto checkIntegerType = [this, emitWarning](const QualType &T,
1962 const int FieldNo) -> bool {
1963 const auto *BT = dyn_cast<BuiltinType>(T.getCanonicalType());
1964 if (!BT || !BT->isInteger())
1965 return emitWarning(diag::note_returned_not_integer_field) << FieldNo;
1966 auto IntSize = Context.getTypeSize(Context.IntTy);
1967 if (Context.getTypeSize(BT) < IntSize)
1968 return emitWarning(diag::note_returned_not_wide_enough_field)
1969 << FieldNo << IntSize;
1970 return false;
1971 };
1972 if (validatePointerType(FirstFieldType) &&
1973 validatePointerType(SecondFieldType)) {
1974 // Pointer + pointer.
1975 return false;
1976 } else if (validatePointerType(FirstFieldType)) {
1977 // Pointer + integer?
1978 return checkIntegerType(SecondFieldType, 2);
1979 } else if (validatePointerType(SecondFieldType)) {
1980 // Integer + pointer?
1981 return checkIntegerType(FirstFieldType, 1);
1982 }
1983 return emitWarning(diag::note_returned_not_span_struct);
1984}
1985
1986static void handleMallocSpanAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1988 if (!S.CheckSpanLikeType(AL, ResultType))
1989 D->addAttr(::new (S.Context) MallocSpanAttr(S.Context, AL));
1990}
1991
1992static void handleCPUSpecificAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1993 // Ensure we don't combine these with themselves, since that causes some
1994 // confusing behavior.
1995 if (AL.getParsedKind() == ParsedAttr::AT_CPUDispatch) {
1997 return;
1998
1999 if (const auto *Other = D->getAttr<CPUDispatchAttr>()) {
2000 S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL;
2001 S.Diag(Other->getLocation(), diag::note_conflicting_attribute);
2002 return;
2003 }
2004 } else if (AL.getParsedKind() == ParsedAttr::AT_CPUSpecific) {
2006 return;
2007
2008 if (const auto *Other = D->getAttr<CPUSpecificAttr>()) {
2009 S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL;
2010 S.Diag(Other->getLocation(), diag::note_conflicting_attribute);
2011 return;
2012 }
2013 }
2014
2016
2017 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
2018 if (MD->getParent()->isLambda()) {
2019 S.Diag(AL.getLoc(), diag::err_attribute_dll_lambda) << AL;
2020 return;
2021 }
2022 }
2023
2024 if (!AL.checkAtLeastNumArgs(S, 1))
2025 return;
2026
2028 for (unsigned ArgNo = 0; ArgNo < getNumAttributeArgs(AL); ++ArgNo) {
2029 if (!AL.isArgIdent(ArgNo)) {
2030 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
2031 << AL << AANT_ArgumentIdentifier;
2032 return;
2033 }
2034
2035 IdentifierLoc *CPUArg = AL.getArgAsIdent(ArgNo);
2036 StringRef CPUName = CPUArg->getIdentifierInfo()->getName().trim();
2037
2039 S.Diag(CPUArg->getLoc(), diag::err_invalid_cpu_specific_dispatch_value)
2040 << CPUName << (AL.getKind() == ParsedAttr::AT_CPUDispatch);
2041 return;
2042 }
2043
2045 if (llvm::any_of(CPUs, [CPUName, &Target](const IdentifierInfo *Cur) {
2046 return Target.CPUSpecificManglingCharacter(CPUName) ==
2047 Target.CPUSpecificManglingCharacter(Cur->getName());
2048 })) {
2049 S.Diag(AL.getLoc(), diag::warn_multiversion_duplicate_entries);
2050 return;
2051 }
2052 CPUs.push_back(CPUArg->getIdentifierInfo());
2053 }
2054
2055 FD->setIsMultiVersion(true);
2056 if (AL.getKind() == ParsedAttr::AT_CPUSpecific)
2057 D->addAttr(::new (S.Context)
2058 CPUSpecificAttr(S.Context, AL, CPUs.data(), CPUs.size()));
2059 else
2060 D->addAttr(::new (S.Context)
2061 CPUDispatchAttr(S.Context, AL, CPUs.data(), CPUs.size()));
2062}
2063
2064static void handleCommonAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2065 if (S.LangOpts.CPlusPlus) {
2066 S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)
2068 return;
2069 }
2070
2071 D->addAttr(::new (S.Context) CommonAttr(S.Context, AL));
2072}
2073
2074static void handleNakedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2075 if (AL.isDeclspecAttribute()) {
2076 const auto &Triple = S.getASTContext().getTargetInfo().getTriple();
2077 const auto &Arch = Triple.getArch();
2078 if (Arch != llvm::Triple::x86 &&
2079 (Arch != llvm::Triple::arm && Arch != llvm::Triple::thumb)) {
2080 S.Diag(AL.getLoc(), diag::err_attribute_not_supported_on_arch)
2081 << AL << Triple.getArchName();
2082 return;
2083 }
2084
2085 // This form is not allowed to be written on a member function (static or
2086 // nonstatic) when in Microsoft compatibility mode.
2087 if (S.getLangOpts().MSVCCompat && isa<CXXMethodDecl>(D)) {
2088 S.Diag(AL.getLoc(), diag::err_attribute_wrong_decl_type)
2090 return;
2091 }
2092 }
2093
2094 D->addAttr(::new (S.Context) NakedAttr(S.Context, AL));
2095}
2096
2097// FIXME: This is a best-effort heuristic.
2098// Currently only handles single throw expressions (optionally with
2099// ExprWithCleanups). We could expand this to perform control-flow analysis for
2100// more complex patterns.
2101static bool isKnownToAlwaysThrow(const FunctionDecl *FD) {
2102 if (!FD->hasBody())
2103 return false;
2104 const Stmt *Body = FD->getBody();
2105 const Stmt *OnlyStmt = nullptr;
2106
2107 if (const auto *Compound = dyn_cast<CompoundStmt>(Body)) {
2108 if (Compound->size() != 1)
2109 return false; // More than one statement, can't be known to always throw.
2110 OnlyStmt = *Compound->body_begin();
2111 } else {
2112 OnlyStmt = Body;
2113 }
2114
2115 // Unwrap ExprWithCleanups if necessary.
2116 if (const auto *EWC = dyn_cast<ExprWithCleanups>(OnlyStmt)) {
2117 OnlyStmt = EWC->getSubExpr();
2118 }
2119
2120 if (isa<CXXThrowExpr>(OnlyStmt)) {
2121 const auto *MD = dyn_cast<CXXMethodDecl>(FD);
2122 if (MD && MD->isVirtual()) {
2123 const auto *RD = MD->getParent();
2124 return MD->hasAttr<FinalAttr>() || (RD && RD->isEffectivelyFinal());
2125 }
2126 return true;
2127 }
2128 return false;
2129}
2130
2132 auto *FD = dyn_cast<FunctionDecl>(D);
2133 if (!FD)
2134 return;
2135
2136 // Skip explicit specializations here as they may have
2137 // a user-provided definition that may deliberately differ from the primary
2138 // template. If an explicit specialization truly never returns, the user
2139 // should explicitly mark it with [[noreturn]].
2141 return;
2142
2143 DiagnosticsEngine &Diags = S.getDiagnostics();
2144 if (Diags.isIgnored(diag::warn_falloff_nonvoid, FD->getLocation()) &&
2145 Diags.isIgnored(diag::warn_suggest_noreturn_function, FD->getLocation()))
2146 return;
2147
2148 if (!FD->isNoReturn() && !FD->hasAttr<InferredNoReturnAttr>() &&
2150 FD->addAttr(InferredNoReturnAttr::CreateImplicit(S.Context));
2151
2152 // [[noreturn]] can only be added to lambdas since C++23
2153 if (const auto *MD = dyn_cast<CXXMethodDecl>(FD);
2155 return;
2156
2157 // Emit a diagnostic suggesting the function being marked [[noreturn]].
2158 S.Diag(FD->getLocation(), diag::warn_suggest_noreturn_function)
2159 << /*isFunction=*/0 << FD;
2160 }
2161}
2162
2163static void handleNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
2164 if (hasDeclarator(D)) return;
2165
2166 if (!isa<ObjCMethodDecl>(D)) {
2167 S.Diag(Attrs.getLoc(), diag::warn_attribute_wrong_decl_type)
2168 << Attrs << Attrs.isRegularKeywordAttribute()
2170 return;
2171 }
2172
2173 D->addAttr(::new (S.Context) NoReturnAttr(S.Context, Attrs));
2174}
2175
2176static void handleStandardNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &A) {
2177 // The [[_Noreturn]] spelling is deprecated in C23, so if that was used,
2178 // issue an appropriate diagnostic. However, don't issue a diagnostic if the
2179 // attribute name comes from a macro expansion. We don't want to punish users
2180 // who write [[noreturn]] after including <stdnoreturn.h> (where 'noreturn'
2181 // is defined as a macro which expands to '_Noreturn').
2182 if (!S.getLangOpts().CPlusPlus &&
2183 A.getSemanticSpelling() == CXX11NoReturnAttr::C23_Noreturn &&
2184 !(A.getLoc().isMacroID() &&
2186 S.Diag(A.getLoc(), diag::warn_deprecated_noreturn_spelling) << A.getRange();
2187
2188 D->addAttr(::new (S.Context) CXX11NoReturnAttr(S.Context, A));
2189}
2190
2191static void handleNoCfCheckAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
2192 if (!S.getLangOpts().CFProtectionBranch)
2193 S.Diag(Attrs.getLoc(), diag::warn_nocf_check_attribute_ignored);
2194 else
2196}
2197
2199 if (!Attrs.checkExactlyNumArgs(*this, 0)) {
2200 Attrs.setInvalid();
2201 return true;
2202 }
2203
2204 return false;
2205}
2206
2208 // Check whether the attribute is valid on the current target.
2209 if (!AL.existsInTarget(Context.getTargetInfo())) {
2211 Diag(AL.getLoc(), diag::err_keyword_not_supported_on_target)
2212 << AL << AL.getRange();
2213 else
2215 AL.setInvalid();
2216 return true;
2217 }
2218 return false;
2219}
2220
2221static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2222
2223 // The checking path for 'noreturn' and 'analyzer_noreturn' are different
2224 // because 'analyzer_noreturn' does not impact the type.
2226 ValueDecl *VD = dyn_cast<ValueDecl>(D);
2227 if (!VD || (!VD->getType()->isBlockPointerType() &&
2228 !VD->getType()->isFunctionPointerType())) {
2230 ? diag::err_attribute_wrong_decl_type
2231 : diag::warn_attribute_wrong_decl_type)
2232 << AL << AL.isRegularKeywordAttribute()
2234 return;
2235 }
2236 }
2237
2238 D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(S.Context, AL));
2239}
2240
2241// PS3 PPU-specific.
2242static void handleVecReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2243 /*
2244 Returning a Vector Class in Registers
2245
2246 According to the PPU ABI specifications, a class with a single member of
2247 vector type is returned in memory when used as the return value of a
2248 function.
2249 This results in inefficient code when implementing vector classes. To return
2250 the value in a single vector register, add the vecreturn attribute to the
2251 class definition. This attribute is also applicable to struct types.
2252
2253 Example:
2254
2255 struct Vector
2256 {
2257 __vector float xyzw;
2258 } __attribute__((vecreturn));
2259
2260 Vector Add(Vector lhs, Vector rhs)
2261 {
2262 Vector result;
2263 result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
2264 return result; // This will be returned in a register
2265 }
2266 */
2267 if (VecReturnAttr *A = D->getAttr<VecReturnAttr>()) {
2268 S.Diag(AL.getLoc(), diag::err_repeat_attribute) << A;
2269 return;
2270 }
2271
2272 const auto *R = cast<RecordDecl>(D);
2273 int count = 0;
2274
2275 if (!isa<CXXRecordDecl>(R)) {
2276 S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
2277 return;
2278 }
2279
2280 if (!cast<CXXRecordDecl>(R)->isPOD()) {
2281 S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
2282 return;
2283 }
2284
2285 for (const auto *I : R->fields()) {
2286 if ((count == 1) || !I->getType()->isVectorType()) {
2287 S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
2288 return;
2289 }
2290 count++;
2291 }
2292
2293 D->addAttr(::new (S.Context) VecReturnAttr(S.Context, AL));
2294}
2295
2297 const ParsedAttr &AL) {
2298 if (isa<ParmVarDecl>(D)) {
2299 // [[carries_dependency]] can only be applied to a parameter if it is a
2300 // parameter of a function declaration or lambda.
2302 S.Diag(AL.getLoc(),
2303 diag::err_carries_dependency_param_not_function_decl);
2304 return;
2305 }
2306 }
2307
2308 D->addAttr(::new (S.Context) CarriesDependencyAttr(S.Context, AL));
2309}
2310
2311static void handleUnusedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2312 bool IsCXX17Attr = AL.isCXX11Attribute() && !AL.getScopeName();
2313
2314 // If this is spelled as the standard C++17 attribute, but not in C++17, warn
2315 // about using it as an extension.
2316 if (!S.getLangOpts().CPlusPlus17 && IsCXX17Attr)
2317 S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
2318
2319 D->addAttr(::new (S.Context) UnusedAttr(S.Context, AL));
2320}
2321
2323 const ParsedAttr &AL) {
2324 // If no Expr node exists on the attribute, return a nullptr result (default
2325 // priority to be used). If Expr node exists but is not valid, return an
2326 // invalid result. Otherwise, return the Expr.
2327 Expr *E = nullptr;
2328 if (AL.getNumArgs() == 1) {
2329 E = AL.getArgAsExpr(0);
2330 if (E->isValueDependent()) {
2331 if (!E->isTypeDependent() && !E->getType()->isIntegerType()) {
2332 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
2334 return ExprError();
2335 }
2336 } else {
2337 uint32_t priority;
2338 if (!S.checkUInt32Argument(AL, AL.getArgAsExpr(0), priority)) {
2339 return ExprError();
2340 }
2341 return ConstantExpr::Create(S.Context, E,
2342 APValue(llvm::APSInt::getUnsigned(priority)));
2343 }
2344 }
2345 return E;
2346}
2347
2348static void handleConstructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2349 if (S.getLangOpts().HLSL && AL.getNumArgs()) {
2350 S.Diag(AL.getLoc(), diag::err_hlsl_init_priority_unsupported);
2351 return;
2352 }
2354 if (E.isInvalid())
2355 return;
2356 S.Diag(D->getLocation(), diag::warn_global_constructor)
2357 << D->getSourceRange();
2358 D->addAttr(ConstructorAttr::Create(S.Context, E.get(), AL));
2359}
2360
2361static void handleDestructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2363 if (E.isInvalid())
2364 return;
2365 S.Diag(D->getLocation(), diag::warn_global_destructor) << D->getSourceRange();
2366 D->addAttr(DestructorAttr::Create(S.Context, E.get(), AL));
2367}
2368
2369template <typename AttrTy>
2370static void handleAttrWithMessage(Sema &S, Decl *D, const ParsedAttr &AL) {
2371 // Handle the case where the attribute has a text message.
2372 StringRef Str;
2373 if (AL.getNumArgs() == 1 && !S.checkStringLiteralArgumentAttr(AL, 0, Str))
2374 return;
2375
2376 D->addAttr(::new (S.Context) AttrTy(S.Context, AL, Str));
2377}
2378
2380 const IdentifierInfo *Platform,
2381 VersionTuple Introduced,
2382 VersionTuple Deprecated,
2383 VersionTuple Obsoleted) {
2384 StringRef PlatformName
2385 = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
2386 if (PlatformName.empty())
2387 PlatformName = Platform->getName();
2388
2389 // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
2390 // of these steps are needed).
2391 if (!Introduced.empty() && !Deprecated.empty() &&
2392 !(Introduced <= Deprecated)) {
2393 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2394 << 1 << PlatformName << Deprecated.getAsString()
2395 << 0 << Introduced.getAsString();
2396 return true;
2397 }
2398
2399 if (!Introduced.empty() && !Obsoleted.empty() &&
2400 !(Introduced <= Obsoleted)) {
2401 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2402 << 2 << PlatformName << Obsoleted.getAsString()
2403 << 0 << Introduced.getAsString();
2404 return true;
2405 }
2406
2407 if (!Deprecated.empty() && !Obsoleted.empty() &&
2408 !(Deprecated <= Obsoleted)) {
2409 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2410 << 2 << PlatformName << Obsoleted.getAsString()
2411 << 1 << Deprecated.getAsString();
2412 return true;
2413 }
2414
2415 return false;
2416}
2417
2418/// Check whether the two versions match.
2419///
2420/// If either version tuple is empty, then they are assumed to match. If
2421/// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y.
2422static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y,
2423 bool BeforeIsOkay) {
2424 if (X.empty() || Y.empty())
2425 return true;
2426
2427 if (X == Y)
2428 return true;
2429
2430 if (BeforeIsOkay && X < Y)
2431 return true;
2432
2433 return false;
2434}
2435
2437 NamedDecl *D, const AttributeCommonInfo &CI, const IdentifierInfo *Platform,
2438 bool Implicit, VersionTuple Introduced, VersionTuple Deprecated,
2439 VersionTuple Obsoleted, bool IsUnavailable, StringRef Message,
2440 bool IsStrict, StringRef Replacement, AvailabilityMergeKind AMK,
2441 int Priority, const IdentifierInfo *Environment,
2442 const IdentifierInfo *InferredPlatformII) {
2443 VersionTuple MergedIntroduced = Introduced;
2444 VersionTuple MergedDeprecated = Deprecated;
2445 VersionTuple MergedObsoleted = Obsoleted;
2446 bool FoundAny = false;
2447 bool OverrideOrImpl = false;
2448 switch (AMK) {
2451 OverrideOrImpl = false;
2452 break;
2453
2457 OverrideOrImpl = true;
2458 break;
2459 }
2460
2461 if (D->hasAttrs()) {
2462 AttrVec &Attrs = D->getAttrs();
2463 for (unsigned i = 0, e = Attrs.size(); i != e;) {
2464 auto *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]);
2465 if (!OldAA) {
2466 ++i;
2467 continue;
2468 }
2469
2470 const IdentifierInfo *OldEnvironment = OldAA->getEnvironment();
2471 if (OldEnvironment != Environment) {
2472 ++i;
2473 continue;
2474 }
2475
2476 if (OldAA->getPlatform() != Platform) {
2477 // If this new attr is for anyappleos and the old attr is for the
2478 // inferred platform, the existing explicit platform attr wins.
2479 if (InferredPlatformII) {
2480 if (OldAA->getPlatform() == InferredPlatformII)
2481 return nullptr;
2482 } else {
2483 // If this new attr is an explicit platform attr, check if the old
2484 // attr is an existing anyAppleOS attr whose inferred attr is for this
2485 // platform. If so, the explicit attr wins: erase the old attr.
2486 if (AvailabilityAttr *Inf = OldAA->getInferredAttrAs();
2487 Inf && Inf->getPlatform() == Platform) {
2488 Attrs.erase(Attrs.begin() + i);
2489 --e;
2490 continue;
2491 }
2492 }
2493 ++i;
2494 continue;
2495 }
2496
2497 // If there is an existing availability attribute for this platform that
2498 // has a lower priority use the existing one and discard the new
2499 // attribute.
2500 if (OldAA->getPriority() < Priority)
2501 return nullptr;
2502
2503 // If there is an existing attribute for this platform that has a higher
2504 // priority than the new attribute then erase the old one and continue
2505 // processing the attributes.
2506 if (OldAA->getPriority() > Priority) {
2507 Attrs.erase(Attrs.begin() + i);
2508 --e;
2509 continue;
2510 }
2511
2512 FoundAny = true;
2513 VersionTuple OldIntroduced = OldAA->getIntroduced();
2514 VersionTuple OldDeprecated = OldAA->getDeprecated();
2515 VersionTuple OldObsoleted = OldAA->getObsoleted();
2516 bool OldIsUnavailable = OldAA->getUnavailable();
2517
2518 if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl) ||
2519 !versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl) ||
2520 !versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl) ||
2521 !(OldIsUnavailable == IsUnavailable ||
2522 (OverrideOrImpl && !OldIsUnavailable && IsUnavailable))) {
2523 if (OverrideOrImpl) {
2524 int Which = -1;
2525 VersionTuple FirstVersion;
2526 VersionTuple SecondVersion;
2527 if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl)) {
2528 Which = 0;
2529 FirstVersion = OldIntroduced;
2530 SecondVersion = Introduced;
2531 } else if (!versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl)) {
2532 Which = 1;
2533 FirstVersion = Deprecated;
2534 SecondVersion = OldDeprecated;
2535 } else if (!versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl)) {
2536 Which = 2;
2537 FirstVersion = Obsoleted;
2538 SecondVersion = OldObsoleted;
2539 }
2540
2541 if (Which == -1) {
2542 Diag(OldAA->getLocation(),
2543 diag::warn_mismatched_availability_override_unavail)
2544 << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
2546 } else if (Which != 1 && AMK == AvailabilityMergeKind::
2548 // Allow different 'introduced' / 'obsoleted' availability versions
2549 // on a method that implements an optional protocol requirement. It
2550 // makes less sense to allow this for 'deprecated' as the user can't
2551 // see if the method is 'deprecated' as 'respondsToSelector' will
2552 // still return true when the method is deprecated.
2553 ++i;
2554 continue;
2555 } else {
2556 Diag(OldAA->getLocation(),
2557 diag::warn_mismatched_availability_override)
2558 << Which
2559 << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
2560 << FirstVersion.getAsString() << SecondVersion.getAsString()
2562 }
2564 Diag(CI.getLoc(), diag::note_overridden_method);
2565 else
2566 Diag(CI.getLoc(), diag::note_protocol_method);
2567 } else {
2568 Diag(OldAA->getLocation(), diag::warn_mismatched_availability);
2569 Diag(CI.getLoc(), diag::note_previous_attribute);
2570 }
2571
2572 Attrs.erase(Attrs.begin() + i);
2573 --e;
2574 continue;
2575 }
2576
2577 VersionTuple MergedIntroduced2 = MergedIntroduced;
2578 VersionTuple MergedDeprecated2 = MergedDeprecated;
2579 VersionTuple MergedObsoleted2 = MergedObsoleted;
2580
2581 if (MergedIntroduced2.empty())
2582 MergedIntroduced2 = OldIntroduced;
2583 if (MergedDeprecated2.empty())
2584 MergedDeprecated2 = OldDeprecated;
2585 if (MergedObsoleted2.empty())
2586 MergedObsoleted2 = OldObsoleted;
2587
2588 if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform,
2589 MergedIntroduced2, MergedDeprecated2,
2590 MergedObsoleted2)) {
2591 Attrs.erase(Attrs.begin() + i);
2592 --e;
2593 continue;
2594 }
2595
2596 MergedIntroduced = MergedIntroduced2;
2597 MergedDeprecated = MergedDeprecated2;
2598 MergedObsoleted = MergedObsoleted2;
2599 ++i;
2600 }
2601 }
2602
2603 if (FoundAny &&
2604 MergedIntroduced == Introduced &&
2605 MergedDeprecated == Deprecated &&
2606 MergedObsoleted == Obsoleted)
2607 return nullptr;
2608
2609 // Only create a new attribute if !OverrideOrImpl, but we want to do
2610 // the checking.
2611 if (!checkAvailabilityAttr(*this, CI.getRange(), Platform, MergedIntroduced,
2612 MergedDeprecated, MergedObsoleted) &&
2613 !OverrideOrImpl) {
2614 auto *Avail = ::new (Context) AvailabilityAttr(
2615 Context, CI, Platform, Introduced, Deprecated, Obsoleted, IsUnavailable,
2616 Message, IsStrict, Replacement, Priority, Environment,
2617 /*InferredAttr=*/nullptr);
2618 Avail->setImplicit(Implicit);
2619 return Avail;
2620 }
2621 return nullptr;
2622}
2623
2625 NamedDecl *D, const AttributeCommonInfo &CI, const IdentifierInfo *Platform,
2626 bool Implicit, VersionTuple Introduced, VersionTuple Deprecated,
2627 VersionTuple Obsoleted, bool IsUnavailable, StringRef Message,
2628 bool IsStrict, StringRef Replacement, AvailabilityMergeKind AMK,
2629 int Priority, const IdentifierInfo *IIEnvironment,
2630 const IdentifierInfo *InferredPlatformII) {
2631 AvailabilityAttr *OrigAttr = mergeAvailabilityAttr(
2632 D, CI, Platform, Implicit, Introduced, Deprecated, Obsoleted,
2633 IsUnavailable, Message, IsStrict, Replacement, AMK, Priority,
2634 IIEnvironment, InferredPlatformII);
2635 if (!OrigAttr || !InferredPlatformII)
2636 return OrigAttr;
2637
2638 auto *InferredAttr = ::new (Context) AvailabilityAttr(
2639 Context, CI, InferredPlatformII, OrigAttr->getIntroduced(),
2640 OrigAttr->getDeprecated(), OrigAttr->getObsoleted(),
2641 OrigAttr->getUnavailable(), OrigAttr->getMessage(), OrigAttr->getStrict(),
2642 OrigAttr->getReplacement(),
2643 Priority == AP_PragmaClangAttribute
2646 IIEnvironment, /*InferredAttr=*/nullptr);
2647 InferredAttr->setImplicit(true);
2648 OrigAttr->setInferredAttr(InferredAttr);
2649 return OrigAttr;
2650}
2651
2652/// Returns true if the given availability attribute should be inferred, and
2653/// adjusts the value of the attribute as necessary to facilitate that.
2655 IdentifierInfo *&II,
2656 bool &IsUnavailable,
2657 VersionTuple &Introduced,
2658 VersionTuple &Deprecated,
2659 VersionTuple &Obsolete, Sema &S) {
2660 const llvm::Triple &TT = S.Context.getTargetInfo().getTriple();
2661 const ASTContext &Context = S.Context;
2662 if (TT.getOS() != llvm::Triple::XROS)
2663 return false;
2664 IdentifierInfo *NewII = nullptr;
2665 if (II->getName() == "ios")
2666 NewII = &Context.Idents.get("xros");
2667 else if (II->getName() == "ios_app_extension")
2668 NewII = &Context.Idents.get("xros_app_extension");
2669 if (!NewII)
2670 return false;
2671 II = NewII;
2672
2673 auto MakeUnavailable = [&]() {
2674 IsUnavailable = true;
2675 // Reset introduced, deprecated, obsoleted.
2676 Introduced = VersionTuple();
2677 Deprecated = VersionTuple();
2678 Obsolete = VersionTuple();
2679 };
2680
2682 AL.getRange().getBegin(), "ios");
2683
2684 if (!SDKInfo) {
2685 MakeUnavailable();
2686 return true;
2687 }
2688 // Map from the fallback platform availability to the current platform
2689 // availability.
2690 const auto *Mapping = SDKInfo->getVersionMapping(DarwinSDKInfo::OSEnvPair(
2691 llvm::Triple::IOS, llvm::Triple::UnknownEnvironment, llvm::Triple::XROS,
2692 llvm::Triple::UnknownEnvironment));
2693 if (!Mapping) {
2694 MakeUnavailable();
2695 return true;
2696 }
2697
2698 if (!Introduced.empty()) {
2699 auto NewIntroduced = Mapping->mapIntroducedAvailabilityVersion(Introduced);
2700 if (!NewIntroduced) {
2701 MakeUnavailable();
2702 return true;
2703 }
2704 Introduced = *NewIntroduced;
2705 }
2706
2707 if (!Obsolete.empty()) {
2708 auto NewObsolete =
2709 Mapping->mapDeprecatedObsoletedAvailabilityVersion(Obsolete);
2710 if (!NewObsolete) {
2711 MakeUnavailable();
2712 return true;
2713 }
2714 Obsolete = *NewObsolete;
2715 }
2716
2717 if (!Deprecated.empty()) {
2718 auto NewDeprecated =
2719 Mapping->mapDeprecatedObsoletedAvailabilityVersion(Deprecated);
2720 Deprecated = NewDeprecated ? *NewDeprecated : VersionTuple();
2721 }
2722
2723 return true;
2724}
2725
2726static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2728 D)) {
2729 S.Diag(AL.getRange().getBegin(), diag::warn_deprecated_ignored_on_using)
2730 << AL;
2731 return;
2732 }
2733
2734 if (!AL.checkExactlyNumArgs(S, 1))
2735 return;
2736 IdentifierLoc *Platform = AL.getArgAsIdent(0);
2737
2738 IdentifierInfo *II = Platform->getIdentifierInfo();
2739 StringRef PrettyName = AvailabilityAttr::getPrettyPlatformName(II->getName());
2740 if (PrettyName.empty())
2741 S.Diag(Platform->getLoc(), diag::warn_availability_unknown_platform)
2742 << Platform->getIdentifierInfo();
2743
2744 auto *ND = dyn_cast<NamedDecl>(D);
2745 if (!ND) // We warned about this already, so just return.
2746 return;
2747
2751
2752 const llvm::Triple::OSType PlatformOS = AvailabilityAttr::getOSType(
2753 AvailabilityAttr::canonicalizePlatformName(II->getName()));
2754
2755 auto reportAndUpdateIfInvalidOS = [&](auto &InputVersion) -> void {
2756 const bool IsInValidRange =
2757 llvm::Triple::isValidVersionForOS(PlatformOS, InputVersion);
2758 // Canonicalize availability versions.
2759 auto CanonicalVersion = llvm::Triple::getCanonicalVersionForOS(
2760 PlatformOS, InputVersion, IsInValidRange);
2761 if (!IsInValidRange) {
2762 S.Diag(Platform->getLoc(), diag::warn_availability_invalid_os_version)
2763 << InputVersion.getAsString() << PrettyName;
2764 S.Diag(Platform->getLoc(),
2765 diag::note_availability_invalid_os_version_adjusted)
2766 << CanonicalVersion.getAsString();
2767 }
2768 InputVersion = CanonicalVersion;
2769 };
2770
2771 if (PlatformOS != llvm::Triple::OSType::UnknownOS) {
2772 reportAndUpdateIfInvalidOS(Introduced.Version);
2773 reportAndUpdateIfInvalidOS(Deprecated.Version);
2774 reportAndUpdateIfInvalidOS(Obsoleted.Version);
2775 }
2776
2777 bool IsUnavailable = AL.getUnavailableLoc().isValid();
2778 bool IsStrict = AL.getStrictLoc().isValid();
2779 StringRef Str;
2780 if (const auto *SE = dyn_cast_if_present<StringLiteral>(AL.getMessageExpr()))
2781 Str = SE->getString();
2782 StringRef Replacement;
2783 if (const auto *SE =
2784 dyn_cast_if_present<StringLiteral>(AL.getReplacementExpr()))
2785 Replacement = SE->getString();
2786
2787 if (II->isStr("swift")) {
2788 if (Introduced.isValid() || Obsoleted.isValid() ||
2789 (!IsUnavailable && !Deprecated.isValid())) {
2790 S.Diag(AL.getLoc(),
2791 diag::warn_availability_swift_unavailable_deprecated_only);
2792 return;
2793 }
2794 }
2795
2796 if (II->isStr("fuchsia")) {
2797 std::optional<unsigned> Min, Sub;
2798 if ((Min = Introduced.Version.getMinor()) ||
2799 (Sub = Introduced.Version.getSubminor())) {
2800 S.Diag(AL.getLoc(), diag::warn_availability_fuchsia_unavailable_minor);
2801 return;
2802 }
2803 }
2804
2805 if (S.getLangOpts().HLSL && IsStrict)
2806 S.Diag(AL.getStrictLoc(), diag::err_availability_unexpected_parameter)
2807 << "strict" << /* HLSL */ 0;
2808
2809 int PriorityModifier = AL.isPragmaClangAttribute()
2812
2813 const IdentifierLoc *EnvironmentLoc = AL.getEnvironment();
2814 IdentifierInfo *IIEnvironment = nullptr;
2815 if (EnvironmentLoc) {
2816 if (S.getLangOpts().HLSL) {
2817 IIEnvironment = EnvironmentLoc->getIdentifierInfo();
2818 if (AvailabilityAttr::getEnvironmentType(
2819 EnvironmentLoc->getIdentifierInfo()->getName()) ==
2820 llvm::Triple::EnvironmentType::UnknownEnvironment)
2821 S.Diag(EnvironmentLoc->getLoc(),
2822 diag::warn_availability_unknown_environment)
2823 << EnvironmentLoc->getIdentifierInfo();
2824 } else {
2825 S.Diag(EnvironmentLoc->getLoc(),
2826 diag::err_availability_unexpected_parameter)
2827 << "environment" << /* C/C++ */ 1;
2828 }
2829 }
2830
2831 // Handle anyAppleOS: preserve the original anyappleos attr on the decl and
2832 // store the inferred platform-specific attr as a field on it.
2833 if (II->getName() == "anyappleos") {
2834 // Validate anyAppleOS versions; reject versions older than 26.0.
2835 auto ValidateVersion = [&](const llvm::VersionTuple &Version,
2836 SourceLocation Loc) -> bool {
2838 return true;
2839 S.Diag(Loc, diag::err_availability_invalid_anyappleos_version)
2840 << Version.getAsString();
2841 return false;
2842 };
2843
2844 // Validate the versions; bail out if any are invalid.
2845 bool Valid = ValidateVersion(Introduced.Version, Introduced.KeywordLoc);
2846 Valid &= ValidateVersion(Deprecated.Version, Deprecated.KeywordLoc);
2847 Valid &= ValidateVersion(Obsoleted.Version, Obsoleted.KeywordLoc);
2848 if (!Valid)
2849 return;
2850
2851 llvm::Triple T = S.Context.getTargetInfo().getTriple();
2852
2853 // Only create implicit attributes for Darwin OSes.
2854 if (!T.isOSDarwin())
2855 return;
2856
2857 StringRef PlatformName;
2858
2859 // Determine the platform name based on the target triple.
2860 if (T.isMacOSX())
2861 PlatformName = "macos";
2862 else if (T.getOS() == llvm::Triple::IOS && T.isMacCatalystEnvironment())
2863 PlatformName = "maccatalyst";
2864 else // For iOS, tvOS, watchOS, visionOS, bridgeOS, etc.
2865 PlatformName = llvm::Triple::getOSTypeName(T.getOS());
2866
2867 IdentifierInfo *InferredPlatformII = &S.Context.Idents.get(PlatformName);
2868
2869 // Call mergeAvailabilityAttr for the original anyappleos attr. Pass
2870 // InferredPlatformII so the dedup loop can detect a conflicting explicit
2871 // platform attr (in which case mergeAvailabilityAttr returns null and we
2872 // add neither attr).
2873 AvailabilityAttr *OrigAttr = S.mergeAndInferAvailabilityAttr(
2874 ND, AL, II, /*Implicit=*/false, Introduced.Version, Deprecated.Version,
2875 Obsoleted.Version, IsUnavailable, Str, IsStrict, Replacement,
2876 AvailabilityMergeKind::None, PriorityModifier, IIEnvironment,
2877 InferredPlatformII);
2878 if (!OrigAttr)
2879 return;
2880 D->addAttr(OrigAttr);
2881 return;
2882 }
2883
2884 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2885 ND, AL, II, false /*Implicit*/, Introduced.Version, Deprecated.Version,
2886 Obsoleted.Version, IsUnavailable, Str, IsStrict, Replacement,
2887 AvailabilityMergeKind::None, PriorityModifier, IIEnvironment);
2888 if (NewAttr)
2889 D->addAttr(NewAttr);
2890
2891 if (S.Context.getTargetInfo().getTriple().getOS() == llvm::Triple::XROS) {
2892 IdentifierInfo *NewII = II;
2893 bool NewIsUnavailable = IsUnavailable;
2894 VersionTuple NewIntroduced = Introduced.Version;
2895 VersionTuple NewDeprecated = Deprecated.Version;
2896 VersionTuple NewObsoleted = Obsoleted.Version;
2897 if (shouldInferAvailabilityAttribute(AL, NewII, NewIsUnavailable,
2898 NewIntroduced, NewDeprecated,
2899 NewObsoleted, S)) {
2900 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2901 ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
2902 NewObsoleted, NewIsUnavailable, Str, IsStrict, Replacement,
2904 PriorityModifier + Sema::AP_InferredFromOtherPlatform, IIEnvironment);
2905 if (NewAttr)
2906 D->addAttr(NewAttr);
2907 }
2908 }
2909
2910 // Transcribe "ios" to "watchos" (and add a new attribute) if the versioning
2911 // matches before the start of the watchOS platform.
2912 if (S.Context.getTargetInfo().getTriple().isWatchOS()) {
2913 IdentifierInfo *NewII = nullptr;
2914 if (II->getName() == "ios")
2915 NewII = &S.Context.Idents.get("watchos");
2916 else if (II->getName() == "ios_app_extension")
2917 NewII = &S.Context.Idents.get("watchos_app_extension");
2918
2919 if (NewII) {
2920 const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking();
2921 const auto *IOSToWatchOSMapping =
2922 SDKInfo ? SDKInfo->getVersionMapping(
2924 : nullptr;
2925
2926 auto adjustWatchOSVersion =
2927 [IOSToWatchOSMapping](VersionTuple Version) -> VersionTuple {
2928 if (Version.empty())
2929 return Version;
2930 auto MinimumWatchOSVersion = VersionTuple(2, 0);
2931
2932 if (IOSToWatchOSMapping) {
2933 if (auto MappedVersion = IOSToWatchOSMapping->map(
2934 Version, MinimumWatchOSVersion, std::nullopt)) {
2935 return *MappedVersion;
2936 }
2937 }
2938
2939 auto Major = Version.getMajor();
2940 auto NewMajor = Major;
2941 if (Major < 9)
2942 NewMajor = 0;
2943 else if (Major < 12)
2944 NewMajor = Major - 7;
2945 if (NewMajor >= 2) {
2946 if (Version.getMinor()) {
2947 if (Version.getSubminor())
2948 return VersionTuple(NewMajor, *Version.getMinor(),
2949 *Version.getSubminor());
2950 else
2951 return VersionTuple(NewMajor, *Version.getMinor());
2952 }
2953 return VersionTuple(NewMajor);
2954 }
2955
2956 return MinimumWatchOSVersion;
2957 };
2958
2959 auto NewIntroduced = adjustWatchOSVersion(Introduced.Version);
2960 auto NewDeprecated = adjustWatchOSVersion(Deprecated.Version);
2961 auto NewObsoleted = adjustWatchOSVersion(Obsoleted.Version);
2962
2963 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2964 ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
2965 NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,
2967 PriorityModifier + Sema::AP_InferredFromOtherPlatform, IIEnvironment);
2968 if (NewAttr)
2969 D->addAttr(NewAttr);
2970 }
2971 } else if (S.Context.getTargetInfo().getTriple().isTvOS()) {
2972 // Transcribe "ios" to "tvos" (and add a new attribute) if the versioning
2973 // matches before the start of the tvOS platform.
2974 IdentifierInfo *NewII = nullptr;
2975 if (II->getName() == "ios")
2976 NewII = &S.Context.Idents.get("tvos");
2977 else if (II->getName() == "ios_app_extension")
2978 NewII = &S.Context.Idents.get("tvos_app_extension");
2979
2980 if (NewII) {
2981 const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking();
2982 const auto *IOSToTvOSMapping =
2983 SDKInfo ? SDKInfo->getVersionMapping(
2985 : nullptr;
2986
2987 auto AdjustTvOSVersion =
2988 [IOSToTvOSMapping](VersionTuple Version) -> VersionTuple {
2989 if (Version.empty())
2990 return Version;
2991
2992 if (IOSToTvOSMapping) {
2993 if (auto MappedVersion = IOSToTvOSMapping->map(
2994 Version, VersionTuple(0, 0), std::nullopt)) {
2995 return *MappedVersion;
2996 }
2997 }
2998 return Version;
2999 };
3000
3001 auto NewIntroduced = AdjustTvOSVersion(Introduced.Version);
3002 auto NewDeprecated = AdjustTvOSVersion(Deprecated.Version);
3003 auto NewObsoleted = AdjustTvOSVersion(Obsoleted.Version);
3004
3005 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
3006 ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
3007 NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,
3009 PriorityModifier + Sema::AP_InferredFromOtherPlatform, IIEnvironment);
3010 if (NewAttr)
3011 D->addAttr(NewAttr);
3012 }
3013 } else if (S.Context.getTargetInfo().getTriple().getOS() ==
3014 llvm::Triple::IOS &&
3015 S.Context.getTargetInfo().getTriple().isMacCatalystEnvironment()) {
3016 auto GetSDKInfo = [&]() {
3018 "macOS");
3019 };
3020
3021 // Transcribe "ios" to "maccatalyst" (and add a new attribute).
3022 IdentifierInfo *NewII = nullptr;
3023 if (II->getName() == "ios")
3024 NewII = &S.Context.Idents.get("maccatalyst");
3025 else if (II->getName() == "ios_app_extension")
3026 NewII = &S.Context.Idents.get("maccatalyst_app_extension");
3027 if (NewII) {
3028 auto MinMacCatalystVersion = [](const VersionTuple &V) {
3029 if (V.empty())
3030 return V;
3031 if (V.getMajor() < 13 ||
3032 (V.getMajor() == 13 && V.getMinor() && *V.getMinor() < 1))
3033 return VersionTuple(13, 1); // The min Mac Catalyst version is 13.1.
3034 return V;
3035 };
3036 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
3037 ND, AL, NewII, true /*Implicit*/,
3038 MinMacCatalystVersion(Introduced.Version),
3039 MinMacCatalystVersion(Deprecated.Version),
3040 MinMacCatalystVersion(Obsoleted.Version), IsUnavailable, Str,
3041 IsStrict, Replacement, AvailabilityMergeKind::None,
3042 PriorityModifier + Sema::AP_InferredFromOtherPlatform, IIEnvironment);
3043 if (NewAttr)
3044 D->addAttr(NewAttr);
3045 } else if (II->getName() == "macos" && GetSDKInfo() &&
3046 (!Introduced.Version.empty() || !Deprecated.Version.empty() ||
3047 !Obsoleted.Version.empty())) {
3048 if (const auto *MacOStoMacCatalystMapping =
3049 GetSDKInfo()->getVersionMapping(
3051 // Infer Mac Catalyst availability from the macOS availability attribute
3052 // if it has versioned availability. Don't infer 'unavailable'. This
3053 // inferred availability has lower priority than the other availability
3054 // attributes that are inferred from 'ios'.
3055 NewII = &S.Context.Idents.get("maccatalyst");
3056 auto RemapMacOSVersion =
3057 [&](const VersionTuple &V) -> std::optional<VersionTuple> {
3058 if (V.empty())
3059 return std::nullopt;
3060 // API_TO_BE_DEPRECATED is 100000.
3061 if (V.getMajor() == 100000)
3062 return VersionTuple(100000);
3063 // The minimum iosmac version is 13.1
3064 return MacOStoMacCatalystMapping->map(V, VersionTuple(13, 1),
3065 std::nullopt);
3066 };
3067 std::optional<VersionTuple> NewIntroduced =
3068 RemapMacOSVersion(Introduced.Version),
3069 NewDeprecated =
3070 RemapMacOSVersion(Deprecated.Version),
3071 NewObsoleted =
3072 RemapMacOSVersion(Obsoleted.Version);
3073 if (NewIntroduced || NewDeprecated || NewObsoleted) {
3074 auto VersionOrEmptyVersion =
3075 [](const std::optional<VersionTuple> &V) -> VersionTuple {
3076 return V ? *V : VersionTuple();
3077 };
3078 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
3079 ND, AL, NewII, true /*Implicit*/,
3080 VersionOrEmptyVersion(NewIntroduced),
3081 VersionOrEmptyVersion(NewDeprecated),
3082 VersionOrEmptyVersion(NewObsoleted), /*IsUnavailable=*/false, Str,
3083 IsStrict, Replacement, AvailabilityMergeKind::None,
3084 PriorityModifier + Sema::AP_InferredFromOtherPlatform +
3086 IIEnvironment);
3087 if (NewAttr)
3088 D->addAttr(NewAttr);
3089 }
3090 }
3091 }
3092 }
3093}
3094
3096 const ParsedAttr &AL) {
3097 if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 4))
3098 return;
3099
3100 StringRef Language;
3101 if (const auto *SE = dyn_cast_if_present<StringLiteral>(AL.getArgAsExpr(0)))
3102 Language = SE->getString();
3103 StringRef DefinedIn;
3104 if (const auto *SE = dyn_cast_if_present<StringLiteral>(AL.getArgAsExpr(1)))
3105 DefinedIn = SE->getString();
3106 bool IsGeneratedDeclaration = AL.getArgAsIdent(2) != nullptr;
3107 StringRef USR;
3108 if (const auto *SE = dyn_cast_if_present<StringLiteral>(AL.getArgAsExpr(3)))
3109 USR = SE->getString();
3110
3111 D->addAttr(::new (S.Context) ExternalSourceSymbolAttr(
3112 S.Context, AL, Language, DefinedIn, IsGeneratedDeclaration, USR));
3113}
3114
3116 VisibilityAttr::VisibilityType Value) {
3117 if (VisibilityAttr *Attr = D->getAttr<VisibilityAttr>()) {
3118 if (Attr->getVisibility() != Value)
3119 Diag(Loc, diag::err_mismatched_visibility);
3120 } else
3121 D->addAttr(VisibilityAttr::CreateImplicit(Context, Value));
3122}
3123
3124template <class T>
3126 typename T::VisibilityType value) {
3127 T *existingAttr = D->getAttr<T>();
3128 if (existingAttr) {
3129 typename T::VisibilityType existingValue = existingAttr->getVisibility();
3130 if (existingValue == value)
3131 return nullptr;
3132 S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
3133 S.Diag(CI.getLoc(), diag::note_previous_attribute);
3134 D->dropAttr<T>();
3135 }
3136 return ::new (S.Context) T(S.Context, CI, value);
3137}
3138
3140 const AttributeCommonInfo &CI,
3141 VisibilityAttr::VisibilityType Vis) {
3142 return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, CI, Vis);
3143}
3144
3145TypeVisibilityAttr *
3147 TypeVisibilityAttr::VisibilityType Vis) {
3148 return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, CI, Vis);
3149}
3150
3151static void handleVisibilityAttr(Sema &S, Decl *D, const ParsedAttr &AL,
3152 bool isTypeVisibility) {
3153 // Visibility attributes don't mean anything on a typedef.
3154 if (isa<TypedefNameDecl>(D)) {
3155 S.Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored) << AL;
3156 return;
3157 }
3158
3159 // 'type_visibility' can only go on a type or namespace.
3160 if (isTypeVisibility && !(isa<TagDecl>(D) || isa<ObjCInterfaceDecl>(D) ||
3161 isa<NamespaceDecl>(D))) {
3162 S.Diag(AL.getRange().getBegin(), diag::err_attribute_wrong_decl_type)
3164 return;
3165 }
3166
3167 // Check that the argument is a string literal.
3168 StringRef TypeStr;
3169 SourceLocation LiteralLoc;
3170 if (!S.checkStringLiteralArgumentAttr(AL, 0, TypeStr, &LiteralLoc))
3171 return;
3172
3173 VisibilityAttr::VisibilityType type;
3174 if (!VisibilityAttr::ConvertStrToVisibilityType(TypeStr, type)) {
3175 S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported) << AL
3176 << TypeStr;
3177 return;
3178 }
3179
3180 // Complain about attempts to use protected visibility on targets
3181 // (like Darwin) that don't support it.
3182 if (type == VisibilityAttr::Protected &&
3184 S.Diag(AL.getLoc(), diag::warn_attribute_protected_visibility);
3185 type = VisibilityAttr::Default;
3186 }
3187
3188 Attr *newAttr;
3189 if (isTypeVisibility) {
3190 newAttr = S.mergeTypeVisibilityAttr(
3191 D, AL, (TypeVisibilityAttr::VisibilityType)type);
3192 } else {
3193 newAttr = S.mergeVisibilityAttr(D, AL, type);
3194 }
3195 if (newAttr)
3196 D->addAttr(newAttr);
3197}
3198
3199static void handleSentinelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3200 unsigned sentinel = (unsigned)SentinelAttr::DefaultSentinel;
3201 if (AL.getNumArgs() > 0) {
3202 Expr *E = AL.getArgAsExpr(0);
3203 std::optional<llvm::APSInt> Idx = llvm::APSInt(32);
3204 if (E->isTypeDependent() || !(Idx = E->getIntegerConstantExpr(S.Context))) {
3205 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3206 << AL << 1 << AANT_ArgumentIntegerConstant << E->getSourceRange();
3207 return;
3208 }
3209
3210 if (Idx->isSigned() && Idx->isNegative()) {
3211 S.Diag(AL.getLoc(), diag::err_attribute_sentinel_less_than_zero)
3212 << E->getSourceRange();
3213 return;
3214 }
3215
3216 sentinel = Idx->getZExtValue();
3217 }
3218
3219 unsigned nullPos = (unsigned)SentinelAttr::DefaultNullPos;
3220 if (AL.getNumArgs() > 1) {
3221 Expr *E = AL.getArgAsExpr(1);
3222 std::optional<llvm::APSInt> Idx = llvm::APSInt(32);
3223 if (E->isTypeDependent() || !(Idx = E->getIntegerConstantExpr(S.Context))) {
3224 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3225 << AL << 2 << AANT_ArgumentIntegerConstant << E->getSourceRange();
3226 return;
3227 }
3228 nullPos = Idx->getZExtValue();
3229
3230 if ((Idx->isSigned() && Idx->isNegative()) || nullPos > 1) {
3231 // FIXME: This error message could be improved, it would be nice
3232 // to say what the bounds actually are.
3233 S.Diag(AL.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
3234 << E->getSourceRange();
3235 return;
3236 }
3237 }
3238
3239 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3240 const FunctionType *FT = FD->getType()->castAs<FunctionType>();
3241 if (isa<FunctionNoProtoType>(FT)) {
3242 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_named_arguments);
3243 return;
3244 }
3245
3246 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
3247 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
3248 return;
3249 }
3250 } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
3251 if (!MD->isVariadic()) {
3252 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
3253 return;
3254 }
3255 } else if (const auto *BD = dyn_cast<BlockDecl>(D)) {
3256 if (!BD->isVariadic()) {
3257 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
3258 return;
3259 }
3260 } else if (const auto *V = dyn_cast<VarDecl>(D)) {
3261 QualType Ty = V->getType();
3262 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
3263 const FunctionType *FT = Ty->isFunctionPointerType()
3264 ? D->getFunctionType()
3265 : Ty->castAs<BlockPointerType>()
3266 ->getPointeeType()
3267 ->castAs<FunctionType>();
3268 if (isa<FunctionNoProtoType>(FT)) {
3269 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_named_arguments);
3270 return;
3271 }
3272 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
3273 int m = Ty->isFunctionPointerType() ? 0 : 1;
3274 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
3275 return;
3276 }
3277 } else {
3278 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
3279 << AL << AL.isRegularKeywordAttribute()
3281 return;
3282 }
3283 } else {
3284 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
3285 << AL << AL.isRegularKeywordAttribute()
3287 return;
3288 }
3289 D->addAttr(::new (S.Context) SentinelAttr(S.Context, AL, sentinel, nullPos));
3290}
3291
3292static void handleWarnUnusedResult(Sema &S, Decl *D, const ParsedAttr &AL) {
3293 if (D->getFunctionType() &&
3296 S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) << AL << 0;
3297 return;
3298 }
3299 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
3300 if (MD->getReturnType()->isVoidType()) {
3301 S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) << AL << 1;
3302 return;
3303 }
3304
3305 StringRef Str;
3306 if (AL.isStandardAttributeSyntax()) {
3307 // If this is spelled [[clang::warn_unused_result]] we look for an optional
3308 // string literal. This is not gated behind any specific version of the
3309 // standard.
3310 if (AL.isClangScope()) {
3311 if (AL.getNumArgs() == 1 &&
3312 !S.checkStringLiteralArgumentAttr(AL, 0, Str, nullptr))
3313 return;
3314 } else if (!AL.getScopeName()) {
3315 // The standard attribute cannot be applied to variable declarations such
3316 // as a function pointer.
3317 if (isa<VarDecl>(D))
3318 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
3319 << AL << AL.isRegularKeywordAttribute()
3321
3322 // If this is spelled as the standard C++17 attribute, but not in C++17,
3323 // warn about using it as an extension. If there are attribute arguments,
3324 // then claim it's a C++20 extension instead. C23 supports this attribute
3325 // with the message; no extension warning is needed there beyond the one
3326 // already issued for accepting attributes in older modes.
3327 const LangOptions &LO = S.getLangOpts();
3328 if (AL.getNumArgs() == 1) {
3329 if (LO.CPlusPlus && !LO.CPlusPlus20)
3330 S.Diag(AL.getLoc(), diag::ext_cxx20_attr) << AL;
3331
3332 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, nullptr))
3333 return;
3334 } else if (LO.CPlusPlus && !LO.CPlusPlus17)
3335 S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
3336 }
3337 }
3338
3339 if ((!AL.isGNUAttribute() &&
3340 !(AL.isStandardAttributeSyntax() && AL.isClangScope())) &&
3342 S.Diag(AL.getLoc(), diag::warn_unused_result_typedef_unsupported_spelling)
3343 << AL.isGNUScope();
3344 return;
3345 }
3346
3347 D->addAttr(::new (S.Context) WarnUnusedResultAttr(S.Context, AL, Str));
3348}
3349
3350static void handleWeakImportAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3351 // weak_import only applies to variable & function declarations.
3352 bool isDef = false;
3353 if (!D->canBeWeakImported(isDef)) {
3354 if (isDef)
3355 S.Diag(AL.getLoc(), diag::warn_attribute_invalid_on_definition)
3356 << "weak_import";
3357 else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
3358 (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
3360 // Nothing to warn about here.
3361 } else
3362 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
3364
3365 return;
3366 }
3367
3368 D->addAttr(::new (S.Context) WeakImportAttr(S.Context, AL));
3369}
3370
3371// Checks whether an argument of launch_bounds-like attribute is
3372// acceptable, performs implicit conversion to Rvalue, and returns
3373// non-nullptr Expr result on success. Otherwise, it returns nullptr
3374// and may output an error.
3375template <class Attribute>
3376static Expr *makeAttributeArgExpr(Sema &S, Expr *E, const Attribute &Attr,
3377 const unsigned Idx) {
3379 return nullptr;
3380
3381 // Accept template arguments for now as they depend on something else.
3382 // We'll get to check them when they eventually get instantiated.
3383 if (E->isValueDependent())
3384 return E;
3385
3386 std::optional<llvm::APSInt> I = llvm::APSInt(64);
3387 if (!(I = E->getIntegerConstantExpr(S.Context))) {
3388 S.Diag(E->getExprLoc(), diag::err_attribute_argument_n_type)
3389 << &Attr << Idx << AANT_ArgumentIntegerConstant << E->getSourceRange();
3390 return nullptr;
3391 }
3392 // Make sure we can fit it in 32 bits.
3393 if (!I->isIntN(32)) {
3394 S.Diag(E->getExprLoc(), diag::err_ice_too_large)
3395 << toString(*I, 10, false) << 32 << /* Unsigned */ 1;
3396 return nullptr;
3397 }
3398 if (*I < 0)
3399 S.Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer)
3400 << &Attr << /*non-negative*/ 1 << E->getSourceRange();
3401
3402 // We may need to perform implicit conversion of the argument.
3404 S.Context, S.Context.getConstType(S.Context.IntTy), /*consume*/ false);
3405 ExprResult ValArg = S.PerformCopyInitialization(Entity, SourceLocation(), E);
3406 assert(!ValArg.isInvalid() &&
3407 "Unexpected PerformCopyInitialization() failure.");
3408
3409 return ValArg.getAs<Expr>();
3410}
3411
3412// Handles reqd_work_group_size and work_group_size_hint.
3413template <typename WorkGroupAttr>
3414static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
3415 Expr *WGSize[3];
3416 for (unsigned i = 0; i < 3; ++i) {
3417 if (Expr *E = makeAttributeArgExpr(S, AL.getArgAsExpr(i), AL, i))
3418 WGSize[i] = E;
3419 else
3420 return;
3421 }
3422
3423 auto IsZero = [&](Expr *E) {
3424 if (E->isValueDependent())
3425 return false;
3426 std::optional<llvm::APSInt> I = E->getIntegerConstantExpr(S.Context);
3427 assert(I && "Non-integer constant expr");
3428 return I->isZero();
3429 };
3430
3431 if (!llvm::all_of(WGSize, IsZero)) {
3432 for (unsigned i = 0; i < 3; ++i) {
3433 const Expr *E = AL.getArgAsExpr(i);
3434 if (IsZero(WGSize[i])) {
3435 S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
3436 << AL << E->getSourceRange();
3437 return;
3438 }
3439 }
3440 }
3441
3442 auto Equal = [&](Expr *LHS, Expr *RHS) {
3443 if (LHS->isValueDependent() || RHS->isValueDependent())
3444 return true;
3445 std::optional<llvm::APSInt> L = LHS->getIntegerConstantExpr(S.Context);
3446 assert(L && "Non-integer constant expr");
3447 std::optional<llvm::APSInt> R = RHS->getIntegerConstantExpr(S.Context);
3448 assert(L && "Non-integer constant expr");
3449 return L == R;
3450 };
3451
3452 WorkGroupAttr *Existing = D->getAttr<WorkGroupAttr>();
3453 if (Existing &&
3454 !llvm::equal(std::initializer_list<Expr *>{Existing->getXDim(),
3455 Existing->getYDim(),
3456 Existing->getZDim()},
3457 WGSize, Equal))
3458 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3459
3460 D->addAttr(::new (S.Context)
3461 WorkGroupAttr(S.Context, AL, WGSize[0], WGSize[1], WGSize[2]));
3462}
3463
3464static void handleVecTypeHint(Sema &S, Decl *D, const ParsedAttr &AL) {
3465 if (!AL.hasParsedType()) {
3466 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
3467 return;
3468 }
3469
3470 TypeSourceInfo *ParmTSI = nullptr;
3471 QualType ParmType = S.GetTypeFromParser(AL.getTypeArg(), &ParmTSI);
3472 assert(ParmTSI && "no type source info for attribute argument");
3473
3474 if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() &&
3475 (ParmType->isBooleanType() ||
3476 !ParmType->isIntegralType(S.getASTContext()))) {
3477 S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument) << 2 << AL;
3478 return;
3479 }
3480
3481 if (VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>()) {
3482 if (!S.Context.hasSameType(A->getTypeHint(), ParmType)) {
3483 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3484 return;
3485 }
3486 }
3487
3488 D->addAttr(::new (S.Context) VecTypeHintAttr(S.Context, AL, ParmTSI));
3489}
3490
3492 StringRef Name) {
3493 // Explicit or partial specializations do not inherit
3494 // the section attribute from the primary template.
3495 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3496 if (CI.getAttributeSpellingListIndex() == SectionAttr::Declspec_allocate &&
3498 return nullptr;
3499 }
3500 if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
3501 if (ExistingAttr->getName() == Name)
3502 return nullptr;
3503 Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section)
3504 << 1 /*section*/;
3505 Diag(CI.getLoc(), diag::note_previous_attribute);
3506 return nullptr;
3507 }
3508 return ::new (Context) SectionAttr(Context, CI, Name);
3509}
3510
3511llvm::Error Sema::isValidSectionSpecifier(StringRef SecName) {
3512 if (!Context.getTargetInfo().getTriple().isOSDarwin())
3513 return llvm::Error::success();
3514
3515 // Let MCSectionMachO validate this.
3516 StringRef Segment, Section;
3517 unsigned TAA, StubSize;
3518 bool HasTAA;
3519 return llvm::MCSectionMachO::ParseSectionSpecifier(SecName, Segment, Section,
3520 TAA, HasTAA, StubSize);
3521}
3522
3523bool Sema::checkSectionName(SourceLocation LiteralLoc, StringRef SecName) {
3524 if (llvm::Error E = isValidSectionSpecifier(SecName)) {
3525 Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
3526 << toString(std::move(E)) << 1 /*'section'*/;
3527 return false;
3528 }
3529 return true;
3530}
3531
3532static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3533 // Make sure that there is a string literal as the sections's single
3534 // argument.
3535 StringRef Str;
3536 SourceLocation LiteralLoc;
3537 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))
3538 return;
3539
3540 if (!S.checkSectionName(LiteralLoc, Str))
3541 return;
3542
3543 SectionAttr *NewAttr = S.mergeSectionAttr(D, AL, Str);
3544 if (NewAttr) {
3545 D->addAttr(NewAttr);
3547 ObjCPropertyDecl>(D))
3548 S.UnifySection(NewAttr->getName(),
3550 cast<NamedDecl>(D));
3551 }
3552}
3553
3554static bool isValidCodeModelAttr(llvm::Triple &Triple, StringRef Str) {
3555 if (Triple.isLoongArch()) {
3556 return Str == "normal" || Str == "medium" || Str == "extreme";
3557 } else {
3558 assert(Triple.getArch() == llvm::Triple::x86_64 &&
3559 "only loongarch/x86-64 supported");
3560 return Str == "small" || Str == "large";
3561 }
3562}
3563
3564static void handleCodeModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3565 StringRef Str;
3566 SourceLocation LiteralLoc;
3567 auto IsTripleSupported = [](llvm::Triple &Triple) {
3568 return Triple.getArch() == llvm::Triple::ArchType::x86_64 ||
3569 Triple.isLoongArch();
3570 };
3571
3572 // Check that it is a string.
3573 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))
3574 return;
3575
3578 if (auto *aux = S.Context.getAuxTargetInfo()) {
3579 Triples.push_back(aux->getTriple());
3580 } else if (S.Context.getTargetInfo().getTriple().isNVPTX() ||
3581 S.Context.getTargetInfo().getTriple().isAMDGPU() ||
3582 S.Context.getTargetInfo().getTriple().isSPIRV()) {
3583 // Ignore the attribute for pure GPU device compiles since it only applies
3584 // to host globals.
3585 return;
3586 }
3587
3588 auto SupportedTripleIt = llvm::find_if(Triples, IsTripleSupported);
3589 if (SupportedTripleIt == Triples.end()) {
3590 S.Diag(LiteralLoc, diag::warn_unknown_attribute_ignored) << AL;
3591 return;
3592 }
3593
3594 llvm::CodeModel::Model CM;
3595 if (!CodeModelAttr::ConvertStrToModel(Str, CM) ||
3596 !isValidCodeModelAttr(*SupportedTripleIt, Str)) {
3597 S.Diag(LiteralLoc, diag::err_attr_codemodel_arg) << Str;
3598 return;
3599 }
3600
3601 D->addAttr(::new (S.Context) CodeModelAttr(S.Context, AL, CM));
3602}
3603
3604// This is used for `__declspec(code_seg("segname"))` on a decl.
3605// `#pragma code_seg("segname")` uses checkSectionName() instead.
3606static bool checkCodeSegName(Sema &S, SourceLocation LiteralLoc,
3607 StringRef CodeSegName) {
3608 if (llvm::Error E = S.isValidSectionSpecifier(CodeSegName)) {
3609 S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
3610 << toString(std::move(E)) << 0 /*'code-seg'*/;
3611 return false;
3612 }
3613
3614 return true;
3615}
3616
3618 StringRef Name) {
3619 // Explicit or partial specializations do not inherit
3620 // the code_seg attribute from the primary template.
3621 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3623 return nullptr;
3624 }
3625 if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) {
3626 if (ExistingAttr->getName() == Name)
3627 return nullptr;
3628 Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section)
3629 << 0 /*codeseg*/;
3630 Diag(CI.getLoc(), diag::note_previous_attribute);
3631 return nullptr;
3632 }
3633 return ::new (Context) CodeSegAttr(Context, CI, Name);
3634}
3635
3636static void handleCodeSegAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3637 StringRef Str;
3638 SourceLocation LiteralLoc;
3639 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))
3640 return;
3641 if (!checkCodeSegName(S, LiteralLoc, Str))
3642 return;
3643 if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) {
3644 if (!ExistingAttr->isImplicit()) {
3645 S.Diag(AL.getLoc(),
3646 ExistingAttr->getName() == Str
3647 ? diag::warn_duplicate_codeseg_attribute
3648 : diag::err_conflicting_codeseg_attribute);
3649 return;
3650 }
3651 D->dropAttr<CodeSegAttr>();
3652 }
3653 if (CodeSegAttr *CSA = S.mergeCodeSegAttr(D, AL, Str))
3654 D->addAttr(CSA);
3655}
3656
3657bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) {
3658 using namespace DiagAttrParams;
3659
3660 if (AttrStr.contains("fpmath="))
3661 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3662 << Unsupported << None << "fpmath=" << Target;
3663
3664 // Diagnose use of tune if target doesn't support it.
3665 if (!Context.getTargetInfo().supportsTargetAttributeTune() &&
3666 AttrStr.contains("tune="))
3667 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3668 << Unsupported << None << "tune=" << Target;
3669
3670 ParsedTargetAttr ParsedAttrs =
3671 Context.getTargetInfo().parseTargetAttr(AttrStr);
3672
3673 if (!ParsedAttrs.CPU.empty() &&
3674 !Context.getTargetInfo().isValidCPUName(ParsedAttrs.CPU))
3675 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3676 << Unknown << CPU << ParsedAttrs.CPU << Target;
3677
3678 if (!ParsedAttrs.Tune.empty() &&
3679 !Context.getTargetInfo().isValidCPUName(ParsedAttrs.Tune))
3680 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3681 << Unknown << Tune << ParsedAttrs.Tune << Target;
3682
3683 if (Context.getTargetInfo().getTriple().isRISCV()) {
3684 if (ParsedAttrs.Duplicate != "")
3685 return Diag(LiteralLoc, diag::err_duplicate_target_attribute)
3686 << Duplicate << None << ParsedAttrs.Duplicate << Target;
3687 for (StringRef CurFeature : ParsedAttrs.Features) {
3688 if (!CurFeature.starts_with('+') && !CurFeature.starts_with('-'))
3689 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3690 << Unsupported << None << AttrStr << Target;
3691 }
3692 }
3693
3694 if (Context.getTargetInfo().getTriple().isLoongArch()) {
3695 for (StringRef CurFeature : ParsedAttrs.Features) {
3696 if (CurFeature.starts_with("!arch=")) {
3697 StringRef ArchValue = CurFeature.split("=").second.trim();
3698 return Diag(LiteralLoc, diag::err_attribute_unsupported)
3699 << "target(arch=..)" << ArchValue;
3700 }
3701 }
3702 }
3703
3704 if (ParsedAttrs.Duplicate != "")
3705 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3706 << Duplicate << None << ParsedAttrs.Duplicate << Target;
3707
3708 for (const auto &Feature : ParsedAttrs.Features) {
3709 auto CurFeature = StringRef(Feature).drop_front(); // remove + or -.
3710 if (!Context.getTargetInfo().isValidFeatureName(CurFeature))
3711 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3712 << Unsupported << None << CurFeature << Target;
3713 }
3714
3716 StringRef DiagMsg;
3717 if (ParsedAttrs.BranchProtection.empty())
3718 return false;
3719 if (!Context.getTargetInfo().validateBranchProtection(
3720 ParsedAttrs.BranchProtection, ParsedAttrs.CPU, BPI,
3721 Context.getLangOpts(), DiagMsg)) {
3722 if (DiagMsg.empty())
3723 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3724 << Unsupported << None << "branch-protection" << Target;
3725 return Diag(LiteralLoc, diag::err_invalid_branch_protection_spec)
3726 << DiagMsg;
3727 }
3728 if (!DiagMsg.empty())
3729 Diag(LiteralLoc, diag::warn_unsupported_branch_protection_spec) << DiagMsg;
3730
3731 return false;
3732}
3733
3734static void handleTargetVersionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3735 StringRef Param;
3736 SourceLocation Loc;
3737 SmallString<64> NewParam;
3738 if (!S.checkStringLiteralArgumentAttr(AL, 0, Param, &Loc))
3739 return;
3740
3741 if (S.Context.getTargetInfo().getTriple().isAArch64()) {
3742 if (S.ARM().checkTargetVersionAttr(Param, Loc, NewParam))
3743 return;
3744 } else if (S.Context.getTargetInfo().getTriple().isRISCV()) {
3745 if (S.RISCV().checkTargetVersionAttr(Param, Loc, NewParam))
3746 return;
3747 }
3748
3749 TargetVersionAttr *NewAttr =
3750 ::new (S.Context) TargetVersionAttr(S.Context, AL, NewParam);
3751 D->addAttr(NewAttr);
3752}
3753
3754static void handleTargetAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3755 StringRef Str;
3756 SourceLocation LiteralLoc;
3757 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc) ||
3758 S.checkTargetAttr(LiteralLoc, Str))
3759 return;
3760
3761 TargetAttr *NewAttr = ::new (S.Context) TargetAttr(S.Context, AL, Str);
3762 D->addAttr(NewAttr);
3763}
3764
3765static void handleTargetClonesAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3766 // Ensure we don't combine these with themselves, since that causes some
3767 // confusing behavior.
3768 if (const auto *Other = D->getAttr<TargetClonesAttr>()) {
3769 S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL;
3770 S.Diag(Other->getLocation(), diag::note_conflicting_attribute);
3771 return;
3772 }
3774 return;
3775
3776 // FIXME: We could probably figure out how to get this to work for lambdas
3777 // someday.
3778 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
3779 if (MD->getParent()->isLambda()) {
3780 S.Diag(D->getLocation(), diag::err_multiversion_doesnt_support)
3781 << static_cast<unsigned>(MultiVersionKind::TargetClones)
3782 << /*Lambda*/ 9;
3783 return;
3784 }
3785 }
3786
3789 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
3790 StringRef Param;
3791 SourceLocation Loc;
3792 if (!S.checkStringLiteralArgumentAttr(AL, I, Param, &Loc))
3793 return;
3794 Params.push_back(Param);
3795 Locations.push_back(Loc);
3796 }
3797
3798 SmallVector<SmallString<64>, 2> NewParams;
3799 if (S.Context.getTargetInfo().getTriple().isAArch64()) {
3800 if (S.ARM().checkTargetClonesAttr(Params, Locations, NewParams))
3801 return;
3802 } else if (S.Context.getTargetInfo().getTriple().isRISCV()) {
3803 if (S.RISCV().checkTargetClonesAttr(Params, Locations, NewParams,
3804 AL.getLoc()))
3805 return;
3806 } else if (S.Context.getTargetInfo().getTriple().isX86()) {
3807 if (S.X86().checkTargetClonesAttr(Params, Locations, NewParams,
3808 AL.getLoc()))
3809 return;
3810 } else if (S.Context.getTargetInfo().getTriple().isOSAIX()) {
3811 if (S.PPC().checkTargetClonesAttr(Params, Locations, NewParams,
3812 AL.getLoc()))
3813 return;
3814 }
3815 Params.clear();
3816 for (auto &SmallStr : NewParams)
3817 Params.push_back(SmallStr.str());
3818
3819 TargetClonesAttr *NewAttr = ::new (S.Context)
3820 TargetClonesAttr(S.Context, AL, Params.data(), Params.size());
3821 D->addAttr(NewAttr);
3822}
3823
3824static void handleMinVectorWidthAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3825 Expr *E = AL.getArgAsExpr(0);
3826 uint32_t VecWidth;
3827 if (!S.checkUInt32Argument(AL, E, VecWidth)) {
3828 AL.setInvalid();
3829 return;
3830 }
3831
3832 MinVectorWidthAttr *Existing = D->getAttr<MinVectorWidthAttr>();
3833 if (Existing && Existing->getVectorWidth() != VecWidth) {
3834 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3835 return;
3836 }
3837
3838 D->addAttr(::new (S.Context) MinVectorWidthAttr(S.Context, AL, VecWidth));
3839}
3840
3841static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3842 Expr *E = AL.getArgAsExpr(0);
3843 SourceLocation Loc = E->getExprLoc();
3844 FunctionDecl *FD = nullptr;
3846
3847 // gcc only allows for simple identifiers. Since we support more than gcc, we
3848 // will warn the user.
3849 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
3850 if (DRE->hasQualifier())
3851 S.Diag(Loc, diag::warn_cleanup_ext);
3852 FD = dyn_cast<FunctionDecl>(DRE->getDecl());
3853 NI = DRE->getNameInfo();
3854 if (!FD) {
3855 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 1
3856 << NI.getName();
3857 return;
3858 }
3859 } else if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
3860 if (ULE->hasExplicitTemplateArgs())
3861 S.Diag(Loc, diag::warn_cleanup_ext);
3863 NI = ULE->getNameInfo();
3864 if (!FD) {
3865 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 2
3866 << NI.getName();
3867 if (ULE->getType() == S.Context.OverloadTy)
3869 return;
3870 }
3871 } else {
3872 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 0;
3873 return;
3874 }
3875
3876 if (FD->getNumParams() != 1) {
3877 S.Diag(Loc, diag::err_attribute_cleanup_func_must_take_one_arg)
3878 << NI.getName();
3879 return;
3880 }
3881
3882 VarDecl *VD = cast<VarDecl>(D);
3883 // Create a reference to the variable declaration. This is a fake/dummy
3884 // reference.
3885 DeclRefExpr *VariableReference = DeclRefExpr::Create(
3886 S.Context, NestedNameSpecifierLoc{}, FD->getLocation(), VD, false,
3887 DeclarationNameInfo{VD->getDeclName(), VD->getLocation()}, VD->getType(),
3888 VK_LValue);
3889
3890 // Create a unary operator expression that represents taking the address of
3891 // the variable. This is a fake/dummy expression.
3892 Expr *AddressOfVariable = UnaryOperator::Create(
3893 S.Context, VariableReference, UnaryOperatorKind::UO_AddrOf,
3895 +false, FPOptionsOverride{});
3896
3897 // Create a function call expression. This is a fake/dummy call expression.
3898 CallExpr *FunctionCallExpression =
3899 CallExpr::Create(S.Context, E, ArrayRef{AddressOfVariable},
3901
3902 if (S.CheckFunctionCall(FD, FunctionCallExpression,
3903 FD->getType()->getAs<FunctionProtoType>())) {
3904 return;
3905 }
3906
3907 auto *attr = ::new (S.Context) CleanupAttr(S.Context, AL, FD);
3908 attr->setArgLoc(E->getExprLoc());
3909 D->addAttr(attr);
3910}
3911
3913 const ParsedAttr &AL) {
3914 if (!AL.isArgIdent(0)) {
3915 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3916 << AL << 0 << AANT_ArgumentIdentifier;
3917 return;
3918 }
3919
3920 EnumExtensibilityAttr::Kind ExtensibilityKind;
3922 if (!EnumExtensibilityAttr::ConvertStrToKind(II->getName(),
3923 ExtensibilityKind)) {
3924 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
3925 return;
3926 }
3927
3928 D->addAttr(::new (S.Context)
3929 EnumExtensibilityAttr(S.Context, AL, ExtensibilityKind));
3930}
3931
3932/// Handle __attribute__((format_arg((idx)))) attribute based on
3933/// https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
3934static void handleFormatArgAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3935 const Expr *IdxExpr = AL.getArgAsExpr(0);
3936 ParamIdx Idx;
3937 if (!S.checkFunctionOrMethodParameterIndex(D, AL, 1, IdxExpr, Idx))
3938 return;
3939
3940 // Make sure the format string is really a string.
3942
3943 bool NotNSStringTy = !S.ObjC().isNSStringType(Ty);
3944 if (NotNSStringTy && !S.ObjC().isCFStringType(Ty) &&
3945 (!Ty->isPointerType() ||
3947 S.Diag(AL.getLoc(), diag::err_format_attribute_not)
3948 << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0);
3949 return;
3950 }
3952 // replace instancetype with the class type
3953 auto *Instancetype = cast<TypedefType>(S.Context.getTypedefType(
3954 ElaboratedTypeKeyword::None, /*Qualifier=*/std::nullopt,
3956 if (Ty->getAs<TypedefType>() == Instancetype)
3957 if (auto *OMD = dyn_cast<ObjCMethodDecl>(D))
3958 if (auto *Interface = OMD->getClassInterface())
3960 QualType(Interface->getTypeForDecl(), 0));
3961 if (!S.ObjC().isNSStringType(Ty, /*AllowNSAttributedString=*/true) &&
3962 !S.ObjC().isCFStringType(Ty) &&
3963 (!Ty->isPointerType() ||
3965 S.Diag(AL.getLoc(), diag::err_format_attribute_result_not)
3966 << (NotNSStringTy ? "string type" : "NSString")
3967 << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0);
3968 return;
3969 }
3970
3971 D->addAttr(::new (S.Context) FormatArgAttr(S.Context, AL, Idx));
3972}
3973
3982
3983/// getFormatAttrKind - Map from format attribute names to supported format
3984/// types.
3985static FormatAttrKind getFormatAttrKind(StringRef Format) {
3986 return llvm::StringSwitch<FormatAttrKind>(Format)
3987 // Check for formats that get handled specially.
3988 .Case("NSString", NSStringFormat)
3989 .Case("CFString", CFStringFormat)
3990 .Cases({"gnu_strftime", "strftime"}, StrftimeFormat)
3991
3992 // Otherwise, check for supported formats.
3993 .Cases({"gnu_scanf", "scanf", "gnu_printf", "printf", "printf0",
3994 "gnu_strfmon", "strfmon"},
3996 .Cases({"cmn_err", "vcmn_err", "zcmn_err"}, SupportedFormat)
3997 .Cases({"kprintf", "syslog"}, SupportedFormat) // OpenBSD.
3998 .Case("freebsd_kprintf", SupportedFormat) // FreeBSD.
3999 .Case("os_trace", SupportedFormat)
4000 .Case("os_log", SupportedFormat)
4001
4002 .Cases({"gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag"},
4005}
4006
4007/// Handle __attribute__((init_priority(priority))) attributes based on
4008/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
4009static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4010 if (!S.getLangOpts().CPlusPlus) {
4011 S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
4012 return;
4013 }
4014
4015 if (S.getLangOpts().HLSL) {
4016 S.Diag(AL.getLoc(), diag::err_hlsl_init_priority_unsupported);
4017 return;
4018 }
4019
4021 S.Diag(AL.getLoc(), diag::err_init_priority_object_attr);
4022 AL.setInvalid();
4023 return;
4024 }
4025
4026 Expr *E = AL.getArgAsExpr(0);
4027 uint32_t prioritynum;
4028 if (!S.checkUInt32Argument(AL, E, prioritynum)) {
4029 AL.setInvalid();
4030 return;
4031 }
4032
4033 if (prioritynum > 65535) {
4034 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_range)
4035 << E->getSourceRange() << AL << 0 << 65535;
4036 AL.setInvalid();
4037 return;
4038 }
4039
4040 // Values <= 100 are reserved for the implementation, and libc++
4041 // benefits from being able to specify values in that range.
4042 if (prioritynum < 101)
4043 S.Diag(AL.getLoc(), diag::warn_init_priority_reserved)
4044 << E->getSourceRange() << prioritynum;
4045 D->addAttr(::new (S.Context) InitPriorityAttr(S.Context, AL, prioritynum));
4046}
4047
4049 StringRef NewUserDiagnostic) {
4050 if (const auto *EA = D->getAttr<ErrorAttr>()) {
4051 std::string NewAttr = CI.getNormalizedFullName();
4052 assert((NewAttr == "error" || NewAttr == "warning") &&
4053 "unexpected normalized full name");
4054 bool Match = (EA->isError() && NewAttr == "error") ||
4055 (EA->isWarning() && NewAttr == "warning");
4056 if (!Match) {
4057 Diag(EA->getLocation(), diag::err_attributes_are_not_compatible)
4058 << CI << EA
4059 << (CI.isRegularKeywordAttribute() ||
4060 EA->isRegularKeywordAttribute());
4061 Diag(CI.getLoc(), diag::note_conflicting_attribute);
4062 return nullptr;
4063 }
4064 if (EA->getUserDiagnostic() != NewUserDiagnostic) {
4065 Diag(CI.getLoc(), diag::warn_duplicate_attribute) << EA;
4066 Diag(EA->getLoc(), diag::note_previous_attribute);
4067 }
4068 D->dropAttr<ErrorAttr>();
4069 }
4070 return ::new (Context) ErrorAttr(Context, CI, NewUserDiagnostic);
4071}
4072
4074 const IdentifierInfo *Format, int FormatIdx,
4075 int FirstArg) {
4076 // Check whether we already have an equivalent format attribute.
4077 for (auto *F : D->specific_attrs<FormatAttr>()) {
4078 if (F->getType() == Format &&
4079 F->getFormatIdx() == FormatIdx &&
4080 F->getFirstArg() == FirstArg) {
4081 // If we don't have a valid location for this attribute, adopt the
4082 // location.
4083 if (F->getLocation().isInvalid())
4084 F->setRange(CI.getRange());
4085 return nullptr;
4086 }
4087 }
4088
4089 return ::new (Context) FormatAttr(Context, CI, Format, FormatIdx, FirstArg);
4090}
4091
4093 const AttributeCommonInfo &CI,
4094 const IdentifierInfo *Format,
4095 int FormatIdx,
4096 StringLiteral *FormatStr) {
4097 // Check whether we already have an equivalent FormatMatches attribute.
4098 for (auto *F : D->specific_attrs<FormatMatchesAttr>()) {
4099 if (F->getType() == Format && F->getFormatIdx() == FormatIdx) {
4100 if (!CheckFormatStringsCompatible(GetFormatStringType(Format->getName()),
4101 F->getFormatString(), FormatStr))
4102 return nullptr;
4103
4104 // If we don't have a valid location for this attribute, adopt the
4105 // location.
4106 if (F->getLocation().isInvalid())
4107 F->setRange(CI.getRange());
4108 return nullptr;
4109 }
4110 }
4111
4112 return ::new (Context)
4113 FormatMatchesAttr(Context, CI, Format, FormatIdx, FormatStr);
4114}
4115
4122
4123/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
4124/// https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
4125static bool handleFormatAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
4126 FormatAttrCommon *Info) {
4127 // Checks the first two arguments of the attribute; this is shared between
4128 // Format and FormatMatches attributes.
4129
4130 if (!AL.isArgIdent(0)) {
4131 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
4132 << AL << 1 << AANT_ArgumentIdentifier;
4133 return false;
4134 }
4135
4136 // In C++ the implicit 'this' function parameter also counts, and they are
4137 // counted from one.
4138 bool HasImplicitThisParam = hasImplicitObjectParameter(D);
4139 Info->NumArgs = getFunctionOrMethodNumParams(D) + HasImplicitThisParam;
4140
4142 StringRef Format = Info->Identifier->getName();
4143
4144 if (normalizeName(Format)) {
4145 // If we've modified the string name, we need a new identifier for it.
4146 Info->Identifier = &S.Context.Idents.get(Format);
4147 }
4148
4149 // Check for supported formats.
4150 Info->Kind = getFormatAttrKind(Format);
4151
4152 if (Info->Kind == IgnoredFormat)
4153 return false;
4154
4155 if (Info->Kind == InvalidFormat) {
4156 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
4157 << AL << Info->Identifier->getName();
4158 return false;
4159 }
4160
4161 // checks for the 2nd argument
4162 Expr *IdxExpr = AL.getArgAsExpr(1);
4163 if (!S.checkUInt32Argument(AL, IdxExpr, Info->FormatStringIdx, 2))
4164 return false;
4165
4166 if (Info->FormatStringIdx < 1 || Info->FormatStringIdx > Info->NumArgs) {
4167 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
4168 << AL << 2 << IdxExpr->getSourceRange();
4169 return false;
4170 }
4171
4172 // FIXME: Do we need to bounds check?
4173 unsigned ArgIdx = Info->FormatStringIdx - 1;
4174
4175 if (HasImplicitThisParam) {
4176 if (ArgIdx == 0) {
4177 S.Diag(AL.getLoc(),
4178 diag::err_format_attribute_implicit_this_format_string)
4179 << IdxExpr->getSourceRange();
4180 return false;
4181 }
4182 ArgIdx--;
4183 }
4184
4185 // make sure the format string is really a string
4186 QualType Ty = getFunctionOrMethodParamType(D, ArgIdx);
4187
4188 if (!S.ObjC().isNSStringType(Ty, true) && !S.ObjC().isCFStringType(Ty) &&
4189 (!Ty->isPointerType() ||
4191 S.Diag(AL.getLoc(), diag::err_format_attribute_not)
4192 << IdxExpr->getSourceRange()
4193 << getFunctionOrMethodParamRange(D, ArgIdx);
4194 return false;
4195 }
4196
4197 return true;
4198}
4199
4200static void handleFormatAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4201 FormatAttrCommon Info;
4202 if (!handleFormatAttrCommon(S, D, AL, &Info))
4203 return;
4204
4205 // check the 3rd argument
4206 Expr *FirstArgExpr = AL.getArgAsExpr(2);
4207 uint32_t FirstArg;
4208 if (!S.checkUInt32Argument(AL, FirstArgExpr, FirstArg, 3))
4209 return;
4210
4211 // FirstArg == 0 is is always valid.
4212 if (FirstArg != 0) {
4213 if (Info.Kind == StrftimeFormat) {
4214 // If the kind is strftime, FirstArg must be 0 because strftime does not
4215 // use any variadic arguments.
4216 S.Diag(AL.getLoc(), diag::err_format_strftime_third_parameter)
4217 << FirstArgExpr->getSourceRange()
4218 << FixItHint::CreateReplacement(FirstArgExpr->getSourceRange(), "0");
4219 return;
4220 } else if (isFunctionOrMethodVariadic(D)) {
4221 // Else, if the function is variadic, then FirstArg must be 0 or the
4222 // "position" of the ... parameter. It's unusual to use 0 with variadic
4223 // functions, so the fixit proposes the latter.
4224 if (FirstArg != Info.NumArgs + 1) {
4225 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
4226 << AL << 3 << FirstArgExpr->getSourceRange()
4228 std::to_string(Info.NumArgs + 1));
4229 return;
4230 }
4231 } else {
4232 // Inescapable GCC compatibility diagnostic.
4233 S.Diag(D->getLocation(), diag::warn_gcc_requires_variadic_function) << AL;
4234 if (FirstArg <= Info.FormatStringIdx) {
4235 // Else, the function is not variadic, and FirstArg must be 0 or any
4236 // parameter after the format parameter. We don't offer a fixit because
4237 // there are too many possible good values.
4238 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
4239 << AL << 3 << FirstArgExpr->getSourceRange();
4240 return;
4241 }
4242 }
4243 }
4244
4245 FormatAttr *NewAttr =
4246 S.mergeFormatAttr(D, AL, Info.Identifier, Info.FormatStringIdx, FirstArg);
4247 if (NewAttr)
4248 D->addAttr(NewAttr);
4249}
4250
4251static void handleFormatMatchesAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4252 FormatAttrCommon Info;
4253 if (!handleFormatAttrCommon(S, D, AL, &Info))
4254 return;
4255
4256 Expr *FormatStrExpr = AL.getArgAsExpr(2)->IgnoreParenImpCasts();
4257 if (auto *SL = dyn_cast<StringLiteral>(FormatStrExpr)) {
4259 if (S.ValidateFormatString(FST, SL))
4260 if (auto *NewAttr = S.mergeFormatMatchesAttr(D, AL, Info.Identifier,
4261 Info.FormatStringIdx, SL))
4262 D->addAttr(NewAttr);
4263 return;
4264 }
4265
4266 S.Diag(AL.getLoc(), diag::err_format_nonliteral)
4267 << FormatStrExpr->getSourceRange();
4268}
4269
4270/// Handle __attribute__((callback(CalleeIdx, PayloadIdx0, ...))) attributes.
4271static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4272 // The index that identifies the callback callee is mandatory.
4273 if (AL.getNumArgs() == 0) {
4274 S.Diag(AL.getLoc(), diag::err_callback_attribute_no_callee)
4275 << AL.getRange();
4276 return;
4277 }
4278
4279 bool HasImplicitThisParam = hasImplicitObjectParameter(D);
4280 int32_t NumArgs = getFunctionOrMethodNumParams(D);
4281
4282 FunctionDecl *FD = D->getAsFunction();
4283 assert(FD && "Expected a function declaration!");
4284
4285 llvm::StringMap<int> NameIdxMapping;
4286 NameIdxMapping["__"] = -1;
4287
4288 NameIdxMapping["this"] = 0;
4289
4290 int Idx = 1;
4291 for (const ParmVarDecl *PVD : FD->parameters())
4292 NameIdxMapping[PVD->getName()] = Idx++;
4293
4294 auto UnknownName = NameIdxMapping.end();
4295
4296 SmallVector<int, 8> EncodingIndices;
4297 for (unsigned I = 0, E = AL.getNumArgs(); I < E; ++I) {
4298 SourceRange SR;
4299 int32_t ArgIdx;
4300
4301 if (AL.isArgIdent(I)) {
4302 IdentifierLoc *IdLoc = AL.getArgAsIdent(I);
4303 auto It = NameIdxMapping.find(IdLoc->getIdentifierInfo()->getName());
4304 if (It == UnknownName) {
4305 S.Diag(AL.getLoc(), diag::err_callback_attribute_argument_unknown)
4306 << IdLoc->getIdentifierInfo() << IdLoc->getLoc();
4307 return;
4308 }
4309
4310 SR = SourceRange(IdLoc->getLoc());
4311 ArgIdx = It->second;
4312 } else if (AL.isArgExpr(I)) {
4313 Expr *IdxExpr = AL.getArgAsExpr(I);
4314
4315 // If the expression is not parseable as an int32_t we have a problem.
4316 if (!S.checkUInt32Argument(AL, IdxExpr, (uint32_t &)ArgIdx, I + 1,
4317 false)) {
4318 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
4319 << AL << (I + 1) << IdxExpr->getSourceRange();
4320 return;
4321 }
4322
4323 // Check oob, excluding the special values, 0 and -1.
4324 if (ArgIdx < -1 || ArgIdx > NumArgs) {
4325 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
4326 << AL << (I + 1) << IdxExpr->getSourceRange();
4327 return;
4328 }
4329
4330 SR = IdxExpr->getSourceRange();
4331 } else {
4332 llvm_unreachable("Unexpected ParsedAttr argument type!");
4333 }
4334
4335 if (ArgIdx == 0 && !HasImplicitThisParam) {
4336 S.Diag(AL.getLoc(), diag::err_callback_implicit_this_not_available)
4337 << (I + 1) << SR;
4338 return;
4339 }
4340
4341 // Adjust for the case we do not have an implicit "this" parameter. In this
4342 // case we decrease all positive values by 1 to get LLVM argument indices.
4343 if (!HasImplicitThisParam && ArgIdx > 0)
4344 ArgIdx -= 1;
4345
4346 EncodingIndices.push_back(ArgIdx);
4347 }
4348
4349 int CalleeIdx = EncodingIndices.front();
4350 // Check if the callee index is proper, thus not "this" and not "unknown".
4351 // This means the "CalleeIdx" has to be non-negative if "HasImplicitThisParam"
4352 // is false and positive if "HasImplicitThisParam" is true.
4353 if (CalleeIdx < (int)HasImplicitThisParam) {
4354 S.Diag(AL.getLoc(), diag::err_callback_attribute_invalid_callee)
4355 << AL.getRange();
4356 return;
4357 }
4358
4359 // Get the callee type, note the index adjustment as the AST doesn't contain
4360 // the this type (which the callee cannot reference anyway!).
4361 const Type *CalleeType =
4362 getFunctionOrMethodParamType(D, CalleeIdx - HasImplicitThisParam)
4363 .getTypePtr();
4364 if (!CalleeType || !CalleeType->isFunctionPointerType()) {
4365 S.Diag(AL.getLoc(), diag::err_callback_callee_no_function_type)
4366 << AL.getRange();
4367 return;
4368 }
4369
4370 const Type *CalleeFnType =
4372
4373 // TODO: Check the type of the callee arguments.
4374
4375 const auto *CalleeFnProtoType = dyn_cast<FunctionProtoType>(CalleeFnType);
4376 if (!CalleeFnProtoType) {
4377 S.Diag(AL.getLoc(), diag::err_callback_callee_no_function_type)
4378 << AL.getRange();
4379 return;
4380 }
4381
4382 if (CalleeFnProtoType->getNumParams() != EncodingIndices.size() - 1) {
4383 S.Diag(AL.getLoc(), diag::err_attribute_wrong_arg_count_for_func)
4384 << AL << QualType{CalleeFnProtoType, 0}
4385 << CalleeFnProtoType->getNumParams()
4386 << (unsigned)(EncodingIndices.size() - 1);
4387 return;
4388 }
4389
4390 if (CalleeFnProtoType->isVariadic()) {
4391 S.Diag(AL.getLoc(), diag::err_callback_callee_is_variadic) << AL.getRange();
4392 return;
4393 }
4394
4395 // Do not allow multiple callback attributes.
4396 if (D->hasAttr<CallbackAttr>()) {
4397 S.Diag(AL.getLoc(), diag::err_callback_attribute_multiple) << AL.getRange();
4398 return;
4399 }
4400
4401 D->addAttr(::new (S.Context) CallbackAttr(
4402 S.Context, AL, EncodingIndices.data(), EncodingIndices.size()));
4403}
4404
4405LifetimeCaptureByAttr *Sema::ParseLifetimeCaptureByAttr(const ParsedAttr &AL,
4406 StringRef ParamName) {
4407 // Atleast one capture by is required.
4408 if (AL.getNumArgs() == 0) {
4409 Diag(AL.getLoc(), diag::err_capture_by_attribute_no_entity)
4410 << AL.getRange();
4411 return nullptr;
4412 }
4413 unsigned N = AL.getNumArgs();
4414 auto ParamIdents =
4416 auto ParamLocs =
4418 bool IsValid = true;
4419 for (unsigned I = 0; I < N; ++I) {
4420 if (AL.isArgExpr(I)) {
4421 Expr *E = AL.getArgAsExpr(I);
4422 Diag(E->getExprLoc(), diag::err_capture_by_attribute_argument_unknown)
4423 << E << E->getExprLoc();
4424 IsValid = false;
4425 continue;
4426 }
4427 assert(AL.isArgIdent(I));
4428 IdentifierLoc *IdLoc = AL.getArgAsIdent(I);
4429 if (IdLoc->getIdentifierInfo()->getName() == ParamName) {
4430 Diag(IdLoc->getLoc(), diag::err_capture_by_references_itself)
4431 << IdLoc->getLoc();
4432 IsValid = false;
4433 continue;
4434 }
4435 ParamIdents[I] = IdLoc->getIdentifierInfo();
4436 ParamLocs[I] = IdLoc->getLoc();
4437 }
4438 if (!IsValid)
4439 return nullptr;
4440 SmallVector<int> FakeParamIndices(N, LifetimeCaptureByAttr::Invalid);
4441 auto *CapturedBy =
4442 LifetimeCaptureByAttr::Create(Context, FakeParamIndices.data(), N, AL);
4443 CapturedBy->setArgs(ParamIdents, ParamLocs);
4444 return CapturedBy;
4445}
4446
4448 const ParsedAttr &AL) {
4449 // Do not allow multiple attributes.
4450 if (D->hasAttr<LifetimeCaptureByAttr>()) {
4451 S.Diag(AL.getLoc(), diag::err_capture_by_attribute_multiple)
4452 << AL.getRange();
4453 return;
4454 }
4455 auto *PVD = dyn_cast<ParmVarDecl>(D);
4456 assert(PVD);
4457 auto *CaptureByAttr = S.ParseLifetimeCaptureByAttr(AL, PVD->getName());
4458 if (CaptureByAttr)
4459 D->addAttr(CaptureByAttr);
4460}
4461
4463 bool HasImplicitThisParam = hasImplicitObjectParameter(FD);
4465 for (ParmVarDecl *PVD : FD->parameters())
4466 if (auto *A = PVD->getAttr<LifetimeCaptureByAttr>())
4467 Attrs.push_back(A);
4468 if (HasImplicitThisParam) {
4469 TypeSourceInfo *TSI = FD->getTypeSourceInfo();
4470 if (!TSI)
4471 return;
4473 for (TypeLoc TL = TSI->getTypeLoc();
4474 (ATL = TL.getAsAdjusted<AttributedTypeLoc>());
4475 TL = ATL.getModifiedLoc()) {
4476 if (auto *A = ATL.getAttrAs<LifetimeCaptureByAttr>())
4477 Attrs.push_back(const_cast<LifetimeCaptureByAttr *>(A));
4478 }
4479 }
4480 if (Attrs.empty())
4481 return;
4482 llvm::StringMap<int> NameIdxMapping = {
4483 {"global", LifetimeCaptureByAttr::Global},
4484 {"unknown", LifetimeCaptureByAttr::Unknown}};
4485 int Idx = 0;
4486 if (HasImplicitThisParam) {
4487 NameIdxMapping["this"] = 0;
4488 Idx++;
4489 }
4490 for (const ParmVarDecl *PVD : FD->parameters())
4491 NameIdxMapping[PVD->getName()] = Idx++;
4492 auto DisallowReservedParams = [&](StringRef Reserved) {
4493 for (const ParmVarDecl *PVD : FD->parameters())
4494 if (PVD->getName() == Reserved)
4495 Diag(PVD->getLocation(), diag::err_capture_by_param_uses_reserved_name)
4496 << (PVD->getName() == "unknown");
4497 };
4498 for (auto *CapturedBy : Attrs) {
4499 const auto &Entities = CapturedBy->getArgIdents();
4500 for (size_t I = 0; I < Entities.size(); ++I) {
4501 StringRef Name = Entities[I]->getName();
4502 auto It = NameIdxMapping.find(Name);
4503 if (It == NameIdxMapping.end()) {
4504 auto Loc = CapturedBy->getArgLocs()[I];
4505 if (!HasImplicitThisParam && Name == "this")
4506 Diag(Loc, diag::err_capture_by_implicit_this_not_available) << Loc;
4507 else
4508 Diag(Loc, diag::err_capture_by_attribute_argument_unknown)
4509 << Entities[I] << Loc;
4510 continue;
4511 }
4512 if (Name == "unknown" || Name == "global")
4513 DisallowReservedParams(Name);
4514 CapturedBy->setParamIdx(I, It->second);
4515 }
4516 }
4517}
4518
4519static bool isFunctionLike(const Type &T) {
4520 // Check for explicit function types.
4521 // 'called_once' is only supported in Objective-C and it has
4522 // function pointers and block pointers.
4523 return T.isFunctionPointerType() || T.isBlockPointerType();
4524}
4525
4526/// Handle 'called_once' attribute.
4527static void handleCalledOnceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4528 // 'called_once' only applies to parameters representing functions.
4529 QualType T = cast<ParmVarDecl>(D)->getType();
4530
4531 if (!isFunctionLike(*T)) {
4532 S.Diag(AL.getLoc(), diag::err_called_once_attribute_wrong_type);
4533 return;
4534 }
4535
4536 D->addAttr(::new (S.Context) CalledOnceAttr(S.Context, AL));
4537}
4538
4539static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4540 // Try to find the underlying union declaration.
4541 RecordDecl *RD = nullptr;
4542 const auto *TD = dyn_cast<TypedefNameDecl>(D);
4543 if (TD && TD->getUnderlyingType()->isUnionType())
4544 RD = TD->getUnderlyingType()->getAsRecordDecl();
4545 else
4546 RD = dyn_cast<RecordDecl>(D);
4547
4548 if (!RD || !RD->isUnion()) {
4549 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
4551 return;
4552 }
4553
4554 if (!RD->isCompleteDefinition()) {
4555 if (!RD->isBeingDefined())
4556 S.Diag(AL.getLoc(),
4557 diag::warn_transparent_union_attribute_not_definition);
4558 return;
4559 }
4560
4562 FieldEnd = RD->field_end();
4563 if (Field == FieldEnd) {
4564 S.Diag(AL.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
4565 return;
4566 }
4567
4568 FieldDecl *FirstField = *Field;
4569 QualType FirstType = FirstField->getType();
4570 if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
4571 S.Diag(FirstField->getLocation(),
4572 diag::warn_transparent_union_attribute_floating)
4573 << FirstType->isVectorType() << FirstType;
4574 return;
4575 }
4576
4577 if (FirstType->isIncompleteType())
4578 return;
4579 uint64_t FirstSize = S.Context.getTypeSize(FirstType);
4580 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
4581 for (; Field != FieldEnd; ++Field) {
4582 QualType FieldType = Field->getType();
4583 if (FieldType->isIncompleteType())
4584 return;
4585 // FIXME: this isn't fully correct; we also need to test whether the
4586 // members of the union would all have the same calling convention as the
4587 // first member of the union. Checking just the size and alignment isn't
4588 // sufficient (consider structs passed on the stack instead of in registers
4589 // as an example).
4590 if (S.Context.getTypeSize(FieldType) != FirstSize ||
4591 S.Context.getTypeAlign(FieldType) > FirstAlign) {
4592 // Warn if we drop the attribute.
4593 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
4594 unsigned FieldBits = isSize ? S.Context.getTypeSize(FieldType)
4595 : S.Context.getTypeAlign(FieldType);
4596 S.Diag(Field->getLocation(),
4597 diag::warn_transparent_union_attribute_field_size_align)
4598 << isSize << *Field << FieldBits;
4599 unsigned FirstBits = isSize ? FirstSize : FirstAlign;
4600 S.Diag(FirstField->getLocation(),
4601 diag::note_transparent_union_first_field_size_align)
4602 << isSize << FirstBits;
4603 return;
4604 }
4605 }
4606
4607 RD->addAttr(::new (S.Context) TransparentUnionAttr(S.Context, AL));
4608}
4609
4610static void handleAnnotateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4611 auto *Attr = S.CreateAnnotationAttr(AL);
4612 if (Attr) {
4613 D->addAttr(Attr);
4614 }
4615}
4616
4617static void handleAlignValueAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4618 S.AddAlignValueAttr(D, AL, AL.getArgAsExpr(0));
4619}
4620
4622 SourceLocation AttrLoc = CI.getLoc();
4623
4624 QualType T;
4625 if (const auto *TD = dyn_cast<TypedefNameDecl>(D))
4626 T = TD->getUnderlyingType();
4627 else if (const auto *VD = dyn_cast<ValueDecl>(D))
4628 T = VD->getType();
4629 else
4630 llvm_unreachable("Unknown decl type for align_value");
4631
4632 if (!T->isDependentType() && !T->isAnyPointerType() &&
4633 !T->isReferenceType() && !T->isMemberPointerType()) {
4634 Diag(AttrLoc, diag::warn_attribute_pointer_or_reference_only)
4635 << CI << T << D->getSourceRange();
4636 return;
4637 }
4638
4639 if (!E->isValueDependent()) {
4640 llvm::APSInt Alignment;
4642 E, &Alignment, diag::err_align_value_attribute_argument_not_int);
4643 if (ICE.isInvalid())
4644 return;
4645
4646 if (!Alignment.isPowerOf2()) {
4647 Diag(AttrLoc, diag::err_alignment_not_power_of_two)
4648 << E->getSourceRange();
4649 return;
4650 }
4651
4652 D->addAttr(::new (Context) AlignValueAttr(Context, CI, ICE.get()));
4653 return;
4654 }
4655
4656 // Save dependent expressions in the AST to be instantiated.
4657 D->addAttr(::new (Context) AlignValueAttr(Context, CI, E));
4658}
4659
4660static void handleAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4661 if (AL.hasParsedType()) {
4662 const ParsedType &TypeArg = AL.getTypeArg();
4663 TypeSourceInfo *TInfo;
4664 (void)S.GetTypeFromParser(
4665 ParsedType::getFromOpaquePtr(TypeArg.getAsOpaquePtr()), &TInfo);
4666 if (AL.isPackExpansion() &&
4668 S.Diag(AL.getEllipsisLoc(),
4669 diag::err_pack_expansion_without_parameter_packs);
4670 return;
4671 }
4672
4673 if (!AL.isPackExpansion() &&
4675 TInfo, Sema::UPPC_Expression))
4676 return;
4677
4678 S.AddAlignedAttr(D, AL, TInfo, AL.isPackExpansion());
4679 return;
4680 }
4681
4682 // check the attribute arguments.
4683 if (AL.getNumArgs() > 1) {
4684 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
4685 return;
4686 }
4687
4688 if (AL.getNumArgs() == 0) {
4689 D->addAttr(::new (S.Context) AlignedAttr(S.Context, AL, true, nullptr));
4690 return;
4691 }
4692
4693 Expr *E = AL.getArgAsExpr(0);
4695 S.Diag(AL.getEllipsisLoc(),
4696 diag::err_pack_expansion_without_parameter_packs);
4697 return;
4698 }
4699
4701 return;
4702
4703 S.AddAlignedAttr(D, AL, E, AL.isPackExpansion());
4704}
4705
4706/// Perform checking of type validity
4707///
4708/// C++11 [dcl.align]p1:
4709/// An alignment-specifier may be applied to a variable or to a class
4710/// data member, but it shall not be applied to a bit-field, a function
4711/// parameter, the formal parameter of a catch clause, or a variable
4712/// declared with the register storage class specifier. An
4713/// alignment-specifier may also be applied to the declaration of a class
4714/// or enumeration type.
4715/// CWG 2354:
4716/// CWG agreed to remove permission for alignas to be applied to
4717/// enumerations.
4718/// C11 6.7.5/2:
4719/// An alignment attribute shall not be specified in a declaration of
4720/// a typedef, or a bit-field, or a function, or a parameter, or an
4721/// object declared with the register storage-class specifier.
4723 const AlignedAttr &Attr,
4724 SourceLocation AttrLoc) {
4725 int DiagKind = -1;
4726 if (isa<ParmVarDecl>(D)) {
4727 DiagKind = 0;
4728 } else if (const auto *VD = dyn_cast<VarDecl>(D)) {
4729 if (VD->getStorageClass() == SC_Register)
4730 DiagKind = 1;
4731 if (VD->isExceptionVariable())
4732 DiagKind = 2;
4733 } else if (const auto *FD = dyn_cast<FieldDecl>(D)) {
4734 if (FD->isBitField())
4735 DiagKind = 3;
4736 } else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
4737 if (ED->getLangOpts().CPlusPlus)
4738 DiagKind = 4;
4739 } else if (!isa<TagDecl>(D)) {
4740 return S.Diag(AttrLoc, diag::err_attribute_wrong_decl_type)
4742 << (Attr.isC11() ? ExpectedVariableOrField
4744 }
4745 if (DiagKind != -1) {
4746 return S.Diag(AttrLoc, diag::err_alignas_attribute_wrong_decl_type)
4747 << &Attr << DiagKind;
4748 }
4749 return false;
4750}
4751
4753 bool IsPackExpansion) {
4754 AlignedAttr TmpAttr(Context, CI, true, E);
4755 SourceLocation AttrLoc = CI.getLoc();
4756
4757 // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
4758 if (TmpAttr.isAlignas() &&
4759 validateAlignasAppliedType(*this, D, TmpAttr, AttrLoc))
4760 return;
4761
4762 if (E->isValueDependent()) {
4763 // We can't support a dependent alignment on a non-dependent type,
4764 // because we have no way to model that a type is "alignment-dependent"
4765 // but not dependent in any other way.
4766 if (const auto *TND = dyn_cast<TypedefNameDecl>(D)) {
4767 if (!TND->getUnderlyingType()->isDependentType()) {
4768 Diag(AttrLoc, diag::err_alignment_dependent_typedef_name)
4769 << E->getSourceRange();
4770 return;
4771 }
4772 }
4773
4774 // Save dependent expressions in the AST to be instantiated.
4775 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, E);
4776 AA->setPackExpansion(IsPackExpansion);
4777 D->addAttr(AA);
4778 return;
4779 }
4780
4781 // FIXME: Cache the number on the AL object?
4782 llvm::APSInt Alignment;
4784 E, &Alignment, diag::err_aligned_attribute_argument_not_int);
4785 if (ICE.isInvalid())
4786 return;
4787
4789 if (Context.getTargetInfo().getTriple().isOSBinFormatCOFF())
4790 MaximumAlignment = std::min(MaximumAlignment, uint64_t(8192));
4791 if (Alignment > MaximumAlignment) {
4792 Diag(AttrLoc, diag::err_attribute_aligned_too_great)
4794 return;
4795 }
4796
4797 uint64_t AlignVal = Alignment.getZExtValue();
4798 // C++11 [dcl.align]p2:
4799 // -- if the constant expression evaluates to zero, the alignment
4800 // specifier shall have no effect
4801 // C11 6.7.5p6:
4802 // An alignment specification of zero has no effect.
4803 if (!(TmpAttr.isAlignas() && !Alignment)) {
4804 if (!llvm::isPowerOf2_64(AlignVal)) {
4805 Diag(AttrLoc, diag::err_alignment_not_power_of_two)
4806 << E->getSourceRange();
4807 return;
4808 }
4809 }
4810
4811 const auto *VD = dyn_cast<VarDecl>(D);
4812 if (VD) {
4813 unsigned MaxTLSAlign =
4814 Context.toCharUnitsFromBits(Context.getTargetInfo().getMaxTLSAlign())
4815 .getQuantity();
4816 if (MaxTLSAlign && AlignVal > MaxTLSAlign &&
4817 VD->getTLSKind() != VarDecl::TLS_None) {
4818 Diag(VD->getLocation(), diag::err_tls_var_aligned_over_maximum)
4819 << (unsigned)AlignVal << VD << MaxTLSAlign;
4820 return;
4821 }
4822 }
4823
4824 // On AIX, an aligned attribute can not decrease the alignment when applied
4825 // to a variable declaration with vector type.
4826 if (VD && Context.getTargetInfo().getTriple().isOSAIX()) {
4827 const Type *Ty = VD->getType().getTypePtr();
4828 if (Ty->isVectorType() && AlignVal < 16) {
4829 Diag(VD->getLocation(), diag::warn_aligned_attr_underaligned)
4830 << VD->getType() << 16;
4831 return;
4832 }
4833 }
4834
4835 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, ICE.get());
4836 AA->setPackExpansion(IsPackExpansion);
4837 AA->setCachedAlignmentValue(
4838 static_cast<unsigned>(AlignVal * Context.getCharWidth()));
4839 D->addAttr(AA);
4840}
4841
4843 TypeSourceInfo *TS, bool IsPackExpansion) {
4844 AlignedAttr TmpAttr(Context, CI, false, TS);
4845 SourceLocation AttrLoc = CI.getLoc();
4846
4847 // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
4848 if (TmpAttr.isAlignas() &&
4849 validateAlignasAppliedType(*this, D, TmpAttr, AttrLoc))
4850 return;
4851
4852 if (TS->getType()->isDependentType()) {
4853 // We can't support a dependent alignment on a non-dependent type,
4854 // because we have no way to model that a type is "type-dependent"
4855 // but not dependent in any other way.
4856 if (const auto *TND = dyn_cast<TypedefNameDecl>(D)) {
4857 if (!TND->getUnderlyingType()->isDependentType()) {
4858 Diag(AttrLoc, diag::err_alignment_dependent_typedef_name)
4859 << TS->getTypeLoc().getSourceRange();
4860 return;
4861 }
4862 }
4863
4864 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, false, TS);
4865 AA->setPackExpansion(IsPackExpansion);
4866 D->addAttr(AA);
4867 return;
4868 }
4869
4870 const auto *VD = dyn_cast<VarDecl>(D);
4871 unsigned AlignVal = TmpAttr.getAlignment(Context);
4872 // On AIX, an aligned attribute can not decrease the alignment when applied
4873 // to a variable declaration with vector type.
4874 if (VD && Context.getTargetInfo().getTriple().isOSAIX()) {
4875 const Type *Ty = VD->getType().getTypePtr();
4876 if (Ty->isVectorType() &&
4877 Context.toCharUnitsFromBits(AlignVal).getQuantity() < 16) {
4878 Diag(VD->getLocation(), diag::warn_aligned_attr_underaligned)
4879 << VD->getType() << 16;
4880 return;
4881 }
4882 }
4883
4884 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, false, TS);
4885 AA->setPackExpansion(IsPackExpansion);
4886 AA->setCachedAlignmentValue(AlignVal);
4887 D->addAttr(AA);
4888}
4889
4891 assert(D->hasAttrs() && "no attributes on decl");
4892
4893 QualType UnderlyingTy, DiagTy;
4894 if (const auto *VD = dyn_cast<ValueDecl>(D)) {
4895 UnderlyingTy = DiagTy = VD->getType();
4896 } else {
4897 UnderlyingTy = DiagTy = Context.getCanonicalTagType(cast<TagDecl>(D));
4898 if (const auto *ED = dyn_cast<EnumDecl>(D))
4899 UnderlyingTy = ED->getIntegerType();
4900 }
4901 if (DiagTy->isDependentType() || DiagTy->isIncompleteType())
4902 return;
4903
4904 // C++11 [dcl.align]p5, C11 6.7.5/4:
4905 // The combined effect of all alignment attributes in a declaration shall
4906 // not specify an alignment that is less strict than the alignment that
4907 // would otherwise be required for the entity being declared.
4908 AlignedAttr *AlignasAttr = nullptr;
4909 AlignedAttr *LastAlignedAttr = nullptr;
4910 unsigned Align = 0;
4911 for (auto *I : D->specific_attrs<AlignedAttr>()) {
4912 if (I->isAlignmentDependent())
4913 return;
4914 if (I->isAlignas())
4915 AlignasAttr = I;
4916 Align = std::max(Align, I->getAlignment(Context));
4917 LastAlignedAttr = I;
4918 }
4919
4920 if (Align && DiagTy->isSizelessType()) {
4921 Diag(LastAlignedAttr->getLocation(), diag::err_attribute_sizeless_type)
4922 << LastAlignedAttr << DiagTy;
4923 } else if (AlignasAttr && Align) {
4924 CharUnits RequestedAlign = Context.toCharUnitsFromBits(Align);
4925 CharUnits NaturalAlign = Context.getTypeAlignInChars(UnderlyingTy);
4926 if (NaturalAlign > RequestedAlign)
4927 Diag(AlignasAttr->getLocation(), diag::err_alignas_underaligned)
4928 << DiagTy << (unsigned)NaturalAlign.getQuantity();
4929 }
4930}
4931
4933 CXXRecordDecl *RD, SourceRange Range, bool BestCase,
4934 MSInheritanceModel ExplicitModel) {
4935 assert(RD->hasDefinition() && "RD has no definition!");
4936
4937 // We may not have seen base specifiers or any virtual methods yet. We will
4938 // have to wait until the record is defined to catch any mismatches.
4939 if (!RD->getDefinition()->isCompleteDefinition())
4940 return false;
4941
4942 // The unspecified model never matches what a definition could need.
4943 if (ExplicitModel == MSInheritanceModel::Unspecified)
4944 return false;
4945
4946 if (BestCase) {
4947 if (RD->calculateInheritanceModel() == ExplicitModel)
4948 return false;
4949 } else {
4950 if (RD->calculateInheritanceModel() <= ExplicitModel)
4951 return false;
4952 }
4953
4954 Diag(Range.getBegin(), diag::err_mismatched_ms_inheritance)
4955 << 0 /*definition*/;
4956 Diag(RD->getDefinition()->getLocation(), diag::note_defined_here) << RD;
4957 return true;
4958}
4959
4960/// parseModeAttrArg - Parses attribute mode string and returns parsed type
4961/// attribute.
4962static void parseModeAttrArg(Sema &S, StringRef Str, unsigned &DestWidth,
4963 bool &IntegerMode, bool &ComplexMode,
4964 FloatModeKind &ExplicitType) {
4965 IntegerMode = true;
4966 ComplexMode = false;
4967 ExplicitType = FloatModeKind::NoFloat;
4968 switch (Str.size()) {
4969 case 2:
4970 switch (Str[0]) {
4971 case 'Q':
4972 DestWidth = 8;
4973 break;
4974 case 'H':
4975 DestWidth = 16;
4976 break;
4977 case 'S':
4978 DestWidth = 32;
4979 break;
4980 case 'D':
4981 DestWidth = 64;
4982 break;
4983 case 'X':
4984 DestWidth = 96;
4985 break;
4986 case 'K': // KFmode - IEEE quad precision (__float128)
4987 ExplicitType = FloatModeKind::Float128;
4988 DestWidth = Str[1] == 'I' ? 0 : 128;
4989 break;
4990 case 'T':
4991 ExplicitType = FloatModeKind::LongDouble;
4992 DestWidth = 128;
4993 break;
4994 case 'I':
4995 ExplicitType = FloatModeKind::Ibm128;
4996 DestWidth = Str[1] == 'I' ? 0 : 128;
4997 break;
4998 }
4999 if (Str[1] == 'F') {
5000 IntegerMode = false;
5001 } else if (Str[1] == 'C') {
5002 IntegerMode = false;
5003 ComplexMode = true;
5004 } else if (Str[1] != 'I') {
5005 DestWidth = 0;
5006 }
5007 break;
5008 case 4:
5009 // FIXME: glibc uses 'word' to define register_t; this is narrower than a
5010 // pointer on PIC16 and other embedded platforms.
5011 if (Str == "word")
5012 DestWidth = S.Context.getTargetInfo().getRegisterWidth();
5013 else if (Str == "byte")
5014 DestWidth = S.Context.getTargetInfo().getCharWidth();
5015 break;
5016 case 7:
5017 if (Str == "pointer")
5019 break;
5020 case 11:
5021 if (Str == "unwind_word")
5022 DestWidth = S.Context.getTargetInfo().getUnwindWordWidth();
5023 break;
5024 }
5025}
5026
5027/// handleModeAttr - This attribute modifies the width of a decl with primitive
5028/// type.
5029///
5030/// Despite what would be logical, the mode attribute is a decl attribute, not a
5031/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
5032/// HImode, not an intermediate pointer.
5033static void handleModeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5034 // This attribute isn't documented, but glibc uses it. It changes
5035 // the width of an int or unsigned int to the specified size.
5036 if (!AL.isArgIdent(0)) {
5037 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
5038 << AL << AANT_ArgumentIdentifier;
5039 return;
5040 }
5041
5043
5044 S.AddModeAttr(D, AL, Name);
5045}
5046
5048 const IdentifierInfo *Name, bool InInstantiation) {
5049 StringRef Str = Name->getName();
5050 normalizeName(Str);
5051 SourceLocation AttrLoc = CI.getLoc();
5052
5053 unsigned DestWidth = 0;
5054 bool IntegerMode = true;
5055 bool ComplexMode = false;
5057 llvm::APInt VectorSize(64, 0);
5058 if (Str.size() >= 4 && Str[0] == 'V') {
5059 // Minimal length of vector mode is 4: 'V' + NUMBER(>=1) + TYPE(>=2).
5060 size_t StrSize = Str.size();
5061 size_t VectorStringLength = 0;
5062 while ((VectorStringLength + 1) < StrSize &&
5063 isdigit(Str[VectorStringLength + 1]))
5064 ++VectorStringLength;
5065 if (VectorStringLength &&
5066 !Str.substr(1, VectorStringLength).getAsInteger(10, VectorSize) &&
5067 VectorSize.isPowerOf2()) {
5068 parseModeAttrArg(*this, Str.substr(VectorStringLength + 1), DestWidth,
5069 IntegerMode, ComplexMode, ExplicitType);
5070 // Avoid duplicate warning from template instantiation.
5071 if (!InInstantiation)
5072 Diag(AttrLoc, diag::warn_vector_mode_deprecated);
5073 } else {
5074 VectorSize = 0;
5075 }
5076 }
5077
5078 if (!VectorSize)
5079 parseModeAttrArg(*this, Str, DestWidth, IntegerMode, ComplexMode,
5080 ExplicitType);
5081
5082 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
5083 // and friends, at least with glibc.
5084 // FIXME: Make sure floating-point mappings are accurate
5085 // FIXME: Support XF and TF types
5086 if (!DestWidth) {
5087 Diag(AttrLoc, diag::err_machine_mode) << 0 /*Unknown*/ << Name;
5088 return;
5089 }
5090
5091 QualType OldTy;
5092 if (const auto *TD = dyn_cast<TypedefNameDecl>(D))
5093 OldTy = TD->getUnderlyingType();
5094 else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
5095 // Something like 'typedef enum { X } __attribute__((mode(XX))) T;'.
5096 // Try to get type from enum declaration, default to int.
5097 OldTy = ED->getIntegerType();
5098 if (OldTy.isNull())
5099 OldTy = Context.IntTy;
5100 } else
5101 OldTy = cast<ValueDecl>(D)->getType();
5102
5103 if (OldTy->isDependentType()) {
5104 D->addAttr(::new (Context) ModeAttr(Context, CI, Name));
5105 return;
5106 }
5107
5108 // Base type can also be a vector type (see PR17453).
5109 // Distinguish between base type and base element type.
5110 QualType OldElemTy = OldTy;
5111 if (const auto *VT = OldTy->getAs<VectorType>())
5112 OldElemTy = VT->getElementType();
5113
5114 // GCC allows 'mode' attribute on enumeration types (even incomplete), except
5115 // for vector modes. So, 'enum X __attribute__((mode(QI)));' forms a complete
5116 // type, 'enum { A } __attribute__((mode(V4SI)))' is rejected.
5117 if ((isa<EnumDecl>(D) || OldElemTy->isEnumeralType()) &&
5118 VectorSize.getBoolValue()) {
5119 Diag(AttrLoc, diag::err_enum_mode_vector_type) << Name << CI.getRange();
5120 return;
5121 }
5122 bool IntegralOrAnyEnumType = (OldElemTy->isIntegralOrEnumerationType() &&
5123 !OldElemTy->isBitIntType()) ||
5124 OldElemTy->isEnumeralType();
5125
5126 if (!OldElemTy->getAs<BuiltinType>() && !OldElemTy->isComplexType() &&
5127 !IntegralOrAnyEnumType)
5128 Diag(AttrLoc, diag::err_mode_not_primitive);
5129 else if (IntegerMode) {
5130 if (!IntegralOrAnyEnumType)
5131 Diag(AttrLoc, diag::err_mode_wrong_type);
5132 } else if (ComplexMode) {
5133 if (!OldElemTy->isComplexType())
5134 Diag(AttrLoc, diag::err_mode_wrong_type);
5135 } else {
5136 if (!OldElemTy->isFloatingType())
5137 Diag(AttrLoc, diag::err_mode_wrong_type);
5138 }
5139
5140 QualType NewElemTy;
5141
5142 if (IntegerMode)
5143 NewElemTy = Context.getIntTypeForBitwidth(DestWidth,
5144 OldElemTy->isSignedIntegerType());
5145 else
5146 NewElemTy = Context.getRealTypeForBitwidth(DestWidth, ExplicitType);
5147
5148 if (NewElemTy.isNull()) {
5149 // Only emit diagnostic on host for 128-bit mode attribute
5150 if (!(DestWidth == 128 &&
5151 (getLangOpts().CUDAIsDevice || getLangOpts().SYCLIsDevice)))
5152 Diag(AttrLoc, diag::err_machine_mode) << 1 /*Unsupported*/ << Name;
5153 return;
5154 }
5155
5156 if (ComplexMode) {
5157 NewElemTy = Context.getComplexType(NewElemTy);
5158 }
5159
5160 QualType NewTy = NewElemTy;
5161 if (VectorSize.getBoolValue()) {
5162 NewTy = Context.getVectorType(NewTy, VectorSize.getZExtValue(),
5164 } else if (const auto *OldVT = OldTy->getAs<VectorType>()) {
5165 // Complex machine mode does not support base vector types.
5166 if (ComplexMode) {
5167 Diag(AttrLoc, diag::err_complex_mode_vector_type);
5168 return;
5169 }
5170 unsigned NumElements = Context.getTypeSize(OldElemTy) *
5171 OldVT->getNumElements() /
5172 Context.getTypeSize(NewElemTy);
5173 NewTy =
5174 Context.getVectorType(NewElemTy, NumElements, OldVT->getVectorKind());
5175 }
5176
5177 if (NewTy.isNull()) {
5178 Diag(AttrLoc, diag::err_mode_wrong_type);
5179 return;
5180 }
5181
5182 // Install the new type.
5183 if (auto *TD = dyn_cast<TypedefNameDecl>(D))
5184 TD->setModedTypeSourceInfo(TD->getTypeSourceInfo(), NewTy);
5185 else if (auto *ED = dyn_cast<EnumDecl>(D))
5186 ED->setIntegerType(NewTy);
5187 else
5188 cast<ValueDecl>(D)->setType(NewTy);
5189
5190 D->addAttr(::new (Context) ModeAttr(Context, CI, Name));
5191}
5192
5193static void handleNonStringAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5194 // This only applies to fields and variable declarations which have an array
5195 // type or pointer type, with character elements.
5196 QualType QT = cast<ValueDecl>(D)->getType();
5197 if ((!QT->isArrayType() && !QT->isPointerType()) ||
5199 S.Diag(D->getBeginLoc(), diag::warn_attribute_non_character_array)
5200 << AL << AL.isRegularKeywordAttribute() << QT << AL.getRange();
5201 return;
5202 }
5203
5204 D->addAttr(::new (S.Context) NonStringAttr(S.Context, AL));
5205}
5206
5207static void handleNoDebugAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5208 D->addAttr(::new (S.Context) NoDebugAttr(S.Context, AL));
5209}
5210
5212 const AttributeCommonInfo &CI,
5213 const IdentifierInfo *Ident) {
5214 if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
5215 Diag(CI.getLoc(), diag::warn_attribute_ignored) << Ident;
5216 Diag(Optnone->getLocation(), diag::note_conflicting_attribute);
5217 return nullptr;
5218 }
5219
5220 if (D->hasAttr<AlwaysInlineAttr>())
5221 return nullptr;
5222
5223 return ::new (Context) AlwaysInlineAttr(Context, CI);
5224}
5225
5226InternalLinkageAttr *Sema::mergeInternalLinkageAttr(Decl *D,
5227 const ParsedAttr &AL) {
5228 if (const auto *VD = dyn_cast<VarDecl>(D)) {
5229 // Attribute applies to Var but not any subclass of it (like ParmVar,
5230 // ImplicitParm or VarTemplateSpecialization).
5231 if (VD->getKind() != Decl::Var) {
5232 Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
5233 << AL << AL.isRegularKeywordAttribute()
5236 return nullptr;
5237 }
5238 // Attribute does not apply to non-static local variables.
5239 if (VD->hasLocalStorage()) {
5240 Diag(VD->getLocation(), diag::warn_internal_linkage_local_storage);
5241 return nullptr;
5242 }
5243 }
5244
5245 return ::new (Context) InternalLinkageAttr(Context, AL);
5246}
5247InternalLinkageAttr *
5248Sema::mergeInternalLinkageAttr(Decl *D, const InternalLinkageAttr &AL) {
5249 if (const auto *VD = dyn_cast<VarDecl>(D)) {
5250 // Attribute applies to Var but not any subclass of it (like ParmVar,
5251 // ImplicitParm or VarTemplateSpecialization).
5252 if (VD->getKind() != Decl::Var) {
5253 Diag(AL.getLocation(), diag::warn_attribute_wrong_decl_type)
5254 << &AL << AL.isRegularKeywordAttribute()
5257 return nullptr;
5258 }
5259 // Attribute does not apply to non-static local variables.
5260 if (VD->hasLocalStorage()) {
5261 Diag(VD->getLocation(), diag::warn_internal_linkage_local_storage);
5262 return nullptr;
5263 }
5264 }
5265
5266 return ::new (Context) InternalLinkageAttr(Context, AL);
5267}
5268
5270 if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
5271 Diag(CI.getLoc(), diag::warn_attribute_ignored) << "'minsize'";
5272 Diag(Optnone->getLocation(), diag::note_conflicting_attribute);
5273 return nullptr;
5274 }
5275
5276 if (D->hasAttr<MinSizeAttr>())
5277 return nullptr;
5278
5279 return ::new (Context) MinSizeAttr(Context, CI);
5280}
5281
5283 const AttributeCommonInfo &CI) {
5284 if (AlwaysInlineAttr *Inline = D->getAttr<AlwaysInlineAttr>()) {
5285 Diag(Inline->getLocation(), diag::warn_attribute_ignored) << Inline;
5286 Diag(CI.getLoc(), diag::note_conflicting_attribute);
5287 D->dropAttr<AlwaysInlineAttr>();
5288 }
5289 if (MinSizeAttr *MinSize = D->getAttr<MinSizeAttr>()) {
5290 Diag(MinSize->getLocation(), diag::warn_attribute_ignored) << MinSize;
5291 Diag(CI.getLoc(), diag::note_conflicting_attribute);
5292 D->dropAttr<MinSizeAttr>();
5293 }
5294
5295 if (D->hasAttr<OptimizeNoneAttr>())
5296 return nullptr;
5297
5298 return ::new (Context) OptimizeNoneAttr(Context, CI);
5299}
5300
5301static void handleAlwaysInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5302 AlwaysInlineAttr AIA(S.Context, AL);
5303 if (!S.getLangOpts().MicrosoftExt &&
5304 (AIA.isMSVCForceInline() || AIA.isMSVCForceInlineCalls())) {
5305 S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
5306 return;
5307 }
5308 if (AIA.isMSVCForceInlineCalls()) {
5309 S.Diag(AL.getLoc(), diag::warn_stmt_attribute_ignored_in_function)
5310 << "[[msvc::forceinline]]";
5311 return;
5312 }
5313
5314 if (AlwaysInlineAttr *Inline =
5315 S.mergeAlwaysInlineAttr(D, AL, AL.getAttrName()))
5316 D->addAttr(Inline);
5317}
5318
5319static void handleMinSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5320 if (MinSizeAttr *MinSize = S.mergeMinSizeAttr(D, AL))
5321 D->addAttr(MinSize);
5322}
5323
5324static void handleOptimizeNoneAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5325 if (OptimizeNoneAttr *Optnone = S.mergeOptimizeNoneAttr(D, AL))
5326 D->addAttr(Optnone);
5327}
5328
5329static void handleConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5330 const auto *VD = cast<VarDecl>(D);
5331 if (VD->hasLocalStorage()) {
5332 S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
5333 return;
5334 }
5336 return;
5337 // constexpr variable may already get an implicit constant attr, which should
5338 // be replaced by the explicit constant attr.
5339 if (auto *A = D->getAttr<CUDAConstantAttr>()) {
5340 if (!A->isImplicit())
5341 return;
5342 D->dropAttr<CUDAConstantAttr>();
5343 }
5344 D->addAttr(::new (S.Context) CUDAConstantAttr(S.Context, AL));
5345}
5346
5347static void handleSharedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5348 const auto *VD = cast<VarDecl>(D);
5349 // extern __shared__ is only allowed on arrays with no length (e.g.
5350 // "int x[]").
5351 if (!S.getLangOpts().GPURelocatableDeviceCode && VD->hasExternalStorage() &&
5352 !isa<IncompleteArrayType>(VD->getType())) {
5353 S.Diag(AL.getLoc(), diag::err_cuda_extern_shared) << VD;
5354 return;
5355 }
5357 return;
5358 if (S.getLangOpts().CUDA && VD->hasLocalStorage() &&
5359 S.CUDA().DiagIfHostCode(AL.getLoc(), diag::err_cuda_host_shared)
5360 << S.CUDA().CurrentTarget())
5361 return;
5362 D->addAttr(::new (S.Context) CUDASharedAttr(S.Context, AL));
5363}
5364
5365static void handleGlobalAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5366 const auto *FD = cast<FunctionDecl>(D);
5367 if (!FD->getReturnType()->isVoidType() &&
5368 !FD->getReturnType()->getAs<AutoType>() &&
5370 SourceRange RTRange = FD->getReturnTypeSourceRange();
5371 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
5372 << FD->getType()
5373 << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void")
5374 : FixItHint());
5375 return;
5376 }
5377 if (const auto *Method = dyn_cast<CXXMethodDecl>(FD)) {
5378 if (Method->isInstance()) {
5379 S.Diag(Method->getBeginLoc(), diag::err_kern_is_nonstatic_method)
5380 << Method;
5381 return;
5382 }
5383 S.Diag(Method->getBeginLoc(), diag::warn_kern_is_method) << Method;
5384 }
5385 // Only warn for "inline" when compiling for host, to cut down on noise.
5386 if (FD->isInlineSpecified() && !S.getLangOpts().CUDAIsDevice)
5387 S.Diag(FD->getBeginLoc(), diag::warn_kern_is_inline) << FD;
5388
5389 if (AL.getKind() == ParsedAttr::AT_DeviceKernel)
5390 D->addAttr(::new (S.Context) DeviceKernelAttr(S.Context, AL));
5391 else
5392 D->addAttr(::new (S.Context) CUDAGlobalAttr(S.Context, AL));
5393 // In host compilation the kernel is emitted as a stub function, which is
5394 // a helper function for launching the kernel. The instructions in the helper
5395 // function has nothing to do with the source code of the kernel. Do not emit
5396 // debug info for the stub function to avoid confusing the debugger.
5397 if (S.LangOpts.HIP && !S.LangOpts.CUDAIsDevice)
5398 D->addAttr(NoDebugAttr::CreateImplicit(S.Context));
5399}
5400
5401static void handleDeviceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5402 if (const auto *VD = dyn_cast<VarDecl>(D)) {
5403 if (VD->hasLocalStorage()) {
5404 S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
5405 return;
5406 }
5408 return;
5409 }
5410
5411 if (auto *A = D->getAttr<CUDADeviceAttr>()) {
5412 if (!A->isImplicit())
5413 return;
5414 D->dropAttr<CUDADeviceAttr>();
5415 }
5416 D->addAttr(::new (S.Context) CUDADeviceAttr(S.Context, AL));
5417}
5418
5419static void handleManagedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5420 if (const auto *VD = dyn_cast<VarDecl>(D)) {
5421 if (VD->hasLocalStorage()) {
5422 S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
5423 return;
5424 }
5426 return;
5427 }
5428 if (!D->hasAttr<HIPManagedAttr>())
5429 D->addAttr(::new (S.Context) HIPManagedAttr(S.Context, AL));
5430 if (!D->hasAttr<CUDADeviceAttr>())
5431 D->addAttr(CUDADeviceAttr::CreateImplicit(S.Context));
5432}
5433
5434static void handleGridConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5435 if (D->isInvalidDecl())
5436 return;
5437 // Whether __grid_constant__ is allowed to be used will be checked in
5438 // Sema::CheckFunctionDeclaration as we need complete function decl to make
5439 // the call.
5440 D->addAttr(::new (S.Context) CUDAGridConstantAttr(S.Context, AL));
5441}
5442
5443static void handleGNUInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5444 const auto *Fn = cast<FunctionDecl>(D);
5445 if (!Fn->isInlineSpecified()) {
5446 S.Diag(AL.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
5447 return;
5448 }
5449
5450 if (S.LangOpts.CPlusPlus && Fn->getStorageClass() != SC_Extern)
5451 S.Diag(AL.getLoc(), diag::warn_gnu_inline_cplusplus_without_extern);
5452
5453 D->addAttr(::new (S.Context) GNUInlineAttr(S.Context, AL));
5454}
5455
5456static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5457 if (hasDeclarator(D)) return;
5458
5459 // Diagnostic is emitted elsewhere: here we store the (valid) AL
5460 // in the Decl node for syntactic reasoning, e.g., pretty-printing.
5461 CallingConv CC;
5463 AL, CC, /*FD*/ nullptr,
5464 S.CUDA().IdentifyTarget(dyn_cast<FunctionDecl>(D))))
5465 return;
5466
5467 if (!isa<ObjCMethodDecl>(D)) {
5468 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
5470 return;
5471 }
5472
5473 switch (AL.getKind()) {
5474 case ParsedAttr::AT_FastCall:
5475 D->addAttr(::new (S.Context) FastCallAttr(S.Context, AL));
5476 return;
5477 case ParsedAttr::AT_StdCall:
5478 D->addAttr(::new (S.Context) StdCallAttr(S.Context, AL));
5479 return;
5480 case ParsedAttr::AT_ThisCall:
5481 D->addAttr(::new (S.Context) ThisCallAttr(S.Context, AL));
5482 return;
5483 case ParsedAttr::AT_CDecl:
5484 D->addAttr(::new (S.Context) CDeclAttr(S.Context, AL));
5485 return;
5486 case ParsedAttr::AT_Pascal:
5487 D->addAttr(::new (S.Context) PascalAttr(S.Context, AL));
5488 return;
5489 case ParsedAttr::AT_SwiftCall:
5490 D->addAttr(::new (S.Context) SwiftCallAttr(S.Context, AL));
5491 return;
5492 case ParsedAttr::AT_SwiftAsyncCall:
5493 D->addAttr(::new (S.Context) SwiftAsyncCallAttr(S.Context, AL));
5494 return;
5495 case ParsedAttr::AT_VectorCall:
5496 D->addAttr(::new (S.Context) VectorCallAttr(S.Context, AL));
5497 return;
5498 case ParsedAttr::AT_MSABI:
5499 D->addAttr(::new (S.Context) MSABIAttr(S.Context, AL));
5500 return;
5501 case ParsedAttr::AT_SysVABI:
5502 D->addAttr(::new (S.Context) SysVABIAttr(S.Context, AL));
5503 return;
5504 case ParsedAttr::AT_RegCall:
5505 D->addAttr(::new (S.Context) RegCallAttr(S.Context, AL));
5506 return;
5507 case ParsedAttr::AT_Pcs: {
5508 PcsAttr::PCSType PCS;
5509 switch (CC) {
5510 case CC_AAPCS:
5511 PCS = PcsAttr::AAPCS;
5512 break;
5513 case CC_AAPCS_VFP:
5514 PCS = PcsAttr::AAPCS_VFP;
5515 break;
5516 default:
5517 llvm_unreachable("unexpected calling convention in pcs attribute");
5518 }
5519
5520 D->addAttr(::new (S.Context) PcsAttr(S.Context, AL, PCS));
5521 return;
5522 }
5523 case ParsedAttr::AT_AArch64VectorPcs:
5524 D->addAttr(::new (S.Context) AArch64VectorPcsAttr(S.Context, AL));
5525 return;
5526 case ParsedAttr::AT_AArch64SVEPcs:
5527 D->addAttr(::new (S.Context) AArch64SVEPcsAttr(S.Context, AL));
5528 return;
5529 case ParsedAttr::AT_DeviceKernel: {
5530 // The attribute should already be applied.
5531 assert(D->hasAttr<DeviceKernelAttr>() && "Expected attribute");
5532 return;
5533 }
5534 case ParsedAttr::AT_IntelOclBicc:
5535 D->addAttr(::new (S.Context) IntelOclBiccAttr(S.Context, AL));
5536 return;
5537 case ParsedAttr::AT_PreserveMost:
5538 D->addAttr(::new (S.Context) PreserveMostAttr(S.Context, AL));
5539 return;
5540 case ParsedAttr::AT_PreserveAll:
5541 D->addAttr(::new (S.Context) PreserveAllAttr(S.Context, AL));
5542 return;
5543 case ParsedAttr::AT_M68kRTD:
5544 D->addAttr(::new (S.Context) M68kRTDAttr(S.Context, AL));
5545 return;
5546 case ParsedAttr::AT_PreserveNone:
5547 D->addAttr(::new (S.Context) PreserveNoneAttr(S.Context, AL));
5548 return;
5549 case ParsedAttr::AT_RISCVVectorCC:
5550 D->addAttr(::new (S.Context) RISCVVectorCCAttr(S.Context, AL));
5551 return;
5552 case ParsedAttr::AT_RISCVVLSCC: {
5553 // If the riscv_abi_vlen doesn't have any argument, default ABI_VLEN is 128.
5554 unsigned VectorLength = 128;
5555 if (AL.getNumArgs() &&
5557 return;
5559 S.Diag(AL.getLoc(), diag::err_argument_invalid_range)
5560 << VectorLength << 32 << 65536;
5561 return;
5562 }
5563 if (!llvm::isPowerOf2_64(VectorLength)) {
5564 S.Diag(AL.getLoc(), diag::err_argument_not_power_of_2);
5565 return;
5566 }
5567
5568 D->addAttr(::new (S.Context) RISCVVLSCCAttr(S.Context, AL, VectorLength));
5569 return;
5570 }
5571 default:
5572 llvm_unreachable("unexpected attribute kind");
5573 }
5574}
5575
5576static void handleDeviceKernelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5577 const auto *FD = dyn_cast_or_null<FunctionDecl>(D);
5578 bool IsFunctionTemplate = FD && FD->getDescribedFunctionTemplate();
5579 llvm::Triple Triple = S.getASTContext().getTargetInfo().getTriple();
5580 const LangOptions &LangOpts = S.getLangOpts();
5581 // OpenCL has its own error messages.
5582 if (!LangOpts.OpenCL && FD && !FD->isExternallyVisible()) {
5583 S.Diag(AL.getLoc(), diag::err_hidden_device_kernel) << FD;
5584 AL.setInvalid();
5585 return;
5586 }
5587 if (Triple.isNVPTX()) {
5588 handleGlobalAttr(S, D, AL);
5589 } else {
5590 // OpenCL C++ will throw a more specific error.
5591 if (!LangOpts.OpenCLCPlusPlus && (!FD || IsFunctionTemplate)) {
5592 S.Diag(AL.getLoc(), diag::err_attribute_wrong_decl_type_str)
5593 << AL << AL.isRegularKeywordAttribute() << "functions";
5594 AL.setInvalid();
5595 return;
5596 }
5598 }
5599 // TODO: isGPU() should probably return true for SPIR.
5600 bool TargetDeviceEnvironment = Triple.isGPU() || Triple.isSPIR() ||
5601 LangOpts.isTargetDevice() || LangOpts.OpenCL;
5602 if (!TargetDeviceEnvironment) {
5603 S.Diag(AL.getLoc(), diag::warn_cconv_unsupported)
5605 AL.setInvalid();
5606 return;
5607 }
5608
5609 // Make sure we validate the CC with the target
5610 // and warn/error if necessary.
5611 handleCallConvAttr(S, D, AL);
5612}
5613
5614static void handleSuppressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5615 if (AL.getAttributeSpellingListIndex() == SuppressAttr::CXX11_gsl_suppress) {
5616 // Suppression attribute with GSL spelling requires at least 1 argument.
5617 if (!AL.checkAtLeastNumArgs(S, 1))
5618 return;
5619 }
5620
5621 std::vector<StringRef> DiagnosticIdentifiers;
5622 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
5623 StringRef RuleName;
5624
5625 if (!S.checkStringLiteralArgumentAttr(AL, I, RuleName, nullptr))
5626 return;
5627
5628 DiagnosticIdentifiers.push_back(RuleName);
5629 }
5630 D->addAttr(::new (S.Context)
5631 SuppressAttr(S.Context, AL, DiagnosticIdentifiers.data(),
5632 DiagnosticIdentifiers.size()));
5633}
5634
5635static void handleLifetimeCategoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5636 TypeSourceInfo *DerefTypeLoc = nullptr;
5637 QualType ParmType;
5638 if (AL.hasParsedType()) {
5639 ParmType = S.GetTypeFromParser(AL.getTypeArg(), &DerefTypeLoc);
5640
5641 unsigned SelectIdx = ~0U;
5642 if (ParmType->isReferenceType())
5643 SelectIdx = 0;
5644 else if (ParmType->isArrayType())
5645 SelectIdx = 1;
5646
5647 if (SelectIdx != ~0U) {
5648 S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument)
5649 << SelectIdx << AL;
5650 return;
5651 }
5652 }
5653
5654 // To check if earlier decl attributes do not conflict the newly parsed ones
5655 // we always add (and check) the attribute to the canonical decl. We need
5656 // to repeat the check for attribute mutual exclusion because we're attaching
5657 // all of the attributes to the canonical declaration rather than the current
5658 // declaration.
5659 D = D->getCanonicalDecl();
5660 if (AL.getKind() == ParsedAttr::AT_Owner) {
5662 return;
5663 if (const auto *OAttr = D->getAttr<OwnerAttr>()) {
5664 const Type *ExistingDerefType = OAttr->getDerefTypeLoc()
5665 ? OAttr->getDerefType().getTypePtr()
5666 : nullptr;
5667 if (ExistingDerefType != ParmType.getTypePtrOrNull()) {
5668 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
5669 << AL << OAttr
5670 << (AL.isRegularKeywordAttribute() ||
5671 OAttr->isRegularKeywordAttribute());
5672 S.Diag(OAttr->getLocation(), diag::note_conflicting_attribute);
5673 }
5674 return;
5675 }
5676 for (Decl *Redecl : D->redecls()) {
5677 Redecl->addAttr(::new (S.Context) OwnerAttr(S.Context, AL, DerefTypeLoc));
5678 }
5679 } else {
5681 return;
5682 if (const auto *PAttr = D->getAttr<PointerAttr>()) {
5683 const Type *ExistingDerefType = PAttr->getDerefTypeLoc()
5684 ? PAttr->getDerefType().getTypePtr()
5685 : nullptr;
5686 if (ExistingDerefType != ParmType.getTypePtrOrNull()) {
5687 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
5688 << AL << PAttr
5689 << (AL.isRegularKeywordAttribute() ||
5690 PAttr->isRegularKeywordAttribute());
5691 S.Diag(PAttr->getLocation(), diag::note_conflicting_attribute);
5692 }
5693 return;
5694 }
5695 for (Decl *Redecl : D->redecls()) {
5696 Redecl->addAttr(::new (S.Context)
5697 PointerAttr(S.Context, AL, DerefTypeLoc));
5698 }
5699 }
5700}
5701
5702static void handleRandomizeLayoutAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5704 return;
5705 if (!D->hasAttr<RandomizeLayoutAttr>())
5706 D->addAttr(::new (S.Context) RandomizeLayoutAttr(S.Context, AL));
5707}
5708
5710 const ParsedAttr &AL) {
5712 return;
5713 if (!D->hasAttr<NoRandomizeLayoutAttr>())
5714 D->addAttr(::new (S.Context) NoRandomizeLayoutAttr(S.Context, AL));
5715}
5716
5718 const FunctionDecl *FD,
5719 CUDAFunctionTarget CFT) {
5720 if (Attrs.isInvalid())
5721 return true;
5722
5723 if (Attrs.hasProcessingCache()) {
5724 CC = (CallingConv) Attrs.getProcessingCache();
5725 return false;
5726 }
5727
5728 if (Attrs.getKind() == ParsedAttr::AT_RISCVVLSCC) {
5729 // riscv_vls_cc only accepts 0 or 1 argument.
5730 if (!Attrs.checkAtLeastNumArgs(*this, 0) ||
5731 !Attrs.checkAtMostNumArgs(*this, 1)) {
5732 Attrs.setInvalid();
5733 return true;
5734 }
5735 } else {
5736 unsigned ReqArgs = Attrs.getKind() == ParsedAttr::AT_Pcs ? 1 : 0;
5737 if (!Attrs.checkExactlyNumArgs(*this, ReqArgs)) {
5738 Attrs.setInvalid();
5739 return true;
5740 }
5741 }
5742
5743 bool IsTargetDefaultMSABI =
5744 Context.getTargetInfo().getTriple().isOSWindows() ||
5745 Context.getTargetInfo().getTriple().isUEFI();
5746 // TODO: diagnose uses of these conventions on the wrong target.
5747 switch (Attrs.getKind()) {
5748 case ParsedAttr::AT_CDecl:
5749 CC = CC_C;
5750 break;
5751 case ParsedAttr::AT_FastCall:
5752 CC = CC_X86FastCall;
5753 break;
5754 case ParsedAttr::AT_StdCall:
5755 CC = CC_X86StdCall;
5756 break;
5757 case ParsedAttr::AT_ThisCall:
5758 CC = CC_X86ThisCall;
5759 break;
5760 case ParsedAttr::AT_Pascal:
5761 CC = CC_X86Pascal;
5762 break;
5763 case ParsedAttr::AT_SwiftCall:
5764 CC = CC_Swift;
5765 break;
5766 case ParsedAttr::AT_SwiftAsyncCall:
5767 CC = CC_SwiftAsync;
5768 break;
5769 case ParsedAttr::AT_VectorCall:
5770 CC = CC_X86VectorCall;
5771 break;
5772 case ParsedAttr::AT_AArch64VectorPcs:
5774 break;
5775 case ParsedAttr::AT_AArch64SVEPcs:
5776 CC = CC_AArch64SVEPCS;
5777 break;
5778 case ParsedAttr::AT_RegCall:
5779 CC = CC_X86RegCall;
5780 break;
5781 case ParsedAttr::AT_MSABI:
5782 CC = IsTargetDefaultMSABI ? CC_C : CC_Win64;
5783 break;
5784 case ParsedAttr::AT_SysVABI:
5785 CC = IsTargetDefaultMSABI ? CC_X86_64SysV : CC_C;
5786 break;
5787 case ParsedAttr::AT_Pcs: {
5788 StringRef StrRef;
5789 if (!checkStringLiteralArgumentAttr(Attrs, 0, StrRef)) {
5790 Attrs.setInvalid();
5791 return true;
5792 }
5793 if (StrRef == "aapcs") {
5794 CC = CC_AAPCS;
5795 break;
5796 } else if (StrRef == "aapcs-vfp") {
5797 CC = CC_AAPCS_VFP;
5798 break;
5799 }
5800
5801 Attrs.setInvalid();
5802 Diag(Attrs.getLoc(), diag::err_invalid_pcs);
5803 return true;
5804 }
5805 case ParsedAttr::AT_IntelOclBicc:
5806 CC = CC_IntelOclBicc;
5807 break;
5808 case ParsedAttr::AT_PreserveMost:
5809 CC = CC_PreserveMost;
5810 break;
5811 case ParsedAttr::AT_PreserveAll:
5812 CC = CC_PreserveAll;
5813 break;
5814 case ParsedAttr::AT_M68kRTD:
5815 CC = CC_M68kRTD;
5816 break;
5817 case ParsedAttr::AT_PreserveNone:
5818 CC = CC_PreserveNone;
5819 break;
5820 case ParsedAttr::AT_RISCVVectorCC:
5821 CC = CC_RISCVVectorCall;
5822 break;
5823 case ParsedAttr::AT_RISCVVLSCC: {
5824 // If the riscv_abi_vlen doesn't have any argument, we set set it to default
5825 // value 128.
5826 unsigned ABIVLen = 128;
5827 if (Attrs.getNumArgs() &&
5828 !checkUInt32Argument(Attrs, Attrs.getArgAsExpr(0), ABIVLen)) {
5829 Attrs.setInvalid();
5830 return true;
5831 }
5832 if (Attrs.getNumArgs() && (ABIVLen < 32 || ABIVLen > 65536)) {
5833 Attrs.setInvalid();
5834 Diag(Attrs.getLoc(), diag::err_argument_invalid_range)
5835 << ABIVLen << 32 << 65536;
5836 return true;
5837 }
5838 if (!llvm::isPowerOf2_64(ABIVLen)) {
5839 Attrs.setInvalid();
5840 Diag(Attrs.getLoc(), diag::err_argument_not_power_of_2);
5841 return true;
5842 }
5844 llvm::Log2_64(ABIVLen) - 5);
5845 break;
5846 }
5847 case ParsedAttr::AT_DeviceKernel: {
5848 // Validation was handled in handleDeviceKernelAttr.
5849 CC = CC_DeviceKernel;
5850 break;
5851 }
5852 default: llvm_unreachable("unexpected attribute kind");
5853 }
5854
5856 const TargetInfo &TI = Context.getTargetInfo();
5857 auto *Aux = Context.getAuxTargetInfo();
5858 // CUDA functions may have host and/or device attributes which indicate
5859 // their targeted execution environment, therefore the calling convention
5860 // of functions in CUDA should be checked against the target deduced based
5861 // on their host/device attributes.
5862 if (LangOpts.CUDA) {
5863 assert(FD || CFT != CUDAFunctionTarget::InvalidTarget);
5864 auto CudaTarget = FD ? CUDA().IdentifyTarget(FD) : CFT;
5865 bool CheckHost = false, CheckDevice = false;
5866 switch (CudaTarget) {
5868 CheckHost = true;
5869 CheckDevice = true;
5870 break;
5872 CheckHost = true;
5873 break;
5876 CheckDevice = true;
5877 break;
5879 llvm_unreachable("unexpected cuda target");
5880 }
5881 auto *HostTI = LangOpts.CUDAIsDevice ? Aux : &TI;
5882 auto *DeviceTI = LangOpts.CUDAIsDevice ? &TI : Aux;
5883 if (CheckHost && HostTI)
5884 A = HostTI->checkCallingConvention(CC);
5885 if (A == TargetInfo::CCCR_OK && CheckDevice && DeviceTI)
5886 A = DeviceTI->checkCallingConvention(CC);
5887 } else if (LangOpts.SYCLIsDevice) {
5888 // During device compilation, calling conventions that are valid for the
5889 // host, for the device, and for both the host and the device may be
5890 // encountered. Diagnostics are desired for cases where the calling
5891 // convention is not supported by either the host or the device. If Aux is
5892 // null (which should rarely be the case), it isn't possible to check
5893 // whether the calling convention is supported by the host, so just assume
5894 // that it is. If the calling convention is supported for the device, there
5895 // is no need to check the host; the device target gets priority since this
5896 // check is only performed during device compilation.
5897 A = TI.checkCallingConvention(CC);
5898 if (Aux && A == TargetInfo::CCCR_Warning) {
5899 // If the calling convention would provoke a warning for the device, check
5900 // the host and preserve the warning only if the calling convention would
5901 // provoke an error for the host. Otherwise, assume this calling
5902 // convention is only used for host only functions.
5903 A = Aux->checkCallingConvention(CC);
5904 if (A == TargetInfo::CCCR_Error)
5906 } else if (Aux && A == TargetInfo::CCCR_Error) {
5907 // Assume this calling convention is only used for host only functions.
5908 A = Aux->checkCallingConvention(CC);
5909 }
5910 } else {
5911 A = TI.checkCallingConvention(CC);
5912 }
5913
5914 switch (A) {
5916 break;
5917
5919 // Treat an ignored convention as if it was an explicit C calling convention
5920 // attribute. For example, __stdcall on Win x64 functions as __cdecl, so
5921 // that command line flags that change the default convention to
5922 // __vectorcall don't affect declarations marked __stdcall.
5923 CC = CC_C;
5924 break;
5925
5927 Diag(Attrs.getLoc(), diag::error_cconv_unsupported)
5929 break;
5930
5932 Diag(Attrs.getLoc(), diag::warn_cconv_unsupported)
5934
5935 // This convention is not valid for the target. Use the default function or
5936 // method calling convention.
5937 bool IsCXXMethod = false, IsVariadic = false;
5938 if (FD) {
5939 IsCXXMethod = FD->isCXXInstanceMember();
5940 IsVariadic = FD->isVariadic();
5941 }
5942 CC = Context.getDefaultCallingConvention(IsVariadic, IsCXXMethod);
5943 break;
5944 }
5945 }
5946
5947 Attrs.setProcessingCache((unsigned) CC);
5948 return false;
5949}
5950
5951bool Sema::CheckRegparmAttr(const ParsedAttr &AL, unsigned &numParams) {
5952 if (AL.isInvalid())
5953 return true;
5954
5955 if (!AL.checkExactlyNumArgs(*this, 1)) {
5956 AL.setInvalid();
5957 return true;
5958 }
5959
5960 uint32_t NP;
5961 Expr *NumParamsExpr = AL.getArgAsExpr(0);
5962 if (!checkUInt32Argument(AL, NumParamsExpr, NP)) {
5963 AL.setInvalid();
5964 return true;
5965 }
5966
5967 if (Context.getTargetInfo().getRegParmMax() == 0) {
5968 Diag(AL.getLoc(), diag::err_attribute_regparm_wrong_platform)
5969 << NumParamsExpr->getSourceRange();
5970 AL.setInvalid();
5971 return true;
5972 }
5973
5974 numParams = NP;
5975 if (numParams > Context.getTargetInfo().getRegParmMax()) {
5976 Diag(AL.getLoc(), diag::err_attribute_regparm_invalid_number)
5977 << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
5978 AL.setInvalid();
5979 return true;
5980 }
5981
5982 return false;
5983}
5984
5985// Helper to get OffloadArch.
5987 if (!TI.getTriple().isNVPTX())
5988 llvm_unreachable("getOffloadArch is only valid for NVPTX triple");
5989 auto &TO = TI.getTargetOpts();
5990 return StringToOffloadArch(TO.CPU);
5991}
5992
5993// Checks whether an argument of launch_bounds attribute is
5994// acceptable, performs implicit conversion to Rvalue, and returns
5995// non-nullptr Expr result on success. Otherwise, it returns nullptr
5996// and may output an error.
5998 const CUDALaunchBoundsAttr &AL,
5999 const unsigned Idx) {
6001 return nullptr;
6002
6003 // Accept template arguments for now as they depend on something else.
6004 // We'll get to check them when they eventually get instantiated.
6005 if (E->isValueDependent())
6006 return E;
6007
6008 std::optional<llvm::APSInt> I = llvm::APSInt(64);
6009 if (!(I = E->getIntegerConstantExpr(S.Context))) {
6010 S.Diag(E->getExprLoc(), diag::err_attribute_argument_n_type)
6011 << &AL << Idx << AANT_ArgumentIntegerConstant << E->getSourceRange();
6012 return nullptr;
6013 }
6014 // Make sure we can fit it in 32 bits.
6015 if (!I->isIntN(32)) {
6016 S.Diag(E->getExprLoc(), diag::err_ice_too_large)
6017 << toString(*I, 10, false) << 32 << /* Unsigned */ 1;
6018 return nullptr;
6019 }
6020 if (*I < 0)
6021 S.Diag(E->getExprLoc(), diag::warn_attribute_argument_n_negative)
6022 << &AL << Idx << E->getSourceRange();
6023
6024 // We may need to perform implicit conversion of the argument.
6026 S.Context, S.Context.getConstType(S.Context.IntTy), /*consume*/ false);
6027 ExprResult ValArg = S.PerformCopyInitialization(Entity, SourceLocation(), E);
6028 assert(!ValArg.isInvalid() &&
6029 "Unexpected PerformCopyInitialization() failure.");
6030
6031 return ValArg.getAs<Expr>();
6032}
6033
6034CUDALaunchBoundsAttr *
6036 Expr *MinBlocks, Expr *MaxBlocks,
6037 bool IgnoreArch) {
6038 CUDALaunchBoundsAttr TmpAttr(Context, CI, MaxThreads, MinBlocks, MaxBlocks);
6039 MaxThreads = makeLaunchBoundsArgExpr(*this, MaxThreads, TmpAttr, 0);
6040 if (!MaxThreads)
6041 return nullptr;
6042
6043 if (MinBlocks) {
6044 MinBlocks = makeLaunchBoundsArgExpr(*this, MinBlocks, TmpAttr, 1);
6045 if (!MinBlocks)
6046 return nullptr;
6047 }
6048
6049 if (MaxBlocks) {
6050 // We might want to ignore the nvptx arch check, e.g., when processing the
6051 // launch bounds attribute within ompx_attribute to support other archs.
6052 if (!IgnoreArch) {
6053 // '.maxclusterrank' ptx directive requires .target sm_90 or higher.
6054 auto SM = getOffloadArch(Context.getTargetInfo());
6056 Diag(MaxBlocks->getBeginLoc(), diag::warn_cuda_maxclusterrank_sm_90)
6057 << OffloadArchToString(SM) << CI << MaxBlocks->getSourceRange();
6058 // Ignore it by setting MaxBlocks to null;
6059 MaxBlocks = nullptr;
6060 }
6061 }
6062
6063 if (MaxBlocks) {
6064 MaxBlocks = makeLaunchBoundsArgExpr(*this, MaxBlocks, TmpAttr, 2);
6065 if (!MaxBlocks)
6066 return nullptr;
6067 }
6068 }
6069
6070 return ::new (Context)
6071 CUDALaunchBoundsAttr(Context, CI, MaxThreads, MinBlocks, MaxBlocks);
6072}
6073
6075 Expr *MaxThreads, Expr *MinBlocks,
6076 Expr *MaxBlocks) {
6077 if (auto *Attr = CreateLaunchBoundsAttr(CI, MaxThreads, MinBlocks, MaxBlocks))
6078 D->addAttr(Attr);
6079}
6080
6081static void handleLaunchBoundsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6082 if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 3))
6083 return;
6084
6085 S.AddLaunchBoundsAttr(D, AL, AL.getArgAsExpr(0),
6086 AL.getNumArgs() > 1 ? AL.getArgAsExpr(1) : nullptr,
6087 AL.getNumArgs() > 2 ? AL.getArgAsExpr(2) : nullptr);
6088}
6089
6090static std::pair<Expr *, int>
6091makeClusterDimsArgExpr(Sema &S, Expr *E, const CUDAClusterDimsAttr &AL,
6092 const unsigned Idx) {
6093 if (!E || S.DiagnoseUnexpandedParameterPack(E))
6094 return {};
6095
6096 // Accept template arguments for now as they depend on something else.
6097 // We'll get to check them when they eventually get instantiated.
6098 if (E->isInstantiationDependent())
6099 return {E, 1};
6100
6101 std::optional<llvm::APSInt> I = E->getIntegerConstantExpr(S.Context);
6102 if (!I) {
6103 S.Diag(E->getExprLoc(), diag::err_attribute_argument_n_type)
6104 << &AL << Idx << AANT_ArgumentIntegerConstant << E->getSourceRange();
6105 return {};
6106 }
6107 // Make sure we can fit it in 4 bits.
6108 if (!I->isIntN(4)) {
6109 S.Diag(E->getExprLoc(), diag::err_ice_too_large)
6110 << toString(*I, 10, false) << 4 << /*Unsigned=*/1;
6111 return {};
6112 }
6113 if (*I < 0) {
6114 S.Diag(E->getExprLoc(), diag::warn_attribute_argument_n_negative)
6115 << &AL << Idx << E->getSourceRange();
6116 }
6117
6118 return {ConstantExpr::Create(S.getASTContext(), E, APValue(*I)),
6119 I->getZExtValue()};
6120}
6121
6123 Expr *X, Expr *Y, Expr *Z) {
6124 CUDAClusterDimsAttr TmpAttr(Context, CI, X, Y, Z);
6125
6126 auto [NewX, ValX] = makeClusterDimsArgExpr(*this, X, TmpAttr, /*Idx=*/0);
6127 auto [NewY, ValY] = makeClusterDimsArgExpr(*this, Y, TmpAttr, /*Idx=*/1);
6128 auto [NewZ, ValZ] = makeClusterDimsArgExpr(*this, Z, TmpAttr, /*Idx=*/2);
6129
6130 if (!NewX || (Y && !NewY) || (Z && !NewZ))
6131 return nullptr;
6132
6133 int FlatDim = ValX * ValY * ValZ;
6134 const llvm::Triple TT =
6135 (!Context.getLangOpts().CUDAIsDevice && Context.getAuxTargetInfo())
6136 ? Context.getAuxTargetInfo()->getTriple()
6137 : Context.getTargetInfo().getTriple();
6138 int MaxDim = 1;
6139 if (TT.isNVPTX())
6140 MaxDim = 8;
6141 else if (TT.isAMDGPU())
6142 MaxDim = 16;
6143 else
6144 return nullptr;
6145
6146 // A maximum of 8 thread blocks in a cluster is supported as a portable
6147 // cluster size in CUDA. The number is 16 for AMDGPU.
6148 if (FlatDim > MaxDim) {
6149 Diag(CI.getLoc(), diag::err_cluster_dims_too_large) << MaxDim << FlatDim;
6150 return nullptr;
6151 }
6152
6153 return CUDAClusterDimsAttr::Create(Context, NewX, NewY, NewZ, CI);
6154}
6155
6157 Expr *Y, Expr *Z) {
6158 if (auto *Attr = createClusterDimsAttr(CI, X, Y, Z))
6159 D->addAttr(Attr);
6160}
6161
6163 D->addAttr(CUDANoClusterAttr::Create(Context, CI));
6164}
6165
6166static void handleClusterDimsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6167 const TargetInfo &TTI = S.Context.getTargetInfo();
6169 if ((TTI.getTriple().isNVPTX() && Arch < clang::OffloadArch::SM_90) ||
6170 (TTI.getTriple().isAMDGPU() &&
6171 !TTI.hasFeatureEnabled(TTI.getTargetOpts().FeatureMap, "clusters"))) {
6172 S.Diag(AL.getLoc(), diag::err_cluster_attr_not_supported) << AL;
6173 return;
6174 }
6175
6176 if (!AL.checkAtLeastNumArgs(S, /*Num=*/1) ||
6177 !AL.checkAtMostNumArgs(S, /*Num=*/3))
6178 return;
6179
6180 S.addClusterDimsAttr(D, AL, AL.getArgAsExpr(0),
6181 AL.getNumArgs() > 1 ? AL.getArgAsExpr(1) : nullptr,
6182 AL.getNumArgs() > 2 ? AL.getArgAsExpr(2) : nullptr);
6183}
6184
6185static void handleNoClusterAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6186 const TargetInfo &TTI = S.Context.getTargetInfo();
6188 if ((TTI.getTriple().isNVPTX() && Arch < clang::OffloadArch::SM_90) ||
6189 (TTI.getTriple().isAMDGPU() &&
6190 !TTI.hasFeatureEnabled(TTI.getTargetOpts().FeatureMap, "clusters"))) {
6191 S.Diag(AL.getLoc(), diag::err_cluster_attr_not_supported) << AL;
6192 return;
6193 }
6194
6195 S.addNoClusterAttr(D, AL);
6196}
6197
6199 const ParsedAttr &AL) {
6200 if (!AL.isArgIdent(0)) {
6201 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
6202 << AL << /* arg num = */ 1 << AANT_ArgumentIdentifier;
6203 return;
6204 }
6205
6206 ParamIdx ArgumentIdx;
6208 D, AL, 2, AL.getArgAsExpr(1), ArgumentIdx,
6209 /*CanIndexImplicitThis=*/false,
6210 /*CanIndexVariadicArguments=*/true))
6211 return;
6212
6213 ParamIdx TypeTagIdx;
6215 D, AL, 3, AL.getArgAsExpr(2), TypeTagIdx,
6216 /*CanIndexImplicitThis=*/false,
6217 /*CanIndexVariadicArguments=*/true))
6218 return;
6219
6220 bool IsPointer = AL.getAttrName()->getName() == "pointer_with_type_tag";
6221 if (IsPointer) {
6222 // Ensure that buffer has a pointer type.
6223 unsigned ArgumentIdxAST = ArgumentIdx.getASTIndex();
6224 if (ArgumentIdxAST >= getFunctionOrMethodNumParams(D) ||
6225 !getFunctionOrMethodParamType(D, ArgumentIdxAST)->isPointerType())
6226 S.Diag(AL.getLoc(), diag::err_attribute_pointers_only) << AL << 0;
6227 }
6228
6229 D->addAttr(::new (S.Context) ArgumentWithTypeTagAttr(
6230 S.Context, AL, AL.getArgAsIdent(0)->getIdentifierInfo(), ArgumentIdx,
6231 TypeTagIdx, IsPointer));
6232}
6233
6235 const ParsedAttr &AL) {
6236 if (!AL.isArgIdent(0)) {
6237 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
6238 << AL << 1 << AANT_ArgumentIdentifier;
6239 return;
6240 }
6241
6242 if (!AL.checkExactlyNumArgs(S, 1))
6243 return;
6244
6245 if (!isa<VarDecl>(D)) {
6246 S.Diag(AL.getLoc(), diag::err_attribute_wrong_decl_type)
6248 return;
6249 }
6250
6251 IdentifierInfo *PointerKind = AL.getArgAsIdent(0)->getIdentifierInfo();
6252 TypeSourceInfo *MatchingCTypeLoc = nullptr;
6253 S.GetTypeFromParser(AL.getMatchingCType(), &MatchingCTypeLoc);
6254 assert(MatchingCTypeLoc && "no type source info for attribute argument");
6255
6256 D->addAttr(::new (S.Context) TypeTagForDatatypeAttr(
6257 S.Context, AL, PointerKind, MatchingCTypeLoc, AL.getLayoutCompatible(),
6258 AL.getMustBeNull()));
6259}
6260
6261static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6262 ParamIdx ArgCount;
6263
6265 ArgCount,
6266 true /* CanIndexImplicitThis */))
6267 return;
6268
6269 // ArgCount isn't a parameter index [0;n), it's a count [1;n]
6270 D->addAttr(::new (S.Context)
6271 XRayLogArgsAttr(S.Context, AL, ArgCount.getSourceIndex()));
6272}
6273
6275 const ParsedAttr &AL) {
6276 if (S.Context.getTargetInfo().getTriple().isOSAIX()) {
6277 S.Diag(AL.getLoc(), diag::err_aix_attr_unsupported) << AL;
6278 return;
6279 }
6280 uint32_t Count = 0, Offset = 0;
6281 StringRef Section;
6282 if (!S.checkUInt32Argument(AL, AL.getArgAsExpr(0), Count, 0, true))
6283 return;
6284 if (AL.getNumArgs() >= 2) {
6285 Expr *Arg = AL.getArgAsExpr(1);
6286 if (!S.checkUInt32Argument(AL, Arg, Offset, 1, true))
6287 return;
6288 if (Count < Offset) {
6289 S.Diag(S.getAttrLoc(AL), diag::err_attribute_argument_out_of_range)
6290 << &AL << 0 << Count << Arg->getBeginLoc();
6291 return;
6292 }
6293 }
6294 if (AL.getNumArgs() == 3) {
6295 SourceLocation LiteralLoc;
6296 if (!S.checkStringLiteralArgumentAttr(AL, 2, Section, &LiteralLoc))
6297 return;
6298 if (llvm::Error E = S.isValidSectionSpecifier(Section)) {
6299 S.Diag(LiteralLoc,
6300 diag::err_attribute_patchable_function_entry_invalid_section)
6301 << toString(std::move(E));
6302 return;
6303 }
6304 if (Section.empty()) {
6305 S.Diag(LiteralLoc,
6306 diag::err_attribute_patchable_function_entry_invalid_section)
6307 << "section must not be empty";
6308 return;
6309 }
6310 }
6311 D->addAttr(::new (S.Context) PatchableFunctionEntryAttr(S.Context, AL, Count,
6312 Offset, Section));
6313}
6314
6315static void handleBuiltinAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6316 if (!AL.isArgIdent(0)) {
6317 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
6318 << AL << 1 << AANT_ArgumentIdentifier;
6319 return;
6320 }
6321
6323 unsigned BuiltinID = Ident->getBuiltinID();
6324 StringRef AliasName = cast<FunctionDecl>(D)->getIdentifier()->getName();
6325
6326 bool IsAArch64 = S.Context.getTargetInfo().getTriple().isAArch64();
6327 bool IsARM = S.Context.getTargetInfo().getTriple().isARM();
6328 bool IsRISCV = S.Context.getTargetInfo().getTriple().isRISCV();
6329 bool IsSPIRV = S.Context.getTargetInfo().getTriple().isSPIRV();
6330 bool IsHLSL = S.Context.getLangOpts().HLSL;
6331 if ((IsAArch64 && !S.ARM().SveAliasValid(BuiltinID, AliasName)) ||
6332 (IsARM && !S.ARM().MveAliasValid(BuiltinID, AliasName) &&
6333 !S.ARM().CdeAliasValid(BuiltinID, AliasName)) ||
6334 (IsRISCV && !S.RISCV().isAliasValid(BuiltinID, AliasName)) ||
6335 (!IsAArch64 && !IsARM && !IsRISCV && !IsHLSL && !IsSPIRV)) {
6336 S.Diag(AL.getLoc(), diag::err_attribute_builtin_alias) << AL;
6337 return;
6338 }
6339
6340 D->addAttr(::new (S.Context) BuiltinAliasAttr(S.Context, AL, Ident));
6341}
6342
6343static void handleNullableTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6344 if (AL.isUsedAsTypeAttr())
6345 return;
6346
6347 if (auto *CRD = dyn_cast<CXXRecordDecl>(D);
6348 !CRD || !(CRD->isClass() || CRD->isStruct())) {
6349 S.Diag(AL.getRange().getBegin(), diag::err_attribute_wrong_decl_type)
6351 return;
6352 }
6353
6355}
6356
6357static void handlePreferredTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6358 if (!AL.hasParsedType()) {
6359 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
6360 return;
6361 }
6362
6363 TypeSourceInfo *ParmTSI = nullptr;
6364 QualType QT = S.GetTypeFromParser(AL.getTypeArg(), &ParmTSI);
6365 assert(ParmTSI && "no type source info for attribute argument");
6366 S.RequireCompleteType(ParmTSI->getTypeLoc().getBeginLoc(), QT,
6367 diag::err_incomplete_type);
6368
6369 D->addAttr(::new (S.Context) PreferredTypeAttr(S.Context, AL, ParmTSI));
6370}
6371
6372//===----------------------------------------------------------------------===//
6373// Microsoft specific attribute handlers.
6374//===----------------------------------------------------------------------===//
6375
6377 StringRef UuidAsWritten, MSGuidDecl *GuidDecl) {
6378 if (const auto *UA = D->getAttr<UuidAttr>()) {
6379 if (declaresSameEntity(UA->getGuidDecl(), GuidDecl))
6380 return nullptr;
6381 if (!UA->getGuid().empty()) {
6382 Diag(UA->getLocation(), diag::err_mismatched_uuid);
6383 Diag(CI.getLoc(), diag::note_previous_uuid);
6384 D->dropAttr<UuidAttr>();
6385 }
6386 }
6387
6388 return ::new (Context) UuidAttr(Context, CI, UuidAsWritten, GuidDecl);
6389}
6390
6391static void handleUuidAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6392 if (!S.LangOpts.CPlusPlus) {
6393 S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)
6394 << AL << AttributeLangSupport::C;
6395 return;
6396 }
6397
6398 StringRef OrigStrRef;
6399 SourceLocation LiteralLoc;
6400 if (!S.checkStringLiteralArgumentAttr(AL, 0, OrigStrRef, &LiteralLoc))
6401 return;
6402
6403 // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
6404 // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", normalize to the former.
6405 StringRef StrRef = OrigStrRef;
6406 if (StrRef.size() == 38 && StrRef.front() == '{' && StrRef.back() == '}')
6407 StrRef = StrRef.drop_front().drop_back();
6408
6409 // Validate GUID length.
6410 if (StrRef.size() != 36) {
6411 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
6412 return;
6413 }
6414
6415 for (unsigned i = 0; i < 36; ++i) {
6416 if (i == 8 || i == 13 || i == 18 || i == 23) {
6417 if (StrRef[i] != '-') {
6418 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
6419 return;
6420 }
6421 } else if (!isHexDigit(StrRef[i])) {
6422 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
6423 return;
6424 }
6425 }
6426
6427 // Convert to our parsed format and canonicalize.
6428 MSGuidDecl::Parts Parsed;
6429 StrRef.substr(0, 8).getAsInteger(16, Parsed.Part1);
6430 StrRef.substr(9, 4).getAsInteger(16, Parsed.Part2);
6431 StrRef.substr(14, 4).getAsInteger(16, Parsed.Part3);
6432 for (unsigned i = 0; i != 8; ++i)
6433 StrRef.substr(19 + 2 * i + (i >= 2 ? 1 : 0), 2)
6434 .getAsInteger(16, Parsed.Part4And5[i]);
6435 MSGuidDecl *Guid = S.Context.getMSGuidDecl(Parsed);
6436
6437 // FIXME: It'd be nice to also emit a fixit removing uuid(...) (and, if it's
6438 // the only thing in the [] list, the [] too), and add an insertion of
6439 // __declspec(uuid(...)). But sadly, neither the SourceLocs of the commas
6440 // separating attributes nor of the [ and the ] are in the AST.
6441 // Cf "SourceLocations of attribute list delimiters - [[ ... , ... ]] etc"
6442 // on cfe-dev.
6443 if (AL.isMicrosoftAttribute()) // Check for [uuid(...)] spelling.
6444 S.Diag(AL.getLoc(), diag::warn_atl_uuid_deprecated);
6445
6446 UuidAttr *UA = S.mergeUuidAttr(D, AL, OrigStrRef, Guid);
6447 if (UA)
6448 D->addAttr(UA);
6449}
6450
6451static void handleMSInheritanceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6452 if (!S.LangOpts.CPlusPlus) {
6453 S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)
6454 << AL << AttributeLangSupport::C;
6455 return;
6456 }
6457 MSInheritanceAttr *IA = S.mergeMSInheritanceAttr(
6458 D, AL, /*BestCase=*/true, (MSInheritanceModel)AL.getSemanticSpelling());
6459 if (IA) {
6460 D->addAttr(IA);
6462 }
6463}
6464
6465static void handleDeclspecThreadAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6466 const auto *VD = cast<VarDecl>(D);
6468 S.Diag(AL.getLoc(), diag::err_thread_unsupported);
6469 return;
6470 }
6471 if (VD->getTSCSpec() != TSCS_unspecified) {
6472 S.Diag(AL.getLoc(), diag::err_declspec_thread_on_thread_variable);
6473 return;
6474 }
6475 if (VD->hasLocalStorage()) {
6476 S.Diag(AL.getLoc(), diag::err_thread_non_global) << "__declspec(thread)";
6477 return;
6478 }
6479 D->addAttr(::new (S.Context) ThreadAttr(S.Context, AL));
6480}
6481
6482static void handleMSConstexprAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6484 S.Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)
6485 << AL << AL.getRange();
6486 return;
6487 }
6488 auto *FD = cast<FunctionDecl>(D);
6489 if (FD->isConstexprSpecified() || FD->isConsteval()) {
6490 S.Diag(AL.getLoc(), diag::err_ms_constexpr_cannot_be_applied)
6491 << FD->isConsteval() << FD;
6492 return;
6493 }
6494 if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
6495 if (!S.getLangOpts().CPlusPlus20 && MD->isVirtual()) {
6496 S.Diag(AL.getLoc(), diag::err_ms_constexpr_cannot_be_applied)
6497 << /*virtual*/ 2 << MD;
6498 return;
6499 }
6500 }
6501 D->addAttr(::new (S.Context) MSConstexprAttr(S.Context, AL));
6502}
6503
6504static void handleMSStructAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6505 if (const auto *First = D->getAttr<GCCStructAttr>()) {
6506 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
6507 << AL << First << 0;
6508 S.Diag(First->getLocation(), diag::note_conflicting_attribute);
6509 return;
6510 }
6511 if (const auto *Preexisting = D->getAttr<MSStructAttr>()) {
6512 if (Preexisting->isImplicit())
6513 D->dropAttr<MSStructAttr>();
6514 }
6515
6516 D->addAttr(::new (S.Context) MSStructAttr(S.Context, AL));
6517}
6518
6519static void handleGCCStructAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6520 if (const auto *First = D->getAttr<MSStructAttr>()) {
6521 if (First->isImplicit()) {
6522 D->dropAttr<MSStructAttr>();
6523 } else {
6524 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
6525 << AL << First << 0;
6526 S.Diag(First->getLocation(), diag::note_conflicting_attribute);
6527 return;
6528 }
6529 }
6530
6531 D->addAttr(::new (S.Context) GCCStructAttr(S.Context, AL));
6532}
6533
6534static void handleAbiTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6536 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
6537 StringRef Tag;
6538 if (!S.checkStringLiteralArgumentAttr(AL, I, Tag))
6539 return;
6540 Tags.push_back(Tag);
6541 }
6542
6543 if (const auto *NS = dyn_cast<NamespaceDecl>(D)) {
6544 if (!NS->isInline()) {
6545 S.Diag(AL.getLoc(), diag::warn_attr_abi_tag_namespace) << 0;
6546 return;
6547 }
6548 if (NS->isAnonymousNamespace()) {
6549 S.Diag(AL.getLoc(), diag::warn_attr_abi_tag_namespace) << 1;
6550 return;
6551 }
6552 if (AL.getNumArgs() == 0)
6553 Tags.push_back(NS->getName());
6554 } else if (!AL.checkAtLeastNumArgs(S, 1))
6555 return;
6556
6557 // Store tags sorted and without duplicates.
6558 llvm::sort(Tags);
6559 Tags.erase(llvm::unique(Tags), Tags.end());
6560
6561 D->addAttr(::new (S.Context)
6562 AbiTagAttr(S.Context, AL, Tags.data(), Tags.size()));
6563}
6564
6565static bool hasBTFDeclTagAttr(Decl *D, StringRef Tag) {
6566 for (const auto *I : D->specific_attrs<BTFDeclTagAttr>()) {
6567 if (I->getBTFDeclTag() == Tag)
6568 return true;
6569 }
6570 return false;
6571}
6572
6573static void handleBTFDeclTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6574 StringRef Str;
6575 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
6576 return;
6577 if (hasBTFDeclTagAttr(D, Str))
6578 return;
6579
6580 D->addAttr(::new (S.Context) BTFDeclTagAttr(S.Context, AL, Str));
6581}
6582
6583BTFDeclTagAttr *Sema::mergeBTFDeclTagAttr(Decl *D, const BTFDeclTagAttr &AL) {
6584 if (hasBTFDeclTagAttr(D, AL.getBTFDeclTag()))
6585 return nullptr;
6586 return ::new (Context) BTFDeclTagAttr(Context, AL, AL.getBTFDeclTag());
6587}
6588
6589static void handleInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6590 // Dispatch the interrupt attribute based on the current target.
6591 switch (S.Context.getTargetInfo().getTriple().getArch()) {
6592 case llvm::Triple::msp430:
6593 S.MSP430().handleInterruptAttr(D, AL);
6594 break;
6595 case llvm::Triple::mipsel:
6596 case llvm::Triple::mips:
6597 S.MIPS().handleInterruptAttr(D, AL);
6598 break;
6599 case llvm::Triple::m68k:
6600 S.M68k().handleInterruptAttr(D, AL);
6601 break;
6602 case llvm::Triple::x86:
6603 case llvm::Triple::x86_64:
6604 S.X86().handleAnyInterruptAttr(D, AL);
6605 break;
6606 case llvm::Triple::avr:
6607 S.AVR().handleInterruptAttr(D, AL);
6608 break;
6609 case llvm::Triple::riscv32:
6610 case llvm::Triple::riscv64:
6611 case llvm::Triple::riscv32be:
6612 case llvm::Triple::riscv64be:
6613 S.RISCV().handleInterruptAttr(D, AL);
6614 break;
6615 default:
6616 S.ARM().handleInterruptAttr(D, AL);
6617 break;
6618 }
6619}
6620
6621static void handleLayoutVersion(Sema &S, Decl *D, const ParsedAttr &AL) {
6622 uint32_t Version;
6623 Expr *VersionExpr = AL.getArgAsExpr(0);
6624 if (!S.checkUInt32Argument(AL, AL.getArgAsExpr(0), Version))
6625 return;
6626
6627 // TODO: Investigate what happens with the next major version of MSVC.
6628 if (Version != LangOptions::MSVC2015 / 100) {
6629 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
6630 << AL << Version << VersionExpr->getSourceRange();
6631 return;
6632 }
6633
6634 // The attribute expects a "major" version number like 19, but new versions of
6635 // MSVC have moved to updating the "minor", or less significant numbers, so we
6636 // have to multiply by 100 now.
6637 Version *= 100;
6638
6639 D->addAttr(::new (S.Context) LayoutVersionAttr(S.Context, AL, Version));
6640}
6641
6643 const AttributeCommonInfo &CI) {
6644 if (D->hasAttr<DLLExportAttr>()) {
6645 Diag(CI.getLoc(), diag::warn_attribute_ignored) << "'dllimport'";
6646 return nullptr;
6647 }
6648
6649 if (D->hasAttr<DLLImportAttr>())
6650 return nullptr;
6651
6652 return ::new (Context) DLLImportAttr(Context, CI);
6653}
6654
6656 const AttributeCommonInfo &CI) {
6657 if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) {
6658 Diag(Import->getLocation(), diag::warn_attribute_ignored) << Import;
6659 D->dropAttr<DLLImportAttr>();
6660 }
6661
6662 if (D->hasAttr<DLLExportAttr>())
6663 return nullptr;
6664
6665 return ::new (Context) DLLExportAttr(Context, CI);
6666}
6667
6668static void handleDLLAttr(Sema &S, Decl *D, const ParsedAttr &A) {
6671 S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored) << A;
6672 return;
6673 }
6674
6675 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
6676 if (FD->isInlined() && A.getKind() == ParsedAttr::AT_DLLImport &&
6678 // MinGW doesn't allow dllimport on inline functions.
6679 S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored_on_inline)
6680 << A;
6681 return;
6682 }
6683 }
6684
6685 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
6687 MD->getParent()->isLambda()) {
6688 S.Diag(A.getRange().getBegin(), diag::err_attribute_dll_lambda) << A;
6689 return;
6690 }
6691 }
6692
6693 if (auto *EA = D->getAttr<ExcludeFromExplicitInstantiationAttr>()) {
6694 S.Diag(A.getRange().getBegin(),
6695 diag::warn_dllattr_ignored_exclusion_takes_precedence)
6696 << A << EA;
6697 return;
6698 }
6699
6700 Attr *NewAttr = A.getKind() == ParsedAttr::AT_DLLExport
6701 ? (Attr *)S.mergeDLLExportAttr(D, A)
6702 : (Attr *)S.mergeDLLImportAttr(D, A);
6703 if (NewAttr)
6704 D->addAttr(NewAttr);
6705}
6706
6707MSInheritanceAttr *
6709 bool BestCase,
6710 MSInheritanceModel Model) {
6711 if (MSInheritanceAttr *IA = D->getAttr<MSInheritanceAttr>()) {
6712 if (IA->getInheritanceModel() == Model)
6713 return nullptr;
6714 Diag(IA->getLocation(), diag::err_mismatched_ms_inheritance)
6715 << 1 /*previous declaration*/;
6716 Diag(CI.getLoc(), diag::note_previous_ms_inheritance);
6717 D->dropAttr<MSInheritanceAttr>();
6718 }
6719
6720 auto *RD = cast<CXXRecordDecl>(D);
6721 if (RD->hasDefinition()) {
6722 if (checkMSInheritanceAttrOnDefinition(RD, CI.getRange(), BestCase,
6723 Model)) {
6724 return nullptr;
6725 }
6726 } else {
6728 Diag(CI.getLoc(), diag::warn_ignored_ms_inheritance)
6729 << 1 /*partial specialization*/;
6730 return nullptr;
6731 }
6732 if (RD->getDescribedClassTemplate()) {
6733 Diag(CI.getLoc(), diag::warn_ignored_ms_inheritance)
6734 << 0 /*primary template*/;
6735 return nullptr;
6736 }
6737 }
6738
6739 return ::new (Context) MSInheritanceAttr(Context, CI, BestCase);
6740}
6741
6742static void handleCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6743 // The capability attributes take a single string parameter for the name of
6744 // the capability they represent. The lockable attribute does not take any
6745 // parameters. However, semantically, both attributes represent the same
6746 // concept, and so they use the same semantic attribute. Eventually, the
6747 // lockable attribute will be removed.
6748 //
6749 // For backward compatibility, any capability which has no specified string
6750 // literal will be considered a "mutex."
6751 StringRef N("mutex");
6752 SourceLocation LiteralLoc;
6753 if (AL.getKind() == ParsedAttr::AT_Capability &&
6754 !S.checkStringLiteralArgumentAttr(AL, 0, N, &LiteralLoc))
6755 return;
6756
6757 D->addAttr(::new (S.Context) CapabilityAttr(S.Context, AL, N));
6758}
6759
6761 const ParsedAttr &AL) {
6762 // Do not permit 'reentrant_capability' without 'capability(..)'. Note that
6763 // the check here requires 'capability' to be before 'reentrant_capability'.
6764 // This helps enforce a canonical style. Also avoids placing an additional
6765 // branch into ProcessDeclAttributeList().
6766 if (!D->hasAttr<CapabilityAttr>()) {
6767 S.Diag(AL.getLoc(), diag::warn_thread_attribute_requires_preceded)
6768 << AL << cast<NamedDecl>(D) << "'capability'";
6769 return;
6770 }
6771
6772 D->addAttr(::new (S.Context) ReentrantCapabilityAttr(S.Context, AL));
6773}
6774
6775static void handleAssertCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6776 if (!checkThreadSafetyAttrSubject(S, D, AL))
6777 return;
6778
6780 if (!checkLockFunAttrCommon(S, D, AL, Args))
6781 return;
6782
6783 D->addAttr(::new (S.Context)
6784 AssertCapabilityAttr(S.Context, AL, Args.data(), Args.size()));
6785}
6786
6788 const ParsedAttr &AL) {
6789 if (!checkThreadSafetyAttrSubject(S, D, AL, /*CheckParmVar=*/true))
6790 return;
6791
6793 if (!checkLockFunAttrCommon(S, D, AL, Args))
6794 return;
6795
6796 D->addAttr(::new (S.Context) AcquireCapabilityAttr(S.Context, AL, Args.data(),
6797 Args.size()));
6798}
6799
6801 const ParsedAttr &AL) {
6802 if (!checkThreadSafetyAttrSubject(S, D, AL))
6803 return;
6804
6806 if (!checkTryLockFunAttrCommon(S, D, AL, Args))
6807 return;
6808
6809 D->addAttr(::new (S.Context) TryAcquireCapabilityAttr(
6810 S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));
6811}
6812
6814 const ParsedAttr &AL) {
6815 if (!checkThreadSafetyAttrSubject(S, D, AL, /*CheckParmVar=*/true))
6816 return;
6817
6818 // Check that all arguments are lockable objects.
6820 checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 0, true);
6821
6822 D->addAttr(::new (S.Context) ReleaseCapabilityAttr(S.Context, AL, Args.data(),
6823 Args.size()));
6824}
6825
6827 const ParsedAttr &AL) {
6828 if (!checkThreadSafetyAttrSubject(S, D, AL, /*CheckParmVar=*/true))
6829 return;
6830
6831 if (!AL.checkAtLeastNumArgs(S, 1))
6832 return;
6833
6834 // check that all arguments are lockable objects
6836 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
6837 if (Args.empty())
6838 return;
6839
6840 RequiresCapabilityAttr *RCA = ::new (S.Context)
6841 RequiresCapabilityAttr(S.Context, AL, Args.data(), Args.size());
6842
6843 D->addAttr(RCA);
6844}
6845
6846static void handleDeprecatedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6847 if (const auto *NSD = dyn_cast<NamespaceDecl>(D)) {
6848 if (NSD->isAnonymousNamespace()) {
6849 S.Diag(AL.getLoc(), diag::warn_deprecated_anonymous_namespace);
6850 // Do not want to attach the attribute to the namespace because that will
6851 // cause confusing diagnostic reports for uses of declarations within the
6852 // namespace.
6853 return;
6854 }
6857 S.Diag(AL.getRange().getBegin(), diag::warn_deprecated_ignored_on_using)
6858 << AL;
6859 return;
6860 }
6861
6862 // Handle the cases where the attribute has a text message.
6863 StringRef Str, Replacement;
6864 if (AL.isArgExpr(0) && AL.getArgAsExpr(0) &&
6865 !S.checkStringLiteralArgumentAttr(AL, 0, Str))
6866 return;
6867
6868 // Support a single optional message only for Declspec and [[]] spellings.
6870 AL.checkAtMostNumArgs(S, 1);
6871 else if (AL.isArgExpr(1) && AL.getArgAsExpr(1) &&
6872 !S.checkStringLiteralArgumentAttr(AL, 1, Replacement))
6873 return;
6874
6875 if (!S.getLangOpts().CPlusPlus14 && AL.isCXX11Attribute() && !AL.isGNUScope())
6876 S.Diag(AL.getLoc(), diag::ext_cxx14_attr) << AL;
6877
6878 D->addAttr(::new (S.Context) DeprecatedAttr(S.Context, AL, Str, Replacement));
6879}
6880
6881static bool isGlobalVar(const Decl *D) {
6882 if (const auto *S = dyn_cast<VarDecl>(D))
6883 return S->hasGlobalStorage();
6884 return false;
6885}
6886
6887static bool isSanitizerAttributeAllowedOnGlobals(StringRef Sanitizer) {
6888 return Sanitizer == "address" || Sanitizer == "hwaddress" ||
6889 Sanitizer == "memtag";
6890}
6891
6892static void handleNoSanitizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6893 if (!AL.checkAtLeastNumArgs(S, 1))
6894 return;
6895
6896 std::vector<StringRef> Sanitizers;
6897
6898 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
6899 StringRef SanitizerName;
6900 SourceLocation LiteralLoc;
6901
6902 if (!S.checkStringLiteralArgumentAttr(AL, I, SanitizerName, &LiteralLoc))
6903 return;
6904
6905 if (parseSanitizerValue(SanitizerName, /*AllowGroups=*/true) ==
6906 SanitizerMask() &&
6907 SanitizerName != "coverage")
6908 S.Diag(LiteralLoc, diag::warn_unknown_sanitizer_ignored) << SanitizerName;
6909 else if (isGlobalVar(D) && !isSanitizerAttributeAllowedOnGlobals(SanitizerName))
6910 S.Diag(D->getLocation(), diag::warn_attribute_type_not_supported_global)
6911 << AL << SanitizerName;
6912 Sanitizers.push_back(SanitizerName);
6913 }
6914
6915 D->addAttr(::new (S.Context) NoSanitizeAttr(S.Context, AL, Sanitizers.data(),
6916 Sanitizers.size()));
6917}
6918
6920getNoSanitizeAttrInfo(const ParsedAttr &NoSanitizeSpecificAttr) {
6921 // FIXME: Rather than create a NoSanitizeSpecificAttr, this creates a
6922 // NoSanitizeAttr object; but we need to calculate the correct spelling list
6923 // index rather than incorrectly assume the index for NoSanitizeSpecificAttr
6924 // has the same spellings as the index for NoSanitizeAttr. We don't have a
6925 // general way to "translate" between the two, so this hack attempts to work
6926 // around the issue with hard-coded indices. This is critical for calling
6927 // getSpelling() or prettyPrint() on the resulting semantic attribute object
6928 // without failing assertions.
6929 unsigned TranslatedSpellingIndex = 0;
6930 if (NoSanitizeSpecificAttr.isStandardAttributeSyntax())
6931 TranslatedSpellingIndex = 1;
6932
6933 AttributeCommonInfo Info = NoSanitizeSpecificAttr;
6934 Info.setAttributeSpellingListIndex(TranslatedSpellingIndex);
6935 return Info;
6936}
6937
6939 const ParsedAttr &AL) {
6940 StringRef SanitizerName = "address";
6942 D->addAttr(::new (S.Context)
6943 NoSanitizeAttr(S.Context, Info, &SanitizerName, 1));
6944}
6945
6946static void handleNoSanitizeThreadAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6947 StringRef SanitizerName = "thread";
6949 D->addAttr(::new (S.Context)
6950 NoSanitizeAttr(S.Context, Info, &SanitizerName, 1));
6951}
6952
6953static void handleNoSanitizeMemoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6954 StringRef SanitizerName = "memory";
6956 D->addAttr(::new (S.Context)
6957 NoSanitizeAttr(S.Context, Info, &SanitizerName, 1));
6958}
6959
6960static void handleInternalLinkageAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6961 if (InternalLinkageAttr *Internal = S.mergeInternalLinkageAttr(D, AL))
6962 D->addAttr(Internal);
6963}
6964
6965static void handleZeroCallUsedRegsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6966 // Check that the argument is a string literal.
6967 StringRef KindStr;
6968 SourceLocation LiteralLoc;
6969 if (!S.checkStringLiteralArgumentAttr(AL, 0, KindStr, &LiteralLoc))
6970 return;
6971
6972 ZeroCallUsedRegsAttr::ZeroCallUsedRegsKind Kind;
6973 if (!ZeroCallUsedRegsAttr::ConvertStrToZeroCallUsedRegsKind(KindStr, Kind)) {
6974 S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported)
6975 << AL << KindStr;
6976 return;
6977 }
6978
6979 D->dropAttr<ZeroCallUsedRegsAttr>();
6980 D->addAttr(ZeroCallUsedRegsAttr::Create(S.Context, Kind, AL));
6981}
6982
6983static void handleNoPFPAttrField(Sema &S, Decl *D, const ParsedAttr &AL) {
6984 D->addAttr(NoFieldProtectionAttr::Create(S.Context, AL));
6985}
6986
6987static void handleCountedByAttrField(Sema &S, Decl *D, const ParsedAttr &AL) {
6988 auto *CountExpr = AL.getArgAsExpr(0);
6989 if (!CountExpr)
6990 return;
6991
6992 bool CountInBytes;
6993 bool OrNull;
6994 switch (AL.getKind()) {
6995 case ParsedAttr::AT_CountedBy:
6996 CountInBytes = false;
6997 OrNull = false;
6998 break;
6999 case ParsedAttr::AT_CountedByOrNull:
7000 CountInBytes = false;
7001 OrNull = true;
7002 break;
7003 case ParsedAttr::AT_SizedBy:
7004 CountInBytes = true;
7005 OrNull = false;
7006 break;
7007 case ParsedAttr::AT_SizedByOrNull:
7008 CountInBytes = true;
7009 OrNull = true;
7010 break;
7011 default:
7012 llvm_unreachable("unexpected counted_by family attribute");
7013 }
7014
7015 FieldDecl *FD = cast<FieldDecl>(D);
7016 if (S.CheckCountedByAttrOnField(FD, CountExpr, CountInBytes, OrNull))
7017 return;
7018
7020 FD->getType(), CountExpr, CountInBytes, OrNull);
7021 FD->setType(CAT);
7022}
7023
7025 const ParsedAttr &AL) {
7026 StringRef KindStr;
7027 SourceLocation LiteralLoc;
7028 if (!S.checkStringLiteralArgumentAttr(AL, 0, KindStr, &LiteralLoc))
7029 return;
7030
7031 FunctionReturnThunksAttr::Kind Kind;
7032 if (!FunctionReturnThunksAttr::ConvertStrToKind(KindStr, Kind)) {
7033 S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported)
7034 << AL << KindStr;
7035 return;
7036 }
7037 // FIXME: it would be good to better handle attribute merging rather than
7038 // silently replacing the existing attribute, so long as it does not break
7039 // the expected codegen tests.
7040 D->dropAttr<FunctionReturnThunksAttr>();
7041 D->addAttr(FunctionReturnThunksAttr::Create(S.Context, Kind, AL));
7042}
7043
7045 const ParsedAttr &AL) {
7046 assert(isa<TypedefNameDecl>(D) && "This attribute only applies to a typedef");
7048}
7049
7050static void handleNoMergeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7051 auto *VDecl = dyn_cast<VarDecl>(D);
7052 if (VDecl && !VDecl->isFunctionPointerType()) {
7053 S.Diag(AL.getLoc(), diag::warn_attribute_ignored_non_function_pointer)
7054 << AL << VDecl;
7055 return;
7056 }
7057 D->addAttr(NoMergeAttr::Create(S.Context, AL));
7058}
7059
7060static void handleNoUniqueAddressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7061 D->addAttr(NoUniqueAddressAttr::Create(S.Context, AL));
7062}
7063
7064static void handleDestroyAttr(Sema &S, Decl *D, const ParsedAttr &A) {
7065 if (!cast<VarDecl>(D)->hasGlobalStorage()) {
7066 S.Diag(D->getLocation(), diag::err_destroy_attr_on_non_static_var)
7067 << (A.getKind() == ParsedAttr::AT_AlwaysDestroy);
7068 return;
7069 }
7070
7071 if (A.getKind() == ParsedAttr::AT_AlwaysDestroy)
7073 else
7075}
7076
7077static void handleUninitializedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7078 assert(cast<VarDecl>(D)->getStorageDuration() == SD_Automatic &&
7079 "uninitialized is only valid on automatic duration variables");
7080 D->addAttr(::new (S.Context) UninitializedAttr(S.Context, AL));
7081}
7082
7083static void handleMIGServerRoutineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7084 // Check that the return type is a `typedef int kern_return_t` or a typedef
7085 // around it, because otherwise MIG convention checks make no sense.
7086 // BlockDecl doesn't store a return type, so it's annoying to check,
7087 // so let's skip it for now.
7088 if (!isa<BlockDecl>(D)) {
7090 bool IsKernReturnT = false;
7091 while (const auto *TT = T->getAs<TypedefType>()) {
7092 IsKernReturnT = (TT->getDecl()->getName() == "kern_return_t");
7093 T = TT->desugar();
7094 }
7095 if (!IsKernReturnT || T.getCanonicalType() != S.getASTContext().IntTy) {
7096 S.Diag(D->getBeginLoc(),
7097 diag::warn_mig_server_routine_does_not_return_kern_return_t);
7098 return;
7099 }
7100 }
7101
7103}
7104
7105static void handleMSAllocatorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7106 // Warn if the return type is not a pointer or reference type.
7107 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
7108 QualType RetTy = FD->getReturnType();
7109 if (!RetTy->isPointerOrReferenceType()) {
7110 S.Diag(AL.getLoc(), diag::warn_declspec_allocator_nonpointer)
7111 << AL.getRange() << RetTy;
7112 return;
7113 }
7114 }
7115
7117}
7118
7119static void handleAcquireHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7120 if (AL.isUsedAsTypeAttr())
7121 return;
7122 // Warn if the parameter is definitely not an output parameter.
7123 if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
7124 if (PVD->getType()->isIntegerType()) {
7125 S.Diag(AL.getLoc(), diag::err_attribute_output_parameter)
7126 << AL.getRange();
7127 return;
7128 }
7129 }
7130 StringRef Argument;
7131 if (!S.checkStringLiteralArgumentAttr(AL, 0, Argument))
7132 return;
7133 D->addAttr(AcquireHandleAttr::Create(S.Context, Argument, AL));
7134}
7135
7136template<typename Attr>
7137static void handleHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7138 StringRef Argument;
7139 if (!S.checkStringLiteralArgumentAttr(AL, 0, Argument))
7140 return;
7141 D->addAttr(Attr::Create(S.Context, Argument, AL));
7142}
7143
7144template<typename Attr>
7145static void handleUnsafeBufferUsage(Sema &S, Decl *D, const ParsedAttr &AL) {
7146 D->addAttr(Attr::Create(S.Context, AL));
7147}
7148
7149static void handleCFGuardAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7150 // The guard attribute takes a single identifier argument.
7151
7152 if (!AL.isArgIdent(0)) {
7153 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7154 << AL << AANT_ArgumentIdentifier;
7155 return;
7156 }
7157
7158 CFGuardAttr::GuardArg Arg;
7160 if (!CFGuardAttr::ConvertStrToGuardArg(II->getName(), Arg)) {
7161 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
7162 return;
7163 }
7164
7165 D->addAttr(::new (S.Context) CFGuardAttr(S.Context, AL, Arg));
7166}
7167
7168
7169template <typename AttrTy>
7170static const AttrTy *findEnforceTCBAttrByName(Decl *D, StringRef Name) {
7171 auto Attrs = D->specific_attrs<AttrTy>();
7172 auto I = llvm::find_if(Attrs,
7173 [Name](const AttrTy *A) {
7174 return A->getTCBName() == Name;
7175 });
7176 return I == Attrs.end() ? nullptr : *I;
7177}
7178
7179template <typename AttrTy, typename ConflictingAttrTy>
7180static void handleEnforceTCBAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7181 StringRef Argument;
7182 if (!S.checkStringLiteralArgumentAttr(AL, 0, Argument))
7183 return;
7184
7185 // A function cannot be have both regular and leaf membership in the same TCB.
7186 if (const ConflictingAttrTy *ConflictingAttr =
7188 // We could attach a note to the other attribute but in this case
7189 // there's no need given how the two are very close to each other.
7190 S.Diag(AL.getLoc(), diag::err_tcb_conflicting_attributes)
7191 << AL.getAttrName()->getName() << ConflictingAttr->getAttrName()->getName()
7192 << Argument;
7193
7194 // Error recovery: drop the non-leaf attribute so that to suppress
7195 // all future warnings caused by erroneous attributes. The leaf attribute
7196 // needs to be kept because it can only suppresses warnings, not cause them.
7197 D->dropAttr<EnforceTCBAttr>();
7198 return;
7199 }
7200
7201 D->addAttr(AttrTy::Create(S.Context, Argument, AL));
7202}
7203
7204template <typename AttrTy, typename ConflictingAttrTy>
7205static AttrTy *mergeEnforceTCBAttrImpl(Sema &S, Decl *D, const AttrTy &AL) {
7206 // Check if the new redeclaration has different leaf-ness in the same TCB.
7207 StringRef TCBName = AL.getTCBName();
7208 if (const ConflictingAttrTy *ConflictingAttr =
7210 S.Diag(ConflictingAttr->getLoc(), diag::err_tcb_conflicting_attributes)
7211 << ConflictingAttr->getAttrName()->getName()
7212 << AL.getAttrName()->getName() << TCBName;
7213
7214 // Add a note so that the user could easily find the conflicting attribute.
7215 S.Diag(AL.getLoc(), diag::note_conflicting_attribute);
7216
7217 // More error recovery.
7218 D->dropAttr<EnforceTCBAttr>();
7219 return nullptr;
7220 }
7221
7222 ASTContext &Context = S.getASTContext();
7223 return ::new(Context) AttrTy(Context, AL, AL.getTCBName());
7224}
7225
7226EnforceTCBAttr *Sema::mergeEnforceTCBAttr(Decl *D, const EnforceTCBAttr &AL) {
7228 *this, D, AL);
7229}
7230
7232 Decl *D, const EnforceTCBLeafAttr &AL) {
7234 *this, D, AL);
7235}
7236
7238 const ParsedAttr &AL) {
7240 const uint32_t NumArgs = AL.getNumArgs();
7241 if (NumArgs > 4) {
7242 S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 4;
7243 AL.setInvalid();
7244 }
7245
7246 if (NumArgs == 0) {
7247 S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) << AL;
7248 AL.setInvalid();
7249 return;
7250 }
7251
7252 if (D->getAttr<VTablePointerAuthenticationAttr>()) {
7253 S.Diag(AL.getLoc(), diag::err_duplicated_vtable_pointer_auth) << Decl;
7254 AL.setInvalid();
7255 }
7256
7257 auto KeyType = VTablePointerAuthenticationAttr::VPtrAuthKeyType::DefaultKey;
7258 if (AL.isArgIdent(0)) {
7259 IdentifierLoc *IL = AL.getArgAsIdent(0);
7260 if (!VTablePointerAuthenticationAttr::ConvertStrToVPtrAuthKeyType(
7261 IL->getIdentifierInfo()->getName(), KeyType)) {
7262 S.Diag(IL->getLoc(), diag::err_invalid_authentication_key)
7263 << IL->getIdentifierInfo();
7264 AL.setInvalid();
7265 }
7266 if (KeyType == VTablePointerAuthenticationAttr::DefaultKey &&
7267 !S.getLangOpts().PointerAuthCalls) {
7268 S.Diag(AL.getLoc(), diag::err_no_default_vtable_pointer_auth) << 0;
7269 AL.setInvalid();
7270 }
7271 } else {
7272 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7273 << AL << AANT_ArgumentIdentifier;
7274 return;
7275 }
7276
7277 auto AddressDiversityMode = VTablePointerAuthenticationAttr::
7278 AddressDiscriminationMode::DefaultAddressDiscrimination;
7279 if (AL.getNumArgs() > 1) {
7280 if (AL.isArgIdent(1)) {
7281 IdentifierLoc *IL = AL.getArgAsIdent(1);
7282 if (!VTablePointerAuthenticationAttr::
7283 ConvertStrToAddressDiscriminationMode(
7284 IL->getIdentifierInfo()->getName(), AddressDiversityMode)) {
7285 S.Diag(IL->getLoc(), diag::err_invalid_address_discrimination)
7286 << IL->getIdentifierInfo();
7287 AL.setInvalid();
7288 }
7289 if (AddressDiversityMode ==
7290 VTablePointerAuthenticationAttr::DefaultAddressDiscrimination &&
7291 !S.getLangOpts().PointerAuthCalls) {
7292 S.Diag(IL->getLoc(), diag::err_no_default_vtable_pointer_auth) << 1;
7293 AL.setInvalid();
7294 }
7295 } else {
7296 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7297 << AL << AANT_ArgumentIdentifier;
7298 }
7299 }
7300
7301 auto ED = VTablePointerAuthenticationAttr::ExtraDiscrimination::
7302 DefaultExtraDiscrimination;
7303 if (AL.getNumArgs() > 2) {
7304 if (AL.isArgIdent(2)) {
7305 IdentifierLoc *IL = AL.getArgAsIdent(2);
7306 if (!VTablePointerAuthenticationAttr::ConvertStrToExtraDiscrimination(
7307 IL->getIdentifierInfo()->getName(), ED)) {
7308 S.Diag(IL->getLoc(), diag::err_invalid_extra_discrimination)
7309 << IL->getIdentifierInfo();
7310 AL.setInvalid();
7311 }
7312 if (ED == VTablePointerAuthenticationAttr::DefaultExtraDiscrimination &&
7313 !S.getLangOpts().PointerAuthCalls) {
7314 S.Diag(AL.getLoc(), diag::err_no_default_vtable_pointer_auth) << 2;
7315 AL.setInvalid();
7316 }
7317 } else {
7318 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7319 << AL << AANT_ArgumentIdentifier;
7320 }
7321 }
7322
7323 uint32_t CustomDiscriminationValue = 0;
7324 if (ED == VTablePointerAuthenticationAttr::CustomDiscrimination) {
7325 if (NumArgs < 4) {
7326 S.Diag(AL.getLoc(), diag::err_missing_custom_discrimination) << AL << 4;
7327 AL.setInvalid();
7328 return;
7329 }
7330 if (NumArgs > 4) {
7331 S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 4;
7332 AL.setInvalid();
7333 }
7334
7335 if (!AL.isArgExpr(3) || !S.checkUInt32Argument(AL, AL.getArgAsExpr(3),
7336 CustomDiscriminationValue)) {
7337 S.Diag(AL.getLoc(), diag::err_invalid_custom_discrimination);
7338 AL.setInvalid();
7339 }
7340 } else if (NumArgs > 3) {
7341 S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 3;
7342 AL.setInvalid();
7343 }
7344
7345 Decl->addAttr(::new (S.Context) VTablePointerAuthenticationAttr(
7346 S.Context, AL, KeyType, AddressDiversityMode, ED,
7347 CustomDiscriminationValue));
7348}
7349
7350static bool modularFormatAttrsEquiv(const ModularFormatAttr *Existing,
7351 const IdentifierInfo *ModularImplFn,
7352 StringRef ImplName,
7353 ArrayRef<StringRef> Aspects) {
7354 return Existing->getModularImplFn() == ModularImplFn &&
7355 Existing->getImplName() == ImplName &&
7356 Existing->aspects_size() == Aspects.size() &&
7357 llvm::equal(Existing->aspects(), Aspects);
7358}
7359
7361 Decl *D, const AttributeCommonInfo &CI, const IdentifierInfo *ModularImplFn,
7362 StringRef ImplName, MutableArrayRef<StringRef> Aspects) {
7363 if (const auto *Existing = D->getAttr<ModularFormatAttr>()) {
7364 if (!modularFormatAttrsEquiv(Existing, ModularImplFn, ImplName, Aspects)) {
7365 Diag(Existing->getLocation(), diag::err_duplicate_attribute) << *Existing;
7366 Diag(CI.getLoc(), diag::note_conflicting_attribute);
7367 }
7368 return nullptr;
7369 }
7370 return ::new (Context) ModularFormatAttr(Context, CI, ModularImplFn, ImplName,
7371 Aspects.data(), Aspects.size());
7372}
7373
7374static void handleModularFormat(Sema &S, Decl *D, const ParsedAttr &AL) {
7375 bool Valid = true;
7376 if (!AL.isArgIdent(0)) {
7377 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
7378 << AL << 1 << AANT_ArgumentIdentifier;
7379 Valid = false;
7380 }
7381 StringRef ImplName;
7382 if (!S.checkStringLiteralArgumentAttr(AL, 1, ImplName))
7383 Valid = false;
7384 SmallVector<StringRef> Aspects;
7385 llvm::DenseSet<StringRef> SeenAspects;
7386 for (unsigned I = 2, E = AL.getNumArgs(); I != E; ++I) {
7387 StringRef Aspect;
7388 if (!S.checkStringLiteralArgumentAttr(AL, I, Aspect))
7389 return;
7390 if (!SeenAspects.insert(Aspect).second) {
7391 S.Diag(AL.getArgAsExpr(I)->getExprLoc(),
7392 diag::err_modular_format_duplicate_aspect)
7393 << Aspect;
7394 Valid = false;
7395 continue;
7396 }
7397 Aspects.push_back(Aspect);
7398 }
7399 if (!Valid)
7400 return;
7401
7402 // Store aspects sorted.
7403 llvm::sort(Aspects);
7404 IdentifierInfo *ModularImplFn = AL.getArgAsIdent(0)->getIdentifierInfo();
7405
7406 if (const auto *Existing = D->getAttr<ModularFormatAttr>()) {
7407 if (!modularFormatAttrsEquiv(Existing, ModularImplFn, ImplName, Aspects)) {
7408 S.Diag(AL.getLoc(), diag::err_duplicate_attribute) << *Existing;
7409 S.Diag(Existing->getLoc(), diag::note_conflicting_attribute);
7410 }
7411 // Ignore the later declaration in favor of the earlier one.
7412 return;
7413 }
7414
7415 D->addAttr(::new (S.Context) ModularFormatAttr(
7416 S.Context, AL, ModularImplFn, ImplName, Aspects.data(), Aspects.size()));
7417}
7418
7419//===----------------------------------------------------------------------===//
7420// Top Level Sema Entry Points
7421//===----------------------------------------------------------------------===//
7422
7423// Returns true if the attribute must delay setting its arguments until after
7424// template instantiation, and false otherwise.
7426 // Only attributes that accept expression parameter packs can delay arguments.
7427 if (!AL.acceptsExprPack())
7428 return false;
7429
7430 bool AttrHasVariadicArg = AL.hasVariadicArg();
7431 unsigned AttrNumArgs = AL.getNumArgMembers();
7432 for (size_t I = 0; I < std::min(AL.getNumArgs(), AttrNumArgs); ++I) {
7433 bool IsLastAttrArg = I == (AttrNumArgs - 1);
7434 // If the argument is the last argument and it is variadic it can contain
7435 // any expression.
7436 if (IsLastAttrArg && AttrHasVariadicArg)
7437 return false;
7438 Expr *E = AL.getArgAsExpr(I);
7439 bool ArgMemberCanHoldExpr = AL.isParamExpr(I);
7440 // If the expression is a pack expansion then arguments must be delayed
7441 // unless the argument is an expression and it is the last argument of the
7442 // attribute.
7444 return !(IsLastAttrArg && ArgMemberCanHoldExpr);
7445 // Last case is if the expression is value dependent then it must delay
7446 // arguments unless the corresponding argument is able to hold the
7447 // expression.
7448 if (E->isValueDependent() && !ArgMemberCanHoldExpr)
7449 return true;
7450 }
7451 return false;
7452}
7453
7455 const AttributeCommonInfo &CI) {
7456 if (PersonalityAttr *PA = D->getAttr<PersonalityAttr>()) {
7457 const FunctionDecl *Personality = PA->getRoutine();
7458 if (Context.isSameEntity(Personality, Routine))
7459 return nullptr;
7460 Diag(PA->getLocation(), diag::err_mismatched_personality);
7461 Diag(CI.getLoc(), diag::note_previous_attribute);
7462 D->dropAttr<PersonalityAttr>();
7463 }
7464 return ::new (Context) PersonalityAttr(Context, CI, Routine);
7465}
7466
7467static void handlePersonalityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7468 Expr *E = AL.getArgAsExpr(0);
7469 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
7470 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(DRE->getDecl()))
7471 if (Attr *A = S.mergePersonalityAttr(D, FD, AL))
7472 return D->addAttr(A);
7473 S.Diag(E->getExprLoc(), diag::err_attribute_personality_arg_not_function)
7474 << AL.getAttrName();
7475}
7476
7477/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
7478/// the attribute applies to decls. If the attribute is a type attribute, just
7479/// silently ignore it if a GNU attribute.
7480static void
7482 const Sema::ProcessDeclAttributeOptions &Options) {
7484 return;
7485
7486 // Ignore C++11 attributes on declarator chunks: they appertain to the type
7487 // instead. Note, isCXX11Attribute() will look at whether the attribute is
7488 // [[]] or alignas, while isC23Attribute() will only look at [[]]. This is
7489 // important for ensuring that alignas in C23 is properly handled on a
7490 // structure member declaration because it is a type-specifier-qualifier in
7491 // C but still applies to the declaration rather than the type.
7492 if ((S.getLangOpts().CPlusPlus ? AL.isCXX11Attribute()
7493 : AL.isC23Attribute()) &&
7494 !Options.IncludeCXX11Attributes)
7495 return;
7496
7497 // Unknown attributes are automatically warned on. Target-specific attributes
7498 // which do not apply to the current target architecture are treated as
7499 // though they were unknown attributes.
7502 if (AL.isRegularKeywordAttribute()) {
7503 S.Diag(AL.getLoc(), diag::err_keyword_not_supported_on_target)
7504 << AL.getAttrName() << AL.getRange();
7505 } else if (AL.isDeclspecAttribute()) {
7506 S.Diag(AL.getLoc(), diag::warn_unhandled_ms_attribute_ignored)
7507 << AL.getAttrName() << AL.getRange();
7508 } else {
7510 }
7511 return;
7512 }
7513
7514 if (S.getLangOpts().HLSL && isa<FunctionDecl>(D) &&
7515 AL.getKind() == ParsedAttr::AT_NoInline) {
7516 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
7517 for (const ParmVarDecl *PVD : FD->parameters()) {
7518 if (PVD->hasAttr<HLSLGroupSharedAddressSpaceAttr>()) {
7519 S.Diag(AL.getLoc(), diag::err_hlsl_attr_incompatible)
7520 << "'noinline'" << "'groupshared' parameter";
7521 return;
7522 }
7523 }
7524 }
7525 }
7526
7527 // Check if argument population must delayed to after template instantiation.
7528 bool MustDelayArgs = MustDelayAttributeArguments(AL);
7529
7530 // Argument number check must be skipped if arguments are delayed.
7531 if (S.checkCommonAttributeFeatures(D, AL, MustDelayArgs))
7532 return;
7533
7534 if (MustDelayArgs) {
7536 return;
7537 }
7538
7539 switch (AL.getKind()) {
7540 default:
7542 break;
7543 if (!AL.isStmtAttr()) {
7544 assert(AL.isTypeAttr() && "Non-type attribute not handled");
7545 }
7546 if (AL.isTypeAttr()) {
7547 if (Options.IgnoreTypeAttributes)
7548 break;
7550 // Non-[[]] type attributes are handled in processTypeAttrs(); silently
7551 // move on.
7552 break;
7553 }
7554
7555 // According to the C and C++ standards, we should never see a
7556 // [[]] type attribute on a declaration. However, we have in the past
7557 // allowed some type attributes to "slide" to the `DeclSpec`, so we need
7558 // to continue to support this legacy behavior. We only do this, however,
7559 // if
7560 // - we actually have a `DeclSpec`, i.e. if we're looking at a
7561 // `DeclaratorDecl`, or
7562 // - we are looking at an alias-declaration, where historically we have
7563 // allowed type attributes after the identifier to slide to the type.
7566 // Suggest moving the attribute to the type instead, but only for our
7567 // own vendor attributes; moving other vendors' attributes might hurt
7568 // portability.
7569 if (AL.isClangScope()) {
7570 S.Diag(AL.getLoc(), diag::warn_type_attribute_deprecated_on_decl)
7571 << AL << D->getLocation();
7572 }
7573
7574 // Allow this type attribute to be handled in processTypeAttrs();
7575 // silently move on.
7576 break;
7577 }
7578
7579 if (AL.getKind() == ParsedAttr::AT_Regparm) {
7580 // `regparm` is a special case: It's a type attribute but we still want
7581 // to treat it as if it had been written on the declaration because that
7582 // way we'll be able to handle it directly in `processTypeAttr()`.
7583 // If we treated `regparm` it as if it had been written on the
7584 // `DeclSpec`, the logic in `distributeFunctionTypeAttrFromDeclSepc()`
7585 // would try to move it to the declarator, but that doesn't work: We
7586 // can't remove the attribute from the list of declaration attributes
7587 // because it might be needed by other declarators in the same
7588 // declaration.
7589 break;
7590 }
7591
7592 if (AL.getKind() == ParsedAttr::AT_VectorSize) {
7593 // `vector_size` is a special case: It's a type attribute semantically,
7594 // but GCC expects the [[]] syntax to be written on the declaration (and
7595 // warns that the attribute has no effect if it is placed on the
7596 // decl-specifier-seq).
7597 // Silently move on and allow the attribute to be handled in
7598 // processTypeAttr().
7599 break;
7600 }
7601
7602 if (AL.getKind() == ParsedAttr::AT_NoDeref) {
7603 // FIXME: `noderef` currently doesn't work correctly in [[]] syntax.
7604 // See https://github.com/llvm/llvm-project/issues/55790 for details.
7605 // We allow processTypeAttrs() to emit a warning and silently move on.
7606 break;
7607 }
7608 }
7609 // N.B., ClangAttrEmitter.cpp emits a diagnostic helper that ensures a
7610 // statement attribute is not written on a declaration, but this code is
7611 // needed for type attributes as well as statement attributes in Attr.td
7612 // that do not list any subjects.
7613 S.Diag(AL.getLoc(), diag::err_attribute_invalid_on_decl)
7614 << AL << AL.isRegularKeywordAttribute() << D->getLocation();
7615 break;
7616 case ParsedAttr::AT_Interrupt:
7617 handleInterruptAttr(S, D, AL);
7618 break;
7619 case ParsedAttr::AT_ARMInterruptSaveFP:
7620 S.ARM().handleInterruptSaveFPAttr(D, AL);
7621 break;
7622 case ParsedAttr::AT_X86ForceAlignArgPointer:
7624 break;
7625 case ParsedAttr::AT_ReadOnlyPlacement:
7627 break;
7628 case ParsedAttr::AT_DLLExport:
7629 case ParsedAttr::AT_DLLImport:
7630 handleDLLAttr(S, D, AL);
7631 break;
7632 case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
7634 break;
7635 case ParsedAttr::AT_AMDGPUWavesPerEU:
7637 break;
7638 case ParsedAttr::AT_AMDGPUNumSGPR:
7640 break;
7641 case ParsedAttr::AT_AMDGPUNumVGPR:
7643 break;
7644 case ParsedAttr::AT_AMDGPUMaxNumWorkGroups:
7646 break;
7647 case ParsedAttr::AT_AVRSignal:
7648 S.AVR().handleSignalAttr(D, AL);
7649 break;
7650 case ParsedAttr::AT_BPFPreserveAccessIndex:
7652 break;
7653 case ParsedAttr::AT_BPFPreserveStaticOffset:
7655 break;
7656 case ParsedAttr::AT_BTFDeclTag:
7657 handleBTFDeclTagAttr(S, D, AL);
7658 break;
7659 case ParsedAttr::AT_WebAssemblyExportName:
7661 break;
7662 case ParsedAttr::AT_WebAssemblyImportModule:
7664 break;
7665 case ParsedAttr::AT_WebAssemblyImportName:
7667 break;
7668 case ParsedAttr::AT_IBOutlet:
7669 S.ObjC().handleIBOutlet(D, AL);
7670 break;
7671 case ParsedAttr::AT_IBOutletCollection:
7672 S.ObjC().handleIBOutletCollection(D, AL);
7673 break;
7674 case ParsedAttr::AT_IFunc:
7675 handleIFuncAttr(S, D, AL);
7676 break;
7677 case ParsedAttr::AT_Alias:
7678 handleAliasAttr(S, D, AL);
7679 break;
7680 case ParsedAttr::AT_Aligned:
7681 handleAlignedAttr(S, D, AL);
7682 break;
7683 case ParsedAttr::AT_AlignValue:
7684 handleAlignValueAttr(S, D, AL);
7685 break;
7686 case ParsedAttr::AT_AllocSize:
7687 handleAllocSizeAttr(S, D, AL);
7688 break;
7689 case ParsedAttr::AT_AlwaysInline:
7690 handleAlwaysInlineAttr(S, D, AL);
7691 break;
7692 case ParsedAttr::AT_AnalyzerNoReturn:
7694 break;
7695 case ParsedAttr::AT_TLSModel:
7696 handleTLSModelAttr(S, D, AL);
7697 break;
7698 case ParsedAttr::AT_Annotate:
7699 handleAnnotateAttr(S, D, AL);
7700 break;
7701 case ParsedAttr::AT_Availability:
7702 handleAvailabilityAttr(S, D, AL);
7703 break;
7704 case ParsedAttr::AT_CarriesDependency:
7705 handleDependencyAttr(S, scope, D, AL);
7706 break;
7707 case ParsedAttr::AT_CPUDispatch:
7708 case ParsedAttr::AT_CPUSpecific:
7709 handleCPUSpecificAttr(S, D, AL);
7710 break;
7711 case ParsedAttr::AT_Common:
7712 handleCommonAttr(S, D, AL);
7713 break;
7714 case ParsedAttr::AT_CUDAConstant:
7715 handleConstantAttr(S, D, AL);
7716 break;
7717 case ParsedAttr::AT_PassObjectSize:
7718 handlePassObjectSizeAttr(S, D, AL);
7719 break;
7720 case ParsedAttr::AT_Constructor:
7721 handleConstructorAttr(S, D, AL);
7722 break;
7723 case ParsedAttr::AT_Deprecated:
7724 handleDeprecatedAttr(S, D, AL);
7725 break;
7726 case ParsedAttr::AT_Destructor:
7727 handleDestructorAttr(S, D, AL);
7728 break;
7729 case ParsedAttr::AT_EnableIf:
7730 handleEnableIfAttr(S, D, AL);
7731 break;
7732 case ParsedAttr::AT_Error:
7733 handleErrorAttr(S, D, AL);
7734 break;
7735 case ParsedAttr::AT_ExcludeFromExplicitInstantiation:
7737 break;
7738 case ParsedAttr::AT_DiagnoseIf:
7739 handleDiagnoseIfAttr(S, D, AL);
7740 break;
7741 case ParsedAttr::AT_DiagnoseAsBuiltin:
7743 break;
7744 case ParsedAttr::AT_NoBuiltin:
7745 handleNoBuiltinAttr(S, D, AL);
7746 break;
7747 case ParsedAttr::AT_CFIUncheckedCallee:
7749 break;
7750 case ParsedAttr::AT_ExtVectorType:
7751 handleExtVectorTypeAttr(S, D, AL);
7752 break;
7753 case ParsedAttr::AT_ExternalSourceSymbol:
7755 break;
7756 case ParsedAttr::AT_MinSize:
7757 handleMinSizeAttr(S, D, AL);
7758 break;
7759 case ParsedAttr::AT_OptimizeNone:
7760 handleOptimizeNoneAttr(S, D, AL);
7761 break;
7762 case ParsedAttr::AT_EnumExtensibility:
7764 break;
7765 case ParsedAttr::AT_SYCLKernel:
7766 S.SYCL().handleKernelAttr(D, AL);
7767 break;
7768 case ParsedAttr::AT_SYCLExternal:
7770 break;
7771 case ParsedAttr::AT_SYCLKernelEntryPoint:
7773 break;
7774 case ParsedAttr::AT_SYCLSpecialClass:
7776 break;
7777 case ParsedAttr::AT_Format:
7778 handleFormatAttr(S, D, AL);
7779 break;
7780 case ParsedAttr::AT_FormatMatches:
7781 handleFormatMatchesAttr(S, D, AL);
7782 break;
7783 case ParsedAttr::AT_FormatArg:
7784 handleFormatArgAttr(S, D, AL);
7785 break;
7786 case ParsedAttr::AT_Callback:
7787 handleCallbackAttr(S, D, AL);
7788 break;
7789 case ParsedAttr::AT_LifetimeCaptureBy:
7791 break;
7792 case ParsedAttr::AT_CalledOnce:
7793 handleCalledOnceAttr(S, D, AL);
7794 break;
7795 case ParsedAttr::AT_CUDAGlobal:
7796 handleGlobalAttr(S, D, AL);
7797 break;
7798 case ParsedAttr::AT_CUDADevice:
7799 handleDeviceAttr(S, D, AL);
7800 break;
7801 case ParsedAttr::AT_CUDAGridConstant:
7802 handleGridConstantAttr(S, D, AL);
7803 break;
7804 case ParsedAttr::AT_HIPManaged:
7805 handleManagedAttr(S, D, AL);
7806 break;
7807 case ParsedAttr::AT_GNUInline:
7808 handleGNUInlineAttr(S, D, AL);
7809 break;
7810 case ParsedAttr::AT_CUDALaunchBounds:
7811 handleLaunchBoundsAttr(S, D, AL);
7812 break;
7813 case ParsedAttr::AT_CUDAClusterDims:
7814 handleClusterDimsAttr(S, D, AL);
7815 break;
7816 case ParsedAttr::AT_CUDANoCluster:
7817 handleNoClusterAttr(S, D, AL);
7818 break;
7819 case ParsedAttr::AT_Restrict:
7820 handleRestrictAttr(S, D, AL);
7821 break;
7822 case ParsedAttr::AT_MallocSpan:
7823 handleMallocSpanAttr(S, D, AL);
7824 break;
7825 case ParsedAttr::AT_Mode:
7826 handleModeAttr(S, D, AL);
7827 break;
7828 case ParsedAttr::AT_NonString:
7829 handleNonStringAttr(S, D, AL);
7830 break;
7831 case ParsedAttr::AT_NonNull:
7832 if (auto *PVD = dyn_cast<ParmVarDecl>(D))
7833 handleNonNullAttrParameter(S, PVD, AL);
7834 else
7835 handleNonNullAttr(S, D, AL);
7836 break;
7837 case ParsedAttr::AT_ReturnsNonNull:
7838 handleReturnsNonNullAttr(S, D, AL);
7839 break;
7840 case ParsedAttr::AT_NoEscape:
7841 handleNoEscapeAttr(S, D, AL);
7842 break;
7843 case ParsedAttr::AT_MaybeUndef:
7845 break;
7846 case ParsedAttr::AT_AssumeAligned:
7847 handleAssumeAlignedAttr(S, D, AL);
7848 break;
7849 case ParsedAttr::AT_AllocAlign:
7850 handleAllocAlignAttr(S, D, AL);
7851 break;
7852 case ParsedAttr::AT_Ownership:
7853 handleOwnershipAttr(S, D, AL);
7854 break;
7855 case ParsedAttr::AT_Naked:
7856 handleNakedAttr(S, D, AL);
7857 break;
7858 case ParsedAttr::AT_NoReturn:
7859 handleNoReturnAttr(S, D, AL);
7860 break;
7861 case ParsedAttr::AT_CXX11NoReturn:
7863 break;
7864 case ParsedAttr::AT_AnyX86NoCfCheck:
7865 handleNoCfCheckAttr(S, D, AL);
7866 break;
7867 case ParsedAttr::AT_NoThrow:
7868 if (!AL.isUsedAsTypeAttr())
7870 break;
7871 case ParsedAttr::AT_CUDAShared:
7872 handleSharedAttr(S, D, AL);
7873 break;
7874 case ParsedAttr::AT_VecReturn:
7875 handleVecReturnAttr(S, D, AL);
7876 break;
7877 case ParsedAttr::AT_ObjCOwnership:
7878 S.ObjC().handleOwnershipAttr(D, AL);
7879 break;
7880 case ParsedAttr::AT_ObjCPreciseLifetime:
7882 break;
7883 case ParsedAttr::AT_ObjCReturnsInnerPointer:
7885 break;
7886 case ParsedAttr::AT_ObjCRequiresSuper:
7887 S.ObjC().handleRequiresSuperAttr(D, AL);
7888 break;
7889 case ParsedAttr::AT_ObjCBridge:
7890 S.ObjC().handleBridgeAttr(D, AL);
7891 break;
7892 case ParsedAttr::AT_ObjCBridgeMutable:
7893 S.ObjC().handleBridgeMutableAttr(D, AL);
7894 break;
7895 case ParsedAttr::AT_ObjCBridgeRelated:
7896 S.ObjC().handleBridgeRelatedAttr(D, AL);
7897 break;
7898 case ParsedAttr::AT_ObjCDesignatedInitializer:
7900 break;
7901 case ParsedAttr::AT_ObjCRuntimeName:
7902 S.ObjC().handleRuntimeName(D, AL);
7903 break;
7904 case ParsedAttr::AT_ObjCBoxable:
7905 S.ObjC().handleBoxable(D, AL);
7906 break;
7907 case ParsedAttr::AT_NSErrorDomain:
7908 S.ObjC().handleNSErrorDomain(D, AL);
7909 break;
7910 case ParsedAttr::AT_CFConsumed:
7911 case ParsedAttr::AT_NSConsumed:
7912 case ParsedAttr::AT_OSConsumed:
7913 S.ObjC().AddXConsumedAttr(D, AL,
7915 /*IsTemplateInstantiation=*/false);
7916 break;
7917 case ParsedAttr::AT_OSReturnsRetainedOnZero:
7919 S, D, AL, S.ObjC().isValidOSObjectOutParameter(D),
7920 diag::warn_ns_attribute_wrong_parameter_type,
7921 /*Extra Args=*/AL, /*pointer-to-OSObject-pointer*/ 3, AL.getRange());
7922 break;
7923 case ParsedAttr::AT_OSReturnsRetainedOnNonZero:
7925 S, D, AL, S.ObjC().isValidOSObjectOutParameter(D),
7926 diag::warn_ns_attribute_wrong_parameter_type,
7927 /*Extra Args=*/AL, /*pointer-to-OSObject-poointer*/ 3, AL.getRange());
7928 break;
7929 case ParsedAttr::AT_NSReturnsAutoreleased:
7930 case ParsedAttr::AT_NSReturnsNotRetained:
7931 case ParsedAttr::AT_NSReturnsRetained:
7932 case ParsedAttr::AT_CFReturnsNotRetained:
7933 case ParsedAttr::AT_CFReturnsRetained:
7934 case ParsedAttr::AT_OSReturnsNotRetained:
7935 case ParsedAttr::AT_OSReturnsRetained:
7937 break;
7938 case ParsedAttr::AT_WorkGroupSizeHint:
7940 break;
7941 case ParsedAttr::AT_ReqdWorkGroupSize:
7943 break;
7944 case ParsedAttr::AT_OpenCLIntelReqdSubGroupSize:
7945 S.OpenCL().handleSubGroupSize(D, AL);
7946 break;
7947 case ParsedAttr::AT_VecTypeHint:
7948 handleVecTypeHint(S, D, AL);
7949 break;
7950 case ParsedAttr::AT_InitPriority:
7951 handleInitPriorityAttr(S, D, AL);
7952 break;
7953 case ParsedAttr::AT_Packed:
7954 handlePackedAttr(S, D, AL);
7955 break;
7956 case ParsedAttr::AT_PreferredName:
7957 handlePreferredName(S, D, AL);
7958 break;
7959 case ParsedAttr::AT_NoSpecializations:
7960 handleNoSpecializations(S, D, AL);
7961 break;
7962 case ParsedAttr::AT_Section:
7963 handleSectionAttr(S, D, AL);
7964 break;
7965 case ParsedAttr::AT_CodeModel:
7966 handleCodeModelAttr(S, D, AL);
7967 break;
7968 case ParsedAttr::AT_RandomizeLayout:
7969 handleRandomizeLayoutAttr(S, D, AL);
7970 break;
7971 case ParsedAttr::AT_NoRandomizeLayout:
7973 break;
7974 case ParsedAttr::AT_CodeSeg:
7975 handleCodeSegAttr(S, D, AL);
7976 break;
7977 case ParsedAttr::AT_Target:
7978 handleTargetAttr(S, D, AL);
7979 break;
7980 case ParsedAttr::AT_TargetVersion:
7981 handleTargetVersionAttr(S, D, AL);
7982 break;
7983 case ParsedAttr::AT_TargetClones:
7984 handleTargetClonesAttr(S, D, AL);
7985 break;
7986 case ParsedAttr::AT_MinVectorWidth:
7987 handleMinVectorWidthAttr(S, D, AL);
7988 break;
7989 case ParsedAttr::AT_Unavailable:
7991 break;
7992 case ParsedAttr::AT_OMPAssume:
7993 S.OpenMP().handleOMPAssumeAttr(D, AL);
7994 break;
7995 case ParsedAttr::AT_ObjCDirect:
7996 S.ObjC().handleDirectAttr(D, AL);
7997 break;
7998 case ParsedAttr::AT_ObjCDirectMembers:
7999 S.ObjC().handleDirectMembersAttr(D, AL);
8001 break;
8002 case ParsedAttr::AT_ObjCExplicitProtocolImpl:
8004 break;
8005 case ParsedAttr::AT_Unused:
8006 handleUnusedAttr(S, D, AL);
8007 break;
8008 case ParsedAttr::AT_Visibility:
8009 handleVisibilityAttr(S, D, AL, false);
8010 break;
8011 case ParsedAttr::AT_TypeVisibility:
8012 handleVisibilityAttr(S, D, AL, true);
8013 break;
8014 case ParsedAttr::AT_WarnUnusedResult:
8015 handleWarnUnusedResult(S, D, AL);
8016 break;
8017 case ParsedAttr::AT_WeakRef:
8018 handleWeakRefAttr(S, D, AL);
8019 break;
8020 case ParsedAttr::AT_WeakImport:
8021 handleWeakImportAttr(S, D, AL);
8022 break;
8023 case ParsedAttr::AT_TransparentUnion:
8025 break;
8026 case ParsedAttr::AT_ObjCMethodFamily:
8027 S.ObjC().handleMethodFamilyAttr(D, AL);
8028 break;
8029 case ParsedAttr::AT_ObjCNSObject:
8030 S.ObjC().handleNSObject(D, AL);
8031 break;
8032 case ParsedAttr::AT_ObjCIndependentClass:
8033 S.ObjC().handleIndependentClass(D, AL);
8034 break;
8035 case ParsedAttr::AT_Blocks:
8036 S.ObjC().handleBlocksAttr(D, AL);
8037 break;
8038 case ParsedAttr::AT_Sentinel:
8039 handleSentinelAttr(S, D, AL);
8040 break;
8041 case ParsedAttr::AT_Cleanup:
8042 handleCleanupAttr(S, D, AL);
8043 break;
8044 case ParsedAttr::AT_NoDebug:
8045 handleNoDebugAttr(S, D, AL);
8046 break;
8047 case ParsedAttr::AT_CmseNSEntry:
8048 S.ARM().handleCmseNSEntryAttr(D, AL);
8049 break;
8050 case ParsedAttr::AT_StdCall:
8051 case ParsedAttr::AT_CDecl:
8052 case ParsedAttr::AT_FastCall:
8053 case ParsedAttr::AT_ThisCall:
8054 case ParsedAttr::AT_Pascal:
8055 case ParsedAttr::AT_RegCall:
8056 case ParsedAttr::AT_SwiftCall:
8057 case ParsedAttr::AT_SwiftAsyncCall:
8058 case ParsedAttr::AT_VectorCall:
8059 case ParsedAttr::AT_MSABI:
8060 case ParsedAttr::AT_SysVABI:
8061 case ParsedAttr::AT_Pcs:
8062 case ParsedAttr::AT_IntelOclBicc:
8063 case ParsedAttr::AT_PreserveMost:
8064 case ParsedAttr::AT_PreserveAll:
8065 case ParsedAttr::AT_AArch64VectorPcs:
8066 case ParsedAttr::AT_AArch64SVEPcs:
8067 case ParsedAttr::AT_M68kRTD:
8068 case ParsedAttr::AT_PreserveNone:
8069 case ParsedAttr::AT_RISCVVectorCC:
8070 case ParsedAttr::AT_RISCVVLSCC:
8071 handleCallConvAttr(S, D, AL);
8072 break;
8073 case ParsedAttr::AT_DeviceKernel:
8074 handleDeviceKernelAttr(S, D, AL);
8075 break;
8076 case ParsedAttr::AT_Suppress:
8077 handleSuppressAttr(S, D, AL);
8078 break;
8079 case ParsedAttr::AT_Owner:
8080 case ParsedAttr::AT_Pointer:
8082 break;
8083 case ParsedAttr::AT_OpenCLAccess:
8084 S.OpenCL().handleAccessAttr(D, AL);
8085 break;
8086 case ParsedAttr::AT_OpenCLNoSVM:
8087 S.OpenCL().handleNoSVMAttr(D, AL);
8088 break;
8089 case ParsedAttr::AT_SwiftContext:
8091 break;
8092 case ParsedAttr::AT_SwiftAsyncContext:
8094 break;
8095 case ParsedAttr::AT_SwiftErrorResult:
8097 break;
8098 case ParsedAttr::AT_SwiftIndirectResult:
8100 break;
8101 case ParsedAttr::AT_InternalLinkage:
8102 handleInternalLinkageAttr(S, D, AL);
8103 break;
8104 case ParsedAttr::AT_ZeroCallUsedRegs:
8106 break;
8107 case ParsedAttr::AT_FunctionReturnThunks:
8109 break;
8110 case ParsedAttr::AT_NoMerge:
8111 handleNoMergeAttr(S, D, AL);
8112 break;
8113 case ParsedAttr::AT_NoUniqueAddress:
8114 handleNoUniqueAddressAttr(S, D, AL);
8115 break;
8116
8117 case ParsedAttr::AT_AvailableOnlyInDefaultEvalMethod:
8119 break;
8120
8121 case ParsedAttr::AT_CountedBy:
8122 case ParsedAttr::AT_CountedByOrNull:
8123 case ParsedAttr::AT_SizedBy:
8124 case ParsedAttr::AT_SizedByOrNull:
8125 handleCountedByAttrField(S, D, AL);
8126 break;
8127
8128 case ParsedAttr::AT_NoFieldProtection:
8129 handleNoPFPAttrField(S, D, AL);
8130 break;
8131
8132 case ParsedAttr::AT_Personality:
8133 handlePersonalityAttr(S, D, AL);
8134 break;
8135
8136 // Microsoft attributes:
8137 case ParsedAttr::AT_LayoutVersion:
8138 handleLayoutVersion(S, D, AL);
8139 break;
8140 case ParsedAttr::AT_Uuid:
8141 handleUuidAttr(S, D, AL);
8142 break;
8143 case ParsedAttr::AT_MSInheritance:
8144 handleMSInheritanceAttr(S, D, AL);
8145 break;
8146 case ParsedAttr::AT_Thread:
8147 handleDeclspecThreadAttr(S, D, AL);
8148 break;
8149 case ParsedAttr::AT_MSConstexpr:
8150 handleMSConstexprAttr(S, D, AL);
8151 break;
8152 case ParsedAttr::AT_HybridPatchable:
8154 break;
8155
8156 // HLSL attributes:
8157 case ParsedAttr::AT_RootSignature:
8158 S.HLSL().handleRootSignatureAttr(D, AL);
8159 break;
8160 case ParsedAttr::AT_HLSLNumThreads:
8161 S.HLSL().handleNumThreadsAttr(D, AL);
8162 break;
8163 case ParsedAttr::AT_HLSLWaveSize:
8164 S.HLSL().handleWaveSizeAttr(D, AL);
8165 break;
8166 case ParsedAttr::AT_HLSLVkExtBuiltinInput:
8168 break;
8169 case ParsedAttr::AT_HLSLVkExtBuiltinOutput:
8171 break;
8172 case ParsedAttr::AT_HLSLVkPushConstant:
8173 S.HLSL().handleVkPushConstantAttr(D, AL);
8174 break;
8175 case ParsedAttr::AT_HLSLVkConstantId:
8176 S.HLSL().handleVkConstantIdAttr(D, AL);
8177 break;
8178 case ParsedAttr::AT_HLSLVkBinding:
8179 S.HLSL().handleVkBindingAttr(D, AL);
8180 break;
8181 case ParsedAttr::AT_HLSLGroupSharedAddressSpace:
8183 break;
8184 case ParsedAttr::AT_HLSLPackOffset:
8185 S.HLSL().handlePackOffsetAttr(D, AL);
8186 break;
8187 case ParsedAttr::AT_HLSLShader:
8188 S.HLSL().handleShaderAttr(D, AL);
8189 break;
8190 case ParsedAttr::AT_HLSLResourceBinding:
8192 break;
8193 case ParsedAttr::AT_HLSLParamModifier:
8194 S.HLSL().handleParamModifierAttr(D, AL);
8195 break;
8196 case ParsedAttr::AT_HLSLMatrixLayout:
8197 S.HLSL().handleMatrixLayoutAttr(D, AL);
8198 break;
8199 case ParsedAttr::AT_HLSLUnparsedSemantic:
8200 S.HLSL().handleSemanticAttr(D, AL);
8201 break;
8202 case ParsedAttr::AT_HLSLVkLocation:
8203 S.HLSL().handleVkLocationAttr(D, AL);
8204 break;
8205
8206 case ParsedAttr::AT_AbiTag:
8207 handleAbiTagAttr(S, D, AL);
8208 break;
8209 case ParsedAttr::AT_CFGuard:
8210 handleCFGuardAttr(S, D, AL);
8211 break;
8212
8213 // Thread safety attributes:
8214 case ParsedAttr::AT_PtGuardedVar:
8215 handlePtGuardedVarAttr(S, D, AL);
8216 break;
8217 case ParsedAttr::AT_NoSanitize:
8218 handleNoSanitizeAttr(S, D, AL);
8219 break;
8220 case ParsedAttr::AT_NoSanitizeAddress:
8222 break;
8223 case ParsedAttr::AT_NoSanitizeThread:
8225 break;
8226 case ParsedAttr::AT_NoSanitizeMemory:
8228 break;
8229 case ParsedAttr::AT_GuardedBy:
8230 handleGuardedByAttr(S, D, AL);
8231 break;
8232 case ParsedAttr::AT_PtGuardedBy:
8233 handlePtGuardedByAttr(S, D, AL);
8234 break;
8235 case ParsedAttr::AT_LockReturned:
8236 handleLockReturnedAttr(S, D, AL);
8237 break;
8238 case ParsedAttr::AT_LocksExcluded:
8239 handleLocksExcludedAttr(S, D, AL);
8240 break;
8241 case ParsedAttr::AT_AcquiredBefore:
8242 handleAcquiredBeforeAttr(S, D, AL);
8243 break;
8244 case ParsedAttr::AT_AcquiredAfter:
8245 handleAcquiredAfterAttr(S, D, AL);
8246 break;
8247
8248 // Capability analysis attributes.
8249 case ParsedAttr::AT_Capability:
8250 case ParsedAttr::AT_Lockable:
8251 handleCapabilityAttr(S, D, AL);
8252 break;
8253 case ParsedAttr::AT_ReentrantCapability:
8255 break;
8256 case ParsedAttr::AT_RequiresCapability:
8258 break;
8259
8260 case ParsedAttr::AT_AssertCapability:
8262 break;
8263 case ParsedAttr::AT_AcquireCapability:
8265 break;
8266 case ParsedAttr::AT_ReleaseCapability:
8268 break;
8269 case ParsedAttr::AT_TryAcquireCapability:
8271 break;
8272
8273 // Consumed analysis attributes.
8274 case ParsedAttr::AT_Consumable:
8275 handleConsumableAttr(S, D, AL);
8276 break;
8277 case ParsedAttr::AT_CallableWhen:
8278 handleCallableWhenAttr(S, D, AL);
8279 break;
8280 case ParsedAttr::AT_ParamTypestate:
8281 handleParamTypestateAttr(S, D, AL);
8282 break;
8283 case ParsedAttr::AT_ReturnTypestate:
8284 handleReturnTypestateAttr(S, D, AL);
8285 break;
8286 case ParsedAttr::AT_SetTypestate:
8287 handleSetTypestateAttr(S, D, AL);
8288 break;
8289 case ParsedAttr::AT_TestTypestate:
8290 handleTestTypestateAttr(S, D, AL);
8291 break;
8292
8293 // Type safety attributes.
8294 case ParsedAttr::AT_ArgumentWithTypeTag:
8296 break;
8297 case ParsedAttr::AT_TypeTagForDatatype:
8299 break;
8300
8301 // Swift attributes.
8302 case ParsedAttr::AT_SwiftAsyncName:
8303 S.Swift().handleAsyncName(D, AL);
8304 break;
8305 case ParsedAttr::AT_SwiftAttr:
8306 S.Swift().handleAttrAttr(D, AL);
8307 break;
8308 case ParsedAttr::AT_SwiftBridge:
8309 S.Swift().handleBridge(D, AL);
8310 break;
8311 case ParsedAttr::AT_SwiftError:
8312 S.Swift().handleError(D, AL);
8313 break;
8314 case ParsedAttr::AT_SwiftName:
8315 S.Swift().handleName(D, AL);
8316 break;
8317 case ParsedAttr::AT_SwiftNewType:
8318 S.Swift().handleNewType(D, AL);
8319 break;
8320 case ParsedAttr::AT_SwiftAsync:
8321 S.Swift().handleAsyncAttr(D, AL);
8322 break;
8323 case ParsedAttr::AT_SwiftAsyncError:
8324 S.Swift().handleAsyncError(D, AL);
8325 break;
8326
8327 // XRay attributes.
8328 case ParsedAttr::AT_XRayLogArgs:
8329 handleXRayLogArgsAttr(S, D, AL);
8330 break;
8331
8332 case ParsedAttr::AT_PatchableFunctionEntry:
8334 break;
8335
8336 case ParsedAttr::AT_AlwaysDestroy:
8337 case ParsedAttr::AT_NoDestroy:
8338 handleDestroyAttr(S, D, AL);
8339 break;
8340
8341 case ParsedAttr::AT_Uninitialized:
8342 handleUninitializedAttr(S, D, AL);
8343 break;
8344
8345 case ParsedAttr::AT_ObjCExternallyRetained:
8347 break;
8348
8349 case ParsedAttr::AT_MIGServerRoutine:
8351 break;
8352
8353 case ParsedAttr::AT_MSAllocator:
8354 handleMSAllocatorAttr(S, D, AL);
8355 break;
8356
8357 case ParsedAttr::AT_ArmBuiltinAlias:
8358 S.ARM().handleBuiltinAliasAttr(D, AL);
8359 break;
8360
8361 case ParsedAttr::AT_ArmLocallyStreaming:
8363 break;
8364
8365 case ParsedAttr::AT_ArmNew:
8366 S.ARM().handleNewAttr(D, AL);
8367 break;
8368
8369 case ParsedAttr::AT_AcquireHandle:
8370 handleAcquireHandleAttr(S, D, AL);
8371 break;
8372
8373 case ParsedAttr::AT_ReleaseHandle:
8375 break;
8376
8377 case ParsedAttr::AT_UnsafeBufferUsage:
8379 break;
8380
8381 case ParsedAttr::AT_UseHandle:
8383 break;
8384
8385 case ParsedAttr::AT_EnforceTCB:
8387 break;
8388
8389 case ParsedAttr::AT_EnforceTCBLeaf:
8391 break;
8392
8393 case ParsedAttr::AT_BuiltinAlias:
8394 handleBuiltinAliasAttr(S, D, AL);
8395 break;
8396
8397 case ParsedAttr::AT_PreferredType:
8398 handlePreferredTypeAttr(S, D, AL);
8399 break;
8400
8401 case ParsedAttr::AT_UsingIfExists:
8403 break;
8404
8405 case ParsedAttr::AT_TypeNullable:
8406 handleNullableTypeAttr(S, D, AL);
8407 break;
8408
8409 case ParsedAttr::AT_VTablePointerAuthentication:
8411 break;
8412
8413 case ParsedAttr::AT_ModularFormat:
8414 handleModularFormat(S, D, AL);
8415 break;
8416
8417 case ParsedAttr::AT_MSStruct:
8418 handleMSStructAttr(S, D, AL);
8419 break;
8420
8421 case ParsedAttr::AT_GCCStruct:
8422 handleGCCStructAttr(S, D, AL);
8423 break;
8424
8425 case ParsedAttr::AT_PointerFieldProtection:
8426 if (!S.getLangOpts().PointerFieldProtectionAttr)
8427 S.Diag(AL.getLoc(),
8428 diag::err_attribute_pointer_field_protection_experimental)
8429 << AL << AL.isRegularKeywordAttribute() << D->getLocation();
8431 break;
8432 }
8433}
8434
8435static bool isKernelDecl(Decl *D) {
8436 const FunctionType *FnTy = D->getFunctionType();
8437 return D->hasAttr<DeviceKernelAttr>() ||
8438 (FnTy && FnTy->getCallConv() == CallingConv::CC_DeviceKernel) ||
8439 D->hasAttr<CUDAGlobalAttr>();
8440}
8441
8443 Scope *S, Decl *D, const ParsedAttributesView &AttrList,
8444 const ProcessDeclAttributeOptions &Options) {
8445 if (AttrList.empty())
8446 return;
8447
8448 for (const ParsedAttr &AL : AttrList)
8449 ProcessDeclAttribute(*this, S, D, AL, Options);
8450
8451 // FIXME: We should be able to handle these cases in TableGen.
8452 // GCC accepts
8453 // static int a9 __attribute__((weakref));
8454 // but that looks really pointless. We reject it.
8455 if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
8456 Diag(AttrList.begin()->getLoc(), diag::err_attribute_weakref_without_alias)
8457 << cast<NamedDecl>(D);
8458 D->dropAttr<WeakRefAttr>();
8459 return;
8460 }
8461
8462 // FIXME: We should be able to handle this in TableGen as well. It would be
8463 // good to have a way to specify "these attributes must appear as a group",
8464 // for these. Additionally, it would be good to have a way to specify "these
8465 // attribute must never appear as a group" for attributes like cold and hot.
8466 if (!(D->hasAttr<DeviceKernelAttr>() ||
8467 (D->hasAttr<CUDAGlobalAttr>() &&
8468 Context.getTargetInfo().getTriple().isSPIRV()))) {
8469 // These attributes cannot be applied to a non-kernel function.
8470 if (const auto *A = D->getAttr<ReqdWorkGroupSizeAttr>()) {
8471 // FIXME: This emits a different error message than
8472 // diag::err_attribute_wrong_decl_type + ExpectedKernelFunction.
8473 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
8474 D->setInvalidDecl();
8475 } else if (const auto *A = D->getAttr<WorkGroupSizeHintAttr>()) {
8476 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
8477 D->setInvalidDecl();
8478 } else if (const auto *A = D->getAttr<VecTypeHintAttr>()) {
8479 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
8480 D->setInvalidDecl();
8481 } else if (const auto *A = D->getAttr<OpenCLIntelReqdSubGroupSizeAttr>()) {
8482 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
8483 D->setInvalidDecl();
8484 }
8485 }
8486 if (!isKernelDecl(D)) {
8487 if (const auto *A = D->getAttr<AMDGPUFlatWorkGroupSizeAttr>()) {
8488 Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
8489 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
8490 D->setInvalidDecl();
8491 } else if (const auto *A = D->getAttr<AMDGPUWavesPerEUAttr>()) {
8492 Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
8493 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
8494 D->setInvalidDecl();
8495 } else if (const auto *A = D->getAttr<AMDGPUNumSGPRAttr>()) {
8496 Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
8497 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
8498 D->setInvalidDecl();
8499 } else if (const auto *A = D->getAttr<AMDGPUNumVGPRAttr>()) {
8500 Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
8501 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
8502 D->setInvalidDecl();
8503 }
8504 }
8505
8506 // CUDA/HIP: restrict explicit CUDA target attributes on deduction guides.
8507 //
8508 // Deduction guides are not callable functions and never participate in
8509 // codegen; they are always treated as host+device for CUDA/HIP semantic
8510 // checks. We therefore allow either no CUDA target attributes or an explicit
8511 // '__host__ __device__' annotation, but reject guides that are host-only,
8512 // device-only, or marked '__global__'. The use of explicit CUDA/HIP target
8513 // attributes on deduction guides is deprecated and will be rejected in a
8514 // future Clang version.
8515 if (getLangOpts().CUDA)
8516 if (auto *Guide = dyn_cast<CXXDeductionGuideDecl>(D)) {
8517 bool HasHost = Guide->hasAttr<CUDAHostAttr>();
8518 bool HasDevice = Guide->hasAttr<CUDADeviceAttr>();
8519 bool HasGlobal = Guide->hasAttr<CUDAGlobalAttr>();
8520
8521 if (HasGlobal || HasHost != HasDevice) {
8522 Diag(Guide->getLocation(), diag::err_deduction_guide_target_attr);
8523 Guide->setInvalidDecl();
8524 } else if (HasHost && HasDevice) {
8525 Diag(Guide->getLocation(),
8526 diag::warn_deduction_guide_target_attr_deprecated);
8527 }
8528 }
8529
8530 // Do not permit 'constructor' or 'destructor' attributes on __device__ code.
8531 if (getLangOpts().CUDAIsDevice && D->hasAttr<CUDADeviceAttr>() &&
8532 (D->hasAttr<ConstructorAttr>() || D->hasAttr<DestructorAttr>()) &&
8533 !getLangOpts().GPUAllowDeviceInit) {
8534 Diag(D->getLocation(), diag::err_cuda_ctor_dtor_attrs)
8535 << (D->hasAttr<ConstructorAttr>() ? "constructors" : "destructors");
8536 D->setInvalidDecl();
8537 }
8538
8539 // Do this check after processing D's attributes because the attribute
8540 // objc_method_family can change whether the given method is in the init
8541 // family, and it can be applied after objc_designated_initializer. This is a
8542 // bit of a hack, but we need it to be compatible with versions of clang that
8543 // processed the attribute list in the wrong order.
8544 if (D->hasAttr<ObjCDesignatedInitializerAttr>() &&
8545 cast<ObjCMethodDecl>(D)->getMethodFamily() != OMF_init) {
8546 Diag(D->getLocation(), diag::err_designated_init_attr_non_init);
8547 D->dropAttr<ObjCDesignatedInitializerAttr>();
8548 }
8549}
8550
8552 const ParsedAttributesView &AttrList) {
8553 for (const ParsedAttr &AL : AttrList)
8554 if (AL.getKind() == ParsedAttr::AT_TransparentUnion) {
8555 handleTransparentUnionAttr(*this, D, AL);
8556 break;
8557 }
8558
8559 // For BPFPreserveAccessIndexAttr, we want to populate the attributes
8560 // to fields and inner records as well.
8561 if (D && D->hasAttr<BPFPreserveAccessIndexAttr>())
8563}
8564
8566 AccessSpecDecl *ASDecl, const ParsedAttributesView &AttrList) {
8567 for (const ParsedAttr &AL : AttrList) {
8568 if (AL.getKind() == ParsedAttr::AT_Annotate) {
8569 ProcessDeclAttribute(*this, nullptr, ASDecl, AL,
8571 } else {
8572 Diag(AL.getLoc(), diag::err_only_annotate_after_access_spec);
8573 return true;
8574 }
8575 }
8576 return false;
8577}
8578
8579/// checkUnusedDeclAttributes - Check a list of attributes to see if it
8580/// contains any decl attributes that we should warn about.
8582 for (const ParsedAttr &AL : A) {
8583 // Only warn if the attribute is an unignored, non-type attribute.
8584 if (AL.isUsedAsTypeAttr() || AL.isInvalid())
8585 continue;
8586 if (AL.getKind() == ParsedAttr::IgnoredAttribute)
8587 continue;
8588
8589 if (AL.getKind() == ParsedAttr::UnknownAttribute) {
8591 } else {
8592 S.Diag(AL.getLoc(), diag::warn_attribute_not_on_decl) << AL
8593 << AL.getRange();
8594 }
8595 }
8596}
8597
8605
8608 StringRef ScopeName = AL.getNormalizedScopeName();
8609 std::optional<StringRef> CorrectedScopeName =
8610 AL.tryGetCorrectedScopeName(ScopeName);
8611 if (CorrectedScopeName) {
8612 ScopeName = *CorrectedScopeName;
8613 }
8614
8615 StringRef AttrName = AL.getNormalizedAttrName(ScopeName);
8616 std::optional<StringRef> CorrectedAttrName = AL.tryGetCorrectedAttrName(
8617 ScopeName, AttrName, Context.getTargetInfo(), getLangOpts());
8618 if (CorrectedAttrName) {
8619 AttrName = *CorrectedAttrName;
8620 }
8621
8622 if (CorrectedScopeName || CorrectedAttrName) {
8623 std::string CorrectedFullName =
8624 AL.getNormalizedFullName(ScopeName, AttrName);
8626 Diag(CorrectedScopeName ? NR.getBegin() : AL.getRange().getBegin(),
8627 diag::warn_unknown_attribute_ignored_suggestion);
8628
8629 D << AL << CorrectedFullName;
8630
8631 if (AL.isExplicitScope()) {
8632 D << FixItHint::CreateReplacement(NR, CorrectedFullName) << NR;
8633 } else {
8634 if (CorrectedScopeName) {
8636 ScopeName);
8637 }
8638 if (CorrectedAttrName) {
8639 D << FixItHint::CreateReplacement(AL.getRange(), AttrName);
8640 }
8641 }
8642 } else {
8643 Diag(NR.getBegin(), diag::warn_unknown_attribute_ignored) << AL << NR;
8644 }
8645}
8646
8648 SourceLocation Loc) {
8649 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
8650 NamedDecl *NewD = nullptr;
8651 if (auto *FD = dyn_cast<FunctionDecl>(ND)) {
8652 FunctionDecl *NewFD;
8653 // FIXME: Missing call to CheckFunctionDeclaration().
8654 // FIXME: Mangling?
8655 // FIXME: Is the qualifier info correct?
8656 // FIXME: Is the DeclContext correct?
8657 NewFD = FunctionDecl::Create(
8658 FD->getASTContext(), FD->getDeclContext(), Loc, Loc,
8660 getCurFPFeatures().isFPConstrained(), false /*isInlineSpecified*/,
8663 NewD = NewFD;
8664
8665 if (FD->getQualifier())
8666 NewFD->setQualifierInfo(FD->getQualifierLoc());
8667
8668 // Fake up parameter variables; they are declared as if this were
8669 // a typedef.
8670 QualType FDTy = FD->getType();
8671 if (const auto *FT = FDTy->getAs<FunctionProtoType>()) {
8673 for (const auto &AI : FT->param_types()) {
8674 ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, AI);
8675 Param->setScopeInfo(0, Params.size());
8676 Params.push_back(Param);
8677 }
8678 NewFD->setParams(Params);
8679 }
8680 } else if (auto *VD = dyn_cast<VarDecl>(ND)) {
8681 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
8682 VD->getInnerLocStart(), VD->getLocation(), II,
8683 VD->getType(), VD->getTypeSourceInfo(),
8684 VD->getStorageClass());
8685 if (VD->getQualifier())
8686 cast<VarDecl>(NewD)->setQualifierInfo(VD->getQualifierLoc());
8687 }
8688 return NewD;
8689}
8690
8692 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
8693 IdentifierInfo *NDId = ND->getIdentifier();
8694 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
8695 NewD->addAttr(
8696 AliasAttr::CreateImplicit(Context, NDId->getName(), W.getLocation()));
8697 NewD->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));
8698 WeakTopLevelDecl.push_back(NewD);
8699 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
8700 // to insert Decl at TU scope, sorry.
8701 DeclContext *SavedContext = CurContext;
8702 CurContext = Context.getTranslationUnitDecl();
8705 PushOnScopeChains(NewD, S);
8706 CurContext = SavedContext;
8707 } else { // just add weak to existing
8708 ND->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));
8709 }
8710}
8711
8713 // It's valid to "forward-declare" #pragma weak, in which case we
8714 // have to do this.
8716 if (WeakUndeclaredIdentifiers.empty())
8717 return;
8718 NamedDecl *ND = nullptr;
8719 if (auto *VD = dyn_cast<VarDecl>(D))
8720 if (VD->isExternC())
8721 ND = VD;
8722 if (auto *FD = dyn_cast<FunctionDecl>(D))
8723 if (FD->isExternC())
8724 ND = FD;
8725 if (!ND)
8726 return;
8727 if (IdentifierInfo *Id = ND->getIdentifier()) {
8728 auto I = WeakUndeclaredIdentifiers.find(Id);
8729 if (I != WeakUndeclaredIdentifiers.end()) {
8730 auto &WeakInfos = I->second;
8731 for (const auto &W : WeakInfos)
8732 DeclApplyPragmaWeak(S, ND, W);
8733 std::remove_reference_t<decltype(WeakInfos)> EmptyWeakInfos;
8734 WeakInfos.swap(EmptyWeakInfos);
8735 }
8736 }
8737}
8738
8739/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
8740/// it, apply them to D. This is a bit tricky because PD can have attributes
8741/// specified in many different places, and we need to find and apply them all.
8743 // Ordering of attributes can be important, so we take care to process
8744 // attributes in the order in which they appeared in the source code.
8745
8746 auto ProcessAttributesWithSliding =
8747 [&](const ParsedAttributesView &Src,
8748 const ProcessDeclAttributeOptions &Options) {
8749 ParsedAttributesView NonSlidingAttrs;
8750 for (ParsedAttr &AL : Src) {
8751 // FIXME: this sliding is specific to standard attributes and should
8752 // eventually be deprecated and removed as those are not intended to
8753 // slide to anything.
8754 if ((AL.isStandardAttributeSyntax() || AL.isAlignas()) &&
8755 AL.slidesFromDeclToDeclSpecLegacyBehavior()) {
8756 // Skip processing the attribute, but do check if it appertains to
8757 // the declaration. This is needed for the `MatrixType` attribute,
8758 // which, despite being a type attribute, defines a `SubjectList`
8759 // that only allows it to be used on typedef declarations.
8760 AL.diagnoseAppertainsTo(*this, D);
8761 } else {
8762 NonSlidingAttrs.addAtEnd(&AL);
8763 }
8764 }
8765 ProcessDeclAttributeList(S, D, NonSlidingAttrs, Options);
8766 };
8767
8768 // First, process attributes that appeared on the declaration itself (but
8769 // only if they don't have the legacy behavior of "sliding" to the DeclSepc).
8770 ProcessAttributesWithSliding(PD.getDeclarationAttributes(), {});
8771
8772 // Apply decl attributes from the DeclSpec if present.
8773 ProcessAttributesWithSliding(PD.getDeclSpec().getAttributes(),
8775 .WithIncludeCXX11Attributes(false)
8776 .WithIgnoreTypeAttributes(true));
8777
8778 // Walk the declarator structure, applying decl attributes that were in a type
8779 // position to the decl itself. This handles cases like:
8780 // int *__attr__(x)** D;
8781 // when X is a decl attribute.
8782 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) {
8785 .WithIncludeCXX11Attributes(false)
8786 .WithIgnoreTypeAttributes(true));
8787 }
8788
8789 // Finally, apply any attributes on the decl itself.
8791
8792 // Apply additional attributes specified by '#pragma clang attribute'.
8793 AddPragmaAttributes(S, D);
8794
8795 // Look for API notes that map to attributes.
8796 ProcessAPINotes(D);
8797}
8798
8799/// Is the given declaration allowed to use a forbidden type?
8800/// If so, it'll still be annotated with an attribute that makes it
8801/// illegal to actually use.
8803 const DelayedDiagnostic &diag,
8804 UnavailableAttr::ImplicitReason &reason) {
8805 // Private ivars are always okay. Unfortunately, people don't
8806 // always properly make their ivars private, even in system headers.
8807 // Plus we need to make fields okay, too.
8808 if (!isa<FieldDecl>(D) && !isa<ObjCPropertyDecl>(D) &&
8810 return false;
8811
8812 // Silently accept unsupported uses of __weak in both user and system
8813 // declarations when it's been disabled, for ease of integration with
8814 // -fno-objc-arc files. We do have to take some care against attempts
8815 // to define such things; for now, we've only done that for ivars
8816 // and properties.
8818 if (diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_disabled ||
8819 diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_no_runtime) {
8820 reason = UnavailableAttr::IR_ForbiddenWeak;
8821 return true;
8822 }
8823 }
8824
8825 // Allow all sorts of things in system headers.
8827 // Currently, all the failures dealt with this way are due to ARC
8828 // restrictions.
8829 reason = UnavailableAttr::IR_ARCForbiddenType;
8830 return true;
8831 }
8832
8833 return false;
8834}
8835
8836/// Handle a delayed forbidden-type diagnostic.
8838 Decl *D) {
8839 auto Reason = UnavailableAttr::IR_None;
8840 if (D && isForbiddenTypeAllowed(S, D, DD, Reason)) {
8841 assert(Reason && "didn't set reason?");
8842 D->addAttr(UnavailableAttr::CreateImplicit(S.Context, "", Reason, DD.Loc));
8843 return;
8844 }
8845 if (S.getLangOpts().ObjCAutoRefCount)
8846 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
8847 // FIXME: we may want to suppress diagnostics for all
8848 // kind of forbidden type messages on unavailable functions.
8849 if (FD->hasAttr<UnavailableAttr>() &&
8851 diag::err_arc_array_param_no_ownership) {
8852 DD.Triggered = true;
8853 return;
8854 }
8855 }
8856
8859 DD.Triggered = true;
8860}
8861
8862
8867
8868 // When delaying diagnostics to run in the context of a parsed
8869 // declaration, we only want to actually emit anything if parsing
8870 // succeeds.
8871 if (!decl) return;
8872
8873 // We emit all the active diagnostics in this pool or any of its
8874 // parents. In general, we'll get one pool for the decl spec
8875 // and a child pool for each declarator; in a decl group like:
8876 // deprecated_typedef foo, *bar, baz();
8877 // only the declarator pops will be passed decls. This is correct;
8878 // we really do need to consider delayed diagnostics from the decl spec
8879 // for each of the different declarations.
8880 const DelayedDiagnosticPool *pool = &poppedPool;
8881 do {
8882 bool AnyAccessFailures = false;
8884 i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) {
8885 // This const_cast is a bit lame. Really, Triggered should be mutable.
8886 DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i);
8887 if (diag.Triggered)
8888 continue;
8889
8890 switch (diag.Kind) {
8892 // Don't bother giving deprecation/unavailable diagnostics if
8893 // the decl is invalid.
8894 if (!decl->isInvalidDecl())
8896 break;
8897
8899 // Only produce one access control diagnostic for a structured binding
8900 // declaration: we don't need to tell the user that all the fields are
8901 // inaccessible one at a time.
8902 if (AnyAccessFailures && isa<DecompositionDecl>(decl))
8903 continue;
8905 if (diag.Triggered)
8906 AnyAccessFailures = true;
8907 break;
8908
8911 break;
8912 }
8913 }
8914 } while ((pool = pool->getParent()));
8915}
8916
8919 assert(curPool && "re-emitting in undelayed context not supported");
8920 curPool->steal(pool);
8921}
8922
8924 VarDecl *VD = cast<VarDecl>(D);
8925 if (VD->getType()->isDependentType())
8926 return;
8927
8928 // Obtains the FunctionDecl that was found when handling the attribute
8929 // earlier.
8930 CleanupAttr *Attr = D->getAttr<CleanupAttr>();
8931 FunctionDecl *FD = Attr->getFunctionDecl();
8932 DeclarationNameInfo NI = FD->getNameInfo();
8933
8934 // We're currently more strict than GCC about what function types we accept.
8935 // If this ever proves to be a problem it should be easy to fix.
8936 QualType Ty = this->Context.getPointerType(VD->getType());
8937 QualType ParamTy = FD->getParamDecl(0)->getType();
8938 if (QualType ConvertedTy;
8940 FD->getParamDecl(0)->getLocation(), ParamTy, Ty)) &&
8941 !ObjC().isObjCWritebackConversion(Ty, ParamTy, ConvertedTy)) {
8942 this->Diag(Attr->getArgLoc(),
8943 diag::err_attribute_cleanup_func_arg_incompatible_type)
8944 << NI.getName() << ParamTy << Ty;
8945 D->dropAttr<CleanupAttr>();
8946 return;
8947 }
8948}
8949
8951 QualType T = cast<VarDecl>(D)->getType();
8952 if (this->Context.getAsArrayType(T))
8953 T = this->Context.getBaseElementType(T);
8954 if (!T->isRecordType()) {
8955 this->Diag(A->getLoc(), diag::err_init_priority_object_attr);
8956 D->dropAttr<InitPriorityAttr>();
8957 }
8958}
Defines the clang::ASTContext interface.
#define V(N, I)
static SmallString< 64 > normalizeName(StringRef AttrName, StringRef ScopeName, AttributeCommonInfo::Syntax SyntaxUsed)
static OffloadArch getOffloadArch(const CodeGenModule &CGM)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines the classes used to store parsed information about declaration-specifiers and decla...
Defines the C++ template declaration subclasses.
Defines the classes clang::DelayedDiagnostic and clang::AccessedEntity.
Defines the clang::Expr interface and subclasses for C++ expressions.
TokenType getType() const
Returns the token's type, e.g.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Result
Implement __builtin_bit_cast and related operations.
#define X(type, name)
Definition Value.h:97
Defines the clang::LangOptions interface.
llvm::MachO::Target Target
Definition MachO.h:51
llvm::MachO::Record Record
Definition MachO.h:31
#define SM(sm)
static unsigned getNumAttributeArgs(const ParsedAttr &AL)
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file declares semantic analysis functions specific to AMDGPU.
This file declares semantic analysis functions specific to ARM.
This file declares semantic analysis functions specific to AVR.
This file declares semantic analysis functions specific to BPF.
This file declares semantic analysis for CUDA constructs.
static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleWeakImportAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleCodeSegAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static const RecordDecl * getRecordDecl(QualType QT)
Checks that the passed in QualType either is of RecordType or points to RecordType.
static void handlePatchableFunctionEntryAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleCountedByAttrField(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkThreadSafetyValueDeclIsFunPtr(Sema &S, const ValueDecl *VD, const AttributeCommonInfo &A)
Checks that thread-safety attributes on variables or fields apply only to function pointer types.
static void handleFormatAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleUninitializedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleRequiresCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleDeviceKernelAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleBTFDeclTagAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleOptimizeNoneAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleEnableIfAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleStandardNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &A)
static void handleMIGServerRoutineAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleZeroCallUsedRegsAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleDiagnoseAsBuiltinAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleEnumExtensibilityAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static T * mergeVisibilityAttr(Sema &S, Decl *D, const AttributeCommonInfo &CI, typename T::VisibilityType value)
static void handleFormatMatchesAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleLayoutVersion(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD, const ParsedAttr &AL)
static void handleDLLAttr(Sema &S, Decl *D, const ParsedAttr &A)
static void handleConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool modularFormatAttrsEquiv(const ModularFormatAttr *Existing, const IdentifierInfo *ModularImplFn, StringRef ImplName, ArrayRef< StringRef > Aspects)
static void handleAlignValueAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static Expr * makeAttributeArgExpr(Sema &S, Expr *E, const Attribute &Attr, const unsigned Idx)
static void handleLifetimeCaptureByAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkGuardedByAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL, SmallVectorImpl< Expr * > &Args)
static void handleNoCfCheckAttr(Sema &S, Decl *D, const ParsedAttr &Attrs)
static void handleMallocSpanAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleNoSpecializations(Sema &S, Decl *D, const ParsedAttr &AL)
static bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordDecl *Record)
static void handleReturnsNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void checkUnusedDeclAttributes(Sema &S, const ParsedAttributesView &A)
checkUnusedDeclAttributes - Check a list of attributes to see if it contains any decl attributes that...
static void handleGNUInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleBuiltinAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleVTablePointerAuthentication(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleNoPFPAttrField(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleEnforceTCBAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D, const ParsedAttr &AL, SmallVectorImpl< Expr * > &Args, unsigned Sidx=0, bool ParamIdxOk=false)
Checks that all attribute arguments, starting from Sidx, resolve to a capability object.
static void handleErrorAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkCodeSegName(Sema &S, SourceLocation LiteralLoc, StringRef CodeSegName)
static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleTryAcquireCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleModularFormat(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleGridConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleSetTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleFormatArgAttr(Sema &S, Decl *D, const ParsedAttr &AL)
Handle attribute((format_arg((idx)))) attribute based on https://gcc.gnu.org/onlinedocs/gcc/Common-Fu...
static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, const Sema::ProcessDeclAttributeOptions &Options)
ProcessDeclAttribute - Apply the specific attribute to the specified decl if the attribute applies to...
static void handleTargetAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handlePassObjectSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleNoMergeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleManagedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleMSStructAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleNonStringAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleParamTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleUnsafeBufferUsage(Sema &S, Decl *D, const ParsedAttr &AL)
static bool attrNonNullArgCheck(Sema &S, QualType T, const ParsedAttr &AL, SourceRange AttrParmRange, SourceRange TypeRange, bool isReturnValue=false)
static void handleAcquireCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleCPUSpecificAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handlePackedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleIFuncAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAbiTagAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAttrWithMessage(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleWeakRefAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleExtVectorTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool isValidCodeModelAttr(llvm::Triple &Triple, StringRef Str)
static void handleCalledOnceAttr(Sema &S, Decl *D, const ParsedAttr &AL)
Handle 'called_once' attribute.
static void handleLockReturnedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkFunctionConditionAttr(Sema &S, Decl *D, const ParsedAttr &AL, Expr *&Cond, StringRef &Msg)
static void handleAcquiredAfterAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleExternalSourceSymbolAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleNonNullAttrParameter(Sema &S, ParmVarDecl *D, const ParsedAttr &AL)
static bool checkParamIsIntegerType(Sema &S, const Decl *D, const AttrInfo &AI, unsigned AttrArgNo)
Checks to be sure that the given parameter number is in bounds, and is an integral type.
static bool checkRecordTypeForCapability(Sema &S, QualType Ty)
static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL, SmallVectorImpl< Expr * > &Args)
static void handleLocksExcludedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleMSAllocatorAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static AttrTy * mergeEnforceTCBAttrImpl(Sema &S, Decl *D, const AttrTy &AL)
static void handleConstructorAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAllocSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleConsumableAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleNoSanitizeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleReturnTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleTargetClonesAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool isKernelDecl(Decl *D)
static void handleAllocAlignAttr(Sema &S, Decl *D, const ParsedAttr &AL)
FormatAttrKind
@ CFStringFormat
@ IgnoredFormat
@ InvalidFormat
@ StrftimeFormat
@ SupportedFormat
@ NSStringFormat
static void handlePreferredTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleDeviceAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handlePtGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handlePersonalityAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAlwaysInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAssertCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleVisibilityAttr(Sema &S, Decl *D, const ParsedAttr &AL, bool isTypeVisibility)
static void handleAnnotateAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static FormatAttrKind getFormatAttrKind(StringRef Format)
getFormatAttrKind - Map from format attribute names to supported format types.
static void handleNullableTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleUuidAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAcquireHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleNoSanitizeAddressAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleMSConstexprAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleCommonAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleTestTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool shouldInferAvailabilityAttribute(const ParsedAttr &AL, IdentifierInfo *&II, bool &IsUnavailable, VersionTuple &Introduced, VersionTuple &Deprecated, VersionTuple &Obsolete, Sema &S)
Returns true if the given availability attribute should be inferred, and adjusts the value of the att...
static bool checkTryLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL, SmallVectorImpl< Expr * > &Args)
static void parseModeAttrArg(Sema &S, StringRef Str, unsigned &DestWidth, bool &IntegerMode, bool &ComplexMode, FloatModeKind &ExplicitType)
parseModeAttrArg - Parses attribute mode string and returns parsed type attribute.
static void handleExcludeFromExplicitInstantiationAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleCFIUncheckedCalleeAttr(Sema &S, Decl *D, const ParsedAttr &Attrs)
static void handleLaunchBoundsAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D, const ParsedAttr &AL)
static bool checkThreadSafetyAttrSubject(Sema &S, Decl *D, const ParsedAttr &AL, bool CheckParmVar=false)
static void handleNoBuiltinAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleGCCStructAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleLifetimeCategoryAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleNoUniqueAddressAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool validateAlignasAppliedType(Sema &S, Decl *D, const AlignedAttr &Attr, SourceLocation AttrLoc)
Perform checking of type validity.
static void handleNakedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleFunctionReturnThunksAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleDeprecatedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static unsigned getNumAttributeArgs(const ParsedAttr &AL)
static void handleGlobalAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleSentinelAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleCodeModelAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleCallableWhenAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool hasBTFDeclTagAttr(Decl *D, StringRef Tag)
static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &DD, Decl *D)
Handle a delayed forbidden-type diagnostic.
static void handleNoClusterAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL, SmallVectorImpl< Expr * > &Args)
static void handleAssumeAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleSharedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleMSInheritanceAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleVecTypeHint(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleRestrictAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleMinVectorWidthAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleUnusedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static Expr * makeLaunchBoundsArgExpr(Sema &S, Expr *E, const CUDALaunchBoundsAttr &AL, const unsigned Idx)
static bool checkFunParamsAreScopedLockable(Sema &S, const ParmVarDecl *ParamDecl, const AttributeCommonInfo &AL)
static void handleDeclspecThreadAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL)
Handle attribute((callback(CalleeIdx, PayloadIdx0, ...))) attributes.
static AttributeCommonInfo getNoSanitizeAttrInfo(const ParsedAttr &NoSanitizeSpecificAttr)
static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL)
Handle attribute((init_priority(priority))) attributes based on http://gcc.gnu.org/onlinedocs/gcc/C_0...
static void handlePtGuardedVarAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkRecordDeclForAttr(const RecordDecl *RD)
static void handleNoSanitizeThreadAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleDestroyAttr(Sema &S, Decl *D, const ParsedAttr &A)
static bool isKnownToAlwaysThrow(const FunctionDecl *FD)
static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleRandomizeLayoutAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void markUsedForAliasOrIfunc(Sema &S, Decl *D, const ParsedAttr &AL, StringRef Str)
static bool isCapabilityExpr(Sema &S, const Expr *Ex)
static void handleNoDebugAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleSuppressAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &Attrs)
static std::pair< Expr *, int > makeClusterDimsArgExpr(Sema &S, Expr *E, const CUDAClusterDimsAttr &AL, const unsigned Idx)
static void handleNoSanitizeMemoryAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static const AttrTy * findEnforceTCBAttrByName(Decl *D, StringRef Name)
static void handleNoEscapeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAvailableOnlyInDefaultEvalMethod(Sema &S, Decl *D, const ParsedAttr &AL)
static bool MustDelayAttributeArguments(const ParsedAttr &AL)
static void handleNoRandomizeLayoutAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleTargetVersionAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleWarnUnusedResult(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkRecordTypeForScopedCapability(Sema &S, QualType Ty)
static bool isIntOrBool(Expr *Exp)
Check if the passed-in expression is of type int or bool.
static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y, bool BeforeIsOkay)
Check whether the two versions match.
static bool isSanitizerAttributeAllowedOnGlobals(StringRef Sanitizer)
static void handleClusterDimsAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool handleFormatAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL, FormatAttrCommon *Info)
Handle attribute((format(type,idx,firstarg))) attributes based on https://gcc.gnu....
static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleMinSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static ExprResult sharedGetConstructorDestructorAttrExpr(Sema &S, const ParsedAttr &AL)
static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkTypedefTypeForCapability(QualType Ty)
static void handleAcquiredBeforeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleReleaseCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool typeHasCapability(Sema &S, QualType Ty)
static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool isFunctionPointerOrDependent(QualType T)
True if T (or its pointee, after stripping a top-level reference) is a function pointer or dependent.
static bool isFunctionLike(const Type &T)
static void handleDiagnoseIfAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleCFGuardAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleReentrantCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D, const ParsedAttr &AL)
Check if passed in Decl is a pointer type.
static bool isForbiddenTypeAllowed(Sema &S, Decl *D, const DelayedDiagnostic &diag, UnavailableAttr::ImplicitReason &reason)
Is the given declaration allowed to use a forbidden type?
static void handleInternalLinkageAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleModeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
handleModeAttr - This attribute modifies the width of a decl with primitive type.
static bool checkAvailabilityAttr(Sema &S, SourceRange Range, const IdentifierInfo *Platform, VersionTuple Introduced, VersionTuple Deprecated, VersionTuple Obsoleted)
static void handleDestructorAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handlePreferredName(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkPositiveIntArgument(Sema &S, const AttrInfo &AI, const Expr *Expr, int &Val, unsigned Idx=UINT_MAX)
Wrapper around checkUInt32Argument, with an extra check to be sure that the result will fit into a re...
static void handleVecReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool isGlobalVar(const Decl *D)
static void handleTLSModelAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL)
This file declares semantic analysis for HLSL constructs.
This file declares semantic analysis functions specific to M68k.
This file declares semantic analysis functions specific to MIPS.
This file declares semantic analysis functions specific to MSP430.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis routines for OpenCL.
This file declares semantic analysis for OpenMP constructs and clauses.
This file declares semantic analysis functions specific to PowerPC.
This file declares semantic analysis functions specific to RISC-V.
This file declares semantic analysis for SYCL constructs.
This file declares semantic analysis functions specific to Swift.
This file declares semantic analysis functions specific to Wasm.
This file declares semantic analysis functions specific to X86.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
static QualType getPointeeType(const MemRegion *R)
C Language Family Type Representation.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition APValue.h:122
virtual void AssignInheritanceModel(CXXRecordDecl *RD)
Callback invoked when an MSInheritanceAttr has been attached to a CXXRecordDecl.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:229
MSGuidDecl * getMSGuidDecl(MSGuidDeclParts Parts) const
Return a declaration for the global GUID object representing the given GUID value.
SourceManager & getSourceManager()
Definition ASTContext.h:868
TypedefDecl * getObjCInstanceTypeDecl()
Retrieve the typedef declaration corresponding to the Objective-C "instancetype" type.
DeclarationNameTable DeclarationNames
Definition ASTContext.h:811
MangleContext * createMangleContext(const TargetInfo *T=nullptr)
If T is null pointer, assume the target in ASTContext.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
IdentifierTable & Idents
Definition ASTContext.h:807
const LangOptions & getLangOpts() const
Definition ASTContext.h:961
QualType getConstType(QualType T) const
Return the uniqued reference to the type for a const qualified type.
const TargetInfo * getAuxTargetInfo() const
Definition ASTContext.h:927
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
CanQualType IntTy
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
CanQualType OverloadTy
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CanQualType VoidTy
QualType getTypedefType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypedefNameDecl *Decl, QualType UnderlyingType=QualType(), std::optional< bool > TypeMatchesDeclOrNone=std::nullopt) const
Return the unique reference to the type for the specified typedef-name decl.
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
const TargetInfo & getTargetInfo() const
Definition ASTContext.h:926
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
unsigned getTypeAlign(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in bits.
Represents an access specifier followed by colon ':'.
Definition DeclCXX.h:86
PtrTy get() const
Definition Ownership.h:171
bool isInvalid() const
Definition Ownership.h:167
Attr - This represents one attribute.
Definition Attr.h:46
bool isInherited() const
Definition Attr.h:101
SourceLocation getScopeLoc() const
void setAttributeSpellingListIndex(unsigned V)
std::string getNormalizedFullName() const
Gets the normalized full name, which consists of both scope and name and with surrounding underscores...
unsigned getAttributeSpellingListIndex() const
const IdentifierInfo * getScopeName() const
StringRef getNormalizedAttrName(StringRef ScopeName) const
std::optional< StringRef > tryGetCorrectedAttrName(StringRef ScopeName, StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts) const
SourceRange getNormalizedRange() const
std::optional< StringRef > tryGetCorrectedScopeName(StringRef ScopeName) const
SourceLocation getLoc() const
const IdentifierInfo * getAttrName() const
StringRef getNormalizedScopeName() const
bool isStandardAttributeSyntax() const
The attribute is spelled [[]] in either C or C++ mode, including standard attributes spelled with a k...
Type source information for an attributed type.
Definition TypeLoc.h:1008
TypeLoc getModifiedLoc() const
The modified type, which is generally canonically different from the attribute type.
Definition TypeLoc.h:1022
static bool validateAnyAppleOSVersion(const llvm::VersionTuple &Version)
Returns true if the anyAppleOS version is valid (empty or >= 26.0).
Pointer to a block type.
Definition TypeBase.h:3604
This class is used for builtin types like 'int'.
Definition TypeBase.h:3226
static bool isBuiltinFunc(llvm::StringRef Name)
Returns true if this is a libc/libm function without the '__builtin_' prefix.
Definition Builtins.cpp:123
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2132
QualType getFunctionObjectParameterType() const
Definition DeclCXX.h:2295
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
CXXRecordDecl * getDefinition() const
Definition DeclCXX.h:548
bool hasDefinition() const
Definition DeclCXX.h:561
MSInheritanceModel calculateInheritanceModel() const
Calculate what the inheritance model would be for this class.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2946
static CallExpr * Create(const ASTContext &Ctx, Expr *Fn, ArrayRef< Expr * > Args, QualType Ty, ExprValueKind VK, SourceLocation RParenLoc, FPOptionsOverride FPFeatures, unsigned MinNumArgs=0, ADLCallKind UsesADL=NotADL)
Create a call expression.
Definition Expr.cpp:1522
CharUnits - This is an opaque type for sizes expressed in character units.
Definition CharUnits.h:38
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition CharUnits.h:185
Declaration of a class template.
static ConstantExpr * Create(const ASTContext &Context, Expr *E, const APValue &Result)
Definition Expr.cpp:355
The information about the darwin SDK that was used during this compilation.
const RelatedTargetVersionMapping * getVersionMapping(OSEnvPair Kind) const
The results of name lookup within a DeclContext.
Definition DeclBase.h:1395
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1462
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2122
bool isFileContext() const
Definition DeclBase.h:2193
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
A reference to a declared variable, function, enum, etc.
Definition Expr.h:1273
DeclarationNameInfo getNameInfo() const
Definition Expr.h:1345
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
Definition Expr.cpp:493
bool hasQualifier() const
Determine whether this declaration reference was preceded by a C++ nested-name-specifier,...
Definition Expr.h:1362
ValueDecl * getDecl()
Definition Expr.h:1341
ParsedAttributes & getAttributes()
Definition DeclSpec.h:880
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
TemplateDecl * getDescribedTemplate() const
If this is a declaration that describes some template, this method returns that template declaration.
Definition DeclBase.cpp:285
T * getAttr() const
Definition DeclBase.h:581
bool hasAttrs() const
Definition DeclBase.h:526
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:547
void addAttr(Attr *A)
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Definition DeclBase.cpp:178
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Definition DeclBase.cpp:273
bool canBeWeakImported(bool &IsDefinition) const
Determines whether this symbol can be weak-imported, e.g., whether it would be well-formed to add the...
Definition DeclBase.cpp:844
void dropAttrs()
bool isInvalidDecl() const
Definition DeclBase.h:596
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
Definition DeclBase.h:567
SourceLocation getLocation() const
Definition DeclBase.h:447
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Definition DeclBase.h:1062
DeclContext * getDeclContext()
Definition DeclBase.h:456
SourceLocation getBeginLoc() const LLVM_READONLY
Definition DeclBase.h:439
void dropAttr()
Definition DeclBase.h:564
AttrVec & getAttrs()
Definition DeclBase.h:532
void setDeclContext(DeclContext *DC)
setDeclContext - Set both the semantic and lexical DeclContext to DC.
Definition DeclBase.cpp:382
bool hasAttr() const
Definition DeclBase.h:585
void setLexicalDeclContext(DeclContext *DC)
Definition DeclBase.cpp:386
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition DeclBase.h:991
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition DeclBase.h:435
DeclarationName getCXXOperatorName(OverloadedOperatorKind Op)
Get the name of the overloadable C++ operator corresponding to Op.
The name of a declaration.
SourceLocation getTypeSpecStartLoc() const
Definition Decl.cpp:2003
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:831
const AssociatedConstraint & getTrailingRequiresClause() const
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
Definition Decl.h:855
void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc)
Definition Decl.cpp:2015
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
Definition Decl.h:845
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...
Definition Decl.h:837
TypeSourceInfo * getTypeSourceInfo() const
Definition Decl.h:809
Information about one declarator, including the parsed type information and the identifier.
Definition DeclSpec.h:1948
const DeclaratorChunk & getTypeObject(unsigned i) const
Return the specified TypeInfo from this declarator.
Definition DeclSpec.h:2446
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
Definition DeclSpec.h:2095
const ParsedAttributes & getAttributes() const
Definition DeclSpec.h:2731
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
Definition DeclSpec.h:2442
const ParsedAttributesView & getDeclarationAttributes() const
Definition DeclSpec.h:2734
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:233
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Definition Diagnostic.h:960
const IntrusiveRefCntPtr< DiagnosticIDs > & getDiagnosticIDs() const
Definition Diagnostic.h:598
This represents one expression.
Definition Expr.h:112
bool isIntegerConstantExpr(const ASTContext &Ctx) const
static bool isPotentialConstantExprUnevaluated(Expr *E, const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExprUnevaluated - Return true if this expression might be usable in a constant exp...
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Definition Expr.cpp:3102
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition Expr.h:177
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition Expr.h:194
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
Definition Expr.h:241
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition Expr.cpp:3097
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
Definition Expr.h:223
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition Expr.cpp:282
QualType getType() const
Definition Expr.h:144
Represents difference between two FPOptions values.
Represents a member of a struct/union/class.
Definition Decl.h:3182
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
Definition Diagnostic.h:80
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
Definition Diagnostic.h:141
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:104
Represents a function declaration or definition.
Definition Decl.h:2018
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, const AssociatedConstraint &TrailingRequiresClause={})
Definition Decl.h:2207
const ParmVarDecl * getParamDecl(unsigned i) const
Definition Decl.h:2815
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
Definition Decl.cpp:3253
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
Definition Decl.cpp:4179
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition Decl.cpp:4167
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition Decl.h:2332
SourceRange getReturnTypeSourceRange() const
Attempt to compute an informative source range covering the function return type.
Definition Decl.cpp:3998
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition Decl.cpp:3736
param_iterator param_end()
Definition Decl.h:2805
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
Definition Decl.h:2939
void setIsMultiVersion(bool V=true)
Sets the multiversion state for this declaration and all of its redeclarations.
Definition Decl.h:2713
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
Definition Decl.cpp:3625
QualType getReturnType() const
Definition Decl.h:2863
ArrayRef< ParmVarDecl * > parameters() const
Definition Decl.h:2792
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
Definition Decl.h:2461
param_iterator param_begin()
Definition Decl.h:2804
bool isVariadic() const
Whether this function is variadic.
Definition Decl.cpp:3107
bool isConstexprSpecified() const
Definition Decl.h:2497
bool isExternC() const
Determines whether this function is a function with external, C linkage.
Definition Decl.cpp:3592
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template instantiation this function represents.
Definition Decl.cpp:4391
bool isConsteval() const
Definition Decl.h:2500
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition Decl.cpp:3800
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
Definition Decl.cpp:3173
bool isInlineSpecified() const
Determine whether the "inline" keyword was specified for this function.
Definition Decl.h:2917
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5369
Declaration of a template function.
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition TypeBase.h:4565
CallingConv getCallConv() const
Definition TypeBase.h:4920
QualType getReturnType() const
Definition TypeBase.h:4905
GlobalDecl - represents a global declaration.
Definition GlobalDecl.h:57
One of these records is kept for each identifier that is lexed.
unsigned getBuiltinID() const
Return a value indicating whether this is a builtin function.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
A simple pair of identifier info and location.
SourceLocation getLoc() const
IdentifierInfo * getIdentifierInfo() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Describes an entity that is being initialized.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool isCompatibleWithMSVC() const
bool isTargetDevice() const
True when compiling for an offloading target device.
void push_back(const T &LocalValue)
Represents the results of name lookup.
Definition Lookup.h:147
A global _GUID constant.
Definition DeclCXX.h:4403
MSGuidDeclParts Parts
Definition DeclCXX.h:4405
Describes a module or submodule.
Definition Module.h:340
This represents a decl that may have a name.
Definition Decl.h:274
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:295
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.
Definition Decl.cpp:1975
bool isExternallyVisible() const
Definition Decl.h:433
A C++ nested-name-specifier augmented with source location information.
ObjCMethodDecl - Represents an instance or class method declaration.
Definition DeclObjC.h:140
Represents one property declaration in an Objective-C interface.
Definition DeclObjC.h:731
void * getAsOpaquePtr() const
Definition Ownership.h:91
static OpaquePtr getFromOpaquePtr(void *P)
Definition Ownership.h:92
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
Definition Attr.h:277
bool isValid() const
Is this parameter index valid?
Definition Attr.h:341
unsigned getSourceIndex() const
Get the parameter index as it would normally be encoded for attributes at the source level of represe...
Definition Attr.h:349
unsigned getASTIndex() const
Get the parameter index as it would normally be encoded at the AST level of representation: zero-orig...
Definition Attr.h:360
Represents a parameter to a function.
Definition Decl.h:1808
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:2954
ParsedAttr - Represents a syntactic attribute.
Definition ParsedAttr.h:119
bool isPackExpansion() const
Definition ParsedAttr.h:367
const AvailabilityChange & getAvailabilityDeprecated() const
Definition ParsedAttr.h:399
unsigned getSemanticSpelling() const
If the parsed attribute has a semantic equivalent, and it would have a semantic Spelling enumeration ...
bool existsInTarget(const TargetInfo &Target) const
bool checkExactlyNumArgs(class Sema &S, unsigned Num) const
Check if the attribute has exactly as many args as Num.
IdentifierLoc * getArgAsIdent(unsigned Arg) const
Definition ParsedAttr.h:389
bool hasParsedType() const
Definition ParsedAttr.h:337
const AvailabilityChange & getAvailabilityIntroduced() const
Definition ParsedAttr.h:393
void setInvalid(bool b=true) const
Definition ParsedAttr.h:345
bool hasVariadicArg() const
const ParsedAttrInfo & getInfo() const
Definition ParsedAttr.h:613
void handleAttrWithDelayedArgs(Sema &S, Decl *D) const
const Expr * getReplacementExpr() const
Definition ParsedAttr.h:429
bool hasProcessingCache() const
Definition ParsedAttr.h:347
SourceLocation getUnavailableLoc() const
Definition ParsedAttr.h:417
unsigned getProcessingCache() const
Definition ParsedAttr.h:349
const IdentifierLoc * getEnvironment() const
Definition ParsedAttr.h:435
bool acceptsExprPack() const
const Expr * getMessageExpr() const
Definition ParsedAttr.h:423
const ParsedType & getMatchingCType() const
Definition ParsedAttr.h:441
const ParsedType & getTypeArg() const
Definition ParsedAttr.h:459
SourceLocation getStrictLoc() const
Definition ParsedAttr.h:411
bool isTypeAttr() const
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this attribute.
Definition ParsedAttr.h:371
bool isArgIdent(unsigned Arg) const
Definition ParsedAttr.h:385
Expr * getArgAsExpr(unsigned Arg) const
Definition ParsedAttr.h:383
bool getMustBeNull() const
Definition ParsedAttr.h:453
bool checkAtLeastNumArgs(class Sema &S, unsigned Num) const
Check if the attribute has at least as many args as Num.
bool isUsedAsTypeAttr() const
Definition ParsedAttr.h:359
unsigned getNumArgMembers() const
bool isStmtAttr() const
bool isPragmaClangAttribute() const
True if the attribute is specified using 'pragma clang attribute'.
Definition ParsedAttr.h:363
bool slidesFromDeclToDeclSpecLegacyBehavior() const
Returns whether a [[]] attribute, if specified ahead of a declaration, should be applied to the decl-...
AttributeCommonInfo::Kind getKind() const
Definition ParsedAttr.h:610
void setProcessingCache(unsigned value) const
Definition ParsedAttr.h:354
bool isParamExpr(size_t N) const
bool isArgExpr(unsigned Arg) const
Definition ParsedAttr.h:379
bool getLayoutCompatible() const
Definition ParsedAttr.h:447
ArgsUnion getArg(unsigned Arg) const
getArg - Return the specified argument.
Definition ParsedAttr.h:374
SourceLocation getEllipsisLoc() const
Definition ParsedAttr.h:368
bool isInvalid() const
Definition ParsedAttr.h:344
bool checkAtMostNumArgs(class Sema &S, unsigned Num) const
Check if the attribute has at most as many args as Num.
const AvailabilityChange & getAvailabilityObsoleted() const
Definition ParsedAttr.h:405
void addAtEnd(ParsedAttr *newAttr)
Definition ParsedAttr.h:827
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition TypeBase.h:3390
QualType getPointeeType() const
Definition TypeBase.h:3400
IdentifierTable & getIdentifierTable()
A (possibly-)qualified type.
Definition TypeBase.h:937
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1004
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8445
QualType getCanonicalType() const
Definition TypeBase.h:8497
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition TypeBase.h:8539
const Type * getTypePtrOrNull() const
Definition TypeBase.h:8449
Represents a struct/union/class.
Definition Decl.h:4347
field_iterator field_end() const
Definition Decl.h:4553
field_range fields() const
Definition Decl.h:4550
specific_decl_iterator< FieldDecl > field_iterator
Definition Decl.h:4547
RecordDecl * getDefinitionOrSelf() const
Definition Decl.h:4535
field_iterator field_begin() const
Definition Decl.cpp:5269
Base for LValueReferenceType and RValueReferenceType.
Definition TypeBase.h:3635
Scope - A scope is a transient data structure that is used while parsing the program.
Definition Scope.h:41
unsigned getFlags() const
getFlags - Return the flags for this scope.
Definition Scope.h:269
@ FunctionDeclarationScope
This is a scope that corresponds to the parameters within a function prototype for a function declara...
Definition Scope.h:91
void handleAMDGPUMaxNumWorkGroupsAttr(Decl *D, const ParsedAttr &AL)
void handleAMDGPUFlatWorkGroupSizeAttr(Decl *D, const ParsedAttr &AL)
void handleAMDGPUNumSGPRAttr(Decl *D, const ParsedAttr &AL)
void handleAMDGPUNumVGPRAttr(Decl *D, const ParsedAttr &AL)
void handleAMDGPUWavesPerEUAttr(Decl *D, const ParsedAttr &AL)
void handleInterruptSaveFPAttr(Decl *D, const ParsedAttr &AL)
Definition SemaARM.cpp:1421
void handleInterruptAttr(Decl *D, const ParsedAttr &AL)
Definition SemaARM.cpp:1389
void handleBuiltinAliasAttr(Decl *D, const ParsedAttr &AL)
Definition SemaARM.cpp:1274
void handleNewAttr(Decl *D, const ParsedAttr &AL)
Definition SemaARM.cpp:1321
bool checkTargetVersionAttr(const StringRef Param, const SourceLocation Loc, SmallString< 64 > &NewParam)
Definition SemaARM.cpp:1644
bool SveAliasValid(unsigned BuiltinID, llvm::StringRef AliasName)
Definition SemaARM.cpp:1260
bool MveAliasValid(unsigned BuiltinID, llvm::StringRef AliasName)
Definition SemaARM.cpp:1247
void handleCmseNSEntryAttr(Decl *D, const ParsedAttr &AL)
Definition SemaARM.cpp:1374
bool checkTargetClonesAttr(SmallVectorImpl< StringRef > &Params, SmallVectorImpl< SourceLocation > &Locs, SmallVectorImpl< SmallString< 64 > > &NewParams)
Definition SemaARM.cpp:1678
bool CdeAliasValid(unsigned BuiltinID, llvm::StringRef AliasName)
Definition SemaARM.cpp:1255
void handleSignalAttr(Decl *D, const ParsedAttr &AL)
Definition SemaAVR.cpp:48
void handleInterruptAttr(Decl *D, const ParsedAttr &AL)
Definition SemaAVR.cpp:23
void handlePreserveAIRecord(RecordDecl *RD)
Definition SemaBPF.cpp:169
void handlePreserveAccessIndexAttr(Decl *D, const ParsedAttr &AL)
Definition SemaBPF.cpp:181
A generic diagnostic builder for errors which may or may not be deferred.
Definition SemaBase.h:111
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Definition SemaBase.cpp:61
CUDAFunctionTarget IdentifyTarget(const FunctionDecl *D, bool IgnoreImplicitHDAttr=false)
Determines whether the given function is a CUDA device/host/kernel/etc.
Definition SemaCUDA.cpp:208
CUDAFunctionTarget CurrentTarget()
Gets the CUDA target for the current context.
Definition SemaCUDA.h:153
SemaDiagnosticBuilder DiagIfHostCode(SourceLocation Loc, unsigned DiagID)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as host cod...
Definition SemaCUDA.cpp:942
void handleWaveSizeAttr(Decl *D, const ParsedAttr &AL)
void handleVkLocationAttr(Decl *D, const ParsedAttr &AL)
void handleSemanticAttr(Decl *D, const ParsedAttr &AL)
void handleShaderAttr(Decl *D, const ParsedAttr &AL)
void handleVkExtBuiltinOutputAttr(Decl *D, const ParsedAttr &AL)
void handlePackOffsetAttr(Decl *D, const ParsedAttr &AL)
void handleParamModifierAttr(Decl *D, const ParsedAttr &AL)
void handleRootSignatureAttr(Decl *D, const ParsedAttr &AL)
void handleResourceBindingAttr(Decl *D, const ParsedAttr &AL)
void handleNumThreadsAttr(Decl *D, const ParsedAttr &AL)
void handleVkExtBuiltinInputAttr(Decl *D, const ParsedAttr &AL)
void handleVkPushConstantAttr(Decl *D, const ParsedAttr &AL)
void handleVkBindingAttr(Decl *D, const ParsedAttr &AL)
void handleMatrixLayoutAttr(Decl *D, const ParsedAttr &AL)
void handleVkConstantIdAttr(Decl *D, const ParsedAttr &AL)
void handleInterruptAttr(Decl *D, const ParsedAttr &AL)
Definition SemaM68k.cpp:23
void handleInterruptAttr(Decl *D, const ParsedAttr &AL)
Definition SemaMIPS.cpp:243
void handleInterruptAttr(Decl *D, const ParsedAttr &AL)
void handleRuntimeName(Decl *D, const ParsedAttr &AL)
void handleNSObject(Decl *D, const ParsedAttr &AL)
bool isValidOSObjectOutParameter(const Decl *D)
void handleNSErrorDomain(Decl *D, const ParsedAttr &Attr)
void handleXReturnsXRetainedAttr(Decl *D, const ParsedAttr &AL)
void handleExternallyRetainedAttr(Decl *D, const ParsedAttr &AL)
void handleMethodFamilyAttr(Decl *D, const ParsedAttr &AL)
void handleIndependentClass(Decl *D, const ParsedAttr &AL)
void handleIBOutlet(Decl *D, const ParsedAttr &AL)
void handleReturnsInnerPointerAttr(Decl *D, const ParsedAttr &Attrs)
bool isObjCWritebackConversion(QualType FromType, QualType ToType, QualType &ConvertedType)
Determine whether this is an Objective-C writeback conversion, used for parameter passing when perfor...
void handleSuppresProtocolAttr(Decl *D, const ParsedAttr &AL)
void handleOwnershipAttr(Decl *D, const ParsedAttr &AL)
void handleBlocksAttr(Decl *D, const ParsedAttr &AL)
void handleBridgeMutableAttr(Decl *D, const ParsedAttr &AL)
Sema::RetainOwnershipKind parsedAttrToRetainOwnershipKind(const ParsedAttr &AL)
void handleRequiresSuperAttr(Decl *D, const ParsedAttr &Attrs)
void AddXConsumedAttr(Decl *D, const AttributeCommonInfo &CI, Sema::RetainOwnershipKind K, bool IsTemplateInstantiation)
void handleDesignatedInitializer(Decl *D, const ParsedAttr &AL)
void handleBridgeRelatedAttr(Decl *D, const ParsedAttr &AL)
void handleIBOutletCollection(Decl *D, const ParsedAttr &AL)
bool isCFStringType(QualType T)
void handleDirectAttr(Decl *D, const ParsedAttr &AL)
bool isNSStringType(QualType T, bool AllowNSAttributedString=false)
void handleBoxable(Decl *D, const ParsedAttr &AL)
void handleDirectMembersAttr(Decl *D, const ParsedAttr &AL)
void handleBridgeAttr(Decl *D, const ParsedAttr &AL)
void handlePreciseLifetimeAttr(Decl *D, const ParsedAttr &AL)
void handleSubGroupSize(Decl *D, const ParsedAttr &AL)
void handleNoSVMAttr(Decl *D, const ParsedAttr &AL)
void handleAccessAttr(Decl *D, const ParsedAttr &AL)
void handleOMPAssumeAttr(Decl *D, const ParsedAttr &AL)
bool checkTargetClonesAttr(const SmallVectorImpl< StringRef > &Params, const SmallVectorImpl< SourceLocation > &Locs, SmallVectorImpl< SmallString< 64 > > &NewParams, SourceLocation AttrLoc)
Definition SemaPPC.cpp:605
bool isAliasValid(unsigned BuiltinID, llvm::StringRef AliasName)
bool checkTargetClonesAttr(const SmallVectorImpl< StringRef > &Params, const SmallVectorImpl< SourceLocation > &Locs, SmallVectorImpl< SmallString< 64 > > &NewParams, SourceLocation AttrLoc)
void handleInterruptAttr(Decl *D, const ParsedAttr &AL)
bool checkTargetVersionAttr(const StringRef Param, const SourceLocation Loc, SmallString< 64 > &NewParam)
void handleKernelEntryPointAttr(Decl *D, const ParsedAttr &AL)
Definition SemaSYCL.cpp:215
void handleKernelAttr(Decl *D, const ParsedAttr &AL)
Definition SemaSYCL.cpp:176
void handleBridge(Decl *D, const ParsedAttr &AL)
Definition SemaSwift.cpp:99
void handleAsyncAttr(Decl *D, const ParsedAttr &AL)
void handleAsyncName(Decl *D, const ParsedAttr &AL)
void handleNewType(Decl *D, const ParsedAttr &AL)
void handleError(Decl *D, const ParsedAttr &AL)
void AddParameterABIAttr(Decl *D, const AttributeCommonInfo &CI, ParameterABI abi)
void handleAsyncError(Decl *D, const ParsedAttr &AL)
void handleName(Decl *D, const ParsedAttr &AL)
void handleAttrAttr(Decl *D, const ParsedAttr &AL)
Definition SemaSwift.cpp:84
void handleWebAssemblyImportNameAttr(Decl *D, const ParsedAttr &AL)
Definition SemaWasm.cpp:376
void handleWebAssemblyImportModuleAttr(Decl *D, const ParsedAttr &AL)
Definition SemaWasm.cpp:359
void handleWebAssemblyExportNameAttr(Decl *D, const ParsedAttr &AL)
Definition SemaWasm.cpp:392
void handleForceAlignArgPointerAttr(Decl *D, const ParsedAttr &AL)
Definition SemaX86.cpp:1033
void handleAnyInterruptAttr(Decl *D, const ParsedAttr &AL)
Definition SemaX86.cpp:964
bool checkTargetClonesAttr(const SmallVectorImpl< StringRef > &Params, const SmallVectorImpl< SourceLocation > &Locs, SmallVectorImpl< SmallString< 64 > > &NewParams, SourceLocation AttrLoc)
Definition SemaX86.cpp:1056
A class which encapsulates the logic for delaying diagnostics during parsing and other processing.
Definition Sema.h:1386
sema::DelayedDiagnosticPool * getCurrentPool() const
Returns the current delayed-diagnostics pool.
Definition Sema.h:1401
void popWithoutEmitting(DelayedDiagnosticsState state)
Leave a delayed-diagnostic state that was previously pushed.
Definition Sema.h:1415
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:868
SemaAMDGPU & AMDGPU()
Definition Sema.h:1448
BTFDeclTagAttr * mergeBTFDeclTagAttr(Decl *D, const BTFDeclTagAttr &AL)
void LoadExternalWeakUndeclaredIdentifiers()
Load weak undeclared identifiers from the external source.
Definition Sema.cpp:1087
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Definition Sema.h:9420
EnforceTCBAttr * mergeEnforceTCBAttr(Decl *D, const EnforceTCBAttr &AL)
SemaM68k & M68k()
Definition Sema.h:1498
DelayedDiagnosticsState ParsingDeclState
Definition Sema.h:1381
bool isValidPointerAttrType(QualType T, bool RefOkay=false)
Determine if type T is a valid subject for a nonnull and similar attributes.
static std::enable_if_t< std::is_base_of_v< Attr, AttrInfo >, SourceLocation > getAttrLoc(const AttrInfo &AL)
A helper function to provide Attribute Location for the Attr types AND the ParsedAttr.
Definition Sema.h:4895
SemaOpenMP & OpenMP()
Definition Sema.h:1533
TypeVisibilityAttr * mergeTypeVisibilityAttr(Decl *D, const AttributeCommonInfo &CI, TypeVisibilityAttr::VisibilityType Vis)
void AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E, bool IsPackExpansion)
AddAlignedAttr - Adds an aligned attribute to a particular declaration.
AvailabilityAttr * mergeAvailabilityAttr(NamedDecl *D, const AttributeCommonInfo &CI, const IdentifierInfo *Platform, bool Implicit, VersionTuple Introduced, VersionTuple Deprecated, VersionTuple Obsoleted, bool IsUnavailable, StringRef Message, bool IsStrict, StringRef Replacement, AvailabilityMergeKind AMK, int Priority, const IdentifierInfo *IIEnvironment, const IdentifierInfo *InferredPlatformII=nullptr)
bool checkFunctionOrMethodParameterIndex(const Decl *D, const AttrInfo &AI, unsigned AttrArgNum, const Expr *IdxExpr, ParamIdx &Idx, bool CanIndexImplicitThis=false, bool CanIndexVariadicArguments=false)
Check if IdxExpr is a valid parameter index for a function or instance method D.
Definition Sema.h:5223
void AddAssumeAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E, Expr *OE)
AddAssumeAlignedAttr - Adds an assume_aligned attribute to a particular declaration.
bool checkSectionName(SourceLocation LiteralLoc, StringRef Str)
void AddPragmaAttributes(Scope *S, Decl *D)
Adds the attributes that have been specified using the '#pragma clang attribute push' directives to t...
SemaCUDA & CUDA()
Definition Sema.h:1473
bool checkCommonAttributeFeatures(const Decl *D, const ParsedAttr &A, bool SkipArgCountCheck=false)
Handles semantic checking for features that are common to all attributes, such as checking whether a ...
bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, const ParsedAttributesView &AttrList)
Annotation attributes are the only attributes allowed after an access specifier.
DLLImportAttr * mergeDLLImportAttr(Decl *D, const AttributeCommonInfo &CI)
ExtVectorDeclsType ExtVectorDecls
ExtVectorDecls - This is a list all the extended vector types.
Definition Sema.h:4955
void PopParsingDeclaration(ParsingDeclState state, Decl *decl)
ErrorAttr * mergeErrorAttr(Decl *D, const AttributeCommonInfo &CI, StringRef NewUserDiagnostic)
bool CheckFormatStringsCompatible(FormatStringType FST, const StringLiteral *AuthoritativeFormatString, const StringLiteral *TestedFormatString, const Expr *FunctionCallArg=nullptr)
Verify that two format strings (as understood by attribute(format) and attribute(format_matches) are ...
bool CheckVarDeclSizeAddressSpace(const VarDecl *VD, LangAS AS)
Check whether the given variable declaration has a size that fits within the address space it is decl...
void redelayDiagnostics(sema::DelayedDiagnosticPool &pool)
Given a set of delayed diagnostics, re-emit them as if they had been delayed in the current context i...
PersonalityAttr * mergePersonalityAttr(Decl *D, FunctionDecl *Routine, const AttributeCommonInfo &CI)
SemaSYCL & SYCL()
Definition Sema.h:1558
AvailabilityAttr * mergeAndInferAvailabilityAttr(NamedDecl *D, const AttributeCommonInfo &CI, const IdentifierInfo *Platform, bool Implicit, VersionTuple Introduced, VersionTuple Deprecated, VersionTuple Obsoleted, bool IsUnavailable, StringRef Message, bool IsStrict, StringRef Replacement, AvailabilityMergeKind AMK, int Priority, const IdentifierInfo *IIEnvironment, const IdentifierInfo *InferredPlatformII)
VisibilityAttr * mergeVisibilityAttr(Decl *D, const AttributeCommonInfo &CI, VisibilityAttr::VisibilityType Vis)
SemaX86 & X86()
Definition Sema.h:1578
ParmVarDecl * BuildParmVarDeclForTypedef(DeclContext *DC, SourceLocation Loc, QualType T)
Synthesizes a variable for a parameter arising from a typedef.
ASTContext & Context
Definition Sema.h:1308
void LazyProcessLifetimeCaptureByParams(FunctionDecl *FD)
DiagnosticsEngine & getDiagnostics() const
Definition Sema.h:936
SemaObjC & ObjC()
Definition Sema.h:1518
void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext=true)
Add this decl to the scope shadowed decl chains.
void AddModeAttr(Decl *D, const AttributeCommonInfo &CI, const IdentifierInfo *Name, bool InInstantiation=false)
AddModeAttr - Adds a mode attribute to a particular declaration.
ASTContext & getASTContext() const
Definition Sema.h:939
void mergeVisibilityType(Decl *D, SourceLocation Loc, VisibilityAttr::VisibilityType Type)
bool CheckCallingConvAttr(const ParsedAttr &attr, CallingConv &CC, const FunctionDecl *FD=nullptr, CUDAFunctionTarget CFT=CUDAFunctionTarget::InvalidTarget)
Check validaty of calling convention attribute attr.
QualType BuildCountAttributedArrayOrPointerType(QualType WrappedTy, Expr *CountExpr, bool CountInBytes, bool OrNull)
void ProcessPragmaWeak(Scope *S, Decl *D)
bool CheckAttrNoArgs(const ParsedAttr &CurrAttr)
bool UnifySection(StringRef SectionName, int SectionFlags, NamedDecl *TheDecl)
Definition SemaAttr.cpp:838
void addNoClusterAttr(Decl *D, const AttributeCommonInfo &CI)
Add a no_cluster attribute to a particular declaration.
FPOptions & getCurFPFeatures()
Definition Sema.h:934
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
Definition Sema.cpp:84
@ UPPC_Expression
An arbitrary expression.
Definition Sema.h:14509
const LangOptions & getLangOpts() const
Definition Sema.h:932
ModularFormatAttr * mergeModularFormatAttr(Decl *D, const AttributeCommonInfo &CI, const IdentifierInfo *ModularImplFn, StringRef ImplName, MutableArrayRef< StringRef > Aspects)
SemaBPF & BPF()
Definition Sema.h:1463
Preprocessor & PP
Definition Sema.h:1307
bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T, UnexpandedParameterPackContext UPPC)
If the given type contains an unexpanded parameter pack, diagnose the error.
MinSizeAttr * mergeMinSizeAttr(Decl *D, const AttributeCommonInfo &CI)
SemaMSP430 & MSP430()
Definition Sema.h:1508
AssignConvertType CheckAssignmentConstraints(SourceLocation Loc, QualType LHSType, QualType RHSType)
CheckAssignmentConstraints - Perform type checking for assignment, argument passing,...
const LangOptions & LangOpts
Definition Sema.h:1306
static const uint64_t MaximumAlignment
Definition Sema.h:1235
CUDAClusterDimsAttr * createClusterDimsAttr(const AttributeCommonInfo &CI, Expr *X, Expr *Y, Expr *Z)
Add a cluster_dims attribute to a particular declaration.
SemaHLSL & HLSL()
Definition Sema.h:1483
AlwaysInlineAttr * mergeAlwaysInlineAttr(Decl *D, const AttributeCommonInfo &CI, const IdentifierInfo *Ident)
SemaMIPS & MIPS()
Definition Sema.h:1503
SemaRISCV & RISCV()
Definition Sema.h:1548
bool CheckCountedByAttrOnField(FieldDecl *FD, Expr *E, bool CountInBytes, bool OrNull)
Check if applying the specified attribute variant from the "counted by" family of attributes to Field...
void ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AttrList, const ProcessDeclAttributeOptions &Options=ProcessDeclAttributeOptions())
ProcessDeclAttributeList - Apply all the decl attributes in the specified attribute list to the speci...
SemaSwift & Swift()
Definition Sema.h:1563
NamedDecl * getCurFunctionOrMethodDecl() const
getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method or C function we're in,...
Definition Sema.cpp:1737
void AddAllocAlignAttr(Decl *D, const AttributeCommonInfo &CI, Expr *ParamExpr)
AddAllocAlignAttr - Adds an alloc_align attribute to a particular declaration.
bool CheckRegparmAttr(const ParsedAttr &attr, unsigned &value)
Checks a regparm attribute, returning true if it is ill-formed and otherwise setting numParams to the...
void ProcessDeclAttributeDelayed(Decl *D, const ParsedAttributesView &AttrList)
Helper for delayed processing TransparentUnion or BPFPreserveAccessIndexAttr attribute.
bool checkUInt32Argument(const AttrInfo &AI, const Expr *Expr, uint32_t &Val, unsigned Idx=UINT_MAX, bool StrictlyUnsigned=false)
If Expr is a valid integer constant, get the value of the integer expression and return success or fa...
Definition Sema.h:4906
MSInheritanceAttr * mergeMSInheritanceAttr(Decl *D, const AttributeCommonInfo &CI, bool BestCase, MSInheritanceModel Model)
InternalLinkageAttr * mergeInternalLinkageAttr(Decl *D, const ParsedAttr &AL)
bool IsAssignConvertCompatible(AssignConvertType ConvTy)
Definition Sema.h:8138
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition Sema.h:1446
void ActOnInitPriorityAttr(Decl *D, const Attr *A)
SemaOpenCL & OpenCL()
Definition Sema.h:1528
ExprResult PerformContextuallyConvertToBool(Expr *From)
PerformContextuallyConvertToBool - Perform a contextual conversion of the expression From to bool (C+...
FunctionDecl * ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, bool Complain=false, DeclAccessPair *Found=nullptr, TemplateSpecCandidateSet *FailedTSC=nullptr, bool ForTypeDeduction=false)
Given an expression that refers to an overloaded function, try to resolve that overloaded function ex...
NamedDecl * DeclClonePragmaWeak(NamedDecl *ND, const IdentifierInfo *II, SourceLocation Loc)
DeclClonePragmaWeak - clone existing decl (maybe definition), #pragma weak needs a non-definition dec...
DLLExportAttr * mergeDLLExportAttr(Decl *D, const AttributeCommonInfo &CI)
CodeSegAttr * mergeCodeSegAttr(Decl *D, const AttributeCommonInfo &CI, StringRef Name)
SectionAttr * mergeSectionAttr(Decl *D, const AttributeCommonInfo &CI, StringRef Name)
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
Definition Sema.h:14055
SourceManager & getSourceManager() const
Definition Sema.h:937
void ActOnCleanupAttr(Decl *D, const Attr *A)
static FormatStringType GetFormatStringType(StringRef FormatFlavor)
bool checkTargetAttr(SourceLocation LiteralLoc, StringRef Str)
bool ValidateFormatString(FormatStringType FST, const StringLiteral *Str)
Verify that one format string (as understood by attribute(format)) is self-consistent; for instance,...
FormatMatchesAttr * mergeFormatMatchesAttr(Decl *D, const AttributeCommonInfo &CI, const IdentifierInfo *Format, int FormatIdx, StringLiteral *FormatStr)
llvm::Error isValidSectionSpecifier(StringRef Str)
Used to implement to perform semantic checking on attribute((section("foo"))) specifiers.
void AddLaunchBoundsAttr(Decl *D, const AttributeCommonInfo &CI, Expr *MaxThreads, Expr *MinBlocks, Expr *MaxBlocks)
AddLaunchBoundsAttr - Adds a launch_bounds attribute to a particular declaration.
void DiagnoseUnknownAttribute(const ParsedAttr &AL)
bool isCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind=CompleteTypeKind::Default)
Definition Sema.h:15572
OptimizeNoneAttr * mergeOptimizeNoneAttr(Decl *D, const AttributeCommonInfo &CI)
void checkUnusedDeclAttributes(Declarator &D)
checkUnusedDeclAttributes - Given a declarator which is not being used to build a declaration,...
bool CheckAttrTarget(const ParsedAttr &CurrAttr)
EnforceTCBLeafAttr * mergeEnforceTCBLeafAttr(Decl *D, const EnforceTCBLeafAttr &AL)
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, AllowFoldKind CanFold=AllowFoldKind::No)
VerifyIntegerConstantExpression - Verifies that an expression is an ICE, and reports the appropriate ...
ASTConsumer & Consumer
Definition Sema.h:1309
void NoteAllOverloadCandidates(Expr *E, QualType DestType=QualType(), bool TakingAddress=false)
bool checkInstantiatedThreadSafetyAttrs(const Decl *D, const Attr *A)
Recheck instantiated thread-safety attributes that could not be validated on the dependent pattern de...
CUDALaunchBoundsAttr * CreateLaunchBoundsAttr(const AttributeCommonInfo &CI, Expr *MaxThreads, Expr *MinBlocks, Expr *MaxBlocks, bool IgnoreArch=false)
Create a CUDALaunchBoundsAttr attribute.
void addClusterDimsAttr(Decl *D, const AttributeCommonInfo &CI, Expr *X, Expr *Y, Expr *Z)
@ AP_InferredFromAnyAppleOS
The availability attribute was inferred from an 'anyAppleOS' availability attribute.
Definition Sema.h:4874
@ AP_PragmaClangAttribute
The availability attribute was applied using 'pragma clang attribute'.
Definition Sema.h:4866
@ AP_InferredFromOtherPlatform
The availability attribute for a specific platform was inferred from an availability attribute for an...
Definition Sema.h:4870
@ AP_PragmaClangAttribute_InferredFromAnyAppleOS
The availability attribute was inferred from an 'anyAppleOS' availability attribute that was applied ...
Definition Sema.h:4879
@ AP_Explicit
The availability attribute was specified explicitly next to the declaration.
Definition Sema.h:4863
SemaPPC & PPC()
Definition Sema.h:1538
SmallVector< Decl *, 2 > WeakTopLevelDecl
WeakTopLevelDecl - Translation-unit scoped declarations generated by #pragma weak during processing o...
Definition Sema.h:4943
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
Definition Sema.h:1267
UuidAttr * mergeUuidAttr(Decl *D, const AttributeCommonInfo &CI, StringRef UuidAsWritten, MSGuidDecl *GuidDecl)
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
Attr * CreateAnnotationAttr(const AttributeCommonInfo &CI, StringRef Annot, MutableArrayRef< Expr * > Args)
CreateAnnotationAttr - Creates an annotation Annot with Args arguments.
Definition Sema.cpp:3049
SemaAVR & AVR()
Definition Sema.h:1458
void handleDelayedAvailabilityCheck(sema::DelayedDiagnostic &DD, Decl *Ctx)
void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD)
ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in it, apply them to D.
void DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, const WeakInfo &W)
DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak applied to it,...
bool CheckSpanLikeType(const AttributeCommonInfo &CI, const QualType &Ty)
Check that the type is a plain record with one field being a pointer type and the other field being a...
llvm::MapVector< IdentifierInfo *, llvm::SetVector< WeakInfo, llvm::SmallVector< WeakInfo, 1u >, llvm::SmallDenseSet< WeakInfo, 2u, WeakInfo::DenseMapInfoByAliasOnly > > > WeakUndeclaredIdentifiers
WeakUndeclaredIdentifiers - Identifiers contained in #pragma weak before declared.
Definition Sema.h:3596
void ProcessAPINotes(Decl *D)
Map any API notes provided for this declaration to attributes on the declaration.
void CheckAlignasUnderalignment(Decl *D)
void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx)
DarwinSDKInfo * getDarwinSDKInfoForAvailabilityChecking(SourceLocation Loc, StringRef Platform)
Definition Sema.cpp:113
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)
void AddAlignValueAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E)
AddAlignValueAttr - Adds an align_value attribute to a particular declaration.
SemaWasm & Wasm()
Definition Sema.h:1573
FormatAttr * mergeFormatAttr(Decl *D, const AttributeCommonInfo &CI, const IdentifierInfo *Format, int FormatIdx, int FirstArg)
LifetimeCaptureByAttr * ParseLifetimeCaptureByAttr(const ParsedAttr &AL, StringRef ParamName)
bool checkMSInheritanceAttrOnDefinition(CXXRecordDecl *RD, SourceRange Range, bool BestCase, MSInheritanceModel SemanticSpelling)
bool checkStringLiteralArgumentAttr(const AttributeCommonInfo &CI, const Expr *E, StringRef &Str, SourceLocation *ArgLocation=nullptr)
Check if the argument E is a ASCII string literal.
SemaARM & ARM()
Definition Sema.h:1453
bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, const FunctionProtoType *Proto)
CheckFunctionCall - Check a direct function call for various correctness and safety properties not st...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
bool isInSystemMacro(SourceLocation loc) const
Returns whether Loc is expanded from a macro in a system header.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
Stmt - This represents one statement.
Definition Stmt.h:86
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:343
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Stmt.cpp:355
StringLiteral - This represents a string literal expression, e.g.
Definition Expr.h:1802
bool isBeingDefined() const
Return true if this decl is currently being defined.
Definition Decl.h:3860
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition Decl.h:3840
bool isUnion() const
Definition Decl.h:3950
Exposes information about the current target.
Definition TargetInfo.h:227
TargetOptions & getTargetOpts() const
Retrieve the target options.
Definition TargetInfo.h:327
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
virtual bool hasFeatureEnabled(const llvm::StringMap< bool > &Features, StringRef Name) const
Check if target has a given feature enabled.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
Definition TargetInfo.h:490
virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const
Determines whether a given calling convention is valid for the target.
bool isTLSSupported() const
Whether the target supports thread-local storage.
virtual unsigned getRegisterWidth() const
Return the "preferred" register width on this target.
Definition TargetInfo.h:907
virtual bool validateCPUSpecificCPUDispatch(StringRef Name) const
virtual bool hasProtectedVisibility() const
Does this target support "protected" visibility?
virtual unsigned getUnwindWordWidth() const
Definition TargetInfo.h:902
unsigned getCharWidth() const
Definition TargetInfo.h:521
virtual bool shouldDLLImportComdatSymbols() const
Does this target aim for semantic compatibility with Microsoft C++ code using dllimport/export attrib...
const llvm::VersionTuple & getSDKVersion() const
std::string CPU
If given, the name of the target CPU to generate code for.
llvm::StringMap< bool > FeatureMap
The map of which features have been enabled disabled based on the command line.
The base class of all kinds of template declarations (e.g., class, function, etc.).
Base wrapper for a particular "section" of type source info.
Definition TypeLoc.h:59
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
Definition TypeLoc.h:154
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition TypeLoc.h:2735
SourceLocation getBeginLoc() const
Get the begin source location.
Definition TypeLoc.cpp:193
A container of type source information.
Definition TypeBase.h:8416
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition TypeLoc.h:267
QualType getType() const
Return the type wrapped by this type source info.
Definition TypeBase.h:8427
The base class of the type hierarchy.
Definition TypeBase.h:1875
bool isSizelessType() const
As an extension, we classify types as one of "sized" or "sizeless"; every type is one or the other.
Definition Type.cpp:2661
bool isBlockPointerType() const
Definition TypeBase.h:8702
bool isVoidType() const
Definition TypeBase.h:9048
bool isBooleanType() const
Definition TypeBase.h:9185
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
Definition TypeBase.h:9235
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
Definition Type.cpp:2266
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
Definition Type.cpp:761
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition Type.h:26
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition Type.h:41
bool isArrayType() const
Definition TypeBase.h:8781
bool isCharType() const
Definition Type.cpp:2193
bool isFunctionPointerType() const
Definition TypeBase.h:8749
bool isPointerType() const
Definition TypeBase.h:8682
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition TypeBase.h:9092
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9342
bool isReferenceType() const
Definition TypeBase.h:8706
bool isEnumeralType() const
Definition TypeBase.h:8813
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
Definition Type.cpp:1958
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
Definition Type.cpp:2156
bool isAlignValT() const
Definition Type.cpp:3302
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:789
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition TypeBase.h:9170
bool isExtVectorType() const
Definition TypeBase.h:8825
bool isAnyCharacterType() const
Determine whether this type is any of the built-in character types.
Definition Type.cpp:2229
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition TypeBase.h:2852
bool isBitIntType() const
Definition TypeBase.h:8957
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition TypeBase.h:2844
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
Definition TypeBase.h:2465
bool isPointerOrReferenceType() const
Definition TypeBase.h:8686
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
Definition Type.cpp:2527
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
Definition Type.cpp:2397
bool isVectorType() const
Definition TypeBase.h:8821
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:2983
bool isFloatingType() const
Definition Type.cpp:2389
bool isAnyPointerType() const
Definition TypeBase.h:8690
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9275
const Type * getUnqualifiedDesugaredType() const
Return the specified type with any "sugar" removed from the type, removing any typedefs,...
Definition Type.cpp:690
Base class for declarations which introduce a typedef-name.
Definition Decl.h:3584
static UnaryOperator * Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, FPOptionsOverride FPFeatures)
Definition Expr.cpp:5159
Represents a dependent using declaration which was marked with typename.
Definition DeclCXX.h:4042
Represents a dependent using declaration which was not marked with typename.
Definition DeclCXX.h:3945
Represents a C++ using-declaration.
Definition DeclCXX.h:3596
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
void setType(QualType newType)
Definition Decl.h:724
QualType getType() const
Definition Decl.h:723
Represents a variable declaration or definition.
Definition Decl.h:924
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
Definition Decl.cpp:2130
@ TLS_None
Not a TLS variable.
Definition Decl.h:944
Represents a GCC generic vector type.
Definition TypeBase.h:4237
Captures information about a #pragma weak directive.
Definition Weak.h:25
const IdentifierInfo * getAlias() const
Definition Weak.h:32
SourceLocation getLocation() const
Definition Weak.h:33
A collection of diagnostics which were delayed.
const DelayedDiagnosticPool * getParent() const
void steal(DelayedDiagnosticPool &pool)
Steal the diagnostics from the given pool.
SmallVectorImpl< DelayedDiagnostic >::const_iterator pool_iterator
A diagnostic message which has been conditionally emitted pending the complete parsing of the current...
unsigned getForbiddenTypeDiagnostic() const
The diagnostic ID to emit.
Defines the clang::TargetInfo interface.
#define UINT_MAX
Definition limits.h:64
Enums for the diagnostics of target, target_version and target_clones.
Definition Sema.h:854
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
Definition Sema.h:830
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ CPlusPlus23
@ ExpectedFunctionMethodOrBlock
@ ExpectedClass
@ ExpectedTypeOrNamespace
@ ExpectedVariableFieldOrTag
@ ExpectedVariableOrField
@ ExpectedUnion
@ ExpectedFunctionOrMethod
@ ExpectedVariable
@ ExpectedFunctionOrClassOrEnum
@ ExpectedVariableOrFunction
@ ExpectedKernelFunction
@ ExpectedFunctionVariableOrClass
@ ExpectedNonMemberFunction
void handleSimpleAttributeOrDiagnose(SemaBase &S, Decl *D, const AttributeCommonInfo &CI, bool PassesCheck, unsigned DiagID, DiagnosticArgs &&...ExtraArgs)
Add an attribute AttrType to declaration D, provided that PassesCheck is true.
Definition Attr.h:185
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
CUDAFunctionTarget
Definition Cuda.h:63
QualType getFunctionOrMethodResultType(const Decl *D)
Definition Attr.h:98
@ OK_Ordinary
An ordinary object is located at an address in memory.
Definition Specifiers.h:152
AvailabilityMergeKind
Describes the kind of merge to perform for availability attributes (including "deprecated",...
Definition Sema.h:628
@ None
Don't merge availability attributes at all.
Definition Sema.h:630
@ Override
Merge availability attributes for an override, which requires an exact match or a weakening of constr...
Definition Sema.h:636
@ OptionalProtocolImplementation
Merge availability attributes for an implementation of an optional protocol requirement.
Definition Sema.h:642
@ Redeclaration
Merge availability attributes for a redeclaration, which requires an exact match.
Definition Sema.h:633
@ ProtocolImplementation
Merge availability attributes for an implementation of a protocol requirement.
Definition Sema.h:639
@ VectorLength
'vector_length' clause, allowed on 'parallel', 'kernels', 'parallel loop', and 'kernels loop' constru...
CudaVersion ToCudaVersion(llvm::VersionTuple)
Definition Cuda.cpp:72
SmallVector< Attr *, 4 > AttrVec
AttrVec - A vector of Attr, which is how they are stored on the AST.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool checkAttrMutualExclusion(SemaBase &S, Decl *D, const ParsedAttr &AL)
Diagnose mutually exclusive attributes when present on a given declaration.
Definition Attr.h:135
@ SC_Extern
Definition Specifiers.h:252
@ SC_Register
Definition Specifiers.h:258
@ SC_None
Definition Specifiers.h:251
@ TSCS_unspecified
Definition Specifiers.h:237
void inferNoReturnAttr(Sema &S, Decl *D)
Expr * Cond
};
SourceRange getFunctionOrMethodResultSourceRange(const Decl *D)
Definition Attr.h:104
bool isFunctionOrMethodOrBlockForAttrSubject(const Decl *D)
Return true if the given decl has function type (function or function-typed variable) or an Objective...
Definition Attr.h:40
QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx)
Definition Attr.h:83
@ Internal
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
Definition Linkage.h:35
Language
The language for the input, used to select and validate the language standard and possible actions.
AttributeArgumentNType
These constants match the enumerated choices of err_attribute_argument_n_type and err_attribute_argum...
@ AANT_ArgumentIntegerConstant
@ AANT_ArgumentBuiltinFunction
@ AANT_ArgumentIntOrBool
@ AANT_ArgumentIdentifier
@ AANT_ArgumentString
@ SD_Automatic
Automatic storage duration (most local variables).
Definition Specifiers.h:342
bool isLambdaCallOperator(const CXXMethodDecl *MD)
Definition ASTLambda.h:28
InheritableAttr * getDLLAttr(Decl *D)
Return a DLL attribute from the declaration.
@ SwiftAsyncContext
This parameter (which must have pointer type) uses the special Swift asynchronous context-pointer ABI...
Definition Specifiers.h:402
@ SwiftErrorResult
This parameter (which must have pointer-to-pointer type) uses the special Swift error-result ABI trea...
Definition Specifiers.h:392
@ SwiftIndirectResult
This parameter (which must have pointer type) is a Swift indirect result parameter.
Definition Specifiers.h:387
@ SwiftContext
This parameter (which must have pointer type) uses the special Swift context-pointer ABI treatment.
Definition Specifiers.h:397
bool isFunctionOrMethodVariadic(const Decl *D)
Definition Attr.h:112
@ Template
We are parsing a template declaration.
Definition Parser.h:81
bool isFuncOrMethodForAttrSubject(const Decl *D)
isFuncOrMethodForAttrSubject - Return true if the given decl has function type (function or function-...
Definition Attr.h:34
ExprResult ExprError()
Definition Ownership.h:265
OffloadArch StringToOffloadArch(llvm::StringRef S)
CudaVersion
Definition Cuda.h:22
LLVM_READONLY bool isHexDigit(unsigned char c)
Return true if this character is an ASCII hex digit: [0-9a-fA-F].
Definition CharInfo.h:144
FormatStringType
Definition Sema.h:499
SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups)
Parse a single value from a -fsanitize= or -fno-sanitize= value list.
const char * OffloadArchToString(OffloadArch A)
void handleSimpleAttribute(SemaBase &S, Decl *D, const AttributeCommonInfo &CI)
Applies the given attribute to the Decl without performing any additional semantic checking.
Definition Attr.h:175
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
bool hasImplicitObjectParameter(const Decl *D)
Definition Attr.h:126
FloatModeKind
Definition TargetInfo.h:75
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition Specifiers.h:136
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Definition Specifiers.h:140
MSInheritanceModel
Assigned inheritance model for a class in the MS C++ ABI.
Definition Specifiers.h:413
bool hasFunctionProto(const Decl *D)
hasFunctionProto - Return true if the given decl has a argument information.
Definition Attr.h:55
unsigned getFunctionOrMethodNumParams(const Decl *D)
getFunctionOrMethodNumParams - Return number of function or method parameters.
Definition Attr.h:64
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
Definition DeclBase.h:1301
DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition Specifiers.h:199
CallingConv
CallingConv - Specifies the calling convention that a function uses.
Definition Specifiers.h:279
@ CC_X86Pascal
Definition Specifiers.h:285
@ CC_Swift
Definition Specifiers.h:294
@ CC_IntelOclBicc
Definition Specifiers.h:291
@ CC_PreserveMost
Definition Specifiers.h:296
@ CC_Win64
Definition Specifiers.h:286
@ CC_X86ThisCall
Definition Specifiers.h:283
@ CC_AArch64VectorCall
Definition Specifiers.h:298
@ CC_DeviceKernel
Definition Specifiers.h:293
@ CC_AAPCS
Definition Specifiers.h:289
@ CC_PreserveNone
Definition Specifiers.h:301
@ CC_M68kRTD
Definition Specifiers.h:300
@ CC_SwiftAsync
Definition Specifiers.h:295
@ CC_X86RegCall
Definition Specifiers.h:288
@ CC_RISCVVectorCall
Definition Specifiers.h:302
@ CC_X86VectorCall
Definition Specifiers.h:284
@ CC_AArch64SVEPCS
Definition Specifiers.h:299
@ CC_RISCVVLSCall_32
Definition Specifiers.h:303
@ CC_X86StdCall
Definition Specifiers.h:281
@ CC_X86_64SysV
Definition Specifiers.h:287
@ CC_PreserveAll
Definition Specifiers.h:297
@ CC_X86FastCall
Definition Specifiers.h:282
@ CC_AAPCS_VFP
Definition Specifiers.h:290
@ Generic
not a target-specific vector type
Definition TypeBase.h:4198
U cast(CodeGen::Address addr)
Definition Address.h:327
SourceRange getFunctionOrMethodParamRange(const Decl *D, unsigned Idx)
Definition Attr.h:92
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
Definition Ownership.h:230
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:5973
@ None
No keyword precedes the qualified type name.
Definition TypeBase.h:5989
@ Union
The "union" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:5976
ActionResult< Expr * > ExprResult
Definition Ownership.h:249
@ Other
Other implicit parameter.
Definition Decl.h:1763
IdentifierInfo * Identifier
FormatAttrKind Kind
Represents information about a change in availability for an entity, which is part of the encoding of...
Definition ParsedAttr.h:47
VersionTuple Version
The version number at which the change occurred.
Definition ParsedAttr.h:52
bool isValid() const
Determine whether this availability change is valid.
Definition ParsedAttr.h:58
SourceLocation KeywordLoc
The location of the keyword indicating the kind of change.
Definition ParsedAttr.h:49
A value that describes two os-environment pairs that can be used as a key to the version map in the S...
static constexpr OSEnvPair macOStoMacCatalystPair()
Returns the os-environment mapping pair that's used to represent the macOS -> Mac Catalyst version ma...
static constexpr OSEnvPair iOStoWatchOSPair()
Returns the os-environment mapping pair that's used to represent the iOS -> watchOS version mapping.
static constexpr OSEnvPair iOStoTvOSPair()
Returns the os-environment mapping pair that's used to represent the iOS -> tvOS version mapping.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
DeclarationName getName() const
getName - Returns the embedded declaration name.
const ParsedAttributesView & getAttrs() const
If there are attributes applied to this declaratorchunk, return them.
Definition DeclSpec.h:1703
uint16_t Part2
...-89ab-...
Definition DeclCXX.h:4382
uint32_t Part1
{01234567-...
Definition DeclCXX.h:4380
uint16_t Part3
...-cdef-...
Definition DeclCXX.h:4384
uint8_t Part4And5[8]
...-0123-456789abcdef}
Definition DeclCXX.h:4386
virtual AttrHandling handleDeclAttribute(Sema &S, Decl *D, const ParsedAttr &Attr) const
If this ParsedAttrInfo knows how to handle this ParsedAttr applied to this Decl then do so and return...
Contains information gathered from parsing the contents of TargetAttr.
Definition TargetInfo.h:60
std::vector< std::string > Features
Definition TargetInfo.h:61