blob: 29aca3370dcbb4ffc2f8ef7043a1ec7712e6ae8e [file] [log] [blame]
Chris Lattner2c6fcf52008-06-26 18:38:35 +00001//===--- 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
John McCall83024632010-08-25 22:03:47 +000014#include "clang/Sema/SemaInternal.h"
Chris Lattner2c6fcf52008-06-26 18:38:35 +000015#include "clang/AST/ASTContext.h"
DeLesley Hutchins5ff430c2012-05-04 16:28:38 +000016#include "clang/AST/CXXInheritance.h"
John McCall28a0cf72010-08-25 07:42:41 +000017#include "clang/AST/DeclCXX.h"
Daniel Dunbar56fdb6a2008-08-11 06:23:49 +000018#include "clang/AST/DeclObjC.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000019#include "clang/AST/DeclTemplate.h"
Daniel Dunbar56fdb6a2008-08-11 06:23:49 +000020#include "clang/AST/Expr.h"
Rafael Espindoladb77c4a2013-02-26 19:13:56 +000021#include "clang/AST/Mangle.h"
Jordan Rosea7d03842013-02-08 22:30:41 +000022#include "clang/Basic/CharInfo.h"
John McCall31168b02011-06-15 23:02:42 +000023#include "clang/Basic/SourceManager.h"
Chris Lattneracbc2d22008-06-27 22:18:37 +000024#include "clang/Basic/TargetInfo.h"
Benjamin Kramer6ee15622013-09-13 15:35:43 +000025#include "clang/Lex/Preprocessor.h"
John McCall8b0666c2010-08-20 18:27:03 +000026#include "clang/Sema/DeclSpec.h"
John McCallb45a1e72010-08-26 02:13:20 +000027#include "clang/Sema/DelayedDiagnostic.h"
John McCallf1e8b342011-09-29 07:17:38 +000028#include "clang/Sema/Lookup.h"
Richard Smithe233fbf2013-01-28 22:42:45 +000029#include "clang/Sema/Scope.h"
Chris Lattner30ba6742009-08-10 19:03:04 +000030#include "llvm/ADT/StringExtras.h"
Chris Lattner2c6fcf52008-06-26 18:38:35 +000031using namespace clang;
John McCallb45a1e72010-08-26 02:13:20 +000032using namespace sema;
Chris Lattner2c6fcf52008-06-26 18:38:35 +000033
Aaron Ballmandf8fe4c2013-11-24 21:35:16 +000034namespace AttributeLangSupport {
NAKAMURA Takumi01d27f92013-11-25 00:52:29 +000035 enum LANG {
Aaron Ballmandf8fe4c2013-11-24 21:35:16 +000036 C,
37 Cpp,
38 ObjC
39 };
40}
41
Chris Lattner58418ff2008-06-29 00:16:31 +000042//===----------------------------------------------------------------------===//
43// Helper functions
44//===----------------------------------------------------------------------===//
45
Ted Kremenek527042b2009-08-14 20:49:40 +000046/// isFunctionOrMethod - Return true if the given decl has function
Daniel Dunbar70e3eba2008-10-19 02:04:16 +000047/// type (function or function-typed variable) or an Objective-C
48/// method.
Chandler Carruthff4c4f02011-07-01 23:49:12 +000049static bool isFunctionOrMethod(const Decl *D) {
Aaron Ballman12b9f652014-01-16 13:55:42 +000050 return (D->getFunctionType() != NULL) || isa<ObjCMethodDecl>(D);
Fariborz Jahanian4447e172009-05-15 23:15:03 +000051}
52
John McCall3882ace2011-01-05 12:14:39 +000053/// Return true if the given decl has a declarator that should have
54/// been processed by Sema::GetTypeForDeclarator.
Chandler Carruthff4c4f02011-07-01 23:49:12 +000055static bool hasDeclarator(const Decl *D) {
John McCall31168b02011-06-15 23:02:42 +000056 // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
Chandler Carruthff4c4f02011-07-01 23:49:12 +000057 return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) ||
58 isa<ObjCPropertyDecl>(D);
John McCall3882ace2011-01-05 12:14:39 +000059}
60
Daniel Dunbar70e3eba2008-10-19 02:04:16 +000061/// hasFunctionProto - Return true if the given decl has a argument
62/// information. This decl should have already passed
Fariborz Jahanian4447e172009-05-15 23:15:03 +000063/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
Chandler Carruthff4c4f02011-07-01 23:49:12 +000064static bool hasFunctionProto(const Decl *D) {
Aaron Ballman12b9f652014-01-16 13:55:42 +000065 if (const FunctionType *FnTy = D->getFunctionType())
Douglas Gregordeaad8c2009-02-26 23:50:07 +000066 return isa<FunctionProtoType>(FnTy);
Aaron Ballman12b9f652014-01-16 13:55:42 +000067 return isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D);
Daniel Dunbar70e3eba2008-10-19 02:04:16 +000068}
69
Alp Toker601b22c2014-01-21 23:35:24 +000070/// getFunctionOrMethodNumParams - Return number of function or method
71/// parameters. It is an error to call this on a K&R function (use
Daniel Dunbar70e3eba2008-10-19 02:04:16 +000072/// hasFunctionProto first).
Alp Toker601b22c2014-01-21 23:35:24 +000073static unsigned getFunctionOrMethodNumParams(const Decl *D) {
Aaron Ballman12b9f652014-01-16 13:55:42 +000074 if (const FunctionType *FnTy = D->getFunctionType())
Alp Toker9cacbab2014-01-20 20:26:09 +000075 return cast<FunctionProtoType>(FnTy)->getNumParams();
Chandler Carruthff4c4f02011-07-01 23:49:12 +000076 if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
Fariborz Jahanian960910a2009-05-19 17:08:59 +000077 return BD->getNumParams();
Chandler Carruthff4c4f02011-07-01 23:49:12 +000078 return cast<ObjCMethodDecl>(D)->param_size();
Daniel Dunbarc136e0c2008-09-26 04:12:28 +000079}
80
Alp Toker601b22c2014-01-21 23:35:24 +000081static QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx) {
Aaron Ballman12b9f652014-01-16 13:55:42 +000082 if (const FunctionType *FnTy = D->getFunctionType())
Alp Toker9cacbab2014-01-20 20:26:09 +000083 return cast<FunctionProtoType>(FnTy)->getParamType(Idx);
Chandler Carruthff4c4f02011-07-01 23:49:12 +000084 if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
Fariborz Jahanian960910a2009-05-19 17:08:59 +000085 return BD->getParamDecl(Idx)->getType();
Mike Stumpd3bb5572009-07-24 19:02:52 +000086
Chandler Carruthff4c4f02011-07-01 23:49:12 +000087 return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType();
Daniel Dunbarc136e0c2008-09-26 04:12:28 +000088}
89
Chandler Carruthff4c4f02011-07-01 23:49:12 +000090static QualType getFunctionOrMethodResultType(const Decl *D) {
Aaron Ballman12b9f652014-01-16 13:55:42 +000091 if (const FunctionType *FnTy = D->getFunctionType())
Alp Toker314cc812014-01-25 16:55:45 +000092 return cast<FunctionProtoType>(FnTy)->getReturnType();
93 return cast<ObjCMethodDecl>(D)->getReturnType();
Fariborz Jahanianf1c25022009-05-20 17:41:43 +000094}
95
Chandler Carruthff4c4f02011-07-01 23:49:12 +000096static bool isFunctionOrMethodVariadic(const Decl *D) {
Aaron Ballman12b9f652014-01-16 13:55:42 +000097 if (const FunctionType *FnTy = D->getFunctionType()) {
Douglas Gregordeaad8c2009-02-26 23:50:07 +000098 const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
Daniel Dunbarc136e0c2008-09-26 04:12:28 +000099 return proto->isVariadic();
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000100 } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
Ted Kremenek8af4f402010-04-29 16:48:58 +0000101 return BD->isVariadic();
Fariborz Jahanian960910a2009-05-19 17:08:59 +0000102 else {
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000103 return cast<ObjCMethodDecl>(D)->isVariadic();
Daniel Dunbarc136e0c2008-09-26 04:12:28 +0000104 }
105}
106
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000107static bool isInstanceMethod(const Decl *D) {
108 if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D))
Chandler Carruth743682b2010-11-16 08:35:43 +0000109 return MethodDecl->isInstance();
110 return false;
111}
112
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000113static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
John McCall9dd450b2009-09-21 23:43:11 +0000114 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
Chris Lattner574dee62008-07-26 22:17:49 +0000115 if (!PT)
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000116 return false;
Mike Stumpd3bb5572009-07-24 19:02:52 +0000117
John McCall96fa4842010-05-17 21:00:27 +0000118 ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
119 if (!Cls)
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000120 return false;
Mike Stumpd3bb5572009-07-24 19:02:52 +0000121
John McCall96fa4842010-05-17 21:00:27 +0000122 IdentifierInfo* ClsName = Cls->getIdentifier();
Mike Stumpd3bb5572009-07-24 19:02:52 +0000123
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000124 // FIXME: Should we walk the chain of classes?
125 return ClsName == &Ctx.Idents.get("NSString") ||
126 ClsName == &Ctx.Idents.get("NSMutableString");
127}
128
Daniel Dunbar980c6692008-09-26 03:32:58 +0000129static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000130 const PointerType *PT = T->getAs<PointerType>();
Daniel Dunbar980c6692008-09-26 03:32:58 +0000131 if (!PT)
132 return false;
133
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000134 const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
Daniel Dunbar980c6692008-09-26 03:32:58 +0000135 if (!RT)
136 return false;
Mike Stumpd3bb5572009-07-24 19:02:52 +0000137
Daniel Dunbar980c6692008-09-26 03:32:58 +0000138 const RecordDecl *RD = RT->getDecl();
Abramo Bagnara6150c882010-05-11 21:36:43 +0000139 if (RD->getTagKind() != TTK_Struct)
Daniel Dunbar980c6692008-09-26 03:32:58 +0000140 return false;
141
142 return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
143}
144
Richard Smithb87c4652013-10-31 21:23:20 +0000145static unsigned getNumAttributeArgs(const AttributeList &Attr) {
146 // FIXME: Include the type in the argument list.
147 return Attr.getNumArgs() + Attr.hasParsedType();
148}
149
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000150/// \brief Check if the attribute has exactly as many args as Num. May
151/// output an error.
Chandler Carruthfcc48d92011-07-11 23:30:35 +0000152static bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
Richard Smithb87c4652013-10-31 21:23:20 +0000153 unsigned Num) {
154 if (getNumAttributeArgs(Attr) != Num) {
Aaron Ballmanb7243382013-07-23 19:30:11 +0000155 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
156 << Attr.getName() << Num;
Chandler Carruthfcc48d92011-07-11 23:30:35 +0000157 return false;
158 }
159
160 return true;
161}
162
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000163/// \brief Check if the attribute has at least as many args as Num. May
164/// output an error.
165static bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr,
Richard Smithb87c4652013-10-31 21:23:20 +0000166 unsigned Num) {
167 if (getNumAttributeArgs(Attr) < Num) {
Aaron Ballman05e420a2014-01-02 21:26:14 +0000168 S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments)
169 << Attr.getName() << Num;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000170 return false;
171 }
172
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000173 return true;
174}
175
Aaron Ballmanf22ef5a2013-11-21 01:50:40 +0000176/// \brief If Expr is a valid integer constant, get the value of the integer
177/// expression and return success or failure. May output an error.
178static bool checkUInt32Argument(Sema &S, const AttributeList &Attr,
179 const Expr *Expr, uint32_t &Val,
180 unsigned Idx = UINT_MAX) {
181 llvm::APSInt I(32);
182 if (Expr->isTypeDependent() || Expr->isValueDependent() ||
183 !Expr->isIntegerConstantExpr(I, S.Context)) {
184 if (Idx != UINT_MAX)
185 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
186 << Attr.getName() << Idx << AANT_ArgumentIntegerConstant
187 << Expr->getSourceRange();
188 else
189 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
190 << Attr.getName() << AANT_ArgumentIntegerConstant
191 << Expr->getSourceRange();
192 return false;
193 }
194 Val = (uint32_t)I.getZExtValue();
195 return true;
196}
197
Aaron Ballmanfb763042013-12-02 18:05:46 +0000198/// \brief Diagnose mutually exclusive attributes when present on a given
199/// declaration. Returns true if diagnosed.
200template <typename AttrTy>
201static bool checkAttrMutualExclusion(Sema &S, Decl *D,
Aaron Ballman2cfbc002014-01-03 16:23:46 +0000202 const AttributeList &Attr) {
203 if (AttrTy *A = D->getAttr<AttrTy>()) {
Aaron Ballmanfb763042013-12-02 18:05:46 +0000204 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
Aaron Ballman2cfbc002014-01-03 16:23:46 +0000205 << Attr.getName() << A;
Aaron Ballmanfb763042013-12-02 18:05:46 +0000206 return true;
207 }
208 return false;
209}
210
Alp Toker601b22c2014-01-21 23:35:24 +0000211/// \brief Check if IdxExpr is a valid parameter index for a function or
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +0000212/// instance method D. May output an error.
213///
214/// \returns true if IdxExpr is a valid index.
Alp Toker601b22c2014-01-21 23:35:24 +0000215static bool checkFunctionOrMethodParameterIndex(Sema &S, const Decl *D,
216 const AttributeList &Attr,
217 unsigned AttrArgNum,
218 const Expr *IdxExpr,
219 uint64_t &Idx) {
Aaron Ballmanbe50eb82013-07-30 00:48:57 +0000220 assert(isFunctionOrMethod(D));
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +0000221
222 // In C++ the implicit 'this' function parameter also counts.
223 // Parameters are counted from one.
Aaron Ballmanbe50eb82013-07-30 00:48:57 +0000224 bool HP = hasFunctionProto(D);
225 bool HasImplicitThisParam = isInstanceMethod(D);
226 bool IV = HP && isFunctionOrMethodVariadic(D);
Alp Toker601b22c2014-01-21 23:35:24 +0000227 unsigned NumParams =
228 (HP ? getFunctionOrMethodNumParams(D) : 0) + HasImplicitThisParam;
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +0000229
230 llvm::APSInt IdxInt;
231 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
232 !IdxExpr->isIntegerConstantExpr(IdxInt, S.Context)) {
Aaron Ballmanfaed0fa2013-12-26 16:30:30 +0000233 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
234 << Attr.getName() << AttrArgNum << AANT_ArgumentIntegerConstant
235 << IdxExpr->getSourceRange();
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +0000236 return false;
237 }
238
239 Idx = IdxInt.getLimitedValue();
Alp Toker601b22c2014-01-21 23:35:24 +0000240 if (Idx < 1 || (!IV && Idx > NumParams)) {
Aaron Ballmanfaed0fa2013-12-26 16:30:30 +0000241 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
242 << Attr.getName() << AttrArgNum << IdxExpr->getSourceRange();
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +0000243 return false;
244 }
245 Idx--; // Convert to zero-based.
246 if (HasImplicitThisParam) {
247 if (Idx == 0) {
Aaron Ballmanfaed0fa2013-12-26 16:30:30 +0000248 S.Diag(Attr.getLoc(),
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +0000249 diag::err_attribute_invalid_implicit_this_argument)
Aaron Ballmanfaed0fa2013-12-26 16:30:30 +0000250 << Attr.getName() << IdxExpr->getSourceRange();
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +0000251 return false;
252 }
253 --Idx;
254 }
255
256 return true;
257}
258
Aaron Ballman3b1dde62013-09-13 19:35:18 +0000259/// \brief Check if the argument \p ArgNum of \p Attr is a ASCII string literal.
260/// If not emit an error and return false. If the argument is an identifier it
261/// will emit an error with a fixit hint and treat it as if it was a string
262/// literal.
Tim Northover6a6b63b2013-10-01 14:34:18 +0000263bool Sema::checkStringLiteralArgumentAttr(const AttributeList &Attr,
264 unsigned ArgNum, StringRef &Str,
Tim Northovera484bc02013-10-01 14:34:25 +0000265 SourceLocation *ArgLocation) {
Aaron Ballman3b1dde62013-09-13 19:35:18 +0000266 // Look for identifiers. If we have one emit a hint to fix it to a literal.
267 if (Attr.isArgIdent(ArgNum)) {
268 IdentifierLoc *Loc = Attr.getArgAsIdent(ArgNum);
Tim Northover6a6b63b2013-10-01 14:34:18 +0000269 Diag(Loc->Loc, diag::err_attribute_argument_type)
Aaron Ballman3b1dde62013-09-13 19:35:18 +0000270 << Attr.getName() << AANT_ArgumentString
271 << FixItHint::CreateInsertion(Loc->Loc, "\"")
Tim Northover6a6b63b2013-10-01 14:34:18 +0000272 << FixItHint::CreateInsertion(PP.getLocForEndOfToken(Loc->Loc), "\"");
Aaron Ballman3b1dde62013-09-13 19:35:18 +0000273 Str = Loc->Ident->getName();
274 if (ArgLocation)
275 *ArgLocation = Loc->Loc;
276 return true;
277 }
278
279 // Now check for an actual string literal.
280 Expr *ArgExpr = Attr.getArgAsExpr(ArgNum);
281 StringLiteral *Literal = dyn_cast<StringLiteral>(ArgExpr->IgnoreParenCasts());
282 if (ArgLocation)
283 *ArgLocation = ArgExpr->getLocStart();
284
285 if (!Literal || !Literal->isAscii()) {
Tim Northover6a6b63b2013-10-01 14:34:18 +0000286 Diag(ArgExpr->getLocStart(), diag::err_attribute_argument_type)
Aaron Ballman3b1dde62013-09-13 19:35:18 +0000287 << Attr.getName() << AANT_ArgumentString;
288 return false;
289 }
290
291 Str = Literal->getString();
292 return true;
293}
294
Aaron Ballman6f9165a2013-11-27 15:24:06 +0000295/// \brief Applies the given attribute to the Decl without performing any
296/// additional semantic checking.
297template <typename AttrType>
298static void handleSimpleAttribute(Sema &S, Decl *D,
299 const AttributeList &Attr) {
300 D->addAttr(::new (S.Context) AttrType(Attr.getRange(), S.Context,
301 Attr.getAttributeSpellingListIndex()));
302}
303
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000304/// \brief Check if the passed-in expression is of type int or bool.
305static bool isIntOrBool(Expr *Exp) {
306 QualType QT = Exp->getType();
307 return QT->isBooleanType() || QT->isIntegerType();
308}
309
DeLesley Hutchinse09be232012-04-23 18:39:55 +0000310
311// Check to see if the type is a smart pointer of some kind. We assume
312// it's a smart pointer if it defines both operator-> and operator*.
DeLesley Hutchins90ff4682012-05-02 22:18:42 +0000313static bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) {
314 DeclContextLookupConstResult Res1 = RT->getDecl()->lookup(
315 S.Context.DeclarationNames.getCXXOperatorName(OO_Star));
David Blaikieff7d47a2012-12-19 00:45:41 +0000316 if (Res1.empty())
DeLesley Hutchins90ff4682012-05-02 22:18:42 +0000317 return false;
DeLesley Hutchinse09be232012-04-23 18:39:55 +0000318
DeLesley Hutchins90ff4682012-05-02 22:18:42 +0000319 DeclContextLookupConstResult Res2 = RT->getDecl()->lookup(
320 S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow));
David Blaikieff7d47a2012-12-19 00:45:41 +0000321 if (Res2.empty())
DeLesley Hutchins90ff4682012-05-02 22:18:42 +0000322 return false;
323
324 return true;
DeLesley Hutchinse09be232012-04-23 18:39:55 +0000325}
326
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000327/// \brief Check if passed in Decl is a pointer type.
328/// Note that this function may produce an error message.
329/// \return true if the Decl is a pointer type; false otherwise
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000330static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
331 const AttributeList &Attr) {
Aaron Ballman553e6812013-12-26 14:54:11 +0000332 const ValueDecl *vd = cast<ValueDecl>(D);
333 QualType QT = vd->getType();
334 if (QT->isAnyPointerType())
335 return true;
336
337 if (const RecordType *RT = QT->getAs<RecordType>()) {
338 // If it's an incomplete type, it could be a smart pointer; skip it.
339 // (We don't want to force template instantiation if we can avoid it,
340 // since that would alter the order in which templates are instantiated.)
341 if (RT->isIncompleteType())
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000342 return true;
DeLesley Hutchinse09be232012-04-23 18:39:55 +0000343
Aaron Ballman553e6812013-12-26 14:54:11 +0000344 if (threadSafetyCheckIsSmartPointer(S, RT))
345 return true;
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000346 }
Aaron Ballman553e6812013-12-26 14:54:11 +0000347
348 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer)
Aaron Ballman68289452013-12-26 15:06:01 +0000349 << Attr.getName() << QT;
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000350 return false;
351}
352
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000353/// \brief Checks that the passed in QualType either is of RecordType or points
354/// to RecordType. Returns the relevant RecordType, null if it does not exit.
Benjamin Kramer56b675f2011-08-19 04:18:11 +0000355static const RecordType *getRecordType(QualType QT) {
356 if (const RecordType *RT = QT->getAs<RecordType>())
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000357 return RT;
Benjamin Kramer56b675f2011-08-19 04:18:11 +0000358
359 // Now check if we point to record type.
360 if (const PointerType *PT = QT->getAs<PointerType>())
361 return PT->getPointeeType()->getAs<RecordType>();
362
363 return 0;
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000364}
365
DeLesley Hutchins5ff430c2012-05-04 16:28:38 +0000366
Jordy Rose740b0c22012-05-08 03:27:22 +0000367static bool checkBaseClassIsLockableCallback(const CXXBaseSpecifier *Specifier,
368 CXXBasePath &Path, void *Unused) {
DeLesley Hutchins5ff430c2012-05-04 16:28:38 +0000369 const RecordType *RT = Specifier->getType()->getAs<RecordType>();
Aaron Ballmanefe348e2014-02-18 17:36:50 +0000370 return RT->getDecl()->hasAttr<CapabilityAttr>();
DeLesley Hutchins5ff430c2012-05-04 16:28:38 +0000371}
372
373
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000374/// \brief Thread Safety Analysis: Checks that the passed in RecordType
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000375/// resolves to a lockable object.
DeLesley Hutchins481d5ab2012-04-06 20:02:30 +0000376static void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr,
377 QualType Ty) {
378 const RecordType *RT = getRecordType(Ty);
Michael Hana9171bc2012-08-03 17:40:43 +0000379
DeLesley Hutchins481d5ab2012-04-06 20:02:30 +0000380 // Warn if could not get record type for this argument.
Benjamin Kramer2667afa2011-09-03 03:30:59 +0000381 if (!RT) {
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000382 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_class)
Aaron Ballman1da282a2014-01-02 23:15:58 +0000383 << Attr.getName() << Ty;
DeLesley Hutchins481d5ab2012-04-06 20:02:30 +0000384 return;
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000385 }
DeLesley Hutchins90ff4682012-05-02 22:18:42 +0000386
Michael Hana9171bc2012-08-03 17:40:43 +0000387 // Don't check for lockable if the class hasn't been defined yet.
DeLesley Hutchins3509f292012-02-16 17:15:51 +0000388 if (RT->isIncompleteType())
DeLesley Hutchins481d5ab2012-04-06 20:02:30 +0000389 return;
DeLesley Hutchins90ff4682012-05-02 22:18:42 +0000390
391 // Allow smart pointers to be used as lockable objects.
392 // FIXME -- Check the type that the smart pointer points to.
393 if (threadSafetyCheckIsSmartPointer(S, RT))
394 return;
395
DeLesley Hutchins5ff430c2012-05-04 16:28:38 +0000396 // Check if the type is lockable.
397 RecordDecl *RD = RT->getDecl();
Aaron Ballmanefe348e2014-02-18 17:36:50 +0000398 if (RD->hasAttr<CapabilityAttr>())
DeLesley Hutchins481d5ab2012-04-06 20:02:30 +0000399 return;
DeLesley Hutchins5ff430c2012-05-04 16:28:38 +0000400
401 // Else check if any base classes are lockable.
402 if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
403 CXXBasePaths BPaths(false, false);
404 if (CRD->lookupInBases(checkBaseClassIsLockableCallback, 0, BPaths))
405 return;
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000406 }
DeLesley Hutchins5ff430c2012-05-04 16:28:38 +0000407
408 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
Aaron Ballman1da282a2014-01-02 23:15:58 +0000409 << Attr.getName() << Ty;
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000410}
411
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000412/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000413/// from Sidx, resolve to a lockable object.
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000414/// \param Sidx The attribute argument index to start checking with.
415/// \param ParamIdxOk Whether an argument can be indexing into a function
416/// parameter list.
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000417static void checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000418 const AttributeList &Attr,
419 SmallVectorImpl<Expr*> &Args,
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000420 int Sidx = 0,
421 bool ParamIdxOk = false) {
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000422 for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
Aaron Ballman00e99962013-08-31 01:11:41 +0000423 Expr *ArgExp = Attr.getArgAsExpr(Idx);
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000424
Caitlin Sadowski990d5712011-09-08 17:42:31 +0000425 if (ArgExp->isTypeDependent()) {
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000426 // FIXME -- need to check this again on template instantiation
Caitlin Sadowski990d5712011-09-08 17:42:31 +0000427 Args.push_back(ArgExp);
428 continue;
429 }
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000430
DeLesley Hutchins70b5e8e2012-04-23 16:45:01 +0000431 if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) {
DeLesley Hutchinsa5a00e82012-09-07 17:34:53 +0000432 if (StrLit->getLength() == 0 ||
Benjamin Kramerca9fe142013-09-13 16:30:12 +0000433 (StrLit->isAscii() && StrLit->getString() == StringRef("*"))) {
DeLesley Hutchins3c3d57b2012-08-31 21:57:32 +0000434 // Pass empty strings to the analyzer without warnings.
DeLesley Hutchinsa5a00e82012-09-07 17:34:53 +0000435 // Treat "*" as the universal lock.
DeLesley Hutchins3c3d57b2012-08-31 21:57:32 +0000436 Args.push_back(ArgExp);
DeLesley Hutchins70b5e8e2012-04-23 16:45:01 +0000437 continue;
DeLesley Hutchins3c3d57b2012-08-31 21:57:32 +0000438 }
DeLesley Hutchins70b5e8e2012-04-23 16:45:01 +0000439
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000440 // We allow constant strings to be used as a placeholder for expressions
441 // that are not valid C++ syntax, but warn that they are ignored.
442 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) <<
443 Attr.getName();
DeLesley Hutchins3c3d57b2012-08-31 21:57:32 +0000444 Args.push_back(ArgExp);
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000445 continue;
446 }
447
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000448 QualType ArgTy = ArgExp->getType();
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000449
DeLesley Hutchins70b5e8e2012-04-23 16:45:01 +0000450 // A pointer to member expression of the form &MyClass::mu is treated
451 // specially -- we need to look at the type of the member.
452 if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(ArgExp))
453 if (UOp->getOpcode() == UO_AddrOf)
454 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr()))
455 if (DRE->getDecl()->isCXXInstanceMember())
456 ArgTy = DRE->getDecl()->getType();
457
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000458 // First see if we can just cast to record type, or point to record type.
459 const RecordType *RT = getRecordType(ArgTy);
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000460
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000461 // Now check if we index into a record type function param.
462 if(!RT && ParamIdxOk) {
463 FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000464 IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp);
465 if(FD && IL) {
466 unsigned int NumParams = FD->getNumParams();
467 llvm::APInt ArgValue = IL->getValue();
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000468 uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
469 uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
470 if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000471 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range)
472 << Attr.getName() << Idx + 1 << NumParams;
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000473 continue;
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000474 }
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000475 ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000476 }
477 }
478
DeLesley Hutchins481d5ab2012-04-06 20:02:30 +0000479 checkForLockableRecord(S, D, Attr, ArgTy);
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000480
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000481 Args.push_back(ArgExp);
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000482 }
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000483}
484
Chris Lattner58418ff2008-06-29 00:16:31 +0000485//===----------------------------------------------------------------------===//
Chris Lattner58418ff2008-06-29 00:16:31 +0000486// Attribute Implementations
487//===----------------------------------------------------------------------===//
488
Daniel Dunbar032db472008-07-31 22:40:48 +0000489// FIXME: All this manual attribute parsing code is gross. At the
490// least add some helper functions to check most argument patterns (#
491// and types of args).
492
Michael Hana9171bc2012-08-03 17:40:43 +0000493static void handlePtGuardedVarAttr(Sema &S, Decl *D,
Michael Han99315932013-01-24 16:46:58 +0000494 const AttributeList &Attr) {
Michael Han3be3b442012-07-23 18:48:41 +0000495 if (!threadSafetyCheckIsPointer(S, D, Attr))
496 return;
497
Michael Han99315932013-01-24 16:46:58 +0000498 D->addAttr(::new (S.Context)
499 PtGuardedVarAttr(Attr.getRange(), S.Context,
500 Attr.getAttributeSpellingListIndex()));
Michael Han3be3b442012-07-23 18:48:41 +0000501}
502
Michael Hana9171bc2012-08-03 17:40:43 +0000503static bool checkGuardedByAttrCommon(Sema &S, Decl *D,
504 const AttributeList &Attr,
Michael Han3be3b442012-07-23 18:48:41 +0000505 Expr* &Arg) {
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000506 SmallVector<Expr*, 1> Args;
507 // check that all arguments are lockable objects
508 checkAttrArgsAreLockableObjs(S, D, Attr, Args);
509 unsigned Size = Args.size();
510 if (Size != 1)
Michael Han3be3b442012-07-23 18:48:41 +0000511 return false;
Michael Hana9171bc2012-08-03 17:40:43 +0000512
Michael Han3be3b442012-07-23 18:48:41 +0000513 Arg = Args[0];
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000514
Michael Han3be3b442012-07-23 18:48:41 +0000515 return true;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000516}
517
Michael Han3be3b442012-07-23 18:48:41 +0000518static void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr) {
519 Expr *Arg = 0;
520 if (!checkGuardedByAttrCommon(S, D, Attr, Arg))
521 return;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000522
Aaron Ballman36a53502014-01-16 13:03:14 +0000523 D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg,
524 Attr.getAttributeSpellingListIndex()));
Michael Han3be3b442012-07-23 18:48:41 +0000525}
526
Michael Hana9171bc2012-08-03 17:40:43 +0000527static void handlePtGuardedByAttr(Sema &S, Decl *D,
Michael Han3be3b442012-07-23 18:48:41 +0000528 const AttributeList &Attr) {
529 Expr *Arg = 0;
530 if (!checkGuardedByAttrCommon(S, D, Attr, Arg))
531 return;
532
533 if (!threadSafetyCheckIsPointer(S, D, Attr))
534 return;
535
536 D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(),
Aaron Ballman36a53502014-01-16 13:03:14 +0000537 S.Context, Arg,
538 Attr.getAttributeSpellingListIndex()));
Michael Han3be3b442012-07-23 18:48:41 +0000539}
540
Michael Hana9171bc2012-08-03 17:40:43 +0000541static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D,
542 const AttributeList &Attr,
Craig Topper5603df42013-07-05 19:34:19 +0000543 SmallVectorImpl<Expr *> &Args) {
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000544 if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
Michael Han3be3b442012-07-23 18:48:41 +0000545 return false;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000546
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000547 // Check that this attribute only applies to lockable types.
Aaron Ballmane61b8b82013-12-02 15:02:49 +0000548 QualType QT = cast<ValueDecl>(D)->getType();
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000549 if (!QT->isDependentType()) {
550 const RecordType *RT = getRecordType(QT);
Aaron Ballmanefe348e2014-02-18 17:36:50 +0000551 if (!RT || !RT->getDecl()->hasAttr<CapabilityAttr>()) {
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000552 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable)
Michael Han3be3b442012-07-23 18:48:41 +0000553 << Attr.getName();
554 return false;
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000555 }
556 }
557
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000558 // Check that all arguments are lockable objects.
559 checkAttrArgsAreLockableObjs(S, D, Attr, Args);
Dmitri Gribenko8f8930f2013-05-03 15:05:50 +0000560 if (Args.empty())
Michael Han3be3b442012-07-23 18:48:41 +0000561 return false;
Michael Hana9171bc2012-08-03 17:40:43 +0000562
Michael Han3be3b442012-07-23 18:48:41 +0000563 return true;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000564}
565
Michael Hana9171bc2012-08-03 17:40:43 +0000566static void handleAcquiredAfterAttr(Sema &S, Decl *D,
Michael Han3be3b442012-07-23 18:48:41 +0000567 const AttributeList &Attr) {
568 SmallVector<Expr*, 1> Args;
569 if (!checkAcquireOrderAttrCommon(S, D, Attr, Args))
570 return;
571
572 Expr **StartArg = &Args[0];
Michael Han99315932013-01-24 16:46:58 +0000573 D->addAttr(::new (S.Context)
574 AcquiredAfterAttr(Attr.getRange(), S.Context,
575 StartArg, Args.size(),
576 Attr.getAttributeSpellingListIndex()));
Michael Han3be3b442012-07-23 18:48:41 +0000577}
578
Michael Hana9171bc2012-08-03 17:40:43 +0000579static void handleAcquiredBeforeAttr(Sema &S, Decl *D,
Michael Han3be3b442012-07-23 18:48:41 +0000580 const AttributeList &Attr) {
581 SmallVector<Expr*, 1> Args;
582 if (!checkAcquireOrderAttrCommon(S, D, Attr, Args))
583 return;
584
585 Expr **StartArg = &Args[0];
Michael Han99315932013-01-24 16:46:58 +0000586 D->addAttr(::new (S.Context)
587 AcquiredBeforeAttr(Attr.getRange(), S.Context,
588 StartArg, Args.size(),
589 Attr.getAttributeSpellingListIndex()));
Michael Han3be3b442012-07-23 18:48:41 +0000590}
591
Michael Hana9171bc2012-08-03 17:40:43 +0000592static bool checkLockFunAttrCommon(Sema &S, Decl *D,
593 const AttributeList &Attr,
Craig Topper5603df42013-07-05 19:34:19 +0000594 SmallVectorImpl<Expr *> &Args) {
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000595 // zero or more arguments ok
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000596 // check that all arguments are lockable objects
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000597 checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000598
Michael Han3be3b442012-07-23 18:48:41 +0000599 return true;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000600}
601
DeLesley Hutchinsb6824312013-05-17 23:02:59 +0000602static void handleAssertSharedLockAttr(Sema &S, Decl *D,
603 const AttributeList &Attr) {
604 SmallVector<Expr*, 1> Args;
605 if (!checkLockFunAttrCommon(S, D, Attr, Args))
606 return;
607
608 unsigned Size = Args.size();
609 Expr **StartArg = Size == 0 ? 0 : &Args[0];
610 D->addAttr(::new (S.Context)
611 AssertSharedLockAttr(Attr.getRange(), S.Context, StartArg, Size,
612 Attr.getAttributeSpellingListIndex()));
613}
614
615static void handleAssertExclusiveLockAttr(Sema &S, Decl *D,
616 const AttributeList &Attr) {
617 SmallVector<Expr*, 1> Args;
618 if (!checkLockFunAttrCommon(S, D, Attr, Args))
619 return;
620
621 unsigned Size = Args.size();
622 Expr **StartArg = Size == 0 ? 0 : &Args[0];
623 D->addAttr(::new (S.Context)
624 AssertExclusiveLockAttr(Attr.getRange(), S.Context,
625 StartArg, Size,
626 Attr.getAttributeSpellingListIndex()));
627}
628
629
Michael Hana9171bc2012-08-03 17:40:43 +0000630static bool checkTryLockFunAttrCommon(Sema &S, Decl *D,
631 const AttributeList &Attr,
Craig Topper5603df42013-07-05 19:34:19 +0000632 SmallVectorImpl<Expr *> &Args) {
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000633 if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
Michael Han3be3b442012-07-23 18:48:41 +0000634 return false;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000635
Aaron Ballman00e99962013-08-31 01:11:41 +0000636 if (!isIntOrBool(Attr.getArgAsExpr(0))) {
Aaron Ballman29982272013-07-23 14:03:57 +0000637 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
Aaron Ballman3bf758c2013-07-30 01:31:03 +0000638 << Attr.getName() << 1 << AANT_ArgumentIntOrBool;
Michael Han3be3b442012-07-23 18:48:41 +0000639 return false;
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000640 }
641
642 // check that all arguments are lockable objects
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000643 checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1);
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000644
Michael Han3be3b442012-07-23 18:48:41 +0000645 return true;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000646}
647
Michael Hana9171bc2012-08-03 17:40:43 +0000648static void handleSharedTrylockFunctionAttr(Sema &S, Decl *D,
Michael Han3be3b442012-07-23 18:48:41 +0000649 const AttributeList &Attr) {
650 SmallVector<Expr*, 2> Args;
651 if (!checkTryLockFunAttrCommon(S, D, Attr, Args))
652 return;
653
Michael Han99315932013-01-24 16:46:58 +0000654 D->addAttr(::new (S.Context)
655 SharedTrylockFunctionAttr(Attr.getRange(), S.Context,
Aaron Ballman00e99962013-08-31 01:11:41 +0000656 Attr.getArgAsExpr(0),
657 Args.data(), Args.size(),
Michael Han99315932013-01-24 16:46:58 +0000658 Attr.getAttributeSpellingListIndex()));
Michael Han3be3b442012-07-23 18:48:41 +0000659}
660
Michael Hana9171bc2012-08-03 17:40:43 +0000661static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D,
Michael Han3be3b442012-07-23 18:48:41 +0000662 const AttributeList &Attr) {
663 SmallVector<Expr*, 2> Args;
664 if (!checkTryLockFunAttrCommon(S, D, Attr, Args))
665 return;
666
Michael Han99315932013-01-24 16:46:58 +0000667 D->addAttr(::new (S.Context)
668 ExclusiveTrylockFunctionAttr(Attr.getRange(), S.Context,
Aaron Ballman00e99962013-08-31 01:11:41 +0000669 Attr.getArgAsExpr(0),
670 Args.data(), Args.size(),
Michael Han99315932013-01-24 16:46:58 +0000671 Attr.getAttributeSpellingListIndex()));
Michael Han3be3b442012-07-23 18:48:41 +0000672}
673
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000674static void handleLockReturnedAttr(Sema &S, Decl *D,
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000675 const AttributeList &Attr) {
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000676 // check that the argument is lockable object
DeLesley Hutchinsd96b46a2012-05-02 17:38:37 +0000677 SmallVector<Expr*, 1> Args;
678 checkAttrArgsAreLockableObjs(S, D, Attr, Args);
679 unsigned Size = Args.size();
680 if (Size == 0)
681 return;
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000682
Michael Han99315932013-01-24 16:46:58 +0000683 D->addAttr(::new (S.Context)
684 LockReturnedAttr(Attr.getRange(), S.Context, Args[0],
685 Attr.getAttributeSpellingListIndex()));
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000686}
687
688static void handleLocksExcludedAttr(Sema &S, Decl *D,
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000689 const AttributeList &Attr) {
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000690 if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000691 return;
692
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000693 // check that all arguments are lockable objects
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000694 SmallVector<Expr*, 1> Args;
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000695 checkAttrArgsAreLockableObjs(S, D, Attr, Args);
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000696 unsigned Size = Args.size();
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000697 if (Size == 0)
698 return;
699 Expr **StartArg = &Args[0];
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000700
Michael Han99315932013-01-24 16:46:58 +0000701 D->addAttr(::new (S.Context)
702 LocksExcludedAttr(Attr.getRange(), S.Context, StartArg, Size,
703 Attr.getAttributeSpellingListIndex()));
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000704}
705
Nick Lewycky35a6ef42014-01-11 02:50:57 +0000706static void handleEnableIfAttr(Sema &S, Decl *D, const AttributeList &Attr) {
707 Expr *Cond = Attr.getArgAsExpr(0);
708 if (!Cond->isTypeDependent()) {
709 ExprResult Converted = S.PerformContextuallyConvertToBool(Cond);
710 if (Converted.isInvalid())
711 return;
712 Cond = Converted.take();
713 }
714
715 StringRef Msg;
716 if (!S.checkStringLiteralArgumentAttr(Attr, 1, Msg))
717 return;
718
719 SmallVector<PartialDiagnosticAt, 8> Diags;
720 if (!Cond->isValueDependent() &&
721 !Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(D),
722 Diags)) {
723 S.Diag(Attr.getLoc(), diag::err_enable_if_never_constant_expr);
724 for (int I = 0, N = Diags.size(); I != N; ++I)
725 S.Diag(Diags[I].first, Diags[I].second);
726 return;
727 }
728
729 D->addAttr(::new (S.Context)
730 EnableIfAttr(Attr.getRange(), S.Context, Cond, Msg,
731 Attr.getAttributeSpellingListIndex()));
732}
733
DeLesley Hutchins5a715c42013-08-30 22:56:34 +0000734static void handleConsumableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
David Blaikie16f76d22013-09-06 01:28:43 +0000735 ConsumableAttr::ConsumedState DefaultState;
736
737 if (Attr.isArgIdent(0)) {
Aaron Ballman682ee422013-09-11 19:47:58 +0000738 IdentifierLoc *IL = Attr.getArgAsIdent(0);
739 if (!ConsumableAttr::ConvertStrToConsumedState(IL->Ident->getName(),
740 DefaultState)) {
741 S.Diag(IL->Loc, diag::warn_attribute_type_not_supported)
742 << Attr.getName() << IL->Ident;
David Blaikie16f76d22013-09-06 01:28:43 +0000743 return;
744 }
David Blaikie16f76d22013-09-06 01:28:43 +0000745 } else {
746 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
747 << Attr.getName() << AANT_ArgumentIdentifier;
748 return;
749 }
DeLesley Hutchins48a31762013-08-12 21:20:55 +0000750
751 D->addAttr(::new (S.Context)
David Blaikie16f76d22013-09-06 01:28:43 +0000752 ConsumableAttr(Attr.getRange(), S.Context, DefaultState,
DeLesley Hutchins5a715c42013-08-30 22:56:34 +0000753 Attr.getAttributeSpellingListIndex()));
754}
755
DeLesley Hutchinsf28bbec2014-01-14 00:36:53 +0000756
DeLesley Hutchins5a715c42013-08-30 22:56:34 +0000757static bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD,
758 const AttributeList &Attr) {
759 ASTContext &CurrContext = S.getASTContext();
760 QualType ThisType = MD->getThisType(CurrContext)->getPointeeType();
761
762 if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) {
763 if (!RD->hasAttr<ConsumableAttr>()) {
764 S.Diag(Attr.getLoc(), diag::warn_attr_on_unconsumable_class) <<
765 RD->getNameAsString();
766
767 return false;
768 }
769 }
770
771 return true;
772}
773
DeLesley Hutchins48a31762013-08-12 21:20:55 +0000774
DeLesley Hutchins210791a2013-10-04 21:28:06 +0000775static void handleCallableWhenAttr(Sema &S, Decl *D,
776 const AttributeList &Attr) {
Aaron Ballmandbd586f2013-10-14 23:26:04 +0000777 if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
778 return;
DeLesley Hutchins48a31762013-08-12 21:20:55 +0000779
DeLesley Hutchins5a715c42013-08-30 22:56:34 +0000780 if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr))
781 return;
782
DeLesley Hutchins210791a2013-10-04 21:28:06 +0000783 SmallVector<CallableWhenAttr::ConsumedState, 3> States;
784 for (unsigned ArgIndex = 0; ArgIndex < Attr.getNumArgs(); ++ArgIndex) {
785 CallableWhenAttr::ConsumedState CallableState;
786
Aaron Ballman4c9b7dc2013-10-05 22:45:34 +0000787 StringRef StateString;
788 SourceLocation Loc;
789 if (!S.checkStringLiteralArgumentAttr(Attr, ArgIndex, StateString, &Loc))
790 return;
791
792 if (!CallableWhenAttr::ConvertStrToConsumedState(StateString,
DeLesley Hutchins69391772013-10-17 23:23:53 +0000793 CallableState)) {
Aaron Ballman4c9b7dc2013-10-05 22:45:34 +0000794 S.Diag(Loc, diag::warn_attribute_type_not_supported)
795 << Attr.getName() << StateString;
DeLesley Hutchins210791a2013-10-04 21:28:06 +0000796 return;
797 }
Aaron Ballman4c9b7dc2013-10-05 22:45:34 +0000798
799 States.push_back(CallableState);
DeLesley Hutchins210791a2013-10-04 21:28:06 +0000800 }
801
DeLesley Hutchins48a31762013-08-12 21:20:55 +0000802 D->addAttr(::new (S.Context)
DeLesley Hutchins210791a2013-10-04 21:28:06 +0000803 CallableWhenAttr(Attr.getRange(), S.Context, States.data(),
804 States.size(), Attr.getAttributeSpellingListIndex()));
DeLesley Hutchins48a31762013-08-12 21:20:55 +0000805}
806
DeLesley Hutchins48a31762013-08-12 21:20:55 +0000807
DeLesley Hutchins69391772013-10-17 23:23:53 +0000808static void handleParamTypestateAttr(Sema &S, Decl *D,
809 const AttributeList &Attr) {
810 if (!checkAttributeNumArgs(S, Attr, 1)) return;
Aaron Ballman74eeeae2013-11-27 13:27:02 +0000811
DeLesley Hutchins69391772013-10-17 23:23:53 +0000812 ParamTypestateAttr::ConsumedState ParamState;
813
814 if (Attr.isArgIdent(0)) {
815 IdentifierLoc *Ident = Attr.getArgAsIdent(0);
816 StringRef StateString = Ident->Ident->getName();
817
818 if (!ParamTypestateAttr::ConvertStrToConsumedState(StateString,
819 ParamState)) {
820 S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported)
821 << Attr.getName() << StateString;
822 return;
823 }
824 } else {
825 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) <<
826 Attr.getName() << AANT_ArgumentIdentifier;
827 return;
828 }
829
830 // FIXME: This check is currently being done in the analysis. It can be
831 // enabled here only after the parser propagates attributes at
832 // template specialization definition, not declaration.
833 //QualType ReturnType = cast<ParmVarDecl>(D)->getType();
834 //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
835 //
836 //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
837 // S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
838 // ReturnType.getAsString();
839 // return;
840 //}
841
842 D->addAttr(::new (S.Context)
843 ParamTypestateAttr(Attr.getRange(), S.Context, ParamState,
844 Attr.getAttributeSpellingListIndex()));
845}
846
847
DeLesley Hutchinsfc368252013-09-03 20:11:38 +0000848static void handleReturnTypestateAttr(Sema &S, Decl *D,
849 const AttributeList &Attr) {
DeLesley Hutchins36ea1dd2013-10-17 22:53:04 +0000850 if (!checkAttributeNumArgs(S, Attr, 1)) return;
851
DeLesley Hutchinsfc368252013-09-03 20:11:38 +0000852 ReturnTypestateAttr::ConsumedState ReturnState;
853
854 if (Attr.isArgIdent(0)) {
Aaron Ballman682ee422013-09-11 19:47:58 +0000855 IdentifierLoc *IL = Attr.getArgAsIdent(0);
856 if (!ReturnTypestateAttr::ConvertStrToConsumedState(IL->Ident->getName(),
857 ReturnState)) {
858 S.Diag(IL->Loc, diag::warn_attribute_type_not_supported)
859 << Attr.getName() << IL->Ident;
DeLesley Hutchinsfc368252013-09-03 20:11:38 +0000860 return;
861 }
DeLesley Hutchinsfc368252013-09-03 20:11:38 +0000862 } else {
863 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) <<
864 Attr.getName() << AANT_ArgumentIdentifier;
865 return;
866 }
867
DeLesley Hutchinsfc368252013-09-03 20:11:38 +0000868 // FIXME: This check is currently being done in the analysis. It can be
869 // enabled here only after the parser propagates attributes at
870 // template specialization definition, not declaration.
871 //QualType ReturnType;
872 //
DeLesley Hutchins36ea1dd2013-10-17 22:53:04 +0000873 //if (const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D)) {
874 // ReturnType = Param->getType();
875 //
876 //} else if (const CXXConstructorDecl *Constructor =
877 // dyn_cast<CXXConstructorDecl>(D)) {
DeLesley Hutchinsfc368252013-09-03 20:11:38 +0000878 // ReturnType = Constructor->getThisType(S.getASTContext())->getPointeeType();
879 //
880 //} else {
881 //
882 // ReturnType = cast<FunctionDecl>(D)->getCallResultType();
883 //}
884 //
885 //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
886 //
887 //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
888 // S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
889 // ReturnType.getAsString();
890 // return;
891 //}
892
893 D->addAttr(::new (S.Context)
894 ReturnTypestateAttr(Attr.getRange(), S.Context, ReturnState,
895 Attr.getAttributeSpellingListIndex()));
896}
897
DeLesley Hutchins33a29342013-10-11 23:03:26 +0000898
899static void handleSetTypestateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Aaron Ballmandbd586f2013-10-14 23:26:04 +0000900 if (!checkAttributeNumArgs(S, Attr, 1))
901 return;
DeLesley Hutchins33a29342013-10-11 23:03:26 +0000902
903 if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr))
904 return;
905
906 SetTypestateAttr::ConsumedState NewState;
DeLesley Hutchins33a29342013-10-11 23:03:26 +0000907 if (Attr.isArgIdent(0)) {
Aaron Ballman91c98e12013-10-14 23:22:37 +0000908 IdentifierLoc *Ident = Attr.getArgAsIdent(0);
909 StringRef Param = Ident->Ident->getName();
910 if (!SetTypestateAttr::ConvertStrToConsumedState(Param, NewState)) {
911 S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported)
912 << Attr.getName() << Param;
DeLesley Hutchins33a29342013-10-11 23:03:26 +0000913 return;
914 }
DeLesley Hutchins33a29342013-10-11 23:03:26 +0000915 } else {
916 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) <<
917 Attr.getName() << AANT_ArgumentIdentifier;
918 return;
919 }
920
921 D->addAttr(::new (S.Context)
922 SetTypestateAttr(Attr.getRange(), S.Context, NewState,
923 Attr.getAttributeSpellingListIndex()));
924}
925
Chris Wailes9385f9f2013-10-29 20:28:41 +0000926static void handleTestTypestateAttr(Sema &S, Decl *D,
927 const AttributeList &Attr) {
Aaron Ballmandbd586f2013-10-14 23:26:04 +0000928 if (!checkAttributeNumArgs(S, Attr, 1))
929 return;
DeLesley Hutchins33a29342013-10-11 23:03:26 +0000930
DeLesley Hutchins33a29342013-10-11 23:03:26 +0000931 if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr))
932 return;
933
Chris Wailes9385f9f2013-10-29 20:28:41 +0000934 TestTypestateAttr::ConsumedState TestState;
DeLesley Hutchins33a29342013-10-11 23:03:26 +0000935 if (Attr.isArgIdent(0)) {
Aaron Ballman91c98e12013-10-14 23:22:37 +0000936 IdentifierLoc *Ident = Attr.getArgAsIdent(0);
937 StringRef Param = Ident->Ident->getName();
Chris Wailes9385f9f2013-10-29 20:28:41 +0000938 if (!TestTypestateAttr::ConvertStrToConsumedState(Param, TestState)) {
Aaron Ballman91c98e12013-10-14 23:22:37 +0000939 S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported)
940 << Attr.getName() << Param;
DeLesley Hutchins33a29342013-10-11 23:03:26 +0000941 return;
942 }
DeLesley Hutchins33a29342013-10-11 23:03:26 +0000943 } else {
944 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) <<
945 Attr.getName() << AANT_ArgumentIdentifier;
946 return;
947 }
948
949 D->addAttr(::new (S.Context)
Chris Wailes9385f9f2013-10-29 20:28:41 +0000950 TestTypestateAttr(Attr.getRange(), S.Context, TestState,
DeLesley Hutchins33a29342013-10-11 23:03:26 +0000951 Attr.getAttributeSpellingListIndex()));
952}
953
Chandler Carruthedc2c642011-07-02 00:01:44 +0000954static void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
955 const AttributeList &Attr) {
Richard Smith1f5a4322013-01-13 02:11:23 +0000956 // Remember this typedef decl, we will need it later for diagnostics.
Aaron Ballman74eeeae2013-11-27 13:27:02 +0000957 S.ExtVectorDecls.push_back(cast<TypedefNameDecl>(D));
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000958}
959
Chandler Carruthedc2c642011-07-02 00:01:44 +0000960static void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000961 if (TagDecl *TD = dyn_cast<TagDecl>(D))
Aaron Ballman36a53502014-01-16 13:03:14 +0000962 TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context,
963 Attr.getAttributeSpellingListIndex()));
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000964 else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000965 // If the alignment is less than or equal to 8 bits, the packed attribute
966 // has no effect.
Eli Friedmanc087c3f2012-11-07 00:35:20 +0000967 if (!FD->getType()->isDependentType() &&
968 !FD->getType()->isIncompleteType() &&
Chris Lattnerb632a6e2008-06-29 00:43:07 +0000969 S.Context.getTypeAlign(FD->getType()) <= 8)
Chris Lattner3b054132008-11-19 05:08:23 +0000970 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
Chris Lattnere3d20d92008-11-23 21:45:46 +0000971 << Attr.getName() << FD->getType();
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000972 else
Michael Han99315932013-01-24 16:46:58 +0000973 FD->addAttr(::new (S.Context)
974 PackedAttr(Attr.getRange(), S.Context,
975 Attr.getAttributeSpellingListIndex()));
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000976 } else
Chris Lattner4bd8dd82008-11-19 08:23:25 +0000977 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000978}
979
Ted Kremenek7fd17232011-09-29 07:02:25 +0000980static bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) {
981 // The IBOutlet/IBOutletCollection attributes only apply to instance
982 // variables or properties of Objective-C classes. The outlet must also
983 // have an object reference type.
984 if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) {
985 if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
Ted Kremenek5d6044e2011-11-01 18:08:35 +0000986 S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
Ted Kremenek7fd17232011-09-29 07:02:25 +0000987 << Attr.getName() << VD->getType() << 0;
988 return false;
989 }
990 }
991 else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
992 if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
Douglas Gregor5c3cc422012-03-14 16:55:17 +0000993 S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
Ted Kremenek7fd17232011-09-29 07:02:25 +0000994 << Attr.getName() << PD->getType() << 1;
995 return false;
996 }
997 }
998 else {
999 S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
1000 return false;
1001 }
Douglas Gregor5c3cc422012-03-14 16:55:17 +00001002
Ted Kremenek7fd17232011-09-29 07:02:25 +00001003 return true;
1004}
1005
Chandler Carruthedc2c642011-07-02 00:01:44 +00001006static void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
Ted Kremenek7fd17232011-09-29 07:02:25 +00001007 if (!checkIBOutletCommon(S, D, Attr))
Ted Kremenek1f672822010-02-18 03:08:58 +00001008 return;
Ted Kremenek1f672822010-02-18 03:08:58 +00001009
Michael Han99315932013-01-24 16:46:58 +00001010 D->addAttr(::new (S.Context)
1011 IBOutletAttr(Attr.getRange(), S.Context,
1012 Attr.getAttributeSpellingListIndex()));
Ted Kremenek8e3704d2008-07-15 22:26:48 +00001013}
1014
Chandler Carruthedc2c642011-07-02 00:01:44 +00001015static void handleIBOutletCollection(Sema &S, Decl *D,
1016 const AttributeList &Attr) {
Ted Kremenek26bde772010-05-19 17:38:06 +00001017
1018 // The iboutletcollection attribute can have zero or one arguments.
Aaron Ballman00e99962013-08-31 01:11:41 +00001019 if (Attr.getNumArgs() > 1) {
Aaron Ballmanb7243382013-07-23 19:30:11 +00001020 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
1021 << Attr.getName() << 1;
Ted Kremenek26bde772010-05-19 17:38:06 +00001022 return;
1023 }
1024
Ted Kremenek7fd17232011-09-29 07:02:25 +00001025 if (!checkIBOutletCommon(S, D, Attr))
Ted Kremenek26bde772010-05-19 17:38:06 +00001026 return;
Ted Kremenek7fd17232011-09-29 07:02:25 +00001027
Richard Smithb1f9a282013-10-31 01:56:18 +00001028 ParsedType PT;
1029
1030 if (Attr.hasParsedType())
1031 PT = Attr.getTypeArg();
1032 else {
1033 PT = S.getTypeName(S.Context.Idents.get("NSObject"), Attr.getLoc(),
1034 S.getScopeForContext(D->getDeclContext()->getParent()));
1035 if (!PT) {
1036 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << "NSObject";
1037 return;
1038 }
Aaron Ballman00e99962013-08-31 01:11:41 +00001039 }
Richard Smithb1f9a282013-10-31 01:56:18 +00001040
Richard Smithb87c4652013-10-31 21:23:20 +00001041 TypeSourceInfo *QTLoc = 0;
1042 QualType QT = S.GetTypeFromParser(PT, &QTLoc);
1043 if (!QTLoc)
1044 QTLoc = S.Context.getTrivialTypeSourceInfo(QT, Attr.getLoc());
Richard Smithb1f9a282013-10-31 01:56:18 +00001045
Fariborz Jahanianb5d59b62010-08-17 20:23:12 +00001046 // Diagnose use of non-object type in iboutletcollection attribute.
1047 // FIXME. Gnu attribute extension ignores use of builtin types in
1048 // attributes. So, __attribute__((iboutletcollection(char))) will be
1049 // treated as __attribute__((iboutletcollection())).
Fariborz Jahanian2f31b332011-10-18 19:54:31 +00001050 if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {
Richard Smithb1f9a282013-10-31 01:56:18 +00001051 S.Diag(Attr.getLoc(),
1052 QT->isBuiltinType() ? diag::err_iboutletcollection_builtintype
1053 : diag::err_iboutletcollection_type) << QT;
Fariborz Jahanianb5d59b62010-08-17 20:23:12 +00001054 return;
1055 }
Richard Smithb1f9a282013-10-31 01:56:18 +00001056
Michael Han99315932013-01-24 16:46:58 +00001057 D->addAttr(::new (S.Context)
Richard Smithb87c4652013-10-31 21:23:20 +00001058 IBOutletCollectionAttr(Attr.getRange(), S.Context, QTLoc,
Michael Han99315932013-01-24 16:46:58 +00001059 Attr.getAttributeSpellingListIndex()));
Ted Kremenek26bde772010-05-19 17:38:06 +00001060}
1061
Chandler Carruth3ed22c32011-07-01 23:49:16 +00001062static void possibleTransparentUnionPointerType(QualType &T) {
Fariborz Jahanianf4aa2792011-06-27 21:12:03 +00001063 if (const RecordType *UT = T->getAsUnionType())
1064 if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
1065 RecordDecl *UD = UT->getDecl();
Aaron Ballmane8a8bae2014-03-08 20:12:42 +00001066 for (const auto *I : UD->fields()) {
1067 QualType QT = I->getType();
Fariborz Jahanianf4aa2792011-06-27 21:12:03 +00001068 if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
1069 T = QT;
1070 return;
1071 }
1072 }
1073 }
1074}
1075
Ted Kremenek9aedc152014-01-17 06:24:56 +00001076static bool attrNonNullArgCheck(Sema &S, QualType T, const AttributeList &Attr,
Ted Kremenekdbf62e32014-01-20 05:50:47 +00001077 SourceRange R, bool isReturnValue = false) {
Ted Kremenek9aedc152014-01-17 06:24:56 +00001078 T = T.getNonReferenceType();
1079 possibleTransparentUnionPointerType(T);
1080
1081 if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
Ted Kremenekdbf62e32014-01-20 05:50:47 +00001082 S.Diag(Attr.getLoc(),
1083 isReturnValue ? diag::warn_attribute_return_pointers_only
1084 : diag::warn_attribute_pointers_only)
Ted Kremenek9aedc152014-01-17 06:24:56 +00001085 << Attr.getName() << R;
1086 return false;
1087 }
1088 return true;
1089}
1090
Chandler Carruthedc2c642011-07-02 00:01:44 +00001091static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Aaron Ballmanbe50eb82013-07-30 00:48:57 +00001092 SmallVector<unsigned, 8> NonNullArgs;
1093 for (unsigned i = 0; i < Attr.getNumArgs(); ++i) {
Aaron Ballman00e99962013-08-31 01:11:41 +00001094 Expr *Ex = Attr.getArgAsExpr(i);
Aaron Ballmanbe50eb82013-07-30 00:48:57 +00001095 uint64_t Idx;
Alp Toker601b22c2014-01-21 23:35:24 +00001096 if (!checkFunctionOrMethodParameterIndex(S, D, Attr, i + 1, Ex, Idx))
Ted Kremenek2d63bc12008-07-21 21:53:04 +00001097 return;
Ted Kremenek2d63bc12008-07-21 21:53:04 +00001098
1099 // Is the function argument a pointer type?
Ted Kremenek9aedc152014-01-17 06:24:56 +00001100 // FIXME: Should also highlight argument in decl in the diagnostic.
Alp Toker601b22c2014-01-21 23:35:24 +00001101 if (!attrNonNullArgCheck(S, getFunctionOrMethodParamType(D, Idx), Attr,
1102 Ex->getSourceRange()))
Ted Kremenekc4f6d902008-09-01 19:57:52 +00001103 continue;
Mike Stumpd3bb5572009-07-24 19:02:52 +00001104
Aaron Ballmanbe50eb82013-07-30 00:48:57 +00001105 NonNullArgs.push_back(Idx);
Ted Kremenek2d63bc12008-07-21 21:53:04 +00001106 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001107
1108 // If no arguments were specified to __attribute__((nonnull)) then all pointer
1109 // arguments have a nonnull attribute.
Ted Kremenekc4f6d902008-09-01 19:57:52 +00001110 if (NonNullArgs.empty()) {
Alp Toker601b22c2014-01-21 23:35:24 +00001111 for (unsigned i = 0, e = getFunctionOrMethodNumParams(D); i != e; ++i) {
1112 QualType T = getFunctionOrMethodParamType(D, i).getNonReferenceType();
Chandler Carruth3ed22c32011-07-01 23:49:16 +00001113 possibleTransparentUnionPointerType(T);
Ted Kremenekd4adebb2009-07-15 23:23:54 +00001114 if (T->isAnyPointerType() || T->isBlockPointerType())
Nick Lewyckye1121512013-01-24 01:12:16 +00001115 NonNullArgs.push_back(i);
Ted Kremenek5fa50522008-11-18 06:52:58 +00001116 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001117
Ted Kremenek22813f42010-10-21 18:49:36 +00001118 // No pointer arguments?
Fariborz Jahaniancb67d7b2010-09-27 19:05:51 +00001119 if (NonNullArgs.empty()) {
1120 // Warn the trivial case only if attribute is not coming from a
1121 // macro instantiation.
1122 if (Attr.getLoc().isFileID())
1123 S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
Ted Kremenekc4f6d902008-09-01 19:57:52 +00001124 return;
Fariborz Jahaniancb67d7b2010-09-27 19:05:51 +00001125 }
Ted Kremenek2d63bc12008-07-21 21:53:04 +00001126 }
Ted Kremenekc4f6d902008-09-01 19:57:52 +00001127
Nick Lewyckye1121512013-01-24 01:12:16 +00001128 unsigned *start = &NonNullArgs[0];
Ted Kremenekc4f6d902008-09-01 19:57:52 +00001129 unsigned size = NonNullArgs.size();
Ted Kremenekd21139a2010-07-31 01:52:11 +00001130 llvm::array_pod_sort(start, start + size);
Michael Han99315932013-01-24 16:46:58 +00001131 D->addAttr(::new (S.Context)
1132 NonNullAttr(Attr.getRange(), S.Context, start, size,
1133 Attr.getAttributeSpellingListIndex()));
Ted Kremenek2d63bc12008-07-21 21:53:04 +00001134}
1135
Jordan Rosec9399072014-02-11 17:27:59 +00001136static void handleNonNullAttrParameter(Sema &S, ParmVarDecl *D,
1137 const AttributeList &Attr) {
1138 if (Attr.getNumArgs() > 0) {
1139 if (D->getFunctionType()) {
1140 handleNonNullAttr(S, D, Attr);
1141 } else {
1142 S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_parm_no_args)
1143 << D->getSourceRange();
1144 }
1145 return;
1146 }
1147
1148 // Is the argument a pointer type?
1149 if (!attrNonNullArgCheck(S, D->getType(), Attr, D->getSourceRange()))
1150 return;
1151
1152 D->addAttr(::new (S.Context)
1153 NonNullAttr(Attr.getRange(), S.Context, 0, 0,
1154 Attr.getAttributeSpellingListIndex()));
1155}
1156
Ted Kremenekdbf62e32014-01-20 05:50:47 +00001157static void handleReturnsNonNullAttr(Sema &S, Decl *D,
1158 const AttributeList &Attr) {
Aaron Ballmanfc1951c2014-01-20 14:19:44 +00001159 QualType ResultType = getFunctionOrMethodResultType(D);
Ted Kremenekdbf62e32014-01-20 05:50:47 +00001160 if (!attrNonNullArgCheck(S, ResultType, Attr, Attr.getRange(),
1161 /* isReturnValue */ true))
1162 return;
1163
1164 D->addAttr(::new (S.Context)
1165 ReturnsNonNullAttr(Attr.getRange(), S.Context,
1166 Attr.getAttributeSpellingListIndex()));
1167}
1168
Chandler Carruthedc2c642011-07-02 00:01:44 +00001169static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
Aaron Ballman6e2dd7b2013-09-16 18:11:41 +00001170 // This attribute must be applied to a function declaration. The first
1171 // argument to the attribute must be an identifier, the name of the resource,
1172 // for example: malloc. The following arguments must be argument indexes, the
1173 // arguments must be of integer type for Returns, otherwise of pointer type.
Ted Kremenekd21139a2010-07-31 01:52:11 +00001174 // The difference between Holds and Takes is that a pointer may still be used
Aaron Ballman6e2dd7b2013-09-16 18:11:41 +00001175 // after being held. free() should be __attribute((ownership_takes)), whereas
Jordy Rose5af0e3c2010-08-12 08:54:03 +00001176 // a list append function may well be __attribute((ownership_holds)).
Ted Kremenekd21139a2010-07-31 01:52:11 +00001177
Aaron Ballman00e99962013-08-31 01:11:41 +00001178 if (!AL.isArgIdent(0)) {
Aaron Ballman29982272013-07-23 14:03:57 +00001179 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
Aaron Ballman6e2dd7b2013-09-16 18:11:41 +00001180 << AL.getName() << 1 << AANT_ArgumentIdentifier;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001181 return;
1182 }
Aaron Ballman6e2dd7b2013-09-16 18:11:41 +00001183
Richard Smith852e9ce2013-11-27 01:46:48 +00001184 // Figure out our Kind.
1185 OwnershipAttr::OwnershipKind K =
1186 OwnershipAttr(AL.getLoc(), S.Context, 0, 0, 0,
1187 AL.getAttributeSpellingListIndex()).getOwnKind();
Aaron Ballman6e2dd7b2013-09-16 18:11:41 +00001188
Richard Smith852e9ce2013-11-27 01:46:48 +00001189 // Check arguments.
1190 switch (K) {
1191 case OwnershipAttr::Takes:
1192 case OwnershipAttr::Holds:
1193 if (AL.getNumArgs() < 2) {
Aaron Ballman05e420a2014-01-02 21:26:14 +00001194 S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments)
1195 << AL.getName() << 2;
Richard Smith852e9ce2013-11-27 01:46:48 +00001196 return;
1197 }
1198 break;
1199 case OwnershipAttr::Returns:
Aaron Ballman00e99962013-08-31 01:11:41 +00001200 if (AL.getNumArgs() > 2) {
Aaron Ballman05e420a2014-01-02 21:26:14 +00001201 S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments)
1202 << AL.getName() << 1;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001203 return;
1204 }
Jordy Rose5af0e3c2010-08-12 08:54:03 +00001205 break;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001206 }
1207
Richard Smith852e9ce2013-11-27 01:46:48 +00001208 IdentifierInfo *Module = AL.getArgAsIdent(0)->Ident;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001209
1210 // Normalize the argument, __foo__ becomes foo.
Richard Smith852e9ce2013-11-27 01:46:48 +00001211 StringRef ModuleName = Module->getName();
1212 if (ModuleName.startswith("__") && ModuleName.endswith("__") &&
1213 ModuleName.size() > 4) {
1214 ModuleName = ModuleName.drop_front(2).drop_back(2);
1215 Module = &S.PP.getIdentifierTable().get(ModuleName);
1216 }
Ted Kremenekd21139a2010-07-31 01:52:11 +00001217
Aaron Ballmanbe50eb82013-07-30 00:48:57 +00001218 SmallVector<unsigned, 8> OwnershipArgs;
Aaron Ballman00e99962013-08-31 01:11:41 +00001219 for (unsigned i = 1; i < AL.getNumArgs(); ++i) {
1220 Expr *Ex = AL.getArgAsExpr(i);
Aaron Ballmanbe50eb82013-07-30 00:48:57 +00001221 uint64_t Idx;
Alp Toker601b22c2014-01-21 23:35:24 +00001222 if (!checkFunctionOrMethodParameterIndex(S, D, AL, i, Ex, Idx))
Aaron Ballmanbe50eb82013-07-30 00:48:57 +00001223 return;
Chandler Carruth743682b2010-11-16 08:35:43 +00001224
Aaron Ballman6e2dd7b2013-09-16 18:11:41 +00001225 // Is the function argument a pointer type?
Alp Toker601b22c2014-01-21 23:35:24 +00001226 QualType T = getFunctionOrMethodParamType(D, Idx);
Aaron Ballman6e2dd7b2013-09-16 18:11:41 +00001227 int Err = -1; // No error
Ted Kremenekd21139a2010-07-31 01:52:11 +00001228 switch (K) {
Aaron Ballman6e2dd7b2013-09-16 18:11:41 +00001229 case OwnershipAttr::Takes:
1230 case OwnershipAttr::Holds:
1231 if (!T->isAnyPointerType() && !T->isBlockPointerType())
1232 Err = 0;
1233 break;
1234 case OwnershipAttr::Returns:
1235 if (!T->isIntegerType())
1236 Err = 1;
1237 break;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001238 }
Aaron Ballman6e2dd7b2013-09-16 18:11:41 +00001239 if (-1 != Err) {
Fariborz Jahanian8a5e9472013-09-19 16:37:20 +00001240 S.Diag(AL.getLoc(), diag::err_ownership_type) << AL.getName() << Err
Aaron Ballman6e2dd7b2013-09-16 18:11:41 +00001241 << Ex->getSourceRange();
1242 return;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001243 }
Ted Kremenekd21139a2010-07-31 01:52:11 +00001244
1245 // Check we don't have a conflict with another ownership attribute.
Aaron Ballmanbe22bcb2014-03-10 17:08:28 +00001246 for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
Richard Smith852e9ce2013-11-27 01:46:48 +00001247 // FIXME: A returns attribute should conflict with any returns attribute
1248 // with a different index too.
Aaron Ballmanbe22bcb2014-03-10 17:08:28 +00001249 if (I->getOwnKind() != K && I->args_end() !=
1250 std::find(I->args_begin(), I->args_end(), Idx)) {
Aaron Ballman6e2dd7b2013-09-16 18:11:41 +00001251 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
Aaron Ballmanbe22bcb2014-03-10 17:08:28 +00001252 << AL.getName() << I;
Aaron Ballman6e2dd7b2013-09-16 18:11:41 +00001253 return;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001254 }
1255 }
Aaron Ballmanbe50eb82013-07-30 00:48:57 +00001256 OwnershipArgs.push_back(Idx);
Ted Kremenekd21139a2010-07-31 01:52:11 +00001257 }
1258
1259 unsigned* start = OwnershipArgs.data();
1260 unsigned size = OwnershipArgs.size();
1261 llvm::array_pod_sort(start, start + size);
Alexis Huntdcfba7b2010-08-18 23:23:40 +00001262
Michael Han99315932013-01-24 16:46:58 +00001263 D->addAttr(::new (S.Context)
Richard Smith852e9ce2013-11-27 01:46:48 +00001264 OwnershipAttr(AL.getLoc(), S.Context, Module, start, size,
Michael Han99315932013-01-24 16:46:58 +00001265 AL.getAttributeSpellingListIndex()));
Ted Kremenekd21139a2010-07-31 01:52:11 +00001266}
1267
Chandler Carruthedc2c642011-07-02 00:01:44 +00001268static void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Rafael Espindolac18086a2010-02-23 22:00:30 +00001269 // Check the attribute arguments.
1270 if (Attr.getNumArgs() > 1) {
Aaron Ballmanb7243382013-07-23 19:30:11 +00001271 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
1272 << Attr.getName() << 1;
Rafael Espindolac18086a2010-02-23 22:00:30 +00001273 return;
1274 }
1275
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001276 NamedDecl *nd = cast<NamedDecl>(D);
John McCall7a198ce2011-02-08 22:35:49 +00001277
Rafael Espindolac18086a2010-02-23 22:00:30 +00001278 // gcc rejects
1279 // class c {
1280 // static int a __attribute__((weakref ("v2")));
1281 // static int b() __attribute__((weakref ("f3")));
1282 // };
1283 // and ignores the attributes of
1284 // void f(void) {
1285 // static int a __attribute__((weakref ("v2")));
1286 // }
1287 // we reject them
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001288 const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
Sebastian Redl50c68252010-08-31 00:36:30 +00001289 if (!Ctx->isFileContext()) {
Aaron Ballman9f6fec42014-01-02 23:02:01 +00001290 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context)
1291 << nd;
Sebastian Redl50c68252010-08-31 00:36:30 +00001292 return;
Rafael Espindolac18086a2010-02-23 22:00:30 +00001293 }
1294
1295 // The GCC manual says
1296 //
1297 // At present, a declaration to which `weakref' is attached can only
1298 // be `static'.
1299 //
1300 // It also says
1301 //
1302 // Without a TARGET,
1303 // given as an argument to `weakref' or to `alias', `weakref' is
1304 // equivalent to `weak'.
1305 //
1306 // gcc 4.4.1 will accept
1307 // int a7 __attribute__((weakref));
1308 // as
1309 // int a7 __attribute__((weak));
1310 // This looks like a bug in gcc. We reject that for now. We should revisit
1311 // it if this behaviour is actually used.
1312
Rafael Espindolac18086a2010-02-23 22:00:30 +00001313 // GCC rejects
1314 // static ((alias ("y"), weakref)).
1315 // Should we? How to check that weakref is before or after alias?
1316
Aaron Ballmanfebff0c2013-09-09 23:40:31 +00001317 // FIXME: it would be good for us to keep the WeakRefAttr as-written instead
1318 // of transforming it into an AliasAttr. The WeakRefAttr never uses the
1319 // StringRef parameter it was given anyway.
Aaron Ballman3b1dde62013-09-13 19:35:18 +00001320 StringRef Str;
Tim Northover6a6b63b2013-10-01 14:34:18 +00001321 if (Attr.getNumArgs() && S.checkStringLiteralArgumentAttr(Attr, 0, Str))
Rafael Espindolac18086a2010-02-23 22:00:30 +00001322 // GCC will accept anything as the argument of weakref. Should we
1323 // check for an existing decl?
Aaron Ballman3b1dde62013-09-13 19:35:18 +00001324 D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, Str,
1325 Attr.getAttributeSpellingListIndex()));
Rafael Espindolac18086a2010-02-23 22:00:30 +00001326
Michael Han99315932013-01-24 16:46:58 +00001327 D->addAttr(::new (S.Context)
1328 WeakRefAttr(Attr.getRange(), S.Context,
1329 Attr.getAttributeSpellingListIndex()));
Rafael Espindolac18086a2010-02-23 22:00:30 +00001330}
1331
Benjamin Kramer6ee15622013-09-13 15:35:43 +00001332static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1333 StringRef Str;
Tim Northover6a6b63b2013-10-01 14:34:18 +00001334 if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str))
Benjamin Kramer6ee15622013-09-13 15:35:43 +00001335 return;
1336
Douglas Gregore8bbc122011-09-02 00:18:52 +00001337 if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
Rafael Espindola0017c5f2010-12-07 15:23:23 +00001338 S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
1339 return;
1340 }
1341
Chris Lattner2c6fcf52008-06-26 18:38:35 +00001342 // FIXME: check if target symbol exists in current file
Mike Stumpd3bb5572009-07-24 19:02:52 +00001343
Benjamin Kramer6ee15622013-09-13 15:35:43 +00001344 D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, Str,
Michael Han99315932013-01-24 16:46:58 +00001345 Attr.getAttributeSpellingListIndex()));
Chris Lattner2c6fcf52008-06-26 18:38:35 +00001346}
1347
Benjamin Kramer29c2b432012-05-12 21:10:52 +00001348static void handleColdAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Aaron Ballman2cfbc002014-01-03 16:23:46 +00001349 if (checkAttrMutualExclusion<HotAttr>(S, D, Attr))
Benjamin Kramer29c2b432012-05-12 21:10:52 +00001350 return;
Benjamin Kramer29c2b432012-05-12 21:10:52 +00001351
Michael Han99315932013-01-24 16:46:58 +00001352 D->addAttr(::new (S.Context) ColdAttr(Attr.getRange(), S.Context,
1353 Attr.getAttributeSpellingListIndex()));
Benjamin Kramer29c2b432012-05-12 21:10:52 +00001354}
1355
1356static void handleHotAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Aaron Ballman2cfbc002014-01-03 16:23:46 +00001357 if (checkAttrMutualExclusion<ColdAttr>(S, D, Attr))
Benjamin Kramer29c2b432012-05-12 21:10:52 +00001358 return;
Benjamin Kramer29c2b432012-05-12 21:10:52 +00001359
Michael Han99315932013-01-24 16:46:58 +00001360 D->addAttr(::new (S.Context) HotAttr(Attr.getRange(), S.Context,
1361 Attr.getAttributeSpellingListIndex()));
Benjamin Kramer29c2b432012-05-12 21:10:52 +00001362}
1363
Hans Wennborgd3b01bc2012-06-23 11:51:46 +00001364static void handleTLSModelAttr(Sema &S, Decl *D,
1365 const AttributeList &Attr) {
Benjamin Kramer6ee15622013-09-13 15:35:43 +00001366 StringRef Model;
1367 SourceLocation LiteralLoc;
Hans Wennborgd3b01bc2012-06-23 11:51:46 +00001368 // Check that it is a string.
Tim Northover6a6b63b2013-10-01 14:34:18 +00001369 if (!S.checkStringLiteralArgumentAttr(Attr, 0, Model, &LiteralLoc))
Hans Wennborgd3b01bc2012-06-23 11:51:46 +00001370 return;
Hans Wennborgd3b01bc2012-06-23 11:51:46 +00001371
Hans Wennborgd3b01bc2012-06-23 11:51:46 +00001372 // Check that the value.
Hans Wennborgd3b01bc2012-06-23 11:51:46 +00001373 if (Model != "global-dynamic" && Model != "local-dynamic"
1374 && Model != "initial-exec" && Model != "local-exec") {
Benjamin Kramer6ee15622013-09-13 15:35:43 +00001375 S.Diag(LiteralLoc, diag::err_attr_tlsmodel_arg);
Hans Wennborgd3b01bc2012-06-23 11:51:46 +00001376 return;
1377 }
1378
Michael Han99315932013-01-24 16:46:58 +00001379 D->addAttr(::new (S.Context)
1380 TLSModelAttr(Attr.getRange(), S.Context, Model,
1381 Attr.getAttributeSpellingListIndex()));
Hans Wennborgd3b01bc2012-06-23 11:51:46 +00001382}
1383
Chandler Carruthedc2c642011-07-02 00:01:44 +00001384static void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001385 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
Alp Toker314cc812014-01-25 16:55:45 +00001386 QualType RetTy = FD->getReturnType();
Ted Kremenek08479ae2009-08-15 00:51:46 +00001387 if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
Michael Han99315932013-01-24 16:46:58 +00001388 D->addAttr(::new (S.Context)
1389 MallocAttr(Attr.getRange(), S.Context,
1390 Attr.getAttributeSpellingListIndex()));
Ted Kremenek08479ae2009-08-15 00:51:46 +00001391 return;
1392 }
Ryan Flynn1f1fdc02009-08-09 20:07:29 +00001393 }
1394
Ted Kremenek08479ae2009-08-15 00:51:46 +00001395 S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
Ryan Flynn1f1fdc02009-08-09 20:07:29 +00001396}
1397
Chandler Carruthedc2c642011-07-02 00:01:44 +00001398static void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Eli Friedman6fc7ad12013-06-20 22:55:04 +00001399 if (S.LangOpts.CPlusPlus) {
Aaron Ballman3db89662013-11-24 21:48:06 +00001400 S.Diag(Attr.getLoc(), diag::err_attribute_not_supported_in_lang)
1401 << Attr.getName() << AttributeLangSupport::Cpp;
Eli Friedman6fc7ad12013-06-20 22:55:04 +00001402 return;
1403 }
1404
Aaron Ballman74eeeae2013-11-27 13:27:02 +00001405 D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context,
1406 Attr.getAttributeSpellingListIndex()));
Eric Christopher8a2ee392010-12-02 02:45:55 +00001407}
1408
Chandler Carruthedc2c642011-07-02 00:01:44 +00001409static void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001410 if (hasDeclarator(D)) return;
John McCall3882ace2011-01-05 12:14:39 +00001411
1412 if (S.CheckNoReturnAttr(attr)) return;
1413
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001414 if (!isa<ObjCMethodDecl>(D)) {
John McCall3882ace2011-01-05 12:14:39 +00001415 S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00001416 << attr.getName() << ExpectedFunctionOrMethod;
John McCall3882ace2011-01-05 12:14:39 +00001417 return;
1418 }
1419
Michael Han99315932013-01-24 16:46:58 +00001420 D->addAttr(::new (S.Context)
1421 NoReturnAttr(attr.getRange(), S.Context,
1422 attr.getAttributeSpellingListIndex()));
John McCall3882ace2011-01-05 12:14:39 +00001423}
1424
1425bool Sema::CheckNoReturnAttr(const AttributeList &attr) {
Aaron Ballman00e99962013-08-31 01:11:41 +00001426 if (!checkAttributeNumArgs(*this, attr, 0)) {
John McCall3882ace2011-01-05 12:14:39 +00001427 attr.setInvalid();
1428 return true;
1429 }
1430
1431 return false;
Ted Kremenek40f4ee72009-04-10 00:01:14 +00001432}
1433
Chandler Carruthedc2c642011-07-02 00:01:44 +00001434static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
1435 const AttributeList &Attr) {
Ted Kremenek5295ce82010-08-19 00:51:58 +00001436
1437 // The checking path for 'noreturn' and 'analyzer_noreturn' are different
1438 // because 'analyzer_noreturn' does not impact the type.
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001439 if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
1440 ValueDecl *VD = dyn_cast<ValueDecl>(D);
Ted Kremenek5295ce82010-08-19 00:51:58 +00001441 if (VD == 0 || (!VD->getType()->isBlockPointerType()
1442 && !VD->getType()->isFunctionPointerType())) {
1443 S.Diag(Attr.getLoc(),
Richard Smith89645bc2013-01-02 12:01:23 +00001444 Attr.isCXX11Attribute() ? diag::err_attribute_wrong_decl_type
Ted Kremenek5295ce82010-08-19 00:51:58 +00001445 : diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00001446 << Attr.getName() << ExpectedFunctionMethodOrBlock;
Ted Kremenek5295ce82010-08-19 00:51:58 +00001447 return;
1448 }
1449 }
1450
Michael Han99315932013-01-24 16:46:58 +00001451 D->addAttr(::new (S.Context)
1452 AnalyzerNoReturnAttr(Attr.getRange(), S.Context,
1453 Attr.getAttributeSpellingListIndex()));
Chris Lattner2c6fcf52008-06-26 18:38:35 +00001454}
1455
John Thompsoncdb847ba2010-08-09 21:53:52 +00001456// PS3 PPU-specific.
Chandler Carruthedc2c642011-07-02 00:01:44 +00001457static void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
John Thompsoncdb847ba2010-08-09 21:53:52 +00001458/*
1459 Returning a Vector Class in Registers
1460
Eric Christopherbc638a82010-12-01 22:13:54 +00001461 According to the PPU ABI specifications, a class with a single member of
1462 vector type is returned in memory when used as the return value of a function.
1463 This results in inefficient code when implementing vector classes. To return
1464 the value in a single vector register, add the vecreturn attribute to the
1465 class definition. This attribute is also applicable to struct types.
John Thompsoncdb847ba2010-08-09 21:53:52 +00001466
1467 Example:
1468
1469 struct Vector
1470 {
1471 __vector float xyzw;
1472 } __attribute__((vecreturn));
1473
1474 Vector Add(Vector lhs, Vector rhs)
1475 {
1476 Vector result;
1477 result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
1478 return result; // This will be returned in a register
1479 }
1480*/
Aaron Ballman3e424b52013-12-26 18:30:57 +00001481 if (VecReturnAttr *A = D->getAttr<VecReturnAttr>()) {
1482 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << A;
John Thompsoncdb847ba2010-08-09 21:53:52 +00001483 return;
1484 }
1485
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001486 RecordDecl *record = cast<RecordDecl>(D);
John Thompson9a587aaa2010-09-18 01:12:07 +00001487 int count = 0;
1488
1489 if (!isa<CXXRecordDecl>(record)) {
1490 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
1491 return;
1492 }
1493
1494 if (!cast<CXXRecordDecl>(record)->isPOD()) {
1495 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
1496 return;
1497 }
1498
Aaron Ballmane8a8bae2014-03-08 20:12:42 +00001499 for (const auto *I : record->fields()) {
1500 if ((count == 1) || !I->getType()->isVectorType()) {
John Thompson9a587aaa2010-09-18 01:12:07 +00001501 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
1502 return;
1503 }
1504 count++;
1505 }
1506
Michael Han99315932013-01-24 16:46:58 +00001507 D->addAttr(::new (S.Context)
1508 VecReturnAttr(Attr.getRange(), S.Context,
1509 Attr.getAttributeSpellingListIndex()));
John Thompsoncdb847ba2010-08-09 21:53:52 +00001510}
1511
Richard Smithe233fbf2013-01-28 22:42:45 +00001512static void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D,
1513 const AttributeList &Attr) {
1514 if (isa<ParmVarDecl>(D)) {
1515 // [[carries_dependency]] can only be applied to a parameter if it is a
1516 // parameter of a function declaration or lambda.
1517 if (!(Scope->getFlags() & clang::Scope::FunctionDeclarationScope)) {
1518 S.Diag(Attr.getLoc(),
1519 diag::err_carries_dependency_param_not_function_decl);
1520 return;
1521 }
Alexis Hunt96d5c762009-11-21 08:43:09 +00001522 }
Richard Smithe233fbf2013-01-28 22:42:45 +00001523
1524 D->addAttr(::new (S.Context) CarriesDependencyAttr(
1525 Attr.getRange(), S.Context,
1526 Attr.getAttributeSpellingListIndex()));
Alexis Hunt96d5c762009-11-21 08:43:09 +00001527}
1528
Chandler Carruthedc2c642011-07-02 00:01:44 +00001529static void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001530 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Rafael Espindola87198cd2013-08-16 23:18:50 +00001531 if (VD->hasLocalStorage()) {
Aaron Ballman88fe3222013-12-26 17:30:44 +00001532 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
Daniel Dunbarfee07a02009-02-13 19:23:53 +00001533 return;
1534 }
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001535 } else if (!isFunctionOrMethod(D)) {
Daniel Dunbarfee07a02009-02-13 19:23:53 +00001536 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00001537 << Attr.getName() << ExpectedVariableOrFunction;
Daniel Dunbarfee07a02009-02-13 19:23:53 +00001538 return;
1539 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001540
Michael Han99315932013-01-24 16:46:58 +00001541 D->addAttr(::new (S.Context)
1542 UsedAttr(Attr.getRange(), S.Context,
1543 Attr.getAttributeSpellingListIndex()));
Daniel Dunbarfee07a02009-02-13 19:23:53 +00001544}
1545
Chandler Carruthedc2c642011-07-02 00:01:44 +00001546static void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Daniel Dunbar032db472008-07-31 22:40:48 +00001547 // check the attribute arguments.
John McCall80ee5962011-03-02 12:15:05 +00001548 if (Attr.getNumArgs() > 1) {
Aaron Ballman05e420a2014-01-02 21:26:14 +00001549 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments)
1550 << Attr.getName() << 1;
Daniel Dunbar032db472008-07-31 22:40:48 +00001551 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00001552 }
Daniel Dunbar032db472008-07-31 22:40:48 +00001553
Aaron Ballmanf22ef5a2013-11-21 01:50:40 +00001554 uint32_t priority = ConstructorAttr::DefaultPriority;
1555 if (Attr.getNumArgs() > 0 &&
1556 !checkUInt32Argument(S, Attr, Attr.getArgAsExpr(0), priority))
1557 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00001558
Michael Han99315932013-01-24 16:46:58 +00001559 D->addAttr(::new (S.Context)
1560 ConstructorAttr(Attr.getRange(), S.Context, priority,
1561 Attr.getAttributeSpellingListIndex()));
Daniel Dunbar032db472008-07-31 22:40:48 +00001562}
1563
Chandler Carruthedc2c642011-07-02 00:01:44 +00001564static void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Daniel Dunbar032db472008-07-31 22:40:48 +00001565 // check the attribute arguments.
John McCall80ee5962011-03-02 12:15:05 +00001566 if (Attr.getNumArgs() > 1) {
Aaron Ballman05e420a2014-01-02 21:26:14 +00001567 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments)
1568 << Attr.getName() << 1;
Daniel Dunbar032db472008-07-31 22:40:48 +00001569 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00001570 }
Daniel Dunbar032db472008-07-31 22:40:48 +00001571
Aaron Ballmanf28e4992014-01-20 15:22:57 +00001572 uint32_t priority = DestructorAttr::DefaultPriority;
Aaron Ballmanf22ef5a2013-11-21 01:50:40 +00001573 if (Attr.getNumArgs() > 0 &&
1574 !checkUInt32Argument(S, Attr, Attr.getArgAsExpr(0), priority))
1575 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00001576
Michael Han99315932013-01-24 16:46:58 +00001577 D->addAttr(::new (S.Context)
1578 DestructorAttr(Attr.getRange(), S.Context, priority,
1579 Attr.getAttributeSpellingListIndex()));
Daniel Dunbar032db472008-07-31 22:40:48 +00001580}
1581
Benjamin Kramerf435ab42012-05-16 12:19:08 +00001582template <typename AttrTy>
Aaron Ballman8b8ebdd2013-07-18 13:13:52 +00001583static void handleAttrWithMessage(Sema &S, Decl *D,
1584 const AttributeList &Attr) {
Chris Lattner190aa102011-02-24 05:42:24 +00001585 unsigned NumArgs = Attr.getNumArgs();
1586 if (NumArgs > 1) {
Aaron Ballman05e420a2014-01-02 21:26:14 +00001587 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments)
1588 << Attr.getName() << 1;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00001589 return;
1590 }
Benjamin Kramerf435ab42012-05-16 12:19:08 +00001591
1592 // Handle the case where the attribute has a text message.
Chris Lattner0e62c1c2011-07-23 10:55:15 +00001593 StringRef Str;
Tim Northover6a6b63b2013-10-01 14:34:18 +00001594 if (NumArgs == 1 && !S.checkStringLiteralArgumentAttr(Attr, 0, Str))
Benjamin Kramer6ee15622013-09-13 15:35:43 +00001595 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00001596
Michael Han99315932013-01-24 16:46:58 +00001597 D->addAttr(::new (S.Context) AttrTy(Attr.getRange(), S.Context, Str,
1598 Attr.getAttributeSpellingListIndex()));
Fariborz Jahanian1470e932008-12-17 01:07:27 +00001599}
1600
Ted Kremenek438f8db2014-02-22 01:06:05 +00001601static void handleObjCSuppresProtocolAttr(Sema &S, Decl *D,
Ted Kremenek28eace62013-11-23 01:01:34 +00001602 const AttributeList &Attr) {
Ted Kremenek438f8db2014-02-22 01:06:05 +00001603 if (!cast<ObjCProtocolDecl>(D)->isThisDeclarationADefinition()) {
Ted Kremenek27cfe102014-02-21 22:49:04 +00001604 S.Diag(Attr.getLoc(), diag::err_objc_attr_protocol_requires_definition)
1605 << Attr.getName() << Attr.getRange();
1606 return;
1607 }
1608
Ted Kremenek28eace62013-11-23 01:01:34 +00001609 D->addAttr(::new (S.Context)
Ted Kremenekf41cf7f12013-12-10 19:43:48 +00001610 ObjCExplicitProtocolImplAttr(Attr.getRange(), S.Context,
1611 Attr.getAttributeSpellingListIndex()));
Ted Kremenek28eace62013-11-23 01:01:34 +00001612}
1613
Jordy Rose740b0c22012-05-08 03:27:22 +00001614static bool checkAvailabilityAttr(Sema &S, SourceRange Range,
1615 IdentifierInfo *Platform,
1616 VersionTuple Introduced,
1617 VersionTuple Deprecated,
1618 VersionTuple Obsoleted) {
Rafael Espindola2d243bf2012-05-06 19:56:25 +00001619 StringRef PlatformName
1620 = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
1621 if (PlatformName.empty())
1622 PlatformName = Platform->getName();
1623
1624 // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
1625 // of these steps are needed).
1626 if (!Introduced.empty() && !Deprecated.empty() &&
1627 !(Introduced <= Deprecated)) {
1628 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
1629 << 1 << PlatformName << Deprecated.getAsString()
1630 << 0 << Introduced.getAsString();
1631 return true;
1632 }
1633
1634 if (!Introduced.empty() && !Obsoleted.empty() &&
1635 !(Introduced <= Obsoleted)) {
1636 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
1637 << 2 << PlatformName << Obsoleted.getAsString()
1638 << 0 << Introduced.getAsString();
1639 return true;
1640 }
1641
1642 if (!Deprecated.empty() && !Obsoleted.empty() &&
1643 !(Deprecated <= Obsoleted)) {
1644 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
1645 << 2 << PlatformName << Obsoleted.getAsString()
1646 << 1 << Deprecated.getAsString();
1647 return true;
1648 }
1649
1650 return false;
1651}
1652
Douglas Gregor66a8ca02013-01-15 22:43:08 +00001653/// \brief Check whether the two versions match.
1654///
1655/// If either version tuple is empty, then they are assumed to match. If
1656/// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y.
1657static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y,
1658 bool BeforeIsOkay) {
1659 if (X.empty() || Y.empty())
1660 return true;
1661
1662 if (X == Y)
1663 return true;
1664
1665 if (BeforeIsOkay && X < Y)
1666 return true;
1667
1668 return false;
1669}
1670
Rafael Espindolaa3aea432013-01-08 22:04:34 +00001671AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
Rafael Espindolae200f1c2012-05-13 03:25:18 +00001672 IdentifierInfo *Platform,
1673 VersionTuple Introduced,
1674 VersionTuple Deprecated,
1675 VersionTuple Obsoleted,
1676 bool IsUnavailable,
Douglas Gregor66a8ca02013-01-15 22:43:08 +00001677 StringRef Message,
Michael Han99315932013-01-24 16:46:58 +00001678 bool Override,
1679 unsigned AttrSpellingListIndex) {
Rafael Espindolac67f2232012-05-10 02:50:16 +00001680 VersionTuple MergedIntroduced = Introduced;
1681 VersionTuple MergedDeprecated = Deprecated;
1682 VersionTuple MergedObsoleted = Obsoleted;
Rafael Espindola2d243bf2012-05-06 19:56:25 +00001683 bool FoundAny = false;
1684
Rafael Espindolac67f2232012-05-10 02:50:16 +00001685 if (D->hasAttrs()) {
1686 AttrVec &Attrs = D->getAttrs();
1687 for (unsigned i = 0, e = Attrs.size(); i != e;) {
1688 const AvailabilityAttr *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]);
1689 if (!OldAA) {
1690 ++i;
1691 continue;
1692 }
Rafael Espindola2d243bf2012-05-06 19:56:25 +00001693
Rafael Espindolac67f2232012-05-10 02:50:16 +00001694 IdentifierInfo *OldPlatform = OldAA->getPlatform();
1695 if (OldPlatform != Platform) {
1696 ++i;
1697 continue;
1698 }
1699
1700 FoundAny = true;
1701 VersionTuple OldIntroduced = OldAA->getIntroduced();
1702 VersionTuple OldDeprecated = OldAA->getDeprecated();
1703 VersionTuple OldObsoleted = OldAA->getObsoleted();
1704 bool OldIsUnavailable = OldAA->getUnavailable();
Rafael Espindolac67f2232012-05-10 02:50:16 +00001705
Douglas Gregor66a8ca02013-01-15 22:43:08 +00001706 if (!versionsMatch(OldIntroduced, Introduced, Override) ||
1707 !versionsMatch(Deprecated, OldDeprecated, Override) ||
1708 !versionsMatch(Obsoleted, OldObsoleted, Override) ||
1709 !(OldIsUnavailable == IsUnavailable ||
Douglas Gregor43dc0c72013-01-16 00:54:48 +00001710 (Override && !OldIsUnavailable && IsUnavailable))) {
Douglas Gregor66a8ca02013-01-15 22:43:08 +00001711 if (Override) {
1712 int Which = -1;
1713 VersionTuple FirstVersion;
1714 VersionTuple SecondVersion;
1715 if (!versionsMatch(OldIntroduced, Introduced, Override)) {
1716 Which = 0;
1717 FirstVersion = OldIntroduced;
1718 SecondVersion = Introduced;
1719 } else if (!versionsMatch(Deprecated, OldDeprecated, Override)) {
1720 Which = 1;
1721 FirstVersion = Deprecated;
1722 SecondVersion = OldDeprecated;
1723 } else if (!versionsMatch(Obsoleted, OldObsoleted, Override)) {
1724 Which = 2;
1725 FirstVersion = Obsoleted;
1726 SecondVersion = OldObsoleted;
1727 }
1728
1729 if (Which == -1) {
1730 Diag(OldAA->getLocation(),
1731 diag::warn_mismatched_availability_override_unavail)
1732 << AvailabilityAttr::getPrettyPlatformName(Platform->getName());
1733 } else {
1734 Diag(OldAA->getLocation(),
1735 diag::warn_mismatched_availability_override)
1736 << Which
1737 << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
1738 << FirstVersion.getAsString() << SecondVersion.getAsString();
1739 }
1740 Diag(Range.getBegin(), diag::note_overridden_method);
1741 } else {
1742 Diag(OldAA->getLocation(), diag::warn_mismatched_availability);
1743 Diag(Range.getBegin(), diag::note_previous_attribute);
1744 }
1745
Rafael Espindolac67f2232012-05-10 02:50:16 +00001746 Attrs.erase(Attrs.begin() + i);
1747 --e;
1748 continue;
1749 }
1750
1751 VersionTuple MergedIntroduced2 = MergedIntroduced;
1752 VersionTuple MergedDeprecated2 = MergedDeprecated;
1753 VersionTuple MergedObsoleted2 = MergedObsoleted;
1754
1755 if (MergedIntroduced2.empty())
1756 MergedIntroduced2 = OldIntroduced;
1757 if (MergedDeprecated2.empty())
1758 MergedDeprecated2 = OldDeprecated;
1759 if (MergedObsoleted2.empty())
1760 MergedObsoleted2 = OldObsoleted;
1761
1762 if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform,
1763 MergedIntroduced2, MergedDeprecated2,
1764 MergedObsoleted2)) {
1765 Attrs.erase(Attrs.begin() + i);
1766 --e;
1767 continue;
1768 }
1769
1770 MergedIntroduced = MergedIntroduced2;
1771 MergedDeprecated = MergedDeprecated2;
1772 MergedObsoleted = MergedObsoleted2;
1773 ++i;
Rafael Espindola2d243bf2012-05-06 19:56:25 +00001774 }
Rafael Espindola2d243bf2012-05-06 19:56:25 +00001775 }
1776
1777 if (FoundAny &&
1778 MergedIntroduced == Introduced &&
1779 MergedDeprecated == Deprecated &&
1780 MergedObsoleted == Obsoleted)
Rafael Espindolae200f1c2012-05-13 03:25:18 +00001781 return NULL;
Rafael Espindola2d243bf2012-05-06 19:56:25 +00001782
Ted Kremenekb5445722013-04-06 00:34:27 +00001783 // Only create a new attribute if !Override, but we want to do
1784 // the checking.
Rafael Espindolac67f2232012-05-10 02:50:16 +00001785 if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced,
Ted Kremenekb5445722013-04-06 00:34:27 +00001786 MergedDeprecated, MergedObsoleted) &&
1787 !Override) {
Rafael Espindolae200f1c2012-05-13 03:25:18 +00001788 return ::new (Context) AvailabilityAttr(Range, Context, Platform,
1789 Introduced, Deprecated,
Michael Han99315932013-01-24 16:46:58 +00001790 Obsoleted, IsUnavailable, Message,
1791 AttrSpellingListIndex);
Rafael Espindola2d243bf2012-05-06 19:56:25 +00001792 }
Rafael Espindolae200f1c2012-05-13 03:25:18 +00001793 return NULL;
Rafael Espindola2d243bf2012-05-06 19:56:25 +00001794}
1795
Chandler Carruthedc2c642011-07-02 00:01:44 +00001796static void handleAvailabilityAttr(Sema &S, Decl *D,
1797 const AttributeList &Attr) {
Aaron Ballman00e99962013-08-31 01:11:41 +00001798 if (!checkAttributeNumArgs(S, Attr, 1))
1799 return;
1800 IdentifierLoc *Platform = Attr.getArgAsIdent(0);
Michael Han99315932013-01-24 16:46:58 +00001801 unsigned Index = Attr.getAttributeSpellingListIndex();
1802
Aaron Ballman00e99962013-08-31 01:11:41 +00001803 IdentifierInfo *II = Platform->Ident;
1804 if (AvailabilityAttr::getPrettyPlatformName(II->getName()).empty())
1805 S.Diag(Platform->Loc, diag::warn_availability_unknown_platform)
1806 << Platform->Ident;
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00001807
Rafael Espindolac231fab2013-01-08 21:30:32 +00001808 NamedDecl *ND = dyn_cast<NamedDecl>(D);
1809 if (!ND) {
1810 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1811 return;
1812 }
1813
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00001814 AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
1815 AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
1816 AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
Douglas Gregor7ab142b2011-03-26 03:35:55 +00001817 bool IsUnavailable = Attr.getUnavailableLoc().isValid();
Fariborz Jahanian88d510d2011-12-10 00:28:41 +00001818 StringRef Str;
Benjamin Kramera9dfa922013-09-13 17:31:48 +00001819 if (const StringLiteral *SE =
1820 dyn_cast_or_null<StringLiteral>(Attr.getMessageExpr()))
Fariborz Jahanian88d510d2011-12-10 00:28:41 +00001821 Str = SE->getString();
Rafael Espindola2d243bf2012-05-06 19:56:25 +00001822
Aaron Ballman00e99962013-08-31 01:11:41 +00001823 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, Attr.getRange(), II,
Rafael Espindolae200f1c2012-05-13 03:25:18 +00001824 Introduced.Version,
1825 Deprecated.Version,
1826 Obsoleted.Version,
Douglas Gregor66a8ca02013-01-15 22:43:08 +00001827 IsUnavailable, Str,
Michael Han99315932013-01-24 16:46:58 +00001828 /*Override=*/false,
1829 Index);
Rafael Espindola19de5612013-01-12 06:42:30 +00001830 if (NewAttr)
Rafael Espindolae200f1c2012-05-13 03:25:18 +00001831 D->addAttr(NewAttr);
Rafael Espindolac67f2232012-05-10 02:50:16 +00001832}
1833
John McCalld041a9b2013-02-20 01:54:26 +00001834template <class T>
1835static T *mergeVisibilityAttr(Sema &S, Decl *D, SourceRange range,
1836 typename T::VisibilityType value,
1837 unsigned attrSpellingListIndex) {
1838 T *existingAttr = D->getAttr<T>();
1839 if (existingAttr) {
1840 typename T::VisibilityType existingValue = existingAttr->getVisibility();
1841 if (existingValue == value)
1842 return NULL;
1843 S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
1844 S.Diag(range.getBegin(), diag::note_previous_attribute);
1845 D->dropAttr<T>();
1846 }
1847 return ::new (S.Context) T(range, S.Context, value, attrSpellingListIndex);
1848}
1849
Rafael Espindolae200f1c2012-05-13 03:25:18 +00001850VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range,
Michael Han99315932013-01-24 16:46:58 +00001851 VisibilityAttr::VisibilityType Vis,
1852 unsigned AttrSpellingListIndex) {
John McCalld041a9b2013-02-20 01:54:26 +00001853 return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, Range, Vis,
1854 AttrSpellingListIndex);
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00001855}
1856
John McCalld041a9b2013-02-20 01:54:26 +00001857TypeVisibilityAttr *Sema::mergeTypeVisibilityAttr(Decl *D, SourceRange Range,
1858 TypeVisibilityAttr::VisibilityType Vis,
1859 unsigned AttrSpellingListIndex) {
1860 return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, Range, Vis,
1861 AttrSpellingListIndex);
1862}
1863
1864static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr,
1865 bool isTypeVisibility) {
1866 // Visibility attributes don't mean anything on a typedef.
1867 if (isa<TypedefNameDecl>(D)) {
1868 S.Diag(Attr.getRange().getBegin(), diag::warn_attribute_ignored)
1869 << Attr.getName();
1870 return;
1871 }
1872
1873 // 'type_visibility' can only go on a type or namespace.
1874 if (isTypeVisibility &&
1875 !(isa<TagDecl>(D) ||
1876 isa<ObjCInterfaceDecl>(D) ||
1877 isa<NamespaceDecl>(D))) {
1878 S.Diag(Attr.getRange().getBegin(), diag::err_attribute_wrong_decl_type)
1879 << Attr.getName() << ExpectedTypeOrNamespace;
1880 return;
1881 }
1882
Benjamin Kramer70370212013-09-09 15:08:57 +00001883 // Check that the argument is a string literal.
Benjamin Kramer6ee15622013-09-13 15:35:43 +00001884 StringRef TypeStr;
1885 SourceLocation LiteralLoc;
Tim Northover6a6b63b2013-10-01 14:34:18 +00001886 if (!S.checkStringLiteralArgumentAttr(Attr, 0, TypeStr, &LiteralLoc))
Chris Lattner2c6fcf52008-06-26 18:38:35 +00001887 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00001888
Alexis Huntdcfba7b2010-08-18 23:23:40 +00001889 VisibilityAttr::VisibilityType type;
Aaron Ballman682ee422013-09-11 19:47:58 +00001890 if (!VisibilityAttr::ConvertStrToVisibilityType(TypeStr, type)) {
Benjamin Kramer6ee15622013-09-13 15:35:43 +00001891 S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported)
Aaron Ballman682ee422013-09-11 19:47:58 +00001892 << Attr.getName() << TypeStr;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00001893 return;
1894 }
Aaron Ballman682ee422013-09-11 19:47:58 +00001895
1896 // Complain about attempts to use protected visibility on targets
1897 // (like Darwin) that don't support it.
1898 if (type == VisibilityAttr::Protected &&
1899 !S.Context.getTargetInfo().hasProtectedVisibility()) {
1900 S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility);
1901 type = VisibilityAttr::Default;
1902 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001903
Michael Han99315932013-01-24 16:46:58 +00001904 unsigned Index = Attr.getAttributeSpellingListIndex();
John McCalld041a9b2013-02-20 01:54:26 +00001905 clang::Attr *newAttr;
1906 if (isTypeVisibility) {
1907 newAttr = S.mergeTypeVisibilityAttr(D, Attr.getRange(),
1908 (TypeVisibilityAttr::VisibilityType) type,
1909 Index);
1910 } else {
1911 newAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type, Index);
1912 }
1913 if (newAttr)
1914 D->addAttr(newAttr);
Chris Lattner2c6fcf52008-06-26 18:38:35 +00001915}
1916
Chandler Carruthedc2c642011-07-02 00:01:44 +00001917static void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
1918 const AttributeList &Attr) {
Aaron Ballman74eeeae2013-11-27 13:27:02 +00001919 ObjCMethodDecl *method = cast<ObjCMethodDecl>(decl);
Aaron Ballman00e99962013-08-31 01:11:41 +00001920 if (!Attr.isArgIdent(0)) {
1921 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
1922 << Attr.getName() << 1 << AANT_ArgumentIdentifier;
John McCall86bc21f2011-03-02 11:33:24 +00001923 return;
1924 }
Aaron Ballman00e99962013-08-31 01:11:41 +00001925
Aaron Ballman682ee422013-09-11 19:47:58 +00001926 IdentifierLoc *IL = Attr.getArgAsIdent(0);
1927 ObjCMethodFamilyAttr::FamilyKind F;
1928 if (!ObjCMethodFamilyAttr::ConvertStrToFamilyKind(IL->Ident->getName(), F)) {
1929 S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << Attr.getName()
1930 << IL->Ident;
John McCall86bc21f2011-03-02 11:33:24 +00001931 return;
1932 }
1933
Alp Toker314cc812014-01-25 16:55:45 +00001934 if (F == ObjCMethodFamilyAttr::OMF_init &&
1935 !method->getReturnType()->isObjCObjectPointerType()) {
John McCall31168b02011-06-15 23:02:42 +00001936 S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
Alp Toker314cc812014-01-25 16:55:45 +00001937 << method->getReturnType();
John McCall31168b02011-06-15 23:02:42 +00001938 // Ignore the attribute.
1939 return;
1940 }
1941
Argyrios Kyrtzidis309b4c42011-09-13 16:05:58 +00001942 method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(),
Aaron Ballman36a53502014-01-16 13:03:14 +00001943 S.Context, F,
1944 Attr.getAttributeSpellingListIndex()));
John McCall86bc21f2011-03-02 11:33:24 +00001945}
1946
Chandler Carruthedc2c642011-07-02 00:01:44 +00001947static void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
Richard Smithdda56e42011-04-15 14:24:37 +00001948 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
Fariborz Jahanian255c0952009-01-13 23:34:40 +00001949 QualType T = TD->getUnderlyingType();
Ted Kremenek7712eef2012-08-29 22:54:47 +00001950 if (!T->isCARCBridgableType()) {
Fariborz Jahanian255c0952009-01-13 23:34:40 +00001951 S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1952 return;
1953 }
1954 }
Fariborz Jahanianbebd0ba2012-05-31 23:18:32 +00001955 else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
1956 QualType T = PD->getType();
Ted Kremenek7712eef2012-08-29 22:54:47 +00001957 if (!T->isCARCBridgableType()) {
Fariborz Jahanianbebd0ba2012-05-31 23:18:32 +00001958 S.Diag(PD->getLocation(), diag::err_nsobject_attribute);
1959 return;
1960 }
1961 }
1962 else {
Ted Kremenek05e916b2012-03-01 01:40:32 +00001963 // It is okay to include this attribute on properties, e.g.:
1964 //
1965 // @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
1966 //
1967 // In this case it follows tradition and suppresses an error in the above
1968 // case.
Fariborz Jahaniana45495a2011-11-29 01:48:40 +00001969 S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
Ted Kremenek05e916b2012-03-01 01:40:32 +00001970 }
Michael Han99315932013-01-24 16:46:58 +00001971 D->addAttr(::new (S.Context)
1972 ObjCNSObjectAttr(Attr.getRange(), S.Context,
1973 Attr.getAttributeSpellingListIndex()));
Fariborz Jahanian255c0952009-01-13 23:34:40 +00001974}
1975
Chandler Carruthedc2c642011-07-02 00:01:44 +00001976static void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Aaron Ballman00e99962013-08-31 01:11:41 +00001977 if (!Attr.isArgIdent(0)) {
Aaron Ballman29982272013-07-23 14:03:57 +00001978 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
Aaron Ballman00e99962013-08-31 01:11:41 +00001979 << Attr.getName() << 1 << AANT_ArgumentIdentifier;
Steve Naroff3405a732008-09-18 16:44:58 +00001980 return;
1981 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001982
Aaron Ballman00e99962013-08-31 01:11:41 +00001983 IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident;
Alexis Huntdcfba7b2010-08-18 23:23:40 +00001984 BlocksAttr::BlockType type;
Aaron Ballman682ee422013-09-11 19:47:58 +00001985 if (!BlocksAttr::ConvertStrToBlockType(II->getName(), type)) {
1986 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
1987 << Attr.getName() << II;
Steve Naroff3405a732008-09-18 16:44:58 +00001988 return;
1989 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001990
Michael Han99315932013-01-24 16:46:58 +00001991 D->addAttr(::new (S.Context)
1992 BlocksAttr(Attr.getRange(), S.Context, type,
1993 Attr.getAttributeSpellingListIndex()));
Steve Naroff3405a732008-09-18 16:44:58 +00001994}
1995
Chandler Carruthedc2c642011-07-02 00:01:44 +00001996static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Anders Carlssonc181b012008-10-05 18:05:59 +00001997 // check the attribute arguments.
1998 if (Attr.getNumArgs() > 2) {
Aaron Ballman05e420a2014-01-02 21:26:14 +00001999 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments)
2000 << Attr.getName() << 2;
Anders Carlssonc181b012008-10-05 18:05:59 +00002001 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00002002 }
2003
Aaron Ballman18a78382013-11-21 00:28:23 +00002004 unsigned sentinel = (unsigned)SentinelAttr::DefaultSentinel;
Anders Carlssonc181b012008-10-05 18:05:59 +00002005 if (Attr.getNumArgs() > 0) {
Aaron Ballman00e99962013-08-31 01:11:41 +00002006 Expr *E = Attr.getArgAsExpr(0);
Anders Carlssonc181b012008-10-05 18:05:59 +00002007 llvm::APSInt Idx(32);
Douglas Gregorbdb604a2010-05-18 23:01:22 +00002008 if (E->isTypeDependent() || E->isValueDependent() ||
2009 !E->isIntegerConstantExpr(Idx, S.Context)) {
Aaron Ballman29982272013-07-23 14:03:57 +00002010 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
Aaron Ballman3bf758c2013-07-30 01:31:03 +00002011 << Attr.getName() << 1 << AANT_ArgumentIntegerConstant
Aaron Ballman29982272013-07-23 14:03:57 +00002012 << E->getSourceRange();
Anders Carlssonc181b012008-10-05 18:05:59 +00002013 return;
2014 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002015
John McCallb46f2872011-09-09 07:56:05 +00002016 if (Idx.isSigned() && Idx.isNegative()) {
Chris Lattner3b054132008-11-19 05:08:23 +00002017 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
2018 << E->getSourceRange();
Anders Carlssonc181b012008-10-05 18:05:59 +00002019 return;
2020 }
John McCallb46f2872011-09-09 07:56:05 +00002021
2022 sentinel = Idx.getZExtValue();
Anders Carlssonc181b012008-10-05 18:05:59 +00002023 }
2024
Aaron Ballman18a78382013-11-21 00:28:23 +00002025 unsigned nullPos = (unsigned)SentinelAttr::DefaultNullPos;
Anders Carlssonc181b012008-10-05 18:05:59 +00002026 if (Attr.getNumArgs() > 1) {
Aaron Ballman00e99962013-08-31 01:11:41 +00002027 Expr *E = Attr.getArgAsExpr(1);
Anders Carlssonc181b012008-10-05 18:05:59 +00002028 llvm::APSInt Idx(32);
Douglas Gregorbdb604a2010-05-18 23:01:22 +00002029 if (E->isTypeDependent() || E->isValueDependent() ||
2030 !E->isIntegerConstantExpr(Idx, S.Context)) {
Aaron Ballman29982272013-07-23 14:03:57 +00002031 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
Aaron Ballman3bf758c2013-07-30 01:31:03 +00002032 << Attr.getName() << 2 << AANT_ArgumentIntegerConstant
Aaron Ballman29982272013-07-23 14:03:57 +00002033 << E->getSourceRange();
Anders Carlssonc181b012008-10-05 18:05:59 +00002034 return;
2035 }
2036 nullPos = Idx.getZExtValue();
Mike Stumpd3bb5572009-07-24 19:02:52 +00002037
John McCallb46f2872011-09-09 07:56:05 +00002038 if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) {
Anders Carlssonc181b012008-10-05 18:05:59 +00002039 // FIXME: This error message could be improved, it would be nice
2040 // to say what the bounds actually are.
Chris Lattner3b054132008-11-19 05:08:23 +00002041 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
2042 << E->getSourceRange();
Anders Carlssonc181b012008-10-05 18:05:59 +00002043 return;
2044 }
2045 }
2046
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002047 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
John McCallb46f2872011-09-09 07:56:05 +00002048 const FunctionType *FT = FD->getType()->castAs<FunctionType>();
Chris Lattner9363e312009-03-17 23:03:47 +00002049 if (isa<FunctionNoProtoType>(FT)) {
2050 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
2051 return;
2052 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002053
Chris Lattner9363e312009-03-17 23:03:47 +00002054 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
Fariborz Jahanian6802ed92009-05-15 21:18:04 +00002055 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
Anders Carlssonc181b012008-10-05 18:05:59 +00002056 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00002057 }
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002058 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
Anders Carlssonc181b012008-10-05 18:05:59 +00002059 if (!MD->isVariadic()) {
Fariborz Jahanian6802ed92009-05-15 21:18:04 +00002060 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
Anders Carlssonc181b012008-10-05 18:05:59 +00002061 return;
Fariborz Jahanian6607b212009-05-14 20:53:39 +00002062 }
Eli Friedman5c5e3b72012-01-06 01:23:10 +00002063 } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
2064 if (!BD->isVariadic()) {
2065 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
2066 return;
2067 }
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002068 } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
Fariborz Jahanian6607b212009-05-14 20:53:39 +00002069 QualType Ty = V->getType();
Fariborz Jahanian0aa5c452009-05-15 20:33:25 +00002070 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
Aaron Ballman12b9f652014-01-16 13:55:42 +00002071 const FunctionType *FT = Ty->isFunctionPointerType()
2072 ? D->getFunctionType()
Eric Christopherbc638a82010-12-01 22:13:54 +00002073 : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
Fariborz Jahanian6607b212009-05-14 20:53:39 +00002074 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
Fariborz Jahanian6802ed92009-05-15 21:18:04 +00002075 int m = Ty->isFunctionPointerType() ? 0 : 1;
2076 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
Fariborz Jahanian6607b212009-05-14 20:53:39 +00002077 return;
2078 }
Mike Stump12b8ce12009-08-04 21:02:39 +00002079 } else {
Fariborz Jahanian6607b212009-05-14 20:53:39 +00002080 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00002081 << Attr.getName() << ExpectedFunctionMethodOrBlock;
Fariborz Jahanian6607b212009-05-14 20:53:39 +00002082 return;
2083 }
Anders Carlssonc181b012008-10-05 18:05:59 +00002084 } else {
Chris Lattner3b054132008-11-19 05:08:23 +00002085 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00002086 << Attr.getName() << ExpectedFunctionMethodOrBlock;
Anders Carlssonc181b012008-10-05 18:05:59 +00002087 return;
2088 }
Michael Han99315932013-01-24 16:46:58 +00002089 D->addAttr(::new (S.Context)
2090 SentinelAttr(Attr.getRange(), S.Context, sentinel, nullPos,
2091 Attr.getAttributeSpellingListIndex()));
Anders Carlssonc181b012008-10-05 18:05:59 +00002092}
2093
Chandler Carruthedc2c642011-07-02 00:01:44 +00002094static void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
Alp Toker314cc812014-01-25 16:55:45 +00002095 if (D->getFunctionType() &&
2096 D->getFunctionType()->getReturnType()->isVoidType()) {
Fariborz Jahanian5cab26d2010-03-30 18:22:15 +00002097 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
2098 << Attr.getName() << 0;
Nuno Lopes56abcbd2009-12-22 23:59:52 +00002099 return;
2100 }
Fariborz Jahanian5cab26d2010-03-30 18:22:15 +00002101 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Alp Toker314cc812014-01-25 16:55:45 +00002102 if (MD->getReturnType()->isVoidType()) {
Fariborz Jahanian5cab26d2010-03-30 18:22:15 +00002103 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
2104 << Attr.getName() << 1;
2105 return;
2106 }
2107
Michael Han99315932013-01-24 16:46:58 +00002108 D->addAttr(::new (S.Context)
2109 WarnUnusedResultAttr(Attr.getRange(), S.Context,
2110 Attr.getAttributeSpellingListIndex()));
Chris Lattner237f2752009-02-14 07:37:35 +00002111}
2112
Chandler Carruthedc2c642011-07-02 00:01:44 +00002113static void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Daniel Dunbar5cb85eb2009-03-06 06:39:57 +00002114 // weak_import only applies to variable & function declarations.
2115 bool isDef = false;
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00002116 if (!D->canBeWeakImported(isDef)) {
2117 if (isDef)
Reid Kleckner52d598e2013-05-20 21:53:29 +00002118 S.Diag(Attr.getLoc(), diag::warn_attribute_invalid_on_definition)
2119 << "weak_import";
Douglas Gregord71149a2011-03-23 13:27:51 +00002120 else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
Douglas Gregore8bbc122011-09-02 00:18:52 +00002121 (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
Fariborz Jahanian3249a1e2011-10-26 23:59:12 +00002122 (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) {
Douglas Gregord71149a2011-03-23 13:27:51 +00002123 // Nothing to warn about here.
2124 } else
Fariborz Jahanianea70a172010-04-13 20:22:35 +00002125 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00002126 << Attr.getName() << ExpectedVariableOrFunction;
Daniel Dunbar5cb85eb2009-03-06 06:39:57 +00002127
Daniel Dunbar5cb85eb2009-03-06 06:39:57 +00002128 return;
2129 }
2130
Michael Han99315932013-01-24 16:46:58 +00002131 D->addAttr(::new (S.Context)
2132 WeakImportAttr(Attr.getRange(), S.Context,
2133 Attr.getAttributeSpellingListIndex()));
Daniel Dunbar5cb85eb2009-03-06 06:39:57 +00002134}
2135
Tanya Lattnerbcffcdf2012-07-09 22:06:01 +00002136// Handles reqd_work_group_size and work_group_size_hint.
Aaron Ballman1d0d2a42013-12-02 22:38:33 +00002137template <typename WorkGroupAttr>
Tanya Lattnerbcffcdf2012-07-09 22:06:01 +00002138static void handleWorkGroupSize(Sema &S, Decl *D,
Nick Lewyckyb9e4a3a2012-07-24 01:31:55 +00002139 const AttributeList &Attr) {
Aaron Ballmanf22ef5a2013-11-21 01:50:40 +00002140 uint32_t WGSize[3];
2141 for (unsigned i = 0; i < 3; ++i)
2142 if (!checkUInt32Argument(S, Attr, Attr.getArgAsExpr(i), WGSize[i], i))
Nate Begemanf2758702009-06-26 06:32:41 +00002143 return;
Tanya Lattnerbcffcdf2012-07-09 22:06:01 +00002144
Aaron Ballman1d0d2a42013-12-02 22:38:33 +00002145 WorkGroupAttr *Existing = D->getAttr<WorkGroupAttr>();
2146 if (Existing && !(Existing->getXDim() == WGSize[0] &&
2147 Existing->getYDim() == WGSize[1] &&
2148 Existing->getZDim() == WGSize[2]))
2149 S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr.getName();
Tanya Lattnerbcffcdf2012-07-09 22:06:01 +00002150
Aaron Ballman1d0d2a42013-12-02 22:38:33 +00002151 D->addAttr(::new (S.Context) WorkGroupAttr(Attr.getRange(), S.Context,
2152 WGSize[0], WGSize[1], WGSize[2],
Michael Han99315932013-01-24 16:46:58 +00002153 Attr.getAttributeSpellingListIndex()));
Nate Begemanf2758702009-06-26 06:32:41 +00002154}
2155
Joey Goulyaba589c2013-03-08 09:42:32 +00002156static void handleVecTypeHint(Sema &S, Decl *D, const AttributeList &Attr) {
Aaron Ballman00e99962013-08-31 01:11:41 +00002157 if (!Attr.hasParsedType()) {
2158 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
2159 << Attr.getName() << 1;
2160 return;
2161 }
2162
Richard Smithb87c4652013-10-31 21:23:20 +00002163 TypeSourceInfo *ParmTSI = 0;
2164 QualType ParmType = S.GetTypeFromParser(Attr.getTypeArg(), &ParmTSI);
2165 assert(ParmTSI && "no type source info for attribute argument");
Joey Goulyaba589c2013-03-08 09:42:32 +00002166
2167 if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() &&
2168 (ParmType->isBooleanType() ||
2169 !ParmType->isIntegralType(S.getASTContext()))) {
2170 S.Diag(Attr.getLoc(), diag::err_attribute_argument_vec_type_hint)
2171 << ParmType;
2172 return;
2173 }
2174
Aaron Ballmana9e05402013-12-02 22:16:55 +00002175 if (VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>()) {
Richard Smithb87c4652013-10-31 21:23:20 +00002176 if (!S.Context.hasSameType(A->getTypeHint(), ParmType)) {
Joey Goulyaba589c2013-03-08 09:42:32 +00002177 S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr.getName();
2178 return;
2179 }
2180 }
2181
2182 D->addAttr(::new (S.Context) VecTypeHintAttr(Attr.getLoc(), S.Context,
Aaron Ballman36a53502014-01-16 13:03:14 +00002183 ParmTSI,
2184 Attr.getAttributeSpellingListIndex()));
Joey Goulyaba589c2013-03-08 09:42:32 +00002185}
2186
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002187SectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range,
Michael Han99315932013-01-24 16:46:58 +00002188 StringRef Name,
2189 unsigned AttrSpellingListIndex) {
Rafael Espindola9869c3a2012-05-13 02:42:42 +00002190 if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
2191 if (ExistingAttr->getName() == Name)
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002192 return NULL;
Rafael Espindola9869c3a2012-05-13 02:42:42 +00002193 Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section);
2194 Diag(Range.getBegin(), diag::note_previous_attribute);
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002195 return NULL;
Rafael Espindola9869c3a2012-05-13 02:42:42 +00002196 }
Michael Han99315932013-01-24 16:46:58 +00002197 return ::new (Context) SectionAttr(Range, Context, Name,
2198 AttrSpellingListIndex);
Rafael Espindola9869c3a2012-05-13 02:42:42 +00002199}
2200
Chandler Carruthedc2c642011-07-02 00:01:44 +00002201static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Daniel Dunbar648bf782009-02-12 17:28:23 +00002202 // Make sure that there is a string literal as the sections's single
2203 // argument.
Benjamin Kramer6ee15622013-09-13 15:35:43 +00002204 StringRef Str;
2205 SourceLocation LiteralLoc;
Tim Northover6a6b63b2013-10-01 14:34:18 +00002206 if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &LiteralLoc))
Daniel Dunbar648bf782009-02-12 17:28:23 +00002207 return;
Mike Stump11289f42009-09-09 15:08:12 +00002208
Chris Lattner30ba6742009-08-10 19:03:04 +00002209 // If the target wants to validate the section specifier, make it happen.
Benjamin Kramer6ee15622013-09-13 15:35:43 +00002210 std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(Str);
Chris Lattner20aee9b2010-01-12 20:58:53 +00002211 if (!Error.empty()) {
Benjamin Kramer6ee15622013-09-13 15:35:43 +00002212 S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
Chris Lattner20aee9b2010-01-12 20:58:53 +00002213 << Error;
Chris Lattner30ba6742009-08-10 19:03:04 +00002214 return;
2215 }
Mike Stump11289f42009-09-09 15:08:12 +00002216
Michael Han99315932013-01-24 16:46:58 +00002217 unsigned Index = Attr.getAttributeSpellingListIndex();
Benjamin Kramer6ee15622013-09-13 15:35:43 +00002218 SectionAttr *NewAttr = S.mergeSectionAttr(D, Attr.getRange(), Str, Index);
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002219 if (NewAttr)
2220 D->addAttr(NewAttr);
Daniel Dunbar648bf782009-02-12 17:28:23 +00002221}
2222
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002223
Chandler Carruthedc2c642011-07-02 00:01:44 +00002224static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Aaron Ballman74eeeae2013-11-27 13:27:02 +00002225 VarDecl *VD = cast<VarDecl>(D);
2226 if (!VD->hasLocalStorage()) {
Aaron Ballmanc12aaff2013-09-11 01:37:41 +00002227 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
Anders Carlssond277d792009-01-31 01:16:18 +00002228 return;
2229 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002230
Aaron Ballmanc12aaff2013-09-11 01:37:41 +00002231 Expr *E = Attr.getArgAsExpr(0);
2232 SourceLocation Loc = E->getExprLoc();
2233 FunctionDecl *FD = 0;
2234 DeclarationNameInfo NI;
Aaron Ballman00e99962013-08-31 01:11:41 +00002235
Aaron Ballmanc12aaff2013-09-11 01:37:41 +00002236 // gcc only allows for simple identifiers. Since we support more than gcc, we
2237 // will warn the user.
2238 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
2239 if (DRE->hasQualifier())
2240 S.Diag(Loc, diag::warn_cleanup_ext);
2241 FD = dyn_cast<FunctionDecl>(DRE->getDecl());
2242 NI = DRE->getNameInfo();
2243 if (!FD) {
2244 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 1
2245 << NI.getName();
2246 return;
2247 }
2248 } else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
2249 if (ULE->hasExplicitTemplateArgs())
2250 S.Diag(Loc, diag::warn_cleanup_ext);
Aaron Ballmanc12aaff2013-09-11 01:37:41 +00002251 FD = S.ResolveSingleFunctionTemplateSpecialization(ULE, true);
2252 NI = ULE->getNameInfo();
Alp Toker67b47ac2013-10-20 18:48:56 +00002253 if (!FD) {
2254 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 2
2255 << NI.getName();
2256 if (ULE->getType() == S.Context.OverloadTy)
2257 S.NoteAllOverloadCandidates(ULE);
2258 return;
2259 }
Aaron Ballmanc12aaff2013-09-11 01:37:41 +00002260 } else {
2261 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 0;
Anders Carlssond277d792009-01-31 01:16:18 +00002262 return;
2263 }
2264
Anders Carlssond277d792009-01-31 01:16:18 +00002265 if (FD->getNumParams() != 1) {
Aaron Ballmanc12aaff2013-09-11 01:37:41 +00002266 S.Diag(Loc, diag::err_attribute_cleanup_func_must_take_one_arg)
2267 << NI.getName();
Anders Carlssond277d792009-01-31 01:16:18 +00002268 return;
2269 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002270
Anders Carlsson723f55d2009-02-07 23:16:50 +00002271 // We're currently more strict than GCC about what function types we accept.
2272 // If this ever proves to be a problem it should be easy to fix.
2273 QualType Ty = S.Context.getPointerType(VD->getType());
2274 QualType ParamTy = FD->getParamDecl(0)->getType();
Douglas Gregorc03a1082011-01-28 02:26:04 +00002275 if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
2276 ParamTy, Ty) != Sema::Compatible) {
Aaron Ballmanc12aaff2013-09-11 01:37:41 +00002277 S.Diag(Loc, diag::err_attribute_cleanup_func_arg_incompatible_type)
2278 << NI.getName() << ParamTy << Ty;
Anders Carlsson723f55d2009-02-07 23:16:50 +00002279 return;
2280 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002281
Michael Han99315932013-01-24 16:46:58 +00002282 D->addAttr(::new (S.Context)
2283 CleanupAttr(Attr.getRange(), S.Context, FD,
2284 Attr.getAttributeSpellingListIndex()));
Anders Carlssond277d792009-01-31 01:16:18 +00002285}
2286
Mike Stumpd3bb5572009-07-24 19:02:52 +00002287/// Handle __attribute__((format_arg((idx)))) attribute based on
Bill Wendling44426052012-12-20 19:22:21 +00002288/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
Chandler Carruthedc2c642011-07-02 00:01:44 +00002289static void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Aaron Ballman00e99962013-08-31 01:11:41 +00002290 Expr *IdxExpr = Attr.getArgAsExpr(0);
Alp Toker601b22c2014-01-21 23:35:24 +00002291 uint64_t Idx;
2292 if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 1, IdxExpr, Idx))
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002293 return;
Chandler Carruth743682b2010-11-16 08:35:43 +00002294
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002295 // make sure the format string is really a string
Alp Toker601b22c2014-01-21 23:35:24 +00002296 QualType Ty = getFunctionOrMethodParamType(D, Idx);
Mike Stumpd3bb5572009-07-24 19:02:52 +00002297
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002298 bool not_nsstring_type = !isNSStringType(Ty, S.Context);
2299 if (not_nsstring_type &&
2300 !isCFStringType(Ty, S.Context) &&
2301 (!Ty->isPointerType() ||
Ted Kremenekc23c7e62009-07-29 21:53:49 +00002302 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002303 // FIXME: Should highlight the actual expression that has the wrong type.
2304 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
Mike Stumpd3bb5572009-07-24 19:02:52 +00002305 << (not_nsstring_type ? "a string type" : "an NSString")
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002306 << IdxExpr->getSourceRange();
2307 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00002308 }
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002309 Ty = getFunctionOrMethodResultType(D);
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002310 if (!isNSStringType(Ty, S.Context) &&
2311 !isCFStringType(Ty, S.Context) &&
2312 (!Ty->isPointerType() ||
Ted Kremenekc23c7e62009-07-29 21:53:49 +00002313 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002314 // FIXME: Should highlight the actual expression that has the wrong type.
2315 S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
Mike Stumpd3bb5572009-07-24 19:02:52 +00002316 << (not_nsstring_type ? "string type" : "NSString")
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002317 << IdxExpr->getSourceRange();
2318 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00002319 }
2320
Alp Toker601b22c2014-01-21 23:35:24 +00002321 // We cannot use the Idx returned from checkFunctionOrMethodParameterIndex
Aaron Ballmanbe50eb82013-07-30 00:48:57 +00002322 // because that has corrected for the implicit this parameter, and is zero-
2323 // based. The attribute expects what the user wrote explicitly.
2324 llvm::APSInt Val;
2325 IdxExpr->EvaluateAsInt(Val, S.Context);
2326
Michael Han99315932013-01-24 16:46:58 +00002327 D->addAttr(::new (S.Context)
Aaron Ballmanbe50eb82013-07-30 00:48:57 +00002328 FormatArgAttr(Attr.getRange(), S.Context, Val.getZExtValue(),
Michael Han99315932013-01-24 16:46:58 +00002329 Attr.getAttributeSpellingListIndex()));
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002330}
2331
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00002332enum FormatAttrKind {
2333 CFStringFormat,
2334 NSStringFormat,
2335 StrftimeFormat,
2336 SupportedFormat,
Chris Lattner12161d32010-03-22 21:08:50 +00002337 IgnoredFormat,
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00002338 InvalidFormat
2339};
2340
2341/// getFormatAttrKind - Map from format attribute names to supported format
2342/// types.
Chris Lattner0e62c1c2011-07-23 10:55:15 +00002343static FormatAttrKind getFormatAttrKind(StringRef Format) {
Benjamin Kramer96a44b62012-05-16 12:44:25 +00002344 return llvm::StringSwitch<FormatAttrKind>(Format)
2345 // Check for formats that get handled specially.
2346 .Case("NSString", NSStringFormat)
2347 .Case("CFString", CFStringFormat)
2348 .Case("strftime", StrftimeFormat)
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00002349
Benjamin Kramer96a44b62012-05-16 12:44:25 +00002350 // Otherwise, check for supported formats.
2351 .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat)
2352 .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat)
2353 .Case("kprintf", SupportedFormat) // OpenBSD.
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00002354
Benjamin Kramer96a44b62012-05-16 12:44:25 +00002355 .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat)
2356 .Default(InvalidFormat);
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00002357}
2358
Fariborz Jahanianef5f6212010-06-18 21:44:06 +00002359/// Handle __attribute__((init_priority(priority))) attributes based on
Bill Wendling44426052012-12-20 19:22:21 +00002360/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
Chandler Carruthedc2c642011-07-02 00:01:44 +00002361static void handleInitPriorityAttr(Sema &S, Decl *D,
2362 const AttributeList &Attr) {
David Blaikiebbafb8a2012-03-11 07:00:24 +00002363 if (!S.getLangOpts().CPlusPlus) {
Fariborz Jahanianef5f6212010-06-18 21:44:06 +00002364 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2365 return;
2366 }
2367
Aaron Ballman4a611152013-11-27 16:34:09 +00002368 if (S.getCurFunctionOrMethodDecl()) {
Fariborz Jahanian0bf5ee72010-06-18 23:14:53 +00002369 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2370 Attr.setInvalid();
2371 return;
2372 }
Aaron Ballman4a611152013-11-27 16:34:09 +00002373 QualType T = cast<VarDecl>(D)->getType();
Fariborz Jahanian0bf5ee72010-06-18 23:14:53 +00002374 if (S.Context.getAsArrayType(T))
2375 T = S.Context.getBaseElementType(T);
2376 if (!T->getAs<RecordType>()) {
2377 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2378 Attr.setInvalid();
2379 return;
2380 }
Aaron Ballmanf22ef5a2013-11-21 01:50:40 +00002381
2382 Expr *E = Attr.getArgAsExpr(0);
2383 uint32_t prioritynum;
2384 if (!checkUInt32Argument(S, Attr, E, prioritynum)) {
Fariborz Jahanianef5f6212010-06-18 21:44:06 +00002385 Attr.setInvalid();
2386 return;
2387 }
Aaron Ballmanf22ef5a2013-11-21 01:50:40 +00002388
Fariborz Jahanianef5f6212010-06-18 21:44:06 +00002389 if (prioritynum < 101 || prioritynum > 65535) {
2390 S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
Aaron Ballmanf22ef5a2013-11-21 01:50:40 +00002391 << E->getSourceRange();
Fariborz Jahanianef5f6212010-06-18 21:44:06 +00002392 Attr.setInvalid();
2393 return;
2394 }
Michael Han99315932013-01-24 16:46:58 +00002395 D->addAttr(::new (S.Context)
2396 InitPriorityAttr(Attr.getRange(), S.Context, prioritynum,
2397 Attr.getAttributeSpellingListIndex()));
Fariborz Jahanianef5f6212010-06-18 21:44:06 +00002398}
2399
Aaron Ballmanf58070b2013-09-03 21:02:22 +00002400FormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range,
2401 IdentifierInfo *Format, int FormatIdx,
2402 int FirstArg,
Michael Han99315932013-01-24 16:46:58 +00002403 unsigned AttrSpellingListIndex) {
Rafael Espindola92d49452012-05-11 00:36:07 +00002404 // Check whether we already have an equivalent format attribute.
Aaron Ballmanbe22bcb2014-03-10 17:08:28 +00002405 for (auto *F : D->specific_attrs<FormatAttr>()) {
2406 if (F->getType() == Format &&
2407 F->getFormatIdx() == FormatIdx &&
2408 F->getFirstArg() == FirstArg) {
Rafael Espindola92d49452012-05-11 00:36:07 +00002409 // If we don't have a valid location for this attribute, adopt the
2410 // location.
Aaron Ballmanbe22bcb2014-03-10 17:08:28 +00002411 if (F->getLocation().isInvalid())
2412 F->setRange(Range);
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002413 return NULL;
Rafael Espindola92d49452012-05-11 00:36:07 +00002414 }
2415 }
2416
Aaron Ballmanf58070b2013-09-03 21:02:22 +00002417 return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx,
2418 FirstArg, AttrSpellingListIndex);
Rafael Espindola92d49452012-05-11 00:36:07 +00002419}
2420
Mike Stumpd3bb5572009-07-24 19:02:52 +00002421/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
Bill Wendling44426052012-12-20 19:22:21 +00002422/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
Chandler Carruthedc2c642011-07-02 00:01:44 +00002423static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Aaron Ballman00e99962013-08-31 01:11:41 +00002424 if (!Attr.isArgIdent(0)) {
Aaron Ballman29982272013-07-23 14:03:57 +00002425 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
Aaron Ballman00e99962013-08-31 01:11:41 +00002426 << Attr.getName() << 1 << AANT_ArgumentIdentifier;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002427 return;
2428 }
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002429
Chandler Carruth743682b2010-11-16 08:35:43 +00002430 // In C++ the implicit 'this' function parameter also counts, and they are
2431 // counted from one.
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002432 bool HasImplicitThisParam = isInstanceMethod(D);
Alp Toker601b22c2014-01-21 23:35:24 +00002433 unsigned NumArgs = getFunctionOrMethodNumParams(D) + HasImplicitThisParam;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002434
Aaron Ballman00e99962013-08-31 01:11:41 +00002435 IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident;
2436 StringRef Format = II->getName();
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002437
2438 // Normalize the argument, __foo__ becomes foo.
Aaron Ballmanf58070b2013-09-03 21:02:22 +00002439 if (Format.startswith("__") && Format.endswith("__")) {
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00002440 Format = Format.substr(2, Format.size() - 4);
Aaron Ballmanf58070b2013-09-03 21:02:22 +00002441 // If we've modified the string name, we need a new identifier for it.
2442 II = &S.Context.Idents.get(Format);
2443 }
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002444
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00002445 // Check for supported formats.
2446 FormatAttrKind Kind = getFormatAttrKind(Format);
Chris Lattner12161d32010-03-22 21:08:50 +00002447
2448 if (Kind == IgnoredFormat)
2449 return;
2450
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00002451 if (Kind == InvalidFormat) {
Chris Lattner3b054132008-11-19 05:08:23 +00002452 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
Aaron Ballman190bad42013-12-26 16:13:50 +00002453 << Attr.getName() << II->getName();
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002454 return;
2455 }
2456
2457 // checks for the 2nd argument
Aaron Ballman00e99962013-08-31 01:11:41 +00002458 Expr *IdxExpr = Attr.getArgAsExpr(1);
Aaron Ballmanf22ef5a2013-11-21 01:50:40 +00002459 uint32_t Idx;
2460 if (!checkUInt32Argument(S, Attr, IdxExpr, Idx, 2))
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002461 return;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002462
Aaron Ballmanf22ef5a2013-11-21 01:50:40 +00002463 if (Idx < 1 || Idx > NumArgs) {
Chris Lattner3b054132008-11-19 05:08:23 +00002464 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
Aaron Ballmanfaed0fa2013-12-26 16:30:30 +00002465 << Attr.getName() << 2 << IdxExpr->getSourceRange();
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002466 return;
2467 }
2468
2469 // FIXME: Do we need to bounds check?
Aaron Ballmanf22ef5a2013-11-21 01:50:40 +00002470 unsigned ArgIdx = Idx - 1;
Mike Stumpd3bb5572009-07-24 19:02:52 +00002471
Sebastian Redl6eedcc12009-11-17 18:02:24 +00002472 if (HasImplicitThisParam) {
2473 if (ArgIdx == 0) {
Chandler Carruth743682b2010-11-16 08:35:43 +00002474 S.Diag(Attr.getLoc(),
2475 diag::err_format_attribute_implicit_this_format_string)
2476 << IdxExpr->getSourceRange();
Sebastian Redl6eedcc12009-11-17 18:02:24 +00002477 return;
2478 }
2479 ArgIdx--;
2480 }
Mike Stump11289f42009-09-09 15:08:12 +00002481
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002482 // make sure the format string is really a string
Alp Toker601b22c2014-01-21 23:35:24 +00002483 QualType Ty = getFunctionOrMethodParamType(D, ArgIdx);
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002484
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00002485 if (Kind == CFStringFormat) {
Daniel Dunbar980c6692008-09-26 03:32:58 +00002486 if (!isCFStringType(Ty, S.Context)) {
Chris Lattner3b054132008-11-19 05:08:23 +00002487 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2488 << "a CFString" << IdxExpr->getSourceRange();
Daniel Dunbar980c6692008-09-26 03:32:58 +00002489 return;
2490 }
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00002491 } else if (Kind == NSStringFormat) {
Mike Stump87c57ac2009-05-16 07:39:55 +00002492 // FIXME: do we need to check if the type is NSString*? What are the
2493 // semantics?
Chris Lattnerb632a6e2008-06-29 00:43:07 +00002494 if (!isNSStringType(Ty, S.Context)) {
Mike Stump87c57ac2009-05-16 07:39:55 +00002495 // FIXME: Should highlight the actual expression that has the wrong type.
Chris Lattner3b054132008-11-19 05:08:23 +00002496 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2497 << "an NSString" << IdxExpr->getSourceRange();
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002498 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00002499 }
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002500 } else if (!Ty->isPointerType() ||
Ted Kremenekc23c7e62009-07-29 21:53:49 +00002501 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
Mike Stump87c57ac2009-05-16 07:39:55 +00002502 // FIXME: Should highlight the actual expression that has the wrong type.
Chris Lattner3b054132008-11-19 05:08:23 +00002503 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2504 << "a string type" << IdxExpr->getSourceRange();
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002505 return;
2506 }
2507
2508 // check the 3rd argument
Aaron Ballman00e99962013-08-31 01:11:41 +00002509 Expr *FirstArgExpr = Attr.getArgAsExpr(2);
Aaron Ballmanf22ef5a2013-11-21 01:50:40 +00002510 uint32_t FirstArg;
2511 if (!checkUInt32Argument(S, Attr, FirstArgExpr, FirstArg, 3))
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002512 return;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002513
2514 // check if the function is variadic if the 3rd argument non-zero
2515 if (FirstArg != 0) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002516 if (isFunctionOrMethodVariadic(D)) {
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002517 ++NumArgs; // +1 for ...
2518 } else {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002519 S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002520 return;
2521 }
2522 }
2523
Chris Lattner4bd8dd82008-11-19 08:23:25 +00002524 // strftime requires FirstArg to be 0 because it doesn't read from any
2525 // variable the input is just the current time + the format string.
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00002526 if (Kind == StrftimeFormat) {
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002527 if (FirstArg != 0) {
Chris Lattner3b054132008-11-19 05:08:23 +00002528 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
2529 << FirstArgExpr->getSourceRange();
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002530 return;
2531 }
2532 // if 0 it disables parameter checking (to use with e.g. va_list)
2533 } else if (FirstArg != 0 && FirstArg != NumArgs) {
Chris Lattner3b054132008-11-19 05:08:23 +00002534 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
Aaron Ballmanfaed0fa2013-12-26 16:30:30 +00002535 << Attr.getName() << 3 << FirstArgExpr->getSourceRange();
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002536 return;
2537 }
2538
Aaron Ballmanf58070b2013-09-03 21:02:22 +00002539 FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), II,
Aaron Ballmanf22ef5a2013-11-21 01:50:40 +00002540 Idx, FirstArg,
Michael Han99315932013-01-24 16:46:58 +00002541 Attr.getAttributeSpellingListIndex());
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002542 if (NewAttr)
2543 D->addAttr(NewAttr);
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002544}
2545
Chandler Carruthedc2c642011-07-02 00:01:44 +00002546static void handleTransparentUnionAttr(Sema &S, Decl *D,
2547 const AttributeList &Attr) {
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00002548 // Try to find the underlying union declaration.
2549 RecordDecl *RD = 0;
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002550 TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00002551 if (TD && TD->getUnderlyingType()->isUnionType())
2552 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
2553 else
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002554 RD = dyn_cast<RecordDecl>(D);
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00002555
2556 if (!RD || !RD->isUnion()) {
Chris Lattner3b054132008-11-19 05:08:23 +00002557 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00002558 << Attr.getName() << ExpectedUnion;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002559 return;
2560 }
2561
John McCallf937c022011-10-07 06:10:15 +00002562 if (!RD->isCompleteDefinition()) {
Mike Stumpd3bb5572009-07-24 19:02:52 +00002563 S.Diag(Attr.getLoc(),
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00002564 diag::warn_transparent_union_attribute_not_definition);
2565 return;
2566 }
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002567
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +00002568 RecordDecl::field_iterator Field = RD->field_begin(),
2569 FieldEnd = RD->field_end();
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00002570 if (Field == FieldEnd) {
2571 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
2572 return;
2573 }
Eli Friedman7c9ba6a2008-09-02 05:19:23 +00002574
David Blaikie40ed2972012-06-06 20:45:41 +00002575 FieldDecl *FirstField = *Field;
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00002576 QualType FirstType = FirstField->getType();
Douglas Gregor21872662010-06-30 17:24:13 +00002577 if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
Mike Stumpd3bb5572009-07-24 19:02:52 +00002578 S.Diag(FirstField->getLocation(),
Douglas Gregor21872662010-06-30 17:24:13 +00002579 diag::warn_transparent_union_attribute_floating)
2580 << FirstType->isVectorType() << FirstType;
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00002581 return;
2582 }
2583
2584 uint64_t FirstSize = S.Context.getTypeSize(FirstType);
2585 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
2586 for (; Field != FieldEnd; ++Field) {
2587 QualType FieldType = Field->getType();
Aaron Ballman54fe5eb2014-01-28 01:47:34 +00002588 // FIXME: this isn't fully correct; we also need to test whether the
2589 // members of the union would all have the same calling convention as the
2590 // first member of the union. Checking just the size and alignment isn't
2591 // sufficient (consider structs passed on the stack instead of in registers
2592 // as an example).
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00002593 if (S.Context.getTypeSize(FieldType) != FirstSize ||
Aaron Ballman54fe5eb2014-01-28 01:47:34 +00002594 S.Context.getTypeAlign(FieldType) > FirstAlign) {
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00002595 // Warn if we drop the attribute.
2596 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
Mike Stumpd3bb5572009-07-24 19:02:52 +00002597 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00002598 : S.Context.getTypeAlign(FieldType);
Mike Stumpd3bb5572009-07-24 19:02:52 +00002599 S.Diag(Field->getLocation(),
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00002600 diag::warn_transparent_union_attribute_field_size_align)
2601 << isSize << Field->getDeclName() << FieldBits;
2602 unsigned FirstBits = isSize? FirstSize : FirstAlign;
Mike Stumpd3bb5572009-07-24 19:02:52 +00002603 S.Diag(FirstField->getLocation(),
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00002604 diag::note_transparent_union_first_field_size_align)
2605 << isSize << FirstBits;
Eli Friedman7c9ba6a2008-09-02 05:19:23 +00002606 return;
2607 }
2608 }
2609
Michael Han99315932013-01-24 16:46:58 +00002610 RD->addAttr(::new (S.Context)
2611 TransparentUnionAttr(Attr.getRange(), S.Context,
2612 Attr.getAttributeSpellingListIndex()));
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002613}
2614
Chandler Carruthedc2c642011-07-02 00:01:44 +00002615static void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002616 // Make sure that there is a string literal as the annotation's single
2617 // argument.
Benjamin Kramer6ee15622013-09-13 15:35:43 +00002618 StringRef Str;
Tim Northover6a6b63b2013-10-01 14:34:18 +00002619 if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str))
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002620 return;
Julien Lerouge5a6b6982011-09-09 22:41:49 +00002621
2622 // Don't duplicate annotations that are already set.
Aaron Ballmanbe22bcb2014-03-10 17:08:28 +00002623 for (const auto *I : D->specific_attrs<AnnotateAttr>()) {
2624 if (I->getAnnotation() == Str)
Benjamin Kramer6ee15622013-09-13 15:35:43 +00002625 return;
Julien Lerouge5a6b6982011-09-09 22:41:49 +00002626 }
Michael Han99315932013-01-24 16:46:58 +00002627
2628 D->addAttr(::new (S.Context)
Benjamin Kramer6ee15622013-09-13 15:35:43 +00002629 AnnotateAttr(Attr.getRange(), S.Context, Str,
Michael Han99315932013-01-24 16:46:58 +00002630 Attr.getAttributeSpellingListIndex()));
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002631}
2632
Chandler Carruthedc2c642011-07-02 00:01:44 +00002633static void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002634 // check the attribute arguments.
Chris Lattner4a927cb2008-06-28 23:36:30 +00002635 if (Attr.getNumArgs() > 1) {
Aaron Ballmanb7243382013-07-23 19:30:11 +00002636 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
2637 << Attr.getName() << 1;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002638 return;
2639 }
Aaron Ballman478faed2012-06-19 22:09:27 +00002640
Richard Smith848e1f12013-02-01 08:12:08 +00002641 if (Attr.getNumArgs() == 0) {
2642 D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context,
2643 true, 0, Attr.getAttributeSpellingListIndex()));
2644 return;
2645 }
2646
Aaron Ballman00e99962013-08-31 01:11:41 +00002647 Expr *E = Attr.getArgAsExpr(0);
Richard Smith44c247f2013-02-22 08:32:16 +00002648 if (Attr.isPackExpansion() && !E->containsUnexpandedParameterPack()) {
2649 S.Diag(Attr.getEllipsisLoc(),
2650 diag::err_pack_expansion_without_parameter_packs);
2651 return;
2652 }
2653
2654 if (!Attr.isPackExpansion() && S.DiagnoseUnexpandedParameterPack(E))
2655 return;
2656
2657 S.AddAlignedAttr(Attr.getRange(), D, E, Attr.getAttributeSpellingListIndex(),
2658 Attr.isPackExpansion());
Richard Smith848e1f12013-02-01 08:12:08 +00002659}
2660
2661void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
Richard Smith44c247f2013-02-22 08:32:16 +00002662 unsigned SpellingListIndex, bool IsPackExpansion) {
Richard Smith848e1f12013-02-01 08:12:08 +00002663 AlignedAttr TmpAttr(AttrRange, Context, true, E, SpellingListIndex);
2664 SourceLocation AttrLoc = AttrRange.getBegin();
2665
Richard Smith1dba27c2013-01-29 09:02:09 +00002666 // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
Richard Smith848e1f12013-02-01 08:12:08 +00002667 if (TmpAttr.isAlignas()) {
Richard Smith1dba27c2013-01-29 09:02:09 +00002668 // C++11 [dcl.align]p1:
2669 // An alignment-specifier may be applied to a variable or to a class
2670 // data member, but it shall not be applied to a bit-field, a function
2671 // parameter, the formal parameter of a catch clause, or a variable
2672 // declared with the register storage class specifier. An
2673 // alignment-specifier may also be applied to the declaration of a class
2674 // or enumeration type.
2675 // C11 6.7.5/2:
2676 // An alignment attribute shall not be specified in a declaration of
2677 // a typedef, or a bit-field, or a function, or a parameter, or an
2678 // object declared with the register storage-class specifier.
2679 int DiagKind = -1;
2680 if (isa<ParmVarDecl>(D)) {
2681 DiagKind = 0;
2682 } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
2683 if (VD->getStorageClass() == SC_Register)
2684 DiagKind = 1;
2685 if (VD->isExceptionVariable())
2686 DiagKind = 2;
2687 } else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
2688 if (FD->isBitField())
2689 DiagKind = 3;
2690 } else if (!isa<TagDecl>(D)) {
Aaron Ballman3d216a52014-01-02 23:39:11 +00002691 Diag(AttrLoc, diag::err_attribute_wrong_decl_type) << &TmpAttr
Richard Smith9eaab4b2013-02-01 08:25:07 +00002692 << (TmpAttr.isC11() ? ExpectedVariableOrField
2693 : ExpectedVariableFieldOrTag);
Richard Smith1dba27c2013-01-29 09:02:09 +00002694 return;
2695 }
2696 if (DiagKind != -1) {
Richard Smith848e1f12013-02-01 08:12:08 +00002697 Diag(AttrLoc, diag::err_alignas_attribute_wrong_decl_type)
Aaron Ballman3d216a52014-01-02 23:39:11 +00002698 << &TmpAttr << DiagKind;
Richard Smith1dba27c2013-01-29 09:02:09 +00002699 return;
2700 }
2701 }
2702
Chandler Carruthf40c42f2010-06-25 03:22:07 +00002703 if (E->isTypeDependent() || E->isValueDependent()) {
2704 // Save dependent expressions in the AST to be instantiated.
Richard Smith44c247f2013-02-22 08:32:16 +00002705 AlignedAttr *AA = ::new (Context) AlignedAttr(TmpAttr);
2706 AA->setPackExpansion(IsPackExpansion);
2707 D->addAttr(AA);
Chandler Carruthf40c42f2010-06-25 03:22:07 +00002708 return;
2709 }
Michael Hanaf02bbe2013-02-01 01:19:17 +00002710
Alexis Huntdcfba7b2010-08-18 23:23:40 +00002711 // FIXME: Cache the number on the Attr object?
Chris Lattner4627b742008-06-28 23:50:44 +00002712 llvm::APSInt Alignment(32);
Douglas Gregore2b37442012-05-04 22:38:52 +00002713 ExprResult ICE
2714 = VerifyIntegerConstantExpression(E, &Alignment,
2715 diag::err_aligned_attribute_argument_not_int,
2716 /*AllowFold*/ false);
Richard Smithf4c51d92012-02-04 09:53:13 +00002717 if (ICE.isInvalid())
Chris Lattner4627b742008-06-28 23:50:44 +00002718 return;
Richard Smith848e1f12013-02-01 08:12:08 +00002719
2720 // C++11 [dcl.align]p2:
2721 // -- if the constant expression evaluates to zero, the alignment
2722 // specifier shall have no effect
2723 // C11 6.7.5p6:
2724 // An alignment specification of zero has no effect.
2725 if (!(TmpAttr.isAlignas() && !Alignment) &&
2726 !llvm::isPowerOf2_64(Alignment.getZExtValue())) {
Chandler Carruthf40c42f2010-06-25 03:22:07 +00002727 Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
2728 << E->getSourceRange();
Daniel Dunbar6e8c07d2009-02-16 23:37:57 +00002729 return;
2730 }
Michael Hanaf02bbe2013-02-01 01:19:17 +00002731
David Majnemerabecae72014-02-12 20:36:10 +00002732 // Alignment calculations can wrap around if it's greater than 2**28.
2733 unsigned MaxValidAlignment = TmpAttr.isDeclspec() ? 8192 : 268435456;
2734 if (Alignment.getZExtValue() > MaxValidAlignment) {
2735 Diag(AttrLoc, diag::err_attribute_aligned_too_great) << MaxValidAlignment
2736 << E->getSourceRange();
2737 return;
Aaron Ballman478faed2012-06-19 22:09:27 +00002738 }
Daniel Dunbar6e8c07d2009-02-16 23:37:57 +00002739
Richard Smith44c247f2013-02-22 08:32:16 +00002740 AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, true,
2741 ICE.take(), SpellingListIndex);
2742 AA->setPackExpansion(IsPackExpansion);
2743 D->addAttr(AA);
Alexis Huntdcfba7b2010-08-18 23:23:40 +00002744}
2745
Michael Hanaf02bbe2013-02-01 01:19:17 +00002746void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS,
Richard Smith44c247f2013-02-22 08:32:16 +00002747 unsigned SpellingListIndex, bool IsPackExpansion) {
Alexis Huntdcfba7b2010-08-18 23:23:40 +00002748 // FIXME: Cache the number on the Attr object if non-dependent?
2749 // FIXME: Perform checking of type validity
Richard Smith44c247f2013-02-22 08:32:16 +00002750 AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, false, TS,
2751 SpellingListIndex);
2752 AA->setPackExpansion(IsPackExpansion);
2753 D->addAttr(AA);
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002754}
Chris Lattneracbc2d22008-06-27 22:18:37 +00002755
Richard Smith848e1f12013-02-01 08:12:08 +00002756void Sema::CheckAlignasUnderalignment(Decl *D) {
2757 assert(D->hasAttrs() && "no attributes on decl");
2758
2759 QualType Ty;
2760 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2761 Ty = VD->getType();
2762 else
2763 Ty = Context.getTagDeclType(cast<TagDecl>(D));
Richard Smith3653b7e2013-02-22 09:21:42 +00002764 if (Ty->isDependentType() || Ty->isIncompleteType())
Richard Smith848e1f12013-02-01 08:12:08 +00002765 return;
2766
2767 // C++11 [dcl.align]p5, C11 6.7.5/4:
2768 // The combined effect of all alignment attributes in a declaration shall
2769 // not specify an alignment that is less strict than the alignment that
2770 // would otherwise be required for the entity being declared.
2771 AlignedAttr *AlignasAttr = 0;
2772 unsigned Align = 0;
Aaron Ballmanbe22bcb2014-03-10 17:08:28 +00002773 for (auto *I : D->specific_attrs<AlignedAttr>()) {
Richard Smith848e1f12013-02-01 08:12:08 +00002774 if (I->isAlignmentDependent())
2775 return;
2776 if (I->isAlignas())
Aaron Ballmanbe22bcb2014-03-10 17:08:28 +00002777 AlignasAttr = I;
Richard Smith848e1f12013-02-01 08:12:08 +00002778 Align = std::max(Align, I->getAlignment(Context));
2779 }
2780
2781 if (AlignasAttr && Align) {
2782 CharUnits RequestedAlign = Context.toCharUnitsFromBits(Align);
2783 CharUnits NaturalAlign = Context.getTypeAlignInChars(Ty);
2784 if (NaturalAlign > RequestedAlign)
2785 Diag(AlignasAttr->getLocation(), diag::err_alignas_underaligned)
2786 << Ty << (unsigned)NaturalAlign.getQuantity();
2787 }
2788}
2789
David Majnemer2c4e00a2014-01-29 22:07:36 +00002790bool Sema::checkMSInheritanceAttrOnDefinition(
David Majnemer4bb09802014-02-10 19:50:15 +00002791 CXXRecordDecl *RD, SourceRange Range, bool BestCase,
David Majnemer2c4e00a2014-01-29 22:07:36 +00002792 MSInheritanceAttr::Spelling SemanticSpelling) {
2793 assert(RD->hasDefinition() && "RD has no definition!");
2794
David Majnemer98c9ee22014-02-07 00:43:07 +00002795 // We may not have seen base specifiers or any virtual methods yet. We will
2796 // have to wait until the record is defined to catch any mismatches.
2797 if (!RD->getDefinition()->isCompleteDefinition())
2798 return false;
David Majnemer2c4e00a2014-01-29 22:07:36 +00002799
David Majnemer98c9ee22014-02-07 00:43:07 +00002800 // The unspecified model never matches what a definition could need.
2801 if (SemanticSpelling == MSInheritanceAttr::Keyword_unspecified_inheritance)
2802 return false;
2803
David Majnemer4bb09802014-02-10 19:50:15 +00002804 if (BestCase) {
2805 if (RD->calculateInheritanceModel() == SemanticSpelling)
2806 return false;
2807 } else {
2808 if (RD->calculateInheritanceModel() <= SemanticSpelling)
2809 return false;
2810 }
David Majnemer98c9ee22014-02-07 00:43:07 +00002811
2812 Diag(Range.getBegin(), diag::err_mismatched_ms_inheritance)
2813 << 0 /*definition*/;
2814 Diag(RD->getDefinition()->getLocation(), diag::note_defined_here)
2815 << RD->getNameAsString();
2816 return true;
David Majnemer2c4e00a2014-01-29 22:07:36 +00002817}
2818
Chandler Carruth3ed22c32011-07-01 23:49:16 +00002819/// handleModeAttr - This attribute modifies the width of a decl with primitive
Mike Stumpd3bb5572009-07-24 19:02:52 +00002820/// type.
Chris Lattneracbc2d22008-06-27 22:18:37 +00002821///
Mike Stumpd3bb5572009-07-24 19:02:52 +00002822/// Despite what would be logical, the mode attribute is a decl attribute, not a
2823/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
2824/// HImode, not an intermediate pointer.
Chandler Carruthedc2c642011-07-02 00:01:44 +00002825static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattneracbc2d22008-06-27 22:18:37 +00002826 // This attribute isn't documented, but glibc uses it. It changes
2827 // the width of an int or unsigned int to the specified size.
Aaron Ballman00e99962013-08-31 01:11:41 +00002828 if (!Attr.isArgIdent(0)) {
Aaron Ballman9744ffd2013-07-30 14:29:12 +00002829 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr.getName()
2830 << AANT_ArgumentIdentifier;
Chris Lattneracbc2d22008-06-27 22:18:37 +00002831 return;
2832 }
Aaron Ballman00e99962013-08-31 01:11:41 +00002833
Aaron Ballman00e99962013-08-31 01:11:41 +00002834 IdentifierInfo *Name = Attr.getArgAsIdent(0)->Ident;
2835 StringRef Str = Name->getName();
Chris Lattneracbc2d22008-06-27 22:18:37 +00002836
2837 // Normalize the attribute name, __foo__ becomes foo.
Daniel Dunbarafff4342009-10-18 02:09:24 +00002838 if (Str.startswith("__") && Str.endswith("__"))
2839 Str = Str.substr(2, Str.size() - 4);
Chris Lattneracbc2d22008-06-27 22:18:37 +00002840
2841 unsigned DestWidth = 0;
2842 bool IntegerMode = true;
Eli Friedman4735374e2009-03-03 06:41:03 +00002843 bool ComplexMode = false;
Daniel Dunbarafff4342009-10-18 02:09:24 +00002844 switch (Str.size()) {
Chris Lattneracbc2d22008-06-27 22:18:37 +00002845 case 2:
Eli Friedman4735374e2009-03-03 06:41:03 +00002846 switch (Str[0]) {
2847 case 'Q': DestWidth = 8; break;
2848 case 'H': DestWidth = 16; break;
2849 case 'S': DestWidth = 32; break;
2850 case 'D': DestWidth = 64; break;
2851 case 'X': DestWidth = 96; break;
2852 case 'T': DestWidth = 128; break;
2853 }
2854 if (Str[1] == 'F') {
2855 IntegerMode = false;
2856 } else if (Str[1] == 'C') {
2857 IntegerMode = false;
2858 ComplexMode = true;
2859 } else if (Str[1] != 'I') {
2860 DestWidth = 0;
2861 }
Chris Lattneracbc2d22008-06-27 22:18:37 +00002862 break;
2863 case 4:
2864 // FIXME: glibc uses 'word' to define register_t; this is narrower than a
2865 // pointer on PIC16 and other embedded platforms.
Daniel Dunbarafff4342009-10-18 02:09:24 +00002866 if (Str == "word")
Douglas Gregore8bbc122011-09-02 00:18:52 +00002867 DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
Daniel Dunbarafff4342009-10-18 02:09:24 +00002868 else if (Str == "byte")
Douglas Gregore8bbc122011-09-02 00:18:52 +00002869 DestWidth = S.Context.getTargetInfo().getCharWidth();
Chris Lattneracbc2d22008-06-27 22:18:37 +00002870 break;
2871 case 7:
Daniel Dunbarafff4342009-10-18 02:09:24 +00002872 if (Str == "pointer")
Douglas Gregore8bbc122011-09-02 00:18:52 +00002873 DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
Chris Lattneracbc2d22008-06-27 22:18:37 +00002874 break;
Rafael Espindolaf0dafd32013-01-07 19:58:54 +00002875 case 11:
2876 if (Str == "unwind_word")
Rafael Espindola03705972013-01-07 20:01:57 +00002877 DestWidth = S.Context.getTargetInfo().getUnwindWordWidth();
Rafael Espindolaf0dafd32013-01-07 19:58:54 +00002878 break;
Chris Lattneracbc2d22008-06-27 22:18:37 +00002879 }
2880
2881 QualType OldTy;
Richard Smithdda56e42011-04-15 14:24:37 +00002882 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
Chris Lattneracbc2d22008-06-27 22:18:37 +00002883 OldTy = TD->getUnderlyingType();
2884 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2885 OldTy = VD->getType();
2886 else {
Chris Lattner3b054132008-11-19 05:08:23 +00002887 S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
Aaron Ballman2dfb03f2013-12-27 16:30:46 +00002888 << Attr.getName() << Attr.getRange();
Chris Lattneracbc2d22008-06-27 22:18:37 +00002889 return;
2890 }
Eli Friedman4735374e2009-03-03 06:41:03 +00002891
John McCall9dd450b2009-09-21 23:43:11 +00002892 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
Eli Friedman4735374e2009-03-03 06:41:03 +00002893 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
2894 else if (IntegerMode) {
Douglas Gregorb90df602010-06-16 00:17:44 +00002895 if (!OldTy->isIntegralOrEnumerationType())
Eli Friedman4735374e2009-03-03 06:41:03 +00002896 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
2897 } else if (ComplexMode) {
2898 if (!OldTy->isComplexType())
2899 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
2900 } else {
2901 if (!OldTy->isFloatingType())
2902 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
2903 }
2904
Mike Stump87c57ac2009-05-16 07:39:55 +00002905 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2906 // and friends, at least with glibc.
Eli Friedman1efaaea2009-02-13 02:31:07 +00002907 // FIXME: Make sure floating-point mappings are accurate
2908 // FIXME: Support XF and TF types
Stepan Dyatkovskiyb88c30f2013-09-18 09:08:52 +00002909 if (!DestWidth) {
Aaron Ballman03909082013-12-23 15:23:11 +00002910 S.Diag(Attr.getLoc(), diag::err_machine_mode) << 0 /*Unknown*/ << Name;
Chris Lattneracbc2d22008-06-27 22:18:37 +00002911 return;
Stepan Dyatkovskiyb88c30f2013-09-18 09:08:52 +00002912 }
2913
2914 QualType NewTy;
2915
2916 if (IntegerMode)
2917 NewTy = S.Context.getIntTypeForBitwidth(DestWidth,
2918 OldTy->isSignedIntegerType());
2919 else
2920 NewTy = S.Context.getRealTypeForBitwidth(DestWidth);
2921
2922 if (NewTy.isNull()) {
Aaron Ballman03909082013-12-23 15:23:11 +00002923 S.Diag(Attr.getLoc(), diag::err_machine_mode) << 1 /*Unsupported*/ << Name;
Chris Lattneracbc2d22008-06-27 22:18:37 +00002924 return;
Chris Lattneracbc2d22008-06-27 22:18:37 +00002925 }
2926
Eli Friedman4735374e2009-03-03 06:41:03 +00002927 if (ComplexMode) {
2928 NewTy = S.Context.getComplexType(NewTy);
Chris Lattneracbc2d22008-06-27 22:18:37 +00002929 }
2930
2931 // Install the new type.
Enea Zaffanellaa86d88c2013-06-20 12:46:19 +00002932 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
2933 TD->setModedTypeSourceInfo(TD->getTypeSourceInfo(), NewTy);
2934 else
Chris Lattneracbc2d22008-06-27 22:18:37 +00002935 cast<ValueDecl>(D)->setType(NewTy);
Enea Zaffanellaa86d88c2013-06-20 12:46:19 +00002936
2937 D->addAttr(::new (S.Context)
2938 ModeAttr(Attr.getRange(), S.Context, Name,
2939 Attr.getAttributeSpellingListIndex()));
Chris Lattneracbc2d22008-06-27 22:18:37 +00002940}
Chris Lattner9e2aafe2008-06-29 00:23:49 +00002941
Chandler Carruthedc2c642011-07-02 00:01:44 +00002942static void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Nick Lewycky08597072012-07-24 01:40:49 +00002943 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
2944 if (!VD->hasGlobalStorage())
2945 S.Diag(Attr.getLoc(),
2946 diag::warn_attribute_requires_functions_or_static_globals)
2947 << Attr.getName();
2948 } else if (!isFunctionOrMethod(D)) {
2949 S.Diag(Attr.getLoc(),
2950 diag::warn_attribute_requires_functions_or_static_globals)
2951 << Attr.getName();
Anders Carlsson76187b42009-02-13 06:46:13 +00002952 return;
2953 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002954
Michael Han99315932013-01-24 16:46:58 +00002955 D->addAttr(::new (S.Context)
2956 NoDebugAttr(Attr.getRange(), S.Context,
2957 Attr.getAttributeSpellingListIndex()));
Anders Carlsson76187b42009-02-13 06:46:13 +00002958}
2959
Chandler Carruthedc2c642011-07-02 00:01:44 +00002960static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Aaron Ballman3aff6332013-12-02 19:30:36 +00002961 FunctionDecl *FD = cast<FunctionDecl>(D);
Alp Toker314cc812014-01-25 16:55:45 +00002962 if (!FD->getReturnType()->isVoidType()) {
Aaron Ballman3aff6332013-12-02 19:30:36 +00002963 TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
2964 if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) {
2965 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
2966 << FD->getType()
Alp Toker42a16a62014-01-25 23:51:36 +00002967 << FixItHint::CreateReplacement(FTL.getReturnLoc().getSourceRange(),
Aaron Ballman3aff6332013-12-02 19:30:36 +00002968 "void");
2969 } else {
2970 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
2971 << FD->getType();
Peter Collingbournee8cfaf42010-12-12 23:02:57 +00002972 }
Aaron Ballman3aff6332013-12-02 19:30:36 +00002973 return;
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00002974 }
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00002975
Aaron Ballman3aff6332013-12-02 19:30:36 +00002976 D->addAttr(::new (S.Context)
2977 CUDAGlobalAttr(Attr.getRange(), S.Context,
Michael Han99315932013-01-24 16:46:58 +00002978 Attr.getAttributeSpellingListIndex()));
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00002979}
2980
Chandler Carruthedc2c642011-07-02 00:01:44 +00002981static void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Aaron Ballman74eeeae2013-11-27 13:27:02 +00002982 FunctionDecl *Fn = cast<FunctionDecl>(D);
Douglas Gregor35b57532009-10-27 21:01:01 +00002983 if (!Fn->isInlineSpecified()) {
Chris Lattnerddf6ca02009-04-20 19:12:28 +00002984 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
Chris Lattner4225e232009-04-14 17:02:11 +00002985 return;
2986 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002987
Michael Han99315932013-01-24 16:46:58 +00002988 D->addAttr(::new (S.Context)
2989 GNUInlineAttr(Attr.getRange(), S.Context,
2990 Attr.getAttributeSpellingListIndex()));
Chris Lattnereaad6b72009-04-14 16:30:50 +00002991}
2992
Chandler Carruthedc2c642011-07-02 00:01:44 +00002993static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002994 if (hasDeclarator(D)) return;
Abramo Bagnara50099372010-04-30 13:10:51 +00002995
Aaron Ballman02df2e02012-12-09 17:45:41 +00002996 const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002997 // Diagnostic is emitted elsewhere: here we store the (valid) Attr
John McCall3882ace2011-01-05 12:14:39 +00002998 // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2999 CallingConv CC;
Aaron Ballman02df2e02012-12-09 17:45:41 +00003000 if (S.CheckCallingConvAttr(Attr, CC, FD))
John McCall3882ace2011-01-05 12:14:39 +00003001 return;
3002
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003003 if (!isa<ObjCMethodDecl>(D)) {
3004 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3005 << Attr.getName() << ExpectedFunctionOrMethod;
John McCall3882ace2011-01-05 12:14:39 +00003006 return;
3007 }
3008
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003009 switch (Attr.getKind()) {
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003010 case AttributeList::AT_FastCall:
Michael Han99315932013-01-24 16:46:58 +00003011 D->addAttr(::new (S.Context)
3012 FastCallAttr(Attr.getRange(), S.Context,
3013 Attr.getAttributeSpellingListIndex()));
Abramo Bagnara50099372010-04-30 13:10:51 +00003014 return;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003015 case AttributeList::AT_StdCall:
Michael Han99315932013-01-24 16:46:58 +00003016 D->addAttr(::new (S.Context)
3017 StdCallAttr(Attr.getRange(), S.Context,
3018 Attr.getAttributeSpellingListIndex()));
Abramo Bagnara50099372010-04-30 13:10:51 +00003019 return;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003020 case AttributeList::AT_ThisCall:
Michael Han99315932013-01-24 16:46:58 +00003021 D->addAttr(::new (S.Context)
3022 ThisCallAttr(Attr.getRange(), S.Context,
3023 Attr.getAttributeSpellingListIndex()));
Douglas Gregor4d13d102010-08-30 23:30:49 +00003024 return;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003025 case AttributeList::AT_CDecl:
Michael Han99315932013-01-24 16:46:58 +00003026 D->addAttr(::new (S.Context)
3027 CDeclAttr(Attr.getRange(), S.Context,
3028 Attr.getAttributeSpellingListIndex()));
Abramo Bagnara50099372010-04-30 13:10:51 +00003029 return;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003030 case AttributeList::AT_Pascal:
Michael Han99315932013-01-24 16:46:58 +00003031 D->addAttr(::new (S.Context)
3032 PascalAttr(Attr.getRange(), S.Context,
3033 Attr.getAttributeSpellingListIndex()));
Dawn Perchik335e16b2010-09-03 01:29:35 +00003034 return;
Charles Davisb5a214e2013-08-30 04:39:01 +00003035 case AttributeList::AT_MSABI:
3036 D->addAttr(::new (S.Context)
3037 MSABIAttr(Attr.getRange(), S.Context,
3038 Attr.getAttributeSpellingListIndex()));
3039 return;
3040 case AttributeList::AT_SysVABI:
3041 D->addAttr(::new (S.Context)
3042 SysVABIAttr(Attr.getRange(), S.Context,
3043 Attr.getAttributeSpellingListIndex()));
3044 return;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003045 case AttributeList::AT_Pcs: {
Anton Korobeynikov231e8752011-04-14 20:06:49 +00003046 PcsAttr::PCSType PCS;
Benjamin Kramer25885f42012-08-14 13:24:39 +00003047 switch (CC) {
3048 case CC_AAPCS:
Anton Korobeynikov231e8752011-04-14 20:06:49 +00003049 PCS = PcsAttr::AAPCS;
Benjamin Kramer25885f42012-08-14 13:24:39 +00003050 break;
3051 case CC_AAPCS_VFP:
Anton Korobeynikov231e8752011-04-14 20:06:49 +00003052 PCS = PcsAttr::AAPCS_VFP;
Benjamin Kramer25885f42012-08-14 13:24:39 +00003053 break;
3054 default:
3055 llvm_unreachable("unexpected calling convention in pcs attribute");
Anton Korobeynikov231e8752011-04-14 20:06:49 +00003056 }
3057
Michael Han99315932013-01-24 16:46:58 +00003058 D->addAttr(::new (S.Context)
3059 PcsAttr(Attr.getRange(), S.Context, PCS,
3060 Attr.getAttributeSpellingListIndex()));
Derek Schuffa2020962012-10-16 22:30:41 +00003061 return;
Anton Korobeynikov231e8752011-04-14 20:06:49 +00003062 }
Derek Schuffa2020962012-10-16 22:30:41 +00003063 case AttributeList::AT_PnaclCall:
Michael Han99315932013-01-24 16:46:58 +00003064 D->addAttr(::new (S.Context)
3065 PnaclCallAttr(Attr.getRange(), S.Context,
3066 Attr.getAttributeSpellingListIndex()));
Derek Schuffa2020962012-10-16 22:30:41 +00003067 return;
Guy Benyeif0a014b2012-12-25 08:53:55 +00003068 case AttributeList::AT_IntelOclBicc:
Michael Han99315932013-01-24 16:46:58 +00003069 D->addAttr(::new (S.Context)
3070 IntelOclBiccAttr(Attr.getRange(), S.Context,
3071 Attr.getAttributeSpellingListIndex()));
Guy Benyeif0a014b2012-12-25 08:53:55 +00003072 return;
Derek Schuffa2020962012-10-16 22:30:41 +00003073
Abramo Bagnara50099372010-04-30 13:10:51 +00003074 default:
3075 llvm_unreachable("unexpected attribute kind");
Abramo Bagnara50099372010-04-30 13:10:51 +00003076 }
3077}
3078
Aaron Ballman02df2e02012-12-09 17:45:41 +00003079bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
3080 const FunctionDecl *FD) {
John McCall3882ace2011-01-05 12:14:39 +00003081 if (attr.isInvalid())
3082 return true;
3083
Benjamin Kramer833fb9f2012-08-14 13:13:47 +00003084 unsigned ReqArgs = attr.getKind() == AttributeList::AT_Pcs ? 1 : 0;
Aaron Ballman00e99962013-08-31 01:11:41 +00003085 if (!checkAttributeNumArgs(*this, attr, ReqArgs)) {
John McCall3882ace2011-01-05 12:14:39 +00003086 attr.setInvalid();
3087 return true;
3088 }
3089
Aaron Ballmanab7691c2014-01-09 22:48:32 +00003090 // TODO: diagnose uses of these conventions on the wrong target.
John McCall3882ace2011-01-05 12:14:39 +00003091 switch (attr.getKind()) {
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003092 case AttributeList::AT_CDecl: CC = CC_C; break;
3093 case AttributeList::AT_FastCall: CC = CC_X86FastCall; break;
3094 case AttributeList::AT_StdCall: CC = CC_X86StdCall; break;
3095 case AttributeList::AT_ThisCall: CC = CC_X86ThisCall; break;
3096 case AttributeList::AT_Pascal: CC = CC_X86Pascal; break;
Charles Davisb5a214e2013-08-30 04:39:01 +00003097 case AttributeList::AT_MSABI:
3098 CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C :
3099 CC_X86_64Win64;
3100 break;
3101 case AttributeList::AT_SysVABI:
3102 CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_X86_64SysV :
3103 CC_C;
3104 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003105 case AttributeList::AT_Pcs: {
Aaron Ballmand6600a52013-09-13 17:48:25 +00003106 StringRef StrRef;
Tim Northover6a6b63b2013-10-01 14:34:18 +00003107 if (!checkStringLiteralArgumentAttr(attr, 0, StrRef)) {
Anton Korobeynikov231e8752011-04-14 20:06:49 +00003108 attr.setInvalid();
3109 return true;
3110 }
Anton Korobeynikov231e8752011-04-14 20:06:49 +00003111 if (StrRef == "aapcs") {
3112 CC = CC_AAPCS;
3113 break;
3114 } else if (StrRef == "aapcs-vfp") {
3115 CC = CC_AAPCS_VFP;
3116 break;
3117 }
Benjamin Kramer833fb9f2012-08-14 13:13:47 +00003118
3119 attr.setInvalid();
3120 Diag(attr.getLoc(), diag::err_invalid_pcs);
3121 return true;
Anton Korobeynikov231e8752011-04-14 20:06:49 +00003122 }
Derek Schuffa2020962012-10-16 22:30:41 +00003123 case AttributeList::AT_PnaclCall: CC = CC_PnaclCall; break;
Guy Benyeif0a014b2012-12-25 08:53:55 +00003124 case AttributeList::AT_IntelOclBicc: CC = CC_IntelOclBicc; break;
David Blaikie8a40f702012-01-17 06:56:22 +00003125 default: llvm_unreachable("unexpected attribute kind");
John McCall3882ace2011-01-05 12:14:39 +00003126 }
3127
Aaron Ballmane91c6be2012-10-02 14:26:08 +00003128 const TargetInfo &TI = Context.getTargetInfo();
3129 TargetInfo::CallingConvCheckResult A = TI.checkCallingConvention(CC);
3130 if (A == TargetInfo::CCCR_Warning) {
3131 Diag(attr.getLoc(), diag::warn_cconv_ignored) << attr.getName();
Aaron Ballman02df2e02012-12-09 17:45:41 +00003132
3133 TargetInfo::CallingConvMethodType MT = TargetInfo::CCMT_Unknown;
3134 if (FD)
3135 MT = FD->isCXXInstanceMember() ? TargetInfo::CCMT_Member :
3136 TargetInfo::CCMT_NonMember;
3137 CC = TI.getDefaultCallingConv(MT);
Aaron Ballmane91c6be2012-10-02 14:26:08 +00003138 }
3139
John McCall3882ace2011-01-05 12:14:39 +00003140 return false;
3141}
3142
John McCall3882ace2011-01-05 12:14:39 +00003143/// Checks a regparm attribute, returning true if it is ill-formed and
3144/// otherwise setting numParams to the appropriate value.
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003145bool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
3146 if (Attr.isInvalid())
John McCall3882ace2011-01-05 12:14:39 +00003147 return true;
3148
Aaron Ballmanc2cbc662013-07-18 18:01:48 +00003149 if (!checkAttributeNumArgs(*this, Attr, 1)) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003150 Attr.setInvalid();
John McCall3882ace2011-01-05 12:14:39 +00003151 return true;
Fariborz Jahaniana2d609e2009-03-27 18:38:55 +00003152 }
Eli Friedman7044b762009-03-27 21:06:47 +00003153
Aaron Ballmanf22ef5a2013-11-21 01:50:40 +00003154 uint32_t NP;
Aaron Ballman00e99962013-08-31 01:11:41 +00003155 Expr *NumParamsExpr = Attr.getArgAsExpr(0);
Aaron Ballmanf22ef5a2013-11-21 01:50:40 +00003156 if (!checkUInt32Argument(*this, Attr, NumParamsExpr, NP)) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003157 Attr.setInvalid();
John McCall3882ace2011-01-05 12:14:39 +00003158 return true;
Eli Friedman7044b762009-03-27 21:06:47 +00003159 }
3160
Douglas Gregore8bbc122011-09-02 00:18:52 +00003161 if (Context.getTargetInfo().getRegParmMax() == 0) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003162 Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
Eli Friedman7044b762009-03-27 21:06:47 +00003163 << NumParamsExpr->getSourceRange();
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003164 Attr.setInvalid();
John McCall3882ace2011-01-05 12:14:39 +00003165 return true;
Eli Friedman7044b762009-03-27 21:06:47 +00003166 }
3167
Aaron Ballmanf22ef5a2013-11-21 01:50:40 +00003168 numParams = NP;
Douglas Gregore8bbc122011-09-02 00:18:52 +00003169 if (numParams > Context.getTargetInfo().getRegParmMax()) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003170 Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
Douglas Gregore8bbc122011-09-02 00:18:52 +00003171 << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003172 Attr.setInvalid();
John McCall3882ace2011-01-05 12:14:39 +00003173 return true;
Eli Friedman7044b762009-03-27 21:06:47 +00003174 }
3175
John McCall3882ace2011-01-05 12:14:39 +00003176 return false;
Fariborz Jahaniana2d609e2009-03-27 18:38:55 +00003177}
3178
Aaron Ballman66039932013-12-19 00:41:31 +00003179static void handleLaunchBoundsAttr(Sema &S, Decl *D,
3180 const AttributeList &Attr) {
Aaron Ballman3aff6332013-12-02 19:30:36 +00003181 // check the attribute arguments.
3182 if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
3183 // FIXME: 0 is not okay.
Aaron Ballman05e420a2014-01-02 21:26:14 +00003184 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments)
3185 << Attr.getName() << 2;
Aaron Ballman3aff6332013-12-02 19:30:36 +00003186 return;
Peter Collingbourne827301e2010-12-12 23:03:07 +00003187 }
Aaron Ballman3aff6332013-12-02 19:30:36 +00003188
Aaron Ballman66039932013-12-19 00:41:31 +00003189 uint32_t MaxThreads, MinBlocks = 0;
3190 if (!checkUInt32Argument(S, Attr, Attr.getArgAsExpr(0), MaxThreads, 1))
3191 return;
3192 if (Attr.getNumArgs() > 1 && !checkUInt32Argument(S, Attr,
3193 Attr.getArgAsExpr(1),
3194 MinBlocks, 2))
Aaron Ballman3aff6332013-12-02 19:30:36 +00003195 return;
3196
3197 D->addAttr(::new (S.Context)
3198 CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
3199 MaxThreads, MinBlocks,
3200 Attr.getAttributeSpellingListIndex()));
Peter Collingbourne827301e2010-12-12 23:03:07 +00003201}
3202
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +00003203static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D,
3204 const AttributeList &Attr) {
Aaron Ballman00e99962013-08-31 01:11:41 +00003205 if (!Attr.isArgIdent(0)) {
Aaron Ballman29982272013-07-23 14:03:57 +00003206 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
Aaron Ballman3bf758c2013-07-30 01:31:03 +00003207 << Attr.getName() << /* arg num = */ 1 << AANT_ArgumentIdentifier;
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +00003208 return;
3209 }
Aaron Ballman00e99962013-08-31 01:11:41 +00003210
3211 if (!checkAttributeNumArgs(S, Attr, 3))
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +00003212 return;
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +00003213
Aaron Ballman00e99962013-08-31 01:11:41 +00003214 IdentifierInfo *ArgumentKind = Attr.getArgAsIdent(0)->Ident;
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +00003215
3216 if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
3217 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
3218 << Attr.getName() << ExpectedFunctionOrMethod;
3219 return;
3220 }
3221
3222 uint64_t ArgumentIdx;
Alp Toker601b22c2014-01-21 23:35:24 +00003223 if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 2, Attr.getArgAsExpr(1),
3224 ArgumentIdx))
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +00003225 return;
3226
3227 uint64_t TypeTagIdx;
Alp Toker601b22c2014-01-21 23:35:24 +00003228 if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 3, Attr.getArgAsExpr(2),
3229 TypeTagIdx))
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +00003230 return;
3231
Aaron Ballmanfaed0fa2013-12-26 16:30:30 +00003232 bool IsPointer = (Attr.getName()->getName() == "pointer_with_type_tag");
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +00003233 if (IsPointer) {
3234 // Ensure that buffer has a pointer type.
Alp Toker601b22c2014-01-21 23:35:24 +00003235 QualType BufferTy = getFunctionOrMethodParamType(D, ArgumentIdx);
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +00003236 if (!BufferTy->isPointerType()) {
3237 S.Diag(Attr.getLoc(), diag::err_attribute_pointers_only)
Aaron Ballman317a77f2013-05-22 23:25:32 +00003238 << Attr.getName();
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +00003239 }
3240 }
3241
Michael Han99315932013-01-24 16:46:58 +00003242 D->addAttr(::new (S.Context)
3243 ArgumentWithTypeTagAttr(Attr.getRange(), S.Context, ArgumentKind,
3244 ArgumentIdx, TypeTagIdx, IsPointer,
3245 Attr.getAttributeSpellingListIndex()));
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +00003246}
3247
3248static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
3249 const AttributeList &Attr) {
Aaron Ballman00e99962013-08-31 01:11:41 +00003250 if (!Attr.isArgIdent(0)) {
Aaron Ballman29982272013-07-23 14:03:57 +00003251 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
Aaron Ballman3bf758c2013-07-30 01:31:03 +00003252 << Attr.getName() << 1 << AANT_ArgumentIdentifier;
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +00003253 return;
3254 }
Aaron Ballman00e99962013-08-31 01:11:41 +00003255
3256 if (!checkAttributeNumArgs(S, Attr, 1))
3257 return;
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +00003258
Aaron Ballman90f8c6f2013-11-25 18:50:49 +00003259 if (!isa<VarDecl>(D)) {
3260 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
3261 << Attr.getName() << ExpectedVariable;
3262 return;
3263 }
3264
Aaron Ballman00e99962013-08-31 01:11:41 +00003265 IdentifierInfo *PointerKind = Attr.getArgAsIdent(0)->Ident;
Richard Smithb87c4652013-10-31 21:23:20 +00003266 TypeSourceInfo *MatchingCTypeLoc = 0;
3267 S.GetTypeFromParser(Attr.getMatchingCType(), &MatchingCTypeLoc);
3268 assert(MatchingCTypeLoc && "no type source info for attribute argument");
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +00003269
Michael Han99315932013-01-24 16:46:58 +00003270 D->addAttr(::new (S.Context)
3271 TypeTagForDatatypeAttr(Attr.getRange(), S.Context, PointerKind,
Richard Smithb87c4652013-10-31 21:23:20 +00003272 MatchingCTypeLoc,
Michael Han99315932013-01-24 16:46:58 +00003273 Attr.getLayoutCompatible(),
3274 Attr.getMustBeNull(),
3275 Attr.getAttributeSpellingListIndex()));
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +00003276}
3277
Chris Lattner9e2aafe2008-06-29 00:23:49 +00003278//===----------------------------------------------------------------------===//
Ted Kremenek9ecdfaf2009-05-09 02:44:38 +00003279// Checker-specific attribute handlers.
3280//===----------------------------------------------------------------------===//
3281
John McCalled433932011-01-25 03:31:58 +00003282static bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
Douglas Gregorf892c7f2011-10-09 22:26:49 +00003283 return type->isDependentType() ||
3284 type->isObjCObjectPointerType() ||
3285 S.Context.isObjCNSObjectType(type);
John McCalled433932011-01-25 03:31:58 +00003286}
3287static bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
Douglas Gregorf892c7f2011-10-09 22:26:49 +00003288 return type->isDependentType() ||
3289 type->isPointerType() ||
3290 isValidSubjectOfNSAttribute(S, type);
John McCalled433932011-01-25 03:31:58 +00003291}
3292
Chandler Carruthedc2c642011-07-02 00:01:44 +00003293static void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Aaron Ballman74eeeae2013-11-27 13:27:02 +00003294 ParmVarDecl *param = cast<ParmVarDecl>(D);
John McCalled433932011-01-25 03:31:58 +00003295 bool typeOK, cf;
Aaron Ballman74eeeae2013-11-27 13:27:02 +00003296
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003297 if (Attr.getKind() == AttributeList::AT_NSConsumed) {
John McCalled433932011-01-25 03:31:58 +00003298 typeOK = isValidSubjectOfNSAttribute(S, param->getType());
3299 cf = false;
3300 } else {
3301 typeOK = isValidSubjectOfCFAttribute(S, param->getType());
3302 cf = true;
3303 }
3304
3305 if (!typeOK) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003306 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
Argyrios Kyrtzidis309b4c42011-09-13 16:05:58 +00003307 << Attr.getRange() << Attr.getName() << cf;
John McCalled433932011-01-25 03:31:58 +00003308 return;
3309 }
3310
3311 if (cf)
Michael Han99315932013-01-24 16:46:58 +00003312 param->addAttr(::new (S.Context)
3313 CFConsumedAttr(Attr.getRange(), S.Context,
3314 Attr.getAttributeSpellingListIndex()));
John McCalled433932011-01-25 03:31:58 +00003315 else
Michael Han99315932013-01-24 16:46:58 +00003316 param->addAttr(::new (S.Context)
3317 NSConsumedAttr(Attr.getRange(), S.Context,
3318 Attr.getAttributeSpellingListIndex()));
John McCalled433932011-01-25 03:31:58 +00003319}
3320
Chandler Carruthedc2c642011-07-02 00:01:44 +00003321static void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
3322 const AttributeList &Attr) {
Ted Kremenek9ecdfaf2009-05-09 02:44:38 +00003323
John McCalled433932011-01-25 03:31:58 +00003324 QualType returnType;
Mike Stumpd3bb5572009-07-24 19:02:52 +00003325
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003326 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Alp Toker314cc812014-01-25 16:55:45 +00003327 returnType = MD->getReturnType();
David Blaikiebbafb8a2012-03-11 07:00:24 +00003328 else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) &&
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003329 (Attr.getKind() == AttributeList::AT_NSReturnsRetained))
John McCall31168b02011-06-15 23:02:42 +00003330 return; // ignore: was handled as a type attribute
Fariborz Jahanian272b7dc2012-08-28 22:26:21 +00003331 else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
3332 returnType = PD->getType();
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003333 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Alp Toker314cc812014-01-25 16:55:45 +00003334 returnType = FD->getReturnType();
Ted Kremenek3b204e42009-05-13 21:07:32 +00003335 else {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003336 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
Argyrios Kyrtzidis309b4c42011-09-13 16:05:58 +00003337 << Attr.getRange() << Attr.getName()
John McCall5fca7ea2011-03-02 12:29:23 +00003338 << ExpectedFunctionOrMethod;
Ted Kremenek9ecdfaf2009-05-09 02:44:38 +00003339 return;
3340 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00003341
John McCalled433932011-01-25 03:31:58 +00003342 bool typeOK;
3343 bool cf;
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003344 switch (Attr.getKind()) {
David Blaikie8a40f702012-01-17 06:56:22 +00003345 default: llvm_unreachable("invalid ownership attribute");
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003346 case AttributeList::AT_NSReturnsAutoreleased:
3347 case AttributeList::AT_NSReturnsRetained:
3348 case AttributeList::AT_NSReturnsNotRetained:
John McCalled433932011-01-25 03:31:58 +00003349 typeOK = isValidSubjectOfNSAttribute(S, returnType);
3350 cf = false;
3351 break;
3352
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003353 case AttributeList::AT_CFReturnsRetained:
3354 case AttributeList::AT_CFReturnsNotRetained:
John McCalled433932011-01-25 03:31:58 +00003355 typeOK = isValidSubjectOfCFAttribute(S, returnType);
3356 cf = true;
3357 break;
3358 }
3359
3360 if (!typeOK) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003361 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
Argyrios Kyrtzidis309b4c42011-09-13 16:05:58 +00003362 << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
Mike Stumpd3bb5572009-07-24 19:02:52 +00003363 return;
Ted Kremenek3b204e42009-05-13 21:07:32 +00003364 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00003365
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003366 switch (Attr.getKind()) {
Ted Kremenek9ecdfaf2009-05-09 02:44:38 +00003367 default:
David Blaikie83d382b2011-09-23 05:06:16 +00003368 llvm_unreachable("invalid ownership attribute");
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003369 case AttributeList::AT_NSReturnsAutoreleased:
Michael Han99315932013-01-24 16:46:58 +00003370 D->addAttr(::new (S.Context)
3371 NSReturnsAutoreleasedAttr(Attr.getRange(), S.Context,
3372 Attr.getAttributeSpellingListIndex()));
John McCalled433932011-01-25 03:31:58 +00003373 return;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003374 case AttributeList::AT_CFReturnsNotRetained:
Michael Han99315932013-01-24 16:46:58 +00003375 D->addAttr(::new (S.Context)
3376 CFReturnsNotRetainedAttr(Attr.getRange(), S.Context,
3377 Attr.getAttributeSpellingListIndex()));
Ted Kremenekd9c66632010-02-18 00:05:45 +00003378 return;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003379 case AttributeList::AT_NSReturnsNotRetained:
Michael Han99315932013-01-24 16:46:58 +00003380 D->addAttr(::new (S.Context)
3381 NSReturnsNotRetainedAttr(Attr.getRange(), S.Context,
3382 Attr.getAttributeSpellingListIndex()));
Ted Kremenekd9c66632010-02-18 00:05:45 +00003383 return;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003384 case AttributeList::AT_CFReturnsRetained:
Michael Han99315932013-01-24 16:46:58 +00003385 D->addAttr(::new (S.Context)
3386 CFReturnsRetainedAttr(Attr.getRange(), S.Context,
3387 Attr.getAttributeSpellingListIndex()));
Ted Kremenek9ecdfaf2009-05-09 02:44:38 +00003388 return;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003389 case AttributeList::AT_NSReturnsRetained:
Michael Han99315932013-01-24 16:46:58 +00003390 D->addAttr(::new (S.Context)
3391 NSReturnsRetainedAttr(Attr.getRange(), S.Context,
3392 Attr.getAttributeSpellingListIndex()));
Ted Kremenek9ecdfaf2009-05-09 02:44:38 +00003393 return;
3394 };
3395}
3396
John McCallcf166702011-07-22 08:53:00 +00003397static void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
3398 const AttributeList &attr) {
Fariborz Jahanian8bf05562013-09-19 17:52:50 +00003399 const int EP_ObjCMethod = 1;
3400 const int EP_ObjCProperty = 2;
Fariborz Jahanian5c005832013-09-19 17:18:55 +00003401
John McCallcf166702011-07-22 08:53:00 +00003402 SourceLocation loc = attr.getLoc();
Fariborz Jahanian8a5e9472013-09-19 16:37:20 +00003403 QualType resultType;
Aaron Ballman74eeeae2013-11-27 13:27:02 +00003404 if (isa<ObjCMethodDecl>(D))
Alp Toker314cc812014-01-25 16:55:45 +00003405 resultType = cast<ObjCMethodDecl>(D)->getReturnType();
Fariborz Jahanian8a5e9472013-09-19 16:37:20 +00003406 else
Aaron Ballman74eeeae2013-11-27 13:27:02 +00003407 resultType = cast<ObjCPropertyDecl>(D)->getType();
John McCallcf166702011-07-22 08:53:00 +00003408
Fariborz Jahanian044a5be2011-09-30 20:50:23 +00003409 if (!resultType->isReferenceType() &&
3410 (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
Fariborz Jahanian8a5e9472013-09-19 16:37:20 +00003411 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
John McCallcf166702011-07-22 08:53:00 +00003412 << SourceRange(loc)
Aaron Ballman74eeeae2013-11-27 13:27:02 +00003413 << attr.getName()
3414 << (isa<ObjCMethodDecl>(D) ? EP_ObjCMethod : EP_ObjCProperty)
Fariborz Jahanian5c005832013-09-19 17:18:55 +00003415 << /*non-retainable pointer*/ 2;
John McCallcf166702011-07-22 08:53:00 +00003416
3417 // Drop the attribute.
3418 return;
3419 }
3420
Fariborz Jahanian8a5e9472013-09-19 16:37:20 +00003421 D->addAttr(::new (S.Context)
Michael Han99315932013-01-24 16:46:58 +00003422 ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context,
3423 attr.getAttributeSpellingListIndex()));
John McCallcf166702011-07-22 08:53:00 +00003424}
3425
Fariborz Jahanian566fff02012-09-07 23:46:23 +00003426static void handleObjCRequiresSuperAttr(Sema &S, Decl *D,
3427 const AttributeList &attr) {
Aaron Ballman74eeeae2013-11-27 13:27:02 +00003428 ObjCMethodDecl *method = cast<ObjCMethodDecl>(D);
Fariborz Jahanian566fff02012-09-07 23:46:23 +00003429
Fariborz Jahanian566fff02012-09-07 23:46:23 +00003430 DeclContext *DC = method->getDeclContext();
3431 if (const ObjCProtocolDecl *PDecl = dyn_cast_or_null<ObjCProtocolDecl>(DC)) {
3432 S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol)
3433 << attr.getName() << 0;
3434 S.Diag(PDecl->getLocation(), diag::note_protocol_decl);
3435 return;
3436 }
3437 if (method->getMethodFamily() == OMF_dealloc) {
3438 S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol)
3439 << attr.getName() << 1;
3440 return;
3441 }
3442
Michael Han99315932013-01-24 16:46:58 +00003443 method->addAttr(::new (S.Context)
3444 ObjCRequiresSuperAttr(attr.getRange(), S.Context,
3445 attr.getAttributeSpellingListIndex()));
Fariborz Jahanian566fff02012-09-07 23:46:23 +00003446}
3447
Aaron Ballmanfb763042013-12-02 18:05:46 +00003448static void handleCFAuditedTransferAttr(Sema &S, Decl *D,
3449 const AttributeList &Attr) {
Aaron Ballman2cfbc002014-01-03 16:23:46 +00003450 if (checkAttrMutualExclusion<CFUnknownTransferAttr>(S, D, Attr))
John McCall32f5fe12011-09-30 05:12:12 +00003451 return;
John McCall32f5fe12011-09-30 05:12:12 +00003452
Aaron Ballmanfb763042013-12-02 18:05:46 +00003453 D->addAttr(::new (S.Context)
3454 CFAuditedTransferAttr(Attr.getRange(), S.Context,
3455 Attr.getAttributeSpellingListIndex()));
3456}
3457
3458static void handleCFUnknownTransferAttr(Sema &S, Decl *D,
3459 const AttributeList &Attr) {
Aaron Ballman2cfbc002014-01-03 16:23:46 +00003460 if (checkAttrMutualExclusion<CFAuditedTransferAttr>(S, D, Attr))
Aaron Ballmanfb763042013-12-02 18:05:46 +00003461 return;
3462
3463 D->addAttr(::new (S.Context)
3464 CFUnknownTransferAttr(Attr.getRange(), S.Context,
3465 Attr.getAttributeSpellingListIndex()));
John McCall32f5fe12011-09-30 05:12:12 +00003466}
3467
Fariborz Jahanian0a0a3972013-11-13 23:59:17 +00003468static void handleObjCBridgeAttr(Sema &S, Scope *Sc, Decl *D,
3469 const AttributeList &Attr) {
Fariborz Jahanian2651ac52013-11-22 00:02:22 +00003470 IdentifierLoc * Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : 0;
Ted Kremenek2d3379e2013-11-21 07:20:34 +00003471
Fariborz Jahanian0a0a3972013-11-13 23:59:17 +00003472 if (!Parm) {
Ted Kremenek2d3379e2013-11-21 07:20:34 +00003473 S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << Attr.getName() << 0;
Fariborz Jahanian0a0a3972013-11-13 23:59:17 +00003474 return;
3475 }
3476
3477 D->addAttr(::new (S.Context)
Ted Kremenek2d3379e2013-11-21 07:20:34 +00003478 ObjCBridgeAttr(Attr.getRange(), S.Context, Parm->Ident,
Fariborz Jahanian0a0a3972013-11-13 23:59:17 +00003479 Attr.getAttributeSpellingListIndex()));
3480}
3481
Fariborz Jahanian87c77912013-11-21 20:50:32 +00003482static void handleObjCBridgeMutableAttr(Sema &S, Scope *Sc, Decl *D,
3483 const AttributeList &Attr) {
Fariborz Jahanian2651ac52013-11-22 00:02:22 +00003484 IdentifierLoc * Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : 0;
Fariborz Jahanian87c77912013-11-21 20:50:32 +00003485
3486 if (!Parm) {
3487 S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << Attr.getName() << 0;
3488 return;
3489 }
3490
3491 D->addAttr(::new (S.Context)
3492 ObjCBridgeMutableAttr(Attr.getRange(), S.Context, Parm->Ident,
3493 Attr.getAttributeSpellingListIndex()));
3494}
3495
Fariborz Jahanian1a2519a2013-12-04 20:32:50 +00003496static void handleObjCBridgeRelatedAttr(Sema &S, Scope *Sc, Decl *D,
3497 const AttributeList &Attr) {
3498 IdentifierInfo *RelatedClass =
3499 Attr.isArgIdent(0) ? Attr.getArgAsIdent(0)->Ident : 0;
3500 if (!RelatedClass) {
3501 S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << Attr.getName() << 0;
3502 return;
3503 }
3504 IdentifierInfo *ClassMethod =
3505 Attr.getArgAsIdent(1) ? Attr.getArgAsIdent(1)->Ident : 0;
3506 IdentifierInfo *InstanceMethod =
3507 Attr.getArgAsIdent(2) ? Attr.getArgAsIdent(2)->Ident : 0;
3508 D->addAttr(::new (S.Context)
3509 ObjCBridgeRelatedAttr(Attr.getRange(), S.Context, RelatedClass,
3510 ClassMethod, InstanceMethod,
3511 Attr.getAttributeSpellingListIndex()));
3512}
3513
Argyrios Kyrtzidisd1438b42013-12-03 21:11:25 +00003514static void handleObjCDesignatedInitializer(Sema &S, Decl *D,
3515 const AttributeList &Attr) {
Fariborz Jahanian6efab6e2014-03-14 18:19:46 +00003516 ObjCInterfaceDecl *IFace;
3517 if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(D->getDeclContext()))
3518 IFace = CatDecl->getClassInterface();
3519 else
3520 IFace = cast<ObjCInterfaceDecl>(D->getDeclContext());
Argyrios Kyrtzidis9ed9e5f2013-12-03 21:11:30 +00003521 IFace->setHasDesignatedInitializers();
Argyrios Kyrtzidise8186812013-12-07 06:08:04 +00003522 D->addAttr(::new (S.Context)
Argyrios Kyrtzidisd1438b42013-12-03 21:11:25 +00003523 ObjCDesignatedInitializerAttr(Attr.getRange(), S.Context,
3524 Attr.getAttributeSpellingListIndex()));
3525}
3526
Chandler Carruthedc2c642011-07-02 00:01:44 +00003527static void handleObjCOwnershipAttr(Sema &S, Decl *D,
3528 const AttributeList &Attr) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003529 if (hasDeclarator(D)) return;
John McCall31168b02011-06-15 23:02:42 +00003530
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003531 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
Douglas Gregor5c3cc422012-03-14 16:55:17 +00003532 << Attr.getRange() << Attr.getName() << ExpectedVariable;
John McCall31168b02011-06-15 23:02:42 +00003533}
3534
Chandler Carruthedc2c642011-07-02 00:01:44 +00003535static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
3536 const AttributeList &Attr) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003537 ValueDecl *vd = cast<ValueDecl>(D);
John McCall31168b02011-06-15 23:02:42 +00003538 QualType type = vd->getType();
3539
3540 if (!type->isDependentType() &&
3541 !type->isObjCLifetimeType()) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003542 S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
John McCall31168b02011-06-15 23:02:42 +00003543 << type;
3544 return;
3545 }
3546
3547 Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
3548
3549 // If we have no lifetime yet, check the lifetime we're presumably
3550 // going to infer.
3551 if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
3552 lifetime = type->getObjCARCImplicitLifetime();
3553
3554 switch (lifetime) {
3555 case Qualifiers::OCL_None:
3556 assert(type->isDependentType() &&
3557 "didn't infer lifetime for non-dependent type?");
3558 break;
3559
3560 case Qualifiers::OCL_Weak: // meaningful
3561 case Qualifiers::OCL_Strong: // meaningful
3562 break;
3563
3564 case Qualifiers::OCL_ExplicitNone:
3565 case Qualifiers::OCL_Autoreleasing:
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003566 S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
John McCall31168b02011-06-15 23:02:42 +00003567 << (lifetime == Qualifiers::OCL_Autoreleasing);
3568 break;
3569 }
3570
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003571 D->addAttr(::new (S.Context)
Michael Han99315932013-01-24 16:46:58 +00003572 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context,
3573 Attr.getAttributeSpellingListIndex()));
John McCall31168b02011-06-15 23:02:42 +00003574}
3575
Francois Picheta83957a2010-12-19 06:50:37 +00003576//===----------------------------------------------------------------------===//
3577// Microsoft specific attribute handlers.
3578//===----------------------------------------------------------------------===//
3579
Chandler Carruthedc2c642011-07-02 00:01:44 +00003580static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Aaron Ballmandf8fe4c2013-11-24 21:35:16 +00003581 if (!S.LangOpts.CPlusPlus) {
3582 S.Diag(Attr.getLoc(), diag::err_attribute_not_supported_in_lang)
3583 << Attr.getName() << AttributeLangSupport::C;
3584 return;
3585 }
3586
Aaron Ballman60e705e2013-11-24 20:58:02 +00003587 if (!isa<CXXRecordDecl>(D)) {
3588 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3589 << Attr.getName() << ExpectedClass;
3590 return;
3591 }
3592
Benjamin Kramer6ee15622013-09-13 15:35:43 +00003593 StringRef StrRef;
3594 SourceLocation LiteralLoc;
Tim Northover6a6b63b2013-10-01 14:34:18 +00003595 if (!S.checkStringLiteralArgumentAttr(Attr, 0, StrRef, &LiteralLoc))
Reid Kleckner140c4a72013-05-17 14:04:52 +00003596 return;
Francois Pichet7da11662010-12-20 01:41:49 +00003597
David Majnemer89085342013-08-09 08:56:20 +00003598 // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
3599 // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", normalize to the former.
David Majnemer89085342013-08-09 08:56:20 +00003600 if (StrRef.size() == 38 && StrRef.front() == '{' && StrRef.back() == '}')
3601 StrRef = StrRef.drop_front().drop_back();
Francois Pichet7da11662010-12-20 01:41:49 +00003602
Reid Kleckner140c4a72013-05-17 14:04:52 +00003603 // Validate GUID length.
David Majnemer89085342013-08-09 08:56:20 +00003604 if (StrRef.size() != 36) {
Benjamin Kramer6ee15622013-09-13 15:35:43 +00003605 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
Reid Kleckner140c4a72013-05-17 14:04:52 +00003606 return;
3607 }
Anders Carlsson19588aa2011-01-23 21:07:30 +00003608
David Majnemer89085342013-08-09 08:56:20 +00003609 for (unsigned i = 0; i < 36; ++i) {
Reid Kleckner140c4a72013-05-17 14:04:52 +00003610 if (i == 8 || i == 13 || i == 18 || i == 23) {
David Majnemer89085342013-08-09 08:56:20 +00003611 if (StrRef[i] != '-') {
Benjamin Kramer6ee15622013-09-13 15:35:43 +00003612 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
Francois Pichet7da11662010-12-20 01:41:49 +00003613 return;
3614 }
David Majnemer89085342013-08-09 08:56:20 +00003615 } else if (!isHexDigit(StrRef[i])) {
Benjamin Kramer6ee15622013-09-13 15:35:43 +00003616 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
Reid Kleckner140c4a72013-05-17 14:04:52 +00003617 return;
Francois Pichet7da11662010-12-20 01:41:49 +00003618 }
Reid Kleckner140c4a72013-05-17 14:04:52 +00003619 }
Francois Picheta83957a2010-12-19 06:50:37 +00003620
David Majnemer89085342013-08-09 08:56:20 +00003621 D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context, StrRef,
3622 Attr.getAttributeSpellingListIndex()));
Charles Davis163855f2010-02-16 18:27:26 +00003623}
3624
David Majnemer2c4e00a2014-01-29 22:07:36 +00003625static void handleMSInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3626 if (!S.LangOpts.CPlusPlus) {
3627 S.Diag(Attr.getLoc(), diag::err_attribute_not_supported_in_lang)
3628 << Attr.getName() << AttributeLangSupport::C;
3629 return;
3630 }
3631 MSInheritanceAttr *IA = S.mergeMSInheritanceAttr(
David Majnemer4bb09802014-02-10 19:50:15 +00003632 D, Attr.getRange(), /*BestCase=*/true,
3633 Attr.getAttributeSpellingListIndex(),
David Majnemer2c4e00a2014-01-29 22:07:36 +00003634 (MSInheritanceAttr::Spelling)Attr.getSemanticSpelling());
3635 if (IA)
3636 D->addAttr(IA);
3637}
3638
Aaron Ballmanab7691c2014-01-09 22:48:32 +00003639static void handleARMInterruptAttr(Sema &S, Decl *D,
3640 const AttributeList &Attr) {
3641 // Check the attribute arguments.
3642 if (Attr.getNumArgs() > 1) {
3643 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments)
3644 << Attr.getName() << 1;
3645 return;
3646 }
3647
3648 StringRef Str;
3649 SourceLocation ArgLoc;
3650
3651 if (Attr.getNumArgs() == 0)
3652 Str = "";
3653 else if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &ArgLoc))
3654 return;
3655
3656 ARMInterruptAttr::InterruptType Kind;
3657 if (!ARMInterruptAttr::ConvertStrToInterruptType(Str, Kind)) {
3658 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
3659 << Attr.getName() << Str << ArgLoc;
3660 return;
3661 }
3662
3663 unsigned Index = Attr.getAttributeSpellingListIndex();
3664 D->addAttr(::new (S.Context)
3665 ARMInterruptAttr(Attr.getLoc(), S.Context, Kind, Index));
3666}
3667
3668static void handleMSP430InterruptAttr(Sema &S, Decl *D,
3669 const AttributeList &Attr) {
3670 if (!checkAttributeNumArgs(S, Attr, 1))
3671 return;
3672
3673 if (!Attr.isArgExpr(0)) {
3674 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr.getName()
3675 << AANT_ArgumentIntegerConstant;
3676 return;
3677 }
3678
3679 // FIXME: Check for decl - it should be void ()(void).
3680
3681 Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArgAsExpr(0));
3682 llvm::APSInt NumParams(32);
3683 if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
3684 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
3685 << Attr.getName() << AANT_ArgumentIntegerConstant
3686 << NumParamsExpr->getSourceRange();
3687 return;
3688 }
3689
3690 unsigned Num = NumParams.getLimitedValue(255);
3691 if ((Num & 1) || Num > 30) {
3692 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
3693 << Attr.getName() << (int)NumParams.getSExtValue()
3694 << NumParamsExpr->getSourceRange();
3695 return;
3696 }
3697
Aaron Ballman36a53502014-01-16 13:03:14 +00003698 D->addAttr(::new (S.Context)
3699 MSP430InterruptAttr(Attr.getLoc(), S.Context, Num,
3700 Attr.getAttributeSpellingListIndex()));
3701 D->addAttr(UsedAttr::CreateImplicit(S.Context));
Aaron Ballmanab7691c2014-01-09 22:48:32 +00003702}
3703
3704static void handleInterruptAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3705 // Dispatch the interrupt attribute based on the current target.
3706 if (S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::msp430)
3707 handleMSP430InterruptAttr(S, D, Attr);
3708 else
3709 handleARMInterruptAttr(S, D, Attr);
3710}
3711
3712static void handleX86ForceAlignArgPointerAttr(Sema &S, Decl *D,
3713 const AttributeList& Attr) {
3714 // If we try to apply it to a function pointer, don't warn, but don't
3715 // do anything, either. It doesn't matter anyway, because there's nothing
3716 // special about calling a force_align_arg_pointer function.
3717 ValueDecl *VD = dyn_cast<ValueDecl>(D);
3718 if (VD && VD->getType()->isFunctionPointerType())
3719 return;
3720 // Also don't warn on function pointer typedefs.
3721 TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
3722 if (TD && (TD->getUnderlyingType()->isFunctionPointerType() ||
3723 TD->getUnderlyingType()->isFunctionType()))
3724 return;
3725 // Attribute can only be applied to function types.
3726 if (!isa<FunctionDecl>(D)) {
3727 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3728 << Attr.getName() << /* function */0;
3729 return;
3730 }
3731
Aaron Ballman36a53502014-01-16 13:03:14 +00003732 D->addAttr(::new (S.Context)
3733 X86ForceAlignArgPointerAttr(Attr.getRange(), S.Context,
3734 Attr.getAttributeSpellingListIndex()));
Aaron Ballmanab7691c2014-01-09 22:48:32 +00003735}
3736
3737DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D, SourceRange Range,
3738 unsigned AttrSpellingListIndex) {
3739 if (D->hasAttr<DLLExportAttr>()) {
Nico Rieck60478662014-02-22 19:47:30 +00003740 Diag(Range.getBegin(), diag::warn_attribute_ignored) << "'dllimport'";
Aaron Ballmanab7691c2014-01-09 22:48:32 +00003741 return NULL;
3742 }
3743
3744 if (D->hasAttr<DLLImportAttr>())
3745 return NULL;
3746
Aaron Ballman3f5f3e72014-01-20 16:15:55 +00003747 return ::new (Context) DLLImportAttr(Range, Context, AttrSpellingListIndex);
Aaron Ballmanab7691c2014-01-09 22:48:32 +00003748}
3749
3750static void handleDLLImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3751 // Attribute can be applied only to functions or variables.
3752 FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
3753 if (!FD && !isa<VarDecl>(D)) {
3754 // Apparently Visual C++ thinks it is okay to not emit a warning
3755 // in this case, so only emit a warning when -fms-extensions is not
3756 // specified.
3757 if (!S.getLangOpts().MicrosoftExt)
3758 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
Aaron Ballman3f5f3e72014-01-20 16:15:55 +00003759 << Attr.getName() << ExpectedVariableOrFunction;
Aaron Ballmanab7691c2014-01-09 22:48:32 +00003760 return;
3761 }
3762
3763 // Currently, the dllimport attribute is ignored for inlined functions.
3764 // Warning is emitted.
3765 if (FD && FD->isInlineSpecified()) {
3766 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
3767 return;
3768 }
3769
3770 unsigned Index = Attr.getAttributeSpellingListIndex();
3771 DLLImportAttr *NewAttr = S.mergeDLLImportAttr(D, Attr.getRange(), Index);
3772 if (NewAttr)
3773 D->addAttr(NewAttr);
3774}
3775
3776DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D, SourceRange Range,
3777 unsigned AttrSpellingListIndex) {
3778 if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) {
Nico Rieck60478662014-02-22 19:47:30 +00003779 Diag(Import->getLocation(), diag::warn_attribute_ignored) << Import;
Aaron Ballmanab7691c2014-01-09 22:48:32 +00003780 D->dropAttr<DLLImportAttr>();
3781 }
3782
3783 if (D->hasAttr<DLLExportAttr>())
3784 return NULL;
3785
Aaron Ballman3f5f3e72014-01-20 16:15:55 +00003786 return ::new (Context) DLLExportAttr(Range, Context, AttrSpellingListIndex);
Aaron Ballmanab7691c2014-01-09 22:48:32 +00003787}
3788
3789static void handleDLLExportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3790 // Currently, the dllexport attribute is ignored for inlined functions, unless
Aaron Ballman3f5f3e72014-01-20 16:15:55 +00003791 // the -fkeep-inline-functions flag has been used. Warning is emitted.
Aaron Ballmanab7691c2014-01-09 22:48:32 +00003792 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isInlineSpecified()) {
3793 // FIXME: ... unless the -fkeep-inline-functions flag has been used.
3794 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
3795 return;
3796 }
3797
3798 unsigned Index = Attr.getAttributeSpellingListIndex();
3799 DLLExportAttr *NewAttr = S.mergeDLLExportAttr(D, Attr.getRange(), Index);
3800 if (NewAttr)
3801 D->addAttr(NewAttr);
3802}
3803
David Majnemer2c4e00a2014-01-29 22:07:36 +00003804MSInheritanceAttr *
David Majnemer4bb09802014-02-10 19:50:15 +00003805Sema::mergeMSInheritanceAttr(Decl *D, SourceRange Range, bool BestCase,
David Majnemer2c4e00a2014-01-29 22:07:36 +00003806 unsigned AttrSpellingListIndex,
3807 MSInheritanceAttr::Spelling SemanticSpelling) {
3808 if (MSInheritanceAttr *IA = D->getAttr<MSInheritanceAttr>()) {
3809 if (IA->getSemanticSpelling() == SemanticSpelling)
3810 return 0;
3811 Diag(IA->getLocation(), diag::err_mismatched_ms_inheritance)
3812 << 1 /*previous declaration*/;
3813 Diag(Range.getBegin(), diag::note_previous_ms_inheritance);
3814 D->dropAttr<MSInheritanceAttr>();
3815 }
3816
3817 CXXRecordDecl *RD = cast<CXXRecordDecl>(D);
3818 if (RD->hasDefinition()) {
David Majnemer4bb09802014-02-10 19:50:15 +00003819 if (checkMSInheritanceAttrOnDefinition(RD, Range, BestCase,
3820 SemanticSpelling)) {
David Majnemer2c4e00a2014-01-29 22:07:36 +00003821 return 0;
3822 }
3823 } else {
3824 if (isa<ClassTemplatePartialSpecializationDecl>(RD)) {
3825 Diag(Range.getBegin(), diag::warn_ignored_ms_inheritance)
3826 << 1 /*partial specialization*/;
3827 return 0;
3828 }
3829 if (RD->getDescribedClassTemplate()) {
3830 Diag(Range.getBegin(), diag::warn_ignored_ms_inheritance)
3831 << 0 /*primary template*/;
3832 return 0;
3833 }
3834 }
3835
3836 return ::new (Context)
David Majnemer4bb09802014-02-10 19:50:15 +00003837 MSInheritanceAttr(Range, Context, BestCase, AttrSpellingListIndex);
David Majnemer2c4e00a2014-01-29 22:07:36 +00003838}
3839
Aaron Ballmanefe348e2014-02-18 17:36:50 +00003840static void handleCapabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3841 // The capability attributes take a single string parameter for the name of
3842 // the capability they represent. The lockable attribute does not take any
3843 // parameters. However, semantically, both attributes represent the same
3844 // concept, and so they use the same semantic attribute. Eventually, the
3845 // lockable attribute will be removed.
Aaron Ballman6c810072014-03-05 21:47:13 +00003846 //
3847 // For backwards compatibility, any capability which has no specified string
3848 // literal will be considered a "mutex."
3849 StringRef N("mutex");
Aaron Ballmanefe348e2014-02-18 17:36:50 +00003850 SourceLocation LiteralLoc;
3851 if (Attr.getKind() == AttributeList::AT_Capability &&
3852 !S.checkStringLiteralArgumentAttr(Attr, 0, N, &LiteralLoc))
3853 return;
3854
Aaron Ballman6c810072014-03-05 21:47:13 +00003855 // Currently, there are only two names allowed for a capability: role and
3856 // mutex (case insensitive). Diagnose other capability names.
3857 if (!N.equals_lower("mutex") && !N.equals_lower("role"))
3858 S.Diag(LiteralLoc, diag::warn_invalid_capability_name) << N;
3859
Aaron Ballmanefe348e2014-02-18 17:36:50 +00003860 D->addAttr(::new (S.Context) CapabilityAttr(Attr.getRange(), S.Context, N,
3861 Attr.getAttributeSpellingListIndex()));
3862}
3863
Aaron Ballman9e9d1842014-02-21 21:05:14 +00003864static void handleAssertCapabilityAttr(Sema &S, Decl *D,
3865 const AttributeList &Attr) {
3866 D->addAttr(::new (S.Context) AssertCapabilityAttr(Attr.getRange(), S.Context,
3867 Attr.getArgAsExpr(0),
3868 Attr.getAttributeSpellingListIndex()));
3869}
3870
3871static void handleAcquireCapabilityAttr(Sema &S, Decl *D,
3872 const AttributeList &Attr) {
3873 SmallVector<Expr*, 1> Args;
Aaron Ballman18d85ae2014-03-20 16:02:49 +00003874 if (!checkLockFunAttrCommon(S, D, Attr, Args))
Aaron Ballman9e9d1842014-02-21 21:05:14 +00003875 return;
3876
3877 D->addAttr(::new (S.Context) AcquireCapabilityAttr(Attr.getRange(),
3878 S.Context,
3879 Args.data(), Args.size(),
3880 Attr.getAttributeSpellingListIndex()));
3881}
3882
3883static void handleTryAcquireCapabilityAttr(Sema &S, Decl *D,
3884 const AttributeList &Attr) {
3885 SmallVector<Expr*, 2> Args;
3886 if (!checkTryLockFunAttrCommon(S, D, Attr, Args))
3887 return;
3888
3889 D->addAttr(::new (S.Context) TryAcquireCapabilityAttr(Attr.getRange(),
3890 S.Context,
3891 Attr.getArgAsExpr(0),
3892 Args.data(),
3893 Args.size(),
3894 Attr.getAttributeSpellingListIndex()));
3895}
3896
3897static void handleReleaseCapabilityAttr(Sema &S, Decl *D,
3898 const AttributeList &Attr) {
Aaron Ballman9e9d1842014-02-21 21:05:14 +00003899 // Check that all arguments are lockable objects.
Aaron Ballman18d85ae2014-03-20 16:02:49 +00003900 SmallVector<Expr *, 1> Args;
3901 checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, true);
Aaron Ballman9e9d1842014-02-21 21:05:14 +00003902
Aaron Ballman18d85ae2014-03-20 16:02:49 +00003903 D->addAttr(::new (S.Context) ReleaseCapabilityAttr(
3904 Attr.getRange(), S.Context, Args.data(), Args.size(),
3905 Attr.getAttributeSpellingListIndex()));
Aaron Ballman9e9d1842014-02-21 21:05:14 +00003906}
3907
Aaron Ballmanefe348e2014-02-18 17:36:50 +00003908static void handleRequiresCapabilityAttr(Sema &S, Decl *D,
3909 const AttributeList &Attr) {
3910 if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
3911 return;
3912
3913 // check that all arguments are lockable objects
3914 SmallVector<Expr*, 1> Args;
3915 checkAttrArgsAreLockableObjs(S, D, Attr, Args);
3916 if (Args.empty())
3917 return;
3918
3919 RequiresCapabilityAttr *RCA = ::new (S.Context)
3920 RequiresCapabilityAttr(Attr.getRange(), S.Context, Args.data(),
3921 Args.size(), Attr.getAttributeSpellingListIndex());
3922
3923 D->addAttr(RCA);
3924}
3925
Aaron Ballman8ee40b72013-09-09 23:33:17 +00003926/// Handles semantic checking for features that are common to all attributes,
3927/// such as checking whether a parameter was properly specified, or the correct
3928/// number of arguments were passed, etc.
3929static bool handleCommonAttributeFeatures(Sema &S, Scope *scope, Decl *D,
3930 const AttributeList &Attr) {
3931 // Several attributes carry different semantics than the parsing requires, so
3932 // those are opted out of the common handling.
3933 //
3934 // We also bail on unknown and ignored attributes because those are handled
3935 // as part of the target-specific handling logic.
3936 if (Attr.hasCustomParsing() ||
Aaron Ballmanab7691c2014-01-09 22:48:32 +00003937 Attr.getKind() == AttributeList::UnknownAttribute)
Aaron Ballman8ee40b72013-09-09 23:33:17 +00003938 return false;
3939
Aaron Ballman3aff6332013-12-02 19:30:36 +00003940 // Check whether the attribute requires specific language extensions to be
3941 // enabled.
3942 if (!Attr.diagnoseLangOpts(S))
3943 return true;
3944
Aaron Ballman8ee40b72013-09-09 23:33:17 +00003945 // If there are no optional arguments, then checking for the argument count
3946 // is trivial.
3947 if (Attr.getMinArgs() == Attr.getMaxArgs() &&
3948 !checkAttributeNumArgs(S, Attr, Attr.getMinArgs()))
3949 return true;
Aaron Ballman74eeeae2013-11-27 13:27:02 +00003950
3951 // Check whether the attribute appertains to the given subject.
3952 if (!Attr.diagnoseAppertainsTo(S, D))
3953 return true;
3954
Aaron Ballman8ee40b72013-09-09 23:33:17 +00003955 return false;
3956}
3957
Ted Kremenek9ecdfaf2009-05-09 02:44:38 +00003958//===----------------------------------------------------------------------===//
Chris Lattner9e2aafe2008-06-29 00:23:49 +00003959// Top Level Sema Entry Points
3960//===----------------------------------------------------------------------===//
3961
Richard Smithf8a75c32013-08-29 00:47:48 +00003962/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
3963/// the attribute applies to decls. If the attribute is a type attribute, just
3964/// silently ignore it if a GNU attribute.
3965static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
3966 const AttributeList &Attr,
3967 bool IncludeCXX11Attributes) {
Aaron Ballmanab7691c2014-01-09 22:48:32 +00003968 if (Attr.isInvalid() || Attr.getKind() == AttributeList::IgnoredAttribute)
Richard Smithf8a75c32013-08-29 00:47:48 +00003969 return;
Abramo Bagnara50099372010-04-30 13:10:51 +00003970
Richard Smithf8a75c32013-08-29 00:47:48 +00003971 // Ignore C++11 attributes on declarator chunks: they appertain to the type
3972 // instead.
3973 if (Attr.isCXX11Attribute() && !IncludeCXX11Attributes)
3974 return;
3975
Aaron Ballmanab7691c2014-01-09 22:48:32 +00003976 // Unknown attributes are automatically warned on. Target-specific attributes
3977 // which do not apply to the current target architecture are treated as
3978 // though they were unknown attributes.
3979 if (Attr.getKind() == AttributeList::UnknownAttribute ||
3980 !Attr.existsInTarget(S.Context.getTargetInfo().getTriple())) {
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00003981 S.Diag(Attr.getLoc(), Attr.isDeclspecAttribute()
3982 ? diag::warn_unhandled_ms_attribute_ignored
3983 : diag::warn_unknown_attribute_ignored)
3984 << Attr.getName();
Aaron Ballmanab7691c2014-01-09 22:48:32 +00003985 return;
3986 }
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00003987
Aaron Ballman8ee40b72013-09-09 23:33:17 +00003988 if (handleCommonAttributeFeatures(S, scope, D, Attr))
3989 return;
3990
Chris Lattnerb632a6e2008-06-29 00:43:07 +00003991 switch (Attr.getKind()) {
Aaron Ballmanab7691c2014-01-09 22:48:32 +00003992 default:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00003993 // Type attributes are handled elsewhere; silently move on.
Aaron Ballmanab7691c2014-01-09 22:48:32 +00003994 assert(Attr.isTypeAttr() && "Non-type attribute not handled");
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00003995 break;
Aaron Ballmanab7691c2014-01-09 22:48:32 +00003996 case AttributeList::AT_Interrupt:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00003997 handleInterruptAttr(S, D, Attr);
3998 break;
Aaron Ballmanab7691c2014-01-09 22:48:32 +00003999 case AttributeList::AT_X86ForceAlignArgPointer:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004000 handleX86ForceAlignArgPointerAttr(S, D, Attr);
4001 break;
Aaron Ballmanab7691c2014-01-09 22:48:32 +00004002 case AttributeList::AT_DLLExport:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004003 handleDLLExportAttr(S, D, Attr);
4004 break;
Aaron Ballmanab7691c2014-01-09 22:48:32 +00004005 case AttributeList::AT_DLLImport:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004006 handleDLLImportAttr(S, D, Attr);
4007 break;
Aaron Ballmanab7691c2014-01-09 22:48:32 +00004008 case AttributeList::AT_Mips16:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004009 handleSimpleAttribute<Mips16Attr>(S, D, Attr);
4010 break;
Aaron Ballmanab7691c2014-01-09 22:48:32 +00004011 case AttributeList::AT_NoMips16:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004012 handleSimpleAttribute<NoMips16Attr>(S, D, Attr);
4013 break;
Aaron Ballman9beb5172013-12-02 15:13:14 +00004014 case AttributeList::AT_IBAction:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004015 handleSimpleAttribute<IBActionAttr>(S, D, Attr);
4016 break;
4017 case AttributeList::AT_IBOutlet:
4018 handleIBOutlet(S, D, Attr);
4019 break;
Richard Smith10876ef2013-01-17 01:30:42 +00004020 case AttributeList::AT_IBOutletCollection:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004021 handleIBOutletCollection(S, D, Attr);
4022 break;
4023 case AttributeList::AT_Alias:
4024 handleAliasAttr(S, D, Attr);
4025 break;
4026 case AttributeList::AT_Aligned:
4027 handleAlignedAttr(S, D, Attr);
4028 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004029 case AttributeList::AT_AlwaysInline:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004030 handleSimpleAttribute<AlwaysInlineAttr>(S, D, Attr);
4031 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004032 case AttributeList::AT_AnalyzerNoReturn:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004033 handleAnalyzerNoReturnAttr(S, D, Attr);
4034 break;
4035 case AttributeList::AT_TLSModel:
4036 handleTLSModelAttr(S, D, Attr);
4037 break;
4038 case AttributeList::AT_Annotate:
4039 handleAnnotateAttr(S, D, Attr);
4040 break;
4041 case AttributeList::AT_Availability:
4042 handleAvailabilityAttr(S, D, Attr);
4043 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004044 case AttributeList::AT_CarriesDependency:
Richard Smithe233fbf2013-01-28 22:42:45 +00004045 handleDependencyAttr(S, scope, D, Attr);
4046 break;
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004047 case AttributeList::AT_Common:
4048 handleCommonAttr(S, D, Attr);
4049 break;
Aaron Ballman3aff6332013-12-02 19:30:36 +00004050 case AttributeList::AT_CUDAConstant:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004051 handleSimpleAttribute<CUDAConstantAttr>(S, D, Attr);
4052 break;
4053 case AttributeList::AT_Constructor:
4054 handleConstructorAttr(S, D, Attr);
4055 break;
Richard Smith10876ef2013-01-17 01:30:42 +00004056 case AttributeList::AT_CXX11NoReturn:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004057 handleSimpleAttribute<CXX11NoReturnAttr>(S, D, Attr);
4058 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004059 case AttributeList::AT_Deprecated:
Aaron Ballman8b8ebdd2013-07-18 13:13:52 +00004060 handleAttrWithMessage<DeprecatedAttr>(S, D, Attr);
Benjamin Kramerf435ab42012-05-16 12:19:08 +00004061 break;
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004062 case AttributeList::AT_Destructor:
4063 handleDestructorAttr(S, D, Attr);
4064 break;
4065 case AttributeList::AT_EnableIf:
4066 handleEnableIfAttr(S, D, Attr);
4067 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004068 case AttributeList::AT_ExtVectorType:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004069 handleExtVectorTypeAttr(S, scope, D, Attr);
Chris Lattnerb632a6e2008-06-29 00:43:07 +00004070 break;
Quentin Colombet4e172062012-11-01 23:55:47 +00004071 case AttributeList::AT_MinSize:
Aaron Ballman6f9165a2013-11-27 15:24:06 +00004072 handleSimpleAttribute<MinSizeAttr>(S, D, Attr);
Quentin Colombet4e172062012-11-01 23:55:47 +00004073 break;
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004074 case AttributeList::AT_Format:
4075 handleFormatAttr(S, D, Attr);
4076 break;
4077 case AttributeList::AT_FormatArg:
4078 handleFormatArgAttr(S, D, Attr);
4079 break;
4080 case AttributeList::AT_CUDAGlobal:
4081 handleGlobalAttr(S, D, Attr);
4082 break;
Aaron Ballmanf79ee272013-12-02 21:09:08 +00004083 case AttributeList::AT_CUDADevice:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004084 handleSimpleAttribute<CUDADeviceAttr>(S, D, Attr);
4085 break;
Aaron Ballman3aff6332013-12-02 19:30:36 +00004086 case AttributeList::AT_CUDAHost:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004087 handleSimpleAttribute<CUDAHostAttr>(S, D, Attr);
4088 break;
4089 case AttributeList::AT_GNUInline:
4090 handleGNUInlineAttr(S, D, Attr);
4091 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004092 case AttributeList::AT_CUDALaunchBounds:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004093 handleLaunchBoundsAttr(S, D, Attr);
Peter Collingbourne827301e2010-12-12 23:03:07 +00004094 break;
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004095 case AttributeList::AT_Malloc:
4096 handleMallocAttr(S, D, Attr);
4097 break;
Aaron Ballman6f9165a2013-11-27 15:24:06 +00004098 case AttributeList::AT_MayAlias:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004099 handleSimpleAttribute<MayAliasAttr>(S, D, Attr);
4100 break;
4101 case AttributeList::AT_Mode:
4102 handleModeAttr(S, D, Attr);
4103 break;
Aaron Ballman6f9165a2013-11-27 15:24:06 +00004104 case AttributeList::AT_NoCommon:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004105 handleSimpleAttribute<NoCommonAttr>(S, D, Attr);
4106 break;
Ted Kremenek9aedc152014-01-17 06:24:56 +00004107 case AttributeList::AT_NonNull:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004108 if (ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(D))
4109 handleNonNullAttrParameter(S, PVD, Attr);
4110 else
4111 handleNonNullAttr(S, D, Attr);
4112 break;
Aaron Ballmanfc1951c2014-01-20 14:19:44 +00004113 case AttributeList::AT_ReturnsNonNull:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004114 handleReturnsNonNullAttr(S, D, Attr);
4115 break;
Aaron Ballman6f9165a2013-11-27 15:24:06 +00004116 case AttributeList::AT_Overloadable:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004117 handleSimpleAttribute<OverloadableAttr>(S, D, Attr);
4118 break;
4119 case AttributeList::AT_Ownership:
4120 handleOwnershipAttr(S, D, Attr);
4121 break;
4122 case AttributeList::AT_Cold:
4123 handleColdAttr(S, D, Attr);
4124 break;
4125 case AttributeList::AT_Hot:
4126 handleHotAttr(S, D, Attr);
4127 break;
Aaron Ballman6f9165a2013-11-27 15:24:06 +00004128 case AttributeList::AT_Naked:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004129 handleSimpleAttribute<NakedAttr>(S, D, Attr);
4130 break;
4131 case AttributeList::AT_NoReturn:
4132 handleNoReturnAttr(S, D, Attr);
4133 break;
Aaron Ballmanbf7b1ee2013-12-21 16:49:29 +00004134 case AttributeList::AT_NoThrow:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004135 handleSimpleAttribute<NoThrowAttr>(S, D, Attr);
4136 break;
Aaron Ballman3aff6332013-12-02 19:30:36 +00004137 case AttributeList::AT_CUDAShared:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004138 handleSimpleAttribute<CUDASharedAttr>(S, D, Attr);
4139 break;
4140 case AttributeList::AT_VecReturn:
4141 handleVecReturnAttr(S, D, Attr);
4142 break;
Ted Kremenek9ecdfaf2009-05-09 02:44:38 +00004143
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004144 case AttributeList::AT_ObjCOwnership:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004145 handleObjCOwnershipAttr(S, D, Attr);
4146 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004147 case AttributeList::AT_ObjCPreciseLifetime:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004148 handleObjCPreciseLifetimeAttr(S, D, Attr);
4149 break;
John McCall31168b02011-06-15 23:02:42 +00004150
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004151 case AttributeList::AT_ObjCReturnsInnerPointer:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004152 handleObjCReturnsInnerPointerAttr(S, D, Attr);
4153 break;
John McCallcf166702011-07-22 08:53:00 +00004154
Fariborz Jahanian566fff02012-09-07 23:46:23 +00004155 case AttributeList::AT_ObjCRequiresSuper:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004156 handleObjCRequiresSuperAttr(S, D, Attr);
4157 break;
4158
Fariborz Jahanian0a0a3972013-11-13 23:59:17 +00004159 case AttributeList::AT_ObjCBridge:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004160 handleObjCBridgeAttr(S, scope, D, Attr);
4161 break;
4162
Fariborz Jahanian87c77912013-11-21 20:50:32 +00004163 case AttributeList::AT_ObjCBridgeMutable:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004164 handleObjCBridgeMutableAttr(S, scope, D, Attr);
4165 break;
4166
Fariborz Jahanian1a2519a2013-12-04 20:32:50 +00004167 case AttributeList::AT_ObjCBridgeRelated:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004168 handleObjCBridgeRelatedAttr(S, scope, D, Attr);
4169 break;
John McCallf1e8b342011-09-29 07:17:38 +00004170
Argyrios Kyrtzidisd1438b42013-12-03 21:11:25 +00004171 case AttributeList::AT_ObjCDesignatedInitializer:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004172 handleObjCDesignatedInitializer(S, D, Attr);
4173 break;
Argyrios Kyrtzidisd1438b42013-12-03 21:11:25 +00004174
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004175 case AttributeList::AT_CFAuditedTransfer:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004176 handleCFAuditedTransferAttr(S, D, Attr);
4177 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004178 case AttributeList::AT_CFUnknownTransfer:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004179 handleCFUnknownTransferAttr(S, D, Attr);
4180 break;
John McCall32f5fe12011-09-30 05:12:12 +00004181
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004182 case AttributeList::AT_CFConsumed:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004183 case AttributeList::AT_NSConsumed:
4184 handleNSConsumedAttr(S, D, Attr);
4185 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004186 case AttributeList::AT_NSConsumesSelf:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004187 handleSimpleAttribute<NSConsumesSelfAttr>(S, D, Attr);
4188 break;
John McCalled433932011-01-25 03:31:58 +00004189
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004190 case AttributeList::AT_NSReturnsAutoreleased:
4191 case AttributeList::AT_NSReturnsNotRetained:
4192 case AttributeList::AT_CFReturnsNotRetained:
4193 case AttributeList::AT_NSReturnsRetained:
4194 case AttributeList::AT_CFReturnsRetained:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004195 handleNSReturnsRetainedAttr(S, D, Attr);
4196 break;
Tanya Lattnerbcffcdf2012-07-09 22:06:01 +00004197 case AttributeList::AT_WorkGroupSizeHint:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004198 handleWorkGroupSize<WorkGroupSizeHintAttr>(S, D, Attr);
4199 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004200 case AttributeList::AT_ReqdWorkGroupSize:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004201 handleWorkGroupSize<ReqdWorkGroupSizeAttr>(S, D, Attr);
4202 break;
Joey Goulyaba589c2013-03-08 09:42:32 +00004203 case AttributeList::AT_VecTypeHint:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004204 handleVecTypeHint(S, D, Attr);
4205 break;
Joey Goulyaba589c2013-03-08 09:42:32 +00004206
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004207 case AttributeList::AT_InitPriority:
4208 handleInitPriorityAttr(S, D, Attr);
4209 break;
4210
4211 case AttributeList::AT_Packed:
4212 handlePackedAttr(S, D, Attr);
4213 break;
4214 case AttributeList::AT_Section:
4215 handleSectionAttr(S, D, Attr);
4216 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004217 case AttributeList::AT_Unavailable:
Aaron Ballman8b8ebdd2013-07-18 13:13:52 +00004218 handleAttrWithMessage<UnavailableAttr>(S, D, Attr);
Benjamin Kramerf435ab42012-05-16 12:19:08 +00004219 break;
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004220 case AttributeList::AT_ArcWeakrefUnavailable:
4221 handleSimpleAttribute<ArcWeakrefUnavailableAttr>(S, D, Attr);
4222 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004223 case AttributeList::AT_ObjCRootClass:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004224 handleSimpleAttribute<ObjCRootClassAttr>(S, D, Attr);
4225 break;
Ted Kremenekf41cf7f12013-12-10 19:43:48 +00004226 case AttributeList::AT_ObjCExplicitProtocolImpl:
Ted Kremenek438f8db2014-02-22 01:06:05 +00004227 handleObjCSuppresProtocolAttr(S, D, Attr);
Ted Kremenek28eace62013-11-23 01:01:34 +00004228 break;
4229 case AttributeList::AT_ObjCRequiresPropertyDefs:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004230 handleSimpleAttribute<ObjCRequiresPropertyDefsAttr>(S, D, Attr);
4231 break;
Aaron Ballman12b9f652014-01-16 13:55:42 +00004232 case AttributeList::AT_Unused:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004233 handleSimpleAttribute<UnusedAttr>(S, D, Attr);
4234 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004235 case AttributeList::AT_ReturnsTwice:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004236 handleSimpleAttribute<ReturnsTwiceAttr>(S, D, Attr);
4237 break;
4238 case AttributeList::AT_Used:
4239 handleUsedAttr(S, D, Attr);
4240 break;
John McCalld041a9b2013-02-20 01:54:26 +00004241 case AttributeList::AT_Visibility:
4242 handleVisibilityAttr(S, D, Attr, false);
4243 break;
4244 case AttributeList::AT_TypeVisibility:
4245 handleVisibilityAttr(S, D, Attr, true);
4246 break;
Lubos Lunakedc13882013-07-20 15:05:36 +00004247 case AttributeList::AT_WarnUnused:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004248 handleSimpleAttribute<WarnUnusedAttr>(S, D, Attr);
4249 break;
4250 case AttributeList::AT_WarnUnusedResult:
4251 handleWarnUnusedResult(S, D, Attr);
Chris Lattner237f2752009-02-14 07:37:35 +00004252 break;
Aaron Ballman604dfec2013-12-02 17:07:07 +00004253 case AttributeList::AT_Weak:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004254 handleSimpleAttribute<WeakAttr>(S, D, Attr);
4255 break;
4256 case AttributeList::AT_WeakRef:
4257 handleWeakRefAttr(S, D, Attr);
4258 break;
4259 case AttributeList::AT_WeakImport:
4260 handleWeakImportAttr(S, D, Attr);
4261 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004262 case AttributeList::AT_TransparentUnion:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004263 handleTransparentUnionAttr(S, D, Attr);
Chris Lattnerb632a6e2008-06-29 00:43:07 +00004264 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004265 case AttributeList::AT_ObjCException:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004266 handleSimpleAttribute<ObjCExceptionAttr>(S, D, Attr);
4267 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004268 case AttributeList::AT_ObjCMethodFamily:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004269 handleObjCMethodFamilyAttr(S, D, Attr);
John McCall86bc21f2011-03-02 11:33:24 +00004270 break;
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004271 case AttributeList::AT_ObjCNSObject:
4272 handleObjCNSObject(S, D, Attr);
4273 break;
4274 case AttributeList::AT_Blocks:
4275 handleBlocksAttr(S, D, Attr);
4276 break;
4277 case AttributeList::AT_Sentinel:
4278 handleSentinelAttr(S, D, Attr);
4279 break;
Aaron Ballmanbf7b1ee2013-12-21 16:49:29 +00004280 case AttributeList::AT_Const:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004281 handleSimpleAttribute<ConstAttr>(S, D, Attr);
4282 break;
Aaron Ballman6f9165a2013-11-27 15:24:06 +00004283 case AttributeList::AT_Pure:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004284 handleSimpleAttribute<PureAttr>(S, D, Attr);
4285 break;
4286 case AttributeList::AT_Cleanup:
4287 handleCleanupAttr(S, D, Attr);
4288 break;
4289 case AttributeList::AT_NoDebug:
4290 handleNoDebugAttr(S, D, Attr);
4291 break;
Aaron Ballman7c19ab12014-02-22 16:59:24 +00004292 case AttributeList::AT_NoDuplicate:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004293 handleSimpleAttribute<NoDuplicateAttr>(S, D, Attr);
4294 break;
Aaron Ballman6f9165a2013-11-27 15:24:06 +00004295 case AttributeList::AT_NoInline:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004296 handleSimpleAttribute<NoInlineAttr>(S, D, Attr);
4297 break;
4298 case AttributeList::AT_NoInstrumentFunction: // Interacts with -pg.
4299 handleSimpleAttribute<NoInstrumentFunctionAttr>(S, D, Attr);
4300 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004301 case AttributeList::AT_StdCall:
4302 case AttributeList::AT_CDecl:
4303 case AttributeList::AT_FastCall:
4304 case AttributeList::AT_ThisCall:
4305 case AttributeList::AT_Pascal:
Charles Davisb5a214e2013-08-30 04:39:01 +00004306 case AttributeList::AT_MSABI:
4307 case AttributeList::AT_SysVABI:
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004308 case AttributeList::AT_Pcs:
Derek Schuffa2020962012-10-16 22:30:41 +00004309 case AttributeList::AT_PnaclCall:
Guy Benyeif0a014b2012-12-25 08:53:55 +00004310 case AttributeList::AT_IntelOclBicc:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004311 handleCallConvAttr(S, D, Attr);
John McCallab26cfa2010-02-05 21:31:56 +00004312 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004313 case AttributeList::AT_OpenCLKernel:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004314 handleSimpleAttribute<OpenCLKernelAttr>(S, D, Attr);
4315 break;
Guy Benyeifb36ede2013-03-24 13:58:12 +00004316 case AttributeList::AT_OpenCLImageAccess:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004317 handleSimpleAttribute<OpenCLImageAccessAttr>(S, D, Attr);
4318 break;
John McCall8d32c052012-05-22 21:28:12 +00004319
4320 // Microsoft attributes:
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004321 case AttributeList::AT_MsStruct:
Aaron Ballman6f9165a2013-11-27 15:24:06 +00004322 handleSimpleAttribute<MsStructAttr>(S, D, Attr);
John McCall8d32c052012-05-22 21:28:12 +00004323 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004324 case AttributeList::AT_Uuid:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004325 handleUuidAttr(S, D, Attr);
Francois Picheta83957a2010-12-19 06:50:37 +00004326 break;
Aaron Ballman8edb5c22013-12-18 23:44:18 +00004327 case AttributeList::AT_MSInheritance:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004328 handleMSInheritanceAttr(S, D, Attr);
4329 break;
Reid Klecknerb144d362013-05-20 14:02:37 +00004330 case AttributeList::AT_SelectAny:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004331 handleSimpleAttribute<SelectAnyAttr>(S, D, Attr);
4332 break;
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +00004333
4334 // Thread safety attributes:
DeLesley Hutchinsb6824312013-05-17 23:02:59 +00004335 case AttributeList::AT_AssertExclusiveLock:
4336 handleAssertExclusiveLockAttr(S, D, Attr);
4337 break;
4338 case AttributeList::AT_AssertSharedLock:
4339 handleAssertSharedLockAttr(S, D, Attr);
4340 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004341 case AttributeList::AT_GuardedVar:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004342 handleSimpleAttribute<GuardedVarAttr>(S, D, Attr);
4343 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004344 case AttributeList::AT_PtGuardedVar:
Michael Han3be3b442012-07-23 18:48:41 +00004345 handlePtGuardedVarAttr(S, D, Attr);
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +00004346 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004347 case AttributeList::AT_ScopedLockable:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004348 handleSimpleAttribute<ScopedLockableAttr>(S, D, Attr);
4349 break;
Kostya Serebryany4c0fc992013-02-26 06:58:27 +00004350 case AttributeList::AT_NoSanitizeAddress:
Aaron Ballman6f9165a2013-11-27 15:24:06 +00004351 handleSimpleAttribute<NoSanitizeAddressAttr>(S, D, Attr);
Kostya Serebryany588d6ab2012-01-24 19:25:38 +00004352 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004353 case AttributeList::AT_NoThreadSafetyAnalysis:
Aaron Ballman6f9165a2013-11-27 15:24:06 +00004354 handleSimpleAttribute<NoThreadSafetyAnalysisAttr>(S, D, Attr);
Kostya Serebryany4c0fc992013-02-26 06:58:27 +00004355 break;
4356 case AttributeList::AT_NoSanitizeThread:
Aaron Ballman6f9165a2013-11-27 15:24:06 +00004357 handleSimpleAttribute<NoSanitizeThreadAttr>(S, D, Attr);
Kostya Serebryany4c0fc992013-02-26 06:58:27 +00004358 break;
4359 case AttributeList::AT_NoSanitizeMemory:
Aaron Ballman6f9165a2013-11-27 15:24:06 +00004360 handleSimpleAttribute<NoSanitizeMemoryAttr>(S, D, Attr);
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +00004361 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004362 case AttributeList::AT_GuardedBy:
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004363 handleGuardedByAttr(S, D, Attr);
4364 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004365 case AttributeList::AT_PtGuardedBy:
Michael Han3be3b442012-07-23 18:48:41 +00004366 handlePtGuardedByAttr(S, D, Attr);
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004367 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004368 case AttributeList::AT_ExclusiveTrylockFunction:
Michael Han3be3b442012-07-23 18:48:41 +00004369 handleExclusiveTrylockFunctionAttr(S, D, Attr);
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004370 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004371 case AttributeList::AT_LockReturned:
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004372 handleLockReturnedAttr(S, D, Attr);
4373 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004374 case AttributeList::AT_LocksExcluded:
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004375 handleLocksExcludedAttr(S, D, Attr);
4376 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004377 case AttributeList::AT_SharedTrylockFunction:
Michael Han3be3b442012-07-23 18:48:41 +00004378 handleSharedTrylockFunctionAttr(S, D, Attr);
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004379 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004380 case AttributeList::AT_AcquiredBefore:
Michael Han3be3b442012-07-23 18:48:41 +00004381 handleAcquiredBeforeAttr(S, D, Attr);
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004382 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004383 case AttributeList::AT_AcquiredAfter:
Michael Han3be3b442012-07-23 18:48:41 +00004384 handleAcquiredAfterAttr(S, D, Attr);
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004385 break;
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +00004386
Aaron Ballmanefe348e2014-02-18 17:36:50 +00004387 // Capability analysis attributes.
4388 case AttributeList::AT_Capability:
4389 case AttributeList::AT_Lockable:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004390 handleCapabilityAttr(S, D, Attr);
4391 break;
Aaron Ballman9e9d1842014-02-21 21:05:14 +00004392 case AttributeList::AT_RequiresCapability:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004393 handleRequiresCapabilityAttr(S, D, Attr);
4394 break;
Aaron Ballman9e9d1842014-02-21 21:05:14 +00004395
4396 case AttributeList::AT_AssertCapability:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004397 handleAssertCapabilityAttr(S, D, Attr);
4398 break;
Aaron Ballman9e9d1842014-02-21 21:05:14 +00004399 case AttributeList::AT_AcquireCapability:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004400 handleAcquireCapabilityAttr(S, D, Attr);
4401 break;
Aaron Ballman9e9d1842014-02-21 21:05:14 +00004402 case AttributeList::AT_ReleaseCapability:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004403 handleReleaseCapabilityAttr(S, D, Attr);
4404 break;
Aaron Ballman9e9d1842014-02-21 21:05:14 +00004405 case AttributeList::AT_TryAcquireCapability:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004406 handleTryAcquireCapabilityAttr(S, D, Attr);
4407 break;
Aaron Ballmanefe348e2014-02-18 17:36:50 +00004408
DeLesley Hutchins8d41d992013-10-11 22:30:48 +00004409 // Consumed analysis attributes.
DeLesley Hutchins5a715c42013-08-30 22:56:34 +00004410 case AttributeList::AT_Consumable:
4411 handleConsumableAttr(S, D, Attr);
4412 break;
DeLesley Hutchinsf28bbec2014-01-14 00:36:53 +00004413 case AttributeList::AT_ConsumableAutoCast:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004414 handleSimpleAttribute<ConsumableAutoCastAttr>(S, D, Attr);
4415 break;
DeLesley Hutchinsf28bbec2014-01-14 00:36:53 +00004416 case AttributeList::AT_ConsumableSetOnRead:
Aaron Ballman8abdd0e2014-03-06 14:02:27 +00004417 handleSimpleAttribute<ConsumableSetOnReadAttr>(S, D, Attr);
4418 break;
DeLesley Hutchins210791a2013-10-04 21:28:06 +00004419 case AttributeList::AT_CallableWhen:
4420 handleCallableWhenAttr(S, D, Attr);
DeLesley Hutchins48a31762013-08-12 21:20:55 +00004421 break;
DeLesley Hutchins69391772013-10-17 23:23:53 +00004422 case AttributeList::AT_ParamTypestate:
4423 handleParamTypestateAttr(S, D, Attr);
4424 break;
DeLesley Hutchinsfc368252013-09-03 20:11:38 +00004425 case AttributeList::AT_ReturnTypestate:
4426 handleReturnTypestateAttr(S, D, Attr);
4427 break;
DeLesley Hutchins33a29342013-10-11 23:03:26 +00004428 case AttributeList::AT_SetTypestate:
4429 handleSetTypestateAttr(S, D, Attr);
4430 break;
Chris Wailes9385f9f2013-10-29 20:28:41 +00004431 case AttributeList::AT_TestTypestate:
4432 handleTestTypestateAttr(S, D, Attr);
DeLesley Hutchins33a29342013-10-11 23:03:26 +00004433 break;
DeLesley Hutchins48a31762013-08-12 21:20:55 +00004434
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +00004435 // Type safety attributes.
4436 case AttributeList::AT_ArgumentWithTypeTag:
4437 handleArgumentWithTypeTagAttr(S, D, Attr);
4438 break;
4439 case AttributeList::AT_TypeTagForDatatype:
4440 handleTypeTagForDatatypeAttr(S, D, Attr);
4441 break;
Chris Lattnerb632a6e2008-06-29 00:43:07 +00004442 }
4443}
4444
4445/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
4446/// attribute list to the specified decl, ignoring any type attributes.
Eric Christopherbc638a82010-12-01 22:13:54 +00004447void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
Peter Collingbourneb331b262011-01-21 02:08:45 +00004448 const AttributeList *AttrList,
Richard Smith10876ef2013-01-17 01:30:42 +00004449 bool IncludeCXX11Attributes) {
4450 for (const AttributeList* l = AttrList; l; l = l->getNext())
Richard Smithf8a75c32013-08-29 00:47:48 +00004451 ProcessDeclAttribute(*this, S, D, *l, IncludeCXX11Attributes);
Rafael Espindolac18086a2010-02-23 22:00:30 +00004452
Joey Gouly2cd9db12013-12-13 16:15:28 +00004453 // FIXME: We should be able to handle these cases in TableGen.
Rafael Espindolac18086a2010-02-23 22:00:30 +00004454 // GCC accepts
4455 // static int a9 __attribute__((weakref));
4456 // but that looks really pointless. We reject it.
Richard Smithf8a75c32013-08-29 00:47:48 +00004457 if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
Aaron Ballman9f6fec42014-01-02 23:02:01 +00004458 Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias)
4459 << cast<NamedDecl>(D);
Rafael Espindolab3069002013-01-16 23:49:06 +00004460 D->dropAttr<WeakRefAttr>();
Rafael Espindolac18086a2010-02-23 22:00:30 +00004461 return;
Chris Lattnerb632a6e2008-06-29 00:43:07 +00004462 }
Joey Gouly2cd9db12013-12-13 16:15:28 +00004463
4464 if (!D->hasAttr<OpenCLKernelAttr>()) {
4465 // These attributes cannot be applied to a non-kernel function.
Aaron Ballman3e424b52013-12-26 18:30:57 +00004466 if (Attr *A = D->getAttr<ReqdWorkGroupSizeAttr>()) {
4467 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
Joey Gouly2cd9db12013-12-13 16:15:28 +00004468 D->setInvalidDecl();
4469 }
Aaron Ballman3e424b52013-12-26 18:30:57 +00004470 if (Attr *A = D->getAttr<WorkGroupSizeHintAttr>()) {
4471 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
Joey Gouly2cd9db12013-12-13 16:15:28 +00004472 D->setInvalidDecl();
4473 }
Aaron Ballman3e424b52013-12-26 18:30:57 +00004474 if (Attr *A = D->getAttr<VecTypeHintAttr>()) {
4475 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
Joey Gouly2cd9db12013-12-13 16:15:28 +00004476 D->setInvalidDecl();
4477 }
4478 }
Chris Lattnerb632a6e2008-06-29 00:43:07 +00004479}
4480
Erik Verbruggenca98f2a2011-10-13 09:41:32 +00004481// Annotation attributes are the only attributes allowed after an access
4482// specifier.
4483bool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
4484 const AttributeList *AttrList) {
4485 for (const AttributeList* l = AttrList; l; l = l->getNext()) {
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004486 if (l->getKind() == AttributeList::AT_Annotate) {
Erik Verbruggenca98f2a2011-10-13 09:41:32 +00004487 handleAnnotateAttr(*this, ASDecl, *l);
4488 } else {
4489 Diag(l->getLoc(), diag::err_only_annotate_after_access_spec);
4490 return true;
4491 }
4492 }
4493
4494 return false;
4495}
4496
John McCall42856de2011-10-01 05:17:03 +00004497/// checkUnusedDeclAttributes - Check a list of attributes to see if it
4498/// contains any decl attributes that we should warn about.
4499static void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
4500 for ( ; A; A = A->getNext()) {
4501 // Only warn if the attribute is an unignored, non-type attribute.
Richard Smith810ad3e2013-01-29 10:02:16 +00004502 if (A->isUsedAsTypeAttr() || A->isInvalid()) continue;
John McCall42856de2011-10-01 05:17:03 +00004503 if (A->getKind() == AttributeList::IgnoredAttribute) continue;
4504
4505 if (A->getKind() == AttributeList::UnknownAttribute) {
4506 S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored)
4507 << A->getName() << A->getRange();
4508 } else {
4509 S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl)
4510 << A->getName() << A->getRange();
4511 }
4512 }
4513}
4514
4515/// checkUnusedDeclAttributes - Given a declarator which is not being
4516/// used to build a declaration, complain about any decl attributes
4517/// which might be lying around on it.
4518void Sema::checkUnusedDeclAttributes(Declarator &D) {
4519 ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList());
4520 ::checkUnusedDeclAttributes(*this, D.getAttributes());
4521 for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
4522 ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());
4523}
4524
Ryan Flynn7d470f32009-07-30 03:15:39 +00004525/// DeclClonePragmaWeak - clone existing decl (maybe definition),
James Dennett634962f2012-06-14 21:40:34 +00004526/// \#pragma weak needs a non-definition decl and source may not have one.
Eli Friedmance3e2c82011-09-07 04:05:06 +00004527NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
4528 SourceLocation Loc) {
Ryan Flynnd963a492009-07-31 02:52:19 +00004529 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
Ryan Flynn7d470f32009-07-30 03:15:39 +00004530 NamedDecl *NewD = 0;
4531 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
Eli Friedmance3e2c82011-09-07 04:05:06 +00004532 FunctionDecl *NewFD;
4533 // FIXME: Missing call to CheckFunctionDeclaration().
4534 // FIXME: Mangling?
4535 // FIXME: Is the qualifier info correct?
4536 // FIXME: Is the DeclContext correct?
4537 NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
4538 Loc, Loc, DeclarationName(II),
4539 FD->getType(), FD->getTypeSourceInfo(),
Rafael Espindola6ae7e502013-04-03 19:27:57 +00004540 SC_None, false/*isInlineSpecified*/,
Eli Friedmance3e2c82011-09-07 04:05:06 +00004541 FD->hasPrototype(),
4542 false/*isConstexprSpecified*/);
4543 NewD = NewFD;
4544
4545 if (FD->getQualifier())
Douglas Gregor14454802011-02-25 02:25:35 +00004546 NewFD->setQualifierInfo(FD->getQualifierLoc());
Eli Friedmance3e2c82011-09-07 04:05:06 +00004547
4548 // Fake up parameter variables; they are declared as if this were
4549 // a typedef.
4550 QualType FDTy = FD->getType();
4551 if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) {
4552 SmallVector<ParmVarDecl*, 16> Params;
Aaron Ballman40bd0aa2014-03-17 15:23:01 +00004553 for (const auto &AI : FT->param_types()) {
4554 ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, AI);
Eli Friedmance3e2c82011-09-07 04:05:06 +00004555 Param->setScopeInfo(0, Params.size());
4556 Params.push_back(Param);
4557 }
David Blaikie9c70e042011-09-21 18:16:56 +00004558 NewFD->setParams(Params);
John McCall3e11ebe2010-03-15 10:12:16 +00004559 }
Ryan Flynn7d470f32009-07-30 03:15:39 +00004560 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
4561 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
Abramo Bagnaradff19302011-03-08 08:55:46 +00004562 VD->getInnerLocStart(), VD->getLocation(), II,
John McCallbcd03502009-12-07 02:54:59 +00004563 VD->getType(), VD->getTypeSourceInfo(),
Rafael Espindola6ae7e502013-04-03 19:27:57 +00004564 VD->getStorageClass());
John McCall3e11ebe2010-03-15 10:12:16 +00004565 if (VD->getQualifier()) {
4566 VarDecl *NewVD = cast<VarDecl>(NewD);
Douglas Gregor14454802011-02-25 02:25:35 +00004567 NewVD->setQualifierInfo(VD->getQualifierLoc());
John McCall3e11ebe2010-03-15 10:12:16 +00004568 }
Ryan Flynn7d470f32009-07-30 03:15:39 +00004569 }
4570 return NewD;
4571}
4572
James Dennett634962f2012-06-14 21:40:34 +00004573/// DeclApplyPragmaWeak - A declaration (maybe definition) needs \#pragma weak
Ryan Flynn7d470f32009-07-30 03:15:39 +00004574/// applied to it, possibly with an alias.
Ryan Flynnd963a492009-07-31 02:52:19 +00004575void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
Chris Lattnere6eab982009-09-08 18:10:11 +00004576 if (W.getUsed()) return; // only do this once
4577 W.setUsed(true);
4578 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
4579 IdentifierInfo *NDId = ND->getIdentifier();
Eli Friedmance3e2c82011-09-07 04:05:06 +00004580 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
Aaron Ballman36a53502014-01-16 13:03:14 +00004581 NewD->addAttr(AliasAttr::CreateImplicit(Context, NDId->getName(),
4582 W.getLocation()));
4583 NewD->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));
Chris Lattnere6eab982009-09-08 18:10:11 +00004584 WeakTopLevelDecl.push_back(NewD);
4585 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
4586 // to insert Decl at TU scope, sorry.
4587 DeclContext *SavedContext = CurContext;
4588 CurContext = Context.getTranslationUnitDecl();
Argyrios Kyrtzidis0098a4b2014-03-09 05:15:28 +00004589 NewD->setDeclContext(CurContext);
4590 NewD->setLexicalDeclContext(CurContext);
Chris Lattnere6eab982009-09-08 18:10:11 +00004591 PushOnScopeChains(NewD, S);
4592 CurContext = SavedContext;
4593 } else { // just add weak to existing
Aaron Ballman36a53502014-01-16 13:03:14 +00004594 ND->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));
Ryan Flynn7d470f32009-07-30 03:15:39 +00004595 }
4596}
4597
Rafael Espindolade6a39f2013-03-02 21:41:48 +00004598void Sema::ProcessPragmaWeak(Scope *S, Decl *D) {
4599 // It's valid to "forward-declare" #pragma weak, in which case we
4600 // have to do this.
4601 LoadExternalWeakUndeclaredIdentifiers();
4602 if (!WeakUndeclaredIdentifiers.empty()) {
4603 NamedDecl *ND = NULL;
4604 if (VarDecl *VD = dyn_cast<VarDecl>(D))
4605 if (VD->isExternC())
4606 ND = VD;
4607 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
4608 if (FD->isExternC())
4609 ND = FD;
4610 if (ND) {
4611 if (IdentifierInfo *Id = ND->getIdentifier()) {
4612 llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
4613 = WeakUndeclaredIdentifiers.find(Id);
4614 if (I != WeakUndeclaredIdentifiers.end()) {
4615 WeakInfo W = I->second;
4616 DeclApplyPragmaWeak(S, ND, W);
4617 WeakUndeclaredIdentifiers[Id] = W;
4618 }
4619 }
4620 }
4621 }
4622}
4623
Chris Lattner9e2aafe2008-06-29 00:23:49 +00004624/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
4625/// it, apply them to D. This is a bit tricky because PD can have attributes
4626/// specified in many different places, and we need to find and apply them all.
Richard Smithf8a75c32013-08-29 00:47:48 +00004627void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
Chris Lattner9e2aafe2008-06-29 00:23:49 +00004628 // Apply decl attributes from the DeclSpec if present.
John McCall53fa7142010-12-24 02:08:15 +00004629 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
Richard Smithf8a75c32013-08-29 00:47:48 +00004630 ProcessDeclAttributeList(S, D, Attrs);
Mike Stumpd3bb5572009-07-24 19:02:52 +00004631
Chris Lattner9e2aafe2008-06-29 00:23:49 +00004632 // Walk the declarator structure, applying decl attributes that were in a type
4633 // position to the decl itself. This handles cases like:
4634 // int *__attr__(x)** D;
4635 // when X is a decl attribute.
4636 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
4637 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
Richard Smithf8a75c32013-08-29 00:47:48 +00004638 ProcessDeclAttributeList(S, D, Attrs, /*IncludeCXX11Attributes=*/false);
Mike Stumpd3bb5572009-07-24 19:02:52 +00004639
Chris Lattner9e2aafe2008-06-29 00:23:49 +00004640 // Finally, apply any attributes on the decl itself.
4641 if (const AttributeList *Attrs = PD.getAttributes())
Richard Smithf8a75c32013-08-29 00:47:48 +00004642 ProcessDeclAttributeList(S, D, Attrs);
Chris Lattner9e2aafe2008-06-29 00:23:49 +00004643}
John McCall28a6aea2009-11-04 02:18:39 +00004644
John McCall31168b02011-06-15 23:02:42 +00004645/// Is the given declaration allowed to use a forbidden type?
4646static bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
4647 // Private ivars are always okay. Unfortunately, people don't
4648 // always properly make their ivars private, even in system headers.
4649 // Plus we need to make fields okay, too.
Fariborz Jahanian6d5d6a22011-09-26 21:23:35 +00004650 // Function declarations in sys headers will be marked unavailable.
4651 if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) &&
4652 !isa<FunctionDecl>(decl))
John McCall31168b02011-06-15 23:02:42 +00004653 return false;
4654
4655 // Require it to be declared in a system header.
4656 return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
4657}
4658
4659/// Handle a delayed forbidden-type diagnostic.
4660static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
4661 Decl *decl) {
4662 if (decl && isForbiddenTypeAllowed(S, decl)) {
Aaron Ballman36a53502014-01-16 13:03:14 +00004663 decl->addAttr(UnavailableAttr::CreateImplicit(S.Context,
4664 "this system declaration uses an unsupported type",
4665 diag.Loc));
John McCall31168b02011-06-15 23:02:42 +00004666 return;
4667 }
David Blaikiebbafb8a2012-03-11 07:00:24 +00004668 if (S.getLangOpts().ObjCAutoRefCount)
Fariborz Jahanianed1933b2011-10-03 22:11:57 +00004669 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) {
Benjamin Kramer474261a2012-06-02 10:20:41 +00004670 // FIXME: we may want to suppress diagnostics for all
Fariborz Jahanianed1933b2011-10-03 22:11:57 +00004671 // kind of forbidden type messages on unavailable functions.
4672 if (FD->hasAttr<UnavailableAttr>() &&
4673 diag.getForbiddenTypeDiagnostic() ==
4674 diag::err_arc_array_param_no_ownership) {
4675 diag.Triggered = true;
4676 return;
4677 }
4678 }
John McCall31168b02011-06-15 23:02:42 +00004679
4680 S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
4681 << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
4682 diag.Triggered = true;
4683}
4684
John McCall2ec85372012-05-07 06:16:41 +00004685void Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) {
4686 assert(DelayedDiagnostics.getCurrentPool());
John McCall6347b682012-05-07 06:16:58 +00004687 DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool();
John McCall2ec85372012-05-07 06:16:41 +00004688 DelayedDiagnostics.popWithoutEmitting(state);
John McCallc1465822011-02-14 07:13:47 +00004689
John McCall2ec85372012-05-07 06:16:41 +00004690 // When delaying diagnostics to run in the context of a parsed
4691 // declaration, we only want to actually emit anything if parsing
4692 // succeeds.
4693 if (!decl) return;
John McCallc1465822011-02-14 07:13:47 +00004694
John McCall2ec85372012-05-07 06:16:41 +00004695 // We emit all the active diagnostics in this pool or any of its
4696 // parents. In general, we'll get one pool for the decl spec
4697 // and a child pool for each declarator; in a decl group like:
4698 // deprecated_typedef foo, *bar, baz();
4699 // only the declarator pops will be passed decls. This is correct;
4700 // we really do need to consider delayed diagnostics from the decl spec
4701 // for each of the different declarations.
John McCall6347b682012-05-07 06:16:58 +00004702 const DelayedDiagnosticPool *pool = &poppedPool;
John McCall2ec85372012-05-07 06:16:41 +00004703 do {
John McCall6347b682012-05-07 06:16:58 +00004704 for (DelayedDiagnosticPool::pool_iterator
John McCall2ec85372012-05-07 06:16:41 +00004705 i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) {
4706 // This const_cast is a bit lame. Really, Triggered should be mutable.
4707 DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i);
John McCallc1465822011-02-14 07:13:47 +00004708 if (diag.Triggered)
John McCall86121512010-01-27 03:50:35 +00004709 continue;
4710
John McCallc1465822011-02-14 07:13:47 +00004711 switch (diag.Kind) {
John McCall86121512010-01-27 03:50:35 +00004712 case DelayedDiagnostic::Deprecation:
Ted Kremenekb79ee572013-12-18 23:30:06 +00004713 case DelayedDiagnostic::Unavailable:
4714 // Don't bother giving deprecation/unavailable diagnostics if
4715 // the decl is invalid.
John McCall18a962b2012-01-26 20:04:03 +00004716 if (!decl->isInvalidDecl())
Ted Kremenekb79ee572013-12-18 23:30:06 +00004717 HandleDelayedAvailabilityCheck(diag, decl);
John McCall86121512010-01-27 03:50:35 +00004718 break;
4719
4720 case DelayedDiagnostic::Access:
John McCall2ec85372012-05-07 06:16:41 +00004721 HandleDelayedAccessCheck(diag, decl);
John McCall86121512010-01-27 03:50:35 +00004722 break;
John McCall31168b02011-06-15 23:02:42 +00004723
4724 case DelayedDiagnostic::ForbiddenType:
John McCall2ec85372012-05-07 06:16:41 +00004725 handleDelayedForbiddenType(*this, diag, decl);
John McCall31168b02011-06-15 23:02:42 +00004726 break;
John McCall86121512010-01-27 03:50:35 +00004727 }
4728 }
John McCall2ec85372012-05-07 06:16:41 +00004729 } while ((pool = pool->getParent()));
John McCall28a6aea2009-11-04 02:18:39 +00004730}
4731
John McCall6347b682012-05-07 06:16:58 +00004732/// Given a set of delayed diagnostics, re-emit them as if they had
4733/// been delayed in the current context instead of in the given pool.
4734/// Essentially, this just moves them to the current pool.
4735void Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) {
4736 DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool();
4737 assert(curPool && "re-emitting in undelayed context not supported");
4738 curPool->steal(pool);
4739}
4740
John McCall28a6aea2009-11-04 02:18:39 +00004741static bool isDeclDeprecated(Decl *D) {
4742 do {
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00004743 if (D->isDeprecated())
John McCall28a6aea2009-11-04 02:18:39 +00004744 return true;
Argyrios Kyrtzidisc281c962011-10-06 23:23:27 +00004745 // A category implicitly has the availability of the interface.
4746 if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
4747 return CatD->getClassInterface()->isDeprecated();
John McCall28a6aea2009-11-04 02:18:39 +00004748 } while ((D = cast_or_null<Decl>(D->getDeclContext())));
4749 return false;
4750}
4751
Ted Kremenekb79ee572013-12-18 23:30:06 +00004752static bool isDeclUnavailable(Decl *D) {
4753 do {
4754 if (D->isUnavailable())
4755 return true;
4756 // A category implicitly has the availability of the interface.
4757 if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
4758 return CatD->getClassInterface()->isUnavailable();
4759 } while ((D = cast_or_null<Decl>(D->getDeclContext())));
4760 return false;
4761}
4762
Eli Friedman971bfa12012-08-08 21:52:41 +00004763static void
Ted Kremenekb79ee572013-12-18 23:30:06 +00004764DoEmitAvailabilityWarning(Sema &S,
4765 DelayedDiagnostic::DDKind K,
4766 Decl *Ctx,
4767 const NamedDecl *D,
4768 StringRef Message,
4769 SourceLocation Loc,
4770 const ObjCInterfaceDecl *UnknownObjCClass,
4771 const ObjCPropertyDecl *ObjCProperty) {
4772
4773 // Diagnostics for deprecated or unavailable.
4774 unsigned diag, diag_message, diag_fwdclass_message;
4775
4776 // Matches 'diag::note_property_attribute' options.
4777 unsigned property_note_select;
4778
4779 // Matches diag::note_availability_specified_here.
4780 unsigned available_here_select_kind;
4781
4782 // Don't warn if our current context is deprecated or unavailable.
4783 switch (K) {
4784 case DelayedDiagnostic::Deprecation:
4785 if (isDeclDeprecated(Ctx))
4786 return;
4787 diag = diag::warn_deprecated;
4788 diag_message = diag::warn_deprecated_message;
4789 diag_fwdclass_message = diag::warn_deprecated_fwdclass_message;
4790 property_note_select = /* deprecated */ 0;
4791 available_here_select_kind = /* deprecated */ 2;
4792 break;
4793
4794 case DelayedDiagnostic::Unavailable:
4795 if (isDeclUnavailable(Ctx))
4796 return;
4797 diag = diag::err_unavailable;
4798 diag_message = diag::err_unavailable_message;
4799 diag_fwdclass_message = diag::warn_unavailable_fwdclass_message;
4800 property_note_select = /* unavailable */ 1;
4801 available_here_select_kind = /* unavailable */ 0;
4802 break;
4803
4804 default:
4805 llvm_unreachable("Neither a deprecation or unavailable kind");
4806 }
4807
Eli Friedman971bfa12012-08-08 21:52:41 +00004808 DeclarationName Name = D->getDeclName();
4809 if (!Message.empty()) {
Ted Kremenekb79ee572013-12-18 23:30:06 +00004810 S.Diag(Loc, diag_message) << Name << Message;
Ted Kremenekb79ee572013-12-18 23:30:06 +00004811 if (ObjCProperty)
4812 S.Diag(ObjCProperty->getLocation(), diag::note_property_attribute)
4813 << ObjCProperty->getDeclName() << property_note_select;
Eli Friedman971bfa12012-08-08 21:52:41 +00004814 } else if (!UnknownObjCClass) {
Ted Kremenekb79ee572013-12-18 23:30:06 +00004815 S.Diag(Loc, diag) << Name;
Ted Kremenekb79ee572013-12-18 23:30:06 +00004816 if (ObjCProperty)
4817 S.Diag(ObjCProperty->getLocation(), diag::note_property_attribute)
4818 << ObjCProperty->getDeclName() << property_note_select;
Eli Friedman971bfa12012-08-08 21:52:41 +00004819 } else {
Ted Kremenekb79ee572013-12-18 23:30:06 +00004820 S.Diag(Loc, diag_fwdclass_message) << Name;
Eli Friedman971bfa12012-08-08 21:52:41 +00004821 S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
4822 }
Ted Kremenekb79ee572013-12-18 23:30:06 +00004823
4824 S.Diag(D->getLocation(), diag::note_availability_specified_here)
4825 << D << available_here_select_kind;
Eli Friedman971bfa12012-08-08 21:52:41 +00004826}
4827
Ted Kremenekb79ee572013-12-18 23:30:06 +00004828void Sema::HandleDelayedAvailabilityCheck(DelayedDiagnostic &DD,
4829 Decl *Ctx) {
John McCall86121512010-01-27 03:50:35 +00004830 DD.Triggered = true;
Ted Kremenekb79ee572013-12-18 23:30:06 +00004831 DoEmitAvailabilityWarning(*this,
4832 (DelayedDiagnostic::DDKind) DD.Kind,
4833 Ctx,
4834 DD.getDeprecationDecl(),
4835 DD.getDeprecationMessage(),
4836 DD.Loc,
4837 DD.getUnknownObjCClass(),
4838 DD.getObjCProperty());
John McCall28a6aea2009-11-04 02:18:39 +00004839}
4840
Ted Kremenekb79ee572013-12-18 23:30:06 +00004841void Sema::EmitAvailabilityWarning(AvailabilityDiagnostic AD,
4842 NamedDecl *D, StringRef Message,
4843 SourceLocation Loc,
4844 const ObjCInterfaceDecl *UnknownObjCClass,
4845 const ObjCPropertyDecl *ObjCProperty) {
John McCall28a6aea2009-11-04 02:18:39 +00004846 // Delay if we're currently parsing a declaration.
John McCallc1465822011-02-14 07:13:47 +00004847 if (DelayedDiagnostics.shouldDelayDiagnostics()) {
Ted Kremenekb79ee572013-12-18 23:30:06 +00004848 DelayedDiagnostics.add(DelayedDiagnostic::makeAvailability(AD, Loc, D,
4849 UnknownObjCClass,
4850 ObjCProperty,
4851 Message));
John McCall28a6aea2009-11-04 02:18:39 +00004852 return;
4853 }
4854
Ted Kremenekb79ee572013-12-18 23:30:06 +00004855 Decl *Ctx = cast<Decl>(getCurLexicalContext());
4856 DelayedDiagnostic::DDKind K;
4857 switch (AD) {
4858 case AD_Deprecation:
4859 K = DelayedDiagnostic::Deprecation;
4860 break;
4861 case AD_Unavailable:
4862 K = DelayedDiagnostic::Unavailable;
4863 break;
4864 }
4865
4866 DoEmitAvailabilityWarning(*this, K, Ctx, D, Message, Loc,
4867 UnknownObjCClass, ObjCProperty);
John McCall28a6aea2009-11-04 02:18:39 +00004868}