Coverage Report

Created: 2022-01-22 13:19

/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/AST/Type.h"
25
#include "clang/Basic/CharInfo.h"
26
#include "clang/Basic/DarwinSDKInfo.h"
27
#include "clang/Basic/SourceLocation.h"
28
#include "clang/Basic/SourceManager.h"
29
#include "clang/Basic/TargetBuiltins.h"
30
#include "clang/Basic/TargetInfo.h"
31
#include "clang/Lex/Preprocessor.h"
32
#include "clang/Sema/DeclSpec.h"
33
#include "clang/Sema/DelayedDiagnostic.h"
34
#include "clang/Sema/Initialization.h"
35
#include "clang/Sema/Lookup.h"
36
#include "clang/Sema/ParsedAttr.h"
37
#include "clang/Sema/Scope.h"
38
#include "clang/Sema/ScopeInfo.h"
39
#include "clang/Sema/SemaInternal.h"
40
#include "llvm/ADT/Optional.h"
41
#include "llvm/ADT/STLExtras.h"
42
#include "llvm/ADT/StringExtras.h"
43
#include "llvm/IR/Assumptions.h"
44
#include "llvm/MC/MCSectionMachO.h"
45
#include "llvm/Support/Error.h"
46
#include "llvm/Support/MathExtras.h"
47
#include "llvm/Support/raw_ostream.h"
48
49
using namespace clang;
50
using namespace sema;
51
52
namespace AttributeLangSupport {
53
  enum LANG {
54
    C,
55
    Cpp,
56
    ObjC
57
  };
58
} // end namespace AttributeLangSupport
59
60
//===----------------------------------------------------------------------===//
61
//  Helper functions
62
//===----------------------------------------------------------------------===//
63
64
/// isFunctionOrMethod - Return true if the given decl has function
65
/// type (function or function-typed variable) or an Objective-C
66
/// method.
67
66.7k
static bool isFunctionOrMethod(const Decl *D) {
68
66.7k
  return (D->getFunctionType() != nullptr) || 
isa<ObjCMethodDecl>(D)265
;
69
66.7k
}
70
71
/// Return true if the given decl has function type (function or
72
/// function-typed variable) or an Objective-C method or a block.
73
61.6k
static bool isFunctionOrMethodOrBlock(const Decl *D) {
74
61.6k
  return isFunctionOrMethod(D) || 
isa<BlockDecl>(D)1
;
75
61.6k
}
76
77
/// Return true if the given decl has a declarator that should have
78
/// been processed by Sema::GetTypeForDeclarator.
79
16.1k
static bool hasDeclarator(const Decl *D) {
80
  // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
81
16.1k
  return isa<DeclaratorDecl>(D) || 
isa<BlockDecl>(D)366
||
isa<TypedefNameDecl>(D)357
||
82
16.1k
         
isa<ObjCPropertyDecl>(D)206
;
83
16.1k
}
84
85
/// hasFunctionProto - Return true if the given decl has a argument
86
/// information. This decl should have already passed
87
/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
88
66.7k
static bool hasFunctionProto(const Decl *D) {
89
66.7k
  if (const FunctionType *FnTy = D->getFunctionType())
90
66.5k
    return isa<FunctionProtoType>(FnTy);
91
268
  return isa<ObjCMethodDecl>(D) || 
isa<BlockDecl>(D)9
;
92
66.7k
}
93
94
/// getFunctionOrMethodNumParams - Return number of function or method
95
/// parameters. It is an error to call this on a K&R function (use
96
/// hasFunctionProto first).
97
152k
static unsigned getFunctionOrMethodNumParams(const Decl *D) {
98
152k
  if (const FunctionType *FnTy = D->getFunctionType())
99
149k
    return cast<FunctionProtoType>(FnTy)->getNumParams();
100
2.94k
  if (const auto *BD = dyn_cast<BlockDecl>(D))
101
25
    return BD->getNumParams();
102
2.92k
  return cast<ObjCMethodDecl>(D)->param_size();
103
2.94k
}
104
105
static const ParmVarDecl *getFunctionOrMethodParam(const Decl *D,
106
54.8k
                                                   unsigned Idx) {
107
54.8k
  if (const auto *FD = dyn_cast<FunctionDecl>(D))
108
54.5k
    return FD->getParamDecl(Idx);
109
283
  if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
110
42
    return MD->getParamDecl(Idx);
111
241
  if (const auto *BD = dyn_cast<BlockDecl>(D))
112
16
    return BD->getParamDecl(Idx);
113
225
  return nullptr;
114
241
}
115
116
97.1k
static QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx) {
117
97.1k
  if (const FunctionType *FnTy = D->getFunctionType())
118
94.2k
    return cast<FunctionProtoType>(FnTy)->getParamType(Idx);
119
2.90k
  if (const auto *BD = dyn_cast<BlockDecl>(D))
120
16
    return BD->getParamDecl(Idx)->getType();
121
122
2.88k
  return cast<ObjCMethodDecl>(D)->parameters()[Idx]->getType();
123
2.90k
}
124
125
54.6k
static SourceRange getFunctionOrMethodParamRange(const Decl *D, unsigned Idx) {
126
54.6k
  if (auto *PVD = getFunctionOrMethodParam(D, Idx))
127
54.4k
    return PVD->getSourceRange();
128
225
  return SourceRange();
129
54.6k
}
130
131
18.0k
static QualType getFunctionOrMethodResultType(const Decl *D) {
132
18.0k
  if (const FunctionType *FnTy = D->getFunctionType())
133
17.7k
    return FnTy->getReturnType();
134
240
  return cast<ObjCMethodDecl>(D)->getReturnType();
135
18.0k
}
136
137
90
static SourceRange getFunctionOrMethodResultSourceRange(const Decl *D) {
138
90
  if (const auto *FD = dyn_cast<FunctionDecl>(D))
139
86
    return FD->getReturnTypeSourceRange();
140
4
  if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
141
4
    return MD->getReturnTypeSourceRange();
142
0
  return SourceRange();
143
4
}
144
145
79.3k
static bool isFunctionOrMethodVariadic(const Decl *D) {
146
79.3k
  if (const FunctionType *FnTy = D->getFunctionType())
147
77.1k
    return cast<FunctionProtoType>(FnTy)->isVariadic();
148
2.25k
  if (const auto *BD = dyn_cast<BlockDecl>(D))
149
14
    return BD->isVariadic();
150
2.23k
  return cast<ObjCMethodDecl>(D)->isVariadic();
151
2.25k
}
152
153
97.2k
static bool isInstanceMethod(const Decl *D) {
154
97.2k
  if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(D))
155
256
    return MethodDecl->isInstance();
156
97.0k
  return false;
157
97.2k
}
158
159
static inline bool isNSStringType(QualType T, ASTContext &Ctx,
160
5.17k
                                  bool AllowNSAttributedString = false) {
161
5.17k
  const auto *PT = T->getAs<ObjCObjectPointerType>();
162
5.17k
  if (!PT)
163
1.12k
    return false;
164
165
4.05k
  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
166
4.05k
  if (!Cls)
167
1
    return false;
168
169
4.05k
  IdentifierInfo* ClsName = Cls->getIdentifier();
170
171
4.05k
  if (AllowNSAttributedString &&
172
4.05k
      
ClsName == &Ctx.Idents.get("NSAttributedString")3.38k
)
173
3
    return true;
174
  // FIXME: Should we walk the chain of classes?
175
4.05k
  return ClsName == &Ctx.Idents.get("NSString") ||
176
4.05k
         
ClsName == &Ctx.Idents.get("NSMutableString")0
;
177
4.05k
}
178
179
2.01k
static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
180
2.01k
  const auto *PT = T->getAs<PointerType>();
181
2.01k
  if (!PT)
182
4
    return false;
183
184
2.01k
  const auto *RT = PT->getPointeeType()->getAs<RecordType>();
185
2.01k
  if (!RT)
186
452
    return false;
187
188
1.55k
  const RecordDecl *RD = RT->getDecl();
189
1.55k
  if (RD->getTagKind() != TTK_Struct)
190
0
    return false;
191
192
1.55k
  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
193
1.55k
}
194
195
366
static unsigned getNumAttributeArgs(const ParsedAttr &AL) {
196
  // FIXME: Include the type in the argument list.
197
366
  return AL.getNumArgs() + AL.hasParsedType();
198
366
}
199
200
/// A helper function to provide Attribute Location for the Attr types
201
/// AND the ParsedAttr.
202
template <typename AttrInfo>
203
static std::enable_if_t<std::is_base_of<Attr, AttrInfo>::value, SourceLocation>
204
23
getAttrLoc(const AttrInfo &AL) {
205
23
  return AL.getLocation();
206
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
204
9
getAttrLoc(const AttrInfo &AL) {
205
9
  return AL.getLocation();
206
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
204
9
getAttrLoc(const AttrInfo &AL) {
205
9
  return AL.getLocation();
206
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
204
5
getAttrLoc(const AttrInfo &AL) {
205
5
  return AL.getLocation();
206
5
}
207
85
static SourceLocation getAttrLoc(const ParsedAttr &AL) { return AL.getLoc(); }
208
209
/// If Expr is a valid integer constant, get the value of the integer
210
/// expression and return success or failure. May output an error.
211
///
212
/// Negative argument is implicitly converted to unsigned, unless
213
/// \p StrictlyUnsigned is true.
214
template <typename AttrInfo>
215
static bool checkUInt32Argument(Sema &S, const AttrInfo &AI, const Expr *Expr,
216
                                uint32_t &Val, unsigned Idx = UINT_MAX,
217
1.16M
                                bool StrictlyUnsigned = false) {
218
1.16M
  Optional<llvm::APSInt> I = llvm::APSInt(32);
219
1.16M
  if (Expr->isTypeDependent() ||
220
1.16M
      !(I = Expr->getIntegerConstantExpr(S.Context))) {
221
34
    if (Idx != UINT_MAX)
222
24
      S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
223
24
          << &AI << Idx << AANT_ArgumentIntegerConstant
224
24
          << Expr->getSourceRange();
225
10
    else
226
10
      S.Diag(getAttrLoc(AI), diag::err_attribute_argument_type)
227
10
          << &AI << AANT_ArgumentIntegerConstant << Expr->getSourceRange();
228
34
    return false;
229
34
  }
230
231
1.16M
  if (!I->isIntN(32)) {
232
10
    S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
233
10
        << toString(*I, 10, false) << 32 << /* Unsigned */ 1;
234
10
    return false;
235
10
  }
236
237
1.16M
  if (StrictlyUnsigned && 
I->isSigned()101
&&
I->isNegative()101
) {
238
3
    S.Diag(getAttrLoc(AI), diag::err_attribute_requires_positive_integer)
239
3
        << &AI << /*non-negative*/ 1;
240
3
    return false;
241
3
  }
242
243
1.16M
  Val = (uint32_t)I->getZExtValue();
244
1.16M
  return true;
245
1.16M
}
SemaDeclAttr.cpp:bool checkUInt32Argument<clang::AMDGPUFlatWorkGroupSizeAttr>(clang::Sema&, clang::AMDGPUFlatWorkGroupSizeAttr const&, clang::Expr const*, unsigned int&, unsigned int, bool)
Line
Count
Source
217
205
                                bool StrictlyUnsigned = false) {
218
205
  Optional<llvm::APSInt> I = llvm::APSInt(32);
219
205
  if (Expr->isTypeDependent() ||
220
205
      !(I = Expr->getIntegerConstantExpr(S.Context))) {
221
9
    if (Idx != UINT_MAX)
222
9
      S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
223
9
          << &AI << Idx << AANT_ArgumentIntegerConstant
224
9
          << Expr->getSourceRange();
225
0
    else
226
0
      S.Diag(getAttrLoc(AI), diag::err_attribute_argument_type)
227
0
          << &AI << AANT_ArgumentIntegerConstant << Expr->getSourceRange();
228
9
    return false;
229
9
  }
230
231
196
  if (!I->isIntN(32)) {
232
3
    S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
233
3
        << toString(*I, 10, false) << 32 << /* Unsigned */ 1;
234
3
    return false;
235
3
  }
236
237
193
  if (StrictlyUnsigned && 
I->isSigned()0
&&
I->isNegative()0
) {
238
0
    S.Diag(getAttrLoc(AI), diag::err_attribute_requires_positive_integer)
239
0
        << &AI << /*non-negative*/ 1;
240
0
    return false;
241
0
  }
242
243
193
  Val = (uint32_t)I->getZExtValue();
244
193
  return true;
245
193
}
SemaDeclAttr.cpp:bool checkUInt32Argument<clang::AMDGPUWavesPerEUAttr>(clang::Sema&, clang::AMDGPUWavesPerEUAttr const&, clang::Expr const*, unsigned int&, unsigned int, bool)
Line
Count
Source
217
192
                                bool StrictlyUnsigned = false) {
218
192
  Optional<llvm::APSInt> I = llvm::APSInt(32);
219
192
  if (Expr->isTypeDependent() ||
220
192
      !(I = Expr->getIntegerConstantExpr(S.Context))) {
221
9
    if (Idx != UINT_MAX)
222
9
      S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
223
9
          << &AI << Idx << AANT_ArgumentIntegerConstant
224
9
          << Expr->getSourceRange();
225
0
    else
226
0
      S.Diag(getAttrLoc(AI), diag::err_attribute_argument_type)
227
0
          << &AI << AANT_ArgumentIntegerConstant << Expr->getSourceRange();
228
9
    return false;
229
9
  }
230
231
183
  if (!I->isIntN(32)) {
232
3
    S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
233
3
        << toString(*I, 10, false) << 32 << /* Unsigned */ 1;
234
3
    return false;
235
3
  }
236
237
180
  if (StrictlyUnsigned && 
I->isSigned()0
&&
I->isNegative()0
) {
238
0
    S.Diag(getAttrLoc(AI), diag::err_attribute_requires_positive_integer)
239
0
        << &AI << /*non-negative*/ 1;
240
0
    return false;
241
0
  }
242
243
180
  Val = (uint32_t)I->getZExtValue();
244
180
  return true;
245
180
}
SemaDeclAttr.cpp:bool checkUInt32Argument<clang::ParsedAttr>(clang::Sema&, clang::ParsedAttr const&, clang::Expr const*, unsigned int&, unsigned int, bool)
Line
Count
Source
217
1.16M
                                bool StrictlyUnsigned = false) {
218
1.16M
  Optional<llvm::APSInt> I = llvm::APSInt(32);
219
1.16M
  if (Expr->isTypeDependent() ||
220
1.16M
      !(I = Expr->getIntegerConstantExpr(S.Context))) {
221
16
    if (Idx != UINT_MAX)
222
6
      S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
223
6
          << &AI << Idx << AANT_ArgumentIntegerConstant
224
6
          << Expr->getSourceRange();
225
10
    else
226
10
      S.Diag(getAttrLoc(AI), diag::err_attribute_argument_type)
227
10
          << &AI << AANT_ArgumentIntegerConstant << Expr->getSourceRange();
228
16
    return false;
229
16
  }
230
231
1.16M
  if (!I->isIntN(32)) {
232
4
    S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
233
4
        << toString(*I, 10, false) << 32 << /* Unsigned */ 1;
234
4
    return false;
235
4
  }
236
237
1.16M
  if (StrictlyUnsigned && 
I->isSigned()101
&&
I->isNegative()101
) {
238
3
    S.Diag(getAttrLoc(AI), diag::err_attribute_requires_positive_integer)
239
3
        << &AI << /*non-negative*/ 1;
240
3
    return false;
241
3
  }
242
243
1.16M
  Val = (uint32_t)I->getZExtValue();
244
1.16M
  return true;
245
1.16M
}
246
247
/// Wrapper around checkUInt32Argument, with an extra check to be sure
248
/// that the result will fit into a regular (signed) int. All args have the same
249
/// purpose as they do in checkUInt32Argument.
250
template <typename AttrInfo>
251
static bool checkPositiveIntArgument(Sema &S, const AttrInfo &AI, const Expr *Expr,
252
5.84k
                                     int &Val, unsigned Idx = UINT_MAX) {
253
5.84k
  uint32_t UVal;
254
5.84k
  if (!checkUInt32Argument(S, AI, Expr, UVal, Idx))
255
2
    return false;
256
257
5.84k
  if (UVal > (uint32_t)std::numeric_limits<int>::max()) {
258
1
    llvm::APSInt I(32); // for toString
259
1
    I = UVal;
260
1
    S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
261
1
        << toString(I, 10, false) << 32 << /* Unsigned */ 0;
262
1
    return false;
263
1
  }
264
265
5.83k
  Val = UVal;
266
5.83k
  return true;
267
5.84k
}
268
269
/// Diagnose mutually exclusive attributes when present on a given
270
/// declaration. Returns true if diagnosed.
271
template <typename AttrTy>
272
265
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
273
265
  if (const auto *A = D->getAttr<AttrTy>()) {
274
3
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
275
3
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
276
3
    return true;
277
3
  }
278
262
  return false;
279
265
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::Mips16Attr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
272
23
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
273
23
  if (const auto *A = D->getAttr<AttrTy>()) {
274
2
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
275
2
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
276
2
    return true;
277
2
  }
278
21
  return false;
279
23
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::CPUSpecificAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
272
53
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
273
53
  if (const auto *A = D->getAttr<AttrTy>()) {
274
0
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
275
0
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
276
0
    return true;
277
0
  }
278
53
  return false;
279
53
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::CPUDispatchAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
272
99
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
273
99
  if (const auto *A = D->getAttr<AttrTy>()) {
274
0
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
275
0
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
276
0
    return true;
277
0
  }
278
99
  return false;
279
99
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::TargetClonesAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
272
47
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
273
47
  if (const auto *A = D->getAttr<AttrTy>()) {
274
0
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
275
0
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
276
0
    return true;
277
0
  }
278
47
  return false;
279
47
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::PointerAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
272
28
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
273
28
  if (const auto *A = D->getAttr<AttrTy>()) {
274
1
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
275
1
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
276
1
    return true;
277
1
  }
278
27
  return false;
279
28
}
SemaDeclAttr.cpp:bool checkAttrMutualExclusion<clang::OwnerAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
272
15
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
273
15
  if (const auto *A = D->getAttr<AttrTy>()) {
274
0
    S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
275
0
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
276
0
    return true;
277
0
  }
278
15
  return false;
279
15
}
280
281
template <typename AttrTy>
282
static bool checkAttrMutualExclusion(Sema &S, Decl *D, const Attr &AL) {
283
  if (const auto *A = D->getAttr<AttrTy>()) {
284
    S.Diag(AL.getLocation(), diag::err_attributes_are_not_compatible) << &AL
285
                                                                      << A;
286
    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
287
    return true;
288
  }
289
  return false;
290
}
291
292
/// Check if IdxExpr is a valid parameter index for a function or
293
/// instance method D.  May output an error.
294
///
295
/// \returns true if IdxExpr is a valid index.
296
template <typename AttrInfo>
297
static bool checkFunctionOrMethodParameterIndex(
298
    Sema &S, const Decl *D, const AttrInfo &AI, unsigned AttrArgNum,
299
61.6k
    const Expr *IdxExpr, ParamIdx &Idx, bool CanIndexImplicitThis = false) {
300
61.6k
  assert(isFunctionOrMethodOrBlock(D));
301
302
  // In C++ the implicit 'this' function parameter also counts.
303
  // Parameters are counted from one.
304
0
  bool HP = hasFunctionProto(D);
305
61.6k
  bool HasImplicitThisParam = isInstanceMethod(D);
306
61.6k
  bool IV = HP && 
isFunctionOrMethodVariadic(D)61.6k
;
307
61.6k
  unsigned NumParams =
308
61.6k
      (HP ? 
getFunctionOrMethodNumParams(D)61.6k
:
05
) + HasImplicitThisParam;
309
310
61.6k
  Optional<llvm::APSInt> IdxInt;
311
61.6k
  if (IdxExpr->isTypeDependent() ||
312
61.6k
      !(IdxInt = IdxExpr->getIntegerConstantExpr(S.Context))) {
313
13
    S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
314
13
        << &AI << AttrArgNum << AANT_ArgumentIntegerConstant
315
13
        << IdxExpr->getSourceRange();
316
13
    return false;
317
13
  }
318
319
61.6k
  unsigned IdxSource = IdxInt->getLimitedValue(UINT_MAX);
320
61.6k
  if (IdxSource < 1 || 
(61.5k
!IV61.5k
&&
IdxSource > NumParams61.0k
)) {
321
51
    S.Diag(getAttrLoc(AI), diag::err_attribute_argument_out_of_bounds)
322
51
        << &AI << AttrArgNum << IdxExpr->getSourceRange();
323
51
    return false;
324
51
  }
325
61.5k
  if (HasImplicitThisParam && 
!CanIndexImplicitThis75
) {
326
72
    if (IdxSource == 1) {
327
6
      S.Diag(getAttrLoc(AI), diag::err_attribute_invalid_implicit_this_argument)
328
6
          << &AI << IdxExpr->getSourceRange();
329
6
      return false;
330
6
    }
331
72
  }
332
333
61.5k
  Idx = ParamIdx(IdxSource, D);
334
61.5k
  return true;
335
61.5k
}
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
299
61.5k
    const Expr *IdxExpr, ParamIdx &Idx, bool CanIndexImplicitThis = false) {
300
61.5k
  assert(isFunctionOrMethodOrBlock(D));
301
302
  // In C++ the implicit 'this' function parameter also counts.
303
  // Parameters are counted from one.
304
0
  bool HP = hasFunctionProto(D);
305
61.5k
  bool HasImplicitThisParam = isInstanceMethod(D);
306
61.5k
  bool IV = HP && 
isFunctionOrMethodVariadic(D)61.5k
;
307
61.5k
  unsigned NumParams =
308
61.5k
      (HP ? 
getFunctionOrMethodNumParams(D)61.5k
:
05
) + HasImplicitThisParam;
309
310
61.5k
  Optional<llvm::APSInt> IdxInt;
311
61.5k
  if (IdxExpr->isTypeDependent() ||
312
61.5k
      !(IdxInt = IdxExpr->getIntegerConstantExpr(S.Context))) {
313
11
    S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
314
11
        << &AI << AttrArgNum << AANT_ArgumentIntegerConstant
315
11
        << IdxExpr->getSourceRange();
316
11
    return false;
317
11
  }
318
319
61.5k
  unsigned IdxSource = IdxInt->getLimitedValue(UINT_MAX);
320
61.5k
  if (IdxSource < 1 || 
(61.5k
!IV61.5k
&&
IdxSource > NumParams61.0k
)) {
321
49
    S.Diag(getAttrLoc(AI), diag::err_attribute_argument_out_of_bounds)
322
49
        << &AI << AttrArgNum << IdxExpr->getSourceRange();
323
49
    return false;
324
49
  }
325
61.5k
  if (HasImplicitThisParam && 
!CanIndexImplicitThis64
) {
326
61
    if (IdxSource == 1) {
327
5
      S.Diag(getAttrLoc(AI), diag::err_attribute_invalid_implicit_this_argument)
328
5
          << &AI << IdxExpr->getSourceRange();
329
5
      return false;
330
5
    }
331
61
  }
332
333
61.5k
  Idx = ParamIdx(IdxSource, D);
334
61.5k
  return true;
335
61.5k
}
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
299
42
    const Expr *IdxExpr, ParamIdx &Idx, bool CanIndexImplicitThis = false) {
300
42
  assert(isFunctionOrMethodOrBlock(D));
301
302
  // In C++ the implicit 'this' function parameter also counts.
303
  // Parameters are counted from one.
304
0
  bool HP = hasFunctionProto(D);
305
42
  bool HasImplicitThisParam = isInstanceMethod(D);
306
42
  bool IV = HP && isFunctionOrMethodVariadic(D);
307
42
  unsigned NumParams =
308
42
      (HP ? getFunctionOrMethodNumParams(D) : 
00
) + HasImplicitThisParam;
309
310
42
  Optional<llvm::APSInt> IdxInt;
311
42
  if (IdxExpr->isTypeDependent() ||
312
42
      !(IdxInt = IdxExpr->getIntegerConstantExpr(S.Context))) {
313
2
    S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
314
2
        << &AI << AttrArgNum << AANT_ArgumentIntegerConstant
315
2
        << IdxExpr->getSourceRange();
316
2
    return false;
317
2
  }
318
319
40
  unsigned IdxSource = IdxInt->getLimitedValue(UINT_MAX);
320
40
  if (IdxSource < 1 || 
(39
!IV39
&&
IdxSource > NumParams39
)) {
321
2
    S.Diag(getAttrLoc(AI), diag::err_attribute_argument_out_of_bounds)
322
2
        << &AI << AttrArgNum << IdxExpr->getSourceRange();
323
2
    return false;
324
2
  }
325
38
  if (HasImplicitThisParam && 
!CanIndexImplicitThis11
) {
326
11
    if (IdxSource == 1) {
327
1
      S.Diag(getAttrLoc(AI), diag::err_attribute_invalid_implicit_this_argument)
328
1
          << &AI << IdxExpr->getSourceRange();
329
1
      return false;
330
1
    }
331
11
  }
332
333
37
  Idx = ParamIdx(IdxSource, D);
334
37
  return true;
335
38
}
336
337
/// Check if the argument \p ArgNum of \p Attr is a ASCII string literal.
338
/// If not emit an error and return false. If the argument is an identifier it
339
/// will emit an error with a fixit hint and treat it as if it was a string
340
/// literal.
341
bool Sema::checkStringLiteralArgumentAttr(const ParsedAttr &AL, unsigned ArgNum,
342
                                          StringRef &Str,
343
2.96M
                                          SourceLocation *ArgLocation) {
344
  // Look for identifiers. If we have one emit a hint to fix it to a literal.
345
2.96M
  if (AL.isArgIdent(ArgNum)) {
346
11
    IdentifierLoc *Loc = AL.getArgAsIdent(ArgNum);
347
11
    Diag(Loc->Loc, diag::err_attribute_argument_type)
348
11
        << AL << AANT_ArgumentString
349
11
        << FixItHint::CreateInsertion(Loc->Loc, "\"")
350
11
        << FixItHint::CreateInsertion(getLocForEndOfToken(Loc->Loc), "\"");
351
11
    Str = Loc->Ident->getName();
352
11
    if (ArgLocation)
353
8
      *ArgLocation = Loc->Loc;
354
11
    return true;
355
11
  }
356
357
  // Now check for an actual string literal.
358
2.96M
  Expr *ArgExpr = AL.getArgAsExpr(ArgNum);
359
2.96M
  const auto *Literal = dyn_cast<StringLiteral>(ArgExpr->IgnoreParenCasts());
360
2.96M
  if (ArgLocation)
361
2.92M
    *ArgLocation = ArgExpr->getBeginLoc();
362
363
2.96M
  if (!Literal || 
!Literal->isAscii()2.96M
) {
364
33
    Diag(ArgExpr->getBeginLoc(), diag::err_attribute_argument_type)
365
33
        << AL << AANT_ArgumentString;
366
33
    return false;
367
33
  }
368
369
2.96M
  Str = Literal->getString();
370
2.96M
  return true;
371
2.96M
}
372
373
/// Applies the given attribute to the Decl without performing any
374
/// additional semantic checking.
375
template <typename AttrType>
376
static void handleSimpleAttribute(Sema &S, Decl *D,
377
276k
                                  const AttributeCommonInfo &CI) {
378
276k
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
276k
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::AVRInterruptAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
2
                                  const AttributeCommonInfo &CI) {
378
2
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
2
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::AVRSignalAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
2
                                  const AttributeCommonInfo &CI) {
378
2
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
2
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::SYCLKernelAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
23
                                  const AttributeCommonInfo &CI) {
378
23
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
23
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::AnyX86NoCfCheckAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
19
                                  const AttributeCommonInfo &CI) {
378
19
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
19
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NoThrowAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
21.7k
                                  const AttributeCommonInfo &CI) {
378
21.7k
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
21.7k
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::OSReturnsRetainedOnZeroAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
3
                                  const AttributeCommonInfo &CI) {
378
3
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
3
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::OSReturnsRetainedOnNonZeroAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
2
                                  const AttributeCommonInfo &CI) {
378
2
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
2
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NSReturnsAutoreleasedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
6
                                  const AttributeCommonInfo &CI) {
378
6
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
6
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::CFReturnsNotRetainedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
526
                                  const AttributeCommonInfo &CI) {
378
526
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
526
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NSReturnsNotRetainedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
113
                                  const AttributeCommonInfo &CI) {
378
113
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
113
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::CFReturnsRetainedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
32.1k
                                  const AttributeCommonInfo &CI) {
378
32.1k
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
32.1k
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NSReturnsRetainedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
23.8k
                                  const AttributeCommonInfo &CI) {
378
23.8k
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
23.8k
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::OSReturnsRetainedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
19
                                  const AttributeCommonInfo &CI) {
378
19
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
19
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::OSReturnsNotRetainedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
11
                                  const AttributeCommonInfo &CI) {
378
11
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
11
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ObjCDirectAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
115
                                  const AttributeCommonInfo &CI) {
378
115
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
115
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ObjCDirectMembersAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
24
                                  const AttributeCommonInfo &CI) {
378
24
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
24
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::AlwaysDestroyAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
24
                                  const AttributeCommonInfo &CI) {
378
24
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
24
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NoDestroyAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
38
                                  const AttributeCommonInfo &CI) {
378
38
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
38
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::ObjCExternallyRetainedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
51
                                  const AttributeCommonInfo &CI) {
378
51
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
51
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::MIGServerRoutineAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
26
                                  const AttributeCommonInfo &CI) {
378
26
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
26
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::MSAllocatorAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
5
                                  const AttributeCommonInfo &CI) {
378
5
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
5
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::UsingIfExistsAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
195k
                                  const AttributeCommonInfo &CI) {
378
195k
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
195k
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::OSConsumedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
9
                                  const AttributeCommonInfo &CI) {
378
9
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
9
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::NSConsumedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
421
                                  const AttributeCommonInfo &CI) {
378
421
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
421
}
SemaDeclAttr.cpp:void handleSimpleAttribute<clang::CFConsumedAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&)
Line
Count
Source
377
1.90k
                                  const AttributeCommonInfo &CI) {
378
1.90k
  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
379
1.90k
}
380
381
template <typename... DiagnosticArgs>
382
static const Sema::SemaDiagnosticBuilder&
383
4
appendDiagnostics(const Sema::SemaDiagnosticBuilder &Bldr) {
384
4
  return Bldr;
385
4
}
386
387
template <typename T, typename... DiagnosticArgs>
388
static const Sema::SemaDiagnosticBuilder&
389
appendDiagnostics(const Sema::SemaDiagnosticBuilder &Bldr, T &&ExtraArg,
390
12
                  DiagnosticArgs &&... ExtraArgs) {
391
12
  return appendDiagnostics(Bldr << std::forward<T>(ExtraArg),
392
12
                           std::forward<DiagnosticArgs>(ExtraArgs)...);
393
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
390
2
                  DiagnosticArgs &&... ExtraArgs) {
391
2
  return appendDiagnostics(Bldr << std::forward<T>(ExtraArg),
392
2
                           std::forward<DiagnosticArgs>(ExtraArgs)...);
393
2
}
SemaDeclAttr.cpp:clang::Sema::SemaDiagnosticBuilder const& appendDiagnostics<int, clang::SourceRange>(clang::Sema::SemaDiagnosticBuilder const&, int&&, clang::SourceRange&&)
Line
Count
Source
390
2
                  DiagnosticArgs &&... ExtraArgs) {
391
2
  return appendDiagnostics(Bldr << std::forward<T>(ExtraArg),
392
2
                           std::forward<DiagnosticArgs>(ExtraArgs)...);
393
2
}
SemaDeclAttr.cpp:clang::Sema::SemaDiagnosticBuilder const& appendDiagnostics<clang::SourceRange>(clang::Sema::SemaDiagnosticBuilder const&, clang::SourceRange&&)
Line
Count
Source
390
2
                  DiagnosticArgs &&... ExtraArgs) {
391
2
  return appendDiagnostics(Bldr << std::forward<T>(ExtraArg),
392
2
                           std::forward<DiagnosticArgs>(ExtraArgs)...);
393
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
390
2
                  DiagnosticArgs &&... ExtraArgs) {
391
2
  return appendDiagnostics(Bldr << std::forward<T>(ExtraArg),
392
2
                           std::forward<DiagnosticArgs>(ExtraArgs)...);
393
2
}
SemaDeclAttr.cpp:clang::Sema::SemaDiagnosticBuilder const& appendDiagnostics<char const (&) [12], int>(clang::Sema::SemaDiagnosticBuilder const&, char const (&) [12], int&&)
Line
Count
Source
390
2
                  DiagnosticArgs &&... ExtraArgs) {
391
2
  return appendDiagnostics(Bldr << std::forward<T>(ExtraArg),
392
2
                           std::forward<DiagnosticArgs>(ExtraArgs)...);
393
2
}
SemaDeclAttr.cpp:clang::Sema::SemaDiagnosticBuilder const& appendDiagnostics<int>(clang::Sema::SemaDiagnosticBuilder const&, int&&)
Line
Count
Source
390
2
                  DiagnosticArgs &&... ExtraArgs) {
391
2
  return appendDiagnostics(Bldr << std::forward<T>(ExtraArg),
392
2
                           std::forward<DiagnosticArgs>(ExtraArgs)...);
393
2
}
394
395
/// Add an attribute @c AttrType to declaration @c D, provided that
396
/// @c PassesCheck is true.
397
/// Otherwise, emit diagnostic @c DiagID, passing in all parameters
398
/// specified in @c ExtraArgs.
399
template <typename AttrType, typename... DiagnosticArgs>
400
static void handleSimpleAttributeOrDiagnose(Sema &S, Decl *D,
401
                                            const AttributeCommonInfo &CI,
402
                                            bool PassesCheck, unsigned DiagID,
403
2.33k
                                            DiagnosticArgs &&... ExtraArgs) {
404
2.33k
  if (!PassesCheck) {
405
4
    Sema::SemaDiagnosticBuilder DB = S.Diag(D->getBeginLoc(), DiagID);
406
4
    appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...);
407
4
    return;
408
4
  }
409
2.33k
  handleSimpleAttribute<AttrType>(S, D, CI);
410
2.33k
}
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
403
4
                                            DiagnosticArgs &&... ExtraArgs) {
404
4
  if (!PassesCheck) {
405
1
    Sema::SemaDiagnosticBuilder DB = S.Diag(D->getBeginLoc(), DiagID);
406
1
    appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...);
407
1
    return;
408
1
  }
409
3
  handleSimpleAttribute<AttrType>(S, D, CI);
410
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
403
3
                                            DiagnosticArgs &&... ExtraArgs) {
404
3
  if (!PassesCheck) {
405
1
    Sema::SemaDiagnosticBuilder DB = S.Diag(D->getBeginLoc(), DiagID);
406
1
    appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...);
407
1
    return;
408
1
  }
409
2
  handleSimpleAttribute<AttrType>(S, D, CI);
410
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
403
10
                                            DiagnosticArgs &&... ExtraArgs) {
404
10
  if (!PassesCheck) {
405
1
    Sema::SemaDiagnosticBuilder DB = S.Diag(D->getBeginLoc(), DiagID);
406
1
    appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...);
407
1
    return;
408
1
  }
409
9
  handleSimpleAttribute<AttrType>(S, D, CI);
410
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
403
422
                                            DiagnosticArgs &&... ExtraArgs) {
404
422
  if (!PassesCheck) {
405
1
    Sema::SemaDiagnosticBuilder DB = S.Diag(D->getBeginLoc(), DiagID);
406
1
    appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...);
407
1
    return;
408
1
  }
409
421
  handleSimpleAttribute<AttrType>(S, D, CI);
410
421
}
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
403
1.90k
                                            DiagnosticArgs &&... ExtraArgs) {
404
1.90k
  if (!PassesCheck) {
405
0
    Sema::SemaDiagnosticBuilder DB = S.Diag(D->getBeginLoc(), DiagID);
406
0
    appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...);
407
0
    return;
408
0
  }
409
1.90k
  handleSimpleAttribute<AttrType>(S, D, CI);
410
1.90k
}
411
412
/// Check if the passed-in expression is of type int or bool.
413
188
static bool isIntOrBool(Expr *Exp) {
414
188
  QualType QT = Exp->getType();
415
188
  return QT->isBooleanType() || 
QT->isIntegerType()132
;
416
188
}
417
418
419
// Check to see if the type is a smart pointer of some kind.  We assume
420
// it's a smart pointer if it defines both operator-> and operator*.
421
2.80k
static bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) {
422
2.80k
  auto IsOverloadedOperatorPresent = [&S](const RecordDecl *Record,
423
5.68k
                                          OverloadedOperatorKind Op) {
424
5.68k
    DeclContextLookupResult Result =
425
5.68k
        Record->lookup(S.Context.DeclarationNames.getCXXOperatorName(Op));
426
5.68k
    return !Result.empty();
427
5.68k
  };
428
429
2.80k
  const RecordDecl *Record = RT->getDecl();
430
2.80k
  bool foundStarOperator = IsOverloadedOperatorPresent(Record, OO_Star);
431
2.80k
  bool foundArrowOperator = IsOverloadedOperatorPresent(Record, OO_Arrow);
432
2.80k
  if (foundStarOperator && 
foundArrowOperator46
)
433
46
    return true;
434
435
2.75k
  const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(Record);
436
2.75k
  if (!CXXRecord)
437
21
    return false;
438
439
2.73k
  for (auto BaseSpecifier : CXXRecord->bases()) {
440
44
    if (!foundStarOperator)
441
44
      foundStarOperator = IsOverloadedOperatorPresent(
442
44
          BaseSpecifier.getType()->getAsRecordDecl(), OO_Star);
443
44
    if (!foundArrowOperator)
444
44
      foundArrowOperator = IsOverloadedOperatorPresent(
445
44
          BaseSpecifier.getType()->getAsRecordDecl(), OO_Arrow);
446
44
  }
447
448
2.73k
  if (foundStarOperator && 
foundArrowOperator16
)
449
16
    return true;
450
451
2.71k
  return false;
452
2.73k
}
453
454
/// Check if passed in Decl is a pointer type.
455
/// Note that this function may produce an error message.
456
/// \return true if the Decl is a pointer type; false otherwise
457
static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
458
161
                                       const ParsedAttr &AL) {
459
161
  const auto *VD = cast<ValueDecl>(D);
460
161
  QualType QT = VD->getType();
461
161
  if (QT->isAnyPointerType())
462
122
    return true;
463
464
39
  if (const auto *RT = QT->getAs<RecordType>()) {
465
    // If it's an incomplete type, it could be a smart pointer; skip it.
466
    // (We don't want to force template instantiation if we can avoid it,
467
    // since that would alter the order in which templates are instantiated.)
468
22
    if (RT->isIncompleteType())
469
3
      return true;
470
471
19
    if (threadSafetyCheckIsSmartPointer(S, RT))
472
19
      return true;
473
19
  }
474
475
17
  S.Diag(AL.getLoc(), diag::warn_thread_attribute_decl_not_pointer) << AL << QT;
476
17
  return false;
477
39
}
478
479
/// Checks that the passed in QualType either is of RecordType or points
480
/// to RecordType. Returns the relevant RecordType, null if it does not exit.
481
5.87k
static const RecordType *getRecordType(QualType QT) {
482
5.87k
  if (const auto *RT = QT->getAs<RecordType>())
483
4.54k
    return RT;
484
485
  // Now check if we point to record type.
486
1.33k
  if (const auto *PT = QT->getAs<PointerType>())
487
804
    return PT->getPointeeType()->getAs<RecordType>();
488
489
529
  return nullptr;
490
1.33k
}
491
492
template <typename AttrType>
493
3.28k
static bool checkRecordDeclForAttr(const RecordDecl *RD) {
494
  // Check if the record itself has the attribute.
495
3.28k
  if (RD->hasAttr<AttrType>())
496
2.95k
    return true;
497
498
  // Else check if any base classes have the attribute.
499
331
  if (const auto *CRD = dyn_cast<CXXRecordDecl>(RD)) {
500
329
    if (!CRD->forallBases([](const CXXRecordDecl *Base) {
501
58
          return !Base->hasAttr<AttrType>();
502
58
        }))
SemaDeclAttr.cpp:bool checkRecordDeclForAttr<clang::CapabilityAttr>(clang::RecordDecl const*)::'lambda'(clang::CXXRecordDecl const*)::operator()(clang::CXXRecordDecl const*) const
Line
Count
Source
500
46
    if (!CRD->forallBases([](const CXXRecordDecl *Base) {
501
46
          return !Base->hasAttr<AttrType>();
502
46
        }))
SemaDeclAttr.cpp:bool checkRecordDeclForAttr<clang::ScopedLockableAttr>(clang::RecordDecl const*)::'lambda'(clang::CXXRecordDecl const*)::operator()(clang::CXXRecordDecl const*) const
Line
Count
Source
500
12
    if (!CRD->forallBases([](const CXXRecordDecl *Base) {
501
12
          return !Base->hasAttr<AttrType>();
502
12
        }))
503
22
      return true;
504
329
  }
505
309
  return false;
506
331
}
SemaDeclAttr.cpp:bool checkRecordDeclForAttr<clang::CapabilityAttr>(clang::RecordDecl const*)
Line
Count
Source
493
3.11k
static bool checkRecordDeclForAttr(const RecordDecl *RD) {
494
  // Check if the record itself has the attribute.
495
3.11k
  if (RD->hasAttr<AttrType>())
496
2.81k
    return true;
497
498
  // Else check if any base classes have the attribute.
499
300
  if (const auto *CRD = dyn_cast<CXXRecordDecl>(RD)) {
500
298
    if (!CRD->forallBases([](const CXXRecordDecl *Base) {
501
298
          return !Base->hasAttr<AttrType>();
502
298
        }))
503
19
      return true;
504
298
  }
505
281
  return false;
506
300
}
SemaDeclAttr.cpp:bool checkRecordDeclForAttr<clang::ScopedLockableAttr>(clang::RecordDecl const*)
Line
Count
Source
493
170
static bool checkRecordDeclForAttr(const RecordDecl *RD) {
494
  // Check if the record itself has the attribute.
495
170
  if (RD->hasAttr<AttrType>())
496
139
    return true;
497
498
  // Else check if any base classes have the attribute.
499
31
  if (const auto *CRD = dyn_cast<CXXRecordDecl>(RD)) {
500
31
    if (!CRD->forallBases([](const CXXRecordDecl *Base) {
501
31
          return !Base->hasAttr<AttrType>();
502
31
        }))
503
3
      return true;
504
31
  }
505
28
  return false;
506
31
}
507
508
3.13k
static bool checkRecordTypeForCapability(Sema &S, QualType Ty) {
509
3.13k
  const RecordType *RT = getRecordType(Ty);
510
511
3.13k
  if (!RT)
512
356
    return false;
513
514
  // Don't check for the capability if the class hasn't been defined yet.
515
2.78k
  if (RT->isIncompleteType())
516
0
    return true;
517
518
  // Allow smart pointers to be used as capability objects.
519
  // FIXME -- Check the type that the smart pointer points to.
520
2.78k
  if (threadSafetyCheckIsSmartPointer(S, RT))
521
43
    return true;
522
523
2.73k
  return checkRecordDeclForAttr<CapabilityAttr>(RT->getDecl());
524
2.78k
}
525
526
3.19k
static bool checkTypedefTypeForCapability(QualType Ty) {
527
3.19k
  const auto *TD = Ty->getAs<TypedefType>();
528
3.19k
  if (!TD)
529
3.13k
    return false;
530
531
60
  TypedefNameDecl *TN = TD->getDecl();
532
60
  if (!TN)
533
0
    return false;
534
535
60
  return TN->hasAttr<CapabilityAttr>();
536
60
}
537
538
3.19k
static bool typeHasCapability(Sema &S, QualType Ty) {
539
3.19k
  if (checkTypedefTypeForCapability(Ty))
540
60
    return true;
541
542
3.13k
  if (checkRecordTypeForCapability(S, Ty))
543
2.67k
    return true;
544
545
467
  return false;
546
3.13k
}
547
548
343
static bool isCapabilityExpr(Sema &S, const Expr *Ex) {
549
  // Capability expressions are simple expressions involving the boolean logic
550
  // operators &&, || or !, a simple DeclRefExpr, CastExpr or a ParenExpr. Once
551
  // a DeclRefExpr is found, its type should be checked to determine whether it
552
  // is a capability or not.
553
554
343
  if (const auto *E = dyn_cast<CastExpr>(Ex))
555
50
    return isCapabilityExpr(S, E->getSubExpr());
556
293
  else if (const auto *E = dyn_cast<ParenExpr>(Ex))
557
1
    return isCapabilityExpr(S, E->getSubExpr());
558
292
  else if (const auto *E = dyn_cast<UnaryOperator>(Ex)) {
559
38
    if (E->getOpcode() == UO_LNot || 
E->getOpcode() == UO_AddrOf12
||
560
38
        
E->getOpcode() == UO_Deref3
)
561
38
      return isCapabilityExpr(S, E->getSubExpr());
562
0
    return false;
563
254
  } else if (const auto *E = dyn_cast<BinaryOperator>(Ex)) {
564
5
    if (E->getOpcode() == BO_LAnd || 
E->getOpcode() == BO_LOr2
)
565
5
      return isCapabilityExpr(S, E->getLHS()) &&
566
5
             isCapabilityExpr(S, E->getRHS());
567
0
    return false;
568
5
  }
569
570
249
  return typeHasCapability(S, Ex->getType());
571
343
}
572
573
/// Checks that all attribute arguments, starting from Sidx, resolve to
574
/// a capability object.
575
/// \param Sidx The attribute argument index to start checking with.
576
/// \param ParamIdxOk Whether an argument can be indexing into a function
577
/// parameter list.
578
static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D,
579
                                           const ParsedAttr &AL,
580
                                           SmallVectorImpl<Expr *> &Args,
581
                                           unsigned Sidx = 0,
582
3.07k
                                           bool ParamIdxOk = false) {
583
3.07k
  if (Sidx == AL.getNumArgs()) {
584
    // If we don't have any capability arguments, the attribute implicitly
585
    // refers to 'this'. So we need to make sure that 'this' exists, i.e. we're
586
    // a non-static method, and that the class is a (scoped) capability.
587
421
    const auto *MD = dyn_cast<const CXXMethodDecl>(D);
588
421
    if (MD && 
!MD->isStatic()376
) {
589
376
      const CXXRecordDecl *RD = MD->getParent();
590
      // FIXME -- need to check this again on template instantiation
591
376
      if (!checkRecordDeclForAttr<CapabilityAttr>(RD) &&
592
376
          
!checkRecordDeclForAttr<ScopedLockableAttr>(RD)170
)
593
28
        S.Diag(AL.getLoc(),
594
28
               diag::warn_thread_attribute_not_on_capability_member)
595
28
            << AL << MD->getParent();
596
376
    } else {
597
45
      S.Diag(AL.getLoc(), diag::warn_thread_attribute_not_on_non_static_member)
598
45
          << AL;
599
45
    }
600
421
  }
601
602
5.97k
  for (unsigned Idx = Sidx; Idx < AL.getNumArgs(); 
++Idx2.90k
) {
603
2.90k
    Expr *ArgExp = AL.getArgAsExpr(Idx);
604
605
2.90k
    if (ArgExp->isTypeDependent()) {
606
      // FIXME -- need to check this again on template instantiation
607
54
      Args.push_back(ArgExp);
608
54
      continue;
609
54
    }
610
611
2.84k
    if (const auto *StrLit = dyn_cast<StringLiteral>(ArgExp)) {
612
104
      if (StrLit->getLength() == 0 ||
613
104
          
(70
StrLit->isAscii()70
&&
StrLit->getString() == StringRef("*")67
)) {
614
        // Pass empty strings to the analyzer without warnings.
615
        // Treat "*" as the universal lock.
616
62
        Args.push_back(ArgExp);
617
62
        continue;
618
62
      }
619
620
      // We allow constant strings to be used as a placeholder for expressions
621
      // that are not valid C++ syntax, but warn that they are ignored.
622
42
      S.Diag(AL.getLoc(), diag::warn_thread_attribute_ignored) << AL;
623
42
      Args.push_back(ArgExp);
624
42
      continue;
625
104
    }
626
627
2.74k
    QualType ArgTy = ArgExp->getType();
628
629
    // A pointer to member expression of the form  &MyClass::mu is treated
630
    // specially -- we need to look at the type of the member.
631
2.74k
    if (const auto *UOp = dyn_cast<UnaryOperator>(ArgExp))
632
140
      if (UOp->getOpcode() == UO_AddrOf)
633
76
        if (const auto *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr()))
634
76
          if (DRE->getDecl()->isCXXInstanceMember())
635
37
            ArgTy = DRE->getDecl()->getType();
636
637
    // First see if we can just cast to record type, or pointer to record type.
638
2.74k
    const RecordType *RT = getRecordType(ArgTy);
639
640
    // Now check if we index into a record type function param.
641
2.74k
    if(!RT && 
ParamIdxOk290
) {
642
129
      const auto *FD = dyn_cast<FunctionDecl>(D);
643
129
      const auto *IL = dyn_cast<IntegerLiteral>(ArgExp);
644
129
      if(FD && IL) {
645
63
        unsigned int NumParams = FD->getNumParams();
646
63
        llvm::APInt ArgValue = IL->getValue();
647
63
        uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
648
63
        uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
649
63
        if (!ArgValue.isStrictlyPositive() || 
ParamIdxFromOne > NumParams36
) {
650
36
          S.Diag(AL.getLoc(),
651
36
                 diag::err_attribute_argument_out_of_bounds_extra_info)
652
36
              << AL << Idx + 1 << NumParams;
653
36
          continue;
654
36
        }
655
27
        ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
656
27
      }
657
129
    }
658
659
    // If the type does not have a capability, see if the components of the
660
    // expression have capabilities. This allows for writing C code where the
661
    // capability may be on the type, and the expression is a capability
662
    // boolean logic expression. Eg) requires_capability(A || B && !C)
663
2.70k
    if (!typeHasCapability(S, ArgTy) && 
!isCapabilityExpr(S, ArgExp)244
)
664
217
      S.Diag(AL.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
665
217
          << AL << ArgTy;
666
667
2.70k
    Args.push_back(ArgExp);
668
2.70k
  }
669
3.07k
}
670
671
//===----------------------------------------------------------------------===//
672
// Attribute Implementations
673
//===----------------------------------------------------------------------===//
674
675
25
static void handlePtGuardedVarAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
676
25
  if (!threadSafetyCheckIsPointer(S, D, AL))
677
10
    return;
678
679
15
  D->addAttr(::new (S.Context) PtGuardedVarAttr(S.Context, AL));
680
15
}
681
682
static bool checkGuardedByAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
683
690
                                     Expr *&Arg) {
684
690
  SmallVector<Expr *, 1> Args;
685
  // check that all arguments are lockable objects
686
690
  checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
687
690
  unsigned Size = Args.size();
688
690
  if (Size != 1)
689
0
    return false;
690
691
690
  Arg = Args[0];
692
693
690
  return true;
694
690
}
695
696
554
static void handleGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
697
554
  Expr *Arg = nullptr;
698
554
  if (!checkGuardedByAttrCommon(S, D, AL, Arg))
699
0
    return;
700
701
554
  D->addAttr(::new (S.Context) GuardedByAttr(S.Context, AL, Arg));
702
554
}
703
704
136
static void handlePtGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
705
136
  Expr *Arg = nullptr;
706
136
  if (!checkGuardedByAttrCommon(S, D, AL, Arg))
707
0
    return;
708
709
136
  if (!threadSafetyCheckIsPointer(S, D, AL))
710
7
    return;
711
712
129
  D->addAttr(::new (S.Context) PtGuardedByAttr(S.Context, AL, Arg));
713
129
}
714
715
static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
716
254
                                        SmallVectorImpl<Expr *> &Args) {
717
254
  if (!AL.checkAtLeastNumArgs(S, 1))
718
12
    return false;
719
720
  // Check that this attribute only applies to lockable types.
721
242
  QualType QT = cast<ValueDecl>(D)->getType();
722
242
  if (!QT->isDependentType() && !typeHasCapability(S, QT)) {
723
6
    S.Diag(AL.getLoc(), diag::warn_thread_attribute_decl_not_lockable) << AL;
724
6
    return false;
725
6
  }
726
727
  // Check that all arguments are lockable objects.
728
236
  checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
729
236
  if (Args.empty())
730
0
    return false;
731
732
236
  return true;
733
236
}
734
735
147
static void handleAcquiredAfterAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
736
147
  SmallVector<Expr *, 1> Args;
737
147
  if (!checkAcquireOrderAttrCommon(S, D, AL, Args))
738
9
    return;
739
740
138
  Expr **StartArg = &Args[0];
741
138
  D->addAttr(::new (S.Context)
742
138
                 AcquiredAfterAttr(S.Context, AL, StartArg, Args.size()));
743
138
}
744
745
107
static void handleAcquiredBeforeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
746
107
  SmallVector<Expr *, 1> Args;
747
107
  if (!checkAcquireOrderAttrCommon(S, D, AL, Args))
748
9
    return;
749
750
98
  Expr **StartArg = &Args[0];
751
98
  D->addAttr(::new (S.Context)
752
98
                 AcquiredBeforeAttr(S.Context, AL, StartArg, Args.size()));
753
98
}
754
755
static bool checkLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
756
567
                                   SmallVectorImpl<Expr *> &Args) {
757
  // zero or more arguments ok
758
  // check that all arguments are lockable objects
759
567
  checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 0, /*ParamIdxOk=*/true);
760
761
567
  return true;
762
567
}
763
764
17
static void handleAssertSharedLockAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
765
17
  SmallVector<Expr *, 1> Args;
766
17
  if (!checkLockFunAttrCommon(S, D, AL, Args))
767
0
    return;
768
769
17
  unsigned Size = Args.size();
770
17
  Expr **StartArg = Size == 0 ? 
nullptr7
:
&Args[0]10
;
771
17
  D->addAttr(::new (S.Context)
772
17
                 AssertSharedLockAttr(S.Context, AL, StartArg, Size));
773
17
}
774
775
static void handleAssertExclusiveLockAttr(Sema &S, Decl *D,
776
19
                                          const ParsedAttr &AL) {
777
19
  SmallVector<Expr *, 1> Args;
778
19
  if (!checkLockFunAttrCommon(S, D, AL, Args))
779
0
    return;
780
781
19
  unsigned Size = Args.size();
782
19
  Expr **StartArg = Size == 0 ? 
nullptr7
:
&Args[0]12
;
783
19
  D->addAttr(::new (S.Context)
784
19
                 AssertExclusiveLockAttr(S.Context, AL, StartArg, Size));
785
19
}
786
787
/// Checks to be sure that the given parameter number is in bounds, and
788
/// is an integral type. Will emit appropriate diagnostics if this returns
789
/// false.
790
///
791
/// AttrArgNo is used to actually retrieve the argument, so it's base-0.
792
template <typename AttrInfo>
793
static bool checkParamIsIntegerType(Sema &S, const Decl *D, const AttrInfo &AI,
794
5.83k
                                    unsigned AttrArgNo) {
795
5.83k
  assert(AI.isArgExpr(AttrArgNo) && "Expected expression argument");
796
0
  Expr *AttrArg = AI.getArgAsExpr(AttrArgNo);
797
5.83k
  ParamIdx Idx;
798
5.83k
  if (!checkFunctionOrMethodParameterIndex(S, D, AI, AttrArgNo + 1, AttrArg,
799
5.83k
                                           Idx))
800
6
    return false;
801
802
5.83k
  QualType ParamTy = getFunctionOrMethodParamType(D, Idx.getASTIndex());
803
5.83k
  if (!ParamTy->isIntegerType() && 
!ParamTy->isCharType()1
) {
804
1
    SourceLocation SrcLoc = AttrArg->getBeginLoc();
805
1
    S.Diag(SrcLoc, diag::err_attribute_integers_only)
806
1
        << AI << getFunctionOrMethodParamRange(D, Idx.getASTIndex());
807
1
    return false;
808
1
  }
809
5.83k
  return true;
810
5.83k
}
811
812
4.89k
static void handleAllocSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
813
4.89k
  if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 2))
814
0
    return;
815
816
4.89k
  assert(isFunctionOrMethod(D) && hasFunctionProto(D));
817
818
0
  QualType RetTy = getFunctionOrMethodResultType(D);
819
4.89k
  if (!RetTy->isPointerType()) {
820
1
    S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only) << AL;
821
1
    return;
822
1
  }
823
824
4.89k
  const Expr *SizeExpr = AL.getArgAsExpr(0);
825
4.89k
  int SizeArgNoVal;
826
  // Parameter indices are 1-indexed, hence Index=1
827
4.89k
  if (!checkPositiveIntArgument(S, AL, SizeExpr, SizeArgNoVal, /*Idx=*/1))
828
2
    return;
829
4.89k
  if (!checkParamIsIntegerType(S, D, AL, /*AttrArgNo=*/0))
830
5
    return;
831
4.89k
  ParamIdx SizeArgNo(SizeArgNoVal, D);
832
833
4.89k
  ParamIdx NumberArgNo;
834
4.89k
  if (AL.getNumArgs() == 2) {
835
945
    const Expr *NumberExpr = AL.getArgAsExpr(1);
836
945
    int Val;
837
    // Parameter indices are 1-based, hence Index=2
838
945
    if (!checkPositiveIntArgument(S, AL, NumberExpr, Val, /*Idx=*/2))
839
1
      return;
840
944
    if (!checkParamIsIntegerType(S, D, AL, /*AttrArgNo=*/1))
841
2
      return;
842
942
    NumberArgNo = ParamIdx(Val, D);
843
942
  }
844
845
4.88k
  D->addAttr(::new (S.Context)
846
4.88k
                 AllocSizeAttr(S.Context, AL, SizeArgNo, NumberArgNo));
847
4.88k
}
848
849
static bool checkTryLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
850
188
                                      SmallVectorImpl<Expr *> &Args) {
851
188
  if (!AL.checkAtLeastNumArgs(S, 1))
852
0
    return false;
853
854
188
  if (!isIntOrBool(AL.getArgAsExpr(0))) {
855
18
    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
856
18
        << AL << 1 << AANT_ArgumentIntOrBool;
857
18
    return false;
858
18
  }
859
860
  // check that all arguments are lockable objects
861
170
  checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 1);
862
863
170
  return true;
864
188
}
865
866
static void handleSharedTrylockFunctionAttr(Sema &S, Decl *D,
867
74
                                            const ParsedAttr &AL) {
868
74
  SmallVector<Expr*, 2> Args;
869
74
  if (!checkTryLockFunAttrCommon(S, D, AL, Args))
870
9
    return;
871
872
65
  D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(
873
65
      S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));
874
65
}
875
876
static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D,
877
82
                                               const ParsedAttr &AL) {
878
82
  SmallVector<Expr*, 2> Args;
879
82
  if (!checkTryLockFunAttrCommon(S, D, AL, Args))
880
9
    return;
881
882
73
  D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(
883
73
      S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));
884
73
}
885
886
84
static void handleLockReturnedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
887
  // check that the argument is lockable object
888
84
  SmallVector<Expr*, 1> Args;
889
84
  checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
890
84
  unsigned Size = Args.size();
891
84
  if (Size == 0)
892
0
    return;
893
894
84
  D->addAttr(::new (S.Context) LockReturnedAttr(S.Context, AL, Args[0]));
895
84
}
896
897
146
static void handleLocksExcludedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
898
146
  if (!AL.checkAtLeastNumArgs(S, 1))
899
3
    return;
900
901
  // check that all arguments are lockable objects
902
143
  SmallVector<Expr*, 1> Args;
903
143
  checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
904
143
  unsigned Size = Args.size();
905
143
  if (Size == 0)
906
0
    return;
907
143
  Expr **StartArg = &Args[0];
908
909
143
  D->addAttr(::new (S.Context)
910
143
                 LocksExcludedAttr(S.Context, AL, StartArg, Size));
911
143
}
912
913
static bool checkFunctionConditionAttr(Sema &S, Decl *D, const ParsedAttr &AL,
914
18.3k
                                       Expr *&Cond, StringRef &Msg) {
915
18.3k
  Cond = AL.getArgAsExpr(0);
916
18.3k
  if (!Cond->isTypeDependent()) {
917
18.2k
    ExprResult Converted = S.PerformContextuallyConvertToBool(Cond);
918
18.2k
    if (Converted.isInvalid())
919
0
      return false;
920
18.2k
    Cond = Converted.get();
921
18.2k
  }
922
923
18.3k
  if (!S.checkStringLiteralArgumentAttr(AL, 1, Msg))
924
2
    return false;
925
926
18.3k
  if (Msg.empty())
927
10.2k
    Msg = "<no message provided>";
928
929
18.3k
  SmallVector<PartialDiagnosticAt, 8> Diags;
930
18.3k
  if (isa<FunctionDecl>(D) && 
!Cond->isValueDependent()18.3k
&&
931
18.3k
      !Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(D),
932
18.2k
                                                Diags)) {
933
3
    S.Diag(AL.getLoc(), diag::err_attr_cond_never_constant_expr) << AL;
934
3
    for (const PartialDiagnosticAt &PDiag : Diags)
935
3
      S.Diag(PDiag.first, PDiag.second);
936
3
    return false;
937
3
  }
938
18.3k
  return true;
939
18.3k
}
940
941
10.3k
static void handleEnableIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
942
10.3k
  S.Diag(AL.getLoc(), diag::ext_clang_enable_if);
943
944
10.3k
  Expr *Cond;
945
10.3k
  StringRef Msg;
946
10.3k
  if (checkFunctionConditionAttr(S, D, AL, Cond, Msg))
947
10.3k
    D->addAttr(::new (S.Context) EnableIfAttr(S.Context, AL, Cond, Msg));
948
10.3k
}
949
950
60
static void handleErrorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
951
60
  StringRef NewUserDiagnostic;
952
60
  if (!S.checkStringLiteralArgumentAttr(AL, 0, NewUserDiagnostic))
953
2
    return;
954
58
  if (ErrorAttr *EA = S.mergeErrorAttr(D, AL, NewUserDiagnostic))
955
56
    D->addAttr(EA);
956
58
}
957
958
namespace {
959
/// Determines if a given Expr references any of the given function's
960
/// ParmVarDecls, or the function's implicit `this` parameter (if applicable).
961
class ArgumentDependenceChecker
962
    : public RecursiveASTVisitor<ArgumentDependenceChecker> {
963
#ifndef NDEBUG
964
  const CXXRecordDecl *ClassType;
965
#endif
966
  llvm::SmallPtrSet<const ParmVarDecl *, 16> Parms;
967
  bool Result;
968
969
public:
970
7.96k
  ArgumentDependenceChecker(const FunctionDecl *FD) {
971
7.96k
#ifndef NDEBUG
972
7.96k
    if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
973
3.47k
      ClassType = MD->getParent();
974
4.49k
    else
975
4.49k
      ClassType = nullptr;
976
7.96k
#endif
977
7.96k
    Parms.insert(FD->param_begin(), FD->param_end());
978
7.96k
  }
979
980
7.96k
  bool referencesArgs(Expr *E) {
981
7.96k
    Result = false;
982
7.96k
    TraverseStmt(E);
983
7.96k
    return Result;
984
7.96k
  }
985
986
27
  bool VisitCXXThisExpr(CXXThisExpr *E) {
987
27
    assert(E->getType()->getPointeeCXXRecordDecl() == ClassType &&
988
27
           "`this` doesn't refer to the enclosing class?");
989
0
    Result = true;
990
27
    return false;
991
27
  }
992
993
7.97k
  bool VisitDeclRefExpr(DeclRefExpr *DRE) {
994
7.97k
    if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
995
7.85k
      if (Parms.count(PVD)) {
996
7.85k
        Result = true;
997
7.85k
        return false;
998
7.85k
      }
999
116
    return true;
1000
7.97k
  }
1001
};
1002
}
1003
1004
static void handleDiagnoseAsBuiltinAttr(Sema &S, Decl *D,
1005
29
                                        const ParsedAttr &AL) {
1006
29
  const auto *DeclFD = cast<FunctionDecl>(D);
1007
1008
29
  if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(DeclFD))
1009
2
    if (!MethodDecl->isStatic()) {
1010
1
      S.Diag(AL.getLoc(), diag::err_attribute_no_member_function) << AL;
1011
1
      return;
1012
1
    }
1013
1014
28
  auto DiagnoseType = [&](unsigned Index, AttributeArgumentNType T) {
1015
7
    SourceLocation Loc = [&]() {
1016
7
      auto Union = AL.getArg(Index - 1);
1017
7
      if (Union.is<Expr *>())
1018
7
        return Union.get<Expr *>()->getBeginLoc();
1019
0
      return Union.get<IdentifierLoc *>()->Loc;
1020
7
    }();
1021
1022
7
    S.Diag(Loc, diag::err_attribute_argument_n_type) << AL << Index << T;
1023
7
  };
1024
1025
28
  FunctionDecl *AttrFD = [&]() -> FunctionDecl * {
1026
28
    if (!AL.isArgExpr(0))
1027
0
      return nullptr;
1028
28
    auto *F = dyn_cast_or_null<DeclRefExpr>(AL.getArgAsExpr(0));
1029
28
    if (!F)
1030
5
      return nullptr;
1031
23
    return dyn_cast_or_null<FunctionDecl>(F->getFoundDecl());
1032
28
  }();
1033
1034
28
  if (!AttrFD || 
!AttrFD->getBuiltinID(true)23
) {
1035
7
    DiagnoseType(1, AANT_ArgumentBuiltinFunction);
1036
7
    return;
1037
7
  }
1038
1039
21
  if (AttrFD->getNumParams() != AL.getNumArgs() - 1) {
1040
4
    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments_for)
1041
4
        << AL << AttrFD << AttrFD->getNumParams();
1042
4
    return;
1043
4
  }
1044
1045
17
  SmallVector<unsigned, 8> Indices;
1046
1047
48
  for (unsigned I = 1; I < AL.getNumArgs(); 
++I31
) {
1048
39
    if (!AL.isArgExpr(I)) {
1049
0
      DiagnoseType(I + 1, AANT_ArgumentIntegerConstant);
1050
0
      return;
1051
0
    }
1052
1053
39
    const Expr *IndexExpr = AL.getArgAsExpr(I);
1054
39
    uint32_t Index;
1055
1056
39
    if (!checkUInt32Argument(S, AL, IndexExpr, Index, I + 1, false))
1057
2
      return;
1058
1059
37
    if (Index > DeclFD->getNumParams()) {
1060
2
      S.Diag(AL.getLoc(), diag::err_attribute_bounds_for_function)
1061
2
          << AL << Index << DeclFD << DeclFD->getNumParams();
1062
2
      return;
1063
2
    }
1064
1065
35
    QualType T1 = AttrFD->getParamDecl(I - 1)->getType();
1066
35
    QualType T2 = DeclFD->getParamDecl(Index - 1)->getType();
1067
1068
35
    if (T1.getCanonicalType().getUnqualifiedType() !=
1069
35
        T2.getCanonicalType().getUnqualifiedType()) {
1070
4
      S.Diag(IndexExpr->getBeginLoc(), diag::err_attribute_parameter_types)
1071
4
          << AL << Index << DeclFD << T2 << I << AttrFD << T1;
1072
4
      return;
1073
4
    }
1074
1075
31
    Indices.push_back(Index - 1);
1076
31
  }
1077
1078
9
  D->addAttr(::new (S.Context) DiagnoseAsBuiltinAttr(
1079
9
      S.Context, AL, AttrFD, Indices.data(), Indices.size()));
1080
9
}
1081
1082
7.97k
static void handleDiagnoseIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1083
7.97k
  S.Diag(AL.getLoc(), diag::ext_clang_diagnose_if);
1084
1085
7.97k
  Expr *Cond;
1086
7.97k
  StringRef Msg;
1087
7.97k
  if (!checkFunctionConditionAttr(S, D, AL, Cond, Msg))
1088
3
    return;
1089
1090
7.97k
  StringRef DiagTypeStr;
1091
7.97k
  if (!S.checkStringLiteralArgumentAttr(AL, 2, DiagTypeStr))
1092
0
    return;
1093
1094
7.97k
  DiagnoseIfAttr::DiagnosticType DiagType;
1095
7.97k
  if (!DiagnoseIfAttr::ConvertStrToDiagnosticType(DiagTypeStr, DiagType)) {
1096
3
    S.Diag(AL.getArgAsExpr(2)->getBeginLoc(),
1097
3
           diag::err_diagnose_if_invalid_diagnostic_type);
1098
3
    return;
1099
3
  }
1100
1101
7.97k
  bool ArgDependent = false;
1102
7.97k
  if (const auto *FD = dyn_cast<FunctionDecl>(D))
1103
7.96k
    ArgDependent = ArgumentDependenceChecker(FD).referencesArgs(Cond);
1104
7.97k
  D->addAttr(::new (S.Context) DiagnoseIfAttr(
1105
7.97k
      S.Context, AL, Cond, Msg, DiagType, ArgDependent, cast<NamedDecl>(D)));
1106
7.97k
}
1107
1108
31
static void handleNoBuiltinAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1109
31
  static constexpr const StringRef kWildcard = "*";
1110
1111
31
  llvm::SmallVector<StringRef, 16> Names;
1112
31
  bool HasWildcard = false;
1113
1114
41
  const auto AddBuiltinName = [&Names, &HasWildcard](StringRef Name) {
1115
41
    if (Name == kWildcard)
1116
12
      HasWildcard = true;
1117
41
    Names.push_back(Name);
1118
41
  };
1119
1120
  // Add previously defined attributes.
1121
31
  if (const auto *NBA = D->getAttr<NoBuiltinAttr>())
1122
8
    for (StringRef BuiltinName : NBA->builtinNames())
1123
8
      AddBuiltinName(BuiltinName);
1124
1125
  // Add current attributes.
1126
31
  if (AL.getNumArgs() == 0)
1127
10
    AddBuiltinName(kWildcard);
1128
21
  else
1129
45
    
for (unsigned I = 0, E = AL.getNumArgs(); 21
I != E;
++I24
) {
1130
24
      StringRef BuiltinName;
1131
24
      SourceLocation LiteralLoc;
1132
24
      if (!S.checkStringLiteralArgumentAttr(AL, I, BuiltinName, &LiteralLoc))
1133
0
        return;
1134
1135
24
      if (Builtin::Context::isBuiltinFunc(BuiltinName))
1136
23
        AddBuiltinName(BuiltinName);
1137
1
      else
1138
1
        S.Diag(LiteralLoc, diag::warn_attribute_no_builtin_invalid_builtin_name)
1139
1
            << BuiltinName << AL;
1140
24
    }
1141
1142
  // Repeating the same attribute is fine.
1143
31
  llvm::sort(Names);
1144
31
  Names.erase(std::unique(Names.begin(), Names.end()), Names.end());
1145
1146
  // Empty no_builtin must be on its own.
1147
31
  if (HasWildcard && 
Names.size() > 111
)
1148
1
    S.Diag(D->getLocation(),
1149
1
           diag::err_attribute_no_builtin_wildcard_or_builtin_name)
1150
1
        << AL;
1151
1152
31
  if (D->hasAttr<NoBuiltinAttr>())
1153
8
    D->dropAttr<NoBuiltinAttr>();
1154
31
  D->addAttr(::new (S.Context)
1155
31
                 NoBuiltinAttr(S.Context, AL, Names.data(), Names.size()));
1156
31
}
1157
1158
136
static void handlePassObjectSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1159
136
  if (D->hasAttr<PassObjectSizeAttr>()) {
1160
1
    S.Diag(D->getBeginLoc(), diag::err_attribute_only_once_per_parameter) << AL;
1161
1
    return;
1162
1
  }
1163
1164
135
  Expr *E = AL.getArgAsExpr(0);
1165
135
  uint32_t Type;
1166
135
  if (!checkUInt32Argument(S, AL, E, Type, /*Idx=*/1))
1167
2
    return;
1168
1169
  // pass_object_size's argument is passed in as the second argument of
1170
  // __builtin_object_size. So, it has the same constraints as that second
1171
  // argument; namely, it must be in the range [0, 3].
1172
133
  if (Type > 3) {
1173
2
    S.Diag(E->getBeginLoc(), diag::err_attribute_argument_out_of_range)
1174
2
        << AL << 0 << 3 << E->getSourceRange();
1175
2
    return;
1176
2
  }
1177
1178
  // pass_object_size is only supported on constant pointer parameters; as a
1179
  // kindness to users, we allow the parameter to be non-const for declarations.
1180
  // At this point, we have no clue if `D` belongs to a function declaration or
1181
  // definition, so we defer the constness check until later.
1182
131
  if (!cast<ParmVarDecl>(D)->getType()->isPointerType()) {
1183
3
    S.Diag(D->getBeginLoc(), diag::err_attribute_pointers_only) << AL << 1;
1184
3
    return;
1185
3
  }
1186
1187
128
  D->addAttr(::new (S.Context) PassObjectSizeAttr(S.Context, AL, (int)Type));
1188
128
}
1189
1190
7
static void handleConsumableAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1191
7
  ConsumableAttr::ConsumedState DefaultState;
1192
1193
7
  if (AL.isArgIdent(0)) {
1194
6
    IdentifierLoc *IL = AL.getArgAsIdent(0);
1195
6
    if (!ConsumableAttr::ConvertStrToConsumedState(IL->Ident->getName(),
1196
6
                                                   DefaultState)) {
1197
0
      S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL
1198
0
                                                               << IL->Ident;
1199
0
      return;
1200
0
    }
1201
6
  } else {
1202
1
    S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1203
1
        << AL << AANT_ArgumentIdentifier;
1204
1
    return;
1205
1
  }
1206
1207
6
  D->addAttr(::new (S.Context) ConsumableAttr(S.Context, AL, DefaultState));
1208
6
}
1209
1210
static bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD,
1211
31
                                    const ParsedAttr &AL) {
1212
31
  QualType ThisType = MD->getThisType()->getPointeeType();
1213
1214
31
  if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) {
1215
31
    if (!RD->hasAttr<ConsumableAttr>()) {
1216
3
      S.Diag(AL.getLoc(), diag::warn_attr_on_unconsumable_class) << RD;
1217
1218
3
      return false;
1219
3
    }
1220
31
  }
1221
1222
28
  return true;
1223
31
}
1224
1225
16
static void handleCallableWhenAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1226
16
  if (!AL.checkAtLeastNumArgs(S, 1))
1227
1
    return;
1228
1229
15
  if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL))
1230
1
    return;
1231
1232
14
  SmallVector<CallableWhenAttr::ConsumedState, 3> States;
1233
32
  for (unsigned ArgIndex = 0; ArgIndex < AL.getNumArgs(); 
++ArgIndex18
) {
1234
20
    CallableWhenAttr::ConsumedState CallableState;
1235
1236
20
    StringRef StateString;
1237
20
    SourceLocation Loc;
1238
20
    if (AL.isArgIdent(ArgIndex)) {
1239
1
      IdentifierLoc *Ident = AL.getArgAsIdent(ArgIndex);
1240
1
      StateString = Ident->Ident->getName();
1241
1
      Loc = Ident->Loc;
1242
19
    } else {
1243
19
      if (!S.checkStringLiteralArgumentAttr(AL, ArgIndex, StateString, &Loc))
1244
1
        return;
1245
19
    }
1246
1247
19
    if (!CallableWhenAttr::ConvertStrToConsumedState(StateString,
1248
19
                                                     CallableState)) {
1249
1
      S.Diag(Loc, diag::warn_attribute_type_not_supported) << AL << StateString;
1250
1
      return;
1251
1
    }
1252
1253
18
    States.push_back(CallableState);
1254
18
  }
1255
1256
12
  D->addAttr(::new (S.Context)
1257
12
                 CallableWhenAttr(S.Context, AL, States.data(), States.size()));
1258
12
}
1259
1260
7
static void handleParamTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1261
7
  ParamTypestateAttr::ConsumedState ParamState;
1262
1263
7
  if (AL.isArgIdent(0)) {
1264
7
    IdentifierLoc *Ident = AL.getArgAsIdent(0);
1265
7
    StringRef StateString = Ident->Ident->getName();
1266
1267
7
    if (!ParamTypestateAttr::ConvertStrToConsumedState(StateString,
1268
7
                                                       ParamState)) {
1269
0
      S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported)
1270
0
          << AL << StateString;
1271
0
      return;
1272
0
    }
1273
7
  } else {
1274
0
    S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1275
0
        << AL << AANT_ArgumentIdentifier;
1276
0
    return;
1277
0
  }
1278
1279
  // FIXME: This check is currently being done in the analysis.  It can be
1280
  //        enabled here only after the parser propagates attributes at
1281
  //        template specialization definition, not declaration.
1282
  //QualType ReturnType = cast<ParmVarDecl>(D)->getType();
1283
  //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1284
  //
1285
  //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1286
  //    S.Diag(AL.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1287
  //      ReturnType.getAsString();
1288
  //    return;
1289
  //}
1290
1291
7
  D->addAttr(::new (S.Context) ParamTypestateAttr(S.Context, AL, ParamState));
1292
7
}
1293
1294
15
static void handleReturnTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1295
15
  ReturnTypestateAttr::ConsumedState ReturnState;
1296
1297
15
  if (AL.isArgIdent(0)) {
1298
14
    IdentifierLoc *IL = AL.getArgAsIdent(0);
1299
14
    if (!ReturnTypestateAttr::ConvertStrToConsumedState(IL->Ident->getName(),
1300
14
                                                        ReturnState)) {
1301
1
      S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL
1302
1
                                                               << IL->Ident;
1303
1
      return;
1304
1
    }
1305
14
  } else {
1306
1
    S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1307
1
        << AL << AANT_ArgumentIdentifier;
1308
1
    return;
1309
1
  }
1310
1311
  // FIXME: This check is currently being done in the analysis.  It can be
1312
  //        enabled here only after the parser propagates attributes at
1313
  //        template specialization definition, not declaration.
1314
  //QualType ReturnType;
1315
  //
1316
  //if (const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D)) {
1317
  //  ReturnType = Param->getType();
1318
  //
1319
  //} else if (const CXXConstructorDecl *Constructor =
1320
  //             dyn_cast<CXXConstructorDecl>(D)) {
1321
  //  ReturnType = Constructor->getThisType()->getPointeeType();
1322
  //
1323
  //} else {
1324
  //
1325
  //  ReturnType = cast<FunctionDecl>(D)->getCallResultType();
1326
  //}
1327
  //
1328
  //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1329
  //
1330
  //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1331
  //    S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1332
  //      ReturnType.getAsString();
1333
  //    return;
1334
  //}
1335
1336
13
  D->addAttr(::new (S.Context) ReturnTypestateAttr(S.Context, AL, ReturnState));
1337
13
}
1338
1339
10
static void handleSetTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1340
10
  if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL))
1341
1
    return;
1342
1343
9
  SetTypestateAttr::ConsumedState NewState;
1344
9
  if (AL.isArgIdent(0)) {
1345
9
    IdentifierLoc *Ident = AL.getArgAsIdent(0);
1346
9
    StringRef Param = Ident->Ident->getName();
1347
9
    if (!SetTypestateAttr::ConvertStrToConsumedState(Param, NewState)) {
1348
0
      S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) << AL
1349
0
                                                                  << Param;
1350
0
      return;
1351
0
    }
1352
9
  } else {
1353
0
    S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1354
0
        << AL << AANT_ArgumentIdentifier;
1355
0
    return;
1356
0
  }
1357
1358
9
  D->addAttr(::new (S.Context) SetTypestateAttr(S.Context, AL, NewState));
1359
9
}
1360
1361
6
static void handleTestTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1362
6
  if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL))
1363
1
    return;
1364
1365
5
  TestTypestateAttr::ConsumedState TestState;
1366
5
  if (AL.isArgIdent(0)) {
1367
5
    IdentifierLoc *Ident = AL.getArgAsIdent(0);
1368
5
    StringRef Param = Ident->Ident->getName();
1369
5
    if (!TestTypestateAttr::ConvertStrToConsumedState(Param, TestState)) {
1370
0
      S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) << AL
1371
0
                                                                  << Param;
1372
0
      return;
1373
0
    }
1374
5
  } else {
1375
0
    S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1376
0
        << AL << AANT_ArgumentIdentifier;
1377
0
    return;
1378
0
  }
1379
1380
5
  D->addAttr(::new (S.Context) TestTypestateAttr(S.Context, AL, TestState));
1381
5
}
1382
1383
3.93k
static void handleExtVectorTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1384
  // Remember this typedef decl, we will need it later for diagnostics.
1385
3.93k
  S.ExtVectorDecls.push_back(cast<TypedefNameDecl>(D));
1386
3.93k
}
1387
1388
36.8k
static void handlePackedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1389
36.8k
  if (auto *TD = dyn_cast<TagDecl>(D))
1390
35.6k
    TD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
1391
1.21k
  else if (auto *FD = dyn_cast<FieldDecl>(D)) {
1392
1.20k
    bool BitfieldByteAligned = (!FD->getType()->isDependentType() &&
1393
1.20k
                                
!FD->getType()->isIncompleteType()1.19k
&&
1394
1.20k
                                
FD->isBitField()1.00k
&&
1395
1.20k
                                
S.Context.getTypeAlign(FD->getType()) <= 830
);
1396
1397
1.20k
    if (S.getASTContext().getTargetInfo().getTriple().isPS4()) {
1398
6
      if (BitfieldByteAligned)
1399
        // The PS4 target needs to maintain ABI backwards compatibility.
1400
1
        S.Diag(AL.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
1401
1
            << AL << FD->getType();
1402
5
      else
1403
5
        FD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
1404
1.19k
    } else {
1405
      // Report warning about changed offset in the newer compiler versions.
1406
1.19k
      if (BitfieldByteAligned)
1407
2
        S.Diag(AL.getLoc(), diag::warn_attribute_packed_for_bitfield);
1408
1409
1.19k
      FD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
1410
1.19k
    }
1411
1412
1.20k
  } else
1413
10
    S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
1414
36.8k
}
1415
1416
14.6k
static void handlePreferredName(Sema &S, Decl *D, const ParsedAttr &AL) {
1417
14.6k
  auto *RD = cast<CXXRecordDecl>(D);
1418
14.6k
  ClassTemplateDecl *CTD = RD->getDescribedClassTemplate();
1419
14.6k
  assert(CTD && "attribute does not appertain to this declaration");
1420
1421
0
  ParsedType PT = AL.getTypeArg();
1422
14.6k
  TypeSourceInfo *TSI = nullptr;
1423
14.6k
  QualType T = S.GetTypeFromParser(PT, &TSI);
1424
14.6k
  if (!TSI)
1425
0
    TSI = S.Context.getTrivialTypeSourceInfo(T, AL.getLoc());
1426
1427
14.6k
  if (!T.hasQualifiers() && 
T->isTypedefNameType()14.6k
) {
1428
    // Find the template name, if this type names a template specialization.
1429
14.5k
    const TemplateDecl *Template = nullptr;
1430
14.5k
    if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
1431
14.5k
            T->getAsCXXRecordDecl())) {
1432
14.5k
      Template = CTSD->getSpecializedTemplate();
1433
14.5k
    } else 
if (const auto *32
TST32
= T->getAs<TemplateSpecializationType>()) {
1434
8
      while (TST && TST->isTypeAlias())
1435
2
        TST = TST->getAliasedType()->getAs<TemplateSpecializationType>();
1436
6
      if (TST)
1437
6
        Template = TST->getTemplateName().getAsTemplateDecl();
1438
6
    }
1439
1440
14.5k
    if (Template && 
declaresSameEntity(Template, CTD)14.5k
) {
1441
14.5k
      D->addAttr(::new (S.Context) PreferredNameAttr(S.Context, AL, TSI));
1442
14.5k
      return;
1443
14.5k
    }
1444
14.5k
  }
1445
1446
34
  S.Diag(AL.getLoc(), diag::err_attribute_preferred_name_arg_invalid)
1447
34
      << T << CTD;
1448
34
  if (const auto *TT = T->getAs<TypedefType>())
1449
30
    S.Diag(TT->getDecl()->getLocation(), diag::note_entity_declared_at)
1450
30
        << TT->getDecl();
1451
34
}
1452
1453
134
static bool checkIBOutletCommon(Sema &S, Decl *D, const ParsedAttr &AL) {
1454
  // The IBOutlet/IBOutletCollection attributes only apply to instance
1455
  // variables or properties of Objective-C classes.  The outlet must also
1456
  // have an object reference type.
1457
134
  if (const auto *VD = dyn_cast<ObjCIvarDecl>(D)) {
1458
39
    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
1459
10
      S.Diag(AL.getLoc(), diag::warn_iboutlet_object_type)
1460
10
          << AL << VD->getType() << 0;
1461
10
      return false;
1462
10
    }
1463
39
  }
1464
95
  else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) {
1465
95
    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
1466
8
      S.Diag(AL.getLoc(), diag::warn_iboutlet_object_type)
1467
8
          << AL << PD->getType() << 1;
1468
8
      return false;
1469
8
    }
1470
95
  }
1471
0
  else {
1472
0
    S.Diag(AL.getLoc(), diag::warn_attribute_iboutlet) << AL;
1473
0
    return false;
1474
0
  }
1475
1476
116
  return true;
1477
134
}
1478
1479
99
static void handleIBOutlet(Sema &S, Decl *D, const ParsedAttr &AL) {
1480
99
  if (!checkIBOutletCommon(S, D, AL))
1481
14
    return;
1482
1483
85
  D->addAttr(::new (S.Context) IBOutletAttr(S.Context, AL));
1484
85
}
1485
1486
35
static void handleIBOutletCollection(Sema &S, Decl *D, const ParsedAttr &AL) {
1487
1488
  // The iboutletcollection attribute can have zero or one arguments.
1489
35
  if (AL.getNumArgs() > 1) {
1490
0
    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
1491
0
    return;
1492
0
  }
1493
1494
35
  if (!checkIBOutletCommon(S, D, AL))
1495
4
    return;
1496
1497
31
  ParsedType PT;
1498
1499
31
  if (AL.hasParsedType())
1500
23
    PT = AL.getTypeArg();
1501
8
  else {
1502
8
    PT = S.getTypeName(S.Context.Idents.get("NSObject"), AL.getLoc(),
1503
8
                       S.getScopeForContext(D->getDeclContext()->getParent()));
1504
8
    if (!PT) {
1505
0
      S.Diag(AL.getLoc(), diag::err_iboutletcollection_type) << "NSObject";
1506
0
      return;
1507
0
    }
1508
8
  }
1509
1510
31
  TypeSourceInfo *QTLoc = nullptr;
1511
31
  QualType QT = S.GetTypeFromParser(PT, &QTLoc);
1512
31
  if (!QTLoc)
1513
8
    QTLoc = S.Context.getTrivialTypeSourceInfo(QT, AL.getLoc());
1514
1515
  // Diagnose use of non-object type in iboutletcollection attribute.
1516
  // FIXME. Gnu attribute extension ignores use of builtin types in
1517
  // attributes. So, __attribute__((iboutletcollection(char))) will be
1518
  // treated as __attribute__((iboutletcollection())).
1519
31
  if (!QT->isObjCIdType() && 
!QT->isObjCObjectType()26
) {
1520
4
    S.Diag(AL.getLoc(),
1521
4
           QT->isBuiltinType() ? 
diag::err_iboutletcollection_builtintype2
1522
4
                               : 
diag::err_iboutletcollection_type2
) << QT;
1523
4
    return;
1524
4
  }
1525
1526
27
  D->addAttr(::new (S.Context) IBOutletCollectionAttr(S.Context, AL, QTLoc));
1527
27
}
1528
1529
79.8k
bool Sema::isValidPointerAttrType(QualType T, bool RefOkay) {
1530
79.8k
  if (RefOkay) {
1531
24.3k
    if (T->isReferenceType())
1532
20
      return true;
1533
55.5k
  } else {
1534
55.5k
    T = T.getNonReferenceType();
1535
55.5k
  }
1536
1537
  // The nonnull attribute, and other similar attributes, can be applied to a
1538
  // transparent union that contains a pointer type.
1539
79.8k
  if (const RecordType *UT = T->getAsUnionType()) {
1540
18
    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
1541
18
      RecordDecl *UD = UT->getDecl();
1542
23
      for (const auto *I : UD->fields()) {
1543
23
        QualType QT = I->getType();
1544
23
        if (QT->isAnyPointerType() || 
QT->isBlockPointerType()5
)
1545
18
          return true;
1546
23
      }
1547
18
    }
1548
18
  }
1549
1550
79.8k
  return T->isAnyPointerType() || 
T->isBlockPointerType()25.9k
;
1551
79.8k
}
1552
1553
static bool attrNonNullArgCheck(Sema &S, QualType T, const ParsedAttr &AL,
1554
                                SourceRange AttrParmRange,
1555
                                SourceRange TypeRange,
1556
54.7k
                                bool isReturnValue = false) {
1557
54.7k
  if (!S.isValidPointerAttrType(T)) {
1558
17
    if (isReturnValue)
1559
6
      S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only)
1560
6
          << AL << AttrParmRange << TypeRange;
1561
11
    else
1562
11
      S.Diag(AL.getLoc(), diag::warn_attribute_pointers_only)
1563
11
          << AL << AttrParmRange << TypeRange << 0;
1564
17
    return false;
1565
17
  }
1566
54.6k
  return true;
1567
54.7k
}
1568
1569
71.4k
static void handleNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1570
71.4k
  SmallVector<ParamIdx, 8> NonNullArgs;
1571
126k
  for (unsigned I = 0; I < AL.getNumArgs(); 
++I54.6k
) {
1572
54.6k
    Expr *Ex = AL.getArgAsExpr(I);
1573
54.6k
    ParamIdx Idx;
1574
54.6k
    if (!checkFunctionOrMethodParameterIndex(S, D, AL, I + 1, Ex, Idx))
1575
5
      return;
1576
1577
    // Is the function argument a pointer type?
1578
54.6k
    if (Idx.getASTIndex() < getFunctionOrMethodNumParams(D) &&
1579
54.6k
        !attrNonNullArgCheck(
1580
54.6k
            S, getFunctionOrMethodParamType(D, Idx.getASTIndex()), AL,
1581
54.6k
            Ex->getSourceRange(),
1582
54.6k
            getFunctionOrMethodParamRange(D, Idx.getASTIndex())))
1583
7
      continue;
1584
1585
54.6k
    NonNullArgs.push_back(Idx);
1586
54.6k
  }
1587
1588
  // If no arguments were specified to __attribute__((nonnull)) then all pointer
1589
  // arguments have a nonnull attribute; warn if there aren't any. Skip this
1590
  // check if the attribute came from a macro expansion or a template
1591
  // instantiation.
1592
71.4k
  if (NonNullArgs.empty() && 
AL.getLoc().isFileID()19.1k
&&
1593
71.4k
      
!S.inTemplateInstantiation()65
) {
1594
65
    bool AnyPointers = isFunctionOrMethodVariadic(D);
1595
65
    for (unsigned I = 0, E = getFunctionOrMethodNumParams(D);
1596
120
         I != E && 
!AnyPointers82
;
++I55
) {
1597
55
      QualType T = getFunctionOrMethodParamType(D, I);
1598
55
      if (T->isDependentType() || 
S.isValidPointerAttrType(T)53
)
1599
47
        AnyPointers = true;
1600
55
    }
1601
1602
65
    if (!AnyPointers)
1603
6
      S.Diag(AL.getLoc(), diag::warn_attribute_nonnull_no_pointers);
1604
65
  }
1605
1606
71.4k
  ParamIdx *Start = NonNullArgs.data();
1607
71.4k
  unsigned Size = NonNullArgs.size();
1608
71.4k
  llvm::array_pod_sort(Start, Start + Size);
1609
71.4k
  D->addAttr(::new (S.Context) NonNullAttr(S.Context, AL, Start, Size));
1610
71.4k
}
1611
1612
static void handleNonNullAttrParameter(Sema &S, ParmVarDecl *D,
1613
47
                                       const ParsedAttr &AL) {
1614
47
  if (AL.getNumArgs() > 0) {
1615
6
    if (D->getFunctionType()) {
1616
3
      handleNonNullAttr(S, D, AL);
1617
3
    } else {
1618
3
      S.Diag(AL.getLoc(), diag::warn_attribute_nonnull_parm_no_args)
1619
3
        << D->getSourceRange();
1620
3
    }
1621
6
    return;
1622
6
  }
1623
1624
  // Is the argument a pointer type?
1625
41
  if (!attrNonNullArgCheck(S, D->getType(), AL, SourceRange(),
1626
41
                           D->getSourceRange()))
1627
4
    return;
1628
1629
37
  D->addAttr(::new (S.Context) NonNullAttr(S.Context, AL, nullptr, 0));
1630
37
}
1631
1632
30
static void handleReturnsNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1633
30
  QualType ResultType = getFunctionOrMethodResultType(D);
1634
30
  SourceRange SR = getFunctionOrMethodResultSourceRange(D);
1635
30
  if (!attrNonNullArgCheck(S, ResultType, AL, SourceRange(), SR,
1636
30
                           /* isReturnValue */ true))
1637
6
    return;
1638
1639
24
  D->addAttr(::new (S.Context) ReturnsNonNullAttr(S.Context, AL));
1640
24
}
1641
1642
24.2k
static void handleNoEscapeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1643
24.2k
  if (D->isInvalidDecl())
1644
0
    return;
1645
1646
  // noescape only applies to pointer types.
1647
24.2k
  QualType T = cast<ParmVarDecl>(D)->getType();
1648
24.2k
  if (!S.isValidPointerAttrType(T, /* RefOkay */ true)) {
1649
8
    S.Diag(AL.getLoc(), diag::warn_attribute_pointers_only)
1650
8
        << AL << AL.getRange() << 0;
1651
8
    return;
1652
8
  }
1653
1654
24.2k
  D->addAttr(::new (S.Context) NoEscapeAttr(S.Context, AL));
1655
24.2k
}
1656
1657
35
static void handleAssumeAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1658
35
  Expr *E = AL.getArgAsExpr(0),
1659
35
       *OE = AL.getNumArgs() > 1 ? 
AL.getArgAsExpr(1)10
:
nullptr25
;
1660
35
  S.AddAssumeAlignedAttr(D, AL, E, OE);
1661
35
}
1662
1663
36
static void handleAllocAlignAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1664
36
  S.AddAllocAlignAttr(D, AL, AL.getArgAsExpr(0));
1665
36
}
1666
1667
void Sema::AddAssumeAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
1668
43
                                Expr *OE) {
1669
43
  QualType ResultType = getFunctionOrMethodResultType(D);
1670
43
  SourceRange SR = getFunctionOrMethodResultSourceRange(D);
1671
1672
43
  AssumeAlignedAttr TmpAttr(Context, CI, E, OE);
1673
43
  SourceLocation AttrLoc = TmpAttr.getLocation();
1674
1675
43
  if (!isValidPointerAttrType(ResultType, /* RefOkay */ true)) {
1676
5
    Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)
1677
5
        << &TmpAttr << TmpAttr.getRange() << SR;
1678
5
    return;
1679
5
  }
1680
1681
38
  if (!E->isValueDependent()) {
1682
34
    Optional<llvm::APSInt> I = llvm::APSInt(64);
1683
34
    if (!(I = E->getIntegerConstantExpr(Context))) {
1684
0
      if (OE)
1685
0
        Diag(AttrLoc, diag::err_attribute_argument_n_type)
1686
0
          << &TmpAttr << 1 << AANT_ArgumentIntegerConstant
1687
0
          << E->getSourceRange();
1688
0
      else
1689
0
        Diag(AttrLoc, diag::err_attribute_argument_type)
1690
0
          << &TmpAttr << AANT_ArgumentIntegerConstant
1691
0
          << E->getSourceRange();
1692
0
      return;
1693
0
    }
1694
1695
34
    if (!I->isPowerOf2()) {
1696
6
      Diag(AttrLoc, diag::err_alignment_not_power_of_two)
1697
6
        << E->getSourceRange();
1698
6
      return;
1699
6
    }
1700
1701
28
    if (*I > Sema::MaximumAlignment)
1702
2
      Diag(CI.getLoc(), diag::warn_assume_aligned_too_great)
1703
2
          << CI.getRange() << Sema::MaximumAlignment;
1704
28
  }
1705
1706
32
  if (OE && 
!OE->isValueDependent()11
&&
!OE->isIntegerConstantExpr(Context)9
) {
1707
0
    Diag(AttrLoc, diag::err_attribute_argument_n_type)
1708
0
        << &TmpAttr << 2 << AANT_ArgumentIntegerConstant
1709
0
        << OE->getSourceRange();
1710
0
    return;
1711
0
  }
1712
1713
32
  D->addAttr(::new (Context) AssumeAlignedAttr(Context, CI, E, OE));
1714
32
}
1715
1716
void Sema::AddAllocAlignAttr(Decl *D, const AttributeCommonInfo &CI,
1717
44
                             Expr *ParamExpr) {
1718
44
  QualType ResultType = getFunctionOrMethodResultType(D);
1719
1720
44
  AllocAlignAttr TmpAttr(Context, CI, ParamIdx());
1721
44
  SourceLocation AttrLoc = CI.getLoc();
1722
1723
44
  if (!ResultType->isDependentType() &&
1724
44
      
!isValidPointerAttrType(ResultType, /* RefOkay */ true)42
) {
1725
2
    Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)
1726
2
        << &TmpAttr << CI.getRange() << getFunctionOrMethodResultSourceRange(D);
1727
2
    return;
1728
2
  }
1729
1730
42
  ParamIdx Idx;
1731
42
  const auto *FuncDecl = cast<FunctionDecl>(D);
1732
42
  if (!checkFunctionOrMethodParameterIndex(*this, FuncDecl, TmpAttr,
1733
42
                                           /*AttrArgNum=*/1, ParamExpr, Idx))
1734
5
    return;
1735
1736
37
  QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex());
1737
37
  if (!Ty->isDependentType() && 
!Ty->isIntegralType(Context)35
&&
1738
37
      
!Ty->isAlignValT()9
) {
1739
3
    Diag(ParamExpr->getBeginLoc(), diag::err_attribute_integers_only)
1740
3
        << &TmpAttr
1741
3
        << FuncDecl->getParamDecl(Idx.getASTIndex())->getSourceRange();
1742
3
    return;
1743
3
  }
1744
1745
34
  D->addAttr(::new (Context) AllocAlignAttr(Context, CI, Idx));
1746
34
}
1747
1748
/// Check if \p AssumptionStr is a known assumption and warn if not.
1749
static void checkAssumptionAttr(Sema &S, SourceLocation Loc,
1750
87
                                StringRef AssumptionStr) {
1751
87
  if (llvm::KnownAssumptionStrings.count(AssumptionStr))
1752
7
    return;
1753
1754
80
  unsigned BestEditDistance = 3;
1755
80
  StringRef Suggestion;
1756
320
  for (const auto &KnownAssumptionIt : llvm::KnownAssumptionStrings) {
1757
320
    unsigned EditDistance =
1758
320
        AssumptionStr.edit_distance(KnownAssumptionIt.getKey());
1759
320
    if (EditDistance < BestEditDistance) {
1760
3
      Suggestion = KnownAssumptionIt.getKey();
1761
3
      BestEditDistance = EditDistance;
1762
3
    }
1763
320
  }
1764
1765
80
  if (!Suggestion.empty())
1766
3
    S.Diag(Loc, diag::warn_assume_attribute_string_unknown_suggested)
1767
3
        << AssumptionStr << Suggestion;
1768
77
  else
1769
77
    S.Diag(Loc, diag::warn_assume_attribute_string_unknown) << AssumptionStr;
1770
80
}
1771
1772
88
static void handleAssumumptionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1773
  // Handle the case where the attribute has a text message.
1774
88
  StringRef Str;
1775
88
  SourceLocation AttrStrLoc;
1776
88
  if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &AttrStrLoc))
1777
1
    return;
1778
1779
87
  checkAssumptionAttr(S, AttrStrLoc, Str);
1780
1781
87
  D->addAttr(::new (S.Context) AssumptionAttr(S.Context, AL, Str));
1782
87
}
1783
1784
/// Normalize the attribute, __foo__ becomes foo.
1785
/// Returns true if normalization was applied.
1786
35.8k
static bool normalizeName(StringRef &AttrName) {
1787
35.8k
  if (AttrName.size() > 4 && 
AttrName.startswith("__")35.5k
&&
1788
35.8k
      
AttrName.endswith("__")33.3k
) {
1789
33.3k
    AttrName = AttrName.drop_front(2).drop_back(2);
1790
33.3k
    return true;
1791
33.3k
  }
1792
2.48k
  return false;
1793
35.8k
}
1794
1795
52
static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1796
  // This attribute must be applied to a function declaration. The first
1797
  // argument to the attribute must be an identifier, the name of the resource,
1798
  // for example: malloc. The following arguments must be argument indexes, the
1799
  // arguments must be of integer type for Returns, otherwise of pointer type.
1800
  // The difference between Holds and Takes is that a pointer may still be used
1801
  // after being held. free() should be __attribute((ownership_takes)), whereas
1802
  // a list append function may well be __attribute((ownership_holds)).
1803
1804
52
  if (!AL.isArgIdent(0)) {
1805
1
    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
1806
1
        << AL << 1 << AANT_ArgumentIdentifier;
1807
1
    return;
1808
1
  }
1809
1810
  // Figure out our Kind.
1811
51
  OwnershipAttr::OwnershipKind K =
1812
51
      OwnershipAttr(S.Context, AL, nullptr, nullptr, 0).getOwnKind();
1813
1814
  // Check arguments.
1815
51
  switch (K) {
1816
12
  case OwnershipAttr::Takes:
1817
32
  case OwnershipAttr::Holds:
1818
32
    if (AL.getNumArgs() < 2) {
1819
2
      S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) << AL << 2;
1820
2
      return;
1821
2
    }
1822
30
    break;
1823
30
  case OwnershipAttr::Returns:
1824
19
    if (AL.getNumArgs() > 2) {
1825
1
      S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 1;
1826
1
      return;
1827
1
    }
1828
18
    break;
1829
51
  }
1830
1831
48
  IdentifierInfo *Module = AL.getArgAsIdent(0)->Ident;
1832
1833
48
  StringRef ModuleName = Module->getName();
1834
48
  if (normalizeName(ModuleName)) {
1835
0
    Module = &S.PP.getIdentifierTable().get(ModuleName);
1836
0
  }
1837
1838
48
  SmallVector<ParamIdx, 8> OwnershipArgs;
1839
91
  for (unsigned i = 1; i < AL.getNumArgs(); 
++i43
) {
1840
52
    Expr *Ex = AL.getArgAsExpr(i);
1841
52
    ParamIdx Idx;
1842
52
    if (!checkFunctionOrMethodParameterIndex(S, D, AL, i, Ex, Idx))
1843
3
      return;
1844
1845
    // Is the function argument a pointer type?
1846
49
    QualType T = getFunctionOrMethodParamType(D, Idx.getASTIndex());
1847
49
    int Err = -1;  // No error
1848
49
    switch (K) {
1849
15
      case OwnershipAttr::Takes:
1850
38
      case OwnershipAttr::Holds:
1851
38
        if (!T->isAnyPointerType() && 
!T->isBlockPointerType()1
)
1852
1
          Err = 0;
1853
38
        break;
1854
11
      case OwnershipAttr::Returns:
1855
11
        if (!T->isIntegerType())
1856
2
          Err = 1;
1857
11
        break;
1858
49
    }
1859
49
    if (-1 != Err) {
1860
3
      S.Diag(AL.getLoc(), diag::err_ownership_type) << AL << Err
1861
3
                                                    << Ex->getSourceRange();
1862
3
      return;
1863
3
    }
1864
1865
    // Check we don't have a conflict with another ownership attribute.
1866
46
    for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
1867
      // Cannot have two ownership attributes of different kinds for the same
1868
      // index.
1869
8
      if (I->getOwnKind() != K && I->args_end() !=
1870
2
          std::find(I->args_begin(), I->args_end(), Idx)) {
1871
1
        S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << I;
1872
1
        return;
1873
7
      } else if (K == OwnershipAttr::Returns &&
1874
7
                 
I->getOwnKind() == OwnershipAttr::Returns2
) {
1875
        // A returns attribute conflicts with any other returns attribute using
1876
        // a different index.
1877
2
        if (!llvm::is_contained(I->args(), Idx)) {
1878
2
          S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch)
1879
2
              << I->args_begin()->getSourceIndex();
1880
2
          if (I->args_size())
1881
2
            S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch)
1882
2
                << Idx.getSourceIndex() << Ex->getSourceRange();
1883
2
          return;
1884
2
        }
1885
2
      }
1886
8
    }
1887
43
    OwnershipArgs.push_back(Idx);
1888
43
  }
1889
1890
39
  ParamIdx *Start = OwnershipArgs.data();
1891
39
  unsigned Size = OwnershipArgs.size();
1892
39
  llvm::array_pod_sort(Start, Start + Size);
1893
39
  D->addAttr(::new (S.Context)
1894
39
                 OwnershipAttr(S.Context, AL, Module, Start, Size));
1895
39
}
1896
1897
48
static void handleWeakRefAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1898
  // Check the attribute arguments.
1899
48
  if (AL.getNumArgs() > 1) {
1900
0
    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
1901
0
    return;
1902
0
  }
1903
1904
  // gcc rejects
1905
  // class c {
1906
  //   static int a __attribute__((weakref ("v2")));
1907
  //   static int b() __attribute__((weakref ("f3")));
1908
  // };
1909
  // and ignores the attributes of
1910
  // void f(void) {
1911
  //   static int a __attribute__((weakref ("v2")));
1912
  // }
1913
  // we reject them
1914
48
  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
1915
48
  if (!Ctx->isFileContext()) {
1916
3
    S.Diag(AL.getLoc(), diag::err_attribute_weakref_not_global_context)
1917
3
        << cast<NamedDecl>(D);
1918
3
    return;
1919
3
  }
1920
1921
  // The GCC manual says
1922
  //
1923
  // At present, a declaration to which `weakref' is attached can only
1924
  // be `static'.
1925
  //
1926
  // It also says
1927
  //
1928
  // Without a TARGET,
1929
  // given as an argument to `weakref' or to `alias', `weakref' is
1930
  // equivalent to `weak'.
1931
  //
1932
  // gcc 4.4.1 will accept
1933
  // int a7 __attribute__((weakref));
1934
  // as
1935
  // int a7 __attribute__((weak));
1936
  // This looks like a bug in gcc. We reject that for now. We should revisit
1937
  // it if this behaviour is actually used.
1938
1939
  // GCC rejects
1940
  // static ((alias ("y"), weakref)).
1941
  // Should we? How to check that weakref is before or after alias?
1942
1943
  // FIXME: it would be good for us to keep the WeakRefAttr as-written instead
1944
  // of transforming it into an AliasAttr.  The WeakRefAttr never uses the
1945
  // StringRef parameter it was given anyway.
1946
45
  StringRef Str;
1947
45
  if (AL.getNumArgs() && 
S.checkStringLiteralArgumentAttr(AL, 0, Str)36
)
1948
    // GCC will accept anything as the argument of weakref. Should we
1949
    // check for an existing decl?
1950
35
    D->addAttr(::new (S.Context) AliasAttr(S.Context, AL, Str));
1951
1952
45
  D->addAttr(::new (S.Context) WeakRefAttr(S.Context, AL));
1953
45
}
1954
1955
17
static void handleIFuncAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1956
17
  StringRef Str;
1957
17
  if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
1958
0
    return;
1959
1960
  // Aliases should be on declarations, not definitions.
1961
17
  const auto *FD = cast<FunctionDecl>(D);
1962
17
  if (FD->isThisDeclarationADefinition()) {
1963
0
    S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 1;
1964
0
    return;
1965
0
  }
1966
1967
17
  D->addAttr(::new (S.Context) IFuncAttr(S.Context, AL, Str));
1968
17
}
1969
1970
156
static void handleAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1971
156
  StringRef Str;
1972
156
  if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
1973
0
    return;
1974
1975
156
  if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
1976
1
    S.Diag(AL.getLoc(), diag::err_alias_not_supported_on_darwin);
1977
1
    return;
1978
1
  }
1979
155
  if (S.Context.getTargetInfo().getTriple().isNVPTX()) {
1980
1
    S.Diag(AL.getLoc(), diag::err_alias_not_supported_on_nvptx);
1981
1
  }
1982
1983
  // Aliases should be on declarations, not definitions.
1984
155
  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
1985
107
    if (FD->isThisDeclarationADefinition()) {
1986
0
      S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 0;
1987
0
      return;
1988
0
    }
1989
107
  } else {
1990
48
    const auto *VD = cast<VarDecl>(D);
1991
48
    if (VD->isThisDeclarationADefinition() && 
VD->isExternallyVisible()11
) {
1992
1
      S.Diag(AL.getLoc(), diag::err_alias_is_definition) << VD << 0;
1993
1
      return;
1994
1
    }
1995
48
  }
1996
1997
  // Mark target used to prevent unneeded-internal-declaration warnings.
1998
154
  if (!S.LangOpts.CPlusPlus) {
1999
    // FIXME: demangle Str for C++, as the attribute refers to the mangled
2000
    // linkage name, not the pre-mangled identifier.
2001
118
    const DeclarationNameInfo target(&S.Context.Idents.get(Str), AL.getLoc());
2002
118
    LookupResult LR(S, target, Sema::LookupOrdinaryName);
2003
118
    if (S.LookupQualifiedName(LR, S.getCurLexicalContext()))
2004
96
      for (NamedDecl *ND : LR)
2005
96
        ND->markUsed(S.Context);
2006
118
  }
2007
2008
154
  D->addAttr(::new (S.Context) AliasAttr(S.Context, AL, Str));
2009
154
}
2010
2011
33
static void handleTLSModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2012
33
  StringRef Model;
2013
33
  SourceLocation LiteralLoc;
2014
  // Check that it is a string.
2015
33
  if (!S.checkStringLiteralArgumentAttr(AL, 0, Model, &LiteralLoc))
2016
1
    return;
2017
2018
  // Check that the value.
2019
32
  if (Model != "global-dynamic" && 
Model != "local-dynamic"26
2020
32
      && 
Model != "initial-exec"21
&&
Model != "local-exec"7
) {
2021
1
    S.Diag(LiteralLoc, diag::err_attr_tlsmodel_arg);
2022
1
    return;
2023
1
  }
2024
2025
31
  if (S.Context.getTargetInfo().getTriple().isOSAIX() &&
2026
31
      
Model != "global-dynamic"8
) {
2027
6
    S.Diag(LiteralLoc, diag::err_aix_attr_unsupported_tls_model) << Model;
2028
6
    return;
2029
6
  }
2030
2031
25
  D->addAttr(::new (S.Context) TLSModelAttr(S.Context, AL, Model));
2032
25
}
2033
2034
11.9k
static void handleRestrictAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2035
11.9k
  QualType ResultType = getFunctionOrMethodResultType(D);
2036
11.9k
  if (ResultType->isAnyPointerType() || 
ResultType->isBlockPointerType()5
) {
2037
11.9k
    D->addAttr(::new (S.Context) RestrictAttr(S.Context, AL));
2038
11.9k
    return;
2039
11.9k
  }
2040
2041
4
  S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only)
2042
4
      << AL << getFunctionOrMethodResultSourceRange(D);
2043
4
}
2044
2045
152
static void handleCPUSpecificAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2046
  // Ensure we don't combine these with themselves, since that causes some
2047
  // confusing behavior.
2048
152
  if (AL.getParsedKind() == ParsedAttr::AT_CPUDispatch) {
2049
53
    if (checkAttrMutualExclusion<CPUSpecificAttr>(S, D, AL))
2050
0
      return;
2051
2052
53
    if (const auto *Other = D->getAttr<CPUDispatchAttr>()) {
2053
0
      S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL;
2054
0
      S.Diag(Other->getLocation(), diag::note_conflicting_attribute);
2055
0
      return;
2056
0
    }
2057
99
  } else if (AL.getParsedKind() == ParsedAttr::AT_CPUSpecific) {
2058
99
    if (checkAttrMutualExclusion<CPUDispatchAttr>(S, D, AL))
2059
0
      return;
2060
2061
99
    if (const auto *Other = D->getAttr<CPUSpecificAttr>()) {
2062
0
      S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL;
2063
0
      S.Diag(Other->getLocation(), diag::note_conflicting_attribute);
2064
0
      return;
2065
0
    }
2066
99
  }
2067
2068
152
  FunctionDecl *FD = cast<FunctionDecl>(D);
2069
2070
152
  if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
2071
50
    if (MD->getParent()->isLambda()) {
2072
1
      S.Diag(AL.getLoc(), diag::err_attribute_dll_lambda) << AL;
2073
1
      return;
2074
1
    }
2075
50
  }
2076
2077
151
  if (!AL.checkAtLeastNumArgs(S, 1))
2078
2
    return;
2079
2080
149
  SmallVector<IdentifierInfo *, 8> CPUs;
2081
366
  for (unsigned ArgNo = 0; ArgNo < getNumAttributeArgs(AL); 
++ArgNo217
) {
2082
221
    if (!AL.isArgIdent(ArgNo)) {
2083
0
      S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
2084
0
          << AL << AANT_ArgumentIdentifier;
2085
0
      return;
2086
0
    }
2087
2088
221
    IdentifierLoc *CPUArg = AL.getArgAsIdent(ArgNo);
2089
221
    StringRef CPUName = CPUArg->Ident->getName().trim();
2090
2091
221
    if (!S.Context.getTargetInfo().validateCPUSpecificCPUDispatch(CPUName)) {
2092
2
      S.Diag(CPUArg->Loc, diag::err_invalid_cpu_specific_dispatch_value)
2093
2
          << CPUName << (AL.getKind() == ParsedAttr::AT_CPUDispatch);
2094
2
      return;
2095
2
    }
2096
2097
219
    const TargetInfo &Target = S.Context.getTargetInfo();
2098
219
    if (llvm::any_of(CPUs, [CPUName, &Target](const IdentifierInfo *Cur) {
2099
101
          return Target.CPUSpecificManglingCharacter(CPUName) ==
2100
101
                 Target.CPUSpecificManglingCharacter(Cur->getName());
2101
101
        })) {
2102
2
      S.Diag(AL.getLoc(), diag::warn_multiversion_duplicate_entries);
2103
2
      return;
2104
2
    }
2105
217
    CPUs.push_back(CPUArg->Ident);
2106
217
  }
2107
2108
145
  FD->setIsMultiVersion(true);
2109
145
  if (AL.getKind() == ParsedAttr::AT_CPUSpecific)
2110
96
    D->addAttr(::new (S.Context)
2111
96
                   CPUSpecificAttr(S.Context, AL, CPUs.data(), CPUs.size()));
2112
49
  else
2113
49
    D->addAttr(::new (S.Context)
2114
49
                   CPUDispatchAttr(S.Context, AL, CPUs.data(), CPUs.size()));
2115
145
}
2116
2117
9
static void handleCommonAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2118
9
  if (S.LangOpts.CPlusPlus) {
2119
1
    S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)
2120
1
        << AL << AttributeLangSupport::Cpp;
2121
1
    return;
2122
1
  }
2123
2124
8
  D->addAttr(::new (S.Context) CommonAttr(S.Context, AL));
2125
8
}
2126
2127
100
static void handleCmseNSEntryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2128
100
  if (S.LangOpts.CPlusPlus && 
!D->getDeclContext()->isExternCContext()2
) {
2129
1
    S.Diag(AL.getLoc(), diag::err_attribute_not_clinkage) << AL;
2130
1
    return;
2131
1
  }
2132
2133
99
  const auto *FD = cast<FunctionDecl>(D);
2134
99
  if (!FD->isExternallyVisible()) {
2135
1
    S.Diag(AL.getLoc(), diag::warn_attribute_cmse_entry_static);
2136
1
    return;
2137
1
  }
2138
2139
98
  D->addAttr(::new (S.Context) CmseNSEntryAttr(S.Context, AL));
2140
98
}
2141
2142
34
static void handleNakedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2143
34
  if (AL.isDeclspecAttribute()) {
2144
9
    const auto &Triple = S.getASTContext().getTargetInfo().getTriple();
2145
9
    const auto &Arch = Triple.getArch();
2146
9
    if (Arch != llvm::Triple::x86 &&
2147
9
        
(2
Arch != llvm::Triple::arm2
&&
Arch != llvm::Triple::thumb2
)) {
2148
1
      S.Diag(AL.getLoc(), diag::err_attribute_not_supported_on_arch)
2149
1
          << AL << Triple.getArchName();
2150
1
      return;
2151
1
    }
2152
9
  }
2153
2154
33
  D->addAttr(::new (S.Context) NakedAttr(S.Context, AL));
2155
33
}
2156
2157
7.33k
static void handleNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
2158
7.33k
  if (hasDeclarator(D)) 
return7.32k
;
2159
2160
19
  if (!isa<ObjCMethodDecl>(D)) {
2161
4
    S.Diag(Attrs.getLoc(), diag::warn_attribute_wrong_decl_type)
2162
4
        << Attrs << ExpectedFunctionOrMethod;
2163
4
    return;
2164
4
  }
2165
2166
15
  D->addAttr(::new (S.Context) NoReturnAttr(S.Context, Attrs));
2167
15
}
2168
2169
19
static void handleNoCfCheckAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
2170
19
  if (!S.getLangOpts().CFProtectionBranch)
2171
0
    S.Diag(Attrs.getLoc(), diag::warn_nocf_check_attribute_ignored);
2172
19
  else
2173
19
    handleSimpleAttribute<AnyX86NoCfCheckAttr>(S, D, Attrs);
2174
19
}
2175
2176
47.2k
bool Sema::CheckAttrNoArgs(const ParsedAttr &Attrs) {
2177
47.2k
  if (!Attrs.checkExactlyNumArgs(*this, 0)) {
2178
6
    Attrs.setInvalid();
2179
6
    return true;
2180
6
  }
2181
2182
47.2k
  return false;
2183
47.2k
}
2184
2185
92.0M
bool Sema::CheckAttrTarget(const ParsedAttr &AL) {
2186
  // Check whether the attribute is valid on the current target.
2187
92.0M
  if (!AL.existsInTarget(Context.getTargetInfo())) {
2188
11
    Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)
2189
11
        << AL << AL.getRange();
2190
11
    AL.setInvalid();
2191
11
    return true;
2192
11
  }
2193
2194
92.0M
  return false;
2195
92.0M
}
2196
2197
7
static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2198
2199
  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
2200
  // because 'analyzer_noreturn' does not impact the type.
2201
7
  if (!isFunctionOrMethodOrBlock(D)) {
2202
0
    ValueDecl *VD = dyn_cast<ValueDecl>(D);
2203
0
    if (!VD || (!VD->getType()->isBlockPointerType() &&
2204
0
                !VD->getType()->isFunctionPointerType())) {
2205
0
      S.Diag(AL.getLoc(), AL.isStandardAttributeSyntax()
2206
0
                              ? diag::err_attribute_wrong_decl_type
2207
0
                              : diag::warn_attribute_wrong_decl_type)
2208
0
          << AL << ExpectedFunctionMethodOrBlock;
2209
0
      return;
2210
0
    }
2211
0
  }
2212
2213
7
  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(S.Context, AL));
2214
7
}
2215
2216
// PS3 PPU-specific.
2217
23
static void handleVecReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2218
  /*
2219
    Returning a Vector Class in Registers
2220
2221
    According to the PPU ABI specifications, a class with a single member of
2222
    vector type is returned in memory when used as the return value of a
2223
    function.
2224
    This results in inefficient code when implementing vector classes. To return
2225
    the value in a single vector register, add the vecreturn attribute to the
2226
    class definition. This attribute is also applicable to struct types.
2227
2228
    Example:
2229
2230
    struct Vector
2231
    {
2232
      __vector float xyzw;
2233
    } __attribute__((vecreturn));
2234
2235
    Vector Add(Vector lhs, Vector rhs)
2236
    {
2237
      Vector result;
2238
      result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
2239
      return result; // This will be returned in a register
2240
    }
2241
  */
2242
23
  if (VecReturnAttr *A = D->getAttr<VecReturnAttr>()) {
2243
1
    S.Diag(AL.getLoc(), diag::err_repeat_attribute) << A;
2244
1
    return;
2245
1
  }
2246
2247
22
  const auto *R = cast<RecordDecl>(D);
2248
22
  int count = 0;
2249
2250
22
  if (!isa<CXXRecordDecl>(R)) {
2251
0
    S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
2252
0
    return;
2253
0
  }
2254
2255
22
  if (!cast<CXXRecordDecl>(R)->isPOD()) {
2256
7
    S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
2257
7
    return;
2258
7
  }
2259
2260
22
  
for (const auto *I : R->fields())15
{
2261
22
    if ((count == 1) || 
!I->getType()->isVectorType()15
) {
2262
7
      S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
2263
7
      return;
2264
7
    }
2265
15
    count++;
2266
15
  }
2267
2268
8
  D->addAttr(::new (S.Context) VecReturnAttr(S.Context, AL));
2269
8
}
2270
2271
static void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D,
2272
27
                                 const ParsedAttr &AL) {
2273
27
  if (isa<ParmVarDecl>(D)) {
2274
    // [[carries_dependency]] can only be applied to a parameter if it is a
2275
    // parameter of a function declaration or lambda.
2276
14
    if (!(Scope->getFlags() & clang::Scope::FunctionDeclarationScope)) {
2277
6
      S.Diag(AL.getLoc(),
2278
6
             diag::err_carries_dependency_param_not_function_decl);
2279
6
      return;
2280
6
    }
2281
14
  }
2282
2283
21
  D->addAttr(::new (S.Context) CarriesDependencyAttr(S.Context, AL));
2284
21
}
2285
2286
109k
static void handleUnusedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2287
109k
  bool IsCXX17Attr = AL.isCXX11Attribute() && 
!AL.getScopeName()29
;
2288
2289
  // If this is spelled as the standard C++17 attribute, but not in C++17, warn
2290
  // about using it as an extension.
2291
109k
  if (!S.getLangOpts().CPlusPlus17 && 
IsCXX17Attr108k
)
2292
8
    S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
2293
2294
109k
  D->addAttr(::new (S.Context) UnusedAttr(S.Context, AL));
2295
109k
}
2296
2297
37
static void handleConstructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2298
37
  uint32_t priority = ConstructorAttr::DefaultPriority;
2299
37
  if (AL.getNumArgs() &&
2300
37
      
!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), priority)19
)
2301
4
    return;
2302
2303
33
  D->addAttr(::new (S.Context) ConstructorAttr(S.Context, AL, priority));
2304
33
}
2305
2306
48
static void handleDestructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2307
48
  uint32_t priority = DestructorAttr::DefaultPriority;
2308
48
  if (AL.getNumArgs() &&
2309
48
      
!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), priority)35
)
2310
1
    return;
2311
2312
47
  D->addAttr(::new (S.Context) DestructorAttr(S.Context, AL, priority));
2313
47
}
2314
2315
template <typename AttrTy>
2316
6.59k
static void handleAttrWithMessage(Sema &S, Decl *D, const ParsedAttr &AL) {
2317
  // Handle the case where the attribute has a text message.
2318
6.59k
  StringRef Str;
2319
6.59k
  if (AL.getNumArgs() == 1 && 
!S.checkStringLiteralArgumentAttr(AL, 0, Str)1.66k
)
2320
1
    return;
2321
2322
6.59k
  D->addAttr(::new (S.Context) AttrTy(S.Context, AL, Str));
2323
6.59k
}
2324
2325
static void handleObjCSuppresProtocolAttr(Sema &S, Decl *D,
2326
88
                                          const ParsedAttr &AL) {
2327
88
  if (!cast<ObjCProtocolDecl>(D)->isThisDeclarationADefinition()) {
2328
1
    S.Diag(AL.getLoc(), diag::err_objc_attr_protocol_requires_definition)
2329
1
        << AL << AL.getRange();
2330
1
    return;
2331
1
  }
2332
2333
87
  D->addAttr(::new (S.Context) ObjCExplicitProtocolImplAttr(S.Context, AL));
2334
87
}
2335
2336
static bool checkAvailabilityAttr(Sema &S, SourceRange Range,
2337
                                  IdentifierInfo *Platform,
2338
                                  VersionTuple Introduced,
2339
                                  VersionTuple Deprecated,
2340
6.12M
                                  VersionTuple Obsoleted) {
2341
6.12M
  StringRef PlatformName
2342
6.12M
    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
2343
6.12M
  if (PlatformName.empty())
2344
509
    PlatformName = Platform->getName();
2345
2346
  // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
2347
  // of these steps are needed).
2348
6.12M
  if (!Introduced.empty() && 
!Deprecated.empty()4.80M
&&
2349
6.12M
      
!(Introduced <= Deprecated)1.03M
) {
2350
7
    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2351
7
      << 1 << PlatformName << Deprecated.getAsString()
2352
7
      << 0 << Introduced.getAsString();
2353
7
    return true;
2354
7
  }
2355
2356
6.12M
  if (!Introduced.empty() && 
!Obsoleted.empty()4.80M
&&
2357
6.12M
      
!(Introduced <= Obsoleted)65
) {
2358
0
    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2359
0
      << 2 << PlatformName << Obsoleted.getAsString()
2360
0
      << 0 << Introduced.getAsString();
2361
0
    return true;
2362
0
  }
2363
2364
6.12M
  if (!Deprecated.empty() && 
!Obsoleted.empty()1.08M
&&
2365
6.12M
      
!(Deprecated <= Obsoleted)40
) {
2366
3
    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2367
3
      << 2 << PlatformName << Obsoleted.getAsString()
2368
3
      << 1 << Deprecated.getAsString();
2369
3
    return true;
2370
3
  }
2371
2372
6.12M
  return false;
2373
6.12M
}
2374
2375
/// Check whether the two versions match.
2376
///
2377
/// If either version tuple is empty, then they are assumed to match. If
2378
/// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y.
2379
static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y,
2380
418k
                          bool BeforeIsOkay) {
2381
418k
  if (X.empty() || 
Y.empty()143k
)
2382
282k
    return true;
2383
2384
135k
  if (X == Y)
2385
134k
    return true;
2386
2387
733
  if (BeforeIsOkay && 
X < Y112
)
2388
22
    return true;
2389
2390
711
  return false;
2391
733
}
2392
2393
AvailabilityAttr *Sema::mergeAvailabilityAttr(
2394
    NamedDecl *D, const AttributeCommonInfo &CI, IdentifierInfo *Platform,
2395
    bool Implicit, VersionTuple Introduced, VersionTuple Deprecated,
2396
    VersionTuple Obsoleted, bool IsUnavailable, StringRef Message,
2397
    bool IsStrict, StringRef Replacement, AvailabilityMergeKind AMK,
2398
6.10M
    int Priority) {
2399
6.10M
  VersionTuple MergedIntroduced = Introduced;
2400
6.10M
  VersionTuple MergedDeprecated = Deprecated;
2401
6.10M
  VersionTuple MergedObsoleted = Obsoleted;
2402
6.10M
  bool FoundAny = false;
2403
6.10M
  bool OverrideOrImpl = false;
2404
6.10M
  switch (AMK) {
2405
5.94M
  case AMK_None:
2406
5.97M
  case AMK_Redeclaration:
2407
5.97M
    OverrideOrImpl = false;
2408
5.97M
    break;
2409
2410
133k
  case AMK_Override:
2411
133k
  case AMK_ProtocolImplementation:
2412
134k
  case AMK_OptionalProtocolImplementation:
2413
134k
    OverrideOrImpl = true;
2414
134k
    break;
2415
6.10M
  }
2416
2417
6.10M
  if (D->hasAttrs()) {
2418
4.19M
    AttrVec &Attrs = D->getAttrs();
2419
12.7M
    for (unsigned i = 0, e = Attrs.size(); i != e;) {
2420
8.51M
      const auto *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]);
2421
8.51M
      if (!OldAA) {
2422
1.32M
        ++i;
2423
1.32M
        continue;
2424
1.32M
      }
2425
2426
7.19M
      IdentifierInfo *OldPlatform = OldAA->getPlatform();
2427
7.19M
      if (OldPlatform != Platform) {
2428
7.05M
        ++i;
2429
7.05M
        continue;
2430
7.05M
      }
2431
2432
      // If there is an existing availability attribute for this platform that
2433
      // has a lower priority use the existing one and discard the new
2434
      // attribute.
2435
140k
      if (OldAA->getPriority() < Priority)
2436
494
        return nullptr;
2437
2438
      // If there is an existing attribute for this platform that has a higher
2439
      // priority than the new attribute then erase the old one and continue
2440
      // processing the attributes.
2441
139k
      if (OldAA->getPriority() > Priority) {
2442
16
        Attrs.erase(Attrs.begin() + i);
2443
16
        --e;
2444
16
        continue;
2445
16
      }
2446
2447
139k
      FoundAny = true;
2448
139k
      VersionTuple OldIntroduced = OldAA->getIntroduced();
2449
139k
      VersionTuple OldDeprecated = OldAA->getDeprecated();
2450
139k
      VersionTuple OldObsoleted = OldAA->getObsoleted();
2451
139k
      bool OldIsUnavailable = OldAA->getUnavailable();
2452
2453
139k
      if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl) ||
2454
139k
          
!versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl)139k
||
2455
139k
          
!versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl)139k
||
2456
139k
          
!(139k
OldIsUnavailable == IsUnavailable139k
||
2457
139k
            
(11
OverrideOrImpl11
&&
!OldIsUnavailable11
&&
IsUnavailable5
))) {
2458
672
        if (OverrideOrImpl) {
2459
51
          int Which = -1;
2460
51
          VersionTuple FirstVersion;
2461
51
          VersionTuple SecondVersion;
2462
51
          if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl)) {
2463
37
            Which = 0;
2464
37
            FirstVersion = OldIntroduced;
2465
37
            SecondVersion = Introduced;
2466
37
          } else 
if (14
!versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl)14
) {
2467
6
            Which = 1;
2468
6
            FirstVersion = Deprecated;
2469
6
            SecondVersion = OldDeprecated;
2470
8
          } else if (!versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl)) {
2471
2
            Which = 2;
2472
2
            FirstVersion = Obsoleted;
2473
2
            SecondVersion = OldObsoleted;
2474
2
          }
2475
2476
51
          if (Which == -1) {
2477
6
            Diag(OldAA->getLocation(),
2478
6
                 diag::warn_mismatched_availability_override_unavail)
2479
6
              << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
2480
6
              << (AMK == AMK_Override);
2481
45
          } else if (Which != 1 && 
AMK == AMK_OptionalProtocolImplementation39
) {
2482
            // Allow different 'introduced' / 'obsoleted' availability versions
2483
            // on a method that implements an optional protocol requirement. It
2484
            // makes less sense to allow this for 'deprecated' as the user can't
2485
            // see if the method is 'deprecated' as 'respondsToSelector' will
2486
            // still return true when the method is deprecated.
2487
8
            ++i;
2488
8
            continue;
2489
37
          } else {
2490
37
            Diag(OldAA->getLocation(),
2491
37
                 diag::warn_mismatched_availability_override)
2492
37
              << Which
2493
37
              << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
2494
37
              << FirstVersion.getAsString() << SecondVersion.getAsString()
2495
37
              << (AMK == AMK_Override);
2496
37
          }
2497
43
          if (AMK == AMK_Override)
2498
15
            Diag(CI.getLoc(), diag::note_overridden_method);
2499
28
          else
2500
28
            Diag(CI.getLoc(), diag::note_protocol_method);
2501
621
        } else {
2502
621
          Diag(OldAA->getLocation(), diag::warn_mismatched_availability);
2503
621
          Diag(CI.getLoc(), diag::note_previous_attribute);
2504
621
        }
2505
2506
664
        Attrs.erase(Attrs.begin() + i);
2507
664
        --e;
2508
664
        continue;
2509
672
      }
2510
2511
139k
      VersionTuple MergedIntroduced2 = MergedIntroduced;
2512
139k
      VersionTuple MergedDeprecated2 = MergedDeprecated;
2513
139k
      VersionTuple MergedObsoleted2 = MergedObsoleted;
2514
2515
139k
      if (MergedIntroduced2.empty())
2516
15.6k
        MergedIntroduced2 = OldIntroduced;
2517
139k
      if (MergedDeprecated2.empty())
2518
113k
        MergedDeprecated2 = OldDeprecated;
2519
139k
      if (MergedObsoleted2.empty())
2520
139k
        MergedObsoleted2 = OldObsoleted;
2521
2522
139k
      if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform,
2523
139k
                                MergedIntroduced2, MergedDeprecated2,
2524
139k
                                MergedObsoleted2)) {
2525
4
        Attrs.erase(Attrs.begin() + i);
2526
4
        --e;
2527
4
        continue;
2528
4
      }
2529
2530
139k
      MergedIntroduced = MergedIntroduced2;
2531
139k
      MergedDeprecated = MergedDeprecated2;
2532
139k
      MergedObsoleted = MergedObsoleted2;
2533
139k
      ++i;
2534
139k
    }
2535
4.19M
  }
2536
2537
6.10M
  if (FoundAny &&
2538
6.10M
      
MergedIntroduced == Introduced139k
&&
2539
6.10M
      
MergedDeprecated == Deprecated135k
&&
2540
6.10M
      
MergedObsoleted == Obsoleted125k
)
2541
125k
    return nullptr;
2542
2543
  // Only create a new attribute if !OverrideOrImpl, but we want to do
2544
  // the checking.
2545
5.98M
  if (!checkAvailabilityAttr(*this, CI.getRange(), Platform, MergedIntroduced,
2546
5.98M
                             MergedDeprecated, MergedObsoleted) &&
2547
5.98M
      
!OverrideOrImpl5.98M
) {
2548
5.97M
    auto *Avail = ::new (Context) AvailabilityAttr(
2549
5.97M
        Context, CI, Platform, Introduced, Deprecated, Obsoleted, IsUnavailable,
2550
5.97M
        Message, IsStrict, Replacement, Priority);
2551
5.97M
    Avail->setImplicit(Implicit);
2552
5.97M
    return Avail;
2553
5.97M
  }
2554
10.5k
  return nullptr;
2555
5.98M
}
2556
2557
5.94M
static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2558
5.94M
  if (isa<UsingDecl, UnresolvedUsingTypenameDecl, UnresolvedUsingValueDecl>(
2559
5.94M
          D)) {
2560
2
    S.Diag(AL.getRange().getBegin(), diag::warn_deprecated_ignored_on_using)
2561
2
        << AL;
2562
2
    return;
2563
2
  }
2564
2565
5.94M
  if (!AL.checkExactlyNumArgs(S, 1))
2566
0
    return;
2567
5.94M
  IdentifierLoc *Platform = AL.getArgAsIdent(0);
2568
2569
5.94M
  IdentifierInfo *II = Platform->Ident;
2570
5.94M
  if (AvailabilityAttr::getPrettyPlatformName(II->getName()).empty())
2571
509
    S.Diag(Platform->Loc, diag::warn_availability_unknown_platform)
2572
509
      << Platform->Ident;
2573
2574
5.94M
  auto *ND = dyn_cast<NamedDecl>(D);
2575
5.94M
  if (!ND) // We warned about this already, so just return.
2576
0
    return;
2577
2578
5.94M
  AvailabilityChange Introduced = AL.getAvailabilityIntroduced();
2579
5.94M
  AvailabilityChange Deprecated = AL.getAvailabilityDeprecated();
2580
5.94M
  AvailabilityChange Obsoleted = AL.getAvailabilityObsoleted();
2581
5.94M
  bool IsUnavailable = AL.getUnavailableLoc().isValid();
2582
5.94M
  bool IsStrict = AL.getStrictLoc().isValid();
2583
5.94M
  StringRef Str;
2584
5.94M
  if (const auto *SE = dyn_cast_or_null<StringLiteral>(AL.getMessageExpr()))
2585
518k
    Str = SE->getString();
2586
5.94M
  StringRef Replacement;
2587
5.94M
  if (const auto *SE = dyn_cast_or_null<StringLiteral>(AL.getReplacementExpr()))
2588
81.4k
    Replacement = SE->getString();
2589
2590
5.94M
  if (II->isStr("swift")) {
2591
36.1k
    if (Introduced.isValid() || 
Obsoleted.isValid()36.1k
||
2592
36.1k
        
(36.1k
!IsUnavailable36.1k
&&
!Deprecated.isValid()3
)) {
2593
2
      S.Diag(AL.getLoc(),
2594
2
             diag::warn_availability_swift_unavailable_deprecated_only);
2595
2
      return;
2596
2
    }
2597
36.1k
  }
2598
2599
5.94M
  if (II->isStr("fuchsia")) {
2600
18
    Optional<unsigned> Min, Sub;
2601
18
    if ((Min = Introduced.Version.getMinor()) ||
2602
18
        
(Sub = Introduced.Version.getSubminor())14
) {
2603
4
      S.Diag(AL.getLoc(), diag::warn_availability_fuchsia_unavailable_minor);
2604
4
      return;
2605
4
    }
2606
18
  }
2607
2608
5.94M
  int PriorityModifier = AL.isPragmaClangAttribute()
2609
5.94M
                             ? 
Sema::AP_PragmaClangAttribute63.8k
2610
5.94M
                             : 
Sema::AP_Explicit5.87M
;
2611
5.94M
  AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2612
5.94M
      ND, AL, II, false /*Implicit*/, Introduced.Version, Deprecated.Version,
2613
5.94M
      Obsoleted.Version, IsUnavailable, Str, IsStrict, Replacement,
2614
5.94M
      Sema::AMK_None, PriorityModifier);
2615
5.94M
  if (NewAttr)
2616
5.94M
    D->addAttr(NewAttr);
2617
2618
  // Transcribe "ios" to "watchos" (and add a new attribute) if the versioning
2619
  // matches before the start of the watchOS platform.
2620
5.94M
  if (S.Context.getTargetInfo().getTriple().isWatchOS()) {
2621
83
    IdentifierInfo *NewII = nullptr;
2622
83
    if (II->getName() == "ios")
2623
34
      NewII = &S.Context.Idents.get("watchos");
2624
49
    else if (II->getName() == "ios_app_extension")
2625
0
      NewII = &S.Context.Idents.get("watchos_app_extension");
2626
2627
83
    if (NewII) {
2628
34
      const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking();
2629
34
      const auto *IOSToWatchOSMapping =
2630
34
          SDKInfo ? SDKInfo->getVersionMapping(
2631
16
                        DarwinSDKInfo::OSEnvPair::iOStoWatchOSPair())
2632
34
                  : 
nullptr18
;
2633
2634
34
      auto adjustWatchOSVersion =
2635
102
          [IOSToWatchOSMapping](VersionTuple Version) -> VersionTuple {
2636
102
        if (Version.empty())
2637
56
          return Version;
2638
46
        auto MinimumWatchOSVersion = VersionTuple(2, 0);
2639
2640
46
        if (IOSToWatchOSMapping) {
2641
22
          if (auto MappedVersion = IOSToWatchOSMapping->map(
2642
22
                  Version, MinimumWatchOSVersion, None)) {
2643
22
            return MappedVersion.getValue();
2644
22
          }
2645
22
        }
2646
2647
24
        auto Major = Version.getMajor();
2648
24
        auto NewMajor = Major >= 9 ? 
Major - 76
:
018
;
2649
24
        if (NewMajor >= 2) {
2650
6
          if (Version.getMinor().hasValue()) {
2651
5
            if (Version.getSubminor().hasValue())
2652
1
              return VersionTuple(NewMajor, Version.getMinor().getValue(),
2653
1
                                  Version.getSubminor().getValue());
2654
4
            else
2655
4
              return VersionTuple(NewMajor, Version.getMinor().getValue());
2656
5
          }
2657
1
          return VersionTuple(NewMajor);
2658
6
        }
2659
2660
18
        return MinimumWatchOSVersion;
2661
24
      };
2662
2663
34
      auto NewIntroduced = adjustWatchOSVersion(Introduced.Version);
2664
34
      auto NewDeprecated = adjustWatchOSVersion(Deprecated.Version);
2665
34
      auto NewObsoleted = adjustWatchOSVersion(Obsoleted.Version);
2666
2667
34
      AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2668
34
          ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
2669
34
          NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,
2670
34
          Sema::AMK_None,
2671
34
          PriorityModifier + Sema::AP_InferredFromOtherPlatform);
2672
34
      if (NewAttr)
2673
32
        D->addAttr(NewAttr);
2674
34
    }
2675
5.94M
  } else if (S.Context.getTargetInfo().getTriple().isTvOS()) {
2676
    // Transcribe "ios" to "tvos" (and add a new attribute) if the versioning
2677
    // matches before the start of the tvOS platform.
2678
117
    IdentifierInfo *NewII = nullptr;
2679
117
    if (II->getName() == "ios")
2680
29
      NewII = &S.Context.Idents.get("tvos");
2681
88
    else if (II->getName() == "ios_app_extension")
2682
3
      NewII = &S.Context.Idents.get("tvos_app_extension");
2683
2684
117
    if (NewII) {
2685
32
      const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking();
2686
32
      const auto *IOSToTvOSMapping =
2687
32
          SDKInfo ? SDKInfo->getVersionMapping(
2688
8
                        DarwinSDKInfo::OSEnvPair::iOStoTvOSPair())
2689
32
                  : 
nullptr24
;
2690
2691
32
      auto AdjustTvOSVersion =
2692
96
          [IOSToTvOSMapping](VersionTuple Version) -> VersionTuple {
2693
96
        if (Version.empty())
2694
58
          return Version;
2695
2696
38
        if (IOSToTvOSMapping) {
2697
10
          if (auto MappedVersion =
2698
10
                  IOSToTvOSMapping->map(Version, VersionTuple(0, 0), None)) {
2699
6
            return MappedVersion.getValue();
2700
6
          }
2701
10
        }
2702
32
        return Version;
2703
38
      };
2704
2705
32
      auto NewIntroduced = AdjustTvOSVersion(Introduced.Version);
2706
32
      auto NewDeprecated = AdjustTvOSVersion(Deprecated.Version);
2707
32
      auto NewObsoleted = AdjustTvOSVersion(Obsoleted.Version);
2708
2709
32
      AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2710
32
          ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
2711
32
          NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,
2712
32
          Sema::AMK_None,
2713
32
          PriorityModifier + Sema::AP_InferredFromOtherPlatform);
2714
32
      if (NewAttr)
2715
24
        D->addAttr(NewAttr);
2716
32
    }
2717
5.94M
  } else if (S.Context.getTargetInfo().getTriple().getOS() ==
2718
5.94M
                 llvm::Triple::IOS &&
2719
5.94M
             
S.Context.getTargetInfo().getTriple().isMacCatalystEnvironment()223
) {
2720
119
    auto GetSDKInfo = [&]() {
2721
46
      return S.getDarwinSDKInfoForAvailabilityChecking(AL.getRange().getBegin(),
2722
46
                                                       "macOS");
2723
46
    };
2724
2725
    // Transcribe "ios" to "maccatalyst" (and add a new attribute).
2726
119
    IdentifierInfo *NewII = nullptr;
2727
119
    if (II->getName() == "ios")
2728
32
      NewII = &S.Context.Idents.get("maccatalyst");
2729
87
    else if (II->getName() == "ios_app_extension")
2730
10
      NewII = &S.Context.Idents.get("maccatalyst_app_extension");
2731
119
    if (NewII) {
2732
126
      auto MinMacCatalystVersion = [](const VersionTuple &V) {
2733
126
        if (V.empty())
2734
78
          return V;
2735
48
        if (V.getMajor() < 13 ||
2736
48
            
(14
V.getMajor() == 1314
&&
V.getMinor()2
&&
*V.getMinor() < 12
))
2737
34
          return VersionTuple(13, 1); // The min Mac Catalyst version is 13.1.
2738
14
        return V;
2739
48
      };
2740
42
      AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2741
42
          ND, AL.getRange(), NewII, true /*Implicit*/,
2742
42
          MinMacCatalystVersion(Introduced.Version),
2743
42
          MinMacCatalystVersion(Deprecated.Version),
2744
42
          MinMacCatalystVersion(Obsoleted.Version), IsUnavailable, Str,
2745
42
          IsStrict, Replacement, Sema::AMK_None,
2746
42
          PriorityModifier + Sema::AP_InferredFromOtherPlatform);
2747
42
      if (NewAttr)
2748
28
        D->addAttr(NewAttr);
2749
77
    } else if (II->getName() == "macos" && 
GetSDKInfo()25
&&
2750
77
               
(23
!Introduced.Version.empty()23
||
!Deprecated.Version.empty()2
||
2751
23
                
!Obsoleted.Version.empty()2
)) {
2752
21
      if (const auto *MacOStoMacCatalystMapping =
2753
21
              GetSDKInfo()->getVersionMapping(
2754
21
                  DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {
2755
        // Infer Mac Catalyst availability from the macOS availability attribute
2756
        // if it has versioned availability. Don't infer 'unavailable'. This
2757
        // inferred availability has lower priority than the other availability
2758
        // attributes that are inferred from 'ios'.
2759
21
        NewII = &S.Context.Idents.get("maccatalyst");
2760
21
        auto RemapMacOSVersion =
2761
63
            [&](const VersionTuple &V) -> Optional<VersionTuple> {
2762
63
          if (V.empty())
2763
29
            return None;
2764
          // API_TO_BE_DEPRECATED is 100000.
2765
34
          if (V.getMajor() == 100000)
2766
4
            return VersionTuple(100000);
2767
          // The minimum iosmac version is 13.1
2768
30
          return MacOStoMacCatalystMapping->map(V, VersionTuple(13, 1), None);
2769
34
        };
2770
21
        Optional<VersionTuple> NewIntroduced =
2771
21
                                   RemapMacOSVersion(Introduced.Version),
2772
21
                               NewDeprecated =
2773
21
                                   RemapMacOSVersion(Deprecated.Version),
2774
21
                               NewObsoleted =
2775
21
                                   RemapMacOSVersion(Obsoleted.Version);
2776
21
        if (NewIntroduced || 
NewDeprecated2
||
NewObsoleted2
) {
2777
19
          auto VersionOrEmptyVersion =
2778
57
              [](const Optional<VersionTuple> &V) -> VersionTuple {
2779
57
            return V ? 
*V32
:
VersionTuple()25
;
2780
57
          };
2781
19
          AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2782
19
              ND, AL.getRange(), NewII, true /*Implicit*/,
2783
19
              VersionOrEmptyVersion(NewIntroduced),
2784
19
              VersionOrEmptyVersion(NewDeprecated),
2785
19
              VersionOrEmptyVersion(NewObsoleted), /*IsUnavailable=*/false, Str,
2786
19
              IsStrict, Replacement, Sema::AMK_None,
2787
19
              PriorityModifier + Sema::AP_InferredFromOtherPlatform +
2788
19
                  Sema::AP_InferredFromOtherPlatform);
2789
19
          if (NewAttr)
2790
19
            D->addAttr(NewAttr);
2791
19
        }
2792
21
      }
2793
21
    }
2794
119
  }
2795
5.94M
}
2796
2797
static void handleExternalSourceSymbolAttr(Sema &S, Decl *D,
2798
71
                                           const ParsedAttr &AL) {
2799
71
  if (!AL.checkAtLeastNumArgs(S, 1) || 
!AL.checkAtMostNumArgs(S, 3)68
)
2800
3
    return;
2801
2802
68
  StringRef Language;
2803
68
  if (const auto *SE = dyn_cast_or_null<StringLiteral>(AL.getArgAsExpr(0)))
2804
57
    Language = SE->getString();
2805
68
  StringRef DefinedIn;
2806
68
  if (const auto *SE = dyn_cast_or_null<StringLiteral>(AL.getArgAsExpr(1)))
2807
55
    DefinedIn = SE->getString();
2808
68
  bool IsGeneratedDeclaration = AL.getArgAsIdent(2) != nullptr;
2809
2810
68
  D->addAttr(::new (S.Context) ExternalSourceSymbolAttr(
2811
68
      S.Context, AL, Language, DefinedIn, IsGeneratedDeclaration));
2812
68
}
2813
2814
template <class T>
2815
static T *mergeVisibilityAttr(Sema &S, Decl *D, const AttributeCommonInfo &CI,
2816
1.88M
                              typename T::VisibilityType value) {
2817
1.88M
  T *existingAttr = D->getAttr<T>();
2818
1.88M
  if (existingAttr) {
2819
46.6k
    typename T::VisibilityType existingValue = existingAttr->getVisibility();
2820
46.6k
    if (existingValue == value)
2821
46.6k
      return nullptr;
2822
6
    S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
2823
6
    S.Diag(CI.getLoc(), diag::note_previous_attribute);
2824
6
    D->dropAttr<T>();
2825
6
  }
2826
1.83M
  return ::new (S.Context) T(S.Context, CI, value);
2827
1.88M
}
SemaDeclAttr.cpp:clang::VisibilityAttr* mergeVisibilityAttr<clang::VisibilityAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&, clang::VisibilityAttr::VisibilityType)
Line
Count
Source
2816
1.71M
                              typename T::VisibilityType value) {
2817
1.71M
  T *existingAttr = D->getAttr<T>();
2818
1.71M
  if (existingAttr) {
2819
35.9k
    typename T::VisibilityType existingValue = existingAttr->getVisibility();
2820
35.9k
    if (existingValue == value)
2821
35.9k
      return nullptr;
2822
6
    S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
2823
6
    S.Diag(CI.getLoc(), diag::note_previous_attribute);
2824
6
    D->dropAttr<T>();
2825
6
  }
2826
1.67M
  return ::new (S.Context) T(S.Context, CI, value);
2827
1.71M
}
SemaDeclAttr.cpp:clang::TypeVisibilityAttr* mergeVisibilityAttr<clang::TypeVisibilityAttr>(clang::Sema&, clang::Decl*, clang::AttributeCommonInfo const&, clang::TypeVisibilityAttr::VisibilityType)
Line
Count
Source
2816
170k
                              typename T::VisibilityType value) {
2817
170k
  T *existingAttr = D->getAttr<T>();
2818
170k
  if (existingAttr) {
2819
10.6k
    typename T::VisibilityType existingValue = existingAttr->getVisibility();
2820
10.6k
    if (existingValue == value)
2821
10.6k
      return nullptr;
2822
0
    S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
2823
0
    S.Diag(CI.getLoc(), diag::note_previous_attribute);
2824
0
    D->dropAttr<T>();
2825
0
  }
2826
160k
  return ::new (S.Context) T(S.Context, CI, value);
2827
170k
}
2828
2829
VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D,
2830
                                          const AttributeCommonInfo &CI,
2831
1.71M
                                          VisibilityAttr::VisibilityType Vis) {
2832
1.71M
  return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, CI, Vis);
2833
1.71M
}
2834
2835
TypeVisibilityAttr *
2836
Sema::mergeTypeVisibilityAttr(Decl *D, const AttributeCommonInfo &CI,
2837
170k
                              TypeVisibilityAttr::VisibilityType Vis) {
2838
170k
  return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, CI, Vis);
2839
170k
}
2840
2841
static void handleVisibilityAttr(Sema &S, Decl *D, const ParsedAttr &AL,
2842
1.76M
                                 bool isTypeVisibility) {
2843
  // Visibility attributes don't mean anything on a typedef.
2844
1.76M
  if (isa<TypedefNameDecl>(D)) {
2845
1
    S.Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored) << AL;
2846
1
    return;
2847
1
  }
2848
2849
  // 'type_visibility' can only go on a type or namespace.
2850
1.76M
  if (isTypeVisibility &&
2851
1.76M
      
!(150k
isa<TagDecl>(D)150k
||
2852
150k
        
isa<ObjCInterfaceDecl>(D)1
||
2853
150k
        
isa<NamespaceDecl>(D)1
)) {
2854
1
    S.Diag(AL.getRange().getBegin(), diag::err_attribute_wrong_decl_type)
2855
1
        << AL << ExpectedTypeOrNamespace;
2856
1
    return;
2857
1
  }
2858
2859
  // Check that the argument is a string literal.
2860
1.76M
  StringRef TypeStr;
2861
1.76M
  SourceLocation LiteralLoc;
2862
1.76M
  if (!S.checkStringLiteralArgumentAttr(AL, 0, TypeStr, &LiteralLoc))
2863
0
    return;
2864
2865
1.76M
  VisibilityAttr::VisibilityType type;
2866
1.76M
  if (!VisibilityAttr::ConvertStrToVisibilityType(TypeStr, type)) {
2867
0
    S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported) << AL
2868
0
                                                                << TypeStr;
2869
0
    return;
2870
0
  }
2871
2872
  // Complain about attempts to use protected visibility on targets
2873
  // (like Darwin) that don't support it.
2874
1.76M
  if (type == VisibilityAttr::Protected &&
2875
1.76M
      
!S.Context.getTargetInfo().hasProtectedVisibility()44
) {
2876
3
    S.Diag(AL.getLoc(), diag::warn_attribute_protected_visibility);
2877
3
    type = VisibilityAttr::Default;
2878
3
  }
2879
2880
1.76M
  Attr *newAttr;
2881
1.76M
  if (isTypeVisibility) {
2882
150k
    newAttr = S.mergeTypeVisibilityAttr(
2883
150k
        D, AL, (TypeVisibilityAttr::VisibilityType)type);
2884
1.61M
  } else {
2885
1.61M
    newAttr = S.mergeVisibilityAttr(D, AL, type);
2886
1.61M
  }
2887
1.76M
  if (newAttr)
2888
1.76M
    D->addAttr(newAttr);
2889
1.76M
}
2890
2891
117
static void handleObjCDirectAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2892
  // objc_direct cannot be set on methods declared in the context of a protocol
2893
117
  if (isa<ObjCProtocolDecl>(D->getDeclContext())) {
2894
2
    S.Diag(AL.getLoc(), diag::err_objc_direct_on_protocol) << false;
2895
2
    return;
2896
2
  }
2897
2898
115
  if (S.getLangOpts().ObjCRuntime.allowsDirectDispatch()) {
2899
115
    handleSimpleAttribute<ObjCDirectAttr>(S, D, AL);
2900
115
  } else {
2901
0
    S.Diag(AL.getLoc(), diag::warn_objc_direct_ignored) << AL;
2902
0
  }
2903
115
}
2904
2905
static void handleObjCDirectMembersAttr(Sema &S, Decl *D,
2906
12
                                        const ParsedAttr &AL) {
2907
12
  if (S.getLangOpts().ObjCRuntime.allowsDirectDispatch()) {
2908
12
    handleSimpleAttribute<ObjCDirectMembersAttr>(S, D, AL);
2909
12
  } else {
2910
0
    S.Diag(AL.getLoc(), diag::warn_objc_direct_ignored) << AL;
2911
0
  }
2912
12
}
2913
2914
18
static void handleObjCMethodFamilyAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2915
18
  const auto *M = cast<ObjCMethodDecl>(D);
2916
18
  if (!AL.isArgIdent(0)) {
2917
2
    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
2918
2
        << AL << 1 << AANT_ArgumentIdentifier;
2919
2
    return;
2920
2
  }
2921
2922
16
  IdentifierLoc *IL = AL.getArgAsIdent(0);
2923
16
  ObjCMethodFamilyAttr::FamilyKind F;
2924
16
  if (!ObjCMethodFamilyAttr::ConvertStrToFamilyKind(IL->Ident->getName(), F)) {
2925
0
    S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL << IL->Ident;
2926
0
    return;
2927
0
  }
2928
2929
16
  if (F == ObjCMethodFamilyAttr::OMF_init &&
2930
16
      
!M->getReturnType()->isObjCObjectPointerType()14
) {
2931
0
    S.Diag(M->getLocation(), diag::err_init_method_bad_return_type)
2932
0
        << M->getReturnType();
2933
    // Ignore the attribute.
2934
0
    return;
2935
0
  }
2936
2937
16
  D->addAttr(new (S.Context) ObjCMethodFamilyAttr(S.Context, AL, F));
2938
16
}
2939
2940
15
static void handleObjCNSObject(Sema &S, Decl *D, const ParsedAttr &AL) {
2941
15
  if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) {
2942
9
    QualType T = TD->getUnderlyingType();
2943
9
    if (!T->isCARCBridgableType()) {
2944
1
      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
2945
1
      return;
2946
1
    }
2947
9
  }
2948
6
  else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) {
2949
4
    QualType T = PD->getType();
2950
4
    if (!T->isCARCBridgableType()) {
2951
1
      S.Diag(PD->getLocation(), diag::err_nsobject_attribute);
2952
1
      return;
2953
1
    }
2954
4
  }
2955
2
  else {
2956
    // It is okay to include this attribute on properties, e.g.:
2957
    //
2958
    //  @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
2959
    //
2960
    // In this case it follows tradition and suppresses an error in the above
2961
    // case.
2962
2
    S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
2963
2
  }
2964
13
  D->addAttr(::new (S.Context) ObjCNSObjectAttr(S.Context, AL));
2965
13
}
2966
2967
4.35k
static void handleObjCIndependentClass(Sema &S, Decl *D, const ParsedAttr &AL) {
2968
4.35k
  if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) {
2969
4.35k
    QualType T = TD->getUnderlyingType();
2970
4.35k
    if (!T->isObjCObjectPointerType()) {
2971
1
      S.Diag(TD->getLocation(), diag::warn_ptr_independentclass_attribute);
2972
1
      return;
2973
1
    }
2974
4.35k
  } else {
2975
4
    S.Diag(D->getLocation(), diag::warn_independentclass_attribute);
2976
4
    return;
2977
4
  }
2978
4.35k
  D->addAttr(::new (S.Context) ObjCIndependentClassAttr(S.Context, AL));
2979
4.35k
}
2980
2981
507
static void handleBlocksAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2982
507
  if (!AL.isArgIdent(0)) {
2983
0
    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
2984
0
        << AL << 1 << AANT_ArgumentIdentifier;
2985
0
    return;
2986
0
  }
2987
2988
507
  IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
2989
507
  BlocksAttr::BlockType type;
2990
507
  if (!BlocksAttr::ConvertStrToBlockType(II->getName(), type)) {
2991
0
    S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
2992
0
    return;
2993
0
  }
2994
2995
507
  D->addAttr(::new (S.Context) BlocksAttr(S.Context, AL, type));
2996
507
}
2997
2998
1.96k
static void handleSentinelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2999
1.96k
  unsigned sentinel = (unsigned)SentinelAttr::DefaultSentinel;
3000
1.96k
  if (AL.getNumArgs() > 0) {
3001
1.92k
    Expr *E = AL.getArgAsExpr(0);
3002
1.92k
    Optional<llvm::APSInt> Idx = llvm::APSInt(32);
3003
1.92k
    if (E->isTypeDependent() || !(Idx = E->getIntegerConstantExpr(S.Context))) {
3004
4
      S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3005
4
          << AL << 1 << AANT_ArgumentIntegerConstant << E->getSourceRange();
3006
4
      return;
3007
4
    }
3008
3009
1.92k
    if (Idx->isSigned() && Idx->isNegative()) {
3010
4
      S.Diag(AL.getLoc(), diag::err_attribute_sentinel_less_than_zero)
3011
4
        << E->getSourceRange();
3012
4
      return;
3013
4
    }
3014
3015
1.91k
    sentinel = Idx->getZExtValue();
3016
1.91k
  }
3017
3018
1.95k
  unsigned nullPos = (unsigned)SentinelAttr::DefaultNullPos;
3019
1.95k
  if (AL.getNumArgs() > 1) {
3020
1.87k
    Expr *E = AL.getArgAsExpr(1);
3021
1.87k
    Optional<llvm::APSInt> Idx = llvm::APSInt(32);
3022
1.87k
    if (E->isTypeDependent() || !(Idx = E->getIntegerConstantExpr(S.Context))) {
3023
0
      S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3024
0
          << AL << 2 << AANT_ArgumentIntegerConstant << E->getSourceRange();
3025
0
      return;
3026
0
    }
3027
1.87k
    nullPos = Idx->getZExtValue();
3028
3029
1.87k
    if ((Idx->isSigned() && Idx->isNegative()) || nullPos > 1) {
3030
      // FIXME: This error message could be improved, it would be nice
3031
      // to say what the bounds actually are.
3032
3
      S.Diag(AL.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
3033
3
        << E->getSourceRange();
3034
3
      return;
3035
3
    }
3036
1.87k
  }
3037
3038
1.95k
  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3039
61
    const FunctionType *FT = FD->getType()->castAs<FunctionType>();
3040
61
    if (isa<FunctionNoProtoType>(FT)) {
3041
2
      S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_named_arguments);
3042
2
      return;
3043
2
    }
3044
3045
59
    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
3046
4
      S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
3047
4
      return;
3048
4
    }
3049
1.89k
  } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
3050
1.87k
    if (!MD->isVariadic()) {
3051
1
      S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
3052
1
      return;
3053
1
    }
3054
1.87k
  } else 
if (const auto *16
BD16
= dyn_cast<BlockDecl>(D)) {
3055
4
    if (!BD->isVariadic()) {
3056
1
      S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
3057
1
      return;
3058
1
    }
3059
12
  } else if (const auto *V = dyn_cast<VarDecl>(D)) {
3060
12
    QualType Ty = V->getType();
3061
12
    if (Ty->isBlockPointerType() || 
Ty->isFunctionPointerType()7
) {
3062
9
      const FunctionType *FT = Ty->isFunctionPointerType()
3063
9
                                   ? 
D->getFunctionType()4
3064
9
                                   : Ty->castAs<BlockPointerType>()
3065
5
                                         ->getPointeeType()
3066
5
                                         ->castAs<FunctionType>();
3067
9
      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
3068
1
        int m = Ty->isFunctionPointerType() ? 
00
: 1;
3069
1
        S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
3070
1
        return;
3071
1
      }
3072
9
    } else {
3073
3
      S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
3074
3
          << AL << ExpectedFunctionMethodOrBlock;
3075
3
      return;
3076
3
    }
3077
12
  } else {
3078
0
    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
3079
0
        << AL << ExpectedFunctionMethodOrBlock;
3080
0
    return;
3081
0
  }
3082
1.93k
  D->addAttr(::new (S.Context) SentinelAttr(S.Context, AL, sentinel, nullPos));
3083
1.93k
}
3084
3085
37.3k
static void handleWarnUnusedResult(Sema &S, Decl *D, const ParsedAttr &AL) {
3086
37.3k
  if (D->getFunctionType() &&
3087
37.3k
      
D->getFunctionType()->getReturnType()->isVoidType()37.2k
&&
3088
37.3k
      
!isa<CXXConstructorDecl>(D)10
) {
3089
1
    S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) << AL << 0;
3090
1
    return;
3091
1
  }
3092
37.3k
  if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
3093
64
    if (MD->getReturnType()->isVoidType()) {
3094
1
      S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) << AL << 1;
3095
1
      return;
3096
1
    }
3097
3098
37.3k
  StringRef Str;
3099
37.3k
  if (AL.isStandardAttributeSyntax() && 
!AL.getScopeName()126
) {
3100
    // The standard attribute cannot be applied to variable declarations such
3101
    // as a function pointer.
3102
100
    if (isa<VarDecl>(D))
3103
5
      S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type_str)
3104
5
          << AL << "functions, classes, or enumerations";
3105
3106
    // If this is spelled as the standard C++17 attribute, but not in C++17,
3107
    // warn about using it as an extension. If there are attribute arguments,
3108
    // then claim it's a C++2a extension instead.
3109
    // FIXME: If WG14 does not seem likely to adopt the same feature, add an
3110
    // extension warning for C2x mode.
3111
100
    const LangOptions &LO = S.getLangOpts();
3112
100
    if (AL.getNumArgs() == 1) {
3113
32
      if (LO.CPlusPlus && 
!LO.CPlusPlus2031
)
3114
21
        S.Diag(AL.getLoc(), diag::ext_cxx20_attr) << AL;
3115
3116
      // Since this this is spelled [[nodiscard]], get the optional string
3117
      // literal. If in C++ mode, but not in C++2a mode, diagnose as an
3118
      // extension.
3119
      // FIXME: C2x should support this feature as well, even as an extension.
3120
32
      if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, nullptr))
3121
0
        return;
3122
68
    } else if (LO.CPlusPlus && 
!LO.CPlusPlus1757
)
3123
16
      S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
3124
100
  }
3125
3126
37.3k
  D->addAttr(::new (S.Context) WarnUnusedResultAttr(S.Context, AL, Str));
3127
37.3k
}
3128
3129
914
static void handleWeakImportAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3130
  // weak_import only applies to variable & function declarations.
3131
914
  bool isDef = false;
3132
914
  if (!D->canBeWeakImported(isDef)) {
3133
9
    if (isDef)
3134
3
      S.Diag(AL.getLoc(), diag::warn_attribute_invalid_on_definition)
3135
3
        << "weak_import";
3136
6
    else if (isa<ObjCPropertyDecl>(D) || 
isa<ObjCMethodDecl>(D)5
||
3137
6
             
(3
S.Context.getTargetInfo().getTriple().isOSDarwin()3
&&
3138
5
              
(3
isa<ObjCInterfaceDecl>(D)3
||
isa<EnumDecl>(D)3
))) {
3139
      // Nothing to warn about here.
3140
5
    } else
3141
1
      S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
3142
1
          << AL << ExpectedVariableOrFunction;
3143
3144
9
    return;
3145
9
  }
3146
3147
905
  D->addAttr(::new (S.Context) WeakImportAttr(S.Context, AL));
3148
905
}
3149
3150
// Handles reqd_work_group_size and work_group_size_hint.
3151
template <typename WorkGroupAttr>
3152
20
static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
3153
20
  uint32_t WGSize[3];
3154
71
  for (unsigned i = 0; i < 3; 
++i51
) {
3155
56
    const Expr *E = AL.getArgAsExpr(i);
3156
56
    if (!checkUInt32Argument(S, AL, E, WGSize[i], i,
3157
56
                             /*StrictlyUnsigned=*/true))
3158
2
      return;
3159
54
    if (WGSize[i] == 0) {
3160
3
      S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
3161
3
          << AL << E->getSourceRange();
3162
3
      return;
3163
3
    }
3164
54
  }
3165
3166
15
  WorkGroupAttr *Existing = D->getAttr<WorkGroupAttr>();
3167
15
  if (Existing && 
!(1
Existing->getXDim() == WGSize[0]1
&&
3168
1
                    
Existing->getYDim() == WGSize[1]0
&&
3169
1
                    
Existing->getZDim() == WGSize[2]0
))
3170
1
    S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3171
3172
15
  D->addAttr(::new (S.Context)
3173
15
                 WorkGroupAttr(S.Context, AL, WGSize[0], WGSize[1], WGSize[2]));
3174
15
}
SemaDeclAttr.cpp:void handleWorkGroupSize<clang::WorkGroupSizeHintAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
3152
6
static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
3153
6
  uint32_t WGSize[3];
3154
22
  for (unsigned i = 0; i < 3; 
++i16
) {
3155
17
    const Expr *E = AL.getArgAsExpr(i);
3156
17
    if (!checkUInt32Argument(S, AL, E, WGSize[i], i,
3157
17
                             /*StrictlyUnsigned=*/true))
3158
1
      return;
3159
16
    if (WGSize[i] == 0) {
3160
0
      S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
3161
0
          << AL << E->getSourceRange();
3162
0
      return;
3163
0
    }
3164
16
  }
3165
3166
5
  WorkGroupAttr *Existing = D->getAttr<WorkGroupAttr>();
3167
5
  if (Existing && 
!(1
Existing->getXDim() == WGSize[0]1
&&
3168
1
                    
Existing->getYDim() == WGSize[1]0
&&
3169
1
                    
Existing->getZDim() == WGSize[2]0
))
3170
1
    S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3171
3172
5
  D->addAttr(::new (S.Context)
3173
5
                 WorkGroupAttr(S.Context, AL, WGSize[0], WGSize[1], WGSize[2]));
3174
5
}
SemaDeclAttr.cpp:void handleWorkGroupSize<clang::ReqdWorkGroupSizeAttr>(clang::Sema&, clang::Decl*, clang::ParsedAttr const&)
Line
Count
Source
3152
14
static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
3153
14
  uint32_t WGSize[3];
3154
49
  for (unsigned i = 0; i < 3; 
++i35
) {
3155
39
    const Expr *E = AL.getArgAsExpr(i);
3156
39
    if (!checkUInt32Argument(S, AL, E, WGSize[i], i,
3157
39
                             /*StrictlyUnsigned=*/true))
3158
1
      return;
3159
38
    if (WGSize[i] == 0) {
3160
3
      S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
3161
3
          << AL << E->getSourceRange();
3162
3
      return;
3163
3
    }
3164
38
  }
3165
3166
10
  WorkGroupAttr *Existing = D->getAttr<WorkGroupAttr>();
3167
10
  if (Existing && 
!(0
Existing->getXDim() == WGSize[0]0
&&
3168
0
                    Existing->getYDim() == WGSize[1] &&
3169
0
                    Existing->getZDim() == WGSize[2]))
3170
0
    S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3171
3172
10
  D->addAttr(::new (S.Context)
3173
10
                 WorkGroupAttr(S.Context, AL, WGSize[0], WGSize[1], WGSize[2]));
3174
10
}
3175
3176
// Handles intel_reqd_sub_group_size.
3177
6
static void handleSubGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
3178
6
  uint32_t SGSize;
3179
6
  const Expr *E = AL.getArgAsExpr(0);
3180
6
  if (!checkUInt32Argument(S, AL, E, SGSize))
3181
0
    return;
3182
6
  if (SGSize == 0) {
3183
1
    S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
3184
1
        << AL << E->getSourceRange();
3185
1
    return;
3186
1
  }
3187
3188
5
  OpenCLIntelReqdSubGroupSizeAttr *Existing =
3189
5
      D->getAttr<OpenCLIntelReqdSubGroupSizeAttr>();
3190
5
  if (Existing && 
Existing->getSubGroupSize() != SGSize1
)
3191
1
    S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3192
3193
5
  D->addAttr(::new (S.Context)
3194
5
                 OpenCLIntelReqdSubGroupSizeAttr(S.Context, AL, SGSize));
3195
5
}
3196
3197
8
static void handleVecTypeHint(Sema &S, Decl *D, const ParsedAttr &AL) {
3198
8
  if (!AL.hasParsedType()) {
3199
0
    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
3200
0
    return;
3201
0
  }
3202
3203
8
  TypeSourceInfo *ParmTSI = nullptr;
3204
8
  QualType ParmType = S.GetTypeFromParser(AL.getTypeArg(), &ParmTSI);
3205
8
  assert(ParmTSI && "no type source info for attribute argument");
3206
3207
8
  if (!ParmType->isExtVectorType() && 
!ParmType->isFloatingType()7
&&
3208
8
      
(6
ParmType->isBooleanType()6
||
3209
6
       
!ParmType->isIntegralType(S.getASTContext())5
)) {
3210
2
    S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument) << 2 << AL;
3211
2
    return;
3212
2
  }
3213
3214
6
  if (VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>()) {
3215
1
    if (!S.Context.hasSameType(A->getTypeHint(), ParmType)) {
3216
1
      S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3217
1
      return;
3218
1
    }
3219
1
  }
3220
3221
5
  D->addAttr(::new (S.Context) VecTypeHintAttr(S.Context, AL, ParmTSI));
3222
5
}
3223
3224
SectionAttr *Sema::mergeSectionAttr(Decl *D, const AttributeCommonInfo &CI,
3225
1.28k
                                    StringRef Name) {
3226
  // Explicit or partial specializations do not inherit
3227
  // the section attribute from the primary template.
3228
1.28k
  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3229
68
    if (CI.getAttributeSpellingListIndex() == SectionAttr::Declspec_allocate &&
3230
68
        
FD->isFunctionTemplateSpecialization()3
)
3231
3
      return nullptr;
3232
68
  }
3233
1.28k
  if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
3234
7
    if (ExistingAttr->getName() == Name)
3235
0
      return nullptr;
3236
7
    Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section)
3237
7
         << 1 /*section*/;
3238
7
    Diag(CI.getLoc(), diag::note_previous_attribute);
3239
7
    return nullptr;
3240
7
  }
3241
1.27k
  return ::new (Context) SectionAttr(Context, CI, Name);
3242
1.28k
}
3243
3244
/// Used to implement to perform semantic checking on
3245
/// attribute((section("foo"))) specifiers.
3246
///
3247
/// In this case, "foo" is passed in to be checked.  If the section
3248
/// specifier is invalid, return an Error that indicates the problem.
3249
///
3250
/// This is a simple quality of implementation feature to catch errors
3251
/// and give good diagnostics in cases when the assembler or code generator
3252
/// would otherwise reject the section specifier.
3253
1.43k
llvm::Error Sema::isValidSectionSpecifier(StringRef SecName) {
3254
1.43k
  if (!Context.getTargetInfo().getTriple().isOSDarwin())
3255
253
    return llvm::Error::success();
3256
3257
  // Let MCSectionMachO validate this.
3258
1.18k
  StringRef Segment, Section;
3259
1.18k
  unsigned TAA, StubSize;
3260
1.18k
  bool HasTAA;
3261
1.18k
  return llvm::MCSectionMachO::ParseSectionSpecifier(SecName, Segment, Section,
3262
1.18k
                                                     TAA, HasTAA, StubSize);
3263
1.43k
}
3264
3265
1.30k
bool Sema::checkSectionName(SourceLocation LiteralLoc, StringRef SecName) {
3266
1.30k
  if (llvm::Error E = isValidSectionSpecifier(SecName)) {
3267
2
    Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
3268
2
        << toString(std::move(E)) << 1 /*'section'*/;
3269
2
    return false;
3270
2
  }
3271
1.30k
  return true;
3272
1.30k
}
3273
3274
1.26k
static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3275
  // Make sure that there is a string literal as the sections's single
3276
  // argument.
3277
1.26k
  StringRef Str;
3278
1.26k
  SourceLocation LiteralLoc;
3279
1.26k
  if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))
3280
2
    return;
3281
3282
1.25k
  if (!S.checkSectionName(LiteralLoc, Str))
3283
1
    return;
3284
3285
1.25k
  SectionAttr *NewAttr = S.mergeSectionAttr(D, AL, Str);
3286
1.25k
  if (NewAttr) {
3287
1.25k
    D->addAttr(NewAttr);
3288
1.25k
    if (isa<FunctionDecl, FunctionTemplateDecl, ObjCMethodDecl,
3289
1.25k
            ObjCPropertyDecl>(D))
3290
50
      S.UnifySection(NewAttr->getName(),
3291
50
                     ASTContext::PSF_Execute | ASTContext::PSF_Read,
3292
50
                     cast<NamedDecl>(D));
3293
1.25k
  }
3294
1.25k
}
3295
3296
// This is used for `__declspec(code_seg("segname"))` on a decl.
3297
// `#pragma code_seg("segname")` uses checkSectionName() instead.
3298
static bool checkCodeSegName(Sema &S, SourceLocation LiteralLoc,
3299
83
                             StringRef CodeSegName) {
3300
83
  if (llvm::Error E = S.isValidSectionSpecifier(CodeSegName)) {
3301
0
    S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
3302
0
        << toString(std::move(E)) << 0 /*'code-seg'*/;
3303
0
    return false;
3304
0
  }
3305
3306
83
  return true;
3307
83
}
3308
3309
CodeSegAttr *Sema::mergeCodeSegAttr(Decl *D, const AttributeCommonInfo &CI,
3310
94
                                    StringRef Name) {
3311
  // Explicit or partial specializations do not inherit
3312
  // the code_seg attribute from the primary template.
3313
94
  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3314
46
    if (FD->isFunctionTemplateSpecialization())
3315
3
      return nullptr;
3316
46
  }
3317
91
  if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) {
3318
14
    if (ExistingAttr->getName() == Name)
3319
12
      return nullptr;
3320
2
    Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section)
3321
2
         << 0 /*codeseg*/;
3322
2
    Diag(CI.getLoc(), diag::note_previous_attribute);
3323
2
    return nullptr;
3324
14
  }
3325
77
  return ::new (Context) CodeSegAttr(Context, CI, Name);
3326
91
}
3327
3328
83
static void handleCodeSegAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3329
83
  StringRef Str;
3330
83
  SourceLocation LiteralLoc;
3331
83
  if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))
3332
0
    return;
3333
83
  if (!checkCodeSegName(S, LiteralLoc, Str))
3334
0
    return;
3335
83
  if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) {
3336
14
    if (!ExistingAttr->isImplicit()) {
3337
6
      S.Diag(AL.getLoc(),
3338
6
             ExistingAttr->getName() == Str
3339
6
             ? 
diag::warn_duplicate_codeseg_attribute3
3340
6
             : 
diag::err_conflicting_codeseg_attribute3
);
3341
6
      return;
3342
6
    }
3343
8
    D->dropAttr<CodeSegAttr>();
3344
8
  }
3345
77
  if (CodeSegAttr *CSA = S.mergeCodeSegAttr(D, AL, Str))
3346
77
    D->addAttr(CSA);
3347
77
}
3348
3349
// Check for things we'd like to warn about. Multiversioning issues are
3350
// handled later in the process, once we know how many exist.
3351
1.14M
bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) {
3352
1.14M
  enum FirstParam { Unsupported, Duplicate, Unknown };
3353
1.14M
  enum SecondParam { None, Architecture, Tune };
3354
1.14M
  enum ThirdParam { Target, TargetClones };
3355
1.14M
  if (AttrStr.contains("fpmath="))
3356
2
    return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3357
2
           << Unsupported << None << "fpmath=" << Target;
3358
3359
  // Diagnose use of tune if target doesn't support it.
3360
1.14M
  if (!Context.getTargetInfo().supportsTargetAttributeTune() &&
3361
1.14M
      
AttrStr.contains("tune=")556
)
3362
1
    return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3363
1
           << Unsupported << None << "tune=" << Target;
3364
3365
1.14M
  ParsedTargetAttr ParsedAttrs = TargetAttr::parse(AttrStr);
3366
3367
1.14M
  if (!ParsedAttrs.Architecture.empty() &&
3368
1.14M
      
!Context.getTargetInfo().isValidCPUName(ParsedAttrs.Architecture)165
)
3369
3
    return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3370
3
           << Unknown << Architecture << ParsedAttrs.Architecture << Target;
3371
3372
1.14M
  if (!ParsedAttrs.Tune.empty() &&
3373
1.14M
      
!Context.getTargetInfo().isValidCPUName(ParsedAttrs.Tune)3
)
3374
1
    return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3375
1
           << Unknown << Tune << ParsedAttrs.Tune << Target;
3376
3377
1.14M
  if (ParsedAttrs.DuplicateArchitecture)
3378
1
    return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3379
1
           << Duplicate << None << "arch=" << Target;
3380
1.14M
  if (ParsedAttrs.DuplicateTune)
3381
0
    return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3382
0
           << Duplicate << None << "tune=" << Target;
3383
3384
1.33M
  
for (const auto &Feature : ParsedAttrs.Features)1.14M
{
3385
1.33M
    auto CurFeature = StringRef(Feature).drop_front(); // remove + or -.
3386
1.33M
    if (!Context.getTargetInfo().isValidFeatureName(CurFeature))
3387
4
      return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3388
4
             << Unsupported << None << CurFeature << Target;
3389
1.33M
  }
3390
3391
1.14M
  TargetInfo::BranchProtectionInfo BPI;
3392
1.14M
  StringRef DiagMsg;
3393
1.14M
  if (ParsedAttrs.BranchProtection.empty())
3394
1.14M
    return false;
3395
36
  if (!Context.getTargetInfo().validateBranchProtection(
3396
36
          ParsedAttrs.BranchProtection, BPI, DiagMsg)) {
3397
15
    if (DiagMsg.empty())
3398
1
      return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3399
1
             << Unsupported << None << "branch-protection" << Target;
3400
14
    return Diag(LiteralLoc, diag::err_invalid_branch_protection_spec)
3401
14
           << DiagMsg;
3402
15
  }
3403
21
  if (!DiagMsg.empty())
3404
2
    Diag(LiteralLoc, diag::warn_unsupported_branch_protection_spec) << DiagMsg;
3405
3406
21
  return false;
3407
36
}
3408
3409
1.14M
static void handleTargetAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3410
1.14M
  StringRef Str;
3411
1.14M
  SourceLocation LiteralLoc;
3412
1.14M
  if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc) ||
3413
1.14M
      S.checkTargetAttr(LiteralLoc, Str))
3414
27
    return;
3415
3416
1.14M
  TargetAttr *NewAttr = ::new (S.Context) TargetAttr(S.Context, AL, Str);
3417
1.14M
  D->addAttr(NewAttr);
3418
1.14M
}
3419
3420
bool Sema::checkTargetClonesAttrString(SourceLocation LiteralLoc, StringRef Str,
3421
                                       const StringLiteral *Literal,
3422
                                       bool &HasDefault, bool &HasCommas,
3423
74
                                       SmallVectorImpl<StringRef> &Strings) {
3424
74
  enum FirstParam { Unsupported, Duplicate, Unknown };
3425
74
  enum SecondParam { None, Architecture, Tune };
3426
74
  enum ThirdParam { Target, TargetClones };
3427
74
  HasCommas = HasCommas || 
Str.contains(',')72
;
3428
  // Warn on empty at the beginning of a string.
3429
74
  if (Str.size() == 0)
3430
2
    return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3431
2
           << Unsupported << None << "" << TargetClones;
3432
3433
72
  std::pair<StringRef, StringRef> Parts = {{}, Str};
3434
174
  while (!Parts.second.empty()) {
3435
104
    Parts = Parts.second.split(',');
3436
104
    StringRef Cur = Parts.first.trim();
3437
104
    SourceLocation CurLoc = Literal->getLocationOfByte(
3438
104
        Cur.data() - Literal->getString().data(), getSourceManager(),
3439
104
        getLangOpts(), Context.getTargetInfo());
3440
3441
104
    bool DefaultIsDupe = false;
3442
104
    if (Cur.empty())
3443
2
      return Diag(CurLoc, diag::warn_unsupported_target_attribute)
3444
2
             << Unsupported << None << "" << TargetClones;
3445
3446
102
    if (Cur.startswith("arch=")) {
3447
18
      if (!Context.getTargetInfo().isValidCPUName(
3448
18
              Cur.drop_front(sizeof("arch=") - 1)))
3449
0
        return Diag(CurLoc, diag::warn_unsupported_target_attribute)
3450
0
               << Unsupported << Architecture
3451
0
               << Cur.drop_front(sizeof("arch=") - 1) << TargetClones;
3452
84
    } else if (Cur == "default") {
3453
47
      DefaultIsDupe = HasDefault;
3454
47
      HasDefault = true;
3455
47
    } else 
if (37
!Context.getTargetInfo().isValidFeatureName(Cur)37
)
3456
0
      return Diag(CurLoc, diag::warn_unsupported_target_attribute)
3457
0
             << Unsupported << None << Cur << TargetClones;
3458
3459
102
    if (llvm::find(Strings, Cur) != Strings.end() || 
DefaultIsDupe96
)
3460
6
      Diag(CurLoc, diag::warn_target_clone_duplicate_options);
3461
    // Note: Add even if there are duplicates, since it changes name mangling.
3462
102
    Strings.push_back(Cur);
3463
102
  }
3464
3465
70
  if (Str.rtrim().endswith(","))
3466
1
    return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3467
1
           << Unsupported << None << "" << TargetClones;
3468
69
  return false;
3469
70
}
3470
3471
48
static void handleTargetClonesAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3472
  // Ensure we don't combine these with themselves, since that causes some
3473
  // confusing behavior.
3474
48
  if (const auto *Other = D->getAttr<TargetClonesAttr>()) {
3475
1
    S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL;
3476
1
    S.Diag(Other->getLocation(), diag::note_conflicting_attribute);
3477
1
    return;
3478
1
  }
3479
47
  if (checkAttrMutualExclusion<TargetClonesAttr>(S, D, AL))
3480
0
    return;
3481
3482
47
  SmallVector<StringRef, 2> Strings;
3483
47
  bool HasCommas = false, HasDefault = false;
3484
3485
116
  for (unsigned I = 0, E = AL.getNumArgs(); I != E; 
++I69
) {
3486
74
    StringRef CurStr;
3487
74
    SourceLocation LiteralLoc;
3488
74
    if (!S.checkStringLiteralArgumentAttr(AL, I, CurStr, &LiteralLoc) ||
3489
74
        S.checkTargetClonesAttrString(
3490
74
            LiteralLoc, CurStr,
3491
74
            cast<StringLiteral>(AL.getArgAsExpr(I)->IgnoreParenCasts()),
3492
74
            HasDefault, HasCommas, Strings))
3493
5
      return;
3494
74
  }
3495
3496
42
  if (HasCommas && 
AL.getNumArgs() > 120
)
3497
1
    S.Diag(AL.getLoc(), diag::warn_target_clone_mixed_values);
3498
3499
42
  if (!HasDefault) {
3500
1
    S.Diag(AL.getLoc(), diag::err_target_clone_must_have_default);
3501
1
    return;
3502
1
  }
3503
3504
  // FIXME: We could probably figure out how to get this to work for lambdas
3505
  // someday.
3506
41
  if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
3507
7
    if (MD->getParent()->isLambda()) {
3508
1
      S.Diag(D->getLocation(), diag::err_multiversion_doesnt_support)
3509
1
          << static_cast<unsigned>(MultiVersionKind::TargetClones)
3510
1
          << /*Lambda*/ 9;
3511
1
      return;
3512
1
    }
3513
7
  }
3514
3515
40
  cast<FunctionDecl>(D)->setIsMultiVersion();
3516
40
  TargetClonesAttr *NewAttr = ::new (S.Context)
3517
40
      TargetClonesAttr(S.Context, AL, Strings.data(), Strings.size());
3518
40
  D->addAttr(NewAttr);
3519
40
}
3520
3521
1.08M
static void handleMinVectorWidthAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3522
1.08M
  Expr *E = AL.getArgAsExpr(0);
3523
1.08M
  uint32_t VecWidth;
3524
1.08M
  if (!checkUInt32Argument(S, AL, E, VecWidth)) {
3525
1
    AL.setInvalid();
3526
1
    return;
3527
1
  }
3528
3529
1.08M
  MinVectorWidthAttr *Existing = D->getAttr<MinVectorWidthAttr>();
3530
1.08M
  if (Existing && 
Existing->getVectorWidth() != VecWidth1
) {
3531
1
    S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3532
1
    return;
3533
1
  }
3534
3535
1.08M
  D->addAttr(::new (S.Context) MinVectorWidthAttr(S.Context, AL, VecWidth));
3536
1.08M
}
3537
3538
40
static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3539
40
  Expr *E = AL.getArgAsExpr(0);
3540
40
  SourceLocation Loc = E->getExprLoc();
3541
40
  FunctionDecl *FD = nullptr;
3542
40
  DeclarationNameInfo NI;
3543
3544
  // gcc only allows for simple identifiers. Since we support more than gcc, we
3545
  // will warn the user.
3546
40
  if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
3547
37
    if (DRE->hasQualifier())
3548
4
      S.Diag(Loc, diag::warn_cleanup_ext);
3549
37
    FD = dyn_cast<FunctionDecl>(DRE->getDecl());
3550
37
    NI = DRE->getNameInfo();
3551
37
    if (!FD) {
3552
1
      S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 1
3553
1
        << NI.getName();
3554
1
      return;
3555
1
    }
3556
37
  } else 
if (auto *3
ULE3
= dyn_cast<UnresolvedLookupExpr>(E)) {
3557
2
    if (ULE->hasExplicitTemplateArgs())
3558
1
      S.Diag(Loc, diag::warn_cleanup_ext);
3559
2
    FD = S.ResolveSingleFunctionTemplateSpecialization(ULE, true);
3560
2
    NI = ULE->getNameInfo();
3561
2
    if (!FD) {
3562
1
      S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 2
3563
1
        << NI.getName();
3564
1
      if (ULE->getType() == S.Context.OverloadTy)
3565
1
        S.NoteAllOverloadCandidates(ULE);
3566
1
      return;
3567
1
    }
3568
2
  } else {
3569
1
    S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 0;
3570
1
    return;
3571
1
  }
3572
3573
37
  if (FD->getNumParams() != 1) {
3574
1
    S.Diag(Loc, diag::err_attribute_cleanup_func_must_take_one_arg)
3575
1
      << NI.getName();
3576
1
    return;
3577
1
  }
3578
3579
  // We're currently more strict than GCC about what function types we accept.
3580
  // If this ever proves to be a problem it should be easy to fix.
3581
36
  QualType Ty = S.Context.getPointerType(cast<VarDecl>(D)->getType());
3582
36
  QualType ParamTy = FD->getParamDecl(0)->getType();
3583
36
  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
3584
36
                                   ParamTy, Ty) != Sema::Compatible) {
3585
1
    S.Diag(Loc, diag::err_attribute_cleanup_func_arg_incompatible_type)
3586
1
      << NI.getName() << ParamTy << Ty;
3587
1
    return;
3588
1
  }
3589
3590
35
  D->addAttr(::new (S.Context) CleanupAttr(S.Context, AL, FD));
3591
35
}
3592
3593
static void handleEnumExtensibilityAttr(Sema &S, Decl *D,
3594
97.2k
                                        const ParsedAttr &AL) {
3595
97.2k
  if (!AL.isArgIdent(0)) {
3596
0
    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3597
0
        << AL << 0 << AANT_ArgumentIdentifier;
3598
0
    return;
3599
0
  }
3600
3601
97.2k
  EnumExtensibilityAttr::Kind ExtensibilityKind;
3602
97.2k
  IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
3603
97.2k
  if (!EnumExtensibilityAttr::ConvertStrToKind(II->getName(),
3604
97.2k
                                               ExtensibilityKind)) {
3605
1
    S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
3606
1
    return;
3607
1
  }
3608
3609
97.2k
  D->addAttr(::new (S.Context)
3610
97.2k
                 EnumExtensibilityAttr(S.Context, AL, ExtensibilityKind));
3611
97.2k
}
3612
3613
/// Handle __attribute__((format_arg((idx)))) attribute based on
3614
/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
3615
793
static void handleFormatArgAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3616
793
  Expr *IdxExpr = AL.getArgAsExpr(0);
3617
793
  ParamIdx Idx;
3618
793
  if (!checkFunctionOrMethodParameterIndex(S, D, AL, 1, IdxExpr, Idx))
3619
2
    return;
3620
3621
  // Make sure the format string is really a string.
3622
791
  QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex());
3623
3624
791
  bool NotNSStringTy = !isNSStringType(Ty, S.Context);
3625
791
  if (NotNSStringTy &&
3626
791
      
!isCFStringType(Ty, S.Context)559
&&
3627
791
      
(338
!Ty->isPointerType()338
||
3628
338
       
!Ty->castAs<PointerType>()->getPointeeType()->isCharType()336
)) {
3629
2
    S.Diag(AL.getLoc(), diag::err_format_attribute_not)
3630
2
        << "a string type" << IdxExpr->getSourceRange()
3631
2
        << getFunctionOrMethodParamRange(D, 0);
3632
2
    return;
3633
2
  }
3634
789
  Ty = getFunctionOrMethodResultType(D);
3635
  // replace instancetype with the class type
3636
789
  auto Instancetype = S.Context.getObjCInstanceTypeDecl()->getTypeForDecl();
3637
789
  if (Ty->getAs<TypedefType>() == Instancetype)
3638
116
    if (auto *OMD = dyn_cast<ObjCMethodDecl>(D))
3639
5
      if (auto *Interface = OMD->getClassInterface())
3640
4
        Ty = S.Context.getObjCObjectPointerType(
3641
4
            QualType(Interface->getTypeForDecl(), 0));
3642
789
  if (!isNSStringType(Ty, S.Context, /*AllowNSAttributedString=*/true) &&
3643
789
      
!isCFStringType(Ty, S.Context)557
&&
3644
789
      
(115
!Ty->isPointerType()115
||
3645
115
       
!Ty->castAs<PointerType>()->getPointeeType()->isCharType()113
)) {
3646
2
    S.Diag(AL.getLoc(), diag::err_format_attribute_result_not)
3647
2
        << (NotNSStringTy ? 
"string type"1
:
"NSString"1
)
3648
2
        << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0);
3649
2
    return;
3650
2
  }
3651
3652
787
  D->addAttr(::new (S.Context) FormatArgAttr(S.Context, AL, Idx));
3653
787
}
3654
3655
enum FormatAttrKind {
3656
  CFStringFormat,
3657
  NSStringFormat,
3658
  StrftimeFormat,
3659
  SupportedFormat,
3660
  IgnoredFormat,
3661
  InvalidFormat
3662
};
3663
3664
/// getFormatAttrKind - Map from format attribute names to supported format
3665
/// types.
3666
35.3k
static FormatAttrKind getFormatAttrKind(StringRef Format) {
3667
35.3k
  return llvm::StringSwitch<FormatAttrKind>(Format)
3668
      // Check for formats that get handled specially.
3669
35.3k
      .Case("NSString", NSStringFormat)
3670
35.3k
      .Case("CFString", CFStringFormat)
3671
35.3k
      .Case("strftime", StrftimeFormat)
3672
3673
      // Otherwise, check for supported formats.
3674
35.3k
      .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat)
3675
35.3k
      .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat)
3676
35.3k
      .Case("kprintf", SupportedFormat)         // OpenBSD.
3677
35.3k
      .Case("freebsd_kprintf", SupportedFormat) // FreeBSD.
3678
35.3k
      .Case("os_trace", SupportedFormat)
3679
35.3k
      .Case("os_log", SupportedFormat)
3680
3681
35.3k
      .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat)
3682
35.3k
      .Default(InvalidFormat);
3683
35.3k
}
3684
3685
/// Handle __attribute__((init_priority(priority))) attributes based on
3686
/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
3687
1.14k
static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3688
1.14k
  if (!S.getLangOpts().CPlusPlus) {
3689
0
    S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
3690
0
    return;
3691
0
  }
3692
3693
1.14k
  if (S.getCurFunctionOrMethodDecl()) {
3694
2
    S.Diag(AL.getLoc(), diag::err_init_priority_object_attr);
3695
2
    AL.setInvalid();
3696
2
    return;
3697
2
  }
3698
1.14k
  QualType T = cast<VarDecl>(D)->getType();
3699
1.14k
  if (S.Context.getAsArrayType(T))
3700
6
    T = S.Context.getBaseElementType(T);
3701
1.14k
  if (!T->getAs<RecordType>()) {
3702
2
    S.Diag(AL.getLoc(), diag::err_init_priority_object_attr);
3703
2
    AL.setInvalid();
3704
2
    return;
3705
2
  }
3706
3707
1.14k
  Expr *E = AL.getArgAsExpr(0);
3708
1.14k
  uint32_t prioritynum;
3709
1.14k
  if (!checkUInt32Argument(S, AL, E, prioritynum)) {
3710
2
    AL.setInvalid();
3711
2
    return;
3712
2
  }
3713
3714
  // Only perform the priority check if the attribute is outside of a system
3715
  // header. Values <= 100 are reserved for the implementation, and libc++
3716
  // benefits from being able to specify values in that range.
3717
1.13k
  if ((prioritynum < 101 || 
prioritynum > 655351.13k
) &&
3718
1.13k
      
!S.getSourceManager().isInSystemHeader(AL.getLoc())4
) {
3719
2
    S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_range)
3720
2
        << E->getSourceRange() << AL << 101 << 65535;
3721
2
    AL.setInvalid();
3722
2
    return;
3723
2
  }
3724
1.13k
  D->addAttr(::new (S.Context) InitPriorityAttr(S.Context, AL, prioritynum));
3725
1.13k
}
3726
3727
ErrorAttr *Sema::mergeErrorAttr(Decl *D, const AttributeCommonInfo &CI,
3728
63
                                StringRef NewUserDiagnostic) {
3729
63
  if (const auto *EA = D->getAttr<ErrorAttr>()) {
3730
17
    std::string NewAttr = CI.getNormalizedFullName();
3731
17
    assert((NewAttr == "error" || NewAttr == "warning") &&
3732
17
           "unexpected normalized full name");
3733
17
    bool Match = (EA->isError() && 
NewAttr == "error"8
) ||
3734
17
                 
(10
EA->isWarning()10
&&
NewAttr == "warning"9
);
3735
17
    if (!Match) {
3736
3
      Diag(EA->getLocation(), diag::err_attributes_are_not_compatible)
3737
3
          << CI << EA;
3738
3
      Diag(CI.getLoc(), diag::note_conflicting_attribute);
3739
3
      return nullptr;
3740
3
    }
3741
14
    if (EA->getUserDiagnostic() != NewUserDiagnostic) {
3742
8
      Diag(CI.getLoc(), diag::warn_duplicate_attribute) << EA;
3743
8
      Diag(EA->getLoc(), diag::note_previous_attribute);
3744
8
    }
3745
14
    D->dropAttr<ErrorAttr>();
3746
14
  }
3747
60
  return ::new (Context) ErrorAttr(Context, CI, NewUserDiagnostic);
3748
63
}
3749
3750
FormatAttr *Sema::mergeFormatAttr(Decl *D, const AttributeCommonInfo &CI,
3751
                                  IdentifierInfo *Format, int FormatIdx,
3752
36.1k
                                  int FirstArg) {
3753
  // Check whether we already have an equivalent format attribute.
3754
36.1k
  for (auto *F : D->specific_attrs<FormatAttr>()) {
3755
298
    if (F->getType() == Format &&
3756
298
        
F->getFormatIdx() == FormatIdx284
&&
3757
298
        
F->getFirstArg() == FirstArg284
) {
3758
      // If we don't have a valid location for this attribute, adopt the
3759
      // location.
3760
284
      if (F->getLocation().isInvalid())
3761
0
        F->setRange(CI.getRange());
3762
284
      return nullptr;
3763
284
    }
3764
298
  }
3765
3766
35.8k
  return ::new (Context) FormatAttr(Context, CI, Format, FormatIdx, FirstArg);
3767
36.1k
}
3768
3769
/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
3770
/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
3771
35.3k
static void handleFormatAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3772
35.3k
  if (!AL.isArgIdent(0)) {
3773
0
    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3774
0
        << AL << 1 << AANT_ArgumentIdentifier;
3775
0
    return;
3776
0
  }
3777
3778
  // In C++ the implicit 'this' function parameter also counts, and they are
3779
  // counted from one.
3780
35.3k
  bool HasImplicitThisParam = isInstanceMethod(D);
3781
35.3k
  unsigned NumArgs = getFunctionOrMethodNumParams(D) + HasImplicitThisParam;
3782
3783
35.3k
  IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
3784
35.3k
  StringRef Format = II->getName();
3785
3786
35.3k
  if (normalizeName(Format)) {
3787
    // If we've modified the string name, we need a new identifier for it.
3788
33.2k
    II = &S.Context.Idents.get(Format);
3789
33.2k
  }
3790
3791
  // Check for supported formats.
3792
35.3k
  FormatAttrKind Kind = getFormatAttrKind(Format);
3793
3794
35.3k
  if (Kind == IgnoredFormat)
3795
4
    return;
3796
3797
35.3k
  if (Kind == InvalidFormat) {
3798
0
    S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
3799
0
        << AL << II->getName();
3800
0
    return;
3801
0
  }
3802
3803
  // checks for the 2nd argument
3804
35.3k
  Expr *IdxExpr = AL.getArgAsExpr(1);
3805
35.3k
  uint32_t Idx;
3806
35.3k
  if (!checkUInt32Argument(S, AL, IdxExpr, Idx, 2))
3807
0
    return;
3808
3809
35.3k
  if (Idx < 1 || 
Idx > NumArgs35.3k
) {
3810
3
    S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
3811
3
        << AL << 2 << IdxExpr->getSourceRange();
3812
3
    return;
3813
3
  }
3814
3815
  // FIXME: Do we need to bounds check?
3816
35.3k
  unsigned ArgIdx = Idx - 1;
3817
3818
35.3k
  if (HasImplicitThisParam) {
3819
76
    if (ArgIdx == 0) {
3820
4
      S.Diag(AL.getLoc(),
3821
4
             diag::err_format_attribute_implicit_this_format_string)
3822
4
        << IdxExpr->getSourceRange();
3823
4
      return;
3824
4
    }
3825
72
    ArgIdx--;
3826
72
  }
3827
3828
  // make sure the format string is really a string
3829
35.3k
  QualType Ty = getFunctionOrMethodParamType(D, ArgIdx);
3830
3831
35.3k
  if (Kind == CFStringFormat) {
3832
892
    if (!isCFStringType(Ty, S.Context)) {
3833
1
      S.Diag(AL.getLoc(), diag::err_format_attribute_not)
3834
1
        << "a CFString" << IdxExpr->getSourceRange()
3835
1
        << getFunctionOrMethodParamRange(D, ArgIdx);
3836
1
      return;
3837
1
    }
3838
34.4k
  } else if (Kind == NSStringFormat) {
3839
    // FIXME: do we need to check if the type is NSString*?  What are the
3840
    // semantics?
3841
3.15k
    if (!isNSStringType(Ty, S.Context, /*AllowNSAttributedString=*/true)) {
3842
1
      S.Diag(AL.getLoc(), diag::err_format_attribute_not)
3843
1
        << "an NSString" << IdxExpr->getSourceRange()
3844
1
        << getFunctionOrMethodParamRange(D, ArgIdx);
3845
1
      return;
3846
1
    }
3847
31.3k
  } else if (!Ty->isPointerType() ||
3848
31.3k
             
!Ty->castAs<PointerType>()->getPointeeType()->isCharType()31.2k
) {
3849
8
    S.Diag(AL.getLoc(), diag::err_format_attribute_not)
3850
8
      << "a string type" << IdxExpr->getSourceRange()
3851
8
      << getFunctionOrMethodParamRange(D, ArgIdx);
3852
8
    return;
3853
8
  }
3854
3855
  // check the 3rd argument
3856
35.3k
  Expr *FirstArgExpr = AL.getArgAsExpr(2);
3857
35.3k
  uint32_t FirstArg;
3858
35.3k
  if (!checkUInt32Argument(S, AL, FirstArgExpr, FirstArg, 3))
3859
0
    return;
3860
3861
  // check if the function is variadic if the 3rd argument non-zero
3862
35.3k
  if (FirstArg != 0) {
3863
17.6k
    if (isFunctionOrMethodVariadic(D)) {
3864
17.6k
      ++NumArgs; // +1 for ...
3865
17.6k
    } else {
3866
3
      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
3867
3
      return;
3868
3
    }
3869
17.6k
  }
3870
3871
  // strftime requires FirstArg to be 0 because it doesn't read from any
3872
  // variable the input is just the current time + the format string.
3873
35.3k
  if (Kind == StrftimeFormat) {
3874
196
    if (FirstArg != 0) {
3875
1
      S.Diag(AL.getLoc(), diag::err_format_strftime_third_parameter)
3876
1
        << FirstArgExpr->getSourceRange();
3877
1
      return;
3878
1
    }
3879
  // if 0 it disables parameter checking (to use with e.g. va_list)
3880
35.1k
  } else if (FirstArg != 0 && 
FirstArg != NumArgs17.6k
) {
3881
4
    S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
3882
4
        << AL << 3 << FirstArgExpr->getSourceRange();
3883
4
    return;
3884
4
  }
3885
3886
35.3k
  FormatAttr *NewAttr = S.mergeFormatAttr(D, AL, II, Idx, FirstArg);
3887
35.3k
  if (NewAttr)
3888
35.3k
    D->addAttr(NewAttr);
3889
35.3k
}
3890
3891
/// Handle __attribute__((callback(CalleeIdx, PayloadIdx0, ...))) attributes.
3892
142
static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3893
  // The index that identifies the callback callee is mandatory.
3894
142
  if (AL.getNumArgs() == 0) {
3895
2
    S.Diag(AL.getLoc(), diag::err_callback_attribute_no_callee)
3896
2
        << AL.getRange();
3897
2
    return;
3898
2
  }
3899
3900
140
  bool HasImplicitThisParam = isInstanceMethod(D);
3901
140
  int32_t NumArgs = getFunctionOrMethodNumParams(D);
3902
3903
140
  FunctionDecl *FD = D->getAsFunction();
3904
140
  assert(FD && "Expected a function declaration!");
3905
3906
0
  llvm::StringMap<int> NameIdxMapping;
3907
140
  NameIdxMapping["__"] = -1;
3908
3909
140
  NameIdxMapping["this"] = 0;
3910
3911
140
  int Idx = 1;
3912
140
  for (const ParmVarDecl *PVD : FD->parameters())
3913
248
    NameIdxMapping[PVD->getName()] = Idx++;
3914
3915
140
  auto UnknownName = NameIdxMapping.end();
3916
3917
140
  SmallVector<int, 8> EncodingIndices;
3918
437
  for (unsigned I = 0, E = AL.getNumArgs(); I < E; 
++I297
) {
3919
317
    SourceRange SR;
3920
317
    int32_t ArgIdx;
3921
3922
317
    if (AL.isArgIdent(I)) {
3923
127
      IdentifierLoc *IdLoc = AL.getArgAsIdent(I);
3924
127
      auto It = NameIdxMapping.find(IdLoc->Ident->getName());
3925
127
      if (It == UnknownName) {
3926
4
        S.Diag(AL.getLoc(), diag::err_callback_attribute_argument_unknown)
3927
4
            << IdLoc->Ident << IdLoc->Loc;
3928
4
        return;
3929
4
      }
3930
3931
123
      SR = SourceRange(IdLoc->Loc);
3932
123
      ArgIdx = It->second;
3933
190
    } else if (AL.isArgExpr(I)) {
3934
190
      Expr *IdxExpr = AL.getArgAsExpr(I);
3935
3936
      // If the expression is not parseable as an int32_t we have a problem.
3937
190
      if (!checkUInt32Argument(S, AL, IdxExpr, (uint32_t &)ArgIdx, I + 1,
3938
190
                               false)) {
3939
0
        S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
3940
0
            << AL << (I + 1) << IdxExpr->getSourceRange();
3941
0
        return;
3942
0
      }
3943
3944
      // Check oob, excluding the special values, 0 and -1.
3945
190
      if (ArgIdx < -1 || 
ArgIdx > NumArgs186
) {
3946
10
        S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
3947
10
            << AL << (I + 1) << IdxExpr->getSourceRange();
3948
10
        return;
3949
10
      }
3950
3951
180
      SR = IdxExpr->getSourceRange();
3952
180
    } else {
3953
0
      llvm_unreachable("Unexpected ParsedAttr argument type!");
3954
0
    }
3955
3956
303
    if (ArgIdx == 0 && 
!HasImplicitThisParam14
) {
3957
6
      S.Diag(AL.getLoc(), diag::err_callback_implicit_this_not_available)
3958
6
          << (I + 1) << SR;
3959
6
      return;
3960
6
    }
3961
3962
    // Adjust for the case we do not have an implicit "this" parameter. In this
3963
    // case we decrease all positive values by 1 to get LLVM argument indices.
3964
297
    if (!HasImplicitThisParam && 
ArgIdx > 0152
)
3965
116
      ArgIdx -= 1;
3966
3967
297
    EncodingIndices.push_back(ArgIdx);
3968
297
  }
3969
3970
120
  int CalleeIdx = EncodingIndices.front();
3971
  // Check if the callee index is proper, thus not "this" and not "unknown".
3972
  // This means the "CalleeIdx" has to be non-negative if "HasImplicitThisParam"
3973
  // is false and positive if "HasImplicitThisParam" is true.
3974
120
  if (CalleeIdx < (int)HasImplicitThisParam) {
3975
6
    S.Diag(AL.getLoc(), diag::err_callback_attribute_invalid_callee)
3976
6
        << AL.getRange();
3977
6
    return;
3978
6
  }
3979
3980
  // Get the callee type, note the index adjustment as the AST doesn't contain
3981
  // the this type (which the callee cannot reference anyway!).
3982
114
  const Type *CalleeType =
3983
114
      getFunctionOrMethodParamType(D, CalleeIdx - HasImplicitThisParam)
3984
114
          .getTypePtr();
3985
114
  if (!CalleeType || !CalleeType->isFunctionPointerType()) {
3986
0
    S.Diag(AL.getLoc(), diag::err_callback_callee_no_function_type)
3987
0
        << AL.getRange();
3988
0
    return;
3989
0
  }
3990
3991
114
  const Type *CalleeFnType =
3992
114
      CalleeType->getPointeeType()->getUnqualifiedDesugaredType();
3993
3994
  // TODO: Check the type of the callee arguments.
3995
3996
114
  const auto *CalleeFnProtoType = dyn_cast<FunctionProtoType>(CalleeFnType);
3997
114
  if (!CalleeFnProtoType) {
3998
0
    S.Diag(AL.getLoc(), diag::err_callback_callee_no_function_type)
3999
0
        << AL.getRange();
4000
0
    return;
4001
0
  }
4002
4003
114
  if (CalleeFnProtoType->getNumParams() > EncodingIndices.size() - 1) {
4004
12
    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
4005
12
        << AL << (unsigned)(EncodingIndices.size() - 1);
4006
12
    return;
4007
12
  }
4008
4009
102
  if (CalleeFnProtoType->getNumParams() < EncodingIndices.size() - 1) {
4010
28
    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
4011
28
        << AL << (unsigned)(EncodingIndices.size() - 1);
4012
28
    return;
4013
28
  }
4014
4015
74
  if (CalleeFnProtoType->isVariadic()) {
4016
8
    S.Diag(AL.getLoc(), diag::err_callback_callee_is_variadic) << AL.getRange();
4017
8
    return;
4018
8
  }
4019
4020
  // Do not allow multiple callback attributes.
4021
66
  if (D->hasAttr<CallbackAttr>()) {
4022
8
    S.Diag(AL.getLoc(), diag::err_callback_attribute_multiple) << AL.getRange();
4023
8
    return;
4024
8
  }
4025
4026
58
  D->addAttr(::new (S.Context) CallbackAttr(
4027
58
      S.Context, AL, EncodingIndices.data(), EncodingIndices.size()));
4028
58
}
4029
4030
103
static bool isFunctionLike(const Type &T) {
4031
  // Check for explicit function types.
4032
  // 'called_once' is only supported in Objective-C and it has
4033
  // function pointers and block pointers.
4034
103
  return T.isFunctionPointerType() || 
T.isBlockPointerType()100
;
4035
103
}
4036
4037
/// Handle 'called_once' attribute.
4038
103
static void handleCalledOnceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4039
  // 'called_once' only applies to parameters representing functions.
4040
103
  QualType T = cast<ParmVarDecl>(D)->getType();
4041
4042
103
  if (!isFunctionLike(*T)) {
4043
2
    S.Diag(AL.getLoc(), diag::err_called_once_attribute_wrong_type);
4044
2
    return;
4045
2
  }
4046
4047
101
  D->addAttr(::new (S.Context) CalledOnceAttr(S.Context, AL));
4048
101
}
4049
4050
65
static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4051
  // Try to find the underlying union declaration.
4052
65
  RecordDecl *RD = nullptr;
4053
65
  const auto *TD = dyn_cast<TypedefNameDecl>(D);
4054
65
  if (TD && 
TD->getUnderlyingType()->isUnionType()36
)
4055
36
    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
4056
29
  else
4057
29
    RD = dyn_cast<RecordDecl>(D);
4058
4059
65
  if (!RD || !RD->isUnion()) {
4060
0
    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) << AL
4061
0
                                                              << ExpectedUnion;
4062
0
    return;
4063
0
  }
4064
4065
65
  if (!RD->isCompleteDefinition()) {
4066
8
    if (!RD->isBeingDefined())
4067
0
      S.Diag(AL.getLoc(),
4068
0
             diag::warn_transparent_union_attribute_not_definition);
4069
8
    return;
4070
8
  }
4071
4072
57
  RecordDecl::field_iterator Field = RD->field_begin(),
4073
57
                          FieldEnd = RD->field_end();
4074
57
  if (Field == FieldEnd) {
4075
1
    S.Diag(AL.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
4076
1
    return;
4077
1
  }
4078
4079
56
  FieldDecl *FirstField = *Field;
4080
56
  QualType FirstType = FirstField->getType();
4081
56
  if (FirstType->hasFloatingRepresentation() || 
FirstType->isVectorType()55
) {
4082
2
    S.Diag(FirstField->getLocation(),
4083
2
           diag::warn_transparent_union_attribute_floating)
4084
2
      << FirstType->isVectorType() << FirstType;
4085
2
    return;
4086
2
  }
4087
4088
54
  if (FirstType->isIncompleteType())
4089
3
    return;
4090
51
  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
4091
51
  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
4092
220
  for (; Field != FieldEnd; 
++Field169
) {
4093
175
    QualType FieldType = Field->getType();
4094
175
    if (FieldType->isIncompleteType())
4095
1
      return;
4096
    // FIXME: this isn't fully correct; we also need to test whether the
4097
    // members of the union would all have the same calling convention as the
4098
    // first member of the union. Checking just the size and alignment isn't
4099
    // sufficient (consider structs passed on the stack instead of in registers
4100
    // as an example).
4101
174
    if (S.Context.getTypeSize(FieldType) != FirstSize ||
4102
174
        
S.Context.getTypeAlign(FieldType) > FirstAlign172
) {
4103
      // Warn if we drop the attribute.
4104
5
      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
4105
5
      unsigned FieldBits = isSize ? 
S.Context.getTypeSize(FieldType)2
4106
5
                                  : 
S.Context.getTypeAlign(FieldType)3
;
4107
5
      S.Diag(Field->getLocation(),
4108
5
             diag::warn_transparent_union_attribute_field_size_align)
4109
5
          << isSize << *Field << FieldBits;
4110
5
      unsigned FirstBits = isSize ? 
FirstSize2
:
FirstAlign3
;
4111
5
      S.Diag(FirstField->getLocation(),
4112
5
             diag::note_transparent_union_first_field_size_align)
4113
5
          << isSize << FirstBits;
4114
5
      return;
4115
5
    }
4116
174
  }
4117
4118
45
  RD->addAttr(::new (S.Context) TransparentUnionAttr(S.Context, AL));
4119
45
}
4120
4121
void Sema::AddAnnotationAttr(Decl *D, const AttributeCommonInfo &CI,
4122
374
                             StringRef Str, MutableArrayRef<Expr *> Args) {
4123
374
  auto *Attr = AnnotateAttr::Create(Context, Str, Args.data(), Args.size(), CI);
4124
374
  llvm::SmallVector<PartialDiagnosticAt, 8> Notes;
4125
440
  for (unsigned Idx = 0; Idx < Attr->args_size(); 
Idx++66
) {
4126
72
    Expr *&E = Attr->args_begin()[Idx];
4127
72
    assert(E && "error are handled before");
4128
72
    if (E->isValueDependent() || 
E->isTypeDependent()48
)
4129
24
      continue;
4130
4131
48
    if (E->getType()->isArrayType())
4132
2
      E = ImpCastExprToType(E, Context.getPointerType(E->getType()),
4133
2
                            clang::CK_ArrayToPointerDecay)
4134
2
              .get();
4135
48
    if (E->getType()->isFunctionType())
4136
2
      E = ImplicitCastExpr::Create(Context,
4137
2
                                   Context.getPointerType(E->getType()),
4138
2
                                   clang::CK_FunctionToPointerDecay, E, nullptr,
4139
2
                                   VK_PRValue, FPOptionsOverride());
4140
48
    if (E->isLValue())
4141
8
      E = ImplicitCastExpr::Create(Context, E->getType().getNonReferenceType(),
4142
8
                                   clang::CK_LValueToRValue, E, nullptr,
4143
8
                                   VK_PRValue, FPOptionsOverride());
4144
4145
48
    Expr::EvalResult Eval;
4146
48
    Notes.clear();
4147
48
    Eval.Diag = &Notes;
4148
4149
48
    bool Result =
4150
48
        E->EvaluateAsConstantExpr(Eval, Context);
4151
4152
    /// Result means the expression can be folded to a constant.
4153
    /// Note.empty() means the expression is a valid constant expression in the
4154
    /// current language mode.
4155
48
    if (!Result || 
!Notes.empty()43
) {
4156
6
      Diag(E->getBeginLoc(), diag::err_attribute_argument_n_type)
4157
6
          << CI << (Idx + 1) << AANT_ArgumentConstantExpr;
4158
6
      for (auto &Note : Notes)
4159
10
        Diag(Note.first, Note.second);
4160
6
      return;
4161
6
    }
4162
42
    assert(Eval.Val.hasValue());
4163
0
    E = ConstantExpr::Create(Context, E, Eval.Val);
4164
42
  }
4165
368
  D->addAttr(Attr);
4166
368
}
4167
4168
353
static void handleAnnotateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4169
  // Make sure that there is a string literal as the annotation's first
4170
  // argument.
4171
353
  StringRef Str;
4172
353
  if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
4173
2
    return;
4174
4175
351
  llvm::SmallVector<Expr *, 4> Args;
4176
351
  Args.reserve(AL.getNumArgs() - 1);
4177
391
  for (unsigned Idx = 1; Idx < AL.getNumArgs(); 
Idx++40
) {
4178
40
    assert(!AL.isArgIdent(Idx));
4179
0
    Args.push_back(AL.getArgAsExpr(Idx));
4180
40
  }
4181
4182
351
  S.AddAnnotationAttr(D, AL, Str, Args);
4183
351
}
4184
4185
290
static void handleAlignValueAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4186
290
  S.AddAlignValueAttr(D, AL, AL.getArgAsExpr(0));
4187
290
}
4188
4189
293
void Sema::AddAlignValueAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E) {
4190
293
  AlignValueAttr TmpAttr(Context, CI, E);
4191
293
  SourceLocation AttrLoc = CI.getLoc();
4192
4193
293
  QualType T;
4194
293
  if (const auto *TD = dyn_cast<TypedefNameDecl>(D))
4195
14
    T = TD->getUnderlyingType();
4196
279
  else if (const auto *VD = dyn_cast<ValueDecl>(D))
4197
279
    T = VD->getType();
4198
0
  else
4199
0
    llvm_unreachable("Unknown decl type for align_value");
4200
4201
293
  if (!T->isDependentType() && 
!T->isAnyPointerType()290
&&
4202
293
      
!T->isReferenceType()5
&&
!T->isMemberPointerType()1
) {
4203
1
    Diag(AttrLoc, diag::warn_attribute_pointer_or_reference_only)
4204
1
      << &TmpAttr << T << D->getSourceRange();
4205
1
    return;
4206
1
  }
4207
4208
292
  if (!E->isValueDependent()) {
4209
289
    llvm::APSInt Alignment;
4210
289
    ExprResult ICE = VerifyIntegerConstantExpression(
4211
289
        E, &Alignment, diag::err_align_value_attribute_argument_not_int);
4212
289
    if (ICE.isInvalid())
4213
1
      return;
4214
4215
288
    if (!Alignment.isPowerOf2()) {
4216
3
      Diag(AttrLoc, diag::err_alignment_not_power_of_two)
4217
3
        << E->getSourceRange();
4218
3
      return;
4219
3
    }
4220
4221
285
    D->addAttr(::new (Context) AlignValueAttr(Context, CI, ICE.get()));
4222
285
    return;
4223
288
  }
4224
4225
  // Save dependent expressions in the AST to be instantiated.
4226
3
  D->addAttr(::new (Context) AlignValueAttr(Context, CI, E));
4227
3
}
4228
4229
30.7k
static void handleAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4230
  // check the attribute arguments.
4231
30.7k
  if (AL.getNumArgs() > 1) {
4232
0
    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
4233
0
    return;
4234
0
  }
4235
4236
30.7k
  if (AL.getNumArgs() == 0) {
4237
46
    D->addAttr(::new (S.Context) AlignedAttr(S.Context, AL, true, nullptr));
4238
46
    return;
4239
46
  }
4240
4241
30.7k
  Expr *E = AL.getArgAsExpr(0);
4242
30.7k
  if (AL.isPackExpansion() && 
!E->containsUnexpandedParameterPack()9
) {
4243
1
    S.Diag(AL.getEllipsisLoc(),
4244
1
           diag::err_pack_expansion_without_parameter_packs);
4245
1
    return;
4246
1
  }
4247
4248
30.7k
  if (!AL.isPackExpansion() && 
S.DiagnoseUnexpandedParameterPack(E)30.7k
)
4249
3
    return;
4250
4251
30.7k
  S.AddAlignedAttr(D, AL, E, AL.isPackExpansion());
4252
30.7k
}
4253
4254
void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
4255
30.8k
                          bool IsPackExpansion) {
4256
30.8k
  AlignedAttr TmpAttr(Context, CI, true, E);
4257
30.8k
  SourceLocation AttrLoc = CI.getLoc();
4258
4259
  // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
4260
30.8k
  if (TmpAttr.isAlignas()) {
4261
    // C++11 [dcl.align]p1:
4262
    //   An alignment-specifier may be applied to a variable or to a class
4263
    //   data member, but it shall not be applied to a bit-field, a function
4264
    //   parameter, the formal parameter of a catch clause, or a variable
4265
    //   declared with the register storage class specifier. An
4266
    //   alignment-specifier may also be applied to the declaration of a class
4267
    //   or enumeration type.
4268
    // C11 6.7.5/2:
4269
    //   An alignment attribute shall not be specified in a declaration of
4270
    //   a typedef, or a bit-field, or a function, or a parameter, or an
4271
    //   object declared with the register storage-class specifier.
4272
9.71k
    int DiagKind = -1;
4273
9.71k
    if (isa<ParmVarDecl>(D)) {
4274
3
      DiagKind = 0;
4275
9.71k
    } else if (const auto *VD = dyn_cast<VarDecl>(D)) {
4276
1.28k
      if (VD->getStorageClass() == SC_Register)
4277
3
        DiagKind = 1;
4278
1.28k
      if (VD->isExceptionVariable())
4279
1
        DiagKind = 2;
4280
8.42k
    } else if (const auto *FD = dyn_cast<FieldDecl>(D)) {
4281
81
      if (FD->isBitField())
4282
3
        DiagKind = 3;
4283
8.34k
    } else if (!isa<TagDecl>(D)) {
4284
8
      Diag(AttrLoc, diag::err_attribute_wrong_decl_type) << &TmpAttr
4285
8
        << (TmpAttr.isC11() ? 
ExpectedVariableOrField2
4286
8
                            : 
ExpectedVariableFieldOrTag6
);
4287
8
      return;
4288
8
    }
4289
9.70k
    if (DiagKind != -1) {
4290
10
      Diag(AttrLoc, diag::err_alignas_attribute_wrong_decl_type)
4291
10
        << &TmpAttr << DiagKind;
4292
10
      return;
4293
10
    }
4294
9.70k
  }
4295
4296
30.8k
  if (E->isValueDependent()) {
4297
    // We can't support a dependent alignment on a non-dependent type,
4298
    // because we have no way to model that a type is "alignment-dependent"
4299
    // but not dependent in any other way.
4300
963
    if (const auto *TND = dyn_cast<TypedefNameDecl>(D)) {
4301
2
      if (!TND->getUnderlyingType()->isDependentType()) {
4302
2
        Diag(AttrLoc, diag::err_alignment_dependent_typedef_name)
4303
2
            << E->getSourceRange();
4304
2
        return;
4305
2
      }
4306
2
    }
4307
4308
    // Save dependent expressions in the AST to be instantiated.
4309
961
    AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, E);
4310
961
    AA->setPackExpansion(IsPackExpansion);
4311
961
    D->addAttr(AA);
4312
961
    return;
4313
963
  }
4314
4315
  // FIXME: Cache the number on the AL object?
4316
29.9k
  llvm::APSInt Alignment;
4317
29.9k
  ExprResult ICE = VerifyIntegerConstantExpression(
4318
29.9k
      E, &Alignment, diag::err_aligned_attribute_argument_not_int);
4319
29.9k
  if (ICE.isInvalid())
4320
3
    return;
4321
4322
29.9k
  uint64_t AlignVal = Alignment.getZExtValue();
4323
  // 16 byte ByVal alignment not due to a vector member is not honoured by XL
4324
  // on AIX. Emit a warning here that users are generating binary incompatible
4325
  // code to be safe.
4326
29.9k
  if (AlignVal >= 16 && 
isa<FieldDecl>(D)14.7k
&&
4327
29.9k
      
Context.getTargetInfo().getTriple().isOSAIX()363
)
4328
14
    Diag(AttrLoc, diag::warn_not_xl_compatible) << E->getSourceRange();
4329
4330
  // C++11 [dcl.align]p2:
4331
  //   -- if the constant expression evaluates to zero, the alignment
4332
  //      specifier shall have no effect
4333
  // C11 6.7.5p6:
4334
  //   An alignment specification of zero has no effect.
4335
29.9k
  if (!(TmpAttr.isAlignas() && 
!Alignment8.73k
)) {
4336
29.9k
    if (!llvm::isPowerOf2_64(AlignVal)) {
4337
6
      Diag(AttrLoc, diag::err_alignment_not_power_of_two)
4338
6
        << E->getSourceRange();
4339
6
      return;
4340
6
    }
4341
29.9k
  }
4342
4343
29.9k
  uint64_t MaximumAlignment = Sema::MaximumAlignment;
4344
29.9k
  if (Context.getTargetInfo().getTriple().isOSBinFormatCOFF())
4345
867
    MaximumAlignment = std::min(MaximumAlignment, uint64_t(8192));
4346
29.9k
  if (AlignVal > MaximumAlignment) {
4347
15
    Diag(AttrLoc, diag::err_attribute_aligned_too_great)
4348
15
        << MaximumAlignment << E->getSourceRange();
4349
15
    return;
4350
15
  }
4351
4352
29.8k
  const auto *VD = dyn_cast<VarDecl>(D);
4353
29.8k
  if (VD && 
Context.getTargetInfo().isTLSSupported()2.10k
) {
4354
1.76k
    unsigned MaxTLSAlign =
4355
1.76k
        Context.toCharUnitsFromBits(Context.getTargetInfo().getMaxTLSAlign())
4356
1.76k
            .getQuantity();
4357
1.76k
    if (MaxTLSAlign && 
AlignVal > MaxTLSAlign16
&&
4358
1.76k
        
VD->getTLSKind() != VarDecl::TLS_None2
) {
4359
2
      Diag(VD->getLocation(), diag::err_tls_var_aligned_over_maximum)
4360
2
          << (unsigned)AlignVal << VD << MaxTLSAlign;
4361
2
      return;
4362
2
    }
4363
1.76k
  }
4364
4365
  // On AIX, an aligned attribute can not decrease the alignment when applied
4366
  // to a variable declaration with vector type.
4367
29.8k
  if (VD && 
Context.getTargetInfo().getTriple().isOSAIX()2.10k
) {
4368
14
    const Type *Ty = VD->getType().getTypePtr();
4369
14
    if (Ty->isVectorType() && 
AlignVal < 162
) {
4370
2
      Diag(VD->getLocation(), diag::warn_aligned_attr_underaligned)
4371
2
          << VD->getType() << 16;
4372
2
      return;
4373
2
    }
4374
14
  }
4375
4376
29.8k
  AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, ICE.get());
4377
29.8k
  AA->setPackExpansion(IsPackExpansion);
4378
29.8k
  D->addAttr(AA);
4379
29.8k
}
4380
4381
void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI,
4382
0
                          TypeSourceInfo *TS, bool IsPackExpansion) {
4383
  // FIXME: Cache the number on the AL object if non-dependent?
4384
  // FIXME: Perform checking of type validity
4385
0
  AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, false, TS);
4386
0
  AA->setPackExpansion(IsPackExpansion);
4387
0
  D->addAttr(AA);
4388
0
}
4389
4390
1.39M
void Sema::CheckAlignasUnderalignment(Decl *D) {
4391
1.39M
  assert(D->hasAttrs() && "no attributes on decl");
4392
4393
0
  QualType UnderlyingTy, DiagTy;
4394
1.39M
  if (const auto *VD = dyn_cast<ValueDecl>(D)) {
4395
801k
    UnderlyingTy = DiagTy = VD->getType();
4396
801k
  } else {
4397
588k
    UnderlyingTy = DiagTy = Context.getTagDeclType(cast<TagDecl>(D));
4398
588k
    if (const auto *ED = dyn_cast<EnumDecl>(D))
4399
100k
      UnderlyingTy = ED->getIntegerType();
4400
588k
  }
4401
1.39M
  if (DiagTy->isDependentType() || 
DiagTy->isIncompleteType()1.26M
)
4402
133k
    return;
4403
4404
  // C++11 [dcl.align]p5, C11 6.7.5/4:
4405
  //   The combined effect of all alignment attributes in a declaration shall
4406
  //   not specify an alignment that is less strict than the alignment that
4407
  //   would otherwise be required for the entity being declared.
4408
1.25M
  AlignedAttr *AlignasAttr = nullptr;
4409
1.25M
  AlignedAttr *LastAlignedAttr = nullptr;
4410
1.25M
  unsigned Align = 0;
4411
1.25M
  for (auto *I : D->specific_attrs<AlignedAttr>()) {
4412
12.5k
    if (I->isAlignmentDependent())
4413
16
      return;
4414
12.5k
    if (I->isAlignas())
4415
2.44k
      AlignasAttr = I;
4416
12.5k
    Align = std::max(Align, I->getAlignment(Context));
4417
12.5k
    LastAlignedAttr = I;
4418
12.5k
  }
4419
4420
1.25M
  if (Align && 
DiagTy->isSizelessType()12.5k
) {
4421
21
    Diag(LastAlignedAttr->getLocation(), diag::err_attribute_sizeless_type)
4422
21
        << LastAlignedAttr << DiagTy;
4423
1.25M
  } else if (AlignasAttr && 
Align2.39k
) {
4424
2.39k
    CharUnits RequestedAlign = Context.toCharUnitsFromBits(Align);
4425
2.39k
    CharUnits NaturalAlign = Context.getTypeAlignInChars(UnderlyingTy);
4426
2.39k
    if (NaturalAlign > RequestedAlign)
4427
27
      Diag(AlignasAttr->getLocation(), diag::err_alignas_underaligned)
4428
27
        << DiagTy << (unsigned)NaturalAlign.getQuantity();
4429
2.39k
  }
4430
1.25M
}
4431
4432
bool Sema::checkMSInheritanceAttrOnDefinition(
4433
    CXXRecordDecl *RD, SourceRange Range, bool BestCase,
4434
92
    MSInheritanceModel ExplicitModel) {
4435
92
  assert(RD->hasDefinition() && "RD has no definition!");
4436
4437
  // We may not have seen base specifiers or any virtual methods yet.  We will
4438
  // have to wait until the record is defined to catch any mismatches.
4439
92
  if (!RD->getDefinition()->isCompleteDefinition())
4440
29
    return false;
4441
4442
  // The unspecified model never matches what a definition could need.
4443
63
  if (ExplicitModel == MSInheritanceModel::Unspecified)
4444
33
    return false;
4445
4446
30
  if (BestCase) {
4447
28
    if (RD->calculateInheritanceModel() == ExplicitModel)
4448
22
      return false;
4449
28
  } else {
4450
2
    if (RD->calculateInheritanceModel() <= ExplicitModel)
4451
2
      return false;
4452
2
  }
4453
4454
6
  Diag(Range.getBegin(), diag::err_mismatched_ms_inheritance)
4455
6
      << 0 /*definition*/;
4456
6
  Diag(RD->getDefinition()->getLocation(), diag::note_defined_here) << RD;
4457
6
  return true;
4458
30
}
4459
4460
/// parseModeAttrArg - Parses attribute mode string and returns parsed type
4461
/// attribute.
4462
static void parseModeAttrArg(Sema &S, StringRef Str, unsigned &DestWidth,
4463
                             bool &IntegerMode, bool &ComplexMode,
4464
378
                             FloatModeKind &ExplicitType) {
4465
378
  IntegerMode = true;
4466
378
  ComplexMode = false;
4467
378
  ExplicitType = FloatModeKind::NoFloat;
4468
378
  switch (Str.size()) {
4469
343
  case 2:
4470
343
    switch (Str[0]) {
4471
66
    case 'Q':
4472
66
      DestWidth = 8;
4473
66
      break;
4474
67
    case 'H':
4475
67
      DestWidth = 16;
4476
67
      break;
4477
93
    case 'S':
4478
93
      DestWidth = 32;
4479
93
      break;
4480
81
    case 'D':
4481
81
      DestWidth = 64;
4482
81
      break;
4483
5
    case 'X':
4484
5
      DestWidth = 96;
4485
5
      break;
4486
4
    case 'K': // KFmode - IEEE quad precision (__float128)
4487
4
      ExplicitType = FloatModeKind::Float128;
4488
4
      DestWidth = Str[1] == 'I' ? 
01
:
1283
;
4489
4
      break;
4490
12
    case 'T':
4491
12
      ExplicitType = FloatModeKind::LongDouble;
4492
12
      DestWidth = 128;
4493
12
      break;
4494
15
    case 'I':
4495
15
      ExplicitType = FloatModeKind::Ibm128;
4496
15
      DestWidth = Str[1] == 'I' ? 
09
:
1286
;
4497
15
      break;
4498
343
    }
4499
343
    if (Str[1] == 'F') {
4500
55
      IntegerMode = false;
4501
288
    } else if (Str[1] == 'C') {
4502
30
      IntegerMode = false;
4503
30
      ComplexMode = true;
4504
258
    } else if (Str[1] != 'I') {
4505
0
      DestWidth = 0;
4506
0
    }
4507
343
    break;
4508
7
  case 4:
4509
    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
4510
    // pointer on PIC16 and other embedded platforms.
4511
7
    if (Str == "word")
4512
1
      DestWidth = S.Context.getTargetInfo().getRegisterWidth();
4513
6
    else if (Str == "byte")
4514
5
      DestWidth = S.Context.getTargetInfo().getCharWidth();
4515
7
    break;
4516
0
  case 7:
4517
0
    if (Str == "pointer")
4518
0
      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
4519
0
    break;
4520
28
  case 11:
4521
28
    if (Str == "unwind_word")
4522
28
      DestWidth = S.Context.getTargetInfo().getUnwindWordWidth();
4523
28
    break;
4524
378
  }
4525
378
}
4526
4527
/// handleModeAttr - This attribute modifies the width of a decl with primitive
4528
/// type.
4529
///
4530
/// Despite what would be logical, the mode attribute is a decl attribute, not a
4531
/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
4532
/// HImode, not an intermediate pointer.
4533
303
static void handleModeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4534
  // This attribute isn't documented, but glibc uses it.  It changes
4535
  // the width of an int or unsigned int to the specified size.
4536
303
  if (!AL.isArgIdent(0)) {
4537
9
    S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
4538
9
        << AL << AANT_ArgumentIdentifier;
4539
9
    return;
4540
9
  }
4541
4542
294
  IdentifierInfo *Name = AL.getArgAsIdent(0)->Ident;
4543
4544
294
  S.AddModeAttr(D, AL, Name);
4545
294
}
4546
4547
void Sema::AddModeAttr(Decl *D, const AttributeCommonInfo &CI,
4548
378
                       IdentifierInfo *Name, bool InInstantiation) {
4549
378
  StringRef Str = Name->getName();
4550
378
  normalizeName(Str);
4551
378
  SourceLocation AttrLoc = CI.getLoc();
4552
4553
378
  unsigned DestWidth = 0;
4554
378
  bool IntegerMode = true;
4555
378
  bool ComplexMode = false;
4556
378
  FloatModeKind ExplicitType = FloatModeKind::NoFloat;
4557
378
  llvm::APInt VectorSize(64, 0);
4558
378
  if (Str.size() >= 4 && 
Str[0] == 'V'85
) {
4559
    // Minimal length of vector mode is 4: 'V' + NUMBER(>=1) + TYPE(>=2).
4560
51
    size_t StrSize = Str.size();
4561
51
    size_t VectorStringLength = 0;
4562
106
    while ((VectorStringLength + 1) < StrSize &&
4563
106
           isdigit(Str[VectorStringLength + 1]))
4564
55
      ++VectorStringLength;
4565
51
    if (VectorStringLength &&
4566
51
        !Str.substr(1, VectorStringLength).getAsInteger(10, VectorSize) &&
4567
51
        VectorSize.isPowerOf2()) {
4568
50
      parseModeAttrArg(*this, Str.substr(VectorStringLength + 1), DestWidth,
4569
50
                       IntegerMode, ComplexMode, ExplicitType);
4570
      // Avoid duplicate warning from template instantiation.
4571
50
      if (!InInstantiation)
4572
25
        Diag(AttrLoc, diag::warn_vector_mode_deprecated);
4573
50
    } else {
4574
1
      VectorSize = 0;
4575
1
    }
4576
51
  }
4577
4578
378
  if (!VectorSize)
4579
328
    parseModeAttrArg(*this, Str, DestWidth, IntegerMode, ComplexMode,
4580
328
                     ExplicitType);
4581
4582
  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
4583
  // and friends, at least with glibc.
4584
  // FIXME: Make sure floating-point mappings are accurate
4585
  // FIXME: Support XF and TF types
4586
378
  if (!DestWidth) {
4587
11
    Diag(AttrLoc, diag::err_machine_mode) << 0 /*Unknown*/ << Name;
4588
11
    return;
4589
11
  }
4590
4591
367
  QualType OldTy;
4592
367
  if (const auto *TD = dyn_cast<TypedefNameDecl>(D))
4593
283
    OldTy = TD->getUnderlyingType();
4594
84
  else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
4595
    // Something like 'typedef enum { X } __attribute__((mode(XX))) T;'.
4596
    // Try to get type from enum declaration, default to int.
4597
20
    OldTy = ED->getIntegerType();
4598
20
    if (OldTy.isNull())
4599
20
      OldTy = Context.IntTy;
4600
20
  } else
4601
64
    OldTy = cast<ValueDecl>(D)->getType();
4602
4603
367
  if (OldTy->isDependentType()) {
4604
31
    D->addAttr(::new (Context) ModeAttr(Context, CI, Name));
4605
31
    return;
4606
31
  }
4607
4608
  // Base type can also be a vector type (see PR17453).
4609
  // Distinguish between base type and base element type.
4610
336
  QualType OldElemTy = OldTy;
4