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