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