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