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