clang 19.0.0git
SemaDeclAttr.cpp
Go to the documentation of this file.
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
17#include "clang/AST/DeclCXX.h"
18#include "clang/AST/DeclObjC.h"
20#include "clang/AST/Expr.h"
21#include "clang/AST/ExprCXX.h"
22#include "clang/AST/Mangle.h"
24#include "clang/AST/Type.h"
26#include "clang/Basic/Cuda.h"
35#include "clang/Sema/DeclSpec.h"
38#include "clang/Sema/Lookup.h"
40#include "clang/Sema/Scope.h"
42#include "clang/Sema/SemaCUDA.h"
43#include "clang/Sema/SemaHLSL.h"
45#include "clang/Sema/SemaObjC.h"
46#include "llvm/ADT/STLExtras.h"
47#include "llvm/ADT/STLForwardCompat.h"
48#include "llvm/ADT/StringExtras.h"
49#include "llvm/Demangle/Demangle.h"
50#include "llvm/IR/Assumptions.h"
51#include "llvm/MC/MCSectionMachO.h"
52#include "llvm/Support/Error.h"
53#include "llvm/Support/MathExtras.h"
54#include "llvm/Support/raw_ostream.h"
55#include <optional>
56
57using namespace clang;
58using namespace sema;
59
61 enum LANG {
64 ObjC
65 };
66} // end namespace AttributeLangSupport
67
68//===----------------------------------------------------------------------===//
69// Helper functions
70//===----------------------------------------------------------------------===//
71
72/// isFunctionOrMethod - Return true if the given decl has function
73/// type (function or function-typed variable) or an Objective-C
74/// method.
75static bool isFunctionOrMethod(const Decl *D) {
76 return (D->getFunctionType() != nullptr) || isa<ObjCMethodDecl>(D);
77}
78
79/// Return true if the given decl has function type (function or
80/// function-typed variable) or an Objective-C method or a block.
81static bool isFunctionOrMethodOrBlock(const Decl *D) {
82 return isFunctionOrMethod(D) || isa<BlockDecl>(D);
83}
84
85/// Return true if the given decl has a declarator that should have
86/// been processed by Sema::GetTypeForDeclarator.
87static bool hasDeclarator(const Decl *D) {
88 // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
89 return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) ||
90 isa<ObjCPropertyDecl>(D);
91}
92
93/// hasFunctionProto - Return true if the given decl has a argument
94/// information. This decl should have already passed
95/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
96static bool hasFunctionProto(const Decl *D) {
97 if (const FunctionType *FnTy = D->getFunctionType())
98 return isa<FunctionProtoType>(FnTy);
99 return isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D);
100}
101
102/// getFunctionOrMethodNumParams - Return number of function or method
103/// parameters. It is an error to call this on a K&R function (use
104/// hasFunctionProto first).
105static unsigned getFunctionOrMethodNumParams(const Decl *D) {
106 if (const FunctionType *FnTy = D->getFunctionType())
107 return cast<FunctionProtoType>(FnTy)->getNumParams();
108 if (const auto *BD = dyn_cast<BlockDecl>(D))
109 return BD->getNumParams();
110 return cast<ObjCMethodDecl>(D)->param_size();
111}
112
114 unsigned Idx) {
115 if (const auto *FD = dyn_cast<FunctionDecl>(D))
116 return FD->getParamDecl(Idx);
117 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
118 return MD->getParamDecl(Idx);
119 if (const auto *BD = dyn_cast<BlockDecl>(D))
120 return BD->getParamDecl(Idx);
121 return nullptr;
122}
123
124static QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx) {
125 if (const FunctionType *FnTy = D->getFunctionType())
126 return cast<FunctionProtoType>(FnTy)->getParamType(Idx);
127 if (const auto *BD = dyn_cast<BlockDecl>(D))
128 return BD->getParamDecl(Idx)->getType();
129
130 return cast<ObjCMethodDecl>(D)->parameters()[Idx]->getType();
131}
132
133static SourceRange getFunctionOrMethodParamRange(const Decl *D, unsigned Idx) {
134 if (auto *PVD = getFunctionOrMethodParam(D, Idx))
135 return PVD->getSourceRange();
136 return SourceRange();
137}
138
140 if (const FunctionType *FnTy = D->getFunctionType())
141 return FnTy->getReturnType();
142 return cast<ObjCMethodDecl>(D)->getReturnType();
143}
144
146 if (const auto *FD = dyn_cast<FunctionDecl>(D))
147 return FD->getReturnTypeSourceRange();
148 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
149 return MD->getReturnTypeSourceRange();
150 return SourceRange();
151}
152
153static bool isFunctionOrMethodVariadic(const Decl *D) {
154 if (const FunctionType *FnTy = D->getFunctionType())
155 return cast<FunctionProtoType>(FnTy)->isVariadic();
156 if (const auto *BD = dyn_cast<BlockDecl>(D))
157 return BD->isVariadic();
158 return cast<ObjCMethodDecl>(D)->isVariadic();
159}
160
161static bool isInstanceMethod(const Decl *D) {
162 if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(D))
163 return MethodDecl->isInstance();
164 return false;
165}
166
167static inline bool isNSStringType(QualType T, ASTContext &Ctx,
168 bool AllowNSAttributedString = false) {
169 const auto *PT = T->getAs<ObjCObjectPointerType>();
170 if (!PT)
171 return false;
172
173 ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
174 if (!Cls)
175 return false;
176
177 IdentifierInfo* ClsName = Cls->getIdentifier();
178
179 if (AllowNSAttributedString &&
180 ClsName == &Ctx.Idents.get("NSAttributedString"))
181 return true;
182 // FIXME: Should we walk the chain of classes?
183 return ClsName == &Ctx.Idents.get("NSString") ||
184 ClsName == &Ctx.Idents.get("NSMutableString");
185}
186
187static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
188 const auto *PT = T->getAs<PointerType>();
189 if (!PT)
190 return false;
191
192 const auto *RT = PT->getPointeeType()->getAs<RecordType>();
193 if (!RT)
194 return false;
195
196 const RecordDecl *RD = RT->getDecl();
197 if (RD->getTagKind() != TagTypeKind::Struct)
198 return false;
199
200 return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
201}
202
203static unsigned getNumAttributeArgs(const ParsedAttr &AL) {
204 // FIXME: Include the type in the argument list.
205 return AL.getNumArgs() + AL.hasParsedType();
206}
207
208/// A helper function to provide Attribute Location for the Attr types
209/// AND the ParsedAttr.
210template <typename AttrInfo>
211static std::enable_if_t<std::is_base_of_v<Attr, AttrInfo>, SourceLocation>
212getAttrLoc(const AttrInfo &AL) {
213 return AL.getLocation();
214}
215static SourceLocation getAttrLoc(const ParsedAttr &AL) { return AL.getLoc(); }
216
217/// If Expr is a valid integer constant, get the value of the integer
218/// expression and return success or failure. May output an error.
219///
220/// Negative argument is implicitly converted to unsigned, unless
221/// \p StrictlyUnsigned is true.
222template <typename AttrInfo>
223static bool checkUInt32Argument(Sema &S, const AttrInfo &AI, const Expr *Expr,
224 uint32_t &Val, unsigned Idx = UINT_MAX,
225 bool StrictlyUnsigned = false) {
226 std::optional<llvm::APSInt> I = llvm::APSInt(32);
227 if (Expr->isTypeDependent() ||
229 if (Idx != UINT_MAX)
230 S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
231 << &AI << Idx << AANT_ArgumentIntegerConstant
232 << Expr->getSourceRange();
233 else
234 S.Diag(getAttrLoc(AI), diag::err_attribute_argument_type)
236 return false;
237 }
238
239 if (!I->isIntN(32)) {
240 S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
241 << toString(*I, 10, false) << 32 << /* Unsigned */ 1;
242 return false;
243 }
244
245 if (StrictlyUnsigned && I->isSigned() && I->isNegative()) {
246 S.Diag(getAttrLoc(AI), diag::err_attribute_requires_positive_integer)
247 << &AI << /*non-negative*/ 1;
248 return false;
249 }
250
251 Val = (uint32_t)I->getZExtValue();
252 return true;
253}
254
255/// Wrapper around checkUInt32Argument, with an extra check to be sure
256/// that the result will fit into a regular (signed) int. All args have the same
257/// purpose as they do in checkUInt32Argument.
258template <typename AttrInfo>
259static bool checkPositiveIntArgument(Sema &S, const AttrInfo &AI, const Expr *Expr,
260 int &Val, unsigned Idx = UINT_MAX) {
261 uint32_t UVal;
262 if (!checkUInt32Argument(S, AI, Expr, UVal, Idx))
263 return false;
264
265 if (UVal > (uint32_t)std::numeric_limits<int>::max()) {
266 llvm::APSInt I(32); // for toString
267 I = UVal;
268 S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
269 << toString(I, 10, false) << 32 << /* Unsigned */ 0;
270 return false;
271 }
272
273 Val = UVal;
274 return true;
275}
276
277/// Diagnose mutually exclusive attributes when present on a given
278/// declaration. Returns true if diagnosed.
279template <typename AttrTy>
280static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
281 if (const auto *A = D->getAttr<AttrTy>()) {
282 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
283 << AL << A
284 << (AL.isRegularKeywordAttribute() || A->isRegularKeywordAttribute());
285 S.Diag(A->getLocation(), diag::note_conflicting_attribute);
286 return true;
287 }
288 return false;
289}
290
291template <typename AttrTy>
292static bool checkAttrMutualExclusion(Sema &S, Decl *D, const Attr &AL) {
293 if (const auto *A = D->getAttr<AttrTy>()) {
294 S.Diag(AL.getLocation(), diag::err_attributes_are_not_compatible)
295 << &AL << A
296 << (AL.isRegularKeywordAttribute() || A->isRegularKeywordAttribute());
297 S.Diag(A->getLocation(), diag::note_conflicting_attribute);
298 return true;
299 }
300 return false;
301}
302
303/// Check if IdxExpr is a valid parameter index for a function or
304/// instance method D. May output an error.
305///
306/// \returns true if IdxExpr is a valid index.
307template <typename AttrInfo>
309 Sema &S, const Decl *D, const AttrInfo &AI, unsigned AttrArgNum,
310 const Expr *IdxExpr, ParamIdx &Idx, bool CanIndexImplicitThis = false) {
311 assert(isFunctionOrMethodOrBlock(D));
312
313 // In C++ the implicit 'this' function parameter also counts.
314 // Parameters are counted from one.
315 bool HP = hasFunctionProto(D);
316 bool HasImplicitThisParam = isInstanceMethod(D);
317 bool IV = HP && isFunctionOrMethodVariadic(D);
318 unsigned NumParams =
319 (HP ? getFunctionOrMethodNumParams(D) : 0) + HasImplicitThisParam;
320
321 std::optional<llvm::APSInt> IdxInt;
322 if (IdxExpr->isTypeDependent() ||
323 !(IdxInt = IdxExpr->getIntegerConstantExpr(S.Context))) {
324 S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
325 << &AI << AttrArgNum << AANT_ArgumentIntegerConstant
326 << IdxExpr->getSourceRange();
327 return false;
328 }
329
330 unsigned IdxSource = IdxInt->getLimitedValue(UINT_MAX);
331 if (IdxSource < 1 || (!IV && IdxSource > NumParams)) {
332 S.Diag(getAttrLoc(AI), diag::err_attribute_argument_out_of_bounds)
333 << &AI << AttrArgNum << IdxExpr->getSourceRange();
334 return false;
335 }
336 if (HasImplicitThisParam && !CanIndexImplicitThis) {
337 if (IdxSource == 1) {
338 S.Diag(getAttrLoc(AI), diag::err_attribute_invalid_implicit_this_argument)
339 << &AI << IdxExpr->getSourceRange();
340 return false;
341 }
342 }
343
344 Idx = ParamIdx(IdxSource, D);
345 return true;
346}
347
348/// Check if the argument \p E is a ASCII string literal. If not emit an error
349/// and return false, otherwise set \p Str to the value of the string literal
350/// and return true.
352 const Expr *E, StringRef &Str,
353 SourceLocation *ArgLocation) {
354 const auto *Literal = dyn_cast<StringLiteral>(E->IgnoreParenCasts());
355 if (ArgLocation)
356 *ArgLocation = E->getBeginLoc();
357
358 if (!Literal || (!Literal->isUnevaluated() && !Literal->isOrdinary())) {
359 Diag(E->getBeginLoc(), diag::err_attribute_argument_type)
360 << CI << AANT_ArgumentString;
361 return false;
362 }
363
364 Str = Literal->getString();
365 return true;
366}
367
368/// Check if the argument \p ArgNum of \p Attr is a ASCII string literal.
369/// If not emit an error and return false. If the argument is an identifier it
370/// will emit an error with a fixit hint and treat it as if it was a string
371/// literal.
372bool Sema::checkStringLiteralArgumentAttr(const ParsedAttr &AL, unsigned ArgNum,
373 StringRef &Str,
374 SourceLocation *ArgLocation) {
375 // Look for identifiers. If we have one emit a hint to fix it to a literal.
376 if (AL.isArgIdent(ArgNum)) {
377 IdentifierLoc *Loc = AL.getArgAsIdent(ArgNum);
378 Diag(Loc->Loc, diag::err_attribute_argument_type)
379 << AL << AANT_ArgumentString
380 << FixItHint::CreateInsertion(Loc->Loc, "\"")
382 Str = Loc->Ident->getName();
383 if (ArgLocation)
384 *ArgLocation = Loc->Loc;
385 return true;
386 }
387
388 // Now check for an actual string literal.
389 Expr *ArgExpr = AL.getArgAsExpr(ArgNum);
390 const auto *Literal = dyn_cast<StringLiteral>(ArgExpr->IgnoreParenCasts());
391 if (ArgLocation)
392 *ArgLocation = ArgExpr->getBeginLoc();
393
394 if (!Literal || (!Literal->isUnevaluated() && !Literal->isOrdinary())) {
395 Diag(ArgExpr->getBeginLoc(), diag::err_attribute_argument_type)
396 << AL << AANT_ArgumentString;
397 return false;
398 }
399 Str = Literal->getString();
400 return checkStringLiteralArgumentAttr(AL, ArgExpr, Str, ArgLocation);
401}
402
403/// Applies the given attribute to the Decl without performing any
404/// additional semantic checking.
405template <typename AttrType>
406static void handleSimpleAttribute(Sema &S, Decl *D,
407 const AttributeCommonInfo &CI) {
408 D->addAttr(::new (S.Context) AttrType(S.Context, CI));
409}
410
411template <typename... DiagnosticArgs>
412static const Sema::SemaDiagnosticBuilder&
414 return Bldr;
415}
416
417template <typename T, typename... DiagnosticArgs>
418static const Sema::SemaDiagnosticBuilder&
420 DiagnosticArgs &&... ExtraArgs) {
421 return appendDiagnostics(Bldr << std::forward<T>(ExtraArg),
422 std::forward<DiagnosticArgs>(ExtraArgs)...);
423}
424
425/// Add an attribute @c AttrType to declaration @c D, provided that
426/// @c PassesCheck is true.
427/// Otherwise, emit diagnostic @c DiagID, passing in all parameters
428/// specified in @c ExtraArgs.
429template <typename AttrType, typename... DiagnosticArgs>
431 const AttributeCommonInfo &CI,
432 bool PassesCheck, unsigned DiagID,
433 DiagnosticArgs &&... ExtraArgs) {
434 if (!PassesCheck) {
435 Sema::SemaDiagnosticBuilder DB = S.Diag(D->getBeginLoc(), DiagID);
436 appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...);
437 return;
438 }
439 handleSimpleAttribute<AttrType>(S, D, CI);
440}
441
442/// Check if the passed-in expression is of type int or bool.
443static bool isIntOrBool(Expr *Exp) {
444 QualType QT = Exp->getType();
445 return QT->isBooleanType() || QT->isIntegerType();
446}
447
448
449// Check to see if the type is a smart pointer of some kind. We assume
450// it's a smart pointer if it defines both operator-> and operator*.
452 auto IsOverloadedOperatorPresent = [&S](const RecordDecl *Record,
456 return !Result.empty();
457 };
458
459 const RecordDecl *Record = RT->getDecl();
460 bool foundStarOperator = IsOverloadedOperatorPresent(Record, OO_Star);
461 bool foundArrowOperator = IsOverloadedOperatorPresent(Record, OO_Arrow);
462 if (foundStarOperator && foundArrowOperator)
463 return true;
464
465 const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(Record);
466 if (!CXXRecord)
467 return false;
468
469 for (const auto &BaseSpecifier : CXXRecord->bases()) {
470 if (!foundStarOperator)
471 foundStarOperator = IsOverloadedOperatorPresent(
472 BaseSpecifier.getType()->getAsRecordDecl(), OO_Star);
473 if (!foundArrowOperator)
474 foundArrowOperator = IsOverloadedOperatorPresent(
475 BaseSpecifier.getType()->getAsRecordDecl(), OO_Arrow);
476 }
477
478 if (foundStarOperator && foundArrowOperator)
479 return true;
480
481 return false;
482}
483
484/// Check if passed in Decl is a pointer type.
485/// Note that this function may produce an error message.
486/// \return true if the Decl is a pointer type; false otherwise
487static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
488 const ParsedAttr &AL) {
489 const auto *VD = cast<ValueDecl>(D);
490 QualType QT = VD->getType();
491 if (QT->isAnyPointerType())
492 return true;
493
494 if (const auto *RT = QT->getAs<RecordType>()) {
495 // If it's an incomplete type, it could be a smart pointer; skip it.
496 // (We don't want to force template instantiation if we can avoid it,
497 // since that would alter the order in which templates are instantiated.)
498 if (RT->isIncompleteType())
499 return true;
500
502 return true;
503 }
504
505 S.Diag(AL.getLoc(), diag::warn_thread_attribute_decl_not_pointer) << AL << QT;
506 return false;
507}
508
509/// Checks that the passed in QualType either is of RecordType or points
510/// to RecordType. Returns the relevant RecordType, null if it does not exit.
512 if (const auto *RT = QT->getAs<RecordType>())
513 return RT;
514
515 // Now check if we point to record type.
516 if (const auto *PT = QT->getAs<PointerType>())
517 return PT->getPointeeType()->getAs<RecordType>();
518
519 return nullptr;
520}
521
522template <typename AttrType>
523static bool checkRecordDeclForAttr(const RecordDecl *RD) {
524 // Check if the record itself has the attribute.
525 if (RD->hasAttr<AttrType>())
526 return true;
527
528 // Else check if any base classes have the attribute.
529 if (const auto *CRD = dyn_cast<CXXRecordDecl>(RD)) {
530 if (!CRD->forallBases([](const CXXRecordDecl *Base) {
531 return !Base->hasAttr<AttrType>();
532 }))
533 return true;
534 }
535 return false;
536}
537
539 const RecordType *RT = getRecordType(Ty);
540
541 if (!RT)
542 return false;
543
544 // Don't check for the capability if the class hasn't been defined yet.
545 if (RT->isIncompleteType())
546 return true;
547
548 // Allow smart pointers to be used as capability objects.
549 // FIXME -- Check the type that the smart pointer points to.
551 return true;
552
553 return checkRecordDeclForAttr<CapabilityAttr>(RT->getDecl());
554}
555
557 const auto *TD = Ty->getAs<TypedefType>();
558 if (!TD)
559 return false;
560
561 TypedefNameDecl *TN = TD->getDecl();
562 if (!TN)
563 return false;
564
565 return TN->hasAttr<CapabilityAttr>();
566}
567
568static bool typeHasCapability(Sema &S, QualType Ty) {
570 return true;
571
573 return true;
574
575 return false;
576}
577
578static bool isCapabilityExpr(Sema &S, const Expr *Ex) {
579 // Capability expressions are simple expressions involving the boolean logic
580 // operators &&, || or !, a simple DeclRefExpr, CastExpr or a ParenExpr. Once
581 // a DeclRefExpr is found, its type should be checked to determine whether it
582 // is a capability or not.
583
584 if (const auto *E = dyn_cast<CastExpr>(Ex))
585 return isCapabilityExpr(S, E->getSubExpr());
586 else if (const auto *E = dyn_cast<ParenExpr>(Ex))
587 return isCapabilityExpr(S, E->getSubExpr());
588 else if (const auto *E = dyn_cast<UnaryOperator>(Ex)) {
589 if (E->getOpcode() == UO_LNot || E->getOpcode() == UO_AddrOf ||
590 E->getOpcode() == UO_Deref)
591 return isCapabilityExpr(S, E->getSubExpr());
592 return false;
593 } else if (const auto *E = dyn_cast<BinaryOperator>(Ex)) {
594 if (E->getOpcode() == BO_LAnd || E->getOpcode() == BO_LOr)
595 return isCapabilityExpr(S, E->getLHS()) &&
596 isCapabilityExpr(S, E->getRHS());
597 return false;
598 }
599
600 return typeHasCapability(S, Ex->getType());
601}
602
603/// Checks that all attribute arguments, starting from Sidx, resolve to
604/// a capability object.
605/// \param Sidx The attribute argument index to start checking with.
606/// \param ParamIdxOk Whether an argument can be indexing into a function
607/// parameter list.
609 const ParsedAttr &AL,
611 unsigned Sidx = 0,
612 bool ParamIdxOk = false) {
613 if (Sidx == AL.getNumArgs()) {
614 // If we don't have any capability arguments, the attribute implicitly
615 // refers to 'this'. So we need to make sure that 'this' exists, i.e. we're
616 // a non-static method, and that the class is a (scoped) capability.
617 const auto *MD = dyn_cast<const CXXMethodDecl>(D);
618 if (MD && !MD->isStatic()) {
619 const CXXRecordDecl *RD = MD->getParent();
620 // FIXME -- need to check this again on template instantiation
621 if (!checkRecordDeclForAttr<CapabilityAttr>(RD) &&
622 !checkRecordDeclForAttr<ScopedLockableAttr>(RD))
623 S.Diag(AL.getLoc(),
624 diag::warn_thread_attribute_not_on_capability_member)
625 << AL << MD->getParent();
626 } else {
627 S.Diag(AL.getLoc(), diag::warn_thread_attribute_not_on_non_static_member)
628 << AL;
629 }
630 }
631
632 for (unsigned Idx = Sidx; Idx < AL.getNumArgs(); ++Idx) {
633 Expr *ArgExp = AL.getArgAsExpr(Idx);
634
635 if (ArgExp->isTypeDependent()) {
636 // FIXME -- need to check this again on template instantiation
637 Args.push_back(ArgExp);
638 continue;
639 }
640
641 if (const auto *StrLit = dyn_cast<StringLiteral>(ArgExp)) {
642 if (StrLit->getLength() == 0 ||
643 (StrLit->isOrdinary() && StrLit->getString() == "*")) {
644 // Pass empty strings to the analyzer without warnings.
645 // Treat "*" as the universal lock.
646 Args.push_back(ArgExp);
647 continue;
648 }
649
650 // We allow constant strings to be used as a placeholder for expressions
651 // that are not valid C++ syntax, but warn that they are ignored.
652 S.Diag(AL.getLoc(), diag::warn_thread_attribute_ignored) << AL;
653 Args.push_back(ArgExp);
654 continue;
655 }
656
657 QualType ArgTy = ArgExp->getType();
658
659 // A pointer to member expression of the form &MyClass::mu is treated
660 // specially -- we need to look at the type of the member.
661 if (const auto *UOp = dyn_cast<UnaryOperator>(ArgExp))
662 if (UOp->getOpcode() == UO_AddrOf)
663 if (const auto *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr()))
664 if (DRE->getDecl()->isCXXInstanceMember())
665 ArgTy = DRE->getDecl()->getType();
666
667 // First see if we can just cast to record type, or pointer to record type.
668 const RecordType *RT = getRecordType(ArgTy);
669
670 // Now check if we index into a record type function param.
671 if(!RT && ParamIdxOk) {
672 const auto *FD = dyn_cast<FunctionDecl>(D);
673 const auto *IL = dyn_cast<IntegerLiteral>(ArgExp);
674 if(FD && IL) {
675 unsigned int NumParams = FD->getNumParams();
676 llvm::APInt ArgValue = IL->getValue();
677 uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
678 uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
679 if (!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
680 S.Diag(AL.getLoc(),
681 diag::err_attribute_argument_out_of_bounds_extra_info)
682 << AL << Idx + 1 << NumParams;
683 continue;
684 }
685 ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
686 }
687 }
688
689 // If the type does not have a capability, see if the components of the
690 // expression have capabilities. This allows for writing C code where the
691 // capability may be on the type, and the expression is a capability
692 // boolean logic expression. Eg) requires_capability(A || B && !C)
693 if (!typeHasCapability(S, ArgTy) && !isCapabilityExpr(S, ArgExp))
694 S.Diag(AL.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
695 << AL << ArgTy;
696
697 Args.push_back(ArgExp);
698 }
699}
700
701//===----------------------------------------------------------------------===//
702// Attribute Implementations
703//===----------------------------------------------------------------------===//
704
705static void handlePtGuardedVarAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
706 if (!threadSafetyCheckIsPointer(S, D, AL))
707 return;
708
709 D->addAttr(::new (S.Context) PtGuardedVarAttr(S.Context, AL));
710}
711
712static bool checkGuardedByAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
713 Expr *&Arg) {
715 // check that all arguments are lockable objects
716 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
717 unsigned Size = Args.size();
718 if (Size != 1)
719 return false;
720
721 Arg = Args[0];
722
723 return true;
724}
725
726static void handleGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
727 Expr *Arg = nullptr;
728 if (!checkGuardedByAttrCommon(S, D, AL, Arg))
729 return;
730
731 D->addAttr(::new (S.Context) GuardedByAttr(S.Context, AL, Arg));
732}
733
734static void handlePtGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
735 Expr *Arg = nullptr;
736 if (!checkGuardedByAttrCommon(S, D, AL, Arg))
737 return;
738
739 if (!threadSafetyCheckIsPointer(S, D, AL))
740 return;
741
742 D->addAttr(::new (S.Context) PtGuardedByAttr(S.Context, AL, Arg));
743}
744
745static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
747 if (!AL.checkAtLeastNumArgs(S, 1))
748 return false;
749
750 // Check that this attribute only applies to lockable types.
751 QualType QT = cast<ValueDecl>(D)->getType();
752 if (!QT->isDependentType() && !typeHasCapability(S, QT)) {
753 S.Diag(AL.getLoc(), diag::warn_thread_attribute_decl_not_lockable) << AL;
754 return false;
755 }
756
757 // Check that all arguments are lockable objects.
758 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
759 if (Args.empty())
760 return false;
761
762 return true;
763}
764
765static void handleAcquiredAfterAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
767 if (!checkAcquireOrderAttrCommon(S, D, AL, Args))
768 return;
769
770 Expr **StartArg = &Args[0];
771 D->addAttr(::new (S.Context)
772 AcquiredAfterAttr(S.Context, AL, StartArg, Args.size()));
773}
774
775static void handleAcquiredBeforeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
777 if (!checkAcquireOrderAttrCommon(S, D, AL, Args))
778 return;
779
780 Expr **StartArg = &Args[0];
781 D->addAttr(::new (S.Context)
782 AcquiredBeforeAttr(S.Context, AL, StartArg, Args.size()));
783}
784
785static bool checkLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
787 // zero or more arguments ok
788 // check that all arguments are lockable objects
789 checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 0, /*ParamIdxOk=*/true);
790
791 return true;
792}
793
794static void handleAssertSharedLockAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
796 if (!checkLockFunAttrCommon(S, D, AL, Args))
797 return;
798
799 unsigned Size = Args.size();
800 Expr **StartArg = Size == 0 ? nullptr : &Args[0];
801 D->addAttr(::new (S.Context)
802 AssertSharedLockAttr(S.Context, AL, StartArg, Size));
803}
804
806 const ParsedAttr &AL) {
808 if (!checkLockFunAttrCommon(S, D, AL, Args))
809 return;
810
811 unsigned Size = Args.size();
812 Expr **StartArg = Size == 0 ? nullptr : &Args[0];
813 D->addAttr(::new (S.Context)
814 AssertExclusiveLockAttr(S.Context, AL, StartArg, Size));
815}
816
817/// Checks to be sure that the given parameter number is in bounds, and
818/// is an integral type. Will emit appropriate diagnostics if this returns
819/// false.
820///
821/// AttrArgNo is used to actually retrieve the argument, so it's base-0.
822template <typename AttrInfo>
823static bool checkParamIsIntegerType(Sema &S, const Decl *D, const AttrInfo &AI,
824 unsigned AttrArgNo) {
825 assert(AI.isArgExpr(AttrArgNo) && "Expected expression argument");
826 Expr *AttrArg = AI.getArgAsExpr(AttrArgNo);
827 ParamIdx Idx;
828 if (!checkFunctionOrMethodParameterIndex(S, D, AI, AttrArgNo + 1, AttrArg,
829 Idx))
830 return false;
831
833 if (!ParamTy->isIntegerType() && !ParamTy->isCharType()) {
834 SourceLocation SrcLoc = AttrArg->getBeginLoc();
835 S.Diag(SrcLoc, diag::err_attribute_integers_only)
837 return false;
838 }
839 return true;
840}
841
842static void handleAllocSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
843 if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 2))
844 return;
845
846 assert(isFunctionOrMethod(D) && hasFunctionProto(D));
847
849 if (!RetTy->isPointerType()) {
850 S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only) << AL;
851 return;
852 }
853
854 const Expr *SizeExpr = AL.getArgAsExpr(0);
855 int SizeArgNoVal;
856 // Parameter indices are 1-indexed, hence Index=1
857 if (!checkPositiveIntArgument(S, AL, SizeExpr, SizeArgNoVal, /*Idx=*/1))
858 return;
859 if (!checkParamIsIntegerType(S, D, AL, /*AttrArgNo=*/0))
860 return;
861 ParamIdx SizeArgNo(SizeArgNoVal, D);
862
863 ParamIdx NumberArgNo;
864 if (AL.getNumArgs() == 2) {
865 const Expr *NumberExpr = AL.getArgAsExpr(1);
866 int Val;
867 // Parameter indices are 1-based, hence Index=2
868 if (!checkPositiveIntArgument(S, AL, NumberExpr, Val, /*Idx=*/2))
869 return;
870 if (!checkParamIsIntegerType(S, D, AL, /*AttrArgNo=*/1))
871 return;
872 NumberArgNo = ParamIdx(Val, D);
873 }
874
875 D->addAttr(::new (S.Context)
876 AllocSizeAttr(S.Context, AL, SizeArgNo, NumberArgNo));
877}
878
879static bool checkTryLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
881 if (!AL.checkAtLeastNumArgs(S, 1))
882 return false;
883
884 if (!isIntOrBool(AL.getArgAsExpr(0))) {
885 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
886 << AL << 1 << AANT_ArgumentIntOrBool;
887 return false;
888 }
889
890 // check that all arguments are lockable objects
891 checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 1);
892
893 return true;
894}
895
897 const ParsedAttr &AL) {
899 if (!checkTryLockFunAttrCommon(S, D, AL, Args))
900 return;
901
902 D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(
903 S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));
904}
905
907 const ParsedAttr &AL) {
909 if (!checkTryLockFunAttrCommon(S, D, AL, Args))
910 return;
911
912 D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(
913 S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));
914}
915
916static void handleLockReturnedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
917 // check that the argument is lockable object
919 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
920 unsigned Size = Args.size();
921 if (Size == 0)
922 return;
923
924 D->addAttr(::new (S.Context) LockReturnedAttr(S.Context, AL, Args[0]));
925}
926
927static void handleLocksExcludedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
928 if (!AL.checkAtLeastNumArgs(S, 1))
929 return;
930
931 // check that all arguments are lockable objects
933 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
934 unsigned Size = Args.size();
935 if (Size == 0)
936 return;
937 Expr **StartArg = &Args[0];
938
939 D->addAttr(::new (S.Context)
940 LocksExcludedAttr(S.Context, AL, StartArg, Size));
941}
942
943static bool checkFunctionConditionAttr(Sema &S, Decl *D, const ParsedAttr &AL,
944 Expr *&Cond, StringRef &Msg) {
945 Cond = AL.getArgAsExpr(0);
946 if (!Cond->isTypeDependent()) {
948 if (Converted.isInvalid())
949 return false;
950 Cond = Converted.get();
951 }
952
953 if (!S.checkStringLiteralArgumentAttr(AL, 1, Msg))
954 return false;
955
956 if (Msg.empty())
957 Msg = "<no message provided>";
958
960 if (isa<FunctionDecl>(D) && !Cond->isValueDependent() &&
961 !Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(D),
962 Diags)) {
963 S.Diag(AL.getLoc(), diag::err_attr_cond_never_constant_expr) << AL;
964 for (const PartialDiagnosticAt &PDiag : Diags)
965 S.Diag(PDiag.first, PDiag.second);
966 return false;
967 }
968 return true;
969}
970
971static void handleEnableIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
972 S.Diag(AL.getLoc(), diag::ext_clang_enable_if);
973
974 Expr *Cond;
975 StringRef Msg;
976 if (checkFunctionConditionAttr(S, D, AL, Cond, Msg))
977 D->addAttr(::new (S.Context) EnableIfAttr(S.Context, AL, Cond, Msg));
978}
979
980static void handleErrorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
981 StringRef NewUserDiagnostic;
982 if (!S.checkStringLiteralArgumentAttr(AL, 0, NewUserDiagnostic))
983 return;
984 if (ErrorAttr *EA = S.mergeErrorAttr(D, AL, NewUserDiagnostic))
985 D->addAttr(EA);
986}
987
989 const ParsedAttr &AL) {
990 const auto *PD = isa<CXXRecordDecl>(D)
991 ? cast<DeclContext>(D)
993 if (const auto *RD = dyn_cast<CXXRecordDecl>(PD); RD && RD->isLocalClass()) {
994 S.Diag(AL.getLoc(),
995 diag::warn_attribute_exclude_from_explicit_instantiation_local_class)
996 << AL << /*IsMember=*/!isa<CXXRecordDecl>(D);
997 return;
998 }
999 D->addAttr(::new (S.Context)
1000 ExcludeFromExplicitInstantiationAttr(S.Context, AL));
1001}
1002
1003namespace {
1004/// Determines if a given Expr references any of the given function's
1005/// ParmVarDecls, or the function's implicit `this` parameter (if applicable).
1006class ArgumentDependenceChecker
1007 : public RecursiveASTVisitor<ArgumentDependenceChecker> {
1008#ifndef NDEBUG
1009 const CXXRecordDecl *ClassType;
1010#endif
1012 bool Result;
1013
1014public:
1015 ArgumentDependenceChecker(const FunctionDecl *FD) {
1016#ifndef NDEBUG
1017 if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
1018 ClassType = MD->getParent();
1019 else
1020 ClassType = nullptr;
1021#endif
1022 Parms.insert(FD->param_begin(), FD->param_end());
1023 }
1024
1025 bool referencesArgs(Expr *E) {
1026 Result = false;
1027 TraverseStmt(E);
1028 return Result;
1029 }
1030
1031 bool VisitCXXThisExpr(CXXThisExpr *E) {
1032 assert(E->getType()->getPointeeCXXRecordDecl() == ClassType &&
1033 "`this` doesn't refer to the enclosing class?");
1034 Result = true;
1035 return false;
1036 }
1037
1038 bool VisitDeclRefExpr(DeclRefExpr *DRE) {
1039 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
1040 if (Parms.count(PVD)) {
1041 Result = true;
1042 return false;
1043 }
1044 return true;
1045 }
1046};
1047}
1048
1050 const ParsedAttr &AL) {
1051 const auto *DeclFD = cast<FunctionDecl>(D);
1052
1053 if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(DeclFD))
1054 if (!MethodDecl->isStatic()) {
1055 S.Diag(AL.getLoc(), diag::err_attribute_no_member_function) << AL;
1056 return;
1057 }
1058
1059 auto DiagnoseType = [&](unsigned Index, AttributeArgumentNType T) {
1060 SourceLocation Loc = [&]() {
1061 auto Union = AL.getArg(Index - 1);
1062 if (Union.is<Expr *>())
1063 return Union.get<Expr *>()->getBeginLoc();
1064 return Union.get<IdentifierLoc *>()->Loc;
1065 }();
1066
1067 S.Diag(Loc, diag::err_attribute_argument_n_type) << AL << Index << T;
1068 };
1069
1070 FunctionDecl *AttrFD = [&]() -> FunctionDecl * {
1071 if (!AL.isArgExpr(0))
1072 return nullptr;
1073 auto *F = dyn_cast_if_present<DeclRefExpr>(AL.getArgAsExpr(0));
1074 if (!F)
1075 return nullptr;
1076 return dyn_cast_if_present<FunctionDecl>(F->getFoundDecl());
1077 }();
1078
1079 if (!AttrFD || !AttrFD->getBuiltinID(true)) {
1080 DiagnoseType(1, AANT_ArgumentBuiltinFunction);
1081 return;
1082 }
1083
1084 if (AttrFD->getNumParams() != AL.getNumArgs() - 1) {
1085 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments_for)
1086 << AL << AttrFD << AttrFD->getNumParams();
1087 return;
1088 }
1089
1091
1092 for (unsigned I = 1; I < AL.getNumArgs(); ++I) {
1093 if (!AL.isArgExpr(I)) {
1094 DiagnoseType(I + 1, AANT_ArgumentIntegerConstant);
1095 return;
1096 }
1097
1098 const Expr *IndexExpr = AL.getArgAsExpr(I);
1099 uint32_t Index;
1100
1101 if (!checkUInt32Argument(S, AL, IndexExpr, Index, I + 1, false))
1102 return;
1103
1104 if (Index > DeclFD->getNumParams()) {
1105 S.Diag(AL.getLoc(), diag::err_attribute_bounds_for_function)
1106 << AL << Index << DeclFD << DeclFD->getNumParams();
1107 return;
1108 }
1109
1110 QualType T1 = AttrFD->getParamDecl(I - 1)->getType();
1111 QualType T2 = DeclFD->getParamDecl(Index - 1)->getType();
1112
1115 S.Diag(IndexExpr->getBeginLoc(), diag::err_attribute_parameter_types)
1116 << AL << Index << DeclFD << T2 << I << AttrFD << T1;
1117 return;
1118 }
1119
1120 Indices.push_back(Index - 1);
1121 }
1122
1123 D->addAttr(::new (S.Context) DiagnoseAsBuiltinAttr(
1124 S.Context, AL, AttrFD, Indices.data(), Indices.size()));
1125}
1126
1127static void handleDiagnoseIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1128 S.Diag(AL.getLoc(), diag::ext_clang_diagnose_if);
1129
1130 Expr *Cond;
1131 StringRef Msg;
1132 if (!checkFunctionConditionAttr(S, D, AL, Cond, Msg))
1133 return;
1134
1135 StringRef DiagTypeStr;
1136 if (!S.checkStringLiteralArgumentAttr(AL, 2, DiagTypeStr))
1137 return;
1138
1139 DiagnoseIfAttr::DiagnosticType DiagType;
1140 if (!DiagnoseIfAttr::ConvertStrToDiagnosticType(DiagTypeStr, DiagType)) {
1141 S.Diag(AL.getArgAsExpr(2)->getBeginLoc(),
1142 diag::err_diagnose_if_invalid_diagnostic_type);
1143 return;
1144 }
1145
1146 bool ArgDependent = false;
1147 if (const auto *FD = dyn_cast<FunctionDecl>(D))
1148 ArgDependent = ArgumentDependenceChecker(FD).referencesArgs(Cond);
1149 D->addAttr(::new (S.Context) DiagnoseIfAttr(
1150 S.Context, AL, Cond, Msg, DiagType, ArgDependent, cast<NamedDecl>(D)));
1151}
1152
1153static void handleNoBuiltinAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1154 static constexpr const StringRef kWildcard = "*";
1155
1157 bool HasWildcard = false;
1158
1159 const auto AddBuiltinName = [&Names, &HasWildcard](StringRef Name) {
1160 if (Name == kWildcard)
1161 HasWildcard = true;
1162 Names.push_back(Name);
1163 };
1164
1165 // Add previously defined attributes.
1166 if (const auto *NBA = D->getAttr<NoBuiltinAttr>())
1167 for (StringRef BuiltinName : NBA->builtinNames())
1168 AddBuiltinName(BuiltinName);
1169
1170 // Add current attributes.
1171 if (AL.getNumArgs() == 0)
1172 AddBuiltinName(kWildcard);
1173 else
1174 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
1175 StringRef BuiltinName;
1176 SourceLocation LiteralLoc;
1177 if (!S.checkStringLiteralArgumentAttr(AL, I, BuiltinName, &LiteralLoc))
1178 return;
1179
1180 if (Builtin::Context::isBuiltinFunc(BuiltinName))
1181 AddBuiltinName(BuiltinName);
1182 else
1183 S.Diag(LiteralLoc, diag::warn_attribute_no_builtin_invalid_builtin_name)
1184 << BuiltinName << AL;
1185 }
1186
1187 // Repeating the same attribute is fine.
1188 llvm::sort(Names);
1189 Names.erase(std::unique(Names.begin(), Names.end()), Names.end());
1190
1191 // Empty no_builtin must be on its own.
1192 if (HasWildcard && Names.size() > 1)
1193 S.Diag(D->getLocation(),
1194 diag::err_attribute_no_builtin_wildcard_or_builtin_name)
1195 << AL;
1196
1197 if (D->hasAttr<NoBuiltinAttr>())
1198 D->dropAttr<NoBuiltinAttr>();
1199 D->addAttr(::new (S.Context)
1200 NoBuiltinAttr(S.Context, AL, Names.data(), Names.size()));
1201}
1202
1203static void handlePassObjectSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1204 if (D->hasAttr<PassObjectSizeAttr>()) {
1205 S.Diag(D->getBeginLoc(), diag::err_attribute_only_once_per_parameter) << AL;
1206 return;
1207 }
1208
1209 Expr *E = AL.getArgAsExpr(0);
1210 uint32_t Type;
1211 if (!checkUInt32Argument(S, AL, E, Type, /*Idx=*/1))
1212 return;
1213
1214 // pass_object_size's argument is passed in as the second argument of
1215 // __builtin_object_size. So, it has the same constraints as that second
1216 // argument; namely, it must be in the range [0, 3].
1217 if (Type > 3) {
1218 S.Diag(E->getBeginLoc(), diag::err_attribute_argument_out_of_range)
1219 << AL << 0 << 3 << E->getSourceRange();
1220 return;
1221 }
1222
1223 // pass_object_size is only supported on constant pointer parameters; as a
1224 // kindness to users, we allow the parameter to be non-const for declarations.
1225 // At this point, we have no clue if `D` belongs to a function declaration or
1226 // definition, so we defer the constness check until later.
1227 if (!cast<ParmVarDecl>(D)->getType()->isPointerType()) {
1228 S.Diag(D->getBeginLoc(), diag::err_attribute_pointers_only) << AL << 1;
1229 return;
1230 }
1231
1232 D->addAttr(::new (S.Context) PassObjectSizeAttr(S.Context, AL, (int)Type));
1233}
1234
1235static void handleConsumableAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1236 ConsumableAttr::ConsumedState DefaultState;
1237
1238 if (AL.isArgIdent(0)) {
1239 IdentifierLoc *IL = AL.getArgAsIdent(0);
1240 if (!ConsumableAttr::ConvertStrToConsumedState(IL->Ident->getName(),
1241 DefaultState)) {
1242 S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL
1243 << IL->Ident;
1244 return;
1245 }
1246 } else {
1247 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1248 << AL << AANT_ArgumentIdentifier;
1249 return;
1250 }
1251
1252 D->addAttr(::new (S.Context) ConsumableAttr(S.Context, AL, DefaultState));
1253}
1254
1256 const ParsedAttr &AL) {
1258
1259 if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) {
1260 if (!RD->hasAttr<ConsumableAttr>()) {
1261 S.Diag(AL.getLoc(), diag::warn_attr_on_unconsumable_class) << RD;
1262
1263 return false;
1264 }
1265 }
1266
1267 return true;
1268}
1269
1270static void handleCallableWhenAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1271 if (!AL.checkAtLeastNumArgs(S, 1))
1272 return;
1273
1274 if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL))
1275 return;
1276
1278 for (unsigned ArgIndex = 0; ArgIndex < AL.getNumArgs(); ++ArgIndex) {
1279 CallableWhenAttr::ConsumedState CallableState;
1280
1281 StringRef StateString;
1283 if (AL.isArgIdent(ArgIndex)) {
1284 IdentifierLoc *Ident = AL.getArgAsIdent(ArgIndex);
1285 StateString = Ident->Ident->getName();
1286 Loc = Ident->Loc;
1287 } else {
1288 if (!S.checkStringLiteralArgumentAttr(AL, ArgIndex, StateString, &Loc))
1289 return;
1290 }
1291
1292 if (!CallableWhenAttr::ConvertStrToConsumedState(StateString,
1293 CallableState)) {
1294 S.Diag(Loc, diag::warn_attribute_type_not_supported) << AL << StateString;
1295 return;
1296 }
1297
1298 States.push_back(CallableState);
1299 }
1300
1301 D->addAttr(::new (S.Context)
1302 CallableWhenAttr(S.Context, AL, States.data(), States.size()));
1303}
1304
1305static void handleParamTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1306 ParamTypestateAttr::ConsumedState ParamState;
1307
1308 if (AL.isArgIdent(0)) {
1309 IdentifierLoc *Ident = AL.getArgAsIdent(0);
1310 StringRef StateString = Ident->Ident->getName();
1311
1312 if (!ParamTypestateAttr::ConvertStrToConsumedState(StateString,
1313 ParamState)) {
1314 S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported)
1315 << AL << StateString;
1316 return;
1317 }
1318 } else {
1319 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1320 << AL << AANT_ArgumentIdentifier;
1321 return;
1322 }
1323
1324 // FIXME: This check is currently being done in the analysis. It can be
1325 // enabled here only after the parser propagates attributes at
1326 // template specialization definition, not declaration.
1327 //QualType ReturnType = cast<ParmVarDecl>(D)->getType();
1328 //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1329 //
1330 //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1331 // S.Diag(AL.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1332 // ReturnType.getAsString();
1333 // return;
1334 //}
1335
1336 D->addAttr(::new (S.Context) ParamTypestateAttr(S.Context, AL, ParamState));
1337}
1338
1339static void handleReturnTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1340 ReturnTypestateAttr::ConsumedState ReturnState;
1341
1342 if (AL.isArgIdent(0)) {
1343 IdentifierLoc *IL = AL.getArgAsIdent(0);
1344 if (!ReturnTypestateAttr::ConvertStrToConsumedState(IL->Ident->getName(),
1345 ReturnState)) {
1346 S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL
1347 << IL->Ident;
1348 return;
1349 }
1350 } else {
1351 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1352 << AL << AANT_ArgumentIdentifier;
1353 return;
1354 }
1355
1356 // FIXME: This check is currently being done in the analysis. It can be
1357 // enabled here only after the parser propagates attributes at
1358 // template specialization definition, not declaration.
1359 // QualType ReturnType;
1360 //
1361 // if (const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D)) {
1362 // ReturnType = Param->getType();
1363 //
1364 //} else if (const CXXConstructorDecl *Constructor =
1365 // dyn_cast<CXXConstructorDecl>(D)) {
1366 // ReturnType = Constructor->getFunctionObjectParameterType();
1367 //
1368 //} else {
1369 //
1370 // ReturnType = cast<FunctionDecl>(D)->getCallResultType();
1371 //}
1372 //
1373 // const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1374 //
1375 // if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1376 // S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1377 // ReturnType.getAsString();
1378 // return;
1379 //}
1380
1381 D->addAttr(::new (S.Context) ReturnTypestateAttr(S.Context, AL, ReturnState));
1382}
1383
1384static void handleSetTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1385 if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL))
1386 return;
1387
1388 SetTypestateAttr::ConsumedState NewState;
1389 if (AL.isArgIdent(0)) {
1390 IdentifierLoc *Ident = AL.getArgAsIdent(0);
1391 StringRef Param = Ident->Ident->getName();
1392 if (!SetTypestateAttr::ConvertStrToConsumedState(Param, NewState)) {
1393 S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) << AL
1394 << Param;
1395 return;
1396 }
1397 } else {
1398 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1399 << AL << AANT_ArgumentIdentifier;
1400 return;
1401 }
1402
1403 D->addAttr(::new (S.Context) SetTypestateAttr(S.Context, AL, NewState));
1404}
1405
1406static void handleTestTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1407 if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL))
1408 return;
1409
1410 TestTypestateAttr::ConsumedState TestState;
1411 if (AL.isArgIdent(0)) {
1412 IdentifierLoc *Ident = AL.getArgAsIdent(0);
1413 StringRef Param = Ident->Ident->getName();
1414 if (!TestTypestateAttr::ConvertStrToConsumedState(Param, TestState)) {
1415 S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) << AL
1416 << Param;
1417 return;
1418 }
1419 } else {
1420 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1421 << AL << AANT_ArgumentIdentifier;
1422 return;
1423 }
1424
1425 D->addAttr(::new (S.Context) TestTypestateAttr(S.Context, AL, TestState));
1426}
1427
1428static void handleExtVectorTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1429 // Remember this typedef decl, we will need it later for diagnostics.
1430 S.ExtVectorDecls.push_back(cast<TypedefNameDecl>(D));
1431}
1432
1433static void handlePackedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1434 if (auto *TD = dyn_cast<TagDecl>(D))
1435 TD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
1436 else if (auto *FD = dyn_cast<FieldDecl>(D)) {
1437 bool BitfieldByteAligned = (!FD->getType()->isDependentType() &&
1438 !FD->getType()->isIncompleteType() &&
1439 FD->isBitField() &&
1440 S.Context.getTypeAlign(FD->getType()) <= 8);
1441
1442 if (S.getASTContext().getTargetInfo().getTriple().isPS()) {
1443 if (BitfieldByteAligned)
1444 // The PS4/PS5 targets need to maintain ABI backwards compatibility.
1445 S.Diag(AL.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
1446 << AL << FD->getType();
1447 else
1448 FD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
1449 } else {
1450 // Report warning about changed offset in the newer compiler versions.
1451 if (BitfieldByteAligned)
1452 S.Diag(AL.getLoc(), diag::warn_attribute_packed_for_bitfield);
1453
1454 FD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
1455 }
1456
1457 } else
1458 S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
1459}
1460
1461static void handlePreferredName(Sema &S, Decl *D, const ParsedAttr &AL) {
1462 auto *RD = cast<CXXRecordDecl>(D);
1463 ClassTemplateDecl *CTD = RD->getDescribedClassTemplate();
1464 assert(CTD && "attribute does not appertain to this declaration");
1465
1466 ParsedType PT = AL.getTypeArg();
1467 TypeSourceInfo *TSI = nullptr;
1468 QualType T = S.GetTypeFromParser(PT, &TSI);
1469 if (!TSI)
1471
1472 if (!T.hasQualifiers() && T->isTypedefNameType()) {
1473 // Find the template name, if this type names a template specialization.
1474 const TemplateDecl *Template = nullptr;
1475 if (const auto *CTSD = dyn_cast_if_present<ClassTemplateSpecializationDecl>(
1476 T->getAsCXXRecordDecl())) {
1477 Template = CTSD->getSpecializedTemplate();
1478 } else if (const auto *TST = T->getAs<TemplateSpecializationType>()) {
1479 while (TST && TST->isTypeAlias())
1480 TST = TST->getAliasedType()->getAs<TemplateSpecializationType>();
1481 if (TST)
1482 Template = TST->getTemplateName().getAsTemplateDecl();
1483 }
1484
1485 if (Template && declaresSameEntity(Template, CTD)) {
1486 D->addAttr(::new (S.Context) PreferredNameAttr(S.Context, AL, TSI));
1487 return;
1488 }
1489 }
1490
1491 S.Diag(AL.getLoc(), diag::err_attribute_preferred_name_arg_invalid)
1492 << T << CTD;
1493 if (const auto *TT = T->getAs<TypedefType>())
1494 S.Diag(TT->getDecl()->getLocation(), diag::note_entity_declared_at)
1495 << TT->getDecl();
1496}
1497
1498static bool checkIBOutletCommon(Sema &S, Decl *D, const ParsedAttr &AL) {
1499 // The IBOutlet/IBOutletCollection attributes only apply to instance
1500 // variables or properties of Objective-C classes. The outlet must also
1501 // have an object reference type.
1502 if (const auto *VD = dyn_cast<ObjCIvarDecl>(D)) {
1503 if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
1504 S.Diag(AL.getLoc(), diag::warn_iboutlet_object_type)
1505 << AL << VD->getType() << 0;
1506 return false;
1507 }
1508 }
1509 else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) {
1510 if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
1511 S.Diag(AL.getLoc(), diag::warn_iboutlet_object_type)
1512 << AL << PD->getType() << 1;
1513 return false;
1514 }
1515 }
1516 else {
1517 S.Diag(AL.getLoc(), diag::warn_attribute_iboutlet) << AL;
1518 return false;
1519 }
1520
1521 return true;
1522}
1523
1524static void handleIBOutlet(Sema &S, Decl *D, const ParsedAttr &AL) {
1525 if (!checkIBOutletCommon(S, D, AL))
1526 return;
1527
1528 D->addAttr(::new (S.Context) IBOutletAttr(S.Context, AL));
1529}
1530
1531static void handleIBOutletCollection(Sema &S, Decl *D, const ParsedAttr &AL) {
1532
1533 // The iboutletcollection attribute can have zero or one arguments.
1534 if (AL.getNumArgs() > 1) {
1535 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
1536 return;
1537 }
1538
1539 if (!checkIBOutletCommon(S, D, AL))
1540 return;
1541
1542 ParsedType PT;
1543
1544 if (AL.hasParsedType())
1545 PT = AL.getTypeArg();
1546 else {
1547 PT = S.getTypeName(S.Context.Idents.get("NSObject"), AL.getLoc(),
1549 if (!PT) {
1550 S.Diag(AL.getLoc(), diag::err_iboutletcollection_type) << "NSObject";
1551 return;
1552 }
1553 }
1554
1555 TypeSourceInfo *QTLoc = nullptr;
1556 QualType QT = S.GetTypeFromParser(PT, &QTLoc);
1557 if (!QTLoc)
1558 QTLoc = S.Context.getTrivialTypeSourceInfo(QT, AL.getLoc());
1559
1560 // Diagnose use of non-object type in iboutletcollection attribute.
1561 // FIXME. Gnu attribute extension ignores use of builtin types in
1562 // attributes. So, __attribute__((iboutletcollection(char))) will be
1563 // treated as __attribute__((iboutletcollection())).
1564 if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {
1565 S.Diag(AL.getLoc(),
1566 QT->isBuiltinType() ? diag::err_iboutletcollection_builtintype
1567 : diag::err_iboutletcollection_type) << QT;
1568 return;
1569 }
1570
1571 D->addAttr(::new (S.Context) IBOutletCollectionAttr(S.Context, AL, QTLoc));
1572}
1573
1575 if (RefOkay) {
1576 if (T->isReferenceType())
1577 return true;
1578 } else {
1579 T = T.getNonReferenceType();
1580 }
1581
1582 // The nonnull attribute, and other similar attributes, can be applied to a
1583 // transparent union that contains a pointer type.
1584 if (const RecordType *UT = T->getAsUnionType()) {
1585 if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
1586 RecordDecl *UD = UT->getDecl();
1587 for (const auto *I : UD->fields()) {
1588 QualType QT = I->getType();
1589 if (QT->isAnyPointerType() || QT->isBlockPointerType())
1590 return true;
1591 }
1592 }
1593 }
1594
1595 return T->isAnyPointerType() || T->isBlockPointerType();
1596}
1597
1598static bool attrNonNullArgCheck(Sema &S, QualType T, const ParsedAttr &AL,
1599 SourceRange AttrParmRange,
1600 SourceRange TypeRange,
1601 bool isReturnValue = false) {
1602 if (!S.isValidPointerAttrType(T)) {
1603 if (isReturnValue)
1604 S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only)
1605 << AL << AttrParmRange << TypeRange;
1606 else
1607 S.Diag(AL.getLoc(), diag::warn_attribute_pointers_only)
1608 << AL << AttrParmRange << TypeRange << 0;
1609 return false;
1610 }
1611 return true;
1612}
1613
1614static void handleNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1615 SmallVector<ParamIdx, 8> NonNullArgs;
1616 for (unsigned I = 0; I < AL.getNumArgs(); ++I) {
1617 Expr *Ex = AL.getArgAsExpr(I);
1618 ParamIdx Idx;
1619 if (!checkFunctionOrMethodParameterIndex(S, D, AL, I + 1, Ex, Idx))
1620 return;
1621
1622 // Is the function argument a pointer type?
1626 Ex->getSourceRange(),
1628 continue;
1629
1630 NonNullArgs.push_back(Idx);
1631 }
1632
1633 // If no arguments were specified to __attribute__((nonnull)) then all pointer
1634 // arguments have a nonnull attribute; warn if there aren't any. Skip this
1635 // check if the attribute came from a macro expansion or a template
1636 // instantiation.
1637 if (NonNullArgs.empty() && AL.getLoc().isFileID() &&
1639 bool AnyPointers = isFunctionOrMethodVariadic(D);
1640 for (unsigned I = 0, E = getFunctionOrMethodNumParams(D);
1641 I != E && !AnyPointers; ++I) {
1644 AnyPointers = true;
1645 }
1646
1647 if (!AnyPointers)
1648 S.Diag(AL.getLoc(), diag::warn_attribute_nonnull_no_pointers);
1649 }
1650
1651 ParamIdx *Start = NonNullArgs.data();
1652 unsigned Size = NonNullArgs.size();
1653 llvm::array_pod_sort(Start, Start + Size);
1654 D->addAttr(::new (S.Context) NonNullAttr(S.Context, AL, Start, Size));
1655}
1656
1658 const ParsedAttr &AL) {
1659 if (AL.getNumArgs() > 0) {
1660 if (D->getFunctionType()) {
1661 handleNonNullAttr(S, D, AL);
1662 } else {
1663 S.Diag(AL.getLoc(), diag::warn_attribute_nonnull_parm_no_args)
1664 << D->getSourceRange();
1665 }
1666 return;
1667 }
1668
1669 // Is the argument a pointer type?
1670 if (!attrNonNullArgCheck(S, D->getType(), AL, SourceRange(),
1671 D->getSourceRange()))
1672 return;
1673
1674 D->addAttr(::new (S.Context) NonNullAttr(S.Context, AL, nullptr, 0));
1675}
1676
1677static void handleReturnsNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1680 if (!attrNonNullArgCheck(S, ResultType, AL, SourceRange(), SR,
1681 /* isReturnValue */ true))
1682 return;
1683
1684 D->addAttr(::new (S.Context) ReturnsNonNullAttr(S.Context, AL));
1685}
1686
1687static void handleNoEscapeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1688 if (D->isInvalidDecl())
1689 return;
1690
1691 // noescape only applies to pointer types.
1692 QualType T = cast<ParmVarDecl>(D)->getType();
1693 if (!S.isValidPointerAttrType(T, /* RefOkay */ true)) {
1694 S.Diag(AL.getLoc(), diag::warn_attribute_pointers_only)
1695 << AL << AL.getRange() << 0;
1696 return;
1697 }
1698
1699 D->addAttr(::new (S.Context) NoEscapeAttr(S.Context, AL));
1700}
1701
1702static void handleAssumeAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1703 Expr *E = AL.getArgAsExpr(0),
1704 *OE = AL.getNumArgs() > 1 ? AL.getArgAsExpr(1) : nullptr;
1705 S.AddAssumeAlignedAttr(D, AL, E, OE);
1706}
1707
1708static void handleAllocAlignAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1709 S.AddAllocAlignAttr(D, AL, AL.getArgAsExpr(0));
1710}
1711
1713 Expr *OE) {
1716
1717 AssumeAlignedAttr TmpAttr(Context, CI, E, OE);
1718 SourceLocation AttrLoc = TmpAttr.getLocation();
1719
1720 if (!isValidPointerAttrType(ResultType, /* RefOkay */ true)) {
1721 Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)
1722 << &TmpAttr << TmpAttr.getRange() << SR;
1723 return;
1724 }
1725
1726 if (!E->isValueDependent()) {
1727 std::optional<llvm::APSInt> I = llvm::APSInt(64);
1728 if (!(I = E->getIntegerConstantExpr(Context))) {
1729 if (OE)
1730 Diag(AttrLoc, diag::err_attribute_argument_n_type)
1731 << &TmpAttr << 1 << AANT_ArgumentIntegerConstant
1732 << E->getSourceRange();
1733 else
1734 Diag(AttrLoc, diag::err_attribute_argument_type)
1735 << &TmpAttr << AANT_ArgumentIntegerConstant
1736 << E->getSourceRange();
1737 return;
1738 }
1739
1740 if (!I->isPowerOf2()) {
1741 Diag(AttrLoc, diag::err_alignment_not_power_of_two)
1742 << E->getSourceRange();
1743 return;
1744 }
1745
1746 if (*I > Sema::MaximumAlignment)
1747 Diag(CI.getLoc(), diag::warn_assume_aligned_too_great)
1749 }
1750
1751 if (OE && !OE->isValueDependent() && !OE->isIntegerConstantExpr(Context)) {
1752 Diag(AttrLoc, diag::err_attribute_argument_n_type)
1753 << &TmpAttr << 2 << AANT_ArgumentIntegerConstant
1754 << OE->getSourceRange();
1755 return;
1756 }
1757
1758 D->addAttr(::new (Context) AssumeAlignedAttr(Context, CI, E, OE));
1759}
1760
1762 Expr *ParamExpr) {
1764
1765 AllocAlignAttr TmpAttr(Context, CI, ParamIdx());
1766 SourceLocation AttrLoc = CI.getLoc();
1767
1768 if (!ResultType->isDependentType() &&
1769 !isValidPointerAttrType(ResultType, /* RefOkay */ true)) {
1770 Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)
1771 << &TmpAttr << CI.getRange() << getFunctionOrMethodResultSourceRange(D);
1772 return;
1773 }
1774
1775 ParamIdx Idx;
1776 const auto *FuncDecl = cast<FunctionDecl>(D);
1777 if (!checkFunctionOrMethodParameterIndex(*this, FuncDecl, TmpAttr,
1778 /*AttrArgNum=*/1, ParamExpr, Idx))
1779 return;
1780
1782 if (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
1783 !Ty->isAlignValT()) {
1784 Diag(ParamExpr->getBeginLoc(), diag::err_attribute_integers_only)
1785 << &TmpAttr
1786 << FuncDecl->getParamDecl(Idx.getASTIndex())->getSourceRange();
1787 return;
1788 }
1789
1790 D->addAttr(::new (Context) AllocAlignAttr(Context, CI, Idx));
1791}
1792
1793/// Check if \p AssumptionStr is a known assumption and warn if not.
1795 StringRef AssumptionStr) {
1796 if (llvm::KnownAssumptionStrings.count(AssumptionStr))
1797 return;
1798
1799 unsigned BestEditDistance = 3;
1800 StringRef Suggestion;
1801 for (const auto &KnownAssumptionIt : llvm::KnownAssumptionStrings) {
1802 unsigned EditDistance =
1803 AssumptionStr.edit_distance(KnownAssumptionIt.getKey());
1804 if (EditDistance < BestEditDistance) {
1805 Suggestion = KnownAssumptionIt.getKey();
1806 BestEditDistance = EditDistance;
1807 }
1808 }
1809
1810 if (!Suggestion.empty())
1811 S.Diag(Loc, diag::warn_omp_assume_attribute_string_unknown_suggested)
1812 << AssumptionStr << Suggestion;
1813 else
1814 S.Diag(Loc, diag::warn_omp_assume_attribute_string_unknown)
1815 << AssumptionStr;
1816}
1817
1818static void handleOMPAssumeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1819 // Handle the case where the attribute has a text message.
1820 StringRef Str;
1821 SourceLocation AttrStrLoc;
1822 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &AttrStrLoc))
1823 return;
1824
1825 checkOMPAssumeAttr(S, AttrStrLoc, Str);
1826
1827 D->addAttr(::new (S.Context) OMPAssumeAttr(S.Context, AL, Str));
1828}
1829
1830/// Normalize the attribute, __foo__ becomes foo.
1831/// Returns true if normalization was applied.
1832static bool normalizeName(StringRef &AttrName) {
1833 if (AttrName.size() > 4 && AttrName.starts_with("__") &&
1834 AttrName.ends_with("__")) {
1835 AttrName = AttrName.drop_front(2).drop_back(2);
1836 return true;
1837 }
1838 return false;
1839}
1840
1841static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1842 // This attribute must be applied to a function declaration. The first
1843 // argument to the attribute must be an identifier, the name of the resource,
1844 // for example: malloc. The following arguments must be argument indexes, the
1845 // arguments must be of integer type for Returns, otherwise of pointer type.
1846 // The difference between Holds and Takes is that a pointer may still be used
1847 // after being held. free() should be __attribute((ownership_takes)), whereas
1848 // a list append function may well be __attribute((ownership_holds)).
1849
1850 if (!AL.isArgIdent(0)) {
1851 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
1852 << AL << 1 << AANT_ArgumentIdentifier;
1853 return;
1854 }
1855
1856 // Figure out our Kind.
1857 OwnershipAttr::OwnershipKind K =
1858 OwnershipAttr(S.Context, AL, nullptr, nullptr, 0).getOwnKind();
1859
1860 // Check arguments.
1861 switch (K) {
1862 case OwnershipAttr::Takes:
1863 case OwnershipAttr::Holds:
1864 if (AL.getNumArgs() < 2) {
1865 S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) << AL << 2;
1866 return;
1867 }
1868 break;
1869 case OwnershipAttr::Returns:
1870 if (AL.getNumArgs() > 2) {
1871 S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 1;
1872 return;
1873 }
1874 break;
1875 }
1876
1878
1879 StringRef ModuleName = Module->getName();
1880 if (normalizeName(ModuleName)) {
1881 Module = &S.PP.getIdentifierTable().get(ModuleName);
1882 }
1883
1884 SmallVector<ParamIdx, 8> OwnershipArgs;
1885 for (unsigned i = 1; i < AL.getNumArgs(); ++i) {
1886 Expr *Ex = AL.getArgAsExpr(i);
1887 ParamIdx Idx;
1888 if (!checkFunctionOrMethodParameterIndex(S, D, AL, i, Ex, Idx))
1889 return;
1890
1891 // Is the function argument a pointer type?
1893 int Err = -1; // No error
1894 switch (K) {
1895 case OwnershipAttr::Takes:
1896 case OwnershipAttr::Holds:
1897 if (!T->isAnyPointerType() && !T->isBlockPointerType())
1898 Err = 0;
1899 break;
1900 case OwnershipAttr::Returns:
1901 if (!T->isIntegerType())
1902 Err = 1;
1903 break;
1904 }
1905 if (-1 != Err) {
1906 S.Diag(AL.getLoc(), diag::err_ownership_type) << AL << Err
1907 << Ex->getSourceRange();
1908 return;
1909 }
1910
1911 // Check we don't have a conflict with another ownership attribute.
1912 for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
1913 // Cannot have two ownership attributes of different kinds for the same
1914 // index.
1915 if (I->getOwnKind() != K && llvm::is_contained(I->args(), Idx)) {
1916 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
1917 << AL << I
1918 << (AL.isRegularKeywordAttribute() ||
1919 I->isRegularKeywordAttribute());
1920 return;
1921 } else if (K == OwnershipAttr::Returns &&
1922 I->getOwnKind() == OwnershipAttr::Returns) {
1923 // A returns attribute conflicts with any other returns attribute using
1924 // a different index.
1925 if (!llvm::is_contained(I->args(), Idx)) {
1926 S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch)
1927 << I->args_begin()->getSourceIndex();
1928 if (I->args_size())
1929 S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch)
1930 << Idx.getSourceIndex() << Ex->getSourceRange();
1931 return;
1932 }
1933 }
1934 }
1935 OwnershipArgs.push_back(Idx);
1936 }
1937
1938 ParamIdx *Start = OwnershipArgs.data();
1939 unsigned Size = OwnershipArgs.size();
1940 llvm::array_pod_sort(Start, Start + Size);
1941 D->addAttr(::new (S.Context)
1942 OwnershipAttr(S.Context, AL, Module, Start, Size));
1943}
1944
1945static void handleWeakRefAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1946 // Check the attribute arguments.
1947 if (AL.getNumArgs() > 1) {
1948 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
1949 return;
1950 }
1951
1952 // gcc rejects
1953 // class c {
1954 // static int a __attribute__((weakref ("v2")));
1955 // static int b() __attribute__((weakref ("f3")));
1956 // };
1957 // and ignores the attributes of
1958 // void f(void) {
1959 // static int a __attribute__((weakref ("v2")));
1960 // }
1961 // we reject them
1962 const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
1963 if (!Ctx->isFileContext()) {
1964 S.Diag(AL.getLoc(), diag::err_attribute_weakref_not_global_context)
1965 << cast<NamedDecl>(D);
1966 return;
1967 }
1968
1969 // The GCC manual says
1970 //
1971 // At present, a declaration to which `weakref' is attached can only
1972 // be `static'.
1973 //
1974 // It also says
1975 //
1976 // Without a TARGET,
1977 // given as an argument to `weakref' or to `alias', `weakref' is
1978 // equivalent to `weak'.
1979 //
1980 // gcc 4.4.1 will accept
1981 // int a7 __attribute__((weakref));
1982 // as
1983 // int a7 __attribute__((weak));
1984 // This looks like a bug in gcc. We reject that for now. We should revisit
1985 // it if this behaviour is actually used.
1986
1987 // GCC rejects
1988 // static ((alias ("y"), weakref)).
1989 // Should we? How to check that weakref is before or after alias?
1990
1991 // FIXME: it would be good for us to keep the WeakRefAttr as-written instead
1992 // of transforming it into an AliasAttr. The WeakRefAttr never uses the
1993 // StringRef parameter it was given anyway.
1994 StringRef Str;
1995 if (AL.getNumArgs() && S.checkStringLiteralArgumentAttr(AL, 0, Str))
1996 // GCC will accept anything as the argument of weakref. Should we
1997 // check for an existing decl?
1998 D->addAttr(::new (S.Context) AliasAttr(S.Context, AL, Str));
1999
2000 D->addAttr(::new (S.Context) WeakRefAttr(S.Context, AL));
2001}
2002
2003// Mark alias/ifunc target as used. Due to name mangling, we look up the
2004// demangled name ignoring parameters (not supported by microsoftDemangle
2005// https://github.com/llvm/llvm-project/issues/88825). This should handle the
2006// majority of use cases while leaving namespace scope names unmarked.
2007static void markUsedForAliasOrIfunc(Sema &S, Decl *D, const ParsedAttr &AL,
2008 StringRef Str) {
2009 std::unique_ptr<char, llvm::FreeDeleter> Demangled;
2010 if (S.getASTContext().getCXXABIKind() != TargetCXXABI::Microsoft)
2011 Demangled.reset(llvm::itaniumDemangle(Str, /*ParseParams=*/false));
2012 std::unique_ptr<MangleContext> MC(S.Context.createMangleContext());
2013 SmallString<256> Name;
2014
2016 &S.Context.Idents.get(Demangled ? Demangled.get() : Str), AL.getLoc());
2018 if (S.LookupName(LR, S.TUScope)) {
2019 for (NamedDecl *ND : LR) {
2020 if (!isa<FunctionDecl>(ND) && !isa<VarDecl>(ND))
2021 continue;
2022 if (MC->shouldMangleDeclName(ND)) {
2023 llvm::raw_svector_ostream Out(Name);
2024 Name.clear();
2025 MC->mangleName(GlobalDecl(ND), Out);
2026 } else {
2027 Name = ND->getIdentifier()->getName();
2028 }
2029 if (Name == Str)
2030 ND->markUsed(S.Context);
2031 }
2032 }
2033}
2034
2035static void handleIFuncAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2036 StringRef Str;
2037 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
2038 return;
2039
2040 // Aliases should be on declarations, not definitions.
2041 const auto *FD = cast<FunctionDecl>(D);
2042 if (FD->isThisDeclarationADefinition()) {
2043 S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 1;
2044 return;
2045 }
2046
2047 markUsedForAliasOrIfunc(S, D, AL, Str);
2048 D->addAttr(::new (S.Context) IFuncAttr(S.Context, AL, Str));
2049}
2050
2051static void handleAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2052 StringRef Str;
2053 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
2054 return;
2055
2056 if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
2057 S.Diag(AL.getLoc(), diag::err_alias_not_supported_on_darwin);
2058 return;
2059 }
2060
2061 if (S.Context.getTargetInfo().getTriple().isNVPTX()) {
2062 CudaVersion Version =
2064 if (Version != CudaVersion::UNKNOWN && Version < CudaVersion::CUDA_100)
2065 S.Diag(AL.getLoc(), diag::err_alias_not_supported_on_nvptx);
2066 }
2067
2068 // Aliases should be on declarations, not definitions.
2069 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
2070 if (FD->isThisDeclarationADefinition()) {
2071 S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 0;
2072 return;
2073 }
2074 } else {
2075 const auto *VD = cast<VarDecl>(D);
2076 if (VD->isThisDeclarationADefinition() && VD->isExternallyVisible()) {
2077 S.Diag(AL.getLoc(), diag::err_alias_is_definition) << VD << 0;
2078 return;
2079 }
2080 }
2081
2082 markUsedForAliasOrIfunc(S, D, AL, Str);
2083 D->addAttr(::new (S.Context) AliasAttr(S.Context, AL, Str));
2084}
2085
2086static void handleTLSModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2087 StringRef Model;
2088 SourceLocation LiteralLoc;
2089 // Check that it is a string.
2090 if (!S.checkStringLiteralArgumentAttr(AL, 0, Model, &LiteralLoc))
2091 return;
2092
2093 // Check that the value.
2094 if (Model != "global-dynamic" && Model != "local-dynamic"
2095 && Model != "initial-exec" && Model != "local-exec") {
2096 S.Diag(LiteralLoc, diag::err_attr_tlsmodel_arg);
2097 return;
2098 }
2099
2100 D->addAttr(::new (S.Context) TLSModelAttr(S.Context, AL, Model));
2101}
2102
2103static void handleRestrictAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2105 if (ResultType->isAnyPointerType() || ResultType->isBlockPointerType()) {
2106 D->addAttr(::new (S.Context) RestrictAttr(S.Context, AL));
2107 return;
2108 }
2109
2110 S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only)
2112}
2113
2114static void handleCPUSpecificAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2115 // Ensure we don't combine these with themselves, since that causes some
2116 // confusing behavior.
2117 if (AL.getParsedKind() == ParsedAttr::AT_CPUDispatch) {
2118 if (checkAttrMutualExclusion<CPUSpecificAttr>(S, D, AL))
2119 return;
2120
2121 if (const auto *Other = D->getAttr<CPUDispatchAttr>()) {
2122 S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL;
2123 S.Diag(Other->getLocation(), diag::note_conflicting_attribute);
2124 return;
2125 }
2126 } else if (AL.getParsedKind() == ParsedAttr::AT_CPUSpecific) {
2127 if (checkAttrMutualExclusion<CPUDispatchAttr>(S, D, AL))
2128 return;
2129
2130 if (const auto *Other = D->getAttr<CPUSpecificAttr>()) {
2131 S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL;
2132 S.Diag(Other->getLocation(), diag::note_conflicting_attribute);
2133 return;
2134 }
2135 }
2136
2137 FunctionDecl *FD = cast<FunctionDecl>(D);
2138
2139 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
2140 if (MD->getParent()->isLambda()) {
2141 S.Diag(AL.getLoc(), diag::err_attribute_dll_lambda) << AL;
2142 return;
2143 }
2144 }
2145
2146 if (!AL.checkAtLeastNumArgs(S, 1))
2147 return;
2148
2150 for (unsigned ArgNo = 0; ArgNo < getNumAttributeArgs(AL); ++ArgNo) {
2151 if (!AL.isArgIdent(ArgNo)) {
2152 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
2153 << AL << AANT_ArgumentIdentifier;
2154 return;
2155 }
2156
2157 IdentifierLoc *CPUArg = AL.getArgAsIdent(ArgNo);
2158 StringRef CPUName = CPUArg->Ident->getName().trim();
2159
2161 S.Diag(CPUArg->Loc, diag::err_invalid_cpu_specific_dispatch_value)
2162 << CPUName << (AL.getKind() == ParsedAttr::AT_CPUDispatch);
2163 return;
2164 }
2165
2167 if (llvm::any_of(CPUs, [CPUName, &Target](const IdentifierInfo *Cur) {
2168 return Target.CPUSpecificManglingCharacter(CPUName) ==
2169 Target.CPUSpecificManglingCharacter(Cur->getName());
2170 })) {
2171 S.Diag(AL.getLoc(), diag::warn_multiversion_duplicate_entries);
2172 return;
2173 }
2174 CPUs.push_back(CPUArg->Ident);
2175 }
2176
2177 FD->setIsMultiVersion(true);
2178 if (AL.getKind() == ParsedAttr::AT_CPUSpecific)
2179 D->addAttr(::new (S.Context)
2180 CPUSpecificAttr(S.Context, AL, CPUs.data(), CPUs.size()));
2181 else
2182 D->addAttr(::new (S.Context)
2183 CPUDispatchAttr(S.Context, AL, CPUs.data(), CPUs.size()));
2184}
2185
2186static void handleCommonAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2187 if (S.LangOpts.CPlusPlus) {
2188 S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)
2190 return;
2191 }
2192
2193 D->addAttr(::new (S.Context) CommonAttr(S.Context, AL));
2194}
2195
2196static void handleCmseNSEntryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2197 if (S.LangOpts.CPlusPlus && !D->getDeclContext()->isExternCContext()) {
2198 S.Diag(AL.getLoc(), diag::err_attribute_not_clinkage) << AL;
2199 return;
2200 }
2201
2202 const auto *FD = cast<FunctionDecl>(D);
2203 if (!FD->isExternallyVisible()) {
2204 S.Diag(AL.getLoc(), diag::warn_attribute_cmse_entry_static);
2205 return;
2206 }
2207
2208 D->addAttr(::new (S.Context) CmseNSEntryAttr(S.Context, AL));
2209}
2210
2211static void handleNakedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2212 if (AL.isDeclspecAttribute()) {
2213 const auto &Triple = S.getASTContext().getTargetInfo().getTriple();
2214 const auto &Arch = Triple.getArch();
2215 if (Arch != llvm::Triple::x86 &&
2216 (Arch != llvm::Triple::arm && Arch != llvm::Triple::thumb)) {
2217 S.Diag(AL.getLoc(), diag::err_attribute_not_supported_on_arch)
2218 << AL << Triple.getArchName();
2219 return;
2220 }
2221
2222 // This form is not allowed to be written on a member function (static or
2223 // nonstatic) when in Microsoft compatibility mode.
2224 if (S.getLangOpts().MSVCCompat && isa<CXXMethodDecl>(D)) {
2225 S.Diag(AL.getLoc(), diag::err_attribute_wrong_decl_type_str)
2226 << AL << AL.isRegularKeywordAttribute() << "non-member functions";
2227 return;
2228 }
2229 }
2230
2231 D->addAttr(::new (S.Context) NakedAttr(S.Context, AL));
2232}
2233
2234static void handleNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
2235 if (hasDeclarator(D)) return;
2236
2237 if (!isa<ObjCMethodDecl>(D)) {
2238 S.Diag(Attrs.getLoc(), diag::warn_attribute_wrong_decl_type)
2239 << Attrs << Attrs.isRegularKeywordAttribute()
2241 return;
2242 }
2243
2244 D->addAttr(::new (S.Context) NoReturnAttr(S.Context, Attrs));
2245}
2246
2247static void handleStandardNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &A) {
2248 // The [[_Noreturn]] spelling is deprecated in C23, so if that was used,
2249 // issue an appropriate diagnostic. However, don't issue a diagnostic if the
2250 // attribute name comes from a macro expansion. We don't want to punish users
2251 // who write [[noreturn]] after including <stdnoreturn.h> (where 'noreturn'
2252 // is defined as a macro which expands to '_Noreturn').
2253 if (!S.getLangOpts().CPlusPlus &&
2254 A.getSemanticSpelling() == CXX11NoReturnAttr::C23_Noreturn &&
2255 !(A.getLoc().isMacroID() &&
2257 S.Diag(A.getLoc(), diag::warn_deprecated_noreturn_spelling) << A.getRange();
2258
2259 D->addAttr(::new (S.Context) CXX11NoReturnAttr(S.Context, A));
2260}
2261
2262static void handleNoCfCheckAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
2263 if (!S.getLangOpts().CFProtectionBranch)
2264 S.Diag(Attrs.getLoc(), diag::warn_nocf_check_attribute_ignored);
2265 else
2266 handleSimpleAttribute<AnyX86NoCfCheckAttr>(S, D, Attrs);
2267}
2268
2270 if (!Attrs.checkExactlyNumArgs(*this, 0)) {
2271 Attrs.setInvalid();
2272 return true;
2273 }
2274
2275 return false;
2276}
2277
2279 // Check whether the attribute is valid on the current target.
2282 ? diag::err_keyword_not_supported_on_target
2283 : diag::warn_unknown_attribute_ignored)
2284 << AL << AL.getRange();
2285 AL.setInvalid();
2286 return true;
2287 }
2288
2289 return false;
2290}
2291
2292static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2293
2294 // The checking path for 'noreturn' and 'analyzer_noreturn' are different
2295 // because 'analyzer_noreturn' does not impact the type.
2296 if (!isFunctionOrMethodOrBlock(D)) {
2297 ValueDecl *VD = dyn_cast<ValueDecl>(D);
2298 if (!VD || (!VD->getType()->isBlockPointerType() &&
2299 !VD->getType()->isFunctionPointerType())) {
2301 ? diag::err_attribute_wrong_decl_type
2302 : diag::warn_attribute_wrong_decl_type)
2303 << AL << AL.isRegularKeywordAttribute()
2305 return;
2306 }
2307 }
2308
2309 D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(S.Context, AL));
2310}
2311
2312// PS3 PPU-specific.
2313static void handleVecReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2314 /*
2315 Returning a Vector Class in Registers
2316
2317 According to the PPU ABI specifications, a class with a single member of
2318 vector type is returned in memory when used as the return value of a
2319 function.
2320 This results in inefficient code when implementing vector classes. To return
2321 the value in a single vector register, add the vecreturn attribute to the
2322 class definition. This attribute is also applicable to struct types.
2323
2324 Example:
2325
2326 struct Vector
2327 {
2328 __vector float xyzw;
2329 } __attribute__((vecreturn));
2330
2331 Vector Add(Vector lhs, Vector rhs)
2332 {
2333 Vector result;
2334 result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
2335 return result; // This will be returned in a register
2336 }
2337 */
2338 if (VecReturnAttr *A = D->getAttr<VecReturnAttr>()) {
2339 S.Diag(AL.getLoc(), diag::err_repeat_attribute) << A;
2340 return;
2341 }
2342
2343 const auto *R = cast<RecordDecl>(D);
2344 int count = 0;
2345
2346 if (!isa<CXXRecordDecl>(R)) {
2347 S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
2348 return;
2349 }
2350
2351 if (!cast<CXXRecordDecl>(R)->isPOD()) {
2352 S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
2353 return;
2354 }
2355
2356 for (const auto *I : R->fields()) {
2357 if ((count == 1) || !I->getType()->isVectorType()) {
2358 S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
2359 return;
2360 }
2361 count++;
2362 }
2363
2364 D->addAttr(::new (S.Context) VecReturnAttr(S.Context, AL));
2365}
2366
2368 const ParsedAttr &AL) {
2369 if (isa<ParmVarDecl>(D)) {
2370 // [[carries_dependency]] can only be applied to a parameter if it is a
2371 // parameter of a function declaration or lambda.
2373 S.Diag(AL.getLoc(),
2374 diag::err_carries_dependency_param_not_function_decl);
2375 return;
2376 }
2377 }
2378
2379 D->addAttr(::new (S.Context) CarriesDependencyAttr(S.Context, AL));
2380}
2381
2382static void handleUnusedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2383 bool IsCXX17Attr = AL.isCXX11Attribute() && !AL.getScopeName();
2384
2385 // If this is spelled as the standard C++17 attribute, but not in C++17, warn
2386 // about using it as an extension.
2387 if (!S.getLangOpts().CPlusPlus17 && IsCXX17Attr)
2388 S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
2389
2390 D->addAttr(::new (S.Context) UnusedAttr(S.Context, AL));
2391}
2392
2393static void handleConstructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2394 uint32_t priority = ConstructorAttr::DefaultPriority;
2395 if (S.getLangOpts().HLSL && AL.getNumArgs()) {
2396 S.Diag(AL.getLoc(), diag::err_hlsl_init_priority_unsupported);
2397 return;
2398 }
2399 if (AL.getNumArgs() &&
2400 !checkUInt32Argument(S, AL, AL.getArgAsExpr(0), priority))
2401 return;
2402
2403 D->addAttr(::new (S.Context) ConstructorAttr(S.Context, AL, priority));
2404}
2405
2406static void handleDestructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2407 uint32_t priority = DestructorAttr::DefaultPriority;
2408 if (AL.getNumArgs() &&
2409 !checkUInt32Argument(S, AL, AL.getArgAsExpr(0), priority))
2410 return;
2411
2412 D->addAttr(::new (S.Context) DestructorAttr(S.Context, AL, priority));
2413}
2414
2415template <typename AttrTy>
2416static void handleAttrWithMessage(Sema &S, Decl *D, const ParsedAttr &AL) {
2417 // Handle the case where the attribute has a text message.
2418 StringRef Str;
2419 if (AL.getNumArgs() == 1 && !S.checkStringLiteralArgumentAttr(AL, 0, Str))
2420 return;
2421
2422 D->addAttr(::new (S.Context) AttrTy(S.Context, AL, Str));
2423}
2424
2426 const ParsedAttr &AL) {
2427 if (!cast<ObjCProtocolDecl>(D)->isThisDeclarationADefinition()) {
2428 S.Diag(AL.getLoc(), diag::err_objc_attr_protocol_requires_definition)
2429 << AL << AL.getRange();
2430 return;
2431 }
2432
2433 D->addAttr(::new (S.Context) ObjCExplicitProtocolImplAttr(S.Context, AL));
2434}
2435
2437 IdentifierInfo *Platform,
2438 VersionTuple Introduced,
2439 VersionTuple Deprecated,
2440 VersionTuple Obsoleted) {
2441 StringRef PlatformName
2442 = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
2443 if (PlatformName.empty())
2444 PlatformName = Platform->getName();
2445
2446 // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
2447 // of these steps are needed).
2448 if (!Introduced.empty() && !Deprecated.empty() &&
2449 !(Introduced <= Deprecated)) {
2450 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2451 << 1 << PlatformName << Deprecated.getAsString()
2452 << 0 << Introduced.getAsString();
2453 return true;
2454 }
2455
2456 if (!Introduced.empty() && !Obsoleted.empty() &&
2457 !(Introduced <= Obsoleted)) {
2458 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2459 << 2 << PlatformName << Obsoleted.getAsString()
2460 << 0 << Introduced.getAsString();
2461 return true;
2462 }
2463
2464 if (!Deprecated.empty() && !Obsoleted.empty() &&
2465 !(Deprecated <= Obsoleted)) {
2466 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2467 << 2 << PlatformName << Obsoleted.getAsString()
2468 << 1 << Deprecated.getAsString();
2469 return true;
2470 }
2471
2472 return false;
2473}
2474
2475/// Check whether the two versions match.
2476///
2477/// If either version tuple is empty, then they are assumed to match. If
2478/// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y.
2479static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y,
2480 bool BeforeIsOkay) {
2481 if (X.empty() || Y.empty())
2482 return true;
2483
2484 if (X == Y)
2485 return true;
2486
2487 if (BeforeIsOkay && X < Y)
2488 return true;
2489
2490 return false;
2491}
2492
2494 NamedDecl *D, const AttributeCommonInfo &CI, IdentifierInfo *Platform,
2495 bool Implicit, VersionTuple Introduced, VersionTuple Deprecated,
2496 VersionTuple Obsoleted, bool IsUnavailable, StringRef Message,
2497 bool IsStrict, StringRef Replacement, AvailabilityMergeKind AMK,
2498 int Priority) {
2499 VersionTuple MergedIntroduced = Introduced;
2500 VersionTuple MergedDeprecated = Deprecated;
2501 VersionTuple MergedObsoleted = Obsoleted;
2502 bool FoundAny = false;
2503 bool OverrideOrImpl = false;
2504 switch (AMK) {
2505 case AMK_None:
2506 case AMK_Redeclaration:
2507 OverrideOrImpl = false;
2508 break;
2509
2510 case AMK_Override:
2513 OverrideOrImpl = true;
2514 break;
2515 }
2516
2517 if (D->hasAttrs()) {
2518 AttrVec &Attrs = D->getAttrs();
2519 for (unsigned i = 0, e = Attrs.size(); i != e;) {
2520 const auto *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]);
2521 if (!OldAA) {
2522 ++i;
2523 continue;
2524 }
2525
2526 IdentifierInfo *OldPlatform = OldAA->getPlatform();
2527 if (OldPlatform != Platform) {
2528 ++i;
2529 continue;
2530 }
2531
2532 // If there is an existing availability attribute for this platform that
2533 // has a lower priority use the existing one and discard the new
2534 // attribute.
2535 if (OldAA->getPriority() < Priority)
2536 return nullptr;
2537
2538 // If there is an existing attribute for this platform that has a higher
2539 // priority than the new attribute then erase the old one and continue
2540 // processing the attributes.
2541 if (OldAA->getPriority() > Priority) {
2542 Attrs.erase(Attrs.begin() + i);
2543 --e;
2544 continue;
2545 }
2546
2547 FoundAny = true;
2548 VersionTuple OldIntroduced = OldAA->getIntroduced();
2549 VersionTuple OldDeprecated = OldAA->getDeprecated();
2550 VersionTuple OldObsoleted = OldAA->getObsoleted();
2551 bool OldIsUnavailable = OldAA->getUnavailable();
2552
2553 if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl) ||
2554 !versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl) ||
2555 !versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl) ||
2556 !(OldIsUnavailable == IsUnavailable ||
2557 (OverrideOrImpl && !OldIsUnavailable && IsUnavailable))) {
2558 if (OverrideOrImpl) {
2559 int Which = -1;
2560 VersionTuple FirstVersion;
2561 VersionTuple SecondVersion;
2562 if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl)) {
2563 Which = 0;
2564 FirstVersion = OldIntroduced;
2565 SecondVersion = Introduced;
2566 } else if (!versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl)) {
2567 Which = 1;
2568 FirstVersion = Deprecated;
2569 SecondVersion = OldDeprecated;
2570 } else if (!versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl)) {
2571 Which = 2;
2572 FirstVersion = Obsoleted;
2573 SecondVersion = OldObsoleted;
2574 }
2575
2576 if (Which == -1) {
2577 Diag(OldAA->getLocation(),
2578 diag::warn_mismatched_availability_override_unavail)
2579 << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
2580 << (AMK == AMK_Override);
2581 } else if (Which != 1 && AMK == AMK_OptionalProtocolImplementation) {
2582 // Allow different 'introduced' / 'obsoleted' availability versions
2583 // on a method that implements an optional protocol requirement. It
2584 // makes less sense to allow this for 'deprecated' as the user can't
2585 // see if the method is 'deprecated' as 'respondsToSelector' will
2586 // still return true when the method is deprecated.
2587 ++i;
2588 continue;
2589 } else {
2590 Diag(OldAA->getLocation(),
2591 diag::warn_mismatched_availability_override)
2592 << Which
2593 << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
2594 << FirstVersion.getAsString() << SecondVersion.getAsString()
2595 << (AMK == AMK_Override);
2596 }
2597 if (AMK == AMK_Override)
2598 Diag(CI.getLoc(), diag::note_overridden_method);
2599 else
2600 Diag(CI.getLoc(), diag::note_protocol_method);
2601 } else {
2602 Diag(OldAA->getLocation(), diag::warn_mismatched_availability);
2603 Diag(CI.getLoc(), diag::note_previous_attribute);
2604 }
2605
2606 Attrs.erase(Attrs.begin() + i);
2607 --e;
2608 continue;
2609 }
2610
2611 VersionTuple MergedIntroduced2 = MergedIntroduced;
2612 VersionTuple MergedDeprecated2 = MergedDeprecated;
2613 VersionTuple MergedObsoleted2 = MergedObsoleted;
2614
2615 if (MergedIntroduced2.empty())
2616 MergedIntroduced2 = OldIntroduced;
2617 if (MergedDeprecated2.empty())
2618 MergedDeprecated2 = OldDeprecated;
2619 if (MergedObsoleted2.empty())
2620 MergedObsoleted2 = OldObsoleted;
2621
2622 if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform,
2623 MergedIntroduced2, MergedDeprecated2,
2624 MergedObsoleted2)) {
2625 Attrs.erase(Attrs.begin() + i);
2626 --e;
2627 continue;
2628 }
2629
2630 MergedIntroduced = MergedIntroduced2;
2631 MergedDeprecated = MergedDeprecated2;
2632 MergedObsoleted = MergedObsoleted2;
2633 ++i;
2634 }
2635 }
2636
2637 if (FoundAny &&
2638 MergedIntroduced == Introduced &&
2639 MergedDeprecated == Deprecated &&
2640 MergedObsoleted == Obsoleted)
2641 return nullptr;
2642
2643 // Only create a new attribute if !OverrideOrImpl, but we want to do
2644 // the checking.
2645 if (!checkAvailabilityAttr(*this, CI.getRange(), Platform, MergedIntroduced,
2646 MergedDeprecated, MergedObsoleted) &&
2647 !OverrideOrImpl) {
2648 auto *Avail = ::new (Context) AvailabilityAttr(
2649 Context, CI, Platform, Introduced, Deprecated, Obsoleted, IsUnavailable,
2650 Message, IsStrict, Replacement, Priority);
2651 Avail->setImplicit(Implicit);
2652 return Avail;
2653 }
2654 return nullptr;
2655}
2656
2657static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2658 if (isa<UsingDecl, UnresolvedUsingTypenameDecl, UnresolvedUsingValueDecl>(
2659 D)) {
2660 S.Diag(AL.getRange().getBegin(), diag::warn_deprecated_ignored_on_using)
2661 << AL;
2662 return;
2663 }
2664
2665 if (!AL.checkExactlyNumArgs(S, 1))
2666 return;
2667 IdentifierLoc *Platform = AL.getArgAsIdent(0);
2668
2669 IdentifierInfo *II = Platform->Ident;
2670 if (AvailabilityAttr::getPrettyPlatformName(II->getName()).empty())
2671 S.Diag(Platform->Loc, diag::warn_availability_unknown_platform)
2672 << Platform->Ident;
2673
2674 auto *ND = dyn_cast<NamedDecl>(D);
2675 if (!ND) // We warned about this already, so just return.
2676 return;
2677
2681 bool IsUnavailable = AL.getUnavailableLoc().isValid();
2682 bool IsStrict = AL.getStrictLoc().isValid();
2683 StringRef Str;
2684 if (const auto *SE = dyn_cast_if_present<StringLiteral>(AL.getMessageExpr()))
2685 Str = SE->getString();
2686 StringRef Replacement;
2687 if (const auto *SE =
2688 dyn_cast_if_present<StringLiteral>(AL.getReplacementExpr()))
2689 Replacement = SE->getString();
2690
2691 if (II->isStr("swift")) {
2692 if (Introduced.isValid() || Obsoleted.isValid() ||
2693 (!IsUnavailable && !Deprecated.isValid())) {
2694 S.Diag(AL.getLoc(),
2695 diag::warn_availability_swift_unavailable_deprecated_only);
2696 return;
2697 }
2698 }
2699
2700 if (II->isStr("fuchsia")) {
2701 std::optional<unsigned> Min, Sub;
2702 if ((Min = Introduced.Version.getMinor()) ||
2703 (Sub = Introduced.Version.getSubminor())) {
2704 S.Diag(AL.getLoc(), diag::warn_availability_fuchsia_unavailable_minor);
2705 return;
2706 }
2707 }
2708
2709 int PriorityModifier = AL.isPragmaClangAttribute()
2712 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2713 ND, AL, II, false /*Implicit*/, Introduced.Version, Deprecated.Version,
2714 Obsoleted.Version, IsUnavailable, Str, IsStrict, Replacement,
2715 Sema::AMK_None, PriorityModifier);
2716 if (NewAttr)
2717 D->addAttr(NewAttr);
2718
2719 // Transcribe "ios" to "watchos" (and add a new attribute) if the versioning
2720 // matches before the start of the watchOS platform.
2721 if (S.Context.getTargetInfo().getTriple().isWatchOS()) {
2722 IdentifierInfo *NewII = nullptr;
2723 if (II->getName() == "ios")
2724 NewII = &S.Context.Idents.get("watchos");
2725 else if (II->getName() == "ios_app_extension")
2726 NewII = &S.Context.Idents.get("watchos_app_extension");
2727
2728 if (NewII) {
2729 const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking();
2730 const auto *IOSToWatchOSMapping =
2731 SDKInfo ? SDKInfo->getVersionMapping(
2733 : nullptr;
2734
2735 auto adjustWatchOSVersion =
2736 [IOSToWatchOSMapping](VersionTuple Version) -> VersionTuple {
2737 if (Version.empty())
2738 return Version;
2739 auto MinimumWatchOSVersion = VersionTuple(2, 0);
2740
2741 if (IOSToWatchOSMapping) {
2742 if (auto MappedVersion = IOSToWatchOSMapping->map(
2743 Version, MinimumWatchOSVersion, std::nullopt)) {
2744 return *MappedVersion;
2745 }
2746 }
2747
2748 auto Major = Version.getMajor();
2749 auto NewMajor = Major >= 9 ? Major - 7 : 0;
2750 if (NewMajor >= 2) {
2751 if (Version.getMinor()) {
2752 if (Version.getSubminor())
2753 return VersionTuple(NewMajor, *Version.getMinor(),
2754 *Version.getSubminor());
2755 else
2756 return VersionTuple(NewMajor, *Version.getMinor());
2757 }
2758 return VersionTuple(NewMajor);
2759 }
2760
2761 return MinimumWatchOSVersion;
2762 };
2763
2764 auto NewIntroduced = adjustWatchOSVersion(Introduced.Version);
2765 auto NewDeprecated = adjustWatchOSVersion(Deprecated.Version);
2766 auto NewObsoleted = adjustWatchOSVersion(Obsoleted.Version);
2767
2768 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2769 ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
2770 NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,
2772 PriorityModifier + Sema::AP_InferredFromOtherPlatform);
2773 if (NewAttr)
2774 D->addAttr(NewAttr);
2775 }
2776 } else if (S.Context.getTargetInfo().getTriple().isTvOS()) {
2777 // Transcribe "ios" to "tvos" (and add a new attribute) if the versioning
2778 // matches before the start of the tvOS platform.
2779 IdentifierInfo *NewII = nullptr;
2780 if (II->getName() == "ios")
2781 NewII = &S.Context.Idents.get("tvos");
2782 else if (II->getName() == "ios_app_extension")
2783 NewII = &S.Context.Idents.get("tvos_app_extension");
2784
2785 if (NewII) {
2786 const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking();
2787 const auto *IOSToTvOSMapping =
2788 SDKInfo ? SDKInfo->getVersionMapping(
2790 : nullptr;
2791
2792 auto AdjustTvOSVersion =
2793 [IOSToTvOSMapping](VersionTuple Version) -> VersionTuple {
2794 if (Version.empty())
2795 return Version;
2796
2797 if (IOSToTvOSMapping) {
2798 if (auto MappedVersion = IOSToTvOSMapping->map(
2799 Version, VersionTuple(0, 0), std::nullopt)) {
2800 return *MappedVersion;
2801 }
2802 }
2803 return Version;
2804 };
2805
2806 auto NewIntroduced = AdjustTvOSVersion(Introduced.Version);
2807 auto NewDeprecated = AdjustTvOSVersion(Deprecated.Version);
2808 auto NewObsoleted = AdjustTvOSVersion(Obsoleted.Version);
2809
2810 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2811 ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
2812 NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,
2814 PriorityModifier + Sema::AP_InferredFromOtherPlatform);
2815 if (NewAttr)
2816 D->addAttr(NewAttr);
2817 }
2818 } else if (S.Context.getTargetInfo().getTriple().getOS() ==
2819 llvm::Triple::IOS &&
2820 S.Context.getTargetInfo().getTriple().isMacCatalystEnvironment()) {
2821 auto GetSDKInfo = [&]() {
2823 "macOS");
2824 };
2825
2826 // Transcribe "ios" to "maccatalyst" (and add a new attribute).
2827 IdentifierInfo *NewII = nullptr;
2828 if (II->getName() == "ios")
2829 NewII = &S.Context.Idents.get("maccatalyst");
2830 else if (II->getName() == "ios_app_extension")
2831 NewII = &S.Context.Idents.get("maccatalyst_app_extension");
2832 if (NewII) {
2833 auto MinMacCatalystVersion = [](const VersionTuple &V) {
2834 if (V.empty())
2835 return V;
2836 if (V.getMajor() < 13 ||
2837 (V.getMajor() == 13 && V.getMinor() && *V.getMinor() < 1))
2838 return VersionTuple(13, 1); // The min Mac Catalyst version is 13.1.
2839 return V;
2840 };
2841 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2842 ND, AL, NewII, true /*Implicit*/,
2843 MinMacCatalystVersion(Introduced.Version),
2844 MinMacCatalystVersion(Deprecated.Version),
2845 MinMacCatalystVersion(Obsoleted.Version), IsUnavailable, Str,
2846 IsStrict, Replacement, Sema::AMK_None,
2847 PriorityModifier + Sema::AP_InferredFromOtherPlatform);
2848 if (NewAttr)
2849 D->addAttr(NewAttr);
2850 } else if (II->getName() == "macos" && GetSDKInfo() &&
2851 (!Introduced.Version.empty() || !Deprecated.Version.empty() ||
2852 !Obsoleted.Version.empty())) {
2853 if (const auto *MacOStoMacCatalystMapping =
2854 GetSDKInfo()->getVersionMapping(
2856 // Infer Mac Catalyst availability from the macOS availability attribute
2857 // if it has versioned availability. Don't infer 'unavailable'. This
2858 // inferred availability has lower priority than the other availability
2859 // attributes that are inferred from 'ios'.
2860 NewII = &S.Context.Idents.get("maccatalyst");
2861 auto RemapMacOSVersion =
2862 [&](const VersionTuple &V) -> std::optional<VersionTuple> {
2863 if (V.empty())
2864 return std::nullopt;
2865 // API_TO_BE_DEPRECATED is 100000.
2866 if (V.getMajor() == 100000)
2867 return VersionTuple(100000);
2868 // The minimum iosmac version is 13.1
2869 return MacOStoMacCatalystMapping->map(V, VersionTuple(13, 1),
2870 std::nullopt);
2871 };
2872 std::optional<VersionTuple> NewIntroduced =
2873 RemapMacOSVersion(Introduced.Version),
2874 NewDeprecated =
2875 RemapMacOSVersion(Deprecated.Version),
2876 NewObsoleted =
2877 RemapMacOSVersion(Obsoleted.Version);
2878 if (NewIntroduced || NewDeprecated || NewObsoleted) {
2879 auto VersionOrEmptyVersion =
2880 [](const std::optional<VersionTuple> &V) -> VersionTuple {
2881 return V ? *V : VersionTuple();
2882 };
2883 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2884 ND, AL, NewII, true /*Implicit*/,
2885 VersionOrEmptyVersion(NewIntroduced),
2886 VersionOrEmptyVersion(NewDeprecated),
2887 VersionOrEmptyVersion(NewObsoleted), /*IsUnavailable=*/false, Str,
2888 IsStrict, Replacement, Sema::AMK_None,
2889 PriorityModifier + Sema::AP_InferredFromOtherPlatform +
2891 if (NewAttr)
2892 D->addAttr(NewAttr);
2893 }
2894 }
2895 }
2896 }
2897}
2898
2900 const ParsedAttr &AL) {
2901 if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 4))
2902 return;
2903
2904 StringRef Language;
2905 if (const auto *SE = dyn_cast_if_present<StringLiteral>(AL.getArgAsExpr(0)))
2906 Language = SE->getString();
2907 StringRef DefinedIn;
2908 if (const auto *SE = dyn_cast_if_present<StringLiteral>(AL.getArgAsExpr(1)))
2909 DefinedIn = SE->getString();
2910 bool IsGeneratedDeclaration = AL.getArgAsIdent(2) != nullptr;
2911 StringRef USR;
2912 if (const auto *SE = dyn_cast_if_present<StringLiteral>(AL.getArgAsExpr(3)))
2913 USR = SE->getString();
2914
2915 D->addAttr(::new (S.Context) ExternalSourceSymbolAttr(
2916 S.Context, AL, Language, DefinedIn, IsGeneratedDeclaration, USR));
2917}
2918
2919template <class T>
2921 typename T::VisibilityType value) {
2922 T *existingAttr = D->getAttr<T>();
2923 if (existingAttr) {
2924 typename T::VisibilityType existingValue = existingAttr->getVisibility();
2925 if (existingValue == value)
2926 return nullptr;
2927 S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
2928 S.Diag(CI.getLoc(), diag::note_previous_attribute);
2929 D->dropAttr<T>();
2930 }
2931 return ::new (S.Context) T(S.Context, CI, value);
2932}
2933
2935 const AttributeCommonInfo &CI,
2936 VisibilityAttr::VisibilityType Vis) {
2937 return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, CI, Vis);
2938}
2939
2940TypeVisibilityAttr *
2942 TypeVisibilityAttr::VisibilityType Vis) {
2943 return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, CI, Vis);
2944}
2945
2946static void handleVisibilityAttr(Sema &S, Decl *D, const ParsedAttr &AL,
2947 bool isTypeVisibility) {
2948 // Visibility attributes don't mean anything on a typedef.
2949 if (isa<TypedefNameDecl>(D)) {
2950 S.Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored) << AL;
2951 return;
2952 }
2953
2954 // 'type_visibility' can only go on a type or namespace.
2955 if (isTypeVisibility && !(isa<TagDecl>(D) || isa<ObjCInterfaceDecl>(D) ||
2956 isa<NamespaceDecl>(D))) {
2957 S.Diag(AL.getRange().getBegin(), diag::err_attribute_wrong_decl_type)
2959 return;
2960 }
2961
2962 // Check that the argument is a string literal.
2963 StringRef TypeStr;
2964 SourceLocation LiteralLoc;
2965 if (!S.checkStringLiteralArgumentAttr(AL, 0, TypeStr, &LiteralLoc))
2966 return;
2967
2968 VisibilityAttr::VisibilityType type;
2969 if (!VisibilityAttr::ConvertStrToVisibilityType(TypeStr, type)) {
2970 S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported) << AL
2971 << TypeStr;
2972 return;
2973 }
2974
2975 // Complain about attempts to use protected visibility on targets
2976 // (like Darwin) that don't support it.
2977 if (type == VisibilityAttr::Protected &&
2979 S.Diag(AL.getLoc(), diag::warn_attribute_protected_visibility);
2980 type = VisibilityAttr::Default;
2981 }
2982
2983 Attr *newAttr;
2984 if (isTypeVisibility) {
2985 newAttr = S.mergeTypeVisibilityAttr(
2986 D, AL, (TypeVisibilityAttr::VisibilityType)type);
2987 } else {
2988 newAttr = S.mergeVisibilityAttr(D, AL, type);
2989 }
2990 if (newAttr)
2991 D->addAttr(newAttr);
2992}
2993
2994static void handleObjCDirectAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2995 // objc_direct cannot be set on methods declared in the context of a protocol
2996 if (isa<ObjCProtocolDecl>(D->getDeclContext())) {
2997 S.Diag(AL.getLoc(), diag::err_objc_direct_on_protocol) << false;
2998 return;
2999 }
3000
3002 handleSimpleAttribute<ObjCDirectAttr>(S, D, AL);
3003 } else {
3004 S.Diag(AL.getLoc(), diag::warn_objc_direct_ignored) << AL;
3005 }
3006}
3007
3009 const ParsedAttr &AL) {
3011 handleSimpleAttribute<ObjCDirectMembersAttr>(S, D, AL);
3012 } else {
3013 S.Diag(AL.getLoc(), diag::warn_objc_direct_ignored) << AL;
3014 }
3015}
3016
3017static void handleObjCMethodFamilyAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3018 const auto *M = cast<ObjCMethodDecl>(D);
3019 if (!AL.isArgIdent(0)) {
3020 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3021 << AL << 1 << AANT_ArgumentIdentifier;
3022 return;
3023 }
3024
3025 IdentifierLoc *IL = AL.getArgAsIdent(0);
3026 ObjCMethodFamilyAttr::FamilyKind F;
3027 if (!ObjCMethodFamilyAttr::ConvertStrToFamilyKind(IL->Ident->getName(), F)) {
3028 S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL << IL->Ident;
3029 return;
3030 }
3031
3032 if (F == ObjCMethodFamilyAttr::OMF_init &&
3033 !M->getReturnType()->isObjCObjectPointerType()) {
3034 S.Diag(M->getLocation(), diag::err_init_method_bad_return_type)
3035 << M->getReturnType();
3036 // Ignore the attribute.
3037 return;
3038 }
3039
3040 D->addAttr(new (S.Context) ObjCMethodFamilyAttr(S.Context, AL, F));
3041}
3042
3043static void handleObjCNSObject(Sema &S, Decl *D, const ParsedAttr &AL) {
3044 if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) {
3045 QualType T = TD->getUnderlyingType();
3046 if (!T->isCARCBridgableType()) {
3047 S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
3048 return;
3049 }
3050 }
3051 else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) {
3052 QualType T = PD->getType();
3053 if (!T->isCARCBridgableType()) {
3054 S.Diag(PD->getLocation(), diag::err_nsobject_attribute);
3055 return;
3056 }
3057 }
3058 else {
3059 // It is okay to include this attribute on properties, e.g.:
3060 //
3061 // @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
3062 //
3063 // In this case it follows tradition and suppresses an error in the above
3064 // case.
3065 S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
3066 }
3067 D->addAttr(::new (S.Context) ObjCNSObjectAttr(S.Context, AL));
3068}
3069
3070static void handleObjCIndependentClass(Sema &S, Decl *D, const ParsedAttr &AL) {
3071 if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) {
3072 QualType T = TD->getUnderlyingType();
3073 if (!T->isObjCObjectPointerType()) {
3074 S.Diag(TD->getLocation(), diag::warn_ptr_independentclass_attribute);
3075 return;
3076 }
3077 } else {
3078 S.Diag(D->getLocation(), diag::warn_independentclass_attribute);
3079 return;
3080 }
3081 D->addAttr(::new (S.Context) ObjCIndependentClassAttr(S.Context, AL));
3082}
3083
3084static void handleBlocksAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3085 if (!AL.isArgIdent(0)) {
3086 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3087 << AL << 1 << AANT_ArgumentIdentifier;
3088 return;
3089 }
3090
3091 IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
3092 BlocksAttr::BlockType type;
3093 if (!BlocksAttr::ConvertStrToBlockType(II->getName(), type)) {
3094 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
3095 return;
3096 }
3097
3098 D->addAttr(::new (S.Context) BlocksAttr(S.Context, AL, type));
3099}
3100
3101static void handleSentinelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3102 unsigned sentinel = (unsigned)SentinelAttr::DefaultSentinel;
3103 if (AL.getNumArgs() > 0) {
3104 Expr *E = AL.getArgAsExpr(0);
3105 std::optional<llvm::APSInt> Idx = llvm::APSInt(32);
3106 if (E->isTypeDependent() || !(Idx = E->getIntegerConstantExpr(S.Context))) {
3107 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3108 << AL << 1 << AANT_ArgumentIntegerConstant << E->getSourceRange();
3109 return;
3110 }
3111
3112 if (Idx->isSigned() && Idx->isNegative()) {
3113 S.Diag(AL.getLoc(), diag::err_attribute_sentinel_less_than_zero)
3114 << E->getSourceRange();
3115 return;
3116 }
3117
3118 sentinel = Idx->getZExtValue();
3119 }
3120
3121 unsigned nullPos = (unsigned)SentinelAttr::DefaultNullPos;
3122 if (AL.getNumArgs() > 1) {
3123 Expr *E = AL.getArgAsExpr(1);
3124 std::optional<llvm::APSInt> Idx = llvm::APSInt(32);
3125 if (E->isTypeDependent() || !(Idx = E->getIntegerConstantExpr(S.Context))) {
3126 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3127 << AL << 2 << AANT_ArgumentIntegerConstant << E->getSourceRange();
3128 return;
3129 }
3130 nullPos = Idx->getZExtValue();
3131
3132 if ((Idx->isSigned() && Idx->isNegative()) || nullPos > 1) {
3133 // FIXME: This error message could be improved, it would be nice
3134 // to say what the bounds actually are.
3135 S.Diag(AL.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
3136 << E->getSourceRange();
3137 return;
3138 }
3139 }
3140
3141 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3142 const FunctionType *FT = FD->getType()->castAs<FunctionType>();
3143 if (isa<FunctionNoProtoType>(FT)) {
3144 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_named_arguments);
3145 return;
3146 }
3147
3148 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
3149 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
3150 return;
3151 }
3152 } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
3153 if (!MD->isVariadic()) {
3154 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
3155 return;
3156 }
3157 } else if (const auto *BD = dyn_cast<BlockDecl>(D)) {
3158 if (!BD->isVariadic()) {
3159 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
3160 return;
3161 }
3162 } else if (const auto *V = dyn_cast<VarDecl>(D)) {
3163 QualType Ty = V->getType();
3164 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
3165 const FunctionType *FT = Ty->isFunctionPointerType()
3166 ? D->getFunctionType()
3167 : Ty->castAs<BlockPointerType>()
3168 ->getPointeeType()
3169 ->castAs<FunctionType>();
3170 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
3171 int m = Ty->isFunctionPointerType() ? 0 : 1;
3172 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
3173 return;
3174 }
3175 } else {
3176 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
3177 << AL << AL.isRegularKeywordAttribute()
3179 return;
3180 }
3181 } else {
3182 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
3183 << AL << AL.isRegularKeywordAttribute()
3185 return;
3186 }
3187 D->addAttr(::new (S.Context) SentinelAttr(S.Context, AL, sentinel, nullPos));
3188}
3189
3190static void handleWarnUnusedResult(Sema &S, Decl *D, const ParsedAttr &AL) {
3191 if (D->getFunctionType() &&
3193 !isa<CXXConstructorDecl>(D)) {
3194 S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) << AL << 0;
3195 return;
3196 }
3197 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
3198 if (MD->getReturnType()->isVoidType()) {
3199 S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) << AL << 1;
3200 return;
3201 }
3202
3203 StringRef Str;
3204 if (AL.isStandardAttributeSyntax() && !AL.getScopeName()) {
3205 // The standard attribute cannot be applied to variable declarations such
3206 // as a function pointer.
3207 if (isa<VarDecl>(D))
3208 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type_str)
3209 << AL << AL.isRegularKeywordAttribute()
3210 << "functions, classes, or enumerations";
3211
3212 // If this is spelled as the standard C++17 attribute, but not in C++17,
3213 // warn about using it as an extension. If there are attribute arguments,
3214 // then claim it's a C++20 extension instead.
3215 // FIXME: If WG14 does not seem likely to adopt the same feature, add an
3216 // extension warning for C23 mode.
3217 const LangOptions &LO = S.getLangOpts();
3218 if (AL.getNumArgs() == 1) {
3219 if (LO.CPlusPlus && !LO.CPlusPlus20)
3220 S.Diag(AL.getLoc(), diag::ext_cxx20_attr) << AL;
3221
3222 // Since this is spelled [[nodiscard]], get the optional string
3223 // literal. If in C++ mode, but not in C++20 mode, diagnose as an
3224 // extension.
3225 // FIXME: C23 should support this feature as well, even as an extension.
3226 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, nullptr))
3227 return;
3228 } else if (LO.CPlusPlus && !LO.CPlusPlus17)
3229 S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
3230 }
3231
3232 if ((!AL.isGNUAttribute() &&
3233 !(AL.isStandardAttributeSyntax() && AL.isClangScope())) &&
3234 isa<TypedefNameDecl>(D)) {
3235 S.Diag(AL.getLoc(), diag::warn_unused_result_typedef_unsupported_spelling)
3236 << AL.isGNUScope();
3237 return;
3238 }
3239
3240 D->addAttr(::new (S.Context) WarnUnusedResultAttr(S.Context, AL, Str));
3241}
3242
3243static void handleWeakImportAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3244 // weak_import only applies to variable & function declarations.
3245 bool isDef = false;
3246 if (!D->canBeWeakImported(isDef)) {
3247 if (isDef)
3248 S.Diag(AL.getLoc(), diag::warn_attribute_invalid_on_definition)
3249 << "weak_import";
3250 else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
3251 (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
3252 (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) {
3253 // Nothing to warn about here.
3254 } else
3255 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
3257
3258 return;
3259 }
3260
3261 D->addAttr(::new (S.Context) WeakImportAttr(S.Context, AL));
3262}
3263
3264// Handles reqd_work_group_size and work_group_size_hint.
3265template <typename WorkGroupAttr>
3266static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
3267 uint32_t WGSize[3];
3268 for (unsigned i = 0; i < 3; ++i) {
3269 const Expr *E = AL.getArgAsExpr(i);
3270 if (!checkUInt32Argument(S, AL, E, WGSize[i], i,
3271 /*StrictlyUnsigned=*/true))
3272 return;
3273 if (WGSize[i] == 0) {
3274 S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
3275 << AL << E->getSourceRange();
3276 return;
3277 }
3278 }
3279
3280 WorkGroupAttr *Existing = D->getAttr<WorkGroupAttr>();
3281 if (Existing && !(Existing->getXDim() == WGSize[0] &&
3282 Existing->getYDim() == WGSize[1] &&
3283 Existing->getZDim() == WGSize[2]))
3284 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3285
3286 D->addAttr(::new (S.Context)
3287 WorkGroupAttr(S.Context, AL, WGSize[0], WGSize[1], WGSize[2]));
3288}
3289
3290// Handles intel_reqd_sub_group_size.
3291static void handleSubGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
3292 uint32_t SGSize;
3293 const Expr *E = AL.getArgAsExpr(0);
3294 if (!checkUInt32Argument(S, AL, E, SGSize))
3295 return;
3296 if (SGSize == 0) {
3297 S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
3298 << AL << E->getSourceRange();
3299 return;
3300 }
3301
3302 OpenCLIntelReqdSubGroupSizeAttr *Existing =
3303 D->getAttr<OpenCLIntelReqdSubGroupSizeAttr>();
3304 if (Existing && Existing->getSubGroupSize() != SGSize)
3305 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3306
3307 D->addAttr(::new (S.Context)
3308 OpenCLIntelReqdSubGroupSizeAttr(S.Context, AL, SGSize));
3309}
3310
3311static void handleVecTypeHint(Sema &S, Decl *D, const ParsedAttr &AL) {
3312 if (!AL.hasParsedType()) {
3313 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
3314 return;
3315 }
3316
3317 TypeSourceInfo *ParmTSI = nullptr;
3318 QualType ParmType = S.GetTypeFromParser(AL.getTypeArg(), &ParmTSI);
3319 assert(ParmTSI && "no type source info for attribute argument");
3320
3321 if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() &&
3322 (ParmType->isBooleanType() ||
3323 !ParmType->isIntegralType(S.getASTContext()))) {
3324 S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument) << 2 << AL;
3325 return;
3326 }
3327
3328 if (VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>()) {
3329 if (!S.Context.hasSameType(A->getTypeHint(), ParmType)) {
3330 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3331 return;
3332 }
3333 }
3334
3335 D->addAttr(::new (S.Context) VecTypeHintAttr(S.Context, AL, ParmTSI));
3336}
3337
3339 StringRef Name) {
3340 // Explicit or partial specializations do not inherit
3341 // the section attribute from the primary template.
3342 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3343 if (CI.getAttributeSpellingListIndex() == SectionAttr::Declspec_allocate &&
3345 return nullptr;
3346 }
3347 if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
3348 if (ExistingAttr->getName() == Name)
3349 return nullptr;
3350 Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section)
3351 << 1 /*section*/;
3352 Diag(CI.getLoc(), diag::note_previous_attribute);
3353 return nullptr;
3354 }
3355 return ::new (Context) SectionAttr(Context, CI, Name);
3356}
3357
3358/// Used to implement to perform semantic checking on
3359/// attribute((section("foo"))) specifiers.
3360///
3361/// In this case, "foo" is passed in to be checked. If the section
3362/// specifier is invalid, return an Error that indicates the problem.
3363///
3364/// This is a simple quality of implementation feature to catch errors
3365/// and give good diagnostics in cases when the assembler or code generator
3366/// would otherwise reject the section specifier.
3367llvm::Error Sema::isValidSectionSpecifier(StringRef SecName) {
3368 if (!Context.getTargetInfo().getTriple().isOSDarwin())
3369 return llvm::Error::success();
3370
3371 // Let MCSectionMachO validate this.
3372 StringRef Segment, Section;
3373 unsigned TAA, StubSize;
3374 bool HasTAA;
3375 return llvm::MCSectionMachO::ParseSectionSpecifier(SecName, Segment, Section,
3376 TAA, HasTAA, StubSize);
3377}
3378
3379bool Sema::checkSectionName(SourceLocation LiteralLoc, StringRef SecName) {
3380 if (llvm::Error E = isValidSectionSpecifier(SecName)) {
3381 Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
3382 << toString(std::move(E)) << 1 /*'section'*/;
3383 return false;
3384 }
3385 return true;
3386}
3387
3388static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3389 // Make sure that there is a string literal as the sections's single
3390 // argument.
3391 StringRef Str;
3392 SourceLocation LiteralLoc;
3393 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))
3394 return;
3395
3396 if (!S.checkSectionName(LiteralLoc, Str))
3397 return;
3398
3399 SectionAttr *NewAttr = S.mergeSectionAttr(D, AL, Str);
3400 if (NewAttr) {
3401 D->addAttr(NewAttr);
3403 ObjCPropertyDecl>(D))
3404 S.UnifySection(NewAttr->getName(),
3406 cast<NamedDecl>(D));
3407 }
3408}
3409
3410static void handleCodeModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3411 StringRef Str;
3412 SourceLocation LiteralLoc;
3413 // Check that it is a string.
3414 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))
3415 return;
3416
3417 llvm::CodeModel::Model CM;
3418 if (!CodeModelAttr::ConvertStrToModel(Str, CM)) {
3419 S.Diag(LiteralLoc, diag::err_attr_codemodel_arg) << Str;
3420 return;
3421 }
3422
3423 D->addAttr(::new (S.Context) CodeModelAttr(S.Context, AL, CM));
3424}
3425
3426// This is used for `__declspec(code_seg("segname"))` on a decl.
3427// `#pragma code_seg("segname")` uses checkSectionName() instead.
3428static bool checkCodeSegName(Sema &S, SourceLocation LiteralLoc,
3429 StringRef CodeSegName) {
3430 if (llvm::Error E = S.isValidSectionSpecifier(CodeSegName)) {
3431 S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
3432 << toString(std::move(E)) << 0 /*'code-seg'*/;
3433 return false;
3434 }
3435
3436 return true;
3437}
3438
3440 StringRef Name) {
3441 // Explicit or partial specializations do not inherit
3442 // the code_seg attribute from the primary template.
3443 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3445 return nullptr;
3446 }
3447 if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) {
3448 if (ExistingAttr->getName() == Name)
3449 return nullptr;
3450 Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section)
3451 << 0 /*codeseg*/;
3452 Diag(CI.getLoc(), diag::note_previous_attribute);
3453 return nullptr;
3454 }
3455 return ::new (Context) CodeSegAttr(Context, CI, Name);
3456}
3457
3458static void handleCodeSegAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3459 StringRef Str;
3460 SourceLocation LiteralLoc;
3461 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))
3462 return;
3463 if (!checkCodeSegName(S, LiteralLoc, Str))
3464 return;
3465 if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) {
3466 if (!ExistingAttr->isImplicit()) {
3467 S.Diag(AL.getLoc(),
3468 ExistingAttr->getName() == Str
3469 ? diag::warn_duplicate_codeseg_attribute
3470 : diag::err_conflicting_codeseg_attribute);
3471 return;
3472 }
3473 D->dropAttr<CodeSegAttr>();
3474 }
3475 if (CodeSegAttr *CSA = S.mergeCodeSegAttr(D, AL, Str))
3476 D->addAttr(CSA);
3477}
3478
3479// Check for things we'd like to warn about. Multiversioning issues are
3480// handled later in the process, once we know how many exist.
3481bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) {
3482 enum FirstParam { Unsupported, Duplicate, Unknown };
3483 enum SecondParam { None, CPU, Tune };
3484 enum ThirdParam { Target, TargetClones };
3485 if (AttrStr.contains("fpmath="))
3486 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3487 << Unsupported << None << "fpmath=" << Target;
3488
3489 // Diagnose use of tune if target doesn't support it.
3491 AttrStr.contains("tune="))
3492 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3493 << Unsupported << None << "tune=" << Target;
3494
3495 ParsedTargetAttr ParsedAttrs =
3497
3498 if (!ParsedAttrs.CPU.empty() &&
3499 !Context.getTargetInfo().isValidCPUName(ParsedAttrs.CPU))
3500 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3501 << Unknown << CPU << ParsedAttrs.CPU << Target;
3502
3503 if (!ParsedAttrs.Tune.empty() &&
3504 !Context.getTargetInfo().isValidCPUName(ParsedAttrs.Tune))
3505 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3506 << Unknown << Tune << ParsedAttrs.Tune << Target;
3507
3508 if (Context.getTargetInfo().getTriple().isRISCV() &&
3509 ParsedAttrs.Duplicate != "")
3510 return Diag(LiteralLoc, diag::err_duplicate_target_attribute)
3511 << Duplicate << None << ParsedAttrs.Duplicate << Target;
3512
3513 if (ParsedAttrs.Duplicate != "")
3514 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3515 << Duplicate << None << ParsedAttrs.Duplicate << Target;
3516
3517 for (const auto &Feature : ParsedAttrs.Features) {
3518 auto CurFeature = StringRef(Feature).drop_front(); // remove + or -.
3519 if (!Context.getTargetInfo().isValidFeatureName(CurFeature))
3520 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3521 << Unsupported << None << CurFeature << Target;
3522 }
3523
3525 StringRef DiagMsg;
3526 if (ParsedAttrs.BranchProtection.empty())
3527 return false;
3529 ParsedAttrs.BranchProtection, ParsedAttrs.CPU, BPI, DiagMsg)) {
3530 if (DiagMsg.empty())
3531 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3532 << Unsupported << None << "branch-protection" << Target;
3533 return Diag(LiteralLoc, diag::err_invalid_branch_protection_spec)
3534 << DiagMsg;
3535 }
3536 if (!DiagMsg.empty())
3537 Diag(LiteralLoc, diag::warn_unsupported_branch_protection_spec) << DiagMsg;
3538
3539 return false;
3540}
3541
3542// Check Target Version attrs
3544 StringRef &AttrStr, bool &isDefault) {
3545 enum FirstParam { Unsupported };
3546 enum SecondParam { None };
3547 enum ThirdParam { Target, TargetClones, TargetVersion };
3548 if (AttrStr.trim() == "default")
3549 isDefault = true;
3551 AttrStr.split(Features, "+");
3552 for (auto &CurFeature : Features) {
3553 CurFeature = CurFeature.trim();
3554 if (CurFeature == "default")
3555 continue;
3556 if (!Context.getTargetInfo().validateCpuSupports(CurFeature))
3557 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3558 << Unsupported << None << CurFeature << TargetVersion;
3559 }
3560 if (IsArmStreamingFunction(cast<FunctionDecl>(D),
3561 /*IncludeLocallyStreaming=*/false))
3562 return Diag(LiteralLoc, diag::err_sme_streaming_cannot_be_multiversioned);
3563 return false;
3564}
3565
3566static void handleTargetVersionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3567 StringRef Str;
3568 SourceLocation LiteralLoc;
3569 bool isDefault = false;
3570 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc) ||
3571 S.checkTargetVersionAttr(LiteralLoc, D, Str, isDefault))
3572 return;
3573 // Do not create default only target_version attribute
3574 if (!isDefault) {
3575 TargetVersionAttr *NewAttr =
3576 ::new (S.Context) TargetVersionAttr(S.Context, AL, Str);
3577 D->addAttr(NewAttr);
3578 }
3579}
3580
3581static void handleTargetAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3582 StringRef Str;
3583 SourceLocation LiteralLoc;
3584 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc) ||
3585 S.checkTargetAttr(LiteralLoc, Str))
3586 return;
3587
3588 TargetAttr *NewAttr = ::new (S.Context) TargetAttr(S.Context, AL, Str);
3589 D->addAttr(NewAttr);
3590}
3591
3593 SourceLocation LiteralLoc, StringRef Str, const StringLiteral *Literal,
3594 Decl *D, bool &HasDefault, bool &HasCommas, bool &HasNotDefault,
3595 SmallVectorImpl<SmallString<64>> &StringsBuffer) {
3596 enum FirstParam { Unsupported, Duplicate, Unknown };
3597 enum SecondParam { None, CPU, Tune };
3598 enum ThirdParam { Target, TargetClones };
3599 HasCommas = HasCommas || Str.contains(',');
3600 const TargetInfo &TInfo = Context.getTargetInfo();
3601 // Warn on empty at the beginning of a string.
3602 if (Str.size() == 0)
3603 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3604 << Unsupported << None << "" << TargetClones;
3605
3606 std::pair<StringRef, StringRef> Parts = {{}, Str};
3607 while (!Parts.second.empty()) {
3608 Parts = Parts.second.split(',');
3609 StringRef Cur = Parts.first.trim();
3610 SourceLocation CurLoc =
3611 Literal->getLocationOfByte(Cur.data() - Literal->getString().data(),
3612 getSourceManager(), getLangOpts(), TInfo);
3613
3614 bool DefaultIsDupe = false;
3615 bool HasCodeGenImpact = false;
3616 if (Cur.empty())
3617 return Diag(CurLoc, diag::warn_unsupported_target_attribute)
3618 << Unsupported << None << "" << TargetClones;
3619
3620 if (TInfo.getTriple().isAArch64()) {
3621 // AArch64 target clones specific
3622 if (Cur == "default") {
3623 DefaultIsDupe = HasDefault;
3624 HasDefault = true;
3625 if (llvm::is_contained(StringsBuffer, Cur) || DefaultIsDupe)
3626 Diag(CurLoc, diag::warn_target_clone_duplicate_options);
3627 else
3628 StringsBuffer.push_back(Cur);
3629 } else {
3630 std::pair<StringRef, StringRef> CurParts = {{}, Cur};
3632 while (!CurParts.second.empty()) {
3633 CurParts = CurParts.second.split('+');
3634 StringRef CurFeature = CurParts.first.trim();
3635 if (!TInfo.validateCpuSupports(CurFeature)) {
3636 Diag(CurLoc, diag::warn_unsupported_target_attribute)
3637 << Unsupported << None << CurFeature << TargetClones;
3638 continue;
3639 }
3640 if (TInfo.doesFeatureAffectCodeGen(CurFeature))
3641 HasCodeGenImpact = true;
3642 CurFeatures.push_back(CurFeature);
3643 }
3644 // Canonize TargetClones Attributes
3645 llvm::sort(CurFeatures);
3646 SmallString<64> Res;
3647 for (auto &CurFeat : CurFeatures) {
3648 if (!Res.empty())
3649 Res.append("+");
3650 Res.append(CurFeat);
3651 }
3652 if (llvm::is_contained(StringsBuffer, Res) || DefaultIsDupe)
3653 Diag(CurLoc, diag::warn_target_clone_duplicate_options);
3654 else if (!HasCodeGenImpact)
3655 // Ignore features in target_clone attribute that don't impact
3656 // code generation
3657 Diag(CurLoc, diag::warn_target_clone_no_impact_options);
3658 else if (!Res.empty()) {
3659 StringsBuffer.push_back(Res);
3660 HasNotDefault = true;
3661 }
3662 }
3663 if (IsArmStreamingFunction(cast<FunctionDecl>(D),
3664 /*IncludeLocallyStreaming=*/false))
3665 return Diag(LiteralLoc,
3666 diag::err_sme_streaming_cannot_be_multiversioned);
3667 } else {
3668 // Other targets ( currently X86 )
3669 if (Cur.starts_with("arch=")) {
3671 Cur.drop_front(sizeof("arch=") - 1)))
3672 return Diag(CurLoc, diag::warn_unsupported_target_attribute)
3673 << Unsupported << CPU << Cur.drop_front(sizeof("arch=") - 1)
3674 << TargetClones;
3675 } else if (Cur == "default") {
3676 DefaultIsDupe = HasDefault;
3677 HasDefault = true;
3678 } else if (!Context.getTargetInfo().isValidFeatureName(Cur))
3679 return Diag(CurLoc, diag::warn_unsupported_target_attribute)
3680 << Unsupported << None << Cur << TargetClones;
3681 if (llvm::is_contained(StringsBuffer, Cur) || DefaultIsDupe)
3682 Diag(CurLoc, diag::warn_target_clone_duplicate_options);
3683 // Note: Add even if there are duplicates, since it changes name mangling.
3684 StringsBuffer.push_back(Cur);
3685 }
3686 }
3687 if (Str.rtrim().ends_with(","))
3688 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3689 << Unsupported << None << "" << TargetClones;
3690 return false;
3691}
3692
3693static void handleTargetClonesAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3694 if (S.Context.getTargetInfo().getTriple().isAArch64() &&
3695 !S.Context.getTargetInfo().hasFeature("fmv"))
3696 return;
3697
3698 // Ensure we don't combine these with themselves, since that causes some
3699 // confusing behavior.
3700 if (const auto *Other = D->getAttr<TargetClonesAttr>()) {
3701 S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL;
3702 S.Diag(Other->getLocation(), diag::note_conflicting_attribute);
3703 return;
3704 }
3705 if (checkAttrMutualExclusion<TargetClonesAttr>(S, D, AL))
3706 return;
3707
3709 SmallVector<SmallString<64>, 2> StringsBuffer;
3710 bool HasCommas = false, HasDefault = false, HasNotDefault = false;
3711
3712 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
3713 StringRef CurStr;
3714 SourceLocation LiteralLoc;
3715 if (!S.checkStringLiteralArgumentAttr(AL, I, CurStr, &LiteralLoc) ||
3717 LiteralLoc, CurStr,
3718 cast<StringLiteral>(AL.getArgAsExpr(I)->IgnoreParenCasts()), D,
3719 HasDefault, HasCommas, HasNotDefault, StringsBuffer))
3720 return;
3721 }
3722 for (auto &SmallStr : StringsBuffer)
3723 Strings.push_back(SmallStr.str());
3724
3725 if (HasCommas && AL.getNumArgs() > 1)
3726 S.Diag(AL.getLoc(), diag::warn_target_clone_mixed_values);
3727
3728 if (S.Context.getTargetInfo().getTriple().isAArch64() && !HasDefault) {
3729 // Add default attribute if there is no one
3730 HasDefault = true;
3731 Strings.push_back("default");
3732 }
3733
3734 if (!HasDefault) {
3735 S.Diag(AL.getLoc(), diag::err_target_clone_must_have_default);
3736 return;
3737 }
3738
3739 // FIXME: We could probably figure out how to get this to work for lambdas
3740 // someday.
3741 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
3742 if (MD->getParent()->isLambda()) {
3743 S.Diag(D->getLocation(), diag::err_multiversion_doesnt_support)
3744 << static_cast<unsigned>(MultiVersionKind::TargetClones)
3745 << /*Lambda*/ 9;
3746 return;
3747 }
3748 }
3749
3750 // No multiversion if we have default version only.
3751 if (S.Context.getTargetInfo().getTriple().isAArch64() && !HasNotDefault)
3752 return;
3753
3754 cast<FunctionDecl>(D)->setIsMultiVersion();
3755 TargetClonesAttr *NewAttr = ::new (S.Context)
3756 TargetClonesAttr(S.Context, AL, Strings.data(), Strings.size());
3757 D->addAttr(NewAttr);
3758}
3759
3760static void handleMinVectorWidthAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3761 Expr *E = AL.getArgAsExpr(0);
3762 uint32_t VecWidth;
3763 if (!checkUInt32Argument(S, AL, E, VecWidth)) {
3764 AL.setInvalid();
3765 return;
3766 }
3767
3768 MinVectorWidthAttr *Existing = D->getAttr<MinVectorWidthAttr>();
3769 if (Existing && Existing->getVectorWidth() != VecWidth) {
3770 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3771 return;
3772 }
3773
3774 D->addAttr(::new (S.Context) MinVectorWidthAttr(S.Context, AL, VecWidth));
3775}
3776
3777static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3778 Expr *E = AL.getArgAsExpr(0);
3780 FunctionDecl *FD = nullptr;
3782
3783 // gcc only allows for simple identifiers. Since we support more than gcc, we
3784 // will warn the user.
3785 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
3786 if (DRE->hasQualifier())
3787 S.Diag(Loc, diag::warn_cleanup_ext);
3788 FD = dyn_cast<FunctionDecl>(DRE->getDecl());
3789 NI = DRE->getNameInfo();
3790 if (!FD) {
3791 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 1
3792 << NI.getName();
3793 return;
3794 }
3795 } else if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
3796 if (ULE->hasExplicitTemplateArgs())
3797 S.Diag(Loc, diag::warn_cleanup_ext);
3799 NI = ULE->getNameInfo();
3800 if (!FD) {
3801 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 2
3802 << NI.getName();
3803 if (ULE->getType() == S.Context.OverloadTy)
3805 return;
3806 }
3807 } else {
3808 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 0;
3809 return;
3810 }
3811
3812 if (FD->getNumParams() != 1) {
3813 S.Diag(Loc, diag::err_attribute_cleanup_func_must_take_one_arg)
3814 << NI.getName();
3815 return;
3816 }
3817
3818 // We're currently more strict than GCC about what function types we accept.
3819 // If this ever proves to be a problem it should be easy to fix.
3820 QualType Ty = S.Context.getPointerType(cast<VarDecl>(D)->getType());
3821 QualType ParamTy = FD->getParamDecl(0)->getType();
3823 ParamTy, Ty) != Sema::Compatible) {
3824 S.Diag(Loc, diag::err_attribute_cleanup_func_arg_incompatible_type)
3825 << NI.getName() << ParamTy << Ty;
3826 return;
3827 }
3828 VarDecl *VD = cast<VarDecl>(D);
3829 // Create a reference to the variable declaration. This is a fake/dummy
3830 // reference.
3831 DeclRefExpr *VariableReference = DeclRefExpr::Create(
3832 S.Context, NestedNameSpecifierLoc{}, FD->getLocation(), VD, false,
3833 DeclarationNameInfo{VD->getDeclName(), VD->getLocation()}, VD->getType(),
3834 VK_LValue);
3835
3836 // Create a unary operator expression that represents taking the address of
3837 // the variable. This is a fake/dummy expression.
3838 Expr *AddressOfVariable = UnaryOperator::Create(
3839 S.Context, VariableReference, UnaryOperatorKind::UO_AddrOf,
3841 +false, FPOptionsOverride{});
3842
3843 // Create a function call expression. This is a fake/dummy call expression.
3844 CallExpr *FunctionCallExpression =
3845 CallExpr::Create(S.Context, E, ArrayRef{AddressOfVariable},
3847
3848 if (S.CheckFunctionCall(FD, FunctionCallExpression,
3849 FD->getType()->getAs<FunctionProtoType>())) {
3850 return;
3851 }
3852
3853 D->addAttr(::new (S.Context) CleanupAttr(S.Context, AL, FD));
3854}
3855
3857 const ParsedAttr &AL) {
3858 if (!AL.isArgIdent(0)) {
3859 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3860 << AL << 0 << AANT_ArgumentIdentifier;
3861 return;
3862 }
3863
3864 EnumExtensibilityAttr::Kind ExtensibilityKind;
3865 IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
3866 if (!EnumExtensibilityAttr::ConvertStrToKind(II->getName(),
3867 ExtensibilityKind)) {
3868 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
3869 return;
3870 }
3871
3872 D->addAttr(::new (S.Context)
3873 EnumExtensibilityAttr(S.Context, AL, ExtensibilityKind));
3874}
3875
3876/// Handle __attribute__((format_arg((idx)))) attribute based on
3877/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
3878static void handleFormatArgAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3879 const Expr *IdxExpr = AL.getArgAsExpr(0);
3880 ParamIdx Idx;
3881 if (!checkFunctionOrMethodParameterIndex(S, D, AL, 1, IdxExpr, Idx))
3882 return;
3883
3884 // Make sure the format string is really a string.
3886
3887 bool NotNSStringTy = !isNSStringType(Ty, S.Context);
3888 if (NotNSStringTy &&
3889 !isCFStringType(Ty, S.Context) &&
3890 (!Ty->isPointerType() ||
3892 S.Diag(AL.getLoc(), diag::err_format_attribute_not)
3893 << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0);
3894 return;
3895 }
3897 // replace instancetype with the class type
3898 auto Instancetype = S.Context.getObjCInstanceTypeDecl()->getTypeForDecl();
3899 if (Ty->getAs<TypedefType>() == Instancetype)
3900 if (auto *OMD = dyn_cast<ObjCMethodDecl>(D))
3901 if (auto *Interface = OMD->getClassInterface())
3903 QualType(Interface->getTypeForDecl(), 0));
3904 if (!isNSStringType(Ty, S.Context, /*AllowNSAttributedString=*/true) &&
3905 !isCFStringType(Ty, S.Context) &&
3906 (!Ty->isPointerType() ||
3908 S.Diag(AL.getLoc(), diag::err_format_attribute_result_not)
3909 << (NotNSStringTy ? "string type" : "NSString")
3910 << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0);
3911 return;
3912 }
3913
3914 D->addAttr(::new (S.Context) FormatArgAttr(S.Context, AL, Idx));
3915}
3916
3925
3926/// getFormatAttrKind - Map from format attribute names to supported format
3927/// types.
3928static FormatAttrKind getFormatAttrKind(StringRef Format) {
3929 return llvm::StringSwitch<FormatAttrKind>(Format)
3930 // Check for formats that get handled specially.
3931 .Case("NSString", NSStringFormat)
3932 .Case("CFString", CFStringFormat)
3933 .Case("strftime", StrftimeFormat)
3934
3935 // Otherwise, check for supported formats.
3936 .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat)
3937 .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat)
3938 .Case("kprintf", SupportedFormat) // OpenBSD.
3939 .Case("freebsd_kprintf", SupportedFormat) // FreeBSD.
3940 .Case("os_trace", SupportedFormat)
3941 .Case("os_log", SupportedFormat)
3942
3943 .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat)
3944 .Default(InvalidFormat);
3945}
3946
3947/// Handle __attribute__((init_priority(priority))) attributes based on
3948/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
3949static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3950 if (!S.getLangOpts().CPlusPlus) {
3951 S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
3952 return;
3953 }
3954
3955 if (S.getLangOpts().HLSL) {
3956 S.Diag(AL.getLoc(), diag::err_hlsl_init_priority_unsupported);
3957 return;
3958 }
3959
3961 S.Diag(AL.getLoc(), diag::err_init_priority_object_attr);
3962 AL.setInvalid();
3963 return;
3964 }
3965 QualType T = cast<VarDecl>(D)->getType();
3966 if (S.Context.getAsArrayType(T))
3968 if (!T->getAs<RecordType>()) {
3969 S.Diag(AL.getLoc(), diag::err_init_priority_object_attr);
3970 AL.setInvalid();
3971 return;
3972 }
3973
3974 Expr *E = AL.getArgAsExpr(0);
3975 uint32_t prioritynum;
3976 if (!checkUInt32Argument(S, AL, E, prioritynum)) {
3977 AL.setInvalid();
3978 return;
3979 }
3980
3981 // Only perform the priority check if the attribute is outside of a system
3982 // header. Values <= 100 are reserved for the implementation, and libc++
3983 // benefits from being able to specify values in that range.
3984 if ((prioritynum < 101 || prioritynum > 65535) &&
3986 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_range)
3987 << E->getSourceRange() << AL << 101 << 65535;
3988 AL.setInvalid();
3989 return;
3990 }
3991 D->addAttr(::new (S.Context) InitPriorityAttr(S.Context, AL, prioritynum));
3992}
3993
3995 StringRef NewUserDiagnostic) {
3996 if (const auto *EA = D->getAttr<ErrorAttr>()) {
3997 std::string NewAttr = CI.getNormalizedFullName();
3998 assert((NewAttr == "error" || NewAttr == "warning") &&
3999 "unexpected normalized full name");
4000 bool Match = (EA->isError() && NewAttr == "error") ||
4001 (EA->isWarning() && NewAttr == "warning");
4002 if (!Match) {
4003 Diag(EA->getLocation(), diag::err_attributes_are_not_compatible)
4004 << CI << EA
4005 << (CI.isRegularKeywordAttribute() ||
4006 EA->isRegularKeywordAttribute());
4007 Diag(CI.getLoc(), diag::note_conflicting_attribute);
4008 return nullptr;
4009 }
4010 if (EA->getUserDiagnostic() != NewUserDiagnostic) {
4011 Diag(CI.getLoc(), diag::warn_duplicate_attribute) << EA;
4012 Diag(EA->getLoc(), diag::note_previous_attribute);
4013 }
4014 D->dropAttr<ErrorAttr>();
4015 }
4016 return ::new (Context) ErrorAttr(Context, CI, NewUserDiagnostic);
4017}
4018
4020 IdentifierInfo *Format, int FormatIdx,
4021 int FirstArg) {
4022 // Check whether we already have an equivalent format attribute.
4023 for (auto *F : D->specific_attrs<FormatAttr>()) {
4024 if (F->getType() == Format &&
4025 F->getFormatIdx() == FormatIdx &&
4026 F->getFirstArg() == FirstArg) {
4027 // If we don't have a valid location for this attribute, adopt the
4028 // location.
4029 if (F->getLocation().isInvalid())
4030 F->setRange(CI.getRange());
4031 return nullptr;
4032 }
4033 }
4034
4035 return ::new (Context) FormatAttr(Context, CI, Format, FormatIdx, FirstArg);
4036}
4037
4038/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
4039/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
4040static void handleFormatAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4041 if (!AL.isArgIdent(0)) {
4042 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
4043 << AL << 1 << AANT_ArgumentIdentifier;
4044 return;
4045 }
4046
4047 // In C++ the implicit 'this' function parameter also counts, and they are
4048 // counted from one.
4049 bool HasImplicitThisParam = isInstanceMethod(D);
4050 unsigned NumArgs = getFunctionOrMethodNumParams(D) + HasImplicitThisParam;
4051
4052 IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
4053 StringRef Format = II->getName();
4054
4055 if (normalizeName(Format)) {
4056 // If we've modified the string name, we need a new identifier for it.
4057 II = &S.Context.Idents.get(Format);
4058 }
4059
4060 // Check for supported formats.
4061 FormatAttrKind Kind = getFormatAttrKind(Format);
4062
4063 if (Kind == IgnoredFormat)
4064 return;
4065
4066 if (Kind == InvalidFormat) {
4067 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
4068 << AL << II->getName();
4069 return;
4070 }
4071
4072 // checks for the 2nd argument
4073 Expr *IdxExpr = AL.getArgAsExpr(1);
4074 uint32_t Idx;
4075 if (!checkUInt32Argument(S, AL, IdxExpr, Idx, 2))
4076 return;
4077
4078 if (Idx < 1 || Idx > NumArgs) {
4079 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
4080 << AL << 2 << IdxExpr->getSourceRange();
4081 return;
4082 }
4083
4084 // FIXME: Do we need to bounds check?
4085 unsigned ArgIdx = Idx - 1;
4086
4087 if (HasImplicitThisParam) {
4088 if (ArgIdx == 0) {
4089 S.Diag(AL.getLoc(),
4090 diag::err_format_attribute_implicit_this_format_string)
4091 << IdxExpr->getSourceRange();
4092 return;
4093 }
4094 ArgIdx--;
4095 }
4096
4097 // make sure the format string is really a string
4098 QualType Ty = getFunctionOrMethodParamType(D, ArgIdx);
4099
4100 if (!isNSStringType(Ty, S.Context, true) &&
4101 !isCFStringType(Ty, S.Context) &&
4102 (!Ty->isPointerType() ||
4104 S.Diag(AL.getLoc(), diag::err_format_attribute_not)
4105 << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, ArgIdx);
4106 return;
4107 }
4108
4109 // check the 3rd argument
4110 Expr *FirstArgExpr = AL.getArgAsExpr(2);
4111 uint32_t FirstArg;
4112 if (!checkUInt32Argument(S, AL, FirstArgExpr, FirstArg, 3))
4113 return;
4114
4115 // FirstArg == 0 is is always valid.
4116 if (FirstArg != 0) {
4117 if (Kind == StrftimeFormat) {
4118 // If the kind is strftime, FirstArg must be 0 because strftime does not
4119 // use any variadic arguments.
4120 S.Diag(AL.getLoc(), diag::err_format_strftime_third_parameter)
4121 << FirstArgExpr->getSourceRange()
4122 << FixItHint::CreateReplacement(FirstArgExpr->getSourceRange(), "0");
4123 return;
4124 } else if (isFunctionOrMethodVariadic(D)) {
4125 // Else, if the function is variadic, then FirstArg must be 0 or the
4126 // "position" of the ... parameter. It's unusual to use 0 with variadic
4127 // functions, so the fixit proposes the latter.
4128 if (FirstArg != NumArgs + 1) {
4129 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
4130 << AL << 3 << FirstArgExpr->getSourceRange()
4132 std::to_string(NumArgs + 1));
4133 return;
4134 }
4135 } else {
4136 // Inescapable GCC compatibility diagnostic.
4137 S.Diag(D->getLocation(), diag::warn_gcc_requires_variadic_function) << AL;
4138 if (FirstArg <= Idx) {
4139 // Else, the function is not variadic, and FirstArg must be 0 or any
4140 // parameter after the format parameter. We don't offer a fixit because
4141 // there are too many possible good values.
4142 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
4143 << AL << 3 << FirstArgExpr->getSourceRange();
4144 return;
4145 }
4146 }
4147 }
4148
4149 FormatAttr *NewAttr = S.mergeFormatAttr(D, AL, II, Idx, FirstArg);
4150 if (NewAttr)
4151 D->addAttr(NewAttr);
4152}
4153
4154/// Handle __attribute__((callback(CalleeIdx, PayloadIdx0, ...))) attributes.
4155static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4156 // The index that identifies the callback callee is mandatory.
4157 if (AL.getNumArgs() == 0) {
4158 S.Diag(AL.getLoc(), diag::err_callback_attribute_no_callee)
4159 << AL.getRange();
4160 return;
4161 }
4162
4163 bool HasImplicitThisParam = isInstanceMethod(D);
4164 int32_t NumArgs = getFunctionOrMethodNumParams(D);
4165
4166 FunctionDecl *FD = D->getAsFunction();
4167 assert(FD && "Expected a function declaration!");
4168
4169 llvm::StringMap<int> NameIdxMapping;
4170 NameIdxMapping["__"] = -1;
4171
4172 NameIdxMapping["this"] = 0;
4173
4174 int Idx = 1;
4175 for (const ParmVarDecl *PVD : FD->parameters())
4176 NameIdxMapping[PVD->getName()] = Idx++;
4177
4178 auto UnknownName = NameIdxMapping.end();
4179
4180 SmallVector<int, 8> EncodingIndices;
4181 for (unsigned I = 0, E = AL.getNumArgs(); I < E; ++I) {
4182 SourceRange SR;
4183 int32_t ArgIdx;
4184
4185 if (AL.isArgIdent(I)) {
4186 IdentifierLoc *IdLoc = AL.getArgAsIdent(I);
4187 auto It = NameIdxMapping.find(IdLoc->Ident->getName());
4188 if (It == UnknownName) {
4189 S.Diag(AL.getLoc(), diag::err_callback_attribute_argument_unknown)
4190 << IdLoc->Ident << IdLoc->Loc;
4191 return;
4192 }
4193
4194 SR = SourceRange(IdLoc->Loc);
4195 ArgIdx = It->second;
4196 } else if (AL.isArgExpr(I)) {
4197 Expr *IdxExpr = AL.getArgAsExpr(I);
4198
4199 // If the expression is not parseable as an int32_t we have a problem.
4200 if (!checkUInt32Argument(S, AL, IdxExpr, (uint32_t &)ArgIdx, I + 1,
4201 false)) {
4202 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
4203 << AL << (I + 1) << IdxExpr->getSourceRange();
4204 return;
4205 }
4206
4207 // Check oob, excluding the special values, 0 and -1.
4208 if (ArgIdx < -1 || ArgIdx > NumArgs) {
4209 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
4210 << AL << (I + 1) << IdxExpr->getSourceRange();
4211 return;
4212 }
4213
4214 SR = IdxExpr->getSourceRange();
4215 } else {
4216 llvm_unreachable("Unexpected ParsedAttr argument type!");
4217 }
4218
4219 if (ArgIdx == 0 && !HasImplicitThisParam) {
4220 S.Diag(AL.getLoc(), diag::err_callback_implicit_this_not_available)
4221 << (I + 1) << SR;
4222 return;
4223 }
4224
4225 // Adjust for the case we do not have an implicit "this" parameter. In this
4226 // case we decrease all positive values by 1 to get LLVM argument indices.
4227 if (!HasImplicitThisParam && ArgIdx > 0)
4228 ArgIdx -= 1;
4229
4230 EncodingIndices.push_back(ArgIdx);
4231 }
4232
4233 int CalleeIdx = EncodingIndices.front();
4234 // Check if the callee index is proper, thus not "this" and not "unknown".
4235 // This means the "CalleeIdx" has to be non-negative if "HasImplicitThisParam"
4236 // is false and positive if "HasImplicitThisParam" is true.
4237 if (CalleeIdx < (int)HasImplicitThisParam) {
4238 S.Diag(AL.getLoc(), diag::err_callback_attribute_invalid_callee)
4239 << AL.getRange();
4240 return;
4241 }
4242
4243 // Get the callee type, note the index adjustment as the AST doesn't contain
4244 // the this type (which the callee cannot reference anyway!).
4245 const Type *CalleeType =
4246 getFunctionOrMethodParamType(D, CalleeIdx - HasImplicitThisParam)
4247 .getTypePtr();
4248 if (!CalleeType || !CalleeType->isFunctionPointerType()) {
4249 S.Diag(AL.getLoc(), diag::err_callback_callee_no_function_type)
4250 << AL.getRange();
4251 return;
4252 }
4253
4254 const Type *CalleeFnType =
4256
4257 // TODO: Check the type of the callee arguments.
4258
4259 const auto *CalleeFnProtoType = dyn_cast<FunctionProtoType>(CalleeFnType);
4260 if (!CalleeFnProtoType) {
4261 S.Diag(AL.getLoc(), diag::err_callback_callee_no_function_type)
4262 << AL.getRange();
4263 return;
4264 }
4265
4266 if (CalleeFnProtoType->getNumParams() > EncodingIndices.size() - 1) {
4267 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
4268 << AL << (unsigned)(EncodingIndices.size() - 1);
4269 return;
4270 }
4271
4272 if (CalleeFnProtoType->getNumParams() < EncodingIndices.size() - 1) {
4273 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
4274 << AL << (unsigned)(EncodingIndices.size() - 1);
4275 return;
4276 }
4277
4278 if (CalleeFnProtoType->isVariadic()) {
4279 S.Diag(AL.getLoc(), diag::err_callback_callee_is_variadic) << AL.getRange();
4280 return;
4281 }
4282
4283 // Do not allow multiple callback attributes.
4284 if (D->hasAttr<CallbackAttr>()) {
4285 S.Diag(AL.getLoc(), diag::err_callback_attribute_multiple) << AL.getRange();
4286 return;
4287 }
4288
4289 D->addAttr(::new (S.Context) CallbackAttr(
4290 S.Context, AL, EncodingIndices.data(), EncodingIndices.size()));
4291}
4292
4293static bool isFunctionLike(const Type &T) {
4294 // Check for explicit function types.
4295 // 'called_once' is only supported in Objective-C and it has
4296 // function pointers and block pointers.
4298}
4299
4300/// Handle 'called_once' attribute.
4301static void handleCalledOnceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4302 // 'called_once' only applies to parameters representing functions.
4303 QualType T = cast<ParmVarDecl>(D)->getType();
4304
4305 if (!isFunctionLike(*T)) {
4306 S.Diag(AL.getLoc(), diag::err_called_once_attribute_wrong_type);
4307 return;
4308 }
4309
4310 D->addAttr(::new (S.Context) CalledOnceAttr(S.Context, AL));
4311}
4312
4313static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4314 // Try to find the underlying union declaration.
4315 RecordDecl *RD = nullptr;
4316 const auto *TD = dyn_cast<TypedefNameDecl>(D);
4317 if (TD && TD->getUnderlyingType()->isUnionType())
4318 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
4319 else
4320 RD = dyn_cast<RecordDecl>(D);
4321
4322 if (!RD || !RD->isUnion()) {
4323 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
4325 return;
4326 }
4327
4328 if (!RD->isCompleteDefinition()) {
4329 if (!RD->isBeingDefined())
4330 S.Diag(AL.getLoc(),
4331 diag::warn_transparent_union_attribute_not_definition);
4332 return;
4333 }
4334
4336 FieldEnd = RD->field_end();
4337 if (Field == FieldEnd) {
4338 S.Diag(AL.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
4339 return;
4340 }
4341
4342 FieldDecl *FirstField = *Field;
4343 QualType FirstType = FirstField->getType();
4344 if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
4345 S.Diag(FirstField->getLocation(),
4346 diag::warn_transparent_union_attribute_floating)
4347 << FirstType->isVectorType() << FirstType;
4348 return;
4349 }
4350
4351 if (FirstType->isIncompleteType())
4352 return;
4353 uint64_t FirstSize = S.Context.getTypeSize(FirstType);
4354 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
4355 for (; Field != FieldEnd; ++Field) {
4356 QualType FieldType = Field->getType();
4357 if (FieldType->isIncompleteType())
4358 return;
4359 // FIXME: this isn't fully correct; we also need to test whether the
4360 // members of the union would all have the same calling convention as the
4361 // first member of the union. Checking just the size and alignment isn't
4362 // sufficient (consider structs passed on the stack instead of in registers
4363 // as an example).
4364 if (S.Context.getTypeSize(FieldType) != FirstSize ||
4365 S.Context.getTypeAlign(FieldType) > FirstAlign) {
4366 // Warn if we drop the attribute.
4367 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
4368 unsigned FieldBits = isSize ? S.Context.getTypeSize(FieldType)
4369 : S.Context.getTypeAlign(FieldType);
4370 S.Diag(Field->getLocation(),
4371 diag::warn_transparent_union_attribute_field_size_align)
4372 << isSize << *Field << FieldBits;
4373 unsigned FirstBits = isSize ? FirstSize : FirstAlign;
4374 S.Diag(FirstField->getLocation(),
4375 diag::note_transparent_union_first_field_size_align)
4376 << isSize << FirstBits;
4377 return;
4378 }
4379 }
4380
4381 RD->addAttr(::new (S.Context) TransparentUnionAttr(S.Context, AL));
4382}
4383
4385 StringRef Str, MutableArrayRef<Expr *> Args) {
4386 auto *Attr = AnnotateAttr::Create(Context, Str, Args.data(), Args.size(), CI);
4388 CI, MutableArrayRef<Expr *>(Attr->args_begin(), Attr->args_end()))) {
4389 D->addAttr(Attr);
4390 }
4391}
4392
4393static void handleAnnotateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4394 // Make sure that there is a string literal as the annotation's first
4395 // argument.
4396 StringRef Str;
4397 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
4398 return;
4399
4401 Args.reserve(AL.getNumArgs() - 1);
4402 for (unsigned Idx = 1; Idx < AL.getNumArgs(); Idx++) {
4403 assert(!AL.isArgIdent(Idx));
4404 Args.push_back(AL.getArgAsExpr(Idx));
4405 }
4406
4407 S.AddAnnotationAttr(D, AL, Str, Args);
4408}
4409
4410static void handleAlignValueAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4411 S.AddAlignValueAttr(D, AL, AL.getArgAsExpr(0));
4412}
4413
4415 AlignValueAttr TmpAttr(Context, CI, E);
4416 SourceLocation AttrLoc = CI.getLoc();
4417
4418 QualType T;
4419 if (const auto *TD = dyn_cast<TypedefNameDecl>(D))
4420 T = TD->getUnderlyingType();
4421 else if (const auto *VD = dyn_cast<ValueDecl>(D))
4422 T = VD->getType();
4423 else
4424 llvm_unreachable("Unknown decl type for align_value");
4425
4426 if (!T->isDependentType() && !T->isAnyPointerType() &&
4428 Diag(AttrLoc, diag::warn_attribute_pointer_or_reference_only)
4429 << &TmpAttr << T << D->getSourceRange();
4430 return;
4431 }
4432
4433 if (!E->isValueDependent()) {
4434 llvm::APSInt Alignment;
4436 E, &Alignment, diag::err_align_value_attribute_argument_not_int);
4437 if (ICE.isInvalid())
4438 return;
4439
4440 if (!Alignment.isPowerOf2()) {
4441 Diag(AttrLoc, diag::err_alignment_not_power_of_two)
4442 << E->getSourceRange();
4443 return;
4444 }
4445
4446 D->addAttr(::new (Context) AlignValueAttr(Context, CI, ICE.get()));
4447 return;
4448 }
4449
4450 // Save dependent expressions in the AST to be instantiated.
4451 D->addAttr(::new (Context) AlignValueAttr(Context, CI, E));
4452}
4453
4454static void handleAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4455 if (AL.hasParsedType()) {
4456 const ParsedType &TypeArg = AL.getTypeArg();
4457 TypeSourceInfo *TInfo;
4458 (void)S.GetTypeFromParser(
4459 ParsedType::getFromOpaquePtr(TypeArg.getAsOpaquePtr()), &TInfo);
4460 if (AL.isPackExpansion() &&
4462 S.Diag(AL.getEllipsisLoc(),
4463 diag::err_pack_expansion_without_parameter_packs);
4464 return;
4465 }
4466
4467 if (!AL.isPackExpansion() &&
4469 TInfo, Sema::UPPC_Expression))
4470 return;
4471
4472 S.AddAlignedAttr(D, AL, TInfo, AL.isPackExpansion());
4473 return;
4474 }
4475
4476 // check the attribute arguments.
4477 if (AL.getNumArgs() > 1) {
4478 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
4479 return;
4480 }
4481
4482 if (AL.getNumArgs() == 0) {
4483 D->addAttr(::new (S.Context) AlignedAttr(S.Context, AL, true, nullptr));
4484 return;
4485 }
4486
4487 Expr *E = AL.getArgAsExpr(0);
4489 S.Diag(AL.getEllipsisLoc(),
4490 diag::err_pack_expansion_without_parameter_packs);
4491 return;
4492 }
4493
4495 return;
4496
4497 S.AddAlignedAttr(D, AL, E, AL.isPackExpansion());
4498}
4499
4500/// Perform checking of type validity
4501///
4502/// C++11 [dcl.align]p1:
4503/// An alignment-specifier may be applied to a variable or to a class
4504/// data member, but it shall not be applied to a bit-field, a function
4505/// parameter, the formal parameter of a catch clause, or a variable
4506/// declared with the register storage class specifier. An
4507/// alignment-specifier may also be applied to the declaration of a class
4508/// or enumeration type.
4509/// CWG 2354:
4510/// CWG agreed to remove permission for alignas to be applied to
4511/// enumerations.
4512/// C11 6.7.5/2:
4513/// An alignment attribute shall not be specified in a declaration of
4514/// a typedef, or a bit-field, or a function, or a parameter, or an
4515/// object declared with the register storage-class specifier.
4517 const AlignedAttr &Attr,
4518 SourceLocation AttrLoc) {
4519 int DiagKind = -1;
4520 if (isa<ParmVarDecl>(D)) {
4521 DiagKind = 0;
4522 } else if (const auto *VD = dyn_cast<VarDecl>(D)) {
4523 if (VD->getStorageClass() == SC_Register)
4524 DiagKind = 1;
4525 if (VD->isExceptionVariable())
4526 DiagKind = 2;
4527 } else if (const auto *FD = dyn_cast<FieldDecl>(D)) {
4528 if (FD->isBitField())
4529 DiagKind = 3;
4530 } else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
4531 if (ED->getLangOpts().CPlusPlus)
4532 DiagKind = 4;
4533 } else if (!isa<TagDecl>(D)) {
4534 return S.Diag(AttrLoc, diag::err_attribute_wrong_decl_type)
4536 << (Attr.isC11() ? ExpectedVariableOrField
4538 }
4539 if (DiagKind != -1) {
4540 return S.Diag(AttrLoc, diag::err_alignas_attribute_wrong_decl_type)
4541 << &Attr << DiagKind;
4542 }
4543 return false;
4544}
4545
4547 bool IsPackExpansion) {
4548 AlignedAttr TmpAttr(Context, CI, true, E);
4549 SourceLocation AttrLoc = CI.getLoc();
4550
4551 // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
4552 if (TmpAttr.isAlignas() &&
4553 validateAlignasAppliedType(*this, D, TmpAttr, AttrLoc))
4554 return;
4555
4556 if (E->isValueDependent()) {
4557 // We can't support a dependent alignment on a non-dependent type,
4558 // because we have no way to model that a type is "alignment-dependent"
4559 // but not dependent in any other way.
4560 if (const auto *TND = dyn_cast<TypedefNameDecl>(D)) {
4561 if (!TND->getUnderlyingType()->isDependentType()) {
4562 Diag(AttrLoc, diag::err_alignment_dependent_typedef_name)
4563 << E->getSourceRange();
4564 return;
4565 }
4566 }
4567
4568 // Save dependent expressions in the AST to be instantiated.
4569 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, E);
4570 AA->setPackExpansion(IsPackExpansion);
4571 D->addAttr(AA);
4572 return;
4573 }
4574
4575 // FIXME: Cache the number on the AL object?
4576 llvm::APSInt Alignment;
4578 E, &Alignment, diag::err_aligned_attribute_argument_not_int);
4579 if (ICE.isInvalid())
4580 return;
4581
4583 if (Context.getTargetInfo().getTriple().isOSBinFormatCOFF())
4584 MaximumAlignment = std::min(MaximumAlignment, uint64_t(8192));
4585 if (Alignment > MaximumAlignment) {
4586 Diag(AttrLoc, diag::err_attribute_aligned_too_great)
4588 return;
4589 }
4590
4591 uint64_t AlignVal = Alignment.getZExtValue();
4592 // C++11 [dcl.align]p2:
4593 // -- if the constant expression evaluates to zero, the alignment
4594 // specifier shall have no effect
4595 // C11 6.7.5p6:
4596 // An alignment specification of zero has no effect.
4597 if (!(TmpAttr.isAlignas() && !Alignment)) {
4598 if (!llvm::isPowerOf2_64(AlignVal)) {
4599 Diag(AttrLoc, diag::err_alignment_not_power_of_two)
4600 << E->getSourceRange();
4601 return;
4602 }
4603 }
4604
4605 const auto *VD = dyn_cast<VarDecl>(D);
4606 if (VD) {
4607 unsigned MaxTLSAlign =
4609 .getQuantity();
4610 if (MaxTLSAlign && AlignVal > MaxTLSAlign &&
4611 VD->getTLSKind() != VarDecl::TLS_None) {
4612 Diag(VD->getLocation(), diag::err_tls_var_aligned_over_maximum)
4613 << (unsigned)AlignVal << VD << MaxTLSAlign;
4614 return;
4615 }
4616 }
4617
4618 // On AIX, an aligned attribute can not decrease the alignment when applied
4619 // to a variable declaration with vector type.
4620 if (VD && Context.getTargetInfo().getTriple().isOSAIX()) {
4621 const Type *Ty = VD->getType().getTypePtr();
4622 if (Ty->isVectorType() && AlignVal < 16) {
4623 Diag(VD->getLocation(), diag::warn_aligned_attr_underaligned)
4624 << VD->getType() << 16;
4625 return;
4626 }
4627 }
4628
4629 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, ICE.get());
4630 AA->setPackExpansion(IsPackExpansion);
4631 AA->setCachedAlignmentValue(
4632 static_cast<unsigned>(AlignVal * Context.getCharWidth()));
4633 D->addAttr(AA);
4634}
4635
4637 TypeSourceInfo *TS, bool IsPackExpansion) {
4638 AlignedAttr TmpAttr(Context, CI, false, TS);
4639 SourceLocation AttrLoc = CI.getLoc();
4640
4641 // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
4642 if (TmpAttr.isAlignas() &&
4643 validateAlignasAppliedType(*this, D, TmpAttr, AttrLoc))
4644 return;
4645
4646 if (TS->getType()->isDependentType()) {
4647 // We can't support a dependent alignment on a non-dependent type,
4648 // because we have no way to model that a type is "type-dependent"
4649 // but not dependent in any other way.
4650 if (const auto *TND = dyn_cast<TypedefNameDecl>(D)) {
4651 if (!TND->getUnderlyingType()->isDependentType()) {
4652 Diag(AttrLoc, diag::err_alignment_dependent_typedef_name)
4653 << TS->getTypeLoc().getSourceRange();
4654 return;
4655 }
4656 }
4657
4658 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, false, TS);
4659 AA->setPackExpansion(IsPackExpansion);
4660 D->addAttr(AA);
4661 return;
4662 }
4663
4664 const auto *VD = dyn_cast<VarDecl>(D);
4665 unsigned AlignVal = TmpAttr.getAlignment(Context);
4666 // On AIX, an aligned attribute can not decrease the alignment when applied
4667 // to a variable declaration with vector type.
4668 if (VD && Context.getTargetInfo().getTriple().isOSAIX()) {
4669 const Type *Ty = VD->getType().getTypePtr();
4670 if (Ty->isVectorType() &&
4671 Context.toCharUnitsFromBits(AlignVal).getQuantity() < 16) {
4672 Diag(VD->getLocation(), diag::warn_aligned_attr_underaligned)
4673 << VD->getType() << 16;
4674 return;
4675 }
4676 }
4677
4678 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, false, TS);
4679 AA->setPackExpansion(IsPackExpansion);
4680 AA->setCachedAlignmentValue(AlignVal);
4681 D->addAttr(AA);
4682}
4683
4685 assert(D->hasAttrs() && "no attributes on decl");
4686
4687 QualType UnderlyingTy, DiagTy;
4688 if (const auto *VD = dyn_cast<ValueDecl>(D)) {
4689 UnderlyingTy = DiagTy = VD->getType();
4690 } else {
4691 UnderlyingTy = DiagTy = Context.getTagDeclType(cast<TagDecl>(D));
4692 if (const auto *ED = dyn_cast<EnumDecl>(D))
4693 UnderlyingTy = ED->getIntegerType();
4694 }
4695 if (DiagTy->isDependentType() || DiagTy->isIncompleteType())
4696 return;
4697
4698 // C++11 [dcl.align]p5, C11 6.7.5/4:
4699 // The combined effect of all alignment attributes in a declaration shall
4700 // not specify an alignment that is less strict than the alignment that
4701 // would otherwise be required for the entity being declared.
4702 AlignedAttr *AlignasAttr = nullptr;
4703 AlignedAttr *LastAlignedAttr = nullptr;
4704 unsigned Align = 0;
4705 for (auto *I : D->specific_attrs<AlignedAttr>()) {
4706 if (I->isAlignmentDependent())
4707 return;
4708 if (I->isAlignas())
4709 AlignasAttr = I;
4710 Align = std::max(Align, I->getAlignment(Context));
4711 LastAlignedAttr = I;
4712 }
4713
4714 if (Align && DiagTy->isSizelessType()) {
4715 Diag(LastAlignedAttr->getLocation(), diag::err_attribute_sizeless_type)
4716 << LastAlignedAttr << DiagTy;
4717 } else if (AlignasAttr && Align) {
4718 CharUnits RequestedAlign = Context.toCharUnitsFromBits(Align);
4719 CharUnits NaturalAlign = Context.getTypeAlignInChars(UnderlyingTy);
4720 if (NaturalAlign > RequestedAlign)
4721 Diag(AlignasAttr->getLocation(), diag::err_alignas_underaligned)
4722 << DiagTy << (unsigned)NaturalAlign.getQuantity();
4723 }
4724}
4725
4727 CXXRecordDecl *RD, SourceRange Range, bool BestCase,
4728 MSInheritanceModel ExplicitModel) {
4729 assert(RD->hasDefinition() && "RD has no definition!");
4730
4731 // We may not have seen base specifiers or any virtual methods yet. We will
4732 // have to wait until the record is defined to catch any mismatches.
4733 if (!RD->getDefinition()->isCompleteDefinition())
4734 return false;
4735
4736 // The unspecified model never matches what a definition could need.
4737 if (ExplicitModel == MSInheritanceModel::Unspecified)
4738 return false;
4739
4740 if (BestCase) {
4741 if (RD->calculateInheritanceModel() == ExplicitModel)
4742 return false;
4743 } else {
4744 if (RD->calculateInheritanceModel() <= ExplicitModel)
4745 return false;
4746 }
4747
4748 Diag(Range.getBegin(), diag::err_mismatched_ms_inheritance)
4749 << 0 /*definition*/;
4750 Diag(RD->getDefinition()->getLocation(), diag::note_defined_here) << RD;
4751 return true;
4752}
4753
4754/// parseModeAttrArg - Parses attribute mode string and returns parsed type
4755/// attribute.
4756static void parseModeAttrArg(Sema &S, StringRef Str, unsigned &DestWidth,
4757 bool &IntegerMode, bool &ComplexMode,
4758 FloatModeKind &ExplicitType) {
4759 IntegerMode = true;
4760 ComplexMode = false;
4761 ExplicitType = FloatModeKind::NoFloat;
4762 switch (Str.size()) {
4763 case 2:
4764 switch (Str[0]) {
4765 case 'Q':
4766 DestWidth = 8;
4767 break;
4768 case 'H':
4769 DestWidth = 16;
4770 break;
4771 case 'S':
4772 DestWidth = 32;
4773 break;
4774 case 'D':
4775 DestWidth = 64;
4776 break;
4777 case 'X':
4778 DestWidth = 96;
4779 break;
4780 case 'K': // KFmode - IEEE quad precision (__float128)
4781 ExplicitType = FloatModeKind::Float128;
4782 DestWidth = Str[1] == 'I' ? 0 : 128;
4783 break;
4784 case 'T':
4785 ExplicitType = FloatModeKind::LongDouble;
4786 DestWidth = 128;
4787 break;
4788 case 'I':
4789 ExplicitType = FloatModeKind::Ibm128;
4790 DestWidth = Str[1] == 'I' ? 0 : 128;
4791 break;
4792 }
4793 if (Str[1] == 'F') {
4794 IntegerMode = false;
4795 } else if (Str[1] == 'C') {
4796 IntegerMode = false;
4797 ComplexMode = true;
4798 } else if (Str[1] != 'I') {
4799 DestWidth = 0;
4800 }
4801 break;
4802 case 4:
4803 // FIXME: glibc uses 'word' to define register_t; this is narrower than a
4804 // pointer on PIC16 and other embedded platforms.
4805 if (Str == "word")
4806 DestWidth = S.Context.getTargetInfo().getRegisterWidth();
4807 else if (Str == "byte")
4808 DestWidth = S.Context.getTargetInfo().getCharWidth();
4809 break;
4810 case 7:
4811 if (Str == "pointer")
4813 break;
4814 case 11:
4815 if (Str == "unwind_word")
4816 DestWidth = S.Context.getTargetInfo().getUnwindWordWidth();
4817 break;
4818 }
4819}
4820
4821/// handleModeAttr - This attribute modifies the width of a decl with primitive
4822/// type.
4823///
4824/// Despite what would be logical, the mode attribute is a decl attribute, not a
4825/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
4826/// HImode, not an intermediate pointer.
4827static void handleModeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4828 // This attribute isn't documented, but glibc uses it. It changes
4829 // the width of an int or unsigned int to the specified size.
4830 if (!AL.isArgIdent(0)) {
4831 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
4832 << AL << AANT_ArgumentIdentifier;
4833 return;
4834 }
4835
4836 IdentifierInfo *Name = AL.getArgAsIdent(0)->Ident;
4837
4838 S.AddModeAttr(D, AL, Name);
4839}
4840
4842 IdentifierInfo *Name, bool InInstantiation) {
4843 StringRef Str = Name->getName();
4844 normalizeName(Str);
4845 SourceLocation AttrLoc = CI.getLoc();
4846
4847 unsigned DestWidth = 0;
4848 bool IntegerMode = true;
4849 bool ComplexMode = false;
4851 llvm::APInt VectorSize(64, 0);
4852 if (Str.size() >= 4 && Str[0] == 'V') {
4853 // Minimal length of vector mode is 4: 'V' + NUMBER(>=1) + TYPE(>=2).
4854 size_t StrSize = Str.size();
4855 size_t VectorStringLength = 0;
4856 while ((VectorStringLength + 1) < StrSize &&
4857 isdigit(Str[VectorStringLength + 1]))
4858 ++VectorStringLength;
4859 if (VectorStringLength &&
4860 !Str.substr(1, VectorStringLength).getAsInteger(10, VectorSize) &&
4861 VectorSize.isPowerOf2()) {
4862 parseModeAttrArg(*this, Str.substr(VectorStringLength + 1), DestWidth,
4863 IntegerMode, ComplexMode, ExplicitType);
4864 // Avoid duplicate warning from template instantiation.
4865 if (!InInstantiation)
4866 Diag(AttrLoc, diag::warn_vector_mode_deprecated);
4867 } else {
4868 VectorSize = 0;
4869 }
4870 }
4871
4872 if (!VectorSize)
4873 parseModeAttrArg(*this, Str, DestWidth, IntegerMode, ComplexMode,
4874 ExplicitType);
4875
4876 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
4877 // and friends, at least with glibc.
4878 // FIXME: Make sure floating-point mappings are accurate
4879 // FIXME: Support XF and TF types
4880 if (!DestWidth) {
4881 Diag(AttrLoc, diag::err_machine_mode) << 0 /*Unknown*/ << Name;
4882 return;
4883 }
4884
4885 QualType OldTy;
4886 if (const auto *TD = dyn_cast<TypedefNameDecl>(D))
4887 OldTy = TD->getUnderlyingType();
4888 else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
4889 // Something like 'typedef enum { X } __attribute__((mode(XX))) T;'.
4890 // Try to get type from enum declaration, default to int.
4891 OldTy = ED->getIntegerType();
4892 if (OldTy.isNull())
4893 OldTy = Context.IntTy;
4894 } else
4895 OldTy = cast<ValueDecl>(D)->getType();
4896
4897 if (OldTy->isDependentType()) {
4898 D->addAttr(::new (Context) ModeAttr(Context, CI, Name));
4899 return;
4900 }
4901
4902 // Base type can also be a vector type (see PR17453).
4903 // Distinguish between base type and base element type.
4904 QualType OldElemTy = OldTy;
4905 if (const auto *VT = OldTy->getAs<VectorType>())
4906 OldElemTy = VT->getElementType();
4907
4908 // GCC allows 'mode' attribute on enumeration types (even incomplete), except
4909 // for vector modes. So, 'enum X __attribute__((mode(QI)));' forms a complete
4910 // type, 'enum { A } __attribute__((mode(V4SI)))' is rejected.
4911 if ((isa<EnumDecl>(D) || OldElemTy->getAs<EnumType>()) &&
4912 VectorSize.getBoolValue()) {
4913 Diag(AttrLoc, diag::err_enum_mode_vector_type) << Name << CI.getRange();
4914 return;
4915 }
4916 bool IntegralOrAnyEnumType = (OldElemTy->isIntegralOrEnumerationType() &&
4917 !OldElemTy->isBitIntType()) ||
4918 OldElemTy->getAs<EnumType>();
4919
4920 if (!OldElemTy->getAs<BuiltinType>() && !OldElemTy->isComplexType() &&
4921 !IntegralOrAnyEnumType)
4922 Diag(AttrLoc, diag::err_mode_not_primitive);
4923 else if (IntegerMode) {
4924 if (!IntegralOrAnyEnumType)
4925 Diag(AttrLoc, diag::err_mode_wrong_type);
4926 } else if (ComplexMode) {
4927 if (!OldElemTy->isComplexType())
4928 Diag(AttrLoc, diag::err_mode_wrong_type);
4929 } else {
4930 if (!OldElemTy->isFloatingType())
4931 Diag(AttrLoc, diag::err_mode_wrong_type);
4932 }
4933
4934 QualType NewElemTy;
4935
4936 if (IntegerMode)
4937 NewElemTy = Context.getIntTypeForBitwidth(DestWidth,
4938 OldElemTy->isSignedIntegerType());
4939 else
4940 NewElemTy = Context.getRealTypeForBitwidth(DestWidth, ExplicitType);
4941
4942 if (NewElemTy.isNull()) {
4943 // Only emit diagnostic on host for 128-bit mode attribute
4944 if (!(DestWidth == 128 && getLangOpts().CUDAIsDevice))
4945 Diag(AttrLoc, diag::err_machine_mode) << 1 /*Unsupported*/ << Name;
4946 return;
4947 }
4948
4949 if (ComplexMode) {
4950 NewElemTy = Context.getComplexType(NewElemTy);
4951 }
4952
4953 QualType NewTy = NewElemTy;
4954 if (VectorSize.getBoolValue()) {
4955 NewTy = Context.getVectorType(NewTy, VectorSize.getZExtValue(),
4957 } else if (const auto *OldVT = OldTy->getAs<VectorType>()) {
4958 // Complex machine mode does not support base vector types.
4959 if (ComplexMode) {
4960 Diag(AttrLoc, diag::err_complex_mode_vector_type);
4961 return;
4962 }
4963 unsigned NumElements = Context.getTypeSize(OldElemTy) *
4964 OldVT->getNumElements() /
4965 Context.getTypeSize(NewElemTy);
4966 NewTy =
4967 Context.getVectorType(NewElemTy, NumElements, OldVT->getVectorKind());
4968 }
4969
4970 if (NewTy.isNull()) {
4971 Diag(AttrLoc, diag::err_mode_wrong_type);
4972 return;
4973 }
4974
4975 // Install the new type.
4976 if (auto *TD = dyn_cast<TypedefNameDecl>(D))
4977 TD->setModedTypeSourceInfo(TD->getTypeSourceInfo(), NewTy);
4978 else if (auto *ED = dyn_cast<EnumDecl>(D))
4979 ED->setIntegerType(NewTy);
4980 else
4981 cast<ValueDecl>(D)->setType(NewTy);
4982
4983 D->addAttr(::new (Context) ModeAttr(Context, CI, Name));
4984}
4985
4986static void handleNoDebugAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4987 D->addAttr(::new (S.Context) NoDebugAttr(S.Context, AL));
4988}
4989
4991 const AttributeCommonInfo &CI,
4992 const IdentifierInfo *Ident) {
4993 if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
4994 Diag(CI.getLoc(), diag::warn_attribute_ignored) << Ident;
4995 Diag(Optnone->getLocation(), diag::note_conflicting_attribute);
4996 return nullptr;
4997 }
4998
4999 if (D->hasAttr<AlwaysInlineAttr>())
5000 return nullptr;
5001
5002 return ::new (Context) AlwaysInlineAttr(Context, CI);
5003}
5004
5005InternalLinkageAttr *Sema::mergeInternalLinkageAttr(Decl *D,
5006 const ParsedAttr &AL) {
5007 if (const auto *VD = dyn_cast<VarDecl>(D)) {
5008 // Attribute applies to Var but not any subclass of it (like ParmVar,
5009 // ImplicitParm or VarTemplateSpecialization).
5010 if (VD->getKind() != Decl::Var) {
5011 Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
5012 << AL << AL.isRegularKeywordAttribute()
5015 return nullptr;
5016 }
5017 // Attribute does not apply to non-static local variables.
5018 if (VD->hasLocalStorage()) {
5019 Diag(VD->getLocation(), diag::warn_internal_linkage_local_storage);
5020 return nullptr;
5021 }
5022 }
5023
5024 return ::new (Context) InternalLinkageAttr(Context, AL);
5025}
5026InternalLinkageAttr *
5027Sema::mergeInternalLinkageAttr(Decl *D, const InternalLinkageAttr &AL) {
5028 if (const auto *VD = dyn_cast<VarDecl>(D)) {
5029 // Attribute applies to Var but not any subclass of it (like ParmVar,
5030 // ImplicitParm or VarTemplateSpecialization).
5031 if (VD->getKind() != Decl::Var) {
5032 Diag(AL.getLocation(), diag::warn_attribute_wrong_decl_type)
5033 << &AL << AL.isRegularKeywordAttribute()
5036 return nullptr;
5037 }
5038 // Attribute does not apply to non-static local variables.
5039 if (VD->hasLocalStorage()) {
5040 Diag(VD->getLocation(), diag::warn_internal_linkage_local_storage);
5041 return nullptr;
5042 }
5043 }
5044
5045 return ::new (Context) InternalLinkageAttr(Context, AL);
5046}
5047
5049 if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
5050 Diag(CI.getLoc(), diag::warn_attribute_ignored) << "'minsize'";
5051 Diag(Optnone->getLocation(), diag::note_conflicting_attribute);
5052 return nullptr;
5053 }
5054
5055 if (D->hasAttr<MinSizeAttr>())
5056 return nullptr;
5057
5058 return ::new (Context) MinSizeAttr(Context, CI);
5059}
5060
5061SwiftNameAttr *Sema::mergeSwiftNameAttr(Decl *D, const SwiftNameAttr &SNA,
5062 StringRef Name) {
5063 if (const auto *PrevSNA = D->getAttr<SwiftNameAttr>()) {
5064 if (PrevSNA->getName() != Name && !PrevSNA->isImplicit()) {
5065 Diag(PrevSNA->getLocation(), diag::err_attributes_are_not_compatible)
5066 << PrevSNA << &SNA
5067 << (PrevSNA->isRegularKeywordAttribute() ||
5068 SNA.isRegularKeywordAttribute());
5069 Diag(SNA.getLoc(), diag::note_conflicting_attribute);
5070 }
5071
5072 D->dropAttr<SwiftNameAttr>();
5073 }
5074 return ::new (Context) SwiftNameAttr(Context, SNA, Name);
5075}
5076
5078 const AttributeCommonInfo &CI) {
5079 if (AlwaysInlineAttr *Inline = D->getAttr<AlwaysInlineAttr>()) {
5080 Diag(Inline->getLocation(), diag::warn_attribute_ignored) << Inline;
5081 Diag(CI.getLoc(), diag::note_conflicting_attribute);
5082 D->dropAttr<AlwaysInlineAttr>();
5083 }
5084 if (MinSizeAttr *MinSize = D->getAttr<MinSizeAttr>()) {
5085 Diag(MinSize->getLocation(), diag::warn_attribute_ignored) << MinSize;
5086 Diag(CI.getLoc(), diag::note_conflicting_attribute);
5087 D->dropAttr<MinSizeAttr>();
5088 }
5089
5090 if (D->hasAttr<OptimizeNoneAttr>())
5091 return nullptr;
5092
5093 return ::new (Context) OptimizeNoneAttr(Context, CI);
5094}
5095
5096static void handleAlwaysInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5097 if (AlwaysInlineAttr *Inline =
5098 S.mergeAlwaysInlineAttr(D, AL, AL.getAttrName()))
5099 D->addAttr(Inline);
5100}
5101
5102static void handleMinSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5103 if (MinSizeAttr *MinSize = S.mergeMinSizeAttr(D, AL))
5104 D->addAttr(MinSize);
5105}
5106
5107static void handleOptimizeNoneAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5108 if (OptimizeNoneAttr *Optnone = S.mergeOptimizeNoneAttr(D, AL))
5109 D->addAttr(Optnone);
5110}
5111
5112static void handleConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5113 const auto *VD = cast<VarDecl>(D);
5114 if (VD->hasLocalStorage()) {
5115 S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
5116 return;
5117 }
5118 // constexpr variable may already get an implicit constant attr, which should
5119 // be replaced by the explicit constant attr.
5120 if (auto *A = D->getAttr<CUDAConstantAttr>()) {
5121 if (!A->isImplicit())
5122 return;
5123 D->dropAttr<CUDAConstantAttr>();
5124 }
5125 D->addAttr(::new (S.Context) CUDAConstantAttr(S.Context, AL));
5126}
5127
5128static void handleSharedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5129 const auto *VD = cast<VarDecl>(D);
5130 // extern __shared__ is only allowed on arrays with no length (e.g.
5131 // "int x[]").
5132 if (!S.getLangOpts().GPURelocatableDeviceCode && VD->hasExternalStorage() &&
5133 !isa<IncompleteArrayType>(VD->getType())) {
5134 S.Diag(AL.getLoc(), diag::err_cuda_extern_shared) << VD;
5135 return;
5136 }
5137 if (S.getLangOpts().CUDA && VD->hasLocalStorage() &&
5138 S.CUDA().DiagIfHostCode(AL.getLoc(), diag::err_cuda_host_shared)
5139 << llvm::to_underlying(S.CUDA().CurrentTarget()))
5140 return;
5141 D->addAttr(::new (S.Context) CUDASharedAttr(S.Context, AL));
5142}
5143
5144static void handleGlobalAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5145 const auto *FD = cast<FunctionDecl>(D);
5146 if (!FD->getReturnType()->isVoidType() &&
5147 !FD->getReturnType()->getAs<AutoType>() &&
5149 SourceRange RTRange = FD->getReturnTypeSourceRange();
5150 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
5151 << FD->getType()
5152 << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void")
5153 : FixItHint());
5154 return;
5155 }
5156 if (const auto *Method = dyn_cast<CXXMethodDecl>(FD)) {
5157 if (Method->isInstance()) {
5158 S.Diag(Method->getBeginLoc(), diag::err_kern_is_nonstatic_method)
5159 << Method;
5160 return;
5161 }
5162 S.Diag(Method->getBeginLoc(), diag::warn_kern_is_method) << Method;
5163 }
5164 // Only warn for "inline" when compiling for host, to cut down on noise.
5165 if (FD->isInlineSpecified() && !S.getLangOpts().CUDAIsDevice)
5166 S.Diag(FD->getBeginLoc(), diag::warn_kern_is_inline) << FD;
5167
5168 if (AL.getKind() == ParsedAttr::AT_NVPTXKernel)
5169 D->addAttr(::new (S.Context) NVPTXKernelAttr(S.Context, AL));
5170 else
5171 D->addAttr(::new (S.Context) CUDAGlobalAttr(S.Context, AL));
5172 // In host compilation the kernel is emitted as a stub function, which is
5173 // a helper function for launching the kernel. The instructions in the helper
5174 // function has nothing to do with the source code of the kernel. Do not emit
5175 // debug info for the stub function to avoid confusing the debugger.
5176 if (S.LangOpts.HIP && !S.LangOpts.CUDAIsDevice)
5177 D->addAttr(NoDebugAttr::CreateImplicit(S.Context));
5178}
5179
5180static void handleDeviceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5181 if (const auto *VD = dyn_cast<VarDecl>(D)) {
5182 if (VD->hasLocalStorage()) {
5183 S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
5184 return;
5185 }
5186 }
5187
5188 if (auto *A = D->getAttr<CUDADeviceAttr>()) {
5189 if (!A->isImplicit())
5190 return;
5191 D->dropAttr<CUDADeviceAttr>();
5192 }
5193 D->addAttr(::new (S.Context) CUDADeviceAttr(S.Context, AL));
5194}
5195
5196static void handleManagedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5197 if (const auto *VD = dyn_cast<VarDecl>(D)) {
5198 if (VD->hasLocalStorage()) {
5199 S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
5200 return;
5201 }
5202 }
5203 if (!D->hasAttr<HIPManagedAttr>())
5204 D->addAttr(::new (S.Context) HIPManagedAttr(S.Context, AL));
5205 if (!D->hasAttr<CUDADeviceAttr>())
5206 D->addAttr(CUDADeviceAttr::CreateImplicit(S.Context));
5207}
5208
5209static void handleGNUInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5210 const auto *Fn = cast<FunctionDecl>(D);
5211 if (!Fn->isInlineSpecified()) {
5212 S.Diag(AL.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
5213 return;
5214 }
5215
5216 if (S.LangOpts.CPlusPlus && Fn->getStorageClass() != SC_Extern)
5217 S.Diag(AL.getLoc(), diag::warn_gnu_inline_cplusplus_without_extern);
5218
5219 D->addAttr(::new (S.Context) GNUInlineAttr(S.Context, AL));
5220}
5221
5222static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5223 if (hasDeclarator(D)) return;
5224
5225 // Diagnostic is emitted elsewhere: here we store the (valid) AL
5226 // in the Decl node for syntactic reasoning, e.g., pretty-printing.
5227 CallingConv CC;
5229 AL, CC, /*FD*/ nullptr,
5230 S.CUDA().IdentifyTarget(dyn_cast<FunctionDecl>(D))))
5231 return;
5232
5233 if (!isa<ObjCMethodDecl>(D)) {
5234 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
5236 return;
5237 }
5238
5239 switch (AL.getKind()) {
5240 case ParsedAttr::AT_FastCall:
5241 D->addAttr(::new (S.Context) FastCallAttr(S.Context, AL));
5242 return;
5243 case ParsedAttr::AT_StdCall:
5244 D->addAttr(::new (S.Context) StdCallAttr(S.Context, AL));
5245 return;
5246 case ParsedAttr::AT_ThisCall:
5247 D->addAttr(::new (S.Context) ThisCallAttr(S.Context, AL));
5248 return;
5249 case ParsedAttr::AT_CDecl:
5250 D->addAttr(::new (S.Context) CDeclAttr(S.Context, AL));
5251 return;
5252 case ParsedAttr::AT_Pascal:
5253 D->addAttr(::new (S.Context) PascalAttr(S.Context, AL));
5254 return;
5255 case ParsedAttr::AT_SwiftCall:
5256 D->addAttr(::new (S.Context) SwiftCallAttr(S.Context, AL));
5257 return;
5258 case ParsedAttr::AT_SwiftAsyncCall:
5259 D->addAttr(::new (S.Context) SwiftAsyncCallAttr(S.Context, AL));
5260 return;
5261 case ParsedAttr::AT_VectorCall:
5262 D->addAttr(::new (S.Context) VectorCallAttr(S.Context, AL));
5263 return;
5264 case ParsedAttr::AT_MSABI:
5265 D->addAttr(::new (S.Context) MSABIAttr(S.Context, AL));
5266 return;
5267 case ParsedAttr::AT_SysVABI:
5268 D->addAttr(::new (S.Context) SysVABIAttr(S.Context, AL));
5269 return;
5270 case ParsedAttr::AT_RegCall:
5271 D->addAttr(::new (S.Context) RegCallAttr(S.Context, AL));
5272 return;
5273 case ParsedAttr::AT_Pcs: {
5274 PcsAttr::PCSType PCS;
5275 switch (CC) {
5276 case CC_AAPCS:
5277 PCS = PcsAttr::AAPCS;
5278 break;
5279 case CC_AAPCS_VFP:
5280 PCS = PcsAttr::AAPCS_VFP;
5281 break;
5282 default:
5283 llvm_unreachable("unexpected calling convention in pcs attribute");
5284 }
5285
5286 D->addAttr(::new (S.Context) PcsAttr(S.Context, AL, PCS));
5287 return;
5288 }
5289 case ParsedAttr::AT_AArch64VectorPcs:
5290 D->addAttr(::new (S.Context) AArch64VectorPcsAttr(S.Context, AL));
5291 return;
5292 case ParsedAttr::AT_AArch64SVEPcs:
5293 D->addAttr(::new (S.Context) AArch64SVEPcsAttr(S.Context, AL));
5294 return;
5295 case ParsedAttr::AT_AMDGPUKernelCall:
5296 D->addAttr(::new (S.Context) AMDGPUKernelCallAttr(S.Context, AL));
5297 return;
5298 case ParsedAttr::AT_IntelOclBicc:
5299 D->addAttr(::new (S.Context) IntelOclBiccAttr(S.Context, AL));
5300 return;
5301 case ParsedAttr::AT_PreserveMost:
5302 D->addAttr(::new (S.Context) PreserveMostAttr(S.Context, AL));
5303 return;
5304 case ParsedAttr::AT_PreserveAll:
5305 D->addAttr(::new (S.Context) PreserveAllAttr(S.Context, AL));
5306 return;
5307 case ParsedAttr::AT_M68kRTD:
5308 D->addAttr(::new (S.Context) M68kRTDAttr(S.Context, AL));
5309 return;
5310 case ParsedAttr::AT_PreserveNone:
5311 D->addAttr(::new (S.Context) PreserveNoneAttr(S.Context, AL));
5312 return;
5313 case ParsedAttr::AT_RISCVVectorCC:
5314 D->addAttr(::new (S.Context) RISCVVectorCCAttr(S.Context, AL));
5315 return;
5316 default:
5317 llvm_unreachable("unexpected attribute kind");
5318 }
5319}
5320
5321static void handleSuppressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5322 if (AL.getAttributeSpellingListIndex() == SuppressAttr::CXX11_gsl_suppress) {
5323 // Suppression attribute with GSL spelling requires at least 1 argument.
5324 if (!AL.checkAtLeastNumArgs(S, 1))
5325 return;
5326 }
5327
5328 std::vector<StringRef> DiagnosticIdentifiers;
5329 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
5330 StringRef RuleName;
5331
5332 if (!S.checkStringLiteralArgumentAttr(AL, I, RuleName, nullptr))
5333 return;
5334
5335 DiagnosticIdentifiers.push_back(RuleName);
5336 }
5337 D->addAttr(::new (S.Context)
5338 SuppressAttr(S.Context, AL, DiagnosticIdentifiers.data(),
5339 DiagnosticIdentifiers.size()));
5340}
5341
5342static void handleLifetimeCategoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5343 TypeSourceInfo *DerefTypeLoc = nullptr;
5344 QualType ParmType;
5345 if (AL.hasParsedType()) {
5346 ParmType = S.GetTypeFromParser(AL.getTypeArg(), &DerefTypeLoc);
5347
5348 unsigned SelectIdx = ~0U;
5349 if (ParmType->isReferenceType())
5350 SelectIdx = 0;
5351 else if (ParmType->isArrayType())
5352 SelectIdx = 1;
5353
5354 if (SelectIdx != ~0U) {
5355 S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument)
5356 << SelectIdx << AL;
5357 return;
5358 }
5359 }
5360
5361 // To check if earlier decl attributes do not conflict the newly parsed ones
5362 // we always add (and check) the attribute to the canonical decl. We need
5363 // to repeat the check for attribute mutual exclusion because we're attaching
5364 // all of the attributes to the canonical declaration rather than the current
5365 // declaration.
5366 D = D->getCanonicalDecl();
5367 if (AL.getKind() == ParsedAttr::AT_Owner) {
5368 if (checkAttrMutualExclusion<PointerAttr>(S, D, AL))
5369 return;
5370 if (const auto *OAttr = D->getAttr<OwnerAttr>()) {
5371 const Type *ExistingDerefType = OAttr->getDerefTypeLoc()
5372 ? OAttr->getDerefType().getTypePtr()
5373 : nullptr;
5374 if (ExistingDerefType != ParmType.getTypePtrOrNull()) {
5375 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
5376 << AL << OAttr
5377 << (AL.isRegularKeywordAttribute() ||
5378 OAttr->isRegularKeywordAttribute());
5379 S.Diag(OAttr->getLocation(), diag::note_conflicting_attribute);
5380 }
5381 return;
5382 }
5383 for (Decl *Redecl : D->redecls()) {
5384 Redecl->addAttr(::new (S.Context) OwnerAttr(S.Context, AL, DerefTypeLoc));
5385 }
5386 } else {
5387 if (checkAttrMutualExclusion<OwnerAttr>(S, D, AL))
5388 return;
5389 if (const auto *PAttr = D->getAttr<PointerAttr>()) {
5390 const Type *ExistingDerefType = PAttr->getDerefTypeLoc()
5391 ? PAttr->getDerefType().getTypePtr()
5392 : nullptr;
5393 if (ExistingDerefType != ParmType.getTypePtrOrNull()) {
5394 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
5395 << AL << PAttr
5396 << (AL.isRegularKeywordAttribute() ||
5397 PAttr->isRegularKeywordAttribute());
5398 S.Diag(PAttr->getLocation(), diag::note_conflicting_attribute);
5399 }
5400 return;
5401 }
5402 for (Decl *Redecl : D->redecls()) {
5403 Redecl->addAttr(::new (S.Context)
5404 PointerAttr(S.Context, AL, DerefTypeLoc));
5405 }
5406 }
5407}
5408
5409static void handleRandomizeLayoutAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5410 if (checkAttrMutualExclusion<NoRandomizeLayoutAttr>(S, D, AL))
5411 return;
5412 if (!D->hasAttr<RandomizeLayoutAttr>())
5413 D->addAttr(::new (S.Context) RandomizeLayoutAttr(S.Context, AL));
5414}
5415
5417 const ParsedAttr &AL) {
5418 if (checkAttrMutualExclusion<RandomizeLayoutAttr>(S, D, AL))
5419 return;
5420 if (!D->hasAttr<NoRandomizeLayoutAttr>())
5421 D->addAttr(::new (S.Context) NoRandomizeLayoutAttr(S.Context, AL));
5422}
5423
5425 const FunctionDecl *FD,
5426 CUDAFunctionTarget CFT) {
5427 if (Attrs.isInvalid())
5428 return true;
5429
5430 if (Attrs.hasProcessingCache()) {
5431 CC = (CallingConv) Attrs.getProcessingCache();
5432 return false;
5433 }
5434
5435 unsigned ReqArgs = Attrs.getKind() == ParsedAttr::AT_Pcs ? 1 : 0;
5436 if (!Attrs.checkExactlyNumArgs(*this, ReqArgs)) {
5437 Attrs.setInvalid();
5438 return true;
5439 }
5440
5441 // TODO: diagnose uses of these conventions on the wrong target.
5442 switch (Attrs.getKind()) {
5443 case ParsedAttr::AT_CDecl:
5444 CC = CC_C;
5445 break;
5446 case ParsedAttr::AT_FastCall:
5447 CC = CC_X86FastCall;
5448 break;
5449 case ParsedAttr::AT_StdCall:
5450 CC = CC_X86StdCall;
5451 break;
5452 case ParsedAttr::AT_ThisCall:
5453 CC = CC_X86ThisCall;
5454 break;
5455 case ParsedAttr::AT_Pascal:
5456 CC = CC_X86Pascal;
5457 break;
5458 case ParsedAttr::AT_SwiftCall:
5459 CC = CC_Swift;
5460 break;
5461 case ParsedAttr::AT_SwiftAsyncCall:
5462 CC = CC_SwiftAsync;
5463 break;
5464 case ParsedAttr::AT_VectorCall:
5465 CC = CC_X86VectorCall;
5466 break;
5467 case ParsedAttr::AT_AArch64VectorPcs:
5469 break;
5470 case ParsedAttr::AT_AArch64SVEPcs:
5471 CC = CC_AArch64SVEPCS;
5472 break;
5473 case ParsedAttr::AT_AMDGPUKernelCall:
5475 break;
5476 case ParsedAttr::AT_RegCall:
5477 CC = CC_X86RegCall;
5478 break;
5479 case ParsedAttr::AT_MSABI:
5480 CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C :
5481 CC_Win64;
5482 break;
5483 case ParsedAttr::AT_SysVABI:
5484 CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_X86_64SysV :
5485 CC_C;
5486 break;
5487 case ParsedAttr::AT_Pcs: {
5488 StringRef StrRef;
5489 if (!checkStringLiteralArgumentAttr(Attrs, 0, StrRef)) {
5490 Attrs.setInvalid();
5491 return true;
5492 }
5493 if (StrRef == "aapcs") {
5494 CC = CC_AAPCS;
5495 break;
5496 } else if (StrRef == "aapcs-vfp") {
5497 CC = CC_AAPCS_VFP;
5498 break;
5499 }
5500
5501 Attrs.setInvalid();
5502 Diag(Attrs.getLoc(), diag::err_invalid_pcs);
5503 return true;
5504 }
5505 case ParsedAttr::AT_IntelOclBicc:
5506 CC = CC_IntelOclBicc;
5507 break;
5508 case ParsedAttr::AT_PreserveMost:
5509 CC = CC_PreserveMost;
5510 break;
5511 case ParsedAttr::AT_PreserveAll:
5512 CC = CC_PreserveAll;
5513 break;
5514 case ParsedAttr::AT_M68kRTD:
5515 CC = CC_M68kRTD;
5516 break;
5517 case ParsedAttr::AT_PreserveNone:
5518 CC = CC_PreserveNone;
5519 break;
5520 case ParsedAttr::AT_RISCVVectorCC:
5521 CC = CC_RISCVVectorCall;
5522 break;
5523 default: llvm_unreachable("unexpected attribute kind");
5524 }
5525
5527 const TargetInfo &TI = Context.getTargetInfo();
5528 // CUDA functions may have host and/or device attributes which indicate
5529 // their targeted execution environment, therefore the calling convention
5530 // of functions in CUDA should be checked against the target deduced based
5531 // on their host/device attributes.
5532 if (LangOpts.CUDA) {
5533 auto *Aux = Context.getAuxTargetInfo();
5534 assert(FD || CFT != CUDAFunctionTarget::InvalidTarget);
5535 auto CudaTarget = FD ? CUDA().IdentifyTarget(FD) : CFT;
5536 bool CheckHost = false, CheckDevice = false;
5537 switch (CudaTarget) {
5539 CheckHost = true;
5540 CheckDevice = true;
5541 break;
5543 CheckHost = true;
5544 break;
5547 CheckDevice = true;
5548 break;
5550 llvm_unreachable("unexpected cuda target");
5551 }
5552 auto *HostTI = LangOpts.CUDAIsDevice ? Aux : &TI;
5553 auto *DeviceTI = LangOpts.CUDAIsDevice ? &TI : Aux;
5554 if (CheckHost && HostTI)
5555 A = HostTI->checkCallingConvention(CC);
5556 if (A == TargetInfo::CCCR_OK && CheckDevice && DeviceTI)
5557 A = DeviceTI->checkCallingConvention(CC);
5558 } else {
5559 A = TI.checkCallingConvention(CC);
5560 }
5561
5562 switch (A) {
5564 break;
5565
5567 // Treat an ignored convention as if it was an explicit C calling convention
5568 // attribute. For example, __stdcall on Win x64 functions as __cdecl, so
5569 // that command line flags that change the default convention to
5570 // __vectorcall don't affect declarations marked __stdcall.
5571 CC = CC_C;
5572 break;
5573
5575 Diag(Attrs.getLoc(), diag::error_cconv_unsupported)
5577 break;
5578
5580 Diag(Attrs.getLoc(), diag::warn_cconv_unsupported)
5582
5583 // This convention is not valid for the target. Use the default function or
5584 // method calling convention.
5585 bool IsCXXMethod = false, IsVariadic = false;
5586 if (FD) {
5587 IsCXXMethod = FD->isCXXInstanceMember();
5588 IsVariadic = FD->isVariadic();
5589 }
5590 CC = Context.getDefaultCallingConvention(IsVariadic, IsCXXMethod);
5591 break;
5592 }
5593 }
5594
5595 Attrs.setProcessingCache((unsigned) CC);
5596 return false;
5597}
5598
5599/// Pointer-like types in the default address space.
5601 if (!Ty->hasPointerRepresentation())
5602 return Ty->isDependentType();
5604}
5605
5606/// Pointers and references in the default address space.
5608 if (const auto *PtrType = Ty->getAs<PointerType>()) {
5609 Ty = PtrType->getPointeeType();
5610 } else if (const auto *RefType = Ty->getAs<ReferenceType>()) {
5611 Ty = RefType->getPointeeType();
5612 } else {
5613 return Ty->isDependentType();
5614 }
5615 return Ty.getAddressSpace() == LangAS::Default;
5616}
5617
5618/// Pointers and references to pointers in the default address space.
5620 if (const auto *PtrType = Ty->getAs<PointerType>()) {
5621 Ty = PtrType->getPointeeType();
5622 } else if (const auto *RefType = Ty->getAs<ReferenceType>()) {
5623 Ty = RefType->getPointeeType();
5624 } else {
5625 return Ty->isDependentType();
5626 }
5627 if (!Ty.getQualifiers().empty())
5628 return false;
5629 return isValidSwiftContextType(Ty);
5630}
5631
5633 ParameterABI abi) {
5634
5635 QualType type = cast<ParmVarDecl>(D)->getType();
5636
5637 if (auto existingAttr = D->getAttr<ParameterABIAttr>()) {
5638 if (existingAttr->getABI() != abi) {
5639 Diag(CI.getLoc(), diag::err_attributes_are_not_compatible)
5640 << getParameterABISpelling(abi) << existingAttr
5641 << (CI.isRegularKeywordAttribute() ||
5642 existingAttr->isRegularKeywordAttribute());
5643 Diag(existingAttr->getLocation(), diag::note_conflicting_attribute);
5644 return;
5645 }
5646 }
5647
5648 switch (abi) {
5650 llvm_unreachable("explicit attribute for ordinary parameter ABI?");
5651
5654 Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type)
5655 << getParameterABISpelling(abi) << /*pointer to pointer */ 0 << type;
5656 }
5657 D->addAttr(::new (Context) SwiftContextAttr(Context, CI));
5658 return;
5659
5662 Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type)
5663 << getParameterABISpelling(abi) << /*pointer to pointer */ 0 << type;
5664 }
5665 D->addAttr(::new (Context) SwiftAsyncContextAttr(Context, CI));
5666 return;
5667
5670 Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type)
5671 << getParameterABISpelling(abi) << /*pointer to pointer */ 1 << type;
5672 }
5673 D->addAttr(::new (Context) SwiftErrorResultAttr(Context, CI));
5674 return;
5675
5678 Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type)
5679 << getParameterABISpelling(abi) << /*pointer*/ 0 << type;
5680 }
5681 D->addAttr(::new (Context) SwiftIndirectResultAttr(Context, CI));
5682 return;
5683 }
5684 llvm_unreachable("bad parameter ABI attribute");
5685}
5686
5687/// Checks a regparm attribute, returning true if it is ill-formed and
5688/// otherwise setting numParams to the appropriate value.
5689bool Sema::CheckRegparmAttr(const ParsedAttr &AL, unsigned &numParams) {
5690 if (AL.isInvalid())
5691 return true;
5692
5693 if (!AL.checkExactlyNumArgs(*this, 1)) {
5694 AL.setInvalid();
5695 return true;
5696 }
5697
5698 uint32_t NP;
5699 Expr *NumParamsExpr = AL.getArgAsExpr(0);
5700 if (!checkUInt32Argument(*this, AL, NumParamsExpr, NP)) {
5701 AL.setInvalid();
5702 return true;
5703 }
5704
5705 if (Context.getTargetInfo().getRegParmMax() == 0) {
5706 Diag(AL.getLoc(), diag::err_attribute_regparm_wrong_platform)
5707 << NumParamsExpr->getSourceRange();
5708 AL.setInvalid();
5709 return true;
5710 }
5711
5712 numParams = NP;
5713 if (numParams > Context.getTargetInfo().getRegParmMax()) {
5714 Diag(AL.getLoc(), diag::err_attribute_regparm_invalid_number)
5715 << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
5716 AL.setInvalid();
5717 return true;
5718 }
5719
5720 return false;
5721}
5722
5723// Helper to get CudaArch.
5725 if (!TI.getTriple().isNVPTX())
5726 llvm_unreachable("getCudaArch is only valid for NVPTX triple");
5727 auto &TO = TI.getTargetOpts();
5728 return StringToCudaArch(TO.CPU);
5729}
5730
5731// Checks whether an argument of launch_bounds attribute is
5732// acceptable, performs implicit conversion to Rvalue, and returns
5733// non-nullptr Expr result on success. Otherwise, it returns nullptr
5734// and may output an error.
5736 const CUDALaunchBoundsAttr &AL,
5737 const unsigned Idx) {
5739 return nullptr;
5740
5741 // Accept template arguments for now as they depend on something else.
5742 // We'll get to check them when they eventually get instantiated.
5743 if (E->isValueDependent())
5744 return E;
5745
5746 std::optional<llvm::APSInt> I = llvm::APSInt(64);
5747 if (!(I = E->getIntegerConstantExpr(S.Context))) {
5748 S.Diag(E->getExprLoc(), diag::err_attribute_argument_n_type)
5749 << &AL << Idx << AANT_ArgumentIntegerConstant << E->getSourceRange();
5750 return nullptr;
5751 }
5752 // Make sure we can fit it in 32 bits.
5753 if (!I->isIntN(32)) {
5754 S.Diag(E->getExprLoc(), diag::err_ice_too_large)
5755 << toString(*I, 10, false) << 32 << /* Unsigned */ 1;
5756 return nullptr;
5757 }
5758 if (*I < 0)
5759 S.Diag(E->getExprLoc(), diag::warn_attribute_argument_n_negative)
5760 << &AL << Idx << E->getSourceRange();
5761
5762 // We may need to perform implicit conversion of the argument.
5764 S.Context, S.Context.getConstType(S.Context.IntTy), /*consume*/ false);
5765 ExprResult ValArg = S.PerformCopyInitialization(Entity, SourceLocation(), E);
5766 assert(!ValArg.isInvalid() &&
5767 "Unexpected PerformCopyInitialization() failure.");
5768
5769 return ValArg.getAs<Expr>();
5770}
5771
5772CUDALaunchBoundsAttr *
5774 Expr *MinBlocks, Expr *MaxBlocks) {
5775 CUDALaunchBoundsAttr TmpAttr(Context, CI, MaxThreads, MinBlocks, MaxBlocks);
5776 MaxThreads = makeLaunchBoundsArgExpr(*this, MaxThreads, TmpAttr, 0);
5777 if (!MaxThreads)
5778 return nullptr;
5779
5780 if (MinBlocks) {
5781 MinBlocks = makeLaunchBoundsArgExpr(*this, MinBlocks, TmpAttr, 1);
5782 if (!MinBlocks)
5783 return nullptr;
5784 }
5785
5786 if (MaxBlocks) {
5787 // '.maxclusterrank' ptx directive requires .target sm_90 or higher.
5789 if (SM == CudaArch::UNKNOWN || SM < CudaArch::SM_90) {
5790 Diag(MaxBlocks->getBeginLoc(), diag::warn_cuda_maxclusterrank_sm_90)
5791 << CudaArchToString(SM) << CI << MaxBlocks->getSourceRange();
5792 // Ignore it by setting MaxBlocks to null;
5793 MaxBlocks = nullptr;
5794 } else {
5795 MaxBlocks = makeLaunchBoundsArgExpr(*this, MaxBlocks, TmpAttr, 2);
5796 if (!MaxBlocks)
5797 return nullptr;
5798 }
5799 }
5800
5801 return ::new (Context)
5802 CUDALaunchBoundsAttr(Context, CI, MaxThreads, MinBlocks, MaxBlocks);
5803}
5804
5806 Expr *MaxThreads, Expr *MinBlocks,
5807 Expr *MaxBlocks) {
5808 if (auto *Attr = CreateLaunchBoundsAttr(CI, MaxThreads, MinBlocks, MaxBlocks))
5809 D->addAttr(Attr);
5810}
5811
5812static void handleLaunchBoundsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5813 if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 3))
5814 return;
5815
5816 S.AddLaunchBoundsAttr(D, AL, AL.getArgAsExpr(0),
5817 AL.getNumArgs() > 1 ? AL.getArgAsExpr(1) : nullptr,
5818 AL.getNumArgs() > 2 ? AL.getArgAsExpr(2) : nullptr);
5819}
5820
5822 const ParsedAttr &AL) {
5823 if (!AL.isArgIdent(0)) {
5824 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
5825 << AL << /* arg num = */ 1 << AANT_ArgumentIdentifier;
5826 return;
5827 }
5828
5829 ParamIdx ArgumentIdx;
5830 if (!checkFunctionOrMethodParameterIndex(S, D, AL, 2, AL.getArgAsExpr(1),
5831 ArgumentIdx))
5832 return;
5833
5834 ParamIdx TypeTagIdx;
5835 if (!checkFunctionOrMethodParameterIndex(S, D, AL, 3, AL.getArgAsExpr(2),
5836 TypeTagIdx))
5837 return;
5838
5839 bool IsPointer = AL.getAttrName()->getName() == "pointer_with_type_tag";
5840 if (IsPointer) {
5841 // Ensure that buffer has a pointer type.
5842 unsigned ArgumentIdxAST = ArgumentIdx.getASTIndex();
5843 if (ArgumentIdxAST >= getFunctionOrMethodNumParams(D) ||
5844 !getFunctionOrMethodParamType(D, ArgumentIdxAST)->isPointerType())
5845 S.Diag(AL.getLoc(), diag::err_attribute_pointers_only) << AL << 0;
5846 }
5847
5848 D->addAttr(::new (S.Context) ArgumentWithTypeTagAttr(
5849 S.Context, AL, AL.getArgAsIdent(0)->Ident, ArgumentIdx, TypeTagIdx,
5850 IsPointer));
5851}
5852
5854 const ParsedAttr &AL) {
5855 if (!AL.isArgIdent(0)) {
5856 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
5857 << AL << 1 << AANT_ArgumentIdentifier;
5858 return;
5859 }
5860
5861 if (!AL.checkExactlyNumArgs(S, 1))
5862 return;
5863
5864 if (!isa<VarDecl>(D)) {
5865 S.Diag(AL.getLoc(), diag::err_attribute_wrong_decl_type)
5867 return;
5868 }
5869
5870 IdentifierInfo *PointerKind = AL.getArgAsIdent(0)->Ident;
5871 TypeSourceInfo *MatchingCTypeLoc = nullptr;
5872 S.GetTypeFromParser(AL.getMatchingCType(), &MatchingCTypeLoc);
5873 assert(MatchingCTypeLoc && "no type source info for attribute argument");
5874
5875 D->addAttr(::new (S.Context) TypeTagForDatatypeAttr(
5876 S.Context, AL, PointerKind, MatchingCTypeLoc, AL.getLayoutCompatible(),
5877 AL.getMustBeNull()));
5878}
5879
5880static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5881 ParamIdx ArgCount;
5882
5883 if (!checkFunctionOrMethodParameterIndex(S, D, AL, 1, AL.getArgAsExpr(0),
5884 ArgCount,
5885 true /* CanIndexImplicitThis */))
5886 return;
5887
5888 // ArgCount isn't a parameter index [0;n), it's a count [1;n]
5889 D->addAttr(::new (S.Context)
5890 XRayLogArgsAttr(S.Context, AL, ArgCount.getSourceIndex()));
5891}
5892
5894 const ParsedAttr &AL) {
5895 uint32_t Count = 0, Offset = 0;
5896 if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), Count, 0, true))
5897 return;
5898 if (AL.getNumArgs() == 2) {
5899 Expr *Arg = AL.getArgAsExpr(1);
5900 if (!checkUInt32Argument(S, AL, Arg, Offset, 1, true))
5901 return;
5902 if (Count < Offset) {
5903 S.Diag(getAttrLoc(AL), diag::err_attribute_argument_out_of_range)
5904 << &AL << 0 << Count << Arg->getBeginLoc();
5905 return;
5906 }
5907 }
5908 D->addAttr(::new (S.Context)
5909 PatchableFunctionEntryAttr(S.Context, AL, Count, Offset));
5910}
5911
5912namespace {
5913struct IntrinToName {
5914 uint32_t Id;
5915 int32_t FullName;
5916 int32_t ShortName;
5917};
5918} // unnamed namespace
5919
5920static bool ArmBuiltinAliasValid(unsigned BuiltinID, StringRef AliasName,
5922 const char *IntrinNames) {
5923 AliasName.consume_front("__arm_");
5924 const IntrinToName *It =
5925 llvm::lower_bound(Map, BuiltinID, [](const IntrinToName &L, unsigned Id) {
5926 return L.Id < Id;
5927 });
5928 if (It == Map.end() || It->Id != BuiltinID)
5929 return false;
5930 StringRef FullName(&IntrinNames[It->FullName]);
5931 if (AliasName == FullName)
5932 return true;
5933 if (It->ShortName == -1)
5934 return false;
5935 StringRef ShortName(&IntrinNames[It->ShortName]);
5936 return AliasName == ShortName;
5937}
5938
5939static bool ArmMveAliasValid(unsigned BuiltinID, StringRef AliasName) {
5940#include "clang/Basic/arm_mve_builtin_aliases.inc"
5941 // The included file defines:
5942 // - ArrayRef<IntrinToName> Map
5943 // - const char IntrinNames[]
5944 return ArmBuiltinAliasValid(BuiltinID, AliasName, Map, IntrinNames);
5945}
5946
5947static bool ArmCdeAliasValid(unsigned BuiltinID, StringRef AliasName) {
5948#include "clang/Basic/arm_cde_builtin_aliases.inc"
5949 return ArmBuiltinAliasValid(BuiltinID, AliasName, Map, IntrinNames);
5950}
5951
5952static bool ArmSveAliasValid(ASTContext &Context, unsigned BuiltinID,
5953 StringRef AliasName) {
5954 if (Context.BuiltinInfo.isAuxBuiltinID(BuiltinID))
5955 BuiltinID = Context.BuiltinInfo.getAuxBuiltinID(BuiltinID);
5956 return BuiltinID >= AArch64::FirstSVEBuiltin &&
5957 BuiltinID <= AArch64::LastSVEBuiltin;
5958}
5959
5960static bool ArmSmeAliasValid(ASTContext &Context, unsigned BuiltinID,
5961 StringRef AliasName) {
5962 if (Context.BuiltinInfo.isAuxBuiltinID(BuiltinID))
5963 BuiltinID = Context.BuiltinInfo.getAuxBuiltinID(BuiltinID);
5964 return BuiltinID >= AArch64::FirstSMEBuiltin &&
5965 BuiltinID <= AArch64::LastSMEBuiltin;
5966}
5967
5968static void handleArmBuiltinAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5969 if (!AL.isArgIdent(0)) {
5970 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
5971 << AL << 1 << AANT_ArgumentIdentifier;
5972 return;
5973 }
5974
5975 IdentifierInfo *Ident = AL.getArgAsIdent(0)->Ident;
5976 unsigned BuiltinID = Ident->getBuiltinID();
5977 StringRef AliasName = cast<FunctionDecl>(D)->getIdentifier()->getName();
5978
5979 bool IsAArch64 = S.Context.getTargetInfo().getTriple().isAArch64();
5980 if ((IsAArch64 && !ArmSveAliasValid(S.Context, BuiltinID, AliasName) &&
5981 !ArmSmeAliasValid(S.Context, BuiltinID, AliasName)) ||
5982 (!IsAArch64 && !ArmMveAliasValid(BuiltinID, AliasName) &&
5983 !ArmCdeAliasValid(BuiltinID, AliasName))) {
5984 S.Diag(AL.getLoc(), diag::err_attribute_arm_builtin_alias);
5985 return;
5986 }
5987
5988 D->addAttr(::new (S.Context) ArmBuiltinAliasAttr(S.Context, AL, Ident));
5989}
5990
5991static bool RISCVAliasValid(unsigned BuiltinID, StringRef AliasName) {
5992 return BuiltinID >= RISCV::FirstRVVBuiltin &&
5993 BuiltinID <= RISCV::LastRVVBuiltin;
5994}
5995
5997 const ParsedAttr &AL) {
5998 if (!AL.isArgIdent(0)) {
5999 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
6000 << AL << 1 << AANT_ArgumentIdentifier;
6001 return;
6002 }
6003
6004 IdentifierInfo *Ident = AL.getArgAsIdent(0)->Ident;
6005 unsigned BuiltinID = Ident->getBuiltinID();
6006 StringRef AliasName = cast<FunctionDecl>(D)->getIdentifier()->getName();
6007
6008 bool IsAArch64 = S.Context.getTargetInfo().getTriple().isAArch64();
6009 bool IsARM = S.Context.getTargetInfo().getTriple().isARM();
6010 bool IsRISCV = S.Context.getTargetInfo().getTriple().isRISCV();
6011 bool IsHLSL = S.Context.getLangOpts().HLSL;
6012 if ((IsAArch64 && !ArmSveAliasValid(S.Context, BuiltinID, AliasName)) ||
6013 (IsARM && !ArmMveAliasValid(BuiltinID, AliasName) &&
6014 !ArmCdeAliasValid(BuiltinID, AliasName)) ||
6015 (IsRISCV && !RISCVAliasValid(BuiltinID, AliasName)) ||
6016 (!IsAArch64 && !IsARM && !IsRISCV && !IsHLSL)) {
6017 S.Diag(AL.getLoc(), diag::err_attribute_builtin_alias) << AL;
6018 return;
6019 }
6020
6021 D->addAttr(::new (S.Context) BuiltinAliasAttr(S.Context, AL, Ident));
6022}
6023
6024static void handleNullableTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6025 if (AL.isUsedAsTypeAttr())
6026 return;
6027
6028 if (auto *CRD = dyn_cast<CXXRecordDecl>(D);
6029 !CRD || !(CRD->isClass() || CRD->isStruct())) {
6030 S.Diag(AL.getRange().getBegin(), diag::err_attribute_wrong_decl_type_str)
6031 << AL << AL.isRegularKeywordAttribute() << "classes";
6032 return;
6033 }
6034
6035 handleSimpleAttribute<TypeNullableAttr>(S, D, AL);
6036}
6037
6038static void handlePreferredTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6039 if (!AL.hasParsedType()) {
6040 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
6041 return;
6042 }
6043
6044 TypeSourceInfo *ParmTSI = nullptr;
6045 QualType QT = S.GetTypeFromParser(AL.getTypeArg(), &ParmTSI);
6046 assert(ParmTSI && "no type source info for attribute argument");
6047 S.RequireCompleteType(ParmTSI->getTypeLoc().getBeginLoc(), QT,
6048 diag::err_incomplete_type);
6049
6050 D->addAttr(::new (S.Context) PreferredTypeAttr(S.Context, AL, ParmTSI));
6051}
6052
6053//===----------------------------------------------------------------------===//
6054// Checker-specific attribute handlers.
6055//===----------------------------------------------------------------------===//
6057 return QT->isDependentType() || QT->isObjCRetainableType();
6058}
6059
6061 return QT->isDependentType() || QT->isObjCObjectPointerType() ||
6062 QT->isObjCNSObjectType();
6063}
6064
6066 return QT->isDependentType() || QT->isPointerType() ||
6068}
6069
6071 if (QT->isDependentType())
6072 return true;
6073 QualType PT = QT->getPointeeType();
6074 return !PT.isNull() && PT->getAsCXXRecordDecl() != nullptr;
6075}
6076
6079 bool IsTemplateInstantiation) {
6080 ValueDecl *VD = cast<ValueDecl>(D);
6081 switch (K) {
6083 handleSimpleAttributeOrDiagnose<OSConsumedAttr>(
6084 *this, VD, CI, isValidSubjectOfOSAttribute(VD->getType()),
6085 diag::warn_ns_attribute_wrong_parameter_type,
6086 /*ExtraArgs=*/CI.getRange(), "os_consumed", /*pointers*/ 1);
6087 return;
6089 handleSimpleAttributeOrDiagnose<NSConsumedAttr>(
6090 *this, VD, CI, isValidSubjectOfNSAttribute(VD->getType()),
6091
6092 // These attributes are normally just advisory, but in ARC, ns_consumed
6093 // is significant. Allow non-dependent code to contain inappropriate
6094 // attributes even in ARC, but require template instantiations to be
6095 // set up correctly.
6096 ((IsTemplateInstantiation && getLangOpts().ObjCAutoRefCount)
6097 ? diag::err_ns_attribute_wrong_parameter_type
6098 : diag::warn_ns_attribute_wrong_parameter_type),
6099 /*ExtraArgs=*/CI.getRange(), "ns_consumed", /*objc pointers*/ 0);
6100 return;
6102 handleSimpleAttributeOrDiagnose<CFConsumedAttr>(
6103 *this, VD, CI, isValidSubjectOfCFAttribute(VD->getType()),
6104 diag::warn_ns_attribute_wrong_parameter_type,
6105 /*ExtraArgs=*/CI.getRange(), "cf_consumed", /*pointers*/ 1);
6106 return;
6107 }
6108}
6109
6112 switch (AL.getKind()) {
6113 case ParsedAttr::AT_CFConsumed:
6114 case ParsedAttr::AT_CFReturnsRetained:
6115 case ParsedAttr::AT_CFReturnsNotRetained:
6117 case ParsedAttr::AT_OSConsumesThis:
6118 case ParsedAttr::AT_OSConsumed:
6119 case ParsedAttr::AT_OSReturnsRetained:
6120 case ParsedAttr::AT_OSReturnsNotRetained:
6121 case ParsedAttr::AT_OSReturnsRetainedOnZero:
6122 case ParsedAttr::AT_OSReturnsRetainedOnNonZero:
6124 case ParsedAttr::AT_NSConsumesSelf:
6125 case ParsedAttr::AT_NSConsumed:
6126 case ParsedAttr::AT_NSReturnsRetained:
6127 case ParsedAttr::AT_NSReturnsNotRetained:
6128 case ParsedAttr::AT_NSReturnsAutoreleased:
6130 default:
6131 llvm_unreachable("Wrong argument supplied");
6132 }
6133}
6134
6137 return false;
6138
6139 Diag(Loc, diag::warn_ns_attribute_wrong_return_type)
6140 << "'ns_returns_retained'" << 0 << 0;
6141 return true;
6142}
6143
6144/// \return whether the parameter is a pointer to OSObject pointer.
6145static bool isValidOSObjectOutParameter(const Decl *D) {
6146 const auto *PVD = dyn_cast<ParmVarDecl>(D);
6147 if (!PVD)
6148 return false;
6149 QualType QT = PVD->getType();
6150 QualType PT = QT->getPointeeType();
6151 return !PT.isNull() && isValidSubjectOfOSAttribute(PT);
6152}
6153
6155 const ParsedAttr &AL) {
6156 QualType ReturnType;
6158
6159 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
6160 ReturnType = MD->getReturnType();
6161 } else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) &&
6162 (AL.getKind() == ParsedAttr::AT_NSReturnsRetained)) {
6163 return; // ignore: was handled as a type attribute
6164 } else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) {
6165 ReturnType = PD->getType();
6166 } else if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
6167 ReturnType = FD->getReturnType();
6168 } else if (const auto *Param = dyn_cast<ParmVarDecl>(D)) {
6169 // Attributes on parameters are used for out-parameters,
6170 // passed as pointers-to-pointers.
6171 unsigned DiagID = K == Sema::RetainOwnershipKind::CF
6172 ? /*pointer-to-CF-pointer*/2
6173 : /*pointer-to-OSObject-pointer*/3;
6174 ReturnType = Param->getType()->getPointeeType();
6175 if (ReturnType.isNull()) {
6176 S.Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_parameter_type)
6177 << AL << DiagID << AL.getRange();
6178 return;
6179 }
6180 } else if (AL.isUsedAsTypeAttr()) {
6181 return;
6182 } else {
6183 AttributeDeclKind ExpectedDeclKind;
6184 switch (AL.getKind()) {
6185 default: llvm_unreachable("invalid ownership attribute");
6186 case ParsedAttr::AT_NSReturnsRetained:
6187 case ParsedAttr::AT_NSReturnsAutoreleased:
6188 case ParsedAttr::AT_NSReturnsNotRetained:
6189 ExpectedDeclKind = ExpectedFunctionOrMethod;
6190 break;
6191
6192 case ParsedAttr::AT_OSReturnsRetained:
6193 case ParsedAttr::AT_OSReturnsNotRetained:
6194 case ParsedAttr::AT_CFReturnsRetained:
6195 case ParsedAttr::AT_CFReturnsNotRetained:
6196 ExpectedDeclKind = ExpectedFunctionMethodOrParameter;
6197 break;
6198 }
6199 S.Diag(D->getBeginLoc(), diag::warn_attribute_wrong_decl_type)
6200 << AL.getRange() << AL << AL.isRegularKeywordAttribute()
6201 << ExpectedDeclKind;
6202 return;
6203 }
6204
6205 bool TypeOK;
6206 bool Cf;
6207 unsigned ParmDiagID = 2; // Pointer-to-CF-pointer
6208 switch (AL.getKind()) {
6209 default: llvm_unreachable("invalid ownership attribute");
6210 case ParsedAttr::AT_NSReturnsRetained:
6211 TypeOK = isValidSubjectOfNSReturnsRetainedAttribute(ReturnType);
6212 Cf = false;
6213 break;
6214
6215 case ParsedAttr::AT_NSReturnsAutoreleased:
6216 case ParsedAttr::AT_NSReturnsNotRetained:
6217 TypeOK = isValidSubjectOfNSAttribute(ReturnType);
6218 Cf = false;
6219 break;
6220
6221 case ParsedAttr::AT_CFReturnsRetained:
6222 case ParsedAttr::AT_CFReturnsNotRetained:
6223 TypeOK = isValidSubjectOfCFAttribute(ReturnType);
6224 Cf = true;
6225 break;
6226
6227 case ParsedAttr::AT_OSReturnsRetained:
6228 case ParsedAttr::AT_OSReturnsNotRetained:
6229 TypeOK = isValidSubjectOfOSAttribute(ReturnType);
6230 Cf = true;
6231 ParmDiagID = 3; // Pointer-to-OSObject-pointer
6232 break;
6233 }
6234
6235 if (!TypeOK) {
6236 if (AL.isUsedAsTypeAttr())
6237 return;
6238
6239 if (isa<ParmVarDecl>(D)) {
6240 S.Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_parameter_type)
6241 << AL << ParmDiagID << AL.getRange();
6242 } else {
6243 // Needs to be kept in sync with warn_ns_attribute_wrong_return_type.
6244 enum : unsigned {
6245 Function,
6246 Method,
6247 Property
6248 } SubjectKind = Function;
6249 if (isa<ObjCMethodDecl>(D))
6250 SubjectKind = Method;
6251 else if (isa<ObjCPropertyDecl>(D))
6252 SubjectKind = Property;
6253 S.Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_return_type)
6254 << AL << SubjectKind << Cf << AL.getRange();
6255 }
6256 return;
6257 }
6258
6259 switch (AL.getKind()) {
6260 default:
6261 llvm_unreachable("invalid ownership attribute");
6262 case ParsedAttr::AT_NSReturnsAutoreleased:
6263 handleSimpleAttribute<NSReturnsAutoreleasedAttr>(S, D, AL);
6264 return;
6265 case ParsedAttr::AT_CFReturnsNotRetained:
6266 handleSimpleAttribute<CFReturnsNotRetainedAttr>(S, D, AL);
6267 return;
6268 case ParsedAttr::AT_NSReturnsNotRetained:
6269 handleSimpleAttribute<NSReturnsNotRetainedAttr>(S, D, AL);
6270 return;
6271 case ParsedAttr::AT_CFReturnsRetained:
6272 handleSimpleAttribute<CFReturnsRetainedAttr>(S, D, AL);
6273 return;
6274 case ParsedAttr::AT_NSReturnsRetained:
6275 handleSimpleAttribute<NSReturnsRetainedAttr>(S, D, AL);
6276 return;
6277 case ParsedAttr::AT_OSReturnsRetained:
6278 handleSimpleAttribute<OSReturnsRetainedAttr>(S, D, AL);
6279 return;
6280 case ParsedAttr::AT_OSReturnsNotRetained:
6281 handleSimpleAttribute<OSReturnsNotRetainedAttr>(S, D, AL);
6282 return;
6283 };
6284}
6285
6287 const ParsedAttr &Attrs) {
6288 const int EP_ObjCMethod = 1;
6289 const int EP_ObjCProperty = 2;
6290
6291 SourceLocation loc = Attrs.getLoc();
6292 QualType resultType;
6293 if (isa<ObjCMethodDecl>(D))
6294 resultType = cast<ObjCMethodDecl>(D)->getReturnType();
6295 else
6296 resultType = cast<ObjCPropertyDecl>(D)->getType();
6297
6298 if (!resultType->isReferenceType() &&
6299 (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
6300 S.Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_return_type)
6301 << SourceRange(loc) << Attrs
6302 << (isa<ObjCMethodDecl>(D) ? EP_ObjCMethod : EP_ObjCProperty)
6303 << /*non-retainable pointer*/ 2;
6304
6305 // Drop the attribute.
6306 return;
6307 }
6308
6309 D->addAttr(::new (S.Context) ObjCReturnsInnerPointerAttr(S.Context, Attrs));
6310}
6311
6313 const ParsedAttr &Attrs) {
6314 const auto *Method = cast<ObjCMethodDecl>(D);
6315
6316 const DeclContext *DC = Method->getDeclContext();
6317 if (const auto *PDecl = dyn_cast_if_present<ObjCProtocolDecl>(DC)) {
6318 S.Diag(D->getBeginLoc(), diag::warn_objc_requires_super_protocol) << Attrs
6319 << 0;
6320 S.Diag(PDecl->getLocation(), diag::note_protocol_decl);
6321 return;
6322 }
6323 if (Method->getMethodFamily() == OMF_dealloc) {
6324 S.Diag(D->getBeginLoc(), diag::warn_objc_requires_super_protocol) << Attrs
6325 << 1;
6326 return;
6327 }
6328
6329 D->addAttr(::new (S.Context) ObjCRequiresSuperAttr(S.Context, Attrs));
6330}
6331
6332static void handleNSErrorDomain(Sema &S, Decl *D, const ParsedAttr &Attr) {
6333 if (!isa<TagDecl>(D)) {
6334 S.Diag(D->getBeginLoc(), diag::err_nserrordomain_invalid_decl) << 0;
6335 return;
6336 }
6337
6338 IdentifierLoc *IdentLoc =
6339 Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : nullptr;
6340 if (!IdentLoc || !IdentLoc->Ident) {
6341 // Try to locate the argument directly.
6343 if (Attr.isArgExpr(0) && Attr.getArgAsExpr(0))
6344 Loc = Attr.getArgAsExpr(0)->getBeginLoc();
6345
6346 S.Diag(Loc, diag::err_nserrordomain_invalid_decl) << 0;
6347 return;
6348 }
6349
6350 // Verify that the identifier is a valid decl in the C decl namespace.
6353 if (!S.LookupName(Result, S.TUScope) || !Result.getAsSingle<VarDecl>()) {
6354 S.Diag(IdentLoc->Loc, diag::err_nserrordomain_invalid_decl)
6355 << 1 << IdentLoc->Ident;
6356 return;
6357 }
6358
6359 D->addAttr(::new (S.Context)
6360 NSErrorDomainAttr(S.Context, Attr, IdentLoc->Ident));
6361}
6362
6363static void handleObjCBridgeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6364 IdentifierLoc *Parm = AL.isArgIdent(0) ? AL.getArgAsIdent(0) : nullptr;
6365
6366 if (!Parm) {
6367 S.Diag(D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0;
6368 return;
6369 }
6370
6371 // Typedefs only allow objc_bridge(id) and have some additional checking.
6372 if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) {
6373 if (!Parm->Ident->isStr("id")) {
6374 S.Diag(AL.getLoc(), diag::err_objc_attr_typedef_not_id) << AL;
6375 return;
6376 }
6377
6378 // Only allow 'cv void *'.
6379 QualType T = TD->getUnderlyingType();
6380 if (!T->isVoidPointerType()) {
6381 S.Diag(AL.getLoc(), diag::err_objc_attr_typedef_not_void_pointer);
6382 return;
6383 }
6384 }
6385
6386 D->addAttr(::new (S.Context) ObjCBridgeAttr(S.Context, AL, Parm->Ident));
6387}
6388
6390 const ParsedAttr &AL) {
6391 IdentifierLoc *Parm = AL.isArgIdent(0) ? AL.getArgAsIdent(0) : nullptr;
6392
6393 if (!Parm) {
6394 S.Diag(D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0;
6395 return;
6396 }
6397
6398 D->addAttr(::new (S.Context)
6399 ObjCBridgeMutableAttr(S.Context, AL, Parm->Ident));
6400}
6401
6403 const ParsedAttr &AL) {
6404 IdentifierInfo *RelatedClass =
6405 AL.isArgIdent(0) ? AL.getArgAsIdent(0)->Ident : nullptr;
6406 if (!RelatedClass) {
6407 S.Diag(D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0;
6408 return;
6409 }
6410 IdentifierInfo *ClassMethod =
6411 AL.getArgAsIdent(1) ? AL.getArgAsIdent(1)->Ident : nullptr;
6412 IdentifierInfo *InstanceMethod =
6413 AL.getArgAsIdent(2) ? AL.getArgAsIdent(2)->Ident : nullptr;
6414 D->addAttr(::new (S.Context) ObjCBridgeRelatedAttr(
6415 S.Context, AL, RelatedClass, ClassMethod, InstanceMethod));
6416}
6417
6419 const ParsedAttr &AL) {
6420 DeclContext *Ctx = D->getDeclContext();
6421
6422 // This attribute can only be applied to methods in interfaces or class
6423 // extensions.
6424 if (!isa<ObjCInterfaceDecl>(Ctx) &&
6425 !(isa<ObjCCategoryDecl>(Ctx) &&
6426 cast<ObjCCategoryDecl>(Ctx)->IsClassExtension())) {
6427 S.Diag(D->getLocation(), diag::err_designated_init_attr_non_init);
6428 return;
6429 }
6430
6431 ObjCInterfaceDecl *IFace;
6432 if (auto *CatDecl = dyn_cast<ObjCCategoryDecl>(Ctx))
6433 IFace = CatDecl->getClassInterface();
6434 else
6435 IFace = cast<ObjCInterfaceDecl>(Ctx);
6436
6437 if (!IFace)
6438 return;
6439
6441 D->addAttr(::new (S.Context) ObjCDesignatedInitializerAttr(S.Context, AL));
6442}
6443
6444static void handleObjCRuntimeName(Sema &S, Decl *D, const ParsedAttr &AL) {
6445 StringRef MetaDataName;
6446 if (!S.checkStringLiteralArgumentAttr(AL, 0, MetaDataName))
6447 return;
6448 D->addAttr(::new (S.Context)
6449 ObjCRuntimeNameAttr(S.Context, AL, MetaDataName));
6450}
6451
6452// When a user wants to use objc_boxable with a union or struct
6453// but they don't have access to the declaration (legacy/third-party code)
6454// then they can 'enable' this feature with a typedef:
6455// typedef struct __attribute((objc_boxable)) legacy_struct legacy_struct;
6456static void handleObjCBoxable(Sema &S, Decl *D, const ParsedAttr &AL) {
6457 bool notify = false;
6458
6459 auto *RD = dyn_cast<RecordDecl>(D);
6460 if (RD && RD->getDefinition()) {
6461 RD = RD->getDefinition();
6462 notify = true;
6463 }
6464
6465 if (RD) {
6466 ObjCBoxableAttr *BoxableAttr =
6467 ::new (S.Context) ObjCBoxableAttr(S.Context, AL);
6468 RD->addAttr(BoxableAttr);
6469 if (notify) {
6470 // we need to notify ASTReader/ASTWriter about
6471 // modification of existing declaration
6473 L->AddedAttributeToRecord(BoxableAttr, RD);
6474 }
6475 }
6476}
6477
6478static void handleObjCOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6479 if (hasDeclarator(D))
6480 return;
6481
6482 S.Diag(D->getBeginLoc(), diag::err_attribute_wrong_decl_type)
6483 << AL.getRange() << AL << AL.isRegularKeywordAttribute()
6485}
6486
6488 const ParsedAttr &AL) {
6489 const auto *VD = cast<ValueDecl>(D);
6490 QualType QT = VD->getType();
6491
6492 if (!QT->isDependentType() &&
6493 !QT->isObjCLifetimeType()) {
6494 S.Diag(AL.getLoc(), diag::err_objc_precise_lifetime_bad_type)
6495 << QT;
6496 return;
6497 }
6498
6500
6501 // If we have no lifetime yet, check the lifetime we're presumably
6502 // going to infer.
6503 if (Lifetime == Qualifiers::OCL_None && !QT->isDependentType())
6504 Lifetime = QT->getObjCARCImplicitLifetime();
6505
6506 switch (Lifetime) {
6508 assert(QT->isDependentType() &&
6509 "didn't infer lifetime for non-dependent type?");
6510 break;
6511
6512 case Qualifiers::OCL_Weak: // meaningful
6513 case Qualifiers::OCL_Strong: // meaningful
6514 break;
6515
6518 S.Diag(AL.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
6519 << (Lifetime == Qualifiers::OCL_Autoreleasing);
6520 break;
6521 }
6522
6523 D->addAttr(::new (S.Context) ObjCPreciseLifetimeAttr(S.Context, AL));
6524}
6525
6526static void handleSwiftAttrAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6527 // Make sure that there is a string literal as the annotation's single
6528 // argument.
6529 StringRef Str;
6530 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
6531 return;
6532
6533 D->addAttr(::new (S.Context) SwiftAttrAttr(S.Context, AL, Str));
6534}
6535
6536static void handleSwiftBridge(Sema &S, Decl *D, const ParsedAttr &AL) {
6537 // Make sure that there is a string literal as the annotation's single
6538 // argument.
6539 StringRef BT;
6540 if (!S.checkStringLiteralArgumentAttr(AL, 0, BT))
6541 return;
6542
6543 // Warn about duplicate attributes if they have different arguments, but drop
6544 // any duplicate attributes regardless.
6545 if (const auto *Other = D->getAttr<SwiftBridgeAttr>()) {
6546 if (Other->getSwiftType() != BT)
6547 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
6548 return;
6549 }
6550
6551 D->addAttr(::new (S.Context) SwiftBridgeAttr(S.Context, AL, BT));
6552}
6553
6554static bool isErrorParameter(Sema &S, QualType QT) {
6555 const auto *PT = QT->getAs<PointerType>();
6556 if (!PT)
6557 return false;
6558
6559 QualType Pointee = PT->getPointeeType();
6560
6561 // Check for NSError**.
6562 if (const auto *OPT = Pointee->getAs<ObjCObjectPointerType>())
6563 if (const auto *ID = OPT->getInterfaceDecl())
6564 if (ID->getIdentifier() == S.ObjC().getNSErrorIdent())
6565 return true;
6566
6567 // Check for CFError**.
6568 if (const auto *PT = Pointee->getAs<PointerType>())
6569 if (const auto *RT = PT->getPointeeType()->getAs<RecordType>())
6570 if (S.ObjC().isCFError(RT->getDecl()))
6571 return true;
6572
6573 return false;
6574}
6575
6576static void handleSwiftError(Sema &S, Decl *D, const ParsedAttr &AL) {
6577 auto hasErrorParameter = [](Sema &S, Decl *D, const ParsedAttr &AL) -> bool {
6578 for (unsigned I = 0, E = getFunctionOrMethodNumParams(D); I != E; ++I) {
6580 return true;
6581 }
6582
6583 S.Diag(AL.getLoc(), diag::err_attr_swift_error_no_error_parameter)
6584 << AL << isa<ObjCMethodDecl>(D);
6585 return false;
6586 };
6587
6588 auto hasPointerResult = [](Sema &S, Decl *D, const ParsedAttr &AL) -> bool {
6589 // - C, ObjC, and block pointers are definitely okay.
6590 // - References are definitely not okay.
6591 // - nullptr_t is weird, but acceptable.
6593 if (RT->hasPointerRepresentation() && !RT->isReferenceType())
6594 return true;
6595
6596 S.Diag(AL.getLoc(), diag::err_attr_swift_error_return_type)
6597 << AL << AL.getArgAsIdent(0)->Ident->getName() << isa<ObjCMethodDecl>(D)
6598 << /*pointer*/ 1;
6599 return false;
6600 };
6601
6602 auto hasIntegerResult = [](Sema &S, Decl *D, const ParsedAttr &AL) -> bool {
6604 if (RT->isIntegralType(S.Context))
6605 return true;
6606
6607 S.Diag(AL.getLoc(), diag::err_attr_swift_error_return_type)
6608 << AL << AL.getArgAsIdent(0)->Ident->getName() << isa<ObjCMethodDecl>(D)
6609 << /*integral*/ 0;
6610 return false;
6611 };
6612
6613 if (D->isInvalidDecl())
6614 return;
6615
6617 SwiftErrorAttr::ConventionKind Convention;
6618 if (!SwiftErrorAttr::ConvertStrToConventionKind(Loc->Ident->getName(),
6619 Convention)) {
6620 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
6621 << AL << Loc->Ident;
6622 return;
6623 }
6624
6625 switch (Convention) {
6626 case SwiftErrorAttr::None:
6627 // No additional validation required.
6628 break;
6629
6630 case SwiftErrorAttr::NonNullError:
6631 if (!hasErrorParameter(S, D, AL))
6632 return;
6633 break;
6634
6635 case SwiftErrorAttr::NullResult:
6636 if (!hasErrorParameter(S, D, AL) || !hasPointerResult(S, D, AL))
6637 return;
6638 break;
6639
6640 case SwiftErrorAttr::NonZeroResult:
6641 case SwiftErrorAttr::ZeroResult:
6642 if (!hasErrorParameter(S, D, AL) || !hasIntegerResult(S, D, AL))
6643 return;
6644 break;
6645 }
6646
6647 D->addAttr(::new (S.Context) SwiftErrorAttr(S.Context, AL, Convention));
6648}
6649
6651 const SwiftAsyncErrorAttr *ErrorAttr,
6652 const SwiftAsyncAttr *AsyncAttr) {
6653 if (AsyncAttr->getKind() == SwiftAsyncAttr::None) {
6654 if (ErrorAttr->getConvention() != SwiftAsyncErrorAttr::None) {
6655 S.Diag(AsyncAttr->getLocation(),
6656 diag::err_swift_async_error_without_swift_async)
6657 << AsyncAttr << isa<ObjCMethodDecl>(D);
6658 }
6659 return;
6660 }
6661
6662 const ParmVarDecl *HandlerParam = getFunctionOrMethodParam(
6663 D, AsyncAttr->getCompletionHandlerIndex().getASTIndex());
6664 // handleSwiftAsyncAttr already verified the type is correct, so no need to
6665 // double-check it here.
6666 const auto *FuncTy = HandlerParam->getType()
6668 ->getPointeeType()
6670 ArrayRef<QualType> BlockParams;
6671 if (FuncTy)
6672 BlockParams = FuncTy->getParamTypes();
6673
6674 switch (ErrorAttr->getConvention()) {
6675 case SwiftAsyncErrorAttr::ZeroArgument:
6676 case SwiftAsyncErrorAttr::NonZeroArgument: {
6677 uint32_t ParamIdx = ErrorAttr->getHandlerParamIdx();
6678 if (ParamIdx == 0 || ParamIdx > BlockParams.size()) {
6679 S.Diag(ErrorAttr->getLocation(),
6680 diag::err_attribute_argument_out_of_bounds) << ErrorAttr << 2;
6681 return;
6682 }
6683 QualType ErrorParam = BlockParams[ParamIdx - 1];
6684 if (!ErrorParam->isIntegralType(S.Context)) {
6685 StringRef ConvStr =
6686 ErrorAttr->getConvention() == SwiftAsyncErrorAttr::ZeroArgument
6687 ? "zero_argument"
6688 : "nonzero_argument";
6689 S.Diag(ErrorAttr->getLocation(), diag::err_swift_async_error_non_integral)
6690 << ErrorAttr << ConvStr << ParamIdx << ErrorParam;
6691 return;
6692 }
6693 break;
6694 }
6695 case SwiftAsyncErrorAttr::NonNullError: {
6696 bool AnyErrorParams = false;
6697 for (QualType Param : BlockParams) {
6698 // Check for NSError *.
6699 if (const auto *ObjCPtrTy = Param->getAs<ObjCObjectPointerType>()) {
6700 if (const auto *ID = ObjCPtrTy->getInterfaceDecl()) {
6701 if (ID->getIdentifier() == S.ObjC().getNSErrorIdent()) {
6702 AnyErrorParams = true;
6703 break;
6704 }
6705 }
6706 }
6707 // Check for CFError *.
6708 if (const auto *PtrTy = Param->getAs<PointerType>()) {
6709 if (const auto *RT = PtrTy->getPointeeType()->getAs<RecordType>()) {
6710 if (S.ObjC().isCFError(RT->getDecl())) {
6711 AnyErrorParams = true;
6712 break;
6713 }
6714 }
6715 }
6716 }
6717
6718 if (!AnyErrorParams) {
6719 S.Diag(ErrorAttr->getLocation(),
6720 diag::err_swift_async_error_no_error_parameter)
6721 << ErrorAttr << isa<ObjCMethodDecl>(D);
6722 return;
6723 }
6724 break;
6725 }
6726 case SwiftAsyncErrorAttr::None:
6727 break;
6728 }
6729}
6730
6731static void handleSwiftAsyncError(Sema &S, Decl *D, const ParsedAttr &AL) {
6732 IdentifierLoc *IDLoc = AL.getArgAsIdent(0);
6733 SwiftAsyncErrorAttr::ConventionKind ConvKind;
6734 if (!SwiftAsyncErrorAttr::ConvertStrToConventionKind(IDLoc->Ident->getName(),
6735 ConvKind)) {
6736 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
6737 << AL << IDLoc->Ident;
6738 return;
6739 }
6740
6741 uint32_t ParamIdx = 0;
6742 switch (ConvKind) {
6743 case SwiftAsyncErrorAttr::ZeroArgument:
6744 case SwiftAsyncErrorAttr::NonZeroArgument: {
6745 if (!AL.checkExactlyNumArgs(S, 2))
6746 return;
6747
6748 Expr *IdxExpr = AL.getArgAsExpr(1);
6749 if (!checkUInt32Argument(S, AL, IdxExpr, ParamIdx))
6750 return;
6751 break;
6752 }
6753 case SwiftAsyncErrorAttr::NonNullError:
6754 case SwiftAsyncErrorAttr::None: {
6755 if (!AL.checkExactlyNumArgs(S, 1))
6756 return;
6757 break;
6758 }
6759 }
6760
6761 auto *ErrorAttr =
6762 ::new (S.Context) SwiftAsyncErrorAttr(S.Context, AL, ConvKind, ParamIdx);
6763 D->addAttr(ErrorAttr);
6764
6765 if (auto *AsyncAttr = D->getAttr<SwiftAsyncAttr>())
6766 checkSwiftAsyncErrorBlock(S, D, ErrorAttr, AsyncAttr);
6767}
6768
6769// For a function, this will validate a compound Swift name, e.g.
6770// <code>init(foo:bar:baz:)</code> or <code>controllerForName(_:)</code>, and
6771// the function will output the number of parameter names, and whether this is a
6772// single-arg initializer.
6773//
6774// For a type, enum constant, property, or variable declaration, this will
6775// validate either a simple identifier, or a qualified
6776// <code>context.identifier</code> name.
6777static bool
6779 StringRef Name, unsigned &SwiftParamCount,
6780 bool &IsSingleParamInit) {
6781 SwiftParamCount = 0;
6782 IsSingleParamInit = false;
6783
6784 // Check whether this will be mapped to a getter or setter of a property.
6785 bool IsGetter = false, IsSetter = false;
6786 if (Name.consume_front("getter:"))
6787 IsGetter = true;
6788 else if (Name.consume_front("setter:"))
6789 IsSetter = true;
6790
6791 if (Name.back() != ')') {
6792 S.Diag(Loc, diag::warn_attr_swift_name_function) << AL;
6793 return false;
6794 }
6795
6796 bool IsMember = false;
6797 StringRef ContextName, BaseName, Parameters;
6798
6799 std::tie(BaseName, Parameters) = Name.split('(');
6800
6801 // Split at the first '.', if it exists, which separates the context name
6802 // from the base name.
6803 std::tie(ContextName, BaseName) = BaseName.split('.');
6804 if (BaseName.empty()) {
6805 BaseName = ContextName;
6806 ContextName = StringRef();
6807 } else if (ContextName.empty() || !isValidAsciiIdentifier(ContextName)) {
6808 S.Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
6809 << AL << /*context*/ 1;
6810 return false;
6811 } else {
6812 IsMember = true;
6813 }
6814
6815 if (!isValidAsciiIdentifier(BaseName) || BaseName == "_") {
6816 S.Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
6817 << AL << /*basename*/ 0;
6818 return false;
6819 }
6820
6821 bool IsSubscript = BaseName == "subscript";
6822 // A subscript accessor must be a getter or setter.
6823 if (IsSubscript && !IsGetter && !IsSetter) {
6824 S.Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
6825 << AL << /* getter or setter */ 0;
6826 return false;
6827 }
6828
6829 if (Parameters.empty()) {
6830 S.Diag(Loc, diag::warn_attr_swift_name_missing_parameters) << AL;
6831 return false;
6832 }
6833
6834 assert(Parameters.back() == ')' && "expected ')'");
6835 Parameters = Parameters.drop_back(); // ')'
6836
6837 if (Parameters.empty()) {
6838 // Setters and subscripts must have at least one parameter.
6839 if (IsSubscript) {
6840 S.Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
6841 << AL << /* have at least one parameter */1;
6842 return false;
6843 }
6844
6845 if (IsSetter) {
6846 S.Diag(Loc, diag::warn_attr_swift_name_setter_parameters) << AL;
6847 return false;
6848 }
6849
6850 return true;
6851 }
6852
6853 if (Parameters.back() != ':') {
6854 S.Diag(Loc, diag::warn_attr_swift_name_function) << AL;
6855 return false;
6856 }
6857
6858 StringRef CurrentParam;
6859 std::optional<unsigned> SelfLocation;
6860 unsigned NewValueCount = 0;
6861 std::optional<unsigned> NewValueLocation;
6862 do {
6863 std::tie(CurrentParam, Parameters) = Parameters.split(':');
6864
6865 if (!isValidAsciiIdentifier(CurrentParam)) {
6866 S.Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
6867 << AL << /*parameter*/2;
6868 return false;
6869 }
6870
6871 if (IsMember && CurrentParam == "self") {
6872 // "self" indicates the "self" argument for a member.
6873
6874 // More than one "self"?
6875 if (SelfLocation) {
6876 S.Diag(Loc, diag::warn_attr_swift_name_multiple_selfs) << AL;
6877 return false;
6878 }
6879
6880 // The "self" location is the current parameter.
6881 SelfLocation = SwiftParamCount;
6882 } else if (CurrentParam == "newValue") {
6883 // "newValue" indicates the "newValue" argument for a setter.
6884
6885 // There should only be one 'newValue', but it's only significant for
6886 // subscript accessors, so don't error right away.
6887 ++NewValueCount;
6888
6889 NewValueLocation = SwiftParamCount;
6890 }
6891
6892 ++SwiftParamCount;
6893 } while (!Parameters.empty());
6894
6895 // Only instance subscripts are currently supported.
6896 if (IsSubscript && !SelfLocation) {
6897 S.Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
6898 << AL << /*have a 'self:' parameter*/2;
6899 return false;
6900 }
6901
6902 IsSingleParamInit =
6903 SwiftParamCount == 1 && BaseName == "init" && CurrentParam != "_";
6904
6905 // Check the number of parameters for a getter/setter.
6906 if (IsGetter || IsSetter) {
6907 // Setters have one parameter for the new value.
6908 unsigned NumExpectedParams = IsGetter ? 0 : 1;
6909 unsigned ParamDiag =
6910 IsGetter ? diag::warn_attr_swift_name_getter_parameters
6911 : diag::warn_attr_swift_name_setter_parameters;
6912
6913 // Instance methods have one parameter for "self".
6914 if (SelfLocation)
6915 ++NumExpectedParams;
6916
6917 // Subscripts may have additional parameters beyond the expected params for
6918 // the index.
6919 if (IsSubscript) {
6920 if (SwiftParamCount < NumExpectedParams) {
6921 S.Diag(Loc, ParamDiag) << AL;
6922 return false;
6923 }
6924
6925 // A subscript setter must explicitly label its newValue parameter to
6926 // distinguish it from index parameters.
6927 if (IsSetter) {
6928 if (!NewValueLocation) {
6929 S.Diag(Loc, diag::warn_attr_swift_name_subscript_setter_no_newValue)
6930 << AL;
6931 return false;
6932 }
6933 if (NewValueCount > 1) {
6934 S.Diag(Loc, diag::warn_attr_swift_name_subscript_setter_multiple_newValues)
6935 << AL;
6936 return false;
6937 }
6938 } else {
6939 // Subscript getters should have no 'newValue:' parameter.
6940 if (NewValueLocation) {
6941 S.Diag(Loc, diag::warn_attr_swift_name_subscript_getter_newValue)
6942 << AL;
6943 return false;
6944 }
6945 }
6946 } else {
6947 // Property accessors must have exactly the number of expected params.
6948 if (SwiftParamCount != NumExpectedParams) {
6949 S.Diag(Loc, ParamDiag) << AL;
6950 return false;
6951 }
6952 }
6953 }
6954
6955 return true;
6956}
6957
6959 const ParsedAttr &AL, bool IsAsync) {
6960 if (isa<ObjCMethodDecl>(D) || isa<FunctionDecl>(D)) {
6962 unsigned ParamCount;
6963
6964 if (const auto *Method = dyn_cast<ObjCMethodDecl>(D)) {
6965 ParamCount = Method->getSelector().getNumArgs();
6966 Params = Method->parameters().slice(0, ParamCount);
6967 } else {
6968 const auto *F = cast<FunctionDecl>(D);
6969
6970 ParamCount = F->getNumParams();
6971 Params = F->parameters();
6972
6973 if (!F->hasWrittenPrototype()) {
6974 Diag(Loc, diag::warn_attribute_wrong_decl_type)
6975 << AL << AL.isRegularKeywordAttribute()
6977 return false;
6978 }
6979 }
6980
6981 // The async name drops the last callback parameter.
6982 if (IsAsync) {
6983 if (ParamCount == 0) {
6984 Diag(Loc, diag::warn_attr_swift_name_decl_missing_params)
6985 << AL << isa<ObjCMethodDecl>(D);
6986 return false;
6987 }
6988 ParamCount -= 1;
6989 }
6990
6991 unsigned SwiftParamCount;
6992 bool IsSingleParamInit;
6993 if (!validateSwiftFunctionName(*this, AL, Loc, Name,
6994 SwiftParamCount, IsSingleParamInit))
6995 return false;
6996
6997 bool ParamCountValid;
6998 if (SwiftParamCount == ParamCount) {
6999 ParamCountValid = true;
7000 } else if (SwiftParamCount > ParamCount) {
7001 ParamCountValid = IsSingleParamInit && ParamCount == 0;
7002 } else {
7003 // We have fewer Swift parameters than Objective-C parameters, but that
7004 // might be because we've transformed some of them. Check for potential
7005 // "out" parameters and err on the side of not warning.
7006 unsigned MaybeOutParamCount =
7007 llvm::count_if(Params, [](const ParmVarDecl *Param) -> bool {
7008 QualType ParamTy = Param->getType();
7009 if (ParamTy->isReferenceType() || ParamTy->isPointerType())
7010 return !ParamTy->getPointeeType().isConstQualified();
7011 return false;
7012 });
7013
7014 ParamCountValid = SwiftParamCount + MaybeOutParamCount >= ParamCount;
7015 }
7016
7017 if (!ParamCountValid) {
7018 Diag(Loc, diag::warn_attr_swift_name_num_params)
7019 << (SwiftParamCount > ParamCount) << AL << ParamCount
7020 << SwiftParamCount;
7021 return false;
7022 }
7023 } else if ((isa<EnumConstantDecl>(D) || isa<ObjCProtocolDecl>(D) ||
7024 isa<ObjCInterfaceDecl>(D) || isa<ObjCPropertyDecl>(D) ||
7025 isa<VarDecl>(D) || isa<TypedefNameDecl>(D) || isa<TagDecl>(D) ||
7026 isa<IndirectFieldDecl>(D) || isa<FieldDecl>(D)) &&
7027 !IsAsync) {
7028 StringRef ContextName, BaseName;
7029
7030 std::tie(ContextName, BaseName) = Name.split('.');
7031 if (BaseName.empty()) {
7032 BaseName = ContextName;
7033 ContextName = StringRef();
7034 } else if (!isValidAsciiIdentifier(ContextName)) {
7035 Diag(Loc, diag::warn_attr_swift_name_invalid_identifier) << AL
7036 << /*context*/1;
7037 return false;
7038 }
7039
7040 if (!isValidAsciiIdentifier(BaseName)) {
7041 Diag(Loc, diag::warn_attr_swift_name_invalid_identifier) << AL
7042 << /*basename*/0;
7043 return false;
7044 }
7045 } else {
7046 Diag(Loc, diag::warn_attr_swift_name_decl_kind) << AL;
7047 return false;
7048 }
7049 return true;
7050}
7051
7052static void handleSwiftName(Sema &S, Decl *D, const ParsedAttr &AL) {
7053 StringRef Name;
7055 if (!S.checkStringLiteralArgumentAttr(AL, 0, Name, &Loc))
7056 return;
7057
7058 if (!S.DiagnoseSwiftName(D, Name, Loc, AL, /*IsAsync=*/false))
7059 return;
7060
7061 D->addAttr(::new (S.Context) SwiftNameAttr(S.Context, AL, Name));
7062}
7063
7064static void handleSwiftAsyncName(Sema &S, Decl *D, const ParsedAttr &AL) {
7065 StringRef Name;
7067 if (!S.checkStringLiteralArgumentAttr(AL, 0, Name, &Loc))
7068 return;
7069
7070 if (!S.DiagnoseSwiftName(D, Name, Loc, AL, /*IsAsync=*/true))
7071 return;
7072
7073 D->addAttr(::new (S.Context) SwiftAsyncNameAttr(S.Context, AL, Name));
7074}
7075
7076static void handleSwiftNewType(Sema &S, Decl *D, const ParsedAttr &AL) {
7077 // Make sure that there is an identifier as the annotation's single argument.
7078 if (!AL.checkExactlyNumArgs(S, 1))
7079 return;
7080
7081 if (!AL.isArgIdent(0)) {
7082 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7083 << AL << AANT_ArgumentIdentifier;
7084 return;
7085 }
7086
7087 SwiftNewTypeAttr::NewtypeKind Kind;
7088 IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
7089 if (!SwiftNewTypeAttr::ConvertStrToNewtypeKind(II->getName(), Kind)) {
7090 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
7091 return;
7092 }
7093
7094 if (!isa<TypedefNameDecl>(D)) {
7095 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type_str)
7096 << AL << AL.isRegularKeywordAttribute() << "typedefs";
7097 return;
7098 }
7099
7100 D->addAttr(::new (S.Context) SwiftNewTypeAttr(S.Context, AL, Kind));
7101}
7102
7103static void handleSwiftAsyncAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7104 if (!AL.isArgIdent(0)) {
7105 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
7106 << AL << 1 << AANT_ArgumentIdentifier;
7107 return;
7108 }
7109
7110 SwiftAsyncAttr::Kind Kind;
7111 IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
7112 if (!SwiftAsyncAttr::ConvertStrToKind(II->getName(), Kind)) {
7113 S.Diag(AL.getLoc(), diag::err_swift_async_no_access) << AL << II;
7114 return;
7115 }
7116
7117 ParamIdx Idx;
7118 if (Kind == SwiftAsyncAttr::None) {
7119 // If this is 'none', then there shouldn't be any additional arguments.
7120 if (!AL.checkExactlyNumArgs(S, 1))
7121 return;
7122 } else {
7123 // Non-none swift_async requires a completion handler index argument.
7124 if (!AL.checkExactlyNumArgs(S, 2))
7125 return;
7126
7127 Expr *HandlerIdx = AL.getArgAsExpr(1);
7128 if (!checkFunctionOrMethodParameterIndex(S, D, AL, 2, HandlerIdx, Idx))
7129 return;
7130
7131 const ParmVarDecl *CompletionBlock =
7133 QualType CompletionBlockType = CompletionBlock->getType();
7134 if (!CompletionBlockType->isBlockPointerType()) {
7135 S.Diag(CompletionBlock->getLocation(),
7136 diag::err_swift_async_bad_block_type)
7137 << CompletionBlock->getType();
7138 return;
7139 }
7140 QualType BlockTy =
7141 CompletionBlockType->castAs<BlockPointerType>()->getPointeeType();
7142 if (!BlockTy->castAs<FunctionType>()->getReturnType()->isVoidType()) {
7143 S.Diag(CompletionBlock->getLocation(),
7144 diag::err_swift_async_bad_block_type)
7145 << CompletionBlock->getType();
7146 return;
7147 }
7148 }
7149
7150 auto *AsyncAttr =
7151 ::new (S.Context) SwiftAsyncAttr(S.Context, AL, Kind, Idx);
7152 D->addAttr(AsyncAttr);
7153
7154 if (auto *ErrorAttr = D->getAttr<SwiftAsyncErrorAttr>())
7155 checkSwiftAsyncErrorBlock(S, D, ErrorAttr, AsyncAttr);
7156}
7157
7158//===----------------------------------------------------------------------===//
7159// Microsoft specific attribute handlers.
7160//===----------------------------------------------------------------------===//
7161
7163 StringRef UuidAsWritten, MSGuidDecl *GuidDecl) {
7164 if (const auto *UA = D->getAttr<UuidAttr>()) {
7165 if (declaresSameEntity(UA->getGuidDecl(), GuidDecl))
7166 return nullptr;
7167 if (!UA->getGuid().empty()) {
7168 Diag(UA->getLocation(), diag::err_mismatched_uuid);
7169 Diag(CI.getLoc(), diag::note_previous_uuid);
7170 D->dropAttr<UuidAttr>();
7171 }
7172 }
7173
7174 return ::new (Context) UuidAttr(Context, CI, UuidAsWritten, GuidDecl);
7175}
7176
7177static void handleUuidAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7178 if (!S.LangOpts.CPlusPlus) {
7179 S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)
7180 << AL << AttributeLangSupport::C;
7181 return;
7182 }
7183
7184 StringRef OrigStrRef;
7185 SourceLocation LiteralLoc;
7186 if (!S.checkStringLiteralArgumentAttr(AL, 0, OrigStrRef, &LiteralLoc))
7187 return;
7188
7189 // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
7190 // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", normalize to the former.
7191 StringRef StrRef = OrigStrRef;
7192 if (StrRef.size() == 38 && StrRef.front() == '{' && StrRef.back() == '}')
7193 StrRef = StrRef.drop_front().drop_back();
7194
7195 // Validate GUID length.
7196 if (StrRef.size() != 36) {
7197 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
7198 return;
7199 }
7200
7201 for (unsigned i = 0; i < 36; ++i) {
7202 if (i == 8 || i == 13 || i == 18 || i == 23) {
7203 if (StrRef[i] != '-') {
7204 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
7205 return;
7206 }
7207 } else if (!isHexDigit(StrRef[i])) {
7208 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
7209 return;
7210 }
7211 }
7212
7213 // Convert to our parsed format and canonicalize.
7214 MSGuidDecl::Parts Parsed;
7215 StrRef.substr(0, 8).getAsInteger(16, Parsed.Part1);
7216 StrRef.substr(9, 4).getAsInteger(16, Parsed.Part2);
7217 StrRef.substr(14, 4).getAsInteger(16, Parsed.Part3);
7218 for (unsigned i = 0; i != 8; ++i)
7219 StrRef.substr(19 + 2 * i + (i >= 2 ? 1 : 0), 2)
7220 .getAsInteger(16, Parsed.Part4And5[i]);
7221 MSGuidDecl *Guid = S.Context.getMSGuidDecl(Parsed);
7222
7223 // FIXME: It'd be nice to also emit a fixit removing uuid(...) (and, if it's
7224 // the only thing in the [] list, the [] too), and add an insertion of
7225 // __declspec(uuid(...)). But sadly, neither the SourceLocs of the commas
7226 // separating attributes nor of the [ and the ] are in the AST.
7227 // Cf "SourceLocations of attribute list delimiters - [[ ... , ... ]] etc"
7228 // on cfe-dev.
7229 if (AL.isMicrosoftAttribute()) // Check for [uuid(...)] spelling.
7230 S.Diag(AL.getLoc(), diag::warn_atl_uuid_deprecated);
7231
7232 UuidAttr *UA = S.mergeUuidAttr(D, AL, OrigStrRef, Guid);
7233 if (UA)
7234 D->addAttr(UA);
7235}
7236
7237static void handleHLSLNumThreadsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7238 llvm::VersionTuple SMVersion =
7239 S.Context.getTargetInfo().getTriple().getOSVersion();
7240 uint32_t ZMax = 1024;
7241 uint32_t ThreadMax = 1024;
7242 if (SMVersion.getMajor() <= 4) {
7243 ZMax = 1;
7244 ThreadMax = 768;
7245 } else if (SMVersion.getMajor() == 5) {
7246 ZMax = 64;
7247 ThreadMax = 1024;
7248 }
7249
7250 uint32_t X;
7251 if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), X))
7252 return;
7253 if (X > 1024) {
7254 S.Diag(AL.getArgAsExpr(0)->getExprLoc(),
7255 diag::err_hlsl_numthreads_argument_oor) << 0 << 1024;
7256 return;
7257 }
7258 uint32_t Y;
7259 if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(1), Y))
7260 return;
7261 if (Y > 1024) {
7262 S.Diag(AL.getArgAsExpr(1)->getExprLoc(),
7263 diag::err_hlsl_numthreads_argument_oor) << 1 << 1024;
7264 return;
7265 }
7266 uint32_t Z;
7267 if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(2), Z))
7268 return;
7269 if (Z > ZMax) {
7270 S.Diag(AL.getArgAsExpr(2)->getExprLoc(),
7271 diag::err_hlsl_numthreads_argument_oor) << 2 << ZMax;
7272 return;
7273 }
7274
7275 if (X * Y * Z > ThreadMax) {
7276 S.Diag(AL.getLoc(), diag::err_hlsl_numthreads_invalid) << ThreadMax;
7277 return;
7278 }
7279
7280 HLSLNumThreadsAttr *NewAttr = S.HLSL().mergeNumThreadsAttr(D, AL, X, Y, Z);
7281 if (NewAttr)
7282 D->addAttr(NewAttr);
7283}
7284
7287 return false;
7288 if (const auto *VT = T->getAs<VectorType>())
7289 return VT->getNumElements() <= 3;
7290 return true;
7291}
7292
7294 const ParsedAttr &AL) {
7295 // FIXME: support semantic on field.
7296 // See https://github.com/llvm/llvm-project/issues/57889.
7297 if (isa<FieldDecl>(D)) {
7298 S.Diag(AL.getLoc(), diag::err_hlsl_attr_invalid_ast_node)
7299 << AL << "parameter";
7300 return;
7301 }
7302
7303 auto *VD = cast<ValueDecl>(D);
7304 if (!isLegalTypeForHLSLSV_DispatchThreadID(VD->getType())) {
7305 S.Diag(AL.getLoc(), diag::err_hlsl_attr_invalid_type)
7306 << AL << "uint/uint2/uint3";
7307 return;
7308 }
7309
7310 D->addAttr(::new (S.Context) HLSLSV_DispatchThreadIDAttr(S.Context, AL));
7311}
7312
7313static void handleHLSLPackOffsetAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7314 if (!isa<VarDecl>(D) || !isa<HLSLBufferDecl>(D->getDeclContext())) {
7315 S.Diag(AL.getLoc(), diag::err_hlsl_attr_invalid_ast_node)
7316 << AL << "shader constant in a constant buffer";
7317 return;
7318 }
7319
7320 uint32_t SubComponent;
7321 if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), SubComponent))
7322 return;
7323 uint32_t Component;
7324 if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(1), Component))
7325 return;
7326
7327 QualType T = cast<VarDecl>(D)->getType().getCanonicalType();
7328 // Check if T is an array or struct type.
7329 // TODO: mark matrix type as aggregate type.
7330 bool IsAggregateTy = (T->isArrayType() || T->isStructureType());
7331
7332 // Check Component is valid for T.
7333 if (Component) {
7334 unsigned Size = S.getASTContext().getTypeSize(T);
7335 if (IsAggregateTy || Size > 128) {
7336 S.Diag(AL.getLoc(), diag::err_hlsl_packoffset_cross_reg_boundary);
7337 return;
7338 } else {
7339 // Make sure Component + sizeof(T) <= 4.
7340 if ((Component * 32 + Size) > 128) {
7341 S.Diag(AL.getLoc(), diag::err_hlsl_packoffset_cross_reg_boundary);
7342 return;
7343 }
7344 QualType EltTy = T;
7345 if (const auto *VT = T->getAs<VectorType>())
7346 EltTy = VT->getElementType();
7347 unsigned Align = S.getASTContext().getTypeAlign(EltTy);
7348 if (Align > 32 && Component == 1) {
7349 // NOTE: Component 3 will hit err_hlsl_packoffset_cross_reg_boundary.
7350 // So we only need to check Component 1 here.
7351 S.Diag(AL.getLoc(), diag::err_hlsl_packoffset_alignment_mismatch)
7352 << Align << EltTy;
7353 return;
7354 }
7355 }
7356 }
7357
7358 D->addAttr(::new (S.Context)
7359 HLSLPackOffsetAttr(S.Context, AL, SubComponent, Component));
7360}
7361
7362static void handleHLSLShaderAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7363 StringRef Str;
7364 SourceLocation ArgLoc;
7365 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
7366 return;
7367
7368 HLSLShaderAttr::ShaderType ShaderType;
7369 if (!HLSLShaderAttr::ConvertStrToShaderType(Str, ShaderType)) {
7370 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
7371 << AL << Str << ArgLoc;
7372 return;
7373 }
7374
7375 // FIXME: check function match the shader stage.
7376
7377 HLSLShaderAttr *NewAttr = S.HLSL().mergeShaderAttr(D, AL, ShaderType);
7378 if (NewAttr)
7379 D->addAttr(NewAttr);
7380}
7381
7383 const ParsedAttr &AL) {
7384 StringRef Space = "space0";
7385 StringRef Slot = "";
7386
7387 if (!AL.isArgIdent(0)) {
7388 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7389 << AL << AANT_ArgumentIdentifier;
7390 return;
7391 }
7392
7394 StringRef Str = Loc->Ident->getName();
7395 SourceLocation ArgLoc = Loc->Loc;
7396
7397 SourceLocation SpaceArgLoc;
7398 if (AL.getNumArgs() == 2) {
7399 Slot = Str;
7400 if (!AL.isArgIdent(1)) {
7401 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7402 << AL << AANT_ArgumentIdentifier;
7403 return;
7404 }
7405
7407 Space = Loc->Ident->getName();
7408 SpaceArgLoc = Loc->Loc;
7409 } else {
7410 Slot = Str;
7411 }
7412
7413 // Validate.
7414 if (!Slot.empty()) {
7415 switch (Slot[0]) {
7416 case 'u':
7417 case 'b':
7418 case 's':
7419 case 't':
7420 break;
7421 default:
7422 S.Diag(ArgLoc, diag::err_hlsl_unsupported_register_type)
7423 << Slot.substr(0, 1);
7424 return;
7425 }
7426
7427 StringRef SlotNum = Slot.substr(1);
7428 unsigned Num = 0;
7429 if (SlotNum.getAsInteger(10, Num)) {
7430 S.Diag(ArgLoc, diag::err_hlsl_unsupported_register_number);
7431 return;
7432 }
7433 }
7434
7435 if (!Space.starts_with("space")) {
7436 S.Diag(SpaceArgLoc, diag::err_hlsl_expected_space) << Space;
7437 return;
7438 }
7439 StringRef SpaceNum = Space.substr(5);
7440 unsigned Num = 0;
7441 if (SpaceNum.getAsInteger(10, Num)) {
7442 S.Diag(SpaceArgLoc, diag::err_hlsl_expected_space) << Space;
7443 return;
7444 }
7445
7446 // FIXME: check reg type match decl. Issue
7447 // https://github.com/llvm/llvm-project/issues/57886.
7448 HLSLResourceBindingAttr *NewAttr =
7449 HLSLResourceBindingAttr::Create(S.getASTContext(), Slot, Space, AL);
7450 if (NewAttr)
7451 D->addAttr(NewAttr);
7452}
7453
7455 const ParsedAttr &AL) {
7456 HLSLParamModifierAttr *NewAttr = S.HLSL().mergeParamModifierAttr(
7457 D, AL,
7458 static_cast<HLSLParamModifierAttr::Spelling>(AL.getSemanticSpelling()));
7459 if (NewAttr)
7460 D->addAttr(NewAttr);
7461}
7462
7463static void handleMSInheritanceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7464 if (!S.LangOpts.CPlusPlus) {
7465 S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)
7466 << AL << AttributeLangSupport::C;
7467 return;
7468 }
7469 MSInheritanceAttr *IA = S.mergeMSInheritanceAttr(
7470 D, AL, /*BestCase=*/true, (MSInheritanceModel)AL.getSemanticSpelling());
7471 if (IA) {
7472 D->addAttr(IA);
7473 S.Consumer.AssignInheritanceModel(cast<CXXRecordDecl>(D));
7474 }
7475}
7476
7477static void handleDeclspecThreadAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7478 const auto *VD = cast<VarDecl>(D);
7480 S.Diag(AL.getLoc(), diag::err_thread_unsupported);
7481 return;
7482 }
7483 if (VD->getTSCSpec() != TSCS_unspecified) {
7484 S.Diag(AL.getLoc(), diag::err_declspec_thread_on_thread_variable);
7485 return;
7486 }
7487 if (VD->hasLocalStorage()) {
7488 S.Diag(AL.getLoc(), diag::err_thread_non_global) << "__declspec(thread)";
7489 return;
7490 }
7491 D->addAttr(::new (S.Context) ThreadAttr(S.Context, AL));
7492}
7493
7494static void handleMSConstexprAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7496 S.Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)
7497 << AL << AL.getRange();
7498 return;
7499 }
7500 auto *FD = cast<FunctionDecl>(D);
7501 if (FD->isConstexprSpecified() || FD->isConsteval()) {
7502 S.Diag(AL.getLoc(), diag::err_ms_constexpr_cannot_be_applied)
7503 << FD->isConsteval() << FD;
7504 return;
7505 }
7506 if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
7507 if (!S.getLangOpts().CPlusPlus20 && MD->isVirtual()) {
7508 S.Diag(AL.getLoc(), diag::err_ms_constexpr_cannot_be_applied)
7509 << /*virtual*/ 2 << MD;
7510 return;
7511 }
7512 }
7513 D->addAttr(::new (S.Context) MSConstexprAttr(S.Context, AL));
7514}
7515
7516static void handleAbiTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7518 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
7519 StringRef Tag;
7520 if (!S.checkStringLiteralArgumentAttr(AL, I, Tag))
7521 return;
7522 Tags.push_back(Tag);
7523 }
7524
7525 if (const auto *NS = dyn_cast<NamespaceDecl>(D)) {
7526 if (!NS->isInline()) {
7527 S.Diag(AL.getLoc(), diag::warn_attr_abi_tag_namespace) << 0;
7528 return;
7529 }
7530 if (NS->isAnonymousNamespace()) {
7531 S.Diag(AL.getLoc(), diag::warn_attr_abi_tag_namespace) << 1;
7532 return;
7533 }
7534 if (AL.getNumArgs() == 0)
7535 Tags.push_back(NS->getName());
7536 } else if (!AL.checkAtLeastNumArgs(S, 1))
7537 return;
7538
7539 // Store tags sorted and without duplicates.
7540 llvm::sort(Tags);
7541 Tags.erase(std::unique(Tags.begin(), Tags.end()), Tags.end());
7542
7543 D->addAttr(::new (S.Context)
7544 AbiTagAttr(S.Context, AL, Tags.data(), Tags.size()));
7545}
7546
7547static void handleARMInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7548 // Check the attribute arguments.
7549 if (AL.getNumArgs() > 1) {
7550 S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 1;
7551 return;
7552 }
7553
7554 StringRef Str;
7555 SourceLocation ArgLoc;
7556
7557 if (AL.getNumArgs() == 0)
7558 Str = "";
7559 else if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
7560 return;
7561
7562 ARMInterruptAttr::InterruptType Kind;
7563 if (!ARMInterruptAttr::ConvertStrToInterruptType(Str, Kind)) {
7564 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << Str
7565 << ArgLoc;
7566 return;
7567 }
7568
7569 D->addAttr(::new (S.Context) ARMInterruptAttr(S.Context, AL, Kind));
7570}
7571
7572static void handleMSP430InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7573 // MSP430 'interrupt' attribute is applied to
7574 // a function with no parameters and void return type.
7575 if (!isFunctionOrMethod(D)) {
7576 S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
7578 return;
7579 }
7580
7582 S.Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
7583 << /*MSP430*/ 1 << 0;
7584 return;
7585 }
7586
7587 if (!getFunctionOrMethodResultType(D)->isVoidType()) {
7588 S.Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
7589 << /*MSP430*/ 1 << 1;
7590 return;
7591 }
7592
7593 // The attribute takes one integer argument.
7594 if (!AL.checkExactlyNumArgs(S, 1))
7595 return;
7596
7597 if (!AL.isArgExpr(0)) {
7598 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7600 return;
7601 }
7602
7603 Expr *NumParamsExpr = static_cast<Expr *>(AL.getArgAsExpr(0));
7604 std::optional<llvm::APSInt> NumParams = llvm::APSInt(32);
7605 if (!(NumParams = NumParamsExpr->getIntegerConstantExpr(S.Context))) {
7606 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7608 << NumParamsExpr->getSourceRange();
7609 return;
7610 }
7611 // The argument should be in range 0..63.
7612 unsigned Num = NumParams->getLimitedValue(255);
7613 if (Num > 63) {
7614 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
7615 << AL << (int)NumParams->getSExtValue()
7616 << NumParamsExpr->getSourceRange();
7617 return;
7618 }
7619
7620 D->addAttr(::new (S.Context) MSP430InterruptAttr(S.Context, AL, Num));
7621 D->addAttr(UsedAttr::CreateImplicit(S.Context));
7622}
7623
7624static void handleMipsInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7625 // Only one optional argument permitted.
7626 if (AL.getNumArgs() > 1) {
7627 S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 1;
7628 return;
7629 }
7630
7631 StringRef Str;
7632 SourceLocation ArgLoc;
7633
7634 if (AL.getNumArgs() == 0)
7635 Str = "";
7636 else if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
7637 return;
7638
7639 // Semantic checks for a function with the 'interrupt' attribute for MIPS:
7640 // a) Must be a function.
7641 // b) Must have no parameters.
7642 // c) Must have the 'void' return type.
7643 // d) Cannot have the 'mips16' attribute, as that instruction set
7644 // lacks the 'eret' instruction.
7645 // e) The attribute itself must either have no argument or one of the
7646 // valid interrupt types, see [MipsInterruptDocs].
7647
7648 if (!isFunctionOrMethod(D)) {
7649 S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
7651 return;
7652 }
7653
7655 S.Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
7656 << /*MIPS*/ 0 << 0;
7657 return;
7658 }
7659
7660 if (!getFunctionOrMethodResultType(D)->isVoidType()) {
7661 S.Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
7662 << /*MIPS*/ 0 << 1;
7663 return;
7664 }
7665
7666 // We still have to do this manually because the Interrupt attributes are
7667 // a bit special due to sharing their spellings across targets.
7668 if (checkAttrMutualExclusion<Mips16Attr>(S, D, AL))
7669 return;
7670
7671 MipsInterruptAttr::InterruptType Kind;
7672 if (!MipsInterruptAttr::ConvertStrToInterruptType(Str, Kind)) {
7673 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
7674 << AL << "'" + std::string(Str) + "'";
7675 return;
7676 }
7677
7678 D->addAttr(::new (S.Context) MipsInterruptAttr(S.Context, AL, Kind));
7679}
7680
7681static void handleM68kInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7682 if (!AL.checkExactlyNumArgs(S, 1))
7683 return;
7684
7685 if (!AL.isArgExpr(0)) {
7686 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7688 return;
7689 }
7690
7691 // FIXME: Check for decl - it should be void ()(void).
7692
7693 Expr *NumParamsExpr = static_cast<Expr *>(AL.getArgAsExpr(0));
7694 auto MaybeNumParams = NumParamsExpr->getIntegerConstantExpr(S.Context);
7695 if (!MaybeNumParams) {
7696 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
7698 << NumParamsExpr->getSourceRange();
7699 return;
7700 }
7701
7702 unsigned Num = MaybeNumParams->getLimitedValue(255);
7703 if ((Num & 1) || Num > 30) {
7704 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
7705 << AL << (int)MaybeNumParams->getSExtValue()
7706 << NumParamsExpr->getSourceRange();
7707 return;
7708 }
7709
7710 D->addAttr(::new (S.Context) M68kInterruptAttr(S.Context, AL, Num));
7711 D->addAttr(UsedAttr::CreateImplicit(S.Context));
7712}
7713
7714static void handleAnyX86InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7715 // Semantic checks for a function with the 'interrupt' attribute.
7716 // a) Must be a function.
7717 // b) Must have the 'void' return type.
7718 // c) Must take 1 or 2 arguments.
7719 // d) The 1st argument must be a pointer.
7720 // e) The 2nd argument (if any) must be an unsigned integer.
7723 cast<NamedDecl>(D)->getDeclName().getCXXOverloadedOperator())) {
7724 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
7725 << AL << AL.isRegularKeywordAttribute()
7727 return;
7728 }
7729 // Interrupt handler must have void return type.
7730 if (!getFunctionOrMethodResultType(D)->isVoidType()) {
7732 diag::err_anyx86_interrupt_attribute)
7733 << (S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86
7734 ? 0
7735 : 1)
7736 << 0;
7737 return;
7738 }
7739 // Interrupt handler must have 1 or 2 parameters.
7740 unsigned NumParams = getFunctionOrMethodNumParams(D);
7741 if (NumParams < 1 || NumParams > 2) {
7742 S.Diag(D->getBeginLoc(), diag::err_anyx86_interrupt_attribute)
7743 << (S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86
7744 ? 0
7745 : 1)
7746 << 1;
7747 return;
7748 }
7749 // The first argument must be a pointer.
7752 diag::err_anyx86_interrupt_attribute)
7753 << (S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86
7754 ? 0
7755 : 1)
7756 << 2;
7757 return;
7758 }
7759 // The second argument, if present, must be an unsigned integer.
7760 unsigned TypeSize =
7761 S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86_64
7762 ? 64
7763 : 32;
7764 if (NumParams == 2 &&
7765 (!getFunctionOrMethodParamType(D, 1)->isUnsignedIntegerType() ||
7766 S.Context.getTypeSize(getFunctionOrMethodParamType(D, 1)) != TypeSize)) {
7768 diag::err_anyx86_interrupt_attribute)
7769 << (S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86
7770 ? 0
7771 : 1)
7772 << 3 << S.Context.getIntTypeForBitwidth(TypeSize, /*Signed=*/false);
7773 return;
7774 }
7775 D->addAttr(::new (S.Context) AnyX86InterruptAttr(S.Context, AL));
7776 D->addAttr(UsedAttr::CreateImplicit(S.Context));
7777}
7778
7779static void handleAVRInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7780 if (!isFunctionOrMethod(D)) {
7781 S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
7783 return;
7784 }
7785
7786 if (!AL.checkExactlyNumArgs(S, 0))
7787 return;
7788
7789 handleSimpleAttribute<AVRInterruptAttr>(S, D, AL);
7790}
7791
7792static void handleAVRSignalAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7793 if (!isFunctionOrMethod(D)) {
7794 S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
7796 return;
7797 }
7798
7799 if (!AL.checkExactlyNumArgs(S, 0))
7800 return;
7801
7802 handleSimpleAttribute<AVRSignalAttr>(S, D, AL);
7803}
7804
7806 // Add preserve_access_index attribute to all fields and inner records.
7807 for (auto *D : RD->decls()) {
7808 if (D->hasAttr<BPFPreserveAccessIndexAttr>())
7809 continue;
7810
7811 D->addAttr(BPFPreserveAccessIndexAttr::CreateImplicit(S.Context));
7812 if (auto *Rec = dyn_cast<RecordDecl>(D))
7814 }
7815}
7816
7818 const ParsedAttr &AL) {
7819 auto *Rec = cast<RecordDecl>(D);
7821 Rec->addAttr(::new (S.Context) BPFPreserveAccessIndexAttr(S.Context, AL));
7822}
7823
7824static bool hasBTFDeclTagAttr(Decl *D, StringRef Tag) {
7825 for (const auto *I : D->specific_attrs<BTFDeclTagAttr>()) {
7826 if (I->getBTFDeclTag() == Tag)
7827 return true;
7828 }
7829 return false;
7830}
7831
7832static void handleBTFDeclTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7833 StringRef Str;
7834 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
7835 return;
7836 if (hasBTFDeclTagAttr(D, Str))
7837 return;
7838
7839 D->addAttr(::new (S.Context) BTFDeclTagAttr(S.Context, AL, Str));
7840}
7841
7842BTFDeclTagAttr *Sema::mergeBTFDeclTagAttr(Decl *D, const BTFDeclTagAttr &AL) {
7843 if (hasBTFDeclTagAttr(D, AL.getBTFDeclTag()))
7844 return nullptr;
7845 return ::new (Context) BTFDeclTagAttr(Context, AL, AL.getBTFDeclTag());
7846}
7847
7849 const ParsedAttr &AL) {
7850 if (!isFunctionOrMethod(D)) {
7851 S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
7853 return;
7854 }
7855
7856 auto *FD = cast<FunctionDecl>(D);
7857 if (FD->isThisDeclarationADefinition()) {
7858 S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0;
7859 return;
7860 }
7861
7862 StringRef Str;
7863 SourceLocation ArgLoc;
7864 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
7865 return;
7866
7867 D->addAttr(::new (S.Context) WebAssemblyExportNameAttr(S.Context, AL, Str));
7868 D->addAttr(UsedAttr::CreateImplicit(S.Context));
7869}
7870
7871WebAssemblyImportModuleAttr *
7872Sema::mergeImportModuleAttr(Decl *D, const WebAssemblyImportModuleAttr &AL) {
7873 auto *FD = cast<FunctionDecl>(D);
7874
7875 if (const auto *ExistingAttr = FD->getAttr<WebAssemblyImportModuleAttr>()) {
7876 if (ExistingAttr->getImportModule() == AL.getImportModule())
7877 return nullptr;
7878 Diag(ExistingAttr->getLocation(), diag::warn_mismatched_import) << 0
7879 << ExistingAttr->getImportModule() << AL.getImportModule();
7880 Diag(AL.getLoc(), diag::note_previous_attribute);
7881 return nullptr;
7882 }
7883 if (FD->hasBody()) {
7884 Diag(AL.getLoc(), diag::warn_import_on_definition) << 0;
7885 return nullptr;
7886 }
7887 return ::new (Context) WebAssemblyImportModuleAttr(Context, AL,
7888 AL.getImportModule());
7889}
7890
7891WebAssemblyImportNameAttr *
7892Sema::mergeImportNameAttr(Decl *D, const WebAssemblyImportNameAttr &AL) {
7893 auto *FD = cast<FunctionDecl>(D);
7894
7895 if (const auto *ExistingAttr = FD->getAttr<WebAssemblyImportNameAttr>()) {
7896 if (ExistingAttr->getImportName() == AL.getImportName())
7897 return nullptr;
7898 Diag(ExistingAttr->getLocation(), diag::warn_mismatched_import) << 1
7899 << ExistingAttr->getImportName() << AL.getImportName();
7900 Diag(AL.getLoc(), diag::note_previous_attribute);
7901 return nullptr;
7902 }
7903 if (FD->hasBody()) {
7904 Diag(AL.getLoc(), diag::warn_import_on_definition) << 1;
7905 return nullptr;
7906 }
7907 return ::new (Context) WebAssemblyImportNameAttr(Context, AL,
7908 AL.getImportName());
7909}
7910
7911static void
7913 auto *FD = cast<FunctionDecl>(D);
7914
7915 StringRef Str;
7916 SourceLocation ArgLoc;
7917 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
7918 return;
7919 if (FD->hasBody()) {
7920 S.Diag(AL.getLoc(), diag::warn_import_on_definition) << 0;
7921 return;
7922 }
7923
7924 FD->addAttr(::new (S.Context)
7925 WebAssemblyImportModuleAttr(S.Context, AL, Str));
7926}
7927
7928static void
7930 auto *FD = cast<FunctionDecl>(D);
7931
7932 StringRef Str;
7933 SourceLocation ArgLoc;
7934 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
7935 return;
7936 if (FD->hasBody()) {
7937 S.Diag(AL.getLoc(), diag::warn_import_on_definition) << 1;
7938 return;
7939 }
7940
7941 FD->addAttr(::new (S.Context) WebAssemblyImportNameAttr(S.Context, AL, Str));
7942}
7943
7945 const ParsedAttr &AL) {
7946 // Warn about repeated attributes.
7947 if (const auto *A = D->getAttr<RISCVInterruptAttr>()) {
7948 S.Diag(AL.getRange().getBegin(),
7949 diag::warn_riscv_repeated_interrupt_attribute);
7950 S.Diag(A->getLocation(), diag::note_riscv_repeated_interrupt_attribute);
7951 return;
7952 }
7953
7954 // Check the attribute argument. Argument is optional.
7955 if (!AL.checkAtMostNumArgs(S, 1))
7956 return;
7957
7958 StringRef Str;
7959 SourceLocation ArgLoc;
7960
7961 // 'machine'is the default interrupt mode.
7962 if (AL.getNumArgs() == 0)
7963 Str = "machine";
7964 else if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
7965 return;
7966
7967 // Semantic checks for a function with the 'interrupt' attribute:
7968 // - Must be a function.
7969 // - Must have no parameters.
7970 // - Must have the 'void' return type.
7971 // - The attribute itself must either have no argument or one of the
7972 // valid interrupt types, see [RISCVInterruptDocs].
7973
7974 if (D->getFunctionType() == nullptr) {
7975 S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
7977 return;
7978 }
7979
7981 S.Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
7982 << /*RISC-V*/ 2 << 0;
7983 return;
7984 }
7985
7986 if (!getFunctionOrMethodResultType(D)->isVoidType()) {
7987 S.Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
7988 << /*RISC-V*/ 2 << 1;
7989 return;
7990 }
7991
7992 RISCVInterruptAttr::InterruptType Kind;
7993 if (!RISCVInterruptAttr::ConvertStrToInterruptType(Str, Kind)) {
7994 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << Str
7995 << ArgLoc;
7996 return;
7997 }
7998
7999 D->addAttr(::new (S.Context) RISCVInterruptAttr(S.Context, AL, Kind));
8000}
8001
8002static void handleInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8003 // Dispatch the interrupt attribute based on the current target.
8004 switch (S.Context.getTargetInfo().getTriple().getArch()) {
8005 case llvm::Triple::msp430:
8006 handleMSP430InterruptAttr(S, D, AL);
8007 break;
8008 case llvm::Triple::mipsel:
8009 case llvm::Triple::mips:
8010 handleMipsInterruptAttr(S, D, AL);
8011 break;
8012 case llvm::Triple::m68k:
8013 handleM68kInterruptAttr(S, D, AL);
8014 break;
8015 case llvm::Triple::x86:
8016 case llvm::Triple::x86_64:
8017 handleAnyX86InterruptAttr(S, D, AL);
8018 break;
8019 case llvm::Triple::avr:
8020 handleAVRInterruptAttr(S, D, AL);
8021 break;
8022 case llvm::Triple::riscv32:
8023 case llvm::Triple::riscv64:
8024 handleRISCVInterruptAttr(S, D, AL);
8025 break;
8026 default:
8027 handleARMInterruptAttr(S, D, AL);
8028 break;
8029 }
8030}
8031
8032static bool
8034 const AMDGPUFlatWorkGroupSizeAttr &Attr) {
8035 // Accept template arguments for now as they depend on something else.
8036 // We'll get to check them when they eventually get instantiated.
8037 if (MinExpr->isValueDependent() || MaxExpr->isValueDependent())
8038 return false;
8039
8040 uint32_t Min = 0;
8041 if (!checkUInt32Argument(S, Attr, MinExpr, Min, 0))
8042 return true;
8043
8044 uint32_t Max = 0;
8045 if (!checkUInt32Argument(S, Attr, MaxExpr, Max, 1))
8046 return true;
8047
8048 if (Min == 0 && Max != 0) {
8049 S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid)
8050 << &Attr << 0;
8051 return true;
8052 }
8053 if (Min > Max) {
8054 S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid)
8055 << &Attr << 1;
8056 return true;
8057 }
8058
8059 return false;
8060}
8061
8062AMDGPUFlatWorkGroupSizeAttr *
8064 Expr *MinExpr, Expr *MaxExpr) {
8065 AMDGPUFlatWorkGroupSizeAttr TmpAttr(Context, CI, MinExpr, MaxExpr);
8066
8067 if (checkAMDGPUFlatWorkGroupSizeArguments(*this, MinExpr, MaxExpr, TmpAttr))
8068 return nullptr;
8069 return ::new (Context)
8070 AMDGPUFlatWorkGroupSizeAttr(Context, CI, MinExpr, MaxExpr);
8071}
8072
8074 const AttributeCommonInfo &CI,
8075 Expr *MinExpr, Expr *MaxExpr) {
8076 if (auto *Attr = CreateAMDGPUFlatWorkGroupSizeAttr(CI, MinExpr, MaxExpr))
8077 D->addAttr(Attr);
8078}
8079
8081 const ParsedAttr &AL) {
8082 Expr *MinExpr = AL.getArgAsExpr(0);
8083 Expr *MaxExpr = AL.getArgAsExpr(1);
8084
8085 S.addAMDGPUFlatWorkGroupSizeAttr(D, AL, MinExpr, MaxExpr);
8086}
8087
8089 Expr *MaxExpr,
8090 const AMDGPUWavesPerEUAttr &Attr) {
8091 if (S.DiagnoseUnexpandedParameterPack(MinExpr) ||
8092 (MaxExpr && S.DiagnoseUnexpandedParameterPack(MaxExpr)))
8093 return true;
8094
8095 // Accept template arguments for now as they depend on something else.
8096 // We'll get to check them when they eventually get instantiated.
8097 if (MinExpr->isValueDependent() || (MaxExpr && MaxExpr->isValueDependent()))
8098 return false;
8099
8100 uint32_t Min = 0;
8101 if (!checkUInt32Argument(S, Attr, MinExpr, Min, 0))
8102 return true;
8103
8104 uint32_t Max = 0;
8105 if (MaxExpr && !checkUInt32Argument(S, Attr, MaxExpr, Max, 1))
8106 return true;
8107
8108 if (Min == 0 && Max != 0) {
8109 S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid)
8110 << &Attr << 0;
8111 return true;
8112 }
8113 if (Max != 0 && Min > Max) {
8114 S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid)
8115 << &Attr << 1;
8116 return true;
8117 }
8118
8119 return false;
8120}
8121
8122AMDGPUWavesPerEUAttr *
8124 Expr *MaxExpr) {
8125 AMDGPUWavesPerEUAttr TmpAttr(Context, CI, MinExpr, MaxExpr);
8126
8127 if (checkAMDGPUWavesPerEUArguments(*this, MinExpr, MaxExpr, TmpAttr))
8128 return nullptr;
8129
8130 return ::new (Context) AMDGPUWavesPerEUAttr(Context, CI, MinExpr, MaxExpr);
8131}
8132
8134 Expr *MinExpr, Expr *MaxExpr) {
8135 if (auto *Attr = CreateAMDGPUWavesPerEUAttr(CI, MinExpr, MaxExpr))
8136 D->addAttr(Attr);
8137}
8138
8139static void handleAMDGPUWavesPerEUAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8140 if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 2))
8141 return;
8142
8143 Expr *MinExpr = AL.getArgAsExpr(0);
8144 Expr *MaxExpr = (AL.getNumArgs() > 1) ? AL.getArgAsExpr(1) : nullptr;
8145
8146 S.addAMDGPUWavesPerEUAttr(D, AL, MinExpr, MaxExpr);
8147}
8148
8149static void handleAMDGPUNumSGPRAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8150 uint32_t NumSGPR = 0;
8151 Expr *NumSGPRExpr = AL.getArgAsExpr(0);
8152 if (!checkUInt32Argument(S, AL, NumSGPRExpr, NumSGPR))
8153 return;
8154
8155 D->addAttr(::new (S.Context) AMDGPUNumSGPRAttr(S.Context, AL, NumSGPR));
8156}
8157
8158static void handleAMDGPUNumVGPRAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8159 uint32_t NumVGPR = 0;
8160 Expr *NumVGPRExpr = AL.getArgAsExpr(0);
8161 if (!checkUInt32Argument(S, AL, NumVGPRExpr, NumVGPR))
8162 return;
8163
8164 D->addAttr(::new (S.Context) AMDGPUNumVGPRAttr(S.Context, AL, NumVGPR));
8165}
8166
8167static bool
8169 Expr *ZExpr,
8170 const AMDGPUMaxNumWorkGroupsAttr &Attr) {
8171 if (S.DiagnoseUnexpandedParameterPack(XExpr) ||
8172 (YExpr && S.DiagnoseUnexpandedParameterPack(YExpr)) ||
8173 (ZExpr && S.DiagnoseUnexpandedParameterPack(ZExpr)))
8174 return true;
8175
8176 // Accept template arguments for now as they depend on something else.
8177 // We'll get to check them when they eventually get instantiated.
8178 if (XExpr->isValueDependent() || (YExpr && YExpr->isValueDependent()) ||
8179 (ZExpr && ZExpr->isValueDependent()))
8180 return false;
8181
8182 uint32_t NumWG = 0;
8183 Expr *Exprs[3] = {XExpr, YExpr, ZExpr};
8184 for (int i = 0; i < 3; i++) {
8185 if (Exprs[i]) {
8186 if (!checkUInt32Argument(S, Attr, Exprs[i], NumWG, i,
8187 /*StrictlyUnsigned=*/true))
8188 return true;
8189 if (NumWG == 0) {
8190 S.Diag(Attr.getLoc(), diag::err_attribute_argument_is_zero)
8191 << &Attr << Exprs[i]->getSourceRange();
8192 return true;
8193 }
8194 }
8195 }
8196
8197 return false;
8198}
8199
8200AMDGPUMaxNumWorkGroupsAttr *
8202 Expr *XExpr, Expr *YExpr, Expr *ZExpr) {
8203 AMDGPUMaxNumWorkGroupsAttr TmpAttr(Context, CI, XExpr, YExpr, ZExpr);
8204
8205 if (checkAMDGPUMaxNumWorkGroupsArguments(*this, XExpr, YExpr, ZExpr, TmpAttr))
8206 return nullptr;
8207
8208 return ::new (Context)
8209 AMDGPUMaxNumWorkGroupsAttr(Context, CI, XExpr, YExpr, ZExpr);
8210}
8211
8213 Expr *XExpr, Expr *YExpr,
8214 Expr *ZExpr) {
8215 if (auto *Attr = CreateAMDGPUMaxNumWorkGroupsAttr(CI, XExpr, YExpr, ZExpr))
8216 D->addAttr(Attr);
8217}
8218
8220 const ParsedAttr &AL) {
8221 Expr *YExpr = (AL.getNumArgs() > 1) ? AL.getArgAsExpr(1) : nullptr;
8222 Expr *ZExpr = (AL.getNumArgs() > 2) ? AL.getArgAsExpr(2) : nullptr;
8223 S.addAMDGPUMaxNumWorkGroupsAttr(D, AL, AL.getArgAsExpr(0), YExpr, ZExpr);
8224}
8225
8227 const ParsedAttr &AL) {
8228 // If we try to apply it to a function pointer, don't warn, but don't
8229 // do anything, either. It doesn't matter anyway, because there's nothing
8230 // special about calling a force_align_arg_pointer function.
8231 const auto *VD = dyn_cast<ValueDecl>(D);
8232 if (VD && VD->getType()->isFunctionPointerType())
8233 return;
8234 // Also don't warn on function pointer typedefs.
8235 const auto *TD = dyn_cast<TypedefNameDecl>(D);
8236 if (TD && (TD->getUnderlyingType()->isFunctionPointerType() ||
8237 TD->getUnderlyingType()->isFunctionType()))
8238 return;
8239 // Attribute can only be applied to function types.
8240 if (!isa<FunctionDecl>(D)) {
8241 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
8243 return;
8244 }
8245
8246 D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr(S.Context, AL));
8247}
8248
8249static void handleLayoutVersion(Sema &S, Decl *D, const ParsedAttr &AL) {
8250 uint32_t Version;
8251 Expr *VersionExpr = static_cast<Expr *>(AL.getArgAsExpr(0));
8252 if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), Version))
8253 return;
8254
8255 // TODO: Investigate what happens with the next major version of MSVC.
8256 if (Version != LangOptions::MSVC2015 / 100) {
8257 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
8258 << AL << Version << VersionExpr->getSourceRange();
8259 return;
8260 }
8261
8262 // The attribute expects a "major" version number like 19, but new versions of
8263 // MSVC have moved to updating the "minor", or less significant numbers, so we
8264 // have to multiply by 100 now.
8265 Version *= 100;
8266
8267 D->addAttr(::new (S.Context) LayoutVersionAttr(S.Context, AL, Version));
8268}
8269
8271 const AttributeCommonInfo &CI) {
8272 if (D->hasAttr<DLLExportAttr>()) {
8273 Diag(CI.getLoc(), diag::warn_attribute_ignored) << "'dllimport'";
8274 return nullptr;
8275 }
8276
8277 if (D->hasAttr<DLLImportAttr>())
8278 return nullptr;
8279
8280 return ::new (Context) DLLImportAttr(Context, CI);
8281}
8282
8284 const AttributeCommonInfo &CI) {
8285 if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) {
8286 Diag(Import->getLocation(), diag::warn_attribute_ignored) << Import;
8287 D->dropAttr<DLLImportAttr>();
8288 }
8289
8290 if (D->hasAttr<DLLExportAttr>())
8291 return nullptr;
8292
8293 return ::new (Context) DLLExportAttr(Context, CI);
8294}
8295
8296static void handleDLLAttr(Sema &S, Decl *D, const ParsedAttr &A) {
8297 if (isa<ClassTemplatePartialSpecializationDecl>(D) &&
8299 S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored) << A;
8300 return;
8301 }
8302
8303 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
8304 if (FD->isInlined() && A.getKind() == ParsedAttr::AT_DLLImport &&
8306 // MinGW doesn't allow dllimport on inline functions.
8307 S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored_on_inline)
8308 << A;
8309 return;
8310 }
8311 }
8312
8313 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
8315 MD->getParent()->isLambda()) {
8316 S.Diag(A.getRange().getBegin(), diag::err_attribute_dll_lambda) << A;
8317 return;
8318 }
8319 }
8320
8321 Attr *NewAttr = A.getKind() == ParsedAttr::AT_DLLExport
8322 ? (Attr *)S.mergeDLLExportAttr(D, A)
8323 : (Attr *)S.mergeDLLImportAttr(D, A);
8324 if (NewAttr)
8325 D->addAttr(NewAttr);
8326}
8327
8328MSInheritanceAttr *
8330 bool BestCase,
8331 MSInheritanceModel Model) {
8332 if (MSInheritanceAttr *IA = D->getAttr<MSInheritanceAttr>()) {
8333 if (IA->getInheritanceModel() == Model)
8334 return nullptr;
8335 Diag(IA->getLocation(), diag::err_mismatched_ms_inheritance)
8336 << 1 /*previous declaration*/;
8337 Diag(CI.getLoc(), diag::note_previous_ms_inheritance);
8338 D->dropAttr<MSInheritanceAttr>();
8339 }
8340
8341 auto *RD = cast<CXXRecordDecl>(D);
8342 if (RD->hasDefinition()) {
8343 if (checkMSInheritanceAttrOnDefinition(RD, CI.getRange(), BestCase,
8344 Model)) {
8345 return nullptr;
8346 }
8347 } else {
8348 if (isa<ClassTemplatePartialSpecializationDecl>(RD)) {
8349 Diag(CI.getLoc(), diag::warn_ignored_ms_inheritance)
8350 << 1 /*partial specialization*/;
8351 return nullptr;
8352 }
8353 if (RD->getDescribedClassTemplate()) {
8354 Diag(CI.getLoc(), diag::warn_ignored_ms_inheritance)
8355 << 0 /*primary template*/;
8356 return nullptr;
8357 }
8358 }
8359
8360 return ::new (Context) MSInheritanceAttr(Context, CI, BestCase);
8361}
8362
8363static void handleCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8364 // The capability attributes take a single string parameter for the name of
8365 // the capability they represent. The lockable attribute does not take any
8366 // parameters. However, semantically, both attributes represent the same
8367 // concept, and so they use the same semantic attribute. Eventually, the
8368 // lockable attribute will be removed.
8369 //
8370 // For backward compatibility, any capability which has no specified string
8371 // literal will be considered a "mutex."
8372 StringRef N("mutex");
8373 SourceLocation LiteralLoc;
8374 if (AL.getKind() == ParsedAttr::AT_Capability &&
8375 !S.checkStringLiteralArgumentAttr(AL, 0, N, &LiteralLoc))
8376 return;
8377
8378 D->addAttr(::new (S.Context) CapabilityAttr(S.Context, AL, N));
8379}
8380
8381static void handleAssertCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8383 if (!checkLockFunAttrCommon(S, D, AL, Args))
8384 return;
8385
8386 D->addAttr(::new (S.Context)
8387 AssertCapabilityAttr(S.Context, AL, Args.data(), Args.size()));
8388}
8389
8391 const ParsedAttr &AL) {
8393 if (!checkLockFunAttrCommon(S, D, AL, Args))
8394 return;
8395
8396 D->addAttr(::new (S.Context) AcquireCapabilityAttr(S.Context, AL, Args.data(),
8397 Args.size()));
8398}
8399
8401 const ParsedAttr &AL) {
8403 if (!checkTryLockFunAttrCommon(S, D, AL, Args))
8404 return;
8405
8406 D->addAttr(::new (S.Context) TryAcquireCapabilityAttr(
8407 S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));
8408}
8409
8411 const ParsedAttr &AL) {
8412 // Check that all arguments are lockable objects.
8414 checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 0, true);
8415
8416 D->addAttr(::new (S.Context) ReleaseCapabilityAttr(S.Context, AL, Args.data(),
8417 Args.size()));
8418}
8419
8421 const ParsedAttr &AL) {
8422 if (!AL.checkAtLeastNumArgs(S, 1))
8423 return;
8424
8425 // check that all arguments are lockable objects
8427 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
8428 if (Args.empty())
8429 return;
8430
8431 RequiresCapabilityAttr *RCA = ::new (S.Context)
8432 RequiresCapabilityAttr(S.Context, AL, Args.data(), Args.size());
8433
8434 D->addAttr(RCA);
8435}
8436
8437static void handleDeprecatedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8438 if (const auto *NSD = dyn_cast<NamespaceDecl>(D)) {
8439 if (NSD->isAnonymousNamespace()) {
8440 S.Diag(AL.getLoc(), diag::warn_deprecated_anonymous_namespace);
8441 // Do not want to attach the attribute to the namespace because that will
8442 // cause confusing diagnostic reports for uses of declarations within the
8443 // namespace.
8444 return;
8445 }
8448 S.Diag(AL.getRange().getBegin(), diag::warn_deprecated_ignored_on_using)
8449 << AL;
8450 return;
8451 }
8452
8453 // Handle the cases where the attribute has a text message.
8454 StringRef Str, Replacement;
8455 if (AL.isArgExpr(0) && AL.getArgAsExpr(0) &&
8456 !S.checkStringLiteralArgumentAttr(AL, 0, Str))
8457 return;
8458
8459 // Support a single optional message only for Declspec and [[]] spellings.
8461 AL.checkAtMostNumArgs(S, 1);
8462 else if (AL.isArgExpr(1) && AL.getArgAsExpr(1) &&
8463 !S.checkStringLiteralArgumentAttr(AL, 1, Replacement))
8464 return;
8465
8466 if (!S.getLangOpts().CPlusPlus14 && AL.isCXX11Attribute() && !AL.isGNUScope())
8467 S.Diag(AL.getLoc(), diag::ext_cxx14_attr) << AL;
8468
8469 D->addAttr(::new (S.Context) DeprecatedAttr(S.Context, AL, Str, Replacement));
8470}
8471
8472static bool isGlobalVar(const Decl *D) {
8473 if (const auto *S = dyn_cast<VarDecl>(D))
8474 return S->hasGlobalStorage();
8475 return false;
8476}
8477
8478static bool isSanitizerAttributeAllowedOnGlobals(StringRef Sanitizer) {
8479 return Sanitizer == "address" || Sanitizer == "hwaddress" ||
8480 Sanitizer == "memtag";
8481}
8482
8483static void handleNoSanitizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8484 if (!AL.checkAtLeastNumArgs(S, 1))
8485 return;
8486
8487 std::vector<StringRef> Sanitizers;
8488
8489 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
8490 StringRef SanitizerName;
8491 SourceLocation LiteralLoc;
8492
8493 if (!S.checkStringLiteralArgumentAttr(AL, I, SanitizerName, &LiteralLoc))
8494 return;
8495
8496 if (parseSanitizerValue(SanitizerName, /*AllowGroups=*/true) ==
8497 SanitizerMask() &&
8498 SanitizerName != "coverage")
8499 S.Diag(LiteralLoc, diag::warn_unknown_sanitizer_ignored) << SanitizerName;
8500 else if (isGlobalVar(D) && !isSanitizerAttributeAllowedOnGlobals(SanitizerName))
8501 S.Diag(D->getLocation(), diag::warn_attribute_type_not_supported_global)
8502 << AL << SanitizerName;
8503 Sanitizers.push_back(SanitizerName);
8504 }
8505
8506 D->addAttr(::new (S.Context) NoSanitizeAttr(S.Context, AL, Sanitizers.data(),
8507 Sanitizers.size()));
8508}
8509
8511 const ParsedAttr &AL) {
8512 StringRef AttrName = AL.getAttrName()->getName();
8513 normalizeName(AttrName);
8514 StringRef SanitizerName = llvm::StringSwitch<StringRef>(AttrName)
8515 .Case("no_address_safety_analysis", "address")
8516 .Case("no_sanitize_address", "address")
8517 .Case("no_sanitize_thread", "thread")
8518 .Case("no_sanitize_memory", "memory");
8519 if (isGlobalVar(D) && SanitizerName != "address")
8520 S.Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
8522
8523 // FIXME: Rather than create a NoSanitizeSpecificAttr, this creates a
8524 // NoSanitizeAttr object; but we need to calculate the correct spelling list
8525 // index rather than incorrectly assume the index for NoSanitizeSpecificAttr
8526 // has the same spellings as the index for NoSanitizeAttr. We don't have a
8527 // general way to "translate" between the two, so this hack attempts to work
8528 // around the issue with hard-coded indices. This is critical for calling
8529 // getSpelling() or prettyPrint() on the resulting semantic attribute object
8530 // without failing assertions.
8531 unsigned TranslatedSpellingIndex = 0;
8533 TranslatedSpellingIndex = 1;
8534
8535 AttributeCommonInfo Info = AL;
8536 Info.setAttributeSpellingListIndex(TranslatedSpellingIndex);
8537 D->addAttr(::new (S.Context)
8538 NoSanitizeAttr(S.Context, Info, &SanitizerName, 1));
8539}
8540
8541static void handleInternalLinkageAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8542 if (InternalLinkageAttr *Internal = S.mergeInternalLinkageAttr(D, AL))
8543 D->addAttr(Internal);
8544}
8545
8546static void handleOpenCLNoSVMAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8548 S.Diag(AL.getLoc(), diag::err_attribute_requires_opencl_version)
8549 << AL << "2.0" << 1;
8550 else
8551 S.Diag(AL.getLoc(), diag::warn_opencl_attr_deprecated_ignored)
8552 << AL << S.LangOpts.getOpenCLVersionString();
8553}
8554
8555static void handleOpenCLAccessAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8556 if (D->isInvalidDecl())
8557 return;
8558
8559 // Check if there is only one access qualifier.
8560 if (D->hasAttr<OpenCLAccessAttr>()) {
8561 if (D->getAttr<OpenCLAccessAttr>()->getSemanticSpelling() ==
8562 AL.getSemanticSpelling()) {
8563 S.Diag(AL.getLoc(), diag::warn_duplicate_declspec)
8564 << AL.getAttrName()->getName() << AL.getRange();
8565 } else {
8566 S.Diag(AL.getLoc(), diag::err_opencl_multiple_access_qualifiers)
8567 << D->getSourceRange();
8568 D->setInvalidDecl(true);
8569 return;
8570 }
8571 }
8572
8573 // OpenCL v2.0 s6.6 - read_write can be used for image types to specify that
8574 // an image object can be read and written. OpenCL v2.0 s6.13.6 - A kernel
8575 // cannot read from and write to the same pipe object. Using the read_write
8576 // (or __read_write) qualifier with the pipe qualifier is a compilation error.
8577 // OpenCL v3.0 s6.8 - For OpenCL C 2.0, or with the
8578 // __opencl_c_read_write_images feature, image objects specified as arguments
8579 // to a kernel can additionally be declared to be read-write.
8580 // C++ for OpenCL 1.0 inherits rule from OpenCL C v2.0.
8581 // C++ for OpenCL 2021 inherits rule from OpenCL C v3.0.
8582 if (const auto *PDecl = dyn_cast<ParmVarDecl>(D)) {
8583 const Type *DeclTy = PDecl->getType().getCanonicalType().getTypePtr();
8584 if (AL.getAttrName()->getName().contains("read_write")) {
8585 bool ReadWriteImagesUnsupported =
8588 !S.getOpenCLOptions().isSupported("__opencl_c_read_write_images",
8589 S.getLangOpts()));
8590 if (ReadWriteImagesUnsupported || DeclTy->isPipeType()) {
8591 S.Diag(AL.getLoc(), diag::err_opencl_invalid_read_write)
8592 << AL << PDecl->getType() << DeclTy->isImageType();
8593 D->setInvalidDecl(true);
8594 return;
8595 }
8596 }
8597 }
8598
8599 D->addAttr(::new (S.Context) OpenCLAccessAttr(S.Context, AL));
8600}
8601
8602static void handleZeroCallUsedRegsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8603 // Check that the argument is a string literal.
8604 StringRef KindStr;
8605 SourceLocation LiteralLoc;
8606 if (!S.checkStringLiteralArgumentAttr(AL, 0, KindStr, &LiteralLoc))
8607 return;
8608
8609 ZeroCallUsedRegsAttr::ZeroCallUsedRegsKind Kind;
8610 if (!ZeroCallUsedRegsAttr::ConvertStrToZeroCallUsedRegsKind(KindStr, Kind)) {
8611 S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported)
8612 << AL << KindStr;
8613 return;
8614 }
8615
8616 D->dropAttr<ZeroCallUsedRegsAttr>();
8617 D->addAttr(ZeroCallUsedRegsAttr::Create(S.Context, Kind, AL));
8618}
8619
8621 const auto *RD = FD->getParent();
8622 // An unnamed struct is anonymous struct only if it's not instantiated.
8623 // However, the struct may not be fully processed yet to determine
8624 // whether it's anonymous or not. In that case, this function treats it as
8625 // an anonymous struct and tries to find a named parent.
8626 while (RD && (RD->isAnonymousStructOrUnion() ||
8627 (!RD->isCompleteDefinition() && RD->getName().empty()))) {
8628 const auto *Parent = dyn_cast<RecordDecl>(RD->getParent());
8629 if (!Parent)
8630 break;
8631 RD = Parent;
8632 }
8633 return RD;
8634}
8635
8637 INCOMPLETE,
8638 SIZELESS,
8639 FUNCTION,
8641 VALID,
8642};
8643
8645 Sema &S, FieldDecl *FD, Expr *E,
8647 // Check the context the attribute is used in
8648
8649 if (FD->getParent()->isUnion()) {
8650 S.Diag(FD->getBeginLoc(), diag::err_counted_by_attr_in_union)
8651 << FD->getSourceRange();
8652 return true;
8653 }
8654
8655 const auto FieldTy = FD->getType();
8656 if (!FieldTy->isArrayType() && !FieldTy->isPointerType()) {
8657 S.Diag(FD->getBeginLoc(),
8658 diag::err_counted_by_attr_not_on_ptr_or_flexible_array_member)
8659 << FD->getLocation();
8660 return true;
8661 }
8662
8663 LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel =
8665 if (FieldTy->isArrayType() &&
8667 StrictFlexArraysLevel, true)) {
8668 S.Diag(FD->getBeginLoc(),
8669 diag::err_counted_by_attr_on_array_not_flexible_array_member)
8670 << FD->getLocation();
8671 return true;
8672 }
8673
8674 CountedByInvalidPointeeTypeKind InvalidTypeKind =
8675 CountedByInvalidPointeeTypeKind::VALID;
8676 QualType PointeeTy;
8677 int SelectPtrOrArr = 0;
8678 if (FieldTy->isPointerType()) {
8679 PointeeTy = FieldTy->getPointeeType();
8680 SelectPtrOrArr = 0;
8681 } else {
8682 assert(FieldTy->isArrayType());
8683 const ArrayType *AT = S.getASTContext().getAsArrayType(FieldTy);
8684 PointeeTy = AT->getElementType();
8685 SelectPtrOrArr = 1;
8686 }
8687 // Note: The `Decl::isFlexibleArrayMemberLike` check earlier on means
8688 // only `PointeeTy->isStructureTypeWithFlexibleArrayMember()` is reachable
8689 // when `FieldTy->isArrayType()`.
8690 if (PointeeTy->isIncompleteType()) {
8691 InvalidTypeKind = CountedByInvalidPointeeTypeKind::INCOMPLETE;
8692 } else if (PointeeTy->isSizelessType()) {
8693 InvalidTypeKind = CountedByInvalidPointeeTypeKind::SIZELESS;
8694 } else if (PointeeTy->isFunctionType()) {
8695 InvalidTypeKind = CountedByInvalidPointeeTypeKind::FUNCTION;
8696 } else if (PointeeTy->isStructureTypeWithFlexibleArrayMember()) {
8697 InvalidTypeKind = CountedByInvalidPointeeTypeKind::FLEXIBLE_ARRAY_MEMBER;
8698 }
8699
8700 if (InvalidTypeKind != CountedByInvalidPointeeTypeKind::VALID) {
8701 S.Diag(FD->getBeginLoc(), diag::err_counted_by_attr_pointee_unknown_size)
8702 << SelectPtrOrArr << PointeeTy << (int)InvalidTypeKind
8703 << FD->getSourceRange();
8704 return true;
8705 }
8706
8707 // Check the expression
8708
8709 if (!E->getType()->isIntegerType() || E->getType()->isBooleanType()) {
8710 S.Diag(E->getBeginLoc(), diag::err_counted_by_attr_argument_not_integer)
8711 << E->getSourceRange();
8712 return true;
8713 }
8714
8715 auto *DRE = dyn_cast<DeclRefExpr>(E);
8716 if (!DRE) {
8717 S.Diag(E->getBeginLoc(),
8718 diag::err_counted_by_attr_only_support_simple_decl_reference)
8719 << E->getSourceRange();
8720 return true;
8721 }
8722
8723 auto *CountDecl = DRE->getDecl();
8724 FieldDecl *CountFD = dyn_cast<FieldDecl>(CountDecl);
8725 if (auto *IFD = dyn_cast<IndirectFieldDecl>(CountDecl)) {
8726 CountFD = IFD->getAnonField();
8727 }
8728 if (!CountFD) {
8729 S.Diag(E->getBeginLoc(), diag::err_counted_by_must_be_in_structure)
8730 << CountDecl << E->getSourceRange();
8731
8732 S.Diag(CountDecl->getBeginLoc(),
8733 diag::note_flexible_array_counted_by_attr_field)
8734 << CountDecl << CountDecl->getSourceRange();
8735 return true;
8736 }
8737
8738 if (FD->getParent() != CountFD->getParent()) {
8739 if (CountFD->getParent()->isUnion()) {
8740 S.Diag(CountFD->getBeginLoc(), diag::err_counted_by_attr_refer_to_union)
8741 << CountFD->getSourceRange();
8742 return true;
8743 }
8744 // Whether CountRD is an anonymous struct is not determined at this
8745 // point. Thus, an additional diagnostic in case it's not anonymous struct
8746 // is done later in `Parser::ParseStructDeclaration`.
8747 auto *RD = GetEnclosingNamedOrTopAnonRecord(FD);
8748 auto *CountRD = GetEnclosingNamedOrTopAnonRecord(CountFD);
8749
8750 if (RD != CountRD) {
8751 S.Diag(E->getBeginLoc(),
8752 diag::err_flexible_array_count_not_in_same_struct)
8753 << CountFD << E->getSourceRange();
8754 S.Diag(CountFD->getBeginLoc(),
8755 diag::note_flexible_array_counted_by_attr_field)
8756 << CountFD << CountFD->getSourceRange();
8757 return true;
8758 }
8759 }
8760
8761 Decls.push_back(TypeCoupledDeclRefInfo(CountFD, /*IsDref*/ false));
8762 return false;
8763}
8764
8765static void handleCountedByAttrField(Sema &S, Decl *D, const ParsedAttr &AL) {
8766 auto *FD = dyn_cast<FieldDecl>(D);
8767 assert(FD);
8768
8769 auto *CountExpr = AL.getArgAsExpr(0);
8770 if (!CountExpr)
8771 return;
8772
8774 if (CheckCountedByAttrOnField(S, FD, CountExpr, Decls))
8775 return;
8776
8777 QualType CAT =
8779 FD->setType(CAT);
8780}
8781
8783 const ParsedAttr &AL) {
8784 StringRef KindStr;
8785 SourceLocation LiteralLoc;
8786 if (!S.checkStringLiteralArgumentAttr(AL, 0, KindStr, &LiteralLoc))
8787 return;
8788
8789 FunctionReturnThunksAttr::Kind Kind;
8790 if (!FunctionReturnThunksAttr::ConvertStrToKind(KindStr, Kind)) {
8791 S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported)
8792 << AL << KindStr;
8793 return;
8794 }
8795 // FIXME: it would be good to better handle attribute merging rather than
8796 // silently replacing the existing attribute, so long as it does not break
8797 // the expected codegen tests.
8798 D->dropAttr<FunctionReturnThunksAttr>();
8799 D->addAttr(FunctionReturnThunksAttr::Create(S.Context, Kind, AL));
8800}
8801
8803 const ParsedAttr &AL) {
8804 assert(isa<TypedefNameDecl>(D) && "This attribute only applies to a typedef");
8805 handleSimpleAttribute<AvailableOnlyInDefaultEvalMethodAttr>(S, D, AL);
8806}
8807
8808static void handleNoMergeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8809 auto *VDecl = dyn_cast<VarDecl>(D);
8810 if (VDecl && !VDecl->isFunctionPointerType()) {
8811 S.Diag(AL.getLoc(), diag::warn_attribute_ignored_non_function_pointer)
8812 << AL << VDecl;
8813 return;
8814 }
8815 D->addAttr(NoMergeAttr::Create(S.Context, AL));
8816}
8817
8818static void handleNoUniqueAddressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8819 D->addAttr(NoUniqueAddressAttr::Create(S.Context, AL));
8820}
8821
8822static void handleSYCLKernelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8823 // The 'sycl_kernel' attribute applies only to function templates.
8824 const auto *FD = cast<FunctionDecl>(D);
8826 assert(FT && "Function template is expected");
8827
8828 // Function template must have at least two template parameters.
8830 if (TL->size() < 2) {
8831 S.Diag(FT->getLocation(), diag::warn_sycl_kernel_num_of_template_params);
8832 return;
8833 }
8834
8835 // Template parameters must be typenames.
8836 for (unsigned I = 0; I < 2; ++I) {
8837 const NamedDecl *TParam = TL->getParam(I);
8838 if (isa<NonTypeTemplateParmDecl>(TParam)) {
8839 S.Diag(FT->getLocation(),
8840 diag::warn_sycl_kernel_invalid_template_param_type);
8841 return;
8842 }
8843 }
8844
8845 // Function must have at least one argument.
8846 if (getFunctionOrMethodNumParams(D) != 1) {
8847 S.Diag(FT->getLocation(), diag::warn_sycl_kernel_num_of_function_params);
8848 return;
8849 }
8850
8851 // Function must return void.
8853 if (!RetTy->isVoidType()) {
8854 S.Diag(FT->getLocation(), diag::warn_sycl_kernel_return_type);
8855 return;
8856 }
8857
8858 handleSimpleAttribute<SYCLKernelAttr>(S, D, AL);
8859}
8860
8861static void handleDestroyAttr(Sema &S, Decl *D, const ParsedAttr &A) {
8862 if (!cast<VarDecl>(D)->hasGlobalStorage()) {
8863 S.Diag(D->getLocation(), diag::err_destroy_attr_on_non_static_var)
8864 << (A.getKind() == ParsedAttr::AT_AlwaysDestroy);
8865 return;
8866 }
8867
8868 if (A.getKind() == ParsedAttr::AT_AlwaysDestroy)
8869 handleSimpleAttribute<AlwaysDestroyAttr>(S, D, A);
8870 else
8871 handleSimpleAttribute<NoDestroyAttr>(S, D, A);
8872}
8873
8874static void handleUninitializedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8875 assert(cast<VarDecl>(D)->getStorageDuration() == SD_Automatic &&
8876 "uninitialized is only valid on automatic duration variables");
8877 D->addAttr(::new (S.Context) UninitializedAttr(S.Context, AL));
8878}
8879
8881 bool DiagnoseFailure) {
8882 QualType Ty = VD->getType();
8883 if (!Ty->isObjCRetainableType()) {
8884 if (DiagnoseFailure) {
8885 S.Diag(VD->getBeginLoc(), diag::warn_ignored_objc_externally_retained)
8886 << 0;
8887 }
8888 return false;
8889 }
8890
8892
8893 // SemaObjC::inferObjCARCLifetime must run after processing decl attributes
8894 // (because __block lowers to an attribute), so if the lifetime hasn't been
8895 // explicitly specified, infer it locally now.
8896 if (LifetimeQual == Qualifiers::OCL_None)
8897 LifetimeQual = Ty->getObjCARCImplicitLifetime();
8898
8899 // The attributes only really makes sense for __strong variables; ignore any
8900 // attempts to annotate a parameter with any other lifetime qualifier.
8901 if (LifetimeQual != Qualifiers::OCL_Strong) {
8902 if (DiagnoseFailure) {
8903 S.Diag(VD->getBeginLoc(), diag::warn_ignored_objc_externally_retained)
8904 << 1;
8905 }
8906 return false;
8907 }
8908
8909 // Tampering with the type of a VarDecl here is a bit of a hack, but we need
8910 // to ensure that the variable is 'const' so that we can error on
8911 // modification, which can otherwise over-release.
8912 VD->setType(Ty.withConst());
8913 VD->setARCPseudoStrong(true);
8914 return true;
8915}
8916
8918 const ParsedAttr &AL) {
8919 if (auto *VD = dyn_cast<VarDecl>(D)) {
8920 assert(!isa<ParmVarDecl>(VD) && "should be diagnosed automatically");
8921 if (!VD->hasLocalStorage()) {
8922 S.Diag(D->getBeginLoc(), diag::warn_ignored_objc_externally_retained)
8923 << 0;
8924 return;
8925 }
8926
8927 if (!tryMakeVariablePseudoStrong(S, VD, /*DiagnoseFailure=*/true))
8928 return;
8929
8930 handleSimpleAttribute<ObjCExternallyRetainedAttr>(S, D, AL);
8931 return;
8932 }
8933
8934 // If D is a function-like declaration (method, block, or function), then we
8935 // make every parameter psuedo-strong.
8936 unsigned NumParams =
8938 for (unsigned I = 0; I != NumParams; ++I) {
8939 auto *PVD = const_cast<ParmVarDecl *>(getFunctionOrMethodParam(D, I));
8940 QualType Ty = PVD->getType();
8941
8942 // If a user wrote a parameter with __strong explicitly, then assume they
8943 // want "real" strong semantics for that parameter. This works because if
8944 // the parameter was written with __strong, then the strong qualifier will
8945 // be non-local.
8948 continue;
8949
8950 tryMakeVariablePseudoStrong(S, PVD, /*DiagnoseFailure=*/false);
8951 }
8952 handleSimpleAttribute<ObjCExternallyRetainedAttr>(S, D, AL);
8953}
8954
8955static void handleMIGServerRoutineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8956 // Check that the return type is a `typedef int kern_return_t` or a typedef
8957 // around it, because otherwise MIG convention checks make no sense.
8958 // BlockDecl doesn't store a return type, so it's annoying to check,
8959 // so let's skip it for now.
8960 if (!isa<BlockDecl>(D)) {
8962 bool IsKernReturnT = false;
8963 while (const auto *TT = T->getAs<TypedefType>()) {
8964 IsKernReturnT = (TT->getDecl()->getName() == "kern_return_t");
8965 T = TT->desugar();
8966 }
8967 if (!IsKernReturnT || T.getCanonicalType() != S.getASTContext().IntTy) {
8968 S.Diag(D->getBeginLoc(),
8969 diag::warn_mig_server_routine_does_not_return_kern_return_t);
8970 return;
8971 }
8972 }
8973
8974 handleSimpleAttribute<MIGServerRoutineAttr>(S, D, AL);
8975}
8976
8977static void handleMSAllocatorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8978 // Warn if the return type is not a pointer or reference type.
8979 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
8980 QualType RetTy = FD->getReturnType();
8981 if (!RetTy->isPointerType() && !RetTy->isReferenceType()) {
8982 S.Diag(AL.getLoc(), diag::warn_declspec_allocator_nonpointer)
8983 << AL.getRange() << RetTy;
8984 return;
8985 }
8986 }
8987
8988 handleSimpleAttribute<MSAllocatorAttr>(S, D, AL);
8989}
8990
8991static void handleAcquireHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8992 if (AL.isUsedAsTypeAttr())
8993 return;
8994 // Warn if the parameter is definitely not an output parameter.
8995 if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
8996 if (PVD->getType()->isIntegerType()) {
8997 S.Diag(AL.getLoc(), diag::err_attribute_output_parameter)
8998 << AL.getRange();
8999 return;
9000 }
9001 }
9002 StringRef Argument;
9003 if (!S.checkStringLiteralArgumentAttr(AL, 0, Argument))
9004 return;
9005 D->addAttr(AcquireHandleAttr::Create(S.Context, Argument, AL));
9006}
9007
9008template<typename Attr>
9009static void handleHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
9010 StringRef Argument;
9011 if (!S.checkStringLiteralArgumentAttr(AL, 0, Argument))
9012 return;
9013 D->addAttr(Attr::Create(S.Context, Argument, AL));
9014}
9015
9016template<typename Attr>
9017static void handleUnsafeBufferUsage(Sema &S, Decl *D, const ParsedAttr &AL) {
9018 D->addAttr(Attr::Create(S.Context, AL));
9019}
9020
9021static void handleCFGuardAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
9022 // The guard attribute takes a single identifier argument.
9023
9024 if (!AL.isArgIdent(0)) {
9025 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
9026 << AL << AANT_ArgumentIdentifier;
9027 return;
9028 }
9029
9030 CFGuardAttr::GuardArg Arg;
9031 IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
9032 if (!CFGuardAttr::ConvertStrToGuardArg(II->getName(), Arg)) {
9033 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
9034 return;
9035 }
9036
9037 D->addAttr(::new (S.Context) CFGuardAttr(S.Context, AL, Arg));
9038}
9039
9040
9041template <typename AttrTy>
9042static const AttrTy *findEnforceTCBAttrByName(Decl *D, StringRef Name) {
9043 auto Attrs = D->specific_attrs<AttrTy>();
9044 auto I = llvm::find_if(Attrs,
9045 [Name](const AttrTy *A) {
9046 return A->getTCBName() == Name;
9047 });
9048 return I == Attrs.end() ? nullptr : *I;
9049}
9050
9051template <typename AttrTy, typename ConflictingAttrTy>
9052static void handleEnforceTCBAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
9053 StringRef Argument;
9054 if (!S.checkStringLiteralArgumentAttr(AL, 0, Argument))
9055 return;
9056
9057 // A function cannot be have both regular and leaf membership in the same TCB.
9058 if (const ConflictingAttrTy *ConflictingAttr =
9059 findEnforceTCBAttrByName<ConflictingAttrTy>(D, Argument)) {
9060 // We could attach a note to the other attribute but in this case
9061 // there's no need given how the two are very close to each other.
9062 S.Diag(AL.getLoc(), diag::err_tcb_conflicting_attributes)
9063 << AL.getAttrName()->getName() << ConflictingAttr->getAttrName()->getName()
9064 << Argument;
9065
9066 // Error recovery: drop the non-leaf attribute so that to suppress
9067 // all future warnings caused by erroneous attributes. The leaf attribute
9068 // needs to be kept because it can only suppresses warnings, not cause them.
9069 D->dropAttr<EnforceTCBAttr>();
9070 return;
9071 }
9072
9073 D->addAttr(AttrTy::Create(S.Context, Argument, AL));
9074}
9075
9076template <typename AttrTy, typename ConflictingAttrTy>
9077static AttrTy *mergeEnforceTCBAttrImpl(Sema &S, Decl *D, const AttrTy &AL) {
9078 // Check if the new redeclaration has different leaf-ness in the same TCB.
9079 StringRef TCBName = AL.getTCBName();
9080 if (const ConflictingAttrTy *ConflictingAttr =
9081 findEnforceTCBAttrByName<ConflictingAttrTy>(D, TCBName)) {
9082 S.Diag(ConflictingAttr->getLoc(), diag::err_tcb_conflicting_attributes)
9083 << ConflictingAttr->getAttrName()->getName()
9084 << AL.getAttrName()->getName() << TCBName;
9085
9086 // Add a note so that the user could easily find the conflicting attribute.
9087 S.Diag(AL.getLoc(), diag::note_conflicting_attribute);
9088
9089 // More error recovery.
9090 D->dropAttr<EnforceTCBAttr>();
9091 return nullptr;
9092 }
9093
9094 ASTContext &Context = S.getASTContext();
9095 return ::new(Context) AttrTy(Context, AL, AL.getTCBName());
9096}
9097
9098EnforceTCBAttr *Sema::mergeEnforceTCBAttr(Decl *D, const EnforceTCBAttr &AL) {
9099 return mergeEnforceTCBAttrImpl<EnforceTCBAttr, EnforceTCBLeafAttr>(
9100 *this, D, AL);
9101}
9102
9104 Decl *D, const EnforceTCBLeafAttr &AL) {
9105 return mergeEnforceTCBAttrImpl<EnforceTCBLeafAttr, EnforceTCBAttr>(
9106 *this, D, AL);
9107}
9108
9109//===----------------------------------------------------------------------===//
9110// Top Level Sema Entry Points
9111//===----------------------------------------------------------------------===//
9112
9113// Returns true if the attribute must delay setting its arguments until after
9114// template instantiation, and false otherwise.
9116 // Only attributes that accept expression parameter packs can delay arguments.
9117 if (!AL.acceptsExprPack())
9118 return false;
9119
9120 bool AttrHasVariadicArg = AL.hasVariadicArg();
9121 unsigned AttrNumArgs = AL.getNumArgMembers();
9122 for (size_t I = 0; I < std::min(AL.getNumArgs(), AttrNumArgs); ++I) {
9123 bool IsLastAttrArg = I == (AttrNumArgs - 1);
9124 // If the argument is the last argument and it is variadic it can contain
9125 // any expression.
9126 if (IsLastAttrArg && AttrHasVariadicArg)
9127 return false;
9128 Expr *E = AL.getArgAsExpr(I);
9129 bool ArgMemberCanHoldExpr = AL.isParamExpr(I);
9130 // If the expression is a pack expansion then arguments must be delayed
9131 // unless the argument is an expression and it is the last argument of the
9132 // attribute.
9133 if (isa<PackExpansionExpr>(E))
9134 return !(IsLastAttrArg && ArgMemberCanHoldExpr);
9135 // Last case is if the expression is value dependent then it must delay
9136 // arguments unless the corresponding argument is able to hold the
9137 // expression.
9138 if (E->isValueDependent() && !ArgMemberCanHoldExpr)
9139 return true;
9140 }
9141 return false;
9142}
9143
9145 Sema &S, const ParsedAttr &AL, const FunctionProtoType *FPT,
9146 FunctionType::ArmStateValue CurrentState, StringRef StateName) {
9147 auto CheckForIncompatibleAttr =
9148 [&](FunctionType::ArmStateValue IncompatibleState,
9149 StringRef IncompatibleStateName) {
9150 if (CurrentState == IncompatibleState) {
9151 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
9152 << (std::string("'__arm_new(\"") + StateName.str() + "\")'")
9153 << (std::string("'") + IncompatibleStateName.str() + "(\"" +
9154 StateName.str() + "\")'")
9155 << true;
9156 AL.setInvalid();
9157 }
9158 };
9159
9160 CheckForIncompatibleAttr(FunctionType::ARM_In, "__arm_in");
9161 CheckForIncompatibleAttr(FunctionType::ARM_Out, "__arm_out");
9162 CheckForIncompatibleAttr(FunctionType::ARM_InOut, "__arm_inout");
9163 CheckForIncompatibleAttr(FunctionType::ARM_Preserves, "__arm_preserves");
9164 return AL.isInvalid();
9165}
9166
9167static void handleArmNewAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
9168 if (!AL.getNumArgs()) {
9169 S.Diag(AL.getLoc(), diag::err_missing_arm_state) << AL;
9170 AL.setInvalid();
9171 return;
9172 }
9173
9174 std::vector<StringRef> NewState;
9175 if (const auto *ExistingAttr = D->getAttr<ArmNewAttr>()) {
9176 for (StringRef S : ExistingAttr->newArgs())
9177 NewState.push_back(S);
9178 }
9179
9180 bool HasZA = false;
9181 bool HasZT0 = false;
9182 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
9183 StringRef StateName;
9184 SourceLocation LiteralLoc;
9185 if (!S.checkStringLiteralArgumentAttr(AL, I, StateName, &LiteralLoc))
9186 return;
9187
9188 if (StateName == "za")
9189 HasZA = true;
9190 else if (StateName == "zt0")
9191 HasZT0 = true;
9192 else {
9193 S.Diag(LiteralLoc, diag::err_unknown_arm_state) << StateName;
9194 AL.setInvalid();
9195 return;
9196 }
9197
9198 if (!llvm::is_contained(NewState, StateName)) // Avoid adding duplicates.
9199 NewState.push_back(StateName);
9200 }
9201
9202 if (auto *FPT = dyn_cast<FunctionProtoType>(D->getFunctionType())) {
9204 FunctionType::getArmZAState(FPT->getAArch64SMEAttributes());
9205 if (HasZA && ZAState != FunctionType::ARM_None &&
9206 checkArmNewAttrMutualExclusion(S, AL, FPT, ZAState, "za"))
9207 return;
9209 FunctionType::getArmZT0State(FPT->getAArch64SMEAttributes());
9210 if (HasZT0 && ZT0State != FunctionType::ARM_None &&
9211 checkArmNewAttrMutualExclusion(S, AL, FPT, ZT0State, "zt0"))
9212 return;
9213 }
9214
9215 D->dropAttr<ArmNewAttr>();
9216 D->addAttr(::new (S.Context)
9217 ArmNewAttr(S.Context, AL, NewState.data(), NewState.size()));
9218}
9219
9220/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
9221/// the attribute applies to decls. If the attribute is a type attribute, just
9222/// silently ignore it if a GNU attribute.
9223static void
9225 const Sema::ProcessDeclAttributeOptions &Options) {
9227 return;
9228
9229 // Ignore C++11 attributes on declarator chunks: they appertain to the type
9230 // instead.
9231 if (AL.isCXX11Attribute() && !Options.IncludeCXX11Attributes)
9232 return;
9233
9234 // Unknown attributes are automatically warned on. Target-specific attributes
9235 // which do not apply to the current target architecture are treated as
9236 // though they were unknown attributes.
9239 S.Diag(AL.getLoc(),
9241 ? (unsigned)diag::err_keyword_not_supported_on_target
9242 : AL.isDeclspecAttribute()
9243 ? (unsigned)diag::warn_unhandled_ms_attribute_ignored
9244 : (unsigned)diag::warn_unknown_attribute_ignored)
9245 << AL << AL.getRange();
9246 return;
9247 }
9248
9249 // Check if argument population must delayed to after template instantiation.
9250 bool MustDelayArgs = MustDelayAttributeArguments(AL);
9251
9252 // Argument number check must be skipped if arguments are delayed.
9253 if (S.checkCommonAttributeFeatures(D, AL, MustDelayArgs))
9254 return;
9255
9256 if (MustDelayArgs) {
9258 return;
9259 }
9260
9261 switch (AL.getKind()) {
9262 default:
9264 break;
9265 if (!AL.isStmtAttr()) {
9266 assert(AL.isTypeAttr() && "Non-type attribute not handled");
9267 }
9268 if (AL.isTypeAttr()) {
9269 if (Options.IgnoreTypeAttributes)
9270 break;
9272 // Non-[[]] type attributes are handled in processTypeAttrs(); silently
9273 // move on.
9274 break;
9275 }
9276
9277 // According to the C and C++ standards, we should never see a
9278 // [[]] type attribute on a declaration. However, we have in the past
9279 // allowed some type attributes to "slide" to the `DeclSpec`, so we need
9280 // to continue to support this legacy behavior. We only do this, however,
9281 // if
9282 // - we actually have a `DeclSpec`, i.e. if we're looking at a
9283 // `DeclaratorDecl`, or
9284 // - we are looking at an alias-declaration, where historically we have
9285 // allowed type attributes after the identifier to slide to the type.
9287 isa<DeclaratorDecl, TypeAliasDecl>(D)) {
9288 // Suggest moving the attribute to the type instead, but only for our
9289 // own vendor attributes; moving other vendors' attributes might hurt
9290 // portability.
9291 if (AL.isClangScope()) {
9292 S.Diag(AL.getLoc(), diag::warn_type_attribute_deprecated_on_decl)
9293 << AL << D->getLocation();
9294 }
9295
9296 // Allow this type attribute to be handled in processTypeAttrs();
9297 // silently move on.
9298 break;
9299 }
9300
9301 if (AL.getKind() == ParsedAttr::AT_Regparm) {
9302 // `regparm` is a special case: It's a type attribute but we still want
9303 // to treat it as if it had been written on the declaration because that
9304 // way we'll be able to handle it directly in `processTypeAttr()`.
9305 // If we treated `regparm` it as if it had been written on the
9306 // `DeclSpec`, the logic in `distributeFunctionTypeAttrFromDeclSepc()`
9307 // would try to move it to the declarator, but that doesn't work: We
9308 // can't remove the attribute from the list of declaration attributes
9309 // because it might be needed by other declarators in the same
9310 // declaration.
9311 break;
9312 }
9313
9314 if (AL.getKind() == ParsedAttr::AT_VectorSize) {
9315 // `vector_size` is a special case: It's a type attribute semantically,
9316 // but GCC expects the [[]] syntax to be written on the declaration (and
9317 // warns that the attribute has no effect if it is placed on the
9318 // decl-specifier-seq).
9319 // Silently move on and allow the attribute to be handled in
9320 // processTypeAttr().
9321 break;
9322 }
9323
9324 if (AL.getKind() == ParsedAttr::AT_NoDeref) {
9325 // FIXME: `noderef` currently doesn't work correctly in [[]] syntax.
9326 // See https://github.com/llvm/llvm-project/issues/55790 for details.
9327 // We allow processTypeAttrs() to emit a warning and silently move on.
9328 break;
9329 }
9330 }
9331 // N.B., ClangAttrEmitter.cpp emits a diagnostic helper that ensures a
9332 // statement attribute is not written on a declaration, but this code is
9333 // needed for type attributes as well as statement attributes in Attr.td
9334 // that do not list any subjects.
9335 S.Diag(AL.getLoc(), diag::err_attribute_invalid_on_decl)
9336 << AL << AL.isRegularKeywordAttribute() << D->getLocation();
9337 break;
9338 case ParsedAttr::AT_Interrupt:
9339 handleInterruptAttr(S, D, AL);
9340 break;
9341 case ParsedAttr::AT_X86ForceAlignArgPointer:
9343 break;
9344 case ParsedAttr::AT_ReadOnlyPlacement:
9345 handleSimpleAttribute<ReadOnlyPlacementAttr>(S, D, AL);
9346 break;
9347 case ParsedAttr::AT_DLLExport:
9348 case ParsedAttr::AT_DLLImport:
9349 handleDLLAttr(S, D, AL);
9350 break;
9351 case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
9353 break;
9354 case ParsedAttr::AT_AMDGPUWavesPerEU:
9356 break;
9357 case ParsedAttr::AT_AMDGPUNumSGPR:
9358 handleAMDGPUNumSGPRAttr(S, D, AL);
9359 break;
9360 case ParsedAttr::AT_AMDGPUNumVGPR:
9361 handleAMDGPUNumVGPRAttr(S, D, AL);
9362 break;
9363 case ParsedAttr::AT_AMDGPUMaxNumWorkGroups:
9365 break;
9366 case ParsedAttr::AT_AVRSignal:
9367 handleAVRSignalAttr(S, D, AL);
9368 break;
9369 case ParsedAttr::AT_BPFPreserveAccessIndex:
9371 break;
9372 case ParsedAttr::AT_BPFPreserveStaticOffset:
9373 handleSimpleAttribute<BPFPreserveStaticOffsetAttr>(S, D, AL);
9374 break;
9375 case ParsedAttr::AT_BTFDeclTag:
9376 handleBTFDeclTagAttr(S, D, AL);
9377 break;
9378 case ParsedAttr::AT_WebAssemblyExportName:
9380 break;
9381 case ParsedAttr::AT_WebAssemblyImportModule:
9383 break;
9384 case ParsedAttr::AT_WebAssemblyImportName:
9386 break;
9387 case ParsedAttr::AT_IBOutlet:
9388 handleIBOutlet(S, D, AL);
9389 break;
9390 case ParsedAttr::AT_IBOutletCollection:
9391 handleIBOutletCollection(S, D, AL);
9392 break;
9393 case ParsedAttr::AT_IFunc:
9394 handleIFuncAttr(S, D, AL);
9395 break;
9396 case ParsedAttr::AT_Alias:
9397 handleAliasAttr(S, D, AL);
9398 break;
9399 case ParsedAttr::AT_Aligned:
9400 handleAlignedAttr(S, D, AL);
9401 break;
9402 case ParsedAttr::AT_AlignValue:
9403 handleAlignValueAttr(S, D, AL);
9404 break;
9405 case ParsedAttr::AT_AllocSize:
9406 handleAllocSizeAttr(S, D, AL);
9407 break;
9408 case ParsedAttr::AT_AlwaysInline:
9409 handleAlwaysInlineAttr(S, D, AL);
9410 break;
9411 case ParsedAttr::AT_AnalyzerNoReturn:
9413 break;
9414 case ParsedAttr::AT_TLSModel:
9415 handleTLSModelAttr(S, D, AL);
9416 break;
9417 case ParsedAttr::AT_Annotate:
9418 handleAnnotateAttr(S, D, AL);
9419 break;
9420 case ParsedAttr::AT_Availability:
9421 handleAvailabilityAttr(S, D, AL);
9422 break;
9423 case ParsedAttr::AT_CarriesDependency:
9424 handleDependencyAttr(S, scope, D, AL);
9425 break;
9426 case ParsedAttr::AT_CPUDispatch:
9427 case ParsedAttr::AT_CPUSpecific:
9428 handleCPUSpecificAttr(S, D, AL);
9429 break;
9430 case ParsedAttr::AT_Common:
9431 handleCommonAttr(S, D, AL);
9432 break;
9433 case ParsedAttr::AT_CUDAConstant:
9434 handleConstantAttr(S, D, AL);
9435 break;
9436 case ParsedAttr::AT_PassObjectSize:
9437 handlePassObjectSizeAttr(S, D, AL);
9438 break;
9439 case ParsedAttr::AT_Constructor:
9440 handleConstructorAttr(S, D, AL);
9441 break;
9442 case ParsedAttr::AT_Deprecated:
9443 handleDeprecatedAttr(S, D, AL);
9444 break;
9445 case ParsedAttr::AT_Destructor:
9446 handleDestructorAttr(S, D, AL);
9447 break;
9448 case ParsedAttr::AT_EnableIf:
9449 handleEnableIfAttr(S, D, AL);
9450 break;
9451 case ParsedAttr::AT_Error:
9452 handleErrorAttr(S, D, AL);
9453 break;
9454 case ParsedAttr::AT_ExcludeFromExplicitInstantiation:
9456 break;
9457 case ParsedAttr::AT_DiagnoseIf:
9458 handleDiagnoseIfAttr(S, D, AL);
9459 break;
9460 case ParsedAttr::AT_DiagnoseAsBuiltin:
9462 break;
9463 case ParsedAttr::AT_NoBuiltin:
9464 handleNoBuiltinAttr(S, D, AL);
9465 break;
9466 case ParsedAttr::AT_ExtVectorType:
9467 handleExtVectorTypeAttr(S, D, AL);
9468 break;
9469 case ParsedAttr::AT_ExternalSourceSymbol:
9471 break;
9472 case ParsedAttr::AT_MinSize:
9473 handleMinSizeAttr(S, D, AL);
9474 break;
9475 case ParsedAttr::AT_OptimizeNone:
9476 handleOptimizeNoneAttr(S, D, AL);
9477 break;
9478 case ParsedAttr::AT_EnumExtensibility:
9480 break;
9481 case ParsedAttr::AT_SYCLKernel:
9482 handleSYCLKernelAttr(S, D, AL);
9483 break;
9484 case ParsedAttr::AT_SYCLSpecialClass:
9485 handleSimpleAttribute<SYCLSpecialClassAttr>(S, D, AL);
9486 break;
9487 case ParsedAttr::AT_Format:
9488 handleFormatAttr(S, D, AL);
9489 break;
9490 case ParsedAttr::AT_FormatArg:
9491 handleFormatArgAttr(S, D, AL);
9492 break;
9493 case ParsedAttr::AT_Callback:
9494 handleCallbackAttr(S, D, AL);
9495 break;
9496 case ParsedAttr::AT_CalledOnce:
9497 handleCalledOnceAttr(S, D, AL);
9498 break;
9499 case ParsedAttr::AT_NVPTXKernel:
9500 case ParsedAttr::AT_CUDAGlobal:
9501 handleGlobalAttr(S, D, AL);
9502 break;
9503 case ParsedAttr::AT_CUDADevice:
9504 handleDeviceAttr(S, D, AL);
9505 break;
9506 case ParsedAttr::AT_HIPManaged:
9507 handleManagedAttr(S, D, AL);
9508 break;
9509 case ParsedAttr::AT_GNUInline:
9510 handleGNUInlineAttr(S, D, AL);
9511 break;
9512 case ParsedAttr::AT_CUDALaunchBounds:
9513 handleLaunchBoundsAttr(S, D, AL);
9514 break;
9515 case ParsedAttr::AT_Restrict:
9516 handleRestrictAttr(S, D, AL);
9517 break;
9518 case ParsedAttr::AT_Mode:
9519 handleModeAttr(S, D, AL);
9520 break;
9521 case ParsedAttr::AT_NonNull:
9522 if (auto *PVD = dyn_cast<ParmVarDecl>(D))
9523 handleNonNullAttrParameter(S, PVD, AL);
9524 else
9525 handleNonNullAttr(S, D, AL);
9526 break;
9527 case ParsedAttr::AT_ReturnsNonNull:
9528 handleReturnsNonNullAttr(S, D, AL);
9529 break;
9530 case ParsedAttr::AT_NoEscape:
9531 handleNoEscapeAttr(S, D, AL);
9532 break;
9533 case ParsedAttr::AT_MaybeUndef:
9534 handleSimpleAttribute<MaybeUndefAttr>(S, D, AL);
9535 break;
9536 case ParsedAttr::AT_AssumeAligned:
9537 handleAssumeAlignedAttr(S, D, AL);
9538 break;
9539 case ParsedAttr::AT_AllocAlign:
9540 handleAllocAlignAttr(S, D, AL);
9541 break;
9542 case ParsedAttr::AT_Ownership:
9543 handleOwnershipAttr(S, D, AL);
9544 break;
9545 case ParsedAttr::AT_Naked:
9546 handleNakedAttr(S, D, AL);
9547 break;
9548 case ParsedAttr::AT_NoReturn:
9549 handleNoReturnAttr(S, D, AL);
9550 break;
9551 case ParsedAttr::AT_CXX11NoReturn:
9553 break;
9554 case ParsedAttr::AT_AnyX86NoCfCheck:
9555 handleNoCfCheckAttr(S, D, AL);
9556 break;
9557 case ParsedAttr::AT_NoThrow:
9558 if (!AL.isUsedAsTypeAttr())
9559 handleSimpleAttribute<NoThrowAttr>(S, D, AL);
9560 break;
9561 case ParsedAttr::AT_CUDAShared:
9562 handleSharedAttr(S, D, AL);
9563 break;
9564 case ParsedAttr::AT_VecReturn:
9565 handleVecReturnAttr(S, D, AL);
9566 break;
9567 case ParsedAttr::AT_ObjCOwnership:
9568 handleObjCOwnershipAttr(S, D, AL);
9569 break;
9570 case ParsedAttr::AT_ObjCPreciseLifetime:
9572 break;
9573 case ParsedAttr::AT_ObjCReturnsInnerPointer:
9575 break;
9576 case ParsedAttr::AT_ObjCRequiresSuper:
9578 break;
9579 case ParsedAttr::AT_ObjCBridge:
9580 handleObjCBridgeAttr(S, D, AL);
9581 break;
9582 case ParsedAttr::AT_ObjCBridgeMutable:
9584 break;
9585 case ParsedAttr::AT_ObjCBridgeRelated:
9587 break;
9588 case ParsedAttr::AT_ObjCDesignatedInitializer:
9590 break;
9591 case ParsedAttr::AT_ObjCRuntimeName:
9592 handleObjCRuntimeName(S, D, AL);
9593 break;
9594 case ParsedAttr::AT_ObjCBoxable:
9595 handleObjCBoxable(S, D, AL);
9596 break;
9597 case ParsedAttr::AT_NSErrorDomain:
9598 handleNSErrorDomain(S, D, AL);
9599 break;
9600 case ParsedAttr::AT_CFConsumed:
9601 case ParsedAttr::AT_NSConsumed:
9602 case ParsedAttr::AT_OSConsumed:
9604 /*IsTemplateInstantiation=*/false);
9605 break;
9606 case ParsedAttr::AT_OSReturnsRetainedOnZero:
9607 handleSimpleAttributeOrDiagnose<OSReturnsRetainedOnZeroAttr>(
9608 S, D, AL, isValidOSObjectOutParameter(D),
9609 diag::warn_ns_attribute_wrong_parameter_type,
9610 /*Extra Args=*/AL, /*pointer-to-OSObject-pointer*/ 3, AL.getRange());
9611 break;
9612 case ParsedAttr::AT_OSReturnsRetainedOnNonZero:
9613 handleSimpleAttributeOrDiagnose<OSReturnsRetainedOnNonZeroAttr>(
9614 S, D, AL, isValidOSObjectOutParameter(D),
9615 diag::warn_ns_attribute_wrong_parameter_type,
9616 /*Extra Args=*/AL, /*pointer-to-OSObject-poointer*/ 3, AL.getRange());
9617 break;
9618 case ParsedAttr::AT_NSReturnsAutoreleased:
9619 case ParsedAttr::AT_NSReturnsNotRetained:
9620 case ParsedAttr::AT_NSReturnsRetained:
9621 case ParsedAttr::AT_CFReturnsNotRetained:
9622 case ParsedAttr::AT_CFReturnsRetained:
9623 case ParsedAttr::AT_OSReturnsNotRetained:
9624 case ParsedAttr::AT_OSReturnsRetained:
9626 break;
9627 case ParsedAttr::AT_WorkGroupSizeHint:
9628 handleWorkGroupSize<WorkGroupSizeHintAttr>(S, D, AL);
9629 break;
9630 case ParsedAttr::AT_ReqdWorkGroupSize:
9631 handleWorkGroupSize<ReqdWorkGroupSizeAttr>(S, D, AL);
9632 break;
9633 case ParsedAttr::AT_OpenCLIntelReqdSubGroupSize:
9634 handleSubGroupSize(S, D, AL);
9635 break;
9636 case ParsedAttr::AT_VecTypeHint:
9637 handleVecTypeHint(S, D, AL);
9638 break;
9639 case ParsedAttr::AT_InitPriority:
9640 handleInitPriorityAttr(S, D, AL);
9641 break;
9642 case ParsedAttr::AT_Packed:
9643 handlePackedAttr(S, D, AL);
9644 break;
9645 case ParsedAttr::AT_PreferredName:
9646 handlePreferredName(S, D, AL);
9647 break;
9648 case ParsedAttr::AT_Section:
9649 handleSectionAttr(S, D, AL);
9650 break;
9651 case ParsedAttr::AT_CodeModel:
9652 handleCodeModelAttr(S, D, AL);
9653 break;
9654 case ParsedAttr::AT_RandomizeLayout:
9655 handleRandomizeLayoutAttr(S, D, AL);
9656 break;
9657 case ParsedAttr::AT_NoRandomizeLayout:
9659 break;
9660 case ParsedAttr::AT_CodeSeg:
9661 handleCodeSegAttr(S, D, AL);
9662 break;
9663 case ParsedAttr::AT_Target:
9664 handleTargetAttr(S, D, AL);
9665 break;
9666 case ParsedAttr::AT_TargetVersion:
9667 handleTargetVersionAttr(S, D, AL);
9668 break;
9669 case ParsedAttr::AT_TargetClones:
9670 handleTargetClonesAttr(S, D, AL);
9671 break;
9672 case ParsedAttr::AT_MinVectorWidth:
9673 handleMinVectorWidthAttr(S, D, AL);
9674 break;
9675 case ParsedAttr::AT_Unavailable:
9676 handleAttrWithMessage<UnavailableAttr>(S, D, AL);
9677 break;
9678 case ParsedAttr::AT_OMPAssume:
9679 handleOMPAssumeAttr(S, D, AL);
9680 break;
9681 case ParsedAttr::AT_ObjCDirect:
9682 handleObjCDirectAttr(S, D, AL);
9683 break;
9684 case ParsedAttr::AT_ObjCDirectMembers:
9686 handleSimpleAttribute<ObjCDirectMembersAttr>(S, D, AL);
9687 break;
9688 case ParsedAttr::AT_ObjCExplicitProtocolImpl:
9690 break;
9691 case ParsedAttr::AT_Unused:
9692 handleUnusedAttr(S, D, AL);
9693 break;
9694 case ParsedAttr::AT_Visibility:
9695 handleVisibilityAttr(S, D, AL, false);
9696 break;
9697 case ParsedAttr::AT_TypeVisibility:
9698 handleVisibilityAttr(S, D, AL, true);
9699 break;
9700 case ParsedAttr::AT_WarnUnusedResult:
9701 handleWarnUnusedResult(S, D, AL);
9702 break;
9703 case ParsedAttr::AT_WeakRef:
9704 handleWeakRefAttr(S, D, AL);
9705 break;
9706 case ParsedAttr::AT_WeakImport:
9707 handleWeakImportAttr(S, D, AL);
9708 break;
9709 case ParsedAttr::AT_TransparentUnion:
9711 break;
9712 case ParsedAttr::AT_ObjCMethodFamily:
9714 break;
9715 case ParsedAttr::AT_ObjCNSObject:
9716 handleObjCNSObject(S, D, AL);
9717 break;
9718 case ParsedAttr::AT_ObjCIndependentClass:
9720 break;
9721 case ParsedAttr::AT_Blocks:
9722 handleBlocksAttr(S, D, AL);
9723 break;
9724 case ParsedAttr::AT_Sentinel:
9725 handleSentinelAttr(S, D, AL);
9726 break;
9727 case ParsedAttr::AT_Cleanup:
9728 handleCleanupAttr(S, D, AL);
9729 break;
9730 case ParsedAttr::AT_NoDebug:
9731 handleNoDebugAttr(S, D, AL);
9732 break;
9733 case ParsedAttr::AT_CmseNSEntry:
9734 handleCmseNSEntryAttr(S, D, AL);
9735 break;
9736 case ParsedAttr::AT_StdCall:
9737 case ParsedAttr::AT_CDecl:
9738 case ParsedAttr::AT_FastCall:
9739 case ParsedAttr::AT_ThisCall:
9740 case ParsedAttr::AT_Pascal:
9741 case ParsedAttr::AT_RegCall:
9742 case ParsedAttr::AT_SwiftCall:
9743 case ParsedAttr::AT_SwiftAsyncCall:
9744 case ParsedAttr::AT_VectorCall:
9745 case ParsedAttr::AT_MSABI:
9746 case ParsedAttr::AT_SysVABI:
9747 case ParsedAttr::AT_Pcs:
9748 case ParsedAttr::AT_IntelOclBicc:
9749 case ParsedAttr::AT_PreserveMost:
9750 case ParsedAttr::AT_PreserveAll:
9751 case ParsedAttr::AT_AArch64VectorPcs:
9752 case ParsedAttr::AT_AArch64SVEPcs:
9753 case ParsedAttr::AT_AMDGPUKernelCall:
9754 case ParsedAttr::AT_M68kRTD:
9755 case ParsedAttr::AT_PreserveNone:
9756 case ParsedAttr::AT_RISCVVectorCC:
9757 handleCallConvAttr(S, D, AL);
9758 break;
9759 case ParsedAttr::AT_Suppress:
9760 handleSuppressAttr(S, D, AL);
9761 break;
9762 case ParsedAttr::AT_Owner:
9763 case ParsedAttr::AT_Pointer:
9765 break;
9766 case ParsedAttr::AT_OpenCLAccess:
9767 handleOpenCLAccessAttr(S, D, AL);
9768 break;
9769 case ParsedAttr::AT_OpenCLNoSVM:
9770 handleOpenCLNoSVMAttr(S, D, AL);
9771 break;
9772 case ParsedAttr::AT_SwiftContext:
9774 break;
9775 case ParsedAttr::AT_SwiftAsyncContext:
9777 break;
9778 case ParsedAttr::AT_SwiftErrorResult:
9780 break;
9781 case ParsedAttr::AT_SwiftIndirectResult:
9783 break;
9784 case ParsedAttr::AT_InternalLinkage:
9785 handleInternalLinkageAttr(S, D, AL);
9786 break;
9787 case ParsedAttr::AT_ZeroCallUsedRegs:
9789 break;
9790 case ParsedAttr::AT_FunctionReturnThunks:
9792 break;
9793 case ParsedAttr::AT_NoMerge:
9794 handleNoMergeAttr(S, D, AL);
9795 break;
9796 case ParsedAttr::AT_NoUniqueAddress:
9797 handleNoUniqueAddressAttr(S, D, AL);
9798 break;
9799
9800 case ParsedAttr::AT_AvailableOnlyInDefaultEvalMethod:
9802 break;
9803
9804 case ParsedAttr::AT_CountedBy:
9805 handleCountedByAttrField(S, D, AL);
9806 break;
9807
9808 // Microsoft attributes:
9809 case ParsedAttr::AT_LayoutVersion:
9810 handleLayoutVersion(S, D, AL);
9811 break;
9812 case ParsedAttr::AT_Uuid:
9813 handleUuidAttr(S, D, AL);
9814 break;
9815 case ParsedAttr::AT_MSInheritance:
9816 handleMSInheritanceAttr(S, D, AL);
9817 break;
9818 case ParsedAttr::AT_Thread:
9819 handleDeclspecThreadAttr(S, D, AL);
9820 break;
9821 case ParsedAttr::AT_MSConstexpr:
9822 handleMSConstexprAttr(S, D, AL);
9823 break;
9824
9825 // HLSL attributes:
9826 case ParsedAttr::AT_HLSLNumThreads:
9827 handleHLSLNumThreadsAttr(S, D, AL);
9828 break;
9829 case ParsedAttr::AT_HLSLSV_GroupIndex:
9830 handleSimpleAttribute<HLSLSV_GroupIndexAttr>(S, D, AL);
9831 break;
9832 case ParsedAttr::AT_HLSLSV_DispatchThreadID:
9834 break;
9835 case ParsedAttr::AT_HLSLPackOffset:
9836 handleHLSLPackOffsetAttr(S, D, AL);
9837 break;
9838 case ParsedAttr::AT_HLSLShader:
9839 handleHLSLShaderAttr(S, D, AL);
9840 break;
9841 case ParsedAttr::AT_HLSLResourceBinding:
9843 break;
9844 case ParsedAttr::AT_HLSLParamModifier:
9846 break;
9847
9848 case ParsedAttr::AT_AbiTag:
9849 handleAbiTagAttr(S, D, AL);
9850 break;
9851 case ParsedAttr::AT_CFGuard:
9852 handleCFGuardAttr(S, D, AL);
9853 break;
9854
9855 // Thread safety attributes:
9856 case ParsedAttr::AT_AssertExclusiveLock:
9858 break;
9859 case ParsedAttr::AT_AssertSharedLock:
9861 break;
9862 case ParsedAttr::AT_PtGuardedVar:
9863 handlePtGuardedVarAttr(S, D, AL);
9864 break;
9865 case ParsedAttr::AT_NoSanitize:
9866 handleNoSanitizeAttr(S, D, AL);
9867 break;
9868 case ParsedAttr::AT_NoSanitizeSpecific:
9870 break;
9871 case ParsedAttr::AT_GuardedBy:
9872 handleGuardedByAttr(S, D, AL);
9873 break;
9874 case ParsedAttr::AT_PtGuardedBy:
9875 handlePtGuardedByAttr(S, D, AL);
9876 break;
9877 case ParsedAttr::AT_ExclusiveTrylockFunction:
9879 break;
9880 case ParsedAttr::AT_LockReturned:
9881 handleLockReturnedAttr(S, D, AL);
9882 break;
9883 case ParsedAttr::AT_LocksExcluded:
9884 handleLocksExcludedAttr(S, D, AL);
9885 break;
9886 case ParsedAttr::AT_SharedTrylockFunction:
9888 break;
9889 case ParsedAttr::AT_AcquiredBefore:
9890 handleAcquiredBeforeAttr(S, D, AL);
9891 break;
9892 case ParsedAttr::AT_AcquiredAfter:
9893 handleAcquiredAfterAttr(S, D, AL);
9894 break;
9895
9896 // Capability analysis attributes.
9897 case ParsedAttr::AT_Capability:
9898 case ParsedAttr::AT_Lockable:
9899 handleCapabilityAttr(S, D, AL);
9900 break;
9901 case ParsedAttr::AT_RequiresCapability:
9903 break;
9904
9905 case ParsedAttr::AT_AssertCapability:
9907 break;
9908 case ParsedAttr::AT_AcquireCapability:
9910 break;
9911 case ParsedAttr::AT_ReleaseCapability:
9913 break;
9914 case ParsedAttr::AT_TryAcquireCapability:
9916 break;
9917
9918 // Consumed analysis attributes.
9919 case ParsedAttr::AT_Consumable:
9920 handleConsumableAttr(S, D, AL);
9921 break;
9922 case ParsedAttr::AT_CallableWhen:
9923 handleCallableWhenAttr(S, D, AL);
9924 break;
9925 case ParsedAttr::AT_ParamTypestate:
9926 handleParamTypestateAttr(S, D, AL);
9927 break;
9928 case ParsedAttr::AT_ReturnTypestate:
9929 handleReturnTypestateAttr(S, D, AL);
9930 break;
9931 case ParsedAttr::AT_SetTypestate:
9932 handleSetTypestateAttr(S, D, AL);
9933 break;
9934 case ParsedAttr::AT_TestTypestate:
9935 handleTestTypestateAttr(S, D, AL);
9936 break;
9937
9938 // Type safety attributes.
9939 case ParsedAttr::AT_ArgumentWithTypeTag:
9941 break;
9942 case ParsedAttr::AT_TypeTagForDatatype:
9944 break;
9945
9946 // Swift attributes.
9947 case ParsedAttr::AT_SwiftAsyncName:
9948 handleSwiftAsyncName(S, D, AL);
9949 break;
9950 case ParsedAttr::AT_SwiftAttr:
9951 handleSwiftAttrAttr(S, D, AL);
9952 break;
9953 case ParsedAttr::AT_SwiftBridge:
9954 handleSwiftBridge(S, D, AL);
9955 break;
9956 case ParsedAttr::AT_SwiftError:
9957 handleSwiftError(S, D, AL);
9958 break;
9959 case ParsedAttr::AT_SwiftName:
9960 handleSwiftName(S, D, AL);
9961 break;
9962 case ParsedAttr::AT_SwiftNewType:
9963 handleSwiftNewType(S, D, AL);
9964 break;
9965 case ParsedAttr::AT_SwiftAsync:
9966 handleSwiftAsyncAttr(S, D, AL);
9967 break;
9968 case ParsedAttr::AT_SwiftAsyncError:
9969 handleSwiftAsyncError(S, D, AL);
9970 break;
9971
9972 // XRay attributes.
9973 case ParsedAttr::AT_XRayLogArgs:
9974 handleXRayLogArgsAttr(S, D, AL);
9975 break;
9976
9977 case ParsedAttr::AT_PatchableFunctionEntry:
9979 break;
9980
9981 case ParsedAttr::AT_AlwaysDestroy:
9982 case ParsedAttr::AT_NoDestroy:
9983 handleDestroyAttr(S, D, AL);
9984 break;
9985
9986 case ParsedAttr::AT_Uninitialized:
9987 handleUninitializedAttr(S, D, AL);
9988 break;
9989
9990 case ParsedAttr::AT_ObjCExternallyRetained:
9992 break;
9993
9994 case ParsedAttr::AT_MIGServerRoutine:
9996 break;
9997
9998 case ParsedAttr::AT_MSAllocator:
9999 handleMSAllocatorAttr(S, D, AL);
10000 break;
10001
10002 case ParsedAttr::AT_ArmBuiltinAlias:
10003 handleArmBuiltinAliasAttr(S, D, AL);
10004 break;
10005
10006 case ParsedAttr::AT_ArmLocallyStreaming:
10007 handleSimpleAttribute<ArmLocallyStreamingAttr>(S, D, AL);
10008 break;
10009
10010 case ParsedAttr::AT_ArmNew:
10011 handleArmNewAttr(S, D, AL);
10012 break;
10013
10014 case ParsedAttr::AT_AcquireHandle:
10015 handleAcquireHandleAttr(S, D, AL);
10016 break;
10017
10018 case ParsedAttr::AT_ReleaseHandle:
10019 handleHandleAttr<ReleaseHandleAttr>(S, D, AL);
10020 break;
10021
10022 case ParsedAttr::AT_UnsafeBufferUsage:
10023 handleUnsafeBufferUsage<UnsafeBufferUsageAttr>(S, D, AL);
10024 break;
10025
10026 case ParsedAttr::AT_UseHandle:
10027 handleHandleAttr<UseHandleAttr>(S, D, AL);
10028 break;
10029
10030 case ParsedAttr::AT_EnforceTCB:
10031 handleEnforceTCBAttr<EnforceTCBAttr, EnforceTCBLeafAttr>(S, D, AL);
10032 break;
10033
10034 case ParsedAttr::AT_EnforceTCBLeaf:
10035 handleEnforceTCBAttr<EnforceTCBLeafAttr, EnforceTCBAttr>(S, D, AL);
10036 break;
10037
10038 case ParsedAttr::AT_BuiltinAlias:
10039 handleBuiltinAliasAttr(S, D, AL);
10040 break;
10041
10042 case ParsedAttr::AT_PreferredType:
10043 handlePreferredTypeAttr(S, D, AL);
10044 break;
10045
10046 case ParsedAttr::AT_UsingIfExists:
10047 handleSimpleAttribute<UsingIfExistsAttr>(S, D, AL);
10048 break;
10049
10050 case ParsedAttr::AT_TypeNullable:
10051 handleNullableTypeAttr(S, D, AL);
10052 break;
10053 }
10054}
10055
10056/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
10057/// attribute list to the specified decl, ignoring any type attributes.
10059 Scope *S, Decl *D, const ParsedAttributesView &AttrList,
10060 const ProcessDeclAttributeOptions &Options) {
10061 if (AttrList.empty())
10062 return;
10063
10064 for (const ParsedAttr &AL : AttrList)
10065 ProcessDeclAttribute(*this, S, D, AL, Options);
10066
10067 // FIXME: We should be able to handle these cases in TableGen.
10068 // GCC accepts
10069 // static int a9 __attribute__((weakref));
10070 // but that looks really pointless. We reject it.
10071 if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
10072 Diag(AttrList.begin()->getLoc(), diag::err_attribute_weakref_without_alias)
10073 << cast<NamedDecl>(D);
10074 D->dropAttr<WeakRefAttr>();
10075 return;
10076 }
10077
10078 // FIXME: We should be able to handle this in TableGen as well. It would be
10079 // good to have a way to specify "these attributes must appear as a group",
10080 // for these. Additionally, it would be good to have a way to specify "these
10081 // attribute must never appear as a group" for attributes like cold and hot.
10082 if (!D->hasAttr<OpenCLKernelAttr>()) {
10083 // These attributes cannot be applied to a non-kernel function.
10084 if (const auto *A = D->getAttr<ReqdWorkGroupSizeAttr>()) {
10085 // FIXME: This emits a different error message than
10086 // diag::err_attribute_wrong_decl_type + ExpectedKernelFunction.
10087 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
10088 D->setInvalidDecl();
10089 } else if (const auto *A = D->getAttr<WorkGroupSizeHintAttr>()) {
10090 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
10091 D->setInvalidDecl();
10092 } else if (const auto *A = D->getAttr<VecTypeHintAttr>()) {
10093 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
10094 D->setInvalidDecl();
10095 } else if (const auto *A = D->getAttr<OpenCLIntelReqdSubGroupSizeAttr>()) {
10096 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
10097 D->setInvalidDecl();
10098 } else if (!D->hasAttr<CUDAGlobalAttr>()) {
10099 if (const auto *A = D->getAttr<AMDGPUFlatWorkGroupSizeAttr>()) {
10100 Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
10101 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
10102 D->setInvalidDecl();
10103 } else if (const auto *A = D->getAttr<AMDGPUWavesPerEUAttr>()) {
10104 Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
10105 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
10106 D->setInvalidDecl();
10107 } else if (const auto *A = D->getAttr<AMDGPUNumSGPRAttr>()) {
10108 Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
10109 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
10110 D->setInvalidDecl();
10111 } else if (const auto *A = D->getAttr<AMDGPUNumVGPRAttr>()) {
10112 Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
10113 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
10114 D->setInvalidDecl();
10115 }
10116 }
10117 }
10118
10119 // Do this check after processing D's attributes because the attribute
10120 // objc_method_family can change whether the given method is in the init
10121 // family, and it can be applied after objc_designated_initializer. This is a
10122 // bit of a hack, but we need it to be compatible with versions of clang that
10123 // processed the attribute list in the wrong order.
10124 if (D->hasAttr<ObjCDesignatedInitializerAttr>() &&
10125 cast<ObjCMethodDecl>(D)->getMethodFamily() != OMF_init) {
10126 Diag(D->getLocation(), diag::err_designated_init_attr_non_init);
10127 D->dropAttr<ObjCDesignatedInitializerAttr>();
10128 }
10129}
10130
10131// Helper for delayed processing TransparentUnion or BPFPreserveAccessIndexAttr
10132// attribute.
10134 const ParsedAttributesView &AttrList) {
10135 for (const ParsedAttr &AL : AttrList)
10136 if (AL.getKind() == ParsedAttr::AT_TransparentUnion) {
10137 handleTransparentUnionAttr(*this, D, AL);
10138 break;
10139 }
10140
10141 // For BPFPreserveAccessIndexAttr, we want to populate the attributes
10142 // to fields and inner records as well.
10143 if (D && D->hasAttr<BPFPreserveAccessIndexAttr>())
10144 handleBPFPreserveAIRecord(*this, cast<RecordDecl>(D));
10145}
10146
10147// Annotation attributes are the only attributes allowed after an access
10148// specifier.
10150 AccessSpecDecl *ASDecl, const ParsedAttributesView &AttrList) {
10151 for (const ParsedAttr &AL : AttrList) {
10152 if (AL.getKind() == ParsedAttr::AT_Annotate) {
10153 ProcessDeclAttribute(*this, nullptr, ASDecl, AL,
10155 } else {
10156 Diag(AL.getLoc(), diag::err_only_annotate_after_access_spec);
10157 return true;
10158 }
10159 }
10160 return false;
10161}
10162
10163/// checkUnusedDeclAttributes - Check a list of attributes to see if it
10164/// contains any decl attributes that we should warn about.
10166 for (const ParsedAttr &AL : A) {
10167 // Only warn if the attribute is an unignored, non-type attribute.
10168 if (AL.isUsedAsTypeAttr() || AL.isInvalid())
10169 continue;
10170 if (AL.getKind() == ParsedAttr::IgnoredAttribute)
10171 continue;
10172
10173 if (AL.getKind() == ParsedAttr::UnknownAttribute) {
10174 S.Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)
10175 << AL << AL.getRange();
10176 } else {
10177 S.Diag(AL.getLoc(), diag::warn_attribute_not_on_decl) << AL
10178 << AL.getRange();
10179 }
10180 }
10181}
10182
10183/// checkUnusedDeclAttributes - Given a declarator which is not being
10184/// used to build a declaration, complain about any decl attributes
10185/// which might be lying around on it.
10190 for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
10192}
10193
10194/// DeclClonePragmaWeak - clone existing decl (maybe definition),
10195/// \#pragma weak needs a non-definition decl and source may not have one.
10198 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
10199 NamedDecl *NewD = nullptr;
10200 if (auto *FD = dyn_cast<FunctionDecl>(ND)) {
10201 FunctionDecl *NewFD;
10202 // FIXME: Missing call to CheckFunctionDeclaration().
10203 // FIXME: Mangling?
10204 // FIXME: Is the qualifier info correct?
10205 // FIXME: Is the DeclContext correct?
10206 NewFD = FunctionDecl::Create(
10207 FD->getASTContext(), FD->getDeclContext(), Loc, Loc,
10209 getCurFPFeatures().isFPConstrained(), false /*isInlineSpecified*/,
10212 NewD = NewFD;
10213
10214 if (FD->getQualifier())
10215 NewFD->setQualifierInfo(FD->getQualifierLoc());
10216
10217 // Fake up parameter variables; they are declared as if this were
10218 // a typedef.
10219 QualType FDTy = FD->getType();
10220 if (const auto *FT = FDTy->getAs<FunctionProtoType>()) {
10222 for (const auto &AI : FT->param_types()) {
10223 ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, AI);
10224 Param->setScopeInfo(0, Params.size());
10225 Params.push_back(Param);
10226 }
10227 NewFD->setParams(Params);
10228 }
10229 } else if (auto *VD = dyn_cast<VarDecl>(ND)) {
10230 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
10231 VD->getInnerLocStart(), VD->getLocation(), II,
10232 VD->getType(), VD->getTypeSourceInfo(),
10233 VD->getStorageClass());
10234 if (VD->getQualifier())
10235 cast<VarDecl>(NewD)->setQualifierInfo(VD->getQualifierLoc());
10236 }
10237 return NewD;
10238}
10239
10240/// DeclApplyPragmaWeak - A declaration (maybe definition) needs \#pragma weak
10241/// applied to it, possibly with an alias.
10243 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
10244 IdentifierInfo *NDId = ND->getIdentifier();
10245 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
10246 NewD->addAttr(
10247 AliasAttr::CreateImplicit(Context, NDId->getName(), W.getLocation()));
10248 NewD->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));
10249 WeakTopLevelDecl.push_back(NewD);
10250 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
10251 // to insert Decl at TU scope, sorry.
10252 DeclContext *SavedContext = CurContext;
10256 PushOnScopeChains(NewD, S);
10257 CurContext = SavedContext;
10258 } else { // just add weak to existing
10259 ND->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));
10260 }
10261}
10262
10264 // It's valid to "forward-declare" #pragma weak, in which case we
10265 // have to do this.
10267 if (WeakUndeclaredIdentifiers.empty())
10268 return;
10269 NamedDecl *ND = nullptr;
10270 if (auto *VD = dyn_cast<VarDecl>(D))
10271 if (VD->isExternC())
10272 ND = VD;
10273 if (auto *FD = dyn_cast<FunctionDecl>(D))
10274 if (FD->isExternC())
10275 ND = FD;
10276 if (!ND)
10277 return;
10278 if (IdentifierInfo *Id = ND->getIdentifier()) {
10279 auto I = WeakUndeclaredIdentifiers.find(Id);
10280 if (I != WeakUndeclaredIdentifiers.end()) {
10281 auto &WeakInfos = I->second;
10282 for (const auto &W : WeakInfos)
10283 DeclApplyPragmaWeak(S, ND, W);
10284 std::remove_reference_t<decltype(WeakInfos)> EmptyWeakInfos;
10285 WeakInfos.swap(EmptyWeakInfos);
10286 }
10287 }
10288}
10289
10290/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
10291/// it, apply them to D. This is a bit tricky because PD can have attributes
10292/// specified in many different places, and we need to find and apply them all.
10294 // Ordering of attributes can be important, so we take care to process
10295 // attributes in the order in which they appeared in the source code.
10296
10297 // First, process attributes that appeared on the declaration itself (but
10298 // only if they don't have the legacy behavior of "sliding" to the DeclSepc).
10299 ParsedAttributesView NonSlidingAttrs;
10300 for (ParsedAttr &AL : PD.getDeclarationAttributes()) {
10301 if (AL.slidesFromDeclToDeclSpecLegacyBehavior()) {
10302 // Skip processing the attribute, but do check if it appertains to the
10303 // declaration. This is needed for the `MatrixType` attribute, which,
10304 // despite being a type attribute, defines a `SubjectList` that only
10305 // allows it to be used on typedef declarations.
10306 AL.diagnoseAppertainsTo(*this, D);
10307 } else {
10308 NonSlidingAttrs.addAtEnd(&AL);
10309 }
10310 }
10311 ProcessDeclAttributeList(S, D, NonSlidingAttrs);
10312
10313 // Apply decl attributes from the DeclSpec if present.
10314 if (!PD.getDeclSpec().getAttributes().empty()) {
10317 .WithIncludeCXX11Attributes(false)
10318 .WithIgnoreTypeAttributes(true));
10319 }
10320
10321 // Walk the declarator structure, applying decl attributes that were in a type
10322 // position to the decl itself. This handles cases like:
10323 // int *__attr__(x)** D;
10324 // when X is a decl attribute.
10325 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) {
10328 .WithIncludeCXX11Attributes(false)
10329 .WithIgnoreTypeAttributes(true));
10330 }
10331
10332 // Finally, apply any attributes on the decl itself.
10334
10335 // Apply additional attributes specified by '#pragma clang attribute'.
10336 AddPragmaAttributes(S, D);
10337
10338 // Look for API notes that map to attributes.
10339 ProcessAPINotes(D);
10340}
10341
10342/// Is the given declaration allowed to use a forbidden type?
10343/// If so, it'll still be annotated with an attribute that makes it
10344/// illegal to actually use.
10346 const DelayedDiagnostic &diag,
10347 UnavailableAttr::ImplicitReason &reason) {
10348 // Private ivars are always okay. Unfortunately, people don't
10349 // always properly make their ivars private, even in system headers.
10350 // Plus we need to make fields okay, too.
10351 if (!isa<FieldDecl>(D) && !isa<ObjCPropertyDecl>(D) &&
10352 !isa<FunctionDecl>(D))
10353 return false;
10354
10355 // Silently accept unsupported uses of __weak in both user and system
10356 // declarations when it's been disabled, for ease of integration with
10357 // -fno-objc-arc files. We do have to take some care against attempts
10358 // to define such things; for now, we've only done that for ivars
10359 // and properties.
10360 if ((isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D))) {
10361 if (diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_disabled ||
10362 diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_no_runtime) {
10363 reason = UnavailableAttr::IR_ForbiddenWeak;
10364 return true;
10365 }
10366 }
10367
10368 // Allow all sorts of things in system headers.
10370 // Currently, all the failures dealt with this way are due to ARC
10371 // restrictions.
10372 reason = UnavailableAttr::IR_ARCForbiddenType;
10373 return true;
10374 }
10375
10376 return false;
10377}
10378
10379/// Handle a delayed forbidden-type diagnostic.
10381 Decl *D) {
10382 auto Reason = UnavailableAttr::IR_None;
10383 if (D && isForbiddenTypeAllowed(S, D, DD, Reason)) {
10384 assert(Reason && "didn't set reason?");
10385 D->addAttr(UnavailableAttr::CreateImplicit(S.Context, "", Reason, DD.Loc));
10386 return;
10387 }
10388 if (S.getLangOpts().ObjCAutoRefCount)
10389 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
10390 // FIXME: we may want to suppress diagnostics for all
10391 // kind of forbidden type messages on unavailable functions.
10392 if (FD->hasAttr<UnavailableAttr>() &&
10394 diag::err_arc_array_param_no_ownership) {
10395 DD.Triggered = true;
10396 return;
10397 }
10398 }
10399
10402 DD.Triggered = true;
10403}
10404
10405
10410
10411 // When delaying diagnostics to run in the context of a parsed
10412 // declaration, we only want to actually emit anything if parsing
10413 // succeeds.
10414 if (!decl) return;
10415
10416 // We emit all the active diagnostics in this pool or any of its
10417 // parents. In general, we'll get one pool for the decl spec
10418 // and a child pool for each declarator; in a decl group like:
10419 // deprecated_typedef foo, *bar, baz();
10420 // only the declarator pops will be passed decls. This is correct;
10421 // we really do need to consider delayed diagnostics from the decl spec
10422 // for each of the different declarations.
10423 const DelayedDiagnosticPool *pool = &poppedPool;
10424 do {
10425 bool AnyAccessFailures = false;
10427 i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) {
10428 // This const_cast is a bit lame. Really, Triggered should be mutable.
10429 DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i);
10430 if (diag.Triggered)
10431 continue;
10432
10433 switch (diag.Kind) {
10435 // Don't bother giving deprecation/unavailable diagnostics if
10436 // the decl is invalid.
10437 if (!decl->isInvalidDecl())
10439 break;
10440
10442 // Only produce one access control diagnostic for a structured binding
10443 // declaration: we don't need to tell the user that all the fields are
10444 // inaccessible one at a time.
10445 if (AnyAccessFailures && isa<DecompositionDecl>(decl))
10446 continue;
10448 if (diag.Triggered)
10449 AnyAccessFailures = true;
10450 break;
10451
10453 handleDelayedForbiddenType(*this, diag, decl);
10454 break;
10455 }
10456 }
10457 } while ((pool = pool->getParent()));
10458}
10459
10460/// Given a set of delayed diagnostics, re-emit them as if they had
10461/// been delayed in the current context instead of in the given pool.
10462/// Essentially, this just moves them to the current pool.
10465 assert(curPool && "re-emitting in undelayed context not supported");
10466 curPool->steal(pool);
10467}
Defines the clang::ASTContext interface.
#define V(N, I)
Definition: ASTContext.h:3285
NodeId Parent
Definition: ASTDiff.cpp:191
int Id
Definition: ASTDiff.cpp:190
static SmallString< 64 > normalizeName(const IdentifierInfo *Name, const IdentifierInfo *Scope, AttributeCommonInfo::Syntax SyntaxUsed)
Definition: Attributes.cpp:127
#define SM(sm)
Definition: Cuda.cpp:83
static CudaArch getCudaArch(CodeGenModule &CGM)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the classes clang::DelayedDiagnostic and clang::AccessedEntity.
Defines the clang::Expr interface and subclasses for C++ expressions.
int Priority
Definition: Format.cpp:2979
Defines helper utilities for supporting the HLSL runtime environment.
#define X(type, name)
Definition: Value.h:143
Defines the clang::LangOptions interface.
llvm::MachO::Target Target
Definition: MachO.h:50
llvm::MachO::Record Record
Definition: MachO.h:31
static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y)
Check whether the two versions match.
Definition: ObjCMT.cpp:1068
static unsigned getNumAttributeArgs(const ParsedAttr &AL)
Definition: ParsedAttr.cpp:282
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file declares semantic analysis for CUDA constructs.
static bool isCFStringType(QualType T, ASTContext &Ctx)
static void handleObjCBoxable(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleBPFPreserveAccessIndexAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleWeakImportAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleHLSLShaderAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkGuardedByAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL, Expr *&Arg)
static void handleCodeSegAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handlePatchableFunctionEntryAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleCountedByAttrField(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAMDGPUNumVGPRAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleOpenCLAccessAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleFormatAttr(Sema &S, Decl *D, const ParsedAttr &AL)
Handle attribute((format(type,idx,firstarg))) attributes based on http://gcc.gnu.org/onlinedocs/gcc/F...
static bool CheckCountedByAttrOnField(Sema &S, FieldDecl *FD, Expr *E, llvm::SmallVectorImpl< TypeCoupledDeclRefInfo > &Decls)
static void handleUninitializedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool isNSStringType(QualType T, ASTContext &Ctx, bool AllowNSAttributedString=false)
static void handleRequiresCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleBTFDeclTagAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleOptimizeNoneAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleEnableIfAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool isFunctionOrMethodVariadic(const Decl *D)
static void handleSwiftError(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleStandardNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &A)
static void handleMIGServerRoutineAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleZeroCallUsedRegsAttr(Sema &S, Decl *D, const ParsedAttr &AL)
CountedByInvalidPointeeTypeKind
static const RecordDecl * GetEnclosingNamedOrTopAnonRecord(const FieldDecl *FD)
static void handleDiagnoseAsBuiltinAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleEnumExtensibilityAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static T * mergeVisibilityAttr(Sema &S, Decl *D, const AttributeCommonInfo &CI, typename T::VisibilityType value)
static void handleLayoutVersion(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAMDGPUWavesPerEUAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD, const ParsedAttr &AL)
static void handleDLLAttr(Sema &S, Decl *D, const ParsedAttr &A)
static void handleConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAlignValueAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleHLSLSV_DispatchThreadIDAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleSubGroupSize(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleNoCfCheckAttr(Sema &S, Decl *D, const ParsedAttr &Attrs)
static void handleArmBuiltinAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleCmseNSEntryAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleOpenCLNoSVMAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleReturnsNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void checkUnusedDeclAttributes(Sema &S, const ParsedAttributesView &A)
checkUnusedDeclAttributes - Check a list of attributes to see if it contains any decl attributes that...
static void handleGNUInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkArmNewAttrMutualExclusion(Sema &S, const ParsedAttr &AL, const FunctionProtoType *FPT, FunctionType::ArmStateValue CurrentState, StringRef StateName)
static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleBuiltinAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool isErrorParameter(Sema &S, QualType QT)
static void handleEnforceTCBAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D, const ParsedAttr &AL, SmallVectorImpl< Expr * > &Args, unsigned Sidx=0, bool ParamIdxOk=false)
Checks that all attribute arguments, starting from Sidx, resolve to a capability object.
static QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx)
static bool isLegalTypeForHLSLSV_DispatchThreadID(QualType T)
static void handleSwiftNewType(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleObjCIndependentClass(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleXReturnsXRetainedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleErrorAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkCodeSegName(Sema &S, SourceLocation LiteralLoc, StringRef CodeSegName)
static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleSwiftAsyncName(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleTryAcquireCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleRISCVInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleSetTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleFormatArgAttr(Sema &S, Decl *D, const ParsedAttr &AL)
Handle attribute((format_arg((idx)))) attribute based on http://gcc.gnu.org/onlinedocs/gcc/Function-A...
static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, const Sema::ProcessDeclAttributeOptions &Options)
ProcessDeclAttribute - Apply the specific attribute to the specified decl if the attribute applies to...
static void handleTargetAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleObjCOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static const Sema::SemaDiagnosticBuilder & appendDiagnostics(const Sema::SemaDiagnosticBuilder &Bldr)
static void handlePassObjectSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static const ParmVarDecl * getFunctionOrMethodParam(const Decl *D, unsigned Idx)
static bool ArmCdeAliasValid(unsigned BuiltinID, StringRef AliasName)
static void handleAMDGPUMaxNumWorkGroupsAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleNoMergeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleArmNewAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkUInt32Argument(Sema &S, const AttrInfo &AI, const Expr *Expr, uint32_t &Val, unsigned Idx=UINT_MAX, bool StrictlyUnsigned=false)
If Expr is a valid integer constant, get the value of the integer expression and return success or fa...
static void handleAnyX86InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleObjCDirectMembersAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleManagedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleSwiftAttrAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAVRInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleSwiftAsyncAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleParamTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleUnsafeBufferUsage(Sema &S, Decl *D, const ParsedAttr &AL)
static bool isValidSubjectOfNSReturnsRetainedAttribute(QualType QT)
static bool attrNonNullArgCheck(Sema &S, QualType T, const ParsedAttr &AL, SourceRange AttrParmRange, SourceRange TypeRange, bool isReturnValue=false)
static void handleAcquireCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static std::enable_if_t< std::is_base_of_v< Attr, AttrInfo >, SourceLocation > getAttrLoc(const AttrInfo &AL)
A helper function to provide Attribute Location for the Attr types AND the ParsedAttr.
static void handleCPUSpecificAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleObjCRuntimeName(Sema &S, Decl *D, const ParsedAttr &AL)
static void handlePackedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleIFuncAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkFunctionOrMethodParameterIndex(Sema &S, const Decl *D, const AttrInfo &AI, unsigned AttrArgNum, const Expr *IdxExpr, ParamIdx &Idx, bool CanIndexImplicitThis=false)
Check if IdxExpr is a valid parameter index for a function or instance method D.
static void handleAbiTagAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool isFunctionOrMethod(const Decl *D)
isFunctionOrMethod - Return true if the given decl has function type (function or function-typed vari...
static void handleObjCMethodFamilyAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAttrWithMessage(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleWeakRefAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleExtVectorTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleX86ForceAlignArgPointerAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleCalledOnceAttr(Sema &S, Decl *D, const ParsedAttr &AL)
Handle 'called_once' attribute.
static void handleLockReturnedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkFunctionConditionAttr(Sema &S, Decl *D, const ParsedAttr &AL, Expr *&Cond, StringRef &Msg)
static void handleAcquiredAfterAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleExternalSourceSymbolAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleNonNullAttrParameter(Sema &S, ParmVarDecl *D, const ParsedAttr &AL)
static bool checkParamIsIntegerType(Sema &S, const Decl *D, const AttrInfo &AI, unsigned AttrArgNo)
Checks to be sure that the given parameter number is in bounds, and is an integral type.
static void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D, const ParsedAttr &Attrs)
static bool checkRecordTypeForCapability(Sema &S, QualType Ty)
static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkIBOutletCommon(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL, SmallVectorImpl< Expr * > &Args)
static void handleWebAssemblyImportModuleAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleLocksExcludedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleMSAllocatorAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static AttrTy * mergeEnforceTCBAttrImpl(Sema &S, Decl *D, const AttrTy &AL)
static bool isValidSubjectOfOSAttribute(QualType QT)
static bool hasDeclarator(const Decl *D)
Return true if the given decl has a declarator that should have been processed by Sema::GetTypeForDec...
static bool ArmMveAliasValid(unsigned BuiltinID, StringRef AliasName)
static void handleConstructorAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAllocSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleConsumableAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static const RecordType * getRecordType(QualType QT)
Checks that the passed in QualType either is of RecordType or points to RecordType.
static void handleObjCExternallyRetainedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleNoSanitizeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleReturnTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool isValidSubjectOfNSAttribute(QualType QT)
static void handleTargetClonesAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAllocAlignAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleM68kInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleIBOutlet(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleHLSLResourceBindingAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleObjCSuppresProtocolAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkAMDGPUFlatWorkGroupSizeArguments(Sema &S, Expr *MinExpr, Expr *MaxExpr, const AMDGPUFlatWorkGroupSizeAttr &Attr)
static void handleSwiftBridge(Sema &S, Decl *D, const ParsedAttr &AL)
FormatAttrKind
@ CFStringFormat
@ IgnoredFormat
@ InvalidFormat
@ StrftimeFormat
@ SupportedFormat
@ NSStringFormat
static void handleBPFPreserveAIRecord(Sema &S, RecordDecl *RD)
static bool isFunctionOrMethodOrBlock(const Decl *D)
Return true if the given decl has function type (function or function-typed variable) or an Objective...
static void handlePreferredTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool isValidSubjectOfCFAttribute(QualType QT)
static void checkOMPAssumeAttr(Sema &S, SourceLocation Loc, StringRef AssumptionStr)
Check if AssumptionStr is a known assumption and warn if not.
static void handleDeviceAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleHLSLPackOffsetAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handlePtGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAlwaysInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAssertCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleVisibilityAttr(Sema &S, Decl *D, const ParsedAttr &AL, bool isTypeVisibility)
static void handleAnnotateAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static FormatAttrKind getFormatAttrKind(StringRef Format)
getFormatAttrKind - Map from format attribute names to supported format types.
static void handleNullableTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleUuidAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAcquireHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool isValidSwiftIndirectResultType(QualType Ty)
Pointers and references in the default address space.
static void handleWebAssemblyImportNameAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool tryMakeVariablePseudoStrong(Sema &S, VarDecl *VD, bool DiagnoseFailure)
static void handleMSConstexprAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void checkSwiftAsyncErrorBlock(Sema &S, Decl *D, const SwiftAsyncErrorAttr *ErrorAttr, const SwiftAsyncAttr *AsyncAttr)
static void handleCommonAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleTestTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkTryLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL, SmallVectorImpl< Expr * > &Args)
static bool ArmBuiltinAliasValid(unsigned BuiltinID, StringRef AliasName, ArrayRef< IntrinToName > Map, const char *IntrinNames)
static void parseModeAttrArg(Sema &S, StringRef Str, unsigned &DestWidth, bool &IntegerMode, bool &ComplexMode, FloatModeKind &ExplicitType)
parseModeAttrArg - Parses attribute mode string and returns parsed type attribute.
static void handleSimpleAttribute(Sema &S, Decl *D, const AttributeCommonInfo &CI)
Applies the given attribute to the Decl without performing any additional semantic checking.
static void handleExcludeFromExplicitInstantiationAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleHLSLNumThreadsAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleSharedTrylockFunctionAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleLaunchBoundsAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkAvailabilityAttr(Sema &S, SourceRange Range, IdentifierInfo *Platform, VersionTuple Introduced, VersionTuple Deprecated, VersionTuple Obsoleted)
static void handleObjCBridgeMutableAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D, const ParsedAttr &AL)
static void handleARMInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleNoBuiltinAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleLifetimeCategoryAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleNoUniqueAddressAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool validateAlignasAppliedType(Sema &S, Decl *D, const AlignedAttr &Attr, SourceLocation AttrLoc)
Perform checking of type validity.
static void handleNakedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleFunctionReturnThunksAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleDeprecatedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static SourceRange getFunctionOrMethodResultSourceRange(const Decl *D)
static Sema::RetainOwnershipKind parsedAttrToRetainOwnershipKind(const ParsedAttr &AL)
static unsigned getNumAttributeArgs(const ParsedAttr &AL)
static void handleGlobalAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleSentinelAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleCodeModelAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleHLSLParamModifierAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleCallableWhenAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool hasBTFDeclTagAttr(Decl *D, StringRef Tag)
static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &DD, Decl *D)
Handle a delayed forbidden-type diagnostic.
static void handleAssertSharedLockAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL, SmallVectorImpl< Expr * > &Args)
static bool RISCVAliasValid(unsigned BuiltinID, StringRef AliasName)
static void handleAssumeAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleSharedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleMSInheritanceAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkAMDGPUMaxNumWorkGroupsArguments(Sema &S, Expr *XExpr, Expr *YExpr, Expr *ZExpr, const AMDGPUMaxNumWorkGroupsAttr &Attr)
static void handleVecTypeHint(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleRestrictAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleMinVectorWidthAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleUnusedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static Expr * makeLaunchBoundsArgExpr(Sema &S, Expr *E, const CUDALaunchBoundsAttr &AL, const unsigned Idx)
static bool ArmSmeAliasValid(ASTContext &Context, unsigned BuiltinID, StringRef AliasName)
static void handleMipsInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleDeclspecThreadAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleSYCLKernelAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAMDGPUNumSGPRAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool ArmSveAliasValid(ASTContext &Context, unsigned BuiltinID, StringRef AliasName)
static void handleInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL)
Handle attribute((callback(CalleeIdx, PayloadIdx0, ...))) attributes.
static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL)
Handle attribute((init_priority(priority))) attributes based on http://gcc.gnu.org/onlinedocs/gcc/C_0...
static void handlePtGuardedVarAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool hasFunctionProto(const Decl *D)
hasFunctionProto - Return true if the given decl has a argument information.
static bool checkRecordDeclForAttr(const RecordDecl *RD)
static void handleDestroyAttr(Sema &S, Decl *D, const ParsedAttr &A)
static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static unsigned getFunctionOrMethodNumParams(const Decl *D)
getFunctionOrMethodNumParams - Return number of function or method parameters.
static void handleRandomizeLayoutAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void markUsedForAliasOrIfunc(Sema &S, Decl *D, const ParsedAttr &AL, StringRef Str)
static bool isCapabilityExpr(Sema &S, const Expr *Ex)
static bool isValidOSObjectOutParameter(const Decl *D)
static bool isValidSwiftContextType(QualType Ty)
Pointer-like types in the default address space.
static void handleNoDebugAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleSuppressAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleSwiftName(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleObjCRequiresSuperAttr(Sema &S, Decl *D, const ParsedAttr &Attrs)
static void handleObjCDesignatedInitializer(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &Attrs)
static const AttrTy * findEnforceTCBAttrByName(Decl *D, StringRef Name)
static void handleWebAssemblyExportNameAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleNoEscapeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAvailableOnlyInDefaultEvalMethod(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL)
Diagnose mutually exclusive attributes when present on a given declaration.
static bool MustDelayAttributeArguments(const ParsedAttr &AL)
static void handleNoRandomizeLayoutAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool isInstanceMethod(const Decl *D)
static void handleTargetVersionAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static SourceRange getFunctionOrMethodParamRange(const Decl *D, unsigned Idx)
static void handleAVRSignalAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static QualType getFunctionOrMethodResultType(const Decl *D)
static void handleWarnUnusedResult(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleBlocksAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAssertExclusiveLockAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool isIntOrBool(Expr *Exp)
Check if the passed-in expression is of type int or bool.
static void handleSimpleAttributeOrDiagnose(Sema &S, Decl *D, const AttributeCommonInfo &CI, bool PassesCheck, unsigned DiagID, DiagnosticArgs &&... ExtraArgs)
Add an attribute AttrType to declaration D, provided that PassesCheck is true.
static bool isSanitizerAttributeAllowedOnGlobals(StringRef Sanitizer)
static void handleObjCBridgeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleObjCBridgeRelatedAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool isValidSwiftErrorResultType(QualType Ty)
Pointers and references to pointers in the default address space.
static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkAMDGPUWavesPerEUArguments(Sema &S, Expr *MinExpr, Expr *MaxExpr, const AMDGPUWavesPerEUAttr &Attr)
static void handleMinSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool validateSwiftFunctionName(Sema &S, const ParsedAttr &AL, SourceLocation Loc, StringRef Name, unsigned &SwiftParamCount, bool &IsSingleParamInit)
static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkTypedefTypeForCapability(QualType Ty)
static void handleAcquiredBeforeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleReleaseCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleMSP430InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool typeHasCapability(Sema &S, QualType Ty)
static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleIBOutletCollection(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleObjCNSObject(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleObjCDirectAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleNSErrorDomain(Sema &S, Decl *D, const ParsedAttr &Attr)
static bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType *RT)
static bool isFunctionLike(const Type &T)
static void handleOMPAssumeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleDiagnoseIfAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleCFGuardAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D, const ParsedAttr &AL)
Check if passed in Decl is a pointer type.
static bool isForbiddenTypeAllowed(Sema &S, Decl *D, const DelayedDiagnostic &diag, UnavailableAttr::ImplicitReason &reason)
Is the given declaration allowed to use a forbidden type? If so, it'll still be annotated with an att...
static void handleInternalLinkageAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAMDGPUFlatWorkGroupSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleModeAttr(Sema &S, Decl *D, const ParsedAttr &AL)
handleModeAttr - This attribute modifies the width of a decl with primitive type.
static void handleDestructorAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handlePreferredName(Sema &S, Decl *D, const ParsedAttr &AL)
static bool checkPositiveIntArgument(Sema &S, const AttrInfo &AI, const Expr *Expr, int &Val, unsigned Idx=UINT_MAX)
Wrapper around checkUInt32Argument, with an extra check to be sure that the result will fit into a re...
static void handleNoSanitizeSpecificAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleVecReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static bool isGlobalVar(const Decl *D)
static void handleSwiftAsyncError(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleTLSModelAttr(Sema &S, Decl *D, const ParsedAttr &AL)
static void handleAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL)
This file declares semantic analysis for HLSL constructs.
SourceRange Range
Definition: SemaObjC.cpp:754
SourceLocation Loc
Definition: SemaObjC.cpp:755
This file declares semantic analysis for Objective-C.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Enumerates target-specific builtins in their own namespaces within namespace clang.
C Language Family Type Representation.
__device__ int
virtual void AssignInheritanceModel(CXXRecordDecl *RD)
Callback invoked when an MSInheritanceAttr has been attached to a CXXRecordDecl.
Definition: ASTConsumer.h:112
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
MSGuidDecl * getMSGuidDecl(MSGuidDeclParts Parts) const
Return a declaration for the global GUID object representing the given GUID value.
SourceManager & getSourceManager()
Definition: ASTContext.h:705
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:1073
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
TypedefDecl * getObjCInstanceTypeDecl()
Retrieve the typedef declaration corresponding to the Objective-C "instancetype" type.
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl.
DeclarationNameTable DeclarationNames
Definition: ASTContext.h:648
MangleContext * createMangleContext(const TargetInfo *T=nullptr)
If T is null pointer, assume the target in ASTContext.
QualType getRealTypeForBitwidth(unsigned DestWidth, FloatModeKind ExplicitType) const
getRealTypeForBitwidth - sets floating point QualTy according to specified bitwidth.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2591
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
CallingConv getDefaultCallingConvention(bool IsVariadic, bool IsCXXMethod, bool IsBuiltin=false) const
Retrieves the default calling convention for the current target.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
IdentifierTable & Idents
Definition: ASTContext.h:644
Builtin::Context & BuiltinInfo
Definition: ASTContext.h:646
const LangOptions & getLangOpts() const
Definition: ASTContext.h:775
QualType getConstType(QualType T) const
Return the uniqued reference to the type for a const qualified type.
Definition: ASTContext.h:1299
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...
const TargetInfo * getAuxTargetInfo() const
Definition: ASTContext.h:758
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
CanQualType IntTy
Definition: ASTContext.h:1100
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
CanQualType OverloadTy
Definition: ASTContext.h:1119
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:2341
CanQualType VoidTy
Definition: ASTContext.h:1091
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:757
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
Definition: ASTContext.cpp:818
unsigned getTypeAlign(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in bits.
Definition: ASTContext.h:2372
uint64_t getCharWidth() const
Return the size of the character type, in bits.
Definition: ASTContext.h:2345
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
Represents an access specifier followed by colon ':'.
Definition: DeclCXX.h:86
PtrTy get() const
Definition: Ownership.h:170
bool isInvalid() const
Definition: Ownership.h:166
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:3519
QualType getElementType() const
Definition: Type.h:3531
Attr - This represents one attribute.
Definition: Attr.h:42
SourceLocation getLocation() const
Definition: Attr.h:95
void setAttributeSpellingListIndex(unsigned V)
std::string getNormalizedFullName() const
Gets the normalized full name, which consists of both scope and name and with surrounding underscores...
Definition: Attributes.cpp:151
unsigned getAttributeSpellingListIndex() const
const IdentifierInfo * getScopeName() const
SourceLocation getLoc() const
const IdentifierInfo * getAttrName() const
bool isStandardAttributeSyntax() const
The attribute is spelled [[]] in either C or C++ mode, including standard attributes spelled with a k...
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Definition: Type.h:5982
Pointer to a block type.
Definition: Type.h:3350
This class is used for builtin types like 'int'.
Definition: Type.h:2982
bool isAuxBuiltinID(unsigned ID) const
Return true if builtin ID belongs to AuxTarget.
Definition: Builtins.h:262
static bool isBuiltinFunc(llvm::StringRef Name)
Returns true if this is a libc/libm function without the '__builtin_' prefix.
Definition: Builtins.cpp:63
unsigned getAuxBuiltinID(unsigned ID) const
Return real builtin ID (i.e.
Definition: Builtins.h:268
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2060
QualType getFunctionObjectParameterType() const
Definition: DeclCXX.h:2210
static bool isStaticOverloadedOperator(OverloadedOperatorKind OOK)
Returns true if the given operator is implicitly static in a record context.
Definition: DeclCXX.h:2102
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
CXXRecordDecl * getDefinition() const
Definition: DeclCXX.h:564
bool hasDefinition() const
Definition: DeclCXX.h:571
MSInheritanceModel calculateInheritanceModel() const
Calculate what the inheritance model would be for this class.
Represents the this expression in C++.
Definition: ExprCXX.h:1148
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2820
static CallExpr * Create(const ASTContext &Ctx, Expr *Fn, ArrayRef< Expr * > Args, QualType Ty, ExprValueKind VK, SourceLocation RParenLoc, FPOptionsOverride FPFeatures, unsigned MinNumArgs=0, ADLCallKind UsesADL=NotADL)
Create a call expression.
Definition: Expr.cpp:1494
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition: CharUnits.h:185
Declaration of a class template.
const RelatedTargetVersionMapping * getVersionMapping(OSEnvPair Kind) const
The results of name lookup within a DeclContext.
Definition: DeclBase.h:1369
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
Definition: DeclBase.h:2342
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1436
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2066
bool isFileContext() const
Definition: DeclBase.h:2137
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
Definition: DeclBase.cpp:1922
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition: DeclBase.h:2322
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
Definition: DeclBase.cpp:1317
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1260
DeclarationNameInfo getNameInfo() const
Definition: Expr.h:1332
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
Definition: Expr.cpp:488
bool hasQualifier() const
Determine whether this declaration reference was preceded by a C++ nested-name-specifier,...
Definition: Expr.h:1343
ValueDecl * getDecl()
Definition: Expr.h:1328
ParsedAttributes & getAttributes()
Definition: DeclSpec.h:870
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
T * getAttr() const
Definition: DeclBase.h:579
bool hasAttrs() const
Definition: DeclBase.h:524
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:501
void addAttr(Attr *A)
Definition: DeclBase.cpp:975
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Definition: DeclBase.cpp:132
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible.
Definition: DeclBase.cpp:1116
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Definition: DeclBase.cpp:227
bool canBeWeakImported(bool &IsDefinition) const
Determines whether this symbol can be weak-imported, e.g., whether it would be well-formed to add the...
Definition: DeclBase.cpp:775
bool isInvalidDecl() const
Definition: DeclBase.h:594
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
Definition: DeclBase.h:565
SourceLocation getLocation() const
Definition: DeclBase.h:445
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Definition: DeclBase.h:1039
DeclContext * getDeclContext()
Definition: DeclBase.h:454
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclBase.h:437
void dropAttr()
Definition: DeclBase.h:562
AttrVec & getAttrs()
Definition: DeclBase.h:530
static bool isFlexibleArrayMemberLike(ASTContext &Context, const Decl *D, QualType Ty, LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel, bool IgnoreTemplateOrMacroSubstitution)
Whether it resembles a flexible array member.
Definition: DeclBase.cpp:413
void setDeclContext(DeclContext *DC)
setDeclContext - Set both the semantic and lexical DeclContext to DC.
Definition: DeclBase.cpp:336
bool hasAttr() const
Definition: DeclBase.h:583
void setLexicalDeclContext(DeclContext *DC)
Definition: DeclBase.cpp:340
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:968
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition: DeclBase.h:433
DeclarationName getCXXOperatorName(OverloadedOperatorKind Op)
Get the name of the overloadable C++ operator corresponding to Op.
The name of a declaration.
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...
Definition: Decl.h:828
SourceLocation getTypeSpecStartLoc() const
Definition: Decl.cpp:1985
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Decl.h:822
void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc)
Definition: Decl.cpp:1997
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
Definition: Decl.h:836
Expr * getTrailingRequiresClause()
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
Definition: Decl.h:846
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:799
Information about one declarator, including the parsed type information and the identifier.
Definition: DeclSpec.h:1900
const DeclaratorChunk & getTypeObject(unsigned i) const
Return the specified TypeInfo from this declarator.
Definition: DeclSpec.h:2398
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
Definition: DeclSpec.h:2047
const ParsedAttributes & getAttributes() const
Definition: DeclSpec.h:2683
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
Definition: DeclSpec.h:2394
const ParsedAttributesView & getDeclarationAttributes() const
Definition: DeclSpec.h:2686
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Definition: Type.h:5576
This represents one expression.
Definition: Expr.h:110
static bool isPotentialConstantExprUnevaluated(Expr *E, const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExprUnevaluated - Return true if this expression might be usable in a constant exp...
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Definition: Expr.cpp:3064
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition: Expr.h:175
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition: Expr.h:192
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
Definition: Expr.h:239
bool isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition: Expr.cpp:277
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
QualType getType() const
Definition: Expr.h:142
Represents difference between two FPOptions values.
Definition: LangOptions.h:915
Represents a member of a struct/union/class.
Definition: Decl.h:3057
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:4666
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Definition: Decl.h:3270
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
Definition: Diagnostic.h:71
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
Definition: Diagnostic.h:134
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
Definition: Diagnostic.h:97
Represents a function declaration or definition.
Definition: Decl.h:1971
const ParmVarDecl * getParamDecl(unsigned i) const
Definition: Decl.h:2706
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
Definition: Decl.cpp:4054
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition: Decl.cpp:4042
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition: Decl.h:2283
SourceRange getReturnTypeSourceRange() const
Attempt to compute an informative source range covering the function return type.
Definition: Decl.cpp:3873
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition: Decl.cpp:3632
param_iterator param_end()
Definition: Decl.h:2696
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
Definition: Decl.h:2830
void setIsMultiVersion(bool V=true)
Sets the multiversion state for this declaration and all of its redeclarations.
Definition: Decl.h:2605
QualType getReturnType() const
Definition: Decl.h:2754
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2683
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
Definition: Decl.h:2405
param_iterator param_begin()
Definition: Decl.h:2695
bool isVariadic() const
Whether this function is variadic.
Definition: Decl.cpp:3089
bool isConstexprSpecified() const
Definition: Decl.h:2441
bool isExternC() const
Determines whether this function is a function with external, C linkage.
Definition: Decl.cpp:3492
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, Expr *TrailingRequiresClause=nullptr)
Definition: Decl.h:2160
bool isConsteval() const
Definition: Decl.h:2444
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition: Decl.cpp:3692
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
Definition: Decl.cpp:3156
bool isInlineSpecified() const
Determine whether the "inline" keyword was specified for this function.
Definition: Decl.h:2808
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4657
QualType desugar() const
Definition: Type.h:5124
Declaration of a template function.
Definition: DeclTemplate.h:957
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:4257
static ArmStateValue getArmZT0State(unsigned AttrBits)
Definition: Type.h:4544
static ArmStateValue getArmZAState(unsigned AttrBits)
Definition: Type.h:4540
QualType getReturnType() const
Definition: Type.h:4574
GlobalDecl - represents a global declaration.
Definition: GlobalDecl.h:56
One of these records is kept for each identifier that is lexed.
unsigned getBuiltinID() const
Return a value indicating whether this is a builtin function.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Describes an entity that is being initialized.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
@ IncompleteOnly
Any trailing array member of undefined size is a FAM.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:461
bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const
Definition: LangOptions.h:625
clang::ObjCRuntime ObjCRuntime
Definition: LangOptions.h:496
std::string getOpenCLVersionString() const
Return the OpenCL C or C++ for OpenCL language name and version as a string.
Definition: LangOptions.cpp:79
unsigned getOpenCLCompatibleVersion() const
Return the OpenCL version that kernel language is compatible with.
Definition: LangOptions.cpp:63
void push_back(const T &LocalValue)
Represents the results of name lookup.
Definition: Lookup.h:46
A global _GUID constant.
Definition: DeclCXX.h:4289
Describes a module or submodule.
Definition: Module.h:105
This represents a decl that may have a name.
Definition: Decl.h:249
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:270
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.
Definition: Decl.cpp:1959
bool isExternallyVisible() const
Definition: Decl.h:408
A C++ nested-name-specifier augmented with source location information.
Represents an ObjC class declaration.
Definition: DeclObjC.h:1153
void setHasDesignatedInitializers()
Indicate that this interface decl contains at least one initializer marked with the 'objc_designated_...
Definition: DeclObjC.cpp:1595
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:140
Represents a pointer to an Objective C object.
Definition: Type.h:7009
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:730
bool allowsDirectDispatch() const
Does this runtime supports direct dispatch.
Definition: ObjCRuntime.h:467
void * getAsOpaquePtr() const
Definition: Ownership.h:90
static OpaquePtr getFromOpaquePtr(void *P)
Definition: Ownership.h:91
bool isSupported(llvm::StringRef Ext, const LangOptions &LO) const
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
Definition: Attr.h:250
unsigned getSourceIndex() const
Get the parameter index as it would normally be encoded for attributes at the source level of represe...
Definition: Attr.h:318
unsigned getASTIndex() const
Get the parameter index as it would normally be encoded at the AST level of representation: zero-orig...
Definition: Attr.h:329
A parameter attribute which changes the argument-passing ABI rule for the parameter.
Definition: Attr.h:218
Represents a parameter to a function.
Definition: Decl.h:1761
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
Definition: Decl.h:1794
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:2938
ParsedAttr - Represents a syntactic attribute.
Definition: ParsedAttr.h:126
bool isPackExpansion() const
Definition: ParsedAttr.h:378
const AvailabilityChange & getAvailabilityDeprecated() const
Definition: ParsedAttr.h:412
unsigned getSemanticSpelling() const
If the parsed attribute has a semantic equivalent, and it would have a semantic Spelling enumeration ...
Definition: ParsedAttr.cpp:262
bool existsInTarget(const TargetInfo &Target) const
Definition: ParsedAttr.cpp:201
bool checkExactlyNumArgs(class Sema &S, unsigned Num) const
Check if the attribute has exactly as many args as Num.
Definition: ParsedAttr.cpp:298
IdentifierLoc * getArgAsIdent(unsigned Arg) const
Definition: ParsedAttr.h:402
bool hasParsedType() const
Definition: ParsedAttr.h:348
const AvailabilityChange & getAvailabilityIntroduced() const
Definition: ParsedAttr.h:406
void setInvalid(bool b=true) const
Definition: ParsedAttr.h:356
bool hasVariadicArg() const
Definition: ParsedAttr.cpp:266
const ParsedAttrInfo & getInfo() const
Definition: ParsedAttr.h:620
void handleAttrWithDelayedArgs(Sema &S, Decl *D) const
Definition: ParsedAttr.cpp:278
const Expr * getReplacementExpr() const
Definition: ParsedAttr.h:442
bool hasProcessingCache() const
Definition: ParsedAttr.h:358
SourceLocation getUnavailableLoc() const
Definition: ParsedAttr.h:430
unsigned getProcessingCache() const
Definition: ParsedAttr.h:360
bool acceptsExprPack() const
Definition: ParsedAttr.cpp:260
const Expr * getMessageExpr() const
Definition: ParsedAttr.h:436
const ParsedType & getMatchingCType() const
Definition: ParsedAttr.h:448
const ParsedType & getTypeArg() const
Definition: ParsedAttr.h:466
SourceLocation getStrictLoc() const
Definition: ParsedAttr.h:424
bool isTypeAttr() const
Definition: ParsedAttr.cpp:197
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this attribute.
Definition: ParsedAttr.h:382
bool isArgIdent(unsigned Arg) const
Definition: ParsedAttr.h:398
Expr * getArgAsExpr(unsigned Arg) const
Definition: ParsedAttr.h:394
bool getMustBeNull() const
Definition: ParsedAttr.h:460
bool checkAtLeastNumArgs(class Sema &S, unsigned Num) const
Check if the attribute has at least as many args as Num.
Definition: ParsedAttr.cpp:303
bool isUsedAsTypeAttr() const
Definition: ParsedAttr.h:370
unsigned getNumArgMembers() const
Definition: ParsedAttr.cpp:154
bool isStmtAttr() const
Definition: ParsedAttr.cpp:199
bool isPragmaClangAttribute() const
True if the attribute is specified using '#pragma clang attribute'.
Definition: ParsedAttr.h:374
bool slidesFromDeclToDeclSpecLegacyBehavior() const
Returns whether a [[]] attribute, if specified ahead of a declaration, should be applied to the decl-...
Definition: ParsedAttr.cpp:222
AttributeCommonInfo::Kind getKind() const
Definition: ParsedAttr.h:617
void setProcessingCache(unsigned value) const
Definition: ParsedAttr.h:365
bool isParamExpr(size_t N) const
Definition: ParsedAttr.cpp:274
bool isArgExpr(unsigned Arg) const
Definition: ParsedAttr.h:390
bool getLayoutCompatible() const
Definition: ParsedAttr.h:454
ArgsUnion getArg(unsigned Arg) const
getArg - Return the specified argument.
Definition: ParsedAttr.h:385
SourceLocation getEllipsisLoc() const
Definition: ParsedAttr.h:379
bool isInvalid() const
Definition: ParsedAttr.h:355
bool checkAtMostNumArgs(class Sema &S, unsigned Num) const
Check if the attribute has at most as many args as Num.
Definition: ParsedAttr.cpp:308
const AvailabilityChange & getAvailabilityObsoleted() const
Definition: ParsedAttr.h:418
void addAtEnd(ParsedAttr *newAttr)
Definition: ParsedAttr.h:836
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3140
QualType getPointeeType() const
Definition: Type.h:3150
IdentifierTable & getIdentifierTable()
A (possibly-)qualified type.
Definition: Type.h:940
QualType withConst() const
Definition: Type.h:1154
QualType getLocalUnqualifiedType() const
Return this type with all of the instance-specific qualifiers removed, but without removing any quali...
Definition: Type.h:1220
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1007
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:7360
LangAS getAddressSpace() const
Return the address space of this type.
Definition: Type.h:7486
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition: Type.h:7400
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
Definition: Type.h:1432
QualType getCanonicalType() const
Definition: Type.h:7412
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: Type.h:7454
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: Type.h:7433
const Type * getTypePtrOrNull() const
Definition: Type.h:7364
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Definition: Type.h:347
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
Definition: Type.h:340
@ OCL_None
There is no lifetime qualification on this type.
Definition: Type.h:336
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Definition: Type.h:350
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
Definition: Type.h:353
ObjCLifetime getObjCLifetime() const
Definition: Type.h:531
bool empty() const
Definition: Type.h:633
Represents a struct/union/class.
Definition: Decl.h:4168
field_iterator field_end() const
Definition: Decl.h:4377
field_range fields() const
Definition: Decl.h:4374
field_iterator field_begin() const
Definition: Decl.cpp:5069
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:5550
RecordDecl * getDecl() const
Definition: Type.h:5560
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3381
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:41
unsigned getFlags() const
getFlags - Return the flags for this scope.
Definition: Scope.h:262
@ FunctionDeclarationScope
This is a scope that corresponds to the parameters within a function prototype for a function declara...
Definition: Scope.h:91
A generic diagnostic builder for errors which may or may not be deferred.
Definition: SemaBase.h:110
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: SemaBase.cpp:56
CUDAFunctionTarget IdentifyTarget(const FunctionDecl *D, bool IgnoreImplicitHDAttr=false)
Determines whether the given function is a CUDA device/host/kernel/etc.
Definition: SemaCUDA.cpp:136
CUDAFunctionTarget CurrentTarget()
Gets the CUDA target for the current context.
Definition: SemaCUDA.h:142
SemaDiagnosticBuilder DiagIfHostCode(SourceLocation Loc, unsigned DiagID)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as host cod...
Definition: SemaCUDA.cpp:851
HLSLNumThreadsAttr * mergeNumThreadsAttr(Decl *D, const AttributeCommonInfo &AL, int X, int Y, int Z)
Definition: SemaHLSL.cpp:128
HLSLShaderAttr * mergeShaderAttr(Decl *D, const AttributeCommonInfo &AL, HLSLShaderAttr::ShaderType ShaderType)
Definition: SemaHLSL.cpp:143
HLSLParamModifierAttr * mergeParamModifierAttr(Decl *D, const AttributeCommonInfo &AL, HLSLParamModifierAttr::Spelling Spelling)
Definition: SemaHLSL.cpp:156
bool isCFError(RecordDecl *D)
Definition: SemaObjC.cpp:1461
IdentifierInfo * getNSErrorIdent()
Retrieve the identifier "NSError".
Definition: SemaObjC.cpp:1265
A class which encapsulates the logic for delaying diagnostics during parsing and other processing.
Definition: Sema.h:926
sema::DelayedDiagnosticPool * getCurrentPool() const
Returns the current delayed-diagnostics pool.
Definition: Sema.h:941
void popWithoutEmitting(DelayedDiagnosticsState state)
Leave a delayed-diagnostic state that was previously pushed.
Definition: Sema.h:955
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:450
AvailabilityAttr * mergeAvailabilityAttr(NamedDecl *D, const AttributeCommonInfo &CI, IdentifierInfo *Platform, bool Implicit, VersionTuple Introduced, VersionTuple Deprecated, VersionTuple Obsoleted, bool IsUnavailable, StringRef Message, bool IsStrict, StringRef Replacement, AvailabilityMergeKind AMK, int Priority)
bool ConstantFoldAttrArgs(const AttributeCommonInfo &CI, MutableArrayRef< Expr * > Args)
ConstantFoldAttrArgs - Folds attribute arguments into ConstantExprs (unless they are value dependent ...
Definition: SemaAttr.cpp:400
BTFDeclTagAttr * mergeBTFDeclTagAttr(Decl *D, const BTFDeclTagAttr &AL)
void LoadExternalWeakUndeclaredIdentifiers()
Load weak undeclared identifiers from the external source.
Definition: Sema.cpp:939
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Definition: Sema.h:7288
EnforceTCBAttr * mergeEnforceTCBAttr(Decl *D, const EnforceTCBAttr &AL)
bool checkTargetVersionAttr(SourceLocation LiteralLoc, Decl *D, StringRef &Str, bool &isDefault)
bool isValidPointerAttrType(QualType T, bool RefOkay=false)
Determine if type T is a valid subject for a nonnull and similar attributes.
RetainOwnershipKind
Definition: Sema.h:3674
TypeVisibilityAttr * mergeTypeVisibilityAttr(Decl *D, const AttributeCommonInfo &CI, TypeVisibilityAttr::VisibilityType Vis)
void AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E, bool IsPackExpansion)
AddAlignedAttr - Adds an aligned attribute to a particular declaration.
void AddAssumeAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E, Expr *OE)
AddAssumeAlignedAttr - Adds an assume_aligned attribute to a particular declaration.
bool checkSectionName(SourceLocation LiteralLoc, StringRef Str)
void AddPragmaAttributes(Scope *S, Decl *D)
Adds the attributes that have been specified using the '#pragma clang attribute push' directives to t...
Definition: SemaAttr.cpp:1093
SemaCUDA & CUDA()
Definition: Sema.h:992
bool checkCommonAttributeFeatures(const Decl *D, const ParsedAttr &A, bool SkipArgCountCheck=false)
Handles semantic checking for features that are common to all attributes, such as checking whether a ...
Definition: SemaAttr.cpp:1454
void addAMDGPUWavesPerEUAttr(Decl *D, const AttributeCommonInfo &CI, Expr *Min, Expr *Max)
addAMDGPUWavePersEUAttr - Adds an amdgpu_waves_per_eu attribute to a particular declaration.
WebAssemblyImportNameAttr * mergeImportNameAttr(Decl *D, const WebAssemblyImportNameAttr &AL)
void addAMDGPUMaxNumWorkGroupsAttr(Decl *D, const AttributeCommonInfo &CI, Expr *XExpr, Expr *YExpr, Expr *ZExpr)
addAMDGPUMaxNumWorkGroupsAttr - Adds an amdgpu_max_num_work_groups attribute to a particular declarat...
Scope * getScopeForContext(DeclContext *Ctx)
Determines the active Scope associated with the given declaration context.
Definition: Sema.cpp:2113
bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, const ParsedAttributesView &AttrList)
AMDGPUFlatWorkGroupSizeAttr * CreateAMDGPUFlatWorkGroupSizeAttr(const AttributeCommonInfo &CI, Expr *Min, Expr *Max)
Create an AMDGPUWavesPerEUAttr attribute.
DLLImportAttr * mergeDLLImportAttr(Decl *D, const AttributeCommonInfo &CI)
ExtVectorDeclsType ExtVectorDecls
ExtVectorDecls - This is a list all the extended vector types.
Definition: Sema.h:3555
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, AllowFoldKind CanFold=NoFold)
VerifyIntegerConstantExpression - Verifies that an expression is an ICE, and reports the appropriate ...
Definition: SemaExpr.cpp:17081
void PopParsingDeclaration(ParsingDeclState state, Decl *decl)
ErrorAttr * mergeErrorAttr(Decl *D, const AttributeCommonInfo &CI, StringRef NewUserDiagnostic)
void redelayDiagnostics(sema::DelayedDiagnosticPool &pool)
Given a set of delayed diagnostics, re-emit them as if they had been delayed in the current context i...
VisibilityAttr * mergeVisibilityAttr(Decl *D, const AttributeCommonInfo &CI, VisibilityAttr::VisibilityType Vis)
ParmVarDecl * BuildParmVarDeclForTypedef(DeclContext *DC, SourceLocation Loc, QualType T)
Synthesizes a variable for a parameter arising from a typedef.
Definition: SemaDecl.cpp:15217
ASTContext & Context
Definition: Sema.h:847
AMDGPUWavesPerEUAttr * CreateAMDGPUWavesPerEUAttr(const AttributeCommonInfo &CI, Expr *Min, Expr *Max)
Create an AMDGPUWavesPerEUAttr attribute.
SemaObjC & ObjC()
Definition: Sema.h:1002
void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext=true)
Add this decl to the scope shadowed decl chains.
Definition: SemaDecl.cpp:1523
ASTContext & getASTContext() const
Definition: Sema.h:516
@ None
This is not a defaultable comparison operator.
bool CheckCallingConvAttr(const ParsedAttr &attr, CallingConv &CC, const FunctionDecl *FD=nullptr, CUDAFunctionTarget CFT=CUDAFunctionTarget::InvalidTarget)
Check validaty of calling convention attribute attr.
FunctionDecl * ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, bool Complain=false, DeclAccessPair *Found=nullptr, TemplateSpecCandidateSet *FailedTSC=nullptr)
Given an expression that refers to an overloaded function, try to resolve that overloaded function ex...
void ProcessPragmaWeak(Scope *S, Decl *D)
void AddXConsumedAttr(Decl *D, const AttributeCommonInfo &CI, RetainOwnershipKind K, bool IsTemplateInstantiation)
bool CheckAttrNoArgs(const ParsedAttr &CurrAttr)
bool UnifySection(StringRef SectionName, int SectionFlags, NamedDecl *TheDecl)
Definition: SemaAttr.cpp:693
FPOptions & getCurFPFeatures()
Definition: Sema.h:511
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
Definition: Sema.cpp:65
@ UPPC_Expression
An arbitrary expression.
Definition: Sema.h:10708
const LangOptions & getLangOpts() const
Definition: Sema.h:509
void AddModeAttr(Decl *D, const AttributeCommonInfo &CI, IdentifierInfo *Name, bool InInstantiation=false)
AddModeAttr - Adds a mode attribute to a particular declaration.
bool checkNSReturnsRetainedReturnType(SourceLocation loc, QualType type)
Preprocessor & PP
Definition: Sema.h:846
bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T, UnexpandedParameterPackContext UPPC)
If the given type contains an unexpanded parameter pack, diagnose the error.
MinSizeAttr * mergeMinSizeAttr(Decl *D, const AttributeCommonInfo &CI)
const LangOptions & LangOpts
Definition: Sema.h:845
static const uint64_t MaximumAlignment
Definition: Sema.h:787
SemaHLSL & HLSL()
Definition: Sema.h:997
AlwaysInlineAttr * mergeAlwaysInlineAttr(Decl *D, const AttributeCommonInfo &CI, const IdentifierInfo *Ident)
QualType BuildCountAttributedArrayOrPointerType(QualType WrappedTy, Expr *CountExpr)
Definition: SemaType.cpp:9348
void ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AttrList, const ProcessDeclAttributeOptions &Options=ProcessDeclAttributeOptions())
ProcessDeclAttributeList - Apply all the decl attributes in the specified attribute list to the speci...
WebAssemblyImportModuleAttr * mergeImportModuleAttr(Decl *D, const WebAssemblyImportModuleAttr &AL)
NamedDecl * getCurFunctionOrMethodDecl() const
getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method or C function we're in,...
Definition: Sema.cpp:1511
void AddAllocAlignAttr(Decl *D, const AttributeCommonInfo &CI, Expr *ParamExpr)
AddAllocAlignAttr - Adds an alloc_align attribute to a particular declaration.
bool CheckRegparmAttr(const ParsedAttr &attr, unsigned &value)
Checks a regparm attribute, returning true if it is ill-formed and otherwise setting numParams to the...
void AddAnnotationAttr(Decl *D, const AttributeCommonInfo &CI, StringRef Annot, MutableArrayRef< Expr * > Args)
AddAnnotationAttr - Adds an annotation Annot with Args arguments to D.
void ProcessDeclAttributeDelayed(Decl *D, const ParsedAttributesView &AttrList)
MSInheritanceAttr * mergeMSInheritanceAttr(Decl *D, const AttributeCommonInfo &CI, bool BestCase, MSInheritanceModel Model)
InternalLinkageAttr * mergeInternalLinkageAttr(Decl *D, const ParsedAttr &AL)
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition: Sema.h:985
ExprResult PerformContextuallyConvertToBool(Expr *From)
PerformContextuallyConvertToBool - Perform a contextual conversion of the expression From to bool (C+...
@ Compatible
Compatible - the types are compatible according to the standard.
Definition: Sema.h:6021
NamedDecl * DeclClonePragmaWeak(NamedDecl *ND, const IdentifierInfo *II, SourceLocation Loc)
DeclClonePragmaWeak - clone existing decl (maybe definition), #pragma weak needs a non-definition dec...
DLLExportAttr * mergeDLLExportAttr(Decl *D, const AttributeCommonInfo &CI)
AMDGPUMaxNumWorkGroupsAttr * CreateAMDGPUMaxNumWorkGroupsAttr(const AttributeCommonInfo &CI, Expr *XExpr, Expr *YExpr, Expr *ZExpr)
Create an AMDGPUMaxNumWorkGroupsAttr attribute.
CodeSegAttr * mergeCodeSegAttr(Decl *D, const AttributeCommonInfo &CI, StringRef Name)
SectionAttr * mergeSectionAttr(Decl *D, const AttributeCommonInfo &CI, StringRef Name)
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
Definition: Sema.h:10401
SourceManager & getSourceManager() const
Definition: Sema.h:514
bool checkTargetAttr(SourceLocation LiteralLoc, StringRef Str)
llvm::Error isValidSectionSpecifier(StringRef Str)
Used to implement to perform semantic checking on attribute((section("foo"))) specifiers.
void AddLaunchBoundsAttr(Decl *D, const AttributeCommonInfo &CI, Expr *MaxThreads, Expr *MinBlocks, Expr *MaxBlocks)
AddLaunchBoundsAttr - Adds a launch_bounds attribute to a particular declaration.
OptimizeNoneAttr * mergeOptimizeNoneAttr(Decl *D, const AttributeCommonInfo &CI)
void checkUnusedDeclAttributes(Declarator &D)
checkUnusedDeclAttributes - Given a declarator which is not being used to build a declaration,...
bool CheckAttrTarget(const ParsedAttr &CurrAttr)
EnforceTCBLeafAttr * mergeEnforceTCBLeafAttr(Decl *D, const EnforceTCBLeafAttr &AL)
ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS=nullptr, bool isClassName=false, bool HasTrailingDot=false, ParsedType ObjectType=nullptr, bool IsCtorOrDtorName=false, bool WantNontrivialTypeSourceInfo=false, bool IsClassTemplateDeductionContext=true, ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No, IdentifierInfo **CorrectedII=nullptr)
If the identifier refers to a type name within this scope, return the declaration of that type.
Definition: SemaDecl.cpp:291
ASTConsumer & Consumer
Definition: Sema.h:848
void NoteAllOverloadCandidates(Expr *E, QualType DestType=QualType(), bool TakingAddress=false)
FormatAttr * mergeFormatAttr(Decl *D, const AttributeCommonInfo &CI, IdentifierInfo *Format, int FormatIdx, int FirstArg)
@ AP_PragmaClangAttribute
The availability attribute was applied using '#pragma clang attribute'.
Definition: Sema.h:3522
@ AP_InferredFromOtherPlatform
The availability attribute for a specific platform was inferred from an availability attribute for an...
Definition: Sema.h:3526
@ AP_Explicit
The availability attribute was specified explicitly next to the declaration.
Definition: Sema.h:3519
AvailabilityMergeKind
Describes the kind of merge to perform for availability attributes (including "deprecated",...
Definition: Sema.h:3316
@ AMK_None
Don't merge availability attributes at all.
Definition: Sema.h:3318
@ AMK_Override
Merge availability attributes for an override, which requires an exact match or a weakening of constr...
Definition: Sema.h:3324
@ AMK_ProtocolImplementation
Merge availability attributes for an implementation of a protocol requirement.
Definition: Sema.h:3327
@ AMK_OptionalProtocolImplementation
Merge availability attributes for an implementation of an optional protocol requirement.
Definition: Sema.h:3330
@ AMK_Redeclaration
Merge availability attributes for a redeclaration, which requires an exact match.
Definition: Sema.h:3321
SmallVector< Decl *, 2 > WeakTopLevelDecl
WeakTopLevelDecl - Translation-unit scoped declarations generated by #pragma weak during processing o...
Definition: Sema.h:3543
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Definition: SemaType.cpp:8831
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
Definition: Sema.h:819
UuidAttr * mergeUuidAttr(Decl *D, const AttributeCommonInfo &CI, StringRef UuidAsWritten, MSGuidDecl *GuidDecl)
void addAMDGPUFlatWorkGroupSizeAttr(Decl *D, const AttributeCommonInfo &CI, Expr *Min, Expr *Max)
addAMDGPUFlatWorkGroupSizeAttr - Adds an amdgpu_flat_work_group_size attribute to a particular declar...
OpenCLOptions & getOpenCLOptions()
Definition: Sema.h:510
void AddParameterABIAttr(Decl *D, const AttributeCommonInfo &CI, ParameterABI ABI)
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
Definition: SemaInit.cpp:10684
bool checkTargetClonesAttrString(SourceLocation LiteralLoc, StringRef Str, const StringLiteral *Literal, Decl *D, bool &HasDefault, bool &HasCommas, bool &HasNotDefault, SmallVectorImpl< SmallString< 64 > > &StringsBuffer)
void handleDelayedAvailabilityCheck(sema::DelayedDiagnostic &DD, Decl *Ctx)
void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD)
ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in it, apply them to D.
void DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, const WeakInfo &W)
DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak applied to it,...
bool DiagnoseSwiftName(Decl *D, StringRef Name, SourceLocation Loc, const ParsedAttr &AL, bool IsAsync)
Do a check to make sure Name looks like a legal argument for the swift_name attribute applied to decl...
llvm::MapVector< IdentifierInfo *, llvm::SetVector< WeakInfo, llvm::SmallVector< WeakInfo, 1u >, llvm::SmallDenseSet< WeakInfo, 2u, WeakInfo::DenseMapInfoByAliasOnly > > > WeakUndeclaredIdentifiers
WeakUndeclaredIdentifiers - Identifiers contained in #pragma weak before declared.
Definition: Sema.h:2594
void ProcessAPINotes(Decl *D)
Map any API notes provided for this declaration to attributes on the declaration.
void CheckAlignasUnderalignment(Decl *D)
void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx)
DarwinSDKInfo * getDarwinSDKInfoForAvailabilityChecking(SourceLocation Loc, StringRef Platform)
Definition: Sema.cpp:72
AssignConvertType CheckAssignmentConstraints(SourceLocation Loc, QualType LHSType, QualType RHSType)
CheckAssignmentConstraints - Perform type checking for assignment, argument passing,...
Definition: SemaExpr.cpp:9251
SwiftNameAttr * mergeSwiftNameAttr(Decl *D, const SwiftNameAttr &SNA, StringRef Name)
CUDALaunchBoundsAttr * CreateLaunchBoundsAttr(const AttributeCommonInfo &CI, Expr *MaxThreads, Expr *MinBlocks, Expr *MaxBlocks)
Create an CUDALaunchBoundsAttr attribute.
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
Definition: SemaType.cpp:2805
void AddAlignValueAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E)
AddAlignValueAttr - Adds an align_value attribute to a particular declaration.
bool checkMSInheritanceAttrOnDefinition(CXXRecordDecl *RD, SourceRange Range, bool BestCase, MSInheritanceModel SemanticSpelling)
bool checkStringLiteralArgumentAttr(const AttributeCommonInfo &CI, const Expr *E, StringRef &Str, SourceLocation *ArgLocation=nullptr)
Check if the argument E is a ASCII string literal.
bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, const FunctionProtoType *Proto)
CheckFunctionCall - Check a direct function call for various correctness and safety properties not st...
ASTMutationListener * getASTMutationListener() const
Definition: Sema.cpp:550
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
bool isInSystemMacro(SourceLocation loc) const
Returns whether Loc is expanded from a macro in a system header.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
bool isValid() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:326
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:338
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1773
bool isBeingDefined() const
Return true if this decl is currently being defined.
Definition: Decl.h:3707
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition: Decl.h:3687
bool isUnion() const
Definition: Decl.h:3790
TagKind getTagKind() const
Definition: Decl.h:3779
Exposes information about the current target.
Definition: TargetInfo.h:218
TargetOptions & getTargetOpts() const
Retrieve the target options.
Definition: TargetInfo.h:312
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:1256
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
Definition: TargetInfo.h:472
virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const
Determines whether a given calling convention is valid for the target.
Definition: TargetInfo.h:1679
bool isTLSSupported() const
Whether the target supports thread-local storage.
Definition: TargetInfo.h:1561
unsigned getMaxTLSAlign() const
Return the maximum alignment (in bits) of a TLS variable.
Definition: TargetInfo.h:1569
virtual unsigned getRegisterWidth() const
Return the "preferred" register width on this target.
Definition: TargetInfo.h:879
virtual bool validateCpuSupports(StringRef Name) const
Definition: TargetInfo.h:1504
virtual bool doesFeatureAffectCodeGen(StringRef Feature) const
Returns true if feature has an impact on target code generation.
Definition: TargetInfo.h:1399
virtual bool validateCPUSpecificCPUDispatch(StringRef Name) const
Definition: TargetInfo.h:1522
virtual bool hasProtectedVisibility() const
Does this target support "protected" visibility?
Definition: TargetInfo.h:1290
unsigned getRegParmMax() const
Definition: TargetInfo.h:1555
virtual unsigned getUnwindWordWidth() const
Definition: TargetInfo.h:874
virtual bool isValidFeatureName(StringRef Feature) const
Determine whether this TargetInfo supports the given feature.
Definition: TargetInfo.h:1393
unsigned getCharWidth() const
Definition: TargetInfo.h:496
virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const
Definition: TargetInfo.cpp:548
virtual bool supportsTargetAttributeTune() const
Determine whether this TargetInfo supports tune in target attribute.
Definition: TargetInfo.h:1360
virtual bool shouldDLLImportComdatSymbols() const
Does this target aim for semantic compatibility with Microsoft C++ code using dllimport/export attrib...
Definition: TargetInfo.h:1294
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
Definition: TargetInfo.h:1472
virtual bool isValidCPUName(StringRef Name) const
Determine whether this TargetInfo supports the given CPU name.
Definition: TargetInfo.h:1347
const llvm::VersionTuple & getSDKVersion() const
Definition: TargetInfo.h:1780
virtual bool validateBranchProtection(StringRef Spec, StringRef Arch, BranchProtectionInfo &BPI, StringRef &Err) const
Determine if this TargetInfo supports the given branch protection specification.
Definition: TargetInfo.h:1448
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:394
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:413
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
NamedDecl * getParam(unsigned Idx)
Definition: DeclTemplate.h:144
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: Type.h:6090
[BoundsSafety] Represents information of declarations referenced by the arguments of the counted_by a...
Definition: Type.h:3168
const Type * getTypeForDecl() const
Definition: Decl.h:3414
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
Definition: TypeLoc.h:153
SourceLocation getBeginLoc() const
Get the begin source location.
Definition: TypeLoc.cpp:192
A container of type source information.
Definition: Type.h:7331
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:256
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:7342
The base class of the type hierarchy.
Definition: Type.h:1813
bool isSizelessType() const
As an extension, we classify types as one of "sized" or "sizeless"; every type is one or the other.
Definition: Type.cpp:2465
bool isStructureType() const
Definition: Type.cpp:629
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1881
bool isBlockPointerType() const
Definition: Type.h:7621
bool isVoidType() const
Definition: Type.h:7906
bool isBooleanType() const
Definition: Type.h:8034
const RecordType * getAsUnionType() const
NOTE: getAs*ArrayType are methods on ASTContext.
Definition: Type.cpp:740
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
Definition: Type.cpp:2145
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
Definition: Type.cpp:677
bool isVoidPointerType() const
Definition: Type.cpp:665
bool isArrayType() const
Definition: Type.h:7679
bool isCharType() const
Definition: Type.cpp:2088
bool isFunctionPointerType() const
Definition: Type.h:7647
bool isPointerType() const
Definition: Type.h:7613
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition: Type.h:7946
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8194
bool isReferenceType() const
Definition: Type.h:7625
bool isObjCNSObjectType() const
Definition: Type.cpp:4876
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
Definition: Type.cpp:1866
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
Definition: Type.cpp:2057
bool isAlignValT() const
Definition: Type.cpp:3081
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:705
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition: Type.h:8021
bool hasUnsignedIntegerRepresentation() const
Determine whether this type has an unsigned integer representation of some sort, e....
Definition: Type.cpp:2235
bool isExtVectorType() const
Definition: Type.h:7723
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition: Type.h:2662
bool isBitIntType() const
Definition: Type.h:7841
bool isBuiltinType() const
Helper methods to distinguish type categories.
Definition: Type.h:7703
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2654
bool isCARCBridgableType() const
Determine whether the given type T is a "bridgeable" C type.
Definition: Type.cpp:4922
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
Definition: Type.h:2320
bool isMemberPointerType() const
Definition: Type.h:7661
bool isObjCIdType() const
Definition: Type.h:7778
bool isObjCObjectType() const
Definition: Type.h:7749
bool isObjCLifetimeType() const
Returns true if objects of this type have lifetime semantics under ARC.
Definition: Type.cpp:4908
Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const
Return the implicit lifetime for this type, which must not be dependent.
Definition: Type.cpp:4851
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
Definition: Type.cpp:2361
bool isFunctionType() const
Definition: Type.h:7609
bool isObjCObjectPointerType() const
Definition: Type.h:7745
bool isStructureTypeWithFlexibleArrayMember() const
Definition: Type.cpp:635
Visibility getVisibility() const
Determine the visibility of this type.
Definition: Type.h:2883
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
Definition: Type.cpp:2257
bool isVectorType() const
Definition: Type.h:7719
bool isFloatingType() const
Definition: Type.cpp:2248
bool isAnyPointerType() const
Definition: Type.h:7617
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8127
const Type * getUnqualifiedDesugaredType() const
Return the specified type with any "sugar" removed from the type, removing any typedefs,...
Definition: Type.cpp:605
bool isObjCRetainableType() const
Definition: Type.cpp:4888
bool isTypedefNameType() const
Determines whether this type is written as a typedef-name.
Definition: Type.h:8055
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
Definition: Type.h:8068
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3432
static UnaryOperator * Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, FPOptionsOverride FPFeatures)
Definition: Expr.cpp:4843
Represents a dependent using declaration which was marked with typename.
Definition: DeclCXX.h:3959
Represents a dependent using declaration which was not marked with typename.
Definition: DeclCXX.h:3862
Represents a C++ using-declaration.
Definition: DeclCXX.h:3512
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:706
void setType(QualType newType)
Definition: Decl.h:718
QualType getType() const
Definition: Decl.h:717
Represents a variable declaration or definition.
Definition: Decl.h:918
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
Definition: Decl.cpp:2148
void setARCPseudoStrong(bool PS)
Definition: Decl.h:1528
@ TLS_None
Not a TLS variable.
Definition: Decl.h:938
Represents a GCC generic vector type.
Definition: Type.h:3970
Captures information about a #pragma weak directive.
Definition: Weak.h:25
const IdentifierInfo * getAlias() const
Definition: Weak.h:32
SourceLocation getLocation() const
Definition: Weak.h:33
A collection of diagnostics which were delayed.
const DelayedDiagnosticPool * getParent() const
void steal(DelayedDiagnosticPool &pool)
Steal the diagnostics from the given pool.
SmallVectorImpl< DelayedDiagnostic >::const_iterator pool_iterator
A diagnostic message which has been conditionally emitted pending the complete parsing of the current...
QualType getForbiddenTypeOperand() const
unsigned getForbiddenTypeDiagnostic() const
The diagnostic ID to emit.
unsigned getForbiddenTypeArgument() const
Defines the clang::TargetInfo interface.
#define UINT_MAX
Definition: limits.h:64
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:21
bool isa(CodeGen::Address addr)
Definition: Address.h:294
AttributeDeclKind
These constants match the enumerated choices of warn_attribute_wrong_decl_type and err_attribute_wron...
Definition: ParsedAttr.h:1076
@ ExpectedFunctionMethodOrParameter
Definition: ParsedAttr.h:1082
@ ExpectedFunctionWithProtoType
Definition: ParsedAttr.h:1089
@ ExpectedFunctionMethodOrBlock
Definition: ParsedAttr.h:1081
@ ExpectedTypeOrNamespace
Definition: ParsedAttr.h:1086
@ ExpectedVariableFieldOrTag
Definition: ParsedAttr.h:1085
@ ExpectedVariableOrField
Definition: ParsedAttr.h:1084
@ ExpectedUnion
Definition: ParsedAttr.h:1078
@ ExpectedFunctionOrMethod
Definition: ParsedAttr.h:1080
@ ExpectedVariable
Definition: ParsedAttr.h:1083
@ ExpectedVariableOrFunction
Definition: ParsedAttr.h:1079
@ ExpectedKernelFunction
Definition: ParsedAttr.h:1088
@ ExpectedFunctionVariableOrClass
Definition: ParsedAttr.h:1087
@ ExpectedFunction
Definition: ParsedAttr.h:1077
CudaArch
Definition: Cuda.h:54
llvm::StringRef getParameterABISpelling(ParameterABI kind)
CUDAFunctionTarget
Definition: Cuda.h:132
@ OK_Ordinary
An ordinary object is located at an address in memory.
Definition: Specifiers.h:148
CudaVersion ToCudaVersion(llvm::VersionTuple)
Definition: Cuda.cpp:66
LLVM_READONLY bool isValidAsciiIdentifier(StringRef S, bool AllowDollar=false)
Return true if this is a valid ASCII identifier.
Definition: CharInfo.h:244
CudaArch StringToCudaArch(llvm::StringRef S)
Definition: Cuda.cpp:169
@ SC_Extern
Definition: Specifiers.h:248
@ SC_Register
Definition: Specifiers.h:254
@ SC_None
Definition: Specifiers.h:247
@ TSCS_unspecified
Definition: Specifiers.h:233
@ Internal
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
Language
The language for the input, used to select and validate the language standard and possible actions.
Definition: LangStandard.h:23
AttributeArgumentNType
These constants match the enumerated choices of err_attribute_argument_n_type and err_attribute_argum...
Definition: ParsedAttr.h:1065
@ AANT_ArgumentIntegerConstant
Definition: ParsedAttr.h:1067
@ AANT_ArgumentBuiltinFunction
Definition: ParsedAttr.h:1071
@ AANT_ArgumentIntOrBool
Definition: ParsedAttr.h:1066
@ AANT_ArgumentIdentifier
Definition: ParsedAttr.h:1069
@ AANT_ArgumentString
Definition: ParsedAttr.h:1068
@ SD_Automatic
Automatic storage duration (most local variables).
Definition: Specifiers.h:326
@ Property
The type of a property.
@ Result
The result type of a method or function.
ParameterABI
Kinds of parameter ABI.
Definition: Specifiers.h:363
@ SwiftAsyncContext
This parameter (which must have pointer type) uses the special Swift asynchronous context-pointer ABI...
@ SwiftErrorResult
This parameter (which must have pointer-to-pointer type) uses the special Swift error-result ABI trea...
@ Ordinary
This parameter uses ordinary ABI rules for its type.
@ SwiftIndirectResult
This parameter (which must have pointer type) is a Swift indirect result parameter.
@ SwiftContext
This parameter (which must have pointer type) uses the special Swift context-pointer ABI treatment.
CudaVersion
Definition: Cuda.h:20
LLVM_READONLY bool isHexDigit(unsigned char c)
Return true if this character is an ASCII hex digit: [0-9a-fA-F].
Definition: CharInfo.h:145
SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups)
Parse a single value from a -fsanitize= or -fno-sanitize= value list.
Definition: Sanitizers.cpp:29
FloatModeKind
Definition: TargetInfo.h:72
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:132
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Definition: Specifiers.h:136
const FunctionProtoType * T
MSInheritanceModel
Assigned inheritance model for a class in the MS C++ ABI.
Definition: Specifiers.h:389
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
Definition: DeclBase.h:1275
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
Definition: Specifiers.h:275
@ CC_X86Pascal
Definition: Specifiers.h:281
@ CC_Swift
Definition: Specifiers.h:290
@ CC_IntelOclBicc
Definition: Specifiers.h:287
@ CC_PreserveMost
Definition: Specifiers.h:292
@ CC_Win64
Definition: Specifiers.h:282
@ CC_X86ThisCall
Definition: Specifiers.h:279
@ CC_AArch64VectorCall
Definition: Specifiers.h:294
@ CC_AAPCS
Definition: Specifiers.h:285
@ CC_PreserveNone
Definition: Specifiers.h:298
@ CC_C
Definition: Specifiers.h:276
@ CC_AMDGPUKernelCall
Definition: Specifiers.h:296
@ CC_M68kRTD
Definition: Specifiers.h:297
@ CC_SwiftAsync
Definition: Specifiers.h:291
@ CC_X86RegCall
Definition: Specifiers.h:284
@ CC_RISCVVectorCall
Definition: Specifiers.h:299
@ CC_X86VectorCall
Definition: Specifiers.h:280
@ CC_AArch64SVEPCS
Definition: Specifiers.h:295
@ CC_X86StdCall
Definition: Specifiers.h:277
@ CC_X86_64SysV
Definition: Specifiers.h:283
@ CC_PreserveAll
Definition: Specifiers.h:293
@ CC_X86FastCall
Definition: Specifiers.h:278
@ CC_AAPCS_VFP
Definition: Specifiers.h:286
@ Generic
not a target-specific vector type
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
@ Union
The "union" keyword introduces the elaborated-type-specifier.
bool IsArmStreamingFunction(const FunctionDecl *FD, bool IncludeLocallyStreaming)
Returns whether the given FunctionDecl has an __arm[_locally]_streaming attribute.
Definition: Decl.cpp:5760
@ Other
Other implicit parameter.
@ Implicit
An implicit conversion.
const char * CudaArchToString(CudaArch A)
Definition: Cuda.cpp:151
Represents information about a change in availability for an entity, which is part of the encoding of...
Definition: ParsedAttr.h:47
VersionTuple Version
The version number at which the change occurred.
Definition: ParsedAttr.h:52
bool isValid() const
Determine whether this availability change is valid.
Definition: ParsedAttr.h:58
static constexpr OSEnvPair macOStoMacCatalystPair()
Returns the os-environment mapping pair that's used to represent the macOS -> Mac Catalyst version ma...
Definition: DarwinSDKInfo.h:49
static constexpr OSEnvPair iOStoWatchOSPair()
Returns the os-environment mapping pair that's used to represent the iOS -> watchOS version mapping.
Definition: DarwinSDKInfo.h:63
static constexpr OSEnvPair iOStoTvOSPair()
Returns the os-environment mapping pair that's used to represent the iOS -> tvOS version mapping.
Definition: DarwinSDKInfo.h:70
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
DeclarationName getName() const
getName - Returns the embedded declaration name.
const ParsedAttributesView & getAttrs() const
If there are attributes applied to this declaratorchunk, return them.
Definition: DeclSpec.h:1660
Wraps an identifier and optional source location for the identifier.
Definition: ParsedAttr.h:100
SourceLocation Loc
Definition: ParsedAttr.h:101
IdentifierInfo * Ident
Definition: ParsedAttr.h:102
Parts of a decomposed MSGuidDecl.
Definition: DeclCXX.h:4264
uint16_t Part2
...-89ab-...
Definition: DeclCXX.h:4268
uint32_t Part1
{01234567-...
Definition: DeclCXX.h:4266
uint16_t Part3
...-cdef-...
Definition: DeclCXX.h:4270
uint8_t Part4And5[8]
...-0123-456789abcdef}
Definition: DeclCXX.h:4272
virtual AttrHandling handleDeclAttribute(Sema &S, Decl *D, const ParsedAttr &Attr) const
If this ParsedAttrInfo knows how to handle this ParsedAttr applied to this Decl then do so and return...
Contains information gathered from parsing the contents of TargetAttr.
Definition: TargetInfo.h:57
std::vector< std::string > Features
Definition: TargetInfo.h:58
StringRef BranchProtection
Definition: TargetInfo.h:61