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