Coverage Report

Created: 2020-02-25 14:32

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp
Line
Count
Source (jump to first uncovered line)
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/Basic/CharInfo.h"
25
#include "clang/Basic/SourceManager.h"
26
#include "clang/Basic/TargetBuiltins.h"
27
#include "clang/Basic/TargetInfo.h"
28
#include "clang/Lex/Preprocessor.h"
29
#include "clang/Sema/DeclSpec.h"
30
#include "clang/Sema/DelayedDiagnostic.h"
31
#include "clang/Sema/Initialization.h"
32
#include "clang/Sema/Lookup.h"
33
#include "clang/Sema/Scope.h"
34
#include "clang/Sema/ScopeInfo.h"
35
#include "clang/Sema/SemaInternal.h"
36
#include "llvm/ADT/STLExtras.h"
37
#include "llvm/ADT/StringExtras.h"
38
#include "llvm/Support/MathExtras.h"
39
40
using namespace clang;
41
using namespace sema;
42
43
namespace AttributeLangSupport {
44
  enum LANG {
45
    C,
46
    Cpp,
47
    ObjC
48
  };
49
} // end namespace AttributeLangSupport
50
51
//===----------------------------------------------------------------------===//
52
//  Helper functions
53
//===----------------------------------------------------------------------===//
54
55
/// isFunctionOrMethod - Return true if the given decl has function
56
/// type (function or function-typed variable) or an Objective-C
57
/// method.
58
35.2k
static bool isFunctionOrMethod(const Decl *D) {
59
35.2k
  return (D->getFunctionType() != nullptr) || 
isa<ObjCMethodDecl>(D)313
;
60
35.2k
}
61
62
/// Return true if the given decl has function type (function or
63
/// function-typed variable) or an Objective-C method or a block.
64
35.0k
static bool isFunctionOrMethodOrBlock(const Decl *D) {
65
35.0k
  return isFunctionOrMethod(D) || 
isa<BlockDecl>(D)1
;
66
35.0k
}
67
68
/// Return true if the given decl has a declarator that should have
69
/// been processed by Sema::GetTypeForDeclarator.
70
15.2k
static bool hasDeclarator(const Decl *D) {
71
15.2k
  // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
72
15.2k
  return isa<DeclaratorDecl>(D) || 
isa<BlockDecl>(D)359
||
isa<TypedefNameDecl>(D)350
||
73
15.2k
         
isa<ObjCPropertyDecl>(D)205
;
74
15.2k
}
75
76
/// hasFunctionProto - Return true if the given decl has a argument
77
/// information. This decl should have already passed
78
/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
79
35.2k
static bool hasFunctionProto(const Decl *D) {
80
35.2k
  if (const FunctionType *FnTy = D->getFunctionType())
81
34.9k
    return isa<FunctionProtoType>(FnTy);
82
297
  return isa<ObjCMethodDecl>(D) || 
isa<BlockDecl>(D)1
;
83
297
}
84
85
/// getFunctionOrMethodNumParams - Return number of function or method
86
/// parameters. It is an error to call this on a K&R function (use
87
/// hasFunctionProto first).
88
99.3k
static unsigned getFunctionOrMethodNumParams(const Decl *D) {
89
99.3k
  if (const FunctionType *FnTy = D->getFunctionType())
90
95.5k
    return cast<FunctionProtoType>(FnTy)->getNumParams();
91
3.82k
  if (const auto *BD = dyn_cast<BlockDecl>(D))
92
17
    return BD->getNumParams();
93
3.80k
  return cast<ObjCMethodDecl>(D)->param_size();
94
3.80k
}
95
96
static const ParmVarDecl *getFunctionOrMethodParam(const Decl *D,
97
28.2k
                                                   unsigned Idx) {
98
28.2k
  if (const auto *FD = dyn_cast<FunctionDecl>(D))
99
28.1k
    return FD->getParamDecl(Idx);
100
55
  if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
101
23
    return MD->getParamDecl(Idx);
102
32
  if (const auto *BD = dyn_cast<BlockDecl>(D))
103
16
    return BD->getParamDecl(Idx);
104
16
  return nullptr;
105
16
}
106
107
65.2k
static QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx) {
108
65.2k
  if (const FunctionType *FnTy = D->getFunctionType())
109
61.4k
    return cast<FunctionProtoType>(FnTy)->getParamType(Idx);
110
3.79k
  if (const auto *BD = dyn_cast<BlockDecl>(D))
111
8
    return BD->getParamDecl(Idx)->getType();
112
3.78k
113
3.78k
  return cast<ObjCMethodDecl>(D)->parameters()[Idx]->getType();
114
3.78k
}
115
116
28.1k
static SourceRange getFunctionOrMethodParamRange(const Decl *D, unsigned Idx) {
117
28.1k
  if (auto *PVD = getFunctionOrMethodParam(D, Idx))
118
28.1k
    return PVD->getSourceRange();
119
16
  return SourceRange();
120
16
}
121
122
6.23k
static QualType getFunctionOrMethodResultType(const Decl *D) {
123
6.23k
  if (const FunctionType *FnTy = D->getFunctionType())
124
5.93k
    return FnTy->getReturnType();
125
299
  return cast<ObjCMethodDecl>(D)->getReturnType();
126
299
}
127
128
80
static SourceRange getFunctionOrMethodResultSourceRange(const Decl *D) {
129
80
  if (const auto *FD = dyn_cast<FunctionDecl>(D))
130
76
    return FD->getReturnTypeSourceRange();
131
4
  if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
132
4
    return MD->getReturnTypeSourceRange();
133
0
  return SourceRange();
134
0
}
135
136
53.2k
static bool isFunctionOrMethodVariadic(const Decl *D) {
137
53.2k
  if (const FunctionType *FnTy = D->getFunctionType())
138
50.2k
    return cast<FunctionProtoType>(FnTy)->isVariadic();
139
2.92k
  if (const auto *BD = dyn_cast<BlockDecl>(D))
140
6
    return BD->isVariadic();
141
2.92k
  return cast<ObjCMethodDecl>(D)->isVariadic();
142
2.92k
}
143
144
71.0k
static bool isInstanceMethod(const Decl *D) {
145
71.0k
  if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(D))
146
243
    return MethodDecl->isInstance();
147
70.8k
  return false;
148
70.8k
}
149
150
6.15k
static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
151
6.15k
  const auto *PT = T->getAs<ObjCObjectPointerType>();
152
6.15k
  if (!PT)
153
1.40k
    return false;
154
4.75k
155
4.75k
  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
156
4.75k
  if (!Cls)
157
0
    return false;
158
4.75k
159
4.75k
  IdentifierInfo* ClsName = Cls->getIdentifier();
160
4.75k
161
4.75k
  // FIXME: Should we walk the chain of classes?
162
4.75k
  return ClsName == &Ctx.Idents.get("NSString") ||
163
4.75k
         
ClsName == &Ctx.Idents.get("NSMutableString")0
;
164
4.75k
}
165
166
2.57k
static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
167
2.57k
  const auto *PT = T->getAs<PointerType>();
168
2.57k
  if (!PT)
169
3
    return false;
170
2.57k
171
2.57k
  const auto *RT = PT->getPointeeType()->getAs<RecordType>();
172
2.57k
  if (!RT)
173
523
    return false;
174
2.05k
175
2.05k
  const RecordDecl *RD = RT->getDecl();
176
2.05k
  if (RD->getTagKind() != TTK_Struct)
177
0
    return false;
178
2.05k
179
2.05k
  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
180
2.05k
}
181
182
18.5M
static unsigned getNumAttributeArgs(const ParsedAttr &AL) {
183
18.5M
  // FIXME: Include the type in the argument list.
184
18.5M
  return AL.getNumArgs() + AL.hasParsedType();
185
18.5M
}
186
187
template <typename Compare>
188
static bool checkAttributeNumArgsImpl(Sema &S, const ParsedAttr &AL,
189
                                      unsigned Num, unsigned Diag,
190
18.5M
                                      Compare Comp) {
191
18.5M
  if (Comp(getNumAttributeArgs(AL), Num)) {
192
319
    S.Diag(AL.getLoc(), Diag) << AL << Num;
193
319
    return false;
194
319
  }
195
18.5M
196
18.5M
  return true;
197
18.5M
}
SemaDeclAttr.cpp:bool checkAttributeNumArgsImpl<std::__1::not_equal_to<unsigned int> >(clang::Sema&, clang::ParsedAttr const&, unsigned int, unsigned int, std::__1::not_equal_to<unsigned int>)
Line
Count
Source
190
18.3M
                                      Compare Comp) {
191
18.3M
  if (Comp(getNumAttributeArgs(AL), Num)) {
192
252
    S.Diag(AL.getLoc(), Diag) << AL << Num;
193
252
    return false;
194
252
  }
195
18.3M
196
18.3M
  return true;
197
18.3M
}
SemaDeclAttr.cpp:bool checkAttributeNumArgsImpl<std::__1::less<unsigned int> >(clang::Sema&, clang::ParsedAttr const&, unsigned int, unsigned int, std::__1::less<unsigned int>)
Line
Count
Source
190
17.3k
                                      Compare Comp) {
191
17.3k
  if (Comp(getNumAttributeArgs(AL), Num)) {
192
48
    S.Diag(AL.getLoc(), Diag) << AL << Num;
193
48
    return false;
194
48
  }
195
17.3k
196
17.3k
  return true;
197
17.3k
}
SemaDeclAttr.cpp:bool checkAttributeNumArgsImpl<std::__1::greater<unsigned int> >(clang::Sema&, clang::ParsedAttr const&, unsigned int, unsigned int, std::__1::greater<unsigned int>)
Line
Count
Source
190
104k
                                      Compare Comp) {
191
104k
  if (Comp(getNumAttributeArgs(AL), Num)) {
192
19
    S.Diag(AL.getLoc(), Diag) << AL << Num;
193
19
    return false;
194
19
  }
195
104k
196
104k
  return true;
197
104k
}
198
199
/// Check if the attribute has exactly as many args as Num. May
200
/// output an error.
201
18.3M
static bool checkAttributeNumArgs(Sema &S, const ParsedAttr &AL, unsigned Num) {
202
18.3M
  return checkAttributeNumArgsImpl(S, AL, Num,
203
18.3M
                                   diag::err_attribute_wrong_number_arguments,
204
18.3M
                                   std::not_equal_to<unsigned>());
205
18.3M
}
206
207
/// Check if the attribute has at least as many args as Num. May
208
/// output an error.
209
static bool checkAttributeAtLeastNumArgs(Sema &S, const ParsedAttr &AL,
210
17.3k
                                         unsigned Num) {
211
17.3k
  return checkAttributeNumArgsImpl(S, AL, Num,
212
17.3k
                                   diag::err_attribute_too_few_arguments,
213
17.3k
                                   std::less<unsigned>());
214
17.3k
}
215
216
/// Check if the attribute has at most as many args as Num. May
217
/// output an error.
218
static bool checkAttributeAtMostNumArgs(Sema &S, const ParsedAttr &AL,
219
104k
                                        unsigned Num) {
220
104k
  return checkAttributeNumArgsImpl(S, AL, Num,
221
104k
                                   diag::err_attribute_too_many_arguments,
222
104k
                                   std::greater<unsigned>());
223
104k
}
224
225
/// A helper function to provide Attribute Location for the Attr types
226
/// AND the ParsedAttr.
227
template <typename AttrInfo>
228
static std::enable_if_t<std::is_base_of<Attr, AttrInfo>::value, SourceLocation>
229
23
getAttrLoc(const AttrInfo &AL) {
230
23
  return AL.getLocation();
231
23
}
SemaDeclAttr.cpp:std::__1::enable_if<std::is_base_of<clang::Attr, clang::AMDGPUFlatWorkGroupSizeAttr>::value, clang::SourceLocation>::type getAttrLoc<clang::AMDGPUFlatWorkGroupSizeAttr>(clang::AMDGPUFlatWorkGroupSizeAttr const&)
Line
Count
Source
229
9
getAttrLoc(const AttrInfo &AL) {
230
9
  return AL.getLocation();
231
9
}
SemaDeclAttr.cpp:std::__1::enable_if<std::is_base_of<clang::Attr, clang::AMDGPUWavesPerEUAttr>::value, clang::SourceLocation>::type getAttrLoc<clang::AMDGPUWavesPerEUAttr>(clang::AMDGPUWavesPerEUAttr const&)
Line
Count
Source
229
9
getAttrLoc(const AttrInfo &AL) {
230
9
  return AL.getLocation();
231
9
}
SemaDeclAttr.cpp:std::__1::enable_if<std::is_base_of<clang::Attr, clang::AllocAlignAttr>::value, clang::SourceLocation>::type getAttrLoc<clang::AllocAlignAttr>(clang::AllocAlignAttr const&)
Line
Count
Source
229
5
getAttrLoc(const AttrInfo &AL) {
230
5
  return AL.getLocation();
231
5
}
232
72
static SourceLocation getAttrLoc(const ParsedAttr &AL) { return AL.getLoc(); }
233
234
/// If Expr is a valid integer constant, get the value of the integer
235
/// expression and return success or failure. May output an error.
236
///
237
/// Negative argument is implicitly converted to unsigned, unless
238
/// \p StrictlyUnsigned is true.
239
template <typename AttrInfo>
240
static bool checkUInt32Argument(Sema &S, const AttrInfo &AI, const Expr *Expr,
241
                                uint32_t &Val, unsigned Idx = UINT_MAX,
242
993k
                                bool StrictlyUnsigned = false) {
243
993k
  llvm::APSInt I(32);
244
993k
  if (Expr->isTypeDependent() || Expr->isValueDependent() ||
245
993k
      !Expr->isIntegerConstantExpr(I, S.Context)) {
246
31
    if (Idx != UINT_MAX)
247
31
      S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
248
22
          << &AI << Idx << AANT_ArgumentIntegerConstant
249
22
          << Expr->getSourceRange();
250
9
    else
251
9
      S.Diag(getAttrLoc(AI), diag::err_attribute_argument_type)
252
9
          << &AI << AANT_ArgumentIntegerConstant << Expr->getSourceRange();
253
31
    return false;
254
31
  }
255
993k
256
993k
  if (!I.isIntN(32)) {
257
10
    S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
258
10
        << I.toString(10, false) << 32 << /* Unsigned */ 1;
259
10
    return false;
260
10
  }
261
993k
262
993k
  if (StrictlyUnsigned && 
I.isSigned()86
&&
I.isNegative()86
) {
263
3
    S.Diag(getAttrLoc(AI), diag::err_attribute_requires_positive_integer)
264
3
        << &AI << /*non-negative*/ 1;
265
3
    return false;
266
3
  }
267
993k
268
993k
  Val = (uint32_t)I.getZExtValue();
269
993k
  return true;
270
993k
}
SemaDeclAttr.cpp:bool checkUInt32Argument<clang::AMDGPUFlatWorkGroupSizeAttr>(clang::Sema&, clang::AMDGPUFlatWorkGroupSizeAttr const&, clang::Expr const*, unsigned int&, unsigned int, bool)
Line
Count
Source
242
205
                                bool StrictlyUnsigned = false) {
243
205
  llvm::APSInt I(32);
244
205
  if (Expr->isTypeDependent() || Expr->isValueDependent() ||
245
205
      !Expr->isIntegerConstantExpr(I, S.Context)) {
246
9
    if (Idx != UINT_MAX)
247
9
      S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
248
9
          << &AI << Idx << AANT_ArgumentIntegerConstant
249
9
          << Expr->getSourceRange();
250
0
    else
251
0
      S.Diag(getAttrLoc(AI), diag::err_attribute_argument_type)
252
0
          << &AI << AANT_ArgumentIntegerConstant << Expr->getSourceRange();
253
9
    return false;
254
9
  }
255
196
256
196
  if (!I.isIntN(32)) {
257
3
    S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
258
3
        << I.toString(10, false) << 32 << /* Unsigned */ 1;
259
3
    return false;
260
3
  }
261
193
262
193
  if (StrictlyUnsigned && 
I.isSigned()0
&&
I.isNegative()0
) {
263
0
    S.Diag(getAttrLoc(AI), diag::err_attribute_requires_positive_integer)
264
0
        << &AI << /*non-negative*/ 1;
265
0
    return false;
266
0
  }
267
193
268
193
  Val = (uint32_t)I.getZExtValue();
269
193
  return true;
270
193
}
SemaDeclAttr.cpp:bool checkUInt32Argument<clang::AMDGPUWavesPerEUAttr>(clang::Sema&, clang::AMDGPUWavesPerEUAttr const&, clang::Expr const*, unsigned int&, unsigned int, bool)
Line
Count
Source
242
192
                                bool StrictlyUnsigned = false) {
243
192
  llvm::APSInt I(32);
244
192
  if (Expr->isTypeDependent() || Expr->isValueDependent() ||
245
192
      !Expr->isIntegerConstantExpr(I, S.Context)) {
246
9
    if (Idx != UINT_MAX)
247
9
      S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
248
9
          << &AI << Idx << AANT_ArgumentIntegerConstant
249
9
          << Expr->getSourceRange();
250
0
    else
251
0
      S.Diag(getAttrLoc(AI), diag::err_attribute_argument_type)
252
0
          << &AI << AANT_ArgumentIntegerConstant << Expr->getSourceRange();
253
9
    return false;
254
9
  }
255
183
256
183
  if (!I.isIntN(32)) {
257
3
    S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
258
3
        << I.toString(10, false) << 32 << /* Unsigned */ 1;
259
3
    return false;
260
3
  }
261
180
262
180
  if (StrictlyUnsigned && 
I.isSigned()0
&&
I.isNegative()0
) {
263
0
    S.Diag(getAttrLoc(AI), diag::err_attribute_requires_positive_integer)
264
0
        << &AI << /*non-negative*/ 1;
265
0
    return false;
266
0
  }
267
180
268
180
  Val = (uint32_t)I.getZExtValue();
269
180
  return true;
270
180
}
SemaDeclAttr.cpp:bool checkUInt32Argument<clang::ParsedAttr>(clang::Sema&, clang::ParsedAttr const&, clang::Expr const*, unsigned int&, unsigned int, bool)
Line
Count
Source
242
993k
                                bool StrictlyUnsigned = false) {
243
993k
  llvm::APSInt I(32);
244
993k
  if (Expr->isTypeDependent() || Expr->isValueDependent() ||
245
993k
      !Expr->isIntegerConstantExpr(I, S.Context)) {
246
13
    if (Idx != UINT_MAX)
247
13
      S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
248
4
          << &AI << Idx << AANT_ArgumentIntegerConstant
249
4
          << Expr->getSourceRange();
250
9
    else
251
9
      S.Diag(getAttrLoc(AI), diag::err_attribute_argument_type)
252
9
          << &AI << AANT_ArgumentIntegerConstant << Expr->getSourceRange();
253
13
    return false;
254
13
  }
255
993k
256
993k
  if (!I.isIntN(32)) {
257
4
    S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
258
4
        << I.toString(10, false) << 32 << /* Unsigned */ 1;
259
4
    return false;
260
4
  }
261
993k
262
993k
  if (StrictlyUnsigned && 
I.isSigned()86
&&
I.isNegative()86
) {
263
3
    S.Diag(getAttrLoc(AI), diag::err_attribute_requires_positive_integer)
264
3
        << &AI << /*non-negative*/ 1;
265
3
    return false;
266
3
  }
267
993k
268
993k
  Val = (uint32_t)I.getZExtValue();
269
993k
  return true;
270
993k
}
271
272
/// Wrapper around checkUInt32Argument, with an extra check to be sure
273
/// that the result will fit into a regular (signed) int. All args have the same
274
/// purpose as they do in checkUInt32Argument.
275
template <typename AttrInfo>
276
static bool checkPositiveIntArgument(Sema &S, const AttrInfo &AI, const Expr *Expr,
277
5.67k
                                     int &Val, unsigned Idx = UINT_MAX) {
278
5.67k
  uint32_t UVal;
279
5.67k
  if (!checkUInt32Argument(S, AI, Expr, UVal, Idx))
280
2
    return false;
281
5.67k
282
5.67k
  if (UVal > (uint32_t)std::numeric_limits<int>::max()) {
283
1
    llvm::APSInt I(32); // for toString
284
1
    I = UVal;
285
1
    S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
286
1
        << I.toString(10, false) << 32 << /* Unsigned */ 0;
287
1
    return false;
288
1
  }
289
5.67k
290
5.67k
  Val = UVal;
291
5.67k
  return true;
292
5.67k
}
293
294
/// Diagnose mutually exclusive attributes when present on a given
295
/// declaration. Returns true if diagnosed.
296
template <typename AttrTy>
297
1.41M
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
1.41M
  if (const auto *A = D->getAttr<AttrTy>()) {
299
53
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
53
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
53
    return true;
302
53
  }
303
1.41M
  return false;
304
1.41M
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::Mips16Attr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
28
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
28
  if (const auto *A = D->getAttr<AttrTy>()) {
299
4
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
4
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
4
    return true;
302
4
  }
303
24
  return false;
304
24
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::MicroMipsAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
11
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
11
  if (const auto *A = D->getAttr<AttrTy>()) {
299
1
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
1
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
1
    return true;
302
1
  }
303
10
  return false;
304
10
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::MipsInterruptAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
10
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
10
  if (const auto *A = D->getAttr<AttrTy>()) {
299
2
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
2
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
2
    return true;
302
2
  }
303
8
  return false;
304
8
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::MipsShortCallAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
16
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
16
  if (const auto *A = D->getAttr<AttrTy>()) {
299
2
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
2
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
2
    return true;
302
2
  }
303
14
  return false;
304
14
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::MipsLongCallAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
16
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
16
  if (const auto *A = D->getAttr<AttrTy>()) {
299
2
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
2
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
2
    return true;
302
2
  }
303
14
  return false;
304
14
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::NotTailCalledAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
1.40M
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
1.40M
  if (const auto *A = D->getAttr<AttrTy>()) {
299
1
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
1
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
1
    return true;
302
1
  }
303
1.40M
  return false;
304
1.40M
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::CUDASharedAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
155
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
155
  if (const auto *A = D->getAttr<AttrTy>()) {
299
2
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
2
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
2
    return true;
302
2
  }
303
153
  return false;
304
153
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::CUDADeviceAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
247
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
247
  if (const auto *A = D->getAttr<AttrTy>()) {
299
4
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
4
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
4
    return true;
302
4
  }
303
243
  return false;
304
243
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::CUDAHostAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
235
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
235
  if (const auto *A = D->getAttr<AttrTy>()) {
299
2
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
2
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
2
    return true;
302
2
  }
303
233
  return false;
304
233
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::CUDAGlobalAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
2.35k
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
2.35k
  if (const auto *A = D->getAttr<AttrTy>()) {
299
4
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
4
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
4
    return true;
302
4
  }
303
2.34k
  return false;
304
2.34k
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::CUDAConstantAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
232
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
232
  if (const auto *A = D->getAttr<AttrTy>()) {
299
6
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
6
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
6
    return true;
302
6
  }
303
226
  return false;
304
226
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::HotAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
26
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
26
  if (const auto *A = D->getAttr<AttrTy>()) {
299
1
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
1
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
1
    return true;
302
1
  }
303
25
  return false;
304
25
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::ColdAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
3
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
3
  if (const auto *A = D->getAttr<AttrTy>()) {
299
1
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
1
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
1
    return true;
302
1
  }
303
2
  return false;
304
2
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::DisableTailCallsAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
31
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
31
  if (const auto *A = D->getAttr<AttrTy>()) {
299
1
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
1
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
1
    return true;
302
1
  }
303
30
  return false;
304
30
}
Unexecuted instantiation: SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::CFUnknownTransferAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::CFAuditedTransferAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
1
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
1
  if (const auto *A = D->getAttr<AttrTy>()) {
299
0
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
0
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
0
    return true;
302
0
  }
303
1
  return false;
304
1
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::NoSpeculativeLoadHardeningAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
27
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
27
  if (const auto *A = D->getAttr<AttrTy>()) {
299
2
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
2
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
2
    return true;
302
2
  }
303
25
  return false;
304
25
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::SpeculativeLoadHardeningAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
27
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
27
  if (const auto *A = D->getAttr<AttrTy>()) {
299
2
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
2
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
2
    return true;
302
2
  }
303
25
  return false;
304
25
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::AlwaysInlineAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
673
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
673
  if (const auto *A = D->getAttr<AttrTy>()) {
299
1
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
1
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
1
    return true;
302
1
  }
303
672
  return false;
304
672
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::NakedAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
382
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
382
  if (const auto *A = D->getAttr<AttrTy>()) {
299
1
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
1
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
1
    return true;
302
1
  }
303
381
  return false;
304
381
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::PointerAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
26
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
26
  if (const auto *A = D->getAttr<AttrTy>()) {
299
1
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
1
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
1
    return true;
302
1
  }
303
25
  return false;
304
25
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::OwnerAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
14
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
14
  if (const auto *A = D->getAttr<AttrTy>()) {
299
1
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
1
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
1
    return true;
302
1
  }
303
13
  return false;
304
13
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::NoDestroyAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
28
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
28
  if (const auto *A = D->getAttr<AttrTy>()) {
299
4
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
4
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
4
    return true;
302
4
  }
303
24
  return false;
304
24
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::AlwaysDestroyAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
42
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
42
  if (const auto *A = D->getAttr<AttrTy>()) {
299
4
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
4
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
4
    return true;
302
4
  }
303
38
  return false;
304
38
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::InternalLinkageAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
8
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
8
  if (const auto *A = D->getAttr<AttrTy>()) {
299
1
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
1
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
1
    return true;
302
1
  }
303
7
  return false;
304
7
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::CommonAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
297
1.16k
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
298
1.16k
  if (const auto *A = D->getAttr<AttrTy>()) {
299
3
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
300
3
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
301
3
    return true;
302
3
  }
303
1.16k
  return false;
304
1.16k
}
305
306
template <typename AttrTy>
307
11
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const Attr &AL) {
308
11
  if (const auto *A = D->getAttr<AttrTy>()) {
309
4
    S.Diag(AL.getLocation(), diag::err_attributes_are_not_compatible) << &AL
310
4
                                                                      << A;
311
4
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
312
4
    return true;
313
4
  }
314
7
  return false;
315
7
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::InternalLinkageAttr>(clang::Sema&, clang::Decl*, clang::Attr const&)
Line
Count
Source
307
1
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const Attr &AL) {
308
1
  if (const auto *A = D->getAttr<AttrTy>()) {
309
1
    S.Diag(AL.getLocation(), diag::err_attributes_are_not_compatible) << &AL
310
1
                                                                      << A;
311
1
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
312
1
    return true;
313
1
  }
314
0
  return false;
315
0
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::CommonAttr>(clang::Sema&, clang::Decl*, clang::Attr const&)
Line
Count
Source
307
8
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const Attr &AL) {
308
8
  if (const auto *A = D->getAttr<AttrTy>()) {
309
1
    S.Diag(AL.getLocation(), diag::err_attributes_are_not_compatible) << &AL
310
1
                                                                      << A;
311
1
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
312
1
    return true;
313
1
  }
314
7
  return false;
315
7
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::SpeculativeLoadHardeningAttr>(clang::Sema&, clang::Decl*, clang::Attr const&)
Line
Count
Source
307
1
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const Attr &AL) {
308
1
  if (const auto *A = D->getAttr<AttrTy>()) {
309
1
    S.Diag(AL.getLocation(), diag::err_attributes_are_not_compatible) << &AL
310
1
                                                                      << A;
311
1
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
312
1
    return true;
313
1
  }
314
0
  return false;
315
0
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::NoSpeculativeLoadHardeningAttr>(clang::Sema&, clang::Decl*, clang::Attr const&)
Line
Count
Source
307
1
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const Attr &AL) {
308
1
  if (const auto *A = D->getAttr<AttrTy>()) {
309
1
    S.Diag(AL.getLocation(), diag::err_attributes_are_not_compatible) << &AL
310
1
                                                                      << A;
311
1
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
312
1
    return true;
313
1
  }
314
0
  return false;
315
0
}
316
317
/// Check if IdxExpr is a valid parameter index for a function or
318
/// instance method D.  May output an error.
319
///
320
/// \returns true if IdxExpr is a valid index.
321
template <typename AttrInfo>
322
static bool checkFunctionOrMethodParameterIndex(
323
    Sema &S, const Decl *D, const AttrInfo &AI, unsigned AttrArgNum,
324
35.0k
    const Expr *IdxExpr, ParamIdx &Idx, bool CanIndexImplicitThis = false) {
325
35.0k
  assert(isFunctionOrMethodOrBlock(D));
326
35.0k
327
35.0k
  // In C++ the implicit 'this' function parameter also counts.
328
35.0k
  // Parameters are counted from one.
329
35.0k
  bool HP = hasFunctionProto(D);
330
35.0k
  bool HasImplicitThisParam = isInstanceMethod(D);
331
35.0k
  bool IV = HP && 
isFunctionOrMethodVariadic(D)35.0k
;
332
35.0k
  unsigned NumParams =
333
35.0k
      (HP ? 
getFunctionOrMethodNumParams(D)35.0k
:
03
) + HasImplicitThisParam;
334
35.0k
335
35.0k
  llvm::APSInt IdxInt;
336
35.0k
  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
337
35.0k
      
!IdxExpr->isIntegerConstantExpr(IdxInt, S.Context)35.0k
) {
338
13
    S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
339
13
        << &AI << AttrArgNum << AANT_ArgumentIntegerConstant
340
13
        << IdxExpr->getSourceRange();
341
13
    return false;
342
13
  }
343
35.0k
344
35.0k
  unsigned IdxSource = IdxInt.getLimitedValue(UINT_MAX);
345
35.0k
  if (IdxSource < 1 || 
(35.0k
!IV35.0k
&&
IdxSource > NumParams34.6k
)) {
346
42
    S.Diag(getAttrLoc(AI), diag::err_attribute_argument_out_of_bounds)
347
42
        << &AI << AttrArgNum << IdxExpr->getSourceRange();
348
42
    return false;
349
42
  }
350
35.0k
  if (HasImplicitThisParam && 
!CanIndexImplicitThis72
) {
351
69
    if (IdxSource == 1) {
352
5
      S.Diag(getAttrLoc(AI), diag::err_attribute_invalid_implicit_this_argument)
353
5
          << &AI << IdxExpr->getSourceRange();
354
5
      return false;
355
5
    }
356
35.0k
  }
357
35.0k
358
35.0k
  Idx = ParamIdx(IdxSource, D);
359
35.0k
  return true;
360
35.0k
}
SemaDeclAttr.cpp:bool checkFunctionOrMethodParameterIndex<clang::ParsedAttr>(clang::Sema&, clang::Decl const*, clang::ParsedAttr const&, unsigned int, clang::Expr const*, clang::ParamIdx&, bool)
Line
Count
Source
324
35.0k
    const Expr *IdxExpr, ParamIdx &Idx, bool CanIndexImplicitThis = false) {
325
35.0k
  assert(isFunctionOrMethodOrBlock(D));
326
35.0k
327
35.0k
  // In C++ the implicit 'this' function parameter also counts.
328
35.0k
  // Parameters are counted from one.
329
35.0k
  bool HP = hasFunctionProto(D);
330
35.0k
  bool HasImplicitThisParam = isInstanceMethod(D);
331
35.0k
  bool IV = HP && 
isFunctionOrMethodVariadic(D)35.0k
;
332
35.0k
  unsigned NumParams =
333
35.0k
      (HP ? 
getFunctionOrMethodNumParams(D)35.0k
:
03
) + HasImplicitThisParam;
334
35.0k
335
35.0k
  llvm::APSInt IdxInt;
336
35.0k
  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
337
35.0k
      
!IdxExpr->isIntegerConstantExpr(IdxInt, S.Context)35.0k
) {
338
11
    S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
339
11
        << &AI << AttrArgNum << AANT_ArgumentIntegerConstant
340
11
        << IdxExpr->getSourceRange();
341
11
    return false;
342
11
  }
343
35.0k
344
35.0k
  unsigned IdxSource = IdxInt.getLimitedValue(UINT_MAX);
345
35.0k
  if (IdxSource < 1 || 
(35.0k
!IV35.0k
&&
IdxSource > NumParams34.6k
)) {
346
40
    S.Diag(getAttrLoc(AI), diag::err_attribute_argument_out_of_bounds)
347
40
        << &AI << AttrArgNum << IdxExpr->getSourceRange();
348
40
    return false;
349
40
  }
350
34.9k
  if (HasImplicitThisParam && 
!CanIndexImplicitThis61
) {
351
58
    if (IdxSource == 1) {
352
4
      S.Diag(getAttrLoc(AI), diag::err_attribute_invalid_implicit_this_argument)
353
4
          << &AI << IdxExpr->getSourceRange();
354
4
      return false;
355
4
    }
356
34.9k
  }
357
34.9k
358
34.9k
  Idx = ParamIdx(IdxSource, D);
359
34.9k
  return true;
360
34.9k
}
SemaDeclAttr.cpp:bool checkFunctionOrMethodParameterIndex<clang::AllocAlignAttr>(clang::Sema&, clang::Decl const*, clang::AllocAlignAttr const&, unsigned int, clang::Expr const*, clang::ParamIdx&, bool)
Line
Count
Source
324
42
    const Expr *IdxExpr, ParamIdx &Idx, bool CanIndexImplicitThis = false) {
325
42
  assert(isFunctionOrMethodOrBlock(D));
326
42
327
42
  // In C++ the implicit 'this' function parameter also counts.
328
42
  // Parameters are counted from one.
329
42
  bool HP = hasFunctionProto(D);
330
42
  bool HasImplicitThisParam = isInstanceMethod(D);
331
42
  bool IV = HP && isFunctionOrMethodVariadic(D);
332
42
  unsigned NumParams =
333
42
      (HP ? getFunctionOrMethodNumParams(D) : 
00
) + HasImplicitThisParam;
334
42
335
42
  llvm::APSInt IdxInt;
336
42
  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
337
42
      
!IdxExpr->isIntegerConstantExpr(IdxInt, S.Context)41
) {
338
2
    S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
339
2
        << &AI << AttrArgNum << AANT_ArgumentIntegerConstant
340
2
        << IdxExpr->getSourceRange();
341
2
    return false;
342
2
  }
343
40
344
40
  unsigned IdxSource = IdxInt.getLimitedValue(UINT_MAX);
345
40
  if (IdxSource < 1 || 
(39
!IV39
&&
IdxSource > NumParams39
)) {
346
2
    S.Diag(getAttrLoc(AI), diag::err_attribute_argument_out_of_bounds)
347
2
        << &AI << AttrArgNum << IdxExpr->getSourceRange();
348
2
    return false;
349
2
  }
350
38
  if (HasImplicitThisParam && 
!CanIndexImplicitThis11
) {
351
11
    if (IdxSource == 1) {
352
1
      S.Diag(getAttrLoc(AI), diag::err_attribute_invalid_implicit_this_argument)
353
1
          << &AI << IdxExpr->getSourceRange();
354
1
      return false;
355
1
    }
356
37
  }
357
37
358
37
  Idx = ParamIdx(IdxSource, D);
359
37
  return true;
360
37
}
361
362
/// Check if the argument \p ArgNum of \p Attr is a ASCII string literal.
363
/// If not emit an error and return false. If the argument is an identifier it
364
/// will emit an error with a fixit hint and treat it as if it was a string
365
/// literal.
366
bool Sema::checkStringLiteralArgumentAttr(const ParsedAttr &AL, unsigned ArgNum,
367
                                          StringRef &Str,
368
2.37M
                                          SourceLocation *ArgLocation) {
369
2.37M
  // Look for identifiers. If we have one emit a hint to fix it to a literal.
370
2.37M
  if (AL.isArgIdent(ArgNum)) {
371
11
    IdentifierLoc *Loc = AL.getArgAsIdent(ArgNum);
372
11
    Diag(Loc->Loc, diag::err_attribute_argument_type)
373
11
        << AL << AANT_ArgumentString
374
11
        << FixItHint::CreateInsertion(Loc->Loc, "\"")
375
11
        << FixItHint::CreateInsertion(getLocForEndOfToken(Loc->Loc), "\"");
376
11
    Str = Loc->Ident->getName();
377
11
    if (ArgLocation)
378
8
      *ArgLocation = Loc->Loc;
379
11
    return true;
380
11
  }
381
2.37M
382
2.37M
  // Now check for an actual string literal.
383
2.37M
  Expr *ArgExpr = AL.getArgAsExpr(ArgNum);
384
2.37M
  const auto *Literal = dyn_cast<StringLiteral>(ArgExpr->IgnoreParenCasts());
385
2.37M
  if (ArgLocation)
386
2.33M
    *ArgLocation = ArgExpr->getBeginLoc();
387
2.37M
388
2.37M
  if (!Literal || 
!Literal->isAscii()2.37M
) {
389
25
    Diag(ArgExpr->getBeginLoc(), diag::err_attribute_argument_type)
390
25
        << AL << AANT_ArgumentString;
391
25
    return false;
392
25
  }
393
2.37M
394
2.37M
  Str = Literal->getString();
395
2.37M
  return true;
396
2.37M
}
397
398
/// Applies the given attribute to the Decl without performing any
399
/// additional semantic checking.
400
template <typename AttrType>
401
static void handleSimpleAttribute(Sema &S, Decl *D,
402
2.24M
                                  const AttributeCommonInfo &CI) {
403
2.24M
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
2.24M
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::AVRInterruptAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
2
                                  const AttributeCommonInfo &CI) {
403
2
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
2
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::Mips16Attr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
8
                                  const AttributeCommonInfo &CI) {
403
8
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
8
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NoMips16Attr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
4
                                  const AttributeCommonInfo &CI) {
403
4
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
4
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::MicroMipsAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
3
                                  const AttributeCommonInfo &CI) {
403
3
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
3
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NoMicroMipsAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
2
                                  const AttributeCommonInfo &CI) {
403
2
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
2
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::MipsLongCallAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
14
                                  const AttributeCommonInfo &CI) {
403
14
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
14
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::MipsShortCallAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
14
                                  const AttributeCommonInfo &CI) {
403
14
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
14
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::AVRSignalAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
2
                                  const AttributeCommonInfo &CI) {
403
2
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
2
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::IBActionAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
355
                                  const AttributeCommonInfo &CI) {
403
355
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
355
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ArtificialAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
6.90k
                                  const AttributeCommonInfo &CI) {
403
6.90k
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
6.90k
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::CXX11NoReturnAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
9.44k
                                  const AttributeCommonInfo &CI) {
403
9.44k
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
9.44k
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::FlagEnumAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
34.8k
                                  const AttributeCommonInfo &CI) {
403
34.8k
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
34.8k
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::FlattenAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
10
                                  const AttributeCommonInfo &CI) {
403
10
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
10
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::SYCLKernelAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
4
                                  const AttributeCommonInfo &CI) {
403
4
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
4
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::CUDADeviceAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
1.62k
                                  const AttributeCommonInfo &CI) {
403
1.62k
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
1.62k
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::CUDAHostAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
726
                                  const AttributeCommonInfo &CI) {
403
726
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
726
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::HIPPinnedShadowAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
6
                                  const AttributeCommonInfo &CI) {
403
6
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
6
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::LifetimeBoundAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
11
                                  const AttributeCommonInfo &CI) {
403
11
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
11
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::MayAliasAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
23.7k
                                  const AttributeCommonInfo &CI) {
403
23.7k
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
23.7k
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NoAliasAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
2
                                  const AttributeCommonInfo &CI) {
403
2
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
2
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NoCommonAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
4
                                  const AttributeCommonInfo &CI) {
403
4
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
4
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NoSplitStackAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
14
                                  const AttributeCommonInfo &CI) {
403
14
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
14
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NoUniqueAddressAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
63
                                  const AttributeCommonInfo &CI) {
403
63
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
63
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::OverloadableAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
883k
                                  const AttributeCommonInfo &CI) {
403
883k
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
883k
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ColdAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
25
                                  const AttributeCommonInfo &CI) {
403
25
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
25
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::HotAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
2
                                  const AttributeCommonInfo &CI) {
403
2
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
2
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::AnyX86NoCfCheckAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
10
                                  const AttributeCommonInfo &CI) {
403
10
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
10
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NoThrowAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
26.3k
                                  const AttributeCommonInfo &CI) {
403
26.3k
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
26.3k
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ObjCRuntimeVisibleAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
4
                                  const AttributeCommonInfo &CI) {
403
4
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
4
}
Unexecuted instantiation: SemaDeclAttr.cpp:void handleSimpleAttribute<clang::CFAuditedTransferAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::CFUnknownTransferAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
1
                                  const AttributeCommonInfo &CI) {
403
1
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
1
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NSConsumesSelfAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
310
                                  const AttributeCommonInfo &CI) {
403
310
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
310
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::OSConsumesThisAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
3
                                  const AttributeCommonInfo &CI) {
403
3
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
3
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::OSReturnsRetainedOnZeroAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
3
                                  const AttributeCommonInfo &CI) {
403
3
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
3
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::OSReturnsRetainedOnNonZeroAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
2
                                  const AttributeCommonInfo &CI) {
403
2
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
2
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NSReturnsAutoreleasedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
6
                                  const AttributeCommonInfo &CI) {
403
6
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
6
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::CFReturnsNotRetainedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
675
                                  const AttributeCommonInfo &CI) {
403
675
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
675
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NSReturnsNotRetainedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
111
                                  const AttributeCommonInfo &CI) {
403
111
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
111
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::CFReturnsRetainedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
42.3k
                                  const AttributeCommonInfo &CI) {
403
42.3k
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
42.3k
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NSReturnsRetainedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
15.3k
                                  const AttributeCommonInfo &CI) {
403
15.3k
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
15.3k
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::OSReturnsRetainedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
18
                                  const AttributeCommonInfo &CI) {
403
18
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
18
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::OSReturnsNotRetainedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
11
                                  const AttributeCommonInfo &CI) {
403
11
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
11
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ConstInitAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
173
                                  const AttributeCommonInfo &CI) {
403
173
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
173
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::SpeculativeLoadHardeningAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
25
                                  const AttributeCommonInfo &CI) {
403
25
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
25
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NoSpeculativeLoadHardeningAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
25
                                  const AttributeCommonInfo &CI) {
403
25
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
25
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ArcWeakrefUnavailableAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
919
                                  const AttributeCommonInfo &CI) {
403
919
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
919
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ObjCRootClassAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
786
                                  const AttributeCommonInfo &CI) {
403
786
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
786
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ObjCDirectAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
84
                                  const AttributeCommonInfo &CI) {
403
84
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
84
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ObjCDirectMembersAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
16
                                  const AttributeCommonInfo &CI) {
403
16
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
16
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ObjCNonLazyClassAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
7
                                  const AttributeCommonInfo &CI) {
403
7
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
7
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ObjCSubclassingRestrictedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
21
                                  const AttributeCommonInfo &CI) {
403
21
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
21
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ObjCClassStubAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
6
                                  const AttributeCommonInfo &CI) {
403
6
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
6
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ObjCRequiresPropertyDefsAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
7
                                  const AttributeCommonInfo &CI) {
403
7
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
7
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ReturnsTwiceAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
9
                                  const AttributeCommonInfo &CI) {
403
9
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
9
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NotTailCalledAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
672
                                  const AttributeCommonInfo &CI) {
403
672
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
672
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::DisableTailCallsAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
381
                                  const AttributeCommonInfo &CI) {
403
381
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
381
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::UsedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
115
                                  const AttributeCommonInfo &CI) {
403
115
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
115
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::WarnUnusedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
7
                                  const AttributeCommonInfo &CI) {
403
7
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
7
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::WeakAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
102
                                  const AttributeCommonInfo &CI) {
403
102
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
102
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ObjCExceptionAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
316
                                  const AttributeCommonInfo &CI) {
403
316
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
316
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ConstAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
210k
                                  const AttributeCommonInfo &CI) {
403
210k
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
210k
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::PureAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
7.82k
                                  const AttributeCommonInfo &CI) {
403
7.82k
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
7.82k
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NoDuplicateAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
6
                                  const AttributeCommonInfo &CI) {
403
6
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
6
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ConvergentAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
4.68k
                                  const AttributeCommonInfo &CI) {
403
4.68k
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
4.68k
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NoInlineAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
543
                                  const AttributeCommonInfo &CI) {
403
543
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
543
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NoInstrumentFunctionAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
35
                                  const AttributeCommonInfo &CI) {
403
35
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
35
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NoStackProtectorAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
10
                                  const AttributeCommonInfo &CI) {
403
10
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
10
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::CFICanonicalJumpTableAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
5
                                  const AttributeCommonInfo &CI) {
403
5
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
5
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::OpenCLKernelAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
821
                                  const AttributeCommonInfo &CI) {
403
821
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
821
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ExcludeFromExplicitInstantiationAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
964k
                                  const AttributeCommonInfo &CI) {
403
964k
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
964k
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::LTOVisibilityPublicAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
10
                                  const AttributeCommonInfo &CI) {
403
10
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
10
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::EmptyBasesAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
9
                                  const AttributeCommonInfo &CI) {
403
9
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
9
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::TrivialABIAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
40
                                  const AttributeCommonInfo &CI) {
403
40
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
40
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::MSNoVTableAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
6
                                  const AttributeCommonInfo &CI) {
403
6
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
6
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::MSStructAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
73
                                  const AttributeCommonInfo &CI) {
403
73
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
73
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::SelectAnyAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
77
                                  const AttributeCommonInfo &CI) {
403
77
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
77
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::GuardedVarAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
13
                                  const AttributeCommonInfo &CI) {
403
13
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
13
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ScopedLockableAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
66
                                  const AttributeCommonInfo &CI) {
403
66
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
66
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NoThreadSafetyAnalysisAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
43
                                  const AttributeCommonInfo &CI) {
403
43
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
43
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ConsumableAutoCastAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
2
                                  const AttributeCommonInfo &CI) {
403
2
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
2
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ConsumableSetOnReadAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
2
                                  const AttributeCommonInfo &CI) {
403
2
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
2
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::AnyX86NoCallerSavedRegistersAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
27
                                  const AttributeCommonInfo &CI) {
403
27
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
27
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::RenderScriptKernelAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
1
                                  const AttributeCommonInfo &CI) {
403
1
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
1
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::XRayInstrumentAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
84
                                  const AttributeCommonInfo &CI) {
403
84
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
84
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ReinitializesAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
11
                                  const AttributeCommonInfo &CI) {
403
11
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
11
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::AlwaysDestroyAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
24
                                  const AttributeCommonInfo &CI) {
403
24
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
24
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NoDestroyAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
38
                                  const AttributeCommonInfo &CI) {
403
38
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
38
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ObjCExternallyRetainedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
47
                                  const AttributeCommonInfo &CI) {
403
47
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
47
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::MIGServerRoutineAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
26
                                  const AttributeCommonInfo &CI) {
403
26
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
26
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::MSAllocatorAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
4
                                  const AttributeCommonInfo &CI) {
403
4
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
4
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::OSConsumedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
9
                                  const AttributeCommonInfo &CI) {
403
9
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
9
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NSConsumedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
490
                                  const AttributeCommonInfo &CI) {
403
490
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
490
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::CFConsumedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
402
2.40k
                                  const AttributeCommonInfo &CI) {
403
2.40k
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
404
2.40k
}
405
406
template <typename... DiagnosticArgs>
407
static const Sema::SemaDiagnosticBuilder&
408
4
appendDiagnostics(const Sema::SemaDiagnosticBuilder &Bldr) {
409
4
  return Bldr;
410
4
}
411
412
template <typename T, typename... DiagnosticArgs>
413
static const Sema::SemaDiagnosticBuilder&
414
appendDiagnostics(const Sema::SemaDiagnosticBuilder &Bldr, T &&ExtraArg,
415
12
                  DiagnosticArgs &&... ExtraArgs) {
416
12
  return appendDiagnostics(Bldr << std::forward<T>(ExtraArg),
417
12
                           std::forward<DiagnosticArgs>(ExtraArgs)...);
418
12
}
SemaDeclAttr.cpp:clang::Sema::SemaDiagnosticBuilder const& appendDiagnostics<clang::ParsedAttr const&, int, clang::SourceRange>(clang::Sema::SemaDiagnosticBuilder const&, clang::ParsedAttr const&&&, int&&, clang::SourceRange&&)
Line
Count
Source
415
2
                  DiagnosticArgs &&... ExtraArgs) {
416
2
  return appendDiagnostics(Bldr << std::forward<T>(ExtraArg),
417
2
                           std::forward<DiagnosticArgs>(ExtraArgs)...);
418
2
}
SemaDeclAttr.cpp:clang::Sema::SemaDiagnosticBuilder const& appendDiagnostics<int, clang::SourceRange>(clang::Sema::SemaDiagnosticBuilder const&, int&&, clang::SourceRange&&)
Line
Count
Source
415
2
                  DiagnosticArgs &&... ExtraArgs) {
416
2
  return appendDiagnostics(Bldr << std::forward<T>(ExtraArg),
417
2
                           std::forward<DiagnosticArgs>(ExtraArgs)...);
418
2
}
SemaDeclAttr.cpp:clang::Sema::SemaDiagnosticBuilder const& appendDiagnostics<clang::SourceRange>(clang::Sema::SemaDiagnosticBuilder const&, clang::SourceRange&&)
Line
Count
Source
415
2
                  DiagnosticArgs &&... ExtraArgs) {
416
2
  return appendDiagnostics(Bldr << std::forward<T>(ExtraArg),
417
2
                           std::forward<DiagnosticArgs>(ExtraArgs)...);
418
2
}
SemaDeclAttr.cpp:clang::Sema::SemaDiagnosticBuilder const& appendDiagnostics<clang::SourceRange, char const (&) [12], int>(clang::Sema::SemaDiagnosticBuilder const&, clang::SourceRange&&, char const (&&&) [12], int&&)
Line
Count
Source
415
2
                  DiagnosticArgs &&... ExtraArgs) {
416
2
  return appendDiagnostics(Bldr << std::forward<T>(ExtraArg),
417
2
                           std::forward<DiagnosticArgs>(ExtraArgs)...);
418
2
}
SemaDeclAttr.cpp:clang::Sema::SemaDiagnosticBuilder const& appendDiagnostics<char const (&) [12], int>(clang::Sema::SemaDiagnosticBuilder const&, char const (&&&) [12], int&&)
Line
Count
Source
415
2
                  DiagnosticArgs &&... ExtraArgs) {
416
2
  return appendDiagnostics(Bldr << std::forward<T>(ExtraArg),
417
2
                           std::forward<DiagnosticArgs>(ExtraArgs)...);
418
2
}
SemaDeclAttr.cpp:clang::Sema::SemaDiagnosticBuilder const& appendDiagnostics<int>(clang::Sema::SemaDiagnosticBuilder const&, int&&)
Line
Count
Source
415
2
                  DiagnosticArgs &&... ExtraArgs) {
416
2
  return appendDiagnostics(Bldr << std::forward<T>(ExtraArg),
417
2
                           std::forward<DiagnosticArgs>(ExtraArgs)...);
418
2
}
419
420
/// Add an attribute {@code AttrType} to declaration {@code D}, provided that
421
/// {@code PassesCheck} is true.
422
/// Otherwise, emit diagnostic {@code DiagID}, passing in all parameters
423
/// specified in {@code ExtraArgs}.
424
template <typename AttrType, typename... DiagnosticArgs>
425
static void handleSimpleAttributeOrDiagnose(Sema &S, Decl *D,
426
                                            const AttributeCommonInfo &CI,
427
                                            bool PassesCheck, unsigned DiagID,
428
2.91k
                                            DiagnosticArgs &&... ExtraArgs) {
429
2.91k
  if (!PassesCheck) {
430
4
    Sema::SemaDiagnosticBuilder DB = S.Diag(D->getBeginLoc(), DiagID);
431
4
    appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...);
432
4
    return;
433
4
  }
434
2.90k
  handleSimpleAttribute<AttrType>(S, D, CI);
435
2.90k
}
SemaDeclAttr.cpp:void handleSimpleAttributeOrDiagnose<clang::OSReturnsRetainedOnZeroAttr, clang::ParsedAttr const&, int, clang::SourceRange>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&, bool, unsigned int, clang::ParsedAttr const&&&, int&&, clang::SourceRange&&)
Line
Count
Source
428
4
                                            DiagnosticArgs &&... ExtraArgs) {
429
4
  if (!PassesCheck) {
430
1
    Sema::SemaDiagnosticBuilder DB = S.Diag(D->getBeginLoc(), DiagID);
431
1
    appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...);
432
1
    return;
433
1
  }
434
3
  handleSimpleAttribute<AttrType>(S, D, CI);
435
3
}
SemaDeclAttr.cpp:void handleSimpleAttributeOrDiagnose<clang::OSReturnsRetainedOnNonZeroAttr, clang::ParsedAttr const&, int, clang::SourceRange>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&, bool, unsigned int, clang::ParsedAttr const&&&, int&&, clang::SourceRange&&)
Line
Count
Source
428
3
                                            DiagnosticArgs &&... ExtraArgs) {
429
3
  if (!PassesCheck) {
430
1
    Sema::SemaDiagnosticBuilder DB = S.Diag(D->getBeginLoc(), DiagID);
431
1
    appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...);
432
1
    return;
433
1
  }
434
2
  handleSimpleAttribute<AttrType>(S, D, CI);
435
2
}
SemaDeclAttr.cpp:void handleSimpleAttributeOrDiagnose<clang::OSConsumedAttr, clang::SourceRange, char const (&) [12], int>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&, bool, unsigned int, clang::SourceRange&&, char const (&&&) [12], int&&)
Line
Count
Source
428
10
                                            DiagnosticArgs &&... ExtraArgs) {
429
10
  if (!PassesCheck) {
430
1
    Sema::SemaDiagnosticBuilder DB = S.Diag(D->getBeginLoc(), DiagID);
431
1
    appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...);
432
1
    return;
433
1
  }
434
9
  handleSimpleAttribute<AttrType>(S, D, CI);
435
9
}
SemaDeclAttr.cpp:void handleSimpleAttributeOrDiagnose<clang::NSConsumedAttr, clang::SourceRange, char const (&) [12], int>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&, bool, unsigned int, clang::SourceRange&&, char const (&&&) [12], int&&)
Line
Count
Source
428
491
                                            DiagnosticArgs &&... ExtraArgs) {
429
491
  if (!PassesCheck) {
430
1
    Sema::SemaDiagnosticBuilder DB = S.Diag(D->getBeginLoc(), DiagID);
431
1
    appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...);
432
1
    return;
433
1
  }
434
490
  handleSimpleAttribute<AttrType>(S, D, CI);
435
490
}
SemaDeclAttr.cpp:void handleSimpleAttributeOrDiagnose<clang::CFConsumedAttr, clang::SourceRange, char const (&) [12], int>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&, bool, unsigned int, clang::SourceRange&&, char const (&&&) [12], int&&)
Line
Count
Source
428
2.40k
                                            DiagnosticArgs &&... ExtraArgs) {
429
2.40k
  if (!PassesCheck) {
430
0
    Sema::SemaDiagnosticBuilder DB = S.Diag(D->getBeginLoc(), DiagID);
431
0
    appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...);
432
0
    return;
433
0
  }
434
2.40k
  handleSimpleAttribute<AttrType>(S, D, CI);
435
2.40k
}
436
437
template <typename AttrType>
438
static void handleSimpleAttributeWithExclusions(Sema &S, Decl *D,
439
3.58k
                                                const ParsedAttr &AL) {
440
3.58k
  handleSimpleAttribute<AttrType>(S, D, AL);
441
3.58k
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::Mips16Attr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
439
8
                                                const ParsedAttr &AL) {
440
8
  handleSimpleAttribute<AttrType>(S, D, AL);
441
8
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::MicroMipsAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
439
3
                                                const ParsedAttr &AL) {
440
3
  handleSimpleAttribute<AttrType>(S, D, AL);
441
3
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::MipsLongCallAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
439
14
                                                const ParsedAttr &AL) {
440
14
  handleSimpleAttribute<AttrType>(S, D, AL);
441
14
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::MipsShortCallAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
439
14
                                                const ParsedAttr &AL) {
440
14
  handleSimpleAttribute<AttrType>(S, D, AL);
441
14
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::CUDADeviceAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
439
1.62k
                                                const ParsedAttr &AL) {
440
1.62k
  handleSimpleAttribute<AttrType>(S, D, AL);
441
1.62k
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::CUDAHostAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
439
726
                                                const ParsedAttr &AL) {
440
726
  handleSimpleAttribute<AttrType>(S, D, AL);
441
726
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::HIPPinnedShadowAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
439
6
                                                const ParsedAttr &AL) {
440
6
  handleSimpleAttribute<AttrType>(S, D, AL);
441
6
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::ColdAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
439
25
                                                const ParsedAttr &AL) {
440
25
  handleSimpleAttribute<AttrType>(S, D, AL);
441
25
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::HotAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
439
2
                                                const ParsedAttr &AL) {
440
2
  handleSimpleAttribute<AttrType>(S, D, AL);
441
2
}
Unexecuted instantiation: SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::CFAuditedTransferAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::CFUnknownTransferAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
439
1
                                                const ParsedAttr &AL) {
440
1
  handleSimpleAttribute<AttrType>(S, D, AL);
441
1
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::SpeculativeLoadHardeningAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
439
25
                                                const ParsedAttr &AL) {
440
25
  handleSimpleAttribute<AttrType>(S, D, AL);
441
25
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::NoSpeculativeLoadHardeningAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
439
25
                                                const ParsedAttr &AL) {
440
25
  handleSimpleAttribute<AttrType>(S, D, AL);
441
25
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::NotTailCalledAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
439
672
                                                const ParsedAttr &AL) {
440
672
  handleSimpleAttribute<AttrType>(S, D, AL);
441
672
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::DisableTailCallsAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
439
381
                                                const ParsedAttr &AL) {
440
381
  handleSimpleAttribute<AttrType>(S, D, AL);
441
381
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::AlwaysDestroyAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
439
24
                                                const ParsedAttr &AL) {
440
24
  handleSimpleAttribute<AttrType>(S, D, AL);
441
24
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::NoDestroyAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
439
38
                                                const ParsedAttr &AL) {
440
38
  handleSimpleAttribute<AttrType>(S, D, AL);
441
38
}
442
443
/// Applies the given attribute to the Decl so long as the Decl doesn't
444
/// already have one of the given incompatible attributes.
445
template <typename AttrType, typename IncompatibleAttrType,
446
          typename... IncompatibleAttrTypes>
447
static void handleSimpleAttributeWithExclusions(Sema &S, Decl *D,
448
3.63k
                                                const ParsedAttr &AL) {
449
3.63k
  if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
450
33
    return;
451
3.60k
  handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
452
3.60k
                                                                          AL);
453
3.60k
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::Mips16Attr, clang::MicroMipsAttr, clang::MipsInterruptAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
448
11
                                                const ParsedAttr &AL) {
449
11
  if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
450
1
    return;
451
10
  handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
452
10
                                                                          AL);
453
10
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::Mips16Attr, clang::MipsInterruptAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
448
10
                                                const ParsedAttr &AL) {
449
10
  if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
450
2
    return;
451
8
  handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
452
8
                                                                          AL);
453
8
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::MicroMipsAttr, clang::Mips16Attr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
448
5
                                                const ParsedAttr &AL) {
449
5
  if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
450
2
    return;
451
3
  handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
452
3
                                                                          AL);
453
3
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::MipsLongCallAttr, clang::MipsShortCallAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
448
16
                                                const ParsedAttr &AL) {
449
16
  if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
450
2
    return;
451
14
  handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
452
14
                                                                          AL);
453
14
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::MipsShortCallAttr, clang::MipsLongCallAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
448
16
                                                const ParsedAttr &AL) {
449
16
  if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
450
2
    return;
451
14
  handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
452
14
                                                                          AL);
453
14
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::CUDADeviceAttr, clang::CUDAGlobalAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
448
1.62k
                                                const ParsedAttr &AL) {
449
1.62k
  if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
450
2
    return;
451
1.62k
  handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
452
1.62k
                                                                          AL);
453
1.62k
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::CUDAHostAttr, clang::CUDAGlobalAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
448
728
                                                const ParsedAttr &AL) {
449
728
  if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
450
2
    return;
451
726
  handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
452
726
                                                                          AL);
453
726
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::HIPPinnedShadowAttr, clang::CUDADeviceAttr, clang::CUDAConstantAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
448
10
                                                const ParsedAttr &AL) {
449
10
  if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
450
2
    return;
451
8
  handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
452
8
                                                                          AL);
453
8
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::HIPPinnedShadowAttr, clang::CUDAConstantAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
448
8
                                                const ParsedAttr &AL) {
449
8
  if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
450
2
    return;
451
6
  handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
452
6
                                                                          AL);
453
6
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::ColdAttr, clang::HotAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
448
26
                                                const ParsedAttr &AL) {
449
26
  if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
450
1
    return;
451
25
  handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
452
25
                                                                          AL);
453
25
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::HotAttr, clang::ColdAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
448
3
                                                const ParsedAttr &AL) {
449
3
  if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
450
1
    return;
451
2
  handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
452
2
                                                                          AL);
453
2
}
Unexecuted instantiation: SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::CFAuditedTransferAttr, clang::CFUnknownTransferAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::CFUnknownTransferAttr, clang::CFAuditedTransferAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
448
1
                                                const ParsedAttr &AL) {
449
1
  if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
450
0
    return;
451
1
  handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
452
1
                                                                          AL);
453
1
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::SpeculativeLoadHardeningAttr, clang::NoSpeculativeLoadHardeningAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
448
27
                                                const ParsedAttr &AL) {
449
27
  if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
450
2
    return;
451
25
  handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
452
25
                                                                          AL);
453
25
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::NoSpeculativeLoadHardeningAttr, clang::SpeculativeLoadHardeningAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
448
27
                                                const ParsedAttr &AL) {
449
27
  if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
450
2
    return;
451
25
  handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
452
25
                                                                          AL);
453
25
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::NotTailCalledAttr, clang::AlwaysInlineAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
448
673
                                                const ParsedAttr &AL) {
449
673
  if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
450
1
    return;
451
672
  handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
452
672
                                                                          AL);
453
672
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::DisableTailCallsAttr, clang::NakedAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
448
382
                                                const ParsedAttr &AL) {
449
382
  if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
450
1
    return;
451
381
  handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
452
381
                                                                          AL);
453
381
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::AlwaysDestroyAttr, clang::NoDestroyAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
448
28
                                                const ParsedAttr &AL) {
449
28
  if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
450
4
    return;
451
24
  handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
452
24
                                                                          AL);
453
24
}
SemaDeclAttr.cpp:void handleSimpleAttributeWithExclusions<clang::NoDestroyAttr, clang::AlwaysDestroyAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
448
42
                                                const ParsedAttr &AL) {
449
42
  if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
450
4
    return;
451
38
  handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
452
38
                                                                          AL);
453
38
}
454
455
/// Check if the passed-in expression is of type int or bool.
456
176
static bool isIntOrBool(Expr *Exp) {
457
176
  QualType QT = Exp->getType();
458
176
  return QT->isBooleanType() || 
QT->isIntegerType()120
;
459
176
}
460
461
462
// Check to see if the type is a smart pointer of some kind.  We assume
463
// it's a smart pointer if it defines both operator-> and operator*.
464
2.74k
static bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) {
465
2.74k
  auto IsOverloadedOperatorPresent = [&S](const RecordDecl *Record,
466
5.57k
                                          OverloadedOperatorKind Op) {
467
5.57k
    DeclContextLookupResult Result =
468
5.57k
        Record->lookup(S.Context.DeclarationNames.getCXXOperatorName(Op));
469
5.57k
    return !Result.empty();
470
5.57k
  };
471
2.74k
472
2.74k
  const RecordDecl *Record = RT->getDecl();
473
2.74k
  bool foundStarOperator = IsOverloadedOperatorPresent(Record, OO_Star);
474
2.74k
  bool foundArrowOperator = IsOverloadedOperatorPresent(Record, OO_Arrow);
475
2.74k
  if (foundStarOperator && 
foundArrowOperator46
)
476
46
    return true;
477
2.69k
478
2.69k
  const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(Record);
479
2.69k
  if (!CXXRecord)
480
21
    return false;
481
2.67k
482
2.67k
  for (auto BaseSpecifier : CXXRecord->bases()) {
483
44
    if (!foundStarOperator)
484
44
      foundStarOperator = IsOverloadedOperatorPresent(
485
44
          BaseSpecifier.getType()->getAsRecordDecl(), OO_Star);
486
44
    if (!foundArrowOperator)
487
44
      foundArrowOperator = IsOverloadedOperatorPresent(
488
44
          BaseSpecifier.getType()->getAsRecordDecl(), OO_Arrow);
489
44
  }
490
2.67k
491
2.67k
  if (foundStarOperator && 
foundArrowOperator16
)
492
16
    return true;
493
2.65k
494
2.65k
  return false;
495
2.65k
}
496
497
/// Check if passed in Decl is a pointer type.
498
/// Note that this function may produce an error message.
499
/// \return true if the Decl is a pointer type; false otherwise
500
static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
501
153
                                       const ParsedAttr &AL) {
502
153
  const auto *VD = cast<ValueDecl>(D);
503
153
  QualType QT = VD->getType();
504
153
  if (QT->isAnyPointerType())
505
114
    return true;
506
39
507
39
  if (const auto *RT = QT->getAs<RecordType>()) {
508
22
    // If it's an incomplete type, it could be a smart pointer; skip it.
509
22
    // (We don't want to force template instantiation if we can avoid it,
510
22
    // since that would alter the order in which templates are instantiated.)
511
22
    if (RT->isIncompleteType())
512
3
      return true;
513
19
514
19
    if (threadSafetyCheckIsSmartPointer(S, RT))
515
19
      return true;
516
17
  }
517
17
518
17
  S.Diag(AL.getLoc(), diag::warn_thread_attribute_decl_not_pointer) << AL << QT;
519
17
  return false;
520
17
}
521
522
/// Checks that the passed in QualType either is of RecordType or points
523
/// to RecordType. Returns the relevant RecordType, null if it does not exit.
524
5.47k
static const RecordType *getRecordType(QualType QT) {
525
5.47k
  if (const auto *RT = QT->getAs<RecordType>())
526
4.46k
    return RT;
527
1.00k
528
1.00k
  // Now check if we point to record type.
529
1.00k
  if (const auto *PT = QT->getAs<PointerType>())
530
780
    return PT->getPointeeType()->getAs<RecordType>();
531
229
532
229
  return nullptr;
533
229
}
534
535
template <typename AttrType>
536
3.21k
static bool checkRecordDeclForAttr(const RecordDecl *RD) {
537
3.21k
  // Check if the record itself has the attribute.
538
3.21k
  if (RD->hasAttr<AttrType>())
539
2.89k
    return true;
540
323
541
323
  // Else check if any base classes have the attribute.
542
323
  if (const auto *CRD = dyn_cast<CXXRecordDecl>(RD)) {
543
321
    CXXBasePaths BPaths(false, false);
544
321
    if (CRD->lookupInBases(
545
321
            [](const CXXBaseSpecifier *BS, CXXBasePath &) {
546
49
              const auto &Ty = *BS->getType();
547
49
              // If it's type-dependent, we assume it could have the attribute.
548
49
              if (Ty.isDependentType())
549
3
                return true;
550
46
              return Ty.castAs<RecordType>()->getDecl()->hasAttr<AttrType>();
551
46
            },
SemaDeclAttr.cpp:bool checkRecordDeclForAttr<clang::CapabilityAttr>(clang::RecordDecl const*)::'lambda'(clang::CXXBaseSpecifier const*, clang::CXXBasePath&)::operator()(clang::CXXBaseSpecifier const*, clang::CXXBasePath&) const
Line
Count
Source
545
43
            [](const CXXBaseSpecifier *BS, CXXBasePath &) {
546
43
              const auto &Ty = *BS->getType();
547
43
              // If it's type-dependent, we assume it could have the attribute.
548
43
              if (Ty.isDependentType())
549
3
                return true;
550
40
              return Ty.castAs<RecordType>()->getDecl()->hasAttr<AttrType>();
551
40
            },
SemaDeclAttr.cpp:bool checkRecordDeclForAttr<clang::ScopedLockableAttr>(clang::RecordDecl const*)::'lambda'(clang::CXXBaseSpecifier const*, clang::CXXBasePath&)::operator()(clang::CXXBaseSpecifier const*, clang::CXXBasePath&) const
Line
Count
Source
545
6
            [](const CXXBaseSpecifier *BS, CXXBasePath &) {
546
6
              const auto &Ty = *BS->getType();
547
6
              // If it's type-dependent, we assume it could have the attribute.
548
6
              if (Ty.isDependentType())
549
0
                return true;
550
6
              return Ty.castAs<RecordType>()->getDecl()->hasAttr<AttrType>();
551
6
            },
552
321
            BPaths, true))
553
22
      return true;
554
301
  }
555
301
  return false;
556
301
}
SemaDeclAttr.cpp:bool checkRecordDeclForAttr<clang::CapabilityAttr>(clang::RecordDecl const*)
Line
Count
Source
536
3.05k
static bool checkRecordDeclForAttr(const RecordDecl *RD) {
537
3.05k
  // Check if the record itself has the attribute.
538
3.05k
  if (RD->hasAttr<AttrType>())
539
2.75k
    return true;
540
295
541
295
  // Else check if any base classes have the attribute.
542
295
  if (const auto *CRD = dyn_cast<CXXRecordDecl>(RD)) {
543
293
    CXXBasePaths BPaths(false, false);
544
293
    if (CRD->lookupInBases(
545
293
            [](const CXXBaseSpecifier *BS, CXXBasePath &) {
546
293
              const auto &Ty = *BS->getType();
547
293
              // If it's type-dependent, we assume it could have the attribute.
548
293
              if (Ty.isDependentType())
549
293
                return true;
550
293
              return Ty.castAs<RecordType>()->getDecl()->hasAttr<AttrType>();
551
293
            },
552
293
            BPaths, true))
553
19
      return true;
554
276
  }
555
276
  return false;
556
276
}
SemaDeclAttr.cpp:bool checkRecordDeclForAttr<clang::ScopedLockableAttr>(clang::RecordDecl const*)
Line
Count
Source
536
165
static bool checkRecordDeclForAttr(const RecordDecl *RD) {
537
165
  // Check if the record itself has the attribute.
538
165
  if (RD->hasAttr<AttrType>())
539
137
    return true;
540
28
541
28
  // Else check if any base classes have the attribute.
542
28
  if (const auto *CRD = dyn_cast<CXXRecordDecl>(RD)) {
543
28
    CXXBasePaths BPaths(false, false);
544
28
    if (CRD->lookupInBases(
545
28
            [](const CXXBaseSpecifier *BS, CXXBasePath &) {
546
28
              const auto &Ty = *BS->getType();
547
28
              // If it's type-dependent, we assume it could have the attribute.
548
28
              if (Ty.isDependentType())
549
28
                return true;
550
28
              return Ty.castAs<RecordType>()->getDecl()->hasAttr<AttrType>();
551
28
            },
552
28
            BPaths, true))
553
3
      return true;
554
25
  }
555
25
  return false;
556
25
}
557
558
2.88k
static bool checkRecordTypeForCapability(Sema &S, QualType Ty) {
559
2.88k
  const RecordType *RT = getRecordType(Ty);
560
2.88k
561
2.88k
  if (!RT)
562
160
    return false;
563
2.72k
564
2.72k
  // Don't check for the capability if the class hasn't been defined yet.
565
2.72k
  if (RT->isIncompleteType())
566
0
    return true;
567
2.72k
568
2.72k
  // Allow smart pointers to be used as capability objects.
569
2.72k
  // FIXME -- Check the type that the smart pointer points to.
570
2.72k
  if (threadSafetyCheckIsSmartPointer(S, RT))
571
43
    return true;
572
2.68k
573
2.68k
  return checkRecordDeclForAttr<CapabilityAttr>(RT->getDecl());
574
2.68k
}
575
576
2.93k
static bool checkTypedefTypeForCapability(QualType Ty) {
577
2.93k
  const auto *TD = Ty->getAs<TypedefType>();
578
2.93k
  if (!TD)
579
2.88k
    return false;
580
48
581
48
  TypedefNameDecl *TN = TD->getDecl();
582
48
  if (!TN)
583
0
    return false;
584
48
585
48
  return TN->hasAttr<CapabilityAttr>();
586
48
}
587
588
2.93k
static bool typeHasCapability(Sema &S, QualType Ty) {
589
2.93k
  if (checkTypedefTypeForCapability(Ty))
590
48
    return true;
591
2.88k
592
2.88k
  if (checkRecordTypeForCapability(S, Ty))
593
2.61k
    return true;
594
271
595
271
  return false;
596
271
}
597
598
203
static bool isCapabilityExpr(Sema &S, const Expr *Ex) {
599
203
  // Capability expressions are simple expressions involving the boolean logic
600
203
  // operators &&, || or !, a simple DeclRefExpr, CastExpr or a ParenExpr. Once
601
203
  // a DeclRefExpr is found, its type should be checked to determine whether it
602
203
  // is a capability or not.
603
203
604
203
  if (const auto *E = dyn_cast<CastExpr>(Ex))
605
26
    return isCapabilityExpr(S, E->getSubExpr());
606
177
  else if (const auto *E = dyn_cast<ParenExpr>(Ex))
607
1
    return isCapabilityExpr(S, E->getSubExpr());
608
176
  else if (const auto *E = dyn_cast<UnaryOperator>(Ex)) {
609
26
    if (E->getOpcode() == UO_LNot || 
E->getOpcode() == UO_AddrOf12
||
610
26
        
E->getOpcode() == UO_Deref3
)
611
26
      return isCapabilityExpr(S, E->getSubExpr());
612
0
    return false;
613
150
  } else if (const auto *E = dyn_cast<BinaryOperator>(Ex)) {
614
5
    if (E->getOpcode() == BO_LAnd || 
E->getOpcode() == BO_LOr2
)
615
5
      return isCapabilityExpr(S, E->getLHS()) &&
616
5
             isCapabilityExpr(S, E->getRHS());
617
0
    return false;
618
0
  }
619
145
620
145
  return typeHasCapability(S, Ex->getType());
621
145
}
622
623
/// Checks that all attribute arguments, starting from Sidx, resolve to
624
/// a capability object.
625
/// \param Sidx The attribute argument index to start checking with.
626
/// \param ParamIdxOk Whether an argument can be indexing into a function
627
/// parameter list.
628
static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D,
629
                                           const ParsedAttr &AL,
630
                                           SmallVectorImpl<Expr *> &Args,
631
                                           unsigned Sidx = 0,
632
2.96k
                                           bool ParamIdxOk = false) {
633
2.96k
  if (Sidx == AL.getNumArgs()) {
634
416
    // If we don't have any capability arguments, the attribute implicitly
635
416
    // refers to 'this'. So we need to make sure that 'this' exists, i.e. we're
636
416
    // a non-static method, and that the class is a (scoped) capability.
637
416
    const auto *MD = dyn_cast<const CXXMethodDecl>(D);
638
416
    if (MD && 
!MD->isStatic()371
) {
639
371
      const CXXRecordDecl *RD = MD->getParent();
640
371
      // FIXME -- need to check this again on template instantiation
641
371
      if (!checkRecordDeclForAttr<CapabilityAttr>(RD) &&
642
371
          
!checkRecordDeclForAttr<ScopedLockableAttr>(RD)165
)
643
25
        S.Diag(AL.getLoc(),
644
25
               diag::warn_thread_attribute_not_on_capability_member)
645
25
            << AL << MD->getParent();
646
371
    } else {
647
45
      S.Diag(AL.getLoc(), diag::warn_thread_attribute_not_on_non_static_member)
648
45
          << AL;
649
45
    }
650
416
  }
651
2.96k
652
5.71k
  for (unsigned Idx = Sidx; Idx < AL.getNumArgs(); 
++Idx2.74k
) {
653
2.74k
    Expr *ArgExp = AL.getArgAsExpr(Idx);
654
2.74k
655
2.74k
    if (ArgExp->isTypeDependent()) {
656
54
      // FIXME -- need to check this again on template instantiation
657
54
      Args.push_back(ArgExp);
658
54
      continue;
659
54
    }
660
2.69k
661
2.69k
    if (const auto *StrLit = dyn_cast<StringLiteral>(ArgExp)) {
662
104
      if (StrLit->getLength() == 0 ||
663
104
          
(70
StrLit->isAscii()70
&&
StrLit->getString() == StringRef("*")67
)) {
664
62
        // Pass empty strings to the analyzer without warnings.
665
62
        // Treat "*" as the universal lock.
666
62
        Args.push_back(ArgExp);
667
62
        continue;
668
62
      }
669
42
670
42
      // We allow constant strings to be used as a placeholder for expressions
671
42
      // that are not valid C++ syntax, but warn that they are ignored.
672
42
      S.Diag(AL.getLoc(), diag::warn_thread_attribute_ignored) << AL;
673
42
      Args.push_back(ArgExp);
674
42
      continue;
675
42
    }
676
2.58k
677
2.58k
    QualType ArgTy = ArgExp->getType();
678
2.58k
679
2.58k
    // A pointer to member expression of the form  &MyClass::mu is treated
680
2.58k
    // specially -- we need to look at the type of the member.
681
2.58k
    if (const auto *UOp = dyn_cast<UnaryOperator>(ArgExp))
682
128
      if (UOp->getOpcode() == UO_AddrOf)
683
76
        if (const auto *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr()))
684
76
          if (DRE->getDecl()->isCXXInstanceMember())
685
37
            ArgTy = DRE->getDecl()->getType();
686
2.58k
687
2.58k
    // First see if we can just cast to record type, or pointer to record type.
688
2.58k
    const RecordType *RT = getRecordType(ArgTy);
689
2.58k
690
2.58k
    // Now check if we index into a record type function param.
691
2.58k
    if(!RT && 
ParamIdxOk186
) {
692
89
      const auto *FD = dyn_cast<FunctionDecl>(D);
693
89
      const auto *IL = dyn_cast<IntegerLiteral>(ArgExp);
694
89
      if(FD && IL) {
695
63
        unsigned int NumParams = FD->getNumParams();
696
63
        llvm::APInt ArgValue = IL->getValue();
697
63
        uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
698
63
        uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
699
63
        if (!ArgValue.isStrictlyPositive() || 
ParamIdxFromOne > NumParams36
) {
700
36
          S.Diag(AL.getLoc(),
701
36
                 diag::err_attribute_argument_out_of_bounds_extra_info)
702
36
              << AL << Idx + 1 << NumParams;
703
36
          continue;
704
36
        }
705
27
        ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
706
27
      }
707
89
    }
708
2.58k
709
2.58k
    // If the type does not have a capability, see if the components of the
710
2.58k
    // expression have capabilities. This allows for writing C code where the
711
2.58k
    // capability may be on the type, and the expression is a capability
712
2.58k
    // boolean logic expression. Eg) requires_capability(A || B && !C)
713
2.58k
    
if (2.55k
!typeHasCapability(S, ArgTy)2.55k
&&
!isCapabilityExpr(S, ArgExp)140
)
714
125
      S.Diag(AL.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
715
125
          << AL << ArgTy;
716
2.55k
717
2.55k
    Args.push_back(ArgExp);
718
2.55k
  }
719
2.96k
}
720
721
//===----------------------------------------------------------------------===//
722
// Attribute Implementations
723
//===----------------------------------------------------------------------===//
724
725
21
static void handlePtGuardedVarAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
726
21
  if (!threadSafetyCheckIsPointer(S, D, AL))
727
10
    return;
728
11
729
11
  D->addAttr(::new (S.Context) PtGuardedVarAttr(S.Context, AL));
730
11
}
731
732
static bool checkGuardedByAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
733
681
                                     Expr *&Arg) {
734
681
  SmallVector<Expr *, 1> Args;
735
681
  // check that all arguments are lockable objects
736
681
  checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
737
681
  unsigned Size = Args.size();
738
681
  if (Size != 1)
739
0
    return false;
740
681
741
681
  Arg = Args[0];
742
681
743
681
  return true;
744
681
}
745
746
549
static void handleGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
747
549
  Expr *Arg = nullptr;
748
549
  if (!checkGuardedByAttrCommon(S, D, AL, Arg))
749
0
    return;
750
549
751
549
  D->addAttr(::new (S.Context) GuardedByAttr(S.Context, AL, Arg));
752
549
}
753
754
132
static void handlePtGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
755
132
  Expr *Arg = nullptr;
756
132
  if (!checkGuardedByAttrCommon(S, D, AL, Arg))
757
0
    return;
758
132
759
132
  if (!threadSafetyCheckIsPointer(S, D, AL))
760
7
    return;
761
125
762
125
  D->addAttr(::new (S.Context) PtGuardedByAttr(S.Context, AL, Arg));
763
125
}
764
765
static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
766
245
                                        SmallVectorImpl<Expr *> &Args) {
767
245
  if (!checkAttributeAtLeastNumArgs(S, AL, 1))
768
12
    return false;
769
233
770
233
  // Check that this attribute only applies to lockable types.
771
233
  QualType QT = cast<ValueDecl>(D)->getType();
772
233
  if (!QT->isDependentType() && !typeHasCapability(S, QT)) {
773
6
    S.Diag(AL.getLoc(), diag::warn_thread_attribute_decl_not_lockable) << AL;
774
6
    return false;
775
6
  }
776
227
777
227
  // Check that all arguments are lockable objects.
778
227
  checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
779
227
  if (Args.empty())
780
0
    return false;
781
227
782
227
  return true;
783
227
}
784
785
142
static void handleAcquiredAfterAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
786
142
  SmallVector<Expr *, 1> Args;
787
142
  if (!checkAcquireOrderAttrCommon(S, D, AL, Args))
788
9
    return;
789
133
790
133
  Expr **StartArg = &Args[0];
791
133
  D->addAttr(::new (S.Context)
792
133
                 AcquiredAfterAttr(S.Context, AL, StartArg, Args.size()));
793
133
}
794
795
103
static void handleAcquiredBeforeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
796
103
  SmallVector<Expr *, 1> Args;
797
103
  if (!checkAcquireOrderAttrCommon(S, D, AL, Args))
798
9
    return;
799
94
800
94
  Expr **StartArg = &Args[0];
801
94
  D->addAttr(::new (S.Context)
802
94
                 AcquiredBeforeAttr(S.Context, AL, StartArg, Args.size()));
803
94
}
804
805
static bool checkLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
806
549
                                   SmallVectorImpl<Expr *> &Args) {
807
549
  // zero or more arguments ok
808
549
  // check that all arguments are lockable objects
809
549
  checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 0, /*ParamIdxOk=*/true);
810
549
811
549
  return true;
812
549
}
813
814
13
static void handleAssertSharedLockAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
815
13
  SmallVector<Expr *, 1> Args;
816
13
  if (!checkLockFunAttrCommon(S, D, AL, Args))
817
0
    return;
818
13
819
13
  unsigned Size = Args.size();
820
13
  Expr **StartArg = Size == 0 ? 
nullptr7
:
&Args[0]6
;
821
13
  D->addAttr(::new (S.Context)
822
13
                 AssertSharedLockAttr(S.Context, AL, StartArg, Size));
823
13
}
824
825
static void handleAssertExclusiveLockAttr(Sema &S, Decl *D,
826
15
                                          const ParsedAttr &AL) {
827
15
  SmallVector<Expr *, 1> Args;
828
15
  if (!checkLockFunAttrCommon(S, D, AL, Args))
829
0
    return;
830
15
831
15
  unsigned Size = Args.size();
832
15
  Expr **StartArg = Size == 0 ? 
nullptr7
:
&Args[0]8
;
833
15
  D->addAttr(::new (S.Context)
834
15
                 AssertExclusiveLockAttr(S.Context, AL, StartArg, Size));
835
15
}
836
837
/// Checks to be sure that the given parameter number is in bounds, and
838
/// is an integral type. Will emit appropriate diagnostics if this returns
839
/// false.
840
///
841
/// AttrArgNo is used to actually retrieve the argument, so it's base-0.
842
template <typename AttrInfo>
843
static bool checkParamIsIntegerType(Sema &S, const FunctionDecl *FD,
844
5.67k
                                    const AttrInfo &AI, unsigned AttrArgNo) {
845
5.67k
  assert(AI.isArgExpr(AttrArgNo) && "Expected expression argument");
846
5.67k
  Expr *AttrArg = AI.getArgAsExpr(AttrArgNo);
847
5.67k
  ParamIdx Idx;
848
5.67k
  if (!checkFunctionOrMethodParameterIndex(S, FD, AI, AttrArgNo + 1, AttrArg,
849
5.67k
                                           Idx))
850
6
    return false;
851
5.66k
852
5.66k
  const ParmVarDecl *Param = FD->getParamDecl(Idx.getASTIndex());
853
5.66k
  if (!Param->getType()->isIntegerType() && 
!Param->getType()->isCharType()1
) {
854
1
    SourceLocation SrcLoc = AttrArg->getBeginLoc();
855
1
    S.Diag(SrcLoc, diag::err_attribute_integers_only)
856
1
        << AI << Param->getSourceRange();
857
1
    return false;
858
1
  }
859
5.66k
  return true;
860
5.66k
}
861
862
4.72k
static void handleAllocSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
863
4.72k
  if (!checkAttributeAtLeastNumArgs(S, AL, 1) ||
864
4.72k
      !checkAttributeAtMostNumArgs(S, AL, 2))
865
0
    return;
866
4.72k
867
4.72k
  const auto *FD = cast<FunctionDecl>(D);
868
4.72k
  if (!FD->getReturnType()->isPointerType()) {
869
1
    S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only) << AL;
870
1
    return;
871
1
  }
872
4.71k
873
4.71k
  const Expr *SizeExpr = AL.getArgAsExpr(0);
874
4.71k
  int SizeArgNoVal;
875
4.71k
  // Parameter indices are 1-indexed, hence Index=1
876
4.71k
  if (!checkPositiveIntArgument(S, AL, SizeExpr, SizeArgNoVal, /*Idx=*/1))
877
2
    return;
878
4.71k
  if (!checkParamIsIntegerType(S, FD, AL, /*AttrArgNo=*/0))
879
5
    return;
880
4.71k
  ParamIdx SizeArgNo(SizeArgNoVal, D);
881
4.71k
882
4.71k
  ParamIdx NumberArgNo;
883
4.71k
  if (AL.getNumArgs() == 2) {
884
954
    const Expr *NumberExpr = AL.getArgAsExpr(1);
885
954
    int Val;
886
954
    // Parameter indices are 1-based, hence Index=2
887
954
    if (!checkPositiveIntArgument(S, AL, NumberExpr, Val, /*Idx=*/2))
888
1
      return;
889
953
    if (!checkParamIsIntegerType(S, FD, AL, /*AttrArgNo=*/1))
890
2
      return;
891
951
    NumberArgNo = ParamIdx(Val, D);
892
951
  }
893
4.71k
894
4.71k
  D->addAttr(::new (S.Context)
895
4.70k
                 AllocSizeAttr(S.Context, AL, SizeArgNo, NumberArgNo));
896
4.70k
}
897
898
static bool checkTryLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
899
176
                                      SmallVectorImpl<Expr *> &Args) {
900
176
  if (!checkAttributeAtLeastNumArgs(S, AL, 1))
901
0
    return false;
902
176
903
176
  if (!isIntOrBool(AL.getArgAsExpr(0))) {
904
18
    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
905
18
        << AL << 1 << AANT_ArgumentIntOrBool;
906
18
    return false;
907
18
  }
908
158
909
158
  // check that all arguments are lockable objects
910
158
  checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 1);
911
158
912
158
  return true;
913
158
}
914
915
static void handleSharedTrylockFunctionAttr(Sema &S, Decl *D,
916
70
                                            const ParsedAttr &AL) {
917
70
  SmallVector<Expr*, 2> Args;
918
70
  if (!checkTryLockFunAttrCommon(S, D, AL, Args))
919
9
    return;
920
61
921
61
  D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(
922
61
      S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));
923
61
}
924
925
static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D,
926
78
                                               const ParsedAttr &AL) {
927
78
  SmallVector<Expr*, 2> Args;
928
78
  if (!checkTryLockFunAttrCommon(S, D, AL, Args))
929
9
    return;
930
69
931
69
  D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(
932
69
      S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));
933
69
}
934
935
80
static void handleLockReturnedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
936
80
  // check that the argument is lockable object
937
80
  SmallVector<Expr*, 1> Args;
938
80
  checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
939
80
  unsigned Size = Args.size();
940
80
  if (Size == 0)
941
0
    return;
942
80
943
80
  D->addAttr(::new (S.Context) LockReturnedAttr(S.Context, AL, Args[0]));
944
80
}
945
946
134
static void handleLocksExcludedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
947
134
  if (!checkAttributeAtLeastNumArgs(S, AL, 1))
948
3
    return;
949
131
950
131
  // check that all arguments are lockable objects
951
131
  SmallVector<Expr*, 1> Args;
952
131
  checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
953
131
  unsigned Size = Args.size();
954
131
  if (Size == 0)
955
0
    return;
956
131
  Expr **StartArg = &Args[0];
957
131
958
131
  D->addAttr(::new (S.Context)
959
131
                 LocksExcludedAttr(S.Context, AL, StartArg, Size));
960
131
}
961
962
static bool checkFunctionConditionAttr(Sema &S, Decl *D, const ParsedAttr &AL,
963
17.8k
                                       Expr *&Cond, StringRef &Msg) {
964
17.8k
  Cond = AL.getArgAsExpr(0);
965
17.8k
  if (!Cond->isTypeDependent()) {
966
17.7k
    ExprResult Converted = S.PerformContextuallyConvertToBool(Cond);
967
17.7k
    if (Converted.isInvalid())
968
0
      return false;
969
17.7k
    Cond = Converted.get();
970
17.7k
  }
971
17.8k
972
17.8k
  if (!S.checkStringLiteralArgumentAttr(AL, 1, Msg))
973
2
    return false;
974
17.8k
975
17.8k
  if (Msg.empty())
976
9.41k
    Msg = "<no message provided>";
977
17.8k
978
17.8k
  SmallVector<PartialDiagnosticAt, 8> Diags;
979
17.8k
  if (isa<FunctionDecl>(D) && 
!Cond->isValueDependent()17.8k
&&
980
17.8k
      !Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(D),
981
17.7k
                                                Diags)) {
982
3
    S.Diag(AL.getLoc(), diag::err_attr_cond_never_constant_expr) << AL;
983
3
    for (const PartialDiagnosticAt &PDiag : Diags)
984
3
      S.Diag(PDiag.first, PDiag.second);
985
3
    return false;
986
3
  }
987
17.8k
  return true;
988
17.8k
}
989
990
11.0k
static void handleEnableIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
991
11.0k
  S.Diag(AL.getLoc(), diag::ext_clang_enable_if);
992
11.0k
993
11.0k
  Expr *Cond;
994
11.0k
  StringRef Msg;
995
11.0k
  if (checkFunctionConditionAttr(S, D, AL, Cond, Msg))
996
11.0k
    D->addAttr(::new (S.Context) EnableIfAttr(S.Context, AL, Cond, Msg));
997
11.0k
}
998
999
namespace {
1000
/// Determines if a given Expr references any of the given function's
1001
/// ParmVarDecls, or the function's implicit `this` parameter (if applicable).
1002
class ArgumentDependenceChecker
1003
    : public RecursiveASTVisitor<ArgumentDependenceChecker> {
1004
#ifndef NDEBUG
1005
  const CXXRecordDecl *ClassType;
1006
#endif
1007
  llvm::SmallPtrSet<const ParmVarDecl *, 16> Parms;
1008
  bool Result;
1009
1010
public:
1011
6.78k
  ArgumentDependenceChecker(const FunctionDecl *FD) {
1012
6.78k
#ifndef NDEBUG
1013
6.78k
    if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
1014
2.98k
      ClassType = MD->getParent();
1015
3.80k
    else
1016
3.80k
      ClassType = nullptr;
1017
6.78k
#endif
1018
6.78k
    Parms.insert(FD->param_begin(), FD->param_end());
1019
6.78k
  }
1020
1021
6.78k
  bool referencesArgs(Expr *E) {
1022
6.78k
    Result = false;
1023
6.78k
    TraverseStmt(E);
1024
6.78k
    return Result;
1025
6.78k
  }
1026
1027
27
  bool VisitCXXThisExpr(CXXThisExpr *E) {
1028
27
    assert(E->getType()->getPointeeCXXRecordDecl() == ClassType &&
1029
27
           "`this` doesn't refer to the enclosing class?");
1030
27
    Result = true;
1031
27
    return false;
1032
27
  }
1033
1034
6.66k
  bool VisitDeclRefExpr(DeclRefExpr *DRE) {
1035
6.66k
    if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
1036
6.65k
      if (Parms.count(PVD)) {
1037
6.65k
        Result = true;
1038
6.65k
        return false;
1039
6.65k
      }
1040
12
    return true;
1041
12
  }
1042
};
1043
}
1044
1045
6.79k
static void handleDiagnoseIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1046
6.79k
  S.Diag(AL.getLoc(), diag::ext_clang_diagnose_if);
1047
6.79k
1048
6.79k
  Expr *Cond;
1049
6.79k
  StringRef Msg;
1050
6.79k
  if (!checkFunctionConditionAttr(S, D, AL, Cond, Msg))
1051
3
    return;
1052
6.78k
1053
6.78k
  StringRef DiagTypeStr;
1054
6.78k
  if (!S.checkStringLiteralArgumentAttr(AL, 2, DiagTypeStr))
1055
0
    return;
1056
6.78k
1057
6.78k
  DiagnoseIfAttr::DiagnosticType DiagType;
1058
6.78k
  if (!DiagnoseIfAttr::ConvertStrToDiagnosticType(DiagTypeStr, DiagType)) {
1059
3
    S.Diag(AL.getArgAsExpr(2)->getBeginLoc(),
1060
3
           diag::err_diagnose_if_invalid_diagnostic_type);
1061
3
    return;
1062
3
  }
1063
6.78k
1064
6.78k
  bool ArgDependent = false;
1065
6.78k
  if (const auto *FD = dyn_cast<FunctionDecl>(D))
1066
6.78k
    ArgDependent = ArgumentDependenceChecker(FD).referencesArgs(Cond);
1067
6.78k
  D->addAttr(::new (S.Context) DiagnoseIfAttr(
1068
6.78k
      S.Context, AL, Cond, Msg, DiagType, ArgDependent, cast<NamedDecl>(D)));
1069
6.78k
}
1070
1071
31
static void handleNoBuiltinAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1072
31
  static constexpr const StringRef kWildcard = "*";
1073
31
1074
31
  llvm::SmallVector<StringRef, 16> Names;
1075
31
  bool HasWildcard = false;
1076
31
1077
41
  const auto AddBuiltinName = [&Names, &HasWildcard](StringRef Name) {
1078
41
    if (Name == kWildcard)
1079
12
      HasWildcard = true;
1080
41
    Names.push_back(Name);
1081
41
  };
1082
31
1083
31
  // Add previously defined attributes.
1084
31
  if (const auto *NBA = D->getAttr<NoBuiltinAttr>())
1085
8
    for (StringRef BuiltinName : NBA->builtinNames())
1086
8
      AddBuiltinName(BuiltinName);
1087
31
1088
31
  // Add current attributes.
1089
31
  if (AL.getNumArgs() == 0)
1090
10
    AddBuiltinName(kWildcard);
1091
21
  else
1092
45
    
for (unsigned I = 0, E = AL.getNumArgs(); 21
I != E;
++I24
) {
1093
24
      StringRef BuiltinName;
1094
24
      SourceLocation LiteralLoc;
1095
24
      if (!S.checkStringLiteralArgumentAttr(AL, I, BuiltinName, &LiteralLoc))
1096
0
        return;
1097
24
1098
24
      if (Builtin::Context::isBuiltinFunc(BuiltinName))
1099
23
        AddBuiltinName(BuiltinName);
1100
1
      else
1101
1
        S.Diag(LiteralLoc, diag::warn_attribute_no_builtin_invalid_builtin_name)
1102
1
            << BuiltinName << AL.getAttrName()->getName();
1103
24
    }
1104
31
1105
31
  // Repeating the same attribute is fine.
1106
31
  llvm::sort(Names);
1107
31
  Names.erase(std::unique(Names.begin(), Names.end()), Names.end());
1108
31
1109
31
  // Empty no_builtin must be on its own.
1110
31
  if (HasWildcard && 
Names.size() > 111
)
1111
1
    S.Diag(D->getLocation(),
1112
1
           diag::err_attribute_no_builtin_wildcard_or_builtin_name)
1113
1
        << AL.getAttrName()->getName();
1114
31
1115
31
  if (D->hasAttr<NoBuiltinAttr>())
1116
8
    D->dropAttr<NoBuiltinAttr>();
1117
31
  D->addAttr(::new (S.Context)
1118
31
                 NoBuiltinAttr(S.Context, AL, Names.data(), Names.size()));
1119
31
}
1120
1121
138
static void handlePassObjectSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1122
138
  if (D->hasAttr<PassObjectSizeAttr>()) {
1123
1
    S.Diag(D->getBeginLoc(), diag::err_attribute_only_once_per_parameter) << AL;
1124
1
    return;
1125
1
  }
1126
137
1127
137
  Expr *E = AL.getArgAsExpr(0);
1128
137
  uint32_t Type;
1129
137
  if (!checkUInt32Argument(S, AL, E, Type, /*Idx=*/1))
1130
2
    return;
1131
135
1132
135
  // pass_object_size's argument is passed in as the second argument of
1133
135
  // __builtin_object_size. So, it has the same constraints as that second
1134
135
  // argument; namely, it must be in the range [0, 3].
1135
135
  if (Type > 3) {
1136
2
    S.Diag(E->getBeginLoc(), diag::err_attribute_argument_out_of_range)
1137
2
        << AL << 0 << 3 << E->getSourceRange();
1138
2
    return;
1139
2
  }
1140
133
1141
133
  // pass_object_size is only supported on constant pointer parameters; as a
1142
133
  // kindness to users, we allow the parameter to be non-const for declarations.
1143
133
  // At this point, we have no clue if `D` belongs to a function declaration or
1144
133
  // definition, so we defer the constness check until later.
1145
133
  if (!cast<ParmVarDecl>(D)->getType()->isPointerType()) {
1146
3
    S.Diag(D->getBeginLoc(), diag::err_attribute_pointers_only) << AL << 1;
1147
3
    return;
1148
3
  }
1149
130
1150
130
  D->addAttr(::new (S.Context) PassObjectSizeAttr(S.Context, AL, (int)Type));
1151
130
}
1152
1153
7
static void handleConsumableAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1154
7
  ConsumableAttr::ConsumedState DefaultState;
1155
7
1156
7
  if (AL.isArgIdent(0)) {
1157
6
    IdentifierLoc *IL = AL.getArgAsIdent(0);
1158
6
    if (!ConsumableAttr::ConvertStrToConsumedState(IL->Ident->getName(),
1159
6
                                                   DefaultState)) {
1160
0
      S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL
1161
0
                                                               << IL->Ident;
1162
0
      return;
1163
0
    }
1164
1
  } else {
1165
1
    S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1166
1
        << AL << AANT_ArgumentIdentifier;
1167
1
    return;
1168
1
  }
1169
6
1170
6
  D->addAttr(::new (S.Context) ConsumableAttr(S.Context, AL, DefaultState));
1171
6
}
1172
1173
static bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD,
1174
31
                                    const ParsedAttr &AL) {
1175
31
  QualType ThisType = MD->getThisType()->getPointeeType();
1176
31
1177
31
  if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) {
1178
31
    if (!RD->hasAttr<ConsumableAttr>()) {
1179
3
      S.Diag(AL.getLoc(), diag::warn_attr_on_unconsumable_class) <<
1180
3
        RD->getNameAsString();
1181
3
1182
3
      return false;
1183
3
    }
1184
28
  }
1185
28
1186
28
  return true;
1187
28
}
1188
1189
16
static void handleCallableWhenAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1190
16
  if (!checkAttributeAtLeastNumArgs(S, AL, 1))
1191
1
    return;
1192
15
1193
15
  if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL))
1194
1
    return;
1195
14
1196
14
  SmallVector<CallableWhenAttr::ConsumedState, 3> States;
1197
32
  for (unsigned ArgIndex = 0; ArgIndex < AL.getNumArgs(); 
++ArgIndex18
) {
1198
20
    CallableWhenAttr::ConsumedState CallableState;
1199
20
1200
20
    StringRef StateString;
1201
20
    SourceLocation Loc;
1202
20
    if (AL.isArgIdent(ArgIndex)) {
1203
1
      IdentifierLoc *Ident = AL.getArgAsIdent(ArgIndex);
1204
1
      StateString = Ident->Ident->getName();
1205
1
      Loc = Ident->Loc;
1206
19
    } else {
1207
19
      if (!S.checkStringLiteralArgumentAttr(AL, ArgIndex, StateString, &Loc))
1208
1
        return;
1209
19
    }
1210
19
1211
19
    if (!CallableWhenAttr::ConvertStrToConsumedState(StateString,
1212
19
                                                     CallableState)) {
1213
1
      S.Diag(Loc, diag::warn_attribute_type_not_supported) << AL << StateString;
1214
1
      return;
1215
1
    }
1216
18
1217
18
    States.push_back(CallableState);
1218
18
  }
1219
14
1220
14
  D->addAttr(::new (S.Context)
1221
12
                 CallableWhenAttr(S.Context, AL, States.data(), States.size()));
1222
12
}
1223
1224
7
static void handleParamTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1225
7
  ParamTypestateAttr::ConsumedState ParamState;
1226
7
1227
7
  if (AL.isArgIdent(0)) {
1228
7
    IdentifierLoc *Ident = AL.getArgAsIdent(0);
1229
7
    StringRef StateString = Ident->Ident->getName();
1230
7
1231
7
    if (!ParamTypestateAttr::ConvertStrToConsumedState(StateString,
1232
7
                                                       ParamState)) {
1233
0
      S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported)
1234
0
          << AL << StateString;
1235
0
      return;
1236
0
    }
1237
0
  } else {
1238
0
    S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1239
0
        << AL << AANT_ArgumentIdentifier;
1240
0
    return;
1241
0
  }
1242
7
1243
7
  // FIXME: This check is currently being done in the analysis.  It can be
1244
7
  //        enabled here only after the parser propagates attributes at
1245
7
  //        template specialization definition, not declaration.
1246
7
  //QualType ReturnType = cast<ParmVarDecl>(D)->getType();
1247
7
  //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1248
7
  //
1249
7
  //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1250
7
  //    S.Diag(AL.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1251
7
  //      ReturnType.getAsString();
1252
7
  //    return;
1253
7
  //}
1254
7
1255
7
  D->addAttr(::new (S.Context) ParamTypestateAttr(S.Context, AL, ParamState));
1256
7
}
1257
1258
15
static void handleReturnTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1259
15
  ReturnTypestateAttr::ConsumedState ReturnState;
1260
15
1261
15
  if (AL.isArgIdent(0)) {
1262
14
    IdentifierLoc *IL = AL.getArgAsIdent(0);
1263
14
    if (!ReturnTypestateAttr::ConvertStrToConsumedState(IL->Ident->getName(),
1264
14
                                                        ReturnState)) {
1265
1
      S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL
1266
1
                                                               << IL->Ident;
1267
1
      return;
1268
1
    }
1269
1
  } else {
1270
1
    S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1271
1
        << AL << AANT_ArgumentIdentifier;
1272
1
    return;
1273
1
  }
1274
13
1275
13
  // FIXME: This check is currently being done in the analysis.  It can be
1276
13
  //        enabled here only after the parser propagates attributes at
1277
13
  //        template specialization definition, not declaration.
1278
13
  //QualType ReturnType;
1279
13
  //
1280
13
  //if (const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D)) {
1281
13
  //  ReturnType = Param->getType();
1282
13
  //
1283
13
  //} else if (const CXXConstructorDecl *Constructor =
1284
13
  //             dyn_cast<CXXConstructorDecl>(D)) {
1285
13
  //  ReturnType = Constructor->getThisType()->getPointeeType();
1286
13
  //
1287
13
  //} else {
1288
13
  //
1289
13
  //  ReturnType = cast<FunctionDecl>(D)->getCallResultType();
1290
13
  //}
1291
13
  //
1292
13
  //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1293
13
  //
1294
13
  //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1295
13
  //    S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1296
13
  //      ReturnType.getAsString();
1297
13
  //    return;
1298
13
  //}
1299
13
1300
13
  D->addAttr(::new (S.Context) ReturnTypestateAttr(S.Context, AL, ReturnState));
1301
13
}
1302
1303
10
static void handleSetTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1304
10
  if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL))
1305
1
    return;
1306
9
1307
9
  SetTypestateAttr::ConsumedState NewState;
1308
9
  if (AL.isArgIdent(0)) {
1309
9
    IdentifierLoc *Ident = AL.getArgAsIdent(0);
1310
9
    StringRef Param = Ident->Ident->getName();
1311
9
    if (!SetTypestateAttr::ConvertStrToConsumedState(Param, NewState)) {
1312
0
      S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) << AL
1313
0
                                                                  << Param;
1314
0
      return;
1315
0
    }
1316
0
  } else {
1317
0
    S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1318
0
        << AL << AANT_ArgumentIdentifier;
1319
0
    return;
1320
0
  }
1321
9
1322
9
  D->addAttr(::new (S.Context) SetTypestateAttr(S.Context, AL, NewState));
1323
9
}
1324
1325
6
static void handleTestTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1326
6
  if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL))
1327
1
    return;
1328
5
1329
5
  TestTypestateAttr::ConsumedState TestState;
1330
5
  if (AL.isArgIdent(0)) {
1331
5
    IdentifierLoc *Ident = AL.getArgAsIdent(0);
1332
5
    StringRef Param = Ident->Ident->getName();
1333
5
    if (!TestTypestateAttr::ConvertStrToConsumedState(Param, TestState)) {
1334
0
      S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) << AL
1335
0
                                                                  << Param;
1336
0
      return;
1337
0
    }
1338
0
  } else {
1339
0
    S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1340
0
        << AL << AANT_ArgumentIdentifier;
1341
0
    return;
1342
0
  }
1343
5
1344
5
  D->addAttr(::new (S.Context) TestTypestateAttr(S.Context, AL, TestState));
1345
5
}
1346
1347
2.35k
static void handleExtVectorTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1348
2.35k
  // Remember this typedef decl, we will need it later for diagnostics.
1349
2.35k
  S.ExtVectorDecls.push_back(cast<TypedefNameDecl>(D));
1350
2.35k
}
1351
1352
36.4k
static void handlePackedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1353
36.4k
  if (auto *TD = dyn_cast<TagDecl>(D))
1354
34.8k
    TD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
1355
1.56k
  else if (auto *FD = dyn_cast<FieldDecl>(D)) {
1356
1.55k
    bool BitfieldByteAligned = (!FD->getType()->isDependentType() &&
1357
1.55k
                                
!FD->getType()->isIncompleteType()1.54k
&&
1358
1.55k
                                
FD->isBitField()1.28k
&&
1359
1.55k
                                
S.Context.getTypeAlign(FD->getType()) <= 830
);
1360
1.55k
1361
1.55k
    if (S.getASTContext().getTargetInfo().getTriple().isPS4()) {
1362
6
      if (BitfieldByteAligned)
1363
1
        // The PS4 target needs to maintain ABI backwards compatibility.
1364
1
        S.Diag(AL.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
1365
1
            << AL << FD->getType();
1366
5
      else
1367
5
        FD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
1368
1.54k
    } else {
1369
1.54k
      // Report warning about changed offset in the newer compiler versions.
1370
1.54k
      if (BitfieldByteAligned)
1371
2
        S.Diag(AL.getLoc(), diag::warn_attribute_packed_for_bitfield);
1372
1.54k
1373
1.54k
      FD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
1374
1.54k
    }
1375
1.55k
1376
1.55k
  } else
1377
10
    S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
1378
36.4k
}
1379
1380
204
static bool checkIBOutletCommon(Sema &S, Decl *D, const ParsedAttr &AL) {
1381
204
  // The IBOutlet/IBOutletCollection attributes only apply to instance
1382
204
  // variables or properties of Objective-C classes.  The outlet must also
1383
204
  // have an object reference type.
1384
204
  if (const auto *VD = dyn_cast<ObjCIvarDecl>(D)) {
1385
98
    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
1386
10
      S.Diag(AL.getLoc(), diag::warn_iboutlet_object_type)
1387
10
          << AL << VD->getType() << 0;
1388
10
      return false;
1389
10
    }
1390
106
  }
1391
106
  else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) {
1392
106
    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
1393
8
      S.Diag(AL.getLoc(), diag::warn_iboutlet_object_type)
1394
8
          << AL << PD->getType() << 1;
1395
8
      return false;
1396
8
    }
1397
0
  }
1398
0
  else {
1399
0
    S.Diag(AL.getLoc(), diag::warn_attribute_iboutlet) << AL;
1400
0
    return false;
1401
0
  }
1402
186
1403
186
  return true;
1404
186
}
1405
1406
169
static void handleIBOutlet(Sema &S, Decl *D, const ParsedAttr &AL) {
1407
169
  if (!checkIBOutletCommon(S, D, AL))
1408
14
    return;
1409
155
1410
155
  D->addAttr(::new (S.Context) IBOutletAttr(S.Context, AL));
1411
155
}
1412
1413
35
static void handleIBOutletCollection(Sema &S, Decl *D, const ParsedAttr &AL) {
1414
35
1415
35
  // The iboutletcollection attribute can have zero or one arguments.
1416
35
  if (AL.getNumArgs() > 1) {
1417
0
    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
1418
0
    return;
1419
0
  }
1420
35
1421
35
  if (!checkIBOutletCommon(S, D, AL))
1422
4
    return;
1423
31
1424
31
  ParsedType PT;
1425
31
1426
31
  if (AL.hasParsedType())
1427
23
    PT = AL.getTypeArg();
1428
8
  else {
1429
8
    PT = S.getTypeName(S.Context.Idents.get("NSObject"), AL.getLoc(),
1430
8
                       S.getScopeForContext(D->getDeclContext()->getParent()));
1431
8
    if (!PT) {
1432
0
      S.Diag(AL.getLoc(), diag::err_iboutletcollection_type) << "NSObject";
1433
0
      return;
1434
0
    }
1435
31
  }
1436
31
1437
31
  TypeSourceInfo *QTLoc = nullptr;
1438
31
  QualType QT = S.GetTypeFromParser(PT, &QTLoc);
1439
31
  if (!QTLoc)
1440
8
    QTLoc = S.Context.getTrivialTypeSourceInfo(QT, AL.getLoc());
1441
31
1442
31
  // Diagnose use of non-object type in iboutletcollection attribute.
1443
31
  // FIXME. Gnu attribute extension ignores use of builtin types in
1444
31
  // attributes. So, __attribute__((iboutletcollection(char))) will be
1445
31
  // treated as __attribute__((iboutletcollection())).
1446
31
  if (!QT->isObjCIdType() && 
!QT->isObjCObjectType()26
) {
1447
4
    S.Diag(AL.getLoc(),
1448
4
           QT->isBuiltinType() ? 
diag::err_iboutletcollection_builtintype2
1449
4
                               : 
diag::err_iboutletcollection_type2
) << QT;
1450
4
    return;
1451
4
  }
1452
27
1453
27
  D->addAttr(::new (S.Context) IBOutletCollectionAttr(S.Context, AL, QTLoc));
1454
27
}
1455
1456
54.2k
bool Sema::isValidPointerAttrType(QualType T, bool RefOkay) {
1457
54.2k
  if (RefOkay) {
1458
25.1k
    if (T->isReferenceType())
1459
2
      return true;
1460
29.1k
  } else {
1461
29.1k
    T = T.getNonReferenceType();
1462
29.1k
  }
1463
54.2k
1464
54.2k
  // The nonnull attribute, and other similar attributes, can be applied to a
1465
54.2k
  // transparent union that contains a pointer type.
1466
54.2k
  
if (const RecordType *54.2k
UT54.2k
= T->getAsUnionType()) {
1467
18
    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
1468
18
      RecordDecl *UD = UT->getDecl();
1469
23
      for (const auto *I : UD->fields()) {
1470
23
        QualType QT = I->getType();
1471
23
        if (QT->isAnyPointerType() || 
QT->isBlockPointerType()5
)
1472
18
          return true;
1473
23
      }
1474
18
    }
1475
18
  }
1476
54.2k
1477
54.2k
  
return 54.2k
T->isAnyPointerType()54.2k
||
T->isBlockPointerType()26.2k
;
1478
54.2k
}
1479
1480
static bool attrNonNullArgCheck(Sema &S, QualType T, const ParsedAttr &AL,
1481
                                SourceRange AttrParmRange,
1482
                                SourceRange TypeRange,
1483
28.1k
                                bool isReturnValue = false) {
1484
28.1k
  if (!S.isValidPointerAttrType(T)) {
1485
17
    if (isReturnValue)
1486
6
      S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only)
1487
6
          << AL << AttrParmRange << TypeRange;
1488
11
    else
1489
11
      S.Diag(AL.getLoc(), diag::warn_attribute_pointers_only)
1490
11
          << AL << AttrParmRange << TypeRange << 0;
1491
17
    return false;
1492
17
  }
1493
28.1k
  return true;
1494
28.1k
}
1495
1496
38.9k
static void handleNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1497
38.9k
  SmallVector<ParamIdx, 8> NonNullArgs;
1498
67.1k
  for (unsigned I = 0; I < AL.getNumArgs(); 
++I28.1k
) {
1499
28.1k
    Expr *Ex = AL.getArgAsExpr(I);
1500
28.1k
    ParamIdx Idx;
1501
28.1k
    if (!checkFunctionOrMethodParameterIndex(S, D, AL, I + 1, Ex, Idx))
1502
5
      return;
1503
28.1k
1504
28.1k
    // Is the function argument a pointer type?
1505
28.1k
    if (Idx.getASTIndex() < getFunctionOrMethodNumParams(D) &&
1506
28.1k
        !attrNonNullArgCheck(
1507
28.1k
            S, getFunctionOrMethodParamType(D, Idx.getASTIndex()), AL,
1508
28.1k
            Ex->getSourceRange(),
1509
28.1k
            getFunctionOrMethodParamRange(D, Idx.getASTIndex())))
1510
7
      continue;
1511
28.1k
1512
28.1k
    NonNullArgs.push_back(Idx);
1513
28.1k
  }
1514
38.9k
1515
38.9k
  // If no arguments were specified to __attribute__((nonnull)) then all pointer
1516
38.9k
  // arguments have a nonnull attribute; warn if there aren't any. Skip this
1517
38.9k
  // check if the attribute came from a macro expansion or a template
1518
38.9k
  // instantiation.
1519
38.9k
  
if (38.9k
NonNullArgs.empty()38.9k
&&
AL.getLoc().isFileID()13.2k
&&
1520
38.9k
      
!S.inTemplateInstantiation()57
) {
1521
57
    bool AnyPointers = isFunctionOrMethodVariadic(D);
1522
57
    for (unsigned I = 0, E = getFunctionOrMethodNumParams(D);
1523
103
         I != E && 
!AnyPointers73
;
++I46
) {
1524
46
      QualType T = getFunctionOrMethodParamType(D, I);
1525
46
      if (T->isDependentType() || 
S.isValidPointerAttrType(T)45
)
1526
39
        AnyPointers = true;
1527
46
    }
1528
57
1529
57
    if (!AnyPointers)
1530
6
      S.Diag(AL.getLoc(), diag::warn_attribute_nonnull_no_pointers);
1531
57
  }
1532
38.9k
1533
38.9k
  ParamIdx *Start = NonNullArgs.data();
1534
38.9k
  unsigned Size = NonNullArgs.size();
1535
38.9k
  llvm::array_pod_sort(Start, Start + Size);
1536
38.9k
  D->addAttr(::new (S.Context) NonNullAttr(S.Context, AL, Start, Size));
1537
38.9k
}
1538
1539
static void handleNonNullAttrParameter(Sema &S, ParmVarDecl *D,
1540
32
                                       const ParsedAttr &AL) {
1541
32
  if (AL.getNumArgs() > 0) {
1542
6
    if (D->getFunctionType()) {
1543
3
      handleNonNullAttr(S, D, AL);
1544
3
    } else {
1545
3
      S.Diag(AL.getLoc(), diag::warn_attribute_nonnull_parm_no_args)
1546
3
        << D->getSourceRange();
1547
3
    }
1548
6
    return;
1549
6
  }
1550
26
1551
26
  // Is the argument a pointer type?
1552
26
  if (!attrNonNullArgCheck(S, D->getType(), AL, SourceRange(),
1553
26
                           D->getSourceRange()))
1554
4
    return;
1555
22
1556
22
  D->addAttr(::new (S.Context) NonNullAttr(S.Context, AL, nullptr, 0));
1557
22
}
1558
1559
29
static void handleReturnsNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1560
29
  QualType ResultType = getFunctionOrMethodResultType(D);
1561
29
  SourceRange SR = getFunctionOrMethodResultSourceRange(D);
1562
29
  if (!attrNonNullArgCheck(S, ResultType, AL, SourceRange(), SR,
1563
29
                           /* isReturnValue */ true))
1564
6
    return;
1565
23
1566
23
  D->addAttr(::new (S.Context) ReturnsNonNullAttr(S.Context, AL));
1567
23
}
1568
1569
25.0k
static void handleNoEscapeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1570
25.0k
  if (D->isInvalidDecl())
1571
0
    return;
1572
25.0k
1573
25.0k
  // noescape only applies to pointer types.
1574
25.0k
  QualType T = cast<ParmVarDecl>(D)->getType();
1575
25.0k
  if (!S.isValidPointerAttrType(T, /* RefOkay */ true)) {
1576
6
    S.Diag(AL.getLoc(), diag::warn_attribute_pointers_only)
1577
6
        << AL << AL.getRange() << 0;
1578
6
    return;
1579
6
  }
1580
25.0k
1581
25.0k
  D->addAttr(::new (S.Context) NoEscapeAttr(S.Context, AL));
1582
25.0k
}
1583
1584
27
static void handleAssumeAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1585
27
  Expr *E = AL.getArgAsExpr(0),
1586
27
       *OE = AL.getNumArgs() > 1 ? 
AL.getArgAsExpr(1)9
:
nullptr18
;
1587
27
  S.AddAssumeAlignedAttr(D, AL, E, OE);
1588
27
}
1589
1590
36
static void handleAllocAlignAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1591
36
  S.AddAllocAlignAttr(D, AL, AL.getArgAsExpr(0));
1592
36
}
1593
1594
void Sema::AddAssumeAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
1595
35
                                Expr *OE) {
1596
35
  QualType ResultType = getFunctionOrMethodResultType(D);
1597
35
  SourceRange SR = getFunctionOrMethodResultSourceRange(D);
1598
35
1599
35
  AssumeAlignedAttr TmpAttr(Context, CI, E, OE);
1600
35
  SourceLocation AttrLoc = TmpAttr.getLocation();
1601
35
1602
35
  if (!isValidPointerAttrType(ResultType, /* RefOkay */ true)) {
1603
3
    Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)
1604
3
        << &TmpAttr << TmpAttr.getRange() << SR;
1605
3
    return;
1606
3
  }
1607
32
1608
32
  if (!E->isValueDependent()) {
1609
28
    llvm::APSInt I(64);
1610
28
    if (!E->isIntegerConstantExpr(I, Context)) {
1611
0
      if (OE)
1612
0
        Diag(AttrLoc, diag::err_attribute_argument_n_type)
1613
0
          << &TmpAttr << 1 << AANT_ArgumentIntegerConstant
1614
0
          << E->getSourceRange();
1615
0
      else
1616
0
        Diag(AttrLoc, diag::err_attribute_argument_type)
1617
0
          << &TmpAttr << AANT_ArgumentIntegerConstant
1618
0
          << E->getSourceRange();
1619
0
      return;
1620
0
    }
1621
28
1622
28
    if (!I.isPowerOf2()) {
1623
5
      Diag(AttrLoc, diag::err_alignment_not_power_of_two)
1624
5
        << E->getSourceRange();
1625
5
      return;
1626
5
    }
1627
23
1628
23
    if (I > Sema::MaximumAlignment)
1629
5
      Diag(CI.getLoc(), diag::warn_assume_aligned_too_great)
1630
5
          << CI.getRange() << Sema::MaximumAlignment;
1631
23
  }
1632
32
1633
32
  
if (27
OE27
) {
1634
10
    if (!OE->isValueDependent()) {
1635
8
      llvm::APSInt I(64);
1636
8
      if (!OE->isIntegerConstantExpr(I, Context)) {
1637
0
        Diag(AttrLoc, diag::err_attribute_argument_n_type)
1638
0
          << &TmpAttr << 2 << AANT_ArgumentIntegerConstant
1639
0
          << OE->getSourceRange();
1640
0
        return;
1641
0
      }
1642
27
    }
1643
10
  }
1644
27
1645
27
  D->addAttr(::new (Context) AssumeAlignedAttr(Context, CI, E, OE));
1646
27
}
1647
1648
void Sema::AddAllocAlignAttr(Decl *D, const AttributeCommonInfo &CI,
1649
44
                             Expr *ParamExpr) {
1650
44
  QualType ResultType = getFunctionOrMethodResultType(D);
1651
44
1652
44
  AllocAlignAttr TmpAttr(Context, CI, ParamIdx());
1653
44
  SourceLocation AttrLoc = CI.getLoc();
1654
44
1655
44
  if (!ResultType->isDependentType() &&
1656
44
      
!isValidPointerAttrType(ResultType, /* RefOkay */ true)42
) {
1657
2
    Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)
1658
2
        << &TmpAttr << CI.getRange() << getFunctionOrMethodResultSourceRange(D);
1659
2
    return;
1660
2
  }
1661
42
1662
42
  ParamIdx Idx;
1663
42
  const auto *FuncDecl = cast<FunctionDecl>(D);
1664
42
  if (!checkFunctionOrMethodParameterIndex(*this, FuncDecl, TmpAttr,
1665
42
                                           /*AttrArgNum=*/1, ParamExpr, Idx))
1666
5
    return;
1667
37
1668
37
  QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex());
1669
37
  if (!Ty->isDependentType() && 
!Ty->isIntegralType(Context)35
&&
1670
37
      
!Ty->isAlignValT()9
) {
1671
3
    Diag(ParamExpr->getBeginLoc(), diag::err_attribute_integers_only)
1672
3
        << &TmpAttr
1673
3
        << FuncDecl->getParamDecl(Idx.getASTIndex())->getSourceRange();
1674
3
    return;
1675
3
  }
1676
34
1677
34
  D->addAttr(::new (Context) AllocAlignAttr(Context, CI, Idx));
1678
34
}
1679
1680
/// Normalize the attribute, __foo__ becomes foo.
1681
/// Returns true if normalization was applied.
1682
36.1k
static bool normalizeName(StringRef &AttrName) {
1683
36.1k
  if (AttrName.size() > 4 && 
AttrName.startswith("__")35.8k
&&
1684
36.1k
      
AttrName.endswith("__")33.7k
) {
1685
33.7k
    AttrName = AttrName.drop_front(2).drop_back(2);
1686
33.7k
    return true;
1687
33.7k
  }
1688
2.41k
  return false;
1689
2.41k
}
1690
1691
50
static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1692
50
  // This attribute must be applied to a function declaration. The first
1693
50
  // argument to the attribute must be an identifier, the name of the resource,
1694
50
  // for example: malloc. The following arguments must be argument indexes, the
1695
50
  // arguments must be of integer type for Returns, otherwise of pointer type.
1696
50
  // The difference between Holds and Takes is that a pointer may still be used
1697
50
  // after being held. free() should be __attribute((ownership_takes)), whereas
1698
50
  // a list append function may well be __attribute((ownership_holds)).
1699
50
1700
50
  if (!AL.isArgIdent(0)) {
1701
1
    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
1702
1
        << AL << 1 << AANT_ArgumentIdentifier;
1703
1
    return;
1704
1
  }
1705
49
1706
49
  // Figure out our Kind.
1707
49
  OwnershipAttr::OwnershipKind K =
1708
49
      OwnershipAttr(S.Context, AL, nullptr, nullptr, 0).getOwnKind();
1709
49
1710
49
  // Check arguments.
1711
49
  switch (K) {
1712
31
  case OwnershipAttr::Takes:
1713
31
  case OwnershipAttr::Holds:
1714
31
    if (AL.getNumArgs() < 2) {
1715
2
      S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) << AL << 2;
1716
2
      return;
1717
2
    }
1718
29
    break;
1719
29
  case OwnershipAttr::Returns:
1720
18
    if (AL.getNumArgs() > 2) {
1721
1
      S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 1;
1722
1
      return;
1723
1
    }
1724
17
    break;
1725
46
  }
1726
46
1727
46
  IdentifierInfo *Module = AL.getArgAsIdent(0)->Ident;
1728
46
1729
46
  StringRef ModuleName = Module->getName();
1730
46
  if (normalizeName(ModuleName)) {
1731
0
    Module = &S.PP.getIdentifierTable().get(ModuleName);
1732
0
  }
1733
46
1734
46
  SmallVector<ParamIdx, 8> OwnershipArgs;
1735
88
  for (unsigned i = 1; i < AL.getNumArgs(); 
++i42
) {
1736
51
    Expr *Ex = AL.getArgAsExpr(i);
1737
51
    ParamIdx Idx;
1738
51
    if (!checkFunctionOrMethodParameterIndex(S, D, AL, i, Ex, Idx))
1739
3
      return;
1740
48
1741
48
    // Is the function argument a pointer type?
1742
48
    QualType T = getFunctionOrMethodParamType(D, Idx.getASTIndex());
1743
48
    int Err = -1;  // No error
1744
48
    switch (K) {
1745
37
      case OwnershipAttr::Takes:
1746
37
      case OwnershipAttr::Holds:
1747
37
        if (!T->isAnyPointerType() && 
!T->isBlockPointerType()1
)
1748
1
          Err = 0;
1749
37
        break;
1750
37
      case OwnershipAttr::Returns:
1751
11
        if (!T->isIntegerType())
1752
2
          Err = 1;
1753
11
        break;
1754
48
    }
1755
48
    if (-1 != Err) {
1756
3
      S.Diag(AL.getLoc(), diag::err_ownership_type) << AL << Err
1757
3
                                                    << Ex->getSourceRange();
1758
3
      return;
1759
3
    }
1760
45
1761
45
    // Check we don't have a conflict with another ownership attribute.
1762
45
    for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
1763
8
      // Cannot have two ownership attributes of different kinds for the same
1764
8
      // index.
1765
8
      if (I->getOwnKind() != K && I->args_end() !=
1766
2
          std::find(I->args_begin(), I->args_end(), Idx)) {
1767
1
        S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << I;
1768
1
        return;
1769
7
      } else if (K == OwnershipAttr::Returns &&
1770
7
                 
I->getOwnKind() == OwnershipAttr::Returns2
) {
1771
2
        // A returns attribute conflicts with any other returns attribute using
1772
2
        // a different index.
1773
2
        if (std::find(I->args_begin(), I->args_end(), Idx) == I->args_end()) {
1774
2
          S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch)
1775
2
              << I->args_begin()->getSourceIndex();
1776
2
          if (I->args_size())
1777
2
            S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch)
1778
2
                << Idx.getSourceIndex() << Ex->getSourceRange();
1779
2
          return;
1780
2
        }
1781
2
      }
1782
8
    }
1783
45
    OwnershipArgs.push_back(Idx);
1784
42
  }
1785
46
1786
46
  ParamIdx *Start = OwnershipArgs.data();
1787
37
  unsigned Size = OwnershipArgs.size();
1788
37
  llvm::array_pod_sort(Start, Start + Size);
1789
37
  D->addAttr(::new (S.Context)
1790
37
                 OwnershipAttr(S.Context, AL, Module, Start, Size));
1791
37
}
1792
1793
48
static void handleWeakRefAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1794
48
  // Check the attribute arguments.
1795
48
  if (AL.getNumArgs() > 1) {
1796
0
    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
1797
0
    return;
1798
0
  }
1799
48
1800
48
  // gcc rejects
1801
48
  // class c {
1802
48
  //   static int a __attribute__((weakref ("v2")));
1803
48
  //   static int b() __attribute__((weakref ("f3")));
1804
48
  // };
1805
48
  // and ignores the attributes of
1806
48
  // void f(void) {
1807
48
  //   static int a __attribute__((weakref ("v2")));
1808
48
  // }
1809
48
  // we reject them
1810
48
  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
1811
48
  if (!Ctx->isFileContext()) {
1812
3
    S.Diag(AL.getLoc(), diag::err_attribute_weakref_not_global_context)
1813
3
        << cast<NamedDecl>(D);
1814
3
    return;
1815
3
  }
1816
45
1817
45
  // The GCC manual says
1818
45
  //
1819
45
  // At present, a declaration to which `weakref' is attached can only
1820
45
  // be `static'.
1821
45
  //
1822
45
  // It also says
1823
45
  //
1824
45
  // Without a TARGET,
1825
45
  // given as an argument to `weakref' or to `alias', `weakref' is
1826
45
  // equivalent to `weak'.
1827
45
  //
1828
45
  // gcc 4.4.1 will accept
1829
45
  // int a7 __attribute__((weakref));
1830
45
  // as
1831
45
  // int a7 __attribute__((weak));
1832
45
  // This looks like a bug in gcc. We reject that for now. We should revisit
1833
45
  // it if this behaviour is actually used.
1834
45
1835
45
  // GCC rejects
1836
45
  // static ((alias ("y"), weakref)).
1837
45
  // Should we? How to check that weakref is before or after alias?
1838
45
1839
45
  // FIXME: it would be good for us to keep the WeakRefAttr as-written instead
1840
45
  // of transforming it into an AliasAttr.  The WeakRefAttr never uses the
1841
45
  // StringRef parameter it was given anyway.
1842
45
  StringRef Str;
1843
45
  if (AL.getNumArgs() && 
S.checkStringLiteralArgumentAttr(AL, 0, Str)36
)
1844
35
    // GCC will accept anything as the argument of weakref. Should we
1845
35
    // check for an existing decl?
1846
35
    D->addAttr(::new (S.Context) AliasAttr(S.Context, AL, Str));
1847
45
1848
45
  D->addAttr(::new (S.Context) WeakRefAttr(S.Context, AL));
1849
45
}
1850
1851
12
static void handleIFuncAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1852
12
  StringRef Str;
1853
12
  if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
1854
0
    return;
1855
12
1856
12
  // Aliases should be on declarations, not definitions.
1857
12
  const auto *FD = cast<FunctionDecl>(D);
1858
12
  if (FD->isThisDeclarationADefinition()) {
1859
0
    S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 1;
1860
0
    return;
1861
0
  }
1862
12
1863
12
  D->addAttr(::new (S.Context) IFuncAttr(S.Context, AL, Str));
1864
12
}
1865
1866
124
static void handleAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1867
124
  StringRef Str;
1868
124
  if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
1869
0
    return;
1870
124
1871
124
  if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
1872
1
    S.Diag(AL.getLoc(), diag::err_alias_not_supported_on_darwin);
1873
1
    return;
1874
1
  }
1875
123
  if (S.Context.getTargetInfo().getTriple().isNVPTX()) {
1876
1
    S.Diag(AL.getLoc(), diag::err_alias_not_supported_on_nvptx);
1877
1
  }
1878
123
1879
123
  // Aliases should be on declarations, not definitions.
1880
123
  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
1881
92
    if (FD->isThisDeclarationADefinition()) {
1882
0
      S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 0;
1883
0
      return;
1884
0
    }
1885
31
  } else {
1886
31
    const auto *VD = cast<VarDecl>(D);
1887
31
    if (VD->isThisDeclarationADefinition() && 
VD->isExternallyVisible()10
) {
1888
1
      S.Diag(AL.getLoc(), diag::err_alias_is_definition) << VD << 0;
1889
1
      return;
1890
1
    }
1891
122
  }
1892
122
1893
122
  // Mark target used to prevent unneeded-internal-declaration warnings.
1894
122
  if (!S.LangOpts.CPlusPlus) {
1895
109
    // FIXME: demangle Str for C++, as the attribute refers to the mangled
1896
109
    // linkage name, not the pre-mangled identifier.
1897
109
    const DeclarationNameInfo target(&S.Context.Idents.get(Str), AL.getLoc());
1898
109
    LookupResult LR(S, target, Sema::LookupOrdinaryName);
1899
109
    if (S.LookupQualifiedName(LR, S.getCurLexicalContext()))
1900
88
      for (NamedDecl *ND : LR)
1901
88
        ND->markUsed(S.Context);
1902
109
  }
1903
122
1904
122
  D->addAttr(::new (S.Context) AliasAttr(S.Context, AL, Str));
1905
122
}
1906
1907
25
static void handleTLSModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1908
25
  StringRef Model;
1909
25
  SourceLocation LiteralLoc;
1910
25
  // Check that it is a string.
1911
25
  if (!S.checkStringLiteralArgumentAttr(AL, 0, Model, &LiteralLoc))
1912
1
    return;
1913
24
1914
24
  // Check that the value.
1915
24
  if (Model != "global-dynamic" && 
Model != "local-dynamic"20
1916
24
      && 
Model != "initial-exec"17
&&
Model != "local-exec"5
) {
1917
1
    S.Diag(LiteralLoc, diag::err_attr_tlsmodel_arg);
1918
1
    return;
1919
1
  }
1920
23
1921
23
  D->addAttr(::new (S.Context) TLSModelAttr(S.Context, AL, Model));
1922
23
}
1923
1924
4.89k
static void handleRestrictAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1925
4.89k
  QualType ResultType = getFunctionOrMethodResultType(D);
1926
4.89k
  if (ResultType->isAnyPointerType() || 
ResultType->isBlockPointerType()5
) {
1927
4.88k
    D->addAttr(::new (S.Context) RestrictAttr(S.Context, AL));
1928
4.88k
    return;
1929
4.88k
  }
1930
4
1931
4
  S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only)
1932
4
      << AL << getFunctionOrMethodResultSourceRange(D);
1933
4
}
1934
1935
109
static void handleCPUSpecificAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1936
109
  FunctionDecl *FD = cast<FunctionDecl>(D);
1937
109
1938
109
  if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
1939
18
    if (MD->getParent()->isLambda()) {
1940
1
      S.Diag(AL.getLoc(), diag::err_attribute_dll_lambda) << AL;
1941
1
      return;
1942
1
    }
1943
108
  }
1944
108
1945
108
  if (!checkAttributeAtLeastNumArgs(S, AL, 1))
1946
2
    return;
1947
106
1948
106
  SmallVector<IdentifierInfo *, 8> CPUs;
1949
264
  for (unsigned ArgNo = 0; ArgNo < getNumAttributeArgs(AL); 
++ArgNo158
) {
1950
162
    if (!AL.isArgIdent(ArgNo)) {
1951
0
      S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1952
0
          << AL << AANT_ArgumentIdentifier;
1953
0
      return;
1954
0
    }
1955
162
1956
162
    IdentifierLoc *CPUArg = AL.getArgAsIdent(ArgNo);
1957
162
    StringRef CPUName = CPUArg->Ident->getName().trim();
1958
162
1959
162
    if (!S.Context.getTargetInfo().validateCPUSpecificCPUDispatch(CPUName)) {
1960
2
      S.Diag(CPUArg->Loc, diag::err_invalid_cpu_specific_dispatch_value)
1961
2
          << CPUName << (AL.getKind() == ParsedAttr::AT_CPUDispatch);
1962
2
      return;
1963
2
    }
1964
160
1965
160
    const TargetInfo &Target = S.Context.getTargetInfo();
1966
160
    if (llvm::any_of(CPUs, [CPUName, &Target](const IdentifierInfo *Cur) {
1967
83
          return Target.CPUSpecificManglingCharacter(CPUName) ==
1968
83
                 Target.CPUSpecificManglingCharacter(Cur->getName());
1969
83
        })) {
1970
2
      S.Diag(AL.getLoc(), diag::warn_multiversion_duplicate_entries);
1971
2
      return;
1972
2
    }
1973
158
    CPUs.push_back(CPUArg->Ident);
1974
158
  }
1975
106
1976
106
  FD->setIsMultiVersion(true);
1977
102
  if (AL.getKind() == ParsedAttr::AT_CPUSpecific)
1978
69
    D->addAttr(::new (S.Context)
1979
69
                   CPUSpecificAttr(S.Context, AL, CPUs.data(), CPUs.size()));
1980
33
  else
1981
33
    D->addAttr(::new (S.Context)
1982
33
                   CPUDispatchAttr(S.Context, AL, CPUs.data(), CPUs.size()));
1983
102
}
1984
1985
9
static void handleCommonAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1986
9
  if (S.LangOpts.CPlusPlus) {
1987
1
    S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)
1988
1
        << AL << AttributeLangSupport::Cpp;
1989
1
    return;
1990
1
  }
1991
8
1992
8
  if (CommonAttr *CA = S.mergeCommonAttr(D, AL))
1993
7
    D->addAttr(CA);
1994
8
}
1995
1996
31
static void handleNakedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1997
31
  if (checkAttrMutualExclusion<DisableTailCallsAttr>(S, D, AL))
1998
1
    return;
1999
30
2000
30
  if (AL.isDeclspecAttribute()) {
2001
9
    const auto &Triple = S.getASTContext().getTargetInfo().getTriple();
2002
9
    const auto &Arch = Triple.getArch();
2003
9
    if (Arch != llvm::Triple::x86 &&
2004
9
        
(2
Arch != llvm::Triple::arm2
&&
Arch != llvm::Triple::thumb2
)) {
2005
1
      S.Diag(AL.getLoc(), diag::err_attribute_not_supported_on_arch)
2006
1
          << AL << Triple.getArchName();
2007
1
      return;
2008
1
    }
2009
29
  }
2010
29
2011
29
  D->addAttr(::new (S.Context) NakedAttr(S.Context, AL));
2012
29
}
2013
2014
7.35k
static void handleNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
2015
7.35k
  if (hasDeclarator(D)) 
return7.33k
;
2016
18
2017
18
  if (!isa<ObjCMethodDecl>(D)) {
2018
4
    S.Diag(Attrs.getLoc(), diag::warn_attribute_wrong_decl_type)
2019
4
        << Attrs << ExpectedFunctionOrMethod;
2020
4
    return;
2021
4
  }
2022
14
2023
14
  D->addAttr(::new (S.Context) NoReturnAttr(S.Context, Attrs));
2024
14
}
2025
2026
10
static void handleNoCfCheckAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
2027
10
  if (!S.getLangOpts().CFProtectionBranch)
2028
0
    S.Diag(Attrs.getLoc(), diag::warn_nocf_check_attribute_ignored);
2029
10
  else
2030
10
    handleSimpleAttribute<AnyX86NoCfCheckAttr>(S, D, Attrs);
2031
10
}
2032
2033
15.2k
bool Sema::CheckAttrNoArgs(const ParsedAttr &Attrs) {
2034
15.2k
  if (!checkAttributeNumArgs(*this, Attrs, 0)) {
2035
6
    Attrs.setInvalid();
2036
6
    return true;
2037
6
  }
2038
15.2k
2039
15.2k
  return false;
2040
15.2k
}
2041
2042
12.4M
bool Sema::CheckAttrTarget(const ParsedAttr &AL) {
2043
12.4M
  // Check whether the attribute is valid on the current target.
2044
12.4M
  if (!AL.existsInTarget(Context.getTargetInfo())) {
2045
11
    Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored) << AL;
2046
11
    AL.setInvalid();
2047
11
    return true;
2048
11
  }
2049
12.4M
2050
12.4M
  return false;
2051
12.4M
}
2052
2053
7
static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2054
7
2055
7
  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
2056
7
  // because 'analyzer_noreturn' does not impact the type.
2057
7
  if (!isFunctionOrMethodOrBlock(D)) {
2058
0
    ValueDecl *VD = dyn_cast<ValueDecl>(D);
2059
0
    if (!VD || (!VD->getType()->isBlockPointerType() &&
2060
0
                !VD->getType()->isFunctionPointerType())) {
2061
0
      S.Diag(AL.getLoc(), AL.isCXX11Attribute()
2062
0
                              ? diag::err_attribute_wrong_decl_type
2063
0
                              : diag::warn_attribute_wrong_decl_type)
2064
0
          << AL << ExpectedFunctionMethodOrBlock;
2065
0
      return;
2066
0
    }
2067
7
  }
2068
7
2069
7
  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(S.Context, AL));
2070
7
}
2071
2072
// PS3 PPU-specific.
2073
11
static void handleVecReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2074
11
  /*
2075
11
    Returning a Vector Class in Registers
2076
11
2077
11
    According to the PPU ABI specifications, a class with a single member of
2078
11
    vector type is returned in memory when used as the return value of a
2079
11
    function.
2080
11
    This results in inefficient code when implementing vector classes. To return
2081
11
    the value in a single vector register, add the vecreturn attribute to the
2082
11
    class definition. This attribute is also applicable to struct types.
2083
11
2084
11
    Example:
2085
11
2086
11
    struct Vector
2087
11
    {
2088
11
      __vector float xyzw;
2089
11
    } __attribute__((vecreturn));
2090
11
2091
11
    Vector Add(Vector lhs, Vector rhs)
2092
11
    {
2093
11
      Vector result;
2094
11
      result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
2095
11
      return result; // This will be returned in a register
2096
11
    }
2097
11
  */
2098
11
  if (VecReturnAttr *A = D->getAttr<VecReturnAttr>()) {
2099
1
    S.Diag(AL.getLoc(), diag::err_repeat_attribute) << A;
2100
1
    return;
2101
1
  }
2102
10
2103
10
  const auto *R = cast<RecordDecl>(D);
2104
10
  int count = 0;
2105
10
2106
10
  if (!isa<CXXRecordDecl>(R)) {
2107
0
    S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
2108
0
    return;
2109
0
  }
2110
10
2111
10
  if (!cast<CXXRecordDecl>(R)->isPOD()) {
2112
3
    S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
2113
3
    return;
2114
3
  }
2115
7
2116
10
  
for (const auto *I : R->fields())7
{
2117
10
    if ((count == 1) || 
!I->getType()->isVectorType()7
) {
2118
3
      S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
2119
3
      return;
2120
3
    }
2121
7
    count++;
2122
7
  }
2123
7
2124
7
  D->addAttr(::new (S.Context) VecReturnAttr(S.Context, AL));
2125
4
}
2126
2127
static void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D,
2128
27
                                 const ParsedAttr &AL) {
2129
27
  if (isa<ParmVarDecl>(D)) {
2130
14
    // [[carries_dependency]] can only be applied to a parameter if it is a
2131
14
    // parameter of a function declaration or lambda.
2132
14
    if (!(Scope->getFlags() & clang::Scope::FunctionDeclarationScope)) {
2133
6
      S.Diag(AL.getLoc(),
2134
6
             diag::err_carries_dependency_param_not_function_decl);
2135
6
      return;
2136
6
    }
2137
21
  }
2138
21
2139
21
  D->addAttr(::new (S.Context) CarriesDependencyAttr(S.Context, AL));
2140
21
}
2141
2142
18.9k
static void handleUnusedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2143
18.9k
  bool IsCXX17Attr = AL.isCXX11Attribute() && 
!AL.getScopeName()25
;
2144
18.9k
2145
18.9k
  // If this is spelled as the standard C++17 attribute, but not in C++17, warn
2146
18.9k
  // about using it as an extension.
2147
18.9k
  if (!S.getLangOpts().CPlusPlus17 && 
IsCXX17Attr17.9k
)
2148
5
    S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
2149
18.9k
2150
18.9k
  D->addAttr(::new (S.Context) UnusedAttr(S.Context, AL));
2151
18.9k
}
2152
2153
23
static void handleConstructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2154
23
  uint32_t priority = ConstructorAttr::DefaultPriority;
2155
23
  if (AL.getNumArgs() &&
2156
23
      
!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), priority)6
)
2157
4
    return;
2158
19
2159
19
  D->addAttr(::new (S.Context) ConstructorAttr(S.Context, AL, priority));
2160
19
}
2161
2162
23
static void handleDestructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2163
23
  uint32_t priority = DestructorAttr::DefaultPriority;
2164
23
  if (AL.getNumArgs() &&
2165
23
      
!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), priority)11
)
2166
1
    return;
2167
22
2168
22
  D->addAttr(::new (S.Context) DestructorAttr(S.Context, AL, priority));
2169
22
}
2170
2171
template <typename AttrTy>
2172
9.16k
static void handleAttrWithMessage(Sema &S, Decl *D, const ParsedAttr &AL) {
2173
9.16k
  // Handle the case where the attribute has a text message.
2174
9.16k
  StringRef Str;
2175
9.16k
  if (AL.getNumArgs() == 1 && 
!S.checkStringLiteralArgumentAttr(AL, 0, Str)1.61k
)
2176
1
    return;
2177
9.15k
2178
9.15k
  D->addAttr(::new (S.Context) AttrTy(S.Context, AL, Str));
2179
9.15k
}
2180
2181
static void handleObjCSuppresProtocolAttr(Sema &S, Decl *D,
2182
106
                                          const ParsedAttr &AL) {
2183
106
  if (!cast<ObjCProtocolDecl>(D)->isThisDeclarationADefinition()) {
2184
1
    S.Diag(AL.getLoc(), diag::err_objc_attr_protocol_requires_definition)
2185
1
        << AL << AL.getRange();
2186
1
    return;
2187
1
  }
2188
105
2189
105
  D->addAttr(::new (S.Context) ObjCExplicitProtocolImplAttr(S.Context, AL));
2190
105
}
2191
2192
static bool checkAvailabilityAttr(Sema &S, SourceRange Range,
2193
                                  IdentifierInfo *Platform,
2194
                                  VersionTuple Introduced,
2195
                                  VersionTuple Deprecated,
2196
6.27M
                                  VersionTuple Obsoleted) {
2197
6.27M
  StringRef PlatformName
2198
6.27M
    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
2199
6.27M
  if (PlatformName.empty())
2200
2.93k
    PlatformName = Platform->getName();
2201
6.27M
2202
6.27M
  // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
2203
6.27M
  // of these steps are needed).
2204
6.27M
  if (!Introduced.empty() && 
!Deprecated.empty()5.55M
&&
2205
6.27M
      
!(Introduced <= Deprecated)1.09M
) {
2206
7
    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2207
7
      << 1 << PlatformName << Deprecated.getAsString()
2208
7
      << 0 << Introduced.getAsString();
2209
7
    return true;
2210
7
  }
2211
6.27M
2212
6.27M
  if (!Introduced.empty() && 
!Obsoleted.empty()5.55M
&&
2213
6.27M
      
!(Introduced <= Obsoleted)31
) {
2214
0
    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2215
0
      << 2 << PlatformName << Obsoleted.getAsString()
2216
0
      << 0 << Introduced.getAsString();
2217
0
    return true;
2218
0
  }
2219
6.27M
2220
6.27M
  if (!Deprecated.empty() && 
!Obsoleted.empty()1.16M
&&
2221
6.27M
      
!(Deprecated <= Obsoleted)28
) {
2222
3
    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2223
3
      << 2 << PlatformName << Obsoleted.getAsString()
2224
3
      << 1 << Deprecated.getAsString();
2225
3
    return true;
2226
3
  }
2227
6.27M
2228
6.27M
  return false;
2229
6.27M
}
2230
2231
/// Check whether the two versions match.
2232
///
2233
/// If either version tuple is empty, then they are assumed to match. If
2234
/// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y.
2235
static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y,
2236
449k
                          bool BeforeIsOkay) {
2237
449k
  if (X.empty() || 
Y.empty()145k
)
2238
313k
    return true;
2239
136k
2240
136k
  if (X == Y)
2241
136k
    return true;
2242
724
2243
724
  if (BeforeIsOkay && 
X < Y103
)
2244
15
    return true;
2245
709
2246
709
  return false;
2247
709
}
2248
2249
AvailabilityAttr *Sema::mergeAvailabilityAttr(
2250
    NamedDecl *D, const AttributeCommonInfo &CI, IdentifierInfo *Platform,
2251
    bool Implicit, VersionTuple Introduced, VersionTuple Deprecated,
2252
    VersionTuple Obsoleted, bool IsUnavailable, StringRef Message,
2253
    bool IsStrict, StringRef Replacement, AvailabilityMergeKind AMK,
2254
6.25M
    int Priority) {
2255
6.25M
  VersionTuple MergedIntroduced = Introduced;
2256
6.25M
  VersionTuple MergedDeprecated = Deprecated;
2257
6.25M
  VersionTuple MergedObsoleted = Obsoleted;
2258
6.25M
  bool FoundAny = false;
2259
6.25M
  bool OverrideOrImpl = false;
2260
6.25M
  switch (AMK) {
2261
6.12M
  case AMK_None:
2262
6.12M
  case AMK_Redeclaration:
2263
6.12M
    OverrideOrImpl = false;
2264
6.12M
    break;
2265
6.12M
2266
6.12M
  case AMK_Override:
2267
131k
  case AMK_ProtocolImplementation:
2268
131k
    OverrideOrImpl = true;
2269
131k
    break;
2270
6.25M
  }
2271
6.25M
2272
6.25M
  if (D->hasAttrs()) {
2273
3.49M
    AttrVec &Attrs = D->getAttrs();
2274
10.4M
    for (unsigned i = 0, e = Attrs.size(); i != e;) {
2275
6.97M
      const auto *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]);
2276
6.97M
      if (!OldAA) {
2277
512k
        ++i;
2278
512k
        continue;
2279
512k
      }
2280
6.46M
2281
6.46M
      IdentifierInfo *OldPlatform = OldAA->getPlatform();
2282
6.46M
      if (OldPlatform != Platform) {
2283
6.31M
        ++i;
2284
6.31M
        continue;
2285
6.31M
      }
2286
150k
2287
150k
      // If there is an existing availability attribute for this platform that
2288
150k
      // has a lower priority use the existing one and discard the new
2289
150k
      // attribute.
2290
150k
      if (OldAA->getPriority() < Priority)
2291
10
        return nullptr;
2292
150k
2293
150k
      // If there is an existing attribute for this platform that has a higher
2294
150k
      // priority than the new attribute then erase the old one and continue
2295
150k
      // processing the attributes.
2296
150k
      if (OldAA->getPriority() > Priority) {
2297
94
        Attrs.erase(Attrs.begin() + i);
2298
94
        --e;
2299
94
        continue;
2300
94
      }
2301
150k
2302
150k
      FoundAny = true;
2303
150k
      VersionTuple OldIntroduced = OldAA->getIntroduced();
2304
150k
      VersionTuple OldDeprecated = OldAA->getDeprecated();
2305
150k
      VersionTuple OldObsoleted = OldAA->getObsoleted();
2306
150k
      bool OldIsUnavailable = OldAA->getUnavailable();
2307
150k
2308
150k
      if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl) ||
2309
150k
          
!versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl)149k
||
2310
150k
          
!versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl)149k
||
2311
150k
          
!(149k
OldIsUnavailable == IsUnavailable149k
||
2312
149k
            
(10
OverrideOrImpl10
&&
!OldIsUnavailable10
&&
IsUnavailable5
))) {
2313
670
        if (OverrideOrImpl) {
2314
49
          int Which = -1;
2315
49
          VersionTuple FirstVersion;
2316
49
          VersionTuple SecondVersion;
2317
49
          if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl)) {
2318
39
            Which = 0;
2319
39
            FirstVersion = OldIntroduced;
2320
39
            SecondVersion = Introduced;
2321
39
          } else 
if (10
!versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl)10
) {
2322
5
            Which = 1;
2323
5
            FirstVersion = Deprecated;
2324
5
            SecondVersion = OldDeprecated;
2325
5
          } else if (!versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl)) {
2326
0
            Which = 2;
2327
0
            FirstVersion = Obsoleted;
2328
0
            SecondVersion = OldObsoleted;
2329
0
          }
2330
49
2331
49
          if (Which == -1) {
2332
5
            Diag(OldAA->getLocation(),
2333
5
                 diag::warn_mismatched_availability_override_unavail)
2334
5
              << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
2335
5
              << (AMK == AMK_Override);
2336
44
          } else {
2337
44
            Diag(OldAA->getLocation(),
2338
44
                 diag::warn_mismatched_availability_override)
2339
44
              << Which
2340
44
              << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
2341
44
              << FirstVersion.getAsString() << SecondVersion.getAsString()
2342
44
              << (AMK == AMK_Override);
2343
44
          }
2344
49
          if (AMK == AMK_Override)
2345
15
            Diag(CI.getLoc(), diag::note_overridden_method);
2346
34
          else
2347
34
            Diag(CI.getLoc(), diag::note_protocol_method);
2348
621
        } else {
2349
621
          Diag(OldAA->getLocation(), diag::warn_mismatched_availability);
2350
621
          Diag(CI.getLoc(), diag::note_previous_attribute);
2351
621
        }
2352
670
2353
670
        Attrs.erase(Attrs.begin() + i);
2354
670
        --e;
2355
670
        continue;
2356
670
      }
2357
149k
2358
149k
      VersionTuple MergedIntroduced2 = MergedIntroduced;
2359
149k
      VersionTuple MergedDeprecated2 = MergedDeprecated;
2360
149k
      VersionTuple MergedObsoleted2 = MergedObsoleted;
2361
149k
2362
149k
      if (MergedIntroduced2.empty())
2363
9.16k
        MergedIntroduced2 = OldIntroduced;
2364
149k
      if (MergedDeprecated2.empty())
2365
136k
        MergedDeprecated2 = OldDeprecated;
2366
149k
      if (MergedObsoleted2.empty())
2367
149k
        MergedObsoleted2 = OldObsoleted;
2368
149k
2369
149k
      if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform,
2370
149k
                                MergedIntroduced2, MergedDeprecated2,
2371
149k
                                MergedObsoleted2)) {
2372
4
        Attrs.erase(Attrs.begin() + i);
2373
4
        --e;
2374
4
        continue;
2375
4
      }
2376
149k
2377
149k
      MergedIntroduced = MergedIntroduced2;
2378
149k
      MergedDeprecated = MergedDeprecated2;
2379
149k
      MergedObsoleted = MergedObsoleted2;
2380
149k
      ++i;
2381
149k
    }
2382
3.49M
  }
2383
6.25M
2384
6.25M
  
if (6.25M
FoundAny6.25M
&&
2385
6.25M
      
MergedIntroduced == Introduced150k
&&
2386
6.25M
      
MergedDeprecated == Deprecated146k
&&
2387
6.25M
      
MergedObsoleted == Obsoleted132k
)
2388
132k
    return nullptr;
2389
6.12M
2390
6.12M
  // Only create a new attribute if !OverrideOrImpl, but we want to do
2391
6.12M
  // the checking.
2392
6.12M
  if (!checkAvailabilityAttr(*this, CI.getRange(), Platform, MergedIntroduced,
2393
6.12M
                             MergedDeprecated, MergedObsoleted) &&
2394
6.12M
      
!OverrideOrImpl6.12M
) {
2395
6.12M
    auto *Avail = ::new (Context) AvailabilityAttr(
2396
6.12M
        Context, CI, Platform, Introduced, Deprecated, Obsoleted, IsUnavailable,
2397
6.12M
        Message, IsStrict, Replacement, Priority);
2398
6.12M
    Avail->setImplicit(Implicit);
2399
6.12M
    return Avail;
2400
6.12M
  }
2401
622
  return nullptr;
2402
622
}
2403
2404
6.11M
static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2405
6.11M
  if (!checkAttributeNumArgs(S, AL, 1))
2406
0
    return;
2407
6.11M
  IdentifierLoc *Platform = AL.getArgAsIdent(0);
2408
6.11M
2409
6.11M
  IdentifierInfo *II = Platform->Ident;
2410
6.11M
  if (AvailabilityAttr::getPrettyPlatformName(II->getName()).empty())
2411
2.93k
    S.Diag(Platform->Loc, diag::warn_availability_unknown_platform)
2412
2.93k
      << Platform->Ident;
2413
6.11M
2414
6.11M
  auto *ND = dyn_cast<NamedDecl>(D);
2415
6.11M
  if (!ND) // We warned about this already, so just return.
2416
0
    return;
2417
6.11M
2418
6.11M
  AvailabilityChange Introduced = AL.getAvailabilityIntroduced();
2419
6.11M
  AvailabilityChange Deprecated = AL.getAvailabilityDeprecated();
2420
6.11M
  AvailabilityChange Obsoleted = AL.getAvailabilityObsoleted();
2421
6.11M
  bool IsUnavailable = AL.getUnavailableLoc().isValid();
2422
6.11M
  bool IsStrict = AL.getStrictLoc().isValid();
2423
6.11M
  StringRef Str;
2424
6.11M
  if (const auto *SE = dyn_cast_or_null<StringLiteral>(AL.getMessageExpr()))
2425
495k
    Str = SE->getString();
2426
6.11M
  StringRef Replacement;
2427
6.11M
  if (const auto *SE = dyn_cast_or_null<StringLiteral>(AL.getReplacementExpr()))
2428
12.0k
    Replacement = SE->getString();
2429
6.11M
2430
6.11M
  if (II->isStr("swift")) {
2431
39.4k
    if (Introduced.isValid() || 
Obsoleted.isValid()39.4k
||
2432
39.4k
        
(39.4k
!IsUnavailable39.4k
&&
!Deprecated.isValid()3
)) {
2433
2
      S.Diag(AL.getLoc(),
2434
2
             diag::warn_availability_swift_unavailable_deprecated_only);
2435
2
      return;
2436
2
    }
2437
6.11M
  }
2438
6.11M
2439
6.11M
  int PriorityModifier = AL.isPragmaClangAttribute()
2440
6.11M
                             ? 
Sema::AP_PragmaClangAttribute55.6k
2441
6.11M
                             : 
Sema::AP_Explicit6.05M
;
2442
6.11M
  AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2443
6.11M
      ND, AL, II, false /*Implicit*/, Introduced.Version, Deprecated.Version,
2444
6.11M
      Obsoleted.Version, IsUnavailable, Str, IsStrict, Replacement,
2445
6.11M
      Sema::AMK_None, PriorityModifier);
2446
6.11M
  if (NewAttr)
2447
6.11M
    D->addAttr(NewAttr);
2448
6.11M
2449
6.11M
  // Transcribe "ios" to "watchos" (and add a new attribute) if the versioning
2450
6.11M
  // matches before the start of the watchOS platform.
2451
6.11M
  if (S.Context.getTargetInfo().getTriple().isWatchOS()) {
2452
621
    IdentifierInfo *NewII = nullptr;
2453
621
    if (II->getName() == "ios")
2454
259
      NewII = &S.Context.Idents.get("watchos");
2455
362
    else if (II->getName() == "ios_app_extension")
2456
0
      NewII = &S.Context.Idents.get("watchos_app_extension");
2457
621
2458
621
    if (NewII) {
2459
777
        auto adjustWatchOSVersion = [](VersionTuple Version) -> VersionTuple {
2460
777
          if (Version.empty())
2461
524
            return Version;
2462
253
          auto Major = Version.getMajor();
2463
253
          auto NewMajor = Major >= 9 ? 
Major - 737
:
0216
;
2464
253
          if (NewMajor >= 2) {
2465
37
            if (Version.getMinor().hasValue()) {
2466
36
              if (Version.getSubminor().hasValue())
2467
0
                return VersionTuple(NewMajor, Version.getMinor().getValue(),
2468
0
                                    Version.getSubminor().getValue());
2469
36
              else
2470
36
                return VersionTuple(NewMajor, Version.getMinor().getValue());
2471
1
            }
2472
1
            return VersionTuple(NewMajor);
2473
1
          }
2474
216
2475
216
          return VersionTuple(2, 0);
2476
216
        };
2477
259
2478
259
        auto NewIntroduced = adjustWatchOSVersion(Introduced.Version);
2479
259
        auto NewDeprecated = adjustWatchOSVersion(Deprecated.Version);
2480
259
        auto NewObsoleted = adjustWatchOSVersion(Obsoleted.Version);
2481
259
2482
259
        AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2483
259
            ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
2484
259
            NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,
2485
259
            Sema::AMK_None,
2486
259
            PriorityModifier + Sema::AP_InferredFromOtherPlatform);
2487
259
        if (NewAttr)
2488
257
          D->addAttr(NewAttr);
2489
259
      }
2490
6.11M
  } else if (S.Context.getTargetInfo().getTriple().isTvOS()) {
2491
650
    // Transcribe "ios" to "tvos" (and add a new attribute) if the versioning
2492
650
    // matches before the start of the tvOS platform.
2493
650
    IdentifierInfo *NewII = nullptr;
2494
650
    if (II->getName() == "ios")
2495
260
      NewII = &S.Context.Idents.get("tvos");
2496
390
    else if (II->getName() == "ios_app_extension")
2497
3
      NewII = &S.Context.Idents.get("tvos_app_extension");
2498
650
2499
650
    if (NewII) {
2500
263
      AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2501
263
          ND, AL, NewII, true /*Implicit*/, Introduced.Version,
2502
263
          Deprecated.Version, Obsoleted.Version, IsUnavailable, Str, IsStrict,
2503
263
          Replacement, Sema::AMK_None,
2504
263
          PriorityModifier + Sema::AP_InferredFromOtherPlatform);
2505
263
      if (NewAttr)
2506
256
        D->addAttr(NewAttr);
2507
263
      }
2508
650
  }
2509
6.11M
}
2510
2511
static void handleExternalSourceSymbolAttr(Sema &S, Decl *D,
2512
63
                                           const ParsedAttr &AL) {
2513
63
  if (!checkAttributeAtLeastNumArgs(S, AL, 1))
2514
3
    return;
2515
60
  assert(checkAttributeAtMostNumArgs(S, AL, 3) &&
2516
60
         "Invalid number of arguments in an external_source_symbol attribute");
2517
60
2518
60
  StringRef Language;
2519
60
  if (const auto *SE = dyn_cast_or_null<StringLiteral>(AL.getArgAsExpr(0)))
2520
49
    Language = SE->getString();
2521
60
  StringRef DefinedIn;
2522
60
  if (const auto *SE = dyn_cast_or_null<StringLiteral>(AL.getArgAsExpr(1)))
2523
47
    DefinedIn = SE->getString();
2524
60
  bool IsGeneratedDeclaration = AL.getArgAsIdent(2) != nullptr;
2525
60
2526
60
  D->addAttr(::new (S.Context) ExternalSourceSymbolAttr(
2527
60
      S.Context, AL, Language, DefinedIn, IsGeneratedDeclaration));
2528
60
}
2529
2530
template <class T>
2531
static T *mergeVisibilityAttr(Sema &S, Decl *D, const AttributeCommonInfo &CI,
2532
1.48M
                              typename T::VisibilityType value) {
2533
1.48M
  T *existingAttr = D->getAttr<T>();
2534
1.48M
  if (existingAttr) {
2535
36.3k
    typename T::VisibilityType existingValue = existingAttr->getVisibility();
2536
36.3k
    if (existingValue == value)
2537
36.3k
      return nullptr;
2538
6
    S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
2539
6
    S.Diag(CI.getLoc(), diag::note_previous_attribute);
2540
6
    D->dropAttr<T>();
2541
6
  }
2542
1.48M
  
return ::new (S.Context) T(S.Context, CI, value)1.44M
;
2543
1.48M
}
SemaDeclAttr.cpp:clang::VisibilityAttr* mergeVisibilityAttr<clang::VisibilityAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&, clang::VisibilityAttr::VisibilityType)
Line
Count
Source
2532
1.30M
                              typename T::VisibilityType value) {
2533
1.30M
  T *existingAttr = D->getAttr<T>();
2534
1.30M
  if (existingAttr) {
2535
26.9k
    typename T::VisibilityType existingValue = existingAttr->getVisibility();
2536
26.9k
    if (existingValue == value)
2537
26.9k
      return nullptr;
2538
6
    S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
2539
6
    S.Diag(CI.getLoc(), diag::note_previous_attribute);
2540
6
    D->dropAttr<T>();
2541
6
  }
2542
1.30M
  
return ::new (S.Context) T(S.Context, CI, value)1.28M
;
2543
1.30M
}
SemaDeclAttr.cpp:clang::TypeVisibilityAttr* mergeVisibilityAttr<clang::TypeVisibilityAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&, clang::TypeVisibilityAttr::VisibilityType)
Line
Count
Source
2532
173k
                              typename T::VisibilityType value) {
2533
173k
  T *existingAttr = D->getAttr<T>();
2534
173k
  if (existingAttr) {
2535
9.33k
    typename T::VisibilityType existingValue = existingAttr->getVisibility();
2536
9.33k
    if (existingValue == value)
2537
9.33k
      return nullptr;
2538
0
    S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
2539
0
    S.Diag(CI.getLoc(), diag::note_previous_attribute);
2540
0
    D->dropAttr<T>();
2541
0
  }
2542
173k
  
return ::new (S.Context) T(S.Context, CI, value)164k
;
2543
173k
}
2544
2545
VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D,
2546
                                          const AttributeCommonInfo &CI,
2547
1.30M
                                          VisibilityAttr::VisibilityType Vis) {
2548
1.30M
  return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, CI, Vis);
2549
1.30M
}
2550
2551
TypeVisibilityAttr *
2552
Sema::mergeTypeVisibilityAttr(Decl *D, const AttributeCommonInfo &CI,
2553
173k
                              TypeVisibilityAttr::VisibilityType Vis) {
2554
173k
  return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, CI, Vis);
2555
173k
}
2556
2557
static void handleVisibilityAttr(Sema &S, Decl *D, const ParsedAttr &AL,
2558
1.36M
                                 bool isTypeVisibility) {
2559
1.36M
  // Visibility attributes don't mean anything on a typedef.
2560
1.36M
  if (isa<TypedefNameDecl>(D)) {
2561
1
    S.Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored) << AL;
2562
1
    return;
2563
1
  }
2564
1.36M
2565
1.36M
  // 'type_visibility' can only go on a type or namespace.
2566
1.36M
  if (isTypeVisibility &&
2567
1.36M
      
!(162k
isa<TagDecl>(D)162k
||
2568
162k
        
isa<ObjCInterfaceDecl>(D)1
||
2569
162k
        
isa<NamespaceDecl>(D)1
)) {
2570
1
    S.Diag(AL.getRange().getBegin(), diag::err_attribute_wrong_decl_type)
2571
1
        << AL << ExpectedTypeOrNamespace;
2572
1
    return;
2573
1
  }
2574
1.36M
2575
1.36M
  // Check that the argument is a string literal.
2576
1.36M
  StringRef TypeStr;
2577
1.36M
  SourceLocation LiteralLoc;
2578
1.36M
  if (!S.checkStringLiteralArgumentAttr(AL, 0, TypeStr, &LiteralLoc))
2579
0
    return;
2580
1.36M
2581
1.36M
  VisibilityAttr::VisibilityType type;
2582
1.36M
  if (!VisibilityAttr::ConvertStrToVisibilityType(TypeStr, type)) {
2583
0
    S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported) << AL
2584
0
                                                                << TypeStr;
2585
0
    return;
2586
0
  }
2587
1.36M
2588
1.36M
  // Complain about attempts to use protected visibility on targets
2589
1.36M
  // (like Darwin) that don't support it.
2590
1.36M
  if (type == VisibilityAttr::Protected &&
2591
1.36M
      
!S.Context.getTargetInfo().hasProtectedVisibility()35
) {
2592
3
    S.Diag(AL.getLoc(), diag::warn_attribute_protected_visibility);
2593
3
    type = VisibilityAttr::Default;
2594
3
  }
2595
1.36M
2596
1.36M
  Attr *newAttr;
2597
1.36M
  if (isTypeVisibility) {
2598
162k
    newAttr = S.mergeTypeVisibilityAttr(
2599
162k
        D, AL, (TypeVisibilityAttr::VisibilityType)type);
2600
1.20M
  } else {
2601
1.20M
    newAttr = S.mergeVisibilityAttr(D, AL, type);
2602
1.20M
  }
2603
1.36M
  if (newAttr)
2604
1.36M
    D->addAttr(newAttr);
2605
1.36M
}
2606
2607
86
static void handleObjCDirectAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2608
86
  // objc_direct cannot be set on methods declared in the context of a protocol
2609
86
  if (isa<ObjCProtocolDecl>(D->getDeclContext())) {
2610
2
    S.Diag(AL.getLoc(), diag::err_objc_direct_on_protocol) << false;
2611
2
    return;
2612
2
  }
2613
84
2614
84
  if (S.getLangOpts().ObjCRuntime.allowsDirectDispatch()) {
2615
84
    handleSimpleAttribute<ObjCDirectAttr>(S, D, AL);
2616
84
  } else {
2617
0
    S.Diag(AL.getLoc(), diag::warn_objc_direct_ignored) << AL;
2618
0
  }
2619
84
}
2620
2621
static void handleObjCDirectMembersAttr(Sema &S, Decl *D,
2622
8
                                        const ParsedAttr &AL) {
2623
8
  if (S.getLangOpts().ObjCRuntime.allowsDirectDispatch()) {
2624
8
    handleSimpleAttribute<ObjCDirectMembersAttr>(S, D, AL);
2625
8
  } else {
2626
0
    S.Diag(AL.getLoc(), diag::warn_objc_direct_ignored) << AL;
2627
0
  }
2628
8
}
2629
2630
18
static void handleObjCMethodFamilyAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2631
18
  const auto *M = cast<ObjCMethodDecl>(D);
2632
18
  if (!AL.isArgIdent(0)) {
2633
2
    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
2634
2
        << AL << 1 << AANT_ArgumentIdentifier;
2635
2
    return;
2636
2
  }
2637
16
2638
16
  IdentifierLoc *IL = AL.getArgAsIdent(0);
2639
16
  ObjCMethodFamilyAttr::FamilyKind F;
2640
16
  if (!ObjCMethodFamilyAttr::ConvertStrToFamilyKind(IL->Ident->getName(), F)) {
2641
0
    S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL << IL->Ident;
2642
0
    return;
2643
0
  }
2644
16
2645
16
  if (F == ObjCMethodFamilyAttr::OMF_init &&
2646
16
      
!M->getReturnType()->isObjCObjectPointerType()14
) {
2647
0
    S.Diag(M->getLocation(), diag::err_init_method_bad_return_type)
2648
0
        << M->getReturnType();
2649
0
    // Ignore the attribute.
2650
0
    return;
2651
0
  }
2652
16
2653
16
  D->addAttr(new (S.Context) ObjCMethodFamilyAttr(S.Context, AL, F));
2654
16
}
2655
2656
15
static void handleObjCNSObject(Sema &S, Decl *D, const ParsedAttr &AL) {
2657
15
  if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) {
2658
9
    QualType T = TD->getUnderlyingType();
2659
9
    if (!T->isCARCBridgableType()) {
2660
1
      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
2661
1
      return;
2662
1
    }
2663
6
  }
2664
6
  else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) {
2665
4
    QualType T = PD->getType();
2666
4
    if (!T->isCARCBridgableType()) {
2667
1
      S.Diag(PD->getLocation(), diag::err_nsobject_attribute);
2668
1
      return;
2669
1
    }
2670
2
  }
2671
2
  else {
2672
2
    // It is okay to include this attribute on properties, e.g.:
2673
2
    //
2674
2
    //  @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
2675
2
    //
2676
2
    // In this case it follows tradition and suppresses an error in the above
2677
2
    // case.
2678
2
    S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
2679
2
  }
2680
15
  D->addAttr(::new (S.Context) ObjCNSObjectAttr(S.Context, AL));
2681
13
}
2682
2683
5.20k
static void handleObjCIndependentClass(Sema &S, Decl *D, const ParsedAttr &AL) {
2684
5.20k
  if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) {
2685
5.20k
    QualType T = TD->getUnderlyingType();
2686
5.20k
    if (!T->isObjCObjectPointerType()) {
2687
1
      S.Diag(TD->getLocation(), diag::warn_ptr_independentclass_attribute);
2688
1
      return;
2689
1
    }
2690
4
  } else {
2691
4
    S.Diag(D->getLocation(), diag::warn_independentclass_attribute);
2692
4
    return;
2693
4
  }
2694
5.20k
  D->addAttr(::new (S.Context) ObjCIndependentClassAttr(S.Context, AL));
2695
5.20k
}
2696
2697
432
static void handleBlocksAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2698
432
  if (!AL.isArgIdent(0)) {
2699
0
    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
2700
0
        << AL << 1 << AANT_ArgumentIdentifier;
2701
0
    return;
2702
0
  }
2703
432
2704
432
  IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
2705
432
  BlocksAttr::BlockType type;
2706
432
  if (!BlocksAttr::ConvertStrToBlockType(II->getName(), type)) {
2707
0
    S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
2708
0
    return;
2709
0
  }
2710
432
2711
432
  D->addAttr(::new (S.Context) BlocksAttr(S.Context, AL, type));
2712
432
}
2713
2714
2.53k
static void handleSentinelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2715
2.53k
  unsigned sentinel = (unsigned)SentinelAttr::DefaultSentinel;
2716
2.53k
  if (AL.getNumArgs() > 0) {
2717
2.49k
    Expr *E = AL.getArgAsExpr(0);
2718
2.49k
    llvm::APSInt Idx(32);
2719
2.49k
    if (E->isTypeDependent() || E->isValueDependent() ||
2720
2.49k
        !E->isIntegerConstantExpr(Idx, S.Context)) {
2721
4
      S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
2722
4
          << AL << 1 << AANT_ArgumentIntegerConstant << E->getSourceRange();
2723
4
      return;
2724
4
    }
2725
2.49k
2726
2.49k
    if (Idx.isSigned() && Idx.isNegative()) {
2727
4
      S.Diag(AL.getLoc(), diag::err_attribute_sentinel_less_than_zero)
2728
4
        << E->getSourceRange();
2729
4
      return;
2730
4
    }
2731
2.48k
2732
2.48k
    sentinel = Idx.getZExtValue();
2733
2.48k
  }
2734
2.53k
2735
2.53k
  unsigned nullPos = (unsigned)SentinelAttr::DefaultNullPos;
2736
2.52k
  if (AL.getNumArgs() > 1) {
2737
2.44k
    Expr *E = AL.getArgAsExpr(1);
2738
2.44k
    llvm::APSInt Idx(32);
2739
2.44k
    if (E->isTypeDependent() || E->isValueDependent() ||
2740
2.44k
        !E->isIntegerConstantExpr(Idx, S.Context)) {
2741
0
      S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
2742
0
          << AL << 2 << AANT_ArgumentIntegerConstant << E->getSourceRange();
2743
0
      return;
2744
0
    }
2745
2.44k
    nullPos = Idx.getZExtValue();
2746
2.44k
2747
2.44k
    if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) {
2748
3
      // FIXME: This error message could be improved, it would be nice
2749
3
      // to say what the bounds actually are.
2750
3
      S.Diag(AL.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
2751
3
        << E->getSourceRange();
2752
3
      return;
2753
3
    }
2754
2.52k
  }
2755
2.52k
2756
2.52k
  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
2757
61
    const FunctionType *FT = FD->getType()->castAs<FunctionType>();
2758
61
    if (isa<FunctionNoProtoType>(FT)) {
2759
2
      S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_named_arguments);
2760
2
      return;
2761
2
    }
2762
59
2763
59
    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
2764
4
      S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
2765
4
      return;
2766
4
    }
2767
2.45k
  } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
2768
2.44k
    if (!MD->isVariadic()) {
2769
1
      S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
2770
1
      return;
2771
1
    }
2772
16
  } else if (const auto *BD = dyn_cast<BlockDecl>(D)) {
2773
4
    if (!BD->isVariadic()) {
2774
1
      S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
2775
1
      return;
2776
1
    }
2777
12
  } else if (const auto *V = dyn_cast<VarDecl>(D)) {
2778
12
    QualType Ty = V->getType();
2779
12
    if (Ty->isBlockPointerType() || 
Ty->isFunctionPointerType()7
) {
2780
9
      const FunctionType *FT = Ty->isFunctionPointerType()
2781
9
       ? 
D->getFunctionType()4
2782
9
       : 
Ty->castAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>()5
;
2783
9
      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
2784
1
        int m = Ty->isFunctionPointerType() ? 
00
: 1;
2785
1
        S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
2786
1
        return;
2787
1
      }
2788
3
    } else {
2789
3
      S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
2790
3
          << AL << ExpectedFunctionMethodOrBlock;
2791
3
      return;
2792
3
    }
2793
0
  } else {
2794
0
    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
2795
0
        << AL << ExpectedFunctionMethodOrBlock;
2796
0
    return;
2797
0
  }
2798
2.50k
  D->addAttr(::new (S.Context) SentinelAttr(S.Context, AL, sentinel, nullPos));
2799
2.50k
}
2800
2801
16.1k
static void handleWarnUnusedResult(Sema &S, Decl *D, const ParsedAttr &AL) {
2802
16.1k
  if (D->getFunctionType() &&
2803
16.1k
      
D->getFunctionType()->getReturnType()->isVoidType()16.1k
&&
2804
16.1k
      
!isa<CXXConstructorDecl>(D)10
) {
2805
1
    S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) << AL << 0;
2806
1
    return;
2807
1
  }
2808
16.1k
  if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
2809
4
    if (MD->getReturnType()->isVoidType()) {
2810
1
      S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) << AL << 1;
2811
1
      return;
2812
1
    }
2813
16.1k
2814
16.1k
  StringRef Str;
2815
16.1k
  if ((AL.isCXX11Attribute() || 
AL.isC2xAttribute()16.1k
) &&
!AL.getScopeName()94
) {
2816
82
    // If this is spelled as the standard C++17 attribute, but not in C++17,
2817
82
    // warn about using it as an extension. If there are attribute arguments,
2818
82
    // then claim it's a C++2a extension instead.
2819
82
    // FIXME: If WG14 does not seem likely to adopt the same feature, add an
2820
82
    // extension warning for C2x mode.
2821
82
    const LangOptions &LO = S.getLangOpts();
2822
82
    if (AL.getNumArgs() == 1) {
2823
29
      if (LO.CPlusPlus && 
!LO.CPlusPlus2a28
)
2824
18
        S.Diag(AL.getLoc(), diag::ext_cxx2a_attr) << AL;
2825
29
2826
29
      // Since this this is spelled [[nodiscard]], get the optional string
2827
29
      // literal. If in C++ mode, but not in C++2a mode, diagnose as an
2828
29
      // extension.
2829
29
      // FIXME: C2x should support this feature as well, even as an extension.
2830
29
      if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, nullptr))
2831
0
        return;
2832
53
    } else if (LO.CPlusPlus && 
!LO.CPlusPlus1742
)
2833
9
      S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
2834
82
  }
2835
16.1k
2836
16.1k
  D->addAttr(::new (S.Context) WarnUnusedResultAttr(S.Context, AL, Str));
2837
16.1k
}
2838
2839
113
static void handleWeakImportAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2840
113
  // weak_import only applies to variable & function declarations.
2841
113
  bool isDef = false;
2842
113
  if (!D->canBeWeakImported(isDef)) {
2843
9
    if (isDef)
2844
3
      S.Diag(AL.getLoc(), diag::warn_attribute_invalid_on_definition)
2845
3
        << "weak_import";
2846
6
    else if (isa<ObjCPropertyDecl>(D) || 
isa<ObjCMethodDecl>(D)5
||
2847
6
             
(3
S.Context.getTargetInfo().getTriple().isOSDarwin()3
&&
2848
5
              
(3
isa<ObjCInterfaceDecl>(D)3
||
isa<EnumDecl>(D)3
))) {
2849
5
      // Nothing to warn about here.
2850
5
    } else
2851
1
      S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
2852
1
          << AL << ExpectedVariableOrFunction;
2853
9
2854
9
    return;
2855
9
  }
2856
104
2857
104
  D->addAttr(::new (S.Context) WeakImportAttr(S.Context, AL));
2858
104
}
2859
2860
// Handles reqd_work_group_size and work_group_size_hint.
2861
template <typename WorkGroupAttr>
2862
20
static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
2863
20
  uint32_t WGSize[3];
2864
71
  for (unsigned i = 0; i < 3; 
++i51
) {
2865
56
    const Expr *E = AL.getArgAsExpr(i);
2866
56
    if (!checkUInt32Argument(S, AL, E, WGSize[i], i,
2867
56
                             /*StrictlyUnsigned=*/true))
2868
2
      return;
2869
54
    if (WGSize[i] == 0) {
2870
3
      S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
2871
3
          << AL << E->getSourceRange();
2872
3
      return;
2873
3
    }
2874
54
  }
2875
20
2876
20
  WorkGroupAttr *Existing = D->getAttr<WorkGroupAttr>();
2877
15
  if (Existing && 
!(1
Existing->getXDim() == WGSize[0]1
&&
2878
1
                    
Existing->getYDim() == WGSize[1]0
&&
2879
1
                    
Existing->getZDim() == WGSize[2]0
))
2880
1
    S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
2881
15
2882
15
  D->addAttr(::new (S.Context)
2883
15
                 WorkGroupAttr(S.Context, AL, WGSize[0], WGSize[1], WGSize[2]));
2884
15
}
SemaDeclAttr.cpp:void handleWorkGroupSize<clang::WorkGroupSizeHintAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
2862
6
static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
2863
6
  uint32_t WGSize[3];
2864
22
  for (unsigned i = 0; i < 3; 
++i16
) {
2865
17
    const Expr *E = AL.getArgAsExpr(i);
2866
17
    if (!checkUInt32Argument(S, AL, E, WGSize[i], i,
2867
17
                             /*StrictlyUnsigned=*/true))
2868
1
      return;
2869
16
    if (WGSize[i] == 0) {
2870
0
      S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
2871
0
          << AL << E->getSourceRange();
2872
0
      return;
2873
0
    }
2874
16
  }
2875
6
2876
6
  WorkGroupAttr *Existing = D->getAttr<WorkGroupAttr>();
2877
5
  if (Existing && 
!(1
Existing->getXDim() == WGSize[0]1
&&
2878
1
                    
Existing->getYDim() == WGSize[1]0
&&
2879
1
                    
Existing->getZDim() == WGSize[2]0
))
2880
1
    S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
2881
5
2882
5
  D->addAttr(::new (S.Context)
2883
5
                 WorkGroupAttr(S.Context, AL, WGSize[0], WGSize[1], WGSize[2]));
2884
5
}
SemaDeclAttr.cpp:void handleWorkGroupSize<clang::ReqdWorkGroupSizeAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
2862
14
static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
2863
14
  uint32_t WGSize[3];
2864
49
  for (unsigned i = 0; i < 3; 
++i35
) {
2865
39
    const Expr *E = AL.getArgAsExpr(i);
2866
39
    if (!checkUInt32Argument(S, AL, E, WGSize[i], i,
2867
39
                             /*StrictlyUnsigned=*/true))
2868
1
      return;
2869
38
    if (WGSize[i] == 0) {
2870
3
      S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
2871
3
          << AL << E->getSourceRange();
2872
3
      return;
2873
3
    }
2874
38
  }
2875
14
2876
14
  WorkGroupAttr *Existing = D->getAttr<WorkGroupAttr>();
2877
10
  if (Existing && 
!(0
Existing->getXDim() == WGSize[0]0
&&
2878
0
                    Existing->getYDim() == WGSize[1] &&
2879
0
                    Existing->getZDim() == WGSize[2]))
2880
0
    S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
2881
10
2882
10
  D->addAttr(::new (S.Context)
2883
10
                 WorkGroupAttr(S.Context, AL, WGSize[0], WGSize[1], WGSize[2]));
2884
10
}
2885
2886
// Handles intel_reqd_sub_group_size.
2887
6
static void handleSubGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
2888
6
  uint32_t SGSize;
2889
6
  const Expr *E = AL.getArgAsExpr(0);
2890
6
  if (!checkUInt32Argument(S, AL, E, SGSize))
2891
0
    return;
2892
6
  if (SGSize == 0) {
2893
1
    S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
2894
1
        << AL << E->getSourceRange();
2895
1
    return;
2896
1
  }
2897
5
2898
5
  OpenCLIntelReqdSubGroupSizeAttr *Existing =
2899
5
      D->getAttr<OpenCLIntelReqdSubGroupSizeAttr>();
2900
5
  if (Existing && 
Existing->getSubGroupSize() != SGSize1
)
2901
1
    S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
2902
5
2903
5
  D->addAttr(::new (S.Context)
2904
5
                 OpenCLIntelReqdSubGroupSizeAttr(S.Context, AL, SGSize));
2905
5
}
2906
2907
8
static void handleVecTypeHint(Sema &S, Decl *D, const ParsedAttr &AL) {
2908
8
  if (!AL.hasParsedType()) {
2909
0
    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
2910
0
    return;
2911
0
  }
2912
8
2913
8
  TypeSourceInfo *ParmTSI = nullptr;
2914
8
  QualType ParmType = S.GetTypeFromParser(AL.getTypeArg(), &ParmTSI);
2915
8
  assert(ParmTSI && "no type source info for attribute argument");
2916
8
2917
8
  if (!ParmType->isExtVectorType() && 
!ParmType->isFloatingType()7
&&
2918
8
      
(6
ParmType->isBooleanType()6
||
2919
6
       
!ParmType->isIntegralType(S.getASTContext())5
)) {
2920
2
    S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument) << 2 << AL;
2921
2
    return;
2922
2
  }
2923
6
2924
6
  if (VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>()) {
2925
1
    if (!S.Context.hasSameType(A->getTypeHint(), ParmType)) {
2926
1
      S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
2927
1
      return;
2928
1
    }
2929
5
  }
2930
5
2931
5
  D->addAttr(::new (S.Context) VecTypeHintAttr(S.Context, AL, ParmTSI));
2932
5
}
2933
2934
SectionAttr *Sema::mergeSectionAttr(Decl *D, const AttributeCommonInfo &CI,
2935
1.22k
                                    StringRef Name) {
2936
1.22k
  // Explicit or partial specializations do not inherit
2937
1.22k
  // the section attribute from the primary template.
2938
1.22k
  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
2939
42
    if (CI.getAttributeSpellingListIndex() == SectionAttr::Declspec_allocate &&
2940
42
        
FD->isFunctionTemplateSpecialization()3
)
2941
3
      return nullptr;
2942
1.21k
  }
2943
1.21k
  if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
2944
4
    if (ExistingAttr->getName() == Name)
2945
0
      return nullptr;
2946
4
    Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section)
2947
4
         << 1 /*section*/;
2948
4
    Diag(CI.getLoc(), diag::note_previous_attribute);
2949
4
    return nullptr;
2950
4
  }
2951
1.21k
  return ::new (Context) SectionAttr(Context, CI, Name);
2952
1.21k
}
2953
2954
1.25k
bool Sema::checkSectionName(SourceLocation LiteralLoc, StringRef SecName) {
2955
1.25k
  std::string Error = Context.getTargetInfo().isValidSectionSpecifier(SecName);
2956
1.25k
  if (!Error.empty()) {
2957
2
    Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target) << Error
2958
2
         << 1 /*'section'*/;
2959
2
    return false;
2960
2
  }
2961
1.24k
  return true;
2962
1.24k
}
2963
2964
1.20k
static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2965
1.20k
  // Make sure that there is a string literal as the sections's single
2966
1.20k
  // argument.
2967
1.20k
  StringRef Str;
2968
1.20k
  SourceLocation LiteralLoc;
2969
1.20k
  if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))
2970
2
    return;
2971
1.20k
2972
1.20k
  if (!S.checkSectionName(LiteralLoc, Str))
2973
1
    return;
2974
1.20k
2975
1.20k
  // If the target wants to validate the section specifier, make it happen.
2976
1.20k
  std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(Str);
2977
1.20k
  if (!Error.empty()) {
2978
0
    S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
2979
0
    << Error;
2980
0
    return;
2981
0
  }
2982
1.20k
2983
1.20k
  SectionAttr *NewAttr = S.mergeSectionAttr(D, AL, Str);
2984
1.20k
  if (NewAttr)
2985
1.20k
    D->addAttr(NewAttr);
2986
1.20k
}
2987
2988
// This is used for `__declspec(code_seg("segname"))` on a decl.
2989
// `#pragma code_seg("segname")` uses checkSectionName() instead.
2990
static bool checkCodeSegName(Sema &S, SourceLocation LiteralLoc,
2991
82
                             StringRef CodeSegName) {
2992
82
  std::string Error =
2993
82
      S.Context.getTargetInfo().isValidSectionSpecifier(CodeSegName);
2994
82
  if (!Error.empty()) {
2995
0
    S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
2996
0
        << Error << 0 /*'code-seg'*/;
2997
0
    return false;
2998
0
  }
2999
82
3000
82
  return true;
3001
82
}
3002
3003
CodeSegAttr *Sema::mergeCodeSegAttr(Decl *D, const AttributeCommonInfo &CI,
3004
93
                                    StringRef Name) {
3005
93
  // Explicit or partial specializations do not inherit
3006
93
  // the code_seg attribute from the primary template.
3007
93
  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3008
46
    if (FD->isFunctionTemplateSpecialization())
3009
3
      return nullptr;
3010
90
  }
3011
90
  if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) {
3012
14
    if (ExistingAttr->getName() == Name)
3013
12
      return nullptr;
3014
2
    Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section)
3015
2
         << 0 /*codeseg*/;
3016
2
    Diag(CI.getLoc(), diag::note_previous_attribute);
3017
2
    return nullptr;
3018
2
  }
3019
76
  return ::new (Context) CodeSegAttr(Context, CI, Name);
3020
76
}
3021
3022
82
static void handleCodeSegAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3023
82
  StringRef Str;
3024
82
  SourceLocation LiteralLoc;
3025
82
  if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))
3026
0
    return;
3027
82
  if (!checkCodeSegName(S, LiteralLoc, Str))
3028
0
    return;
3029
82
  if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) {
3030
14
    if (!ExistingAttr->isImplicit()) {
3031
6
      S.Diag(AL.getLoc(),
3032
6
             ExistingAttr->getName() == Str
3033
6
             ? 
diag::warn_duplicate_codeseg_attribute3
3034
6
             : 
diag::err_conflicting_codeseg_attribute3
);
3035
6
      return;
3036
6
    }
3037
8
    D->dropAttr<CodeSegAttr>();
3038
8
  }
3039
82
  
if (CodeSegAttr *76
CSA76
= S.mergeCodeSegAttr(D, AL, Str))
3040
76
    D->addAttr(CSA);
3041
76
}
3042
3043
// Check for things we'd like to warn about. Multiversioning issues are
3044
// handled later in the process, once we know how many exist.
3045
957k
bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) {
3046
957k
  enum FirstParam { Unsupported, Duplicate };
3047
957k
  enum SecondParam { None, Architecture };
3048
957k
  for (auto Str : {"tune=", "fpmath="})
3049
1.91M
    if (AttrStr.find(Str) != StringRef::npos)
3050
4
      return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3051
4
             << Unsupported << None << Str;
3052
957k
3053
957k
  ParsedTargetAttr ParsedAttrs = TargetAttr::parse(AttrStr);
3054
957k
3055
957k
  if (!ParsedAttrs.Architecture.empty() &&
3056
957k
      
!Context.getTargetInfo().isValidCPUName(ParsedAttrs.Architecture)135
)
3057
3
    return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3058
3
           << Unsupported << Architecture << ParsedAttrs.Architecture;
3059
957k
3060
957k
  if (ParsedAttrs.DuplicateArchitecture)
3061
1
    return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3062
1
           << Duplicate << None << "arch=";
3063
957k
3064
1.11M
  
for (const auto &Feature : ParsedAttrs.Features)957k
{
3065
1.11M
    auto CurFeature = StringRef(Feature).drop_front(); // remove + or -.
3066
1.11M
    if (!Context.getTargetInfo().isValidFeatureName(CurFeature))
3067
4
      return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3068
4
             << Unsupported << None << CurFeature;
3069
1.11M
  }
3070
957k
3071
957k
  TargetInfo::BranchProtectionInfo BPI;
3072
957k
  StringRef Error;
3073
957k
  if (!ParsedAttrs.BranchProtection.empty() &&
3074
957k
      !Context.getTargetInfo().validateBranchProtection(
3075
30
          ParsedAttrs.BranchProtection, BPI, Error)) {
3076
8
    if (Error.empty())
3077
1
      return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3078
1
             << Unsupported << None << "branch-protection";
3079
7
    else
3080
7
      return Diag(LiteralLoc, diag::err_invalid_branch_protection_spec)
3081
7
             << Error;
3082
957k
  }
3083
957k
3084
957k
  return false;
3085
957k
}
3086
3087
957k
static void handleTargetAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3088
957k
  StringRef Str;
3089
957k
  SourceLocation LiteralLoc;
3090
957k
  if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc) ||
3091
957k
      S.checkTargetAttr(LiteralLoc, Str))
3092
20
    return;
3093
957k
3094
957k
  TargetAttr *NewAttr = ::new (S.Context) TargetAttr(S.Context, AL, Str);
3095
957k
  D->addAttr(NewAttr);
3096
957k
}
3097
3098
914k
static void handleMinVectorWidthAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3099
914k
  Expr *E = AL.getArgAsExpr(0);
3100
914k
  uint32_t VecWidth;
3101
914k
  if (!checkUInt32Argument(S, AL, E, VecWidth)) {
3102
1
    AL.setInvalid();
3103
1
    return;
3104
1
  }
3105
914k
3106
914k
  MinVectorWidthAttr *Existing = D->getAttr<MinVectorWidthAttr>();
3107
914k
  if (Existing && 
Existing->getVectorWidth() != VecWidth1
) {
3108
1
    S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3109
1
    return;
3110
1
  }
3111
914k
3112
914k
  D->addAttr(::new (S.Context) MinVectorWidthAttr(S.Context, AL, VecWidth));
3113
914k
}
3114
3115
37
static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3116
37
  Expr *E = AL.getArgAsExpr(0);
3117
37
  SourceLocation Loc = E->getExprLoc();
3118
37
  FunctionDecl *FD = nullptr;
3119
37
  DeclarationNameInfo NI;
3120
37
3121
37
  // gcc only allows for simple identifiers. Since we support more than gcc, we
3122
37
  // will warn the user.
3123
37
  if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
3124
34
    if (DRE->hasQualifier())
3125
4
      S.Diag(Loc, diag::warn_cleanup_ext);
3126
34
    FD = dyn_cast<FunctionDecl>(DRE->getDecl());
3127
34
    NI = DRE->getNameInfo();
3128
34
    if (!FD) {
3129
1
      S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 1
3130
1
        << NI.getName();
3131
1
      return;
3132
1
    }
3133
3
  } else if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
3134
2
    if (ULE->hasExplicitTemplateArgs())
3135
1
      S.Diag(Loc, diag::warn_cleanup_ext);
3136
2
    FD = S.ResolveSingleFunctionTemplateSpecialization(ULE, true);
3137
2
    NI = ULE->getNameInfo();
3138
2
    if (!FD) {
3139
1
      S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 2
3140
1
        << NI.getName();
3141
1
      if (ULE->getType() == S.Context.OverloadTy)
3142
1
        S.NoteAllOverloadCandidates(ULE);
3143
1
      return;
3144
1
    }
3145
1
  } else {
3146
1
    S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 0;
3147
1
    return;
3148
1
  }
3149
34
3150
34
  if (FD->getNumParams() != 1) {
3151
1
    S.Diag(Loc, diag::err_attribute_cleanup_func_must_take_one_arg)
3152
1
      << NI.getName();
3153
1
    return;
3154
1
  }
3155
33
3156
33
  // We're currently more strict than GCC about what function types we accept.
3157
33
  // If this ever proves to be a problem it should be easy to fix.
3158
33
  QualType Ty = S.Context.getPointerType(cast<VarDecl>(D)->getType());
3159
33
  QualType ParamTy = FD->getParamDecl(0)->getType();
3160
33
  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
3161
33
                                   ParamTy, Ty) != Sema::Compatible) {
3162
1
    S.Diag(Loc, diag::err_attribute_cleanup_func_arg_incompatible_type)
3163
1
      << NI.getName() << ParamTy << Ty;
3164
1
    return;
3165
1
  }
3166
32
3167
32
  D->addAttr(::new (S.Context) CleanupAttr(S.Context, AL, FD));
3168
32
}
3169
3170
static void handleEnumExtensibilityAttr(Sema &S, Decl *D,
3171
124k
                                        const ParsedAttr &AL) {
3172
124k
  if (!AL.isArgIdent(0)) {
3173
0
    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3174
0
        << AL << 0 << AANT_ArgumentIdentifier;
3175
0
    return;
3176
0
  }
3177
124k
3178
124k
  EnumExtensibilityAttr::Kind ExtensibilityKind;
3179
124k
  IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
3180
124k
  if (!EnumExtensibilityAttr::ConvertStrToKind(II->getName(),
3181
124k
                                               ExtensibilityKind)) {
3182
1
    S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
3183
1
    return;
3184
1
  }
3185
124k
3186
124k
  D->addAttr(::new (S.Context)
3187
124k
                 EnumExtensibilityAttr(S.Context, AL, ExtensibilityKind));
3188
124k
}
3189
3190
/// Handle __attribute__((format_arg((idx)))) attribute based on
3191
/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
3192
1.00k
static void handleFormatArgAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3193
1.00k
  Expr *IdxExpr = AL.getArgAsExpr(0);
3194
1.00k
  ParamIdx Idx;
3195
1.00k
  if (!checkFunctionOrMethodParameterIndex(S, D, AL, 1, IdxExpr, Idx))
3196
2
    return;
3197
999
3198
999
  // Make sure the format string is really a string.
3199
999
  QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex());
3200
999
3201
999
  bool NotNSStringTy = !isNSStringType(Ty, S.Context);
3202
999
  if (NotNSStringTy &&
3203
999
      
!isCFStringType(Ty, S.Context)701
&&
3204
999
      
(409
!Ty->isPointerType()409
||
3205
409
       
!Ty->castAs<PointerType>()->getPointeeType()->isCharType()407
)) {
3206
2
    S.Diag(AL.getLoc(), diag::err_format_attribute_not)
3207
2
        << "a string type" << IdxExpr->getSourceRange()
3208
2
        << getFunctionOrMethodParamRange(D, 0);
3209
2
    return;
3210
2
  }
3211
997
  Ty = getFunctionOrMethodResultType(D);
3212
997
  if (!isNSStringType(Ty, S.Context) &&
3213
997
      
!isCFStringType(Ty, S.Context)700
&&
3214
997
      
(116
!Ty->isPointerType()116
||
3215
116
       
!Ty->castAs<PointerType>()->getPointeeType()->isCharType()115
)) {
3216
1
    S.Diag(AL.getLoc(), diag::err_format_attribute_result_not)
3217
1
        << (NotNSStringTy ? 
"string type"0
: "NSString")
3218
1
        << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0);
3219
1
    return;
3220
1
  }
3221
996
3222
996
  D->addAttr(::new (S.Context) FormatArgAttr(S.Context, AL, Idx));
3223
996
}
3224
3225
enum FormatAttrKind {
3226
  CFStringFormat,
3227
  NSStringFormat,
3228
  StrftimeFormat,
3229
  SupportedFormat,
3230
  IgnoredFormat,
3231
  InvalidFormat
3232
};
3233
3234
/// getFormatAttrKind - Map from format attribute names to supported format
3235
/// types.
3236
35.6k
static FormatAttrKind getFormatAttrKind(StringRef Format) {
3237
35.6k
  return llvm::StringSwitch<FormatAttrKind>(Format)
3238
35.6k
      // Check for formats that get handled specially.
3239
35.6k
      .Case("NSString", NSStringFormat)
3240
35.6k
      .Case("CFString", CFStringFormat)
3241
35.6k
      .Case("strftime", StrftimeFormat)
3242
35.6k
3243
35.6k
      // Otherwise, check for supported formats.
3244
35.6k
      .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat)
3245
35.6k
      .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat)
3246
35.6k
      .Case("kprintf", SupportedFormat)         // OpenBSD.
3247
35.6k
      .Case("freebsd_kprintf", SupportedFormat) // FreeBSD.
3248
35.6k
      .Case("os_trace", SupportedFormat)
3249
35.6k
      .Case("os_log", SupportedFormat)
3250
35.6k
3251
35.6k
      .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat)
3252
35.6k
      .Default(InvalidFormat);
3253
35.6k
}
3254
3255
/// Handle __attribute__((init_priority(priority))) attributes based on
3256
/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
3257
602
static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3258
602
  if (!S.getLangOpts().CPlusPlus) {
3259
0
    S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
3260
0
    return;
3261
0
  }
3262
602
3263
602
  if (S.getCurFunctionOrMethodDecl()) {
3264
1
    S.Diag(AL.getLoc(), diag::err_init_priority_object_attr);
3265
1
    AL.setInvalid();
3266
1
    return;
3267
1
  }
3268
601
  QualType T = cast<VarDecl>(D)->getType();
3269
601
  if (S.Context.getAsArrayType(T))
3270
2
    T = S.Context.getBaseElementType(T);
3271
601
  if (!T->getAs<RecordType>()) {
3272
1
    S.Diag(AL.getLoc(), diag::err_init_priority_object_attr);
3273
1
    AL.setInvalid();
3274
1
    return;
3275
1
  }
3276
600
3277
600
  Expr *E = AL.getArgAsExpr(0);
3278
600
  uint32_t prioritynum;
3279
600
  if (!checkUInt32Argument(S, AL, E, prioritynum)) {
3280
1
    AL.setInvalid();
3281
1
    return;
3282
1
  }
3283
599
3284
599
  if (prioritynum < 101 || 
prioritynum > 65535598
) {
3285
1
    S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_range)
3286
1
        << E->getSourceRange() << AL << 101 << 65535;
3287
1
    AL.setInvalid();
3288
1
    return;
3289
1
  }
3290
598
  D->addAttr(::new (S.Context) InitPriorityAttr(S.Context, AL, prioritynum));
3291
598
}
3292
3293
FormatAttr *Sema::mergeFormatAttr(Decl *D, const AttributeCommonInfo &CI,
3294
                                  IdentifierInfo *Format, int FormatIdx,
3295
36.5k
                                  int FirstArg) {
3296
36.5k
  // Check whether we already have an equivalent format attribute.
3297
36.5k
  for (auto *F : D->specific_attrs<FormatAttr>()) {
3298
422
    if (F->getType() == Format &&
3299
422
        
F->getFormatIdx() == FormatIdx414
&&
3300
422
        
F->getFirstArg() == FirstArg414
) {
3301
414
      // If we don't have a valid location for this attribute, adopt the
3302
414
      // location.
3303
414
      if (F->getLocation().isInvalid())
3304
0
        F->setRange(CI.getRange());
3305
414
      return nullptr;
3306
414
    }
3307
422
  }
3308
36.5k
3309
36.5k
  
return ::new (Context) FormatAttr(Context, CI, Format, FormatIdx, FirstArg)36.1k
;
3310
36.5k
}
3311
3312
/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
3313
/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
3314
35.6k
static void handleFormatAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3315
35.6k
  if (!AL.isArgIdent(0)) {
3316
0
    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3317
0
        << AL << 1 << AANT_ArgumentIdentifier;
3318
0
    return;
3319
0
  }
3320
35.6k
3321
35.6k
  // In C++ the implicit 'this' function parameter also counts, and they are
3322
35.6k
  // counted from one.
3323
35.6k
  bool HasImplicitThisParam = isInstanceMethod(D);
3324
35.6k
  unsigned NumArgs = getFunctionOrMethodNumParams(D) + HasImplicitThisParam;
3325
35.6k
3326
35.6k
  IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
3327
35.6k
  StringRef Format = II->getName();
3328
35.6k
3329
35.6k
  if (normalizeName(Format)) {
3330
33.6k
    // If we've modified the string name, we need a new identifier for it.
3331
33.6k
    II = &S.Context.Idents.get(Format);
3332
33.6k
  }
3333
35.6k
3334
35.6k
  // Check for supported formats.
3335
35.6k
  FormatAttrKind Kind = getFormatAttrKind(Format);
3336
35.6k
3337
35.6k
  if (Kind == IgnoredFormat)
3338
4
    return;
3339
35.6k
3340
35.6k
  if (Kind == InvalidFormat) {
3341
0
    S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
3342
0
        << AL << II->getName();
3343
0
    return;
3344
0
  }
3345
35.6k
3346
35.6k
  // checks for the 2nd argument
3347
35.6k
  Expr *IdxExpr = AL.getArgAsExpr(1);
3348
35.6k
  uint32_t Idx;
3349
35.6k
  if (!checkUInt32Argument(S, AL, IdxExpr, Idx, 2))
3350
0
    return;
3351
35.6k
3352
35.6k
  if (Idx < 1 || 
Idx > NumArgs35.6k
) {
3353
3
    S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
3354
3
        << AL << 2 << IdxExpr->getSourceRange();
3355
3
    return;
3356
3
  }
3357
35.6k
3358
35.6k
  // FIXME: Do we need to bounds check?
3359
35.6k
  unsigned ArgIdx = Idx - 1;
3360
35.6k
3361
35.6k
  if (HasImplicitThisParam) {
3362
67
    if (ArgIdx == 0) {
3363
4
      S.Diag(AL.getLoc(),
3364
4
             diag::err_format_attribute_implicit_this_format_string)
3365
4
        << IdxExpr->getSourceRange();
3366
4
      return;
3367
4
    }
3368
63
    ArgIdx--;
3369
63
  }
3370
35.6k
3371
35.6k
  // make sure the format string is really a string
3372
35.6k
  QualType Ty = getFunctionOrMethodParamType(D, ArgIdx);
3373
35.6k
3374
35.6k
  if (Kind == CFStringFormat) {
3375
1.17k
    if (!isCFStringType(Ty, S.Context)) {
3376
1
      S.Diag(AL.getLoc(), diag::err_format_attribute_not)
3377
1
        << "a CFString" << IdxExpr->getSourceRange()
3378
1
        << getFunctionOrMethodParamRange(D, ArgIdx);
3379
1
      return;
3380
1
    }
3381
34.5k
  } else if (Kind == NSStringFormat) {
3382
4.15k
    // FIXME: do we need to check if the type is NSString*?  What are the
3383
4.15k
    // semantics?
3384
4.15k
    if (!isNSStringType(Ty, S.Context)) {
3385
1
      S.Diag(AL.getLoc(), diag::err_format_attribute_not)
3386
1
        << "an NSString" << IdxExpr->getSourceRange()
3387
1
        << getFunctionOrMethodParamRange(D, ArgIdx);
3388
1
      return;
3389
1
    }
3390
30.3k
  } else if (!Ty->isPointerType() ||
3391
30.3k
             
!Ty->castAs<PointerType>()->getPointeeType()->isCharType()30.3k
) {
3392
8
    S.Diag(AL.getLoc(), diag::err_format_attribute_not)
3393
8
      << "a string type" << IdxExpr->getSourceRange()
3394
8
      << getFunctionOrMethodParamRange(D, ArgIdx);
3395
8
    return;
3396
8
  }
3397
35.6k
3398
35.6k
  // check the 3rd argument
3399
35.6k
  Expr *FirstArgExpr = AL.getArgAsExpr(2);
3400
35.6k
  uint32_t FirstArg;
3401
35.6k
  if (!checkUInt32Argument(S, AL, FirstArgExpr, FirstArg, 3))
3402
0
    return;
3403
35.6k
3404
35.6k
  // check if the function is variadic if the 3rd argument non-zero
3405
35.6k
  if (FirstArg != 0) {
3406
18.0k
    if (isFunctionOrMethodVariadic(D)) {
3407
18.0k
      ++NumArgs; // +1 for ...
3408
18.0k
    } else {
3409
3
      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
3410
3
      return;
3411
3
    }
3412
35.6k
  }
3413
35.6k
3414
35.6k
  // strftime requires FirstArg to be 0 because it doesn't read from any
3415
35.6k
  // variable the input is just the current time + the format string.
3416
35.6k
  if (Kind == StrftimeFormat) {
3417
198
    if (FirstArg != 0) {
3418
1
      S.Diag(AL.getLoc(), diag::err_format_strftime_third_parameter)
3419
1
        << FirstArgExpr->getSourceRange();
3420
1
      return;
3421
1
    }
3422
35.4k
  // if 0 it disables parameter checking (to use with e.g. va_list)
3423
35.4k
  } else if (FirstArg != 0 && 
FirstArg != NumArgs18.0k
) {
3424
4
    S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
3425
4
        << AL << 3 << FirstArgExpr->getSourceRange();
3426
4
    return;
3427
4
  }
3428
35.6k
3429
35.6k
  FormatAttr *NewAttr = S.mergeFormatAttr(D, AL, II, Idx, FirstArg);
3430
35.6k
  if (NewAttr)
3431
35.6k
    D->addAttr(NewAttr);
3432
35.6k
}
3433
3434
/// Handle __attribute__((callback(CalleeIdx, PayloadIdx0, ...))) attributes.
3435
154
static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3436
154
  // The index that identifies the callback callee is mandatory.
3437
154
  if (AL.getNumArgs() == 0) {
3438
2
    S.Diag(AL.getLoc(), diag::err_callback_attribute_no_callee)
3439
2
        << AL.getRange();
3440
2
    return;
3441
2
  }
3442
152
3443
152
  bool HasImplicitThisParam = isInstanceMethod(D);
3444
152
  int32_t NumArgs = getFunctionOrMethodNumParams(D);
3445
152
3446
152
  FunctionDecl *FD = D->getAsFunction();
3447
152
  assert(FD && "Expected a function declaration!");
3448
152
3449
152
  llvm::StringMap<int> NameIdxMapping;
3450
152
  NameIdxMapping["__"] = -1;
3451
152
3452
152
  NameIdxMapping["this"] = 0;
3453
152
3454
152
  int Idx = 1;
3455
152
  for (const ParmVarDecl *PVD : FD->parameters())
3456
288
    NameIdxMapping[PVD->getName()] = Idx++;
3457
152
3458
152
  auto UnknownName = NameIdxMapping.end();
3459
152
3460
152
  SmallVector<int, 8> EncodingIndices;
3461
483
  for (unsigned I = 0, E = AL.getNumArgs(); I < E; 
++I331
) {
3462
351
    SourceRange SR;
3463
351
    int32_t ArgIdx;
3464
351
3465
351
    if (AL.isArgIdent(I)) {
3466
141
      IdentifierLoc *IdLoc = AL.getArgAsIdent(I);
3467
141
      auto It = NameIdxMapping.find(IdLoc->Ident->getName());
3468
141
      if (It == UnknownName) {
3469
4
        S.Diag(AL.getLoc(), diag::err_callback_attribute_argument_unknown)
3470
4
            << IdLoc->Ident << IdLoc->Loc;
3471
4
        return;
3472
4
      }
3473
137
3474
137
      SR = SourceRange(IdLoc->Loc);
3475
137
      ArgIdx = It->second;
3476
210
    } else if (AL.isArgExpr(I)) {
3477
210
      Expr *IdxExpr = AL.getArgAsExpr(I);
3478
210
3479
210
      // If the expression is not parseable as an int32_t we have a problem.
3480
210
      if (!checkUInt32Argument(S, AL, IdxExpr, (uint32_t &)ArgIdx, I + 1,
3481
210
                               false)) {
3482
0
        S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
3483
0
            << AL << (I + 1) << IdxExpr->getSourceRange();
3484
0
        return;
3485
0
      }
3486
210
3487
210
      // Check oob, excluding the special values, 0 and -1.
3488
210
      if (ArgIdx < -1 || 
ArgIdx > NumArgs206
) {
3489
10
        S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
3490
10
            << AL << (I + 1) << IdxExpr->getSourceRange();
3491
10
        return;
3492
10
      }
3493
200
3494
200
      SR = IdxExpr->getSourceRange();
3495
200
    } else {
3496
0
      llvm_unreachable("Unexpected ParsedAttr argument type!");
3497
0
    }
3498
337
3499
337
    if (ArgIdx == 0 && 
!HasImplicitThisParam14
) {
3500
6
      S.Diag(AL.getLoc(), diag::err_callback_implicit_this_not_available)
3501
6
          << (I + 1) << SR;
3502
6
      return;
3503
6
    }
3504
331
3505
331
    // Adjust for the case we do not have an implicit "this" parameter. In this
3506
331
    // case we decrease all positive values by 1 to get LLVM argument indices.
3507
331
    if (!HasImplicitThisParam && 
ArgIdx > 0186
)
3508
146
      ArgIdx -= 1;
3509
331
3510
331
    EncodingIndices.push_back(ArgIdx);
3511
331
  }
3512
152
3513
152
  int CalleeIdx = EncodingIndices.front();
3514
132
  // Check if the callee index is proper, thus not "this" and not "unknown".
3515
132
  // This means the "CalleeIdx" has to be non-negative if "HasImplicitThisParam"
3516
132
  // is false and positive if "HasImplicitThisParam" is true.
3517
132
  if (CalleeIdx < (int)HasImplicitThisParam) {
3518
6
    S.Diag(AL.getLoc(), diag::err_callback_attribute_invalid_callee)
3519
6
        << AL.getRange();
3520
6
    return;
3521
6
  }
3522
126
3523
126
  // Get the callee type, note the index adjustment as the AST doesn't contain
3524
126
  // the this type (which the callee cannot reference anyway!).
3525
126
  const Type *CalleeType =
3526
126
      getFunctionOrMethodParamType(D, CalleeIdx - HasImplicitThisParam)
3527
126
          .getTypePtr();
3528
126
  if (!CalleeType || !CalleeType->isFunctionPointerType()) {
3529
0
    S.Diag(AL.getLoc(), diag::err_callback_callee_no_function_type)
3530
0
        << AL.getRange();
3531
0
    return;
3532
0
  }
3533
126
3534
126
  const Type *CalleeFnType =
3535
126
      CalleeType->getPointeeType()->getUnqualifiedDesugaredType();
3536
126
3537
126
  // TODO: Check the type of the callee arguments.
3538
126
3539
126
  const auto *CalleeFnProtoType = dyn_cast<FunctionProtoType>(CalleeFnType);
3540
126
  if (!CalleeFnProtoType) {
3541
0
    S.Diag(AL.getLoc(), diag::err_callback_callee_no_function_type)
3542
0
        << AL.getRange();
3543
0
    return;
3544
0
  }
3545
126
3546
126
  if (CalleeFnProtoType->getNumParams() > EncodingIndices.size() - 1) {
3547
12
    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
3548
12
        << AL << (unsigned)(EncodingIndices.size() - 1);
3549
12
    return;
3550
12
  }
3551
114
3552
114
  if (CalleeFnProtoType->getNumParams() < EncodingIndices.size() - 1) {
3553
28
    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
3554
28
        << AL << (unsigned)(EncodingIndices.size() - 1);
3555
28
    return;
3556
28
  }
3557
86
3558
86
  if (CalleeFnProtoType->isVariadic()) {
3559
8
    S.Diag(AL.getLoc(), diag::err_callback_callee_is_variadic) << AL.getRange();
3560
8
    return;
3561
8
  }
3562
78
3563
78
  // Do not allow multiple callback attributes.
3564
78
  if (D->hasAttr<CallbackAttr>()) {
3565
8
    S.Diag(AL.getLoc(), diag::err_callback_attribute_multiple) << AL.getRange();
3566
8
    return;
3567
8
  }
3568
70
3569
70
  D->addAttr(::new (S.Context) CallbackAttr(
3570
70
      S.Context, AL, EncodingIndices.data(), EncodingIndices.size()));
3571
70
}
3572
3573
64
static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3574
64
  // Try to find the underlying union declaration.
3575
64
  RecordDecl *RD = nullptr;
3576
64
  const auto *TD = dyn_cast<TypedefNameDecl>(D);
3577
64
  if (TD && 
TD->getUnderlyingType()->isUnionType()36
)
3578
36
    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
3579
28
  else
3580
28
    RD = dyn_cast<RecordDecl>(D);
3581
64
3582
64
  if (!RD || !RD->isUnion()) {
3583
0
    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) << AL
3584
0
                                                              << ExpectedUnion;
3585
0
    return;
3586
0
  }
3587
64
3588
64
  if (!RD->isCompleteDefinition()) {
3589
8
    if (!RD->isBeingDefined())
3590
0
      S.Diag(AL.getLoc(),
3591
0
             diag::warn_transparent_union_attribute_not_definition);
3592
8
    return;
3593
8
  }
3594
56
3595
56
  RecordDecl::field_iterator Field = RD->field_begin(),
3596
56
                          FieldEnd = RD->field_end();
3597
56
  if (Field == FieldEnd) {
3598
1
    S.Diag(AL.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
3599
1
    return;
3600
1
  }
3601
55
3602
55
  FieldDecl *FirstField = *Field;
3603
55
  QualType FirstType = FirstField->getType();
3604
55
  if (FirstType->hasFloatingRepresentation() || 
FirstType->isVectorType()54
) {
3605
2
    S.Diag(FirstField->getLocation(),
3606
2
           diag::warn_transparent_union_attribute_floating)
3607
2
      << FirstType->isVectorType() << FirstType;
3608
2
    return;
3609
2
  }
3610
53
3611
53
  if (FirstType->isIncompleteType())
3612
3
    return;
3613
50
  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
3614
50
  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
3615
212
  for (; Field != FieldEnd; 
++Field162
) {
3616
168
    QualType FieldType = Field->getType();
3617
168
    if (FieldType->isIncompleteType())
3618
1
      return;
3619
167
    // FIXME: this isn't fully correct; we also need to test whether the
3620
167
    // members of the union would all have the same calling convention as the
3621
167
    // first member of the union. Checking just the size and alignment isn't
3622
167
    // sufficient (consider structs passed on the stack instead of in registers
3623
167
    // as an example).
3624
167
    if (S.Context.getTypeSize(FieldType) != FirstSize ||
3625
167
        
S.Context.getTypeAlign(FieldType) > FirstAlign165
) {
3626
5
      // Warn if we drop the attribute.
3627
5
      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
3628
5
      unsigned FieldBits = isSize? 
S.Context.getTypeSize(FieldType)2
3629
5
                                 : 
S.Context.getTypeAlign(FieldType)3
;
3630
5
      S.Diag(Field->getLocation(),
3631
5
          diag::warn_transparent_union_attribute_field_size_align)
3632
5
        << isSize << Field->getDeclName() << FieldBits;
3633
5
      unsigned FirstBits = isSize? 
FirstSize2
:
FirstAlign3
;
3634
5
      S.Diag(FirstField->getLocation(),
3635
5
             diag::note_transparent_union_first_field_size_align)
3636
5
        << isSize << FirstBits;
3637
5
      return;
3638
5
    }
3639
167
  }
3640
50
3641
50
  RD->addAttr(::new (S.Context) TransparentUnionAttr(S.Context, AL));
3642
44
}
3643
3644
302
static void handleAnnotateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3645
302
  // Make sure that there is a string literal as the annotation's single
3646
302
  // argument.
3647
302
  StringRef Str;
3648
302
  if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
3649
2
    return;
3650
300
3651
300
  // Don't duplicate annotations that are already set.
3652
300
  for (const auto *I : D->specific_attrs<AnnotateAttr>()) {
3653
42
    if (I->getAnnotation() == Str)
3654
7
      return;
3655
42
  }
3656
300
3657
300
  D->addAttr(::new (S.Context) AnnotateAttr(S.Context, AL, Str));
3658
293
}
3659
3660
239
static void handleAlignValueAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3661
239
  S.AddAlignValueAttr(D, AL, AL.getArgAsExpr(0));
3662
239
}
3663
3664
242
void Sema::AddAlignValueAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E) {
3665
242
  AlignValueAttr TmpAttr(Context, CI, E);
3666
242
  SourceLocation AttrLoc = CI.getLoc();
3667
242
3668
242
  QualType T;
3669
242
  if (const auto *TD = dyn_cast<TypedefNameDecl>(D))
3670
14
    T = TD->getUnderlyingType();
3671
228
  else if (const auto *VD = dyn_cast<ValueDecl>(D))
3672
228
    T = VD->getType();
3673
228
  else
3674
228
    
llvm_unreachable0
("Unknown decl type for align_value");
3675
242
3676
242
  if (!T->isDependentType() && 
!T->isAnyPointerType()239
&&
3677
242
      
!T->isReferenceType()5
&&
!T->isMemberPointerType()1
) {
3678
1
    Diag(AttrLoc, diag::warn_attribute_pointer_or_reference_only)
3679
1
      << &TmpAttr /*TmpAttr.getName()*/ << T << D->getSourceRange();
3680
1
    return;
3681
1
  }
3682
241
3683
241
  if (!E->isValueDependent()) {
3684
238
    llvm::APSInt Alignment;
3685
238
    ExprResult ICE
3686
238
      = VerifyIntegerConstantExpression(E, &Alignment,
3687
238
          diag::err_align_value_attribute_argument_not_int,
3688
238
            /*AllowFold*/ false);
3689
238
    if (ICE.isInvalid())
3690
1
      return;
3691
237
3692
237
    if (!Alignment.isPowerOf2()) {
3693
3
      Diag(AttrLoc, diag::err_alignment_not_power_of_two)
3694
3
        << E->getSourceRange();
3695
3
      return;
3696
3
    }
3697
234
3698
234
    D->addAttr(::new (Context) AlignValueAttr(Context, CI, ICE.get()));
3699
234
    return;
3700
234
  }
3701
3
3702
3
  // Save dependent expressions in the AST to be instantiated.
3703
3
  D->addAttr(::new (Context) AlignValueAttr(Context, CI, E));
3704
3
}
3705
3706
33.5k
static void handleAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3707
33.5k
  // check the attribute arguments.
3708
33.5k
  if (AL.getNumArgs() > 1) {
3709
0
    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
3710
0
    return;
3711
0
  }
3712
33.5k
3713
33.5k
  if (AL.getNumArgs() == 0) {
3714
36
    D->addAttr(::new (S.Context) AlignedAttr(S.Context, AL, true, nullptr));
3715
36
    return;
3716
36
  }
3717
33.5k
3718
33.5k
  Expr *E = AL.getArgAsExpr(0);
3719
33.5k
  if (AL.isPackExpansion() && 
!E->containsUnexpandedParameterPack()7
) {
3720
1
    S.Diag(AL.getEllipsisLoc(),
3721
1
           diag::err_pack_expansion_without_parameter_packs);
3722
1
    return;
3723
1
  }
3724
33.5k
3725
33.5k
  if (!AL.isPackExpansion() && 
S.DiagnoseUnexpandedParameterPack(E)33.5k
)
3726
3
    return;
3727
33.5k
3728
33.5k
  S.AddAlignedAttr(D, AL, E, AL.isPackExpansion());
3729
33.5k
}
3730
3731
void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
3732
33.6k
                          bool IsPackExpansion) {
3733
33.6k
  AlignedAttr TmpAttr(Context, CI, true, E);
3734
33.6k
  SourceLocation AttrLoc = CI.getLoc();
3735
33.6k
3736
33.6k
  // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
3737
33.6k
  if (TmpAttr.isAlignas()) {
3738
10.8k
    // C++11 [dcl.align]p1:
3739
10.8k
    //   An alignment-specifier may be applied to a variable or to a class
3740
10.8k
    //   data member, but it shall not be applied to a bit-field, a function
3741
10.8k
    //   parameter, the formal parameter of a catch clause, or a variable
3742
10.8k
    //   declared with the register storage class specifier. An
3743
10.8k
    //   alignment-specifier may also be applied to the declaration of a class
3744
10.8k
    //   or enumeration type.
3745
10.8k
    // C11 6.7.5/2:
3746
10.8k
    //   An alignment attribute shall not be specified in a declaration of
3747
10.8k
    //   a typedef, or a bit-field, or a function, or a parameter, or an
3748
10.8k
    //   object declared with the register storage-class specifier.
3749
10.8k
    int DiagKind = -1;
3750