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