1//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements decl-related attribute processing.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/ASTConsumer.h"
14#include "clang/AST/ASTContext.h"
15#include "clang/AST/ASTMutationListener.h"
16#include "clang/AST/CXXInheritance.h"
17#include "clang/AST/DeclCXX.h"
18#include "clang/AST/DeclObjC.h"
19#include "clang/AST/DeclTemplate.h"
20#include "clang/AST/Expr.h"
21#include "clang/AST/ExprCXX.h"
22#include "clang/AST/Mangle.h"
23#include "clang/AST/RecursiveASTVisitor.h"
24#include "clang/AST/Type.h"
25#include "clang/Basic/CharInfo.h"
26#include "clang/Basic/Cuda.h"
27#include "clang/Basic/DarwinSDKInfo.h"
28#include "clang/Basic/HLSLRuntime.h"
29#include "clang/Basic/LangOptions.h"
30#include "clang/Basic/SourceLocation.h"
31#include "clang/Basic/SourceManager.h"
32#include "clang/Basic/TargetBuiltins.h"
33#include "clang/Basic/TargetInfo.h"
34#include "clang/Lex/Preprocessor.h"
35#include "clang/Sema/DeclSpec.h"
36#include "clang/Sema/DelayedDiagnostic.h"
37#include "clang/Sema/Initialization.h"
38#include "clang/Sema/Lookup.h"
39#include "clang/Sema/ParsedAttr.h"
40#include "clang/Sema/Scope.h"
41#include "clang/Sema/ScopeInfo.h"
42#include "clang/Sema/SemaCUDA.h"
43#include "clang/Sema/SemaHLSL.h"
44#include "clang/Sema/SemaInternal.h"
45#include "llvm/ADT/STLExtras.h"
46#include "llvm/ADT/STLForwardCompat.h"
47#include "llvm/ADT/StringExtras.h"
48#include "llvm/Demangle/Demangle.h"
49#include "llvm/IR/Assumptions.h"
50#include "llvm/MC/MCSectionMachO.h"
51#include "llvm/Support/Error.h"
52#include "llvm/Support/MathExtras.h"
53#include "llvm/Support/raw_ostream.h"
54#include <optional>
55
56using namespace clang;
57using namespace sema;
58
59namespace AttributeLangSupport {
60 enum LANG {
61 C,
62 Cpp,
63 ObjC
64 };
65} // end namespace AttributeLangSupport
66
67//===----------------------------------------------------------------------===//
68// Helper functions
69//===----------------------------------------------------------------------===//
70
71/// isFunctionOrMethod - Return true if the given decl has function
72/// type (function or function-typed variable) or an Objective-C
73/// method.
74static bool isFunctionOrMethod(const Decl *D) {
75 return (D->getFunctionType() != nullptr) || isa<ObjCMethodDecl>(Val: D);
76}
77
78/// Return true if the given decl has function type (function or
79/// function-typed variable) or an Objective-C method or a block.
80static bool isFunctionOrMethodOrBlock(const Decl *D) {
81 return isFunctionOrMethod(D) || isa<BlockDecl>(Val: D);
82}
83
84/// Return true if the given decl has a declarator that should have
85/// been processed by Sema::GetTypeForDeclarator.
86static bool hasDeclarator(const Decl *D) {
87 // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
88 return isa<DeclaratorDecl>(Val: D) || isa<BlockDecl>(Val: D) || isa<TypedefNameDecl>(Val: D) ||
89 isa<ObjCPropertyDecl>(Val: D);
90}
91
92/// hasFunctionProto - Return true if the given decl has a argument
93/// information. This decl should have already passed
94/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
95static bool hasFunctionProto(const Decl *D) {
96 if (const FunctionType *FnTy = D->getFunctionType())
97 return isa<FunctionProtoType>(Val: FnTy);
98 return isa<ObjCMethodDecl>(Val: D) || isa<BlockDecl>(Val: D);
99}
100
101/// getFunctionOrMethodNumParams - Return number of function or method
102/// parameters. It is an error to call this on a K&R function (use
103/// hasFunctionProto first).
104static unsigned getFunctionOrMethodNumParams(const Decl *D) {
105 if (const FunctionType *FnTy = D->getFunctionType())
106 return cast<FunctionProtoType>(Val: FnTy)->getNumParams();
107 if (const auto *BD = dyn_cast<BlockDecl>(Val: D))
108 return BD->getNumParams();
109 return cast<ObjCMethodDecl>(Val: D)->param_size();
110}
111
112static const ParmVarDecl *getFunctionOrMethodParam(const Decl *D,
113 unsigned Idx) {
114 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D))
115 return FD->getParamDecl(i: Idx);
116 if (const auto *MD = dyn_cast<ObjCMethodDecl>(Val: D))
117 return MD->getParamDecl(Idx);
118 if (const auto *BD = dyn_cast<BlockDecl>(Val: D))
119 return BD->getParamDecl(i: Idx);
120 return nullptr;
121}
122
123static QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx) {
124 if (const FunctionType *FnTy = D->getFunctionType())
125 return cast<FunctionProtoType>(Val: FnTy)->getParamType(i: Idx);
126 if (const auto *BD = dyn_cast<BlockDecl>(Val: D))
127 return BD->getParamDecl(i: Idx)->getType();
128
129 return cast<ObjCMethodDecl>(Val: D)->parameters()[Idx]->getType();
130}
131
132static SourceRange getFunctionOrMethodParamRange(const Decl *D, unsigned Idx) {
133 if (auto *PVD = getFunctionOrMethodParam(D, Idx))
134 return PVD->getSourceRange();
135 return SourceRange();
136}
137
138static QualType getFunctionOrMethodResultType(const Decl *D) {
139 if (const FunctionType *FnTy = D->getFunctionType())
140 return FnTy->getReturnType();
141 return cast<ObjCMethodDecl>(Val: D)->getReturnType();
142}
143
144static SourceRange getFunctionOrMethodResultSourceRange(const Decl *D) {
145 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D))
146 return FD->getReturnTypeSourceRange();
147 if (const auto *MD = dyn_cast<ObjCMethodDecl>(Val: D))
148 return MD->getReturnTypeSourceRange();
149 return SourceRange();
150}
151
152static bool isFunctionOrMethodVariadic(const Decl *D) {
153 if (const FunctionType *FnTy = D->getFunctionType())
154 return cast<FunctionProtoType>(Val: FnTy)->isVariadic();
155 if (const auto *BD = dyn_cast<BlockDecl>(Val: D))
156 return BD->isVariadic();
157 return cast<ObjCMethodDecl>(Val: D)->isVariadic();
158}
159
160static bool isInstanceMethod(const Decl *D) {
161 if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(Val: D))
162 return MethodDecl->isInstance();
163 return false;
164}
165
166static inline bool isNSStringType(QualType T, ASTContext &Ctx,
167 bool AllowNSAttributedString = false) {
168 const auto *PT = T->getAs<ObjCObjectPointerType>();
169 if (!PT)
170 return false;
171
172 ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
173 if (!Cls)
174 return false;
175
176 IdentifierInfo* ClsName = Cls->getIdentifier();
177
178 if (AllowNSAttributedString &&
179 ClsName == &Ctx.Idents.get(Name: "NSAttributedString"))
180 return true;
181 // FIXME: Should we walk the chain of classes?
182 return ClsName == &Ctx.Idents.get(Name: "NSString") ||
183 ClsName == &Ctx.Idents.get(Name: "NSMutableString");
184}
185
186static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
187 const auto *PT = T->getAs<PointerType>();
188 if (!PT)
189 return false;
190
191 const auto *RT = PT->getPointeeType()->getAs<RecordType>();
192 if (!RT)
193 return false;
194
195 const RecordDecl *RD = RT->getDecl();
196 if (RD->getTagKind() != TagTypeKind::Struct)
197 return false;
198
199 return RD->getIdentifier() == &Ctx.Idents.get(Name: "__CFString");
200}
201
202static unsigned getNumAttributeArgs(const ParsedAttr &AL) {
203 // FIXME: Include the type in the argument list.
204 return AL.getNumArgs() + AL.hasParsedType();
205}
206
207/// A helper function to provide Attribute Location for the Attr types
208/// AND the ParsedAttr.
209template <typename AttrInfo>
210static std::enable_if_t<std::is_base_of_v<Attr, AttrInfo>, SourceLocation>
211getAttrLoc(const AttrInfo &AL) {
212 return AL.getLocation();
213}
214static SourceLocation getAttrLoc(const ParsedAttr &AL) { return AL.getLoc(); }
215
216/// If Expr is a valid integer constant, get the value of the integer
217/// expression and return success or failure. May output an error.
218///
219/// Negative argument is implicitly converted to unsigned, unless
220/// \p StrictlyUnsigned is true.
221template <typename AttrInfo>
222static bool checkUInt32Argument(Sema &S, const AttrInfo &AI, const Expr *Expr,
223 uint32_t &Val, unsigned Idx = UINT_MAX,
224 bool StrictlyUnsigned = false) {
225 std::optional<llvm::APSInt> I = llvm::APSInt(32);
226 if (Expr->isTypeDependent() ||
227 !(I = Expr->getIntegerConstantExpr(Ctx: S.Context))) {
228 if (Idx != UINT_MAX)
229 S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
230 << &AI << Idx << AANT_ArgumentIntegerConstant
231 << Expr->getSourceRange();
232 else
233 S.Diag(getAttrLoc(AI), diag::err_attribute_argument_type)
234 << &AI << AANT_ArgumentIntegerConstant << Expr->getSourceRange();
235 return false;
236 }
237
238 if (!I->isIntN(N: 32)) {
239 S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
240 << toString(*I, 10, false) << 32 << /* Unsigned */ 1;
241 return false;
242 }
243
244 if (StrictlyUnsigned && I->isSigned() && I->isNegative()) {
245 S.Diag(getAttrLoc(AI), diag::err_attribute_requires_positive_integer)
246 << &AI << /*non-negative*/ 1;
247 return false;
248 }
249
250 Val = (uint32_t)I->getZExtValue();
251 return true;
252}
253
254/// Wrapper around checkUInt32Argument, with an extra check to be sure
255/// that the result will fit into a regular (signed) int. All args have the same
256/// purpose as they do in checkUInt32Argument.
257template <typename AttrInfo>
258static bool checkPositiveIntArgument(Sema &S, const AttrInfo &AI, const Expr *Expr,
259 int &Val, unsigned Idx = UINT_MAX) {
260 uint32_t UVal;
261 if (!checkUInt32Argument(S, AI, Expr, UVal, Idx))
262 return false;
263
264 if (UVal > (uint32_t)std::numeric_limits<int>::max()) {
265 llvm::APSInt I(32); // for toString
266 I = UVal;
267 S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
268 << toString(I, 10, false) << 32 << /* Unsigned */ 0;
269 return false;
270 }
271
272 Val = UVal;
273 return true;
274}
275
276/// Diagnose mutually exclusive attributes when present on a given
277/// declaration. Returns true if diagnosed.
278template <typename AttrTy>
279static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
280 if (const auto *A = D->getAttr<AttrTy>()) {
281 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
282 << AL << A
283 << (AL.isRegularKeywordAttribute() || A->isRegularKeywordAttribute());
284 S.Diag(A->getLocation(), diag::note_conflicting_attribute);
285 return true;
286 }
287 return false;
288}
289
290template <typename AttrTy>
291static bool checkAttrMutualExclusion(Sema &S, Decl *D, const Attr &AL) {
292 if (const auto *A = D->getAttr<AttrTy>()) {
293 S.Diag(AL.getLocation(), diag::err_attributes_are_not_compatible)
294 << &AL << A
295 << (AL.isRegularKeywordAttribute() || A->isRegularKeywordAttribute());
296 S.Diag(A->getLocation(), diag::note_conflicting_attribute);
297 return true;
298 }
299 return false;
300}
301
302/// Check if IdxExpr is a valid parameter index for a function or
303/// instance method D. May output an error.
304///
305/// \returns true if IdxExpr is a valid index.
306template <typename AttrInfo>
307static bool checkFunctionOrMethodParameterIndex(
308 Sema &S, const Decl *D, const AttrInfo &AI, unsigned AttrArgNum,
309 const Expr *IdxExpr, ParamIdx &Idx, bool CanIndexImplicitThis = false) {
310 assert(isFunctionOrMethodOrBlock(D));
311
312 // In C++ the implicit 'this' function parameter also counts.
313 // Parameters are counted from one.
314 bool HP = hasFunctionProto(D);
315 bool HasImplicitThisParam = isInstanceMethod(D);
316 bool IV = HP && isFunctionOrMethodVariadic(D);
317 unsigned NumParams =
318 (HP ? getFunctionOrMethodNumParams(D) : 0) + HasImplicitThisParam;
319
320 std::optional<llvm::APSInt> IdxInt;
321 if (IdxExpr->isTypeDependent() ||
322 !(IdxInt = IdxExpr->getIntegerConstantExpr(Ctx: S.Context))) {
323 S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
324 << &AI << AttrArgNum << AANT_ArgumentIntegerConstant
325 << IdxExpr->getSourceRange();
326 return false;
327 }
328
329 unsigned IdxSource = IdxInt->getLimitedValue(UINT_MAX);
330 if (IdxSource < 1 || (!IV && IdxSource > NumParams)) {
331 S.Diag(getAttrLoc(AI), diag::err_attribute_argument_out_of_bounds)
332 << &AI << AttrArgNum << IdxExpr->getSourceRange();
333 return false;
334 }
335 if (HasImplicitThisParam && !CanIndexImplicitThis) {
336 if (IdxSource == 1) {
337 S.Diag(getAttrLoc(AI), diag::err_attribute_invalid_implicit_this_argument)
338 << &AI << IdxExpr->getSourceRange();
339 return false;
340 }
341 }
342
343 Idx = ParamIdx(IdxSource, D);
344 return true;
345}
346
347/// Check if the argument \p E is a ASCII string literal. If not emit an error
348/// and return false, otherwise set \p Str to the value of the string literal
349/// and return true.
350bool Sema::checkStringLiteralArgumentAttr(const AttributeCommonInfo &CI,
351 const Expr *E, StringRef &Str,
352 SourceLocation *ArgLocation) {
353 const auto *Literal = dyn_cast<StringLiteral>(Val: E->IgnoreParenCasts());
354 if (ArgLocation)
355 *ArgLocation = E->getBeginLoc();
356
357 if (!Literal || (!Literal->isUnevaluated() && !Literal->isOrdinary())) {
358 Diag(E->getBeginLoc(), diag::err_attribute_argument_type)
359 << CI << AANT_ArgumentString;
360 return false;
361 }
362
363 Str = Literal->getString();
364 return true;
365}
366
367/// Check if the argument \p ArgNum of \p Attr is a ASCII string literal.
368/// If not emit an error and return false. If the argument is an identifier it
369/// will emit an error with a fixit hint and treat it as if it was a string
370/// literal.
371bool Sema::checkStringLiteralArgumentAttr(const ParsedAttr &AL, unsigned ArgNum,
372 StringRef &Str,
373 SourceLocation *ArgLocation) {
374 // Look for identifiers. If we have one emit a hint to fix it to a literal.
375 if (AL.isArgIdent(Arg: ArgNum)) {
376 IdentifierLoc *Loc = AL.getArgAsIdent(Arg: ArgNum);
377 Diag(Loc->Loc, diag::err_attribute_argument_type)
378 << AL << AANT_ArgumentString
379 << FixItHint::CreateInsertion(Loc->Loc, "\"")
380 << FixItHint::CreateInsertion(getLocForEndOfToken(Loc->Loc), "\"");
381 Str = Loc->Ident->getName();
382 if (ArgLocation)
383 *ArgLocation = Loc->Loc;
384 return true;
385 }
386
387 // Now check for an actual string literal.
388 Expr *ArgExpr = AL.getArgAsExpr(Arg: ArgNum);
389 const auto *Literal = dyn_cast<StringLiteral>(Val: ArgExpr->IgnoreParenCasts());
390 if (ArgLocation)
391 *ArgLocation = ArgExpr->getBeginLoc();
392
393 if (!Literal || (!Literal->isUnevaluated() && !Literal->isOrdinary())) {
394 Diag(ArgExpr->getBeginLoc(), diag::err_attribute_argument_type)
395 << AL << AANT_ArgumentString;
396 return false;
397 }
398 Str = Literal->getString();
399 return checkStringLiteralArgumentAttr(CI: AL, E: ArgExpr, Str, ArgLocation);
400}
401
402/// Applies the given attribute to the Decl without performing any
403/// additional semantic checking.
404template <typename AttrType>
405static void handleSimpleAttribute(Sema &S, Decl *D,
406 const AttributeCommonInfo &CI) {
407 D->addAttr(A: ::new (S.Context) AttrType(S.Context, CI));
408}
409
410template <typename... DiagnosticArgs>
411static const Sema::SemaDiagnosticBuilder&
412appendDiagnostics(const Sema::SemaDiagnosticBuilder &Bldr) {
413 return Bldr;
414}
415
416template <typename T, typename... DiagnosticArgs>
417static const Sema::SemaDiagnosticBuilder&
418appendDiagnostics(const Sema::SemaDiagnosticBuilder &Bldr, T &&ExtraArg,
419 DiagnosticArgs &&... ExtraArgs) {
420 return appendDiagnostics(Bldr << std::forward<T>(ExtraArg),
421 std::forward<DiagnosticArgs>(ExtraArgs)...);
422}
423
424/// Add an attribute @c AttrType to declaration @c D, provided that
425/// @c PassesCheck is true.
426/// Otherwise, emit diagnostic @c DiagID, passing in all parameters
427/// specified in @c ExtraArgs.
428template <typename AttrType, typename... DiagnosticArgs>
429static void handleSimpleAttributeOrDiagnose(Sema &S, Decl *D,
430 const AttributeCommonInfo &CI,
431 bool PassesCheck, unsigned DiagID,
432 DiagnosticArgs &&... ExtraArgs) {
433 if (!PassesCheck) {
434 Sema::SemaDiagnosticBuilder DB = S.Diag(D->getBeginLoc(), DiagID);
435 appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...);
436 return;
437 }
438 handleSimpleAttribute<AttrType>(S, D, CI);
439}
440
441/// Check if the passed-in expression is of type int or bool.
442static bool isIntOrBool(Expr *Exp) {
443 QualType QT = Exp->getType();
444 return QT->isBooleanType() || QT->isIntegerType();
445}
446
447
448// Check to see if the type is a smart pointer of some kind. We assume
449// it's a smart pointer if it defines both operator-> and operator*.
450static bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) {
451 auto IsOverloadedOperatorPresent = [&S](const RecordDecl *Record,
452 OverloadedOperatorKind Op) {
453 DeclContextLookupResult Result =
454 Record->lookup(S.Context.DeclarationNames.getCXXOperatorName(Op));
455 return !Result.empty();
456 };
457
458 const RecordDecl *Record = RT->getDecl();
459 bool foundStarOperator = IsOverloadedOperatorPresent(Record, OO_Star);
460 bool foundArrowOperator = IsOverloadedOperatorPresent(Record, OO_Arrow);
461 if (foundStarOperator && foundArrowOperator)
462 return true;
463
464 const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(Val: Record);
465 if (!CXXRecord)
466 return false;
467
468 for (const auto &BaseSpecifier : CXXRecord->bases()) {
469 if (!foundStarOperator)
470 foundStarOperator = IsOverloadedOperatorPresent(
471 BaseSpecifier.getType()->getAsRecordDecl(), OO_Star);
472 if (!foundArrowOperator)
473 foundArrowOperator = IsOverloadedOperatorPresent(
474 BaseSpecifier.getType()->getAsRecordDecl(), OO_Arrow);
475 }
476
477 if (foundStarOperator && foundArrowOperator)
478 return true;
479
480 return false;
481}
482
483/// Check if passed in Decl is a pointer type.
484/// Note that this function may produce an error message.
485/// \return true if the Decl is a pointer type; false otherwise
486static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
487 const ParsedAttr &AL) {
488 const auto *VD = cast<ValueDecl>(Val: D);
489 QualType QT = VD->getType();
490 if (QT->isAnyPointerType())
491 return true;
492
493 if (const auto *RT = QT->getAs<RecordType>()) {
494 // If it's an incomplete type, it could be a smart pointer; skip it.
495 // (We don't want to force template instantiation if we can avoid it,
496 // since that would alter the order in which templates are instantiated.)
497 if (RT->isIncompleteType())
498 return true;
499
500 if (threadSafetyCheckIsSmartPointer(S, RT))
501 return true;
502 }
503
504 S.Diag(AL.getLoc(), diag::warn_thread_attribute_decl_not_pointer) << AL << QT;
505 return false;
506}
507
508/// Checks that the passed in QualType either is of RecordType or points
509/// to RecordType. Returns the relevant RecordType, null if it does not exit.
510static const RecordType *getRecordType(QualType QT) {
511 if (const auto *RT = QT->getAs<RecordType>())
512 return RT;
513
514 // Now check if we point to record type.
515 if (const auto *PT = QT->getAs<PointerType>())
516 return PT->getPointeeType()->getAs<RecordType>();
517
518 return nullptr;
519}
520
521template <typename AttrType>
522static bool checkRecordDeclForAttr(const RecordDecl *RD) {
523 // Check if the record itself has the attribute.
524 if (RD->hasAttr<AttrType>())
525 return true;
526
527 // Else check if any base classes have the attribute.
528 if (const auto *CRD = dyn_cast<CXXRecordDecl>(Val: RD)) {
529 if (!CRD->forallBases(BaseMatches: [](const CXXRecordDecl *Base) {
530 return !Base->hasAttr<AttrType>();
531 }))
532 return true;
533 }
534 return false;
535}
536
537static bool checkRecordTypeForCapability(Sema &S, QualType Ty) {
538 const RecordType *RT = getRecordType(QT: Ty);
539
540 if (!RT)
541 return false;
542
543 // Don't check for the capability if the class hasn't been defined yet.
544 if (RT->isIncompleteType())
545 return true;
546
547 // Allow smart pointers to be used as capability objects.
548 // FIXME -- Check the type that the smart pointer points to.
549 if (threadSafetyCheckIsSmartPointer(S, RT))
550 return true;
551
552 return checkRecordDeclForAttr<CapabilityAttr>(RT->getDecl());
553}
554
555static bool checkTypedefTypeForCapability(QualType Ty) {
556 const auto *TD = Ty->getAs<TypedefType>();
557 if (!TD)
558 return false;
559
560 TypedefNameDecl *TN = TD->getDecl();
561 if (!TN)
562 return false;
563
564 return TN->hasAttr<CapabilityAttr>();
565}
566
567static bool typeHasCapability(Sema &S, QualType Ty) {
568 if (checkTypedefTypeForCapability(Ty))
569 return true;
570
571 if (checkRecordTypeForCapability(S, Ty))
572 return true;
573
574 return false;
575}
576
577static bool isCapabilityExpr(Sema &S, const Expr *Ex) {
578 // Capability expressions are simple expressions involving the boolean logic
579 // operators &&, || or !, a simple DeclRefExpr, CastExpr or a ParenExpr. Once
580 // a DeclRefExpr is found, its type should be checked to determine whether it
581 // is a capability or not.
582
583 if (const auto *E = dyn_cast<CastExpr>(Val: Ex))
584 return isCapabilityExpr(S, Ex: E->getSubExpr());
585 else if (const auto *E = dyn_cast<ParenExpr>(Val: Ex))
586 return isCapabilityExpr(S, Ex: E->getSubExpr());
587 else if (const auto *E = dyn_cast<UnaryOperator>(Val: Ex)) {
588 if (E->getOpcode() == UO_LNot || E->getOpcode() == UO_AddrOf ||
589 E->getOpcode() == UO_Deref)
590 return isCapabilityExpr(S, Ex: E->getSubExpr());
591 return false;
592 } else if (const auto *E = dyn_cast<BinaryOperator>(Val: Ex)) {
593 if (E->getOpcode() == BO_LAnd || E->getOpcode() == BO_LOr)
594 return isCapabilityExpr(S, Ex: E->getLHS()) &&
595 isCapabilityExpr(S, Ex: E->getRHS());
596 return false;
597 }
598
599 return typeHasCapability(S, Ty: Ex->getType());
600}
601
602/// Checks that all attribute arguments, starting from Sidx, resolve to
603/// a capability object.
604/// \param Sidx The attribute argument index to start checking with.
605/// \param ParamIdxOk Whether an argument can be indexing into a function
606/// parameter list.
607static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D,
608 const ParsedAttr &AL,
609 SmallVectorImpl<Expr *> &Args,
610 unsigned Sidx = 0,
611 bool ParamIdxOk = false) {
612 if (Sidx == AL.getNumArgs()) {
613 // If we don't have any capability arguments, the attribute implicitly
614 // refers to 'this'. So we need to make sure that 'this' exists, i.e. we're
615 // a non-static method, and that the class is a (scoped) capability.
616 const auto *MD = dyn_cast<const CXXMethodDecl>(Val: D);
617 if (MD && !MD->isStatic()) {
618 const CXXRecordDecl *RD = MD->getParent();
619 // FIXME -- need to check this again on template instantiation
620 if (!checkRecordDeclForAttr<CapabilityAttr>(RD) &&
621 !checkRecordDeclForAttr<ScopedLockableAttr>(RD))
622 S.Diag(AL.getLoc(),
623 diag::warn_thread_attribute_not_on_capability_member)
624 << AL << MD->getParent();
625 } else {
626 S.Diag(AL.getLoc(), diag::warn_thread_attribute_not_on_non_static_member)
627 << AL;
628 }
629 }
630
631 for (unsigned Idx = Sidx; Idx < AL.getNumArgs(); ++Idx) {
632 Expr *ArgExp = AL.getArgAsExpr(Arg: Idx);
633
634 if (ArgExp->isTypeDependent()) {
635 // FIXME -- need to check this again on template instantiation
636 Args.push_back(Elt: ArgExp);
637 continue;
638 }
639
640 if (const auto *StrLit = dyn_cast<StringLiteral>(Val: ArgExp)) {
641 if (StrLit->getLength() == 0 ||
642 (StrLit->isOrdinary() && StrLit->getString() == StringRef("*"))) {
643 // Pass empty strings to the analyzer without warnings.
644 // Treat "*" as the universal lock.
645 Args.push_back(Elt: ArgExp);
646 continue;
647 }
648
649 // We allow constant strings to be used as a placeholder for expressions
650 // that are not valid C++ syntax, but warn that they are ignored.
651 S.Diag(AL.getLoc(), diag::warn_thread_attribute_ignored) << AL;
652 Args.push_back(Elt: ArgExp);
653 continue;
654 }
655
656 QualType ArgTy = ArgExp->getType();
657
658 // A pointer to member expression of the form &MyClass::mu is treated
659 // specially -- we need to look at the type of the member.
660 if (const auto *UOp = dyn_cast<UnaryOperator>(Val: ArgExp))
661 if (UOp->getOpcode() == UO_AddrOf)
662 if (const auto *DRE = dyn_cast<DeclRefExpr>(Val: UOp->getSubExpr()))
663 if (DRE->getDecl()->isCXXInstanceMember())
664 ArgTy = DRE->getDecl()->getType();
665
666 // First see if we can just cast to record type, or pointer to record type.
667 const RecordType *RT = getRecordType(QT: ArgTy);
668
669 // Now check if we index into a record type function param.
670 if(!RT && ParamIdxOk) {
671 const auto *FD = dyn_cast<FunctionDecl>(Val: D);
672 const auto *IL = dyn_cast<IntegerLiteral>(Val: ArgExp);
673 if(FD && IL) {
674 unsigned int NumParams = FD->getNumParams();
675 llvm::APInt ArgValue = IL->getValue();
676 uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
677 uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
678 if (!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
679 S.Diag(AL.getLoc(),
680 diag::err_attribute_argument_out_of_bounds_extra_info)
681 << AL << Idx + 1 << NumParams;
682 continue;
683 }
684 ArgTy = FD->getParamDecl(i: ParamIdxFromZero)->getType();
685 }
686 }
687
688 // If the type does not have a capability, see if the components of the
689 // expression have capabilities. This allows for writing C code where the
690 // capability may be on the type, and the expression is a capability
691 // boolean logic expression. Eg) requires_capability(A || B && !C)
692 if (!typeHasCapability(S, ArgTy) && !isCapabilityExpr(S, ArgExp))
693 S.Diag(AL.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
694 << AL << ArgTy;
695
696 Args.push_back(Elt: ArgExp);
697 }
698}
699
700//===----------------------------------------------------------------------===//
701// Attribute Implementations
702//===----------------------------------------------------------------------===//
703
704static void handlePtGuardedVarAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
705 if (!threadSafetyCheckIsPointer(S, D, AL))
706 return;
707
708 D->addAttr(::new (S.Context) PtGuardedVarAttr(S.Context, AL));
709}
710
711static bool checkGuardedByAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
712 Expr *&Arg) {
713 SmallVector<Expr *, 1> Args;
714 // check that all arguments are lockable objects
715 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
716 unsigned Size = Args.size();
717 if (Size != 1)
718 return false;
719
720 Arg = Args[0];
721
722 return true;
723}
724
725static void handleGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
726 Expr *Arg = nullptr;
727 if (!checkGuardedByAttrCommon(S, D, AL, Arg))
728 return;
729
730 D->addAttr(::new (S.Context) GuardedByAttr(S.Context, AL, Arg));
731}
732
733static void handlePtGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
734 Expr *Arg = nullptr;
735 if (!checkGuardedByAttrCommon(S, D, AL, Arg))
736 return;
737
738 if (!threadSafetyCheckIsPointer(S, D, AL))
739 return;
740
741 D->addAttr(::new (S.Context) PtGuardedByAttr(S.Context, AL, Arg));
742}
743
744static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
745 SmallVectorImpl<Expr *> &Args) {
746 if (!AL.checkAtLeastNumArgs(S, Num: 1))
747 return false;
748
749 // Check that this attribute only applies to lockable types.
750 QualType QT = cast<ValueDecl>(Val: D)->getType();
751 if (!QT->isDependentType() && !typeHasCapability(S, Ty: QT)) {
752 S.Diag(AL.getLoc(), diag::warn_thread_attribute_decl_not_lockable) << AL;
753 return false;
754 }
755
756 // Check that all arguments are lockable objects.
757 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
758 if (Args.empty())
759 return false;
760
761 return true;
762}
763
764static void handleAcquiredAfterAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
765 SmallVector<Expr *, 1> Args;
766 if (!checkAcquireOrderAttrCommon(S, D, AL, Args))
767 return;
768
769 Expr **StartArg = &Args[0];
770 D->addAttr(::new (S.Context)
771 AcquiredAfterAttr(S.Context, AL, StartArg, Args.size()));
772}
773
774static void handleAcquiredBeforeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
775 SmallVector<Expr *, 1> Args;
776 if (!checkAcquireOrderAttrCommon(S, D, AL, Args))
777 return;
778
779 Expr **StartArg = &Args[0];
780 D->addAttr(::new (S.Context)
781 AcquiredBeforeAttr(S.Context, AL, StartArg, Args.size()));
782}
783
784static bool checkLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
785 SmallVectorImpl<Expr *> &Args) {
786 // zero or more arguments ok
787 // check that all arguments are lockable objects
788 checkAttrArgsAreCapabilityObjs(S, D, AL, Args, Sidx: 0, /*ParamIdxOk=*/true);
789
790 return true;
791}
792
793static void handleAssertSharedLockAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
794 SmallVector<Expr *, 1> Args;
795 if (!checkLockFunAttrCommon(S, D, AL, Args))
796 return;
797
798 unsigned Size = Args.size();
799 Expr **StartArg = Size == 0 ? nullptr : &Args[0];
800 D->addAttr(::new (S.Context)
801 AssertSharedLockAttr(S.Context, AL, StartArg, Size));
802}
803
804static void handleAssertExclusiveLockAttr(Sema &S, Decl *D,
805 const ParsedAttr &AL) {
806 SmallVector<Expr *, 1> Args;
807 if (!checkLockFunAttrCommon(S, D, AL, Args))
808 return;
809
810 unsigned Size = Args.size();
811 Expr **StartArg = Size == 0 ? nullptr : &Args[0];
812 D->addAttr(::new (S.Context)
813 AssertExclusiveLockAttr(S.Context, AL, StartArg, Size));
814}
815
816/// Checks to be sure that the given parameter number is in bounds, and
817/// is an integral type. Will emit appropriate diagnostics if this returns
818/// false.
819///
820/// AttrArgNo is used to actually retrieve the argument, so it's base-0.
821template <typename AttrInfo>
822static bool checkParamIsIntegerType(Sema &S, const Decl *D, const AttrInfo &AI,
823 unsigned AttrArgNo) {
824 assert(AI.isArgExpr(AttrArgNo) && "Expected expression argument");
825 Expr *AttrArg = AI.getArgAsExpr(AttrArgNo);
826 ParamIdx Idx;
827 if (!checkFunctionOrMethodParameterIndex(S, D, AI, AttrArgNo + 1, AttrArg,
828 Idx))
829 return false;
830
831 QualType ParamTy = getFunctionOrMethodParamType(D, Idx: Idx.getASTIndex());
832 if (!ParamTy->isIntegerType() && !ParamTy->isCharType()) {
833 SourceLocation SrcLoc = AttrArg->getBeginLoc();
834 S.Diag(SrcLoc, diag::err_attribute_integers_only)
835 << AI << getFunctionOrMethodParamRange(D, Idx.getASTIndex());
836 return false;
837 }
838 return true;
839}
840
841static void handleAllocSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
842 if (!AL.checkAtLeastNumArgs(S, Num: 1) || !AL.checkAtMostNumArgs(S, Num: 2))
843 return;
844
845 assert(isFunctionOrMethod(D) && hasFunctionProto(D));
846
847 QualType RetTy = getFunctionOrMethodResultType(D);
848 if (!RetTy->isPointerType()) {
849 S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only) << AL;
850 return;
851 }
852
853 const Expr *SizeExpr = AL.getArgAsExpr(Arg: 0);
854 int SizeArgNoVal;
855 // Parameter indices are 1-indexed, hence Index=1
856 if (!checkPositiveIntArgument(S, AI: AL, Expr: SizeExpr, Val&: SizeArgNoVal, /*Idx=*/1))
857 return;
858 if (!checkParamIsIntegerType(S, D, AI: AL, /*AttrArgNo=*/0))
859 return;
860 ParamIdx SizeArgNo(SizeArgNoVal, D);
861
862 ParamIdx NumberArgNo;
863 if (AL.getNumArgs() == 2) {
864 const Expr *NumberExpr = AL.getArgAsExpr(Arg: 1);
865 int Val;
866 // Parameter indices are 1-based, hence Index=2
867 if (!checkPositiveIntArgument(S, AI: AL, Expr: NumberExpr, Val, /*Idx=*/2))
868 return;
869 if (!checkParamIsIntegerType(S, D, AI: AL, /*AttrArgNo=*/1))
870 return;
871 NumberArgNo = ParamIdx(Val, D);
872 }
873
874 D->addAttr(::new (S.Context)
875 AllocSizeAttr(S.Context, AL, SizeArgNo, NumberArgNo));
876}
877
878static bool checkTryLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
879 SmallVectorImpl<Expr *> &Args) {
880 if (!AL.checkAtLeastNumArgs(S, Num: 1))
881 return false;
882
883 if (!isIntOrBool(Exp: AL.getArgAsExpr(Arg: 0))) {
884 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
885 << AL << 1 << AANT_ArgumentIntOrBool;
886 return false;
887 }
888
889 // check that all arguments are lockable objects
890 checkAttrArgsAreCapabilityObjs(S, D, AL, Args, Sidx: 1);
891
892 return true;
893}
894
895static void handleSharedTrylockFunctionAttr(Sema &S, Decl *D,
896 const ParsedAttr &AL) {
897 SmallVector<Expr*, 2> Args;
898 if (!checkTryLockFunAttrCommon(S, D, AL, Args))
899 return;
900
901 D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(
902 S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));
903}
904
905static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D,
906 const ParsedAttr &AL) {
907 SmallVector<Expr*, 2> Args;
908 if (!checkTryLockFunAttrCommon(S, D, AL, Args))
909 return;
910
911 D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(
912 S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));
913}
914
915static void handleLockReturnedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
916 // check that the argument is lockable object
917 SmallVector<Expr*, 1> Args;
918 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
919 unsigned Size = Args.size();
920 if (Size == 0)
921 return;
922
923 D->addAttr(::new (S.Context) LockReturnedAttr(S.Context, AL, Args[0]));
924}
925
926static void handleLocksExcludedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
927 if (!AL.checkAtLeastNumArgs(S, Num: 1))
928 return;
929
930 // check that all arguments are lockable objects
931 SmallVector<Expr*, 1> Args;
932 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
933 unsigned Size = Args.size();
934 if (Size == 0)
935 return;
936 Expr **StartArg = &Args[0];
937
938 D->addAttr(::new (S.Context)
939 LocksExcludedAttr(S.Context, AL, StartArg, Size));
940}
941
942static bool checkFunctionConditionAttr(Sema &S, Decl *D, const ParsedAttr &AL,
943 Expr *&Cond, StringRef &Msg) {
944 Cond = AL.getArgAsExpr(Arg: 0);
945 if (!Cond->isTypeDependent()) {
946 ExprResult Converted = S.PerformContextuallyConvertToBool(From: Cond);
947 if (Converted.isInvalid())
948 return false;
949 Cond = Converted.get();
950 }
951
952 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 1, Str&: Msg))
953 return false;
954
955 if (Msg.empty())
956 Msg = "<no message provided>";
957
958 SmallVector<PartialDiagnosticAt, 8> Diags;
959 if (isa<FunctionDecl>(Val: D) && !Cond->isValueDependent() &&
960 !Expr::isPotentialConstantExprUnevaluated(E: Cond, FD: cast<FunctionDecl>(Val: D),
961 Diags)) {
962 S.Diag(AL.getLoc(), diag::err_attr_cond_never_constant_expr) << AL;
963 for (const PartialDiagnosticAt &PDiag : Diags)
964 S.Diag(PDiag.first, PDiag.second);
965 return false;
966 }
967 return true;
968}
969
970static void handleEnableIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
971 S.Diag(AL.getLoc(), diag::ext_clang_enable_if);
972
973 Expr *Cond;
974 StringRef Msg;
975 if (checkFunctionConditionAttr(S, D, AL, Cond, Msg))
976 D->addAttr(::new (S.Context) EnableIfAttr(S.Context, AL, Cond, Msg));
977}
978
979static void handleErrorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
980 StringRef NewUserDiagnostic;
981 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: NewUserDiagnostic))
982 return;
983 if (ErrorAttr *EA = S.mergeErrorAttr(D, AL, NewUserDiagnostic))
984 D->addAttr(EA);
985}
986
987static void handleExcludeFromExplicitInstantiationAttr(Sema &S, Decl *D,
988 const ParsedAttr &AL) {
989 const auto *PD = isa<CXXRecordDecl>(Val: D)
990 ? cast<DeclContext>(Val: D)
991 : D->getDeclContext()->getRedeclContext();
992 if (const auto *RD = dyn_cast<CXXRecordDecl>(Val: PD); RD && RD->isLocalClass()) {
993 S.Diag(AL.getLoc(),
994 diag::warn_attribute_exclude_from_explicit_instantiation_local_class)
995 << AL << /*IsMember=*/!isa<CXXRecordDecl>(D);
996 return;
997 }
998 D->addAttr(::new (S.Context)
999 ExcludeFromExplicitInstantiationAttr(S.Context, AL));
1000}
1001
1002namespace {
1003/// Determines if a given Expr references any of the given function's
1004/// ParmVarDecls, or the function's implicit `this` parameter (if applicable).
1005class ArgumentDependenceChecker
1006 : public RecursiveASTVisitor<ArgumentDependenceChecker> {
1007#ifndef NDEBUG
1008 const CXXRecordDecl *ClassType;
1009#endif
1010 llvm::SmallPtrSet<const ParmVarDecl *, 16> Parms;
1011 bool Result;
1012
1013public:
1014 ArgumentDependenceChecker(const FunctionDecl *FD) {
1015#ifndef NDEBUG
1016 if (const auto *MD = dyn_cast<CXXMethodDecl>(Val: FD))
1017 ClassType = MD->getParent();
1018 else
1019 ClassType = nullptr;
1020#endif
1021 Parms.insert(I: FD->param_begin(), E: FD->param_end());
1022 }
1023
1024 bool referencesArgs(Expr *E) {
1025 Result = false;
1026 TraverseStmt(E);
1027 return Result;
1028 }
1029
1030 bool VisitCXXThisExpr(CXXThisExpr *E) {
1031 assert(E->getType()->getPointeeCXXRecordDecl() == ClassType &&
1032 "`this` doesn't refer to the enclosing class?");
1033 Result = true;
1034 return false;
1035 }
1036
1037 bool VisitDeclRefExpr(DeclRefExpr *DRE) {
1038 if (const auto *PVD = dyn_cast<ParmVarDecl>(Val: DRE->getDecl()))
1039 if (Parms.count(Ptr: PVD)) {
1040 Result = true;
1041 return false;
1042 }
1043 return true;
1044 }
1045};
1046}
1047
1048static void handleDiagnoseAsBuiltinAttr(Sema &S, Decl *D,
1049 const ParsedAttr &AL) {
1050 const auto *DeclFD = cast<FunctionDecl>(Val: D);
1051
1052 if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(Val: DeclFD))
1053 if (!MethodDecl->isStatic()) {
1054 S.Diag(AL.getLoc(), diag::err_attribute_no_member_function) << AL;
1055 return;
1056 }
1057
1058 auto DiagnoseType = [&](unsigned Index, AttributeArgumentNType T) {
1059 SourceLocation Loc = [&]() {
1060 auto Union = AL.getArg(Arg: Index - 1);
1061 if (Union.is<Expr *>())
1062 return Union.get<Expr *>()->getBeginLoc();
1063 return Union.get<IdentifierLoc *>()->Loc;
1064 }();
1065
1066 S.Diag(Loc, diag::err_attribute_argument_n_type) << AL << Index << T;
1067 };
1068
1069 FunctionDecl *AttrFD = [&]() -> FunctionDecl * {
1070 if (!AL.isArgExpr(Arg: 0))
1071 return nullptr;
1072 auto *F = dyn_cast_if_present<DeclRefExpr>(Val: AL.getArgAsExpr(Arg: 0));
1073 if (!F)
1074 return nullptr;
1075 return dyn_cast_if_present<FunctionDecl>(Val: F->getFoundDecl());
1076 }();
1077
1078 if (!AttrFD || !AttrFD->getBuiltinID(ConsiderWrapperFunctions: true)) {
1079 DiagnoseType(1, AANT_ArgumentBuiltinFunction);
1080 return;
1081 }
1082
1083 if (AttrFD->getNumParams() != AL.getNumArgs() - 1) {
1084 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments_for)
1085 << AL << AttrFD << AttrFD->getNumParams();
1086 return;
1087 }
1088
1089 SmallVector<unsigned, 8> Indices;
1090
1091 for (unsigned I = 1; I < AL.getNumArgs(); ++I) {
1092 if (!AL.isArgExpr(Arg: I)) {
1093 DiagnoseType(I + 1, AANT_ArgumentIntegerConstant);
1094 return;
1095 }
1096
1097 const Expr *IndexExpr = AL.getArgAsExpr(Arg: I);
1098 uint32_t Index;
1099
1100 if (!checkUInt32Argument(S, AI: AL, Expr: IndexExpr, Val&: Index, Idx: I + 1, StrictlyUnsigned: false))
1101 return;
1102
1103 if (Index > DeclFD->getNumParams()) {
1104 S.Diag(AL.getLoc(), diag::err_attribute_bounds_for_function)
1105 << AL << Index << DeclFD << DeclFD->getNumParams();
1106 return;
1107 }
1108
1109 QualType T1 = AttrFD->getParamDecl(i: I - 1)->getType();
1110 QualType T2 = DeclFD->getParamDecl(i: Index - 1)->getType();
1111
1112 if (T1.getCanonicalType().getUnqualifiedType() !=
1113 T2.getCanonicalType().getUnqualifiedType()) {
1114 S.Diag(IndexExpr->getBeginLoc(), diag::err_attribute_parameter_types)
1115 << AL << Index << DeclFD << T2 << I << AttrFD << T1;
1116 return;
1117 }
1118
1119 Indices.push_back(Elt: Index - 1);
1120 }
1121
1122 D->addAttr(::new (S.Context) DiagnoseAsBuiltinAttr(
1123 S.Context, AL, AttrFD, Indices.data(), Indices.size()));
1124}
1125
1126static void handleDiagnoseIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1127 S.Diag(AL.getLoc(), diag::ext_clang_diagnose_if);
1128
1129 Expr *Cond;
1130 StringRef Msg;
1131 if (!checkFunctionConditionAttr(S, D, AL, Cond, Msg))
1132 return;
1133
1134 StringRef DiagTypeStr;
1135 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 2, Str&: DiagTypeStr))
1136 return;
1137
1138 DiagnoseIfAttr::DiagnosticType DiagType;
1139 if (!DiagnoseIfAttr::ConvertStrToDiagnosticType(DiagTypeStr, DiagType)) {
1140 S.Diag(AL.getArgAsExpr(2)->getBeginLoc(),
1141 diag::err_diagnose_if_invalid_diagnostic_type);
1142 return;
1143 }
1144
1145 bool ArgDependent = false;
1146 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D))
1147 ArgDependent = ArgumentDependenceChecker(FD).referencesArgs(E: Cond);
1148 D->addAttr(::new (S.Context) DiagnoseIfAttr(
1149 S.Context, AL, Cond, Msg, DiagType, ArgDependent, cast<NamedDecl>(D)));
1150}
1151
1152static void handleNoBuiltinAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1153 static constexpr const StringRef kWildcard = "*";
1154
1155 llvm::SmallVector<StringRef, 16> Names;
1156 bool HasWildcard = false;
1157
1158 const auto AddBuiltinName = [&Names, &HasWildcard](StringRef Name) {
1159 if (Name == kWildcard)
1160 HasWildcard = true;
1161 Names.push_back(Elt: Name);
1162 };
1163
1164 // Add previously defined attributes.
1165 if (const auto *NBA = D->getAttr<NoBuiltinAttr>())
1166 for (StringRef BuiltinName : NBA->builtinNames())
1167 AddBuiltinName(BuiltinName);
1168
1169 // Add current attributes.
1170 if (AL.getNumArgs() == 0)
1171 AddBuiltinName(kWildcard);
1172 else
1173 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
1174 StringRef BuiltinName;
1175 SourceLocation LiteralLoc;
1176 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: I, Str&: BuiltinName, ArgLocation: &LiteralLoc))
1177 return;
1178
1179 if (Builtin::Context::isBuiltinFunc(Name: BuiltinName))
1180 AddBuiltinName(BuiltinName);
1181 else
1182 S.Diag(LiteralLoc, diag::warn_attribute_no_builtin_invalid_builtin_name)
1183 << BuiltinName << AL;
1184 }
1185
1186 // Repeating the same attribute is fine.
1187 llvm::sort(C&: Names);
1188 Names.erase(CS: std::unique(first: Names.begin(), last: Names.end()), CE: Names.end());
1189
1190 // Empty no_builtin must be on its own.
1191 if (HasWildcard && Names.size() > 1)
1192 S.Diag(D->getLocation(),
1193 diag::err_attribute_no_builtin_wildcard_or_builtin_name)
1194 << AL;
1195
1196 if (D->hasAttr<NoBuiltinAttr>())
1197 D->dropAttr<NoBuiltinAttr>();
1198 D->addAttr(::new (S.Context)
1199 NoBuiltinAttr(S.Context, AL, Names.data(), Names.size()));
1200}
1201
1202static void handlePassObjectSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1203 if (D->hasAttr<PassObjectSizeAttr>()) {
1204 S.Diag(D->getBeginLoc(), diag::err_attribute_only_once_per_parameter) << AL;
1205 return;
1206 }
1207
1208 Expr *E = AL.getArgAsExpr(Arg: 0);
1209 uint32_t Type;
1210 if (!checkUInt32Argument(S, AI: AL, Expr: E, Val&: Type, /*Idx=*/1))
1211 return;
1212
1213 // pass_object_size's argument is passed in as the second argument of
1214 // __builtin_object_size. So, it has the same constraints as that second
1215 // argument; namely, it must be in the range [0, 3].
1216 if (Type > 3) {
1217 S.Diag(E->getBeginLoc(), diag::err_attribute_argument_out_of_range)
1218 << AL << 0 << 3 << E->getSourceRange();
1219 return;
1220 }
1221
1222 // pass_object_size is only supported on constant pointer parameters; as a
1223 // kindness to users, we allow the parameter to be non-const for declarations.
1224 // At this point, we have no clue if `D` belongs to a function declaration or
1225 // definition, so we defer the constness check until later.
1226 if (!cast<ParmVarDecl>(Val: D)->getType()->isPointerType()) {
1227 S.Diag(D->getBeginLoc(), diag::err_attribute_pointers_only) << AL << 1;
1228 return;
1229 }
1230
1231 D->addAttr(::new (S.Context) PassObjectSizeAttr(S.Context, AL, (int)Type));
1232}
1233
1234static void handleConsumableAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1235 ConsumableAttr::ConsumedState DefaultState;
1236
1237 if (AL.isArgIdent(Arg: 0)) {
1238 IdentifierLoc *IL = AL.getArgAsIdent(Arg: 0);
1239 if (!ConsumableAttr::ConvertStrToConsumedState(IL->Ident->getName(),
1240 DefaultState)) {
1241 S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL
1242 << IL->Ident;
1243 return;
1244 }
1245 } else {
1246 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1247 << AL << AANT_ArgumentIdentifier;
1248 return;
1249 }
1250
1251 D->addAttr(::new (S.Context) ConsumableAttr(S.Context, AL, DefaultState));
1252}
1253
1254static bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD,
1255 const ParsedAttr &AL) {
1256 QualType ThisType = MD->getFunctionObjectParameterType();
1257
1258 if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) {
1259 if (!RD->hasAttr<ConsumableAttr>()) {
1260 S.Diag(AL.getLoc(), diag::warn_attr_on_unconsumable_class) << RD;
1261
1262 return false;
1263 }
1264 }
1265
1266 return true;
1267}
1268
1269static void handleCallableWhenAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1270 if (!AL.checkAtLeastNumArgs(S, Num: 1))
1271 return;
1272
1273 if (!checkForConsumableClass(S, MD: cast<CXXMethodDecl>(Val: D), AL))
1274 return;
1275
1276 SmallVector<CallableWhenAttr::ConsumedState, 3> States;
1277 for (unsigned ArgIndex = 0; ArgIndex < AL.getNumArgs(); ++ArgIndex) {
1278 CallableWhenAttr::ConsumedState CallableState;
1279
1280 StringRef StateString;
1281 SourceLocation Loc;
1282 if (AL.isArgIdent(Arg: ArgIndex)) {
1283 IdentifierLoc *Ident = AL.getArgAsIdent(Arg: ArgIndex);
1284 StateString = Ident->Ident->getName();
1285 Loc = Ident->Loc;
1286 } else {
1287 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: ArgIndex, Str&: StateString, ArgLocation: &Loc))
1288 return;
1289 }
1290
1291 if (!CallableWhenAttr::ConvertStrToConsumedState(StateString,
1292 CallableState)) {
1293 S.Diag(Loc, diag::warn_attribute_type_not_supported) << AL << StateString;
1294 return;
1295 }
1296
1297 States.push_back(CallableState);
1298 }
1299
1300 D->addAttr(::new (S.Context)
1301 CallableWhenAttr(S.Context, AL, States.data(), States.size()));
1302}
1303
1304static void handleParamTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1305 ParamTypestateAttr::ConsumedState ParamState;
1306
1307 if (AL.isArgIdent(Arg: 0)) {
1308 IdentifierLoc *Ident = AL.getArgAsIdent(Arg: 0);
1309 StringRef StateString = Ident->Ident->getName();
1310
1311 if (!ParamTypestateAttr::ConvertStrToConsumedState(StateString,
1312 ParamState)) {
1313 S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported)
1314 << AL << StateString;
1315 return;
1316 }
1317 } else {
1318 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1319 << AL << AANT_ArgumentIdentifier;
1320 return;
1321 }
1322
1323 // FIXME: This check is currently being done in the analysis. It can be
1324 // enabled here only after the parser propagates attributes at
1325 // template specialization definition, not declaration.
1326 //QualType ReturnType = cast<ParmVarDecl>(D)->getType();
1327 //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1328 //
1329 //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1330 // S.Diag(AL.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1331 // ReturnType.getAsString();
1332 // return;
1333 //}
1334
1335 D->addAttr(::new (S.Context) ParamTypestateAttr(S.Context, AL, ParamState));
1336}
1337
1338static void handleReturnTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1339 ReturnTypestateAttr::ConsumedState ReturnState;
1340
1341 if (AL.isArgIdent(Arg: 0)) {
1342 IdentifierLoc *IL = AL.getArgAsIdent(Arg: 0);
1343 if (!ReturnTypestateAttr::ConvertStrToConsumedState(IL->Ident->getName(),
1344 ReturnState)) {
1345 S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL
1346 << IL->Ident;
1347 return;
1348 }
1349 } else {
1350 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1351 << AL << AANT_ArgumentIdentifier;
1352 return;
1353 }
1354
1355 // FIXME: This check is currently being done in the analysis. It can be
1356 // enabled here only after the parser propagates attributes at
1357 // template specialization definition, not declaration.
1358 // QualType ReturnType;
1359 //
1360 // if (const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D)) {
1361 // ReturnType = Param->getType();
1362 //
1363 //} else if (const CXXConstructorDecl *Constructor =
1364 // dyn_cast<CXXConstructorDecl>(D)) {
1365 // ReturnType = Constructor->getFunctionObjectParameterType();
1366 //
1367 //} else {
1368 //
1369 // ReturnType = cast<FunctionDecl>(D)->getCallResultType();
1370 //}
1371 //
1372 // const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1373 //
1374 // if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1375 // S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1376 // ReturnType.getAsString();
1377 // return;
1378 //}
1379
1380 D->addAttr(::new (S.Context) ReturnTypestateAttr(S.Context, AL, ReturnState));
1381}
1382
1383static void handleSetTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1384 if (!checkForConsumableClass(S, MD: cast<CXXMethodDecl>(Val: D), AL))
1385 return;
1386
1387 SetTypestateAttr::ConsumedState NewState;
1388 if (AL.isArgIdent(Arg: 0)) {
1389 IdentifierLoc *Ident = AL.getArgAsIdent(Arg: 0);
1390 StringRef Param = Ident->Ident->getName();
1391 if (!SetTypestateAttr::ConvertStrToConsumedState(Param, NewState)) {
1392 S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) << AL
1393 << Param;
1394 return;
1395 }
1396 } else {
1397 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1398 << AL << AANT_ArgumentIdentifier;
1399 return;
1400 }
1401
1402 D->addAttr(::new (S.Context) SetTypestateAttr(S.Context, AL, NewState));
1403}
1404
1405static void handleTestTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1406 if (!checkForConsumableClass(S, MD: cast<CXXMethodDecl>(Val: D), AL))
1407 return;
1408
1409 TestTypestateAttr::ConsumedState TestState;
1410 if (AL.isArgIdent(Arg: 0)) {
1411 IdentifierLoc *Ident = AL.getArgAsIdent(Arg: 0);
1412 StringRef Param = Ident->Ident->getName();
1413 if (!TestTypestateAttr::ConvertStrToConsumedState(Param, TestState)) {
1414 S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) << AL
1415 << Param;
1416 return;
1417 }
1418 } else {
1419 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1420 << AL << AANT_ArgumentIdentifier;
1421 return;
1422 }
1423
1424 D->addAttr(::new (S.Context) TestTypestateAttr(S.Context, AL, TestState));
1425}
1426
1427static void handleExtVectorTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1428 // Remember this typedef decl, we will need it later for diagnostics.
1429 S.ExtVectorDecls.push_back(LocalValue: cast<TypedefNameDecl>(Val: D));
1430}
1431
1432static void handlePackedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1433 if (auto *TD = dyn_cast<TagDecl>(Val: D))
1434 TD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
1435 else if (auto *FD = dyn_cast<FieldDecl>(Val: D)) {
1436 bool BitfieldByteAligned = (!FD->getType()->isDependentType() &&
1437 !FD->getType()->isIncompleteType() &&
1438 FD->isBitField() &&
1439 S.Context.getTypeAlign(FD->getType()) <= 8);
1440
1441 if (S.getASTContext().getTargetInfo().getTriple().isPS()) {
1442 if (BitfieldByteAligned)
1443 // The PS4/PS5 targets need to maintain ABI backwards compatibility.
1444 S.Diag(AL.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
1445 << AL << FD->getType();
1446 else
1447 FD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
1448 } else {
1449 // Report warning about changed offset in the newer compiler versions.
1450 if (BitfieldByteAligned)
1451 S.Diag(AL.getLoc(), diag::warn_attribute_packed_for_bitfield);
1452
1453 FD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
1454 }
1455
1456 } else
1457 S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
1458}
1459
1460static void handlePreferredName(Sema &S, Decl *D, const ParsedAttr &AL) {
1461 auto *RD = cast<CXXRecordDecl>(Val: D);
1462 ClassTemplateDecl *CTD = RD->getDescribedClassTemplate();
1463 assert(CTD && "attribute does not appertain to this declaration");
1464
1465 ParsedType PT = AL.getTypeArg();
1466 TypeSourceInfo *TSI = nullptr;
1467 QualType T = S.GetTypeFromParser(Ty: PT, TInfo: &TSI);
1468 if (!TSI)
1469 TSI = S.Context.getTrivialTypeSourceInfo(T, Loc: AL.getLoc());
1470
1471 if (!T.hasQualifiers() && T->isTypedefNameType()) {
1472 // Find the template name, if this type names a template specialization.
1473 const TemplateDecl *Template = nullptr;
1474 if (const auto *CTSD = dyn_cast_if_present<ClassTemplateSpecializationDecl>(
1475 Val: T->getAsCXXRecordDecl())) {
1476 Template = CTSD->getSpecializedTemplate();
1477 } else if (const auto *TST = T->getAs<TemplateSpecializationType>()) {
1478 while (TST && TST->isTypeAlias())
1479 TST = TST->getAliasedType()->getAs<TemplateSpecializationType>();
1480 if (TST)
1481 Template = TST->getTemplateName().getAsTemplateDecl();
1482 }
1483
1484 if (Template && declaresSameEntity(Template, CTD)) {
1485 D->addAttr(::new (S.Context) PreferredNameAttr(S.Context, AL, TSI));
1486 return;
1487 }
1488 }
1489
1490 S.Diag(AL.getLoc(), diag::err_attribute_preferred_name_arg_invalid)
1491 << T << CTD;
1492 if (const auto *TT = T->getAs<TypedefType>())
1493 S.Diag(TT->getDecl()->getLocation(), diag::note_entity_declared_at)
1494 << TT->getDecl();
1495}
1496
1497static bool checkIBOutletCommon(Sema &S, Decl *D, const ParsedAttr &AL) {
1498 // The IBOutlet/IBOutletCollection attributes only apply to instance
1499 // variables or properties of Objective-C classes. The outlet must also
1500 // have an object reference type.
1501 if (const auto *VD = dyn_cast<ObjCIvarDecl>(Val: D)) {
1502 if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
1503 S.Diag(AL.getLoc(), diag::warn_iboutlet_object_type)
1504 << AL << VD->getType() << 0;
1505 return false;
1506 }
1507 }
1508 else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(Val: D)) {
1509 if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
1510 S.Diag(AL.getLoc(), diag::warn_iboutlet_object_type)
1511 << AL << PD->getType() << 1;
1512 return false;
1513 }
1514 }
1515 else {
1516 S.Diag(AL.getLoc(), diag::warn_attribute_iboutlet) << AL;
1517 return false;
1518 }
1519
1520 return true;
1521}
1522
1523static void handleIBOutlet(Sema &S, Decl *D, const ParsedAttr &AL) {
1524 if (!checkIBOutletCommon(S, D, AL))
1525 return;
1526
1527 D->addAttr(::new (S.Context) IBOutletAttr(S.Context, AL));
1528}
1529
1530static void handleIBOutletCollection(Sema &S, Decl *D, const ParsedAttr &AL) {
1531
1532 // The iboutletcollection attribute can have zero or one arguments.
1533 if (AL.getNumArgs() > 1) {
1534 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
1535 return;
1536 }
1537
1538 if (!checkIBOutletCommon(S, D, AL))
1539 return;
1540
1541 ParsedType PT;
1542
1543 if (AL.hasParsedType())
1544 PT = AL.getTypeArg();
1545 else {
1546 PT = S.getTypeName(II: S.Context.Idents.get(Name: "NSObject"), NameLoc: AL.getLoc(),
1547 S: S.getScopeForContext(Ctx: D->getDeclContext()->getParent()));
1548 if (!PT) {
1549 S.Diag(AL.getLoc(), diag::err_iboutletcollection_type) << "NSObject";
1550 return;
1551 }
1552 }
1553
1554 TypeSourceInfo *QTLoc = nullptr;
1555 QualType QT = S.GetTypeFromParser(Ty: PT, TInfo: &QTLoc);
1556 if (!QTLoc)
1557 QTLoc = S.Context.getTrivialTypeSourceInfo(T: QT, Loc: AL.getLoc());
1558
1559 // Diagnose use of non-object type in iboutletcollection attribute.
1560 // FIXME. Gnu attribute extension ignores use of builtin types in
1561 // attributes. So, __attribute__((iboutletcollection(char))) will be
1562 // treated as __attribute__((iboutletcollection())).
1563 if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {
1564 S.Diag(AL.getLoc(),
1565 QT->isBuiltinType() ? diag::err_iboutletcollection_builtintype
1566 : diag::err_iboutletcollection_type) << QT;
1567 return;
1568 }
1569
1570 D->addAttr(::new (S.Context) IBOutletCollectionAttr(S.Context, AL, QTLoc));
1571}
1572
1573bool Sema::isValidPointerAttrType(QualType T, bool RefOkay) {
1574 if (RefOkay) {
1575 if (T->isReferenceType())
1576 return true;
1577 } else {
1578 T = T.getNonReferenceType();
1579 }
1580
1581 // The nonnull attribute, and other similar attributes, can be applied to a
1582 // transparent union that contains a pointer type.
1583 if (const RecordType *UT = T->getAsUnionType()) {
1584 if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
1585 RecordDecl *UD = UT->getDecl();
1586 for (const auto *I : UD->fields()) {
1587 QualType QT = I->getType();
1588 if (QT->isAnyPointerType() || QT->isBlockPointerType())
1589 return true;
1590 }
1591 }
1592 }
1593
1594 return T->isAnyPointerType() || T->isBlockPointerType();
1595}
1596
1597static bool attrNonNullArgCheck(Sema &S, QualType T, const ParsedAttr &AL,
1598 SourceRange AttrParmRange,
1599 SourceRange TypeRange,
1600 bool isReturnValue = false) {
1601 if (!S.isValidPointerAttrType(T)) {
1602 if (isReturnValue)
1603 S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only)
1604 << AL << AttrParmRange << TypeRange;
1605 else
1606 S.Diag(AL.getLoc(), diag::warn_attribute_pointers_only)
1607 << AL << AttrParmRange << TypeRange << 0;
1608 return false;
1609 }
1610 return true;
1611}
1612
1613static void handleNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1614 SmallVector<ParamIdx, 8> NonNullArgs;
1615 for (unsigned I = 0; I < AL.getNumArgs(); ++I) {
1616 Expr *Ex = AL.getArgAsExpr(Arg: I);
1617 ParamIdx Idx;
1618 if (!checkFunctionOrMethodParameterIndex(S, D, AI: AL, AttrArgNum: I + 1, IdxExpr: Ex, Idx))
1619 return;
1620
1621 // Is the function argument a pointer type?
1622 if (Idx.getASTIndex() < getFunctionOrMethodNumParams(D) &&
1623 !attrNonNullArgCheck(
1624 S, getFunctionOrMethodParamType(D, Idx: Idx.getASTIndex()), AL,
1625 Ex->getSourceRange(),
1626 getFunctionOrMethodParamRange(D, Idx: Idx.getASTIndex())))
1627 continue;
1628
1629 NonNullArgs.push_back(Elt: Idx);
1630 }
1631
1632 // If no arguments were specified to __attribute__((nonnull)) then all pointer
1633 // arguments have a nonnull attribute; warn if there aren't any. Skip this
1634 // check if the attribute came from a macro expansion or a template
1635 // instantiation.
1636 if (NonNullArgs.empty() && AL.getLoc().isFileID() &&
1637 !S.inTemplateInstantiation()) {
1638 bool AnyPointers = isFunctionOrMethodVariadic(D);
1639 for (unsigned I = 0, E = getFunctionOrMethodNumParams(D);
1640 I != E && !AnyPointers; ++I) {
1641 QualType T = getFunctionOrMethodParamType(D, Idx: I);
1642 if (T->isDependentType() || S.isValidPointerAttrType(T))
1643 AnyPointers = true;
1644 }
1645
1646 if (!AnyPointers)
1647 S.Diag(AL.getLoc(), diag::warn_attribute_nonnull_no_pointers);
1648 }
1649
1650 ParamIdx *Start = NonNullArgs.data();
1651 unsigned Size = NonNullArgs.size();
1652 llvm::array_pod_sort(Start, End: Start + Size);
1653 D->addAttr(::new (S.Context) NonNullAttr(S.Context, AL, Start, Size));
1654}
1655
1656static void handleNonNullAttrParameter(Sema &S, ParmVarDecl *D,
1657 const ParsedAttr &AL) {
1658 if (AL.getNumArgs() > 0) {
1659 if (D->getFunctionType()) {
1660 handleNonNullAttr(S, D, AL);
1661 } else {
1662 S.Diag(AL.getLoc(), diag::warn_attribute_nonnull_parm_no_args)
1663 << D->getSourceRange();
1664 }
1665 return;
1666 }
1667
1668 // Is the argument a pointer type?
1669 if (!attrNonNullArgCheck(S, D->getType(), AL, SourceRange(),
1670 D->getSourceRange()))
1671 return;
1672
1673 D->addAttr(::new (S.Context) NonNullAttr(S.Context, AL, nullptr, 0));
1674}
1675
1676static void handleReturnsNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1677 QualType ResultType = getFunctionOrMethodResultType(D);
1678 SourceRange SR = getFunctionOrMethodResultSourceRange(D);
1679 if (!attrNonNullArgCheck(S, T: ResultType, AL, AttrParmRange: SourceRange(), TypeRange: SR,
1680 /* isReturnValue */ true))
1681 return;
1682
1683 D->addAttr(::new (S.Context) ReturnsNonNullAttr(S.Context, AL));
1684}
1685
1686static void handleNoEscapeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1687 if (D->isInvalidDecl())
1688 return;
1689
1690 // noescape only applies to pointer types.
1691 QualType T = cast<ParmVarDecl>(Val: D)->getType();
1692 if (!S.isValidPointerAttrType(T, /* RefOkay */ true)) {
1693 S.Diag(AL.getLoc(), diag::warn_attribute_pointers_only)
1694 << AL << AL.getRange() << 0;
1695 return;
1696 }
1697
1698 D->addAttr(::new (S.Context) NoEscapeAttr(S.Context, AL));
1699}
1700
1701static void handleAssumeAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1702 Expr *E = AL.getArgAsExpr(Arg: 0),
1703 *OE = AL.getNumArgs() > 1 ? AL.getArgAsExpr(Arg: 1) : nullptr;
1704 S.AddAssumeAlignedAttr(D, CI: AL, E, OE);
1705}
1706
1707static void handleAllocAlignAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1708 S.AddAllocAlignAttr(D, CI: AL, ParamExpr: AL.getArgAsExpr(Arg: 0));
1709}
1710
1711void Sema::AddAssumeAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
1712 Expr *OE) {
1713 QualType ResultType = getFunctionOrMethodResultType(D);
1714 SourceRange SR = getFunctionOrMethodResultSourceRange(D);
1715
1716 AssumeAlignedAttr TmpAttr(Context, CI, E, OE);
1717 SourceLocation AttrLoc = TmpAttr.getLocation();
1718
1719 if (!isValidPointerAttrType(T: ResultType, /* RefOkay */ true)) {
1720 Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)
1721 << &TmpAttr << TmpAttr.getRange() << SR;
1722 return;
1723 }
1724
1725 if (!E->isValueDependent()) {
1726 std::optional<llvm::APSInt> I = llvm::APSInt(64);
1727 if (!(I = E->getIntegerConstantExpr(Ctx: Context))) {
1728 if (OE)
1729 Diag(AttrLoc, diag::err_attribute_argument_n_type)
1730 << &TmpAttr << 1 << AANT_ArgumentIntegerConstant
1731 << E->getSourceRange();
1732 else
1733 Diag(AttrLoc, diag::err_attribute_argument_type)
1734 << &TmpAttr << AANT_ArgumentIntegerConstant
1735 << E->getSourceRange();
1736 return;
1737 }
1738
1739 if (!I->isPowerOf2()) {
1740 Diag(AttrLoc, diag::err_alignment_not_power_of_two)
1741 << E->getSourceRange();
1742 return;
1743 }
1744
1745 if (*I > Sema::MaximumAlignment)
1746 Diag(CI.getLoc(), diag::warn_assume_aligned_too_great)
1747 << CI.getRange() << Sema::MaximumAlignment;
1748 }
1749
1750 if (OE && !OE->isValueDependent() && !OE->isIntegerConstantExpr(Ctx: Context)) {
1751 Diag(AttrLoc, diag::err_attribute_argument_n_type)
1752 << &TmpAttr << 2 << AANT_ArgumentIntegerConstant
1753 << OE->getSourceRange();
1754 return;
1755 }
1756
1757 D->addAttr(::new (Context) AssumeAlignedAttr(Context, CI, E, OE));
1758}
1759
1760void Sema::AddAllocAlignAttr(Decl *D, const AttributeCommonInfo &CI,
1761 Expr *ParamExpr) {
1762 QualType ResultType = getFunctionOrMethodResultType(D);
1763
1764 AllocAlignAttr TmpAttr(Context, CI, ParamIdx());
1765 SourceLocation AttrLoc = CI.getLoc();
1766
1767 if (!ResultType->isDependentType() &&
1768 !isValidPointerAttrType(T: ResultType, /* RefOkay */ true)) {
1769 Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)
1770 << &TmpAttr << CI.getRange() << getFunctionOrMethodResultSourceRange(D);
1771 return;
1772 }
1773
1774 ParamIdx Idx;
1775 const auto *FuncDecl = cast<FunctionDecl>(Val: D);
1776 if (!checkFunctionOrMethodParameterIndex(*this, FuncDecl, TmpAttr,
1777 /*AttrArgNum=*/1, ParamExpr, Idx))
1778 return;
1779
1780 QualType Ty = getFunctionOrMethodParamType(D, Idx: Idx.getASTIndex());
1781 if (!Ty->isDependentType() && !Ty->isIntegralType(Ctx: Context) &&
1782 !Ty->isAlignValT()) {
1783 Diag(ParamExpr->getBeginLoc(), diag::err_attribute_integers_only)
1784 << &TmpAttr
1785 << FuncDecl->getParamDecl(Idx.getASTIndex())->getSourceRange();
1786 return;
1787 }
1788
1789 D->addAttr(::new (Context) AllocAlignAttr(Context, CI, Idx));
1790}
1791
1792/// Check if \p AssumptionStr is a known assumption and warn if not.
1793static void checkOMPAssumeAttr(Sema &S, SourceLocation Loc,
1794 StringRef AssumptionStr) {
1795 if (llvm::KnownAssumptionStrings.count(Key: AssumptionStr))
1796 return;
1797
1798 unsigned BestEditDistance = 3;
1799 StringRef Suggestion;
1800 for (const auto &KnownAssumptionIt : llvm::KnownAssumptionStrings) {
1801 unsigned EditDistance =
1802 AssumptionStr.edit_distance(Other: KnownAssumptionIt.getKey());
1803 if (EditDistance < BestEditDistance) {
1804 Suggestion = KnownAssumptionIt.getKey();
1805 BestEditDistance = EditDistance;
1806 }
1807 }
1808
1809 if (!Suggestion.empty())
1810 S.Diag(Loc, diag::warn_omp_assume_attribute_string_unknown_suggested)
1811 << AssumptionStr << Suggestion;
1812 else
1813 S.Diag(Loc, diag::warn_omp_assume_attribute_string_unknown)
1814 << AssumptionStr;
1815}
1816
1817static void handleOMPAssumeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1818 // Handle the case where the attribute has a text message.
1819 StringRef Str;
1820 SourceLocation AttrStrLoc;
1821 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str, ArgLocation: &AttrStrLoc))
1822 return;
1823
1824 checkOMPAssumeAttr(S, Loc: AttrStrLoc, AssumptionStr: Str);
1825
1826 D->addAttr(::new (S.Context) OMPAssumeAttr(S.Context, AL, Str));
1827}
1828
1829/// Normalize the attribute, __foo__ becomes foo.
1830/// Returns true if normalization was applied.
1831static bool normalizeName(StringRef &AttrName) {
1832 if (AttrName.size() > 4 && AttrName.starts_with(Prefix: "__") &&
1833 AttrName.ends_with(Suffix: "__")) {
1834 AttrName = AttrName.drop_front(N: 2).drop_back(N: 2);
1835 return true;
1836 }
1837 return false;
1838}
1839
1840static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1841 // This attribute must be applied to a function declaration. The first
1842 // argument to the attribute must be an identifier, the name of the resource,
1843 // for example: malloc. The following arguments must be argument indexes, the
1844 // arguments must be of integer type for Returns, otherwise of pointer type.
1845 // The difference between Holds and Takes is that a pointer may still be used
1846 // after being held. free() should be __attribute((ownership_takes)), whereas
1847 // a list append function may well be __attribute((ownership_holds)).
1848
1849 if (!AL.isArgIdent(Arg: 0)) {
1850 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
1851 << AL << 1 << AANT_ArgumentIdentifier;
1852 return;
1853 }
1854
1855 // Figure out our Kind.
1856 OwnershipAttr::OwnershipKind K =
1857 OwnershipAttr(S.Context, AL, nullptr, nullptr, 0).getOwnKind();
1858
1859 // Check arguments.
1860 switch (K) {
1861 case OwnershipAttr::Takes:
1862 case OwnershipAttr::Holds:
1863 if (AL.getNumArgs() < 2) {
1864 S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) << AL << 2;
1865 return;
1866 }
1867 break;
1868 case OwnershipAttr::Returns:
1869 if (AL.getNumArgs() > 2) {
1870 S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 1;
1871 return;
1872 }
1873 break;
1874 }
1875
1876 IdentifierInfo *Module = AL.getArgAsIdent(Arg: 0)->Ident;
1877
1878 StringRef ModuleName = Module->getName();
1879 if (normalizeName(AttrName&: ModuleName)) {
1880 Module = &S.PP.getIdentifierTable().get(Name: ModuleName);
1881 }
1882
1883 SmallVector<ParamIdx, 8> OwnershipArgs;
1884 for (unsigned i = 1; i < AL.getNumArgs(); ++i) {
1885 Expr *Ex = AL.getArgAsExpr(Arg: i);
1886 ParamIdx Idx;
1887 if (!checkFunctionOrMethodParameterIndex(S, D, AI: AL, AttrArgNum: i, IdxExpr: Ex, Idx))
1888 return;
1889
1890 // Is the function argument a pointer type?
1891 QualType T = getFunctionOrMethodParamType(D, Idx: Idx.getASTIndex());
1892 int Err = -1; // No error
1893 switch (K) {
1894 case OwnershipAttr::Takes:
1895 case OwnershipAttr::Holds:
1896 if (!T->isAnyPointerType() && !T->isBlockPointerType())
1897 Err = 0;
1898 break;
1899 case OwnershipAttr::Returns:
1900 if (!T->isIntegerType())
1901 Err = 1;
1902 break;
1903 }
1904 if (-1 != Err) {
1905 S.Diag(AL.getLoc(), diag::err_ownership_type) << AL << Err
1906 << Ex->getSourceRange();
1907 return;
1908 }
1909
1910 // Check we don't have a conflict with another ownership attribute.
1911 for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
1912 // Cannot have two ownership attributes of different kinds for the same
1913 // index.
1914 if (I->getOwnKind() != K && llvm::is_contained(I->args(), Idx)) {
1915 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
1916 << AL << I
1917 << (AL.isRegularKeywordAttribute() ||
1918 I->isRegularKeywordAttribute());
1919 return;
1920 } else if (K == OwnershipAttr::Returns &&
1921 I->getOwnKind() == OwnershipAttr::Returns) {
1922 // A returns attribute conflicts with any other returns attribute using
1923 // a different index.
1924 if (!llvm::is_contained(I->args(), Idx)) {
1925 S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch)
1926 << I->args_begin()->getSourceIndex();
1927 if (I->args_size())
1928 S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch)
1929 << Idx.getSourceIndex() << Ex->getSourceRange();
1930 return;
1931 }
1932 }
1933 }
1934 OwnershipArgs.push_back(Elt: Idx);
1935 }
1936
1937 ParamIdx *Start = OwnershipArgs.data();
1938 unsigned Size = OwnershipArgs.size();
1939 llvm::array_pod_sort(Start, End: Start + Size);
1940 D->addAttr(::new (S.Context)
1941 OwnershipAttr(S.Context, AL, Module, Start, Size));
1942}
1943
1944static void handleWeakRefAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1945 // Check the attribute arguments.
1946 if (AL.getNumArgs() > 1) {
1947 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
1948 return;
1949 }
1950
1951 // gcc rejects
1952 // class c {
1953 // static int a __attribute__((weakref ("v2")));
1954 // static int b() __attribute__((weakref ("f3")));
1955 // };
1956 // and ignores the attributes of
1957 // void f(void) {
1958 // static int a __attribute__((weakref ("v2")));
1959 // }
1960 // we reject them
1961 const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
1962 if (!Ctx->isFileContext()) {
1963 S.Diag(AL.getLoc(), diag::err_attribute_weakref_not_global_context)
1964 << cast<NamedDecl>(D);
1965 return;
1966 }
1967
1968 // The GCC manual says
1969 //
1970 // At present, a declaration to which `weakref' is attached can only
1971 // be `static'.
1972 //
1973 // It also says
1974 //
1975 // Without a TARGET,
1976 // given as an argument to `weakref' or to `alias', `weakref' is
1977 // equivalent to `weak'.
1978 //
1979 // gcc 4.4.1 will accept
1980 // int a7 __attribute__((weakref));
1981 // as
1982 // int a7 __attribute__((weak));
1983 // This looks like a bug in gcc. We reject that for now. We should revisit
1984 // it if this behaviour is actually used.
1985
1986 // GCC rejects
1987 // static ((alias ("y"), weakref)).
1988 // Should we? How to check that weakref is before or after alias?
1989
1990 // FIXME: it would be good for us to keep the WeakRefAttr as-written instead
1991 // of transforming it into an AliasAttr. The WeakRefAttr never uses the
1992 // StringRef parameter it was given anyway.
1993 StringRef Str;
1994 if (AL.getNumArgs() && S.checkStringLiteralArgumentAttr(AL, 0, Str))
1995 // GCC will accept anything as the argument of weakref. Should we
1996 // check for an existing decl?
1997 D->addAttr(::new (S.Context) AliasAttr(S.Context, AL, Str));
1998
1999 D->addAttr(::new (S.Context) WeakRefAttr(S.Context, AL));
2000}
2001
2002// Mark alias/ifunc target as used. Due to name mangling, we look up the
2003// demangled name ignoring parameters (not supported by microsoftDemangle
2004// https://github.com/llvm/llvm-project/issues/88825). This should handle the
2005// majority of use cases while leaving namespace scope names unmarked.
2006static void markUsedForAliasOrIfunc(Sema &S, Decl *D, const ParsedAttr &AL,
2007 StringRef Str) {
2008 std::unique_ptr<char, llvm::FreeDeleter> Demangled;
2009 if (S.getASTContext().getCXXABIKind() != TargetCXXABI::Microsoft)
2010 Demangled.reset(p: llvm::itaniumDemangle(mangled_name: Str, /*ParseParams=*/false));
2011 std::unique_ptr<MangleContext> MC(S.Context.createMangleContext());
2012 SmallString<256> Name;
2013
2014 const DeclarationNameInfo Target(
2015 &S.Context.Idents.get(Name: Demangled ? Demangled.get() : Str), AL.getLoc());
2016 LookupResult LR(S, Target, Sema::LookupOrdinaryName);
2017 if (S.LookupName(R&: LR, S: S.TUScope)) {
2018 for (NamedDecl *ND : LR) {
2019 if (!isa<FunctionDecl>(Val: ND) && !isa<VarDecl>(Val: ND))
2020 continue;
2021 if (MC->shouldMangleDeclName(D: ND)) {
2022 llvm::raw_svector_ostream Out(Name);
2023 Name.clear();
2024 MC->mangleName(GD: GlobalDecl(ND), Out);
2025 } else {
2026 Name = ND->getIdentifier()->getName();
2027 }
2028 if (Name == Str)
2029 ND->markUsed(S.Context);
2030 }
2031 }
2032}
2033
2034static void handleIFuncAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2035 StringRef Str;
2036 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str))
2037 return;
2038
2039 // Aliases should be on declarations, not definitions.
2040 const auto *FD = cast<FunctionDecl>(Val: D);
2041 if (FD->isThisDeclarationADefinition()) {
2042 S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 1;
2043 return;
2044 }
2045
2046 markUsedForAliasOrIfunc(S, D, AL, Str);
2047 D->addAttr(::new (S.Context) IFuncAttr(S.Context, AL, Str));
2048}
2049
2050static void handleAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2051 StringRef Str;
2052 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str))
2053 return;
2054
2055 if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
2056 S.Diag(AL.getLoc(), diag::err_alias_not_supported_on_darwin);
2057 return;
2058 }
2059
2060 if (S.Context.getTargetInfo().getTriple().isNVPTX()) {
2061 CudaVersion Version =
2062 ToCudaVersion(S.Context.getTargetInfo().getSDKVersion());
2063 if (Version != CudaVersion::UNKNOWN && Version < CudaVersion::CUDA_100)
2064 S.Diag(AL.getLoc(), diag::err_alias_not_supported_on_nvptx);
2065 }
2066
2067 // Aliases should be on declarations, not definitions.
2068 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
2069 if (FD->isThisDeclarationADefinition()) {
2070 S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 0;
2071 return;
2072 }
2073 } else {
2074 const auto *VD = cast<VarDecl>(Val: D);
2075 if (VD->isThisDeclarationADefinition() && VD->isExternallyVisible()) {
2076 S.Diag(AL.getLoc(), diag::err_alias_is_definition) << VD << 0;
2077 return;
2078 }
2079 }
2080
2081 markUsedForAliasOrIfunc(S, D, AL, Str);
2082 D->addAttr(::new (S.Context) AliasAttr(S.Context, AL, Str));
2083}
2084
2085static void handleTLSModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2086 StringRef Model;
2087 SourceLocation LiteralLoc;
2088 // Check that it is a string.
2089 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: Model, ArgLocation: &LiteralLoc))
2090 return;
2091
2092 // Check that the value.
2093 if (Model != "global-dynamic" && Model != "local-dynamic"
2094 && Model != "initial-exec" && Model != "local-exec") {
2095 S.Diag(LiteralLoc, diag::err_attr_tlsmodel_arg);
2096 return;
2097 }
2098
2099 D->addAttr(::new (S.Context) TLSModelAttr(S.Context, AL, Model));
2100}
2101
2102static void handleRestrictAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2103 QualType ResultType = getFunctionOrMethodResultType(D);
2104 if (ResultType->isAnyPointerType() || ResultType->isBlockPointerType()) {
2105 D->addAttr(::new (S.Context) RestrictAttr(S.Context, AL));
2106 return;
2107 }
2108
2109 S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only)
2110 << AL << getFunctionOrMethodResultSourceRange(D);
2111}
2112
2113static void handleCPUSpecificAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2114 // Ensure we don't combine these with themselves, since that causes some
2115 // confusing behavior.
2116 if (AL.getParsedKind() == ParsedAttr::AT_CPUDispatch) {
2117 if (checkAttrMutualExclusion<CPUSpecificAttr>(S, D, AL))
2118 return;
2119
2120 if (const auto *Other = D->getAttr<CPUDispatchAttr>()) {
2121 S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL;
2122 S.Diag(Other->getLocation(), diag::note_conflicting_attribute);
2123 return;
2124 }
2125 } else if (AL.getParsedKind() == ParsedAttr::AT_CPUSpecific) {
2126 if (checkAttrMutualExclusion<CPUDispatchAttr>(S, D, AL))
2127 return;
2128
2129 if (const auto *Other = D->getAttr<CPUSpecificAttr>()) {
2130 S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL;
2131 S.Diag(Other->getLocation(), diag::note_conflicting_attribute);
2132 return;
2133 }
2134 }
2135
2136 FunctionDecl *FD = cast<FunctionDecl>(Val: D);
2137
2138 if (const auto *MD = dyn_cast<CXXMethodDecl>(Val: D)) {
2139 if (MD->getParent()->isLambda()) {
2140 S.Diag(AL.getLoc(), diag::err_attribute_dll_lambda) << AL;
2141 return;
2142 }
2143 }
2144
2145 if (!AL.checkAtLeastNumArgs(S, Num: 1))
2146 return;
2147
2148 SmallVector<IdentifierInfo *, 8> CPUs;
2149 for (unsigned ArgNo = 0; ArgNo < getNumAttributeArgs(AL); ++ArgNo) {
2150 if (!AL.isArgIdent(Arg: ArgNo)) {
2151 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
2152 << AL << AANT_ArgumentIdentifier;
2153 return;
2154 }
2155
2156 IdentifierLoc *CPUArg = AL.getArgAsIdent(Arg: ArgNo);
2157 StringRef CPUName = CPUArg->Ident->getName().trim();
2158
2159 if (!S.Context.getTargetInfo().validateCPUSpecificCPUDispatch(Name: CPUName)) {
2160 S.Diag(CPUArg->Loc, diag::err_invalid_cpu_specific_dispatch_value)
2161 << CPUName << (AL.getKind() == ParsedAttr::AT_CPUDispatch);
2162 return;
2163 }
2164
2165 const TargetInfo &Target = S.Context.getTargetInfo();
2166 if (llvm::any_of(Range&: CPUs, P: [CPUName, &Target](const IdentifierInfo *Cur) {
2167 return Target.CPUSpecificManglingCharacter(Name: CPUName) ==
2168 Target.CPUSpecificManglingCharacter(Name: Cur->getName());
2169 })) {
2170 S.Diag(AL.getLoc(), diag::warn_multiversion_duplicate_entries);
2171 return;
2172 }
2173 CPUs.push_back(Elt: CPUArg->Ident);
2174 }
2175
2176 FD->setIsMultiVersion(true);
2177 if (AL.getKind() == ParsedAttr::AT_CPUSpecific)
2178 D->addAttr(::new (S.Context)
2179 CPUSpecificAttr(S.Context, AL, CPUs.data(), CPUs.size()));
2180 else
2181 D->addAttr(::new (S.Context)
2182 CPUDispatchAttr(S.Context, AL, CPUs.data(), CPUs.size()));
2183}
2184
2185static void handleCommonAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2186 if (S.LangOpts.CPlusPlus) {
2187 S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)
2188 << AL << AttributeLangSupport::Cpp;
2189 return;
2190 }
2191
2192 D->addAttr(::new (S.Context) CommonAttr(S.Context, AL));
2193}
2194
2195static void handleCmseNSEntryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2196 if (S.LangOpts.CPlusPlus && !D->getDeclContext()->isExternCContext()) {
2197 S.Diag(AL.getLoc(), diag::err_attribute_not_clinkage) << AL;
2198 return;
2199 }
2200
2201 const auto *FD = cast<FunctionDecl>(Val: D);
2202 if (!FD->isExternallyVisible()) {
2203 S.Diag(AL.getLoc(), diag::warn_attribute_cmse_entry_static);
2204 return;
2205 }
2206
2207 D->addAttr(::new (S.Context) CmseNSEntryAttr(S.Context, AL));
2208}
2209
2210static void handleNakedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2211 if (AL.isDeclspecAttribute()) {
2212 const auto &Triple = S.getASTContext().getTargetInfo().getTriple();
2213 const auto &Arch = Triple.getArch();
2214 if (Arch != llvm::Triple::x86 &&
2215 (Arch != llvm::Triple::arm && Arch != llvm::Triple::thumb)) {
2216 S.Diag(AL.getLoc(), diag::err_attribute_not_supported_on_arch)
2217 << AL << Triple.getArchName();
2218 return;
2219 }
2220
2221 // This form is not allowed to be written on a member function (static or
2222 // nonstatic) when in Microsoft compatibility mode.
2223 if (S.getLangOpts().MSVCCompat && isa<CXXMethodDecl>(Val: D)) {
2224 S.Diag(AL.getLoc(), diag::err_attribute_wrong_decl_type_str)
2225 << AL << AL.isRegularKeywordAttribute() << "non-member functions";
2226 return;
2227 }
2228 }
2229
2230 D->addAttr(::new (S.Context) NakedAttr(S.Context, AL));
2231}
2232
2233static void handleNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
2234 if (hasDeclarator(D)) return;
2235
2236 if (!isa<ObjCMethodDecl>(Val: D)) {
2237 S.Diag(Attrs.getLoc(), diag::warn_attribute_wrong_decl_type)
2238 << Attrs << Attrs.isRegularKeywordAttribute()
2239 << ExpectedFunctionOrMethod;
2240 return;
2241 }
2242
2243 D->addAttr(::new (S.Context) NoReturnAttr(S.Context, Attrs));
2244}
2245
2246static void handleStandardNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &A) {
2247 // The [[_Noreturn]] spelling is deprecated in C23, so if that was used,
2248 // issue an appropriate diagnostic. However, don't issue a diagnostic if the
2249 // attribute name comes from a macro expansion. We don't want to punish users
2250 // who write [[noreturn]] after including <stdnoreturn.h> (where 'noreturn'
2251 // is defined as a macro which expands to '_Noreturn').
2252 if (!S.getLangOpts().CPlusPlus &&
2253 A.getSemanticSpelling() == CXX11NoReturnAttr::C23_Noreturn &&
2254 !(A.getLoc().isMacroID() &&
2255 S.getSourceManager().isInSystemMacro(A.getLoc())))
2256 S.Diag(A.getLoc(), diag::warn_deprecated_noreturn_spelling) << A.getRange();
2257
2258 D->addAttr(::new (S.Context) CXX11NoReturnAttr(S.Context, A));
2259}
2260
2261static void handleNoCfCheckAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
2262 if (!S.getLangOpts().CFProtectionBranch)
2263 S.Diag(Attrs.getLoc(), diag::warn_nocf_check_attribute_ignored);
2264 else
2265 handleSimpleAttribute<AnyX86NoCfCheckAttr>(S, D, Attrs);
2266}
2267
2268bool Sema::CheckAttrNoArgs(const ParsedAttr &Attrs) {
2269 if (!Attrs.checkExactlyNumArgs(S&: *this, Num: 0)) {
2270 Attrs.setInvalid();
2271 return true;
2272 }
2273
2274 return false;
2275}
2276
2277bool Sema::CheckAttrTarget(const ParsedAttr &AL) {
2278 // Check whether the attribute is valid on the current target.
2279 if (!AL.existsInTarget(Target: Context.getTargetInfo())) {
2280 Diag(AL.getLoc(), AL.isRegularKeywordAttribute()
2281 ? diag::err_keyword_not_supported_on_target
2282 : diag::warn_unknown_attribute_ignored)
2283 << AL << AL.getRange();
2284 AL.setInvalid();
2285 return true;
2286 }
2287
2288 return false;
2289}
2290
2291static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2292
2293 // The checking path for 'noreturn' and 'analyzer_noreturn' are different
2294 // because 'analyzer_noreturn' does not impact the type.
2295 if (!isFunctionOrMethodOrBlock(D)) {
2296 ValueDecl *VD = dyn_cast<ValueDecl>(Val: D);
2297 if (!VD || (!VD->getType()->isBlockPointerType() &&
2298 !VD->getType()->isFunctionPointerType())) {
2299 S.Diag(AL.getLoc(), AL.isStandardAttributeSyntax()
2300 ? diag::err_attribute_wrong_decl_type
2301 : diag::warn_attribute_wrong_decl_type)
2302 << AL << AL.isRegularKeywordAttribute()
2303 << ExpectedFunctionMethodOrBlock;
2304 return;
2305 }
2306 }
2307
2308 D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(S.Context, AL));
2309}
2310
2311// PS3 PPU-specific.
2312static void handleVecReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2313 /*
2314 Returning a Vector Class in Registers
2315
2316 According to the PPU ABI specifications, a class with a single member of
2317 vector type is returned in memory when used as the return value of a
2318 function.
2319 This results in inefficient code when implementing vector classes. To return
2320 the value in a single vector register, add the vecreturn attribute to the
2321 class definition. This attribute is also applicable to struct types.
2322
2323 Example:
2324
2325 struct Vector
2326 {
2327 __vector float xyzw;
2328 } __attribute__((vecreturn));
2329
2330 Vector Add(Vector lhs, Vector rhs)
2331 {
2332 Vector result;
2333 result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
2334 return result; // This will be returned in a register
2335 }
2336 */
2337 if (VecReturnAttr *A = D->getAttr<VecReturnAttr>()) {
2338 S.Diag(AL.getLoc(), diag::err_repeat_attribute) << A;
2339 return;
2340 }
2341
2342 const auto *R = cast<RecordDecl>(Val: D);
2343 int count = 0;
2344
2345 if (!isa<CXXRecordDecl>(Val: R)) {
2346 S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
2347 return;
2348 }
2349
2350 if (!cast<CXXRecordDecl>(Val: R)->isPOD()) {
2351 S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
2352 return;
2353 }
2354
2355 for (const auto *I : R->fields()) {
2356 if ((count == 1) || !I->getType()->isVectorType()) {
2357 S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
2358 return;
2359 }
2360 count++;
2361 }
2362
2363 D->addAttr(::new (S.Context) VecReturnAttr(S.Context, AL));
2364}
2365
2366static void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D,
2367 const ParsedAttr &AL) {
2368 if (isa<ParmVarDecl>(Val: D)) {
2369 // [[carries_dependency]] can only be applied to a parameter if it is a
2370 // parameter of a function declaration or lambda.
2371 if (!(Scope->getFlags() & clang::Scope::FunctionDeclarationScope)) {
2372 S.Diag(AL.getLoc(),
2373 diag::err_carries_dependency_param_not_function_decl);
2374 return;
2375 }
2376 }
2377
2378 D->addAttr(::new (S.Context) CarriesDependencyAttr(S.Context, AL));
2379}
2380
2381static void handleUnusedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2382 bool IsCXX17Attr = AL.isCXX11Attribute() && !AL.getScopeName();
2383
2384 // If this is spelled as the standard C++17 attribute, but not in C++17, warn
2385 // about using it as an extension.
2386 if (!S.getLangOpts().CPlusPlus17 && IsCXX17Attr)
2387 S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
2388
2389 D->addAttr(::new (S.Context) UnusedAttr(S.Context, AL));
2390}
2391
2392static void handleConstructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2393 uint32_t priority = ConstructorAttr::DefaultPriority;
2394 if (S.getLangOpts().HLSL && AL.getNumArgs()) {
2395 S.Diag(AL.getLoc(), diag::err_hlsl_init_priority_unsupported);
2396 return;
2397 }
2398 if (AL.getNumArgs() &&
2399 !checkUInt32Argument(S, AI: AL, Expr: AL.getArgAsExpr(Arg: 0), Val&: priority))
2400 return;
2401
2402 D->addAttr(::new (S.Context) ConstructorAttr(S.Context, AL, priority));
2403}
2404
2405static void handleDestructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2406 uint32_t priority = DestructorAttr::DefaultPriority;
2407 if (AL.getNumArgs() &&
2408 !checkUInt32Argument(S, AI: AL, Expr: AL.getArgAsExpr(Arg: 0), Val&: priority))
2409 return;
2410
2411 D->addAttr(::new (S.Context) DestructorAttr(S.Context, AL, priority));
2412}
2413
2414template <typename AttrTy>
2415static void handleAttrWithMessage(Sema &S, Decl *D, const ParsedAttr &AL) {
2416 // Handle the case where the attribute has a text message.
2417 StringRef Str;
2418 if (AL.getNumArgs() == 1 && !S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str))
2419 return;
2420
2421 D->addAttr(A: ::new (S.Context) AttrTy(S.Context, AL, Str));
2422}
2423
2424static void handleObjCSuppresProtocolAttr(Sema &S, Decl *D,
2425 const ParsedAttr &AL) {
2426 if (!cast<ObjCProtocolDecl>(Val: D)->isThisDeclarationADefinition()) {
2427 S.Diag(AL.getLoc(), diag::err_objc_attr_protocol_requires_definition)
2428 << AL << AL.getRange();
2429 return;
2430 }
2431
2432 D->addAttr(::new (S.Context) ObjCExplicitProtocolImplAttr(S.Context, AL));
2433}
2434
2435static bool checkAvailabilityAttr(Sema &S, SourceRange Range,
2436 IdentifierInfo *Platform,
2437 VersionTuple Introduced,
2438 VersionTuple Deprecated,
2439 VersionTuple Obsoleted) {
2440 StringRef PlatformName
2441 = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
2442 if (PlatformName.empty())
2443 PlatformName = Platform->getName();
2444
2445 // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
2446 // of these steps are needed).
2447 if (!Introduced.empty() && !Deprecated.empty() &&
2448 !(Introduced <= Deprecated)) {
2449 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2450 << 1 << PlatformName << Deprecated.getAsString()
2451 << 0 << Introduced.getAsString();
2452 return true;
2453 }
2454
2455 if (!Introduced.empty() && !Obsoleted.empty() &&
2456 !(Introduced <= Obsoleted)) {
2457 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2458 << 2 << PlatformName << Obsoleted.getAsString()
2459 << 0 << Introduced.getAsString();
2460 return true;
2461 }
2462
2463 if (!Deprecated.empty() && !Obsoleted.empty() &&
2464 !(Deprecated <= Obsoleted)) {
2465 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2466 << 2 << PlatformName << Obsoleted.getAsString()
2467 << 1 << Deprecated.getAsString();
2468 return true;
2469 }
2470
2471 return false;
2472}
2473
2474/// Check whether the two versions match.
2475///
2476/// If either version tuple is empty, then they are assumed to match. If
2477/// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y.
2478static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y,
2479 bool BeforeIsOkay) {
2480 if (X.empty() || Y.empty())
2481 return true;
2482
2483 if (X == Y)
2484 return true;
2485
2486 if (BeforeIsOkay && X < Y)
2487 return true;
2488
2489 return false;
2490}
2491
2492AvailabilityAttr *Sema::mergeAvailabilityAttr(
2493 NamedDecl *D, const AttributeCommonInfo &CI, IdentifierInfo *Platform,
2494 bool Implicit, VersionTuple Introduced, VersionTuple Deprecated,
2495 VersionTuple Obsoleted, bool IsUnavailable, StringRef Message,
2496 bool IsStrict, StringRef Replacement, AvailabilityMergeKind AMK,
2497 int Priority) {
2498 VersionTuple MergedIntroduced = Introduced;
2499 VersionTuple MergedDeprecated = Deprecated;
2500 VersionTuple MergedObsoleted = Obsoleted;
2501 bool FoundAny = false;
2502 bool OverrideOrImpl = false;
2503 switch (AMK) {
2504 case AMK_None:
2505 case AMK_Redeclaration:
2506 OverrideOrImpl = false;
2507 break;
2508
2509 case AMK_Override:
2510 case AMK_ProtocolImplementation:
2511 case AMK_OptionalProtocolImplementation:
2512 OverrideOrImpl = true;
2513 break;
2514 }
2515
2516 if (D->hasAttrs()) {
2517 AttrVec &Attrs = D->getAttrs();
2518 for (unsigned i = 0, e = Attrs.size(); i != e;) {
2519 const auto *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]);
2520 if (!OldAA) {
2521 ++i;
2522 continue;
2523 }
2524
2525 IdentifierInfo *OldPlatform = OldAA->getPlatform();
2526 if (OldPlatform != Platform) {
2527 ++i;
2528 continue;
2529 }
2530
2531 // If there is an existing availability attribute for this platform that
2532 // has a lower priority use the existing one and discard the new
2533 // attribute.
2534 if (OldAA->getPriority() < Priority)
2535 return nullptr;
2536
2537 // If there is an existing attribute for this platform that has a higher
2538 // priority than the new attribute then erase the old one and continue
2539 // processing the attributes.
2540 if (OldAA->getPriority() > Priority) {
2541 Attrs.erase(CI: Attrs.begin() + i);
2542 --e;
2543 continue;
2544 }
2545
2546 FoundAny = true;
2547 VersionTuple OldIntroduced = OldAA->getIntroduced();
2548 VersionTuple OldDeprecated = OldAA->getDeprecated();
2549 VersionTuple OldObsoleted = OldAA->getObsoleted();
2550 bool OldIsUnavailable = OldAA->getUnavailable();
2551
2552 if (!versionsMatch(X: OldIntroduced, Y: Introduced, BeforeIsOkay: OverrideOrImpl) ||
2553 !versionsMatch(X: Deprecated, Y: OldDeprecated, BeforeIsOkay: OverrideOrImpl) ||
2554 !versionsMatch(X: Obsoleted, Y: OldObsoleted, BeforeIsOkay: OverrideOrImpl) ||
2555 !(OldIsUnavailable == IsUnavailable ||
2556 (OverrideOrImpl && !OldIsUnavailable && IsUnavailable))) {
2557 if (OverrideOrImpl) {
2558 int Which = -1;
2559 VersionTuple FirstVersion;
2560 VersionTuple SecondVersion;
2561 if (!versionsMatch(X: OldIntroduced, Y: Introduced, BeforeIsOkay: OverrideOrImpl)) {
2562 Which = 0;
2563 FirstVersion = OldIntroduced;
2564 SecondVersion = Introduced;
2565 } else if (!versionsMatch(X: Deprecated, Y: OldDeprecated, BeforeIsOkay: OverrideOrImpl)) {
2566 Which = 1;
2567 FirstVersion = Deprecated;
2568 SecondVersion = OldDeprecated;
2569 } else if (!versionsMatch(X: Obsoleted, Y: OldObsoleted, BeforeIsOkay: OverrideOrImpl)) {
2570 Which = 2;
2571 FirstVersion = Obsoleted;
2572 SecondVersion = OldObsoleted;
2573 }
2574
2575 if (Which == -1) {
2576 Diag(OldAA->getLocation(),
2577 diag::warn_mismatched_availability_override_unavail)
2578 << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
2579 << (AMK == AMK_Override);
2580 } else if (Which != 1 && AMK == AMK_OptionalProtocolImplementation) {
2581 // Allow different 'introduced' / 'obsoleted' availability versions
2582 // on a method that implements an optional protocol requirement. It
2583 // makes less sense to allow this for 'deprecated' as the user can't
2584 // see if the method is 'deprecated' as 'respondsToSelector' will
2585 // still return true when the method is deprecated.
2586 ++i;
2587 continue;
2588 } else {
2589 Diag(OldAA->getLocation(),
2590 diag::warn_mismatched_availability_override)
2591 << Which
2592 << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
2593 << FirstVersion.getAsString() << SecondVersion.getAsString()
2594 << (AMK == AMK_Override);
2595 }
2596 if (AMK == AMK_Override)
2597 Diag(CI.getLoc(), diag::note_overridden_method);
2598 else
2599 Diag(CI.getLoc(), diag::note_protocol_method);
2600 } else {
2601 Diag(OldAA->getLocation(), diag::warn_mismatched_availability);
2602 Diag(CI.getLoc(), diag::note_previous_attribute);
2603 }
2604
2605 Attrs.erase(CI: Attrs.begin() + i);
2606 --e;
2607 continue;
2608 }
2609
2610 VersionTuple MergedIntroduced2 = MergedIntroduced;
2611 VersionTuple MergedDeprecated2 = MergedDeprecated;
2612 VersionTuple MergedObsoleted2 = MergedObsoleted;
2613
2614 if (MergedIntroduced2.empty())
2615 MergedIntroduced2 = OldIntroduced;
2616 if (MergedDeprecated2.empty())
2617 MergedDeprecated2 = OldDeprecated;
2618 if (MergedObsoleted2.empty())
2619 MergedObsoleted2 = OldObsoleted;
2620
2621 if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform,
2622 MergedIntroduced2, MergedDeprecated2,
2623 MergedObsoleted2)) {
2624 Attrs.erase(CI: Attrs.begin() + i);
2625 --e;
2626 continue;
2627 }
2628
2629 MergedIntroduced = MergedIntroduced2;
2630 MergedDeprecated = MergedDeprecated2;
2631 MergedObsoleted = MergedObsoleted2;
2632 ++i;
2633 }
2634 }
2635
2636 if (FoundAny &&
2637 MergedIntroduced == Introduced &&
2638 MergedDeprecated == Deprecated &&
2639 MergedObsoleted == Obsoleted)
2640 return nullptr;
2641
2642 // Only create a new attribute if !OverrideOrImpl, but we want to do
2643 // the checking.
2644 if (!checkAvailabilityAttr(S&: *this, Range: CI.getRange(), Platform, Introduced: MergedIntroduced,
2645 Deprecated: MergedDeprecated, Obsoleted: MergedObsoleted) &&
2646 !OverrideOrImpl) {
2647 auto *Avail = ::new (Context) AvailabilityAttr(
2648 Context, CI, Platform, Introduced, Deprecated, Obsoleted, IsUnavailable,
2649 Message, IsStrict, Replacement, Priority);
2650 Avail->setImplicit(Implicit);
2651 return Avail;
2652 }
2653 return nullptr;
2654}
2655
2656static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2657 if (isa<UsingDecl, UnresolvedUsingTypenameDecl, UnresolvedUsingValueDecl>(
2658 Val: D)) {
2659 S.Diag(AL.getRange().getBegin(), diag::warn_deprecated_ignored_on_using)
2660 << AL;
2661 return;
2662 }
2663
2664 if (!AL.checkExactlyNumArgs(S, Num: 1))
2665 return;
2666 IdentifierLoc *Platform = AL.getArgAsIdent(Arg: 0);
2667
2668 IdentifierInfo *II = Platform->Ident;
2669 if (AvailabilityAttr::getPrettyPlatformName(II->getName()).empty())
2670 S.Diag(Platform->Loc, diag::warn_availability_unknown_platform)
2671 << Platform->Ident;
2672
2673 auto *ND = dyn_cast<NamedDecl>(Val: D);
2674 if (!ND) // We warned about this already, so just return.
2675 return;
2676
2677 AvailabilityChange Introduced = AL.getAvailabilityIntroduced();
2678 AvailabilityChange Deprecated = AL.getAvailabilityDeprecated();
2679 AvailabilityChange Obsoleted = AL.getAvailabilityObsoleted();
2680 bool IsUnavailable = AL.getUnavailableLoc().isValid();
2681 bool IsStrict = AL.getStrictLoc().isValid();
2682 StringRef Str;
2683 if (const auto *SE = dyn_cast_if_present<StringLiteral>(Val: AL.getMessageExpr()))
2684 Str = SE->getString();
2685 StringRef Replacement;
2686 if (const auto *SE =
2687 dyn_cast_if_present<StringLiteral>(Val: AL.getReplacementExpr()))
2688 Replacement = SE->getString();
2689
2690 if (II->isStr(Str: "swift")) {
2691 if (Introduced.isValid() || Obsoleted.isValid() ||
2692 (!IsUnavailable && !Deprecated.isValid())) {
2693 S.Diag(AL.getLoc(),
2694 diag::warn_availability_swift_unavailable_deprecated_only);
2695 return;
2696 }
2697 }
2698
2699 if (II->isStr(Str: "fuchsia")) {
2700 std::optional<unsigned> Min, Sub;
2701 if ((Min = Introduced.Version.getMinor()) ||
2702 (Sub = Introduced.Version.getSubminor())) {
2703 S.Diag(AL.getLoc(), diag::warn_availability_fuchsia_unavailable_minor);
2704 return;
2705 }
2706 }
2707
2708 int PriorityModifier = AL.isPragmaClangAttribute()
2709 ? Sema::AP_PragmaClangAttribute
2710 : Sema::AP_Explicit;
2711 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2712 ND, AL, II, false /*Implicit*/, Introduced.Version, Deprecated.Version,
2713 Obsoleted.Version, IsUnavailable, Str, IsStrict, Replacement,
2714 Sema::AMK_None, PriorityModifier);
2715 if (NewAttr)
2716 D->addAttr(A: NewAttr);
2717
2718 // Transcribe "ios" to "watchos" (and add a new attribute) if the versioning
2719 // matches before the start of the watchOS platform.
2720 if (S.Context.getTargetInfo().getTriple().isWatchOS()) {
2721 IdentifierInfo *NewII = nullptr;
2722 if (II->getName() == "ios")
2723 NewII = &S.Context.Idents.get(Name: "watchos");
2724 else if (II->getName() == "ios_app_extension")
2725 NewII = &S.Context.Idents.get(Name: "watchos_app_extension");
2726
2727 if (NewII) {
2728 const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking();
2729 const auto *IOSToWatchOSMapping =
2730 SDKInfo ? SDKInfo->getVersionMapping(
2731 Kind: DarwinSDKInfo::OSEnvPair::iOStoWatchOSPair())
2732 : nullptr;
2733
2734 auto adjustWatchOSVersion =
2735 [IOSToWatchOSMapping](VersionTuple Version) -> VersionTuple {
2736 if (Version.empty())
2737 return Version;
2738 auto MinimumWatchOSVersion = VersionTuple(2, 0);
2739
2740 if (IOSToWatchOSMapping) {
2741 if (auto MappedVersion = IOSToWatchOSMapping->map(
2742 Key: Version, MinimumValue: MinimumWatchOSVersion, MaximumValue: std::nullopt)) {
2743 return *MappedVersion;
2744 }
2745 }
2746
2747 auto Major = Version.getMajor();
2748 auto NewMajor = Major >= 9 ? Major - 7 : 0;
2749 if (NewMajor >= 2) {
2750 if (Version.getMinor()) {
2751 if (Version.getSubminor())
2752 return VersionTuple(NewMajor, *Version.getMinor(),
2753 *Version.getSubminor());
2754 else
2755 return VersionTuple(NewMajor, *Version.getMinor());
2756 }
2757 return VersionTuple(NewMajor);
2758 }
2759
2760 return MinimumWatchOSVersion;
2761 };
2762
2763 auto NewIntroduced = adjustWatchOSVersion(Introduced.Version);
2764 auto NewDeprecated = adjustWatchOSVersion(Deprecated.Version);
2765 auto NewObsoleted = adjustWatchOSVersion(Obsoleted.Version);
2766
2767 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2768 ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
2769 NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,
2770 Sema::AMK_None,
2771 PriorityModifier + Sema::AP_InferredFromOtherPlatform);
2772 if (NewAttr)
2773 D->addAttr(A: NewAttr);
2774 }
2775 } else if (S.Context.getTargetInfo().getTriple().isTvOS()) {
2776 // Transcribe "ios" to "tvos" (and add a new attribute) if the versioning
2777 // matches before the start of the tvOS platform.
2778 IdentifierInfo *NewII = nullptr;
2779 if (II->getName() == "ios")
2780 NewII = &S.Context.Idents.get(Name: "tvos");
2781 else if (II->getName() == "ios_app_extension")
2782 NewII = &S.Context.Idents.get(Name: "tvos_app_extension");
2783
2784 if (NewII) {
2785 const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking();
2786 const auto *IOSToTvOSMapping =
2787 SDKInfo ? SDKInfo->getVersionMapping(
2788 Kind: DarwinSDKInfo::OSEnvPair::iOStoTvOSPair())
2789 : nullptr;
2790
2791 auto AdjustTvOSVersion =
2792 [IOSToTvOSMapping](VersionTuple Version) -> VersionTuple {
2793 if (Version.empty())
2794 return Version;
2795
2796 if (IOSToTvOSMapping) {
2797 if (auto MappedVersion = IOSToTvOSMapping->map(
2798 Key: Version, MinimumValue: VersionTuple(0, 0), MaximumValue: std::nullopt)) {
2799 return *MappedVersion;
2800 }
2801 }
2802 return Version;
2803 };
2804
2805 auto NewIntroduced = AdjustTvOSVersion(Introduced.Version);
2806 auto NewDeprecated = AdjustTvOSVersion(Deprecated.Version);
2807 auto NewObsoleted = AdjustTvOSVersion(Obsoleted.Version);
2808
2809 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2810 ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
2811 NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,
2812 Sema::AMK_None,
2813 PriorityModifier + Sema::AP_InferredFromOtherPlatform);
2814 if (NewAttr)
2815 D->addAttr(A: NewAttr);
2816 }
2817 } else if (S.Context.getTargetInfo().getTriple().getOS() ==
2818 llvm::Triple::IOS &&
2819 S.Context.getTargetInfo().getTriple().isMacCatalystEnvironment()) {
2820 auto GetSDKInfo = [&]() {
2821 return S.getDarwinSDKInfoForAvailabilityChecking(Loc: AL.getRange().getBegin(),
2822 Platform: "macOS");
2823 };
2824
2825 // Transcribe "ios" to "maccatalyst" (and add a new attribute).
2826 IdentifierInfo *NewII = nullptr;
2827 if (II->getName() == "ios")
2828 NewII = &S.Context.Idents.get(Name: "maccatalyst");
2829 else if (II->getName() == "ios_app_extension")
2830 NewII = &S.Context.Idents.get(Name: "maccatalyst_app_extension");
2831 if (NewII) {
2832 auto MinMacCatalystVersion = [](const VersionTuple &V) {
2833 if (V.empty())
2834 return V;
2835 if (V.getMajor() < 13 ||
2836 (V.getMajor() == 13 && V.getMinor() && *V.getMinor() < 1))
2837 return VersionTuple(13, 1); // The min Mac Catalyst version is 13.1.
2838 return V;
2839 };
2840 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2841 ND, AL, NewII, true /*Implicit*/,
2842 MinMacCatalystVersion(Introduced.Version),
2843 MinMacCatalystVersion(Deprecated.Version),
2844 MinMacCatalystVersion(Obsoleted.Version), IsUnavailable, Str,
2845 IsStrict, Replacement, Sema::AMK_None,
2846 PriorityModifier + Sema::AP_InferredFromOtherPlatform);
2847 if (NewAttr)
2848 D->addAttr(A: NewAttr);
2849 } else if (II->getName() == "macos" && GetSDKInfo() &&
2850 (!Introduced.Version.empty() || !Deprecated.Version.empty() ||
2851 !Obsoleted.Version.empty())) {
2852 if (const auto *MacOStoMacCatalystMapping =
2853 GetSDKInfo()->getVersionMapping(
2854 Kind: DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {
2855 // Infer Mac Catalyst availability from the macOS availability attribute
2856 // if it has versioned availability. Don't infer 'unavailable'. This
2857 // inferred availability has lower priority than the other availability
2858 // attributes that are inferred from 'ios'.
2859 NewII = &S.Context.Idents.get(Name: "maccatalyst");
2860 auto RemapMacOSVersion =
2861 [&](const VersionTuple &V) -> std::optional<VersionTuple> {
2862 if (V.empty())
2863 return std::nullopt;
2864 // API_TO_BE_DEPRECATED is 100000.
2865 if (V.getMajor() == 100000)
2866 return VersionTuple(100000);
2867 // The minimum iosmac version is 13.1
2868 return MacOStoMacCatalystMapping->map(Key: V, MinimumValue: VersionTuple(13, 1),
2869 MaximumValue: std::nullopt);
2870 };
2871 std::optional<VersionTuple> NewIntroduced =
2872 RemapMacOSVersion(Introduced.Version),
2873 NewDeprecated =
2874 RemapMacOSVersion(Deprecated.Version),
2875 NewObsoleted =
2876 RemapMacOSVersion(Obsoleted.Version);
2877 if (NewIntroduced || NewDeprecated || NewObsoleted) {
2878 auto VersionOrEmptyVersion =
2879 [](const std::optional<VersionTuple> &V) -> VersionTuple {
2880 return V ? *V : VersionTuple();
2881 };
2882 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2883 ND, AL, NewII, true /*Implicit*/,
2884 VersionOrEmptyVersion(NewIntroduced),
2885 VersionOrEmptyVersion(NewDeprecated),
2886 VersionOrEmptyVersion(NewObsoleted), /*IsUnavailable=*/false, Str,
2887 IsStrict, Replacement, Sema::AMK_None,
2888 PriorityModifier + Sema::AP_InferredFromOtherPlatform +
2889 Sema::AP_InferredFromOtherPlatform);
2890 if (NewAttr)
2891 D->addAttr(A: NewAttr);
2892 }
2893 }
2894 }
2895 }
2896}
2897
2898static void handleExternalSourceSymbolAttr(Sema &S, Decl *D,
2899 const ParsedAttr &AL) {
2900 if (!AL.checkAtLeastNumArgs(S, Num: 1) || !AL.checkAtMostNumArgs(S, Num: 4))
2901 return;
2902
2903 StringRef Language;
2904 if (const auto *SE = dyn_cast_if_present<StringLiteral>(Val: AL.getArgAsExpr(Arg: 0)))
2905 Language = SE->getString();
2906 StringRef DefinedIn;
2907 if (const auto *SE = dyn_cast_if_present<StringLiteral>(Val: AL.getArgAsExpr(Arg: 1)))
2908 DefinedIn = SE->getString();
2909 bool IsGeneratedDeclaration = AL.getArgAsIdent(Arg: 2) != nullptr;
2910 StringRef USR;
2911 if (const auto *SE = dyn_cast_if_present<StringLiteral>(Val: AL.getArgAsExpr(Arg: 3)))
2912 USR = SE->getString();
2913
2914 D->addAttr(::new (S.Context) ExternalSourceSymbolAttr(
2915 S.Context, AL, Language, DefinedIn, IsGeneratedDeclaration, USR));
2916}
2917
2918template <class T>
2919static T *mergeVisibilityAttr(Sema &S, Decl *D, const AttributeCommonInfo &CI,
2920 typename T::VisibilityType value) {
2921 T *existingAttr = D->getAttr<T>();
2922 if (existingAttr) {
2923 typename T::VisibilityType existingValue = existingAttr->getVisibility();
2924 if (existingValue == value)
2925 return nullptr;
2926 S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
2927 S.Diag(CI.getLoc(), diag::note_previous_attribute);
2928 D->dropAttr<T>();
2929 }
2930 return ::new (S.Context) T(S.Context, CI, value);
2931}
2932
2933VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D,
2934 const AttributeCommonInfo &CI,
2935 VisibilityAttr::VisibilityType Vis) {
2936 return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, CI, Vis);
2937}
2938
2939TypeVisibilityAttr *
2940Sema::mergeTypeVisibilityAttr(Decl *D, const AttributeCommonInfo &CI,
2941 TypeVisibilityAttr::VisibilityType Vis) {
2942 return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, CI, Vis);
2943}
2944
2945static void handleVisibilityAttr(Sema &S, Decl *D, const ParsedAttr &AL,
2946 bool isTypeVisibility) {
2947 // Visibility attributes don't mean anything on a typedef.
2948 if (isa<TypedefNameDecl>(Val: D)) {
2949 S.Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored) << AL;
2950 return;
2951 }
2952
2953 // 'type_visibility' can only go on a type or namespace.
2954 if (isTypeVisibility && !(isa<TagDecl>(Val: D) || isa<ObjCInterfaceDecl>(Val: D) ||
2955 isa<NamespaceDecl>(Val: D))) {
2956 S.Diag(AL.getRange().getBegin(), diag::err_attribute_wrong_decl_type)
2957 << AL << AL.isRegularKeywordAttribute() << ExpectedTypeOrNamespace;
2958 return;
2959 }
2960
2961 // Check that the argument is a string literal.
2962 StringRef TypeStr;
2963 SourceLocation LiteralLoc;
2964 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: TypeStr, ArgLocation: &LiteralLoc))
2965 return;
2966
2967 VisibilityAttr::VisibilityType type;
2968 if (!VisibilityAttr::ConvertStrToVisibilityType(TypeStr, type)) {
2969 S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported) << AL
2970 << TypeStr;
2971 return;
2972 }
2973
2974 // Complain about attempts to use protected visibility on targets
2975 // (like Darwin) that don't support it.
2976 if (type == VisibilityAttr::Protected &&
2977 !S.Context.getTargetInfo().hasProtectedVisibility()) {
2978 S.Diag(AL.getLoc(), diag::warn_attribute_protected_visibility);
2979 type = VisibilityAttr::Default;
2980 }
2981
2982 Attr *newAttr;
2983 if (isTypeVisibility) {
2984 newAttr = S.mergeTypeVisibilityAttr(
2985 D, AL, (TypeVisibilityAttr::VisibilityType)type);
2986 } else {
2987 newAttr = S.mergeVisibilityAttr(D, AL, type);
2988 }
2989 if (newAttr)
2990 D->addAttr(A: newAttr);
2991}
2992
2993static void handleObjCDirectAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2994 // objc_direct cannot be set on methods declared in the context of a protocol
2995 if (isa<ObjCProtocolDecl>(Val: D->getDeclContext())) {
2996 S.Diag(AL.getLoc(), diag::err_objc_direct_on_protocol) << false;
2997 return;
2998 }
2999
3000 if (S.getLangOpts().ObjCRuntime.allowsDirectDispatch()) {
3001 handleSimpleAttribute<ObjCDirectAttr>(S, D, AL);
3002 } else {
3003 S.Diag(AL.getLoc(), diag::warn_objc_direct_ignored) << AL;
3004 }
3005}
3006
3007static void handleObjCDirectMembersAttr(Sema &S, Decl *D,
3008 const ParsedAttr &AL) {
3009 if (S.getLangOpts().ObjCRuntime.allowsDirectDispatch()) {
3010 handleSimpleAttribute<ObjCDirectMembersAttr>(S, D, AL);
3011 } else {
3012 S.Diag(AL.getLoc(), diag::warn_objc_direct_ignored) << AL;
3013 }
3014}
3015
3016static void handleObjCMethodFamilyAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3017 const auto *M = cast<ObjCMethodDecl>(Val: D);
3018 if (!AL.isArgIdent(Arg: 0)) {
3019 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3020 << AL << 1 << AANT_ArgumentIdentifier;
3021 return;
3022 }
3023
3024 IdentifierLoc *IL = AL.getArgAsIdent(Arg: 0);
3025 ObjCMethodFamilyAttr::FamilyKind F;
3026 if (!ObjCMethodFamilyAttr::ConvertStrToFamilyKind(IL->Ident->getName(), F)) {
3027 S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL << IL->Ident;
3028 return;
3029 }
3030
3031 if (F == ObjCMethodFamilyAttr::OMF_init &&
3032 !M->getReturnType()->isObjCObjectPointerType()) {
3033 S.Diag(M->getLocation(), diag::err_init_method_bad_return_type)
3034 << M->getReturnType();
3035 // Ignore the attribute.
3036 return;
3037 }
3038
3039 D->addAttr(new (S.Context) ObjCMethodFamilyAttr(S.Context, AL, F));
3040}
3041
3042static void handleObjCNSObject(Sema &S, Decl *D, const ParsedAttr &AL) {
3043 if (const auto *TD = dyn_cast<TypedefNameDecl>(Val: D)) {
3044 QualType T = TD->getUnderlyingType();
3045 if (!T->isCARCBridgableType()) {
3046 S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
3047 return;
3048 }
3049 }
3050 else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(Val: D)) {
3051 QualType T = PD->getType();
3052 if (!T->isCARCBridgableType()) {
3053 S.Diag(PD->getLocation(), diag::err_nsobject_attribute);
3054 return;
3055 }
3056 }
3057 else {
3058 // It is okay to include this attribute on properties, e.g.:
3059 //
3060 // @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
3061 //
3062 // In this case it follows tradition and suppresses an error in the above
3063 // case.
3064 S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
3065 }
3066 D->addAttr(::new (S.Context) ObjCNSObjectAttr(S.Context, AL));
3067}
3068
3069static void handleObjCIndependentClass(Sema &S, Decl *D, const ParsedAttr &AL) {
3070 if (const auto *TD = dyn_cast<TypedefNameDecl>(Val: D)) {
3071 QualType T = TD->getUnderlyingType();
3072 if (!T->isObjCObjectPointerType()) {
3073 S.Diag(TD->getLocation(), diag::warn_ptr_independentclass_attribute);
3074 return;
3075 }
3076 } else {
3077 S.Diag(D->getLocation(), diag::warn_independentclass_attribute);
3078 return;
3079 }
3080 D->addAttr(::new (S.Context) ObjCIndependentClassAttr(S.Context, AL));
3081}
3082
3083static void handleBlocksAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3084 if (!AL.isArgIdent(Arg: 0)) {
3085 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3086 << AL << 1 << AANT_ArgumentIdentifier;
3087 return;
3088 }
3089
3090 IdentifierInfo *II = AL.getArgAsIdent(Arg: 0)->Ident;
3091 BlocksAttr::BlockType type;
3092 if (!BlocksAttr::ConvertStrToBlockType(II->getName(), type)) {
3093 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
3094 return;
3095 }
3096
3097 D->addAttr(::new (S.Context) BlocksAttr(S.Context, AL, type));
3098}
3099
3100static void handleSentinelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3101 unsigned sentinel = (unsigned)SentinelAttr::DefaultSentinel;
3102 if (AL.getNumArgs() > 0) {
3103 Expr *E = AL.getArgAsExpr(Arg: 0);
3104 std::optional<llvm::APSInt> Idx = llvm::APSInt(32);
3105 if (E->isTypeDependent() || !(Idx = E->getIntegerConstantExpr(Ctx: S.Context))) {
3106 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3107 << AL << 1 << AANT_ArgumentIntegerConstant << E->getSourceRange();
3108 return;
3109 }
3110
3111 if (Idx->isSigned() && Idx->isNegative()) {
3112 S.Diag(AL.getLoc(), diag::err_attribute_sentinel_less_than_zero)
3113 << E->getSourceRange();
3114 return;
3115 }
3116
3117 sentinel = Idx->getZExtValue();
3118 }
3119
3120 unsigned nullPos = (unsigned)SentinelAttr::DefaultNullPos;
3121 if (AL.getNumArgs() > 1) {
3122 Expr *E = AL.getArgAsExpr(Arg: 1);
3123 std::optional<llvm::APSInt> Idx = llvm::APSInt(32);
3124 if (E->isTypeDependent() || !(Idx = E->getIntegerConstantExpr(Ctx: S.Context))) {
3125 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3126 << AL << 2 << AANT_ArgumentIntegerConstant << E->getSourceRange();
3127 return;
3128 }
3129 nullPos = Idx->getZExtValue();
3130
3131 if ((Idx->isSigned() && Idx->isNegative()) || nullPos > 1) {
3132 // FIXME: This error message could be improved, it would be nice
3133 // to say what the bounds actually are.
3134 S.Diag(AL.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
3135 << E->getSourceRange();
3136 return;
3137 }
3138 }
3139
3140 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
3141 const FunctionType *FT = FD->getType()->castAs<FunctionType>();
3142 if (isa<FunctionNoProtoType>(Val: FT)) {
3143 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_named_arguments);
3144 return;
3145 }
3146
3147 if (!cast<FunctionProtoType>(Val: FT)->isVariadic()) {
3148 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
3149 return;
3150 }
3151 } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(Val: D)) {
3152 if (!MD->isVariadic()) {
3153 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
3154 return;
3155 }
3156 } else if (const auto *BD = dyn_cast<BlockDecl>(Val: D)) {
3157 if (!BD->isVariadic()) {
3158 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
3159 return;
3160 }
3161 } else if (const auto *V = dyn_cast<VarDecl>(Val: D)) {
3162 QualType Ty = V->getType();
3163 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
3164 const FunctionType *FT = Ty->isFunctionPointerType()
3165 ? D->getFunctionType()
3166 : Ty->castAs<BlockPointerType>()
3167 ->getPointeeType()
3168 ->castAs<FunctionType>();
3169 if (!cast<FunctionProtoType>(Val: FT)->isVariadic()) {
3170 int m = Ty->isFunctionPointerType() ? 0 : 1;
3171 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
3172 return;
3173 }
3174 } else {
3175 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
3176 << AL << AL.isRegularKeywordAttribute()
3177 << ExpectedFunctionMethodOrBlock;
3178 return;
3179 }
3180 } else {
3181 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
3182 << AL << AL.isRegularKeywordAttribute()
3183 << ExpectedFunctionMethodOrBlock;
3184 return;
3185 }
3186 D->addAttr(::new (S.Context) SentinelAttr(S.Context, AL, sentinel, nullPos));
3187}
3188
3189static void handleWarnUnusedResult(Sema &S, Decl *D, const ParsedAttr &AL) {
3190 if (D->getFunctionType() &&
3191 D->getFunctionType()->getReturnType()->isVoidType() &&
3192 !isa<CXXConstructorDecl>(Val: D)) {
3193 S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) << AL << 0;
3194 return;
3195 }
3196 if (const auto *MD = dyn_cast<ObjCMethodDecl>(Val: D))
3197 if (MD->getReturnType()->isVoidType()) {
3198 S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) << AL << 1;
3199 return;
3200 }
3201
3202 StringRef Str;
3203 if (AL.isStandardAttributeSyntax() && !AL.getScopeName()) {
3204 // The standard attribute cannot be applied to variable declarations such
3205 // as a function pointer.
3206 if (isa<VarDecl>(D))
3207 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type_str)
3208 << AL << AL.isRegularKeywordAttribute()
3209 << "functions, classes, or enumerations";
3210
3211 // If this is spelled as the standard C++17 attribute, but not in C++17,
3212 // warn about using it as an extension. If there are attribute arguments,
3213 // then claim it's a C++20 extension instead.
3214 // FIXME: If WG14 does not seem likely to adopt the same feature, add an
3215 // extension warning for C23 mode.
3216 const LangOptions &LO = S.getLangOpts();
3217 if (AL.getNumArgs() == 1) {
3218 if (LO.CPlusPlus && !LO.CPlusPlus20)
3219 S.Diag(AL.getLoc(), diag::ext_cxx20_attr) << AL;
3220
3221 // Since this is spelled [[nodiscard]], get the optional string
3222 // literal. If in C++ mode, but not in C++20 mode, diagnose as an
3223 // extension.
3224 // FIXME: C23 should support this feature as well, even as an extension.
3225 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str, ArgLocation: nullptr))
3226 return;
3227 } else if (LO.CPlusPlus && !LO.CPlusPlus17)
3228 S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
3229 }
3230
3231 if ((!AL.isGNUAttribute() &&
3232 !(AL.isStandardAttributeSyntax() && AL.isClangScope())) &&
3233 isa<TypedefNameDecl>(Val: D)) {
3234 S.Diag(AL.getLoc(), diag::warn_unused_result_typedef_unsupported_spelling)
3235 << AL.isGNUScope();
3236 return;
3237 }
3238
3239 D->addAttr(::new (S.Context) WarnUnusedResultAttr(S.Context, AL, Str));
3240}
3241
3242static void handleWeakImportAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3243 // weak_import only applies to variable & function declarations.
3244 bool isDef = false;
3245 if (!D->canBeWeakImported(IsDefinition&: isDef)) {
3246 if (isDef)
3247 S.Diag(AL.getLoc(), diag::warn_attribute_invalid_on_definition)
3248 << "weak_import";
3249 else if (isa<ObjCPropertyDecl>(Val: D) || isa<ObjCMethodDecl>(Val: D) ||
3250 (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
3251 (isa<ObjCInterfaceDecl>(Val: D) || isa<EnumDecl>(Val: D)))) {
3252 // Nothing to warn about here.
3253 } else
3254 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
3255 << AL << AL.isRegularKeywordAttribute() << ExpectedVariableOrFunction;
3256
3257 return;
3258 }
3259
3260 D->addAttr(::new (S.Context) WeakImportAttr(S.Context, AL));
3261}
3262
3263// Handles reqd_work_group_size and work_group_size_hint.
3264template <typename WorkGroupAttr>
3265static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
3266 uint32_t WGSize[3];
3267 for (unsigned i = 0; i < 3; ++i) {
3268 const Expr *E = AL.getArgAsExpr(Arg: i);
3269 if (!checkUInt32Argument(S, AI: AL, Expr: E, Val&: WGSize[i], Idx: i,
3270 /*StrictlyUnsigned=*/true))
3271 return;
3272 if (WGSize[i] == 0) {
3273 S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
3274 << AL << E->getSourceRange();
3275 return;
3276 }
3277 }
3278
3279 WorkGroupAttr *Existing = D->getAttr<WorkGroupAttr>();
3280 if (Existing && !(Existing->getXDim() == WGSize[0] &&
3281 Existing->getYDim() == WGSize[1] &&
3282 Existing->getZDim() == WGSize[2]))
3283 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3284
3285 D->addAttr(A: ::new (S.Context)
3286 WorkGroupAttr(S.Context, AL, WGSize[0], WGSize[1], WGSize[2]));
3287}
3288
3289// Handles intel_reqd_sub_group_size.
3290static void handleSubGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
3291 uint32_t SGSize;
3292 const Expr *E = AL.getArgAsExpr(Arg: 0);
3293 if (!checkUInt32Argument(S, AI: AL, Expr: E, Val&: SGSize))
3294 return;
3295 if (SGSize == 0) {
3296 S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
3297 << AL << E->getSourceRange();
3298 return;
3299 }
3300
3301 OpenCLIntelReqdSubGroupSizeAttr *Existing =
3302 D->getAttr<OpenCLIntelReqdSubGroupSizeAttr>();
3303 if (Existing && Existing->getSubGroupSize() != SGSize)
3304 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3305
3306 D->addAttr(::new (S.Context)
3307 OpenCLIntelReqdSubGroupSizeAttr(S.Context, AL, SGSize));
3308}
3309
3310static void handleVecTypeHint(Sema &S, Decl *D, const ParsedAttr &AL) {
3311 if (!AL.hasParsedType()) {
3312 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
3313 return;
3314 }
3315
3316 TypeSourceInfo *ParmTSI = nullptr;
3317 QualType ParmType = S.GetTypeFromParser(Ty: AL.getTypeArg(), TInfo: &ParmTSI);
3318 assert(ParmTSI && "no type source info for attribute argument");
3319
3320 if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() &&
3321 (ParmType->isBooleanType() ||
3322 !ParmType->isIntegralType(Ctx: S.getASTContext()))) {
3323 S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument) << 2 << AL;
3324 return;
3325 }
3326
3327 if (VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>()) {
3328 if (!S.Context.hasSameType(A->getTypeHint(), ParmType)) {
3329 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3330 return;
3331 }
3332 }
3333
3334 D->addAttr(::new (S.Context) VecTypeHintAttr(S.Context, AL, ParmTSI));
3335}
3336
3337SectionAttr *Sema::mergeSectionAttr(Decl *D, const AttributeCommonInfo &CI,
3338 StringRef Name) {
3339 // Explicit or partial specializations do not inherit
3340 // the section attribute from the primary template.
3341 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
3342 if (CI.getAttributeSpellingListIndex() == SectionAttr::Declspec_allocate &&
3343 FD->isFunctionTemplateSpecialization())
3344 return nullptr;
3345 }
3346 if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
3347 if (ExistingAttr->getName() == Name)
3348 return nullptr;
3349 Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section)
3350 << 1 /*section*/;
3351 Diag(CI.getLoc(), diag::note_previous_attribute);
3352 return nullptr;
3353 }
3354 return ::new (Context) SectionAttr(Context, CI, Name);
3355}
3356
3357/// Used to implement to perform semantic checking on
3358/// attribute((section("foo"))) specifiers.
3359///
3360/// In this case, "foo" is passed in to be checked. If the section
3361/// specifier is invalid, return an Error that indicates the problem.
3362///
3363/// This is a simple quality of implementation feature to catch errors
3364/// and give good diagnostics in cases when the assembler or code generator
3365/// would otherwise reject the section specifier.
3366llvm::Error Sema::isValidSectionSpecifier(StringRef SecName) {
3367 if (!Context.getTargetInfo().getTriple().isOSDarwin())
3368 return llvm::Error::success();
3369
3370 // Let MCSectionMachO validate this.
3371 StringRef Segment, Section;
3372 unsigned TAA, StubSize;
3373 bool HasTAA;
3374 return llvm::MCSectionMachO::ParseSectionSpecifier(Spec: SecName, Segment, Section,
3375 TAA, TAAParsed&: HasTAA, StubSize);
3376}
3377
3378bool Sema::checkSectionName(SourceLocation LiteralLoc, StringRef SecName) {
3379 if (llvm::Error E = isValidSectionSpecifier(SecName)) {
3380 Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
3381 << toString(std::move(E)) << 1 /*'section'*/;
3382 return false;
3383 }
3384 return true;
3385}
3386
3387static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3388 // Make sure that there is a string literal as the sections's single
3389 // argument.
3390 StringRef Str;
3391 SourceLocation LiteralLoc;
3392 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str, ArgLocation: &LiteralLoc))
3393 return;
3394
3395 if (!S.checkSectionName(LiteralLoc, SecName: Str))
3396 return;
3397
3398 SectionAttr *NewAttr = S.mergeSectionAttr(D, AL, Str);
3399 if (NewAttr) {
3400 D->addAttr(A: NewAttr);
3401 if (isa<FunctionDecl, FunctionTemplateDecl, ObjCMethodDecl,
3402 ObjCPropertyDecl>(Val: D))
3403 S.UnifySection(NewAttr->getName(),
3404 ASTContext::PSF_Execute | ASTContext::PSF_Read,
3405 cast<NamedDecl>(Val: D));
3406 }
3407}
3408
3409static void handleCodeModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3410 StringRef Str;
3411 SourceLocation LiteralLoc;
3412 // Check that it is a string.
3413 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str, ArgLocation: &LiteralLoc))
3414 return;
3415
3416 llvm::CodeModel::Model CM;
3417 if (!CodeModelAttr::ConvertStrToModel(Str, CM)) {
3418 S.Diag(LiteralLoc, diag::err_attr_codemodel_arg) << Str;
3419 return;
3420 }
3421
3422 D->addAttr(::new (S.Context) CodeModelAttr(S.Context, AL, CM));
3423}
3424
3425// This is used for `__declspec(code_seg("segname"))` on a decl.
3426// `#pragma code_seg("segname")` uses checkSectionName() instead.
3427static bool checkCodeSegName(Sema &S, SourceLocation LiteralLoc,
3428 StringRef CodeSegName) {
3429 if (llvm::Error E = S.isValidSectionSpecifier(SecName: CodeSegName)) {
3430 S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
3431 << toString(std::move(E)) << 0 /*'code-seg'*/;
3432 return false;
3433 }
3434
3435 return true;
3436}
3437
3438CodeSegAttr *Sema::mergeCodeSegAttr(Decl *D, const AttributeCommonInfo &CI,
3439 StringRef Name) {
3440 // Explicit or partial specializations do not inherit
3441 // the code_seg attribute from the primary template.
3442 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
3443 if (FD->isFunctionTemplateSpecialization())
3444 return nullptr;
3445 }
3446 if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) {
3447 if (ExistingAttr->getName() == Name)
3448 return nullptr;
3449 Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section)
3450 << 0 /*codeseg*/;
3451 Diag(CI.getLoc(), diag::note_previous_attribute);
3452 return nullptr;
3453 }
3454 return ::new (Context) CodeSegAttr(Context, CI, Name);
3455}
3456
3457static void handleCodeSegAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3458 StringRef Str;
3459 SourceLocation LiteralLoc;
3460 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str, ArgLocation: &LiteralLoc))
3461 return;
3462 if (!checkCodeSegName(S, LiteralLoc, CodeSegName: Str))
3463 return;
3464 if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) {
3465 if (!ExistingAttr->isImplicit()) {
3466 S.Diag(AL.getLoc(),
3467 ExistingAttr->getName() == Str
3468 ? diag::warn_duplicate_codeseg_attribute
3469 : diag::err_conflicting_codeseg_attribute);
3470 return;
3471 }
3472 D->dropAttr<CodeSegAttr>();
3473 }
3474 if (CodeSegAttr *CSA = S.mergeCodeSegAttr(D, AL, Str))
3475 D->addAttr(CSA);
3476}
3477
3478// Check for things we'd like to warn about. Multiversioning issues are
3479// handled later in the process, once we know how many exist.
3480bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) {
3481 enum FirstParam { Unsupported, Duplicate, Unknown };
3482 enum SecondParam { None, CPU, Tune };
3483 enum ThirdParam { Target, TargetClones };
3484 if (AttrStr.contains("fpmath="))
3485 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3486 << Unsupported << None << "fpmath=" << Target;
3487
3488 // Diagnose use of tune if target doesn't support it.
3489 if (!Context.getTargetInfo().supportsTargetAttributeTune() &&
3490 AttrStr.contains("tune="))
3491 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3492 << Unsupported << None << "tune=" << Target;
3493
3494 ParsedTargetAttr ParsedAttrs =
3495 Context.getTargetInfo().parseTargetAttr(Str: AttrStr);
3496
3497 if (!ParsedAttrs.CPU.empty() &&
3498 !Context.getTargetInfo().isValidCPUName(ParsedAttrs.CPU))
3499 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3500 << Unknown << CPU << ParsedAttrs.CPU << Target;
3501
3502 if (!ParsedAttrs.Tune.empty() &&
3503 !Context.getTargetInfo().isValidCPUName(ParsedAttrs.Tune))
3504 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3505 << Unknown << Tune << ParsedAttrs.Tune << Target;
3506
3507 if (Context.getTargetInfo().getTriple().isRISCV() &&
3508 ParsedAttrs.Duplicate != "")
3509 return Diag(LiteralLoc, diag::err_duplicate_target_attribute)
3510 << Duplicate << None << ParsedAttrs.Duplicate << Target;
3511
3512 if (ParsedAttrs.Duplicate != "")
3513 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3514 << Duplicate << None << ParsedAttrs.Duplicate << Target;
3515
3516 for (const auto &Feature : ParsedAttrs.Features) {
3517 auto CurFeature = StringRef(Feature).drop_front(); // remove + or -.
3518 if (!Context.getTargetInfo().isValidFeatureName(CurFeature))
3519 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3520 << Unsupported << None << CurFeature << Target;
3521 }
3522
3523 TargetInfo::BranchProtectionInfo BPI;
3524 StringRef DiagMsg;
3525 if (ParsedAttrs.BranchProtection.empty())
3526 return false;
3527 if (!Context.getTargetInfo().validateBranchProtection(
3528 Spec: ParsedAttrs.BranchProtection, Arch: ParsedAttrs.CPU, BPI, Err&: DiagMsg)) {
3529 if (DiagMsg.empty())
3530 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3531 << Unsupported << None << "branch-protection" << Target;
3532 return Diag(LiteralLoc, diag::err_invalid_branch_protection_spec)
3533 << DiagMsg;
3534 }
3535 if (!DiagMsg.empty())
3536 Diag(LiteralLoc, diag::warn_unsupported_branch_protection_spec) << DiagMsg;
3537
3538 return false;
3539}
3540
3541static bool hasArmStreamingInterface(const FunctionDecl *FD) {
3542 if (const auto *T = FD->getType()->getAs<FunctionProtoType>())
3543 if (T->getAArch64SMEAttributes() & FunctionType::SME_PStateSMEnabledMask)
3544 return true;
3545 return false;
3546}
3547
3548// Check Target Version attrs
3549bool Sema::checkTargetVersionAttr(SourceLocation LiteralLoc, Decl *D,
3550 StringRef &AttrStr, bool &isDefault) {
3551 enum FirstParam { Unsupported };
3552 enum SecondParam { None };
3553 enum ThirdParam { Target, TargetClones, TargetVersion };
3554 if (AttrStr.trim() == "default")
3555 isDefault = true;
3556 llvm::SmallVector<StringRef, 8> Features;
3557 AttrStr.split(A&: Features, Separator: "+");
3558 for (auto &CurFeature : Features) {
3559 CurFeature = CurFeature.trim();
3560 if (CurFeature == "default")
3561 continue;
3562 if (!Context.getTargetInfo().validateCpuSupports(CurFeature))
3563 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3564 << Unsupported << None << CurFeature << TargetVersion;
3565 }
3566 if (hasArmStreamingInterface(cast<FunctionDecl>(D)))
3567 return Diag(LiteralLoc, diag::err_sme_streaming_cannot_be_multiversioned);
3568 return false;
3569}
3570
3571static void handleTargetVersionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3572 StringRef Str;
3573 SourceLocation LiteralLoc;
3574 bool isDefault = false;
3575 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str, ArgLocation: &LiteralLoc) ||
3576 S.checkTargetVersionAttr(LiteralLoc, D, AttrStr&: Str, isDefault))
3577 return;
3578 // Do not create default only target_version attribute
3579 if (!isDefault) {
3580 TargetVersionAttr *NewAttr =
3581 ::new (S.Context) TargetVersionAttr(S.Context, AL, Str);
3582 D->addAttr(A: NewAttr);
3583 }
3584}
3585
3586static void handleTargetAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3587 StringRef Str;
3588 SourceLocation LiteralLoc;
3589 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str, ArgLocation: &LiteralLoc) ||
3590 S.checkTargetAttr(LiteralLoc, AttrStr: Str))
3591 return;
3592
3593 TargetAttr *NewAttr = ::new (S.Context) TargetAttr(S.Context, AL, Str);
3594 D->addAttr(NewAttr);
3595}
3596
3597bool Sema::checkTargetClonesAttrString(
3598 SourceLocation LiteralLoc, StringRef Str, const StringLiteral *Literal,
3599 Decl *D, bool &HasDefault, bool &HasCommas, bool &HasNotDefault,
3600 SmallVectorImpl<SmallString<64>> &StringsBuffer) {
3601 enum FirstParam { Unsupported, Duplicate, Unknown };
3602 enum SecondParam { None, CPU, Tune };
3603 enum ThirdParam { Target, TargetClones };
3604 HasCommas = HasCommas || Str.contains(C: ',');
3605 const TargetInfo &TInfo = Context.getTargetInfo();
3606 // Warn on empty at the beginning of a string.
3607 if (Str.size() == 0)
3608 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3609 << Unsupported << None << "" << TargetClones;
3610
3611 std::pair<StringRef, StringRef> Parts = {{}, Str};
3612 while (!Parts.second.empty()) {
3613 Parts = Parts.second.split(Separator: ',');
3614 StringRef Cur = Parts.first.trim();
3615 SourceLocation CurLoc =
3616 Literal->getLocationOfByte(ByteNo: Cur.data() - Literal->getString().data(),
3617 SM: getSourceManager(), Features: getLangOpts(), Target: TInfo);
3618
3619 bool DefaultIsDupe = false;
3620 bool HasCodeGenImpact = false;
3621 if (Cur.empty())
3622 return Diag(CurLoc, diag::warn_unsupported_target_attribute)
3623 << Unsupported << None << "" << TargetClones;
3624
3625 if (TInfo.getTriple().isAArch64()) {
3626 // AArch64 target clones specific
3627 if (Cur == "default") {
3628 DefaultIsDupe = HasDefault;
3629 HasDefault = true;
3630 if (llvm::is_contained(Range&: StringsBuffer, Element: Cur) || DefaultIsDupe)
3631 Diag(CurLoc, diag::warn_target_clone_duplicate_options);
3632 else
3633 StringsBuffer.push_back(Elt: Cur);
3634 } else {
3635 std::pair<StringRef, StringRef> CurParts = {{}, Cur};
3636 llvm::SmallVector<StringRef, 8> CurFeatures;
3637 while (!CurParts.second.empty()) {
3638 CurParts = CurParts.second.split(Separator: '+');
3639 StringRef CurFeature = CurParts.first.trim();
3640 if (!TInfo.validateCpuSupports(Name: CurFeature)) {
3641 Diag(CurLoc, diag::warn_unsupported_target_attribute)
3642 << Unsupported << None << CurFeature << TargetClones;
3643 continue;
3644 }
3645 if (TInfo.doesFeatureAffectCodeGen(Feature: CurFeature))
3646 HasCodeGenImpact = true;
3647 CurFeatures.push_back(Elt: CurFeature);
3648 }
3649 // Canonize TargetClones Attributes
3650 llvm::sort(C&: CurFeatures);
3651 SmallString<64> Res;
3652 for (auto &CurFeat : CurFeatures) {
3653 if (!Res.equals(RHS: ""))
3654 Res.append(RHS: "+");
3655 Res.append(RHS: CurFeat);
3656 }
3657 if (llvm::is_contained(Range&: StringsBuffer, Element: Res) || DefaultIsDupe)
3658 Diag(CurLoc, diag::warn_target_clone_duplicate_options);
3659 else if (!HasCodeGenImpact)
3660 // Ignore features in target_clone attribute that don't impact
3661 // code generation
3662 Diag(CurLoc, diag::warn_target_clone_no_impact_options);
3663 else if (!Res.empty()) {
3664 StringsBuffer.push_back(Elt: Res);
3665 HasNotDefault = true;
3666 }
3667 }
3668 if (hasArmStreamingInterface(cast<FunctionDecl>(D)))
3669 return Diag(LiteralLoc,
3670 diag::err_sme_streaming_cannot_be_multiversioned);
3671 } else {
3672 // Other targets ( currently X86 )
3673 if (Cur.starts_with(Prefix: "arch=")) {
3674 if (!Context.getTargetInfo().isValidCPUName(
3675 Cur.drop_front(sizeof("arch=") - 1)))
3676 return Diag(CurLoc, diag::warn_unsupported_target_attribute)
3677 << Unsupported << CPU << Cur.drop_front(sizeof("arch=") - 1)
3678 << TargetClones;
3679 } else if (Cur == "default") {
3680 DefaultIsDupe = HasDefault;
3681 HasDefault = true;
3682 } else if (!Context.getTargetInfo().isValidFeatureName(Cur))
3683 return Diag(CurLoc, diag::warn_unsupported_target_attribute)
3684 << Unsupported << None << Cur << TargetClones;
3685 if (llvm::is_contained(StringsBuffer, Cur) || DefaultIsDupe)
3686 Diag(CurLoc, diag::warn_target_clone_duplicate_options);
3687 // Note: Add even if there are duplicates, since it changes name mangling.
3688 StringsBuffer.push_back(Elt: Cur);
3689 }
3690 }
3691 if (Str.rtrim().ends_with(","))
3692 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3693 << Unsupported << None << "" << TargetClones;
3694 return false;
3695}
3696
3697static void handleTargetClonesAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3698 if (S.Context.getTargetInfo().getTriple().isAArch64() &&
3699 !S.Context.getTargetInfo().hasFeature(Feature: "fmv"))
3700 return;
3701
3702 // Ensure we don't combine these with themselves, since that causes some
3703 // confusing behavior.
3704 if (const auto *Other = D->getAttr<TargetClonesAttr>()) {
3705 S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL;
3706 S.Diag(Other->getLocation(), diag::note_conflicting_attribute);
3707 return;
3708 }
3709 if (checkAttrMutualExclusion<TargetClonesAttr>(S, D, AL))
3710 return;
3711
3712 SmallVector<StringRef, 2> Strings;
3713 SmallVector<SmallString<64>, 2> StringsBuffer;
3714 bool HasCommas = false, HasDefault = false, HasNotDefault = false;
3715
3716 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
3717 StringRef CurStr;
3718 SourceLocation LiteralLoc;
3719 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: I, Str&: CurStr, ArgLocation: &LiteralLoc) ||
3720 S.checkTargetClonesAttrString(
3721 LiteralLoc, Str: CurStr,
3722 Literal: cast<StringLiteral>(Val: AL.getArgAsExpr(Arg: I)->IgnoreParenCasts()), D,
3723 HasDefault, HasCommas, HasNotDefault, StringsBuffer))
3724 return;
3725 }
3726 for (auto &SmallStr : StringsBuffer)
3727 Strings.push_back(Elt: SmallStr.str());
3728
3729 if (HasCommas && AL.getNumArgs() > 1)
3730 S.Diag(AL.getLoc(), diag::warn_target_clone_mixed_values);
3731
3732 if (S.Context.getTargetInfo().getTriple().isAArch64() && !HasDefault) {
3733 // Add default attribute if there is no one
3734 HasDefault = true;
3735 Strings.push_back(Elt: "default");
3736 }
3737
3738 if (!HasDefault) {
3739 S.Diag(AL.getLoc(), diag::err_target_clone_must_have_default);
3740 return;
3741 }
3742
3743 // FIXME: We could probably figure out how to get this to work for lambdas
3744 // someday.
3745 if (const auto *MD = dyn_cast<CXXMethodDecl>(Val: D)) {
3746 if (MD->getParent()->isLambda()) {
3747 S.Diag(D->getLocation(), diag::err_multiversion_doesnt_support)
3748 << static_cast<unsigned>(MultiVersionKind::TargetClones)
3749 << /*Lambda*/ 9;
3750 return;
3751 }
3752 }
3753
3754 // No multiversion if we have default version only.
3755 if (S.Context.getTargetInfo().getTriple().isAArch64() && !HasNotDefault)
3756 return;
3757
3758 cast<FunctionDecl>(Val: D)->setIsMultiVersion();
3759 TargetClonesAttr *NewAttr = ::new (S.Context)
3760 TargetClonesAttr(S.Context, AL, Strings.data(), Strings.size());
3761 D->addAttr(A: NewAttr);
3762}
3763
3764static void handleMinVectorWidthAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3765 Expr *E = AL.getArgAsExpr(Arg: 0);
3766 uint32_t VecWidth;
3767 if (!checkUInt32Argument(S, AI: AL, Expr: E, Val&: VecWidth)) {
3768 AL.setInvalid();
3769 return;
3770 }
3771
3772 MinVectorWidthAttr *Existing = D->getAttr<MinVectorWidthAttr>();
3773 if (Existing && Existing->getVectorWidth() != VecWidth) {
3774 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3775 return;
3776 }
3777
3778 D->addAttr(::new (S.Context) MinVectorWidthAttr(S.Context, AL, VecWidth));
3779}
3780
3781static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3782 Expr *E = AL.getArgAsExpr(Arg: 0);
3783 SourceLocation Loc = E->getExprLoc();
3784 FunctionDecl *FD = nullptr;
3785 DeclarationNameInfo NI;
3786
3787 // gcc only allows for simple identifiers. Since we support more than gcc, we
3788 // will warn the user.
3789 if (auto *DRE = dyn_cast<DeclRefExpr>(Val: E)) {
3790 if (DRE->hasQualifier())
3791 S.Diag(Loc, diag::warn_cleanup_ext);
3792 FD = dyn_cast<FunctionDecl>(Val: DRE->getDecl());
3793 NI = DRE->getNameInfo();
3794 if (!FD) {
3795 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 1
3796 << NI.getName();
3797 return;
3798 }
3799 } else if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(Val: E)) {
3800 if (ULE->hasExplicitTemplateArgs())
3801 S.Diag(Loc, diag::warn_cleanup_ext);
3802 FD = S.ResolveSingleFunctionTemplateSpecialization(ULE, true);
3803 NI = ULE->getNameInfo();
3804 if (!FD) {
3805 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 2
3806 << NI.getName();
3807 if (ULE->getType() == S.Context.OverloadTy)
3808 S.NoteAllOverloadCandidates(ULE);
3809 return;
3810 }
3811 } else {
3812 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 0;
3813 return;
3814 }
3815
3816 if (FD->getNumParams() != 1) {
3817 S.Diag(Loc, diag::err_attribute_cleanup_func_must_take_one_arg)
3818 << NI.getName();
3819 return;
3820 }
3821
3822 // We're currently more strict than GCC about what function types we accept.
3823 // If this ever proves to be a problem it should be easy to fix.
3824 QualType Ty = S.Context.getPointerType(cast<VarDecl>(Val: D)->getType());
3825 QualType ParamTy = FD->getParamDecl(i: 0)->getType();
3826 if (S.CheckAssignmentConstraints(FD->getParamDecl(i: 0)->getLocation(),
3827 ParamTy, Ty) != Sema::Compatible) {
3828 S.Diag(Loc, diag::err_attribute_cleanup_func_arg_incompatible_type)
3829 << NI.getName() << ParamTy << Ty;
3830 return;
3831 }
3832 VarDecl *VD = cast<VarDecl>(Val: D);
3833 // Create a reference to the variable declaration. This is a fake/dummy
3834 // reference.
3835 DeclRefExpr *VariableReference = DeclRefExpr::Create(
3836 S.Context, NestedNameSpecifierLoc{}, FD->getLocation(), VD, false,
3837 DeclarationNameInfo{VD->getDeclName(), VD->getLocation()}, VD->getType(),
3838 VK_LValue);
3839
3840 // Create a unary operator expression that represents taking the address of
3841 // the variable. This is a fake/dummy expression.
3842 Expr *AddressOfVariable = UnaryOperator::Create(
3843 C: S.Context, input: VariableReference, opc: UnaryOperatorKind::UO_AddrOf,
3844 type: S.Context.getPointerType(VD->getType()), VK: VK_PRValue, OK: OK_Ordinary, l: Loc,
3845 CanOverflow: +false, FPFeatures: FPOptionsOverride{});
3846
3847 // Create a function call expression. This is a fake/dummy call expression.
3848 CallExpr *FunctionCallExpression =
3849 CallExpr::Create(Ctx: S.Context, Fn: E, Args: ArrayRef{AddressOfVariable},
3850 Ty: S.Context.VoidTy, VK: VK_PRValue, RParenLoc: Loc, FPFeatures: FPOptionsOverride{});
3851
3852 if (S.CheckFunctionCall(FDecl: FD, TheCall: FunctionCallExpression,
3853 Proto: FD->getType()->getAs<FunctionProtoType>())) {
3854 return;
3855 }
3856
3857 D->addAttr(::new (S.Context) CleanupAttr(S.Context, AL, FD));
3858}
3859
3860static void handleEnumExtensibilityAttr(Sema &S, Decl *D,
3861 const ParsedAttr &AL) {
3862 if (!AL.isArgIdent(Arg: 0)) {
3863 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3864 << AL << 0 << AANT_ArgumentIdentifier;
3865 return;
3866 }
3867
3868 EnumExtensibilityAttr::Kind ExtensibilityKind;
3869 IdentifierInfo *II = AL.getArgAsIdent(Arg: 0)->Ident;
3870 if (!EnumExtensibilityAttr::ConvertStrToKind(II->getName(),
3871 ExtensibilityKind)) {
3872 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
3873 return;
3874 }
3875
3876 D->addAttr(::new (S.Context)
3877 EnumExtensibilityAttr(S.Context, AL, ExtensibilityKind));
3878}
3879
3880/// Handle __attribute__((format_arg((idx)))) attribute based on
3881/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
3882static void handleFormatArgAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3883 const Expr *IdxExpr = AL.getArgAsExpr(Arg: 0);
3884 ParamIdx Idx;
3885 if (!checkFunctionOrMethodParameterIndex(S, D, AI: AL, AttrArgNum: 1, IdxExpr, Idx))
3886 return;
3887
3888 // Make sure the format string is really a string.
3889 QualType Ty = getFunctionOrMethodParamType(D, Idx: Idx.getASTIndex());
3890
3891 bool NotNSStringTy = !isNSStringType(T: Ty, Ctx&: S.Context);
3892 if (NotNSStringTy &&
3893 !isCFStringType(T: Ty, Ctx&: S.Context) &&
3894 (!Ty->isPointerType() ||
3895 !Ty->castAs<PointerType>()->getPointeeType()->isCharType())) {
3896 S.Diag(AL.getLoc(), diag::err_format_attribute_not)
3897 << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0);
3898 return;
3899 }
3900 Ty = getFunctionOrMethodResultType(D);
3901 // replace instancetype with the class type
3902 auto Instancetype = S.Context.getObjCInstanceTypeDecl()->getTypeForDecl();
3903 if (Ty->getAs<TypedefType>() == Instancetype)
3904 if (auto *OMD = dyn_cast<ObjCMethodDecl>(Val: D))
3905 if (auto *Interface = OMD->getClassInterface())
3906 Ty = S.Context.getObjCObjectPointerType(
3907 OIT: QualType(Interface->getTypeForDecl(), 0));
3908 if (!isNSStringType(T: Ty, Ctx&: S.Context, /*AllowNSAttributedString=*/true) &&
3909 !isCFStringType(T: Ty, Ctx&: S.Context) &&
3910 (!Ty->isPointerType() ||
3911 !Ty->castAs<PointerType>()->getPointeeType()->isCharType())) {
3912 S.Diag(AL.getLoc(), diag::err_format_attribute_result_not)
3913 << (NotNSStringTy ? "string type" : "NSString")
3914 << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0);
3915 return;
3916 }
3917
3918 D->addAttr(::new (S.Context) FormatArgAttr(S.Context, AL, Idx));
3919}
3920
3921enum FormatAttrKind {
3922 CFStringFormat,
3923 NSStringFormat,
3924 StrftimeFormat,
3925 SupportedFormat,
3926 IgnoredFormat,
3927 InvalidFormat
3928};
3929
3930/// getFormatAttrKind - Map from format attribute names to supported format
3931/// types.
3932static FormatAttrKind getFormatAttrKind(StringRef Format) {
3933 return llvm::StringSwitch<FormatAttrKind>(Format)
3934 // Check for formats that get handled specially.
3935 .Case(S: "NSString", Value: NSStringFormat)
3936 .Case(S: "CFString", Value: CFStringFormat)
3937 .Case(S: "strftime", Value: StrftimeFormat)
3938
3939 // Otherwise, check for supported formats.
3940 .Cases(S0: "scanf", S1: "printf", S2: "printf0", S3: "strfmon", Value: SupportedFormat)
3941 .Cases(S0: "cmn_err", S1: "vcmn_err", S2: "zcmn_err", Value: SupportedFormat)
3942 .Case(S: "kprintf", Value: SupportedFormat) // OpenBSD.
3943 .Case(S: "freebsd_kprintf", Value: SupportedFormat) // FreeBSD.
3944 .Case(S: "os_trace", Value: SupportedFormat)
3945 .Case(S: "os_log", Value: SupportedFormat)
3946
3947 .Cases(S0: "gcc_diag", S1: "gcc_cdiag", S2: "gcc_cxxdiag", S3: "gcc_tdiag", Value: IgnoredFormat)
3948 .Default(Value: InvalidFormat);
3949}
3950
3951/// Handle __attribute__((init_priority(priority))) attributes based on
3952/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
3953static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3954 if (!S.getLangOpts().CPlusPlus) {
3955 S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
3956 return;
3957 }
3958
3959 if (S.getLangOpts().HLSL) {
3960 S.Diag(AL.getLoc(), diag::err_hlsl_init_priority_unsupported);
3961 return;
3962 }
3963
3964 if (S.getCurFunctionOrMethodDecl()) {
3965 S.Diag(AL.getLoc(), diag::err_init_priority_object_attr);
3966 AL.setInvalid();
3967 return;
3968 }
3969 QualType T = cast<VarDecl>(Val: D)->getType();
3970 if (S.Context.getAsArrayType(T))
3971 T = S.Context.getBaseElementType(QT: T);
3972 if (!T->getAs<RecordType>()) {
3973 S.Diag(AL.getLoc(), diag::err_init_priority_object_attr);
3974 AL.setInvalid();
3975 return;
3976 }
3977
3978 Expr *E = AL.getArgAsExpr(Arg: 0);
3979 uint32_t prioritynum;
3980 if (!checkUInt32Argument(S, AI: AL, Expr: E, Val&: prioritynum)) {
3981 AL.setInvalid();
3982 return;
3983 }
3984
3985 // Only perform the priority check if the attribute is outside of a system
3986 // header. Values <= 100 are reserved for the implementation, and libc++
3987 // benefits from being able to specify values in that range.
3988 if ((prioritynum < 101 || prioritynum > 65535) &&
3989 !S.getSourceManager().isInSystemHeader(Loc: AL.getLoc())) {
3990 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_range)
3991 << E->getSourceRange() << AL << 101 << 65535;
3992 AL.setInvalid();
3993 return;
3994 }
3995 D->addAttr(::new (S.Context) InitPriorityAttr(S.Context, AL, prioritynum));
3996}
3997
3998ErrorAttr *Sema::mergeErrorAttr(Decl *D, const AttributeCommonInfo &CI,
3999 StringRef NewUserDiagnostic) {
4000 if (const auto *EA = D->getAttr<ErrorAttr>()) {
4001 std::string NewAttr = CI.getNormalizedFullName();
4002 assert((NewAttr == "error" || NewAttr == "warning") &&
4003 "unexpected normalized full name");
4004 bool Match = (EA->isError() && NewAttr == "error") ||
4005 (EA->isWarning() && NewAttr == "warning");
4006 if (!Match) {
4007 Diag(EA->getLocation(), diag::err_attributes_are_not_compatible)
4008 << CI << EA
4009 << (CI.isRegularKeywordAttribute() ||
4010 EA->isRegularKeywordAttribute());
4011 Diag(CI.getLoc(), diag::note_conflicting_attribute);
4012 return nullptr;
4013 }
4014 if (EA->getUserDiagnostic() != NewUserDiagnostic) {
4015 Diag(CI.getLoc(), diag::warn_duplicate_attribute) << EA;
4016 Diag(EA->getLoc(), diag::note_previous_attribute);
4017 }
4018 D->dropAttr<ErrorAttr>();
4019 }
4020 return ::new (Context) ErrorAttr(Context, CI, NewUserDiagnostic);
4021}
4022
4023FormatAttr *Sema::mergeFormatAttr(Decl *D, const AttributeCommonInfo &CI,
4024 IdentifierInfo *Format, int FormatIdx,
4025 int FirstArg) {
4026 // Check whether we already have an equivalent format attribute.
4027 for (auto *F : D->specific_attrs<FormatAttr>()) {
4028 if (F->getType() == Format &&
4029 F->getFormatIdx() == FormatIdx &&
4030 F->getFirstArg() == FirstArg) {
4031 // If we don't have a valid location for this attribute, adopt the
4032 // location.
4033 if (F->getLocation().isInvalid())
4034 F->setRange(CI.getRange());
4035 return nullptr;
4036 }
4037 }
4038
4039 return ::new (Context) FormatAttr(Context, CI, Format, FormatIdx, FirstArg);
4040}
4041
4042/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
4043/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
4044static void handleFormatAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4045 if (!AL.isArgIdent(Arg: 0)) {
4046 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
4047 << AL << 1 << AANT_ArgumentIdentifier;
4048 return;
4049 }
4050
4051 // In C++ the implicit 'this' function parameter also counts, and they are
4052 // counted from one.
4053 bool HasImplicitThisParam = isInstanceMethod(D);
4054 unsigned NumArgs = getFunctionOrMethodNumParams(D) + HasImplicitThisParam;
4055
4056 IdentifierInfo *II = AL.getArgAsIdent(Arg: 0)->Ident;
4057 StringRef Format = II->getName();
4058
4059 if (normalizeName(AttrName&: Format)) {
4060 // If we've modified the string name, we need a new identifier for it.
4061 II = &S.Context.Idents.get(Name: Format);
4062 }
4063
4064 // Check for supported formats.
4065 FormatAttrKind Kind = getFormatAttrKind(Format);
4066
4067 if (Kind == IgnoredFormat)
4068 return;
4069
4070 if (Kind == InvalidFormat) {
4071 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
4072 << AL << II->getName();
4073 return;
4074 }
4075
4076 // checks for the 2nd argument
4077 Expr *IdxExpr = AL.getArgAsExpr(Arg: 1);
4078 uint32_t Idx;
4079 if (!checkUInt32Argument(S, AI: AL, Expr: IdxExpr, Val&: Idx, Idx: 2))
4080 return;
4081
4082 if (Idx < 1 || Idx > NumArgs) {
4083 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
4084 << AL << 2 << IdxExpr->getSourceRange();
4085 return;
4086 }
4087
4088 // FIXME: Do we need to bounds check?
4089 unsigned ArgIdx = Idx - 1;
4090
4091 if (HasImplicitThisParam) {
4092 if (ArgIdx == 0) {
4093 S.Diag(AL.getLoc(),
4094 diag::err_format_attribute_implicit_this_format_string)
4095 << IdxExpr->getSourceRange();
4096 return;
4097 }
4098 ArgIdx--;
4099 }
4100
4101 // make sure the format string is really a string
4102 QualType Ty = getFunctionOrMethodParamType(D, Idx: ArgIdx);
4103
4104 if (!isNSStringType(T: Ty, Ctx&: S.Context, AllowNSAttributedString: true) &&
4105 !isCFStringType(T: Ty, Ctx&: S.Context) &&
4106 (!Ty->isPointerType() ||
4107 !Ty->castAs<PointerType>()->getPointeeType()->isCharType())) {
4108 S.Diag(AL.getLoc(), diag::err_format_attribute_not)
4109 << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, ArgIdx);
4110 return;
4111 }
4112
4113 // check the 3rd argument
4114 Expr *FirstArgExpr = AL.getArgAsExpr(Arg: 2);
4115 uint32_t FirstArg;
4116 if (!checkUInt32Argument(S, AI: AL, Expr: FirstArgExpr, Val&: FirstArg, Idx: 3))
4117 return;
4118
4119 // FirstArg == 0 is is always valid.
4120 if (FirstArg != 0) {
4121 if (Kind == StrftimeFormat) {
4122 // If the kind is strftime, FirstArg must be 0 because strftime does not
4123 // use any variadic arguments.
4124 S.Diag(AL.getLoc(), diag::err_format_strftime_third_parameter)
4125 << FirstArgExpr->getSourceRange()
4126 << FixItHint::CreateReplacement(FirstArgExpr->getSourceRange(), "0");
4127 return;
4128 } else if (isFunctionOrMethodVariadic(D)) {
4129 // Else, if the function is variadic, then FirstArg must be 0 or the
4130 // "position" of the ... parameter. It's unusual to use 0 with variadic
4131 // functions, so the fixit proposes the latter.
4132 if (FirstArg != NumArgs + 1) {
4133 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
4134 << AL << 3 << FirstArgExpr->getSourceRange()
4135 << FixItHint::CreateReplacement(FirstArgExpr->getSourceRange(),
4136 std::to_string(NumArgs + 1));
4137 return;
4138 }
4139 } else {
4140 // Inescapable GCC compatibility diagnostic.
4141 S.Diag(D->getLocation(), diag::warn_gcc_requires_variadic_function) << AL;
4142 if (FirstArg <= Idx) {
4143 // Else, the function is not variadic, and FirstArg must be 0 or any
4144 // parameter after the format parameter. We don't offer a fixit because
4145 // there are too many possible good values.
4146 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
4147 << AL << 3 << FirstArgExpr->getSourceRange();
4148 return;
4149 }
4150 }
4151 }
4152
4153 FormatAttr *NewAttr = S.mergeFormatAttr(D, CI: AL, Format: II, FormatIdx: Idx, FirstArg);
4154 if (NewAttr)
4155 D->addAttr(NewAttr);
4156}
4157
4158/// Handle __attribute__((callback(CalleeIdx, PayloadIdx0, ...))) attributes.
4159static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4160 // The index that identifies the callback callee is mandatory.
4161 if (AL.getNumArgs() == 0) {
4162 S.Diag(AL.getLoc(), diag::err_callback_attribute_no_callee)
4163 << AL.getRange();
4164 return;
4165 }
4166
4167 bool HasImplicitThisParam = isInstanceMethod(D);
4168 int32_t NumArgs = getFunctionOrMethodNumParams(D);
4169
4170 FunctionDecl *FD = D->getAsFunction();
4171 assert(FD && "Expected a function declaration!");
4172
4173 llvm::StringMap<int> NameIdxMapping;
4174 NameIdxMapping["__"] = -1;
4175
4176 NameIdxMapping["this"] = 0;
4177
4178 int Idx = 1;
4179 for (const ParmVarDecl *PVD : FD->parameters())
4180 NameIdxMapping[PVD->getName()] = Idx++;
4181
4182 auto UnknownName = NameIdxMapping.end();
4183
4184 SmallVector<int, 8> EncodingIndices;
4185 for (unsigned I = 0, E = AL.getNumArgs(); I < E; ++I) {
4186 SourceRange SR;
4187 int32_t ArgIdx;
4188
4189 if (AL.isArgIdent(Arg: I)) {
4190 IdentifierLoc *IdLoc = AL.getArgAsIdent(Arg: I);
4191 auto It = NameIdxMapping.find(Key: IdLoc->Ident->getName());
4192 if (It == UnknownName) {
4193 S.Diag(AL.getLoc(), diag::err_callback_attribute_argument_unknown)
4194 << IdLoc->Ident << IdLoc->Loc;
4195 return;
4196 }
4197
4198 SR = SourceRange(IdLoc->Loc);
4199 ArgIdx = It->second;
4200 } else if (AL.isArgExpr(Arg: I)) {
4201 Expr *IdxExpr = AL.getArgAsExpr(Arg: I);
4202
4203 // If the expression is not parseable as an int32_t we have a problem.
4204 if (!checkUInt32Argument(S, AI: AL, Expr: IdxExpr, Val&: (uint32_t &)ArgIdx, Idx: I + 1,
4205 StrictlyUnsigned: false)) {
4206 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
4207 << AL << (I + 1) << IdxExpr->getSourceRange();
4208 return;
4209 }
4210
4211 // Check oob, excluding the special values, 0 and -1.
4212 if (ArgIdx < -1 || ArgIdx > NumArgs) {
4213 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
4214 << AL << (I + 1) << IdxExpr->getSourceRange();
4215 return;
4216 }
4217
4218 SR = IdxExpr->getSourceRange();
4219 } else {
4220 llvm_unreachable("Unexpected ParsedAttr argument type!");
4221 }
4222
4223 if (ArgIdx == 0 && !HasImplicitThisParam) {
4224 S.Diag(AL.getLoc(), diag::err_callback_implicit_this_not_available)
4225 << (I + 1) << SR;
4226 return;
4227 }
4228
4229 // Adjust for the case we do not have an implicit "this" parameter. In this
4230 // case we decrease all positive values by 1 to get LLVM argument indices.
4231 if (!HasImplicitThisParam && ArgIdx > 0)
4232 ArgIdx -= 1;
4233
4234 EncodingIndices.push_back(Elt: ArgIdx);
4235 }
4236
4237 int CalleeIdx = EncodingIndices.front();
4238 // Check if the callee index is proper, thus not "this" and not "unknown".
4239 // This means the "CalleeIdx" has to be non-negative if "HasImplicitThisParam"
4240 // is false and positive if "HasImplicitThisParam" is true.
4241 if (CalleeIdx < (int)HasImplicitThisParam) {
4242 S.Diag(AL.getLoc(), diag::err_callback_attribute_invalid_callee)
4243 << AL.getRange();
4244 return;
4245 }
4246
4247 // Get the callee type, note the index adjustment as the AST doesn't contain
4248 // the this type (which the callee cannot reference anyway!).
4249 const Type *CalleeType =
4250 getFunctionOrMethodParamType(D, Idx: CalleeIdx - HasImplicitThisParam)
4251 .getTypePtr();
4252 if (!CalleeType || !CalleeType->isFunctionPointerType()) {
4253 S.Diag(AL.getLoc(), diag::err_callback_callee_no_function_type)
4254 << AL.getRange();
4255 return;
4256 }
4257
4258 const Type *CalleeFnType =
4259 CalleeType->getPointeeType()->getUnqualifiedDesugaredType();
4260
4261 // TODO: Check the type of the callee arguments.
4262
4263 const auto *CalleeFnProtoType = dyn_cast<FunctionProtoType>(Val: CalleeFnType);
4264 if (!CalleeFnProtoType) {
4265 S.Diag(AL.getLoc(), diag::err_callback_callee_no_function_type)
4266 << AL.getRange();
4267 return;
4268 }
4269
4270 if (CalleeFnProtoType->getNumParams() > EncodingIndices.size() - 1) {
4271 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
4272 << AL << (unsigned)(EncodingIndices.size() - 1);
4273 return;
4274 }
4275
4276 if (CalleeFnProtoType->getNumParams() < EncodingIndices.size() - 1) {
4277 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
4278 << AL << (unsigned)(EncodingIndices.size() - 1);
4279 return;
4280 }
4281
4282 if (CalleeFnProtoType->isVariadic()) {
4283 S.Diag(AL.getLoc(), diag::err_callback_callee_is_variadic) << AL.getRange();
4284 return;
4285 }
4286
4287 // Do not allow multiple callback attributes.
4288 if (D->hasAttr<CallbackAttr>()) {
4289 S.Diag(AL.getLoc(), diag::err_callback_attribute_multiple) << AL.getRange();
4290 return;
4291 }
4292
4293 D->addAttr(::new (S.Context) CallbackAttr(
4294 S.Context, AL, EncodingIndices.data(), EncodingIndices.size()));
4295}
4296
4297static bool isFunctionLike(const Type &T) {
4298 // Check for explicit function types.
4299 // 'called_once' is only supported in Objective-C and it has
4300 // function pointers and block pointers.
4301 return T.isFunctionPointerType() || T.isBlockPointerType();
4302}
4303
4304/// Handle 'called_once' attribute.
4305static void handleCalledOnceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4306 // 'called_once' only applies to parameters representing functions.
4307 QualType T = cast<ParmVarDecl>(Val: D)->getType();
4308
4309 if (!isFunctionLike(T: *T)) {
4310 S.Diag(AL.getLoc(), diag::err_called_once_attribute_wrong_type);
4311 return;
4312 }
4313
4314 D->addAttr(::new (S.Context) CalledOnceAttr(S.Context, AL));
4315}
4316
4317static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4318 // Try to find the underlying union declaration.
4319 RecordDecl *RD = nullptr;
4320 const auto *TD = dyn_cast<TypedefNameDecl>(Val: D);
4321 if (TD && TD->getUnderlyingType()->isUnionType())
4322 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
4323 else
4324 RD = dyn_cast<RecordDecl>(Val: D);
4325
4326 if (!RD || !RD->isUnion()) {
4327 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
4328 << AL << AL.isRegularKeywordAttribute() << ExpectedUnion;
4329 return;
4330 }
4331
4332 if (!RD->isCompleteDefinition()) {
4333 if (!RD->isBeingDefined())
4334 S.Diag(AL.getLoc(),
4335 diag::warn_transparent_union_attribute_not_definition);
4336 return;
4337 }
4338
4339 RecordDecl::field_iterator Field = RD->field_begin(),
4340 FieldEnd = RD->field_end();
4341 if (Field == FieldEnd) {
4342 S.Diag(AL.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
4343 return;
4344 }
4345
4346 FieldDecl *FirstField = *Field;
4347 QualType FirstType = FirstField->getType();
4348 if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
4349 S.Diag(FirstField->getLocation(),
4350 diag::warn_transparent_union_attribute_floating)
4351 << FirstType->isVectorType() << FirstType;
4352 return;
4353 }
4354
4355 if (FirstType->isIncompleteType())
4356 return;
4357 uint64_t FirstSize = S.Context.getTypeSize(T: FirstType);
4358 uint64_t FirstAlign = S.Context.getTypeAlign(T: FirstType);
4359 for (; Field != FieldEnd; ++Field) {
4360 QualType FieldType = Field->getType();
4361 if (FieldType->isIncompleteType())
4362 return;
4363 // FIXME: this isn't fully correct; we also need to test whether the
4364 // members of the union would all have the same calling convention as the
4365 // first member of the union. Checking just the size and alignment isn't
4366 // sufficient (consider structs passed on the stack instead of in registers
4367 // as an example).
4368 if (S.Context.getTypeSize(T: FieldType) != FirstSize ||
4369 S.Context.getTypeAlign(T: FieldType) > FirstAlign) {
4370 // Warn if we drop the attribute.
4371 bool isSize = S.Context.getTypeSize(T: FieldType) != FirstSize;
4372 unsigned FieldBits = isSize ? S.Context.getTypeSize(T: FieldType)
4373 : S.Context.getTypeAlign(T: FieldType);
4374 S.Diag(Field->getLocation(),
4375 diag::warn_transparent_union_attribute_field_size_align)
4376 << isSize << *Field << FieldBits;
4377 unsigned FirstBits = isSize ? FirstSize : FirstAlign;
4378 S.Diag(FirstField->getLocation(),
4379 diag::note_transparent_union_first_field_size_align)
4380 << isSize << FirstBits;
4381 return;
4382 }
4383 }
4384
4385 RD->addAttr(::new (S.Context) TransparentUnionAttr(S.Context, AL));
4386}
4387
4388void Sema::AddAnnotationAttr(Decl *D, const AttributeCommonInfo &CI,
4389 StringRef Str, MutableArrayRef<Expr *> Args) {
4390 auto *Attr = AnnotateAttr::Create(Context, Str, Args.data(), Args.size(), CI);
4391 if (ConstantFoldAttrArgs(
4392 CI, Args: MutableArrayRef<Expr *>(Attr->args_begin(), Attr->args_end()))) {
4393 D->addAttr(A: Attr);
4394 }
4395}
4396
4397static void handleAnnotateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4398 // Make sure that there is a string literal as the annotation's first
4399 // argument.
4400 StringRef Str;
4401 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str))
4402 return;
4403
4404 llvm::SmallVector<Expr *, 4> Args;
4405 Args.reserve(N: AL.getNumArgs() - 1);
4406 for (unsigned Idx = 1; Idx < AL.getNumArgs(); Idx++) {
4407 assert(!AL.isArgIdent(Idx));
4408 Args.push_back(Elt: AL.getArgAsExpr(Arg: Idx));
4409 }
4410
4411 S.AddAnnotationAttr(D, CI: AL, Str, Args);
4412}
4413
4414static void handleAlignValueAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4415 S.AddAlignValueAttr(D, CI: AL, E: AL.getArgAsExpr(Arg: 0));
4416}
4417
4418void Sema::AddAlignValueAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E) {
4419 AlignValueAttr TmpAttr(Context, CI, E);
4420 SourceLocation AttrLoc = CI.getLoc();
4421
4422 QualType T;
4423 if (const auto *TD = dyn_cast<TypedefNameDecl>(Val: D))
4424 T = TD->getUnderlyingType();
4425 else if (const auto *VD = dyn_cast<ValueDecl>(Val: D))
4426 T = VD->getType();
4427 else
4428 llvm_unreachable("Unknown decl type for align_value");
4429
4430 if (!T->isDependentType() && !T->isAnyPointerType() &&
4431 !T->isReferenceType() && !T->isMemberPointerType()) {
4432 Diag(AttrLoc, diag::warn_attribute_pointer_or_reference_only)
4433 << &TmpAttr << T << D->getSourceRange();
4434 return;
4435 }
4436
4437 if (!E->isValueDependent()) {
4438 llvm::APSInt Alignment;
4439 ExprResult ICE = VerifyIntegerConstantExpression(
4440 E, &Alignment, diag::err_align_value_attribute_argument_not_int);
4441 if (ICE.isInvalid())
4442 return;
4443
4444 if (!Alignment.isPowerOf2()) {
4445 Diag(AttrLoc, diag::err_alignment_not_power_of_two)
4446 << E->getSourceRange();
4447 return;
4448 }
4449
4450 D->addAttr(::new (Context) AlignValueAttr(Context, CI, ICE.get()));
4451 return;
4452 }
4453
4454 // Save dependent expressions in the AST to be instantiated.
4455 D->addAttr(::new (Context) AlignValueAttr(Context, CI, E));
4456}
4457
4458static void handleAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4459 if (AL.hasParsedType()) {
4460 const ParsedType &TypeArg = AL.getTypeArg();
4461 TypeSourceInfo *TInfo;
4462 (void)S.GetTypeFromParser(
4463 Ty: ParsedType::getFromOpaquePtr(P: TypeArg.getAsOpaquePtr()), TInfo: &TInfo);
4464 if (AL.isPackExpansion() &&
4465 !TInfo->getType()->containsUnexpandedParameterPack()) {
4466 S.Diag(AL.getEllipsisLoc(),
4467 diag::err_pack_expansion_without_parameter_packs);
4468 return;
4469 }
4470
4471 if (!AL.isPackExpansion() &&
4472 S.DiagnoseUnexpandedParameterPack(Loc: TInfo->getTypeLoc().getBeginLoc(),
4473 T: TInfo, UPPC: Sema::UPPC_Expression))
4474 return;
4475
4476 S.AddAlignedAttr(D, CI: AL, T: TInfo, IsPackExpansion: AL.isPackExpansion());
4477 return;
4478 }
4479
4480 // check the attribute arguments.
4481 if (AL.getNumArgs() > 1) {
4482 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
4483 return;
4484 }
4485
4486 if (AL.getNumArgs() == 0) {
4487 D->addAttr(::new (S.Context) AlignedAttr(S.Context, AL, true, nullptr));
4488 return;
4489 }
4490
4491 Expr *E = AL.getArgAsExpr(Arg: 0);
4492 if (AL.isPackExpansion() && !E->containsUnexpandedParameterPack()) {
4493 S.Diag(AL.getEllipsisLoc(),
4494 diag::err_pack_expansion_without_parameter_packs);
4495 return;
4496 }
4497
4498 if (!AL.isPackExpansion() && S.DiagnoseUnexpandedParameterPack(E))
4499 return;
4500
4501 S.AddAlignedAttr(D, CI: AL, E, IsPackExpansion: AL.isPackExpansion());
4502}
4503
4504/// Perform checking of type validity
4505///
4506/// C++11 [dcl.align]p1:
4507/// An alignment-specifier may be applied to a variable or to a class
4508/// data member, but it shall not be applied to a bit-field, a function
4509/// parameter, the formal parameter of a catch clause, or a variable
4510/// declared with the register storage class specifier. An
4511/// alignment-specifier may also be applied to the declaration of a class
4512/// or enumeration type.
4513/// CWG 2354:
4514/// CWG agreed to remove permission for alignas to be applied to
4515/// enumerations.
4516/// C11 6.7.5/2:
4517/// An alignment attribute shall not be specified in a declaration of
4518/// a typedef, or a bit-field, or a function, or a parameter, or an
4519/// object declared with the register storage-class specifier.
4520static bool validateAlignasAppliedType(Sema &S, Decl *D,
4521 const AlignedAttr &Attr,
4522 SourceLocation AttrLoc) {
4523 int DiagKind = -1;
4524 if (isa<ParmVarDecl>(Val: D)) {
4525 DiagKind = 0;
4526 } else if (const auto *VD = dyn_cast<VarDecl>(Val: D)) {
4527 if (VD->getStorageClass() == SC_Register)
4528 DiagKind = 1;
4529 if (VD->isExceptionVariable())
4530 DiagKind = 2;
4531 } else if (const auto *FD = dyn_cast<FieldDecl>(Val: D)) {
4532 if (FD->isBitField())
4533 DiagKind = 3;
4534 } else if (const auto *ED = dyn_cast<EnumDecl>(Val: D)) {
4535 if (ED->getLangOpts().CPlusPlus)
4536 DiagKind = 4;
4537 } else if (!isa<TagDecl>(Val: D)) {
4538 return S.Diag(AttrLoc, diag::err_attribute_wrong_decl_type)
4539 << &Attr << Attr.isRegularKeywordAttribute()
4540 << (Attr.isC11() ? ExpectedVariableOrField
4541 : ExpectedVariableFieldOrTag);
4542 }
4543 if (DiagKind != -1) {
4544 return S.Diag(AttrLoc, diag::err_alignas_attribute_wrong_decl_type)
4545 << &Attr << DiagKind;
4546 }
4547 return false;
4548}
4549
4550void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
4551 bool IsPackExpansion) {
4552 AlignedAttr TmpAttr(Context, CI, true, E);
4553 SourceLocation AttrLoc = CI.getLoc();
4554
4555 // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
4556 if (TmpAttr.isAlignas() &&
4557 validateAlignasAppliedType(*this, D, TmpAttr, AttrLoc))
4558 return;
4559
4560 if (E->isValueDependent()) {
4561 // We can't support a dependent alignment on a non-dependent type,
4562 // because we have no way to model that a type is "alignment-dependent"
4563 // but not dependent in any other way.
4564 if (const auto *TND = dyn_cast<TypedefNameDecl>(Val: D)) {
4565 if (!TND->getUnderlyingType()->isDependentType()) {
4566 Diag(AttrLoc, diag::err_alignment_dependent_typedef_name)
4567 << E->getSourceRange();
4568 return;
4569 }
4570 }
4571
4572 // Save dependent expressions in the AST to be instantiated.
4573 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, E);
4574 AA->setPackExpansion(IsPackExpansion);
4575 D->addAttr(A: AA);
4576 return;
4577 }
4578
4579 // FIXME: Cache the number on the AL object?
4580 llvm::APSInt Alignment;
4581 ExprResult ICE = VerifyIntegerConstantExpression(
4582 E, &Alignment, diag::err_aligned_attribute_argument_not_int);
4583 if (ICE.isInvalid())
4584 return;
4585
4586 uint64_t MaximumAlignment = Sema::MaximumAlignment;
4587 if (Context.getTargetInfo().getTriple().isOSBinFormatCOFF())
4588 MaximumAlignment = std::min(a: MaximumAlignment, b: uint64_t(8192));
4589 if (Alignment > MaximumAlignment) {
4590 Diag(AttrLoc, diag::err_attribute_aligned_too_great)
4591 << MaximumAlignment << E->getSourceRange();
4592 return;
4593 }
4594
4595 uint64_t AlignVal = Alignment.getZExtValue();
4596 // C++11 [dcl.align]p2:
4597 // -- if the constant expression evaluates to zero, the alignment
4598 // specifier shall have no effect
4599 // C11 6.7.5p6:
4600 // An alignment specification of zero has no effect.
4601 if (!(TmpAttr.isAlignas() && !Alignment)) {
4602 if (!llvm::isPowerOf2_64(Value: AlignVal)) {
4603 Diag(AttrLoc, diag::err_alignment_not_power_of_two)
4604 << E->getSourceRange();
4605 return;
4606 }
4607 }
4608
4609 const auto *VD = dyn_cast<VarDecl>(Val: D);
4610 if (VD) {
4611 unsigned MaxTLSAlign =
4612 Context.toCharUnitsFromBits(BitSize: Context.getTargetInfo().getMaxTLSAlign())
4613 .getQuantity();
4614 if (MaxTLSAlign && AlignVal > MaxTLSAlign &&
4615 VD->getTLSKind() != VarDecl::TLS_None) {
4616 Diag(VD->getLocation(), diag::err_tls_var_aligned_over_maximum)
4617 << (unsigned)AlignVal << VD << MaxTLSAlign;
4618 return;
4619 }
4620 }
4621
4622 // On AIX, an aligned attribute can not decrease the alignment when applied
4623 // to a variable declaration with vector type.
4624 if (VD && Context.getTargetInfo().getTriple().isOSAIX()) {
4625 const Type *Ty = VD->getType().getTypePtr();
4626 if (Ty->isVectorType() && AlignVal < 16) {
4627 Diag(VD->getLocation(), diag::warn_aligned_attr_underaligned)
4628 << VD->getType() << 16;
4629 return;
4630 }
4631 }
4632
4633 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, ICE.get());
4634 AA->setPackExpansion(IsPackExpansion);
4635 AA->setCachedAlignmentValue(
4636 static_cast<unsigned>(AlignVal * Context.getCharWidth()));
4637 D->addAttr(A: AA);
4638}
4639
4640void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI,
4641 TypeSourceInfo *TS, bool IsPackExpansion) {
4642 AlignedAttr TmpAttr(Context, CI, false, TS);
4643 SourceLocation AttrLoc = CI.getLoc();
4644
4645 // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
4646 if (TmpAttr.isAlignas() &&
4647 validateAlignasAppliedType(*this, D, TmpAttr, AttrLoc))
4648 return;
4649
4650 if (TS->getType()->isDependentType()) {
4651 // We can't support a dependent alignment on a non-dependent type,
4652 // because we have no way to model that a type is "type-dependent"
4653 // but not dependent in any other way.
4654 if (const auto *TND = dyn_cast<TypedefNameDecl>(Val: D)) {
4655 if (!TND->getUnderlyingType()->isDependentType()) {
4656 Diag(AttrLoc, diag::err_alignment_dependent_typedef_name)
4657 << TS->getTypeLoc().getSourceRange();
4658 return;
4659 }
4660 }
4661
4662 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, false, TS);
4663 AA->setPackExpansion(IsPackExpansion);
4664 D->addAttr(A: AA);
4665 return;
4666 }
4667
4668 const auto *VD = dyn_cast<VarDecl>(Val: D);
4669 unsigned AlignVal = TmpAttr.getAlignment(Context);
4670 // On AIX, an aligned attribute can not decrease the alignment when applied
4671 // to a variable declaration with vector type.
4672 if (VD && Context.getTargetInfo().getTriple().isOSAIX()) {
4673 const Type *Ty = VD->getType().getTypePtr();
4674 if (Ty->isVectorType() &&
4675 Context.toCharUnitsFromBits(BitSize: AlignVal).getQuantity() < 16) {
4676 Diag(VD->getLocation(), diag::warn_aligned_attr_underaligned)
4677 << VD->getType() << 16;
4678 return;
4679 }
4680 }
4681
4682 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, false, TS);
4683 AA->setPackExpansion(IsPackExpansion);
4684 AA->setCachedAlignmentValue(AlignVal);
4685 D->addAttr(A: AA);
4686}
4687
4688void Sema::CheckAlignasUnderalignment(Decl *D) {
4689 assert(D->hasAttrs() && "no attributes on decl");
4690
4691 QualType UnderlyingTy, DiagTy;
4692 if (const auto *VD = dyn_cast<ValueDecl>(Val: D)) {
4693 UnderlyingTy = DiagTy = VD->getType();
4694 } else {
4695 UnderlyingTy = DiagTy = Context.getTagDeclType(Decl: cast<TagDecl>(Val: D));
4696 if (const auto *ED = dyn_cast<EnumDecl>(Val: D))
4697 UnderlyingTy = ED->getIntegerType();
4698 }
4699 if (DiagTy->isDependentType() || DiagTy->isIncompleteType())
4700 return;
4701
4702 // C++11 [dcl.align]p5, C11 6.7.5/4:
4703 // The combined effect of all alignment attributes in a declaration shall
4704 // not specify an alignment that is less strict than the alignment that
4705 // would otherwise be required for the entity being declared.
4706 AlignedAttr *AlignasAttr = nullptr;
4707 AlignedAttr *LastAlignedAttr = nullptr;
4708 unsigned Align = 0;
4709 for (auto *I : D->specific_attrs<AlignedAttr>()) {
4710 if (I->isAlignmentDependent())
4711 return;
4712 if (I->isAlignas())
4713 AlignasAttr = I;
4714 Align = std::max(Align, I->getAlignment(Context));
4715 LastAlignedAttr = I;
4716 }
4717
4718 if (Align && DiagTy->isSizelessType()) {
4719 Diag(LastAlignedAttr->getLocation(), diag::err_attribute_sizeless_type)
4720 << LastAlignedAttr << DiagTy;
4721 } else if (AlignasAttr && Align) {
4722 CharUnits RequestedAlign = Context.toCharUnitsFromBits(BitSize: Align);
4723 CharUnits NaturalAlign = Context.getTypeAlignInChars(T: UnderlyingTy);
4724 if (NaturalAlign > RequestedAlign)
4725 Diag(AlignasAttr->getLocation(), diag::err_alignas_underaligned)
4726 << DiagTy << (unsigned)NaturalAlign.getQuantity();
4727 }
4728}
4729
4730bool Sema::checkMSInheritanceAttrOnDefinition(
4731 CXXRecordDecl *RD, SourceRange Range, bool BestCase,
4732 MSInheritanceModel ExplicitModel) {
4733 assert(RD->hasDefinition() && "RD has no definition!");
4734
4735 // We may not have seen base specifiers or any virtual methods yet. We will
4736 // have to wait until the record is defined to catch any mismatches.
4737 if (!RD->getDefinition()->isCompleteDefinition())
4738 return false;
4739
4740 // The unspecified model never matches what a definition could need.
4741 if (ExplicitModel == MSInheritanceModel::Unspecified)
4742 return false;
4743
4744 if (BestCase) {
4745 if (RD->calculateInheritanceModel() == ExplicitModel)
4746 return false;
4747 } else {
4748 if (RD->calculateInheritanceModel() <= ExplicitModel)
4749 return false;
4750 }
4751
4752 Diag(Range.getBegin(), diag::err_mismatched_ms_inheritance)
4753 << 0 /*definition*/;
4754 Diag(RD->getDefinition()->getLocation(), diag::note_defined_here) << RD;
4755 return true;
4756}
4757
4758/// parseModeAttrArg - Parses attribute mode string and returns parsed type
4759/// attribute.
4760static void parseModeAttrArg(Sema &S, StringRef Str, unsigned &DestWidth,
4761 bool &IntegerMode, bool &ComplexMode,
4762 FloatModeKind &ExplicitType) {
4763 IntegerMode = true;
4764 ComplexMode = false;
4765 ExplicitType = FloatModeKind::NoFloat;
4766 switch (Str.size()) {
4767 case 2:
4768 switch (Str[0]) {
4769 case 'Q':
4770 DestWidth = 8;
4771 break;
4772 case 'H':
4773 DestWidth = 16;
4774 break;
4775 case 'S':
4776 DestWidth = 32;
4777 break;
4778 case 'D':
4779 DestWidth = 64;
4780 break;
4781 case 'X':
4782 DestWidth = 96;
4783 break;
4784 case 'K': // KFmode - IEEE quad precision (__float128)
4785 ExplicitType = FloatModeKind::Float128;
4786 DestWidth = Str[1] == 'I' ? 0 : 128;
4787 break;
4788 case 'T':
4789 ExplicitType = FloatModeKind::LongDouble;
4790 DestWidth = 128;
4791 break;
4792 case 'I':
4793 ExplicitType = FloatModeKind::Ibm128;
4794 DestWidth = Str[1] == 'I' ? 0 : 128;
4795 break;
4796 }
4797 if (Str[1] == 'F') {
4798 IntegerMode = false;
4799 } else if (Str[1] == 'C') {
4800 IntegerMode = false;
4801 ComplexMode = true;
4802 } else if (Str[1] != 'I') {
4803 DestWidth = 0;
4804 }
4805 break;
4806 case 4:
4807 // FIXME: glibc uses 'word' to define register_t; this is narrower than a
4808 // pointer on PIC16 and other embedded platforms.
4809 if (Str == "word")
4810 DestWidth = S.Context.getTargetInfo().getRegisterWidth();
4811 else if (Str == "byte")
4812 DestWidth = S.Context.getTargetInfo().getCharWidth();
4813 break;
4814 case 7:
4815 if (Str == "pointer")
4816 DestWidth = S.Context.getTargetInfo().getPointerWidth(AddrSpace: LangAS::Default);
4817 break;
4818 case 11:
4819 if (Str == "unwind_word")
4820 DestWidth = S.Context.getTargetInfo().getUnwindWordWidth();
4821 break;
4822 }
4823}
4824
4825/// handleModeAttr - This attribute modifies the width of a decl with primitive
4826/// type.
4827///
4828/// Despite what would be logical, the mode attribute is a decl attribute, not a
4829/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
4830/// HImode, not an intermediate pointer.
4831static void handleModeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4832 // This attribute isn't documented, but glibc uses it. It changes
4833 // the width of an int or unsigned int to the specified size.
4834 if (!AL.isArgIdent(Arg: 0)) {
4835 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
4836 << AL << AANT_ArgumentIdentifier;
4837 return;
4838 }
4839
4840 IdentifierInfo *Name = AL.getArgAsIdent(Arg: 0)->Ident;
4841
4842 S.AddModeAttr(D, CI: AL, Name);
4843}
4844
4845void Sema::AddModeAttr(Decl *D, const AttributeCommonInfo &CI,
4846 IdentifierInfo *Name, bool InInstantiation) {
4847 StringRef Str = Name->getName();
4848 normalizeName(AttrName&: Str);
4849 SourceLocation AttrLoc = CI.getLoc();
4850
4851 unsigned DestWidth = 0;
4852 bool IntegerMode = true;
4853 bool ComplexMode = false;
4854 FloatModeKind ExplicitType = FloatModeKind::NoFloat;
4855 llvm::APInt VectorSize(64, 0);
4856 if (Str.size() >= 4 && Str[0] == 'V') {
4857 // Minimal length of vector mode is 4: 'V' + NUMBER(>=1) + TYPE(>=2).
4858 size_t StrSize = Str.size();
4859 size_t VectorStringLength = 0;
4860 while ((VectorStringLength + 1) < StrSize &&
4861 isdigit(Str[VectorStringLength + 1]))
4862 ++VectorStringLength;
4863 if (VectorStringLength &&
4864 !Str.substr(Start: 1, N: VectorStringLength).getAsInteger(Radix: 10, Result&: VectorSize) &&
4865 VectorSize.isPowerOf2()) {
4866 parseModeAttrArg(S&: *this, Str: Str.substr(Start: VectorStringLength + 1), DestWidth,
4867 IntegerMode, ComplexMode, ExplicitType);
4868 // Avoid duplicate warning from template instantiation.
4869 if (!InInstantiation)
4870 Diag(AttrLoc, diag::warn_vector_mode_deprecated);
4871 } else {
4872 VectorSize = 0;
4873 }
4874 }
4875
4876 if (!VectorSize)
4877 parseModeAttrArg(S&: *this, Str, DestWidth, IntegerMode, ComplexMode,
4878 ExplicitType);
4879
4880 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
4881 // and friends, at least with glibc.
4882 // FIXME: Make sure floating-point mappings are accurate
4883 // FIXME: Support XF and TF types
4884 if (!DestWidth) {
4885 Diag(AttrLoc, diag::err_machine_mode) << 0 /*Unknown*/ << Name;
4886 return;
4887 }
4888
4889 QualType OldTy;
4890 if (const auto *TD = dyn_cast<TypedefNameDecl>(Val: D))
4891 OldTy = TD->getUnderlyingType();
4892 else if (const auto *ED = dyn_cast<EnumDecl>(Val: D)) {
4893 // Something like 'typedef enum { X } __attribute__((mode(XX))) T;'.
4894 // Try to get type from enum declaration, default to int.
4895 OldTy = ED->getIntegerType();
4896 if (OldTy.isNull())
4897 OldTy = Context.IntTy;
4898 } else
4899 OldTy = cast<ValueDecl>(Val: D)->getType();
4900
4901 if (OldTy->isDependentType()) {
4902 D->addAttr(::new (Context) ModeAttr(Context, CI, Name));
4903 return;
4904 }
4905
4906 // Base type can also be a vector type (see PR17453).
4907 // Distinguish between base type and base element type.
4908 QualType OldElemTy = OldTy;
4909 if (const auto *VT = OldTy->getAs<VectorType>())
4910 OldElemTy = VT->getElementType();
4911
4912 // GCC allows 'mode' attribute on enumeration types (even incomplete), except
4913 // for vector modes. So, 'enum X __attribute__((mode(QI)));' forms a complete
4914 // type, 'enum { A } __attribute__((mode(V4SI)))' is rejected.
4915 if ((isa<EnumDecl>(Val: D) || OldElemTy->getAs<EnumType>()) &&
4916 VectorSize.getBoolValue()) {
4917 Diag(AttrLoc, diag::err_enum_mode_vector_type) << Name << CI.getRange();
4918 return;
4919 }
4920 bool IntegralOrAnyEnumType = (OldElemTy->isIntegralOrEnumerationType() &&
4921 !OldElemTy->isBitIntType()) ||
4922 OldElemTy->getAs<EnumType>();
4923
4924 if (!OldElemTy->getAs<BuiltinType>() && !OldElemTy->isComplexType() &&
4925 !IntegralOrAnyEnumType)
4926 Diag(AttrLoc, diag::err_mode_not_primitive);
4927 else if (IntegerMode) {
4928 if (!IntegralOrAnyEnumType)
4929 Diag(AttrLoc, diag::err_mode_wrong_type);
4930 } else if (ComplexMode) {
4931 if (!OldElemTy->isComplexType())
4932 Diag(AttrLoc, diag::err_mode_wrong_type);
4933 } else {
4934 if (!OldElemTy->isFloatingType())
4935 Diag(AttrLoc, diag::err_mode_wrong_type);
4936 }
4937
4938 QualType NewElemTy;
4939
4940 if (IntegerMode)
4941 NewElemTy = Context.getIntTypeForBitwidth(DestWidth,
4942 Signed: OldElemTy->isSignedIntegerType());
4943 else
4944 NewElemTy = Context.getRealTypeForBitwidth(DestWidth, ExplicitType);
4945
4946 if (NewElemTy.isNull()) {
4947 // Only emit diagnostic on host for 128-bit mode attribute
4948 if (!(DestWidth == 128 && getLangOpts().CUDAIsDevice))
4949 Diag(AttrLoc, diag::err_machine_mode) << 1 /*Unsupported*/ << Name;
4950 return;
4951 }
4952
4953 if (ComplexMode) {
4954 NewElemTy = Context.getComplexType(T: NewElemTy);
4955 }
4956
4957 QualType NewTy = NewElemTy;
4958 if (VectorSize.getBoolValue()) {
4959 NewTy = Context.getVectorType(VectorType: NewTy, NumElts: VectorSize.getZExtValue(),
4960 VecKind: VectorKind::Generic);
4961 } else if (const auto *OldVT = OldTy->getAs<VectorType>()) {
4962 // Complex machine mode does not support base vector types.
4963 if (ComplexMode) {
4964 Diag(AttrLoc, diag::err_complex_mode_vector_type);
4965 return;
4966 }
4967 unsigned NumElements = Context.getTypeSize(T: OldElemTy) *
4968 OldVT->getNumElements() /
4969 Context.getTypeSize(T: NewElemTy);
4970 NewTy =
4971 Context.getVectorType(VectorType: NewElemTy, NumElts: NumElements, VecKind: OldVT->getVectorKind());
4972 }
4973
4974 if (NewTy.isNull()) {
4975 Diag(AttrLoc, diag::err_mode_wrong_type);
4976 return;
4977 }
4978
4979 // Install the new type.
4980 if (auto *TD = dyn_cast<TypedefNameDecl>(Val: D))
4981 TD->setModedTypeSourceInfo(unmodedTSI: TD->getTypeSourceInfo(), modedTy: NewTy);
4982 else if (auto *ED = dyn_cast<EnumDecl>(Val: D))
4983 ED->setIntegerType(NewTy);
4984 else
4985 cast<ValueDecl>(Val: D)->setType(NewTy);
4986
4987 D->addAttr(::new (Context) ModeAttr(Context, CI, Name));
4988}
4989
4990static void handleNoDebugAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4991 D->addAttr(::new (S.Context) NoDebugAttr(S.Context, AL));
4992}
4993
4994AlwaysInlineAttr *Sema::mergeAlwaysInlineAttr(Decl *D,
4995 const AttributeCommonInfo &CI,
4996 const IdentifierInfo *Ident) {
4997 if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
4998 Diag(CI.getLoc(), diag::warn_attribute_ignored) << Ident;
4999 Diag(Optnone->getLocation(), diag::note_conflicting_attribute);
5000 return nullptr;
5001 }
5002
5003 if (D->hasAttr<AlwaysInlineAttr>())
5004 return nullptr;
5005
5006 return ::new (Context) AlwaysInlineAttr(Context, CI);
5007}
5008
5009InternalLinkageAttr *Sema::mergeInternalLinkageAttr(Decl *D,
5010 const ParsedAttr &AL) {
5011 if (const auto *VD = dyn_cast<VarDecl>(Val: D)) {
5012 // Attribute applies to Var but not any subclass of it (like ParmVar,
5013 // ImplicitParm or VarTemplateSpecialization).
5014 if (VD->getKind() != Decl::Var) {
5015 Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
5016 << AL << AL.isRegularKeywordAttribute()
5017 << (getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass
5018 : ExpectedVariableOrFunction);
5019 return nullptr;
5020 }
5021 // Attribute does not apply to non-static local variables.
5022 if (VD->hasLocalStorage()) {
5023 Diag(VD->getLocation(), diag::warn_internal_linkage_local_storage);
5024 return nullptr;
5025 }
5026 }
5027
5028 return ::new (Context) InternalLinkageAttr(Context, AL);
5029}
5030InternalLinkageAttr *
5031Sema::mergeInternalLinkageAttr(Decl *D, const InternalLinkageAttr &AL) {
5032 if (const auto *VD = dyn_cast<VarDecl>(Val: D)) {
5033 // Attribute applies to Var but not any subclass of it (like ParmVar,
5034 // ImplicitParm or VarTemplateSpecialization).
5035 if (VD->getKind() != Decl::Var) {
5036 Diag(AL.getLocation(), diag::warn_attribute_wrong_decl_type)
5037 << &AL << AL.isRegularKeywordAttribute()
5038 << (getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass
5039 : ExpectedVariableOrFunction);
5040 return nullptr;
5041 }
5042 // Attribute does not apply to non-static local variables.
5043 if (VD->hasLocalStorage()) {
5044 Diag(VD->getLocation(), diag::warn_internal_linkage_local_storage);
5045 return nullptr;
5046 }
5047 }
5048
5049 return ::new (Context) InternalLinkageAttr(Context, AL);
5050}
5051
5052MinSizeAttr *Sema::mergeMinSizeAttr(Decl *D, const AttributeCommonInfo &CI) {
5053 if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
5054 Diag(CI.getLoc(), diag::warn_attribute_ignored) << "'minsize'";
5055 Diag(Optnone->getLocation(), diag::note_conflicting_attribute);
5056 return nullptr;
5057 }
5058
5059 if (D->hasAttr<MinSizeAttr>())
5060 return nullptr;
5061
5062 return ::new (Context) MinSizeAttr(Context, CI);
5063}
5064
5065SwiftNameAttr *Sema::mergeSwiftNameAttr(Decl *D, const SwiftNameAttr &SNA,
5066 StringRef Name) {
5067 if (const auto *PrevSNA = D->getAttr<SwiftNameAttr>()) {
5068 if (PrevSNA->getName() != Name && !PrevSNA->isImplicit()) {
5069 Diag(PrevSNA->getLocation(), diag::err_attributes_are_not_compatible)
5070 << PrevSNA << &SNA
5071 << (PrevSNA->isRegularKeywordAttribute() ||
5072 SNA.isRegularKeywordAttribute());
5073 Diag(SNA.getLoc(), diag::note_conflicting_attribute);
5074 }
5075
5076 D->dropAttr<SwiftNameAttr>();
5077 }
5078 return ::new (Context) SwiftNameAttr(Context, SNA, Name);
5079}
5080
5081OptimizeNoneAttr *Sema::mergeOptimizeNoneAttr(Decl *D,
5082 const AttributeCommonInfo &CI) {
5083 if (AlwaysInlineAttr *Inline = D->getAttr<AlwaysInlineAttr>()) {
5084 Diag(Inline->getLocation(), diag::warn_attribute_ignored) << Inline;
5085 Diag(CI.getLoc(), diag::note_conflicting_attribute);
5086 D->dropAttr<AlwaysInlineAttr>();
5087 }
5088 if (MinSizeAttr *MinSize = D->getAttr<MinSizeAttr>()) {
5089 Diag(MinSize->getLocation(), diag::warn_attribute_ignored) << MinSize;
5090 Diag(CI.getLoc(), diag::note_conflicting_attribute);
5091 D->dropAttr<MinSizeAttr>();
5092 }
5093
5094 if (D->hasAttr<OptimizeNoneAttr>())
5095 return nullptr;
5096
5097 return ::new (Context) OptimizeNoneAttr(Context, CI);
5098}
5099
5100static void handleAlwaysInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5101 if (AlwaysInlineAttr *Inline =
5102 S.mergeAlwaysInlineAttr(D, AL, AL.getAttrName()))
5103 D->addAttr(Inline);
5104}
5105
5106static void handleMinSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5107 if (MinSizeAttr *MinSize = S.mergeMinSizeAttr(D, AL))
5108 D->addAttr(MinSize);
5109}
5110
5111static void handleOptimizeNoneAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5112 if (OptimizeNoneAttr *Optnone = S.mergeOptimizeNoneAttr(D, AL))
5113 D->addAttr(Optnone);
5114}
5115
5116static void handleConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5117 const auto *VD = cast<VarDecl>(Val: D);
5118 if (VD->hasLocalStorage()) {
5119 S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
5120 return;
5121 }
5122 // constexpr variable may already get an implicit constant attr, which should
5123 // be replaced by the explicit constant attr.
5124 if (auto *A = D->getAttr<CUDAConstantAttr>()) {
5125 if (!A->isImplicit())
5126 return;
5127 D->dropAttr<CUDAConstantAttr>();
5128 }
5129 D->addAttr(::new (S.Context) CUDAConstantAttr(S.Context, AL));
5130}
5131
5132static void handleSharedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5133 const auto *VD = cast<VarDecl>(Val: D);
5134 // extern __shared__ is only allowed on arrays with no length (e.g.
5135 // "int x[]").
5136 if (!S.getLangOpts().GPURelocatableDeviceCode && VD->hasExternalStorage() &&
5137 !isa<IncompleteArrayType>(VD->getType())) {
5138 S.Diag(AL.getLoc(), diag::err_cuda_extern_shared) << VD;
5139 return;
5140 }
5141 if (S.getLangOpts().CUDA && VD->hasLocalStorage() &&
5142 S.CUDA().DiagIfHostCode(AL.getLoc(), diag::err_cuda_host_shared)
5143 << llvm::to_underlying(S.CUDA().CurrentTarget()))
5144 return;
5145 D->addAttr(::new (S.Context) CUDASharedAttr(S.Context, AL));
5146}
5147
5148static void handleGlobalAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5149 const auto *FD = cast<FunctionDecl>(Val: D);
5150 if (!FD->getReturnType()->isVoidType() &&
5151 !FD->getReturnType()->getAs<AutoType>() &&
5152 !FD->getReturnType()->isInstantiationDependentType()) {
5153 SourceRange RTRange = FD->getReturnTypeSourceRange();
5154 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
5155 << FD->getType()
5156 << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void")
5157 : FixItHint());
5158 return;
5159 }
5160 if (const auto *Method = dyn_cast<CXXMethodDecl>(Val: FD)) {
5161 if (Method->isInstance()) {
5162 S.Diag(Method->getBeginLoc(), diag::err_kern_is_nonstatic_method)
5163 << Method;
5164 return;
5165 }
5166 S.Diag(Method->getBeginLoc(), diag::warn_kern_is_method) << Method;
5167 }
5168 // Only warn for "inline" when compiling for host, to cut down on noise.
5169 if (FD->isInlineSpecified() && !S.getLangOpts().CUDAIsDevice)
5170 S.Diag(FD->getBeginLoc(), diag::warn_kern_is_inline) << FD;
5171
5172 if (AL.getKind() == ParsedAttr::AT_NVPTXKernel)
5173 D->addAttr(::new (S.Context) NVPTXKernelAttr(S.Context, AL));
5174 else
5175 D->addAttr(::new (S.Context) CUDAGlobalAttr(S.Context, AL));
5176 // In host compilation the kernel is emitted as a stub function, which is
5177 // a helper function for launching the kernel. The instructions in the helper
5178 // function has nothing to do with the source code of the kernel. Do not emit
5179 // debug info for the stub function to avoid confusing the debugger.
5180 if (S.LangOpts.HIP && !S.LangOpts.CUDAIsDevice)
5181 D->addAttr(NoDebugAttr::CreateImplicit(S.Context));
5182}
5183
5184static void handleDeviceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5185 if (const auto *VD = dyn_cast<VarDecl>(Val: D)) {
5186 if (VD->hasLocalStorage()) {
5187 S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
5188 return;
5189 }
5190 }
5191
5192 if (auto *A = D->getAttr<CUDADeviceAttr>()) {
5193 if (!A->isImplicit())
5194 return;
5195 D->dropAttr<CUDADeviceAttr>();
5196 }
5197 D->addAttr(::new (S.Context) CUDADeviceAttr(S.Context, AL));
5198}
5199
5200static void handleManagedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5201 if (const auto *VD = dyn_cast<VarDecl>(Val: D)) {
5202 if (VD->hasLocalStorage()) {
5203 S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
5204 return;
5205 }
5206 }
5207 if (!D->hasAttr<HIPManagedAttr>())
5208 D->addAttr(::new (S.Context) HIPManagedAttr(S.Context, AL));
5209 if (!D->hasAttr<CUDADeviceAttr>())
5210 D->addAttr(CUDADeviceAttr::CreateImplicit(S.Context));
5211}
5212
5213static void handleGNUInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5214 const auto *Fn = cast<FunctionDecl>(Val: D);
5215 if (!Fn->isInlineSpecified()) {
5216 S.Diag(AL.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
5217 return;
5218 }
5219
5220 if (S.LangOpts.CPlusPlus && Fn->getStorageClass() != SC_Extern)
5221 S.Diag(AL.getLoc(), diag::warn_gnu_inline_cplusplus_without_extern);
5222
5223 D->addAttr(::new (S.Context) GNUInlineAttr(S.Context, AL));
5224}
5225
5226static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5227 if (hasDeclarator(D)) return;
5228
5229 // Diagnostic is emitted elsewhere: here we store the (valid) AL
5230 // in the Decl node for syntactic reasoning, e.g., pretty-printing.
5231 CallingConv CC;
5232 if (S.CheckCallingConvAttr(
5233 attr: AL, CC, /*FD*/ nullptr,
5234 CFT: S.CUDA().IdentifyTarget(D: dyn_cast<FunctionDecl>(Val: D))))
5235 return;
5236
5237 if (!isa<ObjCMethodDecl>(Val: D)) {
5238 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
5239 << AL << AL.isRegularKeywordAttribute() << ExpectedFunctionOrMethod;
5240 return;
5241 }
5242
5243 switch (AL.getKind()) {
5244 case ParsedAttr::AT_FastCall:
5245 D->addAttr(::new (S.Context) FastCallAttr(S.Context, AL));
5246 return;
5247 case ParsedAttr::AT_StdCall:
5248 D->addAttr(::new (S.Context) StdCallAttr(S.Context, AL));
5249 return;
5250 case ParsedAttr::AT_ThisCall:
5251 D->addAttr(::new (S.Context) ThisCallAttr(S.Context, AL));
5252 return;
5253 case ParsedAttr::AT_CDecl:
5254 D->addAttr(::new (S.Context) CDeclAttr(S.Context, AL));
5255 return;
5256 case ParsedAttr::AT_Pascal:
5257 D->addAttr(::new (S.Context) PascalAttr(S.Context, AL));
5258 return;
5259 case ParsedAttr::AT_SwiftCall:
5260 D->addAttr(::new (S.Context) SwiftCallAttr(S.Context, AL));
5261 return;
5262 case ParsedAttr::AT_SwiftAsyncCall:
5263 D->addAttr(::new (S.Context) SwiftAsyncCallAttr(S.Context, AL));
5264 return;
5265 case ParsedAttr::AT_VectorCall:
5266 D->addAttr(::new (S.Context) VectorCallAttr(S.Context, AL));
5267 return;
5268 case ParsedAttr::AT_MSABI:
5269 D->addAttr(::new (S.Context) MSABIAttr(S.Context, AL));
5270 return;
5271 case ParsedAttr::AT_SysVABI:
5272 D->addAttr(::new (S.Context) SysVABIAttr(S.Context, AL));
5273 return;
5274 case ParsedAttr::AT_RegCall:
5275 D->addAttr(::new (S.Context) RegCallAttr(S.Context, AL));
5276 return;
5277 case ParsedAttr::AT_Pcs: {
5278 PcsAttr::PCSType PCS;
5279 switch (CC) {
5280 case CC_AAPCS:
5281 PCS = PcsAttr::AAPCS;
5282 break;
5283 case CC_AAPCS_VFP:
5284 PCS = PcsAttr::AAPCS_VFP;
5285 break;
5286 default:
5287 llvm_unreachable("unexpected calling convention in pcs attribute");
5288 }
5289
5290 D->addAttr(::new (S.Context) PcsAttr(S.Context, AL, PCS));
5291 return;
5292 }
5293 case ParsedAttr::AT_AArch64VectorPcs:
5294 D->addAttr(::new (S.Context) AArch64VectorPcsAttr(S.Context, AL));
5295 return;
5296 case ParsedAttr::AT_AArch64SVEPcs:
5297 D->addAttr(::new (S.Context) AArch64SVEPcsAttr(S.Context, AL));
5298 return;
5299 case ParsedAttr::AT_AMDGPUKernelCall:
5300 D->addAttr(::new (S.Context) AMDGPUKernelCallAttr(S.Context, AL));
5301 return;
5302 case ParsedAttr::AT_IntelOclBicc:
5303 D->addAttr(::new (S.Context) IntelOclBiccAttr(S.Context, AL));
5304 return;
5305 case ParsedAttr::AT_PreserveMost:
5306 D->addAttr(::new (S.Context) PreserveMostAttr(S.Context, AL));
5307 return;
5308 case ParsedAttr::AT_PreserveAll:
5309 D->addAttr(::new (S.Context) PreserveAllAttr(S.Context, AL));
5310 return;
5311 case ParsedAttr::AT_M68kRTD:
5312 D->addAttr(::new (S.Context) M68kRTDAttr(S.Context, AL));
5313 return;
5314 case ParsedAttr::AT_PreserveNone:
5315 D->addAttr(::new (S.Context) PreserveNoneAttr(S.Context, AL));
5316 return;
5317 case ParsedAttr::AT_RISCVVectorCC:
5318 D->addAttr(::new (S.Context) RISCVVectorCCAttr(S.Context, AL));
5319 return;
5320 default:
5321 llvm_unreachable("unexpected attribute kind");
5322 }
5323}
5324
5325static void handleSuppressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5326 if (AL.getAttributeSpellingListIndex() == SuppressAttr::CXX11_gsl_suppress) {
5327 // Suppression attribute with GSL spelling requires at least 1 argument.
5328 if (!AL.checkAtLeastNumArgs(S, Num: 1))
5329 return;
5330 }
5331
5332 std::vector<StringRef> DiagnosticIdentifiers;
5333 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
5334 StringRef RuleName;
5335
5336 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: I, Str&: RuleName, ArgLocation: nullptr))
5337 return;
5338
5339 DiagnosticIdentifiers.push_back(x: RuleName);
5340 }
5341 D->addAttr(::new (S.Context)
5342 SuppressAttr(S.Context, AL, DiagnosticIdentifiers.data(),
5343 DiagnosticIdentifiers.size()));
5344}
5345
5346static void handleLifetimeCategoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5347 TypeSourceInfo *DerefTypeLoc = nullptr;
5348 QualType ParmType;
5349 if (AL.hasParsedType()) {
5350 ParmType = S.GetTypeFromParser(Ty: AL.getTypeArg(), TInfo: &DerefTypeLoc);
5351
5352 unsigned SelectIdx = ~0U;
5353 if (ParmType->isReferenceType())
5354 SelectIdx = 0;
5355 else if (ParmType->isArrayType())
5356 SelectIdx = 1;
5357
5358 if (SelectIdx != ~0U) {
5359 S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument)
5360 << SelectIdx << AL;
5361 return;
5362 }
5363 }
5364
5365 // To check if earlier decl attributes do not conflict the newly parsed ones
5366 // we always add (and check) the attribute to the canonical decl. We need
5367 // to repeat the check for attribute mutual exclusion because we're attaching
5368 // all of the attributes to the canonical declaration rather than the current
5369 // declaration.
5370 D = D->getCanonicalDecl();
5371 if (AL.getKind() == ParsedAttr::AT_Owner) {
5372 if (checkAttrMutualExclusion<PointerAttr>(S, D, AL))
5373 return;
5374 if (const auto *OAttr = D->getAttr<OwnerAttr>()) {
5375 const Type *ExistingDerefType = OAttr->getDerefTypeLoc()
5376 ? OAttr->getDerefType().getTypePtr()
5377 : nullptr;
5378 if (ExistingDerefType != ParmType.getTypePtrOrNull()) {
5379 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
5380 << AL << OAttr
5381 << (AL.isRegularKeywordAttribute() ||
5382 OAttr->isRegularKeywordAttribute());
5383 S.Diag(OAttr->getLocation(), diag::note_conflicting_attribute);
5384 }
5385 return;
5386 }
5387 for (Decl *Redecl : D->redecls()) {
5388 Redecl->addAttr(::new (S.Context) OwnerAttr(S.Context, AL, DerefTypeLoc));
5389 }
5390 } else {
5391 if (checkAttrMutualExclusion<OwnerAttr>(S, D, AL))
5392 return;
5393 if (const auto *PAttr = D->getAttr<PointerAttr>()) {
5394 const Type *ExistingDerefType = PAttr->getDerefTypeLoc()
5395 ? PAttr->getDerefType().getTypePtr()
5396 : nullptr;
5397 if (ExistingDerefType != ParmType.getTypePtrOrNull()) {
5398 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
5399 << AL << PAttr
5400 << (AL.isRegularKeywordAttribute() ||
5401 PAttr->isRegularKeywordAttribute());
5402 S.Diag(PAttr->getLocation(), diag::note_conflicting_attribute);
5403 }
5404 return;
5405 }
5406 for (Decl *Redecl : D->redecls()) {
5407 Redecl->addAttr(::new (S.Context)
5408 PointerAttr(S.Context, AL, DerefTypeLoc));
5409 }
5410 }
5411}
5412
5413static void handleRandomizeLayoutAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5414 if (checkAttrMutualExclusion<NoRandomizeLayoutAttr>(S, D, AL))
5415 return;
5416 if (!D->hasAttr<RandomizeLayoutAttr>())
5417 D->addAttr(::new (S.Context) RandomizeLayoutAttr(S.Context, AL));
5418}
5419
5420static void handleNoRandomizeLayoutAttr(Sema &S, Decl *D,
5421 const ParsedAttr &AL) {
5422 if (checkAttrMutualExclusion<RandomizeLayoutAttr>(S, D, AL))
5423 return;
5424 if (!D->hasAttr<NoRandomizeLayoutAttr>())
5425 D->addAttr(::new (S.Context) NoRandomizeLayoutAttr(S.Context, AL));
5426}
5427
5428bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
5429 const FunctionDecl *FD,
5430 CUDAFunctionTarget CFT) {
5431 if (Attrs.isInvalid())
5432 return true;
5433
5434 if (Attrs.hasProcessingCache()) {
5435 CC = (CallingConv) Attrs.getProcessingCache();
5436 return false;
5437 }
5438
5439 unsigned ReqArgs = Attrs.getKind() == ParsedAttr::AT_Pcs ? 1 : 0;
5440 if (!Attrs.checkExactlyNumArgs(S&: *this, Num: ReqArgs)) {
5441 Attrs.setInvalid();
5442 return true;
5443 }
5444
5445 // TODO: diagnose uses of these conventions on the wrong target.
5446 switch (Attrs.getKind()) {
5447 case ParsedAttr::AT_CDecl:
5448 CC = CC_C;
5449 break;
5450 case ParsedAttr::AT_FastCall:
5451 CC = CC_X86FastCall;
5452 break;
5453 case ParsedAttr::AT_StdCall:
5454 CC = CC_X86StdCall;
5455 break;
5456 case ParsedAttr::AT_ThisCall:
5457 CC = CC_X86ThisCall;
5458 break;
5459 case ParsedAttr::AT_Pascal:
5460 CC = CC_X86Pascal;
5461 break;
5462 case ParsedAttr::AT_SwiftCall:
5463 CC = CC_Swift;
5464 break;
5465 case ParsedAttr::AT_SwiftAsyncCall:
5466 CC = CC_SwiftAsync;
5467 break;
5468 case ParsedAttr::AT_VectorCall:
5469 CC = CC_X86VectorCall;
5470 break;
5471 case ParsedAttr::AT_AArch64VectorPcs:
5472 CC = CC_AArch64VectorCall;
5473 break;
5474 case ParsedAttr::AT_AArch64SVEPcs:
5475 CC = CC_AArch64SVEPCS;
5476 break;
5477 case ParsedAttr::AT_AMDGPUKernelCall:
5478 CC = CC_AMDGPUKernelCall;
5479 break;
5480 case ParsedAttr::AT_RegCall:
5481 CC = CC_X86RegCall;
5482 break;
5483 case ParsedAttr::AT_MSABI:
5484 CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C :
5485 CC_Win64;
5486 break;
5487 case ParsedAttr::AT_SysVABI:
5488 CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_X86_64SysV :
5489 CC_C;
5490 break;
5491 case ParsedAttr::AT_Pcs: {
5492 StringRef StrRef;
5493 if (!checkStringLiteralArgumentAttr(AL: Attrs, ArgNum: 0, Str&: StrRef)) {
5494 Attrs.setInvalid();
5495 return true;
5496 }
5497 if (StrRef == "aapcs") {
5498 CC = CC_AAPCS;
5499 break;
5500 } else if (StrRef == "aapcs-vfp") {
5501 CC = CC_AAPCS_VFP;
5502 break;
5503 }
5504
5505 Attrs.setInvalid();
5506 Diag(Attrs.getLoc(), diag::err_invalid_pcs);
5507 return true;
5508 }
5509 case ParsedAttr::AT_IntelOclBicc:
5510 CC = CC_IntelOclBicc;
5511 break;
5512 case ParsedAttr::AT_PreserveMost:
5513 CC = CC_PreserveMost;
5514 break;
5515 case ParsedAttr::AT_PreserveAll:
5516 CC = CC_PreserveAll;
5517 break;
5518 case ParsedAttr::AT_M68kRTD:
5519 CC = CC_M68kRTD;
5520 break;
5521 case ParsedAttr::AT_PreserveNone:
5522 CC = CC_PreserveNone;
5523 break;
5524 case ParsedAttr::AT_RISCVVectorCC:
5525 CC = CC_RISCVVectorCall;
5526 break;
5527 default: llvm_unreachable("unexpected attribute kind");
5528 }
5529
5530 TargetInfo::CallingConvCheckResult A = TargetInfo::CCCR_OK;
5531 const TargetInfo &TI = Context.getTargetInfo();
5532 // CUDA functions may have host and/or device attributes which indicate
5533 // their targeted execution environment, therefore the calling convention
5534 // of functions in CUDA should be checked against the target deduced based
5535 // on their host/device attributes.
5536 if (LangOpts.CUDA) {
5537 auto *Aux = Context.getAuxTargetInfo();
5538 assert(FD || CFT != CUDAFunctionTarget::InvalidTarget);
5539 auto CudaTarget = FD ? CUDA().IdentifyTarget(D: FD) : CFT;
5540 bool CheckHost = false, CheckDevice = false;
5541 switch (CudaTarget) {
5542 case CUDAFunctionTarget::HostDevice:
5543 CheckHost = true;
5544 CheckDevice = true;
5545 break;
5546 case CUDAFunctionTarget::Host:
5547 CheckHost = true;
5548 break;
5549 case CUDAFunctionTarget::Device:
5550 case CUDAFunctionTarget::Global:
5551 CheckDevice = true;
5552 break;
5553 case CUDAFunctionTarget::InvalidTarget:
5554 llvm_unreachable("unexpected cuda target");
5555 }
5556 auto *HostTI = LangOpts.CUDAIsDevice ? Aux : &TI;
5557 auto *DeviceTI = LangOpts.CUDAIsDevice ? &TI : Aux;
5558 if (CheckHost && HostTI)
5559 A = HostTI->checkCallingConvention(CC);
5560 if (A == TargetInfo::CCCR_OK && CheckDevice && DeviceTI)
5561 A = DeviceTI->checkCallingConvention(CC);
5562 } else {
5563 A = TI.checkCallingConvention(CC);
5564 }
5565
5566 switch (A) {
5567 case TargetInfo::CCCR_OK:
5568 break;
5569
5570 case TargetInfo::CCCR_Ignore:
5571 // Treat an ignored convention as if it was an explicit C calling convention
5572 // attribute. For example, __stdcall on Win x64 functions as __cdecl, so
5573 // that command line flags that change the default convention to
5574 // __vectorcall don't affect declarations marked __stdcall.
5575 CC = CC_C;
5576 break;
5577
5578 case TargetInfo::CCCR_Error:
5579 Diag(Attrs.getLoc(), diag::error_cconv_unsupported)
5580 << Attrs << (int)CallingConventionIgnoredReason::ForThisTarget;
5581 break;
5582
5583 case TargetInfo::CCCR_Warning: {
5584 Diag(Attrs.getLoc(), diag::warn_cconv_unsupported)
5585 << Attrs << (int)CallingConventionIgnoredReason::ForThisTarget;
5586
5587 // This convention is not valid for the target. Use the default function or
5588 // method calling convention.
5589 bool IsCXXMethod = false, IsVariadic = false;
5590 if (FD) {
5591 IsCXXMethod = FD->isCXXInstanceMember();
5592 IsVariadic = FD->isVariadic();
5593 }
5594 CC = Context.getDefaultCallingConvention(IsVariadic, IsCXXMethod);
5595 break;
5596 }
5597 }
5598
5599 Attrs.setProcessingCache((unsigned) CC);
5600 return false;
5601}
5602
5603/// Pointer-like types in the default address space.
5604static bool isValidSwiftContextType(QualType Ty) {
5605 if (!Ty->hasPointerRepresentation())
5606 return Ty->isDependentType();
5607 return Ty->getPointeeType().getAddressSpace() == LangAS::Default;
5608}
5609
5610/// Pointers and references in the default address space.
5611static bool isValidSwiftIndirectResultType(QualType Ty) {
5612 if (const auto *PtrType = Ty->getAs<PointerType>()) {
5613 Ty = PtrType->getPointeeType();
5614 } else if (const auto *RefType = Ty->getAs<ReferenceType>()) {
5615 Ty = RefType->getPointeeType();
5616 } else {
5617 return Ty->isDependentType();
5618 }
5619 return Ty.getAddressSpace() == LangAS::Default;
5620}
5621
5622/// Pointers and references to pointers in the default address space.
5623static bool isValidSwiftErrorResultType(QualType Ty) {
5624 if (const auto *PtrType = Ty->getAs<PointerType>()) {
5625 Ty = PtrType->getPointeeType();
5626 } else if (const auto *RefType = Ty->getAs<ReferenceType>()) {
5627 Ty = RefType->getPointeeType();
5628 } else {
5629 return Ty->isDependentType();
5630 }
5631 if (!Ty.getQualifiers().empty())
5632 return false;
5633 return isValidSwiftContextType(Ty);
5634}
5635
5636void Sema::AddParameterABIAttr(Decl *D, const AttributeCommonInfo &CI,
5637 ParameterABI abi) {
5638
5639 QualType type = cast<ParmVarDecl>(Val: D)->getType();
5640
5641 if (auto existingAttr = D->getAttr<ParameterABIAttr>()) {
5642 if (existingAttr->getABI() != abi) {
5643 Diag(CI.getLoc(), diag::err_attributes_are_not_compatible)
5644 << getParameterABISpelling(abi) << existingAttr
5645 << (CI.isRegularKeywordAttribute() ||
5646 existingAttr->isRegularKeywordAttribute());
5647 Diag(existingAttr->getLocation(), diag::note_conflicting_attribute);
5648 return;
5649 }
5650 }
5651
5652 switch (abi) {
5653 case ParameterABI::Ordinary:
5654 llvm_unreachable("explicit attribute for ordinary parameter ABI?");
5655
5656 case ParameterABI::SwiftContext:
5657 if (!isValidSwiftContextType(Ty: type)) {
5658 Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type)
5659 << getParameterABISpelling(abi) << /*pointer to pointer */ 0 << type;
5660 }
5661 D->addAttr(::new (Context) SwiftContextAttr(Context, CI));
5662 return;
5663
5664 case ParameterABI::SwiftAsyncContext:
5665 if (!isValidSwiftContextType(Ty: type)) {
5666 Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type)
5667 << getParameterABISpelling(abi) << /*pointer to pointer */ 0 << type;
5668 }
5669 D->addAttr(::new (Context) SwiftAsyncContextAttr(Context, CI));
5670 return;
5671
5672 case ParameterABI::SwiftErrorResult:
5673 if (!isValidSwiftErrorResultType(Ty: type)) {
5674 Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type)
5675 << getParameterABISpelling(abi) << /*pointer to pointer */ 1 << type;
5676 }
5677 D->addAttr(::new (Context) SwiftErrorResultAttr(Context, CI));
5678 return;
5679
5680 case ParameterABI::SwiftIndirectResult:
5681 if (!isValidSwiftIndirectResultType(Ty: type)) {
5682 Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type)
5683 << getParameterABISpelling(abi) << /*pointer*/ 0 << type;
5684 }
5685 D->addAttr(::new (Context) SwiftIndirectResultAttr(Context, CI));
5686 return;
5687 }
5688 llvm_unreachable("bad parameter ABI attribute");
5689}
5690
5691/// Checks a regparm attribute, returning true if it is ill-formed and
5692/// otherwise setting numParams to the appropriate value.
5693bool Sema::CheckRegparmAttr(const ParsedAttr &AL, unsigned &numParams) {
5694 if (AL.isInvalid())
5695 return true;
5696
5697 if (!AL.checkExactlyNumArgs(S&: *this, Num: 1)) {
5698 AL.setInvalid();
5699 return true;
5700 }
5701
5702 uint32_t NP;
5703 Expr *NumParamsExpr = AL.getArgAsExpr(Arg: 0);
5704 if (!checkUInt32Argument(S&: *this, AI: AL, Expr: NumParamsExpr, Val&: NP)) {
5705 AL.setInvalid();
5706 return true;
5707 }
5708
5709 if (Context.getTargetInfo().getRegParmMax() == 0) {
5710 Diag(AL.getLoc(), diag::err_attribute_regparm_wrong_platform)
5711 << NumParamsExpr->getSourceRange();
5712 AL.setInvalid();
5713 return true;
5714 }
5715
5716 numParams = NP;
5717 if (numParams > Context.getTargetInfo().getRegParmMax()) {
5718 Diag(AL.getLoc(), diag::err_attribute_regparm_invalid_number)
5719 << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
5720 AL.setInvalid();
5721 return true;
5722 }
5723
5724 return false;
5725}
5726
5727// Helper to get CudaArch.
5728static CudaArch getCudaArch(const TargetInfo &TI) {
5729 if (!TI.getTriple().isNVPTX())
5730 llvm_unreachable("getCudaArch is only valid for NVPTX triple");
5731 auto &TO = TI.getTargetOpts();
5732 return StringToCudaArch(S: TO.CPU);
5733}
5734
5735// Checks whether an argument of launch_bounds attribute is
5736// acceptable, performs implicit conversion to Rvalue, and returns
5737// non-nullptr Expr result on success. Otherwise, it returns nullptr
5738// and may output an error.
5739static Expr *makeLaunchBoundsArgExpr(Sema &S, Expr *E,
5740 const CUDALaunchBoundsAttr &AL,
5741 const unsigned Idx) {
5742 if (S.DiagnoseUnexpandedParameterPack(E))
5743 return nullptr;
5744
5745 // Accept template arguments for now as they depend on something else.
5746 // We'll get to check them when they eventually get instantiated.
5747 if (E->isValueDependent())
5748 return E;
5749
5750 std::optional<llvm::APSInt> I = llvm::APSInt(64);
5751 if (!(I = E->getIntegerConstantExpr(Ctx: S.Context))) {
5752 S.Diag(E->getExprLoc(), diag::err_attribute_argument_n_type)
5753 << &AL << Idx << AANT_ArgumentIntegerConstant << E->getSourceRange();
5754 return nullptr;
5755 }
5756 // Make sure we can fit it in 32 bits.
5757 if (!I->isIntN(N: 32)) {
5758 S.Diag(E->getExprLoc(), diag::err_ice_too_large)
5759 << toString(*I, 10, false) << 32 << /* Unsigned */ 1;
5760 return nullptr;
5761 }
5762 if (*I < 0)
5763 S.Diag(E->getExprLoc(), diag::warn_attribute_argument_n_negative)
5764 << &AL << Idx << E->getSourceRange();
5765
5766 // We may need to perform implicit conversion of the argument.
5767 InitializedEntity Entity = InitializedEntity::InitializeParameter(
5768 S.Context, S.Context.getConstType(T: S.Context.IntTy), /*consume*/ false);
5769 ExprResult ValArg = S.PerformCopyInitialization(Entity, EqualLoc: SourceLocation(), Init: E);
5770 assert(!ValArg.isInvalid() &&
5771 "Unexpected PerformCopyInitialization() failure.");
5772
5773 return ValArg.getAs<Expr>();
5774}
5775
5776CUDALaunchBoundsAttr *
5777Sema::CreateLaunchBoundsAttr(const AttributeCommonInfo &CI, Expr *MaxThreads,
5778 Expr *MinBlocks, Expr *MaxBlocks) {
5779 CUDALaunchBoundsAttr TmpAttr(Context, CI, MaxThreads, MinBlocks, MaxBlocks);
5780 MaxThreads = makeLaunchBoundsArgExpr(*this, MaxThreads, TmpAttr, 0);
5781 if (!MaxThreads)
5782 return nullptr;
5783
5784 if (MinBlocks) {
5785 MinBlocks = makeLaunchBoundsArgExpr(*this, MinBlocks, TmpAttr, 1);
5786 if (!MinBlocks)
5787 return nullptr;
5788 }
5789
5790 if (MaxBlocks) {
5791 // '.maxclusterrank' ptx directive requires .target sm_90 or higher.
5792 auto SM = getCudaArch(TI: Context.getTargetInfo());
5793 if (SM == CudaArch::UNKNOWN || SM < CudaArch::SM_90) {
5794 Diag(MaxBlocks->getBeginLoc(), diag::warn_cuda_maxclusterrank_sm_90)
5795 << CudaArchToString(SM) << CI << MaxBlocks->getSourceRange();
5796 // Ignore it by setting MaxBlocks to null;
5797 MaxBlocks = nullptr;
5798 } else {
5799 MaxBlocks = makeLaunchBoundsArgExpr(*this, MaxBlocks, TmpAttr, 2);
5800 if (!MaxBlocks)
5801 return nullptr;
5802 }
5803 }
5804
5805 return ::new (Context)
5806 CUDALaunchBoundsAttr(Context, CI, MaxThreads, MinBlocks, MaxBlocks);
5807}
5808
5809void Sema::AddLaunchBoundsAttr(Decl *D, const AttributeCommonInfo &CI,
5810 Expr *MaxThreads, Expr *MinBlocks,
5811 Expr *MaxBlocks) {
5812 if (auto *Attr = CreateLaunchBoundsAttr(CI, MaxThreads, MinBlocks, MaxBlocks))
5813 D->addAttr(A: Attr);
5814}
5815
5816static void handleLaunchBoundsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5817 if (!AL.checkAtLeastNumArgs(S, Num: 1) || !AL.checkAtMostNumArgs(S, Num: 3))
5818 return;
5819
5820 S.AddLaunchBoundsAttr(D, CI: AL, MaxThreads: AL.getArgAsExpr(Arg: 0),
5821 MinBlocks: AL.getNumArgs() > 1 ? AL.getArgAsExpr(Arg: 1) : nullptr,
5822 MaxBlocks: AL.getNumArgs() > 2 ? AL.getArgAsExpr(Arg: 2) : nullptr);
5823}
5824
5825static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D,
5826 const ParsedAttr &AL) {
5827 if (!AL.isArgIdent(Arg: 0)) {
5828 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
5829 << AL << /* arg num = */ 1 << AANT_ArgumentIdentifier;
5830 return;
5831 }
5832
5833 ParamIdx ArgumentIdx;
5834 if (!checkFunctionOrMethodParameterIndex(S, D, AI: AL, AttrArgNum: 2, IdxExpr: AL.getArgAsExpr(Arg: 1),
5835 Idx&: ArgumentIdx))
5836 return;
5837
5838 ParamIdx TypeTagIdx;
5839 if (!checkFunctionOrMethodParameterIndex(S, D, AI: AL, AttrArgNum: 3, IdxExpr: AL.getArgAsExpr(Arg: 2),
5840 Idx&: TypeTagIdx))
5841 return;
5842
5843 bool IsPointer = AL.getAttrName()->getName() == "pointer_with_type_tag";
5844 if (IsPointer) {
5845 // Ensure that buffer has a pointer type.
5846 unsigned ArgumentIdxAST = ArgumentIdx.getASTIndex();
5847 if (ArgumentIdxAST >= getFunctionOrMethodNumParams(D) ||
5848 !getFunctionOrMethodParamType(D, ArgumentIdxAST)->isPointerType())
5849 S.Diag(AL.getLoc(), diag::err_attribute_pointers_only) << AL << 0;
5850 }
5851
5852 D->addAttr(::new (S.Context) ArgumentWithTypeTagAttr(
5853 S.Context, AL, AL.getArgAsIdent(0)->Ident, ArgumentIdx, TypeTagIdx,
5854 IsPointer));
5855}
5856
5857static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
5858 const ParsedAttr &AL) {
5859 if (!AL.isArgIdent(Arg: 0)) {
5860 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
5861 << AL << 1 << AANT_ArgumentIdentifier;
5862 return;
5863 }
5864
5865 if (!AL.checkExactlyNumArgs(S, Num: 1))
5866 return;
5867
5868 if (!isa<VarDecl>(Val: D)) {
5869 S.Diag(AL.getLoc(), diag::err_attribute_wrong_decl_type)
5870 << AL << AL.isRegularKeywordAttribute() << ExpectedVariable;
5871 return;
5872 }
5873
5874 IdentifierInfo *PointerKind = AL.getArgAsIdent(Arg: 0)->Ident;
5875 TypeSourceInfo *MatchingCTypeLoc = nullptr;
5876 S.GetTypeFromParser(Ty: AL.getMatchingCType(), TInfo: &MatchingCTypeLoc);
5877 assert(MatchingCTypeLoc && "no type source info for attribute argument");
5878
5879 D->addAttr(::new (S.Context) TypeTagForDatatypeAttr(
5880 S.Context, AL, PointerKind, MatchingCTypeLoc, AL.getLayoutCompatible(),
5881 AL.getMustBeNull()));
5882}
5883
5884static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5885 ParamIdx ArgCount;
5886
5887 if (!checkFunctionOrMethodParameterIndex(S, D, AI: AL, AttrArgNum: 1, IdxExpr: AL.getArgAsExpr(Arg: 0),
5888 Idx&: ArgCount,
5889 CanIndexImplicitThis: true /* CanIndexImplicitThis */))
5890 return;
5891
5892 // ArgCount isn't a parameter index [0;n), it's a count [1;n]
5893 D->addAttr(::new (S.Context)
5894 XRayLogArgsAttr(S.Context, AL, ArgCount.getSourceIndex()));
5895}
5896
5897static void handlePatchableFunctionEntryAttr(Sema &S, Decl *D,
5898 const ParsedAttr &AL) {
5899 uint32_t Count = 0, Offset = 0;
5900 if (!checkUInt32Argument(S, AI: AL, Expr: AL.getArgAsExpr(Arg: 0), Val&: Count, Idx: 0, StrictlyUnsigned: true))
5901 return;
5902 if (AL.getNumArgs() == 2) {
5903 Expr *Arg = AL.getArgAsExpr(Arg: 1);
5904 if (!checkUInt32Argument(S, AI: AL, Expr: Arg, Val&: Offset, Idx: 1, StrictlyUnsigned: true))
5905 return;
5906 if (Count < Offset) {
5907 S.Diag(getAttrLoc(AL), diag::err_attribute_argument_out_of_range)
5908 << &AL << 0 << Count << Arg->getBeginLoc();
5909 return;
5910 }
5911 }
5912 D->addAttr(::new (S.Context)
5913 PatchableFunctionEntryAttr(S.Context, AL, Count, Offset));
5914}
5915
5916namespace {
5917struct IntrinToName {
5918 uint32_t Id;
5919 int32_t FullName;
5920 int32_t ShortName;
5921};
5922} // unnamed namespace
5923
5924static bool ArmBuiltinAliasValid(unsigned BuiltinID, StringRef AliasName,
5925 ArrayRef<IntrinToName> Map,
5926 const char *IntrinNames) {
5927 AliasName.consume_front(Prefix: "__arm_");
5928 const IntrinToName *It =
5929 llvm::lower_bound(Range&: Map, Value&: BuiltinID, C: [](const IntrinToName &L, unsigned Id) {
5930 return L.Id < Id;
5931 });
5932 if (It == Map.end() || It->Id != BuiltinID)
5933 return false;
5934 StringRef FullName(&IntrinNames[It->FullName]);
5935 if (AliasName == FullName)
5936 return true;
5937 if (It->ShortName == -1)
5938 return false;
5939 StringRef ShortName(&IntrinNames[It->ShortName]);
5940 return AliasName == ShortName;
5941}
5942
5943static bool ArmMveAliasValid(unsigned BuiltinID, StringRef AliasName) {
5944#include "clang/Basic/arm_mve_builtin_aliases.inc"
5945 // The included file defines:
5946 // - ArrayRef<IntrinToName> Map
5947 // - const char IntrinNames[]
5948 return ArmBuiltinAliasValid(BuiltinID, AliasName, Map, IntrinNames);
5949}
5950
5951static bool ArmCdeAliasValid(unsigned BuiltinID, StringRef AliasName) {
5952#include "clang/Basic/arm_cde_builtin_aliases.inc"
5953 return ArmBuiltinAliasValid(BuiltinID, AliasName, Map, IntrinNames);
5954}
5955
5956static bool ArmSveAliasValid(ASTContext &Context, unsigned BuiltinID,
5957 StringRef AliasName) {
5958 if (Context.BuiltinInfo.isAuxBuiltinID(ID: BuiltinID))
5959 BuiltinID = Context.BuiltinInfo.getAuxBuiltinID(ID: BuiltinID);
5960 return BuiltinID >= AArch64::FirstSVEBuiltin &&
5961 BuiltinID <= AArch64::LastSVEBuiltin;
5962}
5963
5964static bool ArmSmeAliasValid(ASTContext &Context, unsigned BuiltinID,
5965 StringRef AliasName) {
5966 if (Context.BuiltinInfo.isAuxBuiltinID(ID: BuiltinID))
5967 BuiltinID = Context.BuiltinInfo.getAuxBuiltinID(ID: BuiltinID);
5968 return BuiltinID >= AArch64::FirstSMEBuiltin &&
5969 BuiltinID <= AArch64::LastSMEBuiltin;
5970}
5971
5972static void handleArmBuiltinAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5973 if (!AL.isArgIdent(Arg: 0)) {
5974 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
5975 << AL << 1 << AANT_ArgumentIdentifier;
5976 return;
5977 }
5978
5979 IdentifierInfo *Ident = AL.getArgAsIdent(Arg: 0)->Ident;
5980 unsigned BuiltinID = Ident->getBuiltinID();
5981 StringRef AliasName = cast<FunctionDecl>(Val: D)->getIdentifier()->getName();
5982
5983 bool IsAArch64 = S.Context.getTargetInfo().getTriple().isAArch64();
5984 if ((IsAArch64 && !ArmSveAliasValid(Context&: S.Context, BuiltinID, AliasName) &&
5985 !ArmSmeAliasValid(Context&: S.Context, BuiltinID, AliasName)) ||
5986 (!IsAArch64 && !ArmMveAliasValid(BuiltinID, AliasName) &&
5987 !ArmCdeAliasValid(BuiltinID, AliasName))) {
5988 S.Diag(AL.getLoc(), diag::err_attribute_arm_builtin_alias);
5989 return;
5990 }
5991
5992 D->addAttr(::new (S.Context) ArmBuiltinAliasAttr(S.Context, AL, Ident));
5993}
5994
5995static bool RISCVAliasValid(unsigned BuiltinID, StringRef AliasName) {
5996 return BuiltinID >= RISCV::FirstRVVBuiltin &&
5997 BuiltinID <= RISCV::LastRVVBuiltin;
5998}
5999
6000static void handleBuiltinAliasAttr(Sema &S, Decl *D,
6001 const ParsedAttr &AL) {
6002 if (!AL.isArgIdent(Arg: 0)) {
6003 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
6004 << AL << 1 << AANT_ArgumentIdentifier;
6005 return;
6006 }
6007
6008 IdentifierInfo *Ident = AL.getArgAsIdent(Arg: 0)->Ident;
6009 unsigned BuiltinID = Ident->getBuiltinID();
6010 StringRef AliasName = cast<FunctionDecl>(Val: D)->getIdentifier()->getName();
6011
6012 bool IsAArch64 = S.Context.getTargetInfo().getTriple().isAArch64();
6013 bool IsARM = S.Context.getTargetInfo().getTriple().isARM();
6014 bool IsRISCV = S.Context.getTargetInfo().getTriple().isRISCV();
6015 bool IsHLSL = S.Context.getLangOpts().HLSL;
6016 if ((IsAArch64 && !ArmSveAliasValid(Context&: S.Context, BuiltinID, AliasName)) ||
6017 (IsARM && !ArmMveAliasValid(BuiltinID, AliasName) &&
6018 !ArmCdeAliasValid(BuiltinID, AliasName)) ||
6019 (IsRISCV && !RISCVAliasValid(BuiltinID, AliasName)) ||
6020 (!IsAArch64 && !IsARM && !IsRISCV && !IsHLSL)) {
6021 S.Diag(AL.getLoc(), diag::err_attribute_builtin_alias) << AL;
6022 return;
6023 }
6024
6025 D->addAttr(::new (S.Context) BuiltinAliasAttr(S.Context, AL, Ident));
6026}
6027
6028static void handleNullableTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6029 if (AL.isUsedAsTypeAttr())
6030 return;
6031
6032 if (auto *CRD = dyn_cast<CXXRecordDecl>(Val: D);
6033 !CRD || !(CRD->isClass() || CRD->isStruct())) {
6034 S.Diag(AL.getRange().getBegin(), diag::err_attribute_wrong_decl_type_str)
6035 << AL << AL.isRegularKeywordAttribute() << "classes";
6036 return;
6037 }
6038
6039 handleSimpleAttribute<TypeNullableAttr>(S, D, AL);
6040}
6041
6042static void handlePreferredTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6043 if (!AL.hasParsedType()) {
6044 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
6045 return;
6046 }
6047
6048 TypeSourceInfo *ParmTSI = nullptr;
6049 QualType QT = S.GetTypeFromParser(Ty: AL.getTypeArg(), TInfo: &ParmTSI);
6050 assert(ParmTSI && "no type source info for attribute argument");
6051 S.RequireCompleteType(ParmTSI->getTypeLoc().getBeginLoc(), QT,
6052 diag::err_incomplete_type);
6053
6054 D->addAttr(::new (S.Context) PreferredTypeAttr(S.Context, AL, ParmTSI));
6055}
6056
6057//===----------------------------------------------------------------------===//
6058// Checker-specific attribute handlers.
6059//===----------------------------------------------------------------------===//
6060static bool isValidSubjectOfNSReturnsRetainedAttribute(QualType QT) {
6061 return QT->isDependentType() || QT->isObjCRetainableType();
6062}
6063
6064static bool isValidSubjectOfNSAttribute(QualType QT) {
6065 return QT->isDependentType() || QT->isObjCObjectPointerType() ||
6066 QT->isObjCNSObjectType();
6067}
6068
6069static bool isValidSubjectOfCFAttribute(QualType QT) {
6070 return QT->isDependentType() || QT->isPointerType() ||
6071 isValidSubjectOfNSAttribute(QT);
6072}
6073
6074static bool isValidSubjectOfOSAttribute(QualType QT) {
6075 if (QT->isDependentType())
6076 return true;
6077 QualType PT = QT->getPointeeType();
6078 return !PT.isNull() && PT->getAsCXXRecordDecl() != nullptr;
6079}
6080
6081void Sema::AddXConsumedAttr(Decl *D, const AttributeCommonInfo &CI,
6082 RetainOwnershipKind K,
6083 bool IsTemplateInstantiation) {
6084 ValueDecl *VD = cast<ValueDecl>(Val: D);
6085 switch (K) {
6086 case RetainOwnershipKind::OS:
6087 handleSimpleAttributeOrDiagnose<OSConsumedAttr>(
6088 *this, VD, CI, isValidSubjectOfOSAttribute(VD->getType()),
6089 diag::warn_ns_attribute_wrong_parameter_type,
6090 /*ExtraArgs=*/CI.getRange(), "os_consumed", /*pointers*/ 1);
6091 return;
6092 case RetainOwnershipKind::NS:
6093 handleSimpleAttributeOrDiagnose<NSConsumedAttr>(
6094 *this, VD, CI, isValidSubjectOfNSAttribute(VD->getType()),
6095
6096 // These attributes are normally just advisory, but in ARC, ns_consumed
6097 // is significant. Allow non-dependent code to contain inappropriate
6098 // attributes even in ARC, but require template instantiations to be
6099 // set up correctly.
6100 ((IsTemplateInstantiation && getLangOpts().ObjCAutoRefCount)
6101 ? diag::err_ns_attribute_wrong_parameter_type
6102 : diag::warn_ns_attribute_wrong_parameter_type),
6103 /*ExtraArgs=*/CI.getRange(), "ns_consumed", /*objc pointers*/ 0);
6104 return;
6105 case RetainOwnershipKind::CF:
6106 handleSimpleAttributeOrDiagnose<CFConsumedAttr>(
6107 *this, VD, CI, isValidSubjectOfCFAttribute(VD->getType()),
6108 diag::warn_ns_attribute_wrong_parameter_type,
6109 /*ExtraArgs=*/CI.getRange(), "cf_consumed", /*pointers*/ 1);
6110 return;
6111 }
6112}
6113
6114static Sema::RetainOwnershipKind
6115parsedAttrToRetainOwnershipKind(const ParsedAttr &AL) {
6116 switch (AL.getKind()) {
6117 case ParsedAttr::AT_CFConsumed:
6118 case ParsedAttr::AT_CFReturnsRetained:
6119 case ParsedAttr::AT_CFReturnsNotRetained:
6120 return Sema::RetainOwnershipKind::CF;
6121 case ParsedAttr::AT_OSConsumesThis:
6122 case ParsedAttr::AT_OSConsumed:
6123 case ParsedAttr::AT_OSReturnsRetained:
6124 case ParsedAttr::AT_OSReturnsNotRetained:
6125 case ParsedAttr::AT_OSReturnsRetainedOnZero:
6126 case ParsedAttr::AT_OSReturnsRetainedOnNonZero:
6127 return Sema::RetainOwnershipKind::OS;
6128 case ParsedAttr::AT_NSConsumesSelf:
6129 case ParsedAttr::AT_NSConsumed:
6130 case ParsedAttr::AT_NSReturnsRetained:
6131 case ParsedAttr::AT_NSReturnsNotRetained:
6132 case ParsedAttr::AT_NSReturnsAutoreleased:
6133 return Sema::RetainOwnershipKind::NS;
6134 default:
6135 llvm_unreachable("Wrong argument supplied");
6136 }
6137}
6138
6139bool Sema::checkNSReturnsRetainedReturnType(SourceLocation Loc, QualType QT) {
6140 if (isValidSubjectOfNSReturnsRetainedAttribute(QT))
6141 return false;
6142
6143 Diag(Loc, diag::warn_ns_attribute_wrong_return_type)
6144 << "'ns_returns_retained'" << 0 << 0;
6145 return true;
6146}
6147
6148/// \return whether the parameter is a pointer to OSObject pointer.
6149static bool isValidOSObjectOutParameter(const Decl *D) {
6150 const auto *PVD = dyn_cast<ParmVarDecl>(Val: D);
6151 if (!PVD)
6152 return false;
6153 QualType QT = PVD->getType();
6154 QualType PT = QT->getPointeeType();
6155 return !PT.isNull() && isValidSubjectOfOSAttribute(QT: PT);
6156}
6157
6158static void handleXReturnsXRetainedAttr(Sema &S, Decl *D,
6159 const ParsedAttr &AL) {
6160 QualType ReturnType;
6161 Sema::RetainOwnershipKind K = parsedAttrToRetainOwnershipKind(AL);
6162
6163 if (const auto *MD = dyn_cast<ObjCMethodDecl>(Val: D)) {
6164 ReturnType = MD->getReturnType();
6165 } else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) &&
6166 (AL.getKind() == ParsedAttr::AT_NSReturnsRetained)) {
6167 return; // ignore: was handled as a type attribute
6168 } else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(Val: D)) {
6169 ReturnType = PD->getType();
6170 } else if (const auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
6171 ReturnType = FD->getReturnType();
6172 } else if (const auto *Param = dyn_cast<ParmVarDecl>(Val: D)) {
6173 // Attributes on parameters are used for out-parameters,
6174 // passed as pointers-to-pointers.
6175 unsigned DiagID = K == Sema::RetainOwnershipKind::CF
6176 ? /*pointer-to-CF-pointer*/2
6177 : /*pointer-to-OSObject-pointer*/3;
6178 ReturnType = Param->getType()->getPointeeType();
6179 if (ReturnType.isNull()) {
6180 S.Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_parameter_type)
6181 << AL << DiagID << AL.getRange();
6182 return;
6183 }
6184 } else if (AL.isUsedAsTypeAttr()) {
6185 return;
6186 } else {
6187 AttributeDeclKind ExpectedDeclKind;
6188 switch (AL.getKind()) {
6189 default: llvm_unreachable("invalid ownership attribute");
6190 case ParsedAttr::AT_NSReturnsRetained:
6191 case ParsedAttr::AT_NSReturnsAutoreleased:
6192 case ParsedAttr::AT_NSReturnsNotRetained:
6193 ExpectedDeclKind = ExpectedFunctionOrMethod;
6194 break;
6195
6196 case ParsedAttr::AT_OSReturnsRetained:
6197 case ParsedAttr::AT_OSReturnsNotRetained:
6198 case ParsedAttr::AT_CFReturnsRetained:
6199 case ParsedAttr::AT_CFReturnsNotRetained:
6200 ExpectedDeclKind = ExpectedFunctionMethodOrParameter;
6201 break;
6202 }
6203 S.Diag(D->getBeginLoc(), diag::warn_attribute_wrong_decl_type)
6204 << AL.getRange() << AL << AL.isRegularKeywordAttribute()
6205 << ExpectedDeclKind;
6206 return;
6207 }
6208
6209 bool TypeOK;
6210 bool Cf;
6211 unsigned ParmDiagID = 2; // Pointer-to-CF-pointer
6212 switch (AL.getKind()) {
6213 default: llvm_unreachable("invalid ownership attribute");
6214 case ParsedAttr::AT_NSReturnsRetained:
6215 TypeOK = isValidSubjectOfNSReturnsRetainedAttribute(QT: ReturnType);
6216 Cf = false;
6217 break;
6218
6219 case ParsedAttr::AT_NSReturnsAutoreleased:
6220 case ParsedAttr::AT_NSReturnsNotRetained:
6221 TypeOK = isValidSubjectOfNSAttribute(QT: ReturnType);
6222 Cf = false;
6223 break;
6224
6225 case ParsedAttr::AT_CFReturnsRetained:
6226 case ParsedAttr::AT_CFReturnsNotRetained:
6227 TypeOK = isValidSubjectOfCFAttribute(QT: ReturnType);
6228 Cf = true;
6229 break;
6230
6231 case ParsedAttr::AT_OSReturnsRetained:
6232 case ParsedAttr::AT_OSReturnsNotRetained:
6233 TypeOK = isValidSubjectOfOSAttribute(QT: ReturnType);
6234 Cf = true;
6235 ParmDiagID = 3; // Pointer-to-OSObject-pointer
6236 break;
6237 }
6238
6239 if (!TypeOK) {
6240 if (AL.isUsedAsTypeAttr())
6241 return;
6242
6243 if (isa<ParmVarDecl>(Val: D)) {
6244 S.Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_parameter_type)
6245 << AL << ParmDiagID << AL.getRange();
6246 } else {
6247 // Needs to be kept in sync with warn_ns_attribute_wrong_return_type.
6248 enum : unsigned {
6249 Function,
6250 Method,
6251 Property
6252 } SubjectKind = Function;
6253 if (isa<ObjCMethodDecl>(Val: D))
6254 SubjectKind = Method;
6255 else if (isa<ObjCPropertyDecl>(Val: D))
6256 SubjectKind = Property;
6257 S.Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_return_type)
6258 << AL << SubjectKind << Cf << AL.getRange();
6259 }
6260 return;
6261 }
6262
6263 switch (AL.getKind()) {
6264 default:
6265 llvm_unreachable("invalid ownership attribute");
6266 case ParsedAttr::AT_NSReturnsAutoreleased:
6267 handleSimpleAttribute<NSReturnsAutoreleasedAttr>(S, D, AL);
6268 return;
6269 case ParsedAttr::AT_CFReturnsNotRetained:
6270 handleSimpleAttribute<CFReturnsNotRetainedAttr>(S, D, AL);
6271 return;
6272 case ParsedAttr::AT_NSReturnsNotRetained:
6273 handleSimpleAttribute<NSReturnsNotRetainedAttr>(S, D, AL);
6274 return;
6275 case ParsedAttr::AT_CFReturnsRetained:
6276 handleSimpleAttribute<CFReturnsRetainedAttr>(S, D, AL);
6277 return;
6278 case ParsedAttr::AT_NSReturnsRetained:
6279 handleSimpleAttribute<NSReturnsRetainedAttr>(S, D, AL);
6280 return;
6281 case ParsedAttr::AT_OSReturnsRetained:
6282 handleSimpleAttribute<OSReturnsRetainedAttr>(S, D, AL);
6283 return;
6284 case ParsedAttr::AT_OSReturnsNotRetained:
6285 handleSimpleAttribute<OSReturnsNotRetainedAttr>(S, D, AL);
6286 return;
6287 };
6288}
6289
6290static void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
6291 const ParsedAttr &Attrs) {
6292 const int EP_ObjCMethod = 1;
6293 const int EP_ObjCProperty = 2;
6294
6295 SourceLocation loc = Attrs.getLoc();
6296 QualType resultType;
6297 if (isa<ObjCMethodDecl>(Val: D))
6298 resultType = cast<ObjCMethodDecl>(Val: D)->getReturnType();
6299 else
6300 resultType = cast<ObjCPropertyDecl>(Val: D)->getType();
6301
6302 if (!resultType->isReferenceType() &&
6303 (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
6304 S.Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_return_type)
6305 << SourceRange(loc) << Attrs
6306 << (isa<ObjCMethodDecl>(D) ? EP_ObjCMethod : EP_ObjCProperty)
6307 << /*non-retainable pointer*/ 2;
6308
6309 // Drop the attribute.
6310 return;
6311 }
6312
6313 D->addAttr(::new (S.Context) ObjCReturnsInnerPointerAttr(S.Context, Attrs));
6314}
6315
6316static void handleObjCRequiresSuperAttr(Sema &S, Decl *D,
6317 const ParsedAttr &Attrs) {
6318 const auto *Method = cast<ObjCMethodDecl>(Val: D);
6319
6320 const DeclContext *DC = Method->getDeclContext();
6321 if (const auto *PDecl = dyn_cast_if_present<ObjCProtocolDecl>(DC)) {
6322 S.Diag(D->getBeginLoc(), diag::warn_objc_requires_super_protocol) << Attrs
6323 << 0;
6324 S.Diag(PDecl->getLocation(), diag::note_protocol_decl);
6325 return;
6326 }
6327 if (Method->getMethodFamily() == OMF_dealloc) {
6328 S.Diag(D->getBeginLoc(), diag::warn_objc_requires_super_protocol) << Attrs
6329 << 1;
6330 return;
6331 }
6332
6333 D->addAttr(::new (S.Context) ObjCRequiresSuperAttr(S.Context, Attrs));
6334}
6335
6336static void handleNSErrorDomain(Sema &S, Decl *D, const ParsedAttr &Attr) {
6337 if (!isa<TagDecl>(Val: D)) {
6338 S.Diag(D->getBeginLoc(), diag::err_nserrordomain_invalid_decl) << 0;
6339 return;
6340 }
6341
6342 IdentifierLoc *IdentLoc =
6343 Attr.isArgIdent(Arg: 0) ? Attr.getArgAsIdent(Arg: 0) : nullptr;
6344 if (!IdentLoc || !IdentLoc->Ident) {
6345 // Try to locate the argument directly.
6346 SourceLocation Loc = Attr.getLoc();
6347 if (Attr.isArgExpr(Arg: 0) && Attr.getArgAsExpr(Arg: 0))
6348 Loc = Attr.getArgAsExpr(Arg: 0)->getBeginLoc();
6349
6350 S.Diag(Loc, diag::err_nserrordomain_invalid_decl) << 0;
6351 return;
6352 }
6353
6354 // Verify that the identifier is a valid decl in the C decl namespace.
6355 LookupResult Result(S, DeclarationName(IdentLoc->Ident), SourceLocation(),
6356 Sema::LookupNameKind::LookupOrdinaryName);
6357 if (!S.LookupName(R&: Result, S: S.TUScope) || !Result.getAsSingle<VarDecl>()) {
6358 S.Diag(IdentLoc->Loc, diag::err_nserrordomain_invalid_decl)
6359 << 1 << IdentLoc->Ident;
6360 return;
6361 }
6362
6363 D->addAttr(::new (S.Context)
6364 NSErrorDomainAttr(S.Context, Attr, IdentLoc->Ident));
6365}
6366
6367static void handleObjCBridgeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6368 IdentifierLoc *Parm = AL.isArgIdent(Arg: 0) ? AL.getArgAsIdent(Arg: 0) : nullptr;
6369
6370 if (!Parm) {
6371 S.Diag(D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0;
6372 return;
6373 }
6374
6375 // Typedefs only allow objc_bridge(id) and have some additional checking.
6376 if (const auto *TD = dyn_cast<TypedefNameDecl>(Val: D)) {
6377 if (!Parm->Ident->isStr(Str: "id")) {
6378 S.Diag(AL.getLoc(), diag::err_objc_attr_typedef_not_id) << AL;
6379 return;
6380 }
6381
6382 // Only allow 'cv void *'.
6383 QualType T = TD->getUnderlyingType();
6384 if (!T->isVoidPointerType()) {
6385 S.Diag(AL.getLoc(), diag::err_objc_attr_typedef_not_void_pointer);
6386 return;
6387 }
6388 }
6389
6390 D->addAttr(::new (S.Context) ObjCBridgeAttr(S.Context, AL, Parm->Ident));
6391}
6392
6393static void handleObjCBridgeMutableAttr(Sema &S, Decl *D,
6394 const ParsedAttr &AL) {
6395 IdentifierLoc *Parm = AL.isArgIdent(Arg: 0) ? AL.getArgAsIdent(Arg: 0) : nullptr;
6396
6397 if (!Parm) {
6398 S.Diag(D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0;
6399 return;
6400 }
6401
6402 D->addAttr(::new (S.Context)
6403 ObjCBridgeMutableAttr(S.Context, AL, Parm->Ident));
6404}
6405
6406static void handleObjCBridgeRelatedAttr(Sema &S, Decl *D,
6407 const ParsedAttr &AL) {
6408 IdentifierInfo *RelatedClass =
6409 AL.isArgIdent(Arg: 0) ? AL.getArgAsIdent(Arg: 0)->Ident : nullptr;
6410 if (!RelatedClass) {
6411 S.Diag(D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0;
6412 return;
6413 }
6414 IdentifierInfo *ClassMethod =
6415 AL.getArgAsIdent(Arg: 1) ? AL.getArgAsIdent(Arg: 1)->Ident : nullptr;
6416 IdentifierInfo *InstanceMethod =
6417 AL.getArgAsIdent(Arg: 2) ? AL.getArgAsIdent(Arg: 2)->Ident : nullptr;
6418 D->addAttr(::new (S.Context) ObjCBridgeRelatedAttr(
6419 S.Context, AL, RelatedClass, ClassMethod, InstanceMethod));
6420}
6421
6422static void handleObjCDesignatedInitializer(Sema &S, Decl *D,
6423 const ParsedAttr &AL) {
6424 DeclContext *Ctx = D->getDeclContext();
6425
6426 // This attribute can only be applied to methods in interfaces or class
6427 // extensions.
6428 if (!isa<ObjCInterfaceDecl>(Val: Ctx) &&
6429 !(isa<ObjCCategoryDecl>(Val: Ctx) &&
6430 cast<ObjCCategoryDecl>(Val: Ctx)->IsClassExtension())) {
6431 S.Diag(D->getLocation(), diag::err_designated_init_attr_non_init);
6432 return;
6433 }
6434
6435 ObjCInterfaceDecl *IFace;
6436 if (auto *CatDecl = dyn_cast<ObjCCategoryDecl>(Val: Ctx))
6437 IFace = CatDecl->getClassInterface();
6438 else
6439 IFace = cast<ObjCInterfaceDecl>(Val: Ctx);
6440
6441 if (!IFace)
6442 return;
6443
6444 IFace->setHasDesignatedInitializers();
6445 D->addAttr(::new (S.Context) ObjCDesignatedInitializerAttr(S.Context, AL));
6446}
6447
6448static void handleObjCRuntimeName(Sema &S, Decl *D, const ParsedAttr &AL) {
6449 StringRef MetaDataName;
6450 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: MetaDataName))
6451 return;
6452 D->addAttr(::new (S.Context)
6453 ObjCRuntimeNameAttr(S.Context, AL, MetaDataName));
6454}
6455
6456// When a user wants to use objc_boxable with a union or struct
6457// but they don't have access to the declaration (legacy/third-party code)
6458// then they can 'enable' this feature with a typedef:
6459// typedef struct __attribute((objc_boxable)) legacy_struct legacy_struct;
6460static void handleObjCBoxable(Sema &S, Decl *D, const ParsedAttr &AL) {
6461 bool notify = false;
6462
6463 auto *RD = dyn_cast<RecordDecl>(Val: D);
6464 if (RD && RD->getDefinition()) {
6465 RD = RD->getDefinition();
6466 notify = true;
6467 }
6468
6469 if (RD) {
6470 ObjCBoxableAttr *BoxableAttr =
6471 ::new (S.Context) ObjCBoxableAttr(S.Context, AL);
6472 RD->addAttr(A: BoxableAttr);
6473 if (notify) {
6474 // we need to notify ASTReader/ASTWriter about
6475 // modification of existing declaration
6476 if (ASTMutationListener *L = S.getASTMutationListener())
6477 L->AddedAttributeToRecord(Attr: BoxableAttr, Record: RD);
6478 }
6479 }
6480}
6481
6482static void handleObjCOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6483 if (hasDeclarator(D))
6484 return;
6485
6486 S.Diag(D->getBeginLoc(), diag::err_attribute_wrong_decl_type)
6487 << AL.getRange() << AL << AL.isRegularKeywordAttribute()
6488 << ExpectedVariable;
6489}
6490
6491static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
6492 const ParsedAttr &AL) {
6493 const auto *VD = cast<ValueDecl>(Val: D);
6494 QualType QT = VD->getType();
6495
6496 if (!QT->isDependentType() &&
6497 !QT->isObjCLifetimeType()) {
6498 S.Diag(AL.getLoc(), diag::err_objc_precise_lifetime_bad_type)
6499 << QT;
6500 return;
6501 }
6502
6503 Qualifiers::ObjCLifetime Lifetime = QT.getObjCLifetime();
6504
6505 // If we have no lifetime yet, check the lifetime we're presumably
6506 // going to infer.
6507 if (Lifetime == Qualifiers::OCL_None && !QT->isDependentType())
6508 Lifetime = QT->getObjCARCImplicitLifetime();
6509
6510 switch (Lifetime) {
6511 case Qualifiers::OCL_None:
6512 assert(QT->isDependentType() &&
6513 "didn't infer lifetime for non-dependent type?");
6514 break;
6515
6516 case Qualifiers::OCL_Weak: // meaningful
6517 case Qualifiers::OCL_Strong: // meaningful
6518 break;
6519
6520 case Qualifiers::OCL_ExplicitNone:
6521 case Qualifiers::OCL_Autoreleasing:
6522 S.Diag(AL.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
6523 << (Lifetime == Qualifiers::OCL_Autoreleasing);
6524 break;
6525 }
6526
6527 D->addAttr(::new (S.Context) ObjCPreciseLifetimeAttr(S.Context, AL));
6528}
6529
6530static void handleSwiftAttrAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6531 // Make sure that there is a string literal as the annotation's single
6532 // argument.
6533 StringRef Str;
6534 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str))
6535 return;
6536
6537 D->addAttr(::new (S.Context) SwiftAttrAttr(S.Context, AL, Str));
6538}
6539
6540static void handleSwiftBridge(Sema &S, Decl *D, const ParsedAttr &AL) {
6541 // Make sure that there is a string literal as the annotation's single
6542 // argument.
6543 StringRef BT;
6544 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: BT))
6545 return;
6546
6547 // Warn about duplicate attributes if they have different arguments, but drop
6548 // any duplicate attributes regardless.
6549 if (const auto *Other = D->getAttr<SwiftBridgeAttr>()) {
6550 if (Other->getSwiftType() != BT)
6551 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
6552 return;
6553 }
6554
6555 D->addAttr(::new (S.Context) SwiftBridgeAttr(S.Context, AL, BT));
6556}
6557
6558static bool isErrorParameter(Sema &S, QualType QT) {
6559 const auto *PT = QT->getAs<PointerType>();
6560 if (!PT)
6561 return false;
6562
6563 QualType Pointee = PT->getPointeeType();
6564
6565 // Check for NSError**.
6566 if (const auto *OPT = Pointee->getAs<ObjCObjectPointerType>())
6567 if (const auto *ID = OPT->getInterfaceDecl())
6568 if (ID->getIdentifier() == S.getNSErrorIdent())
6569 return true;
6570
6571 // Check for CFError**.
6572 if (const auto *PT = Pointee->getAs<PointerType>())
6573 if (const auto *RT = PT->getPointeeType()->getAs<RecordType>())
6574 if (S.isCFError(D: RT->getDecl()))
6575 return true;
6576
6577 return false;
6578}
6579
6580static void handleSwiftError(Sema &S, Decl *D, const ParsedAttr &AL) {
6581 auto hasErrorParameter = [](Sema &S, Decl *D, const ParsedAttr &AL) -> bool {
6582 for (unsigned I = 0, E = getFunctionOrMethodNumParams(D); I != E; ++I) {
6583 if (isErrorParameter(S, QT: getFunctionOrMethodParamType(D, Idx: I)))
6584 return true;
6585 }
6586
6587 S.Diag(AL.getLoc(), diag::err_attr_swift_error_no_error_parameter)
6588 << AL << isa<ObjCMethodDecl>(D);
6589 return false;
6590 };
6591
6592 auto hasPointerResult = [](Sema &S, Decl *D, const ParsedAttr &AL) -> bool {
6593 // - C, ObjC, and block pointers are definitely okay.
6594 // - References are definitely not okay.
6595 // - nullptr_t is weird, but acceptable.
6596 QualType RT = getFunctionOrMethodResultType(D);
6597 if (RT->hasPointerRepresentation() && !RT->isReferenceType())
6598 return true;
6599
6600 S.Diag(AL.getLoc(), diag::err_attr_swift_error_return_type)
6601 << AL << AL.getArgAsIdent(0)->Ident->getName() << isa<ObjCMethodDecl>(D)
6602 << /*pointer*/ 1;
6603 return false;
6604 };
6605
6606 auto hasIntegerResult = [](Sema &S, Decl *D, const ParsedAttr &AL) -> bool {
6607 QualType RT = getFunctionOrMethodResultType(D);
6608 if (RT->isIntegralType(Ctx: S.Context))
6609 return true;
6610
6611 S.Diag(AL.getLoc(), diag::err_attr_swift_error_return_type)
6612 << AL << AL.getArgAsIdent(0)->Ident->getName() << isa<ObjCMethodDecl>(D)
6613 << /*integral*/ 0;
6614 return false;
6615 };
6616
6617 if (D->isInvalidDecl())
6618 return;
6619
6620 IdentifierLoc *Loc = AL.getArgAsIdent(Arg: 0);
6621 SwiftErrorAttr::ConventionKind Convention;
6622 if (!SwiftErrorAttr::ConvertStrToConventionKind(Loc->Ident->getName(),
6623 Convention)) {
6624 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
6625 << AL << Loc->Ident;
6626 return;
6627 }
6628
6629 switch (Convention) {
6630 case SwiftErrorAttr::None:
6631 // No additional validation required.
6632 break;
6633
6634 case SwiftErrorAttr::NonNullError:
6635 if (!hasErrorParameter(S, D, AL))
6636 return;
6637 break;
6638
6639 case SwiftErrorAttr::NullResult:
6640 if (!hasErrorParameter(S, D, AL) || !hasPointerResult(S, D, AL))
6641 return;
6642 break;
6643
6644 case SwiftErrorAttr::NonZeroResult:
6645 case SwiftErrorAttr::ZeroResult:
6646 if (!hasErrorParameter(S, D, AL) || !hasIntegerResult(S, D, AL))
6647 return;
6648 break;
6649 }
6650
6651 D->addAttr(::new (S.Context) SwiftErrorAttr(S.Context, AL, Convention));
6652}
6653
6654static void checkSwiftAsyncErrorBlock(Sema &S, Decl *D,
6655 const SwiftAsyncErrorAttr *ErrorAttr,
6656 const SwiftAsyncAttr *AsyncAttr) {
6657 if (AsyncAttr->getKind() == SwiftAsyncAttr::None) {
6658 if (ErrorAttr->getConvention() != SwiftAsyncErrorAttr::None) {
6659 S.Diag(AsyncAttr->getLocation(),
6660 diag::err_swift_async_error_without_swift_async)
6661 << AsyncAttr << isa<ObjCMethodDecl>(D);
6662 }
6663 return;
6664 }
6665
6666 const ParmVarDecl *HandlerParam = getFunctionOrMethodParam(
6667 D, AsyncAttr->getCompletionHandlerIndex().getASTIndex());
6668 // handleSwiftAsyncAttr already verified the type is correct, so no need to
6669 // double-check it here.
6670 const auto *FuncTy = HandlerParam->getType()
6671 ->castAs<BlockPointerType>()
6672 ->getPointeeType()
6673 ->getAs<FunctionProtoType>();
6674 ArrayRef<QualType> BlockParams;
6675 if (FuncTy)
6676 BlockParams = FuncTy->getParamTypes();
6677
6678 switch (ErrorAttr->getConvention()) {
6679 case SwiftAsyncErrorAttr::ZeroArgument:
6680 case SwiftAsyncErrorAttr::NonZeroArgument: {
6681 uint32_t ParamIdx = ErrorAttr->getHandlerParamIdx();
6682 if (ParamIdx == 0 || ParamIdx > BlockParams.size()) {
6683 S.Diag(ErrorAttr->getLocation(),
6684 diag::err_attribute_argument_out_of_bounds) << ErrorAttr << 2;
6685 return;
6686 }
6687 QualType ErrorParam = BlockParams[ParamIdx - 1];
6688 if (!ErrorParam->isIntegralType(Ctx: S.Context)) {
6689 StringRef ConvStr =
6690 ErrorAttr->getConvention() == SwiftAsyncErrorAttr::ZeroArgument
6691 ? "zero_argument"
6692 : "nonzero_argument";
6693 S.Diag(ErrorAttr->getLocation(), diag::err_swift_async_error_non_integral)
6694 << ErrorAttr << ConvStr << ParamIdx << ErrorParam;
6695 return;
6696 }
6697 break;
6698 }
6699 case SwiftAsyncErrorAttr::NonNullError: {
6700 bool AnyErrorParams = false;
6701 for (QualType Param : BlockParams) {
6702 // Check for NSError *.
6703 if (const auto *ObjCPtrTy = Param->getAs<ObjCObjectPointerType>()) {
6704 if (const auto *ID = ObjCPtrTy->getInterfaceDecl()) {
6705 if (ID->getIdentifier() == S.getNSErrorIdent()) {
6706 AnyErrorParams = true;
6707 break;
6708 }
6709 }
6710 }
6711 // Check for CFError *.
6712 if (const auto *PtrTy = Param->getAs<PointerType>()) {
6713 if (const auto *RT = PtrTy->getPointeeType()->getAs<RecordType>()) {
6714 if (S.isCFError(D: RT->getDecl())) {
6715 AnyErrorParams = true;
6716 break;
6717 }
6718 }
6719 }
6720 }
6721
6722 if (!AnyErrorParams) {
6723 S.Diag(ErrorAttr->getLocation(),
6724 diag::err_swift_async_error_no_error_parameter)
6725 << ErrorAttr << isa<ObjCMethodDecl>(D);
6726 return;
6727 }
6728 break;
6729 }
6730 case SwiftAsyncErrorAttr::None:
6731 break;
6732 }
6733}
6734
6735static void handleSwiftAsyncError(Sema &S, Decl *D, const ParsedAttr &AL) {
6736 IdentifierLoc *IDLoc = AL.getArgAsIdent(Arg: 0);
6737 SwiftAsyncErrorAttr::ConventionKind ConvKind;
6738 if (!SwiftAsyncErrorAttr::ConvertStrToConventionKind(IDLoc->Ident->getName(),
6739 ConvKind)) {
6740 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
6741 << AL << IDLoc->Ident;
6742 return;
6743 }
6744
6745 uint32_t ParamIdx = 0;
6746 switch (ConvKind) {
6747 case SwiftAsyncErrorAttr::ZeroArgument:
6748 case SwiftAsyncErrorAttr::NonZeroArgument: {
6749 if (!AL.checkExactlyNumArgs(S, Num: 2))
6750 return;
6751
6752 Expr *IdxExpr = AL.getArgAsExpr(Arg: 1);
6753 if (!checkUInt32Argument(S, AI: AL, Expr: IdxExpr, Val&: ParamIdx))
6754 return;
6755 break;
6756 }
6757 case SwiftAsyncErrorAttr::NonNullError:
6758 case SwiftAsyncErrorAttr::None: {
6759 if (!AL.checkExactlyNumArgs(S, Num: 1))
6760 return;
6761 break;
6762 }
6763 }
6764
6765 auto *ErrorAttr =
6766 ::new (S.Context) SwiftAsyncErrorAttr(S.Context, AL, ConvKind, ParamIdx);
6767 D->addAttr(A: ErrorAttr);
6768
6769 if (auto *AsyncAttr = D->getAttr<SwiftAsyncAttr>())
6770 checkSwiftAsyncErrorBlock(S, D, ErrorAttr, AsyncAttr);
6771}
6772
6773// For a function, this will validate a compound Swift name, e.g.
6774// <code>init(foo:bar:baz:)</code> or <code>controllerForName(_:)</code>, and
6775// the function will output the number of parameter names, and whether this is a
6776// single-arg initializer.
6777//
6778// For a type, enum constant, property, or variable declaration, this will
6779// validate either a simple identifier, or a qualified
6780// <code>context.identifier</code> name.
6781static bool
6782validateSwiftFunctionName(Sema &S, const ParsedAttr &AL, SourceLocation Loc,
6783 StringRef Name, unsigned &SwiftParamCount,
6784 bool &IsSingleParamInit) {
6785 SwiftParamCount = 0;
6786 IsSingleParamInit = false;
6787
6788 // Check whether this will be mapped to a getter or setter of a property.
6789 bool IsGetter = false, IsSetter = false;
6790 if (Name.consume_front(Prefix: "getter:"))
6791 IsGetter = true;
6792 else if (Name.consume_front(Prefix: "setter:"))
6793 IsSetter = true;
6794
6795 if (Name.back() != ')') {
6796 S.Diag(Loc, diag::warn_attr_swift_name_function) << AL;
6797 return false;
6798 }
6799
6800 bool IsMember = false;
6801 StringRef ContextName, BaseName, Parameters;
6802
6803 std::tie(args&: BaseName, args&: Parameters) = Name.split(Separator: '(');
6804
6805 // Split at the first '.', if it exists, which separates the context name
6806 // from the base name.
6807 std::tie(args&: ContextName, args&: BaseName) = BaseName.split(Separator: '.');
6808 if (BaseName.empty()) {
6809 BaseName = ContextName;
6810 ContextName = StringRef();
6811 } else if (ContextName.empty() || !isValidAsciiIdentifier(S: ContextName)) {
6812 S.Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
6813 << AL << /*context*/ 1;
6814 return false;
6815 } else {
6816 IsMember = true;
6817 }
6818
6819 if (!isValidAsciiIdentifier(S: BaseName) || BaseName == "_") {
6820 S.Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
6821 << AL << /*basename*/ 0;
6822 return false;
6823 }
6824
6825 bool IsSubscript = BaseName == "subscript";
6826 // A subscript accessor must be a getter or setter.
6827 if (IsSubscript && !IsGetter && !IsSetter) {
6828 S.Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
6829 << AL << /* getter or setter */ 0;
6830 return false;
6831 }
6832
6833 if (Parameters.empty()) {
6834 S.Diag(Loc, diag::warn_attr_swift_name_missing_parameters) << AL;
6835 return false;
6836 }
6837
6838 assert(Parameters.back() == ')' && "expected ')'");
6839 Parameters = Parameters.drop_back(); // ')'
6840
6841 if (Parameters.empty()) {
6842 // Setters and subscripts must have at least one parameter.
6843 if (IsSubscript) {
6844 S.Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
6845 << AL << /* have at least one parameter */1;
6846 return false;
6847 }
6848
6849 if (IsSetter) {
6850 S.Diag(Loc, diag::warn_attr_swift_name_setter_parameters) << AL;
6851 return false;
6852 }
6853
6854 return true;
6855 }
6856
6857 if (Parameters.back() != ':') {
6858 S.Diag(Loc, diag::warn_attr_swift_name_function) << AL;
6859 return false;
6860 }
6861
6862 StringRef CurrentParam;
6863 std::optional<unsigned> SelfLocation;
6864 unsigned NewValueCount = 0;
6865 std::optional<unsigned> NewValueLocation;
6866 do {
6867 std::tie(args&: CurrentParam, args&: Parameters) = Parameters.split(Separator: ':');
6868
6869 if (!isValidAsciiIdentifier(S: CurrentParam)) {
6870 S.Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
6871 << AL << /*parameter*/2;
6872 return false;
6873 }
6874
6875 if (IsMember && CurrentParam == "self") {
6876 // "self" indicates the "self" argument for a member.
6877
6878 // More than one "self"?
6879 if (SelfLocation) {
6880 S.Diag(Loc, diag::warn_attr_swift_name_multiple_selfs) << AL;
6881 return false;
6882 }
6883
6884 // The "self" location is the current parameter.
6885 SelfLocation = SwiftParamCount;
6886 } else if (CurrentParam == "newValue") {
6887 // "newValue" indicates the "newValue" argument for a setter.
6888
6889 // There should only be one 'newValue', but it's only significant for
6890 // subscript accessors, so don't error right away.
6891 ++NewValueCount;
6892
6893 NewValueLocation = SwiftParamCount;
6894 }
6895
6896 ++SwiftParamCount;
6897 } while (!Parameters.empty());
6898
6899 // Only instance subscripts are currently supported.
6900 if (IsSubscript && !SelfLocation) {
6901 S.Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
6902 << AL << /*have a 'self:' parameter*/2;
6903 return false;
6904 }
6905
6906 IsSingleParamInit =
6907 SwiftParamCount == 1 && BaseName == "init" && CurrentParam != "_";
6908
6909 // Check the number of parameters for a getter/setter.
6910 if (IsGetter || IsSetter) {
6911 // Setters have one parameter for the new value.
6912 unsigned NumExpectedParams = IsGetter ? 0 : 1;
6913 unsigned ParamDiag =
6914 IsGetter ? diag::warn_attr_swift_name_getter_parameters
6915 : diag::warn_attr_swift_name_setter_parameters;
6916
6917 // Instance methods have one parameter for "self".
6918 if (SelfLocation)
6919 ++NumExpectedParams;
6920
6921 // Subscripts may have additional parameters beyond the expected params for
6922 // the index.
6923 if (IsSubscript) {
6924 if (SwiftParamCount < NumExpectedParams) {
6925 S.Diag(Loc, ParamDiag) << AL;
6926 return false;
6927 }
6928
6929 // A subscript setter must explicitly label its newValue parameter to
6930 // distinguish it from index parameters.
6931 if (IsSetter) {
6932 if (!NewValueLocation) {
6933 S.Diag(Loc, diag::warn_attr_swift_name_subscript_setter_no_newValue)
6934 << AL;
6935 return false;
6936 }
6937 if (NewValueCount > 1) {
6938 S.Diag(Loc, diag::warn_attr_swift_name_subscript_setter_multiple_newValues)
6939 << AL;
6940 return false;
6941 }
6942 } else {
6943 // Subscript getters should have no 'newValue:' parameter.
6944 if (NewValueLocation) {
6945 S.Diag(Loc, diag::warn_attr_swift_name_subscript_getter_newValue)
6946 << AL;
6947 return false;
6948 }
6949 }
6950 } else {
6951 // Property accessors must have exactly the number of expected params.
6952 if (SwiftParamCount != NumExpectedParams) {
6953 S.Diag(Loc, ParamDiag) << AL;
6954 return false;
6955 }
6956 }
6957 }
6958
6959 return true;
6960}
6961
6962bool Sema::DiagnoseSwiftName(Decl *D, StringRef Name, SourceLocation Loc,
6963 const ParsedAttr &AL, bool IsAsync) {
6964 if (isa<ObjCMethodDecl>(Val: D) || isa<FunctionDecl>(Val: D)) {
6965 ArrayRef<ParmVarDecl*> Params;
6966 unsigned ParamCount;
6967
6968 if (const auto *Method = dyn_cast<ObjCMethodDecl>(Val: D)) {
6969 ParamCount = Method->getSelector().getNumArgs();
6970 Params = Method->parameters().slice(N: 0, M: ParamCount);
6971 } else {
6972 const auto *F = cast<FunctionDecl>(Val: D);
6973
6974 ParamCount = F->getNumParams();
6975 Params = F->parameters();
6976
6977 if (!F->hasWrittenPrototype()) {
6978 Diag(Loc, diag::warn_attribute_wrong_decl_type)
6979 << AL << AL.isRegularKeywordAttribute()
6980 << ExpectedFunctionWithProtoType;
6981 return false;
6982 }
6983 }
6984
6985 // The async name drops the last callback parameter.
6986 if (IsAsync) {
6987 if (ParamCount == 0) {
6988 Diag(Loc, diag::warn_attr_swift_name_decl_missing_params)
6989 << AL << isa<ObjCMethodDecl>(D);
6990 return false;
6991 }
6992 ParamCount -= 1;
6993 }
6994
6995 unsigned SwiftParamCount;
6996 bool IsSingleParamInit;
6997 if (!validateSwiftFunctionName(S&: *this, AL, Loc, Name,
6998 SwiftParamCount, IsSingleParamInit))
6999 return false;
7000
7001 bool ParamCountValid;
7002 if (SwiftParamCount == ParamCount) {
7003 ParamCountValid = true;
7004 } else if (SwiftParamCount > ParamCount) {
7005 ParamCountValid = IsSingleParamInit && ParamCount == 0;
7006 } else {
7007 // We have fewer Swift parameters than Objective-C parameters, but that
7008 // might be because we've transformed some of them. Check for potential
7009 // "out" parameters and err on the side of not warning.
7010 unsigned MaybeOutParamCount =
7011 llvm::count_if(Range&: Params, P: [](const ParmVarDecl *Param) -> bool {
7012 QualType ParamTy = Param->getType();
7013 if (ParamTy->isReferenceType() || ParamTy->isPointerType())
7014 return !ParamTy->getPointeeType().isConstQualified();
7015 return false;
7016 });
7017
7018 ParamCountValid = SwiftParamCount + MaybeOutParamCount >= ParamCount;
7019 }
7020
7021 if (!ParamCountValid) {
7022 Diag(Loc, diag::warn_attr_swift_name_num_params)
7023 << (SwiftParamCount > ParamCount) << AL << ParamCount
7024 << SwiftParamCount;
7025 return false;
7026 }
7027 } else if ((isa<EnumConstantDecl>(Val: D) || isa<ObjCProtocolDecl>(Val: D) ||
7028 isa<ObjCInterfaceDecl>(Val: D) || isa<ObjCPropertyDecl>(Val: D) ||
7029 isa<VarDecl>(Val: D) || isa<TypedefNameDecl>(Val: D) || isa<TagDecl>(Val: D) ||
7030 isa<IndirectFieldDecl>(Val: D) || isa<FieldDecl>(Val: D)) &&
7031 !IsAsync) {
7032 StringRef ContextName, BaseName;
7033
7034 std::tie(args&: ContextName, args&: BaseName) = Name.split(Separator: '.');
7035 if (BaseName.empty()) {
7036 BaseName = ContextName;
7037 ContextName = StringRef();
7038 } else if (!isValidAsciiIdentifier(S: ContextName)) {
7039 Diag(Loc, diag::warn_attr_swift_name_invalid_identifier) << AL
7040 << /*context*/1;
7041 return false;
7042 }
7043
7044 if (!isValidAsciiIdentifier(S: BaseName)) {
7045 Diag(Loc, diag::warn_attr_swift_name_invalid_identifier) << AL
7046 << /*basename*/0;
7047 return false;
7048 }
7049 } else {
7050 Diag(Loc, diag::warn_attr_swift_name_decl_kind) << AL;
7051 return false;
7052 }
7053 return true;
7054}
7055
7056static void handleSwiftName(Sema &S, Decl *D, const ParsedAttr &AL) {
7057 StringRef Name;
7058 SourceLocation Loc;
7059 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: Name, ArgLocation: &Loc))
7060 return;
7061
7062 if (!S.DiagnoseSwiftName(D, Name, Loc, AL, /*IsAsync=*/false))
7063 return;
7064
7065 D->addAttr(::new (S.Context) SwiftNameAttr(S.Context, AL, Name));
7066}
7067
7068static void handleSwiftAsyncName(Sema &S, Decl *D, const ParsedAttr &AL) {
7069 StringRef Name;
7070 SourceLocation Loc;
7071 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: Name, ArgLocation: &Loc))
7072 return;
7073
7074 if (!S.DiagnoseSwiftName(D, Name, Loc, AL, /*IsAsync=*/true))
7075 return;
7076
7077 D->addAttr(::new (S.Context) SwiftAsyncNameAttr(S.Context, AL, Name));
7078}
7079
7080static void handleSwiftNewType(Sema &S, Decl *D, const ParsedAttr &AL) {
7081 // Make sure that there is an identifier as the annotation's single argument.
7082 if (!AL.checkExactlyNumArgs(S, Num: 1))
7083 return;
7084
7085 if (!AL.isArgIdent(Arg: 0)) {
7086 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7087 << AL << AANT_ArgumentIdentifier;
7088 return;
7089 }
7090
7091 SwiftNewTypeAttr::NewtypeKind Kind;
7092 IdentifierInfo *II = AL.getArgAsIdent(Arg: 0)->Ident;
7093 if (!SwiftNewTypeAttr::ConvertStrToNewtypeKind(II->getName(), Kind)) {
7094 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
7095 return;
7096 }
7097
7098 if (!isa<TypedefNameDecl>(Val: D)) {
7099 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type_str)
7100 << AL << AL.isRegularKeywordAttribute() << "typedefs";
7101 return;
7102 }
7103
7104 D->addAttr(::new (S.Context) SwiftNewTypeAttr(S.Context, AL, Kind));
7105}
7106
7107static void handleSwiftAsyncAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7108 if (!AL.isArgIdent(Arg: 0)) {
7109 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
7110 << AL << 1 << AANT_ArgumentIdentifier;
7111 return;
7112 }
7113
7114 SwiftAsyncAttr::Kind Kind;
7115 IdentifierInfo *II = AL.getArgAsIdent(Arg: 0)->Ident;
7116 if (!SwiftAsyncAttr::ConvertStrToKind(II->getName(), Kind)) {
7117 S.Diag(AL.getLoc(), diag::err_swift_async_no_access) << AL << II;
7118 return;
7119 }
7120
7121 ParamIdx Idx;
7122 if (Kind == SwiftAsyncAttr::None) {
7123 // If this is 'none', then there shouldn't be any additional arguments.
7124 if (!AL.checkExactlyNumArgs(S, Num: 1))
7125 return;
7126 } else {
7127 // Non-none swift_async requires a completion handler index argument.
7128 if (!AL.checkExactlyNumArgs(S, Num: 2))
7129 return;
7130
7131 Expr *HandlerIdx = AL.getArgAsExpr(Arg: 1);
7132 if (!checkFunctionOrMethodParameterIndex(S, D, AI: AL, AttrArgNum: 2, IdxExpr: HandlerIdx, Idx))
7133 return;
7134
7135 const ParmVarDecl *CompletionBlock =
7136 getFunctionOrMethodParam(D, Idx: Idx.getASTIndex());
7137 QualType CompletionBlockType = CompletionBlock->getType();
7138 if (!CompletionBlockType->isBlockPointerType()) {
7139 S.Diag(CompletionBlock->getLocation(),
7140 diag::err_swift_async_bad_block_type)
7141 << CompletionBlock->getType();
7142 return;
7143 }
7144 QualType BlockTy =
7145 CompletionBlockType->castAs<BlockPointerType>()->getPointeeType();
7146 if (!BlockTy->castAs<FunctionType>()->getReturnType()->isVoidType()) {
7147 S.Diag(CompletionBlock->getLocation(),
7148 diag::err_swift_async_bad_block_type)
7149 << CompletionBlock->getType();
7150 return;
7151 }
7152 }
7153
7154 auto *AsyncAttr =
7155 ::new (S.Context) SwiftAsyncAttr(S.Context, AL, Kind, Idx);
7156 D->addAttr(A: AsyncAttr);
7157
7158 if (auto *ErrorAttr = D->getAttr<SwiftAsyncErrorAttr>())
7159 checkSwiftAsyncErrorBlock(S, D, ErrorAttr, AsyncAttr);
7160}
7161
7162//===----------------------------------------------------------------------===//
7163// Microsoft specific attribute handlers.
7164//===----------------------------------------------------------------------===//
7165
7166UuidAttr *Sema::mergeUuidAttr(Decl *D, const AttributeCommonInfo &CI,
7167 StringRef UuidAsWritten, MSGuidDecl *GuidDecl) {
7168 if (const auto *UA = D->getAttr<UuidAttr>()) {
7169 if (declaresSameEntity(UA->getGuidDecl(), GuidDecl))
7170 return nullptr;
7171 if (!UA->getGuid().empty()) {
7172 Diag(UA->getLocation(), diag::err_mismatched_uuid);
7173 Diag(CI.getLoc(), diag::note_previous_uuid);
7174 D->dropAttr<UuidAttr>();
7175 }
7176 }
7177
7178 return ::new (Context) UuidAttr(Context, CI, UuidAsWritten, GuidDecl);
7179}
7180
7181static void handleUuidAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7182 if (!S.LangOpts.CPlusPlus) {
7183 S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)
7184 << AL << AttributeLangSupport::C;
7185 return;
7186 }
7187
7188 StringRef OrigStrRef;
7189 SourceLocation LiteralLoc;
7190 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: OrigStrRef, ArgLocation: &LiteralLoc))
7191 return;
7192
7193 // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
7194 // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", normalize to the former.
7195 StringRef StrRef = OrigStrRef;
7196 if (StrRef.size() == 38 && StrRef.front() == '{' && StrRef.back() == '}')
7197 StrRef = StrRef.drop_front().drop_back();
7198
7199 // Validate GUID length.
7200 if (StrRef.size() != 36) {
7201 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
7202 return;
7203 }
7204
7205 for (unsigned i = 0; i < 36; ++i) {
7206 if (i == 8 || i == 13 || i == 18 || i == 23) {
7207 if (StrRef[i] != '-') {
7208 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
7209 return;
7210 }
7211 } else if (!isHexDigit(c: StrRef[i])) {
7212 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
7213 return;
7214 }
7215 }
7216
7217 // Convert to our parsed format and canonicalize.
7218 MSGuidDecl::Parts Parsed;
7219 StrRef.substr(Start: 0, N: 8).getAsInteger(Radix: 16, Result&: Parsed.Part1);
7220 StrRef.substr(Start: 9, N: 4).getAsInteger(Radix: 16, Result&: Parsed.Part2);
7221 StrRef.substr(Start: 14, N: 4).getAsInteger(Radix: 16, Result&: Parsed.Part3);
7222 for (unsigned i = 0; i != 8; ++i)
7223 StrRef.substr(Start: 19 + 2 * i + (i >= 2 ? 1 : 0), N: 2)
7224 .getAsInteger(Radix: 16, Result&: Parsed.Part4And5[i]);
7225 MSGuidDecl *Guid = S.Context.getMSGuidDecl(Parsed);
7226
7227 // FIXME: It'd be nice to also emit a fixit removing uuid(...) (and, if it's
7228 // the only thing in the [] list, the [] too), and add an insertion of
7229 // __declspec(uuid(...)). But sadly, neither the SourceLocs of the commas
7230 // separating attributes nor of the [ and the ] are in the AST.
7231 // Cf "SourceLocations of attribute list delimiters - [[ ... , ... ]] etc"
7232 // on cfe-dev.
7233 if (AL.isMicrosoftAttribute()) // Check for [uuid(...)] spelling.
7234 S.Diag(AL.getLoc(), diag::warn_atl_uuid_deprecated);
7235
7236 UuidAttr *UA = S.mergeUuidAttr(D, AL, OrigStrRef, Guid);
7237 if (UA)
7238 D->addAttr(A: UA);
7239}
7240
7241static void handleHLSLNumThreadsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7242 llvm::VersionTuple SMVersion =
7243 S.Context.getTargetInfo().getTriple().getOSVersion();
7244 uint32_t ZMax = 1024;
7245 uint32_t ThreadMax = 1024;
7246 if (SMVersion.getMajor() <= 4) {
7247 ZMax = 1;
7248 ThreadMax = 768;
7249 } else if (SMVersion.getMajor() == 5) {
7250 ZMax = 64;
7251 ThreadMax = 1024;
7252 }
7253
7254 uint32_t X;
7255 if (!checkUInt32Argument(S, AI: AL, Expr: AL.getArgAsExpr(Arg: 0), Val&: X))
7256 return;
7257 if (X > 1024) {
7258 S.Diag(AL.getArgAsExpr(0)->getExprLoc(),
7259 diag::err_hlsl_numthreads_argument_oor) << 0 << 1024;
7260 return;
7261 }
7262 uint32_t Y;
7263 if (!checkUInt32Argument(S, AI: AL, Expr: AL.getArgAsExpr(Arg: 1), Val&: Y))
7264 return;
7265 if (Y > 1024) {
7266 S.Diag(AL.getArgAsExpr(1)->getExprLoc(),
7267 diag::err_hlsl_numthreads_argument_oor) << 1 << 1024;
7268 return;
7269 }
7270 uint32_t Z;
7271 if (!checkUInt32Argument(S, AI: AL, Expr: AL.getArgAsExpr(Arg: 2), Val&: Z))
7272 return;
7273 if (Z > ZMax) {
7274 S.Diag(AL.getArgAsExpr(2)->getExprLoc(),
7275 diag::err_hlsl_numthreads_argument_oor) << 2 << ZMax;
7276 return;
7277 }
7278
7279 if (X * Y * Z > ThreadMax) {
7280 S.Diag(AL.getLoc(), diag::err_hlsl_numthreads_invalid) << ThreadMax;
7281 return;
7282 }
7283
7284 HLSLNumThreadsAttr *NewAttr = S.HLSL().mergeNumThreadsAttr(D, AL, X, Y, Z);
7285 if (NewAttr)
7286 D->addAttr(A: NewAttr);
7287}
7288
7289static bool isLegalTypeForHLSLSV_DispatchThreadID(QualType T) {
7290 if (!T->hasUnsignedIntegerRepresentation())
7291 return false;
7292 if (const auto *VT = T->getAs<VectorType>())
7293 return VT->getNumElements() <= 3;
7294 return true;
7295}
7296
7297static void handleHLSLSV_DispatchThreadIDAttr(Sema &S, Decl *D,
7298 const ParsedAttr &AL) {
7299 // FIXME: support semantic on field.
7300 // See https://github.com/llvm/llvm-project/issues/57889.
7301 if (isa<FieldDecl>(Val: D)) {
7302 S.Diag(AL.getLoc(), diag::err_hlsl_attr_invalid_ast_node)
7303 << AL << "parameter";
7304 return;
7305 }
7306
7307 auto *VD = cast<ValueDecl>(Val: D);
7308 if (!isLegalTypeForHLSLSV_DispatchThreadID(T: VD->getType())) {
7309 S.Diag(AL.getLoc(), diag::err_hlsl_attr_invalid_type)
7310 << AL << "uint/uint2/uint3";
7311 return;
7312 }
7313
7314 D->addAttr(::new (S.Context) HLSLSV_DispatchThreadIDAttr(S.Context, AL));
7315}
7316
7317static void handleHLSLShaderAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7318 StringRef Str;
7319 SourceLocation ArgLoc;
7320 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str, ArgLocation: &ArgLoc))
7321 return;
7322
7323 HLSLShaderAttr::ShaderType ShaderType;
7324 if (!HLSLShaderAttr::ConvertStrToShaderType(Str, ShaderType)) {
7325 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
7326 << AL << Str << ArgLoc;
7327 return;
7328 }
7329
7330 // FIXME: check function match the shader stage.
7331
7332 HLSLShaderAttr *NewAttr = S.HLSL().mergeShaderAttr(D, AL, ShaderType);
7333 if (NewAttr)
7334 D->addAttr(A: NewAttr);
7335}
7336
7337static void handleHLSLResourceBindingAttr(Sema &S, Decl *D,
7338 const ParsedAttr &AL) {
7339 StringRef Space = "space0";
7340 StringRef Slot = "";
7341
7342 if (!AL.isArgIdent(Arg: 0)) {
7343 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7344 << AL << AANT_ArgumentIdentifier;
7345 return;
7346 }
7347
7348 IdentifierLoc *Loc = AL.getArgAsIdent(Arg: 0);
7349 StringRef Str = Loc->Ident->getName();
7350 SourceLocation ArgLoc = Loc->Loc;
7351
7352 SourceLocation SpaceArgLoc;
7353 if (AL.getNumArgs() == 2) {
7354 Slot = Str;
7355 if (!AL.isArgIdent(Arg: 1)) {
7356 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7357 << AL << AANT_ArgumentIdentifier;
7358 return;
7359 }
7360
7361 IdentifierLoc *Loc = AL.getArgAsIdent(Arg: 1);
7362 Space = Loc->Ident->getName();
7363 SpaceArgLoc = Loc->Loc;
7364 } else {
7365 Slot = Str;
7366 }
7367
7368 // Validate.
7369 if (!Slot.empty()) {
7370 switch (Slot[0]) {
7371 case 'u':
7372 case 'b':
7373 case 's':
7374 case 't':
7375 break;
7376 default:
7377 S.Diag(ArgLoc, diag::err_hlsl_unsupported_register_type)
7378 << Slot.substr(0, 1);
7379 return;
7380 }
7381
7382 StringRef SlotNum = Slot.substr(Start: 1);
7383 unsigned Num = 0;
7384 if (SlotNum.getAsInteger(Radix: 10, Result&: Num)) {
7385 S.Diag(ArgLoc, diag::err_hlsl_unsupported_register_number);
7386 return;
7387 }
7388 }
7389
7390 if (!Space.starts_with(Prefix: "space")) {
7391 S.Diag(SpaceArgLoc, diag::err_hlsl_expected_space) << Space;
7392 return;
7393 }
7394 StringRef SpaceNum = Space.substr(Start: 5);
7395 unsigned Num = 0;
7396 if (SpaceNum.getAsInteger(Radix: 10, Result&: Num)) {
7397 S.Diag(SpaceArgLoc, diag::err_hlsl_expected_space) << Space;
7398 return;
7399 }
7400
7401 // FIXME: check reg type match decl. Issue
7402 // https://github.com/llvm/llvm-project/issues/57886.
7403 HLSLResourceBindingAttr *NewAttr =
7404 HLSLResourceBindingAttr::Create(S.getASTContext(), Slot, Space, AL);
7405 if (NewAttr)
7406 D->addAttr(A: NewAttr);
7407}
7408
7409static void handleHLSLParamModifierAttr(Sema &S, Decl *D,
7410 const ParsedAttr &AL) {
7411 HLSLParamModifierAttr *NewAttr = S.HLSL().mergeParamModifierAttr(
7412 D, AL,
7413 static_cast<HLSLParamModifierAttr::Spelling>(AL.getSemanticSpelling()));
7414 if (NewAttr)
7415 D->addAttr(A: NewAttr);
7416}
7417
7418static void handleMSInheritanceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7419 if (!S.LangOpts.CPlusPlus) {
7420 S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)
7421 << AL << AttributeLangSupport::C;
7422 return;
7423 }
7424 MSInheritanceAttr *IA = S.mergeMSInheritanceAttr(
7425 D, AL, /*BestCase=*/true, (MSInheritanceModel)AL.getSemanticSpelling());
7426 if (IA) {
7427 D->addAttr(A: IA);
7428 S.Consumer.AssignInheritanceModel(RD: cast<CXXRecordDecl>(Val: D));
7429 }
7430}
7431
7432static void handleDeclspecThreadAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7433 const auto *VD = cast<VarDecl>(Val: D);
7434 if (!S.Context.getTargetInfo().isTLSSupported()) {
7435 S.Diag(AL.getLoc(), diag::err_thread_unsupported);
7436 return;
7437 }
7438 if (VD->getTSCSpec() != TSCS_unspecified) {
7439 S.Diag(AL.getLoc(), diag::err_declspec_thread_on_thread_variable);
7440 return;
7441 }
7442 if (VD->hasLocalStorage()) {
7443 S.Diag(AL.getLoc(), diag::err_thread_non_global) << "__declspec(thread)";
7444 return;
7445 }
7446 D->addAttr(::new (S.Context) ThreadAttr(S.Context, AL));
7447}
7448
7449static void handleMSConstexprAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7450 if (!S.getLangOpts().isCompatibleWithMSVC(MajorVersion: LangOptions::MSVC2022_3)) {
7451 S.Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)
7452 << AL << AL.getRange();
7453 return;
7454 }
7455 auto *FD = cast<FunctionDecl>(Val: D);
7456 if (FD->isConstexprSpecified() || FD->isConsteval()) {
7457 S.Diag(AL.getLoc(), diag::err_ms_constexpr_cannot_be_applied)
7458 << FD->isConsteval() << FD;
7459 return;
7460 }
7461 if (auto *MD = dyn_cast<CXXMethodDecl>(Val: FD)) {
7462 if (!S.getLangOpts().CPlusPlus20 && MD->isVirtual()) {
7463 S.Diag(AL.getLoc(), diag::err_ms_constexpr_cannot_be_applied)
7464 << /*virtual*/ 2 << MD;
7465 return;
7466 }
7467 }
7468 D->addAttr(::new (S.Context) MSConstexprAttr(S.Context, AL));
7469}
7470
7471static void handleAbiTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7472 SmallVector<StringRef, 4> Tags;
7473 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
7474 StringRef Tag;
7475 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: I, Str&: Tag))
7476 return;
7477 Tags.push_back(Elt: Tag);
7478 }
7479
7480 if (const auto *NS = dyn_cast<NamespaceDecl>(Val: D)) {
7481 if (!NS->isInline()) {
7482 S.Diag(AL.getLoc(), diag::warn_attr_abi_tag_namespace) << 0;
7483 return;
7484 }
7485 if (NS->isAnonymousNamespace()) {
7486 S.Diag(AL.getLoc(), diag::warn_attr_abi_tag_namespace) << 1;
7487 return;
7488 }
7489 if (AL.getNumArgs() == 0)
7490 Tags.push_back(Elt: NS->getName());
7491 } else if (!AL.checkAtLeastNumArgs(S, Num: 1))
7492 return;
7493
7494 // Store tags sorted and without duplicates.
7495 llvm::sort(C&: Tags);
7496 Tags.erase(CS: std::unique(first: Tags.begin(), last: Tags.end()), CE: Tags.end());
7497
7498 D->addAttr(::new (S.Context)
7499 AbiTagAttr(S.Context, AL, Tags.data(), Tags.size()));
7500}
7501
7502static void handleARMInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7503 // Check the attribute arguments.
7504 if (AL.getNumArgs() > 1) {
7505 S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 1;
7506 return;
7507 }
7508
7509 StringRef Str;
7510 SourceLocation ArgLoc;
7511
7512 if (AL.getNumArgs() == 0)
7513 Str = "";
7514 else if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str, ArgLocation: &ArgLoc))
7515 return;
7516
7517 ARMInterruptAttr::InterruptType Kind;
7518 if (!ARMInterruptAttr::ConvertStrToInterruptType(Str, Kind)) {
7519 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << Str
7520 << ArgLoc;
7521 return;
7522 }
7523
7524 D->addAttr(::new (S.Context) ARMInterruptAttr(S.Context, AL, Kind));
7525}
7526
7527static void handleMSP430InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7528 // MSP430 'interrupt' attribute is applied to
7529 // a function with no parameters and void return type.
7530 if (!isFunctionOrMethod(D)) {
7531 S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
7532 << AL << AL.isRegularKeywordAttribute() << ExpectedFunctionOrMethod;
7533 return;
7534 }
7535
7536 if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) {
7537 S.Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
7538 << /*MSP430*/ 1 << 0;
7539 return;
7540 }
7541
7542 if (!getFunctionOrMethodResultType(D)->isVoidType()) {
7543 S.Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
7544 << /*MSP430*/ 1 << 1;
7545 return;
7546 }
7547
7548 // The attribute takes one integer argument.
7549 if (!AL.checkExactlyNumArgs(S, Num: 1))
7550 return;
7551
7552 if (!AL.isArgExpr(Arg: 0)) {
7553 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7554 << AL << AANT_ArgumentIntegerConstant;
7555 return;
7556 }
7557
7558 Expr *NumParamsExpr = static_cast<Expr *>(AL.getArgAsExpr(Arg: 0));
7559 std::optional<llvm::APSInt> NumParams = llvm::APSInt(32);
7560 if (!(NumParams = NumParamsExpr->getIntegerConstantExpr(Ctx: S.Context))) {
7561 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7562 << AL << AANT_ArgumentIntegerConstant
7563 << NumParamsExpr->getSourceRange();
7564 return;
7565 }
7566 // The argument should be in range 0..63.
7567 unsigned Num = NumParams->getLimitedValue(Limit: 255);
7568 if (Num > 63) {
7569 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
7570 << AL << (int)NumParams->getSExtValue()
7571 << NumParamsExpr->getSourceRange();
7572 return;
7573 }
7574
7575 D->addAttr(::new (S.Context) MSP430InterruptAttr(S.Context, AL, Num));
7576 D->addAttr(UsedAttr::CreateImplicit(S.Context));
7577}
7578
7579static void handleMipsInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7580 // Only one optional argument permitted.
7581 if (AL.getNumArgs() > 1) {
7582 S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 1;
7583 return;
7584 }
7585
7586 StringRef Str;
7587 SourceLocation ArgLoc;
7588
7589 if (AL.getNumArgs() == 0)
7590 Str = "";
7591 else if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str, ArgLocation: &ArgLoc))
7592 return;
7593
7594 // Semantic checks for a function with the 'interrupt' attribute for MIPS:
7595 // a) Must be a function.
7596 // b) Must have no parameters.
7597 // c) Must have the 'void' return type.
7598 // d) Cannot have the 'mips16' attribute, as that instruction set
7599 // lacks the 'eret' instruction.
7600 // e) The attribute itself must either have no argument or one of the
7601 // valid interrupt types, see [MipsInterruptDocs].
7602
7603 if (!isFunctionOrMethod(D)) {
7604 S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
7605 << AL << AL.isRegularKeywordAttribute() << ExpectedFunctionOrMethod;
7606 return;
7607 }
7608
7609 if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) {
7610 S.Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
7611 << /*MIPS*/ 0 << 0;
7612 return;
7613 }
7614
7615 if (!getFunctionOrMethodResultType(D)->isVoidType()) {
7616 S.Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
7617 << /*MIPS*/ 0 << 1;
7618 return;
7619 }
7620
7621 // We still have to do this manually because the Interrupt attributes are
7622 // a bit special due to sharing their spellings across targets.
7623 if (checkAttrMutualExclusion<Mips16Attr>(S, D, AL))
7624 return;
7625
7626 MipsInterruptAttr::InterruptType Kind;
7627 if (!MipsInterruptAttr::ConvertStrToInterruptType(Str, Kind)) {
7628 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
7629 << AL << "'" + std::string(Str) + "'";
7630 return;
7631 }
7632
7633 D->addAttr(::new (S.Context) MipsInterruptAttr(S.Context, AL, Kind));
7634}
7635
7636static void handleM68kInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7637 if (!AL.checkExactlyNumArgs(S, Num: 1))
7638 return;
7639
7640 if (!AL.isArgExpr(Arg: 0)) {
7641 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7642 << AL << AANT_ArgumentIntegerConstant;
7643 return;
7644 }
7645
7646 // FIXME: Check for decl - it should be void ()(void).
7647
7648 Expr *NumParamsExpr = static_cast<Expr *>(AL.getArgAsExpr(Arg: 0));
7649 auto MaybeNumParams = NumParamsExpr->getIntegerConstantExpr(Ctx: S.Context);
7650 if (!MaybeNumParams) {
7651 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7652 << AL << AANT_ArgumentIntegerConstant
7653 << NumParamsExpr->getSourceRange();
7654 return;
7655 }
7656
7657 unsigned Num = MaybeNumParams->getLimitedValue(Limit: 255);
7658 if ((Num & 1) || Num > 30) {
7659 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
7660 << AL << (int)MaybeNumParams->getSExtValue()
7661 << NumParamsExpr->getSourceRange();
7662 return;
7663 }
7664
7665 D->addAttr(::new (S.Context) M68kInterruptAttr(S.Context, AL, Num));
7666 D->addAttr(UsedAttr::CreateImplicit(S.Context));
7667}
7668
7669static void handleAnyX86InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7670 // Semantic checks for a function with the 'interrupt' attribute.
7671 // a) Must be a function.
7672 // b) Must have the 'void' return type.
7673 // c) Must take 1 or 2 arguments.
7674 // d) The 1st argument must be a pointer.
7675 // e) The 2nd argument (if any) must be an unsigned integer.
7676 if (!isFunctionOrMethod(D) || !hasFunctionProto(D) || isInstanceMethod(D) ||
7677 CXXMethodDecl::isStaticOverloadedOperator(
7678 OOK: cast<NamedDecl>(Val: D)->getDeclName().getCXXOverloadedOperator())) {
7679 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
7680 << AL << AL.isRegularKeywordAttribute()
7681 << ExpectedFunctionWithProtoType;
7682 return;
7683 }
7684 // Interrupt handler must have void return type.
7685 if (!getFunctionOrMethodResultType(D)->isVoidType()) {
7686 S.Diag(getFunctionOrMethodResultSourceRange(D).getBegin(),
7687 diag::err_anyx86_interrupt_attribute)
7688 << (S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86
7689 ? 0
7690 : 1)
7691 << 0;
7692 return;
7693 }
7694 // Interrupt handler must have 1 or 2 parameters.
7695 unsigned NumParams = getFunctionOrMethodNumParams(D);
7696 if (NumParams < 1 || NumParams > 2) {
7697 S.Diag(D->getBeginLoc(), diag::err_anyx86_interrupt_attribute)
7698 << (S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86
7699 ? 0
7700 : 1)
7701 << 1;
7702 return;
7703 }
7704 // The first argument must be a pointer.
7705 if (!getFunctionOrMethodParamType(D, Idx: 0)->isPointerType()) {
7706 S.Diag(getFunctionOrMethodParamRange(D, 0).getBegin(),
7707 diag::err_anyx86_interrupt_attribute)
7708 << (S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86
7709 ? 0
7710 : 1)
7711 << 2;
7712 return;
7713 }
7714 // The second argument, if present, must be an unsigned integer.
7715 unsigned TypeSize =
7716 S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86_64
7717 ? 64
7718 : 32;
7719 if (NumParams == 2 &&
7720 (!getFunctionOrMethodParamType(D, Idx: 1)->isUnsignedIntegerType() ||
7721 S.Context.getTypeSize(T: getFunctionOrMethodParamType(D, Idx: 1)) != TypeSize)) {
7722 S.Diag(getFunctionOrMethodParamRange(D, 1).getBegin(),
7723 diag::err_anyx86_interrupt_attribute)
7724 << (S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86
7725 ? 0
7726 : 1)
7727 << 3 << S.Context.getIntTypeForBitwidth(TypeSize, /*Signed=*/false);
7728 return;
7729 }
7730 D->addAttr(::new (S.Context) AnyX86InterruptAttr(S.Context, AL));
7731 D->addAttr(UsedAttr::CreateImplicit(S.Context));
7732}
7733
7734static void handleAVRInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7735 if (!isFunctionOrMethod(D)) {
7736 S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
7737 << AL << AL.isRegularKeywordAttribute() << ExpectedFunction;
7738 return;
7739 }
7740
7741 if (!AL.checkExactlyNumArgs(S, Num: 0))
7742 return;
7743
7744 handleSimpleAttribute<AVRInterruptAttr>(S, D, AL);
7745}
7746
7747static void handleAVRSignalAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7748 if (!isFunctionOrMethod(D)) {
7749 S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
7750 << AL << AL.isRegularKeywordAttribute() << ExpectedFunction;
7751 return;
7752 }
7753
7754 if (!AL.checkExactlyNumArgs(S, Num: 0))
7755 return;
7756
7757 handleSimpleAttribute<AVRSignalAttr>(S, D, AL);
7758}
7759
7760static void handleBPFPreserveAIRecord(Sema &S, RecordDecl *RD) {
7761 // Add preserve_access_index attribute to all fields and inner records.
7762 for (auto *D : RD->decls()) {
7763 if (D->hasAttr<BPFPreserveAccessIndexAttr>())
7764 continue;
7765
7766 D->addAttr(BPFPreserveAccessIndexAttr::CreateImplicit(S.Context));
7767 if (auto *Rec = dyn_cast<RecordDecl>(D))
7768 handleBPFPreserveAIRecord(S, Rec);
7769 }
7770}
7771
7772static void handleBPFPreserveAccessIndexAttr(Sema &S, Decl *D,
7773 const ParsedAttr &AL) {
7774 auto *Rec = cast<RecordDecl>(Val: D);
7775 handleBPFPreserveAIRecord(S, RD: Rec);
7776 Rec->addAttr(::new (S.Context) BPFPreserveAccessIndexAttr(S.Context, AL));
7777}
7778
7779static bool hasBTFDeclTagAttr(Decl *D, StringRef Tag) {
7780 for (const auto *I : D->specific_attrs<BTFDeclTagAttr>()) {
7781 if (I->getBTFDeclTag() == Tag)
7782 return true;
7783 }
7784 return false;
7785}
7786
7787static void handleBTFDeclTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7788 StringRef Str;
7789 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str))
7790 return;
7791 if (hasBTFDeclTagAttr(D, Tag: Str))
7792 return;
7793
7794 D->addAttr(::new (S.Context) BTFDeclTagAttr(S.Context, AL, Str));
7795}
7796
7797BTFDeclTagAttr *Sema::mergeBTFDeclTagAttr(Decl *D, const BTFDeclTagAttr &AL) {
7798 if (hasBTFDeclTagAttr(D, AL.getBTFDeclTag()))
7799 return nullptr;
7800 return ::new (Context) BTFDeclTagAttr(Context, AL, AL.getBTFDeclTag());
7801}
7802
7803static void handleWebAssemblyExportNameAttr(Sema &S, Decl *D,
7804 const ParsedAttr &AL) {
7805 if (!isFunctionOrMethod(D)) {
7806 S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
7807 << AL << AL.isRegularKeywordAttribute() << ExpectedFunction;
7808 return;
7809 }
7810
7811 auto *FD = cast<FunctionDecl>(Val: D);
7812 if (FD->isThisDeclarationADefinition()) {
7813 S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0;
7814 return;
7815 }
7816
7817 StringRef Str;
7818 SourceLocation ArgLoc;
7819 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str, ArgLocation: &ArgLoc))
7820 return;
7821
7822 D->addAttr(::new (S.Context) WebAssemblyExportNameAttr(S.Context, AL, Str));
7823 D->addAttr(UsedAttr::CreateImplicit(S.Context));
7824}
7825
7826WebAssemblyImportModuleAttr *
7827Sema::mergeImportModuleAttr(Decl *D, const WebAssemblyImportModuleAttr &AL) {
7828 auto *FD = cast<FunctionDecl>(Val: D);
7829
7830 if (const auto *ExistingAttr = FD->getAttr<WebAssemblyImportModuleAttr>()) {
7831 if (ExistingAttr->getImportModule() == AL.getImportModule())
7832 return nullptr;
7833 Diag(ExistingAttr->getLocation(), diag::warn_mismatched_import) << 0
7834 << ExistingAttr->getImportModule() << AL.getImportModule();
7835 Diag(AL.getLoc(), diag::note_previous_attribute);
7836 return nullptr;
7837 }
7838 if (FD->hasBody()) {
7839 Diag(AL.getLoc(), diag::warn_import_on_definition) << 0;
7840 return nullptr;
7841 }
7842 return ::new (Context) WebAssemblyImportModuleAttr(Context, AL,
7843 AL.getImportModule());
7844}
7845
7846WebAssemblyImportNameAttr *
7847Sema::mergeImportNameAttr(Decl *D, const WebAssemblyImportNameAttr &AL) {
7848 auto *FD = cast<FunctionDecl>(Val: D);
7849
7850 if (const auto *ExistingAttr = FD->getAttr<WebAssemblyImportNameAttr>()) {
7851 if (ExistingAttr->getImportName() == AL.getImportName())
7852 return nullptr;
7853 Diag(ExistingAttr->getLocation(), diag::warn_mismatched_import) << 1
7854 << ExistingAttr->getImportName() << AL.getImportName();
7855 Diag(AL.getLoc(), diag::note_previous_attribute);
7856 return nullptr;
7857 }
7858 if (FD->hasBody()) {
7859 Diag(AL.getLoc(), diag::warn_import_on_definition) << 1;
7860 return nullptr;
7861 }
7862 return ::new (Context) WebAssemblyImportNameAttr(Context, AL,
7863 AL.getImportName());
7864}
7865
7866static void
7867handleWebAssemblyImportModuleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7868 auto *FD = cast<FunctionDecl>(Val: D);
7869
7870 StringRef Str;
7871 SourceLocation ArgLoc;
7872 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str, ArgLocation: &ArgLoc))
7873 return;
7874 if (FD->hasBody()) {
7875 S.Diag(AL.getLoc(), diag::warn_import_on_definition) << 0;
7876 return;
7877 }
7878
7879 FD->addAttr(::new (S.Context)
7880 WebAssemblyImportModuleAttr(S.Context, AL, Str));
7881}
7882
7883static void
7884handleWebAssemblyImportNameAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7885 auto *FD = cast<FunctionDecl>(Val: D);
7886
7887 StringRef Str;
7888 SourceLocation ArgLoc;
7889 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str, ArgLocation: &ArgLoc))
7890 return;
7891 if (FD->hasBody()) {
7892 S.Diag(AL.getLoc(), diag::warn_import_on_definition) << 1;
7893 return;
7894 }
7895
7896 FD->addAttr(::new (S.Context) WebAssemblyImportNameAttr(S.Context, AL, Str));
7897}
7898
7899static void handleRISCVInterruptAttr(Sema &S, Decl *D,
7900 const ParsedAttr &AL) {
7901 // Warn about repeated attributes.
7902 if (const auto *A = D->getAttr<RISCVInterruptAttr>()) {
7903 S.Diag(AL.getRange().getBegin(),
7904 diag::warn_riscv_repeated_interrupt_attribute);
7905 S.Diag(A->getLocation(), diag::note_riscv_repeated_interrupt_attribute);
7906 return;
7907 }
7908
7909 // Check the attribute argument. Argument is optional.
7910 if (!AL.checkAtMostNumArgs(S, Num: 1))
7911 return;
7912
7913 StringRef Str;
7914 SourceLocation ArgLoc;
7915
7916 // 'machine'is the default interrupt mode.
7917 if (AL.getNumArgs() == 0)
7918 Str = "machine";
7919 else if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str, ArgLocation: &ArgLoc))
7920 return;
7921
7922 // Semantic checks for a function with the 'interrupt' attribute:
7923 // - Must be a function.
7924 // - Must have no parameters.
7925 // - Must have the 'void' return type.
7926 // - The attribute itself must either have no argument or one of the
7927 // valid interrupt types, see [RISCVInterruptDocs].
7928
7929 if (D->getFunctionType() == nullptr) {
7930 S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
7931 << AL << AL.isRegularKeywordAttribute() << ExpectedFunction;
7932 return;
7933 }
7934
7935 if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) {
7936 S.Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
7937 << /*RISC-V*/ 2 << 0;
7938 return;
7939 }
7940
7941 if (!getFunctionOrMethodResultType(D)->isVoidType()) {
7942 S.Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
7943 << /*RISC-V*/ 2 << 1;
7944 return;
7945 }
7946
7947 RISCVInterruptAttr::InterruptType Kind;
7948 if (!RISCVInterruptAttr::ConvertStrToInterruptType(Str, Kind)) {
7949 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << Str
7950 << ArgLoc;
7951 return;
7952 }
7953
7954 D->addAttr(::new (S.Context) RISCVInterruptAttr(S.Context, AL, Kind));
7955}
7956
7957static void handleInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7958 // Dispatch the interrupt attribute based on the current target.
7959 switch (S.Context.getTargetInfo().getTriple().getArch()) {
7960 case llvm::Triple::msp430:
7961 handleMSP430InterruptAttr(S, D, AL);
7962 break;
7963 case llvm::Triple::mipsel:
7964 case llvm::Triple::mips:
7965 handleMipsInterruptAttr(S, D, AL);
7966 break;
7967 case llvm::Triple::m68k:
7968 handleM68kInterruptAttr(S, D, AL);
7969 break;
7970 case llvm::Triple::x86:
7971 case llvm::Triple::x86_64:
7972 handleAnyX86InterruptAttr(S, D, AL);
7973 break;
7974 case llvm::Triple::avr:
7975 handleAVRInterruptAttr(S, D, AL);
7976 break;
7977 case llvm::Triple::riscv32:
7978 case llvm::Triple::riscv64:
7979 handleRISCVInterruptAttr(S, D, AL);
7980 break;
7981 default:
7982 handleARMInterruptAttr(S, D, AL);
7983 break;
7984 }
7985}
7986
7987static bool
7988checkAMDGPUFlatWorkGroupSizeArguments(Sema &S, Expr *MinExpr, Expr *MaxExpr,
7989 const AMDGPUFlatWorkGroupSizeAttr &Attr) {
7990 // Accept template arguments for now as they depend on something else.
7991 // We'll get to check them when they eventually get instantiated.
7992 if (MinExpr->isValueDependent() || MaxExpr->isValueDependent())
7993 return false;
7994
7995 uint32_t Min = 0;
7996 if (!checkUInt32Argument(S, Attr, MinExpr, Min, 0))
7997 return true;
7998
7999 uint32_t Max = 0;
8000 if (!checkUInt32Argument(S, Attr, MaxExpr, Max, 1))
8001 return true;
8002
8003 if (Min == 0 && Max != 0) {
8004 S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid)
8005 << &Attr << 0;
8006 return true;
8007 }
8008 if (Min > Max) {
8009 S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid)
8010 << &Attr << 1;
8011 return true;
8012 }
8013
8014 return false;
8015}
8016
8017AMDGPUFlatWorkGroupSizeAttr *
8018Sema::CreateAMDGPUFlatWorkGroupSizeAttr(const AttributeCommonInfo &CI,
8019 Expr *MinExpr, Expr *MaxExpr) {
8020 AMDGPUFlatWorkGroupSizeAttr TmpAttr(Context, CI, MinExpr, MaxExpr);
8021
8022 if (checkAMDGPUFlatWorkGroupSizeArguments(*this, MinExpr, MaxExpr, TmpAttr))
8023 return nullptr;
8024 return ::new (Context)
8025 AMDGPUFlatWorkGroupSizeAttr(Context, CI, MinExpr, MaxExpr);
8026}
8027
8028void Sema::addAMDGPUFlatWorkGroupSizeAttr(Decl *D,
8029 const AttributeCommonInfo &CI,
8030 Expr *MinExpr, Expr *MaxExpr) {
8031 if (auto *Attr = CreateAMDGPUFlatWorkGroupSizeAttr(CI, MinExpr, MaxExpr))
8032 D->addAttr(A: Attr);
8033}
8034
8035static void handleAMDGPUFlatWorkGroupSizeAttr(Sema &S, Decl *D,
8036 const ParsedAttr &AL) {
8037 Expr *MinExpr = AL.getArgAsExpr(Arg: 0);
8038 Expr *MaxExpr = AL.getArgAsExpr(Arg: 1);
8039
8040 S.addAMDGPUFlatWorkGroupSizeAttr(D, CI: AL, MinExpr, MaxExpr);
8041}
8042
8043static bool checkAMDGPUWavesPerEUArguments(Sema &S, Expr *MinExpr,
8044 Expr *MaxExpr,
8045 const AMDGPUWavesPerEUAttr &Attr) {
8046 if (S.DiagnoseUnexpandedParameterPack(E: MinExpr) ||
8047 (MaxExpr && S.DiagnoseUnexpandedParameterPack(E: MaxExpr)))
8048 return true;
8049
8050 // Accept template arguments for now as they depend on something else.
8051 // We'll get to check them when they eventually get instantiated.
8052 if (MinExpr->isValueDependent() || (MaxExpr && MaxExpr->isValueDependent()))
8053 return false;
8054
8055 uint32_t Min = 0;
8056 if (!checkUInt32Argument(S, Attr, MinExpr, Min, 0))
8057 return true;
8058
8059 uint32_t Max = 0;
8060 if (MaxExpr && !checkUInt32Argument(S, Attr, MaxExpr, Max, 1))
8061 return true;
8062
8063 if (Min == 0 && Max != 0) {
8064 S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid)
8065 << &Attr << 0;
8066 return true;
8067 }
8068 if (Max != 0 && Min > Max) {
8069 S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid)
8070 << &Attr << 1;
8071 return true;
8072 }
8073
8074 return false;
8075}
8076
8077AMDGPUWavesPerEUAttr *
8078Sema::CreateAMDGPUWavesPerEUAttr(const AttributeCommonInfo &CI, Expr *MinExpr,
8079 Expr *MaxExpr) {
8080 AMDGPUWavesPerEUAttr TmpAttr(Context, CI, MinExpr, MaxExpr);
8081
8082 if (checkAMDGPUWavesPerEUArguments(*this, MinExpr, MaxExpr, TmpAttr))
8083 return nullptr;
8084
8085 return ::new (Context) AMDGPUWavesPerEUAttr(Context, CI, MinExpr, MaxExpr);
8086}
8087
8088void Sema::addAMDGPUWavesPerEUAttr(Decl *D, const AttributeCommonInfo &CI,
8089 Expr *MinExpr, Expr *MaxExpr) {
8090 if (auto *Attr = CreateAMDGPUWavesPerEUAttr(CI, MinExpr, MaxExpr))
8091 D->addAttr(A: Attr);
8092}
8093
8094static void handleAMDGPUWavesPerEUAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8095 if (!AL.checkAtLeastNumArgs(S, Num: 1) || !AL.checkAtMostNumArgs(S, Num: 2))
8096 return;
8097
8098 Expr *MinExpr = AL.getArgAsExpr(Arg: 0);
8099 Expr *MaxExpr = (AL.getNumArgs() > 1) ? AL.getArgAsExpr(Arg: 1) : nullptr;
8100
8101 S.addAMDGPUWavesPerEUAttr(D, CI: AL, MinExpr, MaxExpr);
8102}
8103
8104static void handleAMDGPUNumSGPRAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8105 uint32_t NumSGPR = 0;
8106 Expr *NumSGPRExpr = AL.getArgAsExpr(Arg: 0);
8107 if (!checkUInt32Argument(S, AI: AL, Expr: NumSGPRExpr, Val&: NumSGPR))
8108 return;
8109
8110 D->addAttr(::new (S.Context) AMDGPUNumSGPRAttr(S.Context, AL, NumSGPR));
8111}
8112
8113static void handleAMDGPUNumVGPRAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8114 uint32_t NumVGPR = 0;
8115 Expr *NumVGPRExpr = AL.getArgAsExpr(Arg: 0);
8116 if (!checkUInt32Argument(S, AI: AL, Expr: NumVGPRExpr, Val&: NumVGPR))
8117 return;
8118
8119 D->addAttr(::new (S.Context) AMDGPUNumVGPRAttr(S.Context, AL, NumVGPR));
8120}
8121
8122static bool
8123checkAMDGPUMaxNumWorkGroupsArguments(Sema &S, Expr *XExpr, Expr *YExpr,
8124 Expr *ZExpr,
8125 const AMDGPUMaxNumWorkGroupsAttr &Attr) {
8126 if (S.DiagnoseUnexpandedParameterPack(E: XExpr) ||
8127 (YExpr && S.DiagnoseUnexpandedParameterPack(E: YExpr)) ||
8128 (ZExpr && S.DiagnoseUnexpandedParameterPack(E: ZExpr)))
8129 return true;
8130
8131 // Accept template arguments for now as they depend on something else.
8132 // We'll get to check them when they eventually get instantiated.
8133 if (XExpr->isValueDependent() || (YExpr && YExpr->isValueDependent()) ||
8134 (ZExpr && ZExpr->isValueDependent()))
8135 return false;
8136
8137 uint32_t NumWG = 0;
8138 Expr *Exprs[3] = {XExpr, YExpr, ZExpr};
8139 for (int i = 0; i < 3; i++) {
8140 if (Exprs[i]) {
8141 if (!checkUInt32Argument(S, Attr, Exprs[i], NumWG, i,
8142 /*StrictlyUnsigned=*/true))
8143 return true;
8144 if (NumWG == 0) {
8145 S.Diag(Attr.getLoc(), diag::err_attribute_argument_is_zero)
8146 << &Attr << Exprs[i]->getSourceRange();
8147 return true;
8148 }
8149 }
8150 }
8151
8152 return false;
8153}
8154
8155AMDGPUMaxNumWorkGroupsAttr *
8156Sema::CreateAMDGPUMaxNumWorkGroupsAttr(const AttributeCommonInfo &CI,
8157 Expr *XExpr, Expr *YExpr, Expr *ZExpr) {
8158 AMDGPUMaxNumWorkGroupsAttr TmpAttr(Context, CI, XExpr, YExpr, ZExpr);
8159
8160 if (checkAMDGPUMaxNumWorkGroupsArguments(*this, XExpr, YExpr, ZExpr, TmpAttr))
8161 return nullptr;
8162
8163 return ::new (Context)
8164 AMDGPUMaxNumWorkGroupsAttr(Context, CI, XExpr, YExpr, ZExpr);
8165}
8166
8167void Sema::addAMDGPUMaxNumWorkGroupsAttr(Decl *D, const AttributeCommonInfo &CI,
8168 Expr *XExpr, Expr *YExpr,
8169 Expr *ZExpr) {
8170 if (auto *Attr = CreateAMDGPUMaxNumWorkGroupsAttr(CI, XExpr, YExpr, ZExpr))
8171 D->addAttr(A: Attr);
8172}
8173
8174static void handleAMDGPUMaxNumWorkGroupsAttr(Sema &S, Decl *D,
8175 const ParsedAttr &AL) {
8176 Expr *YExpr = (AL.getNumArgs() > 1) ? AL.getArgAsExpr(Arg: 1) : nullptr;
8177 Expr *ZExpr = (AL.getNumArgs() > 2) ? AL.getArgAsExpr(Arg: 2) : nullptr;
8178 S.addAMDGPUMaxNumWorkGroupsAttr(D, CI: AL, XExpr: AL.getArgAsExpr(Arg: 0), YExpr, ZExpr);
8179}
8180
8181static void handleX86ForceAlignArgPointerAttr(Sema &S, Decl *D,
8182 const ParsedAttr &AL) {
8183 // If we try to apply it to a function pointer, don't warn, but don't
8184 // do anything, either. It doesn't matter anyway, because there's nothing
8185 // special about calling a force_align_arg_pointer function.
8186 const auto *VD = dyn_cast<ValueDecl>(Val: D);
8187 if (VD && VD->getType()->isFunctionPointerType())
8188 return;
8189 // Also don't warn on function pointer typedefs.
8190 const auto *TD = dyn_cast<TypedefNameDecl>(Val: D);
8191 if (TD && (TD->getUnderlyingType()->isFunctionPointerType() ||
8192 TD->getUnderlyingType()->isFunctionType()))
8193 return;
8194 // Attribute can only be applied to function types.
8195 if (!isa<FunctionDecl>(Val: D)) {
8196 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
8197 << AL << AL.isRegularKeywordAttribute() << ExpectedFunction;
8198 return;
8199 }
8200
8201 D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr(S.Context, AL));
8202}
8203
8204static void handleLayoutVersion(Sema &S, Decl *D, const ParsedAttr &AL) {
8205 uint32_t Version;
8206 Expr *VersionExpr = static_cast<Expr *>(AL.getArgAsExpr(Arg: 0));
8207 if (!checkUInt32Argument(S, AI: AL, Expr: AL.getArgAsExpr(Arg: 0), Val&: Version))
8208 return;
8209
8210 // TODO: Investigate what happens with the next major version of MSVC.
8211 if (Version != LangOptions::MSVC2015 / 100) {
8212 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
8213 << AL << Version << VersionExpr->getSourceRange();
8214 return;
8215 }
8216
8217 // The attribute expects a "major" version number like 19, but new versions of
8218 // MSVC have moved to updating the "minor", or less significant numbers, so we
8219 // have to multiply by 100 now.
8220 Version *= 100;
8221
8222 D->addAttr(::new (S.Context) LayoutVersionAttr(S.Context, AL, Version));
8223}
8224
8225DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D,
8226 const AttributeCommonInfo &CI) {
8227 if (D->hasAttr<DLLExportAttr>()) {
8228 Diag(CI.getLoc(), diag::warn_attribute_ignored) << "'dllimport'";
8229 return nullptr;
8230 }
8231
8232 if (D->hasAttr<DLLImportAttr>())
8233 return nullptr;
8234
8235 return ::new (Context) DLLImportAttr(Context, CI);
8236}
8237
8238DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D,
8239 const AttributeCommonInfo &CI) {
8240 if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) {
8241 Diag(Import->getLocation(), diag::warn_attribute_ignored) << Import;
8242 D->dropAttr<DLLImportAttr>();
8243 }
8244
8245 if (D->hasAttr<DLLExportAttr>())
8246 return nullptr;
8247
8248 return ::new (Context) DLLExportAttr(Context, CI);
8249}
8250
8251static void handleDLLAttr(Sema &S, Decl *D, const ParsedAttr &A) {
8252 if (isa<ClassTemplatePartialSpecializationDecl>(Val: D) &&
8253 (S.Context.getTargetInfo().shouldDLLImportComdatSymbols())) {
8254 S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored) << A;
8255 return;
8256 }
8257
8258 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
8259 if (FD->isInlined() && A.getKind() == ParsedAttr::AT_DLLImport &&
8260 !(S.Context.getTargetInfo().shouldDLLImportComdatSymbols())) {
8261 // MinGW doesn't allow dllimport on inline functions.
8262 S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored_on_inline)
8263 << A;
8264 return;
8265 }
8266 }
8267
8268 if (const auto *MD = dyn_cast<CXXMethodDecl>(Val: D)) {
8269 if ((S.Context.getTargetInfo().shouldDLLImportComdatSymbols()) &&
8270 MD->getParent()->isLambda()) {
8271 S.Diag(A.getRange().getBegin(), diag::err_attribute_dll_lambda) << A;
8272 return;
8273 }
8274 }
8275
8276 Attr *NewAttr = A.getKind() == ParsedAttr::AT_DLLExport
8277 ? (Attr *)S.mergeDLLExportAttr(D, A)
8278 : (Attr *)S.mergeDLLImportAttr(D, A);
8279 if (NewAttr)
8280 D->addAttr(A: NewAttr);
8281}
8282
8283MSInheritanceAttr *
8284Sema::mergeMSInheritanceAttr(Decl *D, const AttributeCommonInfo &CI,
8285 bool BestCase,
8286 MSInheritanceModel Model) {
8287 if (MSInheritanceAttr *IA = D->getAttr<MSInheritanceAttr>()) {
8288 if (IA->getInheritanceModel() == Model)
8289 return nullptr;
8290 Diag(IA->getLocation(), diag::err_mismatched_ms_inheritance)
8291 << 1 /*previous declaration*/;
8292 Diag(CI.getLoc(), diag::note_previous_ms_inheritance);
8293 D->dropAttr<MSInheritanceAttr>();
8294 }
8295
8296 auto *RD = cast<CXXRecordDecl>(Val: D);
8297 if (RD->hasDefinition()) {
8298 if (checkMSInheritanceAttrOnDefinition(RD, Range: CI.getRange(), BestCase,
8299 ExplicitModel: Model)) {
8300 return nullptr;
8301 }
8302 } else {
8303 if (isa<ClassTemplatePartialSpecializationDecl>(Val: RD)) {
8304 Diag(CI.getLoc(), diag::warn_ignored_ms_inheritance)
8305 << 1 /*partial specialization*/;
8306 return nullptr;
8307 }
8308 if (RD->getDescribedClassTemplate()) {
8309 Diag(CI.getLoc(), diag::warn_ignored_ms_inheritance)
8310 << 0 /*primary template*/;
8311 return nullptr;
8312 }
8313 }
8314
8315 return ::new (Context) MSInheritanceAttr(Context, CI, BestCase);
8316}
8317
8318static void handleCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8319 // The capability attributes take a single string parameter for the name of
8320 // the capability they represent. The lockable attribute does not take any
8321 // parameters. However, semantically, both attributes represent the same
8322 // concept, and so they use the same semantic attribute. Eventually, the
8323 // lockable attribute will be removed.
8324 //
8325 // For backward compatibility, any capability which has no specified string
8326 // literal will be considered a "mutex."
8327 StringRef N("mutex");
8328 SourceLocation LiteralLoc;
8329 if (AL.getKind() == ParsedAttr::AT_Capability &&
8330 !S.checkStringLiteralArgumentAttr(AL, 0, N, &LiteralLoc))
8331 return;
8332
8333 D->addAttr(::new (S.Context) CapabilityAttr(S.Context, AL, N));
8334}
8335
8336static void handleAssertCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8337 SmallVector<Expr*, 1> Args;
8338 if (!checkLockFunAttrCommon(S, D, AL, Args))
8339 return;
8340
8341 D->addAttr(::new (S.Context)
8342 AssertCapabilityAttr(S.Context, AL, Args.data(), Args.size()));
8343}
8344
8345static void handleAcquireCapabilityAttr(Sema &S, Decl *D,
8346 const ParsedAttr &AL) {
8347 SmallVector<Expr*, 1> Args;
8348 if (!checkLockFunAttrCommon(S, D, AL, Args))
8349 return;
8350
8351 D->addAttr(::new (S.Context) AcquireCapabilityAttr(S.Context, AL, Args.data(),
8352 Args.size()));
8353}
8354
8355static void handleTryAcquireCapabilityAttr(Sema &S, Decl *D,
8356 const ParsedAttr &AL) {
8357 SmallVector<Expr*, 2> Args;
8358 if (!checkTryLockFunAttrCommon(S, D, AL, Args))
8359 return;
8360
8361 D->addAttr(::new (S.Context) TryAcquireCapabilityAttr(
8362 S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));
8363}
8364
8365static void handleReleaseCapabilityAttr(Sema &S, Decl *D,
8366 const ParsedAttr &AL) {
8367 // Check that all arguments are lockable objects.
8368 SmallVector<Expr *, 1> Args;
8369 checkAttrArgsAreCapabilityObjs(S, D, AL, Args, Sidx: 0, ParamIdxOk: true);
8370
8371 D->addAttr(::new (S.Context) ReleaseCapabilityAttr(S.Context, AL, Args.data(),
8372 Args.size()));
8373}
8374
8375static void handleRequiresCapabilityAttr(Sema &S, Decl *D,
8376 const ParsedAttr &AL) {
8377 if (!AL.checkAtLeastNumArgs(S, Num: 1))
8378 return;
8379
8380 // check that all arguments are lockable objects
8381 SmallVector<Expr*, 1> Args;
8382 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
8383 if (Args.empty())
8384 return;
8385
8386 RequiresCapabilityAttr *RCA = ::new (S.Context)
8387 RequiresCapabilityAttr(S.Context, AL, Args.data(), Args.size());
8388
8389 D->addAttr(A: RCA);
8390}
8391
8392static void handleDeprecatedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8393 if (const auto *NSD = dyn_cast<NamespaceDecl>(Val: D)) {
8394 if (NSD->isAnonymousNamespace()) {
8395 S.Diag(AL.getLoc(), diag::warn_deprecated_anonymous_namespace);
8396 // Do not want to attach the attribute to the namespace because that will
8397 // cause confusing diagnostic reports for uses of declarations within the
8398 // namespace.
8399 return;
8400 }
8401 } else if (isa<UsingDecl, UnresolvedUsingTypenameDecl,
8402 UnresolvedUsingValueDecl>(Val: D)) {
8403 S.Diag(AL.getRange().getBegin(), diag::warn_deprecated_ignored_on_using)
8404 << AL;
8405 return;
8406 }
8407
8408 // Handle the cases where the attribute has a text message.
8409 StringRef Str, Replacement;
8410 if (AL.isArgExpr(Arg: 0) && AL.getArgAsExpr(Arg: 0) &&
8411 !S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str))
8412 return;
8413
8414 // Support a single optional message only for Declspec and [[]] spellings.
8415 if (AL.isDeclspecAttribute() || AL.isStandardAttributeSyntax())
8416 AL.checkAtMostNumArgs(S, Num: 1);
8417 else if (AL.isArgExpr(Arg: 1) && AL.getArgAsExpr(Arg: 1) &&
8418 !S.checkStringLiteralArgumentAttr(AL, ArgNum: 1, Str&: Replacement))
8419 return;
8420
8421 if (!S.getLangOpts().CPlusPlus14 && AL.isCXX11Attribute() && !AL.isGNUScope())
8422 S.Diag(AL.getLoc(), diag::ext_cxx14_attr) << AL;
8423
8424 D->addAttr(::new (S.Context) DeprecatedAttr(S.Context, AL, Str, Replacement));
8425}
8426
8427static bool isGlobalVar(const Decl *D) {
8428 if (const auto *S = dyn_cast<VarDecl>(Val: D))
8429 return S->hasGlobalStorage();
8430 return false;
8431}
8432
8433static bool isSanitizerAttributeAllowedOnGlobals(StringRef Sanitizer) {
8434 return Sanitizer == "address" || Sanitizer == "hwaddress" ||
8435 Sanitizer == "memtag";
8436}
8437
8438static void handleNoSanitizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8439 if (!AL.checkAtLeastNumArgs(S, Num: 1))
8440 return;
8441
8442 std::vector<StringRef> Sanitizers;
8443
8444 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
8445 StringRef SanitizerName;
8446 SourceLocation LiteralLoc;
8447
8448 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: I, Str&: SanitizerName, ArgLocation: &LiteralLoc))
8449 return;
8450
8451 if (parseSanitizerValue(SanitizerName, /*AllowGroups=*/true) ==
8452 SanitizerMask() &&
8453 SanitizerName != "coverage")
8454 S.Diag(LiteralLoc, diag::warn_unknown_sanitizer_ignored) << SanitizerName;
8455 else if (isGlobalVar(D) && !isSanitizerAttributeAllowedOnGlobals(SanitizerName))
8456 S.Diag(D->getLocation(), diag::warn_attribute_type_not_supported_global)
8457 << AL << SanitizerName;
8458 Sanitizers.push_back(x: SanitizerName);
8459 }
8460
8461 D->addAttr(::new (S.Context) NoSanitizeAttr(S.Context, AL, Sanitizers.data(),
8462 Sanitizers.size()));
8463}
8464
8465static void handleNoSanitizeSpecificAttr(Sema &S, Decl *D,
8466 const ParsedAttr &AL) {
8467 StringRef AttrName = AL.getAttrName()->getName();
8468 normalizeName(AttrName);
8469 StringRef SanitizerName = llvm::StringSwitch<StringRef>(AttrName)
8470 .Case(S: "no_address_safety_analysis", Value: "address")
8471 .Case(S: "no_sanitize_address", Value: "address")
8472 .Case(S: "no_sanitize_thread", Value: "thread")
8473 .Case(S: "no_sanitize_memory", Value: "memory");
8474 if (isGlobalVar(D) && SanitizerName != "address")
8475 S.Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
8476 << AL << AL.isRegularKeywordAttribute() << ExpectedFunction;
8477
8478 // FIXME: Rather than create a NoSanitizeSpecificAttr, this creates a
8479 // NoSanitizeAttr object; but we need to calculate the correct spelling list
8480 // index rather than incorrectly assume the index for NoSanitizeSpecificAttr
8481 // has the same spellings as the index for NoSanitizeAttr. We don't have a
8482 // general way to "translate" between the two, so this hack attempts to work
8483 // around the issue with hard-coded indices. This is critical for calling
8484 // getSpelling() or prettyPrint() on the resulting semantic attribute object
8485 // without failing assertions.
8486 unsigned TranslatedSpellingIndex = 0;
8487 if (AL.isStandardAttributeSyntax())
8488 TranslatedSpellingIndex = 1;
8489
8490 AttributeCommonInfo Info = AL;
8491 Info.setAttributeSpellingListIndex(TranslatedSpellingIndex);
8492 D->addAttr(::new (S.Context)
8493 NoSanitizeAttr(S.Context, Info, &SanitizerName, 1));
8494}
8495
8496static void handleInternalLinkageAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8497 if (InternalLinkageAttr *Internal = S.mergeInternalLinkageAttr(D, AL))
8498 D->addAttr(Internal);
8499}
8500
8501static void handleOpenCLNoSVMAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8502 if (S.LangOpts.getOpenCLCompatibleVersion() < 200)
8503 S.Diag(AL.getLoc(), diag::err_attribute_requires_opencl_version)
8504 << AL << "2.0" << 1;
8505 else
8506 S.Diag(AL.getLoc(), diag::warn_opencl_attr_deprecated_ignored)
8507 << AL << S.LangOpts.getOpenCLVersionString();
8508}
8509
8510static void handleOpenCLAccessAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8511 if (D->isInvalidDecl())
8512 return;
8513
8514 // Check if there is only one access qualifier.
8515 if (D->hasAttr<OpenCLAccessAttr>()) {
8516 if (D->getAttr<OpenCLAccessAttr>()->getSemanticSpelling() ==
8517 AL.getSemanticSpelling()) {
8518 S.Diag(AL.getLoc(), diag::warn_duplicate_declspec)
8519 << AL.getAttrName()->getName() << AL.getRange();
8520 } else {
8521 S.Diag(AL.getLoc(), diag::err_opencl_multiple_access_qualifiers)
8522 << D->getSourceRange();
8523 D->setInvalidDecl(true);
8524 return;
8525 }
8526 }
8527
8528 // OpenCL v2.0 s6.6 - read_write can be used for image types to specify that
8529 // an image object can be read and written. OpenCL v2.0 s6.13.6 - A kernel
8530 // cannot read from and write to the same pipe object. Using the read_write
8531 // (or __read_write) qualifier with the pipe qualifier is a compilation error.
8532 // OpenCL v3.0 s6.8 - For OpenCL C 2.0, or with the
8533 // __opencl_c_read_write_images feature, image objects specified as arguments
8534 // to a kernel can additionally be declared to be read-write.
8535 // C++ for OpenCL 1.0 inherits rule from OpenCL C v2.0.
8536 // C++ for OpenCL 2021 inherits rule from OpenCL C v3.0.
8537 if (const auto *PDecl = dyn_cast<ParmVarDecl>(Val: D)) {
8538 const Type *DeclTy = PDecl->getType().getCanonicalType().getTypePtr();
8539 if (AL.getAttrName()->getName().contains(Other: "read_write")) {
8540 bool ReadWriteImagesUnsupported =
8541 (S.getLangOpts().getOpenCLCompatibleVersion() < 200) ||
8542 (S.getLangOpts().getOpenCLCompatibleVersion() == 300 &&
8543 !S.getOpenCLOptions().isSupported(Ext: "__opencl_c_read_write_images",
8544 LO: S.getLangOpts()));
8545 if (ReadWriteImagesUnsupported || DeclTy->isPipeType()) {
8546 S.Diag(AL.getLoc(), diag::err_opencl_invalid_read_write)
8547 << AL << PDecl->getType() << DeclTy->isImageType();
8548 D->setInvalidDecl(true);
8549 return;
8550 }
8551 }
8552 }
8553
8554 D->addAttr(::new (S.Context) OpenCLAccessAttr(S.Context, AL));
8555}
8556
8557static void handleZeroCallUsedRegsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8558 // Check that the argument is a string literal.
8559 StringRef KindStr;
8560 SourceLocation LiteralLoc;
8561 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: KindStr, ArgLocation: &LiteralLoc))
8562 return;
8563
8564 ZeroCallUsedRegsAttr::ZeroCallUsedRegsKind Kind;
8565 if (!ZeroCallUsedRegsAttr::ConvertStrToZeroCallUsedRegsKind(KindStr, Kind)) {
8566 S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported)
8567 << AL << KindStr;
8568 return;
8569 }
8570
8571 D->dropAttr<ZeroCallUsedRegsAttr>();
8572 D->addAttr(ZeroCallUsedRegsAttr::Create(S.Context, Kind, AL));
8573}
8574
8575static const RecordDecl *GetEnclosingNamedOrTopAnonRecord(const FieldDecl *FD) {
8576 const auto *RD = FD->getParent();
8577 // An unnamed struct is anonymous struct only if it's not instantiated.
8578 // However, the struct may not be fully processed yet to determine
8579 // whether it's anonymous or not. In that case, this function treats it as
8580 // an anonymous struct and tries to find a named parent.
8581 while (RD && (RD->isAnonymousStructOrUnion() ||
8582 (!RD->isCompleteDefinition() && RD->getName().empty()))) {
8583 const auto *Parent = dyn_cast<RecordDecl>(RD->getParent());
8584 if (!Parent)
8585 break;
8586 RD = Parent;
8587 }
8588 return RD;
8589}
8590
8591static bool
8592CheckCountExpr(Sema &S, FieldDecl *FD, Expr *E,
8593 llvm::SmallVectorImpl<TypeCoupledDeclRefInfo> &Decls) {
8594 if (FD->getParent()->isUnion()) {
8595 S.Diag(FD->getBeginLoc(), diag::err_counted_by_attr_in_union)
8596 << FD->getSourceRange();
8597 return true;
8598 }
8599
8600 if (!E->getType()->isIntegerType() || E->getType()->isBooleanType()) {
8601 S.Diag(E->getBeginLoc(), diag::err_counted_by_attr_argument_not_integer)
8602 << E->getSourceRange();
8603 return true;
8604 }
8605
8606 LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel =
8607 LangOptions::StrictFlexArraysLevelKind::IncompleteOnly;
8608
8609 if (!Decl::isFlexibleArrayMemberLike(Context&: S.getASTContext(), D: FD, Ty: FD->getType(),
8610 StrictFlexArraysLevel, IgnoreTemplateOrMacroSubstitution: true)) {
8611 // The "counted_by" attribute must be on a flexible array member.
8612 SourceRange SR = FD->getLocation();
8613 S.Diag(SR.getBegin(),
8614 diag::err_counted_by_attr_not_on_flexible_array_member)
8615 << SR;
8616 return true;
8617 }
8618
8619 auto *DRE = dyn_cast<DeclRefExpr>(Val: E);
8620 if (!DRE) {
8621 S.Diag(E->getBeginLoc(),
8622 diag::err_counted_by_attr_only_support_simple_decl_reference)
8623 << E->getSourceRange();
8624 return true;
8625 }
8626
8627 auto *CountDecl = DRE->getDecl();
8628 FieldDecl *CountFD = dyn_cast<FieldDecl>(Val: CountDecl);
8629 if (auto *IFD = dyn_cast<IndirectFieldDecl>(Val: CountDecl)) {
8630 CountFD = IFD->getAnonField();
8631 }
8632 if (!CountFD) {
8633 S.Diag(E->getBeginLoc(), diag::err_counted_by_must_be_in_structure)
8634 << CountDecl << E->getSourceRange();
8635
8636 S.Diag(CountDecl->getBeginLoc(),
8637 diag::note_flexible_array_counted_by_attr_field)
8638 << CountDecl << CountDecl->getSourceRange();
8639 return true;
8640 }
8641
8642 if (FD->getParent() != CountFD->getParent()) {
8643 if (CountFD->getParent()->isUnion()) {
8644 S.Diag(CountFD->getBeginLoc(), diag::err_counted_by_attr_refer_to_union)
8645 << CountFD->getSourceRange();
8646 return true;
8647 }
8648 // Whether CountRD is an anonymous struct is not determined at this
8649 // point. Thus, an additional diagnostic in case it's not anonymous struct
8650 // is done later in `Parser::ParseStructDeclaration`.
8651 auto *RD = GetEnclosingNamedOrTopAnonRecord(FD);
8652 auto *CountRD = GetEnclosingNamedOrTopAnonRecord(FD: CountFD);
8653
8654 if (RD != CountRD) {
8655 S.Diag(E->getBeginLoc(),
8656 diag::err_flexible_array_count_not_in_same_struct)
8657 << CountFD << E->getSourceRange();
8658 S.Diag(CountFD->getBeginLoc(),
8659 diag::note_flexible_array_counted_by_attr_field)
8660 << CountFD << CountFD->getSourceRange();
8661 return true;
8662 }
8663 }
8664
8665 Decls.push_back(Elt: TypeCoupledDeclRefInfo(CountFD, /*IsDref*/ false));
8666 return false;
8667}
8668
8669static void handleCountedByAttrField(Sema &S, Decl *D, const ParsedAttr &AL) {
8670 auto *FD = dyn_cast<FieldDecl>(Val: D);
8671 assert(FD);
8672
8673 auto *CountExpr = AL.getArgAsExpr(Arg: 0);
8674 if (!CountExpr)
8675 return;
8676
8677 llvm::SmallVector<TypeCoupledDeclRefInfo, 1> Decls;
8678 if (CheckCountExpr(S, FD, E: CountExpr, Decls))
8679 return;
8680
8681 QualType CAT = S.BuildCountAttributedArrayType(WrappedTy: FD->getType(), CountExpr);
8682 FD->setType(CAT);
8683}
8684
8685static void handleFunctionReturnThunksAttr(Sema &S, Decl *D,
8686 const ParsedAttr &AL) {
8687 StringRef KindStr;
8688 SourceLocation LiteralLoc;
8689 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: KindStr, ArgLocation: &LiteralLoc))
8690 return;
8691
8692 FunctionReturnThunksAttr::Kind Kind;
8693 if (!FunctionReturnThunksAttr::ConvertStrToKind(KindStr, Kind)) {
8694 S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported)
8695 << AL << KindStr;
8696 return;
8697 }
8698 // FIXME: it would be good to better handle attribute merging rather than
8699 // silently replacing the existing attribute, so long as it does not break
8700 // the expected codegen tests.
8701 D->dropAttr<FunctionReturnThunksAttr>();
8702 D->addAttr(FunctionReturnThunksAttr::Create(S.Context, Kind, AL));
8703}
8704
8705static void handleAvailableOnlyInDefaultEvalMethod(Sema &S, Decl *D,
8706 const ParsedAttr &AL) {
8707 assert(isa<TypedefNameDecl>(D) && "This attribute only applies to a typedef");
8708 handleSimpleAttribute<AvailableOnlyInDefaultEvalMethodAttr>(S, D, AL);
8709}
8710
8711static void handleNoMergeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8712 auto *VDecl = dyn_cast<VarDecl>(Val: D);
8713 if (VDecl && !VDecl->isFunctionPointerType()) {
8714 S.Diag(AL.getLoc(), diag::warn_attribute_ignored_non_function_pointer)
8715 << AL << VDecl;
8716 return;
8717 }
8718 D->addAttr(NoMergeAttr::Create(S.Context, AL));
8719}
8720
8721static void handleNoUniqueAddressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8722 D->addAttr(NoUniqueAddressAttr::Create(S.Context, AL));
8723}
8724
8725static void handleSYCLKernelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8726 // The 'sycl_kernel' attribute applies only to function templates.
8727 const auto *FD = cast<FunctionDecl>(Val: D);
8728 const FunctionTemplateDecl *FT = FD->getDescribedFunctionTemplate();
8729 assert(FT && "Function template is expected");
8730
8731 // Function template must have at least two template parameters.
8732 const TemplateParameterList *TL = FT->getTemplateParameters();
8733 if (TL->size() < 2) {
8734 S.Diag(FT->getLocation(), diag::warn_sycl_kernel_num_of_template_params);
8735 return;
8736 }
8737
8738 // Template parameters must be typenames.
8739 for (unsigned I = 0; I < 2; ++I) {
8740 const NamedDecl *TParam = TL->getParam(Idx: I);
8741 if (isa<NonTypeTemplateParmDecl>(Val: TParam)) {
8742 S.Diag(FT->getLocation(),
8743 diag::warn_sycl_kernel_invalid_template_param_type);
8744 return;
8745 }
8746 }
8747
8748 // Function must have at least one argument.
8749 if (getFunctionOrMethodNumParams(D) != 1) {
8750 S.Diag(FT->getLocation(), diag::warn_sycl_kernel_num_of_function_params);
8751 return;
8752 }
8753
8754 // Function must return void.
8755 QualType RetTy = getFunctionOrMethodResultType(D);
8756 if (!RetTy->isVoidType()) {
8757 S.Diag(FT->getLocation(), diag::warn_sycl_kernel_return_type);
8758 return;
8759 }
8760
8761 handleSimpleAttribute<SYCLKernelAttr>(S, D, AL);
8762}
8763
8764static void handleDestroyAttr(Sema &S, Decl *D, const ParsedAttr &A) {
8765 if (!cast<VarDecl>(Val: D)->hasGlobalStorage()) {
8766 S.Diag(D->getLocation(), diag::err_destroy_attr_on_non_static_var)
8767 << (A.getKind() == ParsedAttr::AT_AlwaysDestroy);
8768 return;
8769 }
8770
8771 if (A.getKind() == ParsedAttr::AT_AlwaysDestroy)
8772 handleSimpleAttribute<AlwaysDestroyAttr>(S, D, A);
8773 else
8774 handleSimpleAttribute<NoDestroyAttr>(S, D, A);
8775}
8776
8777static void handleUninitializedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8778 assert(cast<VarDecl>(D)->getStorageDuration() == SD_Automatic &&
8779 "uninitialized is only valid on automatic duration variables");
8780 D->addAttr(::new (S.Context) UninitializedAttr(S.Context, AL));
8781}
8782
8783static bool tryMakeVariablePseudoStrong(Sema &S, VarDecl *VD,
8784 bool DiagnoseFailure) {
8785 QualType Ty = VD->getType();
8786 if (!Ty->isObjCRetainableType()) {
8787 if (DiagnoseFailure) {
8788 S.Diag(VD->getBeginLoc(), diag::warn_ignored_objc_externally_retained)
8789 << 0;
8790 }
8791 return false;
8792 }
8793
8794 Qualifiers::ObjCLifetime LifetimeQual = Ty.getQualifiers().getObjCLifetime();
8795
8796 // Sema::inferObjCARCLifetime must run after processing decl attributes
8797 // (because __block lowers to an attribute), so if the lifetime hasn't been
8798 // explicitly specified, infer it locally now.
8799 if (LifetimeQual == Qualifiers::OCL_None)
8800 LifetimeQual = Ty->getObjCARCImplicitLifetime();
8801
8802 // The attributes only really makes sense for __strong variables; ignore any
8803 // attempts to annotate a parameter with any other lifetime qualifier.
8804 if (LifetimeQual != Qualifiers::OCL_Strong) {
8805 if (DiagnoseFailure) {
8806 S.Diag(VD->getBeginLoc(), diag::warn_ignored_objc_externally_retained)
8807 << 1;
8808 }
8809 return false;
8810 }
8811
8812 // Tampering with the type of a VarDecl here is a bit of a hack, but we need
8813 // to ensure that the variable is 'const' so that we can error on
8814 // modification, which can otherwise over-release.
8815 VD->setType(Ty.withConst());
8816 VD->setARCPseudoStrong(true);
8817 return true;
8818}
8819
8820static void handleObjCExternallyRetainedAttr(Sema &S, Decl *D,
8821 const ParsedAttr &AL) {
8822 if (auto *VD = dyn_cast<VarDecl>(Val: D)) {
8823 assert(!isa<ParmVarDecl>(VD) && "should be diagnosed automatically");
8824 if (!VD->hasLocalStorage()) {
8825 S.Diag(D->getBeginLoc(), diag::warn_ignored_objc_externally_retained)
8826 << 0;
8827 return;
8828 }
8829
8830 if (!tryMakeVariablePseudoStrong(S, VD, /*DiagnoseFailure=*/true))
8831 return;
8832
8833 handleSimpleAttribute<ObjCExternallyRetainedAttr>(S, D, AL);
8834 return;
8835 }
8836
8837 // If D is a function-like declaration (method, block, or function), then we
8838 // make every parameter psuedo-strong.
8839 unsigned NumParams =
8840 hasFunctionProto(D) ? getFunctionOrMethodNumParams(D) : 0;
8841 for (unsigned I = 0; I != NumParams; ++I) {
8842 auto *PVD = const_cast<ParmVarDecl *>(getFunctionOrMethodParam(D, Idx: I));
8843 QualType Ty = PVD->getType();
8844
8845 // If a user wrote a parameter with __strong explicitly, then assume they
8846 // want "real" strong semantics for that parameter. This works because if
8847 // the parameter was written with __strong, then the strong qualifier will
8848 // be non-local.
8849 if (Ty.getLocalUnqualifiedType().getQualifiers().getObjCLifetime() ==
8850 Qualifiers::OCL_Strong)
8851 continue;
8852
8853 tryMakeVariablePseudoStrong(S, PVD, /*DiagnoseFailure=*/false);
8854 }
8855 handleSimpleAttribute<ObjCExternallyRetainedAttr>(S, D, AL);
8856}
8857
8858static void handleMIGServerRoutineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8859 // Check that the return type is a `typedef int kern_return_t` or a typedef
8860 // around it, because otherwise MIG convention checks make no sense.
8861 // BlockDecl doesn't store a return type, so it's annoying to check,
8862 // so let's skip it for now.
8863 if (!isa<BlockDecl>(Val: D)) {
8864 QualType T = getFunctionOrMethodResultType(D);
8865 bool IsKernReturnT = false;
8866 while (const auto *TT = T->getAs<TypedefType>()) {
8867 IsKernReturnT = (TT->getDecl()->getName() == "kern_return_t");
8868 T = TT->desugar();
8869 }
8870 if (!IsKernReturnT || T.getCanonicalType() != S.getASTContext().IntTy) {
8871 S.Diag(D->getBeginLoc(),
8872 diag::warn_mig_server_routine_does_not_return_kern_return_t);
8873 return;
8874 }
8875 }
8876
8877 handleSimpleAttribute<MIGServerRoutineAttr>(S, D, AL);
8878}
8879
8880static void handleMSAllocatorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8881 // Warn if the return type is not a pointer or reference type.
8882 if (auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
8883 QualType RetTy = FD->getReturnType();
8884 if (!RetTy->isPointerType() && !RetTy->isReferenceType()) {
8885 S.Diag(AL.getLoc(), diag::warn_declspec_allocator_nonpointer)
8886 << AL.getRange() << RetTy;
8887 return;
8888 }
8889 }
8890
8891 handleSimpleAttribute<MSAllocatorAttr>(S, D, AL);
8892}
8893
8894static void handleAcquireHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8895 if (AL.isUsedAsTypeAttr())
8896 return;
8897 // Warn if the parameter is definitely not an output parameter.
8898 if (const auto *PVD = dyn_cast<ParmVarDecl>(Val: D)) {
8899 if (PVD->getType()->isIntegerType()) {
8900 S.Diag(AL.getLoc(), diag::err_attribute_output_parameter)
8901 << AL.getRange();
8902 return;
8903 }
8904 }
8905 StringRef Argument;
8906 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: Argument))
8907 return;
8908 D->addAttr(AcquireHandleAttr::Create(S.Context, Argument, AL));
8909}
8910
8911template<typename Attr>
8912static void handleHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8913 StringRef Argument;
8914 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: Argument))
8915 return;
8916 D->addAttr(A: Attr::Create(S.Context, Argument, AL));
8917}
8918
8919template<typename Attr>
8920static void handleUnsafeBufferUsage(Sema &S, Decl *D, const ParsedAttr &AL) {
8921 D->addAttr(A: Attr::Create(S.Context, AL));
8922}
8923
8924static void handleCFGuardAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8925 // The guard attribute takes a single identifier argument.
8926
8927 if (!AL.isArgIdent(Arg: 0)) {
8928 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
8929 << AL << AANT_ArgumentIdentifier;
8930 return;
8931 }
8932
8933 CFGuardAttr::GuardArg Arg;
8934 IdentifierInfo *II = AL.getArgAsIdent(Arg: 0)->Ident;
8935 if (!CFGuardAttr::ConvertStrToGuardArg(II->getName(), Arg)) {
8936 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
8937 return;
8938 }
8939
8940 D->addAttr(::new (S.Context) CFGuardAttr(S.Context, AL, Arg));
8941}
8942
8943
8944template <typename AttrTy>
8945static const AttrTy *findEnforceTCBAttrByName(Decl *D, StringRef Name) {
8946 auto Attrs = D->specific_attrs<AttrTy>();
8947 auto I = llvm::find_if(Attrs,
8948 [Name](const AttrTy *A) {
8949 return A->getTCBName() == Name;
8950 });
8951 return I == Attrs.end() ? nullptr : *I;
8952}
8953
8954template <typename AttrTy, typename ConflictingAttrTy>
8955static void handleEnforceTCBAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8956 StringRef Argument;
8957 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: Argument))
8958 return;
8959
8960 // A function cannot be have both regular and leaf membership in the same TCB.
8961 if (const ConflictingAttrTy *ConflictingAttr =
8962 findEnforceTCBAttrByName<ConflictingAttrTy>(D, Argument)) {
8963 // We could attach a note to the other attribute but in this case
8964 // there's no need given how the two are very close to each other.
8965 S.Diag(AL.getLoc(), diag::err_tcb_conflicting_attributes)
8966 << AL.getAttrName()->getName() << ConflictingAttr->getAttrName()->getName()
8967 << Argument;
8968
8969 // Error recovery: drop the non-leaf attribute so that to suppress
8970 // all future warnings caused by erroneous attributes. The leaf attribute
8971 // needs to be kept because it can only suppresses warnings, not cause them.
8972 D->dropAttr<EnforceTCBAttr>();
8973 return;
8974 }
8975
8976 D->addAttr(A: AttrTy::Create(S.Context, Argument, AL));
8977}
8978
8979template <typename AttrTy, typename ConflictingAttrTy>
8980static AttrTy *mergeEnforceTCBAttrImpl(Sema &S, Decl *D, const AttrTy &AL) {
8981 // Check if the new redeclaration has different leaf-ness in the same TCB.
8982 StringRef TCBName = AL.getTCBName();
8983 if (const ConflictingAttrTy *ConflictingAttr =
8984 findEnforceTCBAttrByName<ConflictingAttrTy>(D, TCBName)) {
8985 S.Diag(ConflictingAttr->getLoc(), diag::err_tcb_conflicting_attributes)
8986 << ConflictingAttr->getAttrName()->getName()
8987 << AL.getAttrName()->getName() << TCBName;
8988
8989 // Add a note so that the user could easily find the conflicting attribute.
8990 S.Diag(AL.getLoc(), diag::note_conflicting_attribute);
8991
8992 // More error recovery.
8993 D->dropAttr<EnforceTCBAttr>();
8994 return nullptr;
8995 }
8996
8997 ASTContext &Context = S.getASTContext();
8998 return ::new(Context) AttrTy(Context, AL, AL.getTCBName());
8999}
9000
9001EnforceTCBAttr *Sema::mergeEnforceTCBAttr(Decl *D, const EnforceTCBAttr &AL) {
9002 return mergeEnforceTCBAttrImpl<EnforceTCBAttr, EnforceTCBLeafAttr>(
9003 *this, D, AL);
9004}
9005
9006EnforceTCBLeafAttr *Sema::mergeEnforceTCBLeafAttr(
9007 Decl *D, const EnforceTCBLeafAttr &AL) {
9008 return mergeEnforceTCBAttrImpl<EnforceTCBLeafAttr, EnforceTCBAttr>(
9009 *this, D, AL);
9010}
9011
9012//===----------------------------------------------------------------------===//
9013// Top Level Sema Entry Points
9014//===----------------------------------------------------------------------===//
9015
9016// Returns true if the attribute must delay setting its arguments until after
9017// template instantiation, and false otherwise.
9018static bool MustDelayAttributeArguments(const ParsedAttr &AL) {
9019 // Only attributes that accept expression parameter packs can delay arguments.
9020 if (!AL.acceptsExprPack())
9021 return false;
9022
9023 bool AttrHasVariadicArg = AL.hasVariadicArg();
9024 unsigned AttrNumArgs = AL.getNumArgMembers();
9025 for (size_t I = 0; I < std::min(a: AL.getNumArgs(), b: AttrNumArgs); ++I) {
9026 bool IsLastAttrArg = I == (AttrNumArgs - 1);
9027 // If the argument is the last argument and it is variadic it can contain
9028 // any expression.
9029 if (IsLastAttrArg && AttrHasVariadicArg)
9030 return false;
9031 Expr *E = AL.getArgAsExpr(Arg: I);
9032 bool ArgMemberCanHoldExpr = AL.isParamExpr(N: I);
9033 // If the expression is a pack expansion then arguments must be delayed
9034 // unless the argument is an expression and it is the last argument of the
9035 // attribute.
9036 if (isa<PackExpansionExpr>(Val: E))
9037 return !(IsLastAttrArg && ArgMemberCanHoldExpr);
9038 // Last case is if the expression is value dependent then it must delay
9039 // arguments unless the corresponding argument is able to hold the
9040 // expression.
9041 if (E->isValueDependent() && !ArgMemberCanHoldExpr)
9042 return true;
9043 }
9044 return false;
9045}
9046
9047static bool checkArmNewAttrMutualExclusion(
9048 Sema &S, const ParsedAttr &AL, const FunctionProtoType *FPT,
9049 FunctionType::ArmStateValue CurrentState, StringRef StateName) {
9050 auto CheckForIncompatibleAttr =
9051 [&](FunctionType::ArmStateValue IncompatibleState,
9052 StringRef IncompatibleStateName) {
9053 if (CurrentState == IncompatibleState) {
9054 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
9055 << (std::string("'__arm_new(\"") + StateName.str() + "\")'")
9056 << (std::string("'") + IncompatibleStateName.str() + "(\"" +
9057 StateName.str() + "\")'")
9058 << true;
9059 AL.setInvalid();
9060 }
9061 };
9062
9063 CheckForIncompatibleAttr(FunctionType::ARM_In, "__arm_in");
9064 CheckForIncompatibleAttr(FunctionType::ARM_Out, "__arm_out");
9065 CheckForIncompatibleAttr(FunctionType::ARM_InOut, "__arm_inout");
9066 CheckForIncompatibleAttr(FunctionType::ARM_Preserves, "__arm_preserves");
9067 return AL.isInvalid();
9068}
9069
9070static void handleArmNewAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
9071 if (!AL.getNumArgs()) {
9072 S.Diag(AL.getLoc(), diag::err_missing_arm_state) << AL;
9073 AL.setInvalid();
9074 return;
9075 }
9076
9077 std::vector<StringRef> NewState;
9078 if (const auto *ExistingAttr = D->getAttr<ArmNewAttr>()) {
9079 for (StringRef S : ExistingAttr->newArgs())
9080 NewState.push_back(S);
9081 }
9082
9083 bool HasZA = false;
9084 bool HasZT0 = false;
9085 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
9086 StringRef StateName;
9087 SourceLocation LiteralLoc;
9088 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: I, Str&: StateName, ArgLocation: &LiteralLoc))
9089 return;
9090
9091 if (StateName == "za")
9092 HasZA = true;
9093 else if (StateName == "zt0")
9094 HasZT0 = true;
9095 else {
9096 S.Diag(LiteralLoc, diag::err_unknown_arm_state) << StateName;
9097 AL.setInvalid();
9098 return;
9099 }
9100
9101 if (!llvm::is_contained(Range&: NewState, Element: StateName)) // Avoid adding duplicates.
9102 NewState.push_back(x: StateName);
9103 }
9104
9105 if (auto *FPT = dyn_cast<FunctionProtoType>(Val: D->getFunctionType())) {
9106 FunctionType::ArmStateValue ZAState =
9107 FunctionType::getArmZAState(AttrBits: FPT->getAArch64SMEAttributes());
9108 if (HasZA && ZAState != FunctionType::ARM_None &&
9109 checkArmNewAttrMutualExclusion(S, AL, FPT, CurrentState: ZAState, StateName: "za"))
9110 return;
9111 FunctionType::ArmStateValue ZT0State =
9112 FunctionType::getArmZT0State(AttrBits: FPT->getAArch64SMEAttributes());
9113 if (HasZT0 && ZT0State != FunctionType::ARM_None &&
9114 checkArmNewAttrMutualExclusion(S, AL, FPT, CurrentState: ZT0State, StateName: "zt0"))
9115 return;
9116 }
9117
9118 D->dropAttr<ArmNewAttr>();
9119 D->addAttr(::new (S.Context)
9120 ArmNewAttr(S.Context, AL, NewState.data(), NewState.size()));
9121}
9122
9123/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
9124/// the attribute applies to decls. If the attribute is a type attribute, just
9125/// silently ignore it if a GNU attribute.
9126static void
9127ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
9128 const Sema::ProcessDeclAttributeOptions &Options) {
9129 if (AL.isInvalid() || AL.getKind() == ParsedAttr::IgnoredAttribute)
9130 return;
9131
9132 // Ignore C++11 attributes on declarator chunks: they appertain to the type
9133 // instead.
9134 if (AL.isCXX11Attribute() && !Options.IncludeCXX11Attributes)
9135 return;
9136
9137 // Unknown attributes are automatically warned on. Target-specific attributes
9138 // which do not apply to the current target architecture are treated as
9139 // though they were unknown attributes.
9140 if (AL.getKind() == ParsedAttr::UnknownAttribute ||
9141 !AL.existsInTarget(Target: S.Context.getTargetInfo())) {
9142 S.Diag(AL.getLoc(),
9143 AL.isRegularKeywordAttribute()
9144 ? (unsigned)diag::err_keyword_not_supported_on_target
9145 : AL.isDeclspecAttribute()
9146 ? (unsigned)diag::warn_unhandled_ms_attribute_ignored
9147 : (unsigned)diag::warn_unknown_attribute_ignored)
9148 << AL << AL.getRange();
9149 return;
9150 }
9151
9152 // Check if argument population must delayed to after template instantiation.
9153 bool MustDelayArgs = MustDelayAttributeArguments(AL);
9154
9155 // Argument number check must be skipped if arguments are delayed.
9156 if (S.checkCommonAttributeFeatures(D, A: AL, SkipArgCountCheck: MustDelayArgs))
9157 return;
9158
9159 if (MustDelayArgs) {
9160 AL.handleAttrWithDelayedArgs(S, D);
9161 return;
9162 }
9163
9164 switch (AL.getKind()) {
9165 default:
9166 if (AL.getInfo().handleDeclAttribute(S, D, Attr: AL) != ParsedAttrInfo::NotHandled)
9167 break;
9168 if (!AL.isStmtAttr()) {
9169 assert(AL.isTypeAttr() && "Non-type attribute not handled");
9170 }
9171 if (AL.isTypeAttr()) {
9172 if (Options.IgnoreTypeAttributes)
9173 break;
9174 if (!AL.isStandardAttributeSyntax() && !AL.isRegularKeywordAttribute()) {
9175 // Non-[[]] type attributes are handled in processTypeAttrs(); silently
9176 // move on.
9177 break;
9178 }
9179
9180 // According to the C and C++ standards, we should never see a
9181 // [[]] type attribute on a declaration. However, we have in the past
9182 // allowed some type attributes to "slide" to the `DeclSpec`, so we need
9183 // to continue to support this legacy behavior. We only do this, however,
9184 // if
9185 // - we actually have a `DeclSpec`, i.e. if we're looking at a
9186 // `DeclaratorDecl`, or
9187 // - we are looking at an alias-declaration, where historically we have
9188 // allowed type attributes after the identifier to slide to the type.
9189 if (AL.slidesFromDeclToDeclSpecLegacyBehavior() &&
9190 isa<DeclaratorDecl, TypeAliasDecl>(Val: D)) {
9191 // Suggest moving the attribute to the type instead, but only for our
9192 // own vendor attributes; moving other vendors' attributes might hurt
9193 // portability.
9194 if (AL.isClangScope()) {
9195 S.Diag(AL.getLoc(), diag::warn_type_attribute_deprecated_on_decl)
9196 << AL << D->getLocation();
9197 }
9198
9199 // Allow this type attribute to be handled in processTypeAttrs();
9200 // silently move on.
9201 break;
9202 }
9203
9204 if (AL.getKind() == ParsedAttr::AT_Regparm) {
9205 // `regparm` is a special case: It's a type attribute but we still want
9206 // to treat it as if it had been written on the declaration because that
9207 // way we'll be able to handle it directly in `processTypeAttr()`.
9208 // If we treated `regparm` it as if it had been written on the
9209 // `DeclSpec`, the logic in `distributeFunctionTypeAttrFromDeclSepc()`
9210 // would try to move it to the declarator, but that doesn't work: We
9211 // can't remove the attribute from the list of declaration attributes
9212 // because it might be needed by other declarators in the same
9213 // declaration.
9214 break;
9215 }
9216
9217 if (AL.getKind() == ParsedAttr::AT_VectorSize) {
9218 // `vector_size` is a special case: It's a type attribute semantically,
9219 // but GCC expects the [[]] syntax to be written on the declaration (and
9220 // warns that the attribute has no effect if it is placed on the
9221 // decl-specifier-seq).
9222 // Silently move on and allow the attribute to be handled in
9223 // processTypeAttr().
9224 break;
9225 }
9226
9227 if (AL.getKind() == ParsedAttr::AT_NoDeref) {
9228 // FIXME: `noderef` currently doesn't work correctly in [[]] syntax.
9229 // See https://github.com/llvm/llvm-project/issues/55790 for details.
9230 // We allow processTypeAttrs() to emit a warning and silently move on.
9231 break;
9232 }
9233 }
9234 // N.B., ClangAttrEmitter.cpp emits a diagnostic helper that ensures a
9235 // statement attribute is not written on a declaration, but this code is
9236 // needed for type attributes as well as statement attributes in Attr.td
9237 // that do not list any subjects.
9238 S.Diag(AL.getLoc(), diag::err_attribute_invalid_on_decl)
9239 << AL << AL.isRegularKeywordAttribute() << D->getLocation();
9240 break;
9241 case ParsedAttr::AT_Interrupt:
9242 handleInterruptAttr(S, D, AL);
9243 break;
9244 case ParsedAttr::AT_X86ForceAlignArgPointer:
9245 handleX86ForceAlignArgPointerAttr(S, D, AL);
9246 break;
9247 case ParsedAttr::AT_ReadOnlyPlacement:
9248 handleSimpleAttribute<ReadOnlyPlacementAttr>(S, D, AL);
9249 break;
9250 case ParsedAttr::AT_DLLExport:
9251 case ParsedAttr::AT_DLLImport:
9252 handleDLLAttr(S, D, A: AL);
9253 break;
9254 case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
9255 handleAMDGPUFlatWorkGroupSizeAttr(S, D, AL);
9256 break;
9257 case ParsedAttr::AT_AMDGPUWavesPerEU:
9258 handleAMDGPUWavesPerEUAttr(S, D, AL);
9259 break;
9260 case ParsedAttr::AT_AMDGPUNumSGPR:
9261 handleAMDGPUNumSGPRAttr(S, D, AL);
9262 break;
9263 case ParsedAttr::AT_AMDGPUNumVGPR:
9264 handleAMDGPUNumVGPRAttr(S, D, AL);
9265 break;
9266 case ParsedAttr::AT_AMDGPUMaxNumWorkGroups:
9267 handleAMDGPUMaxNumWorkGroupsAttr(S, D, AL);
9268 break;
9269 case ParsedAttr::AT_AVRSignal:
9270 handleAVRSignalAttr(S, D, AL);
9271 break;
9272 case ParsedAttr::AT_BPFPreserveAccessIndex:
9273 handleBPFPreserveAccessIndexAttr(S, D, AL);
9274 break;
9275 case ParsedAttr::AT_BPFPreserveStaticOffset:
9276 handleSimpleAttribute<BPFPreserveStaticOffsetAttr>(S, D, AL);
9277 break;
9278 case ParsedAttr::AT_BTFDeclTag:
9279 handleBTFDeclTagAttr(S, D, AL);
9280 break;
9281 case ParsedAttr::AT_WebAssemblyExportName:
9282 handleWebAssemblyExportNameAttr(S, D, AL);
9283 break;
9284 case ParsedAttr::AT_WebAssemblyImportModule:
9285 handleWebAssemblyImportModuleAttr(S, D, AL);
9286 break;
9287 case ParsedAttr::AT_WebAssemblyImportName:
9288 handleWebAssemblyImportNameAttr(S, D, AL);
9289 break;
9290 case ParsedAttr::AT_IBOutlet:
9291 handleIBOutlet(S, D, AL);
9292 break;
9293 case ParsedAttr::AT_IBOutletCollection:
9294 handleIBOutletCollection(S, D, AL);
9295 break;
9296 case ParsedAttr::AT_IFunc:
9297 handleIFuncAttr(S, D, AL);
9298 break;
9299 case ParsedAttr::AT_Alias:
9300 handleAliasAttr(S, D, AL);
9301 break;
9302 case ParsedAttr::AT_Aligned:
9303 handleAlignedAttr(S, D, AL);
9304 break;
9305 case ParsedAttr::AT_AlignValue:
9306 handleAlignValueAttr(S, D, AL);
9307 break;
9308 case ParsedAttr::AT_AllocSize:
9309 handleAllocSizeAttr(S, D, AL);
9310 break;
9311 case ParsedAttr::AT_AlwaysInline:
9312 handleAlwaysInlineAttr(S, D, AL);
9313 break;
9314 case ParsedAttr::AT_AnalyzerNoReturn:
9315 handleAnalyzerNoReturnAttr(S, D, AL);
9316 break;
9317 case ParsedAttr::AT_TLSModel:
9318 handleTLSModelAttr(S, D, AL);
9319 break;
9320 case ParsedAttr::AT_Annotate:
9321 handleAnnotateAttr(S, D, AL);
9322 break;
9323 case ParsedAttr::AT_Availability:
9324 handleAvailabilityAttr(S, D, AL);
9325 break;
9326 case ParsedAttr::AT_CarriesDependency:
9327 handleDependencyAttr(S, Scope: scope, D, AL);
9328 break;
9329 case ParsedAttr::AT_CPUDispatch:
9330 case ParsedAttr::AT_CPUSpecific:
9331 handleCPUSpecificAttr(S, D, AL);
9332 break;
9333 case ParsedAttr::AT_Common:
9334 handleCommonAttr(S, D, AL);
9335 break;
9336 case ParsedAttr::AT_CUDAConstant:
9337 handleConstantAttr(S, D, AL);
9338 break;
9339 case ParsedAttr::AT_PassObjectSize:
9340 handlePassObjectSizeAttr(S, D, AL);
9341 break;
9342 case ParsedAttr::AT_Constructor:
9343 handleConstructorAttr(S, D, AL);
9344 break;
9345 case ParsedAttr::AT_Deprecated:
9346 handleDeprecatedAttr(S, D, AL);
9347 break;
9348 case ParsedAttr::AT_Destructor:
9349 handleDestructorAttr(S, D, AL);
9350 break;
9351 case ParsedAttr::AT_EnableIf:
9352 handleEnableIfAttr(S, D, AL);
9353 break;
9354 case ParsedAttr::AT_Error:
9355 handleErrorAttr(S, D, AL);
9356 break;
9357 case ParsedAttr::AT_ExcludeFromExplicitInstantiation:
9358 handleExcludeFromExplicitInstantiationAttr(S, D, AL);
9359 break;
9360 case ParsedAttr::AT_DiagnoseIf:
9361 handleDiagnoseIfAttr(S, D, AL);
9362 break;
9363 case ParsedAttr::AT_DiagnoseAsBuiltin:
9364 handleDiagnoseAsBuiltinAttr(S, D, AL);
9365 break;
9366 case ParsedAttr::AT_NoBuiltin:
9367 handleNoBuiltinAttr(S, D, AL);
9368 break;
9369 case ParsedAttr::AT_ExtVectorType:
9370 handleExtVectorTypeAttr(S, D, AL);
9371 break;
9372 case ParsedAttr::AT_ExternalSourceSymbol:
9373 handleExternalSourceSymbolAttr(S, D, AL);
9374 break;
9375 case ParsedAttr::AT_MinSize:
9376 handleMinSizeAttr(S, D, AL);
9377 break;
9378 case ParsedAttr::AT_OptimizeNone:
9379 handleOptimizeNoneAttr(S, D, AL);
9380 break;
9381 case ParsedAttr::AT_EnumExtensibility:
9382 handleEnumExtensibilityAttr(S, D, AL);
9383 break;
9384 case ParsedAttr::AT_SYCLKernel:
9385 handleSYCLKernelAttr(S, D, AL);
9386 break;
9387 case ParsedAttr::AT_SYCLSpecialClass:
9388 handleSimpleAttribute<SYCLSpecialClassAttr>(S, D, AL);
9389 break;
9390 case ParsedAttr::AT_Format:
9391 handleFormatAttr(S, D, AL);
9392 break;
9393 case ParsedAttr::AT_FormatArg:
9394 handleFormatArgAttr(S, D, AL);
9395 break;
9396 case ParsedAttr::AT_Callback:
9397 handleCallbackAttr(S, D, AL);
9398 break;
9399 case ParsedAttr::AT_CalledOnce:
9400 handleCalledOnceAttr(S, D, AL);
9401 break;
9402 case ParsedAttr::AT_NVPTXKernel:
9403 case ParsedAttr::AT_CUDAGlobal:
9404 handleGlobalAttr(S, D, AL);
9405 break;
9406 case ParsedAttr::AT_CUDADevice:
9407 handleDeviceAttr(S, D, AL);
9408 break;
9409 case ParsedAttr::AT_HIPManaged:
9410 handleManagedAttr(S, D, AL);
9411 break;
9412 case ParsedAttr::AT_GNUInline:
9413 handleGNUInlineAttr(S, D, AL);
9414 break;
9415 case ParsedAttr::AT_CUDALaunchBounds:
9416 handleLaunchBoundsAttr(S, D, AL);
9417 break;
9418 case ParsedAttr::AT_Restrict:
9419 handleRestrictAttr(S, D, AL);
9420 break;
9421 case ParsedAttr::AT_Mode:
9422 handleModeAttr(S, D, AL);
9423 break;
9424 case ParsedAttr::AT_NonNull:
9425 if (auto *PVD = dyn_cast<ParmVarDecl>(Val: D))
9426 handleNonNullAttrParameter(S, D: PVD, AL);
9427 else
9428 handleNonNullAttr(S, D, AL);
9429 break;
9430 case ParsedAttr::AT_ReturnsNonNull:
9431 handleReturnsNonNullAttr(S, D, AL);
9432 break;
9433 case ParsedAttr::AT_NoEscape:
9434 handleNoEscapeAttr(S, D, AL);
9435 break;
9436 case ParsedAttr::AT_MaybeUndef:
9437 handleSimpleAttribute<MaybeUndefAttr>(S, D, AL);
9438 break;
9439 case ParsedAttr::AT_AssumeAligned:
9440 handleAssumeAlignedAttr(S, D, AL);
9441 break;
9442 case ParsedAttr::AT_AllocAlign:
9443 handleAllocAlignAttr(S, D, AL);
9444 break;
9445 case ParsedAttr::AT_Ownership:
9446 handleOwnershipAttr(S, D, AL);
9447 break;
9448 case ParsedAttr::AT_Naked:
9449 handleNakedAttr(S, D, AL);
9450 break;
9451 case ParsedAttr::AT_NoReturn:
9452 handleNoReturnAttr(S, D, Attrs: AL);
9453 break;
9454 case ParsedAttr::AT_CXX11NoReturn:
9455 handleStandardNoReturnAttr(S, D, A: AL);
9456 break;
9457 case ParsedAttr::AT_AnyX86NoCfCheck:
9458 handleNoCfCheckAttr(S, D, Attrs: AL);
9459 break;
9460 case ParsedAttr::AT_NoThrow:
9461 if (!AL.isUsedAsTypeAttr())
9462 handleSimpleAttribute<NoThrowAttr>(S, D, AL);
9463 break;
9464 case ParsedAttr::AT_CUDAShared:
9465 handleSharedAttr(S, D, AL);
9466 break;
9467 case ParsedAttr::AT_VecReturn:
9468 handleVecReturnAttr(S, D, AL);
9469 break;
9470 case ParsedAttr::AT_ObjCOwnership:
9471 handleObjCOwnershipAttr(S, D, AL);
9472 break;
9473 case ParsedAttr::AT_ObjCPreciseLifetime:
9474 handleObjCPreciseLifetimeAttr(S, D, AL);
9475 break;
9476 case ParsedAttr::AT_ObjCReturnsInnerPointer:
9477 handleObjCReturnsInnerPointerAttr(S, D, Attrs: AL);
9478 break;
9479 case ParsedAttr::AT_ObjCRequiresSuper:
9480 handleObjCRequiresSuperAttr(S, D, Attrs: AL);
9481 break;
9482 case ParsedAttr::AT_ObjCBridge:
9483 handleObjCBridgeAttr(S, D, AL);
9484 break;
9485 case ParsedAttr::AT_ObjCBridgeMutable:
9486 handleObjCBridgeMutableAttr(S, D, AL);
9487 break;
9488 case ParsedAttr::AT_ObjCBridgeRelated:
9489 handleObjCBridgeRelatedAttr(S, D, AL);
9490 break;
9491 case ParsedAttr::AT_ObjCDesignatedInitializer:
9492 handleObjCDesignatedInitializer(S, D, AL);
9493 break;
9494 case ParsedAttr::AT_ObjCRuntimeName:
9495 handleObjCRuntimeName(S, D, AL);
9496 break;
9497 case ParsedAttr::AT_ObjCBoxable:
9498 handleObjCBoxable(S, D, AL);
9499 break;
9500 case ParsedAttr::AT_NSErrorDomain:
9501 handleNSErrorDomain(S, D, Attr: AL);
9502 break;
9503 case ParsedAttr::AT_CFConsumed:
9504 case ParsedAttr::AT_NSConsumed:
9505 case ParsedAttr::AT_OSConsumed:
9506 S.AddXConsumedAttr(D, CI: AL, K: parsedAttrToRetainOwnershipKind(AL),
9507 /*IsTemplateInstantiation=*/false);
9508 break;
9509 case ParsedAttr::AT_OSReturnsRetainedOnZero:
9510 handleSimpleAttributeOrDiagnose<OSReturnsRetainedOnZeroAttr>(
9511 S, D, AL, isValidOSObjectOutParameter(D),
9512 diag::warn_ns_attribute_wrong_parameter_type,
9513 /*Extra Args=*/AL, /*pointer-to-OSObject-pointer*/ 3, AL.getRange());
9514 break;
9515 case ParsedAttr::AT_OSReturnsRetainedOnNonZero:
9516 handleSimpleAttributeOrDiagnose<OSReturnsRetainedOnNonZeroAttr>(
9517 S, D, AL, isValidOSObjectOutParameter(D),
9518 diag::warn_ns_attribute_wrong_parameter_type,
9519 /*Extra Args=*/AL, /*pointer-to-OSObject-poointer*/ 3, AL.getRange());
9520 break;
9521 case ParsedAttr::AT_NSReturnsAutoreleased:
9522 case ParsedAttr::AT_NSReturnsNotRetained:
9523 case ParsedAttr::AT_NSReturnsRetained:
9524 case ParsedAttr::AT_CFReturnsNotRetained:
9525 case ParsedAttr::AT_CFReturnsRetained:
9526 case ParsedAttr::AT_OSReturnsNotRetained:
9527 case ParsedAttr::AT_OSReturnsRetained:
9528 handleXReturnsXRetainedAttr(S, D, AL);
9529 break;
9530 case ParsedAttr::AT_WorkGroupSizeHint:
9531 handleWorkGroupSize<WorkGroupSizeHintAttr>(S, D, AL);
9532 break;
9533 case ParsedAttr::AT_ReqdWorkGroupSize:
9534 handleWorkGroupSize<ReqdWorkGroupSizeAttr>(S, D, AL);
9535 break;
9536 case ParsedAttr::AT_OpenCLIntelReqdSubGroupSize:
9537 handleSubGroupSize(S, D, AL);
9538 break;
9539 case ParsedAttr::AT_VecTypeHint:
9540 handleVecTypeHint(S, D, AL);
9541 break;
9542 case ParsedAttr::AT_InitPriority:
9543 handleInitPriorityAttr(S, D, AL);
9544 break;
9545 case ParsedAttr::AT_Packed:
9546 handlePackedAttr(S, D, AL);
9547 break;
9548 case ParsedAttr::AT_PreferredName:
9549 handlePreferredName(S, D, AL);
9550 break;
9551 case ParsedAttr::AT_Section:
9552 handleSectionAttr(S, D, AL);
9553 break;
9554 case ParsedAttr::AT_CodeModel:
9555 handleCodeModelAttr(S, D, AL);
9556 break;
9557 case ParsedAttr::AT_RandomizeLayout:
9558 handleRandomizeLayoutAttr(S, D, AL);
9559 break;
9560 case ParsedAttr::AT_NoRandomizeLayout:
9561 handleNoRandomizeLayoutAttr(S, D, AL);
9562 break;
9563 case ParsedAttr::AT_CodeSeg:
9564 handleCodeSegAttr(S, D, AL);
9565 break;
9566 case ParsedAttr::AT_Target:
9567 handleTargetAttr(S, D, AL);
9568 break;
9569 case ParsedAttr::AT_TargetVersion:
9570 handleTargetVersionAttr(S, D, AL);
9571 break;
9572 case ParsedAttr::AT_TargetClones:
9573 handleTargetClonesAttr(S, D, AL);
9574 break;
9575 case ParsedAttr::AT_MinVectorWidth:
9576 handleMinVectorWidthAttr(S, D, AL);
9577 break;
9578 case ParsedAttr::AT_Unavailable:
9579 handleAttrWithMessage<UnavailableAttr>(S, D, AL);
9580 break;
9581 case ParsedAttr::AT_OMPAssume:
9582 handleOMPAssumeAttr(S, D, AL);
9583 break;
9584 case ParsedAttr::AT_ObjCDirect:
9585 handleObjCDirectAttr(S, D, AL);
9586 break;
9587 case ParsedAttr::AT_ObjCDirectMembers:
9588 handleObjCDirectMembersAttr(S, D, AL);
9589 handleSimpleAttribute<ObjCDirectMembersAttr>(S, D, AL);
9590 break;
9591 case ParsedAttr::AT_ObjCExplicitProtocolImpl:
9592 handleObjCSuppresProtocolAttr(S, D, AL);
9593 break;
9594 case ParsedAttr::AT_Unused:
9595 handleUnusedAttr(S, D, AL);
9596 break;
9597 case ParsedAttr::AT_Visibility:
9598 handleVisibilityAttr(S, D, AL, isTypeVisibility: false);
9599 break;
9600 case ParsedAttr::AT_TypeVisibility:
9601 handleVisibilityAttr(S, D, AL, isTypeVisibility: true);
9602 break;
9603 case ParsedAttr::AT_WarnUnusedResult:
9604 handleWarnUnusedResult(S, D, AL);
9605 break;
9606 case ParsedAttr::AT_WeakRef:
9607 handleWeakRefAttr(S, D, AL);
9608 break;
9609 case ParsedAttr::AT_WeakImport:
9610 handleWeakImportAttr(S, D, AL);
9611 break;
9612 case ParsedAttr::AT_TransparentUnion:
9613 handleTransparentUnionAttr(S, D, AL);
9614 break;
9615 case ParsedAttr::AT_ObjCMethodFamily:
9616 handleObjCMethodFamilyAttr(S, D, AL);
9617 break;
9618 case ParsedAttr::AT_ObjCNSObject:
9619 handleObjCNSObject(S, D, AL);
9620 break;
9621 case ParsedAttr::AT_ObjCIndependentClass:
9622 handleObjCIndependentClass(S, D, AL);
9623 break;
9624 case ParsedAttr::AT_Blocks:
9625 handleBlocksAttr(S, D, AL);
9626 break;
9627 case ParsedAttr::AT_Sentinel:
9628 handleSentinelAttr(S, D, AL);
9629 break;
9630 case ParsedAttr::AT_Cleanup:
9631 handleCleanupAttr(S, D, AL);
9632 break;
9633 case ParsedAttr::AT_NoDebug:
9634 handleNoDebugAttr(S, D, AL);
9635 break;
9636 case ParsedAttr::AT_CmseNSEntry:
9637 handleCmseNSEntryAttr(S, D, AL);
9638 break;
9639 case ParsedAttr::AT_StdCall:
9640 case ParsedAttr::AT_CDecl:
9641 case ParsedAttr::AT_FastCall:
9642 case ParsedAttr::AT_ThisCall:
9643 case ParsedAttr::AT_Pascal:
9644 case ParsedAttr::AT_RegCall:
9645 case ParsedAttr::AT_SwiftCall:
9646 case ParsedAttr::AT_SwiftAsyncCall:
9647 case ParsedAttr::AT_VectorCall:
9648 case ParsedAttr::AT_MSABI:
9649 case ParsedAttr::AT_SysVABI:
9650 case ParsedAttr::AT_Pcs:
9651 case ParsedAttr::AT_IntelOclBicc:
9652 case ParsedAttr::AT_PreserveMost:
9653 case ParsedAttr::AT_PreserveAll:
9654 case ParsedAttr::AT_AArch64VectorPcs:
9655 case ParsedAttr::AT_AArch64SVEPcs:
9656 case ParsedAttr::AT_AMDGPUKernelCall:
9657 case ParsedAttr::AT_M68kRTD:
9658 case ParsedAttr::AT_PreserveNone:
9659 case ParsedAttr::AT_RISCVVectorCC:
9660 handleCallConvAttr(S, D, AL);
9661 break;
9662 case ParsedAttr::AT_Suppress:
9663 handleSuppressAttr(S, D, AL);
9664 break;
9665 case ParsedAttr::AT_Owner:
9666 case ParsedAttr::AT_Pointer:
9667 handleLifetimeCategoryAttr(S, D, AL);
9668 break;
9669 case ParsedAttr::AT_OpenCLAccess:
9670 handleOpenCLAccessAttr(S, D, AL);
9671 break;
9672 case ParsedAttr::AT_OpenCLNoSVM:
9673 handleOpenCLNoSVMAttr(S, D, AL);
9674 break;
9675 case ParsedAttr::AT_SwiftContext:
9676 S.AddParameterABIAttr(D, CI: AL, abi: ParameterABI::SwiftContext);
9677 break;
9678 case ParsedAttr::AT_SwiftAsyncContext:
9679 S.AddParameterABIAttr(D, CI: AL, abi: ParameterABI::SwiftAsyncContext);
9680 break;
9681 case ParsedAttr::AT_SwiftErrorResult:
9682 S.AddParameterABIAttr(D, CI: AL, abi: ParameterABI::SwiftErrorResult);
9683 break;
9684 case ParsedAttr::AT_SwiftIndirectResult:
9685 S.AddParameterABIAttr(D, CI: AL, abi: ParameterABI::SwiftIndirectResult);
9686 break;
9687 case ParsedAttr::AT_InternalLinkage:
9688 handleInternalLinkageAttr(S, D, AL);
9689 break;
9690 case ParsedAttr::AT_ZeroCallUsedRegs:
9691 handleZeroCallUsedRegsAttr(S, D, AL);
9692 break;
9693 case ParsedAttr::AT_FunctionReturnThunks:
9694 handleFunctionReturnThunksAttr(S, D, AL);
9695 break;
9696 case ParsedAttr::AT_NoMerge:
9697 handleNoMergeAttr(S, D, AL);
9698 break;
9699 case ParsedAttr::AT_NoUniqueAddress:
9700 handleNoUniqueAddressAttr(S, D, AL);
9701 break;
9702
9703 case ParsedAttr::AT_AvailableOnlyInDefaultEvalMethod:
9704 handleAvailableOnlyInDefaultEvalMethod(S, D, AL);
9705 break;
9706
9707 case ParsedAttr::AT_CountedBy:
9708 handleCountedByAttrField(S, D, AL);
9709 break;
9710
9711 // Microsoft attributes:
9712 case ParsedAttr::AT_LayoutVersion:
9713 handleLayoutVersion(S, D, AL);
9714 break;
9715 case ParsedAttr::AT_Uuid:
9716 handleUuidAttr(S, D, AL);
9717 break;
9718 case ParsedAttr::AT_MSInheritance:
9719 handleMSInheritanceAttr(S, D, AL);
9720 break;
9721 case ParsedAttr::AT_Thread:
9722 handleDeclspecThreadAttr(S, D, AL);
9723 break;
9724 case ParsedAttr::AT_MSConstexpr:
9725 handleMSConstexprAttr(S, D, AL);
9726 break;
9727
9728 // HLSL attributes:
9729 case ParsedAttr::AT_HLSLNumThreads:
9730 handleHLSLNumThreadsAttr(S, D, AL);
9731 break;
9732 case ParsedAttr::AT_HLSLSV_GroupIndex:
9733 handleSimpleAttribute<HLSLSV_GroupIndexAttr>(S, D, AL);
9734 break;
9735 case ParsedAttr::AT_HLSLSV_DispatchThreadID:
9736 handleHLSLSV_DispatchThreadIDAttr(S, D, AL);
9737 break;
9738 case ParsedAttr::AT_HLSLShader:
9739 handleHLSLShaderAttr(S, D, AL);
9740 break;
9741 case ParsedAttr::AT_HLSLResourceBinding:
9742 handleHLSLResourceBindingAttr(S, D, AL);
9743 break;
9744 case ParsedAttr::AT_HLSLParamModifier:
9745 handleHLSLParamModifierAttr(S, D, AL);
9746 break;
9747
9748 case ParsedAttr::AT_AbiTag:
9749 handleAbiTagAttr(S, D, AL);
9750 break;
9751 case ParsedAttr::AT_CFGuard:
9752 handleCFGuardAttr(S, D, AL);
9753 break;
9754
9755 // Thread safety attributes:
9756 case ParsedAttr::AT_AssertExclusiveLock:
9757 handleAssertExclusiveLockAttr(S, D, AL);
9758 break;
9759 case ParsedAttr::AT_AssertSharedLock:
9760 handleAssertSharedLockAttr(S, D, AL);
9761 break;
9762 case ParsedAttr::AT_PtGuardedVar:
9763 handlePtGuardedVarAttr(S, D, AL);
9764 break;
9765 case ParsedAttr::AT_NoSanitize:
9766 handleNoSanitizeAttr(S, D, AL);
9767 break;
9768 case ParsedAttr::AT_NoSanitizeSpecific:
9769 handleNoSanitizeSpecificAttr(S, D, AL);
9770 break;
9771 case ParsedAttr::AT_GuardedBy:
9772 handleGuardedByAttr(S, D, AL);
9773 break;
9774 case ParsedAttr::AT_PtGuardedBy:
9775 handlePtGuardedByAttr(S, D, AL);
9776 break;
9777 case ParsedAttr::AT_ExclusiveTrylockFunction:
9778 handleExclusiveTrylockFunctionAttr(S, D, AL);
9779 break;
9780 case ParsedAttr::AT_LockReturned:
9781 handleLockReturnedAttr(S, D, AL);
9782 break;
9783 case ParsedAttr::AT_LocksExcluded:
9784 handleLocksExcludedAttr(S, D, AL);
9785 break;
9786 case ParsedAttr::AT_SharedTrylockFunction:
9787 handleSharedTrylockFunctionAttr(S, D, AL);
9788 break;
9789 case ParsedAttr::AT_AcquiredBefore:
9790 handleAcquiredBeforeAttr(S, D, AL);
9791 break;
9792 case ParsedAttr::AT_AcquiredAfter:
9793 handleAcquiredAfterAttr(S, D, AL);
9794 break;
9795
9796 // Capability analysis attributes.
9797 case ParsedAttr::AT_Capability:
9798 case ParsedAttr::AT_Lockable:
9799 handleCapabilityAttr(S, D, AL);
9800 break;
9801 case ParsedAttr::AT_RequiresCapability:
9802 handleRequiresCapabilityAttr(S, D, AL);
9803 break;
9804
9805 case ParsedAttr::AT_AssertCapability:
9806 handleAssertCapabilityAttr(S, D, AL);
9807 break;
9808 case ParsedAttr::AT_AcquireCapability:
9809 handleAcquireCapabilityAttr(S, D, AL);
9810 break;
9811 case ParsedAttr::AT_ReleaseCapability:
9812 handleReleaseCapabilityAttr(S, D, AL);
9813 break;
9814 case ParsedAttr::AT_TryAcquireCapability:
9815 handleTryAcquireCapabilityAttr(S, D, AL);
9816 break;
9817
9818 // Consumed analysis attributes.
9819 case ParsedAttr::AT_Consumable:
9820 handleConsumableAttr(S, D, AL);
9821 break;
9822 case ParsedAttr::AT_CallableWhen:
9823 handleCallableWhenAttr(S, D, AL);
9824 break;
9825 case ParsedAttr::AT_ParamTypestate:
9826 handleParamTypestateAttr(S, D, AL);
9827 break;
9828 case ParsedAttr::AT_ReturnTypestate:
9829 handleReturnTypestateAttr(S, D, AL);
9830 break;
9831 case ParsedAttr::AT_SetTypestate:
9832 handleSetTypestateAttr(S, D, AL);
9833 break;
9834 case ParsedAttr::AT_TestTypestate:
9835 handleTestTypestateAttr(S, D, AL);
9836 break;
9837
9838 // Type safety attributes.
9839 case ParsedAttr::AT_ArgumentWithTypeTag:
9840 handleArgumentWithTypeTagAttr(S, D, AL);
9841 break;
9842 case ParsedAttr::AT_TypeTagForDatatype:
9843 handleTypeTagForDatatypeAttr(S, D, AL);
9844 break;
9845
9846 // Swift attributes.
9847 case ParsedAttr::AT_SwiftAsyncName:
9848 handleSwiftAsyncName(S, D, AL);
9849 break;
9850 case ParsedAttr::AT_SwiftAttr:
9851 handleSwiftAttrAttr(S, D, AL);
9852 break;
9853 case ParsedAttr::AT_SwiftBridge:
9854 handleSwiftBridge(S, D, AL);
9855 break;
9856 case ParsedAttr::AT_SwiftError:
9857 handleSwiftError(S, D, AL);
9858 break;
9859 case ParsedAttr::AT_SwiftName:
9860 handleSwiftName(S, D, AL);
9861 break;
9862 case ParsedAttr::AT_SwiftNewType:
9863 handleSwiftNewType(S, D, AL);
9864 break;
9865 case ParsedAttr::AT_SwiftAsync:
9866 handleSwiftAsyncAttr(S, D, AL);
9867 break;
9868 case ParsedAttr::AT_SwiftAsyncError:
9869 handleSwiftAsyncError(S, D, AL);
9870 break;
9871
9872 // XRay attributes.
9873 case ParsedAttr::AT_XRayLogArgs:
9874 handleXRayLogArgsAttr(S, D, AL);
9875 break;
9876
9877 case ParsedAttr::AT_PatchableFunctionEntry:
9878 handlePatchableFunctionEntryAttr(S, D, AL);
9879 break;
9880
9881 case ParsedAttr::AT_AlwaysDestroy:
9882 case ParsedAttr::AT_NoDestroy:
9883 handleDestroyAttr(S, D, A: AL);
9884 break;
9885
9886 case ParsedAttr::AT_Uninitialized:
9887 handleUninitializedAttr(S, D, AL);
9888 break;
9889
9890 case ParsedAttr::AT_ObjCExternallyRetained:
9891 handleObjCExternallyRetainedAttr(S, D, AL);
9892 break;
9893
9894 case ParsedAttr::AT_MIGServerRoutine:
9895 handleMIGServerRoutineAttr(S, D, AL);
9896 break;
9897
9898 case ParsedAttr::AT_MSAllocator:
9899 handleMSAllocatorAttr(S, D, AL);
9900 break;
9901
9902 case ParsedAttr::AT_ArmBuiltinAlias:
9903 handleArmBuiltinAliasAttr(S, D, AL);
9904 break;
9905
9906 case ParsedAttr::AT_ArmLocallyStreaming:
9907 handleSimpleAttribute<ArmLocallyStreamingAttr>(S, D, AL);
9908 break;
9909
9910 case ParsedAttr::AT_ArmNew:
9911 handleArmNewAttr(S, D, AL);
9912 break;
9913
9914 case ParsedAttr::AT_AcquireHandle:
9915 handleAcquireHandleAttr(S, D, AL);
9916 break;
9917
9918 case ParsedAttr::AT_ReleaseHandle:
9919 handleHandleAttr<ReleaseHandleAttr>(S, D, AL);
9920 break;
9921
9922 case ParsedAttr::AT_UnsafeBufferUsage:
9923 handleUnsafeBufferUsage<UnsafeBufferUsageAttr>(S, D, AL);
9924 break;
9925
9926 case ParsedAttr::AT_UseHandle:
9927 handleHandleAttr<UseHandleAttr>(S, D, AL);
9928 break;
9929
9930 case ParsedAttr::AT_EnforceTCB:
9931 handleEnforceTCBAttr<EnforceTCBAttr, EnforceTCBLeafAttr>(S, D, AL);
9932 break;
9933
9934 case ParsedAttr::AT_EnforceTCBLeaf:
9935 handleEnforceTCBAttr<EnforceTCBLeafAttr, EnforceTCBAttr>(S, D, AL);
9936 break;
9937
9938 case ParsedAttr::AT_BuiltinAlias:
9939 handleBuiltinAliasAttr(S, D, AL);
9940 break;
9941
9942 case ParsedAttr::AT_PreferredType:
9943 handlePreferredTypeAttr(S, D, AL);
9944 break;
9945
9946 case ParsedAttr::AT_UsingIfExists:
9947 handleSimpleAttribute<UsingIfExistsAttr>(S, D, AL);
9948 break;
9949
9950 case ParsedAttr::AT_TypeNullable:
9951 handleNullableTypeAttr(S, D, AL);
9952 break;
9953 }
9954}
9955
9956/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
9957/// attribute list to the specified decl, ignoring any type attributes.
9958void Sema::ProcessDeclAttributeList(
9959 Scope *S, Decl *D, const ParsedAttributesView &AttrList,
9960 const ProcessDeclAttributeOptions &Options) {
9961 if (AttrList.empty())
9962 return;
9963
9964 for (const ParsedAttr &AL : AttrList)
9965 ProcessDeclAttribute(S&: *this, scope: S, D, AL, Options);
9966
9967 // FIXME: We should be able to handle these cases in TableGen.
9968 // GCC accepts
9969 // static int a9 __attribute__((weakref));
9970 // but that looks really pointless. We reject it.
9971 if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
9972 Diag(AttrList.begin()->getLoc(), diag::err_attribute_weakref_without_alias)
9973 << cast<NamedDecl>(D);
9974 D->dropAttr<WeakRefAttr>();
9975 return;
9976 }
9977
9978 // FIXME: We should be able to handle this in TableGen as well. It would be
9979 // good to have a way to specify "these attributes must appear as a group",
9980 // for these. Additionally, it would be good to have a way to specify "these
9981 // attribute must never appear as a group" for attributes like cold and hot.
9982 if (!D->hasAttr<OpenCLKernelAttr>()) {
9983 // These attributes cannot be applied to a non-kernel function.
9984 if (const auto *A = D->getAttr<ReqdWorkGroupSizeAttr>()) {
9985 // FIXME: This emits a different error message than
9986 // diag::err_attribute_wrong_decl_type + ExpectedKernelFunction.
9987 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
9988 D->setInvalidDecl();
9989 } else if (const auto *A = D->getAttr<WorkGroupSizeHintAttr>()) {
9990 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
9991 D->setInvalidDecl();
9992 } else if (const auto *A = D->getAttr<VecTypeHintAttr>()) {
9993 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
9994 D->setInvalidDecl();
9995 } else if (const auto *A = D->getAttr<OpenCLIntelReqdSubGroupSizeAttr>()) {
9996 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
9997 D->setInvalidDecl();
9998 } else if (!D->hasAttr<CUDAGlobalAttr>()) {
9999 if (const auto *A = D->getAttr<AMDGPUFlatWorkGroupSizeAttr>()) {
10000 Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
10001 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
10002 D->setInvalidDecl();
10003 } else if (const auto *A = D->getAttr<AMDGPUWavesPerEUAttr>()) {
10004 Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
10005 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
10006 D->setInvalidDecl();
10007 } else if (const auto *A = D->getAttr<AMDGPUNumSGPRAttr>()) {
10008 Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
10009 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
10010 D->setInvalidDecl();
10011 } else if (const auto *A = D->getAttr<AMDGPUNumVGPRAttr>()) {
10012 Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
10013 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
10014 D->setInvalidDecl();
10015 }
10016 }
10017 }
10018
10019 // Do this check after processing D's attributes because the attribute
10020 // objc_method_family can change whether the given method is in the init
10021 // family, and it can be applied after objc_designated_initializer. This is a
10022 // bit of a hack, but we need it to be compatible with versions of clang that
10023 // processed the attribute list in the wrong order.
10024 if (D->hasAttr<ObjCDesignatedInitializerAttr>() &&
10025 cast<ObjCMethodDecl>(D)->getMethodFamily() != OMF_init) {
10026 Diag(D->getLocation(), diag::err_designated_init_attr_non_init);
10027 D->dropAttr<ObjCDesignatedInitializerAttr>();
10028 }
10029}
10030
10031// Helper for delayed processing TransparentUnion or BPFPreserveAccessIndexAttr
10032// attribute.
10033void Sema::ProcessDeclAttributeDelayed(Decl *D,
10034 const ParsedAttributesView &AttrList) {
10035 for (const ParsedAttr &AL : AttrList)
10036 if (AL.getKind() == ParsedAttr::AT_TransparentUnion) {
10037 handleTransparentUnionAttr(S&: *this, D, AL);
10038 break;
10039 }
10040
10041 // For BPFPreserveAccessIndexAttr, we want to populate the attributes
10042 // to fields and inner records as well.
10043 if (D && D->hasAttr<BPFPreserveAccessIndexAttr>())
10044 handleBPFPreserveAIRecord(S&: *this, RD: cast<RecordDecl>(Val: D));
10045}
10046
10047// Annotation attributes are the only attributes allowed after an access
10048// specifier.
10049bool Sema::ProcessAccessDeclAttributeList(
10050 AccessSpecDecl *ASDecl, const ParsedAttributesView &AttrList) {
10051 for (const ParsedAttr &AL : AttrList) {
10052 if (AL.getKind() == ParsedAttr::AT_Annotate) {
10053 ProcessDeclAttribute(*this, nullptr, ASDecl, AL,
10054 ProcessDeclAttributeOptions());
10055 } else {
10056 Diag(AL.getLoc(), diag::err_only_annotate_after_access_spec);
10057 return true;
10058 }
10059 }
10060 return false;
10061}
10062
10063/// checkUnusedDeclAttributes - Check a list of attributes to see if it
10064/// contains any decl attributes that we should warn about.
10065static void checkUnusedDeclAttributes(Sema &S, const ParsedAttributesView &A) {
10066 for (const ParsedAttr &AL : A) {
10067 // Only warn if the attribute is an unignored, non-type attribute.
10068 if (AL.isUsedAsTypeAttr() || AL.isInvalid())
10069 continue;
10070 if (AL.getKind() == ParsedAttr::IgnoredAttribute)
10071 continue;
10072
10073 if (AL.getKind() == ParsedAttr::UnknownAttribute) {
10074 S.Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)
10075 << AL << AL.getRange();
10076 } else {
10077 S.Diag(AL.getLoc(), diag::warn_attribute_not_on_decl) << AL
10078 << AL.getRange();
10079 }
10080 }
10081}
10082
10083/// checkUnusedDeclAttributes - Given a declarator which is not being
10084/// used to build a declaration, complain about any decl attributes
10085/// which might be lying around on it.
10086void Sema::checkUnusedDeclAttributes(Declarator &D) {
10087 ::checkUnusedDeclAttributes(S&: *this, A: D.getDeclarationAttributes());
10088 ::checkUnusedDeclAttributes(S&: *this, A: D.getDeclSpec().getAttributes());
10089 ::checkUnusedDeclAttributes(S&: *this, A: D.getAttributes());
10090 for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
10091 ::checkUnusedDeclAttributes(S&: *this, A: D.getTypeObject(i).getAttrs());
10092}
10093
10094/// DeclClonePragmaWeak - clone existing decl (maybe definition),
10095/// \#pragma weak needs a non-definition decl and source may not have one.
10096NamedDecl *Sema::DeclClonePragmaWeak(NamedDecl *ND, const IdentifierInfo *II,
10097 SourceLocation Loc) {
10098 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
10099 NamedDecl *NewD = nullptr;
10100 if (auto *FD = dyn_cast<FunctionDecl>(Val: ND)) {
10101 FunctionDecl *NewFD;
10102 // FIXME: Missing call to CheckFunctionDeclaration().
10103 // FIXME: Mangling?
10104 // FIXME: Is the qualifier info correct?
10105 // FIXME: Is the DeclContext correct?
10106 NewFD = FunctionDecl::Create(
10107 FD->getASTContext(), FD->getDeclContext(), Loc, Loc,
10108 DeclarationName(II), FD->getType(), FD->getTypeSourceInfo(), SC_None,
10109 getCurFPFeatures().isFPConstrained(), false /*isInlineSpecified*/,
10110 FD->hasPrototype(), ConstexprSpecKind::Unspecified,
10111 FD->getTrailingRequiresClause());
10112 NewD = NewFD;
10113
10114 if (FD->getQualifier())
10115 NewFD->setQualifierInfo(FD->getQualifierLoc());
10116
10117 // Fake up parameter variables; they are declared as if this were
10118 // a typedef.
10119 QualType FDTy = FD->getType();
10120 if (const auto *FT = FDTy->getAs<FunctionProtoType>()) {
10121 SmallVector<ParmVarDecl*, 16> Params;
10122 for (const auto &AI : FT->param_types()) {
10123 ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, AI);
10124 Param->setScopeInfo(0, Params.size());
10125 Params.push_back(Param);
10126 }
10127 NewFD->setParams(Params);
10128 }
10129 } else if (auto *VD = dyn_cast<VarDecl>(Val: ND)) {
10130 NewD = VarDecl::Create(C&: VD->getASTContext(), DC: VD->getDeclContext(),
10131 StartLoc: VD->getInnerLocStart(), IdLoc: VD->getLocation(), Id: II,
10132 T: VD->getType(), TInfo: VD->getTypeSourceInfo(),
10133 S: VD->getStorageClass());
10134 if (VD->getQualifier())
10135 cast<VarDecl>(Val: NewD)->setQualifierInfo(VD->getQualifierLoc());
10136 }
10137 return NewD;
10138}
10139
10140/// DeclApplyPragmaWeak - A declaration (maybe definition) needs \#pragma weak
10141/// applied to it, possibly with an alias.
10142void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, const WeakInfo &W) {
10143 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
10144 IdentifierInfo *NDId = ND->getIdentifier();
10145 NamedDecl *NewD = DeclClonePragmaWeak(ND, II: W.getAlias(), Loc: W.getLocation());
10146 NewD->addAttr(
10147 AliasAttr::CreateImplicit(Context, NDId->getName(), W.getLocation()));
10148 NewD->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));
10149 WeakTopLevelDecl.push_back(NewD);
10150 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
10151 // to insert Decl at TU scope, sorry.
10152 DeclContext *SavedContext = CurContext;
10153 CurContext = Context.getTranslationUnitDecl();
10154 NewD->setDeclContext(CurContext);
10155 NewD->setLexicalDeclContext(CurContext);
10156 PushOnScopeChains(D: NewD, S);
10157 CurContext = SavedContext;
10158 } else { // just add weak to existing
10159 ND->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));
10160 }
10161}
10162
10163void Sema::ProcessPragmaWeak(Scope *S, Decl *D) {
10164 // It's valid to "forward-declare" #pragma weak, in which case we
10165 // have to do this.
10166 LoadExternalWeakUndeclaredIdentifiers();
10167 if (WeakUndeclaredIdentifiers.empty())
10168 return;
10169 NamedDecl *ND = nullptr;
10170 if (auto *VD = dyn_cast<VarDecl>(Val: D))
10171 if (VD->isExternC())
10172 ND = VD;
10173 if (auto *FD = dyn_cast<FunctionDecl>(Val: D))
10174 if (FD->isExternC())
10175 ND = FD;
10176 if (!ND)
10177 return;
10178 if (IdentifierInfo *Id = ND->getIdentifier()) {
10179 auto I = WeakUndeclaredIdentifiers.find(Key: Id);
10180 if (I != WeakUndeclaredIdentifiers.end()) {
10181 auto &WeakInfos = I->second;
10182 for (const auto &W : WeakInfos)
10183 DeclApplyPragmaWeak(S, ND, W);
10184 std::remove_reference_t<decltype(WeakInfos)> EmptyWeakInfos;
10185 WeakInfos.swap(RHS&: EmptyWeakInfos);
10186 }
10187 }
10188}
10189
10190/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
10191/// it, apply them to D. This is a bit tricky because PD can have attributes
10192/// specified in many different places, and we need to find and apply them all.
10193void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
10194 // Ordering of attributes can be important, so we take care to process
10195 // attributes in the order in which they appeared in the source code.
10196
10197 // First, process attributes that appeared on the declaration itself (but
10198 // only if they don't have the legacy behavior of "sliding" to the DeclSepc).
10199 ParsedAttributesView NonSlidingAttrs;
10200 for (ParsedAttr &AL : PD.getDeclarationAttributes()) {
10201 if (AL.slidesFromDeclToDeclSpecLegacyBehavior()) {
10202 // Skip processing the attribute, but do check if it appertains to the
10203 // declaration. This is needed for the `MatrixType` attribute, which,
10204 // despite being a type attribute, defines a `SubjectList` that only
10205 // allows it to be used on typedef declarations.
10206 AL.diagnoseAppertainsTo(S&: *this, D);
10207 } else {
10208 NonSlidingAttrs.addAtEnd(newAttr: &AL);
10209 }
10210 }
10211 ProcessDeclAttributeList(S, D, AttrList: NonSlidingAttrs);
10212
10213 // Apply decl attributes from the DeclSpec if present.
10214 if (!PD.getDeclSpec().getAttributes().empty()) {
10215 ProcessDeclAttributeList(S, D, AttrList: PD.getDeclSpec().getAttributes(),
10216 Options: ProcessDeclAttributeOptions()
10217 .WithIncludeCXX11Attributes(Val: false)
10218 .WithIgnoreTypeAttributes(Val: true));
10219 }
10220
10221 // Walk the declarator structure, applying decl attributes that were in a type
10222 // position to the decl itself. This handles cases like:
10223 // int *__attr__(x)** D;
10224 // when X is a decl attribute.
10225 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) {
10226 ProcessDeclAttributeList(S, D, AttrList: PD.getTypeObject(i).getAttrs(),
10227 Options: ProcessDeclAttributeOptions()
10228 .WithIncludeCXX11Attributes(Val: false)
10229 .WithIgnoreTypeAttributes(Val: true));
10230 }
10231
10232 // Finally, apply any attributes on the decl itself.
10233 ProcessDeclAttributeList(S, D, AttrList: PD.getAttributes());
10234
10235 // Apply additional attributes specified by '#pragma clang attribute'.
10236 AddPragmaAttributes(S, D);
10237
10238 // Look for API notes that map to attributes.
10239 ProcessAPINotes(D);
10240}
10241
10242/// Is the given declaration allowed to use a forbidden type?
10243/// If so, it'll still be annotated with an attribute that makes it
10244/// illegal to actually use.
10245static bool isForbiddenTypeAllowed(Sema &S, Decl *D,
10246 const DelayedDiagnostic &diag,
10247 UnavailableAttr::ImplicitReason &reason) {
10248 // Private ivars are always okay. Unfortunately, people don't
10249 // always properly make their ivars private, even in system headers.
10250 // Plus we need to make fields okay, too.
10251 if (!isa<FieldDecl>(Val: D) && !isa<ObjCPropertyDecl>(Val: D) &&
10252 !isa<FunctionDecl>(Val: D))
10253 return false;
10254
10255 // Silently accept unsupported uses of __weak in both user and system
10256 // declarations when it's been disabled, for ease of integration with
10257 // -fno-objc-arc files. We do have to take some care against attempts
10258 // to define such things; for now, we've only done that for ivars
10259 // and properties.
10260 if ((isa<ObjCIvarDecl>(Val: D) || isa<ObjCPropertyDecl>(Val: D))) {
10261 if (diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_disabled ||
10262 diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_no_runtime) {
10263 reason = UnavailableAttr::IR_ForbiddenWeak;
10264 return true;
10265 }
10266 }
10267
10268 // Allow all sorts of things in system headers.
10269 if (S.Context.getSourceManager().isInSystemHeader(Loc: D->getLocation())) {
10270 // Currently, all the failures dealt with this way are due to ARC
10271 // restrictions.
10272 reason = UnavailableAttr::IR_ARCForbiddenType;
10273 return true;
10274 }
10275
10276 return false;
10277}
10278
10279/// Handle a delayed forbidden-type diagnostic.
10280static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &DD,
10281 Decl *D) {
10282 auto Reason = UnavailableAttr::IR_None;
10283 if (D && isForbiddenTypeAllowed(S, D, DD, Reason)) {
10284 assert(Reason && "didn't set reason?");
10285 D->addAttr(UnavailableAttr::CreateImplicit(S.Context, "", Reason, DD.Loc));
10286 return;
10287 }
10288 if (S.getLangOpts().ObjCAutoRefCount)
10289 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
10290 // FIXME: we may want to suppress diagnostics for all
10291 // kind of forbidden type messages on unavailable functions.
10292 if (FD->hasAttr<UnavailableAttr>() &&
10293 DD.getForbiddenTypeDiagnostic() ==
10294 diag::err_arc_array_param_no_ownership) {
10295 DD.Triggered = true;
10296 return;
10297 }
10298 }
10299
10300 S.Diag(DD.Loc, DD.getForbiddenTypeDiagnostic())
10301 << DD.getForbiddenTypeOperand() << DD.getForbiddenTypeArgument();
10302 DD.Triggered = true;
10303}
10304
10305
10306void Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) {
10307 assert(DelayedDiagnostics.getCurrentPool());
10308 DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool();
10309 DelayedDiagnostics.popWithoutEmitting(state);
10310
10311 // When delaying diagnostics to run in the context of a parsed
10312 // declaration, we only want to actually emit anything if parsing
10313 // succeeds.
10314 if (!decl) return;
10315
10316 // We emit all the active diagnostics in this pool or any of its
10317 // parents. In general, we'll get one pool for the decl spec
10318 // and a child pool for each declarator; in a decl group like:
10319 // deprecated_typedef foo, *bar, baz();
10320 // only the declarator pops will be passed decls. This is correct;
10321 // we really do need to consider delayed diagnostics from the decl spec
10322 // for each of the different declarations.
10323 const DelayedDiagnosticPool *pool = &poppedPool;
10324 do {
10325 bool AnyAccessFailures = false;
10326 for (DelayedDiagnosticPool::pool_iterator
10327 i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) {
10328 // This const_cast is a bit lame. Really, Triggered should be mutable.
10329 DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i);
10330 if (diag.Triggered)
10331 continue;
10332
10333 switch (diag.Kind) {
10334 case DelayedDiagnostic::Availability:
10335 // Don't bother giving deprecation/unavailable diagnostics if
10336 // the decl is invalid.
10337 if (!decl->isInvalidDecl())
10338 handleDelayedAvailabilityCheck(DD&: diag, Ctx: decl);
10339 break;
10340
10341 case DelayedDiagnostic::Access:
10342 // Only produce one access control diagnostic for a structured binding
10343 // declaration: we don't need to tell the user that all the fields are
10344 // inaccessible one at a time.
10345 if (AnyAccessFailures && isa<DecompositionDecl>(Val: decl))
10346 continue;
10347 HandleDelayedAccessCheck(DD&: diag, Ctx: decl);
10348 if (diag.Triggered)
10349 AnyAccessFailures = true;
10350 break;
10351
10352 case DelayedDiagnostic::ForbiddenType:
10353 handleDelayedForbiddenType(S&: *this, DD&: diag, D: decl);
10354 break;
10355 }
10356 }
10357 } while ((pool = pool->getParent()));
10358}
10359
10360/// Given a set of delayed diagnostics, re-emit them as if they had
10361/// been delayed in the current context instead of in the given pool.
10362/// Essentially, this just moves them to the current pool.
10363void Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) {
10364 DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool();
10365 assert(curPool && "re-emitting in undelayed context not supported");
10366 curPool->steal(pool);
10367}
10368

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