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
2298static void handleUnusedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2299 bool IsCXX17Attr = AL.isCXX11Attribute() && !AL.getScopeName();
2300
2301 // If this is spelled as the standard C++17 attribute, but not in C++17, warn
2302 // about using it as an extension.
2303 if (!S.getLangOpts().CPlusPlus17 && IsCXX17Attr)
2304 S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
2305
2306 D->addAttr(::new (S.Context) UnusedAttr(S.Context, AL));
2307}
2308
2310 const ParsedAttr &AL) {
2311 // If no Expr node exists on the attribute, return a nullptr result (default
2312 // priority to be used). If Expr node exists but is not valid, return an
2313 // invalid result. Otherwise, return the Expr.
2314 Expr *E = nullptr;
2315 if (AL.getNumArgs() == 1) {
2316 E = AL.getArgAsExpr(0);
2317 if (E->isValueDependent()) {
2318 if (!E->isTypeDependent() && !E->getType()->isIntegerType()) {
2319 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
2321 return ExprError();
2322 }
2323 } else {
2324 uint32_t priority;
2325 if (!S.checkUInt32Argument(AL, AL.getArgAsExpr(0), priority)) {
2326 return ExprError();
2327 }
2328 return ConstantExpr::Create(S.Context, E,
2329 APValue(llvm::APSInt::getUnsigned(priority)));
2330 }
2331 }
2332 return E;
2333}
2334
2335static void handleConstructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2336 if (S.getLangOpts().HLSL && AL.getNumArgs()) {
2337 S.Diag(AL.getLoc(), diag::err_hlsl_init_priority_unsupported);
2338 return;
2339 }
2341 if (E.isInvalid())
2342 return;
2343 S.Diag(D->getLocation(), diag::warn_global_constructor)
2344 << D->getSourceRange();
2345 D->addAttr(ConstructorAttr::Create(S.Context, E.get(), AL));
2346}
2347
2348static void handleDestructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2350 if (E.isInvalid())
2351 return;
2352 S.Diag(D->getLocation(), diag::warn_global_destructor) << D->getSourceRange();
2353 D->addAttr(DestructorAttr::Create(S.Context, E.get(), AL));
2354}
2355
2356template <typename AttrTy>
2357static void handleAttrWithMessage(Sema &S, Decl *D, const ParsedAttr &AL) {
2358 // Handle the case where the attribute has a text message.
2359 StringRef Str;
2360 if (AL.getNumArgs() == 1 && !S.checkStringLiteralArgumentAttr(AL, 0, Str))
2361 return;
2362
2363 D->addAttr(::new (S.Context) AttrTy(S.Context, AL, Str));
2364}
2365
2367 const IdentifierInfo *Platform,
2368 VersionTuple Introduced,
2369 VersionTuple Deprecated,
2370 VersionTuple Obsoleted) {
2371 StringRef PlatformName
2372 = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
2373 if (PlatformName.empty())
2374 PlatformName = Platform->getName();
2375
2376 // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
2377 // of these steps are needed).
2378 if (!Introduced.empty() && !Deprecated.empty() &&
2379 !(Introduced <= Deprecated)) {
2380 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2381 << 1 << PlatformName << Deprecated.getAsString()
2382 << 0 << Introduced.getAsString();
2383 return true;
2384 }
2385
2386 if (!Introduced.empty() && !Obsoleted.empty() &&
2387 !(Introduced <= Obsoleted)) {
2388 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2389 << 2 << PlatformName << Obsoleted.getAsString()
2390 << 0 << Introduced.getAsString();
2391 return true;
2392 }
2393
2394 if (!Deprecated.empty() && !Obsoleted.empty() &&
2395 !(Deprecated <= Obsoleted)) {
2396 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2397 << 2 << PlatformName << Obsoleted.getAsString()
2398 << 1 << Deprecated.getAsString();
2399 return true;
2400 }
2401
2402 return false;
2403}
2404
2405/// Check whether the two versions match.
2406///
2407/// If either version tuple is empty, then they are assumed to match. If
2408/// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y.
2409static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y,
2410 bool BeforeIsOkay) {
2411 if (X.empty() || Y.empty())
2412 return true;
2413
2414 if (X == Y)
2415 return true;
2416
2417 if (BeforeIsOkay && X < Y)
2418 return true;
2419
2420 return false;
2421}
2422
2424 NamedDecl *D, const AttributeCommonInfo &CI, const IdentifierInfo *Platform,
2425 bool Implicit, VersionTuple Introduced, VersionTuple Deprecated,
2426 VersionTuple Obsoleted, bool IsUnavailable, StringRef Message,
2427 bool IsStrict, StringRef Replacement, AvailabilityMergeKind AMK,
2428 int Priority, const IdentifierInfo *Environment,
2429 const IdentifierInfo *InferredPlatformII) {
2430 VersionTuple MergedIntroduced = Introduced;
2431 VersionTuple MergedDeprecated = Deprecated;
2432 VersionTuple MergedObsoleted = Obsoleted;
2433 bool FoundAny = false;
2434 bool OverrideOrImpl = false;
2435 switch (AMK) {
2438 OverrideOrImpl = false;
2439 break;
2440
2444 OverrideOrImpl = true;
2445 break;
2446 }
2447
2448 if (D->hasAttrs()) {
2449 AttrVec &Attrs = D->getAttrs();
2450 for (unsigned i = 0, e = Attrs.size(); i != e;) {
2451 auto *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]);
2452 if (!OldAA) {
2453 ++i;
2454 continue;
2455 }
2456
2457 const IdentifierInfo *OldEnvironment = OldAA->getEnvironment();
2458 if (OldEnvironment != Environment) {
2459 ++i;
2460 continue;
2461 }
2462
2463 if (OldAA->getPlatform() != Platform) {
2464 // If this new attr is for anyappleos and the old attr is for the
2465 // inferred platform, the existing explicit platform attr wins.
2466 if (InferredPlatformII) {
2467 if (OldAA->getPlatform() == InferredPlatformII)
2468 return nullptr;
2469 } else {
2470 // If this new attr is an explicit platform attr, check if the old
2471 // attr is an existing anyAppleOS attr whose inferred attr is for this
2472 // platform. If so, the explicit attr wins: erase the old attr.
2473 if (AvailabilityAttr *Inf = OldAA->getInferredAttrAs();
2474 Inf && Inf->getPlatform() == Platform) {
2475 Attrs.erase(Attrs.begin() + i);
2476 --e;
2477 continue;
2478 }
2479 }
2480 ++i;
2481 continue;
2482 }
2483
2484 // If there is an existing availability attribute for this platform that
2485 // has a lower priority use the existing one and discard the new
2486 // attribute.
2487 if (OldAA->getPriority() < Priority)
2488 return nullptr;
2489
2490 // If there is an existing attribute for this platform that has a higher
2491 // priority than the new attribute then erase the old one and continue
2492 // processing the attributes.
2493 if (OldAA->getPriority() > Priority) {
2494 Attrs.erase(Attrs.begin() + i);
2495 --e;
2496 continue;
2497 }
2498
2499 FoundAny = true;
2500 VersionTuple OldIntroduced = OldAA->getIntroduced();
2501 VersionTuple OldDeprecated = OldAA->getDeprecated();
2502 VersionTuple OldObsoleted = OldAA->getObsoleted();
2503 bool OldIsUnavailable = OldAA->getUnavailable();
2504
2505 if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl) ||
2506 !versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl) ||
2507 !versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl) ||
2508 !(OldIsUnavailable == IsUnavailable ||
2509 (OverrideOrImpl && !OldIsUnavailable && IsUnavailable))) {
2510 if (OverrideOrImpl) {
2511 int Which = -1;
2512 VersionTuple FirstVersion;
2513 VersionTuple SecondVersion;
2514 if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl)) {
2515 Which = 0;
2516 FirstVersion = OldIntroduced;
2517 SecondVersion = Introduced;
2518 } else if (!versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl)) {
2519 Which = 1;
2520 FirstVersion = Deprecated;
2521 SecondVersion = OldDeprecated;
2522 } else if (!versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl)) {
2523 Which = 2;
2524 FirstVersion = Obsoleted;
2525 SecondVersion = OldObsoleted;
2526 }
2527
2528 if (Which == -1) {
2529 Diag(OldAA->getLocation(),
2530 diag::warn_mismatched_availability_override_unavail)
2531 << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
2533 } else if (Which != 1 && AMK == AvailabilityMergeKind::
2535 // Allow different 'introduced' / 'obsoleted' availability versions
2536 // on a method that implements an optional protocol requirement. It
2537 // makes less sense to allow this for 'deprecated' as the user can't
2538 // see if the method is 'deprecated' as 'respondsToSelector' will
2539 // still return true when the method is deprecated.
2540 ++i;
2541 continue;
2542 } else {
2543 Diag(OldAA->getLocation(),
2544 diag::warn_mismatched_availability_override)
2545 << Which
2546 << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
2547 << FirstVersion.getAsString() << SecondVersion.getAsString()
2549 }
2551 Diag(CI.getLoc(), diag::note_overridden_method);
2552 else
2553 Diag(CI.getLoc(), diag::note_protocol_method);
2554 } else {
2555 Diag(OldAA->getLocation(), diag::warn_mismatched_availability);
2556 Diag(CI.getLoc(), diag::note_previous_attribute);
2557 }
2558
2559 Attrs.erase(Attrs.begin() + i);
2560 --e;
2561 continue;
2562 }
2563
2564 VersionTuple MergedIntroduced2 = MergedIntroduced;
2565 VersionTuple MergedDeprecated2 = MergedDeprecated;
2566 VersionTuple MergedObsoleted2 = MergedObsoleted;
2567
2568 if (MergedIntroduced2.empty())
2569 MergedIntroduced2 = OldIntroduced;
2570 if (MergedDeprecated2.empty())
2571 MergedDeprecated2 = OldDeprecated;
2572 if (MergedObsoleted2.empty())
2573 MergedObsoleted2 = OldObsoleted;
2574
2575 if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform,
2576 MergedIntroduced2, MergedDeprecated2,
2577 MergedObsoleted2)) {
2578 Attrs.erase(Attrs.begin() + i);
2579 --e;
2580 continue;
2581 }
2582
2583 MergedIntroduced = MergedIntroduced2;
2584 MergedDeprecated = MergedDeprecated2;
2585 MergedObsoleted = MergedObsoleted2;
2586 ++i;
2587 }
2588 }
2589
2590 if (FoundAny &&
2591 MergedIntroduced == Introduced &&
2592 MergedDeprecated == Deprecated &&
2593 MergedObsoleted == Obsoleted)
2594 return nullptr;
2595
2596 // Only create a new attribute if !OverrideOrImpl, but we want to do
2597 // the checking.
2598 if (!checkAvailabilityAttr(*this, CI.getRange(), Platform, MergedIntroduced,
2599 MergedDeprecated, MergedObsoleted) &&
2600 !OverrideOrImpl) {
2601 auto *Avail = ::new (Context) AvailabilityAttr(
2602 Context, CI, Platform, Introduced, Deprecated, Obsoleted, IsUnavailable,
2603 Message, IsStrict, Replacement, Priority, Environment,
2604 /*InferredAttr=*/nullptr);
2605 Avail->setImplicit(Implicit);
2606 return Avail;
2607 }
2608 return nullptr;
2609}
2610
2612 NamedDecl *D, const AttributeCommonInfo &CI, const IdentifierInfo *Platform,
2613 bool Implicit, VersionTuple Introduced, VersionTuple Deprecated,
2614 VersionTuple Obsoleted, bool IsUnavailable, StringRef Message,
2615 bool IsStrict, StringRef Replacement, AvailabilityMergeKind AMK,
2616 int Priority, const IdentifierInfo *IIEnvironment,
2617 const IdentifierInfo *InferredPlatformII) {
2618 AvailabilityAttr *OrigAttr = mergeAvailabilityAttr(
2619 D, CI, Platform, Implicit, Introduced, Deprecated, Obsoleted,
2620 IsUnavailable, Message, IsStrict, Replacement, AMK, Priority,
2621 IIEnvironment, InferredPlatformII);
2622 if (!OrigAttr || !InferredPlatformII)
2623 return OrigAttr;
2624
2625 auto *InferredAttr = ::new (Context) AvailabilityAttr(
2626 Context, CI, InferredPlatformII, OrigAttr->getIntroduced(),
2627 OrigAttr->getDeprecated(), OrigAttr->getObsoleted(),
2628 OrigAttr->getUnavailable(), OrigAttr->getMessage(), OrigAttr->getStrict(),
2629 OrigAttr->getReplacement(),
2630 Priority == AP_PragmaClangAttribute
2633 IIEnvironment, /*InferredAttr=*/nullptr);
2634 InferredAttr->setImplicit(true);
2635 OrigAttr->setInferredAttr(InferredAttr);
2636 return OrigAttr;
2637}
2638
2639/// Returns true if the given availability attribute should be inferred, and
2640/// adjusts the value of the attribute as necessary to facilitate that.
2642 IdentifierInfo *&II,
2643 bool &IsUnavailable,
2644 VersionTuple &Introduced,
2645 VersionTuple &Deprecated,
2646 VersionTuple &Obsolete, Sema &S) {
2647 const llvm::Triple &TT = S.Context.getTargetInfo().getTriple();
2648 const ASTContext &Context = S.Context;
2649 if (TT.getOS() != llvm::Triple::XROS)
2650 return false;
2651 IdentifierInfo *NewII = nullptr;
2652 if (II->getName() == "ios")
2653 NewII = &Context.Idents.get("xros");
2654 else if (II->getName() == "ios_app_extension")
2655 NewII = &Context.Idents.get("xros_app_extension");
2656 if (!NewII)
2657 return false;
2658 II = NewII;
2659
2660 auto MakeUnavailable = [&]() {
2661 IsUnavailable = true;
2662 // Reset introduced, deprecated, obsoleted.
2663 Introduced = VersionTuple();
2664 Deprecated = VersionTuple();
2665 Obsolete = VersionTuple();
2666 };
2667
2669 AL.getRange().getBegin(), "ios");
2670
2671 if (!SDKInfo) {
2672 MakeUnavailable();
2673 return true;
2674 }
2675 // Map from the fallback platform availability to the current platform
2676 // availability.
2677 const auto *Mapping = SDKInfo->getVersionMapping(DarwinSDKInfo::OSEnvPair(
2678 llvm::Triple::IOS, llvm::Triple::UnknownEnvironment, llvm::Triple::XROS,
2679 llvm::Triple::UnknownEnvironment));
2680 if (!Mapping) {
2681 MakeUnavailable();
2682 return true;
2683 }
2684
2685 if (!Introduced.empty()) {
2686 auto NewIntroduced = Mapping->mapIntroducedAvailabilityVersion(Introduced);
2687 if (!NewIntroduced) {
2688 MakeUnavailable();
2689 return true;
2690 }
2691 Introduced = *NewIntroduced;
2692 }
2693
2694 if (!Obsolete.empty()) {
2695 auto NewObsolete =
2696 Mapping->mapDeprecatedObsoletedAvailabilityVersion(Obsolete);
2697 if (!NewObsolete) {
2698 MakeUnavailable();
2699 return true;
2700 }
2701 Obsolete = *NewObsolete;
2702 }
2703
2704 if (!Deprecated.empty()) {
2705 auto NewDeprecated =
2706 Mapping->mapDeprecatedObsoletedAvailabilityVersion(Deprecated);
2707 Deprecated = NewDeprecated ? *NewDeprecated : VersionTuple();
2708 }
2709
2710 return true;
2711}
2712
2713static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2715 D)) {
2716 S.Diag(AL.getRange().getBegin(), diag::warn_deprecated_ignored_on_using)
2717 << AL;
2718 return;
2719 }
2720
2721 if (!AL.checkExactlyNumArgs(S, 1))
2722 return;
2723 IdentifierLoc *Platform = AL.getArgAsIdent(0);
2724
2725 IdentifierInfo *II = Platform->getIdentifierInfo();
2726 StringRef PrettyName = AvailabilityAttr::getPrettyPlatformName(II->getName());
2727 if (PrettyName.empty())
2728 S.Diag(Platform->getLoc(), diag::warn_availability_unknown_platform)
2729 << Platform->getIdentifierInfo();
2730
2731 auto *ND = dyn_cast<NamedDecl>(D);
2732 if (!ND) // We warned about this already, so just return.
2733 return;
2734
2738
2739 const llvm::Triple::OSType PlatformOS = AvailabilityAttr::getOSType(
2740 AvailabilityAttr::canonicalizePlatformName(II->getName()));
2741
2742 auto reportAndUpdateIfInvalidOS = [&](auto &InputVersion) -> void {
2743 const bool IsInValidRange =
2744 llvm::Triple::isValidVersionForOS(PlatformOS, InputVersion);
2745 // Canonicalize availability versions.
2746 auto CanonicalVersion = llvm::Triple::getCanonicalVersionForOS(
2747 PlatformOS, InputVersion, IsInValidRange);
2748 if (!IsInValidRange) {
2749 S.Diag(Platform->getLoc(), diag::warn_availability_invalid_os_version)
2750 << InputVersion.getAsString() << PrettyName;
2751 S.Diag(Platform->getLoc(),
2752 diag::note_availability_invalid_os_version_adjusted)
2753 << CanonicalVersion.getAsString();
2754 }
2755 InputVersion = CanonicalVersion;
2756 };
2757
2758 if (PlatformOS != llvm::Triple::OSType::UnknownOS) {
2759 reportAndUpdateIfInvalidOS(Introduced.Version);
2760 reportAndUpdateIfInvalidOS(Deprecated.Version);
2761 reportAndUpdateIfInvalidOS(Obsoleted.Version);
2762 }
2763
2764 bool IsUnavailable = AL.getUnavailableLoc().isValid();
2765 bool IsStrict = AL.getStrictLoc().isValid();
2766 StringRef Str;
2767 if (const auto *SE = dyn_cast_if_present<StringLiteral>(AL.getMessageExpr()))
2768 Str = SE->getString();
2769 StringRef Replacement;
2770 if (const auto *SE =
2771 dyn_cast_if_present<StringLiteral>(AL.getReplacementExpr()))
2772 Replacement = SE->getString();
2773
2774 if (II->isStr("swift")) {
2775 if (Introduced.isValid() || Obsoleted.isValid() ||
2776 (!IsUnavailable && !Deprecated.isValid())) {
2777 S.Diag(AL.getLoc(),
2778 diag::warn_availability_swift_unavailable_deprecated_only);
2779 return;
2780 }
2781 }
2782
2783 if (II->isStr("fuchsia")) {
2784 std::optional<unsigned> Min, Sub;
2785 if ((Min = Introduced.Version.getMinor()) ||
2786 (Sub = Introduced.Version.getSubminor())) {
2787 S.Diag(AL.getLoc(), diag::warn_availability_fuchsia_unavailable_minor);
2788 return;
2789 }
2790 }
2791
2792 if (S.getLangOpts().HLSL && IsStrict)
2793 S.Diag(AL.getStrictLoc(), diag::err_availability_unexpected_parameter)
2794 << "strict" << /* HLSL */ 0;
2795
2796 int PriorityModifier = AL.isPragmaClangAttribute()
2799
2800 const IdentifierLoc *EnvironmentLoc = AL.getEnvironment();
2801 IdentifierInfo *IIEnvironment = nullptr;
2802 if (EnvironmentLoc) {
2803 if (S.getLangOpts().HLSL) {
2804 IIEnvironment = EnvironmentLoc->getIdentifierInfo();
2805 if (AvailabilityAttr::getEnvironmentType(
2806 EnvironmentLoc->getIdentifierInfo()->getName()) ==
2807 llvm::Triple::EnvironmentType::UnknownEnvironment)
2808 S.Diag(EnvironmentLoc->getLoc(),
2809 diag::warn_availability_unknown_environment)
2810 << EnvironmentLoc->getIdentifierInfo();
2811 } else {
2812 S.Diag(EnvironmentLoc->getLoc(),
2813 diag::err_availability_unexpected_parameter)
2814 << "environment" << /* C/C++ */ 1;
2815 }
2816 }
2817
2818 // Handle anyAppleOS: preserve the original anyappleos attr on the decl and
2819 // store the inferred platform-specific attr as a field on it.
2820 if (II->getName() == "anyappleos") {
2821 // Validate anyAppleOS versions; reject versions older than 26.0.
2822 auto ValidateVersion = [&](const llvm::VersionTuple &Version,
2823 SourceLocation Loc) -> bool {
2825 return true;
2826 S.Diag(Loc, diag::err_availability_invalid_anyappleos_version)
2827 << Version.getAsString();
2828 return false;
2829 };
2830
2831 // Validate the versions; bail out if any are invalid.
2832 bool Valid = ValidateVersion(Introduced.Version, Introduced.KeywordLoc);
2833 Valid &= ValidateVersion(Deprecated.Version, Deprecated.KeywordLoc);
2834 Valid &= ValidateVersion(Obsoleted.Version, Obsoleted.KeywordLoc);
2835 if (!Valid)
2836 return;
2837
2838 llvm::Triple T = S.Context.getTargetInfo().getTriple();
2839
2840 // Only create implicit attributes for Darwin OSes.
2841 if (!T.isOSDarwin())
2842 return;
2843
2844 StringRef PlatformName;
2845
2846 // Determine the platform name based on the target triple.
2847 if (T.isMacOSX())
2848 PlatformName = "macos";
2849 else if (T.getOS() == llvm::Triple::IOS && T.isMacCatalystEnvironment())
2850 PlatformName = "maccatalyst";
2851 else // For iOS, tvOS, watchOS, visionOS, bridgeOS, etc.
2852 PlatformName = llvm::Triple::getOSTypeName(T.getOS());
2853
2854 IdentifierInfo *InferredPlatformII = &S.Context.Idents.get(PlatformName);
2855
2856 // Call mergeAvailabilityAttr for the original anyappleos attr. Pass
2857 // InferredPlatformII so the dedup loop can detect a conflicting explicit
2858 // platform attr (in which case mergeAvailabilityAttr returns null and we
2859 // add neither attr).
2860 AvailabilityAttr *OrigAttr = S.mergeAndInferAvailabilityAttr(
2861 ND, AL, II, /*Implicit=*/false, Introduced.Version, Deprecated.Version,
2862 Obsoleted.Version, IsUnavailable, Str, IsStrict, Replacement,
2863 AvailabilityMergeKind::None, PriorityModifier, IIEnvironment,
2864 InferredPlatformII);
2865 if (!OrigAttr)
2866 return;
2867 D->addAttr(OrigAttr);
2868 return;
2869 }
2870
2871 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2872 ND, AL, II, false /*Implicit*/, Introduced.Version, Deprecated.Version,
2873 Obsoleted.Version, IsUnavailable, Str, IsStrict, Replacement,
2874 AvailabilityMergeKind::None, PriorityModifier, IIEnvironment);
2875 if (NewAttr)
2876 D->addAttr(NewAttr);
2877
2878 if (S.Context.getTargetInfo().getTriple().getOS() == llvm::Triple::XROS) {
2879 IdentifierInfo *NewII = II;
2880 bool NewIsUnavailable = IsUnavailable;
2881 VersionTuple NewIntroduced = Introduced.Version;
2882 VersionTuple NewDeprecated = Deprecated.Version;
2883 VersionTuple NewObsoleted = Obsoleted.Version;
2884 if (shouldInferAvailabilityAttribute(AL, NewII, NewIsUnavailable,
2885 NewIntroduced, NewDeprecated,
2886 NewObsoleted, S)) {
2887 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2888 ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
2889 NewObsoleted, NewIsUnavailable, Str, IsStrict, Replacement,
2891 PriorityModifier + Sema::AP_InferredFromOtherPlatform, IIEnvironment);
2892 if (NewAttr)
2893 D->addAttr(NewAttr);
2894 }
2895 }
2896
2897 // Transcribe "ios" to "watchos" (and add a new attribute) if the versioning
2898 // matches before the start of the watchOS platform.
2899 if (S.Context.getTargetInfo().getTriple().isWatchOS()) {
2900 IdentifierInfo *NewII = nullptr;
2901 if (II->getName() == "ios")
2902 NewII = &S.Context.Idents.get("watchos");
2903 else if (II->getName() == "ios_app_extension")
2904 NewII = &S.Context.Idents.get("watchos_app_extension");
2905
2906 if (NewII) {
2907 const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking();
2908 const auto *IOSToWatchOSMapping =
2909 SDKInfo ? SDKInfo->getVersionMapping(
2911 : nullptr;
2912
2913 auto adjustWatchOSVersion =
2914 [IOSToWatchOSMapping](VersionTuple Version) -> VersionTuple {
2915 if (Version.empty())
2916 return Version;
2917 auto MinimumWatchOSVersion = VersionTuple(2, 0);
2918
2919 if (IOSToWatchOSMapping) {
2920 if (auto MappedVersion = IOSToWatchOSMapping->map(
2921 Version, MinimumWatchOSVersion, std::nullopt)) {
2922 return *MappedVersion;
2923 }
2924 }
2925
2926 auto Major = Version.getMajor();
2927 auto NewMajor = Major;
2928 if (Major < 9)
2929 NewMajor = 0;
2930 else if (Major < 12)
2931 NewMajor = Major - 7;
2932 if (NewMajor >= 2) {
2933 if (Version.getMinor()) {
2934 if (Version.getSubminor())
2935 return VersionTuple(NewMajor, *Version.getMinor(),
2936 *Version.getSubminor());
2937 else
2938 return VersionTuple(NewMajor, *Version.getMinor());
2939 }
2940 return VersionTuple(NewMajor);
2941 }
2942
2943 return MinimumWatchOSVersion;
2944 };
2945
2946 auto NewIntroduced = adjustWatchOSVersion(Introduced.Version);
2947 auto NewDeprecated = adjustWatchOSVersion(Deprecated.Version);
2948 auto NewObsoleted = adjustWatchOSVersion(Obsoleted.Version);
2949
2950 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2951 ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
2952 NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,
2954 PriorityModifier + Sema::AP_InferredFromOtherPlatform, IIEnvironment);
2955 if (NewAttr)
2956 D->addAttr(NewAttr);
2957 }
2958 } else if (S.Context.getTargetInfo().getTriple().isTvOS()) {
2959 // Transcribe "ios" to "tvos" (and add a new attribute) if the versioning
2960 // matches before the start of the tvOS platform.
2961 IdentifierInfo *NewII = nullptr;
2962 if (II->getName() == "ios")
2963 NewII = &S.Context.Idents.get("tvos");
2964 else if (II->getName() == "ios_app_extension")
2965 NewII = &S.Context.Idents.get("tvos_app_extension");
2966
2967 if (NewII) {
2968 const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking();
2969 const auto *IOSToTvOSMapping =
2970 SDKInfo ? SDKInfo->getVersionMapping(
2972 : nullptr;
2973
2974 auto AdjustTvOSVersion =
2975 [IOSToTvOSMapping](VersionTuple Version) -> VersionTuple {
2976 if (Version.empty())
2977 return Version;
2978
2979 if (IOSToTvOSMapping) {
2980 if (auto MappedVersion = IOSToTvOSMapping->map(
2981 Version, VersionTuple(0, 0), std::nullopt)) {
2982 return *MappedVersion;
2983 }
2984 }
2985 return Version;
2986 };
2987
2988 auto NewIntroduced = AdjustTvOSVersion(Introduced.Version);
2989 auto NewDeprecated = AdjustTvOSVersion(Deprecated.Version);
2990 auto NewObsoleted = AdjustTvOSVersion(Obsoleted.Version);
2991
2992 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2993 ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
2994 NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,
2996 PriorityModifier + Sema::AP_InferredFromOtherPlatform, IIEnvironment);
2997 if (NewAttr)
2998 D->addAttr(NewAttr);
2999 }
3000 } else if (S.Context.getTargetInfo().getTriple().getOS() ==
3001 llvm::Triple::IOS &&
3002 S.Context.getTargetInfo().getTriple().isMacCatalystEnvironment()) {
3003 auto GetSDKInfo = [&]() {
3005 "macOS");
3006 };
3007
3008 // Transcribe "ios" to "maccatalyst" (and add a new attribute).
3009 IdentifierInfo *NewII = nullptr;
3010 if (II->getName() == "ios")
3011 NewII = &S.Context.Idents.get("maccatalyst");
3012 else if (II->getName() == "ios_app_extension")
3013 NewII = &S.Context.Idents.get("maccatalyst_app_extension");
3014 if (NewII) {
3015 auto MinMacCatalystVersion = [](const VersionTuple &V) {
3016 if (V.empty())
3017 return V;
3018 if (V.getMajor() < 13 ||
3019 (V.getMajor() == 13 && V.getMinor() && *V.getMinor() < 1))
3020 return VersionTuple(13, 1); // The min Mac Catalyst version is 13.1.
3021 return V;
3022 };
3023 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
3024 ND, AL, NewII, true /*Implicit*/,
3025 MinMacCatalystVersion(Introduced.Version),
3026 MinMacCatalystVersion(Deprecated.Version),
3027 MinMacCatalystVersion(Obsoleted.Version), IsUnavailable, Str,
3028 IsStrict, Replacement, AvailabilityMergeKind::None,
3029 PriorityModifier + Sema::AP_InferredFromOtherPlatform, IIEnvironment);
3030 if (NewAttr)
3031 D->addAttr(NewAttr);
3032 } else if (II->getName() == "macos" && GetSDKInfo() &&
3033 (!Introduced.Version.empty() || !Deprecated.Version.empty() ||
3034 !Obsoleted.Version.empty())) {
3035 if (const auto *MacOStoMacCatalystMapping =
3036 GetSDKInfo()->getVersionMapping(
3038 // Infer Mac Catalyst availability from the macOS availability attribute
3039 // if it has versioned availability. Don't infer 'unavailable'. This
3040 // inferred availability has lower priority than the other availability
3041 // attributes that are inferred from 'ios'.
3042 NewII = &S.Context.Idents.get("maccatalyst");
3043 auto RemapMacOSVersion =
3044 [&](const VersionTuple &V) -> std::optional<VersionTuple> {
3045 if (V.empty())
3046 return std::nullopt;
3047 // API_TO_BE_DEPRECATED is 100000.
3048 if (V.getMajor() == 100000)
3049 return VersionTuple(100000);
3050 // The minimum iosmac version is 13.1
3051 return MacOStoMacCatalystMapping->map(V, VersionTuple(13, 1),
3052 std::nullopt);
3053 };
3054 std::optional<VersionTuple> NewIntroduced =
3055 RemapMacOSVersion(Introduced.Version),
3056 NewDeprecated =
3057 RemapMacOSVersion(Deprecated.Version),
3058 NewObsoleted =
3059 RemapMacOSVersion(Obsoleted.Version);
3060 if (NewIntroduced || NewDeprecated || NewObsoleted) {
3061 auto VersionOrEmptyVersion =
3062 [](const std::optional<VersionTuple> &V) -> VersionTuple {
3063 return V ? *V : VersionTuple();
3064 };
3065 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
3066 ND, AL, NewII, true /*Implicit*/,
3067 VersionOrEmptyVersion(NewIntroduced),
3068 VersionOrEmptyVersion(NewDeprecated),
3069 VersionOrEmptyVersion(NewObsoleted), /*IsUnavailable=*/false, Str,
3070 IsStrict, Replacement, AvailabilityMergeKind::None,
3071 PriorityModifier + Sema::AP_InferredFromOtherPlatform +
3073 IIEnvironment);
3074 if (NewAttr)
3075 D->addAttr(NewAttr);
3076 }
3077 }
3078 }
3079 }
3080}
3081
3083 const ParsedAttr &AL) {
3084 if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 4))
3085 return;
3086
3087 StringRef Language;
3088 if (const auto *SE = dyn_cast_if_present<StringLiteral>(AL.getArgAsExpr(0)))
3089 Language = SE->getString();
3090 StringRef DefinedIn;
3091 if (const auto *SE = dyn_cast_if_present<StringLiteral>(AL.getArgAsExpr(1)))
3092 DefinedIn = SE->getString();
3093 bool IsGeneratedDeclaration = AL.getArgAsIdent(2) != nullptr;
3094 StringRef USR;
3095 if (const auto *SE = dyn_cast_if_present<StringLiteral>(AL.getArgAsExpr(3)))
3096 USR = SE->getString();
3097
3098 D->addAttr(::new (S.Context) ExternalSourceSymbolAttr(
3099 S.Context, AL, Language, DefinedIn, IsGeneratedDeclaration, USR));
3100}
3101
3103 VisibilityAttr::VisibilityType Value) {
3104 if (VisibilityAttr *Attr = D->getAttr<VisibilityAttr>()) {
3105 if (Attr->getVisibility() != Value)
3106 Diag(Loc, diag::err_mismatched_visibility);
3107 } else
3108 D->addAttr(VisibilityAttr::CreateImplicit(Context, Value));
3109}
3110
3111template <class T>
3113 typename T::VisibilityType value) {
3114 T *existingAttr = D->getAttr<T>();
3115 if (existingAttr) {
3116 typename T::VisibilityType existingValue = existingAttr->getVisibility();
3117 if (existingValue == value)
3118 return nullptr;
3119 S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
3120 S.Diag(CI.getLoc(), diag::note_previous_attribute);
3121 D->dropAttr<T>();
3122 }
3123 return ::new (S.Context) T(S.Context, CI, value);
3124}
3125
3127 const AttributeCommonInfo &CI,
3128 VisibilityAttr::VisibilityType Vis) {
3129 return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, CI, Vis);
3130}
3131
3132TypeVisibilityAttr *
3134 TypeVisibilityAttr::VisibilityType Vis) {
3135 return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, CI, Vis);
3136}
3137
3138static void handleVisibilityAttr(Sema &S, Decl *D, const ParsedAttr &AL,
3139 bool isTypeVisibility) {
3140 // Visibility attributes don't mean anything on a typedef.
3141 if (isa<TypedefNameDecl>(D)) {
3142 S.Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored) << AL;
3143 return;
3144 }
3145
3146 // 'type_visibility' can only go on a type or namespace.
3147 if (isTypeVisibility && !(isa<TagDecl>(D) || isa<ObjCInterfaceDecl>(D) ||
3148 isa<NamespaceDecl>(D))) {
3149 S.Diag(AL.getRange().getBegin(), diag::err_attribute_wrong_decl_type)
3151 return;
3152 }
3153
3154 // Check that the argument is a string literal.
3155 StringRef TypeStr;
3156 SourceLocation LiteralLoc;
3157 if (!S.checkStringLiteralArgumentAttr(AL, 0, TypeStr, &LiteralLoc))
3158 return;
3159
3160 VisibilityAttr::VisibilityType type;
3161 if (!VisibilityAttr::ConvertStrToVisibilityType(TypeStr, type)) {
3162 S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported) << AL
3163 << TypeStr;
3164 return;
3165 }
3166
3167 // Complain about attempts to use protected visibility on targets
3168 // (like Darwin) that don't support it.
3169 if (type == VisibilityAttr::Protected &&
3171 S.Diag(AL.getLoc(), diag::warn_attribute_protected_visibility);
3172 type = VisibilityAttr::Default;
3173 }
3174
3175 Attr *newAttr;
3176 if (isTypeVisibility) {
3177 newAttr = S.mergeTypeVisibilityAttr(
3178 D, AL, (TypeVisibilityAttr::VisibilityType)type);
3179 } else {
3180 newAttr = S.mergeVisibilityAttr(D, AL, type);
3181 }
3182 if (newAttr)
3183 D->addAttr(newAttr);
3184}
3185
3186static void handleSentinelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3187 unsigned sentinel = (unsigned)SentinelAttr::DefaultSentinel;
3188 if (AL.getNumArgs() > 0) {
3189 Expr *E = AL.getArgAsExpr(0);
3190 std::optional<llvm::APSInt> Idx = llvm::APSInt(32);
3191 if (E->isTypeDependent() || !(Idx = E->getIntegerConstantExpr(S.Context))) {
3192 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3193 << AL << 1 << AANT_ArgumentIntegerConstant << E->getSourceRange();
3194 return;
3195 }
3196
3197 if (Idx->isSigned() && Idx->isNegative()) {
3198 S.Diag(AL.getLoc(), diag::err_attribute_sentinel_less_than_zero)
3199 << E->getSourceRange();
3200 return;
3201 }
3202
3203 sentinel = Idx->getZExtValue();
3204 }
3205
3206 unsigned nullPos = (unsigned)SentinelAttr::DefaultNullPos;
3207 if (AL.getNumArgs() > 1) {
3208 Expr *E = AL.getArgAsExpr(1);
3209 std::optional<llvm::APSInt> Idx = llvm::APSInt(32);
3210 if (E->isTypeDependent() || !(Idx = E->getIntegerConstantExpr(S.Context))) {
3211 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3212 << AL << 2 << AANT_ArgumentIntegerConstant << E->getSourceRange();
3213 return;
3214 }
3215 nullPos = Idx->getZExtValue();
3216
3217 if ((Idx->isSigned() && Idx->isNegative()) || nullPos > 1) {
3218 // FIXME: This error message could be improved, it would be nice
3219 // to say what the bounds actually are.
3220 S.Diag(AL.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
3221 << E->getSourceRange();
3222 return;
3223 }
3224 }
3225
3226 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3227 const FunctionType *FT = FD->getType()->castAs<FunctionType>();
3228 if (isa<FunctionNoProtoType>(FT)) {
3229 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_named_arguments);
3230 return;
3231 }
3232
3233 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
3234 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
3235 return;
3236 }
3237 } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
3238 if (!MD->isVariadic()) {
3239 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
3240 return;
3241 }
3242 } else if (const auto *BD = dyn_cast<BlockDecl>(D)) {
3243 if (!BD->isVariadic()) {
3244 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
3245 return;
3246 }
3247 } else if (const auto *V = dyn_cast<VarDecl>(D)) {
3248 QualType Ty = V->getType();
3249 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
3250 const FunctionType *FT = Ty->isFunctionPointerType()
3251 ? D->getFunctionType()
3252 : Ty->castAs<BlockPointerType>()
3253 ->getPointeeType()
3254 ->castAs<FunctionType>();
3255 if (isa<FunctionNoProtoType>(FT)) {
3256 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_named_arguments);
3257 return;
3258 }
3259 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
3260 int m = Ty->isFunctionPointerType() ? 0 : 1;
3261 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
3262 return;
3263 }
3264 } else {
3265 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
3266 << AL << AL.isRegularKeywordAttribute()
3268 return;
3269 }
3270 } else {
3271 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
3272 << AL << AL.isRegularKeywordAttribute()
3274 return;
3275 }
3276 D->addAttr(::new (S.Context) SentinelAttr(S.Context, AL, sentinel, nullPos));
3277}
3278
3279static void handleWarnUnusedResult(Sema &S, Decl *D, const ParsedAttr &AL) {
3280 if (D->getFunctionType() &&
3283 S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) << AL << 0;
3284 return;
3285 }
3286 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
3287 if (MD->getReturnType()->isVoidType()) {
3288 S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) << AL << 1;
3289 return;
3290 }
3291
3292 StringRef Str;
3293 if (AL.isStandardAttributeSyntax()) {
3294 // If this is spelled [[clang::warn_unused_result]] we look for an optional
3295 // string literal. This is not gated behind any specific version of the
3296 // standard.
3297 if (AL.isClangScope()) {
3298 if (AL.getNumArgs() == 1 &&
3299 !S.checkStringLiteralArgumentAttr(AL, 0, Str, nullptr))
3300 return;
3301 } else if (!AL.getScopeName()) {
3302 // The standard attribute cannot be applied to variable declarations such
3303 // as a function pointer.
3304 if (isa<VarDecl>(D))
3305 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
3306 << AL << AL.isRegularKeywordAttribute()
3308
3309 // If this is spelled as the standard C++17 attribute, but not in C++17,
3310 // warn about using it as an extension. If there are attribute arguments,
3311 // then claim it's a C++20 extension instead. C23 supports this attribute
3312 // with the message; no extension warning is needed there beyond the one
3313 // already issued for accepting attributes in older modes.
3314 const LangOptions &LO = S.getLangOpts();
3315 if (AL.getNumArgs() == 1) {
3316 if (LO.CPlusPlus && !LO.CPlusPlus20)
3317 S.Diag(AL.getLoc(), diag::ext_cxx20_attr) << AL;
3318
3319 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, nullptr))
3320 return;
3321 } else if (LO.CPlusPlus && !LO.CPlusPlus17)
3322 S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
3323 }
3324 }
3325
3326 if ((!AL.isGNUAttribute() &&
3327 !(AL.isStandardAttributeSyntax() && AL.isClangScope())) &&
3329 S.Diag(AL.getLoc(), diag::warn_unused_result_typedef_unsupported_spelling)
3330 << AL.isGNUScope();
3331 return;
3332 }
3333
3334 D->addAttr(::new (S.Context) WarnUnusedResultAttr(S.Context, AL, Str));
3335}
3336
3337static void handleWeakImportAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3338 // weak_import only applies to variable & function declarations.
3339 bool isDef = false;
3340 if (!D->canBeWeakImported(isDef)) {
3341 if (isDef)
3342 S.Diag(AL.getLoc(), diag::warn_attribute_invalid_on_definition)
3343 << "weak_import";
3344 else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
3345 (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
3347 // Nothing to warn about here.
3348 } else
3349 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
3351
3352 return;
3353 }
3354
3355 D->addAttr(::new (S.Context) WeakImportAttr(S.Context, AL));
3356}
3357
3358// Checks whether an argument of launch_bounds-like attribute is
3359// acceptable, performs implicit conversion to Rvalue, and returns
3360// non-nullptr Expr result on success. Otherwise, it returns nullptr
3361// and may output an error.
3362template <class Attribute>
3363static Expr *makeAttributeArgExpr(Sema &S, Expr *E, const Attribute &Attr,
3364 const unsigned Idx) {
3366 return nullptr;
3367
3368 // Accept template arguments for now as they depend on something else.
3369 // We'll get to check them when they eventually get instantiated.
3370 if (E->isValueDependent())
3371 return E;
3372
3373 std::optional<llvm::APSInt> I = llvm::APSInt(64);
3374 if (!(I = E->getIntegerConstantExpr(S.Context))) {
3375 S.Diag(E->getExprLoc(), diag::err_attribute_argument_n_type)
3376 << &Attr << Idx << AANT_ArgumentIntegerConstant << E->getSourceRange();
3377 return nullptr;
3378 }
3379 // Make sure we can fit it in 32 bits.
3380 if (!I->isIntN(32)) {
3381 S.Diag(E->getExprLoc(), diag::err_ice_too_large)
3382 << toString(*I, 10, false) << 32 << /* Unsigned */ 1;
3383 return nullptr;
3384 }
3385 if (*I < 0)
3386 S.Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer)
3387 << &Attr << /*non-negative*/ 1 << E->getSourceRange();
3388
3389 // We may need to perform implicit conversion of the argument.
3391 S.Context, S.Context.getConstType(S.Context.IntTy), /*consume*/ false);
3392 ExprResult ValArg = S.PerformCopyInitialization(Entity, SourceLocation(), E);
3393 assert(!ValArg.isInvalid() &&
3394 "Unexpected PerformCopyInitialization() failure.");
3395
3396 return ValArg.getAs<Expr>();
3397}
3398
3399// Handles reqd_work_group_size and work_group_size_hint.
3400template <typename WorkGroupAttr>
3401static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
3402 Expr *WGSize[3];
3403 for (unsigned i = 0; i < 3; ++i) {
3404 if (Expr *E = makeAttributeArgExpr(S, AL.getArgAsExpr(i), AL, i))
3405 WGSize[i] = E;
3406 else
3407 return;
3408 }
3409
3410 auto IsZero = [&](Expr *E) {
3411 if (E->isValueDependent())
3412 return false;
3413 std::optional<llvm::APSInt> I = E->getIntegerConstantExpr(S.Context);
3414 assert(I && "Non-integer constant expr");
3415 return I->isZero();
3416 };
3417
3418 if (!llvm::all_of(WGSize, IsZero)) {
3419 for (unsigned i = 0; i < 3; ++i) {
3420 const Expr *E = AL.getArgAsExpr(i);
3421 if (IsZero(WGSize[i])) {
3422 S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
3423 << AL << E->getSourceRange();
3424 return;
3425 }
3426 }
3427 }
3428
3429 auto Equal = [&](Expr *LHS, Expr *RHS) {
3430 if (LHS->isValueDependent() || RHS->isValueDependent())
3431 return true;
3432 std::optional<llvm::APSInt> L = LHS->getIntegerConstantExpr(S.Context);
3433 assert(L && "Non-integer constant expr");
3434 std::optional<llvm::APSInt> R = RHS->getIntegerConstantExpr(S.Context);
3435 assert(L && "Non-integer constant expr");
3436 return L == R;
3437 };
3438
3439 WorkGroupAttr *Existing = D->getAttr<WorkGroupAttr>();
3440 if (Existing &&
3441 !llvm::equal(std::initializer_list<Expr *>{Existing->getXDim(),
3442 Existing->getYDim(),
3443 Existing->getZDim()},
3444 WGSize, Equal))
3445 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3446
3447 D->addAttr(::new (S.Context)
3448 WorkGroupAttr(S.Context, AL, WGSize[0], WGSize[1], WGSize[2]));
3449}
3450
3451static void handleVecTypeHint(Sema &S, Decl *D, const ParsedAttr &AL) {
3452 if (!AL.hasParsedType()) {
3453 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
3454 return;
3455 }
3456
3457 TypeSourceInfo *ParmTSI = nullptr;
3458 QualType ParmType = S.GetTypeFromParser(AL.getTypeArg(), &ParmTSI);
3459 assert(ParmTSI && "no type source info for attribute argument");
3460
3461 if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() &&
3462 (ParmType->isBooleanType() ||
3463 !ParmType->isIntegralType(S.getASTContext()))) {
3464 S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument) << 2 << AL;
3465 return;
3466 }
3467
3468 if (VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>()) {
3469 if (!S.Context.hasSameType(A->getTypeHint(), ParmType)) {
3470 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3471 return;
3472 }
3473 }
3474
3475 D->addAttr(::new (S.Context) VecTypeHintAttr(S.Context, AL, ParmTSI));
3476}
3477
3479 StringRef Name) {
3480 // Explicit or partial specializations do not inherit
3481 // the section attribute from the primary template.
3482 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3483 if (CI.getAttributeSpellingListIndex() == SectionAttr::Declspec_allocate &&
3485 return nullptr;
3486 }
3487 if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
3488 if (ExistingAttr->getName() == Name)
3489 return nullptr;
3490 Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section)
3491 << 1 /*section*/;
3492 Diag(CI.getLoc(), diag::note_previous_attribute);
3493 return nullptr;
3494 }
3495 return ::new (Context) SectionAttr(Context, CI, Name);
3496}
3497
3498llvm::Error Sema::isValidSectionSpecifier(StringRef SecName) {
3499 if (!Context.getTargetInfo().getTriple().isOSDarwin())
3500 return llvm::Error::success();
3501
3502 // Let MCSectionMachO validate this.
3503 StringRef Segment, Section;
3504 unsigned TAA, StubSize;
3505 bool HasTAA;
3506 return llvm::MCSectionMachO::ParseSectionSpecifier(SecName, Segment, Section,
3507 TAA, HasTAA, StubSize);
3508}
3509
3510bool Sema::checkSectionName(SourceLocation LiteralLoc, StringRef SecName) {
3511 if (llvm::Error E = isValidSectionSpecifier(SecName)) {
3512 Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
3513 << toString(std::move(E)) << 1 /*'section'*/;
3514 return false;
3515 }
3516 return true;
3517}
3518
3519static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3520 // Make sure that there is a string literal as the sections's single
3521 // argument.
3522 StringRef Str;
3523 SourceLocation LiteralLoc;
3524 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))
3525 return;
3526
3527 if (!S.checkSectionName(LiteralLoc, Str))
3528 return;
3529
3530 SectionAttr *NewAttr = S.mergeSectionAttr(D, AL, Str);
3531 if (NewAttr) {
3532 D->addAttr(NewAttr);
3534 ObjCPropertyDecl>(D))
3535 S.UnifySection(NewAttr->getName(),
3537 cast<NamedDecl>(D));
3538 }
3539}
3540
3541static bool isValidCodeModelAttr(llvm::Triple &Triple, StringRef Str) {
3542 if (Triple.isLoongArch()) {
3543 return Str == "normal" || Str == "medium" || Str == "extreme";
3544 } else {
3545 assert(Triple.getArch() == llvm::Triple::x86_64 &&
3546 "only loongarch/x86-64 supported");
3547 return Str == "small" || Str == "large";
3548 }
3549}
3550
3551static void handleCodeModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3552 StringRef Str;
3553 SourceLocation LiteralLoc;
3554 auto IsTripleSupported = [](llvm::Triple &Triple) {
3555 return Triple.getArch() == llvm::Triple::ArchType::x86_64 ||
3556 Triple.isLoongArch();
3557 };
3558
3559 // Check that it is a string.
3560 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))
3561 return;
3562
3565 if (auto *aux = S.Context.getAuxTargetInfo()) {
3566 Triples.push_back(aux->getTriple());
3567 } else if (S.Context.getTargetInfo().getTriple().isNVPTX() ||
3568 S.Context.getTargetInfo().getTriple().isAMDGPU() ||
3569 S.Context.getTargetInfo().getTriple().isSPIRV()) {
3570 // Ignore the attribute for pure GPU device compiles since it only applies
3571 // to host globals.
3572 return;
3573 }
3574
3575 auto SupportedTripleIt = llvm::find_if(Triples, IsTripleSupported);
3576 if (SupportedTripleIt == Triples.end()) {
3577 S.Diag(LiteralLoc, diag::warn_unknown_attribute_ignored) << AL;
3578 return;
3579 }
3580
3581 llvm::CodeModel::Model CM;
3582 if (!CodeModelAttr::ConvertStrToModel(Str, CM) ||
3583 !isValidCodeModelAttr(*SupportedTripleIt, Str)) {
3584 S.Diag(LiteralLoc, diag::err_attr_codemodel_arg) << Str;
3585 return;
3586 }
3587
3588 D->addAttr(::new (S.Context) CodeModelAttr(S.Context, AL, CM));
3589}
3590
3591// This is used for `__declspec(code_seg("segname"))` on a decl.
3592// `#pragma code_seg("segname")` uses checkSectionName() instead.
3593static bool checkCodeSegName(Sema &S, SourceLocation LiteralLoc,
3594 StringRef CodeSegName) {
3595 if (llvm::Error E = S.isValidSectionSpecifier(CodeSegName)) {
3596 S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
3597 << toString(std::move(E)) << 0 /*'code-seg'*/;
3598 return false;
3599 }
3600
3601 return true;
3602}
3603
3605 StringRef Name) {
3606 // Explicit or partial specializations do not inherit
3607 // the code_seg attribute from the primary template.
3608 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3610 return nullptr;
3611 }
3612 if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) {
3613 if (ExistingAttr->getName() == Name)
3614 return nullptr;
3615 Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section)
3616 << 0 /*codeseg*/;
3617 Diag(CI.getLoc(), diag::note_previous_attribute);
3618 return nullptr;
3619 }
3620 return ::new (Context) CodeSegAttr(Context, CI, Name);
3621}
3622
3623static void handleCodeSegAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3624 StringRef Str;
3625 SourceLocation LiteralLoc;
3626 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))
3627 return;
3628 if (!checkCodeSegName(S, LiteralLoc, Str))
3629 return;
3630 if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) {
3631 if (!ExistingAttr->isImplicit()) {
3632 S.Diag(AL.getLoc(),
3633 ExistingAttr->getName() == Str
3634 ? diag::warn_duplicate_codeseg_attribute
3635 : diag::err_conflicting_codeseg_attribute);
3636 return;
3637 }
3638 D->dropAttr<CodeSegAttr>();
3639 }
3640 if (CodeSegAttr *CSA = S.mergeCodeSegAttr(D, AL, Str))
3641 D->addAttr(CSA);
3642}
3643
3644bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) {
3645 using namespace DiagAttrParams;
3646
3647 if (AttrStr.contains("fpmath="))
3648 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3649 << Unsupported << None << "fpmath=" << Target;
3650
3651 // Diagnose use of tune if target doesn't support it.
3652 if (!Context.getTargetInfo().supportsTargetAttributeTune() &&
3653 AttrStr.contains("tune="))
3654 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3655 << Unsupported << None << "tune=" << Target;
3656
3657 ParsedTargetAttr ParsedAttrs =
3658 Context.getTargetInfo().parseTargetAttr(AttrStr);
3659
3660 if (!ParsedAttrs.CPU.empty() &&
3661 !Context.getTargetInfo().isValidCPUName(ParsedAttrs.CPU))
3662 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3663 << Unknown << CPU << ParsedAttrs.CPU << Target;
3664
3665 if (!ParsedAttrs.Tune.empty() &&
3666 !Context.getTargetInfo().isValidCPUName(ParsedAttrs.Tune))
3667 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3668 << Unknown << Tune << ParsedAttrs.Tune << Target;
3669
3670 if (Context.getTargetInfo().getTriple().isRISCV()) {
3671 if (ParsedAttrs.Duplicate != "")
3672 return Diag(LiteralLoc, diag::err_duplicate_target_attribute)
3673 << Duplicate << None << ParsedAttrs.Duplicate << Target;
3674 for (StringRef CurFeature : ParsedAttrs.Features) {
3675 if (!CurFeature.starts_with('+') && !CurFeature.starts_with('-'))
3676 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3677 << Unsupported << None << AttrStr << Target;
3678 }
3679 }
3680
3681 if (Context.getTargetInfo().getTriple().isLoongArch()) {
3682 for (StringRef CurFeature : ParsedAttrs.Features) {
3683 if (CurFeature.starts_with("!arch=")) {
3684 StringRef ArchValue = CurFeature.split("=").second.trim();
3685 return Diag(LiteralLoc, diag::err_attribute_unsupported)
3686 << "target(arch=..)" << ArchValue;
3687 }
3688 }
3689 }
3690
3691 if (ParsedAttrs.Duplicate != "")
3692 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3693 << Duplicate << None << ParsedAttrs.Duplicate << Target;
3694
3695 for (const auto &Feature : ParsedAttrs.Features) {
3696 auto CurFeature = StringRef(Feature).drop_front(); // remove + or -.
3697 if (!Context.getTargetInfo().isValidFeatureName(CurFeature))
3698 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3699 << Unsupported << None << CurFeature << Target;
3700 }
3701
3703 StringRef DiagMsg;
3704 if (ParsedAttrs.BranchProtection.empty())
3705 return false;
3706 if (!Context.getTargetInfo().validateBranchProtection(
3707 ParsedAttrs.BranchProtection, ParsedAttrs.CPU, BPI,
3708 Context.getLangOpts(), DiagMsg)) {
3709 if (DiagMsg.empty())
3710 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3711 << Unsupported << None << "branch-protection" << Target;
3712 return Diag(LiteralLoc, diag::err_invalid_branch_protection_spec)
3713 << DiagMsg;
3714 }
3715 if (!DiagMsg.empty())
3716 Diag(LiteralLoc, diag::warn_unsupported_branch_protection_spec) << DiagMsg;
3717
3718 return false;
3719}
3720
3721static void handleTargetVersionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3722 StringRef Param;
3723 SourceLocation Loc;
3724 SmallString<64> NewParam;
3725 if (!S.checkStringLiteralArgumentAttr(AL, 0, Param, &Loc))
3726 return;
3727
3728 if (S.Context.getTargetInfo().getTriple().isAArch64()) {
3729 if (S.ARM().checkTargetVersionAttr(Param, Loc, NewParam))
3730 return;
3731 } else if (S.Context.getTargetInfo().getTriple().isRISCV()) {
3732 if (S.RISCV().checkTargetVersionAttr(Param, Loc, NewParam))
3733 return;
3734 }
3735
3736 TargetVersionAttr *NewAttr =
3737 ::new (S.Context) TargetVersionAttr(S.Context, AL, NewParam);
3738 D->addAttr(NewAttr);
3739}
3740
3741static void handleTargetAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3742 StringRef Str;
3743 SourceLocation LiteralLoc;
3744 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc) ||
3745 S.checkTargetAttr(LiteralLoc, Str))
3746 return;
3747
3748 TargetAttr *NewAttr = ::new (S.Context) TargetAttr(S.Context, AL, Str);
3749 D->addAttr(NewAttr);
3750}
3751
3752static void handleTargetClonesAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3753 // Ensure we don't combine these with themselves, since that causes some
3754 // confusing behavior.
3755 if (const auto *Other = D->getAttr<TargetClonesAttr>()) {
3756 S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL;
3757 S.Diag(Other->getLocation(), diag::note_conflicting_attribute);
3758 return;
3759 }
3761 return;
3762
3763 // FIXME: We could probably figure out how to get this to work for lambdas
3764 // someday.
3765 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
3766 if (MD->getParent()->isLambda()) {
3767 S.Diag(D->getLocation(), diag::err_multiversion_doesnt_support)
3768 << static_cast<unsigned>(MultiVersionKind::TargetClones)
3769 << /*Lambda*/ 9;
3770 return;
3771 }
3772 }
3773
3776 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
3777 StringRef Param;
3778 SourceLocation Loc;
3779 if (!S.checkStringLiteralArgumentAttr(AL, I, Param, &Loc))
3780 return;
3781 Params.push_back(Param);
3782 Locations.push_back(Loc);
3783 }
3784
3785 SmallVector<SmallString<64>, 2> NewParams;
3786 if (S.Context.getTargetInfo().getTriple().isAArch64()) {
3787 if (S.ARM().checkTargetClonesAttr(Params, Locations, NewParams))
3788 return;
3789 } else if (S.Context.getTargetInfo().getTriple().isRISCV()) {
3790 if (S.RISCV().checkTargetClonesAttr(Params, Locations, NewParams,
3791 AL.getLoc()))
3792 return;
3793 } else if (S.Context.getTargetInfo().getTriple().isX86()) {
3794 if (S.X86().checkTargetClonesAttr(Params, Locations, NewParams,
3795 AL.getLoc()))
3796 return;
3797 } else if (S.Context.getTargetInfo().getTriple().isOSAIX()) {
3798 if (S.PPC().checkTargetClonesAttr(Params, Locations, NewParams,
3799 AL.getLoc()))
3800 return;
3801 }
3802 Params.clear();
3803 for (auto &SmallStr : NewParams)
3804 Params.push_back(SmallStr.str());
3805
3806 TargetClonesAttr *NewAttr = ::new (S.Context)
3807 TargetClonesAttr(S.Context, AL, Params.data(), Params.size());
3808 D->addAttr(NewAttr);
3809}
3810
3811static void handleMinVectorWidthAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3812 Expr *E = AL.getArgAsExpr(0);
3813 uint32_t VecWidth;
3814 if (!S.checkUInt32Argument(AL, E, VecWidth)) {
3815 AL.setInvalid();
3816 return;
3817 }
3818
3819 MinVectorWidthAttr *Existing = D->getAttr<MinVectorWidthAttr>();
3820 if (Existing && Existing->getVectorWidth() != VecWidth) {
3821 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3822 return;
3823 }
3824
3825 D->addAttr(::new (S.Context) MinVectorWidthAttr(S.Context, AL, VecWidth));
3826}
3827
3828static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3829 Expr *E = AL.getArgAsExpr(0);
3830 SourceLocation Loc = E->getExprLoc();
3831 FunctionDecl *FD = nullptr;
3833
3834 // gcc only allows for simple identifiers. Since we support more than gcc, we
3835 // will warn the user.
3836 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
3837 if (DRE->hasQualifier())
3838 S.Diag(Loc, diag::warn_cleanup_ext);
3839 FD = dyn_cast<FunctionDecl>(DRE->getDecl());
3840 NI = DRE->getNameInfo();
3841 if (!FD) {
3842 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 1
3843 << NI.getName();
3844 return;
3845 }
3846 } else if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
3847 if (ULE->hasExplicitTemplateArgs())
3848 S.Diag(Loc, diag::warn_cleanup_ext);
3850 NI = ULE->getNameInfo();
3851 if (!FD) {
3852 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 2
3853 << NI.getName();
3854 if (ULE->getType() == S.Context.OverloadTy)
3856 return;
3857 }
3858 } else {
3859 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 0;
3860 return;
3861 }
3862
3863 if (FD->getNumParams() != 1) {
3864 S.Diag(Loc, diag::err_attribute_cleanup_func_must_take_one_arg)
3865 << NI.getName();
3866 return;
3867 }
3868
3869 VarDecl *VD = cast<VarDecl>(D);
3870 // Create a reference to the variable declaration. This is a fake/dummy
3871 // reference.
3872 DeclRefExpr *VariableReference = DeclRefExpr::Create(
3873 S.Context, NestedNameSpecifierLoc{}, FD->getLocation(), VD, false,
3874 DeclarationNameInfo{VD->getDeclName(), VD->getLocation()}, VD->getType(),
3875 VK_LValue);
3876
3877 // Create a unary operator expression that represents taking the address of
3878 // the variable. This is a fake/dummy expression.
3879 Expr *AddressOfVariable = UnaryOperator::Create(
3880 S.Context, VariableReference, UnaryOperatorKind::UO_AddrOf,
3882 +false, FPOptionsOverride{});
3883
3884 // Create a function call expression. This is a fake/dummy call expression.
3885 CallExpr *FunctionCallExpression =
3886 CallExpr::Create(S.Context, E, ArrayRef{AddressOfVariable},
3888
3889 if (S.CheckFunctionCall(FD, FunctionCallExpression,
3890 FD->getType()->getAs<FunctionProtoType>())) {
3891 return;
3892 }
3893
3894 // If a declaration contains multiple cleanup attributes, GCC only uses
3895 // the last one.
3896 if (const auto *A = D->getAttr<CleanupAttr>()) {
3897 S.Diag(A->getLoc(), diag::warn_duplicate_cleanup_attr) << A->getRange();
3898 D->dropAttr<CleanupAttr>();
3899 }
3900
3901 auto *attr = ::new (S.Context) CleanupAttr(S.Context, AL, FD);
3902 attr->setArgLoc(E->getExprLoc());
3903 D->addAttr(attr);
3904}
3905
3907 const ParsedAttr &AL) {
3908 if (!AL.isArgIdent(0)) {
3909 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3910 << AL << 0 << AANT_ArgumentIdentifier;
3911 return;
3912 }
3913
3914 EnumExtensibilityAttr::Kind ExtensibilityKind;
3916 if (!EnumExtensibilityAttr::ConvertStrToKind(II->getName(),
3917 ExtensibilityKind)) {
3918 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
3919 return;
3920 }
3921
3922 D->addAttr(::new (S.Context)
3923 EnumExtensibilityAttr(S.Context, AL, ExtensibilityKind));
3924}
3925
3926/// Handle __attribute__((format_arg((idx)))) attribute based on
3927/// https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
3928static void handleFormatArgAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3929 const Expr *IdxExpr = AL.getArgAsExpr(0);
3930 ParamIdx Idx;
3931 if (!S.checkFunctionOrMethodParameterIndex(D, AL, 1, IdxExpr, Idx))
3932 return;
3933
3934 // Make sure the format string is really a string.
3936
3937 bool NotNSStringTy = !S.ObjC().isNSStringType(Ty);
3938 if (NotNSStringTy && !S.ObjC().isCFStringType(Ty) &&
3939 (!Ty->isPointerType() ||
3941 S.Diag(AL.getLoc(), diag::err_format_attribute_not)
3942 << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0);
3943 return;
3944 }
3946 // replace instancetype with the class type
3947 auto *Instancetype = cast<TypedefType>(S.Context.getTypedefType(
3948 ElaboratedTypeKeyword::None, /*Qualifier=*/std::nullopt,
3950 if (Ty->getAs<TypedefType>() == Instancetype)
3951 if (auto *OMD = dyn_cast<ObjCMethodDecl>(D))
3952 if (auto *Interface = OMD->getClassInterface())
3954 QualType(Interface->getTypeForDecl(), 0));
3955 if (!S.ObjC().isNSStringType(Ty, /*AllowNSAttributedString=*/true) &&
3956 !S.ObjC().isCFStringType(Ty) &&
3957 (!Ty->isPointerType() ||
3959 S.Diag(AL.getLoc(), diag::err_format_attribute_result_not)
3960 << (NotNSStringTy ? "string type" : "NSString")
3961 << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0);
3962 return;
3963 }
3964
3965 D->addAttr(::new (S.Context) FormatArgAttr(S.Context, AL, Idx));
3966}
3967
3976
3977/// getFormatAttrKind - Map from format attribute names to supported format
3978/// types.
3979static FormatAttrKind getFormatAttrKind(StringRef Format) {
3980 return llvm::StringSwitch<FormatAttrKind>(Format)
3981 // Check for formats that get handled specially.
3982 .Case("NSString", NSStringFormat)
3983 .Case("CFString", CFStringFormat)
3984 .Cases({"gnu_strftime", "strftime"}, StrftimeFormat)
3985
3986 // Otherwise, check for supported formats.
3987 .Cases({"gnu_scanf", "scanf", "gnu_printf", "printf", "printf0",
3988 "gnu_strfmon", "strfmon"},
3990 .Cases({"cmn_err", "vcmn_err", "zcmn_err"}, SupportedFormat)
3991 .Cases({"kprintf", "syslog"}, SupportedFormat) // OpenBSD.
3992 .Case("freebsd_kprintf", SupportedFormat) // FreeBSD.
3993 .Case("os_trace", SupportedFormat)
3994 .Case("os_log", SupportedFormat)
3995
3996 .Cases({"gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag"},
3999}
4000
4001/// Handle __attribute__((init_priority(priority))) attributes based on
4002/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
4003static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4004 if (!S.getLangOpts().CPlusPlus) {
4005 S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
4006 return;
4007 }
4008
4009 if (S.getLangOpts().HLSL) {
4010 S.Diag(AL.getLoc(), diag::err_hlsl_init_priority_unsupported);
4011 return;
4012 }
4013
4015 S.Diag(AL.getLoc(), diag::err_init_priority_object_attr);
4016 AL.setInvalid();
4017 return;
4018 }
4019
4020 Expr *E = AL.getArgAsExpr(0);
4021 uint32_t prioritynum;
4022 if (!S.checkUInt32Argument(AL, E, prioritynum)) {
4023 AL.setInvalid();
4024 return;
4025 }
4026
4027 if (prioritynum > 65535) {
4028 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_range)
4029 << E->getSourceRange() << AL << 0 << 65535;
4030 AL.setInvalid();
4031 return;
4032 }
4033
4034 // Values <= 100 are reserved for the implementation, and libc++
4035 // benefits from being able to specify values in that range.
4036 if (prioritynum < 101)
4037 S.Diag(AL.getLoc(), diag::warn_init_priority_reserved)
4038 << E->getSourceRange() << prioritynum;
4039 D->addAttr(::new (S.Context) InitPriorityAttr(S.Context, AL, prioritynum));
4040}
4041
4043 StringRef NewUserDiagnostic) {
4044 if (const auto *EA = D->getAttr<ErrorAttr>()) {
4045 std::string NewAttr = CI.getNormalizedFullName();
4046 assert((NewAttr == "error" || NewAttr == "warning") &&
4047 "unexpected normalized full name");
4048 bool Match = (EA->isError() && NewAttr == "error") ||
4049 (EA->isWarning() && NewAttr == "warning");
4050 if (!Match) {
4051 Diag(EA->getLocation(), diag::err_attributes_are_not_compatible)
4052 << CI << EA
4053 << (CI.isRegularKeywordAttribute() ||
4054 EA->isRegularKeywordAttribute());
4055 Diag(CI.getLoc(), diag::note_conflicting_attribute);
4056 return nullptr;
4057 }
4058 if (EA->getUserDiagnostic() != NewUserDiagnostic) {
4059 Diag(CI.getLoc(), diag::warn_duplicate_attribute) << EA;
4060 Diag(EA->getLoc(), diag::note_previous_attribute);
4061 }
4062 D->dropAttr<ErrorAttr>();
4063 }
4064 return ::new (Context) ErrorAttr(Context, CI, NewUserDiagnostic);
4065}
4066
4068 const IdentifierInfo *Format, int FormatIdx,
4069 int FirstArg) {
4070 // Check whether we already have an equivalent format attribute.
4071 for (auto *F : D->specific_attrs<FormatAttr>()) {
4072 if (F->getType() == Format &&
4073 F->getFormatIdx() == FormatIdx &&
4074 F->getFirstArg() == FirstArg) {
4075 // If we don't have a valid location for this attribute, adopt the
4076 // location.
4077 if (F->getLocation().isInvalid())
4078 F->setRange(CI.getRange());
4079 return nullptr;
4080 }
4081 }
4082
4083 return ::new (Context) FormatAttr(Context, CI, Format, FormatIdx, FirstArg);
4084}
4085
4087 const AttributeCommonInfo &CI,
4088 const IdentifierInfo *Format,
4089 int FormatIdx,
4090 StringLiteral *FormatStr) {
4091 // Check whether we already have an equivalent FormatMatches attribute.
4092 for (auto *F : D->specific_attrs<FormatMatchesAttr>()) {
4093 if (F->getType() == Format && F->getFormatIdx() == FormatIdx) {
4094 if (!CheckFormatStringsCompatible(GetFormatStringType(Format->getName()),
4095 F->getFormatString(), FormatStr))
4096 return nullptr;
4097
4098 // If we don't have a valid location for this attribute, adopt the
4099 // location.
4100 if (F->getLocation().isInvalid())
4101 F->setRange(CI.getRange());
4102 return nullptr;
4103 }
4104 }
4105
4106 return ::new (Context)
4107 FormatMatchesAttr(Context, CI, Format, FormatIdx, FormatStr);
4108}
4109
4116
4117/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
4118/// https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
4119static bool handleFormatAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
4120 FormatAttrCommon *Info) {
4121 // Checks the first two arguments of the attribute; this is shared between
4122 // Format and FormatMatches attributes.
4123
4124 if (!AL.isArgIdent(0)) {
4125 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
4126 << AL << 1 << AANT_ArgumentIdentifier;
4127 return false;
4128 }
4129
4130 // In C++ the implicit 'this' function parameter also counts, and they are
4131 // counted from one.
4132 bool HasImplicitThisParam = hasImplicitObjectParameter(D);
4133 Info->NumArgs = getFunctionOrMethodNumParams(D) + HasImplicitThisParam;
4134
4136 StringRef Format = Info->Identifier->getName();
4137
4138 if (normalizeName(Format)) {
4139 // If we've modified the string name, we need a new identifier for it.
4140 Info->Identifier = &S.Context.Idents.get(Format);
4141 }
4142
4143 // Check for supported formats.
4144 Info->Kind = getFormatAttrKind(Format);
4145
4146 if (Info->Kind == IgnoredFormat)
4147 return false;
4148
4149 if (Info->Kind == InvalidFormat) {
4150 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
4151 << AL << Info->Identifier->getName();
4152 return false;
4153 }
4154
4155 // checks for the 2nd argument
4156 Expr *IdxExpr = AL.getArgAsExpr(1);
4157 if (!S.checkUInt32Argument(AL, IdxExpr, Info->FormatStringIdx, 2))
4158 return false;
4159
4160 if (Info->FormatStringIdx < 1 || Info->FormatStringIdx > Info->NumArgs) {
4161 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
4162 << AL << 2 << IdxExpr->getSourceRange();
4163 return false;
4164 }
4165
4166 // FIXME: Do we need to bounds check?
4167 unsigned ArgIdx = Info->FormatStringIdx - 1;
4168
4169 if (HasImplicitThisParam) {
4170 if (ArgIdx == 0) {
4171 S.Diag(AL.getLoc(),
4172 diag::err_format_attribute_implicit_this_format_string)
4173 << IdxExpr->getSourceRange();
4174 return false;
4175 }
4176 ArgIdx--;
4177 }
4178
4179 // make sure the format string is really a string
4180 QualType Ty = getFunctionOrMethodParamType(D, ArgIdx);
4181
4182 if (!S.ObjC().isNSStringType(Ty, true) && !S.ObjC().isCFStringType(Ty) &&
4183 (!Ty->isPointerType() ||
4185 S.Diag(AL.getLoc(), diag::err_format_attribute_not)
4186 << IdxExpr->getSourceRange()
4187 << getFunctionOrMethodParamRange(D, ArgIdx);
4188 return false;
4189 }
4190
4191 return true;
4192}
4193
4194static void handleFormatAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4195 FormatAttrCommon Info;
4196 if (!handleFormatAttrCommon(S, D, AL, &Info))
4197 return;
4198
4199 // check the 3rd argument
4200 Expr *FirstArgExpr = AL.getArgAsExpr(2);
4201 uint32_t FirstArg;
4202 if (!S.checkUInt32Argument(AL, FirstArgExpr, FirstArg, 3))
4203 return;
4204
4205 // FirstArg == 0 is always valid.
4206 if (FirstArg != 0) {
4207 if (Info.Kind == StrftimeFormat) {
4208 // If the kind is strftime, FirstArg must be 0 because strftime does not
4209 // use any variadic arguments.
4210 S.Diag(AL.getLoc(), diag::err_format_strftime_third_parameter)
4211 << FirstArgExpr->getSourceRange()
4212 << FixItHint::CreateReplacement(FirstArgExpr->getSourceRange(), "0");
4213 return;
4214 } else if (isFunctionOrMethodVariadic(D)) {
4215 // Else, if the function is variadic, then FirstArg must be 0 or the
4216 // "position" of the ... parameter. It's unusual to use 0 with variadic
4217 // functions, so the fixit proposes the latter.
4218 if (FirstArg != Info.NumArgs + 1) {
4219 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
4220 << AL << 3 << FirstArgExpr->getSourceRange()
4222 std::to_string(Info.NumArgs + 1));
4223 return;
4224 }
4225 } else {
4226 // Inescapable GCC compatibility diagnostic.
4227 S.Diag(D->getLocation(), diag::warn_gcc_requires_variadic_function) << AL;
4228 if (FirstArg <= Info.FormatStringIdx) {
4229 // Else, the function is not variadic, and FirstArg must be 0 or any
4230 // parameter after the format parameter. We don't offer a fixit because
4231 // there are too many possible good values.
4232 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
4233 << AL << 3 << FirstArgExpr->getSourceRange();
4234 return;
4235 }
4236 }
4237 }
4238
4239 FormatAttr *NewAttr =
4240 S.mergeFormatAttr(D, AL, Info.Identifier, Info.FormatStringIdx, FirstArg);
4241 if (NewAttr)
4242 D->addAttr(NewAttr);
4243}
4244
4245static void handleFormatMatchesAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4246 FormatAttrCommon Info;
4247 if (!handleFormatAttrCommon(S, D, AL, &Info))
4248 return;
4249
4250 Expr *FormatStrExpr = AL.getArgAsExpr(2)->IgnoreParenImpCasts();
4251 if (auto *SL = dyn_cast<StringLiteral>(FormatStrExpr)) {
4253 if (S.ValidateFormatString(FST, SL))
4254 if (auto *NewAttr = S.mergeFormatMatchesAttr(D, AL, Info.Identifier,
4255 Info.FormatStringIdx, SL))
4256 D->addAttr(NewAttr);
4257 return;
4258 }
4259
4260 S.Diag(AL.getLoc(), diag::err_format_nonliteral)
4261 << FormatStrExpr->getSourceRange();
4262}
4263
4264/// Handle __attribute__((callback(CalleeIdx, PayloadIdx0, ...))) attributes.
4265static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4266 // The index that identifies the callback callee is mandatory.
4267 if (AL.getNumArgs() == 0) {
4268 S.Diag(AL.getLoc(), diag::err_callback_attribute_no_callee)
4269 << AL.getRange();
4270 return;
4271 }
4272
4273 bool HasImplicitThisParam = hasImplicitObjectParameter(D);
4275
4276 FunctionDecl *FD = D->getAsFunction();
4277 assert(FD && "Expected a function declaration!");
4278
4279 llvm::StringMap<int> NameIdxMapping;
4280 NameIdxMapping["__"] = -1;
4281
4282 NameIdxMapping["this"] = 0;
4283
4284 int Idx = 1;
4285 for (const ParmVarDecl *PVD : FD->parameters())
4286 NameIdxMapping[PVD->getName()] = Idx++;
4287
4288 auto UnknownName = NameIdxMapping.end();
4289
4290 SmallVector<int, 8> EncodingIndices;
4291 for (unsigned I = 0, E = AL.getNumArgs(); I < E; ++I) {
4292 SourceRange SR;
4293 int32_t ArgIdx;
4294
4295 if (AL.isArgIdent(I)) {
4296 IdentifierLoc *IdLoc = AL.getArgAsIdent(I);
4297 auto It = NameIdxMapping.find(IdLoc->getIdentifierInfo()->getName());
4298 if (It == UnknownName) {
4299 S.Diag(AL.getLoc(), diag::err_callback_attribute_argument_unknown)
4300 << IdLoc->getIdentifierInfo() << IdLoc->getLoc();
4301 return;
4302 }
4303
4304 SR = SourceRange(IdLoc->getLoc());
4305 ArgIdx = It->second;
4306 } else if (AL.isArgExpr(I)) {
4307 Expr *IdxExpr = AL.getArgAsExpr(I);
4308
4309 // If the expression is not parseable as an int32_t we have a problem.
4310 if (!S.checkUInt32Argument(AL, IdxExpr, (uint32_t &)ArgIdx, I + 1,
4311 false)) {
4312 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
4313 << AL << (I + 1) << IdxExpr->getSourceRange();
4314 return;
4315 }
4316
4317 // Check oob, excluding the special values, 0 and -1.
4318 if (ArgIdx < -1 || ArgIdx > NumArgs) {
4319 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
4320 << AL << (I + 1) << IdxExpr->getSourceRange();
4321 return;
4322 }
4323
4324 SR = IdxExpr->getSourceRange();
4325 } else {
4326 llvm_unreachable("Unexpected ParsedAttr argument type!");
4327 }
4328
4329 if (ArgIdx == 0 && !HasImplicitThisParam) {
4330 S.Diag(AL.getLoc(), diag::err_callback_implicit_this_not_available)
4331 << (I + 1) << SR;
4332 return;
4333 }
4334
4335 // Adjust for the case we do not have an implicit "this" parameter. In this
4336 // case we decrease all positive values by 1 to get LLVM argument indices.
4337 if (!HasImplicitThisParam && ArgIdx > 0)
4338 ArgIdx -= 1;
4339
4340 EncodingIndices.push_back(ArgIdx);
4341 }
4342
4343 int CalleeIdx = EncodingIndices.front();
4344 // Check if the callee index is proper, thus not "this" and not "unknown".
4345 // This means the "CalleeIdx" has to be non-negative if "HasImplicitThisParam"
4346 // is false and positive if "HasImplicitThisParam" is true.
4347 if (CalleeIdx < (int)HasImplicitThisParam) {
4348 S.Diag(AL.getLoc(), diag::err_callback_attribute_invalid_callee)
4349 << AL.getRange();
4350 return;
4351 }
4352
4353 // Get the callee type, note the index adjustment as the AST doesn't contain
4354 // the this type (which the callee cannot reference anyway!).
4355 const Type *CalleeType =
4356 getFunctionOrMethodParamType(D, CalleeIdx - HasImplicitThisParam)
4357 .getTypePtr();
4358 if (!CalleeType || !CalleeType->isFunctionPointerType()) {
4359 S.Diag(AL.getLoc(), diag::err_callback_callee_no_function_type)
4360 << AL.getRange();
4361 return;
4362 }
4363
4364 const Type *CalleeFnType =
4366
4367 // TODO: Check the type of the callee arguments.
4368
4369 const auto *CalleeFnProtoType = dyn_cast<FunctionProtoType>(CalleeFnType);
4370 if (!CalleeFnProtoType) {
4371 S.Diag(AL.getLoc(), diag::err_callback_callee_no_function_type)
4372 << AL.getRange();
4373 return;
4374 }
4375
4376 if (CalleeFnProtoType->getNumParams() != EncodingIndices.size() - 1) {
4377 S.Diag(AL.getLoc(), diag::err_attribute_wrong_arg_count_for_func)
4378 << AL << QualType{CalleeFnProtoType, 0}
4379 << CalleeFnProtoType->getNumParams()
4380 << (unsigned)(EncodingIndices.size() - 1);
4381 return;
4382 }
4383
4384 if (CalleeFnProtoType->isVariadic()) {
4385 S.Diag(AL.getLoc(), diag::err_callback_callee_is_variadic) << AL.getRange();
4386 return;
4387 }
4388
4389 // Do not allow multiple callback attributes.
4390 if (D->hasAttr<CallbackAttr>()) {
4391 S.Diag(AL.getLoc(), diag::err_callback_attribute_multiple) << AL.getRange();
4392 return;
4393 }
4394
4395 D->addAttr(::new (S.Context) CallbackAttr(
4396 S.Context, AL, EncodingIndices.data(), EncodingIndices.size()));
4397}
4398
4399LifetimeCaptureByAttr *Sema::ParseLifetimeCaptureByAttr(const ParsedAttr &AL,
4400 StringRef ParamName) {
4401 StringRef AttrName = AL.getAttrName()->getName();
4402 StringRef SpecialEntity;
4403 if (AttrName == "lifetime_capture_by_this")
4404 SpecialEntity = "this";
4405 else if (AttrName == "lifetime_capture_by_global")
4406 SpecialEntity = "global";
4407 else if (AttrName == "lifetime_capture_by_unknown")
4408 SpecialEntity = "unknown";
4409
4410 if (!SpecialEntity.empty() && AL.getNumArgs() != 0) {
4411 Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 0;
4412 return nullptr;
4413 }
4414
4415 // Atleast one capture by is required.
4416 if (SpecialEntity.empty() && AL.getNumArgs() == 0) {
4417 Diag(AL.getLoc(), diag::err_capture_by_attribute_no_entity)
4418 << AL.getRange();
4419 return nullptr;
4420 }
4421 unsigned N = SpecialEntity.empty() ? AL.getNumArgs() : 1;
4422 auto ParamIdents =
4424 auto ParamLocs =
4426 if (!SpecialEntity.empty()) {
4427 ParamIdents[0] = &Context.Idents.get(SpecialEntity);
4428 ParamLocs[0] = AL.getRange().getEnd();
4429 int FakeParamIndices[] = {LifetimeCaptureByAttr::Invalid};
4430 auto *CapturedBy =
4431 LifetimeCaptureByAttr::Create(Context, FakeParamIndices, 1, AL);
4432 CapturedBy->setArgs(ParamIdents, ParamLocs);
4433 return CapturedBy;
4434 }
4435
4436 bool IsValid = true;
4437 for (unsigned I = 0; I < N; ++I) {
4438 if (AL.isArgExpr(I)) {
4439 Expr *E = AL.getArgAsExpr(I);
4440 Diag(E->getExprLoc(), diag::err_capture_by_attribute_argument_unknown)
4441 << E << E->getExprLoc();
4442 IsValid = false;
4443 continue;
4444 }
4445 assert(AL.isArgIdent(I));
4446 IdentifierLoc *IdLoc = AL.getArgAsIdent(I);
4447 StringRef Name = IdLoc->getIdentifierInfo()->getName();
4448 StringRef Replacement;
4449 if (Name == "this")
4450 Replacement = "lifetime_capture_by_this";
4451 else if (Name == "global")
4452 Replacement = "lifetime_capture_by_global";
4453 else if (Name == "unknown")
4454 Replacement = "lifetime_capture_by_unknown";
4455 if (!Replacement.empty())
4456 Diag(IdLoc->getLoc(), diag::warn_deprecated_capture_by_special_entity)
4457 << Name << Replacement << IdLoc->getLoc();
4458 if (IdLoc->getIdentifierInfo()->getName() == ParamName) {
4459 Diag(IdLoc->getLoc(), diag::err_capture_by_references_itself)
4460 << IdLoc->getLoc();
4461 IsValid = false;
4462 continue;
4463 }
4464 ParamIdents[I] = IdLoc->getIdentifierInfo();
4465 ParamLocs[I] = IdLoc->getLoc();
4466 }
4467 if (!IsValid)
4468 return nullptr;
4469 SmallVector<int> FakeParamIndices(N, LifetimeCaptureByAttr::Invalid);
4470 auto *CapturedBy =
4471 LifetimeCaptureByAttr::Create(Context, FakeParamIndices.data(), N, AL);
4472 CapturedBy->setArgs(ParamIdents, ParamLocs);
4473 return CapturedBy;
4474}
4475
4477 const ParsedAttr &AL) {
4478 auto *PVD = dyn_cast<ParmVarDecl>(D);
4479 assert(PVD);
4480 auto *CaptureByAttr = S.ParseLifetimeCaptureByAttr(AL, PVD->getName());
4481 if (!CaptureByAttr)
4482 return;
4483
4484 enum class SpellingKind { ParameterList, This, Global, Unknown };
4485 auto GetSpellingKind = [](const LifetimeCaptureByAttr *A) {
4486 if (A->isThis())
4487 return SpellingKind::This;
4488 if (A->isGlobal())
4489 return SpellingKind::Global;
4490 if (A->isUnknown())
4491 return SpellingKind::Unknown;
4492 return SpellingKind::ParameterList;
4493 };
4494 auto GetSpellingName = [](SpellingKind Kind) -> StringRef {
4495 switch (Kind) {
4496 case SpellingKind::ParameterList:
4497 return "lifetime_capture_by";
4498 case SpellingKind::This:
4499 return "lifetime_capture_by_this";
4500 case SpellingKind::Global:
4501 return "lifetime_capture_by_global";
4502 case SpellingKind::Unknown:
4503 return "lifetime_capture_by_unknown";
4504 }
4505 llvm_unreachable("unknown lifetime_capture_by spelling kind");
4506 };
4507
4508 SpellingKind NewKind = GetSpellingKind(CaptureByAttr);
4509 for (const auto *Existing : D->specific_attrs<LifetimeCaptureByAttr>()) {
4510 if (GetSpellingKind(Existing) == NewKind) {
4511 S.Diag(AL.getLoc(), diag::err_capture_by_attribute_multiple)
4512 << GetSpellingName(NewKind) << AL.getRange();
4513 return;
4514 }
4515 }
4516
4517 D->addAttr(CaptureByAttr);
4518}
4519
4521 bool HasImplicitThisParam = hasImplicitObjectParameter(FD);
4523 for (ParmVarDecl *PVD : FD->parameters())
4524 for (auto *A : PVD->specific_attrs<LifetimeCaptureByAttr>())
4525 Attrs.push_back(A);
4526 if (HasImplicitThisParam) {
4527 TypeSourceInfo *TSI = FD->getTypeSourceInfo();
4528 if (!TSI)
4529 return;
4531 for (TypeLoc TL = TSI->getTypeLoc();
4532 (ATL = TL.getAsAdjusted<AttributedTypeLoc>());
4533 TL = ATL.getModifiedLoc()) {
4534 if (auto *A = ATL.getAttrAs<LifetimeCaptureByAttr>())
4535 Attrs.push_back(const_cast<LifetimeCaptureByAttr *>(A));
4536 }
4537 }
4538 if (Attrs.empty())
4539 return;
4540 llvm::StringMap<int> NameIdxMapping = {
4541 {"global", LifetimeCaptureByAttr::Global},
4542 {"unknown", LifetimeCaptureByAttr::Unknown}};
4543 int Idx = 0;
4544 if (HasImplicitThisParam) {
4545 NameIdxMapping["this"] = 0;
4546 Idx++;
4547 }
4548 for (const ParmVarDecl *PVD : FD->parameters())
4549 NameIdxMapping[PVD->getName()] = Idx++;
4550 auto DisallowReservedParams = [&](StringRef Reserved) {
4551 for (const ParmVarDecl *PVD : FD->parameters())
4552 if (PVD->getName() == Reserved)
4553 Diag(PVD->getLocation(), diag::err_capture_by_param_uses_reserved_name)
4554 << PVD->getName();
4555 };
4556 for (auto *CapturedBy : Attrs) {
4557 const auto &Entities = CapturedBy->getArgIdents();
4558 for (size_t I = 0; I < Entities.size(); ++I) {
4559 StringRef Name = Entities[I]->getName();
4560 auto It = NameIdxMapping.find(Name);
4561 if (It == NameIdxMapping.end()) {
4562 auto Loc = CapturedBy->getArgLocs()[I];
4563 if (!HasImplicitThisParam && Name == "this") {
4564 unsigned DiagID =
4565 CapturedBy->isStandaloneSpecial()
4566 ? diag::err_capture_by_this_attr_without_implicit_this
4567 : diag::err_capture_by_implicit_this_not_available;
4568 Diag(Loc, DiagID) << Loc;
4569 } else
4570 Diag(Loc, diag::err_capture_by_attribute_argument_unknown)
4571 << Entities[I] << Loc;
4572 continue;
4573 }
4574 if ((Name == "unknown" || Name == "global") &&
4575 !CapturedBy->isStandaloneSpecial())
4576 DisallowReservedParams(Name);
4577 CapturedBy->setParamIdx(I, It->second);
4578 }
4579 }
4580}
4581
4582static bool isFunctionLike(const Type &T) {
4583 // Check for explicit function types.
4584 // 'called_once' is only supported in Objective-C and it has
4585 // function pointers and block pointers.
4586 return T.isFunctionPointerType() || T.isBlockPointerType();
4587}
4588
4589/// Handle 'called_once' attribute.
4590static void handleCalledOnceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4591 // 'called_once' only applies to parameters representing functions.
4592 QualType T = cast<ParmVarDecl>(D)->getType();
4593
4594 if (!isFunctionLike(*T)) {
4595 S.Diag(AL.getLoc(), diag::err_called_once_attribute_wrong_type);
4596 return;
4597 }
4598
4599 D->addAttr(::new (S.Context) CalledOnceAttr(S.Context, AL));
4600}
4601
4602static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4603 // Try to find the underlying union declaration.
4604 RecordDecl *RD = nullptr;
4605 const auto *TD = dyn_cast<TypedefNameDecl>(D);
4606 if (TD && TD->getUnderlyingType()->isUnionType())
4607 RD = TD->getUnderlyingType()->getAsRecordDecl();
4608 else
4609 RD = dyn_cast<RecordDecl>(D);
4610
4611 if (!RD || !RD->isUnion()) {
4612 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
4614 return;
4615 }
4616
4617 if (!RD->isCompleteDefinition()) {
4618 if (!RD->isBeingDefined())
4619 S.Diag(AL.getLoc(),
4620 diag::warn_transparent_union_attribute_not_definition);
4621 return;
4622 }
4623
4625 FieldEnd = RD->field_end();
4626 if (Field == FieldEnd) {
4627 S.Diag(AL.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
4628 return;
4629 }
4630
4631 FieldDecl *FirstField = *Field;
4632 QualType FirstType = FirstField->getType();
4633 if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
4634 S.Diag(FirstField->getLocation(),
4635 diag::warn_transparent_union_attribute_floating)
4636 << FirstType->isVectorType() << FirstType;
4637 return;
4638 }
4639
4640 if (FirstType->isIncompleteType())
4641 return;
4642 uint64_t FirstSize = S.Context.getTypeSize(FirstType);
4643 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
4644 for (; Field != FieldEnd; ++Field) {
4645 QualType FieldType = Field->getType();
4646 if (FieldType->isIncompleteType())
4647 return;
4648 // FIXME: this isn't fully correct; we also need to test whether the
4649 // members of the union would all have the same calling convention as the
4650 // first member of the union. Checking just the size and alignment isn't
4651 // sufficient (consider structs passed on the stack instead of in registers
4652 // as an example).
4653 if (S.Context.getTypeSize(FieldType) != FirstSize ||
4654 S.Context.getTypeAlign(FieldType) > FirstAlign) {
4655 // Warn if we drop the attribute.
4656 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
4657 unsigned FieldBits = isSize ? S.Context.getTypeSize(FieldType)
4658 : S.Context.getTypeAlign(FieldType);
4659 S.Diag(Field->getLocation(),
4660 diag::warn_transparent_union_attribute_field_size_align)
4661 << isSize << *Field << FieldBits;
4662 unsigned FirstBits = isSize ? FirstSize : FirstAlign;
4663 S.Diag(FirstField->getLocation(),
4664 diag::note_transparent_union_first_field_size_align)
4665 << isSize << FirstBits;
4666 return;
4667 }
4668 }
4669
4670 RD->addAttr(::new (S.Context) TransparentUnionAttr(S.Context, AL));
4671}
4672
4673static void handleAnnotateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4674 auto *Attr = S.CreateAnnotationAttr(AL);
4675 if (Attr) {
4676 D->addAttr(Attr);
4677 }
4678}
4679
4680static void handleAlignValueAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4681 S.AddAlignValueAttr(D, AL, AL.getArgAsExpr(0));
4682}
4683
4685 SourceLocation AttrLoc = CI.getLoc();
4686
4687 QualType T;
4688 if (const auto *TD = dyn_cast<TypedefNameDecl>(D))
4689 T = TD->getUnderlyingType();
4690 else if (const auto *VD = dyn_cast<ValueDecl>(D))
4691 T = VD->getType();
4692 else
4693 llvm_unreachable("Unknown decl type for align_value");
4694
4695 if (!T->isDependentType() && !T->isAnyPointerType() &&
4696 !T->isReferenceType() && !T->isMemberPointerType()) {
4697 Diag(AttrLoc, diag::warn_attribute_pointer_or_reference_only)
4698 << CI << T << D->getSourceRange();
4699 return;
4700 }
4701
4702 if (!E->isValueDependent()) {
4703 llvm::APSInt Alignment;
4705 E, &Alignment, diag::err_align_value_attribute_argument_not_int);
4706 if (ICE.isInvalid())
4707 return;
4708
4709 if (!Alignment.isPowerOf2()) {
4710 Diag(AttrLoc, diag::err_alignment_not_power_of_two)
4711 << E->getSourceRange();
4712 return;
4713 }
4714
4715 D->addAttr(::new (Context) AlignValueAttr(Context, CI, ICE.get()));
4716 return;
4717 }
4718
4719 // Save dependent expressions in the AST to be instantiated.
4720 D->addAttr(::new (Context) AlignValueAttr(Context, CI, E));
4721}
4722
4723static void handleAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4724 if (AL.hasParsedType()) {
4725 const ParsedType &TypeArg = AL.getTypeArg();
4726 TypeSourceInfo *TInfo;
4727 (void)S.GetTypeFromParser(
4728 ParsedType::getFromOpaquePtr(TypeArg.getAsOpaquePtr()), &TInfo);
4729 if (AL.isPackExpansion() &&
4731 S.Diag(AL.getEllipsisLoc(),
4732 diag::err_pack_expansion_without_parameter_packs);
4733 return;
4734 }
4735
4736 if (!AL.isPackExpansion() &&
4738 TInfo, Sema::UPPC_Expression))
4739 return;
4740
4741 S.AddAlignedAttr(D, AL, TInfo, AL.isPackExpansion());
4742 return;
4743 }
4744
4745 // check the attribute arguments.
4746 if (AL.getNumArgs() > 1) {
4747 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
4748 return;
4749 }
4750
4751 if (AL.getNumArgs() == 0) {
4752 D->addAttr(::new (S.Context) AlignedAttr(S.Context, AL, true, nullptr));
4753 return;
4754 }
4755
4756 Expr *E = AL.getArgAsExpr(0);
4758 S.Diag(AL.getEllipsisLoc(),
4759 diag::err_pack_expansion_without_parameter_packs);
4760 return;
4761 }
4762
4764 return;
4765
4766 S.AddAlignedAttr(D, AL, E, AL.isPackExpansion());
4767}
4768
4769/// Perform checking of type validity
4770///
4771/// C++11 [dcl.align]p1:
4772/// An alignment-specifier may be applied to a variable or to a class
4773/// data member, but it shall not be applied to a bit-field, a function
4774/// parameter, the formal parameter of a catch clause, or a variable
4775/// declared with the register storage class specifier. An
4776/// alignment-specifier may also be applied to the declaration of a class
4777/// or enumeration type.
4778/// CWG 2354:
4779/// CWG agreed to remove permission for alignas to be applied to
4780/// enumerations.
4781/// C11 6.7.5/2:
4782/// An alignment attribute shall not be specified in a declaration of
4783/// a typedef, or a bit-field, or a function, or a parameter, or an
4784/// object declared with the register storage-class specifier.
4786 const AlignedAttr &Attr,
4787 SourceLocation AttrLoc) {
4788 int DiagKind = -1;
4789 if (isa<ParmVarDecl>(D)) {
4790 DiagKind = 0;
4791 } else if (const auto *VD = dyn_cast<VarDecl>(D)) {
4792 if (VD->getStorageClass() == SC_Register)
4793 DiagKind = 1;
4794 if (VD->isExceptionVariable())
4795 DiagKind = 2;
4796 } else if (const auto *FD = dyn_cast<FieldDecl>(D)) {
4797 if (FD->isBitField())
4798 DiagKind = 3;
4799 } else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
4800 if (ED->getLangOpts().CPlusPlus)
4801 DiagKind = 4;
4802 } else if (!isa<TagDecl>(D)) {
4803 return S.Diag(AttrLoc, diag::err_attribute_wrong_decl_type)
4805 << (Attr.isC11() ? ExpectedVariableOrField
4807 }
4808 if (DiagKind != -1) {
4809 return S.Diag(AttrLoc, diag::err_alignas_attribute_wrong_decl_type)
4810 << &Attr << DiagKind;
4811 }
4812 return false;
4813}
4814
4816 bool IsPackExpansion) {
4817 AlignedAttr TmpAttr(Context, CI, true, E);
4818 SourceLocation AttrLoc = CI.getLoc();
4819
4820 // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
4821 if (TmpAttr.isAlignas() &&
4822 validateAlignasAppliedType(*this, D, TmpAttr, AttrLoc))
4823 return;
4824
4825 if (E->isValueDependent()) {
4826 // We can't support a dependent alignment on a non-dependent type,
4827 // because we have no way to model that a type is "alignment-dependent"
4828 // but not dependent in any other way.
4829 if (const auto *TND = dyn_cast<TypedefNameDecl>(D)) {
4830 if (!TND->getUnderlyingType()->isDependentType()) {
4831 Diag(AttrLoc, diag::err_alignment_dependent_typedef_name)
4832 << E->getSourceRange();
4833 return;
4834 }
4835 }
4836
4837 // Save dependent expressions in the AST to be instantiated.
4838 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, E);
4839 AA->setPackExpansion(IsPackExpansion);
4840 D->addAttr(AA);
4841 return;
4842 }
4843
4844 // FIXME: Cache the number on the AL object?
4845 llvm::APSInt Alignment;
4847 E, &Alignment, diag::err_aligned_attribute_argument_not_int);
4848 if (ICE.isInvalid())
4849 return;
4850
4852 if (Context.getTargetInfo().getTriple().isOSBinFormatCOFF())
4853 MaximumAlignment = std::min(MaximumAlignment, uint64_t(8192));
4854 if (Alignment > MaximumAlignment) {
4855 Diag(AttrLoc, diag::err_attribute_aligned_too_great)
4857 return;
4858 }
4859
4860 uint64_t AlignVal = Alignment.getZExtValue();
4861 // C++11 [dcl.align]p2:
4862 // -- if the constant expression evaluates to zero, the alignment
4863 // specifier shall have no effect
4864 // C11 6.7.5p6:
4865 // An alignment specification of zero has no effect.
4866 if (!(TmpAttr.isAlignas() && !Alignment)) {
4867 if (!llvm::isPowerOf2_64(AlignVal)) {
4868 Diag(AttrLoc, diag::err_alignment_not_power_of_two)
4869 << E->getSourceRange();
4870 return;
4871 }
4872 }
4873
4874 const auto *VD = dyn_cast<VarDecl>(D);
4875 if (VD) {
4876 unsigned MaxTLSAlign =
4877 Context.toCharUnitsFromBits(Context.getTargetInfo().getMaxTLSAlign())
4878 .getQuantity();
4879 if (MaxTLSAlign && AlignVal > MaxTLSAlign &&
4880 VD->getTLSKind() != VarDecl::TLS_None) {
4881 Diag(VD->getLocation(), diag::err_tls_var_aligned_over_maximum)
4882 << (unsigned)AlignVal << VD << MaxTLSAlign;
4883 return;
4884 }
4885 }
4886
4887 // On AIX, an aligned attribute can not decrease the alignment when applied
4888 // to a variable declaration with vector type.
4889 if (VD && Context.getTargetInfo().getTriple().isOSAIX()) {
4890 const Type *Ty = VD->getType().getTypePtr();
4891 if (Ty->isVectorType() && AlignVal < 16) {
4892 Diag(VD->getLocation(), diag::warn_aligned_attr_underaligned)
4893 << VD->getType() << 16;
4894 return;
4895 }
4896 }
4897
4898 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, ICE.get());
4899 AA->setPackExpansion(IsPackExpansion);
4900 AA->setCachedAlignmentValue(
4901 static_cast<unsigned>(AlignVal * Context.getCharWidth()));
4902 D->addAttr(AA);
4903}
4904
4906 TypeSourceInfo *TS, bool IsPackExpansion) {
4907 AlignedAttr TmpAttr(Context, CI, false, TS);
4908 SourceLocation AttrLoc = CI.getLoc();
4909
4910 // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
4911 if (TmpAttr.isAlignas() &&
4912 validateAlignasAppliedType(*this, D, TmpAttr, AttrLoc))
4913 return;
4914
4915 if (TS->getType()->isDependentType()) {
4916 // We can't support a dependent alignment on a non-dependent type,
4917 // because we have no way to model that a type is "type-dependent"
4918 // but not dependent in any other way.
4919 if (const auto *TND = dyn_cast<TypedefNameDecl>(D)) {
4920 if (!TND->getUnderlyingType()->isDependentType()) {
4921 Diag(AttrLoc, diag::err_alignment_dependent_typedef_name)
4922 << TS->getTypeLoc().getSourceRange();
4923 return;
4924 }
4925 }
4926
4927 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, false, TS);
4928 AA->setPackExpansion(IsPackExpansion);
4929 D->addAttr(AA);
4930 return;
4931 }
4932
4933 const auto *VD = dyn_cast<VarDecl>(D);
4934 unsigned AlignVal = TmpAttr.getAlignment(Context);
4935 // On AIX, an aligned attribute can not decrease the alignment when applied
4936 // to a variable declaration with vector type.
4937 if (VD && Context.getTargetInfo().getTriple().isOSAIX()) {
4938 const Type *Ty = VD->getType().getTypePtr();
4939 if (Ty->isVectorType() &&
4940 Context.toCharUnitsFromBits(AlignVal).getQuantity() < 16) {
4941 Diag(VD->getLocation(), diag::warn_aligned_attr_underaligned)
4942 << VD->getType() << 16;
4943 return;
4944 }
4945 }
4946
4947 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, false, TS);
4948 AA->setPackExpansion(IsPackExpansion);
4949 AA->setCachedAlignmentValue(AlignVal);
4950 D->addAttr(AA);
4951}
4952
4954 assert(D->hasAttrs() && "no attributes on decl");
4955
4956 QualType UnderlyingTy, DiagTy;
4957 if (const auto *VD = dyn_cast<ValueDecl>(D)) {
4958 UnderlyingTy = DiagTy = VD->getType();
4959 } else {
4960 UnderlyingTy = DiagTy = Context.getCanonicalTagType(cast<TagDecl>(D));
4961 if (const auto *ED = dyn_cast<EnumDecl>(D))
4962 UnderlyingTy = ED->getIntegerType();
4963 }
4964 if (DiagTy->isDependentType() || DiagTy->isIncompleteType())
4965 return;
4966
4967 // C++11 [dcl.align]p5, C11 6.7.5/4:
4968 // The combined effect of all alignment attributes in a declaration shall
4969 // not specify an alignment that is less strict than the alignment that
4970 // would otherwise be required for the entity being declared.
4971 AlignedAttr *AlignasAttr = nullptr;
4972 AlignedAttr *LastAlignedAttr = nullptr;
4973 unsigned Align = 0;
4974 for (auto *I : D->specific_attrs<AlignedAttr>()) {
4975 if (I->isAlignmentDependent())
4976 return;
4977 if (I->isAlignas())
4978 AlignasAttr = I;
4979 Align = std::max(Align, I->getAlignment(Context));
4980 LastAlignedAttr = I;
4981 }
4982
4983 if (Align && DiagTy->isSizelessType()) {
4984 Diag(LastAlignedAttr->getLocation(), diag::err_attribute_sizeless_type)
4985 << LastAlignedAttr << DiagTy;
4986 } else if (AlignasAttr && Align) {
4987 CharUnits RequestedAlign = Context.toCharUnitsFromBits(Align);
4988 CharUnits NaturalAlign = Context.getTypeAlignInChars(UnderlyingTy);
4989 if (NaturalAlign > RequestedAlign)
4990 Diag(AlignasAttr->getLocation(), diag::err_alignas_underaligned)
4991 << DiagTy << (unsigned)NaturalAlign.getQuantity();
4992 }
4993}
4994
4996 CXXRecordDecl *RD, SourceRange Range, bool BestCase,
4997 MSInheritanceModel ExplicitModel) {
4998 assert(RD->hasDefinition() && "RD has no definition!");
4999
5000 // We may not have seen base specifiers or any virtual methods yet. We will
5001 // have to wait until the record is defined to catch any mismatches.
5002 if (!RD->getDefinition()->isCompleteDefinition())
5003 return false;
5004
5005 // The unspecified model never matches what a definition could need.
5006 if (ExplicitModel == MSInheritanceModel::Unspecified)
5007 return false;
5008
5009 if (BestCase) {
5010 if (RD->calculateInheritanceModel() == ExplicitModel)
5011 return false;
5012 } else {
5013 if (RD->calculateInheritanceModel() <= ExplicitModel)
5014 return false;
5015 }
5016
5017 Diag(Range.getBegin(), diag::err_mismatched_ms_inheritance)
5018 << 0 /*definition*/;
5019 Diag(RD->getDefinition()->getLocation(), diag::note_defined_here) << RD;
5020 return true;
5021}
5022
5023/// parseModeAttrArg - Parses attribute mode string and returns parsed type
5024/// attribute.
5025static void parseModeAttrArg(Sema &S, StringRef Str, unsigned &DestWidth,
5026 bool &IntegerMode, bool &ComplexMode,
5027 FloatModeKind &ExplicitType) {
5028 IntegerMode = true;
5029 ComplexMode = false;
5030 ExplicitType = FloatModeKind::NoFloat;
5031 switch (Str.size()) {
5032 case 2:
5033 switch (Str[0]) {
5034 case 'Q':
5035 DestWidth = 8;
5036 break;
5037 case 'H':
5038 DestWidth = 16;
5039 break;
5040 case 'S':
5041 DestWidth = 32;
5042 break;
5043 case 'D':
5044 DestWidth = 64;
5045 break;
5046 case 'X':
5047 DestWidth = 96;
5048 break;
5049 case 'K': // KFmode - IEEE quad precision (__float128)
5050 ExplicitType = FloatModeKind::Float128;
5051 DestWidth = Str[1] == 'I' ? 0 : 128;
5052 break;
5053 case 'T':
5054 ExplicitType = FloatModeKind::LongDouble;
5055 DestWidth = 128;
5056 break;
5057 case 'I':
5058 ExplicitType = FloatModeKind::Ibm128;
5059 DestWidth = Str[1] == 'I' ? 0 : 128;
5060 break;
5061 }
5062 if (Str[1] == 'F') {
5063 IntegerMode = false;
5064 } else if (Str[1] == 'C') {
5065 IntegerMode = false;
5066 ComplexMode = true;
5067 } else if (Str[1] != 'I') {
5068 DestWidth = 0;
5069 }
5070 break;
5071 case 4:
5072 // FIXME: glibc uses 'word' to define register_t; this is narrower than a
5073 // pointer on PIC16 and other embedded platforms.
5074 if (Str == "word")
5075 DestWidth = S.Context.getTargetInfo().getRegisterWidth();
5076 else if (Str == "byte")
5077 DestWidth = S.Context.getTargetInfo().getCharWidth();
5078 break;
5079 case 7:
5080 if (Str == "pointer")
5082 break;
5083 case 11:
5084 if (Str == "unwind_word")
5085 DestWidth = S.Context.getTargetInfo().getUnwindWordWidth();
5086 break;
5087 }
5088}
5089
5090/// handleModeAttr - This attribute modifies the width of a decl with primitive
5091/// type.
5092///
5093/// Despite what would be logical, the mode attribute is a decl attribute, not a
5094/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
5095/// HImode, not an intermediate pointer.
5096static void handleModeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5097 // This attribute isn't documented, but glibc uses it. It changes
5098 // the width of an int or unsigned int to the specified size.
5099 if (!AL.isArgIdent(0)) {
5100 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
5101 << AL << AANT_ArgumentIdentifier;
5102 return;
5103 }
5104
5106
5107 S.AddModeAttr(D, AL, Name);
5108}
5109
5111 const IdentifierInfo *Name, bool InInstantiation) {
5112 StringRef Str = Name->getName();
5113 normalizeName(Str);
5114 SourceLocation AttrLoc = CI.getLoc();
5115
5116 unsigned DestWidth = 0;
5117 bool IntegerMode = true;
5118 bool ComplexMode = false;
5120 llvm::APInt VectorSize(64, 0);
5121 if (Str.size() >= 4 && Str[0] == 'V') {
5122 // Minimal length of vector mode is 4: 'V' + NUMBER(>=1) + TYPE(>=2).
5123 size_t StrSize = Str.size();
5124 size_t VectorStringLength = 0;
5125 while ((VectorStringLength + 1) < StrSize &&
5126 isdigit(Str[VectorStringLength + 1]))
5127 ++VectorStringLength;
5128 if (VectorStringLength &&
5129 !Str.substr(1, VectorStringLength).getAsInteger(10, VectorSize) &&
5130 VectorSize.isPowerOf2()) {
5131 parseModeAttrArg(*this, Str.substr(VectorStringLength + 1), DestWidth,
5132 IntegerMode, ComplexMode, ExplicitType);
5133 // Avoid duplicate warning from template instantiation.
5134 if (!InInstantiation)
5135 Diag(AttrLoc, diag::warn_vector_mode_deprecated);
5136 } else {
5137 VectorSize = 0;
5138 }
5139 }
5140
5141 if (!VectorSize)
5142 parseModeAttrArg(*this, Str, DestWidth, IntegerMode, ComplexMode,
5143 ExplicitType);
5144
5145 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
5146 // and friends, at least with glibc.
5147 // FIXME: Make sure floating-point mappings are accurate
5148 // FIXME: Support XF and TF types
5149 if (!DestWidth) {
5150 Diag(AttrLoc, diag::err_machine_mode) << 0 /*Unknown*/ << Name;
5151 return;
5152 }
5153
5154 QualType OldTy;
5155 if (const auto *TD = dyn_cast<TypedefNameDecl>(D))
5156 OldTy = TD->getUnderlyingType();
5157 else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
5158 // Something like 'typedef enum { X } __attribute__((mode(XX))) T;'.
5159 // Try to get type from enum declaration, default to int.
5160 OldTy = ED->getIntegerType();
5161 if (OldTy.isNull())
5162 OldTy = Context.IntTy;
5163 } else
5164 OldTy = cast<ValueDecl>(D)->getType();
5165
5166 if (OldTy->isDependentType()) {
5167 D->addAttr(::new (Context) ModeAttr(Context, CI, Name));
5168 return;
5169 }
5170
5171 // Base type can also be a vector type (see PR17453).
5172 // Distinguish between base type and base element type.
5173 QualType OldElemTy = OldTy;
5174 if (const auto *VT = OldTy->getAs<VectorType>())
5175 OldElemTy = VT->getElementType();
5176
5177 // GCC allows 'mode' attribute on enumeration types (even incomplete), except
5178 // for vector modes. So, 'enum X __attribute__((mode(QI)));' forms a complete
5179 // type, 'enum { A } __attribute__((mode(V4SI)))' is rejected.
5180 if ((isa<EnumDecl>(D) || OldElemTy->isEnumeralType()) &&
5181 VectorSize.getBoolValue()) {
5182 Diag(AttrLoc, diag::err_enum_mode_vector_type) << Name << CI.getRange();
5183 return;
5184 }
5185 bool IntegralOrAnyEnumType = (OldElemTy->isIntegralOrEnumerationType() &&
5186 !OldElemTy->isBitIntType()) ||
5187 OldElemTy->isEnumeralType();
5188
5189 if (!OldElemTy->getAs<BuiltinType>() && !OldElemTy->isComplexType() &&
5190 !IntegralOrAnyEnumType)
5191 Diag(AttrLoc, diag::err_mode_not_primitive);
5192 else if (IntegerMode) {
5193 if (!IntegralOrAnyEnumType)
5194 Diag(AttrLoc, diag::err_mode_wrong_type);
5195 } else if (ComplexMode) {
5196 if (!OldElemTy->isComplexType())
5197 Diag(AttrLoc, diag::err_mode_wrong_type);
5198 } else {
5199 if (!OldElemTy->isFloatingType())
5200 Diag(AttrLoc, diag::err_mode_wrong_type);
5201 }
5202
5203 QualType NewElemTy;
5204
5205 if (IntegerMode)
5206 NewElemTy = Context.getIntTypeForBitwidth(DestWidth,
5207 OldElemTy->isSignedIntegerType());
5208 else
5209 NewElemTy = Context.getRealTypeForBitwidth(DestWidth, ExplicitType);
5210
5211 if (NewElemTy.isNull()) {
5212 // FIXME: We need to make sure that the target handles correctly the
5213 // requested mode.
5214 // Only emit diagnostic on host for 128-bit mode attribute
5215 if (!(DestWidth == 128 && getLangOpts().isTargetDevice()))
5216 Diag(AttrLoc, diag::err_machine_mode) << 1 /*Unsupported*/ << Name;
5217 return;
5218 }
5219
5220 if (ComplexMode) {
5221 NewElemTy = Context.getComplexType(NewElemTy);
5222 }
5223
5224 QualType NewTy = NewElemTy;
5225 if (VectorSize.getBoolValue()) {
5226 NewTy = Context.getVectorType(NewTy, VectorSize.getZExtValue(),
5228 } else if (const auto *OldVT = OldTy->getAs<VectorType>()) {
5229 // Complex machine mode does not support base vector types.
5230 if (ComplexMode) {
5231 Diag(AttrLoc, diag::err_complex_mode_vector_type);
5232 return;
5233 }
5234 unsigned NumElements = Context.getTypeSize(OldElemTy) *
5235 OldVT->getNumElements() /
5236 Context.getTypeSize(NewElemTy);
5237 NewTy =
5238 Context.getVectorType(NewElemTy, NumElements, OldVT->getVectorKind());
5239 }
5240
5241 if (NewTy.isNull()) {
5242 Diag(AttrLoc, diag::err_mode_wrong_type);
5243 return;
5244 }
5245
5246 // Install the new type.
5247 if (auto *TD = dyn_cast<TypedefNameDecl>(D))
5248 TD->setModedTypeSourceInfo(TD->getTypeSourceInfo(), NewTy);
5249 else if (auto *ED = dyn_cast<EnumDecl>(D))
5250 ED->setIntegerType(NewTy);
5251 else
5252 cast<ValueDecl>(D)->setType(NewTy);
5253
5254 D->addAttr(::new (Context) ModeAttr(Context, CI, Name));
5255}
5256
5257static void handleNonStringAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5258 // This only applies to fields and variable declarations which have an array
5259 // type or pointer type, with character elements.
5260 QualType QT = cast<ValueDecl>(D)->getType();
5261 if ((!QT->isArrayType() && !QT->isPointerType()) ||
5263 S.Diag(D->getBeginLoc(), diag::warn_attribute_non_character_array)
5264 << AL << AL.isRegularKeywordAttribute() << QT << AL.getRange();
5265 return;
5266 }
5267
5268 D->addAttr(::new (S.Context) NonStringAttr(S.Context, AL));
5269}
5270
5271static void handleNoDebugAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5272 D->addAttr(::new (S.Context) NoDebugAttr(S.Context, AL));
5273}
5274
5276 const AttributeCommonInfo &CI,
5277 const IdentifierInfo *Ident) {
5278 if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
5279 Diag(CI.getLoc(), diag::warn_attribute_ignored) << Ident;
5280 Diag(Optnone->getLocation(), diag::note_conflicting_attribute);
5281 return nullptr;
5282 }
5283
5284 if (D->hasAttr<AlwaysInlineAttr>())
5285 return nullptr;
5286
5287 return ::new (Context) AlwaysInlineAttr(Context, CI);
5288}
5289
5290InternalLinkageAttr *Sema::mergeInternalLinkageAttr(Decl *D,
5291 const ParsedAttr &AL) {
5292 if (const auto *VD = dyn_cast<VarDecl>(D)) {
5293 // Attribute applies to Var but not any subclass of it (like ParmVar,
5294 // ImplicitParm or VarTemplateSpecialization).
5295 if (VD->getKind() != Decl::Var) {
5296 Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
5297 << AL << AL.isRegularKeywordAttribute()
5300 return nullptr;
5301 }
5302 // Attribute does not apply to non-static local variables.
5303 if (VD->hasLocalStorage()) {
5304 Diag(VD->getLocation(), diag::warn_internal_linkage_local_storage);
5305 return nullptr;
5306 }
5307 }
5308
5309 return ::new (Context) InternalLinkageAttr(Context, AL);
5310}
5311InternalLinkageAttr *
5312Sema::mergeInternalLinkageAttr(Decl *D, const InternalLinkageAttr &AL) {
5313 if (const auto *VD = dyn_cast<VarDecl>(D)) {
5314 // Attribute applies to Var but not any subclass of it (like ParmVar,
5315 // ImplicitParm or VarTemplateSpecialization).
5316 if (VD->getKind() != Decl::Var) {
5317 Diag(AL.getLocation(), diag::warn_attribute_wrong_decl_type)
5318 << &AL << AL.isRegularKeywordAttribute()
5321 return nullptr;
5322 }
5323 // Attribute does not apply to non-static local variables.
5324 if (VD->hasLocalStorage()) {
5325 Diag(VD->getLocation(), diag::warn_internal_linkage_local_storage);
5326 return nullptr;
5327 }
5328 }
5329
5330 return ::new (Context) InternalLinkageAttr(Context, AL);
5331}
5332
5334 if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
5335 Diag(CI.getLoc(), diag::warn_attribute_ignored) << "'minsize'";
5336 Diag(Optnone->getLocation(), diag::note_conflicting_attribute);
5337 return nullptr;
5338 }
5339
5340 if (D->hasAttr<MinSizeAttr>())
5341 return nullptr;
5342
5343 return ::new (Context) MinSizeAttr(Context, CI);
5344}
5345
5347 const AttributeCommonInfo &CI) {
5348 if (AlwaysInlineAttr *Inline = D->getAttr<AlwaysInlineAttr>()) {
5349 Diag(Inline->getLocation(), diag::warn_attribute_ignored) << Inline;
5350 Diag(CI.getLoc(), diag::note_conflicting_attribute);
5351 D->dropAttr<AlwaysInlineAttr>();
5352 }
5353 if (MinSizeAttr *MinSize = D->getAttr<MinSizeAttr>()) {
5354 Diag(MinSize->getLocation(), diag::warn_attribute_ignored) << MinSize;
5355 Diag(CI.getLoc(), diag::note_conflicting_attribute);
5356 D->dropAttr<MinSizeAttr>();
5357 }
5358
5359 if (D->hasAttr<OptimizeNoneAttr>())
5360 return nullptr;
5361
5362 return ::new (Context) OptimizeNoneAttr(Context, CI);
5363}
5364
5365static void handleAlwaysInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5366 AlwaysInlineAttr AIA(S.Context, AL);
5367 if (!S.getLangOpts().MicrosoftExt &&
5368 (AIA.isMSVCForceInline() || AIA.isMSVCForceInlineCalls())) {
5369 S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
5370 return;
5371 }
5372 if (AIA.isMSVCForceInlineCalls()) {
5373 S.Diag(AL.getLoc(), diag::warn_stmt_attribute_ignored_in_function)
5374 << "[[msvc::forceinline]]";
5375 return;
5376 }
5377
5378 if (AlwaysInlineAttr *Inline =
5379 S.mergeAlwaysInlineAttr(D, AL, AL.getAttrName()))
5380 D->addAttr(Inline);
5381}
5382
5383static void handleMinSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5384 if (MinSizeAttr *MinSize = S.mergeMinSizeAttr(D, AL))
5385 D->addAttr(MinSize);
5386}
5387
5388static void handleOptimizeNoneAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5389 if (OptimizeNoneAttr *Optnone = S.mergeOptimizeNoneAttr(D, AL))
5390 D->addAttr(Optnone);
5391}
5392
5393static void handleConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5394 const auto *VD = cast<VarDecl>(D);
5395 if (VD->hasLocalStorage()) {
5396 S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
5397 return;
5398 }
5400 return;
5401 // constexpr variable may already get an implicit constant attr, which should
5402 // be replaced by the explicit constant attr.
5403 if (auto *A = D->getAttr<CUDAConstantAttr>()) {
5404 if (!A->isImplicit())
5405 return;
5406 D->dropAttr<CUDAConstantAttr>();
5407 }
5408 D->addAttr(::new (S.Context) CUDAConstantAttr(S.Context, AL));
5409}
5410
5411static void handleSharedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5412 const auto *VD = cast<VarDecl>(D);
5413 // extern __shared__ is only allowed on arrays with no length (e.g.
5414 // "int x[]").
5415 if (!S.getLangOpts().GPURelocatableDeviceCode && VD->hasExternalStorage() &&
5416 !isa<IncompleteArrayType>(VD->getType())) {
5417 S.Diag(AL.getLoc(), diag::err_cuda_extern_shared) << VD;
5418 return;
5419 }
5421 return;
5422 if (S.getLangOpts().CUDA && VD->hasLocalStorage() &&
5423 S.CUDA().DiagIfHostCode(AL.getLoc(), diag::err_cuda_host_shared)
5424 << S.CUDA().CurrentTarget())
5425 return;
5426 D->addAttr(::new (S.Context) CUDASharedAttr(S.Context, AL));
5427}
5428
5429static void handleGlobalAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5430 const auto *FD = cast<FunctionDecl>(D);
5431 if (!FD->getReturnType()->isVoidType() &&
5432 !FD->getReturnType()->getAs<AutoType>() &&
5434 SourceRange RTRange = FD->getReturnTypeSourceRange();
5435 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
5436 << FD->getType()
5437 << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void")
5438 : FixItHint());
5439 return;
5440 }
5441 if (const auto *Method = dyn_cast<CXXMethodDecl>(FD)) {
5442 if (Method->isInstance()) {
5443 S.Diag(Method->getBeginLoc(), diag::err_kern_is_nonstatic_method)
5444 << Method;
5445 return;
5446 }
5447 S.Diag(Method->getBeginLoc(), diag::warn_kern_is_method) << Method;
5448 }
5449 // Only warn for "inline" when compiling for host, to cut down on noise.
5450 if (FD->isInlineSpecified() && !S.getLangOpts().CUDAIsDevice)
5451 S.Diag(FD->getBeginLoc(), diag::warn_kern_is_inline) << FD;
5452
5453 switch (AL.getKind()) {
5454 case ParsedAttr::AT_DeviceKernel:
5455 if (!D->hasAttr<DeviceKernelAttr>())
5456 D->addAttr(::new (S.Context) DeviceKernelAttr(S.Context, AL));
5457 break;
5458 case ParsedAttr::AT_CUDAGlobal:
5459 if (!D->hasAttr<CUDAGlobalAttr>())
5460 D->addAttr(::new (S.Context) CUDAGlobalAttr(S.Context, AL));
5461 break;
5462 default:
5463 llvm_unreachable("Unexpected attribute kind");
5464 }
5465 // In host compilation the kernel is emitted as a stub function, which is
5466 // a helper function for launching the kernel. The instructions in the helper
5467 // function has nothing to do with the source code of the kernel. Do not emit
5468 // debug info for the stub function to avoid confusing the debugger.
5469 if (S.LangOpts.HIP && !S.LangOpts.CUDAIsDevice && !D->hasAttr<NoDebugAttr>())
5470 D->addAttr(NoDebugAttr::CreateImplicit(S.Context));
5471}
5472
5473static void handleDeviceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5474 if (const auto *VD = dyn_cast<VarDecl>(D)) {
5475 if (VD->hasLocalStorage()) {
5476 S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
5477 return;
5478 }
5480 return;
5481 }
5482
5483 if (auto *A = D->getAttr<CUDADeviceAttr>()) {
5484 if (!A->isImplicit())
5485 return;
5486 D->dropAttr<CUDADeviceAttr>();
5487 }
5488 D->addAttr(::new (S.Context) CUDADeviceAttr(S.Context, AL));
5489}
5490
5491static void handleManagedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5492 if (const auto *VD = dyn_cast<VarDecl>(D)) {
5493 if (VD->hasLocalStorage()) {
5494 S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
5495 return;
5496 }
5498 return;
5499 }
5500 if (!D->hasAttr<HIPManagedAttr>())
5501 D->addAttr(::new (S.Context) HIPManagedAttr(S.Context, AL));
5502 if (!D->hasAttr<CUDADeviceAttr>())
5503 D->addAttr(CUDADeviceAttr::CreateImplicit(S.Context));
5504}
5505
5506static void handleGridConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5507 if (D->isInvalidDecl())
5508 return;
5509 // Whether __grid_constant__ is allowed to be used will be checked in
5510 // Sema::CheckFunctionDeclaration as we need complete function decl to make
5511 // the call.
5512 D->addAttr(::new (S.Context) CUDAGridConstantAttr(S.Context, AL));
5513}
5514
5515static void handleGNUInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5516 const auto *Fn = cast<FunctionDecl>(D);
5517 if (!Fn->isInlineSpecified()) {
5518 S.Diag(AL.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
5519 return;
5520 }
5521
5522 if (S.LangOpts.CPlusPlus && Fn->getStorageClass() != SC_Extern)
5523 S.Diag(AL.getLoc(), diag::warn_gnu_inline_cplusplus_without_extern);
5524
5525 D->addAttr(::new (S.Context) GNUInlineAttr(S.Context, AL));
5526}
5527
5528static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5529 if (hasDeclarator(D)) return;
5530
5531 // Diagnostic is emitted elsewhere: here we store the (valid) AL
5532 // in the Decl node for syntactic reasoning, e.g., pretty-printing.
5533 CallingConv CC;
5535 AL, CC, /*FD*/ nullptr,
5536 S.CUDA().IdentifyTarget(dyn_cast<FunctionDecl>(D))))
5537 return;
5538
5539 if (!isa<ObjCMethodDecl>(D)) {
5540 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
5542 return;
5543 }
5544
5545 switch (AL.getKind()) {
5546 case ParsedAttr::AT_FastCall:
5547 D->addAttr(::new (S.Context) FastCallAttr(S.Context, AL));
5548 return;
5549 case ParsedAttr::AT_StdCall:
5550 D->addAttr(::new (S.Context) StdCallAttr(S.Context, AL));
5551 return;
5552 case ParsedAttr::AT_ThisCall:
5553 D->addAttr(::new (S.Context) ThisCallAttr(S.Context, AL));
5554 return;
5555 case ParsedAttr::AT_CDecl:
5556 D->addAttr(::new (S.Context) CDeclAttr(S.Context, AL));
5557 return;
5558 case ParsedAttr::AT_Pascal:
5559 D->addAttr(::new (S.Context) PascalAttr(S.Context, AL));
5560 return;
5561 case ParsedAttr::AT_SwiftCall:
5562 D->addAttr(::new (S.Context) SwiftCallAttr(S.Context, AL));
5563 return;
5564 case ParsedAttr::AT_SwiftAsyncCall:
5565 D->addAttr(::new (S.Context) SwiftAsyncCallAttr(S.Context, AL));
5566 return;
5567 case ParsedAttr::AT_VectorCall:
5568 D->addAttr(::new (S.Context) VectorCallAttr(S.Context, AL));
5569 return;
5570 case ParsedAttr::AT_MSABI:
5571 D->addAttr(::new (S.Context) MSABIAttr(S.Context, AL));
5572 return;
5573 case ParsedAttr::AT_SysVABI:
5574 D->addAttr(::new (S.Context) SysVABIAttr(S.Context, AL));
5575 return;
5576 case ParsedAttr::AT_RegCall:
5577 D->addAttr(::new (S.Context) RegCallAttr(S.Context, AL));
5578 return;
5579 case ParsedAttr::AT_Pcs: {
5580 PcsAttr::PCSType PCS;
5581 switch (CC) {
5582 case CC_AAPCS:
5583 PCS = PcsAttr::AAPCS;
5584 break;
5585 case CC_AAPCS_VFP:
5586 PCS = PcsAttr::AAPCS_VFP;
5587 break;
5588 default:
5589 llvm_unreachable("unexpected calling convention in pcs attribute");
5590 }
5591
5592 D->addAttr(::new (S.Context) PcsAttr(S.Context, AL, PCS));
5593 return;
5594 }
5595 case ParsedAttr::AT_AArch64VectorPcs:
5596 D->addAttr(::new (S.Context) AArch64VectorPcsAttr(S.Context, AL));
5597 return;
5598 case ParsedAttr::AT_AArch64SVEPcs:
5599 D->addAttr(::new (S.Context) AArch64SVEPcsAttr(S.Context, AL));
5600 return;
5601 case ParsedAttr::AT_DeviceKernel: {
5602 // The attribute should already be applied.
5603 assert(D->hasAttr<DeviceKernelAttr>() && "Expected attribute");
5604 return;
5605 }
5606 case ParsedAttr::AT_IntelOclBicc:
5607 D->addAttr(::new (S.Context) IntelOclBiccAttr(S.Context, AL));
5608 return;
5609 case ParsedAttr::AT_PreserveMost:
5610 D->addAttr(::new (S.Context) PreserveMostAttr(S.Context, AL));
5611 return;
5612 case ParsedAttr::AT_PreserveAll:
5613 D->addAttr(::new (S.Context) PreserveAllAttr(S.Context, AL));
5614 return;
5615 case ParsedAttr::AT_M68kRTD:
5616 D->addAttr(::new (S.Context) M68kRTDAttr(S.Context, AL));
5617 return;
5618 case ParsedAttr::AT_PreserveNone:
5619 D->addAttr(::new (S.Context) PreserveNoneAttr(S.Context, AL));
5620 return;
5621 case ParsedAttr::AT_RISCVVectorCC:
5622 D->addAttr(::new (S.Context) RISCVVectorCCAttr(S.Context, AL));
5623 return;
5624 case ParsedAttr::AT_RISCVVLSCC: {
5625 // If the riscv_abi_vlen doesn't have any argument, default ABI_VLEN is 128.
5626 unsigned VectorLength = 128;
5627 if (AL.getNumArgs() &&
5629 return;
5631 S.Diag(AL.getLoc(), diag::err_argument_invalid_range)
5632 << VectorLength << 32 << 65536;
5633 return;
5634 }
5635 if (!llvm::isPowerOf2_64(VectorLength)) {
5636 S.Diag(AL.getLoc(), diag::err_argument_not_power_of_2);
5637 return;
5638 }
5639
5640 D->addAttr(::new (S.Context) RISCVVLSCCAttr(S.Context, AL, VectorLength));
5641 return;
5642 }
5643 default:
5644 llvm_unreachable("unexpected attribute kind");
5645 }
5646}
5647
5648static void handleDeviceKernelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5649 const auto *FD = dyn_cast_or_null<FunctionDecl>(D);
5650 bool IsFunctionTemplate = FD && FD->getDescribedFunctionTemplate();
5651 llvm::Triple Triple = S.getASTContext().getTargetInfo().getTriple();
5652 const LangOptions &LangOpts = S.getLangOpts();
5653 // OpenCL has its own error messages.
5654 if (!LangOpts.OpenCL && FD && !FD->isExternallyVisible()) {
5655 S.Diag(AL.getLoc(), diag::err_hidden_device_kernel) << FD;
5656 AL.setInvalid();
5657 return;
5658 }
5659 if (Triple.isNVPTX()) {
5660 handleGlobalAttr(S, D, AL);
5661 } else {
5662 // OpenCL C++ will throw a more specific error.
5663 if (!LangOpts.OpenCLCPlusPlus && (!FD || IsFunctionTemplate)) {
5664 S.Diag(AL.getLoc(), diag::err_attribute_wrong_decl_type_str)
5665 << AL << AL.isRegularKeywordAttribute() << "functions";
5666 AL.setInvalid();
5667 return;
5668 }
5670 }
5671 // TODO: isGPU() should probably return true for SPIR.
5672 bool TargetDeviceEnvironment = Triple.isGPU() || Triple.isSPIR() ||
5673 LangOpts.isTargetDevice() || LangOpts.OpenCL;
5674 if (!TargetDeviceEnvironment) {
5675 S.Diag(AL.getLoc(), diag::warn_cconv_unsupported)
5677 AL.setInvalid();
5678 return;
5679 }
5680
5681 // Make sure we validate the CC with the target
5682 // and warn/error if necessary.
5683 handleCallConvAttr(S, D, AL);
5684}
5685
5686static void handleSuppressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5687 if (AL.getAttributeSpellingListIndex() == SuppressAttr::CXX11_gsl_suppress) {
5688 // Suppression attribute with GSL spelling requires at least 1 argument.
5689 if (!AL.checkAtLeastNumArgs(S, 1))
5690 return;
5691 }
5692
5693 std::vector<StringRef> DiagnosticIdentifiers;
5694 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
5695 StringRef RuleName;
5696
5697 if (!S.checkStringLiteralArgumentAttr(AL, I, RuleName, nullptr))
5698 return;
5699
5700 DiagnosticIdentifiers.push_back(RuleName);
5701 }
5702 D->addAttr(::new (S.Context)
5703 SuppressAttr(S.Context, AL, DiagnosticIdentifiers.data(),
5704 DiagnosticIdentifiers.size()));
5705}
5706
5707static void handleLifetimeCategoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5708 TypeSourceInfo *DerefTypeLoc = nullptr;
5709 QualType ParmType;
5710 if (AL.hasParsedType()) {
5711 ParmType = S.GetTypeFromParser(AL.getTypeArg(), &DerefTypeLoc);
5712
5713 unsigned SelectIdx = ~0U;
5714 if (ParmType->isReferenceType())
5715 SelectIdx = 0;
5716 else if (ParmType->isArrayType())
5717 SelectIdx = 1;
5718
5719 if (SelectIdx != ~0U) {
5720 S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument)
5721 << SelectIdx << AL;
5722 return;
5723 }
5724 }
5725
5726 // To check if earlier decl attributes do not conflict the newly parsed ones
5727 // we always add (and check) the attribute to the canonical decl. We need
5728 // to repeat the check for attribute mutual exclusion because we're attaching
5729 // all of the attributes to the canonical declaration rather than the current
5730 // declaration.
5731 D = D->getCanonicalDecl();
5732 if (AL.getKind() == ParsedAttr::AT_Owner) {
5734 return;
5735 if (const auto *OAttr = D->getAttr<OwnerAttr>()) {
5736 const Type *ExistingDerefType = OAttr->getDerefTypeLoc()
5737 ? OAttr->getDerefType().getTypePtr()
5738 : nullptr;
5739 if (ExistingDerefType != ParmType.getTypePtrOrNull()) {
5740 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
5741 << AL << OAttr
5742 << (AL.isRegularKeywordAttribute() ||
5743 OAttr->isRegularKeywordAttribute());
5744 S.Diag(OAttr->getLocation(), diag::note_conflicting_attribute);
5745 }
5746 return;
5747 }
5748 for (Decl *Redecl : D->redecls()) {
5749 Redecl->addAttr(::new (S.Context) OwnerAttr(S.Context, AL, DerefTypeLoc));
5750 }
5751 } else {
5753 return;
5754 if (const auto *PAttr = D->getAttr<PointerAttr>()) {
5755 const Type *ExistingDerefType = PAttr->getDerefTypeLoc()
5756 ? PAttr->getDerefType().getTypePtr()
5757 : nullptr;
5758 if (ExistingDerefType != ParmType.getTypePtrOrNull()) {
5759 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
5760 << AL << PAttr
5761 << (AL.isRegularKeywordAttribute() ||
5762 PAttr->isRegularKeywordAttribute());
5763 S.Diag(PAttr->getLocation(), diag::note_conflicting_attribute);
5764 }
5765 return;
5766 }
5767 for (Decl *Redecl : D->redecls()) {
5768 Redecl->addAttr(::new (S.Context)
5769 PointerAttr(S.Context, AL, DerefTypeLoc));
5770 }
5771 }
5772}
5773
5774static void handleRandomizeLayoutAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5776 return;
5777 if (!D->hasAttr<RandomizeLayoutAttr>())
5778 D->addAttr(::new (S.Context) RandomizeLayoutAttr(S.Context, AL));
5779}
5780
5782 const ParsedAttr &AL) {
5784 return;
5785 if (!D->hasAttr<NoRandomizeLayoutAttr>())
5786 D->addAttr(::new (S.Context) NoRandomizeLayoutAttr(S.Context, AL));
5787}
5788
5790 const FunctionDecl *FD,
5791 CUDAFunctionTarget CFT) {
5792 if (Attrs.isInvalid())
5793 return true;
5794
5795 if (Attrs.hasProcessingCache()) {
5796 CC = (CallingConv) Attrs.getProcessingCache();
5797 return false;
5798 }
5799
5800 if (Attrs.getKind() == ParsedAttr::AT_RISCVVLSCC) {
5801 // riscv_vls_cc only accepts 0 or 1 argument.
5802 if (!Attrs.checkAtLeastNumArgs(*this, 0) ||
5803 !Attrs.checkAtMostNumArgs(*this, 1)) {
5804 Attrs.setInvalid();
5805 return true;
5806 }
5807 } else {
5808 unsigned ReqArgs = Attrs.getKind() == ParsedAttr::AT_Pcs ? 1 : 0;
5809 if (!Attrs.checkExactlyNumArgs(*this, ReqArgs)) {
5810 Attrs.setInvalid();
5811 return true;
5812 }
5813 }
5814
5815 bool IsTargetDefaultMSABI =
5816 Context.getTargetInfo().getTriple().isOSWindows() ||
5817 Context.getTargetInfo().getTriple().isUEFI();
5818 // TODO: diagnose uses of these conventions on the wrong target.
5819 switch (Attrs.getKind()) {
5820 case ParsedAttr::AT_CDecl:
5821 CC = CC_C;
5822 break;
5823 case ParsedAttr::AT_FastCall:
5824 CC = CC_X86FastCall;
5825 break;
5826 case ParsedAttr::AT_StdCall:
5827 CC = CC_X86StdCall;
5828 break;
5829 case ParsedAttr::AT_ThisCall:
5830 CC = CC_X86ThisCall;
5831 break;
5832 case ParsedAttr::AT_Pascal:
5833 CC = CC_X86Pascal;
5834 break;
5835 case ParsedAttr::AT_SwiftCall:
5836 CC = CC_Swift;
5837 break;
5838 case ParsedAttr::AT_SwiftAsyncCall:
5839 CC = CC_SwiftAsync;
5840 break;
5841 case ParsedAttr::AT_VectorCall:
5842 CC = CC_X86VectorCall;
5843 break;
5844 case ParsedAttr::AT_AArch64VectorPcs:
5846 break;
5847 case ParsedAttr::AT_AArch64SVEPcs:
5848 CC = CC_AArch64SVEPCS;
5849 break;
5850 case ParsedAttr::AT_RegCall:
5851 CC = CC_X86RegCall;
5852 break;
5853 case ParsedAttr::AT_MSABI:
5854 CC = IsTargetDefaultMSABI ? CC_C : CC_Win64;
5855 break;
5856 case ParsedAttr::AT_SysVABI:
5857 CC = IsTargetDefaultMSABI ? CC_X86_64SysV : CC_C;
5858 break;
5859 case ParsedAttr::AT_Pcs: {
5860 StringRef StrRef;
5861 if (!checkStringLiteralArgumentAttr(Attrs, 0, StrRef)) {
5862 Attrs.setInvalid();
5863 return true;
5864 }
5865 if (StrRef == "aapcs") {
5866 CC = CC_AAPCS;
5867 break;
5868 } else if (StrRef == "aapcs-vfp") {
5869 CC = CC_AAPCS_VFP;
5870 break;
5871 }
5872
5873 Attrs.setInvalid();
5874 Diag(Attrs.getLoc(), diag::err_invalid_pcs);
5875 return true;
5876 }
5877 case ParsedAttr::AT_IntelOclBicc:
5878 CC = CC_IntelOclBicc;
5879 break;
5880 case ParsedAttr::AT_PreserveMost:
5881 CC = CC_PreserveMost;
5882 break;
5883 case ParsedAttr::AT_PreserveAll:
5884 CC = CC_PreserveAll;
5885 break;
5886 case ParsedAttr::AT_M68kRTD:
5887 CC = CC_M68kRTD;
5888 break;
5889 case ParsedAttr::AT_PreserveNone:
5890 CC = CC_PreserveNone;
5891 break;
5892 case ParsedAttr::AT_RISCVVectorCC:
5893 CC = CC_RISCVVectorCall;
5894 break;
5895 case ParsedAttr::AT_RISCVVLSCC: {
5896 // If the riscv_abi_vlen doesn't have any argument, we set set it to default
5897 // value 128.
5898 unsigned ABIVLen = 128;
5899 if (Attrs.getNumArgs() &&
5900 !checkUInt32Argument(Attrs, Attrs.getArgAsExpr(0), ABIVLen)) {
5901 Attrs.setInvalid();
5902 return true;
5903 }
5904 if (Attrs.getNumArgs() && (ABIVLen < 32 || ABIVLen > 65536)) {
5905 Attrs.setInvalid();
5906 Diag(Attrs.getLoc(), diag::err_argument_invalid_range)
5907 << ABIVLen << 32 << 65536;
5908 return true;
5909 }
5910 if (!llvm::isPowerOf2_64(ABIVLen)) {
5911 Attrs.setInvalid();
5912 Diag(Attrs.getLoc(), diag::err_argument_not_power_of_2);
5913 return true;
5914 }
5916 llvm::Log2_64(ABIVLen) - 5);
5917 break;
5918 }
5919 case ParsedAttr::AT_DeviceKernel: {
5920 // Validation was handled in handleDeviceKernelAttr.
5921 CC = CC_DeviceKernel;
5922 break;
5923 }
5924 default: llvm_unreachable("unexpected attribute kind");
5925 }
5926
5928 const TargetInfo &TI = Context.getTargetInfo();
5929 auto *Aux = Context.getAuxTargetInfo();
5930 // CUDA functions may have host and/or device attributes which indicate
5931 // their targeted execution environment, therefore the calling convention
5932 // of functions in CUDA should be checked against the target deduced based
5933 // on their host/device attributes.
5934 if (LangOpts.CUDA) {
5935 assert(FD || CFT != CUDAFunctionTarget::InvalidTarget);
5936 auto CudaTarget = FD ? CUDA().IdentifyTarget(FD) : CFT;
5937 bool CheckHost = false, CheckDevice = false;
5938 switch (CudaTarget) {
5940 CheckHost = true;
5941 CheckDevice = true;
5942 break;
5944 CheckHost = true;
5945 break;
5948 CheckDevice = true;
5949 break;
5951 llvm_unreachable("unexpected cuda target");
5952 }
5953 auto *HostTI = LangOpts.CUDAIsDevice ? Aux : &TI;
5954 auto *DeviceTI = LangOpts.CUDAIsDevice ? &TI : Aux;
5955 if (CheckHost && HostTI)
5956 A = HostTI->checkCallingConvention(CC);
5957 if (A == TargetInfo::CCCR_OK && CheckDevice && DeviceTI)
5958 A = DeviceTI->checkCallingConvention(CC);
5959 } else if (LangOpts.SYCLIsDevice) {
5960 // During device compilation, calling conventions that are valid for the
5961 // host, for the device, and for both the host and the device may be
5962 // encountered. Diagnostics are desired for cases where the calling
5963 // convention is not supported by either the host or the device. If Aux is
5964 // null (which should rarely be the case), it isn't possible to check
5965 // whether the calling convention is supported by the host, so just assume
5966 // that it is. If the calling convention is supported for the device, there
5967 // is no need to check the host; the device target gets priority since this
5968 // check is only performed during device compilation.
5969 A = TI.checkCallingConvention(CC);
5970 if (Aux && A == TargetInfo::CCCR_Warning) {
5971 // If the calling convention would provoke a warning for the device, check
5972 // the host and preserve the warning only if the calling convention would
5973 // provoke an error for the host. Otherwise, assume this calling
5974 // convention is only used for host only functions.
5975 A = Aux->checkCallingConvention(CC);
5976 if (A == TargetInfo::CCCR_Error)
5978 } else if (Aux && A == TargetInfo::CCCR_Error) {
5979 // Assume this calling convention is only used for host only functions.
5980 A = Aux->checkCallingConvention(CC);
5981 }
5982 } else {
5983 A = TI.checkCallingConvention(CC);
5984 }
5985
5986 switch (A) {
5988 break;
5989
5991 // Treat an ignored convention as if it was an explicit C calling convention
5992 // attribute. For example, __stdcall on Win x64 functions as __cdecl, so
5993 // that command line flags that change the default convention to
5994 // __vectorcall don't affect declarations marked __stdcall.
5995 CC = CC_C;
5996 break;
5997
5999 Diag(Attrs.getLoc(), diag::error_cconv_unsupported)
6001 break;
6002
6004 Diag(Attrs.getLoc(), diag::warn_cconv_unsupported)
6006
6007 // This convention is not valid for the target. Use the default function or
6008 // method calling convention.
6009 bool IsCXXMethod = false, IsVariadic = false;
6010 if (FD) {
6011 IsCXXMethod = FD->isCXXInstanceMember();
6012 IsVariadic = FD->isVariadic();
6013 }
6014 CC = Context.getDefaultCallingConvention(IsVariadic, IsCXXMethod);
6015 break;
6016 }
6017 }
6018
6019 Attrs.setProcessingCache((unsigned) CC);
6020 return false;
6021}
6022
6023bool Sema::CheckRegparmAttr(const ParsedAttr &AL, unsigned &numParams) {
6024 if (AL.isInvalid())
6025 return true;
6026
6027 if (!AL.checkExactlyNumArgs(*this, 1)) {
6028 AL.setInvalid();
6029 return true;
6030 }
6031
6032 uint32_t NP;
6033 Expr *NumParamsExpr = AL.getArgAsExpr(0);
6034 if (!checkUInt32Argument(AL, NumParamsExpr, NP)) {
6035 AL.setInvalid();
6036 return true;
6037 }
6038
6039 if (Context.getTargetInfo().getRegParmMax() == 0) {
6040 Diag(AL.getLoc(), diag::err_attribute_regparm_wrong_platform)
6041 << NumParamsExpr->getSourceRange();
6042 AL.setInvalid();
6043 return true;
6044 }
6045
6046 numParams = NP;
6047 if (numParams > Context.getTargetInfo().getRegParmMax()) {
6048 Diag(AL.getLoc(), diag::err_attribute_regparm_invalid_number)
6049 << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
6050 AL.setInvalid();
6051 return true;
6052 }
6053
6054 return false;
6055}
6056
6057// Helper to get OffloadArch.
6059 if (!TI.getTriple().isNVPTX())
6060 llvm_unreachable("getOffloadArch is only valid for NVPTX triple");
6061 auto &TO = TI.getTargetOpts();
6062 return StringToOffloadArch(TO.CPU);
6063}
6064
6065// Checks whether an argument of launch_bounds attribute is
6066// acceptable, performs implicit conversion to Rvalue, and returns
6067// non-nullptr Expr result on success. Otherwise, it returns nullptr
6068// and may output an error.
6070 const CUDALaunchBoundsAttr &AL,
6071 const unsigned Idx) {
6073 return nullptr;
6074
6075 // Accept template arguments for now as they depend on something else.
6076 // We'll get to check them when they eventually get instantiated.
6077 if (E->isValueDependent())
6078 return E;
6079
6080 std::optional<llvm::APSInt> I = llvm::APSInt(64);
6081 if (!(I = E->getIntegerConstantExpr(S.Context))) {
6082 S.Diag(E->getExprLoc(), diag::err_attribute_argument_n_type)
6083 << &AL << Idx << AANT_ArgumentIntegerConstant << E->getSourceRange();
6084 return nullptr;
6085 }
6086 // Make sure we can fit it in 32 bits.
6087 if (!I->isIntN(32)) {
6088 S.Diag(E->getExprLoc(), diag::err_ice_too_large)
6089 << toString(*I, 10, false) << 32 << /* Unsigned */ 1;
6090 return nullptr;
6091 }
6092 if (*I < 0)
6093 S.Diag(E->getExprLoc(), diag::warn_attribute_argument_n_negative)
6094 << &AL << Idx << E->getSourceRange();
6095
6096 // We may need to perform implicit conversion of the argument.
6098 S.Context, S.Context.getConstType(S.Context.IntTy), /*consume*/ false);
6099 ExprResult ValArg = S.PerformCopyInitialization(Entity, SourceLocation(), E);
6100 assert(!ValArg.isInvalid() &&
6101 "Unexpected PerformCopyInitialization() failure.");
6102
6103 return ValArg.getAs<Expr>();
6104}
6105
6106CUDALaunchBoundsAttr *
6108 Expr *MinBlocks, Expr *MaxBlocks,
6109 bool IgnoreArch) {
6110 CUDALaunchBoundsAttr TmpAttr(Context, CI, MaxThreads, MinBlocks, MaxBlocks);
6111 MaxThreads = makeLaunchBoundsArgExpr(*this, MaxThreads, TmpAttr, 0);
6112 if (!MaxThreads)
6113 return nullptr;
6114
6115 if (MinBlocks) {
6116 MinBlocks = makeLaunchBoundsArgExpr(*this, MinBlocks, TmpAttr, 1);
6117 if (!MinBlocks)
6118 return nullptr;
6119 }
6120
6121 if (MaxBlocks) {
6122 // We might want to ignore the nvptx arch check, e.g., when processing the
6123 // launch bounds attribute within ompx_attribute to support other archs.
6124 if (!IgnoreArch) {
6125 const TargetInfo &DeviceTI =
6126 (!Context.getLangOpts().CUDAIsDevice && Context.getAuxTargetInfo())
6127 ? *Context.getAuxTargetInfo()
6128 : Context.getTargetInfo();
6129 if (DeviceTI.getTriple().isNVPTX()) {
6130 // '.maxclusterrank' ptx directive requires .target sm_90 or higher.
6131 OffloadArch SM = getOffloadArch(DeviceTI);
6132 if (SM.isUnknown() || llvm::NVPTX::getSmVersion(SM.nvptxKind()) < 900) {
6133 Diag(MaxBlocks->getBeginLoc(), diag::warn_cuda_maxclusterrank_sm_90)
6134 << OffloadArchToString(SM) << CI << MaxBlocks->getSourceRange();
6135 // Ignore it by setting MaxBlocks to null;
6136 MaxBlocks = nullptr;
6137 }
6138 } else {
6139 // maxclusterrank is only handled for NVPTX; ignore it elsewhere.
6140 // TODO: Interpret this for AMDGPU with the "clusters" subtarget
6141 // feature.
6142 MaxBlocks = nullptr;
6143 }
6144 }
6145
6146 if (MaxBlocks) {
6147 MaxBlocks = makeLaunchBoundsArgExpr(*this, MaxBlocks, TmpAttr, 2);
6148 if (!MaxBlocks)
6149 return nullptr;
6150 }
6151 }
6152
6153 return ::new (Context)
6154 CUDALaunchBoundsAttr(Context, CI, MaxThreads, MinBlocks, MaxBlocks);
6155}
6156
6158 Expr *MaxThreads, Expr *MinBlocks,
6159 Expr *MaxBlocks) {
6160 if (auto *Attr = CreateLaunchBoundsAttr(CI, MaxThreads, MinBlocks, MaxBlocks))
6161 D->addAttr(Attr);
6162}
6163
6164static void handleLaunchBoundsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6165 if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 3))
6166 return;
6167
6168 S.AddLaunchBoundsAttr(D, AL, AL.getArgAsExpr(0),
6169 AL.getNumArgs() > 1 ? AL.getArgAsExpr(1) : nullptr,
6170 AL.getNumArgs() > 2 ? AL.getArgAsExpr(2) : nullptr);
6171}
6172
6173static std::pair<Expr *, int>
6174makeClusterDimsArgExpr(Sema &S, Expr *E, const CUDAClusterDimsAttr &AL,
6175 const unsigned Idx) {
6176 if (!E || S.DiagnoseUnexpandedParameterPack(E))
6177 return {};
6178
6179 // Accept template arguments for now as they depend on something else.
6180 // We'll get to check them when they eventually get instantiated.
6181 if (E->isInstantiationDependent())
6182 return {E, 1};
6183
6184 std::optional<llvm::APSInt> I = E->getIntegerConstantExpr(S.Context);
6185 if (!I) {
6186 S.Diag(E->getExprLoc(), diag::err_attribute_argument_n_type)
6187 << &AL << Idx << AANT_ArgumentIntegerConstant << E->getSourceRange();
6188 return {};
6189 }
6190 // Make sure we can fit it in 4 bits.
6191 if (!I->isIntN(4)) {
6192 S.Diag(E->getExprLoc(), diag::err_ice_too_large)
6193 << toString(*I, 10, false) << 4 << /*Unsigned=*/1;
6194 return {};
6195 }
6196 if (*I < 0) {
6197 S.Diag(E->getExprLoc(), diag::warn_attribute_argument_n_negative)
6198 << &AL << Idx << E->getSourceRange();
6199 }
6200
6201 return {ConstantExpr::Create(S.getASTContext(), E, APValue(*I)),
6202 I->getZExtValue()};
6203}
6204
6206 Expr *X, Expr *Y, Expr *Z) {
6207 CUDAClusterDimsAttr TmpAttr(Context, CI, X, Y, Z);
6208
6209 auto [NewX, ValX] = makeClusterDimsArgExpr(*this, X, TmpAttr, /*Idx=*/0);
6210 auto [NewY, ValY] = makeClusterDimsArgExpr(*this, Y, TmpAttr, /*Idx=*/1);
6211 auto [NewZ, ValZ] = makeClusterDimsArgExpr(*this, Z, TmpAttr, /*Idx=*/2);
6212
6213 if (!NewX || (Y && !NewY) || (Z && !NewZ))
6214 return nullptr;
6215
6216 int FlatDim = ValX * ValY * ValZ;
6217 const llvm::Triple TT =
6218 (!Context.getLangOpts().CUDAIsDevice && Context.getAuxTargetInfo())
6219 ? Context.getAuxTargetInfo()->getTriple()
6220 : Context.getTargetInfo().getTriple();
6221 int MaxDim = 1;
6222 if (TT.isNVPTX())
6223 MaxDim = 8;
6224 else if (TT.isAMDGPU())
6225 MaxDim = 16;
6226 else
6227 return nullptr;
6228
6229 // A maximum of 8 thread blocks in a cluster is supported as a portable
6230 // cluster size in CUDA. The number is 16 for AMDGPU.
6231 if (FlatDim > MaxDim) {
6232 Diag(CI.getLoc(), diag::err_cluster_dims_too_large) << MaxDim << FlatDim;
6233 return nullptr;
6234 }
6235
6236 return CUDAClusterDimsAttr::Create(Context, NewX, NewY, NewZ, CI);
6237}
6238
6240 Expr *Y, Expr *Z) {
6241 if (auto *Attr = createClusterDimsAttr(CI, X, Y, Z))
6242 D->addAttr(Attr);
6243}
6244
6246 D->addAttr(CUDANoClusterAttr::Create(Context, CI));
6247}
6248
6249static void handleClusterDimsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6250 const TargetInfo &TTI = S.Context.getTargetInfo();
6252 if ((TTI.getTriple().isNVPTX() &&
6253 llvm::NVPTX::getSmVersion(Arch.nvptxKind()) < 900) ||
6254 (TTI.getTriple().isAMDGPU() &&
6255 !TTI.hasFeatureEnabled(TTI.getTargetOpts().FeatureMap, "clusters"))) {
6256 S.Diag(AL.getLoc(), diag::err_cluster_attr_not_supported) << AL;
6257 return;
6258 }
6259
6260 if (!AL.checkAtLeastNumArgs(S, /*Num=*/1) ||
6261 !AL.checkAtMostNumArgs(S, /*Num=*/3))
6262 return;
6263
6264 S.addClusterDimsAttr(D, AL, AL.getArgAsExpr(0),
6265 AL.getNumArgs() > 1 ? AL.getArgAsExpr(1) : nullptr,
6266 AL.getNumArgs() > 2 ? AL.getArgAsExpr(2) : nullptr);
6267}
6268
6269static void handleNoClusterAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6270 const TargetInfo &TTI = S.Context.getTargetInfo();
6272 if ((TTI.getTriple().isNVPTX() &&
6273 llvm::NVPTX::getSmVersion(Arch.nvptxKind()) < 900) ||
6274 (TTI.getTriple().isAMDGPU() &&
6275 !TTI.hasFeatureEnabled(TTI.getTargetOpts().FeatureMap, "clusters"))) {
6276 S.Diag(AL.getLoc(), diag::err_cluster_attr_not_supported) << AL;
6277 return;
6278 }
6279
6280 S.addNoClusterAttr(D, AL);
6281}
6282
6284 const ParsedAttr &AL) {
6285 if (!AL.isArgIdent(0)) {
6286 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
6287 << AL << /* arg num = */ 1 << AANT_ArgumentIdentifier;
6288 return;
6289 }
6290
6291 ParamIdx ArgumentIdx;
6293 D, AL, 2, AL.getArgAsExpr(1), ArgumentIdx,
6294 /*CanIndexImplicitThis=*/false,
6295 /*CanIndexVariadicArguments=*/true))
6296 return;
6297
6298 ParamIdx TypeTagIdx;
6300 D, AL, 3, AL.getArgAsExpr(2), TypeTagIdx,
6301 /*CanIndexImplicitThis=*/false,
6302 /*CanIndexVariadicArguments=*/true))
6303 return;
6304
6305 bool IsPointer = AL.getAttrName()->getName() == "pointer_with_type_tag";
6306 if (IsPointer) {
6307 // Ensure that buffer has a pointer type.
6308 unsigned ArgumentIdxAST = ArgumentIdx.getASTIndex();
6309 if (ArgumentIdxAST >= getFunctionOrMethodNumParams(D) ||
6310 !getFunctionOrMethodParamType(D, ArgumentIdxAST)->isPointerType())
6311 S.Diag(AL.getLoc(), diag::err_attribute_pointers_only) << AL << 0;
6312 }
6313
6314 D->addAttr(::new (S.Context) ArgumentWithTypeTagAttr(
6315 S.Context, AL, AL.getArgAsIdent(0)->getIdentifierInfo(), ArgumentIdx,
6316 TypeTagIdx, IsPointer));
6317}
6318
6320 const ParsedAttr &AL) {
6321 if (!AL.isArgIdent(0)) {
6322 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
6323 << AL << 1 << AANT_ArgumentIdentifier;
6324 return;
6325 }
6326
6327 if (!AL.checkExactlyNumArgs(S, 1))
6328 return;
6329
6330 if (!isa<VarDecl>(D)) {
6331 S.Diag(AL.getLoc(), diag::err_attribute_wrong_decl_type)
6333 return;
6334 }
6335
6336 IdentifierInfo *PointerKind = AL.getArgAsIdent(0)->getIdentifierInfo();
6337 TypeSourceInfo *MatchingCTypeLoc = nullptr;
6338 S.GetTypeFromParser(AL.getMatchingCType(), &MatchingCTypeLoc);
6339 assert(MatchingCTypeLoc && "no type source info for attribute argument");
6340
6341 D->addAttr(::new (S.Context) TypeTagForDatatypeAttr(
6342 S.Context, AL, PointerKind, MatchingCTypeLoc, AL.getLayoutCompatible(),
6343 AL.getMustBeNull()));
6344}
6345
6346static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6347 ParamIdx ArgCount;
6348
6350 ArgCount,
6351 true /* CanIndexImplicitThis */))
6352 return;
6353
6354 // ArgCount isn't a parameter index [0;n), it's a count [1;n]
6355 D->addAttr(::new (S.Context)
6356 XRayLogArgsAttr(S.Context, AL, ArgCount.getSourceIndex()));
6357}
6358
6360 const ParsedAttr &AL) {
6361 if (S.Context.getTargetInfo().getTriple().isOSAIX()) {
6362 S.Diag(AL.getLoc(), diag::err_aix_attr_unsupported) << AL;
6363 return;
6364 }
6365 uint32_t Count = 0, Offset = 0;
6366 StringRef Section;
6367 if (!S.checkUInt32Argument(AL, AL.getArgAsExpr(0), Count, 0, true))
6368 return;
6369 if (AL.getNumArgs() >= 2) {
6370 Expr *Arg = AL.getArgAsExpr(1);
6371 if (!S.checkUInt32Argument(AL, Arg, Offset, 1, true))
6372 return;
6373 if (Count < Offset) {
6374 S.Diag(S.getAttrLoc(AL), diag::err_attribute_argument_out_of_range)
6375 << &AL << 0 << Count << Arg->getBeginLoc();
6376 return;
6377 }
6378 }
6379 if (AL.getNumArgs() == 3) {
6380 SourceLocation LiteralLoc;
6381 if (!S.checkStringLiteralArgumentAttr(AL, 2, Section, &LiteralLoc))
6382 return;
6383 if (llvm::Error E = S.isValidSectionSpecifier(Section)) {
6384 S.Diag(LiteralLoc,
6385 diag::err_attribute_patchable_function_entry_invalid_section)
6386 << toString(std::move(E));
6387 return;
6388 }
6389 if (Section.empty()) {
6390 S.Diag(LiteralLoc,
6391 diag::err_attribute_patchable_function_entry_invalid_section)
6392 << "section must not be empty";
6393 return;
6394 }
6395 }
6396 D->addAttr(::new (S.Context) PatchableFunctionEntryAttr(S.Context, AL, Count,
6397 Offset, Section));
6398}
6399
6400static void handleBuiltinAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6401 if (!AL.isArgIdent(0)) {
6402 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
6403 << AL << 1 << AANT_ArgumentIdentifier;
6404 return;
6405 }
6406
6408 unsigned BuiltinID = Ident->getBuiltinID();
6409 StringRef AliasName = cast<FunctionDecl>(D)->getIdentifier()->getName();
6410
6411 bool IsAArch64 = S.Context.getTargetInfo().getTriple().isAArch64();
6412 bool IsARM = S.Context.getTargetInfo().getTriple().isARM();
6413 bool IsRISCV = S.Context.getTargetInfo().getTriple().isRISCV();
6414 bool IsSPIRV = S.Context.getTargetInfo().getTriple().isSPIRV();
6415 bool IsHLSL = S.Context.getLangOpts().HLSL;
6416 if ((IsAArch64 && !S.ARM().SveAliasValid(BuiltinID, AliasName)) ||
6417 (IsARM && !S.ARM().MveAliasValid(BuiltinID, AliasName) &&
6418 !S.ARM().CdeAliasValid(BuiltinID, AliasName)) ||
6419 (IsRISCV && !S.RISCV().isAliasValid(BuiltinID, AliasName)) ||
6420 (!IsAArch64 && !IsARM && !IsRISCV && !IsHLSL && !IsSPIRV)) {
6421 S.Diag(AL.getLoc(), diag::err_attribute_builtin_alias) << AL;
6422 return;
6423 }
6424
6425 D->addAttr(::new (S.Context) BuiltinAliasAttr(S.Context, AL, Ident));
6426}
6427
6428static void handleNullableTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6429 if (AL.isUsedAsTypeAttr())
6430 return;
6431
6432 if (auto *CRD = dyn_cast<CXXRecordDecl>(D);
6433 !CRD || !(CRD->isClass() || CRD->isStruct())) {
6434 S.Diag(AL.getRange().getBegin(), diag::err_attribute_wrong_decl_type)
6436 return;
6437 }
6438
6440}
6441
6442static void handlePreferredTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6443 if (!AL.hasParsedType()) {
6444 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
6445 return;
6446 }
6447
6448 TypeSourceInfo *ParmTSI = nullptr;
6449 QualType QT = S.GetTypeFromParser(AL.getTypeArg(), &ParmTSI);
6450 assert(ParmTSI && "no type source info for attribute argument");
6451 S.RequireCompleteType(ParmTSI->getTypeLoc().getBeginLoc(), QT,
6452 diag::err_incomplete_type);
6453
6454 D->addAttr(::new (S.Context) PreferredTypeAttr(S.Context, AL, ParmTSI));
6455}
6456
6457//===----------------------------------------------------------------------===//
6458// Microsoft specific attribute handlers.
6459//===----------------------------------------------------------------------===//
6460
6462 StringRef UuidAsWritten, MSGuidDecl *GuidDecl) {
6463 if (const auto *UA = D->getAttr<UuidAttr>()) {
6464 if (declaresSameEntity(UA->getGuidDecl(), GuidDecl))
6465 return nullptr;
6466 if (!UA->getGuid().empty()) {
6467 Diag(UA->getLocation(), diag::err_mismatched_uuid);
6468 Diag(CI.getLoc(), diag::note_previous_uuid);
6469 D->dropAttr<UuidAttr>();
6470 }
6471 }
6472
6473 return ::new (Context) UuidAttr(Context, CI, UuidAsWritten, GuidDecl);
6474}
6475
6476static void handleUuidAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6477 if (!S.LangOpts.CPlusPlus) {
6478 S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)
6479 << AL << AttributeLangSupport::C;
6480 return;
6481 }
6482
6483 StringRef OrigStrRef;
6484 SourceLocation LiteralLoc;
6485 if (!S.checkStringLiteralArgumentAttr(AL, 0, OrigStrRef, &LiteralLoc))
6486 return;
6487
6488 // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
6489 // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", normalize to the former.
6490 StringRef StrRef = OrigStrRef;
6491 if (StrRef.size() == 38 && StrRef.front() == '{' && StrRef.back() == '}')
6492 StrRef = StrRef.drop_front().drop_back();
6493
6494 // Validate GUID length.
6495 if (StrRef.size() != 36) {
6496 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
6497 return;
6498 }
6499
6500 for (unsigned i = 0; i < 36; ++i) {
6501 if (i == 8 || i == 13 || i == 18 || i == 23) {
6502 if (StrRef[i] != '-') {
6503 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
6504 return;
6505 }
6506 } else if (!isHexDigit(StrRef[i])) {
6507 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
6508 return;
6509 }
6510 }
6511
6512 // Convert to our parsed format and canonicalize.
6513 MSGuidDecl::Parts Parsed;
6514 StrRef.substr(0, 8).getAsInteger(16, Parsed.Part1);
6515 StrRef.substr(9, 4).getAsInteger(16, Parsed.Part2);
6516 StrRef.substr(14, 4).getAsInteger(16, Parsed.Part3);
6517 for (unsigned i = 0; i != 8; ++i)
6518 StrRef.substr(19 + 2 * i + (i >= 2 ? 1 : 0), 2)
6519 .getAsInteger(16, Parsed.Part4And5[i]);
6520 MSGuidDecl *Guid = S.Context.getMSGuidDecl(Parsed);
6521
6522 // FIXME: It'd be nice to also emit a fixit removing uuid(...) (and, if it's
6523 // the only thing in the [] list, the [] too), and add an insertion of
6524 // __declspec(uuid(...)). But sadly, neither the SourceLocs of the commas
6525 // separating attributes nor of the [ and the ] are in the AST.
6526 // Cf "SourceLocations of attribute list delimiters - [[ ... , ... ]] etc"
6527 // on cfe-dev.
6528 if (AL.isMicrosoftAttribute()) // Check for [uuid(...)] spelling.
6529 S.Diag(AL.getLoc(), diag::warn_atl_uuid_deprecated);
6530
6531 UuidAttr *UA = S.mergeUuidAttr(D, AL, OrigStrRef, Guid);
6532 if (UA)
6533 D->addAttr(UA);
6534}
6535
6536static void handleMSInheritanceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6537 if (!S.LangOpts.CPlusPlus) {
6538 S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)
6539 << AL << AttributeLangSupport::C;
6540 return;
6541 }
6542 MSInheritanceAttr *IA = S.mergeMSInheritanceAttr(
6543 D, AL, /*BestCase=*/true, (MSInheritanceModel)AL.getSemanticSpelling());
6544 if (IA) {
6545 D->addAttr(IA);
6547 }
6548}
6549
6550static void handleDeclspecThreadAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6551 const auto *VD = cast<VarDecl>(D);
6553 S.Diag(AL.getLoc(), diag::err_thread_unsupported);
6554 return;
6555 }
6556 if (VD->getTSCSpec() != TSCS_unspecified) {
6557 S.Diag(AL.getLoc(), diag::err_declspec_thread_on_thread_variable);
6558 return;
6559 }
6560 if (VD->hasLocalStorage()) {
6561 S.Diag(AL.getLoc(), diag::err_thread_non_global) << "__declspec(thread)";
6562 return;
6563 }
6564 D->addAttr(::new (S.Context) ThreadAttr(S.Context, AL));
6565}
6566
6567static void handleMSConstexprAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6569 S.Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)
6570 << AL << AL.getRange();
6571 return;
6572 }
6573 auto *FD = cast<FunctionDecl>(D);
6574 if (FD->isConstexprSpecified() || FD->isConsteval()) {
6575 S.Diag(AL.getLoc(), diag::err_ms_constexpr_cannot_be_applied)
6576 << FD->isConsteval() << FD;
6577 return;
6578 }
6579 if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
6580 if (!S.getLangOpts().CPlusPlus20 && MD->isVirtual()) {
6581 S.Diag(AL.getLoc(), diag::err_ms_constexpr_cannot_be_applied)
6582 << /*virtual*/ 2 << MD;
6583 return;
6584 }
6585 }
6586 D->addAttr(::new (S.Context) MSConstexprAttr(S.Context, AL));
6587}
6588
6589static void handleMSStructAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6590 if (const auto *First = D->getAttr<GCCStructAttr>()) {
6591 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
6592 << AL << First << 0;
6593 S.Diag(First->getLocation(), diag::note_conflicting_attribute);
6594 return;
6595 }
6596 if (const auto *Preexisting = D->getAttr<MSStructAttr>()) {
6597 if (Preexisting->isImplicit())
6598 D->dropAttr<MSStructAttr>();
6599 }
6600
6601 D->addAttr(::new (S.Context) MSStructAttr(S.Context, AL));
6602}
6603
6604static void handleGCCStructAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6605 if (const auto *First = D->getAttr<MSStructAttr>()) {
6606 if (First->isImplicit()) {
6607 D->dropAttr<MSStructAttr>();
6608 } else {
6609 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
6610 << AL << First << 0;
6611 S.Diag(First->getLocation(), diag::note_conflicting_attribute);
6612 return;
6613 }
6614 }
6615
6616 D->addAttr(::new (S.Context) GCCStructAttr(S.Context, AL));
6617}
6618
6619static void handleAbiTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6621 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
6622 StringRef Tag;
6623 if (!S.checkStringLiteralArgumentAttr(AL, I, Tag))
6624 return;
6625 Tags.push_back(Tag);
6626 }
6627
6628 if (const auto *NS = dyn_cast<NamespaceDecl>(D)) {
6629 if (!NS->isInline()) {
6630 S.Diag(AL.getLoc(), diag::warn_attr_abi_tag_namespace) << 0;
6631 return;
6632 }
6633 if (NS->isAnonymousNamespace()) {
6634 S.Diag(AL.getLoc(), diag::warn_attr_abi_tag_namespace) << 1;
6635 return;
6636 }
6637 if (AL.getNumArgs() == 0)
6638 Tags.push_back(NS->getName());
6639 } else if (!AL.checkAtLeastNumArgs(S, 1))
6640 return;
6641
6642 // Store tags sorted and without duplicates.
6643 llvm::sort(Tags);
6644 Tags.erase(llvm::unique(Tags), Tags.end());
6645
6646 D->addAttr(::new (S.Context)
6647 AbiTagAttr(S.Context, AL, Tags.data(), Tags.size()));
6648}
6649
6650static bool hasBTFDeclTagAttr(Decl *D, StringRef Tag) {
6651 for (const auto *I : D->specific_attrs<BTFDeclTagAttr>()) {
6652 if (I->getBTFDeclTag() == Tag)
6653 return true;
6654 }
6655 return false;
6656}
6657
6658static void handleBTFDeclTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6659 StringRef Str;
6660 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
6661 return;
6662 if (hasBTFDeclTagAttr(D, Str))
6663 return;
6664
6665 D->addAttr(::new (S.Context) BTFDeclTagAttr(S.Context, AL, Str));
6666}
6667
6668BTFDeclTagAttr *Sema::mergeBTFDeclTagAttr(Decl *D, const BTFDeclTagAttr &AL) {
6669 if (hasBTFDeclTagAttr(D, AL.getBTFDeclTag()))
6670 return nullptr;
6671 return ::new (Context) BTFDeclTagAttr(Context, AL, AL.getBTFDeclTag());
6672}
6673
6674static void handleInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6675 // Dispatch the interrupt attribute based on the current target.
6676 switch (S.Context.getTargetInfo().getTriple().getArch()) {
6677 case llvm::Triple::msp430:
6678 S.MSP430().handleInterruptAttr(D, AL);
6679 break;
6680 case llvm::Triple::mipsel:
6681 case llvm::Triple::mips:
6682 S.MIPS().handleInterruptAttr(D, AL);
6683 break;
6684 case llvm::Triple::m68k:
6685 S.M68k().handleInterruptAttr(D, AL);
6686 break;
6687 case llvm::Triple::x86:
6688 case llvm::Triple::x86_64:
6689 S.X86().handleAnyInterruptAttr(D, AL);
6690 break;
6691 case llvm::Triple::avr:
6692 S.AVR().handleInterruptAttr(D, AL);
6693 break;
6694 case llvm::Triple::riscv32:
6695 case llvm::Triple::riscv64:
6696 case llvm::Triple::riscv32be:
6697 case llvm::Triple::riscv64be:
6698 S.RISCV().handleInterruptAttr(D, AL);
6699 break;
6700 default:
6701 S.ARM().handleInterruptAttr(D, AL);
6702 break;
6703 }
6704}
6705
6706static void handleLayoutVersion(Sema &S, Decl *D, const ParsedAttr &AL) {
6707 uint32_t Version;
6708 Expr *VersionExpr = AL.getArgAsExpr(0);
6709 if (!S.checkUInt32Argument(AL, AL.getArgAsExpr(0), Version))
6710 return;
6711
6712 // TODO: Investigate what happens with the next major version of MSVC.
6713 if (Version != LangOptions::MSVC2015 / 100) {
6714 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
6715 << AL << Version << VersionExpr->getSourceRange();
6716 return;
6717 }
6718
6719 // The attribute expects a "major" version number like 19, but new versions of
6720 // MSVC have moved to updating the "minor", or less significant numbers, so we
6721 // have to multiply by 100 now.
6722 Version *= 100;
6723
6724 D->addAttr(::new (S.Context) LayoutVersionAttr(S.Context, AL, Version));
6725}
6726
6728 const AttributeCommonInfo &CI) {
6729 if (D->hasAttr<DLLExportAttr>()) {
6730 Diag(CI.getLoc(), diag::warn_attribute_ignored) << "'dllimport'";
6731 return nullptr;
6732 }
6733
6734 if (D->hasAttr<DLLImportAttr>())
6735 return nullptr;
6736
6737 return ::new (Context) DLLImportAttr(Context, CI);
6738}
6739
6741 const AttributeCommonInfo &CI) {
6742 if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) {
6743 Diag(Import->getLocation(), diag::warn_attribute_ignored) << Import;
6744 D->dropAttr<DLLImportAttr>();
6745 }
6746
6747 if (D->hasAttr<DLLExportAttr>())
6748 return nullptr;
6749
6750 return ::new (Context) DLLExportAttr(Context, CI);
6751}
6752
6753static void handleDLLAttr(Sema &S, Decl *D, const ParsedAttr &A) {
6756 S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored) << A;
6757 return;
6758 }
6759
6760 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
6761 if (FD->isInlined() && A.getKind() == ParsedAttr::AT_DLLImport &&
6763 // MinGW doesn't allow dllimport on inline functions.
6764 S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored_on_inline)
6765 << A;
6766 return;
6767 }
6768 }
6769
6770 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
6772 MD->getParent()->isLambda()) {
6773 S.Diag(A.getRange().getBegin(), diag::err_attribute_dll_lambda) << A;
6774 return;
6775 }
6776 }
6777
6778 if (auto *EA = D->getAttr<ExcludeFromExplicitInstantiationAttr>()) {
6779 S.Diag(A.getRange().getBegin(),
6780 diag::warn_dllattr_ignored_exclusion_takes_precedence)
6781 << A << EA;
6782 return;
6783 }
6784
6785 Attr *NewAttr = A.getKind() == ParsedAttr::AT_DLLExport
6786 ? (Attr *)S.mergeDLLExportAttr(D, A)
6787 : (Attr *)S.mergeDLLImportAttr(D, A);
6788 if (NewAttr)
6789 D->addAttr(NewAttr);
6790}
6791
6792MSInheritanceAttr *
6794 bool BestCase,
6795 MSInheritanceModel Model) {
6796 if (MSInheritanceAttr *IA = D->getAttr<MSInheritanceAttr>()) {
6797 if (IA->getInheritanceModel() == Model)
6798 return nullptr;
6799 Diag(IA->getLocation(), diag::err_mismatched_ms_inheritance)
6800 << 1 /*previous declaration*/;
6801 Diag(CI.getLoc(), diag::note_previous_ms_inheritance);
6802 D->dropAttr<MSInheritanceAttr>();
6803 }
6804
6805 auto *RD = cast<CXXRecordDecl>(D);
6806 if (RD->hasDefinition()) {
6807 if (checkMSInheritanceAttrOnDefinition(RD, CI.getRange(), BestCase,
6808 Model)) {
6809 return nullptr;
6810 }
6811 } else {
6813 Diag(CI.getLoc(), diag::warn_ignored_ms_inheritance)
6814 << 1 /*partial specialization*/;
6815 return nullptr;
6816 }
6817 if (RD->getDescribedClassTemplate()) {
6818 Diag(CI.getLoc(), diag::warn_ignored_ms_inheritance)
6819 << 0 /*primary template*/;
6820 return nullptr;
6821 }
6822 }
6823
6824 return ::new (Context) MSInheritanceAttr(Context, CI, BestCase);
6825}
6826
6827static void handleCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6828 // The capability attributes take a single string parameter for the name of
6829 // the capability they represent. The lockable attribute does not take any
6830 // parameters. However, semantically, both attributes represent the same
6831 // concept, and so they use the same semantic attribute. Eventually, the
6832 // lockable attribute will be removed.
6833 //
6834 // For backward compatibility, any capability which has no specified string
6835 // literal will be considered a "mutex."
6836 StringRef N("mutex");
6837 SourceLocation LiteralLoc;
6838 if (AL.getKind() == ParsedAttr::AT_Capability &&
6839 !S.checkStringLiteralArgumentAttr(AL, 0, N, &LiteralLoc))
6840 return;
6841
6842 D->addAttr(::new (S.Context) CapabilityAttr(S.Context, AL, N));
6843}
6844
6846 const ParsedAttr &AL) {
6847 // Do not permit 'reentrant_capability' without 'capability(..)'. Note that
6848 // the check here requires 'capability' to be before 'reentrant_capability'.
6849 // This helps enforce a canonical style. Also avoids placing an additional
6850 // branch into ProcessDeclAttributeList().
6851 if (!D->hasAttr<CapabilityAttr>()) {
6852 S.Diag(AL.getLoc(), diag::warn_thread_attribute_requires_preceded)
6853 << AL << cast<NamedDecl>(D) << "'capability'";
6854 return;
6855 }
6856
6857 D->addAttr(::new (S.Context) ReentrantCapabilityAttr(S.Context, AL));
6858}
6859
6860static void handleAssertCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6861 if (!checkThreadSafetyAttrSubject(S, D, AL))
6862 return;
6863
6865 if (!checkLockFunAttrCommon(S, D, AL, Args))
6866 return;
6867
6868 D->addAttr(::new (S.Context)
6869 AssertCapabilityAttr(S.Context, AL, Args.data(), Args.size()));
6870}
6871
6873 const ParsedAttr &AL) {
6874 if (!checkThreadSafetyAttrSubject(S, D, AL, /*CheckParmVar=*/true))
6875 return;
6876
6878 if (!checkLockFunAttrCommon(S, D, AL, Args))
6879 return;
6880
6881 D->addAttr(::new (S.Context) AcquireCapabilityAttr(S.Context, AL, Args.data(),
6882 Args.size()));
6883}
6884
6886 const ParsedAttr &AL) {
6887 if (!checkThreadSafetyAttrSubject(S, D, AL))
6888 return;
6889
6891 if (!checkTryLockFunAttrCommon(S, D, AL, Args))
6892 return;
6893
6894 D->addAttr(::new (S.Context) TryAcquireCapabilityAttr(
6895 S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));
6896}
6897
6899 const ParsedAttr &AL) {
6900 if (!checkThreadSafetyAttrSubject(S, D, AL, /*CheckParmVar=*/true))
6901 return;
6902
6903 // Check that all arguments are lockable objects.
6905 checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 0, true);
6906
6907 D->addAttr(::new (S.Context) ReleaseCapabilityAttr(S.Context, AL, Args.data(),
6908 Args.size()));
6909}
6910
6912 const ParsedAttr &AL) {
6913 if (!checkThreadSafetyAttrSubject(S, D, AL, /*CheckParmVar=*/true))
6914 return;
6915
6916 if (!AL.checkAtLeastNumArgs(S, 1))
6917 return;
6918
6919 // check that all arguments are lockable objects
6921 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
6922 if (Args.empty())
6923 return;
6924
6925 RequiresCapabilityAttr *RCA = ::new (S.Context)
6926 RequiresCapabilityAttr(S.Context, AL, Args.data(), Args.size());
6927
6928 D->addAttr(RCA);
6929}
6930
6931static void handleDeprecatedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6932 if (const auto *NSD = dyn_cast<NamespaceDecl>(D)) {
6933 if (NSD->isAnonymousNamespace()) {
6934 S.Diag(AL.getLoc(), diag::warn_deprecated_anonymous_namespace);
6935 // Do not want to attach the attribute to the namespace because that will
6936 // cause confusing diagnostic reports for uses of declarations within the
6937 // namespace.
6938 return;
6939 }
6942 S.Diag(AL.getRange().getBegin(), diag::warn_deprecated_ignored_on_using)
6943 << AL;
6944 return;
6945 }
6946
6947 // Handle the cases where the attribute has a text message.
6948 StringRef Str, Replacement;
6949 if (AL.isArgExpr(0) && AL.getArgAsExpr(0) &&
6950 !S.checkStringLiteralArgumentAttr(AL, 0, Str))
6951 return;
6952
6953 // Support a single optional message only for Declspec and [[]] spellings.
6955 AL.checkAtMostNumArgs(S, 1);
6956 else if (AL.isArgExpr(1) && AL.getArgAsExpr(1) &&
6957 !S.checkStringLiteralArgumentAttr(AL, 1, Replacement))
6958 return;
6959
6960 if (!S.getLangOpts().CPlusPlus14 && AL.isCXX11Attribute() && !AL.isGNUScope())
6961 S.Diag(AL.getLoc(), diag::ext_cxx14_attr) << AL;
6962
6963 D->addAttr(::new (S.Context) DeprecatedAttr(S.Context, AL, Str, Replacement));
6964}
6965
6966static bool isGlobalVar(const Decl *D) {
6967 if (const auto *S = dyn_cast<VarDecl>(D))
6968 return S->hasGlobalStorage();
6969 return false;
6970}
6971
6972static bool isSanitizerAttributeAllowedOnGlobals(StringRef Sanitizer) {
6973 return Sanitizer == "address" || Sanitizer == "hwaddress" ||
6974 Sanitizer == "memtag";
6975}
6976
6977static void handleNoSanitizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6978 if (!AL.checkAtLeastNumArgs(S, 1))
6979 return;
6980
6981 std::vector<StringRef> Sanitizers;
6982
6983 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
6984 StringRef SanitizerName;
6985 SourceLocation LiteralLoc;
6986
6987 if (!S.checkStringLiteralArgumentAttr(AL, I, SanitizerName, &LiteralLoc))
6988 return;
6989
6990 if (parseSanitizerValue(SanitizerName, /*AllowGroups=*/true) ==
6991 SanitizerMask() &&
6992 SanitizerName != "coverage")
6993 S.Diag(LiteralLoc, diag::warn_unknown_sanitizer_ignored) << SanitizerName;
6994 else if (isGlobalVar(D) && !isSanitizerAttributeAllowedOnGlobals(SanitizerName))
6995 S.Diag(D->getLocation(), diag::warn_attribute_type_not_supported_global)
6996 << AL << SanitizerName;
6997 Sanitizers.push_back(SanitizerName);
6998 }
6999
7000 D->addAttr(::new (S.Context) NoSanitizeAttr(S.Context, AL, Sanitizers.data(),
7001 Sanitizers.size()));
7002}
7003
7005getNoSanitizeAttrInfo(const ParsedAttr &NoSanitizeSpecificAttr) {
7006 // FIXME: Rather than create a NoSanitizeSpecificAttr, this creates a
7007 // NoSanitizeAttr object; but we need to calculate the correct spelling list
7008 // index rather than incorrectly assume the index for NoSanitizeSpecificAttr
7009 // has the same spellings as the index for NoSanitizeAttr. We don't have a
7010 // general way to "translate" between the two, so this hack attempts to work
7011 // around the issue with hard-coded indices. This is critical for calling
7012 // getSpelling() or prettyPrint() on the resulting semantic attribute object
7013 // without failing assertions.
7014 unsigned TranslatedSpellingIndex = 0;
7015 if (NoSanitizeSpecificAttr.isStandardAttributeSyntax())
7016 TranslatedSpellingIndex = 1;
7017
7018 AttributeCommonInfo Info = NoSanitizeSpecificAttr;
7019 Info.setAttributeSpellingListIndex(TranslatedSpellingIndex);
7020 return Info;
7021}
7022
7024 const ParsedAttr &AL) {
7025 StringRef SanitizerName = "address";
7027 D->addAttr(::new (S.Context)
7028 NoSanitizeAttr(S.Context, Info, &SanitizerName, 1));
7029}
7030
7031static void handleNoSanitizeThreadAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7032 StringRef SanitizerName = "thread";
7034 D->addAttr(::new (S.Context)
7035 NoSanitizeAttr(S.Context, Info, &SanitizerName, 1));
7036}
7037
7038static void handleNoSanitizeMemoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7039 StringRef SanitizerName = "memory";
7041 D->addAttr(::new (S.Context)
7042 NoSanitizeAttr(S.Context, Info, &SanitizerName, 1));
7043}
7044
7045static void handleInternalLinkageAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7046 if (InternalLinkageAttr *Internal = S.mergeInternalLinkageAttr(D, AL))
7047 D->addAttr(Internal);
7048}
7049
7050static void handleZeroCallUsedRegsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7051 // Check that the argument is a string literal.
7052 StringRef KindStr;
7053 SourceLocation LiteralLoc;
7054 if (!S.checkStringLiteralArgumentAttr(AL, 0, KindStr, &LiteralLoc))
7055 return;
7056
7057 ZeroCallUsedRegsAttr::ZeroCallUsedRegsKind Kind;
7058 if (!ZeroCallUsedRegsAttr::ConvertStrToZeroCallUsedRegsKind(KindStr, Kind)) {
7059 S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported)
7060 << AL << KindStr;
7061 return;
7062 }
7063
7064 D->dropAttr<ZeroCallUsedRegsAttr>();
7065 D->addAttr(ZeroCallUsedRegsAttr::Create(S.Context, Kind, AL));
7066}
7067
7068static void handleNoPFPAttrField(Sema &S, Decl *D, const ParsedAttr &AL) {
7069 D->addAttr(NoFieldProtectionAttr::Create(S.Context, AL));
7070}
7071
7072static void handleCountedByAttrField(Sema &S, Decl *D, const ParsedAttr &AL) {
7073 auto *CountExpr = AL.getArgAsExpr(0);
7074 if (!CountExpr)
7075 return;
7076
7077 bool CountInBytes;
7078 bool OrNull;
7079 switch (AL.getKind()) {
7080 case ParsedAttr::AT_CountedBy:
7081 CountInBytes = false;
7082 OrNull = false;
7083 break;
7084 case ParsedAttr::AT_CountedByOrNull:
7085 CountInBytes = false;
7086 OrNull = true;
7087 break;
7088 case ParsedAttr::AT_SizedBy:
7089 CountInBytes = true;
7090 OrNull = false;
7091 break;
7092 case ParsedAttr::AT_SizedByOrNull:
7093 CountInBytes = true;
7094 OrNull = true;
7095 break;
7096 default:
7097 llvm_unreachable("unexpected counted_by family attribute");
7098 }
7099
7100 FieldDecl *FD = cast<FieldDecl>(D);
7101 if (S.CheckCountedByAttrOnField(FD, CountExpr, CountInBytes, OrNull))
7102 return;
7103
7105 FD->getType(), CountExpr, CountInBytes, OrNull);
7106 FD->setType(CAT);
7107}
7108
7110 const ParsedAttr &AL) {
7111 StringRef KindStr;
7112 SourceLocation LiteralLoc;
7113 if (!S.checkStringLiteralArgumentAttr(AL, 0, KindStr, &LiteralLoc))
7114 return;
7115
7116 FunctionReturnThunksAttr::Kind Kind;
7117 if (!FunctionReturnThunksAttr::ConvertStrToKind(KindStr, Kind)) {
7118 S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported)
7119 << AL << KindStr;
7120 return;
7121 }
7122 // FIXME: it would be good to better handle attribute merging rather than
7123 // silently replacing the existing attribute, so long as it does not break
7124 // the expected codegen tests.
7125 D->dropAttr<FunctionReturnThunksAttr>();
7126 D->addAttr(FunctionReturnThunksAttr::Create(S.Context, Kind, AL));
7127}
7128
7130 const ParsedAttr &AL) {
7131 assert(isa<TypedefNameDecl>(D) && "This attribute only applies to a typedef");
7133}
7134
7135static void handleNoMergeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7136 auto *VDecl = dyn_cast<VarDecl>(D);
7137 if (VDecl && !VDecl->isFunctionPointerType()) {
7138 S.Diag(AL.getLoc(), diag::warn_attribute_ignored_non_function_pointer)
7139 << AL << VDecl;
7140 return;
7141 }
7142 D->addAttr(NoMergeAttr::Create(S.Context, AL));
7143}
7144
7145static void handleNoUniqueAddressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7146 D->addAttr(NoUniqueAddressAttr::Create(S.Context, AL));
7147}
7148
7149static void handleDestroyAttr(Sema &S, Decl *D, const ParsedAttr &A) {
7150 if (!cast<VarDecl>(D)->hasGlobalStorage()) {
7151 S.Diag(D->getLocation(), diag::err_destroy_attr_on_non_static_var)
7152 << (A.getKind() == ParsedAttr::AT_AlwaysDestroy);
7153 return;
7154 }
7155
7156 if (A.getKind() == ParsedAttr::AT_AlwaysDestroy)
7158 else
7160}
7161
7162static void handleUninitializedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7163 assert(cast<VarDecl>(D)->getStorageDuration() == SD_Automatic &&
7164 "uninitialized is only valid on automatic duration variables");
7165 D->addAttr(::new (S.Context) UninitializedAttr(S.Context, AL));
7166}
7167
7168static void handleMIGServerRoutineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7169 // Check that the return type is a `typedef int kern_return_t` or a typedef
7170 // around it, because otherwise MIG convention checks make no sense.
7171 // BlockDecl doesn't store a return type, so it's annoying to check,
7172 // so let's skip it for now.
7173 if (!isa<BlockDecl>(D)) {
7175 bool IsKernReturnT = false;
7176 while (const auto *TT = T->getAs<TypedefType>()) {
7177 IsKernReturnT = (TT->getDecl()->getName() == "kern_return_t");
7178 T = TT->desugar();
7179 }
7180 if (!IsKernReturnT || T.getCanonicalType() != S.getASTContext().IntTy) {
7181 S.Diag(D->getBeginLoc(),
7182 diag::warn_mig_server_routine_does_not_return_kern_return_t);
7183 return;
7184 }
7185 }
7186
7188}
7189
7190static void handleMSAllocatorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7191 // Warn if the return type is not a pointer or reference type.
7192 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
7193 QualType RetTy = FD->getReturnType();
7194 if (!RetTy->isPointerOrReferenceType()) {
7195 S.Diag(AL.getLoc(), diag::warn_declspec_allocator_nonpointer)
7196 << AL.getRange() << RetTy;
7197 return;
7198 }
7199 }
7200
7202}
7203
7204static void handleAcquireHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7205 if (AL.isUsedAsTypeAttr())
7206 return;
7207 // Warn if the parameter is definitely not an output parameter.
7208 if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
7209 if (PVD->getType()->isIntegerType()) {
7210 S.Diag(AL.getLoc(), diag::err_attribute_output_parameter)
7211 << AL.getRange();
7212 return;
7213 }
7214 }
7215 StringRef Argument;
7216 if (!S.checkStringLiteralArgumentAttr(AL, 0, Argument))
7217 return;
7218 D->addAttr(AcquireHandleAttr::Create(S.Context, Argument, AL));
7219}
7220
7221template<typename Attr>
7222static void handleHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7223 StringRef Argument;
7224 if (!S.checkStringLiteralArgumentAttr(AL, 0, Argument))
7225 return;
7226 D->addAttr(Attr::Create(S.Context, Argument, AL));
7227}
7228
7229template<typename Attr>
7230static void handleUnsafeBufferUsage(Sema &S, Decl *D, const ParsedAttr &AL) {
7231 D->addAttr(Attr::Create(S.Context, AL));
7232}
7233
7234static void handleCFGuardAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7235 // The guard attribute takes a single identifier argument.
7236
7237 if (!AL.isArgIdent(0)) {
7238 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7239 << AL << AANT_ArgumentIdentifier;
7240 return;
7241 }
7242
7243 CFGuardAttr::GuardArg Arg;
7245 if (!CFGuardAttr::ConvertStrToGuardArg(II->getName(), Arg)) {
7246 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
7247 return;
7248 }
7249
7250 D->addAttr(::new (S.Context) CFGuardAttr(S.Context, AL, Arg));
7251}
7252
7253
7254template <typename AttrTy>
7255static const AttrTy *findEnforceTCBAttrByName(Decl *D, StringRef Name) {
7256 auto Attrs = D->specific_attrs<AttrTy>();
7257 auto I = llvm::find_if(Attrs,
7258 [Name](const AttrTy *A) {
7259 return A->getTCBName() == Name;
7260 });
7261 return I == Attrs.end() ? nullptr : *I;
7262}
7263
7264template <typename AttrTy, typename ConflictingAttrTy>
7265static void handleEnforceTCBAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7266 StringRef Argument;
7267 if (!S.checkStringLiteralArgumentAttr(AL, 0, Argument))
7268 return;
7269
7270 // A function cannot be have both regular and leaf membership in the same TCB.
7271 if (const ConflictingAttrTy *ConflictingAttr =
7273 // We could attach a note to the other attribute but in this case
7274 // there's no need given how the two are very close to each other.
7275 S.Diag(AL.getLoc(), diag::err_tcb_conflicting_attributes)
7276 << AL.getAttrName()->getName() << ConflictingAttr->getAttrName()->getName()
7277 << Argument;
7278
7279 // Error recovery: drop the non-leaf attribute so that to suppress
7280 // all future warnings caused by erroneous attributes. The leaf attribute
7281 // needs to be kept because it can only suppresses warnings, not cause them.
7282 D->dropAttr<EnforceTCBAttr>();
7283 return;
7284 }
7285
7286 D->addAttr(AttrTy::Create(S.Context, Argument, AL));
7287}
7288
7289template <typename AttrTy, typename ConflictingAttrTy>
7290static AttrTy *mergeEnforceTCBAttrImpl(Sema &S, Decl *D, const AttrTy &AL) {
7291 // Check if the new redeclaration has different leaf-ness in the same TCB.
7292 StringRef TCBName = AL.getTCBName();
7293 if (const ConflictingAttrTy *ConflictingAttr =
7295 S.Diag(ConflictingAttr->getLoc(), diag::err_tcb_conflicting_attributes)
7296 << ConflictingAttr->getAttrName()->getName()
7297 << AL.getAttrName()->getName() << TCBName;
7298
7299 // Add a note so that the user could easily find the conflicting attribute.
7300 S.Diag(AL.getLoc(), diag::note_conflicting_attribute);
7301
7302 // More error recovery.
7303 D->dropAttr<EnforceTCBAttr>();
7304 return nullptr;
7305 }
7306
7307 ASTContext &Context = S.getASTContext();
7308 return ::new(Context) AttrTy(Context, AL, AL.getTCBName());
7309}
7310
7311EnforceTCBAttr *Sema::mergeEnforceTCBAttr(Decl *D, const EnforceTCBAttr &AL) {
7313 *this, D, AL);
7314}
7315
7317 Decl *D, const EnforceTCBLeafAttr &AL) {
7319 *this, D, AL);
7320}
7321
7323 const ParsedAttr &AL) {
7325 const uint32_t NumArgs = AL.getNumArgs();
7326 if (NumArgs > 4) {
7327 S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 4;
7328 AL.setInvalid();
7329 }
7330
7331 if (NumArgs == 0) {
7332 S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) << AL;
7333 AL.setInvalid();
7334 return;
7335 }
7336
7337 if (D->getAttr<VTablePointerAuthenticationAttr>()) {
7338 S.Diag(AL.getLoc(), diag::err_duplicated_vtable_pointer_auth) << Decl;
7339 AL.setInvalid();
7340 }
7341
7342 auto KeyType = VTablePointerAuthenticationAttr::VPtrAuthKeyType::DefaultKey;
7343 if (AL.isArgIdent(0)) {
7344 IdentifierLoc *IL = AL.getArgAsIdent(0);
7345 if (!VTablePointerAuthenticationAttr::ConvertStrToVPtrAuthKeyType(
7346 IL->getIdentifierInfo()->getName(), KeyType)) {
7347 S.Diag(IL->getLoc(), diag::err_invalid_authentication_key)
7348 << IL->getIdentifierInfo();
7349 AL.setInvalid();
7350 }
7351 if (KeyType == VTablePointerAuthenticationAttr::DefaultKey &&
7352 !S.getLangOpts().PointerAuthCalls) {
7353 S.Diag(AL.getLoc(), diag::err_no_default_vtable_pointer_auth) << 0;
7354 AL.setInvalid();
7355 }
7356 } else {
7357 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7358 << AL << AANT_ArgumentIdentifier;
7359 return;
7360 }
7361
7362 auto AddressDiversityMode = VTablePointerAuthenticationAttr::
7363 AddressDiscriminationMode::DefaultAddressDiscrimination;
7364 if (AL.getNumArgs() > 1) {
7365 if (AL.isArgIdent(1)) {
7366 IdentifierLoc *IL = AL.getArgAsIdent(1);
7367 if (!VTablePointerAuthenticationAttr::
7368 ConvertStrToAddressDiscriminationMode(
7369 IL->getIdentifierInfo()->getName(), AddressDiversityMode)) {
7370 S.Diag(IL->getLoc(), diag::err_invalid_address_discrimination)
7371 << IL->getIdentifierInfo();
7372 AL.setInvalid();
7373 }
7374 if (AddressDiversityMode ==
7375 VTablePointerAuthenticationAttr::DefaultAddressDiscrimination &&
7376 !S.getLangOpts().PointerAuthCalls) {
7377 S.Diag(IL->getLoc(), diag::err_no_default_vtable_pointer_auth) << 1;
7378 AL.setInvalid();
7379 }
7380 } else {
7381 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7382 << AL << AANT_ArgumentIdentifier;
7383 }
7384 }
7385
7386 auto ED = VTablePointerAuthenticationAttr::ExtraDiscrimination::
7387 DefaultExtraDiscrimination;
7388 if (AL.getNumArgs() > 2) {
7389 if (AL.isArgIdent(2)) {
7390 IdentifierLoc *IL = AL.getArgAsIdent(2);
7391 if (!VTablePointerAuthenticationAttr::ConvertStrToExtraDiscrimination(
7392 IL->getIdentifierInfo()->getName(), ED)) {
7393 S.Diag(IL->getLoc(), diag::err_invalid_extra_discrimination)
7394 << IL->getIdentifierInfo();
7395 AL.setInvalid();
7396 }
7397 if (ED == VTablePointerAuthenticationAttr::DefaultExtraDiscrimination &&
7398 !S.getLangOpts().PointerAuthCalls) {
7399 S.Diag(AL.getLoc(), diag::err_no_default_vtable_pointer_auth) << 2;
7400 AL.setInvalid();
7401 }
7402 } else {
7403 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7404 << AL << AANT_ArgumentIdentifier;
7405 }
7406 }
7407
7408 uint32_t CustomDiscriminationValue = 0;
7409 if (ED == VTablePointerAuthenticationAttr::CustomDiscrimination) {
7410 if (NumArgs < 4) {
7411 S.Diag(AL.getLoc(), diag::err_missing_custom_discrimination) << AL << 4;
7412 AL.setInvalid();
7413 return;
7414 }
7415 if (NumArgs > 4) {
7416 S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 4;
7417 AL.setInvalid();
7418 }
7419
7420 if (!AL.isArgExpr(3) || !S.checkUInt32Argument(AL, AL.getArgAsExpr(3),
7421 CustomDiscriminationValue)) {
7422 S.Diag(AL.getLoc(), diag::err_invalid_custom_discrimination);
7423 AL.setInvalid();
7424 }
7425 } else if (NumArgs > 3) {
7426 S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 3;
7427 AL.setInvalid();
7428 }
7429
7430 Decl->addAttr(::new (S.Context) VTablePointerAuthenticationAttr(
7431 S.Context, AL, KeyType, AddressDiversityMode, ED,
7432 CustomDiscriminationValue));
7433}
7434
7435static bool modularFormatAttrsEquiv(const ModularFormatAttr *Existing,
7436 const IdentifierInfo *ModularImplFn,
7437 StringRef ImplName,
7438 ArrayRef<StringRef> Aspects) {
7439 return Existing->getModularImplFn() == ModularImplFn &&
7440 Existing->getImplName() == ImplName &&
7441 Existing->aspects_size() == Aspects.size() &&
7442 llvm::equal(Existing->aspects(), Aspects);
7443}
7444
7446 Decl *D, const AttributeCommonInfo &CI, const IdentifierInfo *ModularImplFn,
7447 StringRef ImplName, MutableArrayRef<StringRef> Aspects) {
7448 if (const auto *Existing = D->getAttr<ModularFormatAttr>()) {
7449 if (!modularFormatAttrsEquiv(Existing, ModularImplFn, ImplName, Aspects)) {
7450 Diag(Existing->getLocation(), diag::err_duplicate_attribute) << *Existing;
7451 Diag(CI.getLoc(), diag::note_conflicting_attribute);
7452 }
7453 return nullptr;
7454 }
7455 return ::new (Context) ModularFormatAttr(Context, CI, ModularImplFn, ImplName,
7456 Aspects.data(), Aspects.size());
7457}
7458
7459static void handleModularFormat(Sema &S, Decl *D, const ParsedAttr &AL) {
7460 bool Valid = true;
7461 if (!AL.isArgIdent(0)) {
7462 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
7463 << AL << 1 << AANT_ArgumentIdentifier;
7464 Valid = false;
7465 }
7466 StringRef ImplName;
7467 if (!S.checkStringLiteralArgumentAttr(AL, 1, ImplName))
7468 Valid = false;
7469 SmallVector<StringRef> Aspects;
7470 llvm::DenseSet<StringRef> SeenAspects;
7471 for (unsigned I = 2, E = AL.getNumArgs(); I != E; ++I) {
7472 StringRef Aspect;
7473 if (!S.checkStringLiteralArgumentAttr(AL, I, Aspect))
7474 return;
7475 if (!SeenAspects.insert(Aspect).second) {
7476 S.Diag(AL.getArgAsExpr(I)->getExprLoc(),
7477 diag::err_modular_format_duplicate_aspect)
7478 << Aspect;
7479 Valid = false;
7480 continue;
7481 }
7482 Aspects.push_back(Aspect);
7483 }
7484 if (!Valid)
7485 return;
7486
7487 // Store aspects sorted.
7488 llvm::sort(Aspects);
7489 IdentifierInfo *ModularImplFn = AL.getArgAsIdent(0)->getIdentifierInfo();
7490
7491 if (const auto *Existing = D->getAttr<ModularFormatAttr>()) {
7492 if (!modularFormatAttrsEquiv(Existing, ModularImplFn, ImplName, Aspects)) {
7493 S.Diag(AL.getLoc(), diag::err_duplicate_attribute) << *Existing;
7494 S.Diag(Existing->getLoc(), diag::note_conflicting_attribute);
7495 }
7496 // Ignore the later declaration in favor of the earlier one.
7497 return;
7498 }
7499
7500 D->addAttr(::new (S.Context) ModularFormatAttr(
7501 S.Context, AL, ModularImplFn, ImplName, Aspects.data(), Aspects.size()));
7502}
7503
7504//===----------------------------------------------------------------------===//
7505// Top Level Sema Entry Points
7506//===----------------------------------------------------------------------===//
7507
7508// Returns true if the attribute must delay setting its arguments until after
7509// template instantiation, and false otherwise.
7511 // Only attributes that accept expression parameter packs can delay arguments.
7512 if (!AL.acceptsExprPack())
7513 return false;
7514
7515 bool AttrHasVariadicArg = AL.hasVariadicArg();
7516 unsigned AttrNumArgs = AL.getNumArgMembers();
7517 for (size_t I = 0; I < std::min(AL.getNumArgs(), AttrNumArgs); ++I) {
7518 bool IsLastAttrArg = I == (AttrNumArgs - 1);
7519 // If the argument is the last argument and it is variadic it can contain
7520 // any expression.
7521 if (IsLastAttrArg && AttrHasVariadicArg)
7522 return false;
7523 Expr *E = AL.getArgAsExpr(I);
7524 bool ArgMemberCanHoldExpr = AL.isParamExpr(I);
7525 // If the expression is a pack expansion then arguments must be delayed
7526 // unless the argument is an expression and it is the last argument of the
7527 // attribute.
7529 return !(IsLastAttrArg && ArgMemberCanHoldExpr);
7530 // Last case is if the expression is value dependent then it must delay
7531 // arguments unless the corresponding argument is able to hold the
7532 // expression.
7533 if (E->isValueDependent() && !ArgMemberCanHoldExpr)
7534 return true;
7535 }
7536 return false;
7537}
7538
7540 const AttributeCommonInfo &CI) {
7541 if (PersonalityAttr *PA = D->getAttr<PersonalityAttr>()) {
7542 const FunctionDecl *Personality = PA->getRoutine();
7543 if (Context.isSameEntity(Personality, Routine))
7544 return nullptr;
7545 Diag(PA->getLocation(), diag::err_mismatched_personality);
7546 Diag(CI.getLoc(), diag::note_previous_attribute);
7547 D->dropAttr<PersonalityAttr>();
7548 }
7549 return ::new (Context) PersonalityAttr(Context, CI, Routine);
7550}
7551
7552static void handlePersonalityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7553 Expr *E = AL.getArgAsExpr(0);
7554 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
7555 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(DRE->getDecl()))
7556 if (Attr *A = S.mergePersonalityAttr(D, FD, AL))
7557 return D->addAttr(A);
7558 S.Diag(E->getExprLoc(), diag::err_attribute_personality_arg_not_function)
7559 << AL.getAttrName();
7560}
7561
7562/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
7563/// the attribute applies to decls. If the attribute is a type attribute, just
7564/// silently ignore it if a GNU attribute.
7565static void
7567 const Sema::ProcessDeclAttributeOptions &Options) {
7569 return;
7570
7571 // Ignore C++11 attributes on declarator chunks: they appertain to the type
7572 // instead. Note, isCXX11Attribute() will look at whether the attribute is
7573 // [[]] or alignas, while isC23Attribute() will only look at [[]]. This is
7574 // important for ensuring that alignas in C23 is properly handled on a
7575 // structure member declaration because it is a type-specifier-qualifier in
7576 // C but still applies to the declaration rather than the type.
7577 if ((S.getLangOpts().CPlusPlus ? AL.isCXX11Attribute()
7578 : AL.isC23Attribute()) &&
7579 !Options.IncludeCXX11Attributes)
7580 return;
7581
7582 // Unknown attributes are automatically warned on. Target-specific attributes
7583 // which do not apply to the current target architecture are treated as
7584 // though they were unknown attributes.
7587 if (AL.isRegularKeywordAttribute()) {
7588 S.Diag(AL.getLoc(), diag::err_keyword_not_supported_on_target)
7589 << AL.getAttrName() << AL.getRange();
7590 } else if (AL.isDeclspecAttribute()) {
7591 S.Diag(AL.getLoc(), diag::warn_unhandled_ms_attribute_ignored)
7592 << AL.getAttrName() << AL.getRange();
7593 } else {
7595 }
7596 return;
7597 }
7598
7599 if (S.getLangOpts().HLSL && isa<FunctionDecl>(D) &&
7600 AL.getKind() == ParsedAttr::AT_NoInline) {
7601 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
7602 for (const ParmVarDecl *PVD : FD->parameters()) {
7603 if (PVD->hasAttr<HLSLGroupSharedAddressSpaceAttr>()) {
7604 S.Diag(AL.getLoc(), diag::err_hlsl_attr_incompatible)
7605 << "'noinline'" << "'groupshared' parameter";
7606 return;
7607 }
7608 }
7609 }
7610 }
7611
7612 // Check if argument population must delayed to after template instantiation.
7613 bool MustDelayArgs = MustDelayAttributeArguments(AL);
7614
7615 // Argument number check must be skipped if arguments are delayed.
7616 if (S.checkCommonAttributeFeatures(D, AL, MustDelayArgs))
7617 return;
7618
7619 if (MustDelayArgs) {
7621 return;
7622 }
7623
7624 switch (AL.getKind()) {
7625 default:
7627 break;
7628 if (!AL.isStmtAttr()) {
7629 assert(AL.isTypeAttr() && "Non-type attribute not handled");
7630 }
7631 if (AL.isTypeAttr()) {
7632 if (Options.IgnoreTypeAttributes)
7633 break;
7635 // Non-[[]] type attributes are handled in processTypeAttrs(); silently
7636 // move on.
7637 break;
7638 }
7639
7640 // According to the C and C++ standards, we should never see a
7641 // [[]] type attribute on a declaration. However, we have in the past
7642 // allowed some type attributes to "slide" to the `DeclSpec`, so we need
7643 // to continue to support this legacy behavior. We only do this, however,
7644 // if
7645 // - we actually have a `DeclSpec`, i.e. if we're looking at a
7646 // `DeclaratorDecl`, or
7647 // - we are looking at an alias-declaration, where historically we have
7648 // allowed type attributes after the identifier to slide to the type.
7651 // Suggest moving the attribute to the type instead, but only for our
7652 // own vendor attributes; moving other vendors' attributes might hurt
7653 // portability.
7654 if (AL.isClangScope()) {
7655 S.Diag(AL.getLoc(), diag::warn_type_attribute_deprecated_on_decl)
7656 << AL << D->getLocation();
7657 }
7658
7659 // Allow this type attribute to be handled in processTypeAttrs();
7660 // silently move on.
7661 break;
7662 }
7663
7664 if (AL.getKind() == ParsedAttr::AT_Regparm) {
7665 // `regparm` is a special case: It's a type attribute but we still want
7666 // to treat it as if it had been written on the declaration because that
7667 // way we'll be able to handle it directly in `processTypeAttr()`.
7668 // If we treated `regparm` it as if it had been written on the
7669 // `DeclSpec`, the logic in `distributeFunctionTypeAttrFromDeclSepc()`
7670 // would try to move it to the declarator, but that doesn't work: We
7671 // can't remove the attribute from the list of declaration attributes
7672 // because it might be needed by other declarators in the same
7673 // declaration.
7674 break;
7675 }
7676
7677 if (AL.getKind() == ParsedAttr::AT_VectorSize) {
7678 // `vector_size` is a special case: It's a type attribute semantically,
7679 // but GCC expects the [[]] syntax to be written on the declaration (and
7680 // warns that the attribute has no effect if it is placed on the
7681 // decl-specifier-seq).
7682 // Silently move on and allow the attribute to be handled in
7683 // processTypeAttr().
7684 break;
7685 }
7686
7687 if (AL.getKind() == ParsedAttr::AT_NoDeref) {
7688 // FIXME: `noderef` currently doesn't work correctly in [[]] syntax.
7689 // See https://github.com/llvm/llvm-project/issues/55790 for details.
7690 // We allow processTypeAttrs() to emit a warning and silently move on.
7691 break;
7692 }
7693 }
7694 // N.B., ClangAttrEmitter.cpp emits a diagnostic helper that ensures a
7695 // statement attribute is not written on a declaration, but this code is
7696 // needed for type attributes as well as statement attributes in Attr.td
7697 // that do not list any subjects.
7698 S.Diag(AL.getLoc(), diag::err_attribute_invalid_on_decl)
7699 << AL << AL.isRegularKeywordAttribute() << D->getLocation();
7700 break;
7701 case ParsedAttr::AT_Interrupt:
7702 handleInterruptAttr(S, D, AL);
7703 break;
7704 case ParsedAttr::AT_ARMInterruptSaveFP:
7705 S.ARM().handleInterruptSaveFPAttr(D, AL);
7706 break;
7707 case ParsedAttr::AT_X86ForceAlignArgPointer:
7709 break;
7710 case ParsedAttr::AT_ReadOnlyPlacement:
7712 break;
7713 case ParsedAttr::AT_DLLExport:
7714 case ParsedAttr::AT_DLLImport:
7715 handleDLLAttr(S, D, AL);
7716 break;
7717 case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
7719 break;
7720 case ParsedAttr::AT_AMDGPUWavesPerEU:
7722 break;
7723 case ParsedAttr::AT_AMDGPUNumSGPR:
7725 break;
7726 case ParsedAttr::AT_AMDGPUNumVGPR:
7728 break;
7729 case ParsedAttr::AT_AMDGPUMaxNumWorkGroups:
7731 break;
7732 case ParsedAttr::AT_AVRSignal:
7733 S.AVR().handleSignalAttr(D, AL);
7734 break;
7735 case ParsedAttr::AT_BPFPreserveAccessIndex:
7737 break;
7738 case ParsedAttr::AT_BPFPreserveStaticOffset:
7740 break;
7741 case ParsedAttr::AT_BTFDeclTag:
7742 handleBTFDeclTagAttr(S, D, AL);
7743 break;
7744 case ParsedAttr::AT_WebAssemblyExportName:
7746 break;
7747 case ParsedAttr::AT_WebAssemblyImportModule:
7749 break;
7750 case ParsedAttr::AT_WebAssemblyImportName:
7752 break;
7753 case ParsedAttr::AT_IBOutlet:
7754 S.ObjC().handleIBOutlet(D, AL);
7755 break;
7756 case ParsedAttr::AT_IBOutletCollection:
7757 S.ObjC().handleIBOutletCollection(D, AL);
7758 break;
7759 case ParsedAttr::AT_IFunc:
7760 handleIFuncAttr(S, D, AL);
7761 break;
7762 case ParsedAttr::AT_Alias:
7763 handleAliasAttr(S, D, AL);
7764 break;
7765 case ParsedAttr::AT_Aligned:
7766 handleAlignedAttr(S, D, AL);
7767 break;
7768 case ParsedAttr::AT_AlignValue:
7769 handleAlignValueAttr(S, D, AL);
7770 break;
7771 case ParsedAttr::AT_AllocSize:
7772 handleAllocSizeAttr(S, D, AL);
7773 break;
7774 case ParsedAttr::AT_AlwaysInline:
7775 handleAlwaysInlineAttr(S, D, AL);
7776 break;
7777 case ParsedAttr::AT_AnalyzerNoReturn:
7779 break;
7780 case ParsedAttr::AT_TLSModel:
7781 handleTLSModelAttr(S, D, AL);
7782 break;
7783 case ParsedAttr::AT_Annotate:
7784 handleAnnotateAttr(S, D, AL);
7785 break;
7786 case ParsedAttr::AT_Availability:
7787 handleAvailabilityAttr(S, D, AL);
7788 break;
7789 case ParsedAttr::AT_CPUDispatch:
7790 case ParsedAttr::AT_CPUSpecific:
7791 handleCPUSpecificAttr(S, D, AL);
7792 break;
7793 case ParsedAttr::AT_Common:
7794 handleCommonAttr(S, D, AL);
7795 break;
7796 case ParsedAttr::AT_CUDAConstant:
7797 handleConstantAttr(S, D, AL);
7798 break;
7799 case ParsedAttr::AT_PassObjectSize:
7800 handlePassObjectSizeAttr(S, D, AL);
7801 break;
7802 case ParsedAttr::AT_Constructor:
7803 handleConstructorAttr(S, D, AL);
7804 break;
7805 case ParsedAttr::AT_Deprecated:
7806 handleDeprecatedAttr(S, D, AL);
7807 break;
7808 case ParsedAttr::AT_Destructor:
7809 handleDestructorAttr(S, D, AL);
7810 break;
7811 case ParsedAttr::AT_EnableIf:
7812 handleEnableIfAttr(S, D, AL);
7813 break;
7814 case ParsedAttr::AT_Error:
7815 handleErrorAttr(S, D, AL);
7816 break;
7817 case ParsedAttr::AT_ExcludeFromExplicitInstantiation:
7819 break;
7820 case ParsedAttr::AT_DiagnoseIf:
7821 handleDiagnoseIfAttr(S, D, AL);
7822 break;
7823 case ParsedAttr::AT_DiagnoseAsBuiltin:
7825 break;
7826 case ParsedAttr::AT_NoBuiltin:
7827 handleNoBuiltinAttr(S, D, AL);
7828 break;
7829 case ParsedAttr::AT_CFIUncheckedCallee:
7831 break;
7832 case ParsedAttr::AT_ExtVectorType:
7833 handleExtVectorTypeAttr(S, D, AL);
7834 break;
7835 case ParsedAttr::AT_ExternalSourceSymbol:
7837 break;
7838 case ParsedAttr::AT_MinSize:
7839 handleMinSizeAttr(S, D, AL);
7840 break;
7841 case ParsedAttr::AT_OptimizeNone:
7842 handleOptimizeNoneAttr(S, D, AL);
7843 break;
7844 case ParsedAttr::AT_EnumExtensibility:
7846 break;
7847 case ParsedAttr::AT_SYCLKernel:
7848 S.SYCL().handleKernelAttr(D, AL);
7849 break;
7850 case ParsedAttr::AT_SYCLExternal:
7852 break;
7853 case ParsedAttr::AT_SYCLKernelEntryPoint:
7855 break;
7856 case ParsedAttr::AT_SYCLSpecialClass:
7858 break;
7859 case ParsedAttr::AT_Format:
7860 handleFormatAttr(S, D, AL);
7861 break;
7862 case ParsedAttr::AT_FormatMatches:
7863 handleFormatMatchesAttr(S, D, AL);
7864 break;
7865 case ParsedAttr::AT_FormatArg:
7866 handleFormatArgAttr(S, D, AL);
7867 break;
7868 case ParsedAttr::AT_Callback:
7869 handleCallbackAttr(S, D, AL);
7870 break;
7871 case ParsedAttr::AT_LifetimeCaptureBy:
7873 break;
7874 case ParsedAttr::AT_CalledOnce:
7875 handleCalledOnceAttr(S, D, AL);
7876 break;
7877 case ParsedAttr::AT_CUDAGlobal:
7878 handleGlobalAttr(S, D, AL);
7879 break;
7880 case ParsedAttr::AT_CUDADevice:
7881 handleDeviceAttr(S, D, AL);
7882 break;
7883 case ParsedAttr::AT_CUDAGridConstant:
7884 handleGridConstantAttr(S, D, AL);
7885 break;
7886 case ParsedAttr::AT_HIPManaged:
7887 handleManagedAttr(S, D, AL);
7888 break;
7889 case ParsedAttr::AT_GNUInline:
7890 handleGNUInlineAttr(S, D, AL);
7891 break;
7892 case ParsedAttr::AT_CUDALaunchBounds:
7893 handleLaunchBoundsAttr(S, D, AL);
7894 break;
7895 case ParsedAttr::AT_CUDAClusterDims:
7896 handleClusterDimsAttr(S, D, AL);
7897 break;
7898 case ParsedAttr::AT_CUDANoCluster:
7899 handleNoClusterAttr(S, D, AL);
7900 break;
7901 case ParsedAttr::AT_Restrict:
7902 handleRestrictAttr(S, D, AL);
7903 break;
7904 case ParsedAttr::AT_MallocSpan:
7905 handleMallocSpanAttr(S, D, AL);
7906 break;
7907 case ParsedAttr::AT_Mode:
7908 handleModeAttr(S, D, AL);
7909 break;
7910 case ParsedAttr::AT_NonString:
7911 handleNonStringAttr(S, D, AL);
7912 break;
7913 case ParsedAttr::AT_NonNull:
7914 if (auto *PVD = dyn_cast<ParmVarDecl>(D))
7915 handleNonNullAttrParameter(S, PVD, AL);
7916 else
7917 handleNonNullAttr(S, D, AL);
7918 break;
7919 case ParsedAttr::AT_ReturnsNonNull:
7920 handleReturnsNonNullAttr(S, D, AL);
7921 break;
7922 case ParsedAttr::AT_NoEscape:
7923 handleNoEscapeAttr(S, D, AL);
7924 break;
7925 case ParsedAttr::AT_MaybeUndef:
7927 break;
7928 case ParsedAttr::AT_AssumeAligned:
7929 handleAssumeAlignedAttr(S, D, AL);
7930 break;
7931 case ParsedAttr::AT_AllocAlign:
7932 handleAllocAlignAttr(S, D, AL);
7933 break;
7934 case ParsedAttr::AT_Ownership:
7935 handleOwnershipAttr(S, D, AL);
7936 break;
7937 case ParsedAttr::AT_Naked:
7938 handleNakedAttr(S, D, AL);
7939 break;
7940 case ParsedAttr::AT_NoReturn:
7941 handleNoReturnAttr(S, D, AL);
7942 break;
7943 case ParsedAttr::AT_CXX11NoReturn:
7945 break;
7946 case ParsedAttr::AT_AnyX86NoCfCheck:
7947 handleNoCfCheckAttr(S, D, AL);
7948 break;
7949 case ParsedAttr::AT_NoThrow:
7950 if (!AL.isUsedAsTypeAttr())
7952 break;
7953 case ParsedAttr::AT_CUDAShared:
7954 handleSharedAttr(S, D, AL);
7955 break;
7956 case ParsedAttr::AT_VecReturn:
7957 handleVecReturnAttr(S, D, AL);
7958 break;
7959 case ParsedAttr::AT_ObjCOwnership:
7960 S.ObjC().handleOwnershipAttr(D, AL);
7961 break;
7962 case ParsedAttr::AT_ObjCPreciseLifetime:
7964 break;
7965 case ParsedAttr::AT_ObjCReturnsInnerPointer:
7967 break;
7968 case ParsedAttr::AT_ObjCRequiresSuper:
7969 S.ObjC().handleRequiresSuperAttr(D, AL);
7970 break;
7971 case ParsedAttr::AT_ObjCBridge:
7972 S.ObjC().handleBridgeAttr(D, AL);
7973 break;
7974 case ParsedAttr::AT_ObjCBridgeMutable:
7975 S.ObjC().handleBridgeMutableAttr(D, AL);
7976 break;
7977 case ParsedAttr::AT_ObjCBridgeRelated:
7978 S.ObjC().handleBridgeRelatedAttr(D, AL);
7979 break;
7980 case ParsedAttr::AT_ObjCDesignatedInitializer:
7982 break;
7983 case ParsedAttr::AT_ObjCRuntimeName:
7984 S.ObjC().handleRuntimeName(D, AL);
7985 break;
7986 case ParsedAttr::AT_ObjCBoxable:
7987 S.ObjC().handleBoxable(D, AL);
7988 break;
7989 case ParsedAttr::AT_NSErrorDomain:
7990 S.ObjC().handleNSErrorDomain(D, AL);
7991 break;
7992 case ParsedAttr::AT_CFConsumed:
7993 case ParsedAttr::AT_NSConsumed:
7994 case ParsedAttr::AT_OSConsumed:
7995 S.ObjC().AddXConsumedAttr(D, AL,
7997 /*IsTemplateInstantiation=*/false);
7998 break;
7999 case ParsedAttr::AT_OSReturnsRetainedOnZero:
8001 S, D, AL, S.ObjC().isValidOSObjectOutParameter(D),
8002 diag::warn_ns_attribute_wrong_parameter_type,
8003 /*Extra Args=*/AL, /*pointer-to-OSObject-pointer*/ 3, AL.getRange());
8004 break;
8005 case ParsedAttr::AT_OSReturnsRetainedOnNonZero:
8007 S, D, AL, S.ObjC().isValidOSObjectOutParameter(D),
8008 diag::warn_ns_attribute_wrong_parameter_type,
8009 /*Extra Args=*/AL, /*pointer-to-OSObject-poointer*/ 3, AL.getRange());
8010 break;
8011 case ParsedAttr::AT_NSReturnsAutoreleased:
8012 case ParsedAttr::AT_NSReturnsNotRetained:
8013 case ParsedAttr::AT_NSReturnsRetained:
8014 case ParsedAttr::AT_CFReturnsNotRetained:
8015 case ParsedAttr::AT_CFReturnsRetained:
8016 case ParsedAttr::AT_OSReturnsNotRetained:
8017 case ParsedAttr::AT_OSReturnsRetained:
8019 break;
8020 case ParsedAttr::AT_WorkGroupSizeHint:
8022 break;
8023 case ParsedAttr::AT_ReqdWorkGroupSize:
8025 break;
8026 case ParsedAttr::AT_OpenCLIntelReqdSubGroupSize:
8027 S.OpenCL().handleSubGroupSize(D, AL);
8028 break;
8029 case ParsedAttr::AT_VecTypeHint:
8030 handleVecTypeHint(S, D, AL);
8031 break;
8032 case ParsedAttr::AT_InitPriority:
8033 handleInitPriorityAttr(S, D, AL);
8034 break;
8035 case ParsedAttr::AT_Packed:
8036 handlePackedAttr(S, D, AL);
8037 break;
8038 case ParsedAttr::AT_PreferredName:
8039 handlePreferredName(S, D, AL);
8040 break;
8041 case ParsedAttr::AT_NoSpecializations:
8042 handleNoSpecializations(S, D, AL);
8043 break;
8044 case ParsedAttr::AT_Section:
8045 handleSectionAttr(S, D, AL);
8046 break;
8047 case ParsedAttr::AT_CodeModel:
8048 handleCodeModelAttr(S, D, AL);
8049 break;
8050 case ParsedAttr::AT_RandomizeLayout:
8051 handleRandomizeLayoutAttr(S, D, AL);
8052 break;
8053 case ParsedAttr::AT_NoRandomizeLayout:
8055 break;
8056 case ParsedAttr::AT_CodeSeg:
8057 handleCodeSegAttr(S, D, AL);
8058 break;
8059 case ParsedAttr::AT_Target:
8060 handleTargetAttr(S, D, AL);
8061 break;
8062 case ParsedAttr::AT_TargetVersion:
8063 handleTargetVersionAttr(S, D, AL);
8064 break;
8065 case ParsedAttr::AT_TargetClones:
8066 handleTargetClonesAttr(S, D, AL);
8067 break;
8068 case ParsedAttr::AT_MinVectorWidth:
8069 handleMinVectorWidthAttr(S, D, AL);
8070 break;
8071 case ParsedAttr::AT_Unavailable:
8073 break;
8074 case ParsedAttr::AT_OMPAssume:
8075 S.OpenMP().handleOMPAssumeAttr(D, AL);
8076 break;
8077 case ParsedAttr::AT_ObjCDirect:
8078 S.ObjC().handleDirectAttr(D, AL);
8079 break;
8080 case ParsedAttr::AT_ObjCDirectMembers:
8081 S.ObjC().handleDirectMembersAttr(D, AL);
8083 break;
8084 case ParsedAttr::AT_ObjCExplicitProtocolImpl:
8086 break;
8087 case ParsedAttr::AT_Unused:
8088 handleUnusedAttr(S, D, AL);
8089 break;
8090 case ParsedAttr::AT_Visibility:
8091 handleVisibilityAttr(S, D, AL, false);
8092 break;
8093 case ParsedAttr::AT_TypeVisibility:
8094 handleVisibilityAttr(S, D, AL, true);
8095 break;
8096 case ParsedAttr::AT_WarnUnusedResult:
8097 handleWarnUnusedResult(S, D, AL);
8098 break;
8099 case ParsedAttr::AT_WeakRef:
8100 handleWeakRefAttr(S, D, AL);
8101 break;
8102 case ParsedAttr::AT_WeakImport:
8103 handleWeakImportAttr(S, D, AL);
8104 break;
8105 case ParsedAttr::AT_TransparentUnion:
8107 break;
8108 case ParsedAttr::AT_ObjCMethodFamily:
8109 S.ObjC().handleMethodFamilyAttr(D, AL);
8110 break;
8111 case ParsedAttr::AT_ObjCNSObject:
8112 S.ObjC().handleNSObject(D, AL);
8113 break;
8114 case ParsedAttr::AT_ObjCIndependentClass:
8115 S.ObjC().handleIndependentClass(D, AL);
8116 break;
8117 case ParsedAttr::AT_Blocks:
8118 S.ObjC().handleBlocksAttr(D, AL);
8119 break;
8120 case ParsedAttr::AT_Sentinel:
8121 handleSentinelAttr(S, D, AL);
8122 break;
8123 case ParsedAttr::AT_Cleanup:
8124 handleCleanupAttr(S, D, AL);
8125 break;
8126 case ParsedAttr::AT_NoDebug:
8127 handleNoDebugAttr(S, D, AL);
8128 break;
8129 case ParsedAttr::AT_CmseNSEntry:
8130 S.ARM().handleCmseNSEntryAttr(D, AL);
8131 break;
8132 case ParsedAttr::AT_StdCall:
8133 case ParsedAttr::AT_CDecl:
8134 case ParsedAttr::AT_FastCall:
8135 case ParsedAttr::AT_ThisCall:
8136 case ParsedAttr::AT_Pascal:
8137 case ParsedAttr::AT_RegCall:
8138 case ParsedAttr::AT_SwiftCall:
8139 case ParsedAttr::AT_SwiftAsyncCall:
8140 case ParsedAttr::AT_VectorCall:
8141 case ParsedAttr::AT_MSABI:
8142 case ParsedAttr::AT_SysVABI:
8143 case ParsedAttr::AT_Pcs:
8144 case ParsedAttr::AT_IntelOclBicc:
8145 case ParsedAttr::AT_PreserveMost:
8146 case ParsedAttr::AT_PreserveAll:
8147 case ParsedAttr::AT_AArch64VectorPcs:
8148 case ParsedAttr::AT_AArch64SVEPcs:
8149 case ParsedAttr::AT_M68kRTD:
8150 case ParsedAttr::AT_PreserveNone:
8151 case ParsedAttr::AT_RISCVVectorCC:
8152 case ParsedAttr::AT_RISCVVLSCC:
8153 handleCallConvAttr(S, D, AL);
8154 break;
8155 case ParsedAttr::AT_DeviceKernel:
8156 handleDeviceKernelAttr(S, D, AL);
8157 break;
8158 case ParsedAttr::AT_Suppress:
8159 handleSuppressAttr(S, D, AL);
8160 break;
8161 case ParsedAttr::AT_Owner:
8162 case ParsedAttr::AT_Pointer:
8164 break;
8165 case ParsedAttr::AT_OpenCLAccess:
8166 S.OpenCL().handleAccessAttr(D, AL);
8167 break;
8168 case ParsedAttr::AT_OpenCLNoSVM:
8169 S.OpenCL().handleNoSVMAttr(D, AL);
8170 break;
8171 case ParsedAttr::AT_SwiftContext:
8173 break;
8174 case ParsedAttr::AT_SwiftAsyncContext:
8176 break;
8177 case ParsedAttr::AT_SwiftErrorResult:
8179 break;
8180 case ParsedAttr::AT_SwiftIndirectResult:
8182 break;
8183 case ParsedAttr::AT_InternalLinkage:
8184 handleInternalLinkageAttr(S, D, AL);
8185 break;
8186 case ParsedAttr::AT_ZeroCallUsedRegs:
8188 break;
8189 case ParsedAttr::AT_FunctionReturnThunks:
8191 break;
8192 case ParsedAttr::AT_NoMerge:
8193 handleNoMergeAttr(S, D, AL);
8194 break;
8195 case ParsedAttr::AT_NoUniqueAddress:
8196 handleNoUniqueAddressAttr(S, D, AL);
8197 break;
8198
8199 case ParsedAttr::AT_AvailableOnlyInDefaultEvalMethod:
8201 break;
8202
8203 case ParsedAttr::AT_CountedBy:
8204 case ParsedAttr::AT_CountedByOrNull:
8205 case ParsedAttr::AT_SizedBy:
8206 case ParsedAttr::AT_SizedByOrNull:
8207 handleCountedByAttrField(S, D, AL);
8208 break;
8209
8210 case ParsedAttr::AT_NoFieldProtection:
8211 handleNoPFPAttrField(S, D, AL);
8212 break;
8213
8214 case ParsedAttr::AT_Personality:
8215 handlePersonalityAttr(S, D, AL);
8216 break;
8217
8218 // Microsoft attributes:
8219 case ParsedAttr::AT_LayoutVersion:
8220 handleLayoutVersion(S, D, AL);
8221 break;
8222 case ParsedAttr::AT_Uuid:
8223 handleUuidAttr(S, D, AL);
8224 break;
8225 case ParsedAttr::AT_MSInheritance:
8226 handleMSInheritanceAttr(S, D, AL);
8227 break;
8228 case ParsedAttr::AT_Thread:
8229 handleDeclspecThreadAttr(S, D, AL);
8230 break;
8231 case ParsedAttr::AT_MSConstexpr:
8232 handleMSConstexprAttr(S, D, AL);
8233 break;
8234 case ParsedAttr::AT_HybridPatchable:
8236 break;
8237
8238 // HLSL attributes:
8239 case ParsedAttr::AT_RootSignature:
8240 S.HLSL().handleRootSignatureAttr(D, AL);
8241 break;
8242 case ParsedAttr::AT_HLSLNumThreads:
8243 S.HLSL().handleNumThreadsAttr(D, AL);
8244 break;
8245 case ParsedAttr::AT_HLSLWaveSize:
8246 S.HLSL().handleWaveSizeAttr(D, AL);
8247 break;
8248 case ParsedAttr::AT_HLSLVkExtBuiltinInput:
8250 break;
8251 case ParsedAttr::AT_HLSLVkExtBuiltinOutput:
8253 break;
8254 case ParsedAttr::AT_HLSLVkPushConstant:
8255 S.HLSL().handleVkPushConstantAttr(D, AL);
8256 break;
8257 case ParsedAttr::AT_HLSLVkConstantId:
8258 S.HLSL().handleVkConstantIdAttr(D, AL);
8259 break;
8260 case ParsedAttr::AT_HLSLVkBinding:
8261 S.HLSL().handleVkBindingAttr(D, AL);
8262 break;
8263 case ParsedAttr::AT_HLSLGroupSharedAddressSpace:
8265 break;
8266 case ParsedAttr::AT_HLSLPackOffset:
8267 S.HLSL().handlePackOffsetAttr(D, AL);
8268 break;
8269 case ParsedAttr::AT_HLSLShader:
8270 S.HLSL().handleShaderAttr(D, AL);
8271 break;
8272 case ParsedAttr::AT_HLSLResourceBinding:
8274 break;
8275 case ParsedAttr::AT_HLSLParamModifier:
8276 S.HLSL().handleParamModifierAttr(D, AL);
8277 break;
8278 case ParsedAttr::AT_HLSLUnparsedSemantic:
8279 S.HLSL().handleSemanticAttr(D, AL);
8280 break;
8281 case ParsedAttr::AT_HLSLVkLocation:
8282 S.HLSL().handleVkLocationAttr(D, AL);
8283 break;
8284
8285 case ParsedAttr::AT_AbiTag:
8286 handleAbiTagAttr(S, D, AL);
8287 break;
8288 case ParsedAttr::AT_CFGuard:
8289 handleCFGuardAttr(S, D, AL);
8290 break;
8291
8292 // Thread safety attributes:
8293 case ParsedAttr::AT_PtGuardedVar:
8294 handlePtGuardedVarAttr(S, D, AL);
8295 break;
8296 case ParsedAttr::AT_NoSanitize:
8297 handleNoSanitizeAttr(S, D, AL);
8298 break;
8299 case ParsedAttr::AT_NoSanitizeAddress:
8301 break;
8302 case ParsedAttr::AT_NoSanitizeThread:
8304 break;
8305 case ParsedAttr::AT_NoSanitizeMemory:
8307 break;
8308 case ParsedAttr::AT_GuardedBy:
8309 handleGuardedByAttr(S, D, AL);
8310 break;
8311 case ParsedAttr::AT_PtGuardedBy:
8312 handlePtGuardedByAttr(S, D, AL);
8313 break;
8314 case ParsedAttr::AT_LockReturned:
8315 handleLockReturnedAttr(S, D, AL);
8316 break;
8317 case ParsedAttr::AT_LocksExcluded:
8318 handleLocksExcludedAttr(S, D, AL);
8319 break;
8320 case ParsedAttr::AT_AcquiredBefore:
8321 handleAcquiredBeforeAttr(S, D, AL);
8322 break;
8323 case ParsedAttr::AT_AcquiredAfter:
8324 handleAcquiredAfterAttr(S, D, AL);
8325 break;
8326
8327 // Capability analysis attributes.
8328 case ParsedAttr::AT_Capability:
8329 case ParsedAttr::AT_Lockable:
8330 handleCapabilityAttr(S, D, AL);
8331 break;
8332 case ParsedAttr::AT_ReentrantCapability:
8334 break;
8335 case ParsedAttr::AT_RequiresCapability:
8337 break;
8338
8339 case ParsedAttr::AT_AssertCapability:
8341 break;
8342 case ParsedAttr::AT_AcquireCapability:
8344 break;
8345 case ParsedAttr::AT_ReleaseCapability:
8347 break;
8348 case ParsedAttr::AT_TryAcquireCapability:
8350 break;
8351
8352 // Consumed analysis attributes.
8353 case ParsedAttr::AT_Consumable:
8354 handleConsumableAttr(S, D, AL);
8355 break;
8356 case ParsedAttr::AT_CallableWhen:
8357 handleCallableWhenAttr(S, D, AL);
8358 break;
8359 case ParsedAttr::AT_ParamTypestate:
8360 handleParamTypestateAttr(S, D, AL);
8361 break;
8362 case ParsedAttr::AT_ReturnTypestate:
8363 handleReturnTypestateAttr(S, D, AL);
8364 break;
8365 case ParsedAttr::AT_SetTypestate:
8366 handleSetTypestateAttr(S, D, AL);
8367 break;
8368 case ParsedAttr::AT_TestTypestate:
8369 handleTestTypestateAttr(S, D, AL);
8370 break;
8371
8372 // Type safety attributes.
8373 case ParsedAttr::AT_ArgumentWithTypeTag:
8375 break;
8376 case ParsedAttr::AT_TypeTagForDatatype:
8378 break;
8379
8380 // Swift attributes.
8381 case ParsedAttr::AT_SwiftAsyncName:
8382 S.Swift().handleAsyncName(D, AL);
8383 break;
8384 case ParsedAttr::AT_SwiftAttr:
8385 S.Swift().handleAttrAttr(D, AL);
8386 break;
8387 case ParsedAttr::AT_SwiftBridge:
8388 S.Swift().handleBridge(D, AL);
8389 break;
8390 case ParsedAttr::AT_SwiftError:
8391 S.Swift().handleError(D, AL);
8392 break;
8393 case ParsedAttr::AT_SwiftName:
8394 S.Swift().handleName(D, AL);
8395 break;
8396 case ParsedAttr::AT_SwiftNewType:
8397 S.Swift().handleNewType(D, AL);
8398 break;
8399 case ParsedAttr::AT_SwiftAsync:
8400 S.Swift().handleAsyncAttr(D, AL);
8401 break;
8402 case ParsedAttr::AT_SwiftAsyncError:
8403 S.Swift().handleAsyncError(D, AL);
8404 break;
8405
8406 // XRay attributes.
8407 case ParsedAttr::AT_XRayLogArgs:
8408 handleXRayLogArgsAttr(S, D, AL);
8409 break;
8410
8411 case ParsedAttr::AT_PatchableFunctionEntry:
8413 break;
8414
8415 case ParsedAttr::AT_AlwaysDestroy:
8416 case ParsedAttr::AT_NoDestroy:
8417 handleDestroyAttr(S, D, AL);
8418 break;
8419
8420 case ParsedAttr::AT_Uninitialized:
8421 handleUninitializedAttr(S, D, AL);
8422 break;
8423
8424 case ParsedAttr::AT_ObjCExternallyRetained:
8426 break;
8427
8428 case ParsedAttr::AT_MIGServerRoutine:
8430 break;
8431
8432 case ParsedAttr::AT_MSAllocator:
8433 handleMSAllocatorAttr(S, D, AL);
8434 break;
8435
8436 case ParsedAttr::AT_ArmBuiltinAlias:
8437 S.ARM().handleBuiltinAliasAttr(D, AL);
8438 break;
8439
8440 case ParsedAttr::AT_ArmLocallyStreaming:
8442 break;
8443
8444 case ParsedAttr::AT_ArmNew:
8445 S.ARM().handleNewAttr(D, AL);
8446 break;
8447
8448 case ParsedAttr::AT_AcquireHandle:
8449 handleAcquireHandleAttr(S, D, AL);
8450 break;
8451
8452 case ParsedAttr::AT_ReleaseHandle:
8454 break;
8455
8456 case ParsedAttr::AT_UnsafeBufferUsage:
8458 break;
8459
8460 case ParsedAttr::AT_UseHandle:
8462 break;
8463
8464 case ParsedAttr::AT_EnforceTCB:
8466 break;
8467
8468 case ParsedAttr::AT_EnforceTCBLeaf:
8470 break;
8471
8472 case ParsedAttr::AT_BuiltinAlias:
8473 handleBuiltinAliasAttr(S, D, AL);
8474 break;
8475
8476 case ParsedAttr::AT_PreferredType:
8477 handlePreferredTypeAttr(S, D, AL);
8478 break;
8479
8480 case ParsedAttr::AT_UsingIfExists:
8482 break;
8483
8484 case ParsedAttr::AT_TypeNullable:
8485 handleNullableTypeAttr(S, D, AL);
8486 break;
8487
8488 case ParsedAttr::AT_VTablePointerAuthentication:
8490 break;
8491
8492 case ParsedAttr::AT_ModularFormat:
8493 handleModularFormat(S, D, AL);
8494 break;
8495
8496 case ParsedAttr::AT_MSStruct:
8497 handleMSStructAttr(S, D, AL);
8498 break;
8499
8500 case ParsedAttr::AT_GCCStruct:
8501 handleGCCStructAttr(S, D, AL);
8502 break;
8503
8504 case ParsedAttr::AT_PointerFieldProtection:
8505 if (!S.getLangOpts().PointerFieldProtectionAttr)
8506 S.Diag(AL.getLoc(),
8507 diag::err_attribute_pointer_field_protection_experimental)
8508 << AL << AL.isRegularKeywordAttribute() << D->getLocation();
8510 break;
8511 }
8512}
8513
8514static bool isKernelDecl(Decl *D) {
8515 const FunctionType *FnTy = D->getFunctionType();
8516 return D->hasAttr<DeviceKernelAttr>() ||
8517 (FnTy && FnTy->getCallConv() == CallingConv::CC_DeviceKernel) ||
8518 D->hasAttr<CUDAGlobalAttr>();
8519}
8520
8522 if (!S.Context.getTargetInfo().getTriple().isAMDGPU())
8523 return;
8524
8525 const auto *Flat = D->getAttr<AMDGPUFlatWorkGroupSizeAttr>();
8526 const auto *Reqd = D->getAttr<ReqdWorkGroupSizeAttr>();
8527 if (!Flat || !Reqd)
8528 return;
8529
8530 auto Eval = [&](Expr *E) -> std::optional<uint64_t> {
8531 if (E->isValueDependent())
8532 return std::nullopt;
8533 std::optional<llvm::APSInt> V = E->getIntegerConstantExpr(S.Context);
8534 if (!V)
8535 return std::nullopt;
8536 return V->getZExtValue();
8537 };
8538
8539 std::optional<uint64_t> X = Eval(Reqd->getXDim());
8540 std::optional<uint64_t> Y = Eval(Reqd->getYDim());
8541 std::optional<uint64_t> Z = Eval(Reqd->getZDim());
8542 std::optional<uint64_t> Min = Eval(Flat->getMin());
8543 std::optional<uint64_t> Max = Eval(Flat->getMax());
8544 if (!X || !Y || !Z || !Min || !Max)
8545 return;
8546
8547 uint64_t Product = *X * *Y * *Z;
8548 if (*Min != Product || *Max != Product) {
8549 S.Diag(Flat->getLocation(),
8550 diag::err_attribute_amdgpu_flat_work_group_size_mismatch);
8551 D->setInvalidDecl();
8552 }
8553}
8554
8556 Scope *S, Decl *D, const ParsedAttributesView &AttrList,
8557 const ProcessDeclAttributeOptions &Options) {
8558 if (AttrList.empty())
8559 return;
8560
8561 for (const ParsedAttr &AL : AttrList)
8562 ProcessDeclAttribute(*this, D, AL, Options);
8563
8564 // FIXME: We should be able to handle these cases in TableGen.
8565 // GCC accepts
8566 // static int a9 __attribute__((weakref));
8567 // but that looks really pointless. We reject it.
8568 if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
8569 Diag(AttrList.begin()->getLoc(), diag::err_attribute_weakref_without_alias)
8570 << cast<NamedDecl>(D);
8571 D->dropAttr<WeakRefAttr>();
8572 return;
8573 }
8574
8575 // FIXME: We should be able to handle this in TableGen as well. It would be
8576 // good to have a way to specify "these attributes must appear as a group",
8577 // for these. Additionally, it would be good to have a way to specify "these
8578 // attribute must never appear as a group" for attributes like cold and hot.
8579 if (!(D->hasAttr<DeviceKernelAttr>() ||
8580 (D->hasAttr<CUDAGlobalAttr>() &&
8581 Context.getTargetInfo().getTriple().isSPIRV()))) {
8582 // These attributes cannot be applied to a non-kernel function.
8583 if (const auto *A = D->getAttr<ReqdWorkGroupSizeAttr>()) {
8584 // FIXME: This emits a different error message than
8585 // diag::err_attribute_wrong_decl_type + ExpectedKernelFunction.
8586 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
8587 D->setInvalidDecl();
8588 } else if (const auto *A = D->getAttr<WorkGroupSizeHintAttr>()) {
8589 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
8590 D->setInvalidDecl();
8591 } else if (const auto *A = D->getAttr<VecTypeHintAttr>()) {
8592 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
8593 D->setInvalidDecl();
8594 } else if (const auto *A = D->getAttr<OpenCLIntelReqdSubGroupSizeAttr>()) {
8595 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
8596 D->setInvalidDecl();
8597 }
8598 }
8599 if (!isKernelDecl(D)) {
8600 if (const auto *A = D->getAttr<AMDGPUFlatWorkGroupSizeAttr>()) {
8601 Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
8602 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
8603 D->setInvalidDecl();
8604 } else if (const auto *A = D->getAttr<AMDGPUWavesPerEUAttr>()) {
8605 Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
8606 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
8607 D->setInvalidDecl();
8608 } else if (const auto *A = D->getAttr<AMDGPUNumSGPRAttr>()) {
8609 Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
8610 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
8611 D->setInvalidDecl();
8612 } else if (const auto *A = D->getAttr<AMDGPUNumVGPRAttr>()) {
8613 Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
8614 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
8615 D->setInvalidDecl();
8616 }
8617 }
8619
8620 // CUDA/HIP: restrict explicit CUDA target attributes on deduction guides.
8621 //
8622 // Deduction guides are not callable functions and never participate in
8623 // codegen; they are always treated as host+device for CUDA/HIP semantic
8624 // checks. We therefore allow either no CUDA target attributes or an explicit
8625 // '__host__ __device__' annotation, but reject guides that are host-only,
8626 // device-only, or marked '__global__'. The use of explicit CUDA/HIP target
8627 // attributes on deduction guides is deprecated and will be rejected in a
8628 // future Clang version.
8629 if (getLangOpts().CUDA)
8630 if (auto *Guide = dyn_cast<CXXDeductionGuideDecl>(D)) {
8631 bool HasHost = Guide->hasAttr<CUDAHostAttr>();
8632 bool HasDevice = Guide->hasAttr<CUDADeviceAttr>();
8633 bool HasGlobal = Guide->hasAttr<CUDAGlobalAttr>();
8634
8635 if (HasGlobal || HasHost != HasDevice) {
8636 Diag(Guide->getLocation(), diag::err_deduction_guide_target_attr);
8637 Guide->setInvalidDecl();
8638 } else if (HasHost && HasDevice) {
8639 Diag(Guide->getLocation(),
8640 diag::warn_deduction_guide_target_attr_deprecated);
8641 }
8642 }
8643
8644 // Do not permit 'constructor' or 'destructor' attributes on __device__ code.
8645 if (getLangOpts().CUDAIsDevice && D->hasAttr<CUDADeviceAttr>() &&
8646 (D->hasAttr<ConstructorAttr>() || D->hasAttr<DestructorAttr>()) &&
8647 !getLangOpts().GPUAllowDeviceInit) {
8648 Diag(D->getLocation(), diag::err_cuda_ctor_dtor_attrs)
8649 << (D->hasAttr<ConstructorAttr>() ? "constructors" : "destructors");
8650 D->setInvalidDecl();
8651 }
8652
8653 // Do this check after processing D's attributes because the attribute
8654 // objc_method_family can change whether the given method is in the init
8655 // family, and it can be applied after objc_designated_initializer. This is a
8656 // bit of a hack, but we need it to be compatible with versions of clang that
8657 // processed the attribute list in the wrong order.
8658 if (D->hasAttr<ObjCDesignatedInitializerAttr>() &&
8659 cast<ObjCMethodDecl>(D)->getMethodFamily() != OMF_init) {
8660 Diag(D->getLocation(), diag::err_designated_init_attr_non_init);
8661 D->dropAttr<ObjCDesignatedInitializerAttr>();
8662 }
8663}
8664
8666 const ParsedAttributesView &AttrList) {
8667 for (const ParsedAttr &AL : AttrList)
8668 if (AL.getKind() == ParsedAttr::AT_TransparentUnion) {
8669 handleTransparentUnionAttr(*this, D, AL);
8670 break;
8671 }
8672
8673 // For BPFPreserveAccessIndexAttr, we want to populate the attributes
8674 // to fields and inner records as well.
8675 if (D && D->hasAttr<BPFPreserveAccessIndexAttr>())
8677}
8678
8680 AccessSpecDecl *ASDecl, const ParsedAttributesView &AttrList) {
8681 for (const ParsedAttr &AL : AttrList) {
8682 if (AL.getKind() == ParsedAttr::AT_Annotate) {
8684 } else {
8685 Diag(AL.getLoc(), diag::err_only_annotate_after_access_spec);
8686 return true;
8687 }
8688 }
8689 return false;
8690}
8691
8692/// checkUnusedDeclAttributes - Check a list of attributes to see if it
8693/// contains any decl attributes that we should warn about.
8695 for (const ParsedAttr &AL : A) {
8696 // Only warn if the attribute is an unignored, non-type attribute.
8697 if (AL.isUsedAsTypeAttr() || AL.isInvalid())
8698 continue;
8699 if (AL.getKind() == ParsedAttr::IgnoredAttribute)
8700 continue;
8701
8702 if (AL.getKind() == ParsedAttr::UnknownAttribute) {
8704 } else {
8705 S.Diag(AL.getLoc(), diag::warn_attribute_not_on_decl) << AL
8706 << AL.getRange();
8707 }
8708 }
8709}
8710
8718
8721 StringRef ScopeName = AL.getNormalizedScopeName();
8722 std::optional<StringRef> CorrectedScopeName =
8723 AL.tryGetCorrectedScopeName(ScopeName);
8724 if (CorrectedScopeName) {
8725 ScopeName = *CorrectedScopeName;
8726 }
8727
8728 StringRef AttrName = AL.getNormalizedAttrName(ScopeName);
8729 std::optional<StringRef> CorrectedAttrName = AL.tryGetCorrectedAttrName(
8730 ScopeName, AttrName, Context.getTargetInfo(), getLangOpts());
8731 if (CorrectedAttrName) {
8732 AttrName = *CorrectedAttrName;
8733 }
8734
8735 if (CorrectedScopeName || CorrectedAttrName) {
8736 std::string CorrectedFullName =
8737 AL.getNormalizedFullName(ScopeName, AttrName);
8739 Diag(CorrectedScopeName ? NR.getBegin() : AL.getRange().getBegin(),
8740 diag::warn_unknown_attribute_ignored_suggestion);
8741
8742 D << AL << CorrectedFullName;
8743
8744 if (AL.isExplicitScope()) {
8745 D << FixItHint::CreateReplacement(NR, CorrectedFullName) << NR;
8746 } else {
8747 if (CorrectedScopeName) {
8749 ScopeName);
8750 }
8751 if (CorrectedAttrName) {
8752 D << FixItHint::CreateReplacement(AL.getRange(), AttrName);
8753 }
8754 }
8755 } else {
8756 Diag(NR.getBegin(), diag::warn_unknown_attribute_ignored) << AL << NR;
8757 }
8758}
8759
8761 SourceLocation Loc) {
8762 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
8763 NamedDecl *NewD = nullptr;
8764 if (auto *FD = dyn_cast<FunctionDecl>(ND)) {
8765 FunctionDecl *NewFD;
8766 // FIXME: Missing call to CheckFunctionDeclaration().
8767 // FIXME: Mangling?
8768 // FIXME: Is the qualifier info correct?
8769 // FIXME: Is the DeclContext correct?
8770 NewFD = FunctionDecl::Create(
8771 FD->getASTContext(), FD->getDeclContext(), Loc, Loc,
8773 getCurFPFeatures().isFPConstrained(), false /*isInlineSpecified*/,
8776 NewD = NewFD;
8777
8778 if (FD->getQualifier())
8779 NewFD->setQualifierInfo(FD->getQualifierLoc());
8780
8781 // Fake up parameter variables; they are declared as if this were
8782 // a typedef.
8783 QualType FDTy = FD->getType();
8784 if (const auto *FT = FDTy->getAs<FunctionProtoType>()) {
8786 for (const auto &AI : FT->param_types()) {
8787 ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, AI);
8788 Param->setScopeInfo(0, Params.size());
8789 Params.push_back(Param);
8790 }
8791 NewFD->setParams(Params);
8792 }
8793 } else if (auto *VD = dyn_cast<VarDecl>(ND)) {
8794 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
8795 VD->getInnerLocStart(), VD->getLocation(), II,
8796 VD->getType(), VD->getTypeSourceInfo(),
8797 VD->getStorageClass());
8798 if (VD->getQualifier())
8799 cast<VarDecl>(NewD)->setQualifierInfo(VD->getQualifierLoc());
8800 }
8801 return NewD;
8802}
8803
8805 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
8806 IdentifierInfo *NDId = ND->getIdentifier();
8807 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
8808 NewD->addAttr(
8809 AliasAttr::CreateImplicit(Context, NDId->getName(), W.getLocation()));
8810 NewD->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));
8811 WeakTopLevelDecl.push_back(NewD);
8812 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
8813 // to insert Decl at TU scope, sorry.
8814 DeclContext *SavedContext = CurContext;
8815 CurContext = Context.getTranslationUnitDecl();
8818 PushOnScopeChains(NewD, S);
8819 CurContext = SavedContext;
8820 } else { // just add weak to existing
8821 ND->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));
8822 }
8823}
8824
8826 // It's valid to "forward-declare" #pragma weak, in which case we
8827 // have to do this.
8829 if (WeakUndeclaredIdentifiers.empty())
8830 return;
8831 NamedDecl *ND = nullptr;
8832 if (auto *VD = dyn_cast<VarDecl>(D))
8833 if (VD->isExternC())
8834 ND = VD;
8835 if (auto *FD = dyn_cast<FunctionDecl>(D))
8836 if (FD->isExternC())
8837 ND = FD;
8838 if (!ND)
8839 return;
8840 if (IdentifierInfo *Id = ND->getIdentifier()) {
8841 auto I = WeakUndeclaredIdentifiers.find(Id);
8842 if (I != WeakUndeclaredIdentifiers.end()) {
8843 auto &WeakInfos = I->second;
8844 for (const auto &W : WeakInfos)
8845 DeclApplyPragmaWeak(S, ND, W);
8846 std::remove_reference_t<decltype(WeakInfos)> EmptyWeakInfos;
8847 WeakInfos.swap(EmptyWeakInfos);
8848 }
8849 }
8850}
8851
8852/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
8853/// it, apply them to D. This is a bit tricky because PD can have attributes
8854/// specified in many different places, and we need to find and apply them all.
8856 // Ordering of attributes can be important, so we take care to process
8857 // attributes in the order in which they appeared in the source code.
8858
8859 auto ProcessAttributesWithSliding =
8860 [&](const ParsedAttributesView &Src,
8861 const ProcessDeclAttributeOptions &Options) {
8862 ParsedAttributesView NonSlidingAttrs;
8863 for (ParsedAttr &AL : Src) {
8864 // FIXME: this sliding is specific to standard attributes and should
8865 // eventually be deprecated and removed as those are not intended to
8866 // slide to anything.
8867 if ((AL.isStandardAttributeSyntax() || AL.isAlignas()) &&
8868 AL.slidesFromDeclToDeclSpecLegacyBehavior()) {
8869 // Skip processing the attribute, but do check if it appertains to
8870 // the declaration. This is needed for the `MatrixType` attribute,
8871 // which, despite being a type attribute, defines a `SubjectList`
8872 // that only allows it to be used on typedef declarations.
8873 AL.diagnoseAppertainsTo(*this, D);
8874 } else {
8875 NonSlidingAttrs.addAtEnd(&AL);
8876 }
8877 }
8878 ProcessDeclAttributeList(S, D, NonSlidingAttrs, Options);
8879 };
8880
8881 // First, process attributes that appeared on the declaration itself (but
8882 // only if they don't have the legacy behavior of "sliding" to the DeclSepc).
8883 ProcessAttributesWithSliding(PD.getDeclarationAttributes(), {});
8884
8885 // Apply decl attributes from the DeclSpec if present.
8886 ProcessAttributesWithSliding(PD.getDeclSpec().getAttributes(),
8888 .WithIncludeCXX11Attributes(false)
8889 .WithIgnoreTypeAttributes(true));
8890
8891 // Walk the declarator structure, applying decl attributes that were in a type
8892 // position to the decl itself. This handles cases like:
8893 // int *__attr__(x)** D;
8894 // when X is a decl attribute.
8895 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) {
8898 .WithIncludeCXX11Attributes(false)
8899 .WithIgnoreTypeAttributes(true));
8900 }
8901
8902 // Finally, apply any attributes on the decl itself.
8904
8905 // Apply additional attributes specified by '#pragma clang attribute'.
8906 AddPragmaAttributes(S, D);
8907
8908 // Look for API notes that map to attributes.
8909 ProcessAPINotes(D);
8910}
8911
8912/// Is the given declaration allowed to use a forbidden type?
8913/// If so, it'll still be annotated with an attribute that makes it
8914/// illegal to actually use.
8916 const DelayedDiagnostic &diag,
8917 UnavailableAttr::ImplicitReason &reason) {
8918 // Private ivars are always okay. Unfortunately, people don't
8919 // always properly make their ivars private, even in system headers.
8920 // Plus we need to make fields okay, too.
8921 if (!isa<FieldDecl>(D) && !isa<ObjCPropertyDecl>(D) &&
8923 return false;
8924
8925 // Silently accept unsupported uses of __weak in both user and system
8926 // declarations when it's been disabled, for ease of integration with
8927 // -fno-objc-arc files. We do have to take some care against attempts
8928 // to define such things; for now, we've only done that for ivars
8929 // and properties.
8931 if (diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_disabled ||
8932 diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_no_runtime) {
8933 reason = UnavailableAttr::IR_ForbiddenWeak;
8934 return true;
8935 }
8936 }
8937
8938 // Allow all sorts of things in system headers.
8940 // Currently, all the failures dealt with this way are due to ARC
8941 // restrictions.
8942 reason = UnavailableAttr::IR_ARCForbiddenType;
8943 return true;
8944 }
8945
8946 return false;
8947}
8948
8949/// Handle a delayed forbidden-type diagnostic.
8951 Decl *D) {
8952 auto Reason = UnavailableAttr::IR_None;
8953 if (D && isForbiddenTypeAllowed(S, D, DD, Reason)) {
8954 assert(Reason && "didn't set reason?");
8955 D->addAttr(UnavailableAttr::CreateImplicit(S.Context, "", Reason, DD.Loc));
8956 return;
8957 }
8958 if (S.getLangOpts().ObjCAutoRefCount)
8959 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
8960 // FIXME: we may want to suppress diagnostics for all
8961 // kind of forbidden type messages on unavailable functions.
8962 if (FD->hasAttr<UnavailableAttr>() &&
8964 diag::err_arc_array_param_no_ownership) {
8965 DD.Triggered = true;
8966 return;
8967 }
8968 }
8969
8972 DD.Triggered = true;
8973}
8974
8975
8980
8981 // When delaying diagnostics to run in the context of a parsed
8982 // declaration, we only want to actually emit anything if parsing
8983 // succeeds.
8984 if (!decl) return;
8985
8986 // We emit all the active diagnostics in this pool or any of its
8987 // parents. In general, we'll get one pool for the decl spec
8988 // and a child pool for each declarator; in a decl group like:
8989 // deprecated_typedef foo, *bar, baz();
8990 // only the declarator pops will be passed decls. This is correct;
8991 // we really do need to consider delayed diagnostics from the decl spec
8992 // for each of the different declarations.
8993 const DelayedDiagnosticPool *pool = &poppedPool;
8994 do {
8995 bool AnyAccessFailures = false;
8997 i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) {
8998 // This const_cast is a bit lame. Really, Triggered should be mutable.
8999 DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i);
9000 if (diag.Triggered)
9001 continue;
9002
9003 switch (diag.Kind) {
9005 // Don't bother giving deprecation/unavailable diagnostics if
9006 // the decl is invalid.
9007 if (!decl->isInvalidDecl())
9009 break;
9010
9012 // Only produce one access control diagnostic for a structured binding
9013 // declaration: we don't need to tell the user that all the fields are
9014 // inaccessible one at a time.
9015 if (AnyAccessFailures && isa<DecompositionDecl>(decl))
9016 continue;
9018 if (diag.Triggered)
9019 AnyAccessFailures = true;
9020 break;
9021
9024 break;
9025 }
9026 }
9027 } while ((pool = pool->getParent()));
9028}
9029
9032 assert(curPool && "re-emitting in undelayed context not supported");
9033 curPool->steal(pool);
9034}
9035
9037 VarDecl *VD = cast<VarDecl>(D);
9038 if (VD->isInvalidDecl() || VD->getType()->isDependentType())
9039 return;
9040
9041 // Obtains the FunctionDecl that was found when handling the attribute
9042 // earlier.
9043 CleanupAttr *Attr = D->getAttr<CleanupAttr>();
9044 FunctionDecl *FD = Attr->getFunctionDecl();
9045 DeclarationNameInfo NI = FD->getNameInfo();
9046
9047 // We're currently more strict than GCC about what function types we accept.
9048 // If this ever proves to be a problem it should be easy to fix.
9049 QualType Ty = this->Context.getPointerType(VD->getType());
9050 QualType ParamTy = FD->getParamDecl(0)->getType();
9051 if (QualType ConvertedTy;
9053 FD->getParamDecl(0)->getLocation(), ParamTy, Ty)) &&
9054 !ObjC().isObjCWritebackConversion(Ty, ParamTy, ConvertedTy)) {
9055 this->Diag(Attr->getArgLoc(),
9056 diag::err_attribute_cleanup_func_arg_incompatible_type)
9057 << NI.getName() << ParamTy << Ty;
9058 D->dropAttr<CleanupAttr>();
9059 return;
9060 }
9061}
9062
9064 QualType T = cast<VarDecl>(D)->getType();
9065 if (this->Context.getAsArrayType(T))
9066 T = this->Context.getBaseElementType(T);
9067 if (!T->isRecordType()) {
9068 this->Diag(A->getLoc(), diag::err_init_priority_object_attr);
9069 D->dropAttr<InitPriorityAttr>();
9070 }
9071}
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 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 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 void ProcessDeclAttribute(Sema &S, Decl *D, const ParsedAttr &AL, const Sema::ProcessDeclAttributeOptions &Options)
ProcessDeclAttribute - Apply the specific attribute to the specified decl if the attribute applies to...
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:889
TypedefDecl * getObjCInstanceTypeDecl()
Retrieve the typedef declaration corresponding to the Objective-C "instancetype" type.
DeclarationNameTable DeclarationNames
Definition ASTContext.h:832
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:828
const LangOptions & getLangOpts() const
Definition ASTContext.h:985
QualType getConstType(QualType T) const
Return the uniqued reference to the type for a const qualified type.
const TargetInfo * getAuxTargetInfo() const
Definition ASTContext.h:948
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:947
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:2149
QualType getFunctionObjectParameterType() const
Definition DeclCXX.h:2316
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:2987
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:1545
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:1290
DeclarationNameInfo getNameInfo() const
Definition Expr.h:1362
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:1379
ValueDecl * getDecl()
Definition Expr.h:1358
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:2006
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:832
const AssociatedConstraint & getTrailingRequiresClause() const
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
Definition Decl.h:856
void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc)
Definition Decl.cpp:2018
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
Definition Decl.h:846
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...
Definition Decl.h:838
TypeSourceInfo * getTypeSourceInfo() const
Definition Decl.h:810
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:113
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:3128
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition Expr.h:178
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition Expr.h:195
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
Definition Expr.h:242
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition Expr.cpp:3123
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
Definition Expr.h:224
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:145
Represents difference between two FPOptions values.
Represents a member of a struct/union/class.
Definition Decl.h:3295
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:2059
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:2303
const ParmVarDecl * getParamDecl(unsigned i) const
Definition Decl.h:2928
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
Definition Decl.cpp:3268
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
Definition Decl.cpp:4246
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition Decl.cpp:4234
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition Decl.h:2428
SourceRange getReturnTypeSourceRange() const
Attempt to compute an informative source range covering the function return type.
Definition Decl.cpp:4068
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition Decl.cpp:3806
param_iterator param_end()
Definition Decl.h:2918
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
Definition Decl.h:3052
void setIsMultiVersion(bool V=true)
Sets the multiversion state for this declaration and all of its redeclarations.
Definition Decl.h:2826
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
Definition Decl.cpp:3695
QualType getReturnType() const
Definition Decl.h:2976
ArrayRef< ParmVarDecl * > parameters() const
Definition Decl.h:2905
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
Definition Decl.h:2570
param_iterator param_begin()
Definition Decl.h:2917
bool isVariadic() const
Whether this function is variadic.
Definition Decl.cpp:3121
bool isConstexprSpecified() const
Definition Decl.h:2606
bool isExternC() const
Determines whether this function is a function with external, C linkage.
Definition Decl.cpp:3662
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template instantiation this function represents.
Definition Decl.cpp:4458
bool isConsteval() const
Definition Decl.h:2609
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition Decl.cpp:3870
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
Definition Decl.cpp:3188
bool isInlineSpecified() const
Determine whether the "inline" keyword was specified for this function.
Definition Decl.h:3030
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:60
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:4432
MSGuidDeclParts Parts
Definition DeclCXX.h:4434
Describes a module or submodule.
Definition Module.h:340
This represents a decl that may have a name.
Definition Decl.h:275
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:296
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.
Definition Decl.cpp:1978
bool isExternallyVisible() const
Definition Decl.h:434
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:91
llvm::NVPTX::GPUKind nvptxKind() const
Definition OffloadArch.h:94
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:1820
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:2968
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:8501
QualType getCanonicalType() const
Definition TypeBase.h:8553
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition TypeBase.h:8595
const Type * getTypePtrOrNull() const
Definition TypeBase.h:8505
Represents a struct/union/class.
Definition Decl.h:4460
field_iterator field_end() const
Definition Decl.h:4666
field_range fields() const
Definition Decl.h:4663
specific_decl_iterator< FieldDecl > field_iterator
Definition Decl.h:4660
RecordDecl * getDefinitionOrSelf() const
Definition Decl.h:4648
field_iterator field_begin() const
Definition Decl.cpp:5339
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
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:211
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:963
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:424
void handleWebAssemblyImportModuleAttr(Decl *D, const ParsedAttr &AL)
Definition SemaWasm.cpp:399
void handleWebAssemblyExportNameAttr(Decl *D, const ParsedAttr &AL)
Definition SemaWasm.cpp:448
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:1384
sema::DelayedDiagnosticPool * getCurrentPool() const
Returns the current delayed-diagnostics pool.
Definition Sema.h:1399
void popWithoutEmitting(DelayedDiagnosticsState state)
Leave a delayed-diagnostic state that was previously pushed.
Definition Sema.h:1413
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:863
SemaAMDGPU & AMDGPU()
Definition Sema.h:1446
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:9370
EnforceTCBAttr * mergeEnforceTCBAttr(Decl *D, const EnforceTCBAttr &AL)
SemaM68k & M68k()
Definition Sema.h:1496
DelayedDiagnosticsState ParsingDeclState
Definition Sema.h:1379
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:4917
SemaOpenMP & OpenMP()
Definition Sema.h:1531
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:5245
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:1471
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:4977
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:1556
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:1576
ParmVarDecl * BuildParmVarDeclForTypedef(DeclContext *DC, SourceLocation Loc, QualType T)
Synthesizes a variable for a parameter arising from a typedef.
ASTContext & Context
Definition Sema.h:1304
void LazyProcessLifetimeCaptureByParams(FunctionDecl *FD)
DiagnosticsEngine & getDiagnostics() const
Definition Sema.h:932
SemaObjC & ObjC()
Definition Sema.h:1516
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:935
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:930
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
Definition Sema.cpp:84
@ UPPC_Expression
An arbitrary expression.
Definition Sema.h:14506
const LangOptions & getLangOpts() const
Definition Sema.h:928
ModularFormatAttr * mergeModularFormatAttr(Decl *D, const AttributeCommonInfo &CI, const IdentifierInfo *ModularImplFn, StringRef ImplName, MutableArrayRef< StringRef > Aspects)
SemaBPF & BPF()
Definition Sema.h:1461
Preprocessor & PP
Definition Sema.h:1303
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:1506
AssignConvertType CheckAssignmentConstraints(SourceLocation Loc, QualType LHSType, QualType RHSType)
CheckAssignmentConstraints - Perform type checking for assignment, argument passing,...
const LangOptions & LangOpts
Definition Sema.h:1302
static const uint64_t MaximumAlignment
Definition Sema.h:1231
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:1481
AlwaysInlineAttr * mergeAlwaysInlineAttr(Decl *D, const AttributeCommonInfo &CI, const IdentifierInfo *Ident)
SemaMIPS & MIPS()
Definition Sema.h:1501
SemaRISCV & RISCV()
Definition Sema.h:1546
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:1561
NamedDecl * getCurFunctionOrMethodDecl() const
getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method or C function we're in,...
Definition Sema.cpp:1780
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:4928
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:8084
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition Sema.h:1444
void ActOnInitPriorityAttr(Decl *D, const Attr *A)
SemaOpenCL & OpenCL()
Definition Sema.h:1526
ExprResult PerformContextuallyConvertToBool(Expr *From)
PerformContextuallyConvertToBool - Perform a contextual conversion of the expression From to bool (C+...
FunctionDecl * ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, bool Complain=false, DeclAccessPair *Found=nullptr, TemplateSpecCandidateSet *FailedTSC=nullptr, bool ForTypeDeduction=false)
Given an expression that refers to an overloaded function, try to resolve that overloaded function ex...
NamedDecl * DeclClonePragmaWeak(NamedDecl *ND, const IdentifierInfo *II, SourceLocation Loc)
DeclClonePragmaWeak - clone existing decl (maybe definition), #pragma weak needs a non-definition dec...
DLLExportAttr * mergeDLLExportAttr(Decl *D, const AttributeCommonInfo &CI)
CodeSegAttr * mergeCodeSegAttr(Decl *D, const AttributeCommonInfo &CI, StringRef Name)
SectionAttr * mergeSectionAttr(Decl *D, const AttributeCommonInfo &CI, StringRef Name)
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
Definition Sema.h:14055
SourceManager & getSourceManager() const
Definition Sema.h:933
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:15594
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:1305
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:4896
@ AP_PragmaClangAttribute
The availability attribute was applied using 'pragma clang attribute'.
Definition Sema.h:4888
@ AP_InferredFromOtherPlatform
The availability attribute for a specific platform was inferred from an availability attribute for an...
Definition Sema.h:4892
@ AP_PragmaClangAttribute_InferredFromAnyAppleOS
The availability attribute was inferred from an 'anyAppleOS' availability attribute that was applied ...
Definition Sema.h:4901
@ AP_Explicit
The availability attribute was specified explicitly next to the declaration.
Definition Sema.h:4885
SemaPPC & PPC()
Definition Sema.h:1536
SmallVector< Decl *, 2 > WeakTopLevelDecl
WeakTopLevelDecl - Translation-unit scoped declarations generated by #pragma weak during processing o...
Definition Sema.h:4965
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:1263
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:3095
SemaAVR & AVR()
Definition Sema.h:1456
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:3602
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:1571
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:1451
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:1819
bool isBeingDefined() const
Return true if this decl is currently being defined.
Definition Decl.h:3973
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition Decl.h:3953
bool isUnion() const
Definition Decl.h:4063
Exposes information about the current target.
Definition TargetInfo.h:226
TargetOptions & getTargetOpts() const
Retrieve the target options.
Definition TargetInfo.h:332
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:495
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:900
virtual bool validateCPUSpecificCPUDispatch(StringRef Name) const
virtual bool hasProtectedVisibility() const
Does this target support "protected" visibility?
virtual unsigned getUnwindWordWidth() const
Definition TargetInfo.h:895
unsigned getCharWidth() const
Definition TargetInfo.h:526
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:8472
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:8483
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:2693
bool isBlockPointerType() const
Definition TypeBase.h:8758
bool isVoidType() const
Definition TypeBase.h:9110
bool isBooleanType() const
Definition TypeBase.h:9247
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
Definition TypeBase.h:9297
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:8837
bool isCharType() const
Definition Type.cpp:2223
bool isFunctionPointerType() const
Definition TypeBase.h:8805
bool isPointerType() const
Definition TypeBase.h:8738
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition TypeBase.h:9154
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9404
bool isReferenceType() const
Definition TypeBase.h:8762
bool isEnumeralType() const
Definition TypeBase.h:8869
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:3338
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:9232
bool isExtVectorType() const
Definition TypeBase.h:8881
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:9013
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:8742
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
Definition Type.cpp:2559
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
Definition Type.cpp:2429
bool isVectorType() const
Definition TypeBase.h:8877
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:2421
bool isAnyPointerType() const
Definition TypeBase.h:8746
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9337
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:3697
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:5188
Represents a dependent using declaration which was marked with typename.
Definition DeclCXX.h:4066
Represents a dependent using declaration which was not marked with typename.
Definition DeclCXX.h:3969
Represents a C++ using-declaration.
Definition DeclCXX.h:3620
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:713
void setType(QualType newType)
Definition Decl.h:725
QualType getType() const
Definition Decl.h:724
Represents a variable declaration or definition.
Definition Decl.h:933
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
Definition Decl.cpp:2133
@ TLS_None
Not a TLS variable.
Definition Decl.h:953
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:849
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:824
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:622
@ None
Don't merge availability attributes at all.
Definition Sema.h:624
@ Override
Merge availability attributes for an override, which requires an exact match or a weakening of constr...
Definition Sema.h:630
@ OptionalProtocolImplementation
Merge availability attributes for an implementation of an optional protocol requirement.
Definition Sema.h:636
@ Redeclaration
Merge availability attributes for a redeclaration, which requires an exact match.
Definition Sema.h:627
@ ProtocolImplementation
Merge availability attributes for an implementation of a protocol requirement.
Definition Sema.h:633
@ 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)
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:493
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:74
@ 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:6024
@ None
No keyword precedes the qualified type name.
Definition TypeBase.h:6040
@ Union
The "union" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:6027
ActionResult< Expr * > ExprResult
Definition Ownership.h:249
@ Other
Other implicit parameter.
Definition Decl.h:1775
__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:4411
uint32_t Part1
{01234567-...
Definition DeclCXX.h:4409
uint16_t Part3
...-cdef-...
Definition DeclCXX.h:4413
uint8_t Part4And5[8]
...-0123-456789abcdef}
Definition DeclCXX.h:4415
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:59
std::vector< std::string > Features
Definition TargetInfo.h:60