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