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

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of clang/lib/Sema/SemaDeclAttr.cpp