1 //===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements decl-related attribute processing.
11 //===----------------------------------------------------------------------===//
13 #include "clang/AST/ASTConsumer.h"
14 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/ASTMutationListener.h"
16 #include "clang/AST/CXXInheritance.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/DeclObjC.h"
19 #include "clang/AST/DeclTemplate.h"
20 #include "clang/AST/Expr.h"
21 #include "clang/AST/ExprCXX.h"
22 #include "clang/AST/Mangle.h"
23 #include "clang/AST/RecursiveASTVisitor.h"
24 #include "clang/AST/Type.h"
25 #include "clang/Basic/CharInfo.h"
26 #include "clang/Basic/DarwinSDKInfo.h"
27 #include "clang/Basic/HLSLRuntime.h"
28 #include "clang/Basic/LangOptions.h"
29 #include "clang/Basic/SourceLocation.h"
30 #include "clang/Basic/SourceManager.h"
31 #include "clang/Basic/TargetBuiltins.h"
32 #include "clang/Basic/TargetInfo.h"
33 #include "clang/Lex/Preprocessor.h"
34 #include "clang/Sema/DeclSpec.h"
35 #include "clang/Sema/DelayedDiagnostic.h"
36 #include "clang/Sema/Initialization.h"
37 #include "clang/Sema/Lookup.h"
38 #include "clang/Sema/ParsedAttr.h"
39 #include "clang/Sema/Scope.h"
40 #include "clang/Sema/ScopeInfo.h"
41 #include "clang/Sema/SemaInternal.h"
42 #include "llvm/ADT/STLExtras.h"
43 #include "llvm/ADT/StringExtras.h"
44 #include "llvm/IR/Assumptions.h"
45 #include "llvm/MC/MCSectionMachO.h"
46 #include "llvm/Support/Error.h"
47 #include "llvm/Support/MathExtras.h"
48 #include "llvm/Support/raw_ostream.h"
51 using namespace clang
;
54 namespace AttributeLangSupport
{
60 } // end namespace AttributeLangSupport
62 //===----------------------------------------------------------------------===//
64 //===----------------------------------------------------------------------===//
66 /// isFunctionOrMethod - Return true if the given decl has function
67 /// type (function or function-typed variable) or an Objective-C
69 static bool isFunctionOrMethod(const Decl
*D
) {
70 return (D
->getFunctionType() != nullptr) || isa
<ObjCMethodDecl
>(D
);
73 /// Return true if the given decl has function type (function or
74 /// function-typed variable) or an Objective-C method or a block.
75 static bool isFunctionOrMethodOrBlock(const Decl
*D
) {
76 return isFunctionOrMethod(D
) || isa
<BlockDecl
>(D
);
79 /// Return true if the given decl has a declarator that should have
80 /// been processed by Sema::GetTypeForDeclarator.
81 static bool hasDeclarator(const Decl
*D
) {
82 // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
83 return isa
<DeclaratorDecl
>(D
) || isa
<BlockDecl
>(D
) || isa
<TypedefNameDecl
>(D
) ||
84 isa
<ObjCPropertyDecl
>(D
);
87 /// hasFunctionProto - Return true if the given decl has a argument
88 /// information. This decl should have already passed
89 /// isFunctionOrMethod or isFunctionOrMethodOrBlock.
90 static bool hasFunctionProto(const Decl
*D
) {
91 if (const FunctionType
*FnTy
= D
->getFunctionType())
92 return isa
<FunctionProtoType
>(FnTy
);
93 return isa
<ObjCMethodDecl
>(D
) || isa
<BlockDecl
>(D
);
96 /// getFunctionOrMethodNumParams - Return number of function or method
97 /// parameters. It is an error to call this on a K&R function (use
98 /// hasFunctionProto first).
99 static unsigned getFunctionOrMethodNumParams(const Decl
*D
) {
100 if (const FunctionType
*FnTy
= D
->getFunctionType())
101 return cast
<FunctionProtoType
>(FnTy
)->getNumParams();
102 if (const auto *BD
= dyn_cast
<BlockDecl
>(D
))
103 return BD
->getNumParams();
104 return cast
<ObjCMethodDecl
>(D
)->param_size();
107 static const ParmVarDecl
*getFunctionOrMethodParam(const Decl
*D
,
109 if (const auto *FD
= dyn_cast
<FunctionDecl
>(D
))
110 return FD
->getParamDecl(Idx
);
111 if (const auto *MD
= dyn_cast
<ObjCMethodDecl
>(D
))
112 return MD
->getParamDecl(Idx
);
113 if (const auto *BD
= dyn_cast
<BlockDecl
>(D
))
114 return BD
->getParamDecl(Idx
);
118 static QualType
getFunctionOrMethodParamType(const Decl
*D
, unsigned Idx
) {
119 if (const FunctionType
*FnTy
= D
->getFunctionType())
120 return cast
<FunctionProtoType
>(FnTy
)->getParamType(Idx
);
121 if (const auto *BD
= dyn_cast
<BlockDecl
>(D
))
122 return BD
->getParamDecl(Idx
)->getType();
124 return cast
<ObjCMethodDecl
>(D
)->parameters()[Idx
]->getType();
127 static SourceRange
getFunctionOrMethodParamRange(const Decl
*D
, unsigned Idx
) {
128 if (auto *PVD
= getFunctionOrMethodParam(D
, Idx
))
129 return PVD
->getSourceRange();
130 return SourceRange();
133 static QualType
getFunctionOrMethodResultType(const Decl
*D
) {
134 if (const FunctionType
*FnTy
= D
->getFunctionType())
135 return FnTy
->getReturnType();
136 return cast
<ObjCMethodDecl
>(D
)->getReturnType();
139 static SourceRange
getFunctionOrMethodResultSourceRange(const Decl
*D
) {
140 if (const auto *FD
= dyn_cast
<FunctionDecl
>(D
))
141 return FD
->getReturnTypeSourceRange();
142 if (const auto *MD
= dyn_cast
<ObjCMethodDecl
>(D
))
143 return MD
->getReturnTypeSourceRange();
144 return SourceRange();
147 static bool isFunctionOrMethodVariadic(const Decl
*D
) {
148 if (const FunctionType
*FnTy
= D
->getFunctionType())
149 return cast
<FunctionProtoType
>(FnTy
)->isVariadic();
150 if (const auto *BD
= dyn_cast
<BlockDecl
>(D
))
151 return BD
->isVariadic();
152 return cast
<ObjCMethodDecl
>(D
)->isVariadic();
155 static bool isInstanceMethod(const Decl
*D
) {
156 if (const auto *MethodDecl
= dyn_cast
<CXXMethodDecl
>(D
))
157 return MethodDecl
->isInstance();
161 static inline bool isNSStringType(QualType T
, ASTContext
&Ctx
,
162 bool AllowNSAttributedString
= false) {
163 const auto *PT
= T
->getAs
<ObjCObjectPointerType
>();
167 ObjCInterfaceDecl
*Cls
= PT
->getObjectType()->getInterface();
171 IdentifierInfo
* ClsName
= Cls
->getIdentifier();
173 if (AllowNSAttributedString
&&
174 ClsName
== &Ctx
.Idents
.get("NSAttributedString"))
176 // FIXME: Should we walk the chain of classes?
177 return ClsName
== &Ctx
.Idents
.get("NSString") ||
178 ClsName
== &Ctx
.Idents
.get("NSMutableString");
181 static inline bool isCFStringType(QualType T
, ASTContext
&Ctx
) {
182 const auto *PT
= T
->getAs
<PointerType
>();
186 const auto *RT
= PT
->getPointeeType()->getAs
<RecordType
>();
190 const RecordDecl
*RD
= RT
->getDecl();
191 if (RD
->getTagKind() != TTK_Struct
)
194 return RD
->getIdentifier() == &Ctx
.Idents
.get("__CFString");
197 static unsigned getNumAttributeArgs(const ParsedAttr
&AL
) {
198 // FIXME: Include the type in the argument list.
199 return AL
.getNumArgs() + AL
.hasParsedType();
202 /// A helper function to provide Attribute Location for the Attr types
203 /// AND the ParsedAttr.
204 template <typename AttrInfo
>
205 static std::enable_if_t
<std::is_base_of_v
<Attr
, AttrInfo
>, SourceLocation
>
206 getAttrLoc(const AttrInfo
&AL
) {
207 return AL
.getLocation();
209 static SourceLocation
getAttrLoc(const ParsedAttr
&AL
) { return AL
.getLoc(); }
211 /// If Expr is a valid integer constant, get the value of the integer
212 /// expression and return success or failure. May output an error.
214 /// Negative argument is implicitly converted to unsigned, unless
215 /// \p StrictlyUnsigned is true.
216 template <typename AttrInfo
>
217 static bool checkUInt32Argument(Sema
&S
, const AttrInfo
&AI
, const Expr
*Expr
,
218 uint32_t &Val
, unsigned Idx
= UINT_MAX
,
219 bool StrictlyUnsigned
= false) {
220 std::optional
<llvm::APSInt
> I
= llvm::APSInt(32);
221 if (Expr
->isTypeDependent() ||
222 !(I
= Expr
->getIntegerConstantExpr(S
.Context
))) {
224 S
.Diag(getAttrLoc(AI
), diag::err_attribute_argument_n_type
)
225 << &AI
<< Idx
<< AANT_ArgumentIntegerConstant
226 << Expr
->getSourceRange();
228 S
.Diag(getAttrLoc(AI
), diag::err_attribute_argument_type
)
229 << &AI
<< AANT_ArgumentIntegerConstant
<< Expr
->getSourceRange();
233 if (!I
->isIntN(32)) {
234 S
.Diag(Expr
->getExprLoc(), diag::err_ice_too_large
)
235 << toString(*I
, 10, false) << 32 << /* Unsigned */ 1;
239 if (StrictlyUnsigned
&& I
->isSigned() && I
->isNegative()) {
240 S
.Diag(getAttrLoc(AI
), diag::err_attribute_requires_positive_integer
)
241 << &AI
<< /*non-negative*/ 1;
245 Val
= (uint32_t)I
->getZExtValue();
249 /// Wrapper around checkUInt32Argument, with an extra check to be sure
250 /// that the result will fit into a regular (signed) int. All args have the same
251 /// purpose as they do in checkUInt32Argument.
252 template <typename AttrInfo
>
253 static bool checkPositiveIntArgument(Sema
&S
, const AttrInfo
&AI
, const Expr
*Expr
,
254 int &Val
, unsigned Idx
= UINT_MAX
) {
256 if (!checkUInt32Argument(S
, AI
, Expr
, UVal
, Idx
))
259 if (UVal
> (uint32_t)std::numeric_limits
<int>::max()) {
260 llvm::APSInt
I(32); // for toString
262 S
.Diag(Expr
->getExprLoc(), diag::err_ice_too_large
)
263 << toString(I
, 10, false) << 32 << /* Unsigned */ 0;
271 /// Diagnose mutually exclusive attributes when present on a given
272 /// declaration. Returns true if diagnosed.
273 template <typename AttrTy
>
274 static bool checkAttrMutualExclusion(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
275 if (const auto *A
= D
->getAttr
<AttrTy
>()) {
276 S
.Diag(AL
.getLoc(), diag::err_attributes_are_not_compatible
) << AL
<< A
;
277 S
.Diag(A
->getLocation(), diag::note_conflicting_attribute
);
283 template <typename AttrTy
>
284 static bool checkAttrMutualExclusion(Sema
&S
, Decl
*D
, const Attr
&AL
) {
285 if (const auto *A
= D
->getAttr
<AttrTy
>()) {
286 S
.Diag(AL
.getLocation(), diag::err_attributes_are_not_compatible
) << &AL
288 S
.Diag(A
->getLocation(), diag::note_conflicting_attribute
);
294 /// Check if IdxExpr is a valid parameter index for a function or
295 /// instance method D. May output an error.
297 /// \returns true if IdxExpr is a valid index.
298 template <typename AttrInfo
>
299 static bool checkFunctionOrMethodParameterIndex(
300 Sema
&S
, const Decl
*D
, const AttrInfo
&AI
, unsigned AttrArgNum
,
301 const Expr
*IdxExpr
, ParamIdx
&Idx
, bool CanIndexImplicitThis
= false) {
302 assert(isFunctionOrMethodOrBlock(D
));
304 // In C++ the implicit 'this' function parameter also counts.
305 // Parameters are counted from one.
306 bool HP
= hasFunctionProto(D
);
307 bool HasImplicitThisParam
= isInstanceMethod(D
);
308 bool IV
= HP
&& isFunctionOrMethodVariadic(D
);
310 (HP
? getFunctionOrMethodNumParams(D
) : 0) + HasImplicitThisParam
;
312 std::optional
<llvm::APSInt
> IdxInt
;
313 if (IdxExpr
->isTypeDependent() ||
314 !(IdxInt
= IdxExpr
->getIntegerConstantExpr(S
.Context
))) {
315 S
.Diag(getAttrLoc(AI
), diag::err_attribute_argument_n_type
)
316 << &AI
<< AttrArgNum
<< AANT_ArgumentIntegerConstant
317 << IdxExpr
->getSourceRange();
321 unsigned IdxSource
= IdxInt
->getLimitedValue(UINT_MAX
);
322 if (IdxSource
< 1 || (!IV
&& IdxSource
> NumParams
)) {
323 S
.Diag(getAttrLoc(AI
), diag::err_attribute_argument_out_of_bounds
)
324 << &AI
<< AttrArgNum
<< IdxExpr
->getSourceRange();
327 if (HasImplicitThisParam
&& !CanIndexImplicitThis
) {
328 if (IdxSource
== 1) {
329 S
.Diag(getAttrLoc(AI
), diag::err_attribute_invalid_implicit_this_argument
)
330 << &AI
<< IdxExpr
->getSourceRange();
335 Idx
= ParamIdx(IdxSource
, D
);
339 /// Check if the argument \p E is a ASCII string literal. If not emit an error
340 /// and return false, otherwise set \p Str to the value of the string literal
342 bool Sema::checkStringLiteralArgumentAttr(const AttributeCommonInfo
&CI
,
343 const Expr
*E
, StringRef
&Str
,
344 SourceLocation
*ArgLocation
) {
345 const auto *Literal
= dyn_cast
<StringLiteral
>(E
->IgnoreParenCasts());
347 *ArgLocation
= E
->getBeginLoc();
349 if (!Literal
|| !Literal
->isOrdinary()) {
350 Diag(E
->getBeginLoc(), diag::err_attribute_argument_type
)
351 << CI
<< AANT_ArgumentString
;
355 Str
= Literal
->getString();
359 /// Check if the argument \p ArgNum of \p Attr is a ASCII string literal.
360 /// If not emit an error and return false. If the argument is an identifier it
361 /// will emit an error with a fixit hint and treat it as if it was a string
363 bool Sema::checkStringLiteralArgumentAttr(const ParsedAttr
&AL
, unsigned ArgNum
,
365 SourceLocation
*ArgLocation
) {
366 // Look for identifiers. If we have one emit a hint to fix it to a literal.
367 if (AL
.isArgIdent(ArgNum
)) {
368 IdentifierLoc
*Loc
= AL
.getArgAsIdent(ArgNum
);
369 Diag(Loc
->Loc
, diag::err_attribute_argument_type
)
370 << AL
<< AANT_ArgumentString
371 << FixItHint::CreateInsertion(Loc
->Loc
, "\"")
372 << FixItHint::CreateInsertion(getLocForEndOfToken(Loc
->Loc
), "\"");
373 Str
= Loc
->Ident
->getName();
375 *ArgLocation
= Loc
->Loc
;
379 // Now check for an actual string literal.
380 Expr
*ArgExpr
= AL
.getArgAsExpr(ArgNum
);
381 return checkStringLiteralArgumentAttr(AL
, ArgExpr
, Str
, ArgLocation
);
384 /// Applies the given attribute to the Decl without performing any
385 /// additional semantic checking.
386 template <typename AttrType
>
387 static void handleSimpleAttribute(Sema
&S
, Decl
*D
,
388 const AttributeCommonInfo
&CI
) {
389 D
->addAttr(::new (S
.Context
) AttrType(S
.Context
, CI
));
392 template <typename
... DiagnosticArgs
>
393 static const Sema::SemaDiagnosticBuilder
&
394 appendDiagnostics(const Sema::SemaDiagnosticBuilder
&Bldr
) {
398 template <typename T
, typename
... DiagnosticArgs
>
399 static const Sema::SemaDiagnosticBuilder
&
400 appendDiagnostics(const Sema::SemaDiagnosticBuilder
&Bldr
, T
&&ExtraArg
,
401 DiagnosticArgs
&&... ExtraArgs
) {
402 return appendDiagnostics(Bldr
<< std::forward
<T
>(ExtraArg
),
403 std::forward
<DiagnosticArgs
>(ExtraArgs
)...);
406 /// Add an attribute @c AttrType to declaration @c D, provided that
407 /// @c PassesCheck is true.
408 /// Otherwise, emit diagnostic @c DiagID, passing in all parameters
409 /// specified in @c ExtraArgs.
410 template <typename AttrType
, typename
... DiagnosticArgs
>
411 static void handleSimpleAttributeOrDiagnose(Sema
&S
, Decl
*D
,
412 const AttributeCommonInfo
&CI
,
413 bool PassesCheck
, unsigned DiagID
,
414 DiagnosticArgs
&&... ExtraArgs
) {
416 Sema::SemaDiagnosticBuilder DB
= S
.Diag(D
->getBeginLoc(), DiagID
);
417 appendDiagnostics(DB
, std::forward
<DiagnosticArgs
>(ExtraArgs
)...);
420 handleSimpleAttribute
<AttrType
>(S
, D
, CI
);
423 /// Check if the passed-in expression is of type int or bool.
424 static bool isIntOrBool(Expr
*Exp
) {
425 QualType QT
= Exp
->getType();
426 return QT
->isBooleanType() || QT
->isIntegerType();
430 // Check to see if the type is a smart pointer of some kind. We assume
431 // it's a smart pointer if it defines both operator-> and operator*.
432 static bool threadSafetyCheckIsSmartPointer(Sema
&S
, const RecordType
* RT
) {
433 auto IsOverloadedOperatorPresent
= [&S
](const RecordDecl
*Record
,
434 OverloadedOperatorKind Op
) {
435 DeclContextLookupResult Result
=
436 Record
->lookup(S
.Context
.DeclarationNames
.getCXXOperatorName(Op
));
437 return !Result
.empty();
440 const RecordDecl
*Record
= RT
->getDecl();
441 bool foundStarOperator
= IsOverloadedOperatorPresent(Record
, OO_Star
);
442 bool foundArrowOperator
= IsOverloadedOperatorPresent(Record
, OO_Arrow
);
443 if (foundStarOperator
&& foundArrowOperator
)
446 const CXXRecordDecl
*CXXRecord
= dyn_cast
<CXXRecordDecl
>(Record
);
450 for (auto BaseSpecifier
: CXXRecord
->bases()) {
451 if (!foundStarOperator
)
452 foundStarOperator
= IsOverloadedOperatorPresent(
453 BaseSpecifier
.getType()->getAsRecordDecl(), OO_Star
);
454 if (!foundArrowOperator
)
455 foundArrowOperator
= IsOverloadedOperatorPresent(
456 BaseSpecifier
.getType()->getAsRecordDecl(), OO_Arrow
);
459 if (foundStarOperator
&& foundArrowOperator
)
465 /// Check if passed in Decl is a pointer type.
466 /// Note that this function may produce an error message.
467 /// \return true if the Decl is a pointer type; false otherwise
468 static bool threadSafetyCheckIsPointer(Sema
&S
, const Decl
*D
,
469 const ParsedAttr
&AL
) {
470 const auto *VD
= cast
<ValueDecl
>(D
);
471 QualType QT
= VD
->getType();
472 if (QT
->isAnyPointerType())
475 if (const auto *RT
= QT
->getAs
<RecordType
>()) {
476 // If it's an incomplete type, it could be a smart pointer; skip it.
477 // (We don't want to force template instantiation if we can avoid it,
478 // since that would alter the order in which templates are instantiated.)
479 if (RT
->isIncompleteType())
482 if (threadSafetyCheckIsSmartPointer(S
, RT
))
486 S
.Diag(AL
.getLoc(), diag::warn_thread_attribute_decl_not_pointer
) << AL
<< QT
;
490 /// Checks that the passed in QualType either is of RecordType or points
491 /// to RecordType. Returns the relevant RecordType, null if it does not exit.
492 static const RecordType
*getRecordType(QualType QT
) {
493 if (const auto *RT
= QT
->getAs
<RecordType
>())
496 // Now check if we point to record type.
497 if (const auto *PT
= QT
->getAs
<PointerType
>())
498 return PT
->getPointeeType()->getAs
<RecordType
>();
503 template <typename AttrType
>
504 static bool checkRecordDeclForAttr(const RecordDecl
*RD
) {
505 // Check if the record itself has the attribute.
506 if (RD
->hasAttr
<AttrType
>())
509 // Else check if any base classes have the attribute.
510 if (const auto *CRD
= dyn_cast
<CXXRecordDecl
>(RD
)) {
511 if (!CRD
->forallBases([](const CXXRecordDecl
*Base
) {
512 return !Base
->hasAttr
<AttrType
>();
519 static bool checkRecordTypeForCapability(Sema
&S
, QualType Ty
) {
520 const RecordType
*RT
= getRecordType(Ty
);
525 // Don't check for the capability if the class hasn't been defined yet.
526 if (RT
->isIncompleteType())
529 // Allow smart pointers to be used as capability objects.
530 // FIXME -- Check the type that the smart pointer points to.
531 if (threadSafetyCheckIsSmartPointer(S
, RT
))
534 return checkRecordDeclForAttr
<CapabilityAttr
>(RT
->getDecl());
537 static bool checkTypedefTypeForCapability(QualType Ty
) {
538 const auto *TD
= Ty
->getAs
<TypedefType
>();
542 TypedefNameDecl
*TN
= TD
->getDecl();
546 return TN
->hasAttr
<CapabilityAttr
>();
549 static bool typeHasCapability(Sema
&S
, QualType Ty
) {
550 if (checkTypedefTypeForCapability(Ty
))
553 if (checkRecordTypeForCapability(S
, Ty
))
559 static bool isCapabilityExpr(Sema
&S
, const Expr
*Ex
) {
560 // Capability expressions are simple expressions involving the boolean logic
561 // operators &&, || or !, a simple DeclRefExpr, CastExpr or a ParenExpr. Once
562 // a DeclRefExpr is found, its type should be checked to determine whether it
563 // is a capability or not.
565 if (const auto *E
= dyn_cast
<CastExpr
>(Ex
))
566 return isCapabilityExpr(S
, E
->getSubExpr());
567 else if (const auto *E
= dyn_cast
<ParenExpr
>(Ex
))
568 return isCapabilityExpr(S
, E
->getSubExpr());
569 else if (const auto *E
= dyn_cast
<UnaryOperator
>(Ex
)) {
570 if (E
->getOpcode() == UO_LNot
|| E
->getOpcode() == UO_AddrOf
||
571 E
->getOpcode() == UO_Deref
)
572 return isCapabilityExpr(S
, E
->getSubExpr());
574 } else if (const auto *E
= dyn_cast
<BinaryOperator
>(Ex
)) {
575 if (E
->getOpcode() == BO_LAnd
|| E
->getOpcode() == BO_LOr
)
576 return isCapabilityExpr(S
, E
->getLHS()) &&
577 isCapabilityExpr(S
, E
->getRHS());
581 return typeHasCapability(S
, Ex
->getType());
584 /// Checks that all attribute arguments, starting from Sidx, resolve to
585 /// a capability object.
586 /// \param Sidx The attribute argument index to start checking with.
587 /// \param ParamIdxOk Whether an argument can be indexing into a function
589 static void checkAttrArgsAreCapabilityObjs(Sema
&S
, Decl
*D
,
590 const ParsedAttr
&AL
,
591 SmallVectorImpl
<Expr
*> &Args
,
593 bool ParamIdxOk
= false) {
594 if (Sidx
== AL
.getNumArgs()) {
595 // If we don't have any capability arguments, the attribute implicitly
596 // refers to 'this'. So we need to make sure that 'this' exists, i.e. we're
597 // a non-static method, and that the class is a (scoped) capability.
598 const auto *MD
= dyn_cast
<const CXXMethodDecl
>(D
);
599 if (MD
&& !MD
->isStatic()) {
600 const CXXRecordDecl
*RD
= MD
->getParent();
601 // FIXME -- need to check this again on template instantiation
602 if (!checkRecordDeclForAttr
<CapabilityAttr
>(RD
) &&
603 !checkRecordDeclForAttr
<ScopedLockableAttr
>(RD
))
605 diag::warn_thread_attribute_not_on_capability_member
)
606 << AL
<< MD
->getParent();
608 S
.Diag(AL
.getLoc(), diag::warn_thread_attribute_not_on_non_static_member
)
613 for (unsigned Idx
= Sidx
; Idx
< AL
.getNumArgs(); ++Idx
) {
614 Expr
*ArgExp
= AL
.getArgAsExpr(Idx
);
616 if (ArgExp
->isTypeDependent()) {
617 // FIXME -- need to check this again on template instantiation
618 Args
.push_back(ArgExp
);
622 if (const auto *StrLit
= dyn_cast
<StringLiteral
>(ArgExp
)) {
623 if (StrLit
->getLength() == 0 ||
624 (StrLit
->isOrdinary() && StrLit
->getString() == StringRef("*"))) {
625 // Pass empty strings to the analyzer without warnings.
626 // Treat "*" as the universal lock.
627 Args
.push_back(ArgExp
);
631 // We allow constant strings to be used as a placeholder for expressions
632 // that are not valid C++ syntax, but warn that they are ignored.
633 S
.Diag(AL
.getLoc(), diag::warn_thread_attribute_ignored
) << AL
;
634 Args
.push_back(ArgExp
);
638 QualType ArgTy
= ArgExp
->getType();
640 // A pointer to member expression of the form &MyClass::mu is treated
641 // specially -- we need to look at the type of the member.
642 if (const auto *UOp
= dyn_cast
<UnaryOperator
>(ArgExp
))
643 if (UOp
->getOpcode() == UO_AddrOf
)
644 if (const auto *DRE
= dyn_cast
<DeclRefExpr
>(UOp
->getSubExpr()))
645 if (DRE
->getDecl()->isCXXInstanceMember())
646 ArgTy
= DRE
->getDecl()->getType();
648 // First see if we can just cast to record type, or pointer to record type.
649 const RecordType
*RT
= getRecordType(ArgTy
);
651 // Now check if we index into a record type function param.
652 if(!RT
&& ParamIdxOk
) {
653 const auto *FD
= dyn_cast
<FunctionDecl
>(D
);
654 const auto *IL
= dyn_cast
<IntegerLiteral
>(ArgExp
);
656 unsigned int NumParams
= FD
->getNumParams();
657 llvm::APInt ArgValue
= IL
->getValue();
658 uint64_t ParamIdxFromOne
= ArgValue
.getZExtValue();
659 uint64_t ParamIdxFromZero
= ParamIdxFromOne
- 1;
660 if (!ArgValue
.isStrictlyPositive() || ParamIdxFromOne
> NumParams
) {
662 diag::err_attribute_argument_out_of_bounds_extra_info
)
663 << AL
<< Idx
+ 1 << NumParams
;
666 ArgTy
= FD
->getParamDecl(ParamIdxFromZero
)->getType();
670 // If the type does not have a capability, see if the components of the
671 // expression have capabilities. This allows for writing C code where the
672 // capability may be on the type, and the expression is a capability
673 // boolean logic expression. Eg) requires_capability(A || B && !C)
674 if (!typeHasCapability(S
, ArgTy
) && !isCapabilityExpr(S
, ArgExp
))
675 S
.Diag(AL
.getLoc(), diag::warn_thread_attribute_argument_not_lockable
)
678 Args
.push_back(ArgExp
);
682 //===----------------------------------------------------------------------===//
683 // Attribute Implementations
684 //===----------------------------------------------------------------------===//
686 static void handlePtGuardedVarAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
687 if (!threadSafetyCheckIsPointer(S
, D
, AL
))
690 D
->addAttr(::new (S
.Context
) PtGuardedVarAttr(S
.Context
, AL
));
693 static bool checkGuardedByAttrCommon(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
,
695 SmallVector
<Expr
*, 1> Args
;
696 // check that all arguments are lockable objects
697 checkAttrArgsAreCapabilityObjs(S
, D
, AL
, Args
);
698 unsigned Size
= Args
.size();
707 static void handleGuardedByAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
709 if (!checkGuardedByAttrCommon(S
, D
, AL
, Arg
))
712 D
->addAttr(::new (S
.Context
) GuardedByAttr(S
.Context
, AL
, Arg
));
715 static void handlePtGuardedByAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
717 if (!checkGuardedByAttrCommon(S
, D
, AL
, Arg
))
720 if (!threadSafetyCheckIsPointer(S
, D
, AL
))
723 D
->addAttr(::new (S
.Context
) PtGuardedByAttr(S
.Context
, AL
, Arg
));
726 static bool checkAcquireOrderAttrCommon(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
,
727 SmallVectorImpl
<Expr
*> &Args
) {
728 if (!AL
.checkAtLeastNumArgs(S
, 1))
731 // Check that this attribute only applies to lockable types.
732 QualType QT
= cast
<ValueDecl
>(D
)->getType();
733 if (!QT
->isDependentType() && !typeHasCapability(S
, QT
)) {
734 S
.Diag(AL
.getLoc(), diag::warn_thread_attribute_decl_not_lockable
) << AL
;
738 // Check that all arguments are lockable objects.
739 checkAttrArgsAreCapabilityObjs(S
, D
, AL
, Args
);
746 static void handleAcquiredAfterAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
747 SmallVector
<Expr
*, 1> Args
;
748 if (!checkAcquireOrderAttrCommon(S
, D
, AL
, Args
))
751 Expr
**StartArg
= &Args
[0];
752 D
->addAttr(::new (S
.Context
)
753 AcquiredAfterAttr(S
.Context
, AL
, StartArg
, Args
.size()));
756 static void handleAcquiredBeforeAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
757 SmallVector
<Expr
*, 1> Args
;
758 if (!checkAcquireOrderAttrCommon(S
, D
, AL
, Args
))
761 Expr
**StartArg
= &Args
[0];
762 D
->addAttr(::new (S
.Context
)
763 AcquiredBeforeAttr(S
.Context
, AL
, StartArg
, Args
.size()));
766 static bool checkLockFunAttrCommon(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
,
767 SmallVectorImpl
<Expr
*> &Args
) {
768 // zero or more arguments ok
769 // check that all arguments are lockable objects
770 checkAttrArgsAreCapabilityObjs(S
, D
, AL
, Args
, 0, /*ParamIdxOk=*/true);
775 static void handleAssertSharedLockAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
776 SmallVector
<Expr
*, 1> Args
;
777 if (!checkLockFunAttrCommon(S
, D
, AL
, Args
))
780 unsigned Size
= Args
.size();
781 Expr
**StartArg
= Size
== 0 ? nullptr : &Args
[0];
782 D
->addAttr(::new (S
.Context
)
783 AssertSharedLockAttr(S
.Context
, AL
, StartArg
, Size
));
786 static void handleAssertExclusiveLockAttr(Sema
&S
, Decl
*D
,
787 const ParsedAttr
&AL
) {
788 SmallVector
<Expr
*, 1> Args
;
789 if (!checkLockFunAttrCommon(S
, D
, AL
, Args
))
792 unsigned Size
= Args
.size();
793 Expr
**StartArg
= Size
== 0 ? nullptr : &Args
[0];
794 D
->addAttr(::new (S
.Context
)
795 AssertExclusiveLockAttr(S
.Context
, AL
, StartArg
, Size
));
798 /// Checks to be sure that the given parameter number is in bounds, and
799 /// is an integral type. Will emit appropriate diagnostics if this returns
802 /// AttrArgNo is used to actually retrieve the argument, so it's base-0.
803 template <typename AttrInfo
>
804 static bool checkParamIsIntegerType(Sema
&S
, const Decl
*D
, const AttrInfo
&AI
,
805 unsigned AttrArgNo
) {
806 assert(AI
.isArgExpr(AttrArgNo
) && "Expected expression argument");
807 Expr
*AttrArg
= AI
.getArgAsExpr(AttrArgNo
);
809 if (!checkFunctionOrMethodParameterIndex(S
, D
, AI
, AttrArgNo
+ 1, AttrArg
,
813 QualType ParamTy
= getFunctionOrMethodParamType(D
, Idx
.getASTIndex());
814 if (!ParamTy
->isIntegerType() && !ParamTy
->isCharType()) {
815 SourceLocation SrcLoc
= AttrArg
->getBeginLoc();
816 S
.Diag(SrcLoc
, diag::err_attribute_integers_only
)
817 << AI
<< getFunctionOrMethodParamRange(D
, Idx
.getASTIndex());
823 static void handleAllocSizeAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
824 if (!AL
.checkAtLeastNumArgs(S
, 1) || !AL
.checkAtMostNumArgs(S
, 2))
827 assert(isFunctionOrMethod(D
) && hasFunctionProto(D
));
829 QualType RetTy
= getFunctionOrMethodResultType(D
);
830 if (!RetTy
->isPointerType()) {
831 S
.Diag(AL
.getLoc(), diag::warn_attribute_return_pointers_only
) << AL
;
835 const Expr
*SizeExpr
= AL
.getArgAsExpr(0);
837 // Parameter indices are 1-indexed, hence Index=1
838 if (!checkPositiveIntArgument(S
, AL
, SizeExpr
, SizeArgNoVal
, /*Idx=*/1))
840 if (!checkParamIsIntegerType(S
, D
, AL
, /*AttrArgNo=*/0))
842 ParamIdx
SizeArgNo(SizeArgNoVal
, D
);
844 ParamIdx NumberArgNo
;
845 if (AL
.getNumArgs() == 2) {
846 const Expr
*NumberExpr
= AL
.getArgAsExpr(1);
848 // Parameter indices are 1-based, hence Index=2
849 if (!checkPositiveIntArgument(S
, AL
, NumberExpr
, Val
, /*Idx=*/2))
851 if (!checkParamIsIntegerType(S
, D
, AL
, /*AttrArgNo=*/1))
853 NumberArgNo
= ParamIdx(Val
, D
);
856 D
->addAttr(::new (S
.Context
)
857 AllocSizeAttr(S
.Context
, AL
, SizeArgNo
, NumberArgNo
));
860 static bool checkTryLockFunAttrCommon(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
,
861 SmallVectorImpl
<Expr
*> &Args
) {
862 if (!AL
.checkAtLeastNumArgs(S
, 1))
865 if (!isIntOrBool(AL
.getArgAsExpr(0))) {
866 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_n_type
)
867 << AL
<< 1 << AANT_ArgumentIntOrBool
;
871 // check that all arguments are lockable objects
872 checkAttrArgsAreCapabilityObjs(S
, D
, AL
, Args
, 1);
877 static void handleSharedTrylockFunctionAttr(Sema
&S
, Decl
*D
,
878 const ParsedAttr
&AL
) {
879 SmallVector
<Expr
*, 2> Args
;
880 if (!checkTryLockFunAttrCommon(S
, D
, AL
, Args
))
883 D
->addAttr(::new (S
.Context
) SharedTrylockFunctionAttr(
884 S
.Context
, AL
, AL
.getArgAsExpr(0), Args
.data(), Args
.size()));
887 static void handleExclusiveTrylockFunctionAttr(Sema
&S
, Decl
*D
,
888 const ParsedAttr
&AL
) {
889 SmallVector
<Expr
*, 2> Args
;
890 if (!checkTryLockFunAttrCommon(S
, D
, AL
, Args
))
893 D
->addAttr(::new (S
.Context
) ExclusiveTrylockFunctionAttr(
894 S
.Context
, AL
, AL
.getArgAsExpr(0), Args
.data(), Args
.size()));
897 static void handleLockReturnedAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
898 // check that the argument is lockable object
899 SmallVector
<Expr
*, 1> Args
;
900 checkAttrArgsAreCapabilityObjs(S
, D
, AL
, Args
);
901 unsigned Size
= Args
.size();
905 D
->addAttr(::new (S
.Context
) LockReturnedAttr(S
.Context
, AL
, Args
[0]));
908 static void handleLocksExcludedAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
909 if (!AL
.checkAtLeastNumArgs(S
, 1))
912 // check that all arguments are lockable objects
913 SmallVector
<Expr
*, 1> Args
;
914 checkAttrArgsAreCapabilityObjs(S
, D
, AL
, Args
);
915 unsigned Size
= Args
.size();
918 Expr
**StartArg
= &Args
[0];
920 D
->addAttr(::new (S
.Context
)
921 LocksExcludedAttr(S
.Context
, AL
, StartArg
, Size
));
924 static bool checkFunctionConditionAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
,
925 Expr
*&Cond
, StringRef
&Msg
) {
926 Cond
= AL
.getArgAsExpr(0);
927 if (!Cond
->isTypeDependent()) {
928 ExprResult Converted
= S
.PerformContextuallyConvertToBool(Cond
);
929 if (Converted
.isInvalid())
931 Cond
= Converted
.get();
934 if (!S
.checkStringLiteralArgumentAttr(AL
, 1, Msg
))
938 Msg
= "<no message provided>";
940 SmallVector
<PartialDiagnosticAt
, 8> Diags
;
941 if (isa
<FunctionDecl
>(D
) && !Cond
->isValueDependent() &&
942 !Expr::isPotentialConstantExprUnevaluated(Cond
, cast
<FunctionDecl
>(D
),
944 S
.Diag(AL
.getLoc(), diag::err_attr_cond_never_constant_expr
) << AL
;
945 for (const PartialDiagnosticAt
&PDiag
: Diags
)
946 S
.Diag(PDiag
.first
, PDiag
.second
);
952 static void handleEnableIfAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
953 S
.Diag(AL
.getLoc(), diag::ext_clang_enable_if
);
957 if (checkFunctionConditionAttr(S
, D
, AL
, Cond
, Msg
))
958 D
->addAttr(::new (S
.Context
) EnableIfAttr(S
.Context
, AL
, Cond
, Msg
));
961 static void handleErrorAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
962 StringRef NewUserDiagnostic
;
963 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, NewUserDiagnostic
))
965 if (ErrorAttr
*EA
= S
.mergeErrorAttr(D
, AL
, NewUserDiagnostic
))
970 /// Determines if a given Expr references any of the given function's
971 /// ParmVarDecls, or the function's implicit `this` parameter (if applicable).
972 class ArgumentDependenceChecker
973 : public RecursiveASTVisitor
<ArgumentDependenceChecker
> {
975 const CXXRecordDecl
*ClassType
;
977 llvm::SmallPtrSet
<const ParmVarDecl
*, 16> Parms
;
981 ArgumentDependenceChecker(const FunctionDecl
*FD
) {
983 if (const auto *MD
= dyn_cast
<CXXMethodDecl
>(FD
))
984 ClassType
= MD
->getParent();
988 Parms
.insert(FD
->param_begin(), FD
->param_end());
991 bool referencesArgs(Expr
*E
) {
997 bool VisitCXXThisExpr(CXXThisExpr
*E
) {
998 assert(E
->getType()->getPointeeCXXRecordDecl() == ClassType
&&
999 "`this` doesn't refer to the enclosing class?");
1004 bool VisitDeclRefExpr(DeclRefExpr
*DRE
) {
1005 if (const auto *PVD
= dyn_cast
<ParmVarDecl
>(DRE
->getDecl()))
1006 if (Parms
.count(PVD
)) {
1015 static void handleDiagnoseAsBuiltinAttr(Sema
&S
, Decl
*D
,
1016 const ParsedAttr
&AL
) {
1017 const auto *DeclFD
= cast
<FunctionDecl
>(D
);
1019 if (const auto *MethodDecl
= dyn_cast
<CXXMethodDecl
>(DeclFD
))
1020 if (!MethodDecl
->isStatic()) {
1021 S
.Diag(AL
.getLoc(), diag::err_attribute_no_member_function
) << AL
;
1025 auto DiagnoseType
= [&](unsigned Index
, AttributeArgumentNType T
) {
1026 SourceLocation Loc
= [&]() {
1027 auto Union
= AL
.getArg(Index
- 1);
1028 if (Union
.is
<Expr
*>())
1029 return Union
.get
<Expr
*>()->getBeginLoc();
1030 return Union
.get
<IdentifierLoc
*>()->Loc
;
1033 S
.Diag(Loc
, diag::err_attribute_argument_n_type
) << AL
<< Index
<< T
;
1036 FunctionDecl
*AttrFD
= [&]() -> FunctionDecl
* {
1037 if (!AL
.isArgExpr(0))
1039 auto *F
= dyn_cast_or_null
<DeclRefExpr
>(AL
.getArgAsExpr(0));
1042 return dyn_cast_or_null
<FunctionDecl
>(F
->getFoundDecl());
1045 if (!AttrFD
|| !AttrFD
->getBuiltinID(true)) {
1046 DiagnoseType(1, AANT_ArgumentBuiltinFunction
);
1050 if (AttrFD
->getNumParams() != AL
.getNumArgs() - 1) {
1051 S
.Diag(AL
.getLoc(), diag::err_attribute_wrong_number_arguments_for
)
1052 << AL
<< AttrFD
<< AttrFD
->getNumParams();
1056 SmallVector
<unsigned, 8> Indices
;
1058 for (unsigned I
= 1; I
< AL
.getNumArgs(); ++I
) {
1059 if (!AL
.isArgExpr(I
)) {
1060 DiagnoseType(I
+ 1, AANT_ArgumentIntegerConstant
);
1064 const Expr
*IndexExpr
= AL
.getArgAsExpr(I
);
1067 if (!checkUInt32Argument(S
, AL
, IndexExpr
, Index
, I
+ 1, false))
1070 if (Index
> DeclFD
->getNumParams()) {
1071 S
.Diag(AL
.getLoc(), diag::err_attribute_bounds_for_function
)
1072 << AL
<< Index
<< DeclFD
<< DeclFD
->getNumParams();
1076 QualType T1
= AttrFD
->getParamDecl(I
- 1)->getType();
1077 QualType T2
= DeclFD
->getParamDecl(Index
- 1)->getType();
1079 if (T1
.getCanonicalType().getUnqualifiedType() !=
1080 T2
.getCanonicalType().getUnqualifiedType()) {
1081 S
.Diag(IndexExpr
->getBeginLoc(), diag::err_attribute_parameter_types
)
1082 << AL
<< Index
<< DeclFD
<< T2
<< I
<< AttrFD
<< T1
;
1086 Indices
.push_back(Index
- 1);
1089 D
->addAttr(::new (S
.Context
) DiagnoseAsBuiltinAttr(
1090 S
.Context
, AL
, AttrFD
, Indices
.data(), Indices
.size()));
1093 static void handleDiagnoseIfAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1094 S
.Diag(AL
.getLoc(), diag::ext_clang_diagnose_if
);
1098 if (!checkFunctionConditionAttr(S
, D
, AL
, Cond
, Msg
))
1101 StringRef DiagTypeStr
;
1102 if (!S
.checkStringLiteralArgumentAttr(AL
, 2, DiagTypeStr
))
1105 DiagnoseIfAttr::DiagnosticType DiagType
;
1106 if (!DiagnoseIfAttr::ConvertStrToDiagnosticType(DiagTypeStr
, DiagType
)) {
1107 S
.Diag(AL
.getArgAsExpr(2)->getBeginLoc(),
1108 diag::err_diagnose_if_invalid_diagnostic_type
);
1112 bool ArgDependent
= false;
1113 if (const auto *FD
= dyn_cast
<FunctionDecl
>(D
))
1114 ArgDependent
= ArgumentDependenceChecker(FD
).referencesArgs(Cond
);
1115 D
->addAttr(::new (S
.Context
) DiagnoseIfAttr(
1116 S
.Context
, AL
, Cond
, Msg
, DiagType
, ArgDependent
, cast
<NamedDecl
>(D
)));
1119 static void handleNoBuiltinAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1120 static constexpr const StringRef kWildcard
= "*";
1122 llvm::SmallVector
<StringRef
, 16> Names
;
1123 bool HasWildcard
= false;
1125 const auto AddBuiltinName
= [&Names
, &HasWildcard
](StringRef Name
) {
1126 if (Name
== kWildcard
)
1128 Names
.push_back(Name
);
1131 // Add previously defined attributes.
1132 if (const auto *NBA
= D
->getAttr
<NoBuiltinAttr
>())
1133 for (StringRef BuiltinName
: NBA
->builtinNames())
1134 AddBuiltinName(BuiltinName
);
1136 // Add current attributes.
1137 if (AL
.getNumArgs() == 0)
1138 AddBuiltinName(kWildcard
);
1140 for (unsigned I
= 0, E
= AL
.getNumArgs(); I
!= E
; ++I
) {
1141 StringRef BuiltinName
;
1142 SourceLocation LiteralLoc
;
1143 if (!S
.checkStringLiteralArgumentAttr(AL
, I
, BuiltinName
, &LiteralLoc
))
1146 if (Builtin::Context::isBuiltinFunc(BuiltinName
))
1147 AddBuiltinName(BuiltinName
);
1149 S
.Diag(LiteralLoc
, diag::warn_attribute_no_builtin_invalid_builtin_name
)
1150 << BuiltinName
<< AL
;
1153 // Repeating the same attribute is fine.
1155 Names
.erase(std::unique(Names
.begin(), Names
.end()), Names
.end());
1157 // Empty no_builtin must be on its own.
1158 if (HasWildcard
&& Names
.size() > 1)
1159 S
.Diag(D
->getLocation(),
1160 diag::err_attribute_no_builtin_wildcard_or_builtin_name
)
1163 if (D
->hasAttr
<NoBuiltinAttr
>())
1164 D
->dropAttr
<NoBuiltinAttr
>();
1165 D
->addAttr(::new (S
.Context
)
1166 NoBuiltinAttr(S
.Context
, AL
, Names
.data(), Names
.size()));
1169 static void handlePassObjectSizeAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1170 if (D
->hasAttr
<PassObjectSizeAttr
>()) {
1171 S
.Diag(D
->getBeginLoc(), diag::err_attribute_only_once_per_parameter
) << AL
;
1175 Expr
*E
= AL
.getArgAsExpr(0);
1177 if (!checkUInt32Argument(S
, AL
, E
, Type
, /*Idx=*/1))
1180 // pass_object_size's argument is passed in as the second argument of
1181 // __builtin_object_size. So, it has the same constraints as that second
1182 // argument; namely, it must be in the range [0, 3].
1184 S
.Diag(E
->getBeginLoc(), diag::err_attribute_argument_out_of_range
)
1185 << AL
<< 0 << 3 << E
->getSourceRange();
1189 // pass_object_size is only supported on constant pointer parameters; as a
1190 // kindness to users, we allow the parameter to be non-const for declarations.
1191 // At this point, we have no clue if `D` belongs to a function declaration or
1192 // definition, so we defer the constness check until later.
1193 if (!cast
<ParmVarDecl
>(D
)->getType()->isPointerType()) {
1194 S
.Diag(D
->getBeginLoc(), diag::err_attribute_pointers_only
) << AL
<< 1;
1198 D
->addAttr(::new (S
.Context
) PassObjectSizeAttr(S
.Context
, AL
, (int)Type
));
1201 static void handleConsumableAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1202 ConsumableAttr::ConsumedState DefaultState
;
1204 if (AL
.isArgIdent(0)) {
1205 IdentifierLoc
*IL
= AL
.getArgAsIdent(0);
1206 if (!ConsumableAttr::ConvertStrToConsumedState(IL
->Ident
->getName(),
1208 S
.Diag(IL
->Loc
, diag::warn_attribute_type_not_supported
) << AL
1213 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_type
)
1214 << AL
<< AANT_ArgumentIdentifier
;
1218 D
->addAttr(::new (S
.Context
) ConsumableAttr(S
.Context
, AL
, DefaultState
));
1221 static bool checkForConsumableClass(Sema
&S
, const CXXMethodDecl
*MD
,
1222 const ParsedAttr
&AL
) {
1223 QualType ThisType
= MD
->getThisType()->getPointeeType();
1225 if (const CXXRecordDecl
*RD
= ThisType
->getAsCXXRecordDecl()) {
1226 if (!RD
->hasAttr
<ConsumableAttr
>()) {
1227 S
.Diag(AL
.getLoc(), diag::warn_attr_on_unconsumable_class
) << RD
;
1236 static void handleCallableWhenAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1237 if (!AL
.checkAtLeastNumArgs(S
, 1))
1240 if (!checkForConsumableClass(S
, cast
<CXXMethodDecl
>(D
), AL
))
1243 SmallVector
<CallableWhenAttr::ConsumedState
, 3> States
;
1244 for (unsigned ArgIndex
= 0; ArgIndex
< AL
.getNumArgs(); ++ArgIndex
) {
1245 CallableWhenAttr::ConsumedState CallableState
;
1247 StringRef StateString
;
1249 if (AL
.isArgIdent(ArgIndex
)) {
1250 IdentifierLoc
*Ident
= AL
.getArgAsIdent(ArgIndex
);
1251 StateString
= Ident
->Ident
->getName();
1254 if (!S
.checkStringLiteralArgumentAttr(AL
, ArgIndex
, StateString
, &Loc
))
1258 if (!CallableWhenAttr::ConvertStrToConsumedState(StateString
,
1260 S
.Diag(Loc
, diag::warn_attribute_type_not_supported
) << AL
<< StateString
;
1264 States
.push_back(CallableState
);
1267 D
->addAttr(::new (S
.Context
)
1268 CallableWhenAttr(S
.Context
, AL
, States
.data(), States
.size()));
1271 static void handleParamTypestateAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1272 ParamTypestateAttr::ConsumedState ParamState
;
1274 if (AL
.isArgIdent(0)) {
1275 IdentifierLoc
*Ident
= AL
.getArgAsIdent(0);
1276 StringRef StateString
= Ident
->Ident
->getName();
1278 if (!ParamTypestateAttr::ConvertStrToConsumedState(StateString
,
1280 S
.Diag(Ident
->Loc
, diag::warn_attribute_type_not_supported
)
1281 << AL
<< StateString
;
1285 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_type
)
1286 << AL
<< AANT_ArgumentIdentifier
;
1290 // FIXME: This check is currently being done in the analysis. It can be
1291 // enabled here only after the parser propagates attributes at
1292 // template specialization definition, not declaration.
1293 //QualType ReturnType = cast<ParmVarDecl>(D)->getType();
1294 //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1296 //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1297 // S.Diag(AL.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1298 // ReturnType.getAsString();
1302 D
->addAttr(::new (S
.Context
) ParamTypestateAttr(S
.Context
, AL
, ParamState
));
1305 static void handleReturnTypestateAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1306 ReturnTypestateAttr::ConsumedState ReturnState
;
1308 if (AL
.isArgIdent(0)) {
1309 IdentifierLoc
*IL
= AL
.getArgAsIdent(0);
1310 if (!ReturnTypestateAttr::ConvertStrToConsumedState(IL
->Ident
->getName(),
1312 S
.Diag(IL
->Loc
, diag::warn_attribute_type_not_supported
) << AL
1317 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_type
)
1318 << AL
<< AANT_ArgumentIdentifier
;
1322 // FIXME: This check is currently being done in the analysis. It can be
1323 // enabled here only after the parser propagates attributes at
1324 // template specialization definition, not declaration.
1325 //QualType ReturnType;
1327 //if (const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D)) {
1328 // ReturnType = Param->getType();
1330 //} else if (const CXXConstructorDecl *Constructor =
1331 // dyn_cast<CXXConstructorDecl>(D)) {
1332 // ReturnType = Constructor->getThisType()->getPointeeType();
1336 // ReturnType = cast<FunctionDecl>(D)->getCallResultType();
1339 //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1341 //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1342 // S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1343 // ReturnType.getAsString();
1347 D
->addAttr(::new (S
.Context
) ReturnTypestateAttr(S
.Context
, AL
, ReturnState
));
1350 static void handleSetTypestateAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1351 if (!checkForConsumableClass(S
, cast
<CXXMethodDecl
>(D
), AL
))
1354 SetTypestateAttr::ConsumedState NewState
;
1355 if (AL
.isArgIdent(0)) {
1356 IdentifierLoc
*Ident
= AL
.getArgAsIdent(0);
1357 StringRef Param
= Ident
->Ident
->getName();
1358 if (!SetTypestateAttr::ConvertStrToConsumedState(Param
, NewState
)) {
1359 S
.Diag(Ident
->Loc
, diag::warn_attribute_type_not_supported
) << AL
1364 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_type
)
1365 << AL
<< AANT_ArgumentIdentifier
;
1369 D
->addAttr(::new (S
.Context
) SetTypestateAttr(S
.Context
, AL
, NewState
));
1372 static void handleTestTypestateAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1373 if (!checkForConsumableClass(S
, cast
<CXXMethodDecl
>(D
), AL
))
1376 TestTypestateAttr::ConsumedState TestState
;
1377 if (AL
.isArgIdent(0)) {
1378 IdentifierLoc
*Ident
= AL
.getArgAsIdent(0);
1379 StringRef Param
= Ident
->Ident
->getName();
1380 if (!TestTypestateAttr::ConvertStrToConsumedState(Param
, TestState
)) {
1381 S
.Diag(Ident
->Loc
, diag::warn_attribute_type_not_supported
) << AL
1386 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_type
)
1387 << AL
<< AANT_ArgumentIdentifier
;
1391 D
->addAttr(::new (S
.Context
) TestTypestateAttr(S
.Context
, AL
, TestState
));
1394 static void handleExtVectorTypeAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1395 // Remember this typedef decl, we will need it later for diagnostics.
1396 S
.ExtVectorDecls
.push_back(cast
<TypedefNameDecl
>(D
));
1399 static void handlePackedAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1400 if (auto *TD
= dyn_cast
<TagDecl
>(D
))
1401 TD
->addAttr(::new (S
.Context
) PackedAttr(S
.Context
, AL
));
1402 else if (auto *FD
= dyn_cast
<FieldDecl
>(D
)) {
1403 bool BitfieldByteAligned
= (!FD
->getType()->isDependentType() &&
1404 !FD
->getType()->isIncompleteType() &&
1406 S
.Context
.getTypeAlign(FD
->getType()) <= 8);
1408 if (S
.getASTContext().getTargetInfo().getTriple().isPS()) {
1409 if (BitfieldByteAligned
)
1410 // The PS4/PS5 targets need to maintain ABI backwards compatibility.
1411 S
.Diag(AL
.getLoc(), diag::warn_attribute_ignored_for_field_of_type
)
1412 << AL
<< FD
->getType();
1414 FD
->addAttr(::new (S
.Context
) PackedAttr(S
.Context
, AL
));
1416 // Report warning about changed offset in the newer compiler versions.
1417 if (BitfieldByteAligned
)
1418 S
.Diag(AL
.getLoc(), diag::warn_attribute_packed_for_bitfield
);
1420 FD
->addAttr(::new (S
.Context
) PackedAttr(S
.Context
, AL
));
1424 S
.Diag(AL
.getLoc(), diag::warn_attribute_ignored
) << AL
;
1427 static void handlePreferredName(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1428 auto *RD
= cast
<CXXRecordDecl
>(D
);
1429 ClassTemplateDecl
*CTD
= RD
->getDescribedClassTemplate();
1430 assert(CTD
&& "attribute does not appertain to this declaration");
1432 ParsedType PT
= AL
.getTypeArg();
1433 TypeSourceInfo
*TSI
= nullptr;
1434 QualType T
= S
.GetTypeFromParser(PT
, &TSI
);
1436 TSI
= S
.Context
.getTrivialTypeSourceInfo(T
, AL
.getLoc());
1438 if (!T
.hasQualifiers() && T
->isTypedefNameType()) {
1439 // Find the template name, if this type names a template specialization.
1440 const TemplateDecl
*Template
= nullptr;
1441 if (const auto *CTSD
= dyn_cast_or_null
<ClassTemplateSpecializationDecl
>(
1442 T
->getAsCXXRecordDecl())) {
1443 Template
= CTSD
->getSpecializedTemplate();
1444 } else if (const auto *TST
= T
->getAs
<TemplateSpecializationType
>()) {
1445 while (TST
&& TST
->isTypeAlias())
1446 TST
= TST
->getAliasedType()->getAs
<TemplateSpecializationType
>();
1448 Template
= TST
->getTemplateName().getAsTemplateDecl();
1451 if (Template
&& declaresSameEntity(Template
, CTD
)) {
1452 D
->addAttr(::new (S
.Context
) PreferredNameAttr(S
.Context
, AL
, TSI
));
1457 S
.Diag(AL
.getLoc(), diag::err_attribute_preferred_name_arg_invalid
)
1459 if (const auto *TT
= T
->getAs
<TypedefType
>())
1460 S
.Diag(TT
->getDecl()->getLocation(), diag::note_entity_declared_at
)
1464 static bool checkIBOutletCommon(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1465 // The IBOutlet/IBOutletCollection attributes only apply to instance
1466 // variables or properties of Objective-C classes. The outlet must also
1467 // have an object reference type.
1468 if (const auto *VD
= dyn_cast
<ObjCIvarDecl
>(D
)) {
1469 if (!VD
->getType()->getAs
<ObjCObjectPointerType
>()) {
1470 S
.Diag(AL
.getLoc(), diag::warn_iboutlet_object_type
)
1471 << AL
<< VD
->getType() << 0;
1475 else if (const auto *PD
= dyn_cast
<ObjCPropertyDecl
>(D
)) {
1476 if (!PD
->getType()->getAs
<ObjCObjectPointerType
>()) {
1477 S
.Diag(AL
.getLoc(), diag::warn_iboutlet_object_type
)
1478 << AL
<< PD
->getType() << 1;
1483 S
.Diag(AL
.getLoc(), diag::warn_attribute_iboutlet
) << AL
;
1490 static void handleIBOutlet(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1491 if (!checkIBOutletCommon(S
, D
, AL
))
1494 D
->addAttr(::new (S
.Context
) IBOutletAttr(S
.Context
, AL
));
1497 static void handleIBOutletCollection(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1499 // The iboutletcollection attribute can have zero or one arguments.
1500 if (AL
.getNumArgs() > 1) {
1501 S
.Diag(AL
.getLoc(), diag::err_attribute_wrong_number_arguments
) << AL
<< 1;
1505 if (!checkIBOutletCommon(S
, D
, AL
))
1510 if (AL
.hasParsedType())
1511 PT
= AL
.getTypeArg();
1513 PT
= S
.getTypeName(S
.Context
.Idents
.get("NSObject"), AL
.getLoc(),
1514 S
.getScopeForContext(D
->getDeclContext()->getParent()));
1516 S
.Diag(AL
.getLoc(), diag::err_iboutletcollection_type
) << "NSObject";
1521 TypeSourceInfo
*QTLoc
= nullptr;
1522 QualType QT
= S
.GetTypeFromParser(PT
, &QTLoc
);
1524 QTLoc
= S
.Context
.getTrivialTypeSourceInfo(QT
, AL
.getLoc());
1526 // Diagnose use of non-object type in iboutletcollection attribute.
1527 // FIXME. Gnu attribute extension ignores use of builtin types in
1528 // attributes. So, __attribute__((iboutletcollection(char))) will be
1529 // treated as __attribute__((iboutletcollection())).
1530 if (!QT
->isObjCIdType() && !QT
->isObjCObjectType()) {
1532 QT
->isBuiltinType() ? diag::err_iboutletcollection_builtintype
1533 : diag::err_iboutletcollection_type
) << QT
;
1537 D
->addAttr(::new (S
.Context
) IBOutletCollectionAttr(S
.Context
, AL
, QTLoc
));
1540 bool Sema::isValidPointerAttrType(QualType T
, bool RefOkay
) {
1542 if (T
->isReferenceType())
1545 T
= T
.getNonReferenceType();
1548 // The nonnull attribute, and other similar attributes, can be applied to a
1549 // transparent union that contains a pointer type.
1550 if (const RecordType
*UT
= T
->getAsUnionType()) {
1551 if (UT
&& UT
->getDecl()->hasAttr
<TransparentUnionAttr
>()) {
1552 RecordDecl
*UD
= UT
->getDecl();
1553 for (const auto *I
: UD
->fields()) {
1554 QualType QT
= I
->getType();
1555 if (QT
->isAnyPointerType() || QT
->isBlockPointerType())
1561 return T
->isAnyPointerType() || T
->isBlockPointerType();
1564 static bool attrNonNullArgCheck(Sema
&S
, QualType T
, const ParsedAttr
&AL
,
1565 SourceRange AttrParmRange
,
1566 SourceRange TypeRange
,
1567 bool isReturnValue
= false) {
1568 if (!S
.isValidPointerAttrType(T
)) {
1570 S
.Diag(AL
.getLoc(), diag::warn_attribute_return_pointers_only
)
1571 << AL
<< AttrParmRange
<< TypeRange
;
1573 S
.Diag(AL
.getLoc(), diag::warn_attribute_pointers_only
)
1574 << AL
<< AttrParmRange
<< TypeRange
<< 0;
1580 static void handleNonNullAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1581 SmallVector
<ParamIdx
, 8> NonNullArgs
;
1582 for (unsigned I
= 0; I
< AL
.getNumArgs(); ++I
) {
1583 Expr
*Ex
= AL
.getArgAsExpr(I
);
1585 if (!checkFunctionOrMethodParameterIndex(S
, D
, AL
, I
+ 1, Ex
, Idx
))
1588 // Is the function argument a pointer type?
1589 if (Idx
.getASTIndex() < getFunctionOrMethodNumParams(D
) &&
1590 !attrNonNullArgCheck(
1591 S
, getFunctionOrMethodParamType(D
, Idx
.getASTIndex()), AL
,
1592 Ex
->getSourceRange(),
1593 getFunctionOrMethodParamRange(D
, Idx
.getASTIndex())))
1596 NonNullArgs
.push_back(Idx
);
1599 // If no arguments were specified to __attribute__((nonnull)) then all pointer
1600 // arguments have a nonnull attribute; warn if there aren't any. Skip this
1601 // check if the attribute came from a macro expansion or a template
1603 if (NonNullArgs
.empty() && AL
.getLoc().isFileID() &&
1604 !S
.inTemplateInstantiation()) {
1605 bool AnyPointers
= isFunctionOrMethodVariadic(D
);
1606 for (unsigned I
= 0, E
= getFunctionOrMethodNumParams(D
);
1607 I
!= E
&& !AnyPointers
; ++I
) {
1608 QualType T
= getFunctionOrMethodParamType(D
, I
);
1609 if (T
->isDependentType() || S
.isValidPointerAttrType(T
))
1614 S
.Diag(AL
.getLoc(), diag::warn_attribute_nonnull_no_pointers
);
1617 ParamIdx
*Start
= NonNullArgs
.data();
1618 unsigned Size
= NonNullArgs
.size();
1619 llvm::array_pod_sort(Start
, Start
+ Size
);
1620 D
->addAttr(::new (S
.Context
) NonNullAttr(S
.Context
, AL
, Start
, Size
));
1623 static void handleNonNullAttrParameter(Sema
&S
, ParmVarDecl
*D
,
1624 const ParsedAttr
&AL
) {
1625 if (AL
.getNumArgs() > 0) {
1626 if (D
->getFunctionType()) {
1627 handleNonNullAttr(S
, D
, AL
);
1629 S
.Diag(AL
.getLoc(), diag::warn_attribute_nonnull_parm_no_args
)
1630 << D
->getSourceRange();
1635 // Is the argument a pointer type?
1636 if (!attrNonNullArgCheck(S
, D
->getType(), AL
, SourceRange(),
1637 D
->getSourceRange()))
1640 D
->addAttr(::new (S
.Context
) NonNullAttr(S
.Context
, AL
, nullptr, 0));
1643 static void handleReturnsNonNullAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1644 QualType ResultType
= getFunctionOrMethodResultType(D
);
1645 SourceRange SR
= getFunctionOrMethodResultSourceRange(D
);
1646 if (!attrNonNullArgCheck(S
, ResultType
, AL
, SourceRange(), SR
,
1647 /* isReturnValue */ true))
1650 D
->addAttr(::new (S
.Context
) ReturnsNonNullAttr(S
.Context
, AL
));
1653 static void handleNoEscapeAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1654 if (D
->isInvalidDecl())
1657 // noescape only applies to pointer types.
1658 QualType T
= cast
<ParmVarDecl
>(D
)->getType();
1659 if (!S
.isValidPointerAttrType(T
, /* RefOkay */ true)) {
1660 S
.Diag(AL
.getLoc(), diag::warn_attribute_pointers_only
)
1661 << AL
<< AL
.getRange() << 0;
1665 D
->addAttr(::new (S
.Context
) NoEscapeAttr(S
.Context
, AL
));
1668 static void handleAssumeAlignedAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1669 Expr
*E
= AL
.getArgAsExpr(0),
1670 *OE
= AL
.getNumArgs() > 1 ? AL
.getArgAsExpr(1) : nullptr;
1671 S
.AddAssumeAlignedAttr(D
, AL
, E
, OE
);
1674 static void handleAllocAlignAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1675 S
.AddAllocAlignAttr(D
, AL
, AL
.getArgAsExpr(0));
1678 void Sema::AddAssumeAlignedAttr(Decl
*D
, const AttributeCommonInfo
&CI
, Expr
*E
,
1680 QualType ResultType
= getFunctionOrMethodResultType(D
);
1681 SourceRange SR
= getFunctionOrMethodResultSourceRange(D
);
1683 AssumeAlignedAttr
TmpAttr(Context
, CI
, E
, OE
);
1684 SourceLocation AttrLoc
= TmpAttr
.getLocation();
1686 if (!isValidPointerAttrType(ResultType
, /* RefOkay */ true)) {
1687 Diag(AttrLoc
, diag::warn_attribute_return_pointers_refs_only
)
1688 << &TmpAttr
<< TmpAttr
.getRange() << SR
;
1692 if (!E
->isValueDependent()) {
1693 std::optional
<llvm::APSInt
> I
= llvm::APSInt(64);
1694 if (!(I
= E
->getIntegerConstantExpr(Context
))) {
1696 Diag(AttrLoc
, diag::err_attribute_argument_n_type
)
1697 << &TmpAttr
<< 1 << AANT_ArgumentIntegerConstant
1698 << E
->getSourceRange();
1700 Diag(AttrLoc
, diag::err_attribute_argument_type
)
1701 << &TmpAttr
<< AANT_ArgumentIntegerConstant
1702 << E
->getSourceRange();
1706 if (!I
->isPowerOf2()) {
1707 Diag(AttrLoc
, diag::err_alignment_not_power_of_two
)
1708 << E
->getSourceRange();
1712 if (*I
> Sema::MaximumAlignment
)
1713 Diag(CI
.getLoc(), diag::warn_assume_aligned_too_great
)
1714 << CI
.getRange() << Sema::MaximumAlignment
;
1717 if (OE
&& !OE
->isValueDependent() && !OE
->isIntegerConstantExpr(Context
)) {
1718 Diag(AttrLoc
, diag::err_attribute_argument_n_type
)
1719 << &TmpAttr
<< 2 << AANT_ArgumentIntegerConstant
1720 << OE
->getSourceRange();
1724 D
->addAttr(::new (Context
) AssumeAlignedAttr(Context
, CI
, E
, OE
));
1727 void Sema::AddAllocAlignAttr(Decl
*D
, const AttributeCommonInfo
&CI
,
1729 QualType ResultType
= getFunctionOrMethodResultType(D
);
1731 AllocAlignAttr
TmpAttr(Context
, CI
, ParamIdx());
1732 SourceLocation AttrLoc
= CI
.getLoc();
1734 if (!ResultType
->isDependentType() &&
1735 !isValidPointerAttrType(ResultType
, /* RefOkay */ true)) {
1736 Diag(AttrLoc
, diag::warn_attribute_return_pointers_refs_only
)
1737 << &TmpAttr
<< CI
.getRange() << getFunctionOrMethodResultSourceRange(D
);
1742 const auto *FuncDecl
= cast
<FunctionDecl
>(D
);
1743 if (!checkFunctionOrMethodParameterIndex(*this, FuncDecl
, TmpAttr
,
1744 /*AttrArgNum=*/1, ParamExpr
, Idx
))
1747 QualType Ty
= getFunctionOrMethodParamType(D
, Idx
.getASTIndex());
1748 if (!Ty
->isDependentType() && !Ty
->isIntegralType(Context
) &&
1749 !Ty
->isAlignValT()) {
1750 Diag(ParamExpr
->getBeginLoc(), diag::err_attribute_integers_only
)
1752 << FuncDecl
->getParamDecl(Idx
.getASTIndex())->getSourceRange();
1756 D
->addAttr(::new (Context
) AllocAlignAttr(Context
, CI
, Idx
));
1759 /// Check if \p AssumptionStr is a known assumption and warn if not.
1760 static void checkAssumptionAttr(Sema
&S
, SourceLocation Loc
,
1761 StringRef AssumptionStr
) {
1762 if (llvm::KnownAssumptionStrings
.count(AssumptionStr
))
1765 unsigned BestEditDistance
= 3;
1766 StringRef Suggestion
;
1767 for (const auto &KnownAssumptionIt
: llvm::KnownAssumptionStrings
) {
1768 unsigned EditDistance
=
1769 AssumptionStr
.edit_distance(KnownAssumptionIt
.getKey());
1770 if (EditDistance
< BestEditDistance
) {
1771 Suggestion
= KnownAssumptionIt
.getKey();
1772 BestEditDistance
= EditDistance
;
1776 if (!Suggestion
.empty())
1777 S
.Diag(Loc
, diag::warn_assume_attribute_string_unknown_suggested
)
1778 << AssumptionStr
<< Suggestion
;
1780 S
.Diag(Loc
, diag::warn_assume_attribute_string_unknown
) << AssumptionStr
;
1783 static void handleAssumumptionAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1784 // Handle the case where the attribute has a text message.
1786 SourceLocation AttrStrLoc
;
1787 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Str
, &AttrStrLoc
))
1790 checkAssumptionAttr(S
, AttrStrLoc
, Str
);
1792 D
->addAttr(::new (S
.Context
) AssumptionAttr(S
.Context
, AL
, Str
));
1795 /// Normalize the attribute, __foo__ becomes foo.
1796 /// Returns true if normalization was applied.
1797 static bool normalizeName(StringRef
&AttrName
) {
1798 if (AttrName
.size() > 4 && AttrName
.startswith("__") &&
1799 AttrName
.endswith("__")) {
1800 AttrName
= AttrName
.drop_front(2).drop_back(2);
1806 static void handleOwnershipAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1807 // This attribute must be applied to a function declaration. The first
1808 // argument to the attribute must be an identifier, the name of the resource,
1809 // for example: malloc. The following arguments must be argument indexes, the
1810 // arguments must be of integer type for Returns, otherwise of pointer type.
1811 // The difference between Holds and Takes is that a pointer may still be used
1812 // after being held. free() should be __attribute((ownership_takes)), whereas
1813 // a list append function may well be __attribute((ownership_holds)).
1815 if (!AL
.isArgIdent(0)) {
1816 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_n_type
)
1817 << AL
<< 1 << AANT_ArgumentIdentifier
;
1821 // Figure out our Kind.
1822 OwnershipAttr::OwnershipKind K
=
1823 OwnershipAttr(S
.Context
, AL
, nullptr, nullptr, 0).getOwnKind();
1827 case OwnershipAttr::Takes
:
1828 case OwnershipAttr::Holds
:
1829 if (AL
.getNumArgs() < 2) {
1830 S
.Diag(AL
.getLoc(), diag::err_attribute_too_few_arguments
) << AL
<< 2;
1834 case OwnershipAttr::Returns
:
1835 if (AL
.getNumArgs() > 2) {
1836 S
.Diag(AL
.getLoc(), diag::err_attribute_too_many_arguments
) << AL
<< 1;
1842 IdentifierInfo
*Module
= AL
.getArgAsIdent(0)->Ident
;
1844 StringRef ModuleName
= Module
->getName();
1845 if (normalizeName(ModuleName
)) {
1846 Module
= &S
.PP
.getIdentifierTable().get(ModuleName
);
1849 SmallVector
<ParamIdx
, 8> OwnershipArgs
;
1850 for (unsigned i
= 1; i
< AL
.getNumArgs(); ++i
) {
1851 Expr
*Ex
= AL
.getArgAsExpr(i
);
1853 if (!checkFunctionOrMethodParameterIndex(S
, D
, AL
, i
, Ex
, Idx
))
1856 // Is the function argument a pointer type?
1857 QualType T
= getFunctionOrMethodParamType(D
, Idx
.getASTIndex());
1858 int Err
= -1; // No error
1860 case OwnershipAttr::Takes
:
1861 case OwnershipAttr::Holds
:
1862 if (!T
->isAnyPointerType() && !T
->isBlockPointerType())
1865 case OwnershipAttr::Returns
:
1866 if (!T
->isIntegerType())
1871 S
.Diag(AL
.getLoc(), diag::err_ownership_type
) << AL
<< Err
1872 << Ex
->getSourceRange();
1876 // Check we don't have a conflict with another ownership attribute.
1877 for (const auto *I
: D
->specific_attrs
<OwnershipAttr
>()) {
1878 // Cannot have two ownership attributes of different kinds for the same
1880 if (I
->getOwnKind() != K
&& llvm::is_contained(I
->args(), Idx
)) {
1881 S
.Diag(AL
.getLoc(), diag::err_attributes_are_not_compatible
) << AL
<< I
;
1883 } else if (K
== OwnershipAttr::Returns
&&
1884 I
->getOwnKind() == OwnershipAttr::Returns
) {
1885 // A returns attribute conflicts with any other returns attribute using
1886 // a different index.
1887 if (!llvm::is_contained(I
->args(), Idx
)) {
1888 S
.Diag(I
->getLocation(), diag::err_ownership_returns_index_mismatch
)
1889 << I
->args_begin()->getSourceIndex();
1891 S
.Diag(AL
.getLoc(), diag::note_ownership_returns_index_mismatch
)
1892 << Idx
.getSourceIndex() << Ex
->getSourceRange();
1897 OwnershipArgs
.push_back(Idx
);
1900 ParamIdx
*Start
= OwnershipArgs
.data();
1901 unsigned Size
= OwnershipArgs
.size();
1902 llvm::array_pod_sort(Start
, Start
+ Size
);
1903 D
->addAttr(::new (S
.Context
)
1904 OwnershipAttr(S
.Context
, AL
, Module
, Start
, Size
));
1907 static void handleWeakRefAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1908 // Check the attribute arguments.
1909 if (AL
.getNumArgs() > 1) {
1910 S
.Diag(AL
.getLoc(), diag::err_attribute_wrong_number_arguments
) << AL
<< 1;
1916 // static int a __attribute__((weakref ("v2")));
1917 // static int b() __attribute__((weakref ("f3")));
1919 // and ignores the attributes of
1921 // static int a __attribute__((weakref ("v2")));
1924 const DeclContext
*Ctx
= D
->getDeclContext()->getRedeclContext();
1925 if (!Ctx
->isFileContext()) {
1926 S
.Diag(AL
.getLoc(), diag::err_attribute_weakref_not_global_context
)
1927 << cast
<NamedDecl
>(D
);
1931 // The GCC manual says
1933 // At present, a declaration to which `weakref' is attached can only
1938 // Without a TARGET,
1939 // given as an argument to `weakref' or to `alias', `weakref' is
1940 // equivalent to `weak'.
1942 // gcc 4.4.1 will accept
1943 // int a7 __attribute__((weakref));
1945 // int a7 __attribute__((weak));
1946 // This looks like a bug in gcc. We reject that for now. We should revisit
1947 // it if this behaviour is actually used.
1950 // static ((alias ("y"), weakref)).
1951 // Should we? How to check that weakref is before or after alias?
1953 // FIXME: it would be good for us to keep the WeakRefAttr as-written instead
1954 // of transforming it into an AliasAttr. The WeakRefAttr never uses the
1955 // StringRef parameter it was given anyway.
1957 if (AL
.getNumArgs() && S
.checkStringLiteralArgumentAttr(AL
, 0, Str
))
1958 // GCC will accept anything as the argument of weakref. Should we
1959 // check for an existing decl?
1960 D
->addAttr(::new (S
.Context
) AliasAttr(S
.Context
, AL
, Str
));
1962 D
->addAttr(::new (S
.Context
) WeakRefAttr(S
.Context
, AL
));
1965 static void handleIFuncAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1967 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Str
))
1970 // Aliases should be on declarations, not definitions.
1971 const auto *FD
= cast
<FunctionDecl
>(D
);
1972 if (FD
->isThisDeclarationADefinition()) {
1973 S
.Diag(AL
.getLoc(), diag::err_alias_is_definition
) << FD
<< 1;
1977 D
->addAttr(::new (S
.Context
) IFuncAttr(S
.Context
, AL
, Str
));
1980 static void handleAliasAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
1982 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Str
))
1985 if (S
.Context
.getTargetInfo().getTriple().isOSDarwin()) {
1986 S
.Diag(AL
.getLoc(), diag::err_alias_not_supported_on_darwin
);
1989 if (S
.Context
.getTargetInfo().getTriple().isNVPTX()) {
1990 S
.Diag(AL
.getLoc(), diag::err_alias_not_supported_on_nvptx
);
1993 // Aliases should be on declarations, not definitions.
1994 if (const auto *FD
= dyn_cast
<FunctionDecl
>(D
)) {
1995 if (FD
->isThisDeclarationADefinition()) {
1996 S
.Diag(AL
.getLoc(), diag::err_alias_is_definition
) << FD
<< 0;
2000 const auto *VD
= cast
<VarDecl
>(D
);
2001 if (VD
->isThisDeclarationADefinition() && VD
->isExternallyVisible()) {
2002 S
.Diag(AL
.getLoc(), diag::err_alias_is_definition
) << VD
<< 0;
2007 // Mark target used to prevent unneeded-internal-declaration warnings.
2008 if (!S
.LangOpts
.CPlusPlus
) {
2009 // FIXME: demangle Str for C++, as the attribute refers to the mangled
2010 // linkage name, not the pre-mangled identifier.
2011 const DeclarationNameInfo
target(&S
.Context
.Idents
.get(Str
), AL
.getLoc());
2012 LookupResult
LR(S
, target
, Sema::LookupOrdinaryName
);
2013 if (S
.LookupQualifiedName(LR
, S
.getCurLexicalContext()))
2014 for (NamedDecl
*ND
: LR
)
2015 ND
->markUsed(S
.Context
);
2018 D
->addAttr(::new (S
.Context
) AliasAttr(S
.Context
, AL
, Str
));
2021 static void handleTLSModelAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
2023 SourceLocation LiteralLoc
;
2024 // Check that it is a string.
2025 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Model
, &LiteralLoc
))
2028 // Check that the value.
2029 if (Model
!= "global-dynamic" && Model
!= "local-dynamic"
2030 && Model
!= "initial-exec" && Model
!= "local-exec") {
2031 S
.Diag(LiteralLoc
, diag::err_attr_tlsmodel_arg
);
2035 if (S
.Context
.getTargetInfo().getTriple().isOSAIX() &&
2036 Model
!= "global-dynamic") {
2037 S
.Diag(LiteralLoc
, diag::err_aix_attr_unsupported_tls_model
) << Model
;
2041 D
->addAttr(::new (S
.Context
) TLSModelAttr(S
.Context
, AL
, Model
));
2044 static void handleRestrictAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
2045 QualType ResultType
= getFunctionOrMethodResultType(D
);
2046 if (ResultType
->isAnyPointerType() || ResultType
->isBlockPointerType()) {
2047 D
->addAttr(::new (S
.Context
) RestrictAttr(S
.Context
, AL
));
2051 S
.Diag(AL
.getLoc(), diag::warn_attribute_return_pointers_only
)
2052 << AL
<< getFunctionOrMethodResultSourceRange(D
);
2055 static void handleCPUSpecificAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
2056 // Ensure we don't combine these with themselves, since that causes some
2057 // confusing behavior.
2058 if (AL
.getParsedKind() == ParsedAttr::AT_CPUDispatch
) {
2059 if (checkAttrMutualExclusion
<CPUSpecificAttr
>(S
, D
, AL
))
2062 if (const auto *Other
= D
->getAttr
<CPUDispatchAttr
>()) {
2063 S
.Diag(AL
.getLoc(), diag::err_disallowed_duplicate_attribute
) << AL
;
2064 S
.Diag(Other
->getLocation(), diag::note_conflicting_attribute
);
2067 } else if (AL
.getParsedKind() == ParsedAttr::AT_CPUSpecific
) {
2068 if (checkAttrMutualExclusion
<CPUDispatchAttr
>(S
, D
, AL
))
2071 if (const auto *Other
= D
->getAttr
<CPUSpecificAttr
>()) {
2072 S
.Diag(AL
.getLoc(), diag::err_disallowed_duplicate_attribute
) << AL
;
2073 S
.Diag(Other
->getLocation(), diag::note_conflicting_attribute
);
2078 FunctionDecl
*FD
= cast
<FunctionDecl
>(D
);
2080 if (const auto *MD
= dyn_cast
<CXXMethodDecl
>(D
)) {
2081 if (MD
->getParent()->isLambda()) {
2082 S
.Diag(AL
.getLoc(), diag::err_attribute_dll_lambda
) << AL
;
2087 if (!AL
.checkAtLeastNumArgs(S
, 1))
2090 SmallVector
<IdentifierInfo
*, 8> CPUs
;
2091 for (unsigned ArgNo
= 0; ArgNo
< getNumAttributeArgs(AL
); ++ArgNo
) {
2092 if (!AL
.isArgIdent(ArgNo
)) {
2093 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_type
)
2094 << AL
<< AANT_ArgumentIdentifier
;
2098 IdentifierLoc
*CPUArg
= AL
.getArgAsIdent(ArgNo
);
2099 StringRef CPUName
= CPUArg
->Ident
->getName().trim();
2101 if (!S
.Context
.getTargetInfo().validateCPUSpecificCPUDispatch(CPUName
)) {
2102 S
.Diag(CPUArg
->Loc
, diag::err_invalid_cpu_specific_dispatch_value
)
2103 << CPUName
<< (AL
.getKind() == ParsedAttr::AT_CPUDispatch
);
2107 const TargetInfo
&Target
= S
.Context
.getTargetInfo();
2108 if (llvm::any_of(CPUs
, [CPUName
, &Target
](const IdentifierInfo
*Cur
) {
2109 return Target
.CPUSpecificManglingCharacter(CPUName
) ==
2110 Target
.CPUSpecificManglingCharacter(Cur
->getName());
2112 S
.Diag(AL
.getLoc(), diag::warn_multiversion_duplicate_entries
);
2115 CPUs
.push_back(CPUArg
->Ident
);
2118 FD
->setIsMultiVersion(true);
2119 if (AL
.getKind() == ParsedAttr::AT_CPUSpecific
)
2120 D
->addAttr(::new (S
.Context
)
2121 CPUSpecificAttr(S
.Context
, AL
, CPUs
.data(), CPUs
.size()));
2123 D
->addAttr(::new (S
.Context
)
2124 CPUDispatchAttr(S
.Context
, AL
, CPUs
.data(), CPUs
.size()));
2127 static void handleCommonAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
2128 if (S
.LangOpts
.CPlusPlus
) {
2129 S
.Diag(AL
.getLoc(), diag::err_attribute_not_supported_in_lang
)
2130 << AL
<< AttributeLangSupport::Cpp
;
2134 D
->addAttr(::new (S
.Context
) CommonAttr(S
.Context
, AL
));
2137 static void handleCmseNSEntryAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
2138 if (S
.LangOpts
.CPlusPlus
&& !D
->getDeclContext()->isExternCContext()) {
2139 S
.Diag(AL
.getLoc(), diag::err_attribute_not_clinkage
) << AL
;
2143 const auto *FD
= cast
<FunctionDecl
>(D
);
2144 if (!FD
->isExternallyVisible()) {
2145 S
.Diag(AL
.getLoc(), diag::warn_attribute_cmse_entry_static
);
2149 D
->addAttr(::new (S
.Context
) CmseNSEntryAttr(S
.Context
, AL
));
2152 static void handleNakedAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
2153 if (AL
.isDeclspecAttribute()) {
2154 const auto &Triple
= S
.getASTContext().getTargetInfo().getTriple();
2155 const auto &Arch
= Triple
.getArch();
2156 if (Arch
!= llvm::Triple::x86
&&
2157 (Arch
!= llvm::Triple::arm
&& Arch
!= llvm::Triple::thumb
)) {
2158 S
.Diag(AL
.getLoc(), diag::err_attribute_not_supported_on_arch
)
2159 << AL
<< Triple
.getArchName();
2163 // This form is not allowed to be written on a member function (static or
2164 // nonstatic) when in Microsoft compatibility mode.
2165 if (S
.getLangOpts().MSVCCompat
&& isa
<CXXMethodDecl
>(D
)) {
2166 S
.Diag(AL
.getLoc(), diag::err_attribute_wrong_decl_type_str
)
2167 << AL
<< "non-member functions";
2172 D
->addAttr(::new (S
.Context
) NakedAttr(S
.Context
, AL
));
2175 static void handleNoReturnAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&Attrs
) {
2176 if (hasDeclarator(D
)) return;
2178 if (!isa
<ObjCMethodDecl
>(D
)) {
2179 S
.Diag(Attrs
.getLoc(), diag::warn_attribute_wrong_decl_type
)
2180 << Attrs
<< ExpectedFunctionOrMethod
;
2184 D
->addAttr(::new (S
.Context
) NoReturnAttr(S
.Context
, Attrs
));
2187 static void handleStandardNoReturnAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&A
) {
2188 // The [[_Noreturn]] spelling is deprecated in C2x, so if that was used,
2189 // issue an appropriate diagnostic. However, don't issue a diagnostic if the
2190 // attribute name comes from a macro expansion. We don't want to punish users
2191 // who write [[noreturn]] after including <stdnoreturn.h> (where 'noreturn'
2192 // is defined as a macro which expands to '_Noreturn').
2193 if (!S
.getLangOpts().CPlusPlus
&&
2194 A
.getSemanticSpelling() == CXX11NoReturnAttr::C2x_Noreturn
&&
2195 !(A
.getLoc().isMacroID() &&
2196 S
.getSourceManager().isInSystemMacro(A
.getLoc())))
2197 S
.Diag(A
.getLoc(), diag::warn_deprecated_noreturn_spelling
) << A
.getRange();
2199 D
->addAttr(::new (S
.Context
) CXX11NoReturnAttr(S
.Context
, A
));
2202 static void handleNoCfCheckAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&Attrs
) {
2203 if (!S
.getLangOpts().CFProtectionBranch
)
2204 S
.Diag(Attrs
.getLoc(), diag::warn_nocf_check_attribute_ignored
);
2206 handleSimpleAttribute
<AnyX86NoCfCheckAttr
>(S
, D
, Attrs
);
2209 bool Sema::CheckAttrNoArgs(const ParsedAttr
&Attrs
) {
2210 if (!Attrs
.checkExactlyNumArgs(*this, 0)) {
2218 bool Sema::CheckAttrTarget(const ParsedAttr
&AL
) {
2219 // Check whether the attribute is valid on the current target.
2220 if (!AL
.existsInTarget(Context
.getTargetInfo())) {
2221 Diag(AL
.getLoc(), diag::warn_unknown_attribute_ignored
)
2222 << AL
<< AL
.getRange();
2230 static void handleAnalyzerNoReturnAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
2232 // The checking path for 'noreturn' and 'analyzer_noreturn' are different
2233 // because 'analyzer_noreturn' does not impact the type.
2234 if (!isFunctionOrMethodOrBlock(D
)) {
2235 ValueDecl
*VD
= dyn_cast
<ValueDecl
>(D
);
2236 if (!VD
|| (!VD
->getType()->isBlockPointerType() &&
2237 !VD
->getType()->isFunctionPointerType())) {
2238 S
.Diag(AL
.getLoc(), AL
.isStandardAttributeSyntax()
2239 ? diag::err_attribute_wrong_decl_type
2240 : diag::warn_attribute_wrong_decl_type
)
2241 << AL
<< ExpectedFunctionMethodOrBlock
;
2246 D
->addAttr(::new (S
.Context
) AnalyzerNoReturnAttr(S
.Context
, AL
));
2249 // PS3 PPU-specific.
2250 static void handleVecReturnAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
2252 Returning a Vector Class in Registers
2254 According to the PPU ABI specifications, a class with a single member of
2255 vector type is returned in memory when used as the return value of a
2257 This results in inefficient code when implementing vector classes. To return
2258 the value in a single vector register, add the vecreturn attribute to the
2259 class definition. This attribute is also applicable to struct types.
2265 __vector float xyzw;
2266 } __attribute__((vecreturn));
2268 Vector Add(Vector lhs, Vector rhs)
2271 result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
2272 return result; // This will be returned in a register
2275 if (VecReturnAttr
*A
= D
->getAttr
<VecReturnAttr
>()) {
2276 S
.Diag(AL
.getLoc(), diag::err_repeat_attribute
) << A
;
2280 const auto *R
= cast
<RecordDecl
>(D
);
2283 if (!isa
<CXXRecordDecl
>(R
)) {
2284 S
.Diag(AL
.getLoc(), diag::err_attribute_vecreturn_only_vector_member
);
2288 if (!cast
<CXXRecordDecl
>(R
)->isPOD()) {
2289 S
.Diag(AL
.getLoc(), diag::err_attribute_vecreturn_only_pod_record
);
2293 for (const auto *I
: R
->fields()) {
2294 if ((count
== 1) || !I
->getType()->isVectorType()) {
2295 S
.Diag(AL
.getLoc(), diag::err_attribute_vecreturn_only_vector_member
);
2301 D
->addAttr(::new (S
.Context
) VecReturnAttr(S
.Context
, AL
));
2304 static void handleDependencyAttr(Sema
&S
, Scope
*Scope
, Decl
*D
,
2305 const ParsedAttr
&AL
) {
2306 if (isa
<ParmVarDecl
>(D
)) {
2307 // [[carries_dependency]] can only be applied to a parameter if it is a
2308 // parameter of a function declaration or lambda.
2309 if (!(Scope
->getFlags() & clang::Scope::FunctionDeclarationScope
)) {
2311 diag::err_carries_dependency_param_not_function_decl
);
2316 D
->addAttr(::new (S
.Context
) CarriesDependencyAttr(S
.Context
, AL
));
2319 static void handleUnusedAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
2320 bool IsCXX17Attr
= AL
.isCXX11Attribute() && !AL
.getScopeName();
2322 // If this is spelled as the standard C++17 attribute, but not in C++17, warn
2323 // about using it as an extension.
2324 if (!S
.getLangOpts().CPlusPlus17
&& IsCXX17Attr
)
2325 S
.Diag(AL
.getLoc(), diag::ext_cxx17_attr
) << AL
;
2327 D
->addAttr(::new (S
.Context
) UnusedAttr(S
.Context
, AL
));
2330 static void handleConstructorAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
2331 uint32_t priority
= ConstructorAttr::DefaultPriority
;
2332 if (S
.getLangOpts().HLSL
&& AL
.getNumArgs()) {
2333 S
.Diag(AL
.getLoc(), diag::err_hlsl_init_priority_unsupported
);
2336 if (AL
.getNumArgs() &&
2337 !checkUInt32Argument(S
, AL
, AL
.getArgAsExpr(0), priority
))
2340 D
->addAttr(::new (S
.Context
) ConstructorAttr(S
.Context
, AL
, priority
));
2343 static void handleDestructorAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
2344 uint32_t priority
= DestructorAttr::DefaultPriority
;
2345 if (AL
.getNumArgs() &&
2346 !checkUInt32Argument(S
, AL
, AL
.getArgAsExpr(0), priority
))
2349 D
->addAttr(::new (S
.Context
) DestructorAttr(S
.Context
, AL
, priority
));
2352 template <typename AttrTy
>
2353 static void handleAttrWithMessage(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
2354 // Handle the case where the attribute has a text message.
2356 if (AL
.getNumArgs() == 1 && !S
.checkStringLiteralArgumentAttr(AL
, 0, Str
))
2359 D
->addAttr(::new (S
.Context
) AttrTy(S
.Context
, AL
, Str
));
2362 static void handleObjCSuppresProtocolAttr(Sema
&S
, Decl
*D
,
2363 const ParsedAttr
&AL
) {
2364 if (!cast
<ObjCProtocolDecl
>(D
)->isThisDeclarationADefinition()) {
2365 S
.Diag(AL
.getLoc(), diag::err_objc_attr_protocol_requires_definition
)
2366 << AL
<< AL
.getRange();
2370 D
->addAttr(::new (S
.Context
) ObjCExplicitProtocolImplAttr(S
.Context
, AL
));
2373 static bool checkAvailabilityAttr(Sema
&S
, SourceRange Range
,
2374 IdentifierInfo
*Platform
,
2375 VersionTuple Introduced
,
2376 VersionTuple Deprecated
,
2377 VersionTuple Obsoleted
) {
2378 StringRef PlatformName
2379 = AvailabilityAttr::getPrettyPlatformName(Platform
->getName());
2380 if (PlatformName
.empty())
2381 PlatformName
= Platform
->getName();
2383 // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
2384 // of these steps are needed).
2385 if (!Introduced
.empty() && !Deprecated
.empty() &&
2386 !(Introduced
<= Deprecated
)) {
2387 S
.Diag(Range
.getBegin(), diag::warn_availability_version_ordering
)
2388 << 1 << PlatformName
<< Deprecated
.getAsString()
2389 << 0 << Introduced
.getAsString();
2393 if (!Introduced
.empty() && !Obsoleted
.empty() &&
2394 !(Introduced
<= Obsoleted
)) {
2395 S
.Diag(Range
.getBegin(), diag::warn_availability_version_ordering
)
2396 << 2 << PlatformName
<< Obsoleted
.getAsString()
2397 << 0 << Introduced
.getAsString();
2401 if (!Deprecated
.empty() && !Obsoleted
.empty() &&
2402 !(Deprecated
<= Obsoleted
)) {
2403 S
.Diag(Range
.getBegin(), diag::warn_availability_version_ordering
)
2404 << 2 << PlatformName
<< Obsoleted
.getAsString()
2405 << 1 << Deprecated
.getAsString();
2412 /// Check whether the two versions match.
2414 /// If either version tuple is empty, then they are assumed to match. If
2415 /// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y.
2416 static bool versionsMatch(const VersionTuple
&X
, const VersionTuple
&Y
,
2417 bool BeforeIsOkay
) {
2418 if (X
.empty() || Y
.empty())
2424 if (BeforeIsOkay
&& X
< Y
)
2430 AvailabilityAttr
*Sema::mergeAvailabilityAttr(
2431 NamedDecl
*D
, const AttributeCommonInfo
&CI
, IdentifierInfo
*Platform
,
2432 bool Implicit
, VersionTuple Introduced
, VersionTuple Deprecated
,
2433 VersionTuple Obsoleted
, bool IsUnavailable
, StringRef Message
,
2434 bool IsStrict
, StringRef Replacement
, AvailabilityMergeKind AMK
,
2436 VersionTuple MergedIntroduced
= Introduced
;
2437 VersionTuple MergedDeprecated
= Deprecated
;
2438 VersionTuple MergedObsoleted
= Obsoleted
;
2439 bool FoundAny
= false;
2440 bool OverrideOrImpl
= false;
2443 case AMK_Redeclaration
:
2444 OverrideOrImpl
= false;
2448 case AMK_ProtocolImplementation
:
2449 case AMK_OptionalProtocolImplementation
:
2450 OverrideOrImpl
= true;
2454 if (D
->hasAttrs()) {
2455 AttrVec
&Attrs
= D
->getAttrs();
2456 for (unsigned i
= 0, e
= Attrs
.size(); i
!= e
;) {
2457 const auto *OldAA
= dyn_cast
<AvailabilityAttr
>(Attrs
[i
]);
2463 IdentifierInfo
*OldPlatform
= OldAA
->getPlatform();
2464 if (OldPlatform
!= Platform
) {
2469 // If there is an existing availability attribute for this platform that
2470 // has a lower priority use the existing one and discard the new
2472 if (OldAA
->getPriority() < Priority
)
2475 // If there is an existing attribute for this platform that has a higher
2476 // priority than the new attribute then erase the old one and continue
2477 // processing the attributes.
2478 if (OldAA
->getPriority() > Priority
) {
2479 Attrs
.erase(Attrs
.begin() + i
);
2485 VersionTuple OldIntroduced
= OldAA
->getIntroduced();
2486 VersionTuple OldDeprecated
= OldAA
->getDeprecated();
2487 VersionTuple OldObsoleted
= OldAA
->getObsoleted();
2488 bool OldIsUnavailable
= OldAA
->getUnavailable();
2490 if (!versionsMatch(OldIntroduced
, Introduced
, OverrideOrImpl
) ||
2491 !versionsMatch(Deprecated
, OldDeprecated
, OverrideOrImpl
) ||
2492 !versionsMatch(Obsoleted
, OldObsoleted
, OverrideOrImpl
) ||
2493 !(OldIsUnavailable
== IsUnavailable
||
2494 (OverrideOrImpl
&& !OldIsUnavailable
&& IsUnavailable
))) {
2495 if (OverrideOrImpl
) {
2497 VersionTuple FirstVersion
;
2498 VersionTuple SecondVersion
;
2499 if (!versionsMatch(OldIntroduced
, Introduced
, OverrideOrImpl
)) {
2501 FirstVersion
= OldIntroduced
;
2502 SecondVersion
= Introduced
;
2503 } else if (!versionsMatch(Deprecated
, OldDeprecated
, OverrideOrImpl
)) {
2505 FirstVersion
= Deprecated
;
2506 SecondVersion
= OldDeprecated
;
2507 } else if (!versionsMatch(Obsoleted
, OldObsoleted
, OverrideOrImpl
)) {
2509 FirstVersion
= Obsoleted
;
2510 SecondVersion
= OldObsoleted
;
2514 Diag(OldAA
->getLocation(),
2515 diag::warn_mismatched_availability_override_unavail
)
2516 << AvailabilityAttr::getPrettyPlatformName(Platform
->getName())
2517 << (AMK
== AMK_Override
);
2518 } else if (Which
!= 1 && AMK
== AMK_OptionalProtocolImplementation
) {
2519 // Allow different 'introduced' / 'obsoleted' availability versions
2520 // on a method that implements an optional protocol requirement. It
2521 // makes less sense to allow this for 'deprecated' as the user can't
2522 // see if the method is 'deprecated' as 'respondsToSelector' will
2523 // still return true when the method is deprecated.
2527 Diag(OldAA
->getLocation(),
2528 diag::warn_mismatched_availability_override
)
2530 << AvailabilityAttr::getPrettyPlatformName(Platform
->getName())
2531 << FirstVersion
.getAsString() << SecondVersion
.getAsString()
2532 << (AMK
== AMK_Override
);
2534 if (AMK
== AMK_Override
)
2535 Diag(CI
.getLoc(), diag::note_overridden_method
);
2537 Diag(CI
.getLoc(), diag::note_protocol_method
);
2539 Diag(OldAA
->getLocation(), diag::warn_mismatched_availability
);
2540 Diag(CI
.getLoc(), diag::note_previous_attribute
);
2543 Attrs
.erase(Attrs
.begin() + i
);
2548 VersionTuple MergedIntroduced2
= MergedIntroduced
;
2549 VersionTuple MergedDeprecated2
= MergedDeprecated
;
2550 VersionTuple MergedObsoleted2
= MergedObsoleted
;
2552 if (MergedIntroduced2
.empty())
2553 MergedIntroduced2
= OldIntroduced
;
2554 if (MergedDeprecated2
.empty())
2555 MergedDeprecated2
= OldDeprecated
;
2556 if (MergedObsoleted2
.empty())
2557 MergedObsoleted2
= OldObsoleted
;
2559 if (checkAvailabilityAttr(*this, OldAA
->getRange(), Platform
,
2560 MergedIntroduced2
, MergedDeprecated2
,
2561 MergedObsoleted2
)) {
2562 Attrs
.erase(Attrs
.begin() + i
);
2567 MergedIntroduced
= MergedIntroduced2
;
2568 MergedDeprecated
= MergedDeprecated2
;
2569 MergedObsoleted
= MergedObsoleted2
;
2575 MergedIntroduced
== Introduced
&&
2576 MergedDeprecated
== Deprecated
&&
2577 MergedObsoleted
== Obsoleted
)
2580 // Only create a new attribute if !OverrideOrImpl, but we want to do
2582 if (!checkAvailabilityAttr(*this, CI
.getRange(), Platform
, MergedIntroduced
,
2583 MergedDeprecated
, MergedObsoleted
) &&
2585 auto *Avail
= ::new (Context
) AvailabilityAttr(
2586 Context
, CI
, Platform
, Introduced
, Deprecated
, Obsoleted
, IsUnavailable
,
2587 Message
, IsStrict
, Replacement
, Priority
);
2588 Avail
->setImplicit(Implicit
);
2594 static void handleAvailabilityAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
2595 if (isa
<UsingDecl
, UnresolvedUsingTypenameDecl
, UnresolvedUsingValueDecl
>(
2597 S
.Diag(AL
.getRange().getBegin(), diag::warn_deprecated_ignored_on_using
)
2602 if (!AL
.checkExactlyNumArgs(S
, 1))
2604 IdentifierLoc
*Platform
= AL
.getArgAsIdent(0);
2606 IdentifierInfo
*II
= Platform
->Ident
;
2607 if (AvailabilityAttr::getPrettyPlatformName(II
->getName()).empty())
2608 S
.Diag(Platform
->Loc
, diag::warn_availability_unknown_platform
)
2611 auto *ND
= dyn_cast
<NamedDecl
>(D
);
2612 if (!ND
) // We warned about this already, so just return.
2615 AvailabilityChange Introduced
= AL
.getAvailabilityIntroduced();
2616 AvailabilityChange Deprecated
= AL
.getAvailabilityDeprecated();
2617 AvailabilityChange Obsoleted
= AL
.getAvailabilityObsoleted();
2618 bool IsUnavailable
= AL
.getUnavailableLoc().isValid();
2619 bool IsStrict
= AL
.getStrictLoc().isValid();
2621 if (const auto *SE
= dyn_cast_or_null
<StringLiteral
>(AL
.getMessageExpr()))
2622 Str
= SE
->getString();
2623 StringRef Replacement
;
2624 if (const auto *SE
= dyn_cast_or_null
<StringLiteral
>(AL
.getReplacementExpr()))
2625 Replacement
= SE
->getString();
2627 if (II
->isStr("swift")) {
2628 if (Introduced
.isValid() || Obsoleted
.isValid() ||
2629 (!IsUnavailable
&& !Deprecated
.isValid())) {
2631 diag::warn_availability_swift_unavailable_deprecated_only
);
2636 if (II
->isStr("fuchsia")) {
2637 std::optional
<unsigned> Min
, Sub
;
2638 if ((Min
= Introduced
.Version
.getMinor()) ||
2639 (Sub
= Introduced
.Version
.getSubminor())) {
2640 S
.Diag(AL
.getLoc(), diag::warn_availability_fuchsia_unavailable_minor
);
2645 int PriorityModifier
= AL
.isPragmaClangAttribute()
2646 ? Sema::AP_PragmaClangAttribute
2647 : Sema::AP_Explicit
;
2648 AvailabilityAttr
*NewAttr
= S
.mergeAvailabilityAttr(
2649 ND
, AL
, II
, false /*Implicit*/, Introduced
.Version
, Deprecated
.Version
,
2650 Obsoleted
.Version
, IsUnavailable
, Str
, IsStrict
, Replacement
,
2651 Sema::AMK_None
, PriorityModifier
);
2653 D
->addAttr(NewAttr
);
2655 // Transcribe "ios" to "watchos" (and add a new attribute) if the versioning
2656 // matches before the start of the watchOS platform.
2657 if (S
.Context
.getTargetInfo().getTriple().isWatchOS()) {
2658 IdentifierInfo
*NewII
= nullptr;
2659 if (II
->getName() == "ios")
2660 NewII
= &S
.Context
.Idents
.get("watchos");
2661 else if (II
->getName() == "ios_app_extension")
2662 NewII
= &S
.Context
.Idents
.get("watchos_app_extension");
2665 const auto *SDKInfo
= S
.getDarwinSDKInfoForAvailabilityChecking();
2666 const auto *IOSToWatchOSMapping
=
2667 SDKInfo
? SDKInfo
->getVersionMapping(
2668 DarwinSDKInfo::OSEnvPair::iOStoWatchOSPair())
2671 auto adjustWatchOSVersion
=
2672 [IOSToWatchOSMapping
](VersionTuple Version
) -> VersionTuple
{
2673 if (Version
.empty())
2675 auto MinimumWatchOSVersion
= VersionTuple(2, 0);
2677 if (IOSToWatchOSMapping
) {
2678 if (auto MappedVersion
= IOSToWatchOSMapping
->map(
2679 Version
, MinimumWatchOSVersion
, std::nullopt
)) {
2680 return *MappedVersion
;
2684 auto Major
= Version
.getMajor();
2685 auto NewMajor
= Major
>= 9 ? Major
- 7 : 0;
2686 if (NewMajor
>= 2) {
2687 if (Version
.getMinor()) {
2688 if (Version
.getSubminor())
2689 return VersionTuple(NewMajor
, *Version
.getMinor(),
2690 *Version
.getSubminor());
2692 return VersionTuple(NewMajor
, *Version
.getMinor());
2694 return VersionTuple(NewMajor
);
2697 return MinimumWatchOSVersion
;
2700 auto NewIntroduced
= adjustWatchOSVersion(Introduced
.Version
);
2701 auto NewDeprecated
= adjustWatchOSVersion(Deprecated
.Version
);
2702 auto NewObsoleted
= adjustWatchOSVersion(Obsoleted
.Version
);
2704 AvailabilityAttr
*NewAttr
= S
.mergeAvailabilityAttr(
2705 ND
, AL
, NewII
, true /*Implicit*/, NewIntroduced
, NewDeprecated
,
2706 NewObsoleted
, IsUnavailable
, Str
, IsStrict
, Replacement
,
2708 PriorityModifier
+ Sema::AP_InferredFromOtherPlatform
);
2710 D
->addAttr(NewAttr
);
2712 } else if (S
.Context
.getTargetInfo().getTriple().isTvOS()) {
2713 // Transcribe "ios" to "tvos" (and add a new attribute) if the versioning
2714 // matches before the start of the tvOS platform.
2715 IdentifierInfo
*NewII
= nullptr;
2716 if (II
->getName() == "ios")
2717 NewII
= &S
.Context
.Idents
.get("tvos");
2718 else if (II
->getName() == "ios_app_extension")
2719 NewII
= &S
.Context
.Idents
.get("tvos_app_extension");
2722 const auto *SDKInfo
= S
.getDarwinSDKInfoForAvailabilityChecking();
2723 const auto *IOSToTvOSMapping
=
2724 SDKInfo
? SDKInfo
->getVersionMapping(
2725 DarwinSDKInfo::OSEnvPair::iOStoTvOSPair())
2728 auto AdjustTvOSVersion
=
2729 [IOSToTvOSMapping
](VersionTuple Version
) -> VersionTuple
{
2730 if (Version
.empty())
2733 if (IOSToTvOSMapping
) {
2734 if (auto MappedVersion
= IOSToTvOSMapping
->map(
2735 Version
, VersionTuple(0, 0), std::nullopt
)) {
2736 return *MappedVersion
;
2742 auto NewIntroduced
= AdjustTvOSVersion(Introduced
.Version
);
2743 auto NewDeprecated
= AdjustTvOSVersion(Deprecated
.Version
);
2744 auto NewObsoleted
= AdjustTvOSVersion(Obsoleted
.Version
);
2746 AvailabilityAttr
*NewAttr
= S
.mergeAvailabilityAttr(
2747 ND
, AL
, NewII
, true /*Implicit*/, NewIntroduced
, NewDeprecated
,
2748 NewObsoleted
, IsUnavailable
, Str
, IsStrict
, Replacement
,
2750 PriorityModifier
+ Sema::AP_InferredFromOtherPlatform
);
2752 D
->addAttr(NewAttr
);
2754 } else if (S
.Context
.getTargetInfo().getTriple().getOS() ==
2755 llvm::Triple::IOS
&&
2756 S
.Context
.getTargetInfo().getTriple().isMacCatalystEnvironment()) {
2757 auto GetSDKInfo
= [&]() {
2758 return S
.getDarwinSDKInfoForAvailabilityChecking(AL
.getRange().getBegin(),
2762 // Transcribe "ios" to "maccatalyst" (and add a new attribute).
2763 IdentifierInfo
*NewII
= nullptr;
2764 if (II
->getName() == "ios")
2765 NewII
= &S
.Context
.Idents
.get("maccatalyst");
2766 else if (II
->getName() == "ios_app_extension")
2767 NewII
= &S
.Context
.Idents
.get("maccatalyst_app_extension");
2769 auto MinMacCatalystVersion
= [](const VersionTuple
&V
) {
2772 if (V
.getMajor() < 13 ||
2773 (V
.getMajor() == 13 && V
.getMinor() && *V
.getMinor() < 1))
2774 return VersionTuple(13, 1); // The min Mac Catalyst version is 13.1.
2777 AvailabilityAttr
*NewAttr
= S
.mergeAvailabilityAttr(
2778 ND
, AL
.getRange(), NewII
, true /*Implicit*/,
2779 MinMacCatalystVersion(Introduced
.Version
),
2780 MinMacCatalystVersion(Deprecated
.Version
),
2781 MinMacCatalystVersion(Obsoleted
.Version
), IsUnavailable
, Str
,
2782 IsStrict
, Replacement
, Sema::AMK_None
,
2783 PriorityModifier
+ Sema::AP_InferredFromOtherPlatform
);
2785 D
->addAttr(NewAttr
);
2786 } else if (II
->getName() == "macos" && GetSDKInfo() &&
2787 (!Introduced
.Version
.empty() || !Deprecated
.Version
.empty() ||
2788 !Obsoleted
.Version
.empty())) {
2789 if (const auto *MacOStoMacCatalystMapping
=
2790 GetSDKInfo()->getVersionMapping(
2791 DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {
2792 // Infer Mac Catalyst availability from the macOS availability attribute
2793 // if it has versioned availability. Don't infer 'unavailable'. This
2794 // inferred availability has lower priority than the other availability
2795 // attributes that are inferred from 'ios'.
2796 NewII
= &S
.Context
.Idents
.get("maccatalyst");
2797 auto RemapMacOSVersion
=
2798 [&](const VersionTuple
&V
) -> std::optional
<VersionTuple
> {
2800 return std::nullopt
;
2801 // API_TO_BE_DEPRECATED is 100000.
2802 if (V
.getMajor() == 100000)
2803 return VersionTuple(100000);
2804 // The minimum iosmac version is 13.1
2805 return MacOStoMacCatalystMapping
->map(V
, VersionTuple(13, 1),
2808 std::optional
<VersionTuple
> NewIntroduced
=
2809 RemapMacOSVersion(Introduced
.Version
),
2811 RemapMacOSVersion(Deprecated
.Version
),
2813 RemapMacOSVersion(Obsoleted
.Version
);
2814 if (NewIntroduced
|| NewDeprecated
|| NewObsoleted
) {
2815 auto VersionOrEmptyVersion
=
2816 [](const std::optional
<VersionTuple
> &V
) -> VersionTuple
{
2817 return V
? *V
: VersionTuple();
2819 AvailabilityAttr
*NewAttr
= S
.mergeAvailabilityAttr(
2820 ND
, AL
.getRange(), NewII
, true /*Implicit*/,
2821 VersionOrEmptyVersion(NewIntroduced
),
2822 VersionOrEmptyVersion(NewDeprecated
),
2823 VersionOrEmptyVersion(NewObsoleted
), /*IsUnavailable=*/false, Str
,
2824 IsStrict
, Replacement
, Sema::AMK_None
,
2825 PriorityModifier
+ Sema::AP_InferredFromOtherPlatform
+
2826 Sema::AP_InferredFromOtherPlatform
);
2828 D
->addAttr(NewAttr
);
2835 static void handleExternalSourceSymbolAttr(Sema
&S
, Decl
*D
,
2836 const ParsedAttr
&AL
) {
2837 if (!AL
.checkAtLeastNumArgs(S
, 1) || !AL
.checkAtMostNumArgs(S
, 3))
2841 if (const auto *SE
= dyn_cast_or_null
<StringLiteral
>(AL
.getArgAsExpr(0)))
2842 Language
= SE
->getString();
2843 StringRef DefinedIn
;
2844 if (const auto *SE
= dyn_cast_or_null
<StringLiteral
>(AL
.getArgAsExpr(1)))
2845 DefinedIn
= SE
->getString();
2846 bool IsGeneratedDeclaration
= AL
.getArgAsIdent(2) != nullptr;
2848 D
->addAttr(::new (S
.Context
) ExternalSourceSymbolAttr(
2849 S
.Context
, AL
, Language
, DefinedIn
, IsGeneratedDeclaration
));
2853 static T
*mergeVisibilityAttr(Sema
&S
, Decl
*D
, const AttributeCommonInfo
&CI
,
2854 typename
T::VisibilityType value
) {
2855 T
*existingAttr
= D
->getAttr
<T
>();
2857 typename
T::VisibilityType existingValue
= existingAttr
->getVisibility();
2858 if (existingValue
== value
)
2860 S
.Diag(existingAttr
->getLocation(), diag::err_mismatched_visibility
);
2861 S
.Diag(CI
.getLoc(), diag::note_previous_attribute
);
2864 return ::new (S
.Context
) T(S
.Context
, CI
, value
);
2867 VisibilityAttr
*Sema::mergeVisibilityAttr(Decl
*D
,
2868 const AttributeCommonInfo
&CI
,
2869 VisibilityAttr::VisibilityType Vis
) {
2870 return ::mergeVisibilityAttr
<VisibilityAttr
>(*this, D
, CI
, Vis
);
2873 TypeVisibilityAttr
*
2874 Sema::mergeTypeVisibilityAttr(Decl
*D
, const AttributeCommonInfo
&CI
,
2875 TypeVisibilityAttr::VisibilityType Vis
) {
2876 return ::mergeVisibilityAttr
<TypeVisibilityAttr
>(*this, D
, CI
, Vis
);
2879 static void handleVisibilityAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
,
2880 bool isTypeVisibility
) {
2881 // Visibility attributes don't mean anything on a typedef.
2882 if (isa
<TypedefNameDecl
>(D
)) {
2883 S
.Diag(AL
.getRange().getBegin(), diag::warn_attribute_ignored
) << AL
;
2887 // 'type_visibility' can only go on a type or namespace.
2888 if (isTypeVisibility
&&
2889 !(isa
<TagDecl
>(D
) ||
2890 isa
<ObjCInterfaceDecl
>(D
) ||
2891 isa
<NamespaceDecl
>(D
))) {
2892 S
.Diag(AL
.getRange().getBegin(), diag::err_attribute_wrong_decl_type
)
2893 << AL
<< ExpectedTypeOrNamespace
;
2897 // Check that the argument is a string literal.
2899 SourceLocation LiteralLoc
;
2900 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, TypeStr
, &LiteralLoc
))
2903 VisibilityAttr::VisibilityType type
;
2904 if (!VisibilityAttr::ConvertStrToVisibilityType(TypeStr
, type
)) {
2905 S
.Diag(LiteralLoc
, diag::warn_attribute_type_not_supported
) << AL
2910 // Complain about attempts to use protected visibility on targets
2911 // (like Darwin) that don't support it.
2912 if (type
== VisibilityAttr::Protected
&&
2913 !S
.Context
.getTargetInfo().hasProtectedVisibility()) {
2914 S
.Diag(AL
.getLoc(), diag::warn_attribute_protected_visibility
);
2915 type
= VisibilityAttr::Default
;
2919 if (isTypeVisibility
) {
2920 newAttr
= S
.mergeTypeVisibilityAttr(
2921 D
, AL
, (TypeVisibilityAttr::VisibilityType
)type
);
2923 newAttr
= S
.mergeVisibilityAttr(D
, AL
, type
);
2926 D
->addAttr(newAttr
);
2929 static void handleObjCDirectAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
2930 // objc_direct cannot be set on methods declared in the context of a protocol
2931 if (isa
<ObjCProtocolDecl
>(D
->getDeclContext())) {
2932 S
.Diag(AL
.getLoc(), diag::err_objc_direct_on_protocol
) << false;
2936 if (S
.getLangOpts().ObjCRuntime
.allowsDirectDispatch()) {
2937 handleSimpleAttribute
<ObjCDirectAttr
>(S
, D
, AL
);
2939 S
.Diag(AL
.getLoc(), diag::warn_objc_direct_ignored
) << AL
;
2943 static void handleObjCDirectMembersAttr(Sema
&S
, Decl
*D
,
2944 const ParsedAttr
&AL
) {
2945 if (S
.getLangOpts().ObjCRuntime
.allowsDirectDispatch()) {
2946 handleSimpleAttribute
<ObjCDirectMembersAttr
>(S
, D
, AL
);
2948 S
.Diag(AL
.getLoc(), diag::warn_objc_direct_ignored
) << AL
;
2952 static void handleObjCMethodFamilyAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
2953 const auto *M
= cast
<ObjCMethodDecl
>(D
);
2954 if (!AL
.isArgIdent(0)) {
2955 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_n_type
)
2956 << AL
<< 1 << AANT_ArgumentIdentifier
;
2960 IdentifierLoc
*IL
= AL
.getArgAsIdent(0);
2961 ObjCMethodFamilyAttr::FamilyKind F
;
2962 if (!ObjCMethodFamilyAttr::ConvertStrToFamilyKind(IL
->Ident
->getName(), F
)) {
2963 S
.Diag(IL
->Loc
, diag::warn_attribute_type_not_supported
) << AL
<< IL
->Ident
;
2967 if (F
== ObjCMethodFamilyAttr::OMF_init
&&
2968 !M
->getReturnType()->isObjCObjectPointerType()) {
2969 S
.Diag(M
->getLocation(), diag::err_init_method_bad_return_type
)
2970 << M
->getReturnType();
2971 // Ignore the attribute.
2975 D
->addAttr(new (S
.Context
) ObjCMethodFamilyAttr(S
.Context
, AL
, F
));
2978 static void handleObjCNSObject(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
2979 if (const auto *TD
= dyn_cast
<TypedefNameDecl
>(D
)) {
2980 QualType T
= TD
->getUnderlyingType();
2981 if (!T
->isCARCBridgableType()) {
2982 S
.Diag(TD
->getLocation(), diag::err_nsobject_attribute
);
2986 else if (const auto *PD
= dyn_cast
<ObjCPropertyDecl
>(D
)) {
2987 QualType T
= PD
->getType();
2988 if (!T
->isCARCBridgableType()) {
2989 S
.Diag(PD
->getLocation(), diag::err_nsobject_attribute
);
2994 // It is okay to include this attribute on properties, e.g.:
2996 // @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
2998 // In this case it follows tradition and suppresses an error in the above
3000 S
.Diag(D
->getLocation(), diag::warn_nsobject_attribute
);
3002 D
->addAttr(::new (S
.Context
) ObjCNSObjectAttr(S
.Context
, AL
));
3005 static void handleObjCIndependentClass(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
3006 if (const auto *TD
= dyn_cast
<TypedefNameDecl
>(D
)) {
3007 QualType T
= TD
->getUnderlyingType();
3008 if (!T
->isObjCObjectPointerType()) {
3009 S
.Diag(TD
->getLocation(), diag::warn_ptr_independentclass_attribute
);
3013 S
.Diag(D
->getLocation(), diag::warn_independentclass_attribute
);
3016 D
->addAttr(::new (S
.Context
) ObjCIndependentClassAttr(S
.Context
, AL
));
3019 static void handleBlocksAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
3020 if (!AL
.isArgIdent(0)) {
3021 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_n_type
)
3022 << AL
<< 1 << AANT_ArgumentIdentifier
;
3026 IdentifierInfo
*II
= AL
.getArgAsIdent(0)->Ident
;
3027 BlocksAttr::BlockType type
;
3028 if (!BlocksAttr::ConvertStrToBlockType(II
->getName(), type
)) {
3029 S
.Diag(AL
.getLoc(), diag::warn_attribute_type_not_supported
) << AL
<< II
;
3033 D
->addAttr(::new (S
.Context
) BlocksAttr(S
.Context
, AL
, type
));
3036 static void handleSentinelAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
3037 unsigned sentinel
= (unsigned)SentinelAttr::DefaultSentinel
;
3038 if (AL
.getNumArgs() > 0) {
3039 Expr
*E
= AL
.getArgAsExpr(0);
3040 std::optional
<llvm::APSInt
> Idx
= llvm::APSInt(32);
3041 if (E
->isTypeDependent() || !(Idx
= E
->getIntegerConstantExpr(S
.Context
))) {
3042 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_n_type
)
3043 << AL
<< 1 << AANT_ArgumentIntegerConstant
<< E
->getSourceRange();
3047 if (Idx
->isSigned() && Idx
->isNegative()) {
3048 S
.Diag(AL
.getLoc(), diag::err_attribute_sentinel_less_than_zero
)
3049 << E
->getSourceRange();
3053 sentinel
= Idx
->getZExtValue();
3056 unsigned nullPos
= (unsigned)SentinelAttr::DefaultNullPos
;
3057 if (AL
.getNumArgs() > 1) {
3058 Expr
*E
= AL
.getArgAsExpr(1);
3059 std::optional
<llvm::APSInt
> Idx
= llvm::APSInt(32);
3060 if (E
->isTypeDependent() || !(Idx
= E
->getIntegerConstantExpr(S
.Context
))) {
3061 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_n_type
)
3062 << AL
<< 2 << AANT_ArgumentIntegerConstant
<< E
->getSourceRange();
3065 nullPos
= Idx
->getZExtValue();
3067 if ((Idx
->isSigned() && Idx
->isNegative()) || nullPos
> 1) {
3068 // FIXME: This error message could be improved, it would be nice
3069 // to say what the bounds actually are.
3070 S
.Diag(AL
.getLoc(), diag::err_attribute_sentinel_not_zero_or_one
)
3071 << E
->getSourceRange();
3076 if (const auto *FD
= dyn_cast
<FunctionDecl
>(D
)) {
3077 const FunctionType
*FT
= FD
->getType()->castAs
<FunctionType
>();
3078 if (isa
<FunctionNoProtoType
>(FT
)) {
3079 S
.Diag(AL
.getLoc(), diag::warn_attribute_sentinel_named_arguments
);
3083 if (!cast
<FunctionProtoType
>(FT
)->isVariadic()) {
3084 S
.Diag(AL
.getLoc(), diag::warn_attribute_sentinel_not_variadic
) << 0;
3087 } else if (const auto *MD
= dyn_cast
<ObjCMethodDecl
>(D
)) {
3088 if (!MD
->isVariadic()) {
3089 S
.Diag(AL
.getLoc(), diag::warn_attribute_sentinel_not_variadic
) << 0;
3092 } else if (const auto *BD
= dyn_cast
<BlockDecl
>(D
)) {
3093 if (!BD
->isVariadic()) {
3094 S
.Diag(AL
.getLoc(), diag::warn_attribute_sentinel_not_variadic
) << 1;
3097 } else if (const auto *V
= dyn_cast
<VarDecl
>(D
)) {
3098 QualType Ty
= V
->getType();
3099 if (Ty
->isBlockPointerType() || Ty
->isFunctionPointerType()) {
3100 const FunctionType
*FT
= Ty
->isFunctionPointerType()
3101 ? D
->getFunctionType()
3102 : Ty
->castAs
<BlockPointerType
>()
3104 ->castAs
<FunctionType
>();
3105 if (!cast
<FunctionProtoType
>(FT
)->isVariadic()) {
3106 int m
= Ty
->isFunctionPointerType() ? 0 : 1;
3107 S
.Diag(AL
.getLoc(), diag::warn_attribute_sentinel_not_variadic
) << m
;
3111 S
.Diag(AL
.getLoc(), diag::warn_attribute_wrong_decl_type
)
3112 << AL
<< ExpectedFunctionMethodOrBlock
;
3116 S
.Diag(AL
.getLoc(), diag::warn_attribute_wrong_decl_type
)
3117 << AL
<< ExpectedFunctionMethodOrBlock
;
3120 D
->addAttr(::new (S
.Context
) SentinelAttr(S
.Context
, AL
, sentinel
, nullPos
));
3123 static void handleWarnUnusedResult(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
3124 if (D
->getFunctionType() &&
3125 D
->getFunctionType()->getReturnType()->isVoidType() &&
3126 !isa
<CXXConstructorDecl
>(D
)) {
3127 S
.Diag(AL
.getLoc(), diag::warn_attribute_void_function_method
) << AL
<< 0;
3130 if (const auto *MD
= dyn_cast
<ObjCMethodDecl
>(D
))
3131 if (MD
->getReturnType()->isVoidType()) {
3132 S
.Diag(AL
.getLoc(), diag::warn_attribute_void_function_method
) << AL
<< 1;
3137 if (AL
.isStandardAttributeSyntax() && !AL
.getScopeName()) {
3138 // The standard attribute cannot be applied to variable declarations such
3139 // as a function pointer.
3140 if (isa
<VarDecl
>(D
))
3141 S
.Diag(AL
.getLoc(), diag::warn_attribute_wrong_decl_type_str
)
3142 << AL
<< "functions, classes, or enumerations";
3144 // If this is spelled as the standard C++17 attribute, but not in C++17,
3145 // warn about using it as an extension. If there are attribute arguments,
3146 // then claim it's a C++2a extension instead.
3147 // FIXME: If WG14 does not seem likely to adopt the same feature, add an
3148 // extension warning for C2x mode.
3149 const LangOptions
&LO
= S
.getLangOpts();
3150 if (AL
.getNumArgs() == 1) {
3151 if (LO
.CPlusPlus
&& !LO
.CPlusPlus20
)
3152 S
.Diag(AL
.getLoc(), diag::ext_cxx20_attr
) << AL
;
3154 // Since this is spelled [[nodiscard]], get the optional string
3155 // literal. If in C++ mode, but not in C++2a mode, diagnose as an
3157 // FIXME: C2x should support this feature as well, even as an extension.
3158 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Str
, nullptr))
3160 } else if (LO
.CPlusPlus
&& !LO
.CPlusPlus17
)
3161 S
.Diag(AL
.getLoc(), diag::ext_cxx17_attr
) << AL
;
3164 if ((!AL
.isGNUAttribute() &&
3165 !(AL
.isStandardAttributeSyntax() && AL
.isClangScope())) &&
3166 isa
<TypedefNameDecl
>(D
)) {
3167 S
.Diag(AL
.getLoc(), diag::warn_unused_result_typedef_unsupported_spelling
)
3172 D
->addAttr(::new (S
.Context
) WarnUnusedResultAttr(S
.Context
, AL
, Str
));
3175 static void handleWeakImportAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
3176 // weak_import only applies to variable & function declarations.
3178 if (!D
->canBeWeakImported(isDef
)) {
3180 S
.Diag(AL
.getLoc(), diag::warn_attribute_invalid_on_definition
)
3182 else if (isa
<ObjCPropertyDecl
>(D
) || isa
<ObjCMethodDecl
>(D
) ||
3183 (S
.Context
.getTargetInfo().getTriple().isOSDarwin() &&
3184 (isa
<ObjCInterfaceDecl
>(D
) || isa
<EnumDecl
>(D
)))) {
3185 // Nothing to warn about here.
3187 S
.Diag(AL
.getLoc(), diag::warn_attribute_wrong_decl_type
)
3188 << AL
<< ExpectedVariableOrFunction
;
3193 D
->addAttr(::new (S
.Context
) WeakImportAttr(S
.Context
, AL
));
3196 // Handles reqd_work_group_size and work_group_size_hint.
3197 template <typename WorkGroupAttr
>
3198 static void handleWorkGroupSize(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
3200 for (unsigned i
= 0; i
< 3; ++i
) {
3201 const Expr
*E
= AL
.getArgAsExpr(i
);
3202 if (!checkUInt32Argument(S
, AL
, E
, WGSize
[i
], i
,
3203 /*StrictlyUnsigned=*/true))
3205 if (WGSize
[i
] == 0) {
3206 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_is_zero
)
3207 << AL
<< E
->getSourceRange();
3212 WorkGroupAttr
*Existing
= D
->getAttr
<WorkGroupAttr
>();
3213 if (Existing
&& !(Existing
->getXDim() == WGSize
[0] &&
3214 Existing
->getYDim() == WGSize
[1] &&
3215 Existing
->getZDim() == WGSize
[2]))
3216 S
.Diag(AL
.getLoc(), diag::warn_duplicate_attribute
) << AL
;
3218 D
->addAttr(::new (S
.Context
)
3219 WorkGroupAttr(S
.Context
, AL
, WGSize
[0], WGSize
[1], WGSize
[2]));
3222 // Handles intel_reqd_sub_group_size.
3223 static void handleSubGroupSize(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
3225 const Expr
*E
= AL
.getArgAsExpr(0);
3226 if (!checkUInt32Argument(S
, AL
, E
, SGSize
))
3229 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_is_zero
)
3230 << AL
<< E
->getSourceRange();
3234 OpenCLIntelReqdSubGroupSizeAttr
*Existing
=
3235 D
->getAttr
<OpenCLIntelReqdSubGroupSizeAttr
>();
3236 if (Existing
&& Existing
->getSubGroupSize() != SGSize
)
3237 S
.Diag(AL
.getLoc(), diag::warn_duplicate_attribute
) << AL
;
3239 D
->addAttr(::new (S
.Context
)
3240 OpenCLIntelReqdSubGroupSizeAttr(S
.Context
, AL
, SGSize
));
3243 static void handleVecTypeHint(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
3244 if (!AL
.hasParsedType()) {
3245 S
.Diag(AL
.getLoc(), diag::err_attribute_wrong_number_arguments
) << AL
<< 1;
3249 TypeSourceInfo
*ParmTSI
= nullptr;
3250 QualType ParmType
= S
.GetTypeFromParser(AL
.getTypeArg(), &ParmTSI
);
3251 assert(ParmTSI
&& "no type source info for attribute argument");
3253 if (!ParmType
->isExtVectorType() && !ParmType
->isFloatingType() &&
3254 (ParmType
->isBooleanType() ||
3255 !ParmType
->isIntegralType(S
.getASTContext()))) {
3256 S
.Diag(AL
.getLoc(), diag::err_attribute_invalid_argument
) << 2 << AL
;
3260 if (VecTypeHintAttr
*A
= D
->getAttr
<VecTypeHintAttr
>()) {
3261 if (!S
.Context
.hasSameType(A
->getTypeHint(), ParmType
)) {
3262 S
.Diag(AL
.getLoc(), diag::warn_duplicate_attribute
) << AL
;
3267 D
->addAttr(::new (S
.Context
) VecTypeHintAttr(S
.Context
, AL
, ParmTSI
));
3270 SectionAttr
*Sema::mergeSectionAttr(Decl
*D
, const AttributeCommonInfo
&CI
,
3272 // Explicit or partial specializations do not inherit
3273 // the section attribute from the primary template.
3274 if (const auto *FD
= dyn_cast
<FunctionDecl
>(D
)) {
3275 if (CI
.getAttributeSpellingListIndex() == SectionAttr::Declspec_allocate
&&
3276 FD
->isFunctionTemplateSpecialization())
3279 if (SectionAttr
*ExistingAttr
= D
->getAttr
<SectionAttr
>()) {
3280 if (ExistingAttr
->getName() == Name
)
3282 Diag(ExistingAttr
->getLocation(), diag::warn_mismatched_section
)
3284 Diag(CI
.getLoc(), diag::note_previous_attribute
);
3287 return ::new (Context
) SectionAttr(Context
, CI
, Name
);
3290 /// Used to implement to perform semantic checking on
3291 /// attribute((section("foo"))) specifiers.
3293 /// In this case, "foo" is passed in to be checked. If the section
3294 /// specifier is invalid, return an Error that indicates the problem.
3296 /// This is a simple quality of implementation feature to catch errors
3297 /// and give good diagnostics in cases when the assembler or code generator
3298 /// would otherwise reject the section specifier.
3299 llvm::Error
Sema::isValidSectionSpecifier(StringRef SecName
) {
3300 if (!Context
.getTargetInfo().getTriple().isOSDarwin())
3301 return llvm::Error::success();
3303 // Let MCSectionMachO validate this.
3304 StringRef Segment
, Section
;
3305 unsigned TAA
, StubSize
;
3307 return llvm::MCSectionMachO::ParseSectionSpecifier(SecName
, Segment
, Section
,
3308 TAA
, HasTAA
, StubSize
);
3311 bool Sema::checkSectionName(SourceLocation LiteralLoc
, StringRef SecName
) {
3312 if (llvm::Error E
= isValidSectionSpecifier(SecName
)) {
3313 Diag(LiteralLoc
, diag::err_attribute_section_invalid_for_target
)
3314 << toString(std::move(E
)) << 1 /*'section'*/;
3320 static void handleSectionAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
3321 // Make sure that there is a string literal as the sections's single
3324 SourceLocation LiteralLoc
;
3325 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Str
, &LiteralLoc
))
3328 if (!S
.checkSectionName(LiteralLoc
, Str
))
3331 SectionAttr
*NewAttr
= S
.mergeSectionAttr(D
, AL
, Str
);
3333 D
->addAttr(NewAttr
);
3334 if (isa
<FunctionDecl
, FunctionTemplateDecl
, ObjCMethodDecl
,
3335 ObjCPropertyDecl
>(D
))
3336 S
.UnifySection(NewAttr
->getName(),
3337 ASTContext::PSF_Execute
| ASTContext::PSF_Read
,
3338 cast
<NamedDecl
>(D
));
3342 // This is used for `__declspec(code_seg("segname"))` on a decl.
3343 // `#pragma code_seg("segname")` uses checkSectionName() instead.
3344 static bool checkCodeSegName(Sema
&S
, SourceLocation LiteralLoc
,
3345 StringRef CodeSegName
) {
3346 if (llvm::Error E
= S
.isValidSectionSpecifier(CodeSegName
)) {
3347 S
.Diag(LiteralLoc
, diag::err_attribute_section_invalid_for_target
)
3348 << toString(std::move(E
)) << 0 /*'code-seg'*/;
3355 CodeSegAttr
*Sema::mergeCodeSegAttr(Decl
*D
, const AttributeCommonInfo
&CI
,
3357 // Explicit or partial specializations do not inherit
3358 // the code_seg attribute from the primary template.
3359 if (const auto *FD
= dyn_cast
<FunctionDecl
>(D
)) {
3360 if (FD
->isFunctionTemplateSpecialization())
3363 if (const auto *ExistingAttr
= D
->getAttr
<CodeSegAttr
>()) {
3364 if (ExistingAttr
->getName() == Name
)
3366 Diag(ExistingAttr
->getLocation(), diag::warn_mismatched_section
)
3368 Diag(CI
.getLoc(), diag::note_previous_attribute
);
3371 return ::new (Context
) CodeSegAttr(Context
, CI
, Name
);
3374 static void handleCodeSegAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
3376 SourceLocation LiteralLoc
;
3377 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Str
, &LiteralLoc
))
3379 if (!checkCodeSegName(S
, LiteralLoc
, Str
))
3381 if (const auto *ExistingAttr
= D
->getAttr
<CodeSegAttr
>()) {
3382 if (!ExistingAttr
->isImplicit()) {
3384 ExistingAttr
->getName() == Str
3385 ? diag::warn_duplicate_codeseg_attribute
3386 : diag::err_conflicting_codeseg_attribute
);
3389 D
->dropAttr
<CodeSegAttr
>();
3391 if (CodeSegAttr
*CSA
= S
.mergeCodeSegAttr(D
, AL
, Str
))
3395 // Check for things we'd like to warn about. Multiversioning issues are
3396 // handled later in the process, once we know how many exist.
3397 bool Sema::checkTargetAttr(SourceLocation LiteralLoc
, StringRef AttrStr
) {
3398 enum FirstParam
{ Unsupported
, Duplicate
, Unknown
};
3399 enum SecondParam
{ None
, CPU
, Tune
};
3400 enum ThirdParam
{ Target
, TargetClones
};
3401 if (AttrStr
.contains("fpmath="))
3402 return Diag(LiteralLoc
, diag::warn_unsupported_target_attribute
)
3403 << Unsupported
<< None
<< "fpmath=" << Target
;
3405 // Diagnose use of tune if target doesn't support it.
3406 if (!Context
.getTargetInfo().supportsTargetAttributeTune() &&
3407 AttrStr
.contains("tune="))
3408 return Diag(LiteralLoc
, diag::warn_unsupported_target_attribute
)
3409 << Unsupported
<< None
<< "tune=" << Target
;
3411 ParsedTargetAttr ParsedAttrs
=
3412 Context
.getTargetInfo().parseTargetAttr(AttrStr
);
3414 if (!ParsedAttrs
.CPU
.empty() &&
3415 !Context
.getTargetInfo().isValidCPUName(ParsedAttrs
.CPU
))
3416 return Diag(LiteralLoc
, diag::warn_unsupported_target_attribute
)
3417 << Unknown
<< CPU
<< ParsedAttrs
.CPU
<< Target
;
3419 if (!ParsedAttrs
.Tune
.empty() &&
3420 !Context
.getTargetInfo().isValidCPUName(ParsedAttrs
.Tune
))
3421 return Diag(LiteralLoc
, diag::warn_unsupported_target_attribute
)
3422 << Unknown
<< Tune
<< ParsedAttrs
.Tune
<< Target
;
3424 if (ParsedAttrs
.Duplicate
!= "")
3425 return Diag(LiteralLoc
, diag::warn_unsupported_target_attribute
)
3426 << Duplicate
<< None
<< ParsedAttrs
.Duplicate
<< Target
;
3428 for (const auto &Feature
: ParsedAttrs
.Features
) {
3429 auto CurFeature
= StringRef(Feature
).drop_front(); // remove + or -.
3430 if (!Context
.getTargetInfo().isValidFeatureName(CurFeature
))
3431 return Diag(LiteralLoc
, diag::warn_unsupported_target_attribute
)
3432 << Unsupported
<< None
<< CurFeature
<< Target
;
3435 TargetInfo::BranchProtectionInfo BPI
;
3437 if (ParsedAttrs
.BranchProtection
.empty())
3439 if (!Context
.getTargetInfo().validateBranchProtection(
3440 ParsedAttrs
.BranchProtection
, ParsedAttrs
.CPU
, BPI
, DiagMsg
)) {
3441 if (DiagMsg
.empty())
3442 return Diag(LiteralLoc
, diag::warn_unsupported_target_attribute
)
3443 << Unsupported
<< None
<< "branch-protection" << Target
;
3444 return Diag(LiteralLoc
, diag::err_invalid_branch_protection_spec
)
3447 if (!DiagMsg
.empty())
3448 Diag(LiteralLoc
, diag::warn_unsupported_branch_protection_spec
) << DiagMsg
;
3453 // Check Target Version attrs
3454 bool Sema::checkTargetVersionAttr(SourceLocation LiteralLoc
, StringRef
&AttrStr
,
3456 enum FirstParam
{ Unsupported
};
3457 enum SecondParam
{ None
};
3458 enum ThirdParam
{ Target
, TargetClones
, TargetVersion
};
3459 if (AttrStr
.trim() == "default")
3461 llvm::SmallVector
<StringRef
, 8> Features
;
3462 AttrStr
.split(Features
, "+");
3463 for (auto &CurFeature
: Features
) {
3464 CurFeature
= CurFeature
.trim();
3465 if (CurFeature
== "default")
3467 if (!Context
.getTargetInfo().validateCpuSupports(CurFeature
))
3468 return Diag(LiteralLoc
, diag::warn_unsupported_target_attribute
)
3469 << Unsupported
<< None
<< CurFeature
<< TargetVersion
;
3474 static void handleTargetVersionAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
3476 SourceLocation LiteralLoc
;
3477 bool isDefault
= false;
3478 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Str
, &LiteralLoc
) ||
3479 S
.checkTargetVersionAttr(LiteralLoc
, Str
, isDefault
))
3481 // Do not create default only target_version attribute
3483 TargetVersionAttr
*NewAttr
=
3484 ::new (S
.Context
) TargetVersionAttr(S
.Context
, AL
, Str
);
3485 D
->addAttr(NewAttr
);
3489 static void handleTargetAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
3491 SourceLocation LiteralLoc
;
3492 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Str
, &LiteralLoc
) ||
3493 S
.checkTargetAttr(LiteralLoc
, Str
))
3496 TargetAttr
*NewAttr
= ::new (S
.Context
) TargetAttr(S
.Context
, AL
, Str
);
3497 D
->addAttr(NewAttr
);
3500 bool Sema::checkTargetClonesAttrString(
3501 SourceLocation LiteralLoc
, StringRef Str
, const StringLiteral
*Literal
,
3502 bool &HasDefault
, bool &HasCommas
, bool &HasNotDefault
,
3503 SmallVectorImpl
<SmallString
<64>> &StringsBuffer
) {
3504 enum FirstParam
{ Unsupported
, Duplicate
, Unknown
};
3505 enum SecondParam
{ None
, CPU
, Tune
};
3506 enum ThirdParam
{ Target
, TargetClones
};
3507 HasCommas
= HasCommas
|| Str
.contains(',');
3508 // Warn on empty at the beginning of a string.
3509 if (Str
.size() == 0)
3510 return Diag(LiteralLoc
, diag::warn_unsupported_target_attribute
)
3511 << Unsupported
<< None
<< "" << TargetClones
;
3513 std::pair
<StringRef
, StringRef
> Parts
= {{}, Str
};
3514 while (!Parts
.second
.empty()) {
3515 Parts
= Parts
.second
.split(',');
3516 StringRef Cur
= Parts
.first
.trim();
3517 SourceLocation CurLoc
= Literal
->getLocationOfByte(
3518 Cur
.data() - Literal
->getString().data(), getSourceManager(),
3519 getLangOpts(), Context
.getTargetInfo());
3521 bool DefaultIsDupe
= false;
3522 bool HasCodeGenImpact
= false;
3524 return Diag(CurLoc
, diag::warn_unsupported_target_attribute
)
3525 << Unsupported
<< None
<< "" << TargetClones
;
3527 if (Context
.getTargetInfo().getTriple().isAArch64()) {
3528 // AArch64 target clones specific
3529 if (Cur
== "default") {
3530 DefaultIsDupe
= HasDefault
;
3532 if (llvm::is_contained(StringsBuffer
, Cur
) || DefaultIsDupe
)
3533 Diag(CurLoc
, diag::warn_target_clone_duplicate_options
);
3535 StringsBuffer
.push_back(Cur
);
3537 std::pair
<StringRef
, StringRef
> CurParts
= {{}, Cur
};
3538 llvm::SmallVector
<StringRef
, 8> CurFeatures
;
3539 while (!CurParts
.second
.empty()) {
3540 CurParts
= CurParts
.second
.split('+');
3541 StringRef CurFeature
= CurParts
.first
.trim();
3542 if (!Context
.getTargetInfo().validateCpuSupports(CurFeature
)) {
3543 Diag(CurLoc
, diag::warn_unsupported_target_attribute
)
3544 << Unsupported
<< None
<< CurFeature
<< TargetClones
;
3547 std::string Options
;
3548 if (Context
.getTargetInfo().getFeatureDepOptions(CurFeature
, Options
))
3549 HasCodeGenImpact
= true;
3550 CurFeatures
.push_back(CurFeature
);
3552 // Canonize TargetClones Attributes
3553 llvm::sort(CurFeatures
);
3554 SmallString
<64> Res
;
3555 for (auto &CurFeat
: CurFeatures
) {
3556 if (!Res
.equals(""))
3558 Res
.append(CurFeat
);
3560 if (llvm::is_contained(StringsBuffer
, Res
) || DefaultIsDupe
)
3561 Diag(CurLoc
, diag::warn_target_clone_duplicate_options
);
3562 else if (!HasCodeGenImpact
)
3563 // Ignore features in target_clone attribute that don't impact
3565 Diag(CurLoc
, diag::warn_target_clone_no_impact_options
);
3566 else if (!Res
.empty()) {
3567 StringsBuffer
.push_back(Res
);
3568 HasNotDefault
= true;
3572 // Other targets ( currently X86 )
3573 if (Cur
.startswith("arch=")) {
3574 if (!Context
.getTargetInfo().isValidCPUName(
3575 Cur
.drop_front(sizeof("arch=") - 1)))
3576 return Diag(CurLoc
, diag::warn_unsupported_target_attribute
)
3577 << Unsupported
<< CPU
<< Cur
.drop_front(sizeof("arch=") - 1)
3579 } else if (Cur
== "default") {
3580 DefaultIsDupe
= HasDefault
;
3582 } else if (!Context
.getTargetInfo().isValidFeatureName(Cur
))
3583 return Diag(CurLoc
, diag::warn_unsupported_target_attribute
)
3584 << Unsupported
<< None
<< Cur
<< TargetClones
;
3585 if (llvm::is_contained(StringsBuffer
, Cur
) || DefaultIsDupe
)
3586 Diag(CurLoc
, diag::warn_target_clone_duplicate_options
);
3587 // Note: Add even if there are duplicates, since it changes name mangling.
3588 StringsBuffer
.push_back(Cur
);
3591 if (Str
.rtrim().endswith(","))
3592 return Diag(LiteralLoc
, diag::warn_unsupported_target_attribute
)
3593 << Unsupported
<< None
<< "" << TargetClones
;
3597 static void handleTargetClonesAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
3598 if (S
.Context
.getTargetInfo().getTriple().isAArch64() &&
3599 !S
.Context
.getTargetInfo().hasFeature("fmv"))
3602 // Ensure we don't combine these with themselves, since that causes some
3603 // confusing behavior.
3604 if (const auto *Other
= D
->getAttr
<TargetClonesAttr
>()) {
3605 S
.Diag(AL
.getLoc(), diag::err_disallowed_duplicate_attribute
) << AL
;
3606 S
.Diag(Other
->getLocation(), diag::note_conflicting_attribute
);
3609 if (checkAttrMutualExclusion
<TargetClonesAttr
>(S
, D
, AL
))
3612 SmallVector
<StringRef
, 2> Strings
;
3613 SmallVector
<SmallString
<64>, 2> StringsBuffer
;
3614 bool HasCommas
= false, HasDefault
= false, HasNotDefault
= false;
3616 for (unsigned I
= 0, E
= AL
.getNumArgs(); I
!= E
; ++I
) {
3618 SourceLocation LiteralLoc
;
3619 if (!S
.checkStringLiteralArgumentAttr(AL
, I
, CurStr
, &LiteralLoc
) ||
3620 S
.checkTargetClonesAttrString(
3622 cast
<StringLiteral
>(AL
.getArgAsExpr(I
)->IgnoreParenCasts()),
3623 HasDefault
, HasCommas
, HasNotDefault
, StringsBuffer
))
3626 for (auto &SmallStr
: StringsBuffer
)
3627 Strings
.push_back(SmallStr
.str());
3629 if (HasCommas
&& AL
.getNumArgs() > 1)
3630 S
.Diag(AL
.getLoc(), diag::warn_target_clone_mixed_values
);
3632 if (S
.Context
.getTargetInfo().getTriple().isAArch64() && !HasDefault
) {
3633 // Add default attribute if there is no one
3635 Strings
.push_back("default");
3639 S
.Diag(AL
.getLoc(), diag::err_target_clone_must_have_default
);
3643 // FIXME: We could probably figure out how to get this to work for lambdas
3645 if (const auto *MD
= dyn_cast
<CXXMethodDecl
>(D
)) {
3646 if (MD
->getParent()->isLambda()) {
3647 S
.Diag(D
->getLocation(), diag::err_multiversion_doesnt_support
)
3648 << static_cast<unsigned>(MultiVersionKind::TargetClones
)
3654 // No multiversion if we have default version only.
3655 if (S
.Context
.getTargetInfo().getTriple().isAArch64() && !HasNotDefault
)
3658 cast
<FunctionDecl
>(D
)->setIsMultiVersion();
3659 TargetClonesAttr
*NewAttr
= ::new (S
.Context
)
3660 TargetClonesAttr(S
.Context
, AL
, Strings
.data(), Strings
.size());
3661 D
->addAttr(NewAttr
);
3664 static void handleMinVectorWidthAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
3665 Expr
*E
= AL
.getArgAsExpr(0);
3667 if (!checkUInt32Argument(S
, AL
, E
, VecWidth
)) {
3672 MinVectorWidthAttr
*Existing
= D
->getAttr
<MinVectorWidthAttr
>();
3673 if (Existing
&& Existing
->getVectorWidth() != VecWidth
) {
3674 S
.Diag(AL
.getLoc(), diag::warn_duplicate_attribute
) << AL
;
3678 D
->addAttr(::new (S
.Context
) MinVectorWidthAttr(S
.Context
, AL
, VecWidth
));
3681 static void handleCleanupAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
3682 Expr
*E
= AL
.getArgAsExpr(0);
3683 SourceLocation Loc
= E
->getExprLoc();
3684 FunctionDecl
*FD
= nullptr;
3685 DeclarationNameInfo NI
;
3687 // gcc only allows for simple identifiers. Since we support more than gcc, we
3688 // will warn the user.
3689 if (auto *DRE
= dyn_cast
<DeclRefExpr
>(E
)) {
3690 if (DRE
->hasQualifier())
3691 S
.Diag(Loc
, diag::warn_cleanup_ext
);
3692 FD
= dyn_cast
<FunctionDecl
>(DRE
->getDecl());
3693 NI
= DRE
->getNameInfo();
3695 S
.Diag(Loc
, diag::err_attribute_cleanup_arg_not_function
) << 1
3699 } else if (auto *ULE
= dyn_cast
<UnresolvedLookupExpr
>(E
)) {
3700 if (ULE
->hasExplicitTemplateArgs())
3701 S
.Diag(Loc
, diag::warn_cleanup_ext
);
3702 FD
= S
.ResolveSingleFunctionTemplateSpecialization(ULE
, true);
3703 NI
= ULE
->getNameInfo();
3705 S
.Diag(Loc
, diag::err_attribute_cleanup_arg_not_function
) << 2
3707 if (ULE
->getType() == S
.Context
.OverloadTy
)
3708 S
.NoteAllOverloadCandidates(ULE
);
3712 S
.Diag(Loc
, diag::err_attribute_cleanup_arg_not_function
) << 0;
3716 if (FD
->getNumParams() != 1) {
3717 S
.Diag(Loc
, diag::err_attribute_cleanup_func_must_take_one_arg
)
3722 // We're currently more strict than GCC about what function types we accept.
3723 // If this ever proves to be a problem it should be easy to fix.
3724 QualType Ty
= S
.Context
.getPointerType(cast
<VarDecl
>(D
)->getType());
3725 QualType ParamTy
= FD
->getParamDecl(0)->getType();
3726 if (S
.CheckAssignmentConstraints(FD
->getParamDecl(0)->getLocation(),
3727 ParamTy
, Ty
) != Sema::Compatible
) {
3728 S
.Diag(Loc
, diag::err_attribute_cleanup_func_arg_incompatible_type
)
3729 << NI
.getName() << ParamTy
<< Ty
;
3733 D
->addAttr(::new (S
.Context
) CleanupAttr(S
.Context
, AL
, FD
));
3736 static void handleEnumExtensibilityAttr(Sema
&S
, Decl
*D
,
3737 const ParsedAttr
&AL
) {
3738 if (!AL
.isArgIdent(0)) {
3739 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_n_type
)
3740 << AL
<< 0 << AANT_ArgumentIdentifier
;
3744 EnumExtensibilityAttr::Kind ExtensibilityKind
;
3745 IdentifierInfo
*II
= AL
.getArgAsIdent(0)->Ident
;
3746 if (!EnumExtensibilityAttr::ConvertStrToKind(II
->getName(),
3747 ExtensibilityKind
)) {
3748 S
.Diag(AL
.getLoc(), diag::warn_attribute_type_not_supported
) << AL
<< II
;
3752 D
->addAttr(::new (S
.Context
)
3753 EnumExtensibilityAttr(S
.Context
, AL
, ExtensibilityKind
));
3756 /// Handle __attribute__((format_arg((idx)))) attribute based on
3757 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
3758 static void handleFormatArgAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
3759 Expr
*IdxExpr
= AL
.getArgAsExpr(0);
3761 if (!checkFunctionOrMethodParameterIndex(S
, D
, AL
, 1, IdxExpr
, Idx
))
3764 // Make sure the format string is really a string.
3765 QualType Ty
= getFunctionOrMethodParamType(D
, Idx
.getASTIndex());
3767 bool NotNSStringTy
= !isNSStringType(Ty
, S
.Context
);
3768 if (NotNSStringTy
&&
3769 !isCFStringType(Ty
, S
.Context
) &&
3770 (!Ty
->isPointerType() ||
3771 !Ty
->castAs
<PointerType
>()->getPointeeType()->isCharType())) {
3772 S
.Diag(AL
.getLoc(), diag::err_format_attribute_not
)
3773 << IdxExpr
->getSourceRange() << getFunctionOrMethodParamRange(D
, 0);
3776 Ty
= getFunctionOrMethodResultType(D
);
3777 // replace instancetype with the class type
3778 auto Instancetype
= S
.Context
.getObjCInstanceTypeDecl()->getTypeForDecl();
3779 if (Ty
->getAs
<TypedefType
>() == Instancetype
)
3780 if (auto *OMD
= dyn_cast
<ObjCMethodDecl
>(D
))
3781 if (auto *Interface
= OMD
->getClassInterface())
3782 Ty
= S
.Context
.getObjCObjectPointerType(
3783 QualType(Interface
->getTypeForDecl(), 0));
3784 if (!isNSStringType(Ty
, S
.Context
, /*AllowNSAttributedString=*/true) &&
3785 !isCFStringType(Ty
, S
.Context
) &&
3786 (!Ty
->isPointerType() ||
3787 !Ty
->castAs
<PointerType
>()->getPointeeType()->isCharType())) {
3788 S
.Diag(AL
.getLoc(), diag::err_format_attribute_result_not
)
3789 << (NotNSStringTy
? "string type" : "NSString")
3790 << IdxExpr
->getSourceRange() << getFunctionOrMethodParamRange(D
, 0);
3794 D
->addAttr(::new (S
.Context
) FormatArgAttr(S
.Context
, AL
, Idx
));
3797 enum FormatAttrKind
{
3806 /// getFormatAttrKind - Map from format attribute names to supported format
3808 static FormatAttrKind
getFormatAttrKind(StringRef Format
) {
3809 return llvm::StringSwitch
<FormatAttrKind
>(Format
)
3810 // Check for formats that get handled specially.
3811 .Case("NSString", NSStringFormat
)
3812 .Case("CFString", CFStringFormat
)
3813 .Case("strftime", StrftimeFormat
)
3815 // Otherwise, check for supported formats.
3816 .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat
)
3817 .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat
)
3818 .Case("kprintf", SupportedFormat
) // OpenBSD.
3819 .Case("freebsd_kprintf", SupportedFormat
) // FreeBSD.
3820 .Case("os_trace", SupportedFormat
)
3821 .Case("os_log", SupportedFormat
)
3823 .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat
)
3824 .Default(InvalidFormat
);
3827 /// Handle __attribute__((init_priority(priority))) attributes based on
3828 /// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
3829 static void handleInitPriorityAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
3830 if (!S
.getLangOpts().CPlusPlus
) {
3831 S
.Diag(AL
.getLoc(), diag::warn_attribute_ignored
) << AL
;
3835 if (S
.getLangOpts().HLSL
) {
3836 S
.Diag(AL
.getLoc(), diag::err_hlsl_init_priority_unsupported
);
3840 if (S
.getCurFunctionOrMethodDecl()) {
3841 S
.Diag(AL
.getLoc(), diag::err_init_priority_object_attr
);
3845 QualType T
= cast
<VarDecl
>(D
)->getType();
3846 if (S
.Context
.getAsArrayType(T
))
3847 T
= S
.Context
.getBaseElementType(T
);
3848 if (!T
->getAs
<RecordType
>()) {
3849 S
.Diag(AL
.getLoc(), diag::err_init_priority_object_attr
);
3854 Expr
*E
= AL
.getArgAsExpr(0);
3855 uint32_t prioritynum
;
3856 if (!checkUInt32Argument(S
, AL
, E
, prioritynum
)) {
3861 // Only perform the priority check if the attribute is outside of a system
3862 // header. Values <= 100 are reserved for the implementation, and libc++
3863 // benefits from being able to specify values in that range.
3864 if ((prioritynum
< 101 || prioritynum
> 65535) &&
3865 !S
.getSourceManager().isInSystemHeader(AL
.getLoc())) {
3866 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_out_of_range
)
3867 << E
->getSourceRange() << AL
<< 101 << 65535;
3871 D
->addAttr(::new (S
.Context
) InitPriorityAttr(S
.Context
, AL
, prioritynum
));
3874 ErrorAttr
*Sema::mergeErrorAttr(Decl
*D
, const AttributeCommonInfo
&CI
,
3875 StringRef NewUserDiagnostic
) {
3876 if (const auto *EA
= D
->getAttr
<ErrorAttr
>()) {
3877 std::string NewAttr
= CI
.getNormalizedFullName();
3878 assert((NewAttr
== "error" || NewAttr
== "warning") &&
3879 "unexpected normalized full name");
3880 bool Match
= (EA
->isError() && NewAttr
== "error") ||
3881 (EA
->isWarning() && NewAttr
== "warning");
3883 Diag(EA
->getLocation(), diag::err_attributes_are_not_compatible
)
3885 Diag(CI
.getLoc(), diag::note_conflicting_attribute
);
3888 if (EA
->getUserDiagnostic() != NewUserDiagnostic
) {
3889 Diag(CI
.getLoc(), diag::warn_duplicate_attribute
) << EA
;
3890 Diag(EA
->getLoc(), diag::note_previous_attribute
);
3892 D
->dropAttr
<ErrorAttr
>();
3894 return ::new (Context
) ErrorAttr(Context
, CI
, NewUserDiagnostic
);
3897 FormatAttr
*Sema::mergeFormatAttr(Decl
*D
, const AttributeCommonInfo
&CI
,
3898 IdentifierInfo
*Format
, int FormatIdx
,
3900 // Check whether we already have an equivalent format attribute.
3901 for (auto *F
: D
->specific_attrs
<FormatAttr
>()) {
3902 if (F
->getType() == Format
&&
3903 F
->getFormatIdx() == FormatIdx
&&
3904 F
->getFirstArg() == FirstArg
) {
3905 // If we don't have a valid location for this attribute, adopt the
3907 if (F
->getLocation().isInvalid())
3908 F
->setRange(CI
.getRange());
3913 return ::new (Context
) FormatAttr(Context
, CI
, Format
, FormatIdx
, FirstArg
);
3916 /// Handle __attribute__((format(type,idx,firstarg))) attributes based on
3917 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
3918 static void handleFormatAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
3919 if (!AL
.isArgIdent(0)) {
3920 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_n_type
)
3921 << AL
<< 1 << AANT_ArgumentIdentifier
;
3925 // In C++ the implicit 'this' function parameter also counts, and they are
3926 // counted from one.
3927 bool HasImplicitThisParam
= isInstanceMethod(D
);
3928 unsigned NumArgs
= getFunctionOrMethodNumParams(D
) + HasImplicitThisParam
;
3930 IdentifierInfo
*II
= AL
.getArgAsIdent(0)->Ident
;
3931 StringRef Format
= II
->getName();
3933 if (normalizeName(Format
)) {
3934 // If we've modified the string name, we need a new identifier for it.
3935 II
= &S
.Context
.Idents
.get(Format
);
3938 // Check for supported formats.
3939 FormatAttrKind Kind
= getFormatAttrKind(Format
);
3941 if (Kind
== IgnoredFormat
)
3944 if (Kind
== InvalidFormat
) {
3945 S
.Diag(AL
.getLoc(), diag::warn_attribute_type_not_supported
)
3946 << AL
<< II
->getName();
3950 // checks for the 2nd argument
3951 Expr
*IdxExpr
= AL
.getArgAsExpr(1);
3953 if (!checkUInt32Argument(S
, AL
, IdxExpr
, Idx
, 2))
3956 if (Idx
< 1 || Idx
> NumArgs
) {
3957 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_out_of_bounds
)
3958 << AL
<< 2 << IdxExpr
->getSourceRange();
3962 // FIXME: Do we need to bounds check?
3963 unsigned ArgIdx
= Idx
- 1;
3965 if (HasImplicitThisParam
) {
3968 diag::err_format_attribute_implicit_this_format_string
)
3969 << IdxExpr
->getSourceRange();
3975 // make sure the format string is really a string
3976 QualType Ty
= getFunctionOrMethodParamType(D
, ArgIdx
);
3978 if (!isNSStringType(Ty
, S
.Context
, true) &&
3979 !isCFStringType(Ty
, S
.Context
) &&
3980 (!Ty
->isPointerType() ||
3981 !Ty
->castAs
<PointerType
>()->getPointeeType()->isCharType())) {
3982 S
.Diag(AL
.getLoc(), diag::err_format_attribute_not
)
3983 << IdxExpr
->getSourceRange() << getFunctionOrMethodParamRange(D
, ArgIdx
);
3987 // check the 3rd argument
3988 Expr
*FirstArgExpr
= AL
.getArgAsExpr(2);
3990 if (!checkUInt32Argument(S
, AL
, FirstArgExpr
, FirstArg
, 3))
3993 // FirstArg == 0 is is always valid.
3994 if (FirstArg
!= 0) {
3995 if (Kind
== StrftimeFormat
) {
3996 // If the kind is strftime, FirstArg must be 0 because strftime does not
3997 // use any variadic arguments.
3998 S
.Diag(AL
.getLoc(), diag::err_format_strftime_third_parameter
)
3999 << FirstArgExpr
->getSourceRange()
4000 << FixItHint::CreateReplacement(FirstArgExpr
->getSourceRange(), "0");
4002 } else if (isFunctionOrMethodVariadic(D
)) {
4003 // Else, if the function is variadic, then FirstArg must be 0 or the
4004 // "position" of the ... parameter. It's unusual to use 0 with variadic
4005 // functions, so the fixit proposes the latter.
4006 if (FirstArg
!= NumArgs
+ 1) {
4007 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_out_of_bounds
)
4008 << AL
<< 3 << FirstArgExpr
->getSourceRange()
4009 << FixItHint::CreateReplacement(FirstArgExpr
->getSourceRange(),
4010 std::to_string(NumArgs
+ 1));
4014 // Inescapable GCC compatibility diagnostic.
4015 S
.Diag(D
->getLocation(), diag::warn_gcc_requires_variadic_function
) << AL
;
4016 if (FirstArg
<= Idx
) {
4017 // Else, the function is not variadic, and FirstArg must be 0 or any
4018 // parameter after the format parameter. We don't offer a fixit because
4019 // there are too many possible good values.
4020 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_out_of_bounds
)
4021 << AL
<< 3 << FirstArgExpr
->getSourceRange();
4027 FormatAttr
*NewAttr
= S
.mergeFormatAttr(D
, AL
, II
, Idx
, FirstArg
);
4029 D
->addAttr(NewAttr
);
4032 /// Handle __attribute__((callback(CalleeIdx, PayloadIdx0, ...))) attributes.
4033 static void handleCallbackAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
4034 // The index that identifies the callback callee is mandatory.
4035 if (AL
.getNumArgs() == 0) {
4036 S
.Diag(AL
.getLoc(), diag::err_callback_attribute_no_callee
)
4041 bool HasImplicitThisParam
= isInstanceMethod(D
);
4042 int32_t NumArgs
= getFunctionOrMethodNumParams(D
);
4044 FunctionDecl
*FD
= D
->getAsFunction();
4045 assert(FD
&& "Expected a function declaration!");
4047 llvm::StringMap
<int> NameIdxMapping
;
4048 NameIdxMapping
["__"] = -1;
4050 NameIdxMapping
["this"] = 0;
4053 for (const ParmVarDecl
*PVD
: FD
->parameters())
4054 NameIdxMapping
[PVD
->getName()] = Idx
++;
4056 auto UnknownName
= NameIdxMapping
.end();
4058 SmallVector
<int, 8> EncodingIndices
;
4059 for (unsigned I
= 0, E
= AL
.getNumArgs(); I
< E
; ++I
) {
4063 if (AL
.isArgIdent(I
)) {
4064 IdentifierLoc
*IdLoc
= AL
.getArgAsIdent(I
);
4065 auto It
= NameIdxMapping
.find(IdLoc
->Ident
->getName());
4066 if (It
== UnknownName
) {
4067 S
.Diag(AL
.getLoc(), diag::err_callback_attribute_argument_unknown
)
4068 << IdLoc
->Ident
<< IdLoc
->Loc
;
4072 SR
= SourceRange(IdLoc
->Loc
);
4073 ArgIdx
= It
->second
;
4074 } else if (AL
.isArgExpr(I
)) {
4075 Expr
*IdxExpr
= AL
.getArgAsExpr(I
);
4077 // If the expression is not parseable as an int32_t we have a problem.
4078 if (!checkUInt32Argument(S
, AL
, IdxExpr
, (uint32_t &)ArgIdx
, I
+ 1,
4080 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_out_of_bounds
)
4081 << AL
<< (I
+ 1) << IdxExpr
->getSourceRange();
4085 // Check oob, excluding the special values, 0 and -1.
4086 if (ArgIdx
< -1 || ArgIdx
> NumArgs
) {
4087 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_out_of_bounds
)
4088 << AL
<< (I
+ 1) << IdxExpr
->getSourceRange();
4092 SR
= IdxExpr
->getSourceRange();
4094 llvm_unreachable("Unexpected ParsedAttr argument type!");
4097 if (ArgIdx
== 0 && !HasImplicitThisParam
) {
4098 S
.Diag(AL
.getLoc(), diag::err_callback_implicit_this_not_available
)
4103 // Adjust for the case we do not have an implicit "this" parameter. In this
4104 // case we decrease all positive values by 1 to get LLVM argument indices.
4105 if (!HasImplicitThisParam
&& ArgIdx
> 0)
4108 EncodingIndices
.push_back(ArgIdx
);
4111 int CalleeIdx
= EncodingIndices
.front();
4112 // Check if the callee index is proper, thus not "this" and not "unknown".
4113 // This means the "CalleeIdx" has to be non-negative if "HasImplicitThisParam"
4114 // is false and positive if "HasImplicitThisParam" is true.
4115 if (CalleeIdx
< (int)HasImplicitThisParam
) {
4116 S
.Diag(AL
.getLoc(), diag::err_callback_attribute_invalid_callee
)
4121 // Get the callee type, note the index adjustment as the AST doesn't contain
4122 // the this type (which the callee cannot reference anyway!).
4123 const Type
*CalleeType
=
4124 getFunctionOrMethodParamType(D
, CalleeIdx
- HasImplicitThisParam
)
4126 if (!CalleeType
|| !CalleeType
->isFunctionPointerType()) {
4127 S
.Diag(AL
.getLoc(), diag::err_callback_callee_no_function_type
)
4132 const Type
*CalleeFnType
=
4133 CalleeType
->getPointeeType()->getUnqualifiedDesugaredType();
4135 // TODO: Check the type of the callee arguments.
4137 const auto *CalleeFnProtoType
= dyn_cast
<FunctionProtoType
>(CalleeFnType
);
4138 if (!CalleeFnProtoType
) {
4139 S
.Diag(AL
.getLoc(), diag::err_callback_callee_no_function_type
)
4144 if (CalleeFnProtoType
->getNumParams() > EncodingIndices
.size() - 1) {
4145 S
.Diag(AL
.getLoc(), diag::err_attribute_wrong_number_arguments
)
4146 << AL
<< (unsigned)(EncodingIndices
.size() - 1);
4150 if (CalleeFnProtoType
->getNumParams() < EncodingIndices
.size() - 1) {
4151 S
.Diag(AL
.getLoc(), diag::err_attribute_wrong_number_arguments
)
4152 << AL
<< (unsigned)(EncodingIndices
.size() - 1);
4156 if (CalleeFnProtoType
->isVariadic()) {
4157 S
.Diag(AL
.getLoc(), diag::err_callback_callee_is_variadic
) << AL
.getRange();
4161 // Do not allow multiple callback attributes.
4162 if (D
->hasAttr
<CallbackAttr
>()) {
4163 S
.Diag(AL
.getLoc(), diag::err_callback_attribute_multiple
) << AL
.getRange();
4167 D
->addAttr(::new (S
.Context
) CallbackAttr(
4168 S
.Context
, AL
, EncodingIndices
.data(), EncodingIndices
.size()));
4171 static bool isFunctionLike(const Type
&T
) {
4172 // Check for explicit function types.
4173 // 'called_once' is only supported in Objective-C and it has
4174 // function pointers and block pointers.
4175 return T
.isFunctionPointerType() || T
.isBlockPointerType();
4178 /// Handle 'called_once' attribute.
4179 static void handleCalledOnceAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
4180 // 'called_once' only applies to parameters representing functions.
4181 QualType T
= cast
<ParmVarDecl
>(D
)->getType();
4183 if (!isFunctionLike(*T
)) {
4184 S
.Diag(AL
.getLoc(), diag::err_called_once_attribute_wrong_type
);
4188 D
->addAttr(::new (S
.Context
) CalledOnceAttr(S
.Context
, AL
));
4191 static void handleTransparentUnionAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
4192 // Try to find the underlying union declaration.
4193 RecordDecl
*RD
= nullptr;
4194 const auto *TD
= dyn_cast
<TypedefNameDecl
>(D
);
4195 if (TD
&& TD
->getUnderlyingType()->isUnionType())
4196 RD
= TD
->getUnderlyingType()->getAsUnionType()->getDecl();
4198 RD
= dyn_cast
<RecordDecl
>(D
);
4200 if (!RD
|| !RD
->isUnion()) {
4201 S
.Diag(AL
.getLoc(), diag::warn_attribute_wrong_decl_type
) << AL
4206 if (!RD
->isCompleteDefinition()) {
4207 if (!RD
->isBeingDefined())
4209 diag::warn_transparent_union_attribute_not_definition
);
4213 RecordDecl::field_iterator Field
= RD
->field_begin(),
4214 FieldEnd
= RD
->field_end();
4215 if (Field
== FieldEnd
) {
4216 S
.Diag(AL
.getLoc(), diag::warn_transparent_union_attribute_zero_fields
);
4220 FieldDecl
*FirstField
= *Field
;
4221 QualType FirstType
= FirstField
->getType();
4222 if (FirstType
->hasFloatingRepresentation() || FirstType
->isVectorType()) {
4223 S
.Diag(FirstField
->getLocation(),
4224 diag::warn_transparent_union_attribute_floating
)
4225 << FirstType
->isVectorType() << FirstType
;
4229 if (FirstType
->isIncompleteType())
4231 uint64_t FirstSize
= S
.Context
.getTypeSize(FirstType
);
4232 uint64_t FirstAlign
= S
.Context
.getTypeAlign(FirstType
);
4233 for (; Field
!= FieldEnd
; ++Field
) {
4234 QualType FieldType
= Field
->getType();
4235 if (FieldType
->isIncompleteType())
4237 // FIXME: this isn't fully correct; we also need to test whether the
4238 // members of the union would all have the same calling convention as the
4239 // first member of the union. Checking just the size and alignment isn't
4240 // sufficient (consider structs passed on the stack instead of in registers
4242 if (S
.Context
.getTypeSize(FieldType
) != FirstSize
||
4243 S
.Context
.getTypeAlign(FieldType
) > FirstAlign
) {
4244 // Warn if we drop the attribute.
4245 bool isSize
= S
.Context
.getTypeSize(FieldType
) != FirstSize
;
4246 unsigned FieldBits
= isSize
? S
.Context
.getTypeSize(FieldType
)
4247 : S
.Context
.getTypeAlign(FieldType
);
4248 S
.Diag(Field
->getLocation(),
4249 diag::warn_transparent_union_attribute_field_size_align
)
4250 << isSize
<< *Field
<< FieldBits
;
4251 unsigned FirstBits
= isSize
? FirstSize
: FirstAlign
;
4252 S
.Diag(FirstField
->getLocation(),
4253 diag::note_transparent_union_first_field_size_align
)
4254 << isSize
<< FirstBits
;
4259 RD
->addAttr(::new (S
.Context
) TransparentUnionAttr(S
.Context
, AL
));
4262 void Sema::AddAnnotationAttr(Decl
*D
, const AttributeCommonInfo
&CI
,
4263 StringRef Str
, MutableArrayRef
<Expr
*> Args
) {
4264 auto *Attr
= AnnotateAttr::Create(Context
, Str
, Args
.data(), Args
.size(), CI
);
4265 if (ConstantFoldAttrArgs(
4266 CI
, MutableArrayRef
<Expr
*>(Attr
->args_begin(), Attr
->args_end()))) {
4271 static void handleAnnotateAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
4272 // Make sure that there is a string literal as the annotation's first
4275 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Str
))
4278 llvm::SmallVector
<Expr
*, 4> Args
;
4279 Args
.reserve(AL
.getNumArgs() - 1);
4280 for (unsigned Idx
= 1; Idx
< AL
.getNumArgs(); Idx
++) {
4281 assert(!AL
.isArgIdent(Idx
));
4282 Args
.push_back(AL
.getArgAsExpr(Idx
));
4285 S
.AddAnnotationAttr(D
, AL
, Str
, Args
);
4288 static void handleAlignValueAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
4289 S
.AddAlignValueAttr(D
, AL
, AL
.getArgAsExpr(0));
4292 void Sema::AddAlignValueAttr(Decl
*D
, const AttributeCommonInfo
&CI
, Expr
*E
) {
4293 AlignValueAttr
TmpAttr(Context
, CI
, E
);
4294 SourceLocation AttrLoc
= CI
.getLoc();
4297 if (const auto *TD
= dyn_cast
<TypedefNameDecl
>(D
))
4298 T
= TD
->getUnderlyingType();
4299 else if (const auto *VD
= dyn_cast
<ValueDecl
>(D
))
4302 llvm_unreachable("Unknown decl type for align_value");
4304 if (!T
->isDependentType() && !T
->isAnyPointerType() &&
4305 !T
->isReferenceType() && !T
->isMemberPointerType()) {
4306 Diag(AttrLoc
, diag::warn_attribute_pointer_or_reference_only
)
4307 << &TmpAttr
<< T
<< D
->getSourceRange();
4311 if (!E
->isValueDependent()) {
4312 llvm::APSInt Alignment
;
4313 ExprResult ICE
= VerifyIntegerConstantExpression(
4314 E
, &Alignment
, diag::err_align_value_attribute_argument_not_int
);
4315 if (ICE
.isInvalid())
4318 if (!Alignment
.isPowerOf2()) {
4319 Diag(AttrLoc
, diag::err_alignment_not_power_of_two
)
4320 << E
->getSourceRange();
4324 D
->addAttr(::new (Context
) AlignValueAttr(Context
, CI
, ICE
.get()));
4328 // Save dependent expressions in the AST to be instantiated.
4329 D
->addAttr(::new (Context
) AlignValueAttr(Context
, CI
, E
));
4332 static void handleAlignedAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
4333 // check the attribute arguments.
4334 if (AL
.getNumArgs() > 1) {
4335 S
.Diag(AL
.getLoc(), diag::err_attribute_wrong_number_arguments
) << AL
<< 1;
4339 if (AL
.getNumArgs() == 0) {
4340 D
->addAttr(::new (S
.Context
) AlignedAttr(S
.Context
, AL
, true, nullptr));
4344 Expr
*E
= AL
.getArgAsExpr(0);
4345 if (AL
.isPackExpansion() && !E
->containsUnexpandedParameterPack()) {
4346 S
.Diag(AL
.getEllipsisLoc(),
4347 diag::err_pack_expansion_without_parameter_packs
);
4351 if (!AL
.isPackExpansion() && S
.DiagnoseUnexpandedParameterPack(E
))
4354 S
.AddAlignedAttr(D
, AL
, E
, AL
.isPackExpansion());
4357 void Sema::AddAlignedAttr(Decl
*D
, const AttributeCommonInfo
&CI
, Expr
*E
,
4358 bool IsPackExpansion
) {
4359 AlignedAttr
TmpAttr(Context
, CI
, true, E
);
4360 SourceLocation AttrLoc
= CI
.getLoc();
4362 // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
4363 if (TmpAttr
.isAlignas()) {
4364 // C++11 [dcl.align]p1:
4365 // An alignment-specifier may be applied to a variable or to a class
4366 // data member, but it shall not be applied to a bit-field, a function
4367 // parameter, the formal parameter of a catch clause, or a variable
4368 // declared with the register storage class specifier. An
4369 // alignment-specifier may also be applied to the declaration of a class
4370 // or enumeration type.
4372 // CWG agreed to remove permission for alignas to be applied to
4375 // An alignment attribute shall not be specified in a declaration of
4376 // a typedef, or a bit-field, or a function, or a parameter, or an
4377 // object declared with the register storage-class specifier.
4379 if (isa
<ParmVarDecl
>(D
)) {
4381 } else if (const auto *VD
= dyn_cast
<VarDecl
>(D
)) {
4382 if (VD
->getStorageClass() == SC_Register
)
4384 if (VD
->isExceptionVariable())
4386 } else if (const auto *FD
= dyn_cast
<FieldDecl
>(D
)) {
4387 if (FD
->isBitField())
4389 } else if (const auto *ED
= dyn_cast
<EnumDecl
>(D
)) {
4390 if (ED
->getLangOpts().CPlusPlus
)
4392 } else if (!isa
<TagDecl
>(D
)) {
4393 Diag(AttrLoc
, diag::err_attribute_wrong_decl_type
) << &TmpAttr
4394 << (TmpAttr
.isC11() ? ExpectedVariableOrField
4395 : ExpectedVariableFieldOrTag
);
4398 if (DiagKind
!= -1) {
4399 Diag(AttrLoc
, diag::err_alignas_attribute_wrong_decl_type
)
4400 << &TmpAttr
<< DiagKind
;
4405 if (E
->isValueDependent()) {
4406 // We can't support a dependent alignment on a non-dependent type,
4407 // because we have no way to model that a type is "alignment-dependent"
4408 // but not dependent in any other way.
4409 if (const auto *TND
= dyn_cast
<TypedefNameDecl
>(D
)) {
4410 if (!TND
->getUnderlyingType()->isDependentType()) {
4411 Diag(AttrLoc
, diag::err_alignment_dependent_typedef_name
)
4412 << E
->getSourceRange();
4417 // Save dependent expressions in the AST to be instantiated.
4418 AlignedAttr
*AA
= ::new (Context
) AlignedAttr(Context
, CI
, true, E
);
4419 AA
->setPackExpansion(IsPackExpansion
);
4424 // FIXME: Cache the number on the AL object?
4425 llvm::APSInt Alignment
;
4426 ExprResult ICE
= VerifyIntegerConstantExpression(
4427 E
, &Alignment
, diag::err_aligned_attribute_argument_not_int
);
4428 if (ICE
.isInvalid())
4431 uint64_t AlignVal
= Alignment
.getZExtValue();
4432 // C++11 [dcl.align]p2:
4433 // -- if the constant expression evaluates to zero, the alignment
4434 // specifier shall have no effect
4436 // An alignment specification of zero has no effect.
4437 if (!(TmpAttr
.isAlignas() && !Alignment
)) {
4438 if (!llvm::isPowerOf2_64(AlignVal
)) {
4439 Diag(AttrLoc
, diag::err_alignment_not_power_of_two
)
4440 << E
->getSourceRange();
4445 uint64_t MaximumAlignment
= Sema::MaximumAlignment
;
4446 if (Context
.getTargetInfo().getTriple().isOSBinFormatCOFF())
4447 MaximumAlignment
= std::min(MaximumAlignment
, uint64_t(8192));
4448 if (AlignVal
> MaximumAlignment
) {
4449 Diag(AttrLoc
, diag::err_attribute_aligned_too_great
)
4450 << MaximumAlignment
<< E
->getSourceRange();
4454 const auto *VD
= dyn_cast
<VarDecl
>(D
);
4456 unsigned MaxTLSAlign
=
4457 Context
.toCharUnitsFromBits(Context
.getTargetInfo().getMaxTLSAlign())
4459 if (MaxTLSAlign
&& AlignVal
> MaxTLSAlign
&&
4460 VD
->getTLSKind() != VarDecl::TLS_None
) {
4461 Diag(VD
->getLocation(), diag::err_tls_var_aligned_over_maximum
)
4462 << (unsigned)AlignVal
<< VD
<< MaxTLSAlign
;
4467 // On AIX, an aligned attribute can not decrease the alignment when applied
4468 // to a variable declaration with vector type.
4469 if (VD
&& Context
.getTargetInfo().getTriple().isOSAIX()) {
4470 const Type
*Ty
= VD
->getType().getTypePtr();
4471 if (Ty
->isVectorType() && AlignVal
< 16) {
4472 Diag(VD
->getLocation(), diag::warn_aligned_attr_underaligned
)
4473 << VD
->getType() << 16;
4478 AlignedAttr
*AA
= ::new (Context
) AlignedAttr(Context
, CI
, true, ICE
.get());
4479 AA
->setPackExpansion(IsPackExpansion
);
4483 void Sema::AddAlignedAttr(Decl
*D
, const AttributeCommonInfo
&CI
,
4484 TypeSourceInfo
*TS
, bool IsPackExpansion
) {
4485 // FIXME: Cache the number on the AL object if non-dependent?
4486 // FIXME: Perform checking of type validity
4487 AlignedAttr
*AA
= ::new (Context
) AlignedAttr(Context
, CI
, false, TS
);
4488 AA
->setPackExpansion(IsPackExpansion
);
4492 void Sema::CheckAlignasUnderalignment(Decl
*D
) {
4493 assert(D
->hasAttrs() && "no attributes on decl");
4495 QualType UnderlyingTy
, DiagTy
;
4496 if (const auto *VD
= dyn_cast
<ValueDecl
>(D
)) {
4497 UnderlyingTy
= DiagTy
= VD
->getType();
4499 UnderlyingTy
= DiagTy
= Context
.getTagDeclType(cast
<TagDecl
>(D
));
4500 if (const auto *ED
= dyn_cast
<EnumDecl
>(D
))
4501 UnderlyingTy
= ED
->getIntegerType();
4503 if (DiagTy
->isDependentType() || DiagTy
->isIncompleteType())
4506 // C++11 [dcl.align]p5, C11 6.7.5/4:
4507 // The combined effect of all alignment attributes in a declaration shall
4508 // not specify an alignment that is less strict than the alignment that
4509 // would otherwise be required for the entity being declared.
4510 AlignedAttr
*AlignasAttr
= nullptr;
4511 AlignedAttr
*LastAlignedAttr
= nullptr;
4513 for (auto *I
: D
->specific_attrs
<AlignedAttr
>()) {
4514 if (I
->isAlignmentDependent())
4518 Align
= std::max(Align
, I
->getAlignment(Context
));
4519 LastAlignedAttr
= I
;
4522 if (Align
&& DiagTy
->isSizelessType()) {
4523 Diag(LastAlignedAttr
->getLocation(), diag::err_attribute_sizeless_type
)
4524 << LastAlignedAttr
<< DiagTy
;
4525 } else if (AlignasAttr
&& Align
) {
4526 CharUnits RequestedAlign
= Context
.toCharUnitsFromBits(Align
);
4527 CharUnits NaturalAlign
= Context
.getTypeAlignInChars(UnderlyingTy
);
4528 if (NaturalAlign
> RequestedAlign
)
4529 Diag(AlignasAttr
->getLocation(), diag::err_alignas_underaligned
)
4530 << DiagTy
<< (unsigned)NaturalAlign
.getQuantity();
4534 bool Sema::checkMSInheritanceAttrOnDefinition(
4535 CXXRecordDecl
*RD
, SourceRange Range
, bool BestCase
,
4536 MSInheritanceModel ExplicitModel
) {
4537 assert(RD
->hasDefinition() && "RD has no definition!");
4539 // We may not have seen base specifiers or any virtual methods yet. We will
4540 // have to wait until the record is defined to catch any mismatches.
4541 if (!RD
->getDefinition()->isCompleteDefinition())
4544 // The unspecified model never matches what a definition could need.
4545 if (ExplicitModel
== MSInheritanceModel::Unspecified
)
4549 if (RD
->calculateInheritanceModel() == ExplicitModel
)
4552 if (RD
->calculateInheritanceModel() <= ExplicitModel
)
4556 Diag(Range
.getBegin(), diag::err_mismatched_ms_inheritance
)
4557 << 0 /*definition*/;
4558 Diag(RD
->getDefinition()->getLocation(), diag::note_defined_here
) << RD
;
4562 /// parseModeAttrArg - Parses attribute mode string and returns parsed type
4564 static void parseModeAttrArg(Sema
&S
, StringRef Str
, unsigned &DestWidth
,
4565 bool &IntegerMode
, bool &ComplexMode
,
4566 FloatModeKind
&ExplicitType
) {
4568 ComplexMode
= false;
4569 ExplicitType
= FloatModeKind::NoFloat
;
4570 switch (Str
.size()) {
4588 case 'K': // KFmode - IEEE quad precision (__float128)
4589 ExplicitType
= FloatModeKind::Float128
;
4590 DestWidth
= Str
[1] == 'I' ? 0 : 128;
4593 ExplicitType
= FloatModeKind::LongDouble
;
4597 ExplicitType
= FloatModeKind::Ibm128
;
4598 DestWidth
= Str
[1] == 'I' ? 0 : 128;
4601 if (Str
[1] == 'F') {
4602 IntegerMode
= false;
4603 } else if (Str
[1] == 'C') {
4604 IntegerMode
= false;
4606 } else if (Str
[1] != 'I') {
4611 // FIXME: glibc uses 'word' to define register_t; this is narrower than a
4612 // pointer on PIC16 and other embedded platforms.
4614 DestWidth
= S
.Context
.getTargetInfo().getRegisterWidth();
4615 else if (Str
== "byte")
4616 DestWidth
= S
.Context
.getTargetInfo().getCharWidth();
4619 if (Str
== "pointer")
4620 DestWidth
= S
.Context
.getTargetInfo().getPointerWidth(LangAS::Default
);
4623 if (Str
== "unwind_word")
4624 DestWidth
= S
.Context
.getTargetInfo().getUnwindWordWidth();
4629 /// handleModeAttr - This attribute modifies the width of a decl with primitive
4632 /// Despite what would be logical, the mode attribute is a decl attribute, not a
4633 /// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
4634 /// HImode, not an intermediate pointer.
4635 static void handleModeAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
4636 // This attribute isn't documented, but glibc uses it. It changes
4637 // the width of an int or unsigned int to the specified size.
4638 if (!AL
.isArgIdent(0)) {
4639 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_type
)
4640 << AL
<< AANT_ArgumentIdentifier
;
4644 IdentifierInfo
*Name
= AL
.getArgAsIdent(0)->Ident
;
4646 S
.AddModeAttr(D
, AL
, Name
);
4649 void Sema::AddModeAttr(Decl
*D
, const AttributeCommonInfo
&CI
,
4650 IdentifierInfo
*Name
, bool InInstantiation
) {
4651 StringRef Str
= Name
->getName();
4653 SourceLocation AttrLoc
= CI
.getLoc();
4655 unsigned DestWidth
= 0;
4656 bool IntegerMode
= true;
4657 bool ComplexMode
= false;
4658 FloatModeKind ExplicitType
= FloatModeKind::NoFloat
;
4659 llvm::APInt
VectorSize(64, 0);
4660 if (Str
.size() >= 4 && Str
[0] == 'V') {
4661 // Minimal length of vector mode is 4: 'V' + NUMBER(>=1) + TYPE(>=2).
4662 size_t StrSize
= Str
.size();
4663 size_t VectorStringLength
= 0;
4664 while ((VectorStringLength
+ 1) < StrSize
&&
4665 isdigit(Str
[VectorStringLength
+ 1]))
4666 ++VectorStringLength
;
4667 if (VectorStringLength
&&
4668 !Str
.substr(1, VectorStringLength
).getAsInteger(10, VectorSize
) &&
4669 VectorSize
.isPowerOf2()) {
4670 parseModeAttrArg(*this, Str
.substr(VectorStringLength
+ 1), DestWidth
,
4671 IntegerMode
, ComplexMode
, ExplicitType
);
4672 // Avoid duplicate warning from template instantiation.
4673 if (!InInstantiation
)
4674 Diag(AttrLoc
, diag::warn_vector_mode_deprecated
);
4681 parseModeAttrArg(*this, Str
, DestWidth
, IntegerMode
, ComplexMode
,
4684 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
4685 // and friends, at least with glibc.
4686 // FIXME: Make sure floating-point mappings are accurate
4687 // FIXME: Support XF and TF types
4689 Diag(AttrLoc
, diag::err_machine_mode
) << 0 /*Unknown*/ << Name
;
4694 if (const auto *TD
= dyn_cast
<TypedefNameDecl
>(D
))
4695 OldTy
= TD
->getUnderlyingType();
4696 else if (const auto *ED
= dyn_cast
<EnumDecl
>(D
)) {
4697 // Something like 'typedef enum { X } __attribute__((mode(XX))) T;'.
4698 // Try to get type from enum declaration, default to int.
4699 OldTy
= ED
->getIntegerType();
4701 OldTy
= Context
.IntTy
;
4703 OldTy
= cast
<ValueDecl
>(D
)->getType();
4705 if (OldTy
->isDependentType()) {
4706 D
->addAttr(::new (Context
) ModeAttr(Context
, CI
, Name
));
4710 // Base type can also be a vector type (see PR17453).
4711 // Distinguish between base type and base element type.
4712 QualType OldElemTy
= OldTy
;
4713 if (const auto *VT
= OldTy
->getAs
<VectorType
>())
4714 OldElemTy
= VT
->getElementType();
4716 // GCC allows 'mode' attribute on enumeration types (even incomplete), except
4717 // for vector modes. So, 'enum X __attribute__((mode(QI)));' forms a complete
4718 // type, 'enum { A } __attribute__((mode(V4SI)))' is rejected.
4719 if ((isa
<EnumDecl
>(D
) || OldElemTy
->getAs
<EnumType
>()) &&
4720 VectorSize
.getBoolValue()) {
4721 Diag(AttrLoc
, diag::err_enum_mode_vector_type
) << Name
<< CI
.getRange();
4724 bool IntegralOrAnyEnumType
= (OldElemTy
->isIntegralOrEnumerationType() &&
4725 !OldElemTy
->isBitIntType()) ||
4726 OldElemTy
->getAs
<EnumType
>();
4728 if (!OldElemTy
->getAs
<BuiltinType
>() && !OldElemTy
->isComplexType() &&
4729 !IntegralOrAnyEnumType
)
4730 Diag(AttrLoc
, diag::err_mode_not_primitive
);
4731 else if (IntegerMode
) {
4732 if (!IntegralOrAnyEnumType
)
4733 Diag(AttrLoc
, diag::err_mode_wrong_type
);
4734 } else if (ComplexMode
) {
4735 if (!OldElemTy
->isComplexType())
4736 Diag(AttrLoc
, diag::err_mode_wrong_type
);
4738 if (!OldElemTy
->isFloatingType())
4739 Diag(AttrLoc
, diag::err_mode_wrong_type
);
4745 NewElemTy
= Context
.getIntTypeForBitwidth(DestWidth
,
4746 OldElemTy
->isSignedIntegerType());
4748 NewElemTy
= Context
.getRealTypeForBitwidth(DestWidth
, ExplicitType
);
4750 if (NewElemTy
.isNull()) {
4751 Diag(AttrLoc
, diag::err_machine_mode
) << 1 /*Unsupported*/ << Name
;
4756 NewElemTy
= Context
.getComplexType(NewElemTy
);
4759 QualType NewTy
= NewElemTy
;
4760 if (VectorSize
.getBoolValue()) {
4761 NewTy
= Context
.getVectorType(NewTy
, VectorSize
.getZExtValue(),
4762 VectorType::GenericVector
);
4763 } else if (const auto *OldVT
= OldTy
->getAs
<VectorType
>()) {
4764 // Complex machine mode does not support base vector types.
4766 Diag(AttrLoc
, diag::err_complex_mode_vector_type
);
4769 unsigned NumElements
= Context
.getTypeSize(OldElemTy
) *
4770 OldVT
->getNumElements() /
4771 Context
.getTypeSize(NewElemTy
);
4773 Context
.getVectorType(NewElemTy
, NumElements
, OldVT
->getVectorKind());
4776 if (NewTy
.isNull()) {
4777 Diag(AttrLoc
, diag::err_mode_wrong_type
);
4781 // Install the new type.
4782 if (auto *TD
= dyn_cast
<TypedefNameDecl
>(D
))
4783 TD
->setModedTypeSourceInfo(TD
->getTypeSourceInfo(), NewTy
);
4784 else if (auto *ED
= dyn_cast
<EnumDecl
>(D
))
4785 ED
->setIntegerType(NewTy
);
4787 cast
<ValueDecl
>(D
)->setType(NewTy
);
4789 D
->addAttr(::new (Context
) ModeAttr(Context
, CI
, Name
));
4792 static void handleNoDebugAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
4793 D
->addAttr(::new (S
.Context
) NoDebugAttr(S
.Context
, AL
));
4796 AlwaysInlineAttr
*Sema::mergeAlwaysInlineAttr(Decl
*D
,
4797 const AttributeCommonInfo
&CI
,
4798 const IdentifierInfo
*Ident
) {
4799 if (OptimizeNoneAttr
*Optnone
= D
->getAttr
<OptimizeNoneAttr
>()) {
4800 Diag(CI
.getLoc(), diag::warn_attribute_ignored
) << Ident
;
4801 Diag(Optnone
->getLocation(), diag::note_conflicting_attribute
);
4805 if (D
->hasAttr
<AlwaysInlineAttr
>())
4808 return ::new (Context
) AlwaysInlineAttr(Context
, CI
);
4811 InternalLinkageAttr
*Sema::mergeInternalLinkageAttr(Decl
*D
,
4812 const ParsedAttr
&AL
) {
4813 if (const auto *VD
= dyn_cast
<VarDecl
>(D
)) {
4814 // Attribute applies to Var but not any subclass of it (like ParmVar,
4815 // ImplicitParm or VarTemplateSpecialization).
4816 if (VD
->getKind() != Decl::Var
) {
4817 Diag(AL
.getLoc(), diag::warn_attribute_wrong_decl_type
)
4818 << AL
<< (getLangOpts().CPlusPlus
? ExpectedFunctionVariableOrClass
4819 : ExpectedVariableOrFunction
);
4822 // Attribute does not apply to non-static local variables.
4823 if (VD
->hasLocalStorage()) {
4824 Diag(VD
->getLocation(), diag::warn_internal_linkage_local_storage
);
4829 return ::new (Context
) InternalLinkageAttr(Context
, AL
);
4831 InternalLinkageAttr
*
4832 Sema::mergeInternalLinkageAttr(Decl
*D
, const InternalLinkageAttr
&AL
) {
4833 if (const auto *VD
= dyn_cast
<VarDecl
>(D
)) {
4834 // Attribute applies to Var but not any subclass of it (like ParmVar,
4835 // ImplicitParm or VarTemplateSpecialization).
4836 if (VD
->getKind() != Decl::Var
) {
4837 Diag(AL
.getLocation(), diag::warn_attribute_wrong_decl_type
)
4838 << &AL
<< (getLangOpts().CPlusPlus
? ExpectedFunctionVariableOrClass
4839 : ExpectedVariableOrFunction
);
4842 // Attribute does not apply to non-static local variables.
4843 if (VD
->hasLocalStorage()) {
4844 Diag(VD
->getLocation(), diag::warn_internal_linkage_local_storage
);
4849 return ::new (Context
) InternalLinkageAttr(Context
, AL
);
4852 MinSizeAttr
*Sema::mergeMinSizeAttr(Decl
*D
, const AttributeCommonInfo
&CI
) {
4853 if (OptimizeNoneAttr
*Optnone
= D
->getAttr
<OptimizeNoneAttr
>()) {
4854 Diag(CI
.getLoc(), diag::warn_attribute_ignored
) << "'minsize'";
4855 Diag(Optnone
->getLocation(), diag::note_conflicting_attribute
);
4859 if (D
->hasAttr
<MinSizeAttr
>())
4862 return ::new (Context
) MinSizeAttr(Context
, CI
);
4865 SwiftNameAttr
*Sema::mergeSwiftNameAttr(Decl
*D
, const SwiftNameAttr
&SNA
,
4867 if (const auto *PrevSNA
= D
->getAttr
<SwiftNameAttr
>()) {
4868 if (PrevSNA
->getName() != Name
&& !PrevSNA
->isImplicit()) {
4869 Diag(PrevSNA
->getLocation(), diag::err_attributes_are_not_compatible
)
4871 Diag(SNA
.getLoc(), diag::note_conflicting_attribute
);
4874 D
->dropAttr
<SwiftNameAttr
>();
4876 return ::new (Context
) SwiftNameAttr(Context
, SNA
, Name
);
4879 OptimizeNoneAttr
*Sema::mergeOptimizeNoneAttr(Decl
*D
,
4880 const AttributeCommonInfo
&CI
) {
4881 if (AlwaysInlineAttr
*Inline
= D
->getAttr
<AlwaysInlineAttr
>()) {
4882 Diag(Inline
->getLocation(), diag::warn_attribute_ignored
) << Inline
;
4883 Diag(CI
.getLoc(), diag::note_conflicting_attribute
);
4884 D
->dropAttr
<AlwaysInlineAttr
>();
4886 if (MinSizeAttr
*MinSize
= D
->getAttr
<MinSizeAttr
>()) {
4887 Diag(MinSize
->getLocation(), diag::warn_attribute_ignored
) << MinSize
;
4888 Diag(CI
.getLoc(), diag::note_conflicting_attribute
);
4889 D
->dropAttr
<MinSizeAttr
>();
4892 if (D
->hasAttr
<OptimizeNoneAttr
>())
4895 return ::new (Context
) OptimizeNoneAttr(Context
, CI
);
4898 static void handleAlwaysInlineAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
4899 if (AlwaysInlineAttr
*Inline
=
4900 S
.mergeAlwaysInlineAttr(D
, AL
, AL
.getAttrName()))
4904 static void handleMinSizeAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
4905 if (MinSizeAttr
*MinSize
= S
.mergeMinSizeAttr(D
, AL
))
4906 D
->addAttr(MinSize
);
4909 static void handleOptimizeNoneAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
4910 if (OptimizeNoneAttr
*Optnone
= S
.mergeOptimizeNoneAttr(D
, AL
))
4911 D
->addAttr(Optnone
);
4914 static void handleConstantAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
4915 const auto *VD
= cast
<VarDecl
>(D
);
4916 if (VD
->hasLocalStorage()) {
4917 S
.Diag(AL
.getLoc(), diag::err_cuda_nonstatic_constdev
);
4920 // constexpr variable may already get an implicit constant attr, which should
4921 // be replaced by the explicit constant attr.
4922 if (auto *A
= D
->getAttr
<CUDAConstantAttr
>()) {
4923 if (!A
->isImplicit())
4925 D
->dropAttr
<CUDAConstantAttr
>();
4927 D
->addAttr(::new (S
.Context
) CUDAConstantAttr(S
.Context
, AL
));
4930 static void handleSharedAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
4931 const auto *VD
= cast
<VarDecl
>(D
);
4932 // extern __shared__ is only allowed on arrays with no length (e.g.
4934 if (!S
.getLangOpts().GPURelocatableDeviceCode
&& VD
->hasExternalStorage() &&
4935 !isa
<IncompleteArrayType
>(VD
->getType())) {
4936 S
.Diag(AL
.getLoc(), diag::err_cuda_extern_shared
) << VD
;
4939 if (S
.getLangOpts().CUDA
&& VD
->hasLocalStorage() &&
4940 S
.CUDADiagIfHostCode(AL
.getLoc(), diag::err_cuda_host_shared
)
4941 << S
.CurrentCUDATarget())
4943 D
->addAttr(::new (S
.Context
) CUDASharedAttr(S
.Context
, AL
));
4946 static void handleGlobalAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
4947 const auto *FD
= cast
<FunctionDecl
>(D
);
4948 if (!FD
->getReturnType()->isVoidType() &&
4949 !FD
->getReturnType()->getAs
<AutoType
>() &&
4950 !FD
->getReturnType()->isInstantiationDependentType()) {
4951 SourceRange RTRange
= FD
->getReturnTypeSourceRange();
4952 S
.Diag(FD
->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return
)
4954 << (RTRange
.isValid() ? FixItHint::CreateReplacement(RTRange
, "void")
4958 if (const auto *Method
= dyn_cast
<CXXMethodDecl
>(FD
)) {
4959 if (Method
->isInstance()) {
4960 S
.Diag(Method
->getBeginLoc(), diag::err_kern_is_nonstatic_method
)
4964 S
.Diag(Method
->getBeginLoc(), diag::warn_kern_is_method
) << Method
;
4966 // Only warn for "inline" when compiling for host, to cut down on noise.
4967 if (FD
->isInlineSpecified() && !S
.getLangOpts().CUDAIsDevice
)
4968 S
.Diag(FD
->getBeginLoc(), diag::warn_kern_is_inline
) << FD
;
4970 D
->addAttr(::new (S
.Context
) CUDAGlobalAttr(S
.Context
, AL
));
4971 // In host compilation the kernel is emitted as a stub function, which is
4972 // a helper function for launching the kernel. The instructions in the helper
4973 // function has nothing to do with the source code of the kernel. Do not emit
4974 // debug info for the stub function to avoid confusing the debugger.
4975 if (S
.LangOpts
.HIP
&& !S
.LangOpts
.CUDAIsDevice
)
4976 D
->addAttr(NoDebugAttr::CreateImplicit(S
.Context
));
4979 static void handleDeviceAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
4980 if (const auto *VD
= dyn_cast
<VarDecl
>(D
)) {
4981 if (VD
->hasLocalStorage()) {
4982 S
.Diag(AL
.getLoc(), diag::err_cuda_nonstatic_constdev
);
4987 if (auto *A
= D
->getAttr
<CUDADeviceAttr
>()) {
4988 if (!A
->isImplicit())
4990 D
->dropAttr
<CUDADeviceAttr
>();
4992 D
->addAttr(::new (S
.Context
) CUDADeviceAttr(S
.Context
, AL
));
4995 static void handleManagedAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
4996 if (const auto *VD
= dyn_cast
<VarDecl
>(D
)) {
4997 if (VD
->hasLocalStorage()) {
4998 S
.Diag(AL
.getLoc(), diag::err_cuda_nonstatic_constdev
);
5002 if (!D
->hasAttr
<HIPManagedAttr
>())
5003 D
->addAttr(::new (S
.Context
) HIPManagedAttr(S
.Context
, AL
));
5004 if (!D
->hasAttr
<CUDADeviceAttr
>())
5005 D
->addAttr(CUDADeviceAttr::CreateImplicit(S
.Context
));
5008 static void handleGNUInlineAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
5009 const auto *Fn
= cast
<FunctionDecl
>(D
);
5010 if (!Fn
->isInlineSpecified()) {
5011 S
.Diag(AL
.getLoc(), diag::warn_gnu_inline_attribute_requires_inline
);
5015 if (S
.LangOpts
.CPlusPlus
&& Fn
->getStorageClass() != SC_Extern
)
5016 S
.Diag(AL
.getLoc(), diag::warn_gnu_inline_cplusplus_without_extern
);
5018 D
->addAttr(::new (S
.Context
) GNUInlineAttr(S
.Context
, AL
));
5021 static void handleCallConvAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
5022 if (hasDeclarator(D
)) return;
5024 // Diagnostic is emitted elsewhere: here we store the (valid) AL
5025 // in the Decl node for syntactic reasoning, e.g., pretty-printing.
5027 if (S
.CheckCallingConvAttr(AL
, CC
, /*FD*/nullptr))
5030 if (!isa
<ObjCMethodDecl
>(D
)) {
5031 S
.Diag(AL
.getLoc(), diag::warn_attribute_wrong_decl_type
)
5032 << AL
<< ExpectedFunctionOrMethod
;
5036 switch (AL
.getKind()) {
5037 case ParsedAttr::AT_FastCall
:
5038 D
->addAttr(::new (S
.Context
) FastCallAttr(S
.Context
, AL
));
5040 case ParsedAttr::AT_StdCall
:
5041 D
->addAttr(::new (S
.Context
) StdCallAttr(S
.Context
, AL
));
5043 case ParsedAttr::AT_ThisCall
:
5044 D
->addAttr(::new (S
.Context
) ThisCallAttr(S
.Context
, AL
));
5046 case ParsedAttr::AT_CDecl
:
5047 D
->addAttr(::new (S
.Context
) CDeclAttr(S
.Context
, AL
));
5049 case ParsedAttr::AT_Pascal
:
5050 D
->addAttr(::new (S
.Context
) PascalAttr(S
.Context
, AL
));
5052 case ParsedAttr::AT_SwiftCall
:
5053 D
->addAttr(::new (S
.Context
) SwiftCallAttr(S
.Context
, AL
));
5055 case ParsedAttr::AT_SwiftAsyncCall
:
5056 D
->addAttr(::new (S
.Context
) SwiftAsyncCallAttr(S
.Context
, AL
));
5058 case ParsedAttr::AT_VectorCall
:
5059 D
->addAttr(::new (S
.Context
) VectorCallAttr(S
.Context
, AL
));
5061 case ParsedAttr::AT_MSABI
:
5062 D
->addAttr(::new (S
.Context
) MSABIAttr(S
.Context
, AL
));
5064 case ParsedAttr::AT_SysVABI
:
5065 D
->addAttr(::new (S
.Context
) SysVABIAttr(S
.Context
, AL
));
5067 case ParsedAttr::AT_RegCall
:
5068 D
->addAttr(::new (S
.Context
) RegCallAttr(S
.Context
, AL
));
5070 case ParsedAttr::AT_Pcs
: {
5071 PcsAttr::PCSType PCS
;
5074 PCS
= PcsAttr::AAPCS
;
5077 PCS
= PcsAttr::AAPCS_VFP
;
5080 llvm_unreachable("unexpected calling convention in pcs attribute");
5083 D
->addAttr(::new (S
.Context
) PcsAttr(S
.Context
, AL
, PCS
));
5086 case ParsedAttr::AT_AArch64VectorPcs
:
5087 D
->addAttr(::new (S
.Context
) AArch64VectorPcsAttr(S
.Context
, AL
));
5089 case ParsedAttr::AT_AArch64SVEPcs
:
5090 D
->addAttr(::new (S
.Context
) AArch64SVEPcsAttr(S
.Context
, AL
));
5092 case ParsedAttr::AT_AMDGPUKernelCall
:
5093 D
->addAttr(::new (S
.Context
) AMDGPUKernelCallAttr(S
.Context
, AL
));
5095 case ParsedAttr::AT_IntelOclBicc
:
5096 D
->addAttr(::new (S
.Context
) IntelOclBiccAttr(S
.Context
, AL
));
5098 case ParsedAttr::AT_PreserveMost
:
5099 D
->addAttr(::new (S
.Context
) PreserveMostAttr(S
.Context
, AL
));
5101 case ParsedAttr::AT_PreserveAll
:
5102 D
->addAttr(::new (S
.Context
) PreserveAllAttr(S
.Context
, AL
));
5105 llvm_unreachable("unexpected attribute kind");
5109 static void handleSuppressAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
5110 if (!AL
.checkAtLeastNumArgs(S
, 1))
5113 std::vector
<StringRef
> DiagnosticIdentifiers
;
5114 for (unsigned I
= 0, E
= AL
.getNumArgs(); I
!= E
; ++I
) {
5117 if (!S
.checkStringLiteralArgumentAttr(AL
, I
, RuleName
, nullptr))
5120 // FIXME: Warn if the rule name is unknown. This is tricky because only
5121 // clang-tidy knows about available rules.
5122 DiagnosticIdentifiers
.push_back(RuleName
);
5124 D
->addAttr(::new (S
.Context
)
5125 SuppressAttr(S
.Context
, AL
, DiagnosticIdentifiers
.data(),
5126 DiagnosticIdentifiers
.size()));
5129 static void handleLifetimeCategoryAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
5130 TypeSourceInfo
*DerefTypeLoc
= nullptr;
5132 if (AL
.hasParsedType()) {
5133 ParmType
= S
.GetTypeFromParser(AL
.getTypeArg(), &DerefTypeLoc
);
5135 unsigned SelectIdx
= ~0U;
5136 if (ParmType
->isReferenceType())
5138 else if (ParmType
->isArrayType())
5141 if (SelectIdx
!= ~0U) {
5142 S
.Diag(AL
.getLoc(), diag::err_attribute_invalid_argument
)
5148 // To check if earlier decl attributes do not conflict the newly parsed ones
5149 // we always add (and check) the attribute to the canonical decl. We need
5150 // to repeat the check for attribute mutual exclusion because we're attaching
5151 // all of the attributes to the canonical declaration rather than the current
5153 D
= D
->getCanonicalDecl();
5154 if (AL
.getKind() == ParsedAttr::AT_Owner
) {
5155 if (checkAttrMutualExclusion
<PointerAttr
>(S
, D
, AL
))
5157 if (const auto *OAttr
= D
->getAttr
<OwnerAttr
>()) {
5158 const Type
*ExistingDerefType
= OAttr
->getDerefTypeLoc()
5159 ? OAttr
->getDerefType().getTypePtr()
5161 if (ExistingDerefType
!= ParmType
.getTypePtrOrNull()) {
5162 S
.Diag(AL
.getLoc(), diag::err_attributes_are_not_compatible
)
5164 S
.Diag(OAttr
->getLocation(), diag::note_conflicting_attribute
);
5168 for (Decl
*Redecl
: D
->redecls()) {
5169 Redecl
->addAttr(::new (S
.Context
) OwnerAttr(S
.Context
, AL
, DerefTypeLoc
));
5172 if (checkAttrMutualExclusion
<OwnerAttr
>(S
, D
, AL
))
5174 if (const auto *PAttr
= D
->getAttr
<PointerAttr
>()) {
5175 const Type
*ExistingDerefType
= PAttr
->getDerefTypeLoc()
5176 ? PAttr
->getDerefType().getTypePtr()
5178 if (ExistingDerefType
!= ParmType
.getTypePtrOrNull()) {
5179 S
.Diag(AL
.getLoc(), diag::err_attributes_are_not_compatible
)
5181 S
.Diag(PAttr
->getLocation(), diag::note_conflicting_attribute
);
5185 for (Decl
*Redecl
: D
->redecls()) {
5186 Redecl
->addAttr(::new (S
.Context
)
5187 PointerAttr(S
.Context
, AL
, DerefTypeLoc
));
5192 static void handleRandomizeLayoutAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
5193 if (checkAttrMutualExclusion
<NoRandomizeLayoutAttr
>(S
, D
, AL
))
5195 if (!D
->hasAttr
<RandomizeLayoutAttr
>())
5196 D
->addAttr(::new (S
.Context
) RandomizeLayoutAttr(S
.Context
, AL
));
5199 static void handleNoRandomizeLayoutAttr(Sema
&S
, Decl
*D
,
5200 const ParsedAttr
&AL
) {
5201 if (checkAttrMutualExclusion
<RandomizeLayoutAttr
>(S
, D
, AL
))
5203 if (!D
->hasAttr
<NoRandomizeLayoutAttr
>())
5204 D
->addAttr(::new (S
.Context
) NoRandomizeLayoutAttr(S
.Context
, AL
));
5207 bool Sema::CheckCallingConvAttr(const ParsedAttr
&Attrs
, CallingConv
&CC
,
5208 const FunctionDecl
*FD
) {
5209 if (Attrs
.isInvalid())
5212 if (Attrs
.hasProcessingCache()) {
5213 CC
= (CallingConv
) Attrs
.getProcessingCache();
5217 unsigned ReqArgs
= Attrs
.getKind() == ParsedAttr::AT_Pcs
? 1 : 0;
5218 if (!Attrs
.checkExactlyNumArgs(*this, ReqArgs
)) {
5223 // TODO: diagnose uses of these conventions on the wrong target.
5224 switch (Attrs
.getKind()) {
5225 case ParsedAttr::AT_CDecl
:
5228 case ParsedAttr::AT_FastCall
:
5229 CC
= CC_X86FastCall
;
5231 case ParsedAttr::AT_StdCall
:
5234 case ParsedAttr::AT_ThisCall
:
5235 CC
= CC_X86ThisCall
;
5237 case ParsedAttr::AT_Pascal
:
5240 case ParsedAttr::AT_SwiftCall
:
5243 case ParsedAttr::AT_SwiftAsyncCall
:
5246 case ParsedAttr::AT_VectorCall
:
5247 CC
= CC_X86VectorCall
;
5249 case ParsedAttr::AT_AArch64VectorPcs
:
5250 CC
= CC_AArch64VectorCall
;
5252 case ParsedAttr::AT_AArch64SVEPcs
:
5253 CC
= CC_AArch64SVEPCS
;
5255 case ParsedAttr::AT_AMDGPUKernelCall
:
5256 CC
= CC_AMDGPUKernelCall
;
5258 case ParsedAttr::AT_RegCall
:
5261 case ParsedAttr::AT_MSABI
:
5262 CC
= Context
.getTargetInfo().getTriple().isOSWindows() ? CC_C
:
5265 case ParsedAttr::AT_SysVABI
:
5266 CC
= Context
.getTargetInfo().getTriple().isOSWindows() ? CC_X86_64SysV
:
5269 case ParsedAttr::AT_Pcs
: {
5271 if (!checkStringLiteralArgumentAttr(Attrs
, 0, StrRef
)) {
5275 if (StrRef
== "aapcs") {
5278 } else if (StrRef
== "aapcs-vfp") {
5284 Diag(Attrs
.getLoc(), diag::err_invalid_pcs
);
5287 case ParsedAttr::AT_IntelOclBicc
:
5288 CC
= CC_IntelOclBicc
;
5290 case ParsedAttr::AT_PreserveMost
:
5291 CC
= CC_PreserveMost
;
5293 case ParsedAttr::AT_PreserveAll
:
5294 CC
= CC_PreserveAll
;
5296 default: llvm_unreachable("unexpected attribute kind");
5299 TargetInfo::CallingConvCheckResult A
= TargetInfo::CCCR_OK
;
5300 const TargetInfo
&TI
= Context
.getTargetInfo();
5301 // CUDA functions may have host and/or device attributes which indicate
5302 // their targeted execution environment, therefore the calling convention
5303 // of functions in CUDA should be checked against the target deduced based
5304 // on their host/device attributes.
5305 if (LangOpts
.CUDA
) {
5306 auto *Aux
= Context
.getAuxTargetInfo();
5307 auto CudaTarget
= IdentifyCUDATarget(FD
);
5308 bool CheckHost
= false, CheckDevice
= false;
5309 switch (CudaTarget
) {
5310 case CFT_HostDevice
:
5321 case CFT_InvalidTarget
:
5322 llvm_unreachable("unexpected cuda target");
5324 auto *HostTI
= LangOpts
.CUDAIsDevice
? Aux
: &TI
;
5325 auto *DeviceTI
= LangOpts
.CUDAIsDevice
? &TI
: Aux
;
5326 if (CheckHost
&& HostTI
)
5327 A
= HostTI
->checkCallingConvention(CC
);
5328 if (A
== TargetInfo::CCCR_OK
&& CheckDevice
&& DeviceTI
)
5329 A
= DeviceTI
->checkCallingConvention(CC
);
5331 A
= TI
.checkCallingConvention(CC
);
5335 case TargetInfo::CCCR_OK
:
5338 case TargetInfo::CCCR_Ignore
:
5339 // Treat an ignored convention as if it was an explicit C calling convention
5340 // attribute. For example, __stdcall on Win x64 functions as __cdecl, so
5341 // that command line flags that change the default convention to
5342 // __vectorcall don't affect declarations marked __stdcall.
5346 case TargetInfo::CCCR_Error
:
5347 Diag(Attrs
.getLoc(), diag::error_cconv_unsupported
)
5348 << Attrs
<< (int)CallingConventionIgnoredReason::ForThisTarget
;
5351 case TargetInfo::CCCR_Warning
: {
5352 Diag(Attrs
.getLoc(), diag::warn_cconv_unsupported
)
5353 << Attrs
<< (int)CallingConventionIgnoredReason::ForThisTarget
;
5355 // This convention is not valid for the target. Use the default function or
5356 // method calling convention.
5357 bool IsCXXMethod
= false, IsVariadic
= false;
5359 IsCXXMethod
= FD
->isCXXInstanceMember();
5360 IsVariadic
= FD
->isVariadic();
5362 CC
= Context
.getDefaultCallingConvention(IsVariadic
, IsCXXMethod
);
5367 Attrs
.setProcessingCache((unsigned) CC
);
5371 /// Pointer-like types in the default address space.
5372 static bool isValidSwiftContextType(QualType Ty
) {
5373 if (!Ty
->hasPointerRepresentation())
5374 return Ty
->isDependentType();
5375 return Ty
->getPointeeType().getAddressSpace() == LangAS::Default
;
5378 /// Pointers and references in the default address space.
5379 static bool isValidSwiftIndirectResultType(QualType Ty
) {
5380 if (const auto *PtrType
= Ty
->getAs
<PointerType
>()) {
5381 Ty
= PtrType
->getPointeeType();
5382 } else if (const auto *RefType
= Ty
->getAs
<ReferenceType
>()) {
5383 Ty
= RefType
->getPointeeType();
5385 return Ty
->isDependentType();
5387 return Ty
.getAddressSpace() == LangAS::Default
;
5390 /// Pointers and references to pointers in the default address space.
5391 static bool isValidSwiftErrorResultType(QualType Ty
) {
5392 if (const auto *PtrType
= Ty
->getAs
<PointerType
>()) {
5393 Ty
= PtrType
->getPointeeType();
5394 } else if (const auto *RefType
= Ty
->getAs
<ReferenceType
>()) {
5395 Ty
= RefType
->getPointeeType();
5397 return Ty
->isDependentType();
5399 if (!Ty
.getQualifiers().empty())
5401 return isValidSwiftContextType(Ty
);
5404 void Sema::AddParameterABIAttr(Decl
*D
, const AttributeCommonInfo
&CI
,
5407 QualType type
= cast
<ParmVarDecl
>(D
)->getType();
5409 if (auto existingAttr
= D
->getAttr
<ParameterABIAttr
>()) {
5410 if (existingAttr
->getABI() != abi
) {
5411 Diag(CI
.getLoc(), diag::err_attributes_are_not_compatible
)
5412 << getParameterABISpelling(abi
) << existingAttr
;
5413 Diag(existingAttr
->getLocation(), diag::note_conflicting_attribute
);
5419 case ParameterABI::Ordinary
:
5420 llvm_unreachable("explicit attribute for ordinary parameter ABI?");
5422 case ParameterABI::SwiftContext
:
5423 if (!isValidSwiftContextType(type
)) {
5424 Diag(CI
.getLoc(), diag::err_swift_abi_parameter_wrong_type
)
5425 << getParameterABISpelling(abi
) << /*pointer to pointer */ 0 << type
;
5427 D
->addAttr(::new (Context
) SwiftContextAttr(Context
, CI
));
5430 case ParameterABI::SwiftAsyncContext
:
5431 if (!isValidSwiftContextType(type
)) {
5432 Diag(CI
.getLoc(), diag::err_swift_abi_parameter_wrong_type
)
5433 << getParameterABISpelling(abi
) << /*pointer to pointer */ 0 << type
;
5435 D
->addAttr(::new (Context
) SwiftAsyncContextAttr(Context
, CI
));
5438 case ParameterABI::SwiftErrorResult
:
5439 if (!isValidSwiftErrorResultType(type
)) {
5440 Diag(CI
.getLoc(), diag::err_swift_abi_parameter_wrong_type
)
5441 << getParameterABISpelling(abi
) << /*pointer to pointer */ 1 << type
;
5443 D
->addAttr(::new (Context
) SwiftErrorResultAttr(Context
, CI
));
5446 case ParameterABI::SwiftIndirectResult
:
5447 if (!isValidSwiftIndirectResultType(type
)) {
5448 Diag(CI
.getLoc(), diag::err_swift_abi_parameter_wrong_type
)
5449 << getParameterABISpelling(abi
) << /*pointer*/ 0 << type
;
5451 D
->addAttr(::new (Context
) SwiftIndirectResultAttr(Context
, CI
));
5454 llvm_unreachable("bad parameter ABI attribute");
5457 /// Checks a regparm attribute, returning true if it is ill-formed and
5458 /// otherwise setting numParams to the appropriate value.
5459 bool Sema::CheckRegparmAttr(const ParsedAttr
&AL
, unsigned &numParams
) {
5463 if (!AL
.checkExactlyNumArgs(*this, 1)) {
5469 Expr
*NumParamsExpr
= AL
.getArgAsExpr(0);
5470 if (!checkUInt32Argument(*this, AL
, NumParamsExpr
, NP
)) {
5475 if (Context
.getTargetInfo().getRegParmMax() == 0) {
5476 Diag(AL
.getLoc(), diag::err_attribute_regparm_wrong_platform
)
5477 << NumParamsExpr
->getSourceRange();
5483 if (numParams
> Context
.getTargetInfo().getRegParmMax()) {
5484 Diag(AL
.getLoc(), diag::err_attribute_regparm_invalid_number
)
5485 << Context
.getTargetInfo().getRegParmMax() << NumParamsExpr
->getSourceRange();
5493 // Checks whether an argument of launch_bounds attribute is
5494 // acceptable, performs implicit conversion to Rvalue, and returns
5495 // non-nullptr Expr result on success. Otherwise, it returns nullptr
5496 // and may output an error.
5497 static Expr
*makeLaunchBoundsArgExpr(Sema
&S
, Expr
*E
,
5498 const CUDALaunchBoundsAttr
&AL
,
5499 const unsigned Idx
) {
5500 if (S
.DiagnoseUnexpandedParameterPack(E
))
5503 // Accept template arguments for now as they depend on something else.
5504 // We'll get to check them when they eventually get instantiated.
5505 if (E
->isValueDependent())
5508 std::optional
<llvm::APSInt
> I
= llvm::APSInt(64);
5509 if (!(I
= E
->getIntegerConstantExpr(S
.Context
))) {
5510 S
.Diag(E
->getExprLoc(), diag::err_attribute_argument_n_type
)
5511 << &AL
<< Idx
<< AANT_ArgumentIntegerConstant
<< E
->getSourceRange();
5514 // Make sure we can fit it in 32 bits.
5515 if (!I
->isIntN(32)) {
5516 S
.Diag(E
->getExprLoc(), diag::err_ice_too_large
)
5517 << toString(*I
, 10, false) << 32 << /* Unsigned */ 1;
5521 S
.Diag(E
->getExprLoc(), diag::warn_attribute_argument_n_negative
)
5522 << &AL
<< Idx
<< E
->getSourceRange();
5524 // We may need to perform implicit conversion of the argument.
5525 InitializedEntity Entity
= InitializedEntity::InitializeParameter(
5526 S
.Context
, S
.Context
.getConstType(S
.Context
.IntTy
), /*consume*/ false);
5527 ExprResult ValArg
= S
.PerformCopyInitialization(Entity
, SourceLocation(), E
);
5528 assert(!ValArg
.isInvalid() &&
5529 "Unexpected PerformCopyInitialization() failure.");
5531 return ValArg
.getAs
<Expr
>();
5534 void Sema::AddLaunchBoundsAttr(Decl
*D
, const AttributeCommonInfo
&CI
,
5535 Expr
*MaxThreads
, Expr
*MinBlocks
) {
5536 CUDALaunchBoundsAttr
TmpAttr(Context
, CI
, MaxThreads
, MinBlocks
);
5537 MaxThreads
= makeLaunchBoundsArgExpr(*this, MaxThreads
, TmpAttr
, 0);
5538 if (MaxThreads
== nullptr)
5542 MinBlocks
= makeLaunchBoundsArgExpr(*this, MinBlocks
, TmpAttr
, 1);
5543 if (MinBlocks
== nullptr)
5547 D
->addAttr(::new (Context
)
5548 CUDALaunchBoundsAttr(Context
, CI
, MaxThreads
, MinBlocks
));
5551 static void handleLaunchBoundsAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
5552 if (!AL
.checkAtLeastNumArgs(S
, 1) || !AL
.checkAtMostNumArgs(S
, 2))
5555 S
.AddLaunchBoundsAttr(D
, AL
, AL
.getArgAsExpr(0),
5556 AL
.getNumArgs() > 1 ? AL
.getArgAsExpr(1) : nullptr);
5559 static void handleArgumentWithTypeTagAttr(Sema
&S
, Decl
*D
,
5560 const ParsedAttr
&AL
) {
5561 if (!AL
.isArgIdent(0)) {
5562 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_n_type
)
5563 << AL
<< /* arg num = */ 1 << AANT_ArgumentIdentifier
;
5567 ParamIdx ArgumentIdx
;
5568 if (!checkFunctionOrMethodParameterIndex(S
, D
, AL
, 2, AL
.getArgAsExpr(1),
5572 ParamIdx TypeTagIdx
;
5573 if (!checkFunctionOrMethodParameterIndex(S
, D
, AL
, 3, AL
.getArgAsExpr(2),
5577 bool IsPointer
= AL
.getAttrName()->getName() == "pointer_with_type_tag";
5579 // Ensure that buffer has a pointer type.
5580 unsigned ArgumentIdxAST
= ArgumentIdx
.getASTIndex();
5581 if (ArgumentIdxAST
>= getFunctionOrMethodNumParams(D
) ||
5582 !getFunctionOrMethodParamType(D
, ArgumentIdxAST
)->isPointerType())
5583 S
.Diag(AL
.getLoc(), diag::err_attribute_pointers_only
) << AL
<< 0;
5586 D
->addAttr(::new (S
.Context
) ArgumentWithTypeTagAttr(
5587 S
.Context
, AL
, AL
.getArgAsIdent(0)->Ident
, ArgumentIdx
, TypeTagIdx
,
5591 static void handleTypeTagForDatatypeAttr(Sema
&S
, Decl
*D
,
5592 const ParsedAttr
&AL
) {
5593 if (!AL
.isArgIdent(0)) {
5594 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_n_type
)
5595 << AL
<< 1 << AANT_ArgumentIdentifier
;
5599 if (!AL
.checkExactlyNumArgs(S
, 1))
5602 if (!isa
<VarDecl
>(D
)) {
5603 S
.Diag(AL
.getLoc(), diag::err_attribute_wrong_decl_type
)
5604 << AL
<< ExpectedVariable
;
5608 IdentifierInfo
*PointerKind
= AL
.getArgAsIdent(0)->Ident
;
5609 TypeSourceInfo
*MatchingCTypeLoc
= nullptr;
5610 S
.GetTypeFromParser(AL
.getMatchingCType(), &MatchingCTypeLoc
);
5611 assert(MatchingCTypeLoc
&& "no type source info for attribute argument");
5613 D
->addAttr(::new (S
.Context
) TypeTagForDatatypeAttr(
5614 S
.Context
, AL
, PointerKind
, MatchingCTypeLoc
, AL
.getLayoutCompatible(),
5615 AL
.getMustBeNull()));
5618 static void handleXRayLogArgsAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
5621 if (!checkFunctionOrMethodParameterIndex(S
, D
, AL
, 1, AL
.getArgAsExpr(0),
5623 true /* CanIndexImplicitThis */))
5626 // ArgCount isn't a parameter index [0;n), it's a count [1;n]
5627 D
->addAttr(::new (S
.Context
)
5628 XRayLogArgsAttr(S
.Context
, AL
, ArgCount
.getSourceIndex()));
5631 static void handlePatchableFunctionEntryAttr(Sema
&S
, Decl
*D
,
5632 const ParsedAttr
&AL
) {
5633 uint32_t Count
= 0, Offset
= 0;
5634 if (!checkUInt32Argument(S
, AL
, AL
.getArgAsExpr(0), Count
, 0, true))
5636 if (AL
.getNumArgs() == 2) {
5637 Expr
*Arg
= AL
.getArgAsExpr(1);
5638 if (!checkUInt32Argument(S
, AL
, Arg
, Offset
, 1, true))
5640 if (Count
< Offset
) {
5641 S
.Diag(getAttrLoc(AL
), diag::err_attribute_argument_out_of_range
)
5642 << &AL
<< 0 << Count
<< Arg
->getBeginLoc();
5646 D
->addAttr(::new (S
.Context
)
5647 PatchableFunctionEntryAttr(S
.Context
, AL
, Count
, Offset
));
5651 struct IntrinToName
{
5656 } // unnamed namespace
5658 static bool ArmBuiltinAliasValid(unsigned BuiltinID
, StringRef AliasName
,
5659 ArrayRef
<IntrinToName
> Map
,
5660 const char *IntrinNames
) {
5661 if (AliasName
.startswith("__arm_"))
5662 AliasName
= AliasName
.substr(6);
5663 const IntrinToName
*It
=
5664 llvm::lower_bound(Map
, BuiltinID
, [](const IntrinToName
&L
, unsigned Id
) {
5667 if (It
== Map
.end() || It
->Id
!= BuiltinID
)
5669 StringRef
FullName(&IntrinNames
[It
->FullName
]);
5670 if (AliasName
== FullName
)
5672 if (It
->ShortName
== -1)
5674 StringRef
ShortName(&IntrinNames
[It
->ShortName
]);
5675 return AliasName
== ShortName
;
5678 static bool ArmMveAliasValid(unsigned BuiltinID
, StringRef AliasName
) {
5679 #include "clang/Basic/arm_mve_builtin_aliases.inc"
5680 // The included file defines:
5681 // - ArrayRef<IntrinToName> Map
5682 // - const char IntrinNames[]
5683 return ArmBuiltinAliasValid(BuiltinID
, AliasName
, Map
, IntrinNames
);
5686 static bool ArmCdeAliasValid(unsigned BuiltinID
, StringRef AliasName
) {
5687 #include "clang/Basic/arm_cde_builtin_aliases.inc"
5688 return ArmBuiltinAliasValid(BuiltinID
, AliasName
, Map
, IntrinNames
);
5691 static bool ArmSveAliasValid(ASTContext
&Context
, unsigned BuiltinID
,
5692 StringRef AliasName
) {
5693 if (Context
.BuiltinInfo
.isAuxBuiltinID(BuiltinID
))
5694 BuiltinID
= Context
.BuiltinInfo
.getAuxBuiltinID(BuiltinID
);
5695 return BuiltinID
>= AArch64::FirstSVEBuiltin
&&
5696 BuiltinID
<= AArch64::LastSVEBuiltin
;
5699 static void handleArmBuiltinAliasAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
5700 if (!AL
.isArgIdent(0)) {
5701 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_n_type
)
5702 << AL
<< 1 << AANT_ArgumentIdentifier
;
5706 IdentifierInfo
*Ident
= AL
.getArgAsIdent(0)->Ident
;
5707 unsigned BuiltinID
= Ident
->getBuiltinID();
5708 StringRef AliasName
= cast
<FunctionDecl
>(D
)->getIdentifier()->getName();
5710 bool IsAArch64
= S
.Context
.getTargetInfo().getTriple().isAArch64();
5711 if ((IsAArch64
&& !ArmSveAliasValid(S
.Context
, BuiltinID
, AliasName
)) ||
5712 (!IsAArch64
&& !ArmMveAliasValid(BuiltinID
, AliasName
) &&
5713 !ArmCdeAliasValid(BuiltinID
, AliasName
))) {
5714 S
.Diag(AL
.getLoc(), diag::err_attribute_arm_builtin_alias
);
5718 D
->addAttr(::new (S
.Context
) ArmBuiltinAliasAttr(S
.Context
, AL
, Ident
));
5721 static bool RISCVAliasValid(unsigned BuiltinID
, StringRef AliasName
) {
5722 return BuiltinID
>= RISCV::FirstRVVBuiltin
&&
5723 BuiltinID
<= RISCV::LastRVVBuiltin
;
5726 static void handleBuiltinAliasAttr(Sema
&S
, Decl
*D
,
5727 const ParsedAttr
&AL
) {
5728 if (!AL
.isArgIdent(0)) {
5729 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_n_type
)
5730 << AL
<< 1 << AANT_ArgumentIdentifier
;
5734 IdentifierInfo
*Ident
= AL
.getArgAsIdent(0)->Ident
;
5735 unsigned BuiltinID
= Ident
->getBuiltinID();
5736 StringRef AliasName
= cast
<FunctionDecl
>(D
)->getIdentifier()->getName();
5738 bool IsAArch64
= S
.Context
.getTargetInfo().getTriple().isAArch64();
5739 bool IsARM
= S
.Context
.getTargetInfo().getTriple().isARM();
5740 bool IsRISCV
= S
.Context
.getTargetInfo().getTriple().isRISCV();
5741 bool IsHLSL
= S
.Context
.getLangOpts().HLSL
;
5742 if ((IsAArch64
&& !ArmSveAliasValid(S
.Context
, BuiltinID
, AliasName
)) ||
5743 (IsARM
&& !ArmMveAliasValid(BuiltinID
, AliasName
) &&
5744 !ArmCdeAliasValid(BuiltinID
, AliasName
)) ||
5745 (IsRISCV
&& !RISCVAliasValid(BuiltinID
, AliasName
)) ||
5746 (!IsAArch64
&& !IsARM
&& !IsRISCV
&& !IsHLSL
)) {
5747 S
.Diag(AL
.getLoc(), diag::err_attribute_builtin_alias
) << AL
;
5751 D
->addAttr(::new (S
.Context
) BuiltinAliasAttr(S
.Context
, AL
, Ident
));
5754 //===----------------------------------------------------------------------===//
5755 // Checker-specific attribute handlers.
5756 //===----------------------------------------------------------------------===//
5757 static bool isValidSubjectOfNSReturnsRetainedAttribute(QualType QT
) {
5758 return QT
->isDependentType() || QT
->isObjCRetainableType();
5761 static bool isValidSubjectOfNSAttribute(QualType QT
) {
5762 return QT
->isDependentType() || QT
->isObjCObjectPointerType() ||
5763 QT
->isObjCNSObjectType();
5766 static bool isValidSubjectOfCFAttribute(QualType QT
) {
5767 return QT
->isDependentType() || QT
->isPointerType() ||
5768 isValidSubjectOfNSAttribute(QT
);
5771 static bool isValidSubjectOfOSAttribute(QualType QT
) {
5772 if (QT
->isDependentType())
5774 QualType PT
= QT
->getPointeeType();
5775 return !PT
.isNull() && PT
->getAsCXXRecordDecl() != nullptr;
5778 void Sema::AddXConsumedAttr(Decl
*D
, const AttributeCommonInfo
&CI
,
5779 RetainOwnershipKind K
,
5780 bool IsTemplateInstantiation
) {
5781 ValueDecl
*VD
= cast
<ValueDecl
>(D
);
5783 case RetainOwnershipKind::OS
:
5784 handleSimpleAttributeOrDiagnose
<OSConsumedAttr
>(
5785 *this, VD
, CI
, isValidSubjectOfOSAttribute(VD
->getType()),
5786 diag::warn_ns_attribute_wrong_parameter_type
,
5787 /*ExtraArgs=*/CI
.getRange(), "os_consumed", /*pointers*/ 1);
5789 case RetainOwnershipKind::NS
:
5790 handleSimpleAttributeOrDiagnose
<NSConsumedAttr
>(
5791 *this, VD
, CI
, isValidSubjectOfNSAttribute(VD
->getType()),
5793 // These attributes are normally just advisory, but in ARC, ns_consumed
5794 // is significant. Allow non-dependent code to contain inappropriate
5795 // attributes even in ARC, but require template instantiations to be
5796 // set up correctly.
5797 ((IsTemplateInstantiation
&& getLangOpts().ObjCAutoRefCount
)
5798 ? diag::err_ns_attribute_wrong_parameter_type
5799 : diag::warn_ns_attribute_wrong_parameter_type
),
5800 /*ExtraArgs=*/CI
.getRange(), "ns_consumed", /*objc pointers*/ 0);
5802 case RetainOwnershipKind::CF
:
5803 handleSimpleAttributeOrDiagnose
<CFConsumedAttr
>(
5804 *this, VD
, CI
, isValidSubjectOfCFAttribute(VD
->getType()),
5805 diag::warn_ns_attribute_wrong_parameter_type
,
5806 /*ExtraArgs=*/CI
.getRange(), "cf_consumed", /*pointers*/ 1);
5811 static Sema::RetainOwnershipKind
5812 parsedAttrToRetainOwnershipKind(const ParsedAttr
&AL
) {
5813 switch (AL
.getKind()) {
5814 case ParsedAttr::AT_CFConsumed
:
5815 case ParsedAttr::AT_CFReturnsRetained
:
5816 case ParsedAttr::AT_CFReturnsNotRetained
:
5817 return Sema::RetainOwnershipKind::CF
;
5818 case ParsedAttr::AT_OSConsumesThis
:
5819 case ParsedAttr::AT_OSConsumed
:
5820 case ParsedAttr::AT_OSReturnsRetained
:
5821 case ParsedAttr::AT_OSReturnsNotRetained
:
5822 case ParsedAttr::AT_OSReturnsRetainedOnZero
:
5823 case ParsedAttr::AT_OSReturnsRetainedOnNonZero
:
5824 return Sema::RetainOwnershipKind::OS
;
5825 case ParsedAttr::AT_NSConsumesSelf
:
5826 case ParsedAttr::AT_NSConsumed
:
5827 case ParsedAttr::AT_NSReturnsRetained
:
5828 case ParsedAttr::AT_NSReturnsNotRetained
:
5829 case ParsedAttr::AT_NSReturnsAutoreleased
:
5830 return Sema::RetainOwnershipKind::NS
;
5832 llvm_unreachable("Wrong argument supplied");
5836 bool Sema::checkNSReturnsRetainedReturnType(SourceLocation Loc
, QualType QT
) {
5837 if (isValidSubjectOfNSReturnsRetainedAttribute(QT
))
5840 Diag(Loc
, diag::warn_ns_attribute_wrong_return_type
)
5841 << "'ns_returns_retained'" << 0 << 0;
5845 /// \return whether the parameter is a pointer to OSObject pointer.
5846 static bool isValidOSObjectOutParameter(const Decl
*D
) {
5847 const auto *PVD
= dyn_cast
<ParmVarDecl
>(D
);
5850 QualType QT
= PVD
->getType();
5851 QualType PT
= QT
->getPointeeType();
5852 return !PT
.isNull() && isValidSubjectOfOSAttribute(PT
);
5855 static void handleXReturnsXRetainedAttr(Sema
&S
, Decl
*D
,
5856 const ParsedAttr
&AL
) {
5857 QualType ReturnType
;
5858 Sema::RetainOwnershipKind K
= parsedAttrToRetainOwnershipKind(AL
);
5860 if (const auto *MD
= dyn_cast
<ObjCMethodDecl
>(D
)) {
5861 ReturnType
= MD
->getReturnType();
5862 } else if (S
.getLangOpts().ObjCAutoRefCount
&& hasDeclarator(D
) &&
5863 (AL
.getKind() == ParsedAttr::AT_NSReturnsRetained
)) {
5864 return; // ignore: was handled as a type attribute
5865 } else if (const auto *PD
= dyn_cast
<ObjCPropertyDecl
>(D
)) {
5866 ReturnType
= PD
->getType();
5867 } else if (const auto *FD
= dyn_cast
<FunctionDecl
>(D
)) {
5868 ReturnType
= FD
->getReturnType();
5869 } else if (const auto *Param
= dyn_cast
<ParmVarDecl
>(D
)) {
5870 // Attributes on parameters are used for out-parameters,
5871 // passed as pointers-to-pointers.
5872 unsigned DiagID
= K
== Sema::RetainOwnershipKind::CF
5873 ? /*pointer-to-CF-pointer*/2
5874 : /*pointer-to-OSObject-pointer*/3;
5875 ReturnType
= Param
->getType()->getPointeeType();
5876 if (ReturnType
.isNull()) {
5877 S
.Diag(D
->getBeginLoc(), diag::warn_ns_attribute_wrong_parameter_type
)
5878 << AL
<< DiagID
<< AL
.getRange();
5881 } else if (AL
.isUsedAsTypeAttr()) {
5884 AttributeDeclKind ExpectedDeclKind
;
5885 switch (AL
.getKind()) {
5886 default: llvm_unreachable("invalid ownership attribute");
5887 case ParsedAttr::AT_NSReturnsRetained
:
5888 case ParsedAttr::AT_NSReturnsAutoreleased
:
5889 case ParsedAttr::AT_NSReturnsNotRetained
:
5890 ExpectedDeclKind
= ExpectedFunctionOrMethod
;
5893 case ParsedAttr::AT_OSReturnsRetained
:
5894 case ParsedAttr::AT_OSReturnsNotRetained
:
5895 case ParsedAttr::AT_CFReturnsRetained
:
5896 case ParsedAttr::AT_CFReturnsNotRetained
:
5897 ExpectedDeclKind
= ExpectedFunctionMethodOrParameter
;
5900 S
.Diag(D
->getBeginLoc(), diag::warn_attribute_wrong_decl_type
)
5901 << AL
.getRange() << AL
<< ExpectedDeclKind
;
5907 unsigned ParmDiagID
= 2; // Pointer-to-CF-pointer
5908 switch (AL
.getKind()) {
5909 default: llvm_unreachable("invalid ownership attribute");
5910 case ParsedAttr::AT_NSReturnsRetained
:
5911 TypeOK
= isValidSubjectOfNSReturnsRetainedAttribute(ReturnType
);
5915 case ParsedAttr::AT_NSReturnsAutoreleased
:
5916 case ParsedAttr::AT_NSReturnsNotRetained
:
5917 TypeOK
= isValidSubjectOfNSAttribute(ReturnType
);
5921 case ParsedAttr::AT_CFReturnsRetained
:
5922 case ParsedAttr::AT_CFReturnsNotRetained
:
5923 TypeOK
= isValidSubjectOfCFAttribute(ReturnType
);
5927 case ParsedAttr::AT_OSReturnsRetained
:
5928 case ParsedAttr::AT_OSReturnsNotRetained
:
5929 TypeOK
= isValidSubjectOfOSAttribute(ReturnType
);
5931 ParmDiagID
= 3; // Pointer-to-OSObject-pointer
5936 if (AL
.isUsedAsTypeAttr())
5939 if (isa
<ParmVarDecl
>(D
)) {
5940 S
.Diag(D
->getBeginLoc(), diag::warn_ns_attribute_wrong_parameter_type
)
5941 << AL
<< ParmDiagID
<< AL
.getRange();
5943 // Needs to be kept in sync with warn_ns_attribute_wrong_return_type.
5948 } SubjectKind
= Function
;
5949 if (isa
<ObjCMethodDecl
>(D
))
5950 SubjectKind
= Method
;
5951 else if (isa
<ObjCPropertyDecl
>(D
))
5952 SubjectKind
= Property
;
5953 S
.Diag(D
->getBeginLoc(), diag::warn_ns_attribute_wrong_return_type
)
5954 << AL
<< SubjectKind
<< Cf
<< AL
.getRange();
5959 switch (AL
.getKind()) {
5961 llvm_unreachable("invalid ownership attribute");
5962 case ParsedAttr::AT_NSReturnsAutoreleased
:
5963 handleSimpleAttribute
<NSReturnsAutoreleasedAttr
>(S
, D
, AL
);
5965 case ParsedAttr::AT_CFReturnsNotRetained
:
5966 handleSimpleAttribute
<CFReturnsNotRetainedAttr
>(S
, D
, AL
);
5968 case ParsedAttr::AT_NSReturnsNotRetained
:
5969 handleSimpleAttribute
<NSReturnsNotRetainedAttr
>(S
, D
, AL
);
5971 case ParsedAttr::AT_CFReturnsRetained
:
5972 handleSimpleAttribute
<CFReturnsRetainedAttr
>(S
, D
, AL
);
5974 case ParsedAttr::AT_NSReturnsRetained
:
5975 handleSimpleAttribute
<NSReturnsRetainedAttr
>(S
, D
, AL
);
5977 case ParsedAttr::AT_OSReturnsRetained
:
5978 handleSimpleAttribute
<OSReturnsRetainedAttr
>(S
, D
, AL
);
5980 case ParsedAttr::AT_OSReturnsNotRetained
:
5981 handleSimpleAttribute
<OSReturnsNotRetainedAttr
>(S
, D
, AL
);
5986 static void handleObjCReturnsInnerPointerAttr(Sema
&S
, Decl
*D
,
5987 const ParsedAttr
&Attrs
) {
5988 const int EP_ObjCMethod
= 1;
5989 const int EP_ObjCProperty
= 2;
5991 SourceLocation loc
= Attrs
.getLoc();
5992 QualType resultType
;
5993 if (isa
<ObjCMethodDecl
>(D
))
5994 resultType
= cast
<ObjCMethodDecl
>(D
)->getReturnType();
5996 resultType
= cast
<ObjCPropertyDecl
>(D
)->getType();
5998 if (!resultType
->isReferenceType() &&
5999 (!resultType
->isPointerType() || resultType
->isObjCRetainableType())) {
6000 S
.Diag(D
->getBeginLoc(), diag::warn_ns_attribute_wrong_return_type
)
6001 << SourceRange(loc
) << Attrs
6002 << (isa
<ObjCMethodDecl
>(D
) ? EP_ObjCMethod
: EP_ObjCProperty
)
6003 << /*non-retainable pointer*/ 2;
6005 // Drop the attribute.
6009 D
->addAttr(::new (S
.Context
) ObjCReturnsInnerPointerAttr(S
.Context
, Attrs
));
6012 static void handleObjCRequiresSuperAttr(Sema
&S
, Decl
*D
,
6013 const ParsedAttr
&Attrs
) {
6014 const auto *Method
= cast
<ObjCMethodDecl
>(D
);
6016 const DeclContext
*DC
= Method
->getDeclContext();
6017 if (const auto *PDecl
= dyn_cast_or_null
<ObjCProtocolDecl
>(DC
)) {
6018 S
.Diag(D
->getBeginLoc(), diag::warn_objc_requires_super_protocol
) << Attrs
6020 S
.Diag(PDecl
->getLocation(), diag::note_protocol_decl
);
6023 if (Method
->getMethodFamily() == OMF_dealloc
) {
6024 S
.Diag(D
->getBeginLoc(), diag::warn_objc_requires_super_protocol
) << Attrs
6029 D
->addAttr(::new (S
.Context
) ObjCRequiresSuperAttr(S
.Context
, Attrs
));
6032 static void handleNSErrorDomain(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
6033 auto *E
= AL
.getArgAsExpr(0);
6034 auto Loc
= E
? E
->getBeginLoc() : AL
.getLoc();
6036 auto *DRE
= dyn_cast
<DeclRefExpr
>(AL
.getArgAsExpr(0));
6038 S
.Diag(Loc
, diag::err_nserrordomain_invalid_decl
) << 0;
6042 auto *VD
= dyn_cast
<VarDecl
>(DRE
->getDecl());
6044 S
.Diag(Loc
, diag::err_nserrordomain_invalid_decl
) << 1 << DRE
->getDecl();
6048 if (!isNSStringType(VD
->getType(), S
.Context
) &&
6049 !isCFStringType(VD
->getType(), S
.Context
)) {
6050 S
.Diag(Loc
, diag::err_nserrordomain_wrong_type
) << VD
;
6054 D
->addAttr(::new (S
.Context
) NSErrorDomainAttr(S
.Context
, AL
, VD
));
6057 static void handleObjCBridgeAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
6058 IdentifierLoc
*Parm
= AL
.isArgIdent(0) ? AL
.getArgAsIdent(0) : nullptr;
6061 S
.Diag(D
->getBeginLoc(), diag::err_objc_attr_not_id
) << AL
<< 0;
6065 // Typedefs only allow objc_bridge(id) and have some additional checking.
6066 if (const auto *TD
= dyn_cast
<TypedefNameDecl
>(D
)) {
6067 if (!Parm
->Ident
->isStr("id")) {
6068 S
.Diag(AL
.getLoc(), diag::err_objc_attr_typedef_not_id
) << AL
;
6072 // Only allow 'cv void *'.
6073 QualType T
= TD
->getUnderlyingType();
6074 if (!T
->isVoidPointerType()) {
6075 S
.Diag(AL
.getLoc(), diag::err_objc_attr_typedef_not_void_pointer
);
6080 D
->addAttr(::new (S
.Context
) ObjCBridgeAttr(S
.Context
, AL
, Parm
->Ident
));
6083 static void handleObjCBridgeMutableAttr(Sema
&S
, Decl
*D
,
6084 const ParsedAttr
&AL
) {
6085 IdentifierLoc
*Parm
= AL
.isArgIdent(0) ? AL
.getArgAsIdent(0) : nullptr;
6088 S
.Diag(D
->getBeginLoc(), diag::err_objc_attr_not_id
) << AL
<< 0;
6092 D
->addAttr(::new (S
.Context
)
6093 ObjCBridgeMutableAttr(S
.Context
, AL
, Parm
->Ident
));
6096 static void handleObjCBridgeRelatedAttr(Sema
&S
, Decl
*D
,
6097 const ParsedAttr
&AL
) {
6098 IdentifierInfo
*RelatedClass
=
6099 AL
.isArgIdent(0) ? AL
.getArgAsIdent(0)->Ident
: nullptr;
6100 if (!RelatedClass
) {
6101 S
.Diag(D
->getBeginLoc(), diag::err_objc_attr_not_id
) << AL
<< 0;
6104 IdentifierInfo
*ClassMethod
=
6105 AL
.getArgAsIdent(1) ? AL
.getArgAsIdent(1)->Ident
: nullptr;
6106 IdentifierInfo
*InstanceMethod
=
6107 AL
.getArgAsIdent(2) ? AL
.getArgAsIdent(2)->Ident
: nullptr;
6108 D
->addAttr(::new (S
.Context
) ObjCBridgeRelatedAttr(
6109 S
.Context
, AL
, RelatedClass
, ClassMethod
, InstanceMethod
));
6112 static void handleObjCDesignatedInitializer(Sema
&S
, Decl
*D
,
6113 const ParsedAttr
&AL
) {
6114 DeclContext
*Ctx
= D
->getDeclContext();
6116 // This attribute can only be applied to methods in interfaces or class
6118 if (!isa
<ObjCInterfaceDecl
>(Ctx
) &&
6119 !(isa
<ObjCCategoryDecl
>(Ctx
) &&
6120 cast
<ObjCCategoryDecl
>(Ctx
)->IsClassExtension())) {
6121 S
.Diag(D
->getLocation(), diag::err_designated_init_attr_non_init
);
6125 ObjCInterfaceDecl
*IFace
;
6126 if (auto *CatDecl
= dyn_cast
<ObjCCategoryDecl
>(Ctx
))
6127 IFace
= CatDecl
->getClassInterface();
6129 IFace
= cast
<ObjCInterfaceDecl
>(Ctx
);
6134 IFace
->setHasDesignatedInitializers();
6135 D
->addAttr(::new (S
.Context
) ObjCDesignatedInitializerAttr(S
.Context
, AL
));
6138 static void handleObjCRuntimeName(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
6139 StringRef MetaDataName
;
6140 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, MetaDataName
))
6142 D
->addAttr(::new (S
.Context
)
6143 ObjCRuntimeNameAttr(S
.Context
, AL
, MetaDataName
));
6146 // When a user wants to use objc_boxable with a union or struct
6147 // but they don't have access to the declaration (legacy/third-party code)
6148 // then they can 'enable' this feature with a typedef:
6149 // typedef struct __attribute((objc_boxable)) legacy_struct legacy_struct;
6150 static void handleObjCBoxable(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
6151 bool notify
= false;
6153 auto *RD
= dyn_cast
<RecordDecl
>(D
);
6154 if (RD
&& RD
->getDefinition()) {
6155 RD
= RD
->getDefinition();
6160 ObjCBoxableAttr
*BoxableAttr
=
6161 ::new (S
.Context
) ObjCBoxableAttr(S
.Context
, AL
);
6162 RD
->addAttr(BoxableAttr
);
6164 // we need to notify ASTReader/ASTWriter about
6165 // modification of existing declaration
6166 if (ASTMutationListener
*L
= S
.getASTMutationListener())
6167 L
->AddedAttributeToRecord(BoxableAttr
, RD
);
6172 static void handleObjCOwnershipAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
6173 if (hasDeclarator(D
)) return;
6175 S
.Diag(D
->getBeginLoc(), diag::err_attribute_wrong_decl_type
)
6176 << AL
.getRange() << AL
<< ExpectedVariable
;
6179 static void handleObjCPreciseLifetimeAttr(Sema
&S
, Decl
*D
,
6180 const ParsedAttr
&AL
) {
6181 const auto *VD
= cast
<ValueDecl
>(D
);
6182 QualType QT
= VD
->getType();
6184 if (!QT
->isDependentType() &&
6185 !QT
->isObjCLifetimeType()) {
6186 S
.Diag(AL
.getLoc(), diag::err_objc_precise_lifetime_bad_type
)
6191 Qualifiers::ObjCLifetime Lifetime
= QT
.getObjCLifetime();
6193 // If we have no lifetime yet, check the lifetime we're presumably
6195 if (Lifetime
== Qualifiers::OCL_None
&& !QT
->isDependentType())
6196 Lifetime
= QT
->getObjCARCImplicitLifetime();
6199 case Qualifiers::OCL_None
:
6200 assert(QT
->isDependentType() &&
6201 "didn't infer lifetime for non-dependent type?");
6204 case Qualifiers::OCL_Weak
: // meaningful
6205 case Qualifiers::OCL_Strong
: // meaningful
6208 case Qualifiers::OCL_ExplicitNone
:
6209 case Qualifiers::OCL_Autoreleasing
:
6210 S
.Diag(AL
.getLoc(), diag::warn_objc_precise_lifetime_meaningless
)
6211 << (Lifetime
== Qualifiers::OCL_Autoreleasing
);
6215 D
->addAttr(::new (S
.Context
) ObjCPreciseLifetimeAttr(S
.Context
, AL
));
6218 static void handleSwiftAttrAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
6219 // Make sure that there is a string literal as the annotation's single
6222 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Str
))
6225 D
->addAttr(::new (S
.Context
) SwiftAttrAttr(S
.Context
, AL
, Str
));
6228 static void handleSwiftBridge(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
6229 // Make sure that there is a string literal as the annotation's single
6232 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, BT
))
6235 // Warn about duplicate attributes if they have different arguments, but drop
6236 // any duplicate attributes regardless.
6237 if (const auto *Other
= D
->getAttr
<SwiftBridgeAttr
>()) {
6238 if (Other
->getSwiftType() != BT
)
6239 S
.Diag(AL
.getLoc(), diag::warn_duplicate_attribute
) << AL
;
6243 D
->addAttr(::new (S
.Context
) SwiftBridgeAttr(S
.Context
, AL
, BT
));
6246 static bool isErrorParameter(Sema
&S
, QualType QT
) {
6247 const auto *PT
= QT
->getAs
<PointerType
>();
6251 QualType Pointee
= PT
->getPointeeType();
6253 // Check for NSError**.
6254 if (const auto *OPT
= Pointee
->getAs
<ObjCObjectPointerType
>())
6255 if (const auto *ID
= OPT
->getInterfaceDecl())
6256 if (ID
->getIdentifier() == S
.getNSErrorIdent())
6259 // Check for CFError**.
6260 if (const auto *PT
= Pointee
->getAs
<PointerType
>())
6261 if (const auto *RT
= PT
->getPointeeType()->getAs
<RecordType
>())
6262 if (S
.isCFError(RT
->getDecl()))
6268 static void handleSwiftError(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
6269 auto hasErrorParameter
= [](Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) -> bool {
6270 for (unsigned I
= 0, E
= getFunctionOrMethodNumParams(D
); I
!= E
; ++I
) {
6271 if (isErrorParameter(S
, getFunctionOrMethodParamType(D
, I
)))
6275 S
.Diag(AL
.getLoc(), diag::err_attr_swift_error_no_error_parameter
)
6276 << AL
<< isa
<ObjCMethodDecl
>(D
);
6280 auto hasPointerResult
= [](Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) -> bool {
6281 // - C, ObjC, and block pointers are definitely okay.
6282 // - References are definitely not okay.
6283 // - nullptr_t is weird, but acceptable.
6284 QualType RT
= getFunctionOrMethodResultType(D
);
6285 if (RT
->hasPointerRepresentation() && !RT
->isReferenceType())
6288 S
.Diag(AL
.getLoc(), diag::err_attr_swift_error_return_type
)
6289 << AL
<< AL
.getArgAsIdent(0)->Ident
->getName() << isa
<ObjCMethodDecl
>(D
)
6294 auto hasIntegerResult
= [](Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) -> bool {
6295 QualType RT
= getFunctionOrMethodResultType(D
);
6296 if (RT
->isIntegralType(S
.Context
))
6299 S
.Diag(AL
.getLoc(), diag::err_attr_swift_error_return_type
)
6300 << AL
<< AL
.getArgAsIdent(0)->Ident
->getName() << isa
<ObjCMethodDecl
>(D
)
6305 if (D
->isInvalidDecl())
6308 IdentifierLoc
*Loc
= AL
.getArgAsIdent(0);
6309 SwiftErrorAttr::ConventionKind Convention
;
6310 if (!SwiftErrorAttr::ConvertStrToConventionKind(Loc
->Ident
->getName(),
6312 S
.Diag(AL
.getLoc(), diag::warn_attribute_type_not_supported
)
6313 << AL
<< Loc
->Ident
;
6317 switch (Convention
) {
6318 case SwiftErrorAttr::None
:
6319 // No additional validation required.
6322 case SwiftErrorAttr::NonNullError
:
6323 if (!hasErrorParameter(S
, D
, AL
))
6327 case SwiftErrorAttr::NullResult
:
6328 if (!hasErrorParameter(S
, D
, AL
) || !hasPointerResult(S
, D
, AL
))
6332 case SwiftErrorAttr::NonZeroResult
:
6333 case SwiftErrorAttr::ZeroResult
:
6334 if (!hasErrorParameter(S
, D
, AL
) || !hasIntegerResult(S
, D
, AL
))
6339 D
->addAttr(::new (S
.Context
) SwiftErrorAttr(S
.Context
, AL
, Convention
));
6342 static void checkSwiftAsyncErrorBlock(Sema
&S
, Decl
*D
,
6343 const SwiftAsyncErrorAttr
*ErrorAttr
,
6344 const SwiftAsyncAttr
*AsyncAttr
) {
6345 if (AsyncAttr
->getKind() == SwiftAsyncAttr::None
) {
6346 if (ErrorAttr
->getConvention() != SwiftAsyncErrorAttr::None
) {
6347 S
.Diag(AsyncAttr
->getLocation(),
6348 diag::err_swift_async_error_without_swift_async
)
6349 << AsyncAttr
<< isa
<ObjCMethodDecl
>(D
);
6354 const ParmVarDecl
*HandlerParam
= getFunctionOrMethodParam(
6355 D
, AsyncAttr
->getCompletionHandlerIndex().getASTIndex());
6356 // handleSwiftAsyncAttr already verified the type is correct, so no need to
6357 // double-check it here.
6358 const auto *FuncTy
= HandlerParam
->getType()
6359 ->castAs
<BlockPointerType
>()
6361 ->getAs
<FunctionProtoType
>();
6362 ArrayRef
<QualType
> BlockParams
;
6364 BlockParams
= FuncTy
->getParamTypes();
6366 switch (ErrorAttr
->getConvention()) {
6367 case SwiftAsyncErrorAttr::ZeroArgument
:
6368 case SwiftAsyncErrorAttr::NonZeroArgument
: {
6369 uint32_t ParamIdx
= ErrorAttr
->getHandlerParamIdx();
6370 if (ParamIdx
== 0 || ParamIdx
> BlockParams
.size()) {
6371 S
.Diag(ErrorAttr
->getLocation(),
6372 diag::err_attribute_argument_out_of_bounds
) << ErrorAttr
<< 2;
6375 QualType ErrorParam
= BlockParams
[ParamIdx
- 1];
6376 if (!ErrorParam
->isIntegralType(S
.Context
)) {
6378 ErrorAttr
->getConvention() == SwiftAsyncErrorAttr::ZeroArgument
6380 : "nonzero_argument";
6381 S
.Diag(ErrorAttr
->getLocation(), diag::err_swift_async_error_non_integral
)
6382 << ErrorAttr
<< ConvStr
<< ParamIdx
<< ErrorParam
;
6387 case SwiftAsyncErrorAttr::NonNullError
: {
6388 bool AnyErrorParams
= false;
6389 for (QualType Param
: BlockParams
) {
6390 // Check for NSError *.
6391 if (const auto *ObjCPtrTy
= Param
->getAs
<ObjCObjectPointerType
>()) {
6392 if (const auto *ID
= ObjCPtrTy
->getInterfaceDecl()) {
6393 if (ID
->getIdentifier() == S
.getNSErrorIdent()) {
6394 AnyErrorParams
= true;
6399 // Check for CFError *.
6400 if (const auto *PtrTy
= Param
->getAs
<PointerType
>()) {
6401 if (const auto *RT
= PtrTy
->getPointeeType()->getAs
<RecordType
>()) {
6402 if (S
.isCFError(RT
->getDecl())) {
6403 AnyErrorParams
= true;
6410 if (!AnyErrorParams
) {
6411 S
.Diag(ErrorAttr
->getLocation(),
6412 diag::err_swift_async_error_no_error_parameter
)
6413 << ErrorAttr
<< isa
<ObjCMethodDecl
>(D
);
6418 case SwiftAsyncErrorAttr::None
:
6423 static void handleSwiftAsyncError(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
6424 IdentifierLoc
*IDLoc
= AL
.getArgAsIdent(0);
6425 SwiftAsyncErrorAttr::ConventionKind ConvKind
;
6426 if (!SwiftAsyncErrorAttr::ConvertStrToConventionKind(IDLoc
->Ident
->getName(),
6428 S
.Diag(AL
.getLoc(), diag::warn_attribute_type_not_supported
)
6429 << AL
<< IDLoc
->Ident
;
6433 uint32_t ParamIdx
= 0;
6435 case SwiftAsyncErrorAttr::ZeroArgument
:
6436 case SwiftAsyncErrorAttr::NonZeroArgument
: {
6437 if (!AL
.checkExactlyNumArgs(S
, 2))
6440 Expr
*IdxExpr
= AL
.getArgAsExpr(1);
6441 if (!checkUInt32Argument(S
, AL
, IdxExpr
, ParamIdx
))
6445 case SwiftAsyncErrorAttr::NonNullError
:
6446 case SwiftAsyncErrorAttr::None
: {
6447 if (!AL
.checkExactlyNumArgs(S
, 1))
6454 ::new (S
.Context
) SwiftAsyncErrorAttr(S
.Context
, AL
, ConvKind
, ParamIdx
);
6455 D
->addAttr(ErrorAttr
);
6457 if (auto *AsyncAttr
= D
->getAttr
<SwiftAsyncAttr
>())
6458 checkSwiftAsyncErrorBlock(S
, D
, ErrorAttr
, AsyncAttr
);
6461 // For a function, this will validate a compound Swift name, e.g.
6462 // <code>init(foo:bar:baz:)</code> or <code>controllerForName(_:)</code>, and
6463 // the function will output the number of parameter names, and whether this is a
6464 // single-arg initializer.
6466 // For a type, enum constant, property, or variable declaration, this will
6467 // validate either a simple identifier, or a qualified
6468 // <code>context.identifier</code> name.
6470 validateSwiftFunctionName(Sema
&S
, const ParsedAttr
&AL
, SourceLocation Loc
,
6471 StringRef Name
, unsigned &SwiftParamCount
,
6472 bool &IsSingleParamInit
) {
6473 SwiftParamCount
= 0;
6474 IsSingleParamInit
= false;
6476 // Check whether this will be mapped to a getter or setter of a property.
6477 bool IsGetter
= false, IsSetter
= false;
6478 if (Name
.startswith("getter:")) {
6480 Name
= Name
.substr(7);
6481 } else if (Name
.startswith("setter:")) {
6483 Name
= Name
.substr(7);
6486 if (Name
.back() != ')') {
6487 S
.Diag(Loc
, diag::warn_attr_swift_name_function
) << AL
;
6491 bool IsMember
= false;
6492 StringRef ContextName
, BaseName
, Parameters
;
6494 std::tie(BaseName
, Parameters
) = Name
.split('(');
6496 // Split at the first '.', if it exists, which separates the context name
6497 // from the base name.
6498 std::tie(ContextName
, BaseName
) = BaseName
.split('.');
6499 if (BaseName
.empty()) {
6500 BaseName
= ContextName
;
6501 ContextName
= StringRef();
6502 } else if (ContextName
.empty() || !isValidAsciiIdentifier(ContextName
)) {
6503 S
.Diag(Loc
, diag::warn_attr_swift_name_invalid_identifier
)
6504 << AL
<< /*context*/ 1;
6510 if (!isValidAsciiIdentifier(BaseName
) || BaseName
== "_") {
6511 S
.Diag(Loc
, diag::warn_attr_swift_name_invalid_identifier
)
6512 << AL
<< /*basename*/ 0;
6516 bool IsSubscript
= BaseName
== "subscript";
6517 // A subscript accessor must be a getter or setter.
6518 if (IsSubscript
&& !IsGetter
&& !IsSetter
) {
6519 S
.Diag(Loc
, diag::warn_attr_swift_name_subscript_invalid_parameter
)
6520 << AL
<< /* getter or setter */ 0;
6524 if (Parameters
.empty()) {
6525 S
.Diag(Loc
, diag::warn_attr_swift_name_missing_parameters
) << AL
;
6529 assert(Parameters
.back() == ')' && "expected ')'");
6530 Parameters
= Parameters
.drop_back(); // ')'
6532 if (Parameters
.empty()) {
6533 // Setters and subscripts must have at least one parameter.
6535 S
.Diag(Loc
, diag::warn_attr_swift_name_subscript_invalid_parameter
)
6536 << AL
<< /* have at least one parameter */1;
6541 S
.Diag(Loc
, diag::warn_attr_swift_name_setter_parameters
) << AL
;
6548 if (Parameters
.back() != ':') {
6549 S
.Diag(Loc
, diag::warn_attr_swift_name_function
) << AL
;
6553 StringRef CurrentParam
;
6554 std::optional
<unsigned> SelfLocation
;
6555 unsigned NewValueCount
= 0;
6556 std::optional
<unsigned> NewValueLocation
;
6558 std::tie(CurrentParam
, Parameters
) = Parameters
.split(':');
6560 if (!isValidAsciiIdentifier(CurrentParam
)) {
6561 S
.Diag(Loc
, diag::warn_attr_swift_name_invalid_identifier
)
6562 << AL
<< /*parameter*/2;
6566 if (IsMember
&& CurrentParam
== "self") {
6567 // "self" indicates the "self" argument for a member.
6569 // More than one "self"?
6571 S
.Diag(Loc
, diag::warn_attr_swift_name_multiple_selfs
) << AL
;
6575 // The "self" location is the current parameter.
6576 SelfLocation
= SwiftParamCount
;
6577 } else if (CurrentParam
== "newValue") {
6578 // "newValue" indicates the "newValue" argument for a setter.
6580 // There should only be one 'newValue', but it's only significant for
6581 // subscript accessors, so don't error right away.
6584 NewValueLocation
= SwiftParamCount
;
6588 } while (!Parameters
.empty());
6590 // Only instance subscripts are currently supported.
6591 if (IsSubscript
&& !SelfLocation
) {
6592 S
.Diag(Loc
, diag::warn_attr_swift_name_subscript_invalid_parameter
)
6593 << AL
<< /*have a 'self:' parameter*/2;
6598 SwiftParamCount
== 1 && BaseName
== "init" && CurrentParam
!= "_";
6600 // Check the number of parameters for a getter/setter.
6601 if (IsGetter
|| IsSetter
) {
6602 // Setters have one parameter for the new value.
6603 unsigned NumExpectedParams
= IsGetter
? 0 : 1;
6604 unsigned ParamDiag
=
6605 IsGetter
? diag::warn_attr_swift_name_getter_parameters
6606 : diag::warn_attr_swift_name_setter_parameters
;
6608 // Instance methods have one parameter for "self".
6610 ++NumExpectedParams
;
6612 // Subscripts may have additional parameters beyond the expected params for
6615 if (SwiftParamCount
< NumExpectedParams
) {
6616 S
.Diag(Loc
, ParamDiag
) << AL
;
6620 // A subscript setter must explicitly label its newValue parameter to
6621 // distinguish it from index parameters.
6623 if (!NewValueLocation
) {
6624 S
.Diag(Loc
, diag::warn_attr_swift_name_subscript_setter_no_newValue
)
6628 if (NewValueCount
> 1) {
6629 S
.Diag(Loc
, diag::warn_attr_swift_name_subscript_setter_multiple_newValues
)
6634 // Subscript getters should have no 'newValue:' parameter.
6635 if (NewValueLocation
) {
6636 S
.Diag(Loc
, diag::warn_attr_swift_name_subscript_getter_newValue
)
6642 // Property accessors must have exactly the number of expected params.
6643 if (SwiftParamCount
!= NumExpectedParams
) {
6644 S
.Diag(Loc
, ParamDiag
) << AL
;
6653 bool Sema::DiagnoseSwiftName(Decl
*D
, StringRef Name
, SourceLocation Loc
,
6654 const ParsedAttr
&AL
, bool IsAsync
) {
6655 if (isa
<ObjCMethodDecl
>(D
) || isa
<FunctionDecl
>(D
)) {
6656 ArrayRef
<ParmVarDecl
*> Params
;
6657 unsigned ParamCount
;
6659 if (const auto *Method
= dyn_cast
<ObjCMethodDecl
>(D
)) {
6660 ParamCount
= Method
->getSelector().getNumArgs();
6661 Params
= Method
->parameters().slice(0, ParamCount
);
6663 const auto *F
= cast
<FunctionDecl
>(D
);
6665 ParamCount
= F
->getNumParams();
6666 Params
= F
->parameters();
6668 if (!F
->hasWrittenPrototype()) {
6669 Diag(Loc
, diag::warn_attribute_wrong_decl_type
) << AL
6670 << ExpectedFunctionWithProtoType
;
6675 // The async name drops the last callback parameter.
6677 if (ParamCount
== 0) {
6678 Diag(Loc
, diag::warn_attr_swift_name_decl_missing_params
)
6679 << AL
<< isa
<ObjCMethodDecl
>(D
);
6685 unsigned SwiftParamCount
;
6686 bool IsSingleParamInit
;
6687 if (!validateSwiftFunctionName(*this, AL
, Loc
, Name
,
6688 SwiftParamCount
, IsSingleParamInit
))
6691 bool ParamCountValid
;
6692 if (SwiftParamCount
== ParamCount
) {
6693 ParamCountValid
= true;
6694 } else if (SwiftParamCount
> ParamCount
) {
6695 ParamCountValid
= IsSingleParamInit
&& ParamCount
== 0;
6697 // We have fewer Swift parameters than Objective-C parameters, but that
6698 // might be because we've transformed some of them. Check for potential
6699 // "out" parameters and err on the side of not warning.
6700 unsigned MaybeOutParamCount
=
6701 llvm::count_if(Params
, [](const ParmVarDecl
*Param
) -> bool {
6702 QualType ParamTy
= Param
->getType();
6703 if (ParamTy
->isReferenceType() || ParamTy
->isPointerType())
6704 return !ParamTy
->getPointeeType().isConstQualified();
6708 ParamCountValid
= SwiftParamCount
+ MaybeOutParamCount
>= ParamCount
;
6711 if (!ParamCountValid
) {
6712 Diag(Loc
, diag::warn_attr_swift_name_num_params
)
6713 << (SwiftParamCount
> ParamCount
) << AL
<< ParamCount
6717 } else if ((isa
<EnumConstantDecl
>(D
) || isa
<ObjCProtocolDecl
>(D
) ||
6718 isa
<ObjCInterfaceDecl
>(D
) || isa
<ObjCPropertyDecl
>(D
) ||
6719 isa
<VarDecl
>(D
) || isa
<TypedefNameDecl
>(D
) || isa
<TagDecl
>(D
) ||
6720 isa
<IndirectFieldDecl
>(D
) || isa
<FieldDecl
>(D
)) &&
6722 StringRef ContextName
, BaseName
;
6724 std::tie(ContextName
, BaseName
) = Name
.split('.');
6725 if (BaseName
.empty()) {
6726 BaseName
= ContextName
;
6727 ContextName
= StringRef();
6728 } else if (!isValidAsciiIdentifier(ContextName
)) {
6729 Diag(Loc
, diag::warn_attr_swift_name_invalid_identifier
) << AL
6734 if (!isValidAsciiIdentifier(BaseName
)) {
6735 Diag(Loc
, diag::warn_attr_swift_name_invalid_identifier
) << AL
6740 Diag(Loc
, diag::warn_attr_swift_name_decl_kind
) << AL
;
6746 static void handleSwiftName(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
6749 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Name
, &Loc
))
6752 if (!S
.DiagnoseSwiftName(D
, Name
, Loc
, AL
, /*IsAsync=*/false))
6755 D
->addAttr(::new (S
.Context
) SwiftNameAttr(S
.Context
, AL
, Name
));
6758 static void handleSwiftAsyncName(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
6761 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Name
, &Loc
))
6764 if (!S
.DiagnoseSwiftName(D
, Name
, Loc
, AL
, /*IsAsync=*/true))
6767 D
->addAttr(::new (S
.Context
) SwiftAsyncNameAttr(S
.Context
, AL
, Name
));
6770 static void handleSwiftNewType(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
6771 // Make sure that there is an identifier as the annotation's single argument.
6772 if (!AL
.checkExactlyNumArgs(S
, 1))
6775 if (!AL
.isArgIdent(0)) {
6776 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_type
)
6777 << AL
<< AANT_ArgumentIdentifier
;
6781 SwiftNewTypeAttr::NewtypeKind Kind
;
6782 IdentifierInfo
*II
= AL
.getArgAsIdent(0)->Ident
;
6783 if (!SwiftNewTypeAttr::ConvertStrToNewtypeKind(II
->getName(), Kind
)) {
6784 S
.Diag(AL
.getLoc(), diag::warn_attribute_type_not_supported
) << AL
<< II
;
6788 if (!isa
<TypedefNameDecl
>(D
)) {
6789 S
.Diag(AL
.getLoc(), diag::warn_attribute_wrong_decl_type_str
)
6790 << AL
<< "typedefs";
6794 D
->addAttr(::new (S
.Context
) SwiftNewTypeAttr(S
.Context
, AL
, Kind
));
6797 static void handleSwiftAsyncAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
6798 if (!AL
.isArgIdent(0)) {
6799 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_n_type
)
6800 << AL
<< 1 << AANT_ArgumentIdentifier
;
6804 SwiftAsyncAttr::Kind Kind
;
6805 IdentifierInfo
*II
= AL
.getArgAsIdent(0)->Ident
;
6806 if (!SwiftAsyncAttr::ConvertStrToKind(II
->getName(), Kind
)) {
6807 S
.Diag(AL
.getLoc(), diag::err_swift_async_no_access
) << AL
<< II
;
6812 if (Kind
== SwiftAsyncAttr::None
) {
6813 // If this is 'none', then there shouldn't be any additional arguments.
6814 if (!AL
.checkExactlyNumArgs(S
, 1))
6817 // Non-none swift_async requires a completion handler index argument.
6818 if (!AL
.checkExactlyNumArgs(S
, 2))
6821 Expr
*HandlerIdx
= AL
.getArgAsExpr(1);
6822 if (!checkFunctionOrMethodParameterIndex(S
, D
, AL
, 2, HandlerIdx
, Idx
))
6825 const ParmVarDecl
*CompletionBlock
=
6826 getFunctionOrMethodParam(D
, Idx
.getASTIndex());
6827 QualType CompletionBlockType
= CompletionBlock
->getType();
6828 if (!CompletionBlockType
->isBlockPointerType()) {
6829 S
.Diag(CompletionBlock
->getLocation(),
6830 diag::err_swift_async_bad_block_type
)
6831 << CompletionBlock
->getType();
6835 CompletionBlockType
->castAs
<BlockPointerType
>()->getPointeeType();
6836 if (!BlockTy
->castAs
<FunctionType
>()->getReturnType()->isVoidType()) {
6837 S
.Diag(CompletionBlock
->getLocation(),
6838 diag::err_swift_async_bad_block_type
)
6839 << CompletionBlock
->getType();
6845 ::new (S
.Context
) SwiftAsyncAttr(S
.Context
, AL
, Kind
, Idx
);
6846 D
->addAttr(AsyncAttr
);
6848 if (auto *ErrorAttr
= D
->getAttr
<SwiftAsyncErrorAttr
>())
6849 checkSwiftAsyncErrorBlock(S
, D
, ErrorAttr
, AsyncAttr
);
6852 //===----------------------------------------------------------------------===//
6853 // Microsoft specific attribute handlers.
6854 //===----------------------------------------------------------------------===//
6856 UuidAttr
*Sema::mergeUuidAttr(Decl
*D
, const AttributeCommonInfo
&CI
,
6857 StringRef UuidAsWritten
, MSGuidDecl
*GuidDecl
) {
6858 if (const auto *UA
= D
->getAttr
<UuidAttr
>()) {
6859 if (declaresSameEntity(UA
->getGuidDecl(), GuidDecl
))
6861 if (!UA
->getGuid().empty()) {
6862 Diag(UA
->getLocation(), diag::err_mismatched_uuid
);
6863 Diag(CI
.getLoc(), diag::note_previous_uuid
);
6864 D
->dropAttr
<UuidAttr
>();
6868 return ::new (Context
) UuidAttr(Context
, CI
, UuidAsWritten
, GuidDecl
);
6871 static void handleUuidAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
6872 if (!S
.LangOpts
.CPlusPlus
) {
6873 S
.Diag(AL
.getLoc(), diag::err_attribute_not_supported_in_lang
)
6874 << AL
<< AttributeLangSupport::C
;
6878 StringRef OrigStrRef
;
6879 SourceLocation LiteralLoc
;
6880 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, OrigStrRef
, &LiteralLoc
))
6883 // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
6884 // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", normalize to the former.
6885 StringRef StrRef
= OrigStrRef
;
6886 if (StrRef
.size() == 38 && StrRef
.front() == '{' && StrRef
.back() == '}')
6887 StrRef
= StrRef
.drop_front().drop_back();
6889 // Validate GUID length.
6890 if (StrRef
.size() != 36) {
6891 S
.Diag(LiteralLoc
, diag::err_attribute_uuid_malformed_guid
);
6895 for (unsigned i
= 0; i
< 36; ++i
) {
6896 if (i
== 8 || i
== 13 || i
== 18 || i
== 23) {
6897 if (StrRef
[i
] != '-') {
6898 S
.Diag(LiteralLoc
, diag::err_attribute_uuid_malformed_guid
);
6901 } else if (!isHexDigit(StrRef
[i
])) {
6902 S
.Diag(LiteralLoc
, diag::err_attribute_uuid_malformed_guid
);
6907 // Convert to our parsed format and canonicalize.
6908 MSGuidDecl::Parts Parsed
;
6909 StrRef
.substr(0, 8).getAsInteger(16, Parsed
.Part1
);
6910 StrRef
.substr(9, 4).getAsInteger(16, Parsed
.Part2
);
6911 StrRef
.substr(14, 4).getAsInteger(16, Parsed
.Part3
);
6912 for (unsigned i
= 0; i
!= 8; ++i
)
6913 StrRef
.substr(19 + 2 * i
+ (i
>= 2 ? 1 : 0), 2)
6914 .getAsInteger(16, Parsed
.Part4And5
[i
]);
6915 MSGuidDecl
*Guid
= S
.Context
.getMSGuidDecl(Parsed
);
6917 // FIXME: It'd be nice to also emit a fixit removing uuid(...) (and, if it's
6918 // the only thing in the [] list, the [] too), and add an insertion of
6919 // __declspec(uuid(...)). But sadly, neither the SourceLocs of the commas
6920 // separating attributes nor of the [ and the ] are in the AST.
6921 // Cf "SourceLocations of attribute list delimiters - [[ ... , ... ]] etc"
6923 if (AL
.isMicrosoftAttribute()) // Check for [uuid(...)] spelling.
6924 S
.Diag(AL
.getLoc(), diag::warn_atl_uuid_deprecated
);
6926 UuidAttr
*UA
= S
.mergeUuidAttr(D
, AL
, OrigStrRef
, Guid
);
6931 static void handleHLSLNumThreadsAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
6933 Triple Target
= S
.Context
.getTargetInfo().getTriple();
6934 auto Env
= S
.Context
.getTargetInfo().getTriple().getEnvironment();
6935 if (!llvm::is_contained({Triple::Compute
, Triple::Mesh
, Triple::Amplification
,
6939 static_cast<uint32_t>(hlsl::getStageFromEnvironment(Env
));
6940 S
.Diag(AL
.getLoc(), diag::err_hlsl_attr_unsupported_in_stage
)
6941 << AL
<< Pipeline
<< "Compute, Amplification, Mesh or Library";
6945 llvm::VersionTuple SMVersion
= Target
.getOSVersion();
6946 uint32_t ZMax
= 1024;
6947 uint32_t ThreadMax
= 1024;
6948 if (SMVersion
.getMajor() <= 4) {
6951 } else if (SMVersion
.getMajor() == 5) {
6957 if (!checkUInt32Argument(S
, AL
, AL
.getArgAsExpr(0), X
))
6960 S
.Diag(AL
.getArgAsExpr(0)->getExprLoc(),
6961 diag::err_hlsl_numthreads_argument_oor
) << 0 << 1024;
6965 if (!checkUInt32Argument(S
, AL
, AL
.getArgAsExpr(1), Y
))
6968 S
.Diag(AL
.getArgAsExpr(1)->getExprLoc(),
6969 diag::err_hlsl_numthreads_argument_oor
) << 1 << 1024;
6973 if (!checkUInt32Argument(S
, AL
, AL
.getArgAsExpr(2), Z
))
6976 S
.Diag(AL
.getArgAsExpr(2)->getExprLoc(),
6977 diag::err_hlsl_numthreads_argument_oor
) << 2 << ZMax
;
6981 if (X
* Y
* Z
> ThreadMax
) {
6982 S
.Diag(AL
.getLoc(), diag::err_hlsl_numthreads_invalid
) << ThreadMax
;
6986 HLSLNumThreadsAttr
*NewAttr
= S
.mergeHLSLNumThreadsAttr(D
, AL
, X
, Y
, Z
);
6988 D
->addAttr(NewAttr
);
6991 HLSLNumThreadsAttr
*Sema::mergeHLSLNumThreadsAttr(Decl
*D
,
6992 const AttributeCommonInfo
&AL
,
6993 int X
, int Y
, int Z
) {
6994 if (HLSLNumThreadsAttr
*NT
= D
->getAttr
<HLSLNumThreadsAttr
>()) {
6995 if (NT
->getX() != X
|| NT
->getY() != Y
|| NT
->getZ() != Z
) {
6996 Diag(NT
->getLocation(), diag::err_hlsl_attribute_param_mismatch
) << AL
;
6997 Diag(AL
.getLoc(), diag::note_conflicting_attribute
);
7001 return ::new (Context
) HLSLNumThreadsAttr(Context
, AL
, X
, Y
, Z
);
7004 static void handleHLSLSVGroupIndexAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7006 auto Env
= S
.Context
.getTargetInfo().getTriple().getEnvironment();
7007 if (Env
!= Triple::Compute
&& Env
!= Triple::Library
) {
7008 // FIXME: it is OK for a compute shader entry and pixel shader entry live in
7009 // same HLSL file. Issue https://github.com/llvm/llvm-project/issues/57880.
7010 ShaderStage Pipeline
= hlsl::getStageFromEnvironment(Env
);
7011 S
.Diag(AL
.getLoc(), diag::err_hlsl_attr_unsupported_in_stage
)
7012 << AL
<< (uint32_t)Pipeline
<< "Compute";
7016 D
->addAttr(::new (S
.Context
) HLSLSV_GroupIndexAttr(S
.Context
, AL
));
7019 static bool isLegalTypeForHLSLSV_DispatchThreadID(QualType T
) {
7020 if (!T
->hasUnsignedIntegerRepresentation())
7022 if (const auto *VT
= T
->getAs
<VectorType
>())
7023 return VT
->getNumElements() <= 3;
7027 static void handleHLSLSV_DispatchThreadIDAttr(Sema
&S
, Decl
*D
,
7028 const ParsedAttr
&AL
) {
7030 Triple Target
= S
.Context
.getTargetInfo().getTriple();
7031 // FIXME: it is OK for a compute shader entry and pixel shader entry live in
7032 // same HLSL file.Issue https://github.com/llvm/llvm-project/issues/57880.
7033 if (Target
.getEnvironment() != Triple::Compute
&&
7034 Target
.getEnvironment() != Triple::Library
) {
7036 (uint32_t)S
.Context
.getTargetInfo().getTriple().getEnvironment() -
7037 (uint32_t)llvm::Triple::Pixel
;
7038 S
.Diag(AL
.getLoc(), diag::err_hlsl_attr_unsupported_in_stage
)
7039 << AL
<< Pipeline
<< "Compute";
7043 // FIXME: report warning and ignore semantic when cannot apply on the Decl.
7044 // See https://github.com/llvm/llvm-project/issues/57916.
7046 // FIXME: support semantic on field.
7047 // See https://github.com/llvm/llvm-project/issues/57889.
7048 if (isa
<FieldDecl
>(D
)) {
7049 S
.Diag(AL
.getLoc(), diag::err_hlsl_attr_invalid_ast_node
)
7050 << AL
<< "parameter";
7054 auto *VD
= cast
<ValueDecl
>(D
);
7055 if (!isLegalTypeForHLSLSV_DispatchThreadID(VD
->getType())) {
7056 S
.Diag(AL
.getLoc(), diag::err_hlsl_attr_invalid_type
)
7057 << AL
<< "uint/uint2/uint3";
7061 D
->addAttr(::new (S
.Context
) HLSLSV_DispatchThreadIDAttr(S
.Context
, AL
));
7064 static void handleHLSLShaderAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7066 SourceLocation ArgLoc
;
7067 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Str
, &ArgLoc
))
7070 HLSLShaderAttr::ShaderType ShaderType
;
7071 if (!HLSLShaderAttr::ConvertStrToShaderType(Str
, ShaderType
) ||
7072 // Library is added to help convert HLSLShaderAttr::ShaderType to
7073 // llvm::Triple::EnviromentType. It is not a legal
7074 // HLSLShaderAttr::ShaderType.
7075 ShaderType
== HLSLShaderAttr::Library
) {
7076 S
.Diag(AL
.getLoc(), diag::warn_attribute_type_not_supported
)
7077 << AL
<< Str
<< ArgLoc
;
7081 // FIXME: check function match the shader stage.
7083 HLSLShaderAttr
*NewAttr
= S
.mergeHLSLShaderAttr(D
, AL
, ShaderType
);
7085 D
->addAttr(NewAttr
);
7089 Sema::mergeHLSLShaderAttr(Decl
*D
, const AttributeCommonInfo
&AL
,
7090 HLSLShaderAttr::ShaderType ShaderType
) {
7091 if (HLSLShaderAttr
*NT
= D
->getAttr
<HLSLShaderAttr
>()) {
7092 if (NT
->getType() != ShaderType
) {
7093 Diag(NT
->getLocation(), diag::err_hlsl_attribute_param_mismatch
) << AL
;
7094 Diag(AL
.getLoc(), diag::note_conflicting_attribute
);
7098 return HLSLShaderAttr::Create(Context
, ShaderType
, AL
);
7101 static void handleHLSLResourceBindingAttr(Sema
&S
, Decl
*D
,
7102 const ParsedAttr
&AL
) {
7103 StringRef Space
= "space0";
7104 StringRef Slot
= "";
7106 if (!AL
.isArgIdent(0)) {
7107 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_type
)
7108 << AL
<< AANT_ArgumentIdentifier
;
7112 IdentifierLoc
*Loc
= AL
.getArgAsIdent(0);
7113 StringRef Str
= Loc
->Ident
->getName();
7114 SourceLocation ArgLoc
= Loc
->Loc
;
7116 SourceLocation SpaceArgLoc
;
7117 if (AL
.getNumArgs() == 2) {
7119 if (!AL
.isArgIdent(1)) {
7120 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_type
)
7121 << AL
<< AANT_ArgumentIdentifier
;
7125 IdentifierLoc
*Loc
= AL
.getArgAsIdent(1);
7126 Space
= Loc
->Ident
->getName();
7127 SpaceArgLoc
= Loc
->Loc
;
7133 if (!Slot
.empty()) {
7141 S
.Diag(ArgLoc
, diag::err_hlsl_unsupported_register_type
)
7142 << Slot
.substr(0, 1);
7146 StringRef SlotNum
= Slot
.substr(1);
7148 if (SlotNum
.getAsInteger(10, Num
)) {
7149 S
.Diag(ArgLoc
, diag::err_hlsl_unsupported_register_number
);
7154 if (!Space
.startswith("space")) {
7155 S
.Diag(SpaceArgLoc
, diag::err_hlsl_expected_space
) << Space
;
7158 StringRef SpaceNum
= Space
.substr(5);
7160 if (SpaceNum
.getAsInteger(10, Num
)) {
7161 S
.Diag(SpaceArgLoc
, diag::err_hlsl_expected_space
) << Space
;
7165 // FIXME: check reg type match decl. Issue
7166 // https://github.com/llvm/llvm-project/issues/57886.
7167 HLSLResourceBindingAttr
*NewAttr
=
7168 HLSLResourceBindingAttr::Create(S
.getASTContext(), Slot
, Space
, AL
);
7170 D
->addAttr(NewAttr
);
7173 static void handleMSInheritanceAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7174 if (!S
.LangOpts
.CPlusPlus
) {
7175 S
.Diag(AL
.getLoc(), diag::err_attribute_not_supported_in_lang
)
7176 << AL
<< AttributeLangSupport::C
;
7179 MSInheritanceAttr
*IA
= S
.mergeMSInheritanceAttr(
7180 D
, AL
, /*BestCase=*/true, (MSInheritanceModel
)AL
.getSemanticSpelling());
7183 S
.Consumer
.AssignInheritanceModel(cast
<CXXRecordDecl
>(D
));
7187 static void handleDeclspecThreadAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7188 const auto *VD
= cast
<VarDecl
>(D
);
7189 if (!S
.Context
.getTargetInfo().isTLSSupported()) {
7190 S
.Diag(AL
.getLoc(), diag::err_thread_unsupported
);
7193 if (VD
->getTSCSpec() != TSCS_unspecified
) {
7194 S
.Diag(AL
.getLoc(), diag::err_declspec_thread_on_thread_variable
);
7197 if (VD
->hasLocalStorage()) {
7198 S
.Diag(AL
.getLoc(), diag::err_thread_non_global
) << "__declspec(thread)";
7201 D
->addAttr(::new (S
.Context
) ThreadAttr(S
.Context
, AL
));
7204 static void handleAbiTagAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7205 SmallVector
<StringRef
, 4> Tags
;
7206 for (unsigned I
= 0, E
= AL
.getNumArgs(); I
!= E
; ++I
) {
7208 if (!S
.checkStringLiteralArgumentAttr(AL
, I
, Tag
))
7210 Tags
.push_back(Tag
);
7213 if (const auto *NS
= dyn_cast
<NamespaceDecl
>(D
)) {
7214 if (!NS
->isInline()) {
7215 S
.Diag(AL
.getLoc(), diag::warn_attr_abi_tag_namespace
) << 0;
7218 if (NS
->isAnonymousNamespace()) {
7219 S
.Diag(AL
.getLoc(), diag::warn_attr_abi_tag_namespace
) << 1;
7222 if (AL
.getNumArgs() == 0)
7223 Tags
.push_back(NS
->getName());
7224 } else if (!AL
.checkAtLeastNumArgs(S
, 1))
7227 // Store tags sorted and without duplicates.
7229 Tags
.erase(std::unique(Tags
.begin(), Tags
.end()), Tags
.end());
7231 D
->addAttr(::new (S
.Context
)
7232 AbiTagAttr(S
.Context
, AL
, Tags
.data(), Tags
.size()));
7235 static void handleARMInterruptAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7236 // Check the attribute arguments.
7237 if (AL
.getNumArgs() > 1) {
7238 S
.Diag(AL
.getLoc(), diag::err_attribute_too_many_arguments
) << AL
<< 1;
7243 SourceLocation ArgLoc
;
7245 if (AL
.getNumArgs() == 0)
7247 else if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Str
, &ArgLoc
))
7250 ARMInterruptAttr::InterruptType Kind
;
7251 if (!ARMInterruptAttr::ConvertStrToInterruptType(Str
, Kind
)) {
7252 S
.Diag(AL
.getLoc(), diag::warn_attribute_type_not_supported
) << AL
<< Str
7257 D
->addAttr(::new (S
.Context
) ARMInterruptAttr(S
.Context
, AL
, Kind
));
7260 static void handleMSP430InterruptAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7261 // MSP430 'interrupt' attribute is applied to
7262 // a function with no parameters and void return type.
7263 if (!isFunctionOrMethod(D
)) {
7264 S
.Diag(D
->getLocation(), diag::warn_attribute_wrong_decl_type
)
7265 << "'interrupt'" << ExpectedFunctionOrMethod
;
7269 if (hasFunctionProto(D
) && getFunctionOrMethodNumParams(D
) != 0) {
7270 S
.Diag(D
->getLocation(), diag::warn_interrupt_attribute_invalid
)
7271 << /*MSP430*/ 1 << 0;
7275 if (!getFunctionOrMethodResultType(D
)->isVoidType()) {
7276 S
.Diag(D
->getLocation(), diag::warn_interrupt_attribute_invalid
)
7277 << /*MSP430*/ 1 << 1;
7281 // The attribute takes one integer argument.
7282 if (!AL
.checkExactlyNumArgs(S
, 1))
7285 if (!AL
.isArgExpr(0)) {
7286 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_type
)
7287 << AL
<< AANT_ArgumentIntegerConstant
;
7291 Expr
*NumParamsExpr
= static_cast<Expr
*>(AL
.getArgAsExpr(0));
7292 std::optional
<llvm::APSInt
> NumParams
= llvm::APSInt(32);
7293 if (!(NumParams
= NumParamsExpr
->getIntegerConstantExpr(S
.Context
))) {
7294 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_type
)
7295 << AL
<< AANT_ArgumentIntegerConstant
7296 << NumParamsExpr
->getSourceRange();
7299 // The argument should be in range 0..63.
7300 unsigned Num
= NumParams
->getLimitedValue(255);
7302 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_out_of_bounds
)
7303 << AL
<< (int)NumParams
->getSExtValue()
7304 << NumParamsExpr
->getSourceRange();
7308 D
->addAttr(::new (S
.Context
) MSP430InterruptAttr(S
.Context
, AL
, Num
));
7309 D
->addAttr(UsedAttr::CreateImplicit(S
.Context
));
7312 static void handleMipsInterruptAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7313 // Only one optional argument permitted.
7314 if (AL
.getNumArgs() > 1) {
7315 S
.Diag(AL
.getLoc(), diag::err_attribute_too_many_arguments
) << AL
<< 1;
7320 SourceLocation ArgLoc
;
7322 if (AL
.getNumArgs() == 0)
7324 else if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Str
, &ArgLoc
))
7327 // Semantic checks for a function with the 'interrupt' attribute for MIPS:
7328 // a) Must be a function.
7329 // b) Must have no parameters.
7330 // c) Must have the 'void' return type.
7331 // d) Cannot have the 'mips16' attribute, as that instruction set
7332 // lacks the 'eret' instruction.
7333 // e) The attribute itself must either have no argument or one of the
7334 // valid interrupt types, see [MipsInterruptDocs].
7336 if (!isFunctionOrMethod(D
)) {
7337 S
.Diag(D
->getLocation(), diag::warn_attribute_wrong_decl_type
)
7338 << "'interrupt'" << ExpectedFunctionOrMethod
;
7342 if (hasFunctionProto(D
) && getFunctionOrMethodNumParams(D
) != 0) {
7343 S
.Diag(D
->getLocation(), diag::warn_interrupt_attribute_invalid
)
7348 if (!getFunctionOrMethodResultType(D
)->isVoidType()) {
7349 S
.Diag(D
->getLocation(), diag::warn_interrupt_attribute_invalid
)
7354 // We still have to do this manually because the Interrupt attributes are
7355 // a bit special due to sharing their spellings across targets.
7356 if (checkAttrMutualExclusion
<Mips16Attr
>(S
, D
, AL
))
7359 MipsInterruptAttr::InterruptType Kind
;
7360 if (!MipsInterruptAttr::ConvertStrToInterruptType(Str
, Kind
)) {
7361 S
.Diag(AL
.getLoc(), diag::warn_attribute_type_not_supported
)
7362 << AL
<< "'" + std::string(Str
) + "'";
7366 D
->addAttr(::new (S
.Context
) MipsInterruptAttr(S
.Context
, AL
, Kind
));
7369 static void handleM68kInterruptAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7370 if (!AL
.checkExactlyNumArgs(S
, 1))
7373 if (!AL
.isArgExpr(0)) {
7374 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_type
)
7375 << AL
<< AANT_ArgumentIntegerConstant
;
7379 // FIXME: Check for decl - it should be void ()(void).
7381 Expr
*NumParamsExpr
= static_cast<Expr
*>(AL
.getArgAsExpr(0));
7382 auto MaybeNumParams
= NumParamsExpr
->getIntegerConstantExpr(S
.Context
);
7383 if (!MaybeNumParams
) {
7384 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_type
)
7385 << AL
<< AANT_ArgumentIntegerConstant
7386 << NumParamsExpr
->getSourceRange();
7390 unsigned Num
= MaybeNumParams
->getLimitedValue(255);
7391 if ((Num
& 1) || Num
> 30) {
7392 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_out_of_bounds
)
7393 << AL
<< (int)MaybeNumParams
->getSExtValue()
7394 << NumParamsExpr
->getSourceRange();
7398 D
->addAttr(::new (S
.Context
) M68kInterruptAttr(S
.Context
, AL
, Num
));
7399 D
->addAttr(UsedAttr::CreateImplicit(S
.Context
));
7402 static void handleAnyX86InterruptAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7403 // Semantic checks for a function with the 'interrupt' attribute.
7404 // a) Must be a function.
7405 // b) Must have the 'void' return type.
7406 // c) Must take 1 or 2 arguments.
7407 // d) The 1st argument must be a pointer.
7408 // e) The 2nd argument (if any) must be an unsigned integer.
7409 if (!isFunctionOrMethod(D
) || !hasFunctionProto(D
) || isInstanceMethod(D
) ||
7410 CXXMethodDecl::isStaticOverloadedOperator(
7411 cast
<NamedDecl
>(D
)->getDeclName().getCXXOverloadedOperator())) {
7412 S
.Diag(AL
.getLoc(), diag::warn_attribute_wrong_decl_type
)
7413 << AL
<< ExpectedFunctionWithProtoType
;
7416 // Interrupt handler must have void return type.
7417 if (!getFunctionOrMethodResultType(D
)->isVoidType()) {
7418 S
.Diag(getFunctionOrMethodResultSourceRange(D
).getBegin(),
7419 diag::err_anyx86_interrupt_attribute
)
7420 << (S
.Context
.getTargetInfo().getTriple().getArch() == llvm::Triple::x86
7426 // Interrupt handler must have 1 or 2 parameters.
7427 unsigned NumParams
= getFunctionOrMethodNumParams(D
);
7428 if (NumParams
< 1 || NumParams
> 2) {
7429 S
.Diag(D
->getBeginLoc(), diag::err_anyx86_interrupt_attribute
)
7430 << (S
.Context
.getTargetInfo().getTriple().getArch() == llvm::Triple::x86
7436 // The first argument must be a pointer.
7437 if (!getFunctionOrMethodParamType(D
, 0)->isPointerType()) {
7438 S
.Diag(getFunctionOrMethodParamRange(D
, 0).getBegin(),
7439 diag::err_anyx86_interrupt_attribute
)
7440 << (S
.Context
.getTargetInfo().getTriple().getArch() == llvm::Triple::x86
7446 // The second argument, if present, must be an unsigned integer.
7448 S
.Context
.getTargetInfo().getTriple().getArch() == llvm::Triple::x86_64
7451 if (NumParams
== 2 &&
7452 (!getFunctionOrMethodParamType(D
, 1)->isUnsignedIntegerType() ||
7453 S
.Context
.getTypeSize(getFunctionOrMethodParamType(D
, 1)) != TypeSize
)) {
7454 S
.Diag(getFunctionOrMethodParamRange(D
, 1).getBegin(),
7455 diag::err_anyx86_interrupt_attribute
)
7456 << (S
.Context
.getTargetInfo().getTriple().getArch() == llvm::Triple::x86
7459 << 3 << S
.Context
.getIntTypeForBitwidth(TypeSize
, /*Signed=*/false);
7462 D
->addAttr(::new (S
.Context
) AnyX86InterruptAttr(S
.Context
, AL
));
7463 D
->addAttr(UsedAttr::CreateImplicit(S
.Context
));
7466 static void handleAVRInterruptAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7467 if (!isFunctionOrMethod(D
)) {
7468 S
.Diag(D
->getLocation(), diag::warn_attribute_wrong_decl_type
)
7469 << "'interrupt'" << ExpectedFunction
;
7473 if (!AL
.checkExactlyNumArgs(S
, 0))
7476 handleSimpleAttribute
<AVRInterruptAttr
>(S
, D
, AL
);
7479 static void handleAVRSignalAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7480 if (!isFunctionOrMethod(D
)) {
7481 S
.Diag(D
->getLocation(), diag::warn_attribute_wrong_decl_type
)
7482 << "'signal'" << ExpectedFunction
;
7486 if (!AL
.checkExactlyNumArgs(S
, 0))
7489 handleSimpleAttribute
<AVRSignalAttr
>(S
, D
, AL
);
7492 static void handleBPFPreserveAIRecord(Sema
&S
, RecordDecl
*RD
) {
7493 // Add preserve_access_index attribute to all fields and inner records.
7494 for (auto *D
: RD
->decls()) {
7495 if (D
->hasAttr
<BPFPreserveAccessIndexAttr
>())
7498 D
->addAttr(BPFPreserveAccessIndexAttr::CreateImplicit(S
.Context
));
7499 if (auto *Rec
= dyn_cast
<RecordDecl
>(D
))
7500 handleBPFPreserveAIRecord(S
, Rec
);
7504 static void handleBPFPreserveAccessIndexAttr(Sema
&S
, Decl
*D
,
7505 const ParsedAttr
&AL
) {
7506 auto *Rec
= cast
<RecordDecl
>(D
);
7507 handleBPFPreserveAIRecord(S
, Rec
);
7508 Rec
->addAttr(::new (S
.Context
) BPFPreserveAccessIndexAttr(S
.Context
, AL
));
7511 static bool hasBTFDeclTagAttr(Decl
*D
, StringRef Tag
) {
7512 for (const auto *I
: D
->specific_attrs
<BTFDeclTagAttr
>()) {
7513 if (I
->getBTFDeclTag() == Tag
)
7519 static void handleBTFDeclTagAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7521 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Str
))
7523 if (hasBTFDeclTagAttr(D
, Str
))
7526 D
->addAttr(::new (S
.Context
) BTFDeclTagAttr(S
.Context
, AL
, Str
));
7529 BTFDeclTagAttr
*Sema::mergeBTFDeclTagAttr(Decl
*D
, const BTFDeclTagAttr
&AL
) {
7530 if (hasBTFDeclTagAttr(D
, AL
.getBTFDeclTag()))
7532 return ::new (Context
) BTFDeclTagAttr(Context
, AL
, AL
.getBTFDeclTag());
7535 static void handleWebAssemblyExportNameAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7536 if (!isFunctionOrMethod(D
)) {
7537 S
.Diag(D
->getLocation(), diag::warn_attribute_wrong_decl_type
)
7538 << "'export_name'" << ExpectedFunction
;
7542 auto *FD
= cast
<FunctionDecl
>(D
);
7543 if (FD
->isThisDeclarationADefinition()) {
7544 S
.Diag(D
->getLocation(), diag::err_alias_is_definition
) << FD
<< 0;
7549 SourceLocation ArgLoc
;
7550 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Str
, &ArgLoc
))
7553 D
->addAttr(::new (S
.Context
) WebAssemblyExportNameAttr(S
.Context
, AL
, Str
));
7554 D
->addAttr(UsedAttr::CreateImplicit(S
.Context
));
7557 WebAssemblyImportModuleAttr
*
7558 Sema::mergeImportModuleAttr(Decl
*D
, const WebAssemblyImportModuleAttr
&AL
) {
7559 auto *FD
= cast
<FunctionDecl
>(D
);
7561 if (const auto *ExistingAttr
= FD
->getAttr
<WebAssemblyImportModuleAttr
>()) {
7562 if (ExistingAttr
->getImportModule() == AL
.getImportModule())
7564 Diag(ExistingAttr
->getLocation(), diag::warn_mismatched_import
) << 0
7565 << ExistingAttr
->getImportModule() << AL
.getImportModule();
7566 Diag(AL
.getLoc(), diag::note_previous_attribute
);
7569 if (FD
->hasBody()) {
7570 Diag(AL
.getLoc(), diag::warn_import_on_definition
) << 0;
7573 return ::new (Context
) WebAssemblyImportModuleAttr(Context
, AL
,
7574 AL
.getImportModule());
7577 WebAssemblyImportNameAttr
*
7578 Sema::mergeImportNameAttr(Decl
*D
, const WebAssemblyImportNameAttr
&AL
) {
7579 auto *FD
= cast
<FunctionDecl
>(D
);
7581 if (const auto *ExistingAttr
= FD
->getAttr
<WebAssemblyImportNameAttr
>()) {
7582 if (ExistingAttr
->getImportName() == AL
.getImportName())
7584 Diag(ExistingAttr
->getLocation(), diag::warn_mismatched_import
) << 1
7585 << ExistingAttr
->getImportName() << AL
.getImportName();
7586 Diag(AL
.getLoc(), diag::note_previous_attribute
);
7589 if (FD
->hasBody()) {
7590 Diag(AL
.getLoc(), diag::warn_import_on_definition
) << 1;
7593 return ::new (Context
) WebAssemblyImportNameAttr(Context
, AL
,
7594 AL
.getImportName());
7598 handleWebAssemblyImportModuleAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7599 auto *FD
= cast
<FunctionDecl
>(D
);
7602 SourceLocation ArgLoc
;
7603 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Str
, &ArgLoc
))
7605 if (FD
->hasBody()) {
7606 S
.Diag(AL
.getLoc(), diag::warn_import_on_definition
) << 0;
7610 FD
->addAttr(::new (S
.Context
)
7611 WebAssemblyImportModuleAttr(S
.Context
, AL
, Str
));
7615 handleWebAssemblyImportNameAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7616 auto *FD
= cast
<FunctionDecl
>(D
);
7619 SourceLocation ArgLoc
;
7620 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Str
, &ArgLoc
))
7622 if (FD
->hasBody()) {
7623 S
.Diag(AL
.getLoc(), diag::warn_import_on_definition
) << 1;
7627 FD
->addAttr(::new (S
.Context
) WebAssemblyImportNameAttr(S
.Context
, AL
, Str
));
7630 static void handleRISCVInterruptAttr(Sema
&S
, Decl
*D
,
7631 const ParsedAttr
&AL
) {
7632 // Warn about repeated attributes.
7633 if (const auto *A
= D
->getAttr
<RISCVInterruptAttr
>()) {
7634 S
.Diag(AL
.getRange().getBegin(),
7635 diag::warn_riscv_repeated_interrupt_attribute
);
7636 S
.Diag(A
->getLocation(), diag::note_riscv_repeated_interrupt_attribute
);
7640 // Check the attribute argument. Argument is optional.
7641 if (!AL
.checkAtMostNumArgs(S
, 1))
7645 SourceLocation ArgLoc
;
7647 // 'machine'is the default interrupt mode.
7648 if (AL
.getNumArgs() == 0)
7650 else if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Str
, &ArgLoc
))
7653 // Semantic checks for a function with the 'interrupt' attribute:
7654 // - Must be a function.
7655 // - Must have no parameters.
7656 // - Must have the 'void' return type.
7657 // - The attribute itself must either have no argument or one of the
7658 // valid interrupt types, see [RISCVInterruptDocs].
7660 if (D
->getFunctionType() == nullptr) {
7661 S
.Diag(D
->getLocation(), diag::warn_attribute_wrong_decl_type
)
7662 << "'interrupt'" << ExpectedFunction
;
7666 if (hasFunctionProto(D
) && getFunctionOrMethodNumParams(D
) != 0) {
7667 S
.Diag(D
->getLocation(), diag::warn_interrupt_attribute_invalid
)
7668 << /*RISC-V*/ 2 << 0;
7672 if (!getFunctionOrMethodResultType(D
)->isVoidType()) {
7673 S
.Diag(D
->getLocation(), diag::warn_interrupt_attribute_invalid
)
7674 << /*RISC-V*/ 2 << 1;
7678 RISCVInterruptAttr::InterruptType Kind
;
7679 if (!RISCVInterruptAttr::ConvertStrToInterruptType(Str
, Kind
)) {
7680 S
.Diag(AL
.getLoc(), diag::warn_attribute_type_not_supported
) << AL
<< Str
7685 D
->addAttr(::new (S
.Context
) RISCVInterruptAttr(S
.Context
, AL
, Kind
));
7688 static void handleInterruptAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7689 // Dispatch the interrupt attribute based on the current target.
7690 switch (S
.Context
.getTargetInfo().getTriple().getArch()) {
7691 case llvm::Triple::msp430
:
7692 handleMSP430InterruptAttr(S
, D
, AL
);
7694 case llvm::Triple::mipsel
:
7695 case llvm::Triple::mips
:
7696 handleMipsInterruptAttr(S
, D
, AL
);
7698 case llvm::Triple::m68k
:
7699 handleM68kInterruptAttr(S
, D
, AL
);
7701 case llvm::Triple::x86
:
7702 case llvm::Triple::x86_64
:
7703 handleAnyX86InterruptAttr(S
, D
, AL
);
7705 case llvm::Triple::avr
:
7706 handleAVRInterruptAttr(S
, D
, AL
);
7708 case llvm::Triple::riscv32
:
7709 case llvm::Triple::riscv64
:
7710 handleRISCVInterruptAttr(S
, D
, AL
);
7713 handleARMInterruptAttr(S
, D
, AL
);
7719 checkAMDGPUFlatWorkGroupSizeArguments(Sema
&S
, Expr
*MinExpr
, Expr
*MaxExpr
,
7720 const AMDGPUFlatWorkGroupSizeAttr
&Attr
) {
7721 // Accept template arguments for now as they depend on something else.
7722 // We'll get to check them when they eventually get instantiated.
7723 if (MinExpr
->isValueDependent() || MaxExpr
->isValueDependent())
7727 if (!checkUInt32Argument(S
, Attr
, MinExpr
, Min
, 0))
7731 if (!checkUInt32Argument(S
, Attr
, MaxExpr
, Max
, 1))
7734 if (Min
== 0 && Max
!= 0) {
7735 S
.Diag(Attr
.getLocation(), diag::err_attribute_argument_invalid
)
7740 S
.Diag(Attr
.getLocation(), diag::err_attribute_argument_invalid
)
7748 void Sema::addAMDGPUFlatWorkGroupSizeAttr(Decl
*D
,
7749 const AttributeCommonInfo
&CI
,
7750 Expr
*MinExpr
, Expr
*MaxExpr
) {
7751 AMDGPUFlatWorkGroupSizeAttr
TmpAttr(Context
, CI
, MinExpr
, MaxExpr
);
7753 if (checkAMDGPUFlatWorkGroupSizeArguments(*this, MinExpr
, MaxExpr
, TmpAttr
))
7756 D
->addAttr(::new (Context
)
7757 AMDGPUFlatWorkGroupSizeAttr(Context
, CI
, MinExpr
, MaxExpr
));
7760 static void handleAMDGPUFlatWorkGroupSizeAttr(Sema
&S
, Decl
*D
,
7761 const ParsedAttr
&AL
) {
7762 Expr
*MinExpr
= AL
.getArgAsExpr(0);
7763 Expr
*MaxExpr
= AL
.getArgAsExpr(1);
7765 S
.addAMDGPUFlatWorkGroupSizeAttr(D
, AL
, MinExpr
, MaxExpr
);
7768 static bool checkAMDGPUWavesPerEUArguments(Sema
&S
, Expr
*MinExpr
,
7770 const AMDGPUWavesPerEUAttr
&Attr
) {
7771 if (S
.DiagnoseUnexpandedParameterPack(MinExpr
) ||
7772 (MaxExpr
&& S
.DiagnoseUnexpandedParameterPack(MaxExpr
)))
7775 // Accept template arguments for now as they depend on something else.
7776 // We'll get to check them when they eventually get instantiated.
7777 if (MinExpr
->isValueDependent() || (MaxExpr
&& MaxExpr
->isValueDependent()))
7781 if (!checkUInt32Argument(S
, Attr
, MinExpr
, Min
, 0))
7785 if (MaxExpr
&& !checkUInt32Argument(S
, Attr
, MaxExpr
, Max
, 1))
7788 if (Min
== 0 && Max
!= 0) {
7789 S
.Diag(Attr
.getLocation(), diag::err_attribute_argument_invalid
)
7793 if (Max
!= 0 && Min
> Max
) {
7794 S
.Diag(Attr
.getLocation(), diag::err_attribute_argument_invalid
)
7802 void Sema::addAMDGPUWavesPerEUAttr(Decl
*D
, const AttributeCommonInfo
&CI
,
7803 Expr
*MinExpr
, Expr
*MaxExpr
) {
7804 AMDGPUWavesPerEUAttr
TmpAttr(Context
, CI
, MinExpr
, MaxExpr
);
7806 if (checkAMDGPUWavesPerEUArguments(*this, MinExpr
, MaxExpr
, TmpAttr
))
7809 D
->addAttr(::new (Context
)
7810 AMDGPUWavesPerEUAttr(Context
, CI
, MinExpr
, MaxExpr
));
7813 static void handleAMDGPUWavesPerEUAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7814 if (!AL
.checkAtLeastNumArgs(S
, 1) || !AL
.checkAtMostNumArgs(S
, 2))
7817 Expr
*MinExpr
= AL
.getArgAsExpr(0);
7818 Expr
*MaxExpr
= (AL
.getNumArgs() > 1) ? AL
.getArgAsExpr(1) : nullptr;
7820 S
.addAMDGPUWavesPerEUAttr(D
, AL
, MinExpr
, MaxExpr
);
7823 static void handleAMDGPUNumSGPRAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7824 uint32_t NumSGPR
= 0;
7825 Expr
*NumSGPRExpr
= AL
.getArgAsExpr(0);
7826 if (!checkUInt32Argument(S
, AL
, NumSGPRExpr
, NumSGPR
))
7829 D
->addAttr(::new (S
.Context
) AMDGPUNumSGPRAttr(S
.Context
, AL
, NumSGPR
));
7832 static void handleAMDGPUNumVGPRAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7833 uint32_t NumVGPR
= 0;
7834 Expr
*NumVGPRExpr
= AL
.getArgAsExpr(0);
7835 if (!checkUInt32Argument(S
, AL
, NumVGPRExpr
, NumVGPR
))
7838 D
->addAttr(::new (S
.Context
) AMDGPUNumVGPRAttr(S
.Context
, AL
, NumVGPR
));
7841 static void handleX86ForceAlignArgPointerAttr(Sema
&S
, Decl
*D
,
7842 const ParsedAttr
&AL
) {
7843 // If we try to apply it to a function pointer, don't warn, but don't
7844 // do anything, either. It doesn't matter anyway, because there's nothing
7845 // special about calling a force_align_arg_pointer function.
7846 const auto *VD
= dyn_cast
<ValueDecl
>(D
);
7847 if (VD
&& VD
->getType()->isFunctionPointerType())
7849 // Also don't warn on function pointer typedefs.
7850 const auto *TD
= dyn_cast
<TypedefNameDecl
>(D
);
7851 if (TD
&& (TD
->getUnderlyingType()->isFunctionPointerType() ||
7852 TD
->getUnderlyingType()->isFunctionType()))
7854 // Attribute can only be applied to function types.
7855 if (!isa
<FunctionDecl
>(D
)) {
7856 S
.Diag(AL
.getLoc(), diag::warn_attribute_wrong_decl_type
)
7857 << AL
<< ExpectedFunction
;
7861 D
->addAttr(::new (S
.Context
) X86ForceAlignArgPointerAttr(S
.Context
, AL
));
7864 static void handleLayoutVersion(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7866 Expr
*VersionExpr
= static_cast<Expr
*>(AL
.getArgAsExpr(0));
7867 if (!checkUInt32Argument(S
, AL
, AL
.getArgAsExpr(0), Version
))
7870 // TODO: Investigate what happens with the next major version of MSVC.
7871 if (Version
!= LangOptions::MSVC2015
/ 100) {
7872 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_out_of_bounds
)
7873 << AL
<< Version
<< VersionExpr
->getSourceRange();
7877 // The attribute expects a "major" version number like 19, but new versions of
7878 // MSVC have moved to updating the "minor", or less significant numbers, so we
7879 // have to multiply by 100 now.
7882 D
->addAttr(::new (S
.Context
) LayoutVersionAttr(S
.Context
, AL
, Version
));
7885 DLLImportAttr
*Sema::mergeDLLImportAttr(Decl
*D
,
7886 const AttributeCommonInfo
&CI
) {
7887 if (D
->hasAttr
<DLLExportAttr
>()) {
7888 Diag(CI
.getLoc(), diag::warn_attribute_ignored
) << "'dllimport'";
7892 if (D
->hasAttr
<DLLImportAttr
>())
7895 return ::new (Context
) DLLImportAttr(Context
, CI
);
7898 DLLExportAttr
*Sema::mergeDLLExportAttr(Decl
*D
,
7899 const AttributeCommonInfo
&CI
) {
7900 if (DLLImportAttr
*Import
= D
->getAttr
<DLLImportAttr
>()) {
7901 Diag(Import
->getLocation(), diag::warn_attribute_ignored
) << Import
;
7902 D
->dropAttr
<DLLImportAttr
>();
7905 if (D
->hasAttr
<DLLExportAttr
>())
7908 return ::new (Context
) DLLExportAttr(Context
, CI
);
7911 static void handleDLLAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&A
) {
7912 if (isa
<ClassTemplatePartialSpecializationDecl
>(D
) &&
7913 (S
.Context
.getTargetInfo().shouldDLLImportComdatSymbols())) {
7914 S
.Diag(A
.getRange().getBegin(), diag::warn_attribute_ignored
) << A
;
7918 if (const auto *FD
= dyn_cast
<FunctionDecl
>(D
)) {
7919 if (FD
->isInlined() && A
.getKind() == ParsedAttr::AT_DLLImport
&&
7920 !(S
.Context
.getTargetInfo().shouldDLLImportComdatSymbols())) {
7921 // MinGW doesn't allow dllimport on inline functions.
7922 S
.Diag(A
.getRange().getBegin(), diag::warn_attribute_ignored_on_inline
)
7928 if (const auto *MD
= dyn_cast
<CXXMethodDecl
>(D
)) {
7929 if ((S
.Context
.getTargetInfo().shouldDLLImportComdatSymbols()) &&
7930 MD
->getParent()->isLambda()) {
7931 S
.Diag(A
.getRange().getBegin(), diag::err_attribute_dll_lambda
) << A
;
7936 Attr
*NewAttr
= A
.getKind() == ParsedAttr::AT_DLLExport
7937 ? (Attr
*)S
.mergeDLLExportAttr(D
, A
)
7938 : (Attr
*)S
.mergeDLLImportAttr(D
, A
);
7940 D
->addAttr(NewAttr
);
7944 Sema::mergeMSInheritanceAttr(Decl
*D
, const AttributeCommonInfo
&CI
,
7946 MSInheritanceModel Model
) {
7947 if (MSInheritanceAttr
*IA
= D
->getAttr
<MSInheritanceAttr
>()) {
7948 if (IA
->getInheritanceModel() == Model
)
7950 Diag(IA
->getLocation(), diag::err_mismatched_ms_inheritance
)
7951 << 1 /*previous declaration*/;
7952 Diag(CI
.getLoc(), diag::note_previous_ms_inheritance
);
7953 D
->dropAttr
<MSInheritanceAttr
>();
7956 auto *RD
= cast
<CXXRecordDecl
>(D
);
7957 if (RD
->hasDefinition()) {
7958 if (checkMSInheritanceAttrOnDefinition(RD
, CI
.getRange(), BestCase
,
7963 if (isa
<ClassTemplatePartialSpecializationDecl
>(RD
)) {
7964 Diag(CI
.getLoc(), diag::warn_ignored_ms_inheritance
)
7965 << 1 /*partial specialization*/;
7968 if (RD
->getDescribedClassTemplate()) {
7969 Diag(CI
.getLoc(), diag::warn_ignored_ms_inheritance
)
7970 << 0 /*primary template*/;
7975 return ::new (Context
) MSInheritanceAttr(Context
, CI
, BestCase
);
7978 static void handleCapabilityAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7979 // The capability attributes take a single string parameter for the name of
7980 // the capability they represent. The lockable attribute does not take any
7981 // parameters. However, semantically, both attributes represent the same
7982 // concept, and so they use the same semantic attribute. Eventually, the
7983 // lockable attribute will be removed.
7985 // For backward compatibility, any capability which has no specified string
7986 // literal will be considered a "mutex."
7987 StringRef
N("mutex");
7988 SourceLocation LiteralLoc
;
7989 if (AL
.getKind() == ParsedAttr::AT_Capability
&&
7990 !S
.checkStringLiteralArgumentAttr(AL
, 0, N
, &LiteralLoc
))
7993 D
->addAttr(::new (S
.Context
) CapabilityAttr(S
.Context
, AL
, N
));
7996 static void handleAssertCapabilityAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
7997 SmallVector
<Expr
*, 1> Args
;
7998 if (!checkLockFunAttrCommon(S
, D
, AL
, Args
))
8001 D
->addAttr(::new (S
.Context
)
8002 AssertCapabilityAttr(S
.Context
, AL
, Args
.data(), Args
.size()));
8005 static void handleAcquireCapabilityAttr(Sema
&S
, Decl
*D
,
8006 const ParsedAttr
&AL
) {
8007 SmallVector
<Expr
*, 1> Args
;
8008 if (!checkLockFunAttrCommon(S
, D
, AL
, Args
))
8011 D
->addAttr(::new (S
.Context
) AcquireCapabilityAttr(S
.Context
, AL
, Args
.data(),
8015 static void handleTryAcquireCapabilityAttr(Sema
&S
, Decl
*D
,
8016 const ParsedAttr
&AL
) {
8017 SmallVector
<Expr
*, 2> Args
;
8018 if (!checkTryLockFunAttrCommon(S
, D
, AL
, Args
))
8021 D
->addAttr(::new (S
.Context
) TryAcquireCapabilityAttr(
8022 S
.Context
, AL
, AL
.getArgAsExpr(0), Args
.data(), Args
.size()));
8025 static void handleReleaseCapabilityAttr(Sema
&S
, Decl
*D
,
8026 const ParsedAttr
&AL
) {
8027 // Check that all arguments are lockable objects.
8028 SmallVector
<Expr
*, 1> Args
;
8029 checkAttrArgsAreCapabilityObjs(S
, D
, AL
, Args
, 0, true);
8031 D
->addAttr(::new (S
.Context
) ReleaseCapabilityAttr(S
.Context
, AL
, Args
.data(),
8035 static void handleRequiresCapabilityAttr(Sema
&S
, Decl
*D
,
8036 const ParsedAttr
&AL
) {
8037 if (!AL
.checkAtLeastNumArgs(S
, 1))
8040 // check that all arguments are lockable objects
8041 SmallVector
<Expr
*, 1> Args
;
8042 checkAttrArgsAreCapabilityObjs(S
, D
, AL
, Args
);
8046 RequiresCapabilityAttr
*RCA
= ::new (S
.Context
)
8047 RequiresCapabilityAttr(S
.Context
, AL
, Args
.data(), Args
.size());
8052 static void handleDeprecatedAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
8053 if (const auto *NSD
= dyn_cast
<NamespaceDecl
>(D
)) {
8054 if (NSD
->isAnonymousNamespace()) {
8055 S
.Diag(AL
.getLoc(), diag::warn_deprecated_anonymous_namespace
);
8056 // Do not want to attach the attribute to the namespace because that will
8057 // cause confusing diagnostic reports for uses of declarations within the
8061 } else if (isa
<UsingDecl
, UnresolvedUsingTypenameDecl
,
8062 UnresolvedUsingValueDecl
>(D
)) {
8063 S
.Diag(AL
.getRange().getBegin(), diag::warn_deprecated_ignored_on_using
)
8068 // Handle the cases where the attribute has a text message.
8069 StringRef Str
, Replacement
;
8070 if (AL
.isArgExpr(0) && AL
.getArgAsExpr(0) &&
8071 !S
.checkStringLiteralArgumentAttr(AL
, 0, Str
))
8074 // Support a single optional message only for Declspec and [[]] spellings.
8075 if (AL
.isDeclspecAttribute() || AL
.isStandardAttributeSyntax())
8076 AL
.checkAtMostNumArgs(S
, 1);
8077 else if (AL
.isArgExpr(1) && AL
.getArgAsExpr(1) &&
8078 !S
.checkStringLiteralArgumentAttr(AL
, 1, Replacement
))
8081 if (!S
.getLangOpts().CPlusPlus14
&& AL
.isCXX11Attribute() && !AL
.isGNUScope())
8082 S
.Diag(AL
.getLoc(), diag::ext_cxx14_attr
) << AL
;
8084 D
->addAttr(::new (S
.Context
) DeprecatedAttr(S
.Context
, AL
, Str
, Replacement
));
8087 static bool isGlobalVar(const Decl
*D
) {
8088 if (const auto *S
= dyn_cast
<VarDecl
>(D
))
8089 return S
->hasGlobalStorage();
8093 static bool isSanitizerAttributeAllowedOnGlobals(StringRef Sanitizer
) {
8094 return Sanitizer
== "address" || Sanitizer
== "hwaddress" ||
8095 Sanitizer
== "memtag";
8098 static void handleNoSanitizeAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
8099 if (!AL
.checkAtLeastNumArgs(S
, 1))
8102 std::vector
<StringRef
> Sanitizers
;
8104 for (unsigned I
= 0, E
= AL
.getNumArgs(); I
!= E
; ++I
) {
8105 StringRef SanitizerName
;
8106 SourceLocation LiteralLoc
;
8108 if (!S
.checkStringLiteralArgumentAttr(AL
, I
, SanitizerName
, &LiteralLoc
))
8111 if (parseSanitizerValue(SanitizerName
, /*AllowGroups=*/true) ==
8113 SanitizerName
!= "coverage")
8114 S
.Diag(LiteralLoc
, diag::warn_unknown_sanitizer_ignored
) << SanitizerName
;
8115 else if (isGlobalVar(D
) && !isSanitizerAttributeAllowedOnGlobals(SanitizerName
))
8116 S
.Diag(D
->getLocation(), diag::warn_attribute_type_not_supported_global
)
8117 << AL
<< SanitizerName
;
8118 Sanitizers
.push_back(SanitizerName
);
8121 D
->addAttr(::new (S
.Context
) NoSanitizeAttr(S
.Context
, AL
, Sanitizers
.data(),
8122 Sanitizers
.size()));
8125 static void handleNoSanitizeSpecificAttr(Sema
&S
, Decl
*D
,
8126 const ParsedAttr
&AL
) {
8127 StringRef AttrName
= AL
.getAttrName()->getName();
8128 normalizeName(AttrName
);
8129 StringRef SanitizerName
= llvm::StringSwitch
<StringRef
>(AttrName
)
8130 .Case("no_address_safety_analysis", "address")
8131 .Case("no_sanitize_address", "address")
8132 .Case("no_sanitize_thread", "thread")
8133 .Case("no_sanitize_memory", "memory");
8134 if (isGlobalVar(D
) && SanitizerName
!= "address")
8135 S
.Diag(D
->getLocation(), diag::err_attribute_wrong_decl_type
)
8136 << AL
<< ExpectedFunction
;
8138 // FIXME: Rather than create a NoSanitizeSpecificAttr, this creates a
8139 // NoSanitizeAttr object; but we need to calculate the correct spelling list
8140 // index rather than incorrectly assume the index for NoSanitizeSpecificAttr
8141 // has the same spellings as the index for NoSanitizeAttr. We don't have a
8142 // general way to "translate" between the two, so this hack attempts to work
8143 // around the issue with hard-coded indices. This is critical for calling
8144 // getSpelling() or prettyPrint() on the resulting semantic attribute object
8145 // without failing assertions.
8146 unsigned TranslatedSpellingIndex
= 0;
8147 if (AL
.isStandardAttributeSyntax())
8148 TranslatedSpellingIndex
= 1;
8150 AttributeCommonInfo Info
= AL
;
8151 Info
.setAttributeSpellingListIndex(TranslatedSpellingIndex
);
8152 D
->addAttr(::new (S
.Context
)
8153 NoSanitizeAttr(S
.Context
, Info
, &SanitizerName
, 1));
8156 static void handleInternalLinkageAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
8157 if (InternalLinkageAttr
*Internal
= S
.mergeInternalLinkageAttr(D
, AL
))
8158 D
->addAttr(Internal
);
8161 static void handleOpenCLNoSVMAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
8162 if (S
.LangOpts
.getOpenCLCompatibleVersion() < 200)
8163 S
.Diag(AL
.getLoc(), diag::err_attribute_requires_opencl_version
)
8164 << AL
<< "2.0" << 1;
8166 S
.Diag(AL
.getLoc(), diag::warn_opencl_attr_deprecated_ignored
)
8167 << AL
<< S
.LangOpts
.getOpenCLVersionString();
8170 static void handleOpenCLAccessAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
8171 if (D
->isInvalidDecl())
8174 // Check if there is only one access qualifier.
8175 if (D
->hasAttr
<OpenCLAccessAttr
>()) {
8176 if (D
->getAttr
<OpenCLAccessAttr
>()->getSemanticSpelling() ==
8177 AL
.getSemanticSpelling()) {
8178 S
.Diag(AL
.getLoc(), diag::warn_duplicate_declspec
)
8179 << AL
.getAttrName()->getName() << AL
.getRange();
8181 S
.Diag(AL
.getLoc(), diag::err_opencl_multiple_access_qualifiers
)
8182 << D
->getSourceRange();
8183 D
->setInvalidDecl(true);
8188 // OpenCL v2.0 s6.6 - read_write can be used for image types to specify that
8189 // an image object can be read and written. OpenCL v2.0 s6.13.6 - A kernel
8190 // cannot read from and write to the same pipe object. Using the read_write
8191 // (or __read_write) qualifier with the pipe qualifier is a compilation error.
8192 // OpenCL v3.0 s6.8 - For OpenCL C 2.0, or with the
8193 // __opencl_c_read_write_images feature, image objects specified as arguments
8194 // to a kernel can additionally be declared to be read-write.
8195 // C++ for OpenCL 1.0 inherits rule from OpenCL C v2.0.
8196 // C++ for OpenCL 2021 inherits rule from OpenCL C v3.0.
8197 if (const auto *PDecl
= dyn_cast
<ParmVarDecl
>(D
)) {
8198 const Type
*DeclTy
= PDecl
->getType().getCanonicalType().getTypePtr();
8199 if (AL
.getAttrName()->getName().contains("read_write")) {
8200 bool ReadWriteImagesUnsupported
=
8201 (S
.getLangOpts().getOpenCLCompatibleVersion() < 200) ||
8202 (S
.getLangOpts().getOpenCLCompatibleVersion() == 300 &&
8203 !S
.getOpenCLOptions().isSupported("__opencl_c_read_write_images",
8205 if (ReadWriteImagesUnsupported
|| DeclTy
->isPipeType()) {
8206 S
.Diag(AL
.getLoc(), diag::err_opencl_invalid_read_write
)
8207 << AL
<< PDecl
->getType() << DeclTy
->isImageType();
8208 D
->setInvalidDecl(true);
8214 D
->addAttr(::new (S
.Context
) OpenCLAccessAttr(S
.Context
, AL
));
8217 static void handleZeroCallUsedRegsAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
8218 // Check that the argument is a string literal.
8220 SourceLocation LiteralLoc
;
8221 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, KindStr
, &LiteralLoc
))
8224 ZeroCallUsedRegsAttr::ZeroCallUsedRegsKind Kind
;
8225 if (!ZeroCallUsedRegsAttr::ConvertStrToZeroCallUsedRegsKind(KindStr
, Kind
)) {
8226 S
.Diag(LiteralLoc
, diag::warn_attribute_type_not_supported
)
8231 D
->dropAttr
<ZeroCallUsedRegsAttr
>();
8232 D
->addAttr(ZeroCallUsedRegsAttr::Create(S
.Context
, Kind
, AL
));
8235 static void handleFunctionReturnThunksAttr(Sema
&S
, Decl
*D
,
8236 const ParsedAttr
&AL
) {
8238 SourceLocation LiteralLoc
;
8239 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, KindStr
, &LiteralLoc
))
8242 FunctionReturnThunksAttr::Kind Kind
;
8243 if (!FunctionReturnThunksAttr::ConvertStrToKind(KindStr
, Kind
)) {
8244 S
.Diag(LiteralLoc
, diag::warn_attribute_type_not_supported
)
8248 // FIXME: it would be good to better handle attribute merging rather than
8249 // silently replacing the existing attribute, so long as it does not break
8250 // the expected codegen tests.
8251 D
->dropAttr
<FunctionReturnThunksAttr
>();
8252 D
->addAttr(FunctionReturnThunksAttr::Create(S
.Context
, Kind
, AL
));
8255 static void handleSYCLKernelAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
8256 // The 'sycl_kernel' attribute applies only to function templates.
8257 const auto *FD
= cast
<FunctionDecl
>(D
);
8258 const FunctionTemplateDecl
*FT
= FD
->getDescribedFunctionTemplate();
8259 assert(FT
&& "Function template is expected");
8261 // Function template must have at least two template parameters.
8262 const TemplateParameterList
*TL
= FT
->getTemplateParameters();
8263 if (TL
->size() < 2) {
8264 S
.Diag(FT
->getLocation(), diag::warn_sycl_kernel_num_of_template_params
);
8268 // Template parameters must be typenames.
8269 for (unsigned I
= 0; I
< 2; ++I
) {
8270 const NamedDecl
*TParam
= TL
->getParam(I
);
8271 if (isa
<NonTypeTemplateParmDecl
>(TParam
)) {
8272 S
.Diag(FT
->getLocation(),
8273 diag::warn_sycl_kernel_invalid_template_param_type
);
8278 // Function must have at least one argument.
8279 if (getFunctionOrMethodNumParams(D
) != 1) {
8280 S
.Diag(FT
->getLocation(), diag::warn_sycl_kernel_num_of_function_params
);
8284 // Function must return void.
8285 QualType RetTy
= getFunctionOrMethodResultType(D
);
8286 if (!RetTy
->isVoidType()) {
8287 S
.Diag(FT
->getLocation(), diag::warn_sycl_kernel_return_type
);
8291 handleSimpleAttribute
<SYCLKernelAttr
>(S
, D
, AL
);
8294 static void handleDestroyAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&A
) {
8295 if (!cast
<VarDecl
>(D
)->hasGlobalStorage()) {
8296 S
.Diag(D
->getLocation(), diag::err_destroy_attr_on_non_static_var
)
8297 << (A
.getKind() == ParsedAttr::AT_AlwaysDestroy
);
8301 if (A
.getKind() == ParsedAttr::AT_AlwaysDestroy
)
8302 handleSimpleAttribute
<AlwaysDestroyAttr
>(S
, D
, A
);
8304 handleSimpleAttribute
<NoDestroyAttr
>(S
, D
, A
);
8307 static void handleUninitializedAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
8308 assert(cast
<VarDecl
>(D
)->getStorageDuration() == SD_Automatic
&&
8309 "uninitialized is only valid on automatic duration variables");
8310 D
->addAttr(::new (S
.Context
) UninitializedAttr(S
.Context
, AL
));
8313 static bool tryMakeVariablePseudoStrong(Sema
&S
, VarDecl
*VD
,
8314 bool DiagnoseFailure
) {
8315 QualType Ty
= VD
->getType();
8316 if (!Ty
->isObjCRetainableType()) {
8317 if (DiagnoseFailure
) {
8318 S
.Diag(VD
->getBeginLoc(), diag::warn_ignored_objc_externally_retained
)
8324 Qualifiers::ObjCLifetime LifetimeQual
= Ty
.getQualifiers().getObjCLifetime();
8326 // Sema::inferObjCARCLifetime must run after processing decl attributes
8327 // (because __block lowers to an attribute), so if the lifetime hasn't been
8328 // explicitly specified, infer it locally now.
8329 if (LifetimeQual
== Qualifiers::OCL_None
)
8330 LifetimeQual
= Ty
->getObjCARCImplicitLifetime();
8332 // The attributes only really makes sense for __strong variables; ignore any
8333 // attempts to annotate a parameter with any other lifetime qualifier.
8334 if (LifetimeQual
!= Qualifiers::OCL_Strong
) {
8335 if (DiagnoseFailure
) {
8336 S
.Diag(VD
->getBeginLoc(), diag::warn_ignored_objc_externally_retained
)
8342 // Tampering with the type of a VarDecl here is a bit of a hack, but we need
8343 // to ensure that the variable is 'const' so that we can error on
8344 // modification, which can otherwise over-release.
8345 VD
->setType(Ty
.withConst());
8346 VD
->setARCPseudoStrong(true);
8350 static void handleObjCExternallyRetainedAttr(Sema
&S
, Decl
*D
,
8351 const ParsedAttr
&AL
) {
8352 if (auto *VD
= dyn_cast
<VarDecl
>(D
)) {
8353 assert(!isa
<ParmVarDecl
>(VD
) && "should be diagnosed automatically");
8354 if (!VD
->hasLocalStorage()) {
8355 S
.Diag(D
->getBeginLoc(), diag::warn_ignored_objc_externally_retained
)
8360 if (!tryMakeVariablePseudoStrong(S
, VD
, /*DiagnoseFailure=*/true))
8363 handleSimpleAttribute
<ObjCExternallyRetainedAttr
>(S
, D
, AL
);
8367 // If D is a function-like declaration (method, block, or function), then we
8368 // make every parameter psuedo-strong.
8369 unsigned NumParams
=
8370 hasFunctionProto(D
) ? getFunctionOrMethodNumParams(D
) : 0;
8371 for (unsigned I
= 0; I
!= NumParams
; ++I
) {
8372 auto *PVD
= const_cast<ParmVarDecl
*>(getFunctionOrMethodParam(D
, I
));
8373 QualType Ty
= PVD
->getType();
8375 // If a user wrote a parameter with __strong explicitly, then assume they
8376 // want "real" strong semantics for that parameter. This works because if
8377 // the parameter was written with __strong, then the strong qualifier will
8379 if (Ty
.getLocalUnqualifiedType().getQualifiers().getObjCLifetime() ==
8380 Qualifiers::OCL_Strong
)
8383 tryMakeVariablePseudoStrong(S
, PVD
, /*DiagnoseFailure=*/false);
8385 handleSimpleAttribute
<ObjCExternallyRetainedAttr
>(S
, D
, AL
);
8388 static void handleMIGServerRoutineAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
8389 // Check that the return type is a `typedef int kern_return_t` or a typedef
8390 // around it, because otherwise MIG convention checks make no sense.
8391 // BlockDecl doesn't store a return type, so it's annoying to check,
8392 // so let's skip it for now.
8393 if (!isa
<BlockDecl
>(D
)) {
8394 QualType T
= getFunctionOrMethodResultType(D
);
8395 bool IsKernReturnT
= false;
8396 while (const auto *TT
= T
->getAs
<TypedefType
>()) {
8397 IsKernReturnT
= (TT
->getDecl()->getName() == "kern_return_t");
8400 if (!IsKernReturnT
|| T
.getCanonicalType() != S
.getASTContext().IntTy
) {
8401 S
.Diag(D
->getBeginLoc(),
8402 diag::warn_mig_server_routine_does_not_return_kern_return_t
);
8407 handleSimpleAttribute
<MIGServerRoutineAttr
>(S
, D
, AL
);
8410 static void handleMSAllocatorAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
8411 // Warn if the return type is not a pointer or reference type.
8412 if (auto *FD
= dyn_cast
<FunctionDecl
>(D
)) {
8413 QualType RetTy
= FD
->getReturnType();
8414 if (!RetTy
->isPointerType() && !RetTy
->isReferenceType()) {
8415 S
.Diag(AL
.getLoc(), diag::warn_declspec_allocator_nonpointer
)
8416 << AL
.getRange() << RetTy
;
8421 handleSimpleAttribute
<MSAllocatorAttr
>(S
, D
, AL
);
8424 static void handleAcquireHandleAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
8425 if (AL
.isUsedAsTypeAttr())
8427 // Warn if the parameter is definitely not an output parameter.
8428 if (const auto *PVD
= dyn_cast
<ParmVarDecl
>(D
)) {
8429 if (PVD
->getType()->isIntegerType()) {
8430 S
.Diag(AL
.getLoc(), diag::err_attribute_output_parameter
)
8436 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Argument
))
8438 D
->addAttr(AcquireHandleAttr::Create(S
.Context
, Argument
, AL
));
8441 template<typename Attr
>
8442 static void handleHandleAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
8444 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Argument
))
8446 D
->addAttr(Attr::Create(S
.Context
, Argument
, AL
));
8449 template<typename Attr
>
8450 static void handleUnsafeBufferUsage(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
8451 D
->addAttr(Attr::Create(S
.Context
, AL
));
8454 static void handleCFGuardAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
8455 // The guard attribute takes a single identifier argument.
8457 if (!AL
.isArgIdent(0)) {
8458 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_type
)
8459 << AL
<< AANT_ArgumentIdentifier
;
8463 CFGuardAttr::GuardArg Arg
;
8464 IdentifierInfo
*II
= AL
.getArgAsIdent(0)->Ident
;
8465 if (!CFGuardAttr::ConvertStrToGuardArg(II
->getName(), Arg
)) {
8466 S
.Diag(AL
.getLoc(), diag::warn_attribute_type_not_supported
) << AL
<< II
;
8470 D
->addAttr(::new (S
.Context
) CFGuardAttr(S
.Context
, AL
, Arg
));
8474 template <typename AttrTy
>
8475 static const AttrTy
*findEnforceTCBAttrByName(Decl
*D
, StringRef Name
) {
8476 auto Attrs
= D
->specific_attrs
<AttrTy
>();
8477 auto I
= llvm::find_if(Attrs
,
8478 [Name
](const AttrTy
*A
) {
8479 return A
->getTCBName() == Name
;
8481 return I
== Attrs
.end() ? nullptr : *I
;
8484 template <typename AttrTy
, typename ConflictingAttrTy
>
8485 static void handleEnforceTCBAttr(Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) {
8487 if (!S
.checkStringLiteralArgumentAttr(AL
, 0, Argument
))
8490 // A function cannot be have both regular and leaf membership in the same TCB.
8491 if (const ConflictingAttrTy
*ConflictingAttr
=
8492 findEnforceTCBAttrByName
<ConflictingAttrTy
>(D
, Argument
)) {
8493 // We could attach a note to the other attribute but in this case
8494 // there's no need given how the two are very close to each other.
8495 S
.Diag(AL
.getLoc(), diag::err_tcb_conflicting_attributes
)
8496 << AL
.getAttrName()->getName() << ConflictingAttr
->getAttrName()->getName()
8499 // Error recovery: drop the non-leaf attribute so that to suppress
8500 // all future warnings caused by erroneous attributes. The leaf attribute
8501 // needs to be kept because it can only suppresses warnings, not cause them.
8502 D
->dropAttr
<EnforceTCBAttr
>();
8506 D
->addAttr(AttrTy::Create(S
.Context
, Argument
, AL
));
8509 template <typename AttrTy
, typename ConflictingAttrTy
>
8510 static AttrTy
*mergeEnforceTCBAttrImpl(Sema
&S
, Decl
*D
, const AttrTy
&AL
) {
8511 // Check if the new redeclaration has different leaf-ness in the same TCB.
8512 StringRef TCBName
= AL
.getTCBName();
8513 if (const ConflictingAttrTy
*ConflictingAttr
=
8514 findEnforceTCBAttrByName
<ConflictingAttrTy
>(D
, TCBName
)) {
8515 S
.Diag(ConflictingAttr
->getLoc(), diag::err_tcb_conflicting_attributes
)
8516 << ConflictingAttr
->getAttrName()->getName()
8517 << AL
.getAttrName()->getName() << TCBName
;
8519 // Add a note so that the user could easily find the conflicting attribute.
8520 S
.Diag(AL
.getLoc(), diag::note_conflicting_attribute
);
8522 // More error recovery.
8523 D
->dropAttr
<EnforceTCBAttr
>();
8527 ASTContext
&Context
= S
.getASTContext();
8528 return ::new(Context
) AttrTy(Context
, AL
, AL
.getTCBName());
8531 EnforceTCBAttr
*Sema::mergeEnforceTCBAttr(Decl
*D
, const EnforceTCBAttr
&AL
) {
8532 return mergeEnforceTCBAttrImpl
<EnforceTCBAttr
, EnforceTCBLeafAttr
>(
8536 EnforceTCBLeafAttr
*Sema::mergeEnforceTCBLeafAttr(
8537 Decl
*D
, const EnforceTCBLeafAttr
&AL
) {
8538 return mergeEnforceTCBAttrImpl
<EnforceTCBLeafAttr
, EnforceTCBAttr
>(
8542 //===----------------------------------------------------------------------===//
8543 // Top Level Sema Entry Points
8544 //===----------------------------------------------------------------------===//
8546 // Returns true if the attribute must delay setting its arguments until after
8547 // template instantiation, and false otherwise.
8548 static bool MustDelayAttributeArguments(const ParsedAttr
&AL
) {
8549 // Only attributes that accept expression parameter packs can delay arguments.
8550 if (!AL
.acceptsExprPack())
8553 bool AttrHasVariadicArg
= AL
.hasVariadicArg();
8554 unsigned AttrNumArgs
= AL
.getNumArgMembers();
8555 for (size_t I
= 0; I
< std::min(AL
.getNumArgs(), AttrNumArgs
); ++I
) {
8556 bool IsLastAttrArg
= I
== (AttrNumArgs
- 1);
8557 // If the argument is the last argument and it is variadic it can contain
8559 if (IsLastAttrArg
&& AttrHasVariadicArg
)
8561 Expr
*E
= AL
.getArgAsExpr(I
);
8562 bool ArgMemberCanHoldExpr
= AL
.isParamExpr(I
);
8563 // If the expression is a pack expansion then arguments must be delayed
8564 // unless the argument is an expression and it is the last argument of the
8566 if (isa
<PackExpansionExpr
>(E
))
8567 return !(IsLastAttrArg
&& ArgMemberCanHoldExpr
);
8568 // Last case is if the expression is value dependent then it must delay
8569 // arguments unless the corresponding argument is able to hold the
8571 if (E
->isValueDependent() && !ArgMemberCanHoldExpr
)
8577 /// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
8578 /// the attribute applies to decls. If the attribute is a type attribute, just
8579 /// silently ignore it if a GNU attribute.
8581 ProcessDeclAttribute(Sema
&S
, Scope
*scope
, Decl
*D
, const ParsedAttr
&AL
,
8582 const Sema::ProcessDeclAttributeOptions
&Options
) {
8583 if (AL
.isInvalid() || AL
.getKind() == ParsedAttr::IgnoredAttribute
)
8586 // Ignore C++11 attributes on declarator chunks: they appertain to the type
8588 // FIXME: We currently check the attribute syntax directly instead of using
8589 // isCXX11Attribute(), which currently erroneously classifies the C11
8590 // `_Alignas` attribute as a C++11 attribute. `_Alignas` can appear on the
8591 // `DeclSpec`, so we need to let it through here to make sure it is processed
8592 // appropriately. Once the behavior of isCXX11Attribute() is fixed, we can
8593 // go back to using that here.
8594 if (AL
.getSyntax() == ParsedAttr::AS_CXX11
&& !Options
.IncludeCXX11Attributes
)
8597 // Unknown attributes are automatically warned on. Target-specific attributes
8598 // which do not apply to the current target architecture are treated as
8599 // though they were unknown attributes.
8600 if (AL
.getKind() == ParsedAttr::UnknownAttribute
||
8601 !AL
.existsInTarget(S
.Context
.getTargetInfo())) {
8603 AL
.isDeclspecAttribute()
8604 ? (unsigned)diag::warn_unhandled_ms_attribute_ignored
8605 : (unsigned)diag::warn_unknown_attribute_ignored
)
8606 << AL
<< AL
.getRange();
8610 // Check if argument population must delayed to after template instantiation.
8611 bool MustDelayArgs
= MustDelayAttributeArguments(AL
);
8613 // Argument number check must be skipped if arguments are delayed.
8614 if (S
.checkCommonAttributeFeatures(D
, AL
, MustDelayArgs
))
8617 if (MustDelayArgs
) {
8618 AL
.handleAttrWithDelayedArgs(S
, D
);
8622 switch (AL
.getKind()) {
8624 if (AL
.getInfo().handleDeclAttribute(S
, D
, AL
) != ParsedAttrInfo::NotHandled
)
8626 if (!AL
.isStmtAttr()) {
8627 assert(AL
.isTypeAttr() && "Non-type attribute not handled");
8629 if (AL
.isTypeAttr()) {
8630 if (Options
.IgnoreTypeAttributes
)
8632 if (!AL
.isStandardAttributeSyntax()) {
8633 // Non-[[]] type attributes are handled in processTypeAttrs(); silently
8638 // According to the C and C++ standards, we should never see a
8639 // [[]] type attribute on a declaration. However, we have in the past
8640 // allowed some type attributes to "slide" to the `DeclSpec`, so we need
8641 // to continue to support this legacy behavior. We only do this, however,
8643 // - we actually have a `DeclSpec`, i.e. if we're looking at a
8644 // `DeclaratorDecl`, or
8645 // - we are looking at an alias-declaration, where historically we have
8646 // allowed type attributes after the identifier to slide to the type.
8647 if (AL
.slidesFromDeclToDeclSpecLegacyBehavior() &&
8648 isa
<DeclaratorDecl
, TypeAliasDecl
>(D
)) {
8649 // Suggest moving the attribute to the type instead, but only for our
8650 // own vendor attributes; moving other vendors' attributes might hurt
8652 if (AL
.isClangScope()) {
8653 S
.Diag(AL
.getLoc(), diag::warn_type_attribute_deprecated_on_decl
)
8654 << AL
<< D
->getLocation();
8657 // Allow this type attribute to be handled in processTypeAttrs();
8658 // silently move on.
8662 if (AL
.getKind() == ParsedAttr::AT_Regparm
) {
8663 // `regparm` is a special case: It's a type attribute but we still want
8664 // to treat it as if it had been written on the declaration because that
8665 // way we'll be able to handle it directly in `processTypeAttr()`.
8666 // If we treated `regparm` it as if it had been written on the
8667 // `DeclSpec`, the logic in `distributeFunctionTypeAttrFromDeclSepc()`
8668 // would try to move it to the declarator, but that doesn't work: We
8669 // can't remove the attribute from the list of declaration attributes
8670 // because it might be needed by other declarators in the same
8675 if (AL
.getKind() == ParsedAttr::AT_VectorSize
) {
8676 // `vector_size` is a special case: It's a type attribute semantically,
8677 // but GCC expects the [[]] syntax to be written on the declaration (and
8678 // warns that the attribute has no effect if it is placed on the
8679 // decl-specifier-seq).
8680 // Silently move on and allow the attribute to be handled in
8681 // processTypeAttr().
8685 if (AL
.getKind() == ParsedAttr::AT_NoDeref
) {
8686 // FIXME: `noderef` currently doesn't work correctly in [[]] syntax.
8687 // See https://github.com/llvm/llvm-project/issues/55790 for details.
8688 // We allow processTypeAttrs() to emit a warning and silently move on.
8692 // N.B., ClangAttrEmitter.cpp emits a diagnostic helper that ensures a
8693 // statement attribute is not written on a declaration, but this code is
8694 // needed for type attributes as well as statement attributes in Attr.td
8695 // that do not list any subjects.
8696 S
.Diag(AL
.getLoc(), diag::err_attribute_invalid_on_decl
)
8697 << AL
<< D
->getLocation();
8699 case ParsedAttr::AT_Interrupt
:
8700 handleInterruptAttr(S
, D
, AL
);
8702 case ParsedAttr::AT_X86ForceAlignArgPointer
:
8703 handleX86ForceAlignArgPointerAttr(S
, D
, AL
);
8705 case ParsedAttr::AT_ReadOnlyPlacement
:
8706 handleSimpleAttribute
<ReadOnlyPlacementAttr
>(S
, D
, AL
);
8708 case ParsedAttr::AT_DLLExport
:
8709 case ParsedAttr::AT_DLLImport
:
8710 handleDLLAttr(S
, D
, AL
);
8712 case ParsedAttr::AT_AMDGPUFlatWorkGroupSize
:
8713 handleAMDGPUFlatWorkGroupSizeAttr(S
, D
, AL
);
8715 case ParsedAttr::AT_AMDGPUWavesPerEU
:
8716 handleAMDGPUWavesPerEUAttr(S
, D
, AL
);
8718 case ParsedAttr::AT_AMDGPUNumSGPR
:
8719 handleAMDGPUNumSGPRAttr(S
, D
, AL
);
8721 case ParsedAttr::AT_AMDGPUNumVGPR
:
8722 handleAMDGPUNumVGPRAttr(S
, D
, AL
);
8724 case ParsedAttr::AT_AVRSignal
:
8725 handleAVRSignalAttr(S
, D
, AL
);
8727 case ParsedAttr::AT_BPFPreserveAccessIndex
:
8728 handleBPFPreserveAccessIndexAttr(S
, D
, AL
);
8730 case ParsedAttr::AT_BTFDeclTag
:
8731 handleBTFDeclTagAttr(S
, D
, AL
);
8733 case ParsedAttr::AT_WebAssemblyExportName
:
8734 handleWebAssemblyExportNameAttr(S
, D
, AL
);
8736 case ParsedAttr::AT_WebAssemblyImportModule
:
8737 handleWebAssemblyImportModuleAttr(S
, D
, AL
);
8739 case ParsedAttr::AT_WebAssemblyImportName
:
8740 handleWebAssemblyImportNameAttr(S
, D
, AL
);
8742 case ParsedAttr::AT_IBOutlet
:
8743 handleIBOutlet(S
, D
, AL
);
8745 case ParsedAttr::AT_IBOutletCollection
:
8746 handleIBOutletCollection(S
, D
, AL
);
8748 case ParsedAttr::AT_IFunc
:
8749 handleIFuncAttr(S
, D
, AL
);
8751 case ParsedAttr::AT_Alias
:
8752 handleAliasAttr(S
, D
, AL
);
8754 case ParsedAttr::AT_Aligned
:
8755 handleAlignedAttr(S
, D
, AL
);
8757 case ParsedAttr::AT_AlignValue
:
8758 handleAlignValueAttr(S
, D
, AL
);
8760 case ParsedAttr::AT_AllocSize
:
8761 handleAllocSizeAttr(S
, D
, AL
);
8763 case ParsedAttr::AT_AlwaysInline
:
8764 handleAlwaysInlineAttr(S
, D
, AL
);
8766 case ParsedAttr::AT_AnalyzerNoReturn
:
8767 handleAnalyzerNoReturnAttr(S
, D
, AL
);
8769 case ParsedAttr::AT_TLSModel
:
8770 handleTLSModelAttr(S
, D
, AL
);
8772 case ParsedAttr::AT_Annotate
:
8773 handleAnnotateAttr(S
, D
, AL
);
8775 case ParsedAttr::AT_Availability
:
8776 handleAvailabilityAttr(S
, D
, AL
);
8778 case ParsedAttr::AT_CarriesDependency
:
8779 handleDependencyAttr(S
, scope
, D
, AL
);
8781 case ParsedAttr::AT_CPUDispatch
:
8782 case ParsedAttr::AT_CPUSpecific
:
8783 handleCPUSpecificAttr(S
, D
, AL
);
8785 case ParsedAttr::AT_Common
:
8786 handleCommonAttr(S
, D
, AL
);
8788 case ParsedAttr::AT_CUDAConstant
:
8789 handleConstantAttr(S
, D
, AL
);
8791 case ParsedAttr::AT_PassObjectSize
:
8792 handlePassObjectSizeAttr(S
, D
, AL
);
8794 case ParsedAttr::AT_Constructor
:
8795 handleConstructorAttr(S
, D
, AL
);
8797 case ParsedAttr::AT_Deprecated
:
8798 handleDeprecatedAttr(S
, D
, AL
);
8800 case ParsedAttr::AT_Destructor
:
8801 handleDestructorAttr(S
, D
, AL
);
8803 case ParsedAttr::AT_EnableIf
:
8804 handleEnableIfAttr(S
, D
, AL
);
8806 case ParsedAttr::AT_Error
:
8807 handleErrorAttr(S
, D
, AL
);
8809 case ParsedAttr::AT_DiagnoseIf
:
8810 handleDiagnoseIfAttr(S
, D
, AL
);
8812 case ParsedAttr::AT_DiagnoseAsBuiltin
:
8813 handleDiagnoseAsBuiltinAttr(S
, D
, AL
);
8815 case ParsedAttr::AT_NoBuiltin
:
8816 handleNoBuiltinAttr(S
, D
, AL
);
8818 case ParsedAttr::AT_ExtVectorType
:
8819 handleExtVectorTypeAttr(S
, D
, AL
);
8821 case ParsedAttr::AT_ExternalSourceSymbol
:
8822 handleExternalSourceSymbolAttr(S
, D
, AL
);
8824 case ParsedAttr::AT_MinSize
:
8825 handleMinSizeAttr(S
, D
, AL
);
8827 case ParsedAttr::AT_OptimizeNone
:
8828 handleOptimizeNoneAttr(S
, D
, AL
);
8830 case ParsedAttr::AT_EnumExtensibility
:
8831 handleEnumExtensibilityAttr(S
, D
, AL
);
8833 case ParsedAttr::AT_SYCLKernel
:
8834 handleSYCLKernelAttr(S
, D
, AL
);
8836 case ParsedAttr::AT_SYCLSpecialClass
:
8837 handleSimpleAttribute
<SYCLSpecialClassAttr
>(S
, D
, AL
);
8839 case ParsedAttr::AT_Format
:
8840 handleFormatAttr(S
, D
, AL
);
8842 case ParsedAttr::AT_FormatArg
:
8843 handleFormatArgAttr(S
, D
, AL
);
8845 case ParsedAttr::AT_Callback
:
8846 handleCallbackAttr(S
, D
, AL
);
8848 case ParsedAttr::AT_CalledOnce
:
8849 handleCalledOnceAttr(S
, D
, AL
);
8851 case ParsedAttr::AT_CUDAGlobal
:
8852 handleGlobalAttr(S
, D
, AL
);
8854 case ParsedAttr::AT_CUDADevice
:
8855 handleDeviceAttr(S
, D
, AL
);
8857 case ParsedAttr::AT_HIPManaged
:
8858 handleManagedAttr(S
, D
, AL
);
8860 case ParsedAttr::AT_GNUInline
:
8861 handleGNUInlineAttr(S
, D
, AL
);
8863 case ParsedAttr::AT_CUDALaunchBounds
:
8864 handleLaunchBoundsAttr(S
, D
, AL
);
8866 case ParsedAttr::AT_Restrict
:
8867 handleRestrictAttr(S
, D
, AL
);
8869 case ParsedAttr::AT_Mode
:
8870 handleModeAttr(S
, D
, AL
);
8872 case ParsedAttr::AT_NonNull
:
8873 if (auto *PVD
= dyn_cast
<ParmVarDecl
>(D
))
8874 handleNonNullAttrParameter(S
, PVD
, AL
);
8876 handleNonNullAttr(S
, D
, AL
);
8878 case ParsedAttr::AT_ReturnsNonNull
:
8879 handleReturnsNonNullAttr(S
, D
, AL
);
8881 case ParsedAttr::AT_NoEscape
:
8882 handleNoEscapeAttr(S
, D
, AL
);
8884 case ParsedAttr::AT_MaybeUndef
:
8885 handleSimpleAttribute
<MaybeUndefAttr
>(S
, D
, AL
);
8887 case ParsedAttr::AT_AssumeAligned
:
8888 handleAssumeAlignedAttr(S
, D
, AL
);
8890 case ParsedAttr::AT_AllocAlign
:
8891 handleAllocAlignAttr(S
, D
, AL
);
8893 case ParsedAttr::AT_Ownership
:
8894 handleOwnershipAttr(S
, D
, AL
);
8896 case ParsedAttr::AT_Naked
:
8897 handleNakedAttr(S
, D
, AL
);
8899 case ParsedAttr::AT_NoReturn
:
8900 handleNoReturnAttr(S
, D
, AL
);
8902 case ParsedAttr::AT_CXX11NoReturn
:
8903 handleStandardNoReturnAttr(S
, D
, AL
);
8905 case ParsedAttr::AT_AnyX86NoCfCheck
:
8906 handleNoCfCheckAttr(S
, D
, AL
);
8908 case ParsedAttr::AT_NoThrow
:
8909 if (!AL
.isUsedAsTypeAttr())
8910 handleSimpleAttribute
<NoThrowAttr
>(S
, D
, AL
);
8912 case ParsedAttr::AT_CUDAShared
:
8913 handleSharedAttr(S
, D
, AL
);
8915 case ParsedAttr::AT_VecReturn
:
8916 handleVecReturnAttr(S
, D
, AL
);
8918 case ParsedAttr::AT_ObjCOwnership
:
8919 handleObjCOwnershipAttr(S
, D
, AL
);
8921 case ParsedAttr::AT_ObjCPreciseLifetime
:
8922 handleObjCPreciseLifetimeAttr(S
, D
, AL
);
8924 case ParsedAttr::AT_ObjCReturnsInnerPointer
:
8925 handleObjCReturnsInnerPointerAttr(S
, D
, AL
);
8927 case ParsedAttr::AT_ObjCRequiresSuper
:
8928 handleObjCRequiresSuperAttr(S
, D
, AL
);
8930 case ParsedAttr::AT_ObjCBridge
:
8931 handleObjCBridgeAttr(S
, D
, AL
);
8933 case ParsedAttr::AT_ObjCBridgeMutable
:
8934 handleObjCBridgeMutableAttr(S
, D
, AL
);
8936 case ParsedAttr::AT_ObjCBridgeRelated
:
8937 handleObjCBridgeRelatedAttr(S
, D
, AL
);
8939 case ParsedAttr::AT_ObjCDesignatedInitializer
:
8940 handleObjCDesignatedInitializer(S
, D
, AL
);
8942 case ParsedAttr::AT_ObjCRuntimeName
:
8943 handleObjCRuntimeName(S
, D
, AL
);
8945 case ParsedAttr::AT_ObjCBoxable
:
8946 handleObjCBoxable(S
, D
, AL
);
8948 case ParsedAttr::AT_NSErrorDomain
:
8949 handleNSErrorDomain(S
, D
, AL
);
8951 case ParsedAttr::AT_CFConsumed
:
8952 case ParsedAttr::AT_NSConsumed
:
8953 case ParsedAttr::AT_OSConsumed
:
8954 S
.AddXConsumedAttr(D
, AL
, parsedAttrToRetainOwnershipKind(AL
),
8955 /*IsTemplateInstantiation=*/false);
8957 case ParsedAttr::AT_OSReturnsRetainedOnZero
:
8958 handleSimpleAttributeOrDiagnose
<OSReturnsRetainedOnZeroAttr
>(
8959 S
, D
, AL
, isValidOSObjectOutParameter(D
),
8960 diag::warn_ns_attribute_wrong_parameter_type
,
8961 /*Extra Args=*/AL
, /*pointer-to-OSObject-pointer*/ 3, AL
.getRange());
8963 case ParsedAttr::AT_OSReturnsRetainedOnNonZero
:
8964 handleSimpleAttributeOrDiagnose
<OSReturnsRetainedOnNonZeroAttr
>(
8965 S
, D
, AL
, isValidOSObjectOutParameter(D
),
8966 diag::warn_ns_attribute_wrong_parameter_type
,
8967 /*Extra Args=*/AL
, /*pointer-to-OSObject-poointer*/ 3, AL
.getRange());
8969 case ParsedAttr::AT_NSReturnsAutoreleased
:
8970 case ParsedAttr::AT_NSReturnsNotRetained
:
8971 case ParsedAttr::AT_NSReturnsRetained
:
8972 case ParsedAttr::AT_CFReturnsNotRetained
:
8973 case ParsedAttr::AT_CFReturnsRetained
:
8974 case ParsedAttr::AT_OSReturnsNotRetained
:
8975 case ParsedAttr::AT_OSReturnsRetained
:
8976 handleXReturnsXRetainedAttr(S
, D
, AL
);
8978 case ParsedAttr::AT_WorkGroupSizeHint
:
8979 handleWorkGroupSize
<WorkGroupSizeHintAttr
>(S
, D
, AL
);
8981 case ParsedAttr::AT_ReqdWorkGroupSize
:
8982 handleWorkGroupSize
<ReqdWorkGroupSizeAttr
>(S
, D
, AL
);
8984 case ParsedAttr::AT_OpenCLIntelReqdSubGroupSize
:
8985 handleSubGroupSize(S
, D
, AL
);
8987 case ParsedAttr::AT_VecTypeHint
:
8988 handleVecTypeHint(S
, D
, AL
);
8990 case ParsedAttr::AT_InitPriority
:
8991 handleInitPriorityAttr(S
, D
, AL
);
8993 case ParsedAttr::AT_Packed
:
8994 handlePackedAttr(S
, D
, AL
);
8996 case ParsedAttr::AT_PreferredName
:
8997 handlePreferredName(S
, D
, AL
);
8999 case ParsedAttr::AT_Section
:
9000 handleSectionAttr(S
, D
, AL
);
9002 case ParsedAttr::AT_RandomizeLayout
:
9003 handleRandomizeLayoutAttr(S
, D
, AL
);
9005 case ParsedAttr::AT_NoRandomizeLayout
:
9006 handleNoRandomizeLayoutAttr(S
, D
, AL
);
9008 case ParsedAttr::AT_CodeSeg
:
9009 handleCodeSegAttr(S
, D
, AL
);
9011 case ParsedAttr::AT_Target
:
9012 handleTargetAttr(S
, D
, AL
);
9014 case ParsedAttr::AT_TargetVersion
:
9015 handleTargetVersionAttr(S
, D
, AL
);
9017 case ParsedAttr::AT_TargetClones
:
9018 handleTargetClonesAttr(S
, D
, AL
);
9020 case ParsedAttr::AT_MinVectorWidth
:
9021 handleMinVectorWidthAttr(S
, D
, AL
);
9023 case ParsedAttr::AT_Unavailable
:
9024 handleAttrWithMessage
<UnavailableAttr
>(S
, D
, AL
);
9026 case ParsedAttr::AT_Assumption
:
9027 handleAssumumptionAttr(S
, D
, AL
);
9029 case ParsedAttr::AT_ObjCDirect
:
9030 handleObjCDirectAttr(S
, D
, AL
);
9032 case ParsedAttr::AT_ObjCDirectMembers
:
9033 handleObjCDirectMembersAttr(S
, D
, AL
);
9034 handleSimpleAttribute
<ObjCDirectMembersAttr
>(S
, D
, AL
);
9036 case ParsedAttr::AT_ObjCExplicitProtocolImpl
:
9037 handleObjCSuppresProtocolAttr(S
, D
, AL
);
9039 case ParsedAttr::AT_Unused
:
9040 handleUnusedAttr(S
, D
, AL
);
9042 case ParsedAttr::AT_Visibility
:
9043 handleVisibilityAttr(S
, D
, AL
, false);
9045 case ParsedAttr::AT_TypeVisibility
:
9046 handleVisibilityAttr(S
, D
, AL
, true);
9048 case ParsedAttr::AT_WarnUnusedResult
:
9049 handleWarnUnusedResult(S
, D
, AL
);
9051 case ParsedAttr::AT_WeakRef
:
9052 handleWeakRefAttr(S
, D
, AL
);
9054 case ParsedAttr::AT_WeakImport
:
9055 handleWeakImportAttr(S
, D
, AL
);
9057 case ParsedAttr::AT_TransparentUnion
:
9058 handleTransparentUnionAttr(S
, D
, AL
);
9060 case ParsedAttr::AT_ObjCMethodFamily
:
9061 handleObjCMethodFamilyAttr(S
, D
, AL
);
9063 case ParsedAttr::AT_ObjCNSObject
:
9064 handleObjCNSObject(S
, D
, AL
);
9066 case ParsedAttr::AT_ObjCIndependentClass
:
9067 handleObjCIndependentClass(S
, D
, AL
);
9069 case ParsedAttr::AT_Blocks
:
9070 handleBlocksAttr(S
, D
, AL
);
9072 case ParsedAttr::AT_Sentinel
:
9073 handleSentinelAttr(S
, D
, AL
);
9075 case ParsedAttr::AT_Cleanup
:
9076 handleCleanupAttr(S
, D
, AL
);
9078 case ParsedAttr::AT_NoDebug
:
9079 handleNoDebugAttr(S
, D
, AL
);
9081 case ParsedAttr::AT_CmseNSEntry
:
9082 handleCmseNSEntryAttr(S
, D
, AL
);
9084 case ParsedAttr::AT_StdCall
:
9085 case ParsedAttr::AT_CDecl
:
9086 case ParsedAttr::AT_FastCall
:
9087 case ParsedAttr::AT_ThisCall
:
9088 case ParsedAttr::AT_Pascal
:
9089 case ParsedAttr::AT_RegCall
:
9090 case ParsedAttr::AT_SwiftCall
:
9091 case ParsedAttr::AT_SwiftAsyncCall
:
9092 case ParsedAttr::AT_VectorCall
:
9093 case ParsedAttr::AT_MSABI
:
9094 case ParsedAttr::AT_SysVABI
:
9095 case ParsedAttr::AT_Pcs
:
9096 case ParsedAttr::AT_IntelOclBicc
:
9097 case ParsedAttr::AT_PreserveMost
:
9098 case ParsedAttr::AT_PreserveAll
:
9099 case ParsedAttr::AT_AArch64VectorPcs
:
9100 case ParsedAttr::AT_AArch64SVEPcs
:
9101 case ParsedAttr::AT_AMDGPUKernelCall
:
9102 handleCallConvAttr(S
, D
, AL
);
9104 case ParsedAttr::AT_Suppress
:
9105 handleSuppressAttr(S
, D
, AL
);
9107 case ParsedAttr::AT_Owner
:
9108 case ParsedAttr::AT_Pointer
:
9109 handleLifetimeCategoryAttr(S
, D
, AL
);
9111 case ParsedAttr::AT_OpenCLAccess
:
9112 handleOpenCLAccessAttr(S
, D
, AL
);
9114 case ParsedAttr::AT_OpenCLNoSVM
:
9115 handleOpenCLNoSVMAttr(S
, D
, AL
);
9117 case ParsedAttr::AT_SwiftContext
:
9118 S
.AddParameterABIAttr(D
, AL
, ParameterABI::SwiftContext
);
9120 case ParsedAttr::AT_SwiftAsyncContext
:
9121 S
.AddParameterABIAttr(D
, AL
, ParameterABI::SwiftAsyncContext
);
9123 case ParsedAttr::AT_SwiftErrorResult
:
9124 S
.AddParameterABIAttr(D
, AL
, ParameterABI::SwiftErrorResult
);
9126 case ParsedAttr::AT_SwiftIndirectResult
:
9127 S
.AddParameterABIAttr(D
, AL
, ParameterABI::SwiftIndirectResult
);
9129 case ParsedAttr::AT_InternalLinkage
:
9130 handleInternalLinkageAttr(S
, D
, AL
);
9132 case ParsedAttr::AT_ZeroCallUsedRegs
:
9133 handleZeroCallUsedRegsAttr(S
, D
, AL
);
9135 case ParsedAttr::AT_FunctionReturnThunks
:
9136 handleFunctionReturnThunksAttr(S
, D
, AL
);
9139 // Microsoft attributes:
9140 case ParsedAttr::AT_LayoutVersion
:
9141 handleLayoutVersion(S
, D
, AL
);
9143 case ParsedAttr::AT_Uuid
:
9144 handleUuidAttr(S
, D
, AL
);
9146 case ParsedAttr::AT_MSInheritance
:
9147 handleMSInheritanceAttr(S
, D
, AL
);
9149 case ParsedAttr::AT_Thread
:
9150 handleDeclspecThreadAttr(S
, D
, AL
);
9154 case ParsedAttr::AT_HLSLNumThreads
:
9155 handleHLSLNumThreadsAttr(S
, D
, AL
);
9157 case ParsedAttr::AT_HLSLSV_GroupIndex
:
9158 handleHLSLSVGroupIndexAttr(S
, D
, AL
);
9160 case ParsedAttr::AT_HLSLSV_DispatchThreadID
:
9161 handleHLSLSV_DispatchThreadIDAttr(S
, D
, AL
);
9163 case ParsedAttr::AT_HLSLShader
:
9164 handleHLSLShaderAttr(S
, D
, AL
);
9166 case ParsedAttr::AT_HLSLResourceBinding
:
9167 handleHLSLResourceBindingAttr(S
, D
, AL
);
9170 case ParsedAttr::AT_AbiTag
:
9171 handleAbiTagAttr(S
, D
, AL
);
9173 case ParsedAttr::AT_CFGuard
:
9174 handleCFGuardAttr(S
, D
, AL
);
9177 // Thread safety attributes:
9178 case ParsedAttr::AT_AssertExclusiveLock
:
9179 handleAssertExclusiveLockAttr(S
, D
, AL
);
9181 case ParsedAttr::AT_AssertSharedLock
:
9182 handleAssertSharedLockAttr(S
, D
, AL
);
9184 case ParsedAttr::AT_PtGuardedVar
:
9185 handlePtGuardedVarAttr(S
, D
, AL
);
9187 case ParsedAttr::AT_NoSanitize
:
9188 handleNoSanitizeAttr(S
, D
, AL
);
9190 case ParsedAttr::AT_NoSanitizeSpecific
:
9191 handleNoSanitizeSpecificAttr(S
, D
, AL
);
9193 case ParsedAttr::AT_GuardedBy
:
9194 handleGuardedByAttr(S
, D
, AL
);
9196 case ParsedAttr::AT_PtGuardedBy
:
9197 handlePtGuardedByAttr(S
, D
, AL
);
9199 case ParsedAttr::AT_ExclusiveTrylockFunction
:
9200 handleExclusiveTrylockFunctionAttr(S
, D
, AL
);
9202 case ParsedAttr::AT_LockReturned
:
9203 handleLockReturnedAttr(S
, D
, AL
);
9205 case ParsedAttr::AT_LocksExcluded
:
9206 handleLocksExcludedAttr(S
, D
, AL
);
9208 case ParsedAttr::AT_SharedTrylockFunction
:
9209 handleSharedTrylockFunctionAttr(S
, D
, AL
);
9211 case ParsedAttr::AT_AcquiredBefore
:
9212 handleAcquiredBeforeAttr(S
, D
, AL
);
9214 case ParsedAttr::AT_AcquiredAfter
:
9215 handleAcquiredAfterAttr(S
, D
, AL
);
9218 // Capability analysis attributes.
9219 case ParsedAttr::AT_Capability
:
9220 case ParsedAttr::AT_Lockable
:
9221 handleCapabilityAttr(S
, D
, AL
);
9223 case ParsedAttr::AT_RequiresCapability
:
9224 handleRequiresCapabilityAttr(S
, D
, AL
);
9227 case ParsedAttr::AT_AssertCapability
:
9228 handleAssertCapabilityAttr(S
, D
, AL
);
9230 case ParsedAttr::AT_AcquireCapability
:
9231 handleAcquireCapabilityAttr(S
, D
, AL
);
9233 case ParsedAttr::AT_ReleaseCapability
:
9234 handleReleaseCapabilityAttr(S
, D
, AL
);
9236 case ParsedAttr::AT_TryAcquireCapability
:
9237 handleTryAcquireCapabilityAttr(S
, D
, AL
);
9240 // Consumed analysis attributes.
9241 case ParsedAttr::AT_Consumable
:
9242 handleConsumableAttr(S
, D
, AL
);
9244 case ParsedAttr::AT_CallableWhen
:
9245 handleCallableWhenAttr(S
, D
, AL
);
9247 case ParsedAttr::AT_ParamTypestate
:
9248 handleParamTypestateAttr(S
, D
, AL
);
9250 case ParsedAttr::AT_ReturnTypestate
:
9251 handleReturnTypestateAttr(S
, D
, AL
);
9253 case ParsedAttr::AT_SetTypestate
:
9254 handleSetTypestateAttr(S
, D
, AL
);
9256 case ParsedAttr::AT_TestTypestate
:
9257 handleTestTypestateAttr(S
, D
, AL
);
9260 // Type safety attributes.
9261 case ParsedAttr::AT_ArgumentWithTypeTag
:
9262 handleArgumentWithTypeTagAttr(S
, D
, AL
);
9264 case ParsedAttr::AT_TypeTagForDatatype
:
9265 handleTypeTagForDatatypeAttr(S
, D
, AL
);
9268 // Swift attributes.
9269 case ParsedAttr::AT_SwiftAsyncName
:
9270 handleSwiftAsyncName(S
, D
, AL
);
9272 case ParsedAttr::AT_SwiftAttr
:
9273 handleSwiftAttrAttr(S
, D
, AL
);
9275 case ParsedAttr::AT_SwiftBridge
:
9276 handleSwiftBridge(S
, D
, AL
);
9278 case ParsedAttr::AT_SwiftError
:
9279 handleSwiftError(S
, D
, AL
);
9281 case ParsedAttr::AT_SwiftName
:
9282 handleSwiftName(S
, D
, AL
);
9284 case ParsedAttr::AT_SwiftNewType
:
9285 handleSwiftNewType(S
, D
, AL
);
9287 case ParsedAttr::AT_SwiftAsync
:
9288 handleSwiftAsyncAttr(S
, D
, AL
);
9290 case ParsedAttr::AT_SwiftAsyncError
:
9291 handleSwiftAsyncError(S
, D
, AL
);
9295 case ParsedAttr::AT_XRayLogArgs
:
9296 handleXRayLogArgsAttr(S
, D
, AL
);
9299 case ParsedAttr::AT_PatchableFunctionEntry
:
9300 handlePatchableFunctionEntryAttr(S
, D
, AL
);
9303 case ParsedAttr::AT_AlwaysDestroy
:
9304 case ParsedAttr::AT_NoDestroy
:
9305 handleDestroyAttr(S
, D
, AL
);
9308 case ParsedAttr::AT_Uninitialized
:
9309 handleUninitializedAttr(S
, D
, AL
);
9312 case ParsedAttr::AT_ObjCExternallyRetained
:
9313 handleObjCExternallyRetainedAttr(S
, D
, AL
);
9316 case ParsedAttr::AT_MIGServerRoutine
:
9317 handleMIGServerRoutineAttr(S
, D
, AL
);
9320 case ParsedAttr::AT_MSAllocator
:
9321 handleMSAllocatorAttr(S
, D
, AL
);
9324 case ParsedAttr::AT_ArmBuiltinAlias
:
9325 handleArmBuiltinAliasAttr(S
, D
, AL
);
9328 case ParsedAttr::AT_AcquireHandle
:
9329 handleAcquireHandleAttr(S
, D
, AL
);
9332 case ParsedAttr::AT_ReleaseHandle
:
9333 handleHandleAttr
<ReleaseHandleAttr
>(S
, D
, AL
);
9336 case ParsedAttr::AT_UnsafeBufferUsage
:
9337 handleUnsafeBufferUsage
<UnsafeBufferUsageAttr
>(S
, D
, AL
);
9340 case ParsedAttr::AT_UseHandle
:
9341 handleHandleAttr
<UseHandleAttr
>(S
, D
, AL
);
9344 case ParsedAttr::AT_EnforceTCB
:
9345 handleEnforceTCBAttr
<EnforceTCBAttr
, EnforceTCBLeafAttr
>(S
, D
, AL
);
9348 case ParsedAttr::AT_EnforceTCBLeaf
:
9349 handleEnforceTCBAttr
<EnforceTCBLeafAttr
, EnforceTCBAttr
>(S
, D
, AL
);
9352 case ParsedAttr::AT_BuiltinAlias
:
9353 handleBuiltinAliasAttr(S
, D
, AL
);
9356 case ParsedAttr::AT_UsingIfExists
:
9357 handleSimpleAttribute
<UsingIfExistsAttr
>(S
, D
, AL
);
9362 /// ProcessDeclAttributeList - Apply all the decl attributes in the specified
9363 /// attribute list to the specified decl, ignoring any type attributes.
9364 void Sema::ProcessDeclAttributeList(
9365 Scope
*S
, Decl
*D
, const ParsedAttributesView
&AttrList
,
9366 const ProcessDeclAttributeOptions
&Options
) {
9367 if (AttrList
.empty())
9370 for (const ParsedAttr
&AL
: AttrList
)
9371 ProcessDeclAttribute(*this, S
, D
, AL
, Options
);
9373 // FIXME: We should be able to handle these cases in TableGen.
9375 // static int a9 __attribute__((weakref));
9376 // but that looks really pointless. We reject it.
9377 if (D
->hasAttr
<WeakRefAttr
>() && !D
->hasAttr
<AliasAttr
>()) {
9378 Diag(AttrList
.begin()->getLoc(), diag::err_attribute_weakref_without_alias
)
9379 << cast
<NamedDecl
>(D
);
9380 D
->dropAttr
<WeakRefAttr
>();
9384 // FIXME: We should be able to handle this in TableGen as well. It would be
9385 // good to have a way to specify "these attributes must appear as a group",
9386 // for these. Additionally, it would be good to have a way to specify "these
9387 // attribute must never appear as a group" for attributes like cold and hot.
9388 if (!D
->hasAttr
<OpenCLKernelAttr
>()) {
9389 // These attributes cannot be applied to a non-kernel function.
9390 if (const auto *A
= D
->getAttr
<ReqdWorkGroupSizeAttr
>()) {
9391 // FIXME: This emits a different error message than
9392 // diag::err_attribute_wrong_decl_type + ExpectedKernelFunction.
9393 Diag(D
->getLocation(), diag::err_opencl_kernel_attr
) << A
;
9394 D
->setInvalidDecl();
9395 } else if (const auto *A
= D
->getAttr
<WorkGroupSizeHintAttr
>()) {
9396 Diag(D
->getLocation(), diag::err_opencl_kernel_attr
) << A
;
9397 D
->setInvalidDecl();
9398 } else if (const auto *A
= D
->getAttr
<VecTypeHintAttr
>()) {
9399 Diag(D
->getLocation(), diag::err_opencl_kernel_attr
) << A
;
9400 D
->setInvalidDecl();
9401 } else if (const auto *A
= D
->getAttr
<OpenCLIntelReqdSubGroupSizeAttr
>()) {
9402 Diag(D
->getLocation(), diag::err_opencl_kernel_attr
) << A
;
9403 D
->setInvalidDecl();
9404 } else if (!D
->hasAttr
<CUDAGlobalAttr
>()) {
9405 if (const auto *A
= D
->getAttr
<AMDGPUFlatWorkGroupSizeAttr
>()) {
9406 Diag(D
->getLocation(), diag::err_attribute_wrong_decl_type
)
9407 << A
<< ExpectedKernelFunction
;
9408 D
->setInvalidDecl();
9409 } else if (const auto *A
= D
->getAttr
<AMDGPUWavesPerEUAttr
>()) {
9410 Diag(D
->getLocation(), diag::err_attribute_wrong_decl_type
)
9411 << A
<< ExpectedKernelFunction
;
9412 D
->setInvalidDecl();
9413 } else if (const auto *A
= D
->getAttr
<AMDGPUNumSGPRAttr
>()) {
9414 Diag(D
->getLocation(), diag::err_attribute_wrong_decl_type
)
9415 << A
<< ExpectedKernelFunction
;
9416 D
->setInvalidDecl();
9417 } else if (const auto *A
= D
->getAttr
<AMDGPUNumVGPRAttr
>()) {
9418 Diag(D
->getLocation(), diag::err_attribute_wrong_decl_type
)
9419 << A
<< ExpectedKernelFunction
;
9420 D
->setInvalidDecl();
9425 // Do this check after processing D's attributes because the attribute
9426 // objc_method_family can change whether the given method is in the init
9427 // family, and it can be applied after objc_designated_initializer. This is a
9428 // bit of a hack, but we need it to be compatible with versions of clang that
9429 // processed the attribute list in the wrong order.
9430 if (D
->hasAttr
<ObjCDesignatedInitializerAttr
>() &&
9431 cast
<ObjCMethodDecl
>(D
)->getMethodFamily() != OMF_init
) {
9432 Diag(D
->getLocation(), diag::err_designated_init_attr_non_init
);
9433 D
->dropAttr
<ObjCDesignatedInitializerAttr
>();
9437 // Helper for delayed processing TransparentUnion or BPFPreserveAccessIndexAttr
9439 void Sema::ProcessDeclAttributeDelayed(Decl
*D
,
9440 const ParsedAttributesView
&AttrList
) {
9441 for (const ParsedAttr
&AL
: AttrList
)
9442 if (AL
.getKind() == ParsedAttr::AT_TransparentUnion
) {
9443 handleTransparentUnionAttr(*this, D
, AL
);
9447 // For BPFPreserveAccessIndexAttr, we want to populate the attributes
9448 // to fields and inner records as well.
9449 if (D
&& D
->hasAttr
<BPFPreserveAccessIndexAttr
>())
9450 handleBPFPreserveAIRecord(*this, cast
<RecordDecl
>(D
));
9453 // Annotation attributes are the only attributes allowed after an access
9455 bool Sema::ProcessAccessDeclAttributeList(
9456 AccessSpecDecl
*ASDecl
, const ParsedAttributesView
&AttrList
) {
9457 for (const ParsedAttr
&AL
: AttrList
) {
9458 if (AL
.getKind() == ParsedAttr::AT_Annotate
) {
9459 ProcessDeclAttribute(*this, nullptr, ASDecl
, AL
,
9460 ProcessDeclAttributeOptions());
9462 Diag(AL
.getLoc(), diag::err_only_annotate_after_access_spec
);
9469 /// checkUnusedDeclAttributes - Check a list of attributes to see if it
9470 /// contains any decl attributes that we should warn about.
9471 static void checkUnusedDeclAttributes(Sema
&S
, const ParsedAttributesView
&A
) {
9472 for (const ParsedAttr
&AL
: A
) {
9473 // Only warn if the attribute is an unignored, non-type attribute.
9474 if (AL
.isUsedAsTypeAttr() || AL
.isInvalid())
9476 if (AL
.getKind() == ParsedAttr::IgnoredAttribute
)
9479 if (AL
.getKind() == ParsedAttr::UnknownAttribute
) {
9480 S
.Diag(AL
.getLoc(), diag::warn_unknown_attribute_ignored
)
9481 << AL
<< AL
.getRange();
9483 S
.Diag(AL
.getLoc(), diag::warn_attribute_not_on_decl
) << AL
9489 /// checkUnusedDeclAttributes - Given a declarator which is not being
9490 /// used to build a declaration, complain about any decl attributes
9491 /// which might be lying around on it.
9492 void Sema::checkUnusedDeclAttributes(Declarator
&D
) {
9493 ::checkUnusedDeclAttributes(*this, D
.getDeclarationAttributes());
9494 ::checkUnusedDeclAttributes(*this, D
.getDeclSpec().getAttributes());
9495 ::checkUnusedDeclAttributes(*this, D
.getAttributes());
9496 for (unsigned i
= 0, e
= D
.getNumTypeObjects(); i
!= e
; ++i
)
9497 ::checkUnusedDeclAttributes(*this, D
.getTypeObject(i
).getAttrs());
9500 /// DeclClonePragmaWeak - clone existing decl (maybe definition),
9501 /// \#pragma weak needs a non-definition decl and source may not have one.
9502 NamedDecl
*Sema::DeclClonePragmaWeak(NamedDecl
*ND
, const IdentifierInfo
*II
,
9503 SourceLocation Loc
) {
9504 assert(isa
<FunctionDecl
>(ND
) || isa
<VarDecl
>(ND
));
9505 NamedDecl
*NewD
= nullptr;
9506 if (auto *FD
= dyn_cast
<FunctionDecl
>(ND
)) {
9507 FunctionDecl
*NewFD
;
9508 // FIXME: Missing call to CheckFunctionDeclaration().
9510 // FIXME: Is the qualifier info correct?
9511 // FIXME: Is the DeclContext correct?
9512 NewFD
= FunctionDecl::Create(
9513 FD
->getASTContext(), FD
->getDeclContext(), Loc
, Loc
,
9514 DeclarationName(II
), FD
->getType(), FD
->getTypeSourceInfo(), SC_None
,
9515 getCurFPFeatures().isFPConstrained(), false /*isInlineSpecified*/,
9516 FD
->hasPrototype(), ConstexprSpecKind::Unspecified
,
9517 FD
->getTrailingRequiresClause());
9520 if (FD
->getQualifier())
9521 NewFD
->setQualifierInfo(FD
->getQualifierLoc());
9523 // Fake up parameter variables; they are declared as if this were
9525 QualType FDTy
= FD
->getType();
9526 if (const auto *FT
= FDTy
->getAs
<FunctionProtoType
>()) {
9527 SmallVector
<ParmVarDecl
*, 16> Params
;
9528 for (const auto &AI
: FT
->param_types()) {
9529 ParmVarDecl
*Param
= BuildParmVarDeclForTypedef(NewFD
, Loc
, AI
);
9530 Param
->setScopeInfo(0, Params
.size());
9531 Params
.push_back(Param
);
9533 NewFD
->setParams(Params
);
9535 } else if (auto *VD
= dyn_cast
<VarDecl
>(ND
)) {
9536 NewD
= VarDecl::Create(VD
->getASTContext(), VD
->getDeclContext(),
9537 VD
->getInnerLocStart(), VD
->getLocation(), II
,
9538 VD
->getType(), VD
->getTypeSourceInfo(),
9539 VD
->getStorageClass());
9540 if (VD
->getQualifier())
9541 cast
<VarDecl
>(NewD
)->setQualifierInfo(VD
->getQualifierLoc());
9546 /// DeclApplyPragmaWeak - A declaration (maybe definition) needs \#pragma weak
9547 /// applied to it, possibly with an alias.
9548 void Sema::DeclApplyPragmaWeak(Scope
*S
, NamedDecl
*ND
, const WeakInfo
&W
) {
9549 if (W
.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
9550 IdentifierInfo
*NDId
= ND
->getIdentifier();
9551 NamedDecl
*NewD
= DeclClonePragmaWeak(ND
, W
.getAlias(), W
.getLocation());
9553 AliasAttr::CreateImplicit(Context
, NDId
->getName(), W
.getLocation()));
9554 NewD
->addAttr(WeakAttr::CreateImplicit(Context
, W
.getLocation(),
9555 AttributeCommonInfo::AS_Pragma
));
9556 WeakTopLevelDecl
.push_back(NewD
);
9557 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
9558 // to insert Decl at TU scope, sorry.
9559 DeclContext
*SavedContext
= CurContext
;
9560 CurContext
= Context
.getTranslationUnitDecl();
9561 NewD
->setDeclContext(CurContext
);
9562 NewD
->setLexicalDeclContext(CurContext
);
9563 PushOnScopeChains(NewD
, S
);
9564 CurContext
= SavedContext
;
9565 } else { // just add weak to existing
9566 ND
->addAttr(WeakAttr::CreateImplicit(Context
, W
.getLocation(),
9567 AttributeCommonInfo::AS_Pragma
));
9571 void Sema::ProcessPragmaWeak(Scope
*S
, Decl
*D
) {
9572 // It's valid to "forward-declare" #pragma weak, in which case we
9574 LoadExternalWeakUndeclaredIdentifiers();
9575 if (WeakUndeclaredIdentifiers
.empty())
9577 NamedDecl
*ND
= nullptr;
9578 if (auto *VD
= dyn_cast
<VarDecl
>(D
))
9579 if (VD
->isExternC())
9581 if (auto *FD
= dyn_cast
<FunctionDecl
>(D
))
9582 if (FD
->isExternC())
9586 if (IdentifierInfo
*Id
= ND
->getIdentifier()) {
9587 auto I
= WeakUndeclaredIdentifiers
.find(Id
);
9588 if (I
!= WeakUndeclaredIdentifiers
.end()) {
9589 auto &WeakInfos
= I
->second
;
9590 for (const auto &W
: WeakInfos
)
9591 DeclApplyPragmaWeak(S
, ND
, W
);
9592 std::remove_reference_t
<decltype(WeakInfos
)> EmptyWeakInfos
;
9593 WeakInfos
.swap(EmptyWeakInfos
);
9598 /// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
9599 /// it, apply them to D. This is a bit tricky because PD can have attributes
9600 /// specified in many different places, and we need to find and apply them all.
9601 void Sema::ProcessDeclAttributes(Scope
*S
, Decl
*D
, const Declarator
&PD
) {
9602 // Ordering of attributes can be important, so we take care to process
9603 // attributes in the order in which they appeared in the source code.
9605 // First, process attributes that appeared on the declaration itself (but
9606 // only if they don't have the legacy behavior of "sliding" to the DeclSepc).
9607 ParsedAttributesView NonSlidingAttrs
;
9608 for (ParsedAttr
&AL
: PD
.getDeclarationAttributes()) {
9609 if (AL
.slidesFromDeclToDeclSpecLegacyBehavior()) {
9610 // Skip processing the attribute, but do check if it appertains to the
9611 // declaration. This is needed for the `MatrixType` attribute, which,
9612 // despite being a type attribute, defines a `SubjectList` that only
9613 // allows it to be used on typedef declarations.
9614 AL
.diagnoseAppertainsTo(*this, D
);
9616 NonSlidingAttrs
.addAtEnd(&AL
);
9619 ProcessDeclAttributeList(S
, D
, NonSlidingAttrs
);
9621 // Apply decl attributes from the DeclSpec if present.
9622 if (!PD
.getDeclSpec().getAttributes().empty()) {
9623 ProcessDeclAttributeList(S
, D
, PD
.getDeclSpec().getAttributes(),
9624 ProcessDeclAttributeOptions()
9625 .WithIncludeCXX11Attributes(false)
9626 .WithIgnoreTypeAttributes(true));
9629 // Walk the declarator structure, applying decl attributes that were in a type
9630 // position to the decl itself. This handles cases like:
9631 // int *__attr__(x)** D;
9632 // when X is a decl attribute.
9633 for (unsigned i
= 0, e
= PD
.getNumTypeObjects(); i
!= e
; ++i
) {
9634 ProcessDeclAttributeList(S
, D
, PD
.getTypeObject(i
).getAttrs(),
9635 ProcessDeclAttributeOptions()
9636 .WithIncludeCXX11Attributes(false)
9637 .WithIgnoreTypeAttributes(true));
9640 // Finally, apply any attributes on the decl itself.
9641 ProcessDeclAttributeList(S
, D
, PD
.getAttributes());
9643 // Apply additional attributes specified by '#pragma clang attribute'.
9644 AddPragmaAttributes(S
, D
);
9647 /// Is the given declaration allowed to use a forbidden type?
9648 /// If so, it'll still be annotated with an attribute that makes it
9649 /// illegal to actually use.
9650 static bool isForbiddenTypeAllowed(Sema
&S
, Decl
*D
,
9651 const DelayedDiagnostic
&diag
,
9652 UnavailableAttr::ImplicitReason
&reason
) {
9653 // Private ivars are always okay. Unfortunately, people don't
9654 // always properly make their ivars private, even in system headers.
9655 // Plus we need to make fields okay, too.
9656 if (!isa
<FieldDecl
>(D
) && !isa
<ObjCPropertyDecl
>(D
) &&
9657 !isa
<FunctionDecl
>(D
))
9660 // Silently accept unsupported uses of __weak in both user and system
9661 // declarations when it's been disabled, for ease of integration with
9662 // -fno-objc-arc files. We do have to take some care against attempts
9663 // to define such things; for now, we've only done that for ivars
9665 if ((isa
<ObjCIvarDecl
>(D
) || isa
<ObjCPropertyDecl
>(D
))) {
9666 if (diag
.getForbiddenTypeDiagnostic() == diag::err_arc_weak_disabled
||
9667 diag
.getForbiddenTypeDiagnostic() == diag::err_arc_weak_no_runtime
) {
9668 reason
= UnavailableAttr::IR_ForbiddenWeak
;
9673 // Allow all sorts of things in system headers.
9674 if (S
.Context
.getSourceManager().isInSystemHeader(D
->getLocation())) {
9675 // Currently, all the failures dealt with this way are due to ARC
9677 reason
= UnavailableAttr::IR_ARCForbiddenType
;
9684 /// Handle a delayed forbidden-type diagnostic.
9685 static void handleDelayedForbiddenType(Sema
&S
, DelayedDiagnostic
&DD
,
9687 auto Reason
= UnavailableAttr::IR_None
;
9688 if (D
&& isForbiddenTypeAllowed(S
, D
, DD
, Reason
)) {
9689 assert(Reason
&& "didn't set reason?");
9690 D
->addAttr(UnavailableAttr::CreateImplicit(S
.Context
, "", Reason
, DD
.Loc
));
9693 if (S
.getLangOpts().ObjCAutoRefCount
)
9694 if (const auto *FD
= dyn_cast
<FunctionDecl
>(D
)) {
9695 // FIXME: we may want to suppress diagnostics for all
9696 // kind of forbidden type messages on unavailable functions.
9697 if (FD
->hasAttr
<UnavailableAttr
>() &&
9698 DD
.getForbiddenTypeDiagnostic() ==
9699 diag::err_arc_array_param_no_ownership
) {
9700 DD
.Triggered
= true;
9705 S
.Diag(DD
.Loc
, DD
.getForbiddenTypeDiagnostic())
9706 << DD
.getForbiddenTypeOperand() << DD
.getForbiddenTypeArgument();
9707 DD
.Triggered
= true;
9711 void Sema::PopParsingDeclaration(ParsingDeclState state
, Decl
*decl
) {
9712 assert(DelayedDiagnostics
.getCurrentPool());
9713 DelayedDiagnosticPool
&poppedPool
= *DelayedDiagnostics
.getCurrentPool();
9714 DelayedDiagnostics
.popWithoutEmitting(state
);
9716 // When delaying diagnostics to run in the context of a parsed
9717 // declaration, we only want to actually emit anything if parsing
9721 // We emit all the active diagnostics in this pool or any of its
9722 // parents. In general, we'll get one pool for the decl spec
9723 // and a child pool for each declarator; in a decl group like:
9724 // deprecated_typedef foo, *bar, baz();
9725 // only the declarator pops will be passed decls. This is correct;
9726 // we really do need to consider delayed diagnostics from the decl spec
9727 // for each of the different declarations.
9728 const DelayedDiagnosticPool
*pool
= &poppedPool
;
9730 bool AnyAccessFailures
= false;
9731 for (DelayedDiagnosticPool::pool_iterator
9732 i
= pool
->pool_begin(), e
= pool
->pool_end(); i
!= e
; ++i
) {
9733 // This const_cast is a bit lame. Really, Triggered should be mutable.
9734 DelayedDiagnostic
&diag
= const_cast<DelayedDiagnostic
&>(*i
);
9738 switch (diag
.Kind
) {
9739 case DelayedDiagnostic::Availability
:
9740 // Don't bother giving deprecation/unavailable diagnostics if
9741 // the decl is invalid.
9742 if (!decl
->isInvalidDecl())
9743 handleDelayedAvailabilityCheck(diag
, decl
);
9746 case DelayedDiagnostic::Access
:
9747 // Only produce one access control diagnostic for a structured binding
9748 // declaration: we don't need to tell the user that all the fields are
9749 // inaccessible one at a time.
9750 if (AnyAccessFailures
&& isa
<DecompositionDecl
>(decl
))
9752 HandleDelayedAccessCheck(diag
, decl
);
9754 AnyAccessFailures
= true;
9757 case DelayedDiagnostic::ForbiddenType
:
9758 handleDelayedForbiddenType(*this, diag
, decl
);
9762 } while ((pool
= pool
->getParent()));
9765 /// Given a set of delayed diagnostics, re-emit them as if they had
9766 /// been delayed in the current context instead of in the given pool.
9767 /// Essentially, this just moves them to the current pool.
9768 void Sema::redelayDiagnostics(DelayedDiagnosticPool
&pool
) {
9769 DelayedDiagnosticPool
*curPool
= DelayedDiagnostics
.getCurrentPool();
9770 assert(curPool
&& "re-emitting in undelayed context not supported");
9771 curPool
->steal(pool
);