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