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