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