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