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