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