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