File: | build-llvm/tools/clang/include/clang/AST/Attrs.inc |
Warning: | line 521, column 9 Null pointer passed as an argument to a 'nonnull' parameter |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===// | |||
2 | // | |||
3 | // The LLVM Compiler Infrastructure | |||
4 | // | |||
5 | // This file is distributed under the University of Illinois Open Source | |||
6 | // License. See LICENSE.TXT for details. | |||
7 | // | |||
8 | //===----------------------------------------------------------------------===// | |||
9 | // | |||
10 | // This file implements decl-related attribute processing. | |||
11 | // | |||
12 | //===----------------------------------------------------------------------===// | |||
13 | ||||
14 | #include "clang/AST/ASTConsumer.h" | |||
15 | #include "clang/AST/ASTContext.h" | |||
16 | #include "clang/AST/ASTMutationListener.h" | |||
17 | #include "clang/AST/CXXInheritance.h" | |||
18 | #include "clang/AST/DeclCXX.h" | |||
19 | #include "clang/AST/DeclObjC.h" | |||
20 | #include "clang/AST/DeclTemplate.h" | |||
21 | #include "clang/AST/Expr.h" | |||
22 | #include "clang/AST/ExprCXX.h" | |||
23 | #include "clang/AST/Mangle.h" | |||
24 | #include "clang/AST/RecursiveASTVisitor.h" | |||
25 | #include "clang/Basic/CharInfo.h" | |||
26 | #include "clang/Basic/SourceManager.h" | |||
27 | #include "clang/Basic/TargetInfo.h" | |||
28 | #include "clang/Lex/Preprocessor.h" | |||
29 | #include "clang/Sema/DeclSpec.h" | |||
30 | #include "clang/Sema/DelayedDiagnostic.h" | |||
31 | #include "clang/Sema/Initialization.h" | |||
32 | #include "clang/Sema/Lookup.h" | |||
33 | #include "clang/Sema/Scope.h" | |||
34 | #include "clang/Sema/ScopeInfo.h" | |||
35 | #include "clang/Sema/SemaInternal.h" | |||
36 | #include "llvm/ADT/STLExtras.h" | |||
37 | #include "llvm/ADT/StringExtras.h" | |||
38 | #include "llvm/Support/MathExtras.h" | |||
39 | ||||
40 | using namespace clang; | |||
41 | using namespace sema; | |||
42 | ||||
43 | namespace AttributeLangSupport { | |||
44 | enum LANG { | |||
45 | C, | |||
46 | Cpp, | |||
47 | ObjC | |||
48 | }; | |||
49 | } // end namespace AttributeLangSupport | |||
50 | ||||
51 | //===----------------------------------------------------------------------===// | |||
52 | // Helper functions | |||
53 | //===----------------------------------------------------------------------===// | |||
54 | ||||
55 | /// isFunctionOrMethod - Return true if the given decl has function | |||
56 | /// type (function or function-typed variable) or an Objective-C | |||
57 | /// method. | |||
58 | static bool isFunctionOrMethod(const Decl *D) { | |||
59 | return (D->getFunctionType() != nullptr) || isa<ObjCMethodDecl>(D); | |||
60 | } | |||
61 | ||||
62 | /// Return true if the given decl has function type (function or | |||
63 | /// function-typed variable) or an Objective-C method or a block. | |||
64 | static bool isFunctionOrMethodOrBlock(const Decl *D) { | |||
65 | return isFunctionOrMethod(D) || isa<BlockDecl>(D); | |||
66 | } | |||
67 | ||||
68 | /// Return true if the given decl has a declarator that should have | |||
69 | /// been processed by Sema::GetTypeForDeclarator. | |||
70 | static bool hasDeclarator(const Decl *D) { | |||
71 | // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl. | |||
72 | return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) || | |||
73 | isa<ObjCPropertyDecl>(D); | |||
74 | } | |||
75 | ||||
76 | /// hasFunctionProto - Return true if the given decl has a argument | |||
77 | /// information. This decl should have already passed | |||
78 | /// isFunctionOrMethod or isFunctionOrMethodOrBlock. | |||
79 | static bool hasFunctionProto(const Decl *D) { | |||
80 | if (const FunctionType *FnTy = D->getFunctionType()) | |||
81 | return isa<FunctionProtoType>(FnTy); | |||
82 | return isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D); | |||
83 | } | |||
84 | ||||
85 | /// getFunctionOrMethodNumParams - Return number of function or method | |||
86 | /// parameters. It is an error to call this on a K&R function (use | |||
87 | /// hasFunctionProto first). | |||
88 | static unsigned getFunctionOrMethodNumParams(const Decl *D) { | |||
89 | if (const FunctionType *FnTy = D->getFunctionType()) | |||
90 | return cast<FunctionProtoType>(FnTy)->getNumParams(); | |||
91 | if (const auto *BD = dyn_cast<BlockDecl>(D)) | |||
92 | return BD->getNumParams(); | |||
93 | return cast<ObjCMethodDecl>(D)->param_size(); | |||
94 | } | |||
95 | ||||
96 | static QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx) { | |||
97 | if (const FunctionType *FnTy = D->getFunctionType()) | |||
98 | return cast<FunctionProtoType>(FnTy)->getParamType(Idx); | |||
99 | if (const auto *BD = dyn_cast<BlockDecl>(D)) | |||
100 | return BD->getParamDecl(Idx)->getType(); | |||
101 | ||||
102 | return cast<ObjCMethodDecl>(D)->parameters()[Idx]->getType(); | |||
103 | } | |||
104 | ||||
105 | static SourceRange getFunctionOrMethodParamRange(const Decl *D, unsigned Idx) { | |||
106 | if (const auto *FD = dyn_cast<FunctionDecl>(D)) | |||
107 | return FD->getParamDecl(Idx)->getSourceRange(); | |||
108 | if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) | |||
109 | return MD->parameters()[Idx]->getSourceRange(); | |||
110 | if (const auto *BD = dyn_cast<BlockDecl>(D)) | |||
111 | return BD->getParamDecl(Idx)->getSourceRange(); | |||
112 | return SourceRange(); | |||
113 | } | |||
114 | ||||
115 | static QualType getFunctionOrMethodResultType(const Decl *D) { | |||
116 | if (const FunctionType *FnTy = D->getFunctionType()) | |||
117 | return FnTy->getReturnType(); | |||
118 | return cast<ObjCMethodDecl>(D)->getReturnType(); | |||
119 | } | |||
120 | ||||
121 | static SourceRange getFunctionOrMethodResultSourceRange(const Decl *D) { | |||
122 | if (const auto *FD = dyn_cast<FunctionDecl>(D)) | |||
123 | return FD->getReturnTypeSourceRange(); | |||
124 | if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) | |||
125 | return MD->getReturnTypeSourceRange(); | |||
126 | return SourceRange(); | |||
127 | } | |||
128 | ||||
129 | static bool isFunctionOrMethodVariadic(const Decl *D) { | |||
130 | if (const FunctionType *FnTy = D->getFunctionType()) | |||
131 | return cast<FunctionProtoType>(FnTy)->isVariadic(); | |||
132 | if (const auto *BD = dyn_cast<BlockDecl>(D)) | |||
133 | return BD->isVariadic(); | |||
134 | return cast<ObjCMethodDecl>(D)->isVariadic(); | |||
135 | } | |||
136 | ||||
137 | static bool isInstanceMethod(const Decl *D) { | |||
138 | if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(D)) | |||
139 | return MethodDecl->isInstance(); | |||
140 | return false; | |||
141 | } | |||
142 | ||||
143 | static inline bool isNSStringType(QualType T, ASTContext &Ctx) { | |||
144 | const auto *PT = T->getAs<ObjCObjectPointerType>(); | |||
145 | if (!PT) | |||
146 | return false; | |||
147 | ||||
148 | ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface(); | |||
149 | if (!Cls) | |||
150 | return false; | |||
151 | ||||
152 | IdentifierInfo* ClsName = Cls->getIdentifier(); | |||
153 | ||||
154 | // FIXME: Should we walk the chain of classes? | |||
155 | return ClsName == &Ctx.Idents.get("NSString") || | |||
156 | ClsName == &Ctx.Idents.get("NSMutableString"); | |||
157 | } | |||
158 | ||||
159 | static inline bool isCFStringType(QualType T, ASTContext &Ctx) { | |||
160 | const auto *PT = T->getAs<PointerType>(); | |||
161 | if (!PT) | |||
162 | return false; | |||
163 | ||||
164 | const auto *RT = PT->getPointeeType()->getAs<RecordType>(); | |||
165 | if (!RT) | |||
166 | return false; | |||
167 | ||||
168 | const RecordDecl *RD = RT->getDecl(); | |||
169 | if (RD->getTagKind() != TTK_Struct) | |||
170 | return false; | |||
171 | ||||
172 | return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); | |||
173 | } | |||
174 | ||||
175 | static unsigned getNumAttributeArgs(const ParsedAttr &AL) { | |||
176 | // FIXME: Include the type in the argument list. | |||
177 | return AL.getNumArgs() + AL.hasParsedType(); | |||
178 | } | |||
179 | ||||
180 | template <typename Compare> | |||
181 | static bool checkAttributeNumArgsImpl(Sema &S, const ParsedAttr &AL, | |||
182 | unsigned Num, unsigned Diag, | |||
183 | Compare Comp) { | |||
184 | if (Comp(getNumAttributeArgs(AL), Num)) { | |||
185 | S.Diag(AL.getLoc(), Diag) << AL.getName() << Num; | |||
186 | return false; | |||
187 | } | |||
188 | ||||
189 | return true; | |||
190 | } | |||
191 | ||||
192 | /// Check if the attribute has exactly as many args as Num. May | |||
193 | /// output an error. | |||
194 | static bool checkAttributeNumArgs(Sema &S, const ParsedAttr &AL, unsigned Num) { | |||
195 | return checkAttributeNumArgsImpl(S, AL, Num, | |||
196 | diag::err_attribute_wrong_number_arguments, | |||
197 | std::not_equal_to<unsigned>()); | |||
198 | } | |||
199 | ||||
200 | /// Check if the attribute has at least as many args as Num. May | |||
201 | /// output an error. | |||
202 | static bool checkAttributeAtLeastNumArgs(Sema &S, const ParsedAttr &AL, | |||
203 | unsigned Num) { | |||
204 | return checkAttributeNumArgsImpl(S, AL, Num, | |||
205 | diag::err_attribute_too_few_arguments, | |||
206 | std::less<unsigned>()); | |||
207 | } | |||
208 | ||||
209 | /// Check if the attribute has at most as many args as Num. May | |||
210 | /// output an error. | |||
211 | static bool checkAttributeAtMostNumArgs(Sema &S, const ParsedAttr &AL, | |||
212 | unsigned Num) { | |||
213 | return checkAttributeNumArgsImpl(S, AL, Num, | |||
214 | diag::err_attribute_too_many_arguments, | |||
215 | std::greater<unsigned>()); | |||
216 | } | |||
217 | ||||
218 | /// A helper function to provide Attribute Location for the Attr types | |||
219 | /// AND the ParsedAttr. | |||
220 | template <typename AttrInfo> | |||
221 | static typename std::enable_if<std::is_base_of<Attr, AttrInfo>::value, | |||
222 | SourceLocation>::type | |||
223 | getAttrLoc(const AttrInfo &AL) { | |||
224 | return AL.getLocation(); | |||
225 | } | |||
226 | static SourceLocation getAttrLoc(const ParsedAttr &AL) { return AL.getLoc(); } | |||
227 | ||||
228 | /// A helper function to provide Attribute Name for the Attr types | |||
229 | /// AND the ParsedAttr. | |||
230 | template <typename AttrInfo> | |||
231 | static typename std::enable_if<std::is_base_of<Attr, AttrInfo>::value, | |||
232 | const AttrInfo *>::type | |||
233 | getAttrName(const AttrInfo &AL) { | |||
234 | return &AL; | |||
235 | } | |||
236 | static const IdentifierInfo *getAttrName(const ParsedAttr &AL) { | |||
237 | return AL.getName(); | |||
238 | } | |||
239 | ||||
240 | /// If Expr is a valid integer constant, get the value of the integer | |||
241 | /// expression and return success or failure. May output an error. | |||
242 | template <typename AttrInfo> | |||
243 | static bool checkUInt32Argument(Sema &S, const AttrInfo &AI, const Expr *Expr, | |||
244 | uint32_t &Val, unsigned Idx = UINT_MAX(2147483647 *2U +1U)) { | |||
245 | llvm::APSInt I(32); | |||
246 | if (Expr->isTypeDependent() || Expr->isValueDependent() || | |||
247 | !Expr->isIntegerConstantExpr(I, S.Context)) { | |||
248 | if (Idx != UINT_MAX(2147483647 *2U +1U)) | |||
249 | S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type) | |||
250 | << getAttrName(AI) << Idx << AANT_ArgumentIntegerConstant | |||
251 | << Expr->getSourceRange(); | |||
252 | else | |||
253 | S.Diag(getAttrLoc(AI), diag::err_attribute_argument_type) | |||
254 | << getAttrName(AI) << AANT_ArgumentIntegerConstant | |||
255 | << Expr->getSourceRange(); | |||
256 | return false; | |||
257 | } | |||
258 | ||||
259 | if (!I.isIntN(32)) { | |||
260 | S.Diag(Expr->getExprLoc(), diag::err_ice_too_large) | |||
261 | << I.toString(10, false) << 32 << /* Unsigned */ 1; | |||
262 | return false; | |||
263 | } | |||
264 | ||||
265 | Val = (uint32_t)I.getZExtValue(); | |||
266 | return true; | |||
267 | } | |||
268 | ||||
269 | /// Wrapper around checkUInt32Argument, with an extra check to be sure | |||
270 | /// that the result will fit into a regular (signed) int. All args have the same | |||
271 | /// purpose as they do in checkUInt32Argument. | |||
272 | template <typename AttrInfo> | |||
273 | static bool checkPositiveIntArgument(Sema &S, const AttrInfo &AI, const Expr *Expr, | |||
274 | int &Val, unsigned Idx = UINT_MAX(2147483647 *2U +1U)) { | |||
275 | uint32_t UVal; | |||
276 | if (!checkUInt32Argument(S, AI, Expr, UVal, Idx)) | |||
277 | return false; | |||
278 | ||||
279 | if (UVal > (uint32_t)std::numeric_limits<int>::max()) { | |||
280 | llvm::APSInt I(32); // for toString | |||
281 | I = UVal; | |||
282 | S.Diag(Expr->getExprLoc(), diag::err_ice_too_large) | |||
283 | << I.toString(10, false) << 32 << /* Unsigned */ 0; | |||
284 | return false; | |||
285 | } | |||
286 | ||||
287 | Val = UVal; | |||
288 | return true; | |||
289 | } | |||
290 | ||||
291 | /// Diagnose mutually exclusive attributes when present on a given | |||
292 | /// declaration. Returns true if diagnosed. | |||
293 | template <typename AttrTy> | |||
294 | static bool checkAttrMutualExclusion(Sema &S, Decl *D, SourceRange Range, | |||
295 | IdentifierInfo *Ident) { | |||
296 | if (const auto *A = D->getAttr<AttrTy>()) { | |||
297 | S.Diag(Range.getBegin(), diag::err_attributes_are_not_compatible) << Ident | |||
298 | << A; | |||
299 | S.Diag(A->getLocation(), diag::note_conflicting_attribute); | |||
300 | return true; | |||
301 | } | |||
302 | return false; | |||
303 | } | |||
304 | ||||
305 | /// Check if IdxExpr is a valid parameter index for a function or | |||
306 | /// instance method D. May output an error. | |||
307 | /// | |||
308 | /// \returns true if IdxExpr is a valid index. | |||
309 | template <typename AttrInfo> | |||
310 | static bool checkFunctionOrMethodParameterIndex( | |||
311 | Sema &S, const Decl *D, const AttrInfo &AI, unsigned AttrArgNum, | |||
312 | const Expr *IdxExpr, ParamIdx &Idx, bool CanIndexImplicitThis = false) { | |||
313 | assert(isFunctionOrMethodOrBlock(D))(static_cast <bool> (isFunctionOrMethodOrBlock(D)) ? void (0) : __assert_fail ("isFunctionOrMethodOrBlock(D)", "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 313, __extension__ __PRETTY_FUNCTION__)); | |||
314 | ||||
315 | // In C++ the implicit 'this' function parameter also counts. | |||
316 | // Parameters are counted from one. | |||
317 | bool HP = hasFunctionProto(D); | |||
318 | bool HasImplicitThisParam = isInstanceMethod(D); | |||
319 | bool IV = HP && isFunctionOrMethodVariadic(D); | |||
320 | unsigned NumParams = | |||
321 | (HP ? getFunctionOrMethodNumParams(D) : 0) + HasImplicitThisParam; | |||
322 | ||||
323 | llvm::APSInt IdxInt; | |||
324 | if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || | |||
325 | !IdxExpr->isIntegerConstantExpr(IdxInt, S.Context)) { | |||
326 | S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type) | |||
327 | << getAttrName(AI) << AttrArgNum << AANT_ArgumentIntegerConstant | |||
328 | << IdxExpr->getSourceRange(); | |||
329 | return false; | |||
330 | } | |||
331 | ||||
332 | unsigned IdxSource = IdxInt.getLimitedValue(UINT_MAX(2147483647 *2U +1U)); | |||
333 | if (IdxSource < 1 || (!IV && IdxSource > NumParams)) { | |||
334 | S.Diag(getAttrLoc(AI), diag::err_attribute_argument_out_of_bounds) | |||
335 | << getAttrName(AI) << AttrArgNum << IdxExpr->getSourceRange(); | |||
336 | return false; | |||
337 | } | |||
338 | if (HasImplicitThisParam && !CanIndexImplicitThis) { | |||
339 | if (IdxSource == 1) { | |||
340 | S.Diag(getAttrLoc(AI), | |||
341 | diag::err_attribute_invalid_implicit_this_argument) | |||
342 | << getAttrName(AI) << IdxExpr->getSourceRange(); | |||
343 | return false; | |||
344 | } | |||
345 | } | |||
346 | ||||
347 | Idx = ParamIdx(IdxSource, D); | |||
348 | return true; | |||
349 | } | |||
350 | ||||
351 | /// Check if the argument \p ArgNum of \p Attr is a ASCII string literal. | |||
352 | /// If not emit an error and return false. If the argument is an identifier it | |||
353 | /// will emit an error with a fixit hint and treat it as if it was a string | |||
354 | /// literal. | |||
355 | bool Sema::checkStringLiteralArgumentAttr(const ParsedAttr &AL, unsigned ArgNum, | |||
356 | StringRef &Str, | |||
357 | SourceLocation *ArgLocation) { | |||
358 | // Look for identifiers. If we have one emit a hint to fix it to a literal. | |||
359 | if (AL.isArgIdent(ArgNum)) { | |||
360 | IdentifierLoc *Loc = AL.getArgAsIdent(ArgNum); | |||
361 | Diag(Loc->Loc, diag::err_attribute_argument_type) | |||
362 | << AL.getName() << AANT_ArgumentString | |||
363 | << FixItHint::CreateInsertion(Loc->Loc, "\"") | |||
364 | << FixItHint::CreateInsertion(getLocForEndOfToken(Loc->Loc), "\""); | |||
365 | Str = Loc->Ident->getName(); | |||
366 | if (ArgLocation) | |||
367 | *ArgLocation = Loc->Loc; | |||
368 | return true; | |||
369 | } | |||
370 | ||||
371 | // Now check for an actual string literal. | |||
372 | Expr *ArgExpr = AL.getArgAsExpr(ArgNum); | |||
373 | const auto *Literal = dyn_cast<StringLiteral>(ArgExpr->IgnoreParenCasts()); | |||
374 | if (ArgLocation) | |||
375 | *ArgLocation = ArgExpr->getLocStart(); | |||
376 | ||||
377 | if (!Literal || !Literal->isAscii()) { | |||
378 | Diag(ArgExpr->getLocStart(), diag::err_attribute_argument_type) | |||
379 | << AL.getName() << AANT_ArgumentString; | |||
380 | return false; | |||
381 | } | |||
382 | ||||
383 | Str = Literal->getString(); | |||
384 | return true; | |||
385 | } | |||
386 | ||||
387 | /// Applies the given attribute to the Decl without performing any | |||
388 | /// additional semantic checking. | |||
389 | template <typename AttrType> | |||
390 | static void handleSimpleAttribute(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
391 | D->addAttr(::new (S.Context) AttrType(AL.getRange(), S.Context, | |||
392 | AL.getAttributeSpellingListIndex())); | |||
393 | } | |||
394 | ||||
395 | template <typename AttrType> | |||
396 | static void handleSimpleAttributeWithExclusions(Sema &S, Decl *D, | |||
397 | const ParsedAttr &AL) { | |||
398 | handleSimpleAttribute<AttrType>(S, D, AL); | |||
399 | } | |||
400 | ||||
401 | /// Applies the given attribute to the Decl so long as the Decl doesn't | |||
402 | /// already have one of the given incompatible attributes. | |||
403 | template <typename AttrType, typename IncompatibleAttrType, | |||
404 | typename... IncompatibleAttrTypes> | |||
405 | static void handleSimpleAttributeWithExclusions(Sema &S, Decl *D, | |||
406 | const ParsedAttr &AL) { | |||
407 | if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL.getRange(), | |||
408 | AL.getName())) | |||
409 | return; | |||
410 | handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D, | |||
411 | AL); | |||
412 | } | |||
413 | ||||
414 | /// Check if the passed-in expression is of type int or bool. | |||
415 | static bool isIntOrBool(Expr *Exp) { | |||
416 | QualType QT = Exp->getType(); | |||
417 | return QT->isBooleanType() || QT->isIntegerType(); | |||
418 | } | |||
419 | ||||
420 | ||||
421 | // Check to see if the type is a smart pointer of some kind. We assume | |||
422 | // it's a smart pointer if it defines both operator-> and operator*. | |||
423 | static bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) { | |||
424 | DeclContextLookupResult Res1 = RT->getDecl()->lookup( | |||
425 | S.Context.DeclarationNames.getCXXOperatorName(OO_Star)); | |||
426 | if (Res1.empty()) | |||
427 | return false; | |||
428 | ||||
429 | DeclContextLookupResult Res2 = RT->getDecl()->lookup( | |||
430 | S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow)); | |||
431 | if (Res2.empty()) | |||
432 | return false; | |||
433 | ||||
434 | return true; | |||
435 | } | |||
436 | ||||
437 | /// Check if passed in Decl is a pointer type. | |||
438 | /// Note that this function may produce an error message. | |||
439 | /// \return true if the Decl is a pointer type; false otherwise | |||
440 | static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D, | |||
441 | const ParsedAttr &AL) { | |||
442 | const auto *VD = cast<ValueDecl>(D); | |||
443 | QualType QT = VD->getType(); | |||
444 | if (QT->isAnyPointerType()) | |||
445 | return true; | |||
446 | ||||
447 | if (const auto *RT = QT->getAs<RecordType>()) { | |||
448 | // If it's an incomplete type, it could be a smart pointer; skip it. | |||
449 | // (We don't want to force template instantiation if we can avoid it, | |||
450 | // since that would alter the order in which templates are instantiated.) | |||
451 | if (RT->isIncompleteType()) | |||
452 | return true; | |||
453 | ||||
454 | if (threadSafetyCheckIsSmartPointer(S, RT)) | |||
455 | return true; | |||
456 | } | |||
457 | ||||
458 | S.Diag(AL.getLoc(), diag::warn_thread_attribute_decl_not_pointer) | |||
459 | << AL.getName() << QT; | |||
460 | return false; | |||
461 | } | |||
462 | ||||
463 | /// Checks that the passed in QualType either is of RecordType or points | |||
464 | /// to RecordType. Returns the relevant RecordType, null if it does not exit. | |||
465 | static const RecordType *getRecordType(QualType QT) { | |||
466 | if (const auto *RT = QT->getAs<RecordType>()) | |||
467 | return RT; | |||
468 | ||||
469 | // Now check if we point to record type. | |||
470 | if (const auto *PT = QT->getAs<PointerType>()) | |||
471 | return PT->getPointeeType()->getAs<RecordType>(); | |||
472 | ||||
473 | return nullptr; | |||
474 | } | |||
475 | ||||
476 | static bool checkRecordTypeForCapability(Sema &S, QualType Ty) { | |||
477 | const RecordType *RT = getRecordType(Ty); | |||
478 | ||||
479 | if (!RT) | |||
480 | return false; | |||
481 | ||||
482 | // Don't check for the capability if the class hasn't been defined yet. | |||
483 | if (RT->isIncompleteType()) | |||
484 | return true; | |||
485 | ||||
486 | // Allow smart pointers to be used as capability objects. | |||
487 | // FIXME -- Check the type that the smart pointer points to. | |||
488 | if (threadSafetyCheckIsSmartPointer(S, RT)) | |||
489 | return true; | |||
490 | ||||
491 | // Check if the record itself has a capability. | |||
492 | RecordDecl *RD = RT->getDecl(); | |||
493 | if (RD->hasAttr<CapabilityAttr>()) | |||
494 | return true; | |||
495 | ||||
496 | // Else check if any base classes have a capability. | |||
497 | if (const auto *CRD = dyn_cast<CXXRecordDecl>(RD)) { | |||
498 | CXXBasePaths BPaths(false, false); | |||
499 | if (CRD->lookupInBases([](const CXXBaseSpecifier *BS, CXXBasePath &) { | |||
500 | const auto *Type = BS->getType()->getAs<RecordType>(); | |||
501 | return Type->getDecl()->hasAttr<CapabilityAttr>(); | |||
502 | }, BPaths)) | |||
503 | return true; | |||
504 | } | |||
505 | return false; | |||
506 | } | |||
507 | ||||
508 | static bool checkTypedefTypeForCapability(QualType Ty) { | |||
509 | const auto *TD = Ty->getAs<TypedefType>(); | |||
510 | if (!TD) | |||
511 | return false; | |||
512 | ||||
513 | TypedefNameDecl *TN = TD->getDecl(); | |||
514 | if (!TN) | |||
515 | return false; | |||
516 | ||||
517 | return TN->hasAttr<CapabilityAttr>(); | |||
518 | } | |||
519 | ||||
520 | static bool typeHasCapability(Sema &S, QualType Ty) { | |||
521 | if (checkTypedefTypeForCapability(Ty)) | |||
522 | return true; | |||
523 | ||||
524 | if (checkRecordTypeForCapability(S, Ty)) | |||
525 | return true; | |||
526 | ||||
527 | return false; | |||
528 | } | |||
529 | ||||
530 | static bool isCapabilityExpr(Sema &S, const Expr *Ex) { | |||
531 | // Capability expressions are simple expressions involving the boolean logic | |||
532 | // operators &&, || or !, a simple DeclRefExpr, CastExpr or a ParenExpr. Once | |||
533 | // a DeclRefExpr is found, its type should be checked to determine whether it | |||
534 | // is a capability or not. | |||
535 | ||||
536 | if (const auto *E = dyn_cast<CastExpr>(Ex)) | |||
537 | return isCapabilityExpr(S, E->getSubExpr()); | |||
538 | else if (const auto *E = dyn_cast<ParenExpr>(Ex)) | |||
539 | return isCapabilityExpr(S, E->getSubExpr()); | |||
540 | else if (const auto *E = dyn_cast<UnaryOperator>(Ex)) { | |||
541 | if (E->getOpcode() == UO_LNot || E->getOpcode() == UO_AddrOf || | |||
542 | E->getOpcode() == UO_Deref) | |||
543 | return isCapabilityExpr(S, E->getSubExpr()); | |||
544 | return false; | |||
545 | } else if (const auto *E = dyn_cast<BinaryOperator>(Ex)) { | |||
546 | if (E->getOpcode() == BO_LAnd || E->getOpcode() == BO_LOr) | |||
547 | return isCapabilityExpr(S, E->getLHS()) && | |||
548 | isCapabilityExpr(S, E->getRHS()); | |||
549 | return false; | |||
550 | } | |||
551 | ||||
552 | return typeHasCapability(S, Ex->getType()); | |||
553 | } | |||
554 | ||||
555 | /// Checks that all attribute arguments, starting from Sidx, resolve to | |||
556 | /// a capability object. | |||
557 | /// \param Sidx The attribute argument index to start checking with. | |||
558 | /// \param ParamIdxOk Whether an argument can be indexing into a function | |||
559 | /// parameter list. | |||
560 | static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D, | |||
561 | const ParsedAttr &AL, | |||
562 | SmallVectorImpl<Expr *> &Args, | |||
563 | int Sidx = 0, | |||
564 | bool ParamIdxOk = false) { | |||
565 | for (unsigned Idx = Sidx; Idx < AL.getNumArgs(); ++Idx) { | |||
566 | Expr *ArgExp = AL.getArgAsExpr(Idx); | |||
567 | ||||
568 | if (ArgExp->isTypeDependent()) { | |||
569 | // FIXME -- need to check this again on template instantiation | |||
570 | Args.push_back(ArgExp); | |||
571 | continue; | |||
572 | } | |||
573 | ||||
574 | if (const auto *StrLit = dyn_cast<StringLiteral>(ArgExp)) { | |||
575 | if (StrLit->getLength() == 0 || | |||
576 | (StrLit->isAscii() && StrLit->getString() == StringRef("*"))) { | |||
577 | // Pass empty strings to the analyzer without warnings. | |||
578 | // Treat "*" as the universal lock. | |||
579 | Args.push_back(ArgExp); | |||
580 | continue; | |||
581 | } | |||
582 | ||||
583 | // We allow constant strings to be used as a placeholder for expressions | |||
584 | // that are not valid C++ syntax, but warn that they are ignored. | |||
585 | S.Diag(AL.getLoc(), diag::warn_thread_attribute_ignored) << AL.getName(); | |||
586 | Args.push_back(ArgExp); | |||
587 | continue; | |||
588 | } | |||
589 | ||||
590 | QualType ArgTy = ArgExp->getType(); | |||
591 | ||||
592 | // A pointer to member expression of the form &MyClass::mu is treated | |||
593 | // specially -- we need to look at the type of the member. | |||
594 | if (const auto *UOp = dyn_cast<UnaryOperator>(ArgExp)) | |||
595 | if (UOp->getOpcode() == UO_AddrOf) | |||
596 | if (const auto *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr())) | |||
597 | if (DRE->getDecl()->isCXXInstanceMember()) | |||
598 | ArgTy = DRE->getDecl()->getType(); | |||
599 | ||||
600 | // First see if we can just cast to record type, or pointer to record type. | |||
601 | const RecordType *RT = getRecordType(ArgTy); | |||
602 | ||||
603 | // Now check if we index into a record type function param. | |||
604 | if(!RT && ParamIdxOk) { | |||
605 | const auto *FD = dyn_cast<FunctionDecl>(D); | |||
606 | const auto *IL = dyn_cast<IntegerLiteral>(ArgExp); | |||
607 | if(FD && IL) { | |||
608 | unsigned int NumParams = FD->getNumParams(); | |||
609 | llvm::APInt ArgValue = IL->getValue(); | |||
610 | uint64_t ParamIdxFromOne = ArgValue.getZExtValue(); | |||
611 | uint64_t ParamIdxFromZero = ParamIdxFromOne - 1; | |||
612 | if (!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) { | |||
613 | S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_range) | |||
614 | << AL.getName() << Idx + 1 << NumParams; | |||
615 | continue; | |||
616 | } | |||
617 | ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType(); | |||
618 | } | |||
619 | } | |||
620 | ||||
621 | // If the type does not have a capability, see if the components of the | |||
622 | // expression have capabilities. This allows for writing C code where the | |||
623 | // capability may be on the type, and the expression is a capability | |||
624 | // boolean logic expression. Eg) requires_capability(A || B && !C) | |||
625 | if (!typeHasCapability(S, ArgTy) && !isCapabilityExpr(S, ArgExp)) | |||
626 | S.Diag(AL.getLoc(), diag::warn_thread_attribute_argument_not_lockable) | |||
627 | << AL.getName() << ArgTy; | |||
628 | ||||
629 | Args.push_back(ArgExp); | |||
630 | } | |||
631 | } | |||
632 | ||||
633 | //===----------------------------------------------------------------------===// | |||
634 | // Attribute Implementations | |||
635 | //===----------------------------------------------------------------------===// | |||
636 | ||||
637 | static void handlePtGuardedVarAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
638 | if (!threadSafetyCheckIsPointer(S, D, AL)) | |||
639 | return; | |||
640 | ||||
641 | D->addAttr(::new (S.Context) | |||
642 | PtGuardedVarAttr(AL.getRange(), S.Context, | |||
643 | AL.getAttributeSpellingListIndex())); | |||
644 | } | |||
645 | ||||
646 | static bool checkGuardedByAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL, | |||
647 | Expr *&Arg) { | |||
648 | SmallVector<Expr *, 1> Args; | |||
649 | // check that all arguments are lockable objects | |||
650 | checkAttrArgsAreCapabilityObjs(S, D, AL, Args); | |||
651 | unsigned Size = Args.size(); | |||
652 | if (Size != 1) | |||
653 | return false; | |||
654 | ||||
655 | Arg = Args[0]; | |||
656 | ||||
657 | return true; | |||
658 | } | |||
659 | ||||
660 | static void handleGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
661 | Expr *Arg = nullptr; | |||
662 | if (!checkGuardedByAttrCommon(S, D, AL, Arg)) | |||
663 | return; | |||
664 | ||||
665 | D->addAttr(::new (S.Context) GuardedByAttr( | |||
666 | AL.getRange(), S.Context, Arg, AL.getAttributeSpellingListIndex())); | |||
667 | } | |||
668 | ||||
669 | static void handlePtGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
670 | Expr *Arg = nullptr; | |||
671 | if (!checkGuardedByAttrCommon(S, D, AL, Arg)) | |||
672 | return; | |||
673 | ||||
674 | if (!threadSafetyCheckIsPointer(S, D, AL)) | |||
675 | return; | |||
676 | ||||
677 | D->addAttr(::new (S.Context) PtGuardedByAttr( | |||
678 | AL.getRange(), S.Context, Arg, AL.getAttributeSpellingListIndex())); | |||
679 | } | |||
680 | ||||
681 | static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL, | |||
682 | SmallVectorImpl<Expr *> &Args) { | |||
683 | if (!checkAttributeAtLeastNumArgs(S, AL, 1)) | |||
684 | return false; | |||
685 | ||||
686 | // Check that this attribute only applies to lockable types. | |||
687 | QualType QT = cast<ValueDecl>(D)->getType(); | |||
688 | if (!QT->isDependentType() && !typeHasCapability(S, QT)) { | |||
689 | S.Diag(AL.getLoc(), diag::warn_thread_attribute_decl_not_lockable) | |||
690 | << AL.getName(); | |||
691 | return false; | |||
692 | } | |||
693 | ||||
694 | // Check that all arguments are lockable objects. | |||
695 | checkAttrArgsAreCapabilityObjs(S, D, AL, Args); | |||
696 | if (Args.empty()) | |||
697 | return false; | |||
698 | ||||
699 | return true; | |||
700 | } | |||
701 | ||||
702 | static void handleAcquiredAfterAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
703 | SmallVector<Expr *, 1> Args; | |||
704 | if (!checkAcquireOrderAttrCommon(S, D, AL, Args)) | |||
705 | return; | |||
706 | ||||
707 | Expr **StartArg = &Args[0]; | |||
708 | D->addAttr(::new (S.Context) AcquiredAfterAttr( | |||
709 | AL.getRange(), S.Context, StartArg, Args.size(), | |||
710 | AL.getAttributeSpellingListIndex())); | |||
711 | } | |||
712 | ||||
713 | static void handleAcquiredBeforeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
714 | SmallVector<Expr *, 1> Args; | |||
715 | if (!checkAcquireOrderAttrCommon(S, D, AL, Args)) | |||
716 | return; | |||
717 | ||||
718 | Expr **StartArg = &Args[0]; | |||
719 | D->addAttr(::new (S.Context) AcquiredBeforeAttr( | |||
720 | AL.getRange(), S.Context, StartArg, Args.size(), | |||
721 | AL.getAttributeSpellingListIndex())); | |||
722 | } | |||
723 | ||||
724 | static bool checkLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL, | |||
725 | SmallVectorImpl<Expr *> &Args) { | |||
726 | // zero or more arguments ok | |||
727 | // check that all arguments are lockable objects | |||
728 | checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 0, /*ParamIdxOk=*/true); | |||
729 | ||||
730 | return true; | |||
731 | } | |||
732 | ||||
733 | static void handleAssertSharedLockAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
734 | SmallVector<Expr *, 1> Args; | |||
735 | if (!checkLockFunAttrCommon(S, D, AL, Args)) | |||
736 | return; | |||
737 | ||||
738 | unsigned Size = Args.size(); | |||
739 | Expr **StartArg = Size == 0 ? nullptr : &Args[0]; | |||
740 | D->addAttr(::new (S.Context) | |||
741 | AssertSharedLockAttr(AL.getRange(), S.Context, StartArg, Size, | |||
742 | AL.getAttributeSpellingListIndex())); | |||
743 | } | |||
744 | ||||
745 | static void handleAssertExclusiveLockAttr(Sema &S, Decl *D, | |||
746 | const ParsedAttr &AL) { | |||
747 | SmallVector<Expr *, 1> Args; | |||
748 | if (!checkLockFunAttrCommon(S, D, AL, Args)) | |||
749 | return; | |||
750 | ||||
751 | unsigned Size = Args.size(); | |||
752 | Expr **StartArg = Size == 0 ? nullptr : &Args[0]; | |||
753 | D->addAttr(::new (S.Context) AssertExclusiveLockAttr( | |||
754 | AL.getRange(), S.Context, StartArg, Size, | |||
755 | AL.getAttributeSpellingListIndex())); | |||
756 | } | |||
757 | ||||
758 | /// Checks to be sure that the given parameter number is in bounds, and | |||
759 | /// is an integral type. Will emit appropriate diagnostics if this returns | |||
760 | /// false. | |||
761 | /// | |||
762 | /// AttrArgNo is used to actually retrieve the argument, so it's base-0. | |||
763 | template <typename AttrInfo> | |||
764 | static bool checkParamIsIntegerType(Sema &S, const FunctionDecl *FD, | |||
765 | const AttrInfo &AI, unsigned AttrArgNo) { | |||
766 | assert(AI.isArgExpr(AttrArgNo) && "Expected expression argument")(static_cast <bool> (AI.isArgExpr(AttrArgNo) && "Expected expression argument") ? void (0) : __assert_fail ( "AI.isArgExpr(AttrArgNo) && \"Expected expression argument\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 766, __extension__ __PRETTY_FUNCTION__)); | |||
767 | Expr *AttrArg = AI.getArgAsExpr(AttrArgNo); | |||
768 | ParamIdx Idx; | |||
769 | if (!checkFunctionOrMethodParameterIndex(S, FD, AI, AttrArgNo + 1, AttrArg, | |||
770 | Idx)) | |||
771 | return false; | |||
772 | ||||
773 | const ParmVarDecl *Param = FD->getParamDecl(Idx.getASTIndex()); | |||
774 | if (!Param->getType()->isIntegerType() && !Param->getType()->isCharType()) { | |||
775 | SourceLocation SrcLoc = AttrArg->getLocStart(); | |||
776 | S.Diag(SrcLoc, diag::err_attribute_integers_only) | |||
777 | << getAttrName(AI) << Param->getSourceRange(); | |||
778 | return false; | |||
779 | } | |||
780 | return true; | |||
781 | } | |||
782 | ||||
783 | static void handleAllocSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
784 | if (!checkAttributeAtLeastNumArgs(S, AL, 1) || | |||
785 | !checkAttributeAtMostNumArgs(S, AL, 2)) | |||
786 | return; | |||
787 | ||||
788 | const auto *FD = cast<FunctionDecl>(D); | |||
789 | if (!FD->getReturnType()->isPointerType()) { | |||
790 | S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only) | |||
791 | << AL.getName(); | |||
792 | return; | |||
793 | } | |||
794 | ||||
795 | const Expr *SizeExpr = AL.getArgAsExpr(0); | |||
796 | int SizeArgNoVal; | |||
797 | // Parameter indices are 1-indexed, hence Index=1 | |||
798 | if (!checkPositiveIntArgument(S, AL, SizeExpr, SizeArgNoVal, /*Index=*/1)) | |||
799 | return; | |||
800 | if (!checkParamIsIntegerType(S, FD, AL, /*AttrArgNo=*/0)) | |||
801 | return; | |||
802 | ParamIdx SizeArgNo(SizeArgNoVal, D); | |||
803 | ||||
804 | ParamIdx NumberArgNo; | |||
805 | if (AL.getNumArgs() == 2) { | |||
806 | const Expr *NumberExpr = AL.getArgAsExpr(1); | |||
807 | int Val; | |||
808 | // Parameter indices are 1-based, hence Index=2 | |||
809 | if (!checkPositiveIntArgument(S, AL, NumberExpr, Val, /*Index=*/2)) | |||
810 | return; | |||
811 | if (!checkParamIsIntegerType(S, FD, AL, /*AttrArgNo=*/1)) | |||
812 | return; | |||
813 | NumberArgNo = ParamIdx(Val, D); | |||
814 | } | |||
815 | ||||
816 | D->addAttr(::new (S.Context) | |||
817 | AllocSizeAttr(AL.getRange(), S.Context, SizeArgNo, NumberArgNo, | |||
818 | AL.getAttributeSpellingListIndex())); | |||
819 | } | |||
820 | ||||
821 | static bool checkTryLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL, | |||
822 | SmallVectorImpl<Expr *> &Args) { | |||
823 | if (!checkAttributeAtLeastNumArgs(S, AL, 1)) | |||
824 | return false; | |||
825 | ||||
826 | if (!isIntOrBool(AL.getArgAsExpr(0))) { | |||
827 | S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type) | |||
828 | << AL.getName() << 1 << AANT_ArgumentIntOrBool; | |||
829 | return false; | |||
830 | } | |||
831 | ||||
832 | // check that all arguments are lockable objects | |||
833 | checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 1); | |||
834 | ||||
835 | return true; | |||
836 | } | |||
837 | ||||
838 | static void handleSharedTrylockFunctionAttr(Sema &S, Decl *D, | |||
839 | const ParsedAttr &AL) { | |||
840 | SmallVector<Expr*, 2> Args; | |||
841 | if (!checkTryLockFunAttrCommon(S, D, AL, Args)) | |||
842 | return; | |||
843 | ||||
844 | D->addAttr(::new (S.Context) SharedTrylockFunctionAttr( | |||
845 | AL.getRange(), S.Context, AL.getArgAsExpr(0), Args.data(), Args.size(), | |||
846 | AL.getAttributeSpellingListIndex())); | |||
847 | } | |||
848 | ||||
849 | static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D, | |||
850 | const ParsedAttr &AL) { | |||
851 | SmallVector<Expr*, 2> Args; | |||
852 | if (!checkTryLockFunAttrCommon(S, D, AL, Args)) | |||
853 | return; | |||
854 | ||||
855 | D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr( | |||
856 | AL.getRange(), S.Context, AL.getArgAsExpr(0), Args.data(), | |||
857 | Args.size(), AL.getAttributeSpellingListIndex())); | |||
858 | } | |||
859 | ||||
860 | static void handleLockReturnedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
861 | // check that the argument is lockable object | |||
862 | SmallVector<Expr*, 1> Args; | |||
863 | checkAttrArgsAreCapabilityObjs(S, D, AL, Args); | |||
864 | unsigned Size = Args.size(); | |||
865 | if (Size == 0) | |||
866 | return; | |||
867 | ||||
868 | D->addAttr(::new (S.Context) | |||
869 | LockReturnedAttr(AL.getRange(), S.Context, Args[0], | |||
870 | AL.getAttributeSpellingListIndex())); | |||
871 | } | |||
872 | ||||
873 | static void handleLocksExcludedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
874 | if (!checkAttributeAtLeastNumArgs(S, AL, 1)) | |||
875 | return; | |||
876 | ||||
877 | // check that all arguments are lockable objects | |||
878 | SmallVector<Expr*, 1> Args; | |||
879 | checkAttrArgsAreCapabilityObjs(S, D, AL, Args); | |||
880 | unsigned Size = Args.size(); | |||
881 | if (Size == 0) | |||
882 | return; | |||
883 | Expr **StartArg = &Args[0]; | |||
884 | ||||
885 | D->addAttr(::new (S.Context) | |||
886 | LocksExcludedAttr(AL.getRange(), S.Context, StartArg, Size, | |||
887 | AL.getAttributeSpellingListIndex())); | |||
888 | } | |||
889 | ||||
890 | static bool checkFunctionConditionAttr(Sema &S, Decl *D, const ParsedAttr &AL, | |||
891 | Expr *&Cond, StringRef &Msg) { | |||
892 | Cond = AL.getArgAsExpr(0); | |||
893 | if (!Cond->isTypeDependent()) { | |||
894 | ExprResult Converted = S.PerformContextuallyConvertToBool(Cond); | |||
895 | if (Converted.isInvalid()) | |||
896 | return false; | |||
897 | Cond = Converted.get(); | |||
898 | } | |||
899 | ||||
900 | if (!S.checkStringLiteralArgumentAttr(AL, 1, Msg)) | |||
901 | return false; | |||
902 | ||||
903 | if (Msg.empty()) | |||
904 | Msg = "<no message provided>"; | |||
905 | ||||
906 | SmallVector<PartialDiagnosticAt, 8> Diags; | |||
907 | if (isa<FunctionDecl>(D) && !Cond->isValueDependent() && | |||
908 | !Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(D), | |||
909 | Diags)) { | |||
910 | S.Diag(AL.getLoc(), diag::err_attr_cond_never_constant_expr) | |||
911 | << AL.getName(); | |||
912 | for (const PartialDiagnosticAt &PDiag : Diags) | |||
913 | S.Diag(PDiag.first, PDiag.second); | |||
914 | return false; | |||
915 | } | |||
916 | return true; | |||
917 | } | |||
918 | ||||
919 | static void handleEnableIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
920 | S.Diag(AL.getLoc(), diag::ext_clang_enable_if); | |||
921 | ||||
922 | Expr *Cond; | |||
923 | StringRef Msg; | |||
924 | if (checkFunctionConditionAttr(S, D, AL, Cond, Msg)) | |||
925 | D->addAttr(::new (S.Context) | |||
926 | EnableIfAttr(AL.getRange(), S.Context, Cond, Msg, | |||
927 | AL.getAttributeSpellingListIndex())); | |||
928 | } | |||
929 | ||||
930 | namespace { | |||
931 | /// Determines if a given Expr references any of the given function's | |||
932 | /// ParmVarDecls, or the function's implicit `this` parameter (if applicable). | |||
933 | class ArgumentDependenceChecker | |||
934 | : public RecursiveASTVisitor<ArgumentDependenceChecker> { | |||
935 | #ifndef NDEBUG | |||
936 | const CXXRecordDecl *ClassType; | |||
937 | #endif | |||
938 | llvm::SmallPtrSet<const ParmVarDecl *, 16> Parms; | |||
939 | bool Result; | |||
940 | ||||
941 | public: | |||
942 | ArgumentDependenceChecker(const FunctionDecl *FD) { | |||
943 | #ifndef NDEBUG | |||
944 | if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) | |||
945 | ClassType = MD->getParent(); | |||
946 | else | |||
947 | ClassType = nullptr; | |||
948 | #endif | |||
949 | Parms.insert(FD->param_begin(), FD->param_end()); | |||
950 | } | |||
951 | ||||
952 | bool referencesArgs(Expr *E) { | |||
953 | Result = false; | |||
954 | TraverseStmt(E); | |||
955 | return Result; | |||
956 | } | |||
957 | ||||
958 | bool VisitCXXThisExpr(CXXThisExpr *E) { | |||
959 | assert(E->getType()->getPointeeCXXRecordDecl() == ClassType &&(static_cast <bool> (E->getType()->getPointeeCXXRecordDecl () == ClassType && "`this` doesn't refer to the enclosing class?" ) ? void (0) : __assert_fail ("E->getType()->getPointeeCXXRecordDecl() == ClassType && \"`this` doesn't refer to the enclosing class?\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 960, __extension__ __PRETTY_FUNCTION__)) | |||
960 | "`this` doesn't refer to the enclosing class?")(static_cast <bool> (E->getType()->getPointeeCXXRecordDecl () == ClassType && "`this` doesn't refer to the enclosing class?" ) ? void (0) : __assert_fail ("E->getType()->getPointeeCXXRecordDecl() == ClassType && \"`this` doesn't refer to the enclosing class?\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 960, __extension__ __PRETTY_FUNCTION__)); | |||
961 | Result = true; | |||
962 | return false; | |||
963 | } | |||
964 | ||||
965 | bool VisitDeclRefExpr(DeclRefExpr *DRE) { | |||
966 | if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) | |||
967 | if (Parms.count(PVD)) { | |||
968 | Result = true; | |||
969 | return false; | |||
970 | } | |||
971 | return true; | |||
972 | } | |||
973 | }; | |||
974 | } | |||
975 | ||||
976 | static void handleDiagnoseIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
977 | S.Diag(AL.getLoc(), diag::ext_clang_diagnose_if); | |||
978 | ||||
979 | Expr *Cond; | |||
980 | StringRef Msg; | |||
981 | if (!checkFunctionConditionAttr(S, D, AL, Cond, Msg)) | |||
982 | return; | |||
983 | ||||
984 | StringRef DiagTypeStr; | |||
985 | if (!S.checkStringLiteralArgumentAttr(AL, 2, DiagTypeStr)) | |||
986 | return; | |||
987 | ||||
988 | DiagnoseIfAttr::DiagnosticType DiagType; | |||
989 | if (!DiagnoseIfAttr::ConvertStrToDiagnosticType(DiagTypeStr, DiagType)) { | |||
990 | S.Diag(AL.getArgAsExpr(2)->getLocStart(), | |||
991 | diag::err_diagnose_if_invalid_diagnostic_type); | |||
992 | return; | |||
993 | } | |||
994 | ||||
995 | bool ArgDependent = false; | |||
996 | if (const auto *FD = dyn_cast<FunctionDecl>(D)) | |||
997 | ArgDependent = ArgumentDependenceChecker(FD).referencesArgs(Cond); | |||
998 | D->addAttr(::new (S.Context) DiagnoseIfAttr( | |||
999 | AL.getRange(), S.Context, Cond, Msg, DiagType, ArgDependent, | |||
1000 | cast<NamedDecl>(D), AL.getAttributeSpellingListIndex())); | |||
1001 | } | |||
1002 | ||||
1003 | static void handlePassObjectSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1004 | if (D->hasAttr<PassObjectSizeAttr>()) { | |||
1005 | S.Diag(D->getLocStart(), diag::err_attribute_only_once_per_parameter) | |||
1006 | << AL.getName(); | |||
1007 | return; | |||
1008 | } | |||
1009 | ||||
1010 | Expr *E = AL.getArgAsExpr(0); | |||
1011 | uint32_t Type; | |||
1012 | if (!checkUInt32Argument(S, AL, E, Type, /*Idx=*/1)) | |||
1013 | return; | |||
1014 | ||||
1015 | // pass_object_size's argument is passed in as the second argument of | |||
1016 | // __builtin_object_size. So, it has the same constraints as that second | |||
1017 | // argument; namely, it must be in the range [0, 3]. | |||
1018 | if (Type > 3) { | |||
1019 | S.Diag(E->getLocStart(), diag::err_attribute_argument_outof_range) | |||
1020 | << AL.getName() << 0 << 3 << E->getSourceRange(); | |||
1021 | return; | |||
1022 | } | |||
1023 | ||||
1024 | // pass_object_size is only supported on constant pointer parameters; as a | |||
1025 | // kindness to users, we allow the parameter to be non-const for declarations. | |||
1026 | // At this point, we have no clue if `D` belongs to a function declaration or | |||
1027 | // definition, so we defer the constness check until later. | |||
1028 | if (!cast<ParmVarDecl>(D)->getType()->isPointerType()) { | |||
1029 | S.Diag(D->getLocStart(), diag::err_attribute_pointers_only) | |||
1030 | << AL.getName() << 1; | |||
1031 | return; | |||
1032 | } | |||
1033 | ||||
1034 | D->addAttr(::new (S.Context) PassObjectSizeAttr( | |||
1035 | AL.getRange(), S.Context, (int)Type, AL.getAttributeSpellingListIndex())); | |||
1036 | } | |||
1037 | ||||
1038 | static void handleConsumableAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1039 | ConsumableAttr::ConsumedState DefaultState; | |||
1040 | ||||
1041 | if (AL.isArgIdent(0)) { | |||
1042 | IdentifierLoc *IL = AL.getArgAsIdent(0); | |||
1043 | if (!ConsumableAttr::ConvertStrToConsumedState(IL->Ident->getName(), | |||
1044 | DefaultState)) { | |||
1045 | S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) | |||
1046 | << AL.getName() << IL->Ident; | |||
1047 | return; | |||
1048 | } | |||
1049 | } else { | |||
1050 | S.Diag(AL.getLoc(), diag::err_attribute_argument_type) | |||
1051 | << AL.getName() << AANT_ArgumentIdentifier; | |||
1052 | return; | |||
1053 | } | |||
1054 | ||||
1055 | D->addAttr(::new (S.Context) | |||
1056 | ConsumableAttr(AL.getRange(), S.Context, DefaultState, | |||
1057 | AL.getAttributeSpellingListIndex())); | |||
1058 | } | |||
1059 | ||||
1060 | static bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD, | |||
1061 | const ParsedAttr &AL) { | |||
1062 | ASTContext &CurrContext = S.getASTContext(); | |||
1063 | QualType ThisType = MD->getThisType(CurrContext)->getPointeeType(); | |||
1064 | ||||
1065 | if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) { | |||
1066 | if (!RD->hasAttr<ConsumableAttr>()) { | |||
1067 | S.Diag(AL.getLoc(), diag::warn_attr_on_unconsumable_class) << | |||
1068 | RD->getNameAsString(); | |||
1069 | ||||
1070 | return false; | |||
1071 | } | |||
1072 | } | |||
1073 | ||||
1074 | return true; | |||
1075 | } | |||
1076 | ||||
1077 | static void handleCallableWhenAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1078 | if (!checkAttributeAtLeastNumArgs(S, AL, 1)) | |||
1079 | return; | |||
1080 | ||||
1081 | if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL)) | |||
1082 | return; | |||
1083 | ||||
1084 | SmallVector<CallableWhenAttr::ConsumedState, 3> States; | |||
1085 | for (unsigned ArgIndex = 0; ArgIndex < AL.getNumArgs(); ++ArgIndex) { | |||
1086 | CallableWhenAttr::ConsumedState CallableState; | |||
1087 | ||||
1088 | StringRef StateString; | |||
1089 | SourceLocation Loc; | |||
1090 | if (AL.isArgIdent(ArgIndex)) { | |||
1091 | IdentifierLoc *Ident = AL.getArgAsIdent(ArgIndex); | |||
1092 | StateString = Ident->Ident->getName(); | |||
1093 | Loc = Ident->Loc; | |||
1094 | } else { | |||
1095 | if (!S.checkStringLiteralArgumentAttr(AL, ArgIndex, StateString, &Loc)) | |||
1096 | return; | |||
1097 | } | |||
1098 | ||||
1099 | if (!CallableWhenAttr::ConvertStrToConsumedState(StateString, | |||
1100 | CallableState)) { | |||
1101 | S.Diag(Loc, diag::warn_attribute_type_not_supported) | |||
1102 | << AL.getName() << StateString; | |||
1103 | return; | |||
1104 | } | |||
1105 | ||||
1106 | States.push_back(CallableState); | |||
1107 | } | |||
1108 | ||||
1109 | D->addAttr(::new (S.Context) | |||
1110 | CallableWhenAttr(AL.getRange(), S.Context, States.data(), | |||
1111 | States.size(), AL.getAttributeSpellingListIndex())); | |||
1112 | } | |||
1113 | ||||
1114 | static void handleParamTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1115 | ParamTypestateAttr::ConsumedState ParamState; | |||
1116 | ||||
1117 | if (AL.isArgIdent(0)) { | |||
1118 | IdentifierLoc *Ident = AL.getArgAsIdent(0); | |||
1119 | StringRef StateString = Ident->Ident->getName(); | |||
1120 | ||||
1121 | if (!ParamTypestateAttr::ConvertStrToConsumedState(StateString, | |||
1122 | ParamState)) { | |||
1123 | S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) | |||
1124 | << AL.getName() << StateString; | |||
1125 | return; | |||
1126 | } | |||
1127 | } else { | |||
1128 | S.Diag(AL.getLoc(), diag::err_attribute_argument_type) << | |||
1129 | AL.getName() << AANT_ArgumentIdentifier; | |||
1130 | return; | |||
1131 | } | |||
1132 | ||||
1133 | // FIXME: This check is currently being done in the analysis. It can be | |||
1134 | // enabled here only after the parser propagates attributes at | |||
1135 | // template specialization definition, not declaration. | |||
1136 | //QualType ReturnType = cast<ParmVarDecl>(D)->getType(); | |||
1137 | //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl(); | |||
1138 | // | |||
1139 | //if (!RD || !RD->hasAttr<ConsumableAttr>()) { | |||
1140 | // S.Diag(AL.getLoc(), diag::warn_return_state_for_unconsumable_type) << | |||
1141 | // ReturnType.getAsString(); | |||
1142 | // return; | |||
1143 | //} | |||
1144 | ||||
1145 | D->addAttr(::new (S.Context) | |||
1146 | ParamTypestateAttr(AL.getRange(), S.Context, ParamState, | |||
1147 | AL.getAttributeSpellingListIndex())); | |||
1148 | } | |||
1149 | ||||
1150 | static void handleReturnTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1151 | ReturnTypestateAttr::ConsumedState ReturnState; | |||
1152 | ||||
1153 | if (AL.isArgIdent(0)) { | |||
1154 | IdentifierLoc *IL = AL.getArgAsIdent(0); | |||
1155 | if (!ReturnTypestateAttr::ConvertStrToConsumedState(IL->Ident->getName(), | |||
1156 | ReturnState)) { | |||
1157 | S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) | |||
1158 | << AL.getName() << IL->Ident; | |||
1159 | return; | |||
1160 | } | |||
1161 | } else { | |||
1162 | S.Diag(AL.getLoc(), diag::err_attribute_argument_type) << | |||
1163 | AL.getName() << AANT_ArgumentIdentifier; | |||
1164 | return; | |||
1165 | } | |||
1166 | ||||
1167 | // FIXME: This check is currently being done in the analysis. It can be | |||
1168 | // enabled here only after the parser propagates attributes at | |||
1169 | // template specialization definition, not declaration. | |||
1170 | //QualType ReturnType; | |||
1171 | // | |||
1172 | //if (const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D)) { | |||
1173 | // ReturnType = Param->getType(); | |||
1174 | // | |||
1175 | //} else if (const CXXConstructorDecl *Constructor = | |||
1176 | // dyn_cast<CXXConstructorDecl>(D)) { | |||
1177 | // ReturnType = Constructor->getThisType(S.getASTContext())->getPointeeType(); | |||
1178 | // | |||
1179 | //} else { | |||
1180 | // | |||
1181 | // ReturnType = cast<FunctionDecl>(D)->getCallResultType(); | |||
1182 | //} | |||
1183 | // | |||
1184 | //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl(); | |||
1185 | // | |||
1186 | //if (!RD || !RD->hasAttr<ConsumableAttr>()) { | |||
1187 | // S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) << | |||
1188 | // ReturnType.getAsString(); | |||
1189 | // return; | |||
1190 | //} | |||
1191 | ||||
1192 | D->addAttr(::new (S.Context) | |||
1193 | ReturnTypestateAttr(AL.getRange(), S.Context, ReturnState, | |||
1194 | AL.getAttributeSpellingListIndex())); | |||
1195 | } | |||
1196 | ||||
1197 | static void handleSetTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1198 | if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL)) | |||
1199 | return; | |||
1200 | ||||
1201 | SetTypestateAttr::ConsumedState NewState; | |||
1202 | if (AL.isArgIdent(0)) { | |||
1203 | IdentifierLoc *Ident = AL.getArgAsIdent(0); | |||
1204 | StringRef Param = Ident->Ident->getName(); | |||
1205 | if (!SetTypestateAttr::ConvertStrToConsumedState(Param, NewState)) { | |||
1206 | S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) | |||
1207 | << AL.getName() << Param; | |||
1208 | return; | |||
1209 | } | |||
1210 | } else { | |||
1211 | S.Diag(AL.getLoc(), diag::err_attribute_argument_type) << | |||
1212 | AL.getName() << AANT_ArgumentIdentifier; | |||
1213 | return; | |||
1214 | } | |||
1215 | ||||
1216 | D->addAttr(::new (S.Context) | |||
1217 | SetTypestateAttr(AL.getRange(), S.Context, NewState, | |||
1218 | AL.getAttributeSpellingListIndex())); | |||
1219 | } | |||
1220 | ||||
1221 | static void handleTestTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1222 | if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL)) | |||
1223 | return; | |||
1224 | ||||
1225 | TestTypestateAttr::ConsumedState TestState; | |||
1226 | if (AL.isArgIdent(0)) { | |||
1227 | IdentifierLoc *Ident = AL.getArgAsIdent(0); | |||
1228 | StringRef Param = Ident->Ident->getName(); | |||
1229 | if (!TestTypestateAttr::ConvertStrToConsumedState(Param, TestState)) { | |||
1230 | S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) | |||
1231 | << AL.getName() << Param; | |||
1232 | return; | |||
1233 | } | |||
1234 | } else { | |||
1235 | S.Diag(AL.getLoc(), diag::err_attribute_argument_type) << | |||
1236 | AL.getName() << AANT_ArgumentIdentifier; | |||
1237 | return; | |||
1238 | } | |||
1239 | ||||
1240 | D->addAttr(::new (S.Context) | |||
1241 | TestTypestateAttr(AL.getRange(), S.Context, TestState, | |||
1242 | AL.getAttributeSpellingListIndex())); | |||
1243 | } | |||
1244 | ||||
1245 | static void handleExtVectorTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1246 | // Remember this typedef decl, we will need it later for diagnostics. | |||
1247 | S.ExtVectorDecls.push_back(cast<TypedefNameDecl>(D)); | |||
1248 | } | |||
1249 | ||||
1250 | static void handlePackedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1251 | if (auto *TD = dyn_cast<TagDecl>(D)) | |||
1252 | TD->addAttr(::new (S.Context) PackedAttr(AL.getRange(), S.Context, | |||
1253 | AL.getAttributeSpellingListIndex())); | |||
1254 | else if (auto *FD = dyn_cast<FieldDecl>(D)) { | |||
1255 | bool BitfieldByteAligned = (!FD->getType()->isDependentType() && | |||
1256 | !FD->getType()->isIncompleteType() && | |||
1257 | FD->isBitField() && | |||
1258 | S.Context.getTypeAlign(FD->getType()) <= 8); | |||
1259 | ||||
1260 | if (S.getASTContext().getTargetInfo().getTriple().isPS4()) { | |||
1261 | if (BitfieldByteAligned) | |||
1262 | // The PS4 target needs to maintain ABI backwards compatibility. | |||
1263 | S.Diag(AL.getLoc(), diag::warn_attribute_ignored_for_field_of_type) | |||
1264 | << AL.getName() << FD->getType(); | |||
1265 | else | |||
1266 | FD->addAttr(::new (S.Context) PackedAttr( | |||
1267 | AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); | |||
1268 | } else { | |||
1269 | // Report warning about changed offset in the newer compiler versions. | |||
1270 | if (BitfieldByteAligned) | |||
1271 | S.Diag(AL.getLoc(), diag::warn_attribute_packed_for_bitfield); | |||
1272 | ||||
1273 | FD->addAttr(::new (S.Context) PackedAttr( | |||
1274 | AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); | |||
1275 | } | |||
1276 | ||||
1277 | } else | |||
1278 | S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL.getName(); | |||
1279 | } | |||
1280 | ||||
1281 | static bool checkIBOutletCommon(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1282 | // The IBOutlet/IBOutletCollection attributes only apply to instance | |||
1283 | // variables or properties of Objective-C classes. The outlet must also | |||
1284 | // have an object reference type. | |||
1285 | if (const auto *VD = dyn_cast<ObjCIvarDecl>(D)) { | |||
1286 | if (!VD->getType()->getAs<ObjCObjectPointerType>()) { | |||
1287 | S.Diag(AL.getLoc(), diag::warn_iboutlet_object_type) | |||
1288 | << AL.getName() << VD->getType() << 0; | |||
1289 | return false; | |||
1290 | } | |||
1291 | } | |||
1292 | else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) { | |||
1293 | if (!PD->getType()->getAs<ObjCObjectPointerType>()) { | |||
1294 | S.Diag(AL.getLoc(), diag::warn_iboutlet_object_type) | |||
1295 | << AL.getName() << PD->getType() << 1; | |||
1296 | return false; | |||
1297 | } | |||
1298 | } | |||
1299 | else { | |||
1300 | S.Diag(AL.getLoc(), diag::warn_attribute_iboutlet) << AL.getName(); | |||
1301 | return false; | |||
1302 | } | |||
1303 | ||||
1304 | return true; | |||
1305 | } | |||
1306 | ||||
1307 | static void handleIBOutlet(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1308 | if (!checkIBOutletCommon(S, D, AL)) | |||
1309 | return; | |||
1310 | ||||
1311 | D->addAttr(::new (S.Context) | |||
1312 | IBOutletAttr(AL.getRange(), S.Context, | |||
1313 | AL.getAttributeSpellingListIndex())); | |||
1314 | } | |||
1315 | ||||
1316 | static void handleIBOutletCollection(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1317 | ||||
1318 | // The iboutletcollection attribute can have zero or one arguments. | |||
1319 | if (AL.getNumArgs() > 1) { | |||
1320 | S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) | |||
1321 | << AL.getName() << 1; | |||
1322 | return; | |||
1323 | } | |||
1324 | ||||
1325 | if (!checkIBOutletCommon(S, D, AL)) | |||
1326 | return; | |||
1327 | ||||
1328 | ParsedType PT; | |||
1329 | ||||
1330 | if (AL.hasParsedType()) | |||
1331 | PT = AL.getTypeArg(); | |||
1332 | else { | |||
1333 | PT = S.getTypeName(S.Context.Idents.get("NSObject"), AL.getLoc(), | |||
1334 | S.getScopeForContext(D->getDeclContext()->getParent())); | |||
1335 | if (!PT) { | |||
1336 | S.Diag(AL.getLoc(), diag::err_iboutletcollection_type) << "NSObject"; | |||
1337 | return; | |||
1338 | } | |||
1339 | } | |||
1340 | ||||
1341 | TypeSourceInfo *QTLoc = nullptr; | |||
1342 | QualType QT = S.GetTypeFromParser(PT, &QTLoc); | |||
1343 | if (!QTLoc) | |||
1344 | QTLoc = S.Context.getTrivialTypeSourceInfo(QT, AL.getLoc()); | |||
1345 | ||||
1346 | // Diagnose use of non-object type in iboutletcollection attribute. | |||
1347 | // FIXME. Gnu attribute extension ignores use of builtin types in | |||
1348 | // attributes. So, __attribute__((iboutletcollection(char))) will be | |||
1349 | // treated as __attribute__((iboutletcollection())). | |||
1350 | if (!QT->isObjCIdType() && !QT->isObjCObjectType()) { | |||
1351 | S.Diag(AL.getLoc(), | |||
1352 | QT->isBuiltinType() ? diag::err_iboutletcollection_builtintype | |||
1353 | : diag::err_iboutletcollection_type) << QT; | |||
1354 | return; | |||
1355 | } | |||
1356 | ||||
1357 | D->addAttr(::new (S.Context) | |||
1358 | IBOutletCollectionAttr(AL.getRange(), S.Context, QTLoc, | |||
1359 | AL.getAttributeSpellingListIndex())); | |||
1360 | } | |||
1361 | ||||
1362 | bool Sema::isValidPointerAttrType(QualType T, bool RefOkay) { | |||
1363 | if (RefOkay) { | |||
1364 | if (T->isReferenceType()) | |||
1365 | return true; | |||
1366 | } else { | |||
1367 | T = T.getNonReferenceType(); | |||
1368 | } | |||
1369 | ||||
1370 | // The nonnull attribute, and other similar attributes, can be applied to a | |||
1371 | // transparent union that contains a pointer type. | |||
1372 | if (const RecordType *UT = T->getAsUnionType()) { | |||
1373 | if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) { | |||
1374 | RecordDecl *UD = UT->getDecl(); | |||
1375 | for (const auto *I : UD->fields()) { | |||
1376 | QualType QT = I->getType(); | |||
1377 | if (QT->isAnyPointerType() || QT->isBlockPointerType()) | |||
1378 | return true; | |||
1379 | } | |||
1380 | } | |||
1381 | } | |||
1382 | ||||
1383 | return T->isAnyPointerType() || T->isBlockPointerType(); | |||
1384 | } | |||
1385 | ||||
1386 | static bool attrNonNullArgCheck(Sema &S, QualType T, const ParsedAttr &AL, | |||
1387 | SourceRange AttrParmRange, | |||
1388 | SourceRange TypeRange, | |||
1389 | bool isReturnValue = false) { | |||
1390 | if (!S.isValidPointerAttrType(T)) { | |||
1391 | if (isReturnValue) | |||
1392 | S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only) | |||
1393 | << AL.getName() << AttrParmRange << TypeRange; | |||
1394 | else | |||
1395 | S.Diag(AL.getLoc(), diag::warn_attribute_pointers_only) | |||
1396 | << AL.getName() << AttrParmRange << TypeRange << 0; | |||
1397 | return false; | |||
1398 | } | |||
1399 | return true; | |||
1400 | } | |||
1401 | ||||
1402 | static void handleNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1403 | SmallVector<ParamIdx, 8> NonNullArgs; | |||
1404 | for (unsigned I = 0; I < AL.getNumArgs(); ++I) { | |||
1405 | Expr *Ex = AL.getArgAsExpr(I); | |||
1406 | ParamIdx Idx; | |||
1407 | if (!checkFunctionOrMethodParameterIndex(S, D, AL, I + 1, Ex, Idx)) | |||
1408 | return; | |||
1409 | ||||
1410 | // Is the function argument a pointer type? | |||
1411 | if (Idx.getASTIndex() < getFunctionOrMethodNumParams(D) && | |||
1412 | !attrNonNullArgCheck( | |||
1413 | S, getFunctionOrMethodParamType(D, Idx.getASTIndex()), AL, | |||
1414 | Ex->getSourceRange(), | |||
1415 | getFunctionOrMethodParamRange(D, Idx.getASTIndex()))) | |||
1416 | continue; | |||
1417 | ||||
1418 | NonNullArgs.push_back(Idx); | |||
1419 | } | |||
1420 | ||||
1421 | // If no arguments were specified to __attribute__((nonnull)) then all pointer | |||
1422 | // arguments have a nonnull attribute; warn if there aren't any. Skip this | |||
1423 | // check if the attribute came from a macro expansion or a template | |||
1424 | // instantiation. | |||
1425 | if (NonNullArgs.empty() && AL.getLoc().isFileID() && | |||
1426 | !S.inTemplateInstantiation()) { | |||
1427 | bool AnyPointers = isFunctionOrMethodVariadic(D); | |||
1428 | for (unsigned I = 0, E = getFunctionOrMethodNumParams(D); | |||
1429 | I != E && !AnyPointers; ++I) { | |||
1430 | QualType T = getFunctionOrMethodParamType(D, I); | |||
1431 | if (T->isDependentType() || S.isValidPointerAttrType(T)) | |||
1432 | AnyPointers = true; | |||
1433 | } | |||
1434 | ||||
1435 | if (!AnyPointers) | |||
1436 | S.Diag(AL.getLoc(), diag::warn_attribute_nonnull_no_pointers); | |||
1437 | } | |||
1438 | ||||
1439 | ParamIdx *Start = NonNullArgs.data(); | |||
1440 | unsigned Size = NonNullArgs.size(); | |||
1441 | llvm::array_pod_sort(Start, Start + Size); | |||
1442 | D->addAttr(::new (S.Context) | |||
1443 | NonNullAttr(AL.getRange(), S.Context, Start, Size, | |||
1444 | AL.getAttributeSpellingListIndex())); | |||
1445 | } | |||
1446 | ||||
1447 | static void handleNonNullAttrParameter(Sema &S, ParmVarDecl *D, | |||
1448 | const ParsedAttr &AL) { | |||
1449 | if (AL.getNumArgs() > 0) { | |||
1450 | if (D->getFunctionType()) { | |||
1451 | handleNonNullAttr(S, D, AL); | |||
1452 | } else { | |||
1453 | S.Diag(AL.getLoc(), diag::warn_attribute_nonnull_parm_no_args) | |||
1454 | << D->getSourceRange(); | |||
1455 | } | |||
1456 | return; | |||
1457 | } | |||
1458 | ||||
1459 | // Is the argument a pointer type? | |||
1460 | if (!attrNonNullArgCheck(S, D->getType(), AL, SourceRange(), | |||
1461 | D->getSourceRange())) | |||
1462 | return; | |||
1463 | ||||
1464 | D->addAttr(::new (S.Context) | |||
1465 | NonNullAttr(AL.getRange(), S.Context, nullptr, 0, | |||
1466 | AL.getAttributeSpellingListIndex())); | |||
1467 | } | |||
1468 | ||||
1469 | static void handleReturnsNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1470 | QualType ResultType = getFunctionOrMethodResultType(D); | |||
1471 | SourceRange SR = getFunctionOrMethodResultSourceRange(D); | |||
1472 | if (!attrNonNullArgCheck(S, ResultType, AL, SourceRange(), SR, | |||
1473 | /* isReturnValue */ true)) | |||
1474 | return; | |||
1475 | ||||
1476 | D->addAttr(::new (S.Context) | |||
1477 | ReturnsNonNullAttr(AL.getRange(), S.Context, | |||
1478 | AL.getAttributeSpellingListIndex())); | |||
1479 | } | |||
1480 | ||||
1481 | static void handleNoEscapeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1482 | if (D->isInvalidDecl()) | |||
1483 | return; | |||
1484 | ||||
1485 | // noescape only applies to pointer types. | |||
1486 | QualType T = cast<ParmVarDecl>(D)->getType(); | |||
1487 | if (!S.isValidPointerAttrType(T, /* RefOkay */ true)) { | |||
1488 | S.Diag(AL.getLoc(), diag::warn_attribute_pointers_only) | |||
1489 | << AL.getName() << AL.getRange() << 0; | |||
1490 | return; | |||
1491 | } | |||
1492 | ||||
1493 | D->addAttr(::new (S.Context) NoEscapeAttr( | |||
1494 | AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); | |||
1495 | } | |||
1496 | ||||
1497 | static void handleAssumeAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1498 | Expr *E = AL.getArgAsExpr(0), | |||
1499 | *OE = AL.getNumArgs() > 1 ? AL.getArgAsExpr(1) : nullptr; | |||
1500 | S.AddAssumeAlignedAttr(AL.getRange(), D, E, OE, | |||
1501 | AL.getAttributeSpellingListIndex()); | |||
1502 | } | |||
1503 | ||||
1504 | static void handleAllocAlignAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1505 | S.AddAllocAlignAttr(AL.getRange(), D, AL.getArgAsExpr(0), | |||
1506 | AL.getAttributeSpellingListIndex()); | |||
1507 | } | |||
1508 | ||||
1509 | void Sema::AddAssumeAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, | |||
1510 | Expr *OE, unsigned SpellingListIndex) { | |||
1511 | QualType ResultType = getFunctionOrMethodResultType(D); | |||
1512 | SourceRange SR = getFunctionOrMethodResultSourceRange(D); | |||
1513 | ||||
1514 | AssumeAlignedAttr TmpAttr(AttrRange, Context, E, OE, SpellingListIndex); | |||
1515 | SourceLocation AttrLoc = AttrRange.getBegin(); | |||
1516 | ||||
1517 | if (!isValidPointerAttrType(ResultType, /* RefOkay */ true)) { | |||
1518 | Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only) | |||
1519 | << &TmpAttr << AttrRange << SR; | |||
1520 | return; | |||
1521 | } | |||
1522 | ||||
1523 | if (!E->isValueDependent()) { | |||
1524 | llvm::APSInt I(64); | |||
1525 | if (!E->isIntegerConstantExpr(I, Context)) { | |||
1526 | if (OE) | |||
1527 | Diag(AttrLoc, diag::err_attribute_argument_n_type) | |||
1528 | << &TmpAttr << 1 << AANT_ArgumentIntegerConstant | |||
1529 | << E->getSourceRange(); | |||
1530 | else | |||
1531 | Diag(AttrLoc, diag::err_attribute_argument_type) | |||
1532 | << &TmpAttr << AANT_ArgumentIntegerConstant | |||
1533 | << E->getSourceRange(); | |||
1534 | return; | |||
1535 | } | |||
1536 | ||||
1537 | if (!I.isPowerOf2()) { | |||
1538 | Diag(AttrLoc, diag::err_alignment_not_power_of_two) | |||
1539 | << E->getSourceRange(); | |||
1540 | return; | |||
1541 | } | |||
1542 | } | |||
1543 | ||||
1544 | if (OE) { | |||
1545 | if (!OE->isValueDependent()) { | |||
1546 | llvm::APSInt I(64); | |||
1547 | if (!OE->isIntegerConstantExpr(I, Context)) { | |||
1548 | Diag(AttrLoc, diag::err_attribute_argument_n_type) | |||
1549 | << &TmpAttr << 2 << AANT_ArgumentIntegerConstant | |||
1550 | << OE->getSourceRange(); | |||
1551 | return; | |||
1552 | } | |||
1553 | } | |||
1554 | } | |||
1555 | ||||
1556 | D->addAttr(::new (Context) | |||
1557 | AssumeAlignedAttr(AttrRange, Context, E, OE, SpellingListIndex)); | |||
1558 | } | |||
1559 | ||||
1560 | void Sema::AddAllocAlignAttr(SourceRange AttrRange, Decl *D, Expr *ParamExpr, | |||
1561 | unsigned SpellingListIndex) { | |||
1562 | QualType ResultType = getFunctionOrMethodResultType(D); | |||
1563 | ||||
1564 | AllocAlignAttr TmpAttr(AttrRange, Context, ParamIdx(), SpellingListIndex); | |||
1565 | SourceLocation AttrLoc = AttrRange.getBegin(); | |||
1566 | ||||
1567 | if (!ResultType->isDependentType() && | |||
1568 | !isValidPointerAttrType(ResultType, /* RefOkay */ true)) { | |||
1569 | Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only) | |||
1570 | << &TmpAttr << AttrRange << getFunctionOrMethodResultSourceRange(D); | |||
1571 | return; | |||
1572 | } | |||
1573 | ||||
1574 | ParamIdx Idx; | |||
1575 | const auto *FuncDecl = cast<FunctionDecl>(D); | |||
1576 | if (!checkFunctionOrMethodParameterIndex(*this, FuncDecl, TmpAttr, | |||
1577 | /*AttrArgNo=*/1, ParamExpr, Idx)) | |||
1578 | return; | |||
1579 | ||||
1580 | QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex()); | |||
1581 | if (!Ty->isDependentType() && !Ty->isIntegralType(Context)) { | |||
1582 | Diag(ParamExpr->getLocStart(), diag::err_attribute_integers_only) | |||
1583 | << &TmpAttr | |||
1584 | << FuncDecl->getParamDecl(Idx.getASTIndex())->getSourceRange(); | |||
1585 | return; | |||
1586 | } | |||
1587 | ||||
1588 | D->addAttr(::new (Context) | |||
1589 | AllocAlignAttr(AttrRange, Context, Idx, SpellingListIndex)); | |||
1590 | } | |||
1591 | ||||
1592 | /// Normalize the attribute, __foo__ becomes foo. | |||
1593 | /// Returns true if normalization was applied. | |||
1594 | static bool normalizeName(StringRef &AttrName) { | |||
1595 | if (AttrName.size() > 4 && AttrName.startswith("__") && | |||
1596 | AttrName.endswith("__")) { | |||
1597 | AttrName = AttrName.drop_front(2).drop_back(2); | |||
1598 | return true; | |||
1599 | } | |||
1600 | return false; | |||
1601 | } | |||
1602 | ||||
1603 | static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1604 | // This attribute must be applied to a function declaration. The first | |||
1605 | // argument to the attribute must be an identifier, the name of the resource, | |||
1606 | // for example: malloc. The following arguments must be argument indexes, the | |||
1607 | // arguments must be of integer type for Returns, otherwise of pointer type. | |||
1608 | // The difference between Holds and Takes is that a pointer may still be used | |||
1609 | // after being held. free() should be __attribute((ownership_takes)), whereas | |||
1610 | // a list append function may well be __attribute((ownership_holds)). | |||
1611 | ||||
1612 | if (!AL.isArgIdent(0)) { | |||
1613 | S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type) | |||
1614 | << AL.getName() << 1 << AANT_ArgumentIdentifier; | |||
1615 | return; | |||
1616 | } | |||
1617 | ||||
1618 | // Figure out our Kind. | |||
1619 | OwnershipAttr::OwnershipKind K = | |||
1620 | OwnershipAttr(AL.getLoc(), S.Context, nullptr, nullptr, 0, | |||
1621 | AL.getAttributeSpellingListIndex()).getOwnKind(); | |||
1622 | ||||
1623 | // Check arguments. | |||
1624 | switch (K) { | |||
1625 | case OwnershipAttr::Takes: | |||
1626 | case OwnershipAttr::Holds: | |||
1627 | if (AL.getNumArgs() < 2) { | |||
1628 | S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) | |||
1629 | << AL.getName() << 2; | |||
1630 | return; | |||
1631 | } | |||
1632 | break; | |||
1633 | case OwnershipAttr::Returns: | |||
1634 | if (AL.getNumArgs() > 2) { | |||
1635 | S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) | |||
1636 | << AL.getName() << 1; | |||
1637 | return; | |||
1638 | } | |||
1639 | break; | |||
1640 | } | |||
1641 | ||||
1642 | IdentifierInfo *Module = AL.getArgAsIdent(0)->Ident; | |||
1643 | ||||
1644 | StringRef ModuleName = Module->getName(); | |||
1645 | if (normalizeName(ModuleName)) { | |||
1646 | Module = &S.PP.getIdentifierTable().get(ModuleName); | |||
1647 | } | |||
1648 | ||||
1649 | SmallVector<ParamIdx, 8> OwnershipArgs; | |||
1650 | for (unsigned i = 1; i < AL.getNumArgs(); ++i) { | |||
1651 | Expr *Ex = AL.getArgAsExpr(i); | |||
1652 | ParamIdx Idx; | |||
1653 | if (!checkFunctionOrMethodParameterIndex(S, D, AL, i, Ex, Idx)) | |||
1654 | return; | |||
1655 | ||||
1656 | // Is the function argument a pointer type? | |||
1657 | QualType T = getFunctionOrMethodParamType(D, Idx.getASTIndex()); | |||
1658 | int Err = -1; // No error | |||
1659 | switch (K) { | |||
1660 | case OwnershipAttr::Takes: | |||
1661 | case OwnershipAttr::Holds: | |||
1662 | if (!T->isAnyPointerType() && !T->isBlockPointerType()) | |||
1663 | Err = 0; | |||
1664 | break; | |||
1665 | case OwnershipAttr::Returns: | |||
1666 | if (!T->isIntegerType()) | |||
1667 | Err = 1; | |||
1668 | break; | |||
1669 | } | |||
1670 | if (-1 != Err) { | |||
1671 | S.Diag(AL.getLoc(), diag::err_ownership_type) << AL.getName() << Err | |||
1672 | << Ex->getSourceRange(); | |||
1673 | return; | |||
1674 | } | |||
1675 | ||||
1676 | // Check we don't have a conflict with another ownership attribute. | |||
1677 | for (const auto *I : D->specific_attrs<OwnershipAttr>()) { | |||
1678 | // Cannot have two ownership attributes of different kinds for the same | |||
1679 | // index. | |||
1680 | if (I->getOwnKind() != K && I->args_end() != | |||
1681 | std::find(I->args_begin(), I->args_end(), Idx)) { | |||
1682 | S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) | |||
1683 | << AL.getName() << I; | |||
1684 | return; | |||
1685 | } else if (K == OwnershipAttr::Returns && | |||
1686 | I->getOwnKind() == OwnershipAttr::Returns) { | |||
1687 | // A returns attribute conflicts with any other returns attribute using | |||
1688 | // a different index. | |||
1689 | if (std::find(I->args_begin(), I->args_end(), Idx) == I->args_end()) { | |||
1690 | S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch) | |||
1691 | << I->args_begin()->getSourceIndex(); | |||
1692 | if (I->args_size()) | |||
1693 | S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch) | |||
1694 | << Idx.getSourceIndex() << Ex->getSourceRange(); | |||
1695 | return; | |||
1696 | } | |||
1697 | } | |||
1698 | } | |||
1699 | OwnershipArgs.push_back(Idx); | |||
1700 | } | |||
1701 | ||||
1702 | ParamIdx *Start = OwnershipArgs.data(); | |||
1703 | unsigned Size = OwnershipArgs.size(); | |||
1704 | llvm::array_pod_sort(Start, Start + Size); | |||
1705 | D->addAttr(::new (S.Context) | |||
1706 | OwnershipAttr(AL.getLoc(), S.Context, Module, Start, Size, | |||
1707 | AL.getAttributeSpellingListIndex())); | |||
1708 | } | |||
1709 | ||||
1710 | static void handleWeakRefAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1711 | // Check the attribute arguments. | |||
1712 | if (AL.getNumArgs() > 1) { | |||
1713 | S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) | |||
1714 | << AL.getName() << 1; | |||
1715 | return; | |||
1716 | } | |||
1717 | ||||
1718 | // gcc rejects | |||
1719 | // class c { | |||
1720 | // static int a __attribute__((weakref ("v2"))); | |||
1721 | // static int b() __attribute__((weakref ("f3"))); | |||
1722 | // }; | |||
1723 | // and ignores the attributes of | |||
1724 | // void f(void) { | |||
1725 | // static int a __attribute__((weakref ("v2"))); | |||
1726 | // } | |||
1727 | // we reject them | |||
1728 | const DeclContext *Ctx = D->getDeclContext()->getRedeclContext(); | |||
1729 | if (!Ctx->isFileContext()) { | |||
1730 | S.Diag(AL.getLoc(), diag::err_attribute_weakref_not_global_context) | |||
1731 | << cast<NamedDecl>(D); | |||
1732 | return; | |||
1733 | } | |||
1734 | ||||
1735 | // The GCC manual says | |||
1736 | // | |||
1737 | // At present, a declaration to which `weakref' is attached can only | |||
1738 | // be `static'. | |||
1739 | // | |||
1740 | // It also says | |||
1741 | // | |||
1742 | // Without a TARGET, | |||
1743 | // given as an argument to `weakref' or to `alias', `weakref' is | |||
1744 | // equivalent to `weak'. | |||
1745 | // | |||
1746 | // gcc 4.4.1 will accept | |||
1747 | // int a7 __attribute__((weakref)); | |||
1748 | // as | |||
1749 | // int a7 __attribute__((weak)); | |||
1750 | // This looks like a bug in gcc. We reject that for now. We should revisit | |||
1751 | // it if this behaviour is actually used. | |||
1752 | ||||
1753 | // GCC rejects | |||
1754 | // static ((alias ("y"), weakref)). | |||
1755 | // Should we? How to check that weakref is before or after alias? | |||
1756 | ||||
1757 | // FIXME: it would be good for us to keep the WeakRefAttr as-written instead | |||
1758 | // of transforming it into an AliasAttr. The WeakRefAttr never uses the | |||
1759 | // StringRef parameter it was given anyway. | |||
1760 | StringRef Str; | |||
1761 | if (AL.getNumArgs() && S.checkStringLiteralArgumentAttr(AL, 0, Str)) | |||
1762 | // GCC will accept anything as the argument of weakref. Should we | |||
1763 | // check for an existing decl? | |||
1764 | D->addAttr(::new (S.Context) AliasAttr(AL.getRange(), S.Context, Str, | |||
1765 | AL.getAttributeSpellingListIndex())); | |||
1766 | ||||
1767 | D->addAttr(::new (S.Context) | |||
1768 | WeakRefAttr(AL.getRange(), S.Context, | |||
1769 | AL.getAttributeSpellingListIndex())); | |||
1770 | } | |||
1771 | ||||
1772 | static void handleIFuncAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1773 | StringRef Str; | |||
1774 | if (!S.checkStringLiteralArgumentAttr(AL, 0, Str)) | |||
1775 | return; | |||
1776 | ||||
1777 | // Aliases should be on declarations, not definitions. | |||
1778 | const auto *FD = cast<FunctionDecl>(D); | |||
1779 | if (FD->isThisDeclarationADefinition()) { | |||
1780 | S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 1; | |||
1781 | return; | |||
1782 | } | |||
1783 | ||||
1784 | D->addAttr(::new (S.Context) IFuncAttr(AL.getRange(), S.Context, Str, | |||
1785 | AL.getAttributeSpellingListIndex())); | |||
1786 | } | |||
1787 | ||||
1788 | static void handleAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1789 | StringRef Str; | |||
1790 | if (!S.checkStringLiteralArgumentAttr(AL, 0, Str)) | |||
1791 | return; | |||
1792 | ||||
1793 | if (S.Context.getTargetInfo().getTriple().isOSDarwin()) { | |||
1794 | S.Diag(AL.getLoc(), diag::err_alias_not_supported_on_darwin); | |||
1795 | return; | |||
1796 | } | |||
1797 | if (S.Context.getTargetInfo().getTriple().isNVPTX()) { | |||
1798 | S.Diag(AL.getLoc(), diag::err_alias_not_supported_on_nvptx); | |||
1799 | } | |||
1800 | ||||
1801 | // Aliases should be on declarations, not definitions. | |||
1802 | if (const auto *FD = dyn_cast<FunctionDecl>(D)) { | |||
1803 | if (FD->isThisDeclarationADefinition()) { | |||
1804 | S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 0; | |||
1805 | return; | |||
1806 | } | |||
1807 | } else { | |||
1808 | const auto *VD = cast<VarDecl>(D); | |||
1809 | if (VD->isThisDeclarationADefinition() && VD->isExternallyVisible()) { | |||
1810 | S.Diag(AL.getLoc(), diag::err_alias_is_definition) << VD << 0; | |||
1811 | return; | |||
1812 | } | |||
1813 | } | |||
1814 | ||||
1815 | // FIXME: check if target symbol exists in current file | |||
1816 | ||||
1817 | D->addAttr(::new (S.Context) AliasAttr(AL.getRange(), S.Context, Str, | |||
1818 | AL.getAttributeSpellingListIndex())); | |||
1819 | } | |||
1820 | ||||
1821 | static void handleTLSModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1822 | StringRef Model; | |||
1823 | SourceLocation LiteralLoc; | |||
1824 | // Check that it is a string. | |||
1825 | if (!S.checkStringLiteralArgumentAttr(AL, 0, Model, &LiteralLoc)) | |||
1826 | return; | |||
1827 | ||||
1828 | // Check that the value. | |||
1829 | if (Model != "global-dynamic" && Model != "local-dynamic" | |||
1830 | && Model != "initial-exec" && Model != "local-exec") { | |||
1831 | S.Diag(LiteralLoc, diag::err_attr_tlsmodel_arg); | |||
1832 | return; | |||
1833 | } | |||
1834 | ||||
1835 | D->addAttr(::new (S.Context) | |||
1836 | TLSModelAttr(AL.getRange(), S.Context, Model, | |||
1837 | AL.getAttributeSpellingListIndex())); | |||
1838 | } | |||
1839 | ||||
1840 | static void handleRestrictAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1841 | QualType ResultType = getFunctionOrMethodResultType(D); | |||
1842 | if (ResultType->isAnyPointerType() || ResultType->isBlockPointerType()) { | |||
1843 | D->addAttr(::new (S.Context) RestrictAttr( | |||
1844 | AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); | |||
1845 | return; | |||
1846 | } | |||
1847 | ||||
1848 | S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only) | |||
1849 | << AL.getName() << getFunctionOrMethodResultSourceRange(D); | |||
1850 | } | |||
1851 | ||||
1852 | static void handleCPUSpecificAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1853 | FunctionDecl *FD = cast<FunctionDecl>(D); | |||
1854 | if (!checkAttributeAtLeastNumArgs(S, AL, 1)) | |||
1855 | return; | |||
1856 | ||||
1857 | SmallVector<IdentifierInfo *, 8> CPUs; | |||
1858 | for (unsigned ArgNo = 0; ArgNo < getNumAttributeArgs(AL); ++ArgNo) { | |||
1859 | if (!AL.isArgIdent(ArgNo)) { | |||
1860 | S.Diag(AL.getLoc(), diag::err_attribute_argument_type) | |||
1861 | << AL.getName() << AANT_ArgumentIdentifier; | |||
1862 | return; | |||
1863 | } | |||
1864 | ||||
1865 | IdentifierLoc *CPUArg = AL.getArgAsIdent(ArgNo); | |||
1866 | StringRef CPUName = CPUArg->Ident->getName().trim(); | |||
1867 | ||||
1868 | if (!S.Context.getTargetInfo().validateCPUSpecificCPUDispatch(CPUName)) { | |||
1869 | S.Diag(CPUArg->Loc, diag::err_invalid_cpu_specific_dispatch_value) | |||
1870 | << CPUName << (AL.getKind() == ParsedAttr::AT_CPUDispatch); | |||
1871 | return; | |||
1872 | } | |||
1873 | ||||
1874 | const TargetInfo &Target = S.Context.getTargetInfo(); | |||
1875 | if (llvm::any_of(CPUs, [CPUName, &Target](const IdentifierInfo *Cur) { | |||
1876 | return Target.CPUSpecificManglingCharacter(CPUName) == | |||
1877 | Target.CPUSpecificManglingCharacter(Cur->getName()); | |||
1878 | })) { | |||
1879 | S.Diag(AL.getLoc(), diag::warn_multiversion_duplicate_entries); | |||
1880 | return; | |||
1881 | } | |||
1882 | CPUs.push_back(CPUArg->Ident); | |||
1883 | } | |||
1884 | ||||
1885 | FD->setIsMultiVersion(true); | |||
1886 | if (AL.getKind() == ParsedAttr::AT_CPUSpecific) | |||
1887 | D->addAttr(::new (S.Context) CPUSpecificAttr( | |||
1888 | AL.getRange(), S.Context, CPUs.data(), CPUs.size(), | |||
1889 | AL.getAttributeSpellingListIndex())); | |||
1890 | else | |||
1891 | D->addAttr(::new (S.Context) CPUDispatchAttr( | |||
1892 | AL.getRange(), S.Context, CPUs.data(), CPUs.size(), | |||
1893 | AL.getAttributeSpellingListIndex())); | |||
1894 | } | |||
1895 | ||||
1896 | static void handleCommonAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1897 | if (S.LangOpts.CPlusPlus) { | |||
1898 | S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang) | |||
1899 | << AL.getName() << AttributeLangSupport::Cpp; | |||
1900 | return; | |||
1901 | } | |||
1902 | ||||
1903 | if (CommonAttr *CA = S.mergeCommonAttr(D, AL.getRange(), AL.getName(), | |||
1904 | AL.getAttributeSpellingListIndex())) | |||
1905 | D->addAttr(CA); | |||
1906 | } | |||
1907 | ||||
1908 | static void handleNakedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1909 | if (checkAttrMutualExclusion<DisableTailCallsAttr>(S, D, AL.getRange(), | |||
1910 | AL.getName())) | |||
1911 | return; | |||
1912 | ||||
1913 | if (AL.isDeclspecAttribute()) { | |||
1914 | const auto &Triple = S.getASTContext().getTargetInfo().getTriple(); | |||
1915 | const auto &Arch = Triple.getArch(); | |||
1916 | if (Arch != llvm::Triple::x86 && | |||
1917 | (Arch != llvm::Triple::arm && Arch != llvm::Triple::thumb)) { | |||
1918 | S.Diag(AL.getLoc(), diag::err_attribute_not_supported_on_arch) | |||
1919 | << AL.getName() << Triple.getArchName(); | |||
1920 | return; | |||
1921 | } | |||
1922 | } | |||
1923 | ||||
1924 | D->addAttr(::new (S.Context) NakedAttr(AL.getRange(), S.Context, | |||
1925 | AL.getAttributeSpellingListIndex())); | |||
1926 | } | |||
1927 | ||||
1928 | static void handleNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) { | |||
1929 | if (hasDeclarator(D)) return; | |||
1930 | ||||
1931 | if (!isa<ObjCMethodDecl>(D)) { | |||
1932 | S.Diag(Attrs.getLoc(), diag::warn_attribute_wrong_decl_type) | |||
1933 | << Attrs.getName() << ExpectedFunctionOrMethod; | |||
1934 | return; | |||
1935 | } | |||
1936 | ||||
1937 | D->addAttr(::new (S.Context) NoReturnAttr( | |||
1938 | Attrs.getRange(), S.Context, Attrs.getAttributeSpellingListIndex())); | |||
1939 | } | |||
1940 | ||||
1941 | static void handleNoCfCheckAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) { | |||
1942 | if (!S.getLangOpts().CFProtectionBranch) | |||
1943 | S.Diag(Attrs.getLoc(), diag::warn_nocf_check_attribute_ignored); | |||
1944 | else | |||
1945 | handleSimpleAttribute<AnyX86NoCfCheckAttr>(S, D, Attrs); | |||
1946 | } | |||
1947 | ||||
1948 | bool Sema::CheckAttrNoArgs(const ParsedAttr &Attrs) { | |||
1949 | if (!checkAttributeNumArgs(*this, Attrs, 0)) { | |||
1950 | Attrs.setInvalid(); | |||
1951 | return true; | |||
1952 | } | |||
1953 | ||||
1954 | return false; | |||
1955 | } | |||
1956 | ||||
1957 | bool Sema::CheckAttrTarget(const ParsedAttr &AL) { | |||
1958 | // Check whether the attribute is valid on the current target. | |||
1959 | if (!AL.existsInTarget(Context.getTargetInfo())) { | |||
1960 | Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored) << AL.getName(); | |||
1961 | AL.setInvalid(); | |||
1962 | return true; | |||
1963 | } | |||
1964 | ||||
1965 | return false; | |||
1966 | } | |||
1967 | ||||
1968 | static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1969 | ||||
1970 | // The checking path for 'noreturn' and 'analyzer_noreturn' are different | |||
1971 | // because 'analyzer_noreturn' does not impact the type. | |||
1972 | if (!isFunctionOrMethodOrBlock(D)) { | |||
1973 | ValueDecl *VD = dyn_cast<ValueDecl>(D); | |||
1974 | if (!VD || (!VD->getType()->isBlockPointerType() && | |||
1975 | !VD->getType()->isFunctionPointerType())) { | |||
1976 | S.Diag(AL.getLoc(), | |||
1977 | AL.isCXX11Attribute() ? diag::err_attribute_wrong_decl_type | |||
1978 | : diag::warn_attribute_wrong_decl_type) | |||
1979 | << AL.getName() << ExpectedFunctionMethodOrBlock; | |||
1980 | return; | |||
1981 | } | |||
1982 | } | |||
1983 | ||||
1984 | D->addAttr(::new (S.Context) | |||
1985 | AnalyzerNoReturnAttr(AL.getRange(), S.Context, | |||
1986 | AL.getAttributeSpellingListIndex())); | |||
1987 | } | |||
1988 | ||||
1989 | // PS3 PPU-specific. | |||
1990 | static void handleVecReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
1991 | /* | |||
1992 | Returning a Vector Class in Registers | |||
1993 | ||||
1994 | According to the PPU ABI specifications, a class with a single member of | |||
1995 | vector type is returned in memory when used as the return value of a | |||
1996 | function. | |||
1997 | This results in inefficient code when implementing vector classes. To return | |||
1998 | the value in a single vector register, add the vecreturn attribute to the | |||
1999 | class definition. This attribute is also applicable to struct types. | |||
2000 | ||||
2001 | Example: | |||
2002 | ||||
2003 | struct Vector | |||
2004 | { | |||
2005 | __vector float xyzw; | |||
2006 | } __attribute__((vecreturn)); | |||
2007 | ||||
2008 | Vector Add(Vector lhs, Vector rhs) | |||
2009 | { | |||
2010 | Vector result; | |||
2011 | result.xyzw = vec_add(lhs.xyzw, rhs.xyzw); | |||
2012 | return result; // This will be returned in a register | |||
2013 | } | |||
2014 | */ | |||
2015 | if (VecReturnAttr *A = D->getAttr<VecReturnAttr>()) { | |||
2016 | S.Diag(AL.getLoc(), diag::err_repeat_attribute) << A; | |||
2017 | return; | |||
2018 | } | |||
2019 | ||||
2020 | const auto *R = cast<RecordDecl>(D); | |||
2021 | int count = 0; | |||
2022 | ||||
2023 | if (!isa<CXXRecordDecl>(R)) { | |||
2024 | S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_vector_member); | |||
2025 | return; | |||
2026 | } | |||
2027 | ||||
2028 | if (!cast<CXXRecordDecl>(R)->isPOD()) { | |||
2029 | S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_pod_record); | |||
2030 | return; | |||
2031 | } | |||
2032 | ||||
2033 | for (const auto *I : R->fields()) { | |||
2034 | if ((count == 1) || !I->getType()->isVectorType()) { | |||
2035 | S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_vector_member); | |||
2036 | return; | |||
2037 | } | |||
2038 | count++; | |||
2039 | } | |||
2040 | ||||
2041 | D->addAttr(::new (S.Context) VecReturnAttr( | |||
2042 | AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); | |||
2043 | } | |||
2044 | ||||
2045 | static void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D, | |||
2046 | const ParsedAttr &AL) { | |||
2047 | if (isa<ParmVarDecl>(D)) { | |||
2048 | // [[carries_dependency]] can only be applied to a parameter if it is a | |||
2049 | // parameter of a function declaration or lambda. | |||
2050 | if (!(Scope->getFlags() & clang::Scope::FunctionDeclarationScope)) { | |||
2051 | S.Diag(AL.getLoc(), | |||
2052 | diag::err_carries_dependency_param_not_function_decl); | |||
2053 | return; | |||
2054 | } | |||
2055 | } | |||
2056 | ||||
2057 | D->addAttr(::new (S.Context) CarriesDependencyAttr( | |||
2058 | AL.getRange(), S.Context, | |||
2059 | AL.getAttributeSpellingListIndex())); | |||
2060 | } | |||
2061 | ||||
2062 | static void handleUnusedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
2063 | bool IsCXX17Attr = AL.isCXX11Attribute() && !AL.getScopeName(); | |||
2064 | ||||
2065 | // If this is spelled as the standard C++17 attribute, but not in C++17, warn | |||
2066 | // about using it as an extension. | |||
2067 | if (!S.getLangOpts().CPlusPlus17 && IsCXX17Attr) | |||
2068 | S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL.getName(); | |||
2069 | ||||
2070 | D->addAttr(::new (S.Context) UnusedAttr( | |||
2071 | AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); | |||
2072 | } | |||
2073 | ||||
2074 | static void handleConstructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
2075 | uint32_t priority = ConstructorAttr::DefaultPriority; | |||
2076 | if (AL.getNumArgs() && | |||
2077 | !checkUInt32Argument(S, AL, AL.getArgAsExpr(0), priority)) | |||
2078 | return; | |||
2079 | ||||
2080 | D->addAttr(::new (S.Context) | |||
2081 | ConstructorAttr(AL.getRange(), S.Context, priority, | |||
2082 | AL.getAttributeSpellingListIndex())); | |||
2083 | } | |||
2084 | ||||
2085 | static void handleDestructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
2086 | uint32_t priority = DestructorAttr::DefaultPriority; | |||
2087 | if (AL.getNumArgs() && | |||
2088 | !checkUInt32Argument(S, AL, AL.getArgAsExpr(0), priority)) | |||
2089 | return; | |||
2090 | ||||
2091 | D->addAttr(::new (S.Context) | |||
2092 | DestructorAttr(AL.getRange(), S.Context, priority, | |||
2093 | AL.getAttributeSpellingListIndex())); | |||
2094 | } | |||
2095 | ||||
2096 | template <typename AttrTy> | |||
2097 | static void handleAttrWithMessage(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
2098 | // Handle the case where the attribute has a text message. | |||
2099 | StringRef Str; | |||
2100 | if (AL.getNumArgs() == 1 && !S.checkStringLiteralArgumentAttr(AL, 0, Str)) | |||
2101 | return; | |||
2102 | ||||
2103 | D->addAttr(::new (S.Context) AttrTy(AL.getRange(), S.Context, Str, | |||
2104 | AL.getAttributeSpellingListIndex())); | |||
2105 | } | |||
2106 | ||||
2107 | static void handleObjCSuppresProtocolAttr(Sema &S, Decl *D, | |||
2108 | const ParsedAttr &AL) { | |||
2109 | if (!cast<ObjCProtocolDecl>(D)->isThisDeclarationADefinition()) { | |||
2110 | S.Diag(AL.getLoc(), diag::err_objc_attr_protocol_requires_definition) | |||
2111 | << AL.getName() << AL.getRange(); | |||
2112 | return; | |||
2113 | } | |||
2114 | ||||
2115 | D->addAttr(::new (S.Context) | |||
2116 | ObjCExplicitProtocolImplAttr(AL.getRange(), S.Context, | |||
2117 | AL.getAttributeSpellingListIndex())); | |||
2118 | } | |||
2119 | ||||
2120 | static bool checkAvailabilityAttr(Sema &S, SourceRange Range, | |||
2121 | IdentifierInfo *Platform, | |||
2122 | VersionTuple Introduced, | |||
2123 | VersionTuple Deprecated, | |||
2124 | VersionTuple Obsoleted) { | |||
2125 | StringRef PlatformName | |||
2126 | = AvailabilityAttr::getPrettyPlatformName(Platform->getName()); | |||
2127 | if (PlatformName.empty()) | |||
2128 | PlatformName = Platform->getName(); | |||
2129 | ||||
2130 | // Ensure that Introduced <= Deprecated <= Obsoleted (although not all | |||
2131 | // of these steps are needed). | |||
2132 | if (!Introduced.empty() && !Deprecated.empty() && | |||
2133 | !(Introduced <= Deprecated)) { | |||
2134 | S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) | |||
2135 | << 1 << PlatformName << Deprecated.getAsString() | |||
2136 | << 0 << Introduced.getAsString(); | |||
2137 | return true; | |||
2138 | } | |||
2139 | ||||
2140 | if (!Introduced.empty() && !Obsoleted.empty() && | |||
2141 | !(Introduced <= Obsoleted)) { | |||
2142 | S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) | |||
2143 | << 2 << PlatformName << Obsoleted.getAsString() | |||
2144 | << 0 << Introduced.getAsString(); | |||
2145 | return true; | |||
2146 | } | |||
2147 | ||||
2148 | if (!Deprecated.empty() && !Obsoleted.empty() && | |||
2149 | !(Deprecated <= Obsoleted)) { | |||
2150 | S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) | |||
2151 | << 2 << PlatformName << Obsoleted.getAsString() | |||
2152 | << 1 << Deprecated.getAsString(); | |||
2153 | return true; | |||
2154 | } | |||
2155 | ||||
2156 | return false; | |||
2157 | } | |||
2158 | ||||
2159 | /// Check whether the two versions match. | |||
2160 | /// | |||
2161 | /// If either version tuple is empty, then they are assumed to match. If | |||
2162 | /// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y. | |||
2163 | static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y, | |||
2164 | bool BeforeIsOkay) { | |||
2165 | if (X.empty() || Y.empty()) | |||
2166 | return true; | |||
2167 | ||||
2168 | if (X == Y) | |||
2169 | return true; | |||
2170 | ||||
2171 | if (BeforeIsOkay && X < Y) | |||
2172 | return true; | |||
2173 | ||||
2174 | return false; | |||
2175 | } | |||
2176 | ||||
2177 | AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range, | |||
2178 | IdentifierInfo *Platform, | |||
2179 | bool Implicit, | |||
2180 | VersionTuple Introduced, | |||
2181 | VersionTuple Deprecated, | |||
2182 | VersionTuple Obsoleted, | |||
2183 | bool IsUnavailable, | |||
2184 | StringRef Message, | |||
2185 | bool IsStrict, | |||
2186 | StringRef Replacement, | |||
2187 | AvailabilityMergeKind AMK, | |||
2188 | unsigned AttrSpellingListIndex) { | |||
2189 | VersionTuple MergedIntroduced = Introduced; | |||
2190 | VersionTuple MergedDeprecated = Deprecated; | |||
2191 | VersionTuple MergedObsoleted = Obsoleted; | |||
2192 | bool FoundAny = false; | |||
2193 | bool OverrideOrImpl = false; | |||
2194 | switch (AMK) { | |||
2195 | case AMK_None: | |||
2196 | case AMK_Redeclaration: | |||
2197 | OverrideOrImpl = false; | |||
2198 | break; | |||
2199 | ||||
2200 | case AMK_Override: | |||
2201 | case AMK_ProtocolImplementation: | |||
2202 | OverrideOrImpl = true; | |||
2203 | break; | |||
2204 | } | |||
2205 | ||||
2206 | if (D->hasAttrs()) { | |||
2207 | AttrVec &Attrs = D->getAttrs(); | |||
2208 | for (unsigned i = 0, e = Attrs.size(); i != e;) { | |||
2209 | const auto *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]); | |||
2210 | if (!OldAA) { | |||
2211 | ++i; | |||
2212 | continue; | |||
2213 | } | |||
2214 | ||||
2215 | IdentifierInfo *OldPlatform = OldAA->getPlatform(); | |||
2216 | if (OldPlatform != Platform) { | |||
2217 | ++i; | |||
2218 | continue; | |||
2219 | } | |||
2220 | ||||
2221 | // If there is an existing availability attribute for this platform that | |||
2222 | // is explicit and the new one is implicit use the explicit one and | |||
2223 | // discard the new implicit attribute. | |||
2224 | if (!OldAA->isImplicit() && Implicit) { | |||
2225 | return nullptr; | |||
2226 | } | |||
2227 | ||||
2228 | // If there is an existing attribute for this platform that is implicit | |||
2229 | // and the new attribute is explicit then erase the old one and | |||
2230 | // continue processing the attributes. | |||
2231 | if (!Implicit && OldAA->isImplicit()) { | |||
2232 | Attrs.erase(Attrs.begin() + i); | |||
2233 | --e; | |||
2234 | continue; | |||
2235 | } | |||
2236 | ||||
2237 | FoundAny = true; | |||
2238 | VersionTuple OldIntroduced = OldAA->getIntroduced(); | |||
2239 | VersionTuple OldDeprecated = OldAA->getDeprecated(); | |||
2240 | VersionTuple OldObsoleted = OldAA->getObsoleted(); | |||
2241 | bool OldIsUnavailable = OldAA->getUnavailable(); | |||
2242 | ||||
2243 | if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl) || | |||
2244 | !versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl) || | |||
2245 | !versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl) || | |||
2246 | !(OldIsUnavailable == IsUnavailable || | |||
2247 | (OverrideOrImpl && !OldIsUnavailable && IsUnavailable))) { | |||
2248 | if (OverrideOrImpl) { | |||
2249 | int Which = -1; | |||
2250 | VersionTuple FirstVersion; | |||
2251 | VersionTuple SecondVersion; | |||
2252 | if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl)) { | |||
2253 | Which = 0; | |||
2254 | FirstVersion = OldIntroduced; | |||
2255 | SecondVersion = Introduced; | |||
2256 | } else if (!versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl)) { | |||
2257 | Which = 1; | |||
2258 | FirstVersion = Deprecated; | |||
2259 | SecondVersion = OldDeprecated; | |||
2260 | } else if (!versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl)) { | |||
2261 | Which = 2; | |||
2262 | FirstVersion = Obsoleted; | |||
2263 | SecondVersion = OldObsoleted; | |||
2264 | } | |||
2265 | ||||
2266 | if (Which == -1) { | |||
2267 | Diag(OldAA->getLocation(), | |||
2268 | diag::warn_mismatched_availability_override_unavail) | |||
2269 | << AvailabilityAttr::getPrettyPlatformName(Platform->getName()) | |||
2270 | << (AMK == AMK_Override); | |||
2271 | } else { | |||
2272 | Diag(OldAA->getLocation(), | |||
2273 | diag::warn_mismatched_availability_override) | |||
2274 | << Which | |||
2275 | << AvailabilityAttr::getPrettyPlatformName(Platform->getName()) | |||
2276 | << FirstVersion.getAsString() << SecondVersion.getAsString() | |||
2277 | << (AMK == AMK_Override); | |||
2278 | } | |||
2279 | if (AMK == AMK_Override) | |||
2280 | Diag(Range.getBegin(), diag::note_overridden_method); | |||
2281 | else | |||
2282 | Diag(Range.getBegin(), diag::note_protocol_method); | |||
2283 | } else { | |||
2284 | Diag(OldAA->getLocation(), diag::warn_mismatched_availability); | |||
2285 | Diag(Range.getBegin(), diag::note_previous_attribute); | |||
2286 | } | |||
2287 | ||||
2288 | Attrs.erase(Attrs.begin() + i); | |||
2289 | --e; | |||
2290 | continue; | |||
2291 | } | |||
2292 | ||||
2293 | VersionTuple MergedIntroduced2 = MergedIntroduced; | |||
2294 | VersionTuple MergedDeprecated2 = MergedDeprecated; | |||
2295 | VersionTuple MergedObsoleted2 = MergedObsoleted; | |||
2296 | ||||
2297 | if (MergedIntroduced2.empty()) | |||
2298 | MergedIntroduced2 = OldIntroduced; | |||
2299 | if (MergedDeprecated2.empty()) | |||
2300 | MergedDeprecated2 = OldDeprecated; | |||
2301 | if (MergedObsoleted2.empty()) | |||
2302 | MergedObsoleted2 = OldObsoleted; | |||
2303 | ||||
2304 | if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform, | |||
2305 | MergedIntroduced2, MergedDeprecated2, | |||
2306 | MergedObsoleted2)) { | |||
2307 | Attrs.erase(Attrs.begin() + i); | |||
2308 | --e; | |||
2309 | continue; | |||
2310 | } | |||
2311 | ||||
2312 | MergedIntroduced = MergedIntroduced2; | |||
2313 | MergedDeprecated = MergedDeprecated2; | |||
2314 | MergedObsoleted = MergedObsoleted2; | |||
2315 | ++i; | |||
2316 | } | |||
2317 | } | |||
2318 | ||||
2319 | if (FoundAny && | |||
2320 | MergedIntroduced == Introduced && | |||
2321 | MergedDeprecated == Deprecated && | |||
2322 | MergedObsoleted == Obsoleted) | |||
2323 | return nullptr; | |||
2324 | ||||
2325 | // Only create a new attribute if !OverrideOrImpl, but we want to do | |||
2326 | // the checking. | |||
2327 | if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced, | |||
2328 | MergedDeprecated, MergedObsoleted) && | |||
2329 | !OverrideOrImpl) { | |||
2330 | auto *Avail = ::new (Context) AvailabilityAttr(Range, Context, Platform, | |||
2331 | Introduced, Deprecated, | |||
2332 | Obsoleted, IsUnavailable, Message, | |||
2333 | IsStrict, Replacement, | |||
2334 | AttrSpellingListIndex); | |||
2335 | Avail->setImplicit(Implicit); | |||
2336 | return Avail; | |||
2337 | } | |||
2338 | return nullptr; | |||
2339 | } | |||
2340 | ||||
2341 | static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
2342 | if (!checkAttributeNumArgs(S, AL, 1)) | |||
2343 | return; | |||
2344 | IdentifierLoc *Platform = AL.getArgAsIdent(0); | |||
2345 | unsigned Index = AL.getAttributeSpellingListIndex(); | |||
2346 | ||||
2347 | IdentifierInfo *II = Platform->Ident; | |||
2348 | if (AvailabilityAttr::getPrettyPlatformName(II->getName()).empty()) | |||
2349 | S.Diag(Platform->Loc, diag::warn_availability_unknown_platform) | |||
2350 | << Platform->Ident; | |||
2351 | ||||
2352 | auto *ND = dyn_cast<NamedDecl>(D); | |||
2353 | if (!ND) // We warned about this already, so just return. | |||
2354 | return; | |||
2355 | ||||
2356 | AvailabilityChange Introduced = AL.getAvailabilityIntroduced(); | |||
2357 | AvailabilityChange Deprecated = AL.getAvailabilityDeprecated(); | |||
2358 | AvailabilityChange Obsoleted = AL.getAvailabilityObsoleted(); | |||
2359 | bool IsUnavailable = AL.getUnavailableLoc().isValid(); | |||
2360 | bool IsStrict = AL.getStrictLoc().isValid(); | |||
2361 | StringRef Str; | |||
2362 | if (const auto *SE = dyn_cast_or_null<StringLiteral>(AL.getMessageExpr())) | |||
2363 | Str = SE->getString(); | |||
2364 | StringRef Replacement; | |||
2365 | if (const auto *SE = dyn_cast_or_null<StringLiteral>(AL.getReplacementExpr())) | |||
2366 | Replacement = SE->getString(); | |||
2367 | ||||
2368 | AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, AL.getRange(), II, | |||
2369 | false/*Implicit*/, | |||
2370 | Introduced.Version, | |||
2371 | Deprecated.Version, | |||
2372 | Obsoleted.Version, | |||
2373 | IsUnavailable, Str, | |||
2374 | IsStrict, Replacement, | |||
2375 | Sema::AMK_None, | |||
2376 | Index); | |||
2377 | if (NewAttr) | |||
2378 | D->addAttr(NewAttr); | |||
2379 | ||||
2380 | // Transcribe "ios" to "watchos" (and add a new attribute) if the versioning | |||
2381 | // matches before the start of the watchOS platform. | |||
2382 | if (S.Context.getTargetInfo().getTriple().isWatchOS()) { | |||
2383 | IdentifierInfo *NewII = nullptr; | |||
2384 | if (II->getName() == "ios") | |||
2385 | NewII = &S.Context.Idents.get("watchos"); | |||
2386 | else if (II->getName() == "ios_app_extension") | |||
2387 | NewII = &S.Context.Idents.get("watchos_app_extension"); | |||
2388 | ||||
2389 | if (NewII) { | |||
2390 | auto adjustWatchOSVersion = [](VersionTuple Version) -> VersionTuple { | |||
2391 | if (Version.empty()) | |||
2392 | return Version; | |||
2393 | auto Major = Version.getMajor(); | |||
2394 | auto NewMajor = Major >= 9 ? Major - 7 : 0; | |||
2395 | if (NewMajor >= 2) { | |||
2396 | if (Version.getMinor().hasValue()) { | |||
2397 | if (Version.getSubminor().hasValue()) | |||
2398 | return VersionTuple(NewMajor, Version.getMinor().getValue(), | |||
2399 | Version.getSubminor().getValue()); | |||
2400 | else | |||
2401 | return VersionTuple(NewMajor, Version.getMinor().getValue()); | |||
2402 | } | |||
2403 | } | |||
2404 | ||||
2405 | return VersionTuple(2, 0); | |||
2406 | }; | |||
2407 | ||||
2408 | auto NewIntroduced = adjustWatchOSVersion(Introduced.Version); | |||
2409 | auto NewDeprecated = adjustWatchOSVersion(Deprecated.Version); | |||
2410 | auto NewObsoleted = adjustWatchOSVersion(Obsoleted.Version); | |||
2411 | ||||
2412 | AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, | |||
2413 | AL.getRange(), | |||
2414 | NewII, | |||
2415 | true/*Implicit*/, | |||
2416 | NewIntroduced, | |||
2417 | NewDeprecated, | |||
2418 | NewObsoleted, | |||
2419 | IsUnavailable, Str, | |||
2420 | IsStrict, | |||
2421 | Replacement, | |||
2422 | Sema::AMK_None, | |||
2423 | Index); | |||
2424 | if (NewAttr) | |||
2425 | D->addAttr(NewAttr); | |||
2426 | } | |||
2427 | } else if (S.Context.getTargetInfo().getTriple().isTvOS()) { | |||
2428 | // Transcribe "ios" to "tvos" (and add a new attribute) if the versioning | |||
2429 | // matches before the start of the tvOS platform. | |||
2430 | IdentifierInfo *NewII = nullptr; | |||
2431 | if (II->getName() == "ios") | |||
2432 | NewII = &S.Context.Idents.get("tvos"); | |||
2433 | else if (II->getName() == "ios_app_extension") | |||
2434 | NewII = &S.Context.Idents.get("tvos_app_extension"); | |||
2435 | ||||
2436 | if (NewII) { | |||
2437 | AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, | |||
2438 | AL.getRange(), | |||
2439 | NewII, | |||
2440 | true/*Implicit*/, | |||
2441 | Introduced.Version, | |||
2442 | Deprecated.Version, | |||
2443 | Obsoleted.Version, | |||
2444 | IsUnavailable, Str, | |||
2445 | IsStrict, | |||
2446 | Replacement, | |||
2447 | Sema::AMK_None, | |||
2448 | Index); | |||
2449 | if (NewAttr) | |||
2450 | D->addAttr(NewAttr); | |||
2451 | } | |||
2452 | } | |||
2453 | } | |||
2454 | ||||
2455 | static void handleExternalSourceSymbolAttr(Sema &S, Decl *D, | |||
2456 | const ParsedAttr &AL) { | |||
2457 | if (!checkAttributeAtLeastNumArgs(S, AL, 1)) | |||
2458 | return; | |||
2459 | assert(checkAttributeAtMostNumArgs(S, AL, 3) &&(static_cast <bool> (checkAttributeAtMostNumArgs(S, AL, 3) && "Invalid number of arguments in an external_source_symbol attribute" ) ? void (0) : __assert_fail ("checkAttributeAtMostNumArgs(S, AL, 3) && \"Invalid number of arguments in an external_source_symbol attribute\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 2460, __extension__ __PRETTY_FUNCTION__)) | |||
2460 | "Invalid number of arguments in an external_source_symbol attribute")(static_cast <bool> (checkAttributeAtMostNumArgs(S, AL, 3) && "Invalid number of arguments in an external_source_symbol attribute" ) ? void (0) : __assert_fail ("checkAttributeAtMostNumArgs(S, AL, 3) && \"Invalid number of arguments in an external_source_symbol attribute\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 2460, __extension__ __PRETTY_FUNCTION__)); | |||
2461 | ||||
2462 | StringRef Language; | |||
2463 | if (const auto *SE = dyn_cast_or_null<StringLiteral>(AL.getArgAsExpr(0))) | |||
2464 | Language = SE->getString(); | |||
2465 | StringRef DefinedIn; | |||
2466 | if (const auto *SE = dyn_cast_or_null<StringLiteral>(AL.getArgAsExpr(1))) | |||
2467 | DefinedIn = SE->getString(); | |||
2468 | bool IsGeneratedDeclaration = AL.getArgAsIdent(2) != nullptr; | |||
2469 | ||||
2470 | D->addAttr(::new (S.Context) ExternalSourceSymbolAttr( | |||
2471 | AL.getRange(), S.Context, Language, DefinedIn, IsGeneratedDeclaration, | |||
2472 | AL.getAttributeSpellingListIndex())); | |||
2473 | } | |||
2474 | ||||
2475 | template <class T> | |||
2476 | static T *mergeVisibilityAttr(Sema &S, Decl *D, SourceRange range, | |||
2477 | typename T::VisibilityType value, | |||
2478 | unsigned attrSpellingListIndex) { | |||
2479 | T *existingAttr = D->getAttr<T>(); | |||
2480 | if (existingAttr) { | |||
2481 | typename T::VisibilityType existingValue = existingAttr->getVisibility(); | |||
2482 | if (existingValue == value) | |||
2483 | return nullptr; | |||
2484 | S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility); | |||
2485 | S.Diag(range.getBegin(), diag::note_previous_attribute); | |||
2486 | D->dropAttr<T>(); | |||
2487 | } | |||
2488 | return ::new (S.Context) T(range, S.Context, value, attrSpellingListIndex); | |||
2489 | } | |||
2490 | ||||
2491 | VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range, | |||
2492 | VisibilityAttr::VisibilityType Vis, | |||
2493 | unsigned AttrSpellingListIndex) { | |||
2494 | return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, Range, Vis, | |||
2495 | AttrSpellingListIndex); | |||
2496 | } | |||
2497 | ||||
2498 | TypeVisibilityAttr *Sema::mergeTypeVisibilityAttr(Decl *D, SourceRange Range, | |||
2499 | TypeVisibilityAttr::VisibilityType Vis, | |||
2500 | unsigned AttrSpellingListIndex) { | |||
2501 | return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, Range, Vis, | |||
2502 | AttrSpellingListIndex); | |||
2503 | } | |||
2504 | ||||
2505 | static void handleVisibilityAttr(Sema &S, Decl *D, const ParsedAttr &AL, | |||
2506 | bool isTypeVisibility) { | |||
2507 | // Visibility attributes don't mean anything on a typedef. | |||
2508 | if (isa<TypedefNameDecl>(D)) { | |||
2509 | S.Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored) | |||
2510 | << AL.getName(); | |||
2511 | return; | |||
2512 | } | |||
2513 | ||||
2514 | // 'type_visibility' can only go on a type or namespace. | |||
2515 | if (isTypeVisibility && | |||
2516 | !(isa<TagDecl>(D) || | |||
2517 | isa<ObjCInterfaceDecl>(D) || | |||
2518 | isa<NamespaceDecl>(D))) { | |||
2519 | S.Diag(AL.getRange().getBegin(), diag::err_attribute_wrong_decl_type) | |||
2520 | << AL.getName() << ExpectedTypeOrNamespace; | |||
2521 | return; | |||
2522 | } | |||
2523 | ||||
2524 | // Check that the argument is a string literal. | |||
2525 | StringRef TypeStr; | |||
2526 | SourceLocation LiteralLoc; | |||
2527 | if (!S.checkStringLiteralArgumentAttr(AL, 0, TypeStr, &LiteralLoc)) | |||
2528 | return; | |||
2529 | ||||
2530 | VisibilityAttr::VisibilityType type; | |||
2531 | if (!VisibilityAttr::ConvertStrToVisibilityType(TypeStr, type)) { | |||
2532 | S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported) | |||
2533 | << AL.getName() << TypeStr; | |||
2534 | return; | |||
2535 | } | |||
2536 | ||||
2537 | // Complain about attempts to use protected visibility on targets | |||
2538 | // (like Darwin) that don't support it. | |||
2539 | if (type == VisibilityAttr::Protected && | |||
2540 | !S.Context.getTargetInfo().hasProtectedVisibility()) { | |||
2541 | S.Diag(AL.getLoc(), diag::warn_attribute_protected_visibility); | |||
2542 | type = VisibilityAttr::Default; | |||
2543 | } | |||
2544 | ||||
2545 | unsigned Index = AL.getAttributeSpellingListIndex(); | |||
2546 | Attr *newAttr; | |||
2547 | if (isTypeVisibility) { | |||
2548 | newAttr = S.mergeTypeVisibilityAttr(D, AL.getRange(), | |||
2549 | (TypeVisibilityAttr::VisibilityType) type, | |||
2550 | Index); | |||
2551 | } else { | |||
2552 | newAttr = S.mergeVisibilityAttr(D, AL.getRange(), type, Index); | |||
2553 | } | |||
2554 | if (newAttr) | |||
2555 | D->addAttr(newAttr); | |||
2556 | } | |||
2557 | ||||
2558 | static void handleObjCMethodFamilyAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
2559 | const auto *M = cast<ObjCMethodDecl>(D); | |||
2560 | if (!AL.isArgIdent(0)) { | |||
2561 | S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type) | |||
2562 | << AL.getName() << 1 << AANT_ArgumentIdentifier; | |||
2563 | return; | |||
2564 | } | |||
2565 | ||||
2566 | IdentifierLoc *IL = AL.getArgAsIdent(0); | |||
2567 | ObjCMethodFamilyAttr::FamilyKind F; | |||
2568 | if (!ObjCMethodFamilyAttr::ConvertStrToFamilyKind(IL->Ident->getName(), F)) { | |||
2569 | S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) | |||
2570 | << AL.getName() << IL->Ident; | |||
2571 | return; | |||
2572 | } | |||
2573 | ||||
2574 | if (F == ObjCMethodFamilyAttr::OMF_init && | |||
2575 | !M->getReturnType()->isObjCObjectPointerType()) { | |||
2576 | S.Diag(M->getLocation(), diag::err_init_method_bad_return_type) | |||
2577 | << M->getReturnType(); | |||
2578 | // Ignore the attribute. | |||
2579 | return; | |||
2580 | } | |||
2581 | ||||
2582 | D->addAttr(new (S.Context) ObjCMethodFamilyAttr( | |||
2583 | AL.getRange(), S.Context, F, AL.getAttributeSpellingListIndex())); | |||
2584 | } | |||
2585 | ||||
2586 | static void handleObjCNSObject(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
2587 | if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) { | |||
2588 | QualType T = TD->getUnderlyingType(); | |||
2589 | if (!T->isCARCBridgableType()) { | |||
2590 | S.Diag(TD->getLocation(), diag::err_nsobject_attribute); | |||
2591 | return; | |||
2592 | } | |||
2593 | } | |||
2594 | else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) { | |||
2595 | QualType T = PD->getType(); | |||
2596 | if (!T->isCARCBridgableType()) { | |||
2597 | S.Diag(PD->getLocation(), diag::err_nsobject_attribute); | |||
2598 | return; | |||
2599 | } | |||
2600 | } | |||
2601 | else { | |||
2602 | // It is okay to include this attribute on properties, e.g.: | |||
2603 | // | |||
2604 | // @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject)); | |||
2605 | // | |||
2606 | // In this case it follows tradition and suppresses an error in the above | |||
2607 | // case. | |||
2608 | S.Diag(D->getLocation(), diag::warn_nsobject_attribute); | |||
2609 | } | |||
2610 | D->addAttr(::new (S.Context) | |||
2611 | ObjCNSObjectAttr(AL.getRange(), S.Context, | |||
2612 | AL.getAttributeSpellingListIndex())); | |||
2613 | } | |||
2614 | ||||
2615 | static void handleObjCIndependentClass(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
2616 | if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) { | |||
2617 | QualType T = TD->getUnderlyingType(); | |||
2618 | if (!T->isObjCObjectPointerType()) { | |||
2619 | S.Diag(TD->getLocation(), diag::warn_ptr_independentclass_attribute); | |||
2620 | return; | |||
2621 | } | |||
2622 | } else { | |||
2623 | S.Diag(D->getLocation(), diag::warn_independentclass_attribute); | |||
2624 | return; | |||
2625 | } | |||
2626 | D->addAttr(::new (S.Context) | |||
2627 | ObjCIndependentClassAttr(AL.getRange(), S.Context, | |||
2628 | AL.getAttributeSpellingListIndex())); | |||
2629 | } | |||
2630 | ||||
2631 | static void handleBlocksAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
2632 | if (!AL.isArgIdent(0)) { | |||
2633 | S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type) | |||
2634 | << AL.getName() << 1 << AANT_ArgumentIdentifier; | |||
2635 | return; | |||
2636 | } | |||
2637 | ||||
2638 | IdentifierInfo *II = AL.getArgAsIdent(0)->Ident; | |||
2639 | BlocksAttr::BlockType type; | |||
2640 | if (!BlocksAttr::ConvertStrToBlockType(II->getName(), type)) { | |||
2641 | S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) | |||
2642 | << AL.getName() << II; | |||
2643 | return; | |||
2644 | } | |||
2645 | ||||
2646 | D->addAttr(::new (S.Context) | |||
2647 | BlocksAttr(AL.getRange(), S.Context, type, | |||
2648 | AL.getAttributeSpellingListIndex())); | |||
2649 | } | |||
2650 | ||||
2651 | static void handleSentinelAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
2652 | unsigned sentinel = (unsigned)SentinelAttr::DefaultSentinel; | |||
2653 | if (AL.getNumArgs() > 0) { | |||
2654 | Expr *E = AL.getArgAsExpr(0); | |||
2655 | llvm::APSInt Idx(32); | |||
2656 | if (E->isTypeDependent() || E->isValueDependent() || | |||
2657 | !E->isIntegerConstantExpr(Idx, S.Context)) { | |||
2658 | S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type) | |||
2659 | << AL.getName() << 1 << AANT_ArgumentIntegerConstant | |||
2660 | << E->getSourceRange(); | |||
2661 | return; | |||
2662 | } | |||
2663 | ||||
2664 | if (Idx.isSigned() && Idx.isNegative()) { | |||
2665 | S.Diag(AL.getLoc(), diag::err_attribute_sentinel_less_than_zero) | |||
2666 | << E->getSourceRange(); | |||
2667 | return; | |||
2668 | } | |||
2669 | ||||
2670 | sentinel = Idx.getZExtValue(); | |||
2671 | } | |||
2672 | ||||
2673 | unsigned nullPos = (unsigned)SentinelAttr::DefaultNullPos; | |||
2674 | if (AL.getNumArgs() > 1) { | |||
2675 | Expr *E = AL.getArgAsExpr(1); | |||
2676 | llvm::APSInt Idx(32); | |||
2677 | if (E->isTypeDependent() || E->isValueDependent() || | |||
2678 | !E->isIntegerConstantExpr(Idx, S.Context)) { | |||
2679 | S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type) | |||
2680 | << AL.getName() << 2 << AANT_ArgumentIntegerConstant | |||
2681 | << E->getSourceRange(); | |||
2682 | return; | |||
2683 | } | |||
2684 | nullPos = Idx.getZExtValue(); | |||
2685 | ||||
2686 | if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) { | |||
2687 | // FIXME: This error message could be improved, it would be nice | |||
2688 | // to say what the bounds actually are. | |||
2689 | S.Diag(AL.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) | |||
2690 | << E->getSourceRange(); | |||
2691 | return; | |||
2692 | } | |||
2693 | } | |||
2694 | ||||
2695 | if (const auto *FD = dyn_cast<FunctionDecl>(D)) { | |||
2696 | const FunctionType *FT = FD->getType()->castAs<FunctionType>(); | |||
2697 | if (isa<FunctionNoProtoType>(FT)) { | |||
2698 | S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_named_arguments); | |||
2699 | return; | |||
2700 | } | |||
2701 | ||||
2702 | if (!cast<FunctionProtoType>(FT)->isVariadic()) { | |||
2703 | S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; | |||
2704 | return; | |||
2705 | } | |||
2706 | } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) { | |||
2707 | if (!MD->isVariadic()) { | |||
2708 | S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; | |||
2709 | return; | |||
2710 | } | |||
2711 | } else if (const auto *BD = dyn_cast<BlockDecl>(D)) { | |||
2712 | if (!BD->isVariadic()) { | |||
2713 | S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1; | |||
2714 | return; | |||
2715 | } | |||
2716 | } else if (const auto *V = dyn_cast<VarDecl>(D)) { | |||
2717 | QualType Ty = V->getType(); | |||
2718 | if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { | |||
2719 | const FunctionType *FT = Ty->isFunctionPointerType() | |||
2720 | ? D->getFunctionType() | |||
2721 | : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); | |||
2722 | if (!cast<FunctionProtoType>(FT)->isVariadic()) { | |||
2723 | int m = Ty->isFunctionPointerType() ? 0 : 1; | |||
2724 | S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; | |||
2725 | return; | |||
2726 | } | |||
2727 | } else { | |||
2728 | S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) | |||
2729 | << AL.getName() << ExpectedFunctionMethodOrBlock; | |||
2730 | return; | |||
2731 | } | |||
2732 | } else { | |||
2733 | S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) | |||
2734 | << AL.getName() << ExpectedFunctionMethodOrBlock; | |||
2735 | return; | |||
2736 | } | |||
2737 | D->addAttr(::new (S.Context) | |||
2738 | SentinelAttr(AL.getRange(), S.Context, sentinel, nullPos, | |||
2739 | AL.getAttributeSpellingListIndex())); | |||
2740 | } | |||
2741 | ||||
2742 | static void handleWarnUnusedResult(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
2743 | if (D->getFunctionType() && | |||
2744 | D->getFunctionType()->getReturnType()->isVoidType()) { | |||
2745 | S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) | |||
2746 | << AL.getName() << 0; | |||
2747 | return; | |||
2748 | } | |||
2749 | if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) | |||
2750 | if (MD->getReturnType()->isVoidType()) { | |||
2751 | S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) | |||
2752 | << AL.getName() << 1; | |||
2753 | return; | |||
2754 | } | |||
2755 | ||||
2756 | // If this is spelled as the standard C++17 attribute, but not in C++17, warn | |||
2757 | // about using it as an extension. | |||
2758 | if (!S.getLangOpts().CPlusPlus17 && AL.isCXX11Attribute() && | |||
2759 | !AL.getScopeName()) | |||
2760 | S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL.getName(); | |||
2761 | ||||
2762 | D->addAttr(::new (S.Context) | |||
2763 | WarnUnusedResultAttr(AL.getRange(), S.Context, | |||
2764 | AL.getAttributeSpellingListIndex())); | |||
2765 | } | |||
2766 | ||||
2767 | static void handleWeakImportAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
2768 | // weak_import only applies to variable & function declarations. | |||
2769 | bool isDef = false; | |||
2770 | if (!D->canBeWeakImported(isDef)) { | |||
2771 | if (isDef) | |||
2772 | S.Diag(AL.getLoc(), diag::warn_attribute_invalid_on_definition) | |||
2773 | << "weak_import"; | |||
2774 | else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) || | |||
2775 | (S.Context.getTargetInfo().getTriple().isOSDarwin() && | |||
2776 | (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) { | |||
2777 | // Nothing to warn about here. | |||
2778 | } else | |||
2779 | S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) | |||
2780 | << AL.getName() << ExpectedVariableOrFunction; | |||
2781 | ||||
2782 | return; | |||
2783 | } | |||
2784 | ||||
2785 | D->addAttr(::new (S.Context) | |||
2786 | WeakImportAttr(AL.getRange(), S.Context, | |||
2787 | AL.getAttributeSpellingListIndex())); | |||
2788 | } | |||
2789 | ||||
2790 | // Handles reqd_work_group_size and work_group_size_hint. | |||
2791 | template <typename WorkGroupAttr> | |||
2792 | static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
2793 | uint32_t WGSize[3]; | |||
2794 | for (unsigned i = 0; i < 3; ++i) { | |||
2795 | const Expr *E = AL.getArgAsExpr(i); | |||
2796 | if (!checkUInt32Argument(S, AL, E, WGSize[i], i)) | |||
2797 | return; | |||
2798 | if (WGSize[i] == 0) { | |||
2799 | S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero) | |||
2800 | << AL.getName() << E->getSourceRange(); | |||
2801 | return; | |||
2802 | } | |||
2803 | } | |||
2804 | ||||
2805 | WorkGroupAttr *Existing = D->getAttr<WorkGroupAttr>(); | |||
2806 | if (Existing && !(Existing->getXDim() == WGSize[0] && | |||
2807 | Existing->getYDim() == WGSize[1] && | |||
2808 | Existing->getZDim() == WGSize[2])) | |||
2809 | S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL.getName(); | |||
2810 | ||||
2811 | D->addAttr(::new (S.Context) WorkGroupAttr(AL.getRange(), S.Context, | |||
2812 | WGSize[0], WGSize[1], WGSize[2], | |||
2813 | AL.getAttributeSpellingListIndex())); | |||
2814 | } | |||
2815 | ||||
2816 | // Handles intel_reqd_sub_group_size. | |||
2817 | static void handleSubGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
2818 | uint32_t SGSize; | |||
2819 | const Expr *E = AL.getArgAsExpr(0); | |||
2820 | if (!checkUInt32Argument(S, AL, E, SGSize)) | |||
2821 | return; | |||
2822 | if (SGSize == 0) { | |||
2823 | S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero) | |||
2824 | << AL.getName() << E->getSourceRange(); | |||
2825 | return; | |||
2826 | } | |||
2827 | ||||
2828 | OpenCLIntelReqdSubGroupSizeAttr *Existing = | |||
2829 | D->getAttr<OpenCLIntelReqdSubGroupSizeAttr>(); | |||
2830 | if (Existing && Existing->getSubGroupSize() != SGSize) | |||
2831 | S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL.getName(); | |||
2832 | ||||
2833 | D->addAttr(::new (S.Context) OpenCLIntelReqdSubGroupSizeAttr( | |||
2834 | AL.getRange(), S.Context, SGSize, | |||
2835 | AL.getAttributeSpellingListIndex())); | |||
2836 | } | |||
2837 | ||||
2838 | static void handleVecTypeHint(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
2839 | if (!AL.hasParsedType()) { | |||
2840 | S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) | |||
2841 | << AL.getName() << 1; | |||
2842 | return; | |||
2843 | } | |||
2844 | ||||
2845 | TypeSourceInfo *ParmTSI = nullptr; | |||
2846 | QualType ParmType = S.GetTypeFromParser(AL.getTypeArg(), &ParmTSI); | |||
2847 | assert(ParmTSI && "no type source info for attribute argument")(static_cast <bool> (ParmTSI && "no type source info for attribute argument" ) ? void (0) : __assert_fail ("ParmTSI && \"no type source info for attribute argument\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 2847, __extension__ __PRETTY_FUNCTION__)); | |||
2848 | ||||
2849 | if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() && | |||
2850 | (ParmType->isBooleanType() || | |||
2851 | !ParmType->isIntegralType(S.getASTContext()))) { | |||
2852 | S.Diag(AL.getLoc(), diag::err_attribute_argument_vec_type_hint) | |||
2853 | << ParmType; | |||
2854 | return; | |||
2855 | } | |||
2856 | ||||
2857 | if (VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>()) { | |||
2858 | if (!S.Context.hasSameType(A->getTypeHint(), ParmType)) { | |||
2859 | S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL.getName(); | |||
2860 | return; | |||
2861 | } | |||
2862 | } | |||
2863 | ||||
2864 | D->addAttr(::new (S.Context) VecTypeHintAttr(AL.getLoc(), S.Context, | |||
2865 | ParmTSI, | |||
2866 | AL.getAttributeSpellingListIndex())); | |||
2867 | } | |||
2868 | ||||
2869 | SectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range, | |||
2870 | StringRef Name, | |||
2871 | unsigned AttrSpellingListIndex) { | |||
2872 | // Explicit or partial specializations do not inherit | |||
2873 | // the section attribute from the primary template. | |||
2874 | if (const auto *FD = dyn_cast<FunctionDecl>(D)) { | |||
2875 | if (AttrSpellingListIndex == SectionAttr::Declspec_allocate && | |||
2876 | FD->isFunctionTemplateSpecialization()) | |||
2877 | return nullptr; | |||
2878 | } | |||
2879 | if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) { | |||
2880 | if (ExistingAttr->getName() == Name) | |||
2881 | return nullptr; | |||
2882 | Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section) | |||
2883 | << 1 /*section*/; | |||
2884 | Diag(Range.getBegin(), diag::note_previous_attribute); | |||
2885 | return nullptr; | |||
2886 | } | |||
2887 | return ::new (Context) SectionAttr(Range, Context, Name, | |||
2888 | AttrSpellingListIndex); | |||
2889 | } | |||
2890 | ||||
2891 | bool Sema::checkSectionName(SourceLocation LiteralLoc, StringRef SecName) { | |||
2892 | std::string Error = Context.getTargetInfo().isValidSectionSpecifier(SecName); | |||
2893 | if (!Error.empty()) { | |||
2894 | Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target) << Error | |||
2895 | << 1 /*'section'*/; | |||
2896 | return false; | |||
2897 | } | |||
2898 | return true; | |||
2899 | } | |||
2900 | ||||
2901 | static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
2902 | // Make sure that there is a string literal as the sections's single | |||
2903 | // argument. | |||
2904 | StringRef Str; | |||
2905 | SourceLocation LiteralLoc; | |||
2906 | if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc)) | |||
2907 | return; | |||
2908 | ||||
2909 | if (!S.checkSectionName(LiteralLoc, Str)) | |||
2910 | return; | |||
2911 | ||||
2912 | // If the target wants to validate the section specifier, make it happen. | |||
2913 | std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(Str); | |||
2914 | if (!Error.empty()) { | |||
2915 | S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target) | |||
2916 | << Error; | |||
2917 | return; | |||
2918 | } | |||
2919 | ||||
2920 | unsigned Index = AL.getAttributeSpellingListIndex(); | |||
2921 | SectionAttr *NewAttr = S.mergeSectionAttr(D, AL.getRange(), Str, Index); | |||
2922 | if (NewAttr) | |||
2923 | D->addAttr(NewAttr); | |||
2924 | } | |||
2925 | ||||
2926 | static bool checkCodeSegName(Sema&S, SourceLocation LiteralLoc, StringRef CodeSegName) { | |||
2927 | std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(CodeSegName); | |||
2928 | if (!Error.empty()) { | |||
2929 | S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target) << Error | |||
2930 | << 0 /*'code-seg'*/; | |||
2931 | return false; | |||
2932 | } | |||
2933 | return true; | |||
2934 | } | |||
2935 | ||||
2936 | CodeSegAttr *Sema::mergeCodeSegAttr(Decl *D, SourceRange Range, | |||
2937 | StringRef Name, | |||
2938 | unsigned AttrSpellingListIndex) { | |||
2939 | // Explicit or partial specializations do not inherit | |||
2940 | // the code_seg attribute from the primary template. | |||
2941 | if (const auto *FD = dyn_cast<FunctionDecl>(D)) { | |||
2942 | if (FD->isFunctionTemplateSpecialization()) | |||
2943 | return nullptr; | |||
2944 | } | |||
2945 | if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) { | |||
2946 | if (ExistingAttr->getName() == Name) | |||
2947 | return nullptr; | |||
2948 | Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section) | |||
2949 | << 0 /*codeseg*/; | |||
2950 | Diag(Range.getBegin(), diag::note_previous_attribute); | |||
2951 | return nullptr; | |||
2952 | } | |||
2953 | return ::new (Context) CodeSegAttr(Range, Context, Name, | |||
2954 | AttrSpellingListIndex); | |||
2955 | } | |||
2956 | ||||
2957 | static void handleCodeSegAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
2958 | StringRef Str; | |||
2959 | SourceLocation LiteralLoc; | |||
2960 | if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc)) | |||
2961 | return; | |||
2962 | if (!checkCodeSegName(S, LiteralLoc, Str)) | |||
2963 | return; | |||
2964 | if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) { | |||
2965 | if (!ExistingAttr->isImplicit()) { | |||
2966 | S.Diag(AL.getLoc(), | |||
2967 | ExistingAttr->getName() == Str | |||
2968 | ? diag::warn_duplicate_codeseg_attribute | |||
2969 | : diag::err_conflicting_codeseg_attribute); | |||
2970 | return; | |||
2971 | } | |||
2972 | D->dropAttr<CodeSegAttr>(); | |||
2973 | } | |||
2974 | if (CodeSegAttr *CSA = S.mergeCodeSegAttr(D, AL.getRange(), Str, | |||
2975 | AL.getAttributeSpellingListIndex())) | |||
2976 | D->addAttr(CSA); | |||
2977 | } | |||
2978 | ||||
2979 | // Check for things we'd like to warn about. Multiversioning issues are | |||
2980 | // handled later in the process, once we know how many exist. | |||
2981 | bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) { | |||
2982 | enum FirstParam { Unsupported, Duplicate }; | |||
2983 | enum SecondParam { None, Architecture }; | |||
2984 | for (auto Str : {"tune=", "fpmath="}) | |||
2985 | if (AttrStr.find(Str) != StringRef::npos) | |||
2986 | return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) | |||
2987 | << Unsupported << None << Str; | |||
2988 | ||||
2989 | TargetAttr::ParsedTargetAttr ParsedAttrs = TargetAttr::parse(AttrStr); | |||
2990 | ||||
2991 | if (!ParsedAttrs.Architecture.empty() && | |||
2992 | !Context.getTargetInfo().isValidCPUName(ParsedAttrs.Architecture)) | |||
2993 | return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) | |||
2994 | << Unsupported << Architecture << ParsedAttrs.Architecture; | |||
2995 | ||||
2996 | if (ParsedAttrs.DuplicateArchitecture) | |||
2997 | return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) | |||
2998 | << Duplicate << None << "arch="; | |||
2999 | ||||
3000 | for (const auto &Feature : ParsedAttrs.Features) { | |||
3001 | auto CurFeature = StringRef(Feature).drop_front(); // remove + or -. | |||
3002 | if (!Context.getTargetInfo().isValidFeatureName(CurFeature)) | |||
3003 | return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) | |||
3004 | << Unsupported << None << CurFeature; | |||
3005 | } | |||
3006 | ||||
3007 | return false; | |||
3008 | } | |||
3009 | ||||
3010 | static void handleTargetAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
3011 | StringRef Str; | |||
3012 | SourceLocation LiteralLoc; | |||
3013 | if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc) || | |||
3014 | S.checkTargetAttr(LiteralLoc, Str)) | |||
3015 | return; | |||
3016 | ||||
3017 | unsigned Index = AL.getAttributeSpellingListIndex(); | |||
3018 | TargetAttr *NewAttr = | |||
3019 | ::new (S.Context) TargetAttr(AL.getRange(), S.Context, Str, Index); | |||
3020 | D->addAttr(NewAttr); | |||
3021 | } | |||
3022 | ||||
3023 | static void handleMinVectorWidthAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
3024 | Expr *E = AL.getArgAsExpr(0); | |||
3025 | uint32_t VecWidth; | |||
3026 | if (!checkUInt32Argument(S, AL, E, VecWidth)) { | |||
3027 | AL.setInvalid(); | |||
3028 | return; | |||
3029 | } | |||
3030 | ||||
3031 | MinVectorWidthAttr *Existing = D->getAttr<MinVectorWidthAttr>(); | |||
3032 | if (Existing && Existing->getVectorWidth() != VecWidth) { | |||
3033 | S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL.getName(); | |||
3034 | return; | |||
3035 | } | |||
3036 | ||||
3037 | D->addAttr(::new (S.Context) | |||
3038 | MinVectorWidthAttr(AL.getRange(), S.Context, VecWidth, | |||
3039 | AL.getAttributeSpellingListIndex())); | |||
3040 | } | |||
3041 | ||||
3042 | static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
3043 | Expr *E = AL.getArgAsExpr(0); | |||
3044 | SourceLocation Loc = E->getExprLoc(); | |||
3045 | FunctionDecl *FD = nullptr; | |||
3046 | DeclarationNameInfo NI; | |||
3047 | ||||
3048 | // gcc only allows for simple identifiers. Since we support more than gcc, we | |||
3049 | // will warn the user. | |||
3050 | if (auto *DRE = dyn_cast<DeclRefExpr>(E)) { | |||
3051 | if (DRE->hasQualifier()) | |||
3052 | S.Diag(Loc, diag::warn_cleanup_ext); | |||
3053 | FD = dyn_cast<FunctionDecl>(DRE->getDecl()); | |||
3054 | NI = DRE->getNameInfo(); | |||
3055 | if (!FD) { | |||
3056 | S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 1 | |||
3057 | << NI.getName(); | |||
3058 | return; | |||
3059 | } | |||
3060 | } else if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(E)) { | |||
3061 | if (ULE->hasExplicitTemplateArgs()) | |||
3062 | S.Diag(Loc, diag::warn_cleanup_ext); | |||
3063 | FD = S.ResolveSingleFunctionTemplateSpecialization(ULE, true); | |||
3064 | NI = ULE->getNameInfo(); | |||
3065 | if (!FD) { | |||
3066 | S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 2 | |||
3067 | << NI.getName(); | |||
3068 | if (ULE->getType() == S.Context.OverloadTy) | |||
3069 | S.NoteAllOverloadCandidates(ULE); | |||
3070 | return; | |||
3071 | } | |||
3072 | } else { | |||
3073 | S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 0; | |||
3074 | return; | |||
3075 | } | |||
3076 | ||||
3077 | if (FD->getNumParams() != 1) { | |||
3078 | S.Diag(Loc, diag::err_attribute_cleanup_func_must_take_one_arg) | |||
3079 | << NI.getName(); | |||
3080 | return; | |||
3081 | } | |||
3082 | ||||
3083 | // We're currently more strict than GCC about what function types we accept. | |||
3084 | // If this ever proves to be a problem it should be easy to fix. | |||
3085 | QualType Ty = S.Context.getPointerType(cast<VarDecl>(D)->getType()); | |||
3086 | QualType ParamTy = FD->getParamDecl(0)->getType(); | |||
3087 | if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(), | |||
3088 | ParamTy, Ty) != Sema::Compatible) { | |||
3089 | S.Diag(Loc, diag::err_attribute_cleanup_func_arg_incompatible_type) | |||
3090 | << NI.getName() << ParamTy << Ty; | |||
3091 | return; | |||
3092 | } | |||
3093 | ||||
3094 | D->addAttr(::new (S.Context) | |||
3095 | CleanupAttr(AL.getRange(), S.Context, FD, | |||
3096 | AL.getAttributeSpellingListIndex())); | |||
3097 | } | |||
3098 | ||||
3099 | static void handleEnumExtensibilityAttr(Sema &S, Decl *D, | |||
3100 | const ParsedAttr &AL) { | |||
3101 | if (!AL.isArgIdent(0)) { | |||
3102 | S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type) | |||
3103 | << AL.getName() << 0 << AANT_ArgumentIdentifier; | |||
3104 | return; | |||
3105 | } | |||
3106 | ||||
3107 | EnumExtensibilityAttr::Kind ExtensibilityKind; | |||
3108 | IdentifierInfo *II = AL.getArgAsIdent(0)->Ident; | |||
3109 | if (!EnumExtensibilityAttr::ConvertStrToKind(II->getName(), | |||
3110 | ExtensibilityKind)) { | |||
3111 | S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) | |||
3112 | << AL.getName() << II; | |||
3113 | return; | |||
3114 | } | |||
3115 | ||||
3116 | D->addAttr(::new (S.Context) EnumExtensibilityAttr( | |||
3117 | AL.getRange(), S.Context, ExtensibilityKind, | |||
3118 | AL.getAttributeSpellingListIndex())); | |||
3119 | } | |||
3120 | ||||
3121 | /// Handle __attribute__((format_arg((idx)))) attribute based on | |||
3122 | /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html | |||
3123 | static void handleFormatArgAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
3124 | Expr *IdxExpr = AL.getArgAsExpr(0); | |||
3125 | ParamIdx Idx; | |||
3126 | if (!checkFunctionOrMethodParameterIndex(S, D, AL, 1, IdxExpr, Idx)) | |||
3127 | return; | |||
3128 | ||||
3129 | // Make sure the format string is really a string. | |||
3130 | QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex()); | |||
3131 | ||||
3132 | bool NotNSStringTy = !isNSStringType(Ty, S.Context); | |||
3133 | if (NotNSStringTy && | |||
3134 | !isCFStringType(Ty, S.Context) && | |||
3135 | (!Ty->isPointerType() || | |||
3136 | !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { | |||
3137 | S.Diag(AL.getLoc(), diag::err_format_attribute_not) | |||
3138 | << "a string type" << IdxExpr->getSourceRange() | |||
3139 | << getFunctionOrMethodParamRange(D, 0); | |||
3140 | return; | |||
3141 | } | |||
3142 | Ty = getFunctionOrMethodResultType(D); | |||
3143 | if (!isNSStringType(Ty, S.Context) && | |||
3144 | !isCFStringType(Ty, S.Context) && | |||
3145 | (!Ty->isPointerType() || | |||
3146 | !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { | |||
3147 | S.Diag(AL.getLoc(), diag::err_format_attribute_result_not) | |||
3148 | << (NotNSStringTy ? "string type" : "NSString") | |||
3149 | << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0); | |||
3150 | return; | |||
3151 | } | |||
3152 | ||||
3153 | D->addAttr(::new (S.Context) FormatArgAttr( | |||
3154 | AL.getRange(), S.Context, Idx, AL.getAttributeSpellingListIndex())); | |||
3155 | } | |||
3156 | ||||
3157 | enum FormatAttrKind { | |||
3158 | CFStringFormat, | |||
3159 | NSStringFormat, | |||
3160 | StrftimeFormat, | |||
3161 | SupportedFormat, | |||
3162 | IgnoredFormat, | |||
3163 | InvalidFormat | |||
3164 | }; | |||
3165 | ||||
3166 | /// getFormatAttrKind - Map from format attribute names to supported format | |||
3167 | /// types. | |||
3168 | static FormatAttrKind getFormatAttrKind(StringRef Format) { | |||
3169 | return llvm::StringSwitch<FormatAttrKind>(Format) | |||
3170 | // Check for formats that get handled specially. | |||
3171 | .Case("NSString", NSStringFormat) | |||
3172 | .Case("CFString", CFStringFormat) | |||
3173 | .Case("strftime", StrftimeFormat) | |||
3174 | ||||
3175 | // Otherwise, check for supported formats. | |||
3176 | .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat) | |||
3177 | .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat) | |||
3178 | .Case("kprintf", SupportedFormat) // OpenBSD. | |||
3179 | .Case("freebsd_kprintf", SupportedFormat) // FreeBSD. | |||
3180 | .Case("os_trace", SupportedFormat) | |||
3181 | .Case("os_log", SupportedFormat) | |||
3182 | ||||
3183 | .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat) | |||
3184 | .Default(InvalidFormat); | |||
3185 | } | |||
3186 | ||||
3187 | /// Handle __attribute__((init_priority(priority))) attributes based on | |||
3188 | /// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html | |||
3189 | static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
3190 | if (!S.getLangOpts().CPlusPlus) { | |||
3191 | S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL.getName(); | |||
3192 | return; | |||
3193 | } | |||
3194 | ||||
3195 | if (S.getCurFunctionOrMethodDecl()) { | |||
3196 | S.Diag(AL.getLoc(), diag::err_init_priority_object_attr); | |||
3197 | AL.setInvalid(); | |||
3198 | return; | |||
3199 | } | |||
3200 | QualType T = cast<VarDecl>(D)->getType(); | |||
3201 | if (S.Context.getAsArrayType(T)) | |||
3202 | T = S.Context.getBaseElementType(T); | |||
3203 | if (!T->getAs<RecordType>()) { | |||
3204 | S.Diag(AL.getLoc(), diag::err_init_priority_object_attr); | |||
3205 | AL.setInvalid(); | |||
3206 | return; | |||
3207 | } | |||
3208 | ||||
3209 | Expr *E = AL.getArgAsExpr(0); | |||
3210 | uint32_t prioritynum; | |||
3211 | if (!checkUInt32Argument(S, AL, E, prioritynum)) { | |||
3212 | AL.setInvalid(); | |||
3213 | return; | |||
3214 | } | |||
3215 | ||||
3216 | if (prioritynum < 101 || prioritynum > 65535) { | |||
3217 | S.Diag(AL.getLoc(), diag::err_attribute_argument_outof_range) | |||
3218 | << E->getSourceRange() << AL.getName() << 101 << 65535; | |||
3219 | AL.setInvalid(); | |||
3220 | return; | |||
3221 | } | |||
3222 | D->addAttr(::new (S.Context) | |||
3223 | InitPriorityAttr(AL.getRange(), S.Context, prioritynum, | |||
3224 | AL.getAttributeSpellingListIndex())); | |||
3225 | } | |||
3226 | ||||
3227 | FormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, | |||
3228 | IdentifierInfo *Format, int FormatIdx, | |||
3229 | int FirstArg, | |||
3230 | unsigned AttrSpellingListIndex) { | |||
3231 | // Check whether we already have an equivalent format attribute. | |||
3232 | for (auto *F : D->specific_attrs<FormatAttr>()) { | |||
3233 | if (F->getType() == Format && | |||
3234 | F->getFormatIdx() == FormatIdx && | |||
3235 | F->getFirstArg() == FirstArg) { | |||
3236 | // If we don't have a valid location for this attribute, adopt the | |||
3237 | // location. | |||
3238 | if (F->getLocation().isInvalid()) | |||
3239 | F->setRange(Range); | |||
3240 | return nullptr; | |||
3241 | } | |||
3242 | } | |||
3243 | ||||
3244 | return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx, | |||
3245 | FirstArg, AttrSpellingListIndex); | |||
3246 | } | |||
3247 | ||||
3248 | /// Handle __attribute__((format(type,idx,firstarg))) attributes based on | |||
3249 | /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html | |||
3250 | static void handleFormatAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
3251 | if (!AL.isArgIdent(0)) { | |||
3252 | S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type) | |||
3253 | << AL.getName() << 1 << AANT_ArgumentIdentifier; | |||
3254 | return; | |||
3255 | } | |||
3256 | ||||
3257 | // In C++ the implicit 'this' function parameter also counts, and they are | |||
3258 | // counted from one. | |||
3259 | bool HasImplicitThisParam = isInstanceMethod(D); | |||
3260 | unsigned NumArgs = getFunctionOrMethodNumParams(D) + HasImplicitThisParam; | |||
3261 | ||||
3262 | IdentifierInfo *II = AL.getArgAsIdent(0)->Ident; | |||
3263 | StringRef Format = II->getName(); | |||
3264 | ||||
3265 | if (normalizeName(Format)) { | |||
3266 | // If we've modified the string name, we need a new identifier for it. | |||
3267 | II = &S.Context.Idents.get(Format); | |||
3268 | } | |||
3269 | ||||
3270 | // Check for supported formats. | |||
3271 | FormatAttrKind Kind = getFormatAttrKind(Format); | |||
3272 | ||||
3273 | if (Kind == IgnoredFormat) | |||
3274 | return; | |||
3275 | ||||
3276 | if (Kind == InvalidFormat) { | |||
3277 | S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) | |||
3278 | << AL.getName() << II->getName(); | |||
3279 | return; | |||
3280 | } | |||
3281 | ||||
3282 | // checks for the 2nd argument | |||
3283 | Expr *IdxExpr = AL.getArgAsExpr(1); | |||
3284 | uint32_t Idx; | |||
3285 | if (!checkUInt32Argument(S, AL, IdxExpr, Idx, 2)) | |||
3286 | return; | |||
3287 | ||||
3288 | if (Idx < 1 || Idx > NumArgs) { | |||
3289 | S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) | |||
3290 | << AL.getName() << 2 << IdxExpr->getSourceRange(); | |||
3291 | return; | |||
3292 | } | |||
3293 | ||||
3294 | // FIXME: Do we need to bounds check? | |||
3295 | unsigned ArgIdx = Idx - 1; | |||
3296 | ||||
3297 | if (HasImplicitThisParam) { | |||
3298 | if (ArgIdx == 0) { | |||
3299 | S.Diag(AL.getLoc(), | |||
3300 | diag::err_format_attribute_implicit_this_format_string) | |||
3301 | << IdxExpr->getSourceRange(); | |||
3302 | return; | |||
3303 | } | |||
3304 | ArgIdx--; | |||
3305 | } | |||
3306 | ||||
3307 | // make sure the format string is really a string | |||
3308 | QualType Ty = getFunctionOrMethodParamType(D, ArgIdx); | |||
3309 | ||||
3310 | if (Kind == CFStringFormat) { | |||
3311 | if (!isCFStringType(Ty, S.Context)) { | |||
3312 | S.Diag(AL.getLoc(), diag::err_format_attribute_not) | |||
3313 | << "a CFString" << IdxExpr->getSourceRange() | |||
3314 | << getFunctionOrMethodParamRange(D, ArgIdx); | |||
3315 | return; | |||
3316 | } | |||
3317 | } else if (Kind == NSStringFormat) { | |||
3318 | // FIXME: do we need to check if the type is NSString*? What are the | |||
3319 | // semantics? | |||
3320 | if (!isNSStringType(Ty, S.Context)) { | |||
3321 | S.Diag(AL.getLoc(), diag::err_format_attribute_not) | |||
3322 | << "an NSString" << IdxExpr->getSourceRange() | |||
3323 | << getFunctionOrMethodParamRange(D, ArgIdx); | |||
3324 | return; | |||
3325 | } | |||
3326 | } else if (!Ty->isPointerType() || | |||
3327 | !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { | |||
3328 | S.Diag(AL.getLoc(), diag::err_format_attribute_not) | |||
3329 | << "a string type" << IdxExpr->getSourceRange() | |||
3330 | << getFunctionOrMethodParamRange(D, ArgIdx); | |||
3331 | return; | |||
3332 | } | |||
3333 | ||||
3334 | // check the 3rd argument | |||
3335 | Expr *FirstArgExpr = AL.getArgAsExpr(2); | |||
3336 | uint32_t FirstArg; | |||
3337 | if (!checkUInt32Argument(S, AL, FirstArgExpr, FirstArg, 3)) | |||
3338 | return; | |||
3339 | ||||
3340 | // check if the function is variadic if the 3rd argument non-zero | |||
3341 | if (FirstArg != 0) { | |||
3342 | if (isFunctionOrMethodVariadic(D)) { | |||
3343 | ++NumArgs; // +1 for ... | |||
3344 | } else { | |||
3345 | S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic); | |||
3346 | return; | |||
3347 | } | |||
3348 | } | |||
3349 | ||||
3350 | // strftime requires FirstArg to be 0 because it doesn't read from any | |||
3351 | // variable the input is just the current time + the format string. | |||
3352 | if (Kind == StrftimeFormat) { | |||
3353 | if (FirstArg != 0) { | |||
3354 | S.Diag(AL.getLoc(), diag::err_format_strftime_third_parameter) | |||
3355 | << FirstArgExpr->getSourceRange(); | |||
3356 | return; | |||
3357 | } | |||
3358 | // if 0 it disables parameter checking (to use with e.g. va_list) | |||
3359 | } else if (FirstArg != 0 && FirstArg != NumArgs) { | |||
3360 | S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) | |||
3361 | << AL.getName() << 3 << FirstArgExpr->getSourceRange(); | |||
3362 | return; | |||
3363 | } | |||
3364 | ||||
3365 | FormatAttr *NewAttr = S.mergeFormatAttr(D, AL.getRange(), II, | |||
3366 | Idx, FirstArg, | |||
3367 | AL.getAttributeSpellingListIndex()); | |||
3368 | if (NewAttr) | |||
3369 | D->addAttr(NewAttr); | |||
3370 | } | |||
3371 | ||||
3372 | static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
3373 | // Try to find the underlying union declaration. | |||
3374 | RecordDecl *RD = nullptr; | |||
3375 | const auto *TD = dyn_cast<TypedefNameDecl>(D); | |||
3376 | if (TD && TD->getUnderlyingType()->isUnionType()) | |||
3377 | RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); | |||
3378 | else | |||
3379 | RD = dyn_cast<RecordDecl>(D); | |||
3380 | ||||
3381 | if (!RD || !RD->isUnion()) { | |||
3382 | S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) | |||
3383 | << AL.getName() << ExpectedUnion; | |||
3384 | return; | |||
3385 | } | |||
3386 | ||||
3387 | if (!RD->isCompleteDefinition()) { | |||
3388 | if (!RD->isBeingDefined()) | |||
3389 | S.Diag(AL.getLoc(), | |||
3390 | diag::warn_transparent_union_attribute_not_definition); | |||
3391 | return; | |||
3392 | } | |||
3393 | ||||
3394 | RecordDecl::field_iterator Field = RD->field_begin(), | |||
3395 | FieldEnd = RD->field_end(); | |||
3396 | if (Field == FieldEnd) { | |||
3397 | S.Diag(AL.getLoc(), diag::warn_transparent_union_attribute_zero_fields); | |||
3398 | return; | |||
3399 | } | |||
3400 | ||||
3401 | FieldDecl *FirstField = *Field; | |||
3402 | QualType FirstType = FirstField->getType(); | |||
3403 | if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { | |||
3404 | S.Diag(FirstField->getLocation(), | |||
3405 | diag::warn_transparent_union_attribute_floating) | |||
3406 | << FirstType->isVectorType() << FirstType; | |||
3407 | return; | |||
3408 | } | |||
3409 | ||||
3410 | if (FirstType->isIncompleteType()) | |||
3411 | return; | |||
3412 | uint64_t FirstSize = S.Context.getTypeSize(FirstType); | |||
3413 | uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); | |||
3414 | for (; Field != FieldEnd; ++Field) { | |||
3415 | QualType FieldType = Field->getType(); | |||
3416 | if (FieldType->isIncompleteType()) | |||
3417 | return; | |||
3418 | // FIXME: this isn't fully correct; we also need to test whether the | |||
3419 | // members of the union would all have the same calling convention as the | |||
3420 | // first member of the union. Checking just the size and alignment isn't | |||
3421 | // sufficient (consider structs passed on the stack instead of in registers | |||
3422 | // as an example). | |||
3423 | if (S.Context.getTypeSize(FieldType) != FirstSize || | |||
3424 | S.Context.getTypeAlign(FieldType) > FirstAlign) { | |||
3425 | // Warn if we drop the attribute. | |||
3426 | bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; | |||
3427 | unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) | |||
3428 | : S.Context.getTypeAlign(FieldType); | |||
3429 | S.Diag(Field->getLocation(), | |||
3430 | diag::warn_transparent_union_attribute_field_size_align) | |||
3431 | << isSize << Field->getDeclName() << FieldBits; | |||
3432 | unsigned FirstBits = isSize? FirstSize : FirstAlign; | |||
3433 | S.Diag(FirstField->getLocation(), | |||
3434 | diag::note_transparent_union_first_field_size_align) | |||
3435 | << isSize << FirstBits; | |||
3436 | return; | |||
3437 | } | |||
3438 | } | |||
3439 | ||||
3440 | RD->addAttr(::new (S.Context) | |||
3441 | TransparentUnionAttr(AL.getRange(), S.Context, | |||
3442 | AL.getAttributeSpellingListIndex())); | |||
3443 | } | |||
3444 | ||||
3445 | static void handleAnnotateAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
3446 | // Make sure that there is a string literal as the annotation's single | |||
3447 | // argument. | |||
3448 | StringRef Str; | |||
3449 | if (!S.checkStringLiteralArgumentAttr(AL, 0, Str)) | |||
3450 | return; | |||
3451 | ||||
3452 | // Don't duplicate annotations that are already set. | |||
3453 | for (const auto *I : D->specific_attrs<AnnotateAttr>()) { | |||
3454 | if (I->getAnnotation() == Str) | |||
3455 | return; | |||
3456 | } | |||
3457 | ||||
3458 | D->addAttr(::new (S.Context) | |||
3459 | AnnotateAttr(AL.getRange(), S.Context, Str, | |||
3460 | AL.getAttributeSpellingListIndex())); | |||
3461 | } | |||
3462 | ||||
3463 | static void handleAlignValueAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
3464 | S.AddAlignValueAttr(AL.getRange(), D, AL.getArgAsExpr(0), | |||
3465 | AL.getAttributeSpellingListIndex()); | |||
3466 | } | |||
3467 | ||||
3468 | void Sema::AddAlignValueAttr(SourceRange AttrRange, Decl *D, Expr *E, | |||
3469 | unsigned SpellingListIndex) { | |||
3470 | AlignValueAttr TmpAttr(AttrRange, Context, E, SpellingListIndex); | |||
3471 | SourceLocation AttrLoc = AttrRange.getBegin(); | |||
3472 | ||||
3473 | QualType T; | |||
3474 | if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) | |||
3475 | T = TD->getUnderlyingType(); | |||
3476 | else if (const auto *VD = dyn_cast<ValueDecl>(D)) | |||
3477 | T = VD->getType(); | |||
3478 | else | |||
3479 | llvm_unreachable("Unknown decl type for align_value")::llvm::llvm_unreachable_internal("Unknown decl type for align_value" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 3479); | |||
3480 | ||||
3481 | if (!T->isDependentType() && !T->isAnyPointerType() && | |||
3482 | !T->isReferenceType() && !T->isMemberPointerType()) { | |||
3483 | Diag(AttrLoc, diag::warn_attribute_pointer_or_reference_only) | |||
3484 | << &TmpAttr /*TmpAttr.getName()*/ << T << D->getSourceRange(); | |||
3485 | return; | |||
3486 | } | |||
3487 | ||||
3488 | if (!E->isValueDependent()) { | |||
3489 | llvm::APSInt Alignment; | |||
3490 | ExprResult ICE | |||
3491 | = VerifyIntegerConstantExpression(E, &Alignment, | |||
3492 | diag::err_align_value_attribute_argument_not_int, | |||
3493 | /*AllowFold*/ false); | |||
3494 | if (ICE.isInvalid()) | |||
3495 | return; | |||
3496 | ||||
3497 | if (!Alignment.isPowerOf2()) { | |||
3498 | Diag(AttrLoc, diag::err_alignment_not_power_of_two) | |||
3499 | << E->getSourceRange(); | |||
3500 | return; | |||
3501 | } | |||
3502 | ||||
3503 | D->addAttr(::new (Context) | |||
3504 | AlignValueAttr(AttrRange, Context, ICE.get(), | |||
3505 | SpellingListIndex)); | |||
3506 | return; | |||
3507 | } | |||
3508 | ||||
3509 | // Save dependent expressions in the AST to be instantiated. | |||
3510 | D->addAttr(::new (Context) AlignValueAttr(TmpAttr)); | |||
3511 | } | |||
3512 | ||||
3513 | static void handleAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
3514 | // check the attribute arguments. | |||
3515 | if (AL.getNumArgs() > 1) { | |||
3516 | S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) | |||
3517 | << AL.getName() << 1; | |||
3518 | return; | |||
3519 | } | |||
3520 | ||||
3521 | if (AL.getNumArgs() == 0) { | |||
3522 | D->addAttr(::new (S.Context) AlignedAttr(AL.getRange(), S.Context, | |||
3523 | true, nullptr, AL.getAttributeSpellingListIndex())); | |||
3524 | return; | |||
3525 | } | |||
3526 | ||||
3527 | Expr *E = AL.getArgAsExpr(0); | |||
3528 | if (AL.isPackExpansion() && !E->containsUnexpandedParameterPack()) { | |||
3529 | S.Diag(AL.getEllipsisLoc(), | |||
3530 | diag::err_pack_expansion_without_parameter_packs); | |||
3531 | return; | |||
3532 | } | |||
3533 | ||||
3534 | if (!AL.isPackExpansion() && S.DiagnoseUnexpandedParameterPack(E)) | |||
3535 | return; | |||
3536 | ||||
3537 | S.AddAlignedAttr(AL.getRange(), D, E, AL.getAttributeSpellingListIndex(), | |||
3538 | AL.isPackExpansion()); | |||
3539 | } | |||
3540 | ||||
3541 | void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, | |||
3542 | unsigned SpellingListIndex, bool IsPackExpansion) { | |||
3543 | AlignedAttr TmpAttr(AttrRange, Context, true, E, SpellingListIndex); | |||
3544 | SourceLocation AttrLoc = AttrRange.getBegin(); | |||
3545 | ||||
3546 | // C++11 alignas(...) and C11 _Alignas(...) have additional requirements. | |||
3547 | if (TmpAttr.isAlignas()) { | |||
3548 | // C++11 [dcl.align]p1: | |||
3549 | // An alignment-specifier may be applied to a variable or to a class | |||
3550 | // data member, but it shall not be applied to a bit-field, a function | |||
3551 | // parameter, the formal parameter of a catch clause, or a variable | |||
3552 | // declared with the register storage class specifier. An | |||
3553 | // alignment-specifier may also be applied to the declaration of a class | |||
3554 | // or enumeration type. | |||
3555 | // C11 6.7.5/2: | |||
3556 | // An alignment attribute shall not be specified in a declaration of | |||
3557 | // a typedef, or a bit-field, or a function, or a parameter, or an | |||
3558 | // object declared with the register storage-class specifier. | |||
3559 | int DiagKind = -1; | |||
3560 | if (isa<ParmVarDecl>(D)) { | |||
3561 | DiagKind = 0; | |||
3562 | } else if (const auto *VD = dyn_cast<VarDecl>(D)) { | |||
3563 | if (VD->getStorageClass() == SC_Register) | |||
3564 | DiagKind = 1; | |||
3565 | if (VD->isExceptionVariable()) | |||
3566 | DiagKind = 2; | |||
3567 | } else if (const auto *FD = dyn_cast<FieldDecl>(D)) { | |||
3568 | if (FD->isBitField()) | |||
3569 | DiagKind = 3; | |||
3570 | } else if (!isa<TagDecl>(D)) { | |||
3571 | Diag(AttrLoc, diag::err_attribute_wrong_decl_type) << &TmpAttr | |||
3572 | << (TmpAttr.isC11() ? ExpectedVariableOrField | |||
3573 | : ExpectedVariableFieldOrTag); | |||
3574 | return; | |||
3575 | } | |||
3576 | if (DiagKind != -1) { | |||
3577 | Diag(AttrLoc, diag::err_alignas_attribute_wrong_decl_type) | |||
3578 | << &TmpAttr << DiagKind; | |||
3579 | return; | |||
3580 | } | |||
3581 | } | |||
3582 | ||||
3583 | if (E->isValueDependent()) { | |||
3584 | // We can't support a dependent alignment on a non-dependent type, | |||
3585 | // because we have no way to model that a type is "alignment-dependent" | |||
3586 | // but not dependent in any other way. | |||
3587 | if (const auto *TND = dyn_cast<TypedefNameDecl>(D)) { | |||
3588 | if (!TND->getUnderlyingType()->isDependentType()) { | |||
3589 | Diag(AttrLoc, diag::err_alignment_dependent_typedef_name) | |||
3590 | << E->getSourceRange(); | |||
3591 | return; | |||
3592 | } | |||
3593 | } | |||
3594 | ||||
3595 | // Save dependent expressions in the AST to be instantiated. | |||
3596 | AlignedAttr *AA = ::new (Context) AlignedAttr(TmpAttr); | |||
3597 | AA->setPackExpansion(IsPackExpansion); | |||
3598 | D->addAttr(AA); | |||
3599 | return; | |||
3600 | } | |||
3601 | ||||
3602 | // FIXME: Cache the number on the AL object? | |||
3603 | llvm::APSInt Alignment; | |||
3604 | ExprResult ICE | |||
3605 | = VerifyIntegerConstantExpression(E, &Alignment, | |||
3606 | diag::err_aligned_attribute_argument_not_int, | |||
3607 | /*AllowFold*/ false); | |||
3608 | if (ICE.isInvalid()) | |||
3609 | return; | |||
3610 | ||||
3611 | uint64_t AlignVal = Alignment.getZExtValue(); | |||
3612 | ||||
3613 | // C++11 [dcl.align]p2: | |||
3614 | // -- if the constant expression evaluates to zero, the alignment | |||
3615 | // specifier shall have no effect | |||
3616 | // C11 6.7.5p6: | |||
3617 | // An alignment specification of zero has no effect. | |||
3618 | if (!(TmpAttr.isAlignas() && !Alignment)) { | |||
3619 | if (!llvm::isPowerOf2_64(AlignVal)) { | |||
3620 | Diag(AttrLoc, diag::err_alignment_not_power_of_two) | |||
3621 | << E->getSourceRange(); | |||
3622 | return; | |||
3623 | } | |||
3624 | } | |||
3625 | ||||
3626 | // Alignment calculations can wrap around if it's greater than 2**28. | |||
3627 | unsigned MaxValidAlignment = | |||
3628 | Context.getTargetInfo().getTriple().isOSBinFormatCOFF() ? 8192 | |||
3629 | : 268435456; | |||
3630 | if (AlignVal > MaxValidAlignment) { | |||
3631 | Diag(AttrLoc, diag::err_attribute_aligned_too_great) << MaxValidAlignment | |||
3632 | << E->getSourceRange(); | |||
3633 | return; | |||
3634 | } | |||
3635 | ||||
3636 | if (Context.getTargetInfo().isTLSSupported()) { | |||
3637 | unsigned MaxTLSAlign = | |||
3638 | Context.toCharUnitsFromBits(Context.getTargetInfo().getMaxTLSAlign()) | |||
3639 | .getQuantity(); | |||
3640 | const auto *VD = dyn_cast<VarDecl>(D); | |||
3641 | if (MaxTLSAlign && AlignVal > MaxTLSAlign && VD && | |||
3642 | VD->getTLSKind() != VarDecl::TLS_None) { | |||
3643 | Diag(VD->getLocation(), diag::err_tls_var_aligned_over_maximum) | |||
3644 | << (unsigned)AlignVal << VD << MaxTLSAlign; | |||
3645 | return; | |||
3646 | } | |||
3647 | } | |||
3648 | ||||
3649 | AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, true, | |||
3650 | ICE.get(), SpellingListIndex); | |||
3651 | AA->setPackExpansion(IsPackExpansion); | |||
3652 | D->addAttr(AA); | |||
3653 | } | |||
3654 | ||||
3655 | void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS, | |||
3656 | unsigned SpellingListIndex, bool IsPackExpansion) { | |||
3657 | // FIXME: Cache the number on the AL object if non-dependent? | |||
3658 | // FIXME: Perform checking of type validity | |||
3659 | AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, false, TS, | |||
3660 | SpellingListIndex); | |||
3661 | AA->setPackExpansion(IsPackExpansion); | |||
3662 | D->addAttr(AA); | |||
3663 | } | |||
3664 | ||||
3665 | void Sema::CheckAlignasUnderalignment(Decl *D) { | |||
3666 | assert(D->hasAttrs() && "no attributes on decl")(static_cast <bool> (D->hasAttrs() && "no attributes on decl" ) ? void (0) : __assert_fail ("D->hasAttrs() && \"no attributes on decl\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 3666, __extension__ __PRETTY_FUNCTION__)); | |||
3667 | ||||
3668 | QualType UnderlyingTy, DiagTy; | |||
3669 | if (const auto *VD = dyn_cast<ValueDecl>(D)) { | |||
3670 | UnderlyingTy = DiagTy = VD->getType(); | |||
3671 | } else { | |||
3672 | UnderlyingTy = DiagTy = Context.getTagDeclType(cast<TagDecl>(D)); | |||
3673 | if (const auto *ED = dyn_cast<EnumDecl>(D)) | |||
3674 | UnderlyingTy = ED->getIntegerType(); | |||
3675 | } | |||
3676 | if (DiagTy->isDependentType() || DiagTy->isIncompleteType()) | |||
3677 | return; | |||
3678 | ||||
3679 | // C++11 [dcl.align]p5, C11 6.7.5/4: | |||
3680 | // The combined effect of all alignment attributes in a declaration shall | |||
3681 | // not specify an alignment that is less strict than the alignment that | |||
3682 | // would otherwise be required for the entity being declared. | |||
3683 | AlignedAttr *AlignasAttr = nullptr; | |||
3684 | unsigned Align = 0; | |||
3685 | for (auto *I : D->specific_attrs<AlignedAttr>()) { | |||
3686 | if (I->isAlignmentDependent()) | |||
3687 | return; | |||
3688 | if (I->isAlignas()) | |||
3689 | AlignasAttr = I; | |||
3690 | Align = std::max(Align, I->getAlignment(Context)); | |||
3691 | } | |||
3692 | ||||
3693 | if (AlignasAttr && Align) { | |||
3694 | CharUnits RequestedAlign = Context.toCharUnitsFromBits(Align); | |||
3695 | CharUnits NaturalAlign = Context.getTypeAlignInChars(UnderlyingTy); | |||
3696 | if (NaturalAlign > RequestedAlign) | |||
3697 | Diag(AlignasAttr->getLocation(), diag::err_alignas_underaligned) | |||
3698 | << DiagTy << (unsigned)NaturalAlign.getQuantity(); | |||
3699 | } | |||
3700 | } | |||
3701 | ||||
3702 | bool Sema::checkMSInheritanceAttrOnDefinition( | |||
3703 | CXXRecordDecl *RD, SourceRange Range, bool BestCase, | |||
3704 | MSInheritanceAttr::Spelling SemanticSpelling) { | |||
3705 | assert(RD->hasDefinition() && "RD has no definition!")(static_cast <bool> (RD->hasDefinition() && "RD has no definition!" ) ? void (0) : __assert_fail ("RD->hasDefinition() && \"RD has no definition!\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 3705, __extension__ __PRETTY_FUNCTION__)); | |||
3706 | ||||
3707 | // We may not have seen base specifiers or any virtual methods yet. We will | |||
3708 | // have to wait until the record is defined to catch any mismatches. | |||
3709 | if (!RD->getDefinition()->isCompleteDefinition()) | |||
3710 | return false; | |||
3711 | ||||
3712 | // The unspecified model never matches what a definition could need. | |||
3713 | if (SemanticSpelling == MSInheritanceAttr::Keyword_unspecified_inheritance) | |||
3714 | return false; | |||
3715 | ||||
3716 | if (BestCase) { | |||
3717 | if (RD->calculateInheritanceModel() == SemanticSpelling) | |||
3718 | return false; | |||
3719 | } else { | |||
3720 | if (RD->calculateInheritanceModel() <= SemanticSpelling) | |||
3721 | return false; | |||
3722 | } | |||
3723 | ||||
3724 | Diag(Range.getBegin(), diag::err_mismatched_ms_inheritance) | |||
3725 | << 0 /*definition*/; | |||
3726 | Diag(RD->getDefinition()->getLocation(), diag::note_defined_here) | |||
3727 | << RD->getNameAsString(); | |||
3728 | return true; | |||
3729 | } | |||
3730 | ||||
3731 | /// parseModeAttrArg - Parses attribute mode string and returns parsed type | |||
3732 | /// attribute. | |||
3733 | static void parseModeAttrArg(Sema &S, StringRef Str, unsigned &DestWidth, | |||
3734 | bool &IntegerMode, bool &ComplexMode) { | |||
3735 | IntegerMode = true; | |||
3736 | ComplexMode = false; | |||
3737 | switch (Str.size()) { | |||
3738 | case 2: | |||
3739 | switch (Str[0]) { | |||
3740 | case 'Q': | |||
3741 | DestWidth = 8; | |||
3742 | break; | |||
3743 | case 'H': | |||
3744 | DestWidth = 16; | |||
3745 | break; | |||
3746 | case 'S': | |||
3747 | DestWidth = 32; | |||
3748 | break; | |||
3749 | case 'D': | |||
3750 | DestWidth = 64; | |||
3751 | break; | |||
3752 | case 'X': | |||
3753 | DestWidth = 96; | |||
3754 | break; | |||
3755 | case 'T': | |||
3756 | DestWidth = 128; | |||
3757 | break; | |||
3758 | } | |||
3759 | if (Str[1] == 'F') { | |||
3760 | IntegerMode = false; | |||
3761 | } else if (Str[1] == 'C') { | |||
3762 | IntegerMode = false; | |||
3763 | ComplexMode = true; | |||
3764 | } else if (Str[1] != 'I') { | |||
3765 | DestWidth = 0; | |||
3766 | } | |||
3767 | break; | |||
3768 | case 4: | |||
3769 | // FIXME: glibc uses 'word' to define register_t; this is narrower than a | |||
3770 | // pointer on PIC16 and other embedded platforms. | |||
3771 | if (Str == "word") | |||
3772 | DestWidth = S.Context.getTargetInfo().getRegisterWidth(); | |||
3773 | else if (Str == "byte") | |||
3774 | DestWidth = S.Context.getTargetInfo().getCharWidth(); | |||
3775 | break; | |||
3776 | case 7: | |||
3777 | if (Str == "pointer") | |||
3778 | DestWidth = S.Context.getTargetInfo().getPointerWidth(0); | |||
3779 | break; | |||
3780 | case 11: | |||
3781 | if (Str == "unwind_word") | |||
3782 | DestWidth = S.Context.getTargetInfo().getUnwindWordWidth(); | |||
3783 | break; | |||
3784 | } | |||
3785 | } | |||
3786 | ||||
3787 | /// handleModeAttr - This attribute modifies the width of a decl with primitive | |||
3788 | /// type. | |||
3789 | /// | |||
3790 | /// Despite what would be logical, the mode attribute is a decl attribute, not a | |||
3791 | /// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be | |||
3792 | /// HImode, not an intermediate pointer. | |||
3793 | static void handleModeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
3794 | // This attribute isn't documented, but glibc uses it. It changes | |||
3795 | // the width of an int or unsigned int to the specified size. | |||
3796 | if (!AL.isArgIdent(0)) { | |||
3797 | S.Diag(AL.getLoc(), diag::err_attribute_argument_type) << AL.getName() | |||
3798 | << AANT_ArgumentIdentifier; | |||
3799 | return; | |||
3800 | } | |||
3801 | ||||
3802 | IdentifierInfo *Name = AL.getArgAsIdent(0)->Ident; | |||
3803 | ||||
3804 | S.AddModeAttr(AL.getRange(), D, Name, AL.getAttributeSpellingListIndex()); | |||
3805 | } | |||
3806 | ||||
3807 | void Sema::AddModeAttr(SourceRange AttrRange, Decl *D, IdentifierInfo *Name, | |||
3808 | unsigned SpellingListIndex, bool InInstantiation) { | |||
3809 | StringRef Str = Name->getName(); | |||
3810 | normalizeName(Str); | |||
3811 | SourceLocation AttrLoc = AttrRange.getBegin(); | |||
3812 | ||||
3813 | unsigned DestWidth = 0; | |||
3814 | bool IntegerMode = true; | |||
3815 | bool ComplexMode = false; | |||
3816 | llvm::APInt VectorSize(64, 0); | |||
3817 | if (Str.size() >= 4 && Str[0] == 'V') { | |||
3818 | // Minimal length of vector mode is 4: 'V' + NUMBER(>=1) + TYPE(>=2). | |||
3819 | size_t StrSize = Str.size(); | |||
3820 | size_t VectorStringLength = 0; | |||
3821 | while ((VectorStringLength + 1) < StrSize && | |||
3822 | isdigit(Str[VectorStringLength + 1])) | |||
3823 | ++VectorStringLength; | |||
3824 | if (VectorStringLength && | |||
3825 | !Str.substr(1, VectorStringLength).getAsInteger(10, VectorSize) && | |||
3826 | VectorSize.isPowerOf2()) { | |||
3827 | parseModeAttrArg(*this, Str.substr(VectorStringLength + 1), DestWidth, | |||
3828 | IntegerMode, ComplexMode); | |||
3829 | // Avoid duplicate warning from template instantiation. | |||
3830 | if (!InInstantiation) | |||
3831 | Diag(AttrLoc, diag::warn_vector_mode_deprecated); | |||
3832 | } else { | |||
3833 | VectorSize = 0; | |||
3834 | } | |||
3835 | } | |||
3836 | ||||
3837 | if (!VectorSize) | |||
3838 | parseModeAttrArg(*this, Str, DestWidth, IntegerMode, ComplexMode); | |||
3839 | ||||
3840 | // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t | |||
3841 | // and friends, at least with glibc. | |||
3842 | // FIXME: Make sure floating-point mappings are accurate | |||
3843 | // FIXME: Support XF and TF types | |||
3844 | if (!DestWidth) { | |||
3845 | Diag(AttrLoc, diag::err_machine_mode) << 0 /*Unknown*/ << Name; | |||
3846 | return; | |||
3847 | } | |||
3848 | ||||
3849 | QualType OldTy; | |||
3850 | if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) | |||
3851 | OldTy = TD->getUnderlyingType(); | |||
3852 | else if (const auto *ED = dyn_cast<EnumDecl>(D)) { | |||
3853 | // Something like 'typedef enum { X } __attribute__((mode(XX))) T;'. | |||
3854 | // Try to get type from enum declaration, default to int. | |||
3855 | OldTy = ED->getIntegerType(); | |||
3856 | if (OldTy.isNull()) | |||
3857 | OldTy = Context.IntTy; | |||
3858 | } else | |||
3859 | OldTy = cast<ValueDecl>(D)->getType(); | |||
3860 | ||||
3861 | if (OldTy->isDependentType()) { | |||
3862 | D->addAttr(::new (Context) | |||
3863 | ModeAttr(AttrRange, Context, Name, SpellingListIndex)); | |||
3864 | return; | |||
3865 | } | |||
3866 | ||||
3867 | // Base type can also be a vector type (see PR17453). | |||
3868 | // Distinguish between base type and base element type. | |||
3869 | QualType OldElemTy = OldTy; | |||
3870 | if (const auto *VT = OldTy->getAs<VectorType>()) | |||
3871 | OldElemTy = VT->getElementType(); | |||
3872 | ||||
3873 | // GCC allows 'mode' attribute on enumeration types (even incomplete), except | |||
3874 | // for vector modes. So, 'enum X __attribute__((mode(QI)));' forms a complete | |||
3875 | // type, 'enum { A } __attribute__((mode(V4SI)))' is rejected. | |||
3876 | if ((isa<EnumDecl>(D) || OldElemTy->getAs<EnumType>()) && | |||
3877 | VectorSize.getBoolValue()) { | |||
3878 | Diag(AttrLoc, diag::err_enum_mode_vector_type) << Name << AttrRange; | |||
3879 | return; | |||
3880 | } | |||
3881 | bool IntegralOrAnyEnumType = | |||
3882 | OldElemTy->isIntegralOrEnumerationType() || OldElemTy->getAs<EnumType>(); | |||
3883 | ||||
3884 | if (!OldElemTy->getAs<BuiltinType>() && !OldElemTy->isComplexType() && | |||
3885 | !IntegralOrAnyEnumType) | |||
3886 | Diag(AttrLoc, diag::err_mode_not_primitive); | |||
3887 | else if (IntegerMode) { | |||
3888 | if (!IntegralOrAnyEnumType) | |||
3889 | Diag(AttrLoc, diag::err_mode_wrong_type); | |||
3890 | } else if (ComplexMode) { | |||
3891 | if (!OldElemTy->isComplexType()) | |||
3892 | Diag(AttrLoc, diag::err_mode_wrong_type); | |||
3893 | } else { | |||
3894 | if (!OldElemTy->isFloatingType()) | |||
3895 | Diag(AttrLoc, diag::err_mode_wrong_type); | |||
3896 | } | |||
3897 | ||||
3898 | QualType NewElemTy; | |||
3899 | ||||
3900 | if (IntegerMode) | |||
3901 | NewElemTy = Context.getIntTypeForBitwidth(DestWidth, | |||
3902 | OldElemTy->isSignedIntegerType()); | |||
3903 | else | |||
3904 | NewElemTy = Context.getRealTypeForBitwidth(DestWidth); | |||
3905 | ||||
3906 | if (NewElemTy.isNull()) { | |||
3907 | Diag(AttrLoc, diag::err_machine_mode) << 1 /*Unsupported*/ << Name; | |||
3908 | return; | |||
3909 | } | |||
3910 | ||||
3911 | if (ComplexMode) { | |||
3912 | NewElemTy = Context.getComplexType(NewElemTy); | |||
3913 | } | |||
3914 | ||||
3915 | QualType NewTy = NewElemTy; | |||
3916 | if (VectorSize.getBoolValue()) { | |||
3917 | NewTy = Context.getVectorType(NewTy, VectorSize.getZExtValue(), | |||
3918 | VectorType::GenericVector); | |||
3919 | } else if (const auto *OldVT = OldTy->getAs<VectorType>()) { | |||
3920 | // Complex machine mode does not support base vector types. | |||
3921 | if (ComplexMode) { | |||
3922 | Diag(AttrLoc, diag::err_complex_mode_vector_type); | |||
3923 | return; | |||
3924 | } | |||
3925 | unsigned NumElements = Context.getTypeSize(OldElemTy) * | |||
3926 | OldVT->getNumElements() / | |||
3927 | Context.getTypeSize(NewElemTy); | |||
3928 | NewTy = | |||
3929 | Context.getVectorType(NewElemTy, NumElements, OldVT->getVectorKind()); | |||
3930 | } | |||
3931 | ||||
3932 | if (NewTy.isNull()) { | |||
3933 | Diag(AttrLoc, diag::err_mode_wrong_type); | |||
3934 | return; | |||
3935 | } | |||
3936 | ||||
3937 | // Install the new type. | |||
3938 | if (auto *TD = dyn_cast<TypedefNameDecl>(D)) | |||
3939 | TD->setModedTypeSourceInfo(TD->getTypeSourceInfo(), NewTy); | |||
3940 | else if (auto *ED = dyn_cast<EnumDecl>(D)) | |||
3941 | ED->setIntegerType(NewTy); | |||
3942 | else | |||
3943 | cast<ValueDecl>(D)->setType(NewTy); | |||
3944 | ||||
3945 | D->addAttr(::new (Context) | |||
3946 | ModeAttr(AttrRange, Context, Name, SpellingListIndex)); | |||
3947 | } | |||
3948 | ||||
3949 | static void handleNoDebugAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
3950 | D->addAttr(::new (S.Context) | |||
3951 | NoDebugAttr(AL.getRange(), S.Context, | |||
3952 | AL.getAttributeSpellingListIndex())); | |||
3953 | } | |||
3954 | ||||
3955 | AlwaysInlineAttr *Sema::mergeAlwaysInlineAttr(Decl *D, SourceRange Range, | |||
3956 | IdentifierInfo *Ident, | |||
3957 | unsigned AttrSpellingListIndex) { | |||
3958 | if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) { | |||
3959 | Diag(Range.getBegin(), diag::warn_attribute_ignored) << Ident; | |||
3960 | Diag(Optnone->getLocation(), diag::note_conflicting_attribute); | |||
3961 | return nullptr; | |||
3962 | } | |||
3963 | ||||
3964 | if (D->hasAttr<AlwaysInlineAttr>()) | |||
3965 | return nullptr; | |||
3966 | ||||
3967 | return ::new (Context) AlwaysInlineAttr(Range, Context, | |||
3968 | AttrSpellingListIndex); | |||
3969 | } | |||
3970 | ||||
3971 | CommonAttr *Sema::mergeCommonAttr(Decl *D, SourceRange Range, | |||
3972 | IdentifierInfo *Ident, | |||
3973 | unsigned AttrSpellingListIndex) { | |||
3974 | if (checkAttrMutualExclusion<InternalLinkageAttr>(*this, D, Range, Ident)) | |||
3975 | return nullptr; | |||
3976 | ||||
3977 | return ::new (Context) CommonAttr(Range, Context, AttrSpellingListIndex); | |||
3978 | } | |||
3979 | ||||
3980 | InternalLinkageAttr * | |||
3981 | Sema::mergeInternalLinkageAttr(Decl *D, SourceRange Range, | |||
3982 | IdentifierInfo *Ident, | |||
3983 | unsigned AttrSpellingListIndex) { | |||
3984 | if (const auto *VD = dyn_cast<VarDecl>(D)) { | |||
3985 | // Attribute applies to Var but not any subclass of it (like ParmVar, | |||
3986 | // ImplicitParm or VarTemplateSpecialization). | |||
3987 | if (VD->getKind() != Decl::Var) { | |||
3988 | Diag(Range.getBegin(), diag::warn_attribute_wrong_decl_type) | |||
3989 | << Ident << (getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass | |||
3990 | : ExpectedVariableOrFunction); | |||
3991 | return nullptr; | |||
3992 | } | |||
3993 | // Attribute does not apply to non-static local variables. | |||
3994 | if (VD->hasLocalStorage()) { | |||
3995 | Diag(VD->getLocation(), diag::warn_internal_linkage_local_storage); | |||
3996 | return nullptr; | |||
3997 | } | |||
3998 | } | |||
3999 | ||||
4000 | if (checkAttrMutualExclusion<CommonAttr>(*this, D, Range, Ident)) | |||
4001 | return nullptr; | |||
4002 | ||||
4003 | return ::new (Context) | |||
4004 | InternalLinkageAttr(Range, Context, AttrSpellingListIndex); | |||
4005 | } | |||
4006 | ||||
4007 | MinSizeAttr *Sema::mergeMinSizeAttr(Decl *D, SourceRange Range, | |||
4008 | unsigned AttrSpellingListIndex) { | |||
4009 | if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) { | |||
4010 | Diag(Range.getBegin(), diag::warn_attribute_ignored) << "'minsize'"; | |||
4011 | Diag(Optnone->getLocation(), diag::note_conflicting_attribute); | |||
4012 | return nullptr; | |||
4013 | } | |||
4014 | ||||
4015 | if (D->hasAttr<MinSizeAttr>()) | |||
4016 | return nullptr; | |||
4017 | ||||
4018 | return ::new (Context) MinSizeAttr(Range, Context, AttrSpellingListIndex); | |||
4019 | } | |||
4020 | ||||
4021 | OptimizeNoneAttr *Sema::mergeOptimizeNoneAttr(Decl *D, SourceRange Range, | |||
4022 | unsigned AttrSpellingListIndex) { | |||
4023 | if (AlwaysInlineAttr *Inline = D->getAttr<AlwaysInlineAttr>()) { | |||
4024 | Diag(Inline->getLocation(), diag::warn_attribute_ignored) << Inline; | |||
4025 | Diag(Range.getBegin(), diag::note_conflicting_attribute); | |||
4026 | D->dropAttr<AlwaysInlineAttr>(); | |||
4027 | } | |||
4028 | if (MinSizeAttr *MinSize = D->getAttr<MinSizeAttr>()) { | |||
4029 | Diag(MinSize->getLocation(), diag::warn_attribute_ignored) << MinSize; | |||
4030 | Diag(Range.getBegin(), diag::note_conflicting_attribute); | |||
4031 | D->dropAttr<MinSizeAttr>(); | |||
4032 | } | |||
4033 | ||||
4034 | if (D->hasAttr<OptimizeNoneAttr>()) | |||
4035 | return nullptr; | |||
4036 | ||||
4037 | return ::new (Context) OptimizeNoneAttr(Range, Context, | |||
4038 | AttrSpellingListIndex); | |||
4039 | } | |||
4040 | ||||
4041 | static void handleAlwaysInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
4042 | if (checkAttrMutualExclusion<NotTailCalledAttr>(S, D, AL.getRange(), | |||
4043 | AL.getName())) | |||
4044 | return; | |||
4045 | ||||
4046 | if (AlwaysInlineAttr *Inline = S.mergeAlwaysInlineAttr( | |||
4047 | D, AL.getRange(), AL.getName(), | |||
4048 | AL.getAttributeSpellingListIndex())) | |||
4049 | D->addAttr(Inline); | |||
4050 | } | |||
4051 | ||||
4052 | static void handleMinSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
4053 | if (MinSizeAttr *MinSize = S.mergeMinSizeAttr( | |||
4054 | D, AL.getRange(), AL.getAttributeSpellingListIndex())) | |||
4055 | D->addAttr(MinSize); | |||
4056 | } | |||
4057 | ||||
4058 | static void handleOptimizeNoneAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
4059 | if (OptimizeNoneAttr *Optnone = S.mergeOptimizeNoneAttr( | |||
4060 | D, AL.getRange(), AL.getAttributeSpellingListIndex())) | |||
4061 | D->addAttr(Optnone); | |||
4062 | } | |||
4063 | ||||
4064 | static void handleConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
4065 | if (checkAttrMutualExclusion<CUDASharedAttr>(S, D, AL.getRange(), | |||
4066 | AL.getName())) | |||
4067 | return; | |||
4068 | const auto *VD = cast<VarDecl>(D); | |||
4069 | if (!VD->hasGlobalStorage()) { | |||
4070 | S.Diag(AL.getLoc(), diag::err_cuda_nonglobal_constant); | |||
4071 | return; | |||
4072 | } | |||
4073 | D->addAttr(::new (S.Context) CUDAConstantAttr( | |||
4074 | AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); | |||
4075 | } | |||
4076 | ||||
4077 | static void handleSharedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
4078 | if (checkAttrMutualExclusion<CUDAConstantAttr>(S, D, AL.getRange(), | |||
4079 | AL.getName())) | |||
4080 | return; | |||
4081 | const auto *VD = cast<VarDecl>(D); | |||
4082 | // extern __shared__ is only allowed on arrays with no length (e.g. | |||
4083 | // "int x[]"). | |||
4084 | if (!S.getLangOpts().CUDARelocatableDeviceCode && VD->hasExternalStorage() && | |||
4085 | !isa<IncompleteArrayType>(VD->getType())) { | |||
4086 | S.Diag(AL.getLoc(), diag::err_cuda_extern_shared) << VD; | |||
4087 | return; | |||
4088 | } | |||
4089 | if (S.getLangOpts().CUDA && VD->hasLocalStorage() && | |||
4090 | S.CUDADiagIfHostCode(AL.getLoc(), diag::err_cuda_host_shared) | |||
4091 | << S.CurrentCUDATarget()) | |||
4092 | return; | |||
4093 | D->addAttr(::new (S.Context) CUDASharedAttr( | |||
4094 | AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); | |||
4095 | } | |||
4096 | ||||
4097 | static void handleGlobalAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
4098 | if (checkAttrMutualExclusion<CUDADeviceAttr>(S, D, AL.getRange(), | |||
4099 | AL.getName()) || | |||
4100 | checkAttrMutualExclusion<CUDAHostAttr>(S, D, AL.getRange(), | |||
4101 | AL.getName())) { | |||
4102 | return; | |||
4103 | } | |||
4104 | const auto *FD = cast<FunctionDecl>(D); | |||
4105 | if (!FD->getReturnType()->isVoidType()) { | |||
4106 | SourceRange RTRange = FD->getReturnTypeSourceRange(); | |||
4107 | S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) | |||
4108 | << FD->getType() | |||
4109 | << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void") | |||
4110 | : FixItHint()); | |||
4111 | return; | |||
4112 | } | |||
4113 | if (const auto *Method = dyn_cast<CXXMethodDecl>(FD)) { | |||
4114 | if (Method->isInstance()) { | |||
4115 | S.Diag(Method->getLocStart(), diag::err_kern_is_nonstatic_method) | |||
4116 | << Method; | |||
4117 | return; | |||
4118 | } | |||
4119 | S.Diag(Method->getLocStart(), diag::warn_kern_is_method) << Method; | |||
4120 | } | |||
4121 | // Only warn for "inline" when compiling for host, to cut down on noise. | |||
4122 | if (FD->isInlineSpecified() && !S.getLangOpts().CUDAIsDevice) | |||
4123 | S.Diag(FD->getLocStart(), diag::warn_kern_is_inline) << FD; | |||
4124 | ||||
4125 | D->addAttr(::new (S.Context) | |||
4126 | CUDAGlobalAttr(AL.getRange(), S.Context, | |||
4127 | AL.getAttributeSpellingListIndex())); | |||
4128 | } | |||
4129 | ||||
4130 | static void handleGNUInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
4131 | const auto *Fn = cast<FunctionDecl>(D); | |||
4132 | if (!Fn->isInlineSpecified()) { | |||
4133 | S.Diag(AL.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); | |||
4134 | return; | |||
4135 | } | |||
4136 | ||||
4137 | D->addAttr(::new (S.Context) | |||
4138 | GNUInlineAttr(AL.getRange(), S.Context, | |||
4139 | AL.getAttributeSpellingListIndex())); | |||
4140 | } | |||
4141 | ||||
4142 | static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
4143 | if (hasDeclarator(D)) return; | |||
4144 | ||||
4145 | // Diagnostic is emitted elsewhere: here we store the (valid) AL | |||
4146 | // in the Decl node for syntactic reasoning, e.g., pretty-printing. | |||
4147 | CallingConv CC; | |||
4148 | if (S.CheckCallingConvAttr(AL, CC, /*FD*/nullptr)) | |||
4149 | return; | |||
4150 | ||||
4151 | if (!isa<ObjCMethodDecl>(D)) { | |||
4152 | S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) | |||
4153 | << AL.getName() << ExpectedFunctionOrMethod; | |||
4154 | return; | |||
4155 | } | |||
4156 | ||||
4157 | switch (AL.getKind()) { | |||
4158 | case ParsedAttr::AT_FastCall: | |||
4159 | D->addAttr(::new (S.Context) | |||
4160 | FastCallAttr(AL.getRange(), S.Context, | |||
4161 | AL.getAttributeSpellingListIndex())); | |||
4162 | return; | |||
4163 | case ParsedAttr::AT_StdCall: | |||
4164 | D->addAttr(::new (S.Context) | |||
4165 | StdCallAttr(AL.getRange(), S.Context, | |||
4166 | AL.getAttributeSpellingListIndex())); | |||
4167 | return; | |||
4168 | case ParsedAttr::AT_ThisCall: | |||
4169 | D->addAttr(::new (S.Context) | |||
4170 | ThisCallAttr(AL.getRange(), S.Context, | |||
4171 | AL.getAttributeSpellingListIndex())); | |||
4172 | return; | |||
4173 | case ParsedAttr::AT_CDecl: | |||
4174 | D->addAttr(::new (S.Context) | |||
4175 | CDeclAttr(AL.getRange(), S.Context, | |||
4176 | AL.getAttributeSpellingListIndex())); | |||
4177 | return; | |||
4178 | case ParsedAttr::AT_Pascal: | |||
4179 | D->addAttr(::new (S.Context) | |||
4180 | PascalAttr(AL.getRange(), S.Context, | |||
4181 | AL.getAttributeSpellingListIndex())); | |||
4182 | return; | |||
4183 | case ParsedAttr::AT_SwiftCall: | |||
4184 | D->addAttr(::new (S.Context) | |||
4185 | SwiftCallAttr(AL.getRange(), S.Context, | |||
4186 | AL.getAttributeSpellingListIndex())); | |||
4187 | return; | |||
4188 | case ParsedAttr::AT_VectorCall: | |||
4189 | D->addAttr(::new (S.Context) | |||
4190 | VectorCallAttr(AL.getRange(), S.Context, | |||
4191 | AL.getAttributeSpellingListIndex())); | |||
4192 | return; | |||
4193 | case ParsedAttr::AT_MSABI: | |||
4194 | D->addAttr(::new (S.Context) | |||
4195 | MSABIAttr(AL.getRange(), S.Context, | |||
4196 | AL.getAttributeSpellingListIndex())); | |||
4197 | return; | |||
4198 | case ParsedAttr::AT_SysVABI: | |||
4199 | D->addAttr(::new (S.Context) | |||
4200 | SysVABIAttr(AL.getRange(), S.Context, | |||
4201 | AL.getAttributeSpellingListIndex())); | |||
4202 | return; | |||
4203 | case ParsedAttr::AT_RegCall: | |||
4204 | D->addAttr(::new (S.Context) RegCallAttr( | |||
4205 | AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); | |||
4206 | return; | |||
4207 | case ParsedAttr::AT_Pcs: { | |||
4208 | PcsAttr::PCSType PCS; | |||
4209 | switch (CC) { | |||
4210 | case CC_AAPCS: | |||
4211 | PCS = PcsAttr::AAPCS; | |||
4212 | break; | |||
4213 | case CC_AAPCS_VFP: | |||
4214 | PCS = PcsAttr::AAPCS_VFP; | |||
4215 | break; | |||
4216 | default: | |||
4217 | llvm_unreachable("unexpected calling convention in pcs attribute")::llvm::llvm_unreachable_internal("unexpected calling convention in pcs attribute" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 4217); | |||
4218 | } | |||
4219 | ||||
4220 | D->addAttr(::new (S.Context) | |||
4221 | PcsAttr(AL.getRange(), S.Context, PCS, | |||
4222 | AL.getAttributeSpellingListIndex())); | |||
4223 | return; | |||
4224 | } | |||
4225 | case ParsedAttr::AT_IntelOclBicc: | |||
4226 | D->addAttr(::new (S.Context) | |||
4227 | IntelOclBiccAttr(AL.getRange(), S.Context, | |||
4228 | AL.getAttributeSpellingListIndex())); | |||
4229 | return; | |||
4230 | case ParsedAttr::AT_PreserveMost: | |||
4231 | D->addAttr(::new (S.Context) PreserveMostAttr( | |||
4232 | AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); | |||
4233 | return; | |||
4234 | case ParsedAttr::AT_PreserveAll: | |||
4235 | D->addAttr(::new (S.Context) PreserveAllAttr( | |||
4236 | AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); | |||
4237 | return; | |||
4238 | default: | |||
4239 | llvm_unreachable("unexpected attribute kind")::llvm::llvm_unreachable_internal("unexpected attribute kind" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 4239); | |||
4240 | } | |||
4241 | } | |||
4242 | ||||
4243 | static void handleSuppressAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
4244 | if (!checkAttributeAtLeastNumArgs(S, AL, 1)) | |||
4245 | return; | |||
4246 | ||||
4247 | std::vector<StringRef> DiagnosticIdentifiers; | |||
4248 | for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) { | |||
4249 | StringRef RuleName; | |||
4250 | ||||
4251 | if (!S.checkStringLiteralArgumentAttr(AL, I, RuleName, nullptr)) | |||
4252 | return; | |||
4253 | ||||
4254 | // FIXME: Warn if the rule name is unknown. This is tricky because only | |||
4255 | // clang-tidy knows about available rules. | |||
4256 | DiagnosticIdentifiers.push_back(RuleName); | |||
4257 | } | |||
4258 | D->addAttr(::new (S.Context) SuppressAttr( | |||
4259 | AL.getRange(), S.Context, DiagnosticIdentifiers.data(), | |||
4260 | DiagnosticIdentifiers.size(), AL.getAttributeSpellingListIndex())); | |||
4261 | } | |||
4262 | ||||
4263 | bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC, | |||
4264 | const FunctionDecl *FD) { | |||
4265 | if (Attrs.isInvalid()) | |||
4266 | return true; | |||
4267 | ||||
4268 | if (Attrs.hasProcessingCache()) { | |||
4269 | CC = (CallingConv) Attrs.getProcessingCache(); | |||
4270 | return false; | |||
4271 | } | |||
4272 | ||||
4273 | unsigned ReqArgs = Attrs.getKind() == ParsedAttr::AT_Pcs ? 1 : 0; | |||
4274 | if (!checkAttributeNumArgs(*this, Attrs, ReqArgs)) { | |||
4275 | Attrs.setInvalid(); | |||
4276 | return true; | |||
4277 | } | |||
4278 | ||||
4279 | // TODO: diagnose uses of these conventions on the wrong target. | |||
4280 | switch (Attrs.getKind()) { | |||
4281 | case ParsedAttr::AT_CDecl: | |||
4282 | CC = CC_C; | |||
4283 | break; | |||
4284 | case ParsedAttr::AT_FastCall: | |||
4285 | CC = CC_X86FastCall; | |||
4286 | break; | |||
4287 | case ParsedAttr::AT_StdCall: | |||
4288 | CC = CC_X86StdCall; | |||
4289 | break; | |||
4290 | case ParsedAttr::AT_ThisCall: | |||
4291 | CC = CC_X86ThisCall; | |||
4292 | break; | |||
4293 | case ParsedAttr::AT_Pascal: | |||
4294 | CC = CC_X86Pascal; | |||
4295 | break; | |||
4296 | case ParsedAttr::AT_SwiftCall: | |||
4297 | CC = CC_Swift; | |||
4298 | break; | |||
4299 | case ParsedAttr::AT_VectorCall: | |||
4300 | CC = CC_X86VectorCall; | |||
4301 | break; | |||
4302 | case ParsedAttr::AT_RegCall: | |||
4303 | CC = CC_X86RegCall; | |||
4304 | break; | |||
4305 | case ParsedAttr::AT_MSABI: | |||
4306 | CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C : | |||
4307 | CC_Win64; | |||
4308 | break; | |||
4309 | case ParsedAttr::AT_SysVABI: | |||
4310 | CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_X86_64SysV : | |||
4311 | CC_C; | |||
4312 | break; | |||
4313 | case ParsedAttr::AT_Pcs: { | |||
4314 | StringRef StrRef; | |||
4315 | if (!checkStringLiteralArgumentAttr(Attrs, 0, StrRef)) { | |||
4316 | Attrs.setInvalid(); | |||
4317 | return true; | |||
4318 | } | |||
4319 | if (StrRef == "aapcs") { | |||
4320 | CC = CC_AAPCS; | |||
4321 | break; | |||
4322 | } else if (StrRef == "aapcs-vfp") { | |||
4323 | CC = CC_AAPCS_VFP; | |||
4324 | break; | |||
4325 | } | |||
4326 | ||||
4327 | Attrs.setInvalid(); | |||
4328 | Diag(Attrs.getLoc(), diag::err_invalid_pcs); | |||
4329 | return true; | |||
4330 | } | |||
4331 | case ParsedAttr::AT_IntelOclBicc: | |||
4332 | CC = CC_IntelOclBicc; | |||
4333 | break; | |||
4334 | case ParsedAttr::AT_PreserveMost: | |||
4335 | CC = CC_PreserveMost; | |||
4336 | break; | |||
4337 | case ParsedAttr::AT_PreserveAll: | |||
4338 | CC = CC_PreserveAll; | |||
4339 | break; | |||
4340 | default: llvm_unreachable("unexpected attribute kind")::llvm::llvm_unreachable_internal("unexpected attribute kind" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 4340); | |||
4341 | } | |||
4342 | ||||
4343 | const TargetInfo &TI = Context.getTargetInfo(); | |||
4344 | TargetInfo::CallingConvCheckResult A = TI.checkCallingConvention(CC); | |||
4345 | if (A != TargetInfo::CCCR_OK) { | |||
4346 | if (A == TargetInfo::CCCR_Warning) | |||
4347 | Diag(Attrs.getLoc(), diag::warn_cconv_ignored) << Attrs.getName(); | |||
4348 | ||||
4349 | // This convention is not valid for the target. Use the default function or | |||
4350 | // method calling convention. | |||
4351 | bool IsCXXMethod = false, IsVariadic = false; | |||
4352 | if (FD) { | |||
4353 | IsCXXMethod = FD->isCXXInstanceMember(); | |||
4354 | IsVariadic = FD->isVariadic(); | |||
4355 | } | |||
4356 | CC = Context.getDefaultCallingConvention(IsVariadic, IsCXXMethod); | |||
4357 | } | |||
4358 | ||||
4359 | Attrs.setProcessingCache((unsigned) CC); | |||
4360 | return false; | |||
4361 | } | |||
4362 | ||||
4363 | /// Pointer-like types in the default address space. | |||
4364 | static bool isValidSwiftContextType(QualType Ty) { | |||
4365 | if (!Ty->hasPointerRepresentation()) | |||
4366 | return Ty->isDependentType(); | |||
4367 | return Ty->getPointeeType().getAddressSpace() == LangAS::Default; | |||
4368 | } | |||
4369 | ||||
4370 | /// Pointers and references in the default address space. | |||
4371 | static bool isValidSwiftIndirectResultType(QualType Ty) { | |||
4372 | if (const auto *PtrType = Ty->getAs<PointerType>()) { | |||
4373 | Ty = PtrType->getPointeeType(); | |||
4374 | } else if (const auto *RefType = Ty->getAs<ReferenceType>()) { | |||
4375 | Ty = RefType->getPointeeType(); | |||
4376 | } else { | |||
4377 | return Ty->isDependentType(); | |||
4378 | } | |||
4379 | return Ty.getAddressSpace() == LangAS::Default; | |||
4380 | } | |||
4381 | ||||
4382 | /// Pointers and references to pointers in the default address space. | |||
4383 | static bool isValidSwiftErrorResultType(QualType Ty) { | |||
4384 | if (const auto *PtrType = Ty->getAs<PointerType>()) { | |||
4385 | Ty = PtrType->getPointeeType(); | |||
4386 | } else if (const auto *RefType = Ty->getAs<ReferenceType>()) { | |||
4387 | Ty = RefType->getPointeeType(); | |||
4388 | } else { | |||
4389 | return Ty->isDependentType(); | |||
4390 | } | |||
4391 | if (!Ty.getQualifiers().empty()) | |||
4392 | return false; | |||
4393 | return isValidSwiftContextType(Ty); | |||
4394 | } | |||
4395 | ||||
4396 | static void handleParameterABIAttr(Sema &S, Decl *D, const ParsedAttr &Attrs, | |||
4397 | ParameterABI Abi) { | |||
4398 | S.AddParameterABIAttr(Attrs.getRange(), D, Abi, | |||
4399 | Attrs.getAttributeSpellingListIndex()); | |||
4400 | } | |||
4401 | ||||
4402 | void Sema::AddParameterABIAttr(SourceRange range, Decl *D, ParameterABI abi, | |||
4403 | unsigned spellingIndex) { | |||
4404 | ||||
4405 | QualType type = cast<ParmVarDecl>(D)->getType(); | |||
4406 | ||||
4407 | if (auto existingAttr = D->getAttr<ParameterABIAttr>()) { | |||
4408 | if (existingAttr->getABI() != abi) { | |||
4409 | Diag(range.getBegin(), diag::err_attributes_are_not_compatible) | |||
4410 | << getParameterABISpelling(abi) << existingAttr; | |||
4411 | Diag(existingAttr->getLocation(), diag::note_conflicting_attribute); | |||
4412 | return; | |||
4413 | } | |||
4414 | } | |||
4415 | ||||
4416 | switch (abi) { | |||
4417 | case ParameterABI::Ordinary: | |||
4418 | llvm_unreachable("explicit attribute for ordinary parameter ABI?")::llvm::llvm_unreachable_internal("explicit attribute for ordinary parameter ABI?" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 4418); | |||
4419 | ||||
4420 | case ParameterABI::SwiftContext: | |||
4421 | if (!isValidSwiftContextType(type)) { | |||
4422 | Diag(range.getBegin(), diag::err_swift_abi_parameter_wrong_type) | |||
4423 | << getParameterABISpelling(abi) | |||
4424 | << /*pointer to pointer */ 0 << type; | |||
4425 | } | |||
4426 | D->addAttr(::new (Context) | |||
4427 | SwiftContextAttr(range, Context, spellingIndex)); | |||
4428 | return; | |||
4429 | ||||
4430 | case ParameterABI::SwiftErrorResult: | |||
4431 | if (!isValidSwiftErrorResultType(type)) { | |||
4432 | Diag(range.getBegin(), diag::err_swift_abi_parameter_wrong_type) | |||
4433 | << getParameterABISpelling(abi) | |||
4434 | << /*pointer to pointer */ 1 << type; | |||
4435 | } | |||
4436 | D->addAttr(::new (Context) | |||
4437 | SwiftErrorResultAttr(range, Context, spellingIndex)); | |||
4438 | return; | |||
4439 | ||||
4440 | case ParameterABI::SwiftIndirectResult: | |||
4441 | if (!isValidSwiftIndirectResultType(type)) { | |||
4442 | Diag(range.getBegin(), diag::err_swift_abi_parameter_wrong_type) | |||
4443 | << getParameterABISpelling(abi) | |||
4444 | << /*pointer*/ 0 << type; | |||
4445 | } | |||
4446 | D->addAttr(::new (Context) | |||
4447 | SwiftIndirectResultAttr(range, Context, spellingIndex)); | |||
4448 | return; | |||
4449 | } | |||
4450 | llvm_unreachable("bad parameter ABI attribute")::llvm::llvm_unreachable_internal("bad parameter ABI attribute" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 4450); | |||
4451 | } | |||
4452 | ||||
4453 | /// Checks a regparm attribute, returning true if it is ill-formed and | |||
4454 | /// otherwise setting numParams to the appropriate value. | |||
4455 | bool Sema::CheckRegparmAttr(const ParsedAttr &AL, unsigned &numParams) { | |||
4456 | if (AL.isInvalid()) | |||
4457 | return true; | |||
4458 | ||||
4459 | if (!checkAttributeNumArgs(*this, AL, 1)) { | |||
4460 | AL.setInvalid(); | |||
4461 | return true; | |||
4462 | } | |||
4463 | ||||
4464 | uint32_t NP; | |||
4465 | Expr *NumParamsExpr = AL.getArgAsExpr(0); | |||
4466 | if (!checkUInt32Argument(*this, AL, NumParamsExpr, NP)) { | |||
4467 | AL.setInvalid(); | |||
4468 | return true; | |||
4469 | } | |||
4470 | ||||
4471 | if (Context.getTargetInfo().getRegParmMax() == 0) { | |||
4472 | Diag(AL.getLoc(), diag::err_attribute_regparm_wrong_platform) | |||
4473 | << NumParamsExpr->getSourceRange(); | |||
4474 | AL.setInvalid(); | |||
4475 | return true; | |||
4476 | } | |||
4477 | ||||
4478 | numParams = NP; | |||
4479 | if (numParams > Context.getTargetInfo().getRegParmMax()) { | |||
4480 | Diag(AL.getLoc(), diag::err_attribute_regparm_invalid_number) | |||
4481 | << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange(); | |||
4482 | AL.setInvalid(); | |||
4483 | return true; | |||
4484 | } | |||
4485 | ||||
4486 | return false; | |||
4487 | } | |||
4488 | ||||
4489 | // Checks whether an argument of launch_bounds attribute is | |||
4490 | // acceptable, performs implicit conversion to Rvalue, and returns | |||
4491 | // non-nullptr Expr result on success. Otherwise, it returns nullptr | |||
4492 | // and may output an error. | |||
4493 | static Expr *makeLaunchBoundsArgExpr(Sema &S, Expr *E, | |||
4494 | const CUDALaunchBoundsAttr &AL, | |||
4495 | const unsigned Idx) { | |||
4496 | if (S.DiagnoseUnexpandedParameterPack(E)) | |||
4497 | return nullptr; | |||
4498 | ||||
4499 | // Accept template arguments for now as they depend on something else. | |||
4500 | // We'll get to check them when they eventually get instantiated. | |||
4501 | if (E->isValueDependent()) | |||
4502 | return E; | |||
4503 | ||||
4504 | llvm::APSInt I(64); | |||
4505 | if (!E->isIntegerConstantExpr(I, S.Context)) { | |||
4506 | S.Diag(E->getExprLoc(), diag::err_attribute_argument_n_type) | |||
4507 | << &AL << Idx << AANT_ArgumentIntegerConstant << E->getSourceRange(); | |||
4508 | return nullptr; | |||
4509 | } | |||
4510 | // Make sure we can fit it in 32 bits. | |||
4511 | if (!I.isIntN(32)) { | |||
4512 | S.Diag(E->getExprLoc(), diag::err_ice_too_large) << I.toString(10, false) | |||
4513 | << 32 << /* Unsigned */ 1; | |||
4514 | return nullptr; | |||
4515 | } | |||
4516 | if (I < 0) | |||
4517 | S.Diag(E->getExprLoc(), diag::warn_attribute_argument_n_negative) | |||
4518 | << &AL << Idx << E->getSourceRange(); | |||
4519 | ||||
4520 | // We may need to perform implicit conversion of the argument. | |||
4521 | InitializedEntity Entity = InitializedEntity::InitializeParameter( | |||
4522 | S.Context, S.Context.getConstType(S.Context.IntTy), /*consume*/ false); | |||
4523 | ExprResult ValArg = S.PerformCopyInitialization(Entity, SourceLocation(), E); | |||
4524 | assert(!ValArg.isInvalid() &&(static_cast <bool> (!ValArg.isInvalid() && "Unexpected PerformCopyInitialization() failure." ) ? void (0) : __assert_fail ("!ValArg.isInvalid() && \"Unexpected PerformCopyInitialization() failure.\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 4525, __extension__ __PRETTY_FUNCTION__)) | |||
4525 | "Unexpected PerformCopyInitialization() failure.")(static_cast <bool> (!ValArg.isInvalid() && "Unexpected PerformCopyInitialization() failure." ) ? void (0) : __assert_fail ("!ValArg.isInvalid() && \"Unexpected PerformCopyInitialization() failure.\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 4525, __extension__ __PRETTY_FUNCTION__)); | |||
4526 | ||||
4527 | return ValArg.getAs<Expr>(); | |||
4528 | } | |||
4529 | ||||
4530 | void Sema::AddLaunchBoundsAttr(SourceRange AttrRange, Decl *D, Expr *MaxThreads, | |||
4531 | Expr *MinBlocks, unsigned SpellingListIndex) { | |||
4532 | CUDALaunchBoundsAttr TmpAttr(AttrRange, Context, MaxThreads, MinBlocks, | |||
4533 | SpellingListIndex); | |||
4534 | MaxThreads = makeLaunchBoundsArgExpr(*this, MaxThreads, TmpAttr, 0); | |||
4535 | if (MaxThreads == nullptr) | |||
4536 | return; | |||
4537 | ||||
4538 | if (MinBlocks) { | |||
4539 | MinBlocks = makeLaunchBoundsArgExpr(*this, MinBlocks, TmpAttr, 1); | |||
4540 | if (MinBlocks == nullptr) | |||
4541 | return; | |||
4542 | } | |||
4543 | ||||
4544 | D->addAttr(::new (Context) CUDALaunchBoundsAttr( | |||
4545 | AttrRange, Context, MaxThreads, MinBlocks, SpellingListIndex)); | |||
4546 | } | |||
4547 | ||||
4548 | static void handleLaunchBoundsAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
4549 | if (!checkAttributeAtLeastNumArgs(S, AL, 1) || | |||
4550 | !checkAttributeAtMostNumArgs(S, AL, 2)) | |||
4551 | return; | |||
4552 | ||||
4553 | S.AddLaunchBoundsAttr(AL.getRange(), D, AL.getArgAsExpr(0), | |||
4554 | AL.getNumArgs() > 1 ? AL.getArgAsExpr(1) : nullptr, | |||
4555 | AL.getAttributeSpellingListIndex()); | |||
4556 | } | |||
4557 | ||||
4558 | static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D, | |||
4559 | const ParsedAttr &AL) { | |||
4560 | if (!AL.isArgIdent(0)) { | |||
4561 | S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type) | |||
4562 | << AL.getName() << /* arg num = */ 1 << AANT_ArgumentIdentifier; | |||
4563 | return; | |||
4564 | } | |||
4565 | ||||
4566 | ParamIdx ArgumentIdx; | |||
4567 | if (!checkFunctionOrMethodParameterIndex(S, D, AL, 2, AL.getArgAsExpr(1), | |||
4568 | ArgumentIdx)) | |||
4569 | return; | |||
4570 | ||||
4571 | ParamIdx TypeTagIdx; | |||
4572 | if (!checkFunctionOrMethodParameterIndex(S, D, AL, 3, AL.getArgAsExpr(2), | |||
4573 | TypeTagIdx)) | |||
4574 | return; | |||
4575 | ||||
4576 | bool IsPointer = AL.getName()->getName() == "pointer_with_type_tag"; | |||
4577 | if (IsPointer) { | |||
4578 | // Ensure that buffer has a pointer type. | |||
4579 | unsigned ArgumentIdxAST = ArgumentIdx.getASTIndex(); | |||
4580 | if (ArgumentIdxAST >= getFunctionOrMethodNumParams(D) || | |||
4581 | !getFunctionOrMethodParamType(D, ArgumentIdxAST)->isPointerType()) | |||
4582 | S.Diag(AL.getLoc(), diag::err_attribute_pointers_only) | |||
4583 | << AL.getName() << 0; | |||
4584 | } | |||
4585 | ||||
4586 | D->addAttr(::new (S.Context) ArgumentWithTypeTagAttr( | |||
4587 | AL.getRange(), S.Context, AL.getArgAsIdent(0)->Ident, ArgumentIdx, | |||
4588 | TypeTagIdx, IsPointer, AL.getAttributeSpellingListIndex())); | |||
4589 | } | |||
4590 | ||||
4591 | static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D, | |||
4592 | const ParsedAttr &AL) { | |||
4593 | if (!AL.isArgIdent(0)) { | |||
4594 | S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type) | |||
4595 | << AL.getName() << 1 << AANT_ArgumentIdentifier; | |||
4596 | return; | |||
4597 | } | |||
4598 | ||||
4599 | if (!checkAttributeNumArgs(S, AL, 1)) | |||
4600 | return; | |||
4601 | ||||
4602 | if (!isa<VarDecl>(D)) { | |||
4603 | S.Diag(AL.getLoc(), diag::err_attribute_wrong_decl_type) | |||
4604 | << AL.getName() << ExpectedVariable; | |||
4605 | return; | |||
4606 | } | |||
4607 | ||||
4608 | IdentifierInfo *PointerKind = AL.getArgAsIdent(0)->Ident; | |||
4609 | TypeSourceInfo *MatchingCTypeLoc = nullptr; | |||
4610 | S.GetTypeFromParser(AL.getMatchingCType(), &MatchingCTypeLoc); | |||
4611 | assert(MatchingCTypeLoc && "no type source info for attribute argument")(static_cast <bool> (MatchingCTypeLoc && "no type source info for attribute argument" ) ? void (0) : __assert_fail ("MatchingCTypeLoc && \"no type source info for attribute argument\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 4611, __extension__ __PRETTY_FUNCTION__)); | |||
4612 | ||||
4613 | D->addAttr(::new (S.Context) | |||
4614 | TypeTagForDatatypeAttr(AL.getRange(), S.Context, PointerKind, | |||
4615 | MatchingCTypeLoc, | |||
4616 | AL.getLayoutCompatible(), | |||
4617 | AL.getMustBeNull(), | |||
4618 | AL.getAttributeSpellingListIndex())); | |||
4619 | } | |||
4620 | ||||
4621 | static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
4622 | ParamIdx ArgCount; | |||
4623 | ||||
4624 | if (!checkFunctionOrMethodParameterIndex(S, D, AL, 1, AL.getArgAsExpr(0), | |||
4625 | ArgCount, | |||
4626 | true /* CanIndexImplicitThis */)) | |||
4627 | return; | |||
4628 | ||||
4629 | // ArgCount isn't a parameter index [0;n), it's a count [1;n] | |||
4630 | D->addAttr(::new (S.Context) XRayLogArgsAttr( | |||
4631 | AL.getRange(), S.Context, ArgCount.getSourceIndex(), | |||
4632 | AL.getAttributeSpellingListIndex())); | |||
4633 | } | |||
4634 | ||||
4635 | //===----------------------------------------------------------------------===// | |||
4636 | // Checker-specific attribute handlers. | |||
4637 | //===----------------------------------------------------------------------===// | |||
4638 | ||||
4639 | static bool isValidSubjectOfNSReturnsRetainedAttribute(QualType QT) { | |||
4640 | return QT->isDependentType() || QT->isObjCRetainableType(); | |||
4641 | } | |||
4642 | ||||
4643 | static bool isValidSubjectOfNSAttribute(Sema &S, QualType QT) { | |||
4644 | return QT->isDependentType() || QT->isObjCObjectPointerType() || | |||
4645 | S.Context.isObjCNSObjectType(QT); | |||
4646 | } | |||
4647 | ||||
4648 | static bool isValidSubjectOfCFAttribute(Sema &S, QualType QT) { | |||
4649 | return QT->isDependentType() || QT->isPointerType() || | |||
4650 | isValidSubjectOfNSAttribute(S, QT); | |||
4651 | } | |||
4652 | ||||
4653 | static void handleNSConsumedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
4654 | S.AddNSConsumedAttr(AL.getRange(), D, AL.getAttributeSpellingListIndex(), | |||
4655 | AL.getKind() == ParsedAttr::AT_NSConsumed, | |||
4656 | /*template instantiation*/ false); | |||
4657 | } | |||
4658 | ||||
4659 | void Sema::AddNSConsumedAttr(SourceRange AttrRange, Decl *D, | |||
4660 | unsigned SpellingIndex, bool IsNSConsumed, | |||
4661 | bool IsTemplateInstantiation) { | |||
4662 | const auto *Param = cast<ParmVarDecl>(D); | |||
4663 | bool TypeOK; | |||
4664 | ||||
4665 | if (IsNSConsumed) | |||
4666 | TypeOK = isValidSubjectOfNSAttribute(*this, Param->getType()); | |||
4667 | else | |||
4668 | TypeOK = isValidSubjectOfCFAttribute(*this, Param->getType()); | |||
4669 | ||||
4670 | if (!TypeOK) { | |||
4671 | // These attributes are normally just advisory, but in ARC, ns_consumed | |||
4672 | // is significant. Allow non-dependent code to contain inappropriate | |||
4673 | // attributes even in ARC, but require template instantiations to be | |||
4674 | // set up correctly. | |||
4675 | Diag(D->getLocStart(), (IsTemplateInstantiation && IsNSConsumed && | |||
4676 | getLangOpts().ObjCAutoRefCount | |||
4677 | ? diag::err_ns_attribute_wrong_parameter_type | |||
4678 | : diag::warn_ns_attribute_wrong_parameter_type)) | |||
4679 | << AttrRange << (IsNSConsumed ? "ns_consumed" : "cf_consumed") | |||
4680 | << (IsNSConsumed ? /*objc pointers*/ 0 : /*cf pointers*/ 1); | |||
4681 | return; | |||
4682 | } | |||
4683 | ||||
4684 | if (IsNSConsumed) | |||
4685 | D->addAttr(::new (Context) | |||
4686 | NSConsumedAttr(AttrRange, Context, SpellingIndex)); | |||
4687 | else | |||
4688 | D->addAttr(::new (Context) | |||
4689 | CFConsumedAttr(AttrRange, Context, SpellingIndex)); | |||
4690 | } | |||
4691 | ||||
4692 | bool Sema::checkNSReturnsRetainedReturnType(SourceLocation Loc, QualType QT) { | |||
4693 | if (isValidSubjectOfNSReturnsRetainedAttribute(QT)) | |||
4694 | return false; | |||
4695 | ||||
4696 | Diag(Loc, diag::warn_ns_attribute_wrong_return_type) | |||
4697 | << "'ns_returns_retained'" << 0 << 0; | |||
4698 | return true; | |||
4699 | } | |||
4700 | ||||
4701 | static void handleNSReturnsRetainedAttr(Sema &S, Decl *D, | |||
4702 | const ParsedAttr &AL) { | |||
4703 | QualType ReturnType; | |||
4704 | ||||
4705 | if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) | |||
4706 | ReturnType = MD->getReturnType(); | |||
4707 | else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) && | |||
4708 | (AL.getKind() == ParsedAttr::AT_NSReturnsRetained)) | |||
4709 | return; // ignore: was handled as a type attribute | |||
4710 | else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) | |||
4711 | ReturnType = PD->getType(); | |||
4712 | else if (const auto *FD = dyn_cast<FunctionDecl>(D)) | |||
4713 | ReturnType = FD->getReturnType(); | |||
4714 | else if (const auto *Param = dyn_cast<ParmVarDecl>(D)) { | |||
4715 | ReturnType = Param->getType()->getPointeeType(); | |||
4716 | if (ReturnType.isNull()) { | |||
4717 | S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type) | |||
4718 | << AL.getName() << /*pointer-to-CF*/2 | |||
4719 | << AL.getRange(); | |||
4720 | return; | |||
4721 | } | |||
4722 | } else if (AL.isUsedAsTypeAttr()) { | |||
4723 | return; | |||
4724 | } else { | |||
4725 | AttributeDeclKind ExpectedDeclKind; | |||
4726 | switch (AL.getKind()) { | |||
4727 | default: llvm_unreachable("invalid ownership attribute")::llvm::llvm_unreachable_internal("invalid ownership attribute" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 4727); | |||
4728 | case ParsedAttr::AT_NSReturnsRetained: | |||
4729 | case ParsedAttr::AT_NSReturnsAutoreleased: | |||
4730 | case ParsedAttr::AT_NSReturnsNotRetained: | |||
4731 | ExpectedDeclKind = ExpectedFunctionOrMethod; | |||
4732 | break; | |||
4733 | ||||
4734 | case ParsedAttr::AT_CFReturnsRetained: | |||
4735 | case ParsedAttr::AT_CFReturnsNotRetained: | |||
4736 | ExpectedDeclKind = ExpectedFunctionMethodOrParameter; | |||
4737 | break; | |||
4738 | } | |||
4739 | S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) | |||
4740 | << AL.getRange() << AL.getName() << ExpectedDeclKind; | |||
4741 | return; | |||
4742 | } | |||
4743 | ||||
4744 | bool TypeOK; | |||
4745 | bool Cf; | |||
4746 | switch (AL.getKind()) { | |||
4747 | default: llvm_unreachable("invalid ownership attribute")::llvm::llvm_unreachable_internal("invalid ownership attribute" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 4747); | |||
4748 | case ParsedAttr::AT_NSReturnsRetained: | |||
4749 | TypeOK = isValidSubjectOfNSReturnsRetainedAttribute(ReturnType); | |||
4750 | Cf = false; | |||
4751 | break; | |||
4752 | ||||
4753 | case ParsedAttr::AT_NSReturnsAutoreleased: | |||
4754 | case ParsedAttr::AT_NSReturnsNotRetained: | |||
4755 | TypeOK = isValidSubjectOfNSAttribute(S, ReturnType); | |||
4756 | Cf = false; | |||
4757 | break; | |||
4758 | ||||
4759 | case ParsedAttr::AT_CFReturnsRetained: | |||
4760 | case ParsedAttr::AT_CFReturnsNotRetained: | |||
4761 | TypeOK = isValidSubjectOfCFAttribute(S, ReturnType); | |||
4762 | Cf = true; | |||
4763 | break; | |||
4764 | } | |||
4765 | ||||
4766 | if (!TypeOK) { | |||
4767 | if (AL.isUsedAsTypeAttr()) | |||
4768 | return; | |||
4769 | ||||
4770 | if (isa<ParmVarDecl>(D)) { | |||
4771 | S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type) | |||
4772 | << AL.getName() << /*pointer-to-CF*/2 | |||
4773 | << AL.getRange(); | |||
4774 | } else { | |||
4775 | // Needs to be kept in sync with warn_ns_attribute_wrong_return_type. | |||
4776 | enum : unsigned { | |||
4777 | Function, | |||
4778 | Method, | |||
4779 | Property | |||
4780 | } SubjectKind = Function; | |||
4781 | if (isa<ObjCMethodDecl>(D)) | |||
4782 | SubjectKind = Method; | |||
4783 | else if (isa<ObjCPropertyDecl>(D)) | |||
4784 | SubjectKind = Property; | |||
4785 | S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) | |||
4786 | << AL.getName() << SubjectKind << Cf | |||
4787 | << AL.getRange(); | |||
4788 | } | |||
4789 | return; | |||
4790 | } | |||
4791 | ||||
4792 | switch (AL.getKind()) { | |||
4793 | default: | |||
4794 | llvm_unreachable("invalid ownership attribute")::llvm::llvm_unreachable_internal("invalid ownership attribute" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 4794); | |||
4795 | case ParsedAttr::AT_NSReturnsAutoreleased: | |||
4796 | D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr( | |||
4797 | AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); | |||
4798 | return; | |||
4799 | case ParsedAttr::AT_CFReturnsNotRetained: | |||
4800 | D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr( | |||
4801 | AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); | |||
4802 | return; | |||
4803 | case ParsedAttr::AT_NSReturnsNotRetained: | |||
4804 | D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr( | |||
4805 | AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); | |||
4806 | return; | |||
4807 | case ParsedAttr::AT_CFReturnsRetained: | |||
4808 | D->addAttr(::new (S.Context) CFReturnsRetainedAttr( | |||
4809 | AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); | |||
4810 | return; | |||
4811 | case ParsedAttr::AT_NSReturnsRetained: | |||
4812 | D->addAttr(::new (S.Context) NSReturnsRetainedAttr( | |||
4813 | AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); | |||
4814 | return; | |||
4815 | }; | |||
4816 | } | |||
4817 | ||||
4818 | static void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D, | |||
4819 | const ParsedAttr &Attrs) { | |||
4820 | const int EP_ObjCMethod = 1; | |||
4821 | const int EP_ObjCProperty = 2; | |||
4822 | ||||
4823 | SourceLocation loc = Attrs.getLoc(); | |||
4824 | QualType resultType; | |||
4825 | if (isa<ObjCMethodDecl>(D)) | |||
4826 | resultType = cast<ObjCMethodDecl>(D)->getReturnType(); | |||
4827 | else | |||
4828 | resultType = cast<ObjCPropertyDecl>(D)->getType(); | |||
4829 | ||||
4830 | if (!resultType->isReferenceType() && | |||
4831 | (!resultType->isPointerType() || resultType->isObjCRetainableType())) { | |||
4832 | S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) | |||
4833 | << SourceRange(loc) | |||
4834 | << Attrs.getName() | |||
4835 | << (isa<ObjCMethodDecl>(D) ? EP_ObjCMethod : EP_ObjCProperty) | |||
4836 | << /*non-retainable pointer*/ 2; | |||
4837 | ||||
4838 | // Drop the attribute. | |||
4839 | return; | |||
4840 | } | |||
4841 | ||||
4842 | D->addAttr(::new (S.Context) ObjCReturnsInnerPointerAttr( | |||
4843 | Attrs.getRange(), S.Context, Attrs.getAttributeSpellingListIndex())); | |||
4844 | } | |||
4845 | ||||
4846 | static void handleObjCRequiresSuperAttr(Sema &S, Decl *D, | |||
4847 | const ParsedAttr &Attrs) { | |||
4848 | const auto *Method = cast<ObjCMethodDecl>(D); | |||
4849 | ||||
4850 | const DeclContext *DC = Method->getDeclContext(); | |||
4851 | if (const auto *PDecl = dyn_cast_or_null<ObjCProtocolDecl>(DC)) { | |||
4852 | S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol) | |||
4853 | << Attrs.getName() << 0; | |||
4854 | S.Diag(PDecl->getLocation(), diag::note_protocol_decl); | |||
4855 | return; | |||
4856 | } | |||
4857 | if (Method->getMethodFamily() == OMF_dealloc) { | |||
4858 | S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol) | |||
4859 | << Attrs.getName() << 1; | |||
4860 | return; | |||
4861 | } | |||
4862 | ||||
4863 | D->addAttr(::new (S.Context) ObjCRequiresSuperAttr( | |||
4864 | Attrs.getRange(), S.Context, Attrs.getAttributeSpellingListIndex())); | |||
4865 | } | |||
4866 | ||||
4867 | static void handleObjCBridgeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
4868 | IdentifierLoc *Parm = AL.isArgIdent(0) ? AL.getArgAsIdent(0) : nullptr; | |||
4869 | ||||
4870 | if (!Parm) { | |||
4871 | S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << AL.getName() << 0; | |||
4872 | return; | |||
4873 | } | |||
4874 | ||||
4875 | // Typedefs only allow objc_bridge(id) and have some additional checking. | |||
4876 | if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) { | |||
4877 | if (!Parm->Ident->isStr("id")) { | |||
4878 | S.Diag(AL.getLoc(), diag::err_objc_attr_typedef_not_id) | |||
4879 | << AL.getName(); | |||
4880 | return; | |||
4881 | } | |||
4882 | ||||
4883 | // Only allow 'cv void *'. | |||
4884 | QualType T = TD->getUnderlyingType(); | |||
4885 | if (!T->isVoidPointerType()) { | |||
4886 | S.Diag(AL.getLoc(), diag::err_objc_attr_typedef_not_void_pointer); | |||
4887 | return; | |||
4888 | } | |||
4889 | } | |||
4890 | ||||
4891 | D->addAttr(::new (S.Context) | |||
4892 | ObjCBridgeAttr(AL.getRange(), S.Context, Parm->Ident, | |||
4893 | AL.getAttributeSpellingListIndex())); | |||
4894 | } | |||
4895 | ||||
4896 | static void handleObjCBridgeMutableAttr(Sema &S, Decl *D, | |||
4897 | const ParsedAttr &AL) { | |||
4898 | IdentifierLoc *Parm = AL.isArgIdent(0) ? AL.getArgAsIdent(0) : nullptr; | |||
4899 | ||||
4900 | if (!Parm) { | |||
4901 | S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << AL.getName() << 0; | |||
4902 | return; | |||
4903 | } | |||
4904 | ||||
4905 | D->addAttr(::new (S.Context) | |||
4906 | ObjCBridgeMutableAttr(AL.getRange(), S.Context, Parm->Ident, | |||
4907 | AL.getAttributeSpellingListIndex())); | |||
4908 | } | |||
4909 | ||||
4910 | static void handleObjCBridgeRelatedAttr(Sema &S, Decl *D, | |||
4911 | const ParsedAttr &AL) { | |||
4912 | IdentifierInfo *RelatedClass = | |||
4913 | AL.isArgIdent(0) ? AL.getArgAsIdent(0)->Ident : nullptr; | |||
4914 | if (!RelatedClass) { | |||
4915 | S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << AL.getName() << 0; | |||
4916 | return; | |||
4917 | } | |||
4918 | IdentifierInfo *ClassMethod = | |||
4919 | AL.getArgAsIdent(1) ? AL.getArgAsIdent(1)->Ident : nullptr; | |||
4920 | IdentifierInfo *InstanceMethod = | |||
4921 | AL.getArgAsIdent(2) ? AL.getArgAsIdent(2)->Ident : nullptr; | |||
4922 | D->addAttr(::new (S.Context) | |||
4923 | ObjCBridgeRelatedAttr(AL.getRange(), S.Context, RelatedClass, | |||
4924 | ClassMethod, InstanceMethod, | |||
4925 | AL.getAttributeSpellingListIndex())); | |||
4926 | } | |||
4927 | ||||
4928 | static void handleObjCDesignatedInitializer(Sema &S, Decl *D, | |||
4929 | const ParsedAttr &AL) { | |||
4930 | ObjCInterfaceDecl *IFace; | |||
4931 | if (auto *CatDecl = dyn_cast<ObjCCategoryDecl>(D->getDeclContext())) | |||
4932 | IFace = CatDecl->getClassInterface(); | |||
4933 | else | |||
4934 | IFace = cast<ObjCInterfaceDecl>(D->getDeclContext()); | |||
4935 | ||||
4936 | if (!IFace) | |||
4937 | return; | |||
4938 | ||||
4939 | IFace->setHasDesignatedInitializers(); | |||
4940 | D->addAttr(::new (S.Context) | |||
4941 | ObjCDesignatedInitializerAttr(AL.getRange(), S.Context, | |||
4942 | AL.getAttributeSpellingListIndex())); | |||
4943 | } | |||
4944 | ||||
4945 | static void handleObjCRuntimeName(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
4946 | StringRef MetaDataName; | |||
4947 | if (!S.checkStringLiteralArgumentAttr(AL, 0, MetaDataName)) | |||
4948 | return; | |||
4949 | D->addAttr(::new (S.Context) | |||
4950 | ObjCRuntimeNameAttr(AL.getRange(), S.Context, | |||
4951 | MetaDataName, | |||
4952 | AL.getAttributeSpellingListIndex())); | |||
4953 | } | |||
4954 | ||||
4955 | // When a user wants to use objc_boxable with a union or struct | |||
4956 | // but they don't have access to the declaration (legacy/third-party code) | |||
4957 | // then they can 'enable' this feature with a typedef: | |||
4958 | // typedef struct __attribute((objc_boxable)) legacy_struct legacy_struct; | |||
4959 | static void handleObjCBoxable(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
4960 | bool notify = false; | |||
4961 | ||||
4962 | auto *RD = dyn_cast<RecordDecl>(D); | |||
4963 | if (RD && RD->getDefinition()) { | |||
4964 | RD = RD->getDefinition(); | |||
4965 | notify = true; | |||
4966 | } | |||
4967 | ||||
4968 | if (RD) { | |||
4969 | ObjCBoxableAttr *BoxableAttr = ::new (S.Context) | |||
4970 | ObjCBoxableAttr(AL.getRange(), S.Context, | |||
4971 | AL.getAttributeSpellingListIndex()); | |||
4972 | RD->addAttr(BoxableAttr); | |||
4973 | if (notify) { | |||
4974 | // we need to notify ASTReader/ASTWriter about | |||
4975 | // modification of existing declaration | |||
4976 | if (ASTMutationListener *L = S.getASTMutationListener()) | |||
4977 | L->AddedAttributeToRecord(BoxableAttr, RD); | |||
4978 | } | |||
4979 | } | |||
4980 | } | |||
4981 | ||||
4982 | static void handleObjCOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
4983 | if (hasDeclarator(D)) return; | |||
4984 | ||||
4985 | S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) | |||
4986 | << AL.getRange() << AL.getName() << ExpectedVariable; | |||
4987 | } | |||
4988 | ||||
4989 | static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D, | |||
4990 | const ParsedAttr &AL) { | |||
4991 | const auto *VD = cast<ValueDecl>(D); | |||
4992 | QualType QT = VD->getType(); | |||
4993 | ||||
4994 | if (!QT->isDependentType() && | |||
4995 | !QT->isObjCLifetimeType()) { | |||
4996 | S.Diag(AL.getLoc(), diag::err_objc_precise_lifetime_bad_type) | |||
4997 | << QT; | |||
4998 | return; | |||
4999 | } | |||
5000 | ||||
5001 | Qualifiers::ObjCLifetime Lifetime = QT.getObjCLifetime(); | |||
5002 | ||||
5003 | // If we have no lifetime yet, check the lifetime we're presumably | |||
5004 | // going to infer. | |||
5005 | if (Lifetime == Qualifiers::OCL_None && !QT->isDependentType()) | |||
5006 | Lifetime = QT->getObjCARCImplicitLifetime(); | |||
5007 | ||||
5008 | switch (Lifetime) { | |||
5009 | case Qualifiers::OCL_None: | |||
5010 | assert(QT->isDependentType() &&(static_cast <bool> (QT->isDependentType() && "didn't infer lifetime for non-dependent type?") ? void (0) : __assert_fail ("QT->isDependentType() && \"didn't infer lifetime for non-dependent type?\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 5011, __extension__ __PRETTY_FUNCTION__)) | |||
5011 | "didn't infer lifetime for non-dependent type?")(static_cast <bool> (QT->isDependentType() && "didn't infer lifetime for non-dependent type?") ? void (0) : __assert_fail ("QT->isDependentType() && \"didn't infer lifetime for non-dependent type?\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 5011, __extension__ __PRETTY_FUNCTION__)); | |||
5012 | break; | |||
5013 | ||||
5014 | case Qualifiers::OCL_Weak: // meaningful | |||
5015 | case Qualifiers::OCL_Strong: // meaningful | |||
5016 | break; | |||
5017 | ||||
5018 | case Qualifiers::OCL_ExplicitNone: | |||
5019 | case Qualifiers::OCL_Autoreleasing: | |||
5020 | S.Diag(AL.getLoc(), diag::warn_objc_precise_lifetime_meaningless) | |||
5021 | << (Lifetime == Qualifiers::OCL_Autoreleasing); | |||
5022 | break; | |||
5023 | } | |||
5024 | ||||
5025 | D->addAttr(::new (S.Context) | |||
5026 | ObjCPreciseLifetimeAttr(AL.getRange(), S.Context, | |||
5027 | AL.getAttributeSpellingListIndex())); | |||
5028 | } | |||
5029 | ||||
5030 | //===----------------------------------------------------------------------===// | |||
5031 | // Microsoft specific attribute handlers. | |||
5032 | //===----------------------------------------------------------------------===// | |||
5033 | ||||
5034 | UuidAttr *Sema::mergeUuidAttr(Decl *D, SourceRange Range, | |||
5035 | unsigned AttrSpellingListIndex, StringRef Uuid) { | |||
5036 | if (const auto *UA = D->getAttr<UuidAttr>()) { | |||
5037 | if (UA->getGuid().equals_lower(Uuid)) | |||
5038 | return nullptr; | |||
5039 | Diag(UA->getLocation(), diag::err_mismatched_uuid); | |||
5040 | Diag(Range.getBegin(), diag::note_previous_uuid); | |||
5041 | D->dropAttr<UuidAttr>(); | |||
5042 | } | |||
5043 | ||||
5044 | return ::new (Context) UuidAttr(Range, Context, Uuid, AttrSpellingListIndex); | |||
5045 | } | |||
5046 | ||||
5047 | static void handleUuidAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5048 | if (!S.LangOpts.CPlusPlus) { | |||
5049 | S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang) | |||
5050 | << AL.getName() << AttributeLangSupport::C; | |||
5051 | return; | |||
5052 | } | |||
5053 | ||||
5054 | StringRef StrRef; | |||
5055 | SourceLocation LiteralLoc; | |||
5056 | if (!S.checkStringLiteralArgumentAttr(AL, 0, StrRef, &LiteralLoc)) | |||
5057 | return; | |||
5058 | ||||
5059 | // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or | |||
5060 | // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", normalize to the former. | |||
5061 | if (StrRef.size() == 38 && StrRef.front() == '{' && StrRef.back() == '}') | |||
5062 | StrRef = StrRef.drop_front().drop_back(); | |||
5063 | ||||
5064 | // Validate GUID length. | |||
5065 | if (StrRef.size() != 36) { | |||
5066 | S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid); | |||
5067 | return; | |||
5068 | } | |||
5069 | ||||
5070 | for (unsigned i = 0; i < 36; ++i) { | |||
5071 | if (i == 8 || i == 13 || i == 18 || i == 23) { | |||
5072 | if (StrRef[i] != '-') { | |||
5073 | S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid); | |||
5074 | return; | |||
5075 | } | |||
5076 | } else if (!isHexDigit(StrRef[i])) { | |||
5077 | S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid); | |||
5078 | return; | |||
5079 | } | |||
5080 | } | |||
5081 | ||||
5082 | // FIXME: It'd be nice to also emit a fixit removing uuid(...) (and, if it's | |||
5083 | // the only thing in the [] list, the [] too), and add an insertion of | |||
5084 | // __declspec(uuid(...)). But sadly, neither the SourceLocs of the commas | |||
5085 | // separating attributes nor of the [ and the ] are in the AST. | |||
5086 | // Cf "SourceLocations of attribute list delimiters - [[ ... , ... ]] etc" | |||
5087 | // on cfe-dev. | |||
5088 | if (AL.isMicrosoftAttribute()) // Check for [uuid(...)] spelling. | |||
5089 | S.Diag(AL.getLoc(), diag::warn_atl_uuid_deprecated); | |||
5090 | ||||
5091 | UuidAttr *UA = S.mergeUuidAttr(D, AL.getRange(), | |||
5092 | AL.getAttributeSpellingListIndex(), StrRef); | |||
5093 | if (UA) | |||
5094 | D->addAttr(UA); | |||
5095 | } | |||
5096 | ||||
5097 | static void handleMSInheritanceAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5098 | if (!S.LangOpts.CPlusPlus) { | |||
5099 | S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang) | |||
5100 | << AL.getName() << AttributeLangSupport::C; | |||
5101 | return; | |||
5102 | } | |||
5103 | MSInheritanceAttr *IA = S.mergeMSInheritanceAttr( | |||
5104 | D, AL.getRange(), /*BestCase=*/true, | |||
5105 | AL.getAttributeSpellingListIndex(), | |||
5106 | (MSInheritanceAttr::Spelling)AL.getSemanticSpelling()); | |||
5107 | if (IA) { | |||
5108 | D->addAttr(IA); | |||
5109 | S.Consumer.AssignInheritanceModel(cast<CXXRecordDecl>(D)); | |||
5110 | } | |||
5111 | } | |||
5112 | ||||
5113 | static void handleDeclspecThreadAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5114 | const auto *VD = cast<VarDecl>(D); | |||
5115 | if (!S.Context.getTargetInfo().isTLSSupported()) { | |||
5116 | S.Diag(AL.getLoc(), diag::err_thread_unsupported); | |||
5117 | return; | |||
5118 | } | |||
5119 | if (VD->getTSCSpec() != TSCS_unspecified) { | |||
5120 | S.Diag(AL.getLoc(), diag::err_declspec_thread_on_thread_variable); | |||
5121 | return; | |||
5122 | } | |||
5123 | if (VD->hasLocalStorage()) { | |||
5124 | S.Diag(AL.getLoc(), diag::err_thread_non_global) << "__declspec(thread)"; | |||
5125 | return; | |||
5126 | } | |||
5127 | D->addAttr(::new (S.Context) ThreadAttr(AL.getRange(), S.Context, | |||
5128 | AL.getAttributeSpellingListIndex())); | |||
5129 | } | |||
5130 | ||||
5131 | static void handleAbiTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5132 | SmallVector<StringRef, 4> Tags; | |||
5133 | for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) { | |||
5134 | StringRef Tag; | |||
5135 | if (!S.checkStringLiteralArgumentAttr(AL, I, Tag)) | |||
5136 | return; | |||
5137 | Tags.push_back(Tag); | |||
5138 | } | |||
5139 | ||||
5140 | if (const auto *NS = dyn_cast<NamespaceDecl>(D)) { | |||
5141 | if (!NS->isInline()) { | |||
5142 | S.Diag(AL.getLoc(), diag::warn_attr_abi_tag_namespace) << 0; | |||
5143 | return; | |||
5144 | } | |||
5145 | if (NS->isAnonymousNamespace()) { | |||
5146 | S.Diag(AL.getLoc(), diag::warn_attr_abi_tag_namespace) << 1; | |||
5147 | return; | |||
5148 | } | |||
5149 | if (AL.getNumArgs() == 0) | |||
5150 | Tags.push_back(NS->getName()); | |||
5151 | } else if (!checkAttributeAtLeastNumArgs(S, AL, 1)) | |||
5152 | return; | |||
5153 | ||||
5154 | // Store tags sorted and without duplicates. | |||
5155 | llvm::sort(Tags.begin(), Tags.end()); | |||
5156 | Tags.erase(std::unique(Tags.begin(), Tags.end()), Tags.end()); | |||
5157 | ||||
5158 | D->addAttr(::new (S.Context) | |||
5159 | AbiTagAttr(AL.getRange(), S.Context, Tags.data(), Tags.size(), | |||
5160 | AL.getAttributeSpellingListIndex())); | |||
5161 | } | |||
5162 | ||||
5163 | static void handleARMInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5164 | // Check the attribute arguments. | |||
5165 | if (AL.getNumArgs() > 1) { | |||
5166 | S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) | |||
5167 | << AL.getName() << 1; | |||
5168 | return; | |||
5169 | } | |||
5170 | ||||
5171 | StringRef Str; | |||
5172 | SourceLocation ArgLoc; | |||
5173 | ||||
5174 | if (AL.getNumArgs() == 0) | |||
5175 | Str = ""; | |||
5176 | else if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc)) | |||
5177 | return; | |||
5178 | ||||
5179 | ARMInterruptAttr::InterruptType Kind; | |||
5180 | if (!ARMInterruptAttr::ConvertStrToInterruptType(Str, Kind)) { | |||
5181 | S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) | |||
5182 | << AL.getName() << Str << ArgLoc; | |||
5183 | return; | |||
5184 | } | |||
5185 | ||||
5186 | unsigned Index = AL.getAttributeSpellingListIndex(); | |||
5187 | D->addAttr(::new (S.Context) | |||
5188 | ARMInterruptAttr(AL.getLoc(), S.Context, Kind, Index)); | |||
5189 | } | |||
5190 | ||||
5191 | static void handleMSP430InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5192 | if (!checkAttributeNumArgs(S, AL, 1)) | |||
5193 | return; | |||
5194 | ||||
5195 | if (!AL.isArgExpr(0)) { | |||
5196 | S.Diag(AL.getLoc(), diag::err_attribute_argument_type) << AL.getName() | |||
5197 | << AANT_ArgumentIntegerConstant; | |||
5198 | return; | |||
5199 | } | |||
5200 | ||||
5201 | // FIXME: Check for decl - it should be void ()(void). | |||
5202 | ||||
5203 | Expr *NumParamsExpr = static_cast<Expr *>(AL.getArgAsExpr(0)); | |||
5204 | llvm::APSInt NumParams(32); | |||
5205 | if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { | |||
5206 | S.Diag(AL.getLoc(), diag::err_attribute_argument_type) | |||
5207 | << AL.getName() << AANT_ArgumentIntegerConstant | |||
5208 | << NumParamsExpr->getSourceRange(); | |||
5209 | return; | |||
5210 | } | |||
5211 | ||||
5212 | unsigned Num = NumParams.getLimitedValue(255); | |||
5213 | if ((Num & 1) || Num > 30) { | |||
5214 | S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) | |||
5215 | << AL.getName() << (int)NumParams.getSExtValue() | |||
5216 | << NumParamsExpr->getSourceRange(); | |||
5217 | return; | |||
5218 | } | |||
5219 | ||||
5220 | D->addAttr(::new (S.Context) | |||
5221 | MSP430InterruptAttr(AL.getLoc(), S.Context, Num, | |||
5222 | AL.getAttributeSpellingListIndex())); | |||
5223 | D->addAttr(UsedAttr::CreateImplicit(S.Context)); | |||
5224 | } | |||
5225 | ||||
5226 | static void handleMipsInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5227 | // Only one optional argument permitted. | |||
5228 | if (AL.getNumArgs() > 1) { | |||
5229 | S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) | |||
5230 | << AL.getName() << 1; | |||
5231 | return; | |||
5232 | } | |||
5233 | ||||
5234 | StringRef Str; | |||
5235 | SourceLocation ArgLoc; | |||
5236 | ||||
5237 | if (AL.getNumArgs() == 0) | |||
5238 | Str = ""; | |||
5239 | else if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc)) | |||
5240 | return; | |||
5241 | ||||
5242 | // Semantic checks for a function with the 'interrupt' attribute for MIPS: | |||
5243 | // a) Must be a function. | |||
5244 | // b) Must have no parameters. | |||
5245 | // c) Must have the 'void' return type. | |||
5246 | // d) Cannot have the 'mips16' attribute, as that instruction set | |||
5247 | // lacks the 'eret' instruction. | |||
5248 | // e) The attribute itself must either have no argument or one of the | |||
5249 | // valid interrupt types, see [MipsInterruptDocs]. | |||
5250 | ||||
5251 | if (!isFunctionOrMethod(D)) { | |||
5252 | S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) | |||
5253 | << "'interrupt'" << ExpectedFunctionOrMethod; | |||
5254 | return; | |||
5255 | } | |||
5256 | ||||
5257 | if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) { | |||
5258 | S.Diag(D->getLocation(), diag::warn_mips_interrupt_attribute) | |||
5259 | << 0; | |||
5260 | return; | |||
5261 | } | |||
5262 | ||||
5263 | if (!getFunctionOrMethodResultType(D)->isVoidType()) { | |||
5264 | S.Diag(D->getLocation(), diag::warn_mips_interrupt_attribute) | |||
5265 | << 1; | |||
5266 | return; | |||
5267 | } | |||
5268 | ||||
5269 | if (checkAttrMutualExclusion<Mips16Attr>(S, D, AL.getRange(), | |||
5270 | AL.getName())) | |||
5271 | return; | |||
5272 | ||||
5273 | MipsInterruptAttr::InterruptType Kind; | |||
5274 | if (!MipsInterruptAttr::ConvertStrToInterruptType(Str, Kind)) { | |||
5275 | S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) | |||
5276 | << AL.getName() << "'" + std::string(Str) + "'"; | |||
5277 | return; | |||
5278 | } | |||
5279 | ||||
5280 | D->addAttr(::new (S.Context) MipsInterruptAttr( | |||
5281 | AL.getLoc(), S.Context, Kind, AL.getAttributeSpellingListIndex())); | |||
5282 | } | |||
5283 | ||||
5284 | static void handleAnyX86InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5285 | // Semantic checks for a function with the 'interrupt' attribute. | |||
5286 | // a) Must be a function. | |||
5287 | // b) Must have the 'void' return type. | |||
5288 | // c) Must take 1 or 2 arguments. | |||
5289 | // d) The 1st argument must be a pointer. | |||
5290 | // e) The 2nd argument (if any) must be an unsigned integer. | |||
5291 | if (!isFunctionOrMethod(D) || !hasFunctionProto(D) || isInstanceMethod(D) || | |||
5292 | CXXMethodDecl::isStaticOverloadedOperator( | |||
5293 | cast<NamedDecl>(D)->getDeclName().getCXXOverloadedOperator())) { | |||
5294 | S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) | |||
5295 | << AL.getName() << ExpectedFunctionWithProtoType; | |||
5296 | return; | |||
5297 | } | |||
5298 | // Interrupt handler must have void return type. | |||
5299 | if (!getFunctionOrMethodResultType(D)->isVoidType()) { | |||
5300 | S.Diag(getFunctionOrMethodResultSourceRange(D).getBegin(), | |||
5301 | diag::err_anyx86_interrupt_attribute) | |||
5302 | << (S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86 | |||
5303 | ? 0 | |||
5304 | : 1) | |||
5305 | << 0; | |||
5306 | return; | |||
5307 | } | |||
5308 | // Interrupt handler must have 1 or 2 parameters. | |||
5309 | unsigned NumParams = getFunctionOrMethodNumParams(D); | |||
5310 | if (NumParams < 1 || NumParams > 2) { | |||
5311 | S.Diag(D->getLocStart(), diag::err_anyx86_interrupt_attribute) | |||
5312 | << (S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86 | |||
5313 | ? 0 | |||
5314 | : 1) | |||
5315 | << 1; | |||
5316 | return; | |||
5317 | } | |||
5318 | // The first argument must be a pointer. | |||
5319 | if (!getFunctionOrMethodParamType(D, 0)->isPointerType()) { | |||
5320 | S.Diag(getFunctionOrMethodParamRange(D, 0).getBegin(), | |||
5321 | diag::err_anyx86_interrupt_attribute) | |||
5322 | << (S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86 | |||
5323 | ? 0 | |||
5324 | : 1) | |||
5325 | << 2; | |||
5326 | return; | |||
5327 | } | |||
5328 | // The second argument, if present, must be an unsigned integer. | |||
5329 | unsigned TypeSize = | |||
5330 | S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86_64 | |||
5331 | ? 64 | |||
5332 | : 32; | |||
5333 | if (NumParams == 2 && | |||
5334 | (!getFunctionOrMethodParamType(D, 1)->isUnsignedIntegerType() || | |||
5335 | S.Context.getTypeSize(getFunctionOrMethodParamType(D, 1)) != TypeSize)) { | |||
5336 | S.Diag(getFunctionOrMethodParamRange(D, 1).getBegin(), | |||
5337 | diag::err_anyx86_interrupt_attribute) | |||
5338 | << (S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86 | |||
5339 | ? 0 | |||
5340 | : 1) | |||
5341 | << 3 << S.Context.getIntTypeForBitwidth(TypeSize, /*Signed=*/false); | |||
5342 | return; | |||
5343 | } | |||
5344 | D->addAttr(::new (S.Context) AnyX86InterruptAttr( | |||
5345 | AL.getLoc(), S.Context, AL.getAttributeSpellingListIndex())); | |||
5346 | D->addAttr(UsedAttr::CreateImplicit(S.Context)); | |||
5347 | } | |||
5348 | ||||
5349 | static void handleAVRInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5350 | if (!isFunctionOrMethod(D)) { | |||
5351 | S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) | |||
5352 | << "'interrupt'" << ExpectedFunction; | |||
5353 | return; | |||
5354 | } | |||
5355 | ||||
5356 | if (!checkAttributeNumArgs(S, AL, 0)) | |||
5357 | return; | |||
5358 | ||||
5359 | handleSimpleAttribute<AVRInterruptAttr>(S, D, AL); | |||
5360 | } | |||
5361 | ||||
5362 | static void handleAVRSignalAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5363 | if (!isFunctionOrMethod(D)) { | |||
5364 | S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) | |||
5365 | << "'signal'" << ExpectedFunction; | |||
5366 | return; | |||
5367 | } | |||
5368 | ||||
5369 | if (!checkAttributeNumArgs(S, AL, 0)) | |||
5370 | return; | |||
5371 | ||||
5372 | handleSimpleAttribute<AVRSignalAttr>(S, D, AL); | |||
5373 | } | |||
5374 | ||||
5375 | ||||
5376 | static void handleRISCVInterruptAttr(Sema &S, Decl *D, | |||
5377 | const ParsedAttr &AL) { | |||
5378 | // Warn about repeated attributes. | |||
5379 | if (const auto *A = D->getAttr<RISCVInterruptAttr>()) { | |||
5380 | S.Diag(AL.getRange().getBegin(), | |||
5381 | diag::warn_riscv_repeated_interrupt_attribute); | |||
5382 | S.Diag(A->getLocation(), diag::note_riscv_repeated_interrupt_attribute); | |||
5383 | return; | |||
5384 | } | |||
5385 | ||||
5386 | // Check the attribute argument. Argument is optional. | |||
5387 | if (!checkAttributeAtMostNumArgs(S, AL, 1)) | |||
5388 | return; | |||
5389 | ||||
5390 | StringRef Str; | |||
5391 | SourceLocation ArgLoc; | |||
5392 | ||||
5393 | // 'machine'is the default interrupt mode. | |||
5394 | if (AL.getNumArgs() == 0) | |||
5395 | Str = "machine"; | |||
5396 | else if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc)) | |||
5397 | return; | |||
5398 | ||||
5399 | // Semantic checks for a function with the 'interrupt' attribute: | |||
5400 | // - Must be a function. | |||
5401 | // - Must have no parameters. | |||
5402 | // - Must have the 'void' return type. | |||
5403 | // - The attribute itself must either have no argument or one of the | |||
5404 | // valid interrupt types, see [RISCVInterruptDocs]. | |||
5405 | ||||
5406 | if (D->getFunctionType() == nullptr) { | |||
5407 | S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) | |||
5408 | << "'interrupt'" << ExpectedFunction; | |||
5409 | return; | |||
5410 | } | |||
5411 | ||||
5412 | if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) { | |||
5413 | S.Diag(D->getLocation(), diag::warn_riscv_interrupt_attribute) << 0; | |||
5414 | return; | |||
5415 | } | |||
5416 | ||||
5417 | if (!getFunctionOrMethodResultType(D)->isVoidType()) { | |||
5418 | S.Diag(D->getLocation(), diag::warn_riscv_interrupt_attribute) << 1; | |||
5419 | return; | |||
5420 | } | |||
5421 | ||||
5422 | RISCVInterruptAttr::InterruptType Kind; | |||
5423 | if (!RISCVInterruptAttr::ConvertStrToInterruptType(Str, Kind)) { | |||
5424 | S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) | |||
5425 | << AL.getName() << Str << ArgLoc; | |||
5426 | return; | |||
5427 | } | |||
5428 | ||||
5429 | D->addAttr(::new (S.Context) RISCVInterruptAttr( | |||
5430 | AL.getLoc(), S.Context, Kind, AL.getAttributeSpellingListIndex())); | |||
5431 | } | |||
5432 | ||||
5433 | static void handleInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5434 | // Dispatch the interrupt attribute based on the current target. | |||
5435 | switch (S.Context.getTargetInfo().getTriple().getArch()) { | |||
5436 | case llvm::Triple::msp430: | |||
5437 | handleMSP430InterruptAttr(S, D, AL); | |||
5438 | break; | |||
5439 | case llvm::Triple::mipsel: | |||
5440 | case llvm::Triple::mips: | |||
5441 | handleMipsInterruptAttr(S, D, AL); | |||
5442 | break; | |||
5443 | case llvm::Triple::x86: | |||
5444 | case llvm::Triple::x86_64: | |||
5445 | handleAnyX86InterruptAttr(S, D, AL); | |||
5446 | break; | |||
5447 | case llvm::Triple::avr: | |||
5448 | handleAVRInterruptAttr(S, D, AL); | |||
5449 | break; | |||
5450 | case llvm::Triple::riscv32: | |||
5451 | case llvm::Triple::riscv64: | |||
5452 | handleRISCVInterruptAttr(S, D, AL); | |||
5453 | break; | |||
5454 | default: | |||
5455 | handleARMInterruptAttr(S, D, AL); | |||
5456 | break; | |||
5457 | } | |||
5458 | } | |||
5459 | ||||
5460 | static void handleAMDGPUFlatWorkGroupSizeAttr(Sema &S, Decl *D, | |||
5461 | const ParsedAttr &AL) { | |||
5462 | uint32_t Min = 0; | |||
5463 | Expr *MinExpr = AL.getArgAsExpr(0); | |||
5464 | if (!checkUInt32Argument(S, AL, MinExpr, Min)) | |||
5465 | return; | |||
5466 | ||||
5467 | uint32_t Max = 0; | |||
5468 | Expr *MaxExpr = AL.getArgAsExpr(1); | |||
5469 | if (!checkUInt32Argument(S, AL, MaxExpr, Max)) | |||
5470 | return; | |||
5471 | ||||
5472 | if (Min == 0 && Max != 0) { | |||
5473 | S.Diag(AL.getLoc(), diag::err_attribute_argument_invalid) | |||
5474 | << AL.getName() << 0; | |||
5475 | return; | |||
5476 | } | |||
5477 | if (Min > Max) { | |||
5478 | S.Diag(AL.getLoc(), diag::err_attribute_argument_invalid) | |||
5479 | << AL.getName() << 1; | |||
5480 | return; | |||
5481 | } | |||
5482 | ||||
5483 | D->addAttr(::new (S.Context) | |||
5484 | AMDGPUFlatWorkGroupSizeAttr(AL.getLoc(), S.Context, Min, Max, | |||
5485 | AL.getAttributeSpellingListIndex())); | |||
5486 | } | |||
5487 | ||||
5488 | static void handleAMDGPUWavesPerEUAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5489 | uint32_t Min = 0; | |||
5490 | Expr *MinExpr = AL.getArgAsExpr(0); | |||
5491 | if (!checkUInt32Argument(S, AL, MinExpr, Min)) | |||
5492 | return; | |||
5493 | ||||
5494 | uint32_t Max = 0; | |||
5495 | if (AL.getNumArgs() == 2) { | |||
5496 | Expr *MaxExpr = AL.getArgAsExpr(1); | |||
5497 | if (!checkUInt32Argument(S, AL, MaxExpr, Max)) | |||
5498 | return; | |||
5499 | } | |||
5500 | ||||
5501 | if (Min == 0 && Max != 0) { | |||
5502 | S.Diag(AL.getLoc(), diag::err_attribute_argument_invalid) | |||
5503 | << AL.getName() << 0; | |||
5504 | return; | |||
5505 | } | |||
5506 | if (Max != 0 && Min > Max) { | |||
5507 | S.Diag(AL.getLoc(), diag::err_attribute_argument_invalid) | |||
5508 | << AL.getName() << 1; | |||
5509 | return; | |||
5510 | } | |||
5511 | ||||
5512 | D->addAttr(::new (S.Context) | |||
5513 | AMDGPUWavesPerEUAttr(AL.getLoc(), S.Context, Min, Max, | |||
5514 | AL.getAttributeSpellingListIndex())); | |||
5515 | } | |||
5516 | ||||
5517 | static void handleAMDGPUNumSGPRAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5518 | uint32_t NumSGPR = 0; | |||
5519 | Expr *NumSGPRExpr = AL.getArgAsExpr(0); | |||
5520 | if (!checkUInt32Argument(S, AL, NumSGPRExpr, NumSGPR)) | |||
5521 | return; | |||
5522 | ||||
5523 | D->addAttr(::new (S.Context) | |||
5524 | AMDGPUNumSGPRAttr(AL.getLoc(), S.Context, NumSGPR, | |||
5525 | AL.getAttributeSpellingListIndex())); | |||
5526 | } | |||
5527 | ||||
5528 | static void handleAMDGPUNumVGPRAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5529 | uint32_t NumVGPR = 0; | |||
5530 | Expr *NumVGPRExpr = AL.getArgAsExpr(0); | |||
5531 | if (!checkUInt32Argument(S, AL, NumVGPRExpr, NumVGPR)) | |||
5532 | return; | |||
5533 | ||||
5534 | D->addAttr(::new (S.Context) | |||
5535 | AMDGPUNumVGPRAttr(AL.getLoc(), S.Context, NumVGPR, | |||
5536 | AL.getAttributeSpellingListIndex())); | |||
5537 | } | |||
5538 | ||||
5539 | static void handleX86ForceAlignArgPointerAttr(Sema &S, Decl *D, | |||
5540 | const ParsedAttr &AL) { | |||
5541 | // If we try to apply it to a function pointer, don't warn, but don't | |||
5542 | // do anything, either. It doesn't matter anyway, because there's nothing | |||
5543 | // special about calling a force_align_arg_pointer function. | |||
5544 | const auto *VD = dyn_cast<ValueDecl>(D); | |||
5545 | if (VD && VD->getType()->isFunctionPointerType()) | |||
5546 | return; | |||
5547 | // Also don't warn on function pointer typedefs. | |||
5548 | const auto *TD = dyn_cast<TypedefNameDecl>(D); | |||
5549 | if (TD && (TD->getUnderlyingType()->isFunctionPointerType() || | |||
5550 | TD->getUnderlyingType()->isFunctionType())) | |||
5551 | return; | |||
5552 | // Attribute can only be applied to function types. | |||
5553 | if (!isa<FunctionDecl>(D)) { | |||
5554 | S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) | |||
5555 | << AL.getName() << ExpectedFunction; | |||
5556 | return; | |||
5557 | } | |||
5558 | ||||
5559 | D->addAttr(::new (S.Context) | |||
5560 | X86ForceAlignArgPointerAttr(AL.getRange(), S.Context, | |||
5561 | AL.getAttributeSpellingListIndex())); | |||
5562 | } | |||
5563 | ||||
5564 | static void handleLayoutVersion(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5565 | uint32_t Version; | |||
5566 | Expr *VersionExpr = static_cast<Expr *>(AL.getArgAsExpr(0)); | |||
5567 | if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), Version)) | |||
5568 | return; | |||
5569 | ||||
5570 | // TODO: Investigate what happens with the next major version of MSVC. | |||
5571 | if (Version != LangOptions::MSVC2015) { | |||
5572 | S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) | |||
5573 | << AL.getName() << Version << VersionExpr->getSourceRange(); | |||
5574 | return; | |||
5575 | } | |||
5576 | ||||
5577 | D->addAttr(::new (S.Context) | |||
5578 | LayoutVersionAttr(AL.getRange(), S.Context, Version, | |||
5579 | AL.getAttributeSpellingListIndex())); | |||
5580 | } | |||
5581 | ||||
5582 | DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D, SourceRange Range, | |||
5583 | unsigned AttrSpellingListIndex) { | |||
5584 | if (D->hasAttr<DLLExportAttr>()) { | |||
5585 | Diag(Range.getBegin(), diag::warn_attribute_ignored) << "'dllimport'"; | |||
5586 | return nullptr; | |||
5587 | } | |||
5588 | ||||
5589 | if (D->hasAttr<DLLImportAttr>()) | |||
5590 | return nullptr; | |||
5591 | ||||
5592 | return ::new (Context) DLLImportAttr(Range, Context, AttrSpellingListIndex); | |||
5593 | } | |||
5594 | ||||
5595 | DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D, SourceRange Range, | |||
5596 | unsigned AttrSpellingListIndex) { | |||
5597 | if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) { | |||
5598 | Diag(Import->getLocation(), diag::warn_attribute_ignored) << Import; | |||
5599 | D->dropAttr<DLLImportAttr>(); | |||
5600 | } | |||
5601 | ||||
5602 | if (D->hasAttr<DLLExportAttr>()) | |||
5603 | return nullptr; | |||
5604 | ||||
5605 | return ::new (Context) DLLExportAttr(Range, Context, AttrSpellingListIndex); | |||
5606 | } | |||
5607 | ||||
5608 | static void handleDLLAttr(Sema &S, Decl *D, const ParsedAttr &A) { | |||
5609 | if (isa<ClassTemplatePartialSpecializationDecl>(D) && | |||
5610 | S.Context.getTargetInfo().getCXXABI().isMicrosoft()) { | |||
5611 | S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored) | |||
5612 | << A.getName(); | |||
5613 | return; | |||
5614 | } | |||
5615 | ||||
5616 | if (const auto *FD = dyn_cast<FunctionDecl>(D)) { | |||
5617 | if (FD->isInlined() && A.getKind() == ParsedAttr::AT_DLLImport && | |||
5618 | !S.Context.getTargetInfo().getCXXABI().isMicrosoft()) { | |||
5619 | // MinGW doesn't allow dllimport on inline functions. | |||
5620 | S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored_on_inline) | |||
5621 | << A.getName(); | |||
5622 | return; | |||
5623 | } | |||
5624 | } | |||
5625 | ||||
5626 | if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) { | |||
5627 | if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() && | |||
5628 | MD->getParent()->isLambda()) { | |||
5629 | S.Diag(A.getRange().getBegin(), diag::err_attribute_dll_lambda) << A.getName(); | |||
5630 | return; | |||
5631 | } | |||
5632 | } | |||
5633 | ||||
5634 | unsigned Index = A.getAttributeSpellingListIndex(); | |||
5635 | Attr *NewAttr = A.getKind() == ParsedAttr::AT_DLLExport | |||
5636 | ? (Attr *)S.mergeDLLExportAttr(D, A.getRange(), Index) | |||
5637 | : (Attr *)S.mergeDLLImportAttr(D, A.getRange(), Index); | |||
5638 | if (NewAttr) | |||
5639 | D->addAttr(NewAttr); | |||
5640 | } | |||
5641 | ||||
5642 | MSInheritanceAttr * | |||
5643 | Sema::mergeMSInheritanceAttr(Decl *D, SourceRange Range, bool BestCase, | |||
5644 | unsigned AttrSpellingListIndex, | |||
5645 | MSInheritanceAttr::Spelling SemanticSpelling) { | |||
5646 | if (MSInheritanceAttr *IA = D->getAttr<MSInheritanceAttr>()) { | |||
5647 | if (IA->getSemanticSpelling() == SemanticSpelling) | |||
5648 | return nullptr; | |||
5649 | Diag(IA->getLocation(), diag::err_mismatched_ms_inheritance) | |||
5650 | << 1 /*previous declaration*/; | |||
5651 | Diag(Range.getBegin(), diag::note_previous_ms_inheritance); | |||
5652 | D->dropAttr<MSInheritanceAttr>(); | |||
5653 | } | |||
5654 | ||||
5655 | auto *RD = cast<CXXRecordDecl>(D); | |||
5656 | if (RD->hasDefinition()) { | |||
5657 | if (checkMSInheritanceAttrOnDefinition(RD, Range, BestCase, | |||
5658 | SemanticSpelling)) { | |||
5659 | return nullptr; | |||
5660 | } | |||
5661 | } else { | |||
5662 | if (isa<ClassTemplatePartialSpecializationDecl>(RD)) { | |||
5663 | Diag(Range.getBegin(), diag::warn_ignored_ms_inheritance) | |||
5664 | << 1 /*partial specialization*/; | |||
5665 | return nullptr; | |||
5666 | } | |||
5667 | if (RD->getDescribedClassTemplate()) { | |||
5668 | Diag(Range.getBegin(), diag::warn_ignored_ms_inheritance) | |||
5669 | << 0 /*primary template*/; | |||
5670 | return nullptr; | |||
5671 | } | |||
5672 | } | |||
5673 | ||||
5674 | return ::new (Context) | |||
5675 | MSInheritanceAttr(Range, Context, BestCase, AttrSpellingListIndex); | |||
5676 | } | |||
5677 | ||||
5678 | static void handleCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5679 | // The capability attributes take a single string parameter for the name of | |||
5680 | // the capability they represent. The lockable attribute does not take any | |||
5681 | // parameters. However, semantically, both attributes represent the same | |||
5682 | // concept, and so they use the same semantic attribute. Eventually, the | |||
5683 | // lockable attribute will be removed. | |||
5684 | // | |||
5685 | // For backward compatibility, any capability which has no specified string | |||
5686 | // literal will be considered a "mutex." | |||
5687 | StringRef N("mutex"); | |||
5688 | SourceLocation LiteralLoc; | |||
5689 | if (AL.getKind() == ParsedAttr::AT_Capability && | |||
5690 | !S.checkStringLiteralArgumentAttr(AL, 0, N, &LiteralLoc)) | |||
5691 | return; | |||
5692 | ||||
5693 | // Currently, there are only two names allowed for a capability: role and | |||
5694 | // mutex (case insensitive). Diagnose other capability names. | |||
5695 | if (!N.equals_lower("mutex") && !N.equals_lower("role")) | |||
5696 | S.Diag(LiteralLoc, diag::warn_invalid_capability_name) << N; | |||
5697 | ||||
5698 | D->addAttr(::new (S.Context) CapabilityAttr(AL.getRange(), S.Context, N, | |||
5699 | AL.getAttributeSpellingListIndex())); | |||
5700 | } | |||
5701 | ||||
5702 | static void handleAssertCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5703 | SmallVector<Expr*, 1> Args; | |||
5704 | if (!checkLockFunAttrCommon(S, D, AL, Args)) | |||
5705 | return; | |||
5706 | ||||
5707 | D->addAttr(::new (S.Context) AssertCapabilityAttr(AL.getRange(), S.Context, | |||
5708 | Args.data(), Args.size(), | |||
5709 | AL.getAttributeSpellingListIndex())); | |||
5710 | } | |||
5711 | ||||
5712 | static void handleAcquireCapabilityAttr(Sema &S, Decl *D, | |||
5713 | const ParsedAttr &AL) { | |||
5714 | SmallVector<Expr*, 1> Args; | |||
5715 | if (!checkLockFunAttrCommon(S, D, AL, Args)) | |||
5716 | return; | |||
5717 | ||||
5718 | D->addAttr(::new (S.Context) AcquireCapabilityAttr(AL.getRange(), | |||
5719 | S.Context, | |||
5720 | Args.data(), Args.size(), | |||
5721 | AL.getAttributeSpellingListIndex())); | |||
5722 | } | |||
5723 | ||||
5724 | static void handleTryAcquireCapabilityAttr(Sema &S, Decl *D, | |||
5725 | const ParsedAttr &AL) { | |||
5726 | SmallVector<Expr*, 2> Args; | |||
5727 | if (!checkTryLockFunAttrCommon(S, D, AL, Args)) | |||
5728 | return; | |||
5729 | ||||
5730 | D->addAttr(::new (S.Context) TryAcquireCapabilityAttr(AL.getRange(), | |||
5731 | S.Context, | |||
5732 | AL.getArgAsExpr(0), | |||
5733 | Args.data(), | |||
5734 | Args.size(), | |||
5735 | AL.getAttributeSpellingListIndex())); | |||
5736 | } | |||
5737 | ||||
5738 | static void handleReleaseCapabilityAttr(Sema &S, Decl *D, | |||
5739 | const ParsedAttr &AL) { | |||
5740 | // Check that all arguments are lockable objects. | |||
5741 | SmallVector<Expr *, 1> Args; | |||
5742 | checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 0, true); | |||
5743 | ||||
5744 | D->addAttr(::new (S.Context) ReleaseCapabilityAttr( | |||
5745 | AL.getRange(), S.Context, Args.data(), Args.size(), | |||
5746 | AL.getAttributeSpellingListIndex())); | |||
5747 | } | |||
5748 | ||||
5749 | static void handleRequiresCapabilityAttr(Sema &S, Decl *D, | |||
5750 | const ParsedAttr &AL) { | |||
5751 | if (!checkAttributeAtLeastNumArgs(S, AL, 1)) | |||
5752 | return; | |||
5753 | ||||
5754 | // check that all arguments are lockable objects | |||
5755 | SmallVector<Expr*, 1> Args; | |||
5756 | checkAttrArgsAreCapabilityObjs(S, D, AL, Args); | |||
5757 | if (Args.empty()) | |||
5758 | return; | |||
5759 | ||||
5760 | RequiresCapabilityAttr *RCA = ::new (S.Context) | |||
5761 | RequiresCapabilityAttr(AL.getRange(), S.Context, Args.data(), | |||
5762 | Args.size(), AL.getAttributeSpellingListIndex()); | |||
5763 | ||||
5764 | D->addAttr(RCA); | |||
5765 | } | |||
5766 | ||||
5767 | static void handleDeprecatedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5768 | if (const auto *NSD = dyn_cast<NamespaceDecl>(D)) { | |||
5769 | if (NSD->isAnonymousNamespace()) { | |||
5770 | S.Diag(AL.getLoc(), diag::warn_deprecated_anonymous_namespace); | |||
5771 | // Do not want to attach the attribute to the namespace because that will | |||
5772 | // cause confusing diagnostic reports for uses of declarations within the | |||
5773 | // namespace. | |||
5774 | return; | |||
5775 | } | |||
5776 | } | |||
5777 | ||||
5778 | // Handle the cases where the attribute has a text message. | |||
5779 | StringRef Str, Replacement; | |||
5780 | if (AL.isArgExpr(0) && AL.getArgAsExpr(0) && | |||
5781 | !S.checkStringLiteralArgumentAttr(AL, 0, Str)) | |||
5782 | return; | |||
5783 | ||||
5784 | // Only support a single optional message for Declspec and CXX11. | |||
5785 | if (AL.isDeclspecAttribute() || AL.isCXX11Attribute()) | |||
5786 | checkAttributeAtMostNumArgs(S, AL, 1); | |||
5787 | else if (AL.isArgExpr(1) && AL.getArgAsExpr(1) && | |||
5788 | !S.checkStringLiteralArgumentAttr(AL, 1, Replacement)) | |||
5789 | return; | |||
5790 | ||||
5791 | if (!S.getLangOpts().CPlusPlus14) | |||
5792 | if (AL.isCXX11Attribute() && | |||
5793 | !(AL.hasScope() && AL.getScopeName()->isStr("gnu"))) | |||
5794 | S.Diag(AL.getLoc(), diag::ext_cxx14_attr) << AL.getName(); | |||
5795 | ||||
5796 | D->addAttr(::new (S.Context) | |||
5797 | DeprecatedAttr(AL.getRange(), S.Context, Str, Replacement, | |||
5798 | AL.getAttributeSpellingListIndex())); | |||
5799 | } | |||
5800 | ||||
5801 | static bool isGlobalVar(const Decl *D) { | |||
5802 | if (const auto *S = dyn_cast<VarDecl>(D)) | |||
5803 | return S->hasGlobalStorage(); | |||
5804 | return false; | |||
5805 | } | |||
5806 | ||||
5807 | static void handleNoSanitizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5808 | if (!checkAttributeAtLeastNumArgs(S, AL, 1)) | |||
5809 | return; | |||
5810 | ||||
5811 | std::vector<StringRef> Sanitizers; | |||
5812 | ||||
5813 | for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) { | |||
5814 | StringRef SanitizerName; | |||
5815 | SourceLocation LiteralLoc; | |||
5816 | ||||
5817 | if (!S.checkStringLiteralArgumentAttr(AL, I, SanitizerName, &LiteralLoc)) | |||
5818 | return; | |||
5819 | ||||
5820 | if (parseSanitizerValue(SanitizerName, /*AllowGroups=*/true) == 0) | |||
5821 | S.Diag(LiteralLoc, diag::warn_unknown_sanitizer_ignored) << SanitizerName; | |||
5822 | else if (isGlobalVar(D) && SanitizerName != "address") | |||
5823 | S.Diag(D->getLocation(), diag::err_attribute_wrong_decl_type) | |||
5824 | << AL.getName() << ExpectedFunctionOrMethod; | |||
5825 | Sanitizers.push_back(SanitizerName); | |||
5826 | } | |||
5827 | ||||
5828 | D->addAttr(::new (S.Context) NoSanitizeAttr( | |||
5829 | AL.getRange(), S.Context, Sanitizers.data(), Sanitizers.size(), | |||
5830 | AL.getAttributeSpellingListIndex())); | |||
5831 | } | |||
5832 | ||||
5833 | static void handleNoSanitizeSpecificAttr(Sema &S, Decl *D, | |||
5834 | const ParsedAttr &AL) { | |||
5835 | StringRef AttrName = AL.getName()->getName(); | |||
5836 | normalizeName(AttrName); | |||
5837 | StringRef SanitizerName = llvm::StringSwitch<StringRef>(AttrName) | |||
5838 | .Case("no_address_safety_analysis", "address") | |||
5839 | .Case("no_sanitize_address", "address") | |||
5840 | .Case("no_sanitize_thread", "thread") | |||
5841 | .Case("no_sanitize_memory", "memory"); | |||
5842 | if (isGlobalVar(D) && SanitizerName != "address") | |||
5843 | S.Diag(D->getLocation(), diag::err_attribute_wrong_decl_type) | |||
5844 | << AL.getName() << ExpectedFunction; | |||
5845 | D->addAttr(::new (S.Context) | |||
5846 | NoSanitizeAttr(AL.getRange(), S.Context, &SanitizerName, 1, | |||
5847 | AL.getAttributeSpellingListIndex())); | |||
5848 | } | |||
5849 | ||||
5850 | static void handleInternalLinkageAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5851 | if (InternalLinkageAttr *Internal = | |||
5852 | S.mergeInternalLinkageAttr(D, AL.getRange(), AL.getName(), | |||
5853 | AL.getAttributeSpellingListIndex())) | |||
5854 | D->addAttr(Internal); | |||
5855 | } | |||
5856 | ||||
5857 | static void handleOpenCLNoSVMAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5858 | if (S.LangOpts.OpenCLVersion != 200) | |||
5859 | S.Diag(AL.getLoc(), diag::err_attribute_requires_opencl_version) | |||
5860 | << AL.getName() << "2.0" << 0; | |||
5861 | else | |||
5862 | S.Diag(AL.getLoc(), diag::warn_opencl_attr_deprecated_ignored) | |||
5863 | << AL.getName() << "2.0"; | |||
5864 | } | |||
5865 | ||||
5866 | /// Handles semantic checking for features that are common to all attributes, | |||
5867 | /// such as checking whether a parameter was properly specified, or the correct | |||
5868 | /// number of arguments were passed, etc. | |||
5869 | static bool handleCommonAttributeFeatures(Sema &S, Decl *D, | |||
5870 | const ParsedAttr &AL) { | |||
5871 | // Several attributes carry different semantics than the parsing requires, so | |||
5872 | // those are opted out of the common argument checks. | |||
5873 | // | |||
5874 | // We also bail on unknown and ignored attributes because those are handled | |||
5875 | // as part of the target-specific handling logic. | |||
5876 | if (AL.getKind() == ParsedAttr::UnknownAttribute) | |||
5877 | return false; | |||
5878 | // Check whether the attribute requires specific language extensions to be | |||
5879 | // enabled. | |||
5880 | if (!AL.diagnoseLangOpts(S)) | |||
5881 | return true; | |||
5882 | // Check whether the attribute appertains to the given subject. | |||
5883 | if (!AL.diagnoseAppertainsTo(S, D)) | |||
5884 | return true; | |||
5885 | if (AL.hasCustomParsing()) | |||
5886 | return false; | |||
5887 | ||||
5888 | if (AL.getMinArgs() == AL.getMaxArgs()) { | |||
5889 | // If there are no optional arguments, then checking for the argument count | |||
5890 | // is trivial. | |||
5891 | if (!checkAttributeNumArgs(S, AL, AL.getMinArgs())) | |||
5892 | return true; | |||
5893 | } else { | |||
5894 | // There are optional arguments, so checking is slightly more involved. | |||
5895 | if (AL.getMinArgs() && | |||
5896 | !checkAttributeAtLeastNumArgs(S, AL, AL.getMinArgs())) | |||
5897 | return true; | |||
5898 | else if (!AL.hasVariadicArg() && AL.getMaxArgs() && | |||
5899 | !checkAttributeAtMostNumArgs(S, AL, AL.getMaxArgs())) | |||
5900 | return true; | |||
5901 | } | |||
5902 | ||||
5903 | if (S.CheckAttrTarget(AL)) | |||
5904 | return true; | |||
5905 | ||||
5906 | return false; | |||
5907 | } | |||
5908 | ||||
5909 | static void handleOpenCLAccessAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |||
5910 | if (D->isInvalidDecl()) | |||
5911 | return; | |||
5912 | ||||
5913 | // Check if there is only one access qualifier. | |||
5914 | if (D->hasAttr<OpenCLAccessAttr>()) { | |||
5915 | S.Diag(AL.getLoc(), diag::err_opencl_multiple_access_qualifiers) | |||
5916 | << D->getSourceRange(); | |||
5917 | D->setInvalidDecl(true); | |||
5918 | return; | |||
5919 | } | |||
5920 | ||||
5921 | // OpenCL v2.0 s6.6 - read_write can be used for image types to specify that an | |||
5922 | // image object can be read and written. | |||
5923 | // OpenCL v2.0 s6.13.6 - A kernel cannot read from and write to the same pipe | |||
5924 | // object. Using the read_write (or __read_write) qualifier with the pipe | |||
5925 | // qualifier is a compilation error. | |||
5926 | if (const auto *PDecl = dyn_cast<ParmVarDecl>(D)) { | |||
5927 | const Type *DeclTy = PDecl->getType().getCanonicalType().getTypePtr(); | |||
5928 | if (AL.getName()->getName().find("read_write") != StringRef::npos) { | |||
5929 | if (S.getLangOpts().OpenCLVersion < 200 || DeclTy->isPipeType()) { | |||
5930 | S.Diag(AL.getLoc(), diag::err_opencl_invalid_read_write) | |||
5931 | << AL.getName() << PDecl->getType() << DeclTy->isImageType(); | |||
5932 | D->setInvalidDecl(true); | |||
5933 | return; | |||
5934 | } | |||
5935 | } | |||
5936 | } | |||
5937 | ||||
5938 | D->addAttr(::new (S.Context) OpenCLAccessAttr( | |||
5939 | AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); | |||
5940 | } | |||
5941 | ||||
5942 | //===----------------------------------------------------------------------===// | |||
5943 | // Top Level Sema Entry Points | |||
5944 | //===----------------------------------------------------------------------===// | |||
5945 | ||||
5946 | /// ProcessDeclAttribute - Apply the specific attribute to the specified decl if | |||
5947 | /// the attribute applies to decls. If the attribute is a type attribute, just | |||
5948 | /// silently ignore it if a GNU attribute. | |||
5949 | static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, | |||
5950 | const ParsedAttr &AL, | |||
5951 | bool IncludeCXX11Attributes) { | |||
5952 | if (AL.isInvalid() || AL.getKind() == ParsedAttr::IgnoredAttribute) | |||
5953 | return; | |||
5954 | ||||
5955 | // Ignore C++11 attributes on declarator chunks: they appertain to the type | |||
5956 | // instead. | |||
5957 | if (AL.isCXX11Attribute() && !IncludeCXX11Attributes) | |||
5958 | return; | |||
5959 | ||||
5960 | // Unknown attributes are automatically warned on. Target-specific attributes | |||
5961 | // which do not apply to the current target architecture are treated as | |||
5962 | // though they were unknown attributes. | |||
5963 | if (AL.getKind() == ParsedAttr::UnknownAttribute || | |||
5964 | !AL.existsInTarget(S.Context.getTargetInfo())) { | |||
5965 | S.Diag(AL.getLoc(), AL.isDeclspecAttribute() | |||
5966 | ? diag::warn_unhandled_ms_attribute_ignored | |||
5967 | : diag::warn_unknown_attribute_ignored) | |||
5968 | << AL.getName(); | |||
5969 | return; | |||
5970 | } | |||
5971 | ||||
5972 | if (handleCommonAttributeFeatures(S, D, AL)) | |||
5973 | return; | |||
5974 | ||||
5975 | switch (AL.getKind()) { | |||
5976 | default: | |||
5977 | if (!AL.isStmtAttr()) { | |||
5978 | // Type attributes are handled elsewhere; silently move on. | |||
5979 | assert(AL.isTypeAttr() && "Non-type attribute not handled")(static_cast <bool> (AL.isTypeAttr() && "Non-type attribute not handled" ) ? void (0) : __assert_fail ("AL.isTypeAttr() && \"Non-type attribute not handled\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 5979, __extension__ __PRETTY_FUNCTION__)); | |||
5980 | break; | |||
5981 | } | |||
5982 | S.Diag(AL.getLoc(), diag::err_stmt_attribute_invalid_on_decl) | |||
5983 | << AL.getName() << D->getLocation(); | |||
5984 | break; | |||
5985 | case ParsedAttr::AT_Interrupt: | |||
5986 | handleInterruptAttr(S, D, AL); | |||
5987 | break; | |||
5988 | case ParsedAttr::AT_X86ForceAlignArgPointer: | |||
5989 | handleX86ForceAlignArgPointerAttr(S, D, AL); | |||
5990 | break; | |||
5991 | case ParsedAttr::AT_DLLExport: | |||
5992 | case ParsedAttr::AT_DLLImport: | |||
5993 | handleDLLAttr(S, D, AL); | |||
5994 | break; | |||
5995 | case ParsedAttr::AT_Mips16: | |||
5996 | handleSimpleAttributeWithExclusions<Mips16Attr, MicroMipsAttr, | |||
5997 | MipsInterruptAttr>(S, D, AL); | |||
5998 | break; | |||
5999 | case ParsedAttr::AT_NoMips16: | |||
6000 | handleSimpleAttribute<NoMips16Attr>(S, D, AL); | |||
6001 | break; | |||
6002 | case ParsedAttr::AT_MicroMips: | |||
6003 | handleSimpleAttributeWithExclusions<MicroMipsAttr, Mips16Attr>(S, D, AL); | |||
6004 | break; | |||
6005 | case ParsedAttr::AT_NoMicroMips: | |||
6006 | handleSimpleAttribute<NoMicroMipsAttr>(S, D, AL); | |||
6007 | break; | |||
6008 | case ParsedAttr::AT_MipsLongCall: | |||
6009 | handleSimpleAttributeWithExclusions<MipsLongCallAttr, MipsShortCallAttr>( | |||
6010 | S, D, AL); | |||
6011 | break; | |||
6012 | case ParsedAttr::AT_MipsShortCall: | |||
6013 | handleSimpleAttributeWithExclusions<MipsShortCallAttr, MipsLongCallAttr>( | |||
6014 | S, D, AL); | |||
6015 | break; | |||
6016 | case ParsedAttr::AT_AMDGPUFlatWorkGroupSize: | |||
6017 | handleAMDGPUFlatWorkGroupSizeAttr(S, D, AL); | |||
6018 | break; | |||
6019 | case ParsedAttr::AT_AMDGPUWavesPerEU: | |||
6020 | handleAMDGPUWavesPerEUAttr(S, D, AL); | |||
6021 | break; | |||
6022 | case ParsedAttr::AT_AMDGPUNumSGPR: | |||
6023 | handleAMDGPUNumSGPRAttr(S, D, AL); | |||
6024 | break; | |||
6025 | case ParsedAttr::AT_AMDGPUNumVGPR: | |||
6026 | handleAMDGPUNumVGPRAttr(S, D, AL); | |||
6027 | break; | |||
6028 | case ParsedAttr::AT_AVRSignal: | |||
6029 | handleAVRSignalAttr(S, D, AL); | |||
6030 | break; | |||
6031 | case ParsedAttr::AT_IBAction: | |||
6032 | handleSimpleAttribute<IBActionAttr>(S, D, AL); | |||
6033 | break; | |||
6034 | case ParsedAttr::AT_IBOutlet: | |||
6035 | handleIBOutlet(S, D, AL); | |||
6036 | break; | |||
6037 | case ParsedAttr::AT_IBOutletCollection: | |||
6038 | handleIBOutletCollection(S, D, AL); | |||
6039 | break; | |||
6040 | case ParsedAttr::AT_IFunc: | |||
6041 | handleIFuncAttr(S, D, AL); | |||
6042 | break; | |||
6043 | case ParsedAttr::AT_Alias: | |||
6044 | handleAliasAttr(S, D, AL); | |||
6045 | break; | |||
6046 | case ParsedAttr::AT_Aligned: | |||
6047 | handleAlignedAttr(S, D, AL); | |||
6048 | break; | |||
6049 | case ParsedAttr::AT_AlignValue: | |||
6050 | handleAlignValueAttr(S, D, AL); | |||
6051 | break; | |||
6052 | case ParsedAttr::AT_AllocSize: | |||
6053 | handleAllocSizeAttr(S, D, AL); | |||
6054 | break; | |||
6055 | case ParsedAttr::AT_AlwaysInline: | |||
6056 | handleAlwaysInlineAttr(S, D, AL); | |||
6057 | break; | |||
6058 | case ParsedAttr::AT_Artificial: | |||
6059 | handleSimpleAttribute<ArtificialAttr>(S, D, AL); | |||
6060 | break; | |||
6061 | case ParsedAttr::AT_AnalyzerNoReturn: | |||
6062 | handleAnalyzerNoReturnAttr(S, D, AL); | |||
6063 | break; | |||
6064 | case ParsedAttr::AT_TLSModel: | |||
6065 | handleTLSModelAttr(S, D, AL); | |||
6066 | break; | |||
6067 | case ParsedAttr::AT_Annotate: | |||
6068 | handleAnnotateAttr(S, D, AL); | |||
6069 | break; | |||
6070 | case ParsedAttr::AT_Availability: | |||
6071 | handleAvailabilityAttr(S, D, AL); | |||
6072 | break; | |||
6073 | case ParsedAttr::AT_CarriesDependency: | |||
6074 | handleDependencyAttr(S, scope, D, AL); | |||
6075 | break; | |||
6076 | case ParsedAttr::AT_CPUDispatch: | |||
6077 | case ParsedAttr::AT_CPUSpecific: | |||
6078 | handleCPUSpecificAttr(S, D, AL); | |||
6079 | break; | |||
6080 | case ParsedAttr::AT_Common: | |||
6081 | handleCommonAttr(S, D, AL); | |||
6082 | break; | |||
6083 | case ParsedAttr::AT_CUDAConstant: | |||
6084 | handleConstantAttr(S, D, AL); | |||
6085 | break; | |||
6086 | case ParsedAttr::AT_PassObjectSize: | |||
6087 | handlePassObjectSizeAttr(S, D, AL); | |||
6088 | break; | |||
6089 | case ParsedAttr::AT_Constructor: | |||
6090 | handleConstructorAttr(S, D, AL); | |||
6091 | break; | |||
6092 | case ParsedAttr::AT_CXX11NoReturn: | |||
6093 | handleSimpleAttribute<CXX11NoReturnAttr>(S, D, AL); | |||
6094 | break; | |||
6095 | case ParsedAttr::AT_Deprecated: | |||
6096 | handleDeprecatedAttr(S, D, AL); | |||
6097 | break; | |||
6098 | case ParsedAttr::AT_Destructor: | |||
6099 | handleDestructorAttr(S, D, AL); | |||
6100 | break; | |||
6101 | case ParsedAttr::AT_EnableIf: | |||
6102 | handleEnableIfAttr(S, D, AL); | |||
6103 | break; | |||
6104 | case ParsedAttr::AT_DiagnoseIf: | |||
6105 | handleDiagnoseIfAttr(S, D, AL); | |||
6106 | break; | |||
6107 | case ParsedAttr::AT_ExtVectorType: | |||
6108 | handleExtVectorTypeAttr(S, D, AL); | |||
6109 | break; | |||
6110 | case ParsedAttr::AT_ExternalSourceSymbol: | |||
6111 | handleExternalSourceSymbolAttr(S, D, AL); | |||
6112 | break; | |||
6113 | case ParsedAttr::AT_MinSize: | |||
6114 | handleMinSizeAttr(S, D, AL); | |||
6115 | break; | |||
6116 | case ParsedAttr::AT_OptimizeNone: | |||
6117 | handleOptimizeNoneAttr(S, D, AL); | |||
6118 | break; | |||
6119 | case ParsedAttr::AT_FlagEnum: | |||
6120 | handleSimpleAttribute<FlagEnumAttr>(S, D, AL); | |||
6121 | break; | |||
6122 | case ParsedAttr::AT_EnumExtensibility: | |||
6123 | handleEnumExtensibilityAttr(S, D, AL); | |||
6124 | break; | |||
6125 | case ParsedAttr::AT_Flatten: | |||
6126 | handleSimpleAttribute<FlattenAttr>(S, D, AL); | |||
6127 | break; | |||
6128 | case ParsedAttr::AT_Format: | |||
6129 | handleFormatAttr(S, D, AL); | |||
6130 | break; | |||
6131 | case ParsedAttr::AT_FormatArg: | |||
6132 | handleFormatArgAttr(S, D, AL); | |||
6133 | break; | |||
6134 | case ParsedAttr::AT_CUDAGlobal: | |||
6135 | handleGlobalAttr(S, D, AL); | |||
6136 | break; | |||
6137 | case ParsedAttr::AT_CUDADevice: | |||
6138 | handleSimpleAttributeWithExclusions<CUDADeviceAttr, CUDAGlobalAttr>(S, D, | |||
6139 | AL); | |||
6140 | break; | |||
6141 | case ParsedAttr::AT_CUDAHost: | |||
6142 | handleSimpleAttributeWithExclusions<CUDAHostAttr, CUDAGlobalAttr>(S, D, AL); | |||
6143 | break; | |||
6144 | case ParsedAttr::AT_GNUInline: | |||
6145 | handleGNUInlineAttr(S, D, AL); | |||
6146 | break; | |||
6147 | case ParsedAttr::AT_CUDALaunchBounds: | |||
6148 | handleLaunchBoundsAttr(S, D, AL); | |||
6149 | break; | |||
6150 | case ParsedAttr::AT_Restrict: | |||
6151 | handleRestrictAttr(S, D, AL); | |||
6152 | break; | |||
6153 | case ParsedAttr::AT_MayAlias: | |||
6154 | handleSimpleAttribute<MayAliasAttr>(S, D, AL); | |||
6155 | break; | |||
6156 | case ParsedAttr::AT_Mode: | |||
6157 | handleModeAttr(S, D, AL); | |||
6158 | break; | |||
6159 | case ParsedAttr::AT_NoAlias: | |||
6160 | handleSimpleAttribute<NoAliasAttr>(S, D, AL); | |||
6161 | break; | |||
6162 | case ParsedAttr::AT_NoCommon: | |||
6163 | handleSimpleAttribute<NoCommonAttr>(S, D, AL); | |||
6164 | break; | |||
6165 | case ParsedAttr::AT_NoSplitStack: | |||
6166 | handleSimpleAttribute<NoSplitStackAttr>(S, D, AL); | |||
6167 | break; | |||
6168 | case ParsedAttr::AT_NonNull: | |||
6169 | if (auto *PVD = dyn_cast<ParmVarDecl>(D)) | |||
6170 | handleNonNullAttrParameter(S, PVD, AL); | |||
6171 | else | |||
6172 | handleNonNullAttr(S, D, AL); | |||
6173 | break; | |||
6174 | case ParsedAttr::AT_ReturnsNonNull: | |||
6175 | handleReturnsNonNullAttr(S, D, AL); | |||
6176 | break; | |||
6177 | case ParsedAttr::AT_NoEscape: | |||
6178 | handleNoEscapeAttr(S, D, AL); | |||
6179 | break; | |||
6180 | case ParsedAttr::AT_AssumeAligned: | |||
6181 | handleAssumeAlignedAttr(S, D, AL); | |||
6182 | break; | |||
6183 | case ParsedAttr::AT_AllocAlign: | |||
6184 | handleAllocAlignAttr(S, D, AL); | |||
6185 | break; | |||
6186 | case ParsedAttr::AT_Overloadable: | |||
6187 | handleSimpleAttribute<OverloadableAttr>(S, D, AL); | |||
6188 | break; | |||
6189 | case ParsedAttr::AT_Ownership: | |||
6190 | handleOwnershipAttr(S, D, AL); | |||
6191 | break; | |||
6192 | case ParsedAttr::AT_Cold: | |||
6193 | handleSimpleAttributeWithExclusions<ColdAttr, HotAttr>(S, D, AL); | |||
6194 | break; | |||
6195 | case ParsedAttr::AT_Hot: | |||
6196 | handleSimpleAttributeWithExclusions<HotAttr, ColdAttr>(S, D, AL); | |||
6197 | break; | |||
6198 | case ParsedAttr::AT_Naked: | |||
6199 | handleNakedAttr(S, D, AL); | |||
6200 | break; | |||
6201 | case ParsedAttr::AT_NoReturn: | |||
6202 | handleNoReturnAttr(S, D, AL); | |||
6203 | break; | |||
6204 | case ParsedAttr::AT_AnyX86NoCfCheck: | |||
6205 | handleNoCfCheckAttr(S, D, AL); | |||
6206 | break; | |||
6207 | case ParsedAttr::AT_NoThrow: | |||
6208 | handleSimpleAttribute<NoThrowAttr>(S, D, AL); | |||
6209 | break; | |||
6210 | case ParsedAttr::AT_CUDAShared: | |||
6211 | handleSharedAttr(S, D, AL); | |||
6212 | break; | |||
6213 | case ParsedAttr::AT_VecReturn: | |||
6214 | handleVecReturnAttr(S, D, AL); | |||
6215 | break; | |||
6216 | case ParsedAttr::AT_ObjCOwnership: | |||
6217 | handleObjCOwnershipAttr(S, D, AL); | |||
6218 | break; | |||
6219 | case ParsedAttr::AT_ObjCPreciseLifetime: | |||
6220 | handleObjCPreciseLifetimeAttr(S, D, AL); | |||
6221 | break; | |||
6222 | case ParsedAttr::AT_ObjCReturnsInnerPointer: | |||
6223 | handleObjCReturnsInnerPointerAttr(S, D, AL); | |||
6224 | break; | |||
6225 | case ParsedAttr::AT_ObjCRequiresSuper: | |||
6226 | handleObjCRequiresSuperAttr(S, D, AL); | |||
6227 | break; | |||
6228 | case ParsedAttr::AT_ObjCBridge: | |||
6229 | handleObjCBridgeAttr(S, D, AL); | |||
6230 | break; | |||
6231 | case ParsedAttr::AT_ObjCBridgeMutable: | |||
6232 | handleObjCBridgeMutableAttr(S, D, AL); | |||
6233 | break; | |||
6234 | case ParsedAttr::AT_ObjCBridgeRelated: | |||
6235 | handleObjCBridgeRelatedAttr(S, D, AL); | |||
6236 | break; | |||
6237 | case ParsedAttr::AT_ObjCDesignatedInitializer: | |||
6238 | handleObjCDesignatedInitializer(S, D, AL); | |||
6239 | break; | |||
6240 | case ParsedAttr::AT_ObjCRuntimeName: | |||
6241 | handleObjCRuntimeName(S, D, AL); | |||
6242 | break; | |||
6243 | case ParsedAttr::AT_ObjCRuntimeVisible: | |||
6244 | handleSimpleAttribute<ObjCRuntimeVisibleAttr>(S, D, AL); | |||
6245 | break; | |||
6246 | case ParsedAttr::AT_ObjCBoxable: | |||
6247 | handleObjCBoxable(S, D, AL); | |||
6248 | break; | |||
6249 | case ParsedAttr::AT_CFAuditedTransfer: | |||
6250 | handleSimpleAttributeWithExclusions<CFAuditedTransferAttr, | |||
6251 | CFUnknownTransferAttr>(S, D, AL); | |||
6252 | break; | |||
6253 | case ParsedAttr::AT_CFUnknownTransfer: | |||
6254 | handleSimpleAttributeWithExclusions<CFUnknownTransferAttr, | |||
6255 | CFAuditedTransferAttr>(S, D, AL); | |||
6256 | break; | |||
6257 | case ParsedAttr::AT_CFConsumed: | |||
6258 | case ParsedAttr::AT_NSConsumed: | |||
6259 | handleNSConsumedAttr(S, D, AL); | |||
6260 | break; | |||
6261 | case ParsedAttr::AT_NSConsumesSelf: | |||
6262 | handleSimpleAttribute<NSConsumesSelfAttr>(S, D, AL); | |||
6263 | break; | |||
6264 | case ParsedAttr::AT_NSReturnsAutoreleased: | |||
6265 | case ParsedAttr::AT_NSReturnsNotRetained: | |||
6266 | case ParsedAttr::AT_CFReturnsNotRetained: | |||
6267 | case ParsedAttr::AT_NSReturnsRetained: | |||
6268 | case ParsedAttr::AT_CFReturnsRetained: | |||
6269 | handleNSReturnsRetainedAttr(S, D, AL); | |||
6270 | break; | |||
6271 | case ParsedAttr::AT_WorkGroupSizeHint: | |||
6272 | handleWorkGroupSize<WorkGroupSizeHintAttr>(S, D, AL); | |||
6273 | break; | |||
6274 | case ParsedAttr::AT_ReqdWorkGroupSize: | |||
6275 | handleWorkGroupSize<ReqdWorkGroupSizeAttr>(S, D, AL); | |||
6276 | break; | |||
6277 | case ParsedAttr::AT_OpenCLIntelReqdSubGroupSize: | |||
6278 | handleSubGroupSize(S, D, AL); | |||
6279 | break; | |||
6280 | case ParsedAttr::AT_VecTypeHint: | |||
6281 | handleVecTypeHint(S, D, AL); | |||
6282 | break; | |||
6283 | case ParsedAttr::AT_RequireConstantInit: | |||
6284 | handleSimpleAttribute<RequireConstantInitAttr>(S, D, AL); | |||
6285 | break; | |||
6286 | case ParsedAttr::AT_InitPriority: | |||
6287 | handleInitPriorityAttr(S, D, AL); | |||
6288 | break; | |||
6289 | case ParsedAttr::AT_Packed: | |||
6290 | handlePackedAttr(S, D, AL); | |||
6291 | break; | |||
6292 | case ParsedAttr::AT_Section: | |||
6293 | handleSectionAttr(S, D, AL); | |||
6294 | break; | |||
6295 | case ParsedAttr::AT_CodeSeg: | |||
6296 | handleCodeSegAttr(S, D, AL); | |||
6297 | break; | |||
6298 | case ParsedAttr::AT_Target: | |||
6299 | handleTargetAttr(S, D, AL); | |||
6300 | break; | |||
6301 | case ParsedAttr::AT_MinVectorWidth: | |||
6302 | handleMinVectorWidthAttr(S, D, AL); | |||
6303 | break; | |||
6304 | case ParsedAttr::AT_Unavailable: | |||
6305 | handleAttrWithMessage<UnavailableAttr>(S, D, AL); | |||
6306 | break; | |||
6307 | case ParsedAttr::AT_ArcWeakrefUnavailable: | |||
6308 | handleSimpleAttribute<ArcWeakrefUnavailableAttr>(S, D, AL); | |||
6309 | break; | |||
6310 | case ParsedAttr::AT_ObjCRootClass: | |||
6311 | handleSimpleAttribute<ObjCRootClassAttr>(S, D, AL); | |||
6312 | break; | |||
6313 | case ParsedAttr::AT_ObjCSubclassingRestricted: | |||
6314 | handleSimpleAttribute<ObjCSubclassingRestrictedAttr>(S, D, AL); | |||
6315 | break; | |||
6316 | case ParsedAttr::AT_ObjCExplicitProtocolImpl: | |||
6317 | handleObjCSuppresProtocolAttr(S, D, AL); | |||
6318 | break; | |||
6319 | case ParsedAttr::AT_ObjCRequiresPropertyDefs: | |||
6320 | handleSimpleAttribute<ObjCRequiresPropertyDefsAttr>(S, D, AL); | |||
6321 | break; | |||
6322 | case ParsedAttr::AT_Unused: | |||
6323 | handleUnusedAttr(S, D, AL); | |||
6324 | break; | |||
6325 | case ParsedAttr::AT_ReturnsTwice: | |||
6326 | handleSimpleAttribute<ReturnsTwiceAttr>(S, D, AL); | |||
6327 | break; | |||
6328 | case ParsedAttr::AT_NotTailCalled: | |||
6329 | handleSimpleAttributeWithExclusions<NotTailCalledAttr, AlwaysInlineAttr>( | |||
6330 | S, D, AL); | |||
6331 | break; | |||
6332 | case ParsedAttr::AT_DisableTailCalls: | |||
6333 | handleSimpleAttributeWithExclusions<DisableTailCallsAttr, NakedAttr>(S, D, | |||
6334 | AL); | |||
6335 | break; | |||
6336 | case ParsedAttr::AT_Used: | |||
6337 | handleSimpleAttribute<UsedAttr>(S, D, AL); | |||
6338 | break; | |||
6339 | case ParsedAttr::AT_Visibility: | |||
6340 | handleVisibilityAttr(S, D, AL, false); | |||
6341 | break; | |||
6342 | case ParsedAttr::AT_TypeVisibility: | |||
6343 | handleVisibilityAttr(S, D, AL, true); | |||
6344 | break; | |||
6345 | case ParsedAttr::AT_WarnUnused: | |||
6346 | handleSimpleAttribute<WarnUnusedAttr>(S, D, AL); | |||
6347 | break; | |||
6348 | case ParsedAttr::AT_WarnUnusedResult: | |||
6349 | handleWarnUnusedResult(S, D, AL); | |||
6350 | break; | |||
6351 | case ParsedAttr::AT_Weak: | |||
6352 | handleSimpleAttribute<WeakAttr>(S, D, AL); | |||
6353 | break; | |||
6354 | case ParsedAttr::AT_WeakRef: | |||
6355 | handleWeakRefAttr(S, D, AL); | |||
6356 | break; | |||
6357 | case ParsedAttr::AT_WeakImport: | |||
6358 | handleWeakImportAttr(S, D, AL); | |||
6359 | break; | |||
6360 | case ParsedAttr::AT_TransparentUnion: | |||
6361 | handleTransparentUnionAttr(S, D, AL); | |||
6362 | break; | |||
6363 | case ParsedAttr::AT_ObjCException: | |||
6364 | handleSimpleAttribute<ObjCExceptionAttr>(S, D, AL); | |||
6365 | break; | |||
6366 | case ParsedAttr::AT_ObjCMethodFamily: | |||
6367 | handleObjCMethodFamilyAttr(S, D, AL); | |||
6368 | break; | |||
6369 | case ParsedAttr::AT_ObjCNSObject: | |||
6370 | handleObjCNSObject(S, D, AL); | |||
6371 | break; | |||
6372 | case ParsedAttr::AT_ObjCIndependentClass: | |||
6373 | handleObjCIndependentClass(S, D, AL); | |||
6374 | break; | |||
6375 | case ParsedAttr::AT_Blocks: | |||
6376 | handleBlocksAttr(S, D, AL); | |||
6377 | break; | |||
6378 | case ParsedAttr::AT_Sentinel: | |||
6379 | handleSentinelAttr(S, D, AL); | |||
6380 | break; | |||
6381 | case ParsedAttr::AT_Const: | |||
6382 | handleSimpleAttribute<ConstAttr>(S, D, AL); | |||
6383 | break; | |||
6384 | case ParsedAttr::AT_Pure: | |||
6385 | handleSimpleAttribute<PureAttr>(S, D, AL); | |||
6386 | break; | |||
6387 | case ParsedAttr::AT_Cleanup: | |||
6388 | handleCleanupAttr(S, D, AL); | |||
6389 | break; | |||
6390 | case ParsedAttr::AT_NoDebug: | |||
6391 | handleNoDebugAttr(S, D, AL); | |||
6392 | break; | |||
6393 | case ParsedAttr::AT_NoDuplicate: | |||
6394 | handleSimpleAttribute<NoDuplicateAttr>(S, D, AL); | |||
6395 | break; | |||
6396 | case ParsedAttr::AT_Convergent: | |||
6397 | handleSimpleAttribute<ConvergentAttr>(S, D, AL); | |||
6398 | break; | |||
6399 | case ParsedAttr::AT_NoInline: | |||
6400 | handleSimpleAttribute<NoInlineAttr>(S, D, AL); | |||
6401 | break; | |||
6402 | case ParsedAttr::AT_NoInstrumentFunction: // Interacts with -pg. | |||
6403 | handleSimpleAttribute<NoInstrumentFunctionAttr>(S, D, AL); | |||
6404 | break; | |||
6405 | case ParsedAttr::AT_NoStackProtector: | |||
6406 | // Interacts with -fstack-protector options. | |||
6407 | handleSimpleAttribute<NoStackProtectorAttr>(S, D, AL); | |||
6408 | break; | |||
6409 | case ParsedAttr::AT_StdCall: | |||
6410 | case ParsedAttr::AT_CDecl: | |||
6411 | case ParsedAttr::AT_FastCall: | |||
6412 | case ParsedAttr::AT_ThisCall: | |||
6413 | case ParsedAttr::AT_Pascal: | |||
6414 | case ParsedAttr::AT_RegCall: | |||
6415 | case ParsedAttr::AT_SwiftCall: | |||
6416 | case ParsedAttr::AT_VectorCall: | |||
6417 | case ParsedAttr::AT_MSABI: | |||
6418 | case ParsedAttr::AT_SysVABI: | |||
6419 | case ParsedAttr::AT_Pcs: | |||
6420 | case ParsedAttr::AT_IntelOclBicc: | |||
6421 | case ParsedAttr::AT_PreserveMost: | |||
6422 | case ParsedAttr::AT_PreserveAll: | |||
6423 | handleCallConvAttr(S, D, AL); | |||
6424 | break; | |||
6425 | case ParsedAttr::AT_Suppress: | |||
6426 | handleSuppressAttr(S, D, AL); | |||
6427 | break; | |||
6428 | case ParsedAttr::AT_OpenCLKernel: | |||
6429 | handleSimpleAttribute<OpenCLKernelAttr>(S, D, AL); | |||
6430 | break; | |||
6431 | case ParsedAttr::AT_OpenCLAccess: | |||
6432 | handleOpenCLAccessAttr(S, D, AL); | |||
6433 | break; | |||
6434 | case ParsedAttr::AT_OpenCLNoSVM: | |||
6435 | handleOpenCLNoSVMAttr(S, D, AL); | |||
6436 | break; | |||
6437 | case ParsedAttr::AT_SwiftContext: | |||
6438 | handleParameterABIAttr(S, D, AL, ParameterABI::SwiftContext); | |||
6439 | break; | |||
6440 | case ParsedAttr::AT_SwiftErrorResult: | |||
6441 | handleParameterABIAttr(S, D, AL, ParameterABI::SwiftErrorResult); | |||
6442 | break; | |||
6443 | case ParsedAttr::AT_SwiftIndirectResult: | |||
6444 | handleParameterABIAttr(S, D, AL, ParameterABI::SwiftIndirectResult); | |||
6445 | break; | |||
6446 | case ParsedAttr::AT_InternalLinkage: | |||
6447 | handleInternalLinkageAttr(S, D, AL); | |||
6448 | break; | |||
6449 | case ParsedAttr::AT_LTOVisibilityPublic: | |||
6450 | handleSimpleAttribute<LTOVisibilityPublicAttr>(S, D, AL); | |||
6451 | break; | |||
6452 | ||||
6453 | // Microsoft attributes: | |||
6454 | case ParsedAttr::AT_EmptyBases: | |||
6455 | handleSimpleAttribute<EmptyBasesAttr>(S, D, AL); | |||
6456 | break; | |||
6457 | case ParsedAttr::AT_LayoutVersion: | |||
6458 | handleLayoutVersion(S, D, AL); | |||
6459 | break; | |||
6460 | case ParsedAttr::AT_TrivialABI: | |||
6461 | handleSimpleAttribute<TrivialABIAttr>(S, D, AL); | |||
6462 | break; | |||
6463 | case ParsedAttr::AT_MSNoVTable: | |||
6464 | handleSimpleAttribute<MSNoVTableAttr>(S, D, AL); | |||
6465 | break; | |||
6466 | case ParsedAttr::AT_MSStruct: | |||
6467 | handleSimpleAttribute<MSStructAttr>(S, D, AL); | |||
6468 | break; | |||
6469 | case ParsedAttr::AT_Uuid: | |||
6470 | handleUuidAttr(S, D, AL); | |||
6471 | break; | |||
6472 | case ParsedAttr::AT_MSInheritance: | |||
6473 | handleMSInheritanceAttr(S, D, AL); | |||
6474 | break; | |||
6475 | case ParsedAttr::AT_SelectAny: | |||
6476 | handleSimpleAttribute<SelectAnyAttr>(S, D, AL); | |||
6477 | break; | |||
6478 | case ParsedAttr::AT_Thread: | |||
6479 | handleDeclspecThreadAttr(S, D, AL); | |||
6480 | break; | |||
6481 | ||||
6482 | case ParsedAttr::AT_AbiTag: | |||
6483 | handleAbiTagAttr(S, D, AL); | |||
6484 | break; | |||
6485 | ||||
6486 | // Thread safety attributes: | |||
6487 | case ParsedAttr::AT_AssertExclusiveLock: | |||
6488 | handleAssertExclusiveLockAttr(S, D, AL); | |||
6489 | break; | |||
6490 | case ParsedAttr::AT_AssertSharedLock: | |||
6491 | handleAssertSharedLockAttr(S, D, AL); | |||
6492 | break; | |||
6493 | case ParsedAttr::AT_GuardedVar: | |||
6494 | handleSimpleAttribute<GuardedVarAttr>(S, D, AL); | |||
6495 | break; | |||
6496 | case ParsedAttr::AT_PtGuardedVar: | |||
6497 | handlePtGuardedVarAttr(S, D, AL); | |||
6498 | break; | |||
6499 | case ParsedAttr::AT_ScopedLockable: | |||
6500 | handleSimpleAttribute<ScopedLockableAttr>(S, D, AL); | |||
6501 | break; | |||
6502 | case ParsedAttr::AT_NoSanitize: | |||
6503 | handleNoSanitizeAttr(S, D, AL); | |||
6504 | break; | |||
6505 | case ParsedAttr::AT_NoSanitizeSpecific: | |||
6506 | handleNoSanitizeSpecificAttr(S, D, AL); | |||
6507 | break; | |||
6508 | case ParsedAttr::AT_NoThreadSafetyAnalysis: | |||
6509 | handleSimpleAttribute<NoThreadSafetyAnalysisAttr>(S, D, AL); | |||
6510 | break; | |||
6511 | case ParsedAttr::AT_GuardedBy: | |||
6512 | handleGuardedByAttr(S, D, AL); | |||
6513 | break; | |||
6514 | case ParsedAttr::AT_PtGuardedBy: | |||
6515 | handlePtGuardedByAttr(S, D, AL); | |||
6516 | break; | |||
6517 | case ParsedAttr::AT_ExclusiveTrylockFunction: | |||
6518 | handleExclusiveTrylockFunctionAttr(S, D, AL); | |||
6519 | break; | |||
6520 | case ParsedAttr::AT_LockReturned: | |||
6521 | handleLockReturnedAttr(S, D, AL); | |||
6522 | break; | |||
6523 | case ParsedAttr::AT_LocksExcluded: | |||
6524 | handleLocksExcludedAttr(S, D, AL); | |||
6525 | break; | |||
6526 | case ParsedAttr::AT_SharedTrylockFunction: | |||
6527 | handleSharedTrylockFunctionAttr(S, D, AL); | |||
6528 | break; | |||
6529 | case ParsedAttr::AT_AcquiredBefore: | |||
6530 | handleAcquiredBeforeAttr(S, D, AL); | |||
6531 | break; | |||
6532 | case ParsedAttr::AT_AcquiredAfter: | |||
6533 | handleAcquiredAfterAttr(S, D, AL); | |||
6534 | break; | |||
6535 | ||||
6536 | // Capability analysis attributes. | |||
6537 | case ParsedAttr::AT_Capability: | |||
6538 | case ParsedAttr::AT_Lockable: | |||
6539 | handleCapabilityAttr(S, D, AL); | |||
6540 | break; | |||
6541 | case ParsedAttr::AT_RequiresCapability: | |||
6542 | handleRequiresCapabilityAttr(S, D, AL); | |||
6543 | break; | |||
6544 | ||||
6545 | case ParsedAttr::AT_AssertCapability: | |||
6546 | handleAssertCapabilityAttr(S, D, AL); | |||
6547 | break; | |||
6548 | case ParsedAttr::AT_AcquireCapability: | |||
6549 | handleAcquireCapabilityAttr(S, D, AL); | |||
6550 | break; | |||
6551 | case ParsedAttr::AT_ReleaseCapability: | |||
6552 | handleReleaseCapabilityAttr(S, D, AL); | |||
6553 | break; | |||
6554 | case ParsedAttr::AT_TryAcquireCapability: | |||
6555 | handleTryAcquireCapabilityAttr(S, D, AL); | |||
6556 | break; | |||
6557 | ||||
6558 | // Consumed analysis attributes. | |||
6559 | case ParsedAttr::AT_Consumable: | |||
6560 | handleConsumableAttr(S, D, AL); | |||
6561 | break; | |||
6562 | case ParsedAttr::AT_ConsumableAutoCast: | |||
6563 | handleSimpleAttribute<ConsumableAutoCastAttr>(S, D, AL); | |||
6564 | break; | |||
6565 | case ParsedAttr::AT_ConsumableSetOnRead: | |||
6566 | handleSimpleAttribute<ConsumableSetOnReadAttr>(S, D, AL); | |||
6567 | break; | |||
6568 | case ParsedAttr::AT_CallableWhen: | |||
6569 | handleCallableWhenAttr(S, D, AL); | |||
6570 | break; | |||
6571 | case ParsedAttr::AT_ParamTypestate: | |||
6572 | handleParamTypestateAttr(S, D, AL); | |||
6573 | break; | |||
6574 | case ParsedAttr::AT_ReturnTypestate: | |||
6575 | handleReturnTypestateAttr(S, D, AL); | |||
6576 | break; | |||
6577 | case ParsedAttr::AT_SetTypestate: | |||
6578 | handleSetTypestateAttr(S, D, AL); | |||
6579 | break; | |||
6580 | case ParsedAttr::AT_TestTypestate: | |||
6581 | handleTestTypestateAttr(S, D, AL); | |||
6582 | break; | |||
6583 | ||||
6584 | // Type safety attributes. | |||
6585 | case ParsedAttr::AT_ArgumentWithTypeTag: | |||
6586 | handleArgumentWithTypeTagAttr(S, D, AL); | |||
6587 | break; | |||
6588 | case ParsedAttr::AT_TypeTagForDatatype: | |||
6589 | handleTypeTagForDatatypeAttr(S, D, AL); | |||
6590 | break; | |||
6591 | case ParsedAttr::AT_AnyX86NoCallerSavedRegisters: | |||
6592 | handleSimpleAttribute<AnyX86NoCallerSavedRegistersAttr>(S, D, AL); | |||
6593 | break; | |||
6594 | case ParsedAttr::AT_RenderScriptKernel: | |||
6595 | handleSimpleAttribute<RenderScriptKernelAttr>(S, D, AL); | |||
6596 | break; | |||
6597 | // XRay attributes. | |||
6598 | case ParsedAttr::AT_XRayInstrument: | |||
6599 | handleSimpleAttribute<XRayInstrumentAttr>(S, D, AL); | |||
6600 | break; | |||
6601 | case ParsedAttr::AT_XRayLogArgs: | |||
6602 | handleXRayLogArgsAttr(S, D, AL); | |||
6603 | break; | |||
6604 | } | |||
6605 | } | |||
6606 | ||||
6607 | /// ProcessDeclAttributeList - Apply all the decl attributes in the specified | |||
6608 | /// attribute list to the specified decl, ignoring any type attributes. | |||
6609 | void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, | |||
6610 | const ParsedAttributesView &AttrList, | |||
6611 | bool IncludeCXX11Attributes) { | |||
6612 | if (AttrList.empty()) | |||
6613 | return; | |||
6614 | ||||
6615 | for (const ParsedAttr &AL : AttrList) | |||
6616 | ProcessDeclAttribute(*this, S, D, AL, IncludeCXX11Attributes); | |||
6617 | ||||
6618 | // FIXME: We should be able to handle these cases in TableGen. | |||
6619 | // GCC accepts | |||
6620 | // static int a9 __attribute__((weakref)); | |||
6621 | // but that looks really pointless. We reject it. | |||
6622 | if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { | |||
6623 | Diag(AttrList.begin()->getLoc(), diag::err_attribute_weakref_without_alias) | |||
6624 | << cast<NamedDecl>(D); | |||
6625 | D->dropAttr<WeakRefAttr>(); | |||
6626 | return; | |||
6627 | } | |||
6628 | ||||
6629 | // FIXME: We should be able to handle this in TableGen as well. It would be | |||
6630 | // good to have a way to specify "these attributes must appear as a group", | |||
6631 | // for these. Additionally, it would be good to have a way to specify "these | |||
6632 | // attribute must never appear as a group" for attributes like cold and hot. | |||
6633 | if (!D->hasAttr<OpenCLKernelAttr>()) { | |||
6634 | // These attributes cannot be applied to a non-kernel function. | |||
6635 | if (const auto *A = D->getAttr<ReqdWorkGroupSizeAttr>()) { | |||
6636 | // FIXME: This emits a different error message than | |||
6637 | // diag::err_attribute_wrong_decl_type + ExpectedKernelFunction. | |||
6638 | Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A; | |||
6639 | D->setInvalidDecl(); | |||
6640 | } else if (const auto *A = D->getAttr<WorkGroupSizeHintAttr>()) { | |||
6641 | Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A; | |||
6642 | D->setInvalidDecl(); | |||
6643 | } else if (const auto *A = D->getAttr<VecTypeHintAttr>()) { | |||
6644 | Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A; | |||
6645 | D->setInvalidDecl(); | |||
6646 | } else if (const auto *A = D->getAttr<OpenCLIntelReqdSubGroupSizeAttr>()) { | |||
6647 | Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A; | |||
6648 | D->setInvalidDecl(); | |||
6649 | } else if (!D->hasAttr<CUDAGlobalAttr>()) { | |||
6650 | if (const auto *A = D->getAttr<AMDGPUFlatWorkGroupSizeAttr>()) { | |||
6651 | Diag(D->getLocation(), diag::err_attribute_wrong_decl_type) | |||
6652 | << A << ExpectedKernelFunction; | |||
6653 | D->setInvalidDecl(); | |||
6654 | } else if (const auto *A = D->getAttr<AMDGPUWavesPerEUAttr>()) { | |||
6655 | Diag(D->getLocation(), diag::err_attribute_wrong_decl_type) | |||
6656 | << A << ExpectedKernelFunction; | |||
6657 | D->setInvalidDecl(); | |||
6658 | } else if (const auto *A = D->getAttr<AMDGPUNumSGPRAttr>()) { | |||
6659 | Diag(D->getLocation(), diag::err_attribute_wrong_decl_type) | |||
6660 | << A << ExpectedKernelFunction; | |||
6661 | D->setInvalidDecl(); | |||
6662 | } else if (const auto *A = D->getAttr<AMDGPUNumVGPRAttr>()) { | |||
6663 | Diag(D->getLocation(), diag::err_attribute_wrong_decl_type) | |||
6664 | << A << ExpectedKernelFunction; | |||
6665 | D->setInvalidDecl(); | |||
6666 | } | |||
6667 | } | |||
6668 | } | |||
6669 | } | |||
6670 | ||||
6671 | // Helper for delayed processing TransparentUnion attribute. | |||
6672 | void Sema::ProcessDeclAttributeDelayed(Decl *D, | |||
6673 | const ParsedAttributesView &AttrList) { | |||
6674 | for (const ParsedAttr &AL : AttrList) | |||
6675 | if (AL.getKind() == ParsedAttr::AT_TransparentUnion) { | |||
6676 | handleTransparentUnionAttr(*this, D, AL); | |||
6677 | break; | |||
6678 | } | |||
6679 | } | |||
6680 | ||||
6681 | // Annotation attributes are the only attributes allowed after an access | |||
6682 | // specifier. | |||
6683 | bool Sema::ProcessAccessDeclAttributeList( | |||
6684 | AccessSpecDecl *ASDecl, const ParsedAttributesView &AttrList) { | |||
6685 | for (const ParsedAttr &AL : AttrList) { | |||
6686 | if (AL.getKind() == ParsedAttr::AT_Annotate) { | |||
6687 | ProcessDeclAttribute(*this, nullptr, ASDecl, AL, AL.isCXX11Attribute()); | |||
6688 | } else { | |||
6689 | Diag(AL.getLoc(), diag::err_only_annotate_after_access_spec); | |||
6690 | return true; | |||
6691 | } | |||
6692 | } | |||
6693 | return false; | |||
6694 | } | |||
6695 | ||||
6696 | /// checkUnusedDeclAttributes - Check a list of attributes to see if it | |||
6697 | /// contains any decl attributes that we should warn about. | |||
6698 | static void checkUnusedDeclAttributes(Sema &S, const ParsedAttributesView &A) { | |||
6699 | for (const ParsedAttr &AL : A) { | |||
6700 | // Only warn if the attribute is an unignored, non-type attribute. | |||
6701 | if (AL.isUsedAsTypeAttr() || AL.isInvalid()) | |||
6702 | continue; | |||
6703 | if (AL.getKind() == ParsedAttr::IgnoredAttribute) | |||
6704 | continue; | |||
6705 | ||||
6706 | if (AL.getKind() == ParsedAttr::UnknownAttribute) { | |||
6707 | S.Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored) | |||
6708 | << AL.getName() << AL.getRange(); | |||
6709 | } else { | |||
6710 | S.Diag(AL.getLoc(), diag::warn_attribute_not_on_decl) | |||
6711 | << AL.getName() << AL.getRange(); | |||
6712 | } | |||
6713 | } | |||
6714 | } | |||
6715 | ||||
6716 | /// checkUnusedDeclAttributes - Given a declarator which is not being | |||
6717 | /// used to build a declaration, complain about any decl attributes | |||
6718 | /// which might be lying around on it. | |||
6719 | void Sema::checkUnusedDeclAttributes(Declarator &D) { | |||
6720 | ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes()); | |||
6721 | ::checkUnusedDeclAttributes(*this, D.getAttributes()); | |||
6722 | for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) | |||
6723 | ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs()); | |||
6724 | } | |||
6725 | ||||
6726 | /// DeclClonePragmaWeak - clone existing decl (maybe definition), | |||
6727 | /// \#pragma weak needs a non-definition decl and source may not have one. | |||
6728 | NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, | |||
6729 | SourceLocation Loc) { | |||
6730 | assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND))(static_cast <bool> (isa<FunctionDecl>(ND) || isa <VarDecl>(ND)) ? void (0) : __assert_fail ("isa<FunctionDecl>(ND) || isa<VarDecl>(ND)" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 6730, __extension__ __PRETTY_FUNCTION__)); | |||
6731 | NamedDecl *NewD = nullptr; | |||
6732 | if (auto *FD = dyn_cast<FunctionDecl>(ND)) { | |||
6733 | FunctionDecl *NewFD; | |||
6734 | // FIXME: Missing call to CheckFunctionDeclaration(). | |||
6735 | // FIXME: Mangling? | |||
6736 | // FIXME: Is the qualifier info correct? | |||
6737 | // FIXME: Is the DeclContext correct? | |||
6738 | NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), | |||
6739 | Loc, Loc, DeclarationName(II), | |||
6740 | FD->getType(), FD->getTypeSourceInfo(), | |||
6741 | SC_None, false/*isInlineSpecified*/, | |||
6742 | FD->hasPrototype(), | |||
6743 | false/*isConstexprSpecified*/); | |||
6744 | NewD = NewFD; | |||
6745 | ||||
6746 | if (FD->getQualifier()) | |||
6747 | NewFD->setQualifierInfo(FD->getQualifierLoc()); | |||
6748 | ||||
6749 | // Fake up parameter variables; they are declared as if this were | |||
6750 | // a typedef. | |||
6751 | QualType FDTy = FD->getType(); | |||
6752 | if (const auto *FT = FDTy->getAs<FunctionProtoType>()) { | |||
6753 | SmallVector<ParmVarDecl*, 16> Params; | |||
6754 | for (const auto &AI : FT->param_types()) { | |||
6755 | ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, AI); | |||
6756 | Param->setScopeInfo(0, Params.size()); | |||
6757 | Params.push_back(Param); | |||
6758 | } | |||
6759 | NewFD->setParams(Params); | |||
6760 | } | |||
6761 | } else if (auto *VD = dyn_cast<VarDecl>(ND)) { | |||
6762 | NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), | |||
6763 | VD->getInnerLocStart(), VD->getLocation(), II, | |||
6764 | VD->getType(), VD->getTypeSourceInfo(), | |||
6765 | VD->getStorageClass()); | |||
6766 | if (VD->getQualifier()) | |||
6767 | cast<VarDecl>(NewD)->setQualifierInfo(VD->getQualifierLoc()); | |||
6768 | } | |||
6769 | return NewD; | |||
6770 | } | |||
6771 | ||||
6772 | /// DeclApplyPragmaWeak - A declaration (maybe definition) needs \#pragma weak | |||
6773 | /// applied to it, possibly with an alias. | |||
6774 | void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { | |||
6775 | if (W.getUsed()) return; // only do this once | |||
6776 | W.setUsed(true); | |||
6777 | if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) | |||
6778 | IdentifierInfo *NDId = ND->getIdentifier(); | |||
6779 | NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation()); | |||
6780 | NewD->addAttr(AliasAttr::CreateImplicit(Context, NDId->getName(), | |||
6781 | W.getLocation())); | |||
6782 | NewD->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation())); | |||
6783 | WeakTopLevelDecl.push_back(NewD); | |||
6784 | // FIXME: "hideous" code from Sema::LazilyCreateBuiltin | |||
6785 | // to insert Decl at TU scope, sorry. | |||
6786 | DeclContext *SavedContext = CurContext; | |||
6787 | CurContext = Context.getTranslationUnitDecl(); | |||
6788 | NewD->setDeclContext(CurContext); | |||
6789 | NewD->setLexicalDeclContext(CurContext); | |||
6790 | PushOnScopeChains(NewD, S); | |||
6791 | CurContext = SavedContext; | |||
6792 | } else { // just add weak to existing | |||
6793 | ND->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation())); | |||
6794 | } | |||
6795 | } | |||
6796 | ||||
6797 | void Sema::ProcessPragmaWeak(Scope *S, Decl *D) { | |||
6798 | // It's valid to "forward-declare" #pragma weak, in which case we | |||
6799 | // have to do this. | |||
6800 | LoadExternalWeakUndeclaredIdentifiers(); | |||
6801 | if (!WeakUndeclaredIdentifiers.empty()) { | |||
| ||||
6802 | NamedDecl *ND = nullptr; | |||
6803 | if (auto *VD = dyn_cast<VarDecl>(D)) | |||
6804 | if (VD->isExternC()) | |||
6805 | ND = VD; | |||
6806 | if (auto *FD = dyn_cast<FunctionDecl>(D)) | |||
6807 | if (FD->isExternC()) | |||
6808 | ND = FD; | |||
6809 | if (ND) { | |||
6810 | if (IdentifierInfo *Id = ND->getIdentifier()) { | |||
6811 | auto I = WeakUndeclaredIdentifiers.find(Id); | |||
6812 | if (I != WeakUndeclaredIdentifiers.end()) { | |||
6813 | WeakInfo W = I->second; | |||
6814 | DeclApplyPragmaWeak(S, ND, W); | |||
6815 | WeakUndeclaredIdentifiers[Id] = W; | |||
6816 | } | |||
6817 | } | |||
6818 | } | |||
6819 | } | |||
6820 | } | |||
6821 | ||||
6822 | /// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in | |||
6823 | /// it, apply them to D. This is a bit tricky because PD can have attributes | |||
6824 | /// specified in many different places, and we need to find and apply them all. | |||
6825 | void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { | |||
6826 | // Apply decl attributes from the DeclSpec if present. | |||
6827 | if (!PD.getDeclSpec().getAttributes().empty()) | |||
6828 | ProcessDeclAttributeList(S, D, PD.getDeclSpec().getAttributes()); | |||
6829 | ||||
6830 | // Walk the declarator structure, applying decl attributes that were in a type | |||
6831 | // position to the decl itself. This handles cases like: | |||
6832 | // int *__attr__(x)** D; | |||
6833 | // when X is a decl attribute. | |||
6834 | for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) | |||
6835 | ProcessDeclAttributeList(S, D, PD.getTypeObject(i).getAttrs(), | |||
6836 | /*IncludeCXX11Attributes=*/false); | |||
6837 | ||||
6838 | // Finally, apply any attributes on the decl itself. | |||
6839 | ProcessDeclAttributeList(S, D, PD.getAttributes()); | |||
6840 | ||||
6841 | // Apply additional attributes specified by '#pragma clang attribute'. | |||
6842 | AddPragmaAttributes(S, D); | |||
6843 | } | |||
6844 | ||||
6845 | /// Is the given declaration allowed to use a forbidden type? | |||
6846 | /// If so, it'll still be annotated with an attribute that makes it | |||
6847 | /// illegal to actually use. | |||
6848 | static bool isForbiddenTypeAllowed(Sema &S, Decl *D, | |||
6849 | const DelayedDiagnostic &diag, | |||
6850 | UnavailableAttr::ImplicitReason &reason) { | |||
6851 | // Private ivars are always okay. Unfortunately, people don't | |||
6852 | // always properly make their ivars private, even in system headers. | |||
6853 | // Plus we need to make fields okay, too. | |||
6854 | if (!isa<FieldDecl>(D) && !isa<ObjCPropertyDecl>(D) && | |||
6855 | !isa<FunctionDecl>(D)) | |||
6856 | return false; | |||
6857 | ||||
6858 | // Silently accept unsupported uses of __weak in both user and system | |||
6859 | // declarations when it's been disabled, for ease of integration with | |||
6860 | // -fno-objc-arc files. We do have to take some care against attempts | |||
6861 | // to define such things; for now, we've only done that for ivars | |||
6862 | // and properties. | |||
6863 | if ((isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D))) { | |||
6864 | if (diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_disabled || | |||
6865 | diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_no_runtime) { | |||
6866 | reason = UnavailableAttr::IR_ForbiddenWeak; | |||
6867 | return true; | |||
6868 | } | |||
6869 | } | |||
6870 | ||||
6871 | // Allow all sorts of things in system headers. | |||
6872 | if (S.Context.getSourceManager().isInSystemHeader(D->getLocation())) { | |||
6873 | // Currently, all the failures dealt with this way are due to ARC | |||
6874 | // restrictions. | |||
6875 | reason = UnavailableAttr::IR_ARCForbiddenType; | |||
6876 | return true; | |||
6877 | } | |||
6878 | ||||
6879 | return false; | |||
6880 | } | |||
6881 | ||||
6882 | /// Handle a delayed forbidden-type diagnostic. | |||
6883 | static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &DD, | |||
6884 | Decl *D) { | |||
6885 | auto Reason = UnavailableAttr::IR_None; | |||
6886 | if (D && isForbiddenTypeAllowed(S, D, DD, Reason)) { | |||
6887 | assert(Reason && "didn't set reason?")(static_cast <bool> (Reason && "didn't set reason?" ) ? void (0) : __assert_fail ("Reason && \"didn't set reason?\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 6887, __extension__ __PRETTY_FUNCTION__)); | |||
6888 | D->addAttr(UnavailableAttr::CreateImplicit(S.Context, "", Reason, DD.Loc)); | |||
6889 | return; | |||
6890 | } | |||
6891 | if (S.getLangOpts().ObjCAutoRefCount) | |||
6892 | if (const auto *FD = dyn_cast<FunctionDecl>(D)) { | |||
6893 | // FIXME: we may want to suppress diagnostics for all | |||
6894 | // kind of forbidden type messages on unavailable functions. | |||
6895 | if (FD->hasAttr<UnavailableAttr>() && | |||
6896 | DD.getForbiddenTypeDiagnostic() == | |||
6897 | diag::err_arc_array_param_no_ownership) { | |||
6898 | DD.Triggered = true; | |||
6899 | return; | |||
6900 | } | |||
6901 | } | |||
6902 | ||||
6903 | S.Diag(DD.Loc, DD.getForbiddenTypeDiagnostic()) | |||
6904 | << DD.getForbiddenTypeOperand() << DD.getForbiddenTypeArgument(); | |||
6905 | DD.Triggered = true; | |||
6906 | } | |||
6907 | ||||
6908 | static const AvailabilityAttr *getAttrForPlatform(ASTContext &Context, | |||
6909 | const Decl *D) { | |||
6910 | // Check each AvailabilityAttr to find the one for this platform. | |||
6911 | for (const auto *A : D->attrs()) { | |||
6912 | if (const auto *Avail = dyn_cast<AvailabilityAttr>(A)) { | |||
6913 | // FIXME: this is copied from CheckAvailability. We should try to | |||
6914 | // de-duplicate. | |||
6915 | ||||
6916 | // Check if this is an App Extension "platform", and if so chop off | |||
6917 | // the suffix for matching with the actual platform. | |||
6918 | StringRef ActualPlatform = Avail->getPlatform()->getName(); | |||
6919 | StringRef RealizedPlatform = ActualPlatform; | |||
6920 | if (Context.getLangOpts().AppExt) { | |||
6921 | size_t suffix = RealizedPlatform.rfind("_app_extension"); | |||
6922 | if (suffix != StringRef::npos) | |||
6923 | RealizedPlatform = RealizedPlatform.slice(0, suffix); | |||
6924 | } | |||
6925 | ||||
6926 | StringRef TargetPlatform = Context.getTargetInfo().getPlatformName(); | |||
6927 | ||||
6928 | // Match the platform name. | |||
6929 | if (RealizedPlatform == TargetPlatform) | |||
6930 | return Avail; | |||
6931 | } | |||
6932 | } | |||
6933 | return nullptr; | |||
6934 | } | |||
6935 | ||||
6936 | /// The diagnostic we should emit for \c D, and the declaration that | |||
6937 | /// originated it, or \c AR_Available. | |||
6938 | /// | |||
6939 | /// \param D The declaration to check. | |||
6940 | /// \param Message If non-null, this will be populated with the message from | |||
6941 | /// the availability attribute that is selected. | |||
6942 | static std::pair<AvailabilityResult, const NamedDecl *> | |||
6943 | ShouldDiagnoseAvailabilityOfDecl(const NamedDecl *D, std::string *Message) { | |||
6944 | AvailabilityResult Result = D->getAvailability(Message); | |||
6945 | ||||
6946 | // For typedefs, if the typedef declaration appears available look | |||
6947 | // to the underlying type to see if it is more restrictive. | |||
6948 | while (const auto *TD = dyn_cast<TypedefNameDecl>(D)) { | |||
6949 | if (Result == AR_Available) { | |||
6950 | if (const auto *TT = TD->getUnderlyingType()->getAs<TagType>()) { | |||
6951 | D = TT->getDecl(); | |||
6952 | Result = D->getAvailability(Message); | |||
6953 | continue; | |||
6954 | } | |||
6955 | } | |||
6956 | break; | |||
6957 | } | |||
6958 | ||||
6959 | // Forward class declarations get their attributes from their definition. | |||
6960 | if (const auto *IDecl = dyn_cast<ObjCInterfaceDecl>(D)) { | |||
6961 | if (IDecl->getDefinition()) { | |||
6962 | D = IDecl->getDefinition(); | |||
6963 | Result = D->getAvailability(Message); | |||
6964 | } | |||
6965 | } | |||
6966 | ||||
6967 | if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) | |||
6968 | if (Result == AR_Available) { | |||
6969 | const DeclContext *DC = ECD->getDeclContext(); | |||
6970 | if (const auto *TheEnumDecl = dyn_cast<EnumDecl>(DC)) { | |||
6971 | Result = TheEnumDecl->getAvailability(Message); | |||
6972 | D = TheEnumDecl; | |||
6973 | } | |||
6974 | } | |||
6975 | ||||
6976 | return {Result, D}; | |||
6977 | } | |||
6978 | ||||
6979 | ||||
6980 | /// whether we should emit a diagnostic for \c K and \c DeclVersion in | |||
6981 | /// the context of \c Ctx. For example, we should emit an unavailable diagnostic | |||
6982 | /// in a deprecated context, but not the other way around. | |||
6983 | static bool ShouldDiagnoseAvailabilityInContext(Sema &S, AvailabilityResult K, | |||
6984 | VersionTuple DeclVersion, | |||
6985 | Decl *Ctx) { | |||
6986 | assert(K != AR_Available && "Expected an unavailable declaration here!")(static_cast <bool> (K != AR_Available && "Expected an unavailable declaration here!" ) ? void (0) : __assert_fail ("K != AR_Available && \"Expected an unavailable declaration here!\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 6986, __extension__ __PRETTY_FUNCTION__)); | |||
6987 | ||||
6988 | // Checks if we should emit the availability diagnostic in the context of C. | |||
6989 | auto CheckContext = [&](const Decl *C) { | |||
6990 | if (K == AR_NotYetIntroduced) { | |||
6991 | if (const AvailabilityAttr *AA = getAttrForPlatform(S.Context, C)) | |||
6992 | if (AA->getIntroduced() >= DeclVersion) | |||
6993 | return true; | |||
6994 | } else if (K == AR_Deprecated) | |||
6995 | if (C->isDeprecated()) | |||
6996 | return true; | |||
6997 | ||||
6998 | if (C->isUnavailable()) | |||
6999 | return true; | |||
7000 | return false; | |||
7001 | }; | |||
7002 | ||||
7003 | do { | |||
7004 | if (CheckContext(Ctx)) | |||
7005 | return false; | |||
7006 | ||||
7007 | // An implementation implicitly has the availability of the interface. | |||
7008 | // Unless it is "+load" method. | |||
7009 | if (const auto *MethodD = dyn_cast<ObjCMethodDecl>(Ctx)) | |||
7010 | if (MethodD->isClassMethod() && | |||
7011 | MethodD->getSelector().getAsString() == "load") | |||
7012 | return true; | |||
7013 | ||||
7014 | if (const auto *CatOrImpl = dyn_cast<ObjCImplDecl>(Ctx)) { | |||
7015 | if (const ObjCInterfaceDecl *Interface = CatOrImpl->getClassInterface()) | |||
7016 | if (CheckContext(Interface)) | |||
7017 | return false; | |||
7018 | } | |||
7019 | // A category implicitly has the availability of the interface. | |||
7020 | else if (const auto *CatD = dyn_cast<ObjCCategoryDecl>(Ctx)) | |||
7021 | if (const ObjCInterfaceDecl *Interface = CatD->getClassInterface()) | |||
7022 | if (CheckContext(Interface)) | |||
7023 | return false; | |||
7024 | } while ((Ctx = cast_or_null<Decl>(Ctx->getDeclContext()))); | |||
7025 | ||||
7026 | return true; | |||
7027 | } | |||
7028 | ||||
7029 | static bool | |||
7030 | shouldDiagnoseAvailabilityByDefault(const ASTContext &Context, | |||
7031 | const VersionTuple &DeploymentVersion, | |||
7032 | const VersionTuple &DeclVersion) { | |||
7033 | const auto &Triple = Context.getTargetInfo().getTriple(); | |||
7034 | VersionTuple ForceAvailabilityFromVersion; | |||
7035 | switch (Triple.getOS()) { | |||
7036 | case llvm::Triple::IOS: | |||
7037 | case llvm::Triple::TvOS: | |||
7038 | ForceAvailabilityFromVersion = VersionTuple(/*Major=*/11); | |||
7039 | break; | |||
7040 | case llvm::Triple::WatchOS: | |||
7041 | ForceAvailabilityFromVersion = VersionTuple(/*Major=*/4); | |||
7042 | break; | |||
7043 | case llvm::Triple::Darwin: | |||
7044 | case llvm::Triple::MacOSX: | |||
7045 | ForceAvailabilityFromVersion = VersionTuple(/*Major=*/10, /*Minor=*/13); | |||
7046 | break; | |||
7047 | default: | |||
7048 | // New targets should always warn about availability. | |||
7049 | return Triple.getVendor() == llvm::Triple::Apple; | |||
7050 | } | |||
7051 | return DeploymentVersion >= ForceAvailabilityFromVersion || | |||
7052 | DeclVersion >= ForceAvailabilityFromVersion; | |||
7053 | } | |||
7054 | ||||
7055 | static NamedDecl *findEnclosingDeclToAnnotate(Decl *OrigCtx) { | |||
7056 | for (Decl *Ctx = OrigCtx; Ctx; | |||
7057 | Ctx = cast_or_null<Decl>(Ctx->getDeclContext())) { | |||
7058 | if (isa<TagDecl>(Ctx) || isa<FunctionDecl>(Ctx) || isa<ObjCMethodDecl>(Ctx)) | |||
7059 | return cast<NamedDecl>(Ctx); | |||
7060 | if (auto *CD = dyn_cast<ObjCContainerDecl>(Ctx)) { | |||
7061 | if (auto *Imp = dyn_cast<ObjCImplDecl>(Ctx)) | |||
7062 | return Imp->getClassInterface(); | |||
7063 | return CD; | |||
7064 | } | |||
7065 | } | |||
7066 | ||||
7067 | return dyn_cast<NamedDecl>(OrigCtx); | |||
7068 | } | |||
7069 | ||||
7070 | namespace { | |||
7071 | ||||
7072 | struct AttributeInsertion { | |||
7073 | StringRef Prefix; | |||
7074 | SourceLocation Loc; | |||
7075 | StringRef Suffix; | |||
7076 | ||||
7077 | static AttributeInsertion createInsertionAfter(const NamedDecl *D) { | |||
7078 | return {" ", D->getLocEnd(), ""}; | |||
7079 | } | |||
7080 | static AttributeInsertion createInsertionAfter(SourceLocation Loc) { | |||
7081 | return {" ", Loc, ""}; | |||
7082 | } | |||
7083 | static AttributeInsertion createInsertionBefore(const NamedDecl *D) { | |||
7084 | return {"", D->getLocStart(), "\n"}; | |||
7085 | } | |||
7086 | }; | |||
7087 | ||||
7088 | } // end anonymous namespace | |||
7089 | ||||
7090 | /// Tries to parse a string as ObjC method name. | |||
7091 | /// | |||
7092 | /// \param Name The string to parse. Expected to originate from availability | |||
7093 | /// attribute argument. | |||
7094 | /// \param SlotNames The vector that will be populated with slot names. In case | |||
7095 | /// of unsuccessful parsing can contain invalid data. | |||
7096 | /// \returns A number of method parameters if parsing was successful, None | |||
7097 | /// otherwise. | |||
7098 | static Optional<unsigned> | |||
7099 | tryParseObjCMethodName(StringRef Name, SmallVectorImpl<StringRef> &SlotNames, | |||
7100 | const LangOptions &LangOpts) { | |||
7101 | // Accept replacements starting with - or + as valid ObjC method names. | |||
7102 | if (!Name.empty() && (Name.front() == '-' || Name.front() == '+')) | |||
7103 | Name = Name.drop_front(1); | |||
7104 | if (Name.empty()) | |||
7105 | return None; | |||
7106 | Name.split(SlotNames, ':'); | |||
7107 | unsigned NumParams; | |||
7108 | if (Name.back() == ':') { | |||
7109 | // Remove an empty string at the end that doesn't represent any slot. | |||
7110 | SlotNames.pop_back(); | |||
7111 | NumParams = SlotNames.size(); | |||
7112 | } else { | |||
7113 | if (SlotNames.size() != 1) | |||
7114 | // Not a valid method name, just a colon-separated string. | |||
7115 | return None; | |||
7116 | NumParams = 0; | |||
7117 | } | |||
7118 | // Verify all slot names are valid. | |||
7119 | bool AllowDollar = LangOpts.DollarIdents; | |||
7120 | for (StringRef S : SlotNames) { | |||
7121 | if (S.empty()) | |||
7122 | continue; | |||
7123 | if (!isValidIdentifier(S, AllowDollar)) | |||
7124 | return None; | |||
7125 | } | |||
7126 | return NumParams; | |||
7127 | } | |||
7128 | ||||
7129 | /// Returns a source location in which it's appropriate to insert a new | |||
7130 | /// attribute for the given declaration \D. | |||
7131 | static Optional<AttributeInsertion> | |||
7132 | createAttributeInsertion(const NamedDecl *D, const SourceManager &SM, | |||
7133 | const LangOptions &LangOpts) { | |||
7134 | if (isa<ObjCPropertyDecl>(D)) | |||
7135 | return AttributeInsertion::createInsertionAfter(D); | |||
7136 | if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) { | |||
7137 | if (MD->hasBody()) | |||
7138 | return None; | |||
7139 | return AttributeInsertion::createInsertionAfter(D); | |||
7140 | } | |||
7141 | if (const auto *TD = dyn_cast<TagDecl>(D)) { | |||
7142 | SourceLocation Loc = | |||
7143 | Lexer::getLocForEndOfToken(TD->getInnerLocStart(), 0, SM, LangOpts); | |||
7144 | if (Loc.isInvalid()) | |||
7145 | return None; | |||
7146 | // Insert after the 'struct'/whatever keyword. | |||
7147 | return AttributeInsertion::createInsertionAfter(Loc); | |||
7148 | } | |||
7149 | return AttributeInsertion::createInsertionBefore(D); | |||
7150 | } | |||
7151 | ||||
7152 | /// Actually emit an availability diagnostic for a reference to an unavailable | |||
7153 | /// decl. | |||
7154 | /// | |||
7155 | /// \param Ctx The context that the reference occurred in | |||
7156 | /// \param ReferringDecl The exact declaration that was referenced. | |||
7157 | /// \param OffendingDecl A related decl to \c ReferringDecl that has an | |||
7158 | /// availability attribute corresponding to \c K attached to it. Note that this | |||
7159 | /// may not be the same as ReferringDecl, i.e. if an EnumDecl is annotated and | |||
7160 | /// we refer to a member EnumConstantDecl, ReferringDecl is the EnumConstantDecl | |||
7161 | /// and OffendingDecl is the EnumDecl. | |||
7162 | static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K, | |||
7163 | Decl *Ctx, const NamedDecl *ReferringDecl, | |||
7164 | const NamedDecl *OffendingDecl, | |||
7165 | StringRef Message, | |||
7166 | ArrayRef<SourceLocation> Locs, | |||
7167 | const ObjCInterfaceDecl *UnknownObjCClass, | |||
7168 | const ObjCPropertyDecl *ObjCProperty, | |||
7169 | bool ObjCPropertyAccess) { | |||
7170 | // Diagnostics for deprecated or unavailable. | |||
7171 | unsigned diag, diag_message, diag_fwdclass_message; | |||
7172 | unsigned diag_available_here = diag::note_availability_specified_here; | |||
7173 | SourceLocation NoteLocation = OffendingDecl->getLocation(); | |||
7174 | ||||
7175 | // Matches 'diag::note_property_attribute' options. | |||
7176 | unsigned property_note_select; | |||
7177 | ||||
7178 | // Matches diag::note_availability_specified_here. | |||
7179 | unsigned available_here_select_kind; | |||
7180 | ||||
7181 | VersionTuple DeclVersion; | |||
7182 | if (const AvailabilityAttr *AA = getAttrForPlatform(S.Context, OffendingDecl)) | |||
7183 | DeclVersion = AA->getIntroduced(); | |||
7184 | ||||
7185 | if (!ShouldDiagnoseAvailabilityInContext(S, K, DeclVersion, Ctx)) | |||
7186 | return; | |||
7187 | ||||
7188 | SourceLocation Loc = Locs.front(); | |||
7189 | ||||
7190 | // The declaration can have multiple availability attributes, we are looking | |||
7191 | // at one of them. | |||
7192 | const AvailabilityAttr *A = getAttrForPlatform(S.Context, OffendingDecl); | |||
7193 | if (A && A->isInherited()) { | |||
7194 | for (const Decl *Redecl = OffendingDecl->getMostRecentDecl(); Redecl; | |||
7195 | Redecl = Redecl->getPreviousDecl()) { | |||
7196 | const AvailabilityAttr *AForRedecl = | |||
7197 | getAttrForPlatform(S.Context, Redecl); | |||
7198 | if (AForRedecl && !AForRedecl->isInherited()) { | |||
7199 | // If D is a declaration with inherited attributes, the note should | |||
7200 | // point to the declaration with actual attributes. | |||
7201 | NoteLocation = Redecl->getLocation(); | |||
7202 | break; | |||
7203 | } | |||
7204 | } | |||
7205 | } | |||
7206 | ||||
7207 | switch (K) { | |||
7208 | case AR_NotYetIntroduced: { | |||
7209 | // We would like to emit the diagnostic even if -Wunguarded-availability is | |||
7210 | // not specified for deployment targets >= to iOS 11 or equivalent or | |||
7211 | // for declarations that were introduced in iOS 11 (macOS 10.13, ...) or | |||
7212 | // later. | |||
7213 | const AvailabilityAttr *AA = | |||
7214 | getAttrForPlatform(S.getASTContext(), OffendingDecl); | |||
7215 | VersionTuple Introduced = AA->getIntroduced(); | |||
7216 | ||||
7217 | bool UseNewWarning = shouldDiagnoseAvailabilityByDefault( | |||
7218 | S.Context, S.Context.getTargetInfo().getPlatformMinVersion(), | |||
7219 | Introduced); | |||
7220 | unsigned Warning = UseNewWarning ? diag::warn_unguarded_availability_new | |||
7221 | : diag::warn_unguarded_availability; | |||
7222 | ||||
7223 | S.Diag(Loc, Warning) | |||
7224 | << OffendingDecl | |||
7225 | << AvailabilityAttr::getPrettyPlatformName( | |||
7226 | S.getASTContext().getTargetInfo().getPlatformName()) | |||
7227 | << Introduced.getAsString(); | |||
7228 | ||||
7229 | S.Diag(OffendingDecl->getLocation(), diag::note_availability_specified_here) | |||
7230 | << OffendingDecl << /* partial */ 3; | |||
7231 | ||||
7232 | if (const auto *Enclosing = findEnclosingDeclToAnnotate(Ctx)) { | |||
7233 | if (const auto *TD = dyn_cast<TagDecl>(Enclosing)) | |||
7234 | if (TD->getDeclName().isEmpty()) { | |||
7235 | S.Diag(TD->getLocation(), | |||
7236 | diag::note_decl_unguarded_availability_silence) | |||
7237 | << /*Anonymous*/ 1 << TD->getKindName(); | |||
7238 | return; | |||
7239 | } | |||
7240 | auto FixitNoteDiag = | |||
7241 | S.Diag(Enclosing->getLocation(), | |||
7242 | diag::note_decl_unguarded_availability_silence) | |||
7243 | << /*Named*/ 0 << Enclosing; | |||
7244 | // Don't offer a fixit for declarations with availability attributes. | |||
7245 | if (Enclosing->hasAttr<AvailabilityAttr>()) | |||
7246 | return; | |||
7247 | if (!S.getPreprocessor().isMacroDefined("API_AVAILABLE")) | |||
7248 | return; | |||
7249 | Optional<AttributeInsertion> Insertion = createAttributeInsertion( | |||
7250 | Enclosing, S.getSourceManager(), S.getLangOpts()); | |||
7251 | if (!Insertion) | |||
7252 | return; | |||
7253 | std::string PlatformName = | |||
7254 | AvailabilityAttr::getPlatformNameSourceSpelling( | |||
7255 | S.getASTContext().getTargetInfo().getPlatformName()) | |||
7256 | .lower(); | |||
7257 | std::string Introduced = | |||
7258 | OffendingDecl->getVersionIntroduced().getAsString(); | |||
7259 | FixitNoteDiag << FixItHint::CreateInsertion( | |||
7260 | Insertion->Loc, | |||
7261 | (llvm::Twine(Insertion->Prefix) + "API_AVAILABLE(" + PlatformName + | |||
7262 | "(" + Introduced + "))" + Insertion->Suffix) | |||
7263 | .str()); | |||
7264 | } | |||
7265 | return; | |||
7266 | } | |||
7267 | case AR_Deprecated: | |||
7268 | diag = !ObjCPropertyAccess ? diag::warn_deprecated | |||
7269 | : diag::warn_property_method_deprecated; | |||
7270 | diag_message = diag::warn_deprecated_message; | |||
7271 | diag_fwdclass_message = diag::warn_deprecated_fwdclass_message; | |||
7272 | property_note_select = /* deprecated */ 0; | |||
7273 | available_here_select_kind = /* deprecated */ 2; | |||
7274 | if (const auto *AL = OffendingDecl->getAttr<DeprecatedAttr>()) | |||
7275 | NoteLocation = AL->getLocation(); | |||
7276 | break; | |||
7277 | ||||
7278 | case AR_Unavailable: | |||
7279 | diag = !ObjCPropertyAccess ? diag::err_unavailable | |||
7280 | : diag::err_property_method_unavailable; | |||
7281 | diag_message = diag::err_unavailable_message; | |||
7282 | diag_fwdclass_message = diag::warn_unavailable_fwdclass_message; | |||
7283 | property_note_select = /* unavailable */ 1; | |||
7284 | available_here_select_kind = /* unavailable */ 0; | |||
7285 | ||||
7286 | if (auto AL = OffendingDecl->getAttr<UnavailableAttr>()) { | |||
7287 | if (AL->isImplicit() && AL->getImplicitReason()) { | |||
7288 | // Most of these failures are due to extra restrictions in ARC; | |||
7289 | // reflect that in the primary diagnostic when applicable. | |||
7290 | auto flagARCError = [&] { | |||
7291 | if (S.getLangOpts().ObjCAutoRefCount && | |||
7292 | S.getSourceManager().isInSystemHeader( | |||
7293 | OffendingDecl->getLocation())) | |||
7294 | diag = diag::err_unavailable_in_arc; | |||
7295 | }; | |||
7296 | ||||
7297 | switch (AL->getImplicitReason()) { | |||
7298 | case UnavailableAttr::IR_None: break; | |||
7299 | ||||
7300 | case UnavailableAttr::IR_ARCForbiddenType: | |||
7301 | flagARCError(); | |||
7302 | diag_available_here = diag::note_arc_forbidden_type; | |||
7303 | break; | |||
7304 | ||||
7305 | case UnavailableAttr::IR_ForbiddenWeak: | |||
7306 | if (S.getLangOpts().ObjCWeakRuntime) | |||
7307 | diag_available_here = diag::note_arc_weak_disabled; | |||
7308 | else | |||
7309 | diag_available_here = diag::note_arc_weak_no_runtime; | |||
7310 | break; | |||
7311 | ||||
7312 | case UnavailableAttr::IR_ARCForbiddenConversion: | |||
7313 | flagARCError(); | |||
7314 | diag_available_here = diag::note_performs_forbidden_arc_conversion; | |||
7315 | break; | |||
7316 | ||||
7317 | case UnavailableAttr::IR_ARCInitReturnsUnrelated: | |||
7318 | flagARCError(); | |||
7319 | diag_available_here = diag::note_arc_init_returns_unrelated; | |||
7320 | break; | |||
7321 | ||||
7322 | case UnavailableAttr::IR_ARCFieldWithOwnership: | |||
7323 | flagARCError(); | |||
7324 | diag_available_here = diag::note_arc_field_with_ownership; | |||
7325 | break; | |||
7326 | } | |||
7327 | } | |||
7328 | } | |||
7329 | break; | |||
7330 | ||||
7331 | case AR_Available: | |||
7332 | llvm_unreachable("Warning for availability of available declaration?")::llvm::llvm_unreachable_internal("Warning for availability of available declaration?" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 7332); | |||
7333 | } | |||
7334 | ||||
7335 | SmallVector<FixItHint, 12> FixIts; | |||
7336 | if (K == AR_Deprecated) { | |||
7337 | StringRef Replacement; | |||
7338 | if (auto AL = OffendingDecl->getAttr<DeprecatedAttr>()) | |||
7339 | Replacement = AL->getReplacement(); | |||
7340 | if (auto AL = getAttrForPlatform(S.Context, OffendingDecl)) | |||
7341 | Replacement = AL->getReplacement(); | |||
7342 | ||||
7343 | CharSourceRange UseRange; | |||
7344 | if (!Replacement.empty()) | |||
7345 | UseRange = | |||
7346 | CharSourceRange::getCharRange(Loc, S.getLocForEndOfToken(Loc)); | |||
7347 | if (UseRange.isValid()) { | |||
7348 | if (const auto *MethodDecl = dyn_cast<ObjCMethodDecl>(ReferringDecl)) { | |||
7349 | Selector Sel = MethodDecl->getSelector(); | |||
7350 | SmallVector<StringRef, 12> SelectorSlotNames; | |||
7351 | Optional<unsigned> NumParams = tryParseObjCMethodName( | |||
7352 | Replacement, SelectorSlotNames, S.getLangOpts()); | |||
7353 | if (NumParams && NumParams.getValue() == Sel.getNumArgs()) { | |||
7354 | assert(SelectorSlotNames.size() == Locs.size())(static_cast <bool> (SelectorSlotNames.size() == Locs.size ()) ? void (0) : __assert_fail ("SelectorSlotNames.size() == Locs.size()" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 7354, __extension__ __PRETTY_FUNCTION__)); | |||
7355 | for (unsigned I = 0; I < Locs.size(); ++I) { | |||
7356 | if (!Sel.getNameForSlot(I).empty()) { | |||
7357 | CharSourceRange NameRange = CharSourceRange::getCharRange( | |||
7358 | Locs[I], S.getLocForEndOfToken(Locs[I])); | |||
7359 | FixIts.push_back(FixItHint::CreateReplacement( | |||
7360 | NameRange, SelectorSlotNames[I])); | |||
7361 | } else | |||
7362 | FixIts.push_back( | |||
7363 | FixItHint::CreateInsertion(Locs[I], SelectorSlotNames[I])); | |||
7364 | } | |||
7365 | } else | |||
7366 | FixIts.push_back(FixItHint::CreateReplacement(UseRange, Replacement)); | |||
7367 | } else | |||
7368 | FixIts.push_back(FixItHint::CreateReplacement(UseRange, Replacement)); | |||
7369 | } | |||
7370 | } | |||
7371 | ||||
7372 | if (!Message.empty()) { | |||
7373 | S.Diag(Loc, diag_message) << ReferringDecl << Message << FixIts; | |||
7374 | if (ObjCProperty) | |||
7375 | S.Diag(ObjCProperty->getLocation(), diag::note_property_attribute) | |||
7376 | << ObjCProperty->getDeclName() << property_note_select; | |||
7377 | } else if (!UnknownObjCClass) { | |||
7378 | S.Diag(Loc, diag) << ReferringDecl << FixIts; | |||
7379 | if (ObjCProperty) | |||
7380 | S.Diag(ObjCProperty->getLocation(), diag::note_property_attribute) | |||
7381 | << ObjCProperty->getDeclName() << property_note_select; | |||
7382 | } else { | |||
7383 | S.Diag(Loc, diag_fwdclass_message) << ReferringDecl << FixIts; | |||
7384 | S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class); | |||
7385 | } | |||
7386 | ||||
7387 | S.Diag(NoteLocation, diag_available_here) | |||
7388 | << OffendingDecl << available_here_select_kind; | |||
7389 | } | |||
7390 | ||||
7391 | static void handleDelayedAvailabilityCheck(Sema &S, DelayedDiagnostic &DD, | |||
7392 | Decl *Ctx) { | |||
7393 | assert(DD.Kind == DelayedDiagnostic::Availability &&(static_cast <bool> (DD.Kind == DelayedDiagnostic::Availability && "Expected an availability diagnostic here") ? void (0) : __assert_fail ("DD.Kind == DelayedDiagnostic::Availability && \"Expected an availability diagnostic here\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 7394, __extension__ __PRETTY_FUNCTION__)) | |||
7394 | "Expected an availability diagnostic here")(static_cast <bool> (DD.Kind == DelayedDiagnostic::Availability && "Expected an availability diagnostic here") ? void (0) : __assert_fail ("DD.Kind == DelayedDiagnostic::Availability && \"Expected an availability diagnostic here\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 7394, __extension__ __PRETTY_FUNCTION__)); | |||
7395 | ||||
7396 | DD.Triggered = true; | |||
7397 | DoEmitAvailabilityWarning( | |||
7398 | S, DD.getAvailabilityResult(), Ctx, DD.getAvailabilityReferringDecl(), | |||
7399 | DD.getAvailabilityOffendingDecl(), DD.getAvailabilityMessage(), | |||
7400 | DD.getAvailabilitySelectorLocs(), DD.getUnknownObjCClass(), | |||
7401 | DD.getObjCProperty(), false); | |||
7402 | } | |||
7403 | ||||
7404 | void Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) { | |||
7405 | assert(DelayedDiagnostics.getCurrentPool())(static_cast <bool> (DelayedDiagnostics.getCurrentPool( )) ? void (0) : __assert_fail ("DelayedDiagnostics.getCurrentPool()" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 7405, __extension__ __PRETTY_FUNCTION__)); | |||
7406 | DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool(); | |||
7407 | DelayedDiagnostics.popWithoutEmitting(state); | |||
7408 | ||||
7409 | // When delaying diagnostics to run in the context of a parsed | |||
7410 | // declaration, we only want to actually emit anything if parsing | |||
7411 | // succeeds. | |||
7412 | if (!decl) return; | |||
7413 | ||||
7414 | // We emit all the active diagnostics in this pool or any of its | |||
7415 | // parents. In general, we'll get one pool for the decl spec | |||
7416 | // and a child pool for each declarator; in a decl group like: | |||
7417 | // deprecated_typedef foo, *bar, baz(); | |||
7418 | // only the declarator pops will be passed decls. This is correct; | |||
7419 | // we really do need to consider delayed diagnostics from the decl spec | |||
7420 | // for each of the different declarations. | |||
7421 | const DelayedDiagnosticPool *pool = &poppedPool; | |||
7422 | do { | |||
7423 | for (DelayedDiagnosticPool::pool_iterator | |||
7424 | i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) { | |||
7425 | // This const_cast is a bit lame. Really, Triggered should be mutable. | |||
7426 | DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i); | |||
7427 | if (diag.Triggered) | |||
7428 | continue; | |||
7429 | ||||
7430 | switch (diag.Kind) { | |||
7431 | case DelayedDiagnostic::Availability: | |||
7432 | // Don't bother giving deprecation/unavailable diagnostics if | |||
7433 | // the decl is invalid. | |||
7434 | if (!decl->isInvalidDecl()) | |||
7435 | handleDelayedAvailabilityCheck(*this, diag, decl); | |||
7436 | break; | |||
7437 | ||||
7438 | case DelayedDiagnostic::Access: | |||
7439 | HandleDelayedAccessCheck(diag, decl); | |||
7440 | break; | |||
7441 | ||||
7442 | case DelayedDiagnostic::ForbiddenType: | |||
7443 | handleDelayedForbiddenType(*this, diag, decl); | |||
7444 | break; | |||
7445 | } | |||
7446 | } | |||
7447 | } while ((pool = pool->getParent())); | |||
7448 | } | |||
7449 | ||||
7450 | /// Given a set of delayed diagnostics, re-emit them as if they had | |||
7451 | /// been delayed in the current context instead of in the given pool. | |||
7452 | /// Essentially, this just moves them to the current pool. | |||
7453 | void Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) { | |||
7454 | DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool(); | |||
7455 | assert(curPool && "re-emitting in undelayed context not supported")(static_cast <bool> (curPool && "re-emitting in undelayed context not supported" ) ? void (0) : __assert_fail ("curPool && \"re-emitting in undelayed context not supported\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 7455, __extension__ __PRETTY_FUNCTION__)); | |||
7456 | curPool->steal(pool); | |||
7457 | } | |||
7458 | ||||
7459 | static void EmitAvailabilityWarning(Sema &S, AvailabilityResult AR, | |||
7460 | const NamedDecl *ReferringDecl, | |||
7461 | const NamedDecl *OffendingDecl, | |||
7462 | StringRef Message, | |||
7463 | ArrayRef<SourceLocation> Locs, | |||
7464 | const ObjCInterfaceDecl *UnknownObjCClass, | |||
7465 | const ObjCPropertyDecl *ObjCProperty, | |||
7466 | bool ObjCPropertyAccess) { | |||
7467 | // Delay if we're currently parsing a declaration. | |||
7468 | if (S.DelayedDiagnostics.shouldDelayDiagnostics()) { | |||
7469 | S.DelayedDiagnostics.add( | |||
7470 | DelayedDiagnostic::makeAvailability( | |||
7471 | AR, Locs, ReferringDecl, OffendingDecl, UnknownObjCClass, | |||
7472 | ObjCProperty, Message, ObjCPropertyAccess)); | |||
7473 | return; | |||
7474 | } | |||
7475 | ||||
7476 | Decl *Ctx = cast<Decl>(S.getCurLexicalContext()); | |||
7477 | DoEmitAvailabilityWarning(S, AR, Ctx, ReferringDecl, OffendingDecl, | |||
7478 | Message, Locs, UnknownObjCClass, ObjCProperty, | |||
7479 | ObjCPropertyAccess); | |||
7480 | } | |||
7481 | ||||
7482 | namespace { | |||
7483 | ||||
7484 | /// Returns true if the given statement can be a body-like child of \p Parent. | |||
7485 | bool isBodyLikeChildStmt(const Stmt *S, const Stmt *Parent) { | |||
7486 | switch (Parent->getStmtClass()) { | |||
7487 | case Stmt::IfStmtClass: | |||
7488 | return cast<IfStmt>(Parent)->getThen() == S || | |||
7489 | cast<IfStmt>(Parent)->getElse() == S; | |||
7490 | case Stmt::WhileStmtClass: | |||
7491 | return cast<WhileStmt>(Parent)->getBody() == S; | |||
7492 | case Stmt::DoStmtClass: | |||
7493 | return cast<DoStmt>(Parent)->getBody() == S; | |||
7494 | case Stmt::ForStmtClass: | |||
7495 | return cast<ForStmt>(Parent)->getBody() == S; | |||
7496 | case Stmt::CXXForRangeStmtClass: | |||
7497 | return cast<CXXForRangeStmt>(Parent)->getBody() == S; | |||
7498 | case Stmt::ObjCForCollectionStmtClass: | |||
7499 | return cast<ObjCForCollectionStmt>(Parent)->getBody() == S; | |||
7500 | case Stmt::CaseStmtClass: | |||
7501 | case Stmt::DefaultStmtClass: | |||
7502 | return cast<SwitchCase>(Parent)->getSubStmt() == S; | |||
7503 | default: | |||
7504 | return false; | |||
7505 | } | |||
7506 | } | |||
7507 | ||||
7508 | class StmtUSEFinder : public RecursiveASTVisitor<StmtUSEFinder> { | |||
7509 | const Stmt *Target; | |||
7510 | ||||
7511 | public: | |||
7512 | bool VisitStmt(Stmt *S) { return S != Target; } | |||
7513 | ||||
7514 | /// Returns true if the given statement is present in the given declaration. | |||
7515 | static bool isContained(const Stmt *Target, const Decl *D) { | |||
7516 | StmtUSEFinder Visitor; | |||
7517 | Visitor.Target = Target; | |||
7518 | return !Visitor.TraverseDecl(const_cast<Decl *>(D)); | |||
7519 | } | |||
7520 | }; | |||
7521 | ||||
7522 | /// Traverses the AST and finds the last statement that used a given | |||
7523 | /// declaration. | |||
7524 | class LastDeclUSEFinder : public RecursiveASTVisitor<LastDeclUSEFinder> { | |||
7525 | const Decl *D; | |||
7526 | ||||
7527 | public: | |||
7528 | bool VisitDeclRefExpr(DeclRefExpr *DRE) { | |||
7529 | if (DRE->getDecl() == D) | |||
7530 | return false; | |||
7531 | return true; | |||
7532 | } | |||
7533 | ||||
7534 | static const Stmt *findLastStmtThatUsesDecl(const Decl *D, | |||
7535 | const CompoundStmt *Scope) { | |||
7536 | LastDeclUSEFinder Visitor; | |||
7537 | Visitor.D = D; | |||
7538 | for (auto I = Scope->body_rbegin(), E = Scope->body_rend(); I != E; ++I) { | |||
7539 | const Stmt *S = *I; | |||
7540 | if (!Visitor.TraverseStmt(const_cast<Stmt *>(S))) | |||
7541 | return S; | |||
7542 | } | |||
7543 | return nullptr; | |||
7544 | } | |||
7545 | }; | |||
7546 | ||||
7547 | /// This class implements -Wunguarded-availability. | |||
7548 | /// | |||
7549 | /// This is done with a traversal of the AST of a function that makes reference | |||
7550 | /// to a partially available declaration. Whenever we encounter an \c if of the | |||
7551 | /// form: \c if(@available(...)), we use the version from the condition to visit | |||
7552 | /// the then statement. | |||
7553 | class DiagnoseUnguardedAvailability | |||
7554 | : public RecursiveASTVisitor<DiagnoseUnguardedAvailability> { | |||
7555 | typedef RecursiveASTVisitor<DiagnoseUnguardedAvailability> Base; | |||
7556 | ||||
7557 | Sema &SemaRef; | |||
7558 | Decl *Ctx; | |||
7559 | ||||
7560 | /// Stack of potentially nested 'if (@available(...))'s. | |||
7561 | SmallVector<VersionTuple, 8> AvailabilityStack; | |||
7562 | SmallVector<const Stmt *, 16> StmtStack; | |||
7563 | ||||
7564 | void DiagnoseDeclAvailability(NamedDecl *D, SourceRange Range); | |||
7565 | ||||
7566 | public: | |||
7567 | DiagnoseUnguardedAvailability(Sema &SemaRef, Decl *Ctx) | |||
7568 | : SemaRef(SemaRef), Ctx(Ctx) { | |||
7569 | AvailabilityStack.push_back( | |||
7570 | SemaRef.Context.getTargetInfo().getPlatformMinVersion()); | |||
7571 | } | |||
7572 | ||||
7573 | bool TraverseDecl(Decl *D) { | |||
7574 | // Avoid visiting nested functions to prevent duplicate warnings. | |||
7575 | if (!D || isa<FunctionDecl>(D)) | |||
7576 | return true; | |||
7577 | return Base::TraverseDecl(D); | |||
7578 | } | |||
7579 | ||||
7580 | bool TraverseStmt(Stmt *S) { | |||
7581 | if (!S) | |||
7582 | return true; | |||
7583 | StmtStack.push_back(S); | |||
7584 | bool Result = Base::TraverseStmt(S); | |||
7585 | StmtStack.pop_back(); | |||
7586 | return Result; | |||
7587 | } | |||
7588 | ||||
7589 | void IssueDiagnostics(Stmt *S) { TraverseStmt(S); } | |||
7590 | ||||
7591 | bool TraverseIfStmt(IfStmt *If); | |||
7592 | ||||
7593 | bool TraverseLambdaExpr(LambdaExpr *E) { return true; } | |||
7594 | ||||
7595 | // for 'case X:' statements, don't bother looking at the 'X'; it can't lead | |||
7596 | // to any useful diagnostics. | |||
7597 | bool TraverseCaseStmt(CaseStmt *CS) { return TraverseStmt(CS->getSubStmt()); } | |||
7598 | ||||
7599 | bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *PRE) { | |||
7600 | if (PRE->isClassReceiver()) | |||
7601 | DiagnoseDeclAvailability(PRE->getClassReceiver(), PRE->getReceiverLocation()); | |||
7602 | return true; | |||
7603 | } | |||
7604 | ||||
7605 | bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) { | |||
7606 | if (ObjCMethodDecl *D = Msg->getMethodDecl()) | |||
7607 | DiagnoseDeclAvailability( | |||
7608 | D, SourceRange(Msg->getSelectorStartLoc(), Msg->getLocEnd())); | |||
7609 | return true; | |||
7610 | } | |||
7611 | ||||
7612 | bool VisitDeclRefExpr(DeclRefExpr *DRE) { | |||
7613 | DiagnoseDeclAvailability(DRE->getDecl(), | |||
7614 | SourceRange(DRE->getLocStart(), DRE->getLocEnd())); | |||
7615 | return true; | |||
7616 | } | |||
7617 | ||||
7618 | bool VisitMemberExpr(MemberExpr *ME) { | |||
7619 | DiagnoseDeclAvailability(ME->getMemberDecl(), | |||
7620 | SourceRange(ME->getLocStart(), ME->getLocEnd())); | |||
7621 | return true; | |||
7622 | } | |||
7623 | ||||
7624 | bool VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) { | |||
7625 | SemaRef.Diag(E->getLocStart(), diag::warn_at_available_unchecked_use) | |||
7626 | << (!SemaRef.getLangOpts().ObjC1); | |||
7627 | return true; | |||
7628 | } | |||
7629 | ||||
7630 | bool VisitTypeLoc(TypeLoc Ty); | |||
7631 | }; | |||
7632 | ||||
7633 | void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability( | |||
7634 | NamedDecl *D, SourceRange Range) { | |||
7635 | AvailabilityResult Result; | |||
7636 | const NamedDecl *OffendingDecl; | |||
7637 | std::tie(Result, OffendingDecl) = | |||
7638 | ShouldDiagnoseAvailabilityOfDecl(D, nullptr); | |||
7639 | if (Result != AR_Available) { | |||
7640 | // All other diagnostic kinds have already been handled in | |||
7641 | // DiagnoseAvailabilityOfDecl. | |||
7642 | if (Result != AR_NotYetIntroduced) | |||
7643 | return; | |||
7644 | ||||
7645 | const AvailabilityAttr *AA = | |||
7646 | getAttrForPlatform(SemaRef.getASTContext(), OffendingDecl); | |||
7647 | VersionTuple Introduced = AA->getIntroduced(); | |||
7648 | ||||
7649 | if (AvailabilityStack.back() >= Introduced) | |||
7650 | return; | |||
7651 | ||||
7652 | // If the context of this function is less available than D, we should not | |||
7653 | // emit a diagnostic. | |||
7654 | if (!ShouldDiagnoseAvailabilityInContext(SemaRef, Result, Introduced, Ctx)) | |||
7655 | return; | |||
7656 | ||||
7657 | // We would like to emit the diagnostic even if -Wunguarded-availability is | |||
7658 | // not specified for deployment targets >= to iOS 11 or equivalent or | |||
7659 | // for declarations that were introduced in iOS 11 (macOS 10.13, ...) or | |||
7660 | // later. | |||
7661 | unsigned DiagKind = | |||
7662 | shouldDiagnoseAvailabilityByDefault( | |||
7663 | SemaRef.Context, | |||
7664 | SemaRef.Context.getTargetInfo().getPlatformMinVersion(), Introduced) | |||
7665 | ? diag::warn_unguarded_availability_new | |||
7666 | : diag::warn_unguarded_availability; | |||
7667 | ||||
7668 | SemaRef.Diag(Range.getBegin(), DiagKind) | |||
7669 | << Range << D | |||
7670 | << AvailabilityAttr::getPrettyPlatformName( | |||
7671 | SemaRef.getASTContext().getTargetInfo().getPlatformName()) | |||
7672 | << Introduced.getAsString(); | |||
7673 | ||||
7674 | SemaRef.Diag(OffendingDecl->getLocation(), | |||
7675 | diag::note_availability_specified_here) | |||
7676 | << OffendingDecl << /* partial */ 3; | |||
7677 | ||||
7678 | auto FixitDiag = | |||
7679 | SemaRef.Diag(Range.getBegin(), diag::note_unguarded_available_silence) | |||
7680 | << Range << D | |||
7681 | << (SemaRef.getLangOpts().ObjC1 ? /*@available*/ 0 | |||
7682 | : /*__builtin_available*/ 1); | |||
7683 | ||||
7684 | // Find the statement which should be enclosed in the if @available check. | |||
7685 | if (StmtStack.empty()) | |||
7686 | return; | |||
7687 | const Stmt *StmtOfUse = StmtStack.back(); | |||
7688 | const CompoundStmt *Scope = nullptr; | |||
7689 | for (const Stmt *S : llvm::reverse(StmtStack)) { | |||
7690 | if (const auto *CS = dyn_cast<CompoundStmt>(S)) { | |||
7691 | Scope = CS; | |||
7692 | break; | |||
7693 | } | |||
7694 | if (isBodyLikeChildStmt(StmtOfUse, S)) { | |||
7695 | // The declaration won't be seen outside of the statement, so we don't | |||
7696 | // have to wrap the uses of any declared variables in if (@available). | |||
7697 | // Therefore we can avoid setting Scope here. | |||
7698 | break; | |||
7699 | } | |||
7700 | StmtOfUse = S; | |||
7701 | } | |||
7702 | const Stmt *LastStmtOfUse = nullptr; | |||
7703 | if (isa<DeclStmt>(StmtOfUse) && Scope) { | |||
7704 | for (const Decl *D : cast<DeclStmt>(StmtOfUse)->decls()) { | |||
7705 | if (StmtUSEFinder::isContained(StmtStack.back(), D)) { | |||
7706 | LastStmtOfUse = LastDeclUSEFinder::findLastStmtThatUsesDecl(D, Scope); | |||
7707 | break; | |||
7708 | } | |||
7709 | } | |||
7710 | } | |||
7711 | ||||
7712 | const SourceManager &SM = SemaRef.getSourceManager(); | |||
7713 | SourceLocation IfInsertionLoc = | |||
7714 | SM.getExpansionLoc(StmtOfUse->getLocStart()); | |||
7715 | SourceLocation StmtEndLoc = | |||
7716 | SM.getExpansionRange( | |||
7717 | (LastStmtOfUse ? LastStmtOfUse : StmtOfUse)->getLocEnd()) | |||
7718 | .getEnd(); | |||
7719 | if (SM.getFileID(IfInsertionLoc) != SM.getFileID(StmtEndLoc)) | |||
7720 | return; | |||
7721 | ||||
7722 | StringRef Indentation = Lexer::getIndentationForLine(IfInsertionLoc, SM); | |||
7723 | const char *ExtraIndentation = " "; | |||
7724 | std::string FixItString; | |||
7725 | llvm::raw_string_ostream FixItOS(FixItString); | |||
7726 | FixItOS << "if (" << (SemaRef.getLangOpts().ObjC1 ? "@available" | |||
7727 | : "__builtin_available") | |||
7728 | << "(" | |||
7729 | << AvailabilityAttr::getPlatformNameSourceSpelling( | |||
7730 | SemaRef.getASTContext().getTargetInfo().getPlatformName()) | |||
7731 | << " " << Introduced.getAsString() << ", *)) {\n" | |||
7732 | << Indentation << ExtraIndentation; | |||
7733 | FixitDiag << FixItHint::CreateInsertion(IfInsertionLoc, FixItOS.str()); | |||
7734 | SourceLocation ElseInsertionLoc = Lexer::findLocationAfterToken( | |||
7735 | StmtEndLoc, tok::semi, SM, SemaRef.getLangOpts(), | |||
7736 | /*SkipTrailingWhitespaceAndNewLine=*/false); | |||
7737 | if (ElseInsertionLoc.isInvalid()) | |||
7738 | ElseInsertionLoc = | |||
7739 | Lexer::getLocForEndOfToken(StmtEndLoc, 0, SM, SemaRef.getLangOpts()); | |||
7740 | FixItOS.str().clear(); | |||
7741 | FixItOS << "\n" | |||
7742 | << Indentation << "} else {\n" | |||
7743 | << Indentation << ExtraIndentation | |||
7744 | << "// Fallback on earlier versions\n" | |||
7745 | << Indentation << "}"; | |||
7746 | FixitDiag << FixItHint::CreateInsertion(ElseInsertionLoc, FixItOS.str()); | |||
7747 | } | |||
7748 | } | |||
7749 | ||||
7750 | bool DiagnoseUnguardedAvailability::VisitTypeLoc(TypeLoc Ty) { | |||
7751 | const Type *TyPtr = Ty.getTypePtr(); | |||
7752 | SourceRange Range{Ty.getBeginLoc(), Ty.getEndLoc()}; | |||
7753 | ||||
7754 | if (Range.isInvalid()) | |||
7755 | return true; | |||
7756 | ||||
7757 | if (const auto *TT = dyn_cast<TagType>(TyPtr)) { | |||
7758 | TagDecl *TD = TT->getDecl(); | |||
7759 | DiagnoseDeclAvailability(TD, Range); | |||
7760 | ||||
7761 | } else if (const auto *TD = dyn_cast<TypedefType>(TyPtr)) { | |||
7762 | TypedefNameDecl *D = TD->getDecl(); | |||
7763 | DiagnoseDeclAvailability(D, Range); | |||
7764 | ||||
7765 | } else if (const auto *ObjCO = dyn_cast<ObjCObjectType>(TyPtr)) { | |||
7766 | if (NamedDecl *D = ObjCO->getInterface()) | |||
7767 | DiagnoseDeclAvailability(D, Range); | |||
7768 | } | |||
7769 | ||||
7770 | return true; | |||
7771 | } | |||
7772 | ||||
7773 | bool DiagnoseUnguardedAvailability::TraverseIfStmt(IfStmt *If) { | |||
7774 | VersionTuple CondVersion; | |||
7775 | if (auto *E = dyn_cast<ObjCAvailabilityCheckExpr>(If->getCond())) { | |||
7776 | CondVersion = E->getVersion(); | |||
7777 | ||||
7778 | // If we're using the '*' case here or if this check is redundant, then we | |||
7779 | // use the enclosing version to check both branches. | |||
7780 | if (CondVersion.empty() || CondVersion <= AvailabilityStack.back()) | |||
7781 | return TraverseStmt(If->getThen()) && TraverseStmt(If->getElse()); | |||
7782 | } else { | |||
7783 | // This isn't an availability checking 'if', we can just continue. | |||
7784 | return Base::TraverseIfStmt(If); | |||
7785 | } | |||
7786 | ||||
7787 | AvailabilityStack.push_back(CondVersion); | |||
7788 | bool ShouldContinue = TraverseStmt(If->getThen()); | |||
7789 | AvailabilityStack.pop_back(); | |||
7790 | ||||
7791 | return ShouldContinue && TraverseStmt(If->getElse()); | |||
7792 | } | |||
7793 | ||||
7794 | } // end anonymous namespace | |||
7795 | ||||
7796 | void Sema::DiagnoseUnguardedAvailabilityViolations(Decl *D) { | |||
7797 | Stmt *Body = nullptr; | |||
7798 | ||||
7799 | if (auto *FD = D->getAsFunction()) { | |||
7800 | // FIXME: We only examine the pattern decl for availability violations now, | |||
7801 | // but we should also examine instantiated templates. | |||
7802 | if (FD->isTemplateInstantiation()) | |||
7803 | return; | |||
7804 | ||||
7805 | Body = FD->getBody(); | |||
7806 | } else if (auto *MD = dyn_cast<ObjCMethodDecl>(D)) | |||
7807 | Body = MD->getBody(); | |||
7808 | else if (auto *BD = dyn_cast<BlockDecl>(D)) | |||
7809 | Body = BD->getBody(); | |||
7810 | ||||
7811 | assert(Body && "Need a body here!")(static_cast <bool> (Body && "Need a body here!" ) ? void (0) : __assert_fail ("Body && \"Need a body here!\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/Sema/SemaDeclAttr.cpp" , 7811, __extension__ __PRETTY_FUNCTION__)); | |||
7812 | ||||
7813 | DiagnoseUnguardedAvailability(*this, D).IssueDiagnostics(Body); | |||
7814 | } | |||
7815 | ||||
7816 | void Sema::DiagnoseAvailabilityOfDecl(NamedDecl *D, | |||
7817 | ArrayRef<SourceLocation> Locs, | |||
7818 | const ObjCInterfaceDecl *UnknownObjCClass, | |||
7819 | bool ObjCPropertyAccess, | |||
7820 | bool AvoidPartialAvailabilityChecks) { | |||
7821 | std::string Message; | |||
7822 | AvailabilityResult Result; | |||
7823 | const NamedDecl* OffendingDecl; | |||
7824 | // See if this declaration is unavailable, deprecated, or partial. | |||
7825 | std::tie(Result, OffendingDecl) = ShouldDiagnoseAvailabilityOfDecl(D, &Message); | |||
7826 | if (Result == AR_Available) | |||
7827 | return; | |||
7828 | ||||
7829 | if (Result == AR_NotYetIntroduced) { | |||
7830 | if (AvoidPartialAvailabilityChecks) | |||
7831 | return; | |||
7832 | ||||
7833 | // We need to know the @available context in the current function to | |||
7834 | // diagnose this use, let DiagnoseUnguardedAvailabilityViolations do that | |||
7835 | // when we're done parsing the current function. | |||
7836 | if (getCurFunctionOrMethodDecl()) { | |||
7837 | getEnclosingFunction()->HasPotentialAvailabilityViolations = true; | |||
7838 | return; | |||
7839 | } else if (getCurBlock() || getCurLambda()) { | |||
7840 | getCurFunction()->HasPotentialAvailabilityViolations = true; | |||
7841 | return; | |||
7842 | } | |||
7843 | } | |||
7844 | ||||
7845 | const ObjCPropertyDecl *ObjCPDecl = nullptr; | |||
7846 | if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) { | |||
7847 | if (const ObjCPropertyDecl *PD = MD->findPropertyDecl()) { | |||
7848 | AvailabilityResult PDeclResult = PD->getAvailability(nullptr); | |||
7849 | if (PDeclResult == Result) | |||
7850 | ObjCPDecl = PD; | |||
7851 | } | |||
7852 | } | |||
7853 | ||||
7854 | EmitAvailabilityWarning(*this, Result, D, OffendingDecl, Message, Locs, | |||
7855 | UnknownObjCClass, ObjCPDecl, ObjCPropertyAccess); | |||
7856 | } |
1 | /*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ | |||
2 | |* *| | |||
3 | |* Attribute classes' definitions *| | |||
4 | |* *| | |||
5 | |* Automatically generated file, do not edit! *| | |||
6 | |* *| | |||
7 | \*===----------------------------------------------------------------------===*/ | |||
8 | ||||
9 | #ifndef LLVM_CLANG_ATTR_CLASSES_INC | |||
10 | #define LLVM_CLANG_ATTR_CLASSES_INC | |||
11 | ||||
12 | class AMDGPUFlatWorkGroupSizeAttr : public InheritableAttr { | |||
13 | unsigned min; | |||
14 | ||||
15 | unsigned max; | |||
16 | ||||
17 | public: | |||
18 | static AMDGPUFlatWorkGroupSizeAttr *CreateImplicit(ASTContext &Ctx, unsigned Min, unsigned Max, SourceRange Loc = SourceRange()) { | |||
19 | auto *A = new (Ctx) AMDGPUFlatWorkGroupSizeAttr(Loc, Ctx, Min, Max, 0); | |||
20 | A->setImplicit(true); | |||
21 | return A; | |||
22 | } | |||
23 | ||||
24 | AMDGPUFlatWorkGroupSizeAttr(SourceRange R, ASTContext &Ctx | |||
25 | , unsigned Min | |||
26 | , unsigned Max | |||
27 | , unsigned SI | |||
28 | ) | |||
29 | : InheritableAttr(attr::AMDGPUFlatWorkGroupSize, R, SI, false, false) | |||
30 | , min(Min) | |||
31 | , max(Max) | |||
32 | { | |||
33 | } | |||
34 | ||||
35 | AMDGPUFlatWorkGroupSizeAttr *clone(ASTContext &C) const; | |||
36 | void printPretty(raw_ostream &OS, | |||
37 | const PrintingPolicy &Policy) const; | |||
38 | const char *getSpelling() const; | |||
39 | unsigned getMin() const { | |||
40 | return min; | |||
41 | } | |||
42 | ||||
43 | unsigned getMax() const { | |||
44 | return max; | |||
45 | } | |||
46 | ||||
47 | ||||
48 | ||||
49 | static bool classof(const Attr *A) { return A->getKind() == attr::AMDGPUFlatWorkGroupSize; } | |||
50 | }; | |||
51 | ||||
52 | class AMDGPUNumSGPRAttr : public InheritableAttr { | |||
53 | unsigned numSGPR; | |||
54 | ||||
55 | public: | |||
56 | static AMDGPUNumSGPRAttr *CreateImplicit(ASTContext &Ctx, unsigned NumSGPR, SourceRange Loc = SourceRange()) { | |||
57 | auto *A = new (Ctx) AMDGPUNumSGPRAttr(Loc, Ctx, NumSGPR, 0); | |||
58 | A->setImplicit(true); | |||
59 | return A; | |||
60 | } | |||
61 | ||||
62 | AMDGPUNumSGPRAttr(SourceRange R, ASTContext &Ctx | |||
63 | , unsigned NumSGPR | |||
64 | , unsigned SI | |||
65 | ) | |||
66 | : InheritableAttr(attr::AMDGPUNumSGPR, R, SI, false, false) | |||
67 | , numSGPR(NumSGPR) | |||
68 | { | |||
69 | } | |||
70 | ||||
71 | AMDGPUNumSGPRAttr *clone(ASTContext &C) const; | |||
72 | void printPretty(raw_ostream &OS, | |||
73 | const PrintingPolicy &Policy) const; | |||
74 | const char *getSpelling() const; | |||
75 | unsigned getNumSGPR() const { | |||
76 | return numSGPR; | |||
77 | } | |||
78 | ||||
79 | ||||
80 | ||||
81 | static bool classof(const Attr *A) { return A->getKind() == attr::AMDGPUNumSGPR; } | |||
82 | }; | |||
83 | ||||
84 | class AMDGPUNumVGPRAttr : public InheritableAttr { | |||
85 | unsigned numVGPR; | |||
86 | ||||
87 | public: | |||
88 | static AMDGPUNumVGPRAttr *CreateImplicit(ASTContext &Ctx, unsigned NumVGPR, SourceRange Loc = SourceRange()) { | |||
89 | auto *A = new (Ctx) AMDGPUNumVGPRAttr(Loc, Ctx, NumVGPR, 0); | |||
90 | A->setImplicit(true); | |||
91 | return A; | |||
92 | } | |||
93 | ||||
94 | AMDGPUNumVGPRAttr(SourceRange R, ASTContext &Ctx | |||
95 | , unsigned NumVGPR | |||
96 | , unsigned SI | |||
97 | ) | |||
98 | : InheritableAttr(attr::AMDGPUNumVGPR, R, SI, false, false) | |||
99 | , numVGPR(NumVGPR) | |||
100 | { | |||
101 | } | |||
102 | ||||
103 | AMDGPUNumVGPRAttr *clone(ASTContext &C) const; | |||
104 | void printPretty(raw_ostream &OS, | |||
105 | const PrintingPolicy &Policy) const; | |||
106 | const char *getSpelling() const; | |||
107 | unsigned getNumVGPR() const { | |||
108 | return numVGPR; | |||
109 | } | |||
110 | ||||
111 | ||||
112 | ||||
113 | static bool classof(const Attr *A) { return A->getKind() == attr::AMDGPUNumVGPR; } | |||
114 | }; | |||
115 | ||||
116 | class AMDGPUWavesPerEUAttr : public InheritableAttr { | |||
117 | unsigned min; | |||
118 | ||||
119 | unsigned max; | |||
120 | ||||
121 | public: | |||
122 | static AMDGPUWavesPerEUAttr *CreateImplicit(ASTContext &Ctx, unsigned Min, unsigned Max, SourceRange Loc = SourceRange()) { | |||
123 | auto *A = new (Ctx) AMDGPUWavesPerEUAttr(Loc, Ctx, Min, Max, 0); | |||
124 | A->setImplicit(true); | |||
125 | return A; | |||
126 | } | |||
127 | ||||
128 | AMDGPUWavesPerEUAttr(SourceRange R, ASTContext &Ctx | |||
129 | , unsigned Min | |||
130 | , unsigned Max | |||
131 | , unsigned SI | |||
132 | ) | |||
133 | : InheritableAttr(attr::AMDGPUWavesPerEU, R, SI, false, false) | |||
134 | , min(Min) | |||
135 | , max(Max) | |||
136 | { | |||
137 | } | |||
138 | ||||
139 | AMDGPUWavesPerEUAttr(SourceRange R, ASTContext &Ctx | |||
140 | , unsigned Min | |||
141 | , unsigned SI | |||
142 | ) | |||
143 | : InheritableAttr(attr::AMDGPUWavesPerEU, R, SI, false, false) | |||
144 | , min(Min) | |||
145 | , max() | |||
146 | { | |||
147 | } | |||
148 | ||||
149 | AMDGPUWavesPerEUAttr *clone(ASTContext &C) const; | |||
150 | void printPretty(raw_ostream &OS, | |||
151 | const PrintingPolicy &Policy) const; | |||
152 | const char *getSpelling() const; | |||
153 | unsigned getMin() const { | |||
154 | return min; | |||
155 | } | |||
156 | ||||
157 | unsigned getMax() const { | |||
158 | return max; | |||
159 | } | |||
160 | ||||
161 | ||||
162 | ||||
163 | static bool classof(const Attr *A) { return A->getKind() == attr::AMDGPUWavesPerEU; } | |||
164 | }; | |||
165 | ||||
166 | class ARMInterruptAttr : public InheritableAttr { | |||
167 | public: | |||
168 | enum InterruptType { | |||
169 | IRQ, | |||
170 | FIQ, | |||
171 | SWI, | |||
172 | ABORT, | |||
173 | UNDEF, | |||
174 | Generic | |||
175 | }; | |||
176 | private: | |||
177 | InterruptType interrupt; | |||
178 | ||||
179 | public: | |||
180 | static ARMInterruptAttr *CreateImplicit(ASTContext &Ctx, InterruptType Interrupt, SourceRange Loc = SourceRange()) { | |||
181 | auto *A = new (Ctx) ARMInterruptAttr(Loc, Ctx, Interrupt, 0); | |||
182 | A->setImplicit(true); | |||
183 | return A; | |||
184 | } | |||
185 | ||||
186 | ARMInterruptAttr(SourceRange R, ASTContext &Ctx | |||
187 | , InterruptType Interrupt | |||
188 | , unsigned SI | |||
189 | ) | |||
190 | : InheritableAttr(attr::ARMInterrupt, R, SI, false, false) | |||
191 | , interrupt(Interrupt) | |||
192 | { | |||
193 | } | |||
194 | ||||
195 | ARMInterruptAttr(SourceRange R, ASTContext &Ctx | |||
196 | , unsigned SI | |||
197 | ) | |||
198 | : InheritableAttr(attr::ARMInterrupt, R, SI, false, false) | |||
199 | , interrupt(InterruptType(0)) | |||
200 | { | |||
201 | } | |||
202 | ||||
203 | ARMInterruptAttr *clone(ASTContext &C) const; | |||
204 | void printPretty(raw_ostream &OS, | |||
205 | const PrintingPolicy &Policy) const; | |||
206 | const char *getSpelling() const; | |||
207 | InterruptType getInterrupt() const { | |||
208 | return interrupt; | |||
209 | } | |||
210 | ||||
211 | static bool ConvertStrToInterruptType(StringRef Val, InterruptType &Out) { | |||
212 | Optional<InterruptType> R = llvm::StringSwitch<Optional<InterruptType>>(Val) | |||
213 | .Case("IRQ", ARMInterruptAttr::IRQ) | |||
214 | .Case("FIQ", ARMInterruptAttr::FIQ) | |||
215 | .Case("SWI", ARMInterruptAttr::SWI) | |||
216 | .Case("ABORT", ARMInterruptAttr::ABORT) | |||
217 | .Case("UNDEF", ARMInterruptAttr::UNDEF) | |||
218 | .Case("", ARMInterruptAttr::Generic) | |||
219 | .Default(Optional<InterruptType>()); | |||
220 | if (R) { | |||
221 | Out = *R; | |||
222 | return true; | |||
223 | } | |||
224 | return false; | |||
225 | } | |||
226 | ||||
227 | static const char *ConvertInterruptTypeToStr(InterruptType Val) { | |||
228 | switch(Val) { | |||
229 | case ARMInterruptAttr::IRQ: return "IRQ"; | |||
230 | case ARMInterruptAttr::FIQ: return "FIQ"; | |||
231 | case ARMInterruptAttr::SWI: return "SWI"; | |||
232 | case ARMInterruptAttr::ABORT: return "ABORT"; | |||
233 | case ARMInterruptAttr::UNDEF: return "UNDEF"; | |||
234 | case ARMInterruptAttr::Generic: return ""; | |||
235 | } | |||
236 | llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 236); | |||
237 | } | |||
238 | ||||
239 | ||||
240 | static bool classof(const Attr *A) { return A->getKind() == attr::ARMInterrupt; } | |||
241 | }; | |||
242 | ||||
243 | class AVRInterruptAttr : public InheritableAttr { | |||
244 | public: | |||
245 | static AVRInterruptAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
246 | auto *A = new (Ctx) AVRInterruptAttr(Loc, Ctx, 0); | |||
247 | A->setImplicit(true); | |||
248 | return A; | |||
249 | } | |||
250 | ||||
251 | AVRInterruptAttr(SourceRange R, ASTContext &Ctx | |||
252 | , unsigned SI | |||
253 | ) | |||
254 | : InheritableAttr(attr::AVRInterrupt, R, SI, false, false) | |||
255 | { | |||
256 | } | |||
257 | ||||
258 | AVRInterruptAttr *clone(ASTContext &C) const; | |||
259 | void printPretty(raw_ostream &OS, | |||
260 | const PrintingPolicy &Policy) const; | |||
261 | const char *getSpelling() const; | |||
262 | ||||
263 | ||||
264 | static bool classof(const Attr *A) { return A->getKind() == attr::AVRInterrupt; } | |||
265 | }; | |||
266 | ||||
267 | class AVRSignalAttr : public InheritableAttr { | |||
268 | public: | |||
269 | static AVRSignalAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
270 | auto *A = new (Ctx) AVRSignalAttr(Loc, Ctx, 0); | |||
271 | A->setImplicit(true); | |||
272 | return A; | |||
273 | } | |||
274 | ||||
275 | AVRSignalAttr(SourceRange R, ASTContext &Ctx | |||
276 | , unsigned SI | |||
277 | ) | |||
278 | : InheritableAttr(attr::AVRSignal, R, SI, false, false) | |||
279 | { | |||
280 | } | |||
281 | ||||
282 | AVRSignalAttr *clone(ASTContext &C) const; | |||
283 | void printPretty(raw_ostream &OS, | |||
284 | const PrintingPolicy &Policy) const; | |||
285 | const char *getSpelling() const; | |||
286 | ||||
287 | ||||
288 | static bool classof(const Attr *A) { return A->getKind() == attr::AVRSignal; } | |||
289 | }; | |||
290 | ||||
291 | class AbiTagAttr : public Attr { | |||
292 | unsigned tags_Size; | |||
293 | StringRef *tags_; | |||
294 | ||||
295 | public: | |||
296 | static AbiTagAttr *CreateImplicit(ASTContext &Ctx, StringRef *Tags, unsigned TagsSize, SourceRange Loc = SourceRange()) { | |||
297 | auto *A = new (Ctx) AbiTagAttr(Loc, Ctx, Tags, TagsSize, 0); | |||
298 | A->setImplicit(true); | |||
299 | return A; | |||
300 | } | |||
301 | ||||
302 | AbiTagAttr(SourceRange R, ASTContext &Ctx | |||
303 | , StringRef *Tags, unsigned TagsSize | |||
304 | , unsigned SI | |||
305 | ) | |||
306 | : Attr(attr::AbiTag, R, SI, false) | |||
307 | , tags_Size(TagsSize), tags_(new (Ctx, 16) StringRef[tags_Size]) | |||
308 | { | |||
309 | for (size_t I = 0, E = tags_Size; I != E; | |||
310 | ++I) { | |||
311 | StringRef Ref = Tags[I]; | |||
312 | if (!Ref.empty()) { | |||
313 | char *Mem = new (Ctx, 1) char[Ref.size()]; | |||
314 | std::memcpy(Mem, Ref.data(), Ref.size()); | |||
315 | tags_[I] = StringRef(Mem, Ref.size()); | |||
316 | } | |||
317 | } | |||
318 | } | |||
319 | ||||
320 | AbiTagAttr(SourceRange R, ASTContext &Ctx | |||
321 | , unsigned SI | |||
322 | ) | |||
323 | : Attr(attr::AbiTag, R, SI, false) | |||
324 | , tags_Size(0), tags_(nullptr) | |||
325 | { | |||
326 | } | |||
327 | ||||
328 | AbiTagAttr *clone(ASTContext &C) const; | |||
329 | void printPretty(raw_ostream &OS, | |||
330 | const PrintingPolicy &Policy) const; | |||
331 | const char *getSpelling() const; | |||
332 | typedef StringRef* tags_iterator; | |||
333 | tags_iterator tags_begin() const { return tags_; } | |||
334 | tags_iterator tags_end() const { return tags_ + tags_Size; } | |||
335 | unsigned tags_size() const { return tags_Size; } | |||
336 | llvm::iterator_range<tags_iterator> tags() const { return llvm::make_range(tags_begin(), tags_end()); } | |||
337 | ||||
338 | ||||
339 | ||||
340 | ||||
341 | static bool classof(const Attr *A) { return A->getKind() == attr::AbiTag; } | |||
342 | }; | |||
343 | ||||
344 | class AcquireCapabilityAttr : public InheritableAttr { | |||
345 | unsigned args_Size; | |||
346 | Expr * *args_; | |||
347 | ||||
348 | public: | |||
349 | enum Spelling { | |||
350 | GNU_acquire_capability = 0, | |||
351 | CXX11_clang_acquire_capability = 1, | |||
352 | GNU_acquire_shared_capability = 2, | |||
353 | CXX11_clang_acquire_shared_capability = 3, | |||
354 | GNU_exclusive_lock_function = 4, | |||
355 | GNU_shared_lock_function = 5 | |||
356 | }; | |||
357 | ||||
358 | static AcquireCapabilityAttr *CreateImplicit(ASTContext &Ctx, Spelling S, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) { | |||
359 | auto *A = new (Ctx) AcquireCapabilityAttr(Loc, Ctx, Args, ArgsSize, S); | |||
360 | A->setImplicit(true); | |||
361 | return A; | |||
362 | } | |||
363 | ||||
364 | AcquireCapabilityAttr(SourceRange R, ASTContext &Ctx | |||
365 | , Expr * *Args, unsigned ArgsSize | |||
366 | , unsigned SI | |||
367 | ) | |||
368 | : InheritableAttr(attr::AcquireCapability, R, SI, true, true) | |||
369 | , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size]) | |||
370 | { | |||
371 | std::copy(Args, Args + args_Size, args_); | |||
372 | } | |||
373 | ||||
374 | AcquireCapabilityAttr(SourceRange R, ASTContext &Ctx | |||
375 | , unsigned SI | |||
376 | ) | |||
377 | : InheritableAttr(attr::AcquireCapability, R, SI, true, true) | |||
378 | , args_Size(0), args_(nullptr) | |||
379 | { | |||
380 | } | |||
381 | ||||
382 | AcquireCapabilityAttr *clone(ASTContext &C) const; | |||
383 | void printPretty(raw_ostream &OS, | |||
384 | const PrintingPolicy &Policy) const; | |||
385 | const char *getSpelling() const; | |||
386 | Spelling getSemanticSpelling() const { | |||
387 | switch (SpellingListIndex) { | |||
388 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 388); | |||
389 | case 0: return GNU_acquire_capability; | |||
390 | case 1: return CXX11_clang_acquire_capability; | |||
391 | case 2: return GNU_acquire_shared_capability; | |||
392 | case 3: return CXX11_clang_acquire_shared_capability; | |||
393 | case 4: return GNU_exclusive_lock_function; | |||
394 | case 5: return GNU_shared_lock_function; | |||
395 | } | |||
396 | } | |||
397 | bool isShared() const { return SpellingListIndex == 2 || | |||
398 | SpellingListIndex == 3 || | |||
399 | SpellingListIndex == 5; } | |||
400 | typedef Expr ** args_iterator; | |||
401 | args_iterator args_begin() const { return args_; } | |||
402 | args_iterator args_end() const { return args_ + args_Size; } | |||
403 | unsigned args_size() const { return args_Size; } | |||
404 | llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); } | |||
405 | ||||
406 | ||||
407 | ||||
408 | ||||
409 | static bool classof(const Attr *A) { return A->getKind() == attr::AcquireCapability; } | |||
410 | }; | |||
411 | ||||
412 | class AcquiredAfterAttr : public InheritableAttr { | |||
413 | unsigned args_Size; | |||
414 | Expr * *args_; | |||
415 | ||||
416 | public: | |||
417 | static AcquiredAfterAttr *CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) { | |||
418 | auto *A = new (Ctx) AcquiredAfterAttr(Loc, Ctx, Args, ArgsSize, 0); | |||
419 | A->setImplicit(true); | |||
420 | return A; | |||
421 | } | |||
422 | ||||
423 | AcquiredAfterAttr(SourceRange R, ASTContext &Ctx | |||
424 | , Expr * *Args, unsigned ArgsSize | |||
425 | , unsigned SI | |||
426 | ) | |||
427 | : InheritableAttr(attr::AcquiredAfter, R, SI, true, true) | |||
428 | , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size]) | |||
429 | { | |||
430 | std::copy(Args, Args + args_Size, args_); | |||
431 | } | |||
432 | ||||
433 | AcquiredAfterAttr(SourceRange R, ASTContext &Ctx | |||
434 | , unsigned SI | |||
435 | ) | |||
436 | : InheritableAttr(attr::AcquiredAfter, R, SI, true, true) | |||
437 | , args_Size(0), args_(nullptr) | |||
438 | { | |||
439 | } | |||
440 | ||||
441 | AcquiredAfterAttr *clone(ASTContext &C) const; | |||
442 | void printPretty(raw_ostream &OS, | |||
443 | const PrintingPolicy &Policy) const; | |||
444 | const char *getSpelling() const; | |||
445 | typedef Expr ** args_iterator; | |||
446 | args_iterator args_begin() const { return args_; } | |||
447 | args_iterator args_end() const { return args_ + args_Size; } | |||
448 | unsigned args_size() const { return args_Size; } | |||
449 | llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); } | |||
450 | ||||
451 | ||||
452 | ||||
453 | ||||
454 | static bool classof(const Attr *A) { return A->getKind() == attr::AcquiredAfter; } | |||
455 | }; | |||
456 | ||||
457 | class AcquiredBeforeAttr : public InheritableAttr { | |||
458 | unsigned args_Size; | |||
459 | Expr * *args_; | |||
460 | ||||
461 | public: | |||
462 | static AcquiredBeforeAttr *CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) { | |||
463 | auto *A = new (Ctx) AcquiredBeforeAttr(Loc, Ctx, Args, ArgsSize, 0); | |||
464 | A->setImplicit(true); | |||
465 | return A; | |||
466 | } | |||
467 | ||||
468 | AcquiredBeforeAttr(SourceRange R, ASTContext &Ctx | |||
469 | , Expr * *Args, unsigned ArgsSize | |||
470 | , unsigned SI | |||
471 | ) | |||
472 | : InheritableAttr(attr::AcquiredBefore, R, SI, true, true) | |||
473 | , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size]) | |||
474 | { | |||
475 | std::copy(Args, Args + args_Size, args_); | |||
476 | } | |||
477 | ||||
478 | AcquiredBeforeAttr(SourceRange R, ASTContext &Ctx | |||
479 | , unsigned SI | |||
480 | ) | |||
481 | : InheritableAttr(attr::AcquiredBefore, R, SI, true, true) | |||
482 | , args_Size(0), args_(nullptr) | |||
483 | { | |||
484 | } | |||
485 | ||||
486 | AcquiredBeforeAttr *clone(ASTContext &C) const; | |||
487 | void printPretty(raw_ostream &OS, | |||
488 | const PrintingPolicy &Policy) const; | |||
489 | const char *getSpelling() const; | |||
490 | typedef Expr ** args_iterator; | |||
491 | args_iterator args_begin() const { return args_; } | |||
492 | args_iterator args_end() const { return args_ + args_Size; } | |||
493 | unsigned args_size() const { return args_Size; } | |||
494 | llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); } | |||
495 | ||||
496 | ||||
497 | ||||
498 | ||||
499 | static bool classof(const Attr *A) { return A->getKind() == attr::AcquiredBefore; } | |||
500 | }; | |||
501 | ||||
502 | class AliasAttr : public Attr { | |||
503 | unsigned aliaseeLength; | |||
504 | char *aliasee; | |||
505 | ||||
506 | public: | |||
507 | static AliasAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Aliasee, SourceRange Loc = SourceRange()) { | |||
508 | auto *A = new (Ctx) AliasAttr(Loc, Ctx, Aliasee, 0); | |||
509 | A->setImplicit(true); | |||
510 | return A; | |||
511 | } | |||
512 | ||||
513 | AliasAttr(SourceRange R, ASTContext &Ctx | |||
514 | , llvm::StringRef Aliasee | |||
515 | , unsigned SI | |||
516 | ) | |||
517 | : Attr(attr::Alias, R, SI, false) | |||
518 | , aliaseeLength(Aliasee.size()),aliasee(new (Ctx, 1) char[aliaseeLength]) | |||
519 | { | |||
520 | if (!Aliasee.empty()) | |||
521 | std::memcpy(aliasee, Aliasee.data(), aliaseeLength); | |||
| ||||
522 | } | |||
523 | ||||
524 | AliasAttr *clone(ASTContext &C) const; | |||
525 | void printPretty(raw_ostream &OS, | |||
526 | const PrintingPolicy &Policy) const; | |||
527 | const char *getSpelling() const; | |||
528 | llvm::StringRef getAliasee() const { | |||
529 | return llvm::StringRef(aliasee, aliaseeLength); | |||
530 | } | |||
531 | unsigned getAliaseeLength() const { | |||
532 | return aliaseeLength; | |||
533 | } | |||
534 | void setAliasee(ASTContext &C, llvm::StringRef S) { | |||
535 | aliaseeLength = S.size(); | |||
536 | this->aliasee = new (C, 1) char [aliaseeLength]; | |||
537 | if (!S.empty()) | |||
538 | std::memcpy(this->aliasee, S.data(), aliaseeLength); | |||
539 | } | |||
540 | ||||
541 | ||||
542 | ||||
543 | static bool classof(const Attr *A) { return A->getKind() == attr::Alias; } | |||
544 | }; | |||
545 | ||||
546 | class AlignMac68kAttr : public InheritableAttr { | |||
547 | public: | |||
548 | static AlignMac68kAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
549 | auto *A = new (Ctx) AlignMac68kAttr(Loc, Ctx, 0); | |||
550 | A->setImplicit(true); | |||
551 | return A; | |||
552 | } | |||
553 | ||||
554 | AlignMac68kAttr(SourceRange R, ASTContext &Ctx | |||
555 | , unsigned SI | |||
556 | ) | |||
557 | : InheritableAttr(attr::AlignMac68k, R, SI, false, false) | |||
558 | { | |||
559 | } | |||
560 | ||||
561 | AlignMac68kAttr *clone(ASTContext &C) const; | |||
562 | void printPretty(raw_ostream &OS, | |||
563 | const PrintingPolicy &Policy) const; | |||
564 | const char *getSpelling() const; | |||
565 | ||||
566 | ||||
567 | static bool classof(const Attr *A) { return A->getKind() == attr::AlignMac68k; } | |||
568 | }; | |||
569 | ||||
570 | class AlignValueAttr : public Attr { | |||
571 | Expr * alignment; | |||
572 | ||||
573 | public: | |||
574 | static AlignValueAttr *CreateImplicit(ASTContext &Ctx, Expr * Alignment, SourceRange Loc = SourceRange()) { | |||
575 | auto *A = new (Ctx) AlignValueAttr(Loc, Ctx, Alignment, 0); | |||
576 | A->setImplicit(true); | |||
577 | return A; | |||
578 | } | |||
579 | ||||
580 | AlignValueAttr(SourceRange R, ASTContext &Ctx | |||
581 | , Expr * Alignment | |||
582 | , unsigned SI | |||
583 | ) | |||
584 | : Attr(attr::AlignValue, R, SI, false) | |||
585 | , alignment(Alignment) | |||
586 | { | |||
587 | } | |||
588 | ||||
589 | AlignValueAttr *clone(ASTContext &C) const; | |||
590 | void printPretty(raw_ostream &OS, | |||
591 | const PrintingPolicy &Policy) const; | |||
592 | const char *getSpelling() const; | |||
593 | Expr * getAlignment() const { | |||
594 | return alignment; | |||
595 | } | |||
596 | ||||
597 | ||||
598 | ||||
599 | static bool classof(const Attr *A) { return A->getKind() == attr::AlignValue; } | |||
600 | }; | |||
601 | ||||
602 | class AlignedAttr : public InheritableAttr { | |||
603 | bool isalignmentExpr; | |||
604 | union { | |||
605 | Expr *alignmentExpr; | |||
606 | TypeSourceInfo *alignmentType; | |||
607 | }; | |||
608 | ||||
609 | public: | |||
610 | enum Spelling { | |||
611 | GNU_aligned = 0, | |||
612 | CXX11_gnu_aligned = 1, | |||
613 | Declspec_align = 2, | |||
614 | Keyword_alignas = 3, | |||
615 | Keyword_Alignas = 4 | |||
616 | }; | |||
617 | ||||
618 | static AlignedAttr *CreateImplicit(ASTContext &Ctx, Spelling S, bool IsAlignmentExpr, void *Alignment, SourceRange Loc = SourceRange()) { | |||
619 | auto *A = new (Ctx) AlignedAttr(Loc, Ctx, IsAlignmentExpr, Alignment, S); | |||
620 | A->setImplicit(true); | |||
621 | return A; | |||
622 | } | |||
623 | ||||
624 | AlignedAttr(SourceRange R, ASTContext &Ctx | |||
625 | , bool IsAlignmentExpr, void *Alignment | |||
626 | , unsigned SI | |||
627 | ) | |||
628 | : InheritableAttr(attr::Aligned, R, SI, false, false) | |||
629 | , isalignmentExpr(IsAlignmentExpr) | |||
630 | { | |||
631 | if (isalignmentExpr) | |||
632 | alignmentExpr = reinterpret_cast<Expr *>(Alignment); | |||
633 | else | |||
634 | alignmentType = reinterpret_cast<TypeSourceInfo *>(Alignment); | |||
635 | } | |||
636 | ||||
637 | AlignedAttr(SourceRange R, ASTContext &Ctx | |||
638 | , unsigned SI | |||
639 | ) | |||
640 | : InheritableAttr(attr::Aligned, R, SI, false, false) | |||
641 | , isalignmentExpr(false) | |||
642 | { | |||
643 | } | |||
644 | ||||
645 | AlignedAttr *clone(ASTContext &C) const; | |||
646 | void printPretty(raw_ostream &OS, | |||
647 | const PrintingPolicy &Policy) const; | |||
648 | const char *getSpelling() const; | |||
649 | Spelling getSemanticSpelling() const { | |||
650 | switch (SpellingListIndex) { | |||
651 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 651); | |||
652 | case 0: return GNU_aligned; | |||
653 | case 1: return CXX11_gnu_aligned; | |||
654 | case 2: return Declspec_align; | |||
655 | case 3: return Keyword_alignas; | |||
656 | case 4: return Keyword_Alignas; | |||
657 | } | |||
658 | } | |||
659 | bool isGNU() const { return SpellingListIndex == 0 || | |||
660 | SpellingListIndex == 1; } | |||
661 | bool isC11() const { return SpellingListIndex == 4; } | |||
662 | bool isAlignas() const { return SpellingListIndex == 3 || | |||
663 | SpellingListIndex == 4; } | |||
664 | bool isDeclspec() const { return SpellingListIndex == 2; } | |||
665 | bool isAlignmentDependent() const; | |||
666 | unsigned getAlignment(ASTContext &Ctx) const; | |||
667 | bool isAlignmentExpr() const { | |||
668 | return isalignmentExpr; | |||
669 | } | |||
670 | Expr *getAlignmentExpr() const { | |||
671 | assert(isalignmentExpr)(static_cast <bool> (isalignmentExpr) ? void (0) : __assert_fail ("isalignmentExpr", "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 671, __extension__ __PRETTY_FUNCTION__)); | |||
672 | return alignmentExpr; | |||
673 | } | |||
674 | TypeSourceInfo *getAlignmentType() const { | |||
675 | assert(!isalignmentExpr)(static_cast <bool> (!isalignmentExpr) ? void (0) : __assert_fail ("!isalignmentExpr", "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 675, __extension__ __PRETTY_FUNCTION__)); | |||
676 | return alignmentType; | |||
677 | } | |||
678 | ||||
679 | ||||
680 | ||||
681 | static bool classof(const Attr *A) { return A->getKind() == attr::Aligned; } | |||
682 | }; | |||
683 | ||||
684 | class AllocAlignAttr : public InheritableAttr { | |||
685 | ParamIdx paramIndex; | |||
686 | ||||
687 | public: | |||
688 | static AllocAlignAttr *CreateImplicit(ASTContext &Ctx, ParamIdx ParamIndex, SourceRange Loc = SourceRange()) { | |||
689 | auto *A = new (Ctx) AllocAlignAttr(Loc, Ctx, ParamIndex, 0); | |||
690 | A->setImplicit(true); | |||
691 | return A; | |||
692 | } | |||
693 | ||||
694 | AllocAlignAttr(SourceRange R, ASTContext &Ctx | |||
695 | , ParamIdx ParamIndex | |||
696 | , unsigned SI | |||
697 | ) | |||
698 | : InheritableAttr(attr::AllocAlign, R, SI, false, false) | |||
699 | , paramIndex(ParamIndex) | |||
700 | { | |||
701 | } | |||
702 | ||||
703 | AllocAlignAttr *clone(ASTContext &C) const; | |||
704 | void printPretty(raw_ostream &OS, | |||
705 | const PrintingPolicy &Policy) const; | |||
706 | const char *getSpelling() const; | |||
707 | ParamIdx getParamIndex() const { | |||
708 | return paramIndex; | |||
709 | } | |||
710 | ||||
711 | ||||
712 | ||||
713 | static bool classof(const Attr *A) { return A->getKind() == attr::AllocAlign; } | |||
714 | }; | |||
715 | ||||
716 | class AllocSizeAttr : public InheritableAttr { | |||
717 | ParamIdx elemSizeParam; | |||
718 | ||||
719 | ParamIdx numElemsParam; | |||
720 | ||||
721 | public: | |||
722 | static AllocSizeAttr *CreateImplicit(ASTContext &Ctx, ParamIdx ElemSizeParam, ParamIdx NumElemsParam, SourceRange Loc = SourceRange()) { | |||
723 | auto *A = new (Ctx) AllocSizeAttr(Loc, Ctx, ElemSizeParam, NumElemsParam, 0); | |||
724 | A->setImplicit(true); | |||
725 | return A; | |||
726 | } | |||
727 | ||||
728 | AllocSizeAttr(SourceRange R, ASTContext &Ctx | |||
729 | , ParamIdx ElemSizeParam | |||
730 | , ParamIdx NumElemsParam | |||
731 | , unsigned SI | |||
732 | ) | |||
733 | : InheritableAttr(attr::AllocSize, R, SI, false, false) | |||
734 | , elemSizeParam(ElemSizeParam) | |||
735 | , numElemsParam(NumElemsParam) | |||
736 | { | |||
737 | } | |||
738 | ||||
739 | AllocSizeAttr(SourceRange R, ASTContext &Ctx | |||
740 | , ParamIdx ElemSizeParam | |||
741 | , unsigned SI | |||
742 | ) | |||
743 | : InheritableAttr(attr::AllocSize, R, SI, false, false) | |||
744 | , elemSizeParam(ElemSizeParam) | |||
745 | , numElemsParam() | |||
746 | { | |||
747 | } | |||
748 | ||||
749 | AllocSizeAttr *clone(ASTContext &C) const; | |||
750 | void printPretty(raw_ostream &OS, | |||
751 | const PrintingPolicy &Policy) const; | |||
752 | const char *getSpelling() const; | |||
753 | ParamIdx getElemSizeParam() const { | |||
754 | return elemSizeParam; | |||
755 | } | |||
756 | ||||
757 | ParamIdx getNumElemsParam() const { | |||
758 | return numElemsParam; | |||
759 | } | |||
760 | ||||
761 | ||||
762 | ||||
763 | static bool classof(const Attr *A) { return A->getKind() == attr::AllocSize; } | |||
764 | }; | |||
765 | ||||
766 | class AlwaysInlineAttr : public InheritableAttr { | |||
767 | public: | |||
768 | enum Spelling { | |||
769 | GNU_always_inline = 0, | |||
770 | CXX11_gnu_always_inline = 1, | |||
771 | Keyword_forceinline = 2 | |||
772 | }; | |||
773 | ||||
774 | static AlwaysInlineAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) { | |||
775 | auto *A = new (Ctx) AlwaysInlineAttr(Loc, Ctx, S); | |||
776 | A->setImplicit(true); | |||
777 | return A; | |||
778 | } | |||
779 | ||||
780 | AlwaysInlineAttr(SourceRange R, ASTContext &Ctx | |||
781 | , unsigned SI | |||
782 | ) | |||
783 | : InheritableAttr(attr::AlwaysInline, R, SI, false, false) | |||
784 | { | |||
785 | } | |||
786 | ||||
787 | AlwaysInlineAttr *clone(ASTContext &C) const; | |||
788 | void printPretty(raw_ostream &OS, | |||
789 | const PrintingPolicy &Policy) const; | |||
790 | const char *getSpelling() const; | |||
791 | Spelling getSemanticSpelling() const { | |||
792 | switch (SpellingListIndex) { | |||
793 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 793); | |||
794 | case 0: return GNU_always_inline; | |||
795 | case 1: return CXX11_gnu_always_inline; | |||
796 | case 2: return Keyword_forceinline; | |||
797 | } | |||
798 | } | |||
799 | ||||
800 | ||||
801 | static bool classof(const Attr *A) { return A->getKind() == attr::AlwaysInline; } | |||
802 | }; | |||
803 | ||||
804 | class AnalyzerNoReturnAttr : public InheritableAttr { | |||
805 | public: | |||
806 | static AnalyzerNoReturnAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
807 | auto *A = new (Ctx) AnalyzerNoReturnAttr(Loc, Ctx, 0); | |||
808 | A->setImplicit(true); | |||
809 | return A; | |||
810 | } | |||
811 | ||||
812 | AnalyzerNoReturnAttr(SourceRange R, ASTContext &Ctx | |||
813 | , unsigned SI | |||
814 | ) | |||
815 | : InheritableAttr(attr::AnalyzerNoReturn, R, SI, false, false) | |||
816 | { | |||
817 | } | |||
818 | ||||
819 | AnalyzerNoReturnAttr *clone(ASTContext &C) const; | |||
820 | void printPretty(raw_ostream &OS, | |||
821 | const PrintingPolicy &Policy) const; | |||
822 | const char *getSpelling() const; | |||
823 | ||||
824 | ||||
825 | static bool classof(const Attr *A) { return A->getKind() == attr::AnalyzerNoReturn; } | |||
826 | }; | |||
827 | ||||
828 | class AnnotateAttr : public InheritableParamAttr { | |||
829 | unsigned annotationLength; | |||
830 | char *annotation; | |||
831 | ||||
832 | public: | |||
833 | static AnnotateAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Annotation, SourceRange Loc = SourceRange()) { | |||
834 | auto *A = new (Ctx) AnnotateAttr(Loc, Ctx, Annotation, 0); | |||
835 | A->setImplicit(true); | |||
836 | return A; | |||
837 | } | |||
838 | ||||
839 | AnnotateAttr(SourceRange R, ASTContext &Ctx | |||
840 | , llvm::StringRef Annotation | |||
841 | , unsigned SI | |||
842 | ) | |||
843 | : InheritableParamAttr(attr::Annotate, R, SI, false, false) | |||
844 | , annotationLength(Annotation.size()),annotation(new (Ctx, 1) char[annotationLength]) | |||
845 | { | |||
846 | if (!Annotation.empty()) | |||
847 | std::memcpy(annotation, Annotation.data(), annotationLength); | |||
848 | } | |||
849 | ||||
850 | AnnotateAttr *clone(ASTContext &C) const; | |||
851 | void printPretty(raw_ostream &OS, | |||
852 | const PrintingPolicy &Policy) const; | |||
853 | const char *getSpelling() const; | |||
854 | llvm::StringRef getAnnotation() const { | |||
855 | return llvm::StringRef(annotation, annotationLength); | |||
856 | } | |||
857 | unsigned getAnnotationLength() const { | |||
858 | return annotationLength; | |||
859 | } | |||
860 | void setAnnotation(ASTContext &C, llvm::StringRef S) { | |||
861 | annotationLength = S.size(); | |||
862 | this->annotation = new (C, 1) char [annotationLength]; | |||
863 | if (!S.empty()) | |||
864 | std::memcpy(this->annotation, S.data(), annotationLength); | |||
865 | } | |||
866 | ||||
867 | ||||
868 | ||||
869 | static bool classof(const Attr *A) { return A->getKind() == attr::Annotate; } | |||
870 | }; | |||
871 | ||||
872 | class AnyX86InterruptAttr : public InheritableAttr { | |||
873 | public: | |||
874 | static AnyX86InterruptAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
875 | auto *A = new (Ctx) AnyX86InterruptAttr(Loc, Ctx, 0); | |||
876 | A->setImplicit(true); | |||
877 | return A; | |||
878 | } | |||
879 | ||||
880 | AnyX86InterruptAttr(SourceRange R, ASTContext &Ctx | |||
881 | , unsigned SI | |||
882 | ) | |||
883 | : InheritableAttr(attr::AnyX86Interrupt, R, SI, false, false) | |||
884 | { | |||
885 | } | |||
886 | ||||
887 | AnyX86InterruptAttr *clone(ASTContext &C) const; | |||
888 | void printPretty(raw_ostream &OS, | |||
889 | const PrintingPolicy &Policy) const; | |||
890 | const char *getSpelling() const; | |||
891 | ||||
892 | ||||
893 | static bool classof(const Attr *A) { return A->getKind() == attr::AnyX86Interrupt; } | |||
894 | }; | |||
895 | ||||
896 | class AnyX86NoCallerSavedRegistersAttr : public InheritableAttr { | |||
897 | public: | |||
898 | static AnyX86NoCallerSavedRegistersAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
899 | auto *A = new (Ctx) AnyX86NoCallerSavedRegistersAttr(Loc, Ctx, 0); | |||
900 | A->setImplicit(true); | |||
901 | return A; | |||
902 | } | |||
903 | ||||
904 | AnyX86NoCallerSavedRegistersAttr(SourceRange R, ASTContext &Ctx | |||
905 | , unsigned SI | |||
906 | ) | |||
907 | : InheritableAttr(attr::AnyX86NoCallerSavedRegisters, R, SI, false, false) | |||
908 | { | |||
909 | } | |||
910 | ||||
911 | AnyX86NoCallerSavedRegistersAttr *clone(ASTContext &C) const; | |||
912 | void printPretty(raw_ostream &OS, | |||
913 | const PrintingPolicy &Policy) const; | |||
914 | const char *getSpelling() const; | |||
915 | ||||
916 | ||||
917 | static bool classof(const Attr *A) { return A->getKind() == attr::AnyX86NoCallerSavedRegisters; } | |||
918 | }; | |||
919 | ||||
920 | class AnyX86NoCfCheckAttr : public InheritableAttr { | |||
921 | public: | |||
922 | static AnyX86NoCfCheckAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
923 | auto *A = new (Ctx) AnyX86NoCfCheckAttr(Loc, Ctx, 0); | |||
924 | A->setImplicit(true); | |||
925 | return A; | |||
926 | } | |||
927 | ||||
928 | AnyX86NoCfCheckAttr(SourceRange R, ASTContext &Ctx | |||
929 | , unsigned SI | |||
930 | ) | |||
931 | : InheritableAttr(attr::AnyX86NoCfCheck, R, SI, false, false) | |||
932 | { | |||
933 | } | |||
934 | ||||
935 | AnyX86NoCfCheckAttr *clone(ASTContext &C) const; | |||
936 | void printPretty(raw_ostream &OS, | |||
937 | const PrintingPolicy &Policy) const; | |||
938 | const char *getSpelling() const; | |||
939 | ||||
940 | ||||
941 | static bool classof(const Attr *A) { return A->getKind() == attr::AnyX86NoCfCheck; } | |||
942 | }; | |||
943 | ||||
944 | class ArcWeakrefUnavailableAttr : public InheritableAttr { | |||
945 | public: | |||
946 | static ArcWeakrefUnavailableAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
947 | auto *A = new (Ctx) ArcWeakrefUnavailableAttr(Loc, Ctx, 0); | |||
948 | A->setImplicit(true); | |||
949 | return A; | |||
950 | } | |||
951 | ||||
952 | ArcWeakrefUnavailableAttr(SourceRange R, ASTContext &Ctx | |||
953 | , unsigned SI | |||
954 | ) | |||
955 | : InheritableAttr(attr::ArcWeakrefUnavailable, R, SI, false, false) | |||
956 | { | |||
957 | } | |||
958 | ||||
959 | ArcWeakrefUnavailableAttr *clone(ASTContext &C) const; | |||
960 | void printPretty(raw_ostream &OS, | |||
961 | const PrintingPolicy &Policy) const; | |||
962 | const char *getSpelling() const; | |||
963 | ||||
964 | ||||
965 | static bool classof(const Attr *A) { return A->getKind() == attr::ArcWeakrefUnavailable; } | |||
966 | }; | |||
967 | ||||
968 | class ArgumentWithTypeTagAttr : public InheritableAttr { | |||
969 | IdentifierInfo * argumentKind; | |||
970 | ||||
971 | ParamIdx argumentIdx; | |||
972 | ||||
973 | ParamIdx typeTagIdx; | |||
974 | ||||
975 | bool isPointer; | |||
976 | ||||
977 | public: | |||
978 | enum Spelling { | |||
979 | GNU_argument_with_type_tag = 0, | |||
980 | CXX11_clang_argument_with_type_tag = 1, | |||
981 | C2x_clang_argument_with_type_tag = 2, | |||
982 | GNU_pointer_with_type_tag = 3, | |||
983 | CXX11_clang_pointer_with_type_tag = 4, | |||
984 | C2x_clang_pointer_with_type_tag = 5 | |||
985 | }; | |||
986 | ||||
987 | static ArgumentWithTypeTagAttr *CreateImplicit(ASTContext &Ctx, Spelling S, IdentifierInfo * ArgumentKind, ParamIdx ArgumentIdx, ParamIdx TypeTagIdx, bool IsPointer, SourceRange Loc = SourceRange()) { | |||
988 | auto *A = new (Ctx) ArgumentWithTypeTagAttr(Loc, Ctx, ArgumentKind, ArgumentIdx, TypeTagIdx, IsPointer, S); | |||
989 | A->setImplicit(true); | |||
990 | return A; | |||
991 | } | |||
992 | ||||
993 | static ArgumentWithTypeTagAttr *CreateImplicit(ASTContext &Ctx, Spelling S, IdentifierInfo * ArgumentKind, ParamIdx ArgumentIdx, ParamIdx TypeTagIdx, SourceRange Loc = SourceRange()) { | |||
994 | auto *A = new (Ctx) ArgumentWithTypeTagAttr(Loc, Ctx, ArgumentKind, ArgumentIdx, TypeTagIdx, S); | |||
995 | A->setImplicit(true); | |||
996 | return A; | |||
997 | } | |||
998 | ||||
999 | ArgumentWithTypeTagAttr(SourceRange R, ASTContext &Ctx | |||
1000 | , IdentifierInfo * ArgumentKind | |||
1001 | , ParamIdx ArgumentIdx | |||
1002 | , ParamIdx TypeTagIdx | |||
1003 | , bool IsPointer | |||
1004 | , unsigned SI | |||
1005 | ) | |||
1006 | : InheritableAttr(attr::ArgumentWithTypeTag, R, SI, false, false) | |||
1007 | , argumentKind(ArgumentKind) | |||
1008 | , argumentIdx(ArgumentIdx) | |||
1009 | , typeTagIdx(TypeTagIdx) | |||
1010 | , isPointer(IsPointer) | |||
1011 | { | |||
1012 | } | |||
1013 | ||||
1014 | ArgumentWithTypeTagAttr(SourceRange R, ASTContext &Ctx | |||
1015 | , IdentifierInfo * ArgumentKind | |||
1016 | , ParamIdx ArgumentIdx | |||
1017 | , ParamIdx TypeTagIdx | |||
1018 | , unsigned SI | |||
1019 | ) | |||
1020 | : InheritableAttr(attr::ArgumentWithTypeTag, R, SI, false, false) | |||
1021 | , argumentKind(ArgumentKind) | |||
1022 | , argumentIdx(ArgumentIdx) | |||
1023 | , typeTagIdx(TypeTagIdx) | |||
1024 | , isPointer() | |||
1025 | { | |||
1026 | } | |||
1027 | ||||
1028 | ArgumentWithTypeTagAttr *clone(ASTContext &C) const; | |||
1029 | void printPretty(raw_ostream &OS, | |||
1030 | const PrintingPolicy &Policy) const; | |||
1031 | const char *getSpelling() const; | |||
1032 | Spelling getSemanticSpelling() const { | |||
1033 | switch (SpellingListIndex) { | |||
1034 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 1034); | |||
1035 | case 0: return GNU_argument_with_type_tag; | |||
1036 | case 1: return CXX11_clang_argument_with_type_tag; | |||
1037 | case 2: return C2x_clang_argument_with_type_tag; | |||
1038 | case 3: return GNU_pointer_with_type_tag; | |||
1039 | case 4: return CXX11_clang_pointer_with_type_tag; | |||
1040 | case 5: return C2x_clang_pointer_with_type_tag; | |||
1041 | } | |||
1042 | } | |||
1043 | IdentifierInfo * getArgumentKind() const { | |||
1044 | return argumentKind; | |||
1045 | } | |||
1046 | ||||
1047 | ParamIdx getArgumentIdx() const { | |||
1048 | return argumentIdx; | |||
1049 | } | |||
1050 | ||||
1051 | ParamIdx getTypeTagIdx() const { | |||
1052 | return typeTagIdx; | |||
1053 | } | |||
1054 | ||||
1055 | bool getIsPointer() const { | |||
1056 | return isPointer; | |||
1057 | } | |||
1058 | ||||
1059 | ||||
1060 | ||||
1061 | static bool classof(const Attr *A) { return A->getKind() == attr::ArgumentWithTypeTag; } | |||
1062 | }; | |||
1063 | ||||
1064 | class ArtificialAttr : public InheritableAttr { | |||
1065 | public: | |||
1066 | static ArtificialAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
1067 | auto *A = new (Ctx) ArtificialAttr(Loc, Ctx, 0); | |||
1068 | A->setImplicit(true); | |||
1069 | return A; | |||
1070 | } | |||
1071 | ||||
1072 | ArtificialAttr(SourceRange R, ASTContext &Ctx | |||
1073 | , unsigned SI | |||
1074 | ) | |||
1075 | : InheritableAttr(attr::Artificial, R, SI, false, false) | |||
1076 | { | |||
1077 | } | |||
1078 | ||||
1079 | ArtificialAttr *clone(ASTContext &C) const; | |||
1080 | void printPretty(raw_ostream &OS, | |||
1081 | const PrintingPolicy &Policy) const; | |||
1082 | const char *getSpelling() const; | |||
1083 | ||||
1084 | ||||
1085 | static bool classof(const Attr *A) { return A->getKind() == attr::Artificial; } | |||
1086 | }; | |||
1087 | ||||
1088 | class AsmLabelAttr : public InheritableAttr { | |||
1089 | unsigned labelLength; | |||
1090 | char *label; | |||
1091 | ||||
1092 | public: | |||
1093 | static AsmLabelAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Label, SourceRange Loc = SourceRange()) { | |||
1094 | auto *A = new (Ctx) AsmLabelAttr(Loc, Ctx, Label, 0); | |||
1095 | A->setImplicit(true); | |||
1096 | return A; | |||
1097 | } | |||
1098 | ||||
1099 | AsmLabelAttr(SourceRange R, ASTContext &Ctx | |||
1100 | , llvm::StringRef Label | |||
1101 | , unsigned SI | |||
1102 | ) | |||
1103 | : InheritableAttr(attr::AsmLabel, R, SI, false, false) | |||
1104 | , labelLength(Label.size()),label(new (Ctx, 1) char[labelLength]) | |||
1105 | { | |||
1106 | if (!Label.empty()) | |||
1107 | std::memcpy(label, Label.data(), labelLength); | |||
1108 | } | |||
1109 | ||||
1110 | AsmLabelAttr *clone(ASTContext &C) const; | |||
1111 | void printPretty(raw_ostream &OS, | |||
1112 | const PrintingPolicy &Policy) const; | |||
1113 | const char *getSpelling() const; | |||
1114 | llvm::StringRef getLabel() const { | |||
1115 | return llvm::StringRef(label, labelLength); | |||
1116 | } | |||
1117 | unsigned getLabelLength() const { | |||
1118 | return labelLength; | |||
1119 | } | |||
1120 | void setLabel(ASTContext &C, llvm::StringRef S) { | |||
1121 | labelLength = S.size(); | |||
1122 | this->label = new (C, 1) char [labelLength]; | |||
1123 | if (!S.empty()) | |||
1124 | std::memcpy(this->label, S.data(), labelLength); | |||
1125 | } | |||
1126 | ||||
1127 | ||||
1128 | ||||
1129 | static bool classof(const Attr *A) { return A->getKind() == attr::AsmLabel; } | |||
1130 | }; | |||
1131 | ||||
1132 | class AssertCapabilityAttr : public InheritableAttr { | |||
1133 | unsigned args_Size; | |||
1134 | Expr * *args_; | |||
1135 | ||||
1136 | public: | |||
1137 | enum Spelling { | |||
1138 | GNU_assert_capability = 0, | |||
1139 | CXX11_clang_assert_capability = 1, | |||
1140 | GNU_assert_shared_capability = 2, | |||
1141 | CXX11_clang_assert_shared_capability = 3 | |||
1142 | }; | |||
1143 | ||||
1144 | static AssertCapabilityAttr *CreateImplicit(ASTContext &Ctx, Spelling S, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) { | |||
1145 | auto *A = new (Ctx) AssertCapabilityAttr(Loc, Ctx, Args, ArgsSize, S); | |||
1146 | A->setImplicit(true); | |||
1147 | return A; | |||
1148 | } | |||
1149 | ||||
1150 | AssertCapabilityAttr(SourceRange R, ASTContext &Ctx | |||
1151 | , Expr * *Args, unsigned ArgsSize | |||
1152 | , unsigned SI | |||
1153 | ) | |||
1154 | : InheritableAttr(attr::AssertCapability, R, SI, true, true) | |||
1155 | , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size]) | |||
1156 | { | |||
1157 | std::copy(Args, Args + args_Size, args_); | |||
1158 | } | |||
1159 | ||||
1160 | AssertCapabilityAttr(SourceRange R, ASTContext &Ctx | |||
1161 | , unsigned SI | |||
1162 | ) | |||
1163 | : InheritableAttr(attr::AssertCapability, R, SI, true, true) | |||
1164 | , args_Size(0), args_(nullptr) | |||
1165 | { | |||
1166 | } | |||
1167 | ||||
1168 | AssertCapabilityAttr *clone(ASTContext &C) const; | |||
1169 | void printPretty(raw_ostream &OS, | |||
1170 | const PrintingPolicy &Policy) const; | |||
1171 | const char *getSpelling() const; | |||
1172 | Spelling getSemanticSpelling() const { | |||
1173 | switch (SpellingListIndex) { | |||
1174 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 1174); | |||
1175 | case 0: return GNU_assert_capability; | |||
1176 | case 1: return CXX11_clang_assert_capability; | |||
1177 | case 2: return GNU_assert_shared_capability; | |||
1178 | case 3: return CXX11_clang_assert_shared_capability; | |||
1179 | } | |||
1180 | } | |||
1181 | bool isShared() const { return SpellingListIndex == 2 || | |||
1182 | SpellingListIndex == 3; } | |||
1183 | typedef Expr ** args_iterator; | |||
1184 | args_iterator args_begin() const { return args_; } | |||
1185 | args_iterator args_end() const { return args_ + args_Size; } | |||
1186 | unsigned args_size() const { return args_Size; } | |||
1187 | llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); } | |||
1188 | ||||
1189 | ||||
1190 | ||||
1191 | ||||
1192 | static bool classof(const Attr *A) { return A->getKind() == attr::AssertCapability; } | |||
1193 | }; | |||
1194 | ||||
1195 | class AssertExclusiveLockAttr : public InheritableAttr { | |||
1196 | unsigned args_Size; | |||
1197 | Expr * *args_; | |||
1198 | ||||
1199 | public: | |||
1200 | static AssertExclusiveLockAttr *CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) { | |||
1201 | auto *A = new (Ctx) AssertExclusiveLockAttr(Loc, Ctx, Args, ArgsSize, 0); | |||
1202 | A->setImplicit(true); | |||
1203 | return A; | |||
1204 | } | |||
1205 | ||||
1206 | AssertExclusiveLockAttr(SourceRange R, ASTContext &Ctx | |||
1207 | , Expr * *Args, unsigned ArgsSize | |||
1208 | , unsigned SI | |||
1209 | ) | |||
1210 | : InheritableAttr(attr::AssertExclusiveLock, R, SI, true, true) | |||
1211 | , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size]) | |||
1212 | { | |||
1213 | std::copy(Args, Args + args_Size, args_); | |||
1214 | } | |||
1215 | ||||
1216 | AssertExclusiveLockAttr(SourceRange R, ASTContext &Ctx | |||
1217 | , unsigned SI | |||
1218 | ) | |||
1219 | : InheritableAttr(attr::AssertExclusiveLock, R, SI, true, true) | |||
1220 | , args_Size(0), args_(nullptr) | |||
1221 | { | |||
1222 | } | |||
1223 | ||||
1224 | AssertExclusiveLockAttr *clone(ASTContext &C) const; | |||
1225 | void printPretty(raw_ostream &OS, | |||
1226 | const PrintingPolicy &Policy) const; | |||
1227 | const char *getSpelling() const; | |||
1228 | typedef Expr ** args_iterator; | |||
1229 | args_iterator args_begin() const { return args_; } | |||
1230 | args_iterator args_end() const { return args_ + args_Size; } | |||
1231 | unsigned args_size() const { return args_Size; } | |||
1232 | llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); } | |||
1233 | ||||
1234 | ||||
1235 | ||||
1236 | ||||
1237 | static bool classof(const Attr *A) { return A->getKind() == attr::AssertExclusiveLock; } | |||
1238 | }; | |||
1239 | ||||
1240 | class AssertSharedLockAttr : public InheritableAttr { | |||
1241 | unsigned args_Size; | |||
1242 | Expr * *args_; | |||
1243 | ||||
1244 | public: | |||
1245 | static AssertSharedLockAttr *CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) { | |||
1246 | auto *A = new (Ctx) AssertSharedLockAttr(Loc, Ctx, Args, ArgsSize, 0); | |||
1247 | A->setImplicit(true); | |||
1248 | return A; | |||
1249 | } | |||
1250 | ||||
1251 | AssertSharedLockAttr(SourceRange R, ASTContext &Ctx | |||
1252 | , Expr * *Args, unsigned ArgsSize | |||
1253 | , unsigned SI | |||
1254 | ) | |||
1255 | : InheritableAttr(attr::AssertSharedLock, R, SI, true, true) | |||
1256 | , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size]) | |||
1257 | { | |||
1258 | std::copy(Args, Args + args_Size, args_); | |||
1259 | } | |||
1260 | ||||
1261 | AssertSharedLockAttr(SourceRange R, ASTContext &Ctx | |||
1262 | , unsigned SI | |||
1263 | ) | |||
1264 | : InheritableAttr(attr::AssertSharedLock, R, SI, true, true) | |||
1265 | , args_Size(0), args_(nullptr) | |||
1266 | { | |||
1267 | } | |||
1268 | ||||
1269 | AssertSharedLockAttr *clone(ASTContext &C) const; | |||
1270 | void printPretty(raw_ostream &OS, | |||
1271 | const PrintingPolicy &Policy) const; | |||
1272 | const char *getSpelling() const; | |||
1273 | typedef Expr ** args_iterator; | |||
1274 | args_iterator args_begin() const { return args_; } | |||
1275 | args_iterator args_end() const { return args_ + args_Size; } | |||
1276 | unsigned args_size() const { return args_Size; } | |||
1277 | llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); } | |||
1278 | ||||
1279 | ||||
1280 | ||||
1281 | ||||
1282 | static bool classof(const Attr *A) { return A->getKind() == attr::AssertSharedLock; } | |||
1283 | }; | |||
1284 | ||||
1285 | class AssumeAlignedAttr : public InheritableAttr { | |||
1286 | Expr * alignment; | |||
1287 | ||||
1288 | Expr * offset; | |||
1289 | ||||
1290 | public: | |||
1291 | static AssumeAlignedAttr *CreateImplicit(ASTContext &Ctx, Expr * Alignment, Expr * Offset, SourceRange Loc = SourceRange()) { | |||
1292 | auto *A = new (Ctx) AssumeAlignedAttr(Loc, Ctx, Alignment, Offset, 0); | |||
1293 | A->setImplicit(true); | |||
1294 | return A; | |||
1295 | } | |||
1296 | ||||
1297 | AssumeAlignedAttr(SourceRange R, ASTContext &Ctx | |||
1298 | , Expr * Alignment | |||
1299 | , Expr * Offset | |||
1300 | , unsigned SI | |||
1301 | ) | |||
1302 | : InheritableAttr(attr::AssumeAligned, R, SI, false, false) | |||
1303 | , alignment(Alignment) | |||
1304 | , offset(Offset) | |||
1305 | { | |||
1306 | } | |||
1307 | ||||
1308 | AssumeAlignedAttr(SourceRange R, ASTContext &Ctx | |||
1309 | , Expr * Alignment | |||
1310 | , unsigned SI | |||
1311 | ) | |||
1312 | : InheritableAttr(attr::AssumeAligned, R, SI, false, false) | |||
1313 | , alignment(Alignment) | |||
1314 | , offset() | |||
1315 | { | |||
1316 | } | |||
1317 | ||||
1318 | AssumeAlignedAttr *clone(ASTContext &C) const; | |||
1319 | void printPretty(raw_ostream &OS, | |||
1320 | const PrintingPolicy &Policy) const; | |||
1321 | const char *getSpelling() const; | |||
1322 | Expr * getAlignment() const { | |||
1323 | return alignment; | |||
1324 | } | |||
1325 | ||||
1326 | Expr * getOffset() const { | |||
1327 | return offset; | |||
1328 | } | |||
1329 | ||||
1330 | ||||
1331 | ||||
1332 | static bool classof(const Attr *A) { return A->getKind() == attr::AssumeAligned; } | |||
1333 | }; | |||
1334 | ||||
1335 | class AvailabilityAttr : public InheritableAttr { | |||
1336 | IdentifierInfo * platform; | |||
1337 | ||||
1338 | VersionTuple introduced; | |||
1339 | ||||
1340 | ||||
1341 | VersionTuple deprecated; | |||
1342 | ||||
1343 | ||||
1344 | VersionTuple obsoleted; | |||
1345 | ||||
1346 | ||||
1347 | bool unavailable; | |||
1348 | ||||
1349 | unsigned messageLength; | |||
1350 | char *message; | |||
1351 | ||||
1352 | bool strict; | |||
1353 | ||||
1354 | unsigned replacementLength; | |||
1355 | char *replacement; | |||
1356 | ||||
1357 | public: | |||
1358 | static AvailabilityAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * Platform, VersionTuple Introduced, VersionTuple Deprecated, VersionTuple Obsoleted, bool Unavailable, llvm::StringRef Message, bool Strict, llvm::StringRef Replacement, SourceRange Loc = SourceRange()) { | |||
1359 | auto *A = new (Ctx) AvailabilityAttr(Loc, Ctx, Platform, Introduced, Deprecated, Obsoleted, Unavailable, Message, Strict, Replacement, 0); | |||
1360 | A->setImplicit(true); | |||
1361 | return A; | |||
1362 | } | |||
1363 | ||||
1364 | AvailabilityAttr(SourceRange R, ASTContext &Ctx | |||
1365 | , IdentifierInfo * Platform | |||
1366 | , VersionTuple Introduced | |||
1367 | , VersionTuple Deprecated | |||
1368 | , VersionTuple Obsoleted | |||
1369 | , bool Unavailable | |||
1370 | , llvm::StringRef Message | |||
1371 | , bool Strict | |||
1372 | , llvm::StringRef Replacement | |||
1373 | , unsigned SI | |||
1374 | ) | |||
1375 | : InheritableAttr(attr::Availability, R, SI, false, true) | |||
1376 | , platform(Platform) | |||
1377 | , introduced(Introduced) | |||
1378 | , deprecated(Deprecated) | |||
1379 | , obsoleted(Obsoleted) | |||
1380 | , unavailable(Unavailable) | |||
1381 | , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength]) | |||
1382 | , strict(Strict) | |||
1383 | , replacementLength(Replacement.size()),replacement(new (Ctx, 1) char[replacementLength]) | |||
1384 | { | |||
1385 | if (!Message.empty()) | |||
1386 | std::memcpy(message, Message.data(), messageLength); | |||
1387 | if (!Replacement.empty()) | |||
1388 | std::memcpy(replacement, Replacement.data(), replacementLength); | |||
1389 | } | |||
1390 | ||||
1391 | AvailabilityAttr *clone(ASTContext &C) const; | |||
1392 | void printPretty(raw_ostream &OS, | |||
1393 | const PrintingPolicy &Policy) const; | |||
1394 | const char *getSpelling() const; | |||
1395 | IdentifierInfo * getPlatform() const { | |||
1396 | return platform; | |||
1397 | } | |||
1398 | ||||
1399 | VersionTuple getIntroduced() const { | |||
1400 | return introduced; | |||
1401 | } | |||
1402 | void setIntroduced(ASTContext &C, VersionTuple V) { | |||
1403 | introduced = V; | |||
1404 | } | |||
1405 | ||||
1406 | VersionTuple getDeprecated() const { | |||
1407 | return deprecated; | |||
1408 | } | |||
1409 | void setDeprecated(ASTContext &C, VersionTuple V) { | |||
1410 | deprecated = V; | |||
1411 | } | |||
1412 | ||||
1413 | VersionTuple getObsoleted() const { | |||
1414 | return obsoleted; | |||
1415 | } | |||
1416 | void setObsoleted(ASTContext &C, VersionTuple V) { | |||
1417 | obsoleted = V; | |||
1418 | } | |||
1419 | ||||
1420 | bool getUnavailable() const { | |||
1421 | return unavailable; | |||
1422 | } | |||
1423 | ||||
1424 | llvm::StringRef getMessage() const { | |||
1425 | return llvm::StringRef(message, messageLength); | |||
1426 | } | |||
1427 | unsigned getMessageLength() const { | |||
1428 | return messageLength; | |||
1429 | } | |||
1430 | void setMessage(ASTContext &C, llvm::StringRef S) { | |||
1431 | messageLength = S.size(); | |||
1432 | this->message = new (C, 1) char [messageLength]; | |||
1433 | if (!S.empty()) | |||
1434 | std::memcpy(this->message, S.data(), messageLength); | |||
1435 | } | |||
1436 | ||||
1437 | bool getStrict() const { | |||
1438 | return strict; | |||
1439 | } | |||
1440 | ||||
1441 | llvm::StringRef getReplacement() const { | |||
1442 | return llvm::StringRef(replacement, replacementLength); | |||
1443 | } | |||
1444 | unsigned getReplacementLength() const { | |||
1445 | return replacementLength; | |||
1446 | } | |||
1447 | void setReplacement(ASTContext &C, llvm::StringRef S) { | |||
1448 | replacementLength = S.size(); | |||
1449 | this->replacement = new (C, 1) char [replacementLength]; | |||
1450 | if (!S.empty()) | |||
1451 | std::memcpy(this->replacement, S.data(), replacementLength); | |||
1452 | } | |||
1453 | ||||
1454 | static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) { | |||
1455 | return llvm::StringSwitch<llvm::StringRef>(Platform) | |||
1456 | .Case("android", "Android") | |||
1457 | .Case("ios", "iOS") | |||
1458 | .Case("macos", "macOS") | |||
1459 | .Case("tvos", "tvOS") | |||
1460 | .Case("watchos", "watchOS") | |||
1461 | .Case("ios_app_extension", "iOS (App Extension)") | |||
1462 | .Case("macos_app_extension", "macOS (App Extension)") | |||
1463 | .Case("tvos_app_extension", "tvOS (App Extension)") | |||
1464 | .Case("watchos_app_extension", "watchOS (App Extension)") | |||
1465 | .Default(llvm::StringRef()); | |||
1466 | } | |||
1467 | static llvm::StringRef getPlatformNameSourceSpelling(llvm::StringRef Platform) { | |||
1468 | return llvm::StringSwitch<llvm::StringRef>(Platform) | |||
1469 | .Case("ios", "iOS") | |||
1470 | .Case("macos", "macOS") | |||
1471 | .Case("tvos", "tvOS") | |||
1472 | .Case("watchos", "watchOS") | |||
1473 | .Case("ios_app_extension", "iOSApplicationExtension") | |||
1474 | .Case("macos_app_extension", "macOSApplicationExtension") | |||
1475 | .Case("tvos_app_extension", "tvOSApplicationExtension") | |||
1476 | .Case("watchos_app_extension", "watchOSApplicationExtension") | |||
1477 | .Default(Platform); | |||
1478 | } | |||
1479 | static llvm::StringRef canonicalizePlatformName(llvm::StringRef Platform) { | |||
1480 | return llvm::StringSwitch<llvm::StringRef>(Platform) | |||
1481 | .Case("iOS", "ios") | |||
1482 | .Case("macOS", "macos") | |||
1483 | .Case("tvOS", "tvos") | |||
1484 | .Case("watchOS", "watchos") | |||
1485 | .Case("iOSApplicationExtension", "ios_app_extension") | |||
1486 | .Case("macOSApplicationExtension", "macos_app_extension") | |||
1487 | .Case("tvOSApplicationExtension", "tvos_app_extension") | |||
1488 | .Case("watchOSApplicationExtension", "watchos_app_extension") | |||
1489 | .Default(Platform); | |||
1490 | } | |||
1491 | ||||
1492 | static bool classof(const Attr *A) { return A->getKind() == attr::Availability; } | |||
1493 | }; | |||
1494 | ||||
1495 | class BlocksAttr : public InheritableAttr { | |||
1496 | public: | |||
1497 | enum BlockType { | |||
1498 | ByRef | |||
1499 | }; | |||
1500 | private: | |||
1501 | BlockType type; | |||
1502 | ||||
1503 | public: | |||
1504 | static BlocksAttr *CreateImplicit(ASTContext &Ctx, BlockType Type, SourceRange Loc = SourceRange()) { | |||
1505 | auto *A = new (Ctx) BlocksAttr(Loc, Ctx, Type, 0); | |||
1506 | A->setImplicit(true); | |||
1507 | return A; | |||
1508 | } | |||
1509 | ||||
1510 | BlocksAttr(SourceRange R, ASTContext &Ctx | |||
1511 | , BlockType Type | |||
1512 | , unsigned SI | |||
1513 | ) | |||
1514 | : InheritableAttr(attr::Blocks, R, SI, false, false) | |||
1515 | , type(Type) | |||
1516 | { | |||
1517 | } | |||
1518 | ||||
1519 | BlocksAttr *clone(ASTContext &C) const; | |||
1520 | void printPretty(raw_ostream &OS, | |||
1521 | const PrintingPolicy &Policy) const; | |||
1522 | const char *getSpelling() const; | |||
1523 | BlockType getType() const { | |||
1524 | return type; | |||
1525 | } | |||
1526 | ||||
1527 | static bool ConvertStrToBlockType(StringRef Val, BlockType &Out) { | |||
1528 | Optional<BlockType> R = llvm::StringSwitch<Optional<BlockType>>(Val) | |||
1529 | .Case("byref", BlocksAttr::ByRef) | |||
1530 | .Default(Optional<BlockType>()); | |||
1531 | if (R) { | |||
1532 | Out = *R; | |||
1533 | return true; | |||
1534 | } | |||
1535 | return false; | |||
1536 | } | |||
1537 | ||||
1538 | static const char *ConvertBlockTypeToStr(BlockType Val) { | |||
1539 | switch(Val) { | |||
1540 | case BlocksAttr::ByRef: return "byref"; | |||
1541 | } | |||
1542 | llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 1542); | |||
1543 | } | |||
1544 | ||||
1545 | ||||
1546 | static bool classof(const Attr *A) { return A->getKind() == attr::Blocks; } | |||
1547 | }; | |||
1548 | ||||
1549 | class C11NoReturnAttr : public InheritableAttr { | |||
1550 | public: | |||
1551 | static C11NoReturnAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
1552 | auto *A = new (Ctx) C11NoReturnAttr(Loc, Ctx, 0); | |||
1553 | A->setImplicit(true); | |||
1554 | return A; | |||
1555 | } | |||
1556 | ||||
1557 | C11NoReturnAttr(SourceRange R, ASTContext &Ctx | |||
1558 | , unsigned SI | |||
1559 | ) | |||
1560 | : InheritableAttr(attr::C11NoReturn, R, SI, false, false) | |||
1561 | { | |||
1562 | } | |||
1563 | ||||
1564 | C11NoReturnAttr *clone(ASTContext &C) const; | |||
1565 | void printPretty(raw_ostream &OS, | |||
1566 | const PrintingPolicy &Policy) const; | |||
1567 | const char *getSpelling() const; | |||
1568 | ||||
1569 | ||||
1570 | static bool classof(const Attr *A) { return A->getKind() == attr::C11NoReturn; } | |||
1571 | }; | |||
1572 | ||||
1573 | class CDeclAttr : public InheritableAttr { | |||
1574 | public: | |||
1575 | static CDeclAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
1576 | auto *A = new (Ctx) CDeclAttr(Loc, Ctx, 0); | |||
1577 | A->setImplicit(true); | |||
1578 | return A; | |||
1579 | } | |||
1580 | ||||
1581 | CDeclAttr(SourceRange R, ASTContext &Ctx | |||
1582 | , unsigned SI | |||
1583 | ) | |||
1584 | : InheritableAttr(attr::CDecl, R, SI, false, false) | |||
1585 | { | |||
1586 | } | |||
1587 | ||||
1588 | CDeclAttr *clone(ASTContext &C) const; | |||
1589 | void printPretty(raw_ostream &OS, | |||
1590 | const PrintingPolicy &Policy) const; | |||
1591 | const char *getSpelling() const; | |||
1592 | ||||
1593 | ||||
1594 | static bool classof(const Attr *A) { return A->getKind() == attr::CDecl; } | |||
1595 | }; | |||
1596 | ||||
1597 | class CFAuditedTransferAttr : public InheritableAttr { | |||
1598 | public: | |||
1599 | static CFAuditedTransferAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
1600 | auto *A = new (Ctx) CFAuditedTransferAttr(Loc, Ctx, 0); | |||
1601 | A->setImplicit(true); | |||
1602 | return A; | |||
1603 | } | |||
1604 | ||||
1605 | CFAuditedTransferAttr(SourceRange R, ASTContext &Ctx | |||
1606 | , unsigned SI | |||
1607 | ) | |||
1608 | : InheritableAttr(attr::CFAuditedTransfer, R, SI, false, false) | |||
1609 | { | |||
1610 | } | |||
1611 | ||||
1612 | CFAuditedTransferAttr *clone(ASTContext &C) const; | |||
1613 | void printPretty(raw_ostream &OS, | |||
1614 | const PrintingPolicy &Policy) const; | |||
1615 | const char *getSpelling() const; | |||
1616 | ||||
1617 | ||||
1618 | static bool classof(const Attr *A) { return A->getKind() == attr::CFAuditedTransfer; } | |||
1619 | }; | |||
1620 | ||||
1621 | class CFConsumedAttr : public InheritableParamAttr { | |||
1622 | public: | |||
1623 | static CFConsumedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
1624 | auto *A = new (Ctx) CFConsumedAttr(Loc, Ctx, 0); | |||
1625 | A->setImplicit(true); | |||
1626 | return A; | |||
1627 | } | |||
1628 | ||||
1629 | CFConsumedAttr(SourceRange R, ASTContext &Ctx | |||
1630 | , unsigned SI | |||
1631 | ) | |||
1632 | : InheritableParamAttr(attr::CFConsumed, R, SI, false, false) | |||
1633 | { | |||
1634 | } | |||
1635 | ||||
1636 | CFConsumedAttr *clone(ASTContext &C) const; | |||
1637 | void printPretty(raw_ostream &OS, | |||
1638 | const PrintingPolicy &Policy) const; | |||
1639 | const char *getSpelling() const; | |||
1640 | ||||
1641 | ||||
1642 | static bool classof(const Attr *A) { return A->getKind() == attr::CFConsumed; } | |||
1643 | }; | |||
1644 | ||||
1645 | class CFReturnsNotRetainedAttr : public InheritableAttr { | |||
1646 | public: | |||
1647 | static CFReturnsNotRetainedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
1648 | auto *A = new (Ctx) CFReturnsNotRetainedAttr(Loc, Ctx, 0); | |||
1649 | A->setImplicit(true); | |||
1650 | return A; | |||
1651 | } | |||
1652 | ||||
1653 | CFReturnsNotRetainedAttr(SourceRange R, ASTContext &Ctx | |||
1654 | , unsigned SI | |||
1655 | ) | |||
1656 | : InheritableAttr(attr::CFReturnsNotRetained, R, SI, false, false) | |||
1657 | { | |||
1658 | } | |||
1659 | ||||
1660 | CFReturnsNotRetainedAttr *clone(ASTContext &C) const; | |||
1661 | void printPretty(raw_ostream &OS, | |||
1662 | const PrintingPolicy &Policy) const; | |||
1663 | const char *getSpelling() const; | |||
1664 | ||||
1665 | ||||
1666 | static bool classof(const Attr *A) { return A->getKind() == attr::CFReturnsNotRetained; } | |||
1667 | }; | |||
1668 | ||||
1669 | class CFReturnsRetainedAttr : public InheritableAttr { | |||
1670 | public: | |||
1671 | static CFReturnsRetainedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
1672 | auto *A = new (Ctx) CFReturnsRetainedAttr(Loc, Ctx, 0); | |||
1673 | A->setImplicit(true); | |||
1674 | return A; | |||
1675 | } | |||
1676 | ||||
1677 | CFReturnsRetainedAttr(SourceRange R, ASTContext &Ctx | |||
1678 | , unsigned SI | |||
1679 | ) | |||
1680 | : InheritableAttr(attr::CFReturnsRetained, R, SI, false, false) | |||
1681 | { | |||
1682 | } | |||
1683 | ||||
1684 | CFReturnsRetainedAttr *clone(ASTContext &C) const; | |||
1685 | void printPretty(raw_ostream &OS, | |||
1686 | const PrintingPolicy &Policy) const; | |||
1687 | const char *getSpelling() const; | |||
1688 | ||||
1689 | ||||
1690 | static bool classof(const Attr *A) { return A->getKind() == attr::CFReturnsRetained; } | |||
1691 | }; | |||
1692 | ||||
1693 | class CFUnknownTransferAttr : public InheritableAttr { | |||
1694 | public: | |||
1695 | static CFUnknownTransferAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
1696 | auto *A = new (Ctx) CFUnknownTransferAttr(Loc, Ctx, 0); | |||
1697 | A->setImplicit(true); | |||
1698 | return A; | |||
1699 | } | |||
1700 | ||||
1701 | CFUnknownTransferAttr(SourceRange R, ASTContext &Ctx | |||
1702 | , unsigned SI | |||
1703 | ) | |||
1704 | : InheritableAttr(attr::CFUnknownTransfer, R, SI, false, false) | |||
1705 | { | |||
1706 | } | |||
1707 | ||||
1708 | CFUnknownTransferAttr *clone(ASTContext &C) const; | |||
1709 | void printPretty(raw_ostream &OS, | |||
1710 | const PrintingPolicy &Policy) const; | |||
1711 | const char *getSpelling() const; | |||
1712 | ||||
1713 | ||||
1714 | static bool classof(const Attr *A) { return A->getKind() == attr::CFUnknownTransfer; } | |||
1715 | }; | |||
1716 | ||||
1717 | class CPUDispatchAttr : public InheritableAttr { | |||
1718 | unsigned cpus_Size; | |||
1719 | IdentifierInfo * *cpus_; | |||
1720 | ||||
1721 | public: | |||
1722 | static CPUDispatchAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * *Cpus, unsigned CpusSize, SourceRange Loc = SourceRange()) { | |||
1723 | auto *A = new (Ctx) CPUDispatchAttr(Loc, Ctx, Cpus, CpusSize, 0); | |||
1724 | A->setImplicit(true); | |||
1725 | return A; | |||
1726 | } | |||
1727 | ||||
1728 | CPUDispatchAttr(SourceRange R, ASTContext &Ctx | |||
1729 | , IdentifierInfo * *Cpus, unsigned CpusSize | |||
1730 | , unsigned SI | |||
1731 | ) | |||
1732 | : InheritableAttr(attr::CPUDispatch, R, SI, false, false) | |||
1733 | , cpus_Size(CpusSize), cpus_(new (Ctx, 16) IdentifierInfo *[cpus_Size]) | |||
1734 | { | |||
1735 | std::copy(Cpus, Cpus + cpus_Size, cpus_); | |||
1736 | } | |||
1737 | ||||
1738 | CPUDispatchAttr(SourceRange R, ASTContext &Ctx | |||
1739 | , unsigned SI | |||
1740 | ) | |||
1741 | : InheritableAttr(attr::CPUDispatch, R, SI, false, false) | |||
1742 | , cpus_Size(0), cpus_(nullptr) | |||
1743 | { | |||
1744 | } | |||
1745 | ||||
1746 | CPUDispatchAttr *clone(ASTContext &C) const; | |||
1747 | void printPretty(raw_ostream &OS, | |||
1748 | const PrintingPolicy &Policy) const; | |||
1749 | const char *getSpelling() const; | |||
1750 | typedef IdentifierInfo ** cpus_iterator; | |||
1751 | cpus_iterator cpus_begin() const { return cpus_; } | |||
1752 | cpus_iterator cpus_end() const { return cpus_ + cpus_Size; } | |||
1753 | unsigned cpus_size() const { return cpus_Size; } | |||
1754 | llvm::iterator_range<cpus_iterator> cpus() const { return llvm::make_range(cpus_begin(), cpus_end()); } | |||
1755 | ||||
1756 | ||||
1757 | ||||
1758 | ||||
1759 | static bool classof(const Attr *A) { return A->getKind() == attr::CPUDispatch; } | |||
1760 | }; | |||
1761 | ||||
1762 | class CPUSpecificAttr : public InheritableAttr { | |||
1763 | unsigned cpus_Size; | |||
1764 | IdentifierInfo * *cpus_; | |||
1765 | ||||
1766 | public: | |||
1767 | static CPUSpecificAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * *Cpus, unsigned CpusSize, SourceRange Loc = SourceRange()) { | |||
1768 | auto *A = new (Ctx) CPUSpecificAttr(Loc, Ctx, Cpus, CpusSize, 0); | |||
1769 | A->setImplicit(true); | |||
1770 | return A; | |||
1771 | } | |||
1772 | ||||
1773 | CPUSpecificAttr(SourceRange R, ASTContext &Ctx | |||
1774 | , IdentifierInfo * *Cpus, unsigned CpusSize | |||
1775 | , unsigned SI | |||
1776 | ) | |||
1777 | : InheritableAttr(attr::CPUSpecific, R, SI, false, false) | |||
1778 | , cpus_Size(CpusSize), cpus_(new (Ctx, 16) IdentifierInfo *[cpus_Size]) | |||
1779 | { | |||
1780 | std::copy(Cpus, Cpus + cpus_Size, cpus_); | |||
1781 | } | |||
1782 | ||||
1783 | CPUSpecificAttr(SourceRange R, ASTContext &Ctx | |||
1784 | , unsigned SI | |||
1785 | ) | |||
1786 | : InheritableAttr(attr::CPUSpecific, R, SI, false, false) | |||
1787 | , cpus_Size(0), cpus_(nullptr) | |||
1788 | { | |||
1789 | } | |||
1790 | ||||
1791 | CPUSpecificAttr *clone(ASTContext &C) const; | |||
1792 | void printPretty(raw_ostream &OS, | |||
1793 | const PrintingPolicy &Policy) const; | |||
1794 | const char *getSpelling() const; | |||
1795 | typedef IdentifierInfo ** cpus_iterator; | |||
1796 | cpus_iterator cpus_begin() const { return cpus_; } | |||
1797 | cpus_iterator cpus_end() const { return cpus_ + cpus_Size; } | |||
1798 | unsigned cpus_size() const { return cpus_Size; } | |||
1799 | llvm::iterator_range<cpus_iterator> cpus() const { return llvm::make_range(cpus_begin(), cpus_end()); } | |||
1800 | ||||
1801 | ||||
1802 | ||||
1803 | unsigned ActiveArgIndex = 0; | |||
1804 | ||||
1805 | IdentifierInfo *getCurCPUName() const { | |||
1806 | return *(cpus_begin() + ActiveArgIndex); | |||
1807 | } | |||
1808 | ||||
1809 | ||||
1810 | static bool classof(const Attr *A) { return A->getKind() == attr::CPUSpecific; } | |||
1811 | }; | |||
1812 | ||||
1813 | class CUDAConstantAttr : public InheritableAttr { | |||
1814 | public: | |||
1815 | static CUDAConstantAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
1816 | auto *A = new (Ctx) CUDAConstantAttr(Loc, Ctx, 0); | |||
1817 | A->setImplicit(true); | |||
1818 | return A; | |||
1819 | } | |||
1820 | ||||
1821 | CUDAConstantAttr(SourceRange R, ASTContext &Ctx | |||
1822 | , unsigned SI | |||
1823 | ) | |||
1824 | : InheritableAttr(attr::CUDAConstant, R, SI, false, false) | |||
1825 | { | |||
1826 | } | |||
1827 | ||||
1828 | CUDAConstantAttr *clone(ASTContext &C) const; | |||
1829 | void printPretty(raw_ostream &OS, | |||
1830 | const PrintingPolicy &Policy) const; | |||
1831 | const char *getSpelling() const; | |||
1832 | ||||
1833 | ||||
1834 | static bool classof(const Attr *A) { return A->getKind() == attr::CUDAConstant; } | |||
1835 | }; | |||
1836 | ||||
1837 | class CUDADeviceAttr : public InheritableAttr { | |||
1838 | public: | |||
1839 | static CUDADeviceAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
1840 | auto *A = new (Ctx) CUDADeviceAttr(Loc, Ctx, 0); | |||
1841 | A->setImplicit(true); | |||
1842 | return A; | |||
1843 | } | |||
1844 | ||||
1845 | CUDADeviceAttr(SourceRange R, ASTContext &Ctx | |||
1846 | , unsigned SI | |||
1847 | ) | |||
1848 | : InheritableAttr(attr::CUDADevice, R, SI, false, false) | |||
1849 | { | |||
1850 | } | |||
1851 | ||||
1852 | CUDADeviceAttr *clone(ASTContext &C) const; | |||
1853 | void printPretty(raw_ostream &OS, | |||
1854 | const PrintingPolicy &Policy) const; | |||
1855 | const char *getSpelling() const; | |||
1856 | ||||
1857 | ||||
1858 | static bool classof(const Attr *A) { return A->getKind() == attr::CUDADevice; } | |||
1859 | }; | |||
1860 | ||||
1861 | class CUDAGlobalAttr : public InheritableAttr { | |||
1862 | public: | |||
1863 | static CUDAGlobalAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
1864 | auto *A = new (Ctx) CUDAGlobalAttr(Loc, Ctx, 0); | |||
1865 | A->setImplicit(true); | |||
1866 | return A; | |||
1867 | } | |||
1868 | ||||
1869 | CUDAGlobalAttr(SourceRange R, ASTContext &Ctx | |||
1870 | , unsigned SI | |||
1871 | ) | |||
1872 | : InheritableAttr(attr::CUDAGlobal, R, SI, false, false) | |||
1873 | { | |||
1874 | } | |||
1875 | ||||
1876 | CUDAGlobalAttr *clone(ASTContext &C) const; | |||
1877 | void printPretty(raw_ostream &OS, | |||
1878 | const PrintingPolicy &Policy) const; | |||
1879 | const char *getSpelling() const; | |||
1880 | ||||
1881 | ||||
1882 | static bool classof(const Attr *A) { return A->getKind() == attr::CUDAGlobal; } | |||
1883 | }; | |||
1884 | ||||
1885 | class CUDAHostAttr : public InheritableAttr { | |||
1886 | public: | |||
1887 | static CUDAHostAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
1888 | auto *A = new (Ctx) CUDAHostAttr(Loc, Ctx, 0); | |||
1889 | A->setImplicit(true); | |||
1890 | return A; | |||
1891 | } | |||
1892 | ||||
1893 | CUDAHostAttr(SourceRange R, ASTContext &Ctx | |||
1894 | , unsigned SI | |||
1895 | ) | |||
1896 | : InheritableAttr(attr::CUDAHost, R, SI, false, false) | |||
1897 | { | |||
1898 | } | |||
1899 | ||||
1900 | CUDAHostAttr *clone(ASTContext &C) const; | |||
1901 | void printPretty(raw_ostream &OS, | |||
1902 | const PrintingPolicy &Policy) const; | |||
1903 | const char *getSpelling() const; | |||
1904 | ||||
1905 | ||||
1906 | static bool classof(const Attr *A) { return A->getKind() == attr::CUDAHost; } | |||
1907 | }; | |||
1908 | ||||
1909 | class CUDAInvalidTargetAttr : public InheritableAttr { | |||
1910 | public: | |||
1911 | static CUDAInvalidTargetAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
1912 | auto *A = new (Ctx) CUDAInvalidTargetAttr(Loc, Ctx, 0); | |||
1913 | A->setImplicit(true); | |||
1914 | return A; | |||
1915 | } | |||
1916 | ||||
1917 | CUDAInvalidTargetAttr(SourceRange R, ASTContext &Ctx | |||
1918 | , unsigned SI | |||
1919 | ) | |||
1920 | : InheritableAttr(attr::CUDAInvalidTarget, R, SI, false, false) | |||
1921 | { | |||
1922 | } | |||
1923 | ||||
1924 | CUDAInvalidTargetAttr *clone(ASTContext &C) const; | |||
1925 | void printPretty(raw_ostream &OS, | |||
1926 | const PrintingPolicy &Policy) const; | |||
1927 | const char *getSpelling() const; | |||
1928 | ||||
1929 | ||||
1930 | static bool classof(const Attr *A) { return A->getKind() == attr::CUDAInvalidTarget; } | |||
1931 | }; | |||
1932 | ||||
1933 | class CUDALaunchBoundsAttr : public InheritableAttr { | |||
1934 | Expr * maxThreads; | |||
1935 | ||||
1936 | Expr * minBlocks; | |||
1937 | ||||
1938 | public: | |||
1939 | static CUDALaunchBoundsAttr *CreateImplicit(ASTContext &Ctx, Expr * MaxThreads, Expr * MinBlocks, SourceRange Loc = SourceRange()) { | |||
1940 | auto *A = new (Ctx) CUDALaunchBoundsAttr(Loc, Ctx, MaxThreads, MinBlocks, 0); | |||
1941 | A->setImplicit(true); | |||
1942 | return A; | |||
1943 | } | |||
1944 | ||||
1945 | CUDALaunchBoundsAttr(SourceRange R, ASTContext &Ctx | |||
1946 | , Expr * MaxThreads | |||
1947 | , Expr * MinBlocks | |||
1948 | , unsigned SI | |||
1949 | ) | |||
1950 | : InheritableAttr(attr::CUDALaunchBounds, R, SI, false, false) | |||
1951 | , maxThreads(MaxThreads) | |||
1952 | , minBlocks(MinBlocks) | |||
1953 | { | |||
1954 | } | |||
1955 | ||||
1956 | CUDALaunchBoundsAttr(SourceRange R, ASTContext &Ctx | |||
1957 | , Expr * MaxThreads | |||
1958 | , unsigned SI | |||
1959 | ) | |||
1960 | : InheritableAttr(attr::CUDALaunchBounds, R, SI, false, false) | |||
1961 | , maxThreads(MaxThreads) | |||
1962 | , minBlocks() | |||
1963 | { | |||
1964 | } | |||
1965 | ||||
1966 | CUDALaunchBoundsAttr *clone(ASTContext &C) const; | |||
1967 | void printPretty(raw_ostream &OS, | |||
1968 | const PrintingPolicy &Policy) const; | |||
1969 | const char *getSpelling() const; | |||
1970 | Expr * getMaxThreads() const { | |||
1971 | return maxThreads; | |||
1972 | } | |||
1973 | ||||
1974 | Expr * getMinBlocks() const { | |||
1975 | return minBlocks; | |||
1976 | } | |||
1977 | ||||
1978 | ||||
1979 | ||||
1980 | static bool classof(const Attr *A) { return A->getKind() == attr::CUDALaunchBounds; } | |||
1981 | }; | |||
1982 | ||||
1983 | class CUDASharedAttr : public InheritableAttr { | |||
1984 | public: | |||
1985 | static CUDASharedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
1986 | auto *A = new (Ctx) CUDASharedAttr(Loc, Ctx, 0); | |||
1987 | A->setImplicit(true); | |||
1988 | return A; | |||
1989 | } | |||
1990 | ||||
1991 | CUDASharedAttr(SourceRange R, ASTContext &Ctx | |||
1992 | , unsigned SI | |||
1993 | ) | |||
1994 | : InheritableAttr(attr::CUDAShared, R, SI, false, false) | |||
1995 | { | |||
1996 | } | |||
1997 | ||||
1998 | CUDASharedAttr *clone(ASTContext &C) const; | |||
1999 | void printPretty(raw_ostream &OS, | |||
2000 | const PrintingPolicy &Policy) const; | |||
2001 | const char *getSpelling() const; | |||
2002 | ||||
2003 | ||||
2004 | static bool classof(const Attr *A) { return A->getKind() == attr::CUDAShared; } | |||
2005 | }; | |||
2006 | ||||
2007 | class CXX11NoReturnAttr : public InheritableAttr { | |||
2008 | public: | |||
2009 | static CXX11NoReturnAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
2010 | auto *A = new (Ctx) CXX11NoReturnAttr(Loc, Ctx, 0); | |||
2011 | A->setImplicit(true); | |||
2012 | return A; | |||
2013 | } | |||
2014 | ||||
2015 | CXX11NoReturnAttr(SourceRange R, ASTContext &Ctx | |||
2016 | , unsigned SI | |||
2017 | ) | |||
2018 | : InheritableAttr(attr::CXX11NoReturn, R, SI, false, false) | |||
2019 | { | |||
2020 | } | |||
2021 | ||||
2022 | CXX11NoReturnAttr *clone(ASTContext &C) const; | |||
2023 | void printPretty(raw_ostream &OS, | |||
2024 | const PrintingPolicy &Policy) const; | |||
2025 | const char *getSpelling() const; | |||
2026 | ||||
2027 | ||||
2028 | static bool classof(const Attr *A) { return A->getKind() == attr::CXX11NoReturn; } | |||
2029 | }; | |||
2030 | ||||
2031 | class CallableWhenAttr : public InheritableAttr { | |||
2032 | public: | |||
2033 | enum ConsumedState { | |||
2034 | Unknown, | |||
2035 | Consumed, | |||
2036 | Unconsumed | |||
2037 | }; | |||
2038 | private: | |||
2039 | unsigned callableStates_Size; | |||
2040 | ConsumedState *callableStates_; | |||
2041 | ||||
2042 | public: | |||
2043 | static CallableWhenAttr *CreateImplicit(ASTContext &Ctx, ConsumedState *CallableStates, unsigned CallableStatesSize, SourceRange Loc = SourceRange()) { | |||
2044 | auto *A = new (Ctx) CallableWhenAttr(Loc, Ctx, CallableStates, CallableStatesSize, 0); | |||
2045 | A->setImplicit(true); | |||
2046 | return A; | |||
2047 | } | |||
2048 | ||||
2049 | CallableWhenAttr(SourceRange R, ASTContext &Ctx | |||
2050 | , ConsumedState *CallableStates, unsigned CallableStatesSize | |||
2051 | , unsigned SI | |||
2052 | ) | |||
2053 | : InheritableAttr(attr::CallableWhen, R, SI, false, false) | |||
2054 | , callableStates_Size(CallableStatesSize), callableStates_(new (Ctx, 16) ConsumedState[callableStates_Size]) | |||
2055 | { | |||
2056 | std::copy(CallableStates, CallableStates + callableStates_Size, callableStates_); | |||
2057 | } | |||
2058 | ||||
2059 | CallableWhenAttr(SourceRange R, ASTContext &Ctx | |||
2060 | , unsigned SI | |||
2061 | ) | |||
2062 | : InheritableAttr(attr::CallableWhen, R, SI, false, false) | |||
2063 | , callableStates_Size(0), callableStates_(nullptr) | |||
2064 | { | |||
2065 | } | |||
2066 | ||||
2067 | CallableWhenAttr *clone(ASTContext &C) const; | |||
2068 | void printPretty(raw_ostream &OS, | |||
2069 | const PrintingPolicy &Policy) const; | |||
2070 | const char *getSpelling() const; | |||
2071 | typedef ConsumedState* callableStates_iterator; | |||
2072 | callableStates_iterator callableStates_begin() const { return callableStates_; } | |||
2073 | callableStates_iterator callableStates_end() const { return callableStates_ + callableStates_Size; } | |||
2074 | unsigned callableStates_size() const { return callableStates_Size; } | |||
2075 | llvm::iterator_range<callableStates_iterator> callableStates() const { return llvm::make_range(callableStates_begin(), callableStates_end()); } | |||
2076 | ||||
2077 | ||||
2078 | static bool ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) { | |||
2079 | Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val) | |||
2080 | .Case("unknown", CallableWhenAttr::Unknown) | |||
2081 | .Case("consumed", CallableWhenAttr::Consumed) | |||
2082 | .Case("unconsumed", CallableWhenAttr::Unconsumed) | |||
2083 | .Default(Optional<ConsumedState>()); | |||
2084 | if (R) { | |||
2085 | Out = *R; | |||
2086 | return true; | |||
2087 | } | |||
2088 | return false; | |||
2089 | } | |||
2090 | ||||
2091 | static const char *ConvertConsumedStateToStr(ConsumedState Val) { | |||
2092 | switch(Val) { | |||
2093 | case CallableWhenAttr::Unknown: return "unknown"; | |||
2094 | case CallableWhenAttr::Consumed: return "consumed"; | |||
2095 | case CallableWhenAttr::Unconsumed: return "unconsumed"; | |||
2096 | } | |||
2097 | llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 2097); | |||
2098 | } | |||
2099 | ||||
2100 | ||||
2101 | static bool classof(const Attr *A) { return A->getKind() == attr::CallableWhen; } | |||
2102 | }; | |||
2103 | ||||
2104 | class CapabilityAttr : public InheritableAttr { | |||
2105 | unsigned nameLength; | |||
2106 | char *name; | |||
2107 | ||||
2108 | public: | |||
2109 | enum Spelling { | |||
2110 | GNU_capability = 0, | |||
2111 | CXX11_clang_capability = 1, | |||
2112 | GNU_shared_capability = 2, | |||
2113 | CXX11_clang_shared_capability = 3 | |||
2114 | }; | |||
2115 | ||||
2116 | static CapabilityAttr *CreateImplicit(ASTContext &Ctx, Spelling S, llvm::StringRef Name, SourceRange Loc = SourceRange()) { | |||
2117 | auto *A = new (Ctx) CapabilityAttr(Loc, Ctx, Name, S); | |||
2118 | A->setImplicit(true); | |||
2119 | return A; | |||
2120 | } | |||
2121 | ||||
2122 | CapabilityAttr(SourceRange R, ASTContext &Ctx | |||
2123 | , llvm::StringRef Name | |||
2124 | , unsigned SI | |||
2125 | ) | |||
2126 | : InheritableAttr(attr::Capability, R, SI, false, false) | |||
2127 | , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength]) | |||
2128 | { | |||
2129 | if (!Name.empty()) | |||
2130 | std::memcpy(name, Name.data(), nameLength); | |||
2131 | } | |||
2132 | ||||
2133 | CapabilityAttr *clone(ASTContext &C) const; | |||
2134 | void printPretty(raw_ostream &OS, | |||
2135 | const PrintingPolicy &Policy) const; | |||
2136 | const char *getSpelling() const; | |||
2137 | Spelling getSemanticSpelling() const { | |||
2138 | switch (SpellingListIndex) { | |||
2139 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 2139); | |||
2140 | case 0: return GNU_capability; | |||
2141 | case 1: return CXX11_clang_capability; | |||
2142 | case 2: return GNU_shared_capability; | |||
2143 | case 3: return CXX11_clang_shared_capability; | |||
2144 | } | |||
2145 | } | |||
2146 | bool isShared() const { return SpellingListIndex == 2 || | |||
2147 | SpellingListIndex == 3; } | |||
2148 | llvm::StringRef getName() const { | |||
2149 | return llvm::StringRef(name, nameLength); | |||
2150 | } | |||
2151 | unsigned getNameLength() const { | |||
2152 | return nameLength; | |||
2153 | } | |||
2154 | void setName(ASTContext &C, llvm::StringRef S) { | |||
2155 | nameLength = S.size(); | |||
2156 | this->name = new (C, 1) char [nameLength]; | |||
2157 | if (!S.empty()) | |||
2158 | std::memcpy(this->name, S.data(), nameLength); | |||
2159 | } | |||
2160 | ||||
2161 | ||||
2162 | bool isMutex() const { return getName().equals_lower("mutex"); } | |||
2163 | bool isRole() const { return getName().equals_lower("role"); } | |||
2164 | ||||
2165 | ||||
2166 | static bool classof(const Attr *A) { return A->getKind() == attr::Capability; } | |||
2167 | }; | |||
2168 | ||||
2169 | class CapturedRecordAttr : public InheritableAttr { | |||
2170 | public: | |||
2171 | static CapturedRecordAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
2172 | auto *A = new (Ctx) CapturedRecordAttr(Loc, Ctx, 0); | |||
2173 | A->setImplicit(true); | |||
2174 | return A; | |||
2175 | } | |||
2176 | ||||
2177 | CapturedRecordAttr(SourceRange R, ASTContext &Ctx | |||
2178 | , unsigned SI | |||
2179 | ) | |||
2180 | : InheritableAttr(attr::CapturedRecord, R, SI, false, false) | |||
2181 | { | |||
2182 | } | |||
2183 | ||||
2184 | CapturedRecordAttr *clone(ASTContext &C) const; | |||
2185 | void printPretty(raw_ostream &OS, | |||
2186 | const PrintingPolicy &Policy) const; | |||
2187 | const char *getSpelling() const; | |||
2188 | ||||
2189 | ||||
2190 | static bool classof(const Attr *A) { return A->getKind() == attr::CapturedRecord; } | |||
2191 | }; | |||
2192 | ||||
2193 | class CarriesDependencyAttr : public InheritableParamAttr { | |||
2194 | public: | |||
2195 | static CarriesDependencyAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
2196 | auto *A = new (Ctx) CarriesDependencyAttr(Loc, Ctx, 0); | |||
2197 | A->setImplicit(true); | |||
2198 | return A; | |||
2199 | } | |||
2200 | ||||
2201 | CarriesDependencyAttr(SourceRange R, ASTContext &Ctx | |||
2202 | , unsigned SI | |||
2203 | ) | |||
2204 | : InheritableParamAttr(attr::CarriesDependency, R, SI, false, false) | |||
2205 | { | |||
2206 | } | |||
2207 | ||||
2208 | CarriesDependencyAttr *clone(ASTContext &C) const; | |||
2209 | void printPretty(raw_ostream &OS, | |||
2210 | const PrintingPolicy &Policy) const; | |||
2211 | const char *getSpelling() const; | |||
2212 | ||||
2213 | ||||
2214 | static bool classof(const Attr *A) { return A->getKind() == attr::CarriesDependency; } | |||
2215 | }; | |||
2216 | ||||
2217 | class CleanupAttr : public InheritableAttr { | |||
2218 | FunctionDecl * functionDecl; | |||
2219 | ||||
2220 | public: | |||
2221 | static CleanupAttr *CreateImplicit(ASTContext &Ctx, FunctionDecl * FunctionDecl, SourceRange Loc = SourceRange()) { | |||
2222 | auto *A = new (Ctx) CleanupAttr(Loc, Ctx, FunctionDecl, 0); | |||
2223 | A->setImplicit(true); | |||
2224 | return A; | |||
2225 | } | |||
2226 | ||||
2227 | CleanupAttr(SourceRange R, ASTContext &Ctx | |||
2228 | , FunctionDecl * FunctionDecl | |||
2229 | , unsigned SI | |||
2230 | ) | |||
2231 | : InheritableAttr(attr::Cleanup, R, SI, false, false) | |||
2232 | , functionDecl(FunctionDecl) | |||
2233 | { | |||
2234 | } | |||
2235 | ||||
2236 | CleanupAttr *clone(ASTContext &C) const; | |||
2237 | void printPretty(raw_ostream &OS, | |||
2238 | const PrintingPolicy &Policy) const; | |||
2239 | const char *getSpelling() const; | |||
2240 | FunctionDecl * getFunctionDecl() const { | |||
2241 | return functionDecl; | |||
2242 | } | |||
2243 | ||||
2244 | ||||
2245 | ||||
2246 | static bool classof(const Attr *A) { return A->getKind() == attr::Cleanup; } | |||
2247 | }; | |||
2248 | ||||
2249 | class CodeSegAttr : public InheritableAttr { | |||
2250 | unsigned nameLength; | |||
2251 | char *name; | |||
2252 | ||||
2253 | public: | |||
2254 | static CodeSegAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Loc = SourceRange()) { | |||
2255 | auto *A = new (Ctx) CodeSegAttr(Loc, Ctx, Name, 0); | |||
2256 | A->setImplicit(true); | |||
2257 | return A; | |||
2258 | } | |||
2259 | ||||
2260 | CodeSegAttr(SourceRange R, ASTContext &Ctx | |||
2261 | , llvm::StringRef Name | |||
2262 | , unsigned SI | |||
2263 | ) | |||
2264 | : InheritableAttr(attr::CodeSeg, R, SI, false, false) | |||
2265 | , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength]) | |||
2266 | { | |||
2267 | if (!Name.empty()) | |||
2268 | std::memcpy(name, Name.data(), nameLength); | |||
2269 | } | |||
2270 | ||||
2271 | CodeSegAttr *clone(ASTContext &C) const; | |||
2272 | void printPretty(raw_ostream &OS, | |||
2273 | const PrintingPolicy &Policy) const; | |||
2274 | const char *getSpelling() const; | |||
2275 | llvm::StringRef getName() const { | |||
2276 | return llvm::StringRef(name, nameLength); | |||
2277 | } | |||
2278 | unsigned getNameLength() const { | |||
2279 | return nameLength; | |||
2280 | } | |||
2281 | void setName(ASTContext &C, llvm::StringRef S) { | |||
2282 | nameLength = S.size(); | |||
2283 | this->name = new (C, 1) char [nameLength]; | |||
2284 | if (!S.empty()) | |||
2285 | std::memcpy(this->name, S.data(), nameLength); | |||
2286 | } | |||
2287 | ||||
2288 | ||||
2289 | ||||
2290 | static bool classof(const Attr *A) { return A->getKind() == attr::CodeSeg; } | |||
2291 | }; | |||
2292 | ||||
2293 | class ColdAttr : public InheritableAttr { | |||
2294 | public: | |||
2295 | static ColdAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
2296 | auto *A = new (Ctx) ColdAttr(Loc, Ctx, 0); | |||
2297 | A->setImplicit(true); | |||
2298 | return A; | |||
2299 | } | |||
2300 | ||||
2301 | ColdAttr(SourceRange R, ASTContext &Ctx | |||
2302 | , unsigned SI | |||
2303 | ) | |||
2304 | : InheritableAttr(attr::Cold, R, SI, false, false) | |||
2305 | { | |||
2306 | } | |||
2307 | ||||
2308 | ColdAttr *clone(ASTContext &C) const; | |||
2309 | void printPretty(raw_ostream &OS, | |||
2310 | const PrintingPolicy &Policy) const; | |||
2311 | const char *getSpelling() const; | |||
2312 | ||||
2313 | ||||
2314 | static bool classof(const Attr *A) { return A->getKind() == attr::Cold; } | |||
2315 | }; | |||
2316 | ||||
2317 | class CommonAttr : public InheritableAttr { | |||
2318 | public: | |||
2319 | static CommonAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
2320 | auto *A = new (Ctx) CommonAttr(Loc, Ctx, 0); | |||
2321 | A->setImplicit(true); | |||
2322 | return A; | |||
2323 | } | |||
2324 | ||||
2325 | CommonAttr(SourceRange R, ASTContext &Ctx | |||
2326 | , unsigned SI | |||
2327 | ) | |||
2328 | : InheritableAttr(attr::Common, R, SI, false, false) | |||
2329 | { | |||
2330 | } | |||
2331 | ||||
2332 | CommonAttr *clone(ASTContext &C) const; | |||
2333 | void printPretty(raw_ostream &OS, | |||
2334 | const PrintingPolicy &Policy) const; | |||
2335 | const char *getSpelling() const; | |||
2336 | ||||
2337 | ||||
2338 | static bool classof(const Attr *A) { return A->getKind() == attr::Common; } | |||
2339 | }; | |||
2340 | ||||
2341 | class ConstAttr : public InheritableAttr { | |||
2342 | public: | |||
2343 | static ConstAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
2344 | auto *A = new (Ctx) ConstAttr(Loc, Ctx, 0); | |||
2345 | A->setImplicit(true); | |||
2346 | return A; | |||
2347 | } | |||
2348 | ||||
2349 | ConstAttr(SourceRange R, ASTContext &Ctx | |||
2350 | , unsigned SI | |||
2351 | ) | |||
2352 | : InheritableAttr(attr::Const, R, SI, false, false) | |||
2353 | { | |||
2354 | } | |||
2355 | ||||
2356 | ConstAttr *clone(ASTContext &C) const; | |||
2357 | void printPretty(raw_ostream &OS, | |||
2358 | const PrintingPolicy &Policy) const; | |||
2359 | const char *getSpelling() const; | |||
2360 | ||||
2361 | ||||
2362 | static bool classof(const Attr *A) { return A->getKind() == attr::Const; } | |||
2363 | }; | |||
2364 | ||||
2365 | class ConstructorAttr : public InheritableAttr { | |||
2366 | int priority; | |||
2367 | ||||
2368 | public: | |||
2369 | static ConstructorAttr *CreateImplicit(ASTContext &Ctx, int Priority, SourceRange Loc = SourceRange()) { | |||
2370 | auto *A = new (Ctx) ConstructorAttr(Loc, Ctx, Priority, 0); | |||
2371 | A->setImplicit(true); | |||
2372 | return A; | |||
2373 | } | |||
2374 | ||||
2375 | ConstructorAttr(SourceRange R, ASTContext &Ctx | |||
2376 | , int Priority | |||
2377 | , unsigned SI | |||
2378 | ) | |||
2379 | : InheritableAttr(attr::Constructor, R, SI, false, false) | |||
2380 | , priority(Priority) | |||
2381 | { | |||
2382 | } | |||
2383 | ||||
2384 | ConstructorAttr(SourceRange R, ASTContext &Ctx | |||
2385 | , unsigned SI | |||
2386 | ) | |||
2387 | : InheritableAttr(attr::Constructor, R, SI, false, false) | |||
2388 | , priority() | |||
2389 | { | |||
2390 | } | |||
2391 | ||||
2392 | ConstructorAttr *clone(ASTContext &C) const; | |||
2393 | void printPretty(raw_ostream &OS, | |||
2394 | const PrintingPolicy &Policy) const; | |||
2395 | const char *getSpelling() const; | |||
2396 | int getPriority() const { | |||
2397 | return priority; | |||
2398 | } | |||
2399 | ||||
2400 | static const int DefaultPriority = 65535; | |||
2401 | ||||
2402 | ||||
2403 | ||||
2404 | static bool classof(const Attr *A) { return A->getKind() == attr::Constructor; } | |||
2405 | }; | |||
2406 | ||||
2407 | class ConsumableAttr : public InheritableAttr { | |||
2408 | public: | |||
2409 | enum ConsumedState { | |||
2410 | Unknown, | |||
2411 | Consumed, | |||
2412 | Unconsumed | |||
2413 | }; | |||
2414 | private: | |||
2415 | ConsumedState defaultState; | |||
2416 | ||||
2417 | public: | |||
2418 | static ConsumableAttr *CreateImplicit(ASTContext &Ctx, ConsumedState DefaultState, SourceRange Loc = SourceRange()) { | |||
2419 | auto *A = new (Ctx) ConsumableAttr(Loc, Ctx, DefaultState, 0); | |||
2420 | A->setImplicit(true); | |||
2421 | return A; | |||
2422 | } | |||
2423 | ||||
2424 | ConsumableAttr(SourceRange R, ASTContext &Ctx | |||
2425 | , ConsumedState DefaultState | |||
2426 | , unsigned SI | |||
2427 | ) | |||
2428 | : InheritableAttr(attr::Consumable, R, SI, false, false) | |||
2429 | , defaultState(DefaultState) | |||
2430 | { | |||
2431 | } | |||
2432 | ||||
2433 | ConsumableAttr *clone(ASTContext &C) const; | |||
2434 | void printPretty(raw_ostream &OS, | |||
2435 | const PrintingPolicy &Policy) const; | |||
2436 | const char *getSpelling() const; | |||
2437 | ConsumedState getDefaultState() const { | |||
2438 | return defaultState; | |||
2439 | } | |||
2440 | ||||
2441 | static bool ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) { | |||
2442 | Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val) | |||
2443 | .Case("unknown", ConsumableAttr::Unknown) | |||
2444 | .Case("consumed", ConsumableAttr::Consumed) | |||
2445 | .Case("unconsumed", ConsumableAttr::Unconsumed) | |||
2446 | .Default(Optional<ConsumedState>()); | |||
2447 | if (R) { | |||
2448 | Out = *R; | |||
2449 | return true; | |||
2450 | } | |||
2451 | return false; | |||
2452 | } | |||
2453 | ||||
2454 | static const char *ConvertConsumedStateToStr(ConsumedState Val) { | |||
2455 | switch(Val) { | |||
2456 | case ConsumableAttr::Unknown: return "unknown"; | |||
2457 | case ConsumableAttr::Consumed: return "consumed"; | |||
2458 | case ConsumableAttr::Unconsumed: return "unconsumed"; | |||
2459 | } | |||
2460 | llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 2460); | |||
2461 | } | |||
2462 | ||||
2463 | ||||
2464 | static bool classof(const Attr *A) { return A->getKind() == attr::Consumable; } | |||
2465 | }; | |||
2466 | ||||
2467 | class ConsumableAutoCastAttr : public InheritableAttr { | |||
2468 | public: | |||
2469 | static ConsumableAutoCastAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
2470 | auto *A = new (Ctx) ConsumableAutoCastAttr(Loc, Ctx, 0); | |||
2471 | A->setImplicit(true); | |||
2472 | return A; | |||
2473 | } | |||
2474 | ||||
2475 | ConsumableAutoCastAttr(SourceRange R, ASTContext &Ctx | |||
2476 | , unsigned SI | |||
2477 | ) | |||
2478 | : InheritableAttr(attr::ConsumableAutoCast, R, SI, false, false) | |||
2479 | { | |||
2480 | } | |||
2481 | ||||
2482 | ConsumableAutoCastAttr *clone(ASTContext &C) const; | |||
2483 | void printPretty(raw_ostream &OS, | |||
2484 | const PrintingPolicy &Policy) const; | |||
2485 | const char *getSpelling() const; | |||
2486 | ||||
2487 | ||||
2488 | static bool classof(const Attr *A) { return A->getKind() == attr::ConsumableAutoCast; } | |||
2489 | }; | |||
2490 | ||||
2491 | class ConsumableSetOnReadAttr : public InheritableAttr { | |||
2492 | public: | |||
2493 | static ConsumableSetOnReadAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
2494 | auto *A = new (Ctx) ConsumableSetOnReadAttr(Loc, Ctx, 0); | |||
2495 | A->setImplicit(true); | |||
2496 | return A; | |||
2497 | } | |||
2498 | ||||
2499 | ConsumableSetOnReadAttr(SourceRange R, ASTContext &Ctx | |||
2500 | , unsigned SI | |||
2501 | ) | |||
2502 | : InheritableAttr(attr::ConsumableSetOnRead, R, SI, false, false) | |||
2503 | { | |||
2504 | } | |||
2505 | ||||
2506 | ConsumableSetOnReadAttr *clone(ASTContext &C) const; | |||
2507 | void printPretty(raw_ostream &OS, | |||
2508 | const PrintingPolicy &Policy) const; | |||
2509 | const char *getSpelling() const; | |||
2510 | ||||
2511 | ||||
2512 | static bool classof(const Attr *A) { return A->getKind() == attr::ConsumableSetOnRead; } | |||
2513 | }; | |||
2514 | ||||
2515 | class ConvergentAttr : public InheritableAttr { | |||
2516 | public: | |||
2517 | static ConvergentAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
2518 | auto *A = new (Ctx) ConvergentAttr(Loc, Ctx, 0); | |||
2519 | A->setImplicit(true); | |||
2520 | return A; | |||
2521 | } | |||
2522 | ||||
2523 | ConvergentAttr(SourceRange R, ASTContext &Ctx | |||
2524 | , unsigned SI | |||
2525 | ) | |||
2526 | : InheritableAttr(attr::Convergent, R, SI, false, false) | |||
2527 | { | |||
2528 | } | |||
2529 | ||||
2530 | ConvergentAttr *clone(ASTContext &C) const; | |||
2531 | void printPretty(raw_ostream &OS, | |||
2532 | const PrintingPolicy &Policy) const; | |||
2533 | const char *getSpelling() const; | |||
2534 | ||||
2535 | ||||
2536 | static bool classof(const Attr *A) { return A->getKind() == attr::Convergent; } | |||
2537 | }; | |||
2538 | ||||
2539 | class DLLExportAttr : public InheritableAttr { | |||
2540 | public: | |||
2541 | static DLLExportAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
2542 | auto *A = new (Ctx) DLLExportAttr(Loc, Ctx, 0); | |||
2543 | A->setImplicit(true); | |||
2544 | return A; | |||
2545 | } | |||
2546 | ||||
2547 | DLLExportAttr(SourceRange R, ASTContext &Ctx | |||
2548 | , unsigned SI | |||
2549 | ) | |||
2550 | : InheritableAttr(attr::DLLExport, R, SI, false, false) | |||
2551 | { | |||
2552 | } | |||
2553 | ||||
2554 | DLLExportAttr *clone(ASTContext &C) const; | |||
2555 | void printPretty(raw_ostream &OS, | |||
2556 | const PrintingPolicy &Policy) const; | |||
2557 | const char *getSpelling() const; | |||
2558 | ||||
2559 | ||||
2560 | static bool classof(const Attr *A) { return A->getKind() == attr::DLLExport; } | |||
2561 | }; | |||
2562 | ||||
2563 | class DLLImportAttr : public InheritableAttr { | |||
2564 | public: | |||
2565 | static DLLImportAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
2566 | auto *A = new (Ctx) DLLImportAttr(Loc, Ctx, 0); | |||
2567 | A->setImplicit(true); | |||
2568 | return A; | |||
2569 | } | |||
2570 | ||||
2571 | DLLImportAttr(SourceRange R, ASTContext &Ctx | |||
2572 | , unsigned SI | |||
2573 | ) | |||
2574 | : InheritableAttr(attr::DLLImport, R, SI, false, false) | |||
2575 | { | |||
2576 | } | |||
2577 | ||||
2578 | DLLImportAttr *clone(ASTContext &C) const; | |||
2579 | void printPretty(raw_ostream &OS, | |||
2580 | const PrintingPolicy &Policy) const; | |||
2581 | const char *getSpelling() const; | |||
2582 | ||||
2583 | private: | |||
2584 | bool PropagatedToBaseTemplate = false; | |||
2585 | ||||
2586 | public: | |||
2587 | void setPropagatedToBaseTemplate() { PropagatedToBaseTemplate = true; } | |||
2588 | bool wasPropagatedToBaseTemplate() { return PropagatedToBaseTemplate; } | |||
2589 | ||||
2590 | ||||
2591 | static bool classof(const Attr *A) { return A->getKind() == attr::DLLImport; } | |||
2592 | }; | |||
2593 | ||||
2594 | class DeprecatedAttr : public InheritableAttr { | |||
2595 | unsigned messageLength; | |||
2596 | char *message; | |||
2597 | ||||
2598 | unsigned replacementLength; | |||
2599 | char *replacement; | |||
2600 | ||||
2601 | public: | |||
2602 | static DeprecatedAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, llvm::StringRef Replacement, SourceRange Loc = SourceRange()) { | |||
2603 | auto *A = new (Ctx) DeprecatedAttr(Loc, Ctx, Message, Replacement, 0); | |||
2604 | A->setImplicit(true); | |||
2605 | return A; | |||
2606 | } | |||
2607 | ||||
2608 | DeprecatedAttr(SourceRange R, ASTContext &Ctx | |||
2609 | , llvm::StringRef Message | |||
2610 | , llvm::StringRef Replacement | |||
2611 | , unsigned SI | |||
2612 | ) | |||
2613 | : InheritableAttr(attr::Deprecated, R, SI, false, false) | |||
2614 | , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength]) | |||
2615 | , replacementLength(Replacement.size()),replacement(new (Ctx, 1) char[replacementLength]) | |||
2616 | { | |||
2617 | if (!Message.empty()) | |||
2618 | std::memcpy(message, Message.data(), messageLength); | |||
2619 | if (!Replacement.empty()) | |||
2620 | std::memcpy(replacement, Replacement.data(), replacementLength); | |||
2621 | } | |||
2622 | ||||
2623 | DeprecatedAttr(SourceRange R, ASTContext &Ctx | |||
2624 | , unsigned SI | |||
2625 | ) | |||
2626 | : InheritableAttr(attr::Deprecated, R, SI, false, false) | |||
2627 | , messageLength(0),message(nullptr) | |||
2628 | , replacementLength(0),replacement(nullptr) | |||
2629 | { | |||
2630 | } | |||
2631 | ||||
2632 | DeprecatedAttr *clone(ASTContext &C) const; | |||
2633 | void printPretty(raw_ostream &OS, | |||
2634 | const PrintingPolicy &Policy) const; | |||
2635 | const char *getSpelling() const; | |||
2636 | llvm::StringRef getMessage() const { | |||
2637 | return llvm::StringRef(message, messageLength); | |||
2638 | } | |||
2639 | unsigned getMessageLength() const { | |||
2640 | return messageLength; | |||
2641 | } | |||
2642 | void setMessage(ASTContext &C, llvm::StringRef S) { | |||
2643 | messageLength = S.size(); | |||
2644 | this->message = new (C, 1) char [messageLength]; | |||
2645 | if (!S.empty()) | |||
2646 | std::memcpy(this->message, S.data(), messageLength); | |||
2647 | } | |||
2648 | ||||
2649 | llvm::StringRef getReplacement() const { | |||
2650 | return llvm::StringRef(replacement, replacementLength); | |||
2651 | } | |||
2652 | unsigned getReplacementLength() const { | |||
2653 | return replacementLength; | |||
2654 | } | |||
2655 | void setReplacement(ASTContext &C, llvm::StringRef S) { | |||
2656 | replacementLength = S.size(); | |||
2657 | this->replacement = new (C, 1) char [replacementLength]; | |||
2658 | if (!S.empty()) | |||
2659 | std::memcpy(this->replacement, S.data(), replacementLength); | |||
2660 | } | |||
2661 | ||||
2662 | ||||
2663 | ||||
2664 | static bool classof(const Attr *A) { return A->getKind() == attr::Deprecated; } | |||
2665 | }; | |||
2666 | ||||
2667 | class DestructorAttr : public InheritableAttr { | |||
2668 | int priority; | |||
2669 | ||||
2670 | public: | |||
2671 | static DestructorAttr *CreateImplicit(ASTContext &Ctx, int Priority, SourceRange Loc = SourceRange()) { | |||
2672 | auto *A = new (Ctx) DestructorAttr(Loc, Ctx, Priority, 0); | |||
2673 | A->setImplicit(true); | |||
2674 | return A; | |||
2675 | } | |||
2676 | ||||
2677 | DestructorAttr(SourceRange R, ASTContext &Ctx | |||
2678 | , int Priority | |||
2679 | , unsigned SI | |||
2680 | ) | |||
2681 | : InheritableAttr(attr::Destructor, R, SI, false, false) | |||
2682 | , priority(Priority) | |||
2683 | { | |||
2684 | } | |||
2685 | ||||
2686 | DestructorAttr(SourceRange R, ASTContext &Ctx | |||
2687 | , unsigned SI | |||
2688 | ) | |||
2689 | : InheritableAttr(attr::Destructor, R, SI, false, false) | |||
2690 | , priority() | |||
2691 | { | |||
2692 | } | |||
2693 | ||||
2694 | DestructorAttr *clone(ASTContext &C) const; | |||
2695 | void printPretty(raw_ostream &OS, | |||
2696 | const PrintingPolicy &Policy) const; | |||
2697 | const char *getSpelling() const; | |||
2698 | int getPriority() const { | |||
2699 | return priority; | |||
2700 | } | |||
2701 | ||||
2702 | static const int DefaultPriority = 65535; | |||
2703 | ||||
2704 | ||||
2705 | ||||
2706 | static bool classof(const Attr *A) { return A->getKind() == attr::Destructor; } | |||
2707 | }; | |||
2708 | ||||
2709 | class DiagnoseIfAttr : public InheritableAttr { | |||
2710 | Expr * cond; | |||
2711 | ||||
2712 | unsigned messageLength; | |||
2713 | char *message; | |||
2714 | ||||
2715 | public: | |||
2716 | enum DiagnosticType { | |||
2717 | DT_Error, | |||
2718 | DT_Warning | |||
2719 | }; | |||
2720 | private: | |||
2721 | DiagnosticType diagnosticType; | |||
2722 | ||||
2723 | bool argDependent; | |||
2724 | ||||
2725 | NamedDecl * parent; | |||
2726 | ||||
2727 | public: | |||
2728 | static DiagnoseIfAttr *CreateImplicit(ASTContext &Ctx, Expr * Cond, llvm::StringRef Message, DiagnosticType DiagnosticType, bool ArgDependent, NamedDecl * Parent, SourceRange Loc = SourceRange()) { | |||
2729 | auto *A = new (Ctx) DiagnoseIfAttr(Loc, Ctx, Cond, Message, DiagnosticType, ArgDependent, Parent, 0); | |||
2730 | A->setImplicit(true); | |||
2731 | return A; | |||
2732 | } | |||
2733 | ||||
2734 | static DiagnoseIfAttr *CreateImplicit(ASTContext &Ctx, Expr * Cond, llvm::StringRef Message, DiagnosticType DiagnosticType, SourceRange Loc = SourceRange()) { | |||
2735 | auto *A = new (Ctx) DiagnoseIfAttr(Loc, Ctx, Cond, Message, DiagnosticType, 0); | |||
2736 | A->setImplicit(true); | |||
2737 | return A; | |||
2738 | } | |||
2739 | ||||
2740 | DiagnoseIfAttr(SourceRange R, ASTContext &Ctx | |||
2741 | , Expr * Cond | |||
2742 | , llvm::StringRef Message | |||
2743 | , DiagnosticType DiagnosticType | |||
2744 | , bool ArgDependent | |||
2745 | , NamedDecl * Parent | |||
2746 | , unsigned SI | |||
2747 | ) | |||
2748 | : InheritableAttr(attr::DiagnoseIf, R, SI, true, true) | |||
2749 | , cond(Cond) | |||
2750 | , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength]) | |||
2751 | , diagnosticType(DiagnosticType) | |||
2752 | , argDependent(ArgDependent) | |||
2753 | , parent(Parent) | |||
2754 | { | |||
2755 | if (!Message.empty()) | |||
2756 | std::memcpy(message, Message.data(), messageLength); | |||
2757 | } | |||
2758 | ||||
2759 | DiagnoseIfAttr(SourceRange R, ASTContext &Ctx | |||
2760 | , Expr * Cond | |||
2761 | , llvm::StringRef Message | |||
2762 | , DiagnosticType DiagnosticType | |||
2763 | , unsigned SI | |||
2764 | ) | |||
2765 | : InheritableAttr(attr::DiagnoseIf, R, SI, true, true) | |||
2766 | , cond(Cond) | |||
2767 | , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength]) | |||
2768 | , diagnosticType(DiagnosticType) | |||
2769 | , argDependent() | |||
2770 | , parent() | |||
2771 | { | |||
2772 | if (!Message.empty()) | |||
2773 | std::memcpy(message, Message.data(), messageLength); | |||
2774 | } | |||
2775 | ||||
2776 | DiagnoseIfAttr *clone(ASTContext &C) const; | |||
2777 | void printPretty(raw_ostream &OS, | |||
2778 | const PrintingPolicy &Policy) const; | |||
2779 | const char *getSpelling() const; | |||
2780 | Expr * getCond() const { | |||
2781 | return cond; | |||
2782 | } | |||
2783 | ||||
2784 | llvm::StringRef getMessage() const { | |||
2785 | return llvm::StringRef(message, messageLength); | |||
2786 | } | |||
2787 | unsigned getMessageLength() const { | |||
2788 | return messageLength; | |||
2789 | } | |||
2790 | void setMessage(ASTContext &C, llvm::StringRef S) { | |||
2791 | messageLength = S.size(); | |||
2792 | this->message = new (C, 1) char [messageLength]; | |||
2793 | if (!S.empty()) | |||
2794 | std::memcpy(this->message, S.data(), messageLength); | |||
2795 | } | |||
2796 | ||||
2797 | DiagnosticType getDiagnosticType() const { | |||
2798 | return diagnosticType; | |||
2799 | } | |||
2800 | ||||
2801 | static bool ConvertStrToDiagnosticType(StringRef Val, DiagnosticType &Out) { | |||
2802 | Optional<DiagnosticType> R = llvm::StringSwitch<Optional<DiagnosticType>>(Val) | |||
2803 | .Case("error", DiagnoseIfAttr::DT_Error) | |||
2804 | .Case("warning", DiagnoseIfAttr::DT_Warning) | |||
2805 | .Default(Optional<DiagnosticType>()); | |||
2806 | if (R) { | |||
2807 | Out = *R; | |||
2808 | return true; | |||
2809 | } | |||
2810 | return false; | |||
2811 | } | |||
2812 | ||||
2813 | static const char *ConvertDiagnosticTypeToStr(DiagnosticType Val) { | |||
2814 | switch(Val) { | |||
2815 | case DiagnoseIfAttr::DT_Error: return "error"; | |||
2816 | case DiagnoseIfAttr::DT_Warning: return "warning"; | |||
2817 | } | |||
2818 | llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 2818); | |||
2819 | } | |||
2820 | bool getArgDependent() const { | |||
2821 | return argDependent; | |||
2822 | } | |||
2823 | ||||
2824 | NamedDecl * getParent() const { | |||
2825 | return parent; | |||
2826 | } | |||
2827 | ||||
2828 | ||||
2829 | bool isError() const { return diagnosticType == DT_Error; } | |||
2830 | bool isWarning() const { return diagnosticType == DT_Warning; } | |||
2831 | ||||
2832 | ||||
2833 | static bool classof(const Attr *A) { return A->getKind() == attr::DiagnoseIf; } | |||
2834 | }; | |||
2835 | ||||
2836 | class DisableTailCallsAttr : public InheritableAttr { | |||
2837 | public: | |||
2838 | static DisableTailCallsAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
2839 | auto *A = new (Ctx) DisableTailCallsAttr(Loc, Ctx, 0); | |||
2840 | A->setImplicit(true); | |||
2841 | return A; | |||
2842 | } | |||
2843 | ||||
2844 | DisableTailCallsAttr(SourceRange R, ASTContext &Ctx | |||
2845 | , unsigned SI | |||
2846 | ) | |||
2847 | : InheritableAttr(attr::DisableTailCalls, R, SI, false, false) | |||
2848 | { | |||
2849 | } | |||
2850 | ||||
2851 | DisableTailCallsAttr *clone(ASTContext &C) const; | |||
2852 | void printPretty(raw_ostream &OS, | |||
2853 | const PrintingPolicy &Policy) const; | |||
2854 | const char *getSpelling() const; | |||
2855 | ||||
2856 | ||||
2857 | static bool classof(const Attr *A) { return A->getKind() == attr::DisableTailCalls; } | |||
2858 | }; | |||
2859 | ||||
2860 | class EmptyBasesAttr : public InheritableAttr { | |||
2861 | public: | |||
2862 | static EmptyBasesAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
2863 | auto *A = new (Ctx) EmptyBasesAttr(Loc, Ctx, 0); | |||
2864 | A->setImplicit(true); | |||
2865 | return A; | |||
2866 | } | |||
2867 | ||||
2868 | EmptyBasesAttr(SourceRange R, ASTContext &Ctx | |||
2869 | , unsigned SI | |||
2870 | ) | |||
2871 | : InheritableAttr(attr::EmptyBases, R, SI, false, false) | |||
2872 | { | |||
2873 | } | |||
2874 | ||||
2875 | EmptyBasesAttr *clone(ASTContext &C) const; | |||
2876 | void printPretty(raw_ostream &OS, | |||
2877 | const PrintingPolicy &Policy) const; | |||
2878 | const char *getSpelling() const; | |||
2879 | ||||
2880 | ||||
2881 | static bool classof(const Attr *A) { return A->getKind() == attr::EmptyBases; } | |||
2882 | }; | |||
2883 | ||||
2884 | class EnableIfAttr : public InheritableAttr { | |||
2885 | Expr * cond; | |||
2886 | ||||
2887 | unsigned messageLength; | |||
2888 | char *message; | |||
2889 | ||||
2890 | public: | |||
2891 | static EnableIfAttr *CreateImplicit(ASTContext &Ctx, Expr * Cond, llvm::StringRef Message, SourceRange Loc = SourceRange()) { | |||
2892 | auto *A = new (Ctx) EnableIfAttr(Loc, Ctx, Cond, Message, 0); | |||
2893 | A->setImplicit(true); | |||
2894 | return A; | |||
2895 | } | |||
2896 | ||||
2897 | EnableIfAttr(SourceRange R, ASTContext &Ctx | |||
2898 | , Expr * Cond | |||
2899 | , llvm::StringRef Message | |||
2900 | , unsigned SI | |||
2901 | ) | |||
2902 | : InheritableAttr(attr::EnableIf, R, SI, false, false) | |||
2903 | , cond(Cond) | |||
2904 | , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength]) | |||
2905 | { | |||
2906 | if (!Message.empty()) | |||
2907 | std::memcpy(message, Message.data(), messageLength); | |||
2908 | } | |||
2909 | ||||
2910 | EnableIfAttr *clone(ASTContext &C) const; | |||
2911 | void printPretty(raw_ostream &OS, | |||
2912 | const PrintingPolicy &Policy) const; | |||
2913 | const char *getSpelling() const; | |||
2914 | Expr * getCond() const { | |||
2915 | return cond; | |||
2916 | } | |||
2917 | ||||
2918 | llvm::StringRef getMessage() const { | |||
2919 | return llvm::StringRef(message, messageLength); | |||
2920 | } | |||
2921 | unsigned getMessageLength() const { | |||
2922 | return messageLength; | |||
2923 | } | |||
2924 | void setMessage(ASTContext &C, llvm::StringRef S) { | |||
2925 | messageLength = S.size(); | |||
2926 | this->message = new (C, 1) char [messageLength]; | |||
2927 | if (!S.empty()) | |||
2928 | std::memcpy(this->message, S.data(), messageLength); | |||
2929 | } | |||
2930 | ||||
2931 | ||||
2932 | ||||
2933 | static bool classof(const Attr *A) { return A->getKind() == attr::EnableIf; } | |||
2934 | }; | |||
2935 | ||||
2936 | class EnumExtensibilityAttr : public InheritableAttr { | |||
2937 | public: | |||
2938 | enum Kind { | |||
2939 | Closed, | |||
2940 | Open | |||
2941 | }; | |||
2942 | private: | |||
2943 | Kind extensibility; | |||
2944 | ||||
2945 | public: | |||
2946 | static EnumExtensibilityAttr *CreateImplicit(ASTContext &Ctx, Kind Extensibility, SourceRange Loc = SourceRange()) { | |||
2947 | auto *A = new (Ctx) EnumExtensibilityAttr(Loc, Ctx, Extensibility, 0); | |||
2948 | A->setImplicit(true); | |||
2949 | return A; | |||
2950 | } | |||
2951 | ||||
2952 | EnumExtensibilityAttr(SourceRange R, ASTContext &Ctx | |||
2953 | , Kind Extensibility | |||
2954 | , unsigned SI | |||
2955 | ) | |||
2956 | : InheritableAttr(attr::EnumExtensibility, R, SI, false, false) | |||
2957 | , extensibility(Extensibility) | |||
2958 | { | |||
2959 | } | |||
2960 | ||||
2961 | EnumExtensibilityAttr *clone(ASTContext &C) const; | |||
2962 | void printPretty(raw_ostream &OS, | |||
2963 | const PrintingPolicy &Policy) const; | |||
2964 | const char *getSpelling() const; | |||
2965 | Kind getExtensibility() const { | |||
2966 | return extensibility; | |||
2967 | } | |||
2968 | ||||
2969 | static bool ConvertStrToKind(StringRef Val, Kind &Out) { | |||
2970 | Optional<Kind> R = llvm::StringSwitch<Optional<Kind>>(Val) | |||
2971 | .Case("closed", EnumExtensibilityAttr::Closed) | |||
2972 | .Case("open", EnumExtensibilityAttr::Open) | |||
2973 | .Default(Optional<Kind>()); | |||
2974 | if (R) { | |||
2975 | Out = *R; | |||
2976 | return true; | |||
2977 | } | |||
2978 | return false; | |||
2979 | } | |||
2980 | ||||
2981 | static const char *ConvertKindToStr(Kind Val) { | |||
2982 | switch(Val) { | |||
2983 | case EnumExtensibilityAttr::Closed: return "closed"; | |||
2984 | case EnumExtensibilityAttr::Open: return "open"; | |||
2985 | } | |||
2986 | llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 2986); | |||
2987 | } | |||
2988 | ||||
2989 | ||||
2990 | static bool classof(const Attr *A) { return A->getKind() == attr::EnumExtensibility; } | |||
2991 | }; | |||
2992 | ||||
2993 | class ExclusiveTrylockFunctionAttr : public InheritableAttr { | |||
2994 | Expr * successValue; | |||
2995 | ||||
2996 | unsigned args_Size; | |||
2997 | Expr * *args_; | |||
2998 | ||||
2999 | public: | |||
3000 | static ExclusiveTrylockFunctionAttr *CreateImplicit(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) { | |||
3001 | auto *A = new (Ctx) ExclusiveTrylockFunctionAttr(Loc, Ctx, SuccessValue, Args, ArgsSize, 0); | |||
3002 | A->setImplicit(true); | |||
3003 | return A; | |||
3004 | } | |||
3005 | ||||
3006 | ExclusiveTrylockFunctionAttr(SourceRange R, ASTContext &Ctx | |||
3007 | , Expr * SuccessValue | |||
3008 | , Expr * *Args, unsigned ArgsSize | |||
3009 | , unsigned SI | |||
3010 | ) | |||
3011 | : InheritableAttr(attr::ExclusiveTrylockFunction, R, SI, true, true) | |||
3012 | , successValue(SuccessValue) | |||
3013 | , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size]) | |||
3014 | { | |||
3015 | std::copy(Args, Args + args_Size, args_); | |||
3016 | } | |||
3017 | ||||
3018 | ExclusiveTrylockFunctionAttr(SourceRange R, ASTContext &Ctx | |||
3019 | , Expr * SuccessValue | |||
3020 | , unsigned SI | |||
3021 | ) | |||
3022 | : InheritableAttr(attr::ExclusiveTrylockFunction, R, SI, true, true) | |||
3023 | , successValue(SuccessValue) | |||
3024 | , args_Size(0), args_(nullptr) | |||
3025 | { | |||
3026 | } | |||
3027 | ||||
3028 | ExclusiveTrylockFunctionAttr *clone(ASTContext &C) const; | |||
3029 | void printPretty(raw_ostream &OS, | |||
3030 | const PrintingPolicy &Policy) const; | |||
3031 | const char *getSpelling() const; | |||
3032 | Expr * getSuccessValue() const { | |||
3033 | return successValue; | |||
3034 | } | |||
3035 | ||||
3036 | typedef Expr ** args_iterator; | |||
3037 | args_iterator args_begin() const { return args_; } | |||
3038 | args_iterator args_end() const { return args_ + args_Size; } | |||
3039 | unsigned args_size() const { return args_Size; } | |||
3040 | llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); } | |||
3041 | ||||
3042 | ||||
3043 | ||||
3044 | ||||
3045 | static bool classof(const Attr *A) { return A->getKind() == attr::ExclusiveTrylockFunction; } | |||
3046 | }; | |||
3047 | ||||
3048 | class ExternalSourceSymbolAttr : public InheritableAttr { | |||
3049 | unsigned languageLength; | |||
3050 | char *language; | |||
3051 | ||||
3052 | unsigned definedInLength; | |||
3053 | char *definedIn; | |||
3054 | ||||
3055 | bool generatedDeclaration; | |||
3056 | ||||
3057 | public: | |||
3058 | static ExternalSourceSymbolAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Language, llvm::StringRef DefinedIn, bool GeneratedDeclaration, SourceRange Loc = SourceRange()) { | |||
3059 | auto *A = new (Ctx) ExternalSourceSymbolAttr(Loc, Ctx, Language, DefinedIn, GeneratedDeclaration, 0); | |||
3060 | A->setImplicit(true); | |||
3061 | return A; | |||
3062 | } | |||
3063 | ||||
3064 | ExternalSourceSymbolAttr(SourceRange R, ASTContext &Ctx | |||
3065 | , llvm::StringRef Language | |||
3066 | , llvm::StringRef DefinedIn | |||
3067 | , bool GeneratedDeclaration | |||
3068 | , unsigned SI | |||
3069 | ) | |||
3070 | : InheritableAttr(attr::ExternalSourceSymbol, R, SI, false, false) | |||
3071 | , languageLength(Language.size()),language(new (Ctx, 1) char[languageLength]) | |||
3072 | , definedInLength(DefinedIn.size()),definedIn(new (Ctx, 1) char[definedInLength]) | |||
3073 | , generatedDeclaration(GeneratedDeclaration) | |||
3074 | { | |||
3075 | if (!Language.empty()) | |||
3076 | std::memcpy(language, Language.data(), languageLength); | |||
3077 | if (!DefinedIn.empty()) | |||
3078 | std::memcpy(definedIn, DefinedIn.data(), definedInLength); | |||
3079 | } | |||
3080 | ||||
3081 | ExternalSourceSymbolAttr(SourceRange R, ASTContext &Ctx | |||
3082 | , unsigned SI | |||
3083 | ) | |||
3084 | : InheritableAttr(attr::ExternalSourceSymbol, R, SI, false, false) | |||
3085 | , languageLength(0),language(nullptr) | |||
3086 | , definedInLength(0),definedIn(nullptr) | |||
3087 | , generatedDeclaration() | |||
3088 | { | |||
3089 | } | |||
3090 | ||||
3091 | ExternalSourceSymbolAttr *clone(ASTContext &C) const; | |||
3092 | void printPretty(raw_ostream &OS, | |||
3093 | const PrintingPolicy &Policy) const; | |||
3094 | const char *getSpelling() const; | |||
3095 | llvm::StringRef getLanguage() const { | |||
3096 | return llvm::StringRef(language, languageLength); | |||
3097 | } | |||
3098 | unsigned getLanguageLength() const { | |||
3099 | return languageLength; | |||
3100 | } | |||
3101 | void setLanguage(ASTContext &C, llvm::StringRef S) { | |||
3102 | languageLength = S.size(); | |||
3103 | this->language = new (C, 1) char [languageLength]; | |||
3104 | if (!S.empty()) | |||
3105 | std::memcpy(this->language, S.data(), languageLength); | |||
3106 | } | |||
3107 | ||||
3108 | llvm::StringRef getDefinedIn() const { | |||
3109 | return llvm::StringRef(definedIn, definedInLength); | |||
3110 | } | |||
3111 | unsigned getDefinedInLength() const { | |||
3112 | return definedInLength; | |||
3113 | } | |||
3114 | void setDefinedIn(ASTContext &C, llvm::StringRef S) { | |||
3115 | definedInLength = S.size(); | |||
3116 | this->definedIn = new (C, 1) char [definedInLength]; | |||
3117 | if (!S.empty()) | |||
3118 | std::memcpy(this->definedIn, S.data(), definedInLength); | |||
3119 | } | |||
3120 | ||||
3121 | bool getGeneratedDeclaration() const { | |||
3122 | return generatedDeclaration; | |||
3123 | } | |||
3124 | ||||
3125 | ||||
3126 | ||||
3127 | static bool classof(const Attr *A) { return A->getKind() == attr::ExternalSourceSymbol; } | |||
3128 | }; | |||
3129 | ||||
3130 | class FallThroughAttr : public StmtAttr { | |||
3131 | public: | |||
3132 | static FallThroughAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
3133 | auto *A = new (Ctx) FallThroughAttr(Loc, Ctx, 0); | |||
3134 | A->setImplicit(true); | |||
3135 | return A; | |||
3136 | } | |||
3137 | ||||
3138 | FallThroughAttr(SourceRange R, ASTContext &Ctx | |||
3139 | , unsigned SI | |||
3140 | ) | |||
3141 | : StmtAttr(attr::FallThrough, R, SI, false) | |||
3142 | { | |||
3143 | } | |||
3144 | ||||
3145 | FallThroughAttr *clone(ASTContext &C) const; | |||
3146 | void printPretty(raw_ostream &OS, | |||
3147 | const PrintingPolicy &Policy) const; | |||
3148 | const char *getSpelling() const; | |||
3149 | ||||
3150 | ||||
3151 | static bool classof(const Attr *A) { return A->getKind() == attr::FallThrough; } | |||
3152 | }; | |||
3153 | ||||
3154 | class FastCallAttr : public InheritableAttr { | |||
3155 | public: | |||
3156 | static FastCallAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
3157 | auto *A = new (Ctx) FastCallAttr(Loc, Ctx, 0); | |||
3158 | A->setImplicit(true); | |||
3159 | return A; | |||
3160 | } | |||
3161 | ||||
3162 | FastCallAttr(SourceRange R, ASTContext &Ctx | |||
3163 | , unsigned SI | |||
3164 | ) | |||
3165 | : InheritableAttr(attr::FastCall, R, SI, false, false) | |||
3166 | { | |||
3167 | } | |||
3168 | ||||
3169 | FastCallAttr *clone(ASTContext &C) const; | |||
3170 | void printPretty(raw_ostream &OS, | |||
3171 | const PrintingPolicy &Policy) const; | |||
3172 | const char *getSpelling() const; | |||
3173 | ||||
3174 | ||||
3175 | static bool classof(const Attr *A) { return A->getKind() == attr::FastCall; } | |||
3176 | }; | |||
3177 | ||||
3178 | class FinalAttr : public InheritableAttr { | |||
3179 | public: | |||
3180 | enum Spelling { | |||
3181 | Keyword_final = 0, | |||
3182 | Keyword_sealed = 1 | |||
3183 | }; | |||
3184 | ||||
3185 | static FinalAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) { | |||
3186 | auto *A = new (Ctx) FinalAttr(Loc, Ctx, S); | |||
3187 | A->setImplicit(true); | |||
3188 | return A; | |||
3189 | } | |||
3190 | ||||
3191 | FinalAttr(SourceRange R, ASTContext &Ctx | |||
3192 | , unsigned SI | |||
3193 | ) | |||
3194 | : InheritableAttr(attr::Final, R, SI, false, false) | |||
3195 | { | |||
3196 | } | |||
3197 | ||||
3198 | FinalAttr *clone(ASTContext &C) const; | |||
3199 | void printPretty(raw_ostream &OS, | |||
3200 | const PrintingPolicy &Policy) const; | |||
3201 | const char *getSpelling() const; | |||
3202 | Spelling getSemanticSpelling() const { | |||
3203 | switch (SpellingListIndex) { | |||
3204 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 3204); | |||
3205 | case 0: return Keyword_final; | |||
3206 | case 1: return Keyword_sealed; | |||
3207 | } | |||
3208 | } | |||
3209 | bool isSpelledAsSealed() const { return SpellingListIndex == 1; } | |||
3210 | ||||
3211 | ||||
3212 | static bool classof(const Attr *A) { return A->getKind() == attr::Final; } | |||
3213 | }; | |||
3214 | ||||
3215 | class FlagEnumAttr : public InheritableAttr { | |||
3216 | public: | |||
3217 | static FlagEnumAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
3218 | auto *A = new (Ctx) FlagEnumAttr(Loc, Ctx, 0); | |||
3219 | A->setImplicit(true); | |||
3220 | return A; | |||
3221 | } | |||
3222 | ||||
3223 | FlagEnumAttr(SourceRange R, ASTContext &Ctx | |||
3224 | , unsigned SI | |||
3225 | ) | |||
3226 | : InheritableAttr(attr::FlagEnum, R, SI, false, false) | |||
3227 | { | |||
3228 | } | |||
3229 | ||||
3230 | FlagEnumAttr *clone(ASTContext &C) const; | |||
3231 | void printPretty(raw_ostream &OS, | |||
3232 | const PrintingPolicy &Policy) const; | |||
3233 | const char *getSpelling() const; | |||
3234 | ||||
3235 | ||||
3236 | static bool classof(const Attr *A) { return A->getKind() == attr::FlagEnum; } | |||
3237 | }; | |||
3238 | ||||
3239 | class FlattenAttr : public InheritableAttr { | |||
3240 | public: | |||
3241 | static FlattenAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
3242 | auto *A = new (Ctx) FlattenAttr(Loc, Ctx, 0); | |||
3243 | A->setImplicit(true); | |||
3244 | return A; | |||
3245 | } | |||
3246 | ||||
3247 | FlattenAttr(SourceRange R, ASTContext &Ctx | |||
3248 | , unsigned SI | |||
3249 | ) | |||
3250 | : InheritableAttr(attr::Flatten, R, SI, false, false) | |||
3251 | { | |||
3252 | } | |||
3253 | ||||
3254 | FlattenAttr *clone(ASTContext &C) const; | |||
3255 | void printPretty(raw_ostream &OS, | |||
3256 | const PrintingPolicy &Policy) const; | |||
3257 | const char *getSpelling() const; | |||
3258 | ||||
3259 | ||||
3260 | static bool classof(const Attr *A) { return A->getKind() == attr::Flatten; } | |||
3261 | }; | |||
3262 | ||||
3263 | class FormatAttr : public InheritableAttr { | |||
3264 | IdentifierInfo * type; | |||
3265 | ||||
3266 | int formatIdx; | |||
3267 | ||||
3268 | int firstArg; | |||
3269 | ||||
3270 | public: | |||
3271 | static FormatAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * Type, int FormatIdx, int FirstArg, SourceRange Loc = SourceRange()) { | |||
3272 | auto *A = new (Ctx) FormatAttr(Loc, Ctx, Type, FormatIdx, FirstArg, 0); | |||
3273 | A->setImplicit(true); | |||
3274 | return A; | |||
3275 | } | |||
3276 | ||||
3277 | FormatAttr(SourceRange R, ASTContext &Ctx | |||
3278 | , IdentifierInfo * Type | |||
3279 | , int FormatIdx | |||
3280 | , int FirstArg | |||
3281 | , unsigned SI | |||
3282 | ) | |||
3283 | : InheritableAttr(attr::Format, R, SI, false, false) | |||
3284 | , type(Type) | |||
3285 | , formatIdx(FormatIdx) | |||
3286 | , firstArg(FirstArg) | |||
3287 | { | |||
3288 | } | |||
3289 | ||||
3290 | FormatAttr *clone(ASTContext &C) const; | |||
3291 | void printPretty(raw_ostream &OS, | |||
3292 | const PrintingPolicy &Policy) const; | |||
3293 | const char *getSpelling() const; | |||
3294 | IdentifierInfo * getType() const { | |||
3295 | return type; | |||
3296 | } | |||
3297 | ||||
3298 | int getFormatIdx() const { | |||
3299 | return formatIdx; | |||
3300 | } | |||
3301 | ||||
3302 | int getFirstArg() const { | |||
3303 | return firstArg; | |||
3304 | } | |||
3305 | ||||
3306 | ||||
3307 | ||||
3308 | static bool classof(const Attr *A) { return A->getKind() == attr::Format; } | |||
3309 | }; | |||
3310 | ||||
3311 | class FormatArgAttr : public InheritableAttr { | |||
3312 | ParamIdx formatIdx; | |||
3313 | ||||
3314 | public: | |||
3315 | static FormatArgAttr *CreateImplicit(ASTContext &Ctx, ParamIdx FormatIdx, SourceRange Loc = SourceRange()) { | |||
3316 | auto *A = new (Ctx) FormatArgAttr(Loc, Ctx, FormatIdx, 0); | |||
3317 | A->setImplicit(true); | |||
3318 | return A; | |||
3319 | } | |||
3320 | ||||
3321 | FormatArgAttr(SourceRange R, ASTContext &Ctx | |||
3322 | , ParamIdx FormatIdx | |||
3323 | , unsigned SI | |||
3324 | ) | |||
3325 | : InheritableAttr(attr::FormatArg, R, SI, false, false) | |||
3326 | , formatIdx(FormatIdx) | |||
3327 | { | |||
3328 | } | |||
3329 | ||||
3330 | FormatArgAttr *clone(ASTContext &C) const; | |||
3331 | void printPretty(raw_ostream &OS, | |||
3332 | const PrintingPolicy &Policy) const; | |||
3333 | const char *getSpelling() const; | |||
3334 | ParamIdx getFormatIdx() const { | |||
3335 | return formatIdx; | |||
3336 | } | |||
3337 | ||||
3338 | ||||
3339 | ||||
3340 | static bool classof(const Attr *A) { return A->getKind() == attr::FormatArg; } | |||
3341 | }; | |||
3342 | ||||
3343 | class GNUInlineAttr : public InheritableAttr { | |||
3344 | public: | |||
3345 | static GNUInlineAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
3346 | auto *A = new (Ctx) GNUInlineAttr(Loc, Ctx, 0); | |||
3347 | A->setImplicit(true); | |||
3348 | return A; | |||
3349 | } | |||
3350 | ||||
3351 | GNUInlineAttr(SourceRange R, ASTContext &Ctx | |||
3352 | , unsigned SI | |||
3353 | ) | |||
3354 | : InheritableAttr(attr::GNUInline, R, SI, false, false) | |||
3355 | { | |||
3356 | } | |||
3357 | ||||
3358 | GNUInlineAttr *clone(ASTContext &C) const; | |||
3359 | void printPretty(raw_ostream &OS, | |||
3360 | const PrintingPolicy &Policy) const; | |||
3361 | const char *getSpelling() const; | |||
3362 | ||||
3363 | ||||
3364 | static bool classof(const Attr *A) { return A->getKind() == attr::GNUInline; } | |||
3365 | }; | |||
3366 | ||||
3367 | class GuardedByAttr : public InheritableAttr { | |||
3368 | Expr * arg; | |||
3369 | ||||
3370 | public: | |||
3371 | static GuardedByAttr *CreateImplicit(ASTContext &Ctx, Expr * Arg, SourceRange Loc = SourceRange()) { | |||
3372 | auto *A = new (Ctx) GuardedByAttr(Loc, Ctx, Arg, 0); | |||
3373 | A->setImplicit(true); | |||
3374 | return A; | |||
3375 | } | |||
3376 | ||||
3377 | GuardedByAttr(SourceRange R, ASTContext &Ctx | |||
3378 | , Expr * Arg | |||
3379 | , unsigned SI | |||
3380 | ) | |||
3381 | : InheritableAttr(attr::GuardedBy, R, SI, true, true) | |||
3382 | , arg(Arg) | |||
3383 | { | |||
3384 | } | |||
3385 | ||||
3386 | GuardedByAttr *clone(ASTContext &C) const; | |||
3387 | void printPretty(raw_ostream &OS, | |||
3388 | const PrintingPolicy &Policy) const; | |||
3389 | const char *getSpelling() const; | |||
3390 | Expr * getArg() const { | |||
3391 | return arg; | |||
3392 | } | |||
3393 | ||||
3394 | ||||
3395 | ||||
3396 | static bool classof(const Attr *A) { return A->getKind() == attr::GuardedBy; } | |||
3397 | }; | |||
3398 | ||||
3399 | class GuardedVarAttr : public InheritableAttr { | |||
3400 | public: | |||
3401 | static GuardedVarAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
3402 | auto *A = new (Ctx) GuardedVarAttr(Loc, Ctx, 0); | |||
3403 | A->setImplicit(true); | |||
3404 | return A; | |||
3405 | } | |||
3406 | ||||
3407 | GuardedVarAttr(SourceRange R, ASTContext &Ctx | |||
3408 | , unsigned SI | |||
3409 | ) | |||
3410 | : InheritableAttr(attr::GuardedVar, R, SI, false, false) | |||
3411 | { | |||
3412 | } | |||
3413 | ||||
3414 | GuardedVarAttr *clone(ASTContext &C) const; | |||
3415 | void printPretty(raw_ostream &OS, | |||
3416 | const PrintingPolicy &Policy) const; | |||
3417 | const char *getSpelling() const; | |||
3418 | ||||
3419 | ||||
3420 | static bool classof(const Attr *A) { return A->getKind() == attr::GuardedVar; } | |||
3421 | }; | |||
3422 | ||||
3423 | class HotAttr : public InheritableAttr { | |||
3424 | public: | |||
3425 | static HotAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
3426 | auto *A = new (Ctx) HotAttr(Loc, Ctx, 0); | |||
3427 | A->setImplicit(true); | |||
3428 | return A; | |||
3429 | } | |||
3430 | ||||
3431 | HotAttr(SourceRange R, ASTContext &Ctx | |||
3432 | , unsigned SI | |||
3433 | ) | |||
3434 | : InheritableAttr(attr::Hot, R, SI, false, false) | |||
3435 | { | |||
3436 | } | |||
3437 | ||||
3438 | HotAttr *clone(ASTContext &C) const; | |||
3439 | void printPretty(raw_ostream &OS, | |||
3440 | const PrintingPolicy &Policy) const; | |||
3441 | const char *getSpelling() const; | |||
3442 | ||||
3443 | ||||
3444 | static bool classof(const Attr *A) { return A->getKind() == attr::Hot; } | |||
3445 | }; | |||
3446 | ||||
3447 | class IBActionAttr : public InheritableAttr { | |||
3448 | public: | |||
3449 | static IBActionAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
3450 | auto *A = new (Ctx) IBActionAttr(Loc, Ctx, 0); | |||
3451 | A->setImplicit(true); | |||
3452 | return A; | |||
3453 | } | |||
3454 | ||||
3455 | IBActionAttr(SourceRange R, ASTContext &Ctx | |||
3456 | , unsigned SI | |||
3457 | ) | |||
3458 | : InheritableAttr(attr::IBAction, R, SI, false, false) | |||
3459 | { | |||
3460 | } | |||
3461 | ||||
3462 | IBActionAttr *clone(ASTContext &C) const; | |||
3463 | void printPretty(raw_ostream &OS, | |||
3464 | const PrintingPolicy &Policy) const; | |||
3465 | const char *getSpelling() const; | |||
3466 | ||||
3467 | ||||
3468 | static bool classof(const Attr *A) { return A->getKind() == attr::IBAction; } | |||
3469 | }; | |||
3470 | ||||
3471 | class IBOutletAttr : public InheritableAttr { | |||
3472 | public: | |||
3473 | static IBOutletAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
3474 | auto *A = new (Ctx) IBOutletAttr(Loc, Ctx, 0); | |||
3475 | A->setImplicit(true); | |||
3476 | return A; | |||
3477 | } | |||
3478 | ||||
3479 | IBOutletAttr(SourceRange R, ASTContext &Ctx | |||
3480 | , unsigned SI | |||
3481 | ) | |||
3482 | : InheritableAttr(attr::IBOutlet, R, SI, false, false) | |||
3483 | { | |||
3484 | } | |||
3485 | ||||
3486 | IBOutletAttr *clone(ASTContext &C) const; | |||
3487 | void printPretty(raw_ostream &OS, | |||
3488 | const PrintingPolicy &Policy) const; | |||
3489 | const char *getSpelling() const; | |||
3490 | ||||
3491 | ||||
3492 | static bool classof(const Attr *A) { return A->getKind() == attr::IBOutlet; } | |||
3493 | }; | |||
3494 | ||||
3495 | class IBOutletCollectionAttr : public InheritableAttr { | |||
3496 | TypeSourceInfo * interface_; | |||
3497 | ||||
3498 | public: | |||
3499 | static IBOutletCollectionAttr *CreateImplicit(ASTContext &Ctx, TypeSourceInfo * Interface, SourceRange Loc = SourceRange()) { | |||
3500 | auto *A = new (Ctx) IBOutletCollectionAttr(Loc, Ctx, Interface, 0); | |||
3501 | A->setImplicit(true); | |||
3502 | return A; | |||
3503 | } | |||
3504 | ||||
3505 | IBOutletCollectionAttr(SourceRange R, ASTContext &Ctx | |||
3506 | , TypeSourceInfo * Interface | |||
3507 | , unsigned SI | |||
3508 | ) | |||
3509 | : InheritableAttr(attr::IBOutletCollection, R, SI, false, false) | |||
3510 | , interface_(Interface) | |||
3511 | { | |||
3512 | } | |||
3513 | ||||
3514 | IBOutletCollectionAttr(SourceRange R, ASTContext &Ctx | |||
3515 | , unsigned SI | |||
3516 | ) | |||
3517 | : InheritableAttr(attr::IBOutletCollection, R, SI, false, false) | |||
3518 | , interface_() | |||
3519 | { | |||
3520 | } | |||
3521 | ||||
3522 | IBOutletCollectionAttr *clone(ASTContext &C) const; | |||
3523 | void printPretty(raw_ostream &OS, | |||
3524 | const PrintingPolicy &Policy) const; | |||
3525 | const char *getSpelling() const; | |||
3526 | QualType getInterface() const { | |||
3527 | return interface_->getType(); | |||
3528 | } TypeSourceInfo * getInterfaceLoc() const { | |||
3529 | return interface_; | |||
3530 | } | |||
3531 | ||||
3532 | ||||
3533 | ||||
3534 | static bool classof(const Attr *A) { return A->getKind() == attr::IBOutletCollection; } | |||
3535 | }; | |||
3536 | ||||
3537 | class IFuncAttr : public Attr { | |||
3538 | unsigned resolverLength; | |||
3539 | char *resolver; | |||
3540 | ||||
3541 | public: | |||
3542 | static IFuncAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Resolver, SourceRange Loc = SourceRange()) { | |||
3543 | auto *A = new (Ctx) IFuncAttr(Loc, Ctx, Resolver, 0); | |||
3544 | A->setImplicit(true); | |||
3545 | return A; | |||
3546 | } | |||
3547 | ||||
3548 | IFuncAttr(SourceRange R, ASTContext &Ctx | |||
3549 | , llvm::StringRef Resolver | |||
3550 | , unsigned SI | |||
3551 | ) | |||
3552 | : Attr(attr::IFunc, R, SI, false) | |||
3553 | , resolverLength(Resolver.size()),resolver(new (Ctx, 1) char[resolverLength]) | |||
3554 | { | |||
3555 | if (!Resolver.empty()) | |||
3556 | std::memcpy(resolver, Resolver.data(), resolverLength); | |||
3557 | } | |||
3558 | ||||
3559 | IFuncAttr *clone(ASTContext &C) const; | |||
3560 | void printPretty(raw_ostream &OS, | |||
3561 | const PrintingPolicy &Policy) const; | |||
3562 | const char *getSpelling() const; | |||
3563 | llvm::StringRef getResolver() const { | |||
3564 | return llvm::StringRef(resolver, resolverLength); | |||
3565 | } | |||
3566 | unsigned getResolverLength() const { | |||
3567 | return resolverLength; | |||
3568 | } | |||
3569 | void setResolver(ASTContext &C, llvm::StringRef S) { | |||
3570 | resolverLength = S.size(); | |||
3571 | this->resolver = new (C, 1) char [resolverLength]; | |||
3572 | if (!S.empty()) | |||
3573 | std::memcpy(this->resolver, S.data(), resolverLength); | |||
3574 | } | |||
3575 | ||||
3576 | ||||
3577 | ||||
3578 | static bool classof(const Attr *A) { return A->getKind() == attr::IFunc; } | |||
3579 | }; | |||
3580 | ||||
3581 | class InitPriorityAttr : public InheritableAttr { | |||
3582 | unsigned priority; | |||
3583 | ||||
3584 | public: | |||
3585 | static InitPriorityAttr *CreateImplicit(ASTContext &Ctx, unsigned Priority, SourceRange Loc = SourceRange()) { | |||
3586 | auto *A = new (Ctx) InitPriorityAttr(Loc, Ctx, Priority, 0); | |||
3587 | A->setImplicit(true); | |||
3588 | return A; | |||
3589 | } | |||
3590 | ||||
3591 | InitPriorityAttr(SourceRange R, ASTContext &Ctx | |||
3592 | , unsigned Priority | |||
3593 | , unsigned SI | |||
3594 | ) | |||
3595 | : InheritableAttr(attr::InitPriority, R, SI, false, false) | |||
3596 | , priority(Priority) | |||
3597 | { | |||
3598 | } | |||
3599 | ||||
3600 | InitPriorityAttr *clone(ASTContext &C) const; | |||
3601 | void printPretty(raw_ostream &OS, | |||
3602 | const PrintingPolicy &Policy) const; | |||
3603 | const char *getSpelling() const; | |||
3604 | unsigned getPriority() const { | |||
3605 | return priority; | |||
3606 | } | |||
3607 | ||||
3608 | ||||
3609 | ||||
3610 | static bool classof(const Attr *A) { return A->getKind() == attr::InitPriority; } | |||
3611 | }; | |||
3612 | ||||
3613 | class InitSegAttr : public Attr { | |||
3614 | unsigned sectionLength; | |||
3615 | char *section; | |||
3616 | ||||
3617 | public: | |||
3618 | static InitSegAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Section, SourceRange Loc = SourceRange()) { | |||
3619 | auto *A = new (Ctx) InitSegAttr(Loc, Ctx, Section, 0); | |||
3620 | A->setImplicit(true); | |||
3621 | return A; | |||
3622 | } | |||
3623 | ||||
3624 | InitSegAttr(SourceRange R, ASTContext &Ctx | |||
3625 | , llvm::StringRef Section | |||
3626 | , unsigned SI | |||
3627 | ) | |||
3628 | : Attr(attr::InitSeg, R, SI, false) | |||
3629 | , sectionLength(Section.size()),section(new (Ctx, 1) char[sectionLength]) | |||
3630 | { | |||
3631 | if (!Section.empty()) | |||
3632 | std::memcpy(section, Section.data(), sectionLength); | |||
3633 | } | |||
3634 | ||||
3635 | InitSegAttr *clone(ASTContext &C) const; | |||
3636 | void printPretty(raw_ostream &OS, | |||
3637 | const PrintingPolicy &Policy) const; | |||
3638 | const char *getSpelling() const; | |||
3639 | llvm::StringRef getSection() const { | |||
3640 | return llvm::StringRef(section, sectionLength); | |||
3641 | } | |||
3642 | unsigned getSectionLength() const { | |||
3643 | return sectionLength; | |||
3644 | } | |||
3645 | void setSection(ASTContext &C, llvm::StringRef S) { | |||
3646 | sectionLength = S.size(); | |||
3647 | this->section = new (C, 1) char [sectionLength]; | |||
3648 | if (!S.empty()) | |||
3649 | std::memcpy(this->section, S.data(), sectionLength); | |||
3650 | } | |||
3651 | ||||
3652 | ||||
3653 | void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const { | |||
3654 | OS << " (" << getSection() << ')'; | |||
3655 | } | |||
3656 | ||||
3657 | ||||
3658 | static bool classof(const Attr *A) { return A->getKind() == attr::InitSeg; } | |||
3659 | }; | |||
3660 | ||||
3661 | class IntelOclBiccAttr : public InheritableAttr { | |||
3662 | public: | |||
3663 | static IntelOclBiccAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
3664 | auto *A = new (Ctx) IntelOclBiccAttr(Loc, Ctx, 0); | |||
3665 | A->setImplicit(true); | |||
3666 | return A; | |||
3667 | } | |||
3668 | ||||
3669 | IntelOclBiccAttr(SourceRange R, ASTContext &Ctx | |||
3670 | , unsigned SI | |||
3671 | ) | |||
3672 | : InheritableAttr(attr::IntelOclBicc, R, SI, false, false) | |||
3673 | { | |||
3674 | } | |||
3675 | ||||
3676 | IntelOclBiccAttr *clone(ASTContext &C) const; | |||
3677 | void printPretty(raw_ostream &OS, | |||
3678 | const PrintingPolicy &Policy) const; | |||
3679 | const char *getSpelling() const; | |||
3680 | ||||
3681 | ||||
3682 | static bool classof(const Attr *A) { return A->getKind() == attr::IntelOclBicc; } | |||
3683 | }; | |||
3684 | ||||
3685 | class InternalLinkageAttr : public InheritableAttr { | |||
3686 | public: | |||
3687 | static InternalLinkageAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
3688 | auto *A = new (Ctx) InternalLinkageAttr(Loc, Ctx, 0); | |||
3689 | A->setImplicit(true); | |||
3690 | return A; | |||
3691 | } | |||
3692 | ||||
3693 | InternalLinkageAttr(SourceRange R, ASTContext &Ctx | |||
3694 | , unsigned SI | |||
3695 | ) | |||
3696 | : InheritableAttr(attr::InternalLinkage, R, SI, false, false) | |||
3697 | { | |||
3698 | } | |||
3699 | ||||
3700 | InternalLinkageAttr *clone(ASTContext &C) const; | |||
3701 | void printPretty(raw_ostream &OS, | |||
3702 | const PrintingPolicy &Policy) const; | |||
3703 | const char *getSpelling() const; | |||
3704 | ||||
3705 | ||||
3706 | static bool classof(const Attr *A) { return A->getKind() == attr::InternalLinkage; } | |||
3707 | }; | |||
3708 | ||||
3709 | class LTOVisibilityPublicAttr : public InheritableAttr { | |||
3710 | public: | |||
3711 | static LTOVisibilityPublicAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
3712 | auto *A = new (Ctx) LTOVisibilityPublicAttr(Loc, Ctx, 0); | |||
3713 | A->setImplicit(true); | |||
3714 | return A; | |||
3715 | } | |||
3716 | ||||
3717 | LTOVisibilityPublicAttr(SourceRange R, ASTContext &Ctx | |||
3718 | , unsigned SI | |||
3719 | ) | |||
3720 | : InheritableAttr(attr::LTOVisibilityPublic, R, SI, false, false) | |||
3721 | { | |||
3722 | } | |||
3723 | ||||
3724 | LTOVisibilityPublicAttr *clone(ASTContext &C) const; | |||
3725 | void printPretty(raw_ostream &OS, | |||
3726 | const PrintingPolicy &Policy) const; | |||
3727 | const char *getSpelling() const; | |||
3728 | ||||
3729 | ||||
3730 | static bool classof(const Attr *A) { return A->getKind() == attr::LTOVisibilityPublic; } | |||
3731 | }; | |||
3732 | ||||
3733 | class LayoutVersionAttr : public InheritableAttr { | |||
3734 | unsigned version; | |||
3735 | ||||
3736 | public: | |||
3737 | static LayoutVersionAttr *CreateImplicit(ASTContext &Ctx, unsigned Version, SourceRange Loc = SourceRange()) { | |||
3738 | auto *A = new (Ctx) LayoutVersionAttr(Loc, Ctx, Version, 0); | |||
3739 | A->setImplicit(true); | |||
3740 | return A; | |||
3741 | } | |||
3742 | ||||
3743 | LayoutVersionAttr(SourceRange R, ASTContext &Ctx | |||
3744 | , unsigned Version | |||
3745 | , unsigned SI | |||
3746 | ) | |||
3747 | : InheritableAttr(attr::LayoutVersion, R, SI, false, false) | |||
3748 | , version(Version) | |||
3749 | { | |||
3750 | } | |||
3751 | ||||
3752 | LayoutVersionAttr *clone(ASTContext &C) const; | |||
3753 | void printPretty(raw_ostream &OS, | |||
3754 | const PrintingPolicy &Policy) const; | |||
3755 | const char *getSpelling() const; | |||
3756 | unsigned getVersion() const { | |||
3757 | return version; | |||
3758 | } | |||
3759 | ||||
3760 | ||||
3761 | ||||
3762 | static bool classof(const Attr *A) { return A->getKind() == attr::LayoutVersion; } | |||
3763 | }; | |||
3764 | ||||
3765 | class LockReturnedAttr : public InheritableAttr { | |||
3766 | Expr * arg; | |||
3767 | ||||
3768 | public: | |||
3769 | static LockReturnedAttr *CreateImplicit(ASTContext &Ctx, Expr * Arg, SourceRange Loc = SourceRange()) { | |||
3770 | auto *A = new (Ctx) LockReturnedAttr(Loc, Ctx, Arg, 0); | |||
3771 | A->setImplicit(true); | |||
3772 | return A; | |||
3773 | } | |||
3774 | ||||
3775 | LockReturnedAttr(SourceRange R, ASTContext &Ctx | |||
3776 | , Expr * Arg | |||
3777 | , unsigned SI | |||
3778 | ) | |||
3779 | : InheritableAttr(attr::LockReturned, R, SI, true, false) | |||
3780 | , arg(Arg) | |||
3781 | { | |||
3782 | } | |||
3783 | ||||
3784 | LockReturnedAttr *clone(ASTContext &C) const; | |||
3785 | void printPretty(raw_ostream &OS, | |||
3786 | const PrintingPolicy &Policy) const; | |||
3787 | const char *getSpelling() const; | |||
3788 | Expr * getArg() const { | |||
3789 | return arg; | |||
3790 | } | |||
3791 | ||||
3792 | ||||
3793 | ||||
3794 | static bool classof(const Attr *A) { return A->getKind() == attr::LockReturned; } | |||
3795 | }; | |||
3796 | ||||
3797 | class LocksExcludedAttr : public InheritableAttr { | |||
3798 | unsigned args_Size; | |||
3799 | Expr * *args_; | |||
3800 | ||||
3801 | public: | |||
3802 | static LocksExcludedAttr *CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) { | |||
3803 | auto *A = new (Ctx) LocksExcludedAttr(Loc, Ctx, Args, ArgsSize, 0); | |||
3804 | A->setImplicit(true); | |||
3805 | return A; | |||
3806 | } | |||
3807 | ||||
3808 | LocksExcludedAttr(SourceRange R, ASTContext &Ctx | |||
3809 | , Expr * *Args, unsigned ArgsSize | |||
3810 | , unsigned SI | |||
3811 | ) | |||
3812 | : InheritableAttr(attr::LocksExcluded, R, SI, true, true) | |||
3813 | , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size]) | |||
3814 | { | |||
3815 | std::copy(Args, Args + args_Size, args_); | |||
3816 | } | |||
3817 | ||||
3818 | LocksExcludedAttr(SourceRange R, ASTContext &Ctx | |||
3819 | , unsigned SI | |||
3820 | ) | |||
3821 | : InheritableAttr(attr::LocksExcluded, R, SI, true, true) | |||
3822 | , args_Size(0), args_(nullptr) | |||
3823 | { | |||
3824 | } | |||
3825 | ||||
3826 | LocksExcludedAttr *clone(ASTContext &C) const; | |||
3827 | void printPretty(raw_ostream &OS, | |||
3828 | const PrintingPolicy &Policy) const; | |||
3829 | const char *getSpelling() const; | |||
3830 | typedef Expr ** args_iterator; | |||
3831 | args_iterator args_begin() const { return args_; } | |||
3832 | args_iterator args_end() const { return args_ + args_Size; } | |||
3833 | unsigned args_size() const { return args_Size; } | |||
3834 | llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); } | |||
3835 | ||||
3836 | ||||
3837 | ||||
3838 | ||||
3839 | static bool classof(const Attr *A) { return A->getKind() == attr::LocksExcluded; } | |||
3840 | }; | |||
3841 | ||||
3842 | class LoopHintAttr : public Attr { | |||
3843 | public: | |||
3844 | enum OptionType { | |||
3845 | Vectorize, | |||
3846 | VectorizeWidth, | |||
3847 | Interleave, | |||
3848 | InterleaveCount, | |||
3849 | Unroll, | |||
3850 | UnrollCount, | |||
3851 | Distribute | |||
3852 | }; | |||
3853 | private: | |||
3854 | OptionType option; | |||
3855 | ||||
3856 | public: | |||
3857 | enum LoopHintState { | |||
3858 | Enable, | |||
3859 | Disable, | |||
3860 | Numeric, | |||
3861 | AssumeSafety, | |||
3862 | Full | |||
3863 | }; | |||
3864 | private: | |||
3865 | LoopHintState state; | |||
3866 | ||||
3867 | Expr * value; | |||
3868 | ||||
3869 | public: | |||
3870 | enum Spelling { | |||
3871 | Pragma_clang_loop = 0, | |||
3872 | Pragma_unroll = 1, | |||
3873 | Pragma_nounroll = 2 | |||
3874 | }; | |||
3875 | ||||
3876 | static LoopHintAttr *CreateImplicit(ASTContext &Ctx, Spelling S, OptionType Option, LoopHintState State, Expr * Value, SourceRange Loc = SourceRange()) { | |||
3877 | auto *A = new (Ctx) LoopHintAttr(Loc, Ctx, Option, State, Value, S); | |||
3878 | A->setImplicit(true); | |||
3879 | return A; | |||
3880 | } | |||
3881 | ||||
3882 | LoopHintAttr(SourceRange R, ASTContext &Ctx | |||
3883 | , OptionType Option | |||
3884 | , LoopHintState State | |||
3885 | , Expr * Value | |||
3886 | , unsigned SI | |||
3887 | ) | |||
3888 | : Attr(attr::LoopHint, R, SI, false) | |||
3889 | , option(Option) | |||
3890 | , state(State) | |||
3891 | , value(Value) | |||
3892 | { | |||
3893 | } | |||
3894 | ||||
3895 | LoopHintAttr *clone(ASTContext &C) const; | |||
3896 | void printPretty(raw_ostream &OS, | |||
3897 | const PrintingPolicy &Policy) const; | |||
3898 | const char *getSpelling() const; | |||
3899 | Spelling getSemanticSpelling() const { | |||
3900 | switch (SpellingListIndex) { | |||
3901 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 3901); | |||
3902 | case 0: return Pragma_clang_loop; | |||
3903 | case 1: return Pragma_unroll; | |||
3904 | case 2: return Pragma_nounroll; | |||
3905 | } | |||
3906 | } | |||
3907 | OptionType getOption() const { | |||
3908 | return option; | |||
3909 | } | |||
3910 | ||||
3911 | static bool ConvertStrToOptionType(StringRef Val, OptionType &Out) { | |||
3912 | Optional<OptionType> R = llvm::StringSwitch<Optional<OptionType>>(Val) | |||
3913 | .Case("vectorize", LoopHintAttr::Vectorize) | |||
3914 | .Case("vectorize_width", LoopHintAttr::VectorizeWidth) | |||
3915 | .Case("interleave", LoopHintAttr::Interleave) | |||
3916 | .Case("interleave_count", LoopHintAttr::InterleaveCount) | |||
3917 | .Case("unroll", LoopHintAttr::Unroll) | |||
3918 | .Case("unroll_count", LoopHintAttr::UnrollCount) | |||
3919 | .Case("distribute", LoopHintAttr::Distribute) | |||
3920 | .Default(Optional<OptionType>()); | |||
3921 | if (R) { | |||
3922 | Out = *R; | |||
3923 | return true; | |||
3924 | } | |||
3925 | return false; | |||
3926 | } | |||
3927 | ||||
3928 | static const char *ConvertOptionTypeToStr(OptionType Val) { | |||
3929 | switch(Val) { | |||
3930 | case LoopHintAttr::Vectorize: return "vectorize"; | |||
3931 | case LoopHintAttr::VectorizeWidth: return "vectorize_width"; | |||
3932 | case LoopHintAttr::Interleave: return "interleave"; | |||
3933 | case LoopHintAttr::InterleaveCount: return "interleave_count"; | |||
3934 | case LoopHintAttr::Unroll: return "unroll"; | |||
3935 | case LoopHintAttr::UnrollCount: return "unroll_count"; | |||
3936 | case LoopHintAttr::Distribute: return "distribute"; | |||
3937 | } | |||
3938 | llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 3938); | |||
3939 | } | |||
3940 | LoopHintState getState() const { | |||
3941 | return state; | |||
3942 | } | |||
3943 | ||||
3944 | static bool ConvertStrToLoopHintState(StringRef Val, LoopHintState &Out) { | |||
3945 | Optional<LoopHintState> R = llvm::StringSwitch<Optional<LoopHintState>>(Val) | |||
3946 | .Case("enable", LoopHintAttr::Enable) | |||
3947 | .Case("disable", LoopHintAttr::Disable) | |||
3948 | .Case("numeric", LoopHintAttr::Numeric) | |||
3949 | .Case("assume_safety", LoopHintAttr::AssumeSafety) | |||
3950 | .Case("full", LoopHintAttr::Full) | |||
3951 | .Default(Optional<LoopHintState>()); | |||
3952 | if (R) { | |||
3953 | Out = *R; | |||
3954 | return true; | |||
3955 | } | |||
3956 | return false; | |||
3957 | } | |||
3958 | ||||
3959 | static const char *ConvertLoopHintStateToStr(LoopHintState Val) { | |||
3960 | switch(Val) { | |||
3961 | case LoopHintAttr::Enable: return "enable"; | |||
3962 | case LoopHintAttr::Disable: return "disable"; | |||
3963 | case LoopHintAttr::Numeric: return "numeric"; | |||
3964 | case LoopHintAttr::AssumeSafety: return "assume_safety"; | |||
3965 | case LoopHintAttr::Full: return "full"; | |||
3966 | } | |||
3967 | llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 3967); | |||
3968 | } | |||
3969 | Expr * getValue() const { | |||
3970 | return value; | |||
3971 | } | |||
3972 | ||||
3973 | ||||
3974 | static const char *getOptionName(int Option) { | |||
3975 | switch(Option) { | |||
3976 | case Vectorize: return "vectorize"; | |||
3977 | case VectorizeWidth: return "vectorize_width"; | |||
3978 | case Interleave: return "interleave"; | |||
3979 | case InterleaveCount: return "interleave_count"; | |||
3980 | case Unroll: return "unroll"; | |||
3981 | case UnrollCount: return "unroll_count"; | |||
3982 | case Distribute: return "distribute"; | |||
3983 | } | |||
3984 | llvm_unreachable("Unhandled LoopHint option.")::llvm::llvm_unreachable_internal("Unhandled LoopHint option." , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 3984); | |||
3985 | } | |||
3986 | ||||
3987 | void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const { | |||
3988 | unsigned SpellingIndex = getSpellingListIndex(); | |||
3989 | // For "#pragma unroll" and "#pragma nounroll" the string "unroll" or | |||
3990 | // "nounroll" is already emitted as the pragma name. | |||
3991 | if (SpellingIndex == Pragma_nounroll) | |||
3992 | return; | |||
3993 | else if (SpellingIndex == Pragma_unroll) { | |||
3994 | OS << ' ' << getValueString(Policy); | |||
3995 | return; | |||
3996 | } | |||
3997 | ||||
3998 | assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling")(static_cast <bool> (SpellingIndex == Pragma_clang_loop && "Unexpected spelling") ? void (0) : __assert_fail ("SpellingIndex == Pragma_clang_loop && \"Unexpected spelling\"" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 3998, __extension__ __PRETTY_FUNCTION__)); | |||
3999 | OS << ' ' << getOptionName(option) << getValueString(Policy); | |||
4000 | } | |||
4001 | ||||
4002 | // Return a string containing the loop hint argument including the | |||
4003 | // enclosing parentheses. | |||
4004 | std::string getValueString(const PrintingPolicy &Policy) const { | |||
4005 | std::string ValueName; | |||
4006 | llvm::raw_string_ostream OS(ValueName); | |||
4007 | OS << "("; | |||
4008 | if (state == Numeric) | |||
4009 | value->printPretty(OS, nullptr, Policy); | |||
4010 | else if (state == Enable) | |||
4011 | OS << "enable"; | |||
4012 | else if (state == Full) | |||
4013 | OS << "full"; | |||
4014 | else if (state == AssumeSafety) | |||
4015 | OS << "assume_safety"; | |||
4016 | else | |||
4017 | OS << "disable"; | |||
4018 | OS << ")"; | |||
4019 | return OS.str(); | |||
4020 | } | |||
4021 | ||||
4022 | // Return a string suitable for identifying this attribute in diagnostics. | |||
4023 | std::string getDiagnosticName(const PrintingPolicy &Policy) const { | |||
4024 | unsigned SpellingIndex = getSpellingListIndex(); | |||
4025 | if (SpellingIndex == Pragma_nounroll) | |||
4026 | return "#pragma nounroll"; | |||
4027 | else if (SpellingIndex == Pragma_unroll) | |||
4028 | return "#pragma unroll" + (option == UnrollCount ? getValueString(Policy) : ""); | |||
4029 | ||||
4030 | assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling")(static_cast <bool> (SpellingIndex == Pragma_clang_loop && "Unexpected spelling") ? void (0) : __assert_fail ("SpellingIndex == Pragma_clang_loop && \"Unexpected spelling\"" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 4030, __extension__ __PRETTY_FUNCTION__)); | |||
4031 | return getOptionName(option) + getValueString(Policy); | |||
4032 | } | |||
4033 | ||||
4034 | ||||
4035 | static bool classof(const Attr *A) { return A->getKind() == attr::LoopHint; } | |||
4036 | }; | |||
4037 | ||||
4038 | class MSABIAttr : public InheritableAttr { | |||
4039 | public: | |||
4040 | static MSABIAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4041 | auto *A = new (Ctx) MSABIAttr(Loc, Ctx, 0); | |||
4042 | A->setImplicit(true); | |||
4043 | return A; | |||
4044 | } | |||
4045 | ||||
4046 | MSABIAttr(SourceRange R, ASTContext &Ctx | |||
4047 | , unsigned SI | |||
4048 | ) | |||
4049 | : InheritableAttr(attr::MSABI, R, SI, false, false) | |||
4050 | { | |||
4051 | } | |||
4052 | ||||
4053 | MSABIAttr *clone(ASTContext &C) const; | |||
4054 | void printPretty(raw_ostream &OS, | |||
4055 | const PrintingPolicy &Policy) const; | |||
4056 | const char *getSpelling() const; | |||
4057 | ||||
4058 | ||||
4059 | static bool classof(const Attr *A) { return A->getKind() == attr::MSABI; } | |||
4060 | }; | |||
4061 | ||||
4062 | class MSInheritanceAttr : public InheritableAttr { | |||
4063 | bool bestCase; | |||
4064 | ||||
4065 | public: | |||
4066 | enum Spelling { | |||
4067 | Keyword_single_inheritance = 0, | |||
4068 | Keyword_multiple_inheritance = 1, | |||
4069 | Keyword_virtual_inheritance = 2, | |||
4070 | Keyword_unspecified_inheritance = 3 | |||
4071 | }; | |||
4072 | ||||
4073 | static MSInheritanceAttr *CreateImplicit(ASTContext &Ctx, Spelling S, bool BestCase, SourceRange Loc = SourceRange()) { | |||
4074 | auto *A = new (Ctx) MSInheritanceAttr(Loc, Ctx, BestCase, S); | |||
4075 | A->setImplicit(true); | |||
4076 | return A; | |||
4077 | } | |||
4078 | ||||
4079 | static MSInheritanceAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) { | |||
4080 | auto *A = new (Ctx) MSInheritanceAttr(Loc, Ctx, S); | |||
4081 | A->setImplicit(true); | |||
4082 | return A; | |||
4083 | } | |||
4084 | ||||
4085 | MSInheritanceAttr(SourceRange R, ASTContext &Ctx | |||
4086 | , bool BestCase | |||
4087 | , unsigned SI | |||
4088 | ) | |||
4089 | : InheritableAttr(attr::MSInheritance, R, SI, false, false) | |||
4090 | , bestCase(BestCase) | |||
4091 | { | |||
4092 | } | |||
4093 | ||||
4094 | MSInheritanceAttr(SourceRange R, ASTContext &Ctx | |||
4095 | , unsigned SI | |||
4096 | ) | |||
4097 | : InheritableAttr(attr::MSInheritance, R, SI, false, false) | |||
4098 | , bestCase() | |||
4099 | { | |||
4100 | } | |||
4101 | ||||
4102 | MSInheritanceAttr *clone(ASTContext &C) const; | |||
4103 | void printPretty(raw_ostream &OS, | |||
4104 | const PrintingPolicy &Policy) const; | |||
4105 | const char *getSpelling() const; | |||
4106 | Spelling getSemanticSpelling() const { | |||
4107 | switch (SpellingListIndex) { | |||
4108 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 4108); | |||
4109 | case 0: return Keyword_single_inheritance; | |||
4110 | case 1: return Keyword_multiple_inheritance; | |||
4111 | case 2: return Keyword_virtual_inheritance; | |||
4112 | case 3: return Keyword_unspecified_inheritance; | |||
4113 | } | |||
4114 | } | |||
4115 | bool getBestCase() const { | |||
4116 | return bestCase; | |||
4117 | } | |||
4118 | ||||
4119 | static const bool DefaultBestCase = true; | |||
4120 | ||||
4121 | ||||
4122 | static bool hasVBPtrOffsetField(Spelling Inheritance) { | |||
4123 | return Inheritance == Keyword_unspecified_inheritance; | |||
4124 | } | |||
4125 | ||||
4126 | // Only member pointers to functions need a this adjustment, since it can be | |||
4127 | // combined with the field offset for data pointers. | |||
4128 | static bool hasNVOffsetField(bool IsMemberFunction, Spelling Inheritance) { | |||
4129 | return IsMemberFunction && Inheritance >= Keyword_multiple_inheritance; | |||
4130 | } | |||
4131 | ||||
4132 | static bool hasVBTableOffsetField(Spelling Inheritance) { | |||
4133 | return Inheritance >= Keyword_virtual_inheritance; | |||
4134 | } | |||
4135 | ||||
4136 | static bool hasOnlyOneField(bool IsMemberFunction, | |||
4137 | Spelling Inheritance) { | |||
4138 | if (IsMemberFunction) | |||
4139 | return Inheritance <= Keyword_single_inheritance; | |||
4140 | return Inheritance <= Keyword_multiple_inheritance; | |||
4141 | } | |||
4142 | ||||
4143 | ||||
4144 | static bool classof(const Attr *A) { return A->getKind() == attr::MSInheritance; } | |||
4145 | }; | |||
4146 | ||||
4147 | class MSNoVTableAttr : public InheritableAttr { | |||
4148 | public: | |||
4149 | static MSNoVTableAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4150 | auto *A = new (Ctx) MSNoVTableAttr(Loc, Ctx, 0); | |||
4151 | A->setImplicit(true); | |||
4152 | return A; | |||
4153 | } | |||
4154 | ||||
4155 | MSNoVTableAttr(SourceRange R, ASTContext &Ctx | |||
4156 | , unsigned SI | |||
4157 | ) | |||
4158 | : InheritableAttr(attr::MSNoVTable, R, SI, false, false) | |||
4159 | { | |||
4160 | } | |||
4161 | ||||
4162 | MSNoVTableAttr *clone(ASTContext &C) const; | |||
4163 | void printPretty(raw_ostream &OS, | |||
4164 | const PrintingPolicy &Policy) const; | |||
4165 | const char *getSpelling() const; | |||
4166 | ||||
4167 | ||||
4168 | static bool classof(const Attr *A) { return A->getKind() == attr::MSNoVTable; } | |||
4169 | }; | |||
4170 | ||||
4171 | class MSP430InterruptAttr : public InheritableAttr { | |||
4172 | unsigned number; | |||
4173 | ||||
4174 | public: | |||
4175 | static MSP430InterruptAttr *CreateImplicit(ASTContext &Ctx, unsigned Number, SourceRange Loc = SourceRange()) { | |||
4176 | auto *A = new (Ctx) MSP430InterruptAttr(Loc, Ctx, Number, 0); | |||
4177 | A->setImplicit(true); | |||
4178 | return A; | |||
4179 | } | |||
4180 | ||||
4181 | MSP430InterruptAttr(SourceRange R, ASTContext &Ctx | |||
4182 | , unsigned Number | |||
4183 | , unsigned SI | |||
4184 | ) | |||
4185 | : InheritableAttr(attr::MSP430Interrupt, R, SI, false, false) | |||
4186 | , number(Number) | |||
4187 | { | |||
4188 | } | |||
4189 | ||||
4190 | MSP430InterruptAttr *clone(ASTContext &C) const; | |||
4191 | void printPretty(raw_ostream &OS, | |||
4192 | const PrintingPolicy &Policy) const; | |||
4193 | const char *getSpelling() const; | |||
4194 | unsigned getNumber() const { | |||
4195 | return number; | |||
4196 | } | |||
4197 | ||||
4198 | ||||
4199 | ||||
4200 | static bool classof(const Attr *A) { return A->getKind() == attr::MSP430Interrupt; } | |||
4201 | }; | |||
4202 | ||||
4203 | class MSStructAttr : public InheritableAttr { | |||
4204 | public: | |||
4205 | static MSStructAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4206 | auto *A = new (Ctx) MSStructAttr(Loc, Ctx, 0); | |||
4207 | A->setImplicit(true); | |||
4208 | return A; | |||
4209 | } | |||
4210 | ||||
4211 | MSStructAttr(SourceRange R, ASTContext &Ctx | |||
4212 | , unsigned SI | |||
4213 | ) | |||
4214 | : InheritableAttr(attr::MSStruct, R, SI, false, false) | |||
4215 | { | |||
4216 | } | |||
4217 | ||||
4218 | MSStructAttr *clone(ASTContext &C) const; | |||
4219 | void printPretty(raw_ostream &OS, | |||
4220 | const PrintingPolicy &Policy) const; | |||
4221 | const char *getSpelling() const; | |||
4222 | ||||
4223 | ||||
4224 | static bool classof(const Attr *A) { return A->getKind() == attr::MSStruct; } | |||
4225 | }; | |||
4226 | ||||
4227 | class MSVtorDispAttr : public InheritableAttr { | |||
4228 | unsigned vdm; | |||
4229 | ||||
4230 | public: | |||
4231 | static MSVtorDispAttr *CreateImplicit(ASTContext &Ctx, unsigned Vdm, SourceRange Loc = SourceRange()) { | |||
4232 | auto *A = new (Ctx) MSVtorDispAttr(Loc, Ctx, Vdm, 0); | |||
4233 | A->setImplicit(true); | |||
4234 | return A; | |||
4235 | } | |||
4236 | ||||
4237 | MSVtorDispAttr(SourceRange R, ASTContext &Ctx | |||
4238 | , unsigned Vdm | |||
4239 | , unsigned SI | |||
4240 | ) | |||
4241 | : InheritableAttr(attr::MSVtorDisp, R, SI, false, false) | |||
4242 | , vdm(Vdm) | |||
4243 | { | |||
4244 | } | |||
4245 | ||||
4246 | MSVtorDispAttr *clone(ASTContext &C) const; | |||
4247 | void printPretty(raw_ostream &OS, | |||
4248 | const PrintingPolicy &Policy) const; | |||
4249 | const char *getSpelling() const; | |||
4250 | unsigned getVdm() const { | |||
4251 | return vdm; | |||
4252 | } | |||
4253 | ||||
4254 | ||||
4255 | enum Mode { | |||
4256 | Never, | |||
4257 | ForVBaseOverride, | |||
4258 | ForVFTable | |||
4259 | }; | |||
4260 | ||||
4261 | Mode getVtorDispMode() const { return Mode(vdm); } | |||
4262 | ||||
4263 | ||||
4264 | static bool classof(const Attr *A) { return A->getKind() == attr::MSVtorDisp; } | |||
4265 | }; | |||
4266 | ||||
4267 | class MaxFieldAlignmentAttr : public InheritableAttr { | |||
4268 | unsigned alignment; | |||
4269 | ||||
4270 | public: | |||
4271 | static MaxFieldAlignmentAttr *CreateImplicit(ASTContext &Ctx, unsigned Alignment, SourceRange Loc = SourceRange()) { | |||
4272 | auto *A = new (Ctx) MaxFieldAlignmentAttr(Loc, Ctx, Alignment, 0); | |||
4273 | A->setImplicit(true); | |||
4274 | return A; | |||
4275 | } | |||
4276 | ||||
4277 | MaxFieldAlignmentAttr(SourceRange R, ASTContext &Ctx | |||
4278 | , unsigned Alignment | |||
4279 | , unsigned SI | |||
4280 | ) | |||
4281 | : InheritableAttr(attr::MaxFieldAlignment, R, SI, false, false) | |||
4282 | , alignment(Alignment) | |||
4283 | { | |||
4284 | } | |||
4285 | ||||
4286 | MaxFieldAlignmentAttr *clone(ASTContext &C) const; | |||
4287 | void printPretty(raw_ostream &OS, | |||
4288 | const PrintingPolicy &Policy) const; | |||
4289 | const char *getSpelling() const; | |||
4290 | unsigned getAlignment() const { | |||
4291 | return alignment; | |||
4292 | } | |||
4293 | ||||
4294 | ||||
4295 | ||||
4296 | static bool classof(const Attr *A) { return A->getKind() == attr::MaxFieldAlignment; } | |||
4297 | }; | |||
4298 | ||||
4299 | class MayAliasAttr : public InheritableAttr { | |||
4300 | public: | |||
4301 | static MayAliasAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4302 | auto *A = new (Ctx) MayAliasAttr(Loc, Ctx, 0); | |||
4303 | A->setImplicit(true); | |||
4304 | return A; | |||
4305 | } | |||
4306 | ||||
4307 | MayAliasAttr(SourceRange R, ASTContext &Ctx | |||
4308 | , unsigned SI | |||
4309 | ) | |||
4310 | : InheritableAttr(attr::MayAlias, R, SI, false, false) | |||
4311 | { | |||
4312 | } | |||
4313 | ||||
4314 | MayAliasAttr *clone(ASTContext &C) const; | |||
4315 | void printPretty(raw_ostream &OS, | |||
4316 | const PrintingPolicy &Policy) const; | |||
4317 | const char *getSpelling() const; | |||
4318 | ||||
4319 | ||||
4320 | static bool classof(const Attr *A) { return A->getKind() == attr::MayAlias; } | |||
4321 | }; | |||
4322 | ||||
4323 | class MicroMipsAttr : public InheritableAttr { | |||
4324 | public: | |||
4325 | static MicroMipsAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4326 | auto *A = new (Ctx) MicroMipsAttr(Loc, Ctx, 0); | |||
4327 | A->setImplicit(true); | |||
4328 | return A; | |||
4329 | } | |||
4330 | ||||
4331 | MicroMipsAttr(SourceRange R, ASTContext &Ctx | |||
4332 | , unsigned SI | |||
4333 | ) | |||
4334 | : InheritableAttr(attr::MicroMips, R, SI, false, false) | |||
4335 | { | |||
4336 | } | |||
4337 | ||||
4338 | MicroMipsAttr *clone(ASTContext &C) const; | |||
4339 | void printPretty(raw_ostream &OS, | |||
4340 | const PrintingPolicy &Policy) const; | |||
4341 | const char *getSpelling() const; | |||
4342 | ||||
4343 | ||||
4344 | static bool classof(const Attr *A) { return A->getKind() == attr::MicroMips; } | |||
4345 | }; | |||
4346 | ||||
4347 | class MinSizeAttr : public InheritableAttr { | |||
4348 | public: | |||
4349 | static MinSizeAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4350 | auto *A = new (Ctx) MinSizeAttr(Loc, Ctx, 0); | |||
4351 | A->setImplicit(true); | |||
4352 | return A; | |||
4353 | } | |||
4354 | ||||
4355 | MinSizeAttr(SourceRange R, ASTContext &Ctx | |||
4356 | , unsigned SI | |||
4357 | ) | |||
4358 | : InheritableAttr(attr::MinSize, R, SI, false, false) | |||
4359 | { | |||
4360 | } | |||
4361 | ||||
4362 | MinSizeAttr *clone(ASTContext &C) const; | |||
4363 | void printPretty(raw_ostream &OS, | |||
4364 | const PrintingPolicy &Policy) const; | |||
4365 | const char *getSpelling() const; | |||
4366 | ||||
4367 | ||||
4368 | static bool classof(const Attr *A) { return A->getKind() == attr::MinSize; } | |||
4369 | }; | |||
4370 | ||||
4371 | class MinVectorWidthAttr : public InheritableAttr { | |||
4372 | unsigned vectorWidth; | |||
4373 | ||||
4374 | public: | |||
4375 | static MinVectorWidthAttr *CreateImplicit(ASTContext &Ctx, unsigned VectorWidth, SourceRange Loc = SourceRange()) { | |||
4376 | auto *A = new (Ctx) MinVectorWidthAttr(Loc, Ctx, VectorWidth, 0); | |||
4377 | A->setImplicit(true); | |||
4378 | return A; | |||
4379 | } | |||
4380 | ||||
4381 | MinVectorWidthAttr(SourceRange R, ASTContext &Ctx | |||
4382 | , unsigned VectorWidth | |||
4383 | , unsigned SI | |||
4384 | ) | |||
4385 | : InheritableAttr(attr::MinVectorWidth, R, SI, false, false) | |||
4386 | , vectorWidth(VectorWidth) | |||
4387 | { | |||
4388 | } | |||
4389 | ||||
4390 | MinVectorWidthAttr *clone(ASTContext &C) const; | |||
4391 | void printPretty(raw_ostream &OS, | |||
4392 | const PrintingPolicy &Policy) const; | |||
4393 | const char *getSpelling() const; | |||
4394 | unsigned getVectorWidth() const { | |||
4395 | return vectorWidth; | |||
4396 | } | |||
4397 | ||||
4398 | ||||
4399 | ||||
4400 | static bool classof(const Attr *A) { return A->getKind() == attr::MinVectorWidth; } | |||
4401 | }; | |||
4402 | ||||
4403 | class Mips16Attr : public InheritableAttr { | |||
4404 | public: | |||
4405 | static Mips16Attr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4406 | auto *A = new (Ctx) Mips16Attr(Loc, Ctx, 0); | |||
4407 | A->setImplicit(true); | |||
4408 | return A; | |||
4409 | } | |||
4410 | ||||
4411 | Mips16Attr(SourceRange R, ASTContext &Ctx | |||
4412 | , unsigned SI | |||
4413 | ) | |||
4414 | : InheritableAttr(attr::Mips16, R, SI, false, false) | |||
4415 | { | |||
4416 | } | |||
4417 | ||||
4418 | Mips16Attr *clone(ASTContext &C) const; | |||
4419 | void printPretty(raw_ostream &OS, | |||
4420 | const PrintingPolicy &Policy) const; | |||
4421 | const char *getSpelling() const; | |||
4422 | ||||
4423 | ||||
4424 | static bool classof(const Attr *A) { return A->getKind() == attr::Mips16; } | |||
4425 | }; | |||
4426 | ||||
4427 | class MipsInterruptAttr : public InheritableAttr { | |||
4428 | public: | |||
4429 | enum InterruptType { | |||
4430 | sw0, | |||
4431 | sw1, | |||
4432 | hw0, | |||
4433 | hw1, | |||
4434 | hw2, | |||
4435 | hw3, | |||
4436 | hw4, | |||
4437 | hw5, | |||
4438 | eic | |||
4439 | }; | |||
4440 | private: | |||
4441 | InterruptType interrupt; | |||
4442 | ||||
4443 | public: | |||
4444 | static MipsInterruptAttr *CreateImplicit(ASTContext &Ctx, InterruptType Interrupt, SourceRange Loc = SourceRange()) { | |||
4445 | auto *A = new (Ctx) MipsInterruptAttr(Loc, Ctx, Interrupt, 0); | |||
4446 | A->setImplicit(true); | |||
4447 | return A; | |||
4448 | } | |||
4449 | ||||
4450 | MipsInterruptAttr(SourceRange R, ASTContext &Ctx | |||
4451 | , InterruptType Interrupt | |||
4452 | , unsigned SI | |||
4453 | ) | |||
4454 | : InheritableAttr(attr::MipsInterrupt, R, SI, false, false) | |||
4455 | , interrupt(Interrupt) | |||
4456 | { | |||
4457 | } | |||
4458 | ||||
4459 | MipsInterruptAttr *clone(ASTContext &C) const; | |||
4460 | void printPretty(raw_ostream &OS, | |||
4461 | const PrintingPolicy &Policy) const; | |||
4462 | const char *getSpelling() const; | |||
4463 | InterruptType getInterrupt() const { | |||
4464 | return interrupt; | |||
4465 | } | |||
4466 | ||||
4467 | static bool ConvertStrToInterruptType(StringRef Val, InterruptType &Out) { | |||
4468 | Optional<InterruptType> R = llvm::StringSwitch<Optional<InterruptType>>(Val) | |||
4469 | .Case("vector=sw0", MipsInterruptAttr::sw0) | |||
4470 | .Case("vector=sw1", MipsInterruptAttr::sw1) | |||
4471 | .Case("vector=hw0", MipsInterruptAttr::hw0) | |||
4472 | .Case("vector=hw1", MipsInterruptAttr::hw1) | |||
4473 | .Case("vector=hw2", MipsInterruptAttr::hw2) | |||
4474 | .Case("vector=hw3", MipsInterruptAttr::hw3) | |||
4475 | .Case("vector=hw4", MipsInterruptAttr::hw4) | |||
4476 | .Case("vector=hw5", MipsInterruptAttr::hw5) | |||
4477 | .Case("eic", MipsInterruptAttr::eic) | |||
4478 | .Case("", MipsInterruptAttr::eic) | |||
4479 | .Default(Optional<InterruptType>()); | |||
4480 | if (R) { | |||
4481 | Out = *R; | |||
4482 | return true; | |||
4483 | } | |||
4484 | return false; | |||
4485 | } | |||
4486 | ||||
4487 | static const char *ConvertInterruptTypeToStr(InterruptType Val) { | |||
4488 | switch(Val) { | |||
4489 | case MipsInterruptAttr::sw0: return "vector=sw0"; | |||
4490 | case MipsInterruptAttr::sw1: return "vector=sw1"; | |||
4491 | case MipsInterruptAttr::hw0: return "vector=hw0"; | |||
4492 | case MipsInterruptAttr::hw1: return "vector=hw1"; | |||
4493 | case MipsInterruptAttr::hw2: return "vector=hw2"; | |||
4494 | case MipsInterruptAttr::hw3: return "vector=hw3"; | |||
4495 | case MipsInterruptAttr::hw4: return "vector=hw4"; | |||
4496 | case MipsInterruptAttr::hw5: return "vector=hw5"; | |||
4497 | case MipsInterruptAttr::eic: return "eic"; | |||
4498 | } | |||
4499 | llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 4499); | |||
4500 | } | |||
4501 | ||||
4502 | ||||
4503 | static bool classof(const Attr *A) { return A->getKind() == attr::MipsInterrupt; } | |||
4504 | }; | |||
4505 | ||||
4506 | class MipsLongCallAttr : public InheritableAttr { | |||
4507 | public: | |||
4508 | enum Spelling { | |||
4509 | GNU_long_call = 0, | |||
4510 | CXX11_gnu_long_call = 1, | |||
4511 | GNU_far = 2, | |||
4512 | CXX11_gnu_far = 3 | |||
4513 | }; | |||
4514 | ||||
4515 | static MipsLongCallAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) { | |||
4516 | auto *A = new (Ctx) MipsLongCallAttr(Loc, Ctx, S); | |||
4517 | A->setImplicit(true); | |||
4518 | return A; | |||
4519 | } | |||
4520 | ||||
4521 | MipsLongCallAttr(SourceRange R, ASTContext &Ctx | |||
4522 | , unsigned SI | |||
4523 | ) | |||
4524 | : InheritableAttr(attr::MipsLongCall, R, SI, false, false) | |||
4525 | { | |||
4526 | } | |||
4527 | ||||
4528 | MipsLongCallAttr *clone(ASTContext &C) const; | |||
4529 | void printPretty(raw_ostream &OS, | |||
4530 | const PrintingPolicy &Policy) const; | |||
4531 | const char *getSpelling() const; | |||
4532 | Spelling getSemanticSpelling() const { | |||
4533 | switch (SpellingListIndex) { | |||
4534 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 4534); | |||
4535 | case 0: return GNU_long_call; | |||
4536 | case 1: return CXX11_gnu_long_call; | |||
4537 | case 2: return GNU_far; | |||
4538 | case 3: return CXX11_gnu_far; | |||
4539 | } | |||
4540 | } | |||
4541 | ||||
4542 | ||||
4543 | static bool classof(const Attr *A) { return A->getKind() == attr::MipsLongCall; } | |||
4544 | }; | |||
4545 | ||||
4546 | class MipsShortCallAttr : public InheritableAttr { | |||
4547 | public: | |||
4548 | enum Spelling { | |||
4549 | GNU_short_call = 0, | |||
4550 | CXX11_gnu_short_call = 1, | |||
4551 | GNU_near = 2, | |||
4552 | CXX11_gnu_near = 3 | |||
4553 | }; | |||
4554 | ||||
4555 | static MipsShortCallAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) { | |||
4556 | auto *A = new (Ctx) MipsShortCallAttr(Loc, Ctx, S); | |||
4557 | A->setImplicit(true); | |||
4558 | return A; | |||
4559 | } | |||
4560 | ||||
4561 | MipsShortCallAttr(SourceRange R, ASTContext &Ctx | |||
4562 | , unsigned SI | |||
4563 | ) | |||
4564 | : InheritableAttr(attr::MipsShortCall, R, SI, false, false) | |||
4565 | { | |||
4566 | } | |||
4567 | ||||
4568 | MipsShortCallAttr *clone(ASTContext &C) const; | |||
4569 | void printPretty(raw_ostream &OS, | |||
4570 | const PrintingPolicy &Policy) const; | |||
4571 | const char *getSpelling() const; | |||
4572 | Spelling getSemanticSpelling() const { | |||
4573 | switch (SpellingListIndex) { | |||
4574 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 4574); | |||
4575 | case 0: return GNU_short_call; | |||
4576 | case 1: return CXX11_gnu_short_call; | |||
4577 | case 2: return GNU_near; | |||
4578 | case 3: return CXX11_gnu_near; | |||
4579 | } | |||
4580 | } | |||
4581 | ||||
4582 | ||||
4583 | static bool classof(const Attr *A) { return A->getKind() == attr::MipsShortCall; } | |||
4584 | }; | |||
4585 | ||||
4586 | class ModeAttr : public Attr { | |||
4587 | IdentifierInfo * mode; | |||
4588 | ||||
4589 | public: | |||
4590 | static ModeAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * Mode, SourceRange Loc = SourceRange()) { | |||
4591 | auto *A = new (Ctx) ModeAttr(Loc, Ctx, Mode, 0); | |||
4592 | A->setImplicit(true); | |||
4593 | return A; | |||
4594 | } | |||
4595 | ||||
4596 | ModeAttr(SourceRange R, ASTContext &Ctx | |||
4597 | , IdentifierInfo * Mode | |||
4598 | , unsigned SI | |||
4599 | ) | |||
4600 | : Attr(attr::Mode, R, SI, false) | |||
4601 | , mode(Mode) | |||
4602 | { | |||
4603 | } | |||
4604 | ||||
4605 | ModeAttr *clone(ASTContext &C) const; | |||
4606 | void printPretty(raw_ostream &OS, | |||
4607 | const PrintingPolicy &Policy) const; | |||
4608 | const char *getSpelling() const; | |||
4609 | IdentifierInfo * getMode() const { | |||
4610 | return mode; | |||
4611 | } | |||
4612 | ||||
4613 | ||||
4614 | ||||
4615 | static bool classof(const Attr *A) { return A->getKind() == attr::Mode; } | |||
4616 | }; | |||
4617 | ||||
4618 | class NSConsumedAttr : public InheritableParamAttr { | |||
4619 | public: | |||
4620 | static NSConsumedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4621 | auto *A = new (Ctx) NSConsumedAttr(Loc, Ctx, 0); | |||
4622 | A->setImplicit(true); | |||
4623 | return A; | |||
4624 | } | |||
4625 | ||||
4626 | NSConsumedAttr(SourceRange R, ASTContext &Ctx | |||
4627 | , unsigned SI | |||
4628 | ) | |||
4629 | : InheritableParamAttr(attr::NSConsumed, R, SI, false, false) | |||
4630 | { | |||
4631 | } | |||
4632 | ||||
4633 | NSConsumedAttr *clone(ASTContext &C) const; | |||
4634 | void printPretty(raw_ostream &OS, | |||
4635 | const PrintingPolicy &Policy) const; | |||
4636 | const char *getSpelling() const; | |||
4637 | ||||
4638 | ||||
4639 | static bool classof(const Attr *A) { return A->getKind() == attr::NSConsumed; } | |||
4640 | }; | |||
4641 | ||||
4642 | class NSConsumesSelfAttr : public InheritableAttr { | |||
4643 | public: | |||
4644 | static NSConsumesSelfAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4645 | auto *A = new (Ctx) NSConsumesSelfAttr(Loc, Ctx, 0); | |||
4646 | A->setImplicit(true); | |||
4647 | return A; | |||
4648 | } | |||
4649 | ||||
4650 | NSConsumesSelfAttr(SourceRange R, ASTContext &Ctx | |||
4651 | , unsigned SI | |||
4652 | ) | |||
4653 | : InheritableAttr(attr::NSConsumesSelf, R, SI, false, false) | |||
4654 | { | |||
4655 | } | |||
4656 | ||||
4657 | NSConsumesSelfAttr *clone(ASTContext &C) const; | |||
4658 | void printPretty(raw_ostream &OS, | |||
4659 | const PrintingPolicy &Policy) const; | |||
4660 | const char *getSpelling() const; | |||
4661 | ||||
4662 | ||||
4663 | static bool classof(const Attr *A) { return A->getKind() == attr::NSConsumesSelf; } | |||
4664 | }; | |||
4665 | ||||
4666 | class NSReturnsAutoreleasedAttr : public InheritableAttr { | |||
4667 | public: | |||
4668 | static NSReturnsAutoreleasedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4669 | auto *A = new (Ctx) NSReturnsAutoreleasedAttr(Loc, Ctx, 0); | |||
4670 | A->setImplicit(true); | |||
4671 | return A; | |||
4672 | } | |||
4673 | ||||
4674 | NSReturnsAutoreleasedAttr(SourceRange R, ASTContext &Ctx | |||
4675 | , unsigned SI | |||
4676 | ) | |||
4677 | : InheritableAttr(attr::NSReturnsAutoreleased, R, SI, false, false) | |||
4678 | { | |||
4679 | } | |||
4680 | ||||
4681 | NSReturnsAutoreleasedAttr *clone(ASTContext &C) const; | |||
4682 | void printPretty(raw_ostream &OS, | |||
4683 | const PrintingPolicy &Policy) const; | |||
4684 | const char *getSpelling() const; | |||
4685 | ||||
4686 | ||||
4687 | static bool classof(const Attr *A) { return A->getKind() == attr::NSReturnsAutoreleased; } | |||
4688 | }; | |||
4689 | ||||
4690 | class NSReturnsNotRetainedAttr : public InheritableAttr { | |||
4691 | public: | |||
4692 | static NSReturnsNotRetainedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4693 | auto *A = new (Ctx) NSReturnsNotRetainedAttr(Loc, Ctx, 0); | |||
4694 | A->setImplicit(true); | |||
4695 | return A; | |||
4696 | } | |||
4697 | ||||
4698 | NSReturnsNotRetainedAttr(SourceRange R, ASTContext &Ctx | |||
4699 | , unsigned SI | |||
4700 | ) | |||
4701 | : InheritableAttr(attr::NSReturnsNotRetained, R, SI, false, false) | |||
4702 | { | |||
4703 | } | |||
4704 | ||||
4705 | NSReturnsNotRetainedAttr *clone(ASTContext &C) const; | |||
4706 | void printPretty(raw_ostream &OS, | |||
4707 | const PrintingPolicy &Policy) const; | |||
4708 | const char *getSpelling() const; | |||
4709 | ||||
4710 | ||||
4711 | static bool classof(const Attr *A) { return A->getKind() == attr::NSReturnsNotRetained; } | |||
4712 | }; | |||
4713 | ||||
4714 | class NSReturnsRetainedAttr : public InheritableAttr { | |||
4715 | public: | |||
4716 | static NSReturnsRetainedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4717 | auto *A = new (Ctx) NSReturnsRetainedAttr(Loc, Ctx, 0); | |||
4718 | A->setImplicit(true); | |||
4719 | return A; | |||
4720 | } | |||
4721 | ||||
4722 | NSReturnsRetainedAttr(SourceRange R, ASTContext &Ctx | |||
4723 | , unsigned SI | |||
4724 | ) | |||
4725 | : InheritableAttr(attr::NSReturnsRetained, R, SI, false, false) | |||
4726 | { | |||
4727 | } | |||
4728 | ||||
4729 | NSReturnsRetainedAttr *clone(ASTContext &C) const; | |||
4730 | void printPretty(raw_ostream &OS, | |||
4731 | const PrintingPolicy &Policy) const; | |||
4732 | const char *getSpelling() const; | |||
4733 | ||||
4734 | ||||
4735 | static bool classof(const Attr *A) { return A->getKind() == attr::NSReturnsRetained; } | |||
4736 | }; | |||
4737 | ||||
4738 | class NakedAttr : public InheritableAttr { | |||
4739 | public: | |||
4740 | static NakedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4741 | auto *A = new (Ctx) NakedAttr(Loc, Ctx, 0); | |||
4742 | A->setImplicit(true); | |||
4743 | return A; | |||
4744 | } | |||
4745 | ||||
4746 | NakedAttr(SourceRange R, ASTContext &Ctx | |||
4747 | , unsigned SI | |||
4748 | ) | |||
4749 | : InheritableAttr(attr::Naked, R, SI, false, false) | |||
4750 | { | |||
4751 | } | |||
4752 | ||||
4753 | NakedAttr *clone(ASTContext &C) const; | |||
4754 | void printPretty(raw_ostream &OS, | |||
4755 | const PrintingPolicy &Policy) const; | |||
4756 | const char *getSpelling() const; | |||
4757 | ||||
4758 | ||||
4759 | static bool classof(const Attr *A) { return A->getKind() == attr::Naked; } | |||
4760 | }; | |||
4761 | ||||
4762 | class NoAliasAttr : public InheritableAttr { | |||
4763 | public: | |||
4764 | static NoAliasAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4765 | auto *A = new (Ctx) NoAliasAttr(Loc, Ctx, 0); | |||
4766 | A->setImplicit(true); | |||
4767 | return A; | |||
4768 | } | |||
4769 | ||||
4770 | NoAliasAttr(SourceRange R, ASTContext &Ctx | |||
4771 | , unsigned SI | |||
4772 | ) | |||
4773 | : InheritableAttr(attr::NoAlias, R, SI, false, false) | |||
4774 | { | |||
4775 | } | |||
4776 | ||||
4777 | NoAliasAttr *clone(ASTContext &C) const; | |||
4778 | void printPretty(raw_ostream &OS, | |||
4779 | const PrintingPolicy &Policy) const; | |||
4780 | const char *getSpelling() const; | |||
4781 | ||||
4782 | ||||
4783 | static bool classof(const Attr *A) { return A->getKind() == attr::NoAlias; } | |||
4784 | }; | |||
4785 | ||||
4786 | class NoCommonAttr : public InheritableAttr { | |||
4787 | public: | |||
4788 | static NoCommonAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4789 | auto *A = new (Ctx) NoCommonAttr(Loc, Ctx, 0); | |||
4790 | A->setImplicit(true); | |||
4791 | return A; | |||
4792 | } | |||
4793 | ||||
4794 | NoCommonAttr(SourceRange R, ASTContext &Ctx | |||
4795 | , unsigned SI | |||
4796 | ) | |||
4797 | : InheritableAttr(attr::NoCommon, R, SI, false, false) | |||
4798 | { | |||
4799 | } | |||
4800 | ||||
4801 | NoCommonAttr *clone(ASTContext &C) const; | |||
4802 | void printPretty(raw_ostream &OS, | |||
4803 | const PrintingPolicy &Policy) const; | |||
4804 | const char *getSpelling() const; | |||
4805 | ||||
4806 | ||||
4807 | static bool classof(const Attr *A) { return A->getKind() == attr::NoCommon; } | |||
4808 | }; | |||
4809 | ||||
4810 | class NoDebugAttr : public InheritableAttr { | |||
4811 | public: | |||
4812 | static NoDebugAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4813 | auto *A = new (Ctx) NoDebugAttr(Loc, Ctx, 0); | |||
4814 | A->setImplicit(true); | |||
4815 | return A; | |||
4816 | } | |||
4817 | ||||
4818 | NoDebugAttr(SourceRange R, ASTContext &Ctx | |||
4819 | , unsigned SI | |||
4820 | ) | |||
4821 | : InheritableAttr(attr::NoDebug, R, SI, false, false) | |||
4822 | { | |||
4823 | } | |||
4824 | ||||
4825 | NoDebugAttr *clone(ASTContext &C) const; | |||
4826 | void printPretty(raw_ostream &OS, | |||
4827 | const PrintingPolicy &Policy) const; | |||
4828 | const char *getSpelling() const; | |||
4829 | ||||
4830 | ||||
4831 | static bool classof(const Attr *A) { return A->getKind() == attr::NoDebug; } | |||
4832 | }; | |||
4833 | ||||
4834 | class NoDuplicateAttr : public InheritableAttr { | |||
4835 | public: | |||
4836 | static NoDuplicateAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4837 | auto *A = new (Ctx) NoDuplicateAttr(Loc, Ctx, 0); | |||
4838 | A->setImplicit(true); | |||
4839 | return A; | |||
4840 | } | |||
4841 | ||||
4842 | NoDuplicateAttr(SourceRange R, ASTContext &Ctx | |||
4843 | , unsigned SI | |||
4844 | ) | |||
4845 | : InheritableAttr(attr::NoDuplicate, R, SI, false, false) | |||
4846 | { | |||
4847 | } | |||
4848 | ||||
4849 | NoDuplicateAttr *clone(ASTContext &C) const; | |||
4850 | void printPretty(raw_ostream &OS, | |||
4851 | const PrintingPolicy &Policy) const; | |||
4852 | const char *getSpelling() const; | |||
4853 | ||||
4854 | ||||
4855 | static bool classof(const Attr *A) { return A->getKind() == attr::NoDuplicate; } | |||
4856 | }; | |||
4857 | ||||
4858 | class NoEscapeAttr : public Attr { | |||
4859 | public: | |||
4860 | static NoEscapeAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4861 | auto *A = new (Ctx) NoEscapeAttr(Loc, Ctx, 0); | |||
4862 | A->setImplicit(true); | |||
4863 | return A; | |||
4864 | } | |||
4865 | ||||
4866 | NoEscapeAttr(SourceRange R, ASTContext &Ctx | |||
4867 | , unsigned SI | |||
4868 | ) | |||
4869 | : Attr(attr::NoEscape, R, SI, false) | |||
4870 | { | |||
4871 | } | |||
4872 | ||||
4873 | NoEscapeAttr *clone(ASTContext &C) const; | |||
4874 | void printPretty(raw_ostream &OS, | |||
4875 | const PrintingPolicy &Policy) const; | |||
4876 | const char *getSpelling() const; | |||
4877 | ||||
4878 | ||||
4879 | static bool classof(const Attr *A) { return A->getKind() == attr::NoEscape; } | |||
4880 | }; | |||
4881 | ||||
4882 | class NoInlineAttr : public InheritableAttr { | |||
4883 | public: | |||
4884 | static NoInlineAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4885 | auto *A = new (Ctx) NoInlineAttr(Loc, Ctx, 0); | |||
4886 | A->setImplicit(true); | |||
4887 | return A; | |||
4888 | } | |||
4889 | ||||
4890 | NoInlineAttr(SourceRange R, ASTContext &Ctx | |||
4891 | , unsigned SI | |||
4892 | ) | |||
4893 | : InheritableAttr(attr::NoInline, R, SI, false, false) | |||
4894 | { | |||
4895 | } | |||
4896 | ||||
4897 | NoInlineAttr *clone(ASTContext &C) const; | |||
4898 | void printPretty(raw_ostream &OS, | |||
4899 | const PrintingPolicy &Policy) const; | |||
4900 | const char *getSpelling() const; | |||
4901 | ||||
4902 | ||||
4903 | static bool classof(const Attr *A) { return A->getKind() == attr::NoInline; } | |||
4904 | }; | |||
4905 | ||||
4906 | class NoInstrumentFunctionAttr : public InheritableAttr { | |||
4907 | public: | |||
4908 | static NoInstrumentFunctionAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4909 | auto *A = new (Ctx) NoInstrumentFunctionAttr(Loc, Ctx, 0); | |||
4910 | A->setImplicit(true); | |||
4911 | return A; | |||
4912 | } | |||
4913 | ||||
4914 | NoInstrumentFunctionAttr(SourceRange R, ASTContext &Ctx | |||
4915 | , unsigned SI | |||
4916 | ) | |||
4917 | : InheritableAttr(attr::NoInstrumentFunction, R, SI, false, false) | |||
4918 | { | |||
4919 | } | |||
4920 | ||||
4921 | NoInstrumentFunctionAttr *clone(ASTContext &C) const; | |||
4922 | void printPretty(raw_ostream &OS, | |||
4923 | const PrintingPolicy &Policy) const; | |||
4924 | const char *getSpelling() const; | |||
4925 | ||||
4926 | ||||
4927 | static bool classof(const Attr *A) { return A->getKind() == attr::NoInstrumentFunction; } | |||
4928 | }; | |||
4929 | ||||
4930 | class NoMicroMipsAttr : public InheritableAttr { | |||
4931 | public: | |||
4932 | static NoMicroMipsAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4933 | auto *A = new (Ctx) NoMicroMipsAttr(Loc, Ctx, 0); | |||
4934 | A->setImplicit(true); | |||
4935 | return A; | |||
4936 | } | |||
4937 | ||||
4938 | NoMicroMipsAttr(SourceRange R, ASTContext &Ctx | |||
4939 | , unsigned SI | |||
4940 | ) | |||
4941 | : InheritableAttr(attr::NoMicroMips, R, SI, false, false) | |||
4942 | { | |||
4943 | } | |||
4944 | ||||
4945 | NoMicroMipsAttr *clone(ASTContext &C) const; | |||
4946 | void printPretty(raw_ostream &OS, | |||
4947 | const PrintingPolicy &Policy) const; | |||
4948 | const char *getSpelling() const; | |||
4949 | ||||
4950 | ||||
4951 | static bool classof(const Attr *A) { return A->getKind() == attr::NoMicroMips; } | |||
4952 | }; | |||
4953 | ||||
4954 | class NoMips16Attr : public InheritableAttr { | |||
4955 | public: | |||
4956 | static NoMips16Attr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4957 | auto *A = new (Ctx) NoMips16Attr(Loc, Ctx, 0); | |||
4958 | A->setImplicit(true); | |||
4959 | return A; | |||
4960 | } | |||
4961 | ||||
4962 | NoMips16Attr(SourceRange R, ASTContext &Ctx | |||
4963 | , unsigned SI | |||
4964 | ) | |||
4965 | : InheritableAttr(attr::NoMips16, R, SI, false, false) | |||
4966 | { | |||
4967 | } | |||
4968 | ||||
4969 | NoMips16Attr *clone(ASTContext &C) const; | |||
4970 | void printPretty(raw_ostream &OS, | |||
4971 | const PrintingPolicy &Policy) const; | |||
4972 | const char *getSpelling() const; | |||
4973 | ||||
4974 | ||||
4975 | static bool classof(const Attr *A) { return A->getKind() == attr::NoMips16; } | |||
4976 | }; | |||
4977 | ||||
4978 | class NoReturnAttr : public InheritableAttr { | |||
4979 | public: | |||
4980 | static NoReturnAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
4981 | auto *A = new (Ctx) NoReturnAttr(Loc, Ctx, 0); | |||
4982 | A->setImplicit(true); | |||
4983 | return A; | |||
4984 | } | |||
4985 | ||||
4986 | NoReturnAttr(SourceRange R, ASTContext &Ctx | |||
4987 | , unsigned SI | |||
4988 | ) | |||
4989 | : InheritableAttr(attr::NoReturn, R, SI, false, false) | |||
4990 | { | |||
4991 | } | |||
4992 | ||||
4993 | NoReturnAttr *clone(ASTContext &C) const; | |||
4994 | void printPretty(raw_ostream &OS, | |||
4995 | const PrintingPolicy &Policy) const; | |||
4996 | const char *getSpelling() const; | |||
4997 | ||||
4998 | ||||
4999 | static bool classof(const Attr *A) { return A->getKind() == attr::NoReturn; } | |||
5000 | }; | |||
5001 | ||||
5002 | class NoSanitizeAttr : public InheritableAttr { | |||
5003 | unsigned sanitizers_Size; | |||
5004 | StringRef *sanitizers_; | |||
5005 | ||||
5006 | public: | |||
5007 | static NoSanitizeAttr *CreateImplicit(ASTContext &Ctx, StringRef *Sanitizers, unsigned SanitizersSize, SourceRange Loc = SourceRange()) { | |||
5008 | auto *A = new (Ctx) NoSanitizeAttr(Loc, Ctx, Sanitizers, SanitizersSize, 0); | |||
5009 | A->setImplicit(true); | |||
5010 | return A; | |||
5011 | } | |||
5012 | ||||
5013 | NoSanitizeAttr(SourceRange R, ASTContext &Ctx | |||
5014 | , StringRef *Sanitizers, unsigned SanitizersSize | |||
5015 | , unsigned SI | |||
5016 | ) | |||
5017 | : InheritableAttr(attr::NoSanitize, R, SI, false, false) | |||
5018 | , sanitizers_Size(SanitizersSize), sanitizers_(new (Ctx, 16) StringRef[sanitizers_Size]) | |||
5019 | { | |||
5020 | for (size_t I = 0, E = sanitizers_Size; I != E; | |||
5021 | ++I) { | |||
5022 | StringRef Ref = Sanitizers[I]; | |||
5023 | if (!Ref.empty()) { | |||
5024 | char *Mem = new (Ctx, 1) char[Ref.size()]; | |||
5025 | std::memcpy(Mem, Ref.data(), Ref.size()); | |||
5026 | sanitizers_[I] = StringRef(Mem, Ref.size()); | |||
5027 | } | |||
5028 | } | |||
5029 | } | |||
5030 | ||||
5031 | NoSanitizeAttr(SourceRange R, ASTContext &Ctx | |||
5032 | , unsigned SI | |||
5033 | ) | |||
5034 | : InheritableAttr(attr::NoSanitize, R, SI, false, false) | |||
5035 | , sanitizers_Size(0), sanitizers_(nullptr) | |||
5036 | { | |||
5037 | } | |||
5038 | ||||
5039 | NoSanitizeAttr *clone(ASTContext &C) const; | |||
5040 | void printPretty(raw_ostream &OS, | |||
5041 | const PrintingPolicy &Policy) const; | |||
5042 | const char *getSpelling() const; | |||
5043 | typedef StringRef* sanitizers_iterator; | |||
5044 | sanitizers_iterator sanitizers_begin() const { return sanitizers_; } | |||
5045 | sanitizers_iterator sanitizers_end() const { return sanitizers_ + sanitizers_Size; } | |||
5046 | unsigned sanitizers_size() const { return sanitizers_Size; } | |||
5047 | llvm::iterator_range<sanitizers_iterator> sanitizers() const { return llvm::make_range(sanitizers_begin(), sanitizers_end()); } | |||
5048 | ||||
5049 | ||||
5050 | ||||
5051 | SanitizerMask getMask() const { | |||
5052 | SanitizerMask Mask = 0; | |||
5053 | for (auto SanitizerName : sanitizers()) { | |||
5054 | SanitizerMask ParsedMask = | |||
5055 | parseSanitizerValue(SanitizerName, /*AllowGroups=*/true); | |||
5056 | Mask |= expandSanitizerGroups(ParsedMask); | |||
5057 | } | |||
5058 | return Mask; | |||
5059 | } | |||
5060 | ||||
5061 | ||||
5062 | static bool classof(const Attr *A) { return A->getKind() == attr::NoSanitize; } | |||
5063 | }; | |||
5064 | ||||
5065 | class NoSplitStackAttr : public InheritableAttr { | |||
5066 | public: | |||
5067 | static NoSplitStackAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
5068 | auto *A = new (Ctx) NoSplitStackAttr(Loc, Ctx, 0); | |||
5069 | A->setImplicit(true); | |||
5070 | return A; | |||
5071 | } | |||
5072 | ||||
5073 | NoSplitStackAttr(SourceRange R, ASTContext &Ctx | |||
5074 | , unsigned SI | |||
5075 | ) | |||
5076 | : InheritableAttr(attr::NoSplitStack, R, SI, false, false) | |||
5077 | { | |||
5078 | } | |||
5079 | ||||
5080 | NoSplitStackAttr *clone(ASTContext &C) const; | |||
5081 | void printPretty(raw_ostream &OS, | |||
5082 | const PrintingPolicy &Policy) const; | |||
5083 | const char *getSpelling() const; | |||
5084 | ||||
5085 | ||||
5086 | static bool classof(const Attr *A) { return A->getKind() == attr::NoSplitStack; } | |||
5087 | }; | |||
5088 | ||||
5089 | class NoStackProtectorAttr : public InheritableAttr { | |||
5090 | public: | |||
5091 | static NoStackProtectorAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
5092 | auto *A = new (Ctx) NoStackProtectorAttr(Loc, Ctx, 0); | |||
5093 | A->setImplicit(true); | |||
5094 | return A; | |||
5095 | } | |||
5096 | ||||
5097 | NoStackProtectorAttr(SourceRange R, ASTContext &Ctx | |||
5098 | , unsigned SI | |||
5099 | ) | |||
5100 | : InheritableAttr(attr::NoStackProtector, R, SI, false, false) | |||
5101 | { | |||
5102 | } | |||
5103 | ||||
5104 | NoStackProtectorAttr *clone(ASTContext &C) const; | |||
5105 | void printPretty(raw_ostream &OS, | |||
5106 | const PrintingPolicy &Policy) const; | |||
5107 | const char *getSpelling() const; | |||
5108 | ||||
5109 | ||||
5110 | static bool classof(const Attr *A) { return A->getKind() == attr::NoStackProtector; } | |||
5111 | }; | |||
5112 | ||||
5113 | class NoThreadSafetyAnalysisAttr : public InheritableAttr { | |||
5114 | public: | |||
5115 | static NoThreadSafetyAnalysisAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
5116 | auto *A = new (Ctx) NoThreadSafetyAnalysisAttr(Loc, Ctx, 0); | |||
5117 | A->setImplicit(true); | |||
5118 | return A; | |||
5119 | } | |||
5120 | ||||
5121 | NoThreadSafetyAnalysisAttr(SourceRange R, ASTContext &Ctx | |||
5122 | , unsigned SI | |||
5123 | ) | |||
5124 | : InheritableAttr(attr::NoThreadSafetyAnalysis, R, SI, false, false) | |||
5125 | { | |||
5126 | } | |||
5127 | ||||
5128 | NoThreadSafetyAnalysisAttr *clone(ASTContext &C) const; | |||
5129 | void printPretty(raw_ostream &OS, | |||
5130 | const PrintingPolicy &Policy) const; | |||
5131 | const char *getSpelling() const; | |||
5132 | ||||
5133 | ||||
5134 | static bool classof(const Attr *A) { return A->getKind() == attr::NoThreadSafetyAnalysis; } | |||
5135 | }; | |||
5136 | ||||
5137 | class NoThrowAttr : public InheritableAttr { | |||
5138 | public: | |||
5139 | static NoThrowAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
5140 | auto *A = new (Ctx) NoThrowAttr(Loc, Ctx, 0); | |||
5141 | A->setImplicit(true); | |||
5142 | return A; | |||
5143 | } | |||
5144 | ||||
5145 | NoThrowAttr(SourceRange R, ASTContext &Ctx | |||
5146 | , unsigned SI | |||
5147 | ) | |||
5148 | : InheritableAttr(attr::NoThrow, R, SI, false, false) | |||
5149 | { | |||
5150 | } | |||
5151 | ||||
5152 | NoThrowAttr *clone(ASTContext &C) const; | |||
5153 | void printPretty(raw_ostream &OS, | |||
5154 | const PrintingPolicy &Policy) const; | |||
5155 | const char *getSpelling() const; | |||
5156 | ||||
5157 | ||||
5158 | static bool classof(const Attr *A) { return A->getKind() == attr::NoThrow; } | |||
5159 | }; | |||
5160 | ||||
5161 | class NonNullAttr : public InheritableParamAttr { | |||
5162 | unsigned args_Size; | |||
5163 | ParamIdx *args_; | |||
5164 | ||||
5165 | public: | |||
5166 | static NonNullAttr *CreateImplicit(ASTContext &Ctx, ParamIdx *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) { | |||
5167 | auto *A = new (Ctx) NonNullAttr(Loc, Ctx, Args, ArgsSize, 0); | |||
5168 | A->setImplicit(true); | |||
5169 | return A; | |||
5170 | } | |||
5171 | ||||
5172 | NonNullAttr(SourceRange R, ASTContext &Ctx | |||
5173 | , ParamIdx *Args, unsigned ArgsSize | |||
5174 | , unsigned SI | |||
5175 | ) | |||
5176 | : InheritableParamAttr(attr::NonNull, R, SI, false, true) | |||
5177 | , args_Size(ArgsSize), args_(new (Ctx, 16) ParamIdx[args_Size]) | |||
5178 | { | |||
5179 | std::copy(Args, Args + args_Size, args_); | |||
5180 | } | |||
5181 | ||||
5182 | NonNullAttr(SourceRange R, ASTContext &Ctx | |||
5183 | , unsigned SI | |||
5184 | ) | |||
5185 | : InheritableParamAttr(attr::NonNull, R, SI, false, true) | |||
5186 | , args_Size(0), args_(nullptr) | |||
5187 | { | |||
5188 | } | |||
5189 | ||||
5190 | NonNullAttr *clone(ASTContext &C) const; | |||
5191 | void printPretty(raw_ostream &OS, | |||
5192 | const PrintingPolicy &Policy) const; | |||
5193 | const char *getSpelling() const; | |||
5194 | typedef ParamIdx* args_iterator; | |||
5195 | args_iterator args_begin() const { return args_; } | |||
5196 | args_iterator args_end() const { return args_ + args_Size; } | |||
5197 | unsigned args_size() const { return args_Size; } | |||
5198 | llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); } | |||
5199 | ||||
5200 | ||||
5201 | ||||
5202 | bool isNonNull(unsigned IdxAST) const { | |||
5203 | if (!args_size()) | |||
5204 | return true; | |||
5205 | return args_end() != std::find_if( | |||
5206 | args_begin(), args_end(), | |||
5207 | [=](const ParamIdx &Idx) { return Idx.getASTIndex() == IdxAST; }); | |||
5208 | } | |||
5209 | ||||
5210 | ||||
5211 | static bool classof(const Attr *A) { return A->getKind() == attr::NonNull; } | |||
5212 | }; | |||
5213 | ||||
5214 | class NotTailCalledAttr : public InheritableAttr { | |||
5215 | public: | |||
5216 | static NotTailCalledAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
5217 | auto *A = new (Ctx) NotTailCalledAttr(Loc, Ctx, 0); | |||
5218 | A->setImplicit(true); | |||
5219 | return A; | |||
5220 | } | |||
5221 | ||||
5222 | NotTailCalledAttr(SourceRange R, ASTContext &Ctx | |||
5223 | , unsigned SI | |||
5224 | ) | |||
5225 | : InheritableAttr(attr::NotTailCalled, R, SI, false, false) | |||
5226 | { | |||
5227 | } | |||
5228 | ||||
5229 | NotTailCalledAttr *clone(ASTContext &C) const; | |||
5230 | void printPretty(raw_ostream &OS, | |||
5231 | const PrintingPolicy &Policy) const; | |||
5232 | const char *getSpelling() const; | |||
5233 | ||||
5234 | ||||
5235 | static bool classof(const Attr *A) { return A->getKind() == attr::NotTailCalled; } | |||
5236 | }; | |||
5237 | ||||
5238 | class OMPCaptureKindAttr : public Attr { | |||
5239 | unsigned captureKind; | |||
5240 | ||||
5241 | public: | |||
5242 | static OMPCaptureKindAttr *CreateImplicit(ASTContext &Ctx, unsigned CaptureKind, SourceRange Loc = SourceRange()) { | |||
5243 | auto *A = new (Ctx) OMPCaptureKindAttr(Loc, Ctx, CaptureKind, 0); | |||
5244 | A->setImplicit(true); | |||
5245 | return A; | |||
5246 | } | |||
5247 | ||||
5248 | OMPCaptureKindAttr(SourceRange R, ASTContext &Ctx | |||
5249 | , unsigned CaptureKind | |||
5250 | , unsigned SI | |||
5251 | ) | |||
5252 | : Attr(attr::OMPCaptureKind, R, SI, false) | |||
5253 | , captureKind(CaptureKind) | |||
5254 | { | |||
5255 | } | |||
5256 | ||||
5257 | OMPCaptureKindAttr *clone(ASTContext &C) const; | |||
5258 | void printPretty(raw_ostream &OS, | |||
5259 | const PrintingPolicy &Policy) const; | |||
5260 | const char *getSpelling() const; | |||
5261 | unsigned getCaptureKind() const { | |||
5262 | return captureKind; | |||
5263 | } | |||
5264 | ||||
5265 | ||||
5266 | ||||
5267 | static bool classof(const Attr *A) { return A->getKind() == attr::OMPCaptureKind; } | |||
5268 | }; | |||
5269 | ||||
5270 | class OMPCaptureNoInitAttr : public InheritableAttr { | |||
5271 | public: | |||
5272 | static OMPCaptureNoInitAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
5273 | auto *A = new (Ctx) OMPCaptureNoInitAttr(Loc, Ctx, 0); | |||
5274 | A->setImplicit(true); | |||
5275 | return A; | |||
5276 | } | |||
5277 | ||||
5278 | OMPCaptureNoInitAttr(SourceRange R, ASTContext &Ctx | |||
5279 | , unsigned SI | |||
5280 | ) | |||
5281 | : InheritableAttr(attr::OMPCaptureNoInit, R, SI, false, false) | |||
5282 | { | |||
5283 | } | |||
5284 | ||||
5285 | OMPCaptureNoInitAttr *clone(ASTContext &C) const; | |||
5286 | void printPretty(raw_ostream &OS, | |||
5287 | const PrintingPolicy &Policy) const; | |||
5288 | const char *getSpelling() const; | |||
5289 | ||||
5290 | ||||
5291 | static bool classof(const Attr *A) { return A->getKind() == attr::OMPCaptureNoInit; } | |||
5292 | }; | |||
5293 | ||||
5294 | class OMPDeclareSimdDeclAttr : public Attr { | |||
5295 | public: | |||
5296 | enum BranchStateTy { | |||
5297 | BS_Undefined, | |||
5298 | BS_Inbranch, | |||
5299 | BS_Notinbranch | |||
5300 | }; | |||
5301 | private: | |||
5302 | BranchStateTy branchState; | |||
5303 | ||||
5304 | Expr * simdlen; | |||
5305 | ||||
5306 | unsigned uniforms_Size; | |||
5307 | Expr * *uniforms_; | |||
5308 | ||||
5309 | unsigned aligneds_Size; | |||
5310 | Expr * *aligneds_; | |||
5311 | ||||
5312 | unsigned alignments_Size; | |||
5313 | Expr * *alignments_; | |||
5314 | ||||
5315 | unsigned linears_Size; | |||
5316 | Expr * *linears_; | |||
5317 | ||||
5318 | unsigned modifiers_Size; | |||
5319 | unsigned *modifiers_; | |||
5320 | ||||
5321 | unsigned steps_Size; | |||
5322 | Expr * *steps_; | |||
5323 | ||||
5324 | public: | |||
5325 | static OMPDeclareSimdDeclAttr *CreateImplicit(ASTContext &Ctx, BranchStateTy BranchState, Expr * Simdlen, Expr * *Uniforms, unsigned UniformsSize, Expr * *Aligneds, unsigned AlignedsSize, Expr * *Alignments, unsigned AlignmentsSize, Expr * *Linears, unsigned LinearsSize, unsigned *Modifiers, unsigned ModifiersSize, Expr * *Steps, unsigned StepsSize, SourceRange Loc = SourceRange()) { | |||
5326 | auto *A = new (Ctx) OMPDeclareSimdDeclAttr(Loc, Ctx, BranchState, Simdlen, Uniforms, UniformsSize, Aligneds, AlignedsSize, Alignments, AlignmentsSize, Linears, LinearsSize, Modifiers, ModifiersSize, Steps, StepsSize, 0); | |||
5327 | A->setImplicit(true); | |||
5328 | return A; | |||
5329 | } | |||
5330 | ||||
5331 | OMPDeclareSimdDeclAttr(SourceRange R, ASTContext &Ctx | |||
5332 | , BranchStateTy BranchState | |||
5333 | , Expr * Simdlen | |||
5334 | , Expr * *Uniforms, unsigned UniformsSize | |||
5335 | , Expr * *Aligneds, unsigned AlignedsSize | |||
5336 | , Expr * *Alignments, unsigned AlignmentsSize | |||
5337 | , Expr * *Linears, unsigned LinearsSize | |||
5338 | , unsigned *Modifiers, unsigned ModifiersSize | |||
5339 | , Expr * *Steps, unsigned StepsSize | |||
5340 | , unsigned SI | |||
5341 | ) | |||
5342 | : Attr(attr::OMPDeclareSimdDecl, R, SI, false) | |||
5343 | , branchState(BranchState) | |||
5344 | , simdlen(Simdlen) | |||
5345 | , uniforms_Size(UniformsSize), uniforms_(new (Ctx, 16) Expr *[uniforms_Size]) | |||
5346 | , aligneds_Size(AlignedsSize), aligneds_(new (Ctx, 16) Expr *[aligneds_Size]) | |||
5347 | , alignments_Size(AlignmentsSize), alignments_(new (Ctx, 16) Expr *[alignments_Size]) | |||
5348 | , linears_Size(LinearsSize), linears_(new (Ctx, 16) Expr *[linears_Size]) | |||
5349 | , modifiers_Size(ModifiersSize), modifiers_(new (Ctx, 16) unsigned[modifiers_Size]) | |||
5350 | , steps_Size(StepsSize), steps_(new (Ctx, 16) Expr *[steps_Size]) | |||
5351 | { | |||
5352 | std::copy(Uniforms, Uniforms + uniforms_Size, uniforms_); | |||
5353 | std::copy(Aligneds, Aligneds + aligneds_Size, aligneds_); | |||
5354 | std::copy(Alignments, Alignments + alignments_Size, alignments_); | |||
5355 | std::copy(Linears, Linears + linears_Size, linears_); | |||
5356 | std::copy(Modifiers, Modifiers + modifiers_Size, modifiers_); | |||
5357 | std::copy(Steps, Steps + steps_Size, steps_); | |||
5358 | } | |||
5359 | ||||
5360 | OMPDeclareSimdDeclAttr(SourceRange R, ASTContext &Ctx | |||
5361 | , BranchStateTy BranchState | |||
5362 | , Expr * Simdlen | |||
5363 | , unsigned SI | |||
5364 | ) | |||
5365 | : Attr(attr::OMPDeclareSimdDecl, R, SI, false) | |||
5366 | , branchState(BranchState) | |||
5367 | , simdlen(Simdlen) | |||
5368 | , uniforms_Size(0), uniforms_(nullptr) | |||
5369 | , aligneds_Size(0), aligneds_(nullptr) | |||
5370 | , alignments_Size(0), alignments_(nullptr) | |||
5371 | , linears_Size(0), linears_(nullptr) | |||
5372 | , modifiers_Size(0), modifiers_(nullptr) | |||
5373 | , steps_Size(0), steps_(nullptr) | |||
5374 | { | |||
5375 | } | |||
5376 | ||||
5377 | OMPDeclareSimdDeclAttr *clone(ASTContext &C) const; | |||
5378 | void printPretty(raw_ostream &OS, | |||
5379 | const PrintingPolicy &Policy) const; | |||
5380 | const char *getSpelling() const; | |||
5381 | BranchStateTy getBranchState() const { | |||
5382 | return branchState; | |||
5383 | } | |||
5384 | ||||
5385 | static bool ConvertStrToBranchStateTy(StringRef Val, BranchStateTy &Out) { | |||
5386 | Optional<BranchStateTy> R = llvm::StringSwitch<Optional<BranchStateTy>>(Val) | |||
5387 | .Case("", OMPDeclareSimdDeclAttr::BS_Undefined) | |||
5388 | .Case("inbranch", OMPDeclareSimdDeclAttr::BS_Inbranch) | |||
5389 | .Case("notinbranch", OMPDeclareSimdDeclAttr::BS_Notinbranch) | |||
5390 | .Default(Optional<BranchStateTy>()); | |||
5391 | if (R) { | |||
5392 | Out = *R; | |||
5393 | return true; | |||
5394 | } | |||
5395 | return false; | |||
5396 | } | |||
5397 | ||||
5398 | static const char *ConvertBranchStateTyToStr(BranchStateTy Val) { | |||
5399 | switch(Val) { | |||
5400 | case OMPDeclareSimdDeclAttr::BS_Undefined: return ""; | |||
5401 | case OMPDeclareSimdDeclAttr::BS_Inbranch: return "inbranch"; | |||
5402 | case OMPDeclareSimdDeclAttr::BS_Notinbranch: return "notinbranch"; | |||
5403 | } | |||
5404 | llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 5404); | |||
5405 | } | |||
5406 | Expr * getSimdlen() const { | |||
5407 | return simdlen; | |||
5408 | } | |||
5409 | ||||
5410 | typedef Expr ** uniforms_iterator; | |||
5411 | uniforms_iterator uniforms_begin() const { return uniforms_; } | |||
5412 | uniforms_iterator uniforms_end() const { return uniforms_ + uniforms_Size; } | |||
5413 | unsigned uniforms_size() const { return uniforms_Size; } | |||
5414 | llvm::iterator_range<uniforms_iterator> uniforms() const { return llvm::make_range(uniforms_begin(), uniforms_end()); } | |||
5415 | ||||
5416 | ||||
5417 | typedef Expr ** aligneds_iterator; | |||
5418 | aligneds_iterator aligneds_begin() const { return aligneds_; } | |||
5419 | aligneds_iterator aligneds_end() const { return aligneds_ + aligneds_Size; } | |||
5420 | unsigned aligneds_size() const { return aligneds_Size; } | |||
5421 | llvm::iterator_range<aligneds_iterator> aligneds() const { return llvm::make_range(aligneds_begin(), aligneds_end()); } | |||
5422 | ||||
5423 | ||||
5424 | typedef Expr ** alignments_iterator; | |||
5425 | alignments_iterator alignments_begin() const { return alignments_; } | |||
5426 | alignments_iterator alignments_end() const { return alignments_ + alignments_Size; } | |||
5427 | unsigned alignments_size() const { return alignments_Size; } | |||
5428 | llvm::iterator_range<alignments_iterator> alignments() const { return llvm::make_range(alignments_begin(), alignments_end()); } | |||
5429 | ||||
5430 | ||||
5431 | typedef Expr ** linears_iterator; | |||
5432 | linears_iterator linears_begin() const { return linears_; } | |||
5433 | linears_iterator linears_end() const { return linears_ + linears_Size; } | |||
5434 | unsigned linears_size() const { return linears_Size; } | |||
5435 | llvm::iterator_range<linears_iterator> linears() const { return llvm::make_range(linears_begin(), linears_end()); } | |||
5436 | ||||
5437 | ||||
5438 | typedef unsigned* modifiers_iterator; | |||
5439 | modifiers_iterator modifiers_begin() const { return modifiers_; } | |||
5440 | modifiers_iterator modifiers_end() const { return modifiers_ + modifiers_Size; } | |||
5441 | unsigned modifiers_size() const { return modifiers_Size; } | |||
5442 | llvm::iterator_range<modifiers_iterator> modifiers() const { return llvm::make_range(modifiers_begin(), modifiers_end()); } | |||
5443 | ||||
5444 | ||||
5445 | typedef Expr ** steps_iterator; | |||
5446 | steps_iterator steps_begin() const { return steps_; } | |||
5447 | steps_iterator steps_end() const { return steps_ + steps_Size; } | |||
5448 | unsigned steps_size() const { return steps_Size; } | |||
5449 | llvm::iterator_range<steps_iterator> steps() const { return llvm::make_range(steps_begin(), steps_end()); } | |||
5450 | ||||
5451 | ||||
5452 | ||||
5453 | void printPrettyPragma(raw_ostream & OS, const PrintingPolicy &Policy) | |||
5454 | const { | |||
5455 | if (getBranchState() != BS_Undefined) | |||
5456 | OS << ' ' << ConvertBranchStateTyToStr(getBranchState()); | |||
5457 | if (auto *E = getSimdlen()) { | |||
5458 | OS << " simdlen("; | |||
5459 | E->printPretty(OS, nullptr, Policy); | |||
5460 | OS << ")"; | |||
5461 | } | |||
5462 | if (uniforms_size() > 0) { | |||
5463 | OS << " uniform"; | |||
5464 | StringRef Sep = "("; | |||
5465 | for (auto *E : uniforms()) { | |||
5466 | OS << Sep; | |||
5467 | E->printPretty(OS, nullptr, Policy); | |||
5468 | Sep = ", "; | |||
5469 | } | |||
5470 | OS << ")"; | |||
5471 | } | |||
5472 | alignments_iterator NI = alignments_begin(); | |||
5473 | for (auto *E : aligneds()) { | |||
5474 | OS << " aligned("; | |||
5475 | E->printPretty(OS, nullptr, Policy); | |||
5476 | if (*NI) { | |||
5477 | OS << ": "; | |||
5478 | (*NI)->printPretty(OS, nullptr, Policy); | |||
5479 | } | |||
5480 | OS << ")"; | |||
5481 | ++NI; | |||
5482 | } | |||
5483 | steps_iterator I = steps_begin(); | |||
5484 | modifiers_iterator MI = modifiers_begin(); | |||
5485 | for (auto *E : linears()) { | |||
5486 | OS << " linear("; | |||
5487 | if (*MI != OMPC_LINEAR_unknown) | |||
5488 | OS << getOpenMPSimpleClauseTypeName(OMPC_linear, *MI) << "("; | |||
5489 | E->printPretty(OS, nullptr, Policy); | |||
5490 | if (*MI != OMPC_LINEAR_unknown) | |||
5491 | OS << ")"; | |||
5492 | if (*I) { | |||
5493 | OS << ": "; | |||
5494 | (*I)->printPretty(OS, nullptr, Policy); | |||
5495 | } | |||
5496 | OS << ")"; | |||
5497 | ++I; | |||
5498 | ++MI; | |||
5499 | } | |||
5500 | } | |||
5501 | ||||
5502 | ||||
5503 | static bool classof(const Attr *A) { return A->getKind() == attr::OMPDeclareSimdDecl; } | |||
5504 | }; | |||
5505 | ||||
5506 | class OMPDeclareTargetDeclAttr : public Attr { | |||
5507 | public: | |||
5508 | enum MapTypeTy { | |||
5509 | MT_To, | |||
5510 | MT_Link | |||
5511 | }; | |||
5512 | private: | |||
5513 | MapTypeTy mapType; | |||
5514 | ||||
5515 | public: | |||
5516 | static OMPDeclareTargetDeclAttr *CreateImplicit(ASTContext &Ctx, MapTypeTy MapType, SourceRange Loc = SourceRange()) { | |||
5517 | auto *A = new (Ctx) OMPDeclareTargetDeclAttr(Loc, Ctx, MapType, 0); | |||
5518 | A->setImplicit(true); | |||
5519 | return A; | |||
5520 | } | |||
5521 | ||||
5522 | OMPDeclareTargetDeclAttr(SourceRange R, ASTContext &Ctx | |||
5523 | , MapTypeTy MapType | |||
5524 | , unsigned SI | |||
5525 | ) | |||
5526 | : Attr(attr::OMPDeclareTargetDecl, R, SI, false) | |||
5527 | , mapType(MapType) | |||
5528 | { | |||
5529 | } | |||
5530 | ||||
5531 | OMPDeclareTargetDeclAttr *clone(ASTContext &C) const; | |||
5532 | void printPretty(raw_ostream &OS, | |||
5533 | const PrintingPolicy &Policy) const; | |||
5534 | const char *getSpelling() const; | |||
5535 | MapTypeTy getMapType() const { | |||
5536 | return mapType; | |||
5537 | } | |||
5538 | ||||
5539 | static bool ConvertStrToMapTypeTy(StringRef Val, MapTypeTy &Out) { | |||
5540 | Optional<MapTypeTy> R = llvm::StringSwitch<Optional<MapTypeTy>>(Val) | |||
5541 | .Case("to", OMPDeclareTargetDeclAttr::MT_To) | |||
5542 | .Case("link", OMPDeclareTargetDeclAttr::MT_Link) | |||
5543 | .Default(Optional<MapTypeTy>()); | |||
5544 | if (R) { | |||
5545 | Out = *R; | |||
5546 | return true; | |||
5547 | } | |||
5548 | return false; | |||
5549 | } | |||
5550 | ||||
5551 | static const char *ConvertMapTypeTyToStr(MapTypeTy Val) { | |||
5552 | switch(Val) { | |||
5553 | case OMPDeclareTargetDeclAttr::MT_To: return "to"; | |||
5554 | case OMPDeclareTargetDeclAttr::MT_Link: return "link"; | |||
5555 | } | |||
5556 | llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 5556); | |||
5557 | } | |||
5558 | ||||
5559 | void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const { | |||
5560 | // Use fake syntax because it is for testing and debugging purpose only. | |||
5561 | if (getMapType() != MT_To) | |||
5562 | OS << ' ' << ConvertMapTypeTyToStr(getMapType()); | |||
5563 | } | |||
5564 | ||||
5565 | ||||
5566 | static bool classof(const Attr *A) { return A->getKind() == attr::OMPDeclareTargetDecl; } | |||
5567 | }; | |||
5568 | ||||
5569 | class OMPReferencedVarAttr : public Attr { | |||
5570 | Expr * ref; | |||
5571 | ||||
5572 | public: | |||
5573 | static OMPReferencedVarAttr *CreateImplicit(ASTContext &Ctx, Expr * Ref, SourceRange Loc = SourceRange()) { | |||
5574 | auto *A = new (Ctx) OMPReferencedVarAttr(Loc, Ctx, Ref, 0); | |||
5575 | A->setImplicit(true); | |||
5576 | return A; | |||
5577 | } | |||
5578 | ||||
5579 | OMPReferencedVarAttr(SourceRange R, ASTContext &Ctx | |||
5580 | , Expr * Ref | |||
5581 | , unsigned SI | |||
5582 | ) | |||
5583 | : Attr(attr::OMPReferencedVar, R, SI, false) | |||
5584 | , ref(Ref) | |||
5585 | { | |||
5586 | } | |||
5587 | ||||
5588 | OMPReferencedVarAttr *clone(ASTContext &C) const; | |||
5589 | void printPretty(raw_ostream &OS, | |||
5590 | const PrintingPolicy &Policy) const; | |||
5591 | const char *getSpelling() const; | |||
5592 | Expr * getRef() const { | |||
5593 | return ref; | |||
5594 | } | |||
5595 | ||||
5596 | ||||
5597 | ||||
5598 | static bool classof(const Attr *A) { return A->getKind() == attr::OMPReferencedVar; } | |||
5599 | }; | |||
5600 | ||||
5601 | class OMPThreadPrivateDeclAttr : public InheritableAttr { | |||
5602 | public: | |||
5603 | static OMPThreadPrivateDeclAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
5604 | auto *A = new (Ctx) OMPThreadPrivateDeclAttr(Loc, Ctx, 0); | |||
5605 | A->setImplicit(true); | |||
5606 | return A; | |||
5607 | } | |||
5608 | ||||
5609 | OMPThreadPrivateDeclAttr(SourceRange R, ASTContext &Ctx | |||
5610 | , unsigned SI | |||
5611 | ) | |||
5612 | : InheritableAttr(attr::OMPThreadPrivateDecl, R, SI, false, false) | |||
5613 | { | |||
5614 | } | |||
5615 | ||||
5616 | OMPThreadPrivateDeclAttr *clone(ASTContext &C) const; | |||
5617 | void printPretty(raw_ostream &OS, | |||
5618 | const PrintingPolicy &Policy) const; | |||
5619 | const char *getSpelling() const; | |||
5620 | ||||
5621 | ||||
5622 | static bool classof(const Attr *A) { return A->getKind() == attr::OMPThreadPrivateDecl; } | |||
5623 | }; | |||
5624 | ||||
5625 | class ObjCBoxableAttr : public Attr { | |||
5626 | public: | |||
5627 | static ObjCBoxableAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
5628 | auto *A = new (Ctx) ObjCBoxableAttr(Loc, Ctx, 0); | |||
5629 | A->setImplicit(true); | |||
5630 | return A; | |||
5631 | } | |||
5632 | ||||
5633 | ObjCBoxableAttr(SourceRange R, ASTContext &Ctx | |||
5634 | , unsigned SI | |||
5635 | ) | |||
5636 | : Attr(attr::ObjCBoxable, R, SI, false) | |||
5637 | { | |||
5638 | } | |||
5639 | ||||
5640 | ObjCBoxableAttr *clone(ASTContext &C) const; | |||
5641 | void printPretty(raw_ostream &OS, | |||
5642 | const PrintingPolicy &Policy) const; | |||
5643 | const char *getSpelling() const; | |||
5644 | ||||
5645 | ||||
5646 | static bool classof(const Attr *A) { return A->getKind() == attr::ObjCBoxable; } | |||
5647 | }; | |||
5648 | ||||
5649 | class ObjCBridgeAttr : public InheritableAttr { | |||
5650 | IdentifierInfo * bridgedType; | |||
5651 | ||||
5652 | public: | |||
5653 | static ObjCBridgeAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * BridgedType, SourceRange Loc = SourceRange()) { | |||
5654 | auto *A = new (Ctx) ObjCBridgeAttr(Loc, Ctx, BridgedType, 0); | |||
5655 | A->setImplicit(true); | |||
5656 | return A; | |||
5657 | } | |||
5658 | ||||
5659 | ObjCBridgeAttr(SourceRange R, ASTContext &Ctx | |||
5660 | , IdentifierInfo * BridgedType | |||
5661 | , unsigned SI | |||
5662 | ) | |||
5663 | : InheritableAttr(attr::ObjCBridge, R, SI, false, false) | |||
5664 | , bridgedType(BridgedType) | |||
5665 | { | |||
5666 | } | |||
5667 | ||||
5668 | ObjCBridgeAttr *clone(ASTContext &C) const; | |||
5669 | void printPretty(raw_ostream &OS, | |||
5670 | const PrintingPolicy &Policy) const; | |||
5671 | const char *getSpelling() const; | |||
5672 | IdentifierInfo * getBridgedType() const { | |||
5673 | return bridgedType; | |||
5674 | } | |||
5675 | ||||
5676 | ||||
5677 | ||||
5678 | static bool classof(const Attr *A) { return A->getKind() == attr::ObjCBridge; } | |||
5679 | }; | |||
5680 | ||||
5681 | class ObjCBridgeMutableAttr : public InheritableAttr { | |||
5682 | IdentifierInfo * bridgedType; | |||
5683 | ||||
5684 | public: | |||
5685 | static ObjCBridgeMutableAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * BridgedType, SourceRange Loc = SourceRange()) { | |||
5686 | auto *A = new (Ctx) ObjCBridgeMutableAttr(Loc, Ctx, BridgedType, 0); | |||
5687 | A->setImplicit(true); | |||
5688 | return A; | |||
5689 | } | |||
5690 | ||||
5691 | ObjCBridgeMutableAttr(SourceRange R, ASTContext &Ctx | |||
5692 | , IdentifierInfo * BridgedType | |||
5693 | , unsigned SI | |||
5694 | ) | |||
5695 | : InheritableAttr(attr::ObjCBridgeMutable, R, SI, false, false) | |||
5696 | , bridgedType(BridgedType) | |||
5697 | { | |||
5698 | } | |||
5699 | ||||
5700 | ObjCBridgeMutableAttr *clone(ASTContext &C) const; | |||
5701 | void printPretty(raw_ostream &OS, | |||
5702 | const PrintingPolicy &Policy) const; | |||
5703 | const char *getSpelling() const; | |||
5704 | IdentifierInfo * getBridgedType() const { | |||
5705 | return bridgedType; | |||
5706 | } | |||
5707 | ||||
5708 | ||||
5709 | ||||
5710 | static bool classof(const Attr *A) { return A->getKind() == attr::ObjCBridgeMutable; } | |||
5711 | }; | |||
5712 | ||||
5713 | class ObjCBridgeRelatedAttr : public InheritableAttr { | |||
5714 | IdentifierInfo * relatedClass; | |||
5715 | ||||
5716 | IdentifierInfo * classMethod; | |||
5717 | ||||
5718 | IdentifierInfo * instanceMethod; | |||
5719 | ||||
5720 | public: | |||
5721 | static ObjCBridgeRelatedAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * RelatedClass, IdentifierInfo * ClassMethod, IdentifierInfo * InstanceMethod, SourceRange Loc = SourceRange()) { | |||
5722 | auto *A = new (Ctx) ObjCBridgeRelatedAttr(Loc, Ctx, RelatedClass, ClassMethod, InstanceMethod, 0); | |||
5723 | A->setImplicit(true); | |||
5724 | return A; | |||
5725 | } | |||
5726 | ||||
5727 | ObjCBridgeRelatedAttr(SourceRange R, ASTContext &Ctx | |||
5728 | , IdentifierInfo * RelatedClass | |||
5729 | , IdentifierInfo * ClassMethod | |||
5730 | , IdentifierInfo * InstanceMethod | |||
5731 | , unsigned SI | |||
5732 | ) | |||
5733 | : InheritableAttr(attr::ObjCBridgeRelated, R, SI, false, false) | |||
5734 | , relatedClass(RelatedClass) | |||
5735 | , classMethod(ClassMethod) | |||
5736 | , instanceMethod(InstanceMethod) | |||
5737 | { | |||
5738 | } | |||
5739 | ||||
5740 | ObjCBridgeRelatedAttr *clone(ASTContext &C) const; | |||
5741 | void printPretty(raw_ostream &OS, | |||
5742 | const PrintingPolicy &Policy) const; | |||
5743 | const char *getSpelling() const; | |||
5744 | IdentifierInfo * getRelatedClass() const { | |||
5745 | return relatedClass; | |||
5746 | } | |||
5747 | ||||
5748 | IdentifierInfo * getClassMethod() const { | |||
5749 | return classMethod; | |||
5750 | } | |||
5751 | ||||
5752 | IdentifierInfo * getInstanceMethod() const { | |||
5753 | return instanceMethod; | |||
5754 | } | |||
5755 | ||||
5756 | ||||
5757 | ||||
5758 | static bool classof(const Attr *A) { return A->getKind() == attr::ObjCBridgeRelated; } | |||
5759 | }; | |||
5760 | ||||
5761 | class ObjCDesignatedInitializerAttr : public Attr { | |||
5762 | public: | |||
5763 | static ObjCDesignatedInitializerAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
5764 | auto *A = new (Ctx) ObjCDesignatedInitializerAttr(Loc, Ctx, 0); | |||
5765 | A->setImplicit(true); | |||
5766 | return A; | |||
5767 | } | |||
5768 | ||||
5769 | ObjCDesignatedInitializerAttr(SourceRange R, ASTContext &Ctx | |||
5770 | , unsigned SI | |||
5771 | ) | |||
5772 | : Attr(attr::ObjCDesignatedInitializer, R, SI, false) | |||
5773 | { | |||
5774 | } | |||
5775 | ||||
5776 | ObjCDesignatedInitializerAttr *clone(ASTContext &C) const; | |||
5777 | void printPretty(raw_ostream &OS, | |||
5778 | const PrintingPolicy &Policy) const; | |||
5779 | const char *getSpelling() const; | |||
5780 | ||||
5781 | ||||
5782 | static bool classof(const Attr *A) { return A->getKind() == attr::ObjCDesignatedInitializer; } | |||
5783 | }; | |||
5784 | ||||
5785 | class ObjCExceptionAttr : public InheritableAttr { | |||
5786 | public: | |||
5787 | static ObjCExceptionAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
5788 | auto *A = new (Ctx) ObjCExceptionAttr(Loc, Ctx, 0); | |||
5789 | A->setImplicit(true); | |||
5790 | return A; | |||
5791 | } | |||
5792 | ||||
5793 | ObjCExceptionAttr(SourceRange R, ASTContext &Ctx | |||
5794 | , unsigned SI | |||
5795 | ) | |||
5796 | : InheritableAttr(attr::ObjCException, R, SI, false, false) | |||
5797 | { | |||
5798 | } | |||
5799 | ||||
5800 | ObjCExceptionAttr *clone(ASTContext &C) const; | |||
5801 | void printPretty(raw_ostream &OS, | |||
5802 | const PrintingPolicy &Policy) const; | |||
5803 | const char *getSpelling() const; | |||
5804 | ||||
5805 | ||||
5806 | static bool classof(const Attr *A) { return A->getKind() == attr::ObjCException; } | |||
5807 | }; | |||
5808 | ||||
5809 | class ObjCExplicitProtocolImplAttr : public InheritableAttr { | |||
5810 | public: | |||
5811 | static ObjCExplicitProtocolImplAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
5812 | auto *A = new (Ctx) ObjCExplicitProtocolImplAttr(Loc, Ctx, 0); | |||
5813 | A->setImplicit(true); | |||
5814 | return A; | |||
5815 | } | |||
5816 | ||||
5817 | ObjCExplicitProtocolImplAttr(SourceRange R, ASTContext &Ctx | |||
5818 | , unsigned SI | |||
5819 | ) | |||
5820 | : InheritableAttr(attr::ObjCExplicitProtocolImpl, R, SI, false, false) | |||
5821 | { | |||
5822 | } | |||
5823 | ||||
5824 | ObjCExplicitProtocolImplAttr *clone(ASTContext &C) const; | |||
5825 | void printPretty(raw_ostream &OS, | |||
5826 | const PrintingPolicy &Policy) const; | |||
5827 | const char *getSpelling() const; | |||
5828 | ||||
5829 | ||||
5830 | static bool classof(const Attr *A) { return A->getKind() == attr::ObjCExplicitProtocolImpl; } | |||
5831 | }; | |||
5832 | ||||
5833 | class ObjCIndependentClassAttr : public InheritableAttr { | |||
5834 | public: | |||
5835 | static ObjCIndependentClassAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
5836 | auto *A = new (Ctx) ObjCIndependentClassAttr(Loc, Ctx, 0); | |||
5837 | A->setImplicit(true); | |||
5838 | return A; | |||
5839 | } | |||
5840 | ||||
5841 | ObjCIndependentClassAttr(SourceRange R, ASTContext &Ctx | |||
5842 | , unsigned SI | |||
5843 | ) | |||
5844 | : InheritableAttr(attr::ObjCIndependentClass, R, SI, false, false) | |||
5845 | { | |||
5846 | } | |||
5847 | ||||
5848 | ObjCIndependentClassAttr *clone(ASTContext &C) const; | |||
5849 | void printPretty(raw_ostream &OS, | |||
5850 | const PrintingPolicy &Policy) const; | |||
5851 | const char *getSpelling() const; | |||
5852 | ||||
5853 | ||||
5854 | static bool classof(const Attr *A) { return A->getKind() == attr::ObjCIndependentClass; } | |||
5855 | }; | |||
5856 | ||||
5857 | class ObjCMethodFamilyAttr : public InheritableAttr { | |||
5858 | public: | |||
5859 | enum FamilyKind { | |||
5860 | OMF_None, | |||
5861 | OMF_alloc, | |||
5862 | OMF_copy, | |||
5863 | OMF_init, | |||
5864 | OMF_mutableCopy, | |||
5865 | OMF_new | |||
5866 | }; | |||
5867 | private: | |||
5868 | FamilyKind family; | |||
5869 | ||||
5870 | public: | |||
5871 | static ObjCMethodFamilyAttr *CreateImplicit(ASTContext &Ctx, FamilyKind Family, SourceRange Loc = SourceRange()) { | |||
5872 | auto *A = new (Ctx) ObjCMethodFamilyAttr(Loc, Ctx, Family, 0); | |||
5873 | A->setImplicit(true); | |||
5874 | return A; | |||
5875 | } | |||
5876 | ||||
5877 | ObjCMethodFamilyAttr(SourceRange R, ASTContext &Ctx | |||
5878 | , FamilyKind Family | |||
5879 | , unsigned SI | |||
5880 | ) | |||
5881 | : InheritableAttr(attr::ObjCMethodFamily, R, SI, false, false) | |||
5882 | , family(Family) | |||
5883 | { | |||
5884 | } | |||
5885 | ||||
5886 | ObjCMethodFamilyAttr *clone(ASTContext &C) const; | |||
5887 | void printPretty(raw_ostream &OS, | |||
5888 | const PrintingPolicy &Policy) const; | |||
5889 | const char *getSpelling() const; | |||
5890 | FamilyKind getFamily() const { | |||
5891 | return family; | |||
5892 | } | |||
5893 | ||||
5894 | static bool ConvertStrToFamilyKind(StringRef Val, FamilyKind &Out) { | |||
5895 | Optional<FamilyKind> R = llvm::StringSwitch<Optional<FamilyKind>>(Val) | |||
5896 | .Case("none", ObjCMethodFamilyAttr::OMF_None) | |||
5897 | .Case("alloc", ObjCMethodFamilyAttr::OMF_alloc) | |||
5898 | .Case("copy", ObjCMethodFamilyAttr::OMF_copy) | |||
5899 | .Case("init", ObjCMethodFamilyAttr::OMF_init) | |||
5900 | .Case("mutableCopy", ObjCMethodFamilyAttr::OMF_mutableCopy) | |||
5901 | .Case("new", ObjCMethodFamilyAttr::OMF_new) | |||
5902 | .Default(Optional<FamilyKind>()); | |||
5903 | if (R) { | |||
5904 | Out = *R; | |||
5905 | return true; | |||
5906 | } | |||
5907 | return false; | |||
5908 | } | |||
5909 | ||||
5910 | static const char *ConvertFamilyKindToStr(FamilyKind Val) { | |||
5911 | switch(Val) { | |||
5912 | case ObjCMethodFamilyAttr::OMF_None: return "none"; | |||
5913 | case ObjCMethodFamilyAttr::OMF_alloc: return "alloc"; | |||
5914 | case ObjCMethodFamilyAttr::OMF_copy: return "copy"; | |||
5915 | case ObjCMethodFamilyAttr::OMF_init: return "init"; | |||
5916 | case ObjCMethodFamilyAttr::OMF_mutableCopy: return "mutableCopy"; | |||
5917 | case ObjCMethodFamilyAttr::OMF_new: return "new"; | |||
5918 | } | |||
5919 | llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 5919); | |||
5920 | } | |||
5921 | ||||
5922 | ||||
5923 | static bool classof(const Attr *A) { return A->getKind() == attr::ObjCMethodFamily; } | |||
5924 | }; | |||
5925 | ||||
5926 | class ObjCNSObjectAttr : public InheritableAttr { | |||
5927 | public: | |||
5928 | static ObjCNSObjectAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
5929 | auto *A = new (Ctx) ObjCNSObjectAttr(Loc, Ctx, 0); | |||
5930 | A->setImplicit(true); | |||
5931 | return A; | |||
5932 | } | |||
5933 | ||||
5934 | ObjCNSObjectAttr(SourceRange R, ASTContext &Ctx | |||
5935 | , unsigned SI | |||
5936 | ) | |||
5937 | : InheritableAttr(attr::ObjCNSObject, R, SI, false, false) | |||
5938 | { | |||
5939 | } | |||
5940 | ||||
5941 | ObjCNSObjectAttr *clone(ASTContext &C) const; | |||
5942 | void printPretty(raw_ostream &OS, | |||
5943 | const PrintingPolicy &Policy) const; | |||
5944 | const char *getSpelling() const; | |||
5945 | ||||
5946 | ||||
5947 | static bool classof(const Attr *A) { return A->getKind() == attr::ObjCNSObject; } | |||
5948 | }; | |||
5949 | ||||
5950 | class ObjCPreciseLifetimeAttr : public InheritableAttr { | |||
5951 | public: | |||
5952 | static ObjCPreciseLifetimeAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
5953 | auto *A = new (Ctx) ObjCPreciseLifetimeAttr(Loc, Ctx, 0); | |||
5954 | A->setImplicit(true); | |||
5955 | return A; | |||
5956 | } | |||
5957 | ||||
5958 | ObjCPreciseLifetimeAttr(SourceRange R, ASTContext &Ctx | |||
5959 | , unsigned SI | |||
5960 | ) | |||
5961 | : InheritableAttr(attr::ObjCPreciseLifetime, R, SI, false, false) | |||
5962 | { | |||
5963 | } | |||
5964 | ||||
5965 | ObjCPreciseLifetimeAttr *clone(ASTContext &C) const; | |||
5966 | void printPretty(raw_ostream &OS, | |||
5967 | const PrintingPolicy &Policy) const; | |||
5968 | const char *getSpelling() const; | |||
5969 | ||||
5970 | ||||
5971 | static bool classof(const Attr *A) { return A->getKind() == attr::ObjCPreciseLifetime; } | |||
5972 | }; | |||
5973 | ||||
5974 | class ObjCRequiresPropertyDefsAttr : public InheritableAttr { | |||
5975 | public: | |||
5976 | static ObjCRequiresPropertyDefsAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
5977 | auto *A = new (Ctx) ObjCRequiresPropertyDefsAttr(Loc, Ctx, 0); | |||
5978 | A->setImplicit(true); | |||
5979 | return A; | |||
5980 | } | |||
5981 | ||||
5982 | ObjCRequiresPropertyDefsAttr(SourceRange R, ASTContext &Ctx | |||
5983 | , unsigned SI | |||
5984 | ) | |||
5985 | : InheritableAttr(attr::ObjCRequiresPropertyDefs, R, SI, false, false) | |||
5986 | { | |||
5987 | } | |||
5988 | ||||
5989 | ObjCRequiresPropertyDefsAttr *clone(ASTContext &C) const; | |||
5990 | void printPretty(raw_ostream &OS, | |||
5991 | const PrintingPolicy &Policy) const; | |||
5992 | const char *getSpelling() const; | |||
5993 | ||||
5994 | ||||
5995 | static bool classof(const Attr *A) { return A->getKind() == attr::ObjCRequiresPropertyDefs; } | |||
5996 | }; | |||
5997 | ||||
5998 | class ObjCRequiresSuperAttr : public InheritableAttr { | |||
5999 | public: | |||
6000 | static ObjCRequiresSuperAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
6001 | auto *A = new (Ctx) ObjCRequiresSuperAttr(Loc, Ctx, 0); | |||
6002 | A->setImplicit(true); | |||
6003 | return A; | |||
6004 | } | |||
6005 | ||||
6006 | ObjCRequiresSuperAttr(SourceRange R, ASTContext &Ctx | |||
6007 | , unsigned SI | |||
6008 | ) | |||
6009 | : InheritableAttr(attr::ObjCRequiresSuper, R, SI, false, false) | |||
6010 | { | |||
6011 | } | |||
6012 | ||||
6013 | ObjCRequiresSuperAttr *clone(ASTContext &C) const; | |||
6014 | void printPretty(raw_ostream &OS, | |||
6015 | const PrintingPolicy &Policy) const; | |||
6016 | const char *getSpelling() const; | |||
6017 | ||||
6018 | ||||
6019 | static bool classof(const Attr *A) { return A->getKind() == attr::ObjCRequiresSuper; } | |||
6020 | }; | |||
6021 | ||||
6022 | class ObjCReturnsInnerPointerAttr : public InheritableAttr { | |||
6023 | public: | |||
6024 | static ObjCReturnsInnerPointerAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
6025 | auto *A = new (Ctx) ObjCReturnsInnerPointerAttr(Loc, Ctx, 0); | |||
6026 | A->setImplicit(true); | |||
6027 | return A; | |||
6028 | } | |||
6029 | ||||
6030 | ObjCReturnsInnerPointerAttr(SourceRange R, ASTContext &Ctx | |||
6031 | , unsigned SI | |||
6032 | ) | |||
6033 | : InheritableAttr(attr::ObjCReturnsInnerPointer, R, SI, false, false) | |||
6034 | { | |||
6035 | } | |||
6036 | ||||
6037 | ObjCReturnsInnerPointerAttr *clone(ASTContext &C) const; | |||
6038 | void printPretty(raw_ostream &OS, | |||
6039 | const PrintingPolicy &Policy) const; | |||
6040 | const char *getSpelling() const; | |||
6041 | ||||
6042 | ||||
6043 | static bool classof(const Attr *A) { return A->getKind() == attr::ObjCReturnsInnerPointer; } | |||
6044 | }; | |||
6045 | ||||
6046 | class ObjCRootClassAttr : public InheritableAttr { | |||
6047 | public: | |||
6048 | static ObjCRootClassAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
6049 | auto *A = new (Ctx) ObjCRootClassAttr(Loc, Ctx, 0); | |||
6050 | A->setImplicit(true); | |||
6051 | return A; | |||
6052 | } | |||
6053 | ||||
6054 | ObjCRootClassAttr(SourceRange R, ASTContext &Ctx | |||
6055 | , unsigned SI | |||
6056 | ) | |||
6057 | : InheritableAttr(attr::ObjCRootClass, R, SI, false, false) | |||
6058 | { | |||
6059 | } | |||
6060 | ||||
6061 | ObjCRootClassAttr *clone(ASTContext &C) const; | |||
6062 | void printPretty(raw_ostream &OS, | |||
6063 | const PrintingPolicy &Policy) const; | |||
6064 | const char *getSpelling() const; | |||
6065 | ||||
6066 | ||||
6067 | static bool classof(const Attr *A) { return A->getKind() == attr::ObjCRootClass; } | |||
6068 | }; | |||
6069 | ||||
6070 | class ObjCRuntimeNameAttr : public Attr { | |||
6071 | unsigned metadataNameLength; | |||
6072 | char *metadataName; | |||
6073 | ||||
6074 | public: | |||
6075 | static ObjCRuntimeNameAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef MetadataName, SourceRange Loc = SourceRange()) { | |||
6076 | auto *A = new (Ctx) ObjCRuntimeNameAttr(Loc, Ctx, MetadataName, 0); | |||
6077 | A->setImplicit(true); | |||
6078 | return A; | |||
6079 | } | |||
6080 | ||||
6081 | ObjCRuntimeNameAttr(SourceRange R, ASTContext &Ctx | |||
6082 | , llvm::StringRef MetadataName | |||
6083 | , unsigned SI | |||
6084 | ) | |||
6085 | : Attr(attr::ObjCRuntimeName, R, SI, false) | |||
6086 | , metadataNameLength(MetadataName.size()),metadataName(new (Ctx, 1) char[metadataNameLength]) | |||
6087 | { | |||
6088 | if (!MetadataName.empty()) | |||
6089 | std::memcpy(metadataName, MetadataName.data(), metadataNameLength); | |||
6090 | } | |||
6091 | ||||
6092 | ObjCRuntimeNameAttr *clone(ASTContext &C) const; | |||
6093 | void printPretty(raw_ostream &OS, | |||
6094 | const PrintingPolicy &Policy) const; | |||
6095 | const char *getSpelling() const; | |||
6096 | llvm::StringRef getMetadataName() const { | |||
6097 | return llvm::StringRef(metadataName, metadataNameLength); | |||
6098 | } | |||
6099 | unsigned getMetadataNameLength() const { | |||
6100 | return metadataNameLength; | |||
6101 | } | |||
6102 | void setMetadataName(ASTContext &C, llvm::StringRef S) { | |||
6103 | metadataNameLength = S.size(); | |||
6104 | this->metadataName = new (C, 1) char [metadataNameLength]; | |||
6105 | if (!S.empty()) | |||
6106 | std::memcpy(this->metadataName, S.data(), metadataNameLength); | |||
6107 | } | |||
6108 | ||||
6109 | ||||
6110 | ||||
6111 | static bool classof(const Attr *A) { return A->getKind() == attr::ObjCRuntimeName; } | |||
6112 | }; | |||
6113 | ||||
6114 | class ObjCRuntimeVisibleAttr : public Attr { | |||
6115 | public: | |||
6116 | static ObjCRuntimeVisibleAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
6117 | auto *A = new (Ctx) ObjCRuntimeVisibleAttr(Loc, Ctx, 0); | |||
6118 | A->setImplicit(true); | |||
6119 | return A; | |||
6120 | } | |||
6121 | ||||
6122 | ObjCRuntimeVisibleAttr(SourceRange R, ASTContext &Ctx | |||
6123 | , unsigned SI | |||
6124 | ) | |||
6125 | : Attr(attr::ObjCRuntimeVisible, R, SI, false) | |||
6126 | { | |||
6127 | } | |||
6128 | ||||
6129 | ObjCRuntimeVisibleAttr *clone(ASTContext &C) const; | |||
6130 | void printPretty(raw_ostream &OS, | |||
6131 | const PrintingPolicy &Policy) const; | |||
6132 | const char *getSpelling() const; | |||
6133 | ||||
6134 | ||||
6135 | static bool classof(const Attr *A) { return A->getKind() == attr::ObjCRuntimeVisible; } | |||
6136 | }; | |||
6137 | ||||
6138 | class ObjCSubclassingRestrictedAttr : public InheritableAttr { | |||
6139 | public: | |||
6140 | static ObjCSubclassingRestrictedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
6141 | auto *A = new (Ctx) ObjCSubclassingRestrictedAttr(Loc, Ctx, 0); | |||
6142 | A->setImplicit(true); | |||
6143 | return A; | |||
6144 | } | |||
6145 | ||||
6146 | ObjCSubclassingRestrictedAttr(SourceRange R, ASTContext &Ctx | |||
6147 | , unsigned SI | |||
6148 | ) | |||
6149 | : InheritableAttr(attr::ObjCSubclassingRestricted, R, SI, false, false) | |||
6150 | { | |||
6151 | } | |||
6152 | ||||
6153 | ObjCSubclassingRestrictedAttr *clone(ASTContext &C) const; | |||
6154 | void printPretty(raw_ostream &OS, | |||
6155 | const PrintingPolicy &Policy) const; | |||
6156 | const char *getSpelling() const; | |||
6157 | ||||
6158 | ||||
6159 | static bool classof(const Attr *A) { return A->getKind() == attr::ObjCSubclassingRestricted; } | |||
6160 | }; | |||
6161 | ||||
6162 | class OpenCLAccessAttr : public Attr { | |||
6163 | public: | |||
6164 | enum Spelling { | |||
6165 | Keyword_read_only = 0, | |||
6166 | Keyword_write_only = 2, | |||
6167 | Keyword_read_write = 4 | |||
6168 | }; | |||
6169 | ||||
6170 | static OpenCLAccessAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) { | |||
6171 | auto *A = new (Ctx) OpenCLAccessAttr(Loc, Ctx, S); | |||
6172 | A->setImplicit(true); | |||
6173 | return A; | |||
6174 | } | |||
6175 | ||||
6176 | OpenCLAccessAttr(SourceRange R, ASTContext &Ctx | |||
6177 | , unsigned SI | |||
6178 | ) | |||
6179 | : Attr(attr::OpenCLAccess, R, SI, false) | |||
6180 | { | |||
6181 | } | |||
6182 | ||||
6183 | OpenCLAccessAttr *clone(ASTContext &C) const; | |||
6184 | void printPretty(raw_ostream &OS, | |||
6185 | const PrintingPolicy &Policy) const; | |||
6186 | const char *getSpelling() const; | |||
6187 | Spelling getSemanticSpelling() const { | |||
6188 | switch (SpellingListIndex) { | |||
6189 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 6189); | |||
6190 | case 0: return Keyword_read_only; | |||
6191 | case 1: return Keyword_read_only; | |||
6192 | case 2: return Keyword_write_only; | |||
6193 | case 3: return Keyword_write_only; | |||
6194 | case 4: return Keyword_read_write; | |||
6195 | case 5: return Keyword_read_write; | |||
6196 | } | |||
6197 | } | |||
6198 | bool isReadOnly() const { return SpellingListIndex == 0 || | |||
6199 | SpellingListIndex == 1; } | |||
6200 | bool isReadWrite() const { return SpellingListIndex == 4 || | |||
6201 | SpellingListIndex == 5; } | |||
6202 | bool isWriteOnly() const { return SpellingListIndex == 2 || | |||
6203 | SpellingListIndex == 3; } | |||
6204 | ||||
6205 | ||||
6206 | static bool classof(const Attr *A) { return A->getKind() == attr::OpenCLAccess; } | |||
6207 | }; | |||
6208 | ||||
6209 | class OpenCLIntelReqdSubGroupSizeAttr : public InheritableAttr { | |||
6210 | unsigned subGroupSize; | |||
6211 | ||||
6212 | public: | |||
6213 | static OpenCLIntelReqdSubGroupSizeAttr *CreateImplicit(ASTContext &Ctx, unsigned SubGroupSize, SourceRange Loc = SourceRange()) { | |||
6214 | auto *A = new (Ctx) OpenCLIntelReqdSubGroupSizeAttr(Loc, Ctx, SubGroupSize, 0); | |||
6215 | A->setImplicit(true); | |||
6216 | return A; | |||
6217 | } | |||
6218 | ||||
6219 | OpenCLIntelReqdSubGroupSizeAttr(SourceRange R, ASTContext &Ctx | |||
6220 | , unsigned SubGroupSize | |||
6221 | , unsigned SI | |||
6222 | ) | |||
6223 | : InheritableAttr(attr::OpenCLIntelReqdSubGroupSize, R, SI, false, false) | |||
6224 | , subGroupSize(SubGroupSize) | |||
6225 | { | |||
6226 | } | |||
6227 | ||||
6228 | OpenCLIntelReqdSubGroupSizeAttr *clone(ASTContext &C) const; | |||
6229 | void printPretty(raw_ostream &OS, | |||
6230 | const PrintingPolicy &Policy) const; | |||
6231 | const char *getSpelling() const; | |||
6232 | unsigned getSubGroupSize() const { | |||
6233 | return subGroupSize; | |||
6234 | } | |||
6235 | ||||
6236 | ||||
6237 | ||||
6238 | static bool classof(const Attr *A) { return A->getKind() == attr::OpenCLIntelReqdSubGroupSize; } | |||
6239 | }; | |||
6240 | ||||
6241 | class OpenCLKernelAttr : public InheritableAttr { | |||
6242 | public: | |||
6243 | static OpenCLKernelAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
6244 | auto *A = new (Ctx) OpenCLKernelAttr(Loc, Ctx, 0); | |||
6245 | A->setImplicit(true); | |||
6246 | return A; | |||
6247 | } | |||
6248 | ||||
6249 | OpenCLKernelAttr(SourceRange R, ASTContext &Ctx | |||
6250 | , unsigned SI | |||
6251 | ) | |||
6252 | : InheritableAttr(attr::OpenCLKernel, R, SI, false, false) | |||
6253 | { | |||
6254 | } | |||
6255 | ||||
6256 | OpenCLKernelAttr *clone(ASTContext &C) const; | |||
6257 | void printPretty(raw_ostream &OS, | |||
6258 | const PrintingPolicy &Policy) const; | |||
6259 | const char *getSpelling() const; | |||
6260 | ||||
6261 | ||||
6262 | static bool classof(const Attr *A) { return A->getKind() == attr::OpenCLKernel; } | |||
6263 | }; | |||
6264 | ||||
6265 | class OpenCLUnrollHintAttr : public InheritableAttr { | |||
6266 | unsigned unrollHint; | |||
6267 | ||||
6268 | public: | |||
6269 | static OpenCLUnrollHintAttr *CreateImplicit(ASTContext &Ctx, unsigned UnrollHint, SourceRange Loc = SourceRange()) { | |||
6270 | auto *A = new (Ctx) OpenCLUnrollHintAttr(Loc, Ctx, UnrollHint, 0); | |||
6271 | A->setImplicit(true); | |||
6272 | return A; | |||
6273 | } | |||
6274 | ||||
6275 | OpenCLUnrollHintAttr(SourceRange R, ASTContext &Ctx | |||
6276 | , unsigned UnrollHint | |||
6277 | , unsigned SI | |||
6278 | ) | |||
6279 | : InheritableAttr(attr::OpenCLUnrollHint, R, SI, false, false) | |||
6280 | , unrollHint(UnrollHint) | |||
6281 | { | |||
6282 | } | |||
6283 | ||||
6284 | OpenCLUnrollHintAttr *clone(ASTContext &C) const; | |||
6285 | void printPretty(raw_ostream &OS, | |||
6286 | const PrintingPolicy &Policy) const; | |||
6287 | const char *getSpelling() const; | |||
6288 | unsigned getUnrollHint() const { | |||
6289 | return unrollHint; | |||
6290 | } | |||
6291 | ||||
6292 | ||||
6293 | ||||
6294 | static bool classof(const Attr *A) { return A->getKind() == attr::OpenCLUnrollHint; } | |||
6295 | }; | |||
6296 | ||||
6297 | class OptimizeNoneAttr : public InheritableAttr { | |||
6298 | public: | |||
6299 | static OptimizeNoneAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
6300 | auto *A = new (Ctx) OptimizeNoneAttr(Loc, Ctx, 0); | |||
6301 | A->setImplicit(true); | |||
6302 | return A; | |||
6303 | } | |||
6304 | ||||
6305 | OptimizeNoneAttr(SourceRange R, ASTContext &Ctx | |||
6306 | , unsigned SI | |||
6307 | ) | |||
6308 | : InheritableAttr(attr::OptimizeNone, R, SI, false, false) | |||
6309 | { | |||
6310 | } | |||
6311 | ||||
6312 | OptimizeNoneAttr *clone(ASTContext &C) const; | |||
6313 | void printPretty(raw_ostream &OS, | |||
6314 | const PrintingPolicy &Policy) const; | |||
6315 | const char *getSpelling() const; | |||
6316 | ||||
6317 | ||||
6318 | static bool classof(const Attr *A) { return A->getKind() == attr::OptimizeNone; } | |||
6319 | }; | |||
6320 | ||||
6321 | class OverloadableAttr : public Attr { | |||
6322 | public: | |||
6323 | static OverloadableAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
6324 | auto *A = new (Ctx) OverloadableAttr(Loc, Ctx, 0); | |||
6325 | A->setImplicit(true); | |||
6326 | return A; | |||
6327 | } | |||
6328 | ||||
6329 | OverloadableAttr(SourceRange R, ASTContext &Ctx | |||
6330 | , unsigned SI | |||
6331 | ) | |||
6332 | : Attr(attr::Overloadable, R, SI, false) | |||
6333 | { | |||
6334 | } | |||
6335 | ||||
6336 | OverloadableAttr *clone(ASTContext &C) const; | |||
6337 | void printPretty(raw_ostream &OS, | |||
6338 | const PrintingPolicy &Policy) const; | |||
6339 | const char *getSpelling() const; | |||
6340 | ||||
6341 | ||||
6342 | static bool classof(const Attr *A) { return A->getKind() == attr::Overloadable; } | |||
6343 | }; | |||
6344 | ||||
6345 | class OverrideAttr : public InheritableAttr { | |||
6346 | public: | |||
6347 | static OverrideAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
6348 | auto *A = new (Ctx) OverrideAttr(Loc, Ctx, 0); | |||
6349 | A->setImplicit(true); | |||
6350 | return A; | |||
6351 | } | |||
6352 | ||||
6353 | OverrideAttr(SourceRange R, ASTContext &Ctx | |||
6354 | , unsigned SI | |||
6355 | ) | |||
6356 | : InheritableAttr(attr::Override, R, SI, false, false) | |||
6357 | { | |||
6358 | } | |||
6359 | ||||
6360 | OverrideAttr *clone(ASTContext &C) const; | |||
6361 | void printPretty(raw_ostream &OS, | |||
6362 | const PrintingPolicy &Policy) const; | |||
6363 | const char *getSpelling() const; | |||
6364 | ||||
6365 | ||||
6366 | static bool classof(const Attr *A) { return A->getKind() == attr::Override; } | |||
6367 | }; | |||
6368 | ||||
6369 | class OwnershipAttr : public InheritableAttr { | |||
6370 | IdentifierInfo * module; | |||
6371 | ||||
6372 | unsigned args_Size; | |||
6373 | ParamIdx *args_; | |||
6374 | ||||
6375 | public: | |||
6376 | enum Spelling { | |||
6377 | GNU_ownership_holds = 0, | |||
6378 | CXX11_clang_ownership_holds = 1, | |||
6379 | C2x_clang_ownership_holds = 2, | |||
6380 | GNU_ownership_returns = 3, | |||
6381 | CXX11_clang_ownership_returns = 4, | |||
6382 | C2x_clang_ownership_returns = 5, | |||
6383 | GNU_ownership_takes = 6, | |||
6384 | CXX11_clang_ownership_takes = 7, | |||
6385 | C2x_clang_ownership_takes = 8 | |||
6386 | }; | |||
6387 | ||||
6388 | static OwnershipAttr *CreateImplicit(ASTContext &Ctx, Spelling S, IdentifierInfo * Module, ParamIdx *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) { | |||
6389 | auto *A = new (Ctx) OwnershipAttr(Loc, Ctx, Module, Args, ArgsSize, S); | |||
6390 | A->setImplicit(true); | |||
6391 | return A; | |||
6392 | } | |||
6393 | ||||
6394 | OwnershipAttr(SourceRange R, ASTContext &Ctx | |||
6395 | , IdentifierInfo * Module | |||
6396 | , ParamIdx *Args, unsigned ArgsSize | |||
6397 | , unsigned SI | |||
6398 | ) | |||
6399 | : InheritableAttr(attr::Ownership, R, SI, false, false) | |||
6400 | , module(Module) | |||
6401 | , args_Size(ArgsSize), args_(new (Ctx, 16) ParamIdx[args_Size]) | |||
6402 | { | |||
6403 | std::copy(Args, Args + args_Size, args_); | |||
6404 | } | |||
6405 | ||||
6406 | OwnershipAttr(SourceRange R, ASTContext &Ctx | |||
6407 | , IdentifierInfo * Module | |||
6408 | , unsigned SI | |||
6409 | ) | |||
6410 | : InheritableAttr(attr::Ownership, R, SI, false, false) | |||
6411 | , module(Module) | |||
6412 | , args_Size(0), args_(nullptr) | |||
6413 | { | |||
6414 | } | |||
6415 | ||||
6416 | OwnershipAttr *clone(ASTContext &C) const; | |||
6417 | void printPretty(raw_ostream &OS, | |||
6418 | const PrintingPolicy &Policy) const; | |||
6419 | const char *getSpelling() const; | |||
6420 | Spelling getSemanticSpelling() const { | |||
6421 | switch (SpellingListIndex) { | |||
6422 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 6422); | |||
6423 | case 0: return GNU_ownership_holds; | |||
6424 | case 1: return CXX11_clang_ownership_holds; | |||
6425 | case 2: return C2x_clang_ownership_holds; | |||
6426 | case 3: return GNU_ownership_returns; | |||
6427 | case 4: return CXX11_clang_ownership_returns; | |||
6428 | case 5: return C2x_clang_ownership_returns; | |||
6429 | case 6: return GNU_ownership_takes; | |||
6430 | case 7: return CXX11_clang_ownership_takes; | |||
6431 | case 8: return C2x_clang_ownership_takes; | |||
6432 | } | |||
6433 | } | |||
6434 | bool isHolds() const { return SpellingListIndex == 0 || | |||
6435 | SpellingListIndex == 1 || | |||
6436 | SpellingListIndex == 2; } | |||
6437 | bool isReturns() const { return SpellingListIndex == 3 || | |||
6438 | SpellingListIndex == 4 || | |||
6439 | SpellingListIndex == 5; } | |||
6440 | bool isTakes() const { return SpellingListIndex == 6 || | |||
6441 | SpellingListIndex == 7 || | |||
6442 | SpellingListIndex == 8; } | |||
6443 | IdentifierInfo * getModule() const { | |||
6444 | return module; | |||
6445 | } | |||
6446 | ||||
6447 | typedef ParamIdx* args_iterator; | |||
6448 | args_iterator args_begin() const { return args_; } | |||
6449 | args_iterator args_end() const { return args_ + args_Size; } | |||
6450 | unsigned args_size() const { return args_Size; } | |||
6451 | llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); } | |||
6452 | ||||
6453 | ||||
6454 | ||||
6455 | enum OwnershipKind { Holds, Returns, Takes }; | |||
6456 | OwnershipKind getOwnKind() const { | |||
6457 | return isHolds() ? Holds : | |||
6458 | isTakes() ? Takes : | |||
6459 | Returns; | |||
6460 | } | |||
6461 | ||||
6462 | ||||
6463 | static bool classof(const Attr *A) { return A->getKind() == attr::Ownership; } | |||
6464 | }; | |||
6465 | ||||
6466 | class PackedAttr : public InheritableAttr { | |||
6467 | public: | |||
6468 | static PackedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
6469 | auto *A = new (Ctx) PackedAttr(Loc, Ctx, 0); | |||
6470 | A->setImplicit(true); | |||
6471 | return A; | |||
6472 | } | |||
6473 | ||||
6474 | PackedAttr(SourceRange R, ASTContext &Ctx | |||
6475 | , unsigned SI | |||
6476 | ) | |||
6477 | : InheritableAttr(attr::Packed, R, SI, false, false) | |||
6478 | { | |||
6479 | } | |||
6480 | ||||
6481 | PackedAttr *clone(ASTContext &C) const; | |||
6482 | void printPretty(raw_ostream &OS, | |||
6483 | const PrintingPolicy &Policy) const; | |||
6484 | const char *getSpelling() const; | |||
6485 | ||||
6486 | ||||
6487 | static bool classof(const Attr *A) { return A->getKind() == attr::Packed; } | |||
6488 | }; | |||
6489 | ||||
6490 | class ParamTypestateAttr : public InheritableAttr { | |||
6491 | public: | |||
6492 | enum ConsumedState { | |||
6493 | Unknown, | |||
6494 | Consumed, | |||
6495 | Unconsumed | |||
6496 | }; | |||
6497 | private: | |||
6498 | ConsumedState paramState; | |||
6499 | ||||
6500 | public: | |||
6501 | static ParamTypestateAttr *CreateImplicit(ASTContext &Ctx, ConsumedState ParamState, SourceRange Loc = SourceRange()) { | |||
6502 | auto *A = new (Ctx) ParamTypestateAttr(Loc, Ctx, ParamState, 0); | |||
6503 | A->setImplicit(true); | |||
6504 | return A; | |||
6505 | } | |||
6506 | ||||
6507 | ParamTypestateAttr(SourceRange R, ASTContext &Ctx | |||
6508 | , ConsumedState ParamState | |||
6509 | , unsigned SI | |||
6510 | ) | |||
6511 | : InheritableAttr(attr::ParamTypestate, R, SI, false, false) | |||
6512 | , paramState(ParamState) | |||
6513 | { | |||
6514 | } | |||
6515 | ||||
6516 | ParamTypestateAttr *clone(ASTContext &C) const; | |||
6517 | void printPretty(raw_ostream &OS, | |||
6518 | const PrintingPolicy &Policy) const; | |||
6519 | const char *getSpelling() const; | |||
6520 | ConsumedState getParamState() const { | |||
6521 | return paramState; | |||
6522 | } | |||
6523 | ||||
6524 | static bool ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) { | |||
6525 | Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val) | |||
6526 | .Case("unknown", ParamTypestateAttr::Unknown) | |||
6527 | .Case("consumed", ParamTypestateAttr::Consumed) | |||
6528 | .Case("unconsumed", ParamTypestateAttr::Unconsumed) | |||
6529 | .Default(Optional<ConsumedState>()); | |||
6530 | if (R) { | |||
6531 | Out = *R; | |||
6532 | return true; | |||
6533 | } | |||
6534 | return false; | |||
6535 | } | |||
6536 | ||||
6537 | static const char *ConvertConsumedStateToStr(ConsumedState Val) { | |||
6538 | switch(Val) { | |||
6539 | case ParamTypestateAttr::Unknown: return "unknown"; | |||
6540 | case ParamTypestateAttr::Consumed: return "consumed"; | |||
6541 | case ParamTypestateAttr::Unconsumed: return "unconsumed"; | |||
6542 | } | |||
6543 | llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 6543); | |||
6544 | } | |||
6545 | ||||
6546 | ||||
6547 | static bool classof(const Attr *A) { return A->getKind() == attr::ParamTypestate; } | |||
6548 | }; | |||
6549 | ||||
6550 | class PascalAttr : public InheritableAttr { | |||
6551 | public: | |||
6552 | static PascalAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
6553 | auto *A = new (Ctx) PascalAttr(Loc, Ctx, 0); | |||
6554 | A->setImplicit(true); | |||
6555 | return A; | |||
6556 | } | |||
6557 | ||||
6558 | PascalAttr(SourceRange R, ASTContext &Ctx | |||
6559 | , unsigned SI | |||
6560 | ) | |||
6561 | : InheritableAttr(attr::Pascal, R, SI, false, false) | |||
6562 | { | |||
6563 | } | |||
6564 | ||||
6565 | PascalAttr *clone(ASTContext &C) const; | |||
6566 | void printPretty(raw_ostream &OS, | |||
6567 | const PrintingPolicy &Policy) const; | |||
6568 | const char *getSpelling() const; | |||
6569 | ||||
6570 | ||||
6571 | static bool classof(const Attr *A) { return A->getKind() == attr::Pascal; } | |||
6572 | }; | |||
6573 | ||||
6574 | class PassObjectSizeAttr : public InheritableParamAttr { | |||
6575 | int type; | |||
6576 | ||||
6577 | public: | |||
6578 | static PassObjectSizeAttr *CreateImplicit(ASTContext &Ctx, int Type, SourceRange Loc = SourceRange()) { | |||
6579 | auto *A = new (Ctx) PassObjectSizeAttr(Loc, Ctx, Type, 0); | |||
6580 | A->setImplicit(true); | |||
6581 | return A; | |||
6582 | } | |||
6583 | ||||
6584 | PassObjectSizeAttr(SourceRange R, ASTContext &Ctx | |||
6585 | , int Type | |||
6586 | , unsigned SI | |||
6587 | ) | |||
6588 | : InheritableParamAttr(attr::PassObjectSize, R, SI, false, false) | |||
6589 | , type(Type) | |||
6590 | { | |||
6591 | } | |||
6592 | ||||
6593 | PassObjectSizeAttr *clone(ASTContext &C) const; | |||
6594 | void printPretty(raw_ostream &OS, | |||
6595 | const PrintingPolicy &Policy) const; | |||
6596 | const char *getSpelling() const; | |||
6597 | int getType() const { | |||
6598 | return type; | |||
6599 | } | |||
6600 | ||||
6601 | ||||
6602 | ||||
6603 | static bool classof(const Attr *A) { return A->getKind() == attr::PassObjectSize; } | |||
6604 | }; | |||
6605 | ||||
6606 | class PcsAttr : public InheritableAttr { | |||
6607 | public: | |||
6608 | enum PCSType { | |||
6609 | AAPCS, | |||
6610 | AAPCS_VFP | |||
6611 | }; | |||
6612 | private: | |||
6613 | PCSType pCS; | |||
6614 | ||||
6615 | public: | |||
6616 | static PcsAttr *CreateImplicit(ASTContext &Ctx, PCSType PCS, SourceRange Loc = SourceRange()) { | |||
6617 | auto *A = new (Ctx) PcsAttr(Loc, Ctx, PCS, 0); | |||
6618 | A->setImplicit(true); | |||
6619 | return A; | |||
6620 | } | |||
6621 | ||||
6622 | PcsAttr(SourceRange R, ASTContext &Ctx | |||
6623 | , PCSType PCS | |||
6624 | , unsigned SI | |||
6625 | ) | |||
6626 | : InheritableAttr(attr::Pcs, R, SI, false, false) | |||
6627 | , pCS(PCS) | |||
6628 | { | |||
6629 | } | |||
6630 | ||||
6631 | PcsAttr *clone(ASTContext &C) const; | |||
6632 | void printPretty(raw_ostream &OS, | |||
6633 | const PrintingPolicy &Policy) const; | |||
6634 | const char *getSpelling() const; | |||
6635 | PCSType getPCS() const { | |||
6636 | return pCS; | |||
6637 | } | |||
6638 | ||||
6639 | static bool ConvertStrToPCSType(StringRef Val, PCSType &Out) { | |||
6640 | Optional<PCSType> R = llvm::StringSwitch<Optional<PCSType>>(Val) | |||
6641 | .Case("aapcs", PcsAttr::AAPCS) | |||
6642 | .Case("aapcs-vfp", PcsAttr::AAPCS_VFP) | |||
6643 | .Default(Optional<PCSType>()); | |||
6644 | if (R) { | |||
6645 | Out = *R; | |||
6646 | return true; | |||
6647 | } | |||
6648 | return false; | |||
6649 | } | |||
6650 | ||||
6651 | static const char *ConvertPCSTypeToStr(PCSType Val) { | |||
6652 | switch(Val) { | |||
6653 | case PcsAttr::AAPCS: return "aapcs"; | |||
6654 | case PcsAttr::AAPCS_VFP: return "aapcs-vfp"; | |||
6655 | } | |||
6656 | llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 6656); | |||
6657 | } | |||
6658 | ||||
6659 | ||||
6660 | static bool classof(const Attr *A) { return A->getKind() == attr::Pcs; } | |||
6661 | }; | |||
6662 | ||||
6663 | class PragmaClangBSSSectionAttr : public InheritableAttr { | |||
6664 | unsigned nameLength; | |||
6665 | char *name; | |||
6666 | ||||
6667 | public: | |||
6668 | static PragmaClangBSSSectionAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Loc = SourceRange()) { | |||
6669 | auto *A = new (Ctx) PragmaClangBSSSectionAttr(Loc, Ctx, Name, 0); | |||
6670 | A->setImplicit(true); | |||
6671 | return A; | |||
6672 | } | |||
6673 | ||||
6674 | PragmaClangBSSSectionAttr(SourceRange R, ASTContext &Ctx | |||
6675 | , llvm::StringRef Name | |||
6676 | , unsigned SI | |||
6677 | ) | |||
6678 | : InheritableAttr(attr::PragmaClangBSSSection, R, SI, false, false) | |||
6679 | , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength]) | |||
6680 | { | |||
6681 | if (!Name.empty()) | |||
6682 | std::memcpy(name, Name.data(), nameLength); | |||
6683 | } | |||
6684 | ||||
6685 | PragmaClangBSSSectionAttr *clone(ASTContext &C) const; | |||
6686 | void printPretty(raw_ostream &OS, | |||
6687 | const PrintingPolicy &Policy) const; | |||
6688 | const char *getSpelling() const; | |||
6689 | llvm::StringRef getName() const { | |||
6690 | return llvm::StringRef(name, nameLength); | |||
6691 | } | |||
6692 | unsigned getNameLength() const { | |||
6693 | return nameLength; | |||
6694 | } | |||
6695 | void setName(ASTContext &C, llvm::StringRef S) { | |||
6696 | nameLength = S.size(); | |||
6697 | this->name = new (C, 1) char [nameLength]; | |||
6698 | if (!S.empty()) | |||
6699 | std::memcpy(this->name, S.data(), nameLength); | |||
6700 | } | |||
6701 | ||||
6702 | ||||
6703 | ||||
6704 | static bool classof(const Attr *A) { return A->getKind() == attr::PragmaClangBSSSection; } | |||
6705 | }; | |||
6706 | ||||
6707 | class PragmaClangDataSectionAttr : public InheritableAttr { | |||
6708 | unsigned nameLength; | |||
6709 | char *name; | |||
6710 | ||||
6711 | public: | |||
6712 | static PragmaClangDataSectionAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Loc = SourceRange()) { | |||
6713 | auto *A = new (Ctx) PragmaClangDataSectionAttr(Loc, Ctx, Name, 0); | |||
6714 | A->setImplicit(true); | |||
6715 | return A; | |||
6716 | } | |||
6717 | ||||
6718 | PragmaClangDataSectionAttr(SourceRange R, ASTContext &Ctx | |||
6719 | , llvm::StringRef Name | |||
6720 | , unsigned SI | |||
6721 | ) | |||
6722 | : InheritableAttr(attr::PragmaClangDataSection, R, SI, false, false) | |||
6723 | , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength]) | |||
6724 | { | |||
6725 | if (!Name.empty()) | |||
6726 | std::memcpy(name, Name.data(), nameLength); | |||
6727 | } | |||
6728 | ||||
6729 | PragmaClangDataSectionAttr *clone(ASTContext &C) const; | |||
6730 | void printPretty(raw_ostream &OS, | |||
6731 | const PrintingPolicy &Policy) const; | |||
6732 | const char *getSpelling() const; | |||
6733 | llvm::StringRef getName() const { | |||
6734 | return llvm::StringRef(name, nameLength); | |||
6735 | } | |||
6736 | unsigned getNameLength() const { | |||
6737 | return nameLength; | |||
6738 | } | |||
6739 | void setName(ASTContext &C, llvm::StringRef S) { | |||
6740 | nameLength = S.size(); | |||
6741 | this->name = new (C, 1) char [nameLength]; | |||
6742 | if (!S.empty()) | |||
6743 | std::memcpy(this->name, S.data(), nameLength); | |||
6744 | } | |||
6745 | ||||
6746 | ||||
6747 | ||||
6748 | static bool classof(const Attr *A) { return A->getKind() == attr::PragmaClangDataSection; } | |||
6749 | }; | |||
6750 | ||||
6751 | class PragmaClangRodataSectionAttr : public InheritableAttr { | |||
6752 | unsigned nameLength; | |||
6753 | char *name; | |||
6754 | ||||
6755 | public: | |||
6756 | static PragmaClangRodataSectionAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Loc = SourceRange()) { | |||
6757 | auto *A = new (Ctx) PragmaClangRodataSectionAttr(Loc, Ctx, Name, 0); | |||
6758 | A->setImplicit(true); | |||
6759 | return A; | |||
6760 | } | |||
6761 | ||||
6762 | PragmaClangRodataSectionAttr(SourceRange R, ASTContext &Ctx | |||
6763 | , llvm::StringRef Name | |||
6764 | , unsigned SI | |||
6765 | ) | |||
6766 | : InheritableAttr(attr::PragmaClangRodataSection, R, SI, false, false) | |||
6767 | , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength]) | |||
6768 | { | |||
6769 | if (!Name.empty()) | |||
6770 | std::memcpy(name, Name.data(), nameLength); | |||
6771 | } | |||
6772 | ||||
6773 | PragmaClangRodataSectionAttr *clone(ASTContext &C) const; | |||
6774 | void printPretty(raw_ostream &OS, | |||
6775 | const PrintingPolicy &Policy) const; | |||
6776 | const char *getSpelling() const; | |||
6777 | llvm::StringRef getName() const { | |||
6778 | return llvm::StringRef(name, nameLength); | |||
6779 | } | |||
6780 | unsigned getNameLength() const { | |||
6781 | return nameLength; | |||
6782 | } | |||
6783 | void setName(ASTContext &C, llvm::StringRef S) { | |||
6784 | nameLength = S.size(); | |||
6785 | this->name = new (C, 1) char [nameLength]; | |||
6786 | if (!S.empty()) | |||
6787 | std::memcpy(this->name, S.data(), nameLength); | |||
6788 | } | |||
6789 | ||||
6790 | ||||
6791 | ||||
6792 | static bool classof(const Attr *A) { return A->getKind() == attr::PragmaClangRodataSection; } | |||
6793 | }; | |||
6794 | ||||
6795 | class PragmaClangTextSectionAttr : public InheritableAttr { | |||
6796 | unsigned nameLength; | |||
6797 | char *name; | |||
6798 | ||||
6799 | public: | |||
6800 | static PragmaClangTextSectionAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Loc = SourceRange()) { | |||
6801 | auto *A = new (Ctx) PragmaClangTextSectionAttr(Loc, Ctx, Name, 0); | |||
6802 | A->setImplicit(true); | |||
6803 | return A; | |||
6804 | } | |||
6805 | ||||
6806 | PragmaClangTextSectionAttr(SourceRange R, ASTContext &Ctx | |||
6807 | , llvm::StringRef Name | |||
6808 | , unsigned SI | |||
6809 | ) | |||
6810 | : InheritableAttr(attr::PragmaClangTextSection, R, SI, false, false) | |||
6811 | , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength]) | |||
6812 | { | |||
6813 | if (!Name.empty()) | |||
6814 | std::memcpy(name, Name.data(), nameLength); | |||
6815 | } | |||
6816 | ||||
6817 | PragmaClangTextSectionAttr *clone(ASTContext &C) const; | |||
6818 | void printPretty(raw_ostream &OS, | |||
6819 | const PrintingPolicy &Policy) const; | |||
6820 | const char *getSpelling() const; | |||
6821 | llvm::StringRef getName() const { | |||
6822 | return llvm::StringRef(name, nameLength); | |||
6823 | } | |||
6824 | unsigned getNameLength() const { | |||
6825 | return nameLength; | |||
6826 | } | |||
6827 | void setName(ASTContext &C, llvm::StringRef S) { | |||
6828 | nameLength = S.size(); | |||
6829 | this->name = new (C, 1) char [nameLength]; | |||
6830 | if (!S.empty()) | |||
6831 | std::memcpy(this->name, S.data(), nameLength); | |||
6832 | } | |||
6833 | ||||
6834 | ||||
6835 | ||||
6836 | static bool classof(const Attr *A) { return A->getKind() == attr::PragmaClangTextSection; } | |||
6837 | }; | |||
6838 | ||||
6839 | class PreserveAllAttr : public InheritableAttr { | |||
6840 | public: | |||
6841 | static PreserveAllAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
6842 | auto *A = new (Ctx) PreserveAllAttr(Loc, Ctx, 0); | |||
6843 | A->setImplicit(true); | |||
6844 | return A; | |||
6845 | } | |||
6846 | ||||
6847 | PreserveAllAttr(SourceRange R, ASTContext &Ctx | |||
6848 | , unsigned SI | |||
6849 | ) | |||
6850 | : InheritableAttr(attr::PreserveAll, R, SI, false, false) | |||
6851 | { | |||
6852 | } | |||
6853 | ||||
6854 | PreserveAllAttr *clone(ASTContext &C) const; | |||
6855 | void printPretty(raw_ostream &OS, | |||
6856 | const PrintingPolicy &Policy) const; | |||
6857 | const char *getSpelling() const; | |||
6858 | ||||
6859 | ||||
6860 | static bool classof(const Attr *A) { return A->getKind() == attr::PreserveAll; } | |||
6861 | }; | |||
6862 | ||||
6863 | class PreserveMostAttr : public InheritableAttr { | |||
6864 | public: | |||
6865 | static PreserveMostAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
6866 | auto *A = new (Ctx) PreserveMostAttr(Loc, Ctx, 0); | |||
6867 | A->setImplicit(true); | |||
6868 | return A; | |||
6869 | } | |||
6870 | ||||
6871 | PreserveMostAttr(SourceRange R, ASTContext &Ctx | |||
6872 | , unsigned SI | |||
6873 | ) | |||
6874 | : InheritableAttr(attr::PreserveMost, R, SI, false, false) | |||
6875 | { | |||
6876 | } | |||
6877 | ||||
6878 | PreserveMostAttr *clone(ASTContext &C) const; | |||
6879 | void printPretty(raw_ostream &OS, | |||
6880 | const PrintingPolicy &Policy) const; | |||
6881 | const char *getSpelling() const; | |||
6882 | ||||
6883 | ||||
6884 | static bool classof(const Attr *A) { return A->getKind() == attr::PreserveMost; } | |||
6885 | }; | |||
6886 | ||||
6887 | class PtGuardedByAttr : public InheritableAttr { | |||
6888 | Expr * arg; | |||
6889 | ||||
6890 | public: | |||
6891 | static PtGuardedByAttr *CreateImplicit(ASTContext &Ctx, Expr * Arg, SourceRange Loc = SourceRange()) { | |||
6892 | auto *A = new (Ctx) PtGuardedByAttr(Loc, Ctx, Arg, 0); | |||
6893 | A->setImplicit(true); | |||
6894 | return A; | |||
6895 | } | |||
6896 | ||||
6897 | PtGuardedByAttr(SourceRange R, ASTContext &Ctx | |||
6898 | , Expr * Arg | |||
6899 | , unsigned SI | |||
6900 | ) | |||
6901 | : InheritableAttr(attr::PtGuardedBy, R, SI, true, true) | |||
6902 | , arg(Arg) | |||
6903 | { | |||
6904 | } | |||
6905 | ||||
6906 | PtGuardedByAttr *clone(ASTContext &C) const; | |||
6907 | void printPretty(raw_ostream &OS, | |||
6908 | const PrintingPolicy &Policy) const; | |||
6909 | const char *getSpelling() const; | |||
6910 | Expr * getArg() const { | |||
6911 | return arg; | |||
6912 | } | |||
6913 | ||||
6914 | ||||
6915 | ||||
6916 | static bool classof(const Attr *A) { return A->getKind() == attr::PtGuardedBy; } | |||
6917 | }; | |||
6918 | ||||
6919 | class PtGuardedVarAttr : public InheritableAttr { | |||
6920 | public: | |||
6921 | static PtGuardedVarAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
6922 | auto *A = new (Ctx) PtGuardedVarAttr(Loc, Ctx, 0); | |||
6923 | A->setImplicit(true); | |||
6924 | return A; | |||
6925 | } | |||
6926 | ||||
6927 | PtGuardedVarAttr(SourceRange R, ASTContext &Ctx | |||
6928 | , unsigned SI | |||
6929 | ) | |||
6930 | : InheritableAttr(attr::PtGuardedVar, R, SI, false, false) | |||
6931 | { | |||
6932 | } | |||
6933 | ||||
6934 | PtGuardedVarAttr *clone(ASTContext &C) const; | |||
6935 | void printPretty(raw_ostream &OS, | |||
6936 | const PrintingPolicy &Policy) const; | |||
6937 | const char *getSpelling() const; | |||
6938 | ||||
6939 | ||||
6940 | static bool classof(const Attr *A) { return A->getKind() == attr::PtGuardedVar; } | |||
6941 | }; | |||
6942 | ||||
6943 | class PureAttr : public InheritableAttr { | |||
6944 | public: | |||
6945 | static PureAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
6946 | auto *A = new (Ctx) PureAttr(Loc, Ctx, 0); | |||
6947 | A->setImplicit(true); | |||
6948 | return A; | |||
6949 | } | |||
6950 | ||||
6951 | PureAttr(SourceRange R, ASTContext &Ctx | |||
6952 | , unsigned SI | |||
6953 | ) | |||
6954 | : InheritableAttr(attr::Pure, R, SI, false, false) | |||
6955 | { | |||
6956 | } | |||
6957 | ||||
6958 | PureAttr *clone(ASTContext &C) const; | |||
6959 | void printPretty(raw_ostream &OS, | |||
6960 | const PrintingPolicy &Policy) const; | |||
6961 | const char *getSpelling() const; | |||
6962 | ||||
6963 | ||||
6964 | static bool classof(const Attr *A) { return A->getKind() == attr::Pure; } | |||
6965 | }; | |||
6966 | ||||
6967 | class RISCVInterruptAttr : public InheritableAttr { | |||
6968 | public: | |||
6969 | enum InterruptType { | |||
6970 | user, | |||
6971 | supervisor, | |||
6972 | machine | |||
6973 | }; | |||
6974 | private: | |||
6975 | InterruptType interrupt; | |||
6976 | ||||
6977 | public: | |||
6978 | static RISCVInterruptAttr *CreateImplicit(ASTContext &Ctx, InterruptType Interrupt, SourceRange Loc = SourceRange()) { | |||
6979 | auto *A = new (Ctx) RISCVInterruptAttr(Loc, Ctx, Interrupt, 0); | |||
6980 | A->setImplicit(true); | |||
6981 | return A; | |||
6982 | } | |||
6983 | ||||
6984 | RISCVInterruptAttr(SourceRange R, ASTContext &Ctx | |||
6985 | , InterruptType Interrupt | |||
6986 | , unsigned SI | |||
6987 | ) | |||
6988 | : InheritableAttr(attr::RISCVInterrupt, R, SI, false, false) | |||
6989 | , interrupt(Interrupt) | |||
6990 | { | |||
6991 | } | |||
6992 | ||||
6993 | RISCVInterruptAttr(SourceRange R, ASTContext &Ctx | |||
6994 | , unsigned SI | |||
6995 | ) | |||
6996 | : InheritableAttr(attr::RISCVInterrupt, R, SI, false, false) | |||
6997 | , interrupt(InterruptType(0)) | |||
6998 | { | |||
6999 | } | |||
7000 | ||||
7001 | RISCVInterruptAttr *clone(ASTContext &C) const; | |||
7002 | void printPretty(raw_ostream &OS, | |||
7003 | const PrintingPolicy &Policy) const; | |||
7004 | const char *getSpelling() const; | |||
7005 | InterruptType getInterrupt() const { | |||
7006 | return interrupt; | |||
7007 | } | |||
7008 | ||||
7009 | static bool ConvertStrToInterruptType(StringRef Val, InterruptType &Out) { | |||
7010 | Optional<InterruptType> R = llvm::StringSwitch<Optional<InterruptType>>(Val) | |||
7011 | .Case("user", RISCVInterruptAttr::user) | |||
7012 | .Case("supervisor", RISCVInterruptAttr::supervisor) | |||
7013 | .Case("machine", RISCVInterruptAttr::machine) | |||
7014 | .Default(Optional<InterruptType>()); | |||
7015 | if (R) { | |||
7016 | Out = *R; | |||
7017 | return true; | |||
7018 | } | |||
7019 | return false; | |||
7020 | } | |||
7021 | ||||
7022 | static const char *ConvertInterruptTypeToStr(InterruptType Val) { | |||
7023 | switch(Val) { | |||
7024 | case RISCVInterruptAttr::user: return "user"; | |||
7025 | case RISCVInterruptAttr::supervisor: return "supervisor"; | |||
7026 | case RISCVInterruptAttr::machine: return "machine"; | |||
7027 | } | |||
7028 | llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 7028); | |||
7029 | } | |||
7030 | ||||
7031 | ||||
7032 | static bool classof(const Attr *A) { return A->getKind() == attr::RISCVInterrupt; } | |||
7033 | }; | |||
7034 | ||||
7035 | class RegCallAttr : public InheritableAttr { | |||
7036 | public: | |||
7037 | static RegCallAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
7038 | auto *A = new (Ctx) RegCallAttr(Loc, Ctx, 0); | |||
7039 | A->setImplicit(true); | |||
7040 | return A; | |||
7041 | } | |||
7042 | ||||
7043 | RegCallAttr(SourceRange R, ASTContext &Ctx | |||
7044 | , unsigned SI | |||
7045 | ) | |||
7046 | : InheritableAttr(attr::RegCall, R, SI, false, false) | |||
7047 | { | |||
7048 | } | |||
7049 | ||||
7050 | RegCallAttr *clone(ASTContext &C) const; | |||
7051 | void printPretty(raw_ostream &OS, | |||
7052 | const PrintingPolicy &Policy) const; | |||
7053 | const char *getSpelling() const; | |||
7054 | ||||
7055 | ||||
7056 | static bool classof(const Attr *A) { return A->getKind() == attr::RegCall; } | |||
7057 | }; | |||
7058 | ||||
7059 | class ReleaseCapabilityAttr : public InheritableAttr { | |||
7060 | unsigned args_Size; | |||
7061 | Expr * *args_; | |||
7062 | ||||
7063 | public: | |||
7064 | enum Spelling { | |||
7065 | GNU_release_capability = 0, | |||
7066 | CXX11_clang_release_capability = 1, | |||
7067 | GNU_release_shared_capability = 2, | |||
7068 | CXX11_clang_release_shared_capability = 3, | |||
7069 | GNU_release_generic_capability = 4, | |||
7070 | CXX11_clang_release_generic_capability = 5, | |||
7071 | GNU_unlock_function = 6, | |||
7072 | CXX11_clang_unlock_function = 7 | |||
7073 | }; | |||
7074 | ||||
7075 | static ReleaseCapabilityAttr *CreateImplicit(ASTContext &Ctx, Spelling S, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) { | |||
7076 | auto *A = new (Ctx) ReleaseCapabilityAttr(Loc, Ctx, Args, ArgsSize, S); | |||
7077 | A->setImplicit(true); | |||
7078 | return A; | |||
7079 | } | |||
7080 | ||||
7081 | ReleaseCapabilityAttr(SourceRange R, ASTContext &Ctx | |||
7082 | , Expr * *Args, unsigned ArgsSize | |||
7083 | , unsigned SI | |||
7084 | ) | |||
7085 | : InheritableAttr(attr::ReleaseCapability, R, SI, true, true) | |||
7086 | , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size]) | |||
7087 | { | |||
7088 | std::copy(Args, Args + args_Size, args_); | |||
7089 | } | |||
7090 | ||||
7091 | ReleaseCapabilityAttr(SourceRange R, ASTContext &Ctx | |||
7092 | , unsigned SI | |||
7093 | ) | |||
7094 | : InheritableAttr(attr::ReleaseCapability, R, SI, true, true) | |||
7095 | , args_Size(0), args_(nullptr) | |||
7096 | { | |||
7097 | } | |||
7098 | ||||
7099 | ReleaseCapabilityAttr *clone(ASTContext &C) const; | |||
7100 | void printPretty(raw_ostream &OS, | |||
7101 | const PrintingPolicy &Policy) const; | |||
7102 | const char *getSpelling() const; | |||
7103 | Spelling getSemanticSpelling() const { | |||
7104 | switch (SpellingListIndex) { | |||
7105 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 7105); | |||
7106 | case 0: return GNU_release_capability; | |||
7107 | case 1: return CXX11_clang_release_capability; | |||
7108 | case 2: return GNU_release_shared_capability; | |||
7109 | case 3: return CXX11_clang_release_shared_capability; | |||
7110 | case 4: return GNU_release_generic_capability; | |||
7111 | case 5: return CXX11_clang_release_generic_capability; | |||
7112 | case 6: return GNU_unlock_function; | |||
7113 | case 7: return CXX11_clang_unlock_function; | |||
7114 | } | |||
7115 | } | |||
7116 | bool isShared() const { return SpellingListIndex == 2 || | |||
7117 | SpellingListIndex == 3; } | |||
7118 | bool isGeneric() const { return SpellingListIndex == 4 || | |||
7119 | SpellingListIndex == 5 || | |||
7120 | SpellingListIndex == 6 || | |||
7121 | SpellingListIndex == 7; } | |||
7122 | typedef Expr ** args_iterator; | |||
7123 | args_iterator args_begin() const { return args_; } | |||
7124 | args_iterator args_end() const { return args_ + args_Size; } | |||
7125 | unsigned args_size() const { return args_Size; } | |||
7126 | llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); } | |||
7127 | ||||
7128 | ||||
7129 | ||||
7130 | ||||
7131 | static bool classof(const Attr *A) { return A->getKind() == attr::ReleaseCapability; } | |||
7132 | }; | |||
7133 | ||||
7134 | class RenderScriptKernelAttr : public Attr { | |||
7135 | public: | |||
7136 | static RenderScriptKernelAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
7137 | auto *A = new (Ctx) RenderScriptKernelAttr(Loc, Ctx, 0); | |||
7138 | A->setImplicit(true); | |||
7139 | return A; | |||
7140 | } | |||
7141 | ||||
7142 | RenderScriptKernelAttr(SourceRange R, ASTContext &Ctx | |||
7143 | , unsigned SI | |||
7144 | ) | |||
7145 | : Attr(attr::RenderScriptKernel, R, SI, false) | |||
7146 | { | |||
7147 | } | |||
7148 | ||||
7149 | RenderScriptKernelAttr *clone(ASTContext &C) const; | |||
7150 | void printPretty(raw_ostream &OS, | |||
7151 | const PrintingPolicy &Policy) const; | |||
7152 | const char *getSpelling() const; | |||
7153 | ||||
7154 | ||||
7155 | static bool classof(const Attr *A) { return A->getKind() == attr::RenderScriptKernel; } | |||
7156 | }; | |||
7157 | ||||
7158 | class ReqdWorkGroupSizeAttr : public InheritableAttr { | |||
7159 | unsigned xDim; | |||
7160 | ||||
7161 | unsigned yDim; | |||
7162 | ||||
7163 | unsigned zDim; | |||
7164 | ||||
7165 | public: | |||
7166 | static ReqdWorkGroupSizeAttr *CreateImplicit(ASTContext &Ctx, unsigned XDim, unsigned YDim, unsigned ZDim, SourceRange Loc = SourceRange()) { | |||
7167 | auto *A = new (Ctx) ReqdWorkGroupSizeAttr(Loc, Ctx, XDim, YDim, ZDim, 0); | |||
7168 | A->setImplicit(true); | |||
7169 | return A; | |||
7170 | } | |||
7171 | ||||
7172 | ReqdWorkGroupSizeAttr(SourceRange R, ASTContext &Ctx | |||
7173 | , unsigned XDim | |||
7174 | , unsigned YDim | |||
7175 | , unsigned ZDim | |||
7176 | , unsigned SI | |||
7177 | ) | |||
7178 | : InheritableAttr(attr::ReqdWorkGroupSize, R, SI, false, false) | |||
7179 | , xDim(XDim) | |||
7180 | , yDim(YDim) | |||
7181 | , zDim(ZDim) | |||
7182 | { | |||
7183 | } | |||
7184 | ||||
7185 | ReqdWorkGroupSizeAttr *clone(ASTContext &C) const; | |||
7186 | void printPretty(raw_ostream &OS, | |||
7187 | const PrintingPolicy &Policy) const; | |||
7188 | const char *getSpelling() const; | |||
7189 | unsigned getXDim() const { | |||
7190 | return xDim; | |||
7191 | } | |||
7192 | ||||
7193 | unsigned getYDim() const { | |||
7194 | return yDim; | |||
7195 | } | |||
7196 | ||||
7197 | unsigned getZDim() const { | |||
7198 | return zDim; | |||
7199 | } | |||
7200 | ||||
7201 | ||||
7202 | ||||
7203 | static bool classof(const Attr *A) { return A->getKind() == attr::ReqdWorkGroupSize; } | |||
7204 | }; | |||
7205 | ||||
7206 | class RequireConstantInitAttr : public InheritableAttr { | |||
7207 | public: | |||
7208 | static RequireConstantInitAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
7209 | auto *A = new (Ctx) RequireConstantInitAttr(Loc, Ctx, 0); | |||
7210 | A->setImplicit(true); | |||
7211 | return A; | |||
7212 | } | |||
7213 | ||||
7214 | RequireConstantInitAttr(SourceRange R, ASTContext &Ctx | |||
7215 | , unsigned SI | |||
7216 | ) | |||
7217 | : InheritableAttr(attr::RequireConstantInit, R, SI, false, false) | |||
7218 | { | |||
7219 | } | |||
7220 | ||||
7221 | RequireConstantInitAttr *clone(ASTContext &C) const; | |||
7222 | void printPretty(raw_ostream &OS, | |||
7223 | const PrintingPolicy &Policy) const; | |||
7224 | const char *getSpelling() const; | |||
7225 | ||||
7226 | ||||
7227 | static bool classof(const Attr *A) { return A->getKind() == attr::RequireConstantInit; } | |||
7228 | }; | |||
7229 | ||||
7230 | class RequiresCapabilityAttr : public InheritableAttr { | |||
7231 | unsigned args_Size; | |||
7232 | Expr * *args_; | |||
7233 | ||||
7234 | public: | |||
7235 | enum Spelling { | |||
7236 | GNU_requires_capability = 0, | |||
7237 | CXX11_clang_requires_capability = 1, | |||
7238 | GNU_exclusive_locks_required = 2, | |||
7239 | CXX11_clang_exclusive_locks_required = 3, | |||
7240 | GNU_requires_shared_capability = 4, | |||
7241 | CXX11_clang_requires_shared_capability = 5, | |||
7242 | GNU_shared_locks_required = 6, | |||
7243 | CXX11_clang_shared_locks_required = 7 | |||
7244 | }; | |||
7245 | ||||
7246 | static RequiresCapabilityAttr *CreateImplicit(ASTContext &Ctx, Spelling S, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) { | |||
7247 | auto *A = new (Ctx) RequiresCapabilityAttr(Loc, Ctx, Args, ArgsSize, S); | |||
7248 | A->setImplicit(true); | |||
7249 | return A; | |||
7250 | } | |||
7251 | ||||
7252 | RequiresCapabilityAttr(SourceRange R, ASTContext &Ctx | |||
7253 | , Expr * *Args, unsigned ArgsSize | |||
7254 | , unsigned SI | |||
7255 | ) | |||
7256 | : InheritableAttr(attr::RequiresCapability, R, SI, true, true) | |||
7257 | , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size]) | |||
7258 | { | |||
7259 | std::copy(Args, Args + args_Size, args_); | |||
7260 | } | |||
7261 | ||||
7262 | RequiresCapabilityAttr(SourceRange R, ASTContext &Ctx | |||
7263 | , unsigned SI | |||
7264 | ) | |||
7265 | : InheritableAttr(attr::RequiresCapability, R, SI, true, true) | |||
7266 | , args_Size(0), args_(nullptr) | |||
7267 | { | |||
7268 | } | |||
7269 | ||||
7270 | RequiresCapabilityAttr *clone(ASTContext &C) const; | |||
7271 | void printPretty(raw_ostream &OS, | |||
7272 | const PrintingPolicy &Policy) const; | |||
7273 | const char *getSpelling() const; | |||
7274 | Spelling getSemanticSpelling() const { | |||
7275 | switch (SpellingListIndex) { | |||
7276 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 7276); | |||
7277 | case 0: return GNU_requires_capability; | |||
7278 | case 1: return CXX11_clang_requires_capability; | |||
7279 | case 2: return GNU_exclusive_locks_required; | |||
7280 | case 3: return CXX11_clang_exclusive_locks_required; | |||
7281 | case 4: return GNU_requires_shared_capability; | |||
7282 | case 5: return CXX11_clang_requires_shared_capability; | |||
7283 | case 6: return GNU_shared_locks_required; | |||
7284 | case 7: return CXX11_clang_shared_locks_required; | |||
7285 | } | |||
7286 | } | |||
7287 | bool isShared() const { return SpellingListIndex == 4 || | |||
7288 | SpellingListIndex == 5 || | |||
7289 | SpellingListIndex == 6 || | |||
7290 | SpellingListIndex == 7; } | |||
7291 | typedef Expr ** args_iterator; | |||
7292 | args_iterator args_begin() const { return args_; } | |||
7293 | args_iterator args_end() const { return args_ + args_Size; } | |||
7294 | unsigned args_size() const { return args_Size; } | |||
7295 | llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); } | |||
7296 | ||||
7297 | ||||
7298 | ||||
7299 | ||||
7300 | static bool classof(const Attr *A) { return A->getKind() == attr::RequiresCapability; } | |||
7301 | }; | |||
7302 | ||||
7303 | class RestrictAttr : public InheritableAttr { | |||
7304 | public: | |||
7305 | enum Spelling { | |||
7306 | Declspec_restrict = 0, | |||
7307 | GNU_malloc = 1, | |||
7308 | CXX11_gnu_malloc = 2 | |||
7309 | }; | |||
7310 | ||||
7311 | static RestrictAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) { | |||
7312 | auto *A = new (Ctx) RestrictAttr(Loc, Ctx, S); | |||
7313 | A->setImplicit(true); | |||
7314 | return A; | |||
7315 | } | |||
7316 | ||||
7317 | RestrictAttr(SourceRange R, ASTContext &Ctx | |||
7318 | , unsigned SI | |||
7319 | ) | |||
7320 | : InheritableAttr(attr::Restrict, R, SI, false, false) | |||
7321 | { | |||
7322 | } | |||
7323 | ||||
7324 | RestrictAttr *clone(ASTContext &C) const; | |||
7325 | void printPretty(raw_ostream &OS, | |||
7326 | const PrintingPolicy &Policy) const; | |||
7327 | const char *getSpelling() const; | |||
7328 | Spelling getSemanticSpelling() const { | |||
7329 | switch (SpellingListIndex) { | |||
7330 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 7330); | |||
7331 | case 0: return Declspec_restrict; | |||
7332 | case 1: return GNU_malloc; | |||
7333 | case 2: return CXX11_gnu_malloc; | |||
7334 | } | |||
7335 | } | |||
7336 | ||||
7337 | ||||
7338 | static bool classof(const Attr *A) { return A->getKind() == attr::Restrict; } | |||
7339 | }; | |||
7340 | ||||
7341 | class ReturnTypestateAttr : public InheritableAttr { | |||
7342 | public: | |||
7343 | enum ConsumedState { | |||
7344 | Unknown, | |||
7345 | Consumed, | |||
7346 | Unconsumed | |||
7347 | }; | |||
7348 | private: | |||
7349 | ConsumedState state; | |||
7350 | ||||
7351 | public: | |||
7352 | static ReturnTypestateAttr *CreateImplicit(ASTContext &Ctx, ConsumedState State, SourceRange Loc = SourceRange()) { | |||
7353 | auto *A = new (Ctx) ReturnTypestateAttr(Loc, Ctx, State, 0); | |||
7354 | A->setImplicit(true); | |||
7355 | return A; | |||
7356 | } | |||
7357 | ||||
7358 | ReturnTypestateAttr(SourceRange R, ASTContext &Ctx | |||
7359 | , ConsumedState State | |||
7360 | , unsigned SI | |||
7361 | ) | |||
7362 | : InheritableAttr(attr::ReturnTypestate, R, SI, false, false) | |||
7363 | , state(State) | |||
7364 | { | |||
7365 | } | |||
7366 | ||||
7367 | ReturnTypestateAttr *clone(ASTContext &C) const; | |||
7368 | void printPretty(raw_ostream &OS, | |||
7369 | const PrintingPolicy &Policy) const; | |||
7370 | const char *getSpelling() const; | |||
7371 | ConsumedState getState() const { | |||
7372 | return state; | |||
7373 | } | |||
7374 | ||||
7375 | static bool ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) { | |||
7376 | Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val) | |||
7377 | .Case("unknown", ReturnTypestateAttr::Unknown) | |||
7378 | .Case("consumed", ReturnTypestateAttr::Consumed) | |||
7379 | .Case("unconsumed", ReturnTypestateAttr::Unconsumed) | |||
7380 | .Default(Optional<ConsumedState>()); | |||
7381 | if (R) { | |||
7382 | Out = *R; | |||
7383 | return true; | |||
7384 | } | |||
7385 | return false; | |||
7386 | } | |||
7387 | ||||
7388 | static const char *ConvertConsumedStateToStr(ConsumedState Val) { | |||
7389 | switch(Val) { | |||
7390 | case ReturnTypestateAttr::Unknown: return "unknown"; | |||
7391 | case ReturnTypestateAttr::Consumed: return "consumed"; | |||
7392 | case ReturnTypestateAttr::Unconsumed: return "unconsumed"; | |||
7393 | } | |||
7394 | llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 7394); | |||
7395 | } | |||
7396 | ||||
7397 | ||||
7398 | static bool classof(const Attr *A) { return A->getKind() == attr::ReturnTypestate; } | |||
7399 | }; | |||
7400 | ||||
7401 | class ReturnsNonNullAttr : public InheritableAttr { | |||
7402 | public: | |||
7403 | static ReturnsNonNullAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
7404 | auto *A = new (Ctx) ReturnsNonNullAttr(Loc, Ctx, 0); | |||
7405 | A->setImplicit(true); | |||
7406 | return A; | |||
7407 | } | |||
7408 | ||||
7409 | ReturnsNonNullAttr(SourceRange R, ASTContext &Ctx | |||
7410 | , unsigned SI | |||
7411 | ) | |||
7412 | : InheritableAttr(attr::ReturnsNonNull, R, SI, false, false) | |||
7413 | { | |||
7414 | } | |||
7415 | ||||
7416 | ReturnsNonNullAttr *clone(ASTContext &C) const; | |||
7417 | void printPretty(raw_ostream &OS, | |||
7418 | const PrintingPolicy &Policy) const; | |||
7419 | const char *getSpelling() const; | |||
7420 | ||||
7421 | ||||
7422 | static bool classof(const Attr *A) { return A->getKind() == attr::ReturnsNonNull; } | |||
7423 | }; | |||
7424 | ||||
7425 | class ReturnsTwiceAttr : public InheritableAttr { | |||
7426 | public: | |||
7427 | static ReturnsTwiceAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
7428 | auto *A = new (Ctx) ReturnsTwiceAttr(Loc, Ctx, 0); | |||
7429 | A->setImplicit(true); | |||
7430 | return A; | |||
7431 | } | |||
7432 | ||||
7433 | ReturnsTwiceAttr(SourceRange R, ASTContext &Ctx | |||
7434 | , unsigned SI | |||
7435 | ) | |||
7436 | : InheritableAttr(attr::ReturnsTwice, R, SI, false, false) | |||
7437 | { | |||
7438 | } | |||
7439 | ||||
7440 | ReturnsTwiceAttr *clone(ASTContext &C) const; | |||
7441 | void printPretty(raw_ostream &OS, | |||
7442 | const PrintingPolicy &Policy) const; | |||
7443 | const char *getSpelling() const; | |||
7444 | ||||
7445 | ||||
7446 | static bool classof(const Attr *A) { return A->getKind() == attr::ReturnsTwice; } | |||
7447 | }; | |||
7448 | ||||
7449 | class ScopedLockableAttr : public InheritableAttr { | |||
7450 | public: | |||
7451 | static ScopedLockableAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
7452 | auto *A = new (Ctx) ScopedLockableAttr(Loc, Ctx, 0); | |||
7453 | A->setImplicit(true); | |||
7454 | return A; | |||
7455 | } | |||
7456 | ||||
7457 | ScopedLockableAttr(SourceRange R, ASTContext &Ctx | |||
7458 | , unsigned SI | |||
7459 | ) | |||
7460 | : InheritableAttr(attr::ScopedLockable, R, SI, false, false) | |||
7461 | { | |||
7462 | } | |||
7463 | ||||
7464 | ScopedLockableAttr *clone(ASTContext &C) const; | |||
7465 | void printPretty(raw_ostream &OS, | |||
7466 | const PrintingPolicy &Policy) const; | |||
7467 | const char *getSpelling() const; | |||
7468 | ||||
7469 | ||||
7470 | static bool classof(const Attr *A) { return A->getKind() == attr::ScopedLockable; } | |||
7471 | }; | |||
7472 | ||||
7473 | class SectionAttr : public InheritableAttr { | |||
7474 | unsigned nameLength; | |||
7475 | char *name; | |||
7476 | ||||
7477 | public: | |||
7478 | enum Spelling { | |||
7479 | GNU_section = 0, | |||
7480 | CXX11_gnu_section = 1, | |||
7481 | Declspec_allocate = 2 | |||
7482 | }; | |||
7483 | ||||
7484 | static SectionAttr *CreateImplicit(ASTContext &Ctx, Spelling S, llvm::StringRef Name, SourceRange Loc = SourceRange()) { | |||
7485 | auto *A = new (Ctx) SectionAttr(Loc, Ctx, Name, S); | |||
7486 | A->setImplicit(true); | |||
7487 | return A; | |||
7488 | } | |||
7489 | ||||
7490 | SectionAttr(SourceRange R, ASTContext &Ctx | |||
7491 | , llvm::StringRef Name | |||
7492 | , unsigned SI | |||
7493 | ) | |||
7494 | : InheritableAttr(attr::Section, R, SI, false, false) | |||
7495 | , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength]) | |||
7496 | { | |||
7497 | if (!Name.empty()) | |||
7498 | std::memcpy(name, Name.data(), nameLength); | |||
7499 | } | |||
7500 | ||||
7501 | SectionAttr *clone(ASTContext &C) const; | |||
7502 | void printPretty(raw_ostream &OS, | |||
7503 | const PrintingPolicy &Policy) const; | |||
7504 | const char *getSpelling() const; | |||
7505 | Spelling getSemanticSpelling() const { | |||
7506 | switch (SpellingListIndex) { | |||
7507 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 7507); | |||
7508 | case 0: return GNU_section; | |||
7509 | case 1: return CXX11_gnu_section; | |||
7510 | case 2: return Declspec_allocate; | |||
7511 | } | |||
7512 | } | |||
7513 | llvm::StringRef getName() const { | |||
7514 | return llvm::StringRef(name, nameLength); | |||
7515 | } | |||
7516 | unsigned getNameLength() const { | |||
7517 | return nameLength; | |||
7518 | } | |||
7519 | void setName(ASTContext &C, llvm::StringRef S) { | |||
7520 | nameLength = S.size(); | |||
7521 | this->name = new (C, 1) char [nameLength]; | |||
7522 | if (!S.empty()) | |||
7523 | std::memcpy(this->name, S.data(), nameLength); | |||
7524 | } | |||
7525 | ||||
7526 | ||||
7527 | ||||
7528 | static bool classof(const Attr *A) { return A->getKind() == attr::Section; } | |||
7529 | }; | |||
7530 | ||||
7531 | class SelectAnyAttr : public InheritableAttr { | |||
7532 | public: | |||
7533 | static SelectAnyAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
7534 | auto *A = new (Ctx) SelectAnyAttr(Loc, Ctx, 0); | |||
7535 | A->setImplicit(true); | |||
7536 | return A; | |||
7537 | } | |||
7538 | ||||
7539 | SelectAnyAttr(SourceRange R, ASTContext &Ctx | |||
7540 | , unsigned SI | |||
7541 | ) | |||
7542 | : InheritableAttr(attr::SelectAny, R, SI, false, false) | |||
7543 | { | |||
7544 | } | |||
7545 | ||||
7546 | SelectAnyAttr *clone(ASTContext &C) const; | |||
7547 | void printPretty(raw_ostream &OS, | |||
7548 | const PrintingPolicy &Policy) const; | |||
7549 | const char *getSpelling() const; | |||
7550 | ||||
7551 | ||||
7552 | static bool classof(const Attr *A) { return A->getKind() == attr::SelectAny; } | |||
7553 | }; | |||
7554 | ||||
7555 | class SentinelAttr : public InheritableAttr { | |||
7556 | int sentinel; | |||
7557 | ||||
7558 | int nullPos; | |||
7559 | ||||
7560 | public: | |||
7561 | static SentinelAttr *CreateImplicit(ASTContext &Ctx, int Sentinel, int NullPos, SourceRange Loc = SourceRange()) { | |||
7562 | auto *A = new (Ctx) SentinelAttr(Loc, Ctx, Sentinel, NullPos, 0); | |||
7563 | A->setImplicit(true); | |||
7564 | return A; | |||
7565 | } | |||
7566 | ||||
7567 | SentinelAttr(SourceRange R, ASTContext &Ctx | |||
7568 | , int Sentinel | |||
7569 | , int NullPos | |||
7570 | , unsigned SI | |||
7571 | ) | |||
7572 | : InheritableAttr(attr::Sentinel, R, SI, false, false) | |||
7573 | , sentinel(Sentinel) | |||
7574 | , nullPos(NullPos) | |||
7575 | { | |||
7576 | } | |||
7577 | ||||
7578 | SentinelAttr(SourceRange R, ASTContext &Ctx | |||
7579 | , unsigned SI | |||
7580 | ) | |||
7581 | : InheritableAttr(attr::Sentinel, R, SI, false, false) | |||
7582 | , sentinel() | |||
7583 | , nullPos() | |||
7584 | { | |||
7585 | } | |||
7586 | ||||
7587 | SentinelAttr *clone(ASTContext &C) const; | |||
7588 | void printPretty(raw_ostream &OS, | |||
7589 | const PrintingPolicy &Policy) const; | |||
7590 | const char *getSpelling() const; | |||
7591 | int getSentinel() const { | |||
7592 | return sentinel; | |||
7593 | } | |||
7594 | ||||
7595 | static const int DefaultSentinel = 0; | |||
7596 | ||||
7597 | int getNullPos() const { | |||
7598 | return nullPos; | |||
7599 | } | |||
7600 | ||||
7601 | static const int DefaultNullPos = 0; | |||
7602 | ||||
7603 | ||||
7604 | ||||
7605 | static bool classof(const Attr *A) { return A->getKind() == attr::Sentinel; } | |||
7606 | }; | |||
7607 | ||||
7608 | class SetTypestateAttr : public InheritableAttr { | |||
7609 | public: | |||
7610 | enum ConsumedState { | |||
7611 | Unknown, | |||
7612 | Consumed, | |||
7613 | Unconsumed | |||
7614 | }; | |||
7615 | private: | |||
7616 | ConsumedState newState; | |||
7617 | ||||
7618 | public: | |||
7619 | static SetTypestateAttr *CreateImplicit(ASTContext &Ctx, ConsumedState NewState, SourceRange Loc = SourceRange()) { | |||
7620 | auto *A = new (Ctx) SetTypestateAttr(Loc, Ctx, NewState, 0); | |||
7621 | A->setImplicit(true); | |||
7622 | return A; | |||
7623 | } | |||
7624 | ||||
7625 | SetTypestateAttr(SourceRange R, ASTContext &Ctx | |||
7626 | , ConsumedState NewState | |||
7627 | , unsigned SI | |||
7628 | ) | |||
7629 | : InheritableAttr(attr::SetTypestate, R, SI, false, false) | |||
7630 | , newState(NewState) | |||
7631 | { | |||
7632 | } | |||
7633 | ||||
7634 | SetTypestateAttr *clone(ASTContext &C) const; | |||
7635 | void printPretty(raw_ostream &OS, | |||
7636 | const PrintingPolicy &Policy) const; | |||
7637 | const char *getSpelling() const; | |||
7638 | ConsumedState getNewState() const { | |||
7639 | return newState; | |||
7640 | } | |||
7641 | ||||
7642 | static bool ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) { | |||
7643 | Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val) | |||
7644 | .Case("unknown", SetTypestateAttr::Unknown) | |||
7645 | .Case("consumed", SetTypestateAttr::Consumed) | |||
7646 | .Case("unconsumed", SetTypestateAttr::Unconsumed) | |||
7647 | .Default(Optional<ConsumedState>()); | |||
7648 | if (R) { | |||
7649 | Out = *R; | |||
7650 | return true; | |||
7651 | } | |||
7652 | return false; | |||
7653 | } | |||
7654 | ||||
7655 | static const char *ConvertConsumedStateToStr(ConsumedState Val) { | |||
7656 | switch(Val) { | |||
7657 | case SetTypestateAttr::Unknown: return "unknown"; | |||
7658 | case SetTypestateAttr::Consumed: return "consumed"; | |||
7659 | case SetTypestateAttr::Unconsumed: return "unconsumed"; | |||
7660 | } | |||
7661 | llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 7661); | |||
7662 | } | |||
7663 | ||||
7664 | ||||
7665 | static bool classof(const Attr *A) { return A->getKind() == attr::SetTypestate; } | |||
7666 | }; | |||
7667 | ||||
7668 | class SharedTrylockFunctionAttr : public InheritableAttr { | |||
7669 | Expr * successValue; | |||
7670 | ||||
7671 | unsigned args_Size; | |||
7672 | Expr * *args_; | |||
7673 | ||||
7674 | public: | |||
7675 | static SharedTrylockFunctionAttr *CreateImplicit(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) { | |||
7676 | auto *A = new (Ctx) SharedTrylockFunctionAttr(Loc, Ctx, SuccessValue, Args, ArgsSize, 0); | |||
7677 | A->setImplicit(true); | |||
7678 | return A; | |||
7679 | } | |||
7680 | ||||
7681 | SharedTrylockFunctionAttr(SourceRange R, ASTContext &Ctx | |||
7682 | , Expr * SuccessValue | |||
7683 | , Expr * *Args, unsigned ArgsSize | |||
7684 | , unsigned SI | |||
7685 | ) | |||
7686 | : InheritableAttr(attr::SharedTrylockFunction, R, SI, true, true) | |||
7687 | , successValue(SuccessValue) | |||
7688 | , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size]) | |||
7689 | { | |||
7690 | std::copy(Args, Args + args_Size, args_); | |||
7691 | } | |||
7692 | ||||
7693 | SharedTrylockFunctionAttr(SourceRange R, ASTContext &Ctx | |||
7694 | , Expr * SuccessValue | |||
7695 | , unsigned SI | |||
7696 | ) | |||
7697 | : InheritableAttr(attr::SharedTrylockFunction, R, SI, true, true) | |||
7698 | , successValue(SuccessValue) | |||
7699 | , args_Size(0), args_(nullptr) | |||
7700 | { | |||
7701 | } | |||
7702 | ||||
7703 | SharedTrylockFunctionAttr *clone(ASTContext &C) const; | |||
7704 | void printPretty(raw_ostream &OS, | |||
7705 | const PrintingPolicy &Policy) const; | |||
7706 | const char *getSpelling() const; | |||
7707 | Expr * getSuccessValue() const { | |||
7708 | return successValue; | |||
7709 | } | |||
7710 | ||||
7711 | typedef Expr ** args_iterator; | |||
7712 | args_iterator args_begin() const { return args_; } | |||
7713 | args_iterator args_end() const { return args_ + args_Size; } | |||
7714 | unsigned args_size() const { return args_Size; } | |||
7715 | llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); } | |||
7716 | ||||
7717 | ||||
7718 | ||||
7719 | ||||
7720 | static bool classof(const Attr *A) { return A->getKind() == attr::SharedTrylockFunction; } | |||
7721 | }; | |||
7722 | ||||
7723 | class StdCallAttr : public InheritableAttr { | |||
7724 | public: | |||
7725 | static StdCallAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
7726 | auto *A = new (Ctx) StdCallAttr(Loc, Ctx, 0); | |||
7727 | A->setImplicit(true); | |||
7728 | return A; | |||
7729 | } | |||
7730 | ||||
7731 | StdCallAttr(SourceRange R, ASTContext &Ctx | |||
7732 | , unsigned SI | |||
7733 | ) | |||
7734 | : InheritableAttr(attr::StdCall, R, SI, false, false) | |||
7735 | { | |||
7736 | } | |||
7737 | ||||
7738 | StdCallAttr *clone(ASTContext &C) const; | |||
7739 | void printPretty(raw_ostream &OS, | |||
7740 | const PrintingPolicy &Policy) const; | |||
7741 | const char *getSpelling() const; | |||
7742 | ||||
7743 | ||||
7744 | static bool classof(const Attr *A) { return A->getKind() == attr::StdCall; } | |||
7745 | }; | |||
7746 | ||||
7747 | class SuppressAttr : public StmtAttr { | |||
7748 | unsigned diagnosticIdentifiers_Size; | |||
7749 | StringRef *diagnosticIdentifiers_; | |||
7750 | ||||
7751 | public: | |||
7752 | static SuppressAttr *CreateImplicit(ASTContext &Ctx, StringRef *DiagnosticIdentifiers, unsigned DiagnosticIdentifiersSize, SourceRange Loc = SourceRange()) { | |||
7753 | auto *A = new (Ctx) SuppressAttr(Loc, Ctx, DiagnosticIdentifiers, DiagnosticIdentifiersSize, 0); | |||
7754 | A->setImplicit(true); | |||
7755 | return A; | |||
7756 | } | |||
7757 | ||||
7758 | SuppressAttr(SourceRange R, ASTContext &Ctx | |||
7759 | , StringRef *DiagnosticIdentifiers, unsigned DiagnosticIdentifiersSize | |||
7760 | , unsigned SI | |||
7761 | ) | |||
7762 | : StmtAttr(attr::Suppress, R, SI, false) | |||
7763 | , diagnosticIdentifiers_Size(DiagnosticIdentifiersSize), diagnosticIdentifiers_(new (Ctx, 16) StringRef[diagnosticIdentifiers_Size]) | |||
7764 | { | |||
7765 | for (size_t I = 0, E = diagnosticIdentifiers_Size; I != E; | |||
7766 | ++I) { | |||
7767 | StringRef Ref = DiagnosticIdentifiers[I]; | |||
7768 | if (!Ref.empty()) { | |||
7769 | char *Mem = new (Ctx, 1) char[Ref.size()]; | |||
7770 | std::memcpy(Mem, Ref.data(), Ref.size()); | |||
7771 | diagnosticIdentifiers_[I] = StringRef(Mem, Ref.size()); | |||
7772 | } | |||
7773 | } | |||
7774 | } | |||
7775 | ||||
7776 | SuppressAttr(SourceRange R, ASTContext &Ctx | |||
7777 | , unsigned SI | |||
7778 | ) | |||
7779 | : StmtAttr(attr::Suppress, R, SI, false) | |||
7780 | , diagnosticIdentifiers_Size(0), diagnosticIdentifiers_(nullptr) | |||
7781 | { | |||
7782 | } | |||
7783 | ||||
7784 | SuppressAttr *clone(ASTContext &C) const; | |||
7785 | void printPretty(raw_ostream &OS, | |||
7786 | const PrintingPolicy &Policy) const; | |||
7787 | const char *getSpelling() const; | |||
7788 | typedef StringRef* diagnosticIdentifiers_iterator; | |||
7789 | diagnosticIdentifiers_iterator diagnosticIdentifiers_begin() const { return diagnosticIdentifiers_; } | |||
7790 | diagnosticIdentifiers_iterator diagnosticIdentifiers_end() const { return diagnosticIdentifiers_ + diagnosticIdentifiers_Size; } | |||
7791 | unsigned diagnosticIdentifiers_size() const { return diagnosticIdentifiers_Size; } | |||
7792 | llvm::iterator_range<diagnosticIdentifiers_iterator> diagnosticIdentifiers() const { return llvm::make_range(diagnosticIdentifiers_begin(), diagnosticIdentifiers_end()); } | |||
7793 | ||||
7794 | ||||
7795 | ||||
7796 | ||||
7797 | static bool classof(const Attr *A) { return A->getKind() == attr::Suppress; } | |||
7798 | }; | |||
7799 | ||||
7800 | class SwiftCallAttr : public InheritableAttr { | |||
7801 | public: | |||
7802 | static SwiftCallAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
7803 | auto *A = new (Ctx) SwiftCallAttr(Loc, Ctx, 0); | |||
7804 | A->setImplicit(true); | |||
7805 | return A; | |||
7806 | } | |||
7807 | ||||
7808 | SwiftCallAttr(SourceRange R, ASTContext &Ctx | |||
7809 | , unsigned SI | |||
7810 | ) | |||
7811 | : InheritableAttr(attr::SwiftCall, R, SI, false, false) | |||
7812 | { | |||
7813 | } | |||
7814 | ||||
7815 | SwiftCallAttr *clone(ASTContext &C) const; | |||
7816 | void printPretty(raw_ostream &OS, | |||
7817 | const PrintingPolicy &Policy) const; | |||
7818 | const char *getSpelling() const; | |||
7819 | ||||
7820 | ||||
7821 | static bool classof(const Attr *A) { return A->getKind() == attr::SwiftCall; } | |||
7822 | }; | |||
7823 | ||||
7824 | class SwiftContextAttr : public ParameterABIAttr { | |||
7825 | public: | |||
7826 | static SwiftContextAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
7827 | auto *A = new (Ctx) SwiftContextAttr(Loc, Ctx, 0); | |||
7828 | A->setImplicit(true); | |||
7829 | return A; | |||
7830 | } | |||
7831 | ||||
7832 | SwiftContextAttr(SourceRange R, ASTContext &Ctx | |||
7833 | , unsigned SI | |||
7834 | ) | |||
7835 | : ParameterABIAttr(attr::SwiftContext, R, SI, false, false) | |||
7836 | { | |||
7837 | } | |||
7838 | ||||
7839 | SwiftContextAttr *clone(ASTContext &C) const; | |||
7840 | void printPretty(raw_ostream &OS, | |||
7841 | const PrintingPolicy &Policy) const; | |||
7842 | const char *getSpelling() const; | |||
7843 | ||||
7844 | ||||
7845 | static bool classof(const Attr *A) { return A->getKind() == attr::SwiftContext; } | |||
7846 | }; | |||
7847 | ||||
7848 | class SwiftErrorResultAttr : public ParameterABIAttr { | |||
7849 | public: | |||
7850 | static SwiftErrorResultAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
7851 | auto *A = new (Ctx) SwiftErrorResultAttr(Loc, Ctx, 0); | |||
7852 | A->setImplicit(true); | |||
7853 | return A; | |||
7854 | } | |||
7855 | ||||
7856 | SwiftErrorResultAttr(SourceRange R, ASTContext &Ctx | |||
7857 | , unsigned SI | |||
7858 | ) | |||
7859 | : ParameterABIAttr(attr::SwiftErrorResult, R, SI, false, false) | |||
7860 | { | |||
7861 | } | |||
7862 | ||||
7863 | SwiftErrorResultAttr *clone(ASTContext &C) const; | |||
7864 | void printPretty(raw_ostream &OS, | |||
7865 | const PrintingPolicy &Policy) const; | |||
7866 | const char *getSpelling() const; | |||
7867 | ||||
7868 | ||||
7869 | static bool classof(const Attr *A) { return A->getKind() == attr::SwiftErrorResult; } | |||
7870 | }; | |||
7871 | ||||
7872 | class SwiftIndirectResultAttr : public ParameterABIAttr { | |||
7873 | public: | |||
7874 | static SwiftIndirectResultAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
7875 | auto *A = new (Ctx) SwiftIndirectResultAttr(Loc, Ctx, 0); | |||
7876 | A->setImplicit(true); | |||
7877 | return A; | |||
7878 | } | |||
7879 | ||||
7880 | SwiftIndirectResultAttr(SourceRange R, ASTContext &Ctx | |||
7881 | , unsigned SI | |||
7882 | ) | |||
7883 | : ParameterABIAttr(attr::SwiftIndirectResult, R, SI, false, false) | |||
7884 | { | |||
7885 | } | |||
7886 | ||||
7887 | SwiftIndirectResultAttr *clone(ASTContext &C) const; | |||
7888 | void printPretty(raw_ostream &OS, | |||
7889 | const PrintingPolicy &Policy) const; | |||
7890 | const char *getSpelling() const; | |||
7891 | ||||
7892 | ||||
7893 | static bool classof(const Attr *A) { return A->getKind() == attr::SwiftIndirectResult; } | |||
7894 | }; | |||
7895 | ||||
7896 | class SysVABIAttr : public InheritableAttr { | |||
7897 | public: | |||
7898 | static SysVABIAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
7899 | auto *A = new (Ctx) SysVABIAttr(Loc, Ctx, 0); | |||
7900 | A->setImplicit(true); | |||
7901 | return A; | |||
7902 | } | |||
7903 | ||||
7904 | SysVABIAttr(SourceRange R, ASTContext &Ctx | |||
7905 | , unsigned SI | |||
7906 | ) | |||
7907 | : InheritableAttr(attr::SysVABI, R, SI, false, false) | |||
7908 | { | |||
7909 | } | |||
7910 | ||||
7911 | SysVABIAttr *clone(ASTContext &C) const; | |||
7912 | void printPretty(raw_ostream &OS, | |||
7913 | const PrintingPolicy &Policy) const; | |||
7914 | const char *getSpelling() const; | |||
7915 | ||||
7916 | ||||
7917 | static bool classof(const Attr *A) { return A->getKind() == attr::SysVABI; } | |||
7918 | }; | |||
7919 | ||||
7920 | class TLSModelAttr : public InheritableAttr { | |||
7921 | unsigned modelLength; | |||
7922 | char *model; | |||
7923 | ||||
7924 | public: | |||
7925 | static TLSModelAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Model, SourceRange Loc = SourceRange()) { | |||
7926 | auto *A = new (Ctx) TLSModelAttr(Loc, Ctx, Model, 0); | |||
7927 | A->setImplicit(true); | |||
7928 | return A; | |||
7929 | } | |||
7930 | ||||
7931 | TLSModelAttr(SourceRange R, ASTContext &Ctx | |||
7932 | , llvm::StringRef Model | |||
7933 | , unsigned SI | |||
7934 | ) | |||
7935 | : InheritableAttr(attr::TLSModel, R, SI, false, false) | |||
7936 | , modelLength(Model.size()),model(new (Ctx, 1) char[modelLength]) | |||
7937 | { | |||
7938 | if (!Model.empty()) | |||
7939 | std::memcpy(model, Model.data(), modelLength); | |||
7940 | } | |||
7941 | ||||
7942 | TLSModelAttr *clone(ASTContext &C) const; | |||
7943 | void printPretty(raw_ostream &OS, | |||
7944 | const PrintingPolicy &Policy) const; | |||
7945 | const char *getSpelling() const; | |||
7946 | llvm::StringRef getModel() const { | |||
7947 | return llvm::StringRef(model, modelLength); | |||
7948 | } | |||
7949 | unsigned getModelLength() const { | |||
7950 | return modelLength; | |||
7951 | } | |||
7952 | void setModel(ASTContext &C, llvm::StringRef S) { | |||
7953 | modelLength = S.size(); | |||
7954 | this->model = new (C, 1) char [modelLength]; | |||
7955 | if (!S.empty()) | |||
7956 | std::memcpy(this->model, S.data(), modelLength); | |||
7957 | } | |||
7958 | ||||
7959 | ||||
7960 | ||||
7961 | static bool classof(const Attr *A) { return A->getKind() == attr::TLSModel; } | |||
7962 | }; | |||
7963 | ||||
7964 | class TargetAttr : public InheritableAttr { | |||
7965 | unsigned featuresStrLength; | |||
7966 | char *featuresStr; | |||
7967 | ||||
7968 | public: | |||
7969 | static TargetAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef FeaturesStr, SourceRange Loc = SourceRange()) { | |||
7970 | auto *A = new (Ctx) TargetAttr(Loc, Ctx, FeaturesStr, 0); | |||
7971 | A->setImplicit(true); | |||
7972 | return A; | |||
7973 | } | |||
7974 | ||||
7975 | TargetAttr(SourceRange R, ASTContext &Ctx | |||
7976 | , llvm::StringRef FeaturesStr | |||
7977 | , unsigned SI | |||
7978 | ) | |||
7979 | : InheritableAttr(attr::Target, R, SI, false, false) | |||
7980 | , featuresStrLength(FeaturesStr.size()),featuresStr(new (Ctx, 1) char[featuresStrLength]) | |||
7981 | { | |||
7982 | if (!FeaturesStr.empty()) | |||
7983 | std::memcpy(featuresStr, FeaturesStr.data(), featuresStrLength); | |||
7984 | } | |||
7985 | ||||
7986 | TargetAttr *clone(ASTContext &C) const; | |||
7987 | void printPretty(raw_ostream &OS, | |||
7988 | const PrintingPolicy &Policy) const; | |||
7989 | const char *getSpelling() const; | |||
7990 | llvm::StringRef getFeaturesStr() const { | |||
7991 | return llvm::StringRef(featuresStr, featuresStrLength); | |||
7992 | } | |||
7993 | unsigned getFeaturesStrLength() const { | |||
7994 | return featuresStrLength; | |||
7995 | } | |||
7996 | void setFeaturesStr(ASTContext &C, llvm::StringRef S) { | |||
7997 | featuresStrLength = S.size(); | |||
7998 | this->featuresStr = new (C, 1) char [featuresStrLength]; | |||
7999 | if (!S.empty()) | |||
8000 | std::memcpy(this->featuresStr, S.data(), featuresStrLength); | |||
8001 | } | |||
8002 | ||||
8003 | ||||
8004 | struct ParsedTargetAttr { | |||
8005 | std::vector<std::string> Features; | |||
8006 | StringRef Architecture; | |||
8007 | bool DuplicateArchitecture = false; | |||
8008 | bool operator ==(const ParsedTargetAttr &Other) const { | |||
8009 | return DuplicateArchitecture == Other.DuplicateArchitecture && | |||
8010 | Architecture == Other.Architecture && Features == Other.Features; | |||
8011 | } | |||
8012 | }; | |||
8013 | ParsedTargetAttr parse() const { | |||
8014 | return parse(getFeaturesStr()); | |||
8015 | } | |||
8016 | ||||
8017 | template<class Compare> | |||
8018 | ParsedTargetAttr parse(Compare cmp) const { | |||
8019 | ParsedTargetAttr Attrs = parse(); | |||
8020 | llvm::sort(std::begin(Attrs.Features), std::end(Attrs.Features), cmp); | |||
8021 | return Attrs; | |||
8022 | } | |||
8023 | ||||
8024 | bool isDefaultVersion() const { return getFeaturesStr() == "default"; } | |||
8025 | ||||
8026 | static ParsedTargetAttr parse(StringRef Features) { | |||
8027 | ParsedTargetAttr Ret; | |||
8028 | if (Features == "default") return Ret; | |||
8029 | SmallVector<StringRef, 1> AttrFeatures; | |||
8030 | Features.split(AttrFeatures, ","); | |||
8031 | ||||
8032 | // Grab the various features and prepend a "+" to turn on the feature to | |||
8033 | // the backend and add them to our existing set of features. | |||
8034 | for (auto &Feature : AttrFeatures) { | |||
8035 | // Go ahead and trim whitespace rather than either erroring or | |||
8036 | // accepting it weirdly. | |||
8037 | Feature = Feature.trim(); | |||
8038 | ||||
8039 | // We don't support cpu tuning this way currently. | |||
8040 | // TODO: Support the fpmath option. It will require checking | |||
8041 | // overall feature validity for the function with the rest of the | |||
8042 | // attributes on the function. | |||
8043 | if (Feature.startswith("fpmath=") || Feature.startswith("tune=")) | |||
8044 | continue; | |||
8045 | ||||
8046 | // While we're here iterating check for a different target cpu. | |||
8047 | if (Feature.startswith("arch=")) { | |||
8048 | if (!Ret.Architecture.empty()) | |||
8049 | Ret.DuplicateArchitecture = true; | |||
8050 | else | |||
8051 | Ret.Architecture = Feature.split("=").second.trim(); | |||
8052 | } else if (Feature.startswith("no-")) | |||
8053 | Ret.Features.push_back("-" + Feature.split("-").second.str()); | |||
8054 | else | |||
8055 | Ret.Features.push_back("+" + Feature.str()); | |||
8056 | } | |||
8057 | return Ret; | |||
8058 | } | |||
8059 | ||||
8060 | ||||
8061 | static bool classof(const Attr *A) { return A->getKind() == attr::Target; } | |||
8062 | }; | |||
8063 | ||||
8064 | class TestTypestateAttr : public InheritableAttr { | |||
8065 | public: | |||
8066 | enum ConsumedState { | |||
8067 | Consumed, | |||
8068 | Unconsumed | |||
8069 | }; | |||
8070 | private: | |||
8071 | ConsumedState testState; | |||
8072 | ||||
8073 | public: | |||
8074 | static TestTypestateAttr *CreateImplicit(ASTContext &Ctx, ConsumedState TestState, SourceRange Loc = SourceRange()) { | |||
8075 | auto *A = new (Ctx) TestTypestateAttr(Loc, Ctx, TestState, 0); | |||
8076 | A->setImplicit(true); | |||
8077 | return A; | |||
8078 | } | |||
8079 | ||||
8080 | TestTypestateAttr(SourceRange R, ASTContext &Ctx | |||
8081 | , ConsumedState TestState | |||
8082 | , unsigned SI | |||
8083 | ) | |||
8084 | : InheritableAttr(attr::TestTypestate, R, SI, false, false) | |||
8085 | , testState(TestState) | |||
8086 | { | |||
8087 | } | |||
8088 | ||||
8089 | TestTypestateAttr *clone(ASTContext &C) const; | |||
8090 | void printPretty(raw_ostream &OS, | |||
8091 | const PrintingPolicy &Policy) const; | |||
8092 | const char *getSpelling() const; | |||
8093 | ConsumedState getTestState() const { | |||
8094 | return testState; | |||
8095 | } | |||
8096 | ||||
8097 | static bool ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) { | |||
8098 | Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val) | |||
8099 | .Case("consumed", TestTypestateAttr::Consumed) | |||
8100 | .Case("unconsumed", TestTypestateAttr::Unconsumed) | |||
8101 | .Default(Optional<ConsumedState>()); | |||
8102 | if (R) { | |||
8103 | Out = *R; | |||
8104 | return true; | |||
8105 | } | |||
8106 | return false; | |||
8107 | } | |||
8108 | ||||
8109 | static const char *ConvertConsumedStateToStr(ConsumedState Val) { | |||
8110 | switch(Val) { | |||
8111 | case TestTypestateAttr::Consumed: return "consumed"; | |||
8112 | case TestTypestateAttr::Unconsumed: return "unconsumed"; | |||
8113 | } | |||
8114 | llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 8114); | |||
8115 | } | |||
8116 | ||||
8117 | ||||
8118 | static bool classof(const Attr *A) { return A->getKind() == attr::TestTypestate; } | |||
8119 | }; | |||
8120 | ||||
8121 | class ThisCallAttr : public InheritableAttr { | |||
8122 | public: | |||
8123 | static ThisCallAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
8124 | auto *A = new (Ctx) ThisCallAttr(Loc, Ctx, 0); | |||
8125 | A->setImplicit(true); | |||
8126 | return A; | |||
8127 | } | |||
8128 | ||||
8129 | ThisCallAttr(SourceRange R, ASTContext &Ctx | |||
8130 | , unsigned SI | |||
8131 | ) | |||
8132 | : InheritableAttr(attr::ThisCall, R, SI, false, false) | |||
8133 | { | |||
8134 | } | |||
8135 | ||||
8136 | ThisCallAttr *clone(ASTContext &C) const; | |||
8137 | void printPretty(raw_ostream &OS, | |||
8138 | const PrintingPolicy &Policy) const; | |||
8139 | const char *getSpelling() const; | |||
8140 | ||||
8141 | ||||
8142 | static bool classof(const Attr *A) { return A->getKind() == attr::ThisCall; } | |||
8143 | }; | |||
8144 | ||||
8145 | class ThreadAttr : public Attr { | |||
8146 | public: | |||
8147 | static ThreadAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
8148 | auto *A = new (Ctx) ThreadAttr(Loc, Ctx, 0); | |||
8149 | A->setImplicit(true); | |||
8150 | return A; | |||
8151 | } | |||
8152 | ||||
8153 | ThreadAttr(SourceRange R, ASTContext &Ctx | |||
8154 | , unsigned SI | |||
8155 | ) | |||
8156 | : Attr(attr::Thread, R, SI, false) | |||
8157 | { | |||
8158 | } | |||
8159 | ||||
8160 | ThreadAttr *clone(ASTContext &C) const; | |||
8161 | void printPretty(raw_ostream &OS, | |||
8162 | const PrintingPolicy &Policy) const; | |||
8163 | const char *getSpelling() const; | |||
8164 | ||||
8165 | ||||
8166 | static bool classof(const Attr *A) { return A->getKind() == attr::Thread; } | |||
8167 | }; | |||
8168 | ||||
8169 | class TransparentUnionAttr : public InheritableAttr { | |||
8170 | public: | |||
8171 | static TransparentUnionAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
8172 | auto *A = new (Ctx) TransparentUnionAttr(Loc, Ctx, 0); | |||
8173 | A->setImplicit(true); | |||
8174 | return A; | |||
8175 | } | |||
8176 | ||||
8177 | TransparentUnionAttr(SourceRange R, ASTContext &Ctx | |||
8178 | , unsigned SI | |||
8179 | ) | |||
8180 | : InheritableAttr(attr::TransparentUnion, R, SI, false, false) | |||
8181 | { | |||
8182 | } | |||
8183 | ||||
8184 | TransparentUnionAttr *clone(ASTContext &C) const; | |||
8185 | void printPretty(raw_ostream &OS, | |||
8186 | const PrintingPolicy &Policy) const; | |||
8187 | const char *getSpelling() const; | |||
8188 | ||||
8189 | ||||
8190 | static bool classof(const Attr *A) { return A->getKind() == attr::TransparentUnion; } | |||
8191 | }; | |||
8192 | ||||
8193 | class TrivialABIAttr : public InheritableAttr { | |||
8194 | public: | |||
8195 | static TrivialABIAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
8196 | auto *A = new (Ctx) TrivialABIAttr(Loc, Ctx, 0); | |||
8197 | A->setImplicit(true); | |||
8198 | return A; | |||
8199 | } | |||
8200 | ||||
8201 | TrivialABIAttr(SourceRange R, ASTContext &Ctx | |||
8202 | , unsigned SI | |||
8203 | ) | |||
8204 | : InheritableAttr(attr::TrivialABI, R, SI, false, false) | |||
8205 | { | |||
8206 | } | |||
8207 | ||||
8208 | TrivialABIAttr *clone(ASTContext &C) const; | |||
8209 | void printPretty(raw_ostream &OS, | |||
8210 | const PrintingPolicy &Policy) const; | |||
8211 | const char *getSpelling() const; | |||
8212 | ||||
8213 | ||||
8214 | static bool classof(const Attr *A) { return A->getKind() == attr::TrivialABI; } | |||
8215 | }; | |||
8216 | ||||
8217 | class TryAcquireCapabilityAttr : public InheritableAttr { | |||
8218 | Expr * successValue; | |||
8219 | ||||
8220 | unsigned args_Size; | |||
8221 | Expr * *args_; | |||
8222 | ||||
8223 | public: | |||
8224 | enum Spelling { | |||
8225 | GNU_try_acquire_capability = 0, | |||
8226 | CXX11_clang_try_acquire_capability = 1, | |||
8227 | GNU_try_acquire_shared_capability = 2, | |||
8228 | CXX11_clang_try_acquire_shared_capability = 3 | |||
8229 | }; | |||
8230 | ||||
8231 | static TryAcquireCapabilityAttr *CreateImplicit(ASTContext &Ctx, Spelling S, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) { | |||
8232 | auto *A = new (Ctx) TryAcquireCapabilityAttr(Loc, Ctx, SuccessValue, Args, ArgsSize, S); | |||
8233 | A->setImplicit(true); | |||
8234 | return A; | |||
8235 | } | |||
8236 | ||||
8237 | TryAcquireCapabilityAttr(SourceRange R, ASTContext &Ctx | |||
8238 | , Expr * SuccessValue | |||
8239 | , Expr * *Args, unsigned ArgsSize | |||
8240 | , unsigned SI | |||
8241 | ) | |||
8242 | : InheritableAttr(attr::TryAcquireCapability, R, SI, true, true) | |||
8243 | , successValue(SuccessValue) | |||
8244 | , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size]) | |||
8245 | { | |||
8246 | std::copy(Args, Args + args_Size, args_); | |||
8247 | } | |||
8248 | ||||
8249 | TryAcquireCapabilityAttr(SourceRange R, ASTContext &Ctx | |||
8250 | , Expr * SuccessValue | |||
8251 | , unsigned SI | |||
8252 | ) | |||
8253 | : InheritableAttr(attr::TryAcquireCapability, R, SI, true, true) | |||
8254 | , successValue(SuccessValue) | |||
8255 | , args_Size(0), args_(nullptr) | |||
8256 | { | |||
8257 | } | |||
8258 | ||||
8259 | TryAcquireCapabilityAttr *clone(ASTContext &C) const; | |||
8260 | void printPretty(raw_ostream &OS, | |||
8261 | const PrintingPolicy &Policy) const; | |||
8262 | const char *getSpelling() const; | |||
8263 | Spelling getSemanticSpelling() const { | |||
8264 | switch (SpellingListIndex) { | |||
8265 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 8265); | |||
8266 | case 0: return GNU_try_acquire_capability; | |||
8267 | case 1: return CXX11_clang_try_acquire_capability; | |||
8268 | case 2: return GNU_try_acquire_shared_capability; | |||
8269 | case 3: return CXX11_clang_try_acquire_shared_capability; | |||
8270 | } | |||
8271 | } | |||
8272 | bool isShared() const { return SpellingListIndex == 2 || | |||
8273 | SpellingListIndex == 3; } | |||
8274 | Expr * getSuccessValue() const { | |||
8275 | return successValue; | |||
8276 | } | |||
8277 | ||||
8278 | typedef Expr ** args_iterator; | |||
8279 | args_iterator args_begin() const { return args_; } | |||
8280 | args_iterator args_end() const { return args_ + args_Size; } | |||
8281 | unsigned args_size() const { return args_Size; } | |||
8282 | llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); } | |||
8283 | ||||
8284 | ||||
8285 | ||||
8286 | ||||
8287 | static bool classof(const Attr *A) { return A->getKind() == attr::TryAcquireCapability; } | |||
8288 | }; | |||
8289 | ||||
8290 | class TypeTagForDatatypeAttr : public InheritableAttr { | |||
8291 | IdentifierInfo * argumentKind; | |||
8292 | ||||
8293 | TypeSourceInfo * matchingCType; | |||
8294 | ||||
8295 | bool layoutCompatible; | |||
8296 | ||||
8297 | bool mustBeNull; | |||
8298 | ||||
8299 | public: | |||
8300 | static TypeTagForDatatypeAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * ArgumentKind, TypeSourceInfo * MatchingCType, bool LayoutCompatible, bool MustBeNull, SourceRange Loc = SourceRange()) { | |||
8301 | auto *A = new (Ctx) TypeTagForDatatypeAttr(Loc, Ctx, ArgumentKind, MatchingCType, LayoutCompatible, MustBeNull, 0); | |||
8302 | A->setImplicit(true); | |||
8303 | return A; | |||
8304 | } | |||
8305 | ||||
8306 | TypeTagForDatatypeAttr(SourceRange R, ASTContext &Ctx | |||
8307 | , IdentifierInfo * ArgumentKind | |||
8308 | , TypeSourceInfo * MatchingCType | |||
8309 | , bool LayoutCompatible | |||
8310 | , bool MustBeNull | |||
8311 | , unsigned SI | |||
8312 | ) | |||
8313 | : InheritableAttr(attr::TypeTagForDatatype, R, SI, false, false) | |||
8314 | , argumentKind(ArgumentKind) | |||
8315 | , matchingCType(MatchingCType) | |||
8316 | , layoutCompatible(LayoutCompatible) | |||
8317 | , mustBeNull(MustBeNull) | |||
8318 | { | |||
8319 | } | |||
8320 | ||||
8321 | TypeTagForDatatypeAttr *clone(ASTContext &C) const; | |||
8322 | void printPretty(raw_ostream &OS, | |||
8323 | const PrintingPolicy &Policy) const; | |||
8324 | const char *getSpelling() const; | |||
8325 | IdentifierInfo * getArgumentKind() const { | |||
8326 | return argumentKind; | |||
8327 | } | |||
8328 | ||||
8329 | QualType getMatchingCType() const { | |||
8330 | return matchingCType->getType(); | |||
8331 | } TypeSourceInfo * getMatchingCTypeLoc() const { | |||
8332 | return matchingCType; | |||
8333 | } | |||
8334 | ||||
8335 | bool getLayoutCompatible() const { | |||
8336 | return layoutCompatible; | |||
8337 | } | |||
8338 | ||||
8339 | bool getMustBeNull() const { | |||
8340 | return mustBeNull; | |||
8341 | } | |||
8342 | ||||
8343 | ||||
8344 | ||||
8345 | static bool classof(const Attr *A) { return A->getKind() == attr::TypeTagForDatatype; } | |||
8346 | }; | |||
8347 | ||||
8348 | class TypeVisibilityAttr : public InheritableAttr { | |||
8349 | public: | |||
8350 | enum VisibilityType { | |||
8351 | Default, | |||
8352 | Hidden, | |||
8353 | Protected | |||
8354 | }; | |||
8355 | private: | |||
8356 | VisibilityType visibility; | |||
8357 | ||||
8358 | public: | |||
8359 | static TypeVisibilityAttr *CreateImplicit(ASTContext &Ctx, VisibilityType Visibility, SourceRange Loc = SourceRange()) { | |||
8360 | auto *A = new (Ctx) TypeVisibilityAttr(Loc, Ctx, Visibility, 0); | |||
8361 | A->setImplicit(true); | |||
8362 | return A; | |||
8363 | } | |||
8364 | ||||
8365 | TypeVisibilityAttr(SourceRange R, ASTContext &Ctx | |||
8366 | , VisibilityType Visibility | |||
8367 | , unsigned SI | |||
8368 | ) | |||
8369 | : InheritableAttr(attr::TypeVisibility, R, SI, false, false) | |||
8370 | , visibility(Visibility) | |||
8371 | { | |||
8372 | } | |||
8373 | ||||
8374 | TypeVisibilityAttr *clone(ASTContext &C) const; | |||
8375 | void printPretty(raw_ostream &OS, | |||
8376 | const PrintingPolicy &Policy) const; | |||
8377 | const char *getSpelling() const; | |||
8378 | VisibilityType getVisibility() const { | |||
8379 | return visibility; | |||
8380 | } | |||
8381 | ||||
8382 | static bool ConvertStrToVisibilityType(StringRef Val, VisibilityType &Out) { | |||
8383 | Optional<VisibilityType> R = llvm::StringSwitch<Optional<VisibilityType>>(Val) | |||
8384 | .Case("default", TypeVisibilityAttr::Default) | |||
8385 | .Case("hidden", TypeVisibilityAttr::Hidden) | |||
8386 | .Case("internal", TypeVisibilityAttr::Hidden) | |||
8387 | .Case("protected", TypeVisibilityAttr::Protected) | |||
8388 | .Default(Optional<VisibilityType>()); | |||
8389 | if (R) { | |||
8390 | Out = *R; | |||
8391 | return true; | |||
8392 | } | |||
8393 | return false; | |||
8394 | } | |||
8395 | ||||
8396 | static const char *ConvertVisibilityTypeToStr(VisibilityType Val) { | |||
8397 | switch(Val) { | |||
8398 | case TypeVisibilityAttr::Default: return "default"; | |||
8399 | case TypeVisibilityAttr::Hidden: return "hidden"; | |||
8400 | case TypeVisibilityAttr::Protected: return "protected"; | |||
8401 | } | |||
8402 | llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 8402); | |||
8403 | } | |||
8404 | ||||
8405 | ||||
8406 | static bool classof(const Attr *A) { return A->getKind() == attr::TypeVisibility; } | |||
8407 | }; | |||
8408 | ||||
8409 | class UnavailableAttr : public InheritableAttr { | |||
8410 | unsigned messageLength; | |||
8411 | char *message; | |||
8412 | ||||
8413 | public: | |||
8414 | enum ImplicitReason { | |||
8415 | IR_None, | |||
8416 | IR_ARCForbiddenType, | |||
8417 | IR_ForbiddenWeak, | |||
8418 | IR_ARCForbiddenConversion, | |||
8419 | IR_ARCInitReturnsUnrelated, | |||
8420 | IR_ARCFieldWithOwnership | |||
8421 | }; | |||
8422 | private: | |||
8423 | ImplicitReason implicitReason; | |||
8424 | ||||
8425 | public: | |||
8426 | static UnavailableAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, ImplicitReason ImplicitReason, SourceRange Loc = SourceRange()) { | |||
8427 | auto *A = new (Ctx) UnavailableAttr(Loc, Ctx, Message, ImplicitReason, 0); | |||
8428 | A->setImplicit(true); | |||
8429 | return A; | |||
8430 | } | |||
8431 | ||||
8432 | static UnavailableAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, SourceRange Loc = SourceRange()) { | |||
8433 | auto *A = new (Ctx) UnavailableAttr(Loc, Ctx, Message, 0); | |||
8434 | A->setImplicit(true); | |||
8435 | return A; | |||
8436 | } | |||
8437 | ||||
8438 | UnavailableAttr(SourceRange R, ASTContext &Ctx | |||
8439 | , llvm::StringRef Message | |||
8440 | , ImplicitReason ImplicitReason | |||
8441 | , unsigned SI | |||
8442 | ) | |||
8443 | : InheritableAttr(attr::Unavailable, R, SI, false, false) | |||
8444 | , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength]) | |||
8445 | , implicitReason(ImplicitReason) | |||
8446 | { | |||
8447 | if (!Message.empty()) | |||
8448 | std::memcpy(message, Message.data(), messageLength); | |||
8449 | } | |||
8450 | ||||
8451 | UnavailableAttr(SourceRange R, ASTContext &Ctx | |||
8452 | , llvm::StringRef Message | |||
8453 | , unsigned SI | |||
8454 | ) | |||
8455 | : InheritableAttr(attr::Unavailable, R, SI, false, false) | |||
8456 | , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength]) | |||
8457 | , implicitReason(ImplicitReason(0)) | |||
8458 | { | |||
8459 | if (!Message.empty()) | |||
8460 | std::memcpy(message, Message.data(), messageLength); | |||
8461 | } | |||
8462 | ||||
8463 | UnavailableAttr(SourceRange R, ASTContext &Ctx | |||
8464 | , unsigned SI | |||
8465 | ) | |||
8466 | : InheritableAttr(attr::Unavailable, R, SI, false, false) | |||
8467 | , messageLength(0),message(nullptr) | |||
8468 | , implicitReason(ImplicitReason(0)) | |||
8469 | { | |||
8470 | } | |||
8471 | ||||
8472 | UnavailableAttr *clone(ASTContext &C) const; | |||
8473 | void printPretty(raw_ostream &OS, | |||
8474 | const PrintingPolicy &Policy) const; | |||
8475 | const char *getSpelling() const; | |||
8476 | llvm::StringRef getMessage() const { | |||
8477 | return llvm::StringRef(message, messageLength); | |||
8478 | } | |||
8479 | unsigned getMessageLength() const { | |||
8480 | return messageLength; | |||
8481 | } | |||
8482 | void setMessage(ASTContext &C, llvm::StringRef S) { | |||
8483 | messageLength = S.size(); | |||
8484 | this->message = new (C, 1) char [messageLength]; | |||
8485 | if (!S.empty()) | |||
8486 | std::memcpy(this->message, S.data(), messageLength); | |||
8487 | } | |||
8488 | ||||
8489 | ImplicitReason getImplicitReason() const { | |||
8490 | return implicitReason; | |||
8491 | } | |||
8492 | ||||
8493 | ||||
8494 | ||||
8495 | static bool classof(const Attr *A) { return A->getKind() == attr::Unavailable; } | |||
8496 | }; | |||
8497 | ||||
8498 | class UnusedAttr : public InheritableAttr { | |||
8499 | public: | |||
8500 | enum Spelling { | |||
8501 | CXX11_maybe_unused = 0, | |||
8502 | GNU_unused = 1, | |||
8503 | CXX11_gnu_unused = 2, | |||
8504 | C2x_maybe_unused = 3 | |||
8505 | }; | |||
8506 | ||||
8507 | static UnusedAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) { | |||
8508 | auto *A = new (Ctx) UnusedAttr(Loc, Ctx, S); | |||
8509 | A->setImplicit(true); | |||
8510 | return A; | |||
8511 | } | |||
8512 | ||||
8513 | UnusedAttr(SourceRange R, ASTContext &Ctx | |||
8514 | , unsigned SI | |||
8515 | ) | |||
8516 | : InheritableAttr(attr::Unused, R, SI, false, false) | |||
8517 | { | |||
8518 | } | |||
8519 | ||||
8520 | UnusedAttr *clone(ASTContext &C) const; | |||
8521 | void printPretty(raw_ostream &OS, | |||
8522 | const PrintingPolicy &Policy) const; | |||
8523 | const char *getSpelling() const; | |||
8524 | Spelling getSemanticSpelling() const { | |||
8525 | switch (SpellingListIndex) { | |||
8526 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 8526); | |||
8527 | case 0: return CXX11_maybe_unused; | |||
8528 | case 1: return GNU_unused; | |||
8529 | case 2: return CXX11_gnu_unused; | |||
8530 | case 3: return C2x_maybe_unused; | |||
8531 | } | |||
8532 | } | |||
8533 | ||||
8534 | ||||
8535 | static bool classof(const Attr *A) { return A->getKind() == attr::Unused; } | |||
8536 | }; | |||
8537 | ||||
8538 | class UsedAttr : public InheritableAttr { | |||
8539 | public: | |||
8540 | static UsedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
8541 | auto *A = new (Ctx) UsedAttr(Loc, Ctx, 0); | |||
8542 | A->setImplicit(true); | |||
8543 | return A; | |||
8544 | } | |||
8545 | ||||
8546 | UsedAttr(SourceRange R, ASTContext &Ctx | |||
8547 | , unsigned SI | |||
8548 | ) | |||
8549 | : InheritableAttr(attr::Used, R, SI, false, false) | |||
8550 | { | |||
8551 | } | |||
8552 | ||||
8553 | UsedAttr *clone(ASTContext &C) const; | |||
8554 | void printPretty(raw_ostream &OS, | |||
8555 | const PrintingPolicy &Policy) const; | |||
8556 | const char *getSpelling() const; | |||
8557 | ||||
8558 | ||||
8559 | static bool classof(const Attr *A) { return A->getKind() == attr::Used; } | |||
8560 | }; | |||
8561 | ||||
8562 | class UuidAttr : public InheritableAttr { | |||
8563 | unsigned guidLength; | |||
8564 | char *guid; | |||
8565 | ||||
8566 | public: | |||
8567 | static UuidAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Guid, SourceRange Loc = SourceRange()) { | |||
8568 | auto *A = new (Ctx) UuidAttr(Loc, Ctx, Guid, 0); | |||
8569 | A->setImplicit(true); | |||
8570 | return A; | |||
8571 | } | |||
8572 | ||||
8573 | UuidAttr(SourceRange R, ASTContext &Ctx | |||
8574 | , llvm::StringRef Guid | |||
8575 | , unsigned SI | |||
8576 | ) | |||
8577 | : InheritableAttr(attr::Uuid, R, SI, false, false) | |||
8578 | , guidLength(Guid.size()),guid(new (Ctx, 1) char[guidLength]) | |||
8579 | { | |||
8580 | if (!Guid.empty()) | |||
8581 | std::memcpy(guid, Guid.data(), guidLength); | |||
8582 | } | |||
8583 | ||||
8584 | UuidAttr *clone(ASTContext &C) const; | |||
8585 | void printPretty(raw_ostream &OS, | |||
8586 | const PrintingPolicy &Policy) const; | |||
8587 | const char *getSpelling() const; | |||
8588 | llvm::StringRef getGuid() const { | |||
8589 | return llvm::StringRef(guid, guidLength); | |||
8590 | } | |||
8591 | unsigned getGuidLength() const { | |||
8592 | return guidLength; | |||
8593 | } | |||
8594 | void setGuid(ASTContext &C, llvm::StringRef S) { | |||
8595 | guidLength = S.size(); | |||
8596 | this->guid = new (C, 1) char [guidLength]; | |||
8597 | if (!S.empty()) | |||
8598 | std::memcpy(this->guid, S.data(), guidLength); | |||
8599 | } | |||
8600 | ||||
8601 | ||||
8602 | ||||
8603 | static bool classof(const Attr *A) { return A->getKind() == attr::Uuid; } | |||
8604 | }; | |||
8605 | ||||
8606 | class VecReturnAttr : public InheritableAttr { | |||
8607 | public: | |||
8608 | static VecReturnAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
8609 | auto *A = new (Ctx) VecReturnAttr(Loc, Ctx, 0); | |||
8610 | A->setImplicit(true); | |||
8611 | return A; | |||
8612 | } | |||
8613 | ||||
8614 | VecReturnAttr(SourceRange R, ASTContext &Ctx | |||
8615 | , unsigned SI | |||
8616 | ) | |||
8617 | : InheritableAttr(attr::VecReturn, R, SI, false, false) | |||
8618 | { | |||
8619 | } | |||
8620 | ||||
8621 | VecReturnAttr *clone(ASTContext &C) const; | |||
8622 | void printPretty(raw_ostream &OS, | |||
8623 | const PrintingPolicy &Policy) const; | |||
8624 | const char *getSpelling() const; | |||
8625 | ||||
8626 | ||||
8627 | static bool classof(const Attr *A) { return A->getKind() == attr::VecReturn; } | |||
8628 | }; | |||
8629 | ||||
8630 | class VecTypeHintAttr : public InheritableAttr { | |||
8631 | TypeSourceInfo * typeHint; | |||
8632 | ||||
8633 | public: | |||
8634 | static VecTypeHintAttr *CreateImplicit(ASTContext &Ctx, TypeSourceInfo * TypeHint, SourceRange Loc = SourceRange()) { | |||
8635 | auto *A = new (Ctx) VecTypeHintAttr(Loc, Ctx, TypeHint, 0); | |||
8636 | A->setImplicit(true); | |||
8637 | return A; | |||
8638 | } | |||
8639 | ||||
8640 | VecTypeHintAttr(SourceRange R, ASTContext &Ctx | |||
8641 | , TypeSourceInfo * TypeHint | |||
8642 | , unsigned SI | |||
8643 | ) | |||
8644 | : InheritableAttr(attr::VecTypeHint, R, SI, false, false) | |||
8645 | , typeHint(TypeHint) | |||
8646 | { | |||
8647 | } | |||
8648 | ||||
8649 | VecTypeHintAttr *clone(ASTContext &C) const; | |||
8650 | void printPretty(raw_ostream &OS, | |||
8651 | const PrintingPolicy &Policy) const; | |||
8652 | const char *getSpelling() const; | |||
8653 | QualType getTypeHint() const { | |||
8654 | return typeHint->getType(); | |||
8655 | } TypeSourceInfo * getTypeHintLoc() const { | |||
8656 | return typeHint; | |||
8657 | } | |||
8658 | ||||
8659 | ||||
8660 | ||||
8661 | static bool classof(const Attr *A) { return A->getKind() == attr::VecTypeHint; } | |||
8662 | }; | |||
8663 | ||||
8664 | class VectorCallAttr : public InheritableAttr { | |||
8665 | public: | |||
8666 | static VectorCallAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
8667 | auto *A = new (Ctx) VectorCallAttr(Loc, Ctx, 0); | |||
8668 | A->setImplicit(true); | |||
8669 | return A; | |||
8670 | } | |||
8671 | ||||
8672 | VectorCallAttr(SourceRange R, ASTContext &Ctx | |||
8673 | , unsigned SI | |||
8674 | ) | |||
8675 | : InheritableAttr(attr::VectorCall, R, SI, false, false) | |||
8676 | { | |||
8677 | } | |||
8678 | ||||
8679 | VectorCallAttr *clone(ASTContext &C) const; | |||
8680 | void printPretty(raw_ostream &OS, | |||
8681 | const PrintingPolicy &Policy) const; | |||
8682 | const char *getSpelling() const; | |||
8683 | ||||
8684 | ||||
8685 | static bool classof(const Attr *A) { return A->getKind() == attr::VectorCall; } | |||
8686 | }; | |||
8687 | ||||
8688 | class VisibilityAttr : public InheritableAttr { | |||
8689 | public: | |||
8690 | enum VisibilityType { | |||
8691 | Default, | |||
8692 | Hidden, | |||
8693 | Protected | |||
8694 | }; | |||
8695 | private: | |||
8696 | VisibilityType visibility; | |||
8697 | ||||
8698 | public: | |||
8699 | static VisibilityAttr *CreateImplicit(ASTContext &Ctx, VisibilityType Visibility, SourceRange Loc = SourceRange()) { | |||
8700 | auto *A = new (Ctx) VisibilityAttr(Loc, Ctx, Visibility, 0); | |||
8701 | A->setImplicit(true); | |||
8702 | return A; | |||
8703 | } | |||
8704 | ||||
8705 | VisibilityAttr(SourceRange R, ASTContext &Ctx | |||
8706 | , VisibilityType Visibility | |||
8707 | , unsigned SI | |||
8708 | ) | |||
8709 | : InheritableAttr(attr::Visibility, R, SI, false, false) | |||
8710 | , visibility(Visibility) | |||
8711 | { | |||
8712 | } | |||
8713 | ||||
8714 | VisibilityAttr *clone(ASTContext &C) const; | |||
8715 | void printPretty(raw_ostream &OS, | |||
8716 | const PrintingPolicy &Policy) const; | |||
8717 | const char *getSpelling() const; | |||
8718 | VisibilityType getVisibility() const { | |||
8719 | return visibility; | |||
8720 | } | |||
8721 | ||||
8722 | static bool ConvertStrToVisibilityType(StringRef Val, VisibilityType &Out) { | |||
8723 | Optional<VisibilityType> R = llvm::StringSwitch<Optional<VisibilityType>>(Val) | |||
8724 | .Case("default", VisibilityAttr::Default) | |||
8725 | .Case("hidden", VisibilityAttr::Hidden) | |||
8726 | .Case("internal", VisibilityAttr::Hidden) | |||
8727 | .Case("protected", VisibilityAttr::Protected) | |||
8728 | .Default(Optional<VisibilityType>()); | |||
8729 | if (R) { | |||
8730 | Out = *R; | |||
8731 | return true; | |||
8732 | } | |||
8733 | return false; | |||
8734 | } | |||
8735 | ||||
8736 | static const char *ConvertVisibilityTypeToStr(VisibilityType Val) { | |||
8737 | switch(Val) { | |||
8738 | case VisibilityAttr::Default: return "default"; | |||
8739 | case VisibilityAttr::Hidden: return "hidden"; | |||
8740 | case VisibilityAttr::Protected: return "protected"; | |||
8741 | } | |||
8742 | llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 8742); | |||
8743 | } | |||
8744 | ||||
8745 | ||||
8746 | static bool classof(const Attr *A) { return A->getKind() == attr::Visibility; } | |||
8747 | }; | |||
8748 | ||||
8749 | class WarnUnusedAttr : public InheritableAttr { | |||
8750 | public: | |||
8751 | static WarnUnusedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
8752 | auto *A = new (Ctx) WarnUnusedAttr(Loc, Ctx, 0); | |||
8753 | A->setImplicit(true); | |||
8754 | return A; | |||
8755 | } | |||
8756 | ||||
8757 | WarnUnusedAttr(SourceRange R, ASTContext &Ctx | |||
8758 | , unsigned SI | |||
8759 | ) | |||
8760 | : InheritableAttr(attr::WarnUnused, R, SI, false, false) | |||
8761 | { | |||
8762 | } | |||
8763 | ||||
8764 | WarnUnusedAttr *clone(ASTContext &C) const; | |||
8765 | void printPretty(raw_ostream &OS, | |||
8766 | const PrintingPolicy &Policy) const; | |||
8767 | const char *getSpelling() const; | |||
8768 | ||||
8769 | ||||
8770 | static bool classof(const Attr *A) { return A->getKind() == attr::WarnUnused; } | |||
8771 | }; | |||
8772 | ||||
8773 | class WarnUnusedResultAttr : public InheritableAttr { | |||
8774 | public: | |||
8775 | enum Spelling { | |||
8776 | CXX11_nodiscard = 0, | |||
8777 | C2x_nodiscard = 1, | |||
8778 | CXX11_clang_warn_unused_result = 2, | |||
8779 | GNU_warn_unused_result = 3, | |||
8780 | CXX11_gnu_warn_unused_result = 4 | |||
8781 | }; | |||
8782 | ||||
8783 | static WarnUnusedResultAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) { | |||
8784 | auto *A = new (Ctx) WarnUnusedResultAttr(Loc, Ctx, S); | |||
8785 | A->setImplicit(true); | |||
8786 | return A; | |||
8787 | } | |||
8788 | ||||
8789 | WarnUnusedResultAttr(SourceRange R, ASTContext &Ctx | |||
8790 | , unsigned SI | |||
8791 | ) | |||
8792 | : InheritableAttr(attr::WarnUnusedResult, R, SI, false, false) | |||
8793 | { | |||
8794 | } | |||
8795 | ||||
8796 | WarnUnusedResultAttr *clone(ASTContext &C) const; | |||
8797 | void printPretty(raw_ostream &OS, | |||
8798 | const PrintingPolicy &Policy) const; | |||
8799 | const char *getSpelling() const; | |||
8800 | Spelling getSemanticSpelling() const { | |||
8801 | switch (SpellingListIndex) { | |||
8802 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 8802); | |||
8803 | case 0: return CXX11_nodiscard; | |||
8804 | case 1: return C2x_nodiscard; | |||
8805 | case 2: return CXX11_clang_warn_unused_result; | |||
8806 | case 3: return GNU_warn_unused_result; | |||
8807 | case 4: return CXX11_gnu_warn_unused_result; | |||
8808 | } | |||
8809 | } | |||
8810 | ||||
8811 | ||||
8812 | static bool classof(const Attr *A) { return A->getKind() == attr::WarnUnusedResult; } | |||
8813 | }; | |||
8814 | ||||
8815 | class WeakAttr : public InheritableAttr { | |||
8816 | public: | |||
8817 | static WeakAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
8818 | auto *A = new (Ctx) WeakAttr(Loc, Ctx, 0); | |||
8819 | A->setImplicit(true); | |||
8820 | return A; | |||
8821 | } | |||
8822 | ||||
8823 | WeakAttr(SourceRange R, ASTContext &Ctx | |||
8824 | , unsigned SI | |||
8825 | ) | |||
8826 | : InheritableAttr(attr::Weak, R, SI, false, false) | |||
8827 | { | |||
8828 | } | |||
8829 | ||||
8830 | WeakAttr *clone(ASTContext &C) const; | |||
8831 | void printPretty(raw_ostream &OS, | |||
8832 | const PrintingPolicy &Policy) const; | |||
8833 | const char *getSpelling() const; | |||
8834 | ||||
8835 | ||||
8836 | static bool classof(const Attr *A) { return A->getKind() == attr::Weak; } | |||
8837 | }; | |||
8838 | ||||
8839 | class WeakImportAttr : public InheritableAttr { | |||
8840 | public: | |||
8841 | static WeakImportAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
8842 | auto *A = new (Ctx) WeakImportAttr(Loc, Ctx, 0); | |||
8843 | A->setImplicit(true); | |||
8844 | return A; | |||
8845 | } | |||
8846 | ||||
8847 | WeakImportAttr(SourceRange R, ASTContext &Ctx | |||
8848 | , unsigned SI | |||
8849 | ) | |||
8850 | : InheritableAttr(attr::WeakImport, R, SI, false, false) | |||
8851 | { | |||
8852 | } | |||
8853 | ||||
8854 | WeakImportAttr *clone(ASTContext &C) const; | |||
8855 | void printPretty(raw_ostream &OS, | |||
8856 | const PrintingPolicy &Policy) const; | |||
8857 | const char *getSpelling() const; | |||
8858 | ||||
8859 | ||||
8860 | static bool classof(const Attr *A) { return A->getKind() == attr::WeakImport; } | |||
8861 | }; | |||
8862 | ||||
8863 | class WeakRefAttr : public InheritableAttr { | |||
8864 | unsigned aliaseeLength; | |||
8865 | char *aliasee; | |||
8866 | ||||
8867 | public: | |||
8868 | static WeakRefAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Aliasee, SourceRange Loc = SourceRange()) { | |||
8869 | auto *A = new (Ctx) WeakRefAttr(Loc, Ctx, Aliasee, 0); | |||
8870 | A->setImplicit(true); | |||
8871 | return A; | |||
8872 | } | |||
8873 | ||||
8874 | WeakRefAttr(SourceRange R, ASTContext &Ctx | |||
8875 | , llvm::StringRef Aliasee | |||
8876 | , unsigned SI | |||
8877 | ) | |||
8878 | : InheritableAttr(attr::WeakRef, R, SI, false, false) | |||
8879 | , aliaseeLength(Aliasee.size()),aliasee(new (Ctx, 1) char[aliaseeLength]) | |||
8880 | { | |||
8881 | if (!Aliasee.empty()) | |||
8882 | std::memcpy(aliasee, Aliasee.data(), aliaseeLength); | |||
8883 | } | |||
8884 | ||||
8885 | WeakRefAttr(SourceRange R, ASTContext &Ctx | |||
8886 | , unsigned SI | |||
8887 | ) | |||
8888 | : InheritableAttr(attr::WeakRef, R, SI, false, false) | |||
8889 | , aliaseeLength(0),aliasee(nullptr) | |||
8890 | { | |||
8891 | } | |||
8892 | ||||
8893 | WeakRefAttr *clone(ASTContext &C) const; | |||
8894 | void printPretty(raw_ostream &OS, | |||
8895 | const PrintingPolicy &Policy) const; | |||
8896 | const char *getSpelling() const; | |||
8897 | llvm::StringRef getAliasee() const { | |||
8898 | return llvm::StringRef(aliasee, aliaseeLength); | |||
8899 | } | |||
8900 | unsigned getAliaseeLength() const { | |||
8901 | return aliaseeLength; | |||
8902 | } | |||
8903 | void setAliasee(ASTContext &C, llvm::StringRef S) { | |||
8904 | aliaseeLength = S.size(); | |||
8905 | this->aliasee = new (C, 1) char [aliaseeLength]; | |||
8906 | if (!S.empty()) | |||
8907 | std::memcpy(this->aliasee, S.data(), aliaseeLength); | |||
8908 | } | |||
8909 | ||||
8910 | ||||
8911 | ||||
8912 | static bool classof(const Attr *A) { return A->getKind() == attr::WeakRef; } | |||
8913 | }; | |||
8914 | ||||
8915 | class WorkGroupSizeHintAttr : public InheritableAttr { | |||
8916 | unsigned xDim; | |||
8917 | ||||
8918 | unsigned yDim; | |||
8919 | ||||
8920 | unsigned zDim; | |||
8921 | ||||
8922 | public: | |||
8923 | static WorkGroupSizeHintAttr *CreateImplicit(ASTContext &Ctx, unsigned XDim, unsigned YDim, unsigned ZDim, SourceRange Loc = SourceRange()) { | |||
8924 | auto *A = new (Ctx) WorkGroupSizeHintAttr(Loc, Ctx, XDim, YDim, ZDim, 0); | |||
8925 | A->setImplicit(true); | |||
8926 | return A; | |||
8927 | } | |||
8928 | ||||
8929 | WorkGroupSizeHintAttr(SourceRange R, ASTContext &Ctx | |||
8930 | , unsigned XDim | |||
8931 | , unsigned YDim | |||
8932 | , unsigned ZDim | |||
8933 | , unsigned SI | |||
8934 | ) | |||
8935 | : InheritableAttr(attr::WorkGroupSizeHint, R, SI, false, false) | |||
8936 | , xDim(XDim) | |||
8937 | , yDim(YDim) | |||
8938 | , zDim(ZDim) | |||
8939 | { | |||
8940 | } | |||
8941 | ||||
8942 | WorkGroupSizeHintAttr *clone(ASTContext &C) const; | |||
8943 | void printPretty(raw_ostream &OS, | |||
8944 | const PrintingPolicy &Policy) const; | |||
8945 | const char *getSpelling() const; | |||
8946 | unsigned getXDim() const { | |||
8947 | return xDim; | |||
8948 | } | |||
8949 | ||||
8950 | unsigned getYDim() const { | |||
8951 | return yDim; | |||
8952 | } | |||
8953 | ||||
8954 | unsigned getZDim() const { | |||
8955 | return zDim; | |||
8956 | } | |||
8957 | ||||
8958 | ||||
8959 | ||||
8960 | static bool classof(const Attr *A) { return A->getKind() == attr::WorkGroupSizeHint; } | |||
8961 | }; | |||
8962 | ||||
8963 | class X86ForceAlignArgPointerAttr : public InheritableAttr { | |||
8964 | public: | |||
8965 | static X86ForceAlignArgPointerAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) { | |||
8966 | auto *A = new (Ctx) X86ForceAlignArgPointerAttr(Loc, Ctx, 0); | |||
8967 | A->setImplicit(true); | |||
8968 | return A; | |||
8969 | } | |||
8970 | ||||
8971 | X86ForceAlignArgPointerAttr(SourceRange R, ASTContext &Ctx | |||
8972 | , unsigned SI | |||
8973 | ) | |||
8974 | : InheritableAttr(attr::X86ForceAlignArgPointer, R, SI, false, false) | |||
8975 | { | |||
8976 | } | |||
8977 | ||||
8978 | X86ForceAlignArgPointerAttr *clone(ASTContext &C) const; | |||
8979 | void printPretty(raw_ostream &OS, | |||
8980 | const PrintingPolicy &Policy) const; | |||
8981 | const char *getSpelling() const; | |||
8982 | ||||
8983 | ||||
8984 | static bool classof(const Attr *A) { return A->getKind() == attr::X86ForceAlignArgPointer; } | |||
8985 | }; | |||
8986 | ||||
8987 | class XRayInstrumentAttr : public InheritableAttr { | |||
8988 | public: | |||
8989 | enum Spelling { | |||
8990 | GNU_xray_always_instrument = 0, | |||
8991 | CXX11_clang_xray_always_instrument = 1, | |||
8992 | C2x_clang_xray_always_instrument = 2, | |||
8993 | GNU_xray_never_instrument = 3, | |||
8994 | CXX11_clang_xray_never_instrument = 4, | |||
8995 | C2x_clang_xray_never_instrument = 5 | |||
8996 | }; | |||
8997 | ||||
8998 | static XRayInstrumentAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) { | |||
8999 | auto *A = new (Ctx) XRayInstrumentAttr(Loc, Ctx, S); | |||
9000 | A->setImplicit(true); | |||
9001 | return A; | |||
9002 | } | |||
9003 | ||||
9004 | XRayInstrumentAttr(SourceRange R, ASTContext &Ctx | |||
9005 | , unsigned SI | |||
9006 | ) | |||
9007 | : InheritableAttr(attr::XRayInstrument, R, SI, false, false) | |||
9008 | { | |||
9009 | } | |||
9010 | ||||
9011 | XRayInstrumentAttr *clone(ASTContext &C) const; | |||
9012 | void printPretty(raw_ostream &OS, | |||
9013 | const PrintingPolicy &Policy) const; | |||
9014 | const char *getSpelling() const; | |||
9015 | Spelling getSemanticSpelling() const { | |||
9016 | switch (SpellingListIndex) { | |||
9017 | default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index" , "/build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include/clang/AST/Attrs.inc" , 9017); | |||
9018 | case 0: return GNU_xray_always_instrument; | |||
9019 | case 1: return CXX11_clang_xray_always_instrument; | |||
9020 | case 2: return C2x_clang_xray_always_instrument; | |||
9021 | case 3: return GNU_xray_never_instrument; | |||
9022 | case 4: return CXX11_clang_xray_never_instrument; | |||
9023 | case 5: return C2x_clang_xray_never_instrument; | |||
9024 | } | |||
9025 | } | |||
9026 | bool alwaysXRayInstrument() const { return SpellingListIndex == 0 || | |||
9027 | SpellingListIndex == 1 || | |||
9028 | SpellingListIndex == 2; } | |||
9029 | bool neverXRayInstrument() const { return SpellingListIndex == 3 || | |||
9030 | SpellingListIndex == 4 || | |||
9031 | SpellingListIndex == 5; } | |||
9032 | ||||
9033 | ||||
9034 | static bool classof(const Attr *A) { return A->getKind() == attr::XRayInstrument; } | |||
9035 | }; | |||
9036 | ||||
9037 | class XRayLogArgsAttr : public InheritableAttr { | |||
9038 | unsigned argumentCount; | |||
9039 | ||||
9040 | public: | |||
9041 | static XRayLogArgsAttr *CreateImplicit(ASTContext &Ctx, unsigned ArgumentCount, SourceRange Loc = SourceRange()) { | |||
9042 | auto *A = new (Ctx) XRayLogArgsAttr(Loc, Ctx, ArgumentCount, 0); | |||
9043 | A->setImplicit(true); | |||
9044 | return A; | |||
9045 | } | |||
9046 | ||||
9047 | XRayLogArgsAttr(SourceRange R, ASTContext &Ctx | |||
9048 | , unsigned ArgumentCount | |||
9049 | , unsigned SI | |||
9050 | ) | |||
9051 | : InheritableAttr(attr::XRayLogArgs, R, SI, false, false) | |||
9052 | , argumentCount(ArgumentCount) | |||
9053 | { | |||
9054 | } | |||
9055 | ||||
9056 | XRayLogArgsAttr *clone(ASTContext &C) const; | |||
9057 | void printPretty(raw_ostream &OS, | |||
9058 | const PrintingPolicy &Policy) const; | |||
9059 | const char *getSpelling() const; | |||
9060 | unsigned getArgumentCount() const { | |||
9061 | return argumentCount; | |||
9062 | } | |||
9063 | ||||
9064 | ||||
9065 | ||||
9066 | static bool classof(const Attr *A) { return A->getKind() == attr::XRayLogArgs; } | |||
9067 | }; | |||
9068 | ||||
9069 | #endif // LLVM_CLANG_ATTR_CLASSES_INC |